diff --git a/shared/modules/transaction.utils.js b/shared/modules/transaction.utils.js index 9e89679f8..092f8e465 100644 --- a/shared/modules/transaction.utils.js +++ b/shared/modules/transaction.utils.js @@ -1,6 +1,40 @@ +import { isHexString } from 'ethereumjs-util'; + export function transactionMatchesNetwork(transaction, chainId, networkId) { if (typeof transaction.chainId !== 'undefined') { return transaction.chainId === chainId; } return transaction.metamaskNetworkId === networkId; } + +/** + * Determines if the maxFeePerGas and maxPriorityFeePerGas fields are supplied + * and valid inputs. This will return false for non hex string inputs. + * @param {import("../constants/transaction").TransactionMeta} transaction - + * the transaction to check + * @returns {boolean} true if transaction uses valid EIP1559 fields + */ +export function isEIP1559Transaction(transaction) { + return ( + isHexString(transaction.txParams.maxFeePerGas) && + isHexString(transaction.txParams.maxPriorityFeePerGas) + ); +} + +/** + * Determine if the maxFeePerGas and maxPriorityFeePerGas fields are not + * supplied and that the gasPrice field is valid if it is provided. This will + * return false if gasPrice is a non hex string. + * @param {import("../constants/transaction").TransactionMeta} transaction - + * the transaction to check + * @returns {boolean} true if transaction uses valid Legacy fields OR lacks + * EIP1559 fields + */ +export function isLegacyTransaction(transaction) { + return ( + typeof transaction.txParams.maxFeePerGas === 'undefined' && + typeof transaction.txParams.maxPriorityFeePerGas === 'undefined' && + (typeof transaction.txParams.gasPrice === 'undefined' || + isHexString(transaction.txParams.gasPrice)) + ); +} diff --git a/shared/modules/transaction.utils.test.js b/shared/modules/transaction.utils.test.js new file mode 100644 index 000000000..3a333caa7 --- /dev/null +++ b/shared/modules/transaction.utils.test.js @@ -0,0 +1,83 @@ +import { isEIP1559Transaction, isLegacyTransaction } from './transaction.utils'; + +describe('Transaction.utils', function () { + describe('isEIP1559Transaction', function () { + it('should return true if both maxFeePerGas and maxPriorityFeePerGas are hex strings', () => { + expect( + isEIP1559Transaction({ + txParams: { maxFeePerGas: '0x1', maxPriorityFeePerGas: '0x1' }, + }), + ).toBe(true); + }); + + it('should return false if either maxFeePerGas and maxPriorityFeePerGas are non-hex strings', () => { + expect( + isEIP1559Transaction({ + txParams: { maxFeePerGas: 0, maxPriorityFeePerGas: '0x1' }, + }), + ).toBe(false); + expect( + isEIP1559Transaction({ + txParams: { maxFeePerGas: '0x1', maxPriorityFeePerGas: 'fail' }, + }), + ).toBe(false); + }); + + it('should return false if either maxFeePerGas or maxPriorityFeePerGas are not supplied', () => { + expect( + isEIP1559Transaction({ + txParams: { maxPriorityFeePerGas: '0x1' }, + }), + ).toBe(false); + expect( + isEIP1559Transaction({ + txParams: { maxFeePerGas: '0x1' }, + }), + ).toBe(false); + }); + }); + + describe('isLegacyTransaction', function () { + it('should return true if no gas related fields are supplied', () => { + expect( + isLegacyTransaction({ + txParams: {}, + }), + ).toBe(true); + }); + + it('should return true if gasPrice is solely provided', () => { + expect( + isLegacyTransaction({ + txParams: { gasPrice: '0x1' }, + }), + ).toBe(true); + }); + + it('should return false if gasPrice is not a hex string', () => { + expect( + isLegacyTransaction({ + txParams: { gasPrice: 100 }, + }), + ).toBe(false); + }); + + it('should return false if either maxFeePerGas or maxPriorityFeePerGas are supplied', () => { + expect( + isLegacyTransaction({ + txParams: { + maxFeePerGas: '0x1', + }, + }), + ).toBe(false); + + expect( + isLegacyTransaction({ + txParams: { + maxPriorityFeePerGas: 'any data', + }, + }), + ).toBe(false); + }); + }); +});