@@ -7,12 +7,30 @@ import { AbstractUtxoCoin, TxFormat } from '../../src';
77
88import { utxoCoins , defaultBitGo } from './util' ;
99
10+ type WalletType = 'hot' | 'cold' | 'custodial' | 'custodialPaired' | 'trading' ;
11+ type WalletSubType = 'distributedCustody' ;
12+ type WalletFlag = { name : string ; value : string } ;
13+
1014type WalletOptions = {
11- type ?: 'hot' | 'cold' | 'custodial' | 'custodialPaired' | 'trading' ;
12- subType ?: string ;
13- walletFlags ?: Array < { name : string ; value : string } > ;
15+ type ?: WalletType ;
16+ subType ?: WalletSubType ;
17+ walletFlags ?: WalletFlag [ ] ;
1418} ;
1519
20+ /**
21+ * Enumerates common wallet configurations for testing
22+ */
23+ export function getWalletConfigurations ( ) : Array < { name : string ; options : WalletOptions } > {
24+ return [
25+ { name : 'hot wallet' , options : { type : 'hot' } } ,
26+ { name : 'cold wallet' , options : { type : 'cold' } } ,
27+ { name : 'custodial wallet' , options : { type : 'custodial' } } ,
28+ { name : 'distributedCustody wallet' , options : { type : 'cold' , subType : 'distributedCustody' } } ,
29+ { name : 'musigKp wallet' , options : { type : 'cold' , walletFlags : [ { name : 'musigKp' , value : 'true' } ] } } ,
30+ { name : 'hot musigKp wallet' , options : { type : 'hot' , walletFlags : [ { name : 'musigKp' , value : 'true' } ] } } ,
31+ ] ;
32+ }
33+
1634/**
1735 * Helper function to create a mock wallet for testing
1836 */
@@ -35,115 +53,122 @@ export function getTxFormat(coin: AbstractUtxoCoin, wallet: Wallet, requestedFor
3553}
3654
3755/**
38- * Helper function to run a txFormat test with named arguments
56+ * Helper function to run a txFormat test with named arguments.
57+ * By default, iterates over all wallet configurations and all coins.
3958 */
4059function runTest ( params : {
4160 description : string ;
42- walletOptions : WalletOptions ;
43- expectedTxFormat : TxFormat | undefined | ( ( coin : AbstractUtxoCoin ) => TxFormat | undefined ) ;
61+ expectedTxFormat :
62+ | TxFormat
63+ | undefined
64+ | ( ( coin : AbstractUtxoCoin , walletConfig : WalletOptions ) => TxFormat | undefined ) ;
4465 coinFilter ?: ( coin : AbstractUtxoCoin ) => boolean ;
66+ walletFilter ?: ( walletConfig : { name : string ; options : WalletOptions } ) => boolean ;
4567 requestedTxFormat ?: TxFormat ;
4668} ) : void {
4769 it ( params . description , function ( ) {
48- for ( const coin of utxoCoins ) {
49- // Skip coins that don't match the filter
50- if ( params . coinFilter && ! params . coinFilter ( coin ) ) {
70+ const walletConfigs = getWalletConfigurations ( ) ;
71+
72+ for ( const walletConfig of walletConfigs ) {
73+ // Skip wallet configurations that don't match the filter
74+ if ( params . walletFilter && ! params . walletFilter ( walletConfig ) ) {
5175 continue ;
5276 }
5377
54- const wallet = createMockWallet ( coin , params . walletOptions ) ;
55- const txFormat = getTxFormat ( coin , wallet , params . requestedTxFormat ) ;
56-
57- const expectedTxFormat =
58- typeof params . expectedTxFormat === 'function' ? params . expectedTxFormat ( coin ) : params . expectedTxFormat ;
59-
60- assert . strictEqual (
61- txFormat ,
62- expectedTxFormat ,
63- `${ params . description } - ${ coin . getChain ( ) } : expected ${ expectedTxFormat } , got ${ txFormat } `
64- ) ;
78+ for ( const coin of utxoCoins ) {
79+ // Skip coins that don't match the filter
80+ if ( params . coinFilter && ! params . coinFilter ( coin ) ) {
81+ continue ;
82+ }
83+
84+ const wallet = createMockWallet ( coin , walletConfig . options ) ;
85+ const txFormat = getTxFormat ( coin , wallet , params . requestedTxFormat ) ;
86+
87+ const expectedTxFormat =
88+ typeof params . expectedTxFormat === 'function'
89+ ? params . expectedTxFormat ( coin , walletConfig . options )
90+ : params . expectedTxFormat ;
91+
92+ assert . strictEqual (
93+ txFormat ,
94+ expectedTxFormat ,
95+ `${ params . description } - ${
96+ walletConfig . name
97+ } - ${ coin . getChain ( ) } : expected ${ expectedTxFormat } , got ${ txFormat } `
98+ ) ;
99+ }
65100 }
66101 } ) ;
67102}
68103
69104describe ( 'txFormat' , function ( ) {
70105 describe ( 'getDefaultTxFormat' , function ( ) {
71- // Testnet hot wallets default to PSBT (except ZCash)
106+ // ZCash never defaults to PSBT
72107 runTest ( {
73- description : 'should default to psbt for testnet hot wallets (except zcash)' ,
74- walletOptions : { type : 'hot' } ,
75- expectedTxFormat : ( coin ) => {
76- const isZcash = utxolib . getMainnet ( coin . network ) === utxolib . networks . zcash ;
77- // ZCash is excluded from PSBT default due to PSBT support issues (BTC-1322)
78- return isZcash ? undefined : 'psbt' ;
79- } ,
80- coinFilter : ( coin ) => utxolib . isTestnet ( coin . network ) ,
108+ description : 'should never return psbt for zcash' ,
109+ coinFilter : ( coin ) => utxolib . getMainnet ( coin . network ) === utxolib . networks . zcash ,
110+ expectedTxFormat : undefined ,
81111 } ) ;
82112
83- // Mainnet Bitcoin hot wallets default to PSBT
113+ // All non-ZCash testnet wallets default to PSBT
84114 runTest ( {
85- description : 'should default to psbt for mainnet bitcoin hot wallets' ,
86- walletOptions : { type : 'hot' } ,
87- expectedTxFormat : 'psbt' ,
115+ description : 'should always return psbt for testnet (non-zcash)' ,
88116 coinFilter : ( coin ) =>
89- utxolib . isMainnet ( coin . network ) && utxolib . getMainnet ( coin . network ) === utxolib . networks . bitcoin ,
117+ utxolib . isTestnet ( coin . network ) && utxolib . getMainnet ( coin . network ) !== utxolib . networks . zcash ,
118+ expectedTxFormat : 'psbt' ,
90119 } ) ;
91120
92- // Mainnet non-Bitcoin hot wallets do NOT default to PSBT
121+ // DistributedCustody wallets default to PSBT (mainnet only, testnet already covered)
93122 runTest ( {
94- description : 'should not default to psbt for mainnet non-bitcoin hot wallets' ,
95- walletOptions : { type : 'hot' } ,
96- expectedTxFormat : undefined ,
123+ description : 'should return psbt for distributedCustody wallets on mainnet' ,
97124 coinFilter : ( coin ) =>
98- utxolib . isMainnet ( coin . network ) && utxolib . getMainnet ( coin . network ) !== utxolib . networks . bitcoin ,
125+ utxolib . isMainnet ( coin . network ) && utxolib . getMainnet ( coin . network ) !== utxolib . networks . zcash ,
126+ walletFilter : ( w ) => w . options . subType === 'distributedCustody' ,
127+ expectedTxFormat : 'psbt' ,
99128 } ) ;
100129
101- // Cold wallets default to PSBT
130+ // MuSig2 wallets default to PSBT (mainnet only, testnet already covered)
102131 runTest ( {
103- description : 'should default to psbt for testnet cold wallets as well' ,
104- walletOptions : { type : 'cold' } ,
105- coinFilter : ( coin ) => utxolib . isTestnet ( coin . network ) ,
106- expectedTxFormat : ( coin ) => {
107- const isZcash = utxolib . getMainnet ( coin . network ) === utxolib . networks . zcash ;
108- // ZCash is excluded from PSBT default due to PSBT support issues (BTC-1322)
109- return isZcash ? undefined : 'psbt' ;
110- } ,
132+ description : 'should return psbt for wallets with musigKp flag on mainnet' ,
133+ coinFilter : ( coin ) =>
134+ utxolib . isMainnet ( coin . network ) && utxolib . getMainnet ( coin . network ) !== utxolib . networks . zcash ,
135+ walletFilter : ( w ) => Boolean ( w . options . walletFlags ?. some ( ( f ) => f . name === 'musigKp' && f . value === 'true' ) ) ,
136+ expectedTxFormat : 'psbt' ,
111137 } ) ;
112138
113- // DistributedCustody wallets default to PSBT
139+ // Mainnet Bitcoin hot wallets default to PSBT
114140 runTest ( {
115- description : 'should default to psbt for distributedCustody wallets' ,
116- walletOptions : { type : 'cold' , subType : 'distributedCustody' } ,
117- expectedTxFormat : ( coin ) => {
118- const isZcash = utxolib . getMainnet ( coin . network ) === utxolib . networks . zcash ;
119- // ZCash is excluded from PSBT default due to PSBT support issues (BTC-1322)
120- return isZcash ? undefined : 'psbt' ;
121- } ,
141+ description : 'should return psbt for mainnet bitcoin hot wallets' ,
142+ coinFilter : ( coin ) =>
143+ utxolib . isMainnet ( coin . network ) && utxolib . getMainnet ( coin . network ) === utxolib . networks . bitcoin ,
144+ walletFilter : ( w ) => w . options . type === 'hot' ,
145+ expectedTxFormat : 'psbt' ,
122146 } ) ;
123147
124- // Wallets with musigKp flag default to PSBT
148+ // Other mainnet wallets do NOT default to PSBT
125149 runTest ( {
126- description : 'should default to psbt for wallets with musigKp flag' ,
127- walletOptions : { type : 'cold' , walletFlags : [ { name : 'musigKp' , value : 'true' } ] } ,
128- expectedTxFormat : ( coin ) => {
129- const isZcash = utxolib . getMainnet ( coin . network ) === utxolib . networks . zcash ;
130- // ZCash is excluded from PSBT default due to PSBT support issues (BTC-1322)
131- return isZcash ? undefined : 'psbt' ;
150+ description : 'should return undefined for other mainnet wallets' ,
151+ coinFilter : ( coin ) =>
152+ utxolib . isMainnet ( coin . network ) && utxolib . getMainnet ( coin . network ) !== utxolib . networks . zcash ,
153+ walletFilter : ( w ) => {
154+ const isHotBitcoin = w . options . type === 'hot' ; // This will be bitcoin hot wallets
155+ const isDistributedCustody = w . options . subType === 'distributedCustody' ;
156+ const hasMusigKpFlag = Boolean ( w . options . walletFlags ?. some ( ( f ) => f . name === 'musigKp' && f . value === 'true' ) ) ;
157+ // Only test "other" wallets - exclude the special cases
158+ return ! isHotBitcoin && ! isDistributedCustody && ! hasMusigKpFlag ;
132159 } ,
160+ expectedTxFormat : undefined ,
133161 } ) ;
134162
135- // Explicitly specified legacy format is respected
163+ // Test explicitly requested formats
136164 runTest ( {
137- description : 'should respect explicitly specified legacy txFormat' ,
138- walletOptions : { type : 'hot' } ,
165+ description : 'should respect explicitly requested legacy format' ,
139166 expectedTxFormat : 'legacy' ,
140167 requestedTxFormat : 'legacy' ,
141168 } ) ;
142169
143- // Explicitly specified psbt format is respected
144170 runTest ( {
145- description : 'should respect explicitly specified psbt txFormat' ,
146- walletOptions : { type : 'cold' } ,
171+ description : 'should respect explicitly requested psbt format' ,
147172 expectedTxFormat : 'psbt' ,
148173 requestedTxFormat : 'psbt' ,
149174 } ) ;
0 commit comments