sui_json_rpc_types/
sui_coin.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::collections::HashMap;
5
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8use serde_with::serde_as;
9
10use crate::Page;
11use sui_types::base_types::{
12    EpochId, ObjectDigest, ObjectID, ObjectRef, SequenceNumber, TransactionDigest,
13};
14use sui_types::coin::CoinMetadata;
15use sui_types::coin_registry;
16use sui_types::error::SuiError;
17use sui_types::object::Object;
18use sui_types::sui_serde::BigInt;
19use sui_types::sui_serde::SequenceNumber as AsSequenceNumber;
20
21pub type CoinPage = Page<Coin, String>;
22
23#[serde_as]
24#[derive(Serialize, Deserialize, Debug, JsonSchema, PartialEq, Eq, Clone)]
25#[serde(rename_all = "camelCase")]
26pub struct Balance {
27    pub coin_type: String,
28    pub coin_object_count: usize,
29    #[schemars(with = "BigInt<u128>")]
30    #[serde_as(as = "BigInt<u128>")]
31    pub total_balance: u128,
32    // TODO: This should be removed
33    #[schemars(with = "HashMap<BigInt<u64>, BigInt<u128>>")]
34    #[serde_as(as = "HashMap<BigInt<u64>, BigInt<u128>>")]
35    pub locked_balance: HashMap<EpochId, u128>,
36}
37
38impl Balance {
39    pub fn zero(coin_type: String) -> Self {
40        Self {
41            coin_type,
42            coin_object_count: 0,
43            total_balance: 0,
44            locked_balance: HashMap::new(),
45        }
46    }
47}
48
49#[serde_as]
50#[derive(Serialize, Deserialize, Debug, JsonSchema, PartialEq, Eq, Clone)]
51#[serde(rename_all = "camelCase")]
52pub struct Coin {
53    pub coin_type: String,
54    pub coin_object_id: ObjectID,
55    #[schemars(with = "AsSequenceNumber")]
56    #[serde_as(as = "AsSequenceNumber")]
57    pub version: SequenceNumber,
58    pub digest: ObjectDigest,
59    #[schemars(with = "BigInt<u64>")]
60    #[serde_as(as = "BigInt<u64>")]
61    pub balance: u64,
62    pub previous_transaction: TransactionDigest,
63}
64
65impl Coin {
66    pub fn object_ref(&self) -> ObjectRef {
67        (self.coin_object_id, self.version, self.digest)
68    }
69}
70
71#[derive(Serialize, Deserialize, Debug, JsonSchema, Clone, PartialEq, Eq)]
72#[serde(rename_all = "camelCase")]
73pub struct SuiCoinMetadata {
74    /// Number of decimal places the coin uses.
75    pub decimals: u8,
76    /// Name for the token
77    pub name: String,
78    /// Symbol for the token
79    pub symbol: String,
80    /// Description of the token
81    pub description: String,
82    /// URL for the token logo
83    pub icon_url: Option<String>,
84    /// Object id for the CoinMetadata object
85    pub id: Option<ObjectID>,
86}
87
88impl TryFrom<Object> for SuiCoinMetadata {
89    type Error = SuiError;
90    fn try_from(object: Object) -> Result<Self, Self::Error> {
91        let metadata: CoinMetadata = object.try_into()?;
92        Ok(metadata.into())
93    }
94}
95
96impl From<CoinMetadata> for SuiCoinMetadata {
97    fn from(metadata: CoinMetadata) -> Self {
98        let CoinMetadata {
99            decimals,
100            name,
101            symbol,
102            description,
103            icon_url,
104            id,
105        } = metadata;
106        Self {
107            id: Some(*id.object_id()),
108            decimals,
109            name,
110            symbol,
111            description,
112            icon_url,
113        }
114    }
115}
116
117impl From<coin_registry::Currency> for SuiCoinMetadata {
118    fn from(currency: coin_registry::Currency) -> Self {
119        Self {
120            id: Some(currency.id),
121            decimals: currency.decimals,
122            name: currency.name,
123            symbol: currency.symbol,
124            description: currency.description,
125            icon_url: Some(currency.icon_url),
126        }
127    }
128}