@@ -94,6 +94,104 @@ describe('Sign ETH Transaction', async function () {
9494 } ) ;
9595} ) ;
9696
97+ describe ( 'Sign ETH Transaction – txInfo fallback' , async function ( ) {
98+ let bitgo : TestBitGoAPI ;
99+ let ethWallet ;
100+ const recipients = [ { address : '0xe59dfe5c67114b39a5662cc856be536c614124c0' , amount : '100000' } ] ;
101+
102+ before ( function ( ) {
103+ bitgo = TestBitGo . decorate ( BitGoAPI , { env : 'test' } ) ;
104+ bitgo . initializeTestVars ( ) ;
105+ bitgo . safeRegister ( 'teth' , Teth . createInstance ) ;
106+ const coin = bitgo . coin ( 'teth' ) ;
107+ ethWallet = coin . newWalletObject ( { } ) ;
108+ } ) ;
109+
110+ afterEach ( function ( ) {
111+ sinon . restore ( ) ;
112+ } ) ;
113+
114+ it ( 'should read recipients from txPrebuild.txInfo.recipients when txPrebuild.recipients is absent' , async function ( ) {
115+ sinon . stub ( Util , 'xprvToEthPrivateKey' ) ;
116+ sinon . stub ( Util , 'ethSignMsgHash' ) ;
117+ sinon . stub ( ethWallet . getOperationSha3ForExecuteAndConfirm ) ;
118+
119+ const txPrebuild = { txInfo : { recipients, nextContractSequenceId : 1 } } ;
120+ const { halfSigned } = ( await ethWallet . signTransaction ( { txPrebuild, prv : 'my_user_prv' } ) ) as any ;
121+ halfSigned . should . have . property ( 'recipients' , recipients ) ;
122+ } ) ;
123+
124+ it ( 'should prefer txPrebuild.recipients over txPrebuild.txInfo.recipients' , async function ( ) {
125+ sinon . stub ( Util , 'xprvToEthPrivateKey' ) ;
126+ sinon . stub ( Util , 'ethSignMsgHash' ) ;
127+ sinon . stub ( ethWallet . getOperationSha3ForExecuteAndConfirm ) ;
128+
129+ const txInfoRecipients = [ { address : '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' , amount : '1' } ] ;
130+ const txPrebuild = { recipients, nextContractSequenceId : 0 , txInfo : { recipients : txInfoRecipients } } ;
131+ const { halfSigned } = ( await ethWallet . signTransaction ( { txPrebuild, prv : 'my_user_prv' } ) ) as any ;
132+ halfSigned . should . have . property ( 'recipients' , recipients ) ;
133+ } ) ;
134+
135+ it ( 'should use txPrebuild.txInfo.nextContractSequenceId when nextContractSequenceId is absent' , async function ( ) {
136+ sinon . stub ( Util , 'xprvToEthPrivateKey' ) ;
137+ sinon . stub ( Util , 'ethSignMsgHash' ) ;
138+ sinon . stub ( ethWallet . getOperationSha3ForExecuteAndConfirm ) ;
139+
140+ const txPrebuild = { recipients, txInfo : { nextContractSequenceId : 5 } } ;
141+ const { halfSigned } = ( await ethWallet . signTransaction ( { txPrebuild, prv : 'my_user_prv' } ) ) as any ;
142+ halfSigned . should . have . property ( 'contractSequenceId' , 5 ) ;
143+ } ) ;
144+
145+ it ( 'should throw when nextContractSequenceId is absent from both txPrebuild and txInfo' , async function ( ) {
146+ await ethWallet
147+ . signTransaction ( { txPrebuild : { recipients } , prv : 'my_user_prv' } )
148+ . should . be . rejectedWith ( 'transaction prebuild missing required property nextContractSequenceId' ) ;
149+ } ) ;
150+
151+ it ( 'should use txPrebuild.txInfo.eip1559 when txPrebuild.eip1559 is absent' , async function ( ) {
152+ sinon . stub ( Util , 'xprvToEthPrivateKey' ) ;
153+ sinon . stub ( Util , 'ethSignMsgHash' ) ;
154+ sinon . stub ( ethWallet . getOperationSha3ForExecuteAndConfirm ) ;
155+
156+ const eip1559 = { maxFeePerGas : '100' , maxPriorityFeePerGas : '10' } ;
157+ const txPrebuild = { recipients, nextContractSequenceId : 0 , txInfo : { eip1559 } } ;
158+ const { halfSigned } = ( await ethWallet . signTransaction ( { txPrebuild, prv : 'my_user_prv' } ) ) as any ;
159+ halfSigned . should . have . property ( 'eip1559' , eip1559 ) ;
160+ } ) ;
161+
162+ it ( 'should prefer txPrebuild.eip1559 over txPrebuild.txInfo.eip1559' , async function ( ) {
163+ sinon . stub ( Util , 'xprvToEthPrivateKey' ) ;
164+ sinon . stub ( Util , 'ethSignMsgHash' ) ;
165+ sinon . stub ( ethWallet . getOperationSha3ForExecuteAndConfirm ) ;
166+
167+ const eip1559 = { maxFeePerGas : '200' , maxPriorityFeePerGas : '20' } ;
168+ const txInfoEip1559 = { maxFeePerGas : '999' , maxPriorityFeePerGas : '99' } ;
169+ const txPrebuild = { recipients, nextContractSequenceId : 0 , eip1559, txInfo : { eip1559 : txInfoEip1559 } } ;
170+ const { halfSigned } = ( await ethWallet . signTransaction ( { txPrebuild, prv : 'my_user_prv' } ) ) as any ;
171+ halfSigned . should . have . property ( 'eip1559' , eip1559 ) ;
172+ } ) ;
173+
174+ it ( 'should use txPrebuild.txInfo.isBatch when txPrebuild.isBatch is absent' , async function ( ) {
175+ sinon . stub ( Util , 'xprvToEthPrivateKey' ) ;
176+ sinon . stub ( Util , 'ethSignMsgHash' ) ;
177+ sinon . stub ( ethWallet . getOperationSha3ForExecuteAndConfirm ) ;
178+
179+ const txPrebuild = { recipients, nextContractSequenceId : 0 , txInfo : { isBatch : true } } ;
180+ const { halfSigned } = ( await ethWallet . signTransaction ( { txPrebuild, prv : 'my_user_prv' } ) ) as any ;
181+ halfSigned . should . have . property ( 'isBatch' , true ) ;
182+ } ) ;
183+
184+ it ( 'should prefer txPrebuild.isBatch over txPrebuild.txInfo.isBatch' , async function ( ) {
185+ sinon . stub ( Util , 'xprvToEthPrivateKey' ) ;
186+ sinon . stub ( Util , 'ethSignMsgHash' ) ;
187+ sinon . stub ( ethWallet . getOperationSha3ForExecuteAndConfirm ) ;
188+
189+ const txPrebuild = { recipients, nextContractSequenceId : 0 , isBatch : false , txInfo : { isBatch : true } } ;
190+ const { halfSigned } = ( await ethWallet . signTransaction ( { txPrebuild, prv : 'my_user_prv' } ) ) as any ;
191+ halfSigned . should . have . property ( 'isBatch' , false ) ;
192+ } ) ;
193+ } ) ;
194+
97195describe ( 'Ethereum Hop Transactions' , function ( ) {
98196 let bitgo : TestBitGoAPI ;
99197 let ethWallet ;
0 commit comments