feat: integrate transaction broadcast
This commit is contained in:
parent
a030b20971
commit
c407e054fd
4 changed files with 170 additions and 16 deletions
|
|
@ -225,4 +225,86 @@
|
||||||
</div>
|
</div>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
||||||
|
<q-dialog v-model="showFinalTx" position="top">
|
||||||
|
<q-card class="q-pa-lg q-pt-xl">
|
||||||
|
<div class="row items-center no-wrap q-mb-sm">
|
||||||
|
<div class="col-12">
|
||||||
|
<span class="text-subtitle1">Transaction Details</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-separator class="q-mb-lg"></q-separator>
|
||||||
|
<div v-if="signedTx" class="row items-center no-wrap q-mb-md">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row items-center no-wrap q-mb-sm">
|
||||||
|
<div class="col-3 q-pr-lg">Version</div>
|
||||||
|
<div class="col-9">{{signedTx.version}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row items-center no-wrap q-mb-sm">
|
||||||
|
<div class="col-3 q-pr-lg">Locktime</div>
|
||||||
|
<div class="col-9">{{signedTx.locktime}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row items-center no-wrap q-mb-sm">
|
||||||
|
<div class="col-3 q-pr-lg">Fee</div>
|
||||||
|
<div class="col-9">
|
||||||
|
<q-badge color="orange">{{satBtc(signedTx.fee)}} </q-badge>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-separator class="q-mb-lg"></q-separator>
|
||||||
|
<span class="text-subtitle2">Outputs</span>
|
||||||
|
<q-separator class="q-mb-lg"></q-separator>
|
||||||
|
<div
|
||||||
|
v-for="out in signedTx.outputs"
|
||||||
|
class="row items-center no-wrap q-mb-sm"
|
||||||
|
>
|
||||||
|
<div class="col-3 q-pr-lg">
|
||||||
|
<q-badge color="orange">{{satBtc(out.amount)}}</q-badge>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-9">
|
||||||
|
<q-badge outline color="blue">{{out.address}}</q-badge>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-separator class="q-mb-lg"></q-separator>
|
||||||
|
<div class="row q-mt-lg">
|
||||||
|
<div class="col-12">
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model.trim="signedTxHex"
|
||||||
|
type="textarea"
|
||||||
|
cols="300"
|
||||||
|
rows="1"
|
||||||
|
label="Signed Tx Hex"
|
||||||
|
></q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row q-mt-lg">
|
||||||
|
<div class="col-12">
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model.trim="psbtBase64Signed"
|
||||||
|
ype="textarea"
|
||||||
|
cols="300"
|
||||||
|
rows="1"
|
||||||
|
label="PSBT"
|
||||||
|
></q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row q-mt-lg">
|
||||||
|
<q-btn
|
||||||
|
unelevated
|
||||||
|
color="secondary"
|
||||||
|
class="float-left"
|
||||||
|
@click="broadcastTransaction"
|
||||||
|
>Send</q-btn
|
||||||
|
>
|
||||||
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
||||||
|
</div>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ async function payment(path) {
|
||||||
DUST_LIMIT: 546,
|
DUST_LIMIT: 546,
|
||||||
tx: null,
|
tx: null,
|
||||||
psbtBase64: null,
|
psbtBase64: null,
|
||||||
|
psbtBase64Signed: null,
|
||||||
signedTx: null,
|
signedTx: null,
|
||||||
sentTxId: null,
|
sentTxId: null,
|
||||||
signedTxId: null,
|
signedTxId: null,
|
||||||
|
|
@ -40,6 +41,7 @@ async function payment(path) {
|
||||||
showChecking: false,
|
showChecking: false,
|
||||||
showChange: false,
|
showChange: false,
|
||||||
showPsbt: false,
|
showPsbt: false,
|
||||||
|
showFinalTx: false,
|
||||||
feeRate: 1
|
feeRate: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -224,9 +226,14 @@ async function payment(path) {
|
||||||
this.selectChangeAddress(this.changeWallet)
|
this.selectChangeAddress(this.changeWallet)
|
||||||
},
|
},
|
||||||
updateSignedPsbt: async function (psbtBase64) {
|
updateSignedPsbt: async function (psbtBase64) {
|
||||||
|
try {
|
||||||
|
this.showChecking = true
|
||||||
|
this.psbtBase64Signed = psbtBase64
|
||||||
|
|
||||||
console.log('### payment updateSignedPsbt psbtBase64', psbtBase64)
|
console.log('### payment updateSignedPsbt psbtBase64', psbtBase64)
|
||||||
|
|
||||||
const data = await this.extractTxFromPsbt(psbtBase64)
|
const data = await this.extractTxFromPsbt(psbtBase64)
|
||||||
|
this.showFinalTx = true
|
||||||
if (data) {
|
if (data) {
|
||||||
this.signedTx = JSON.parse(data.tx_json)
|
this.signedTx = JSON.parse(data.tx_json)
|
||||||
this.signedTxHex = data.tx_hex
|
this.signedTxHex = data.tx_hex
|
||||||
|
|
@ -234,6 +241,9 @@ async function payment(path) {
|
||||||
this.signedTx = null
|
this.signedTx = null
|
||||||
this.signedTxHex = null
|
this.signedTxHex = null
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
this.showChecking = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
extractTxFromPsbt: async function (psbtBase64) {
|
extractTxFromPsbt: async function (psbtBase64) {
|
||||||
console.log('### extractTxFromPsbt psbtBase64', psbtBase64)
|
console.log('### extractTxFromPsbt psbtBase64', psbtBase64)
|
||||||
|
|
@ -286,6 +296,8 @@ async function payment(path) {
|
||||||
caption: `${error}`,
|
caption: `${error}`,
|
||||||
timeout: 10000
|
timeout: 10000
|
||||||
})
|
})
|
||||||
|
} finally {
|
||||||
|
this.showFinalTx = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fetchTxHex: async function (txId) {
|
fetchTxHex: async function (txId) {
|
||||||
|
|
|
||||||
|
|
@ -307,6 +307,36 @@
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
||||||
|
<q-dialog v-model="hww.showSeedDialog" position="top">
|
||||||
|
<q-card class="q-pa-lg q-pt-xl">
|
||||||
|
<span>Check word at position {{hww.seedWordPosition}} on display</span>
|
||||||
|
|
||||||
|
<div class="row q-mt-lg">
|
||||||
|
<div class="col-4">
|
||||||
|
<q-btn
|
||||||
|
v-if="hww.seedWordPosition!== 1"
|
||||||
|
unelevated
|
||||||
|
color="primary"
|
||||||
|
@click="showPrevSeedWord"
|
||||||
|
>Prev</q-btn
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<q-btn
|
||||||
|
v-if="hww.seedWordPosition!== 24"
|
||||||
|
unelevated
|
||||||
|
color="primary"
|
||||||
|
@click="showNextSeedWord"
|
||||||
|
>Next</q-btn
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
|
||||||
<q-dialog v-model="hww.showRestoreDialog" position="top">
|
<q-dialog v-model="hww.showRestoreDialog" position="top">
|
||||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||||
<q-form @submit="hwwRestore" class="q-gutter-md">
|
<q-form @submit="hwwRestore" class="q-gutter-md">
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ async function serialSigner(path) {
|
||||||
loginResolve: null,
|
loginResolve: null,
|
||||||
psbtSentResolve: null,
|
psbtSentResolve: null,
|
||||||
xpubResolve: null,
|
xpubResolve: null,
|
||||||
|
seedWordPosition: 1,
|
||||||
|
showSeedDialog: false,
|
||||||
confirm: {
|
confirm: {
|
||||||
outputIndex: 0,
|
outputIndex: 0,
|
||||||
showFee: false
|
showFee: false
|
||||||
|
|
@ -402,13 +404,11 @@ async function serialSigner(path) {
|
||||||
handleSignResponse: function (res = '') {
|
handleSignResponse: function (res = '') {
|
||||||
this.hww.signingPsbt = false
|
this.hww.signingPsbt = false
|
||||||
this.updateSignedPsbt(res)
|
this.updateSignedPsbt(res)
|
||||||
if (this.hww.authenticated) {
|
|
||||||
this.$q.notify({
|
this.$q.notify({
|
||||||
type: 'positive',
|
type: 'positive',
|
||||||
message: 'Transaction Signed',
|
message: 'Transaction Signed',
|
||||||
timeout: 10000
|
timeout: 10000
|
||||||
})
|
})
|
||||||
}
|
|
||||||
},
|
},
|
||||||
hwwHelp: async function () {
|
hwwHelp: async function () {
|
||||||
try {
|
try {
|
||||||
|
|
@ -496,7 +496,11 @@ async function serialSigner(path) {
|
||||||
},
|
},
|
||||||
hwwShowSeed: async function () {
|
hwwShowSeed: async function () {
|
||||||
try {
|
try {
|
||||||
await this.writer.write(COMMAND_SEED + '\n')
|
this.hww.showSeedDialog = true
|
||||||
|
this.hww.seedWordPosition = 1
|
||||||
|
await this.writer.write(
|
||||||
|
COMMAND_SEED + ' ' + this.hww.seedWordPosition + '\n'
|
||||||
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$q.notify({
|
this.$q.notify({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
|
|
@ -506,6 +510,31 @@ async function serialSigner(path) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
showNextSeedWord: async function () {
|
||||||
|
this.hww.seedWordPosition++
|
||||||
|
await this.writer.write(
|
||||||
|
COMMAND_SEED + ' ' + this.hww.seedWordPosition + '\n'
|
||||||
|
)
|
||||||
|
},
|
||||||
|
showPrevSeedWord: async function () {
|
||||||
|
this.hww.seedWordPosition = Math.max(1, this.hww.seedWordPosition - 1)
|
||||||
|
console.log('### this.hww.seedWordPosition', this.hww.seedWordPosition)
|
||||||
|
await this.writer.write(
|
||||||
|
COMMAND_SEED + ' ' + this.hww.seedWordPosition + '\n'
|
||||||
|
)
|
||||||
|
},
|
||||||
|
handleShowSeedResponse: function (res = '') {
|
||||||
|
const args = res.trim().split(' ')
|
||||||
|
if (args.length < 2 || args[0].trim() !== '1') {
|
||||||
|
this.$q.notify({
|
||||||
|
type: 'warning',
|
||||||
|
message: 'Failed to show seed!',
|
||||||
|
caption: `${res}`,
|
||||||
|
timeout: 10000
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
},
|
||||||
hwwRestore: async function () {
|
hwwRestore: async function () {
|
||||||
try {
|
try {
|
||||||
await this.writer.write(
|
await this.writer.write(
|
||||||
|
|
@ -529,6 +558,7 @@ async function serialSigner(path) {
|
||||||
this.hww.showPassword = false
|
this.hww.showPassword = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateSignedPsbt: async function (value) {
|
updateSignedPsbt: async function (value) {
|
||||||
this.$emit('signed:psbt', value)
|
this.$emit('signed:psbt', value)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue