UNPKG

@cometh/connect-core-sdk

Version:
2,217 lines (2,197 loc) 77.2 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/constants.ts var ENTRYPOINT_ADDRESS_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032"; var SAFE_7579_ADDRESS = "0x7579EE8307284F293B1927136486880611F20002"; var LAUNCHPAD_ADDRESS = "0x7579011aB74c46090561ea277Ba79D510c6C00ff"; var add7579FunctionSelector = "0xd78343d9"; var hardcodeVerificationGasLimit7579 = 1000000n; var defaultSafeContractConfig = { safeProxyFactoryAddress: "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", safeSingletonAddress: "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762", multisendAddress: "0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526", setUpContractAddress: "0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47", safe4337ModuleAddress: "0x75cf11467937ce3F2f357CE24ffc3DBF8fD5c226" }; var defaultClientConfig = { cacheTime: 6e4, batch: { multicall: { wait: 50 } } }; // src/core/accounts/safe/createSafeSmartAccount.ts import { getAccountNonce } from "permissionless/actions"; // src/errors.ts import { BaseError } from "viem"; var WalletNotConnectedError = class extends Error { constructor() { super("Account is not connected"); } }; var FallbackAlreadySetError = class extends Error { constructor() { super("Fallback already set"); } }; var SafeNotDeployedError = class extends Error { constructor() { super("Safe not deployed"); } }; var SmartAccountAddressNotFoundError = class extends Error { constructor() { super("No smart account address found"); } }; var OwnerToRemoveIsNotSafeOwnerError = class extends Error { constructor(ownerToRemove) { super(`${ownerToRemove} is not a safe owner`); } }; var RemoveOwnerOnUndeployedSafeError = class extends Error { constructor() { super("Can't remove owner on an undeployed safe"); } }; var MethodNotSupportedError = class extends BaseError { constructor() { super("Method not supported", { docsBaseUrl: "https://docs.cometh.io/connect-4337", docsPath: "/" }); } }; var BatchCallModeNotSupportedError = class extends Error { constructor(mode) { super( `Mode ${JSON.stringify( mode )} is not supported for batchcall calldata` ); } }; var NoCallsToEncodeError = class extends Error { constructor() { super("No calls to encode"); } }; var InvalidCallDataError = class extends Error { constructor() { super("Invalid callData for Safe Account"); } }; var InvalidAccountAddressError = class extends Error { constructor() { super("Invalid account address"); } }; var InvalidSmartAccountClientError = class extends Error { constructor() { super("Invalid Smart Account Client"); } }; var InvalidSignatureError = class extends Error { constructor() { super("Invalid signature"); } }; var CannotSignForAddressError = class extends Error { constructor() { super("Cannot sign for address that is not the current account"); } }; var MissingToAddressError = class extends BaseError { constructor() { super("Missing to address", { docsBaseUrl: "https://docs.cometh.io/connect-4337", docsPath: "/sdk-features/send-transactions" }); } }; var InvalidParamsError = class extends Error { constructor(message) { super(`Invalid params: ${message}`); } }; // src/core/accounts/safe/utils.ts import { parseAbi } from "abitype"; import { createNonceManager, serializeErc6492Signature } from "viem"; import { getCode, readContract } from "viem/actions"; import { getAction } from "viem/utils"; async function toSmartAccount(comethImplementation) { const { extend, nonceKeyManager = createNonceManager({ source: { get() { return Date.now(); }, set() { } } }), ...rest } = comethImplementation; let deployed = false; const address = await comethImplementation.getAddress(); const signerAddress = comethImplementation.signerAddress; const publicClient = comethImplementation.publicClient; return { ...extend, ...rest, address, signerAddress, publicClient, async getFactoryArgs() { if ("isDeployed" in this && await this.isDeployed()) return { factory: void 0, factoryData: void 0 }; return comethImplementation.getFactoryArgs(); }, async getNonce(parameters) { const key = parameters?.key ?? BigInt( await nonceKeyManager.consume({ address, chainId: comethImplementation.client.chain?.id, client: comethImplementation.client }) ); if (comethImplementation.getNonce) return await comethImplementation.getNonce({ ...parameters, key }); const nonce = await readContract(comethImplementation.client, { abi: parseAbi([ "function getNonce(address, uint192) pure returns (uint256)" ]), address: comethImplementation.entryPoint.address, functionName: "getNonce", args: [address, key] }); return nonce; }, async isDeployed() { if (deployed) return true; const code = await getAction( comethImplementation.client, getCode, "getCode" )({ address }); deployed = Boolean(code); return deployed; }, ...comethImplementation.sign ? { async sign(parameters) { const [{ factory, factoryData }, signature] = await Promise.all([ this.getFactoryArgs(), comethImplementation.sign ? comethImplementation.sign(parameters) : Promise.reject( new MethodNotSupportedError() ) ]); if (factory && factoryData) return serializeErc6492Signature({ address: factory, data: factoryData, signature }); return signature; } } : {}, async signMessage(parameters) { const [{ factory, factoryData }, signature] = await Promise.all([ this.getFactoryArgs(), comethImplementation.signMessage(parameters) ]); if (factory && factoryData) return serializeErc6492Signature({ address: factory, data: factoryData, signature }); return signature; }, async signTypedData(parameters) { const [{ factory, factoryData }, signature] = await Promise.all([ this.getFactoryArgs(), comethImplementation.signTypedData(parameters) ]); if (factory && factoryData) return serializeErc6492Signature({ address: factory, data: factoryData, signature }); return signature; }, type: "smart" }; } // src/core/accounts/safe/createSafeSmartAccount.ts import { http as http3, ChainNotFoundError, createPublicClient as createPublicClient2, encodeFunctionData as encodeFunctionData3, hexToBigInt as hexToBigInt2, zeroHash } from "viem"; // src/core/accounts/utils.ts import { http, createClient } from "viem"; var getViemClient = (chain, publicClient) => { return publicClient ?? createClient({ chain, transport: http(), cacheTime: 6e4, batch: { multicall: { wait: 50 } } }); }; // src/core/accounts/safe/abi/Multisend.ts var MultiSendContractABI = [ { inputs: [], stateMutability: "nonpayable", type: "constructor" }, { inputs: [ { internalType: "bytes", name: "transactions", type: "bytes" } ], name: "multiSend", outputs: [], stateMutability: "payable", type: "function" } ]; // src/core/accounts/safe/abi/safe4337ModuleAbi.ts var safe4337ModuleAbi = [ { inputs: [ { internalType: "address", name: "entryPoint", type: "address" } ], stateMutability: "nonpayable", type: "constructor" }, { inputs: [], name: "ExecutionFailed", type: "error" }, { inputs: [], name: "InvalidCaller", type: "error" }, { inputs: [], name: "InvalidEntryPoint", type: "error" }, { inputs: [], name: "UnsupportedEntryPoint", type: "error" }, { inputs: [{ internalType: "bytes4", name: "selector", type: "bytes4" }], name: "UnsupportedExecutionFunction", type: "error" }, { inputs: [], name: "SUPPORTED_ENTRYPOINT", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", type: "function" }, { inputs: [], name: "domainSeparator", outputs: [ { internalType: "bytes32", name: "domainSeparatorHash", type: "bytes32" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "contract Safe", name: "safe", type: "address" }, { internalType: "bytes", name: "message", type: "bytes" } ], name: "encodeMessageDataForSafe", outputs: [{ internalType: "bytes", name: "", type: "bytes" }], stateMutability: "view", type: "function" }, { 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: "executeUserOp", outputs: [], stateMutability: "nonpayable", type: "function" }, { 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" }, { inputs: [{ internalType: "bytes", name: "message", type: "bytes" }], name: "getMessageHash", outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "contract Safe", name: "safe", type: "address" }, { internalType: "bytes", name: "message", type: "bytes" } ], name: "getMessageHashForSafe", outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], stateMutability: "view", type: "function" }, { inputs: [], name: "getModules", outputs: [{ internalType: "address[]", name: "", type: "address[]" }], stateMutability: "view", type: "function" }, { inputs: [ { components: [ { internalType: "address", name: "sender", type: "address" }, { internalType: "uint256", name: "nonce", type: "uint256" }, { internalType: "bytes", name: "initCode", type: "bytes" }, { internalType: "bytes", name: "callData", type: "bytes" }, { internalType: "bytes32", name: "accountGasLimits", type: "bytes32" }, { internalType: "uint256", name: "preVerificationGas", type: "uint256" }, { internalType: "bytes32", name: "gasFees", type: "bytes32" }, { internalType: "bytes", name: "paymasterAndData", type: "bytes" }, { internalType: "bytes", name: "signature", type: "bytes" } ], internalType: "struct PackedUserOperation", name: "userOp", type: "tuple" } ], name: "getOperationHash", outputs: [ { internalType: "bytes32", name: "operationHash", type: "bytes32" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "bytes32", name: "_dataHash", type: "bytes32" }, { internalType: "bytes", name: "_signature", type: "bytes" } ], name: "isValidSignature", outputs: [{ internalType: "bytes4", name: "", type: "bytes4" }], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "bytes", name: "_data", type: "bytes" }, { internalType: "bytes", name: "_signature", type: "bytes" } ], name: "isValidSignature", outputs: [{ internalType: "bytes4", name: "", type: "bytes4" }], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "", type: "address" }, { internalType: "address", name: "", type: "address" }, { internalType: "uint256[]", name: "", type: "uint256[]" }, { internalType: "uint256[]", name: "", type: "uint256[]" }, { internalType: "bytes", name: "", type: "bytes" } ], name: "onERC1155BatchReceived", outputs: [{ internalType: "bytes4", name: "", type: "bytes4" }], stateMutability: "pure", type: "function" }, { inputs: [ { internalType: "address", name: "", type: "address" }, { internalType: "address", name: "", type: "address" }, { internalType: "uint256", name: "", type: "uint256" }, { internalType: "uint256", name: "", type: "uint256" }, { internalType: "bytes", name: "", type: "bytes" } ], name: "onERC1155Received", outputs: [{ internalType: "bytes4", name: "", type: "bytes4" }], stateMutability: "pure", type: "function" }, { inputs: [ { internalType: "address", name: "", type: "address" }, { internalType: "address", name: "", type: "address" }, { internalType: "uint256", name: "", type: "uint256" }, { internalType: "bytes", name: "", type: "bytes" } ], name: "onERC721Received", outputs: [{ internalType: "bytes4", name: "", type: "bytes4" }], stateMutability: "pure", type: "function" }, { inputs: [ { internalType: "address", name: "targetContract", type: "address" }, { internalType: "bytes", name: "calldataPayload", type: "bytes" } ], name: "simulate", outputs: [{ internalType: "bytes", name: "response", type: "bytes" }], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "bytes4", name: "interfaceId", type: "bytes4" } ], name: "supportsInterface", outputs: [{ internalType: "bool", name: "", type: "bool" }], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "", type: "address" }, { internalType: "address", name: "", type: "address" }, { internalType: "address", name: "", type: "address" }, { internalType: "uint256", name: "", type: "uint256" }, { internalType: "bytes", name: "", type: "bytes" }, { internalType: "bytes", name: "", type: "bytes" } ], name: "tokensReceived", outputs: [], stateMutability: "pure", type: "function" }, { inputs: [ { components: [ { internalType: "address", name: "sender", type: "address" }, { internalType: "uint256", name: "nonce", type: "uint256" }, { internalType: "bytes", name: "initCode", type: "bytes" }, { internalType: "bytes", name: "callData", type: "bytes" }, { internalType: "bytes32", name: "accountGasLimits", type: "bytes32" }, { internalType: "uint256", name: "preVerificationGas", type: "uint256" }, { internalType: "bytes32", name: "gasFees", type: "bytes32" }, { internalType: "bytes", name: "paymasterAndData", type: "bytes" }, { internalType: "bytes", name: "signature", type: "bytes" } ], internalType: "struct PackedUserOperation", name: "userOp", type: "tuple" }, { internalType: "bytes32", name: "", type: "bytes32" }, { internalType: "uint256", name: "missingAccountFunds", type: "uint256" } ], name: "validateUserOp", outputs: [ { internalType: "uint256", name: "validationData", type: "uint256" } ], stateMutability: "nonpayable", type: "function" } ]; // src/core/accounts/safe/abi/safeProxyFactory.ts var SafeProxyContractFactoryABI = [ { anonymous: false, inputs: [ { indexed: true, internalType: "contract SafeProxy", name: "proxy", type: "address" }, { indexed: false, internalType: "address", name: "singleton", type: "address" } ], name: "ProxyCreation", type: "event" }, { inputs: [ { internalType: "address", name: "_singleton", type: "address" }, { internalType: "bytes", name: "initializer", type: "bytes" }, { internalType: "uint256", name: "saltNonce", type: "uint256" } ], name: "createChainSpecificProxyWithNonce", outputs: [ { internalType: "contract SafeProxy", name: "proxy", type: "address" } ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "_singleton", type: "address" }, { internalType: "bytes", name: "initializer", type: "bytes" }, { internalType: "uint256", name: "saltNonce", type: "uint256" }, { internalType: "contract IProxyCreationCallback", name: "callback", type: "address" } ], name: "createProxyWithCallback", outputs: [ { internalType: "contract SafeProxy", name: "proxy", type: "address" } ], stateMutability: "nonpayable", type: "function" }, { 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" }, { inputs: [], name: "getChainId", outputs: [ { internalType: "uint256", name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [], name: "proxyCreationCode", outputs: [ { internalType: "bytes", name: "", type: "bytes" } ], stateMutability: "pure", type: "function" } ]; // src/core/accounts/safe/safeSigner/ecdsa/ecdsa.ts import { encodePacked as encodePacked2 } from "viem"; import { toAccount } from "viem/accounts"; import { signTypedData } from "viem/actions"; // src/core/accounts/safe/services/utils.ts import { concat, encodePacked, toBytes, toHex } from "viem"; var ECDSA_DUMMY_SIGNATURE = "0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; var DUMMY_AUTHENTICATOR_DATA = new Uint8Array(37); DUMMY_AUTHENTICATOR_DATA.fill(254); DUMMY_AUTHENTICATOR_DATA[32] = 4; var buildSignatureBytes = (signatures) => { const SIGNATURE_LENGTH_BYTES = 65; signatures.sort( (left, right) => left.signer.toLowerCase().localeCompare(right.signer.toLowerCase()) ); let signatureBytes = "0x"; let dynamicBytes = ""; for (const sig of signatures) { if (sig.dynamic) { const dynamicPartPosition = (signatures.length * SIGNATURE_LENGTH_BYTES + dynamicBytes.length / 2).toString(16).padStart(64, "0"); const dynamicPartLength = (sig.data.slice(2).length / 2).toString(16).padStart(64, "0"); const staticSignature = `${sig.signer.slice(2).padStart(64, "0")}${dynamicPartPosition}00`; const dynamicPartWithLength = `${dynamicPartLength}${sig.data.slice( 2 )}`; signatureBytes += staticSignature; dynamicBytes += dynamicPartWithLength; } else { signatureBytes += sig.data.slice(2); } } return signatureBytes + dynamicBytes; }; function packPaymasterData({ paymaster, paymasterVerificationGasLimit, paymasterPostOpGasLimit, paymasterData }) { if (!paymasterData) return "0x"; return encodePacked( ["address", "uint128", "uint128", "bytes"], [ paymaster, paymasterVerificationGasLimit, paymasterPostOpGasLimit, paymasterData ] ); } var packInitCode = ({ factory, factoryData }) => { if (!(factoryData && factory)) return "0x"; const factoryBytes = toBytes(factory); const factoryDataBytes = toBytes(factoryData); return toHex(concat([factoryBytes, factoryDataBytes])); }; // src/core/accounts/safe/types.ts var EIP712_SAFE_OPERATION_TYPE = { 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 EIP712_SAFE_MESSAGE_TYPE = { // "SafeMessage(bytes message)" SafeMessage: [{ type: "bytes", name: "message" }] }; var SAFE_SENTINEL_OWNERS = "0x1"; // src/core/accounts/safe/safeSigner/utils.ts import { hashMessage, hashTypedData } from "viem"; var 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 InvalidSignatureError(); } 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); }; var generateSafeMessageMessage = (message) => { const signableMessage = message; if (typeof signableMessage === "string" || signableMessage.raw) { return hashMessage(signableMessage); } return hashTypedData( message ); }; // src/core/accounts/safe/safeSigner/ecdsa/ecdsa.ts async function safeECDSASigner(client, { signer, userOpVerifyingContract, smartAccountAddress }) { const viemSigner = { ...signer, signTransaction: (_, __) => { throw new MethodNotSupportedError(); } }; const account = toAccount({ address: smartAccountAddress, async signMessage({ message }) { return adjustVInSignature( "eth_signTypedData", await viemSigner.signTypedData({ domain: { chainId: client.chain?.id, verifyingContract: smartAccountAddress }, types: EIP712_SAFE_MESSAGE_TYPE, primaryType: "SafeMessage", message: { message: generateSafeMessageMessage(message) } }) ); }, async signTransaction(_, __) { throw new MethodNotSupportedError(); }, async signTypedData(typedData) { return adjustVInSignature( "eth_signTypedData", await signTypedData(client, { account: viemSigner, ...typedData }) ); } }); return { ...account, address: smartAccountAddress, source: "safeECDSASigner", // Sign a user operation async signUserOperation(parameters) { const { ...userOperation } = parameters; const payload = { domain: { chainId: client.chain?.id, verifyingContract: userOpVerifyingContract }, types: EIP712_SAFE_OPERATION_TYPE, primaryType: "SafeOp", message: { callData: userOperation.callData, nonce: userOperation.nonce, initCode: packInitCode({ factory: userOperation.factory, factoryData: userOperation.factoryData }), paymasterAndData: packPaymasterData({ paymaster: userOperation.paymaster, paymasterVerificationGasLimit: userOperation.paymasterVerificationGasLimit, paymasterPostOpGasLimit: userOperation.paymasterPostOpGasLimit, paymasterData: userOperation.paymasterData }), preVerificationGas: userOperation.preVerificationGas, entryPoint: ENTRYPOINT_ADDRESS_V07, validAfter: 0, validUntil: 0, safe: userOperation.sender, verificationGasLimit: userOperation.verificationGasLimit, callGasLimit: userOperation.callGasLimit, maxPriorityFeePerGas: userOperation.maxPriorityFeePerGas, maxFeePerGas: userOperation.maxFeePerGas } }; return encodePacked2( ["uint48", "uint48", "bytes"], [ 0, 0, buildSignatureBytes([ { signer: signer.address, data: await signer.signTypedData(payload) } ]) ] ); }, /** * Get a dummy signature for this smart account */ async getStubSignature() { return ECDSA_DUMMY_SIGNATURE; } }; } // src/core/accounts/safe/services/safe.ts import { isSmartAccountDeployed } from "permissionless"; import { http as http2, concat as concat2, createPublicClient, encodeFunctionData, encodePacked as encodePacked3, getContract, getContractAddress, hexToBigInt, keccak256, size, zeroAddress } from "viem"; // src/core/accounts/safe/abi/enableModule.ts var EnableModuleAbi = [ { inputs: [ { internalType: "address[]", name: "modules", type: "address[]" } ], name: "enableModules", outputs: [], stateMutability: "nonpayable", type: "function" } ]; // src/core/accounts/safe/abi/safe.ts var SafeAbi = [ { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "owner", type: "address" } ], name: "AddedOwner", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "bytes32", name: "approvedHash", type: "bytes32" }, { indexed: true, internalType: "address", name: "owner", type: "address" } ], name: "ApproveHash", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "handler", type: "address" } ], name: "ChangedFallbackHandler", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "guard", type: "address" } ], name: "ChangedGuard", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "uint256", name: "threshold", type: "uint256" } ], name: "ChangedThreshold", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "module", type: "address" } ], name: "DisabledModule", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "module", type: "address" } ], name: "EnabledModule", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "bytes32", name: "txHash", type: "bytes32" }, { indexed: false, internalType: "uint256", name: "payment", type: "uint256" } ], name: "ExecutionFailure", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "module", type: "address" } ], name: "ExecutionFromModuleFailure", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "module", type: "address" } ], name: "ExecutionFromModuleSuccess", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "bytes32", name: "txHash", type: "bytes32" }, { indexed: false, internalType: "uint256", name: "payment", type: "uint256" } ], name: "ExecutionSuccess", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "owner", type: "address" } ], name: "RemovedOwner", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "module", type: "address" }, { indexed: false, internalType: "address", name: "to", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" }, { indexed: false, internalType: "bytes", name: "data", type: "bytes" }, { indexed: false, internalType: "enum Enum.Operation", name: "operation", type: "uint8" } ], name: "SafeModuleTransaction", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "to", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" }, { indexed: false, internalType: "bytes", name: "data", type: "bytes" }, { indexed: false, internalType: "enum Enum.Operation", name: "operation", type: "uint8" }, { indexed: false, internalType: "uint256", name: "safeTxGas", type: "uint256" }, { indexed: false, internalType: "uint256", name: "baseGas", type: "uint256" }, { indexed: false, internalType: "uint256", name: "gasPrice", type: "uint256" }, { indexed: false, internalType: "address", name: "gasToken", type: "address" }, { indexed: false, internalType: "address payable", name: "refundReceiver", type: "address" }, { indexed: false, internalType: "bytes", name: "signatures", type: "bytes" }, { indexed: false, internalType: "bytes", name: "additionalInfo", type: "bytes" } ], name: "SafeMultiSigTransaction", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "sender", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "SafeReceived", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "initiator", type: "address" }, { indexed: false, internalType: "address[]", name: "owners", type: "address[]" }, { indexed: false, internalType: "uint256", name: "threshold", type: "uint256" }, { indexed: false, internalType: "address", name: "initializer", type: "address" }, { indexed: false, internalType: "address", name: "fallbackHandler", type: "address" } ], name: "SafeSetup", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "bytes32", name: "msgHash", type: "bytes32" } ], name: "SignMsg", type: "event" }, { stateMutability: "nonpayable", type: "fallback" }, { inputs: [], name: "VERSION", outputs: [ { internalType: "string", name: "", type: "string" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "owner", type: "address" }, { internalType: "uint256", name: "_threshold", type: "uint256" } ], name: "addOwnerWithThreshold", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "bytes32", name: "hashToApprove", type: "bytes32" } ], name: "approveHash", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "", type: "address" }, { internalType: "bytes32", name: "", type: "bytes32" } ], name: "approvedHashes", outputs: [ { internalType: "uint256", name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "_threshold", type: "uint256" } ], name: "changeThreshold", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "bytes32", name: "dataHash", type: "bytes32" }, { internalType: "bytes", name: "data", type: "bytes" }, { internalType: "bytes", name: "signatures", type: "bytes" }, { internalType: "uint256", name: "requiredSignatures", type: "uint256" } ], name: "checkNSignatures", outputs: [], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "bytes32", name: "dataHash", type: "bytes32" }, { internalType: "bytes", name: "data", type: "bytes" }, { internalType: "bytes", name: "signatures", type: "bytes" } ], name: "checkSignatures", outputs: [], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "prevModule", type: "address" }, { internalType: "address", name: "module", type: "address" } ], name: "disableModule", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "domainSeparator", outputs: [ { internalType: "bytes32", name: "", type: "bytes32" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "module", type: "address" } ], name: "enableModule", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }, { internalType: "bytes", name: "data", type: "bytes" }, { internalType: "enum Enum.Operation", name: "operation", type: "uint8" }, { internalType: "uint256", name: "safeTxGas", type: "uint256" }, { internalType: "uint256", name: "baseGas", type: "uint256" }, { internalType: "uint256", name: "gasPrice", type: "uint256" }, { internalType: "address", name: "gasToken", type: "address" }, { internalType: "address", name: "refundReceiver", type: "address" }, { internalType: "uint256", name: "_nonce", type: "uint256" } ], name: "encodeTransactionData", outputs: [ { internalType: "bytes", name: "", type: "bytes" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }, { internalType: "bytes", name: "data", type: "bytes" }, { internalType: "enum Enum.Operation", name: "operation", type: "uint8" }, { internalType: "uint256", name: "safeTxGas", type: "uint256" }, { internalType: "uint256", name: "baseGas", type: "uint256" }, { internalType: "uint256", name: "gasPrice", type: "uint256" }, { internalType: "address", name: "gasToken", type: "address" }, { internalType: "address payable", name: "refundReceiver", type: "address" }, { internalType: "bytes", name: "signatures", type: "bytes" } ], name: "execTransaction", outputs: [ { internalType: "bool", name: "", type: "bool" } ], stateMutability: "payable", type: "function" }, { inputs: [ { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }, { internalType: "bytes", name: "data", type: "bytes" }, { internalType: "enum Enum.Operation", name: "operation", type: "uint8" } ], name: "execTransactionFromModule", outputs: [ { internalType: "bool", name: "success", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }, { internalType: "bytes", name: "data", type: "bytes" }, { internalType: "enum Enum.Operation", name: "operation", type: "uint8" } ], name: "execTransactionFromModuleReturnData", outputs: [ { internalType: "bool", name: "success", type: "bool" }, { internalType: "bytes", name: "returnData", type: "bytes" } ], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "getChainId", outputs: [ { internalType: "uint256", name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "start", type: "address" }, { internalType: "uint256", name: "pageSize", type: "uint256" } ], name: "getModulesPaginated", outputs: [ { internalType: "address[]", name: "array", type: "address[]" }, { internalType: "address", name: "next", type: "address" } ], stateMutability: "view", type: "function" }, { inputs: [], name: "getOwners", outputs: [ { internalType: "address[]", name: "", type: "address[]" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "offset", type: "uint256" }, { internalType: "uint256", name: "length", type: "uint256" } ], name: "getStorageAt", outputs: [ { internalType: "bytes", name: "", type: "bytes" } ], stateMutability: "view", type: "function" }, { inputs: [], name: "getThreshold", outputs: [ { internalType: "uint256", name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }, { internalType: "bytes", name: "data", type: "bytes" }, { internalType: "enum Enum.Operation", name: "operation", type: "uint8" }, { internalType: "uint256", name: "safeTxGas", type: "uint256" }, { internalType: "uint256", name: "baseGas", type: "uint256" }, { internalType: "uint256", name: "gasPrice", type: "uint256" }, { internalType: "address", name: "gasToken", type: "address" }, { internalType: "address", name: "refundReceiver", type: "address" }, { internalType: "uint256", name: "_nonce", type: "uint256" } ], name: "getTransactionHash", outputs: [ { internalType: "bytes32", name: "", type: "bytes32" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "module", type: "address" } ], name: "isModuleEnabled", outputs: [ { internalType: "bool", name: "", type: "bool" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "owner", type: "address" } ], name: "isOwner", outputs: [ { internalType: "bool", name: "", type: "bool" } ], stateMutability: "view", type: "function" }, { inputs: [], name: "nonce", outputs: [ { internalType: "uint256", name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "prevOwner", type: "address" }, { internalType: "address", name: "owner", type: "address" }, { internalType: "uint256", name: "_threshold", type: "uint256" } ], name: "removeOwner", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "handler", type: "address" } ], name: "setFallbackHandler", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "guard", type: "address" } ], name: "setGuard", outputs: [], stateMutability: "nonpayable", type: "function" }, { 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" }, { inputs: [ { internalType: "bytes32", name: "", type: "bytes32" } ], name: "signedMessages", outputs: [ { internalType: "uint256", name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "targetContract", type: "address" }, { internalType: "bytes", name: "calldataPayload", type: "bytes" } ], name: "simulateAndRevert", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "prevOwner", type: "address" }, { internalType: "address", name: "oldOwner", type: "address" }, { internalType: "address", name: "newOwner", type: "address" } ], name: "swapOwner", outputs: [], stateMutability: "nonpayable", type: "function" }, { stateMutability: "payable", type: "receive" } ]; // src/core/accounts/safe/services/safe.ts var encodeMultiSendTransactions = (transactions) => { return concat2( transactions.map( ({ op, to, value, data }) => encodePacked3( ["uint8", "address", "uint256", "uint256", "bytes"], [op, to, value ?? 0n, BigInt(size(data)), data] ) ) ); }; var getSetUpCallData = ({ modules }) => { const enableModuleCallData = encodeFunctionData({ abi: EnableModuleAbi, functionName: "enableModules", args: [modules] }); return enableModuleCallData; }; var getSafeInitializer = ({ accountSigner, threshold, fallbackHandler, modules, setUpContractAddress }) => { const setUpCallData = getSetUpCallData({ modules }); return getSafeSetUpData({ owner: accountSigner.address, threshold, setUpContractAddress, setUpData: setUpCallData, fallbackHandler }); }; var getSafeAddressFromInitializer = async ({ chain, publicClient, safeProxyFactoryAddress, safeSingletonAddress, initializer, saltNonce }) => { const publicClient_ = publicClient ?? createPublicClient({ chain, transport: http2() }); const proxyCreationCode = await publicClient_.readContract({ address: safeProxyFactoryAddress, abi: SafeProxyContractFactoryABI, functionName: "proxyCreationCode" }); const deploymentCode = encodePacked3( ["bytes", "uint256"], [proxyCreationCode, hexToBigInt(safeSingletonAddress)] ); const salt = keccak256( encodePacked3( ["bytes32", "uint256"], [keccak256(encodePacked3(["bytes"], [initializer])), saltNonce] ) ); return getContractAddress({ bytecode: deploymentCode, from: safeProxyFactoryAddress, opcode: "CREATE2", salt }); }; var getSafeSetUpData = ({ owner, threshold, setUpContractAddress, setUpData, fallbackHandler }) => { return encodeFunctionData({ abi: SafeAbi, functionName: "setup", args: [ [owner], threshold, setUpContractAddress, setUpData, fallbackHandler, zeroAddress, 0, zeroAddress ] }); }; // src/core/accounts/safe/createSafeSmartAccount.ts import { isSmartAccountDeployed as isSmartAccountDeployed2 } from "permissionless"; import { entryPoint07Abi, entryPoint07Address } from "viem/account-abstraction"; // src/core/accounts/safe/services/7579.ts import { concatHex, encodeAbiParameters, encodeFunctionData as encodeFunctionData2, encodePacked as encodePacked4, toBytes as toBytes2, toHex as toHex2 } from "viem"; function parseCallType(callType) { switch (callType) { case "call": return "0x00"; case "batchcall": return "0x01"; case "delegatecall": return "0xff"; } } function encode7579Calls({ mode, callData }) { if (callData.length > 1 && mode?.type !== "batchcall") { throw new BatchCallModeNotSupportedError(mode); } const executeAbi = [ { type: "function", name: "execute", inputs: [ { name: "e