Skip to content

Commit

Permalink
SDK - Reworked advanced section for the 'recommended path' (#1865)
Browse files Browse the repository at this point in the history
* reworked advanced section for the 'recommended path'

* edits

* minor fixes

---------

Co-authored-by: Alexandra Tran <[email protected]>
  • Loading branch information
chakra-guy and alexandratran authored Feb 7, 2025
1 parent 05faf12 commit 9298341
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 163 deletions.
2 changes: 2 additions & 0 deletions docs/whats-new.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ of the [MetaMask developer page](https://metamask.io/developer/).

## January 2025

- Documented SDK [batching contract read operations](/sdk/guides/advanced/batch-requests) and [production readiness guide](/sdk/guides/advanced/production-readiness).
([#1865](https://github.com/MetaMask/metamask-docs/pull/1865))
- Documented [`eth_simulateV1`](/services/reference/ethereum/json-rpc-methods/eth_simulatev1). ([#1798](https://github.com/MetaMask/metamask-docs/pull/1798))
- Added new [MetaMask SDK documentation section](/sdk).
([#1766](https://github.com/MetaMask/metamask-docs/pull/1766))
Expand Down
1 change: 1 addition & 0 deletions sdk-sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const sidebar = {
items: [
'guides/advanced/connect-and-sign',
'guides/advanced/batch-requests',
'guides/advanced/production-readiness',
],
},
],
Expand Down
221 changes: 123 additions & 98 deletions sdk/guides/advanced/batch-requests.md
Original file line number Diff line number Diff line change
@@ -1,132 +1,157 @@
---
description: Batch multiple JSON-RPC requests.
description: Batch multiple JSON-RPC requests using MetaMask SDK or Wagmi.
---

# Batch requests

You can batch multiple JSON-RPC requests in your JavaScript dapp.
MetaMask SDK provides mechanisms to send multiple JSON-RPC requests in a single call.
However, "batching" can be used in two different contexts:

The SDK's `metamask_batch` method enables you to batch multiple JSON-RPC requests in a single call,
providing a streamlined approach for dapps to interact with EVM networks, and enabling complex
sequences of actions.
This method enhances performance, usability, and efficiency by reducing the number of network calls
made to MetaMask.
1. [**Wagmi batching for contract reads**](#use-wagmi-usereadcontracts) - Wagmi does not support MetaMask's generic batching mechanism.
Instead, it provides the [`useReadContracts`](https://wagmi.sh/react/api/hooks/useReadContracts) hook to perform multiple contract read operations in a single hook call.
This is specialized for retrieving data from smart contracts and returns an array of results corresponding to each read call.

Use cases include:
:::note
`useReadContracts` does not support batching JSON-RPC methods.
:::

- **Batching multiple signatures** - Send multiple signing requests in one batch.
2. [**Vanilla JavaScript batching with `metamask_batch`**](#use-vanilla-javascript-metamask_batch) -
This approach uses MetaMask SDK's `metamask_batch` method to group any JSON-RPC requests together, whether they are contract calls or other JSON-RPC methods (for example, signing messages or sending transactions).
Despite being batched into one HTTP request, each call still requires individual user approval, and if any request is rejected, the entire batch fails.

- **Switching networks** - Switch the EVM network, perform an action such as sending a transaction,
and switch back, all in one batch.
## Use Wagmi (`useReadContracts`)

- **Mixed transactions and signatures** - Combine transaction sending and signing requests in one batch.
When using Wagmi, you can perform multiple contract read operations in a single hook call using `useReadContracts`.
This method is designed specifically for contract calls and batches them together internally, returning the results as an array.
It is not a generic JSON-RPC batching tool but rather a specialized solution for reading from smart contracts.

`metamask_batch` opens up additional possibilities for sophisticated transaction flows in dapps,
enhancing the user experience and operational efficiency.
For more information, see the [Wagmi documentation](https://wagmi.sh/react/api/hooks/useReadContracts).

## Prerequisites
The following is an example of batching read operations using `useReadContracts`:

Set up MetaMask SDK in your JavaScript dapp.
```js
import { useReadContracts } from "wagmi";

## Use the `metamask_batch` method
// Example contract definitions with their address and ABI
const contractA = {
address: "0xContractAddress1",
abi: contractABI1,
} as const;

`metamask_batch` takes an array of JSON-RPC requests (`ChainRPC[]`) as its parameter.
const contractB = {
address: "0xContractAddress2",
abi: contractABI2,
} as const;

Each request in the batch is independent.
The user receives a prompt for each action within the batch, allowing them to approve or reject
individual requests.
If any request is rejected, the entire batch fails and an error is returned, ensuring integrity in
transactional operations.
function MyBatchReadComponent() {
const { data, isError, isLoading } = useReadContracts({
contracts: [
{
...contractA,
functionName: "getValueA",
},
{
...contractA,
functionName: "getValueB",
},
{
...contractB,
functionName: "getValueX",
args: [42],
},
{
...contractB,
functionName: "getValueY",
args: [42],
},
],
});

if (isLoading) return <div>Loading...</div>;
if (isError) return <div>Error fetching data.</div>;

return (
<div>
<p>getValueA: {data?.[0]?.toString()}</p>
<p>getValueB: {data?.[1]?.toString()}</p>
<p>getValueX: {data?.[2]?.toString()}</p>
<p>getValueY: {data?.[3]?.toString()}</p>
</div>
);
}
```
The method returns an array of results corresponding to each request.
In this example, four contract read calls are batched together.
The results are returned as an array in the same order as the calls, allowing you to process each result accordingly.
### React / Next.js / React Native example
:::tip
For a better user experience, it's important to use reliable RPC providers instead of public nodes.
We recommend using services like [MetaMask Developer](https://developer.metamask.io/) to ensure better reliability and performance.
:::
The following is an example of using `metamask_batch` to batch
[`personal_sign`](/wallet/reference/json-rpc-methods/personal_sign) and
[`eth_sendTransaction`](/wallet/reference/json-rpc-methods/eth_sendtransaction) in React, Next.js, or React Native/Expo:
## Use Vanilla JavaScript (`metamask_batch`)
```javascript title="index.js"
import { metamask_batch } from "metamask-sdk"
If you're not using Wagmi, you can directly use MetaMask SDK's `metamask_batch` method to group multiple JSON-RPC requests into a single HTTP call.
function MyComponent() {
const handleBatchRequest = async () => {
const batchRequests = [
{ method: "personal_sign", params: ["message", "address"] },
{
method: "eth_sendTransaction",
params: [
{
/* Transaction parameters */
},
],
},
]

try {
const results = await metamask_batch(batchRequests)
console.log(results) // Process results.
} catch (error) {
console.error("Batch request failed", error)
}
}
Use cases include:
return <button onClick={handleBatchRequest}>Send Batch Request</button>
}
```
- **Batching multiple signatures** - Send multiple signing requests in one batch.
- **Switching networks** - Switch the EVM network, perform an action such as sending a transaction, and switch back, all in one batch.
- **Mixed transactions and signatures** - Combine transaction sending and signing requests in one batch.
### Vue.js example
:::note
When using `metamask_batch`, keep in mind the following:
The following is an example of using `metamask_batch` to batch
[`personal_sign`](/wallet/reference/json-rpc-methods/personal_sign) and
[`eth_sendTransaction`](/wallet/reference/json-rpc-methods/eth_sendtransaction) in Vue.js:
- Even though the requests are batched, each individual request still requires user approval.
- If any request in the batch is rejected, the entire batch will fail.
:::
```javascript title="App.vue"
<script>
import { metamask_batch } from "metamask-sdk";
The following is an example of batching JSON-RPC requests using `metamask_batch`:
export default {
methods: {
async sendBatchRequest() {
const batchRequests = [
{ method: "personal_sign", params: ["message", "address"] },
```js
import { MetaMaskSDK } from "@metamask/sdk";

const MMSDK = new MetaMaskSDK();
const provider = MMSDK.getProvider();

async function handleBatchRequests() {
// Example batch: one personal_sign call and one eth_sendTransaction call.
const requests = [
{ method: "personal_sign", params: ["Hello from batch!", "0x1234..."] },
{
method: "eth_sendTransaction",
params: [
{
method: "eth_sendTransaction",
params: [
{
/* Transaction parameters */
},
],
from: "0x1234...",
to: "0xABCD...",
// Additional transaction parameters.
},
];

try {
const results = await metamask_batch(batchRequests);
console.log(results);
} catch (error) {
console.error("Error in batch request", error);
}
}
],
},
];

try {
const results = await provider.request({
method: "metamask_batch",
params: [requests],
});
console.log("Batch Results:", results);
} catch (err) {
console.error("Batch request failed:", err);
}
}
</script>
```

### Best practices

Follow these best practices when using `metamask_batch`:

- **Ensure each request in the batch is properly formatted** according to the JSON-RPC specifications.
document.getElementById("batchBtn").addEventListener("click", handleBatchRequests);
```
- **Handle errors appropriately**, especially when a batch request is partially approved.
The following HTML displays a **Send Batch** button:
- **Test batch operations** to ensure consistent behavior across different networks and accounts.
```html
<button id="batchBtn">Send Batch</button>
```
- **Be aware of the dependencies between chained requests.**
Avoid creating a dependency where the outcome of one request directly influences the context or
validity of a subsequent request within the same batch.
For example, avoid chaining a [`wallet_switchEthereumChain`](/wallet/reference/json-rpc-methods/wallet_switchethereumchain)
request with [`eth_signTypedData_v4`](/wallet/reference/json-rpc-methods/eth_signtypeddata_v4), because
`eth_signTypedData_v4` relies on the current chain ID, which would be altered by `wallet_switchEthereumChain`.
This approach ensures that each request in the batch operates independently and maintains its
integrity, regardless of changes introduced by preceding requests in the batch.
:::tip Tips
- For a better user experience, it's important to use reliable RPC providers instead of public nodes.
We recommend using services like [MetaMask Developer](https://developer.metamask.io/) to ensure better reliability and performance.
- Ensure that requests in a batch do not depend on one another's chain context, as mid-batch state changes can affect outcomes.
:::
Loading

0 comments on commit 9298341

Please sign in to comment.