From 3259e27d77777caf598a81d55f9fd3d0b41b0b7f Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Wed, 8 Dec 2021 11:06:54 -0330 Subject: [PATCH] Fix contract deployments (#112) --- index.js | 6 +++- test/test-eth-trezor-keyring.js | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index f549fae..af69499 100644 --- a/index.js +++ b/index.js @@ -295,7 +295,11 @@ class TrezorKeyring extends EventEmitter { } else { // new-style transaction from @ethereumjs/tx package // we can just copy tx.toJSON() for everything except chainId, which must be a number - transaction = { ...tx.toJSON(), chainId }; + transaction = { + ...tx.toJSON(), + chainId, + to: this._normalize(tx.to), + }; } try { diff --git a/test/test-eth-trezor-keyring.js b/test/test-eth-trezor-keyring.js index b728063..38a008e 100644 --- a/test/test-eth-trezor-keyring.js +++ b/test/test-eth-trezor-keyring.js @@ -71,6 +71,17 @@ const newFakeTx = TransactionFactory.fromTxData( { common, freeze: false }, ); +const contractDeploymentFakeTx = TransactionFactory.fromTxData( + { + nonce: '0x00', + gasPrice: '0x09184e72a000', + gasLimit: '0x2710', + value: '0x00', + data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057', + }, + { common, freeze: false }, +); + const fakeTypeTwoTx = FeeMarketEIP1559Transaction.fromTxData( { nonce: '0x00', @@ -416,6 +427,50 @@ describe('TrezorKeyring', function () { assert(TrezorConnect.ethereumSignTransaction.calledOnce); }); + it('should pass serialized contract deployment transaction to trezor and return signed tx', async function () { + sinon.stub(TransactionFactory, 'fromTxData').callsFake(() => { + // without having a private key/public key pair in this test, we have + // mock out this method and return the original tx because we can't + // replicate r and s values without the private key. + return contractDeploymentFakeTx; + }); + + sinon.stub(TrezorConnect, 'ethereumSignTransaction').callsFake(() => { + return Promise.resolve({ + success: true, + payload: { v: '0x25', r: '0x0', s: '0x0' }, + }); + }); + + sinon + .stub(contractDeploymentFakeTx, 'getSenderAddress') + .callsFake(() => fakeAccounts[0]); + + sinon + .stub(contractDeploymentFakeTx, 'verifySignature') + .callsFake(() => true); + + const returnedTx = await keyring.signTransaction( + fakeAccounts[0], + contractDeploymentFakeTx, + ); + // ensure we get a new version transaction back + assert.equal(returnedTx.getChainId, undefined); + assert.equal(returnedTx.common.chainIdBN().toString('hex'), '1'); + assert(TrezorConnect.ethereumSignTransaction.calledOnce); + assert.deepEqual( + TrezorConnect.ethereumSignTransaction.getCall(0).args[0], + { + path: `m/44'/60'/0'/0/0`, + transaction: { + ...contractDeploymentFakeTx.toJSON(), + to: '0x', + chainId: 1, + }, + }, + ); + }); + it('should pass correctly encoded EIP1559 transaction to trezor and return signed tx', async function () { // Copied from @MetaMask/eth-ledger-bridge-keyring // Generated by signing fakeTypeTwoTx with an unknown private key