1use iota_sdk_types::{ObjectDigest, ObjectId, ObjectReference, TransactionDigest, Version};
6use iota_types::{
7 balance::Supply, coin::CoinMetadata, error::IotaError,
8 messages_checkpoint::CheckpointSequenceNumber, object::Object,
9};
10use schemars::JsonSchema;
11use serde::{Deserialize, Serialize};
12use serde_with::{DeserializeAs, DisplayFromStr, SerializeAs, serde_as};
13
14use crate::{
15 Page,
16 iota_primitives::{
17 Base58 as Base58Schema, ObjectId as ObjectIdSchema,
18 SequenceNumberString as SequenceNumberStringSchema,
19 },
20};
21
22pub type CoinPage = Page<Coin, ObjectId>;
23
24#[serde_as]
25#[derive(Clone, Serialize, Deserialize, JsonSchema)]
26#[schemars(rename = "Supply")]
27pub struct IotaSupply {
28 #[serde_as(as = "DisplayFromStr")]
29 #[schemars(with = "String")]
30 pub value: u64,
31}
32
33impl SerializeAs<Supply> for IotaSupply {
34 fn serialize_as<S>(source: &Supply, serializer: S) -> Result<S::Ok, S::Error>
35 where
36 S: serde::Serializer,
37 {
38 IotaSupply::from(source.clone()).serialize(serializer)
39 }
40}
41
42impl<'de> DeserializeAs<'de, Supply> for IotaSupply {
43 fn deserialize_as<D>(deserializer: D) -> Result<Supply, D::Error>
44 where
45 D: serde::Deserializer<'de>,
46 {
47 let schema = IotaSupply::deserialize(deserializer)?;
48 Ok(Supply::from(schema))
49 }
50}
51
52impl From<Supply> for IotaSupply {
53 fn from(supply: Supply) -> Self {
54 Self {
55 value: supply.value,
56 }
57 }
58}
59
60impl From<IotaSupply> for Supply {
61 fn from(schema: IotaSupply) -> Self {
62 Self {
63 value: schema.value,
64 }
65 }
66}
67
68#[serde_as]
69#[derive(Serialize, Deserialize, Debug, JsonSchema, PartialEq, Eq, Clone)]
70#[serde(rename_all = "camelCase")]
71pub struct Balance {
72 pub coin_type: String,
73 pub coin_object_count: usize,
74 #[schemars(with = "String")]
75 #[serde_as(as = "DisplayFromStr")]
76 pub total_balance: u128,
77}
78
79impl Balance {
80 pub fn zero(coin_type: String) -> Self {
81 Self {
82 coin_type,
83 coin_object_count: 0,
84 total_balance: 0,
85 }
86 }
87}
88
89#[serde_as]
90#[derive(Serialize, Deserialize, Debug, JsonSchema, PartialEq, Eq, Clone)]
91#[serde(rename_all = "camelCase")]
92pub struct Coin {
93 pub coin_type: String,
94 #[serde_as(as = "ObjectIdSchema")]
95 #[schemars(with = "ObjectIdSchema")]
96 pub coin_object_id: ObjectId,
97 #[serde_as(as = "SequenceNumberStringSchema")]
98 #[schemars(with = "SequenceNumberStringSchema")]
99 pub version: Version,
100 #[serde_as(as = "Base58Schema")]
101 #[schemars(with = "Base58Schema")]
102 pub digest: ObjectDigest,
103 #[schemars(with = "String")]
104 #[serde_as(as = "DisplayFromStr")]
105 pub balance: u64,
106 #[serde_as(as = "Base58Schema")]
107 #[schemars(with = "Base58Schema")]
108 pub previous_transaction: TransactionDigest,
109}
110
111impl Coin {
112 pub fn object_ref(&self) -> ObjectReference {
113 ObjectReference::new(self.coin_object_id, self.version, self.digest)
114 }
115}
116
117#[serde_as]
118#[derive(Serialize, Deserialize, Debug, JsonSchema, Clone, PartialEq, Eq)]
119#[serde(rename_all = "camelCase")]
120pub struct IotaCoinMetadata {
121 pub decimals: u8,
123 pub name: String,
125 pub symbol: String,
127 pub description: String,
129 pub icon_url: Option<String>,
131 #[serde_as(as = "Option<ObjectIdSchema>")]
133 #[schemars(with = "Option<ObjectIdSchema>")]
134 pub id: Option<ObjectId>,
135}
136
137impl TryFrom<Object> for IotaCoinMetadata {
138 type Error = IotaError;
139 fn try_from(object: Object) -> Result<Self, Self::Error> {
140 let metadata: CoinMetadata = object.try_into()?;
141 Ok(metadata.into())
142 }
143}
144
145impl From<CoinMetadata> for IotaCoinMetadata {
146 fn from(metadata: CoinMetadata) -> Self {
147 let CoinMetadata {
148 decimals,
149 name,
150 symbol,
151 description,
152 icon_url,
153 id,
154 } = metadata;
155 Self {
156 id: Some(*id.object_id()),
157 decimals,
158 name,
159 symbol,
160 description,
161 icon_url,
162 }
163 }
164}
165
166#[serde_as]
168#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
169#[serde(rename_all = "camelCase")]
170pub struct IotaCirculatingSupply {
171 pub value: u64,
173 pub circulating_supply_percentage: f64,
176 pub at_checkpoint: CheckpointSequenceNumber,
178}