From 662ea79e43b1bd713d5b4c75b12fbbc9003ad9c8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 11 Jan 2026 23:04:50 +0000 Subject: [PATCH 1/3] Initial plan From f8154b09f588cbec12f2afa3d1b85b652303c8d3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 11 Jan 2026 23:08:46 +0000 Subject: [PATCH 2/3] Improve type safety in rbf-service.ts - Add ECCLibrary interface for ecc parameter - Add EsploraTransaction interfaces for transaction types - Change parseSequenceNumber parameter from any to unknown - Add deprecation comment for TransactionBuilder Co-authored-by: jamespepper81 <84083764+jamespepper81@users.noreply.github.com> --- services/rbf-service.ts | 53 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/services/rbf-service.ts b/services/rbf-service.ts index 9134862..cd617de 100644 --- a/services/rbf-service.ts +++ b/services/rbf-service.ts @@ -29,7 +29,12 @@ const MIN_RBF_FEE_INCREASE_RATE = 0.1; * Validates the given ECC library by checking basic functionality. * Throws an error if validation fails. */ -function validateECCLibrary(ecc: any): void { +interface ECCLibrary { + isPrivate(privKey: Uint8Array): boolean; + pointFromScalar(scalar: Uint8Array, compressed: boolean): Uint8Array | null; +} + +function validateECCLibrary(ecc: ECCLibrary): void { const testPrivateKey = new Uint8Array(32); testPrivateKey[31] = 1; // Set to 1 to ensure it's a valid private key @@ -45,9 +50,47 @@ function validateECCLibrary(ecc: any): void { } } +export interface EsploraTransactionVin { + txid?: string; + vout?: number; + sequence?: number; + prevout?: { + value?: number; + scriptpubkey?: string; + scriptpubkey_address?: string; + } | null; + [key: string]: unknown; +} + +export interface EsploraTransactionVout { + value?: number; + scriptpubkey?: string; + scriptpubkey_address?: string; + [key: string]: unknown; +} + +/** + * Minimal representation of an Esplora transaction used by the RBF service. + * Additional fields returned by Esplora are allowed via the index signature. + */ +export interface EsploraTransaction { + txid: string; + version?: number; + locktime?: number; + vin: EsploraTransactionVin[]; + vout: EsploraTransactionVout[]; + status?: { + confirmed?: boolean; + block_height?: number; + block_hash?: string; + block_time?: number; + }; + [key: string]: unknown; +} + export interface RBFTransaction { txid: string; - originalTx: any; // Raw Esplora transaction with vin/vout properties + originalTx: EsploraTransaction; // Raw Esplora transaction with vin/vout properties newFeeRate: number; newFee: number; replacementTx?: string; // hex transaction @@ -59,7 +102,7 @@ export interface RBFValidationResult { isValid: boolean; canReplace: boolean; reason?: string; - originalTx?: any; // Raw Esplora transaction with vin/vout properties + originalTx?: EsploraTransaction; // Raw Esplora transaction with vin/vout properties utxos?: UTXO[]; } @@ -72,7 +115,7 @@ export interface RBFValidationResult { * causing incorrect RBF validation. This function now detects the format * and parses accordingly. */ -function parseSequenceNumber(sequence: any): number { +function parseSequenceNumber(sequence: unknown): number { if (typeof sequence === 'number') { return sequence; } @@ -415,6 +458,7 @@ export async function createReplacementTransaction( const bip32Instance = bip32.BIP32Factory(ecc); // Create transaction builder (replace TransactionBuilder with PSBT for modern bitcoinjs-lib) + // TransactionBuilder is deprecated in newer versions of bitcoinjs-lib. Consider migrating to PSBT (Partially Signed Bitcoin Transaction) for better compatibility and future-proofing. let txb = new bitcoin.TransactionBuilder(bitcoin.networks.bitcoin); // Get our inputs from the original transaction @@ -947,6 +991,7 @@ async function createCancellationTransaction( const bip32Instance = bip32.BIP32Factory(ecc); // Create transaction builder (replace TransactionBuilder with PSBT for modern bitcoinjs-lib) + // TransactionBuilder is deprecated in newer versions of bitcoinjs-lib. Consider migrating to PSBT (Partially Signed Bitcoin Transaction) for better compatibility and future-proofing. let txb = new bitcoin.TransactionBuilder(bitcoin.networks.bitcoin); // Get our inputs from the original transaction From 6db5c0ffafa72618e5fc1613157f2d00ea8bf178 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 11 Jan 2026 23:19:38 +0000 Subject: [PATCH 3/3] Fix pre-existing TypeScript errors in rbf-service.ts - Update tsconfig.json to include ES2015+ and DOM libs - Install @types/node for Node.js type definitions - Add null/undefined checks in rbf-service.ts - Fix all TypeScript compilation errors without changing functionality Co-authored-by: jamespepper81 <84083764+jamespepper81@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- services/rbf-service.ts | 10 +++++++--- tsconfig.json | 2 ++ 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 02cf1c9..860ad4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -94,7 +94,7 @@ }, "devDependencies": { "@expo/ngrok": "^4.1.3", - "@types/node": "^24.5.2", + "@types/node": "^24.10.7", "@types/react": "~19.1.0", "eas-cli-local-build-plugin": "^1.0.240", "eslint": "^9.35.0", @@ -5738,9 +5738,9 @@ } }, "node_modules/@types/node": { - "version": "24.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.4.tgz", - "integrity": "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==", + "version": "24.10.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.7.tgz", + "integrity": "sha512-+054pVMzVTmRQV8BhpGv3UyfZ2Llgl8rdpDTon+cUH9+na0ncBVXj3wTUKh14+Kiz18ziM3b4ikpP5/Pc0rQEQ==", "license": "MIT", "dependencies": { "undici-types": "~7.16.0" diff --git a/package.json b/package.json index 61a48ad..b33f0e9 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ }, "devDependencies": { "@expo/ngrok": "^4.1.3", - "@types/node": "^24.5.2", + "@types/node": "^24.10.7", "@types/react": "~19.1.0", "eas-cli-local-build-plugin": "^1.0.240", "eslint": "^9.35.0", diff --git a/services/rbf-service.ts b/services/rbf-service.ts index cd617de..10cfedd 100644 --- a/services/rbf-service.ts +++ b/services/rbf-service.ts @@ -477,7 +477,11 @@ export async function createReplacementTransaction( const inputMap = new Map(); for (const input of ourInputs) { - const address = input.prevout.scriptpubkey_address; + const address = input.prevout?.scriptpubkey_address; + + if (!address) { + throw new Error(`Input missing address information: ${JSON.stringify(input)}`); + } // Derive the actual BIP32 address index and chain instead of using array index const { index: addressIndex, chain } = await deriveAddressIndexAndChainFromAddress(mnemonic, address); @@ -534,7 +538,7 @@ export async function createReplacementTransaction( } else { throw new Error(`Unsupported output type: ${JSON.stringify(output)}`); } - totalOutputValue += output.value; + totalOutputValue += output.value ?? 0; } // Find the change output in the original transaction (if any) @@ -546,7 +550,7 @@ export async function createReplacementTransaction( const output = originalTx.vout[i]; if (output.scriptpubkey_address && walletAddressesSet.has(output.scriptpubkey_address)) { changeOutputIndex = i; - changeOutputValue = output.value; + changeOutputValue = output.value ?? 0; break; } } diff --git a/tsconfig.json b/tsconfig.json index a56b55a..4ad2417 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,8 @@ "extends": "expo/tsconfig.base", "compilerOptions": { "strict": true, + "lib": ["ES2015", "ES2016", "ES2017", "ES2018", "ES2019", "ES2020", "DOM"], + "target": "ES2015", "paths": { "@/*": [ "./*"