From c2844f16de9f3d3b954b53acaa17806d45758f21 Mon Sep 17 00:00:00 2001 From: Matt Holtzman Date: Wed, 25 Aug 2021 08:48:41 -0400 Subject: [PATCH] implement eip-1559 support for Trezors --- main/signers/hot/HotSigner/worker.js | 1 + main/signers/trezor-connect/Trezor/index.js | 40 +++++++++++++-------- main/transaction/index.ts | 3 +- test/main/transaction/index.test.js | 30 ++++++++++++++-- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/main/signers/hot/HotSigner/worker.js b/main/signers/hot/HotSigner/worker.js index d7dadd580..1c360cfb4 100644 --- a/main/signers/hot/HotSigner/worker.js +++ b/main/signers/hot/HotSigner/worker.js @@ -50,6 +50,7 @@ class HotSignerWorker { signTransaction (key, rawTx, pseudoCallback) { sign(rawTx, tx => { const signedTx = tx.sign(key) + const serialized = signedTx.serialize().toString('hex') pseudoCallback(null, addHexPrefix(serialized)) diff --git a/main/signers/trezor-connect/Trezor/index.js b/main/signers/trezor-connect/Trezor/index.js index e69d513a2..d01965e5d 100644 --- a/main/signers/trezor-connect/Trezor/index.js +++ b/main/signers/trezor-connect/Trezor/index.js @@ -208,27 +208,39 @@ class Trezor extends Signer { }) } - _normalizeTransaction (rawTx) { - return { - nonce: this.normalize(rawTx.nonce), - gasPrice: this.normalize(rawTx.gasPrice), - gasLimit: this.normalize(rawTx.gasLimit), - to: this.normalize(rawTx.to), - value: this.normalize(rawTx.value), - data: this.normalize(rawTx.data), - chainId: utils.hexToNumber(rawTx.chainId) + _normalizeTransaction (chainId, tx) { + const txJson = tx.toJSON() + + const unsignedTx = { + nonce: this.normalize(txJson.nonce), + gasLimit: this.normalize(txJson.gasLimit), + to: this.normalize(txJson.to), + value: this.normalize(txJson.value), + data: this.normalize(txJson.data), + chainId: utils.hexToNumber(chainId) } + + const optionalFields = ['gasPrice', 'maxFeePerGas', 'maxPriorityFeePerGas'] + + optionalFields.forEach(field => { + if (txJson[field]) { + unsignedTx[field] = this.normalize(txJson[field]) + } + }) + + return unsignedTx } signTransaction (index, rawTx, cb) { - // as of 08-05-2021 Trezor doesn't support EIP-1559 transactions - const legacyTx = londonToLegacy(rawTx) + const compatibility = signerCompatibility(rawTx, this.summary()) + const compatibleTx = compatibility.compatible ? { ...rawTx } : londonToLegacy(rawTx) - const trezorTx = this._normalizeTransaction(legacyTx) - const path = this.getPath(index) - sign(legacyTx, () => { + sign(compatibleTx, () => { return new Promise((resolve, reject) => { + const trezorTx = this._normalizeTransaction(tx) + const path = this.getPath(index) + flex.rpc('trezor.ethereumSignTransaction', this.device.path, path, trezorTx, (err, result) => { return err ? reject(err) diff --git a/main/transaction/index.ts b/main/transaction/index.ts index 367f81780..eae989437 100644 --- a/main/transaction/index.ts +++ b/main/transaction/index.ts @@ -8,6 +8,7 @@ const londonHardforkSigners: SignerCompatibilityByVersion = { seed: () => true, ring: () => true, ledger: version => version.major >= 2 || (version.major >= 1 && version.minor >= 9), + trezor: version => version.major >= 3 || (version.major >= 2 && version.minor >= 4 && version.patch >= 2), lattice: version => version.major >= 1 || version.minor >= 11 } @@ -87,7 +88,7 @@ function usesBaseFee (rawTx: RawTransaction) { function populate (rawTx: RawTransaction, chainConfig: Common, gas: any): TransactionData { const txData: TransactionData = { ...rawTx } - + if (chainConfig.isActivatedEIP(1559)) { txData.type = '0x2' diff --git a/test/main/transaction/index.test.js b/test/main/transaction/index.test.js index 74ed8a4c0..097b17eb5 100644 --- a/test/main/transaction/index.test.js +++ b/test/main/transaction/index.test.js @@ -118,8 +118,8 @@ describe('#signerCompatibility', () => { expect(compatibility.compatible).toBe(true) }) - it('is not compatible for eip-1559 transactions on Trezor signers', () => { - const appVersion = { major: 1, minor: 1, patch: 1 } + it('is not compatible for eip-1559 transactions on Trezor signers using firmware prior to 2.4.2', () => { + const appVersion = { major: 2, minor: 3, patch: 1 } const tx = { type: '0x2' } @@ -130,6 +130,32 @@ describe('#signerCompatibility', () => { expect(compatibility.tx).toBe('london') expect(compatibility.compatible).toBe(false) }) + + it('is compatible for eip-1559 transactions on Trezor signers using firmware 2.4.2+', () => { + const appVersion = { major: 2, minor: 4, patch: 3 } + const tx = { + type: '0x2' + } + + const compatibility = signerCompatibility(tx, { type: 'trezor', appVersion }) + + expect(compatibility.signer).toBe('trezor') + expect(compatibility.tx).toBe('london') + expect(compatibility.compatible).toBe(true) + }) + + it('is compatible for eip-1559 transactions on Trezor signers using firmware 3.x', () => { + const appVersion = { major: 3, minor: 2, patch: 4 } + const tx = { + type: '0x2' + } + + const compatibility = signerCompatibility(tx, { type: 'trezor', appVersion }) + + expect(compatibility.signer).toBe('trezor') + expect(compatibility.tx).toBe('london') + expect(compatibility.compatible).toBe(true) + }) }) describe('#londonToLegacy', () => {