{ "openapi": "3.0.3", "info": { "title": "DChain Node API", "version": "0.4.0", "description": "API for reading blockchain state, submitting transactions, and using the relay mailbox. All token amounts are in micro-tokens (µT). 1 T = 1 000 000 µT." }, "servers": [{ "url": "/" }], "tags": [ { "name": "chain", "description": "V2 chain-compatible endpoints" }, { "name": "explorer", "description": "Block explorer read API" }, { "name": "relay", "description": "Encrypted relay mailbox" } ], "paths": { "/api/netstats": { "get": { "tags": ["explorer"], "summary": "Network statistics", "responses": { "200": { "description": "Aggregate chain stats", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NetStats" } } } } } } }, "/api/blocks": { "get": { "tags": ["explorer"], "summary": "Recent blocks", "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } } ], "responses": { "200": { "description": "Array of recent block summaries", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/BlockSummary" } } } } } } } }, "/api/block/{index}": { "get": { "tags": ["explorer"], "summary": "Block by index", "parameters": [ { "name": "index", "in": "path", "required": true, "schema": { "type": "integer", "format": "uint64" } } ], "responses": { "200": { "description": "Block detail", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BlockDetail" } } } }, "404": { "$ref": "#/components/responses/Error" } } } }, "/api/txs/recent": { "get": { "tags": ["explorer"], "summary": "Recent transactions", "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } } ], "responses": { "200": { "description": "Recent transactions", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/TxListEntry" } } } } } } } }, "/api/tx/{txid}": { "get": { "tags": ["explorer"], "summary": "Transaction by ID", "parameters": [ { "name": "txid", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Transaction detail", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TxDetail" } } } }, "404": { "$ref": "#/components/responses/Error" } } } }, "/api/tx": { "post": { "tags": ["explorer"], "summary": "Submit a signed transaction", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Transaction" } } } }, "responses": { "200": { "description": "Accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubmitTransactionResponse" } } } }, "400": { "$ref": "#/components/responses/Error" }, "500": { "$ref": "#/components/responses/Error" } } } }, "/api/address/{addr}": { "get": { "tags": ["explorer"], "summary": "Address balance and transactions", "description": "Accepts a DC... wallet address or hex Ed25519 public key.", "parameters": [ { "name": "addr", "in": "path", "required": true, "schema": { "type": "string" }, "description": "DC... address or hex pub key" }, { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } }, { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } } ], "responses": { "200": { "description": "Address detail", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddressDetail" } } } }, "404": { "$ref": "#/components/responses/Error" } } } }, "/api/node/{pubkey}": { "get": { "tags": ["explorer"], "summary": "Node reputation and stats", "parameters": [ { "name": "pubkey", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Hex Ed25519 pub key or DC... address" }, { "name": "window", "in": "query", "schema": { "type": "integer", "default": 200 }, "description": "Number of recent blocks to scan for rewards" } ], "responses": { "200": { "description": "Node stats", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NodeStats" } } } }, "404": { "$ref": "#/components/responses/Error" } } } }, "/api/relays": { "get": { "tags": ["explorer"], "summary": "Registered relay nodes", "description": "Returns all nodes that have submitted an REGISTER_RELAY transaction.", "responses": { "200": { "description": "List of relay nodes", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/RegisteredRelayInfo" } } } } } } } }, "/api/validators": { "get": { "tags": ["explorer"], "summary": "Active validator set", "description": "Returns the current on-chain validator set. The set changes via ADD_VALIDATOR / REMOVE_VALIDATOR transactions.", "responses": { "200": { "description": "Active validators", "content": { "application/json": { "schema": { "type": "object", "properties": { "count": { "type": "integer" }, "validators": { "type": "array", "items": { "type": "object", "properties": { "pub_key": { "type": "string" }, "address": { "type": "string" } } } } } } } } } } } }, "/api/identity/{pubkey}": { "get": { "tags": ["explorer"], "summary": "Identity info (Ed25519 + X25519 keys)", "description": "Returns identity info for a pub key or DC address. x25519_pub is populated only if the identity has submitted a REGISTER_KEY transaction with an X25519 key.", "parameters": [ { "name": "pubkey", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Hex Ed25519 pub key or DC... address" } ], "responses": { "200": { "description": "Identity info", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IdentityInfo" } } } }, "404": { "$ref": "#/components/responses/Error" } } } }, "/relay/send": { "post": { "tags": ["relay"], "summary": "Send an encrypted message via the relay node", "description": "The relay node seals the message using its own X25519 keypair (sender = relay node) and broadcasts it on gossipsub. No on-chain fee is attached.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["recipient_pub", "msg_b64"], "properties": { "recipient_pub": { "type": "string", "description": "Hex X25519 public key of the recipient" }, "msg_b64": { "type": "string", "description": "Base64-encoded plaintext message" } } } } } }, "responses": { "200": { "description": "Message sent", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Envelope ID" }, "recipient_pub": { "type": "string" }, "status": { "type": "string", "example": "sent" } } } } } }, "400": { "$ref": "#/components/responses/Error" }, "503": { "$ref": "#/components/responses/Error" } } } }, "/relay/broadcast": { "post": { "tags": ["relay"], "summary": "Broadcast a pre-sealed envelope", "description": "Light clients that seal their own NaCl-box envelopes use this to publish without a direct libp2p connection. The node stores it in the mailbox and gossips it.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["envelope"], "properties": { "envelope": { "$ref": "#/components/schemas/Envelope" } } } } } }, "responses": { "200": { "description": "Broadcast accepted", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string" }, "status": { "type": "string", "example": "broadcast" } } } } } }, "400": { "$ref": "#/components/responses/Error" }, "503": { "$ref": "#/components/responses/Error" } } } }, "/relay/inbox": { "get": { "tags": ["relay"], "summary": "List inbox envelopes", "description": "Returns envelopes stored for the given X25519 public key. Envelopes remain encrypted — the relay cannot read them.", "parameters": [ { "name": "pub", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Hex X25519 public key of the recipient" }, { "name": "since", "in": "query", "schema": { "type": "integer", "format": "int64" }, "description": "Unix timestamp — return only messages after this time" }, { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } } ], "responses": { "200": { "description": "Inbox contents", "content": { "application/json": { "schema": { "type": "object", "properties": { "pub": { "type": "string" }, "count": { "type": "integer" }, "has_more": { "type": "boolean" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/InboxItem" } } } } } } }, "400": { "$ref": "#/components/responses/Error" } } } }, "/relay/inbox/count": { "get": { "tags": ["relay"], "summary": "Count inbox envelopes", "parameters": [ { "name": "pub", "in": "query", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Envelope count", "content": { "application/json": { "schema": { "type": "object", "properties": { "pub": { "type": "string" }, "count": { "type": "integer" } } } } } } } } }, "/relay/inbox/{envID}": { "delete": { "tags": ["relay"], "summary": "Delete an envelope from the inbox", "parameters": [ { "name": "envID", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "pub", "in": "query", "required": true, "schema": { "type": "string" }, "description": "X25519 pub key of the inbox owner" } ], "responses": { "200": { "description": "Deleted", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string" }, "status": { "type": "string", "example": "deleted" } } } } } }, "400": { "$ref": "#/components/responses/Error" } } } }, "/relay/contacts": { "get": { "tags": ["relay"], "summary": "Incoming contact requests", "description": "Returns all CONTACT_REQUEST records for the given Ed25519 pub key, including pending, accepted, and blocked.", "parameters": [ { "name": "pub", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Hex Ed25519 pub key" } ], "responses": { "200": { "description": "Contact list", "content": { "application/json": { "schema": { "type": "object", "properties": { "pub": { "type": "string" }, "count": { "type": "integer" }, "contacts": { "type": "array", "items": { "$ref": "#/components/schemas/ContactInfo" } } } } } } }, "400": { "$ref": "#/components/responses/Error" } } } }, "/v2/chain/accounts/{account_id}/transactions": { "get": { "tags": ["chain"], "summary": "Account transactions", "parameters": [ { "name": "account_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 100, "minimum": 1, "maximum": 1000 } }, { "name": "order", "in": "query", "schema": { "type": "string", "enum": ["desc", "asc"], "default": "desc" } }, { "name": "after_block", "in": "query", "schema": { "type": "integer", "format": "uint64" } }, { "name": "before_block", "in": "query", "schema": { "type": "integer", "format": "uint64" } } ], "responses": { "200": { "description": "Transactions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChainTransactionsResponse" } } } }, "400": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" } } } }, "/v2/chain/transactions/{tx_id}": { "get": { "tags": ["chain"], "summary": "Transaction by ID", "parameters": [ { "name": "tx_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Transaction detail", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChainTransactionDetailResponse" } } } }, "404": { "$ref": "#/components/responses/Error" } } } }, "/v2/chain/transactions": { "post": { "tags": ["chain"], "summary": "Submit transaction", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubmitTransactionRequest" } } } }, "responses": { "200": { "description": "Accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubmitTransactionResponse" } } } }, "400": { "$ref": "#/components/responses/Error" }, "500": { "$ref": "#/components/responses/Error" } } } }, "/v2/chain/transactions/draft": { "post": { "tags": ["chain"], "summary": "Build unsigned TRANSFER draft", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DraftTransactionRequest" } } } }, "responses": { "200": { "description": "Draft", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DraftTransactionResponse" } } } }, "400": { "$ref": "#/components/responses/Error" } } } } }, "components": { "responses": { "Error": { "description": "Error response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "schemas": { "ErrorResponse": { "type": "object", "properties": { "error": { "type": "string" } }, "required": ["error"] }, "NetStats": { "type": "object", "properties": { "height": { "type": "integer" }, "total_txs": { "type": "integer" }, "total_transfers": { "type": "integer" }, "total_relay_proofs": { "type": "integer" }, "avg_block_time_ms": { "type": "number" }, "tps": { "type": "number" }, "total_supply_ut": { "type": "integer", "format": "uint64" } } }, "BlockSummary": { "type": "object", "properties": { "index": { "type": "integer", "format": "uint64" }, "hash": { "type": "string" }, "time": { "type": "string", "format": "date-time" }, "validator": { "type": "string", "description": "DC... address" }, "tx_count": { "type": "integer" }, "total_fees_ut": { "type": "integer", "format": "uint64" } } }, "BlockDetail": { "allOf": [ { "$ref": "#/components/schemas/BlockSummary" }, { "type": "object", "properties": { "prev_hash": { "type": "string" }, "validator_addr": { "type": "string" }, "transactions": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "type": { "type": "string" }, "from": { "type": "string" }, "to": { "type": "string" }, "amount_ut": { "type": "integer", "format": "uint64" }, "fee_ut": { "type": "integer", "format": "uint64" } } } } } } ] }, "TxListEntry": { "type": "object", "properties": { "id": { "type": "string" }, "type": { "type": "string", "enum": ["TRANSFER","REGISTER_KEY","RELAY_PROOF","REGISTER_RELAY","CONTACT_REQUEST","ACCEPT_CONTACT","BLOCK_CONTACT","ADD_VALIDATOR","REMOVE_VALIDATOR","HEARTBEAT","BIND_WALLET","SLASH","OPEN_PAY_CHAN","CLOSE_PAY_CHAN","BLOCK_REWARD"] }, "from": { "type": "string" }, "from_addr": { "type": "string" }, "to": { "type": "string" }, "to_addr": { "type": "string" }, "amount_ut": { "type": "integer", "format": "uint64" }, "amount": { "type": "string", "description": "Human-readable token amount" }, "fee_ut": { "type": "integer", "format": "uint64" }, "fee": { "type": "string" }, "time": { "type": "string", "format": "date-time" }, "block_index": { "type": "integer", "format": "uint64" }, "block_hash": { "type": "string" } } }, "TxDetail": { "allOf": [ { "$ref": "#/components/schemas/TxListEntry" }, { "type": "object", "properties": { "block_time": { "type": "string", "format": "date-time" }, "payload": { "description": "Decoded payload JSON (type-specific)" }, "payload_hex": { "type": "string" }, "signature_hex": { "type": "string" } } } ] }, "AddressDetail": { "type": "object", "properties": { "address": { "type": "string" }, "pub_key": { "type": "string" }, "balance_ut": { "type": "integer", "format": "uint64" }, "balance": { "type": "string" }, "tx_count": { "type": "integer" }, "offset": { "type": "integer" }, "limit": { "type": "integer" }, "has_more": { "type": "boolean" }, "next_offset": { "type": "integer" }, "transactions": { "type": "array", "items": { "$ref": "#/components/schemas/TxListEntry" } } } }, "NodeStats": { "type": "object", "properties": { "pub_key": { "type": "string" }, "address": { "type": "string" }, "node_balance_ut": { "type": "integer", "format": "uint64" }, "node_balance": { "type": "string" }, "wallet_binding_address": { "type": "string" }, "wallet_binding_balance_ut": { "type": "integer", "format": "uint64" }, "reputation_score": { "type": "integer", "format": "int64" }, "reputation_rank": { "type": "string", "enum": ["Observer","Active","Trusted","Validator"] }, "blocks_produced": { "type": "integer", "format": "uint64" }, "relay_proofs": { "type": "integer", "format": "uint64" }, "slash_count": { "type": "integer", "format": "uint64" }, "heartbeats": { "type": "integer", "format": "uint64" }, "recent_window_blocks": { "type": "integer" }, "recent_blocks_produced": { "type": "integer" }, "recent_rewards_ut": { "type": "integer", "format": "uint64" }, "recent_rewards": { "type": "string" } } }, "IdentityInfo": { "type": "object", "properties": { "pub_key": { "type": "string", "description": "Hex Ed25519 public key" }, "address": { "type": "string", "description": "DC... wallet address" }, "x25519_pub": { "type": "string", "description": "Hex Curve25519 public key for E2E encryption; empty if not published" }, "nickname": { "type": "string" }, "registered": { "type": "boolean", "description": "true if REGISTER_KEY tx was committed" } } }, "RegisteredRelayInfo": { "type": "object", "properties": { "pub_key": { "type": "string" }, "address": { "type": "string" }, "relay": { "type": "object", "properties": { "x25519_pub_key": { "type": "string" }, "fee_per_msg_ut": { "type": "integer", "format": "uint64" }, "multiaddr": { "type": "string" } } } } }, "Envelope": { "type": "object", "description": "NaCl-box sealed message envelope. Only the holder of the recipient's X25519 private key can decrypt it.", "required": ["id", "recipient_pub", "sender_pub", "nonce", "ciphertext"], "properties": { "id": { "type": "string", "description": "Hex SHA-256[:16] of nonce||ciphertext" }, "recipient_pub": { "type": "string", "description": "Hex X25519 public key of the recipient" }, "sender_pub": { "type": "string", "description": "Hex X25519 public key of the sender" }, "sender_ed25519_pub": { "type": "string", "description": "Sender's Ed25519 pub key for on-chain fee claims" }, "fee_ut": { "type": "integer", "format": "uint64", "description": "Delivery fee µT (0 = free)" }, "fee_sig": { "type": "string", "format": "byte", "description": "Ed25519 sig over FeeAuthBytes(id, fee_ut)" }, "nonce": { "type": "string", "format": "byte", "description": "24-byte NaCl nonce (base64)" }, "ciphertext": { "type": "string", "format": "byte", "description": "NaCl box ciphertext (base64)" }, "sent_at": { "type": "integer", "format": "int64", "description": "Unix timestamp" } } }, "InboxItem": { "type": "object", "properties": { "id": { "type": "string" }, "sender_pub": { "type": "string" }, "recipient_pub": { "type": "string" }, "fee_ut": { "type": "integer", "format": "uint64" }, "sent_at": { "type": "integer", "format": "int64" }, "sent_at_human": { "type": "string", "format": "date-time" }, "nonce": { "type": "string", "format": "byte" }, "ciphertext": { "type": "string", "format": "byte" } } }, "ContactInfo": { "type": "object", "properties": { "requester_pub": { "type": "string" }, "requester_addr": { "type": "string" }, "status": { "type": "string", "enum": ["pending", "accepted", "blocked"] }, "intro": { "type": "string", "description": "Optional plaintext intro (≤ 280 chars)" }, "fee_ut": { "type": "integer", "format": "uint64" }, "tx_id": { "type": "string" }, "created_at": { "type": "integer", "format": "int64" } } }, "Transaction": { "type": "object", "description": "Signed blockchain transaction. Sign the canonical JSON of the object with Signature set to null, using Ed25519.", "required": ["type", "from"], "properties": { "id": { "type": "string" }, "type": { "type": "string", "enum": ["TRANSFER","REGISTER_KEY","RELAY_PROOF","REGISTER_RELAY","CONTACT_REQUEST","ACCEPT_CONTACT","BLOCK_CONTACT","ADD_VALIDATOR","REMOVE_VALIDATOR","HEARTBEAT","BIND_WALLET","SLASH","OPEN_PAY_CHAN","CLOSE_PAY_CHAN"] }, "from": { "type": "string", "description": "Hex Ed25519 pub key of the signer" }, "to": { "type": "string", "description": "Hex Ed25519 pub key of the recipient (if applicable)" }, "amount": { "type": "integer", "format": "uint64", "description": "µT to transfer (TRANSFER, CONTACT_REQUEST)" }, "fee": { "type": "integer", "format": "uint64", "description": "µT fee to block validator (min 1000)" }, "memo": { "type": "string" }, "payload": { "type": "string", "format": "byte", "description": "Base64 JSON payload (type-specific)" }, "signature": { "type": "string", "format": "byte", "description": "Ed25519 signature over canonical bytes" }, "timestamp": { "type": "string", "format": "date-time" } } }, "SubmitTransactionRequest": { "type": "object", "properties": { "tx": { "$ref": "#/components/schemas/Transaction" }, "signed_tx": { "type": "string", "description": "Signed transaction as JSON/base64/hex string" } } }, "DraftTransactionRequest": { "type": "object", "required": ["from", "to", "amount_ut"], "properties": { "from": { "type": "string" }, "to": { "type": "string" }, "amount_ut": { "type": "integer", "format": "uint64" }, "memo": { "type": "string" }, "fee_ut": { "type": "integer", "format": "uint64", "description": "Optional; defaults to MinFee (1000 µT)" } } }, "DraftTransactionResponse": { "type": "object", "properties": { "tx": { "$ref": "#/components/schemas/Transaction" }, "sign_bytes_hex": { "type": "string" }, "sign_bytes_base64": { "type": "string" }, "note": { "type": "string" } }, "required": ["tx", "sign_bytes_hex", "sign_bytes_base64"] }, "SubmitTransactionResponse": { "type": "object", "properties": { "status": { "type": "string" }, "id": { "type": "string" } }, "required": ["status", "id"] }, "ChainTx": { "type": "object", "properties": { "id": { "type": "string" }, "type": { "type": "string" }, "memo": { "type": "string" }, "from": { "type": "string" }, "from_addr": { "type": "string" }, "to": { "type": "string" }, "to_addr": { "type": "string" }, "amount_ut": { "type": "integer", "format": "uint64" }, "fee_ut": { "type": "integer", "format": "uint64" }, "block_index": { "type": "integer", "format": "uint64" }, "block_hash": { "type": "string" }, "time": { "type": "string", "format": "date-time" } } }, "ChainTransactionsResponse": { "type": "object", "properties": { "account_id": { "type": "string" }, "account_addr": { "type": "string" }, "count": { "type": "integer" }, "order": { "type": "string" }, "limit_applied": { "type": "integer" }, "transactions": { "type": "array", "items": { "$ref": "#/components/schemas/ChainTx" } } } }, "ChainTransactionDetailResponse": { "type": "object", "properties": { "tx": { "$ref": "#/components/schemas/ChainTx" }, "payload": {}, "payload_hex": { "type": "string" }, "signature_hex": { "type": "string" } } } } } }