@nevermined-io/core-kit 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contracts/ContractBase.d.ts.map +1 -1
- package/dist/contracts/ContractBase.js +2 -2
- package/dist/contracts/ContractBase.js.map +1 -1
- package/dist/nevermined/utils/BlockchainViemUtils.d.ts +29 -14
- package/dist/nevermined/utils/BlockchainViemUtils.d.ts.map +1 -1
- package/dist/nevermined/utils/BlockchainViemUtils.js +48 -33
- package/dist/nevermined/utils/BlockchainViemUtils.js.map +1 -1
- package/dist/nevermined/utils/ZeroDevPolicies.d.ts +2 -2
- package/dist/nevermined/utils/ZeroDevPolicies.d.ts.map +1 -1
- package/dist/nevermined/utils/ZeroDevPolicies.js +27 -14
- package/dist/nevermined/utils/ZeroDevPolicies.js.map +1 -1
- package/dist/utils/Network.d.ts +6 -1
- package/dist/utils/Network.d.ts.map +1 -1
- package/dist/utils/Network.js +6 -1
- package/dist/utils/Network.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContractBase.d.ts","sourceRoot":"","sources":["../../src/contracts/ContractBase.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ContractBase.d.ts","sourceRoot":"","sources":["../../src/contracts/ContractBase.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,GAAG,EACH,OAAO,EACP,OAAO,EAQP,kBAAkB,EACnB,MAAM,MAAM,CAAA;AACb,OAAO,EAGL,YAAY,EACZ,oBAAoB,EACrB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAKxD,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,OAAO,CAAA;IACxB,GAAG,EAAE,GAAG,CAAA;IACR,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,GAAG,EAAE,CAAA;CACZ;AA0CD,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,GAAG,EAAE,CAAA;IACX,EAAE,EAAE,OAAO,CAAA;CACZ;AAED,8BAAsB,YAAa,SAAQ,YAAY;IACrD,SAAgB,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,EAAE,GAAG,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IACvB,OAAO,CAAC,iBAAiB,CAA+D;gBAE5E,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;cAMlC,IAAI,CAClB,MAAM,EAAE,kBAAkB,EAC1B,cAAc,EAAE;QAAE,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;QAAC,GAAG,EAAE,GAAG,CAAA;KAAE;IAYzC,IAAI,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAiBrE,qBAAqB,CAChC,MAAM,EAAE,oBAAoB,GAAG,kBAAkB,GAChD,OAAO,CAAC,kBAAkB,CAAC;IAiBvB,kBAAkB,CACvB,SAAS,EAAE,kBAAkB,GAAG,oBAAoB,EACpD,SAAS,CAAC,EAAE,MAAM,GAOZ,GAAG,EAAE;IAGA,SAAS,CACpB,KAAK,EAAE,cAAc,EAAE,EACvB,IAAI,EAAE,OAAO,GAAG,YAAY,EAC5B,MAAM,GAAE,YAAiB;IAgBd,iBAAiB,CAC5B,KAAK,EAAE,sBAAsB,EAAE,EAC/B,IAAI,EAAE,OAAO,GAAG,YAAY,EAC5B,MAAM,GAAE,YAAiB;IAgBd,QAAQ,CACnB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,OAAO,GAAG,YAAY,EAC5B,IAAI,EAAE,GAAG,EAAE,EACX,MAAM,GAAE,YAAiB;IAgBd,IAAI,CACf,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,OAAO,GAAG,YAAY,EAC5B,IAAI,EAAE,GAAG,EAAE,EACX,MAAM,GAAE,YAAiB,GACxB,OAAO,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;IAiBrD;;;;;;;OAOG;IACU,uBAAuB,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;YA8BjF,6BAA6B;IAuF3C,OAAO,CAAC,qBAAqB;YAaf,wBAAwB;YAmMxB,4BAA4B;YAuB5B,oBAAoB;YAuBpB,gBAAgB;YAmIhB,qBAAqB;YAyBrB,6BAA6B;YAqB7B,qCAAqC;IAkEnD,OAAO,CAAC,oBAAoB;IAU5B;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAW1B,SAAS,CAAC,aAAa,IAAI,MAAM;IAcjC,OAAO,CAAC,eAAe;CAYxB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createKernelAccountClient, createZeroDevPaymasterClient } from '@zerodev/sdk';
|
|
2
|
-
import {
|
|
2
|
+
import { estimateUserOperationFees, getBundlerRpcUrl, getPaymasterRpcUrl, isRelayerMode } from '../nevermined/utils/BlockchainViemUtils.js';
|
|
3
3
|
import { BaseError, ContractFunctionRevertedError, encodeFunctionData, getContract, http, parseAbi, parseEventLogs } from 'viem';
|
|
4
4
|
import { createBundlerClient, getUserOperationHash } from 'viem/account-abstraction';
|
|
5
5
|
import { ContractsError, ContractSimulationError } from '../errors/index.js';
|
|
@@ -689,7 +689,7 @@ export class ContractBase extends Instantiable {
|
|
|
689
689
|
return {
|
|
690
690
|
paymaster: {
|
|
691
691
|
getPaymasterData: (userOperation)=>zerodevPaymaster.sponsorUserOperation({
|
|
692
|
-
userOperation
|
|
692
|
+
userOperation
|
|
693
693
|
})
|
|
694
694
|
}
|
|
695
695
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/contracts/ContractBase.ts"],"sourcesContent":["import { createKernelAccountClient, createZeroDevPaymasterClient } from '@zerodev/sdk'\nimport {\n applyTempoVerificationGasFloor,\n estimateUserOperationFees,\n getBundlerRpcUrl,\n getPaymasterRpcUrl,\n isRelayerMode,\n} from '../nevermined/utils/BlockchainViemUtils.js'\nimport {\n Abi,\n Account,\n Address,\n BaseError,\n ContractFunctionRevertedError,\n encodeFunctionData,\n getContract,\n http,\n parseAbi,\n parseEventLogs,\n TransactionReceipt,\n} from 'viem'\nimport {\n createBundlerClient,\n getUserOperationHash,\n SmartAccount,\n UserOperationReceipt,\n} from 'viem/account-abstraction'\nimport { ContractsError, ContractSimulationError } from '../errors/index.js'\nimport { Instantiable, InstantiableConfig } from '../Instantiable.abstract.js'\nimport { TxParameters } from '../models/Transactions.js'\nimport { getInputsOfFunctionFormatted, getTransactionReceipt } from '../nevermined/index.js'\nimport { getRandomBigInt } from '../utils/helpers.js'\nimport { getChain } from '../utils/Network.js'\n\nexport interface MulticallEntry {\n contractName?: string\n contractAddress: Address\n abi: Abi\n functionName: string\n args: any[]\n}\n\n/**\n * When a testnet RPC (Base Sepolia) fails internally, some providers return\n * `eth_estimateGas` values equal to — or even above — the block gas limit\n * instead of a real error. Using that value causes the node to reject the tx\n * with `intrinsic gas too high` before it ever reaches the mempool.\n *\n * `writeContract` in viem re-estimates gas internally when `gas` isn't\n * already set on the request (viem's `simulateContract` only performs\n * `eth_call`, not `eth_estimateGas`). That means the naïve path has no\n * chance to intercept a bogus estimate. We run the estimation ourselves\n * here, sanity-check the result, and always pass an explicit gas value\n * into `writeContract` so it doesn't re-query the misbehaving RPC.\n */\nconst GAS_SANITY_THRESHOLD = 25_000_000n\nconst GAS_FALLBACK_CAP = 5_000_000n\n\n// EntryPoint v0.7: ZeroDev's `toKernelPluginManager` rejects `customNonceKey > maxUint16`.\n// 16 bits = 65 536 channels — collision probability for the SDK's expected concurrency\n// (k=2–5 parallel sends from one SCA) is negligible (< 0.02 %). High-fan-out callers\n// (k > 50) should consider a per-process monotonic counter instead. See issue #1579.\nconst ZERODEV_NONCE_KEY_BITS = 16\n\n// Client-side cap on `waitForUserOperationReceipt`. The userOp is already in the bundler\n// mempool when this fires — a client-side timeout does NOT cancel it. Callers that catch\n// the resulting `ContractsError` MUST poll `bundlerClient.getUserOperationReceipt(hash)`\n// before retrying; otherwise a retry can produce a duplicate on-chain op.\nconst USEROP_RECEIPT_TIMEOUT_MS = 90_000\n\nfunction capForBogusEstimate(\n estimatedGas: bigint,\n logger: { warn: (msg: string) => void },\n): bigint {\n if (estimatedGas < GAS_SANITY_THRESHOLD) return estimatedGas\n logger.warn(\n `Estimated gas (${estimatedGas}) exceeds sanity threshold ` +\n `(${GAS_SANITY_THRESHOLD}); overriding with ${GAS_FALLBACK_CAP} to bypass misbehaving RPC estimate.`,\n )\n return GAS_FALLBACK_CAP\n}\n\nexport interface SimulateMulticallEntry {\n functionName: string\n value?: bigint\n abi: Abi\n args: any[]\n to: Address\n}\n\nexport abstract class ContractBase extends Instantiable {\n public readonly contractName: string\n public contract: any\n public address: Address\n private _zeroDevPaymaster: ReturnType<typeof createZeroDevPaymasterClient> | null = null\n\n constructor(contractName: string, address: Address) {\n super()\n this.contractName = contractName\n this.address = address\n }\n\n protected async init(\n config: InstantiableConfig,\n contractConfig: { address: `0x${string}`; abi: Abi },\n ) {\n this.setInstanceConfig(config)\n this.address = contractConfig.address\n\n this.contract = getContract({\n address: contractConfig.address,\n abi: contractConfig.abi,\n client: { public: this.publicClient, wallet: this.walletClient },\n })\n }\n\n public async call<T>(functionName: string, args: any[], from?: string): Promise<T> {\n try {\n return (await this.client.public.readContract({\n address: this.address,\n abi: this.contract.abi,\n functionName: parseAbi([functionName]),\n args,\n ...(from && { account: from as `0x${string}` }),\n })) as T\n //return await this.contract[functionSignature](...args, { from })\n } catch (err) {\n throw new ContractsError(\n `Calling method \"${functionName}\" on contract \"${this.contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n }\n\n public async getTransactionReceipt(\n txHash: UserOperationReceipt | TransactionReceipt,\n ): Promise<TransactionReceipt> {\n // Get the transaction receipt depending on the type of txHash\n if ('transactionHash' in txHash) {\n // txHash is TransactionReceipt\n return txHash\n } else if ('userOpHash' in txHash) {\n // txHash is UserOperationReceipt, fetch the actual receipt using the utility function with retry logic\n const hash = txHash.receipt.transactionHash\n return await getTransactionReceipt({\n txHash: hash,\n publicClient: this.client.public,\n })\n } else {\n throw new Error('Unknown transaction type')\n }\n }\n\n public getTransactionLogs(\n txReceipt: TransactionReceipt | UserOperationReceipt,\n eventName?: string,\n ) {\n return parseEventLogs({\n abi: this.contract.abi,\n logs: txReceipt.logs,\n eventName,\n strict: false,\n }) as any[]\n }\n\n public async multicall(\n calls: MulticallEntry[],\n from: Account | SmartAccount,\n params: TxParameters = {},\n ) {\n if (from.type === 'local') {\n this.logger.debug(`Blockchain Multicall using Local account`)\n return await this.localAccountMulticall(calls, from, params, params.progress)\n } else if (from.type === 'json-rpc') {\n this.logger.debug(`Blockchain Multicall using JSON-RPC account`)\n return await this.localAccountMulticall(calls, from, params, params.progress)\n } else if (from.type === 'smart') {\n this.logger.debug(`Blockchain Multicall using ZeroDev account`)\n return await this.internalMulticallSmartAccount(calls, from, params, params.progress)\n } else {\n throw new ContractsError(`Account not supported`)\n }\n }\n\n public async simulateMulticall(\n calls: SimulateMulticallEntry[],\n from: Account | SmartAccount,\n params: TxParameters = {},\n ) {\n if (from.type === 'local') {\n this.logger.debug(`Simulating calls using Local account`)\n return await this.localAccountSimulateMulticall(calls, from, params)\n } else if (from.type === 'json-rpc') {\n this.logger.debug(`Simulating calls using JSON-RPC account`)\n return await this.localAccountSimulateMulticall(calls, from, params)\n } else if (from.type === 'smart') {\n this.logger.debug(`Simulating calls using Smart Account account`)\n return await this.internalSimulateMulticallSmartAccount(calls, from, params)\n } else {\n throw new ContractsError(`Account not supported`)\n }\n }\n\n public async simulate(\n functionName: string,\n from: Account | SmartAccount,\n args: any[],\n params: TxParameters = {},\n ) {\n if (from.type === 'local') {\n this.logger.debug(`Simulating calls using Local account`)\n return await this.localAccountSimulate(functionName, from, args, params)\n } else if (from.type === 'json-rpc') {\n this.logger.debug(`Simulating calls using JSON-RPC account`)\n return await this.localAccountSimulate(functionName, from, args, params)\n } else if (from.type === 'smart') {\n this.logger.debug(`Simulating calls using Smart Account account`)\n return await this.internalSimulateSmartAccount(functionName, from, args, params)\n } else {\n throw new ContractsError(`Account not supported`)\n }\n }\n\n public async send(\n functionName: string,\n from: Account | SmartAccount,\n args: any[],\n params: TxParameters = {},\n ): Promise<TransactionReceipt | UserOperationReceipt> {\n if (from.type === 'local') {\n this.logger.debug(\n `Blockchain Send using Local account with functionName: ${functionName} and following args: ${args}`,\n )\n return await this.localAccountSend(functionName, from, args, params, params.progress)\n } else if (from.type === 'json-rpc') {\n this.logger.debug(`Blockchain Send using JSON-RPC account to ${functionName}`)\n return await this.localAccountSend(functionName, from, args, params, params.progress)\n } else if (from.type === 'smart') {\n this.logger.debug(`Blockchain Send using ZeroDev account`)\n return await this.internalSendSmartAccount(functionName, from, args, params, params.progress)\n } else {\n throw new ContractsError(`Account not supported`)\n }\n }\n\n /**\n * Poll a previously-submitted UserOperation's receipt by hash WITHOUT\n * blocking. Returns the receipt once the bundler has mined it, or `null`\n * while it is still in the mempool / not yet known. A client-side\n * receipt-wait timeout does NOT cancel a submitted UserOp, so callers that\n * persist the hash (e.g. the onchain-mirror worker, nvm-monorepo#1508) use\n * this to confirm a prior submission instead of resubmitting a duplicate.\n */\n public async getUserOperationReceipt(hash: `0x${string}`): Promise<UserOperationReceipt | null> {\n try {\n const bundlerClient = createBundlerClient({\n chain: getChain(this.config.chainId),\n transport: http(this.getBundlerRPC()),\n client: this.client.public,\n })\n return (await bundlerClient.getUserOperationReceipt({ hash })) ?? null\n } catch (err) {\n // A genuinely-absent receipt (UserOp still in the mempool) is expected\n // and benign — some bundlers signal it by throwing rather than returning\n // null. Anything else (RPC/transport/config fault) must NOT masquerade as\n // \"still pending\": surface it at `warn` so a bundler outage is visible\n // instead of silently driving the caller's grace-window logic. Either\n // way we return null so the caller re-polls rather than consuming a retry.\n const message = err instanceof Error ? err.message : String(err)\n if (/not[\\s_]?found|UserOperationReceiptNotFound/i.test(message)) {\n this.logger.debug(`getUserOperationReceipt(${hash}): not yet mined`)\n } else {\n // Redact URLs before logging: the bundler RPC URL embeds the ZeroDev\n // project id, which should not leak into logs.\n const safeMessage = message.replace(/https?:\\/\\/[^\\s'\")]+/gi, '<redacted-url>')\n this.logger.warn(\n `getUserOperationReceipt(${hash}) lookup error (treating as not-yet-mined): ${safeMessage}`,\n )\n }\n return null\n }\n }\n\n private async internalMulticallSmartAccount(\n calls: MulticallEntry[],\n from: SmartAccount,\n txparams: any,\n progress: ((data: any) => void) | undefined,\n ) {\n if (progress) {\n progress({\n stage: 'multicall-sending',\n args: [],\n method: '',\n from: from,\n contractAddress: this.address,\n })\n }\n\n const kernelClient = createKernelAccountClient({\n account: from,\n chain: getChain(this.config.chainId),\n bundlerTransport: http(this.getBundlerRPC()),\n client: this.client.public,\n ...this.getPaymasterConfig(),\n userOperation: {\n estimateFeesPerGas: async ({ bundlerClient }) => {\n return estimateUserOperationFees(bundlerClient, this.client.public)\n },\n },\n })\n\n const encodedCalls: any[] = []\n calls.map((call) => {\n encodedCalls.push({\n to: call.contractAddress || this.address,\n value: txparams.value || 0n,\n data: encodeFunctionData({\n abi: call.abi,\n functionName: call.functionName,\n args: call.args,\n }),\n })\n })\n\n let userOpHash: `0x${string}` | undefined\n try {\n // Random nonce key per send so concurrent userOps from the same SCA\n // hit distinct EntryPoint nonce channels instead of colliding on the\n // default `customNonceKey=0n`. See issue #1579.\n const nonce = await from.getNonce({ key: getRandomBigInt(ZERODEV_NONCE_KEY_BITS) })\n userOpHash = await kernelClient.sendUserOperation({\n callData: await kernelClient.account.encodeCalls(encodedCalls),\n nonce,\n })\n\n if (progress) {\n progress({\n stage: 'multicall-sent',\n args: [],\n method: '',\n from: from,\n contractAddress: this.address,\n })\n }\n\n // Wait for the transaction to be mined\n this.logger.debug(`Waiting for transaction to be mined... ${userOpHash}`)\n const txReceipt = await kernelClient.waitForUserOperationReceipt({\n hash: userOpHash,\n timeout: USEROP_RECEIPT_TIMEOUT_MS,\n })\n this.logger.debug(`Transaction mined - UserOperationHash: ${userOpHash}`)\n this.logger.debug(\n `Transaction receipt - TransactionHash: ${txReceipt.receipt.transactionHash}`,\n )\n this.assertUserOpSucceeded(txReceipt, 'multicall', userOpHash)\n return txReceipt.receipt\n } catch (err) {\n if (err instanceof BaseError) {\n const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError)\n this.logger.error(`revertError: ${String(revertError)}`)\n }\n // Surface userOpHash so callers can poll for eventual inclusion before\n // retrying — a client-side receipt-wait timeout does NOT cancel the userOp.\n const hashSuffix = userOpHash ? ` userOpHash=${userOpHash}` : ''\n throw new ContractsError(`Multicall failed:${hashSuffix} ${err}`)\n }\n }\n\n private assertUserOpSucceeded(\n txReceipt: UserOperationReceipt,\n method: string,\n userOpHash: string,\n ): void {\n if (txReceipt.success) return\n throw new ContractsError(\n `UserOp inner call reverted for \"${method}\" on \"${this.contractName}\". ` +\n `userOpHash=${userOpHash} txHash=${txReceipt.receipt.transactionHash} ` +\n `reason=${txReceipt.reason ?? 'unknown'}`,\n )\n }\n\n private async internalSendSmartAccount(\n name: string,\n from: SmartAccount,\n args: any[],\n txparams: any,\n progress: ((data: any) => void) | undefined,\n ): Promise<UserOperationReceipt> {\n const functionInputs = getInputsOfFunctionFormatted(this.contract.abi, name, args)\n\n const { gasLimit, value } = txparams\n if (progress) {\n progress({\n stage: 'sending',\n args: functionInputs,\n method: name,\n from: from,\n value,\n contractName: this.contractName,\n contractAddress: this.address,\n gasLimit,\n })\n }\n\n try {\n await this.client.public.simulateContract({\n address: this.address,\n abi: this.contract.abi,\n functionName: name,\n args,\n account: from,\n ...(txparams.value && { value: txparams.value }),\n })\n } catch (err) {\n if (err instanceof BaseError) {\n const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError)\n this.logger.error(`revertError: ${String(revertError)}`)\n }\n throw new ContractsError(\n `Calling method \"${name}\" on contract \"${this.contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n\n const kernelClient = createKernelAccountClient({\n account: from,\n chain: getChain(this.config.chainId),\n bundlerTransport: http(this.getBundlerRPC()),\n client: this.client.public,\n ...this.getPaymasterConfig(),\n userOperation: {\n estimateFeesPerGas: async ({ bundlerClient }) => {\n return estimateUserOperationFees(bundlerClient, this.client.public)\n },\n },\n })\n const data = encodeFunctionData({ abi: this.contract.abi, functionName: name, args })\n\n let userOpHash\n try {\n // Random nonce key per send so concurrent userOps from the same SCA\n // hit distinct EntryPoint nonce channels instead of colliding on the\n // default `customNonceKey=0n`. See issue #1579.\n const nonce = await from.getNonce({ key: getRandomBigInt(ZERODEV_NONCE_KEY_BITS) })\n const callData = await kernelClient.account.encodeCalls([\n {\n to: this.address,\n value: txparams.value || 0n,\n data,\n },\n ])\n\n // When a caller supplies a `progress` callback it may need the UserOp\n // hash BEFORE the send completes — the onchain-mirror worker races the\n // send against a per-tick deadline and must persist the hash even if the\n // send is cut off mid-flight, otherwise it resubmits and double-burns\n // (#1508/#1904). So prepare the UserOp here, surface its hash via\n // `progress({stage:'prepared'})`, and send that exact prepared op so the\n // bundler-returned hash matches. Best-effort and GATED ON `progress`:\n // any failure falls back to the normal send, and callers that pass no\n // progress callback keep the original send path byte-for-byte.\n let preparedUserOp: Awaited<ReturnType<typeof kernelClient.prepareUserOperation>> | undefined\n let preparedHash: `0x${string}` | undefined\n if (progress) {\n try {\n preparedUserOp = await kernelClient.prepareUserOperation({ callData, nonce })\n preparedHash = getUserOperationHash({\n chainId: this.config.chainId,\n entryPointAddress: from.entryPoint.address,\n entryPointVersion: from.entryPoint.version,\n userOperation: preparedUserOp,\n })\n progress({\n stage: 'prepared',\n args: functionInputs,\n userOpHash: preparedHash,\n method: name,\n from: from,\n value,\n contractName: this.contractName,\n contractAddress: this.address,\n gasLimit,\n })\n } catch (prepErr) {\n this.logger.warn(\n `prepareUserOperation (pre-send hash) failed for \"${name}\"; ` +\n `sending without an early hash: ${prepErr}`,\n )\n preparedUserOp = undefined\n preparedHash = undefined\n }\n }\n\n userOpHash = await kernelClient.sendUserOperation(\n // Re-send the exact prepared op (stripping the estimation stub\n // signature so the kernel re-signs) so the bundler hash matches the one\n // emitted above. Falls back to the original {callData, nonce} path\n // (which prepares internally) when no early hash was prepared.\n preparedUserOp\n ? ({ ...preparedUserOp, signature: undefined } as Parameters<\n typeof kernelClient.sendUserOperation\n >[0])\n : { callData, nonce },\n )\n\n // Determinism guard: the 'prepared' hash should equal the bundler's. If a\n // paymaster re-request changed the op it won't — a caller that persisted\n // the 'prepared' hash then just fails to find it and reconciles safely\n // (never a double-burn), but we log so we can see whether the early-hash\n // path is actually holding in practice.\n if (preparedHash && userOpHash !== preparedHash) {\n this.logger.warn(\n `UserOp 'prepared' hash ${preparedHash} != sent hash ${userOpHash} for \"${name}\"; ` +\n `early-hash callers will reconcile via receipt-not-found`,\n )\n }\n } catch (err) {\n if (err instanceof BaseError) {\n const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError)\n this.logger.error(`revertError: ${String(revertError)}`)\n }\n throw new ContractsError(\n `Calling method \"${name}\" on contract \"${this.contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n\n if (progress) {\n progress({\n stage: 'sent',\n args: functionInputs,\n userOpHash,\n method: name,\n from: from,\n value,\n contractName: this.contractName,\n contractAddress: this.address,\n gasLimit,\n })\n }\n\n let txReceipt: UserOperationReceipt\n try {\n txReceipt = await kernelClient.waitForUserOperationReceipt({\n hash: userOpHash,\n timeout: USEROP_RECEIPT_TIMEOUT_MS,\n })\n } catch (err) {\n // The userOp is already in the bundler mempool — a client-side timeout\n // does NOT cancel it. Surface userOpHash so callers can poll for eventual\n // inclusion before retrying, otherwise a retry can produce a duplicate\n // on-chain op. Wrap symmetric to `internalMulticallSmartAccount`.\n throw new ContractsError(\n `Calling method \"${name}\" on contract \"${this.contractName}\" timed out ` +\n `waiting for UserOp receipt. userOpHash=${userOpHash} — confirm on-chain ` +\n `inclusion before retrying. Underlying: ${err}`,\n )\n }\n\n this.assertUserOpSucceeded(txReceipt, name, userOpHash)\n\n if (progress) {\n progress({\n stage: 'receipt',\n args: functionInputs,\n txReceipt,\n method: name,\n from: from,\n value,\n contractName: this.contractName,\n contractAddress: this.address,\n gasLimit,\n })\n }\n\n return txReceipt\n }\n\n private async internalSimulateSmartAccount(\n name: string,\n from: SmartAccount,\n args: any[],\n txparams: any,\n ) {\n try {\n await this.client.public.simulateContract({\n address: this.address,\n abi: this.contract.abi,\n functionName: name,\n args,\n account: from.address,\n ...(txparams.value && { value: txparams.value }),\n })\n return true\n } catch (err) {\n throw new ContractSimulationError(\n `Error Simulating contract call \"${name}\" on contract \"${this.contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n }\n\n private async localAccountSimulate(\n name: string,\n from: Account | `0x${string}`,\n args: any[],\n txparams: any,\n ) {\n try {\n await this.client.public.simulateContract({\n address: this.address,\n abi: this.contract.abi,\n functionName: name,\n args,\n account: from,\n ...(txparams.value && { value: txparams.value }),\n })\n } catch (err) {\n throw new ContractSimulationError(\n `Error Simulating contract call \"${name}\" on contract \"${this.contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n return true\n }\n\n private async localAccountSend(\n name: string,\n from: Account | `0x${string}`,\n args: any[],\n txparams: any,\n progress: ((data: any) => void) | undefined,\n _contractAbi?: Abi,\n _contractAddress?: Address,\n _contractName?: string,\n ) {\n const abi = _contractAbi || this.contract.abi\n const contractAddress = _contractAddress || this.address\n const contractName = _contractName || this.contractName\n\n const functionInputs = getInputsOfFunctionFormatted(abi, name, args)\n // Uncomment to debug contract calls\n // if (name === 'order') {\n // const functionSignature = getSignatureOfFunction(this.contract.abi, name, args)\n // this.logger.info(`Making contract call ....: ${name} - ${from}`)\n // this.logger.info(`With args: `, JSON.stringify(args, jsonReplacer))\n // this.logger.info(`And signature: ${JSON.stringify(functionSignature, jsonReplacer)}`)\n // this.logger.info('And amount: ', txparams.value)\n // }\n // abi.filter(({name, inputs}) => name === 'closeSignals' && inputs.length === 1)\n // const abiFilter = this.contract.abi.filter((abi) => abi.name === name && abi.inputs.length === args.length)\n // const abiFilter = this.contract.abi.filter((abi) => abi.name === name && abi.type === 'function')\n // console.debug('abi', this.contract.abi.filter((abi) => abi.name === name))\n // console.debug('abiFilter', abiFilter)\n // if (!abiFilter)\n // throw new ContractsError(\n // `No ABI found for method \"${name}\" with ${args.length} arguments on contract \"${this.contractName}\"`,\n // )\n\n const { gasLimit, value } = txparams\n // make the call\n if (progress) {\n progress({\n stage: 'sending',\n args: functionInputs,\n method: name,\n from,\n value,\n contractName,\n contractAddress,\n gasLimit,\n })\n }\n\n let txHash: `0x${string}` | undefined\n try {\n const { request } = await this.client.public.simulateContract({\n address: contractAddress,\n abi,\n functionName: name,\n args,\n account: from,\n ...(txparams.value && { value: txparams.value }),\n })\n\n // Resolve gas ourselves so `writeContract` never falls back to its own\n // `eth_estimateGas`. An explicit caller `gasLimit` always wins; otherwise\n // we estimate, apply the block-limit sanity check, and pin the result.\n // If estimation itself fails we still honour any explicit cap.\n let resolvedGas: bigint | undefined = gasLimit\n if (resolvedGas === undefined) {\n try {\n const estimate = await this.client.public.estimateContractGas({\n address: contractAddress,\n abi,\n functionName: name,\n args,\n account: from,\n ...(txparams.value && { value: txparams.value }),\n })\n resolvedGas = capForBogusEstimate(estimate, this.logger)\n } catch (estErr) {\n this.logger.warn(\n `estimateContractGas for \"${name}\" on \"${contractName}\" failed (${estErr}); ` +\n `falling back to ${GAS_FALLBACK_CAP} to avoid a bogus RPC re-estimate in writeContract.`,\n )\n resolvedGas = GAS_FALLBACK_CAP\n }\n }\n\n txHash = await this.client.wallet.writeContract({\n ...request,\n account: from,\n gas: resolvedGas,\n })\n } catch (err) {\n if (err instanceof BaseError) {\n const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError)\n this.logger.error(`revertError: ${String(revertError)}`)\n }\n throw new ContractsError(\n `Calling method \"${name}\" on contract \"${contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n\n if (progress) {\n progress({\n stage: 'sent',\n args: functionInputs,\n txHash,\n method: name,\n from,\n value,\n contractName,\n contractAddress,\n gasLimit,\n })\n }\n const txReceipt = getTransactionReceipt({ txHash, publicClient: this.client.public })\n\n if (progress) {\n progress({\n stage: 'receipt',\n args: functionInputs,\n txReceipt,\n method: name,\n from,\n value,\n contractName,\n contractAddress,\n gasLimit,\n })\n }\n\n return txReceipt\n }\n\n private async localAccountMulticall(\n calls: MulticallEntry[],\n from: Account,\n txparams: any,\n progress: ((data: any) => void) | undefined,\n ): Promise<TransactionReceipt> {\n const receipts: TransactionReceipt[] = []\n for (const call of calls) {\n receipts.push(\n await this.localAccountSend(\n call.functionName,\n from,\n call.args,\n txparams,\n progress,\n call.abi,\n call.contractAddress,\n call.contractName,\n ),\n )\n }\n if (receipts.length > 0) return receipts.pop() as TransactionReceipt\n else throw new ContractsError(`No receipts found for multicall`)\n }\n\n private async localAccountSimulateMulticall(\n calls: SimulateMulticallEntry[],\n from: Account,\n txparams: any,\n ) {\n try {\n const { results } = await this.client.public.simulateCalls({\n calls,\n account: from,\n })\n this.logger.debug(`Simulated multicall - ${results}`)\n return true\n } catch (err) {\n if (err instanceof BaseError) {\n const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError)\n this.logger.error(`revertError: ${String(revertError)}`)\n }\n throw new ContractsError(`Error simulating multicall - ${err}`)\n }\n }\n\n private async internalSimulateMulticallSmartAccount(\n calls: SimulateMulticallEntry[],\n from: SmartAccount,\n txparams: any,\n ) {\n try {\n const kernelClient = createKernelAccountClient({\n account: from,\n chain: getChain(this.config.chainId),\n bundlerTransport: http(this.getBundlerRPC()),\n client: this.client.public,\n ...this.getPaymasterConfig(),\n userOperation: {\n estimateFeesPerGas: async ({ bundlerClient }) => {\n return estimateUserOperationFees(bundlerClient, this.client.public)\n },\n },\n })\n\n const encodedCalls = []\n for (const call of calls) {\n encodedCalls.push({\n to: call.to,\n value: call.value || 0n,\n data: encodeFunctionData({\n abi: call.abi,\n functionName: call.functionName,\n args: call.args,\n }),\n })\n }\n\n // DONT DELETE THE COMMENTED LINES - ARE NECESSARY FOR F***ING ZERODEV DEBUGGING\n\n // this.logger.info(`Encoded multicall - ${JSON.stringify(encodedCalls, jsonReplacer)}`)\n // const code = await this.client.public.getCode({ address: from.address })\n // const isDeployed = code !== undefined && code !== '0x'\n // this.logger.info(`++++++ Smart account ${from.address} deployment status: ${isDeployed ? 'DEPLOYED' : 'NOT DEPLOYED'}`)\n\n // // Log account details\n // this.logger.info(`Account type: ${from.type}`)\n // this.logger.info(`Account address: ${from.address}`)\n\n // // Log the calls being made\n // this.logger.info(`Number of calls: ${encodedCalls.length}`)\n // encodedCalls.forEach((call, index) => {\n // this.logger.info(`Call ${index}: to=${call.to}, value=${call.value}, data=${call.data.slice(0, 10)}...`)\n // })\n\n await kernelClient.prepareUserOperation({\n callData: await kernelClient.account.encodeCalls(encodedCalls),\n })\n\n return true\n } catch (err) {\n this.logger.error(`Error details: ${JSON.stringify(err, null, 2)}`)\n if (err instanceof BaseError) {\n const revertError = err.walk((e) => e instanceof ContractFunctionRevertedError)\n if (revertError) {\n this.logger.error(`Revert error: ${String(revertError)}`)\n }\n }\n throw new ContractSimulationError(`Error Simulating Multicalls - ${err}`)\n }\n }\n\n private getOrCreatePaymaster() {\n if (!this._zeroDevPaymaster) {\n this._zeroDevPaymaster = createZeroDevPaymasterClient({\n chain: getChain(this.config.chainId),\n transport: http(this.getPaymasterRPC()),\n })\n }\n return this._zeroDevPaymaster\n }\n\n /**\n * Builds the `paymaster` partial for `createKernelAccountClient`. In relayer\n * mode (e.g. local `ultra-relay` for tests) returns an empty object so the\n * kernel client submits UserOps without paymaster fields and the bundler\n * pays gas via its executor key. In production returns the ZeroDev paymaster\n * sponsorship callback.\n */\n private getPaymasterConfig() {\n if (isRelayerMode()) return {}\n const zerodevPaymaster = this.getOrCreatePaymaster()\n return {\n paymaster: {\n getPaymasterData: (userOperation: any) =>\n zerodevPaymaster.sponsorUserOperation({\n userOperation: applyTempoVerificationGasFloor(userOperation, this.config.chainId),\n }),\n },\n }\n }\n\n protected getBundlerRPC(): string {\n // In relayer mode `getBundlerRpcUrl` reads `BUNDLER_RPC_URL_OVERRIDE`\n // and never touches the project id, so an empty value is harmless. In\n // production callers must pass a project id — surface a clear error if\n // the SDK was instantiated without one and we need it.\n const projectId = this.config.zeroDevProjectId\n if (!projectId && !isRelayerMode()) {\n throw new ContractsError(\n 'getBundlerRPC: zeroDevProjectId is required for non-relayer (production) mode',\n )\n }\n return getBundlerRpcUrl(projectId ?? '', this.config.chainId, this.config.useUltraRelay)\n }\n\n private getPaymasterRPC(): string {\n // Only ever consulted when `getPaymasterConfig` decides to attach a\n // paymaster, which is gated on `!isRelayerMode()`. A missing project\n // id at this point is a configuration bug worth surfacing.\n const projectId = this.config.zeroDevProjectId\n if (!projectId) {\n throw new ContractsError(\n 'getPaymasterRPC: zeroDevProjectId is required to build the paymaster URL',\n )\n }\n return getPaymasterRpcUrl(projectId, this.config.chainId)\n }\n}\n"],"names":["createKernelAccountClient","createZeroDevPaymasterClient","applyTempoVerificationGasFloor","estimateUserOperationFees","getBundlerRpcUrl","getPaymasterRpcUrl","isRelayerMode","BaseError","ContractFunctionRevertedError","encodeFunctionData","getContract","http","parseAbi","parseEventLogs","createBundlerClient","getUserOperationHash","ContractsError","ContractSimulationError","Instantiable","getInputsOfFunctionFormatted","getTransactionReceipt","getRandomBigInt","getChain","GAS_SANITY_THRESHOLD","GAS_FALLBACK_CAP","ZERODEV_NONCE_KEY_BITS","USEROP_RECEIPT_TIMEOUT_MS","capForBogusEstimate","estimatedGas","logger","warn","ContractBase","contractName","address","_zeroDevPaymaster","init","config","contractConfig","setInstanceConfig","contract","abi","client","public","publicClient","wallet","walletClient","call","functionName","args","from","readContract","account","err","txHash","hash","receipt","transactionHash","Error","getTransactionLogs","txReceipt","eventName","logs","strict","multicall","calls","params","type","debug","localAccountMulticall","progress","internalMulticallSmartAccount","simulateMulticall","localAccountSimulateMulticall","internalSimulateMulticallSmartAccount","simulate","localAccountSimulate","internalSimulateSmartAccount","send","localAccountSend","internalSendSmartAccount","getUserOperationReceipt","bundlerClient","chain","chainId","transport","getBundlerRPC","message","String","test","safeMessage","replace","txparams","stage","method","contractAddress","kernelClient","bundlerTransport","getPaymasterConfig","userOperation","estimateFeesPerGas","encodedCalls","map","push","to","value","data","userOpHash","nonce","getNonce","key","sendUserOperation","callData","encodeCalls","waitForUserOperationReceipt","timeout","assertUserOpSucceeded","revertError","walk","error","hashSuffix","success","reason","name","functionInputs","gasLimit","simulateContract","preparedUserOp","preparedHash","prepareUserOperation","entryPointAddress","entryPoint","entryPointVersion","version","prepErr","undefined","signature","_contractAbi","_contractAddress","_contractName","request","resolvedGas","estimate","estimateContractGas","estErr","writeContract","gas","receipts","length","pop","results","simulateCalls","JSON","stringify","e","getOrCreatePaymaster","getPaymasterRPC","zerodevPaymaster","paymaster","getPaymasterData","sponsorUserOperation","projectId","zeroDevProjectId","useUltraRelay"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/contracts/ContractBase.ts"],"sourcesContent":["import { createKernelAccountClient, createZeroDevPaymasterClient } from '@zerodev/sdk'\nimport {\n estimateUserOperationFees,\n getBundlerRpcUrl,\n getPaymasterRpcUrl,\n isRelayerMode,\n} from '../nevermined/utils/BlockchainViemUtils.js'\nimport {\n Abi,\n Account,\n Address,\n BaseError,\n ContractFunctionRevertedError,\n encodeFunctionData,\n getContract,\n http,\n parseAbi,\n parseEventLogs,\n TransactionReceipt,\n} from 'viem'\nimport {\n createBundlerClient,\n getUserOperationHash,\n SmartAccount,\n UserOperationReceipt,\n} from 'viem/account-abstraction'\nimport { ContractsError, ContractSimulationError } from '../errors/index.js'\nimport { Instantiable, InstantiableConfig } from '../Instantiable.abstract.js'\nimport { TxParameters } from '../models/Transactions.js'\nimport { getInputsOfFunctionFormatted, getTransactionReceipt } from '../nevermined/index.js'\nimport { getRandomBigInt } from '../utils/helpers.js'\nimport { getChain } from '../utils/Network.js'\n\nexport interface MulticallEntry {\n contractName?: string\n contractAddress: Address\n abi: Abi\n functionName: string\n args: any[]\n}\n\n/**\n * When a testnet RPC (Base Sepolia) fails internally, some providers return\n * `eth_estimateGas` values equal to — or even above — the block gas limit\n * instead of a real error. Using that value causes the node to reject the tx\n * with `intrinsic gas too high` before it ever reaches the mempool.\n *\n * `writeContract` in viem re-estimates gas internally when `gas` isn't\n * already set on the request (viem's `simulateContract` only performs\n * `eth_call`, not `eth_estimateGas`). That means the naïve path has no\n * chance to intercept a bogus estimate. We run the estimation ourselves\n * here, sanity-check the result, and always pass an explicit gas value\n * into `writeContract` so it doesn't re-query the misbehaving RPC.\n */\nconst GAS_SANITY_THRESHOLD = 25_000_000n\nconst GAS_FALLBACK_CAP = 5_000_000n\n\n// EntryPoint v0.7: ZeroDev's `toKernelPluginManager` rejects `customNonceKey > maxUint16`.\n// 16 bits = 65 536 channels — collision probability for the SDK's expected concurrency\n// (k=2–5 parallel sends from one SCA) is negligible (< 0.02 %). High-fan-out callers\n// (k > 50) should consider a per-process monotonic counter instead. See issue #1579.\nconst ZERODEV_NONCE_KEY_BITS = 16\n\n// Client-side cap on `waitForUserOperationReceipt`. The userOp is already in the bundler\n// mempool when this fires — a client-side timeout does NOT cancel it. Callers that catch\n// the resulting `ContractsError` MUST poll `bundlerClient.getUserOperationReceipt(hash)`\n// before retrying; otherwise a retry can produce a duplicate on-chain op.\nconst USEROP_RECEIPT_TIMEOUT_MS = 90_000\n\nfunction capForBogusEstimate(\n estimatedGas: bigint,\n logger: { warn: (msg: string) => void },\n): bigint {\n if (estimatedGas < GAS_SANITY_THRESHOLD) return estimatedGas\n logger.warn(\n `Estimated gas (${estimatedGas}) exceeds sanity threshold ` +\n `(${GAS_SANITY_THRESHOLD}); overriding with ${GAS_FALLBACK_CAP} to bypass misbehaving RPC estimate.`,\n )\n return GAS_FALLBACK_CAP\n}\n\nexport interface SimulateMulticallEntry {\n functionName: string\n value?: bigint\n abi: Abi\n args: any[]\n to: Address\n}\n\nexport abstract class ContractBase extends Instantiable {\n public readonly contractName: string\n public contract: any\n public address: Address\n private _zeroDevPaymaster: ReturnType<typeof createZeroDevPaymasterClient> | null = null\n\n constructor(contractName: string, address: Address) {\n super()\n this.contractName = contractName\n this.address = address\n }\n\n protected async init(\n config: InstantiableConfig,\n contractConfig: { address: `0x${string}`; abi: Abi },\n ) {\n this.setInstanceConfig(config)\n this.address = contractConfig.address\n\n this.contract = getContract({\n address: contractConfig.address,\n abi: contractConfig.abi,\n client: { public: this.publicClient, wallet: this.walletClient },\n })\n }\n\n public async call<T>(functionName: string, args: any[], from?: string): Promise<T> {\n try {\n return (await this.client.public.readContract({\n address: this.address,\n abi: this.contract.abi,\n functionName: parseAbi([functionName]),\n args,\n ...(from && { account: from as `0x${string}` }),\n })) as T\n //return await this.contract[functionSignature](...args, { from })\n } catch (err) {\n throw new ContractsError(\n `Calling method \"${functionName}\" on contract \"${this.contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n }\n\n public async getTransactionReceipt(\n txHash: UserOperationReceipt | TransactionReceipt,\n ): Promise<TransactionReceipt> {\n // Get the transaction receipt depending on the type of txHash\n if ('transactionHash' in txHash) {\n // txHash is TransactionReceipt\n return txHash\n } else if ('userOpHash' in txHash) {\n // txHash is UserOperationReceipt, fetch the actual receipt using the utility function with retry logic\n const hash = txHash.receipt.transactionHash\n return await getTransactionReceipt({\n txHash: hash,\n publicClient: this.client.public,\n })\n } else {\n throw new Error('Unknown transaction type')\n }\n }\n\n public getTransactionLogs(\n txReceipt: TransactionReceipt | UserOperationReceipt,\n eventName?: string,\n ) {\n return parseEventLogs({\n abi: this.contract.abi,\n logs: txReceipt.logs,\n eventName,\n strict: false,\n }) as any[]\n }\n\n public async multicall(\n calls: MulticallEntry[],\n from: Account | SmartAccount,\n params: TxParameters = {},\n ) {\n if (from.type === 'local') {\n this.logger.debug(`Blockchain Multicall using Local account`)\n return await this.localAccountMulticall(calls, from, params, params.progress)\n } else if (from.type === 'json-rpc') {\n this.logger.debug(`Blockchain Multicall using JSON-RPC account`)\n return await this.localAccountMulticall(calls, from, params, params.progress)\n } else if (from.type === 'smart') {\n this.logger.debug(`Blockchain Multicall using ZeroDev account`)\n return await this.internalMulticallSmartAccount(calls, from, params, params.progress)\n } else {\n throw new ContractsError(`Account not supported`)\n }\n }\n\n public async simulateMulticall(\n calls: SimulateMulticallEntry[],\n from: Account | SmartAccount,\n params: TxParameters = {},\n ) {\n if (from.type === 'local') {\n this.logger.debug(`Simulating calls using Local account`)\n return await this.localAccountSimulateMulticall(calls, from, params)\n } else if (from.type === 'json-rpc') {\n this.logger.debug(`Simulating calls using JSON-RPC account`)\n return await this.localAccountSimulateMulticall(calls, from, params)\n } else if (from.type === 'smart') {\n this.logger.debug(`Simulating calls using Smart Account account`)\n return await this.internalSimulateMulticallSmartAccount(calls, from, params)\n } else {\n throw new ContractsError(`Account not supported`)\n }\n }\n\n public async simulate(\n functionName: string,\n from: Account | SmartAccount,\n args: any[],\n params: TxParameters = {},\n ) {\n if (from.type === 'local') {\n this.logger.debug(`Simulating calls using Local account`)\n return await this.localAccountSimulate(functionName, from, args, params)\n } else if (from.type === 'json-rpc') {\n this.logger.debug(`Simulating calls using JSON-RPC account`)\n return await this.localAccountSimulate(functionName, from, args, params)\n } else if (from.type === 'smart') {\n this.logger.debug(`Simulating calls using Smart Account account`)\n return await this.internalSimulateSmartAccount(functionName, from, args, params)\n } else {\n throw new ContractsError(`Account not supported`)\n }\n }\n\n public async send(\n functionName: string,\n from: Account | SmartAccount,\n args: any[],\n params: TxParameters = {},\n ): Promise<TransactionReceipt | UserOperationReceipt> {\n if (from.type === 'local') {\n this.logger.debug(\n `Blockchain Send using Local account with functionName: ${functionName} and following args: ${args}`,\n )\n return await this.localAccountSend(functionName, from, args, params, params.progress)\n } else if (from.type === 'json-rpc') {\n this.logger.debug(`Blockchain Send using JSON-RPC account to ${functionName}`)\n return await this.localAccountSend(functionName, from, args, params, params.progress)\n } else if (from.type === 'smart') {\n this.logger.debug(`Blockchain Send using ZeroDev account`)\n return await this.internalSendSmartAccount(functionName, from, args, params, params.progress)\n } else {\n throw new ContractsError(`Account not supported`)\n }\n }\n\n /**\n * Poll a previously-submitted UserOperation's receipt by hash WITHOUT\n * blocking. Returns the receipt once the bundler has mined it, or `null`\n * while it is still in the mempool / not yet known. A client-side\n * receipt-wait timeout does NOT cancel a submitted UserOp, so callers that\n * persist the hash (e.g. the onchain-mirror worker, nvm-monorepo#1508) use\n * this to confirm a prior submission instead of resubmitting a duplicate.\n */\n public async getUserOperationReceipt(hash: `0x${string}`): Promise<UserOperationReceipt | null> {\n try {\n const bundlerClient = createBundlerClient({\n chain: getChain(this.config.chainId),\n transport: http(this.getBundlerRPC()),\n client: this.client.public,\n })\n return (await bundlerClient.getUserOperationReceipt({ hash })) ?? null\n } catch (err) {\n // A genuinely-absent receipt (UserOp still in the mempool) is expected\n // and benign — some bundlers signal it by throwing rather than returning\n // null. Anything else (RPC/transport/config fault) must NOT masquerade as\n // \"still pending\": surface it at `warn` so a bundler outage is visible\n // instead of silently driving the caller's grace-window logic. Either\n // way we return null so the caller re-polls rather than consuming a retry.\n const message = err instanceof Error ? err.message : String(err)\n if (/not[\\s_]?found|UserOperationReceiptNotFound/i.test(message)) {\n this.logger.debug(`getUserOperationReceipt(${hash}): not yet mined`)\n } else {\n // Redact URLs before logging: the bundler RPC URL embeds the ZeroDev\n // project id, which should not leak into logs.\n const safeMessage = message.replace(/https?:\\/\\/[^\\s'\")]+/gi, '<redacted-url>')\n this.logger.warn(\n `getUserOperationReceipt(${hash}) lookup error (treating as not-yet-mined): ${safeMessage}`,\n )\n }\n return null\n }\n }\n\n private async internalMulticallSmartAccount(\n calls: MulticallEntry[],\n from: SmartAccount,\n txparams: any,\n progress: ((data: any) => void) | undefined,\n ) {\n if (progress) {\n progress({\n stage: 'multicall-sending',\n args: [],\n method: '',\n from: from,\n contractAddress: this.address,\n })\n }\n\n const kernelClient = createKernelAccountClient({\n account: from,\n chain: getChain(this.config.chainId),\n bundlerTransport: http(this.getBundlerRPC()),\n client: this.client.public,\n ...this.getPaymasterConfig(),\n userOperation: {\n estimateFeesPerGas: async ({ bundlerClient }) => {\n return estimateUserOperationFees(bundlerClient, this.client.public)\n },\n },\n })\n\n const encodedCalls: any[] = []\n calls.map((call) => {\n encodedCalls.push({\n to: call.contractAddress || this.address,\n value: txparams.value || 0n,\n data: encodeFunctionData({\n abi: call.abi,\n functionName: call.functionName,\n args: call.args,\n }),\n })\n })\n\n let userOpHash: `0x${string}` | undefined\n try {\n // Random nonce key per send so concurrent userOps from the same SCA\n // hit distinct EntryPoint nonce channels instead of colliding on the\n // default `customNonceKey=0n`. See issue #1579.\n const nonce = await from.getNonce({ key: getRandomBigInt(ZERODEV_NONCE_KEY_BITS) })\n userOpHash = await kernelClient.sendUserOperation({\n callData: await kernelClient.account.encodeCalls(encodedCalls),\n nonce,\n })\n\n if (progress) {\n progress({\n stage: 'multicall-sent',\n args: [],\n method: '',\n from: from,\n contractAddress: this.address,\n })\n }\n\n // Wait for the transaction to be mined\n this.logger.debug(`Waiting for transaction to be mined... ${userOpHash}`)\n const txReceipt = await kernelClient.waitForUserOperationReceipt({\n hash: userOpHash,\n timeout: USEROP_RECEIPT_TIMEOUT_MS,\n })\n this.logger.debug(`Transaction mined - UserOperationHash: ${userOpHash}`)\n this.logger.debug(\n `Transaction receipt - TransactionHash: ${txReceipt.receipt.transactionHash}`,\n )\n this.assertUserOpSucceeded(txReceipt, 'multicall', userOpHash)\n return txReceipt.receipt\n } catch (err) {\n if (err instanceof BaseError) {\n const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError)\n this.logger.error(`revertError: ${String(revertError)}`)\n }\n // Surface userOpHash so callers can poll for eventual inclusion before\n // retrying — a client-side receipt-wait timeout does NOT cancel the userOp.\n const hashSuffix = userOpHash ? ` userOpHash=${userOpHash}` : ''\n throw new ContractsError(`Multicall failed:${hashSuffix} ${err}`)\n }\n }\n\n private assertUserOpSucceeded(\n txReceipt: UserOperationReceipt,\n method: string,\n userOpHash: string,\n ): void {\n if (txReceipt.success) return\n throw new ContractsError(\n `UserOp inner call reverted for \"${method}\" on \"${this.contractName}\". ` +\n `userOpHash=${userOpHash} txHash=${txReceipt.receipt.transactionHash} ` +\n `reason=${txReceipt.reason ?? 'unknown'}`,\n )\n }\n\n private async internalSendSmartAccount(\n name: string,\n from: SmartAccount,\n args: any[],\n txparams: any,\n progress: ((data: any) => void) | undefined,\n ): Promise<UserOperationReceipt> {\n const functionInputs = getInputsOfFunctionFormatted(this.contract.abi, name, args)\n\n const { gasLimit, value } = txparams\n if (progress) {\n progress({\n stage: 'sending',\n args: functionInputs,\n method: name,\n from: from,\n value,\n contractName: this.contractName,\n contractAddress: this.address,\n gasLimit,\n })\n }\n\n try {\n await this.client.public.simulateContract({\n address: this.address,\n abi: this.contract.abi,\n functionName: name,\n args,\n account: from,\n ...(txparams.value && { value: txparams.value }),\n })\n } catch (err) {\n if (err instanceof BaseError) {\n const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError)\n this.logger.error(`revertError: ${String(revertError)}`)\n }\n throw new ContractsError(\n `Calling method \"${name}\" on contract \"${this.contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n\n const kernelClient = createKernelAccountClient({\n account: from,\n chain: getChain(this.config.chainId),\n bundlerTransport: http(this.getBundlerRPC()),\n client: this.client.public,\n ...this.getPaymasterConfig(),\n userOperation: {\n estimateFeesPerGas: async ({ bundlerClient }) => {\n return estimateUserOperationFees(bundlerClient, this.client.public)\n },\n },\n })\n const data = encodeFunctionData({ abi: this.contract.abi, functionName: name, args })\n\n let userOpHash\n try {\n // Random nonce key per send so concurrent userOps from the same SCA\n // hit distinct EntryPoint nonce channels instead of colliding on the\n // default `customNonceKey=0n`. See issue #1579.\n const nonce = await from.getNonce({ key: getRandomBigInt(ZERODEV_NONCE_KEY_BITS) })\n const callData = await kernelClient.account.encodeCalls([\n {\n to: this.address,\n value: txparams.value || 0n,\n data,\n },\n ])\n\n // When a caller supplies a `progress` callback it may need the UserOp\n // hash BEFORE the send completes — the onchain-mirror worker races the\n // send against a per-tick deadline and must persist the hash even if the\n // send is cut off mid-flight, otherwise it resubmits and double-burns\n // (#1508/#1904). So prepare the UserOp here, surface its hash via\n // `progress({stage:'prepared'})`, and send that exact prepared op so the\n // bundler-returned hash matches. Best-effort and GATED ON `progress`:\n // any failure falls back to the normal send, and callers that pass no\n // progress callback keep the original send path byte-for-byte.\n let preparedUserOp: Awaited<ReturnType<typeof kernelClient.prepareUserOperation>> | undefined\n let preparedHash: `0x${string}` | undefined\n if (progress) {\n try {\n preparedUserOp = await kernelClient.prepareUserOperation({ callData, nonce })\n preparedHash = getUserOperationHash({\n chainId: this.config.chainId,\n entryPointAddress: from.entryPoint.address,\n entryPointVersion: from.entryPoint.version,\n userOperation: preparedUserOp,\n })\n progress({\n stage: 'prepared',\n args: functionInputs,\n userOpHash: preparedHash,\n method: name,\n from: from,\n value,\n contractName: this.contractName,\n contractAddress: this.address,\n gasLimit,\n })\n } catch (prepErr) {\n this.logger.warn(\n `prepareUserOperation (pre-send hash) failed for \"${name}\"; ` +\n `sending without an early hash: ${prepErr}`,\n )\n preparedUserOp = undefined\n preparedHash = undefined\n }\n }\n\n userOpHash = await kernelClient.sendUserOperation(\n // Re-send the exact prepared op (stripping the estimation stub\n // signature so the kernel re-signs) so the bundler hash matches the one\n // emitted above. Falls back to the original {callData, nonce} path\n // (which prepares internally) when no early hash was prepared.\n preparedUserOp\n ? ({ ...preparedUserOp, signature: undefined } as Parameters<\n typeof kernelClient.sendUserOperation\n >[0])\n : { callData, nonce },\n )\n\n // Determinism guard: the 'prepared' hash should equal the bundler's. If a\n // paymaster re-request changed the op it won't — a caller that persisted\n // the 'prepared' hash then just fails to find it and reconciles safely\n // (never a double-burn), but we log so we can see whether the early-hash\n // path is actually holding in practice.\n if (preparedHash && userOpHash !== preparedHash) {\n this.logger.warn(\n `UserOp 'prepared' hash ${preparedHash} != sent hash ${userOpHash} for \"${name}\"; ` +\n `early-hash callers will reconcile via receipt-not-found`,\n )\n }\n } catch (err) {\n if (err instanceof BaseError) {\n const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError)\n this.logger.error(`revertError: ${String(revertError)}`)\n }\n throw new ContractsError(\n `Calling method \"${name}\" on contract \"${this.contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n\n if (progress) {\n progress({\n stage: 'sent',\n args: functionInputs,\n userOpHash,\n method: name,\n from: from,\n value,\n contractName: this.contractName,\n contractAddress: this.address,\n gasLimit,\n })\n }\n\n let txReceipt: UserOperationReceipt\n try {\n txReceipt = await kernelClient.waitForUserOperationReceipt({\n hash: userOpHash,\n timeout: USEROP_RECEIPT_TIMEOUT_MS,\n })\n } catch (err) {\n // The userOp is already in the bundler mempool — a client-side timeout\n // does NOT cancel it. Surface userOpHash so callers can poll for eventual\n // inclusion before retrying, otherwise a retry can produce a duplicate\n // on-chain op. Wrap symmetric to `internalMulticallSmartAccount`.\n throw new ContractsError(\n `Calling method \"${name}\" on contract \"${this.contractName}\" timed out ` +\n `waiting for UserOp receipt. userOpHash=${userOpHash} — confirm on-chain ` +\n `inclusion before retrying. Underlying: ${err}`,\n )\n }\n\n this.assertUserOpSucceeded(txReceipt, name, userOpHash)\n\n if (progress) {\n progress({\n stage: 'receipt',\n args: functionInputs,\n txReceipt,\n method: name,\n from: from,\n value,\n contractName: this.contractName,\n contractAddress: this.address,\n gasLimit,\n })\n }\n\n return txReceipt\n }\n\n private async internalSimulateSmartAccount(\n name: string,\n from: SmartAccount,\n args: any[],\n txparams: any,\n ) {\n try {\n await this.client.public.simulateContract({\n address: this.address,\n abi: this.contract.abi,\n functionName: name,\n args,\n account: from.address,\n ...(txparams.value && { value: txparams.value }),\n })\n return true\n } catch (err) {\n throw new ContractSimulationError(\n `Error Simulating contract call \"${name}\" on contract \"${this.contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n }\n\n private async localAccountSimulate(\n name: string,\n from: Account | `0x${string}`,\n args: any[],\n txparams: any,\n ) {\n try {\n await this.client.public.simulateContract({\n address: this.address,\n abi: this.contract.abi,\n functionName: name,\n args,\n account: from,\n ...(txparams.value && { value: txparams.value }),\n })\n } catch (err) {\n throw new ContractSimulationError(\n `Error Simulating contract call \"${name}\" on contract \"${this.contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n return true\n }\n\n private async localAccountSend(\n name: string,\n from: Account | `0x${string}`,\n args: any[],\n txparams: any,\n progress: ((data: any) => void) | undefined,\n _contractAbi?: Abi,\n _contractAddress?: Address,\n _contractName?: string,\n ) {\n const abi = _contractAbi || this.contract.abi\n const contractAddress = _contractAddress || this.address\n const contractName = _contractName || this.contractName\n\n const functionInputs = getInputsOfFunctionFormatted(abi, name, args)\n // Uncomment to debug contract calls\n // if (name === 'order') {\n // const functionSignature = getSignatureOfFunction(this.contract.abi, name, args)\n // this.logger.info(`Making contract call ....: ${name} - ${from}`)\n // this.logger.info(`With args: `, JSON.stringify(args, jsonReplacer))\n // this.logger.info(`And signature: ${JSON.stringify(functionSignature, jsonReplacer)}`)\n // this.logger.info('And amount: ', txparams.value)\n // }\n // abi.filter(({name, inputs}) => name === 'closeSignals' && inputs.length === 1)\n // const abiFilter = this.contract.abi.filter((abi) => abi.name === name && abi.inputs.length === args.length)\n // const abiFilter = this.contract.abi.filter((abi) => abi.name === name && abi.type === 'function')\n // console.debug('abi', this.contract.abi.filter((abi) => abi.name === name))\n // console.debug('abiFilter', abiFilter)\n // if (!abiFilter)\n // throw new ContractsError(\n // `No ABI found for method \"${name}\" with ${args.length} arguments on contract \"${this.contractName}\"`,\n // )\n\n const { gasLimit, value } = txparams\n // make the call\n if (progress) {\n progress({\n stage: 'sending',\n args: functionInputs,\n method: name,\n from,\n value,\n contractName,\n contractAddress,\n gasLimit,\n })\n }\n\n let txHash: `0x${string}` | undefined\n try {\n const { request } = await this.client.public.simulateContract({\n address: contractAddress,\n abi,\n functionName: name,\n args,\n account: from,\n ...(txparams.value && { value: txparams.value }),\n })\n\n // Resolve gas ourselves so `writeContract` never falls back to its own\n // `eth_estimateGas`. An explicit caller `gasLimit` always wins; otherwise\n // we estimate, apply the block-limit sanity check, and pin the result.\n // If estimation itself fails we still honour any explicit cap.\n let resolvedGas: bigint | undefined = gasLimit\n if (resolvedGas === undefined) {\n try {\n const estimate = await this.client.public.estimateContractGas({\n address: contractAddress,\n abi,\n functionName: name,\n args,\n account: from,\n ...(txparams.value && { value: txparams.value }),\n })\n resolvedGas = capForBogusEstimate(estimate, this.logger)\n } catch (estErr) {\n this.logger.warn(\n `estimateContractGas for \"${name}\" on \"${contractName}\" failed (${estErr}); ` +\n `falling back to ${GAS_FALLBACK_CAP} to avoid a bogus RPC re-estimate in writeContract.`,\n )\n resolvedGas = GAS_FALLBACK_CAP\n }\n }\n\n txHash = await this.client.wallet.writeContract({\n ...request,\n account: from,\n gas: resolvedGas,\n })\n } catch (err) {\n if (err instanceof BaseError) {\n const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError)\n this.logger.error(`revertError: ${String(revertError)}`)\n }\n throw new ContractsError(\n `Calling method \"${name}\" on contract \"${contractName}\" failed. Args: ${args} - ${err}`,\n )\n }\n\n if (progress) {\n progress({\n stage: 'sent',\n args: functionInputs,\n txHash,\n method: name,\n from,\n value,\n contractName,\n contractAddress,\n gasLimit,\n })\n }\n const txReceipt = getTransactionReceipt({ txHash, publicClient: this.client.public })\n\n if (progress) {\n progress({\n stage: 'receipt',\n args: functionInputs,\n txReceipt,\n method: name,\n from,\n value,\n contractName,\n contractAddress,\n gasLimit,\n })\n }\n\n return txReceipt\n }\n\n private async localAccountMulticall(\n calls: MulticallEntry[],\n from: Account,\n txparams: any,\n progress: ((data: any) => void) | undefined,\n ): Promise<TransactionReceipt> {\n const receipts: TransactionReceipt[] = []\n for (const call of calls) {\n receipts.push(\n await this.localAccountSend(\n call.functionName,\n from,\n call.args,\n txparams,\n progress,\n call.abi,\n call.contractAddress,\n call.contractName,\n ),\n )\n }\n if (receipts.length > 0) return receipts.pop() as TransactionReceipt\n else throw new ContractsError(`No receipts found for multicall`)\n }\n\n private async localAccountSimulateMulticall(\n calls: SimulateMulticallEntry[],\n from: Account,\n txparams: any,\n ) {\n try {\n const { results } = await this.client.public.simulateCalls({\n calls,\n account: from,\n })\n this.logger.debug(`Simulated multicall - ${results}`)\n return true\n } catch (err) {\n if (err instanceof BaseError) {\n const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError)\n this.logger.error(`revertError: ${String(revertError)}`)\n }\n throw new ContractsError(`Error simulating multicall - ${err}`)\n }\n }\n\n private async internalSimulateMulticallSmartAccount(\n calls: SimulateMulticallEntry[],\n from: SmartAccount,\n txparams: any,\n ) {\n try {\n const kernelClient = createKernelAccountClient({\n account: from,\n chain: getChain(this.config.chainId),\n bundlerTransport: http(this.getBundlerRPC()),\n client: this.client.public,\n ...this.getPaymasterConfig(),\n userOperation: {\n estimateFeesPerGas: async ({ bundlerClient }) => {\n return estimateUserOperationFees(bundlerClient, this.client.public)\n },\n },\n })\n\n const encodedCalls = []\n for (const call of calls) {\n encodedCalls.push({\n to: call.to,\n value: call.value || 0n,\n data: encodeFunctionData({\n abi: call.abi,\n functionName: call.functionName,\n args: call.args,\n }),\n })\n }\n\n // DONT DELETE THE COMMENTED LINES - ARE NECESSARY FOR F***ING ZERODEV DEBUGGING\n\n // this.logger.info(`Encoded multicall - ${JSON.stringify(encodedCalls, jsonReplacer)}`)\n // const code = await this.client.public.getCode({ address: from.address })\n // const isDeployed = code !== undefined && code !== '0x'\n // this.logger.info(`++++++ Smart account ${from.address} deployment status: ${isDeployed ? 'DEPLOYED' : 'NOT DEPLOYED'}`)\n\n // // Log account details\n // this.logger.info(`Account type: ${from.type}`)\n // this.logger.info(`Account address: ${from.address}`)\n\n // // Log the calls being made\n // this.logger.info(`Number of calls: ${encodedCalls.length}`)\n // encodedCalls.forEach((call, index) => {\n // this.logger.info(`Call ${index}: to=${call.to}, value=${call.value}, data=${call.data.slice(0, 10)}...`)\n // })\n\n await kernelClient.prepareUserOperation({\n callData: await kernelClient.account.encodeCalls(encodedCalls),\n })\n\n return true\n } catch (err) {\n this.logger.error(`Error details: ${JSON.stringify(err, null, 2)}`)\n if (err instanceof BaseError) {\n const revertError = err.walk((e) => e instanceof ContractFunctionRevertedError)\n if (revertError) {\n this.logger.error(`Revert error: ${String(revertError)}`)\n }\n }\n throw new ContractSimulationError(`Error Simulating Multicalls - ${err}`)\n }\n }\n\n private getOrCreatePaymaster() {\n if (!this._zeroDevPaymaster) {\n this._zeroDevPaymaster = createZeroDevPaymasterClient({\n chain: getChain(this.config.chainId),\n transport: http(this.getPaymasterRPC()),\n })\n }\n return this._zeroDevPaymaster\n }\n\n /**\n * Builds the `paymaster` partial for `createKernelAccountClient`. In relayer\n * mode (e.g. local `ultra-relay` for tests) returns an empty object so the\n * kernel client submits UserOps without paymaster fields and the bundler\n * pays gas via its executor key. In production returns the ZeroDev paymaster\n * sponsorship callback.\n */\n private getPaymasterConfig() {\n if (isRelayerMode()) return {}\n const zerodevPaymaster = this.getOrCreatePaymaster()\n return {\n paymaster: {\n getPaymasterData: (userOperation: any) =>\n zerodevPaymaster.sponsorUserOperation({ userOperation }),\n },\n }\n }\n\n protected getBundlerRPC(): string {\n // In relayer mode `getBundlerRpcUrl` reads `BUNDLER_RPC_URL_OVERRIDE`\n // and never touches the project id, so an empty value is harmless. In\n // production callers must pass a project id — surface a clear error if\n // the SDK was instantiated without one and we need it.\n const projectId = this.config.zeroDevProjectId\n if (!projectId && !isRelayerMode()) {\n throw new ContractsError(\n 'getBundlerRPC: zeroDevProjectId is required for non-relayer (production) mode',\n )\n }\n return getBundlerRpcUrl(projectId ?? '', this.config.chainId, this.config.useUltraRelay)\n }\n\n private getPaymasterRPC(): string {\n // Only ever consulted when `getPaymasterConfig` decides to attach a\n // paymaster, which is gated on `!isRelayerMode()`. A missing project\n // id at this point is a configuration bug worth surfacing.\n const projectId = this.config.zeroDevProjectId\n if (!projectId) {\n throw new ContractsError(\n 'getPaymasterRPC: zeroDevProjectId is required to build the paymaster URL',\n )\n }\n return getPaymasterRpcUrl(projectId, this.config.chainId)\n }\n}\n"],"names":["createKernelAccountClient","createZeroDevPaymasterClient","estimateUserOperationFees","getBundlerRpcUrl","getPaymasterRpcUrl","isRelayerMode","BaseError","ContractFunctionRevertedError","encodeFunctionData","getContract","http","parseAbi","parseEventLogs","createBundlerClient","getUserOperationHash","ContractsError","ContractSimulationError","Instantiable","getInputsOfFunctionFormatted","getTransactionReceipt","getRandomBigInt","getChain","GAS_SANITY_THRESHOLD","GAS_FALLBACK_CAP","ZERODEV_NONCE_KEY_BITS","USEROP_RECEIPT_TIMEOUT_MS","capForBogusEstimate","estimatedGas","logger","warn","ContractBase","contractName","address","_zeroDevPaymaster","init","config","contractConfig","setInstanceConfig","contract","abi","client","public","publicClient","wallet","walletClient","call","functionName","args","from","readContract","account","err","txHash","hash","receipt","transactionHash","Error","getTransactionLogs","txReceipt","eventName","logs","strict","multicall","calls","params","type","debug","localAccountMulticall","progress","internalMulticallSmartAccount","simulateMulticall","localAccountSimulateMulticall","internalSimulateMulticallSmartAccount","simulate","localAccountSimulate","internalSimulateSmartAccount","send","localAccountSend","internalSendSmartAccount","getUserOperationReceipt","bundlerClient","chain","chainId","transport","getBundlerRPC","message","String","test","safeMessage","replace","txparams","stage","method","contractAddress","kernelClient","bundlerTransport","getPaymasterConfig","userOperation","estimateFeesPerGas","encodedCalls","map","push","to","value","data","userOpHash","nonce","getNonce","key","sendUserOperation","callData","encodeCalls","waitForUserOperationReceipt","timeout","assertUserOpSucceeded","revertError","walk","error","hashSuffix","success","reason","name","functionInputs","gasLimit","simulateContract","preparedUserOp","preparedHash","prepareUserOperation","entryPointAddress","entryPoint","entryPointVersion","version","prepErr","undefined","signature","_contractAbi","_contractAddress","_contractName","request","resolvedGas","estimate","estimateContractGas","estErr","writeContract","gas","receipts","length","pop","results","simulateCalls","JSON","stringify","e","getOrCreatePaymaster","getPaymasterRPC","zerodevPaymaster","paymaster","getPaymasterData","sponsorUserOperation","projectId","zeroDevProjectId","useUltraRelay"],"mappings":"AAAA,SAASA,yBAAyB,EAAEC,4BAA4B,QAAQ,eAAc;AACtF,SACEC,yBAAyB,EACzBC,gBAAgB,EAChBC,kBAAkB,EAClBC,aAAa,QACR,6CAA4C;AACnD,SAIEC,SAAS,EACTC,6BAA6B,EAC7BC,kBAAkB,EAClBC,WAAW,EACXC,IAAI,EACJC,QAAQ,EACRC,cAAc,QAET,OAAM;AACb,SACEC,mBAAmB,EACnBC,oBAAoB,QAGf,2BAA0B;AACjC,SAASC,cAAc,EAAEC,uBAAuB,QAAQ,qBAAoB;AAC5E,SAASC,YAAY,QAA4B,8BAA6B;AAE9E,SAASC,4BAA4B,EAAEC,qBAAqB,QAAQ,yBAAwB;AAC5F,SAASC,eAAe,QAAQ,sBAAqB;AACrD,SAASC,QAAQ,QAAQ,sBAAqB;AAU9C;;;;;;;;;;;;CAYC,GACD,MAAMC,uBAAuB,WAAW;AACxC,MAAMC,mBAAmB,UAAU;AAEnC,2FAA2F;AAC3F,uFAAuF;AACvF,qFAAqF;AACrF,qFAAqF;AACrF,MAAMC,yBAAyB;AAE/B,yFAAyF;AACzF,yFAAyF;AACzF,yFAAyF;AACzF,0EAA0E;AAC1E,MAAMC,4BAA4B;AAElC,SAASC,oBACPC,YAAoB,EACpBC,MAAuC;IAEvC,IAAID,eAAeL,sBAAsB,OAAOK;IAChDC,OAAOC,IAAI,CACT,CAAC,eAAe,EAAEF,aAAa,2BAA2B,CAAC,GACzD,CAAC,CAAC,EAAEL,qBAAqB,mBAAmB,EAAEC,iBAAiB,oCAAoC,CAAC;IAExG,OAAOA;AACT;AAUA,OAAO,MAAeO,qBAAqBb;IAMzC,YAAYc,YAAoB,EAAEC,OAAgB,CAAE;QAClD,KAAK,SAHCC,oBAA4E;QAIlF,IAAI,CAACF,YAAY,GAAGA;QACpB,IAAI,CAACC,OAAO,GAAGA;IACjB;IAEA,MAAgBE,KACdC,MAA0B,EAC1BC,cAAoD,EACpD;QACA,IAAI,CAACC,iBAAiB,CAACF;QACvB,IAAI,CAACH,OAAO,GAAGI,eAAeJ,OAAO;QAErC,IAAI,CAACM,QAAQ,GAAG7B,YAAY;YAC1BuB,SAASI,eAAeJ,OAAO;YAC/BO,KAAKH,eAAeG,GAAG;YACvBC,QAAQ;gBAAEC,QAAQ,IAAI,CAACC,YAAY;gBAAEC,QAAQ,IAAI,CAACC,YAAY;YAAC;QACjE;IACF;IAEA,MAAaC,KAAQC,YAAoB,EAAEC,IAAW,EAAEC,IAAa,EAAc;QACjF,IAAI;YACF,OAAQ,MAAM,IAAI,CAACR,MAAM,CAACC,MAAM,CAACQ,YAAY,CAAC;gBAC5CjB,SAAS,IAAI,CAACA,OAAO;gBACrBO,KAAK,IAAI,CAACD,QAAQ,CAACC,GAAG;gBACtBO,cAAcnC,SAAS;oBAACmC;iBAAa;gBACrCC;gBACA,GAAIC,QAAQ;oBAAEE,SAASF;gBAAsB,CAAC;YAChD;QACA,kEAAkE;QACpE,EAAE,OAAOG,KAAK;YACZ,MAAM,IAAIpC,eACR,CAAC,gBAAgB,EAAE+B,aAAa,eAAe,EAAE,IAAI,CAACf,YAAY,CAAC,gBAAgB,EAAEgB,KAAK,GAAG,EAAEI,KAAK;QAExG;IACF;IAEA,MAAahC,sBACXiC,MAAiD,EACpB;QAC7B,8DAA8D;QAC9D,IAAI,qBAAqBA,QAAQ;YAC/B,+BAA+B;YAC/B,OAAOA;QACT,OAAO,IAAI,gBAAgBA,QAAQ;YACjC,uGAAuG;YACvG,MAAMC,OAAOD,OAAOE,OAAO,CAACC,eAAe;YAC3C,OAAO,MAAMpC,sBAAsB;gBACjCiC,QAAQC;gBACRX,cAAc,IAAI,CAACF,MAAM,CAACC,MAAM;YAClC;QACF,OAAO;YACL,MAAM,IAAIe,MAAM;QAClB;IACF;IAEOC,mBACLC,SAAoD,EACpDC,SAAkB,EAClB;QACA,OAAO/C,eAAe;YACpB2B,KAAK,IAAI,CAACD,QAAQ,CAACC,GAAG;YACtBqB,MAAMF,UAAUE,IAAI;YACpBD;YACAE,QAAQ;QACV;IACF;IAEA,MAAaC,UACXC,KAAuB,EACvBf,IAA4B,EAC5BgB,SAAuB,CAAC,CAAC,EACzB;QACA,IAAIhB,KAAKiB,IAAI,KAAK,SAAS;YACzB,IAAI,CAACrC,MAAM,CAACsC,KAAK,CAAC,CAAC,wCAAwC,CAAC;YAC5D,OAAO,MAAM,IAAI,CAACC,qBAAqB,CAACJ,OAAOf,MAAMgB,QAAQA,OAAOI,QAAQ;QAC9E,OAAO,IAAIpB,KAAKiB,IAAI,KAAK,YAAY;YACnC,IAAI,CAACrC,MAAM,CAACsC,KAAK,CAAC,CAAC,2CAA2C,CAAC;YAC/D,OAAO,MAAM,IAAI,CAACC,qBAAqB,CAACJ,OAAOf,MAAMgB,QAAQA,OAAOI,QAAQ;QAC9E,OAAO,IAAIpB,KAAKiB,IAAI,KAAK,SAAS;YAChC,IAAI,CAACrC,MAAM,CAACsC,KAAK,CAAC,CAAC,0CAA0C,CAAC;YAC9D,OAAO,MAAM,IAAI,CAACG,6BAA6B,CAACN,OAAOf,MAAMgB,QAAQA,OAAOI,QAAQ;QACtF,OAAO;YACL,MAAM,IAAIrD,eAAe,CAAC,qBAAqB,CAAC;QAClD;IACF;IAEA,MAAauD,kBACXP,KAA+B,EAC/Bf,IAA4B,EAC5BgB,SAAuB,CAAC,CAAC,EACzB;QACA,IAAIhB,KAAKiB,IAAI,KAAK,SAAS;YACzB,IAAI,CAACrC,MAAM,CAACsC,KAAK,CAAC,CAAC,oCAAoC,CAAC;YACxD,OAAO,MAAM,IAAI,CAACK,6BAA6B,CAACR,OAAOf,MAAMgB;QAC/D,OAAO,IAAIhB,KAAKiB,IAAI,KAAK,YAAY;YACnC,IAAI,CAACrC,MAAM,CAACsC,KAAK,CAAC,CAAC,uCAAuC,CAAC;YAC3D,OAAO,MAAM,IAAI,CAACK,6BAA6B,CAACR,OAAOf,MAAMgB;QAC/D,OAAO,IAAIhB,KAAKiB,IAAI,KAAK,SAAS;YAChC,IAAI,CAACrC,MAAM,CAACsC,KAAK,CAAC,CAAC,4CAA4C,CAAC;YAChE,OAAO,MAAM,IAAI,CAACM,qCAAqC,CAACT,OAAOf,MAAMgB;QACvE,OAAO;YACL,MAAM,IAAIjD,eAAe,CAAC,qBAAqB,CAAC;QAClD;IACF;IAEA,MAAa0D,SACX3B,YAAoB,EACpBE,IAA4B,EAC5BD,IAAW,EACXiB,SAAuB,CAAC,CAAC,EACzB;QACA,IAAIhB,KAAKiB,IAAI,KAAK,SAAS;YACzB,IAAI,CAACrC,MAAM,CAACsC,KAAK,CAAC,CAAC,oCAAoC,CAAC;YACxD,OAAO,MAAM,IAAI,CAACQ,oBAAoB,CAAC5B,cAAcE,MAAMD,MAAMiB;QACnE,OAAO,IAAIhB,KAAKiB,IAAI,KAAK,YAAY;YACnC,IAAI,CAACrC,MAAM,CAACsC,KAAK,CAAC,CAAC,uCAAuC,CAAC;YAC3D,OAAO,MAAM,IAAI,CAACQ,oBAAoB,CAAC5B,cAAcE,MAAMD,MAAMiB;QACnE,OAAO,IAAIhB,KAAKiB,IAAI,KAAK,SAAS;YAChC,IAAI,CAACrC,MAAM,CAACsC,KAAK,CAAC,CAAC,4CAA4C,CAAC;YAChE,OAAO,MAAM,IAAI,CAACS,4BAA4B,CAAC7B,cAAcE,MAAMD,MAAMiB;QAC3E,OAAO;YACL,MAAM,IAAIjD,eAAe,CAAC,qBAAqB,CAAC;QAClD;IACF;IAEA,MAAa6D,KACX9B,YAAoB,EACpBE,IAA4B,EAC5BD,IAAW,EACXiB,SAAuB,CAAC,CAAC,EAC2B;QACpD,IAAIhB,KAAKiB,IAAI,KAAK,SAAS;YACzB,IAAI,CAACrC,MAAM,CAACsC,KAAK,CACf,CAAC,uDAAuD,EAAEpB,aAAa,qBAAqB,EAAEC,MAAM;YAEtG,OAAO,MAAM,IAAI,CAAC8B,gBAAgB,CAAC/B,cAAcE,MAAMD,MAAMiB,QAAQA,OAAOI,QAAQ;QACtF,OAAO,IAAIpB,KAAKiB,IAAI,KAAK,YAAY;YACnC,IAAI,CAACrC,MAAM,CAACsC,KAAK,CAAC,CAAC,0CAA0C,EAAEpB,cAAc;YAC7E,OAAO,MAAM,IAAI,CAAC+B,gBAAgB,CAAC/B,cAAcE,MAAMD,MAAMiB,QAAQA,OAAOI,QAAQ;QACtF,OAAO,IAAIpB,KAAKiB,IAAI,KAAK,SAAS;YAChC,IAAI,CAACrC,MAAM,CAACsC,KAAK,CAAC,CAAC,qCAAqC,CAAC;YACzD,OAAO,MAAM,IAAI,CAACY,wBAAwB,CAAChC,cAAcE,MAAMD,MAAMiB,QAAQA,OAAOI,QAAQ;QAC9F,OAAO;YACL,MAAM,IAAIrD,eAAe,CAAC,qBAAqB,CAAC;QAClD;IACF;IAEA;;;;;;;GAOC,GACD,MAAagE,wBAAwB1B,IAAmB,EAAwC;QAC9F,IAAI;YACF,MAAM2B,gBAAgBnE,oBAAoB;gBACxCoE,OAAO5D,SAAS,IAAI,CAACc,MAAM,CAAC+C,OAAO;gBACnCC,WAAWzE,KAAK,IAAI,CAAC0E,aAAa;gBAClC5C,QAAQ,IAAI,CAACA,MAAM,CAACC,MAAM;YAC5B;YACA,OAAO,AAAC,MAAMuC,cAAcD,uBAAuB,CAAC;gBAAE1B;YAAK,MAAO;QACpE,EAAE,OAAOF,KAAK;YACZ,uEAAuE;YACvE,yEAAyE;YACzE,0EAA0E;YAC1E,uEAAuE;YACvE,sEAAsE;YACtE,2EAA2E;YAC3E,MAAMkC,UAAUlC,eAAeK,QAAQL,IAAIkC,OAAO,GAAGC,OAAOnC;YAC5D,IAAI,+CAA+CoC,IAAI,CAACF,UAAU;gBAChE,IAAI,CAACzD,MAAM,CAACsC,KAAK,CAAC,CAAC,wBAAwB,EAAEb,KAAK,gBAAgB,CAAC;YACrE,OAAO;gBACL,qEAAqE;gBACrE,+CAA+C;gBAC/C,MAAMmC,cAAcH,QAAQI,OAAO,CAAC,0BAA0B;gBAC9D,IAAI,CAAC7D,MAAM,CAACC,IAAI,CACd,CAAC,wBAAwB,EAAEwB,KAAK,4CAA4C,EAAEmC,aAAa;YAE/F;YACA,OAAO;QACT;IACF;IAEA,MAAcnB,8BACZN,KAAuB,EACvBf,IAAkB,EAClB0C,QAAa,EACbtB,QAA2C,EAC3C;QACA,IAAIA,UAAU;YACZA,SAAS;gBACPuB,OAAO;gBACP5C,MAAM,EAAE;gBACR6C,QAAQ;gBACR5C,MAAMA;gBACN6C,iBAAiB,IAAI,CAAC7D,OAAO;YAC/B;QACF;QAEA,MAAM8D,eAAe9F,0BAA0B;YAC7CkD,SAASF;YACTiC,OAAO5D,SAAS,IAAI,CAACc,MAAM,CAAC+C,OAAO;YACnCa,kBAAkBrF,KAAK,IAAI,CAAC0E,aAAa;YACzC5C,QAAQ,IAAI,CAACA,MAAM,CAACC,MAAM;YAC1B,GAAG,IAAI,CAACuD,kBAAkB,EAAE;YAC5BC,eAAe;gBACbC,oBAAoB,OAAO,EAAElB,aAAa,EAAE;oBAC1C,OAAO9E,0BAA0B8E,eAAe,IAAI,CAACxC,MAAM,CAACC,MAAM;gBACpE;YACF;QACF;QAEA,MAAM0D,eAAsB,EAAE;QAC9BpC,MAAMqC,GAAG,CAAC,CAACvD;YACTsD,aAAaE,IAAI,CAAC;gBAChBC,IAAIzD,KAAKgD,eAAe,IAAI,IAAI,CAAC7D,OAAO;gBACxCuE,OAAOb,SAASa,KAAK,IAAI,EAAE;gBAC3BC,MAAMhG,mBAAmB;oBACvB+B,KAAKM,KAAKN,GAAG;oBACbO,cAAcD,KAAKC,YAAY;oBAC/BC,MAAMF,KAAKE,IAAI;gBACjB;YACF;QACF;QAEA,IAAI0D;QACJ,IAAI;YACF,oEAAoE;YACpE,qEAAqE;YACrE,gDAAgD;YAChD,MAAMC,QAAQ,MAAM1D,KAAK2D,QAAQ,CAAC;gBAAEC,KAAKxF,gBAAgBI;YAAwB;YACjFiF,aAAa,MAAMX,aAAae,iBAAiB,CAAC;gBAChDC,UAAU,MAAMhB,aAAa5C,OAAO,CAAC6D,WAAW,CAACZ;gBACjDO;YACF;YAEA,IAAItC,UAAU;gBACZA,SAAS;oBACPuB,OAAO;oBACP5C,MAAM,EAAE;oBACR6C,QAAQ;oBACR5C,MAAMA;oBACN6C,iBAAiB,IAAI,CAAC7D,OAAO;gBAC/B;YACF;YAEA,uCAAuC;YACvC,IAAI,CAACJ,MAAM,CAACsC,KAAK,CAAC,CAAC,uCAAuC,EAAEuC,YAAY;YACxE,MAAM/C,YAAY,MAAMoC,aAAakB,2BAA2B,CAAC;gBAC/D3D,MAAMoD;gBACNQ,SAASxF;YACX;YACA,IAAI,CAACG,MAAM,CAACsC,KAAK,CAAC,CAAC,uCAAuC,EAAEuC,YAAY;YACxE,IAAI,CAAC7E,MAAM,CAACsC,KAAK,CACf,CAAC,uCAAuC,EAAER,UAAUJ,OAAO,CAACC,eAAe,EAAE;YAE/E,IAAI,CAAC2D,qBAAqB,CAACxD,WAAW,aAAa+C;YACnD,OAAO/C,UAAUJ,OAAO;QAC1B,EAAE,OAAOH,KAAK;YACZ,IAAIA,eAAe7C,WAAW;gBAC5B,MAAM6G,cAAchE,IAAIiE,IAAI,CAAC,CAACjE,MAAQA,eAAe5C;gBACrD,IAAI,CAACqB,MAAM,CAACyF,KAAK,CAAC,CAAC,aAAa,EAAE/B,OAAO6B,cAAc;YACzD;YACA,uEAAuE;YACvE,4EAA4E;YAC5E,MAAMG,aAAab,aAAa,CAAC,YAAY,EAAEA,YAAY,GAAG;YAC9D,MAAM,IAAI1F,eAAe,CAAC,iBAAiB,EAAEuG,WAAW,CAAC,EAAEnE,KAAK;QAClE;IACF;IAEQ+D,sBACNxD,SAA+B,EAC/BkC,MAAc,EACda,UAAkB,EACZ;QACN,IAAI/C,UAAU6D,OAAO,EAAE;QACvB,MAAM,IAAIxG,eACR,CAAC,gCAAgC,EAAE6E,OAAO,MAAM,EAAE,IAAI,CAAC7D,YAAY,CAAC,GAAG,CAAC,GACtE,CAAC,WAAW,EAAE0E,WAAW,QAAQ,EAAE/C,UAAUJ,OAAO,CAACC,eAAe,CAAC,CAAC,CAAC,GACvE,CAAC,OAAO,EAAEG,UAAU8D,MAAM,IAAI,WAAW;IAE/C;IAEA,MAAc1C,yBACZ2C,IAAY,EACZzE,IAAkB,EAClBD,IAAW,EACX2C,QAAa,EACbtB,QAA2C,EACZ;QAC/B,MAAMsD,iBAAiBxG,6BAA6B,IAAI,CAACoB,QAAQ,CAACC,GAAG,EAAEkF,MAAM1E;QAE7E,MAAM,EAAE4E,QAAQ,EAAEpB,KAAK,EAAE,GAAGb;QAC5B,IAAItB,UAAU;YACZA,SAAS;gBACPuB,OAAO;gBACP5C,MAAM2E;gBACN9B,QAAQ6B;gBACRzE,MAAMA;gBACNuD;gBACAxE,cAAc,IAAI,CAACA,YAAY;gBAC/B8D,iBAAiB,IAAI,CAAC7D,OAAO;gBAC7B2F;YACF;QACF;QAEA,IAAI;YACF,MAAM,IAAI,CAACnF,MAAM,CAACC,MAAM,CAACmF,gBAAgB,CAAC;gBACxC5F,SAAS,IAAI,CAACA,OAAO;gBACrBO,KAAK,IAAI,CAACD,QAAQ,CAACC,GAAG;gBACtBO,cAAc2E;gBACd1E;gBACAG,SAASF;gBACT,GAAI0C,SAASa,KAAK,IAAI;oBAAEA,OAAOb,SAASa,KAAK;gBAAC,CAAC;YACjD;QACF,EAAE,OAAOpD,KAAK;YACZ,IAAIA,eAAe7C,WAAW;gBAC5B,MAAM6G,cAAchE,IAAIiE,IAAI,CAAC,CAACjE,MAAQA,eAAe5C;gBACrD,IAAI,CAACqB,MAAM,CAACyF,KAAK,CAAC,CAAC,aAAa,EAAE/B,OAAO6B,cAAc;YACzD;YACA,MAAM,IAAIpG,eACR,CAAC,gBAAgB,EAAE0G,KAAK,eAAe,EAAE,IAAI,CAAC1F,YAAY,CAAC,gBAAgB,EAAEgB,KAAK,GAAG,EAAEI,KAAK;QAEhG;QAEA,MAAM2C,eAAe9F,0BAA0B;YAC7CkD,SAASF;YACTiC,OAAO5D,SAAS,IAAI,CAACc,MAAM,CAAC+C,OAAO;YACnCa,kBAAkBrF,KAAK,IAAI,CAAC0E,aAAa;YACzC5C,QAAQ,IAAI,CAACA,MAAM,CAACC,MAAM;YAC1B,GAAG,IAAI,CAACuD,kBAAkB,EAAE;YAC5BC,eAAe;gBACbC,oBAAoB,OAAO,EAAElB,aAAa,EAAE;oBAC1C,OAAO9E,0BAA0B8E,eAAe,IAAI,CAACxC,MAAM,CAACC,MAAM;gBACpE;YACF;QACF;QACA,MAAM+D,OAAOhG,mBAAmB;YAAE+B,KAAK,IAAI,CAACD,QAAQ,CAACC,GAAG;YAAEO,cAAc2E;YAAM1E;QAAK;QAEnF,IAAI0D;QACJ,IAAI;YACF,oEAAoE;YACpE,qEAAqE;YACrE,gDAAgD;YAChD,MAAMC,QAAQ,MAAM1D,KAAK2D,QAAQ,CAAC;gBAAEC,KAAKxF,gBAAgBI;YAAwB;YACjF,MAAMsF,WAAW,MAAMhB,aAAa5C,OAAO,CAAC6D,WAAW,CAAC;gBACtD;oBACET,IAAI,IAAI,CAACtE,OAAO;oBAChBuE,OAAOb,SAASa,KAAK,IAAI,EAAE;oBAC3BC;gBACF;aACD;YAED,sEAAsE;YACtE,uEAAuE;YACvE,yEAAyE;YACzE,sEAAsE;YACtE,kEAAkE;YAClE,yEAAyE;YACzE,sEAAsE;YACtE,sEAAsE;YACtE,+DAA+D;YAC/D,IAAIqB;YACJ,IAAIC;YACJ,IAAI1D,UAAU;gBACZ,IAAI;oBACFyD,iBAAiB,MAAM/B,aAAaiC,oBAAoB,CAAC;wBAAEjB;wBAAUJ;oBAAM;oBAC3EoB,eAAehH,qBAAqB;wBAClCoE,SAAS,IAAI,CAAC/C,MAAM,CAAC+C,OAAO;wBAC5B8C,mBAAmBhF,KAAKiF,UAAU,CAACjG,OAAO;wBAC1CkG,mBAAmBlF,KAAKiF,UAAU,CAACE,OAAO;wBAC1ClC,eAAe4B;oBACjB;oBACAzD,SAAS;wBACPuB,OAAO;wBACP5C,MAAM2E;wBACNjB,YAAYqB;wBACZlC,QAAQ6B;wBACRzE,MAAMA;wBACNuD;wBACAxE,cAAc,IAAI,CAACA,YAAY;wBAC/B8D,iBAAiB,IAAI,CAAC7D,OAAO;wBAC7B2F;oBACF;gBACF,EAAE,OAAOS,SAAS;oBAChB,IAAI,CAACxG,MAAM,CAACC,IAAI,CACd,CAAC,iDAAiD,EAAE4F,KAAK,GAAG,CAAC,GAC3D,CAAC,+BAA+B,EAAEW,SAAS;oBAE/CP,iBAAiBQ;oBACjBP,eAAeO;gBACjB;YACF;YAEA5B,aAAa,MAAMX,aAAae,iBAAiB,CAC/C,+DAA+D;YAC/D,wEAAwE;YACxE,mEAAmE;YACnE,+DAA+D;YAC/DgB,iBACK;gBAAE,GAAGA,cAAc;gBAAES,WAAWD;YAAU,IAG3C;gBAAEvB;gBAAUJ;YAAM;YAGxB,0EAA0E;YAC1E,yEAAyE;YACzE,uEAAuE;YACvE,yEAAyE;YACzE,wCAAwC;YACxC,IAAIoB,gBAAgBrB,eAAeqB,cAAc;gBAC/C,IAAI,CAAClG,MAAM,CAACC,IAAI,CACd,CAAC,uBAAuB,EAAEiG,aAAa,cAAc,EAAErB,WAAW,MAAM,EAAEgB,KAAK,GAAG,CAAC,GACjF,CAAC,uDAAuD,CAAC;YAE/D;QACF,EAAE,OAAOtE,KAAK;YACZ,IAAIA,eAAe7C,WAAW;gBAC5B,MAAM6G,cAAchE,IAAIiE,IAAI,CAAC,CAACjE,MAAQA,eAAe5C;gBACrD,IAAI,CAACqB,MAAM,CAACyF,KAAK,CAAC,CAAC,aAAa,EAAE/B,OAAO6B,cAAc;YACzD;YACA,MAAM,IAAIpG,eACR,CAAC,gBAAgB,EAAE0G,KAAK,eAAe,EAAE,IAAI,CAAC1F,YAAY,CAAC,gBAAgB,EAAEgB,KAAK,GAAG,EAAEI,KAAK;QAEhG;QAEA,IAAIiB,UAAU;YACZA,SAAS;gBACPuB,OAAO;gBACP5C,MAAM2E;gBACNjB;gBACAb,QAAQ6B;gBACRzE,MAAMA;gBACNuD;gBACAxE,cAAc,IAAI,CAACA,YAAY;gBAC/B8D,iBAAiB,IAAI,CAAC7D,OAAO;gBAC7B2F;YACF;QACF;QAEA,IAAIjE;QACJ,IAAI;YACFA,YAAY,MAAMoC,aAAakB,2BAA2B,CAAC;gBACzD3D,MAAMoD;gBACNQ,SAASxF;YACX;QACF,EAAE,OAAO0B,KAAK;YACZ,uEAAuE;YACvE,0EAA0E;YAC1E,uEAAuE;YACvE,kEAAkE;YAClE,MAAM,IAAIpC,eACR,CAAC,gBAAgB,EAAE0G,KAAK,eAAe,EAAE,IAAI,CAAC1F,YAAY,CAAC,YAAY,CAAC,GACtE,CAAC,uCAAuC,EAAE0E,WAAW,oBAAoB,CAAC,GAC1E,CAAC,uCAAuC,EAAEtD,KAAK;QAErD;QAEA,IAAI,CAAC+D,qBAAqB,CAACxD,WAAW+D,MAAMhB;QAE5C,IAAIrC,UAAU;YACZA,SAAS;gBACPuB,OAAO;gBACP5C,MAAM2E;gBACNhE;gBACAkC,QAAQ6B;gBACRzE,MAAMA;gBACNuD;gBACAxE,cAAc,IAAI,CAACA,YAAY;gBAC/B8D,iBAAiB,IAAI,CAAC7D,OAAO;gBAC7B2F;YACF;QACF;QAEA,OAAOjE;IACT;IAEA,MAAciB,6BACZ8C,IAAY,EACZzE,IAAkB,EAClBD,IAAW,EACX2C,QAAa,EACb;QACA,IAAI;YACF,MAAM,IAAI,CAAClD,MAAM,CAACC,MAAM,CAACmF,gBAAgB,CAAC;gBACxC5F,SAAS,IAAI,CAACA,OAAO;gBACrBO,KAAK,IAAI,CAACD,QAAQ,CAACC,GAAG;gBACtBO,cAAc2E;gBACd1E;gBACAG,SAASF,KAAKhB,OAAO;gBACrB,GAAI0D,SAASa,KAAK,IAAI;oBAAEA,OAAOb,SAASa,KAAK;gBAAC,CAAC;YACjD;YACA,OAAO;QACT,EAAE,OAAOpD,KAAK;YACZ,MAAM,IAAInC,wBACR,CAAC,gCAAgC,EAAEyG,KAAK,eAAe,EAAE,IAAI,CAAC1F,YAAY,CAAC,gBAAgB,EAAEgB,KAAK,GAAG,EAAEI,KAAK;QAEhH;IACF;IAEA,MAAcuB,qBACZ+C,IAAY,EACZzE,IAA6B,EAC7BD,IAAW,EACX2C,QAAa,EACb;QACA,IAAI;YACF,MAAM,IAAI,CAAClD,MAAM,CAACC,MAAM,CAACmF,gBAAgB,CAAC;gBACxC5F,SAAS,IAAI,CAACA,OAAO;gBACrBO,KAAK,IAAI,CAACD,QAAQ,CAACC,GAAG;gBACtBO,cAAc2E;gBACd1E;gBACAG,SAASF;gBACT,GAAI0C,SAASa,KAAK,IAAI;oBAAEA,OAAOb,SAASa,KAAK;gBAAC,CAAC;YACjD;QACF,EAAE,OAAOpD,KAAK;YACZ,MAAM,IAAInC,wBACR,CAAC,gCAAgC,EAAEyG,KAAK,eAAe,EAAE,IAAI,CAAC1F,YAAY,CAAC,gBAAgB,EAAEgB,KAAK,GAAG,EAAEI,KAAK;QAEhH;QACA,OAAO;IACT;IAEA,MAAc0B,iBACZ4C,IAAY,EACZzE,IAA6B,EAC7BD,IAAW,EACX2C,QAAa,EACbtB,QAA2C,EAC3CmE,YAAkB,EAClBC,gBAA0B,EAC1BC,aAAsB,EACtB;QACA,MAAMlG,MAAMgG,gBAAgB,IAAI,CAACjG,QAAQ,CAACC,GAAG;QAC7C,MAAMsD,kBAAkB2C,oBAAoB,IAAI,CAACxG,OAAO;QACxD,MAAMD,eAAe0G,iBAAiB,IAAI,CAAC1G,YAAY;QAEvD,MAAM2F,iBAAiBxG,6BAA6BqB,KAAKkF,MAAM1E;QAC/D,oCAAoC;QACpC,0BAA0B;QAC1B,oFAAoF;QACpF,qEAAqE;QACrE,wEAAwE;QACxE,0FAA0F;QAC1F,qDAAqD;QACrD,IAAI;QACJ,kFAAkF;QAClF,8GAA8G;QAC9G,oGAAoG;QACpG,6EAA6E;QAC7E,wCAAwC;QACxC,kBAAkB;QAClB,8BAA8B;QAC9B,4GAA4G;QAC5G,MAAM;QAEN,MAAM,EAAE4E,QAAQ,EAAEpB,KAAK,EAAE,GAAGb;QAC5B,gBAAgB;QAChB,IAAItB,UAAU;YACZA,SAAS;gBACPuB,OAAO;gBACP5C,MAAM2E;gBACN9B,QAAQ6B;gBACRzE;gBACAuD;gBACAxE;gBACA8D;gBACA8B;YACF;QACF;QAEA,IAAIvE;QACJ,IAAI;YACF,MAAM,EAAEsF,OAAO,EAAE,GAAG,MAAM,IAAI,CAAClG,MAAM,CAACC,MAAM,CAACmF,gBAAgB,CAAC;gBAC5D5F,SAAS6D;gBACTtD;gBACAO,cAAc2E;gBACd1E;gBACAG,SAASF;gBACT,GAAI0C,SAASa,KAAK,IAAI;oBAAEA,OAAOb,SAASa,KAAK;gBAAC,CAAC;YACjD;YAEA,uEAAuE;YACvE,0EAA0E;YAC1E,uEAAuE;YACvE,+DAA+D;YAC/D,IAAIoC,cAAkChB;YACtC,IAAIgB,gBAAgBN,WAAW;gBAC7B,IAAI;oBACF,MAAMO,WAAW,MAAM,IAAI,CAACpG,MAAM,CAACC,MAAM,CAACoG,mBAAmB,CAAC;wBAC5D7G,SAAS6D;wBACTtD;wBACAO,cAAc2E;wBACd1E;wBACAG,SAASF;wBACT,GAAI0C,SAASa,KAAK,IAAI;4BAAEA,OAAOb,SAASa,KAAK;wBAAC,CAAC;oBACjD;oBACAoC,cAAcjH,oBAAoBkH,UAAU,IAAI,CAAChH,MAAM;gBACzD,EAAE,OAAOkH,QAAQ;oBACf,IAAI,CAAClH,MAAM,CAACC,IAAI,CACd,CAAC,yBAAyB,EAAE4F,KAAK,MAAM,EAAE1F,aAAa,UAAU,EAAE+G,OAAO,GAAG,CAAC,GAC3E,CAAC,gBAAgB,EAAEvH,iBAAiB,mDAAmD,CAAC;oBAE5FoH,cAAcpH;gBAChB;YACF;YAEA6B,SAAS,MAAM,IAAI,CAACZ,MAAM,CAACG,MAAM,CAACoG,aAAa,CAAC;gBAC9C,GAAGL,OAAO;gBACVxF,SAASF;gBACTgG,KAAKL;YACP;QACF,EAAE,OAAOxF,KAAK;YACZ,IAAIA,eAAe7C,WAAW;gBAC5B,MAAM6G,cAAchE,IAAIiE,IAAI,CAAC,CAACjE,MAAQA,eAAe5C;gBACrD,IAAI,CAACqB,MAAM,CAACyF,KAAK,CAAC,CAAC,aAAa,EAAE/B,OAAO6B,cAAc;YACzD;YACA,MAAM,IAAIpG,eACR,CAAC,gBAAgB,EAAE0G,KAAK,eAAe,EAAE1F,aAAa,gBAAgB,EAAEgB,KAAK,GAAG,EAAEI,KAAK;QAE3F;QAEA,IAAIiB,UAAU;YACZA,SAAS;gBACPuB,OAAO;gBACP5C,MAAM2E;gBACNtE;gBACAwC,QAAQ6B;gBACRzE;gBACAuD;gBACAxE;gBACA8D;gBACA8B;YACF;QACF;QACA,MAAMjE,YAAYvC,sBAAsB;YAAEiC;YAAQV,cAAc,IAAI,CAACF,MAAM,CAACC,MAAM;QAAC;QAEnF,IAAI2B,UAAU;YACZA,SAAS;gBACPuB,OAAO;gBACP5C,MAAM2E;gBACNhE;gBACAkC,QAAQ6B;gBACRzE;gBACAuD;gBACAxE;gBACA8D;gBACA8B;YACF;QACF;QAEA,OAAOjE;IACT;IAEA,MAAcS,sBACZJ,KAAuB,EACvBf,IAAa,EACb0C,QAAa,EACbtB,QAA2C,EACd;QAC7B,MAAM6E,WAAiC,EAAE;QACzC,KAAK,MAAMpG,QAAQkB,MAAO;YACxBkF,SAAS5C,IAAI,CACX,MAAM,IAAI,CAACxB,gBAAgB,CACzBhC,KAAKC,YAAY,EACjBE,MACAH,KAAKE,IAAI,EACT2C,UACAtB,UACAvB,KAAKN,GAAG,EACRM,KAAKgD,eAAe,EACpBhD,KAAKd,YAAY;QAGvB;QACA,IAAIkH,SAASC,MAAM,GAAG,GAAG,OAAOD,SAASE,GAAG;aACvC,MAAM,IAAIpI,eAAe,CAAC,+BAA+B,CAAC;IACjE;IAEA,MAAcwD,8BACZR,KAA+B,EAC/Bf,IAAa,EACb0C,QAAa,EACb;QACA,IAAI;YACF,MAAM,EAAE0D,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC5G,MAAM,CAACC,MAAM,CAAC4G,aAAa,CAAC;gBACzDtF;gBACAb,SAASF;YACX;YACA,IAAI,CAACpB,MAAM,CAACsC,KAAK,CAAC,CAAC,sBAAsB,EAAEkF,SAAS;YACpD,OAAO;QACT,EAAE,OAAOjG,KAAK;YACZ,IAAIA,eAAe7C,WAAW;gBAC5B,MAAM6G,cAAchE,IAAIiE,IAAI,CAAC,CAACjE,MAAQA,eAAe5C;gBACrD,IAAI,CAACqB,MAAM,CAACyF,KAAK,CAAC,CAAC,aAAa,EAAE/B,OAAO6B,cAAc;YACzD;YACA,MAAM,IAAIpG,eAAe,CAAC,6BAA6B,EAAEoC,KAAK;QAChE;IACF;IAEA,MAAcqB,sCACZT,KAA+B,EAC/Bf,IAAkB,EAClB0C,QAAa,EACb;QACA,IAAI;YACF,MAAMI,eAAe9F,0BAA0B;gBAC7CkD,SAASF;gBACTiC,OAAO5D,SAAS,IAAI,CAACc,MAAM,CAAC+C,OAAO;gBACnCa,kBAAkBrF,KAAK,IAAI,CAAC0E,aAAa;gBACzC5C,QAAQ,IAAI,CAACA,MAAM,CAACC,MAAM;gBAC1B,GAAG,IAAI,CAACuD,kBAAkB,EAAE;gBAC5BC,eAAe;oBACbC,oBAAoB,OAAO,EAAElB,aAAa,EAAE;wBAC1C,OAAO9E,0BAA0B8E,eAAe,IAAI,CAACxC,MAAM,CAACC,MAAM;oBACpE;gBACF;YACF;YAEA,MAAM0D,eAAe,EAAE;YACvB,KAAK,MAAMtD,QAAQkB,MAAO;gBACxBoC,aAAaE,IAAI,CAAC;oBAChBC,IAAIzD,KAAKyD,EAAE;oBACXC,OAAO1D,KAAK0D,KAAK,IAAI,EAAE;oBACvBC,MAAMhG,mBAAmB;wBACvB+B,KAAKM,KAAKN,GAAG;wBACbO,cAAcD,KAAKC,YAAY;wBAC/BC,MAAMF,KAAKE,IAAI;oBACjB;gBACF;YACF;YAEA,gFAAgF;YAEhF,wFAAwF;YACxF,2EAA2E;YAC3E,yDAAyD;YACzD,0HAA0H;YAE1H,yBAAyB;YACzB,iDAAiD;YACjD,uDAAuD;YAEvD,8BAA8B;YAC9B,8DAA8D;YAC9D,0CAA0C;YAC1C,6GAA6G;YAC7G,KAAK;YAEL,MAAM+C,aAAaiC,oBAAoB,CAAC;gBACtCjB,UAAU,MAAMhB,aAAa5C,OAAO,CAAC6D,WAAW,CAACZ;YACnD;YAEA,OAAO;QACT,EAAE,OAAOhD,KAAK;YACZ,IAAI,CAACvB,MAAM,CAACyF,KAAK,CAAC,CAAC,eAAe,EAAEiC,KAAKC,SAAS,CAACpG,KAAK,MAAM,IAAI;YAClE,IAAIA,eAAe7C,WAAW;gBAC5B,MAAM6G,cAAchE,IAAIiE,IAAI,CAAC,CAACoC,IAAMA,aAAajJ;gBACjD,IAAI4G,aAAa;oBACf,IAAI,CAACvF,MAAM,CAACyF,KAAK,CAAC,CAAC,cAAc,EAAE/B,OAAO6B,cAAc;gBAC1D;YACF;YACA,MAAM,IAAInG,wBAAwB,CAAC,8BAA8B,EAAEmC,KAAK;QAC1E;IACF;IAEQsG,uBAAuB;QAC7B,IAAI,CAAC,IAAI,CAACxH,iBAAiB,EAAE;YAC3B,IAAI,CAACA,iBAAiB,GAAGhC,6BAA6B;gBACpDgF,OAAO5D,SAAS,IAAI,CAACc,MAAM,CAAC+C,OAAO;gBACnCC,WAAWzE,KAAK,IAAI,CAACgJ,eAAe;YACtC;QACF;QACA,OAAO,IAAI,CAACzH,iBAAiB;IAC/B;IAEA;;;;;;GAMC,GACD,AAAQ+D,qBAAqB;QAC3B,IAAI3F,iBAAiB,OAAO,CAAC;QAC7B,MAAMsJ,mBAAmB,IAAI,CAACF,oBAAoB;QAClD,OAAO;YACLG,WAAW;gBACTC,kBAAkB,CAAC5D,gBACjB0D,iBAAiBG,oBAAoB,CAAC;wBAAE7D;oBAAc;YAC1D;QACF;IACF;IAEUb,gBAAwB;QAChC,sEAAsE;QACtE,sEAAsE;QACtE,uEAAuE;QACvE,uDAAuD;QACvD,MAAM2E,YAAY,IAAI,CAAC5H,MAAM,CAAC6H,gBAAgB;QAC9C,IAAI,CAACD,aAAa,CAAC1J,iBAAiB;YAClC,MAAM,IAAIU,eACR;QAEJ;QACA,OAAOZ,iBAAiB4J,aAAa,IAAI,IAAI,CAAC5H,MAAM,CAAC+C,OAAO,EAAE,IAAI,CAAC/C,MAAM,CAAC8H,aAAa;IACzF;IAEQP,kBAA0B;QAChC,oEAAoE;QACpE,qEAAqE;QACrE,2DAA2D;QAC3D,MAAMK,YAAY,IAAI,CAAC5H,MAAM,CAAC6H,gBAAgB;QAC9C,IAAI,CAACD,WAAW;YACd,MAAM,IAAIhJ,eACR;QAEJ;QACA,OAAOX,mBAAmB2J,WAAW,IAAI,CAAC5H,MAAM,CAAC+C,OAAO;IAC1D;AACF"}
|
|
@@ -286,17 +286,6 @@ export declare function estimateUserOperationFees(bundlerClient: any, _publicCli
|
|
|
286
286
|
maxFeePerGas: bigint;
|
|
287
287
|
maxPriorityFeePerGas: bigint;
|
|
288
288
|
}>;
|
|
289
|
-
/**
|
|
290
|
-
* Floors `verificationGasLimit` on Tempo networks before the UserOp is handed to
|
|
291
|
-
* the ZeroDev paymaster, so `zd_sponsorUserOperation` has headroom and does not
|
|
292
|
-
* revert AA26. No-op on every other network. Shared by both paymaster sponsor
|
|
293
|
-
* call sites. Generic so the caller's UserOp type is preserved; typing
|
|
294
|
-
* `verificationGasLimit?: bigint` also turns a plain-number literal (a `bigint`
|
|
295
|
-
* missing its `n`) into a compile error instead of a silent floor-to-30M.
|
|
296
|
-
*/
|
|
297
|
-
export declare function applyTempoVerificationGasFloor<T extends {
|
|
298
|
-
verificationGasLimit?: bigint;
|
|
299
|
-
}>(userOperation: T, chainId: number): T;
|
|
300
289
|
/**
|
|
301
290
|
* It creates a ZeroDev Kernel client.
|
|
302
291
|
* @param signer the signer account
|
|
@@ -339,6 +328,12 @@ export declare function createKernelSmartAccount(signer: Signer, publicClient: P
|
|
|
339
328
|
export declare function getApproval(signer: Signer, publicClient: any, policies: any[]): Promise<string>;
|
|
340
329
|
export declare function useSessionKey(approval: string, signer: Signer, publicClient: any): Promise<import("@zerodev/sdk").CreateKernelAccountReturnType<"0.7">>;
|
|
341
330
|
export declare function createSessionKey(signer: Signer, publicClient: any, policies: any[], ecdsaValidator?: EcdsaValidator, sessionPrivateKey?: `0x${string}`): Promise<string>;
|
|
331
|
+
/**
|
|
332
|
+
* Permission policies for a multi-network mint: either one set shared by every
|
|
333
|
+
* chain, or a per-chain factory. The factory form is what keeps a chain's key
|
|
334
|
+
* scoped to its OWN settlement tokens instead of the cross-network union.
|
|
335
|
+
*/
|
|
336
|
+
export type PoliciesFor = any[] | ((chainId: number) => any[]);
|
|
342
337
|
/**
|
|
343
338
|
* Multi-network session keys (#1929). Generates ONE session private key and
|
|
344
339
|
* serializes the permission account once per network — each serialization
|
|
@@ -354,9 +349,12 @@ export declare function createSessionKey(signer: Signer, publicClient: any, poli
|
|
|
354
349
|
* @param signer the smart-account owner (e.g. the Privy EOA) — signs each
|
|
355
350
|
* network's enable signature
|
|
356
351
|
* @param publicClientByChainId map of chainId → a PublicClient for that chain
|
|
357
|
-
* @param policies the permission policies
|
|
352
|
+
* @param policies the permission policies — either one set shared by every
|
|
353
|
+
* chain, or a `(chainId) => policies` factory to scope each chain's key to
|
|
354
|
+
* its OWN settlement tokens (the cross-network union overflows Tempo's
|
|
355
|
+
* enable-gas ceiling, see MAX_CALLPOLICY_PERMISSIONS)
|
|
358
356
|
*/
|
|
359
|
-
export declare function createSessionKeysForNetworks(signer: Signer, publicClientByChainId: Record<number, any>, policies:
|
|
357
|
+
export declare function createSessionKeysForNetworks(signer: Signer, publicClientByChainId: Record<number, any>, policies: PoliciesFor, requiredChainId?: number): Promise<Record<number, string>>;
|
|
360
358
|
/**
|
|
361
359
|
* The canonical, CREATE2-deterministic Kernel v3.3 implementation that an EOA
|
|
362
360
|
* delegates to under EIP-7702 (same address on Base mainnet + Base Sepolia).
|
|
@@ -390,7 +388,24 @@ export declare function getSessionKey(serializedSessionKey: string, publicClient
|
|
|
390
388
|
* @param policies Array of policies to enforce for this session key
|
|
391
389
|
* @returns Serialized session key string
|
|
392
390
|
*/
|
|
393
|
-
export declare function createDelegatedSessionKeyFromKernel(kernelAccount: SmartAccount, publicClient: PublicClient, policies: any[], kernelVersion?: KernelVersion): Promise<string>;
|
|
391
|
+
export declare function createDelegatedSessionKeyFromKernel(kernelAccount: SmartAccount, publicClient: PublicClient, policies: any[], kernelVersion?: KernelVersion, existingSessionPrivateKey?: `0x${string}`): Promise<string>;
|
|
392
|
+
/**
|
|
393
|
+
* Multi-network session keys for an EIP-7702 account — the v2 sibling of
|
|
394
|
+
* {@link createSessionKeysForNetworks}.
|
|
395
|
+
*
|
|
396
|
+
* The 7702 path used to mint single-network (primary only), so once a user
|
|
397
|
+
* migrated, EVERY key the backend issued rejected any secondary network with
|
|
398
|
+
* `BCK.APIKEY.0017`. Like the v1 helper this generates ONE session private key
|
|
399
|
+
* and serializes it once per chain, since the enable signature is chain-bound.
|
|
400
|
+
*
|
|
401
|
+
* The 7702 account is re-derived per chain from `signer`: the delegated EOA has
|
|
402
|
+
* the same address everywhere, but the permission validator must be built
|
|
403
|
+
* against THAT chain's client for its enable signature to validate there.
|
|
404
|
+
*
|
|
405
|
+
* Same best-effort contract as the v1 helper: a secondary network whose RPC is
|
|
406
|
+
* unreachable is skipped with a warning; `requiredChainId` always throws.
|
|
407
|
+
*/
|
|
408
|
+
export declare function createDelegatedSessionKeysForNetworks(signer: Signer, publicClientByChainId: Record<number, any>, policies: PoliciesFor, kernelVersion?: KernelVersion, requiredChainId?: number): Promise<Record<number, string>>;
|
|
394
409
|
export declare const WalletUtils: {
|
|
395
410
|
makeWallet: typeof makeWallet;
|
|
396
411
|
makeWallets: typeof makeWallets;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlockchainViemUtils.d.ts","sourceRoot":"","sources":["../../../src/nevermined/utils/BlockchainViemUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AAOjE,OAAO,EAML,mBAAmB,EAEpB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,WAAW,EACX,WAAW,EAGZ,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,OAAO,EAYP,KAAK,GAAG,EACR,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,2BAA2B,EAChC,KAAK,kBAAkB,EACxB,MAAM,MAAM,CAAA;AACb,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAQvD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAA;AAG9F,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAI3C;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,YAAY;gBACvC,MAAM,EAAE,kBAAkB;CAIvC;AAaD;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CAAC,EAC1C,MAAM,EACN,YAAY,GACb,EAAE;IACD,MAAM,EAAE,KAAK,MAAM,EAAE,CAAA;IACrB,YAAY,EAAE,YAAY,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAa9B;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAM/F;AAID;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,GAAG,EAAO,GAAG,WAAW,CAM3F;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,CASpE;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,GAAG,EAAO,GAAG,WAAW,CAEhG;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,GAAG,EAAO,0CAE/E;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,GAAG,EAAO;;;IAOxF;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAEpD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,MAAM,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,iBAElD;AAGD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,SAAI,GAAG,OAAO,CAExE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,SAAK,aAM/D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAG1C;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,SAAK,GAAG,OAAO,EAAE,CAG7D;AAID;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,CAGvE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,CAEnE;AAID;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,MAAM,EACf,aAAa,UAAQ,GACpB,MAAM,CAaR;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,aAAa,EAAE,GAAG,EAClB,aAAa,EAAE,GAAG,GACjB,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAA;CAAE,CAAC,CAKjE;
|
|
1
|
+
{"version":3,"file":"BlockchainViemUtils.d.ts","sourceRoot":"","sources":["../../../src/nevermined/utils/BlockchainViemUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ import { encodeAbiParameters, getAbiItem, getAddress, getContract, http, isAddre
|
|
|
7
7
|
import { english, generateMnemonic, generatePrivateKey, mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
|
|
8
8
|
import { Instantiable } from '../../Instantiable.abstract.js';
|
|
9
9
|
import { ContractsError } from '../../errors/NeverminedErrors.js';
|
|
10
|
-
import { getChain
|
|
10
|
+
import { getChain } from '../../utils/Network.js';
|
|
11
11
|
const ENTRY_POINT_VERSION = '0.7';
|
|
12
12
|
/**
|
|
13
13
|
* Utility class with methods that allow the interaction with the blockchain.
|
|
@@ -283,32 +283,6 @@ const TRANSACTION_RECEIPT_POLLING_INTERVAL_MS = 1_500;
|
|
|
283
283
|
}
|
|
284
284
|
return getUserOperationGasPrice(bundlerClient);
|
|
285
285
|
}
|
|
286
|
-
// Tempo undersizes the ZeroDev bundler's `verificationGasLimit` estimate (cold
|
|
287
|
-
// SCA deploy + session-key enable under TIP-20 gas), so `zd_sponsorUserOperation`
|
|
288
|
-
// re-simulates with that too-low ceiling and reverts `AA26 over
|
|
289
|
-
// verificationGasLimit` (see #1929, staging createPlan on tempo-moderato). We give
|
|
290
|
-
// the sponsor an explicit floor so it stops undersizing. A multiplier is useless
|
|
291
|
-
// here — viem calls getPaymasterData with verificationGasLimit still 0/undefined,
|
|
292
|
-
// so `x * n` is 0. An absolute floor covers both the 0 and the too-low cases.
|
|
293
|
-
// NOTE(#1929): fixed floor — bump if a Tempo op still AA26s (env-tunable if it ever needs per-deploy calibration).
|
|
294
|
-
// needs per-deploy calibration).
|
|
295
|
-
const TEMPO_MIN_VERIFICATION_GAS = 30_000_000n;
|
|
296
|
-
/**
|
|
297
|
-
* Floors `verificationGasLimit` on Tempo networks before the UserOp is handed to
|
|
298
|
-
* the ZeroDev paymaster, so `zd_sponsorUserOperation` has headroom and does not
|
|
299
|
-
* revert AA26. No-op on every other network. Shared by both paymaster sponsor
|
|
300
|
-
* call sites. Generic so the caller's UserOp type is preserved; typing
|
|
301
|
-
* `verificationGasLimit?: bigint` also turns a plain-number literal (a `bigint`
|
|
302
|
-
* missing its `n`) into a compile error instead of a silent floor-to-30M.
|
|
303
|
-
*/ export function applyTempoVerificationGasFloor(userOperation, chainId) {
|
|
304
|
-
if (!isTempoNetwork(chainId)) return userOperation;
|
|
305
|
-
const current = typeof userOperation.verificationGasLimit === 'bigint' ? userOperation.verificationGasLimit : 0n;
|
|
306
|
-
const floored = current > TEMPO_MIN_VERIFICATION_GAS ? current : TEMPO_MIN_VERIFICATION_GAS;
|
|
307
|
-
return {
|
|
308
|
-
...userOperation,
|
|
309
|
-
verificationGasLimit: floored
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
286
|
/**
|
|
313
287
|
* It creates a ZeroDev Kernel client.
|
|
314
288
|
* @param signer the signer account
|
|
@@ -334,7 +308,7 @@ const TEMPO_MIN_VERIFICATION_GAS = 30_000_000n;
|
|
|
334
308
|
transport: http(paymasterRpc)
|
|
335
309
|
});
|
|
336
310
|
return zerodevPaymaster.sponsorUserOperation({
|
|
337
|
-
userOperation
|
|
311
|
+
userOperation
|
|
338
312
|
});
|
|
339
313
|
}
|
|
340
314
|
}
|
|
@@ -509,6 +483,7 @@ export async function createSessionKey(signer, publicClient, policies, ecdsaVali
|
|
|
509
483
|
// why one serialization only validates on the chain it was made for. #1929
|
|
510
484
|
return serializePermissionAccount(sessionKeyAccount, sessionPrivateKey);
|
|
511
485
|
}
|
|
486
|
+
const policiesForChain = (policies, chainId)=>typeof policies === 'function' ? policies(chainId) : policies;
|
|
512
487
|
/**
|
|
513
488
|
* Multi-network session keys (#1929). Generates ONE session private key and
|
|
514
489
|
* serializes the permission account once per network — each serialization
|
|
@@ -524,14 +499,17 @@ export async function createSessionKey(signer, publicClient, policies, ecdsaVali
|
|
|
524
499
|
* @param signer the smart-account owner (e.g. the Privy EOA) — signs each
|
|
525
500
|
* network's enable signature
|
|
526
501
|
* @param publicClientByChainId map of chainId → a PublicClient for that chain
|
|
527
|
-
* @param policies the permission policies
|
|
502
|
+
* @param policies the permission policies — either one set shared by every
|
|
503
|
+
* chain, or a `(chainId) => policies` factory to scope each chain's key to
|
|
504
|
+
* its OWN settlement tokens (the cross-network union overflows Tempo's
|
|
505
|
+
* enable-gas ceiling, see MAX_CALLPOLICY_PERMISSIONS)
|
|
528
506
|
*/ export async function createSessionKeysForNetworks(signer, publicClientByChainId, policies, requiredChainId) {
|
|
529
507
|
const sessionPrivateKey = generatePrivateKey();
|
|
530
508
|
const out = {};
|
|
531
509
|
for (const [chainIdStr, publicClient] of Object.entries(publicClientByChainId)){
|
|
532
510
|
const chainId = Number(chainIdStr);
|
|
533
511
|
try {
|
|
534
|
-
out[chainId] = await createSessionKey(signer, publicClient, policies, undefined, sessionPrivateKey);
|
|
512
|
+
out[chainId] = await createSessionKey(signer, publicClient, policiesForChain(policies, chainId), undefined, sessionPrivateKey);
|
|
535
513
|
} catch (err) {
|
|
536
514
|
// Best-effort: a secondary network whose RPC is unreachable must not break
|
|
537
515
|
// key generation (e.g. login). `requiredChainId` (the primary) still throws.
|
|
@@ -594,9 +572,11 @@ export async function getSessionKey(serializedSessionKey, publicClient, kernelVe
|
|
|
594
572
|
* @param publicClient Viem PublicClient instance
|
|
595
573
|
* @param policies Array of policies to enforce for this session key
|
|
596
574
|
* @returns Serialized session key string
|
|
597
|
-
*/ export async function createDelegatedSessionKeyFromKernel(kernelAccount, publicClient, policies, kernelVersion = KERNEL_V3_1) {
|
|
598
|
-
// 1)
|
|
599
|
-
|
|
575
|
+
*/ export async function createDelegatedSessionKeyFromKernel(kernelAccount, publicClient, policies, kernelVersion = KERNEL_V3_1, existingSessionPrivateKey) {
|
|
576
|
+
// 1) Ephemeral session private key (used only for the permission plugin). A
|
|
577
|
+
// multi-network mint passes the SAME key for every chain so one API key
|
|
578
|
+
// carries one session key with a per-chain enable signature.
|
|
579
|
+
const sessionPrivateKey = existingSessionPrivateKey ?? generatePrivateKey();
|
|
600
580
|
const sessionAccount = privateKeyToAccount(sessionPrivateKey);
|
|
601
581
|
// 2) Wrap ephemeral key as ECDSA signer for permissions
|
|
602
582
|
const sessionKeySigner = await toECDSASigner({
|
|
@@ -634,6 +614,41 @@ export async function getSessionKey(serializedSessionKey, publicClient, kernelVe
|
|
|
634
614
|
const serialized = await serializePermissionAccount(sessionKeyAccount, sessionPrivateKey);
|
|
635
615
|
return serialized;
|
|
636
616
|
}
|
|
617
|
+
/**
|
|
618
|
+
* Multi-network session keys for an EIP-7702 account — the v2 sibling of
|
|
619
|
+
* {@link createSessionKeysForNetworks}.
|
|
620
|
+
*
|
|
621
|
+
* The 7702 path used to mint single-network (primary only), so once a user
|
|
622
|
+
* migrated, EVERY key the backend issued rejected any secondary network with
|
|
623
|
+
* `BCK.APIKEY.0017`. Like the v1 helper this generates ONE session private key
|
|
624
|
+
* and serializes it once per chain, since the enable signature is chain-bound.
|
|
625
|
+
*
|
|
626
|
+
* The 7702 account is re-derived per chain from `signer`: the delegated EOA has
|
|
627
|
+
* the same address everywhere, but the permission validator must be built
|
|
628
|
+
* against THAT chain's client for its enable signature to validate there.
|
|
629
|
+
*
|
|
630
|
+
* Same best-effort contract as the v1 helper: a secondary network whose RPC is
|
|
631
|
+
* unreachable is skipped with a warning; `requiredChainId` always throws.
|
|
632
|
+
*/ export async function createDelegatedSessionKeysForNetworks(signer, publicClientByChainId, policies, kernelVersion = KERNEL_V3_3, requiredChainId) {
|
|
633
|
+
const sessionPrivateKey = generatePrivateKey();
|
|
634
|
+
const out = {};
|
|
635
|
+
for (const [chainIdStr, publicClient] of Object.entries(publicClientByChainId)){
|
|
636
|
+
const chainId = Number(chainIdStr);
|
|
637
|
+
try {
|
|
638
|
+
const account = await createKernel7702Account(signer, publicClient);
|
|
639
|
+
out[chainId] = await createDelegatedSessionKeyFromKernel(account, publicClient, policiesForChain(policies, chainId), kernelVersion, sessionPrivateKey);
|
|
640
|
+
} catch (err) {
|
|
641
|
+
if (requiredChainId != null && chainId === Number(requiredChainId)) throw err;
|
|
642
|
+
console.warn(`[createDelegatedSessionKeysForNetworks] skipping network ${chainId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
// Mirrors the v1 helper: enforce the contract even when the required chain is
|
|
646
|
+
// ABSENT from the map, so a caller never reads `out[primary]` === undefined.
|
|
647
|
+
if (requiredChainId != null && out[requiredChainId] == null) {
|
|
648
|
+
throw new Error(`createDelegatedSessionKeysForNetworks: required network ${requiredChainId} was not in the public-client map`);
|
|
649
|
+
}
|
|
650
|
+
return out;
|
|
651
|
+
}
|
|
637
652
|
export const WalletUtils = {
|
|
638
653
|
makeWallet,
|
|
639
654
|
makeWallets,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/nevermined/utils/BlockchainViemUtils.ts"],"sourcesContent":["import { signerToEcdsaValidator } from '@zerodev/ecdsa-validator'\nimport {\n deserializePermissionAccount,\n serializePermissionAccount,\n toPermissionValidator,\n} from '@zerodev/permissions'\nimport { toECDSASigner } from '@zerodev/permissions/signers'\nimport {\n addressToEmptyAccount,\n createKernelAccount,\n createKernelAccountClient,\n createZeroDevPaymasterClient,\n getUserOperationGasPrice,\n KernelAccountClient,\n type KernelSmartAccountImplementation,\n} from '@zerodev/sdk'\nimport {\n KERNEL_V3_1,\n KERNEL_V3_3,\n KERNEL_7702_DELEGATION_ADDRESS,\n getEntryPoint,\n} from '@zerodev/sdk/constants'\nimport {\n Address,\n encodeAbiParameters,\n getAbiItem,\n getAddress,\n getContract,\n http,\n isAddress,\n pad,\n stringToBytes,\n stringToHex,\n toBytes,\n keccak256 as viemKeccak256,\n type Abi,\n type AbiEvent,\n type AbiFunction,\n type Account,\n type PublicClient,\n type SignAuthorizationReturnType,\n type TransactionReceipt,\n} from 'viem'\nimport { SmartAccount } from 'viem/account-abstraction'\nimport {\n english,\n generateMnemonic,\n generatePrivateKey,\n mnemonicToAccount,\n privateKeyToAccount,\n} from 'viem/accounts'\nimport { Instantiable, InstantiableConfig, Web3Clients } from '../../Instantiable.abstract.js'\nimport { ContractsError } from '../../errors/NeverminedErrors.js'\nimport { getChain, isTempoNetwork } from '../../utils/Network.js'\nimport { Signer } from '@zerodev/sdk/types'\n\nconst ENTRY_POINT_VERSION = '0.7'\n\n/**\n * Utility class with methods that allow the interaction with the blockchain.\n * This class uses Viem library to interact with the blockchain.\n */\nexport class BlockchainViemUtils extends Instantiable {\n constructor(config: InstantiableConfig) {\n super()\n this.setInstanceConfig(config)\n }\n}\n\n//////////////////////////\n///// UTILITIES //////////\n//////////////////////////\n\n///// CONTRACTS\n\n// Wait budget for an L2 block to be mined and the receipt to surface.\n// Base / Base Sepolia block time is ~2s; 30s ≈ 15 blocks of headroom.\nconst TRANSACTION_RECEIPT_TIMEOUT_MS = 30_000\nconst TRANSACTION_RECEIPT_POLLING_INTERVAL_MS = 1_500\n\n/**\n * Given a transaction hash, it returns the transaction receipt.\n * Uses viem's `waitForTransactionReceipt` which polls until the receipt is\n * available, retrying on `TransactionReceiptNotFoundError` and handling\n * tx-replacement / reorgs natively.\n * @param txHash - the transaction hash\n * @returns the transaction receipt\n */\nexport async function getTransactionReceipt({\n txHash,\n publicClient,\n}: {\n txHash: `0x${string}`\n publicClient: PublicClient\n iteration?: number\n}): Promise<TransactionReceipt> {\n try {\n return await publicClient.waitForTransactionReceipt({\n hash: txHash,\n timeout: TRANSACTION_RECEIPT_TIMEOUT_MS,\n pollingInterval: TRANSACTION_RECEIPT_POLLING_INTERVAL_MS,\n confirmations: 1,\n })\n } catch (error) {\n throw new ContractsError(\n `Unable to get transaction receipt with hash: ${txHash}. Error: ${error}`,\n )\n }\n}\n\n/**\n * Given an already deployed contract address and the ABI, it returns the contract instance.\n *\n * @param contractAddress - the contract address\n * @param abi - the contract artifact\n * @param client - the client to interact with the blockchain\n * @returns a contract instance\n */\nexport async function getContractInstance(contractAddress: string, abi: Abi, client: Web3Clients) {\n return getContract({\n abi,\n address: contractAddress as `0x${string}`,\n client: { wallet: client.wallet, public: client.public },\n })\n}\n\n///// ABIs\n\n/**\n * It searchs an ABI function in the ABI.\n * @param abi the ABI of the contract\n * @param funcName the function name\n * @param args the args of the function\n * @returns the function found\n */\nexport function searchAbiFunction(abi: Abi, funcName: string, args: any[] = []): AbiFunction {\n const func = getAbiItem({ abi, name: funcName, args })\n if (!func || func.type !== 'function') {\n throw new ContractsError(`Function \"${funcName}\" is not part of contract`)\n }\n return func as AbiFunction\n}\n\n/**\n * It searchs an ABI event in the ABI.\n * @param abi the ABI of the contract\n * @param funcName the event name\n * @returns the event found\n */\nexport function searchAbiEvent(abi: Abi, eventName: string): AbiEvent {\n const event = getAbiItem({\n abi,\n name: eventName,\n })\n if (!event || event.type !== 'event') {\n throw new ContractsError(`Event \"${event}\" is not part of contract`)\n }\n return event as AbiEvent\n}\n\n/**\n * It searchs an ABI function in the ABI.\n * @param abi the ABI of the contract\n * @param funcName the function name\n * @param args the args of the function\n * @returns the function found\n */\nexport function getSignatureOfFunction(abi: Abi, funcName: string, args: any[] = []): AbiFunction {\n return searchAbiFunction(abi, funcName, args)\n}\n\n/**\n * It searchs an ABI function in the ABI and return the inputs.\n * @param abi the ABI of the contract\n * @param funcName the function name\n * @param args the args of the function\n * @returns the function found\n */\nexport function getInputsOfFunction(abi: Abi, funcName: string, args: any[] = []) {\n return searchAbiFunction(abi, funcName, args).inputs\n}\n\n/**\n * It searchs an ABI function in the ABI and return the inputs formatted.\n * @param abi the ABI of the contract\n * @param funcName the function name\n * @param args the args of the function\n * @returns the function found\n */\nexport function getInputsOfFunctionFormatted(abi: Abi, funcName: string, args: any[] = []) {\n return searchAbiFunction(abi, funcName, args).inputs.map((input, i) => {\n return {\n name: input.name,\n value: args[i],\n }\n })\n}\n\n//////// UTILS\n\n/**\n * Given an address it returns that address in checksum format.\n * @param address the address\n * @returns the same address in checksum format\n */\nexport function getChecksumAddress(address: string): string {\n return getAddress(address)\n}\n\n/**\n * It checks if the address is a valid address.\n * @param address the address to check\n * @returns true of the address is valid\n */\nexport function isValidAddress(address: string): boolean {\n return isAddress(address)\n}\n\n/**\n * Encodes a UTF-8 string into a byte array.\n\n * @param message the string to encode\n * @returns the encoded byte array\n */\nexport function getBytes(message: string): Uint8Array {\n return stringToBytes(message)\n}\n\n/**\n * It pads a value with zeros.\n * @param value the value to pad\n * @param length the expected longitutde of the value\n * @returns the padded value\n */\nexport function zeroPadValue(value: `0x${string}` | Uint8Array, length: number): string {\n return pad(value, { size: length }) as `0x${string}`\n}\n\n/**\n * Encodes a UTF-8 string into a hex string\n * @param message the string to encode\n * @returns the hex string\n */\nexport function encodeBytes32String(message: string) {\n return stringToHex(message, { size: 32 })\n}\n\n////// ACCOUNTS\n/**\n * Given a seedphrase, it returns an account.\n * @param seedphrase - the seedphrase to be used to generate the account\n * @param addressIndex - the address index\n * @returns an account\n */\nexport function makeWallet(seedphrase: string, addressIndex = 0): Account {\n return mnemonicToAccount(seedphrase, { addressIndex })\n}\n\n/**\n * Given a seedphrase generates multiple accounts\n * @param seedphrase - the seedphrase to be used to generate the account\n * @param numAccounts - the number of accounts to create\n * @returns the array of accounts\n */\nexport function makeWallets(seedphrase: string, numAccounts = 10) {\n const accounts: Account[] = []\n for (let i = 0; i < numAccounts; i++) {\n accounts.push(makeWallet(seedphrase, i))\n }\n return accounts\n}\n\n/**\n * It generates a random account.\n * @returns a new account\n */\nexport function makeRandomWallet(): Account {\n const mnemonic = generateMnemonic(english)\n return makeWallet(mnemonic)\n}\n\n/**\n * It generates a list of random accounts\n * @param numAccounts - the number of accounts to create\n * @returns the array of accounts\n */\nexport function makeRandomWallets(numAccounts = 10): Account[] {\n const mnemonic = generateMnemonic(english)\n return makeWallets(mnemonic, numAccounts)\n}\n\n/////// HASHES\n\n/**\n * It hashes a string using keccak256.\n * @param seed the string to hash\n * @returns the hash\n */\nexport function keccak256(seed: string): string {\n return viemKeccak256(toBytes(seed))\n}\n\n/**\n * It encodes and hashes a list of primitive values into an ABI-encoded hex value.\n * @param types the types of the values\n * @param values the values to encode\n * @returns the hash\n */\nexport function keccak256WithEncode(types: any[], values: any[]): string {\n const encoded = encodeAbiParameters(types, values as never)\n return keccak256(encoded)\n}\n\n/**\n * It encodes and hashes a list of primitive values into an ABI-encoded hex value.\n * @param types the types of the values\n * @param values the values to encode\n * @returns the hash\n */\nexport function keccak256Packed(types: any[], values: any[]): string {\n return keccak256WithEncode(types, values)\n}\n\n/////// ZERO DEV\n\n/**\n * Returns the bundler RPC URL. When `BUNDLER_RPC_URL_OVERRIDE` is set\n * (used by tests against a local Alto + anvil-fork stack), it takes precedence\n * over the canonical ZeroDev URL. When `useUltraRelay` is true, the production\n * URL is routed through ZeroDev's UltraRelay (`?provider=ULTRA_RELAY`); the\n * override branch is left untouched.\n * @param useUltraRelay - when true, append `?provider=ULTRA_RELAY` to route the\n * UserOperation through ZeroDev's UltraRelay bundler tier. Ignored when\n * `BUNDLER_RPC_URL_OVERRIDE` is set.\n */\nexport function getBundlerRpcUrl(\n zeroDevProjectId: string,\n chainId: number,\n useUltraRelay = false,\n): string {\n const base = `https://rpc.zerodev.app/api/v3/${zeroDevProjectId}/chain/${chainId}`\n // Per-chain override wins, then the global override, then the canonical URL.\n // The per-chain form (`BUNDLER_RPC_URL_OVERRIDE_<chainId>`) lets a single\n // process route UserOps for different networks to different local bundlers —\n // e.g. a dual-fork dev stack (base-sepolia bundler :4337 + tempo bundler\n // :4338). `||` (not `??`) because Vite replaces missing browser env vars with\n // the empty string at build time; an empty override is equivalent to none.\n return (\n process.env[`BUNDLER_RPC_URL_OVERRIDE_${chainId}`] ||\n process.env.BUNDLER_RPC_URL_OVERRIDE ||\n (useUltraRelay ? `${base}?provider=ULTRA_RELAY` : base)\n )\n}\n\n/**\n * Returns the paymaster RPC URL (ZeroDev-only; the local fork stack uses\n * `ultra-relay` which sponsors via the bundler's executor key without a\n * paymaster, so this URL is not consulted when `BUNDLER_RPC_URL_OVERRIDE` is\n * set).\n */\nexport function getPaymasterRpcUrl(zeroDevProjectId: string, chainId: number): string {\n return `https://rpc.zerodev.app/api/v3/${zeroDevProjectId}/chain/${chainId}`\n}\n\n/**\n * Returns true when the kernel client should run in \"relayer mode\" — no\n * paymaster, gas fees zeroed out. Used by tests against a local\n * `ultra-relay` (ZeroDev's fork of Alto) on top of an anvil-fork. The relayer's\n * executor key pays gas directly via `EntryPoint.handleOps`, avoiding the\n * paymaster sponsorship handshake altogether.\n */\nexport function isRelayerMode(): boolean {\n return Boolean(process.env.BUNDLER_RPC_URL_OVERRIDE)\n}\n\n/**\n * Returns gas prices for UserOperation fee estimation. ZeroDev's bundler\n * exposes a custom `zd_getUserOperationGasPrice` method; standard ERC-4337\n * bundlers do not. In relayer mode the bundler accepts UserOps with zeroed\n * `maxFeePerGas`/`maxPriorityFeePerGas` and pays gas itself.\n */\nexport async function estimateUserOperationFees(\n bundlerClient: any,\n _publicClient: any,\n): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }> {\n if (isRelayerMode()) {\n return { maxFeePerGas: 0n, maxPriorityFeePerGas: 0n }\n }\n return getUserOperationGasPrice(bundlerClient)\n}\n\n// Tempo undersizes the ZeroDev bundler's `verificationGasLimit` estimate (cold\n// SCA deploy + session-key enable under TIP-20 gas), so `zd_sponsorUserOperation`\n// re-simulates with that too-low ceiling and reverts `AA26 over\n// verificationGasLimit` (see #1929, staging createPlan on tempo-moderato). We give\n// the sponsor an explicit floor so it stops undersizing. A multiplier is useless\n// here — viem calls getPaymasterData with verificationGasLimit still 0/undefined,\n// so `x * n` is 0. An absolute floor covers both the 0 and the too-low cases.\n// NOTE(#1929): fixed floor — bump if a Tempo op still AA26s (env-tunable if it ever needs per-deploy calibration).\n// needs per-deploy calibration).\nconst TEMPO_MIN_VERIFICATION_GAS = 30_000_000n\n\n/**\n * Floors `verificationGasLimit` on Tempo networks before the UserOp is handed to\n * the ZeroDev paymaster, so `zd_sponsorUserOperation` has headroom and does not\n * revert AA26. No-op on every other network. Shared by both paymaster sponsor\n * call sites. Generic so the caller's UserOp type is preserved; typing\n * `verificationGasLimit?: bigint` also turns a plain-number literal (a `bigint`\n * missing its `n`) into a compile error instead of a silent floor-to-30M.\n */\nexport function applyTempoVerificationGasFloor<T extends { verificationGasLimit?: bigint }>(\n userOperation: T,\n chainId: number,\n): T {\n if (!isTempoNetwork(chainId)) return userOperation\n const current =\n typeof userOperation.verificationGasLimit === 'bigint' ? userOperation.verificationGasLimit : 0n\n const floored = current > TEMPO_MIN_VERIFICATION_GAS ? current : TEMPO_MIN_VERIFICATION_GAS\n return { ...userOperation, verificationGasLimit: floored } as T\n}\n\n/**\n * It creates a ZeroDev Kernel client.\n * @param signer the signer account\n * @param chainId the chain id\n * @param zeroDevProjectId the zero dev project id, you can get it from the ZeroDev dashboard\n * @param useUltraRelay forwarded straight to `getBundlerRpcUrl` — when true the\n * bundler RPC is routed through ZeroDev's UltraRelay. Ignored when\n * `BUNDLER_RPC_URL_OVERRIDE` is set.\n * @returns the kernel client\n */\nexport async function createKernelClient(\n kernelAccount: SmartAccount,\n chainId: number,\n zeroDevProjectId: string,\n publicClient: any,\n useUltraRelay = false,\n): Promise<KernelAccountClient> {\n const bundlerRpc = getBundlerRpcUrl(zeroDevProjectId, chainId, useUltraRelay)\n const paymasterRpc = getPaymasterRpcUrl(zeroDevProjectId, chainId)\n\n return createKernelAccountClient({\n account: kernelAccount,\n chain: getChain(chainId),\n bundlerTransport: http(bundlerRpc),\n client: publicClient,\n ...(isRelayerMode()\n ? {}\n : {\n paymaster: {\n getPaymasterData: (userOperation: any) => {\n const zerodevPaymaster = createZeroDevPaymasterClient({\n chain: getChain(chainId),\n transport: http(paymasterRpc),\n })\n return zerodevPaymaster.sponsorUserOperation({\n userOperation: applyTempoVerificationGasFloor(userOperation, chainId),\n })\n },\n },\n }),\n userOperation: {\n estimateFeesPerGas: async ({ bundlerClient }) => {\n return estimateUserOperationFees(bundlerClient, publicClient)\n },\n },\n })\n}\n\nexport type EcdsaValidator = Awaited<ReturnType<typeof signerToEcdsaValidator>>\n\n/**\n * Identifies the smart-account derivation inputs (entryPoint + kernel version).\n * The SCA is deterministic from `(EOA, entryPoint, kernelVersion, index)`, so a\n * bump here means the same EOA derives a different SCA. Persisted SCA caches\n * (e.g. the webapp's localStorage) should stamp this and invalidate on change.\n */\nexport const SCA_DERIVATION_VERSION = `${ENTRY_POINT_VERSION}:${KERNEL_V3_1}`\n\n// ponytail: in-process memo for ZeroDev Kernel account resolution. Every\n// deserializePermissionAccount / createKernelAccount reads the EIP-1967 impl\n// slot (eth_getStorageAt) of a deployed account — ~56% of backend Infura RPC\n// volume, and the same session key/owner is re-resolved per request and twice\n// per x402 payment (verify + settle). See #2206. Safe to reuse the resolved\n// account: the Kernel account fetches its nonce fresh at send time, so a cached\n// account never signs against a stale nonce. Keyed by the deterministic inputs\n// (serialized key / owner + kernel version + chainId); short TTL bounds\n// staleness across a kernel upgrade. Single-process only — cross-pod dedup is\n// out of scope (#2206 notes). Upgrade path: swap the Map for a shared store.\nconst ACCOUNT_CACHE_TTL_MS = 60_000\n// Bound the cache: `getSessionKey` runs behind `getAccountAttributes` on every\n// authenticated request, keyed per-API-key, so an entry never re-requested\n// would otherwise sit past its TTL for the life of the (long-lived) apps/api\n// process — a slow leak. Cardinality ≈ distinct API keys ever seen; cap + sweep\n// keep it bounded (matches BlockchainCacheService's MAX_ENTRIES + cleanup()).\nexport const ACCOUNT_CACHE_MAX_ENTRIES = 5_000\nconst accountResolutionCache = new Map<string, { value: Promise<unknown>; expiresAt: number }>()\n\nfunction memoResolveAccount<T>(key: string, resolver: () => Promise<T>): Promise<T> {\n const now = Date.now()\n const cached = accountResolutionCache.get(key)\n if (cached && cached.expiresAt > now) {\n return cached.value as Promise<T>\n }\n // Sweep expired entries + bound size so keys never re-requested don't\n // accumulate for the life of the process (Map keeps insertion order → FIFO).\n for (const [k, e] of accountResolutionCache) {\n if (e.expiresAt <= now) accountResolutionCache.delete(k)\n }\n if (accountResolutionCache.size >= ACCOUNT_CACHE_MAX_ENTRIES) {\n accountResolutionCache.delete(accountResolutionCache.keys().next().value as string)\n }\n const entry: { value: Promise<unknown>; expiresAt: number } = {\n value: undefined as unknown as Promise<unknown>,\n expiresAt: now + ACCOUNT_CACHE_TTL_MS,\n }\n // Coalesce concurrent identical resolutions; evict on rejection so a transient\n // RPC failure isn't cached — but only if this exact entry is still current, so\n // a resolver that hangs past its TTL and then rejects can't drop a newer one.\n entry.value = resolver().catch((err) => {\n if (accountResolutionCache.get(key) === entry) accountResolutionCache.delete(key)\n throw err\n })\n accountResolutionCache.set(key, entry)\n return entry.value as Promise<T>\n}\n\n/** Current entry count of the Kernel account-resolution memo (#2206). */\nexport function getAccountResolutionCacheStats() {\n return { size: accountResolutionCache.size }\n}\n\n/** Clear the account-resolution memo (test isolation / kernel-upgrade invalidation). */\nexport function clearAccountResolutionCache() {\n accountResolutionCache.clear()\n}\n\nfunction chainIdOf(publicClient: any): string | number {\n const id = publicClient?.chain?.id\n // chainId is the ONLY discriminator in the sca:/7702:/sk: keys, and SCA /\n // session-key addresses are identical across chains by CREATE2 design — so an\n // id-less client must fail closed rather than alias two networks under one\n // bucket and serve a chain-A account to a chain-B request (latent until #1933).\n if (id == null) {\n throw new Error('account-resolution cache: publicClient.chain.id is required for keying')\n }\n return id\n}\n\n/**\n * Build the ECDSA sudo validator for a signer. Both `createKernelSmartAccount`\n * and `createSessionKey` need this validator and each derives it via a ZeroDev\n * RPC round-trip. Callers that run both in sequence (e.g. the webapp API-key\n * creation path) can compute it once here and pass it into both helpers to\n * avoid the redundant round-trip.\n *\n * @param ecdsaValidator (on the consumers) must be one built for the SAME\n * `signer` — passing a validator derived from a different signer would attach\n * the wrong owner to the account.\n */\nexport async function createEcdsaValidator(\n signer: Signer,\n publicClient: PublicClient,\n): Promise<EcdsaValidator> {\n return signerToEcdsaValidator(publicClient, {\n signer,\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n kernelVersion: KERNEL_V3_1,\n })\n}\n\nexport async function createKernelSmartAccount(\n signer: Signer,\n publicClient: PublicClient,\n ecdsaValidator?: EcdsaValidator,\n): Promise<SmartAccount> {\n const build = async () => {\n const validator = ecdsaValidator ?? (await createEcdsaValidator(signer, publicClient))\n return createKernelAccount(publicClient, {\n plugins: {\n sudo: validator,\n },\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n kernelVersion: KERNEL_V3_1,\n })\n }\n // A caller-supplied validator isn't part of the key — bypass the memo (like\n // createKernel7702Account does for eip7702Auth) rather than let a cache entry\n // built by a different call silently ignore it (the mismatch createEcdsaValidator warns about).\n if (ecdsaValidator) return build()\n return memoResolveAccount(\n `sca:${chainIdOf(publicClient)}:${SCA_DERIVATION_VERSION}:${signer.address}`,\n build,\n )\n}\n\nexport async function getApproval(signer: Signer, publicClient: any, policies: any[]) {\n const ecdsaValidator = await signerToEcdsaValidator(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n signer,\n kernelVersion: KERNEL_V3_1,\n })\n const emptyAccount = addressToEmptyAccount(signer.address as Address)\n const emptySessionKeySigner = await toECDSASigner({ signer: emptyAccount })\n\n const permissionPlugin = await toPermissionValidator(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n signer: emptySessionKeySigner,\n policies: policies,\n kernelVersion: KERNEL_V3_1,\n })\n const sessionKeyAccount = await createKernelAccount(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n plugins: {\n sudo: ecdsaValidator,\n regular: permissionPlugin,\n },\n kernelVersion: KERNEL_V3_1,\n })\n\n return await serializePermissionAccount(sessionKeyAccount)\n}\n\nexport async function useSessionKey(approval: string, signer: Signer, publicClient: any) {\n const sessionKeySigner = await toECDSASigner({\n signer,\n })\n const sessionKeyAccount = await deserializePermissionAccount(\n publicClient,\n getEntryPoint(ENTRY_POINT_VERSION),\n KERNEL_V3_1,\n approval,\n sessionKeySigner,\n )\n\n return sessionKeyAccount\n}\n\nexport async function createSessionKey(\n signer: Signer,\n publicClient: any,\n policies: any[],\n ecdsaValidator?: EcdsaValidator,\n sessionPrivateKey: `0x${string}` = generatePrivateKey(),\n) {\n const validator = ecdsaValidator ?? (await createEcdsaValidator(signer, publicClient))\n const masterAccount = privateKeyToAccount(sessionPrivateKey)\n const sessionKeySigner = await toECDSASigner({\n signer: masterAccount,\n })\n\n const permissionPlugin = await toPermissionValidator(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n signer: sessionKeySigner,\n policies: policies,\n kernelVersion: KERNEL_V3_1,\n })\n\n const sessionKeyAccount = await createKernelAccount(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n plugins: {\n sudo: validator,\n regular: permissionPlugin,\n },\n kernelVersion: KERNEL_V3_1,\n })\n\n // serializePermissionAccount embeds the ENABLE signature for `publicClient`'s\n // chain (signed by the sudo/owner). That signature is chain-bound, which is\n // why one serialization only validates on the chain it was made for. #1929\n return serializePermissionAccount(sessionKeyAccount, sessionPrivateKey)\n}\n\n/**\n * Multi-network session keys (#1929). Generates ONE session private key and\n * serializes the permission account once per network — each serialization\n * carries that network's chain-bound enable signature. The SAME session key\n * works on every supported chain (the smart-account address + init code are\n * identical via CREATE2 parity); only the enable signature differs per chain.\n *\n * Use the returned map (chainId → serialized session key) to build a single\n * multi-network API key: the backend selects the entry for the operation's\n * network. Avoids the `EnableNotApproved` revert when an API key minted on one\n * chain is used on another.\n *\n * @param signer the smart-account owner (e.g. the Privy EOA) — signs each\n * network's enable signature\n * @param publicClientByChainId map of chainId → a PublicClient for that chain\n * @param policies the permission policies (same on every chain)\n */\nexport async function createSessionKeysForNetworks(\n signer: Signer,\n publicClientByChainId: Record<number, any>,\n policies: any[],\n requiredChainId?: number,\n): Promise<Record<number, string>> {\n const sessionPrivateKey = generatePrivateKey()\n const out: Record<number, string> = {}\n for (const [chainIdStr, publicClient] of Object.entries(publicClientByChainId)) {\n const chainId = Number(chainIdStr)\n try {\n out[chainId] = await createSessionKey(\n signer,\n publicClient,\n policies,\n undefined,\n sessionPrivateKey,\n )\n } catch (err) {\n // Best-effort: a secondary network whose RPC is unreachable must not break\n // key generation (e.g. login). `requiredChainId` (the primary) still throws.\n if (requiredChainId != null && chainId === Number(requiredChainId)) throw err\n console.warn(\n `[createSessionKeysForNetworks] skipping network ${chainId}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n }\n // Enforce the `requiredChainId` contract even when it is ABSENT from the input\n // map (the loop above only throws when it is present AND fails). Without this,\n // callers read `out[primary]` → undefined → an API key with no primary session\n // key, which fails opaquely downstream.\n if (requiredChainId != null && out[requiredChainId] == null) {\n throw new Error(\n `createSessionKeysForNetworks: required network ${requiredChainId} was not in the public-client map`,\n )\n }\n return out\n}\n\n/**\n * The canonical, CREATE2-deterministic Kernel v3.3 implementation that an EOA\n * delegates to under EIP-7702 (same address on Base mainnet + Base Sepolia).\n * This is the `contract`/`address` passed to Privy `sign7702Authorization` and\n * carried in the type-4 authorization. See #2148.\n */\nexport const KERNEL_7702_IMPL_ADDRESS = KERNEL_7702_DELEGATION_ADDRESS\n\n// The two Kernel versions the platform runs: v3.1 for the legacy counterfactual\n// SCA, v3.3 for the EIP-7702-delegated EOA account. Re-exported so the API\n// layer can pick the right version for (de)serializing session keys.\nexport { KERNEL_V3_1, KERNEL_V3_3 }\nexport type KernelVersion = typeof KERNEL_V3_1 | typeof KERNEL_V3_3\n\n/**\n * Resolves a user's EIP-7702 account: the Privy EOA delegated to Kernel v3.3.\n * The resulting account's address **equals the EOA** (no counterfactual SCA),\n * so it both signs EIP-3009 as a plain EOA (Router) and acts as a 4337 smart\n * account (credits/session-keys). `eip7702Auth` is the signed type-4\n * authorization (from Privy `sign7702Authorization`); omit it once the account\n * is already delegated on-chain.\n *\n * ponytail: on-chain correctness (delegation designator, UserOp submission)\n * is validated on Base Sepolia in Phase 0 (#2153); this wrapper only pins the\n * SDK call shape.\n */\nexport async function createKernel7702Account(\n signer: Signer,\n publicClient: PublicClient,\n eip7702Auth?: SignAuthorizationReturnType,\n): Promise<SmartAccount> {\n const build = () =>\n createKernelAccount(publicClient, {\n eip7702Account: signer,\n ...(eip7702Auth ? { eip7702Auth } : {}),\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n kernelVersion: KERNEL_V3_3,\n })\n // The install path (auth attached) is a one-time mutating op — never cache it.\n if (eip7702Auth) return build()\n return memoResolveAccount(`7702:${chainIdOf(publicClient)}:${signer.address}`, build)\n}\n\nexport async function getSessionKey(\n serializedSessionKey: string,\n publicClient: any,\n kernelVersion: KernelVersion = KERNEL_V3_1,\n) {\n return memoResolveAccount(\n `sk:${chainIdOf(publicClient)}:${kernelVersion}:${serializedSessionKey}`,\n () =>\n deserializePermissionAccount(\n publicClient,\n getEntryPoint(ENTRY_POINT_VERSION),\n kernelVersion,\n serializedSessionKey,\n ),\n )\n}\n\n/**\n * Creates a delegated session key for an existing kernel account.\n * The resulting serialized session key can be deserialized into a SmartAccount\n * that shares the same address as the kernel account but enforces the given policies.\n *\n * @param kernelAccount The existing SmartAccount (kernel) to delegate from\n * @param publicClient Viem PublicClient instance\n * @param policies Array of policies to enforce for this session key\n * @returns Serialized session key string\n */\nexport async function createDelegatedSessionKeyFromKernel(\n kernelAccount: SmartAccount,\n publicClient: PublicClient,\n policies: any[],\n kernelVersion: KernelVersion = KERNEL_V3_1,\n): Promise<string> {\n // 1) Generate ephemeral session private key (used only for the permission plugin)\n const sessionPrivateKey = generatePrivateKey()\n const sessionAccount = privateKeyToAccount(sessionPrivateKey)\n\n // 2) Wrap ephemeral key as ECDSA signer for permissions\n const sessionKeySigner = await toECDSASigner({ signer: sessionAccount })\n\n // 3) Create the permission validator plugin — MUST match the parent kernel's\n // version (v3.3 for a 7702 account, v3.1 for the legacy SCA), otherwise the\n // serialized blob deserializes/validates against the wrong kernel.\n const permissionValidator = await toPermissionValidator(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n signer: sessionKeySigner,\n policies,\n kernelVersion,\n })\n\n // 4) Extract the sudo validator from the existing kernel account\n const kernelAccountTyped = kernelAccount as SmartAccount<KernelSmartAccountImplementation>\n const sudoValidator = kernelAccountTyped.kernelPluginManager.sudoValidator\n\n if (!sudoValidator) {\n throw new Error('Kernel account does not have a sudo validator')\n }\n\n // 5) Create a new kernel account with both sudo (from original) and permission\n // validator, at the same address as the parent kernel. For a 7702 account\n // that address is the EOA; pinning `address` keeps the session-key account\n // on the same account rather than a fresh counterfactual one.\n const sessionKeyAccount = await createKernelAccount(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n address: kernelAccountTyped.address,\n plugins: {\n sudo: sudoValidator, // Use existing sudo validator\n regular: permissionValidator,\n },\n kernelVersion,\n })\n\n // 6) Serialize the session key account with the ephemeral private key\n const serialized = await serializePermissionAccount(sessionKeyAccount, sessionPrivateKey)\n\n return serialized\n}\n\nexport const WalletUtils = {\n makeWallet,\n makeWallets,\n makeRandomWallet,\n makeRandomWallets,\n}\n"],"names":["signerToEcdsaValidator","deserializePermissionAccount","serializePermissionAccount","toPermissionValidator","toECDSASigner","addressToEmptyAccount","createKernelAccount","createKernelAccountClient","createZeroDevPaymasterClient","getUserOperationGasPrice","KERNEL_V3_1","KERNEL_V3_3","KERNEL_7702_DELEGATION_ADDRESS","getEntryPoint","encodeAbiParameters","getAbiItem","getAddress","getContract","http","isAddress","pad","stringToBytes","stringToHex","toBytes","keccak256","viemKeccak256","english","generateMnemonic","generatePrivateKey","mnemonicToAccount","privateKeyToAccount","Instantiable","ContractsError","getChain","isTempoNetwork","ENTRY_POINT_VERSION","BlockchainViemUtils","config","setInstanceConfig","TRANSACTION_RECEIPT_TIMEOUT_MS","TRANSACTION_RECEIPT_POLLING_INTERVAL_MS","getTransactionReceipt","txHash","publicClient","waitForTransactionReceipt","hash","timeout","pollingInterval","confirmations","error","getContractInstance","contractAddress","abi","client","address","wallet","public","searchAbiFunction","funcName","args","func","name","type","searchAbiEvent","eventName","event","getSignatureOfFunction","getInputsOfFunction","inputs","getInputsOfFunctionFormatted","map","input","i","value","getChecksumAddress","isValidAddress","getBytes","message","zeroPadValue","length","size","encodeBytes32String","makeWallet","seedphrase","addressIndex","makeWallets","numAccounts","accounts","push","makeRandomWallet","mnemonic","makeRandomWallets","seed","keccak256WithEncode","types","values","encoded","keccak256Packed","getBundlerRpcUrl","zeroDevProjectId","chainId","useUltraRelay","base","process","env","BUNDLER_RPC_URL_OVERRIDE","getPaymasterRpcUrl","isRelayerMode","Boolean","estimateUserOperationFees","bundlerClient","_publicClient","maxFeePerGas","maxPriorityFeePerGas","TEMPO_MIN_VERIFICATION_GAS","applyTempoVerificationGasFloor","userOperation","current","verificationGasLimit","floored","createKernelClient","kernelAccount","bundlerRpc","paymasterRpc","account","chain","bundlerTransport","paymaster","getPaymasterData","zerodevPaymaster","transport","sponsorUserOperation","estimateFeesPerGas","SCA_DERIVATION_VERSION","ACCOUNT_CACHE_TTL_MS","ACCOUNT_CACHE_MAX_ENTRIES","accountResolutionCache","Map","memoResolveAccount","key","resolver","now","Date","cached","get","expiresAt","k","e","delete","keys","next","entry","undefined","catch","err","set","getAccountResolutionCacheStats","clearAccountResolutionCache","clear","chainIdOf","id","Error","createEcdsaValidator","signer","entryPoint","kernelVersion","createKernelSmartAccount","ecdsaValidator","build","validator","plugins","sudo","getApproval","policies","emptyAccount","emptySessionKeySigner","permissionPlugin","sessionKeyAccount","regular","useSessionKey","approval","sessionKeySigner","createSessionKey","sessionPrivateKey","masterAccount","createSessionKeysForNetworks","publicClientByChainId","requiredChainId","out","chainIdStr","Object","entries","Number","console","warn","String","KERNEL_7702_IMPL_ADDRESS","createKernel7702Account","eip7702Auth","eip7702Account","getSessionKey","serializedSessionKey","createDelegatedSessionKeyFromKernel","sessionAccount","permissionValidator","kernelAccountTyped","sudoValidator","kernelPluginManager","serialized","WalletUtils"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/nevermined/utils/BlockchainViemUtils.ts"],"sourcesContent":["import { signerToEcdsaValidator } from '@zerodev/ecdsa-validator'\nimport {\n deserializePermissionAccount,\n serializePermissionAccount,\n toPermissionValidator,\n} from '@zerodev/permissions'\nimport { toECDSASigner } from '@zerodev/permissions/signers'\nimport {\n addressToEmptyAccount,\n createKernelAccount,\n createKernelAccountClient,\n createZeroDevPaymasterClient,\n getUserOperationGasPrice,\n KernelAccountClient,\n type KernelSmartAccountImplementation,\n} from '@zerodev/sdk'\nimport {\n KERNEL_V3_1,\n KERNEL_V3_3,\n KERNEL_7702_DELEGATION_ADDRESS,\n getEntryPoint,\n} from '@zerodev/sdk/constants'\nimport {\n Address,\n encodeAbiParameters,\n getAbiItem,\n getAddress,\n getContract,\n http,\n isAddress,\n pad,\n stringToBytes,\n stringToHex,\n toBytes,\n keccak256 as viemKeccak256,\n type Abi,\n type AbiEvent,\n type AbiFunction,\n type Account,\n type PublicClient,\n type SignAuthorizationReturnType,\n type TransactionReceipt,\n} from 'viem'\nimport { SmartAccount } from 'viem/account-abstraction'\nimport {\n english,\n generateMnemonic,\n generatePrivateKey,\n mnemonicToAccount,\n privateKeyToAccount,\n} from 'viem/accounts'\nimport { Instantiable, InstantiableConfig, Web3Clients } from '../../Instantiable.abstract.js'\nimport { ContractsError } from '../../errors/NeverminedErrors.js'\nimport { getChain } from '../../utils/Network.js'\nimport { Signer } from '@zerodev/sdk/types'\n\nconst ENTRY_POINT_VERSION = '0.7'\n\n/**\n * Utility class with methods that allow the interaction with the blockchain.\n * This class uses Viem library to interact with the blockchain.\n */\nexport class BlockchainViemUtils extends Instantiable {\n constructor(config: InstantiableConfig) {\n super()\n this.setInstanceConfig(config)\n }\n}\n\n//////////////////////////\n///// UTILITIES //////////\n//////////////////////////\n\n///// CONTRACTS\n\n// Wait budget for an L2 block to be mined and the receipt to surface.\n// Base / Base Sepolia block time is ~2s; 30s ≈ 15 blocks of headroom.\nconst TRANSACTION_RECEIPT_TIMEOUT_MS = 30_000\nconst TRANSACTION_RECEIPT_POLLING_INTERVAL_MS = 1_500\n\n/**\n * Given a transaction hash, it returns the transaction receipt.\n * Uses viem's `waitForTransactionReceipt` which polls until the receipt is\n * available, retrying on `TransactionReceiptNotFoundError` and handling\n * tx-replacement / reorgs natively.\n * @param txHash - the transaction hash\n * @returns the transaction receipt\n */\nexport async function getTransactionReceipt({\n txHash,\n publicClient,\n}: {\n txHash: `0x${string}`\n publicClient: PublicClient\n iteration?: number\n}): Promise<TransactionReceipt> {\n try {\n return await publicClient.waitForTransactionReceipt({\n hash: txHash,\n timeout: TRANSACTION_RECEIPT_TIMEOUT_MS,\n pollingInterval: TRANSACTION_RECEIPT_POLLING_INTERVAL_MS,\n confirmations: 1,\n })\n } catch (error) {\n throw new ContractsError(\n `Unable to get transaction receipt with hash: ${txHash}. Error: ${error}`,\n )\n }\n}\n\n/**\n * Given an already deployed contract address and the ABI, it returns the contract instance.\n *\n * @param contractAddress - the contract address\n * @param abi - the contract artifact\n * @param client - the client to interact with the blockchain\n * @returns a contract instance\n */\nexport async function getContractInstance(contractAddress: string, abi: Abi, client: Web3Clients) {\n return getContract({\n abi,\n address: contractAddress as `0x${string}`,\n client: { wallet: client.wallet, public: client.public },\n })\n}\n\n///// ABIs\n\n/**\n * It searchs an ABI function in the ABI.\n * @param abi the ABI of the contract\n * @param funcName the function name\n * @param args the args of the function\n * @returns the function found\n */\nexport function searchAbiFunction(abi: Abi, funcName: string, args: any[] = []): AbiFunction {\n const func = getAbiItem({ abi, name: funcName, args })\n if (!func || func.type !== 'function') {\n throw new ContractsError(`Function \"${funcName}\" is not part of contract`)\n }\n return func as AbiFunction\n}\n\n/**\n * It searchs an ABI event in the ABI.\n * @param abi the ABI of the contract\n * @param funcName the event name\n * @returns the event found\n */\nexport function searchAbiEvent(abi: Abi, eventName: string): AbiEvent {\n const event = getAbiItem({\n abi,\n name: eventName,\n })\n if (!event || event.type !== 'event') {\n throw new ContractsError(`Event \"${event}\" is not part of contract`)\n }\n return event as AbiEvent\n}\n\n/**\n * It searchs an ABI function in the ABI.\n * @param abi the ABI of the contract\n * @param funcName the function name\n * @param args the args of the function\n * @returns the function found\n */\nexport function getSignatureOfFunction(abi: Abi, funcName: string, args: any[] = []): AbiFunction {\n return searchAbiFunction(abi, funcName, args)\n}\n\n/**\n * It searchs an ABI function in the ABI and return the inputs.\n * @param abi the ABI of the contract\n * @param funcName the function name\n * @param args the args of the function\n * @returns the function found\n */\nexport function getInputsOfFunction(abi: Abi, funcName: string, args: any[] = []) {\n return searchAbiFunction(abi, funcName, args).inputs\n}\n\n/**\n * It searchs an ABI function in the ABI and return the inputs formatted.\n * @param abi the ABI of the contract\n * @param funcName the function name\n * @param args the args of the function\n * @returns the function found\n */\nexport function getInputsOfFunctionFormatted(abi: Abi, funcName: string, args: any[] = []) {\n return searchAbiFunction(abi, funcName, args).inputs.map((input, i) => {\n return {\n name: input.name,\n value: args[i],\n }\n })\n}\n\n//////// UTILS\n\n/**\n * Given an address it returns that address in checksum format.\n * @param address the address\n * @returns the same address in checksum format\n */\nexport function getChecksumAddress(address: string): string {\n return getAddress(address)\n}\n\n/**\n * It checks if the address is a valid address.\n * @param address the address to check\n * @returns true of the address is valid\n */\nexport function isValidAddress(address: string): boolean {\n return isAddress(address)\n}\n\n/**\n * Encodes a UTF-8 string into a byte array.\n\n * @param message the string to encode\n * @returns the encoded byte array\n */\nexport function getBytes(message: string): Uint8Array {\n return stringToBytes(message)\n}\n\n/**\n * It pads a value with zeros.\n * @param value the value to pad\n * @param length the expected longitutde of the value\n * @returns the padded value\n */\nexport function zeroPadValue(value: `0x${string}` | Uint8Array, length: number): string {\n return pad(value, { size: length }) as `0x${string}`\n}\n\n/**\n * Encodes a UTF-8 string into a hex string\n * @param message the string to encode\n * @returns the hex string\n */\nexport function encodeBytes32String(message: string) {\n return stringToHex(message, { size: 32 })\n}\n\n////// ACCOUNTS\n/**\n * Given a seedphrase, it returns an account.\n * @param seedphrase - the seedphrase to be used to generate the account\n * @param addressIndex - the address index\n * @returns an account\n */\nexport function makeWallet(seedphrase: string, addressIndex = 0): Account {\n return mnemonicToAccount(seedphrase, { addressIndex })\n}\n\n/**\n * Given a seedphrase generates multiple accounts\n * @param seedphrase - the seedphrase to be used to generate the account\n * @param numAccounts - the number of accounts to create\n * @returns the array of accounts\n */\nexport function makeWallets(seedphrase: string, numAccounts = 10) {\n const accounts: Account[] = []\n for (let i = 0; i < numAccounts; i++) {\n accounts.push(makeWallet(seedphrase, i))\n }\n return accounts\n}\n\n/**\n * It generates a random account.\n * @returns a new account\n */\nexport function makeRandomWallet(): Account {\n const mnemonic = generateMnemonic(english)\n return makeWallet(mnemonic)\n}\n\n/**\n * It generates a list of random accounts\n * @param numAccounts - the number of accounts to create\n * @returns the array of accounts\n */\nexport function makeRandomWallets(numAccounts = 10): Account[] {\n const mnemonic = generateMnemonic(english)\n return makeWallets(mnemonic, numAccounts)\n}\n\n/////// HASHES\n\n/**\n * It hashes a string using keccak256.\n * @param seed the string to hash\n * @returns the hash\n */\nexport function keccak256(seed: string): string {\n return viemKeccak256(toBytes(seed))\n}\n\n/**\n * It encodes and hashes a list of primitive values into an ABI-encoded hex value.\n * @param types the types of the values\n * @param values the values to encode\n * @returns the hash\n */\nexport function keccak256WithEncode(types: any[], values: any[]): string {\n const encoded = encodeAbiParameters(types, values as never)\n return keccak256(encoded)\n}\n\n/**\n * It encodes and hashes a list of primitive values into an ABI-encoded hex value.\n * @param types the types of the values\n * @param values the values to encode\n * @returns the hash\n */\nexport function keccak256Packed(types: any[], values: any[]): string {\n return keccak256WithEncode(types, values)\n}\n\n/////// ZERO DEV\n\n/**\n * Returns the bundler RPC URL. When `BUNDLER_RPC_URL_OVERRIDE` is set\n * (used by tests against a local Alto + anvil-fork stack), it takes precedence\n * over the canonical ZeroDev URL. When `useUltraRelay` is true, the production\n * URL is routed through ZeroDev's UltraRelay (`?provider=ULTRA_RELAY`); the\n * override branch is left untouched.\n * @param useUltraRelay - when true, append `?provider=ULTRA_RELAY` to route the\n * UserOperation through ZeroDev's UltraRelay bundler tier. Ignored when\n * `BUNDLER_RPC_URL_OVERRIDE` is set.\n */\nexport function getBundlerRpcUrl(\n zeroDevProjectId: string,\n chainId: number,\n useUltraRelay = false,\n): string {\n const base = `https://rpc.zerodev.app/api/v3/${zeroDevProjectId}/chain/${chainId}`\n // Per-chain override wins, then the global override, then the canonical URL.\n // The per-chain form (`BUNDLER_RPC_URL_OVERRIDE_<chainId>`) lets a single\n // process route UserOps for different networks to different local bundlers —\n // e.g. a dual-fork dev stack (base-sepolia bundler :4337 + tempo bundler\n // :4338). `||` (not `??`) because Vite replaces missing browser env vars with\n // the empty string at build time; an empty override is equivalent to none.\n return (\n process.env[`BUNDLER_RPC_URL_OVERRIDE_${chainId}`] ||\n process.env.BUNDLER_RPC_URL_OVERRIDE ||\n (useUltraRelay ? `${base}?provider=ULTRA_RELAY` : base)\n )\n}\n\n/**\n * Returns the paymaster RPC URL (ZeroDev-only; the local fork stack uses\n * `ultra-relay` which sponsors via the bundler's executor key without a\n * paymaster, so this URL is not consulted when `BUNDLER_RPC_URL_OVERRIDE` is\n * set).\n */\nexport function getPaymasterRpcUrl(zeroDevProjectId: string, chainId: number): string {\n return `https://rpc.zerodev.app/api/v3/${zeroDevProjectId}/chain/${chainId}`\n}\n\n/**\n * Returns true when the kernel client should run in \"relayer mode\" — no\n * paymaster, gas fees zeroed out. Used by tests against a local\n * `ultra-relay` (ZeroDev's fork of Alto) on top of an anvil-fork. The relayer's\n * executor key pays gas directly via `EntryPoint.handleOps`, avoiding the\n * paymaster sponsorship handshake altogether.\n */\nexport function isRelayerMode(): boolean {\n return Boolean(process.env.BUNDLER_RPC_URL_OVERRIDE)\n}\n\n/**\n * Returns gas prices for UserOperation fee estimation. ZeroDev's bundler\n * exposes a custom `zd_getUserOperationGasPrice` method; standard ERC-4337\n * bundlers do not. In relayer mode the bundler accepts UserOps with zeroed\n * `maxFeePerGas`/`maxPriorityFeePerGas` and pays gas itself.\n */\nexport async function estimateUserOperationFees(\n bundlerClient: any,\n _publicClient: any,\n): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }> {\n if (isRelayerMode()) {\n return { maxFeePerGas: 0n, maxPriorityFeePerGas: 0n }\n }\n return getUserOperationGasPrice(bundlerClient)\n}\n\n/**\n * It creates a ZeroDev Kernel client.\n * @param signer the signer account\n * @param chainId the chain id\n * @param zeroDevProjectId the zero dev project id, you can get it from the ZeroDev dashboard\n * @param useUltraRelay forwarded straight to `getBundlerRpcUrl` — when true the\n * bundler RPC is routed through ZeroDev's UltraRelay. Ignored when\n * `BUNDLER_RPC_URL_OVERRIDE` is set.\n * @returns the kernel client\n */\nexport async function createKernelClient(\n kernelAccount: SmartAccount,\n chainId: number,\n zeroDevProjectId: string,\n publicClient: any,\n useUltraRelay = false,\n): Promise<KernelAccountClient> {\n const bundlerRpc = getBundlerRpcUrl(zeroDevProjectId, chainId, useUltraRelay)\n const paymasterRpc = getPaymasterRpcUrl(zeroDevProjectId, chainId)\n\n return createKernelAccountClient({\n account: kernelAccount,\n chain: getChain(chainId),\n bundlerTransport: http(bundlerRpc),\n client: publicClient,\n ...(isRelayerMode()\n ? {}\n : {\n paymaster: {\n getPaymasterData: (userOperation: any) => {\n const zerodevPaymaster = createZeroDevPaymasterClient({\n chain: getChain(chainId),\n transport: http(paymasterRpc),\n })\n return zerodevPaymaster.sponsorUserOperation({ userOperation })\n },\n },\n }),\n userOperation: {\n estimateFeesPerGas: async ({ bundlerClient }) => {\n return estimateUserOperationFees(bundlerClient, publicClient)\n },\n },\n })\n}\n\nexport type EcdsaValidator = Awaited<ReturnType<typeof signerToEcdsaValidator>>\n\n/**\n * Identifies the smart-account derivation inputs (entryPoint + kernel version).\n * The SCA is deterministic from `(EOA, entryPoint, kernelVersion, index)`, so a\n * bump here means the same EOA derives a different SCA. Persisted SCA caches\n * (e.g. the webapp's localStorage) should stamp this and invalidate on change.\n */\nexport const SCA_DERIVATION_VERSION = `${ENTRY_POINT_VERSION}:${KERNEL_V3_1}`\n\n// ponytail: in-process memo for ZeroDev Kernel account resolution. Every\n// deserializePermissionAccount / createKernelAccount reads the EIP-1967 impl\n// slot (eth_getStorageAt) of a deployed account — ~56% of backend Infura RPC\n// volume, and the same session key/owner is re-resolved per request and twice\n// per x402 payment (verify + settle). See #2206. Safe to reuse the resolved\n// account: the Kernel account fetches its nonce fresh at send time, so a cached\n// account never signs against a stale nonce. Keyed by the deterministic inputs\n// (serialized key / owner + kernel version + chainId); short TTL bounds\n// staleness across a kernel upgrade. Single-process only — cross-pod dedup is\n// out of scope (#2206 notes). Upgrade path: swap the Map for a shared store.\nconst ACCOUNT_CACHE_TTL_MS = 60_000\n// Bound the cache: `getSessionKey` runs behind `getAccountAttributes` on every\n// authenticated request, keyed per-API-key, so an entry never re-requested\n// would otherwise sit past its TTL for the life of the (long-lived) apps/api\n// process — a slow leak. Cardinality ≈ distinct API keys ever seen; cap + sweep\n// keep it bounded (matches BlockchainCacheService's MAX_ENTRIES + cleanup()).\nexport const ACCOUNT_CACHE_MAX_ENTRIES = 5_000\nconst accountResolutionCache = new Map<string, { value: Promise<unknown>; expiresAt: number }>()\n\nfunction memoResolveAccount<T>(key: string, resolver: () => Promise<T>): Promise<T> {\n const now = Date.now()\n const cached = accountResolutionCache.get(key)\n if (cached && cached.expiresAt > now) {\n return cached.value as Promise<T>\n }\n // Sweep expired entries + bound size so keys never re-requested don't\n // accumulate for the life of the process (Map keeps insertion order → FIFO).\n for (const [k, e] of accountResolutionCache) {\n if (e.expiresAt <= now) accountResolutionCache.delete(k)\n }\n if (accountResolutionCache.size >= ACCOUNT_CACHE_MAX_ENTRIES) {\n accountResolutionCache.delete(accountResolutionCache.keys().next().value as string)\n }\n const entry: { value: Promise<unknown>; expiresAt: number } = {\n value: undefined as unknown as Promise<unknown>,\n expiresAt: now + ACCOUNT_CACHE_TTL_MS,\n }\n // Coalesce concurrent identical resolutions; evict on rejection so a transient\n // RPC failure isn't cached — but only if this exact entry is still current, so\n // a resolver that hangs past its TTL and then rejects can't drop a newer one.\n entry.value = resolver().catch((err) => {\n if (accountResolutionCache.get(key) === entry) accountResolutionCache.delete(key)\n throw err\n })\n accountResolutionCache.set(key, entry)\n return entry.value as Promise<T>\n}\n\n/** Current entry count of the Kernel account-resolution memo (#2206). */\nexport function getAccountResolutionCacheStats() {\n return { size: accountResolutionCache.size }\n}\n\n/** Clear the account-resolution memo (test isolation / kernel-upgrade invalidation). */\nexport function clearAccountResolutionCache() {\n accountResolutionCache.clear()\n}\n\nfunction chainIdOf(publicClient: any): string | number {\n const id = publicClient?.chain?.id\n // chainId is the ONLY discriminator in the sca:/7702:/sk: keys, and SCA /\n // session-key addresses are identical across chains by CREATE2 design — so an\n // id-less client must fail closed rather than alias two networks under one\n // bucket and serve a chain-A account to a chain-B request (latent until #1933).\n if (id == null) {\n throw new Error('account-resolution cache: publicClient.chain.id is required for keying')\n }\n return id\n}\n\n/**\n * Build the ECDSA sudo validator for a signer. Both `createKernelSmartAccount`\n * and `createSessionKey` need this validator and each derives it via a ZeroDev\n * RPC round-trip. Callers that run both in sequence (e.g. the webapp API-key\n * creation path) can compute it once here and pass it into both helpers to\n * avoid the redundant round-trip.\n *\n * @param ecdsaValidator (on the consumers) must be one built for the SAME\n * `signer` — passing a validator derived from a different signer would attach\n * the wrong owner to the account.\n */\nexport async function createEcdsaValidator(\n signer: Signer,\n publicClient: PublicClient,\n): Promise<EcdsaValidator> {\n return signerToEcdsaValidator(publicClient, {\n signer,\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n kernelVersion: KERNEL_V3_1,\n })\n}\n\nexport async function createKernelSmartAccount(\n signer: Signer,\n publicClient: PublicClient,\n ecdsaValidator?: EcdsaValidator,\n): Promise<SmartAccount> {\n const build = async () => {\n const validator = ecdsaValidator ?? (await createEcdsaValidator(signer, publicClient))\n return createKernelAccount(publicClient, {\n plugins: {\n sudo: validator,\n },\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n kernelVersion: KERNEL_V3_1,\n })\n }\n // A caller-supplied validator isn't part of the key — bypass the memo (like\n // createKernel7702Account does for eip7702Auth) rather than let a cache entry\n // built by a different call silently ignore it (the mismatch createEcdsaValidator warns about).\n if (ecdsaValidator) return build()\n return memoResolveAccount(\n `sca:${chainIdOf(publicClient)}:${SCA_DERIVATION_VERSION}:${signer.address}`,\n build,\n )\n}\n\nexport async function getApproval(signer: Signer, publicClient: any, policies: any[]) {\n const ecdsaValidator = await signerToEcdsaValidator(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n signer,\n kernelVersion: KERNEL_V3_1,\n })\n const emptyAccount = addressToEmptyAccount(signer.address as Address)\n const emptySessionKeySigner = await toECDSASigner({ signer: emptyAccount })\n\n const permissionPlugin = await toPermissionValidator(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n signer: emptySessionKeySigner,\n policies: policies,\n kernelVersion: KERNEL_V3_1,\n })\n const sessionKeyAccount = await createKernelAccount(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n plugins: {\n sudo: ecdsaValidator,\n regular: permissionPlugin,\n },\n kernelVersion: KERNEL_V3_1,\n })\n\n return await serializePermissionAccount(sessionKeyAccount)\n}\n\nexport async function useSessionKey(approval: string, signer: Signer, publicClient: any) {\n const sessionKeySigner = await toECDSASigner({\n signer,\n })\n const sessionKeyAccount = await deserializePermissionAccount(\n publicClient,\n getEntryPoint(ENTRY_POINT_VERSION),\n KERNEL_V3_1,\n approval,\n sessionKeySigner,\n )\n\n return sessionKeyAccount\n}\n\nexport async function createSessionKey(\n signer: Signer,\n publicClient: any,\n policies: any[],\n ecdsaValidator?: EcdsaValidator,\n sessionPrivateKey: `0x${string}` = generatePrivateKey(),\n) {\n const validator = ecdsaValidator ?? (await createEcdsaValidator(signer, publicClient))\n const masterAccount = privateKeyToAccount(sessionPrivateKey)\n const sessionKeySigner = await toECDSASigner({\n signer: masterAccount,\n })\n\n const permissionPlugin = await toPermissionValidator(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n signer: sessionKeySigner,\n policies: policies,\n kernelVersion: KERNEL_V3_1,\n })\n\n const sessionKeyAccount = await createKernelAccount(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n plugins: {\n sudo: validator,\n regular: permissionPlugin,\n },\n kernelVersion: KERNEL_V3_1,\n })\n\n // serializePermissionAccount embeds the ENABLE signature for `publicClient`'s\n // chain (signed by the sudo/owner). That signature is chain-bound, which is\n // why one serialization only validates on the chain it was made for. #1929\n return serializePermissionAccount(sessionKeyAccount, sessionPrivateKey)\n}\n\n/**\n * Permission policies for a multi-network mint: either one set shared by every\n * chain, or a per-chain factory. The factory form is what keeps a chain's key\n * scoped to its OWN settlement tokens instead of the cross-network union.\n */\nexport type PoliciesFor = any[] | ((chainId: number) => any[])\n\nconst policiesForChain = (policies: PoliciesFor, chainId: number): any[] =>\n typeof policies === 'function' ? policies(chainId) : policies\n\n/**\n * Multi-network session keys (#1929). Generates ONE session private key and\n * serializes the permission account once per network — each serialization\n * carries that network's chain-bound enable signature. The SAME session key\n * works on every supported chain (the smart-account address + init code are\n * identical via CREATE2 parity); only the enable signature differs per chain.\n *\n * Use the returned map (chainId → serialized session key) to build a single\n * multi-network API key: the backend selects the entry for the operation's\n * network. Avoids the `EnableNotApproved` revert when an API key minted on one\n * chain is used on another.\n *\n * @param signer the smart-account owner (e.g. the Privy EOA) — signs each\n * network's enable signature\n * @param publicClientByChainId map of chainId → a PublicClient for that chain\n * @param policies the permission policies — either one set shared by every\n * chain, or a `(chainId) => policies` factory to scope each chain's key to\n * its OWN settlement tokens (the cross-network union overflows Tempo's\n * enable-gas ceiling, see MAX_CALLPOLICY_PERMISSIONS)\n */\nexport async function createSessionKeysForNetworks(\n signer: Signer,\n publicClientByChainId: Record<number, any>,\n policies: PoliciesFor,\n requiredChainId?: number,\n): Promise<Record<number, string>> {\n const sessionPrivateKey = generatePrivateKey()\n const out: Record<number, string> = {}\n for (const [chainIdStr, publicClient] of Object.entries(publicClientByChainId)) {\n const chainId = Number(chainIdStr)\n try {\n out[chainId] = await createSessionKey(\n signer,\n publicClient,\n policiesForChain(policies, chainId),\n undefined,\n sessionPrivateKey,\n )\n } catch (err) {\n // Best-effort: a secondary network whose RPC is unreachable must not break\n // key generation (e.g. login). `requiredChainId` (the primary) still throws.\n if (requiredChainId != null && chainId === Number(requiredChainId)) throw err\n console.warn(\n `[createSessionKeysForNetworks] skipping network ${chainId}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n }\n // Enforce the `requiredChainId` contract even when it is ABSENT from the input\n // map (the loop above only throws when it is present AND fails). Without this,\n // callers read `out[primary]` → undefined → an API key with no primary session\n // key, which fails opaquely downstream.\n if (requiredChainId != null && out[requiredChainId] == null) {\n throw new Error(\n `createSessionKeysForNetworks: required network ${requiredChainId} was not in the public-client map`,\n )\n }\n return out\n}\n\n/**\n * The canonical, CREATE2-deterministic Kernel v3.3 implementation that an EOA\n * delegates to under EIP-7702 (same address on Base mainnet + Base Sepolia).\n * This is the `contract`/`address` passed to Privy `sign7702Authorization` and\n * carried in the type-4 authorization. See #2148.\n */\nexport const KERNEL_7702_IMPL_ADDRESS = KERNEL_7702_DELEGATION_ADDRESS\n\n// The two Kernel versions the platform runs: v3.1 for the legacy counterfactual\n// SCA, v3.3 for the EIP-7702-delegated EOA account. Re-exported so the API\n// layer can pick the right version for (de)serializing session keys.\nexport { KERNEL_V3_1, KERNEL_V3_3 }\nexport type KernelVersion = typeof KERNEL_V3_1 | typeof KERNEL_V3_3\n\n/**\n * Resolves a user's EIP-7702 account: the Privy EOA delegated to Kernel v3.3.\n * The resulting account's address **equals the EOA** (no counterfactual SCA),\n * so it both signs EIP-3009 as a plain EOA (Router) and acts as a 4337 smart\n * account (credits/session-keys). `eip7702Auth` is the signed type-4\n * authorization (from Privy `sign7702Authorization`); omit it once the account\n * is already delegated on-chain.\n *\n * ponytail: on-chain correctness (delegation designator, UserOp submission)\n * is validated on Base Sepolia in Phase 0 (#2153); this wrapper only pins the\n * SDK call shape.\n */\nexport async function createKernel7702Account(\n signer: Signer,\n publicClient: PublicClient,\n eip7702Auth?: SignAuthorizationReturnType,\n): Promise<SmartAccount> {\n const build = () =>\n createKernelAccount(publicClient, {\n eip7702Account: signer,\n ...(eip7702Auth ? { eip7702Auth } : {}),\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n kernelVersion: KERNEL_V3_3,\n })\n // The install path (auth attached) is a one-time mutating op — never cache it.\n if (eip7702Auth) return build()\n return memoResolveAccount(`7702:${chainIdOf(publicClient)}:${signer.address}`, build)\n}\n\nexport async function getSessionKey(\n serializedSessionKey: string,\n publicClient: any,\n kernelVersion: KernelVersion = KERNEL_V3_1,\n) {\n return memoResolveAccount(\n `sk:${chainIdOf(publicClient)}:${kernelVersion}:${serializedSessionKey}`,\n () =>\n deserializePermissionAccount(\n publicClient,\n getEntryPoint(ENTRY_POINT_VERSION),\n kernelVersion,\n serializedSessionKey,\n ),\n )\n}\n\n/**\n * Creates a delegated session key for an existing kernel account.\n * The resulting serialized session key can be deserialized into a SmartAccount\n * that shares the same address as the kernel account but enforces the given policies.\n *\n * @param kernelAccount The existing SmartAccount (kernel) to delegate from\n * @param publicClient Viem PublicClient instance\n * @param policies Array of policies to enforce for this session key\n * @returns Serialized session key string\n */\nexport async function createDelegatedSessionKeyFromKernel(\n kernelAccount: SmartAccount,\n publicClient: PublicClient,\n policies: any[],\n kernelVersion: KernelVersion = KERNEL_V3_1,\n existingSessionPrivateKey?: `0x${string}`,\n): Promise<string> {\n // 1) Ephemeral session private key (used only for the permission plugin). A\n // multi-network mint passes the SAME key for every chain so one API key\n // carries one session key with a per-chain enable signature.\n const sessionPrivateKey = existingSessionPrivateKey ?? generatePrivateKey()\n const sessionAccount = privateKeyToAccount(sessionPrivateKey)\n\n // 2) Wrap ephemeral key as ECDSA signer for permissions\n const sessionKeySigner = await toECDSASigner({ signer: sessionAccount })\n\n // 3) Create the permission validator plugin — MUST match the parent kernel's\n // version (v3.3 for a 7702 account, v3.1 for the legacy SCA), otherwise the\n // serialized blob deserializes/validates against the wrong kernel.\n const permissionValidator = await toPermissionValidator(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n signer: sessionKeySigner,\n policies,\n kernelVersion,\n })\n\n // 4) Extract the sudo validator from the existing kernel account\n const kernelAccountTyped = kernelAccount as SmartAccount<KernelSmartAccountImplementation>\n const sudoValidator = kernelAccountTyped.kernelPluginManager.sudoValidator\n\n if (!sudoValidator) {\n throw new Error('Kernel account does not have a sudo validator')\n }\n\n // 5) Create a new kernel account with both sudo (from original) and permission\n // validator, at the same address as the parent kernel. For a 7702 account\n // that address is the EOA; pinning `address` keeps the session-key account\n // on the same account rather than a fresh counterfactual one.\n const sessionKeyAccount = await createKernelAccount(publicClient, {\n entryPoint: getEntryPoint(ENTRY_POINT_VERSION),\n address: kernelAccountTyped.address,\n plugins: {\n sudo: sudoValidator, // Use existing sudo validator\n regular: permissionValidator,\n },\n kernelVersion,\n })\n\n // 6) Serialize the session key account with the ephemeral private key\n const serialized = await serializePermissionAccount(sessionKeyAccount, sessionPrivateKey)\n\n return serialized\n}\n\n/**\n * Multi-network session keys for an EIP-7702 account — the v2 sibling of\n * {@link createSessionKeysForNetworks}.\n *\n * The 7702 path used to mint single-network (primary only), so once a user\n * migrated, EVERY key the backend issued rejected any secondary network with\n * `BCK.APIKEY.0017`. Like the v1 helper this generates ONE session private key\n * and serializes it once per chain, since the enable signature is chain-bound.\n *\n * The 7702 account is re-derived per chain from `signer`: the delegated EOA has\n * the same address everywhere, but the permission validator must be built\n * against THAT chain's client for its enable signature to validate there.\n *\n * Same best-effort contract as the v1 helper: a secondary network whose RPC is\n * unreachable is skipped with a warning; `requiredChainId` always throws.\n */\nexport async function createDelegatedSessionKeysForNetworks(\n signer: Signer,\n publicClientByChainId: Record<number, any>,\n policies: PoliciesFor,\n kernelVersion: KernelVersion = KERNEL_V3_3,\n requiredChainId?: number,\n): Promise<Record<number, string>> {\n const sessionPrivateKey = generatePrivateKey()\n const out: Record<number, string> = {}\n for (const [chainIdStr, publicClient] of Object.entries(publicClientByChainId)) {\n const chainId = Number(chainIdStr)\n try {\n const account = await createKernel7702Account(signer, publicClient)\n out[chainId] = await createDelegatedSessionKeyFromKernel(\n account,\n publicClient,\n policiesForChain(policies, chainId),\n kernelVersion,\n sessionPrivateKey,\n )\n } catch (err) {\n if (requiredChainId != null && chainId === Number(requiredChainId)) throw err\n console.warn(\n `[createDelegatedSessionKeysForNetworks] skipping network ${chainId}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n }\n // Mirrors the v1 helper: enforce the contract even when the required chain is\n // ABSENT from the map, so a caller never reads `out[primary]` === undefined.\n if (requiredChainId != null && out[requiredChainId] == null) {\n throw new Error(\n `createDelegatedSessionKeysForNetworks: required network ${requiredChainId} was not in the public-client map`,\n )\n }\n return out\n}\n\nexport const WalletUtils = {\n makeWallet,\n makeWallets,\n makeRandomWallet,\n makeRandomWallets,\n}\n"],"names":["signerToEcdsaValidator","deserializePermissionAccount","serializePermissionAccount","toPermissionValidator","toECDSASigner","addressToEmptyAccount","createKernelAccount","createKernelAccountClient","createZeroDevPaymasterClient","getUserOperationGasPrice","KERNEL_V3_1","KERNEL_V3_3","KERNEL_7702_DELEGATION_ADDRESS","getEntryPoint","encodeAbiParameters","getAbiItem","getAddress","getContract","http","isAddress","pad","stringToBytes","stringToHex","toBytes","keccak256","viemKeccak256","english","generateMnemonic","generatePrivateKey","mnemonicToAccount","privateKeyToAccount","Instantiable","ContractsError","getChain","ENTRY_POINT_VERSION","BlockchainViemUtils","config","setInstanceConfig","TRANSACTION_RECEIPT_TIMEOUT_MS","TRANSACTION_RECEIPT_POLLING_INTERVAL_MS","getTransactionReceipt","txHash","publicClient","waitForTransactionReceipt","hash","timeout","pollingInterval","confirmations","error","getContractInstance","contractAddress","abi","client","address","wallet","public","searchAbiFunction","funcName","args","func","name","type","searchAbiEvent","eventName","event","getSignatureOfFunction","getInputsOfFunction","inputs","getInputsOfFunctionFormatted","map","input","i","value","getChecksumAddress","isValidAddress","getBytes","message","zeroPadValue","length","size","encodeBytes32String","makeWallet","seedphrase","addressIndex","makeWallets","numAccounts","accounts","push","makeRandomWallet","mnemonic","makeRandomWallets","seed","keccak256WithEncode","types","values","encoded","keccak256Packed","getBundlerRpcUrl","zeroDevProjectId","chainId","useUltraRelay","base","process","env","BUNDLER_RPC_URL_OVERRIDE","getPaymasterRpcUrl","isRelayerMode","Boolean","estimateUserOperationFees","bundlerClient","_publicClient","maxFeePerGas","maxPriorityFeePerGas","createKernelClient","kernelAccount","bundlerRpc","paymasterRpc","account","chain","bundlerTransport","paymaster","getPaymasterData","userOperation","zerodevPaymaster","transport","sponsorUserOperation","estimateFeesPerGas","SCA_DERIVATION_VERSION","ACCOUNT_CACHE_TTL_MS","ACCOUNT_CACHE_MAX_ENTRIES","accountResolutionCache","Map","memoResolveAccount","key","resolver","now","Date","cached","get","expiresAt","k","e","delete","keys","next","entry","undefined","catch","err","set","getAccountResolutionCacheStats","clearAccountResolutionCache","clear","chainIdOf","id","Error","createEcdsaValidator","signer","entryPoint","kernelVersion","createKernelSmartAccount","ecdsaValidator","build","validator","plugins","sudo","getApproval","policies","emptyAccount","emptySessionKeySigner","permissionPlugin","sessionKeyAccount","regular","useSessionKey","approval","sessionKeySigner","createSessionKey","sessionPrivateKey","masterAccount","policiesForChain","createSessionKeysForNetworks","publicClientByChainId","requiredChainId","out","chainIdStr","Object","entries","Number","console","warn","String","KERNEL_7702_IMPL_ADDRESS","createKernel7702Account","eip7702Auth","eip7702Account","getSessionKey","serializedSessionKey","createDelegatedSessionKeyFromKernel","existingSessionPrivateKey","sessionAccount","permissionValidator","kernelAccountTyped","sudoValidator","kernelPluginManager","serialized","createDelegatedSessionKeysForNetworks","WalletUtils"],"mappings":"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"}
|
|
@@ -15,8 +15,8 @@ export declare const getOrderPolicy: () => Policy;
|
|
|
15
15
|
export declare const getMintNFTPolicy: () => Policy;
|
|
16
16
|
export declare const getBurnNFTPolicy: () => Policy;
|
|
17
17
|
export declare const getRegisterPolicy: () => Policy;
|
|
18
|
-
export declare const buildPolicy: (permissions: string[], tokenAddresses: `0x${string}`[]) => Policy;
|
|
19
|
-
export declare const getAllContractsPolicy: (tokenAddresses: `0x${string}`[]) => Policy;
|
|
18
|
+
export declare const buildPolicy: (permissions: string[], tokenAddresses: `0x${string}`[], chainId?: number) => Policy;
|
|
19
|
+
export declare const getAllContractsPolicy: (tokenAddresses: `0x${string}`[], chainId?: number) => Policy;
|
|
20
20
|
export type OrderContract = {
|
|
21
21
|
address: `0x${string}`;
|
|
22
22
|
isPayAsYouGo: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZeroDevPolicies.d.ts","sourceRoot":"","sources":["../../../src/nevermined/utils/ZeroDevPolicies.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,GAAG,EAAoC,MAAM,MAAM,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"ZeroDevPolicies.d.ts","sourceRoot":"","sources":["../../../src/nevermined/utils/ZeroDevPolicies.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,GAAG,EAAoC,MAAM,MAAM,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAG7C,wBAAgB,SAAS,CAAC,WAAW,EAAE,GAAG,EAAE,UAK3C;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,SAiClE;AAoBD,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,KAAK,MAAM,EAAE;;SAK/D,GAAG;;EAGZ;AACD,eAAO,MAAM,qBAAqB,GAAI,iBAAiB,KAAK,MAAM,EAAE,WACV,CAAA;AAgB1D,eAAO,MAAM,0BAA0B,cACyB,CAAA;AAEhE,eAAO,MAAM,gCAAgC,cAC2C,CAAA;AAExF,eAAO,MAAM,uBAAuB,cACuC,CAAA;AAE3E,eAAO,MAAM,cAAc,cAM1B,CAAA;AAED,eAAO,MAAM,gBAAgB,cAAkE,CAAA;AAE/F,eAAO,MAAM,gBAAgB,cAAkE,CAAA;AAE/F,eAAO,MAAM,iBAAiB,cACuC,CAAA;AAoCrE,eAAO,MAAM,WAAW,GACtB,aAAa,MAAM,EAAE,EACrB,gBAAgB,KAAK,MAAM,EAAE,EAAE,EAC/B,UAAU,MAAM,WAiBjB,CAAA;AAOD,eAAO,MAAM,qBAAqB,GAAI,gBAAgB,KAAK,MAAM,EAAE,EAAE,EAAE,UAAU,MAAM,WAWtF,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,KAAK,MAAM,EAAE,CAAA;IACtB,YAAY,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,aAAa,EAAE,CAAA;IAC1B,iBAAiB,EAAE,KAAK,MAAM,EAAE,CAAA;IAChC,iBAAiB,EAAE,MAAM,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oBAAoB,CAAC,EAAE,KAAK,MAAM,EAAE,CAAA;IACpC,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,oBAAoB,kBAAkB,KAAG,MAAM,EAgFtF,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CallPolicyVersion, ParamCondition, toCallPolicy, toRateLimitPolicy, toTimestampPolicy } from '@zerodev/permissions/policies';
|
|
2
2
|
import { assetsRegistryConfig, fixedPaymentTemplateConfig, nft1155CreditsConfig, payAsYouGoTemplateAddress, payAsYouGoTemplateConfig } from '../../artifacts/generated.js';
|
|
3
3
|
import { isAddress, parseAbi, zeroAddress } from 'viem';
|
|
4
|
+
import { isTempoNetwork } from '../../utils/Network.js';
|
|
4
5
|
export function getPolicy(permissions) {
|
|
5
6
|
return toCallPolicy({
|
|
6
7
|
policyVersion: CallPolicyVersion.V0_0_4,
|
|
@@ -110,16 +111,28 @@ export const getBurnNFTPolicy = ()=>getPolicy(getPermissions(nft1155CreditsConfi
|
|
|
110
111
|
'burn'
|
|
111
112
|
]));
|
|
112
113
|
export const getRegisterPolicy = ()=>getPolicy(getPermissions(assetsRegistryConfig, REGISTER_GROUP_FNS));
|
|
113
|
-
// #1929: the session-key CallPolicy
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
// (
|
|
121
|
-
|
|
122
|
-
|
|
114
|
+
// #1929: the session-key CallPolicy must fit under Tempo's verification-gas
|
|
115
|
+
// ceiling for the on-chain ENABLE. Exceeding it makes the enable revert — and
|
|
116
|
+
// NOT tunably: the ZeroDev sponsor ignores the `verificationGasLimit` we send
|
|
117
|
+
// (AA26 is identical whether we ask for 1M or 1000M), so the ONLY lever is
|
|
118
|
+
// making the enable cheaper.
|
|
119
|
+
//
|
|
120
|
+
// Measured on live tempo-moderato against one warm 7702 account, varying ONLY
|
|
121
|
+
// the permission count (padded with dummy ERC20 `approve` permissions), the
|
|
122
|
+
// hosted ZeroDev bundler sponsoring:
|
|
123
|
+
// - Tempo: 14 perms land (5/5) · 15 → AA26 over verificationGasLimit
|
|
124
|
+
// (4/4) · 16+ → AA23 reverted 0x
|
|
125
|
+
// - base-sepolia: 40 perms land. No ceiling — the bound is Tempo-specific,
|
|
126
|
+
// which is why the guard below only asserts on Tempo.
|
|
127
|
+
// The bound stays at 12, two below the measured 14, because it counts
|
|
128
|
+
// PERMISSIONS while what actually blows is GAS: a permission with a heavier ABI
|
|
129
|
+
// than an `approve` costs more, so the count is only a proxy. Raising it is not
|
|
130
|
+
// the fix — pass a PER-NETWORK token subset (see `policiesFor` in the
|
|
131
|
+
// `*ForNetworks` helpers) so each chain's key only approves its own tokens.
|
|
132
|
+
const MAX_CALLPOLICY_PERMISSIONS = 12;
|
|
133
|
+
const assertPolicyFitsTempoEnableGas = (perms, chainId)=>{
|
|
134
|
+
// No chainId → assume the restrictive chain (the guard predates the param).
|
|
135
|
+
if (chainId !== undefined && !isTempoNetwork(chainId)) return;
|
|
123
136
|
if (perms.length > MAX_CALLPOLICY_PERMISSIONS) {
|
|
124
137
|
throw new Error(`CallPolicy has ${perms.length} permissions; exceeds the Tempo session-key enable-gas budget (${MAX_CALLPOLICY_PERMISSIONS}). Split to a per-network token subset instead of growing the cross-network union.`);
|
|
125
138
|
}
|
|
@@ -128,7 +141,7 @@ const assertPolicyFitsTempoEnableGas = (perms)=>{
|
|
|
128
141
|
// per network/currency), not a single hardcoded one — otherwise paying a plan in
|
|
129
142
|
// a different token (EURC, or pathUSD on Tempo) reverts `InvalidCallData`. No spend
|
|
130
143
|
// limit by design (the approve permissions carry no `valueLimit`).
|
|
131
|
-
export const buildPolicy = (permissions, tokenAddresses)=>{
|
|
144
|
+
export const buildPolicy = (permissions, tokenAddresses, chainId)=>{
|
|
132
145
|
const perms = [
|
|
133
146
|
...permissions.includes('register') ? getPermissions(assetsRegistryConfig, REGISTER_GROUP_FNS) : [],
|
|
134
147
|
...permissions.includes('mint') ? getPermissions(nft1155CreditsConfig, [
|
|
@@ -145,7 +158,7 @@ export const buildPolicy = (permissions, tokenAddresses)=>{
|
|
|
145
158
|
]) : [],
|
|
146
159
|
...permissions.includes('order') ? dedupeTokens(tokenAddresses).map((t)=>getERC20ApprovePermissions(t)) : []
|
|
147
160
|
];
|
|
148
|
-
assertPolicyFitsTempoEnableGas(perms);
|
|
161
|
+
assertPolicyFitsTempoEnableGas(perms, chainId);
|
|
149
162
|
return getPolicy(perms);
|
|
150
163
|
};
|
|
151
164
|
// #1929: the session key must permit `approve` on EVERY settlement token it may
|
|
@@ -153,7 +166,7 @@ export const buildPolicy = (permissions, tokenAddresses)=>{
|
|
|
153
166
|
// breaks the moment the order's token differs from it (EURC plans, or pathUSD on
|
|
154
167
|
// Tempo), reverting validateUserOp with `InvalidCallData`. Dedupe + drop zeros
|
|
155
168
|
// here so callers can pass the raw per-network token list.
|
|
156
|
-
export const getAllContractsPolicy = (tokenAddresses)=>{
|
|
169
|
+
export const getAllContractsPolicy = (tokenAddresses, chainId)=>{
|
|
157
170
|
const perms = [
|
|
158
171
|
...getPermissions(assetsRegistryConfig, REGISTER_GROUP_FNS),
|
|
159
172
|
...getPermissions(fixedPaymentTemplateConfig, [
|
|
@@ -168,7 +181,7 @@ export const getAllContractsPolicy = (tokenAddresses)=>{
|
|
|
168
181
|
]),
|
|
169
182
|
...dedupeTokens(tokenAddresses).map((t)=>getERC20ApprovePermissions(t))
|
|
170
183
|
].filter(Boolean);
|
|
171
|
-
assertPolicyFitsTempoEnableGas(perms);
|
|
184
|
+
assertPolicyFitsTempoEnableGas(perms, chainId);
|
|
172
185
|
return getPolicy(perms);
|
|
173
186
|
};
|
|
174
187
|
export const getZeroDevOrderPolicies = (orderPolicyOptions)=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/nevermined/utils/ZeroDevPolicies.ts"],"sourcesContent":["import {\n CallPolicyVersion,\n ParamCondition,\n toCallPolicy,\n toRateLimitPolicy,\n toTimestampPolicy,\n} from '@zerodev/permissions/policies'\nimport {\n assetsRegistryConfig,\n fixedPaymentTemplateConfig,\n nft1155CreditsConfig,\n payAsYouGoTemplateAddress,\n payAsYouGoTemplateConfig,\n} from '../../artifacts/generated.js'\nimport { Abi, isAddress, parseAbi, zeroAddress } from 'viem'\nimport { Policy } from '@zerodev/permissions'\n\nexport function getPolicy(permissions: any[]) {\n return toCallPolicy({\n policyVersion: CallPolicyVersion.V0_0_4,\n permissions,\n })\n}\n\nexport function getPermissions(config: any, functionNames: string[]) {\n const permissions: any[] = []\n functionNames.forEach((entry) => {\n // A bare name ('register') matches every overload of that name; a full signature\n // ('register(bytes32,string,uint256[])') pins ONE overload. The latter lets callers\n // permit only the signature the SDK actually calls instead of all overloads, which\n // keeps the CallPolicy merkle small (load-bearing on Tempo — see #1929).\n const name = entry.split('(')[0]\n const abis = config.abi.filter((item: any) => {\n if (item.type !== 'function' || item.name !== name) return false\n if (!entry.includes('(')) return true\n const sig = `${item.name}(${(item.inputs ?? []).map((i: any) => i.type).join(',')})`\n return sig === entry\n })\n // Fail LOUD if a requested function resolves to no ABI entry. A pinned full\n // signature (#1929 register trim) that stops matching after a contract regen\n // would otherwise silently emit zero permissions → every userOp for that\n // function reverts `InvalidCallData` at runtime with no build-time error.\n if (abis.length === 0) {\n throw new Error(\n `getPermissions: \"${entry}\" matched no function in the ABI for ${config.address}. ` +\n `A contract regen may have changed the signature (see #1929 register-overload trim).`,\n )\n }\n abis.forEach((abi: any) => {\n permissions.push({\n target: config.address,\n abi: [abi],\n functionName: name,\n })\n })\n })\n return permissions\n}\n\n// Dedupe settlement-token addresses case-insensitively (checksummed vs lowercase\n// are the SAME token) and drop the zero address. Duplicate `approve` permissions\n// re-bloat the CallPolicy merkle, which is load-bearing on Tempo's enable-gas\n// ceiling (#1929) — a case-sensitive `new Set` would let a mixed-casing map edit\n// silently regress the enable.\nfunction dedupeTokens(tokenAddresses: `0x${string}`[]): `0x${string}`[] {\n const seen = new Set<string>()\n const out: `0x${string}`[] = []\n for (const t of tokenAddresses) {\n if (!t || t === zeroAddress) continue\n const key = t.toLowerCase()\n if (seen.has(key)) continue\n seen.add(key)\n out.push(t)\n }\n return out\n}\n\nexport function getERC20ApprovePermissions(contractAddress: `0x${string}`) {\n return {\n target: contractAddress,\n abi: parseAbi([\n 'function approve(address spender, uint256 amount) external returns (bool)',\n ]) as Abi,\n functionName: 'approve',\n }\n}\nexport const getERC20ApprovePolicy = (contractAddress: `0x${string}`) =>\n getPolicy([getERC20ApprovePermissions(contractAddress)])\n\n// AssetRegistry's ABI carries 5 `register` overloads, but the SDK only ever calls\n// register(bytes32 seed, string url, uint256[] plans) (AssetRegistry.register). Pinning the\n// used signature drops the 4 dead overloads from the CallPolicy merkle (16 → 12 perms),\n// which is what lets the session-key ENABLE fit under Tempo's verification-gas ceiling (#1929).\nconst REGISTER_FN = 'register(bytes32,string,uint256[])'\nconst REGISTER_GROUP_FNS = [\n REGISTER_FN,\n 'createPlan',\n 'createPlanWithHooks',\n 'registerAgentAndPlan',\n 'addPlanToAgent',\n 'removePlanFromAgent',\n]\n\nexport const getAgentRegistrationPolicy = () =>\n getPolicy(getPermissions(assetsRegistryConfig, [REGISTER_FN]))\n\nexport const getPricingPlanRegistrationPolicy = () =>\n getPolicy(getPermissions(assetsRegistryConfig, ['createPlan', 'createPlanWithHooks']))\n\nexport const getRegisterAssetsPolicy = () =>\n getPolicy(getPermissions(assetsRegistryConfig, ['registerAgentAndPlan']))\n\nexport const getOrderPolicy = () => {\n const perms = [\n ...getPermissions(fixedPaymentTemplateConfig, ['order']),\n ...getPermissions(payAsYouGoTemplateAddress, ['order']),\n ]\n return getPolicy(perms)\n}\n\nexport const getMintNFTPolicy = () => getPolicy(getPermissions(nft1155CreditsConfig, ['mint']))\n\nexport const getBurnNFTPolicy = () => getPolicy(getPermissions(nft1155CreditsConfig, ['burn']))\n\nexport const getRegisterPolicy = () =>\n getPolicy(getPermissions(assetsRegistryConfig, REGISTER_GROUP_FNS))\n\n// #1929: the session-key CallPolicy is a cross-network UNION (every settlement\n// token's `approve` + the protocol methods) that must fit under Tempo's (most\n// restrictive) verification-gas ceiling for the on-chain ENABLE. The register-\n// overload trim (16 → 12 perms) exists precisely because that margin is thin, and\n// each new network/currency adds an `approve` to EVERY chain's key — so guard the\n// bound explicitly. Exceeding it means the next Tempo `createSessionKey` enable\n// would silently revert (AA23/AA26); the fix is a per-network token subset\n// (`createSessionKeysForNetworks` already loops per network), NOT raising this.\nconst MAX_CALLPOLICY_PERMISSIONS = 14\n\nconst assertPolicyFitsTempoEnableGas = (perms: unknown[]): void => {\n if (perms.length > MAX_CALLPOLICY_PERMISSIONS) {\n throw new Error(\n `CallPolicy has ${perms.length} permissions; exceeds the Tempo session-key enable-gas budget (${MAX_CALLPOLICY_PERMISSIONS}). Split to a per-network token subset instead of growing the cross-network union.`,\n )\n }\n}\n\n// #1929: `order` keys must approve EVERY settlement token they may pay with (one\n// per network/currency), not a single hardcoded one — otherwise paying a plan in\n// a different token (EURC, or pathUSD on Tempo) reverts `InvalidCallData`. No spend\n// limit by design (the approve permissions carry no `valueLimit`).\nexport const buildPolicy = (permissions: string[], tokenAddresses: `0x${string}`[]) => {\n const perms = [\n ...(permissions.includes('register')\n ? getPermissions(assetsRegistryConfig, REGISTER_GROUP_FNS)\n : []),\n ...(permissions.includes('mint') ? getPermissions(nft1155CreditsConfig, ['mint']) : []),\n ...(permissions.includes('burn') ? getPermissions(nft1155CreditsConfig, ['burn']) : []),\n ...(permissions.includes('order') ? getPermissions(fixedPaymentTemplateConfig, ['order']) : []),\n ...(permissions.includes('order') ? getPermissions(payAsYouGoTemplateConfig, ['order']) : []),\n ...(permissions.includes('order')\n ? dedupeTokens(tokenAddresses).map((t) => getERC20ApprovePermissions(t))\n : []),\n ]\n\n assertPolicyFitsTempoEnableGas(perms)\n return getPolicy(perms)\n}\n\n// #1929: the session key must permit `approve` on EVERY settlement token it may\n// ever pay with — one per (network, currency). A single-token policy silently\n// breaks the moment the order's token differs from it (EURC plans, or pathUSD on\n// Tempo), reverting validateUserOp with `InvalidCallData`. Dedupe + drop zeros\n// here so callers can pass the raw per-network token list.\nexport const getAllContractsPolicy = (tokenAddresses: `0x${string}`[]) => {\n const perms = [\n ...getPermissions(assetsRegistryConfig, REGISTER_GROUP_FNS),\n ...getPermissions(fixedPaymentTemplateConfig, ['order']),\n ...getPermissions(payAsYouGoTemplateConfig, ['order']),\n ...getPermissions(nft1155CreditsConfig, ['mint', 'burn']),\n ...dedupeTokens(tokenAddresses).map((t) => getERC20ApprovePermissions(t)),\n ].filter(Boolean)\n\n assertPolicyFitsTempoEnableGas(perms)\n return getPolicy(perms)\n}\n\nexport type OrderContract = {\n address: `0x${string}`\n isPayAsYouGo: boolean\n}\n\nexport type OrderPolicyOptions = {\n contracts: OrderContract[]\n subscriberAddress: `0x${string}`\n numberOfPurchases: bigint\n totalAmount: bigint\n count?: number\n erc20ContractAddress?: `0x${string}`\n validUntil?: number\n}\n\nexport const getZeroDevOrderPolicies = (orderPolicyOptions: OrderPolicyOptions): Policy[] => {\n const policies: Policy[] = []\n\n const orderPermissions = orderPolicyOptions.contracts.map((contract) => {\n if (contract.isPayAsYouGo) {\n return {\n target: contract.address,\n abi: parseAbi([\n 'function order(bytes32 _seed, uint256 _planId, bytes[] memory _params) external payable',\n ]) as Abi,\n valueLimit: 0n,\n functionName: 'order',\n args: [null, null],\n }\n }\n return {\n target: contract.address,\n abi: parseAbi([\n 'function order(bytes32 _seed, uint256 _planId, address _creditsReceiver, uint256 _numberOfPurchases, bytes[] memory _params) external payable',\n ]) as Abi,\n valueLimit: 0n,\n functionName: 'order',\n args: [\n null,\n null,\n {\n condition: ParamCondition.EQUAL,\n value: orderPolicyOptions.subscriberAddress,\n },\n {\n condition: ParamCondition.EQUAL,\n value: orderPolicyOptions.numberOfPurchases,\n },\n ],\n }\n })\n\n const callPermissions: any[] = [...orderPermissions]\n\n if (\n orderPolicyOptions.erc20ContractAddress &&\n isAddress(orderPolicyOptions.erc20ContractAddress)\n ) {\n callPermissions.push({\n target: orderPolicyOptions.erc20ContractAddress,\n abi: parseAbi([\n 'function approve(address spender, uint256 amount) external returns (bool)',\n ]) as Abi,\n valueLimit: 0n,\n functionName: 'approve',\n args: [\n {\n condition: ParamCondition.NOT_EQUAL,\n value: zeroAddress,\n },\n {\n condition: ParamCondition.LESS_THAN_OR_EQUAL,\n value: orderPolicyOptions.totalAmount,\n },\n ],\n })\n }\n\n policies.push(getPolicy(callPermissions))\n\n if (orderPolicyOptions.count) {\n const rateLimitPolicy = toRateLimitPolicy({\n count: orderPolicyOptions.count,\n })\n policies.push(rateLimitPolicy)\n }\n\n if (orderPolicyOptions.validUntil) {\n const timestampPolicy = toTimestampPolicy({\n validUntil: orderPolicyOptions.validUntil,\n })\n policies.push(timestampPolicy)\n }\n\n return policies\n}\n"],"names":["CallPolicyVersion","ParamCondition","toCallPolicy","toRateLimitPolicy","toTimestampPolicy","assetsRegistryConfig","fixedPaymentTemplateConfig","nft1155CreditsConfig","payAsYouGoTemplateAddress","payAsYouGoTemplateConfig","isAddress","parseAbi","zeroAddress","getPolicy","permissions","policyVersion","V0_0_4","getPermissions","config","functionNames","forEach","entry","name","split","abis","abi","filter","item","type","includes","sig","inputs","map","i","join","length","Error","address","push","target","functionName","dedupeTokens","tokenAddresses","seen","Set","out","t","key","toLowerCase","has","add","getERC20ApprovePermissions","contractAddress","getERC20ApprovePolicy","REGISTER_FN","REGISTER_GROUP_FNS","getAgentRegistrationPolicy","getPricingPlanRegistrationPolicy","getRegisterAssetsPolicy","getOrderPolicy","perms","getMintNFTPolicy","getBurnNFTPolicy","getRegisterPolicy","MAX_CALLPOLICY_PERMISSIONS","assertPolicyFitsTempoEnableGas","buildPolicy","getAllContractsPolicy","Boolean","getZeroDevOrderPolicies","orderPolicyOptions","policies","orderPermissions","contracts","contract","isPayAsYouGo","valueLimit","args","condition","EQUAL","value","subscriberAddress","numberOfPurchases","callPermissions","erc20ContractAddress","NOT_EQUAL","LESS_THAN_OR_EQUAL","totalAmount","count","rateLimitPolicy","validUntil","timestampPolicy"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/nevermined/utils/ZeroDevPolicies.ts"],"sourcesContent":["import {\n CallPolicyVersion,\n ParamCondition,\n toCallPolicy,\n toRateLimitPolicy,\n toTimestampPolicy,\n} from '@zerodev/permissions/policies'\nimport {\n assetsRegistryConfig,\n fixedPaymentTemplateConfig,\n nft1155CreditsConfig,\n payAsYouGoTemplateAddress,\n payAsYouGoTemplateConfig,\n} from '../../artifacts/generated.js'\nimport { Abi, isAddress, parseAbi, zeroAddress } from 'viem'\nimport { Policy } from '@zerodev/permissions'\nimport { isTempoNetwork } from '../../utils/Network.js'\n\nexport function getPolicy(permissions: any[]) {\n return toCallPolicy({\n policyVersion: CallPolicyVersion.V0_0_4,\n permissions,\n })\n}\n\nexport function getPermissions(config: any, functionNames: string[]) {\n const permissions: any[] = []\n functionNames.forEach((entry) => {\n // A bare name ('register') matches every overload of that name; a full signature\n // ('register(bytes32,string,uint256[])') pins ONE overload. The latter lets callers\n // permit only the signature the SDK actually calls instead of all overloads, which\n // keeps the CallPolicy merkle small (load-bearing on Tempo — see #1929).\n const name = entry.split('(')[0]\n const abis = config.abi.filter((item: any) => {\n if (item.type !== 'function' || item.name !== name) return false\n if (!entry.includes('(')) return true\n const sig = `${item.name}(${(item.inputs ?? []).map((i: any) => i.type).join(',')})`\n return sig === entry\n })\n // Fail LOUD if a requested function resolves to no ABI entry. A pinned full\n // signature (#1929 register trim) that stops matching after a contract regen\n // would otherwise silently emit zero permissions → every userOp for that\n // function reverts `InvalidCallData` at runtime with no build-time error.\n if (abis.length === 0) {\n throw new Error(\n `getPermissions: \"${entry}\" matched no function in the ABI for ${config.address}. ` +\n `A contract regen may have changed the signature (see #1929 register-overload trim).`,\n )\n }\n abis.forEach((abi: any) => {\n permissions.push({\n target: config.address,\n abi: [abi],\n functionName: name,\n })\n })\n })\n return permissions\n}\n\n// Dedupe settlement-token addresses case-insensitively (checksummed vs lowercase\n// are the SAME token) and drop the zero address. Duplicate `approve` permissions\n// re-bloat the CallPolicy merkle, which is load-bearing on Tempo's enable-gas\n// ceiling (#1929) — a case-sensitive `new Set` would let a mixed-casing map edit\n// silently regress the enable.\nfunction dedupeTokens(tokenAddresses: `0x${string}`[]): `0x${string}`[] {\n const seen = new Set<string>()\n const out: `0x${string}`[] = []\n for (const t of tokenAddresses) {\n if (!t || t === zeroAddress) continue\n const key = t.toLowerCase()\n if (seen.has(key)) continue\n seen.add(key)\n out.push(t)\n }\n return out\n}\n\nexport function getERC20ApprovePermissions(contractAddress: `0x${string}`) {\n return {\n target: contractAddress,\n abi: parseAbi([\n 'function approve(address spender, uint256 amount) external returns (bool)',\n ]) as Abi,\n functionName: 'approve',\n }\n}\nexport const getERC20ApprovePolicy = (contractAddress: `0x${string}`) =>\n getPolicy([getERC20ApprovePermissions(contractAddress)])\n\n// AssetRegistry's ABI carries 5 `register` overloads, but the SDK only ever calls\n// register(bytes32 seed, string url, uint256[] plans) (AssetRegistry.register). Pinning the\n// used signature drops the 4 dead overloads from the CallPolicy merkle (16 → 12 perms),\n// which is what lets the session-key ENABLE fit under Tempo's verification-gas ceiling (#1929).\nconst REGISTER_FN = 'register(bytes32,string,uint256[])'\nconst REGISTER_GROUP_FNS = [\n REGISTER_FN,\n 'createPlan',\n 'createPlanWithHooks',\n 'registerAgentAndPlan',\n 'addPlanToAgent',\n 'removePlanFromAgent',\n]\n\nexport const getAgentRegistrationPolicy = () =>\n getPolicy(getPermissions(assetsRegistryConfig, [REGISTER_FN]))\n\nexport const getPricingPlanRegistrationPolicy = () =>\n getPolicy(getPermissions(assetsRegistryConfig, ['createPlan', 'createPlanWithHooks']))\n\nexport const getRegisterAssetsPolicy = () =>\n getPolicy(getPermissions(assetsRegistryConfig, ['registerAgentAndPlan']))\n\nexport const getOrderPolicy = () => {\n const perms = [\n ...getPermissions(fixedPaymentTemplateConfig, ['order']),\n ...getPermissions(payAsYouGoTemplateAddress, ['order']),\n ]\n return getPolicy(perms)\n}\n\nexport const getMintNFTPolicy = () => getPolicy(getPermissions(nft1155CreditsConfig, ['mint']))\n\nexport const getBurnNFTPolicy = () => getPolicy(getPermissions(nft1155CreditsConfig, ['burn']))\n\nexport const getRegisterPolicy = () =>\n getPolicy(getPermissions(assetsRegistryConfig, REGISTER_GROUP_FNS))\n\n// #1929: the session-key CallPolicy must fit under Tempo's verification-gas\n// ceiling for the on-chain ENABLE. Exceeding it makes the enable revert — and\n// NOT tunably: the ZeroDev sponsor ignores the `verificationGasLimit` we send\n// (AA26 is identical whether we ask for 1M or 1000M), so the ONLY lever is\n// making the enable cheaper.\n//\n// Measured on live tempo-moderato against one warm 7702 account, varying ONLY\n// the permission count (padded with dummy ERC20 `approve` permissions), the\n// hosted ZeroDev bundler sponsoring:\n// - Tempo: 14 perms land (5/5) · 15 → AA26 over verificationGasLimit\n// (4/4) · 16+ → AA23 reverted 0x\n// - base-sepolia: 40 perms land. No ceiling — the bound is Tempo-specific,\n// which is why the guard below only asserts on Tempo.\n// The bound stays at 12, two below the measured 14, because it counts\n// PERMISSIONS while what actually blows is GAS: a permission with a heavier ABI\n// than an `approve` costs more, so the count is only a proxy. Raising it is not\n// the fix — pass a PER-NETWORK token subset (see `policiesFor` in the\n// `*ForNetworks` helpers) so each chain's key only approves its own tokens.\nconst MAX_CALLPOLICY_PERMISSIONS = 12\n\nconst assertPolicyFitsTempoEnableGas = (perms: unknown[], chainId?: number): void => {\n // No chainId → assume the restrictive chain (the guard predates the param).\n if (chainId !== undefined && !isTempoNetwork(chainId)) return\n if (perms.length > MAX_CALLPOLICY_PERMISSIONS) {\n throw new Error(\n `CallPolicy has ${perms.length} permissions; exceeds the Tempo session-key enable-gas budget (${MAX_CALLPOLICY_PERMISSIONS}). Split to a per-network token subset instead of growing the cross-network union.`,\n )\n }\n}\n\n// #1929: `order` keys must approve EVERY settlement token they may pay with (one\n// per network/currency), not a single hardcoded one — otherwise paying a plan in\n// a different token (EURC, or pathUSD on Tempo) reverts `InvalidCallData`. No spend\n// limit by design (the approve permissions carry no `valueLimit`).\nexport const buildPolicy = (\n permissions: string[],\n tokenAddresses: `0x${string}`[],\n chainId?: number,\n) => {\n const perms = [\n ...(permissions.includes('register')\n ? getPermissions(assetsRegistryConfig, REGISTER_GROUP_FNS)\n : []),\n ...(permissions.includes('mint') ? getPermissions(nft1155CreditsConfig, ['mint']) : []),\n ...(permissions.includes('burn') ? getPermissions(nft1155CreditsConfig, ['burn']) : []),\n ...(permissions.includes('order') ? getPermissions(fixedPaymentTemplateConfig, ['order']) : []),\n ...(permissions.includes('order') ? getPermissions(payAsYouGoTemplateConfig, ['order']) : []),\n ...(permissions.includes('order')\n ? dedupeTokens(tokenAddresses).map((t) => getERC20ApprovePermissions(t))\n : []),\n ]\n\n assertPolicyFitsTempoEnableGas(perms, chainId)\n return getPolicy(perms)\n}\n\n// #1929: the session key must permit `approve` on EVERY settlement token it may\n// ever pay with — one per (network, currency). A single-token policy silently\n// breaks the moment the order's token differs from it (EURC plans, or pathUSD on\n// Tempo), reverting validateUserOp with `InvalidCallData`. Dedupe + drop zeros\n// here so callers can pass the raw per-network token list.\nexport const getAllContractsPolicy = (tokenAddresses: `0x${string}`[], chainId?: number) => {\n const perms = [\n ...getPermissions(assetsRegistryConfig, REGISTER_GROUP_FNS),\n ...getPermissions(fixedPaymentTemplateConfig, ['order']),\n ...getPermissions(payAsYouGoTemplateConfig, ['order']),\n ...getPermissions(nft1155CreditsConfig, ['mint', 'burn']),\n ...dedupeTokens(tokenAddresses).map((t) => getERC20ApprovePermissions(t)),\n ].filter(Boolean)\n\n assertPolicyFitsTempoEnableGas(perms, chainId)\n return getPolicy(perms)\n}\n\nexport type OrderContract = {\n address: `0x${string}`\n isPayAsYouGo: boolean\n}\n\nexport type OrderPolicyOptions = {\n contracts: OrderContract[]\n subscriberAddress: `0x${string}`\n numberOfPurchases: bigint\n totalAmount: bigint\n count?: number\n erc20ContractAddress?: `0x${string}`\n validUntil?: number\n}\n\nexport const getZeroDevOrderPolicies = (orderPolicyOptions: OrderPolicyOptions): Policy[] => {\n const policies: Policy[] = []\n\n const orderPermissions = orderPolicyOptions.contracts.map((contract) => {\n if (contract.isPayAsYouGo) {\n return {\n target: contract.address,\n abi: parseAbi([\n 'function order(bytes32 _seed, uint256 _planId, bytes[] memory _params) external payable',\n ]) as Abi,\n valueLimit: 0n,\n functionName: 'order',\n args: [null, null],\n }\n }\n return {\n target: contract.address,\n abi: parseAbi([\n 'function order(bytes32 _seed, uint256 _planId, address _creditsReceiver, uint256 _numberOfPurchases, bytes[] memory _params) external payable',\n ]) as Abi,\n valueLimit: 0n,\n functionName: 'order',\n args: [\n null,\n null,\n {\n condition: ParamCondition.EQUAL,\n value: orderPolicyOptions.subscriberAddress,\n },\n {\n condition: ParamCondition.EQUAL,\n value: orderPolicyOptions.numberOfPurchases,\n },\n ],\n }\n })\n\n const callPermissions: any[] = [...orderPermissions]\n\n if (\n orderPolicyOptions.erc20ContractAddress &&\n isAddress(orderPolicyOptions.erc20ContractAddress)\n ) {\n callPermissions.push({\n target: orderPolicyOptions.erc20ContractAddress,\n abi: parseAbi([\n 'function approve(address spender, uint256 amount) external returns (bool)',\n ]) as Abi,\n valueLimit: 0n,\n functionName: 'approve',\n args: [\n {\n condition: ParamCondition.NOT_EQUAL,\n value: zeroAddress,\n },\n {\n condition: ParamCondition.LESS_THAN_OR_EQUAL,\n value: orderPolicyOptions.totalAmount,\n },\n ],\n })\n }\n\n policies.push(getPolicy(callPermissions))\n\n if (orderPolicyOptions.count) {\n const rateLimitPolicy = toRateLimitPolicy({\n count: orderPolicyOptions.count,\n })\n policies.push(rateLimitPolicy)\n }\n\n if (orderPolicyOptions.validUntil) {\n const timestampPolicy = toTimestampPolicy({\n validUntil: orderPolicyOptions.validUntil,\n })\n policies.push(timestampPolicy)\n }\n\n return policies\n}\n"],"names":["CallPolicyVersion","ParamCondition","toCallPolicy","toRateLimitPolicy","toTimestampPolicy","assetsRegistryConfig","fixedPaymentTemplateConfig","nft1155CreditsConfig","payAsYouGoTemplateAddress","payAsYouGoTemplateConfig","isAddress","parseAbi","zeroAddress","isTempoNetwork","getPolicy","permissions","policyVersion","V0_0_4","getPermissions","config","functionNames","forEach","entry","name","split","abis","abi","filter","item","type","includes","sig","inputs","map","i","join","length","Error","address","push","target","functionName","dedupeTokens","tokenAddresses","seen","Set","out","t","key","toLowerCase","has","add","getERC20ApprovePermissions","contractAddress","getERC20ApprovePolicy","REGISTER_FN","REGISTER_GROUP_FNS","getAgentRegistrationPolicy","getPricingPlanRegistrationPolicy","getRegisterAssetsPolicy","getOrderPolicy","perms","getMintNFTPolicy","getBurnNFTPolicy","getRegisterPolicy","MAX_CALLPOLICY_PERMISSIONS","assertPolicyFitsTempoEnableGas","chainId","undefined","buildPolicy","getAllContractsPolicy","Boolean","getZeroDevOrderPolicies","orderPolicyOptions","policies","orderPermissions","contracts","contract","isPayAsYouGo","valueLimit","args","condition","EQUAL","value","subscriberAddress","numberOfPurchases","callPermissions","erc20ContractAddress","NOT_EQUAL","LESS_THAN_OR_EQUAL","totalAmount","count","rateLimitPolicy","validUntil","timestampPolicy"],"mappings":"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"}
|
package/dist/utils/Network.d.ts
CHANGED
|
@@ -4,7 +4,12 @@ export declare function isTestnet(networkId: number): boolean;
|
|
|
4
4
|
export declare function getChain(networkId: number | undefined): Chain;
|
|
5
5
|
/**
|
|
6
6
|
* True for Tempo networks (mainnet 4217 + moderato 42431); name-prefixed so new
|
|
7
|
-
* Tempo entries are covered.
|
|
7
|
+
* Tempo entries are covered.
|
|
8
|
+
*
|
|
9
|
+
* Tempo is the only chain with a session-key enable-gas ceiling low enough to
|
|
10
|
+
* constrain what a CallPolicy may contain, so callers use this to apply
|
|
11
|
+
* Tempo-only rules — see `MAX_CALLPOLICY_PERMISSIONS` and the SCA/7702 gate in
|
|
12
|
+
* the API's key minting.
|
|
8
13
|
*/
|
|
9
14
|
export declare function isTempoNetwork(networkId: number | undefined): boolean;
|
|
10
15
|
//# sourceMappingURL=Network.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Network.d.ts","sourceRoot":"","sources":["../../src/utils/Network.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,KAAK,EAiBX,MAAM,aAAa,CAAA;AA0EpB,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIvE;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAIpD;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,CAI7D;AAED
|
|
1
|
+
{"version":3,"file":"Network.d.ts","sourceRoot":"","sources":["../../src/utils/Network.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,KAAK,EAiBX,MAAM,aAAa,CAAA;AA0EpB,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIvE;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAIpD;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,CAI7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGrE"}
|
package/dist/utils/Network.js
CHANGED
|
@@ -229,7 +229,12 @@ export function getChain(networkId) {
|
|
|
229
229
|
}
|
|
230
230
|
/**
|
|
231
231
|
* True for Tempo networks (mainnet 4217 + moderato 42431); name-prefixed so new
|
|
232
|
-
* Tempo entries are covered.
|
|
232
|
+
* Tempo entries are covered.
|
|
233
|
+
*
|
|
234
|
+
* Tempo is the only chain with a session-key enable-gas ceiling low enough to
|
|
235
|
+
* constrain what a CallPolicy may contain, so callers use this to apply
|
|
236
|
+
* Tempo-only rules — see `MAX_CALLPOLICY_PERMISSIONS` and the SCA/7702 gate in
|
|
237
|
+
* the API's key minting.
|
|
233
238
|
*/ export function isTempoNetwork(networkId) {
|
|
234
239
|
const entry = networkId != null ? NETWORKS[networkId] : undefined;
|
|
235
240
|
return Boolean(entry?.name.startsWith('tempo'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/Network.ts"],"sourcesContent":["import { defineChain } from 'viem'\nimport {\n type Chain,\n arbitrum,\n arbitrumSepolia,\n aurora,\n auroraTestnet,\n base,\n baseSepolia,\n celo,\n celoAlfajores,\n gnosis,\n hardhat,\n mainnet,\n optimism,\n polygon,\n polygonMumbai,\n tempo,\n tempoModerato,\n} from 'viem/chains'\nimport { ContractsError } from '../errors/NeverminedErrors.js'\n\nconst localhostChain = (id: number): Chain =>\n defineChain({\n id,\n name: 'Localhost',\n fees: { baseFeeMultiplier: 1.2 },\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: [`http://127.0.0.1:${process.env.ETH_PORT || 18545}`] } },\n })\n\n/**\n * Single source of truth for every supported network (#1929). Each entry ties the\n * chainId to its `name`, `testnet` flag, and viem `chain`. Adding a network is ONE\n * entry here — `getNetworkName` / `isTestnet` / `getChain` all read from this map.\n *\n * `chain` is optional: legacy testnets we still name/classify but no longer have a\n * viem chain for (`getChain` throws for those, as before).\n */\nconst NETWORKS: Record<number, { name: string; testnet: boolean; chain?: Chain }> = {\n 1: { name: 'mainnet', testnet: false, chain: mainnet },\n 2: { name: 'morden', testnet: true },\n 3: { name: 'ropsten', testnet: true },\n 4: { name: 'rinkeby', testnet: true },\n 5: { name: 'goerli', testnet: true },\n 10: { name: 'optimism', testnet: false, chain: optimism as Chain },\n 42: { name: 'kovan', testnet: true },\n 77: { name: 'poa_sokol', testnet: false },\n 99: { name: 'poa_core', testnet: false },\n 100: { name: 'gnosis', testnet: false, chain: gnosis },\n 137: { name: 'matic', testnet: false, chain: polygon },\n 1337: {\n name: 'geth-localnet',\n testnet: true,\n chain: defineChain({\n id: 1337,\n name: 'geth-localnet',\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: ['http://contracts.nevermined.localnet'] } },\n }),\n },\n 3141: { name: 'hyperspace', testnet: true },\n 3338: {\n name: 'peaq-mainnet',\n testnet: false,\n chain: defineChain({\n id: 3338,\n name: 'peaq-network',\n nativeCurrency: { name: 'Peaq', symbol: 'PEAQ', decimals: 18 },\n rpcUrls: { default: { http: ['https://evm.peaq.network'] } },\n }),\n },\n 8453: { name: 'base', testnet: false, chain: base as Chain },\n 8996: { name: 'spree', testnet: true, chain: localhostChain(8996) },\n 8997: { name: 'polygon-localnet', testnet: true, chain: localhostChain(8997) },\n 8998: { name: 'hardhat', testnet: true, chain: localhostChain(8998) },\n 10200: { name: 'chiado', testnet: true }, // Gnosis testnet\n 31337: { name: 'geth-localnet', testnet: true, chain: hardhat },\n 42220: { name: 'celo', testnet: false, chain: celo as Chain },\n 44787: { name: 'celo-alfajores', testnet: true, chain: celoAlfajores as Chain },\n 62320: { name: 'celo-baklava', testnet: true },\n 80001: { name: 'mumbai', testnet: true, chain: polygonMumbai },\n 84532: { name: 'base-sepolia', testnet: true, chain: baseSepolia as Chain },\n 42161: { name: 'arbitrum-one', testnet: false, chain: arbitrum },\n 421613: { name: 'arbitrum-goerli', testnet: true },\n 421614: { name: 'arbitrum-sepolia', testnet: true, chain: arbitrumSepolia },\n 1313161554: { name: 'aurora', testnet: false, chain: aurora },\n 1313161555: { name: 'aurora-testnet', testnet: true, chain: auroraTestnet },\n 1313161556: { name: 'aurora-betanet', testnet: true },\n 4217: { name: 'tempo', testnet: false, chain: tempo as Chain },\n 42431: { name: 'tempo-moderato', testnet: true, chain: tempoModerato as Chain },\n}\n\nexport async function getNetworkName(networkId: number): Promise<string> {\n const entry = NETWORKS[networkId]\n if (!entry) throw new ContractsError(`Network with id ${networkId} not supported.`)\n return entry.name\n}\n\nexport function isTestnet(networkId: number): boolean {\n const entry = NETWORKS[networkId]\n if (!entry) throw new ContractsError(`Network with id ${networkId} not supported.`)\n return entry.testnet\n}\n\nexport function getChain(networkId: number | undefined): Chain {\n const entry = networkId != null ? NETWORKS[networkId] : undefined\n if (!entry?.chain) throw new ContractsError(`Network with id ${networkId} not supported.`)\n return entry.chain\n}\n\n/**\n * True for Tempo networks (mainnet 4217 + moderato 42431); name-prefixed so new\n * Tempo entries are covered
|
|
1
|
+
{"version":3,"sources":["../../src/utils/Network.ts"],"sourcesContent":["import { defineChain } from 'viem'\nimport {\n type Chain,\n arbitrum,\n arbitrumSepolia,\n aurora,\n auroraTestnet,\n base,\n baseSepolia,\n celo,\n celoAlfajores,\n gnosis,\n hardhat,\n mainnet,\n optimism,\n polygon,\n polygonMumbai,\n tempo,\n tempoModerato,\n} from 'viem/chains'\nimport { ContractsError } from '../errors/NeverminedErrors.js'\n\nconst localhostChain = (id: number): Chain =>\n defineChain({\n id,\n name: 'Localhost',\n fees: { baseFeeMultiplier: 1.2 },\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: [`http://127.0.0.1:${process.env.ETH_PORT || 18545}`] } },\n })\n\n/**\n * Single source of truth for every supported network (#1929). Each entry ties the\n * chainId to its `name`, `testnet` flag, and viem `chain`. Adding a network is ONE\n * entry here — `getNetworkName` / `isTestnet` / `getChain` all read from this map.\n *\n * `chain` is optional: legacy testnets we still name/classify but no longer have a\n * viem chain for (`getChain` throws for those, as before).\n */\nconst NETWORKS: Record<number, { name: string; testnet: boolean; chain?: Chain }> = {\n 1: { name: 'mainnet', testnet: false, chain: mainnet },\n 2: { name: 'morden', testnet: true },\n 3: { name: 'ropsten', testnet: true },\n 4: { name: 'rinkeby', testnet: true },\n 5: { name: 'goerli', testnet: true },\n 10: { name: 'optimism', testnet: false, chain: optimism as Chain },\n 42: { name: 'kovan', testnet: true },\n 77: { name: 'poa_sokol', testnet: false },\n 99: { name: 'poa_core', testnet: false },\n 100: { name: 'gnosis', testnet: false, chain: gnosis },\n 137: { name: 'matic', testnet: false, chain: polygon },\n 1337: {\n name: 'geth-localnet',\n testnet: true,\n chain: defineChain({\n id: 1337,\n name: 'geth-localnet',\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: ['http://contracts.nevermined.localnet'] } },\n }),\n },\n 3141: { name: 'hyperspace', testnet: true },\n 3338: {\n name: 'peaq-mainnet',\n testnet: false,\n chain: defineChain({\n id: 3338,\n name: 'peaq-network',\n nativeCurrency: { name: 'Peaq', symbol: 'PEAQ', decimals: 18 },\n rpcUrls: { default: { http: ['https://evm.peaq.network'] } },\n }),\n },\n 8453: { name: 'base', testnet: false, chain: base as Chain },\n 8996: { name: 'spree', testnet: true, chain: localhostChain(8996) },\n 8997: { name: 'polygon-localnet', testnet: true, chain: localhostChain(8997) },\n 8998: { name: 'hardhat', testnet: true, chain: localhostChain(8998) },\n 10200: { name: 'chiado', testnet: true }, // Gnosis testnet\n 31337: { name: 'geth-localnet', testnet: true, chain: hardhat },\n 42220: { name: 'celo', testnet: false, chain: celo as Chain },\n 44787: { name: 'celo-alfajores', testnet: true, chain: celoAlfajores as Chain },\n 62320: { name: 'celo-baklava', testnet: true },\n 80001: { name: 'mumbai', testnet: true, chain: polygonMumbai },\n 84532: { name: 'base-sepolia', testnet: true, chain: baseSepolia as Chain },\n 42161: { name: 'arbitrum-one', testnet: false, chain: arbitrum },\n 421613: { name: 'arbitrum-goerli', testnet: true },\n 421614: { name: 'arbitrum-sepolia', testnet: true, chain: arbitrumSepolia },\n 1313161554: { name: 'aurora', testnet: false, chain: aurora },\n 1313161555: { name: 'aurora-testnet', testnet: true, chain: auroraTestnet },\n 1313161556: { name: 'aurora-betanet', testnet: true },\n 4217: { name: 'tempo', testnet: false, chain: tempo as Chain },\n 42431: { name: 'tempo-moderato', testnet: true, chain: tempoModerato as Chain },\n}\n\nexport async function getNetworkName(networkId: number): Promise<string> {\n const entry = NETWORKS[networkId]\n if (!entry) throw new ContractsError(`Network with id ${networkId} not supported.`)\n return entry.name\n}\n\nexport function isTestnet(networkId: number): boolean {\n const entry = NETWORKS[networkId]\n if (!entry) throw new ContractsError(`Network with id ${networkId} not supported.`)\n return entry.testnet\n}\n\nexport function getChain(networkId: number | undefined): Chain {\n const entry = networkId != null ? NETWORKS[networkId] : undefined\n if (!entry?.chain) throw new ContractsError(`Network with id ${networkId} not supported.`)\n return entry.chain\n}\n\n/**\n * True for Tempo networks (mainnet 4217 + moderato 42431); name-prefixed so new\n * Tempo entries are covered.\n *\n * Tempo is the only chain with a session-key enable-gas ceiling low enough to\n * constrain what a CallPolicy may contain, so callers use this to apply\n * Tempo-only rules — see `MAX_CALLPOLICY_PERMISSIONS` and the SCA/7702 gate in\n * the API's key minting.\n */\nexport function isTempoNetwork(networkId: number | undefined): boolean {\n const entry = networkId != null ? NETWORKS[networkId] : undefined\n return Boolean(entry?.name.startsWith('tempo'))\n}\n"],"names":["defineChain","arbitrum","arbitrumSepolia","aurora","auroraTestnet","base","baseSepolia","celo","celoAlfajores","gnosis","hardhat","mainnet","optimism","polygon","polygonMumbai","tempo","tempoModerato","ContractsError","localhostChain","id","name","fees","baseFeeMultiplier","nativeCurrency","symbol","decimals","rpcUrls","default","http","process","env","ETH_PORT","NETWORKS","testnet","chain","getNetworkName","networkId","entry","isTestnet","getChain","undefined","isTempoNetwork","Boolean","startsWith"],"mappings":"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"}
|