xrpl_rs/types/
mod.rs

1pub mod account;
2pub mod fee;
3pub mod ledger;
4pub mod submit;
5pub mod channels;
6pub mod tx;
7pub mod subscribe;
8
9use std::convert::{TryFrom, TryInto};
10use std::num::ParseIntError;
11use std::ops::Add;
12use std::str::FromStr;
13
14use rust_decimal::Decimal;
15use serde;
16use serde::{Deserialize, Serialize};
17use serde_json::Value;
18use serde_with::skip_serializing_none;
19
20#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Default, Clone)]
21pub struct BigInt(pub u64);
22
23impl From<u64> for BigInt {
24    fn from(v: u64) -> Self {
25        Self(v)
26    }
27} 
28
29impl std::ops::Deref for BigInt {
30    type Target = u64;
31
32    fn deref(&self) -> &Self::Target {
33        &self.0
34    }
35}
36
37impl Serialize for BigInt {
38    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
39    where
40        S: serde::Serializer,
41    {
42        serializer.serialize_str(&format!("{}", self.0))
43    }
44}
45
46impl<'de> Deserialize<'de> for BigInt {
47    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
48    where
49        D: serde::de::Deserializer<'de>,
50    {
51        deserializer.deserialize_str(BigIntVisitor)
52    }
53}
54
55struct BigIntVisitor;
56
57impl<'de> serde::de::Visitor<'de> for BigIntVisitor {
58    type Value = BigInt;
59
60    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
61        formatter.write_str("an unsigned integer")
62    }
63
64    fn visit_str<E>(self, value: &str) -> std::result::Result<Self::Value, E>
65    where
66        E: serde::de::Error,
67    {
68        Ok(BigInt(value.parse().map_err(|e| {
69            serde::de::Error::custom(format!("{:?}", e))
70        })?))
71    }
72}
73
74/// An address used to identify an account.
75pub type Address = String;
76
77/// A Marker can be used to paginate the server response. It's content is intentionally undefined. Each server can define a marker as desired.
78pub type Marker = Value;
79
80pub type H256 = String;
81
82/// Unique request id.
83///
84/// NOTE Assigning same id to different requests will cause the previous request to be unsubscribed.
85pub type RequestId = u64;
86
87#[skip_serializing_none]
88#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
89pub struct LedgerInfo {
90    /// (Optional) A 20-byte hex string for the ledger version to use. (See Specifying Ledgers)
91    pub ledger_hash: Option<String>,
92    /// (Optional) The ledger index of the ledger to use, or a shortcut string to choose a ledger automatically. (See Specifying Ledgers)
93    pub ledger_index: Option<Integer>,
94    /// (Omitted if ledger_index is provided instead) The ledger index of the current in-progress ledger, which was used when retrieving this information.
95    pub ledger_current_index: Option<i64>,
96    /// (May be omitted) If true, the information in this response comes from a validated ledger version. Otherwise, the information is subject to change. New in: rippled 0.90.0
97    pub validated: Option<bool>,
98}
99
100#[derive(Debug, Clone, PartialEq, Eq, Default)]
101pub struct Integer(pub u32);
102
103impl Serialize for Integer {
104    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
105    where
106        S: serde::Serializer,
107    {
108        serializer.serialize_str(&format!("{}", self.0))
109    }
110}
111
112impl<'de> Deserialize<'de> for Integer {
113    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
114    where
115        D: serde::de::Deserializer<'de>,
116    {
117        let v = Value::deserialize(deserializer)?;
118        let n = v
119            .as_u64()
120            .or_else(|| v.as_str().and_then(|s| s.parse().ok()))
121            .ok_or_else(|| serde::de::Error::custom("non-integer"))?
122            .try_into()
123            .map_err(|_| serde::de::Error::custom("overflow"))?;
124        Ok(Integer(n))
125    }
126}
127
128#[skip_serializing_none]
129#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
130pub struct PaginationInfo {
131    /// (Optional) Limit the number of transactions to retrieve. Cannot be less than 10 or more than 400. The default is 200.
132    pub limit: Option<i64>,
133    /// (Optional) Value from a previous paginated response. Resume retrieving data where that response left off. Updated in: rippled 1.5.0.
134    pub marker: Option<Marker>,
135}
136
137#[derive(Serialize, Deserialize, Debug, Clone)]
138pub struct JsonRPCResponse<T> {
139    pub result: JsonRPCResponseResult<T>,
140}
141
142#[derive(Serialize, Deserialize, Debug, Clone)]
143#[serde(tag = "status")]
144pub enum JsonRPCResponseResult<T> {
145    #[serde(rename = "success")]
146    Success(JsonRPCSuccessResponse<T>),
147    #[serde(rename = "error")]
148    Error(ErrorResponse),
149}
150
151
152#[derive(Serialize, Deserialize, Debug, Clone)]
153#[serde(tag = "status")]
154pub enum WebsocketResponse<T> {
155    #[serde(rename = "success")]
156    Success(WebsocketSuccessResponse<T>),
157    #[serde(rename = "error")]
158    Error(ErrorResponse),
159}
160
161impl<T> WebsocketResponse<T> {
162    pub fn get_id(&self) -> Option<u64> {
163        match self {
164            Self::Success(res) => Some(res.id.to_owned()),
165            Self::Error(res) => res.id.to_owned(),
166        }
167    }
168}
169
170#[derive(Serialize, Deserialize, Debug, Clone)]
171pub struct WebsocketSuccessResponse<T> {
172    /// (WebSocket only) ID provided in the request that prompted this response
173    pub id: RequestId,
174    /// (WebSocket only) The value response indicates a direct response to an API request. Asynchronous notifications use a different value such as ledgerClosed or transaction.
175    pub r#type: Option<String>,
176    /// The result of the query; contents vary depending on the command.
177    pub result: T,
178    /// (May be omitted) If this field is provided, the value is the string load. This means the client is approaching the rate limiting threshold where the server will disconnect this client.
179    pub warning: Option<String>,
180    /// (May be omitted) If this field is provided, it contains one or more Warnings Objects with important warnings. For details, see API Warnings. New in: rippled 1.5.0
181    /// TODO: Add Warnings Object.
182    pub warnings: Option<Vec<Value>>,
183    /// (May be omitted) If true, this request and response have been forwarded from a Reporting Mode server to a P2P Mode server (and back) because the request requires data that is not available in Reporting Mode. The default is false.
184    pub forwarded: Option<bool>,
185}
186
187#[derive(Serialize, Deserialize, Debug, Clone)]
188pub struct ErrorResponse {
189    pub id: Option<RequestId>,
190    pub r#type: Option<String>,
191    pub error: Option<String>,
192}
193
194
195#[derive(Serialize, Deserialize, Debug, Clone)]
196pub struct JsonRPCSuccessResponse<T> {
197    /// The result of the query; contents vary depending on the command.
198    #[serde(flatten)]
199    pub result: T,
200    /// (May be omitted) If this field is provided, the value is the string load. This means the client is approaching the rate limiting threshold where the server will disconnect this client.
201    pub warning: Option<String>,
202    /// (May be omitted) If this field is provided, it contains one or more Warnings Objects with important warnings. For details, see API Warnings. New in: rippled 1.5.0
203    /// TODO: Add Warnings Object.
204    pub warnings: Option<Vec<Value>>,
205    /// (May be omitted) If true, this request and response have been forwarded from a Reporting Mode server to a P2P Mode server (and back) because the request requires data that is not available in Reporting Mode. The default is false.
206    pub forwarded: Option<bool>,
207}
208
209#[derive(Default, Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
210pub struct SignerList {
211    #[serde(rename = "SignerEntries")]
212    pub signer_entries: Vec<SignerEntry>,
213    #[serde(rename = "SignerQuorum")]
214    pub signer_quorum: u32,
215}
216
217#[derive(Default, Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
218pub struct SignerEntry {
219    #[serde(rename = "Account")]
220    pub account: String,
221    #[serde(rename = "SignerWeight")]
222    pub signer_weight: u16,
223}
224
225#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
226#[serde(untagged)]
227pub enum CurrencyAmount {
228    XRP(BigInt),
229    IssuedCurrency(IssuedCurrencyAmount),
230}
231
232impl CurrencyAmount {
233    pub fn xrp(drops: u64) -> Self {
234        Self::XRP(BigInt(drops))
235    }
236    pub fn issued_currency(value: Decimal, currency: &str, issuer: &Address) -> Self {
237        Self::IssuedCurrency(IssuedCurrencyAmount {
238            value,
239            currency: currency.to_owned(),
240            issuer: issuer.to_owned(),
241        })
242    }
243}
244
245impl Default for CurrencyAmount {
246    fn default() -> Self {
247        Self::XRP(BigInt::default())
248    }
249}
250
251#[derive(Default, Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
252pub struct IssuedCurrencyAmount {
253    pub value: Decimal,
254    pub currency: String,
255    pub issuer: Address,
256}
257
258#[derive(Default, Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
259pub struct TransactionEntryRequest {
260    pub tx_hash: Option<String>,
261    pub ledger_index: Option<u64>,
262    pub ledger_hash: Option<String>,
263}
264
265#[derive(Default, Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
266pub struct TransactionEntryResponse {
267    pub tx_json: Option<Value>,
268    pub ledger_index: Option<u64>,
269    pub ledger_hash: Option<String>,
270}
271
272#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
273#[serde(tag = "LedgerEntryType")]
274pub enum LedgerEntry {
275    Unknown,
276    AccountRoot(AccountRoot),
277    Check(Check),
278}
279
280impl Default for LedgerEntry {
281    fn default() -> Self {
282        Self::Unknown
283    }
284}
285
286#[derive(Default, Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
287#[serde(rename_all = "PascalCase")]
288pub struct AccountRoot {
289    /// The identifying (classic) address of this account.
290    pub account: Address,
291    /// The account's current XRP balance in drops, represented as a string.
292    pub balance: CurrencyAmount,
293    /// A bit-map of boolean flags enabled for this account.
294    pub flags: u32,
295    /// The number of objects this account owns in the ledger, which contributes to its owner reserve.
296    pub owner_count: u32,
297    /// The identifying hash of the transaction that most recently modified this object.
298    #[serde(rename = "PreviousTxnID")]
299    pub previous_txn_id: H256,
300    /// The index of the ledger that contains the transaction that most recently modified this object.
301    pub previous_txn_lgr_seq: u32,
302    /// The sequence number of the next valid transaction for this account.
303    pub sequence: u32,
304    /// (Optional) The identifying hash of the transaction most recently sent by this account. This field must be enabled to use the AccountTxnID transaction field. To enable it, send an AccountSet transaction with the asfAccountTxnID flag enabled.
305    pub account_txn_id: Option<H256>,
306    /// (Optional) A domain associated with this account. In JSON, this is the hexadecimal for the ASCII representation of the domain. Cannot be more than 256 bytes in length.
307    pub domain: Option<String>,
308    /// (Optional) The md5 hash of an email address. Clients can use this to look up an avatar through services such as Gravatar .
309    pub email_hash: Option<H256>,
310    /// (Optional) A public key that may be used to send encrypted messages to this account. In JSON, uses hexadecimal. Must be exactly 33 bytes, with the first byte indicating the key type: 0x02 or 0x03 for secp256k1 keys, 0xED for Ed25519 keys.
311    pub message_key: Option<String>,
312    /// (Optional) The address of a key pair that can be used to sign transactions for this account instead of the master key. Use a SetRegularKey transaction to change this value.
313    pub regular_key: Option<String>,
314    /// (Optional) How many Tickets this account owns in the ledger. This is updated automatically to ensure that the account stays within the hard limit of 250 Tickets at a time. This field is omitted if the account has zero Tickets. (Added by the TicketBatch amendment )
315    pub ticket_count: Option<u32>,
316    /// (Optional) How many significant digits to use for exchange rates of Offers involving currencies issued by this address. Valid values are 3 to 15, inclusive. (Added by the TickSize amendment.)
317    pub tick_size: Option<u8>,
318    /// (Optional) A transfer fee to charge other users for sending currency issued by this account to each other.
319    pub transfer_rate: Option<u32>,
320}
321
322#[derive(Default, Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
323#[serde(rename_all = "PascalCase")]
324pub struct Check {
325    /// The sender of the Check. Cashing the Check debits this address's balance.
326    pub account: Address,
327    /// The intended recipient of the Check. Only this address can cash the Check, using a CheckCash transaction.
328    pub destination: Address,
329    /// A bit-map of boolean flags enabled for this account.
330    pub flags: u32,
331}