> ## Documentation Index
> Fetch the complete documentation index at: https://raveculture-mintlify-gateway-config-docs-1774365568.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Wallet API

> Manage wallets for on-chain transactions and payments

# Wallet API

Manage wallets for on-chain transactions and payments. Supports session-based wallets, Coinbase Developer Platform (CDP) wallets, and Tempo network balance queries.

## Get wallet

```http theme={"dark"}
GET /api/wallet
```

Returns wallet information. Behavior depends on whether an `address` query parameter is provided and on your server configuration.

### Tempo balance query

When the `address` query parameter is present, the endpoint queries the Tempo blockchain for the wallet's balance and fee token information.

```http theme={"dark"}
GET /api/wallet?address=0xd8fd...db56f
```

#### Query parameters

| Parameter | Type   | Required | Description                              |
| --------- | ------ | -------- | ---------------------------------------- |
| `address` | string | Yes      | Hex-encoded wallet address (0x-prefixed) |

#### Response

```json theme={"dark"}
{
  "address": "0xd8fd0e1dce89beaab924ac68098ddb17613db56f",
  "chain": "Tempo",
  "chainId": 4217,
  "testnet": false,
  "feeToken": {
    "address": "0x20c0000000000000000000000000000000000000",
    "balance": "12.470000",
    "balanceRaw": "12470000"
  },
  "pathUsd": {
    "address": "0x20c0000000000000000000000000000000000000",
    "balance": "12.470000",
    "balanceRaw": "12470000"
  }
}
```

#### Response fields

| Field                 | Type    | Description                                         |
| --------------------- | ------- | --------------------------------------------------- |
| `address`             | string  | The queried wallet address                          |
| `chain`               | string  | Network name (`Tempo` or `Tempo Testnet`)           |
| `chainId`             | number  | Chain ID (`4217` for mainnet, `42431` for testnet)  |
| `testnet`             | boolean | Whether the server is configured for testnet        |
| `feeToken.address`    | string  | Contract address of the user's configured fee token |
| `feeToken.balance`    | string  | Fee token balance formatted with 6 decimals         |
| `feeToken.balanceRaw` | string  | Fee token balance in raw units                      |
| `pathUsd.address`     | string  | pathUSD contract address                            |
| `pathUsd.balance`     | string  | pathUSD balance formatted with 6 decimals           |
| `pathUsd.balanceRaw`  | string  | pathUSD balance in raw units                        |

<Note>Balance values are formatted to 6 decimal places. pathUSD uses 6 decimals, not 18. The network is determined server-side by the `TEMPO_TESTNET` environment variable.</Note>

#### Errors

| Code | Description                                |
| ---- | ------------------------------------------ |
| 400  | Missing `address` parameter                |
| 500  | Failed to fetch wallet data from Tempo RPC |

### CDP / session wallet query

When no `address` parameter is provided, the endpoint returns CDP or session-based wallet information. When CDP is configured, returns CDP status without authentication. Otherwise, requires session authentication.

#### Response (CDP configured)

```json theme={"dark"}
{
  "agenticWallet": {
    "status": "configured",
    "projectId": "abc12345...",
    "features": [
      "create_wallet",
      "get_balance",
      "send_usdc",
      "trade_tokens",
      "x402_payments"
    ]
  },
  "instructions": "CDP Agentic Wallet is configured. Use /api/wallet/cdp/* endpoints."
}
```

#### Response (user wallet exists)

```json theme={"dark"}
{
  "address": "0x...",
  "balance": "0",
  "network": "base-sepolia",
  "hasWallet": true,
  "createdAt": "2026-03-01T00:00:00Z"
}
```

#### Response (no wallet)

```json theme={"dark"}
{
  "address": null,
  "balance": "0",
  "network": "base-sepolia",
  "hasWallet": false,
  "message": "No wallet found. Create one to get started."
}
```

#### Errors

| Code | Description                                      |
| ---- | ------------------------------------------------ |
| 401  | Unauthorized (no session and CDP not configured) |

## Wallet actions

```http theme={"dark"}
POST /api/wallet
```

Requires session authentication.

### Request body

| Field    | Type   | Required | Description                                 |
| -------- | ------ | -------- | ------------------------------------------- |
| `action` | string | Yes      | One of: `create`, `get_seed`, `export_seed` |

### Action: `create`

