> For the complete documentation index, see [llms.txt](https://docs.fast.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fast.xyz/api-reference/json-rpc-api.md).

# JSON-RPC API

Direct Fast proxy JSON-RPC endpoints and network configuration, distinct from the REST transport used by the core SDK.

The Fast proxy has a low-level JSON-RPC 2.0 interface. The current `@fastxyz/sdk` uses the separate **REST** proxy interface (`/proxy-rest`), not this JSON-RPC endpoint. For new SDK integrations, use the [Fast SDK reference](/sdk-references/core-sdk-execution/fast-sdk.md) and [REST API](/api-reference/rest-api.md). Keep direct JSON-RPC callers pinned to the server API they have validated; this page does not establish that every older method or response shape is supported by every deployment.

This page is for developers who need direct access to the protocol-level endpoints.

***

### Endpoints

<table><thead><tr><th width="105.70703125">Network</th><th width="639.171875">Proxy RPC</th></tr></thead><tbody><tr><td><strong>Mainnet</strong></td><td><code>https://api.fast.xyz/proxy</code></td></tr><tr><td><strong>Testnet</strong></td><td><code>https://testnet.api.fast.xyz/proxy</code></td></tr></tbody></table>

<table><thead><tr><th width="105.70703125">Network</th><th width="155.9609375">SDK default token</th><th>Token ID</th></tr></thead><tbody><tr><td><strong>Mainnet</strong></td><td><code>fastUSD</code></td><td><a href="https://explorer.fast.xyz/asset/0xc655a12330da6af361d281b197996d2bc135aaed3b66278e729c2222291e9130">c655a12330da6af361d281b197996d2bc135aaed3b66278e729c2222291e9130</a></td></tr><tr><td><strong>Testnet</strong></td><td><code>testUSDC</code></td><td><a href="https://testnet.explorer.fast.xyz/asset/0xd73a0679a2be46981e2a8aedecd951c8b6690e7d5f8502b34ed3ff4cc2163b46">d73a0679a2be46981e2a8aedecd951c8b6690e7d5f8502b34ed3ff4cc2163b46</a></td></tr></tbody></table>

All requests are `POST` with `Content-Type: application/json`.

#### Request

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "<method_name>",
  "params": { ... }
}
```

#### Responses

For a JSON-RPC response, inspect the `result` or `error` member. Do not assume every transport failure returns HTTP 200 or that an absent response means a transaction was not submitted.

Success Response

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    ...
  }
}
```

Error Response

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": "<error_code>",
    "message": "<error_message>",
    "data": "<additional_data>"
  }
}
```

***

### Methods

| Method                    | Purpose                                                         |
| ------------------------- | --------------------------------------------------------------- |
| `proxy_submitTransaction` | Submit a signed transaction — returns a certificate on success  |
| `proxy_getAccountInfo`    | Query account balance, nonce, token holdings, and certificates  |
| `proxy_getTokenInfo`      | Look up token metadata (name, decimals, supply, admin, minters) |

***

#### `proxy_submitTransaction`

Submit a signed transaction to the network. The proxy handles the full settlement lifecycle: it broadcasts the transaction to all validators, collects their signatures, assembles a certificate once quorum is reached, and submits the certificate back to validators for settlement.

**Parameters:**

| Field         | Type                  | Description                                           |
| ------------- | --------------------- | ----------------------------------------------------- |
| `transaction` | `Transaction`         | The transaction to submit                             |
| `signature`   | `SignatureOrMultiSig` | Ed25519 signature over the BCS-serialized transaction |

**Returns:** `ProxySubmitTransactionResult`

* `{ "Success": TransactionCertificate }` — transaction settled, certificate returned
* `{ "IncompleteMultiSig": [...] }` — multisig transaction stored, awaiting additional signatures

<details>

<summary>Example request</summary>

```bash
curl -X POST 'https://testnet.api.fast.xyz/proxy' \
  --header 'Content-Type: application/json' \
  --data '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "proxy_submitTransaction",
    "params": {
      "transaction": {
        "network_id": "fast:testnet",
        "sender": [54,128,54,206,88,243,124,101,147,238,105,180,78,172,190,12,193,195,118,236,177,124,79,251,192,63,114,196,255,73,74,81],
        "nonce": 0,
        "timestamp_nanos": 1769705752161000000,
        "claim": {
          "TokenTransfer": {
            "recipient": [75,164,223,195,221,101,117,31,251,60,194,50,41,1,83,17,79,28,61,165,140,36,12,127,122,60,161,218,118,145,112,210],
            "token_id": [250,87,94,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            "amount": "ffff",
            "user_data": null
          }
        },
        "archival": false
      },
      "signature": {
        "Signature": [228,162,180,83,46,167,133,230,176,100,60,110,57,65,23,113,101,204,242,193,125,59,88,232,122,6,90,118,41,159,94,108,20,181,224,234,57,42,35,95,4,186,62,128,68,213,212,46,214,155,241,163,147,120,155,69,201,1,29,63,106,22,75,15]
      }
    }
  }'
