From 76c41a3439b2365fb3633e2c4d82dc947b5e671e Mon Sep 17 00:00:00 2001 From: Evan Kaloudis Date: Mon, 16 Dec 2024 15:35:37 -0500 Subject: [PATCH] ZEUS-2636: CLNRest: Destination address not shown in transaction --- backends/CoreLightningRequestHandler.ts | 78 ++++++++++++++++++++++++- models/Transaction.ts | 2 +- package.json | 1 + yarn.lock | 12 ++++ 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/backends/CoreLightningRequestHandler.ts b/backends/CoreLightningRequestHandler.ts index 78e12a34b..38ae88a7f 100644 --- a/backends/CoreLightningRequestHandler.ts +++ b/backends/CoreLightningRequestHandler.ts @@ -1,3 +1,9 @@ +const bitcoin = require('bitcoinjs-lib'); +const ecc = require('tiny-secp256k1'); + +// Initialize the ECC library +bitcoin.initEccLib(ecc); + import CLNRest from './CLNRest'; const api = new CLNRest(); @@ -139,7 +145,77 @@ export const getChainTransactions = async () => { api.postRequest('/v1/listtransactions'), api.postRequest('/v1/getinfo') ]); - const [sqlResult, listTxsResult, getinfoResult] = results; + const [sqlResult, listTxsResult, getinfoResult]: any = results; + + listTxsResult?.value?.transactions?.forEach((tx: any) => { + tx.outputs.forEach((output: any) => { + const network = bitcoin.networks.bitcoin; + const scriptPubKeyHex = output.scriptPubKey; + + const script = Buffer.from(scriptPubKeyHex, 'hex'); + + try { + // Check for P2PKH (Pay-to-PubKey-Hash) + if ( + script.length === 25 && + script[0] === 0x76 && + script[1] === 0xa9 && + script[2] === 0x14 + ) { + const hash = script.slice(3, 23); // Extract the 20-byte hash + return bitcoin.payments.p2pkh({ hash, network }).address; + } + + // Check for P2SH (Pay-to-Script-Hash) + if ( + script.length === 23 && + script[0] === 0xa9 && + script[1] === 0x14 && + script[22] === 0x87 + ) { + const hash = script.slice(2, 22); // Extract the 20-byte hash + return bitcoin.payments.p2sh({ hash, network }).address; + } + + // Check for P2WPKH (Pay-to-Witness-PubKey-Hash) + if ( + script.length === 22 && + script[0] === 0x00 && + script[1] === 0x14 + ) { + const hash = script.slice(2, 22); // Extract the 20-byte hash + return bitcoin.payments.p2wpkh({ hash, network }).address; + } + + // Check for P2WSH (Pay-to-Witness-Script-Hash) + if ( + script.length === 34 && + script[0] === 0x00 && + script[1] === 0x20 + ) { + const hash = script.slice(2, 34); // Extract the 32-byte hash + return bitcoin.payments.p2wsh({ hash, network }).address; + } + + // Check for P2TR (Pay-to-Taproot) + if ( + script.length === 34 && + script[0] === 0x51 && + script[1] === 0x20 + ) { + const internalPubkey = script.slice(2, 34); // Extract the 32-byte public key + return bitcoin.payments.p2tr({ internalPubkey, network }) + .address; + } + + // Unknown scriptPubKey type + throw new Error('Unsupported or unknown scriptPubKey type.'); + } catch (err: any) { + console.error('Error decoding scriptPubKey:', err.message); + return null; + } + }); + }); // If getinfo fails, return blank txs if (getinfoResult.status !== 'fulfilled') { diff --git a/models/Transaction.ts b/models/Transaction.ts index 05168aedd..d1ca04aee 100644 --- a/models/Transaction.ts +++ b/models/Transaction.ts @@ -119,7 +119,7 @@ export default class Transaction extends BaseModel { } @computed public get destAddresses(): Array { - return this.dest_addresses || [this.address]; + return this.dest_addresses || this.address ? [this.address] : []; } @computed public get getOutpoint(): string { diff --git a/package.json b/package.json index ed39b7a78..392ee542f 100644 --- a/package.json +++ b/package.json @@ -132,6 +132,7 @@ "stream-browserify": "1.0.0", "text-encoding": "0.7.0", "timers-browserify": "1.4.2", + "tiny-secp256k1": "2.2.3", "tty-browserify": "0.0.0", "url": "0.10.3", "util": "0.10.4", diff --git a/yarn.lock b/yarn.lock index 70dc05baf..1ad6c54c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10096,6 +10096,13 @@ timers-browserify@1.4.2: dependencies: process "~0.11.0" +tiny-secp256k1@2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-2.2.3.tgz#fe1dde11a64fcee2091157d4b78bcb300feb9b65" + integrity sha512-SGcL07SxcPN2nGKHTCvRMkQLYPSoeFcvArUSCYtjVARiFAWU44cCIqYS0mYAU6nY7XfvwURuTIGo2Omt3ZQr0Q== + dependencies: + uint8array-tools "0.0.7" + tmp@^0.2.1: version "0.2.3" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" @@ -10278,6 +10285,11 @@ uglify-js@^3.7.7: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== +uint8array-tools@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/uint8array-tools/-/uint8array-tools-0.0.7.tgz#a7a2bb5d8836eae2fade68c771454e6a438b390d" + integrity sha512-vrrNZJiusLWoFWBqz5Y5KMCgP9W9hnjZHzZiZRT8oNAkq3d5Z5Oe76jAvVVSRh4U8GGR90N2X1dWtrhvx6L8UQ== + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"