refactor: payment: first migration
This commit is contained in:
parent
3765900be0
commit
5638bca2d7
5 changed files with 259 additions and 258 deletions
|
|
@ -0,0 +1,140 @@
|
||||||
|
<div>
|
||||||
|
<q-form @submit="createPsbt" class="q-gutter-md">
|
||||||
|
<q-tabs v-model="paymentTab" no-caps class="bg-dark text-white shadow-2">
|
||||||
|
<q-tab name="destination" label="Send To"></q-tab>
|
||||||
|
<q-tab name="coinControl" label="Coin Control"></q-tab>
|
||||||
|
</q-tabs>
|
||||||
|
<q-tab-panels v-model="paymentTab">
|
||||||
|
<q-tab-panel name="destination">
|
||||||
|
<q-card>
|
||||||
|
<q-card-section>
|
||||||
|
{{sendToList}}
|
||||||
|
<send-to
|
||||||
|
:data.sync="sendToList"
|
||||||
|
:tx:size="txSizeNoChange"
|
||||||
|
:sats-denominated="sats_denominated"
|
||||||
|
></send-to>
|
||||||
|
<!-- <div class="row items-center no-wrap q-mb-md">
|
||||||
|
<div class="col-12">
|
||||||
|
<q-table
|
||||||
|
:columns="summaryTable.columns"
|
||||||
|
:data="summary.data"
|
||||||
|
hide-bottom
|
||||||
|
>
|
||||||
|
<template v-slot:body="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td key="totalInputs" :props="props">
|
||||||
|
<q-badge class="text-subtitle2" color="green">
|
||||||
|
{{satBtc(getTotalSelectedUtxoAmount())}}
|
||||||
|
</q-badge>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="totalOutputs" :props="props">
|
||||||
|
<q-badge class="text-subtitle2" color="blue">
|
||||||
|
{{satBtc(getTotalPaymentAmount())}}
|
||||||
|
</q-badge>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="fees" :props="props">
|
||||||
|
<q-badge class="text-subtitle2" color="orange">
|
||||||
|
{{satBtc(feeValue)}}
|
||||||
|
</q-badge>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="change" :props="props">
|
||||||
|
<q-badge
|
||||||
|
v-if="payment.changeAmount >= 0"
|
||||||
|
class="text-subtitle2"
|
||||||
|
color="green"
|
||||||
|
>
|
||||||
|
{{payment.changeAmount ?
|
||||||
|
satBtc(payment.changeAmount): 'no change'}}
|
||||||
|
</q-badge>
|
||||||
|
<q-badge
|
||||||
|
v-if="payment.changeAmount > 0 && payment.changeAmount < DUST_LIMIT"
|
||||||
|
color="red"
|
||||||
|
>
|
||||||
|
Below dust limit. Will be used as feee.
|
||||||
|
</q-badge>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div
|
||||||
|
v-if="payment.changeAmount < 0"
|
||||||
|
class="row items-center no-wrap q-mb-md"
|
||||||
|
>
|
||||||
|
<div class="col-12">
|
||||||
|
<q-badge
|
||||||
|
class="text-subtitle2 float-left"
|
||||||
|
color="yellow"
|
||||||
|
text-color="black"
|
||||||
|
>
|
||||||
|
The payed amount is higher than the selected amount!
|
||||||
|
</q-badge>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
<div class="row items-center no-wrap q-mb-md q-pt-lg">
|
||||||
|
<div class="col-12">
|
||||||
|
<q-toggle
|
||||||
|
label="Custom Fee"
|
||||||
|
color="secodary"
|
||||||
|
v-model="showCustomFee"
|
||||||
|
></q-toggle>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-card v-show="showCustomFee">
|
||||||
|
<q-card-section>
|
||||||
|
<div class="row items-center no-wrap q-mb-md q-pt-md">
|
||||||
|
<div class="col-12">
|
||||||
|
{{feeRate}}
|
||||||
|
<fee-rate :totalfee="feeValue" :rate.sync="feeRate"></fee-rate>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
</q-tab-panel>
|
||||||
|
|
||||||
|
<q-tab-panel name="coinControl">
|
||||||
|
<utxo-list
|
||||||
|
:utxos="utxos.data"
|
||||||
|
:selectable="true"
|
||||||
|
:payed-amount="getTotalPaymentAmount()"
|
||||||
|
:mempool_endpoint="mempool_endpoint"
|
||||||
|
:sats-denominated="sats_denominated"
|
||||||
|
></utxo-list>
|
||||||
|
<div class="row items-center no-wrap q-mb-md q-pt-lg">
|
||||||
|
<div class="col-2 q-pr-lg">Change Account:</div>
|
||||||
|
<div class="col-3 q-pr-lg">
|
||||||
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
v-model="changeWallet"
|
||||||
|
:options="accounts"
|
||||||
|
@input="selectChangeAddress"
|
||||||
|
:rules="[val => !!val || 'Field is required']"
|
||||||
|
label="Wallet Account"
|
||||||
|
></q-select>
|
||||||
|
</div>
|
||||||
|
<div class="col-7">
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
readonly
|
||||||
|
v-model.trim="changeAddress.address"
|
||||||
|
:rules="[val => !!val || 'Field is required']"
|
||||||
|
type="text"
|
||||||
|
label="Change Address"
|
||||||
|
></q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-tab-panel>
|
||||||
|
</q-tab-panels>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
@ -1,18 +1,125 @@
|
||||||
async function payment(path) {
|
async function payment(path) {
|
||||||
const template = await loadTemplateAsync(path)
|
const t = await loadTemplateAsync(path)
|
||||||
|
console.log('### template', path, t)
|
||||||
Vue.component('payment', {
|
Vue.component('payment', {
|
||||||
name: 'payment',
|
name: 'payment',
|
||||||
template,
|
template: t,
|
||||||
|
|
||||||
props: ['mempool_endpoint', 'sats_denominated'],
|
props: ['accounts', 'utxos', 'mempool_endpoint', 'sats_denominated'],
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
return {}
|
return {
|
||||||
|
paymentTab: 'destination',
|
||||||
|
sendToList: [],
|
||||||
|
changeWallet: null,
|
||||||
|
changeAddress: {},
|
||||||
|
changeAmount: 0,
|
||||||
|
showCustomFee: false,
|
||||||
|
feeRate: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
txSize: function () {
|
||||||
|
const tx = this.createTx()
|
||||||
|
return Math.round(txSize(tx))
|
||||||
|
},
|
||||||
|
txSizeNoChange: function () {
|
||||||
|
const tx = this.createTx(true)
|
||||||
|
return Math.round(txSize(tx))
|
||||||
|
},
|
||||||
|
feeValue: function () {
|
||||||
|
return this.feeRate * this.txSize
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
satBtc(val, showUnit = true) {
|
satBtc(val, showUnit = true) {
|
||||||
return satOrBtc(val, showUnit, this['sats_denominated'])
|
return satOrBtc(val, showUnit, this['sats_denominated'])
|
||||||
|
},
|
||||||
|
createPsbt: async function () {
|
||||||
|
const wallet = this.g.user.wallets[0]
|
||||||
|
try {
|
||||||
|
// this.computeFee(this.feeRate)
|
||||||
|
const tx = this.createTx()
|
||||||
|
// txSize(tx)
|
||||||
|
for (const input of tx.inputs) {
|
||||||
|
input.tx_hex = await this.fetchTxHex(input.tx_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.payment.tx = tx
|
||||||
|
const {data} = await LNbits.api.request(
|
||||||
|
'POST',
|
||||||
|
'/watchonly/api/v1/psbt',
|
||||||
|
wallet.adminkey,
|
||||||
|
tx
|
||||||
|
)
|
||||||
|
|
||||||
|
this.payment.psbtBase64 = data
|
||||||
|
} catch (err) {
|
||||||
|
LNbits.utils.notifyApiError(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createTx: function (excludeChange = false) {
|
||||||
|
const tx = {
|
||||||
|
fee_rate: this.feeRate,
|
||||||
|
// tx_size: this.payment.txSize, ???
|
||||||
|
masterpubs: this.accounts.map(w => ({
|
||||||
|
public_key: w.masterpub,
|
||||||
|
fingerprint: w.fingerprint
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
tx.inputs = this.utxos.data
|
||||||
|
.filter(utxo => utxo.selected)
|
||||||
|
.map(mapUtxoToPsbtInput)
|
||||||
|
.sort((a, b) =>
|
||||||
|
a.tx_id < b.tx_id ? -1 : a.tx_id > b.tx_id ? 1 : a.vout - b.vout
|
||||||
|
)
|
||||||
|
|
||||||
|
tx.outputs = this.sendToList.map(out => ({
|
||||||
|
address: out.address,
|
||||||
|
amount: out.amount
|
||||||
|
}))
|
||||||
|
|
||||||
|
if (excludeChange) {
|
||||||
|
this.changeAmount = 0
|
||||||
|
} else {
|
||||||
|
const change = this.createChangeOutput()
|
||||||
|
this.changeAmount = change.amount // todo: compute separately
|
||||||
|
if (change.amount >= this.DUST_LIMIT) {
|
||||||
|
tx.outputs.push(change)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Only sort by amount on UI level (no lib for address decode)
|
||||||
|
// Should sort by scriptPubKey (as byte array) on the backend
|
||||||
|
// todo: just shuffle
|
||||||
|
tx.outputs.sort((a, b) => a.amount - b.amount)
|
||||||
|
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
createChangeOutput: function () {
|
||||||
|
const change = this.changeAddress
|
||||||
|
// const inputAmount = this.getTotalSelectedUtxoAmount() // todo: set amount separately
|
||||||
|
// const payedAmount = this.getTotalPaymentAmount()
|
||||||
|
const walletAcount =
|
||||||
|
this.accounts.find(w => w.id === change.wallet) || {}
|
||||||
|
|
||||||
|
return {
|
||||||
|
address: change.address,
|
||||||
|
// amount: inputAmount - payedAmount - this.feeValue,
|
||||||
|
addressIndex: change.addressIndex,
|
||||||
|
addressIndex: change.addressIndex,
|
||||||
|
masterpub_fingerprint: walletAcount.fingerprint
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectChangeAddress: function (wallet = {}) {
|
||||||
|
this.changeAddress =
|
||||||
|
this.addresses.find(
|
||||||
|
a => a.wallet === wallet.id && a.isChange && !a.hasActivity
|
||||||
|
) || {}
|
||||||
|
},
|
||||||
|
getTotalPaymentAmount: function () {
|
||||||
|
return this.sendToList.reduce((t, a) => t + (a.amount || 0), 0)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ const watchOnly = async () => {
|
||||||
await sendTo('static/components/send-to/send-to.html')
|
await sendTo('static/components/send-to/send-to.html')
|
||||||
await payment('static/components/payment/payment.html')
|
await payment('static/components/payment/payment.html')
|
||||||
|
|
||||||
|
//emplate static/components/payment/payment.html
|
||||||
|
//lnbits/extensions/watchonly/static/components/payment/payment.html
|
||||||
|
|
||||||
Vue.filter('reverse', function (value) {
|
Vue.filter('reverse', function (value) {
|
||||||
// slice to make a copy of array, then reverse the copy
|
// slice to make a copy of array, then reverse the copy
|
||||||
return value.slice().reverse()
|
return value.slice().reverse()
|
||||||
|
|
@ -32,7 +35,6 @@ const watchOnly = async () => {
|
||||||
currentAddress: null,
|
currentAddress: null,
|
||||||
|
|
||||||
tab: 'addresses',
|
tab: 'addresses',
|
||||||
paymentTab: 'destination',
|
|
||||||
|
|
||||||
config: {
|
config: {
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -84,24 +86,7 @@ const watchOnly = async () => {
|
||||||
|
|
||||||
showAddress: false,
|
showAddress: false,
|
||||||
addressNote: '',
|
addressNote: '',
|
||||||
showPayment: false,
|
showPayment: false
|
||||||
showCustomFee: false,
|
|
||||||
feeRate: 1,
|
|
||||||
sendToList: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
txSize: function() {
|
|
||||||
const tx = this.createTx()
|
|
||||||
return Math.round(txSize(tx))
|
|
||||||
},
|
|
||||||
txSizeNoChange: function() {
|
|
||||||
const tx = this.createTx(true)
|
|
||||||
return Math.round(txSize(tx))
|
|
||||||
},
|
|
||||||
feeValue: function(){
|
|
||||||
return this.feeRate * this.txSize
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -205,58 +190,6 @@ const watchOnly = async () => {
|
||||||
},
|
},
|
||||||
|
|
||||||
//################### PAYMENT ###################
|
//################### PAYMENT ###################
|
||||||
createTx: function (excludeChange = false) {
|
|
||||||
const tx = {
|
|
||||||
fee_rate: this.feeRate,
|
|
||||||
tx_size: this.payment.txSize,
|
|
||||||
masterpubs: this.walletAccounts.map(w => ({
|
|
||||||
public_key: w.masterpub,
|
|
||||||
fingerprint: w.fingerprint
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
tx.inputs = this.utxos.data
|
|
||||||
.filter(utxo => utxo.selected)
|
|
||||||
.map(mapUtxoToPsbtInput)
|
|
||||||
.sort((a, b) =>
|
|
||||||
a.tx_id < b.tx_id ? -1 : a.tx_id > b.tx_id ? 1 : a.vout - b.vout
|
|
||||||
)
|
|
||||||
|
|
||||||
tx.outputs = this.sendToList.map(out => ({
|
|
||||||
address: out.address,
|
|
||||||
amount: out.amount
|
|
||||||
}))
|
|
||||||
|
|
||||||
if (excludeChange) {
|
|
||||||
this.payment.changeAmount = 0
|
|
||||||
} else {
|
|
||||||
const change = this.createChangeOutput()
|
|
||||||
this.payment.changeAmount = change.amount
|
|
||||||
if (change.amount >= this.DUST_LIMIT) {
|
|
||||||
tx.outputs.push(change)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Only sort by amount on UI level (no lib for address decode)
|
|
||||||
// Should sort by scriptPubKey (as byte array) on the backend
|
|
||||||
// todo: just shuffle
|
|
||||||
tx.outputs.sort((a, b) => a.amount - b.amount)
|
|
||||||
|
|
||||||
return tx
|
|
||||||
},
|
|
||||||
createChangeOutput: function () {
|
|
||||||
const change = this.payment.changeAddress
|
|
||||||
// const inputAmount = this.getTotalSelectedUtxoAmount() // todo: set amount separately
|
|
||||||
// const payedAmount = this.getTotalPaymentAmount()
|
|
||||||
const walletAcount =
|
|
||||||
this.walletAccounts.find(w => w.id === change.wallet) || {}
|
|
||||||
|
|
||||||
return {
|
|
||||||
address: change.address,
|
|
||||||
// amount: inputAmount - payedAmount - this.feeValue,
|
|
||||||
addressIndex: change.addressIndex,
|
|
||||||
addressIndex: change.addressIndex,
|
|
||||||
masterpub_fingerprint: walletAcount.fingerprint
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
initPaymentData: async function () {
|
initPaymentData: async function () {
|
||||||
if (!this.payment.show) return
|
if (!this.payment.show) return
|
||||||
|
|
@ -265,19 +198,8 @@ const watchOnly = async () => {
|
||||||
this.payment.showAdvanced = false
|
this.payment.showAdvanced = false
|
||||||
this.payment.changeWallet = this.walletAccounts[0]
|
this.payment.changeWallet = this.walletAccounts[0]
|
||||||
this.selectChangeAddress(this.payment.changeWallet)
|
this.selectChangeAddress(this.payment.changeWallet)
|
||||||
|
|
||||||
this.payment.feeRate = this.payment.recommededFees.halfHourFee
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getTotalPaymentAmount: function () {
|
|
||||||
return this.payment.data.reduce((t, a) => t + (a.amount || 0), 0)
|
|
||||||
},
|
|
||||||
selectChangeAddress: function (wallet = {}) {
|
|
||||||
this.payment.changeAddress =
|
|
||||||
this.addresses.find(
|
|
||||||
a => a.wallet === wallet.id && a.isChange && !a.hasActivity
|
|
||||||
) || {}
|
|
||||||
},
|
|
||||||
goToPaymentView: async function () {
|
goToPaymentView: async function () {
|
||||||
// this.payment.show = true
|
// this.payment.show = true
|
||||||
this.showPayment = true
|
this.showPayment = true
|
||||||
|
|
@ -286,29 +208,7 @@ const watchOnly = async () => {
|
||||||
},
|
},
|
||||||
|
|
||||||
//################### PSBT ###################
|
//################### PSBT ###################
|
||||||
createPsbt: async function () {
|
|
||||||
const wallet = this.g.user.wallets[0]
|
|
||||||
try {
|
|
||||||
// this.computeFee(this.feeRate)
|
|
||||||
const tx = this.createTx()
|
|
||||||
// txSize(tx)
|
|
||||||
for (const input of tx.inputs) {
|
|
||||||
input.tx_hex = await this.fetchTxHex(input.tx_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.payment.tx = tx
|
|
||||||
const {data} = await LNbits.api.request(
|
|
||||||
'POST',
|
|
||||||
'/watchonly/api/v1/psbt',
|
|
||||||
wallet.adminkey,
|
|
||||||
tx
|
|
||||||
)
|
|
||||||
|
|
||||||
this.payment.psbtBase64 = data
|
|
||||||
} catch (err) {
|
|
||||||
LNbits.utils.notifyApiError(err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
extractTxFromPsbt: async function (psbtBase64) {
|
extractTxFromPsbt: async function (psbtBase64) {
|
||||||
const wallet = this.g.user.wallets[0]
|
const wallet = this.g.user.wallets[0]
|
||||||
try {
|
try {
|
||||||
|
|
@ -789,9 +689,7 @@ const watchOnly = async () => {
|
||||||
this.utxos.data = []
|
this.utxos.data = []
|
||||||
this.utxos.total = 0
|
this.utxos.total = 0
|
||||||
this.history = []
|
this.history = []
|
||||||
console.log('### scanAddressWithAmount1', this.addresses)
|
|
||||||
const addresses = this.addresses.filter(a => a.hasActivity)
|
const addresses = this.addresses.filter(a => a.hasActivity)
|
||||||
console.log('### scanAddressWithAmount2', addresses)
|
|
||||||
await this.updateUtxosForAddresses(addresses)
|
await this.updateUtxosForAddresses(addresses)
|
||||||
},
|
},
|
||||||
scanAddress: async function (addressData) {
|
scanAddress: async function (addressData) {
|
||||||
|
|
@ -954,7 +852,7 @@ const watchOnly = async () => {
|
||||||
handleAddressesUpdated: async function (addresses) {
|
handleAddressesUpdated: async function (addresses) {
|
||||||
this.addresses = addresses
|
this.addresses = addresses
|
||||||
await this.scanAddressWithAmount()
|
await this.scanAddressWithAmount()
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
if (this.g.user.wallets.length) {
|
if (this.g.user.wallets.length) {
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,7 @@ const tableData = {
|
||||||
},
|
},
|
||||||
payment: {
|
payment: {
|
||||||
data: [{address: '', amount: undefined}], // todo: remove
|
data: [{address: '', amount: undefined}], // todo: remove
|
||||||
changeWallet: null,
|
|
||||||
changeAddress: {},
|
|
||||||
changeAmount: 0,
|
changeAmount: 0,
|
||||||
|
|
||||||
fee: 0,
|
fee: 0,
|
||||||
|
|
|
||||||
|
|
@ -493,150 +493,7 @@
|
||||||
</q-tab-panels>
|
</q-tab-panels>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section v-show="showPayment">
|
<q-card-section v-show="showPayment">
|
||||||
<q-form @submit="createPsbt" class="q-gutter-md">
|
<payment :accounts="walletAccounts" :utxos="utxos"></payment>
|
||||||
<q-tabs
|
|
||||||
v-model="paymentTab"
|
|
||||||
no-caps
|
|
||||||
class="bg-dark text-white shadow-2"
|
|
||||||
>
|
|
||||||
<q-tab name="destination" label="Send To"></q-tab>
|
|
||||||
<q-tab name="coinControl" label="Coin Control"></q-tab>
|
|
||||||
</q-tabs>
|
|
||||||
<q-tab-panels v-model="paymentTab">
|
|
||||||
<q-tab-panel name="destination">
|
|
||||||
<q-card>
|
|
||||||
<q-card-section>
|
|
||||||
{{sendToList}}
|
|
||||||
<send-to
|
|
||||||
:data.sync="sendToList"
|
|
||||||
:tx:size="txSizeNoChange"
|
|
||||||
:sats-denominated="config.data.sats_denominated"
|
|
||||||
></send-to>
|
|
||||||
<!-- <div class="row items-center no-wrap q-mb-md">
|
|
||||||
<div class="col-12">
|
|
||||||
<q-table
|
|
||||||
:columns="summaryTable.columns"
|
|
||||||
:data="summary.data"
|
|
||||||
hide-bottom
|
|
||||||
>
|
|
||||||
<template v-slot:body="props">
|
|
||||||
<q-tr :props="props">
|
|
||||||
<q-td key="totalInputs" :props="props">
|
|
||||||
<q-badge class="text-subtitle2" color="green">
|
|
||||||
{{satBtc(getTotalSelectedUtxoAmount())}}
|
|
||||||
</q-badge>
|
|
||||||
</q-td>
|
|
||||||
<q-td key="totalOutputs" :props="props">
|
|
||||||
<q-badge class="text-subtitle2" color="blue">
|
|
||||||
{{satBtc(getTotalPaymentAmount())}}
|
|
||||||
</q-badge>
|
|
||||||
</q-td>
|
|
||||||
<q-td key="fees" :props="props">
|
|
||||||
<q-badge class="text-subtitle2" color="orange">
|
|
||||||
{{satBtc(feeValue)}}
|
|
||||||
</q-badge>
|
|
||||||
</q-td>
|
|
||||||
<q-td key="change" :props="props">
|
|
||||||
<q-badge
|
|
||||||
v-if="payment.changeAmount >= 0"
|
|
||||||
class="text-subtitle2"
|
|
||||||
color="green"
|
|
||||||
>
|
|
||||||
{{payment.changeAmount ?
|
|
||||||
satBtc(payment.changeAmount): 'no change'}}
|
|
||||||
</q-badge>
|
|
||||||
<q-badge
|
|
||||||
v-if="payment.changeAmount > 0 && payment.changeAmount < DUST_LIMIT"
|
|
||||||
color="red"
|
|
||||||
>
|
|
||||||
Below dust limit. Will be used as feee.
|
|
||||||
</q-badge>
|
|
||||||
</q-td>
|
|
||||||
</q-tr>
|
|
||||||
</template>
|
|
||||||
</q-table>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<div
|
|
||||||
v-if="payment.changeAmount < 0"
|
|
||||||
class="row items-center no-wrap q-mb-md"
|
|
||||||
>
|
|
||||||
<div class="col-12">
|
|
||||||
<q-badge
|
|
||||||
class="text-subtitle2 float-left"
|
|
||||||
color="yellow"
|
|
||||||
text-color="black"
|
|
||||||
>
|
|
||||||
The payed amount is higher than the selected amount!
|
|
||||||
</q-badge>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
<div class="row items-center no-wrap q-mb-md q-pt-lg">
|
|
||||||
<div class="col-12">
|
|
||||||
<q-toggle
|
|
||||||
label="Custom Fee"
|
|
||||||
color="secodary"
|
|
||||||
v-model="showCustomFee"
|
|
||||||
></q-toggle>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<q-card v-show="showCustomFee">
|
|
||||||
<q-card-section>
|
|
||||||
<div class="row items-center no-wrap q-mb-md q-pt-md">
|
|
||||||
<div class="col-12">
|
|
||||||
{{feeRate}}
|
|
||||||
<fee-rate
|
|
||||||
:totalfee="feeValue"
|
|
||||||
:rate.sync="feeRate"
|
|
||||||
></fee-rate>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
</q-tab-panel>
|
|
||||||
|
|
||||||
<q-tab-panel name="coinControl">
|
|
||||||
<utxo-list
|
|
||||||
:utxos="utxos.data"
|
|
||||||
:selectable="true"
|
|
||||||
:payed-amount="getTotalPaymentAmount()"
|
|
||||||
:mempool_endpoint="config.data.mempool_endpoint"
|
|
||||||
:sats-denominated="config.data.sats_denominated"
|
|
||||||
></utxo-list>
|
|
||||||
<div class="row items-center no-wrap q-mb-md q-pt-lg">
|
|
||||||
<div class="col-2 q-pr-lg">Change Account:</div>
|
|
||||||
<div class="col-3 q-pr-lg">
|
|
||||||
<q-select
|
|
||||||
filled
|
|
||||||
dense
|
|
||||||
emit-value
|
|
||||||
v-model="payment.changeWallet"
|
|
||||||
:options="walletAccounts"
|
|
||||||
@input="selectChangeAddress"
|
|
||||||
:rules="[val => !!val || 'Field is required']"
|
|
||||||
label="Wallet Account"
|
|
||||||
></q-select>
|
|
||||||
</div>
|
|
||||||
<div class="col-7">
|
|
||||||
<q-input
|
|
||||||
filled
|
|
||||||
dense
|
|
||||||
readonly
|
|
||||||
v-model.trim="payment.changeAddress.address"
|
|
||||||
:rules="[val => !!val || 'Field is required']"
|
|
||||||
type="text"
|
|
||||||
label="Change Address"
|
|
||||||
></q-input>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</q-tab-panel>
|
|
||||||
</q-tab-panels>
|
|
||||||
</q-form>
|
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -870,4 +727,4 @@
|
||||||
<script src="{{ url_for('watchonly_static', path='components/send-to/send-to.js') }}"></script>
|
<script src="{{ url_for('watchonly_static', path='components/send-to/send-to.js') }}"></script>
|
||||||
<script src="{{ url_for('watchonly_static', path='components/payment/payment.js') }}"></script>
|
<script src="{{ url_for('watchonly_static', path='components/payment/payment.js') }}"></script>
|
||||||
<script src="{{ url_for('watchonly_static', path='js/index.js') }}"></script>
|
<script src="{{ url_for('watchonly_static', path='js/index.js') }}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue