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

# Funding & Withdrawals

> Use the Execution API for deposit addresses, balances, sync, and withdrawals

<Info>
  Funding endpoints require a signed-in user session. Start with
  [Authentication](/recipes/authentication) before calling the execution routes below.
</Info>

AGG exposes execution endpoints for deposit addresses, balance sync, withdrawals, positions, and
orders so partners can build funding and account views on top of the same user session.

AGG's omni-chain funding flow lets users deposit on supported chains without choosing a destination
venue account up front. After funds arrive, AGG tracks managed balances and automatically
rebalances across managed accounts as needed for execution, eliminating the need for users to split
deposits manually across venues or addresses.

## How it works

<Steps>
  <Step title="User authenticates">
    Sign in via SIWE, SIWS, Google, or any supported provider.
  </Step>

  <Step title="Get deposit address">
    Call `GET /execution/deposit-addresses` to get the user's wallet addresses and supported chains.
    Returns `202` while the addresses are being prepared — poll until `200`.
  </Step>

  <Step title="User sends USDC">
    The user sends USDC to a supported deposit address on the chain they prefer.
  </Step>

  <Step title="Balance updates">
    Call `GET /execution/balances` to see per-chain cash balances plus current venue positions.
    Use `POST /execution/sync-balances` to force an on-chain sync if needed. For paginated activity,
    use `GET /execution/positions` and `GET /execution/orders`.
  </Step>

  <Step title="Withdraw or continue">
    Use the same execution surface for withdrawals, positions, orders, and any account-level
    funding UI in your app.
  </Step>
</Steps>

***

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    import { createAggClient } from "@agg-build/sdk";

    type DepositAddressesResponse =
      | {
          ready: true;
          evmAddress: string;
          svmAddress: string;
          supportedChains: Array<{
            chainId: number;
            name: string;
            tokens: Array<{
              symbol: string;
              address: string;
              decimals: number;
            }>;
          }>;
        }
      | { ready: false };

    const client = createAggClient({
      baseUrl: "https://api.agg.market",
      appId: "your-app-id",
    });

    // After user authenticates...

    // 1. Get deposit addresses (poll until ready)
    async function getDepositInfo() {
      while (true) {
        const res = await client.request<DepositAddressesResponse>(
          "/execution/deposit-addresses",
        );

        if (res.ready) {
          return {
            evmAddress: res.evmAddress,     // Send USDC here on any EVM chain
            svmAddress: res.svmAddress,     // Send USDC here on Solana
            chains: res.supportedChains,    // Available chains + token addresses
          };
        }

        // Deposit addresses are still being prepared — wait and retry
        await new Promise((r) => setTimeout(r, 2000));
      }
    }

    const deposit = await getDepositInfo();
    console.log("EVM deposit address:", deposit.evmAddress);
    console.log("Solana deposit address:", deposit.svmAddress);
    console.log("Supported chains:", deposit.chains.map((c) => c.name));

    // 2. Check balances
    const balances = await client.getManagedBalances();
    // balances.cash    — per-chain token balances
    // balances.positions — per-venue position balances

    // 3. Force balance sync (after deposit)
    await client.request<Record<string, never>>("/execution/sync-balances", {
      method: "POST",
      body: JSON.stringify({}),
    });
    ```
  </Tab>

  <Tab title="Hooks">
    ```tsx theme={null}
    import { useAggClient } from "@agg-build/hooks";
    import { useQuery } from "@tanstack/react-query";

    type DepositAddressesResponse =
      | {
          ready: true;
          evmAddress: string;
          svmAddress: string;
          supportedChains: Array<{
            chainId: number;
            name: string;
            tokens: Array<{ symbol: string; address: string; decimals: number }>;
          }>;
        }
      | { ready: false };

    function DepositInfo() {
      const client = useAggClient();

      const { data: deposit, isLoading } = useQuery({
        queryKey: ["deposit-addresses"],
        queryFn: () =>
          client.request<DepositAddressesResponse>("/execution/deposit-addresses"),
        refetchInterval: (query) => {
          // Poll every 2s until deposit addresses are ready
          return query.state.data?.ready ? false : 2000;
        },
      });

      const { data: balances } = useQuery({
        queryKey: ["managed-balances"],
        queryFn: () => client.getManagedBalances(),
        refetchInterval: 10_000, // Refresh every 10s
      });

      const { data: positions } = useQuery({
        queryKey: ["execution-positions"],
        queryFn: () => client.getExecutionPositions({ limit: 20 }),
        enabled: !!deposit?.ready,
      });

      if (isLoading || !deposit?.ready) {
        return <p>Preparing deposit addresses...</p>;
      }

      return (
        <div>
          <h3>Deposit USDC</h3>
          <p>EVM address: <code>{deposit.evmAddress}</code></p>
          <p>Solana address: <code>{deposit.svmAddress}</code></p>

          <h4>Supported chains</h4>
          <ul>
            {deposit.supportedChains.map((chain) => (
              <li key={chain.chainId}>
                {chain.name} — {chain.tokens.map((t) => t.symbol).join(", ")}
              </li>
            ))}
          </ul>

          {balances && (
            <div>
              <h4>Your balances</h4>
              <pre>{JSON.stringify(balances.cash, null, 2)}</pre>
            </div>
          )}

          {positions && (
            <div>
              <h4>Open positions</h4>
              <p>{positions.data.length} grouped positions loaded</p>
            </div>
          )}
        </div>
      );
    }
    ```
  </Tab>

  <Tab title="UI Components">
    The `@agg-build/ui` package exports `DepositModal` and `WithdrawModal` for venue-level funding
    and withdrawal UX. These components are **presentational**: you provide balances, handlers, and
    any execution API calls behind them.

    New deposits should offer active venues only. During the Kalshi wind-down, an existing Kalshi
    balance may still appear as a disabled historical entry in withdrawal or claim surfaces.

    ```tsx theme={null}
    import { useState } from "react";
    import { DepositModal, WithdrawModal } from "@agg-build/ui/modals";

    function FundingButtons() {
      const [depositOpen, setDepositOpen] = useState(false);
      const [withdrawOpen, setWithdrawOpen] = useState(false);

      return (
        <>
          <button onClick={() => setDepositOpen(true)}>Deposit</button>
          <button onClick={() => setWithdrawOpen(true)}>Withdraw</button>

          <DepositModal
            open={depositOpen}
            onOpenChange={setDepositOpen}
            venues={[
              { venue: "polymarket", balance: 125 },
              { venue: "limitless", balance: 40 },
            ]}
            onSelectVenue={(venue) => console.log("deposit venue", venue)}
            onSelectDepositMethod={(venue, method) =>
              console.log("deposit method", venue, method)
            }
          />

          <WithdrawModal
            open={withdrawOpen}
            onOpenChange={setWithdrawOpen}
            venues={[
              { venue: "polymarket", balance: 125 },
              {
                venue: "kalshi",
                balance: 40,
                disabled: true,
                disabledReason: "Complete Kalshi withdrawals on the Kalshi website.",
              },
            ]}
            onSelectVenue={(venue) => console.log("withdraw venue", venue)}
            onSelectWithdrawMethod={(venue, method) =>
              console.log("withdraw method", venue, method)
            }
          />
        </>
      );
    }
    ```

    Fetch deposit addresses, execution balances, and withdrawal requests through the Execution API
    separately, then pass the resulting state into your UI.
  </Tab>
</Tabs>

***

## Withdrawals

Withdraw USDC to any external address.

```typescript theme={null}
type WithdrawResponse = {
  sources: Array<{
    chainId: number;
    amountRaw: string;
    txHash?: string;
  }>;
};

