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

# Bitcoin wallets

> Register watch-only Bitcoin wallets for your agents and query addresses, balances, and transactions

# Bitcoin wallets

The Bitcoin wallets API lets you register watch-only Bitcoin wallets for your agents, generate receive addresses, check balances, and view transaction history. Wallets are backed by NBXplorer and derivation schemes are encrypted at rest.

<Info>The Bitcoin wallet backend operates on **mainnet**. All addresses, balances, and transactions returned by these endpoints are for the Bitcoin mainnet network.</Info>

<Note>All Bitcoin wallet endpoints require an authenticated session. The frontend proxies requests to the backend with a 10-second timeout. If the Bitcoin backend (NBXplorer) is unreachable, affected endpoints return `502`.</Note>

<Note>The web proxy endpoints documented on this page forward requests to the backend's Underground router. The backend-direct paths are mounted at `/api/underground/bitcoin/...` and use bearer token authentication instead of session authentication. See [Underground API — Bitcoin wallet endpoints](/api-reference/underground#bitcoin-wallet-endpoints) for the backend-direct paths.</Note>

## Authentication

Bitcoin wallet endpoints use two layers of authorization:

1. **Session authentication** — a valid NextAuth session is required. The frontend extracts `session.user.id` and `session.user.email` before proxying the request.
2. **Bearer token** — the frontend attaches the `INTERNAL_API_KEY` as a bearer token when forwarding to the backend. The backend verifies this token using a timing-safe comparison.

User identity headers (`x-user-id`, `x-user-email`) are set by the frontend after session verification and are trusted by the backend. All wallet queries are scoped to the authenticated user.

## Get backend info

```http theme={"dark"}
GET /api/bitcoin/backend/info
```

Returns the status of the Bitcoin backend (NBXplorer). Use this to verify the Bitcoin infrastructure is online before performing wallet operations.

### Response

```json theme={"dark"}
{
  "cryptoCode": "BTC",
  "isFullySynched": true,
  "chainHeight": 895012,
  "networkType": "Mainnet",
  "version": "2.6.2",
  "bitcoinStatus": {
    "blocks": 895012,
    "headers": 895012,
    "verificationProgress": 0.9999,
    "isSynched": true
  }
}
```

| Field                                | Type    | Description                                                              |
| ------------------------------------ | ------- | ------------------------------------------------------------------------ |
| `cryptoCode`                         | string  | The tracked cryptocurrency code (always `"BTC"`)                         |
| `isFullySynched`                     | boolean | Whether the NBXplorer indexer has finished syncing with the Bitcoin node |
| `chainHeight`                        | number  | Current block height tracked by NBXplorer                                |
| `networkType`                        | string  | Network the backend operates on (for example `"Mainnet"` or `"Testnet"`) |
| `version`                            | string  | NBXplorer version string                                                 |
| `bitcoinStatus`                      | object  | Detailed sync state from the connected Bitcoin node                      |
| `bitcoinStatus.blocks`               | number  | Number of fully validated blocks                                         |
| `bitcoinStatus.headers`              | number  | Number of block headers received                                         |
| `bitcoinStatus.verificationProgress` | number  | Fraction of chain verified, where `1.0` means fully synced               |
| `bitcoinStatus.isSynched`            | boolean | Whether the Bitcoin node considers itself synced                         |

The response is a passthrough from the NBXplorer status endpoint and may include additional fields depending on the NBXplorer version.

### Errors

| Code | Description                                         |
| ---- | --------------------------------------------------- |
| 401  | Unauthorized — missing or invalid session           |
| 502  | Bitcoin backend is unreachable or returned an error |

## List wallets

```http theme={"dark"}
GET /api/bitcoin/wallets
```

Returns all Bitcoin wallets belonging to the authenticated user, ordered by creation date (newest first).

### Response

```json theme={"dark"}
[
  {
    "id": 1,
    "agentId": "agent_7",
    "label": "Primary",
    "network": "btc",
    "createdAt": "2026-01-01T00:00:00Z"
  }
]
```

| Field       | Type           | Description                           |
| ----------- | -------------- | ------------------------------------- |
| `id`        | number         | Wallet identifier                     |
| `agentId`   | string         | Agent associated with this wallet     |
| `label`     | string \| null | Human-readable wallet label           |
| `network`   | string         | Always `"btc"`                        |
| `createdAt` | string         | ISO 8601 timestamp of wallet creation |

### Errors

| Code | Description                                                        |
| ---- | ------------------------------------------------------------------ |
| 401  | Unauthorized — missing or invalid session, or missing user context |
| 500  | Failed to list wallets                                             |

## Register a watch-only wallet

```http theme={"dark"}
POST /api/bitcoin/wallets
```

Registers a new watch-only Bitcoin wallet for an agent. The derivation scheme (xpub) is validated against NBXplorer and then AES-encrypted before storage.

<Warning>You must own the agent specified by `agentId`. The frontend verifies agent ownership before forwarding the request to the backend.</Warning>

### Request body

| Field              | Type   | Required | Description                                                                                           |
| ------------------ | ------ | -------- | ----------------------------------------------------------------------------------------------------- |
| `agentId`          | string | Yes      | The agent to associate this wallet with. Must be owned by the authenticated user.                     |
| `derivationScheme` | string | Yes      | The xpub or derivation scheme for the wallet (for example, `"xpub6CUGRU..."`). Whitespace is trimmed. |
| `label`            | string | No       | A human-readable label for the wallet. Defaults to `null`.                                            |

### Response (201 Created)

```json theme={"dark"}
{
  "id": 1,
  "agentId": "agent_7",
  "label": "Primary",
  "network": "btc"
}
```

