Skip to content
9 changes: 6 additions & 3 deletions docs/api/reference/eth-sendbundle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ define transaction execution order. This enables services such as:

Due to being sent atomically, the bundle will only be executed if all transactions are confirmed.

The method can also improve UX, as users can review and approve a bundle of transactions with one
click, rather than multiple clicks. (Assuming the dapp and wallet being used have implemented [EIP-5792](https://eips.ethereum.org/EIPS/eip-5792),
and the wallet supports `eth_sendBundle` on Linea.)
Assuming the dapp and wallet being used have implemented [EIP-5792](https://eips.ethereum.org/EIPS/eip-5792),
and the wallet supports `eth_sendBundle` on Linea, `eth_sendBundle` facilitates improved UX, as
users can review and approve a bundle of transactions with one click. You can also leverage this
functionality via the standard Wallet Call API (EIP-5792) methods, rather than using `eth_sendBundle`
directly. See our [guide on sending transaction bundles](../../get-started/how-to/bundle-transactions.mdx)
for further details.

:::info

Expand Down
173 changes: 173 additions & 0 deletions docs/get-started/how-to/bundle-transactions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
---
title: Send a transaction bundle
description: Use the EIP-5792 Wallet Call API on Linea
image: /img/socialCards/send-a-transaction-bundle.jpg
---

You can use the [EIP-5792 Wallet Call API](https://eips.ethereum.org/EIPS/eip-5792) on Linea with
wallets that support it, including MetaMask Extension v12.20.x or later.

Although [multiple wallets support EIP-5792](https://www.eip5792.xyz/ecosystem/wallets), MetaMask is
the only wallet that currently supports the Wallet Call API on Linea.

## Requirements

- Your dapp already supports EIP-5792.
- A wallet that supports EIP-5792 on Linea.

:::note

`eth_sendBundle` is only supported on Linea via Infura. It's also permissioned; to enable this endpoint
on your Infura account, please open a ticket via the "Contact" button on our [support page](https://support.linea.build).

:::

## How it works

The Wallet Call API enables transaction bundling, where multiple transactions are executed
atomically in a single transaction. This minimizes gas costs for the user and streamlines many
common web3 flows. For example, a transaction bundle could involve approving tokens for a swap and
executing the swap simultaneously.

Generally, the flow for sending a transaction bundle involves:
1. A dapp requests to send a bundle of transactions using `wallet_sendCalls`.
2. The wallet client needs to manage the logic. Usually, this is achieved through [EIP-7702—type transactions](https://eips.ethereum.org/EIPS/eip-7702).
On Linea, however, MetaMask uses [`eth_sendBundle`](../../api/reference/eth-sendbundle.mdx).
3. Once submitted, the dapp can track the status of the bundle using `wallet_getCallsStatus`.

## Send bundled transactions with MetaMask

MetaMask supports `wallet_sendCalls` on Linea by implementing `eth_sendBundle` on the backend;
for your dapp, you can focus on using the standard Wallet Call API methods.

Sending bundled transactions requires the user's externally owned account (EOA) to be upgraded to
a smart account. In MetaMask, the EOA is upgraded to an ERC-4337 smart account.

### Step 1: Query account capabilities

Before sending the transaction bundle, use [`wallet_getCapabilities`](https://docs.metamask.io/wallet/reference/json-rpc-methods/wallet_getcapabilities/)
to check if the wallet client and the user's account support the Wallet Call API:

```javascript
const capabilities = await provider.request({
"method": "wallet_getCapabilities",
"params": [
"0x742d35Cc6634C0532925a3b844Bc454e4438f44e", // User's address
["0x1", "0xe708"] // (Optional) Chains to query capabilities for
],
});
```

The method returns an object for each queried chain, recording whether the account and chain
combination supports the Wallet Call API within the `atomic` object.

```json
{
"0x1": {
"atomic": {
"status": "ready",
}
},
"0xe708": {
"atomic": {
"status": "supported",
}
}
}
```

- `ready`: The account and chain support the Wallet Call API, but the account hasn't yet been
upgraded to a smart account. MetaMask will prompt the user to upgrade the account.
- `supported`: MetaMask supports the Wallet Call API methods on the chain and account combination.

If the queried account and chain combination is not supported, the method will return nothing for
the chain ID.

### Step 2: Submit transaction bundle

Use [`wallet_sendCalls`](https://docs.metamask.io/wallet/reference/json-rpc-methods/wallet_sendcalls/)
to submit the transaction bundle:

```javascript
const bundle = await provider.request({
"method": "wallet_sendCalls",
"params": [
{
version: "2.0.0", // API format version; must be "2.0.0"
from: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e", // User's address
chainId: "0xe708",
atomicRequired: true, // Whether or not atomicity is required
calls: [
{
to: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
value: "0x0", // 0 ETH (e.g. contract call)
},
{
to: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
value: "0x2386f26fc10000", // 0.01 ETH (e.g. transfer value)
}
]
}
]
})
```

:::warning

Your implementation must include fallback logic to conventional transaction sending to cover
situations where the user's wallet does not support `eth_sendBundle` and/or EIP-5792 methods.

:::

`wallet_sendCalls` returns a batch `id` that can be used in step 3 to track the status of the
submitted bundle:

```json
{
"id": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
}
```

### Step 3: Check bundle status

The third element of the Wallet Call API is `wallet_getCallsStatus`, with which you can query the
status of the bundle with the `id` from step 2 as the sole parameter:

```javascript
const status = await provider.request({
"method": "wallet_getCallsStatus",
"params": [
"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
]
})
```

`wallet_getCallsStatus` returns an object including various pieces of information about the bundle:

```json
{
"version": "2.0.0",
"chainId": "0xe708",
"id": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331",
"status": 200, // Confirmed; see reference page for all codes
"atomic": true,
"receipts": [
{
"logs": [
"address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"data": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925",
"topics": [
"0x7f8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8"
],
],
"status": 0x1, // 1 = success, 0 = failure
"blockHash": "0x7f8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8",
"blockNumber": "0x12f3a4b",
"gasUsed": "0x6d60",
"transactionHash": "0x8a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1",
}
]
}
```

On Linea, the `receipts` array will always contain a single receipt.
1 change: 1 addition & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const sidebars = {
},
"get-started/how-to/poh-api",
"get-started/how-to/state-recovery",
"get-started/how-to/bundle-transactions",
],
},
{
Expand Down
Binary file modified static/img/socialCards/etherscan.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified static/img/socialCards/reservoir.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified static/img/socialCards/thirdweb-sdk.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.