From 38bbb4be90b7ee068953a60aa99cd4f053725bf1 Mon Sep 17 00:00:00 2001 From: marie-fourier Date: Wed, 30 Oct 2024 17:14:52 +0500 Subject: [PATCH 1/4] feat: eip-7702 in eth_estimateUserOperationGas --- .../api/src/dto/EstimateUserOperation.dto.ts | 7 ++++++ packages/api/src/dto/SendUserOperation.dto.ts | 11 ++++++++ .../src/services/EntryPointService/service.ts | 13 +++++++++- .../EntryPointService/versions/0.0.7.ts | 25 ++++++++++++++++++- .../EntryPointService/versions/base.ts | 6 +++++ .../UserOpValidation/validators/safe.ts | 9 +++++++ packages/types/src/contracts/UserOperation.ts | 4 +++ 7 files changed, 73 insertions(+), 2 deletions(-) diff --git a/packages/api/src/dto/EstimateUserOperation.dto.ts b/packages/api/src/dto/EstimateUserOperation.dto.ts index 9e6ab523..37fadc38 100644 --- a/packages/api/src/dto/EstimateUserOperation.dto.ts +++ b/packages/api/src/dto/EstimateUserOperation.dto.ts @@ -75,6 +75,13 @@ export class EstimateUserOperation { @IsString() @IsOptional() paymasterData?: BytesLike; + + /** + * EIP-7702 fields + */ + @IsEthereumAddress() + @IsOptional() + authorizationContract?: string; } export class EstimateUserOperationGasArgs { diff --git a/packages/api/src/dto/SendUserOperation.dto.ts b/packages/api/src/dto/SendUserOperation.dto.ts index bd9e2313..981dda97 100644 --- a/packages/api/src/dto/SendUserOperation.dto.ts +++ b/packages/api/src/dto/SendUserOperation.dto.ts @@ -59,6 +59,17 @@ export class SendUserOperation { @IsString() @IsOptional() paymasterData?: BytesLike; + + /** + * EIP-7702 fields + */ + @IsEthereumAddress() + @IsOptional() + authorizationContract?: string; + + @IsOptional() + @IsString() + authorizationSignature?: string; } export class SendUserOperationGasArgs { diff --git a/packages/executor/src/services/EntryPointService/service.ts b/packages/executor/src/services/EntryPointService/service.ts index 5a5c2186..85eb2fef 100644 --- a/packages/executor/src/services/EntryPointService/service.ts +++ b/packages/executor/src/services/EntryPointService/service.ts @@ -10,7 +10,7 @@ import RpcError from "@skandha/types/lib/api/errors/rpc-error"; import * as RpcErrorCodes from "@skandha/types/lib/api/errors/rpc-error-codes"; import { NetworkConfig, UserOpValidationResult } from "../../interfaces"; import { EntryPointV7Service, IEntryPointService } from "./versions"; -import { EntryPointVersion } from "./interfaces"; +import { EntryPointVersion, StateOverrides } from "./interfaces"; export class EntryPointService { private entryPoints: { @@ -194,4 +194,15 @@ export class EntryPointService { getPaymaster(entryPoint: string, userOp: UserOperation): string | undefined { return userOp.paymaster?.toLowerCase(); } + + set7702StateOverrides( + entryPoint: string, + stateOverrides: StateOverrides, + userOp: UserOperation + ): Promise { + return this.entryPoints[entryPoint.toLowerCase()].set7702StateOverrides( + stateOverrides, + userOp + ); + } } diff --git a/packages/executor/src/services/EntryPointService/versions/0.0.7.ts b/packages/executor/src/services/EntryPointService/versions/0.0.7.ts index 628296b1..080fc5ae 100644 --- a/packages/executor/src/services/EntryPointService/versions/0.0.7.ts +++ b/packages/executor/src/services/EntryPointService/versions/0.0.7.ts @@ -115,6 +115,10 @@ export class EntryPointV7Service implements IEntryPointService { }, }; + if (userOp.authorizationContract) { + await this.set7702StateOverrides(stateOverrides, userOp); + } + try { const simulationResult = await this.provider.send("eth_call", [ tx, @@ -139,6 +143,9 @@ export class EntryPointV7Service implements IEntryPointService { async simulateValidation(userOp: UserOperation): Promise { const [data, stateOverrides] = this.encodeSimulateValidation(userOp); + if (userOp.authorizationContract) { + await this.set7702StateOverrides(stateOverrides, userOp); + } const tx: providers.TransactionRequest = { to: this.address, data, @@ -299,6 +306,21 @@ export class EntryPointV7Service implements IEntryPointService { /**************/ /** Utilities */ + async set7702StateOverrides( + stateOverrides: StateOverrides, + userOp: UserOperation + ): Promise { + if (!userOp.authorizationContract) return; + const code = await this.provider.getCode(userOp.authorizationContract); + if (code.length <= 2) { + throw new RpcError( + "Invalid authorization contract", + RpcErrorCodes.INVALID_USEROP + ); + } + stateOverrides[userOp.sender] = { code }; + } + calcPreverificationGas( userOp: Partial, forSignature = true @@ -321,7 +343,8 @@ export class EntryPointV7Service implements IEntryPointService { ov.perUserOp + ov.perUserOpWord * lengthInWord ); - return Math.max(ret + this.networkConfig.pvgMarkup, 0); + const eip7702 = userOp.authorizationContract ? 37500 : 0; + return Math.max(ret + this.networkConfig.pvgMarkup + eip7702, 0); } parseValidationResult( diff --git a/packages/executor/src/services/EntryPointService/versions/base.ts b/packages/executor/src/services/EntryPointService/versions/base.ts index e5d372b6..30d86432 100644 --- a/packages/executor/src/services/EntryPointService/versions/base.ts +++ b/packages/executor/src/services/EntryPointService/versions/base.ts @@ -8,6 +8,7 @@ import { UserOperationReceipt, } from "@skandha/types/lib/api/interfaces"; import { UserOpValidationResult } from "../../../interfaces"; +import { StateOverrides } from "../interfaces"; export interface IEntryPointService { readonly contract: IEntryPointV6 | IEntryPointV7; @@ -46,4 +47,9 @@ export interface IEntryPointService { userOp: UserOperation, data: string ): UserOpValidationResult; + + set7702StateOverrides( + stateOverrides: StateOverrides, + userOp: UserOperation + ): Promise; } diff --git a/packages/executor/src/services/UserOpValidation/validators/safe.ts b/packages/executor/src/services/UserOpValidation/validators/safe.ts index a1157434..99029c42 100644 --- a/packages/executor/src/services/UserOpValidation/validators/safe.ts +++ b/packages/executor/src/services/UserOpValidation/validators/safe.ts @@ -91,6 +91,15 @@ export class SafeValidationService { const [data, stateOverrides] = this.entryPointService.encodeSimulateValidation(entryPoint, userOp); + + if (userOp.authorizationContract) { + await this.entryPointService.set7702StateOverrides( + entryPoint, + stateOverrides, + userOp + ); + } + const tx: providers.TransactionRequest = { to: entryPoint, data, diff --git a/packages/types/src/contracts/UserOperation.ts b/packages/types/src/contracts/UserOperation.ts index 10626691..a3fb7d48 100644 --- a/packages/types/src/contracts/UserOperation.ts +++ b/packages/types/src/contracts/UserOperation.ts @@ -21,6 +21,10 @@ export interface UserOperation { paymasterPostOpGasLimit?: BigNumberish; paymasterData?: BytesLike; signature: BytesLike; + + // eip-7702 fields + authorizationContract?: string; + authorizationSignature?: string; } export type PackedUserOperation = NotPromise; From 92b783abaae0bcde7eb66281ffa3f91d35f90183 Mon Sep 17 00:00:00 2001 From: marie-fourier Date: Thu, 31 Oct 2024 18:50:27 +0500 Subject: [PATCH 2/4] wip: eip7702 --- packages/executor/package.json | 3 +- .../executor/src/entities/MempoolEntry.ts | 5 ++ packages/executor/src/entities/interfaces.ts | 3 + packages/executor/src/modules/eth.ts | 15 ++++ .../BundlingService/relayers/classic.ts | 24 ++++- .../services/BundlingService/utils/eip7702.ts | 87 +++++++++++++++++++ packages/types/src/contracts/UserOperation.ts | 3 +- tsconfig.build.json | 1 + 8 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 packages/executor/src/services/BundlingService/utils/eip7702.ts diff --git a/packages/executor/package.json b/packages/executor/package.json index b66e3630..460b3a4d 100644 --- a/packages/executor/package.json +++ b/packages/executor/package.json @@ -42,7 +42,8 @@ "async-mutex": "0.4.0", "ethers": "5.7.2", "strict-event-emitter-types": "2.0.0", - "ws": "8.16.0" + "ws": "8.16.0", + "viem": "2.21.37" }, "devDependencies": { "@types/ws": "8.2.2" diff --git a/packages/executor/src/entities/MempoolEntry.ts b/packages/executor/src/entities/MempoolEntry.ts index db2faa6d..b681f12d 100644 --- a/packages/executor/src/entities/MempoolEntry.ts +++ b/packages/executor/src/entities/MempoolEntry.ts @@ -218,6 +218,11 @@ export class MempoolEntry implements IMempoolEntry { this.userOp.paymasterVerificationGasLimit, paymasterPostOpGasLimit: this.userOp.paymasterPostOpGasLimit, paymasterData: this.userOp.paymasterData, + authorizationContract: this.userOp.authorizationContract, + authorizationSignature: hexValue( + this.userOp.authorizationSignature || "" + ), + authorizationNonce: this.userOp.authorizationNonce, }, prefund: hexValue(this.prefund), aggregator: this.aggregator, diff --git a/packages/executor/src/entities/interfaces.ts b/packages/executor/src/entities/interfaces.ts index e85b7b6f..7600de36 100644 --- a/packages/executor/src/entities/interfaces.ts +++ b/packages/executor/src/entities/interfaces.ts @@ -42,6 +42,9 @@ export interface MempoolEntrySerialized { paymasterVerificationGasLimit?: BigNumberish; paymasterPostOpGasLimit?: BigNumberish; paymasterData?: BytesLike; + authorizationContract?: string; + authorizationSignature: BytesLike; + authorizationNonce?: number; }; prefund: string; aggregator: string | undefined; diff --git a/packages/executor/src/modules/eth.ts b/packages/executor/src/modules/eth.ts index 5b381632..b7f61edd 100644 --- a/packages/executor/src/modules/eth.ts +++ b/packages/executor/src/modules/eth.ts @@ -30,6 +30,7 @@ import { GetNodeAPI, NetworkConfig } from "../interfaces"; import { EntryPointVersion } from "../services/EntryPointService/interfaces"; import { getUserOpGasLimit } from "../services/BundlingService/utils"; import { maxBn, minBn } from "../utils/bignumber"; +import { validateAuthorization } from "../services/BundlingService/utils/eip7702"; import { EstimateUserOperationGasArgs, SendUserOperationGasArgs, @@ -109,6 +110,20 @@ export class Eth { entryPoint, userOp ); + + // eip-7702 validation + if (userOp.authorizationContract) { + const nonce = await this.provider.getTransactionCount(userOp.sender); + const valid = await validateAuthorization(this.chainId, userOp, nonce); + if (!valid) { + throw new RpcError( + "Invalid authorization. Check nonce", + RpcErrorCodes.INVALID_USEROP + ); + } + userOp.authorizationNonce = nonce; + } + await this.mempoolService.addUserOp( userOp, entryPoint, diff --git a/packages/executor/src/services/BundlingService/relayers/classic.ts b/packages/executor/src/services/BundlingService/relayers/classic.ts index c75f99f2..f11c04e1 100644 --- a/packages/executor/src/services/BundlingService/relayers/classic.ts +++ b/packages/executor/src/services/BundlingService/relayers/classic.ts @@ -1,9 +1,12 @@ -import { providers } from "ethers"; +import { providers, Wallet } from "ethers"; import { chainsWithoutEIP1559 } from "@skandha/params/lib"; import { AccessList } from "ethers/lib/utils"; +import { AuthorizationList } from "viem/experimental"; +import { odysseyTestnet } from "viem/chains"; import { Relayer } from "../interfaces"; import { Bundle, StorageMap } from "../../../interfaces"; import { estimateBundleGasLimit } from "../utils"; +import { getAuthorizationList, getRaw7702Transaction } from "../utils/eip7702"; import { BaseRelayer } from "./base"; export class ClassicRelayer extends BaseRelayer { @@ -100,7 +103,12 @@ export class ClassicRelayer extends BaseRelayer { .map((entry) => entry.userOpHash) .join(", ")}` ); - await this.submitTransaction(relayer, transaction, storageMap) + await this.submitTransaction( + relayer, + transaction, + storageMap, + await getAuthorizationList(this.chainId, bundle) + ) .then(async (txHash: string) => { this.logger.debug(`Bundle submitted: ${txHash}`); this.logger.debug( @@ -150,9 +158,17 @@ export class ClassicRelayer extends BaseRelayer { private async submitTransaction( relayer: Relayer, transaction: providers.TransactionRequest, - storageMap: StorageMap + storageMap: StorageMap, + authorizationList?: AuthorizationList ): Promise { - const signedRawTx = await relayer.signTransaction(transaction); + let signedRawTx = await relayer.signTransaction(transaction); + if (this.chainId in [odysseyTestnet.id]) { + signedRawTx = await getRaw7702Transaction( + transaction, + authorizationList!, + (relayer as Wallet).privateKey as `0x${string}` + ); + } const method = !this.networkConfig.conditionalTransactions ? "eth_sendRawTransaction" : "eth_sendRawTransactionConditional"; diff --git a/packages/executor/src/services/BundlingService/utils/eip7702.ts b/packages/executor/src/services/BundlingService/utils/eip7702.ts new file mode 100644 index 00000000..3c02e973 --- /dev/null +++ b/packages/executor/src/services/BundlingService/utils/eip7702.ts @@ -0,0 +1,87 @@ +import { + Authorization, + AuthorizationList, + verifyAuthorization, +} from "viem/experimental"; +import { BigNumber, providers } from "ethers"; +import { createWalletClient, http, parseSignature } from "viem"; +import { odysseyTestnet } from "viem/chains"; +import { UserOperation } from "@skandha/types/lib/contracts/UserOperation"; +import { Bundle } from "../../../interfaces"; + +export async function validateAuthorization( + chainId: number, + userOp: UserOperation, + nonce: number +): Promise { + const authorization: Authorization = { + contractAddress: userOp.authorizationContract as `0x${string}`, + chainId, + nonce, + }; + return await verifyAuthorization({ + address: userOp.sender as `0x${string}`, + authorization, + signature: userOp.authorizationSignature as `0x${string}`, + }); +} + +export async function getAuthorizationList( + chainId: number, + bundle: Bundle +): Promise { + if (chainId != odysseyTestnet.id) return []; + const authorizationList = []; + for (const entry of bundle.entries) { + const { userOp } = entry; + if (!userOp.authorizationContract) continue; + const authorization: Authorization = { + contractAddress: userOp.authorizationContract as `0x${string}`, + chainId, + nonce: userOp.authorizationNonce!, + }; + const { r, s, yParity } = parseSignature( + userOp.authorizationSignature as `0x${string}` + ); + authorization.r = r; + authorization.s = s; + authorization.yParity = yParity; + + authorizationList.push(authorization); + } + return authorizationList; +} + +export async function getRaw7702Transaction( + transactionRequest: providers.TransactionRequest, + authorizationList: AuthorizationList, + relayer: `0x${string}` +): Promise { + const wallet = createWalletClient({ + transport: http(), + account: relayer, + }); + const transaction = await wallet.signTransaction({ + chain: odysseyTestnet, + authorizationList, + to: transactionRequest.to as `0x${string}`, + gas: + transactionRequest.gasLimit != undefined + ? BigNumber.from(transactionRequest.gasLimit).toBigInt() + : undefined, + maxFeePerGas: + transactionRequest.maxFeePerGas != undefined + ? BigNumber.from(transactionRequest.maxFeePerGas).toBigInt() + : undefined, + maxPriorityFeePerGas: + transactionRequest.maxPriorityFeePerGas != undefined + ? BigNumber.from(transactionRequest.maxPriorityFeePerGas).toBigInt() + : undefined, + data: transactionRequest.data as `0x${string}`, + nonce: + transactionRequest.nonce != undefined + ? BigNumber.from(transactionRequest.nonce).toNumber() + : undefined, + }); + return transaction; +} diff --git a/packages/types/src/contracts/UserOperation.ts b/packages/types/src/contracts/UserOperation.ts index a3fb7d48..3e9a1338 100644 --- a/packages/types/src/contracts/UserOperation.ts +++ b/packages/types/src/contracts/UserOperation.ts @@ -24,7 +24,8 @@ export interface UserOperation { // eip-7702 fields authorizationContract?: string; - authorizationSignature?: string; + authorizationSignature?: BytesLike; + authorizationNonce?: number; } export type PackedUserOperation = NotPromise; diff --git a/tsconfig.build.json b/tsconfig.build.json index d0e38040..4b811146 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -18,6 +18,7 @@ "noImplicitAny": true, "noImplicitThis": true, "noImplicitReturns": true, + "skipLibCheck": true, "esModuleInterop": true, "declaration": true, From ef30a3a48d786512e7ce40f7a0948b39788e4c11 Mon Sep 17 00:00:00 2001 From: marie-fourier Date: Fri, 1 Nov 2024 21:34:43 +0500 Subject: [PATCH 3/4] wip: eip7702 --- packages/executor/src/modules/eth.ts | 34 +++++++++--- .../services/BundlingService/relayers/base.ts | 2 + .../BundlingService/relayers/classic.ts | 2 +- .../services/BundlingService/utils/eip7702.ts | 54 +++++++++++++++---- 4 files changed, 76 insertions(+), 16 deletions(-) diff --git a/packages/executor/src/modules/eth.ts b/packages/executor/src/modules/eth.ts index b7f61edd..525bca3a 100644 --- a/packages/executor/src/modules/eth.ts +++ b/packages/executor/src/modules/eth.ts @@ -113,15 +113,26 @@ export class Eth { // eip-7702 validation if (userOp.authorizationContract) { - const nonce = await this.provider.getTransactionCount(userOp.sender); - const valid = await validateAuthorization(this.chainId, userOp, nonce); + if ( + userOp.authorizationSignature == undefined || + userOp.authorizationNonce == undefined + ) { + throw new RpcError( + "Invalid Authorization. Missing fields", + RpcErrorCodes.INVALID_USEROP + ); + } + const valid = await validateAuthorization( + this.chainId, + userOp, + userOp.authorizationNonce + ); if (!valid) { throw new RpcError( - "Invalid authorization. Check nonce", + "Invalid authorization. Check signature", RpcErrorCodes.INVALID_USEROP ); } - userOp.authorizationNonce = nonce; } await this.mempoolService.addUserOp( @@ -240,9 +251,16 @@ export class Eth { }); //> + const eip7702 = + userOp.authorizationContract != undefined && + userOp.authorizationContract.length > 2; let callGasLimit = minBn(binarySearchCGL, paidFeeCGL); // check between binary search & paid fee cgl - if (userOp.factoryData !== undefined && userOp.factoryData.length <= 2) { + if ( + userOp.factoryData !== undefined && + userOp.factoryData.length <= 2 && + !eip7702 + ) { await this.provider .estimateGas({ from: entryPoint, @@ -256,7 +274,11 @@ export class Eth { } // check between eth_estimateGas & binary search & paid fee cgl - if (userOp.factoryData !== undefined && userOp.factoryData.length <= 2) { + if ( + userOp.factoryData !== undefined && + userOp.factoryData.length <= 2 && + !eip7702 + ) { const prevCGL = callGasLimit; callGasLimit = minBn(ethEstimateGas, callGasLimit); await this.provider diff --git a/packages/executor/src/services/BundlingService/relayers/base.ts b/packages/executor/src/services/BundlingService/relayers/base.ts index e931a7ae..86fc70ce 100644 --- a/packages/executor/src/services/BundlingService/relayers/base.ts +++ b/packages/executor/src/services/BundlingService/relayers/base.ts @@ -12,6 +12,7 @@ import { MempoolService } from "../../MempoolService"; import { ReputationService } from "../../ReputationService"; import { ExecutorEventBus } from "../../SubscriptionService"; import { EntryPointService } from "../../EntryPointService"; +import { odysseyTestnet } from "viem/chains"; const WAIT_FOR_TX_MAX_RETRIES = 3; // 3 blocks @@ -183,6 +184,7 @@ export abstract class BaseRelayer implements IRelayingMode { transactionRequest: providers.TransactionRequest ): Promise { if (this.networkConfig.skipBundleValidation) return true; + if (this.chainId == odysseyTestnet.id) return true; try { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { gasLimit: _, ...txWithoutGasLimit } = transactionRequest; diff --git a/packages/executor/src/services/BundlingService/relayers/classic.ts b/packages/executor/src/services/BundlingService/relayers/classic.ts index f11c04e1..db8acc42 100644 --- a/packages/executor/src/services/BundlingService/relayers/classic.ts +++ b/packages/executor/src/services/BundlingService/relayers/classic.ts @@ -162,7 +162,7 @@ export class ClassicRelayer extends BaseRelayer { authorizationList?: AuthorizationList ): Promise { let signedRawTx = await relayer.signTransaction(transaction); - if (this.chainId in [odysseyTestnet.id]) { + if (odysseyTestnet.id == this.chainId) { signedRawTx = await getRaw7702Transaction( transaction, authorizationList!, diff --git a/packages/executor/src/services/BundlingService/utils/eip7702.ts b/packages/executor/src/services/BundlingService/utils/eip7702.ts index 3c02e973..a3aa2734 100644 --- a/packages/executor/src/services/BundlingService/utils/eip7702.ts +++ b/packages/executor/src/services/BundlingService/utils/eip7702.ts @@ -3,10 +3,16 @@ import { AuthorizationList, verifyAuthorization, } from "viem/experimental"; -import { BigNumber, providers } from "ethers"; -import { createWalletClient, http, parseSignature } from "viem"; +import { BigNumber, ethers, providers } from "ethers"; +import { + createPublicClient, + createWalletClient, + http, + parseSignature, +} from "viem"; import { odysseyTestnet } from "viem/chains"; import { UserOperation } from "@skandha/types/lib/contracts/UserOperation"; +import { privateKeyToAccount } from "viem/accounts"; import { Bundle } from "../../../interfaces"; export async function validateAuthorization( @@ -17,12 +23,13 @@ export async function validateAuthorization( const authorization: Authorization = { contractAddress: userOp.authorizationContract as `0x${string}`, chainId, - nonce, + nonce: ethers.BigNumber.from(nonce).toNumber(), + ...parseSignature(userOp.authorizationSignature as `0x${string}`), }; + console.log("authorization check", authorization); return await verifyAuthorization({ address: userOp.sender as `0x${string}`, authorization, - signature: userOp.authorizationSignature as `0x${string}`, }); } @@ -38,7 +45,7 @@ export async function getAuthorizationList( const authorization: Authorization = { contractAddress: userOp.authorizationContract as `0x${string}`, chainId, - nonce: userOp.authorizationNonce!, + nonce: BigNumber.from(userOp.authorizationNonce!).toNumber(), }; const { r, s, yParity } = parseSignature( userOp.authorizationSignature as `0x${string}` @@ -58,10 +65,14 @@ export async function getRaw7702Transaction( relayer: `0x${string}` ): Promise { const wallet = createWalletClient({ - transport: http(), - account: relayer, + transport: http(odysseyTestnet.rpcUrls.default.http[0]), + account: privateKeyToAccount(relayer), + }); + const publicClient = createPublicClient({ + chain: odysseyTestnet, + transport: http(odysseyTestnet.rpcUrls.default.http[0]), }); - const transaction = await wallet.signTransaction({ + const txRequest = { chain: odysseyTestnet, authorizationList, to: transactionRequest.to as `0x${string}`, @@ -82,6 +93,31 @@ export async function getRaw7702Transaction( transactionRequest.nonce != undefined ? BigNumber.from(transactionRequest.nonce).toNumber() : undefined, - }); + }; + // test + // txRequest.to = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; + // txRequest.data = "0x"; + console.log("viem txrequest", txRequest); + // try { + // console.log( + // "estimation", + // await publicClient.estimateGas({ + // ...txRequest, + // gas: undefined, + // }) + // ); + // } catch (err) { + // console.log(err); + // throw new Error("failed estimation"); + // } + const transaction = await wallet + .signTransaction({ + ...txRequest, + type: "eip7702", + }) + .catch((err) => { + console.log(err); + throw err; + }); return transaction; } From 5d5fce928de35045e1f0531296c4e5402b5a7687 Mon Sep 17 00:00:00 2001 From: marie-fourier Date: Mon, 4 Nov 2024 16:23:20 +0500 Subject: [PATCH 4/4] add delegate --- packages/executor/src/modules/eth.ts | 1 + packages/types/src/api/interfaces.ts | 1 + yarn.lock | 102 +++++++++++++++++++++++++-- 3 files changed, 98 insertions(+), 6 deletions(-) diff --git a/packages/executor/src/modules/eth.ts b/packages/executor/src/modules/eth.ts index 525bca3a..e9790bad 100644 --- a/packages/executor/src/modules/eth.ts +++ b/packages/executor/src/modules/eth.ts @@ -347,6 +347,7 @@ export class Eth { callGasLimit, maxFeePerGas: gasFee.maxFeePerGas, maxPriorityFeePerGas: gasFee.maxPriorityFeePerGas, + delegate: eip7702 ? this.config.relayers[0] : undefined, }; } diff --git a/packages/types/src/api/interfaces.ts b/packages/types/src/api/interfaces.ts index fda46c9a..4fc1e385 100644 --- a/packages/types/src/api/interfaces.ts +++ b/packages/types/src/api/interfaces.ts @@ -9,6 +9,7 @@ export type EstimatedUserOperationGas = { callGasLimit: BigNumberish; validAfter?: BigNumberish; validUntil?: BigNumberish; + delegate?: string; } & GetGasPriceResponse; export type UserOperationByHashResponse = { diff --git a/yarn.lock b/yarn.lock index 94c557fa..19596a1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -39,6 +39,11 @@ merge-options "^3.0.4" xml2js "^0.5.0" +"@adraffy/ens-normalize@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz#42cc67c5baa407ac25059fcd7d405cc5ecdb0c33" + integrity sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg== + "@ampproject/remapping@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" @@ -94,6 +99,11 @@ resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== +"@chainsafe/as-sha256@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.4.2.tgz#21ad1371e2245e430c1a554a05f10d333c6f42cc" + integrity sha512-HJ8GZBRjLeWtRsAXf3EbNsNzmTGpzTFjfpSf4yHkLYC+E52DhT6hwz+7qpj6I/EmFzSUm5tYYvT9K8GZokLQCQ== + "@chainsafe/bls-hd-key@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@chainsafe/bls-hd-key/-/bls-hd-key-0.3.0.tgz#2de2649d5daa76f7460fc23caacf4ed3ebd2c02a" @@ -222,6 +232,14 @@ dependencies: "@chainsafe/as-sha256" "^0.3.1" +"@chainsafe/persistent-merkle-tree@^0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.7.2.tgz#f0ef91daf36752f827432333cbc965f4bf6e750e" + integrity sha512-BUAqrmSUmy6bZhXxnhpR+aYoEDdCeS1dQvq/aje0CDEB14ZHF9UVN2mL9MolOD0ANUiP1OaPG3KfVBxvuW8aTg== + dependencies: + "@chainsafe/as-sha256" "^0.4.2" + "@noble/hashes" "^1.3.0" + "@chainsafe/ssz@0.10.1": version "0.10.1" resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.1.tgz#c05ec168a3c7de1e6b72eac170afbe497ffca329" @@ -230,13 +248,13 @@ "@chainsafe/as-sha256" "^0.3.1" "@chainsafe/persistent-merkle-tree" "^0.5.0" -"@chainsafe/ssz@0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" - integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== +"@chainsafe/ssz@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.16.0.tgz#262c491ac037777a16e8d8db479da2ba27539b8d" + integrity sha512-CgTDyrkbAKvrKwHxPT5rerXAHP3NB+uOvpnN9Gn8aJ/4TGOKhOboj4131bSFUZ679uPJ6pu6391cvInuOdrglw== dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.5.0" + "@chainsafe/as-sha256" "^0.4.2" + "@chainsafe/persistent-merkle-tree" "^0.7.2" "@chainsafe/threads@1.10.0": version "1.10.0" @@ -1731,6 +1749,13 @@ dependencies: "@noble/hashes" "1.3.1" +"@noble/curves@1.6.0", "@noble/curves@^1.4.0", "@noble/curves@~1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.6.0.tgz#be5296ebcd5a1730fccea4786d420f87abfeb40b" + integrity sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ== + dependencies: + "@noble/hashes" "1.5.0" + "@noble/ed25519@^1.6.0": version "1.7.3" resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.3.tgz#57e1677bf6885354b466c38e2b620c62f45a7123" @@ -1741,6 +1766,11 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== +"@noble/hashes@1.5.0", "@noble/hashes@^1.3.0", "@noble/hashes@^1.4.0", "@noble/hashes@~1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0" + integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA== + "@noble/hashes@^1.0.0", "@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": version "1.3.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" @@ -2238,6 +2268,11 @@ resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.3.tgz#8584115565228290a6c6c4961973e0903bb3df2f" integrity sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q== +"@scure/base@~1.1.7", "@scure/base@~1.1.8": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1" + integrity sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg== + "@scure/bip32@1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10" @@ -2247,6 +2282,15 @@ "@noble/hashes" "~1.3.1" "@scure/base" "~1.1.0" +"@scure/bip32@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.5.0.tgz#dd4a2e1b8a9da60e012e776d954c4186db6328e6" + integrity sha512-8EnFYkqEQdnkuGBVpCzKxyIwDCBLDVj3oiX0EKUFre/tOjL/Hqba1D6n/8RcmaQy4f95qQFrO2A8Sr6ybh4NRw== + dependencies: + "@noble/curves" "~1.6.0" + "@noble/hashes" "~1.5.0" + "@scure/base" "~1.1.7" + "@scure/bip39@1.2.1", "@scure/bip39@^1.0.0": version "1.2.1" resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" @@ -2255,6 +2299,14 @@ "@noble/hashes" "~1.3.0" "@scure/base" "~1.1.0" +"@scure/bip39@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.4.0.tgz#664d4f851564e2e1d4bffa0339f9546ea55960a6" + integrity sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw== + dependencies: + "@noble/hashes" "~1.5.0" + "@scure/base" "~1.1.8" + "@sigstore/bundle@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-1.1.0.tgz#17f8d813b09348b16eeed66a8cf1c3d6bd3d04f1" @@ -2938,6 +2990,11 @@ abbrev@^1.0.0: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abitype@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.6.tgz#76410903e1d88e34f1362746e2d407513c38565b" + integrity sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -5968,6 +6025,11 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== +isows@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.6.tgz#0da29d706fa51551c663c627ace42769850f86e7" + integrity sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw== + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" @@ -9658,6 +9720,21 @@ varint@6.0.0, varint@^6.0.0: resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== +viem@2.21.37: + version "2.21.37" + resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.37.tgz#4d67bee8749321b0fd142c54df2021d5774403b1" + integrity sha512-JupwyttT4aJNnP9+kD7E8jorMS5VmgpC3hm3rl5zXsO8WNBTsP3JJqZUSg4AG6s2lTrmmpzS/qpmXMZu5gJw5Q== + dependencies: + "@adraffy/ens-normalize" "1.11.0" + "@noble/curves" "1.6.0" + "@noble/hashes" "1.5.0" + "@scure/bip32" "1.5.0" + "@scure/bip39" "1.4.0" + abitype "1.0.6" + isows "1.0.6" + webauthn-p256 "0.0.10" + ws "8.18.0" + vite-node@0.34.6: version "0.34.6" resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.34.6.tgz#34d19795de1498562bf21541a58edcd106328a17" @@ -9737,6 +9814,14 @@ web3-utils@^1.3.4: randombytes "^2.1.0" utf8 "3.0.0" +webauthn-p256@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/webauthn-p256/-/webauthn-p256-0.0.10.tgz#877e75abe8348d3e14485932968edf3325fd2fdd" + integrity sha512-EeYD+gmIT80YkSIDb2iWq0lq2zbHo1CxHlQTeJ+KkCILWpVy3zASH3ByD4bopzfk0uCwXxLqKGLqp2W4O28VFA== + dependencies: + "@noble/curves" "^1.4.0" + "@noble/hashes" "^1.4.0" + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -9898,6 +9983,11 @@ ws@8.16.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== +ws@8.18.0: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + ws@^8.0.0: version "8.17.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.0.tgz#d145d18eca2ed25aaf791a183903f7be5e295fea"