Skip to content

Commit 447d400

Browse files
Merge pull request #8649 from BitGo/worktree-wal-826-fix-check-recipient
fix(abstract-utxo): guard address in checkRecipient for OP_RETURN outputs
2 parents 3ced71b + 5f0d1ed commit 447d400

2 files changed

Lines changed: 42 additions & 3 deletions

File tree

modules/abstract-utxo/src/abstractUtxoCoin.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -572,10 +572,10 @@ export abstract class AbstractUtxoCoin
572572
return (chainhead as any).height;
573573
}
574574

575-
checkRecipient(recipient: { address: string; amount: number | string }): void {
575+
checkRecipient(recipient: { address?: string; amount: number | string }): void {
576576
assertValidTransactionRecipient(recipient);
577-
if (!isScriptRecipient(recipient.address)) {
578-
super.checkRecipient(recipient);
577+
if (recipient.address && !isScriptRecipient(recipient.address)) {
578+
super.checkRecipient({ address: recipient.address, amount: recipient.amount });
579579
}
580580
}
581581

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import assert from 'assert';
2+
3+
import { getUtxoCoin } from '../util/utxoCoins';
4+
5+
describe('AbstractUtxoCoin.checkRecipient', function () {
6+
const coin = getUtxoCoin('btc');
7+
8+
it('does not throw for OP_RETURN output with no address field', function () {
9+
// Simulates { amount: '0', script: '6a0c...' } coming from buildParams.recipients
10+
assert.doesNotThrow(() => {
11+
coin.checkRecipient({ amount: '0' });
12+
});
13+
});
14+
15+
it('does not throw for script-prefixed address with zero amount', function () {
16+
assert.doesNotThrow(() => {
17+
coin.checkRecipient({ address: 'scriptPubKey:6a0c68656c6c6f20776f726c64', amount: '0' });
18+
});
19+
});
20+
21+
it('does not throw for a regular address', function () {
22+
// A valid mainnet P2PKH address
23+
assert.doesNotThrow(() => {
24+
coin.checkRecipient({ address: '1A1zP1eP5QGefi2DMPTfTL5SLmv7Divf', amount: '1000' });
25+
});
26+
});
27+
28+
it('throws when OP_RETURN output (no address) has non-zero amount', function () {
29+
assert.throws(() => {
30+
coin.checkRecipient({ amount: '1000' });
31+
}, /Only zero amounts allowed for non-encodeable scriptPubkeys/);
32+
});
33+
34+
it('throws when script-prefixed address has non-zero amount', function () {
35+
assert.throws(() => {
36+
coin.checkRecipient({ address: 'scriptPubKey:6a0c68656c6c6f20776f726c64', amount: '500' });
37+
}, /Only zero amounts allowed for non-encodeable scriptPubkeys/);
38+
});
39+
});

0 commit comments

Comments
 (0)