From d1499921eeed302931f32a2d3b71618a6d55f8b5 Mon Sep 17 00:00:00 2001 From: netbonus <151201453+netbonus@users.noreply.github.com> Date: Thu, 20 Feb 2025 05:00:53 -0500 Subject: [PATCH] fix tests --- src/__test__/utils/builders.ts | 17 ++++++---------- src/api/signing.ts | 5 +++-- src/calldata/evm.ts | 18 ++++++++++++----- src/ethereum.ts | 37 ++++++++++++++++++++++++++++++++++ src/types/sign.ts | 18 ++++++++--------- 5 files changed, 68 insertions(+), 27 deletions(-) diff --git a/src/__test__/utils/builders.ts b/src/__test__/utils/builders.ts index dab88e88..aa62ce27 100644 --- a/src/__test__/utils/builders.ts +++ b/src/__test__/utils/builders.ts @@ -14,7 +14,6 @@ import { } from '../../constants'; import type { Currency, SignRequestParams, SigningPath } from '../../types'; import type { FirmwareConstants } from '../../types/firmware'; -import type { ETH_MESSAGE_PROTOCOLS } from '../../types/sign'; import type { TestRequestPayload } from '../../types/utils'; import { randomBytes } from '../../util'; import { MSG_PAYLOAD_METADATA_SZ } from './constants'; @@ -302,10 +301,12 @@ export const buildEncDefs = (vectors: any) => { }); // The calldata is already in hex format, we just need to ensure it has 0x prefix - const encDefsCalldata = vectors.canonicalNames.map((_: string, idx: number) => { - const calldata = `0x${idx.toString(16).padStart(8, '0')}`; - return calldata; - }); + const encDefsCalldata = vectors.canonicalNames.map( + (_: string, idx: number) => { + const calldata = `0x${idx.toString(16).padStart(8, '0')}`; + return calldata; + }, + ); return { encDefs, encDefsCalldata }; }; @@ -376,9 +377,3 @@ export function buildMockConnectedClient(opts) { stateData: JSON.stringify(stateData), }); } - -export const buildEthMsgRequest = (protocol: ETH_MESSAGE_PROTOCOLS = 'signPersonal') => ({ - protocol, - payload: Buffer.from('test message'), - signerPath: [0x80000000 + 44, 0x80000000 + 60, 0x80000000, 0, 0], -}); diff --git a/src/api/signing.ts b/src/api/signing.ts index e6a5afbc..5e774ab7 100644 --- a/src/api/signing.ts +++ b/src/api/signing.ts @@ -1,4 +1,4 @@ -import { Transaction } from 'ethers'; +import { serializeTransaction } from 'viem'; import { Constants } from '..'; import { BTC_LEGACY_DERIVATION, @@ -8,6 +8,7 @@ import { DEFAULT_ETH_DERIVATION, SOLANA_DERIVATION, } from '../constants'; +import { toViemTransaction } from '../ethereum'; import { fetchDecoder } from '../functions/fetchDecoder'; import { BitcoinSignPayload, @@ -23,7 +24,7 @@ export const sign = async ( transaction: TransactionRequest, overrides?: SignRequestParams, ): Promise => { - const serializedTx = Transaction.from(transaction).unsignedSerialized; + const serializedTx = serializeTransaction(toViemTransaction(transaction)); const payload: SigningPayload = { signerPath: DEFAULT_ETH_DERIVATION, diff --git a/src/calldata/evm.ts b/src/calldata/evm.ts index af162640..5c65d85a 100644 --- a/src/calldata/evm.ts +++ b/src/calldata/evm.ts @@ -1,6 +1,5 @@ import { keccak256 } from 'js-sha3'; -import { decodeAbiParameters, type Hex } from 'viem'; - +import { decodeAbiParameters, parseAbiParameters } from 'viem'; /** * Look through an ABI definition to see if there is a function that matches the signature provided. * @param sig a 0x-prefixed hex string containing 4 bytes of info @@ -76,9 +75,18 @@ export const getNestedCalldata = function (def, calldata) { // Skip past first item, which is the function name const defParams = def.slice(1); const strParams = getParamStrNames(defParams); - const abiParams = strParams.map((type) => ({ type })); - const hexData = `0x${calldata.slice(4).toString('hex')}` as Hex; - const decoded = decodeAbiParameters(abiParams, hexData); + const hexStr = ('0x' + calldata.slice(4).toString('hex')) as `0x${string}`; + // Convert strParams to viem's format + const viemParams = strParams.map((type) => { + // Convert tuple format from 'tuple(uint256,uint128)' to '(uint256,uint128)' + if (type.startsWith('tuple(')) { + return type.replace('tuple', ''); + } + return type; + }); + + const abiParams = parseAbiParameters(viemParams.join(',')); + const decoded = decodeAbiParameters(abiParams, hexStr); function couldBeNestedDef(x) { return (x.length - 4) % 32 === 0; diff --git a/src/ethereum.ts b/src/ethereum.ts index 1eb7d55b..c820de0b 100644 --- a/src/ethereum.ts +++ b/src/ethereum.ts @@ -23,6 +23,9 @@ import { } from './util'; import cbor from 'cbor'; import bdec from 'cbor-bigdecimal'; +import { TransactionSerializable } from 'viem'; +import { TRANSACTION_TYPE, TransactionRequest } from './types'; + bdec(cbor); const buildEthereumMsgRequest = function (input) { @@ -983,6 +986,40 @@ const ethConvertLegacyToGenericReq = function (req) { } }; +// Convert an ethers `TransactionRequest` to a viem `TransactionSerializable` +export const toViemTransaction = ( + tx: TransactionRequest, +): TransactionSerializable => { + const base = { + to: tx.to as `0x${string}`, + value: tx.value ? BigInt(tx.value) : undefined, + data: tx.data as `0x${string}`, + nonce: tx.nonce, + gas: tx.gasLimit ? BigInt(tx.gasLimit) : undefined, + }; + + if (tx.type === TRANSACTION_TYPE.EIP1559) { + return { + ...base, + type: 'eip1559', + maxFeePerGas: tx.maxFeePerGas ? BigInt(tx.maxFeePerGas) : undefined, + maxPriorityFeePerGas: tx.maxPriorityFeePerGas + ? BigInt(tx.maxPriorityFeePerGas) + : undefined, + chainId: tx.chainId, + accessList: tx.accessList?.map((item) => ({ + address: item.address as `0x${string}`, + storageKeys: item.storageKeys as `0x${string}`[], + })), + }; + } + + return { + ...base, + gasPrice: tx.maxFeePerGas ? BigInt(tx.maxFeePerGas) : undefined, + }; +}; + export default { buildEthereumMsgRequest, validateEthereumMsgResponse, diff --git a/src/types/sign.ts b/src/types/sign.ts index 5500f059..f09dcbd6 100644 --- a/src/types/sign.ts +++ b/src/types/sign.ts @@ -11,15 +11,15 @@ export const TRANSACTION_TYPE = { }; export type TransactionRequest = { - to?: `0x${string}`; - value?: bigint; - data?: `0x${string}`; - chainId?: number; - nonce?: number; - gas?: bigint; - maxFeePerGas?: bigint; - maxPriorityFeePerGas?: bigint; - from?: `0x${string}`; + to: string; + value: string; + data: string; + chainId: number; + nonce: number; + gasLimit: string; + maxFeePerGas?: string; + maxPriorityFeePerGas?: string; + from?: string; accessList?: Array<{ address: string; storageKeys: string[] }>; type?: (typeof TRANSACTION_TYPE)[keyof typeof TRANSACTION_TYPE]; };