Skip to main content

xrpl_mithril_codec/
lib.rs

1#![doc(html_logo_url = "https://raw.githubusercontent.com/KyleWMiller/xrpl-mithril/main/assets/mithrilLogo.png")]
2//! Binary serialization and deserialization for the XRPL protocol.
3//!
4//! This crate implements the canonical binary encoding used by the XRP Ledger
5//! for transactions, ledger objects, and other protocol messages.
6//!
7//! # Architecture
8//!
9//! - [`definitions`] — Field definitions loaded from `definitions.json`
10//! - [`field_code`] — Field ID encoding (1-3 byte headers from type_code/field_code)
11//! - [`error`] — Codec error types
12//! - [`serializer`] — Canonical binary serialization
13//! - [`deserializer`] — Binary to typed objects
14//! - [`signing`] — Signing-specific serialization with hash prefixes
15//!
16//! # Examples
17//!
18//! Serialize a transaction to binary and deserialize it back:
19//!
20//! ```
21//! use serde_json::json;
22//! use xrpl_mithril_codec::serializer::serialize_json_object;
23//! use xrpl_mithril_codec::deserializer::deserialize_object;
24//!
25//! // Build a minimal Payment transaction as JSON
26//! let tx = json!({
27//!     "TransactionType": "Payment",
28//!     "Flags": 0u32,
29//!     "Sequence": 1u32,
30//!     "Fee": "12",
31//!     "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
32//!     "Destination": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
33//!     "Amount": "1000000"
34//! });
35//!
36//! // Serialize to canonical binary
37//! let map = tx.as_object().expect("json object");
38//! let mut buf = Vec::new();
39//! serialize_json_object(map, &mut buf, false)?;
40//! assert!(!buf.is_empty());
41//!
42//! // Deserialize back to JSON
43//! let decoded = deserialize_object(&buf)?;
44//! assert_eq!(decoded.get("TransactionType").and_then(|v| v.as_str()), Some("Payment"));
45//! assert_eq!(decoded.get("Fee").and_then(|v| v.as_str()), Some("12"));
46//! assert_eq!(decoded.get("Amount").and_then(|v| v.as_str()), Some("1000000"));
47//! assert_eq!(
48//!     decoded.get("Account").and_then(|v| v.as_str()),
49//!     Some("rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh")
50//! );
51//! # Ok::<(), xrpl_mithril_codec::error::CodecError>(())
52//! ```
53//!
54//! Compute a transaction's signing hash and transaction ID:
55//!
56//! ```
57//! use serde_json::json;
58//! use xrpl_mithril_codec::signing::{signing_hash, transaction_id_hex};
59//!
60//! let tx = json!({
61//!     "TransactionType": "Payment",
62//!     "Sequence": 1u32,
63//!     "Fee": "12",
64//!     "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
65//!     "Destination": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
66//!     "Amount": "1000000",
67//!     "SigningPubKey": "ED5F5AC43F527AE97194E860E5B28E6751B0B3BBEAC0780826AAF6DB9B3EE001",
68//!     "TxnSignature": "DEADBEEFCAFE"
69//! });
70//! let map = tx.as_object().expect("json object");
71//!
72//! // Signing hash (for the signer to sign over)
73//! let hash = signing_hash(map)?;
74//! assert_eq!(hash.len(), 32);
75//!
76//! // Transaction ID (includes the signature in the hash)
77//! let tx_id = transaction_id_hex(map)?;
78//! assert_eq!(tx_id.len(), 64); // 32 bytes as uppercase hex
79//! assert!(tx_id.chars().all(|c| c.is_ascii_hexdigit()));
80//! # Ok::<(), xrpl_mithril_codec::error::CodecError>(())
81//! ```
82
83#![forbid(unsafe_code)]
84
85pub mod definitions;
86pub mod error;
87pub mod field_code;
88
89pub mod serializer;
90
91pub mod deserializer;
92pub mod signing;