|
| 1 | +--- |
| 2 | +description: Send atomic batch transactions using `wallet_sendCalls`. |
| 3 | +--- |
| 4 | + |
| 5 | +# Send batch transactions |
| 6 | + |
| 7 | +You can send and manage batch transactions in MetaMask, using the methods specified by |
| 8 | +[EIP-5792](https://eips.ethereum.org/EIPS/eip-5792): |
| 9 | + |
| 10 | +- `wallet_getCapabilities` - Query whether support for atomic batch transactions is available. |
| 11 | +- `wallet_sendCalls` - Submit multiple transactions to be processed atomically by MetaMask. |
| 12 | +- `wallet_getCallsStatus` - Track the status of your transaction batch. |
| 13 | + |
| 14 | +## About atomic batch transactions |
| 15 | + |
| 16 | +An atomic batch transaction is a group of transactions that are executed together as a single unit. |
| 17 | +When a dapp requests to submit a batch of transactions atomically, MetaMask may prompt users to upgrade their externally owned account (EOA) to a [MetaMask delegator account](https://docs.gator.metamask.io/concepts/delegator-accounts). |
| 18 | +If the user accepts, MetaMask proceeds to upgrade the account and process the request as a single atomic transaction as specified by [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702). |
| 19 | + |
| 20 | +:::note Delegator accounts |
| 21 | +MetaMask delegator accounts are [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) smart contract accounts (SCAs) that support programmable account behavior and advanced features such as multi-signature approvals, transaction batching, and custom security policies. |
| 22 | + |
| 23 | +See the [MetaMask Delegation Toolkit documentation](https://docs.gator.metamask.io/) for more information about delegator accounts and their capabilities. |
| 24 | +::: |
| 25 | + |
| 26 | +The key benefits of atomic batch transactions include: |
| 27 | + |
| 28 | +- **Fewer clicks and less friction** - Users only need to review and approve a single wallet confirmation, instead of multiple confirmations. |
| 29 | + For example, users can confirm a spending cap and swap in one step instead of two. |
| 30 | +- **Faster completion times** - Only a single atomic transaction is confirmed onchain, instead of multiple individual transactions. |
| 31 | +- **Reduced gas fees** - When multiple transactions are executed atomically, users only need to pay a single gas fee. |
| 32 | + |
| 33 | +You can send batch transactions using [third-party libraries](#use-third-party-libraries) |
| 34 | +or [directly in your dapp](#send-batch-transactions-1). |
| 35 | + |
| 36 | +## Use third-party libraries |
| 37 | + |
| 38 | +You can send batch transactions using the following third-party libraries that support EIP-5792: |
| 39 | + |
| 40 | +- [Wagmi](https://wagmi.sh/react/api/hooks/useCapabilities) |
| 41 | +- [Viem](https://viem.sh/docs/actions/wallet/getCapabilities) |
| 42 | +- [thirdweb](https://portal.thirdweb.com/references/typescript/v5/hooks#eip5792) |
| 43 | + |
| 44 | +## Send batch transactions |
| 45 | + |
| 46 | +### 1. Query whether atomic batch is supported |
| 47 | + |
| 48 | +Use `wallet_getCapabilities` to query whether MetaMask supports atomic batch transactions for a specific address and specific chain IDs. |
| 49 | +For example: |
| 50 | + |
| 51 | +```js title="index.js" |
| 52 | +const capabilities = await provider // Or window.ethereum if you don't support EIP-6963. |
| 53 | + .request({ |
| 54 | + "method": "wallet_getCapabilities", |
| 55 | + "params": [ |
| 56 | + "0xd46e8dd67c5d32be8058bb8eb970870f07244567", // The user's wallet address. |
| 57 | + ["0x1", "0xaa36a7"] // (Optional) A list of chain IDs to query for. |
| 58 | + ], |
| 59 | + }); |
| 60 | +``` |
| 61 | + |
| 62 | +This method returns the status of the `atomic` capability for each chain ID. |
| 63 | +For example: |
| 64 | + |
| 65 | +```json |
| 66 | +{ |
| 67 | + "0x1": { |
| 68 | + "atomic": { |
| 69 | + "status": "ready" |
| 70 | + } |
| 71 | + }, |
| 72 | + "0xaa36a7": { |
| 73 | + "atomic": { |
| 74 | + "status": "supported" |
| 75 | + } |
| 76 | + } |
| 77 | +} |
| 78 | +``` |
| 79 | + |
| 80 | +The `atomic` capability can have a `status` of `supported` or `ready`: |
| 81 | + |
| 82 | +- `supported` means MetaMask supports atomic batch transactions for the account and chain ID. |
| 83 | +- `ready` means MetaMask will prompt the user to upgrade their account to a MetaMask delegator account. |
| 84 | + If the user approves, the `status` will upgrade to `supported`. |
| 85 | + |
| 86 | +If the `atomic` capability is not `supported` or `ready` for a specified chain ID, MetaMask will not return anything for that chain ID. |
| 87 | +If you don't specify any chain IDs in `wallet_getCapabilities`, MetaMask will return all chains in the wallet where the `atomic` capability is `supported` or `ready`. |
| 88 | + |
| 89 | +:::info Supported networks |
| 90 | +MetaMask currently supports atomic batch transactions on the following networks: |
| 91 | + |
| 92 | +- Ethereum Mainnet |
| 93 | +- Ethereum Sepolia |
| 94 | +- Gnosis Mainnet |
| 95 | +- Gnosis Chiado |
| 96 | +- BNB Smart Chain |
| 97 | + |
| 98 | +MetaMask will support this feature on more networks as they adopt EIP-7702. |
| 99 | +::: |
| 100 | + |
| 101 | +:::note Atomic batch unsupported |
| 102 | +- If the user has already upgraded their account to a third-party smart contract account, MetaMask does not currently support atomic batch transactions for that account. |
| 103 | +- If atomic batch is not supported, fall back to [`eth_sendTransaction`](index.md) instead of `wallet_sendCalls`, |
| 104 | +and [`eth_getTransactionReceipt`](/wallet/reference/json-rpc-methods/eth_gettransactionreceipt) |
| 105 | +instead of `wallet_getCallsStatus`. |
| 106 | +::: |
| 107 | + |
| 108 | +### 2. Submit a batch of transactions |
| 109 | + |
| 110 | +Use `wallet_sendCalls` to submit a batch of transactions. |
| 111 | +For example: |
| 112 | + |
| 113 | +```js title="index.js" |
| 114 | +const result = await provider. // Or window.ethereum if you don't support EIP-6963. |
| 115 | + request({ |
| 116 | + "method": "wallet_sendCalls", |
| 117 | + "params": [ |
| 118 | + { |
| 119 | + version: "2.0.0", // The version of the API format. This must be 2.0.0. |
| 120 | + from: "0xd46e8dd67c5d32be8058bb8eb970870f07244567", // The sender's address. |
| 121 | + chainId: "0xaa36a7", // The chain ID, which must match the currently selected network. |
| 122 | + atomicRequired: true, // Whether or not atomicity is required. |
| 123 | + calls: [ // The list of calls to send as a batch. |
| 124 | + { |
| 125 | + to: "0xd46e8dd67c5d32be8058bb8eb970870f07244567", |
| 126 | + value: "0x0" |
| 127 | + }, |
| 128 | + { |
| 129 | + to: "0xd46e8dd67c5d32be8058bb8eb970870f07244567", |
| 130 | + value: "0x0" |
| 131 | + } |
| 132 | + ] |
| 133 | + } |
| 134 | + ], |
| 135 | + }); |
| 136 | +``` |
| 137 | + |
| 138 | +:::note Atomic required parameter |
| 139 | +MetaMask only supports using `wallet_sendCalls` to send atomic batch transactions (not sequential batch transactions), |
| 140 | +so `atomicRequired` can be set to either `true` or `false`. |
| 141 | +If the `atomic` capability is not supported, `wallet_sendCalls` will return an error. |
| 142 | +::: |
| 143 | + |
| 144 | +This method returns a batch ID that you can use to track the status of the batch. |
| 145 | +For example: |
| 146 | + |
| 147 | +```json |
| 148 | +{ |
| 149 | + "id": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" |
| 150 | +} |
| 151 | +``` |
| 152 | + |
| 153 | +### 3. Track the status of the batch of transactions |
| 154 | + |
| 155 | +Use `wallet_getCallsStatus` to track the status of the submitted batch of transactions, |
| 156 | +using the batch ID returned by `wallet_sendCalls`. |
| 157 | +For example: |
| 158 | + |
| 159 | +```js title="index.js" |
| 160 | +const status = await provider // Or window.ethereum if you don't support EIP-6963. |
| 161 | + .request({ |
| 162 | + "method": "wallet_getCallsStatus", |
| 163 | + "params": [ |
| 164 | + "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" // Batch ID. |
| 165 | + ], |
| 166 | + }); |
| 167 | +``` |
| 168 | + |
| 169 | +This method returns status information about the batch of transactions, including: |
| 170 | + |
| 171 | +- The status code of the batch. |
| 172 | +- Whether the batch was executed atomically. |
| 173 | + Currently, this will always be `true` if the execution was successful. |
| 174 | +- A list of transaction receipts. |
| 175 | + |
| 176 | +For example: |
| 177 | + |
| 178 | +```json |
| 179 | +{ |
| 180 | + "version": "2.0.0", |
| 181 | + "chainId": "0xaa36a7", |
| 182 | + "id": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", |
| 183 | + "status": 200, // Status code. 200 means confirmed. |
| 184 | + "atomic": true, // Whether the calls were executed atomically. |
| 185 | + "receipts": [ // List of transaction receipts. |
| 186 | + { |
| 187 | + "logs": [ |
| 188 | + { |
| 189 | + "address": "0xa922b54716264130634d6ff183747a8ead91a40b", |
| 190 | + "topics": [ |
| 191 | + "0x5a2a90727cc9d000dd060b1132a5c977c9702bb3a52afe360c9c22f0e9451a68" |
| 192 | + ], |
| 193 | + "data": "0xabcd" |
| 194 | + } |
| 195 | + ], |
| 196 | + "status": "0x1", |
| 197 | + "blockHash": "0xf19bbafd9fd0124ec110b848e8de4ab4f62bf60c189524e54213285e7f540d4a", |
| 198 | + "blockNumber": "0xabcd", |
| 199 | + "gasUsed": "0xdef", |
| 200 | + "transactionHash": "0x9b7bb827c2e5e3c1a0a44dc53e573aa0b3af3bd1f9f5ed03071b100bb039eaff" |
| 201 | + } |
| 202 | + ] |
| 203 | +} |
| 204 | +``` |
| 205 | + |
| 206 | +:::note |
| 207 | +If the calls were executed atomically in a single transaction, a single receipt is returned. |
| 208 | + |
| 209 | +In some cases, calls can be executed atomically but in multiple transactions (for example, using |
| 210 | +`eth_bundle` on an L2 network resistant to reorgs). |
| 211 | +In these cases, `atomic` is `true` but multiple receipts are returned. |
| 212 | +::: |
0 commit comments