Creates a new wallet for the authenticated user.

```json theme={"dark"}
{
  "address": "0x...",
  "network": "base-sepolia",
  "message": "Wallet created successfully"
}
```

Returns `400` if a wallet already exists.

### Action: `get_seed`

Returns wallet metadata. Private keys are stored encrypted server-side and are never exposed.

```json theme={"dark"}
{
  "address": "0x...",
  "network": "base-sepolia",
  "createdAt": "2026-03-01T00:00:00Z",
  "warning": "Private keys are stored encrypted server-side and never exposed."
}
```

### Action: `export_seed`

Seed export is disabled for security. Returns `403`.

```json theme={"dark"}
{
  "error": "Seed export is disabled for security. Contact support if you need your private key."
}
```

### Errors

| Code | Description                             |
| ---- | --------------------------------------- |
| 400  | Invalid action or wallet already exists |
| 401  | Unauthorized                            |
| 404  | No wallet found (for `get_seed`)        |

## Get CDP wallet address

```http theme={"dark"}
GET /api/wallet/address
```

Returns the address of the CDP Agentic Wallet.

### Response (authenticated)

```json theme={"dark"}
{
  "authenticated": true,
  "address": "0x..."
}
```

### Response (not authenticated)

When the CDP wallet address cannot be retrieved, the response includes `authenticated: false` and `needsAuth: true`. The remaining fields vary by failure reason:

```json theme={"dark"}
{
  "authenticated": false,
  "needsAuth": true,
  "message": "Run: npx awal auth login your@email.com"
}
```

If the failure is caused by a configuration error, the response includes `error` and `setup` fields instead of `message`:

```json theme={"dark"}
{
  "authenticated": false,
  "needsAuth": true,
  "error": "Error description",
  "setup": "Install: npx skills add coinbase/agentic-wallet-skills"
}
```

## Create CDP wallet

```http theme={"dark"}
POST /api/wallet/create
```

Creates a new wallet using the Coinbase Developer Platform SDK.

### Request body

| Field   | Type   | Required | Description                           |
| ------- | ------ | -------- | ------------------------------------- |
| `email` | string | Yes      | Email address for wallet registration |

### Response

```json theme={"dark"}
{
  "success": true,
  "walletAddress": "0x...",
  "walletId": "wallet_789",
  "networks": ["base-sepolia", "base"]
}
```

### Errors

| Code | Description                                                                                                                                             |
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400  | Email required                                                                                                                                          |
| 500  | CDP not configured. Response includes a `setup` field with configuration instructions. Generic errors include a `details` field with the error message. |

## CDP wallet status

```http theme={"dark"}
GET /api/wallet/cdp
```

Returns supported chain information for the CDP wallet.

```json theme={"dark"}
{
  "status": "ok",
  "type": "evm_wallet",
  "supportedChains": ["base", "base-sepolia"]
}
```

## Create CDP wallet client

```http theme={"dark"}
POST /api/wallet/cdp
```

Creates a viem wallet client on Base Sepolia.

### Request body

| Field        | Type   | Required | Description                                                   |
| ------------ | ------ | -------- | ------------------------------------------------------------- |
| `privateKey` | string | No       | Private key (0x-prefixed). A new key is generated if omitted. |

### Response

```json theme={"dark"}
{
  "success": true,
  "address": "0x...",
  "network": "base-sepolia"
}
```

## USDC transfer validation

When transferring USDC through the wallet service, the following validation rules apply:

* The transfer amount must be a positive finite number. Values such as `NaN`, `Infinity`, negative numbers, and zero are rejected.
* Amounts are rounded to 6 decimal places (USDC precision). If the rounded value equals zero, the transfer is rejected.

These checks run before any on-chain transaction is initiated.

