# Bundler

Source: https://docs.settlemint.com/docs/api-reference/wallets/bundler
Submit and track ERC-4337 UserOperations, request ERC-7677 paymaster sponsorship, and discover the active chain and EntryPoint through DALP's account abstraction JSON-RPC endpoint.



DALP exposes `POST /api/v2/bundler` as an ERC-4337 bundler JSON-RPC endpoint with ERC-7677 paymaster support. Call it from your wallet or SDK to discover the active chain and EntryPoint, to submit and track UserOperations, and to request gas sponsorship. The endpoint is authenticated and scopes every operation to the wallets your organization owns.

**Requires:** advanced accounts enabled for the deployment, and an authenticated API request. Paymaster methods additionally require gas sponsorship to be enabled for your organization.

For the concept model, see [Bundlers](/docs/architects/components/infrastructure/advanced-accounts/bundlers), [UserOperations](/docs/architects/components/infrastructure/advanced-accounts/user-operations), and [Advanced accounts concept](/docs/architecture/concepts/account-abstraction). For paymaster deposits, sponsorship settings, and signer-key rotation, see [System paymasters](/docs/api-reference/wallets/system-paymasters) and [Paymasters and gas sponsorship](/docs/architects/components/infrastructure/advanced-accounts/paymasters-and-gas-sponsorship).

## Before you call [#before-you-call]

Authenticate every request with an API key for the organization whose wallets you operate. The endpoint resolves the active chain from platform configuration and the EntryPoint from the indexed Directory registration for that network.

Operations that name a `sender` wallet (submission, gas estimation, and paymaster sponsorship) only succeed when that wallet belongs to the authenticated organization. A wallet owned by another organization is rejected.

Send requests as JSON-RPC 2.0 objects with `Content-Type: application/json`. Use an `id` when the caller needs a response body. Requests without `id` are JSON-RPC notifications and return `204 No Content`.

## Endpoint [#endpoint]

| Endpoint               | Protocol     | Content type       | Use it for                                                                                |
| ---------------------- | ------------ | ------------------ | ----------------------------------------------------------------------------------------- |
| `POST /api/v2/bundler` | JSON-RPC 2.0 | `application/json` | Discover the active chain and EntryPoint, submit UserOperations, and request sponsorship. |

## Supported methods [#supported-methods]

| Method                         | Category      | Use it for                                                       |
| ------------------------------ | ------------- | ---------------------------------------------------------------- |
| `eth_chainId`                  | Discovery     | Read the active network chain ID.                                |
| `eth_supportedEntryPoints`     | Discovery     | Read the ERC-4337 EntryPoint supported by the platform.          |
| `eth_sendUserOperation`        | UserOperation | Submit a signed UserOperation for an owned wallet.               |
| `eth_estimateUserOperationGas` | UserOperation | Estimate gas limits for a UserOperation before submission.       |
| `eth_getUserOperationByHash`   | UserOperation | Look up a submitted UserOperation by its hash.                   |
| `eth_getUserOperationReceipt`  | UserOperation | Retrieve the receipt of a mined UserOperation.                   |
| `pm_getPaymasterStubData`      | Paymaster     | Get placeholder paymaster data for gas estimation (ERC-7677).    |
| `pm_getPaymasterData`          | Paymaster     | Get signed paymaster data to sponsor a UserOperation (ERC-7677). |

Methods not in this list return a JSON-RPC `-32601` method-not-found error when the request includes an `id`; requests without an `id` are notifications and produce `204 No Content`. `eth_getUserOperationByHash` can resolve a mined, in-flight mempool, or pending multisig-approval result, and returns `null` only when the hash is unknown to every lookup source.

## Quickstart [#quickstart]

Call `eth_supportedEntryPoints` first when your integration needs the EntryPoint for the active network. The EntryPoint address varies by network, so always read it from the bundler rather than hardcoding a canonical value:

```bash
curl --request POST \
  "$DALP_API_URL/api/v2/bundler" \
  --header "Content-Type: application/json" \
  --header "x-api-key: $DALP_API_KEY" \
  --data '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "eth_supportedEntryPoints",
    "params": []
  }'
```

```json
{
  "jsonrpc": "2.0",
  "result": ["0x1111111111111111111111111111111111111111"],
  "id": 1
}
```

A successful response echoes the same `id` and returns the EntryPoint list in `result`. The array format matches the standard ERC-4337 bundler method shape.

