Skip to content

Commit

Permalink
feat(connect): improve serializeEthereumTx
Browse files Browse the repository at this point in the history
  • Loading branch information
martykan committed Dec 11, 2024
1 parent 1edbbc0 commit 12fad78
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 28 deletions.
13 changes: 1 addition & 12 deletions packages/connect/src/api/ethereum/api/ethereumSignTransaction.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// origin: https://github.com/trezor/connect/blob/develop/src/js/core/methods/EthereumSignTransaction.js

import { FeeMarketEIP1559TxData, LegacyTxData } from '@ethereumjs/tx';

import { MessagesSchema } from '@trezor/protobuf';
import { Assert } from '@trezor/schema-utils';

Expand Down Expand Up @@ -155,16 +153,7 @@ export default class EthereumSignTransaction extends AbstractMethod<
definitions,
);

const txData = {
...tx,
...signature,
type: isLegacy ? 0 : 2, // 0 for legacy, 2 for EIP-1559
gasPrice: isLegacy ? tx.gasPrice : undefined,
maxFeePerGas: !isLegacy ? tx.maxFeePerGas : undefined,
maxPriorityFeePerGas: !isLegacy ? tx.maxPriorityFeePerGas : undefined,
} as LegacyTxData | FeeMarketEIP1559TxData;

const serializedTx = helper.serializeEthereumTx(txData, tx.chainId);
const serializedTx = helper.serializeEthereumTx(tx, signature, isLegacy);

return { ...signature, serializedTx };
}
Expand Down
62 changes: 46 additions & 16 deletions packages/connect/src/api/ethereum/ethereumSignTx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import { MessagesSchema } from '@trezor/protobuf';

import { PROTO, ERRORS } from '../../constants';
import type { TypedCall } from '../../device/DeviceCommands';
import type { EthereumAccessList } from '../../types/api/ethereum';
import type {
EthereumAccessList,
EthereumTransaction,
EthereumTransactionEIP1559,
} from '../../types/api/ethereum';
import { addHexPrefix, deepTransform } from '../../utils/formatUtils';

const splitString = (str?: string, len?: number) => {
Expand All @@ -26,9 +30,9 @@ const processTxRequest = async (
data?: string,
chain_id?: number,
): Promise<{
v: string;
r: string;
s: string;
v: `0x${string}`;
r: `0x${string}`;
s: `0x${string}`;
}> => {
if (!request.data_length) {
let v = request.signature_v;
Expand Down Expand Up @@ -59,24 +63,50 @@ const processTxRequest = async (

const deepHexPrefix = deepTransform(addHexPrefix);

export const serializeEthereumTx = (
txData: LegacyTxData | FeeMarketEIP1559TxData,
chainId: number,
) => {
export const getCommonForChain = (chainId: number) => {
// @ethereumjs/tx directly supported chains
if (Common.isSupportedChainId(BigInt(chainId))) return new Common({ chain: chainId });

// @ethereumjs/tx doesn't support ETC (chain 61) by default
// and it needs to be declared as custom chain
// see: https://github.com/ethereumjs/ethereumjs-tx/blob/master/examples/custom-chain-tx.ts
const txOptions =
chainId === 61
if (chainId === 61)
return Common.custom(
{ name: 'ethereum-classic', networkId: 1, chainId: 61 },
{ baseChain: Chain.Mainnet, hardfork: Hardfork.Petersburg },
);

// other chains
return Common.custom({ chainId });
};

export const serializeEthereumTx = (
tx: EthereumTransactionEIP1559 | EthereumTransaction,
signature: { v: `0x${string}`; r: `0x${string}`; s: `0x${string}` },
isLegacy: boolean,
) => {
const txData = deepHexPrefix({
...tx,
...signature,
type: isLegacy ? 0 : 2, // 0 for legacy, 2 for EIP-1559
...(isLegacy
? {
common: Common.custom(
{ name: 'ethereum-classic', networkId: 1, chainId: 61 },
{ baseChain: Chain.Mainnet, hardfork: Hardfork.Petersburg },
),
gasPrice: tx.gasPrice,
maxFeePerGas: undefined,
maxPriorityFeePerGas: undefined,
}
: { chain: chainId };
: {
gasPrice: undefined,
maxFeePerGas: tx.maxFeePerGas,
maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
}),
}) satisfies LegacyTxData | FeeMarketEIP1559TxData;

const txOptions = {
common: getCommonForChain(tx.chainId),
};

const ethTx = TransactionFactory.fromTxData(deepHexPrefix(txData), txOptions);
const ethTx = TransactionFactory.fromTxData(txData, txOptions);

return `0x${Buffer.from(ethTx.serialize()).toString('hex')}`;
};
Expand Down

0 comments on commit 12fad78

Please sign in to comment.