xrpl/core/binarycodec/
mod.rs

1//! Functions for encoding objects into the XRP Ledger's
2//! canonical binary format and decoding them.
3
4pub mod definitions;
5pub mod types;
6
7use types::{AccountId, STObject};
8
9use alloc::{borrow::Cow, string::String, vec::Vec};
10use core::convert::TryFrom;
11use hex::ToHex;
12use serde::Serialize;
13
14pub mod binary_wrappers;
15pub mod exceptions;
16pub(crate) mod test_cases;
17pub mod utils;
18
19pub use binary_wrappers::*;
20
21use crate::XRPLSerdeJsonError;
22
23use super::exceptions::XRPLCoreResult;
24
25const TRANSACTION_SIGNATURE_PREFIX: i32 = 0x53545800;
26const TRANSACTION_MULTISIG_PREFIX: [u8; 4] = (0x534D5400u32).to_be_bytes();
27
28pub fn encode<T>(signed_transaction: &T) -> XRPLCoreResult<String>
29where
30    T: Serialize,
31{
32    serialize_json(signed_transaction, None, None, false)
33}
34
35pub fn encode_for_signing<T>(prepared_transaction: &T) -> XRPLCoreResult<String>
36where
37    T: Serialize,
38{
39    serialize_json(
40        prepared_transaction,
41        Some(TRANSACTION_SIGNATURE_PREFIX.to_be_bytes().as_ref()),
42        None,
43        true,
44    )
45}
46
47pub fn encode_for_multisigning<T>(
48    prepared_transaction: &T,
49    signing_account: Cow<'_, str>,
50) -> XRPLCoreResult<String>
51where
52    T: Serialize,
53{
54    let signing_account_id = AccountId::try_from(signing_account.as_ref()).unwrap();
55
56    serialize_json(
57        prepared_transaction,
58        Some(TRANSACTION_MULTISIG_PREFIX.as_ref()),
59        Some(signing_account_id.as_ref()),
60        true,
61    )
62}
63
64fn serialize_json<T>(
65    prepared_transaction: &T,
66    prefix: Option<&[u8]>,
67    suffix: Option<&[u8]>,
68    signing_only: bool,
69) -> XRPLCoreResult<String>
70where
71    T: Serialize,
72{
73    let mut buffer = Vec::new();
74    if let Some(p) = prefix {
75        buffer.extend(p);
76    }
77
78    let json_value =
79        serde_json::to_value(prepared_transaction).map_err(XRPLSerdeJsonError::from)?;
80    // dbg!(&json_value);
81    let st_object = STObject::try_from_value(json_value, signing_only)?;
82    buffer.extend(st_object.as_ref());
83
84    if let Some(s) = suffix {
85        buffer.extend(s);
86    }
87    let hex_string = buffer.encode_hex_upper::<String>();
88
89    Ok(hex_string)
90}