From 3ad0463dfea9f5822a48ccebd9e28510dae3901b Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 2 Dec 2022 13:40:59 +0200 Subject: [PATCH 1/4] feat: extract utxos. from PSBT --- lnbits/extensions/watchonly/models.py | 10 +++++----- lnbits/extensions/watchonly/views_api.py | 22 ++++++++++++++++++++-- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lnbits/extensions/watchonly/models.py b/lnbits/extensions/watchonly/models.py index d8c278ff..c6265d6c 100644 --- a/lnbits/extensions/watchonly/models.py +++ b/lnbits/extensions/watchonly/models.py @@ -76,9 +76,13 @@ class CreatePsbt(BaseModel): tx_size: int +class SerializedTransaction(BaseModel): + tx_hex: str + + class ExtractPsbt(BaseModel): psbtBase64 = "" # // todo snake case - inputs: List[TransactionInput] + inputs: List[SerializedTransaction] network = "Mainnet" @@ -87,10 +91,6 @@ class SignedTransaction(BaseModel): tx_json: Optional[str] -class BroadcastTransaction(BaseModel): - tx_hex: str - - class Config(BaseModel): mempool_endpoint = "https://mempool.space" receive_gap_limit = 20 diff --git a/lnbits/extensions/watchonly/views_api.py b/lnbits/extensions/watchonly/views_api.py index 9030b9c3..97f731c3 100644 --- a/lnbits/extensions/watchonly/views_api.py +++ b/lnbits/extensions/watchonly/views_api.py @@ -31,11 +31,11 @@ from .crud import ( ) from .helpers import parse_key from .models import ( - BroadcastTransaction, Config, CreatePsbt, CreateWallet, ExtractPsbt, + SerializedTransaction, SignedTransaction, WalletAccount, ) @@ -291,6 +291,24 @@ async def api_psbt_create( raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, detail=str(e)) +@watchonly_ext.put("/api/v1/psbt/utxos") +async def api_psbt_extract_tx( + req: Request, w: WalletTypeInfo = Depends(require_admin_key) +): + """Extract previous unspent transaction outputs (tx_id, vout) from PSBT""" + + body = await req.json() + try: + psbt = PSBT.from_base64(body["psbtBase64"]) + res = [] + for _, inp in enumerate(psbt.inputs): + res.append({"tx_id": inp.txid.hex(), "vout": inp.vout}) + + return res + except Exception as e: + raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, detail=str(e)) + + @watchonly_ext.put("/api/v1/psbt/extract") async def api_psbt_extract_tx( data: ExtractPsbt, w: WalletTypeInfo = Depends(require_admin_key) @@ -327,7 +345,7 @@ async def api_psbt_extract_tx( @watchonly_ext.post("/api/v1/tx") async def api_tx_broadcast( - data: BroadcastTransaction, w: WalletTypeInfo = Depends(require_admin_key) + data: SerializedTransaction, w: WalletTypeInfo = Depends(require_admin_key) ): try: config = await get_config(w.wallet.user) From 8b0c004883753623415a7dfb20f9f92556a043c5 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 2 Dec 2022 13:41:26 +0200 Subject: [PATCH 2/4] feat: allow external signed PSBT --- .../static/components/payment/payment.js | 22 ++++++- .../extensions/watchonly/static/js/index.js | 14 ++++- .../watchonly/templates/watchonly/index.html | 59 ++++++++++++++++++- 3 files changed, 90 insertions(+), 5 deletions(-) diff --git a/lnbits/extensions/watchonly/static/components/payment/payment.js b/lnbits/extensions/watchonly/static/components/payment/payment.js index 9f38df1d..e9689003 100644 --- a/lnbits/extensions/watchonly/static/components/payment/payment.js +++ b/lnbits/extensions/watchonly/static/components/payment/payment.js @@ -272,15 +272,35 @@ async function payment(path) { this.showChecking = false } }, + + fetchUtxoHexForPsbt: async function (psbtBase64) { + if (this.tx?.inputs && this.tx?.inputs.length) return this.tx.inputs + + const {data: psbtUtxos} = await LNbits.api.request( + 'PUT', + '/watchonly/api/v1/psbt/utxos', + this.adminkey, + {psbtBase64} + ) + + const inputs = [] + for (const utxo of psbtUtxos) { + const txHex = await this.fetchTxHex(utxo.tx_id) + inputs.push({tx_hex: txHex}) + } + return inputs + }, extractTxFromPsbt: async function (psbtBase64) { try { + const inputs = await this.fetchUtxoHexForPsbt(psbtBase64) + const {data} = await LNbits.api.request( 'PUT', '/watchonly/api/v1/psbt/extract', this.adminkey, { psbtBase64, - inputs: this.tx.inputs, + inputs, network: this.network } ) diff --git a/lnbits/extensions/watchonly/static/js/index.js b/lnbits/extensions/watchonly/static/js/index.js index 7e410104..c8798303 100644 --- a/lnbits/extensions/watchonly/static/js/index.js +++ b/lnbits/extensions/watchonly/static/js/index.js @@ -54,7 +54,10 @@ const watchOnly = async () => { showPayment: false, fetchedUtxos: false, utxosFilter: '', - network: null + network: null, + + showEnterSignedPsbt: false, + signedBase64Psbt: null } }, computed: { @@ -173,6 +176,15 @@ const watchOnly = async () => { this.$refs.paymentRef.updateSignedPsbt(psbtBase64) }, + showEnterSignedPsbtDialog: function () { + this.showEnterSignedPsbt = true + }, + + checkPsbt: function () { + console.log('### checkPsbt', this.signedBase64Psbt) + this.$refs.paymentRef.updateSignedPsbt(this.signedBase64Psbt) + }, + //################### UTXOs ################### scanAllAddresses: async function () { await this.refreshAddresses() diff --git a/lnbits/extensions/watchonly/templates/watchonly/index.html b/lnbits/extensions/watchonly/templates/watchonly/index.html index 67f89810..3dab74d5 100644 --- a/lnbits/extensions/watchonly/templates/watchonly/index.html +++ b/lnbits/extensions/watchonly/templates/watchonly/index.html @@ -52,14 +52,37 @@ >
- New Payment + + + + New Payment + Create a new payment by selecting Inputs and + Outputs + + + + + From Signed PSBT + Paste a signed PSBT + + + + + + + +
Enter the Signed PSBT
+
+ +

