Bundler
A Bundler
is a class to an ERC-4337 Bundler JSON-RPC API methods such as estimating user operation gas, and sending user operations.
The Bundler
class sets up a Bundler Instance with a Bundler RPC URL.
Usage
Import
import { Bundler } from "abstractionkit";
How to use
Initialize a Bundler with your desired bundler RPC url
const bundlerRPC = "https://api.candide.dev/bundler/version/network/YOUR_API_KEY";
const bundler: Bundler = new Bundler(bundlerRPC);
Then you can consume Bundler methods:
const entrypointAddresses = await bundler.supportedEntryPoints();
Paramaters
bundlerURL string
Methods
chainId
Returns chain ID of the current network that the bundler is operating in
Usage
- example.ts
- Return Type
import { Bundler } from "abstractionkit";
const bundlerRPC = "https://api.candide.dev/bundler/version/network/YOUR_API_KEY";
const bundler: Bundler = new Bundler(bundlerRPC);
const getChainId = await bundler.chainId();
key | type | description |
---|---|---|
chainId | Promise<string> | Target ChainId of the Bundler URL used |
Example Response
0xaa36a7
JSON-RPC Method
supportedEntryPoints
Returns the list of the entryPoint addresses supported by the bundler
Usage
- example.ts
- Return Type
import { Bundler } from "abstractionkit";
const bundlerRPC = "https://api.candide.dev/bundler/version/network/YOUR_API_KEY";
const bundler: Bundler = new Bundler(bundlerRPC);
const entrypointAddresses = await bundler.supportedEntryPoints();
key | type | description |
---|---|---|
entrypoint addresses | Promise<string[]> | Support EntryPoints by the Bundler |
Example Response
[
'0x0000000071727De22E5E9d8BAf0edAc6f37da032',
'0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789'
]
JSON-RPC Method
estimateUserOperationGas
Generates and returns an estimate of how much gas is necessary to allow the user operation to complete, given a UserOperations.
Usage
See a full example in getting-started guide
- example.ts
- Param Type
- Return Type
import { Bundler, UserOperationV7 } from "abstractionkit";
const bundlerRPC = "https://api.candide.dev/bundler/version/network/YOUR_API_KEY";
const bundler: Bundler = new Bundler(bundlerRPC);
// Use createUserOperation() to help you construct the userOp below
const userOperation = smartAccount.createUserOperation(..)
const entryPointAddress = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
const estimation = await bundler.estimateUserOperationGas(userOperation, entryPointAddress);
key | type | description |
---|---|---|
userOperation | UserOperationV6 | UserOperationV7 | Supports both UserOperations Type on EntryPoint v0.6 and v0.7 |
entrypoint address | string | Target EntryPoint |
key | type | description |
---|---|---|
sender | string | The account making the operation |
nonce | string | Anti-replay parameter (see “Semi-abstracted Nonce Support” ) |
factory | string | account factory, only for new accounts |
factoryData | string | data for account factory (only if account factory exists) |
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 | Extra gas to pay the bunder |
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) |
paymaster | string | Address of paymaster contract, (or empty, if account pays for itself) |
paymasterVerificationGasLimit | string | The amount of gas to allocate for the paymaster post-operation code |
paymasterPostOpGasLimit | string | The amount of gas to allocate for the paymaster post-operation code |
paymasterData | string | Data for paymaster (only if paymaster exists) |
signature | string | Data passed into the account to verify authorization |
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 |
---|---|---|
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 |
Example Response
{
callGasLimit: 58588n,
preVerificationGas: 45628n,
verificationGasLimit: 94374n
}
JSON-RPC Method
sendUserOperation
Asks the bundler to sign and submit a User Operation
Usage
See a full example in getting-started guide
- example.ts
- Param Type
- Return Type
import { Bundler } from "abstractionkit";
const bundlerRPC = "https://api.candide.dev/bundler/version/network/YOUR_API_KEY";
const bundler: Bundler = new Bundler(bundlerRPC);
const entrypointAddress = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
// Use createUserOperation() to help you construct the userOp below
const userOperation = smartAccount.createUserOperation(..)
const userOperationHash = await bundler.sendUserOperation(userOperation, entrypointAddress);
key | type | description |
---|---|---|
userOperation | UserOperationV6 | UserOperationV7 | Supports both UserOperations Type on EntryPoint v0.6 and v0.7 |
entrypoint address | string | Target EntryPoint |
key | type | description |
---|---|---|
sender | string | The account making the operation |
nonce | string | Anti-replay parameter (see “Semi-abstracted Nonce Support” ) |
factory | string | account factory, only for new accounts |
factoryData | string | data for account factory (only if account factory exists) |
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 | Extra gas to pay the bunder |
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) |
paymaster | string | Address of paymaster contract, (or empty, if account pays for itself) |
paymasterVerificationGasLimit | string | The amount of gas to allocate for the paymaster post-operation code |
paymasterPostOpGasLimit | string | The amount of gas to allocate for the paymaster post-operation code |
paymasterData | string | Data for paymaster (only if paymaster exists) |
signature | string | Data passed into the account to verify authorization |
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 |
---|---|---|
userOpHash | string | UserOperation Hash |
Example Response
'0x0ff052095987556f476c6e6b7cdff65cc6191d2cede50a109fe6977c3287fc9a'
JSON-RPC Method
getUserOperationByHash
Returns a UserOperation by its hash returned from sendUserOperation
Usage
- example.ts
- Param Type
- Return Type
import { Bundler } from "abstractionkit";
const bundlerRPC = "https://api.candide.dev/bundler/version/network/YOUR_API_KEY";
const bundler: Bundler = new Bundler(bundlerRPC);
const userOperationHash = "0xb348b32bc9b9e90620839c3926db401558806b03b2a46dc6de21d3a4ed8412fb";
const userOperation = await bundler.getUserOperationByHash(userOperationHash);
key | type | description |
---|---|---|
userOpHash | string | UserOperation Hash |
key | type | description |
---|---|---|
userOperation | UserOperationV6 | UserOperationV7 | The user operation object, which can be either version 6 or version 7, depending on the entry point version used. |
entryPoint | string | The address of the entry point contract associated with the user operation. |
blockNumber | bigint | null | The block number in which the user operation was included, or null if it hasn't been included yet. |
blockHash | string | null | The hash of the block containing the user operation, or null if it hasn't been included yet. |
transactionHash | string | null | The transaction hash associated with the user operation, or null if it hasn't been included yet. |
key | type | description |
---|---|---|
sender | string | The account making the operation |
nonce | string | Anti-replay parameter (see “Semi-abstracted Nonce Support” ) |
factory | string | account factory, only for new accounts |
factoryData | string | data for account factory (only if account factory exists) |
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 | Extra gas to pay the bunder |
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) |
paymaster | string | Address of paymaster contract, (or empty, if account pays for itself) |
paymasterVerificationGasLimit | string | The amount of gas to allocate for the paymaster post-operation code |
paymasterPostOpGasLimit | string | The amount of gas to allocate for the paymaster post-operation code |
paymasterData | string | Data for paymaster (only if paymaster exists) |
signature | string | Data passed into the account to verify authorization |
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 |
Example Response
{
userOperation: {
sender: '0xbA1Cd2470F46778c9748ce676c00Ba48D6f0b89d',
nonce: '0x2',
initCode: '0x',
callData: '0xf34308ef0000000000000000000000001a02592a3484c2077d2e5d24482497f85e1980c6000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
callGasLimit: '0xa5e8',
verificationGasLimit: '0x1825b',
preVerificationGas: '0xcb5c',
maxFeePerGas: '0x3b9aca1e',
maxPriorityFeePerGas: '0x3b9aca00',
paymasterAndData: '0x3fe285dcd76bcce4ac92d38a6f2f8e964041e020000000000000000000000000000000000000000003000064cfa9640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064c82c6734b770b84cdf835ba3d1df6237178138c98ec5bef635cf8f3f2ac1fa3c0528a98b33c5ec5d5ab559f79ed3cac4ebb6b57de127840b433557938e46151b',
signature: '0x8a45a5eadb9f2f4b552ec20fa63424dbecca28a7a6f43f065298574861869071446b622ccc17c2eab539115afceb314f859a1cc7e9289935c4fddce833cda3ca1c'
},
entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
blockNumber: '0x908994',
blockHash: '0xd7d5471af5fdf2359031a5b0b7ac4c664b62aaaa0e4a65c248ef0fe78b7eeb9f',
transactionHash: '0xc8262db778457c24d8faa043879de973d6c8699ddb518b3864004d99093ce6e4'
}
JSON-RPC Method
getUserOperationReceipt
Returns the receipt of a UserOperation by its hash returned from sendUserOperation
Usage
- example.ts
- Param Type
- Return Type
import { Bundler } from "abstractionkit";
const bundlerRPC = "https://api.candide.dev/bundler/version/network/YOUR_API_KEY";
const bundler: Bundler = new Bundler(bundlerRPC);
const userOperationHash = "0xb348b32bc9b9e90620839c3926db401558806b03b2a46dc6de21d3a4ed8412fb";
const userOperationReceipt = await bundler.getUserOperationReceipt(
userOperationHash
);
key | type | description |
---|---|---|
userOpHash | string | UserOperation Hash |
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 |
| The detailed receipt of the user operation. |
Example Response
{
userOpHash: '0xb348b32bc9b9e90620839c3926db401558806b03b2a46dc6de21d3a4ed8412fb',
entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
sender: '0xba1cd2470f46778c9748ce676c00ba48d6f0b89d',
nonce: '0x2',
paymaster: '0x3fe285dcd76bcce4ac92d38a6f2f8e964041e020',
actualGasCost: 130079001821106,
actualGasUsed: 130079,
success: true,
logs: '[]',
receipt: {
blockHash: '0xd7d5471af5fdf2359031a5b0b7ac4c664b62aaaa0e4a65c248ef0fe78b7eeb9f',
blockNumber: '0x908994',
from: '0x3cfdc212769c890907bce93d3d8c2c53de6a7a89',
cumulativeGasUsed: '0x5f780b',
gasUsed: '0x1f069',
logs: '[{"address":"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789","blockHash":"0xd7d5471af5fdf2359031a5b0b7ac4c664b62aaaa0e4a65c248ef0fe78b7eeb9f","blockNumber":"0x908994","data":"0x","logIndex":"0x5b","removed":false,"topics":["0xbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972"],"transactionHash":"0xc8262db778457c24d8faa043879de973d6c8699ddb518b3864004d99093ce6e4","transactionIndex":"0x2f"},{"address":"0x3fe285dcd76bcce4ac92d38a6f2f8e964041e020","blockHash":"0xd7d5471af5fdf2359031a5b0b7ac4c664b62aaaa0e4a65c248ef0fe78b7eeb9f","blockNumber":"0x908994","data":"0x0000000000000000000000000000000000000000000000000000000000000000","logIndex":"0x5c","removed":false,"topics":["0xa050a122b4c0e369e3385eb6b7cccd8019638b2764de67bec0af99130ddf8471","0xb348b32bc9b9e90620839c3926db401558806b03b2a46dc6de21d3a4ed8412fb","0x000000000000000000000000ba1cd2470f46778c9748ce676c00ba48d6f0b89d","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":"0xc8262db778457c24d8faa043879de973d6c8699ddb518b3864004d99093ce6e4","transactionIndex":"0x2f"},{"address":"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789","blockHash":"0xd7d5471af5fdf2359031a5b0b7ac4c664b62aaaa0e4a65c248ef0fe78b7eeb9f","blockNumber":"0x908994","data":"0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000764e60b23fb2000000000000000000000000000000000000000000000000000000000001fc1f","logIndex":"0x5d","removed":false,"topics":["0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f","0xb348b32bc9b9e90620839c3926db401558806b03b2a46dc6de21d3a4ed8412fb","0x000000000000000000000000ba1cd2470f46778c9748ce676c00ba48d6f0b89d","0x0000000000000000000000003fe285dcd76bcce4ac92d38a6f2f8e964041e020"],"transactionHash":"0xc8262db778457c24d8faa043879de973d6c8699ddb518b3864004d99093ce6e4","transactionIndex":"0x2f"}]',
logsBloom: '0x000000000000000000000000000001080000000000000000000000000000000000080000000000000002000100000000001000000000000000000a00000000000000000000000000000000040000000000000000010000000000000000800000000000000a0000000000002000000800000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000004000000000040400000000004000000000000000000000002000000000000000000000000000001200000000000000000000000000000100000000022000000000000000000000000000000000000000000000000000000000010000000',
transactionHash: '0xc8262db778457c24d8faa043879de973d6c8699ddb518b3864004d99093ce6e4',
transactionIndex: '0x2f',
effectiveGasPrice: '0x69'
}
}