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::{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 #[schemars(with = "TypeTagSchema")]
89 #[serde_as(as = "TypeTagSchema")]
90 pub type_: TypeTag,
91 pub value: serde_json::Value,
95}
96
97impl SerializeAs<DynamicFieldName> for DynamicFieldNameSchema {
98 fn serialize_as<S>(name: &DynamicFieldName, serializer: S) -> Result<S::Ok, S::Error>
99 where
100 S: serde::Serializer,
101 {
102 let schema = DynamicFieldNameSchema::from(name.clone());
103 schema.serialize(serializer)
104 }
105}
106
107impl<'de> DeserializeAs<'de, DynamicFieldName> for DynamicFieldNameSchema {
108 fn deserialize_as<D>(deserializer: D) -> Result<DynamicFieldName, D::Error>
109 where
110 D: serde::Deserializer<'de>,
111 {
112 let schema = DynamicFieldNameSchema::deserialize(deserializer)?;
113 Ok(DynamicFieldName::from(schema))
114 }
115}
116
117impl From<DynamicFieldName> for DynamicFieldNameSchema {
118 fn from(name: DynamicFieldName) -> Self {
119 Self {
120 type_: name.type_,
121 value: name.value,
122 }
123 }
124}
125
126impl From<DynamicFieldNameSchema> for DynamicFieldName {
127 fn from(name: DynamicFieldNameSchema) -> Self {
128 Self {
129 type_: name.type_,
130 value: name.value,
131 }
132 }
133}
134
135#[derive(Copy, Clone, Serialize, Deserialize, JsonSchema)]
136#[serde(rename = "DynamicFieldType")]
137pub enum DynamicFieldTypeSchema {
138 DynamicField,
139 DynamicObject,
140}
141
142impl SerializeAs<DynamicFieldType> for DynamicFieldTypeSchema {
143 fn serialize_as<S>(type_: &DynamicFieldType, serializer: S) -> Result<S::Ok, S::Error>
144 where
145 S: serde::Serializer,
146 {
147 let schema = DynamicFieldTypeSchema::from(*type_);
148 schema.serialize(serializer)
149 }
150}
151
152impl<'de> DeserializeAs<'de, DynamicFieldType> for DynamicFieldTypeSchema {
153 fn deserialize_as<D>(deserializer: D) -> Result<DynamicFieldType, D::Error>
154 where
155 D: serde::Deserializer<'de>,
156 {
157 let schema = DynamicFieldTypeSchema::deserialize(deserializer)?;
158 Ok(DynamicFieldType::from(schema))
159 }
160}
161
162impl From<DynamicFieldType> for DynamicFieldTypeSchema {
163 fn from(type_: DynamicFieldType) -> Self {
164 match type_ {
165 DynamicFieldType::DynamicField => Self::DynamicField,
166 DynamicFieldType::DynamicObject => Self::DynamicObject,
167 }
168 }
169}
170
171impl From<DynamicFieldTypeSchema> for DynamicFieldType {
172 fn from(type_: DynamicFieldTypeSchema) -> Self {
173 match type_ {
174 DynamicFieldTypeSchema::DynamicField => Self::DynamicField,
175 DynamicFieldTypeSchema::DynamicObject => Self::DynamicObject,
176 }
177 }
178}
179
180#[serde_as]
181#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)]
182#[serde(rename_all = "camelCase")]
183#[schemars(rename = "DynamicFieldInfo")]
184pub struct IotaDynamicFieldInfo {
185 #[schemars(with = "DynamicFieldNameSchema")]
186 #[serde_as(as = "DynamicFieldNameSchema")]
187 pub name: DynamicFieldName,
188 #[serde(flatten)]
189 pub bcs_name: BcsName,
190 #[schemars(with = "DynamicFieldTypeSchema")]
191 #[serde_as(as = "DynamicFieldTypeSchema")]
192 pub type_: DynamicFieldType,
193 pub object_type: String,
194 #[serde_as(as = "ObjectIdSchema")]
195 #[schemars(with = "ObjectIdSchema")]
196 pub object_id: ObjectId,
197 pub version: SequenceNumberU64,
198 #[serde_as(as = "Base58Schema")]
199 #[schemars(with = "Base58Schema")]
200 pub digest: iota_types::digests::ObjectDigest,
201}
202
203impl From<DynamicFieldInfo> for IotaDynamicFieldInfo {
204 fn from(
205 DynamicFieldInfo {
206 name,
207 bcs_name,
208 type_,
209 object_type,
210 object_id,
211 version,
212 digest,
213 }: DynamicFieldInfo,
214 ) -> Self {
215 Self {
216 name,
217 bcs_name: BcsName::new(bcs_name),
218 type_,
219 object_type,
220 object_id,
221 version: version.into(),
222 digest,
223 }
224 }
225}
226
227impl From<IotaDynamicFieldInfo> for DynamicFieldInfo {
228 fn from(
229 IotaDynamicFieldInfo {
230 name,
231 bcs_name,
232 type_,
233 object_type,
234 object_id,
235 version,
236 digest,
237 }: IotaDynamicFieldInfo,
238 ) -> Self {
239 Self {
240 name,
241 bcs_name: bcs_name.into_bytes(),
242 type_,
243 object_type,
244 object_id,
245 version: version.into(),
246 digest,
247 }
248 }
249}
250
251#[serde_as]
252#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, JsonSchema)]
253#[serde(rename_all = "camelCase", tag = "bcsEncoding")]
254#[serde(from = "MaybeTaggedBcsName")]
255pub enum BcsName {
256 Base64 {
257 #[serde_as(as = "Base64")]
258 #[schemars(with = "Base64Schema")]
259 #[serde(rename = "bcsName")]
260 bcs_name: Vec<u8>,
261 },
262 Base58 {
263 #[serde_as(as = "Base58")]
264 #[schemars(with = "Base58Schema")]
265 #[serde(rename = "bcsName")]
266 bcs_name: Vec<u8>,
267 },
268}
269
270impl BcsName {
271 pub fn new(bytes: Vec<u8>) -> Self {
272 Self::Base64 { bcs_name: bytes }
273 }
274
275 pub fn bytes(&self) -> &[u8] {
276 match self {
277 BcsName::Base64 { bcs_name } => bcs_name.as_ref(),
278 BcsName::Base58 { bcs_name } => bcs_name.as_ref(),
279 }
280 }
281
282 pub fn into_bytes(self) -> Vec<u8> {
283 match self {
284 BcsName::Base64 { bcs_name } => bcs_name,
285 BcsName::Base58 { bcs_name } => bcs_name,
286 }
287 }
288}
289
290#[allow(unused)]
291#[serde_as]
292#[derive(Serialize, Deserialize)]
293#[serde(rename_all = "camelCase", untagged)]
294enum MaybeTaggedBcsName {
295 Tagged(TaggedBcsName),
296 Base58 {
297 #[serde_as(as = "Base58")]
298 #[serde(rename = "bcsName")]
299 bcs_name: Vec<u8>,
300 },
301}
302
303#[serde_as]
304#[derive(Serialize, Deserialize)]
305#[serde(rename_all = "camelCase", tag = "bcsEncoding")]
306enum TaggedBcsName {
307 Base64 {
308 #[serde_as(as = "Base64")]
309 #[serde(rename = "bcsName")]
310 bcs_name: Vec<u8>,
311 },
312 Base58 {
313 #[serde_as(as = "Base58")]
314 #[serde(rename = "bcsName")]
315 bcs_name: Vec<u8>,
316 },
317}
318
319impl From<MaybeTaggedBcsName> for BcsName {
320 fn from(name: MaybeTaggedBcsName) -> BcsName {
321 let bcs_name = match name {
322 MaybeTaggedBcsName::Tagged(TaggedBcsName::Base58 { bcs_name })
323 | MaybeTaggedBcsName::Base58 { bcs_name } => bcs_name,
324 MaybeTaggedBcsName::Tagged(TaggedBcsName::Base64 { bcs_name }) => bcs_name,
325 };
326
327 Self::Base64 { bcs_name }
330 }
331}
332
333#[serde_as]
336#[derive(
337 Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
338)]
339#[schemars(rename = "AuthorityPublicKeyBytes")]
340pub struct IotaAuthorityPublicKeyBytes(
341 #[serde_as(as = "Base64")]
342 #[schemars(with = "Base64Schema")]
343 pub [u8; AuthorityPublicKey::LENGTH],
344);
345
346impl From<IotaAuthorityPublicKeyBytes> for AuthorityPublicKeyBytes {
347 fn from(value: IotaAuthorityPublicKeyBytes) -> Self {
348 Self(value.0)
349 }
350}
351
352impl From<AuthorityPublicKeyBytes> for IotaAuthorityPublicKeyBytes {
353 fn from(value: AuthorityPublicKeyBytes) -> Self {
354 Self(value.0)
355 }
356}
357
358#[cfg(test)]
359mod test {
360 use super::*;
361
362 #[test]
363 fn bcs_name_test() {
364 let bytes = vec![0, 1, 2, 3, 4];
365 let untagged_base58 = r#"{"bcsName":"12VfUX"}"#;
366 let tagged_base58 = r#"{"bcsEncoding":"base58","bcsName":"12VfUX"}"#;
367 let tagged_base64 = r#"{"bcsEncoding":"base64","bcsName":"AAECAwQ="}"#;
368
369 assert_eq!(
370 bytes,
371 serde_json::from_str::<BcsName>(untagged_base58)
372 .unwrap()
373 .into_bytes()
374 );
375 assert_eq!(
376 bytes,
377 serde_json::from_str::<BcsName>(tagged_base58)
378 .unwrap()
379 .into_bytes()
380 );
381 assert_eq!(
382 bytes,
383 serde_json::from_str::<BcsName>(tagged_base64)
384 .unwrap()
385 .into_bytes()
386 );
387
388 let name = serde_json::from_str::<BcsName>(tagged_base64).unwrap();
390 let json = serde_json::to_string(&name).unwrap();
391 let from_json = serde_json::from_str::<BcsName>(&json).unwrap();
392 assert_eq!(name, from_json);
393
394 let name = serde_json::from_str::<BcsName>(tagged_base58).unwrap();
396 let json = serde_json::to_string(&name).unwrap();
397 let from_json = serde_json::from_str::<BcsName>(&json).unwrap();
398 assert_eq!(name, from_json);
399 }
400}