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

# Wallet Funding

> USDC wallet funding for cards on the Rain + Coinbase rail

<Info>
  **Effective from the Rain + Coinbase launch.** AgentCard is migrating its
  issuing rail from a card-on-file model to **Rain** — stablecoin-collateralized
  Visa cards funded by a per-user non-custodial **Coinbase CDP wallet** holding
  USDC on Base. Until launch, cards continue to be funded by the cardholder's
  saved payment method.
</Info>

From launch, every user has a USDC wallet. USDC arriving in the wallet is
**automatically deposited on-chain into the user's Rain collateral contract**,
and **card spending power equals that deposited collateral** — it updates
within minutes of funds landing in the wallet. The wallet itself is a
pass-through: in steady state its balance is \~0 because deposits sweep to
Rain, where they back card authorizations.

If you try to create a card while a deposit is still confirming, the API
returns `deposit_confirming` with a retry hint (typically under a couple of
minutes) — the money is on the way; don't ask the user to pay again.

A user can hold **multiple wallets**; exactly one is the **primary** — the
wallet registered with Rain whose deposits back card issuance. Cards aren't
tied to a wallet, so switching the primary just re-registers the new address
with Rain and new deposits flow through the new primary.

## What changes at launch

One-time cutover:

* All existing cards on the previous rail are cancelled. Uncaptured holds are released — **no money is taken**. Monthly card quotas reset, and affected users are emailed.
* Every user must complete (re-)KYC via **Rain's consumer application** before their first new card (this replaces the previous identity verification flow).

Deprecated at launch, removed \~30 days later:

* Payment-method-on-file endpoints (`/api/v1/cardholders/:id/payment-method/*`) — see [Attach a payment method](/api-reference/cardholders/setup-payment-method)
* The approvals flow and `202` approval responses
* Test mode (`sk_test_*` keys)

Unchanged — no integration changes needed:

* The card object shape: `id`, `last4`, `expiry` (`MM/YY`), `balanceCents`, `spendLimitCents`, `status`
* [Get Card Details](/api-reference/cards/get-details) still returns the full PAN/CVV. Credentials are now fetched from the issuer on demand and never stored at rest — a security improvement.
* Webhook event names (`card.created`, `transaction.authorized`, `card.cancelled`, …)
* API key authentication for B2B

Stripe remains in use **only** for subscription/plan billing. Order-confirm
flows no longer capture PaymentIntents for Rain cards — settlement is automatic
on the card rail, and markup is invoiced via the organization's billing
subscription.

## Funding the wallet

Two ways to add USDC:

1. **Fiat onramp (default)** — Coinbase Onramp guest checkout via **Apple Pay or Google Pay**. US-only, with Coinbase guest limits: roughly 15 lifetime / 10 daily transactions per guest, **$2–$10,000** per transaction, and US non-VoIP phone verification (re-verified via OTP every 60 days).
2. **Direct USDC transfer** — send USDC to the wallet's address on Base.

## Endpoints

These endpoints authenticate with the **user's JWT** (the wallet belongs to the
end user), and ship ahead of launch.

### `GET /wallet`

Returns the caller's **primary** wallet (as `wallet`) plus all wallets
(`wallets`), each with a live USDC balance.

```json 200 theme={null}
{
  "wallet": {
    "address": "0xAbC123...",
    "chain": "base",
    "stablecoin": "USDC",
    "balanceUsdc": "25.00",
    "collateralContract": "0xDeF456...",
    "status": "active"
  },
  "wallets": [
    {
      "id": "wal_abc123",
      "address": "0xAbC123...",
      "chain": "base",
      "stablecoin": "USDC",
      "balanceUsdc": "25.00",
      "collateralContract": "0xDeF456...",
      "status": "active",
      "isPrimary": true
    }
  ]
}
```

If the live balance read fails temporarily, the endpoint still returns `200`
with `"balanceUsdc": "0"` and `"balanceUnavailable": true`. Returns
`404 no_wallet` when no wallet has been provisioned yet.