```

</details>

<details>

<summary>Example response</summary>

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "Success": {
      "envelope": {
        "transaction": {
          "network_id": "fast:testnet",
          "sender": [54,128,54,206,...],
          "nonce": 0,
          "timestamp_nanos": 1769705752161000000,
          "claim": {
            "TokenTransfer": {
              "recipient": [75,164,223,195,...],
              "token_id": [250,87,94,112,0,...],
              "amount": "ffff",
              "user_data": null
            }
          },
          "archival": false
        },
        "signature": {
          "Signature": [228,162,180,83,...]
        }
      },
      "signatures": [
        [[223,165,168,37,...], [95,227,196,114,...]],
        [[236,249,103,252,...], [80,65,124,70,...]],
        [[150,20,92,12,...], [26,229,199,218,...]]
      ]
    }
  }
}
```

</details>

***

#### `proxy_getAccountInfo`

Query account information from a validator known to the proxy.

**Parameters:**

| Field                   | Type                        | Description                                                           |
| ----------------------- | --------------------------- | --------------------------------------------------------------------- |
| `address`               | `Array<uint8; 32>`          | The account's Ed25519 public key                                      |
| `token_balances_filter` | `Array<TokenId>` or `null`  | Which token balances to return. `null` = none; `[]` = all tokens held |
| `state_key_filter`      | `Array<StateKey>` or `null` | Which state fields to return. `null` = none; `[]` = all               |
| `certificate_by_nonce`  | `NonceRange` or `null`      | Currently not unabled                                                 |

**Returns:** `AccountInfoResponse`

<details>

<summary>Example request</summary>

```bash
curl -X POST 'https://testnet.api.fast.xyz/proxy' \
  --header 'Content-Type: application/json' \
  --data '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "proxy_getAccountInfo",
    "params": {
      "address": [54,128,54,206,88,243,124,101,147,238,105,180,78,172,190,12,193,195,118,236,177,124,79,251,192,63,114,196,255,73,74,81],
      "token_balances_filter": [],
      "state_key_filter": null,
      "certificate_by_nonce": null
    }
  }'
```

</details>

<details>

<summary>Example response</summary>

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "sender": [54,128,54,206,...],
    "balance": "de0b6b3a7640000",
    "next_nonce": 3,
    "pending_confirmation": null,
    "requested_state": [],
    "requested_certificates": null,
    "requested_validated_transaction": null,
    "token_balance": [
      [[250,87,94,112,0,...], "de0b6b3a7640000"]
    ]
  }
}
```

</details>

***

#### `proxy_getTokenInfo`

Look up metadata for one or more tokens.

**Parameters:**

| Field       | Type                      | Description          |
| ----------- | ------------------------- | -------------------- |
| `token_ids` | `Array<Array<uint8; 32>>` | Token IDs to look up |

**Returns:** `TokenInfoResponse`

<details>

<summary>Example request</summary>

```bash
curl -X POST 'https://testnet.api.fast.xyz/proxy' \
  --header 'Content-Type: application/json' \
  --data '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "proxy_getTokenInfo",
    "params": {
      "token_ids": [
        [250,87,94,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
      ]
    }
  }'
```

</details>

<details>

<summary>Example response</summary>

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "requested_token_metadata": [
      [
        [250,87,94,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        {
          "update_id": 0,
          "admin": [0,0,...],
          "token_name": "SET",
          "decimals": 18,
          "total_supply": "52b7d2dcc80cd2e4000000",
          "mints": []
        }
      ]
    ]
  }
}
```