+ +

+ +
+ Check PSBT + Close +
+
+
+
+ {% endraw %}
From 88035305c515a9db8d1952e6398dbf2c8c1a3f1b Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 2 Dec 2022 13:46:51 +0200 Subject: [PATCH 3/4] fix: hide `New Payment` button --- lnbits/extensions/watchonly/templates/watchonly/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/lnbits/extensions/watchonly/templates/watchonly/index.html b/lnbits/extensions/watchonly/templates/watchonly/index.html index 3dab74d5..84be5c81 100644 --- a/lnbits/extensions/watchonly/templates/watchonly/index.html +++ b/lnbits/extensions/watchonly/templates/watchonly/index.html @@ -53,6 +53,7 @@
Date: Fri, 2 Dec 2022 14:02:59 +0200 Subject: [PATCH 4/4] chore: code clean-up --- lnbits/extensions/watchonly/static/js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lnbits/extensions/watchonly/static/js/index.js b/lnbits/extensions/watchonly/static/js/index.js index c8798303..880d6b30 100644 --- a/lnbits/extensions/watchonly/static/js/index.js +++ b/lnbits/extensions/watchonly/static/js/index.js @@ -177,11 +177,11 @@ const watchOnly = async () => { }, showEnterSignedPsbtDialog: function () { + this.signedBase64Psbt = '' this.showEnterSignedPsbt = true }, checkPsbt: function () { - console.log('### checkPsbt', this.signedBase64Psbt) this.$refs.paymentRef.updateSignedPsbt(this.signedBase64Psbt) },