Safe Account V2 uses the original Safe Singleton and adds ERC-4337 functionality using a module/fallback handler.
The V2 contracts, known as the SafeAccountV0_2_0 class in AbstractionKit, support EntryPoint v0.6.
Import
import { SafeAccountV0_2_0 as SafeAccount } from "abstractionkit";
How to Use
Initialize a new Safe Account and calculate its address:
const ownerPublicAddress = "0xBdbc5FBC9cA8C3F514D073eC3de840Ac84FC6D31";
const smartAccount = SafeAccount.initializeNewAccount([ownerPublicAddress]);
const accountAddress = smartAccount.accountAddress;
Constructor
Creates a SafeAccountV0_2_0 instance for an existing deployed Safe account. For new (undeployed) accounts, use the static initializeNewAccount method instead.
Usage
import { SafeAccountV0_2_0 as SafeAccount } from "abstractionkit";
const accountAddress = "0x1a02592A3484c2077d2E5D24482497F85e1980C6";
const smartAccount = new SafeAccount(accountAddress);
| key | type | description |
|---|
accountAddress | string | The on-chain address of the deployed Safe account. |
overrides? | object | Optional overrides for module and EntryPoint addresses. |
overrides?.safe4337ModuleAddress? | string | Override the default Safe 4337 module address. |
overrides?.entrypointAddress? | string | Override the default EntryPoint address. |
overrides?.onChainIdentifierParams? | OnChainIdentifierParamsType | Parameters for on-chain identifier tracking. |
overrides?.onChainIdentifier? | string | Pre-computed on-chain identifier string. |
| key | type | description |
|---|
SafeAccountV0_2_0 | SafeAccountV0_2_0 | An instance of the SafeAccountV0_2_0 class connected to the existing account. |
Source code
constructor
Methods
The Essentials methods provide all necessary functionalities with support for overrides, offering a streamlined approach.
initializeNewAccount
Initializes a new SafeAccount class given a list of owners' public addresses. Only needs to be called on the first transaction when the account has not been deployed yet.
Usage
In this example, we initiate a single owner account.
- example.ts
- Param Types
- Return Type
example.ts
import { SafeAccountV0_2_0 as SafeAccount } from "abstractionkit";
const ownerPublicAddress = "0xBdbc5FBC9cA8C3F514D073eC3de840Ac84FC6D31";
const smartAccount = SafeAccount.initializeNewAccount([ownerPublicAddress]);
console.log("Account address (sender): " + smartAccount.accountAddress);
| key | type | description |
|---|
owners[] | object | Pass the owner(s) address(es) of the account. It can be a single owner account, a multi-sig, or a WebAuthn |
owners[].Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key |
initCodeOverrides? | object | Override values to change the initialization default values |
initCodeOverrides?.threshold? | number | Signature threshold, defines how many signatures are required. Default is 1. |
initCodeOverrides?.c2Nonce? | bigint | Create2 nonce used to generate different sender addresses from the same owners. Default is 0. |
initCodeOverrides?.entrypointAddress? | string | Address of the entry point for transactions or contracts. |
initCodeOverrides?.safe4337ModuleAddress? | string | Address of the Safe 4337 module. |
initCodeOverrides?.safeModuleSetupAddress? | string | Address used for setting up the Safe module. |
initCodeOverrides?.safeAccountSingleton? | SafeAccountSingleton | Safe contract singleton address. Default is "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762". |
initCodeOverrides?.safeAccountFactoryAddress? | string | Address of the Safe Factory. Default is "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67". |
initCodeOverrides?.multisendContractAddress? | string | Address of the Safe 4337 multisend contract. Default is "0xa581c4A4DB7175302464fF3C06380BC3270b4037". |
initCodeOverrides?.webAuthnSharedSigner? | string | Shared signer used for WebAuthn-based authentication. |
initCodeOverrides?.eip7212WebAuthnPrecompileVerifierForSharedSigner? | string | Verifier contract for WebAuthn precompile, related to the shared signer. |
initCodeOverrides?.eip7212WebAuthnContractVerifierForSharedSigner? | string | Contract verifier for WebAuthn-based shared signer, compliant with EIP-7212. |
initCodeOverrides?.onChainIdentifierParams? | OnChainIdentifierParamsType | Parameters for on-chain identifier tracking. |
initCodeOverrides?.onChainIdentifier? | string | Pre-computed on-chain identifier string. |
| key | type | description |
|---|
ECDSASignature | string | ECDSA signature represented as a string |
WebauthnPublicKey
| key | type | description |
|---|
authenticatorData | ArrayBuffer | Binary data returned by the authenticator during the Webauthn process |
clientDataFields | string | Fields associated with the client's Webauthn request data |
rs | [bigint, bigint] | Array of two bigints representing the 'r' and 's' values of the signature |
| key | type | description |
|---|
SafeAccount class | SafeAccountV0_2_0 | An instance of the Safe V2 Account and the initialization parameters |
Example Response
Account address(sender) : 0x1a02592A3484c2077d2E5D24482497F85e1980C6
Source code
initializeNewAccount
isDeployed
Static method that checks whether a Safe account is already deployed on-chain. Use it to decide between connecting to an existing account (new SafeAccountV0_2_0(address)) and initializing a counterfactual one (SafeAccountV0_2_0.initializeNewAccount(owners)). Once an account is deployed, the factory data carried by initializeNewAccount is no longer needed and including it would waste gas.
This only checks for non-empty bytecode at accountAddress. It does not verify that the deployed code is a Safe or that its on-chain configuration matches a given owner set.
Usage
- example.ts
- Param Types
- Return Type
example.ts
import { SafeAccountV0_2_0 as SafeAccount } from "abstractionkit";
const accountAddress = "0x1a02592A3484c2077d2E5D24482497F85e1980C6";
const nodeRpcUrl = "https://rpc2.sepolia.org";
const account = (await SafeAccount.isDeployed(accountAddress, nodeRpcUrl))
? new SafeAccount(accountAddress)
: SafeAccount.initializeNewAccount([ownerPublicAddress]);
| key | type | description |
|---|
accountAddress | string | The Safe account address to check. |
nodeRpcUrl | string | The JSON-RPC API URL for the target chain. |
| key | type | description |
|---|
isDeployed | Promise<boolean> | Resolves to true if non-empty bytecode is deployed at accountAddress, false otherwise. |
Source code
isDeployed
createUserOperation
This method determines the nonce, fetches the gas prices, estimates gas limits, and returns a UserOperation to be signed. You can override any of these values using the overrides parameter.
Usage
This example mints the same NFT twice in a single UserOperation.
- example.ts
- Param Types
- Return Type
example.ts
import { MetaTransaction } from "abstractionkit";
const jsonRpcNodeProvider = "https://rpc2.sepolia.org";
const bundlerUrl = "https://api.candide.dev/public/v3/11155111";
const transaction: MetaTransaction = {
to: "0xD9de104e3386d9A45a61BcE269c43E48B534e4E7",
value: 0n,
data: "0x1249c58b",
}
let userOperation = await smartAccount.createUserOperation(
[transaction, transaction],
jsonRpcNodeProvider,
bundlerUrl,
)
console.log(userOperation);
| Param Name | Param Type | Description |
|---|
| Transactions | MetaTransaction[] | key | type | description |
|---|
MetaTransaction | object | MetaTransaction is the type of transaction to construct a Safe operation. | MetaTransaction.to | string | To address, or the the target contract address for the transaction | MetaTransaction.value | BigNumberish | Value transfered if making a native token transfer. (usually 0n for contract interaction with non-native tokens like erc-20 tokens) | MetaTransaction.data | BytesLike | The call data for the transaction | MetaTransaction.operation | Operation: enum | Default to 0 for a Call. 1 for a Delegate Call. (Optional) |
| MetaTransaction is the type of a transaction to construct a Safe operation |
| Provider RPC | string | The node URL. It is used to fetch the current nonce and fetch gas prices |
| Bundler URL | string | The Bundler URL. It is used to fetch the gas limits |
| Overrides | CreateUserOperationOverrides, optional object | key | type | description |
|---|
nonce | string | Anti-replay parameter (see “Semi-abstracted Nonce Support” ) | callData | string | The data to pass to the sender during the main execution call | callGasLimit | bigint | The amount of gas to allocate the main execution call | verificationGasLimit | bigint | The amount of gas to allocate for the verification step | preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata | maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) | maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) | callGasLimitPercentageMultiplier | number | Set the callGasLimitPercentageMultiplier instead of estimating gas using the bundler | verificationGasLimitPercentageMultiplier | number | Set the verificationGasLimitPercentageMultiplier instead of estimating gas using the bundler | preVerificationGasPercentageMultiplier | number | Set the preVerificationGasPercentageMultiplier instead of estimating gas using the bundler | maxFeePerGasPercentageMultiplier | number | Set the maxFeePerGasPercentageMultiplier instead of querying the current gas price from the RPC node | maxPriorityFeePerGasPercentageMultiplier | number | Set the maxPriorityFeePerGasPercentageMultiplier instead of querying the current gas price from the RPC node | state_override_set? | object | Pass state overrides for gas estimation | state_override_set?.[address: string] | object | Overrides for a specific address | state_override_set?.[address: string].balance | bigint | Override the balance of the address | state_override_set?.[address: string].nonce | bigint | Override the nonce of the address | state_override_set?.[address: string].code | string | Override the code of the address | state_override_set?.[address: string].state | Dictionary<string> | Override the storage slots of the address | state_override_set?.[address: string].stateDiff | Dictionary<string> | Apply state differences to the storage slots of the address | dummySignerSignaturePairs[] | object | Provide dummy signatures for the operation | dummySignerSignaturePairs[].SignerSignaturePair[] | object | Signature Pair | dummySignerSignaturePairs[].SignerSignaturePair[].Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key | dummySignerSignaturePairs[].SignerSignaturePair[].signature | string | signature | dummySignerSignaturePairs[].SignerSignaturePair[].isContractSignature | boolean | isContractSignature | expectedSigners[] | object | A array of expected signers that will sign over the transaction. This improves the gas estimates. | expectedSigners[].Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key | webAuthnSharedSigner | string | Specify the WebAuthn shared signer | webAuthnSignerFactory | string | Specify the WebAuthn signer factory | webAuthnSignerSingleton | string | Specify the WebAuthn signer singleton | eip7212WebAuthnPrecompileVerifier | string | Specify the EIP-7212 WebAuthn precompile verifier | eip7212WebAuthnContractVerifier | string | Specify the EIP-7212 WebAuthn contract verifier | safeModuleExecutorFunctionSelector | SafeModuleExecutorFunctionSelector | Specify the function selector for the safe module executor | multisendContractAddress | string | Specify the multisend contract address | gasLevel | object | Multiplier to determine the gas price for the user operation | gasLevel.Slow | 1 | Default Slow Gas | gasLevel.Medium | 1.2 | Medium Gas with a 20% increase | gasLevel.Fast | 1.5 | Medium Gas with a 50% increase | polygonGasStation | object | To specify the polygon network | polygonGasStation.Mainnet | v2 | Polygon PoS Mainnet | polygonGasStation.ZkMainnet | zkevm | Polygon zkEVM Mainnet | polygonGasStation.Amoy | amoy | Polygon Amoy PoS Testnet | polygonGasStation.Cardona | cardona | Polygon Cardona zkEVM Testnet | isMultiChainSignature? | boolean | Whether this is a multi-chain signature using Merkle proofs | parallelPaymasterInitValues? | ParallelPaymasterInitValues | Paymaster fields for parallel signing (EntryPoint v0.9) | skipGasEstimation? | boolean | When true, skip the bundler's eth_estimateUserOperationGas call. Gas limits fall back to any overrides or 0n. The returned UserOperation is always populated with a dummy signature so it stays valid for downstream paymaster sponsorship calls that require a placeholder signature. | initCode | string | The initCode of the account, only needed if the account is not yet on-chain and needs to be created |
| CreateUserOperationOverrides allows you to override any of the default parameters for the user operation |
| Param Name | Param Type | Description |
|---|
| UserOperation | Promise<UserOperation | JsonRpcError | BundlerJsonRpcError> UserOperation object | key | type | description |
|---|
sender | string | The account making the operation | nonce | string | Anti-replay parameter (see “Semi-abstracted Nonce Support” ) | initCode | string | The initCode of the account (needed if and only if the account is not yet on-chain and needs to be created) | callData | string | The data to pass to the sender during the main execution call | callGasLimit | bigint | The amount of gas to allocate the main execution call | verificationGasLimit | bigint | The amount of gas to allocate for the verification step | preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata | maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) | maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) | paymasterAndData | string | Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster (empty for self-sponsored transaction). Revolves to '0x' if not using a paymaster, and a paymasterDummyData when estimating gas | signature | string | The signature for the userOperation. It is the data passed into the account along with the nonce during the verification step. Resolves to '0x' when the user did not provide their signature yet |
JsonRpcError object | key | type | description |
|---|
code | number | JSON RPC error code | message | string | JSON RPC error message description |
BundlerJsonRpcError object | key | type | description |
|---|
code | number | Bundler RPC error code | message | string | Bundler RPC error message description |
| Returns a UserOperation on success, or the RPC/bundler error on failure. |
Example Response
{
sender: '0x44e3cb9acd92ab055d3251994352bb8fe0e20879',
nonce: 1n,
initCode: '0x',
callData: '0x541d63c800000000000000000000000038869bf66a61cf6bdb996a6ae40d5853fd43b52600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001048d80ff0a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000b200d9de104e3386d9a45a61bce269c43e48b534e4e7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041249c58b00d9de104e3386d9a45a61bce269c43e48b534e4e7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041249c58b000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
callGasLimit: 95085n,
verificationGasLimit: 62187n,
preVerificationGas: 46156n,
maxFeePerGas: 1625933544n,
maxPriorityFeePerGas: 1200000000n,
paymasterAndData: '0x',
signature: '0x00000000000000000000000041c6297bd9573e8d979a272db4f6576a98f639a7e6874055a627769401dc46d01143551ccaa473364ace4340ec395c546dccb725e1eac2639ecef443d229f0071b'
}
Source code
createUserOperation
signUserOperation
This method takes a userOperation, the private keys of the owner of the account, and the chainId and returns the signature field.
- example.ts
- Param Types
- Return Type
example.ts
const chainId = BigInt("11155111");
const privateKey = "0x4cad764980d84fc6684ca839cae2c78be5432e292fa98416e11687ceb9096a03";
const userOperation = {..}
const signature = smartAccount.signUserOperation(
userOperation,
[privateKey],
chainId,
);
console.log(signature);
| key | type | description |
|---|
userOperation | UserOperationV6 | userOperation to sign |
privateKeys | string[] | private keys of owners/signers |
chainId | bigint | target chain id |
overrides? | object | overrides for the default values |
overrides?.validAfter? | bigint | Timestamp the signature will be valid after |
overrides?.validUntil? | bigint | Timestamp the signature will be valid until |
UserOperationV6
| key | type | description |
|---|
sender | string | The account making the operation |
nonce | string | Anti-replay parameter (see “Semi-abstracted Nonce Support” ) |
initCode | string | The initCode of the account (needed if and only if the account is not yet on-chain and needs to be created) |
callData | string | The data to pass to the sender during the main execution call |
callGasLimit | bigint | The amount of gas to allocate the main execution call |
verificationGasLimit | bigint | The amount of gas to allocate for the verification step |
preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata |
maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) |
maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) |
paymasterAndData | string | Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster (empty for self-sponsored transaction). Revolves to '0x' if not using a paymaster, and a paymasterDummyData when estimating gas |
signature | string | The signature for the userOperation. It is the data passed into the account along with the nonce during the verification step. Resolves to '0x' when the user did not provide their signature yet |
| key | type | description |
|---|
Signature field | string | UserOperation Signature with the data passed into the account along with the nonce during the verification step |
Example Response
0x00000000000000000000000041c6297bd9573e8d979a272db4f6576a98f639a7e6874055a627769401dc46d01143551ccaa473364ace4340ec395c546dccb725e1eac2639ecef443d229f0071b
Source code
signUserOperation
signUserOperationWithSigners
Signs a UserOperation using one or more ExternalSigners instead of raw private keys. Integrates viem, ethers, hardware wallets, HSMs, MPC services, and WebAuthn through the same API.
example.ts
import { fromEthersWallet } from "abstractionkit";
import { Wallet } from "ethers";
const wallet = new Wallet("0x...");
userOperation.signature = await smartAccount.signUserOperationWithSigners(
userOperation,
[fromEthersWallet(wallet)],
chainId,
);
See External Signers for the full list of adapters and custom-signer integrations.
Source code
signUserOperationWithSigners
sendUserOperation
This method sends the UserOperation to the bundler to be executed on-chain. It returns a promise SendUseroperationResponse object to confirm the on-chain inclusion of the UserOperation.
- example.ts
- Param Types
- Return Type
example.ts
const sendUserOperationResponse = await smartAccount.sendUserOperation(userOperation, bundlerUrl)
console.log("sendUserOperationResponse: ", sendUserOperationResponse);
console.log("UserOperation sent. Waiting to be included...");
const receipt = await sendUserOperationResponse.included()
console.log("receipt: ", receipt);
| key | type | description |
|---|
userOperation | UserOperationV6 | userOperation to send |
bundlerRpc | string | bundler rpc to send userOperation |
UserOperationV6
| key | type | description |
|---|
sender | string | The account making the operation |
nonce | string | Anti-replay parameter (see “Semi-abstracted Nonce Support” ) |
initCode | string | The initCode of the account (needed if and only if the account is not yet on-chain and needs to be created) |
callData | string | The data to pass to the sender during the main execution call |
callGasLimit | bigint | The amount of gas to allocate the main execution call |
verificationGasLimit | bigint | The amount of gas to allocate for the verification step |
preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata |
maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) |
maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) |
paymasterAndData | string | Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster (empty for self-sponsored transaction). Revolves to '0x' if not using a paymaster, and a paymasterDummyData when estimating gas |
signature | string | The signature for the userOperation. It is the data passed into the account along with the nonce during the verification step. Resolves to '0x' when the user did not provide their signature yet |
| key | type | description |
|---|
userOperationHash | string | The hash over the userOp (except signature), entryPoint and chainId |
bundler | Bundler | The Bundler class |
entrypointAddress | string | The entrypoint address where the useroperation got executed |
included() | Promise<UserOperationReceiptResult | BundlerJsonRpcError> | Waits for the user operation to be included onchain and returns the user operation receipt on success, or the bundler error on failture |
BundlerJsonRpcError
| key | type | description |
|---|
code | number | Bundler RPC error code |
message | string | Bundler RPC error message description |
UserOperationReceiptResult
| key | type | description |
|---|
userOpHash | string | The hash of the user operation. |
entryPoint | string | The address of the entry point contract that processed the operation. |
sender | string | The address of the sender of the user operation. |
nonce | bigint | The nonce of the user operation. |
paymaster | string | The address of the paymaster that paid for the gas of the user operation. |
actualGasCost | bigint | The actual gas cost incurred for executing the user operation. |
actualGasUsed | bigint | The actual amount of gas used for the user operation. |
success | boolean | Indicates whether the user operation was successful. |
logs | string | The logs produced during the execution of the user operation. |
receipt | object | The detailed receipt of the user operation. |
receipt.blockHash | string | The hash of the block in which the transaction was included. |
receipt.blockNumber | bigint | The number of the block in which the transaction was included. |
receipt.from | string | The address that initiated the transaction. |
receipt.cumulativeGasUsed | bigint | The total amount of gas used in the block up to and including this transaction. |
receipt.gasUsed | bigint | The amount of gas used by this transaction. |
receipt.logs | string | Logs generated by the transaction. |
receipt.logsBloom | string | The bloom filter for the logs generated by the transaction. |
receipt.transactionHash | string | The unique hash of the transaction. |
receipt.transactionIndex | bigint | The index of the transaction within the block. |
receipt.effectiveGasPrice | bigint | The effective gas price for the transaction. This field is optional and may not be present in all receipts. |
Example Response
sendUserOperationResponse: {
userOperationHash: '0x61b3e2c57ad7ad1ae788f0ac84c79b28aab8aeaf872be173cadc72ab8b3d4418',
bundler: { rpcUrl: 'https://api.candide.dev/public/v3/11155111' },
entrypointAddress: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789'
}
UserOperation sent. Waiting to be included...
receipt: {
userOpHash: '0x61b3e2c57ad7ad1ae788f0ac84c79b28aab8aeaf872be173cadc72ab8b3d4418',
entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
sender: '0x44e3cb9acd92ab055d3251994352bb8fe0e20879',
nonce: '0x2',
paymaster: '0x0000000000000000000000000000000000000000',
actualGasCost: 261844423573004,
actualGasUsed: 185893,
success: true,
logs: '[{"address":"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789","blockHash":"0xba4e1221571d457b4a01db81be6c3ca8e1dcf0117c2c383425e8379853345a69","blockNumber":"0x4e4d65","data":"0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000ee2567da7e0c000000000000000000000000000000000000000000000000000000000002d625","logIndex":"0x140","removed":false,"topics":["0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f","0x61b3e2c57ad7ad1ae788f0ac84c79b28aab8aeaf872be173cadc72ab8b3d4418","0x00000000000000000000000044e3cb9acd92ab055d3251994352bb8fe0e20879","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":"0x00289aec83e4f8a109e2026e9e7f9a122bcf66116b1fc9c48099d668eec49f25","transactionIndex":"0xc5"}]',
receipt: {
blockHash: '0xba4e1221571d457b4a01db81be6c3ca8e1dcf0117c2c383425e8379853345a69',
blockNumber: '0x4e4d65',
from: '0x3cfdc212769c890907bce93d3d8c2c53de6a7a89',
cumulativeGasUsed: '0x1c3ffde',
gasUsed: '0x2dbfd',
logs: '[{"address":"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789","blockHash":"0xba4e1221571d457b4a01db81be6c3ca8e1dcf0117c2c383425e8379853345a69","blockNumber":"0x4e4d65","data":"0x00000000000000000000000000000000000000000000000000013cd7ed43f8b8","logIndex":"0x13a","removed":false,"topics":["0x2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4","0x00000000000000000000000044e3cb9acd92ab055d3251994352bb8fe0e20879"],"transactionHash":"0x00289aec83e4f8a109e2026e9e7f9a122bcf66116b1fc9c48099d668eec49f25","transactionIndex":"0xc5"},{"address":"0x44e3cb9acd92ab055d3251994352bb8fe0e20879","blockHash":"0xba4e1221571d457b4a01db81be6c3ca8e1dcf0117c2c383425e8379853345a69","blockNumber":"0x4e4d65","data":"0x","logIndex":"0x13b","removed":false,"topics":["0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8","0x000000000000000000000000d556564bacf6feac2e26ff70695f8250cea8c29e"],"transactionHash":"0x00289aec83e4f8a109e2026e9e7f9a122bcf66116b1fc9c48099d668eec49f25","transactionIndex":"0xc5"},{"address":"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789","blockHash":"0xba4e1221571d457b4a01db81be6c3ca8e1dcf0117c2c383425e8379853345a69","blockNumber":"0x4e4d65","data":"0x","logIndex":"0x13c","removed":false,"topics":["0xbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972"],"transactionHash":"0x00289aec83e4f8a109e2026e9e7f9a122bcf66116b1fc9c48099d668eec49f25","transactionIndex":"0xc5"},{"address":"0xd9de104e3386d9a45a61bce269c43e48b534e4e7","blockHash":"0xba4e1221571d457b4a01db81be6c3ca8e1dcf0117c2c383425e8379853345a69","blockNumber":"0x4e4d65","data":"0x","logIndex":"0x13d","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x00000000000000000000000044e3cb9acd92ab055d3251994352bb8fe0e20879","0x0000000000000000000000000000000000000000000000000000000000000023"],"transactionHash":"0x00289aec83e4f8a109e2026e9e7f9a122bcf66116b1fc9c48099d668eec49f25","transactionIndex":"0xc5"},{"address":"0xd9de104e3386d9a45a61bce269c43e48b534e4e7","blockHash":"0xba4e1221571d457b4a01db81be6c3ca8e1dcf0117c2c383425e8379853345a69","blockNumber":"0x4e4d65","data":"0x","logIndex":"0x13e","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x00000000000000000000000044e3cb9acd92ab055d3251994352bb8fe0e20879","0x0000000000000000000000000000000000000000000000000000000000000024"],"transactionHash":"0x00289aec83e4f8a109e2026e9e7f9a122bcf66116b1fc9c48099d668eec49f25","transactionIndex":"0xc5"},{"address":"0x44e3cb9acd92ab055d3251994352bb8fe0e20879","blockHash":"0xba4e1221571d457b4a01db81be6c3ca8e1dcf0117c2c383425e8379853345a69","blockNumber":"0x4e4d65","data":"0x","logIndex":"0x13f","removed":false,"topics":["0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8","0x000000000000000000000000d556564bacf6feac2e26ff70695f8250cea8c29e"],"transactionHash":"0x00289aec83e4f8a109e2026e9e7f9a122bcf66116b1fc9c48099d668eec49f25","transactionIndex":"0xc5"},{"address":"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789","blockHash":"0xba4e1221571d457b4a01db81be6c3ca8e1dcf0117c2c383425e8379853345a69","blockNumber":"0x4e4d65","data":"0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000ee2567da7e0c000000000000000000000000000000000000000000000000000000000002d625","logIndex":"0x140","removed":false,"topics":["0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f","0x61b3e2c57ad7ad1ae788f0ac84c79b28aab8aeaf872be173cadc72ab8b3d4418","0x00000000000000000000000044e3cb9acd92ab055d3251994352bb8fe0e20879","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":"0x00289aec83e4f8a109e2026e9e7f9a122bcf66116b1fc9c48099d668eec49f25","transactionIndex":"0xc5"}]',
logsBloom: '0x000000000000100000000000000000000000000000000000000000000000000000080000000000000022080100000000001000000000008000000200000020000000000000020000000000080000000008100000000000000000000000002000020000000a0800000000000000000800000000000000000000000014000200000000000000000000000000000008000040000000000200000000000000000000000000000002000000400000400000000200000000000000000002200008000000000002000000000001000008000000000000000000080800000000000020000040000000000000000000000000000200000000000000000100000000000000',
transactionHash: '0x00289aec83e4f8a109e2026e9e7f9a122bcf66116b1fc9c48099d668eec49f25',
transactionIndex: '0xc5',
effectiveGasPrice: '0xc6e9e20'
}
}
Source code
sendUserOperation
Advanced Methods
The Advanced methods offer fine control and customization, catering to developers who require detailed configurations for their specific requirements.
createAccountAddress
Calculates the Account address from the initial owners
Usage
In this example, we initiate a single owner account.
- example.ts
- Param Types
- Return Type
example.ts
import { SafeAccount } from "abstractionkit";
const ownerPublicAddress = "0xBdbc5FBC9cA8C3F514D073eC3de840Ac84FC6D31";
const safeAddress = SafeAccount.createAccountAddress(
[ownerPublicAddress],
);
console.log("Account address (sender): " + safeAddress);
| key | type | description |
|---|
owners[] | object | Pass the owner(s) address(es) of the account. It can be a single owner account, a multi-sig, or a WebAuthn |
owners[].Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key |
initCodeOverrides | object | Override values to change the initialization default values |
initCodeOverrides.threshold? | number | Signature threshold, defines how many signatures are required. Default is 1. |
initCodeOverrides.c2Nonce? | bigint | Create2 nonce used to generate different sender addresses from the same owners. Default is 0. |
initCodeOverrides.entrypointAddress? | string | Address of the entry point for transactions or contracts. |
initCodeOverrides.safe4337ModuleAddress? | string | Address of the Safe 4337 module. |
initCodeOverrides.safeModuleSetupAddress? | string | Address used for setting up the Safe module. |
initCodeOverrides.safeAccountSingleton? | SafeAccountSingleton | Safe contract singleton address. Default is "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762". |
initCodeOverrides.safeAccountFactoryAddress? | string | Address of the Safe Factory. Default is "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67". |
initCodeOverrides.multisendContractAddress? | string | Address of the Safe 4337 multisend contract. Default is "0xa581c4A4DB7175302464fF3C06380BC3270b4037". |
initCodeOverrides.webAuthnSharedSigner? | string | Shared signer used for WebAuthn-based authentication. |
initCodeOverrides.eip7212WebAuthnPrecompileVerifierForSharedSigner? | string | Verifier contract for WebAuthn precompile, related to the shared signer. |
initCodeOverrides.eip7212WebAuthnContractVerifierForSharedSigner? | string | Contract verifier for WebAuthn-based shared signer, compliant with EIP-7212. |
initCodeOverrides.onChainIdentifierParams? | OnChainIdentifierParamsType | Parameters for on-chain identifier tracking. |
initCodeOverrides.onChainIdentifier? | string | Pre-computed on-chain identifier string. |
| key | type | description |
|---|
ECDSASignature | string | ECDSA signature represented as a string |
WebauthnPublicKey
| key | type | description |
|---|
authenticatorData | ArrayBuffer | Binary data returned by the authenticator during the Webauthn process |
clientDataFields | string | Fields associated with the client's Webauthn request data |
rs | [bigint, bigint] | Array of two bigints representing the 'r' and 's' values of the signature |
| key | type | description |
|---|
Smart Account Address | string | Smart Account Address |
Example Response
Account address(sender) : 0x1a02592A3484c2077d2E5D24482497F85e1980C6
Source code
createAccountAddress
createInitCode
Calculates the initCode needed to deploy the account on-chain.
Usage
In this example, we initiate a single owner account.
- example.ts
- Param Types
- Return Type
example.ts
import { SafeAccount } from "abstractionkit";
const owner1PublicAddress = "0xBdbc5FBC9cA8C3F514D073eC3de840Ac84FC6D31";
const owner2PublicAddress = "0x4991A5360e5da9BAF62fF644d89F46268e5159eA";
const initCode = SafeAccount.createInitCode([ownerPublicAddress, owner2PublicAddress], 2);
console.log("initCode: ", initCode);
| key | type | description |
|---|
owners[] | object | Pass the owner(s) address(es) of the account. It can be a single owner account, a multi-sig, or a WebAuthn |
owners[].Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key |
initCodeOverrides? | object | Override values to change the initialization default values |
initCodeOverrides?.threshold? | number | Signature threshold, defines how many signatures are required. Default is 1. |
initCodeOverrides?.c2Nonce? | bigint | Create2 nonce used to generate different sender addresses from the same owners. Default is 0. |
initCodeOverrides?.entrypointAddress? | string | Address of the entry point for transactions or contracts. |
initCodeOverrides?.safe4337ModuleAddress? | string | Address of the Safe 4337 module. |
initCodeOverrides?.safeModuleSetupAddress? | string | Address used for setting up the Safe module. |
initCodeOverrides?.safeAccountSingleton? | SafeAccountSingleton | Safe contract singleton address. Default is "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762". |
initCodeOverrides?.safeAccountFactoryAddress? | string | Address of the Safe Factory. Default is "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67". |
initCodeOverrides?.multisendContractAddress? | string | Address of the Safe 4337 multisend contract. Default is "0xa581c4A4DB7175302464fF3C06380BC3270b4037". |
initCodeOverrides?.webAuthnSharedSigner? | string | Shared signer used for WebAuthn-based authentication. |
initCodeOverrides?.eip7212WebAuthnPrecompileVerifierForSharedSigner? | string | Verifier contract for WebAuthn precompile, related to the shared signer. |
initCodeOverrides?.eip7212WebAuthnContractVerifierForSharedSigner? | string | Contract verifier for WebAuthn-based shared signer, compliant with EIP-7212. |
initCodeOverrides?.onChainIdentifierParams? | OnChainIdentifierParamsType | Parameters for on-chain identifier tracking. |
initCodeOverrides?.onChainIdentifier? | string | Pre-computed on-chain identifier string. |
| key | type | description |
|---|
ECDSASignature | string | ECDSA signature represented as a string |
WebauthnPublicKey
| key | type | description |
|---|
authenticatorData | ArrayBuffer | Binary data returned by the authenticator during the Webauthn process |
clientDataFields | string | Fields associated with the client's Webauthn request data |
rs | [bigint, bigint] | Array of two bigints representing the 'r' and 's' values of the signature |
| key | type | description |
|---|
initCode | string | The initCode of the account, only needed if the account is not yet on-chain and needs to be created |
Example Response
Source code
createInitCode
createAccountAddressAndInitCode
Calculates the Safe address and the initCode needed to deploy the account on-chain.
Usage
In this example, we initiate a single owner account.
- example.ts
- Param Types
- Return Type
example.ts
import { SafeAccountV0_2_0 as SafeAccount } from "abstractionkit";
const ownerPublicAddress = "0xBdbc5FBC9cA8C3F514D073eC3de840Ac84FC6D31";
let [accountAddress, initCode] = SafeAccount.createAccountAddressAndInitCode(
[ownerPublicAddress],
);
console.log("Account address (sender): " + accountAddress);
console.log("initCode: ", initCode);
| key | type | description |
|---|
owners[] | object | Pass the owner(s) address(es) of the account. It can be a single owner account, a multi-sig, or a WebAuthn |
owners[].Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key |
initCodeOverrides? | object | Override values to change the initialization default values |
initCodeOverrides?.threshold? | number | Signature threshold, defines how many signatures are required. Default is 1. |
initCodeOverrides?.c2Nonce? | bigint | Create2 nonce used to generate different sender addresses from the same owners. Default is 0. |
initCodeOverrides?.entrypointAddress? | string | Address of the entry point for transactions or contracts. |
initCodeOverrides?.safe4337ModuleAddress? | string | Address of the Safe 4337 module. |
initCodeOverrides?.safeModuleSetupAddress? | string | Address used for setting up the Safe module. |
initCodeOverrides?.safeAccountSingleton? | SafeAccountSingleton | Safe contract singleton address. Default is "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762". |
initCodeOverrides?.safeAccountFactoryAddress? | string | Address of the Safe Factory. Default is "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67". |
initCodeOverrides?.multisendContractAddress? | string | Address of the Safe 4337 multisend contract. Default is "0xa581c4A4DB7175302464fF3C06380BC3270b4037". |
initCodeOverrides?.webAuthnSharedSigner? | string | Shared signer used for WebAuthn-based authentication. |
initCodeOverrides?.eip7212WebAuthnPrecompileVerifierForSharedSigner? | string | Verifier contract for WebAuthn precompile, related to the shared signer. |
initCodeOverrides?.eip7212WebAuthnContractVerifierForSharedSigner? | string | Contract verifier for WebAuthn-based shared signer, compliant with EIP-7212. |
initCodeOverrides?.onChainIdentifierParams? | OnChainIdentifierParamsType | Parameters for on-chain identifier tracking. |
initCodeOverrides?.onChainIdentifier? | string | Pre-computed on-chain identifier string. |
| key | type | description |
|---|
ECDSASignature | string | ECDSA signature represented as a string |
WebauthnPublicKey
| key | type | description |
|---|
authenticatorData | ArrayBuffer | Binary data returned by the authenticator during the Webauthn process |
clientDataFields | string | Fields associated with the client's Webauthn request data |
rs | [bigint, bigint] | Array of two bigints representing the 'r' and 's' values of the signature |
| key | type | description |
|---|
account address | string | The Safe Account Address |
initcode | string | The initCode field in the userOperation |
Example Response
Account address(sender) : 0x1a02592A3484c2077d2E5D24482497F85e1980C6
initCode: 0x...
Source code
createAccountAddressAndInitCode
createInitializerCallData
Creates the initializer calldata
Usage
- Example
- Param Types
- Return Types
import { SafeAccountV0_3_0 as SafeAccount } from "abstractionkit";
const initializeCallData = SafeAccount.createInitializerCallData(
[ownerPublicAddress],
1,
);
console.log("initializeCallData: " + initializeCallData);
| key | type | description |
|---|
owners[] | object | Pass the owner(s) address(es) of the account. It can be a single owner account, a multi-sig, or a WebAuthn |
owners[].Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key |
threshold | number | Pass the owner(s) address(es) of the account. It can be a single owner account, a multi-sig, or a WebAuthn |
overrides? | object | Override values to change the initialization default values |
overrides?.safe4337ModuleAddress? | string | Address of the Safe 4337 module. |
overrides?.safeModuleSetupAddress? | string | Address used for setting up the Safe module. |
overrides?.multisendContractAddress? | string | Address of the Safe 4337 multisend contract. Default is "0xa581c4A4DB7175302464fF3C06380BC3270b4037". |
overrides?.webAuthnSharedSigner? | string | Shared signer used for WebAuthn-based authentication. |
overrides?.eip7212WebAuthnPrecompileVerifierForSharedSigner? | string | Verifier contract for WebAuthn precompile, related to the shared signer. |
overrides?.eip7212WebAuthnContractVerifierForSharedSigner? | string | Contract verifier for WebAuthn-based shared signer, compliant with EIP-7212. |
| key | type | description |
|---|
ECDSASignature | string | ECDSA signature represented as a string |
WebauthnPublicKey
| key | type | description |
|---|
authenticatorData | ArrayBuffer | Binary data returned by the authenticator during the Webauthn process |
clientDataFields | string | Fields associated with the client's Webauthn request data |
rs | [bigint, bigint] | Array of two bigints representing the 'r' and 's' values of the signature |
| key | type | description |
|---|
calldata | string | The initializer calldata |
Example Response
initializeCallData: 0xb63e800d000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000002dd68b007b46fbe91b9a7c3eda5a7a1063cb5b47000000000000000000000000000000000000000000000000000000000000014000000000000000000000000075cf11467937ce3f2f357ce24ffc3dbf8fd5c2260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000bdbc5fbc9ca8c3f514d073ec3de840ac84fc6d3100000000000000000000000000000000000000000000000000000000000000648d0dc49f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000075cf11467937ce3f2f357ce24ffc3dbf8fd5c22600000000000000000000000000000000000000000000000000000000
Source code
createInitializerCallData
createAccountCallDataSingleTransaction
Encodes calldata for a single MetaTransaction to be executed by a Safe account.
Usage
In this example, we make a transfer of 1 wei to a random address.
- example.ts
- Param Types
- Return Type
example.ts
import { SafeAccountV0_2_0 as SafeAccount } from "abstractionkit";
const ownerPublicAddress = "0xBdbc5FBC9cA8C3F514D073eC3de840Ac84FC6D31";
const smartAccount = SafeAccount.initializeNewAccount([ownerPublicAddress]);
const callData = smartAccount.createAccountCallDataSingleTransaction({
to: "0x1a02592A3484c2077d2E5D24482497F85e1980C6",
value: 1,
data: "0x",
});
console.log("callData: " + callData);
| key | type | description |
|---|
metaTransaction | object | The MetaTransaction to create calldata for |
metaTransaction.MetaTransaction | object | MetaTransaction is the type of transaction to construct a Safe operation. |
metaTransaction.MetaTransaction.to | string | To address, or the the target contract address for the transaction |
metaTransaction.MetaTransaction.value | BigNumberish | Value transfered if making a native token transfer. (usually 0n for contract interaction with non-native tokens like erc-20 tokens) |
metaTransaction.MetaTransaction.data | BytesLike | The call data for the transaction |
metaTransaction.MetaTransaction.operation | Operation: enum | Default to 0 for a Call. 1 for a Delegate Call. (Optional) |
safeModuleExecutorFunctionSelector | object | Safe has two executor functions executeUserOpWithErrorString and executeUserOp |
safeModuleExecutorFunctionSelector.executeUserOpWithErrorString | 0x541d63c8 | The MetaTransaction to create calldata for |
safeModuleExecutorFunctionSelector.executeUserOp | 0x7bb37428 | The MetaTransaction to create calldata for |
| key | type | description |
|---|
callData | string | CallData to be includes in the user operation to send a single transaction |
Example Response
callData : 0xf34308ef000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d6000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Source code
createAccountCallDataSingleTransaction
createAccountCallDataBatchTransactions
Encodes calldata for a list of MetaTransactions to be executed by a Safe account.
Usage
In this example, we make a transfer to 2 different random addresses, 1 wei each.
- example.ts
- Param Types
- Return Type
example.ts
import {
SafeAccountV0_2_0 as SafeAccount,
MetaTransaction,
} from "abstractionkit";
const ownerPublicAddress = "0xBdbc5FBC9cA8C3F514D073eC3de840Ac84FC6D31";
const smartAccount = SafeAccount.initializeNewAccount([ownerPublicAddress]);
const tx1: MetaTransaction = {
to: "0x1a02592A3484c2077d2E5D24482497F85e1980C6",
value: 1,
data: "0x",
};
const tx2: MetaTransaction = {
to: "0x3fe285dcd76bcce4ac92d38a6f2f8e964041e020",
value: 1,
data: "0x",
};
const callData = SafeAccount.createAccountCallDataBatchTransactions([tx1, tx2]);
console.log("callData: " + callData);
| key | type | description |
|---|
metaTransaction[] | object | The MetaTransaction to create calldata for |
metaTransaction[].MetaTransaction | object | MetaTransaction is the type of transaction to construct a Safe operation. |
metaTransaction[].MetaTransaction.to | string | To address, or the the target contract address for the transaction |
metaTransaction[].MetaTransaction.value | BigNumberish | Value transfered if making a native token transfer. (usually 0n for contract interaction with non-native tokens like erc-20 tokens) |
metaTransaction[].MetaTransaction.data | BytesLike | The call data for the transaction |
metaTransaction[].MetaTransaction.operation | Operation: enum | Default to 0 for a Call. 1 for a Delegate Call. (Optional) |
safeModuleExecutorFunctionSelector | object | Safe has two executor functions executeUserOpWithErrorString and executeUserOp |
safeModuleExecutorFunctionSelector.executeUserOpWithErrorString | 0x541d63c8 | The MetaTransaction to create calldata for |
safeModuleExecutorFunctionSelector.executeUserOp | 0x7bb37428 | The MetaTransaction to create calldata for |
| key | type | description |
|---|
callData | string | CallData to be includes in the user operation to send a single transaction |
Example Response
callData : 0xf34308ef000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d6000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Source code
createAccountCallDataBatchTransactions
estimateUserOperationGas
Estimates gas limits for a UserOperation.
Usage
- example.ts
- Param Types
- Response Type
import {
SafeAccountV0_2_0 as SafeAccount,
UserOperationV6
} from "abstractionkit";
const bundlerRPC = "https://api.candide.dev/public/v3/11155111";
const ownerPublicAddress = "0xBdbc5FBC9cA8C3F514D073eC3de840Ac84FC6D31";
const smartAccount = SafeAccount.initializeNewAccount([ownerPublicAddress])
let userOperation: UserOperationV6 = smartAccount.createUserOperation(..);
const [preVerificationGas, verificationGasLimit, callGasLimit] = await estimateUserOperationGas(userOperation, bundlerRPC);
| key | type | description |
|---|
userOperation | UserOperationV6 | userOperation to send |
bundlerRpc | string | bundler rpc to send userOperation |
overrides? | object | overrides for the default values |
overrides?.stateOverrideSet? | object | Timestamp the signature will be valid after |
overrides?.stateOverrideSet?.[address: string] | object | Overrides for a specific address |
overrides?.stateOverrideSet?.[address: string].balance | bigint | Override the balance of the address |
overrides?.stateOverrideSet?.[address: string].nonce | bigint | Override the nonce of the address |
overrides?.stateOverrideSet?.[address: string].code | string | Override the code of the address |
overrides?.stateOverrideSet?.[address: string].state | Dictionary<string> | Override the storage slots of the address |
overrides?.stateOverrideSet?.[address: string].stateDiff | Dictionary<string> | Apply state differences to the storage slots of the address |
overrides?.dummySignerSignaturePairs[]? | object | Provide dummy signatures for the operation |
overrides?.dummySignerSignaturePairs[]?.SignerSignaturePair[] | object | Signature Pair |
overrides?.dummySignerSignaturePairs[]?.SignerSignaturePair[].Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key |
overrides?.dummySignerSignaturePairs[]?.SignerSignaturePair[].signature | string | signature |
overrides?.dummySignerSignaturePairs[]?.SignerSignaturePair[].isContractSignature | boolean | isContractSignature |
overrides?.expectedSigners? | object | The expected signers that will sign over the transaction. This improves the gas estimates. |
overrides?.expectedSigners?.Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key |
overrides?.webAuthnSharedSigner? | string | Specify the WebAuthn shared signer |
overrides?.webAuthnSignerFactory? | string | Specify the WebAuthn signer factory |
overrides?.webAuthnSignerSingleton? | string | Specify the WebAuthn signer singleton |
overrides?.webAuthnSignerProxyCreationCode? | string | Specify the WebAuthn signer proxy creation code |
overrides?.eip7212WebAuthnPrecompileVerifier? | string | Specify the EIP-7212 WebAuthn precompile verifier |
overrides?.eip7212WebAuthnContractVerifier? | string | Specify the EIP-7212 WebAuthn contract verifier |
UserOperationV6
| key | type | description |
|---|
sender | string | The account making the operation |
nonce | string | Anti-replay parameter (see “Semi-abstracted Nonce Support” ) |
initCode | string | The initCode of the account (needed if and only if the account is not yet on-chain and needs to be created) |
callData | string | The data to pass to the sender during the main execution call |
callGasLimit | bigint | The amount of gas to allocate the main execution call |
verificationGasLimit | bigint | The amount of gas to allocate for the verification step |
preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata |
maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) |
maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) |
paymasterAndData | string | Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster (empty for self-sponsored transaction). Revolves to '0x' if not using a paymaster, and a paymasterDummyData when estimating gas |
signature | string | The signature for the userOperation. It is the data passed into the account along with the nonce during the verification step. Resolves to '0x' when the user did not provide their signature yet |
| key | type | description |
|---|
ECDSASignature | string | ECDSA signature represented as a string |
WebauthnPublicKey
| key | type | description |
|---|
authenticatorData | ArrayBuffer | Binary data returned by the authenticator during the Webauthn process |
clientDataFields | string | Fields associated with the client's Webauthn request data |
rs | [bigint, bigint] | Array of two bigints representing the 'r' and 's' values of the signature |
| Parameter | Type | Description |
|---|
| gas estimates | Promise<[bigint, bigint, bigint]> | Returns the gas estimates of preVerificationGas, verificationGasLimit, callGasLimit |
Example Response
[ 46840n, 64545n, 102761n ]
Source code
estimateUserOperationGas
getUserOperationEip712Hash
Creates a UserOperation EIP-712 hash.
Usage
- example
- Param Types
- Return Types
example
import {
SafeAccountV0_2_0 as SafeAccount,
UserOperationV6
} from "abstractionkit";
const userOperation: UserOperationV6 = smartAccount.createUserOperation(..)
const safeUserOpHash = SafeAccount.getUserOperationEip712Hash(userOperation, chainId);
console.log(safeUserOpHash);
| key | type | description |
|---|
userOperation | object | UserOperation to hash |
userOperation.sender | string | The account making the operation |
userOperation.nonce | string | Anti-replay parameter (see “Semi-abstracted Nonce Support” ) |
userOperation.initCode | string | The initCode of the account (needed if and only if the account is not yet on-chain and needs to be created) |
userOperation.callData | string | The data to pass to the sender during the main execution call |
userOperation.callGasLimit | bigint | The amount of gas to allocate the main execution call |
userOperation.verificationGasLimit | bigint | The amount of gas to allocate for the verification step |
userOperation.preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata |
userOperation.maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) |
userOperation.maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) |
userOperation.paymasterAndData | string | Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster (empty for self-sponsored transaction). Revolves to '0x' if not using a paymaster, and a paymasterDummyData when estimating gas |
userOperation.signature | string | The signature for the userOperation. It is the data passed into the account along with the nonce during the verification step. Resolves to '0x' when the user did not provide their signature yet |
chainId | bigint | target chain id |
overrides? | object | Overrides for the default values |
overrides?.validAfter? | bigint | Timestamp the signature will be valid after |
overrides?.validUntil? | bigint | Timestamp the signature will be valid until |
overrides?.entrypointAddress? | string | Target entrypoint. Defaults to EP v0.6 |
overrides?.safe4337ModuleAddress? | string | Defaults to official 4337 safe module address |
| key | type | description |
|---|
userOperation | string | userOperation hash |
Source code
getUserOperationEip712Hash
A static method to format a list of EIP-712 signatures to a UserOperation signature.
Usage
- ethers example
- viem example
- Param Types
- Response Type
import { SafeAccountV0_2_0 as SafeAccount } from "abstractionkit";
import { Wallet } from "ethers";
const ownerPrivateKey = process.env.PRIVATE_KEY as string;
const signer = new Wallet(ownerPrivateKey);
const ownerPublicAddress = signer.address;
const smartAccount = SafeAccount.initializeNewAccount([ownerPublicAddress]);
let userOperation = ...
const safeUserOpHash = SafeAccount.getUserOperationEip712Hash(userOperation, chainId);
const signature = signer.signingKey.sign(safeUserOpHash).serialized;
const formatedSig = SafeAccount.formatEip712SignaturesToUseroperationSignature([ownerPublicAddress], [signature]);
userOperation.signature = formatedSig;
import { SafeAccountV0_2_0 as SafeAccount } from "abstractionkit";
import { privateKeyToAccount } from "viem";
const ownerPrivateKey = process.env.PRIVATE_KEY as string;
const signer = privateKeyToAccount(process.env.PRIVATE_KEY1 as `0x${string}`);
const ownerPublicAddress = signer.address;
const smartAccount = SafeAccount.initializeNewAccount([ownerPublicAddress]);
let userOperation = ...
const chainId = BigInt(process.env.CHAIN_ID as string);
const safeUserOpHash = SafeAccount.getUserOperationEip712Hash(
userOperation,
chainId
) as `0x${string}`;
const signature = await signer.sign({ hash: safeUserOpHash });
const formatedSig = SafeAccount.formatEip712SignaturesToUseroperationSignature([ownerPublicAddress], [signature]);
userOperation.signature = formatedSig;
| key | type | description |
|---|
signersAddresses | string[] | Provide dummy signatures for the operation |
signatures | string[] | Provide dummy signatures for the operation |
overrides? | object | overrides for the default values |
overrides?.validAfter? | bigint | Timestamp the signature will be valid after |
overrides?.validUntil? | bigint | Timestamp the signature will be valid until |
overrides?.isMultiChainSignature? | boolean | Whether this is a multi-chain signature using Merkle proofs |
overrides?.merkleProof? | string | Merkle proof for multi-chain signature verification |
| key | type | description |
|---|
signature | string | The EIP-712 Signature |
Example Response
0x0000000000000000000000006da39f6f7b0d2c0035084d3c313350697b3167ff591a84bf0b4bb4741224b5d226682ec306544c091e2b6535042c900b459282edfe98e393d552963ca8db11731c
Source code
formatEip712SignaturesToUseroperationSignature
isModuleEnabled
Checks if a specified module is enabled for a given Safe account. This function returns a boolean indicating the module's status.
| key | type | description |
|---|
nodeRpcUrl | string | The JSON-RPC API url for the target chain. |
moduleAddress | string | The module address to check if enabled. |
| key | type | description |
|---|
isEnabled | boolean | Indicates whether the specified module is enabled. |
Creates a meta-transaction to add a new owner to the Safe account with a specified threshold. This function returns an object containing the meta-transaction details, including the target address, encoded data, and transaction value.
| key | type | description |
|---|
newOwner | object | The public address of the new owner to be added |
newOwner.Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key |
threshold | number | The new threshold value for owner confirmations. |
overrides | object | Optional Overrides for the default values used in the transaction. |
overrides.nodeRpcUrl | string? | The JSON-RPC API url for the target chain, to check if the new webauthn owner is deployed or not |
overrides.eip7212WebAuthnPrecompileVerifier | string? | Address for the EIP-7212 WebAuthn precompile verifier. |
overrides.eip7212WebAuthnContractVerifier | string? | Address for the EIP-7212 WebAuthn contract verifier. |
overrides.webAuthnSignerFactory | string? | Address for the WebAuthn signer factory. |
overrides.webAuthnSignerSingleton | string? | Address for the WebAuthn signer singleton. |
| key | type | description |
|---|
Promise<MetaTransaction[]> | object | The meta-transaction object for adding a new owner with the specified threshold. |
Promise<MetaTransaction[]>.to | string | The target address for the meta-transaction (Safe account address). |
Promise<MetaTransaction[]>.data | string | The encoded function call data for adding an owner. |
Promise<MetaTransaction[]>.value | bigint | The value to be sent with the meta-transaction, set to zero for this function. |
Creates a meta-transaction to swap an owner in the Safe account. If a new owner verifier is not already deployed, it will deploy one and fetch the previous owner automatically. This function returns a promise that resolves to a list of meta-transactions containing the necessary details for the swap and deployment.
| key | type | description |
|---|
nodeRpcUrl | string | The JSON-RPC API URL for the target chain to fetch the previous owner. |
newOwner | object | The public address of the new owner to be added. |
newOwner.Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key |
oldOwner | Signer | The public address of the owner to be replaced. |
overrides | object | Overrides for the default values used in the transaction. |
overrides.prevOwner | string | If set, it will be used as the previous owner instead of fetching it. |
overrides.eip7212WebAuthnPrecompileVerifier | string | Address for the EIP-7212 WebAuthn precompile verifier. |
overrides.eip7212WebAuthnContractVerifier | string | Address for the EIP-7212 WebAuthn contract verifier. |
overrides.webAuthnSignerFactory | string | Address for the WebAuthn signer factory. |
overrides.webAuthnSignerSingleton | string | Address for the WebAuthn signer singleton. |
| key | type | description |
|---|
MetaTransaction[] | object | A promise that resolves to a list of meta-transactions for swapping the specified owner and deploying the verifier if necessary. |
MetaTransaction[].to | string | The target address for each meta-transaction (Safe account address). |
MetaTransaction[].data | string | The encoded function call data for the swap owner transaction. |
MetaTransaction[].value | bigint | The value to be sent with the meta-transaction, set to zero for these functions. |
Creates a meta-transaction to remove an owner from the Safe account, fetching the previous owner if not provided. This function returns a promise that resolves to a meta-transaction object containing the necessary details for the removal.
| key | type | description |
|---|
nodeRpcUrl | string | The JSON-RPC API URL for the target chain to fetch the previous owner. |
ownerToDelete | object | The public address of the owner to be deleted. |
ownerToDelete.Signer | ECDSAPublicAddress | WebauthnPublicKey | Signer type which can be either an ECDSA public address or a Webauthn public key |
threshold | number | The new threshold value for owner confirmations after removal. |
overrides | object | Optional Overrides for the default values used in the transaction. |
overrides.prevOwner | string | If set, it will be used as the previous owner instead of fetching it. |
overrides.eip7212WebAuthnPrecompileVerifier | string | Address for the EIP-7212 WebAuthn precompile verifier. |
overrides.eip7212WebAuthnContractVerifier | string | Address for the EIP-7212 WebAuthn contract verifier. |
overrides.webAuthnSignerFactory | string | Address for the WebAuthn signer factory. |
overrides.webAuthnSignerSingleton | string | Address for the WebAuthn signer singleton. |
| key | type | description |
|---|
MetaTransaction | object | A promise that resolves to the meta-transaction object for removing the specified owner. |
MetaTransaction.to | string | The target address for the meta-transaction (Safe account address). |
MetaTransaction.data | string | The encoded function call data for removing the owner. |
MetaTransaction.value | bigint | The value to be sent with the meta-transaction, set to zero for this function. |
Creates a meta-transaction to disable a module from the Safe account. The function automatically fetches the previous module address in the linked list if not provided in the overrides. This function returns a promise that resolves to a meta-transaction object containing the necessary details for disabling the module.
| key | type | description |
|---|
nodeRpcUrl | string | The JSON-RPC API URL for the target chain to fetch the previous module address. |
moduleToDisableAddress | string | The address of the module to be disabled. |
accountAddress | string | The Safe account address for which to disable the module. |
overrides | object | Optional overrides for the default values used in the transaction. |
overrides.prevModuleAddress | string | If set, it will be used as the previous module address instead of fetching it. |
overrides.modulesStart | string | Starting address for the module pagination query. |
overrides.modulesPageSize | bigint | Page size for the module pagination query. |
| key | type | description |
|---|
MetaTransaction | object | A promise that resolves to the meta-transaction object for disabling the specified module. |
MetaTransaction.to | string | The target address for the meta-transaction (Safe account address). |
MetaTransaction.data | string | The encoded function call data for disabling the module. |
MetaTransaction.value | bigint | The value to be sent with the meta-transaction, set to zero for this function. |
A static method that verifies a webAuthn signed hash message for Passkeys, and can be also used even if the safe account hasn't been deployed yet.
| key | type | description |
|---|
nodeRpcUrl | string | The JSON-RPC API url for the target chain. |
webAuthnPublicKey | object | The x and y coordinates of the webAuthn public key |
webAuthnPublicKey.x | bigint | The x coordinate of the webAuthn public key |
webAuthnPublicKey.y | bigint | The y coordinate of the webAuthn public key |
message | string | The hashed message to verify |
signature | string | The signed message |
overrides | object | Optional overrides for webAuthn verify signature message |
overrides.webAuthnSignerSingleton | string | Specify the WebAuthn signer singleton |
overrides.eip7212WebAuthnPrecompileVerifier | string | Specify the EIP-7212 WebAuthn precompile verifier |
overrides.eip7212WebAuthnContractVerifier | string | Specify the EIP-7212 WebAuthn contract verifier |
| key | type | description |
|---|
isValid | Promise<boolean> | Returns true if the message is valid signature |
getUserOperationEip712Data
A static method that returns the EIP-712 domain data for a UserOperation.
| key | type | description |
|---|
userOperation | object | UserOp to hash |
userOperation.sender | string | The account making the operation |
userOperation.nonce | string | Anti-replay parameter (see “Semi-abstracted Nonce Support” ) |
userOperation.initCode | string | The initCode of the account (needed if and only if the account is not yet on-chain and needs to be created) |
userOperation.callData | string | The data to pass to the sender during the main execution call |
userOperation.callGasLimit | bigint | The amount of gas to allocate the main execution call |
userOperation.verificationGasLimit | bigint | The amount of gas to allocate for the verification step |
userOperation.preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata |
userOperation.maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) |
userOperation.maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) |
userOperation.paymasterAndData | string | Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster (empty for self-sponsored transaction). Revolves to '0x' if not using a paymaster, and a paymasterDummyData when estimating gas |
userOperation.signature | string | The signature for the userOperation. It is the data passed into the account along with the nonce during the verification step. Resolves to '0x' when the user did not provide their signature yet |
chainId | bigint | target chain id |
overrides? | object | undefined |
overrides?.validAfter? | bigint | Timestamp the signature will be valid after |
overrides?.validUntil? | bigint | Timestamp the signature will be valid until |
overrides?.entrypointAddress? | string | Address of the entrypoint contract |
overrides?.safe4337ModuleAddress? | string | Address of the Safe 4337 module. |
| key | type | description |
|---|
domain | object | Safe userOperation typed data domain |
domain.chainId | number | target chain id |
domain.verifyingContract | string | safe 4337 module contract on traget entrypoint |
types | Record<string, {name: string;type: string;}[]> | The Safe Typed structured data to be signed |
messageValue | object | Safe userOperation typed message value |
messageValue.safe | string | the userop sender address of the safe account |
messageValue.nonce | string | Anti-replay parameter (see “Semi-abstracted Nonce Support” ) |
messageValue.initCode | string | The initCode of the account (needed if and only if the account is not yet on-chain and needs to be created) |
messageValue.callData | string | The data to pass to the sender during the main execution call |
messageValue.callGasLimit | bigint | The amount of gas to allocate the main execution call |
messageValue.verificationGasLimit | bigint | The amount of gas to allocate for the verification step |
messageValue.preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata |
messageValue.maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) |
messageValue.maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) |
messageValue.paymasterAndData | string | Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster (empty for self-sponsored transaction). Revolves to '0x' if not using a paymaster, and a paymasterDummyData when estimating gas |
messageValue.signature | string | The signature for the userOperation. It is the data passed into the account along with the nonce during the verification step. Resolves to '0x' when the user did not provide their signature yet |
Creates an array of meta-transactions to migrate a Safe account from EntryPoint v0.6 (module v0.2.0) to EntryPoint v0.7 (module v0.3.0). The migration disables the v0.6 module, enables the v0.7 module, and updates the fallback handler.
Usage
import { SafeAccountV0_2_0 as SafeAccount } from "abstractionkit";
const nodeRpcUrl = "https://rpc2.sepolia.org";
const smartAccount = new SafeAccount(accountAddress);
const migrationMetaTransactions =
await smartAccount.createMigrateToSafeAccountV0_3_0MetaTransactions(nodeRpcUrl);
const userOperation = await smartAccount.createUserOperation(
migrationMetaTransactions,
nodeRpcUrl,
bundlerUrl,
);
| key | type | description |
|---|
nodeRpcUrl | string | The JSON-RPC API URL for the target chain. |
overrides? | object | Optional overrides for contract addresses and pagination. |
overrides?.safeV06ModuleAddress? | string | Override the Safe v0.6 module address to disable. |
overrides?.safeV07ModuleAddress? | string | Override the Safe v0.7 module address to enable. |
overrides?.pageSize? | bigint | Page size for the module pagination query. |
overrides?.modulesStart? | string | Starting address for the module pagination query. |
| key | type | description |
|---|
MetaTransaction[] | object | Array of meta-transactions that disable the v0.6 module, enable the v0.7 module, and update the fallback handler. |
MetaTransaction[].to | string | The target address for the meta-transaction. |
MetaTransaction[].data | string | The encoded function call data. |
MetaTransaction[].value | bigint | The value to send with the meta-transaction (0n for these operations). |
Source code
createMigrateToSafeAccountV0_3_0MetaTransactions
Audits