Skip to main content
Wagmi와 Base Account로 단일 트랜잭션에서 여러 온체인 콜을 전송하는 방법을 알아보세요.

개요

Wagmi는 EVM(Ethereum Virtual Machine) 호환 네트워크를 위한 React 훅 모음으로, 지갑, 컨트랙트, 트랜잭션, 서명 작업을 쉽게 처리할 수 있게 해줍니다. Base Account는 Wagmi와 완벽하게 통합되어 친숙한 훅을 모두 사용할 수 있습니다. Base Account Wagmi 템플릿으로 바로 시작할 수 있습니다.

설정

이 가이드를 따르기 전에 Wagmi와 Base Account를 설정했는지 확인하세요.

기본 배치 트랜잭션

sendCalls 메서드를 사용하는 컴포넌트를 만들고 트랜잭션을 트리거하는 버튼을 추가하여 단일 트랜잭션에서 여러 ETH 전송을 보냅니다.
"use client";

import { useState } from "react";
import { useSendCalls } from "wagmi";
import { encodeFunctionData, parseUnits } from "viem";
import { baseSepolia } from "wagmi/chains";

// Base Sepolia의 USDC 컨트랙트 주소
const USDC_ADDRESS = "0x036CbD53842c5426634e7929541eC2318f3dCF7e";

// transfer 함수를 위한 ERC20 ABI
const erc20Abi = [
  {
    inputs: [
      { name: "to", type: "address" },
      { name: "amount", type: "uint256" },
    ],
    name: "transfer",
    outputs: [{ name: "", type: "bool" }],
    stateMutability: "nonpayable",
    type: "function",
  },
] as const;

export function BatchTransactions() {
  const { sendCalls, data, isPending, isSuccess, error } = useSendCalls();
  const [amount1, setAmount1] = useState("1");
  const [amount2, setAmount2] = useState("1");
  const [usePaymaster, setUsePaymaster] = useState(false);

  async function handleBatchTransfer() {
    try {
      // 첫 번째 전송 콜 인코딩
      const call1Data = encodeFunctionData({
        abi: erc20Abi,
        functionName: "transfer",
        args: [
          "0x2211d1D0020DAEA8039E46Cf1367962070d77DA9",
          parseUnits(amount1, 6), // USDC는 소수점 6자리
        ],
      });

      // 두 번째 전송 콜 인코딩
      const call2Data = encodeFunctionData({
        abi: erc20Abi,
        functionName: "transfer",
        args: [
          "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
          parseUnits(amount2, 6), // USDC는 소수점 6자리
        ],
      });

      // 페이마스터 활성화 시 capabilities 객체 준비
      const capabilities = usePaymaster
        ? {
            paymasterService: {
              url: process.env.NEXT_PUBLIC_PAYMASTER_URL || "https://api.developer.coinbase.com/rpc/v1/base-sepolia",
            },
          }
        : undefined;

      // 배치 콜 전송
      sendCalls({
        calls: [
          {
            to: USDC_ADDRESS,
            data: call1Data,
          },
          {
            to: USDC_ADDRESS,
            data: call2Data,
          },
        ],
        chainId: baseSepolia.id,
        capabilities,
      });
    } catch (err) {
      console.error("Error batching transactions:", err);
    }
  }

  return (
    <div>
      <h2>USDC 배치 전송</h2>

      <div>
        <div>
          <label>금액 1 (USDC):</label>
          <input
            type="number"
            value={amount1}
            onChange={(e) => setAmount1(e.target.value)}
            placeholder="1"
            step="0.000001"
            min="0"
          />
        </div>

        <div>
          <label>금액 2 (USDC):</label>
          <input
            type="number"
            value={amount2}
            onChange={(e) => setAmount2(e.target.value)}
            placeholder="1"
            step="0.000001"
            min="0"
          />
        </div>

        <div>
          <label>
            <input
              type="checkbox"
              checked={usePaymaster}
              onChange={(e) => setUsePaymaster(e.target.checked)}
            />
            페이마스터 사용 (가스 후원)
          </label>
        </div>

        <button onClick={handleBatchTransfer} disabled={isPending}>
          {isPending ? "전송 중..." : "배치 전송"}
        </button>
      </div>

      {isPending && <div>트랜잭션 처리 중...</div>}

      {isSuccess && data && (
        <div>
          <p>배치 전송 성공!</p>
          <p>배치 ID: {data.id}</p>
        </div>
      )}

      {error && <div>오류: {error.message}</div>}
    </div>
  );
}
먼저 “지갑 연결”을 할 필요가 없습니다Base Account를 사용하면 먼저 “지갑 연결”(즉, eth_requestAccounts 사용)을 하지 않아도 sendCalls 메서드를 사용하여 트랜잭션 전송을 위한 사용자 프롬프트를 표시할 수 있습니다.