Skip to main content

monero_lws/
models.rs

1// Rust Monero Light Wallet Server RPC Client
2// Written in 2021-2022 by
3//   Sebastian Kung <seb.kung@gmail.com>
4//   Monero Rust Contributors
5//
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to deal
8// in the Software without restriction, including without limitation the rights
9// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10// copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12//
13// The above copyright notice and this permission notice shall be included in all
14// copies or substantial portions of the Software.
15//
16#![allow(unexpected_cfgs)]
17
18use std::fmt;
19
20use crate::util::*;
21use monero::{cryptonote::hash::Hash as CryptoNoteHash, util::address::PaymentId};
22use serde::{
23    Deserialize, Deserializer, Serialize,
24    de::{Error as DeserializerError, Visitor},
25};
26
27macro_rules! hash_type {
28    ($name:ident, $len:expr) => {
29        ::fixed_hash::construct_fixed_hash! {
30            #[derive(::serde::Serialize, ::serde::Deserialize)]
31            pub struct $name($len);
32        }
33        hash_type_impl!($name);
34    };
35}
36
37hash_type!(BlockHash, 32);
38
39#[derive(Clone, Debug, Serialize, Deserialize)]
40pub enum Status {
41    OK,
42}
43
44#[derive(Clone, Debug, Serialize, Deserialize)]
45#[serde(tag = "status")]
46pub enum MoneroResult<T> {
47    OK(T),
48}
49
50impl<T> MoneroResult<T> {
51    pub fn into_inner(self) -> T {
52        match self {
53            MoneroResult::OK(v) => v,
54        }
55    }
56}
57
58// Compatibility with version 0.1
59fn number_or_boolean<'de, D>(deserializer: D) -> Result<bool, D::Error>
60where
61    D: Deserializer<'de>,
62{
63    struct BoolVisitor;
64
65    impl<'de> Visitor<'de> for BoolVisitor {
66        type Value = bool;
67
68        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
69            formatter.write_str("integer or boolean")
70        }
71
72        fn visit_bool<E: DeserializerError>(self, value: bool) -> Result<bool, E> {
73            Ok(value)
74        }
75
76        fn visit_u64<E: DeserializerError>(self, value: u64) -> Result<bool, E> {
77            let boolean = match value {
78                0 => false,
79                1 => true,
80                _ => {
81                    return Err(E::invalid_value(
82                        serde::de::Unexpected::Unsigned(value),
83                        &self,
84                    ));
85                }
86            };
87            Ok(boolean)
88        }
89    }
90
91    deserializer.deserialize_any(BoolVisitor)
92}
93
94#[derive(Clone, Debug, Serialize, Deserialize)]
95pub struct AddressInfo {
96    pub locked_funds: String,
97    pub total_received: String,
98    pub total_sent: String,
99    pub scanned_height: u64,
100    pub scanned_block_height: u64,
101    pub start_height: u64,
102    pub transaction_height: u64,
103    pub blockchain_height: u64,
104    pub spent_outputs: Vec<SpendObject>,
105    pub rates: Option<Rates>,
106}
107
108#[derive(Clone, Debug, Serialize, Deserialize)]
109#[allow(non_snake_case)]
110pub struct Rates {
111    pub AUD: Option<f32>,
112}
113
114#[derive(Clone, Debug, Serialize, Deserialize)]
115pub struct SpendObject {
116    pub amount: String,
117    pub key_image: HashString<CryptoNoteHash>,
118    pub tx_pub_key: HashString<CryptoNoteHash>,
119    pub out_index: u16,
120    pub mixin: u32,
121}
122
123#[derive(Clone, Debug, Serialize, Deserialize)]
124pub struct AddressTxs {
125    pub total_received: String,
126    pub scanned_height: u64,
127    pub scanned_block_height: u64,
128    pub start_height: u64,
129    pub blockchain_height: u64,
130    // May not be present in version 0.3
131    #[serde(default)]
132    pub transactions: Vec<Transaction>,
133}
134
135#[derive(Clone, Debug, Serialize, Deserialize)]
136pub struct Transaction {
137    pub id: u64,
138    pub hash: HashString<CryptoNoteHash>,
139    pub timestamp: String,
140    pub total_received: String,
141    pub total_sent: String,
142    pub unlock_time: u64,
143    pub height: Option<u64>,
144    // May not be present in version 0.3
145    #[serde(default)]
146    pub spent_outputs: Vec<SpendObject>,
147    pub payment_id: Option<HashString<PaymentId>>,
148    #[serde(deserialize_with = "number_or_boolean")]
149    pub coinbase: bool,
150    #[serde(deserialize_with = "number_or_boolean")]
151    pub mempool: bool,
152    pub mixin: u32,
153}
154
155#[derive(Clone, Debug, Serialize, Deserialize)]
156pub struct AmountOuts {
157    pub amount_outs: Vec<RandomOutput>,
158}
159
160#[derive(Clone, Debug, Serialize, Deserialize)]
161pub struct RandomOutputs {
162    pub amount: String,
163    pub outputs: Vec<RandomOutput>,
164}
165
166#[derive(Clone, Debug, Serialize, Deserialize)]
167pub struct RandomOutput {
168    pub global_index: u64,
169    pub public_key: HashString<CryptoNoteHash>,
170    pub rct: HashString<CryptoNoteHash>,
171}
172
173#[derive(Clone, Debug, Serialize, Deserialize)]
174pub struct UnspentOuts {
175    pub per_kb_fee: u64,
176    pub fee_mask: u64,
177    pub amount: String,
178    pub outputs: Vec<Output>,
179}
180
181#[derive(Clone, Debug, Serialize, Deserialize)]
182pub struct Output {
183    pub tx_id: u64,
184    pub amount: String,
185    pub index: u16,
186    pub global_index: u64,
187    pub rct: String,
188    pub tx_hash: HashString<CryptoNoteHash>,
189    pub tx_prefix_hash: String,
190    pub public_key: HashString<CryptoNoteHash>,
191    pub tx_pub_key: HashString<CryptoNoteHash>,
192    pub spend_key_images: Vec<HashString<CryptoNoteHash>>,
193    pub timestamp: String,
194    pub height: u64,
195}
196
197#[derive(Clone, Debug, Serialize, Deserialize)]
198pub struct ImportResponse {
199    pub payment_address: Option<monero::Address>,
200    pub payment_id: Option<HashString<PaymentId>>,
201    pub import_fee: Option<String>,
202    #[serde(deserialize_with = "number_or_boolean")]
203    pub new_request: bool,
204    #[serde(deserialize_with = "number_or_boolean")]
205    pub request_fulfilled: bool,
206    pub status: String,
207}
208
209#[derive(Clone, Debug, Serialize, Deserialize)]
210pub struct LoginResponse {
211    #[serde(deserialize_with = "number_or_boolean")]
212    pub new_address: bool,
213    #[serde(deserialize_with = "number_or_boolean")]
214    pub generated_locally: bool,
215    pub start_height: Option<u64>,
216}