## Discovery methods [#discovery-methods]

### `eth_chainId` [#eth_chainid]

Returns the active chain ID as a hexadecimal string. The format matches the Ethereum JSON-RPC convention used by wallets, so the result can be passed directly to ERC-4337 tooling.

```bash
curl --request POST \
  "$DALP_API_URL/api/v2/bundler" \
  --header "Content-Type: application/json" \
  --header "x-api-key: $DALP_API_KEY" \
  --data '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "eth_chainId",
    "params": []
  }'
```

Example result:

```json
{
  "jsonrpc": "2.0",
  "result": "0x89",
  "id": 1
}
```

### `eth_supportedEntryPoints` [#eth_supportedentrypoints]

Returns the EntryPoint address DALP resolves for the active network. The result is an array so ERC-4337 clients can consume it through the standard bundler method shape.

The endpoint can return an EntryPoint registered for a private or local network instead of a hardcoded canonical address, so treat the result as network-specific.

If the Directory contract is not configured, or if the EntryPoint registration has not been indexed yet, the endpoint returns a JSON-RPC error response. Retry after configuration is complete and indexing has caught up.

## UserOperation methods [#useroperation-methods]

`eth_sendUserOperation`, `eth_estimateUserOperationGas`, `eth_getUserOperationByHash`, and `eth_getUserOperationReceipt` follow the ERC-4337 v0.9 bundler shape. Submission and gas estimation take the UserOperation object and the EntryPoint address; the `sender` wallet must belong to the authenticated organization.

Lookup methods take the UserOperation hash. `eth_getUserOperationByHash` resolves a hash across mined, in-flight mempool, and pending multisig-approval states, so an in-flight operation returns its UserOperation with null block fields rather than `null`. It returns `null` only when the hash is unknown to every lookup source. Poll a pending result instead of dropping the operation.

Both lookup methods return partial, nullable read shapes rather than the full standard ERC-4337 receipt and by-hash payloads. `eth_getUserOperationByHash` populates only the fields the network has resolved, leaving `transactionHash`, `blockNumber`, and `blockHash` null while an operation is in flight. The `eth_getUserOperationReceipt` result carries the standard top-level receipt fields, but its nested `receipt` object contains only `transactionHash`, `blockNumber`, and `transactionIndex`. Read these fields defensively and avoid strict ERC-4337 schema validators that reject responses missing optional receipt fields.

For the data model behind these methods, see [UserOperations](/docs/architects/components/infrastructure/advanced-accounts/user-operations).

### Submitting for a multisig wallet [#submitting-for-a-multisig-wallet]

When the `sender` is a smart wallet with a weighted multisig validator, `eth_sendUserOperation` accepts one signer's signature per call and accumulates signatures against a pending approval keyed by the UserOperation hash. A single call therefore does not always enqueue the operation: it submits the calling signer's weight, and the platform enqueues the operation only once the collected weight meets the configured threshold.

Because of this, a returned hash does not by itself confirm that the operation is in the mempool. Treat the response by state:

* **Below threshold.** The call records the signature and returns the UserOperation hash. The operation is held, not yet enqueued. Collect the remaining signer weight before treating it as submitted.
* **Threshold met.** The threshold-crossing call aggregates the collected signatures, validates the operation, and enqueues it. It returns the same UserOperation hash.
* **Duplicate signature.** A signer that has already signed a still-pending approval can resubmit safely. The platform treats it as an idempotent retry, does not add duplicate weight, and returns the same hash.

Confirm progress and final state with `eth_getUserOperationByHash`, which resolves a hash across pending multisig-approval, in-flight mempool, and mined states. To inspect collected weight and per-signer signatures directly, use the [multisig approvals API](/docs/api-reference/wallets/smart-wallet-approvals).

Two states return a JSON-RPC error rather than a hash. Neither is ever silently misread as accepted:

* A submission whose UserOperation hash is already tied to another approval flow that the calling organization cannot act on returns a `-32500` validation error. Submit a UserOperation that resolves to a hash unique to your wallet.
* An approval that is no longer pending and whose operation is not in the mempool returns a `-32603` internal error. Poll `eth_getUserOperationByHash` to check whether the operation has already settled; do not resubmit the same UserOperation.

## Paymaster methods [#paymaster-methods]

