diff --git a/lnbits/extensions/watchonly/models.py b/lnbits/extensions/watchonly/models.py index 0797cdda..1bbb8271 100644 --- a/lnbits/extensions/watchonly/models.py +++ b/lnbits/extensions/watchonly/models.py @@ -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" diff --git a/lnbits/extensions/watchonly/static/components/fee-rate/fee-rate.js b/lnbits/extensions/watchonly/static/components/fee-rate/fee-rate.js index f79300ec..7a920a9a 100644 --- a/lnbits/extensions/watchonly/static/components/fee-rate/fee-rate.js +++ b/lnbits/extensions/watchonly/static/components/fee-rate/fee-rate.js @@ -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) { diff --git a/lnbits/extensions/watchonly/static/components/payment/payment.html b/lnbits/extensions/watchonly/static/components/payment/payment.html index 36cde627..093267b5 100644 --- a/lnbits/extensions/watchonly/static/components/payment/payment.html +++ b/lnbits/extensions/watchonly/static/components/payment/payment.html @@ -2,7 +2,6 @@ -
- +
diff --git a/lnbits/extensions/watchonly/static/components/payment/payment.js b/lnbits/extensions/watchonly/static/components/payment/payment.js index 1c3d09ac..89b95cf9 100644 --- a/lnbits/extensions/watchonly/static/components/payment/payment.js +++ b/lnbits/extensions/watchonly/static/components/payment/payment.js @@ -292,7 +292,7 @@ async function payment(path) { const { bitcoin: {transactions: transactionsAPI} } = mempoolJS({ - hostname: new URL(this.mempoolEndpoint).hostname + hostname: this.mempoolEndpoint }) try { diff --git a/lnbits/extensions/watchonly/static/components/wallet-config/wallet-config.html b/lnbits/extensions/watchonly/static/components/wallet-config/wallet-config.html index ce1ebe2d..61a35362 100644 --- a/lnbits/extensions/watchonly/static/components/wallet-config/wallet-config.html +++ b/lnbits/extensions/watchonly/static/components/wallet-config/wallet-config.html @@ -2,12 +2,7 @@
- +
@@ -21,13 +16,13 @@
- + @@ -36,7 +31,7 @@
@@ -71,7 +66,7 @@ unelevated color="primary" :disable=" - !config.data.mempool_endpoint " + !config.mempool_endpoint " type="submit" >Update diff --git a/lnbits/extensions/watchonly/static/components/wallet-config/wallet-config.js b/lnbits/extensions/watchonly/static/components/wallet-config/wallet-config.js index 45ea1dab..42ebac11 100644 --- a/lnbits/extensions/watchonly/static/components/wallet-config/wallet-config.js +++ b/lnbits/extensions/watchonly/static/components/wallet-config/wallet-config.js @@ -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) } diff --git a/lnbits/extensions/watchonly/static/components/wallet-list/wallet-list.html b/lnbits/extensions/watchonly/static/components/wallet-list/wallet-list.html index a17f13b9..950bceeb 100644 --- a/lnbits/extensions/watchonly/static/components/wallet-list/wallet-list.html +++ b/lnbits/extensions/watchonly/static/components/wallet-list/wallet-list.html @@ -168,15 +168,6 @@ label="Account Extended Public Key; xpub, ypub, zpub; Bitcoin Descriptor" > - -
{ 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) }, diff --git a/lnbits/extensions/watchonly/templates/watchonly/index.html b/lnbits/extensions/watchonly/templates/watchonly/index.html index a29535ed..38746bbf 100644 --- a/lnbits/extensions/watchonly/templates/watchonly/index.html +++ b/lnbits/extensions/watchonly/templates/watchonly/index.html @@ -4,13 +4,13 @@
@@ -19,7 +19,7 @@ - + @@ -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 @@ -
- {{config.data.mempool_endpoint}} +
@@ -168,7 +167,7 @@ size="ms" icon="launch" type="a" - :href="config.mempool_endpoint + '/address/' + currentAddress.address" + :href="mempoolHostname + '/address/' + currentAddress.address" target="_blank" >

diff --git a/lnbits/extensions/watchonly/views_api.py b/lnbits/extensions/watchonly/views_api.py index db7248c4..4d540473 100644 --- a/lnbits/extensions/watchonly/views_api.py +++ b/lnbits/extensions/watchonly/views_api.py @@ -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 = {