UNPKG

@safe-global/relay-kit

Version:

SDK for Safe Smart Accounts with support for ERC-4337 and Relay

1,099 lines (1,079 loc) 60.3 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // test-utils/index.ts var test_utils_exports = {}; __export(test_utils_exports, { ENTRYPOINT_ABI: () => ENTRYPOINT_ABI, ENTRYPOINT_ADDRESS_V06: () => ENTRYPOINT_ADDRESS_V062, RPC_4337_CALLS: () => RPC_4337_CALLS, createSafe4337Pack: () => createSafe4337Pack, fixtures: () => fixtures_exports, generateTransferCallData: () => generateTransferCallData }); module.exports = __toCommonJS(test_utils_exports); // test-utils/fixtures.ts var fixtures_exports = {}; __export(fixtures_exports, { BUNDLER_URL: () => BUNDLER_URL, CHAIN_ID: () => CHAIN_ID, ENTRYPOINT_ADDRESS_V06: () => ENTRYPOINT_ADDRESS_V06, ENTRYPOINT_ADDRESS_V07: () => ENTRYPOINT_ADDRESS_V07, GAS_ESTIMATION: () => GAS_ESTIMATION, OWNER_1: () => OWNER_1, OWNER_2: () => OWNER_2, PAYMASTER_ADDRESS: () => PAYMASTER_ADDRESS, PAYMASTER_TOKEN_ADDRESS: () => PAYMASTER_TOKEN_ADDRESS, PAYMASTER_URL: () => PAYMASTER_URL, PREDICTED_SAFE_ADDRESS: () => PREDICTED_SAFE_ADDRESS, RPC_URL: () => RPC_URL, SAFE_4337_MODULE_ADDRESS_V0_2_0: () => SAFE_4337_MODULE_ADDRESS_V0_2_0, SAFE_4337_MODULE_ADDRESS_V0_3_0: () => SAFE_4337_MODULE_ADDRESS_V0_3_0, SAFE_ADDRESS_4337_FALLBACKHANDLER_NOT_ENABLED: () => SAFE_ADDRESS_4337_FALLBACKHANDLER_NOT_ENABLED, SAFE_ADDRESS_4337_MODULE_NOT_ENABLED: () => SAFE_ADDRESS_4337_MODULE_NOT_ENABLED, SAFE_ADDRESS_4337_PASSKEY: () => SAFE_ADDRESS_4337_PASSKEY, SAFE_ADDRESS_v1_3_0: () => SAFE_ADDRESS_v1_3_0, SAFE_ADDRESS_v1_4_1_WITH_0_2_0_MODULE: () => SAFE_ADDRESS_v1_4_1_WITH_0_2_0_MODULE, SAFE_ADDRESS_v1_4_1_WITH_0_3_0_MODULE: () => SAFE_ADDRESS_v1_4_1_WITH_0_3_0_MODULE, SAFE_MODULES_V0_3_0: () => SAFE_MODULES_V0_3_0, SAFE_OPERATION_RESPONSE: () => SAFE_OPERATION_RESPONSE, SHARED_SIGNER: () => SHARED_SIGNER, SPONSORED_GAS_ESTIMATION: () => SPONSORED_GAS_ESTIMATION, USER_OPERATION_BY_HASH: () => USER_OPERATION_BY_HASH, USER_OPERATION_GAS_PRICE: () => USER_OPERATION_GAS_PRICE, USER_OPERATION_HASH: () => USER_OPERATION_HASH, USER_OPERATION_HEX_VALUES: () => USER_OPERATION_HEX_VALUES, USER_OPERATION_RECEIPT: () => USER_OPERATION_RECEIPT, USER_OPERATION_V06: () => USER_OPERATION_V06, USER_OPERATION_V07: () => USER_OPERATION_V07, USER_OPERATION_V07_HASH: () => USER_OPERATION_V07_HASH }); var import_types_kit = require("@safe-global/types-kit"); var OWNER_1 = "0xFfAC5578BE8AC1B2B9D13b34cAf4A074B96B8A1b"; var OWNER_2 = "0x3059EfD1BCe33be41eeEfd5fb6D520d7fEd54E43"; var PREDICTED_SAFE_ADDRESS = "0xB71d0a777A692870163FFfd777094217a52DD9e4"; var SAFE_ADDRESS_v1_4_1_WITH_0_3_0_MODULE = "0x5f92e52CD555539a0D30c81FcF6703c04E11dA48"; var SAFE_ADDRESS_v1_4_1_WITH_0_2_0_MODULE = "0x717f4BB83D8DF2e5a3Cc603Ee27263ac9EFB6c12"; var SAFE_ADDRESS_v1_3_0 = "0x8C35a08Af278518B59D04ddDe3F1b370aD766D22"; var SAFE_ADDRESS_4337_MODULE_NOT_ENABLED = "0xfC82a1e4A045a44527e8b45FC70332C8F66fc32B"; var SAFE_ADDRESS_4337_FALLBACKHANDLER_NOT_ENABLED = "0xA6FDc4e18404E1715D1bC51B07266c91393C6622"; var SAFE_ADDRESS_4337_PASSKEY = "0x02DCbFD25178b6b8eFb45603D30b5123179117DD"; var SAFE_MODULES_V0_3_0 = "0.3.0"; var PAYMASTER_ADDRESS = "0x0000000000325602a77416A16136FDafd04b299f"; var PAYMASTER_TOKEN_ADDRESS = "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"; var CHAIN_ID = "0xaa36a7"; var SAFE_4337_MODULE_ADDRESS_V0_2_0 = "0xa581c4A4DB7175302464fF3C06380BC3270b4037"; var SAFE_4337_MODULE_ADDRESS_V0_3_0 = "0x75cf11467937ce3F2f357CE24ffc3DBF8fD5c226"; var SHARED_SIGNER = "0x"; var RPC_URL = "https://sepolia.gateway.tenderly.co"; var BUNDLER_URL = "https://bundler.url"; var PAYMASTER_URL = "https://paymaster.url"; var USER_OPERATION_HASH = "0x3cb881d1969036174f38d636d22108d1d032145518b53104fc0b1e1296d2cc9c"; var ENTRYPOINT_ADDRESS_V06 = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; var ENTRYPOINT_ADDRESS_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032"; var USER_OPERATION_RECEIPT = { userOpHash: "0x3cb881d1969036174f38d636d22108d1d032145518b53104fc0b1e1296d2cc9c", sender: "0x1405B3659a11a16459fc27Fa1925b60388C38Ce1", nonce: "1", actualGasUsed: "0x27067", actualGasCost: "0x42f29418377167", success: true, logs: [], receipt: { transactionHash: "0xef262d20f68e4900aa6380b8ac0f66f9c00a7d988179fa177ad9c9758f0e380e", transactionIndex: "0x63", blockHash: "0x65f8249337ffede2067a006a96da47d3d3445ca72492a6a82afa02899f05d2e5", blockNumber: "0x5378b9", from: "0x4337001Fff419768e088Ce247456c1B892888084", to: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", cumulativeGasUsed: "0xc1a846", gasUsed: "0x25e6c", contractAddress: null, logs: [], logsBloom: "0x000000000000900000000000000000000000000000000000080000000002000000080000000000000402000100000000001000000000000080000200000100000000000000000000000000080000000000000000000000000000002000002000000000000a0000000000000000000800000000000000000000000010000200000000000060100000000000000040000000800000000000000008800000000000000000000000000000400000000000000200000000000000000002000000008000000002000100000001000000000000000000000020000000000000000020010040000000000020000010000008000200000000000000000000000000000000", status: "0x1", effectiveGasPrice: "0x1b67f3c201" } }; var USER_OPERATION_V06 = { sender: "0x1405B3659a11a16459fc27Fa1925b60388C38Ce1", nonce: "1", initCode: "0x", callData: "0x7bb3742800000000000000000000000038869bf66a61cf6bdb996a6ae40d5853fd43b52600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001848d80ff0a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000132001c7d4b196cb0c7b01d743fbc6116a902379c723800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000d725e11588f040d86c4c49d8236e32a5868549f000000000000000000000000000000000000000000000000000000000000186a0001c7d4b196cb0c7b01d743fbc6116a902379c723800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000d725e11588f040d86c4c49d8236e32a5868549f000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000", callGasLimit: 120784n, verificationGasLimit: 83056n, preVerificationGas: 48568n, maxFeePerGas: 193584757388n, maxPriorityFeePerGas: 1380000000n, paymasterAndData: "0x", signature: "0x000000000000000000000000a397ca32ee7fb5282256ee3465da0843485930b803d747516aac76e152f834051ac18fd2b3c0565590f9d65085538993c85c9bb189c940d15c15402c7c2885821b" }; var USER_OPERATION_V07 = { sender: "0x26874a65eA7B6B6655e4582c8D215e1De05dd39b", nonce: "0x0", factory: "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", factoryData: "0x1688f0b900000000000000000000000029fcb43b46531bca003ddc8fcb67ffe91900c7620000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000009a15e37d88ba5900000000000000000000000000000000000000000000000000000000000001e4b63e800d000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000002dd68b007b46fbe91b9a7c3eda5a7a1063cb5b47000000000000000000000000000000000000000000000000000000000000014000000000000000000000000075cf11467937ce3f2f357ce24ffc3dbf8fd5c2260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000bc16a6fbc93f62187a137f30c92e3f90bbbaa49200000000000000000000000000000000000000000000000000000000000000648d0dc49f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000075cf11467937ce3f2f357ce24ffc3dbf8fd5c2260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", callData: "0x7bb3742800000000000000000000000038869bf66a61cf6bdb996a6ae40d5853fd43b52600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001848d80ff0a0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000013200fc3e86566895fb007c6a0d3809eb2827df94f75100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000bc16a6fbc93f62187a137f30c92e3f90bbbaa49200000000000000000000000000000000000000000000000000000000000186a000fc3e86566895fb007c6a0d3809eb2827df94f75100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000bc16a6fbc93f62187a137f30c92e3f90bbbaa49200000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000", callGasLimit: 120784n, verificationGasLimit: 83056n, preVerificationGas: 48568n, maxFeePerGas: 193584757388n, maxPriorityFeePerGas: 1380000000n, paymaster: void 0, paymasterVerificationGasLimit: void 0, paymasterPostOpGasLimit: void 0, paymasterData: void 0, signature: "0x0000679fa3ac000067a1786c8c012f3bef75848690703f17ab0519669bc38bc2629bd8b3118f6280936933fa675bc52dde81cc71c3e0c4587e17ddecf21f845a7a34862b586776501845b1511c" }; var USER_OPERATION_V07_HASH = "0xea46190691c27950a9c4246be1e4550fa1bd85bcf1ad9fe7329b51666722b285"; var USER_OPERATION_HEX_VALUES = { sender: "0x1405B3659a11a16459fc27Fa1925b60388C38Ce1", nonce: "0x1", initCode: "0x", callData: "0x7bb3742800000000000000000000000038869bf66a61cf6bdb996a6ae40d5853fd43b52600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001848d80ff0a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000132001c7d4b196cb0c7b01d743fbc6116a902379c723800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000d725e11588f040d86c4c49d8236e32a5868549f000000000000000000000000000000000000000000000000000000000000186a0001c7d4b196cb0c7b01d743fbc6116a902379c723800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000d725e11588f040d86c4c49d8236e32a5868549f000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000", callGasLimit: "0x1d7d0", verificationGasLimit: "0x14470", preVerificationGas: "0xbdb8", maxFeePerGas: "0x2d128cfa8c", maxPriorityFeePerGas: "0x52412100", paymasterAndData: "0x", signature: "0x000000000000000000000000a397ca32ee7fb5282256ee3465da0843485930b803d747516aac76e152f834051ac18fd2b3c0565590f9d65085538993c85c9bb189c940d15c15402c7c2885821b" }; var USER_OPERATION_BY_HASH = { userOperation: USER_OPERATION_HEX_VALUES, entryPoint: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", transactionHash: "0xef262d20f68e4900aa6380b8ac0f66f9c00a7d988179fa177ad9c9758f0e380e", blockHash: "0x65f8249337ffede2067a006a96da47d3d3445ca72492a6a82afa02899f05d2e5", blockNumber: "0x5378b9" }; var GAS_ESTIMATION = { verificationGasLimit: "0x186A0", preVerificationGas: "0x186A0", callGasLimit: "0x186A0" }; var SAFE_OPERATION_RESPONSE = { created: "2024-05-31T10:12:21.169031Z", modified: "2024-05-31T10:12:21.169031Z", safeOperationHash: "0x5a62b1d61f8fca5f766e9456523bb42765d318058b5f235f967ffe3c2af8b1d7", validAfter: null, validUntil: null, moduleAddress: "0xa581c4A4DB7175302464fF3C06380BC3270b4037", confirmations: [ { created: "2024-05-31T10:12:21.184585Z", modified: "2024-05-31T10:12:21.184585Z", owner: "0x3059EfD1BCe33be41eeEfd5fb6D520d7fEd54E43", signature: "0xcb28e74375889e400a4d8aca46b8c59e1cf8825e373c26fa99c2fd7c078080e64fe30eaf1125257bdfe0b358b5caef68aa0420478145f52decc8e74c979d43ab1d", signatureType: import_types_kit.SignatureTypes.EOA } ], preparedSignature: "0xcb28e74375889e400a4d8aca46b8c59e1cf8825e373c26fa99c2fd7c078080e64fe30eaf1125257bdfe0b358b5caef68aa0420478145f52decc8e74c979d43ab1c", userOperation: { ethereumTxHash: null, sender: "0xE322e721bCe76cE7FCf3A475f139A9314571ad3D", userOperationHash: "0x5d23b7d96a718582601183b1849a4c76b2a13d3787f15074d62a0b6e4a3f76a1", nonce: "3", initCode: "0x", callData: "0x7bb37428000000000000000000000000e322e721bce76ce7fcf3a475f139a9314571ad3d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", callGasLimit: "122497", verificationGasLimit: "123498", preVerificationGas: "50705", maxFeePerGas: "105183831060", maxPriorityFeePerGas: "1380000000", paymaster: null, paymasterData: null, signature: "0x54158da2d357241ee1c5c8fca9c4e1bfa6b92a60bd0ed1bea56f4092b008435153d6264a8a8c00925383ecaeaf9d839a2dc1ff006703c65b7f05d0ce8cdd57ab1b", entryPoint: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" } }; var SPONSORED_GAS_ESTIMATION = { paymasterAndData: "0x1405B3659a11a16459fc27Fa1925b60388C38Ce1", ...GAS_ESTIMATION }; var USER_OPERATION_GAS_PRICE = { fast: { maxFeePerGas: "0x186A0", maxPriorityFeePerGas: "0x30D40" } }; // test-utils/helpers.ts var import_viem10 = require("viem"); // src/packs/safe-4337/Safe4337Pack.ts var import_viem8 = require("viem"); var import_satisfies = __toESM(require("semver/functions/satisfies.js")); var import_protocol_kit4 = __toESM(require("@safe-global/protocol-kit")); // src/RelayKitBasePack.ts var RelayKitBasePack = class { /** * Creates a new RelayKitBasePack instance. * The packs implemented using our SDK should extend this class and therefore provide a Safe SDK instance * @param {Safe} protocolKit - The Safe SDK instance */ constructor(protocolKit) { this.protocolKit = protocolKit; } }; // src/packs/safe-4337/Safe4337Pack.ts var import_types_kit4 = require("@safe-global/types-kit"); var import_safe_modules_deployments = require("@safe-global/safe-modules-deployments"); var import_viem9 = require("viem"); // src/packs/safe-4337/BaseSafeOperation.ts var import_viem = require("viem"); var import_protocol_kit = require("@safe-global/protocol-kit"); var BaseSafeOperation = class { constructor(userOperation, options) { this.signatures = /* @__PURE__ */ new Map(); this.userOperation = userOperation; this.options = options; } getSignature(signer) { return this.signatures.get(signer.toLowerCase()); } addSignature(signature) { this.signatures.set(signature.signer.toLowerCase(), signature); } encodedSignatures() { return (0, import_protocol_kit.buildSignatureBytes)(Array.from(this.signatures.values())); } getUserOperation() { return { ...this.userOperation, signature: (0, import_viem.encodePacked)( ["uint48", "uint48", "bytes"], [ this.options.validAfter || 0, this.options.validUntil || 0, this.encodedSignatures() ] ) }; } getHash() { return (0, import_viem.hashTypedData)({ domain: { chainId: Number(this.options.chainId), verifyingContract: this.options.moduleAddress }, types: this.getEIP712Type(), primaryType: "SafeOp", message: this.getSafeOperation() }); } }; var BaseSafeOperation_default = BaseSafeOperation; // src/packs/safe-4337/constants.ts var import_viem2 = require("viem"); var DEFAULT_SAFE_VERSION = "1.4.1"; var DEFAULT_SAFE_MODULES_VERSION = "0.2.0"; var EIP712_SAFE_OPERATION_TYPE_V06 = { SafeOp: [ { type: "address", name: "safe" }, { type: "uint256", name: "nonce" }, { type: "bytes", name: "initCode" }, { type: "bytes", name: "callData" }, { type: "uint256", name: "callGasLimit" }, { type: "uint256", name: "verificationGasLimit" }, { type: "uint256", name: "preVerificationGas" }, { type: "uint256", name: "maxFeePerGas" }, { type: "uint256", name: "maxPriorityFeePerGas" }, { type: "bytes", name: "paymasterAndData" }, { type: "uint48", name: "validAfter" }, { type: "uint48", name: "validUntil" }, { type: "address", name: "entryPoint" } ] }; var EIP712_SAFE_OPERATION_TYPE_V07 = { SafeOp: [ { type: "address", name: "safe" }, { type: "uint256", name: "nonce" }, { type: "bytes", name: "initCode" }, { type: "bytes", name: "callData" }, { type: "uint128", name: "verificationGasLimit" }, { type: "uint128", name: "callGasLimit" }, { type: "uint256", name: "preVerificationGas" }, { type: "uint128", name: "maxPriorityFeePerGas" }, { type: "uint128", name: "maxFeePerGas" }, { type: "bytes", name: "paymasterAndData" }, { type: "uint48", name: "validAfter" }, { type: "uint48", name: "validUntil" }, { type: "address", name: "entryPoint" } ] }; var ABI = (0, import_viem2.parseAbi)([ "function enableModules(address[])", "function multiSend(bytes memory transactions) public payable", "function executeUserOp(address to, uint256 value, bytes data, uint8 operation)", "function approve(address _spender, uint256 _value)", "function configure((uint256 x, uint256 y, uint176 verifiers) signer)" ]); var ENTRYPOINT_ABI = [ { inputs: [ { name: "sender", type: "address" }, { name: "key", type: "uint192" } ], name: "getNonce", outputs: [{ name: "nonce", type: "uint256" }], stateMutability: "view", type: "function" } ]; var ENTRYPOINT_ADDRESS_V062 = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; var ENTRYPOINT_ADDRESS_V072 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032"; var RPC_4337_CALLS = /* @__PURE__ */ ((RPC_4337_CALLS2) => { RPC_4337_CALLS2["ESTIMATE_USER_OPERATION_GAS"] = "eth_estimateUserOperationGas"; RPC_4337_CALLS2["SEND_USER_OPERATION"] = "eth_sendUserOperation"; RPC_4337_CALLS2["GET_USER_OPERATION_BY_HASH"] = "eth_getUserOperationByHash"; RPC_4337_CALLS2["GET_USER_OPERATION_RECEIPT"] = "eth_getUserOperationReceipt"; RPC_4337_CALLS2["SUPPORTED_ENTRY_POINTS"] = "eth_supportedEntryPoints"; RPC_4337_CALLS2["CHAIN_ID"] = "eth_chainId"; RPC_4337_CALLS2["GET_PAYMASTER_STUB_DATA"] = "pm_getPaymasterStubData"; RPC_4337_CALLS2["GET_PAYMASTER_DATA"] = "pm_getPaymasterData"; return RPC_4337_CALLS2; })(RPC_4337_CALLS || {}); // src/packs/safe-4337/SafeOperationV06.ts var SafeOperationV06 = class extends BaseSafeOperation_default { constructor(userOperation, options) { super(userOperation, options); } addEstimations(estimations) { this.userOperation.maxFeePerGas = BigInt( estimations.maxFeePerGas || this.userOperation.maxFeePerGas ); this.userOperation.maxPriorityFeePerGas = BigInt( estimations.maxPriorityFeePerGas || this.userOperation.maxPriorityFeePerGas ); this.userOperation.verificationGasLimit = BigInt( estimations.verificationGasLimit || this.userOperation.verificationGasLimit ); this.userOperation.preVerificationGas = BigInt( estimations.preVerificationGas || this.userOperation.preVerificationGas ); this.userOperation.callGasLimit = BigInt( estimations.callGasLimit || this.userOperation.callGasLimit ); this.userOperation.paymasterAndData = estimations.paymasterAndData || this.userOperation.paymasterAndData; } getSafeOperation() { return { safe: this.userOperation.sender, nonce: this.userOperation.nonce, initCode: this.userOperation.initCode, callData: this.userOperation.callData, callGasLimit: this.userOperation.callGasLimit, verificationGasLimit: this.userOperation.verificationGasLimit, preVerificationGas: this.userOperation.preVerificationGas, maxFeePerGas: this.userOperation.maxFeePerGas, maxPriorityFeePerGas: this.userOperation.maxPriorityFeePerGas, paymasterAndData: this.userOperation.paymasterAndData, validAfter: this.options.validAfter || 0, validUntil: this.options.validUntil || 0, entryPoint: this.options.entryPoint }; } getEIP712Type() { return EIP712_SAFE_OPERATION_TYPE_V06; } }; var SafeOperationV06_default = SafeOperationV06; // src/packs/safe-4337/SafeOperationV07.ts var import_viem3 = require("viem"); var SafeOperationV07 = class extends BaseSafeOperation_default { constructor(userOperation, options) { super(userOperation, options); } addEstimations(estimations) { this.userOperation.maxFeePerGas = BigInt( estimations.maxFeePerGas || this.userOperation.maxFeePerGas ); this.userOperation.maxPriorityFeePerGas = BigInt( estimations.maxPriorityFeePerGas || this.userOperation.maxPriorityFeePerGas ); this.userOperation.verificationGasLimit = BigInt( estimations.verificationGasLimit || this.userOperation.verificationGasLimit ); this.userOperation.preVerificationGas = BigInt( estimations.preVerificationGas || this.userOperation.preVerificationGas ); this.userOperation.callGasLimit = BigInt( estimations.callGasLimit || this.userOperation.callGasLimit ); this.userOperation.paymasterPostOpGasLimit = estimations.paymasterPostOpGasLimit ? BigInt(estimations.paymasterPostOpGasLimit) : this.userOperation.paymasterPostOpGasLimit; this.userOperation.paymasterVerificationGasLimit = estimations.paymasterVerificationGasLimit ? BigInt(estimations.paymasterVerificationGasLimit) : this.userOperation.paymasterVerificationGasLimit; this.userOperation.paymaster = estimations.paymaster || this.userOperation.paymaster; this.userOperation.paymasterData = estimations.paymasterData || this.userOperation.paymasterData; } getSafeOperation() { const initCode = this.userOperation.factory ? (0, import_viem3.concat)([ this.userOperation.factory, this.userOperation.factoryData || "0x" ]) : "0x"; const paymasterAndData = (0, import_viem3.isAddress)(this.userOperation.paymaster || "") ? (0, import_viem3.concat)([ this.userOperation.paymaster, (0, import_viem3.pad)((0, import_viem3.toHex)(this.userOperation.paymasterVerificationGasLimit || 0n), { size: 16 }), (0, import_viem3.pad)((0, import_viem3.toHex)(this.userOperation.paymasterPostOpGasLimit || 0n), { size: 16 }), this.userOperation.paymasterData || "0x" ]) : "0x"; return { safe: this.userOperation.sender, nonce: this.userOperation.nonce, initCode, callData: this.userOperation.callData, callGasLimit: this.userOperation.callGasLimit, verificationGasLimit: this.userOperation.verificationGasLimit, preVerificationGas: this.userOperation.preVerificationGas, maxFeePerGas: this.userOperation.maxFeePerGas, maxPriorityFeePerGas: this.userOperation.maxPriorityFeePerGas, paymasterAndData, validAfter: this.options.validAfter || 0, validUntil: this.options.validUntil || 0, entryPoint: this.options.entryPoint }; } getEIP712Type() { return EIP712_SAFE_OPERATION_TYPE_V07; } }; var SafeOperationV07_default = SafeOperationV07; // src/packs/safe-4337/utils/index.ts var import_viem7 = require("viem"); var import_types_kit3 = require("@safe-global/types-kit"); var import_protocol_kit3 = require("@safe-global/protocol-kit"); // src/packs/safe-4337/utils/entrypoint.ts var EQ_0_2_0 = "0.2.0"; var EQ_OR_GT_0_3_0 = ">=0.3.0"; function sameString(str1, str2) { return str1.toLowerCase() === str2.toLowerCase(); } function entryPointToSafeModules(entryPoint) { const moduleVersionToEntryPoint = { [ENTRYPOINT_ADDRESS_V062]: EQ_0_2_0, [ENTRYPOINT_ADDRESS_V072]: EQ_OR_GT_0_3_0 }; return moduleVersionToEntryPoint[entryPoint]; } function isEntryPointV6(address) { return sameString(address, ENTRYPOINT_ADDRESS_V062); } function isEntryPointV7(address) { return sameString(address, ENTRYPOINT_ADDRESS_V072); } async function getSafeNonceFromEntrypoint(protocolKit, safeAddress, entryPointAddress) { const safeProvider = protocolKit.getSafeProvider(); const newNonce = await safeProvider.readContract({ address: entryPointAddress || "0x", abi: ENTRYPOINT_ABI, functionName: "getNonce", args: [safeAddress, 0n] }); return newNonce; } // src/packs/safe-4337/utils/signing.ts var import_viem4 = require("viem"); var import_protocol_kit2 = require("@safe-global/protocol-kit"); var DUMMY_CLIENT_DATA_FIELDS = [ `"origin":"https://safe.global"`, `"padding":"This pads the clientDataJSON so that we can leave room for additional implementation specific fields for a more accurate 'preVerificationGas' estimate."` ].join(","); var DUMMY_AUTHENTICATOR_DATA = new Uint8Array(37); DUMMY_AUTHENTICATOR_DATA.fill(254); DUMMY_AUTHENTICATOR_DATA[32] = 4; function getDummySignature(signer, threshold) { const signatures = []; for (let i = 0; i < threshold; i++) { const isContractSignature = true; const passkeySignature = getSignatureBytes({ authenticatorData: DUMMY_AUTHENTICATOR_DATA, clientDataFields: DUMMY_CLIENT_DATA_FIELDS, r: BigInt(`0x${"ec".repeat(32)}`), s: BigInt(`0x${"d5a".repeat(21)}f`) }); signatures.push(new import_protocol_kit2.EthSafeSignature(signer, passkeySignature, isContractSignature)); } return (0, import_viem4.encodePacked)(["uint48", "uint48", "bytes"], [0, 0, (0, import_protocol_kit2.buildSignatureBytes)(signatures)]); } function getSignatureBytes({ authenticatorData, clientDataFields, r, s }) { const encodeUint256 = (x) => x.toString(16).padStart(64, "0"); const byteSize = (data) => 32 * (Math.ceil(data.length / 32) + 1); const encodeBytes = (data) => `${encodeUint256(data.length)}${(0, import_viem4.toHex)(data).slice(2)}`.padEnd(byteSize(data) * 2, "0"); const authenticatorDataOffset = 32 * 4; const clientDataFieldsOffset = authenticatorDataOffset + byteSize(authenticatorData); return "0x" + encodeUint256(authenticatorDataOffset) + encodeUint256(clientDataFieldsOffset) + encodeUint256(r) + encodeUint256(s) + encodeBytes(authenticatorData) + encodeBytes(new TextEncoder().encode(clientDataFields)); } // src/packs/safe-4337/utils/userOperations.ts var import_viem5 = require("viem"); var import_types_kit2 = require("@safe-global/types-kit"); function encodeExecuteUserOpCallData(transaction) { return (0, import_viem5.encodeFunctionData)({ abi: ABI, functionName: "executeUserOp", args: [ transaction.to, BigInt(transaction.value), transaction.data, transaction.operation || import_types_kit2.OperationType.Call ] }); } async function getCallData(protocolKit, transactions, paymasterOptions, amountToApprove) { if (amountToApprove) { const approveToPaymasterTransaction = { to: paymasterOptions.paymasterTokenAddress, data: (0, import_viem5.encodeFunctionData)({ abi: ABI, functionName: "approve", args: [paymasterOptions.paymasterAddress, amountToApprove] }), value: "0", operation: import_types_kit2.OperationType.Call // Call for approve }; transactions.push(approveToPaymasterTransaction); } const isBatch = transactions.length > 1; const multiSendAddress = protocolKit.getMultiSendAddress(); const callData = isBatch ? encodeExecuteUserOpCallData({ to: multiSendAddress, value: "0", data: encodeMultiSendCallData(transactions), operation: import_types_kit2.OperationType.DelegateCall }) : encodeExecuteUserOpCallData(transactions[0]); return callData; } function unpackInitCode(initCode) { const initCodeBytes = (0, import_viem5.hexToBytes)(initCode); return initCodeBytes.length > 0 ? { factory: (0, import_viem5.getAddress)((0, import_viem5.sliceHex)(initCode, 0, 20)), factoryData: (0, import_viem5.sliceHex)(initCode, 20) } : {}; } async function createUserOperation(protocolKit, transactions, { amountToApprove, entryPoint, paymasterOptions, customNonce }) { const safeAddress = await protocolKit.getAddress(); const nonce = customNonce || await getSafeNonceFromEntrypoint(protocolKit, safeAddress, entryPoint); const isSafeDeployed = await protocolKit.isSafeDeployed(); const paymasterAndData = paymasterOptions && "paymasterAddress" in paymasterOptions ? paymasterOptions.paymasterAddress : "0x"; const callData = await getCallData( protocolKit, transactions, paymasterOptions, amountToApprove ); const initCode = isSafeDeployed ? "0x" : await protocolKit.getInitCode(); if (isEntryPointV6(entryPoint)) { return { sender: safeAddress, nonce: nonce.toString(), initCode, callData, callGasLimit: 1n, verificationGasLimit: 1n, preVerificationGas: 1n, maxFeePerGas: 1n, maxPriorityFeePerGas: 1n, paymasterAndData, signature: "0x" }; } return { sender: safeAddress, nonce: nonce.toString(), ...unpackInitCode(initCode), callData, callGasLimit: 1n, verificationGasLimit: 1n, preVerificationGas: 1n, maxFeePerGas: 1n, maxPriorityFeePerGas: 1n, paymaster: paymasterAndData, paymasterData: "0x", paymasterVerificationGasLimit: void 0, paymasterPostOpGasLimit: void 0, signature: "0x" }; } function userOperationToHexValues(userOperation, entryPointAddress) { const userOpV07 = userOperation; const userOperationWithHexValues = { ...userOperation, nonce: (0, import_viem5.toHex)(BigInt(userOperation.nonce)), callGasLimit: (0, import_viem5.toHex)(userOperation.callGasLimit), verificationGasLimit: (0, import_viem5.toHex)(userOperation.verificationGasLimit), preVerificationGas: (0, import_viem5.toHex)(userOperation.preVerificationGas), maxFeePerGas: (0, import_viem5.toHex)(userOperation.maxFeePerGas), maxPriorityFeePerGas: (0, import_viem5.toHex)(userOperation.maxPriorityFeePerGas), ...isEntryPointV7(entryPointAddress) ? { paymaster: userOpV07.paymaster !== "0x" ? userOpV07.paymaster : null, paymasterData: userOpV07.paymasterData !== "0x" ? userOpV07.paymasterData : null, paymasterVerificationGasLimit: userOpV07.paymasterVerificationGasLimit ? (0, import_viem5.toHex)(userOpV07.paymasterVerificationGasLimit) : null, paymasterPostOpGasLimit: userOpV07.paymasterPostOpGasLimit ? (0, import_viem5.toHex)(userOpV07.paymasterPostOpGasLimit) : null } : {} }; return userOperationWithHexValues; } // src/packs/safe-4337/utils/getRelayKitVersion.ts var getRelayKitVersion = () => "4.0.4"; // src/packs/safe-4337/utils/encodeNonce.ts var import_viem6 = require("viem"); // src/packs/safe-4337/utils/index.ts function createBundlerClient(bundlerUrl) { const provider = (0, import_viem7.createPublicClient)({ transport: (0, import_viem7.http)(bundlerUrl), rpcSchema: (0, import_viem7.rpcSchema)() }); return provider; } function encodeMultiSendCallData(transactions) { return (0, import_viem7.encodeFunctionData)({ abi: ABI, functionName: "multiSend", args: [ (0, import_protocol_kit3.encodeMultiSendData)( transactions.map((tx) => ({ ...tx, operation: tx.operation ?? import_types_kit3.OperationType.Call })) ) ] }); } // src/packs/safe-4337/SafeOperationFactory.ts var SafeOperationFactory = class { /** * Creates a new SafeOperation with proper validation * @param userOperation - The base user operation * @param options - Configuration options * @returns Validated SafeOperation instance */ static createSafeOperation(userOperation, options) { if (isEntryPointV6(options.entryPoint)) { return new SafeOperationV06_default(userOperation, options); } return new SafeOperationV07_default(userOperation, options); } }; var SafeOperationFactory_default = SafeOperationFactory; // src/packs/safe-4337/estimators/pimlico/PimlicoFeeEstimator.ts var PimlicoFeeEstimator = class { async preEstimateUserOperationGas({ bundlerUrl, userOperation, entryPoint, paymasterOptions }) { const bundlerClient = createBundlerClient(bundlerUrl); const feeData = await this.#getUserOperationGasPrices(bundlerClient); const chainId = await this.#getChainId(bundlerClient); let paymasterStubData = {}; if (paymasterOptions) { const paymasterClient = createBundlerClient( paymasterOptions.paymasterUrl ); const context = "paymasterTokenAddress" in paymasterOptions ? { token: paymasterOptions.paymasterTokenAddress } : void 0; paymasterStubData = await paymasterClient.request({ method: "pm_getPaymasterStubData" /* GET_PAYMASTER_STUB_DATA */, params: [userOperationToHexValues(userOperation, entryPoint), entryPoint, chainId, context] }); } return { ...feeData, ...paymasterStubData }; } async postEstimateUserOperationGas({ userOperation, entryPoint, paymasterOptions }) { if (!paymasterOptions) return {}; const paymasterClient = createBundlerClient( paymasterOptions.paymasterUrl ); if (paymasterOptions.isSponsored) { const params = [ userOperationToHexValues(userOperation, entryPoint), entryPoint ]; if (paymasterOptions.sponsorshipPolicyId) { params.push({ sponsorshipPolicyId: paymasterOptions.sponsorshipPolicyId }); } const sponsoredData = await paymasterClient.request({ method: "pm_sponsorUserOperation" /* SPONSOR_USER_OPERATION */, params }); return sponsoredData; } const chainId = await this.#getChainId(paymasterClient); const erc20PaymasterData = await paymasterClient.request({ method: "pm_getPaymasterData" /* GET_PAYMASTER_DATA */, params: [ userOperationToHexValues(userOperation, entryPoint), entryPoint, chainId, { token: paymasterOptions.paymasterTokenAddress } ] }); return erc20PaymasterData; } async #getUserOperationGasPrices(client) { const feeData = await client.request({ method: "pimlico_getUserOperationGasPrice" /* GET_USER_OPERATION_GAS_PRICE */ }); const { fast: { maxFeePerGas, maxPriorityFeePerGas } } = feeData; return { maxFeePerGas, maxPriorityFeePerGas }; } async #getChainId(client) { const chainId = await client.request({ method: "eth_chainId" }); return chainId; } }; // src/packs/safe-4337/Safe4337Pack.ts var MAX_ERC20_AMOUNT_TO_APPROVE = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn; var EQ_OR_GT_1_4_1 = ">=1.4.1"; var Safe4337Pack = class _Safe4337Pack extends RelayKitBasePack { #BUNDLER_URL; #ENTRYPOINT_ADDRESS; #SAFE_4337_MODULE_ADDRESS = "0x"; #SAFE_WEBAUTHN_SHARED_SIGNER_ADDRESS = "0x"; #bundlerClient; #chainId; #paymasterOptions; #onchainIdentifier = ""; /** * Creates an instance of the Safe4337Pack. * * @param {Safe4337Options} options - The initialization parameters. */ constructor({ protocolKit, bundlerClient, bundlerUrl, chainId, paymasterOptions, entryPointAddress, safe4337ModuleAddress, safeWebAuthnSharedSignerAddress, onchainAnalytics }) { super(protocolKit); this.#BUNDLER_URL = bundlerUrl; this.#bundlerClient = bundlerClient; this.#chainId = chainId; this.#paymasterOptions = paymasterOptions; this.#ENTRYPOINT_ADDRESS = entryPointAddress; this.#SAFE_4337_MODULE_ADDRESS = safe4337ModuleAddress; this.#SAFE_WEBAUTHN_SHARED_SIGNER_ADDRESS = safeWebAuthnSharedSignerAddress || "0x"; if (onchainAnalytics?.project) { const { project, platform } = onchainAnalytics; this.#onchainIdentifier = (0, import_protocol_kit4.generateOnChainIdentifier)({ project, platform, tool: "relay-kit", toolVersion: getRelayKitVersion() }); } } /** * Initializes a Safe4337Pack class. * This method creates the protocolKit instance based on the input parameters. * When the Safe address is provided, it will use the existing Safe. * When the Safe address is not provided, it will use the predictedSafe feature with the provided owners and threshold. * It will use the correct contract addresses for the fallbackHandler and the module and will add the data to enable the 4337 module. * * @param {Safe4337InitOptions} initOptions - The initialization parameters. * @return {Promise<Safe4337Pack>} The Promise object that will be resolved into an instance of Safe4337Pack. */ static async init(initOptions) { const { provider, signer, options, bundlerUrl, customContracts, paymasterOptions, onchainAnalytics } = initOptions; let protocolKit; const bundlerClient = createBundlerClient(bundlerUrl); const chainId = await bundlerClient.request({ method: "eth_chainId" /* CHAIN_ID */ }); let safeModulesSetupAddress = customContracts?.safeModulesSetupAddress; const network = parseInt(chainId, 16).toString(); const safeModulesVersion = initOptions.safeModulesVersion || DEFAULT_SAFE_MODULES_VERSION; if (!safeModulesSetupAddress) { const safeModuleSetupDeployment = (0, import_safe_modules_deployments.getSafeModuleSetupDeployment)({ released: true, version: safeModulesVersion, network }); safeModulesSetupAddress = safeModuleSetupDeployment?.networkAddresses[network]; } let safe4337ModuleAddress = customContracts?.safe4337ModuleAddress; if (!safe4337ModuleAddress) { const safe4337ModuleDeployment = (0, import_safe_modules_deployments.getSafe4337ModuleDeployment)({ released: true, version: safeModulesVersion, network }); safe4337ModuleAddress = safe4337ModuleDeployment?.networkAddresses[network]; } if (!safeModulesSetupAddress || !safe4337ModuleAddress) { throw new Error( `Safe4337Module and/or SafeModuleSetup not available for chain ${network} and modules version ${safeModulesVersion}` ); } let safeWebAuthnSharedSignerAddress = customContracts?.safeWebAuthnSharedSignerAddress; if ("safeAddress" in options) { protocolKit = await import_protocol_kit4.default.init({ provider, signer, safeAddress: options.safeAddress }); const safeVersion = protocolKit.getContractVersion(); const isSafeVersion4337Compatible = (0, import_satisfies.default)(safeVersion, EQ_OR_GT_1_4_1); if (!isSafeVersion4337Compatible) { throw new Error( `Incompatibility detected: The current Safe Account version (${safeVersion}) is not supported. EIP-4337 requires the Safe to use at least v1.4.1.` ); } const safeModules = await protocolKit.getModules(); const is4337ModulePresent = safeModules.some((module2) => module2 === safe4337ModuleAddress); if (!is4337ModulePresent) { throw new Error( `Incompatibility detected: The EIP-4337 module is not enabled in the provided Safe Account. Enable this module (address: ${safe4337ModuleAddress}) to add compatibility.` ); } const safeFallbackhandler = await protocolKit.getFallbackHandler(); const is4337FallbackhandlerPresent = safeFallbackhandler === safe4337ModuleAddress; if (!is4337FallbackhandlerPresent) { throw new Error( `Incompatibility detected: The EIP-4337 fallbackhandler is not attached to the Safe Account. Attach this fallbackhandler (address: ${safe4337ModuleAddress}) to ensure compatibility.` ); } } else { if (!options.owners || !options.threshold) { throw new Error("Owners and threshold are required to deploy a new Safe"); } const safeVersion = options.safeVersion || DEFAULT_SAFE_VERSION; const enable4337ModuleTransaction = { to: safeModulesSetupAddress, value: "0", data: (0, import_viem9.encodeFunctionData)({ abi: ABI, functionName: "enableModules", args: [[safe4337ModuleAddress]] }), operation: import_types_kit4.OperationType.DelegateCall // DelegateCall required for enabling the 4337 module }; const setupTransactions = [enable4337ModuleTransaction]; const isApproveTransactionRequired = !!paymasterOptions && !paymasterOptions.isSponsored && !!paymasterOptions.paymasterTokenAddress; if (isApproveTransactionRequired) { const { paymasterAddress, amountToApprove = MAX_ERC20_AMOUNT_TO_APPROVE } = paymasterOptions; const approveToPaymasterTransaction = { to: paymasterOptions.paymasterTokenAddress, data: (0, import_viem9.encodeFunctionData)({ abi: ABI, functionName: "approve", args: [paymasterAddress, amountToApprove] }), value: "0", operation: import_types_kit4.OperationType.Call // Call for approve }; setupTransactions.push(approveToPaymasterTransaction); } const safeProvider = await import_protocol_kit4.SafeProvider.init({ provider, signer, safeVersion }); const isPasskeySigner = await safeProvider.isPasskeySigner(); if (isPasskeySigner) { if (!safeWebAuthnSharedSignerAddress) { const safeWebAuthnSharedSignerDeployment = (0, import_safe_modules_deployments.getSafeWebAuthnShareSignerDeployment)({ released: true, version: "0.2.1", network }); safeWebAuthnSharedSignerAddress = safeWebAuthnSharedSignerDeployment?.networkAddresses[network]; } if (!safeWebAuthnSharedSignerAddress) { throw new Error(`safeWebAuthnSharedSignerAddress not available for chain ${network}`); } const passkeySigner = await safeProvider.getExternalSigner(); const checkSummedOwners = options.owners.map((owner) => (0, import_viem8.getAddress)(owner)); const checkSummedSignerAddress = (0, import_viem8.getAddress)(safeWebAuthnSharedSignerAddress); if (!checkSummedOwners.includes(checkSummedSignerAddress)) { options.owners.push(checkSummedSignerAddress); } const sharedSignerTransaction = { to: safeWebAuthnSharedSignerAddress, value: "0", data: passkeySigner.encodeConfigure(), operation: import_types_kit4.OperationType.DelegateCall // DelegateCall required into the SafeWebAuthnSharedSigner instance in order for it to set its configuration. }; setupTransactions.push(sharedSignerTransaction); } let deploymentTo; let deploymentData; const isBatch = setupTransactions.length > 1; if (isBatch) { const multiSendContract = await (0, import_protocol_kit4.getMultiSendContract)({ safeProvider, safeVersion, deploymentType: options.deploymentType || void 0 }); const batchData = (0, import_viem9.encodeFunctionData)({ abi: ABI, functionName: "multiSend", args: [(0, import_protocol_kit4.encodeMultiSendData)(setupTransactions)] }); deploymentTo = multiSendContract.getAddress(); deploymentData = batchData; } else { deploymentTo = enable4337ModuleTransaction.to; deploymentData = enable4337ModuleTransaction.data; } protocolKit = await import_protocol_kit4.default.init({ provider, signer, predictedSafe: { safeDeploymentConfig: { safeVersion, saltNonce: options.saltNonce || void 0, deploymentType: options.deploymentType || void 0 }, safeAccountConfig: { owners: options.owners, threshold: options.threshold, to: deploymentTo, data: deploymentData, fallbackHandler: safe4337ModuleAddress, paymentToken: import_viem9.zeroAddress, payment: 0, paymentReceiver: import_viem9.zeroAddress } }, onchainAnalytics }); } let selectedEntryPoint; if (customContracts?.entryPointAddress) { const requiredSafeModulesVersion = entryPointToSafeModules(customContracts?.entryPointAddress); if (!(0, import_satisfies.default)(safeModulesVersion, requiredSafeModulesVersion)) throw new Error( `The selected entrypoint ${customContracts?.entryPointAddress} is not compatible with version ${safeModulesVersion} of Safe modules` ); selectedEntryPoint = customContracts?.entryPointAddress; } else { const supportedEntryPoints = await bundlerClient.request({ method: "eth_supportedEntryPoints" /* SUPPORTED_ENTRY_POINTS */ }); if (!supportedEntryPoints.length) { throw new Error("No entrypoint provided or available through the bundler"); } selectedEntryPoint = supportedEntryPoints.find((entryPoint) => { const requiredSafeModulesVersion = entryPointToSafeModules(entryPoint); return (0, import_satisfies.default)(safeModulesVersion, requiredSafeModulesVersion); }); if (!selectedEntryPoint) { throw new Error( `Incompatibility detected: None of the entrypoints provided by the bundler is compatible with the Safe modules version ${safeModulesVersion}` ); } } return new _Safe4337Pack({ chainId: BigInt(chainId), protocolKit, bundlerClient, paymasterOptions, bundlerUrl, entryPointAddress: selectedEntryPoint, safe4337ModuleAddress, safeWebAuthnSharedSignerAddress, onchainAnalytics }); } /** * Estimates gas for the SafeOperation. * * @param {EstimateFeeProps} props - The parameters for the gas estimation. * @param {BaseSafeOperation} props.safeOperation - The SafeOperation to estimate the gas. * @param {IFeeEstimator} props.feeEstimator - The function to estimate the gas. * @return {Promise<BaseSafeOperation>} The Promise object that will be resolved into the gas estimation. */ async getEstimateFee({ safeOperation, feeEstimator = new PimlicoFeeEstimator() }) { const threshold = await this.protocolKit.getThreshold(); const preEstimationData = await feeEstimator?.preEstimateUserOperationGas?.({ bundlerUrl: this.#BUNDLER_URL, entryPoint: this.#ENTRYPOINT_ADDRESS, userOperation: safeOperation.getUserOperation(), paymasterOptions: this.#paymasterOptions }); if (preEstimationData) { safeOperation.addEstimations(preEstimationData); } const estimateUserOperationGas = await this.#bundlerClient.request({ method: "eth_estimateUserOperationGas" /* ESTIMATE_USER_OPERATION_GAS */, params: [ { ...userOperationToHexValues(safeOperation.getUserOperation(), this.#ENTRYPOINT_ADDRESS), signature: getDummySignature(this.#SAFE_WEBAUTHN_SHARED_SIGNER_ADDRESS, threshold) }, this.#ENTRYPOINT_ADDRESS ] }); if (estimateUserOperationGas) { safeOperation.addEstimations(estimateUserOperationGas); } const postEstimationData = await feeEstimator?.postEstimateUserOperationGas?.({ bundlerUrl: this.#BUNDLER_URL, entryPoint: this.#ENTRYPOINT_ADDRESS, userOperation: { ...safeOperation.getUserOperation(), signature: getDummySignature(this.#SAFE_WEBAUTHN_SHARED_SIGNER_ADDRESS, threshold) }, paymasterOptions: this.#paymasterOptions }); if (postEstima