`pm_getPaymasterStubData` and `pm_getPaymasterData` implement the ERC-7677 paymaster interface so wallets can request gas sponsorship for an owned wallet's UserOperation. Use the stub method during gas estimation and the data method to obtain signed paymaster data before submission.

These methods require gas sponsorship to be enabled for your organization. When sponsorship is not enabled, the endpoint returns a JSON-RPC `-32601` method-not-found error. When no sponsorship paymaster is available for the wallet, it returns a `-32501` paymaster validation failure instead. For how sponsorship is funded and configured, see [System paymasters](/docs/api-reference/wallets/system-paymasters).

## Error responses [#error-responses]

The endpoint sends JSON-RPC error envelopes with HTTP 200 for parse, validation, and method errors, so bundler clients can handle failures through JSON-RPC semantics.

| Code     | Meaning          | When it appears                                                                                          |
| -------- | ---------------- | -------------------------------------------------------------------------------------------------------- |
| `-32700` | Parse error      | The request body is not valid JSON.                                                                      |
| `-32600` | Invalid request  | The request is not a JSON-RPC 2.0 object, has no string `method`, or uses an invalid `id` type.          |
| `-32601` | Method not found | The requested method is not supported, or a paymaster method was called without sponsorship enabled.     |
| `-32602` | Invalid params   | A method's parameters are missing or malformed, or a supplied `chainId` does not match the active chain. |
| `404`    | Not found        | The EntryPoint has not been indexed for the active network.                                              |
| `503`    | Unavailable      | The network Directory contract is not configured for EntryPoint discovery.                               |
| `-32603` | Internal error   | A supported method failed without a more specific JSON-RPC or DALP status code.                          |

UserOperation and paymaster methods can also return the standard ERC-4337 validation error codes. The most common are:

| Code     | Meaning              | When it appears                                                                                  |
| -------- | -------------------- | ------------------------------------------------------------------------------------------------ |
| `-32500` | Validation failed    | The UserOperation failed account validation, for example a sender not owned by the organization. |
| `-32501` | Paymaster validation | Paymaster validation failed or no sponsorship paymaster is available.                            |
| `-32504` | Paymaster throttled  | The paymaster is throttled or banned for the current operation.                                  |
| `-32507` | Signature failed     | The UserOperation signature is invalid, or the signer is not authorized for the wallet.          |
| `-32508` | Paymaster balance    | The paymaster has insufficient deposit to sponsor the operation.                                 |
| `-32521` | Execution reverted   | The UserOperation reverted during execution.                                                     |

Validation and method-resolution errors use this shape:

```json
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32600,
    "message": "Invalid JSON-RPC request",
    "data": {
      "dapiError": {
        "id": "DALP-0085",
        "category": "client",
        "status": 400,
        "retryable": false,
        "message": "Invalid JSON-RPC request",
        "why": "The JSON-RPC request is missing required fields or uses an unsupported shape.",
        "fix": "Send a valid JSON-RPC 2.0 request with the required method, id, and params fields."
      }
    }
  },
  "id": 1
}
```

For invalid JSON, DALP cannot read a request `id`, so the response uses `id: null`. Unsupported method responses use the JSON-RPC error envelope without `data.dapiError` because the method dispatcher can return a specific method-not-found message directly.

## Integration notes [#integration-notes]

* Authenticate every request with an organization API key. The `sender` wallet in submission, estimation, and sponsorship calls must be owned by that organization.
* Send `params` as an array. Discovery methods take no parameters, so `[]` is sufficient.
* You can include the active `chainId` as an optional parameter on `eth_sendUserOperation` and the `pm_*` paymaster methods. The value goes in the third positional parameter (`params[2]`), after the UserOperation and EntryPoint; an ERC-7677 `context` follows it. A supplied value that does not match the active chain is rejected with `-32602`.
* Use request IDs when the caller needs a response. Omit `id` only for fire-and-forget JSON-RPC notifications.
* Treat the returned EntryPoint as network-specific. Private and local networks can register an EntryPoint at a non-canonical address specific to that environment.
* Retry EntryPoint discovery only after the Directory contract is configured and the indexer has processed the registration. A `503` means the Directory address is not configured. A `404` means DALP could not read an indexed EntryPoint for the active network.
* Use the REST paymaster endpoints for funding and sponsorship configuration; the `pm_*` JSON-RPC methods request sponsorship for a specific UserOperation at submission time.
