iota_types/coin_manager.rs
1// Copyright (c) 2024 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use iota_sdk_types::ObjectData;
5use serde::{Deserialize, Serialize};
6
7use crate::{
8 coin::{CoinMetadata, TreasuryCap},
9 error::IotaError,
10 id::UID,
11 object::Object,
12};
13
14/// The purpose of a CoinManager is to allow access to all
15/// properties of a Coin on-chain from within a single shared object
16/// This includes access to the total supply and metadata
17/// In addition a optional maximum supply can be set and a custom
18/// additional Metadata field can be added.
19/// Holds all related objects to a Coin in a convenient shared function.
20#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
21pub struct CoinManager {
22 /// The unique identifier of the object.
23 pub id: UID,
24 /// The original TreasuryCap object as returned by `create_currency`
25 pub treasury_cap: TreasuryCap,
26 /// Metadata object, original one from the `coin` module, if available
27 pub metadata: Option<CoinMetadata>,
28 /// Immutable Metadata object, only to be used as a last resort if the
29 /// original metadata is frozen
30 pub immutable_metadata: Option<ImmutableCoinMetadata>,
31 /// Optional maximum supply, if set you can't mint more as this number - can
32 /// only be set once
33 pub maximum_supply: Option<u64>,
34 /// Flag indicating if the supply is considered immutable (TreasuryCap is
35 /// exchanged for this)
36 pub supply_immutable: bool,
37 /// Flag indicating if the metadata is considered immutable (MetadataCap is
38 /// exchanged for this)
39 pub metadata_immutable: bool,
40}
41
42impl CoinManager {
43 pub fn from_bcs_bytes(content: &[u8]) -> Result<Self, IotaError> {
44 bcs::from_bytes(content).map_err(|err| IotaError::ObjectDeserialization {
45 error: format!("Unable to deserialize CoinManager object: {err}"),
46 })
47 }
48}
49
50/// The immutable version of CoinMetadata, used in case of migrating from frozen
51/// objects to a `CoinManager` holding the metadata.
52#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
53pub struct ImmutableCoinMetadata {
54 /// Number of decimal places the coin uses.
55 pub decimals: u8,
56 /// Name for the token
57 pub name: String,
58 /// Symbol for the token
59 pub symbol: String,
60 /// Description of the token
61 pub description: String,
62 /// URL for the token logo
63 pub icon_url: Option<String>,
64}
65
66impl TryFrom<Object> for CoinManager {
67 type Error = IotaError;
68 fn try_from(object: Object) -> Result<Self, Self::Error> {
69 TryFrom::try_from(&object)
70 }
71}
72
73impl TryFrom<&Object> for CoinManager {
74 type Error = IotaError;
75 fn try_from(object: &Object) -> Result<Self, Self::Error> {
76 if let ObjectData::Struct(o) = &object.data {
77 if o.struct_tag().is_coin_manager() {
78 return CoinManager::from_bcs_bytes(o.contents());
79 }
80 }
81
82 Err(IotaError::Type {
83 error: format!("Object type is not a CoinManager: {object:?}"),
84 })
85 }
86}