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