Skip to main content
The balance action supports advanced parameters for pulling tokens from external accounts and building routes against estimated token amounts. These parameters extend the basic balance action, which simply returns the on-chain balance of the caller’s wallet.
This is an advanced feature intended for integrators who need to pull tokens from external accounts or pre-build routes before balances are available. Using account and estimate incorrectly can lead to loss of funds. Read the risk considerations below before integrating.

How It Works

  1. You submit a /bundle request with a balance action that includes account (and optionally estimate)
  2. The API performs an off-chain RPC call to check the account’s token balance
  3. If no estimate is provided and the balance is zero, the request returns an error
  4. For router strategy: the token and amount are added to tokensIn/amountsIn
  5. For delegate / ensowallet strategies: a transferFrom call is automatically inserted to pull tokens from the external account into the wallet
  6. The API generates approval transactions that the account must sign for the spender contract before the bundle can execute

Parameters

ParameterTypeDescriptionRequired
tokenAddressArgAddress of the token to check balanceYes
estimateNumberArgEstimated balance amount in wei. Allows route building without an existing balance on the account.No
accountAddressArgAddress of an external account to check balance of. Defaults to the caller’s wallet address when omitted.No
When only token is provided (no account or estimate), the action behaves exactly as the basic balance check — returning the on-chain balance of the caller’s wallet. See the basic usage.

Behavior by Routing Strategy

The advanced balance action behaves differently depending on the routing strategy and whether estimate is provided:

Router

  • With account only (no estimate): The account must approve the router contract.
  • With account and estimate: The account must approve the EnsoShortcuts contract. The required approval transaction is returned in the bundle response.
Dangerous: EnsoShortcuts contract approval. When using estimate with the router strategy, the account must approve the EnsoShortcuts contract. If approval is not reset back to 0, anyone will be able to pull funds from the wallet. You should revoke this approval within the same transaction to minimize the window of exposure. Leaving the approval active after the transaction is a security risk.

Delegate / EnsoWallet

StrategyBehavior when account is provided
delegateAutomatically inserts a transferFrom call to pull tokens from the account into the wallet. The account must approve the delegate contract.
ensowallet-v2Same as delegate — inserts a transferFrom call. The account must approve the EnsoWallet contract.
See Routing Strategies for details on choosing a strategy.

Balance Estimates

When estimate is provided alongside account, routes are built using the estimated amount rather than requiring the full on-chain balance:
  • The API uses the estimate for quoting and route optimization, enabling you to build transactions before the account has the full balance available
Routes built with estimate are only as accurate as the estimate itself. If the actual balance at execution time differs significantly from the estimate, the transaction may fail or produce suboptimal results.

Risk Considerations

  • EnsoShortcuts contract approval - When using estimate with the router strategy, the account must approve the EnsoShortcuts contract, which is the main execution contract where tokens will get pulled into. Always revoke this approval in the same transaction. The required approval is returned in the bundle response - pair it with a revoke action to avoid leaving a persistent approval.
  • Estimate as max amount - The estimate value should be treated as the maximum amount that will be pulled from the account. Swap aggregators used during routing may capture positive slippage, meaning the actual amount consumed can be up to the full estimate even if a smaller amount would have sufficed for the desired output. Set the estimate carefully to limit exposure.
  • Estimate accuracy - Using estimate means routes are optimized against projected amounts. Significant divergence between the estimate and the actual balance at execution time can cause transaction failure or poor execution prices.
  • External account security - This feature pulls tokens from an external account via transferFrom. Always verify the account address and its approval status before executing.

Examples

Balance with Account and Route

This example checks the USDC balance of an external account with an estimate, then routes the USDC to USDT.
const bundle = await client.getBundleData(
  {
    chainId: 1,
    fromAddress: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
    routingStrategy: "router",
  },
  [
    {
      protocol: "enso",
      action: "balance",
      args: {
        token: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
        account: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
        estimate: "1000000000", // 1000 USDC
      },
    },
    {
      protocol: "enso",
      action: "route",
      args: {
        tokenIn: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
        tokenOut: "0xdAC17F958D2ee523a2206206994597C13D831ec7", // USDT
        amountIn: { useOutputOfCallAt: 0 },
        slippage: "300",
      },
    },
  ],
);
What’s happening step by step:
  1. Balance — Check the USDC balance of the external account, using 1000 USDC as the estimate for route building
  2. Route — Route the USDC to USDT using useOutputOfCallAt: 0 to reference the balance from step 1

Balance with Account, TransferFrom, and Route

This example checks the balance, explicitly transfers tokens from the external account, then routes.
const bundle = await client.getBundleData(
  {
    chainId: 1,
    fromAddress: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
    routingStrategy: "router",
  },
  [
    {
      protocol: "enso",
      action: "balance",
      args: {
        token: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
        account: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
        estimate: "1000000000", // 1000 USDC
      },
    },
    {
      protocol: "erc20",
      action: "transferfrom",
      args: {
        token: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
        sender: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
        receiver: "0x4Fe93ebC4Ce6Ae4f81601cC7Ce7139023919E003", // EnsoShortcuts
        amount: { useOutputOfCallAt: 0 },
      },
    },
    {
      protocol: "enso",
      action: "route",
      args: {
        tokenIn: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
        tokenOut: "0xdAC17F958D2ee523a2206206994597C13D831ec7", // USDT
        amountIn: { useOutputOfCallAt: 0 },
        slippage: "300",
      },
    },
  ],
);
What’s happening step by step:
  1. Balance — Check the USDC balance of the external account with a 1000 USDC estimate
  2. TransferFrom — Explicitly transfer USDC from the external account to the router, using useOutputOfCallAt: 0 to reference the balance
  3. Route — Route the USDC to USDT
When the balance action detects a following transferFrom for the same token and account, it optimizes the flow automatically. Use useOutputOfCallAt to dynamically chain action outputs. See Chaining Actions for details.

Updated