EIPs

EIP-5792 — Wallet calls (batched submission)

eips.ethereum.org/EIPS/eip-5792

A dapp asks the wallet to execute multiple calls atomically. The wallet can implement the batch any way it likes — multiple sequential transactions, a multicall, an EIP-7702 set-code call, or a smart-account UserOperation. The dapp doesn’t care; it just submits the calls and polls for status.

import { parse } from "valibot";
import { AddressSchema, BytesSchema, UintSchema } from "@ethernauta/core";
import { wallet_sendCalls, wallet_getCallsStatus } from "@ethernauta/eip/5792";
import type { Provider } from "@ethernauta/eip/1193";
import { create_provider, encode_chain_id } from "@ethernauta/transport";
import { eip155_1 } from "@ethernauta/chain/eip155-1";

const CHAIN_ID = encode_chain_id({ namespace: "eip155", reference: eip155_1.chainId });
declare const provider: Provider; // see /eips/6963 for discovery
const { signer } = create_provider(provider);

const account = parse(AddressSchema, "0x70997970C51812dc3A010C7d01b50e0d17dc79C8");
const token_a = parse(AddressSchema, "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
const token_b = parse(AddressSchema, "0xdAC17F958D2ee523a2206206994597C13D831ec7");
const approve_calldata = parse(BytesSchema, "0x");
const swap_calldata = parse(BytesSchema, "0x");
const chainId = parse(UintSchema, "0x1");

const result = await wallet_sendCalls([{
  version: "2.0.0",
  chainId,
  from: account,
  calls: [
    { to: token_a, data: approve_calldata },
    { to: token_b, data: swap_calldata },
  ],
}])(signer({ chain_id: CHAIN_ID }));

const status = await wallet_getCallsStatus([result.id])(
  signer({ chain_id: CHAIN_ID }),
);
void status;

Surface

Methods

MethodShapePurpose
wallet_send_callsSignable<SendCallsResult>Submit a batch.
wallet_get_calls_statusSignable<CallsStatus>Poll for status by batch ID.
wallet_get_capabilitiesSignable<Capabilities>What the wallet supports.

Status codes

CallsStatusCode enumerates pending / confirmed / partial / reverted states. The CALLS_STATUS constant holds the numeric values.

Types

  • SendCallsParameter, SendCallsParameters, SendCallsCall, SendCallsResult
  • CallsStatus, CallsStatusCode, CallsReceipt, CallsReceiptLog
  • Capabilities

All with matching Valibot schemas.

Why this matters

Without 5792, dapps that need “approve + swap” had to choose between:

  • Two separate signatures (bad UX).
  • Asking the user to use a hardcoded gas multiplier (fragile).
  • Relying on permit (only works on tokens that implement ERC-2612).

With 5792 the wallet decides the execution strategy: a multicall on chains where it’s deployed, an EIP-7702 set-code tx on chains where it’s deployed, or a smart-account UserOperation if the account is a 4337 smart account. The dapp doesn’t choose.

What the wallet does

The Ethernauta wallet’s send-calls view shows the batch as a list of decoded calls (using the selector registry to label them — see Tooling → ERC codegen). On approval, it picks the best execution strategy available for the active chain.

wallet_getCallsStatus is a tier-4 internal-storage read: the wallet tracks which batches it submitted and serves their status from a local registry.

See also