Skip to main content
Send transactions through your EIP-7702 smart account. The transaction flow is similar to 4337 but uses your EOA address.

Prerequisites

Setup 7702 Client

Send Transactions

The sending API is identical to 4337 - the mode: "7702" was set during client creation.
useSendTransaction.ts
import { useState, useCallback } from "react";
import type { ModularAccountV2Client } from "@account-kit/smart-contracts";
import type { Address, Hash, Hex } from "viem";

interface TransactionCall {
  target: Address;
  data?: Hex;
  value?: bigint;
}

export function useSendTransaction(client: ModularAccountV2Client | null) {
  const [isPending, setIsPending] = useState(false);
  const [txHash, setTxHash] = useState<Hash | null>(null);
  const [error, setError] = useState<Error | null>(null);

  const sendTransaction = useCallback(
    async (calls: TransactionCall | TransactionCall[]): Promise<Hash> => {
      if (!client) throw new Error("Client not initialized");

      setIsPending(true);
      setError(null);

      try {
        const callsArray = Array.isArray(calls) ? calls : [calls];

        const formattedCalls = callsArray.map((call) => ({
          target: call.target,
          data: call.data ?? "0x",
          value: call.value ?? BigInt(0),
        }));

        const userOpHash = await client.sendUserOperation({
          uo: formattedCalls.length === 1 ? formattedCalls[0] : formattedCalls,
        });

        const hash = await client.waitForUserOperationTransaction(userOpHash);
        setTxHash(hash);
        return hash;
      } catch (err) {
        const error = err instanceof Error ? err : new Error("Failed to send");
        setError(error);
        throw error;
      } finally {
        setIsPending(false);
      }
    },
    [client]
  );

  return { sendTransaction, isPending, txHash, error };
}

Usage

import { useSmartAccountClient } from "./useSmartAccountClient";
import { useSendTransaction } from "./useSendTransaction";
import { parseEther } from "viem";

function SendTransaction() {
  const { client, address } = useSmartAccountClient();
  const { sendTransaction, isPending, txHash } = useSendTransaction(client);

  const handleSend = async () => {
    const hash = await sendTransaction({
      target: "0x...",
      value: parseEther("0.001"),
    });
    console.log("Transaction:", hash);
  };

  return (
    <div>
      <p>Address (same as EOA): {address}</p>
      <button onClick={handleSend} disabled={isPending}>
        {isPending ? "Sending..." : "Send 0.001 ETH"}
      </button>
      {txHash && <p>Tx: {txHash}</p>}
    </div>
  );
}

Key Differences from 4337

AspectEIP-7702EIP-4337
From AddressYour EOA addressSmart contract address
Transaction TypeStandard transaction with delegationUserOperation
Explorer ViewShows your address as senderShows smart wallet as sender

Next Steps