@@ -9,7 +9,10 @@ import {
99 BitGoAPITestHarness ,
1010 DEFAULT_ASYNC_MODE_CONFIG ,
1111 makeMasterExpressTestConfig ,
12+ makeSplitAwmMasterExpressConfig ,
1213 nockAsyncMultisigRecoveryJob ,
14+ nockAsyncRecoveryJobBypass ,
15+ nockSplitAwmMultisigRecovery ,
1316} from './testUtils' ;
1417
1518describe ( 'POST /api/v1/:coin/advancedwallet/recoveryconsolidations' , ( ) => {
@@ -735,4 +738,74 @@ describe('POST /api/v1/:coin/advancedwallet/recoveryconsolidations', () => {
735738 ) ;
736739 } ) ;
737740 } ) ;
741+
742+ describe ( 'Split AWM (separate user and backup AWMs)' , ( ) => {
743+ const halfSignedTxHex = 'half-signed-trx-tx' ;
744+ const fullSignedTxHex = 'signed-trx-tx' ;
745+
746+ const trxConsolidationRequest = {
747+ multisigType : 'onchain' as const ,
748+ userPub : mockUserPub ,
749+ backupPub : mockBackupPub ,
750+ bitgoPub : mockBitgoPub ,
751+ tokenContractAddress : trxTokenContractAddress ,
752+ startingScanIndex : 1 ,
753+ endingScanIndex : 3 ,
754+ } ;
755+
756+ function nockTrxTwoAddressConsolidationScan ( ) {
757+ const tronBalanceWithToken = {
758+ data : [ { balance : 200_000_000 , trc20 : [ { [ trxTokenContractAddress ] : '1000000' } ] } ] ,
759+ } ;
760+ nock ( tronBase ) . get ( `/v1/accounts/${ TRX_ADDR_1 } ` ) . reply ( 200 , tronBalanceWithToken ) ;
761+ nock ( tronBase ) . post ( '/wallet/triggersmartcontract' ) . reply ( 200 , { transaction : TRON_MOCK_TX } ) ;
762+ nock ( tronBase ) . get ( `/v1/accounts/${ TRX_ADDR_2 } ` ) . reply ( 200 , tronBalanceWithToken ) ;
763+ nock ( tronBase ) . post ( '/wallet/triggersmartcontract' ) . reply ( 200 , { transaction : TRON_MOCK_TX } ) ;
764+ }
765+
766+ it ( 'calls user AWM with keyToSign=user then backup AWM with keyToSign=backup per tx' , async ( ) => {
767+ nockTrxTwoAddressConsolidationScan ( ) ;
768+ const { userAwmNock, backupAwmNock } = nockSplitAwmMultisigRecovery ( {
769+ coin : 'trx' ,
770+ halfSignedTxHex,
771+ fullSignedTxHex,
772+ times : 2 ,
773+ } ) ;
774+
775+ const response = await request
776+ . agent ( expressApp ( makeSplitAwmMasterExpressConfig ( ) ) )
777+ . post ( '/api/v1/trx/advancedwallet/recoveryconsolidations' )
778+ . set ( 'Authorization' , `Bearer ${ accessToken } ` )
779+ . send ( trxConsolidationRequest ) ;
780+
781+ response . status . should . equal ( 200 ) ;
782+ response . body . signedTxs . should . have . length ( 2 ) ;
783+ response . body . signedTxs [ 0 ] . should . have . property ( 'txHex' , fullSignedTxHex ) ;
784+ userAwmNock . done ( ) ;
785+ backupAwmNock . done ( ) ;
786+ } ) ;
787+
788+ it ( 'stays sync when async mode is enabled (bridge is not called)' , async ( ) => {
789+ nockTrxTwoAddressConsolidationScan ( ) ;
790+ const bridgeNock = nockAsyncRecoveryJobBypass ( 'trx' ) ;
791+ const { userAwmNock, backupAwmNock } = nockSplitAwmMultisigRecovery ( {
792+ coin : 'trx' ,
793+ halfSignedTxHex,
794+ fullSignedTxHex,
795+ times : 2 ,
796+ } ) ;
797+
798+ const response = await request
799+ . agent ( expressApp ( makeSplitAwmMasterExpressConfig ( { asyncEnabled : true } ) ) )
800+ . post ( '/api/v1/trx/advancedwallet/recoveryconsolidations' )
801+ . set ( 'Authorization' , `Bearer ${ accessToken } ` )
802+ . send ( trxConsolidationRequest ) ;
803+
804+ response . status . should . equal ( 200 ) ;
805+ response . body . signedTxs . should . have . length ( 2 ) ;
806+ userAwmNock . done ( ) ;
807+ backupAwmNock . done ( ) ;
808+ bridgeNock . isDone ( ) . should . be . false ( ) ;
809+ } ) ;
810+ } ) ;
738811} ) ;
0 commit comments