Skip to content

Commit aa745d8

Browse files
committed
test: withdraw lightning psbt verification tests
TICKET: BTC-2470
1 parent e2befa7 commit aa745d8

File tree

2 files changed

+120
-10
lines changed

2 files changed

+120
-10
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { validatePsbtForWithdraw } from '../../../src';
2+
import * as utxolib from '@bitgo/utxo-lib';
3+
import assert from 'assert';
4+
5+
describe('parseWithdrawPsbt', () => {
6+
const unsignedPsbtHex =
7+
'70736274ff01007d02000000015e50b8d96cebdc3273d9a100eb68392d980d5b934b8170c80a23488b595268ca0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15affa80a000000000016001480a06f2e6b77e817fd5de6e41ea512c563c26cb800000000000100ea02000000000101a158d806735bb7c54e4c701d4f5821cd5342d48d5e1fcbed1169e6e45aa444be0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15a6a310c000000000016001478a5d98c7160484b9b00f1782803c58edfc49b9a024730440220407d9162f52371df246dcfa2943d40fbdcb0d4b6768f7682c65193378b2845a60220101c7bc460c93d2976961ac23400f0f10c145efb989a3addb7f03ebaaa2200950121037e17444c85c8b7da07f12fd53cb2ca142c2b4932d0f898649c4b5be0021da0980000000001030401000000220602e57146e5b4762a7ff374adf4072047b67ef115ad46a34189bdeb6a4f88db9b0818000000005400008000000080000000800100000006000000000022020379abbe44004ff7e527bdee3dd8d95e5cd250053f35ee92258b97aa83dfa93c621800000000540000800000008000000080010000005000000000';
8+
const network = utxolib.networks.testnet;
9+
const recipients = [
10+
{
11+
amountSat: 100000n,
12+
address: 'tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k',
13+
},
14+
];
15+
const accounts = [
16+
{
17+
xpub: 'tpubDCmiWMkTJrZ24t1Z6ECR3HyynCyZ9zGsWqhcLh6H4yFK2CDozSszD1pP2Li4Nx1YYtRcvmNbdb3nD1SzFejYtPFfTocTv2EaAgJCg4zpJpA',
18+
purpose: 49,
19+
coin_type: 0,
20+
account: 0,
21+
},
22+
{
23+
xpub: 'tpubDCFN7bsxR9UTKggdH2pmv5HeHGQNiDrJwa1EZFtP9sH5PF28i37FHpoYSYARQkKZ6Mi98pkp7oypDcxFmE4dQGq8jV8Gv3L6gmWBeRwPxkP',
24+
purpose: 84,
25+
coin_type: 0,
26+
account: 0,
27+
},
28+
];
29+
it('should parse a valid withdraw PSBT', () => {
30+
validatePsbtForWithdraw(unsignedPsbtHex, network, recipients, accounts);
31+
});
32+
it('should throw for invalid PSBT', () => {
33+
assert.throws(() => {
34+
validatePsbtForWithdraw('asdasd', network, recipients, accounts);
35+
}, /ERR_BUFFER_OUT_OF_BOUNDS/);
36+
});
37+
it('should throw for invalid recipient address', () => {
38+
const differentRecipients = [
39+
{
40+
...recipients[0],
41+
address: 'tb1qxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyz',
42+
},
43+
];
44+
assert.throws(() => {
45+
validatePsbtForWithdraw(unsignedPsbtHex, network, differentRecipients, accounts);
46+
}, /PSBT output tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k with value 100000 does not match any recipient/);
47+
});
48+
it('should throw for invalid recipient value', () => {
49+
const differentRecipients = [
50+
{
51+
...recipients[0],
52+
amountSat: 99999n,
53+
},
54+
];
55+
assert.throws(() => {
56+
validatePsbtForWithdraw(unsignedPsbtHex, network, differentRecipients, accounts);
57+
}, /PSBT output tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k with value 100000 does not match any recipient/);
58+
});
59+
it('should throw for account not found', () => {
60+
const incompatibleAccounts = [];
61+
assert.throws(() => {
62+
validatePsbtForWithdraw(unsignedPsbtHex, network, recipients, incompatibleAccounts);
63+
}, /Account not found for purpose/);
64+
});
65+
it('should throw for invalid pubkey', () => {
66+
const incompatibleAccounts = [
67+
{
68+
...accounts[1],
69+
xpub: 'tpubDCmiWMkTJrZ24t1Z6ECR3HyynCyZ9zGsWqhcLh6H4yFK2CDozSszD1pP2Li4Nx1YYtRcvmNbdb3nD1SzFejYtPFfTocTv2EaAgJCg4zpJpA',
70+
},
71+
];
72+
assert.throws(() => {
73+
validatePsbtForWithdraw(unsignedPsbtHex, network, recipients, incompatibleAccounts);
74+
}, /Derived pubkey does not match for address/);
75+
});
76+
it('should throw for invalid purpose', () => {
77+
const incompatibleAccounts = [
78+
{
79+
...accounts[1],
80+
purpose: 1017,
81+
},
82+
];
83+
const incompatiblePsbt = `70736274ff01007d02000000015e50b8d96cebdc3273d9a100eb68392d980d5b934b8170c80a23488b595268ca0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15affa80a000000000016001480a06f2e6b77e817fd5de6e41ea512c563c26cb800000000000100ea02000000000101a158d806735bb7c54e4c701d4f5821cd5342d48d5e1fcbed1169e6e45aa444be0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15a6a310c000000000016001478a5d98c7160484b9b00f1782803c58edfc49b9a024730440220407d9162f52371df246dcfa2943d40fbdcb0d4b6768f7682c65193378b2845a60220101c7bc460c93d2976961ac23400f0f10c145efb989a3addb7f03ebaaa2200950121037e17444c85c8b7da07f12fd53cb2ca142c2b4932d0f898649c4b5be0021da0980000000001030401000000220602e57146e5b4762a7ff374adf4072047b67ef115ad46a34189bdeb6a4f88db9b0818000000005400008000000080000000800100000006000000000022020379abbe44004ff7e527bdee3dd8d95e5cd250053f35ee92258b97aa83dfa93c621800000000f90300800000008000000080010000005000000000`;
84+
assert.throws(() => {
85+
validatePsbtForWithdraw(incompatiblePsbt, network, recipients, incompatibleAccounts);
86+
}, /Unsupported purpose/);
87+
});
88+
});

