From 552b83893bd9a6b4e4abdb966701ab2216b9ebd9 Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Sat, 8 Aug 2026 19:29:14 -0700 Subject: [PATCH] docs: document control.wallet.coins, peak, coinById, broadcast Extends the existing control.wallet.balance page into a full control.wallet.* reference covering the four open chain reads (balance, coins, peak, coinById) and the one token-gated write (broadcast) that dig-node's control plane now serves. Generalizes the -32040..-32043 error-code descriptions in error-codes.md and their source in scripts/dig-spec.mjs, which previously named only control.wallet.balance, to cover every control.wallet.* method. Co-Authored-By: Claude --- docs/run-a-node/manage.md | 267 +++++++++++++++++++++++++++++++++++- docs/support/error-codes.md | 10 +- package.json | 2 +- scripts/dig-spec.mjs | 8 +- static/error-codes.json | 16 +-- 5 files changed, 281 insertions(+), 22 deletions(-) diff --git a/docs/run-a-node/manage.md b/docs/run-a-node/manage.md index 8c9f578..0207bb8 100644 --- a/docs/run-a-node/manage.md +++ b/docs/run-a-node/manage.md @@ -1,7 +1,7 @@ --- sidebar_position: 7 title: Manage your node -description: "Operate a running dig-node: the control.* admin RPCs (status, cache, peers) and the DIG Browser's My Node UI that drives them." +description: "Operate a running dig-node: the control.* admin RPCs (status, cache, peers, wallet chain reads) and the DIG Browser's My Node UI that drives them." keywords: - dig-node admin - control RPC @@ -25,6 +25,7 @@ The `control.*` namespace exposes operator actions that are **not** part of the - **status** — health, version, uptime, and the resolved listeners. - **cache** — inspect the `.dig` cache ([capsules](../concepts.md#capsule) held), and prune/evict. - **peers / upstream** — the upstream the node blind-fetches from and any peer state. +- **wallet** — read chain state for a public address or coin, and broadcast an already-signed spend ([below](#control-wallet-balance)). These are admin-scoped: a remote reader hitting the public dig RPC can never call them. @@ -34,9 +35,25 @@ After publishing a store with `digs commit`, seed your own node so it immediatel **Advanced — `DIG_NODE_PUSH_OPEN=true`** lets remote authorized writers push to your node; only a caller holding the store's publisher key can (a signed request signature is required), so it stays safe against cache-poisoning. Leave it off unless you intend to accept remote seed-pushes. -## `control.wallet.balance` — read a public address's balance {#control-wallet-balance} +## `control.wallet.*` — chain reads and broadcast {#control-wallet-balance} -`control.wallet.balance` returns the on-chain balance of any public address, in XCH or $DIG. Unlike the other `control.*` methods it is an **open read**: it needs only an address — no control token, no wallet seed, no signing key — because it reads a public address's balance from the chain. It is served on the node's loopback control plane. +`control.wallet.*` is the wallet-facing slice of the control plane. Five methods, all on the node's loopback control plane, all working with lowercase 64-hex, unprefixed hashes, and integer amounts in the asset's base unit (mojos for XCH): + +| Method | What it does | +|---|---| +| [`control.wallet.balance`](#control-wallet-balance) | Total balance of a public address. | +| [`control.wallet.coins`](#control-wallet-coins) | Unspent coins at a public address. | +| [`control.wallet.peak`](#control-wallet-peak) | The node's current chain peak height. | +| [`control.wallet.coinById`](#control-wallet-coinbyid) | A single coin by id, including a spent one. | +| [`control.wallet.broadcast`](#control-wallet-broadcast) | Push an already-signed spend bundle. | + +Four of the five need only public information — an address, or a coin id — so they are **open reads**: no control token, no wallet seed, no signing key. This means a person whose node runs as a service with a control-token file they can't read can still see their own money. `control.wallet.broadcast` is different: it puts bytes on the network, so it is the one wallet method that **requires a control token**, the same as the other admin `control.*` methods. + +None of the five wallet methods ever accept a key, a seed, or a mnemonic. The node never signs a spend — it only reads chain state and, for `broadcast`, accepts bytes somebody else already signed. + +### `control.wallet.balance` — read a public address's balance {#control-wallet-balance} + +`control.wallet.balance` returns the on-chain balance of any public address, in XCH or $DIG. It is an **open read**: it needs only an address — no control token, no wallet seed, no signing key — because it reads a public address's balance from the chain. **Request** @@ -75,7 +92,7 @@ After publishing a store with `digs commit`, seed your own node so it immediatel | `synced` | boolean | Whether **this answer** came from a fully synced local copy. A `"fallback"` answer is always `false`. | | `peak_height` | number \| null | The chain height **this answer** reflects, or `null` — including for every `"fallback"` answer. | -### Where the answer came from +#### Where the answer came from `source` tells you which of two places produced the figure: @@ -110,6 +127,248 @@ dig-node wallet balance xch1… --asset dig The CLI reaches the same loopback method and prints the returned figure. +### `control.wallet.coins` — read a public address's unspent coins {#control-wallet-coins} + +`control.wallet.coins` lists the **unspent** coins held by a public address, for one asset. It is an **open read** — only an address is needed. + +**Request** + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "control.wallet.coins", + "params": { "address": "xch1…", "asset": "xch" } +} +``` + +| Param | Type | Required | Meaning | +|---|---|---|---| +| `address` | string | yes | The bech32m address to read (e.g. `xch1…`). | +| `asset` | string | no | The asset to list coins for: `"xch"` (default) or `"dig"`. Omit for `"xch"`. | + +**Result** + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "coins": [ + { + "coin_id": "aa11…", + "asset": "xch", + "amount": 1000000000, + "parent_coin_info": "bb22…", + "puzzle_hash": "cc33…", + "created_height": 4200000, + "spent_height": null + } + ], + "source": "db", "synced": true, "peak_height": 4200042 + } +} +``` + +| Field | Type | Meaning | +|---|---|---| +| `coins` | array | The address's unspent coins for the requested asset (see the coin shape below). | +| `source` | string \| null | Which source answered — same meaning as [`control.wallet.balance`](#where-the-answer-came-from). | +| `synced` | boolean | Whether this answer came from a fully synced local copy. | +| `peak_height` | number \| null | The chain height this answer reflects. | + +Each entry in `coins`: + +| Field | Type | Meaning | +|---|---|---| +| `coin_id` | string | The coin's id, lowercase 64-hex. | +| `asset` | string | The asset this coin is denominated in: `"xch"` or `"dig"`. | +| `amount` | number (u64) | The coin's amount in mojos. | +| `parent_coin_info` | string | The parent coin id, lowercase 64-hex. | +| `puzzle_hash` | string | The coin's puzzle hash, lowercase 64-hex. | +| `created_height` | number | The block height this coin was created at. | +| `spent_height` | number \| null | Always `null` from this method — `control.wallet.coins` returns unspent coins only. Use [`control.wallet.coinById`](#control-wallet-coinbyid) to look up a coin that may have been spent. | + +`coins: []` is a **success**: a chain was consulted and the address holds no unspent coins for that asset. It is never returned because the chain couldn't be reached — an unreachable chain is one of the errors below instead, so an empty list always means "checked, and there is nothing there." + +**Errors** + +| Code | Name | Meaning | +|---|---|---| +| `-32602` | Invalid params | `address` is missing, not a valid bech32m address, or `asset` is not `"xch"`/`"dig"`. | +| `-32040` | `WALLET_NO_CHAIN_SOURCE` | No live chain source could answer this read. | +| `-32041` | `WALLET_NOT_SYNCED` | The wallet is still syncing and no fallback is available yet. | +| `-32042` | `WALLET_READ_FAILED` | The read failed at the underlying DB / chain-source layer. | +| `-32043` | `WALLET_RATE_LIMITED` | The open coinset-fallback rate limit is exhausted; back off and retry. | + +See the full [error-code reference](../support/error-codes.md#dig-rpc-json-rpc). + +### `control.wallet.peak` — the node's current chain peak {#control-wallet-peak} + +`control.wallet.peak` returns the chain height this node currently tracks. It is an **open read** and takes no parameters — use it to get a height to compare a coin's `created_height`/`spent_height` against. + +**Request** + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "control.wallet.peak", + "params": {} +} +``` + +**Result** + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { "peak_height": 4200042, "synced": true } +} +``` + +| Field | Type | Meaning | +|---|---|---| +| `peak_height` | number \| null | The chain height this node currently tracks, or `null` if this node tracks no height yet. | +| `synced` | boolean | Whether this node's own copy of the chain is fully synced. | + +`peak_height: null` means "this node doesn't yet know a height" — it is **not** a zero. Treat it as unknown, never as height `0`: every real block sits trivially above `0`, so reading `null` as `0` would make an unconfirmed transaction look buried under thousands of blocks it hasn't actually seen. + +**Errors** + +| Code | Name | Meaning | +|---|---|---| +| `-32040` | `WALLET_NO_CHAIN_SOURCE` | No live chain source could answer this read. | +| `-32041` | `WALLET_NOT_SYNCED` | The wallet is still syncing and no fallback is available yet. | +| `-32042` | `WALLET_READ_FAILED` | The read failed at the underlying DB / chain-source layer. | + +See the full [error-code reference](../support/error-codes.md#dig-rpc-json-rpc). + +### `control.wallet.coinById` — read one coin, spent or unspent {#control-wallet-coinbyid} + +`control.wallet.coinById` looks up a single coin by its coin id — unlike `control.wallet.coins`, it can see a coin that has since been **spent**. It is an **open read**: only a coin id is needed. + +This is the method to use to confirm an on-chain mint or payment once you know which coin was consumed to pay for it: check `spent_height` on the funding coin. + +**Request** + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "control.wallet.coinById", + "params": { "coin_id": "aa11…" } +} +``` + +| Param | Type | Required | Meaning | +|---|---|---|---| +| `coin_id` | string | yes | The coin id to look up, lowercase 64-hex. A `0x` prefix is accepted on input; the node never emits one. | + +**Result** + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "coin": { + "coin_id": "aa11…", + "asset": null, + "amount": 1000000000, + "parent_coin_info": "bb22…", + "puzzle_hash": "cc33…", + "created_height": 4200000, + "spent_height": 4200010 + }, + "source": "fallback", "synced": false, "peak_height": null + } +} +``` + +| Field | Type | Meaning | +|---|---|---| +| `coin` | object \| null | The coin, or `null` if no such coin exists on chain. See the field table below. | +| `source` | string | Always `"fallback"` for this method. | +| `synced` | boolean | Always `false` for this method. | +| `peak_height` | number \| null | Always `null` for this method — call [`control.wallet.peak`](#control-wallet-peak) for a height to compare against. | + +The `coin` object: + +| Field | Type | Meaning | +|---|---|---| +| `coin_id` | string | The coin's id, lowercase 64-hex — echoes the request. | +| `asset` | null | Always `null` here: a coin id alone doesn't say what the coin is denominated in, and the node does not guess. | +| `amount` | number (u64) | The coin's amount in mojos. | +| `parent_coin_info` | string | The parent coin id, lowercase 64-hex. | +| `puzzle_hash` | string | The coin's puzzle hash, lowercase 64-hex. | +| `created_height` | number | The block height this coin was created at. | +| `spent_height` | number \| null | The block height this coin was spent at, or `null` if it is still unspent. This is the field `control.wallet.coins` can never show you. | + +`coin: null` is a **success**: a chain was consulted and no coin with that id exists. It is never returned because the chain couldn't be reached — an unreachable chain is one of the errors below instead. + +**Errors** + +| Code | Name | Meaning | +|---|---|---| +| `-32602` | Invalid params | `coin_id` is missing or not 64 lowercase hex characters (with or without a `0x` prefix). | +| `-32040` | `WALLET_NO_CHAIN_SOURCE` | No live chain source could answer this read. | +| `-32042` | `WALLET_READ_FAILED` | The read failed at the underlying DB / chain-source layer. | +| `-32043` | `WALLET_RATE_LIMITED` | The open coinset-fallback rate limit is exhausted; back off and retry. | + +See the full [error-code reference](../support/error-codes.md#dig-rpc-json-rpc). + +### `control.wallet.broadcast` — push an already-signed spend {#control-wallet-broadcast} + +`control.wallet.broadcast` pushes a spend bundle that was **already signed** somewhere else — the node never signs anything, and there is deliberately no parameter through which a key, a seed, or a mnemonic could be passed. Unlike the four reads above, this method **requires a control token**: it puts bytes on the network, so it carries the same admin authority as the other `control.*` write operations. + +**Request** + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "control.wallet.broadcast", + "params": { "signed_bundle_hex": "d34d…" } +} +``` + +| Param | Type | Required | Meaning | +|---|---|---|---| +| `signed_bundle_hex` | string | yes | The already-signed spend bundle, hex-encoded, lowercase. | + +**Result** + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { "accepted": true, "transaction_id": "ee44…", "rejection": null } +} +``` + +| Field | Type | Meaning | +|---|---|---| +| `accepted` | boolean | Whether the mempool took the bundle. | +| `transaction_id` | string \| null | The transaction id, if accepted. | +| `rejection` | string \| null | The mempool's reason for refusing the bundle, if `accepted` is `false`. | + +Two things worth being precise about: + +- A mempool that looks at the bundle and says no is still a **successful call** — `accepted: false` with a `rejection` reason, not an error. Failing to *reach* a mempool at all is an error instead (below). The remedies are opposite: a `rejection` means retry the *same* bundle only after fixing what it complains about (or rebuild it), while a broadcast error means retry the *same* bundle as-is once the node can reach the network again. +- `accepted: true` means the mempool took the bundle — it is **not** evidence that the spend reached a block. Confirm that separately with [`control.wallet.coinById`](#control-wallet-coinbyid) against the coin the spend consumes: `spent_height` becoming non-null is the actual on-chain confirmation. + +**Errors** + +| Code | Name | Meaning | +|---|---|---| +| `-32602` | Invalid params | `signed_bundle_hex` is missing or not valid hex. | +| `-32030` | Unauthorized (control) | Called without a valid local control token. | +| `-32040` | `WALLET_NO_CHAIN_SOURCE` | No live chain source could reach the network to broadcast. | +| `-32042` | `WALLET_READ_FAILED` | The broadcast failed at the underlying chain-source layer. | + +See the full [error-code reference](../support/error-codes.md#dig-rpc-json-rpc). ## The DIG Browser Control Pane diff --git a/docs/support/error-codes.md b/docs/support/error-codes.md index 620efe0..71d4b8b 100644 --- a/docs/support/error-codes.md +++ b/docs/support/error-codes.md @@ -27,7 +27,7 @@ This catalog is also published as [`error-codes.json`](https://docs.dig.net/erro ## dig RPC (JSON-RPC) -The [dig RPC](../protocol/dig-rpc.md) uses the standard [JSON-RPC 2.0](https://www.jsonrpc.org/specification) error codes plus the protocol-specific `-32004`, `-32005`, the node-profile `-32003` / `-32006` / `-32007` / `-32008` / `-32009`, the shell/staging codes `-32010` (upstream) and `-32011`–`-32014` (`dig.stage`), the metadata-response bound `-32015` (`dig.getMetadata`), the push-reassembly bound `-32016` (`cache.pushCapsule`), the [private-retrieval](../protocol/onion-routing.md) codes `-32020` / `-32021` / `-32022`, the local control-plane codes `-32030` / `-32031` / `-32032`, and the wallet-balance read codes `-32040`–`-32043`. A content **miss is never an error** — the capsule returns its own indistinguishable, non-verifying response (there is no `decoy` field on the wire), and the client discovers the miss by inclusion-proof and/or decryption failure (see [the blind host model](../protocol/blind-host-model.md)). For any well-formed body the HTTP status is `200`; the error is carried in the JSON envelope. +The [dig RPC](../protocol/dig-rpc.md) uses the standard [JSON-RPC 2.0](https://www.jsonrpc.org/specification) error codes plus the protocol-specific `-32004`, `-32005`, the node-profile `-32003` / `-32006` / `-32007` / `-32008` / `-32009`, the shell/staging codes `-32010` (upstream) and `-32011`–`-32014` (`dig.stage`), the metadata-response bound `-32015` (`dig.getMetadata`), the push-reassembly bound `-32016` (`cache.pushCapsule`), the [private-retrieval](../protocol/onion-routing.md) codes `-32020` / `-32021` / `-32022`, the local control-plane codes `-32030` / `-32031` / `-32032`, and the [wallet chain-read/broadcast](../run-a-node/manage.md#control-wallet-balance) codes `-32040`–`-32043`. A content **miss is never an error** — the capsule returns its own indistinguishable, non-verifying response (there is no `decoy` field on the wire), and the client discovers the miss by inclusion-proof and/or decryption failure (see [the blind host model](../protocol/blind-host-model.md)). For any well-formed body the HTTP status is `200`; the error is carried in the JSON envelope. | Code | Meaning | What to do | |---|---|---| @@ -56,10 +56,10 @@ The [dig RPC](../protocol/dig-rpc.md) uses the standard [JSON-RPC 2.0](https://w | `-32030` | **Unauthorized (control)** — a `control.*` method was called without a valid local control token. Control methods are loopback-only. (These codes are `-32030`+ so they never collide with the onion codes above.) | Call control methods from the local machine with the node's control token. | | `-32031` | **Not supported (control)** — a control operation this build/pin cannot perform (e.g. §21 whole-store sync with no loaded identity). | Ensure the required capability/identity is present, or use a build that supports it. | | `-32032` | **Control error** — a control operation failed at runtime (distinct from bad input or an absent capability). | Retry; check the node's logs; report if it persists. | -| `-32040` | **Wallet: no chain source** (`WALLET_NO_CHAIN_SOURCE`) — a [`control.wallet.balance`](../run-a-node/manage.md#control-wallet-balance) read had no live chain source able to answer this address. Reported instead of a fabricated `0`. | Attach/allow a chain source (a synced local node or the coinset fallback), then retry. | -| `-32041` | **Wallet: not synced** (`WALLET_NOT_SYNCED`) — the wallet is still syncing and no live fallback is available to answer yet. | Wait for the node to finish syncing, then retry. | -| `-32042` | **Wallet: read failed** (`WALLET_READ_FAILED`) — the balance read failed at the underlying DB / chain-source layer. | Retry; check the node's logs; report if it persists. | -| `-32043` | **Wallet: rate limited** (`WALLET_RATE_LIMITED`) — the open coinset-fallback rate limit is exhausted (too many arbitrary-address reads in a short window). | Back off and retry; the cheap local-DB fast path is never rate-limited. | +| `-32040` | **Wallet: no chain source** (`WALLET_NO_CHAIN_SOURCE`) — one of the [`control.wallet.*`](../run-a-node/manage.md#control-wallet-balance) methods ([`balance`](../run-a-node/manage.md#control-wallet-balance), [`coins`](../run-a-node/manage.md#control-wallet-coins), [`peak`](../run-a-node/manage.md#control-wallet-peak), [`coinById`](../run-a-node/manage.md#control-wallet-coinbyid), [`broadcast`](../run-a-node/manage.md#control-wallet-broadcast)) had no live chain source able to answer. Reported instead of a fabricated result. | Attach/allow a chain source (a synced local node or the coinset fallback), then retry. | +| `-32041` | **Wallet: not synced** (`WALLET_NOT_SYNCED`) — a `control.wallet.*` read hit a wallet that is still syncing, with no live fallback available yet. | Wait for the node to finish syncing, then retry. | +| `-32042` | **Wallet: read failed** (`WALLET_READ_FAILED`) — a `control.wallet.*` call failed at the underlying DB / chain-source layer. | Retry; check the node's logs; report if it persists. | +| `-32043` | **Wallet: rate limited** (`WALLET_RATE_LIMITED`) — the open coinset-fallback rate limit is exhausted (too many arbitrary-address/coin reads in a short window). | Back off and retry; the cheap local-DB fast path is never rate-limited. | ## dig-store CLI (exit codes) {#digstore-cli-exit-codes} diff --git a/package.json b/package.json index 76b7b8e..22facaf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docs-dig-net", - "version": "0.15.0", + "version": "0.16.0", "private": true, "scripts": { "docusaurus": "docusaurus", diff --git a/scripts/dig-spec.mjs b/scripts/dig-spec.mjs index 461e294..92ceef2 100644 --- a/scripts/dig-spec.mjs +++ b/scripts/dig-spec.mjs @@ -1062,24 +1062,24 @@ export const rpcErrors = { code: -32040, message: "Wallet: no chain source", meaning: - "A control.wallet.balance read had no live chain source able to answer this address. Reported instead of a fabricated 0. See https://docs.dig.net/docs/run-a-node/manage#control-wallet-balance.", + "A control.wallet.* call (balance, coins, peak, coinById, or broadcast) had no live chain source able to answer. Reported instead of a fabricated result. See https://docs.dig.net/docs/run-a-node/manage#control-wallet-balance.", }, WALLET_NOT_SYNCED: { code: -32041, message: "Wallet: not synced", meaning: - "A control.wallet.balance read could not be answered because the wallet is still syncing and no live fallback is available yet.", + "A control.wallet.* read could not be answered because the wallet is still syncing and no live fallback is available yet.", }, WALLET_READ_FAILED: { code: -32042, message: "Wallet: read failed", - meaning: "A control.wallet.balance read failed at the underlying DB / chain-source layer.", + meaning: "A control.wallet.* call failed at the underlying DB / chain-source layer.", }, WALLET_RATE_LIMITED: { code: -32043, message: "Wallet: rate limited", meaning: - "A control.wallet.balance read was refused because the open coinset-fallback rate limit is exhausted. Back off and retry; the cheap local-DB fast path is never rate-limited.", + "A control.wallet.* call was refused because the open coinset-fallback rate limit is exhausted. Back off and retry; the cheap local-DB fast path is never rate-limited.", }, }; diff --git a/static/error-codes.json b/static/error-codes.json index 7334e64..783510c 100644 --- a/static/error-codes.json +++ b/static/error-codes.json @@ -190,28 +190,28 @@ "code": -32040, "name": "WALLET_NO_CHAIN_SOURCE", "http_or_exit": 200, - "description": "Wallet: no chain source — A control.wallet.balance read had no live chain source able to answer this address. Reported instead of a fabricated 0. See https://docs.dig.net/docs/run-a-node/manage#control-wallet-balance." + "description": "Wallet: no chain source — A control.wallet.* call (balance, coins, peak, coinById, or broadcast) had no live chain source able to answer. Reported instead of a fabricated result. See https://docs.dig.net/docs/run-a-node/manage#control-wallet-balance." }, { "surface": "dig-rpc", "code": -32041, "name": "WALLET_NOT_SYNCED", "http_or_exit": 200, - "description": "Wallet: not synced — A control.wallet.balance read could not be answered because the wallet is still syncing and no live fallback is available yet." + "description": "Wallet: not synced — A control.wallet.* read could not be answered because the wallet is still syncing and no live fallback is available yet." }, { "surface": "dig-rpc", "code": -32042, "name": "WALLET_READ_FAILED", "http_or_exit": 200, - "description": "Wallet: read failed — A control.wallet.balance read failed at the underlying DB / chain-source layer." + "description": "Wallet: read failed — A control.wallet.* call failed at the underlying DB / chain-source layer." }, { "surface": "dig-rpc", "code": -32043, "name": "WALLET_RATE_LIMITED", "http_or_exit": 200, - "description": "Wallet: rate limited — A control.wallet.balance read was refused because the open coinset-fallback rate limit is exhausted. Back off and retry; the cheap local-DB fast path is never rate-limited." + "description": "Wallet: rate limited — A control.wallet.* call was refused because the open coinset-fallback rate limit is exhausted. Back off and retry; the cheap local-DB fast path is never rate-limited." }, { "surface": "digstore-cli", @@ -659,28 +659,28 @@ "code": -32040, "name": "WALLET_NO_CHAIN_SOURCE", "http_or_exit": 200, - "description": "Wallet: no chain source — A control.wallet.balance read had no live chain source able to answer this address. Reported instead of a fabricated 0. See https://docs.dig.net/docs/run-a-node/manage#control-wallet-balance." + "description": "Wallet: no chain source — A control.wallet.* call (balance, coins, peak, coinById, or broadcast) had no live chain source able to answer. Reported instead of a fabricated result. See https://docs.dig.net/docs/run-a-node/manage#control-wallet-balance." }, { "surface": "dig-rpc", "code": -32041, "name": "WALLET_NOT_SYNCED", "http_or_exit": 200, - "description": "Wallet: not synced — A control.wallet.balance read could not be answered because the wallet is still syncing and no live fallback is available yet." + "description": "Wallet: not synced — A control.wallet.* read could not be answered because the wallet is still syncing and no live fallback is available yet." }, { "surface": "dig-rpc", "code": -32042, "name": "WALLET_READ_FAILED", "http_or_exit": 200, - "description": "Wallet: read failed — A control.wallet.balance read failed at the underlying DB / chain-source layer." + "description": "Wallet: read failed — A control.wallet.* call failed at the underlying DB / chain-source layer." }, { "surface": "dig-rpc", "code": -32043, "name": "WALLET_RATE_LIMITED", "http_or_exit": 200, - "description": "Wallet: rate limited — A control.wallet.balance read was refused because the open coinset-fallback rate limit is exhausted. Back off and retry; the cheap local-DB fast path is never rate-limited." + "description": "Wallet: rate limited — A control.wallet.* call was refused because the open coinset-fallback rate limit is exhausted. Back off and retry; the cheap local-DB fast path is never rate-limited." } ], "digstore-cli": [