UNPKG

permissionless

Version:

A utility library for working with ERC-4337

1,082 lines • 39.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getDefaultAddresses = exports.EIP712_SAFE_OPERATION_TYPE_V07 = exports.EIP712_SAFE_OPERATION_TYPE_V06 = void 0; exports.getPaymasterAndData = getPaymasterAndData; exports.toSafeSmartAccount = toSafeSmartAccount; const viem_1 = require("viem"); const account_abstraction_1 = require("viem/account-abstraction"); const actions_1 = require("viem/actions"); const utils_1 = require("viem/utils"); const getAccountNonce_js_1 = require("../../actions/public/getAccountNonce.js"); const decode7579Calls_js_1 = require("../../utils/decode7579Calls.js"); const encode7579Calls_js_1 = require("../../utils/encode7579Calls.js"); const isSmartAccountDeployed_js_1 = require("../../utils/isSmartAccountDeployed.js"); const toOwner_js_1 = require("../../utils/toOwner.js"); const signUserOperation_js_1 = require("./signUserOperation.js"); const multiSendAbi = [ { inputs: [ { internalType: "bytes", name: "transactions", type: "bytes" } ], name: "multiSend", outputs: [], stateMutability: "payable", type: "function" } ]; const initSafe7579Abi = [ { type: "function", name: "initSafe7579", inputs: [ { name: "safe7579", type: "address", internalType: "address" }, { name: "executors", type: "tuple[]", internalType: "struct ModuleInit[]", components: [ { name: "module", type: "address", internalType: "address" }, { name: "initData", type: "bytes", internalType: "bytes" } ] }, { name: "fallbacks", type: "tuple[]", internalType: "struct ModuleInit[]", components: [ { name: "module", type: "address", internalType: "address" }, { name: "initData", type: "bytes", internalType: "bytes" } ] }, { name: "hooks", type: "tuple[]", internalType: "struct ModuleInit[]", components: [ { name: "module", type: "address", internalType: "address" }, { name: "initData", type: "bytes", internalType: "bytes" } ] }, { name: "attesters", type: "address[]", internalType: "address[]" }, { name: "threshold", type: "uint8", internalType: "uint8" } ], outputs: [], stateMutability: "nonpayable" } ]; const preValidationSetupAbi = [ { type: "function", name: "preValidationSetup", inputs: [ { name: "initHash", type: "bytes32", internalType: "bytes32" }, { name: "to", type: "address", internalType: "address" }, { name: "preInit", type: "bytes", internalType: "bytes" } ], outputs: [], stateMutability: "nonpayable" } ]; const enableModulesAbi = [ { inputs: [ { internalType: "address[]", name: "modules", type: "address[]" } ], name: "enableModules", outputs: [], stateMutability: "nonpayable", type: "function" } ]; const setupAbi = [ { inputs: [ { internalType: "address[]", name: "_owners", type: "address[]" }, { internalType: "uint256", name: "_threshold", type: "uint256" }, { internalType: "address", name: "to", type: "address" }, { internalType: "bytes", name: "data", type: "bytes" }, { internalType: "address", name: "fallbackHandler", type: "address" }, { internalType: "address", name: "paymentToken", type: "address" }, { internalType: "uint256", name: "payment", type: "uint256" }, { internalType: "address payable", name: "paymentReceiver", type: "address" } ], name: "setup", outputs: [], stateMutability: "nonpayable", type: "function" } ]; const createProxyWithNonceAbi = [ { inputs: [ { internalType: "address", name: "_singleton", type: "address" }, { internalType: "bytes", name: "initializer", type: "bytes" }, { internalType: "uint256", name: "saltNonce", type: "uint256" } ], name: "createProxyWithNonce", outputs: [ { internalType: "contract SafeProxy", name: "proxy", type: "address" } ], stateMutability: "nonpayable", type: "function" } ]; const setupSafeAbi = [ { type: "function", name: "setupSafe", inputs: [ { name: "initData", type: "tuple", internalType: "struct Safe7579Launchpad.InitData", components: [ { name: "singleton", type: "address", internalType: "address" }, { name: "owners", type: "address[]", internalType: "address[]" }, { name: "threshold", type: "uint256", internalType: "uint256" }, { name: "setupTo", type: "address", internalType: "address" }, { name: "setupData", type: "bytes", internalType: "bytes" }, { name: "safe7579", type: "address", internalType: "contract ISafe7579" }, { name: "validators", type: "tuple[]", internalType: "struct ModuleInit[]", components: [ { name: "module", type: "address", internalType: "address" }, { name: "initData", type: "bytes", internalType: "bytes" } ] }, { name: "callData", type: "bytes", internalType: "bytes" } ] } ], outputs: [], stateMutability: "nonpayable" } ]; const executeUserOpWithErrorStringAbi = [ { inputs: [ { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }, { internalType: "bytes", name: "data", type: "bytes" }, { internalType: "uint8", name: "operation", type: "uint8" } ], name: "executeUserOpWithErrorString", outputs: [], stateMutability: "nonpayable", type: "function" } ]; exports.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" } ] }; exports.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" } ] }; const SAFE_VERSION_TO_ADDRESSES_MAP = { "1.4.1": { "0.6": { SAFE_MODULE_SETUP_ADDRESS: "0x8EcD4ec46D4D2a6B64fE960B3D64e8B94B2234eb", SAFE_4337_MODULE_ADDRESS: "0xa581c4A4DB7175302464fF3C06380BC3270b4037", SAFE_PROXY_FACTORY_ADDRESS: "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", SAFE_SINGLETON_ADDRESS: "0x41675C099F32341bf84BFc5382aF534df5C7461a", MULTI_SEND_ADDRESS: "0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526", MULTI_SEND_CALL_ONLY_ADDRESS: "0x9641d764fc13c8B624c04430C7356C1C7C8102e2" }, "0.7": { SAFE_MODULE_SETUP_ADDRESS: "0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47", SAFE_4337_MODULE_ADDRESS: "0x75cf11467937ce3F2f357CE24ffc3DBF8fD5c226", SAFE_PROXY_FACTORY_ADDRESS: "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", SAFE_SINGLETON_ADDRESS: "0x41675C099F32341bf84BFc5382aF534df5C7461a", MULTI_SEND_ADDRESS: "0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526", MULTI_SEND_CALL_ONLY_ADDRESS: "0x9641d764fc13c8B624c04430C7356C1C7C8102e2" } } }; const adjustVInSignature = (signingMethod, signature) => { const ETHEREUM_V_VALUES = [0, 1, 27, 28]; const MIN_VALID_V_VALUE_FOR_SAFE_ECDSA = 27; let signatureV = Number.parseInt(signature.slice(-2), 16); if (!ETHEREUM_V_VALUES.includes(signatureV)) { throw new Error("Invalid signature"); } if (signingMethod === "eth_sign") { if (signatureV < MIN_VALID_V_VALUE_FOR_SAFE_ECDSA) { signatureV += MIN_VALID_V_VALUE_FOR_SAFE_ECDSA; } signatureV += 4; } if (signingMethod === "eth_signTypedData") { if (signatureV < MIN_VALID_V_VALUE_FOR_SAFE_ECDSA) { signatureV += MIN_VALID_V_VALUE_FOR_SAFE_ECDSA; } } return (signature.slice(0, -2) + signatureV.toString(16)); }; const generateSafeMessageMessage = (message) => { const signableMessage = message; if (typeof signableMessage === "string" || signableMessage.raw) { return (0, viem_1.hashMessage)(signableMessage); } return (0, viem_1.hashTypedData)(message); }; const encodeInternalTransaction = (tx) => { const encoded = (0, viem_1.encodePacked)(["uint8", "address", "uint256", "uint256", "bytes"], [ tx.operation, tx.to, tx.value, BigInt(tx.data.slice(2).length / 2), tx.data ]); return encoded.slice(2); }; const encodeMultiSend = (txs) => { const data = `0x${txs .map((tx) => encodeInternalTransaction(tx)) .join("")}`; return (0, viem_1.encodeFunctionData)({ abi: multiSendAbi, functionName: "multiSend", args: [data] }); }; const get7579LaunchPadInitData = ({ safe4337ModuleAddress, safeSingletonAddress, erc7579LaunchpadAddress, owners, validators, executors, fallbacks, hooks, attesters, threshold, attestersThreshold }) => { const initData = { singleton: safeSingletonAddress, owners: owners, threshold: threshold, setupTo: erc7579LaunchpadAddress, setupData: (0, viem_1.encodeFunctionData)({ abi: initSafe7579Abi, functionName: "initSafe7579", args: [ safe4337ModuleAddress, executors.map((executor) => ({ module: executor.address, initData: executor.context })), fallbacks.map((fallback) => ({ module: fallback.address, initData: fallback.context })), hooks.map((hook) => ({ module: hook.address, initData: hook.context })), attesters.sort((left, right) => left.toLowerCase().localeCompare(right.toLowerCase())), attestersThreshold ] }), safe7579: safe4337ModuleAddress, validators: validators }; return initData; }; const getInitializerCode = async ({ owners, threshold, safeModuleSetupAddress, safe4337ModuleAddress, multiSendAddress, safeSingletonAddress, erc7579LaunchpadAddress, setupTransactions = [], safeModules = [], validators = [], executors = [], fallbacks = [], hooks = [], attesters = [], attestersThreshold = 0, paymentToken = viem_1.zeroAddress, payment = BigInt(0), paymentReceiver = viem_1.zeroAddress }) => { if (erc7579LaunchpadAddress) { const initData = get7579LaunchPadInitData({ safe4337ModuleAddress, safeSingletonAddress, erc7579LaunchpadAddress, owners, validators, executors, fallbacks, threshold, hooks, attesters, attestersThreshold }); const initHash = (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([ { internalType: "address", name: "singleton", type: "address" }, { internalType: "address[]", name: "owners", type: "address[]" }, { internalType: "uint256", name: "threshold", type: "uint256" }, { internalType: "address", name: "setupTo", type: "address" }, { internalType: "bytes", name: "setupData", type: "bytes" }, { internalType: "contract ISafe7579", name: "safe7579", type: "address" }, { internalType: "struct ModuleInit[]", name: "validators", type: "tuple[]", components: [ { internalType: "address", name: "module", type: "address" }, { internalType: "bytes", name: "initData", type: "bytes" } ] } ], [ initData.singleton, initData.owners, initData.threshold, initData.setupTo, initData.setupData, initData.safe7579, initData.validators.map((validator) => ({ module: validator.address, initData: validator.context })) ])); return (0, viem_1.encodeFunctionData)({ abi: preValidationSetupAbi, functionName: "preValidationSetup", args: [initHash, viem_1.zeroAddress, "0x"] }); } const multiSendCallData = encodeMultiSend([ { to: safeModuleSetupAddress, data: (0, viem_1.encodeFunctionData)({ abi: enableModulesAbi, functionName: "enableModules", args: [[safe4337ModuleAddress, ...safeModules]] }), value: BigInt(0), operation: 1 }, ...setupTransactions.map((tx) => ({ ...tx, operation: 0 })) ]); return (0, viem_1.encodeFunctionData)({ abi: setupAbi, functionName: "setup", args: [ owners, threshold, multiSendAddress, multiSendCallData, safe4337ModuleAddress, paymentToken, payment, paymentReceiver ] }); }; function getPaymasterAndData(unpackedUserOperation) { return unpackedUserOperation.paymaster ? (0, viem_1.concat)([ unpackedUserOperation.paymaster, (0, viem_1.pad)((0, viem_1.toHex)(unpackedUserOperation.paymasterVerificationGasLimit || BigInt(0)), { size: 16 }), (0, viem_1.pad)((0, viem_1.toHex)(unpackedUserOperation.paymasterPostOpGasLimit || BigInt(0)), { size: 16 }), unpackedUserOperation.paymasterData || "0x" ]) : "0x"; } const getAccountInitCode = async ({ owners, threshold, safeModuleSetupAddress, safe4337ModuleAddress, safeSingletonAddress, erc7579LaunchpadAddress, multiSendAddress, paymentToken, payment, paymentReceiver, saltNonce = BigInt(0), setupTransactions = [], safeModules = [], validators = [], executors = [], fallbacks = [], hooks = [], attesters = [], attestersThreshold = 0 }) => { const initializer = await getInitializerCode({ owners, threshold, safeModuleSetupAddress, safe4337ModuleAddress, multiSendAddress, setupTransactions, safeSingletonAddress, safeModules, erc7579LaunchpadAddress, validators, executors, fallbacks, hooks, attesters, attestersThreshold, paymentToken, payment, paymentReceiver }); const initCodeCallData = (0, viem_1.encodeFunctionData)({ abi: createProxyWithNonceAbi, functionName: "createProxyWithNonce", args: [ erc7579LaunchpadAddress ?? safeSingletonAddress, initializer, saltNonce ] }); return initCodeCallData; }; const getDefaultAddresses = (safeVersion, entryPointVersion, { addModuleLibAddress: _addModuleLibAddress, safeModuleSetupAddress: _safeModuleSetupAddress, safe4337ModuleAddress: _safe4337ModuleAddress, safeProxyFactoryAddress: _safeProxyFactoryAddress, safeSingletonAddress: _safeSingletonAddress, multiSendAddress: _multiSendAddress, multiSendCallOnlyAddress: _multiSendCallOnlyAddress }) => { const safeModuleSetupAddress = _safeModuleSetupAddress ?? _addModuleLibAddress ?? SAFE_VERSION_TO_ADDRESSES_MAP[safeVersion][entryPointVersion] .SAFE_MODULE_SETUP_ADDRESS; const safe4337ModuleAddress = _safe4337ModuleAddress ?? SAFE_VERSION_TO_ADDRESSES_MAP[safeVersion][entryPointVersion] .SAFE_4337_MODULE_ADDRESS; const safeProxyFactoryAddress = _safeProxyFactoryAddress ?? SAFE_VERSION_TO_ADDRESSES_MAP[safeVersion][entryPointVersion] .SAFE_PROXY_FACTORY_ADDRESS; const safeSingletonAddress = _safeSingletonAddress ?? SAFE_VERSION_TO_ADDRESSES_MAP[safeVersion][entryPointVersion] .SAFE_SINGLETON_ADDRESS; const multiSendAddress = _multiSendAddress ?? SAFE_VERSION_TO_ADDRESSES_MAP[safeVersion][entryPointVersion] .MULTI_SEND_ADDRESS; const multiSendCallOnlyAddress = _multiSendCallOnlyAddress ?? SAFE_VERSION_TO_ADDRESSES_MAP[safeVersion][entryPointVersion] .MULTI_SEND_CALL_ONLY_ADDRESS; return { safeModuleSetupAddress, safe4337ModuleAddress, safeProxyFactoryAddress, safeSingletonAddress, multiSendAddress, multiSendCallOnlyAddress }; }; exports.getDefaultAddresses = getDefaultAddresses; function isErc7579Args(args) { return args.erc7579LaunchpadAddress !== undefined; } const proxyCreationCodeAbi = [ { inputs: [], name: "proxyCreationCode", outputs: [ { internalType: "bytes", name: "", type: "bytes" } ], stateMutability: "pure", type: "function" } ]; const getAccountAddress = async ({ client, owners, threshold, safeModuleSetupAddress, safe4337ModuleAddress, safeProxyFactoryAddress, safeSingletonAddress, multiSendAddress, erc7579LaunchpadAddress, paymentToken, payment, paymentReceiver, setupTransactions = [], safeModules = [], saltNonce = BigInt(0), validators = [], executors = [], fallbacks = [], hooks = [], attesters = [], attestersThreshold = 0 }) => { const proxyCreationCode = await (0, actions_1.readContract)(client, { abi: proxyCreationCodeAbi, address: safeProxyFactoryAddress, functionName: "proxyCreationCode" }); const initializer = await getInitializerCode({ owners, threshold, safeModuleSetupAddress, safe4337ModuleAddress, multiSendAddress, setupTransactions, safeSingletonAddress, safeModules, erc7579LaunchpadAddress, validators, executors, fallbacks, hooks, attesters, attestersThreshold, paymentToken, payment, paymentReceiver }); const deploymentCode = (0, viem_1.encodePacked)(["bytes", "uint256"], [ proxyCreationCode, (0, viem_1.hexToBigInt)(erc7579LaunchpadAddress ?? safeSingletonAddress) ]); const salt = (0, viem_1.keccak256)((0, viem_1.encodePacked)(["bytes32", "uint256"], [(0, viem_1.keccak256)((0, viem_1.encodePacked)(["bytes"], [initializer])), saltNonce])); return (0, viem_1.getContractAddress)({ from: safeProxyFactoryAddress, salt, bytecode: deploymentCode, opcode: "CREATE2" }); }; async function toSafeSmartAccount(parameters) { const { client, owners: _owners, address, threshold = BigInt(_owners.length), version, safe4337ModuleAddress: _safe4337ModuleAddress, safeProxyFactoryAddress: _safeProxyFactoryAddress, safeSingletonAddress: _safeSingletonAddress, erc7579LaunchpadAddress, saltNonce = BigInt(0), validUntil = 0, validAfter = 0, nonceKey, paymentToken, payment, paymentReceiver, onchainIdentifier } = parameters; const owners = await Promise.all(_owners.map(async (owner) => { if ("account" in owner) { return owner.account; } if ("request" in owner) { return (0, toOwner_js_1.toOwner)({ owner: owner }); } return owner; })); const localOwners = await Promise.all(_owners .filter((owner) => { if ("type" in owner && owner.type === "local") { return true; } if ("request" in owner) { return true; } if ("account" in owner) { return true; } return false; }) .map((owner) => (0, toOwner_js_1.toOwner)({ owner: owner }))); const entryPoint = { address: parameters.entryPoint?.address ?? account_abstraction_1.entryPoint07Address, abi: (parameters.entryPoint?.version ?? "0.7") === "0.6" ? account_abstraction_1.entryPoint06Abi : account_abstraction_1.entryPoint07Abi, version: parameters.entryPoint?.version ?? "0.7" }; let _safeModuleSetupAddress = undefined; let _multiSendAddress = undefined; let _multiSendCallOnlyAddress = undefined; let safeModules = undefined; let setupTransactions = []; let validators = []; let executors = []; let fallbacks = []; let hooks = []; let attesters = []; let attestersThreshold = 0; if (!isErc7579Args(parameters)) { _safeModuleSetupAddress = parameters.safeModuleSetupAddress; _multiSendAddress = parameters.multiSendAddress; _multiSendCallOnlyAddress = parameters.multiSendCallOnlyAddress; safeModules = parameters.safeModules; setupTransactions = parameters.setupTransactions ?? []; } if (isErc7579Args(parameters)) { validators = parameters.validators ?? []; executors = parameters.executors ?? []; fallbacks = parameters.fallbacks ?? []; hooks = parameters.hooks ?? []; attesters = parameters.attesters ?? []; attestersThreshold = parameters.attestersThreshold ?? 0; } const { safeModuleSetupAddress, safe4337ModuleAddress, safeProxyFactoryAddress, safeSingletonAddress, multiSendAddress, multiSendCallOnlyAddress } = (0, exports.getDefaultAddresses)(version, entryPoint.version, { safeModuleSetupAddress: _safeModuleSetupAddress, safe4337ModuleAddress: _safe4337ModuleAddress, safeProxyFactoryAddress: _safeProxyFactoryAddress, safeSingletonAddress: _safeSingletonAddress, multiSendAddress: _multiSendAddress, multiSendCallOnlyAddress: _multiSendCallOnlyAddress }); let accountAddress = address; let chainId; const getMemoizedChainId = async () => { if (chainId) return chainId; chainId = client.chain ? client.chain.id : await (0, utils_1.getAction)(client, actions_1.getChainId, "getChainId")({}); return chainId; }; const getFactoryArgs = async () => { return { factory: safeProxyFactoryAddress, factoryData: await getAccountInitCode({ owners: owners.map((owner) => owner.address), threshold, safeModuleSetupAddress, safe4337ModuleAddress, safeSingletonAddress, multiSendAddress, erc7579LaunchpadAddress, saltNonce, setupTransactions, safeModules, validators, executors, fallbacks, hooks, attesters, attestersThreshold, paymentToken, payment, paymentReceiver }) }; }; return (0, account_abstraction_1.toSmartAccount)({ client, entryPoint, getFactoryArgs, async getAddress() { if (accountAddress) return accountAddress; accountAddress = await getAccountAddress({ client, owners: owners.map((owner) => owner.address), threshold, safeModuleSetupAddress, safe4337ModuleAddress, safeProxyFactoryAddress, safeSingletonAddress, multiSendAddress, erc7579LaunchpadAddress, saltNonce, setupTransactions, safeModules, validators, executors, fallbacks, hooks, attesters, attestersThreshold, paymentToken, payment, paymentReceiver }); return accountAddress; }, async encodeCalls(calls) { const hasMultipleCalls = calls.length > 1; if (erc7579LaunchpadAddress) { const safeDeployed = await (0, isSmartAccountDeployed_js_1.isSmartAccountDeployed)(client, await this.getAddress()); if (!safeDeployed) { const initData = get7579LaunchPadInitData({ safe4337ModuleAddress, safeSingletonAddress, erc7579LaunchpadAddress, owners: owners.map((owner) => owner.address), threshold, validators, executors, fallbacks, hooks, attesters, attestersThreshold }); return (0, viem_1.encodeFunctionData)({ abi: setupSafeAbi, functionName: "setupSafe", args: [ { ...initData, validators: initData.validators.map((validator) => ({ module: validator.address, initData: validator.context })), callData: (0, encode7579Calls_js_1.encode7579Calls)({ mode: { type: hasMultipleCalls ? "batchcall" : "call", revertOnError: false, selector: "0x", context: "0x" }, callData: calls }) } ] }); } return (0, encode7579Calls_js_1.encode7579Calls)({ mode: { type: hasMultipleCalls ? "batchcall" : "call", revertOnError: false, selector: "0x", context: "0x" }, callData: calls }); } let to; let value; let data; let operationType = 0; if (hasMultipleCalls) { to = multiSendCallOnlyAddress; value = BigInt(0); data = encodeMultiSend(calls.map((tx) => ({ to: tx.to, value: tx.value ?? 0n, data: tx.data ?? "0x", operation: 0 }))); operationType = 1; } else { const call = calls.length === 0 ? undefined : calls[0]; if (!call) { throw new Error("No calls to encode"); } to = call.to; data = call.data ?? "0x"; value = call.value ?? 0n; } const calldata = (0, viem_1.encodeFunctionData)({ abi: executeUserOpWithErrorStringAbi, functionName: "executeUserOpWithErrorString", args: [to, value, data, operationType] }); if (onchainIdentifier) { return (0, viem_1.concat)([calldata, onchainIdentifier]); } return calldata; }, async decodeCalls(callData) { try { const decoded = (0, viem_1.decodeFunctionData)({ abi: setupSafeAbi, data: callData }); return (0, decode7579Calls_js_1.decode7579Calls)(decoded.args[0].callData).callData; } catch (_) { } try { return (0, decode7579Calls_js_1.decode7579Calls)(callData).callData; } catch (_) { } const decoded = (0, viem_1.decodeFunctionData)({ abi: executeUserOpWithErrorStringAbi, data: callData }); const to = decoded.args[0]; const value = decoded.args[1]; const data = decoded.args[2]; if (to === multiSendCallOnlyAddress) { const decodedMultiSend = (0, viem_1.decodeFunctionData)({ abi: multiSendAbi, data: data }); const dataToDecode = decodedMultiSend.args[0]; const transactions = []; let position = 0; const dataLength = (0, viem_1.size)(dataToDecode); while (position < dataLength) { position += 1; const to = (0, viem_1.getAddress)((0, viem_1.slice)(dataToDecode, position, position + 20)); position += 20; const value = BigInt((0, viem_1.slice)(dataToDecode, position, position + 32)); position += 32; const dataLength = Number(BigInt((0, viem_1.slice)(dataToDecode, position, position + 32)) * BigInt(2)); position += 32; const data = (0, viem_1.slice)(dataToDecode, position, position + dataLength); position += dataLength; transactions.push({ to, value, data }); } return transactions; } return [{ to, value, data }]; }, async getNonce(args) { return (0, getAccountNonce_js_1.getAccountNonce)(client, { address: await this.getAddress(), entryPointAddress: entryPoint.address, key: nonceKey ?? args?.key }); }, async getStubSignature() { return (0, viem_1.encodePacked)(["uint48", "uint48", "bytes"], [ 0, 0, `0x${owners .map((_) => "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") .join("")}` ]); }, async sign({ hash }) { return this.signMessage({ message: hash }); }, async signMessage({ message }) { if (localOwners.length !== owners.length) { throw new Error("Owners length mismatch, currently not supported"); } const messageHash = (0, viem_1.hashTypedData)({ domain: { chainId: await getMemoizedChainId(), verifyingContract: await this.getAddress() }, types: { SafeMessage: [{ name: "message", type: "bytes" }] }, primaryType: "SafeMessage", message: { message: generateSafeMessageMessage(message) } }); const signatures = await Promise.all(localOwners.map(async (localOwner) => ({ signer: localOwner.address, data: adjustVInSignature("eth_sign", await localOwner.signMessage({ message: { raw: (0, viem_1.toBytes)(messageHash) } })) }))); signatures.sort((left, right) => left.signer .toLowerCase() .localeCompare(right.signer.toLowerCase())); const signatureBytes = (0, viem_1.concat)(signatures.map((sig) => sig.data)); return erc7579LaunchpadAddress ? (0, viem_1.concat)([viem_1.zeroAddress, signatureBytes]) : signatureBytes; }, async signTypedData(typedData) { if (localOwners.length !== owners.length) { throw new Error("Owners length mismatch, currently not supported"); } const signatures = await Promise.all(localOwners.map(async (localOwner) => ({ signer: localOwner.address, data: adjustVInSignature("eth_signTypedData", await localOwner.signTypedData({ domain: { chainId: await getMemoizedChainId(), verifyingContract: await this.getAddress() }, types: { SafeMessage: [ { name: "message", type: "bytes" } ] }, primaryType: "SafeMessage", message: { message: generateSafeMessageMessage(typedData) } })) }))); signatures.sort((left, right) => left.signer .toLowerCase() .localeCompare(right.signer.toLowerCase())); const signatureBytes = (0, viem_1.concat)(signatures.map((sig) => sig.data)); return erc7579LaunchpadAddress ? (0, viem_1.concat)([viem_1.zeroAddress, signatureBytes]) : signatureBytes; }, async signUserOperation(parameters) { const { chainId = await getMemoizedChainId(), ...userOperation } = parameters; if (localOwners.length !== owners.length) { throw new Error("Owners length mismatch use SafeSmartAccount.signUserOperation from `permissionless/accounts/safe`"); } let signatures = undefined; for (const owner of localOwners) { signatures = await (0, signUserOperation_js_1.signUserOperation)({ ...userOperation, version, entryPoint, owners: localOwners, account: owner, chainId: await getMemoizedChainId(), signatures, validAfter, validUntil, safe4337ModuleAddress }); } if (!signatures) { throw new Error("No signatures found"); } return signatures; } }); } //# sourceMappingURL=toSafeSmartAccount.js.map