Skip to main content

dig_rpc_protocol/
lib.rs

1//! # dig-rpc-protocol
2//!
3//! The **canonical DIG-node JSON-RPC protocol** (formerly `dig-rpc-types`). This
4//! crate is the single
5//! source of truth both DIG node implementations (the digstore `dig-node` crate
6//! and the standalone `dig-node` binary) depend on instead of hand-rolling
7//! `json!({…})` shapes and ad-hoc error codes:
8//!
9//! - the JSON-RPC 2.0 [`envelope`] — [`JsonRpcRequest`],
10//!   [`JsonRpcResponse`], [`RequestId`], [`Version`];
11//! - the canonical [error taxonomy](error) — [`ErrorCode`], the
12//!   [`RpcError`] envelope (`{code, message, data:{code, origin}}`), and the one
13//!   constructor helper both nodes call;
14//! - the [method catalogue](method) — [`Method`] with stable wire names, the
15//!   per-method [`Tier`], and the mTLS peer allowlist;
16//! - the [wire types](types) for every method's params + results, field-for-field
17//!   with the canonical node (network-profile-only fields `Option` + doc-flagged);
18//! - the shape-dispatched [peer frame families](frames) — the DHT and PEX wires;
19//! - the [OpenRPC 1.2.6 generator](openrpc) — the single discovery document,
20//!   generated from the tables above so discovery can never drift.
21//!
22//! ## What does NOT live here
23//!
24//! - **No I/O, no async, no server logic.** No axum, no tokio, no transport. The
25//!   [`dig-rpc`](https://crates.io/crates/dig-rpc) server crate and the node
26//!   implementations build on these types. This crate MUST NOT depend on any
27//!   server or service crate.
28//! - **No crypto.** Hex identifiers are `String` on the wire; length/charset
29//!   validation is the consumer's boundary responsibility.
30//!
31//! ## Stability
32//!
33//! 1. [`ErrorCode`] and [`Method`] are `#[non_exhaustive]`; adding a code /
34//!    method is additive (match with `_ => …`).
35//! 2. [`ErrorCode`] numeric values and machine codes never change once assigned.
36//! 3. Method wire names are stable.
37//! 4. The tier map and the peer allowlist mirror the canonical node exactly.
38//!
39//! ## Example — build and inspect an error envelope
40//!
41//! ```
42//! use dig_rpc_protocol::{RpcError, ErrorCode, ErrorOrigin};
43//!
44//! let e = RpcError::of(ErrorCode::ResourceUnavailable, "not at this root");
45//! assert_eq!(e.code, ErrorCode::ResourceUnavailable);
46//! assert_eq!(e.data.code, "RESOURCE_UNAVAILABLE");
47//! assert_eq!(e.data.origin, ErrorOrigin::Node);
48//! ```
49
50#![forbid(unsafe_code)]
51#![warn(missing_docs)]
52
53pub mod envelope;
54pub mod error;
55pub mod frames;
56pub mod method;
57pub mod openrpc;
58pub mod tier;
59pub mod types;
60
61// Re-export the most-used items at the crate root.
62pub use envelope::{JsonRpcRequest, JsonRpcResponse, JsonRpcResponseBody, RequestId, Version};
63pub use error::{ErrorCode, ErrorData, ErrorOrigin, RpcError};
64pub use method::Method;
65pub use openrpc::{openrpc_document, OPENRPC_VERSION};
66pub use tier::Tier;
67
68/// The interface (wire-schema) version this crate defines. Bumped only on a
69/// wire-breaking change; additive changes leave it untouched.
70pub const INTERFACE_VERSION: &str = "1";