sui_json_rpc_types/
lib.rs1use fastcrypto::encoding::{Base58, Base64};
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7
8pub use balance_changes::*;
9pub use object_changes::*;
10use serde_with::serde_as;
11pub use sui_checkpoint::*;
12pub use sui_coin::*;
13pub use sui_event::*;
14pub use sui_extended::*;
15pub use sui_governance::*;
16pub use sui_move::*;
17pub use sui_object::*;
18pub use sui_protocol::*;
19pub use sui_transaction::*;
20use sui_types::base_types::ObjectID;
21
22#[cfg(test)]
23#[path = "unit_tests/rpc_types_tests.rs"]
24mod rpc_types_tests;
25
26mod balance_changes;
27mod displays;
28mod object_changes;
29mod sui_checkpoint;
30mod sui_coin;
31mod sui_event;
32mod sui_extended;
33mod sui_governance;
34mod sui_move;
35mod sui_object;
36mod sui_protocol;
37mod sui_transaction;
38
39pub type DynamicFieldPage = Page<DynamicFieldInfo, ObjectID>;
40#[derive(Clone, Debug, JsonSchema, Serialize, Deserialize, PartialEq, Eq)]
44#[serde(rename_all = "camelCase")]
45pub struct Page<T, C> {
46    pub data: Vec<T>,
47    pub next_cursor: Option<C>,
48    pub has_next_page: bool,
49}
50
51impl<T, C> Page<T, C> {
52    pub fn empty() -> Self {
53        Self {
54            data: vec![],
55            next_cursor: None,
56            has_next_page: false,
57        }
58    }
59}
60
61#[serde_with::serde_as]
62#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)]
63#[serde(rename_all = "camelCase")]
64pub struct DynamicFieldInfo {
65    pub name: sui_types::dynamic_field::DynamicFieldName,
66    #[serde(flatten)]
67    pub bcs_name: BcsName,
68    pub type_: sui_types::dynamic_field::DynamicFieldType,
69    pub object_type: String,
70    pub object_id: ObjectID,
71    pub version: sui_types::base_types::SequenceNumber,
72    pub digest: sui_types::digests::ObjectDigest,
73}
74
75impl From<sui_types::dynamic_field::DynamicFieldInfo> for DynamicFieldInfo {
76    fn from(
77        sui_types::dynamic_field::DynamicFieldInfo {
78            name,
79            bcs_name,
80            type_,
81            object_type,
82            object_id,
83            version,
84            digest,
85        }: sui_types::dynamic_field::DynamicFieldInfo,
86    ) -> Self {
87        Self {
88            name,
89            bcs_name: BcsName::new(bcs_name),
90            type_,
91            object_type,
92            object_id,
93            version,
94            digest,
95        }
96    }
97}
98
99#[serde_as]
100#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, JsonSchema)]
101#[serde(rename_all = "camelCase", tag = "bcsEncoding")]
102#[serde(from = "MaybeTaggedBcsName")]
103pub enum BcsName {
104    Base64 {
105        #[serde_as(as = "Base64")]
106        #[schemars(with = "Base64")]
107        #[serde(rename = "bcsName")]
108        bcs_name: Vec<u8>,
109    },
110    Base58 {
111        #[serde_as(as = "Base58")]
112        #[schemars(with = "Base58")]
113        #[serde(rename = "bcsName")]
114        bcs_name: Vec<u8>,
115    },
116}
117
118impl BcsName {
119    pub fn new(bytes: Vec<u8>) -> Self {
120        Self::Base64 { bcs_name: bytes }
121    }
122
123    pub fn bytes(&self) -> &[u8] {
124        match self {
125            BcsName::Base64 { bcs_name } => bcs_name.as_ref(),
126            BcsName::Base58 { bcs_name } => bcs_name.as_ref(),
127        }
128    }
129
130    pub fn into_bytes(self) -> Vec<u8> {
131        match self {
132            BcsName::Base64 { bcs_name } => bcs_name,
133            BcsName::Base58 { bcs_name } => bcs_name,
134        }
135    }
136}
137
138#[allow(unused)]
139#[serde_as]
140#[derive(Serialize, Deserialize)]
141#[serde(rename_all = "camelCase", untagged)]
142enum MaybeTaggedBcsName {
143    Tagged(TaggedBcsName),
144    Base58 {
145        #[serde_as(as = "Base58")]
146        #[serde(rename = "bcsName")]
147        bcs_name: Vec<u8>,
148    },
149}
150
151#[serde_as]
152#[derive(Serialize, Deserialize)]
153#[serde(rename_all = "camelCase", tag = "bcsEncoding")]
154enum TaggedBcsName {
155    Base64 {
156        #[serde_as(as = "Base64")]
157        #[serde(rename = "bcsName")]
158        bcs_name: Vec<u8>,
159    },
160    Base58 {
161        #[serde_as(as = "Base58")]
162        #[serde(rename = "bcsName")]
163        bcs_name: Vec<u8>,
164    },
165}
166
167impl From<MaybeTaggedBcsName> for BcsName {
168    fn from(name: MaybeTaggedBcsName) -> BcsName {
169        let bcs_name = match name {
170            MaybeTaggedBcsName::Tagged(TaggedBcsName::Base58 { bcs_name })
171            | MaybeTaggedBcsName::Base58 { bcs_name } => bcs_name,
172            MaybeTaggedBcsName::Tagged(TaggedBcsName::Base64 { bcs_name }) => bcs_name,
173        };
174
175        Self::Base64 { bcs_name }
177    }
178}
179
180#[cfg(test)]
181mod test {
182    use super::*;
183
184    #[test]
185    fn bcs_name_test() {
186        let bytes = vec![0, 1, 2, 3, 4];
187        let untagged_base58 = r#"{"bcsName":"12VfUX"}"#;
188        let tagged_base58 = r#"{"bcsEncoding":"base58","bcsName":"12VfUX"}"#;
189        let tagged_base64 = r#"{"bcsEncoding":"base64","bcsName":"AAECAwQ="}"#;
190
191        println!(
192            "{}",
193            serde_json::to_string(&TaggedBcsName::Base64 {
194                bcs_name: bytes.clone()
195            })
196            .unwrap()
197        );
198
199        assert_eq!(
200            bytes,
201            serde_json::from_str::<BcsName>(untagged_base58)
202                .unwrap()
203                .into_bytes()
204        );
205        assert_eq!(
206            bytes,
207            serde_json::from_str::<BcsName>(tagged_base58)
208                .unwrap()
209                .into_bytes()
210        );
211        assert_eq!(
212            bytes,
213            serde_json::from_str::<BcsName>(tagged_base64)
214                .unwrap()
215                .into_bytes()
216        );
217
218        let name = serde_json::from_str::<BcsName>(tagged_base64).unwrap();
220        let json = serde_json::to_string(&name).unwrap();
221        let from_json = serde_json::from_str::<BcsName>(&json).unwrap();
222        assert_eq!(name, from_json);
223
224        let name = serde_json::from_str::<BcsName>(tagged_base58).unwrap();
226        let json = serde_json::to_string(&name).unwrap();
227        let from_json = serde_json::from_str::<BcsName>(&json).unwrap();
228        assert_eq!(name, from_json);
229    }
230}