</details>

***

### Transaction Signing

To submit a transaction, you must sign it locally before sending it to the proxy.

#### 1. Serialize

Serialize the `Transaction` struct using [BCS (Binary Canonical Serialization)](https://github.com/zefchain/bcs).

BCS libraries:

* **TypeScript/JavaScript:** [`@mysten/bcs`](https://www.npmjs.com/package/@mysten/bcs)
* **Rust:** [`bcs`](https://github.com/zefchain/bcs) (as a `serde` backend)

**Special rule:** Numerical string fields (`Amount` / `Balance`) are encoded as little-endian unsigned 256-bit integers (32 bytes) during BCS serialization.

#### 2. Prefix

Prepend the UTF-8 string `"Transaction::"` to the serialized bytes.

#### 3. Sign

Sign the prefixed bytes with Ed25519 using the sender's private key:

```
signature = ed25519_sign(private_key, "Transaction::" + BCS(transaction))
```

#### 4. Hash

The transaction hash is the keccak256 digest of the BCS-serialized transaction (without the prefix):

```
tx_hash = keccak256(BCS(transaction))
```

#### 5. Submit

Wrap the signature in a `SignatureOrMultiSig` envelope and call `proxy_submitTransaction`.

***

### Data Encoding

| Concept                   | Format                                                         | Example                     |
| ------------------------- | -------------------------------------------------------------- | --------------------------- |
| **Addresses**             | 32-byte Ed25519 public key, as JSON array of unsigned integers | `[54,128,54,206,...,74,81]` |
| **User-facing addresses** | bech32m with `fast` prefix (SDK only, not used in RPC)         | `fast1qxy2kgdy...`          |
| **Amounts**               | Hex-encoded unsigned 256-bit integer (no `0x` prefix)          | `"de0b6b3a7640000"`         |
| **Timestamps**            | `uint128` nanoseconds since Unix epoch                         | `1769705752161000000`       |
| **Nonces**                | `uint64`, auto-incrementing per account, starting at 0         | `0`, `1`, `2`, ...          |

***

### Data Types

#### Transaction

The core unit submitted to the network.

| Field             | Type                | Description                                                                           |
| ----------------- | ------------------- | ------------------------------------------------------------------------------------- |
| `network_id`      | `string`            | The id of the network (e.g., "fast:mainnet", "fast:testnet"). Follows CAIP-2 standard |
| `sender`          | `Array<uint8; 32>`  | Sender's Ed25519 public key                                                           |
| `nonce`           | `uint64`            | Sequence number — must match the account's `next_nonce`                               |
| `timestamp_nanos` | `uint128`           | Nanoseconds since Unix epoch                                                          |
| `claim`           | `ClaimType`         | The operation to perform                                                              |
| `archival`        | `boolean`           | Currently disabled                                                                    |
| `fee_token`       | `TokenId` or `null` | The fee token to use to pay for this transaction. See more details below.             |

> #### Fee token
>
> A transaction may include `fee_token`. Do not assume that an omitted value means USDC on every network: the current SDK network defaults are `fastUSD` on mainnet and `testUSDC` on testnet. Confirm accepted fee tokens with the target deployment before submitting a transaction directly through JSON-RPC.

#### ClaimType

Determines the operation packed into a transaction.

| Variant           | Type              | Description                                    |
| ----------------- | ----------------- | ---------------------------------------------- |
| `TokenTransfer`   | `TokenTransfer`   | Transfer tokens to the recipient               |
| `TokenCreation`   | `TokenCreation`   | Create a new custom token                      |
| `TokenManagement` | `TokenManagement` | Modify a custom token (admin, minters)         |
| `Mint`            | `Mint`            | Mint additional supply of a custom token       |
| `Burn`            | `Burn`            | Burn an amount of a custom token               |
| `ExternalClaim`   | `ExternalClaim`   | Submit arbitrary data with verifier signatures |
| `Batch`           | `OperationBundle` | Bundle multiple operations in one transaction  |

#### TokenTransfer

| Field       | Type                         | Description                      |
| ----------- | ---------------------------- | -------------------------------- |
| `recipient` | `Array<uint8; 32>`           | Recipient address                |
| `token_id`  | `Array<uint8; 32>`           | Token ID to transfer             |
| `amount`    | `Amount`                     | Amount in raw units (hex string) |
| `user_data` | `Array<uint8; 32>` or `null` | Optional arbitrary data          |

#### TokenCreation

| Field            | Type                         | Description                              |
| ---------------- | ---------------------------- | ---------------------------------------- |
| `token_name`     | `string`                     | Human-readable name                      |
| `decimals`       | `uint8`                      | Decimal places (0–18)                    |
| `initial_amount` | `Amount`                     | Initial supply, credited to the creator  |
| `mints`          | `Array<Array<uint8; 32>>`    | Addresses authorized to mint more supply |
| `user_data`      | `Array<uint8; 32>` or `null` | Optional arbitrary data                  |

The token ID is derived from the keccak256 hash of the BCS-serialized transaction that creates the token.

#### TokenManagement

| Field       | Type                                       | Description                                          |
| ----------- | ------------------------------------------ | ---------------------------------------------------- |
| `token_id`  | `Array<uint8; 32>`                         | Token to manage                                      |
| `update_id` | `uint64`                                   | Sequencing counter — must increment by 1 each update |
| `new_admin` | `Array<uint8; 32>` or `null`               | New admin address, or `null` to keep current         |
| `mints`     | `Array<[AddressChange, Array<uint8; 32>]>` | Minter addresses to add or remove                    |
| `user_data` | `Array<uint8; 32>` or `null`               | Optional arbitrary data                              |

`AddressChange` is either `{ "Add": [...] }` or `{ "Remove": [...] }`.

#### Mint

Sender must be an authorized minter for the token.

| Field       | Type               | Description       |
| ----------- | ------------------ | ----------------- |
| `recipient` | `Array<uint8; 32>` | Recipient address |
| `token_id`  | `Array<uint8; 32>` | Token to mint     |
| `amount`    | `Amount`           | Amount to mint    |

#### Burn

| Field      | Type               | Description    |
| ---------- | ------------------ | -------------- |
| `token_id` | `Array<uint8; 32>` | Token to burn  |
| `amount`   | `Amount`           | Amount to burn |

#### ExternalClaim

Submit arbitrary data verified by a set of external verifiers.

| Field                | Type                      | Description                              |
| -------------------- | ------------------------- | ---------------------------------------- |
| `verifier_committee` | `Array<Array<uint8; 32>>` | Verifier public keys                     |
| `verifier_quorum`    | `uint64`                  | Minimum verifier signatures required     |
| `claim_data`         | `Array<uint8>`            | Arbitrary data payload                   |
| `signatures`         | `Array<VerifierSig>`      | Verifier signatures over the transaction |

Each `VerifierSig` contains `verifier_addr` (public key) and `sig` (Ed25519 signature over the `Transaction` struct without verifier signatures).

#### OperationBundle

An array of `Operation` objects. Each `Operation` is one of: `TokenTransfer` (with explicit `recipient`), `TokenCreation`, `TokenManagement`, `ExternalClaim`, `Mint` (with explicit `recipient`), or `Burn`.

The `TokenTransfer` and `Mint` variants inside a bundle include a `recipient` field, since the bundle allows operations targeting different recipients within a single transaction.

***

#### Response Types

**AccountInfoResponse**

| Field                    | Type                                      | Description                                 |
| ------------------------ | ----------------------------------------- | ------------------------------------------- |
| `sender`                 | `Array<uint8; 32>`                        | Account address                             |
| `balance`                | `Balance`                                 | Native SET balance (hex string)             |
| `next_nonce`             | `uint64`                                  | Next valid nonce for this account           |
| `pending_confirmation`   | `ValidatedTransaction` or `null`          | Transaction validated but not yet confirmed |
| `requested_state`        | `Array<[StateKey, State]>`                | Requested state fields                      |
| `requested_certificates` | `Array<TransactionCertificate>` or `null` | Certificates in the requested nonce range   |
| `token_balance`          | `Array<[TokenId, Balance]>`               | Custom token balances                       |

**TokenInfoResponse**

| Field                      | Type                              | Description               |
| -------------------------- | --------------------------------- | ------------------------- |
| `requested_token_metadata` | `Array<[TokenId, TokenMetadata]>` | Token ID → metadata pairs |

`TokenMetadata` fields: `update_id`, `admin`, `token_name`, `decimals`, `total_supply`, `mints`.

**TransactionCertificate**

| Field        | Type                                 | Description                             |
| ------------ | ------------------------------------ | --------------------------------------- |
| `envelope`   | `TransactionEnvelope`                | The transaction + sender's signature    |
| `signatures` | `Array<[PublicKeyBytes, Signature]>` | Validator signatures forming the quorum |

`TransactionEnvelope` contains `transaction` (`Transaction`) and `signature` (`SignatureOrMultiSig`).

**ProxySubmitTransactionResult**

| Variant              | Payload                  | Description                                           |
| -------------------- | ------------------------ | ----------------------------------------------------- |
| `Success`            | `TransactionCertificate` | Transaction settled successfully                      |
| `IncompleteMultiSig` | `array`                  | Multisig transaction stored, awaiting more signatures |

***

#### Primitive Types

| Type                  | Format                                                               | Description                                                            |
| --------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| `Amount`              | Hex string (unsigned 256-bit)                                        | Token amount in raw units. Example: `"de0b6b3a7640000"` = 10¹⁸ = 1 SET |
| `Balance`             | Hex string (signed 257-bit)                                          | Like Amount, but may be negative (prefixed with `-`)                   |
| `Nonce`               | `uint64`                                                             | Sequence number                                                        |
| `NonceRange`          | `{ start: Nonce, limit: uint }`                                      | Range query for certificates                                           |
| `PublicKeyBytes`      | `Array<uint8; 32>`                                                   | Ed25519 public key                                                     |
| `Signature`           | `Array<uint8; 64>`                                                   | Ed25519 signature                                                      |
| `SignatureOrMultiSig` | `{ "Signature": [...] }` or `{ "MultiSig": { config, signatures } }` | Single or multisig authentication                                      |
| `TokenId`             | `Array<uint8; 32>`                                                   | Unique token identifier                                                |
| `StateKey`            | `Array<uint8; 32>`                                                   | Account state field key                                                |
| `State`               | `Array<uint8; 32>`                                                   | Account state field value                                              |
| `UserData`            | `Array<uint8; 32>` or `null`                                         | Optional arbitrary data attached to a transaction                      |

***

#### MultiSig

For accounts controlled by multiple signers.

**MultiSigConfig** — determines the multisig account address:

| Field                | Type                    | Description                                                      |
| -------------------- | ----------------------- | ---------------------------------------------------------------- |
| `authorized_signers` | `Array<PublicKeyBytes>` | Accounts that may sign                                           |
| `quorum`             | `uint64`                | Minimum signatures required                                      |
| `nonce`              | `uint64`                | Distinguishes multiple multisig accounts with the same committee |

**MultiSig** — authentication envelope:

| Field        | Type                                 | Description                          |
| ------------ | ------------------------------------ | ------------------------------------ |
| `config`     | `MultiSigConfig`                     | The account's multisig configuration |
| `signatures` | `Array<[PublicKeyBytes, Signature]>` | Signatures from authorized signers   |

***

### Error Codes

Standard JSON-RPC 2.0 error codes plus application-specific codes:

| Code     | Message          | Description                                                                                                                          |
| -------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `-32700` | Parse error      | Malformed JSON in request body                                                                                                       |
| `-32601` | Method not found | The requested method does not exist                                                                                                  |
| `-32602` | Invalid params   | Missing or invalid parameters                                                                                                        |
| `-32014` | Unexpected Nonce | The nonce of the transaction is incorrect                                                                                            |
| `-32015` | Invalid Request  | The transaction exceeds various limits (size, number of signatures, token name length, number of minters, number of claims in batch) |
| `-32000` | General Error    | Other general errors                                                                                                                 |

***

### Architecture Note

The proxy is a convenience layer — it is not part of the trust model. It relays messages, aggregates signatures, and assembles certificates, but it cannot forge signatures or alter transactions. Anyone can run a proxy.

In the current network configuration, validators are not directly accessible. All traffic routes through the proxy service. This is a temporary operational decision to prevent DDoS attacks — not a protocol requirement. The protocol itself is fully functional with direct client-to-validator communication.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.fast.xyz/api-reference/json-rpc-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `build a script that syncs our docs to a CMS` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
