> ## Documentation Index
> Fetch the complete documentation index at: https://docs.biconomy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Quote: EOA Mode

> Request quotes for standard wallet users

Use `mode: 'eoa'` for users with standard Ethereum wallets like MetaMask, Rabby, Trust Wallet, or any WalletConnect-compatible wallet.

## How EOA Mode Works

EOA mode uses **Fusion execution**—a system that lets regular wallets access Biconomy's gas abstraction without needing a smart account.

<Steps>
  <Step title="User specifies funding tokens">
    You tell the API which tokens the user will spend
  </Step>

  <Step title="API returns permit or approval payload">
    Depending on token support, user either signs a gasless permit or sends an approval tx
  </Step>

  <Step title="User signs">
    One signature per funding token
  </Step>

  <Step title="MEE executes">
    Biconomy handles the rest
  </Step>
</Steps>

## Basic Request

```typescript theme={null}
const quote = await fetch('https://api.biconomy.io/v1/quote', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'YOUR_API_KEY'
  },
  body: JSON.stringify({
    mode: 'eoa',
    ownerAddress: '0xYourUserAddress',
    fundingTokens: [{
      tokenAddress: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', // USDC on Base
      chainId: 8453,
      amount: '100000000' // 100 USDC (6 decimals)
    }],
    feeToken: {
      address: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
      chainId: 8453
    },
    composeFlows: [{
      type: '/instructions/intent-simple',
      data: {
        srcChainId: 8453,
        dstChainId: 10,
        srcToken: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
        dstToken: '0x94b008aa00579c1307b0ef2c499ad98a8ce58e58',
        amount: '100000000',
        slippage: 0.01
      }
    }]
  })
}).then(r => r.json());
```

## Required Parameters

| Parameter       | Type    | Description                               |
| --------------- | ------- | ----------------------------------------- |
| `mode`          | `'eoa'` | Must be `'eoa'`                           |
| `ownerAddress`  | string  | User's wallet address                     |
| `fundingTokens` | array   | Tokens user will spend (required for EOA) |
| `composeFlows`  | array   | Operations to execute                     |

## Understanding fundingTokens

**This is the key difference from other modes.** You must specify exactly which tokens the user is spending:

```typescript theme={null}
fundingTokens: [
  {
    tokenAddress: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', // Token contract
    chainId: 8453,                                              // Chain the token is on
    amount: '100000000'                                         // Amount in wei
  }
]
```

<Warning>
  The `amount` should cover both the operation AND any fees. If you're paying fees in the same token, include enough for both.
</Warning>

### Multiple Funding Tokens

If your operation involves multiple input tokens, list them all:

```typescript theme={null}
fundingTokens: [
  {
    tokenAddress: USDC_BASE,
    chainId: 8453,
    amount: '50000000'  // 50 USDC
  },
  {
    tokenAddress: USDT_BASE,
    chainId: 8453,
    amount: '50000000'  // 50 USDT
  }
]
```

<Note>
  Each funding token requires a separate signature. 2 tokens = 2 signatures.
</Note>

## Fee Token Rules

When using EOA mode, the `feeToken` must match one of your `fundingTokens`:

```typescript theme={null}
// ✅ Correct - feeToken matches a fundingToken
{
  fundingTokens: [{ tokenAddress: USDC, chainId: 8453, amount: '100000000' }],
  feeToken: { address: USDC, chainId: 8453 }
}

// ❌ Wrong - feeToken doesn't match any fundingToken
{
  fundingTokens: [{ tokenAddress: USDC, chainId: 8453, amount: '100000000' }],
  feeToken: { address: USDT, chainId: 8453 }  // Error!
}
```

## Quote Response

The API returns different `quoteType` values based on token capabilities:

```json theme={null}
{
  "quoteType": "permit",  // or "onchain"
  "payloadToSign": [...],
  "fee": { "amount": "50000", "token": "0x...", "chainId": 8453 }
}
```

| quoteType | Meaning                      | User Experience                           |
| --------- | ---------------------------- | ----------------------------------------- |
| `permit`  | Token supports EIP-2612      | Gasless—user just signs a message         |
| `onchain` | Token doesn't support permit | User must send approval transaction first |

