Skip to content

Batch transactions

Function to send a batch of transactions in a single call using the connected Global Wallet.

Viem’s sendCalls method following EIP-5792 can be used to sign and submit multiple transactions in a single call using the connected Global Wallet.

Installation

Install the Global Wallet:

npm install @rapidfire/id

Setup

Import and create the Ecosystem SDK instance:

import EcosystemWallet from '@rapidfire/id'
 
// Initialize the SDK with required parameters
export const config = new EcosystemWallet({
  appChainIds: [84532],
  appLogoUrl: 'https://a.rgbimg.com/users/b/ba/barunpatro/600/mf6B5Gq.jpg',
  appName: 'Example App',
});

Contract interactions

A common pattern is to approve and then mint:

Import required hooks: useAccount and useWriteContracts from Wagmi, define your smart contract ABI, initialize the useWriteContracts hook for batch transactions, and create a transaction handling function that can process multiple contract calls.

app.tsx
 
import * as React from 'react'
import { useAccount, useSendCalls } from 'wagmi'
import { abi } from './abi'
 
function BatchTransactionComponent() {
  const account = useAccount()
  const { SendCalls } = useSendCalls()
 
  const handleBatchTransaction = () => {
    SendCalls({
      contracts: [
        {
          address: "0x119Ea671030FBf79AB93b436D2E20af6ea469a19",
          abi,
          functionName: "approve",
          args: [account.address],
        },
        // Add more contract interactions as needed
        {
          address: "0x119Ea671030FBf79AB93b436D2E20af6ea469a19",
          abi,
          functionName: "safeMint",
          args: [account.address],
        }
      ],
    })
  }
 
  return (
    <button 
      onClick={handleBatchTransaction}
      className="px-4 py-2 bg-blue-600 text-white rounded"
    >
      Execute Batch Transaction
    </button>
  )
}

Advance features

Checking wallet capabilties

First, verify if your app supports atomic batching (This step is crucial if your app supports multiple wallet types). Use the useCapabilities hook from Wagmi experimental features and implement fallback functionality for unsupported wallets.

Note: The useWriteContracts and useCapabilities hooks rely on new wallet RPC and may not be supported in all wallets.

import { useCapabilities } from 'wagmi/experimental'
 
function App() {
  const { data: capabilities } = useCapabilities() 
  // Returns capability object per chain:
  // {
  //   84532: {
  //     atomicBatch: {
  //       supported: true,
  //     },
  //   }  
  // }
  
  // Check if atomic batching is supported in the chain we want to interact with
  const isAtomicBatchSupported = capabilities?.[84532]?.atomicBatch?.supported
  
  return (
    <div>
      {isAtomicBatchSupported ? (
        <BatchTransactionComponent />
      ) : (
        <FallbackComponent />
      )}
    </div>
  )
}

Implement transaction status monitoring

Add the useCallsStatus hook to track transaction status, configure polling interval for status updates, display transaction status to users, and handle transaction completion and errors.

Pro tip: The polling interval can be adjusted based on your needs, but 1 second is a good default.

import { useSendCalls } from 'wagmi'
 
function BatchTransactionComponent() {
  const { data: id, sendCalls } = useSendCalls()
  const { data: callsStatus } = useCallsStatus({
    id: id as string,
    query: {
      enabled: !!id,
      // Poll every second until confirmed
      refetchInterval: (data) =>
        data.state.data?.status === "CONFIRMED" ? false : 1000,
    },
  })
 
  // Example response structure:
  // {
  //   status: 'CONFIRMED',
  //   receipts: [
  //     {
  //       logs: [{
  //         address: '0x...',
  //         topics: ['0x...'],
  //         data: '0x...'
  //       }],
  //       status: 'success',
  //       blockHash: '0x...',
  //       blockNumber: 122414523n,
  //       gasUsed: 390000n,
  //       transactionHash: '0x...'
  //     }
  //   ]
  // }
 
  return (
    <div className="space-y-4">
      <button 
        onClick={handleBatchTransaction}
        className="px-4 py-2 bg-blue-600 text-white rounded"
      >
        Execute Batch Transaction
      </button>
      
      {callsStatus && (
        <div className="p-4 border rounded">
          <p className="font-semibold">
            Status: {callsStatus.status}
          </p>
          {callsStatus.status === 'CONFIRMED' && (
            <p className="text-green-600">
              Transaction confirmed! Hash: {callsStatus.receipts[0].transactionHash}
            </p>
          )}
        </div>
      )}
    </div>
  )
}