const result = await client.request<WithdrawResponse>("/execution/withdraw", {
  method: "POST",
  body: JSON.stringify({
    amountRaw: "50000000",         // 50 USDC (6 decimals)
    tokenSymbol: "USDC",
    destinationAddress: "0x...",   // External wallet address
    destinationChainId: 137,       // Optional preferred destination chain
  }),
});

// result.sources — which chains the funds came from
for (const source of result.sources) {
  console.log(`${source.amountRaw} from chain ${source.chainId}`);
  if (source.txHash) console.log(`  tx: ${source.txHash}`);
}
```

***

## Supported chains

The `supportedChains` array in the deposit response tells you exactly which chains and tokens
are available. Common chains include:

| Chain            | Use                  |
| ---------------- | -------------------- |
| Polygon (137)    | Polymarket trading   |
| Arbitrum (42161) | Low-fee deposits     |
| Ethereum (1)     | High-value deposits  |
| Solana           | Solana-native venues |

<Info>Users can deposit on any supported chain listed in the deposit-address response.</Info>

## Related execution endpoints

* `GET /execution/balances` for managed cash balances and venue position balances.
* `GET /execution/positions` for paginated open positions grouped by matched market.
* `GET /execution/orders` for paginated execution activity.

## Deposit detection

Deposits appear automatically after on-chain confirmation. There is no separate partner-side
confirmation step before the balance becomes visible in `GET /execution/balances`.

For faster UI feedback after a deposit, call `POST /execution/sync-balances` to trigger an
immediate on-chain balance refresh.

## Keep a target-chain balance funded

Use [Managed Balance Refills](/recipes/managed-balance-refills) when a user wants AGG to maintain a
USDC minimum on a selected chain after trading.
