From 91e2fb8949a9bb551965570cce55129e75d71fe4 Mon Sep 17 00:00:00 2001 From: Nikola Divic Date: Thu, 23 Jan 2025 16:02:42 +0100 Subject: [PATCH] fix(EPv0.7.0): :bug: Fix bug with non-stale messages discarded & enable Sepolia v0.7.0 --- config/default.json | 7 +- .../relay-service/BundlerRelayService.ts | 4 + .../api/v3/eth_sendUserOperation/handler.ts | 34 ----- src/test/e2e/nativeTransfer.test.ts | 136 ++++++++++++++++++ 4 files changed, 144 insertions(+), 37 deletions(-) diff --git a/config/default.json b/config/default.json index 8856d8be..7da58192 100644 --- a/config/default.json +++ b/config/default.json @@ -14,10 +14,11 @@ 11155111, 84532, 168587773, 81457, 534351, 534352, 56400, 7000, 11155420, 80002, 27827, 4653, 8101902, 666666666, 2442, 7001, 5003, 100, 10200, 195, 196, 2810, 997, 3799, 167009, 80084, 5845, 167000, 1328, 1329, 995, 28882, - 288, 920637907288165, 1740, 1750, 4202, 1135, 2818 + 288, 920637907288165, 1740, 1750, 4202, 1135, 2818, 11155111 ], "supportedNetworksV07": [ - 1, 11155420, 84532, 8453, 10, 56, 42161, 137, 100, 80084, 168587773, 81457 + 1, 11155420, 84532, 8453, 10, 56, 42161, 137, 100, 80084, 168587773, 81457, + 11155111 ], "EIP1559SupportedNetworks": [ 1, 137, 42161, 10, 43114, 43113, 8453, 59144, 204, 5611, 421614, 11155111, @@ -1027,7 +1028,7 @@ "0x0000000071727De22E5E9d8BAf0edAc6f37da032": { "supportedChainIds": [ 1, 11155420, 84532, 8453, 10, 56, 42161, 137, 100, 80084, 168587773, - 81457 + 81457, 11155111 ] } }, diff --git a/src/common/relay-service/BundlerRelayService.ts b/src/common/relay-service/BundlerRelayService.ts index 603b5a4e..52d0c19a 100644 --- a/src/common/relay-service/BundlerRelayService.ts +++ b/src/common/relay-service/BundlerRelayService.ts @@ -22,6 +22,10 @@ export class BundlerRelayService implements IRelayService { async sendUserOperation( data: SendUserOperation, ): Promise { + if (!data.timestamp) { + data.timestamp = Date.now(); + } + const _log = log.child({ sendUserOperation: data, }); diff --git a/src/server/api/v3/eth_sendUserOperation/handler.ts b/src/server/api/v3/eth_sendUserOperation/handler.ts index 2b733d2b..ba6c9f1f 100644 --- a/src/server/api/v3/eth_sendUserOperation/handler.ts +++ b/src/server/api/v3/eth_sendUserOperation/handler.ts @@ -18,19 +18,12 @@ import { UserOperationStateEnum, } from "../../../../common/types"; import { BUNDLER_ERROR_CODES, STATUSES } from "../../shared/middleware"; -// import { updateRequest } from '../../auth/UpdateRequest'; const log = logger.child({ module: module.filename.split("/").slice(-4).join("/"), }); export const bundleUserOperation = async (req: Request, res: Response) => { - // const bundlerRequestId = req.body.params[6]; - - log.info( - `💰💰💰 EP v7 bundleUserOperation called, entryPointAddress: ${req.body.params[1]}`, - ); - try { const start = performance.now(); const { id } = req.body; @@ -141,21 +134,6 @@ export const bundleUserOperation = async (req: Request, res: Response) => { }); if (isError(response)) { - // updateRequest({ - // chainId: parseInt(chainId, 10), - // apiKey, - // bundlerRequestId, - // transactionId, - // rawResponse: { - // jsonrpc: '2.0', - // id: id || 1, - // error: { - // code: BUNDLER_ERROR_CODES.BAD_REQUEST, - // message: response.error, - // }, - // }, - // httpResponseCode: STATUSES.BAD_REQUEST, - // }); const end = performance.now(); log.info(`bundleUserOperation took: ${end - start} milliseconds`); return res.status(STATUSES.BAD_REQUEST).json({ @@ -168,18 +146,6 @@ export const bundleUserOperation = async (req: Request, res: Response) => { }); } - // updateRequest({ - // chainId: parseInt(chainId, 10), - // apiKey, - // bundlerRequestId, - // transactionId, - // rawResponse: { - // jsonrpc: '2.0', - // id: id || 1, - // result: userOpHash, - // }, - // httpResponseCode: STATUSES.SUCCESS, - // }); const end = performance.now(); log.info(`bundleUserOperation took: ${end - start} milliseconds`); return res.status(STATUSES.SUCCESS).json({ diff --git a/src/test/e2e/nativeTransfer.test.ts b/src/test/e2e/nativeTransfer.test.ts index 8c686bcf..83c41c33 100644 --- a/src/test/e2e/nativeTransfer.test.ts +++ b/src/test/e2e/nativeTransfer.test.ts @@ -16,6 +16,7 @@ import { blast, baseSepolia, berachainTestnetbArtio, + sepolia, } from "viem/chains"; import { BiconomySmartAccountV2, @@ -1198,6 +1199,141 @@ describe("e2e", () => { }); }); }); + + describe("ethereum-sepolia", () => { + const account = privateKeyToAccount(`0x${privateKey}`); + + describe.skip("EntryPoint v0.6.0", () => { + const bundlerUrl = `${bundlerHostname}/api/v2/${sepolia.id}/biconomy`; + + const paymasterUrl = process.env.SEPOLIA_MAINNET_PAYMASTER_URL; + + const signer = createWalletClient({ + account, + chain: sepolia, + transport: http(), + }).extend(publicActions); + + let smartAccount: BiconomySmartAccountV2; + + const tx = { + to: account.address, + value: 1n, + }; + + beforeAll(async () => { + smartAccount = await createSmartAccountClient({ + signer: signer, + bundlerUrl, + paymasterUrl, + }); + await requireBalance(smartAccount, valueToSend); + }); + + it("should perform a native transfer without a paymaster", async () => { + const userOpResponse = await smartAccount.sendTransaction(tx); + + const receipt = await userOpResponse.wait(); + + console.log(receipt); + + expect(receipt.success).toBe("true"); + }, 60_000); + + if (paymasterUrl) { + it("should perform a native transfer using a paymaster", async () => { + if (!paymasterUrl) { + throw new Error("SEPOLIA_MAINNET_PAYMASTER_URL is not defined"); + } + + const unestimatedUserOperation: Partial = + await smartAccount.signUserOp({ + sender: await smartAccount.getAccountAddress(), + nonce: await smartAccount.getNonce(), + initCode: "0x", + callData: await smartAccount.encodeExecute(tx.to, tx.value, "0x"), + callGasLimit: 1n, + verificationGasLimit: 1n, + preVerificationGas: 1n, + maxFeePerGas: 1n, + maxPriorityFeePerGas: 1n, + paymasterAndData: stubPaymasterAndData, + }); + + const gasEstimate = await smartAccount.bundler?.estimateUserOpGas( + unestimatedUserOperation, + ); + + const { + callGasLimit, + verificationGasLimit, + preVerificationGas, + maxFeePerGas, + maxPriorityFeePerGas, + } = gasEstimate!; + + let estimatedUserOperation = await smartAccount.signUserOp({ + ...unestimatedUserOperation, + callGasLimit: BigInt(callGasLimit), + verificationGasLimit: BigInt(verificationGasLimit), + preVerificationGas: BigInt(preVerificationGas), + maxFeePerGas: BigInt(maxFeePerGas), + maxPriorityFeePerGas: BigInt(maxPriorityFeePerGas), + }); + + estimatedUserOperation.paymasterAndData = await sponsorUserOperation( + paymasterUrl, + estimatedUserOperation, + ); + + estimatedUserOperation = await smartAccount.signUserOp( + estimatedUserOperation, + ); + + const response = await smartAccount.bundler!.sendUserOp( + estimatedUserOperation, + ); + + const receipt = await response.wait(); + + console.log(receipt); + + expect(receipt.success).toBe("true"); + }); + } + }); + + describe("EntryPoint v0.7.0", () => { + const bundlerUrl = `${bundlerHostname}/api/v3/${sepolia.id}/biconomy`; + + it("should perform a native transfer without a paymaster", async () => { + const nexusClient = await createNexusClient({ + signer: account, + chain: sepolia, + transport: http(), + bundlerTransport: http(bundlerUrl), + }); + + const smartAccountAddress = nexusClient.account.address; + console.log(`Nexus address: ${smartAccountAddress}`); + + const hash = await nexusClient.sendTransaction({ + calls: [ + { + to: smartAccountAddress, + value: 1n, + }, + ], + }); + + const receipt = await nexusClient.waitForTransactionReceipt({ hash }); + + console.log(receipt); + + expect(receipt.status).toBe("success"); + }); + }); + }); }); function logConfig(