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
23fn default_funds_in_address_balance() -> u128 {
24    0
25}
26
27#[serde_as]
28#[derive(Serialize, Deserialize, Debug, JsonSchema, PartialEq, Eq, Clone)]
29#[serde(rename_all = "camelCase")]
30pub struct Balance {
31    pub coin_type: String,
32    pub coin_object_count: usize,
33    #[schemars(with = "BigInt<u128>")]
34    #[serde_as(as = "BigInt<u128>")]
35    pub total_balance: u128,
36    // TODO: This should be removed
37    #[schemars(with = "HashMap<BigInt<u64>, BigInt<u128>>")]
38    #[serde_as(as = "HashMap<BigInt<u64>, BigInt<u128>>")]
39    pub locked_balance: HashMap<EpochId, u128>,
40
41    /// The portion of `total_balance` that resides in the address balance
42    /// rather than in the coin objects. `total_balance` is the total amount
43    /// of funds owned by the address. That is, do not add these two fields together.
44    #[schemars(with = "BigInt<u128>")]
45    #[serde_as(as = "BigInt<u128>")]
46    #[serde(default = "default_funds_in_address_balance")]
47    pub funds_in_address_balance: u128,
48}
49
50impl Balance {
51    pub fn zero(coin_type: String) -> Self {
52        Self {
53            coin_type,
54            coin_object_count: 0,
55            total_balance: 0,
56            locked_balance: HashMap::new(),
57            funds_in_address_balance: 0,
58        }
59    }
60}
61
62#[serde_as]
63#[derive(Serialize, Deserialize, Debug, JsonSchema, PartialEq, Eq, Clone)]
64#[serde(rename_all = "camelCase")]
65pub struct Coin {
66    pub coin_type: String,
67    pub coin_object_id: ObjectID,
68    #[schemars(with = "AsSequenceNumber")]
69    #[serde_as(as = "AsSequenceNumber")]
70    pub version: SequenceNumber,
71    pub digest: ObjectDigest,
72    #[schemars(with = "BigInt<u64>")]
73    #[serde_as(as = "BigInt<u64>")]
74    pub balance: u64,
75    pub previous_transaction: TransactionDigest,
76}
77
78impl Coin {
79    pub fn object_ref(&self) -> ObjectRef {
80        (self.coin_object_id, self.version, self.digest)
81    }
82}
83
84#[derive(Serialize, Deserialize, Debug, JsonSchema, Clone, PartialEq, Eq)]
85#[serde(rename_all = "camelCase")]
86pub struct SuiCoinMetadata {
87    /// Number of decimal places the coin uses.
88    pub decimals: u8,
89    /// Name for the token
90    pub name: String,
91    /// Symbol for the token
92    pub symbol: String,
93    /// Description of the token
94    pub description: String,
95    /// URL for the token logo
96    pub icon_url: Option<String>,
97    /// Object id for the CoinMetadata object
98    pub id: Option<ObjectID>,
99}
100
101impl TryFrom<Object> for SuiCoinMetadata {
102    type Error = SuiError;
103    fn try_from(object: Object) -> Result<Self, Self::Error> {
104        let metadata: CoinMetadata = object.try_into()?;
105        Ok(metadata.into())
106    }
107}
108
109impl From<CoinMetadata> for SuiCoinMetadata {
110    fn from(metadata: CoinMetadata) -> Self {
111        let CoinMetadata {
112            decimals,
113            name,
114            symbol,
115            description,
116            icon_url,
117            id,
118        } = metadata;
119        Self {
120            id: Some(*id.object_id()),
121            decimals,
122            name,
123            symbol,
124            description,
125            icon_url,
126        }
127    }
128}
129
130impl From<coin_registry::Currency> for SuiCoinMetadata {
131    fn from(currency: coin_registry::Currency) -> Self {
132        Self {
133            id: Some(currency.id),
134            decimals: currency.decimals,
135            name: currency.name,
136            symbol: currency.symbol,
137            description: currency.description,
138            icon_url: Some(currency.icon_url),
139        }
140    }
141}