Skip to content

Commit eb767d8

Browse files
OttoAllmendingerllm-git
andcommitted
feat(abstract-utxo): extract replay protection addresses param
Replace internal call to isReplayProtectionUnspent with explicit param to allow better testing. Add replayProtectionAddresses parameter to signAndVerifyWalletTransaction with fallback to existing values. Issue: BTC-2806 Co-authored-by: llm-git <[email protected]>
1 parent 0175240 commit eb767d8

File tree

1 file changed

+14
-4
lines changed

1 file changed

+14
-4
lines changed

modules/abstract-utxo/src/sign.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as utxolib from '@bitgo/utxo-lib';
22
import debugLib from 'debug';
33

4-
import { isReplayProtectionUnspent } from './replayProtection';
4+
import { getReplayProtectionAddresses } from './replayProtection';
55

66
const debug = debugLib('bitgo:v2:utxo');
77

@@ -139,14 +139,24 @@ export function signAndVerifyPsbt(
139139
* @param unspents - transaction unspents
140140
* @param walletSigner - signing parameters
141141
* @param isLastSignature - Returns full-signed transaction when true. Builds half-signed when false.
142+
* @param replayProtectionAddresses - List of replay protection addresses to skip signing
142143
*/
143144
export function signAndVerifyWalletTransaction<TNumber extends number | bigint>(
144145
transaction: utxolib.bitgo.UtxoTransaction<TNumber> | utxolib.bitgo.UtxoTransactionBuilder<TNumber>,
145146
unspents: Unspent<TNumber>[],
146147
walletSigner: utxolib.bitgo.WalletUnspentSigner<RootWalletKeys>,
147-
{ isLastSignature }: { isLastSignature: boolean }
148+
{
149+
isLastSignature,
150+
replayProtectionAddresses,
151+
}: {
152+
isLastSignature: boolean;
153+
replayProtectionAddresses?: string[];
154+
}
148155
): utxolib.bitgo.UtxoTransaction<TNumber> {
149156
const network = transaction.network as utxolib.Network;
157+
if (replayProtectionAddresses === undefined) {
158+
replayProtectionAddresses = getReplayProtectionAddresses(network);
159+
}
150160
const prevOutputs = unspents.map((u) => toOutput(u, network));
151161

152162
let txBuilder: utxolib.bitgo.UtxoTransactionBuilder<TNumber>;
@@ -163,7 +173,7 @@ export function signAndVerifyWalletTransaction<TNumber extends number | bigint>(
163173

164174
const signErrors: InputSigningError<TNumber>[] = unspents
165175
.map((unspent: Unspent<TNumber>, inputIndex: number) => {
166-
if (isReplayProtectionUnspent<TNumber>(unspent, network)) {
176+
if (replayProtectionAddresses.includes(unspent.address)) {
167177
debug('Skipping signature for input %d of %d (RP input?)', inputIndex + 1, unspents.length);
168178
return;
169179
}
@@ -184,7 +194,7 @@ export function signAndVerifyWalletTransaction<TNumber extends number | bigint>(
184194
const verifyErrors: InputSigningError<TNumber>[] = signedTransaction.ins
185195
.map((input, inputIndex) => {
186196
const unspent = unspents[inputIndex] as Unspent<TNumber>;
187-
if (isReplayProtectionUnspent<TNumber>(unspent, network)) {
197+
if (replayProtectionAddresses.includes(unspent.address)) {
188198
debug(
189199
'Skipping input signature %d of %d (unspent from replay protection address which is platform signed only)',
190200
inputIndex + 1,

0 commit comments

Comments
 (0)