| Field     | Type           | Description                       |
| --------- | -------------- | --------------------------------- |
| `id`      | number         | Wallet identifier                 |
| `agentId` | string         | Agent associated with this wallet |
| `label`   | string \| null | Wallet label                      |
| `network` | string         | Always `"btc"`                    |

### Errors

| Code | Description                                             |
| ---- | ------------------------------------------------------- |
| 400  | `agentId` is missing or not a string                    |
| 400  | `derivationScheme` is missing or empty                  |
| 401  | Unauthorized — missing or invalid session               |
| 403  | The authenticated user does not own the specified agent |
| 500  | Failed to register wallet — NBXplorer or database error |

## Get unused address

```http theme={"dark"}
GET /api/bitcoin/wallets/{walletId}/address
```

Returns an unused receive address for the specified wallet. Use this to generate a fresh address for incoming payments.

<Note>The web proxy path is `/api/bitcoin/wallets/{walletId}/address`. Internally, this forwards to the backend's `/api/underground/bitcoin/wallets/{walletId}/address/unused` endpoint.</Note>

### Path parameters

| Parameter  | Type   | Description                                                   |
| ---------- | ------ | ------------------------------------------------------------- |
| `walletId` | string | The wallet's numeric identifier, passed as a URL path segment |

<Note>The `walletId` must be a positive integer. It is passed as a string in the URL and validated by the backend.</Note>

### Response

```json theme={"dark"}
{
  "address": "bc1qexample..."
}
```

The response is a passthrough from NBXplorer and may include additional fields.

### Errors

| Code | Description                                             |
| ---- | ------------------------------------------------------- |
| 400  | `walletId` is not a positive integer                    |
| 401  | Unauthorized — missing or invalid session               |
| 404  | Wallet not found or not owned by the authenticated user |
| 502  | Failed to derive address — NBXplorer error              |

## Get wallet balance

```http theme={"dark"}
GET /api/bitcoin/wallets/{walletId}/balance
```

Returns the balance for the specified wallet.

### Path parameters

| Parameter  | Type   | Description                                                   |
| ---------- | ------ | ------------------------------------------------------------- |
| `walletId` | string | The wallet's numeric identifier, passed as a URL path segment |

### Response

```json theme={"dark"}
{
  "confirmed": "0.1",
  "unconfirmed": "0.0",
  "available": "0.1",
  "immature": "0.0",
  "total": "0.1"
}
```

| Field         | Type                | Description                          |
| ------------- | ------------------- | ------------------------------------ |
| `confirmed`   | string \| undefined | Confirmed balance in BTC             |
| `unconfirmed` | string \| undefined | Unconfirmed (pending) balance in BTC |
| `available`   | string \| undefined | Available (spendable) balance in BTC |
| `immature`    | string \| undefined | Immature coinbase balance in BTC     |
| `total`       | string \| undefined | Total balance in BTC                 |

<Note>All balance fields are optional strings. A field may be absent if NBXplorer does not return it for the given wallet state.</Note>

### Errors

| Code | Description                                             |
| ---- | ------------------------------------------------------- |
| 400  | `walletId` is not a positive integer                    |
| 401  | Unauthorized — missing or invalid session               |
| 404  | Wallet not found or not owned by the authenticated user |
| 502  | Failed to fetch balance — NBXplorer error               |

## Get wallet transactions

```http theme={"dark"}
GET /api/bitcoin/wallets/{walletId}/transactions
```

Returns the transaction history for the specified wallet.

### Path parameters

| Parameter  | Type   | Description                                                   |
| ---------- | ------ | ------------------------------------------------------------- |
| `walletId` | string | The wallet's numeric identifier, passed as a URL path segment |

### Response

```json theme={"dark"}
{
  "transactions": []
}
```

The response is a passthrough from NBXplorer. The `transactions` array contains transaction objects with details such as transaction ID, amounts, confirmations, and timestamps.

### Errors

| Code | Description                                             |
| ---- | ------------------------------------------------------- |
| 400  | `walletId` is not a positive integer                    |
| 401  | Unauthorized — missing or invalid session               |
| 404  | Wallet not found or not owned by the authenticated user |
| 502  | Failed to fetch transactions — NBXplorer error          |

## Identity model

All user and agent identifiers are strings. The `agentId` field uses the format `"agent_<id>"` and `userId` uses `"user_<id>"`. Wallet `id` values are numeric integers assigned by the database.

Wallet lookups are always scoped by the authenticated user's ID, so users cannot access wallets belonging to other users.

## Liquid network and LWK

The Bitcoin wallets API operates on Bitcoin mainnet via NBXplorer. For Liquid network support, the platform runs a pruned Elements (Liquid) node and exposes a read-only status endpoint. See the [Liquid network API reference](/api-reference/liquid) for full details.

There are two distinct options for Liquid infrastructure:

* **Lightweight LWK path** — deploy the Liquid Wallet Kit as a standalone service. LWK connects to Blockstream's Electrum server and does not require a full Liquid node. This is suitable for multi-sig wallets, Jade hardware wallet signing, and Liquid asset issuance.
* **Full Liquid node** — run your own validating Liquid infrastructure using Blockstream's [Elements Core setup guide](https://help.blockstream.com/hc/en-us/articles/900002026026-Set-up-a-Liquid-node). This gives you independent chain validation and optional Bitcoin-node-backed peg-in verification.

<Note>The Liquid node status endpoint (`GET /api/bitcoin/liquid`) is now live. LWK wallet integration remains a planned feature. The Bitcoin wallets API endpoints above serve Bitcoin mainnet only.</Note>
