From 70b4e34cb643596bd17ef96107c7384cf74f175b Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Mon, 19 Jan 2026 14:34:13 +0100 Subject: [PATCH 1/2] feat(sdk-core): pass wallet to explainTransaction Allow passing wallet instance to explainTransaction for additional context during transaction validation. This enables more accurate verification of staking transactions by providing wallet-specific information. Issue: BTC-2963 Co-authored-by: llm-git --- modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts | 5 ++++- modules/sdk-core/src/bitgo/staking/stakingWallet.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts b/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts index 136630361b..7f88ebbd04 100644 --- a/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts +++ b/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts @@ -583,7 +583,10 @@ export interface IBaseCoin { backup: string; bitgo: string; }>; - explainTransaction(options: Record): Promise | undefined>; + explainTransaction( + options: Record, + wallet?: IWallet + ): Promise | undefined>; verifyTransaction(params: VerifyTransactionOptions): Promise; verifyAddress(params: VerifyAddressOptions): Promise; isWalletAddress(params: VerifyAddressOptions | TssVerifyAddressOptions, wallet?: IWallet): Promise; diff --git a/modules/sdk-core/src/bitgo/staking/stakingWallet.ts b/modules/sdk-core/src/bitgo/staking/stakingWallet.ts index 39708279b2..f67c1f6f55 100644 --- a/modules/sdk-core/src/bitgo/staking/stakingWallet.ts +++ b/modules/sdk-core/src/bitgo/staking/stakingWallet.ts @@ -405,7 +405,7 @@ export class StakingWallet implements IStakingWallet { return; } - const explainedTransaction = await coin.explainTransaction(result); + const explainedTransaction = await coin.explainTransaction(result, this.wallet); const mismatchErrors: string[] = []; if (buildParams?.recipients && buildParams.recipients.length > 0) { From 3ca122bec75333a781be6302a04498ea570401c4 Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Mon, 19 Jan 2026 14:36:42 +0100 Subject: [PATCH 2/2] feat(abstract-utxo): fetch keychains from wallet in explainTransaction Allow explainTransaction to automatically fetch keychains when none are provided but a wallet is available. Issue: BTC-2963 Co-authored-by: llm-git --- modules/abstract-utxo/src/abstractUtxoCoin.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/abstract-utxo/src/abstractUtxoCoin.ts b/modules/abstract-utxo/src/abstractUtxoCoin.ts index 2e7c01065f..375590ba67 100644 --- a/modules/abstract-utxo/src/abstractUtxoCoin.ts +++ b/modules/abstract-utxo/src/abstractUtxoCoin.ts @@ -87,7 +87,7 @@ import { import { assertFixedScriptWalletAddress } from './address/fixedScript'; import { isSdkBackend, ParsedTransaction, SdkBackend } from './transaction/types'; import { decodePsbtWith, encodeTransaction, stringToBufferTryFormats } from './transaction/decode'; -import { toBip32Triple, UtxoKeychain } from './keychains'; +import { fetchKeychains, toBip32Triple, UtxoKeychain } from './keychains'; import { verifyKeySignature, verifyUserPublicKey } from './verifyKey'; import { getPolicyForEnv } from './descriptor/validatePolicy'; import { signTransaction } from './transaction/signTransaction'; @@ -875,8 +875,16 @@ export abstract class AbstractUtxoCoin * @param params */ override async explainTransaction( - params: ExplainTransactionOptions + params: ExplainTransactionOptions, + wallet?: IWallet ): Promise { + if (!params.pubs) { + // if no pubs are provided, opportunistically fetch the keychains from the wallet + if (wallet) { + const keychains = await fetchKeychains(this, wallet); + params.pubs = toBip32Triple(keychains).map((k) => k.neutered().toBase58()) as Triple; + } + } return explainTx(this.decodeTransactionFromPrebuild(params), params, this.name); }