sui_types/
coin_registry.rs1use 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#[derive(Serialize, Deserialize, Copy, Clone, Default, PartialEq, Eq)]
26pub struct CurrencyKey(bool);
27
28#[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#[derive(Serialize, Deserialize)]
46pub enum SupplyState {
47 Fixed(u64),
48 BurnOnly(u64),
49 Unknown,
50}
51
52#[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#[derive(Serialize, Deserialize)]
66pub enum MetadataCapState {
67 Claimed(ObjectID),
68 Unclaimed,
69 Deleted,
70}
71
72#[derive(Serialize, Deserialize)]
74pub struct ExtraField {
75 pub type_: String,
76 pub value: Vec<u8>,
77}
78
79impl Currency {
80 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 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}