diff --git a/docs/api/reference/eth-sendbundle.mdx b/docs/api/reference/eth-sendbundle.mdx index 2f0e47de97..d23847f9ee 100644 --- a/docs/api/reference/eth-sendbundle.mdx +++ b/docs/api/reference/eth-sendbundle.mdx @@ -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 diff --git a/docs/get-started/how-to/bundle-transactions.mdx b/docs/get-started/how-to/bundle-transactions.mdx new file mode 100644 index 0000000000..53ce36f96b --- /dev/null +++ b/docs/get-started/how-to/bundle-transactions.mdx @@ -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. diff --git a/sidebars.js b/sidebars.js index b5335d2be5..6bf64adc0d 100644 --- a/sidebars.js +++ b/sidebars.js @@ -95,6 +95,7 @@ const sidebars = { }, "get-started/how-to/poh-api", "get-started/how-to/state-recovery", + "get-started/how-to/bundle-transactions", ], }, { diff --git a/static/img/socialCards/etherscan.jpg b/static/img/socialCards/etherscan.jpg index 3934132290..71034293a9 100644 Binary files a/static/img/socialCards/etherscan.jpg and b/static/img/socialCards/etherscan.jpg differ diff --git a/static/img/socialCards/reservoir.jpg b/static/img/socialCards/reservoir.jpg index b688f16302..60a61c12c8 100644 Binary files a/static/img/socialCards/reservoir.jpg and b/static/img/socialCards/reservoir.jpg differ diff --git a/static/img/socialCards/thirdweb-sdk.jpg b/static/img/socialCards/thirdweb-sdk.jpg index 23b73a9e5b..697e3cb0bb 100644 Binary files a/static/img/socialCards/thirdweb-sdk.jpg and b/static/img/socialCards/thirdweb-sdk.jpg differ