sui_types/
coin_registry.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use move_core_types::{
5    ident_str,
6    identifier::IdentStr,
7    language_storage::{StructTag, TypeTag},
8};
9use serde::{Deserialize, Serialize};
10
11use crate::{
12    SUI_COIN_REGISTRY_OBJECT_ID, SUI_FRAMEWORK_ADDRESS,
13    base_types::{ObjectID, SequenceNumber},
14    collection_types::VecMap,
15    derived_object,
16    error::SuiResult,
17    object::Owner,
18    storage::ObjectStore,
19};
20
21pub const COIN_REGISTRY_MODULE_NAME: &IdentStr = ident_str!("coin_registry");
22pub const CURRENCY_KEY_STRUCT_NAME: &IdentStr = ident_str!("CurrencyKey");
23
24/// Rust representation of `sui::coin_registry::CurrencyKey<T>`.
25#[derive(Serialize, Deserialize, Copy, Clone, Default, PartialEq, Eq)]
26pub struct CurrencyKey(bool);
27
28/// Rust representation of `sui::coin_registry::Currency<phantom T>`.
29#[derive(Serialize, Deserialize)]
30pub struct Currency {
31    pub id: ObjectID,
32    pub decimals: u8,
33    pub name: String,
34    pub symbol: String,
35    pub description: String,
36    pub icon_url: String,
37    pub supply: Option<SupplyState>,
38    pub regulated: RegulatedState,
39    pub treasury_cap_id: Option<ObjectID>,
40    pub metadata_cap_id: MetadataCapState,
41    pub extra_fields: VecMap<String, ExtraField>,
42}
43
44/// Rust representation of `sui::coin_registry::SupplyState<phantom T>`.
45#[derive(Serialize, Deserialize)]
46pub enum SupplyState {
47    Fixed(u64),
48    BurnOnly(u64),
49    Unknown,
50}
51
52/// Rust representation of `sui::coin_registry::RegulatedState`.
53#[derive(Serialize, Deserialize)]
54pub enum RegulatedState {
55    Regulated {
56        cap: ObjectID,
57        allow_global_pause: Option<bool>,
58        variant: u8,
59    },
60    Unregulated,
61    Unknown,
62}
63
64/// Rust representation of `sui::coin_registry::MetadataCapState`.
65#[derive(Serialize, Deserialize)]
66pub enum MetadataCapState {
67    Claimed(ObjectID),
68    Unclaimed,
69    Deleted,
70}
71
72/// Rust representation of `sui::coin_registry::ExtraField`.
73#[derive(Serialize, Deserialize)]
74pub struct ExtraField {
75    pub type_: String,
76    pub value: Vec<u8>,
77}
78
79impl Currency {
80    /// Derive the ObjectID for `sui::coin_registry::Currency<$coin_type>`.
81    pub fn derive_object_id(coin_type: TypeTag) -> Result<ObjectID, bcs::Error> {
82        let key = TypeTag::Struct(Box::new(StructTag {
83            address: SUI_FRAMEWORK_ADDRESS,
84            module: COIN_REGISTRY_MODULE_NAME.to_owned(),
85            name: CURRENCY_KEY_STRUCT_NAME.to_owned(),
86            type_params: vec![coin_type],
87        }));
88
89        derived_object::derive_object_id(
90            SUI_COIN_REGISTRY_OBJECT_ID,
91            &key,
92            &bcs::to_bytes(&CurrencyKey::default())?,
93        )
94    }
95
96    /// Is this `StructTag` a `sui::coin_registry::Currency<...>`?
97    pub fn is_currency(tag: &StructTag) -> bool {
98        tag.address == SUI_FRAMEWORK_ADDRESS
99            && tag.module.as_str() == "coin_registry"
100            && tag.name.as_str() == "Currency"
101    }
102}
103
104pub fn get_coin_registry_obj_initial_shared_version(
105    object_store: &dyn ObjectStore,
106) -> SuiResult<Option<SequenceNumber>> {
107    Ok(object_store
108        .get_object(&SUI_COIN_REGISTRY_OBJECT_ID)
109        .map(|obj| match obj.owner {
110            Owner::Shared {
111                initial_shared_version,
112            } => initial_shared_version,
113            _ => unreachable!("CoinRegistry object must be shared"),
114        }))
115}