## Signing the Payload

<Tabs>
  <Tab title="permit (Gasless)">
    Most modern tokens (USDC, DAI) support permit—user signs typed data:

    ```typescript theme={null}
    const payload = quote.payloadToSign[0];

    const signature = await walletClient.signTypedData({
      ...payload.signablePayload,
      account
    });
    ```
  </Tab>

  <Tab title="onchain (Approval Tx)">
    For older tokens, user must send an approval transaction:

    ```typescript theme={null}
    const payload = quote.payloadToSign[0];

    // Send the approval
    const txHash = await walletClient.sendTransaction({
      to: payload.to,
      data: payload.data,
      value: BigInt(payload.value || '0')
    });

    // Wait for confirmation (important!)
    await publicClient.waitForTransactionReceipt({ 
      hash: txHash,
      confirmations: 5 
    });

    // Use txHash as the "signature"
    const signature = txHash;
    ```
  </Tab>
</Tabs>

## Complete Example

```typescript theme={null}
import { createWalletClient, createPublicClient, http, parseUnits } from 'viem';
import { base } from 'viem/chains';

const USDC_BASE = '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913';
const USDT_OP = '0x94b008aa00579c1307b0ef2c499ad98a8ce58e58';

async function swapWithEOA(userAddress, walletClient, publicClient) {
  // 1. Get quote
  const quote = await fetch('https://api.biconomy.io/v1/quote', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      mode: 'eoa',
      ownerAddress: userAddress,
      fundingTokens: [{
        tokenAddress: USDC_BASE,
        chainId: 8453,
        amount: parseUnits('100', 6).toString()
      }],
      feeToken: {
        address: USDC_BASE,
        chainId: 8453
      },
      composeFlows: [{
        type: '/instructions/intent-simple',
        data: {
          srcChainId: 8453,
          dstChainId: 10,
          srcToken: USDC_BASE,
          dstToken: USDT_OP,
          amount: parseUnits('100', 6).toString(),
          slippage: 0.01
        }
      }]
    })
  }).then(r => r.json());

  // 2. Sign based on quoteType
  const payload = quote.payloadToSign[0];
  let signature;

  if (quote.quoteType === 'permit') {
    signature = await walletClient.signTypedData({
      ...payload.signablePayload,
      account: walletClient.account
    });
  } else {
    // onchain - send approval tx
    const txHash = await walletClient.sendTransaction({
      to: payload.to,
      data: payload.data
    });
    await publicClient.waitForTransactionReceipt({ hash: txHash });
    signature = txHash;
  }

  // 3. Execute
  const result = await fetch('https://api.biconomy.io/v1/execute', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      ...quote,
      payloadToSign: [{ ...payload, signature }]
    })
  }).then(r => r.json());

  return result.supertxHash;
}
```

## Important: Withdraw Funds

In EOA mode, swapped tokens land in a temporary Nexus account. **Add a withdrawal instruction** to send them back to the user's EOA:

```typescript theme={null}
composeFlows: [
  // Swap
  {
    type: '/instructions/intent-simple',
    data: { /* swap params */ }
  },
  // Withdraw to EOA
  {
    type: '/instructions/build',
    data: {
      chainId: 10,  // Destination chain
      to: USDT_OP,  // Token contract
      functionSignature: 'function transfer(address to, uint256 value)',
      args: [
        userAddress,  // Send to user's EOA
        {
          type: 'runtimeErc20Balance',
          tokenAddress: USDT_OP,
          constraints: { gte: '1' }
        }
      ]
    }
  }
]
```

<Warning>
  Without the withdrawal instruction, tokens stay in the Nexus account and user won't see them in their wallet!
</Warning>

## Next Steps

<CardGroup cols={2}>
  <Card title="Sign Payload" icon="signature" href="/overview/supertransaction-api/sign-payload">
    Detailed signing guide
  </Card>

  <Card title="Execute" icon="play" href="/overview/supertransaction-api/execute">
    Submit and track your transaction
  </Card>
</CardGroup>
