UNPKG

permissionless

Version:

A utility library for working with ERC-4337

410 lines • 14.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.toSimpleSmartAccount = toSimpleSmartAccount; 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 getSenderAddress_js_1 = require("../../actions/public/getSenderAddress.js"); const toOwner_js_1 = require("../../utils/toOwner.js"); const getAccountInitCode = async (owner, index = BigInt(0)) => { if (!owner) throw new Error("Owner account not found"); return (0, viem_1.encodeFunctionData)({ abi: [ { inputs: [ { internalType: "address", name: "owner", type: "address" }, { internalType: "uint256", name: "salt", type: "uint256" } ], name: "createAccount", outputs: [ { internalType: "contract SimpleAccount", name: "ret", type: "address" } ], stateMutability: "nonpayable", type: "function" } ], functionName: "createAccount", args: [owner, index] }); }; const getFactoryAddress = (entryPointVersion, factoryAddress) => { if (factoryAddress) return factoryAddress; switch (entryPointVersion) { case "0.8": return "0x13E9ed32155810FDbd067D4522C492D6f68E5944"; case "0.7": return "0x91E60e0613810449d098b0b5Ec8b51A0FE8c8985"; default: return "0x9406Cc6185a346906296840746125a0E44976454"; } }; const getEntryPointAbi = (entryPointVersion) => { switch (entryPointVersion) { case "0.8": return account_abstraction_1.entryPoint08Abi; case "0.7": return account_abstraction_1.entryPoint07Abi; default: return account_abstraction_1.entryPoint06Abi; } }; async function toSimpleSmartAccount(parameters) { const { client, owner, factoryAddress: _factoryAddress, index = BigInt(0), address, nonceKey, eip7702 = false, accountLogicAddress = "0xe6Cae83BdE06E4c305530e199D7217f42808555B" } = parameters; const localOwner = await (0, toOwner_js_1.toOwner)({ owner }); const entryPoint = parameters.entryPoint ? { address: parameters.entryPoint.address, abi: getEntryPointAbi(parameters.entryPoint.version), version: parameters.entryPoint.version } : eip7702 ? { address: account_abstraction_1.entryPoint08Address, abi: getEntryPointAbi("0.8"), version: "0.8" } : { address: account_abstraction_1.entryPoint07Address, abi: getEntryPointAbi("0.7"), version: "0.7" }; const factoryAddress = getFactoryAddress(entryPoint.version, _factoryAddress); 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 getFactoryArgsFunc = () => async () => { return { factory: factoryAddress, factoryData: await getAccountInitCode(localOwner.address, index) }; }; const { accountAddress, getFactoryArgs } = await (async () => { if (eip7702) { return { accountAddress: localOwner.address, getFactoryArgs: async () => { return { factory: undefined, factoryData: undefined }; } }; } const getFactoryArgs = getFactoryArgsFunc(); if (address) { return { accountAddress: address, getFactoryArgs }; } const { factory, factoryData } = await getFactoryArgs(); const accountAddress = await (0, getSenderAddress_js_1.getSenderAddress)(client, { factory, factoryData, entryPointAddress: entryPoint.address }); return { accountAddress, getFactoryArgs }; })(); return (0, account_abstraction_1.toSmartAccount)({ client, entryPoint, getFactoryArgs, extend: eip7702 ? { implementation: accountLogicAddress } : undefined, authorization: eip7702 ? { address: accountLogicAddress, account: localOwner } : undefined, async getAddress() { return accountAddress; }, async encodeCalls(calls) { if (calls.length > 1) { if (entryPoint.version === "0.8") { return (0, viem_1.encodeFunctionData)({ abi: executeBatch08Abi, functionName: "executeBatch", args: [ calls.map((a) => ({ target: a.to, value: a.value ?? 0n, data: a.data ?? "0x" })) ] }); } if (entryPoint.version === "0.7") { return (0, viem_1.encodeFunctionData)({ abi: executeBatch07Abi, functionName: "executeBatch", args: [ calls.map((a) => a.to), calls.map((a) => a.value ?? 0n), calls.map((a) => a.data ?? "0x") ] }); } return (0, viem_1.encodeFunctionData)({ abi: executeBatch06Abi, functionName: "executeBatch", args: [ calls.map((a) => a.to), calls.map((a) => a.data ?? "0x") ] }); } const call = calls.length === 0 ? undefined : calls[0]; if (!call) { throw new Error("No calls to encode"); } return (0, viem_1.encodeFunctionData)({ abi: executeSingleAbi, functionName: "execute", args: [call.to, call.value ?? 0n, call.data ?? "0x"] }); }, decodeCalls: async (callData) => { try { const calls = []; if (entryPoint.version === "0.8") { const decodedV8 = (0, viem_1.decodeFunctionData)({ abi: executeBatch08Abi, data: callData }); for (const call of decodedV8.args[0]) { calls.push({ to: call.target, data: call.data, value: call.value }); } return calls; } if (entryPoint.version === "0.7") { const decodedV7 = (0, viem_1.decodeFunctionData)({ abi: executeBatch07Abi, data: callData }); const destinations = decodedV7.args[0]; const values = decodedV7.args[1]; const datas = decodedV7.args[2]; for (let i = 0; i < destinations.length; i++) { calls.push({ to: destinations[i], data: datas[i], value: values[i] }); } return calls; } if (entryPoint.version === "0.6") { const decodedV6 = (0, viem_1.decodeFunctionData)({ abi: executeBatch06Abi, data: callData }); const destinations = decodedV6.args[0]; const datas = decodedV6.args[1]; for (let i = 0; i < destinations.length; i++) { calls.push({ to: destinations[i], data: datas[i], value: 0n }); } return calls; } return calls; } catch (_) { const decodedSingle = (0, viem_1.decodeFunctionData)({ abi: executeSingleAbi, data: callData }); return [ { to: decodedSingle.args[0], value: decodedSingle.args[1], data: decodedSingle.args[2] } ]; } }, async getNonce(args) { return (0, getAccountNonce_js_1.getAccountNonce)(client, { address: await this.getAddress(), entryPointAddress: entryPoint.address, key: nonceKey ?? args?.key }); }, async getStubSignature() { return "0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"; }, async sign({ hash }) { return this.signMessage({ message: hash }); }, signMessage: async (_) => { throw new Error("Simple account isn't 1271 compliant"); }, signTypedData: async (_) => { throw new Error("Simple account isn't 1271 compliant"); }, async signUserOperation(parameters) { const { chainId = await getMemoizedChainId(), ...userOperation } = parameters; if (entryPoint.version === "0.8") { const typedData = (0, account_abstraction_1.getUserOperationTypedData)({ chainId, entryPointAddress: entryPoint.address, userOperation: { ...userOperation, sender: await this.getAddress(), signature: "0x" } }); return localOwner.signTypedData(typedData); } return (0, actions_1.signMessage)(client, { account: localOwner, message: { raw: (0, account_abstraction_1.getUserOperationHash)({ userOperation: { ...userOperation, sender: userOperation.sender ?? (await this.getAddress()), signature: "0x" }, entryPointAddress: entryPoint.address, entryPointVersion: entryPoint.version, chainId: chainId }) } }); } }); } const executeSingleAbi = [ { inputs: [ { internalType: "address", name: "dest", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }, { internalType: "bytes", name: "func", type: "bytes" } ], name: "execute", outputs: [], stateMutability: "nonpayable", type: "function" } ]; const executeBatch06Abi = [ { inputs: [ { internalType: "address[]", name: "dest", type: "address[]" }, { internalType: "bytes[]", name: "func", type: "bytes[]" } ], name: "executeBatch", outputs: [], stateMutability: "nonpayable", type: "function" } ]; const executeBatch07Abi = [ { inputs: [ { internalType: "address[]", name: "dest", type: "address[]" }, { internalType: "uint256[]", name: "value", type: "uint256[]" }, { internalType: "bytes[]", name: "func", type: "bytes[]" } ], name: "executeBatch", outputs: [], stateMutability: "nonpayable", type: "function" } ]; const executeBatch08Abi = [ { type: "function", name: "executeBatch", inputs: [ { name: "calls", type: "tuple[]", internalType: "struct BaseAccount.Call[]", components: [ { name: "target", type: "address", internalType: "address" }, { name: "value", type: "uint256", internalType: "uint256" }, { name: "data", type: "bytes", internalType: "bytes" } ] } ], outputs: [], stateMutability: "nonpayable" } ]; //# sourceMappingURL=toSimpleSmartAccount.js.map