modules/bitgo/test/v2/unit/lightning/lightningWallets.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -807,34 +807,54 @@ describe('Lightning wallets', function () {
807807
describe('On chain withdrawal', function () {
808808
let wallet: LightningWallet;
809809
beforeEach(function () {
810+
const watchOnlyAccounts = {
811+
master_key_birthday_timestamp: 'dummy',
812+
master_key_fingerprint: 'dummy',
813+
accounts: [
814+
{
815+
xpub: 'tpubDCmiWMkTJrZ24t1Z6ECR3HyynCyZ9zGsWqhcLh6H4yFK2CDozSszD1pP2Li4Nx1YYtRcvmNbdb3nD1SzFejYtPFfTocTv2EaAgJCg4zpJpA',
816+
purpose: 49,
817+
coin_type: 0,
818+
account: 0,
819+
},
820+
{
821+
xpub: 'tpubDCFN7bsxR9UTKggdH2pmv5HeHGQNiDrJwa1EZFtP9sH5PF28i37FHpoYSYARQkKZ6Mi98pkp7oypDcxFmE4dQGq8jV8Gv3L6gmWBeRwPxkP',
822+
purpose: 84,
823+
coin_type: 0,
824+
account: 0,
825+
},
826+
],
827+
};
810828
wallet = getLightningWallet(
811829
new Wallet(bitgo, basecoin, {
812830
id: 'walletId',
813831
coin: 'tlnbtc',
814832
subType: 'lightningCustody',
815-
coinSpecific: { keys: ['def', 'ghi'] },
833+
coinSpecific: { keys: ['def', 'ghi'], watchOnlyAccounts },
816834
})
817835
) as LightningWallet;
818836
});
819837
it('should withdraw on chain', async function () {
820838
const params: LightningOnchainWithdrawParams = {
821839
recipients: [
822840
{
823-
amountSat: 500000n,
824-
address: 'bcrt1qjq48cqk2u80hewdcndf539m8nnnvt845nl68x7',
841+
amountSat: 100000n,
842+
address: 'tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k',
825843
},
826844
],
827845
satsPerVbyte: 15n,
828846
passphrase: 'password123',
829847
};
848+
const unsignedPsbtHex =
849+
'70736274ff01007d02000000015e50b8d96cebdc3273d9a100eb68392d980d5b934b8170c80a23488b595268ca0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15affa80a000000000016001480a06f2e6b77e817fd5de6e41ea512c563c26cb800000000000100ea02000000000101a158d806735bb7c54e4c701d4f5821cd5342d48d5e1fcbed1169e6e45aa444be0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15a6a310c000000000016001478a5d98c7160484b9b00f1782803c58edfc49b9a024730440220407d9162f52371df246dcfa2943d40fbdcb0d4b6768f7682c65193378b2845a60220101c7bc460c93d2976961ac23400f0f10c145efb989a3addb7f03ebaaa2200950121037e17444c85c8b7da07f12fd53cb2ca142c2b4932d0f898649c4b5be0021da0980000000001030401000000220602e57146e5b4762a7ff374adf4072047b67ef115ad46a34189bdeb6a4f88db9b0818000000005400008000000080000000800100000006000000000022020379abbe44004ff7e527bdee3dd8d95e5cd250053f35ee92258b97aa83dfa93c621800000000540000800000008000000080010000005000000000';
830850

831851
const txRequestResponse = {
832852
txRequestId: 'txReq123',
833853
state: 'pendingDelivery',
834854
transactions: [
835855
{
836856
unsignedTx: {
837-
serializedTxHex: 'unsignedTx123',
857+
serializedTxHex: unsignedPsbtHex,
838858
},
839859
},
840860
],
@@ -846,7 +866,7 @@ describe('Lightning wallets', function () {
846866
transactions: [
847867
{
848868
unsignedTx: {
849-
serializedTxHex: 'unsignedTx123',
869+
serializedTxHex: unsignedPsbtHex,
850870
coinSpecific: {
851871
signature: 'someSignature',
852872
},
@@ -861,7 +881,7 @@ describe('Lightning wallets', function () {
861881
transactions: [
862882
{
863883
unsignedTx: {
864-
serializedTxHex: 'unsignedTx123',
884+
serializedTxHex: unsignedPsbtHex,
865885
coinSpecific: {
866886
signature: 'someSignature',
867887
status: 'delivered',
@@ -1008,13 +1028,15 @@ describe('Lightning wallets', function () {
10081028
const params: LightningOnchainWithdrawParams = {
10091029
recipients: [
10101030
{
1011-
amountSat: 500000n,
1012-
address: 'bcrt1qjq48cqk2u80hewdcndf539m8nnnvt845nl68x7',
1031+
amountSat: 100000n,
1032+
address: 'tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k',
10131033
},
10141034
],
10151035
satsPerVbyte: 15n,
10161036
passphrase: 'password123',
10171037
};
1038+
const unsignedPsbtHex =
1039+
'70736274ff01007d02000000015e50b8d96cebdc3273d9a100eb68392d980d5b934b8170c80a23488b595268ca0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15affa80a000000000016001480a06f2e6b77e817fd5de6e41ea512c563c26cb800000000000100ea02000000000101a158d806735bb7c54e4c701d4f5821cd5342d48d5e1fcbed1169e6e45aa444be0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15a6a310c000000000016001478a5d98c7160484b9b00f1782803c58edfc49b9a024730440220407d9162f52371df246dcfa2943d40fbdcb0d4b6768f7682c65193378b2845a60220101c7bc460c93d2976961ac23400f0f10c145efb989a3addb7f03ebaaa2200950121037e17444c85c8b7da07f12fd53cb2ca142c2b4932d0f898649c4b5be0021da0980000000001030401000000220602e57146e5b4762a7ff374adf4072047b67ef115ad46a34189bdeb6a4f88db9b0818000000005400008000000080000000800100000006000000000022020379abbe44004ff7e527bdee3dd8d95e5cd250053f35ee92258b97aa83dfa93c621800000000540000800000008000000080010000005000000000';
10181040

10191041
const txRequestResponse = {
10201042
txRequestId: 'txReq123',
@@ -1023,7 +1045,7 @@ describe('Lightning wallets', function () {
10231045
transactions: [
10241046
{
10251047
unsignedTx: {
1026-
serializedTxHex: 'unsignedTx123',
1048+
serializedTxHex: unsignedPsbtHex,
10271049
},
10281050
},
10291051
],
@@ -1035,7 +1057,7 @@ describe('Lightning wallets', function () {
10351057
transactions: [
10361058
{
10371059
unsignedTx: {
1038-
serializedTxHex: 'unsignedTx123',
1060+
serializedTxHex: unsignedPsbtHex,
10391061
coinSpecific: {
10401062
signature: 'someSignature',
10411063
},

0 commit comments

Comments
 (0)