# Funding a wallet

> Top up by card or bank, or send USDC on Base to a deposit address. Money is credited when the payment rail confirms it. Ask the gateway which options it offers before you choose one.

An agent **can't fund its own wallet**. Moving money in is always a person's action, in the console or through your own code on their behalf.

## Ask what's available first

Funding options depend on which payment providers the gateway has connected. Ask instead of guessing:

```bash
curl -s https://api.zanora.dev/v1/rail/providers -H "x-api-key: $WKEY"
```

```json
{
  "sandbox": false,
  "providers": [
    { "id": "stripe", "name": "Stripe", "roles": ["funding"], "currencies": ["USD"],
      "rails": ["card", "ach"], "topUps": true, "depositAddresses": false, "faucet": false, "status": "active" },
    { "id": "circle", "name": "Circle", "roles": ["funding", "payout"], "currencies": ["USDC"],
      "rails": ["usdc_base"], "topUps": false, "depositAddresses": true, "faucet": false, "status": "active" }
  ]
}
```

| Flag | Means | Use |
|---|---|---|
| `topUps: true` | you can charge a card or bank account into the wallet | [Top-up](#top-up-card-or-bank) |
| `depositAddresses: true` | you can get a USDC address for the wallet | [Deposit address](#usdc-deposit-address) |
| `faucet: true` | testnet only: free test USDC | [Testnet faucet](#testnet-faucet) |
| `sandbox: true` | a development gateway with mock rails | [Development shortcut](#development-shortcut) |

## Top-up (card or bank)

The console's **Fund** button is the easiest route: it takes a card and handles confirmation. From the API:

```bash
curl -s -X POST https://api.zanora.dev/v1/wallets/$WAL/topup -H "x-api-key: $WKEY" \
  -H 'content-type: application/json' -d '{"amountMinor":"2000"}'
# → {"intent":{"externalRef":"pi_…","asset":"USD","amountMinor":"2000","status":"requires_payment_method","hostedUrl":"…"}}
```

Finish the payment where the intent says: `hostedUrl` if present, or `clientSecret` for your own card form. The wallet is credited **when the card processor confirms**, not when this call returns. If the card is declined, `status` is `declined` with a `declineReason`. That's an answer, not an error.

## USDC deposit address

```bash
curl -s -X POST https://api.zanora.dev/v1/wallets/$WAL/deposit-address -H "x-api-key: $WKEY" \
  -H 'content-type: application/json' -d '{"asset":"USDC","chain":"base"}'
# → {"address":{"id":"…","walletId":"wal_…","treasuryProviderId":"circle","chain":"base","asset":"USDC","address":"0x5f3a…","createdAt":"…"}}
```

- Calling it again returns **the same address**, never a second one.
- Send **only USDC on Base** to it. Other tokens and chains aren't credited.
- The wallet is credited in USD at 1:1 once the transfer is confirmed.
- If USDC is trading more than **0.5% away from $1** when the deposit arrives, it's **held**, not credited at a guessed rate. Zanora checks held deposits again automatically, and credits them once the price is back within the band.

`GET /v1/wallets/$WAL/deposit-addresses` lists a wallet's addresses. The `zanora_deposit_addresses` MCP tool reports them to an agent, so it can tell its user where to send money.

## Testnet faucet

On a testnet deployment where a provider reports `faucet: true`:

```bash
curl -s -X POST https://api.zanora.dev/v1/wallets/$WAL/faucet -H "x-api-key: $WKEY"
```

This sends real testnet USDC to the wallet's deposit address, and it's credited the same way as any deposit.

## Development shortcut

Only on a local or sandbox gateway (`sandbox: true`):

```bash
curl -s -X POST http://127.0.0.1:8080/v1/wallets/$WAL/fund -H "x-api-key: $WKEY" \
  -H 'content-type: application/json' -d '{"amountMinor":"5000","rail":"card"}'
```

It credits instantly against a simulated deposit. Anywhere with a real payment provider connected, including the hosted platform, it returns `501 NOT_SUPPORTED`.

## Checking it landed

```bash
curl -s https://api.zanora.dev/v1/wallets/$WAL/balance -H "x-api-key: $WKEY"
curl -s https://api.zanora.dev/v1/rail/transactions -H "x-api-key: $WKEY"   # each deposit and its state
```

A balance of zero right after you fund is normal. Card payments usually confirm within seconds and USDC within minutes.
