Skip to content

Commit c78c2f2

Browse files
OttoAllmendingerllm-git
andcommitted
feat(abstract-utxo): add support for PSBT decoder selection
Add decodeWith parameter to specify which PSBT decoder to use (utxolib or wasm-utxo). This allows switching between implementations when needed, which is important for compatibility and testing. Also add a helper function to validate decoder selection. Issue: BTC-2806 Co-authored-by: llm-git <[email protected]>
1 parent cc67073 commit c78c2f2

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

modules/abstract-utxo/src/abstractUtxoCoin.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ import {
7878
import { assertDescriptorWalletAddress, getDescriptorMapFromWallet, isDescriptorWallet } from './descriptor';
7979
import { getChainFromNetwork, getFamilyFromNetwork, getFullNameFromNetwork } from './names';
8080
import { assertFixedScriptWalletAddress } from './address/fixedScript';
81-
import { ParsedTransaction } from './transaction/types';
81+
import { isSdkBackend, ParsedTransaction, SdkBackend } from './transaction/types';
8282
import { decodePsbtWith, encodeTransaction, stringToBufferTryFormats } from './transaction/decode';
8383
import { toBip32Triple, UtxoKeychain } from './keychains';
8484
import { verifyKeySignature, verifyUserPublicKey } from './verifyKey';
@@ -215,6 +215,7 @@ export interface ExplainTransactionOptions<TNumber extends number | bigint = num
215215
txInfo?: TransactionInfo<TNumber>;
216216
feeInfo?: string;
217217
pubs?: Triple<string>;
218+
decodeWith?: SdkBackend;
218219
}
219220

220221
export interface DecoratedExplainTransactionOptions<TNumber extends number | bigint = number>
@@ -227,6 +228,7 @@ export type UtxoNetwork = utxolib.Network;
227228
export interface TransactionPrebuild<TNumber extends number | bigint = number> extends BaseTransactionPrebuild {
228229
txInfo?: TransactionInfo<TNumber>;
229230
blockHeight?: number;
231+
decodeWith?: SdkBackend;
230232
}
231233

232234
export interface TransactionParams extends BaseTransactionParams {
@@ -286,6 +288,7 @@ type UtxoBaseSignTransactionOptions<TNumber extends number | bigint = number> =
286288
walletId?: string;
287289
txHex: string;
288290
txInfo?: TransactionInfo<TNumber>;
291+
decodeWith?: SdkBackend;
289292
};
290293
/** xpubs triple for wallet (user, backup, bitgo). Required only when txPrebuild.txHex is not a PSBT */
291294
pubs?: Triple<string>;
@@ -531,15 +534,21 @@ export abstract class AbstractUtxoCoin
531534
return utxolib.bitgo.createTransactionFromHex<TNumber>(hex, this.network, this.amountType);
532535
}
533536

534-
decodeTransaction<TNumber extends number | bigint>(input: Buffer | string): DecodedTransaction<TNumber> {
537+
decodeTransaction<TNumber extends number | bigint>(
538+
input: Buffer | string,
539+
decodeWith?: SdkBackend
540+
): DecodedTransaction<TNumber> {
535541
if (typeof input === 'string') {
536542
const buffer = stringToBufferTryFormats(input, ['hex', 'base64']);
537-
return this.decodeTransaction(buffer);
543+
return this.decodeTransaction(buffer, decodeWith);
538544
}
539545

540546
if (utxolib.bitgo.isPsbt(input)) {
541-
return decodePsbtWith(input, this.network, 'utxolib');
547+
return decodePsbtWith(input, this.network, decodeWith ?? 'utxolib');
542548
} else {
549+
if (decodeWith ?? 'utxolib' !== 'utxolib') {
550+
console.error('received decodeWith hint %s, ignoring for legacy transaction', decodeWith);
551+
}
543552
return utxolib.bitgo.createTransactionFromBuffer(input, this.network, {
544553
amountType: this.amountType,
545554
});
@@ -557,12 +566,20 @@ export abstract class AbstractUtxoCoin
557566
decodeTransactionFromPrebuild<TNumber extends number | bigint>(prebuild: {
558567
txHex?: string;
559568
txBase64?: string;
569+
decodeWith?: string;
560570
}): DecodedTransaction<TNumber> {
561571
const string = prebuild.txHex ?? prebuild.txBase64;
562572
if (!string) {
563573
throw new Error('missing required txHex or txBase64 property');
564574
}
565-
return this.decodeTransaction(string);
575+
let { decodeWith } = prebuild;
576+
if (decodeWith !== undefined) {
577+
if (typeof decodeWith !== 'string' || !isSdkBackend(decodeWith)) {
578+
console.error('decodeWith %s is not a valid value, using default', decodeWith);
579+
decodeWith = undefined;
580+
}
581+
}
582+
return this.decodeTransaction(string, decodeWith);
566583
}
567584

568585
toCanonicalTransactionRecipient(output: { valueString: string; address?: string }): {

modules/abstract-utxo/src/transaction/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import type { CustomChangeOptions } from './fixedScript';
77

88
export type SdkBackend = 'utxolib' | 'wasm-utxo';
99

10+
export function isSdkBackend(backend: string): backend is SdkBackend {
11+
return backend === 'utxolib' || backend === 'wasm-utxo';
12+
}
13+
1014
export type DecodedTransaction<TNumber extends number | bigint> =
1115
| utxolib.bitgo.UtxoTransaction<TNumber>
1216
| utxolib.bitgo.UtxoPsbt

0 commit comments

Comments
 (0)