feat: propagate config update only when explicitly updated

This commit is contained in:
Vlad Stan 2022-08-01 10:45:31 +03:00
parent 657ed7a37c
commit 4671954896
11 changed files with 102 additions and 80 deletions

View File

@ -18,6 +18,7 @@ class WalletAccount(BaseModel):
address_no: int
balance: int
type: str = ""
network: str = "Mainnet"
@classmethod
def from_row(cls, row: Row) -> "WalletAccount":
@ -100,3 +101,4 @@ class Config(BaseModel):
receive_gap_limit = 20
change_gap_limit = 5
sats_denominated = True
network = "Mainnet"

View File

@ -35,13 +35,14 @@ async function feeRate(path) {
},
refreshRecommendedFees: async function () {
const {
bitcoin: {fees: feesAPI}
} = mempoolJS({
hostname: new URL(this.mempoolEndpoint).hostname
})
const fn = async () => feesAPI.getFeesRecommended()
const fn = async () => {
const {
bitcoin: {fees: feesAPI}
} = mempoolJS({
hostname: this.mempoolEndpoint
})
return feesAPI.getFeesRecommended()
}
this.recommededFees = await retryWithDelay(fn)
},
getFeeRateLabel: function (feeRate) {

View File

@ -2,7 +2,6 @@
<q-form @submit="checkAndSend" ref="paymentFormRef" class="q-gutter-md">
<q-card class="q-mt-lg">
<q-card-section>
<send-to
:data.sync="sendToList"
:fee-rate="feeRate"
@ -42,7 +41,11 @@
<div v-show="showCustomFee" class="row items-center no-wrap q-mt-md">
<div class="col-12">
<q-separator class="q-mb-md"></q-separator>
<fee-rate :fee-value="feeValue" :rate.sync="feeRate" :mempool-endpoint="mempoolEndpoint"></fee-rate>
<fee-rate
:fee-value="feeValue"
:rate.sync="feeRate"
:mempool-endpoint="mempoolEndpoint"
></fee-rate>
</div>
</div>
</q-card-section>

View File

@ -292,7 +292,7 @@ async function payment(path) {
const {
bitcoin: {transactions: transactionsAPI}
} = mempoolJS({
hostname: new URL(this.mempoolEndpoint).hostname
hostname: this.mempoolEndpoint
})
try {

View File

@ -2,12 +2,7 @@
<q-card>
<div class="row items-center no-wrap q-mb-md">
<div class="col-2 q-ml-lg">
<q-btn
unelevated
@click="config.show = true"
color="primary"
icon="settings"
>
<q-btn unelevated @click="show = true" color="primary" icon="settings">
</q-btn>
</div>
<div class="col-8">
@ -21,13 +16,13 @@
</div>
</q-card>
<q-dialog v-model="config.show" position="top">
<q-dialog v-model="show" position="top">
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
<q-form @submit="updateConfig" class="q-gutter-md">
<q-input
filled
dense
v-model.trim="config.data.mempool_endpoint"
v-model.trim="config.mempool_endpoint"
type="text"
label="Mempool Endpoint"
>
@ -36,7 +31,7 @@
<q-input
filled
dense
v-model.number="config.data.receive_gap_limit"
v-model.number="config.receive_gap_limit"
type="number"
min="0"
label="Receive Gap Limit"
@ -45,7 +40,7 @@
<q-input
filled
dense
v-model.number="config.data.change_gap_limit"
v-model.number="config.change_gap_limit"
type="number"
min="0"
label="Change Gap Limit"
@ -55,15 +50,15 @@
filled
dense
emit-value
v-model="config.data.network"
v-model="config.network"
:options="networOptions"
label="Network"
></q-select>
<q-toggle
:label="config.data.sats_denominated ? 'sats denominated' : 'BTC denominated'"
:label="config.sats_denominated ? 'sats denominated' : 'BTC denominated'"
color="secodary"
v-model="config.data.sats_denominated"
v-model="config.sats_denominated"
></q-toggle>
<div class="row q-mt-lg">
@ -71,7 +66,7 @@
unelevated
color="primary"
:disable="
!config.data.mempool_endpoint "
!config.mempool_endpoint "
type="submit"
>Update</q-btn
>

View File

@ -4,24 +4,51 @@ async function walletConfig(path) {
name: 'wallet-config',
template: t,
props: ['total', 'config', 'adminkey'],
props: ['total', 'config-data', 'adminkey'],
data: function () {
return {}
return {
networOptions: ['Mainnet', 'Testnet'],
internalConfig: {
mempool_endpoint: 'https://mempool.space',
receive_gap_limit: 20,
change_gap_limit: 5
},
show: false
}
},
computed: {
config: {
get() {
console.log('### get config', this.internalConfig)
return this.internalConfig
},
set(value) {
value.isLoaded = true
console.log('### set config', this.internalConfig)
this.internalConfig = JSON.parse(JSON.stringify(value))
this.$emit(
'update:config-data',
JSON.parse(JSON.stringify(this.internalConfig))
)
}
}
},
methods: {
satBtc(val, showUnit = true) {
return satOrBtc(val, showUnit, this.config.data.sats_denominated)
return satOrBtc(val, showUnit, this.config.sats_denominated)
},
updateConfig: async function () {
try {
await LNbits.api.request(
const {data} = await LNbits.api.request(
'PUT',
'/watchonly/api/v1/config',
this.adminkey,
this.config.data
this.config
)
this.config.show = false
this.show = false
this.config = data
} catch (error) {
LNbits.utils.notifyApiError(error)
}
@ -33,7 +60,7 @@ async function walletConfig(path) {
'/watchonly/api/v1/config',
this.adminkey
)
this.config.data = data
this.config = data
} catch (error) {
LNbits.utils.notifyApiError(error)
}

View File

@ -168,15 +168,6 @@
label="Account Extended Public Key; xpub, ypub, zpub; Bitcoin Descriptor"
></q-input>
<q-select
filled
dense
emit-value
v-model="formDialog.data.network"
:options="networOptions"
label="Network"
></q-select>
<div class="row q-mt-lg">
<q-btn
unelevated

View File

@ -14,7 +14,6 @@ async function walletList(path) {
data: {}
},
filter: '',
networOptions: ['Mainnet', 'Testnet'],
walletsTable: {
columns: [
{

View File

@ -31,15 +31,7 @@ const watchOnly = async () => {
tab: 'addresses',
config: {
data: {
mempool_endpoint: 'https://mempool.space',
receive_gap_limit: 20,
change_gap_limit: 5
},
show: false
},
config: {sats_denominated: true},
qrCodeDialog: {
show: false,
@ -58,6 +50,16 @@ const watchOnly = async () => {
fetchedUtxos: false
}
},
computed: {
mempoolHostname() {
if (!this.config.isLoaded) return
const hostname = new URL(this.config.mempool_endpoint).hostname
if (this.config.network === 'testnet') {
hostname += '/testnet'
}
return hostname
}
},
methods: {
updateAmountForAddress: async function (addressData, amount = 0) {
@ -321,31 +323,32 @@ const watchOnly = async () => {
//################### MEMPOOL API ###################
getAddressTxsDelayed: async function (addrData) {
const {
bitcoin: {addresses: addressesAPI}
} = mempoolJS({
hostname: new URL(this.config.data.mempool_endpoint).hostname
})
const fn = async () =>
addressesAPI.getAddressTxs({
const fn = async () => {
const {
bitcoin: {addresses: addressesAPI}
} = mempoolJS({
hostname: this.mempoolHostname
})
return addressesAPI.getAddressTxs({
address: addrData.address
})
}
const addressTxs = await retryWithDelay(fn)
return this.addressHistoryFromTxs(addrData, addressTxs)
},
getAddressTxsUtxoDelayed: async function (address) {
const {
bitcoin: {addresses: addressesAPI}
} = mempoolJS({
hostname: new URL(this.config.data.mempool_endpoint).hostname
})
const fn = async () => {
const {
bitcoin: {addresses: addressesAPI}
} = mempoolJS({
hostname: this.mempoolHostname
})
const fn = async () =>
addressesAPI.getAddressTxsUtxo({
return addressesAPI.getAddressTxsUtxo({
address
})
}
return retryWithDelay(fn)
},

View File

@ -4,13 +4,13 @@
<div class="col-12 col-md-7 q-gutter-y-md">
<wallet-config
:total="utxos.total"
:config="config"
:config-data.sync="config"
:adminkey="g.user.wallets[0].adminkey"
>
<template v-slot:serial>
<serial-signer
ref="serialSigner"
:sats-denominated="config.data.sats_denominated"
:sats-denominated="config.sats_denominated"
@signed:psbt="updateSignedPsbt"
></serial-signer>
</template>
@ -19,7 +19,7 @@
<wallet-list
:adminkey="g.user.wallets[0].adminkey"
:inkey="g.user.wallets[0].inkey"
:sats-denominated="config.data.sats_denominated"
:sats-denominated="config.sats_denominated"
:addresses="addresses"
@accounts-update="updateAccounts"
@new-receive-address="showAddressDetails"
@ -76,7 +76,7 @@
</div>
</q-card>
<q-card>
<q-card v-if="config.isLoaded">
<q-card-section v-show="!showPayment">
<q-tabs v-model="tab" no-caps class="bg-dark text-white shadow-2">
<q-tab name="addresses" label="Addresses"></q-tab>
@ -89,8 +89,8 @@
ref="addressList"
:addresses="addresses"
:accounts="walletAccounts"
:mempool-endpoint="config.data.mempool_endpoint"
:sats-denominated="config.data.sats_denominated"
:mempool-endpoint="mempoolHostname"
:sats-denominated="config.sats_denominated"
@scan:address="scanAddress"
@show-address-details="showAddressDetails"
@update:addresses="initUtxos"
@ -101,29 +101,28 @@
<q-tab-panel name="history">
<history
:history="history"
:mempool-endpoint="config.data.mempool_endpoint"
:sats-denominated="config.data.sats_denominated"
:mempool-endpoint="mempoolHostname"
:sats-denominated="config.sats_denominated"
></history>
</q-tab-panel>
<q-tab-panel name="utxos">
<utxo-list
:utxos="utxos.data"
:mempool-endpoint="config.data.mempool_endpoint"
:sats-denominated="config.data.sats_denominated"
:mempool-endpoint="mempoolHostname"
:sats-denominated="config.sats_denominated"
></utxo-list>
</q-tab-panel>
</q-tab-panels>
</q-card-section>
</q-card>
<div class="q-pt-sm">
{{config.data.mempool_endpoint}}
<div v-if="config.isLoaded" class="q-pt-sm">
<payment
ref="paymentRef"
v-show="showPayment"
:accounts="walletAccounts"
:addresses="addresses"
:utxos="utxos.data"
:mempool-endpoint="config.data.mempool_endpoint"
:mempool-endpoint="mempoolHostname"
:adminkey="g.user.wallets[0].adminkey"
:serial-signer-ref="$refs.serialSigner"
></payment>
@ -168,7 +167,7 @@
size="ms"
icon="launch"
type="a"
:href="config.mempool_endpoint + '/address/' + currentAddress.address"
:href="mempoolHostname + '/address/' + currentAddress.address"
target="_blank"
></q-btn>
</p>

View File

@ -233,8 +233,9 @@ async def api_psbt_create(
descriptors[masterpub.fingerprint] = parse_key(masterpub.public_key)
inputs_extra = []
bip32_derivations = {}
for i, inp in enumerate(data.inputs):
bip32_derivations = {}
descriptor = descriptors[inp.masterpub_fingerprint][0]
d = descriptor.derive(inp.address_index, inp.branch_index)
for k in d.keys:
@ -291,6 +292,7 @@ async def api_psbt_extract_tx(
if not final_psbt:
raise ValueError("PSBT cannot be finalized!")
res.tx_hex = final_psbt.to_string()
print('### hex', res.tx_hex)
transaction = Transaction.from_string(res.tx_hex)
tx = {