Skip to content

Commit 19cd235

Browse files
OttoAllmendingerllm-git
andcommitted
feat(abstract-utxo): add fixedScriptWallet to decodeTransactionAsPsbt
Support wasm-utxo based fixed script wallet PSBTs in the getMusig2Nonces method by implementing Musig2Participant for both PSBT types. Issue: BTC-2806 Co-authored-by: llm-git <[email protected]>
1 parent 8783f95 commit 19cd235

File tree

1 file changed

+36
-18
lines changed

1 file changed

+36
-18
lines changed

modules/abstract-utxo/src/abstractUtxoCoin.ts

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
isValidPrv,
4343
isValidXprv,
4444
} from '@bitgo/sdk-core';
45+
import { fixedScriptWallet } from '@bitgo/wasm-utxo';
4546

4647
import {
4748
backupKeyRecovery,
@@ -68,6 +69,7 @@ import {
6869
verifyTransaction,
6970
} from './transaction';
7071
import type { TransactionExplanation } from './transaction/fixedScript/explainTransaction';
72+
import { Musig2Participant } from './transaction/fixedScript/musig2';
7173
import {
7274
AggregateValidationError,
7375
ErrorMissingOutputs,
@@ -77,7 +79,7 @@ import { assertDescriptorWalletAddress, getDescriptorMapFromWallet, isDescriptor
7779
import { getChainFromNetwork, getFamilyFromNetwork, getFullNameFromNetwork } from './names';
7880
import { assertFixedScriptWalletAddress } from './address/fixedScript';
7981
import { ParsedTransaction } from './transaction/types';
80-
import { decodePsbtWith, stringToBufferTryFormats } from './transaction/decode';
82+
import { decodePsbtWith, encodeTransaction, stringToBufferTryFormats } from './transaction/decode';
8183
import { toBip32Triple, UtxoKeychain } from './keychains';
8284
import { verifyKeySignature, verifyUserPublicKey } from './verifyKey';
8385
import { getPolicyForEnv } from './descriptor/validatePolicy';
@@ -360,7 +362,10 @@ export interface SignPsbtResponse {
360362
psbt: string;
361363
}
362364

363-
export abstract class AbstractUtxoCoin extends BaseCoin {
365+
export abstract class AbstractUtxoCoin
366+
extends BaseCoin
367+
implements Musig2Participant<utxolib.bitgo.UtxoPsbt>, Musig2Participant<fixedScriptWallet.BitGoPsbt>
368+
{
364369
public altScriptHash?: number;
365370
public supportAltScriptDestination?: boolean;
366371
public readonly amountType: 'number' | 'bigint';
@@ -509,7 +514,7 @@ export abstract class AbstractUtxoCoin extends BaseCoin {
509514
if (_.isUndefined(prebuild.blockHeight)) {
510515
prebuild.blockHeight = (await this.getLatestBlockHeight()) as number;
511516
}
512-
return _.extend({}, prebuild, { txHex: tx.toHex() });
517+
return _.extend({}, prebuild, { txHex: encodeTransaction(tx).toString('hex') });
513518
}
514519

515520
/**
@@ -541,12 +546,12 @@ export abstract class AbstractUtxoCoin extends BaseCoin {
541546
}
542547
}
543548

544-
decodeTransactionAsPsbt(input: Buffer | string): utxolib.bitgo.UtxoPsbt {
549+
decodeTransactionAsPsbt(input: Buffer | string): utxolib.bitgo.UtxoPsbt | fixedScriptWallet.BitGoPsbt {
545550
const decoded = this.decodeTransaction(input);
546-
if (!(decoded instanceof utxolib.bitgo.UtxoPsbt)) {
547-
throw new Error('expected psbt but got transaction');
551+
if (decoded instanceof fixedScriptWallet.BitGoPsbt || decoded instanceof utxolib.bitgo.UtxoPsbt) {
552+
return decoded;
548553
}
549-
return decoded;
554+
throw new Error('expected psbt but got transaction');
550555
}
551556

552557
decodeTransactionFromPrebuild<TNumber extends number | bigint>(prebuild: {
@@ -720,16 +725,29 @@ export abstract class AbstractUtxoCoin extends BaseCoin {
720725

721726
/**
722727
* @returns input psbt added with deterministic MuSig2 nonce for bitgo key for each MuSig2 inputs.
723-
* @param psbtHex all MuSig2 inputs should contain user MuSig2 nonce
728+
* @param psbt all MuSig2 inputs should contain user MuSig2 nonce
724729
* @param walletId
725730
*/
726-
async getMusig2Nonces(psbt: utxolib.bitgo.UtxoPsbt, walletId: string): Promise<utxolib.bitgo.UtxoPsbt> {
727-
const params: SignPsbtRequest = { psbt: psbt.toHex() };
731+
async getMusig2Nonces(psbt: utxolib.bitgo.UtxoPsbt, walletId: string): Promise<utxolib.bitgo.UtxoPsbt>;
732+
async getMusig2Nonces(psbt: fixedScriptWallet.BitGoPsbt, walletId: string): Promise<fixedScriptWallet.BitGoPsbt>;
733+
async getMusig2Nonces<T extends utxolib.bitgo.UtxoPsbt | fixedScriptWallet.BitGoPsbt>(
734+
psbt: T,
735+
walletId: string
736+
): Promise<T>;
737+
async getMusig2Nonces<T extends utxolib.bitgo.UtxoPsbt | fixedScriptWallet.BitGoPsbt>(
738+
psbt: T,
739+
walletId: string
740+
): Promise<T> {
741+
const buffer = encodeTransaction(psbt);
728742
const response = await this.bitgo
729743
.post(this.url('/wallet/' + walletId + '/tx/signpsbt'))
730-
.send(params)
744+
.send({ psbt: buffer.toString('hex') })
731745
.result();
732-
return this.decodeTransactionAsPsbt(response.psbt);
746+
if (psbt instanceof utxolib.bitgo.UtxoPsbt) {
747+
return decodePsbtWith(response.psbt, this.network, 'utxolib') as T;
748+
} else {
749+
return decodePsbtWith(response.psbt, this.network, 'wasm-utxo') as T;
750+
}
733751
}
734752

735753
/**
@@ -739,7 +757,8 @@ export abstract class AbstractUtxoCoin extends BaseCoin {
739757
* @param walletId
740758
*/
741759
async signPsbt(psbtHex: string, walletId: string): Promise<SignPsbtResponse> {
742-
return { psbt: (await this.getMusig2Nonces(this.decodeTransactionAsPsbt(psbtHex), walletId)).toHex() };
760+
const psbt = await this.getMusig2Nonces(this.decodeTransactionAsPsbt(psbtHex), walletId);
761+
return { psbt: encodeTransaction(psbt).toString('hex') };
743762
}
744763

745764
/**
@@ -749,11 +768,10 @@ export abstract class AbstractUtxoCoin extends BaseCoin {
749768
async signPsbtFromOVC(ovcJson: Record<string, unknown>): Promise<Record<string, unknown>> {
750769
assert(ovcJson['psbtHex'], 'ovcJson must contain psbtHex');
751770
assert(ovcJson['walletId'], 'ovcJson must contain walletId');
752-
const psbt = await this.getMusig2Nonces(
753-
this.decodeTransactionAsPsbt(ovcJson['psbtHex'] as string),
754-
ovcJson['walletId'] as string
755-
);
756-
return _.extend(ovcJson, { txHex: psbt.toHex() });
771+
const hex = ovcJson['psbtHex'] as string;
772+
const walletId = ovcJson['walletId'] as string;
773+
const psbt = await this.getMusig2Nonces(this.decodeTransactionAsPsbt(hex), walletId);
774+
return _.extend(ovcJson, { txHex: encodeTransaction(psbt).toString('hex') });
757775
}
758776

759777
/**

0 commit comments

Comments
 (0)