<Note>When payments are initiated through the [x402 pay action](/api-reference/x402#pay), additional protections apply: a per-payment maximum of \$100, recipient address format validation (EVM or Solana), and audit logging of every payment attempt. See the [x402 gateway reference](/api-reference/x402) for details.</Note>

## Wallet top-up

Fund your wallet via Stripe checkout to credit your payment session balance.

### Create checkout session

```http theme={"dark"}
GET /api/wallet/top-up?amount=1000
```

Creates a Stripe checkout session for wallet top-up. Requires session authentication.

#### Query parameters

| Parameter | Type   | Required | Default | Description                                                                          |
| --------- | ------ | -------- | ------- | ------------------------------------------------------------------------------------ |
| `amount`  | number | No       | `1000`  | Amount in cents. Valid values: `500` ($5), `1000` ($10), `2500` ($25), `5000` ($50). |

#### Response

```json theme={"dark"}
{
  "url": "https://checkout.stripe.com/...",
  "sessionId": "cs_live_..."
}
```

| Field       | Type   | Description                                                      |
| ----------- | ------ | ---------------------------------------------------------------- |
| `url`       | string | Stripe checkout URL. Redirect the user here to complete payment. |
| `sessionId` | string | Stripe checkout session ID                                       |

#### Errors

| Code | Description                                                    |
| ---- | -------------------------------------------------------------- |
| 400  | Invalid amount. Must be one of: 500, 1000, 2500, 5000 (cents). |
| 401  | Unauthorized — session authentication required                 |
| 500  | Stripe not configured or failed to create checkout session     |

### Stripe webhook

```http theme={"dark"}
POST /api/wallet/top-up
```

Handles the Stripe `checkout.session.completed` webhook to credit the user's wallet after payment. This endpoint verifies the Stripe webhook signature before processing.

<Note>This endpoint is called by Stripe, not by your application. Configure your Stripe webhook to point to this URL with the `checkout.session.completed` event.</Note>

#### Errors

| Code | Description                                        |
| ---- | -------------------------------------------------- |
| 400  | Invalid Stripe webhook signature                   |
| 500  | Stripe not configured or webhook processing failed |

## MPP payment sessions

Payment sessions enable off-chain, per-call billing for agent requests. Instead of settling every call on-chain, you deposit funds into a session and sign lightweight vouchers that are batched and settled periodically.

When you send a request to the [gateway](/api-reference/gateway) with `X-Session-Id` and `X-Wallet-Address` headers, the gateway auto-debits your session balance and returns the updated balance in the `X-Session-Remaining` response header.

See [MPP payments — sessions](/payments/mpp#sessions) for the full protocol description.

### List sessions

```http theme={"dark"}
GET /api/wallet/sessions?address=0x...
```

Returns all sessions (active and closed) for the given wallet address.

#### Query parameters

| Parameter | Type   | Required | Description                              |
| --------- | ------ | -------- | ---------------------------------------- |
| `address` | string | Yes      | Hex-encoded wallet address (0x-prefixed) |

#### Response

```json theme={"dark"}
{
  "sessions": [
    {
      "id": "ses_a1b2c3d4e5f6...",
      "userAddress": "0x...",
      "deposit": "10.00",
      "spent": "1.25",
      "remaining": "8.75",
      "vouchers": [],
      "status": "active",
      "createdAt": 1742472000000,
      "lastSettledAt": 1742472000000
    }
  ]
}
```

### Get session

```http theme={"dark"}
GET /api/wallet/sessions?sessionId=ses_...
```

Returns a single session by ID.

#### Query parameters

| Parameter   | Type   | Required | Description                       |
| ----------- | ------ | -------- | --------------------------------- |
| `sessionId` | string | Yes      | Session ID (prefixed with `ses_`) |

#### Response

```json theme={"dark"}
{
  "session": {
    "id": "ses_a1b2c3d4e5f6...",
    "userAddress": "0x...",
    "deposit": "10.00",
    "spent": "1.25",
    "remaining": "8.75",
    "vouchers": [],
    "status": "active",
    "createdAt": 1742472000000,
    "lastSettledAt": 1742472000000
  }
}
```

#### Errors

| Code | Description                                |
| ---- | ------------------------------------------ |
| 400  | Missing `address` or `sessionId` parameter |
| 404  | Session not found                          |

### Session fields

| Field           | Type   | Description                                         |
| --------------- | ------ | --------------------------------------------------- |
| `id`            | string | Unique session ID (`ses_` prefix)                   |
| `userAddress`   | string | Wallet address that owns the session                |
| `deposit`       | string | Total deposited amount in USD                       |
| `spent`         | string | Total spent via vouchers in USD                     |
| `remaining`     | string | Remaining balance in USD                            |
| `vouchers`      | array  | Pending vouchers not yet settled on-chain           |
| `status`        | string | One of `active`, `settling`, or `closed`            |
| `createdAt`     | number | Unix timestamp (ms) when the session was created    |
| `lastSettledAt` | number | Unix timestamp (ms) of the last on-chain settlement |

### Create session

```http theme={"dark"}
POST /api/wallet/sessions
```

Opens a new payment session. If the wallet already has an active session, the existing session is returned instead.

#### Request body

| Field     | Type   | Required | Description                                              |
| --------- | ------ | -------- | -------------------------------------------------------- |
| `address` | string | Yes      | Hex-encoded wallet address (0x-prefixed)                 |
| `deposit` | string | Yes      | Deposit amount in USD (minimum `1.00`, maximum `100.00`) |

#### Response (201 Created)

```json theme={"dark"}
{
  "session": {
    "id": "ses_a1b2c3d4e5f6...",
    "userAddress": "0x...",
    "deposit": "10.00",
    "spent": "0.00",
    "remaining": "10.00",
    "vouchers": [],
    "status": "active",
    "createdAt": 1742472000000,
    "lastSettledAt": 1742472000000
  }
}
```

#### Response (existing session)

```json theme={"dark"}
{
  "session": { ... },
  "note": "Active session already exists"
}
```

#### Errors

| Code | Description                                                                     |
| ---- | ------------------------------------------------------------------------------- |
| 400  | Missing `address` or `deposit`, deposit below minimum, or deposit above maximum |

### Close session

```http theme={"dark"}
DELETE /api/wallet/sessions?sessionId=ses_...
```

Closes an active session. Any pending vouchers are settled on-chain first, and the remaining balance is returned to the user.

#### Query parameters

| Parameter   | Type   | Required | Description         |
| ----------- | ------ | -------- | ------------------- |
| `sessionId` | string | Yes      | Session ID to close |

#### Response

```json theme={"dark"}
{
  "success": true,
  "returned": "8.75"
}
```

| Field      | Type    | Description                        |
| ---------- | ------- | ---------------------------------- |
| `success`  | boolean | Whether the session was closed     |
| `returned` | string  | Amount in USD returned to the user |

#### Errors

| Code | Description                                         |
| ---- | --------------------------------------------------- |
| 400  | Missing `sessionId`, or session could not be closed |

### Submit voucher

```http theme={"dark"}
POST /api/wallet/sessions/voucher
```

Submits a signed voucher to debit the session balance off-chain. This is the primary billing mechanism during an active session — each agent call produces one voucher.

#### Request body

| Field         | Type   | Required | Description                                                      |
| ------------- | ------ | -------- | ---------------------------------------------------------------- |
| `sessionId`   | string | Yes      | Active session ID                                                |
| `userAddress` | string | Yes      | Wallet address that owns the session (0x-prefixed)               |
| `plugin`      | string | Yes      | Plugin identifier (e.g., `agent`, `generate-text`, `tts`, `stt`) |
| `signature`   | string | Yes      | User's hex-encoded signature (0x-prefixed)                       |
| `nonce`       | string | Yes      | Unique nonce for this voucher                                    |

The voucher amount is determined automatically from the plugin's pricing. See [plugin pricing](/payments/mpp#plugin-pricing) for current rates.

#### Response

```json theme={"dark"}
{
  "success": true,
  "session": {
    "id": "ses_a1b2c3d4e5f6...",
    "spent": "0.05",
    "remaining": "9.95",
    "pendingVouchers": 1
  },
  "voucher": {
    "amount": "0.05",
    "plugin": "agent",
    "description": "Agent orchestrator request"
  }
}
```

#### Response fields

| Field                     | Type   | Description                                    |
| ------------------------- | ------ | ---------------------------------------------- |
| `session.id`              | string | Session ID                                     |
| `session.spent`           | string | Updated total spent in USD                     |
| `session.remaining`       | string | Updated remaining balance in USD               |
| `session.pendingVouchers` | number | Number of vouchers pending on-chain settlement |
| `voucher.amount`          | string | Amount debited for this call in USD            |
| `voucher.plugin`          | string | Plugin that was called                         |
| `voucher.description`     | string | Human-readable description of the charge       |

#### Errors

| Code | Description                                                                                                               |
| ---- | ------------------------------------------------------------------------------------------------------------------------- |
| 400  | Missing required fields, unknown plugin, session not found, session not active, address mismatch, or insufficient balance |
| 500  | Internal error processing the voucher                                                                                     |
