EIP 5792 Batching Support

Overview

EIP-5792 batching allows the Blockdaemon Earn Widget to combine multiple on-chain operations — such as token approval, fee extraction, and a swap — into a single wallet confirmation. This eliminates the multi-step signing flow that users would otherwise experience, reducing friction and abandonment.

Under EIP-5792, the widget uses the wallet_sendCalls RPC method to submit a list of calls atomically (or non-atomically, depending on configuration). The wallet itself is responsible for sequencing and submitting the calls on-chain.

📘

Prerequisite

Batch transaction support requires walletMode: "external" and embed=true in the widget URL.


Configuration

Batching is controlled by the batchOption field in your widget's feature configuration, managed by Blockdaemon. To enable EIP-5792, set batchOption with an eip5792 key.

batchOption Schema

{
  "batchOption": {
    "eip5792": {
      "atomicRequired": false
    }
  }
}

Important

batchOption is mutually exclusive: exactly one of eip5792 or eip7702 may be set at a time. Omit batchOption entirely to disable batching.

eip5792 Parameters

ParameterTypeDescription
atomicRequiredbooleanIf true, the widget requires the wallet to execute all calls atomically. If false, non-atomic execution is accepted. Defaults to false.

Runtime Override

You can also override batch mode at runtime via URL parameter:

https://<client-slug>.widget.blockdaemon.com?embed=true&batchMode=EIP-5792&atomicRequired=true
URL ParameterValuesDescription
batchModeEIP-5792, eip5792, offEnables or disables batching. Canonical label preferred.
atomicRequiredtrue, falseOverrides the atomicRequired config setting.

PostMessage Flow

When EIP-5792 is active, the widget communicates batch requests to the host application via PostMessage. The host is responsible for forwarding these to the connected wallet.

End-to-end sequence

Widget                          Host App                        Wallet
  │                                │                               │
  │──── sendBatchCalls ───────────▶│                               │
  │     { calls, chainId,          │──── wallet_sendCalls ────────▶│
  │       atomicRequired }         │                               │
  │                                │◀──── { bundleId } ────────────│
  │◀─── sendBatchCallsResponse ────│                               │
  │     { bundleId }               │                               │
  │                                │                               │
  │──── getCallsStatus ───────────▶│                               │
  │     { bundleId }               │──── wallet_getCallsStatus ───▶│
  │                                │◀──── { status, receipts } ────│
  │◀─── getCallsStatusResponse ────│                               │
  │     { status, receipts }       │                               │

Step 1: Widget sends sendBatchCalls

The widget sends an ordered list of calls to the host.

FieldTypeDescription
callsArray<{ to, value, data }>Ordered calls to execute. value is in hex wei.
chainIdstringCAIP-2 chain ID for the target network.
atomicRequiredbooleanWhether atomic execution is required.

Step 2: Host calls wallet_sendCalls

Forward the batch to the wallet using wallet_sendCalls with the calls, chainId, and atomicRequired values from the payload.

Step 3: Host responds with sendBatchCallsResponse

OptionWhen to useWhat to return
Two-phaseHost returns immediately{ bundleId } — widget polls for confirmation every 2s, up to 30 attempts
One-phaseHost polls internally{ hash } — widget skips polling entirely

On error, respond with success: false and an error string.

Step 4: Widget polls with getCallsStatus (two-phase only)

The widget sends { bundleId } periodically. The host calls wallet_getCallsStatus and responds with getCallsStatusResponse, returning { status, receipts } on success or success: false on error.


MetaMask Smart Transactions

⚠️

Known Limitation

MetaMask Smart Transactions do not support wallet_getCallsStatus. If your users connect via MetaMask with Smart Transactions enabled, polling will fail with a "No matching bundle found" error.

The widget handles this gracefully:

  1. Polling retries up to 5 times after receiving "No matching bundle found".
  2. If all retries fail, the widget displays a success state without a block explorer link, treating the transaction as submitted but unconfirmed.

No additional host-side handling is required for this edge case. If you want to avoid it entirely, use Option B (one-phase response with final hash) when detecting MetaMask Smart Transactions in your wallet layer.


👋 Need Help?

Contact us through email or our support page for any issues, bugs, or assistance you may need.