### `POST /wallet/provision`

Idempotently provisions the caller's primary CDP wallet. Returns the same
`{ "wallet": { ... } }` shape. Returns `503 wallet_provider_not_configured`
when wallet provisioning is not enabled on the environment.

### `POST /wallet/additional`

Provisions an extra (non-primary) wallet. Additional wallets can receive USDC,
but only the primary backs card issuance. Returns `{ "wallet": { ... } }` in
the per-wallet shape of the `wallets` list (with `id` and `isPrimary: false`).

### `POST /wallet/primary`

Makes one of the caller's wallets the primary and re-registers its address
with Rain (the collateral contract follows the new primary).

```json Request theme={null}
{ "wallet_id": "wal_abc123" }
```

Returns `200 { "wallet": { ... } }` (the new primary). If Rain re-registration
fails transiently the switch still happens locally and the response carries
`"rainRegistrationFailed": true`. Returns `404 wallet_not_found` for a wallet
that doesn't exist or isn't yours.

### `POST /onramp/sessions`

Creates a Coinbase Onramp guest-checkout order delivering USDC to the caller's
wallet.

```json Request theme={null}
{
  "amount_cents": 5000,
  "payment_method": "apple_pay"
}
```

`amount_cents` must be between 200 and 1000000 ($2–$10,000);
`payment_method` is `apple_pay` or `google_pay`.

```json 200 theme={null}
{
  "session": {
    "id": "onr_abc123",
    "status": "pending",
    "fiatAmountCents": 5000,
    "paymentMethod": "apple_pay"
  },
  "payment": {
    "checkoutUrl": "https://pay.coinbase.com/..."
  }
}
```

Open `checkoutUrl` in a browser to pay. Errors: `404 no_wallet`,
`422 amount_out_of_range`, `422 phone_verification_required`,
`422 guest_region_blocked` (US-only; includes `failure_code`),
`502 onramp_provider_error`, `503 onramp_not_configured`.

### `GET /onramp/sessions/:id`

Poll a session to track delivery of funds.

```json 200 theme={null}
{
  "session": {
    "id": "onr_abc123",
    "status": "completed",
    "fiatAmountCents": 5000,
    "fiatCurrency": "USD",
    "usdcAmount": "49.50",
    "feesCents": 50,
    "paymentMethod": "apple_pay",
    "failureCode": null,
    "completedAt": "2026-06-10T12:05:00.000Z",
    "createdAt": "2026-06-10T12:00:00.000Z"
  }
}
```

## KYC (Rain consumer application)

Card issuance on the Rain rail requires an **approved Rain consumer
application**. Until KYC is approved, card creation returns:

```json 422 theme={null}
{
  "error": "kyc_required",
  "message": "This cardholder must complete identity verification (KYC) before creating a card."
}
```

The consumer identity flow (`submit_user_info` MCP tool / CLI prompts) gains
two **optional** fields that feed the Rain application: `occupation` (SOC code
or free text) and `account_purpose`. Integrations that don't send them keep
working.

## Card creation errors

When the wallet can't back a requested card, `POST /api/v1/cards` returns:

```json 422 (wallet_funding_required) theme={null}
{
  "error": "wallet_funding_required",
  "required_cents": 2500,
  "available_cents": 1000,
  "message": "The wallet needs $15.00 more USDC to create this card."
}
```

```json 503 (wallet_balance_unavailable) theme={null}
{
  "error": "wallet_balance_unavailable"
}
```

`wallet_balance_unavailable` means the wallet's balance could not be read
(temporary provider/RPC issue) — retry shortly. See
[Error Codes](/api-reference/errors) for the full list.

## MCP tools and CLI

For agents connected via MCP, two tools cover the wallet:

* `get_wallet` — wallet address, chain, and USDC balance (provisions the wallet on first use)
* `fund_wallet` — creates an onramp session and returns the checkout URL

From the CLI: `agent-cards wallet` (show / provision) and
`agent-cards wallet fund --amount <dollars>`.
