diff --git a/package-lock.json b/package-lock.json index 67d038a0d..2af98786e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27860,8 +27860,6 @@ "version": "8.12.4", "license": "ISC", "dependencies": { - "@ethereumjs/common": "^4.3.0", - "@ethereumjs/tx": "^5.3.0", "@ethereumjs/util": "^9.0.3", "@toruslabs/base-controllers": "^6.0.3", "@web3auth/auth": "^9.3.1", @@ -27974,8 +27972,6 @@ "version": "8.12.4", "license": "ISC", "dependencies": { - "@ethereumjs/common": "^4.3.0", - "@ethereumjs/tx": "^5.3.0", "@ethereumjs/util": "^9.0.3", "@toruslabs/base-controllers": "^6.0.3", "@toruslabs/http-helpers": "^7.0.0", diff --git a/packages/providers/ethereum-mpc-provider/package.json b/packages/providers/ethereum-mpc-provider/package.json index 674e4364d..4ece47157 100644 --- a/packages/providers/ethereum-mpc-provider/package.json +++ b/packages/providers/ethereum-mpc-provider/package.json @@ -20,8 +20,6 @@ "pre-commit": "lint-staged --cwd ." }, "dependencies": { - "@ethereumjs/common": "^4.3.0", - "@ethereumjs/tx": "^5.3.0", "@ethereumjs/util": "^9.0.3", "@toruslabs/base-controllers": "^6.0.3", "@web3auth/auth": "^9.3.1", diff --git a/packages/providers/ethereum-mpc-provider/src/providers/signingProviders/signingUtils.ts b/packages/providers/ethereum-mpc-provider/src/providers/signingProviders/signingUtils.ts index 87befd185..aef0067b4 100644 --- a/packages/providers/ethereum-mpc-provider/src/providers/signingProviders/signingUtils.ts +++ b/packages/providers/ethereum-mpc-provider/src/providers/signingProviders/signingUtils.ts @@ -1,4 +1,4 @@ -import { intToBytes, isHexString, publicToAddress, stripHexPrefix, toBytes } from "@ethereumjs/util"; +import { intToBytes, isHexString, PrefixedHexString, publicToAddress, stripHexPrefix, toBytes } from "@ethereumjs/util"; import { concatSig } from "@toruslabs/base-controllers"; import { JRPCRequest, providerErrors, SafeEventEmitterProvider } from "@web3auth/auth"; import { log } from "@web3auth/base"; @@ -18,36 +18,15 @@ async function signTx( txParams: TransactionParams & { gas?: string }, sign: (msgHash: Buffer, rawMsg?: Buffer) => Promise<{ v: number; r: Buffer; s: Buffer }>, txFormatter: TransactionFormatter -): Promise { - const [{ Hardfork }, { Capability, TransactionFactory, TransactionType }] = await Promise.all([ - import("@ethereumjs/common"), - import("@ethereumjs/tx"), - ]); +): Promise { + const { Transaction } = await import("ethers"); const finalTxParams = await txFormatter.formatTransaction(txParams); - const common = await txFormatter.getCommonConfiguration(); - const unsignedEthTx = TransactionFactory.fromTxData(finalTxParams, { - common, + const ethTx = Transaction.from({ + ...finalTxParams, + from: undefined, // from is already calculated inside Transaction.from and is not allowed to be passed in }); - // Hack for the constellation that we have got a legacy tx after spuriousDragon with a non-EIP155 conforming signature - // and want to recreate a signature (where EIP155 should be applied) - // Leaving this hack lets the legacy.spec.ts -> sign(), verifySignature() test fail - // 2021-06-23 - let hackApplied = false; - if ( - unsignedEthTx.type === TransactionType.Legacy && - unsignedEthTx.common.gteHardfork(Hardfork.SpuriousDragon) && - !unsignedEthTx.supports(Capability.EIP155ReplayProtection) - ) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (unsignedEthTx as any).activeCapabilities.push(Capability.EIP155ReplayProtection); - hackApplied = true; - } - - const msgHash = unsignedEthTx.getHashedMessageToSign(); - const rawMessage = unsignedEthTx.getMessageToSign(); - - const vrs = await sign(Buffer.from(msgHash), Buffer.from(rawMessage as Uint8Array)); + const vrs = await sign(Buffer.from(ethTx.unsignedHash)); let { v } = vrs; const { r, s } = vrs; @@ -57,20 +36,12 @@ async function signTx( } // addSignature will handle the v value - const tx = unsignedEthTx.addSignature(BigInt(v), r, s); - - // Hack part 2 - if (hackApplied) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const index = (unsignedEthTx as any).activeCapabilities.indexOf(Capability.EIP155ReplayProtection); - if (index > -1) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (unsignedEthTx as any).activeCapabilities.splice(index, 1); - } - } + const tx = ethTx; + tx.signature.v = BigInt(v); + tx.signature.r = r; + tx.signature.s = s; - // should we return uint8array or buffer? - return Buffer.from(tx.serialize()); + return tx.serialized as PrefixedHexString; } async function signMessage(sign: (msgHash: Buffer, rawMsg?: Buffer) => Promise<{ v: number; r: Buffer; s: Buffer }>, data: string) { @@ -164,7 +135,7 @@ export function getProviderHandlers({ const serializedTxn = await signTx(txParams, sign, txFormatter); const txHash = await providerEngineProxy.request({ method: "eth_sendRawTransaction", - params: ["0x".concat(serializedTxn.toString("hex"))], + params: [serializedTxn], }); return txHash; }, @@ -176,7 +147,7 @@ export function getProviderHandlers({ code: 4902, }); const serializedTxn = await signTx(txParams, sign, txFormatter); - return Buffer.from(serializedTxn).toString("hex"); + return serializedTxn; }, processEthSignMessage: async (msgParams: MessageParams, _: JRPCRequest): Promise => { const rawMessageSig = signMessage(sign, msgParams.data); diff --git a/packages/providers/ethereum-provider/package.json b/packages/providers/ethereum-provider/package.json index c2062db56..bd0d4e056 100644 --- a/packages/providers/ethereum-provider/package.json +++ b/packages/providers/ethereum-provider/package.json @@ -20,8 +20,6 @@ "pre-commit": "lint-staged --cwd ." }, "dependencies": { - "@ethereumjs/common": "^4.3.0", - "@ethereumjs/tx": "^5.3.0", "@ethereumjs/util": "^9.0.3", "@toruslabs/base-controllers": "^6.0.3", "@toruslabs/http-helpers": "^7.0.0", diff --git a/packages/providers/ethereum-provider/src/providers/privateKeyProviders/TransactionFormatter/formatter.ts b/packages/providers/ethereum-provider/src/providers/privateKeyProviders/TransactionFormatter/formatter.ts index 5c8ac15cd..60a466ca6 100644 --- a/packages/providers/ethereum-provider/src/providers/privateKeyProviders/TransactionFormatter/formatter.ts +++ b/packages/providers/ethereum-provider/src/providers/privateKeyProviders/TransactionFormatter/formatter.ts @@ -1,8 +1,8 @@ -import { type Common } from "@ethereumjs/common"; -import { addHexPrefix, AddressLike, PrefixedHexString, stripHexPrefix } from "@ethereumjs/util"; +import { addHexPrefix, PrefixedHexString, stripHexPrefix } from "@ethereumjs/util"; import { Block } from "@web3auth/auth"; import { CustomChainConfig, log, SafeEventEmitterProvider } from "@web3auth/base"; import BigNumber from "bignumber.js"; +import { AddressLike } from "ethers"; import { TransactionParams } from "../../../rpc/interfaces"; import { decGWEIToHexWEI, hexWEIToDecGWEI } from "../../converter"; @@ -34,20 +34,6 @@ export class TransactionFormatter { this.isEIP1559Compatible = await this.getEIP1559Compatibility(); } - async getCommonConfiguration(): Promise { - if (!this.chainConfig) throw new Error("Chain config not initialized"); - const { displayName: name, chainId } = this.chainConfig; - const { Hardfork, Common } = await import("@ethereumjs/common"); - const hardfork = this.isEIP1559Compatible ? Hardfork.Paris : Hardfork.Berlin; - const customChainParams = { - name, - chainId: chainId === "loading" ? 0 : Number.parseInt(chainId, 16), - networkId: chainId === "loading" ? 0 : Number.parseInt(chainId, 16), - defaultHardfork: hardfork, - }; - return Common.custom(customChainParams); - } - async formatTransaction(txParams: TransactionParams & { gas?: string }): Promise { if (!this.chainConfig) throw new Error("Chain config not initialized"); @@ -104,10 +90,10 @@ export class TransactionFormatter { clonedTxParams.maxPriorityFeePerGas = bnLessThan( typeof defaultMaxPriorityFeePerGas === "string" ? stripHexPrefix(defaultMaxPriorityFeePerGas) : defaultMaxPriorityFeePerGas, - typeof clonedTxParams.gasPrice === "string" ? stripHexPrefix(clonedTxParams.gasPrice) : clonedTxParams.gasPrice + typeof clonedTxParams.gasPrice === "string" ? stripHexPrefix(clonedTxParams.gasPrice) : clonedTxParams.gasPrice.toString() ) ? addHexPrefix(defaultMaxPriorityFeePerGas) - : addHexPrefix(clonedTxParams.gasPrice); + : addHexPrefix(clonedTxParams.gasPrice.toString()); } else { if (defaultMaxFeePerGas && !clonedTxParams.maxFeePerGas) { // If the dapp has not set the gasPrice or the maxFeePerGas, then we set maxFeePerGas @@ -156,7 +142,7 @@ export class TransactionFormatter { clonedTxParams.gasPrice = defaultGasPrice as never; } - clonedTxParams.type = this.isEIP1559Compatible ? TRANSACTION_ENVELOPE_TYPES.FEE_MARKET : TRANSACTION_ENVELOPE_TYPES.LEGACY; + clonedTxParams.type = Number.parseInt(this.isEIP1559Compatible ? TRANSACTION_ENVELOPE_TYPES.FEE_MARKET : TRANSACTION_ENVELOPE_TYPES.LEGACY, 16); clonedTxParams.chainId = this.chainConfig.chainId as PrefixedHexString; return clonedTxParams; } diff --git a/packages/providers/ethereum-provider/src/providers/privateKeyProviders/ethPrivatekeyUtils.ts b/packages/providers/ethereum-provider/src/providers/privateKeyProviders/ethPrivatekeyUtils.ts index 0626a8bb2..d2c8dadd6 100644 --- a/packages/providers/ethereum-provider/src/providers/privateKeyProviders/ethPrivatekeyUtils.ts +++ b/packages/providers/ethereum-provider/src/providers/privateKeyProviders/ethPrivatekeyUtils.ts @@ -1,4 +1,4 @@ -import { addHexPrefix, isHexString, privateToAddress, stripHexPrefix } from "@ethereumjs/util"; +import { addHexPrefix, isHexString, PrefixedHexString, privateToAddress, stripHexPrefix } from "@ethereumjs/util"; import { signMessage } from "@toruslabs/base-controllers"; import { JRPCRequest, providerErrors } from "@web3auth/auth"; import { log, SafeEventEmitterProvider } from "@web3auth/base"; @@ -8,15 +8,20 @@ import { IProviderHandlers, MessageParams, SignTypedDataMessageV4, TransactionPa import { TransactionFormatter } from "./TransactionFormatter/formatter"; import { validateTypedSignMessageDataV4 } from "./TransactionFormatter/utils"; -async function signTx(txParams: TransactionParams & { gas?: string }, privKey: string, txFormatter: TransactionFormatter): Promise { +async function signTx( + txParams: TransactionParams & { gas?: string }, + privKey: string, + txFormatter: TransactionFormatter +): Promise { const finalTxParams = await txFormatter.formatTransaction(txParams); - const common = await txFormatter.getCommonConfiguration(); - const { TransactionFactory } = await import("@ethereumjs/tx"); - const unsignedEthTx = TransactionFactory.fromTxData(finalTxParams, { - common, + const { Transaction } = await import("ethers"); + const ethTx = Transaction.from({ + ...finalTxParams, + from: undefined, // from is already calculated inside Transaction.from and is not allowed to be passed in }); - const signedTx = unsignedEthTx.sign(Buffer.from(privKey, "hex")).serialize(); - return Buffer.from(signedTx); + const signKey = new SigningKey(addHexPrefix(privKey)); + ethTx.signature = signKey.sign(ethTx.unsignedHash); + return ethTx.serialized as PrefixedHexString; } export function getProviderHandlers({ @@ -49,10 +54,10 @@ export function getProviderHandlers({ code: 4902, }); if (txParams.input && !txParams.data) txParams.data = addHexPrefix(txParams.input); - const signedTx = await signTx(txParams, privKey, txFormatter); + const serializedTx = await signTx(txParams, privKey, txFormatter); const txHash = await providerEngineProxy.request<[string], string>({ method: "eth_sendRawTransaction", - params: ["0x".concat(signedTx.toString("hex"))], + params: [serializedTx], }); return txHash; }, @@ -64,8 +69,8 @@ export function getProviderHandlers({ code: 4902, }); if (txParams.input && !txParams.data) txParams.data = addHexPrefix(txParams.input); - const signedTx = await signTx(txParams, privKey, txFormatter); - return `0x${signedTx.toString("hex")}`; + const serializedTx = await signTx(txParams, privKey, txFormatter); + return serializedTx; }, processEthSignMessage: async (msgParams: MessageParams, _: JRPCRequest): Promise => { const rawMessageSig = signMessage(privKey, msgParams.data); diff --git a/packages/providers/ethereum-provider/src/rpc/interfaces.ts b/packages/providers/ethereum-provider/src/rpc/interfaces.ts index 1af284a9e..ccedbda09 100644 --- a/packages/providers/ethereum-provider/src/rpc/interfaces.ts +++ b/packages/providers/ethereum-provider/src/rpc/interfaces.ts @@ -1,6 +1,5 @@ -import type { AccessListEIP2930TxData, FeeMarketEIP1559TxData, TxData } from "@ethereumjs/tx"; import type { JRPCRequest } from "@web3auth/auth"; -import type { TypedDataDomain, TypedDataField } from "ethers"; +import type { TransactionLike, TypedDataDomain, TypedDataField } from "ethers"; export interface IAccountHandlers { updatePrivatekey: (params: { privateKey: string }) => Promise; } @@ -23,19 +22,7 @@ export interface IChainSwitchHandlers { switchChain: (params: { chainId: string }) => Promise; } -export interface ExtendedAccessListEIP2930TxData extends AccessListEIP2930TxData { - from: string; -} - -export interface ExtendedFeeMarketEIP1559Transaction extends FeeMarketEIP1559TxData { - from: string; -} - -export interface ExtendedTxData extends TxData { - from: string; -} - -export type TransactionParams = ExtendedFeeMarketEIP1559Transaction & ExtendedAccessListEIP2930TxData & ExtendedTxData & { input?: string }; +export type TransactionParams = TransactionLike & { input?: string }; export interface MessageParams { from: string;