{
  "openapi": "3.1.0",
  "info": {
    "title": "fleet REST API",
    "description": "REST API for fleet nodes, served under /v1.",
    "license": {
      "name": ""
    },
    "version": "1.1.2"
  },
  "paths": {
    "/v1/balances": {
      "get": {
        "tags": [
          "balances"
        ],
        "summary": "Get UTXO balances for one or more addresses.",
        "description": "Repeat the `address` query parameter for multiple addresses; use `POST\n/v1/balances/query` instead for large batches.",
        "operationId": "get_balances",
        "parameters": [
          {
            "name": "address",
            "in": "query",
            "description": "Addresses to look up; repeat the parameter for multiple values",
            "required": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "UTXO balance for the requested addresses",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalancesResponse"
                }
              }
            }
          },
          "500": {
            "description": "The mempool node could not be reached",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/balances/query": {
      "post": {
        "tags": [
          "balances"
        ],
        "summary": "Batch-lookup UTXO balances for one or more addresses.",
        "operationId": "query_balances",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddressesQuery"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "UTXO balance for the requested addresses",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalancesResponse"
                }
              }
            }
          },
          "500": {
            "description": "The mempool node could not be reached",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/blockchain-entries/query": {
      "post": {
        "tags": [
          "blockchain-entries"
        ],
        "summary": "Batch-lookup blockchain DB entries by raw storage key.",
        "description": "Keys with no stored entry are omitted from the response rather than erroring.",
        "operationId": "query_blockchain_entries",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KeysQuery"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The entries found for the requested keys",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BlockchainEntryResponse"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/blockchain-entries/{key}": {
      "get": {
        "tags": [
          "blockchain-entries"
        ],
        "summary": "Get a single blockchain DB entry by its raw storage key.",
        "operationId": "get_blockchain_entry",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "description": "The raw storage key",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The stored entry",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlockchainEntryResponse"
                }
              }
            }
          },
          "404": {
            "description": "No entry stored at this key",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/blocks": {
      "get": {
        "tags": [
          "blocks"
        ],
        "summary": "Batch-lookup stored blocks by number.",
        "description": "Block numbers with no stored block are omitted from the response rather than\nerroring; repeat the `num` query parameter for multiple numbers.",
        "operationId": "get_blocks_batch",
        "parameters": [
          {
            "name": "num",
            "in": "query",
            "description": "Block numbers to look up; repeat the parameter for multiple values",
            "required": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int64",
                "minimum": 0
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The block entries found for the requested numbers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BlockchainEntryResponse"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/blocks/latest": {
      "get": {
        "tags": [
          "blocks"
        ],
        "summary": "Get the most recently stored block.",
        "operationId": "get_latest_block",
        "responses": {
          "200": {
            "description": "The latest stored block",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LatestBlockResponse"
                }
              }
            }
          },
          "404": {
            "description": "No block has been stored yet",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/blocks/{num}": {
      "get": {
        "tags": [
          "blocks"
        ],
        "summary": "Get a single stored block by number.",
        "operationId": "get_block_by_num",
        "parameters": [
          {
            "name": "num",
            "in": "path",
            "description": "The block number",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The stored block entry",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlockchainEntryResponse"
                }
              }
            }
          },
          "404": {
            "description": "No block has been stored at this number",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/debug": {
      "get": {
        "tags": [
          "debug"
        ],
        "summary": "Get node type, peer list, and route metadata for this node.",
        "operationId": "get_debug",
        "responses": {
          "200": {
            "description": "Debug data for this node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DebugData"
                }
              }
            }
          }
        }
      }
    },
    "/v1/donation-requests": {
      "post": {
        "tags": [
          "donations"
        ],
        "summary": "Ask a peer to send this user node a donation.",
        "description": "`address` is parsed as a socket address and a `RequestDonation` event is injected\nfor the node to send the request itself; no response payload is returned.",
        "operationId": "post_donation_request",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DonationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Donation request sent"
          },
          "400": {
            "description": "address was not a valid ip:port socket address",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          },
          "500": {
            "description": "The donation request could not be sent",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        },
        "security": [
          {
            "api_key": []
          }
        ]
      }
    },
    "/v1/items": {
      "post": {
        "tags": [
          "items"
        ],
        "summary": "Create an item asset.",
        "description": "On a mempool node, this signs and submits the item-asset creation transaction\ndirectly (`script_public_key`/`public_key`/`signature` are required) and returns\n`201` with the created asset. On a user node, this injects a creation request for\nthe node to construct and sign itself, and returns `202`.",
        "operationId": "post_create_item",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateItemRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Item asset created on the mempool",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateItemResponse"
                }
              }
            }
          },
          "202": {
            "description": "Item-asset creation accepted by the user node",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateItemAcceptedResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing required fields for a mempool-node create",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          },
          "500": {
            "description": "The node could not be reached, or rejected the request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        },
        "security": [
          {
            "api_key": []
          }
        ]
      }
    },
    "/v1/mining/current-block": {
      "get": {
        "tags": [
          "mining"
        ],
        "summary": "Get the latest block received for mining.",
        "operationId": "get_current_block",
        "responses": {
          "200": {
            "description": "The current mining block, or `null` if none has been received yet",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentBlockResponse"
                }
              }
            }
          },
          "500": {
            "description": "This node does not mine",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payments": {
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Make a payment, by address or by ip.",
        "description": "Both kinds first check the wallet passphrase. For `kind=address`, the node\nconstructs and signs the payment (`UserApi::make_payment`); a construction failure\n(`success=false`) is reported as `422`, otherwise the constructed payment is queued\nfor sending (`SendNextPayment`) and its `tx_hash` returned. For `kind=ip`, the\n`address` field is parsed as a socket address and the payment is sent directly to\nthat peer (`MakeIpPayment`); no `tx_hash` is available for this path.",
        "operationId": "post_payment",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "The payment was accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentAcceptedResponse"
                }
              }
            }
          },
          "400": {
            "description": "kind=ip and address was not a valid ip:port socket address",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          },
          "401": {
            "description": "The wallet passphrase was incorrect",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          },
          "422": {
            "description": "kind=address and the payment could not be constructed",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          },
          "500": {
            "description": "This node does not expose a wallet or cannot make payments",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        },
        "security": [
          {
            "api_key": []
          }
        ]
      }
    },
    "/v1/supply": {
      "get": {
        "tags": [
          "supply"
        ],
        "summary": "Get the total and issued token supply.",
        "operationId": "get_supply",
        "responses": {
          "200": {
            "description": "Total and issued token supply",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SupplyResponse"
                }
              }
            }
          },
          "500": {
            "description": "The mempool node could not be reached",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions": {
      "post": {
        "tags": [
          "transactions"
        ],
        "summary": "Construct one or more transactions and submit them to the mempool.",
        "operationId": "post_create_transactions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTransactionsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The transaction(s) were accepted by the mempool",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateTransactionsResponse"
                }
              }
            }
          },
          "400": {
            "description": "One or more transactions were malformed",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          },
          "500": {
            "description": "The mempool node could not be reached, or rejected the transaction(s)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/outgoing": {
      "get": {
        "tags": [
          "transactions"
        ],
        "summary": "Get this node's outgoing (constructed-and-sent) transactions.",
        "description": "An empty wallet with no outgoing transactions yet returns an empty list rather than\nan error, unlike the legacy handler (which surfaced the \"no key in the DB yet\" case\nas a `500`).",
        "operationId": "get_outgoing_txs",
        "responses": {
          "200": {
            "description": "This node's outgoing transactions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OutgoingTxsResponse"
                }
              }
            }
          },
          "500": {
            "description": "This node does not expose a wallet, or the wallet DB could not be read",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/status": {
      "get": {
        "tags": [
          "transactions"
        ],
        "summary": "Get mempool status for one or more transactions.",
        "description": "Repeat the `hash` query parameter for multiple hashes; use `POST\n/v1/transactions/status:query` instead for large batches.",
        "operationId": "get_transaction_status",
        "parameters": [
          {
            "name": "hash",
            "in": "query",
            "description": "Transaction hashes to look up; repeat the parameter for multiple values",
            "required": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status for the requested transaction hashes, keyed by hash",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "$ref": "#/components/schemas/TxStatusResponse"
                  },
                  "propertyNames": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "500": {
            "description": "The mempool node could not be reached",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/status:query": {
      "post": {
        "tags": [
          "transactions"
        ],
        "summary": "Batch-lookup mempool status for one or more transactions.",
        "operationId": "query_transaction_status",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HashesQuery"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Status for the requested transaction hashes, keyed by hash",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "$ref": "#/components/schemas/TxStatusResponse"
                  },
                  "propertyNames": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "500": {
            "description": "The mempool node could not be reached",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions:deserialize": {
      "post": {
        "tags": [
          "transactions"
        ],
        "summary": "Deserialize one or more hex-encoded transactions, without submitting them to the\nmempool. Stateless; not tied to any node's mempool or wallet.",
        "operationId": "post_deserialize_transactions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeserializeTransactionsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The deserialized transaction(s)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeserializeTransactionsResponse"
                }
              }
            }
          },
          "400": {
            "description": "One or more hex strings were malformed",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions:serialize": {
      "post": {
        "tags": [
          "transactions"
        ],
        "summary": "Serialize one or more transactions to hex-encoded bytes, without submitting them to\nthe mempool. Stateless; not tied to any node's mempool or wallet.",
        "operationId": "post_serialize_transactions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SerializeTransactionsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The serialized transaction(s)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SerializeTransactionsResponse"
                }
              }
            }
          },
          "400": {
            "description": "One or more transactions were malformed",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/wallet": {
      "get": {
        "tags": [
          "wallet"
        ],
        "summary": "Get balance and transaction info for this node's wallet.",
        "operationId": "get_wallet_info",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page of transaction_pages to return outpoints from",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "spent",
            "in": "query",
            "description": "Return spent transactions instead of the unspent set",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Balance and transaction info for this node's wallet",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletInfoResponse"
                }
              }
            }
          },
          "500": {
            "description": "This node does not expose a wallet, or the wallet DB could not be read",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/wallet/addresses": {
      "post": {
        "tags": [
          "wallet"
        ],
        "summary": "Generate and return a new payment address for this node's wallet.",
        "operationId": "post_new_address",
        "responses": {
          "201": {
            "description": "A newly generated payment address",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NewAddressResponse"
                }
              }
            }
          },
          "500": {
            "description": "This node does not expose a wallet",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        },
        "security": [
          {
            "api_key": []
          }
        ]
      }
    },
    "/v1/wallet/keypairs": {
      "get": {
        "tags": [
          "wallet"
        ],
        "summary": "Export this node's known key-pairs.",
        "description": "Sensitive: this returns private keys. Protect this route with an api-key entry.",
        "operationId": "get_keypairs",
        "responses": {
          "200": {
            "description": "Hex-encoded key-pairs, keyed by payment address",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeypairsResponse"
                }
              }
            }
          },
          "500": {
            "description": "This node does not expose a wallet",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        },
        "security": [
          {
            "api_key": []
          }
        ]
      },
      "post": {
        "tags": [
          "wallet"
        ],
        "summary": "Import key-pairs into this node's wallet, then request a running-total refresh from\nthe UTXO set for the imported addresses.",
        "operationId": "post_import_keypairs",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportKeypairsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The payment addresses that were imported",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportKeypairsResponse"
                }
              }
            }
          },
          "400": {
            "description": "One of the key-pairs was not valid hex",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          },
          "500": {
            "description": "This node does not expose a wallet, the key-pairs could not be saved, or the running-total refresh could not be requested",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        },
        "security": [
          {
            "api_key": []
          }
        ]
      }
    },
    "/v1/wallet/passphrase": {
      "put": {
        "tags": [
          "wallet"
        ],
        "summary": "Change this node's wallet passphrase.",
        "operationId": "put_passphrase",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePassphraseRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Passphrase changed"
          },
          "400": {
            "description": "The new passphrase was blank",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          },
          "500": {
            "description": "This node does not expose a wallet, or the passphrase change failed",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        },
        "security": [
          {
            "api_key": []
          }
        ]
      }
    },
    "/v1/wallet/running-total:refresh": {
      "post": {
        "tags": [
          "wallet"
        ],
        "summary": "Request a running-total refresh from the UTXO set for this node's wallet.",
        "operationId": "post_running_total_refresh",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunningTotalRefreshRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "The running-total refresh was requested"
          },
          "400": {
            "description": "No addresses to refresh were resolved",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          },
          "500": {
            "description": "This node does not expose a wallet, or the running-total refresh could not be requested",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblem"
                }
              }
            }
          }
        },
        "security": [
          {
            "api_key": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AddressesQuery": {
        "type": "object",
        "description": "Request body for the batch balances lookup.",
        "required": [
          "addresses"
        ],
        "properties": {
          "addresses": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The addresses to look up."
          }
        }
      },
      "ApiAsset": {
        "oneOf": [
          {
            "type": "object",
            "description": "A quantity of the native token.",
            "required": [
              "amount",
              "kind"
            ],
            "properties": {
              "amount": {
                "type": "integer",
                "format": "int64",
                "description": "Token amount, in raw token units.",
                "minimum": 0
              },
              "kind": {
                "type": "string",
                "enum": [
                  "token"
                ]
              }
            }
          },
          {
            "type": "object",
            "description": "An item asset.",
            "required": [
              "amount",
              "kind"
            ],
            "properties": {
              "amount": {
                "type": "integer",
                "format": "int64",
                "description": "The number of items.",
                "minimum": 0
              },
              "genesis_hash": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The genesis transaction hash the item derives from, when known."
              },
              "kind": {
                "type": "string",
                "enum": [
                  "item"
                ]
              },
              "metadata": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Optional item metadata."
              }
            }
          }
        ],
        "description": "A chain asset, tagged by `kind` so each variant is fully described by the schema."
      },
      "ApiProblem": {
        "type": "object",
        "description": "An RFC 9457 `application/problem+json` error body.\n\nReplaces the legacy byte-envelope error path: the HTTP status is authoritative, and\nthis is the one typed error shape returned by every `/v1` handler.",
        "required": [
          "type",
          "title",
          "status"
        ],
        "properties": {
          "code": {
            "type": [
              "string",
              "null"
            ],
            "description": "An optional machine-readable error code."
          },
          "detail": {
            "type": [
              "string",
              "null"
            ],
            "description": "A human-readable explanation specific to this occurrence of the problem."
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "description": "The HTTP status code, duplicated here per RFC 9457.",
            "minimum": 0
          },
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem type."
          },
          "type": {
            "type": "string",
            "description": "A URI identifying the problem type; `about:blank` when none is defined."
          }
        }
      },
      "BTreeMap": {
        "type": "object",
        "additionalProperties": {
          "type": "object",
          "description": "A single transaction output: the destination address and the asset sent to it.",
          "required": [
            "address",
            "asset"
          ],
          "properties": {
            "address": {
              "type": "string",
              "description": "The output's destination address (empty when the output has no script public key)."
            },
            "asset": {
              "$ref": "#/components/schemas/ApiAsset",
              "description": "The asset held by this output."
            }
          }
        },
        "propertyNames": {
          "type": "string"
        }
      },
      "BalancesResponse": {
        "type": "object",
        "description": "UTXO balance for the requested addresses.",
        "required": [
          "balance"
        ],
        "properties": {
          "balance": {
            "type": "object",
            "description": "The combined asset totals and per-address outpoint breakdown, as returned by\nthe mempool's tracked UTXO set (`fleet_core::tracked_utxo::TrackedUtxoBalance`)."
          }
        }
      },
      "BlockchainEntryResponse": {
        "type": "object",
        "description": "A single stored blockchain entry (a block or a transaction), as kept in the\nblockchain DB.",
        "required": [
          "key",
          "item_meta",
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "description": "The entry's JSON payload, as stored alongside the binary-encoded data."
          },
          "item_meta": {
            "$ref": "#/components/schemas/BlockchainItemMetaResponse",
            "description": "Whether this entry is a block or a transaction, with its position metadata."
          },
          "key": {
            "type": "string",
            "description": "The entry's raw storage key (a transaction hash, or an indexed block key)."
          }
        }
      },
      "BlockchainItemMetaResponse": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "block_num",
              "tx_len",
              "type"
            ],
            "properties": {
              "block_num": {
                "type": "integer",
                "format": "int64",
                "minimum": 0
              },
              "tx_len": {
                "type": "integer",
                "format": "int32",
                "minimum": 0
              },
              "type": {
                "type": "string",
                "enum": [
                  "block"
                ]
              }
            }
          },
          {
            "type": "object",
            "required": [
              "block_num",
              "tx_num",
              "type"
            ],
            "properties": {
              "block_num": {
                "type": "integer",
                "format": "int64",
                "minimum": 0
              },
              "tx_num": {
                "type": "integer",
                "format": "int32",
                "minimum": 0
              },
              "type": {
                "type": "string",
                "enum": [
                  "tx"
                ]
              }
            }
          }
        ],
        "description": "Typed mirror of `fleet_core::interfaces::BlockchainItemMeta`."
      },
      "ChangePassphraseRequest": {
        "type": "object",
        "description": "Request body for `PUT /v1/wallet/passphrase`.",
        "required": [
          "old_passphrase",
          "new_passphrase"
        ],
        "properties": {
          "new_passphrase": {
            "type": "string",
            "description": "The passphrase to change to."
          },
          "old_passphrase": {
            "type": "string",
            "description": "The wallet's current passphrase."
          }
        }
      },
      "CreateItemAcceptedResponse": {
        "type": "object",
        "description": "Response body for a user-node item-asset creation request.",
        "required": [
          "item_amount"
        ],
        "properties": {
          "item_amount": {
            "type": "integer",
            "format": "int64",
            "description": "The number of items requested.",
            "minimum": 0
          }
        }
      },
      "CreateItemRequest": {
        "type": "object",
        "description": "Request body for `POST /v1/items`.",
        "required": [
          "item_amount",
          "genesis_hash_spec"
        ],
        "properties": {
          "genesis_hash_spec": {
            "type": "string"
          },
          "item_amount": {
            "type": "integer",
            "format": "int64",
            "description": "The number of items to create.",
            "minimum": 0
          },
          "metadata": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional item metadata."
          },
          "public_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "Required on a mempool node (the client-signed create); ignored on a user node."
          },
          "script_public_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "Required on a mempool node (the client-signed create); ignored on a user node."
          },
          "signature": {
            "type": [
              "string",
              "null"
            ],
            "description": "Required on a mempool node (the client-signed create); ignored on a user node."
          }
        }
      },
      "CreateItemResponse": {
        "type": "object",
        "description": "Response body for a mempool-node item-asset creation.",
        "required": [
          "asset",
          "to_address",
          "tx_hash"
        ],
        "properties": {
          "asset": {
            "$ref": "#/components/schemas/ApiAsset",
            "description": "The created item asset."
          },
          "to_address": {
            "type": "string",
            "description": "The address the item was created against."
          },
          "tx_hash": {
            "type": "string",
            "description": "The hash of the created item-asset transaction."
          }
        }
      },
      "CreateTransaction": {
        "type": "object",
        "description": "Information necessary for the creation of a Transaction\nThis API would change if types are modified.",
        "required": [
          "inputs",
          "outputs",
          "version",
          "druid_info"
        ],
        "properties": {
          "druid_info": {
            "type": "object"
          },
          "fees": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "object"
            }
          },
          "inputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateTxIn"
            },
            "description": "String to sign in each inputs"
          },
          "outputs": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "version": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "CreateTransactionsRequest": {
        "type": "object",
        "description": "Request body for `POST /v1/transactions`.",
        "required": [
          "transactions"
        ],
        "properties": {
          "transactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateTransaction"
            },
            "description": "The transactions to construct and submit."
          }
        }
      },
      "CreateTransactionsResponse": {
        "type": "object",
        "description": "Response body for `POST /v1/transactions`.",
        "required": [
          "transactions"
        ],
        "properties": {
          "transactions": {
            "$ref": "#/components/schemas/BTreeMap",
            "description": "Per-constructed-transaction output summary, keyed by transaction hash."
          }
        }
      },
      "CreateTxIn": {
        "type": "object",
        "description": "Information needed for the creaion of TxIn.\nThis API would change if types are modified.",
        "required": [
          "previous_out"
        ],
        "properties": {
          "previous_out": {
            "type": "object",
            "description": "The previous_out to use"
          },
          "script_signature": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/CreateTxInScript",
                "description": "script info"
              }
            ]
          }
        }
      },
      "CreateTxInScript": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "stack"
            ],
            "properties": {
              "stack": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PrettyStackEntry"
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "Pay2PkH"
            ],
            "properties": {
              "Pay2PkH": {
                "type": "object",
                "required": [
                  "signature",
                  "public_key"
                ],
                "properties": {
                  "address_version": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "format": "int64",
                    "description": "Optional address version field",
                    "minimum": 0
                  },
                  "public_key": {
                    "type": "string",
                    "description": "Hex encoded complete public key"
                  },
                  "signable_data": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Data to sign"
                  },
                  "signature": {
                    "type": "string",
                    "description": "Hex encoded signature"
                  }
                }
              }
            }
          }
        ],
        "description": "Information needed for the creaion of TxIn script."
      },
      "CurrentBlockResponse": {
        "type": "object",
        "description": "The latest block received for mining, if any.",
        "required": [
          "block"
        ],
        "properties": {
          "block": {
            "type": [
              "object",
              "null"
            ],
            "description": "The current mining block (`fleet_core::interfaces::BlockPoWReceived`), passed\nthrough as JSON unchanged, or `null` if no block has been received yet."
          }
        }
      },
      "DebugData": {
        "type": "object",
        "description": "Debug/introspection payload for a node: type, peers, mounted routes, and PoW\ndifficulty per route. Mirrors the legacy `debug_data` handler's `DebugData`.",
        "required": [
          "node_type",
          "node_api",
          "node_peers",
          "routes_pow"
        ],
        "properties": {
          "node_api": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The `/v1` paths mounted on this node's router."
          },
          "node_peers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PeerInfo"
            },
            "description": "Connected peers for this node (and the auxiliary node, if present)."
          },
          "node_type": {
            "type": "string",
            "description": "This node's type; `\"{type}/{aux_type}\"` when an auxiliary node is present."
          },
          "routes_pow": {
            "type": "object",
            "description": "Per-route PoW difficulty, kept for parity with the legacy payload.",
            "additionalProperties": {
              "type": "integer",
              "minimum": 0
            },
            "propertyNames": {
              "type": "string"
            }
          }
        }
      },
      "DeserializeTransactionsRequest": {
        "type": "object",
        "description": "Request body for `POST /v1/transactions:deserialize`.",
        "required": [
          "transactions"
        ],
        "properties": {
          "transactions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Hex-encoded serialized transactions."
          }
        }
      },
      "DeserializeTransactionsResponse": {
        "type": "object",
        "description": "Response body for `POST /v1/transactions:deserialize`.",
        "required": [
          "transactions"
        ],
        "properties": {
          "transactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateTransaction"
            }
          }
        }
      },
      "DonationRequest": {
        "type": "object",
        "description": "Request body for `POST /v1/donation-requests`.",
        "required": [
          "address"
        ],
        "properties": {
          "address": {
            "type": "string",
            "description": "The `ip:port` socket address of the peer to request a donation from."
          }
        }
      },
      "HashesQuery": {
        "type": "object",
        "description": "Request body for the batch transaction-status lookup.",
        "required": [
          "hashes"
        ],
        "properties": {
          "hashes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The transaction hashes to look up."
          }
        }
      },
      "ImportKeypairsRequest": {
        "type": "object",
        "description": "Request body for `POST /v1/wallet/keypairs`.",
        "required": [
          "addresses"
        ],
        "properties": {
          "addresses": {
            "type": "object",
            "description": "Hex-encoded key-pairs to import, keyed by payment address (mirrors the legacy\n`Addresses` request body / `KeypairsResponse`)."
          }
        }
      },
      "ImportKeypairsResponse": {
        "type": "object",
        "description": "The payment addresses imported by `POST /v1/wallet/keypairs`.",
        "required": [
          "imported"
        ],
        "properties": {
          "imported": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The payment addresses that were imported."
          }
        }
      },
      "JsonSerializedTransaction": {
        "type": "object",
        "description": "A Transaction which has been serialized to JSON.",
        "required": [
          "txn_hash_hex",
          "txn_hex"
        ],
        "properties": {
          "txn_hash_hex": {
            "type": "string"
          },
          "txn_hex": {
            "type": "string"
          }
        }
      },
      "KeypairsResponse": {
        "type": "object",
        "description": "Exported key-pairs, keyed by payment address.",
        "required": [
          "addresses"
        ],
        "properties": {
          "addresses": {
            "type": "object",
            "description": "Hex-encoded key-pairs, keyed by payment address\n(`fleet_wallet::AddressStoreHex`), passed through as JSON unchanged, mirroring\nthe legacy `Addresses` embed-as-JSON behaviour."
          }
        }
      },
      "KeysQuery": {
        "type": "object",
        "description": "Request body for the batch blockchain-entries lookup.",
        "required": [
          "keys"
        ],
        "properties": {
          "keys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The raw storage keys to look up."
          }
        }
      },
      "LatestBlockResponse": {
        "type": "object",
        "description": "The latest stored block.\n\nThe block payload is the pre-serialized JSON the storage node already keeps\nalongside the binary-encoded block (`StoredSerializingBlock`, from `fleet-core`),\npassed through unchanged.",
        "required": [
          "block"
        ],
        "properties": {
          "block": {
            "type": "object"
          }
        }
      },
      "NewAddressResponse": {
        "type": "object",
        "description": "A newly generated payment address.",
        "required": [
          "address"
        ],
        "properties": {
          "address": {
            "type": "string",
            "description": "The newly generated payment address."
          }
        }
      },
      "OutgoingTxsResponse": {
        "type": "object",
        "description": "This node's outgoing (constructed-and-sent) transactions, keyed by hash.",
        "required": [
          "transactions"
        ],
        "properties": {
          "transactions": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "`[hash, transaction]` pairs (`tw_chain::primitives::transaction::Transaction`),\npassed through as JSON unchanged, mirroring the legacy embed-as-JSON behaviour."
          }
        }
      },
      "PaymentAcceptedResponse": {
        "type": "object",
        "description": "Response body for `POST /v1/payments`.",
        "required": [
          "to_address",
          "amount"
        ],
        "properties": {
          "amount": {
            "$ref": "#/components/schemas/ApiAsset",
            "description": "The amount paid."
          },
          "to_address": {
            "type": "string",
            "description": "The payment target (address or ip:port, echoing the request)."
          },
          "tx_hash": {
            "type": [
              "string",
              "null"
            ],
            "description": "The constructed transaction hash (present for address payments, null for ip)."
          }
        }
      },
      "PaymentKind": {
        "type": "string",
        "description": "Which kind of payment target `PaymentRequest::address` names.",
        "enum": [
          "address",
          "ip"
        ]
      },
      "PaymentRequest": {
        "type": "object",
        "description": "Request body for `POST /v1/payments`.",
        "required": [
          "kind",
          "address",
          "amount",
          "passphrase"
        ],
        "properties": {
          "address": {
            "type": "string",
            "description": "A payment address (kind=address) or `ip:port` socket address (kind=ip)."
          },
          "amount": {
            "type": "integer",
            "format": "int64",
            "description": "Amount in raw token units.",
            "minimum": 0
          },
          "kind": {
            "$ref": "#/components/schemas/PaymentKind"
          },
          "locktime": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "minimum": 0
          },
          "passphrase": {
            "type": "string"
          }
        }
      },
      "PeerInfo": {
        "type": "object",
        "description": "A connected peer, as reported by `Node::get_peer_list` (mempool/storage peers only).",
        "required": [
          "address",
          "node_type"
        ],
        "properties": {
          "address": {
            "type": "string",
            "description": "The peer's socket address, as a string."
          },
          "node_type": {
            "type": "string",
            "description": "The peer's node type (`Mempool` or `Storage`)."
          }
        }
      },
      "PrettyStackEntry": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "Op"
            ],
            "properties": {
              "Op": {
                "type": "object"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "Signature"
            ],
            "properties": {
              "Signature": {
                "type": "string"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "PubKey"
            ],
            "properties": {
              "PubKey": {
                "type": "string"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "Num"
            ],
            "properties": {
              "Num": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          {
            "type": "object",
            "required": [
              "Bytes"
            ],
            "properties": {
              "Bytes": {
                "type": "string"
              }
            }
          }
        ],
        "description": "Stack entry enum which stores Signature and PubKey items as hex strings"
      },
      "RunningTotalRefreshRequest": {
        "type": "object",
        "description": "Request body for `POST /v1/wallet/running-total:refresh`.",
        "properties": {
          "addresses": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The specific addresses to refresh when `all` is false."
          },
          "all": {
            "type": "boolean",
            "description": "Refresh every known address (ignores `addresses` when true)."
          }
        }
      },
      "SerializeTransactionsRequest": {
        "type": "object",
        "description": "Request body for `POST /v1/transactions:serialize`.",
        "required": [
          "transactions"
        ],
        "properties": {
          "transactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateTransaction"
            },
            "description": "The transactions to serialize."
          }
        }
      },
      "SerializeTransactionsResponse": {
        "type": "object",
        "description": "Response body for `POST /v1/transactions:serialize`.",
        "required": [
          "transactions"
        ],
        "properties": {
          "transactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JsonSerializedTransaction"
            }
          }
        }
      },
      "SupplyResponse": {
        "type": "object",
        "description": "Total and issued token supply.",
        "required": [
          "total",
          "issued"
        ],
        "properties": {
          "issued": {
            "type": "integer",
            "format": "int64",
            "description": "The currently issued token supply.",
            "minimum": 0
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "The fixed total token supply.",
            "minimum": 0
          }
        }
      },
      "TxOutputSummary": {
        "type": "object",
        "description": "A single transaction output: the destination address and the asset sent to it.",
        "required": [
          "address",
          "asset"
        ],
        "properties": {
          "address": {
            "type": "string",
            "description": "The output's destination address (empty when the output has no script public key)."
          },
          "asset": {
            "$ref": "#/components/schemas/ApiAsset",
            "description": "The asset held by this output."
          }
        }
      },
      "TxStatusResponse": {
        "type": "object",
        "description": "Typed mirror of `fleet_core::interfaces::TxStatus`.",
        "required": [
          "status",
          "timestamp",
          "additional_info"
        ],
        "properties": {
          "additional_info": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/TxStatusTypeResponse"
          },
          "timestamp": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "TxStatusTypeResponse": {
        "type": "string",
        "description": "Typed mirror of `fleet_core::interfaces::TxStatusType`.",
        "enum": [
          "Pending",
          "Confirmed",
          "Rejected"
        ]
      },
      "WalletInfoQuery": {
        "type": "object",
        "description": "Query parameters for `GET /v1/wallet`.\n\nThe legacy handler overloaded a single `extra: Option<String>` request param to mean\neither \"spent\" or a page number; this splits that into two typed params. With separate\nparams both can be set at once, so we deliberately let `spent` take precedence over\n`page` (legacy never had to choose, since `extra` carried only one value).",
        "properties": {
          "page": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Which page of `transaction_pages` to return the outpoints from; defaults to the\nunpaged full transaction set when omitted.",
            "minimum": 0
          },
          "spent": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "When `true`, return spent transactions instead of the (paged or unpaged) unspent\nset."
          }
        }
      },
      "WalletInfoResponse": {
        "type": "object",
        "description": "Balance and transaction info for this node's wallet.",
        "required": [
          "running_total",
          "running_total_tokens",
          "locked_total",
          "locked_total_tokens",
          "available_total",
          "available_total_tokens",
          "item_total",
          "addresses"
        ],
        "properties": {
          "addresses": {
            "type": "object",
            "description": "Outpoints (with their held asset), keyed by owning address\n(`fleet_core::interfaces::AddressesWithOutPoints`), passed through as JSON\nunchanged (its element type has private fields, so it's serialized as-is rather\nthan remapped field-by-field), mirroring the legacy embed-as-JSON behaviour."
          },
          "available_total": {
            "type": "number",
            "format": "double",
            "description": "Tokens available to spend, in display units."
          },
          "available_total_tokens": {
            "type": "integer",
            "format": "int64",
            "description": "Tokens available to spend, in raw token units.",
            "minimum": 0
          },
          "item_total": {
            "type": "object",
            "description": "Item-asset totals, keyed by genesis hash.",
            "additionalProperties": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "locked_total": {
            "type": "number",
            "format": "double",
            "description": "Tokens currently locked (e.g. immature coinbase), in display units."
          },
          "locked_total_tokens": {
            "type": "integer",
            "format": "int64",
            "description": "Tokens currently locked, in raw token units.",
            "minimum": 0
          },
          "running_total": {
            "type": "number",
            "format": "double",
            "description": "Total tokens held, in display units."
          },
          "running_total_tokens": {
            "type": "integer",
            "format": "int64",
            "description": "Total tokens held, in raw token units.",
            "minimum": 0
          }
        }
      }
    },
    "securitySchemes": {
      "api_key": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    }
  }
}
