1pub use balance_changes::*;
6use fastcrypto::{
7 encoding::{Base58, Base64},
8 traits::VerifyingKey,
9};
10pub use iota_checkpoint::*;
11pub use iota_coin::*;
12pub use iota_event::*;
13pub use iota_extended::*;
14pub use iota_gas_cost_summary::*;
15pub use iota_governance::*;
16pub use iota_indexer::*;
17pub use iota_move::*;
18pub use iota_object::*;
19pub use iota_object_response_error::*;
20pub use iota_owner::*;
21use iota_primitives::{
22 Base58 as Base58Schema, Base64 as Base64Schema, ObjectId as ObjectIdSchema, SequenceNumberU64,
23 TypeTag as TypeTagSchema,
24};
25pub use iota_protocol::*;
26use iota_sdk_types::{ObjectDigest, ObjectId, TypeTag};
27pub use iota_system_state_summary::*;
28pub use iota_transaction::*;
29use iota_types::{
30 crypto::{AuthorityPublicKey, AuthorityPublicKeyBytes},
31 dynamic_field::{DynamicFieldInfo, DynamicFieldName, DynamicFieldType},
32};
33pub use object_changes::*;
34use schemars::JsonSchema;
35use serde::{Deserialize, Serialize};
36use serde_with::{DeserializeAs, SerializeAs, serde_as};
37
38#[cfg(test)]
39#[path = "unit_tests/rpc_types_tests.rs"]
40mod rpc_types_tests;
41
42mod balance_changes;
43mod displays;
44mod iota_checkpoint;
45mod iota_coin;
46mod iota_event;
47mod iota_extended;
48mod iota_gas_cost_summary;
49mod iota_governance;
50mod iota_indexer;
51mod iota_move;
52mod iota_object;
53mod iota_object_response_error;
54mod iota_owner;
55pub mod iota_primitives;
56mod iota_protocol;
57mod iota_system_state_summary;
58mod iota_transaction;
59mod object_changes;
60
61pub type DynamicFieldPage = Page<IotaDynamicFieldInfo, ObjectId>;
62
63#[derive(Clone, Debug, JsonSchema, Serialize, Deserialize, PartialEq, Eq)]
67#[serde(rename_all = "camelCase")]
68pub struct Page<T, C> {
69 pub data: Vec<T>,
70 pub next_cursor: Option<C>,
71 pub has_next_page: bool,
72}
73
74impl<T, C> Page<T, C> {
75 pub fn empty() -> Self {
76 Self {
77 data: vec![],
78 next_cursor: None,
79 has_next_page: false,
80 }
81 }
82}
83
84#[serde_as]
85#[derive(Clone, Serialize, Deserialize, JsonSchema)]
86#[serde(rename_all = "camelCase", rename = "DynamicFieldName")]
87pub struct DynamicFieldNameSchema {
88 #[serde(rename = "type")]
89 #[schemars(with = "TypeTagSchema")]
90 #[serde_as(as = "TypeTagSchema")]
91 pub type_tag: TypeTag,
92 pub value: serde_json::Value,
96}
97
98impl SerializeAs<DynamicFieldName> for DynamicFieldNameSchema {
99 fn serialize_as<S>(name: &DynamicFieldName, serializer: S) -> Result<S::Ok, S::Error>
100 where
101 S: serde::Serializer,
102 {
103 let schema = DynamicFieldNameSchema::from(name.clone());
104 schema.serialize(serializer)
105 }
106}
107
108impl<'de> DeserializeAs<'de, DynamicFieldName> for DynamicFieldNameSchema {
109 fn deserialize_as<D>(deserializer: D) -> Result<DynamicFieldName, D::Error>
110 where
111 D: serde::Deserializer<'de>,
112 {
113 let schema = DynamicFieldNameSchema::deserialize(deserializer)?;
114 Ok(DynamicFieldName::from(schema))
115 }
116}
117
118impl From<DynamicFieldName> for DynamicFieldNameSchema {
119 fn from(name: DynamicFieldName) -> Self {
120 Self {
121 type_tag: name.type_tag,
122 value: name.value,
123 }
124 }
125}
126
127impl From<DynamicFieldNameSchema> for DynamicFieldName {
128 fn from(name: DynamicFieldNameSchema) -> Self {
129 Self {
130 type_tag: name.type_tag,
131 value: name.value,
132 }
133 }
134}
135
136#[derive(Copy, Clone, Serialize, Deserialize, JsonSchema)]
137#[serde(rename = "DynamicFieldType")]
138pub enum DynamicFieldTypeSchema {
139 DynamicField,
140 DynamicObject,
141}
142
143impl SerializeAs<DynamicFieldType> for DynamicFieldTypeSchema {
144 fn serialize_as<S>(type_: &DynamicFieldType, serializer: S) -> Result<S::Ok, S::Error>
145 where
146 S: serde::Serializer,
147 {
148 let schema = DynamicFieldTypeSchema::from(*type_);
149 schema.serialize(serializer)
150 }
151}
152
153impl<'de> DeserializeAs<'de, DynamicFieldType> for DynamicFieldTypeSchema {
154 fn deserialize_as<D>(deserializer: D) -> Result<DynamicFieldType, D::Error>
155 where
156 D: serde::Deserializer<'de>,
157 {
158 let schema = DynamicFieldTypeSchema::deserialize(deserializer)?;
159 Ok(DynamicFieldType::from(schema))
160 }
161}
162
163impl From<DynamicFieldType> for DynamicFieldTypeSchema {
164 fn from(type_: DynamicFieldType) -> Self {
165 match type_ {
166 DynamicFieldType::DynamicField => Self::DynamicField,
167 DynamicFieldType::DynamicObject => Self::DynamicObject,
168 }
169 }
170}
171
172impl From<DynamicFieldTypeSchema> for DynamicFieldType {
173 fn from(type_: DynamicFieldTypeSchema) -> Self {
174 match type_ {
175 DynamicFieldTypeSchema::DynamicField => Self::DynamicField,
176 DynamicFieldTypeSchema::DynamicObject => Self::DynamicObject,
177 }
178 }
179}
180
181#[serde_as]
182#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)]
183#[serde(rename_all = "camelCase")]
184#[schemars(rename = "DynamicFieldInfo")]
185pub struct IotaDynamicFieldInfo {
186 #[schemars(with = "DynamicFieldNameSchema")]
187 #[serde_as(as = "DynamicFieldNameSchema")]
188 pub name: DynamicFieldName,
189 #[serde(flatten)]
190 pub bcs_name: BcsName,
191 #[schemars(with = "DynamicFieldTypeSchema")]
192 #[serde_as(as = "DynamicFieldTypeSchema")]
193 pub type_: DynamicFieldType,
194 pub object_type: String,
195 #[serde_as(as = "ObjectIdSchema")]
196 #[schemars(with = "ObjectIdSchema")]
197 pub object_id: ObjectId,
198 pub version: SequenceNumberU64,
199 #[serde_as(as = "Base58Schema")]
200 #[schemars(with = "Base58Schema")]
201 pub digest: ObjectDigest,
202}
203
204impl From<DynamicFieldInfo> for IotaDynamicFieldInfo {
205 fn from(
206 DynamicFieldInfo {
207 name,
208 bcs_name,
209 type_,
210 object_type,
211 object_id,
212 version,
213 digest,
214 }: DynamicFieldInfo,
215 ) -> Self {
216 Self {
217 name,
218 bcs_name: BcsName::new(bcs_name),
219 type_,
220 object_type,
221 object_id,
222 version: version.into(),
223 digest,
224 }
225 }
226}
227
228impl From<IotaDynamicFieldInfo> for DynamicFieldInfo {
229 fn from(
230 IotaDynamicFieldInfo {
231 name,
232 bcs_name,
233 type_,
234 object_type,
235 object_id,
236 version,
237 digest,
238 }: IotaDynamicFieldInfo,
239 ) -> Self {
240 Self {
241 name,
242 bcs_name: bcs_name.into_bytes(),
243 type_,
244 object_type,
245 object_id,
246 version: version.into(),
247 digest,
248 }
249 }
250}
251
252#[serde_as]
253#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, JsonSchema)]
254#[serde(rename_all = "camelCase", tag = "bcsEncoding")]
255#[serde(from = "MaybeTaggedBcsName")]
256pub enum BcsName {
257 Base64 {
258 #[serde_as(as = "Base64")]
259 #[schemars(with = "Base64Schema")]
260 #[serde(rename = "bcsName")]
261 bcs_name: Vec<u8>,
262 },
263 Base58 {
264 #[serde_as(as = "Base58")]
265 #[schemars(with = "Base58Schema")]
266 #[serde(rename = "bcsName")]
267 bcs_name: Vec<u8>,
268 },
269}
270
271impl BcsName {
272 pub fn new(bytes: Vec<u8>) -> Self {
273 Self::Base64 { bcs_name: bytes }
274 }
275
276 pub fn bytes(&self) -> &[u8] {
277 match self {
278 BcsName::Base64 { bcs_name } => bcs_name.as_ref(),
279 BcsName::Base58 { bcs_name } => bcs_name.as_ref(),
280 }
281 }
282
283 pub fn into_bytes(self) -> Vec<u8> {
284 match self {
285 BcsName::Base64 { bcs_name } => bcs_name,
286 BcsName::Base58 { bcs_name } => bcs_name,
287 }
288 }
289}
290
291#[allow(unused)]
292#[serde_as]
293#[derive(Serialize, Deserialize)]
294#[serde(rename_all = "camelCase", untagged)]
295enum MaybeTaggedBcsName {
296 Tagged(TaggedBcsName),
297 Base58 {
298 #[serde_as(as = "Base58")]
299 #[serde(rename = "bcsName")]
300 bcs_name: Vec<u8>,
301 },
302}
303
304#[serde_as]
305#[derive(Serialize, Deserialize)]
306#[serde(rename_all = "camelCase", tag = "bcsEncoding")]
307enum TaggedBcsName {
308 Base64 {
309 #[serde_as(as = "Base64")]
310 #[serde(rename = "bcsName")]
311 bcs_name: Vec<u8>,
312 },
313 Base58 {
314 #[serde_as(as = "Base58")]
315 #[serde(rename = "bcsName")]
316 bcs_name: Vec<u8>,
317 },
318}
319
320impl From<MaybeTaggedBcsName> for BcsName {
321 fn from(name: MaybeTaggedBcsName) -> BcsName {
322 let bcs_name = match name {
323 MaybeTaggedBcsName::Tagged(TaggedBcsName::Base58 { bcs_name })
324 | MaybeTaggedBcsName::Base58 { bcs_name } => bcs_name,
325 MaybeTaggedBcsName::Tagged(TaggedBcsName::Base64 { bcs_name }) => bcs_name,
326 };
327
328 Self::Base64 { bcs_name }
331 }
332}
333
334#[serde_as]
337#[derive(
338 Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
339)]
340#[schemars(rename = "AuthorityPublicKeyBytes")]
341pub struct IotaAuthorityPublicKeyBytes(
342 #[serde_as(as = "Base64")]
343 #[schemars(with = "Base64Schema")]
344 pub [u8; AuthorityPublicKey::LENGTH],
345);
346
347impl From<IotaAuthorityPublicKeyBytes> for AuthorityPublicKeyBytes {
348 fn from(value: IotaAuthorityPublicKeyBytes) -> Self {
349 Self(value.0)
350 }
351}
352
353impl From<AuthorityPublicKeyBytes> for IotaAuthorityPublicKeyBytes {
354 fn from(value: AuthorityPublicKeyBytes) -> Self {
355 Self(value.0)
356 }
357}
358
359#[cfg(test)]
360mod test {
361 use super::*;
362
363 #[test]
364 fn bcs_name_test() {
365 let bytes = vec![0, 1, 2, 3, 4];
366 let untagged_base58 = r#"{"bcsName":"12VfUX"}"#;
367 let tagged_base58 = r#"{"bcsEncoding":"base58","bcsName":"12VfUX"}"#;
368 let tagged_base64 = r#"{"bcsEncoding":"base64","bcsName":"AAECAwQ="}"#;
369
370 assert_eq!(
371 bytes,
372 serde_json::from_str::<BcsName>(untagged_base58)
373 .unwrap()
374 .into_bytes()
375 );
376 assert_eq!(
377 bytes,
378 serde_json::from_str::<BcsName>(tagged_base58)
379 .unwrap()
380 .into_bytes()
381 );
382 assert_eq!(
383 bytes,
384 serde_json::from_str::<BcsName>(tagged_base64)
385 .unwrap()
386 .into_bytes()
387 );
388
389 let name = serde_json::from_str::<BcsName>(tagged_base64).unwrap();
391 let json = serde_json::to_string(&name).unwrap();
392 let from_json = serde_json::from_str::<BcsName>(&json).unwrap();
393 assert_eq!(name, from_json);
394
395 let name = serde_json::from_str::<BcsName>(tagged_base58).unwrap();
397 let json = serde_json::to_string(&name).unwrap();
398 let from_json = serde_json::from_str::<BcsName>(&json).unwrap();
399 assert_eq!(name, from_json);
400 }
401}