EIP-7702 enables smart account behavior for EOAs by allowing them to execute arbitrary calls via an authorization signature. This is especially useful for cross-chain transactions where the origin chain funds the destination chain execution, but the destination-side call must still reflect the user’s EOA as the msg.sender.

When to use EIP-7702?

By default, the Solver is the sender (msg.sender) of destination chain transactions. This works well for simple “buy” use cases where the action can be routed to the user. But in many other scenarios (e.g. minting, selling, approvals), the contract logic relies on the caller being the user’s EOA.

EIP-7702 solves this by turning any EOA into a smart wallet, allowing relayed calls to preserve the original msg.sender. This unlocks new capabilities like:

  • Delegated execution: destination chain transactions that require the user as msg.sender
  • Batched actions: approvals, minting, or function calls that must originate from the user

Relaying on the destination chain using EIP-7702

You can use EIP-7702 by passing an authorizationList inside the txs array during your /quote API call. The Solver will relay these transactions on the destination chain by passing the authorizationList while sending a type-4 transaction.

Here’s a complete example:

import { encodeFunctionData, parseEther, privateKeyToAccount } from "viem";
import axios from "axios";

// Step 1: Setup signer and smart account
const eoa7702 = privateKeyToAccount("EOA_PRIVATE_KEY");
const smartAccountImplementation = "0xdef..."; // Replace with your smart account implementation

// Step 2: Sign EIP-7702 authorization
const authorizationHash = await walletClient.signAuthorization({
  account: eoa7702,
  contractAddress: smartAccountImplementation,
});

// Workaround for viem and RPC compatibility 
delete authorizationHash.v;
(authorizationHash as any).address = authorizationHash.contractAddress;

// Step 3: Encode batched destination chain calls
const executeCallData = encodeFunctionData({
  abi,
  functionName: "executeBatch",
  args: [
    [
      {
        target: eoa7702.address,
        value: parseEther("0.00001"),
        data: "0x",
      },
      {
        target: eoa7702.address,
        value: parseEther("0.00002"),
        data: "0x",
      },
    ],
  ],
});

// Step 4: Construct and send quote request
const requestData = {
  user: eoa7702.address,
  originChainId: 10, // Optimism
  destinationChainId: 42161, // Arbitrum
  originCurrency: "0x0000000000000000000000000000000000000000",
  destinationCurrency: "0x0000000000000000000000000000000000000000",
  recipient: eoa7702.address,
  tradeType: "EXACT_OUTPUT",
  amount: "1000000000000000",
  useExternalLiquidity: false,
  txs: [
    {
      to: "0xabc...",
      value: "0",
      data: executeCallData,
      authorizationList: [authorizationHash],
    },
  ],
};