Module sui::coin_registry
Defines the system object for managing coin data in a central registry. This module provides a centralized way to store and manage metadata for all coin types in the Sui ecosystem, including their supply information, regulatory status, and metadata capabilities.
- Struct
CoinRegistry
- Struct
ExtraField
- Struct
CurrencyKey
- Struct
MetadataCap
- Struct
Currency
- Struct
CurrencyInitializer
- Enum
SupplyState
- Enum
RegulatedState
- Enum
MetadataCapState
- Constants
- Function
new_currency
- Function
new_currency_with_otw
- Function
claim_metadata_cap
- Function
make_regulated
- Function
make_supply_fixed_init
- Function
make_supply_burn_only_init
- Function
make_supply_fixed
- Function
make_supply_burn_only
- Function
finalize
- Function
finalize_registration
- Function
delete_metadata_cap
- Function
burn
- Function
burn_balance
- Function
set_name
- Function
set_symbol
- Function
set_description
- Function
set_icon_url
- Function
set_treasury_cap_id
- Function
migrate_legacy_metadata
- Function
update_from_legacy_metadata
- Function
delete_migrated_legacy_metadata
- Function
migrate_regulated_state_by_metadata
- Function
migrate_regulated_state_by_cap
- Function
decimals
- Function
name
- Function
symbol
- Function
description
- Function
icon_url
- Function
is_metadata_cap_claimed
- Function
is_metadata_cap_deleted
- Function
metadata_cap_id
- Function
treasury_cap_id
- Function
deny_cap_id
- Function
is_supply_fixed
- Function
is_supply_burn_only
- Function
is_regulated
- Function
total_supply
- Function
exists
- Function
coin_registry_id
- Function
create
- Macro function
is_ascii_printable
use std::address;
use std::ascii;
use std::bcs;
use std::option;
use std::string;
use std::type_name;
use std::vector;
use sui::accumulator;
use sui::address;
use sui::bag;
use sui::balance;
use sui::coin;
use sui::config;
use sui::deny_list;
use sui::derived_object;
use sui::dynamic_field;
use sui::dynamic_object_field;
use sui::event;
use sui::funds_accumulator;
use sui::hex;
use sui::object;
use sui::party;
use sui::table;
use sui::transfer;
use sui::tx_context;
use sui::types;
use sui::url;
use sui::vec_map;
use sui::vec_set;
Struct CoinRegistry
System object found at address 0xc
that stores coin data for all
registered coin types. This is a shared object that acts as a central
registry for coin metadata, supply information, and regulatory status.
public struct CoinRegistry has key
Fields
-
id: sui::object::UID
Struct ExtraField
Store only object that enables more flexible coin data registration, allowing for additional fields to be added without changing the
Currency
structure.
public struct ExtraField has store
Fields
-
0: std::type_name::TypeName
-
1: vector<u8>
Struct CurrencyKey
Key used to derive addresses when creating
Currency<T>
objects.
public struct CurrencyKey<phantom T> has copy, drop, store
Fields
Struct MetadataCap
Capability object that gates metadata (name, description, icon_url, symbol) changes in the
Currency
. It can only be created (or claimed) once, and can
be deleted to prevent changes to the Currency
metacurrency.
public struct MetadataCap<phantom T> has key, store
Fields
-
id: sui::object::UID
Struct Currency
public struct Currency<phantom T> has key
Fields
-
id: sui::object::UID
-
decimals: u8
- Number of decimal places the coin uses for display purposes.
-
name: std::string::String
- Human-readable name for the coin.
-
symbol: std::string::String
- Short symbol/ticker for the coin.
-
description: std::string::String
- Detailed description of the coin.
-
icon_url: std::string::String
- URL for the coin's icon/logo.
-
supply: std::option::Option<sui::coin_registry::SupplyState<T>>
-
Current supply state of the coin (fixed supply or unknown)
Note: We're using
Option
because
does not have drop, meaning we cannot swap out its value at a later state.SupplyState
-
regulated: sui::coin_registry::RegulatedState
- Regulatory status of the coin (regulated with deny cap or unknown)
-
treasury_cap_id: std::option::Option<sui::object::ID>
- ID of the treasury cap for this coin type, if registered.
-
metadata_cap_id: sui::coin_registry::MetadataCapState
- ID of the metadata capability for this coin type, if claimed.
-
extra_fields: sui::vec_map::VecMap<std::string::String, sui::coin_registry::ExtraField>
- Additional fields for extensibility.
Struct CurrencyInitializer
Hot potato wrapper to enforce registration after "new_currency" data creation. Destroyed in the
finalize
call and either transferred to the CoinRegistry
(in case of an OTW registration) or shared directly (for dynamically created
currencies).
public struct CurrencyInitializer<phantom T>
Fields
-
currency: sui::coin_registry::Currency<T>
-
extra_fields: sui::bag::Bag
-
is_otw: bool
Enum SupplyState
Supply state marks the type of Currency Supply, which can be
- Fixed: no minting or burning;
- BurnOnly: no minting, burning is allowed;
- Unknown: flexible (supply is controlled by its
TreasuryCap
);
public enum SupplyState<phantom T> has store
Variants
-
Variant
Fixed
- Coin has a fixed supply with the given Supply object.
-
0: sui::balance::Supply<T>
-
Variant
BurnOnly
- Coin has a supply that can ONLY decrease.
-
0: sui::balance::Supply<T>
-
Variant
Unknown
- Supply information is not yet known or registered.
Enum RegulatedState
Regulated state of a coin type.
- Regulated:
DenyCap
exists or aRegulatedCoinMetadata
used to mark currency as regulated; - Unregulated: the currency was created without deny list;
- Unknown: the regulatory status is unknown.
public enum RegulatedState has copy, drop, store
Variants
-
Variant
Regulated
-
Coin is regulated with a deny cap for address restrictions.
allow_global_pause
isNone
if the information is unknown (has not been migrated fromDenyCapV2
). -
cap: sui::object::ID
-
allow_global_pause: std::option::Option<bool>
-
variant: u8
-
Variant
Unregulated
- The coin has been created without deny list.
-
Variant
Unknown
-
Regulatory status is unknown.
Result of a legacy migration for that coin (from
constructors)coin.move
Enum MetadataCapState
State of the
MetadataCap
for a single Currency
.
public enum MetadataCapState has copy, drop, store
Variants
-
Variant
Claimed
- The metadata cap has been claimed.
-
Variant
Unclaimed
- The metadata cap has not been claimed.
-
Variant
Deleted
- The metadata cap has been claimed and then deleted.
Constants
Metadata cap already claimed
#[error]
const EMetadataCapAlreadyClaimed: vector<u8> = b"Metadata cap already claimed.";
Only the system address can create the registry
#[error]
const ENotSystemAddress: vector<u8> = b"Only the system can create the registry.";
Currency for this coin type already exists
#[error]
const ECurrencyAlreadyExists: vector<u8> = b"Currency for this coin type already exists.";
Attempt to set the deny list state permissionlessly while it has already been set.
#[error]
const EDenyListStateAlreadySet: vector<u8> = b"Cannot set the deny list state as it has already been set.";
#[error]
const EMetadataCapNotClaimed: vector<u8> = b"Cannot delete legacy metadata before claiming the `MetadataCap`.";
Attempt to update
Currency
with legacy metadata after the MetadataCap
has
been claimed. Updates are only allowed if the MetadataCap
has not yet been
claimed or deleted.
#[error]
const ECannotUpdateManagedMetadata: vector<u8> = b"Cannot update metadata whose `MetadataCap` has already been claimed.";
Attempt to set the symbol to a non-ASCII printable character
#[error]
const EInvalidSymbol: vector<u8> = b"Symbol has to be ASCII printable.";
#[error]
const EDenyCapAlreadyCreated: vector<u8> = b"Cannot claim the deny cap twice.";
Attempt to migrate legacy metadata for a
Currency
that already exists.
#[error]
const ECurrencyAlreadyRegistered: vector<u8> = b"Currency already registered.";
#[error]
const EEmptySupply: vector<u8> = b"Supply cannot be empty.";
#[error]
const ESupplyNotBurnOnly: vector<u8> = b"Cannot burn on a non burn-only supply.";
#[error]
const EInvariantViolation: vector<u8> = b"Code invariant violation.";
Incremental identifier for regulated coin versions in the deny list.
We start from 0
in the new system, which aligns with the state of DenyCapV2
.
const REGULATED_COIN_VERSION: u8 = 0;
Function new_currency
Creates a new currency.
Note: This constructor has no long term difference from
new_currency_with_otw
.
This can be called from the module that defines T
any time after it has been published.
public fun new_currency<T: key>(registry: &mut sui::coin_registry::CoinRegistry, decimals: u8, symbol: std::string::String, name: std::string::String, description: std::string::String, icon_url: std::string::String, ctx: &mut sui::tx_context::TxContext): (sui::coin_registry::CurrencyInitializer<T>, sui::coin::TreasuryCap<T>)
Implementation
public fun new_currency<T: /* internal */ key>(
registry: &mut CoinRegistry,
decimals: u8,
symbol: String,
name: String,
description: String,
icon_url: String,
ctx: &mut TxContext,
): (CurrencyInitializer<T>, TreasuryCap<T>) {
assert!(!registry.exists<T>(), ECurrencyAlreadyExists);
assert!(is_ascii_printable!(&symbol), EInvalidSymbol);
let treasury_cap = coin::new_treasury_cap(ctx);
let currency = Currency<T> {
id: derived_object::claim(&mut registry.id, CurrencyKey<T>()),
decimals,
name,
symbol,
description,
icon_url,
supply: option::some(SupplyState::Unknown),
regulated: RegulatedState::Unregulated,
treasury_cap_id: option::some(object::id(&treasury_cap)),
metadata_cap_id: MetadataCapState::Unclaimed,
extra_fields: vec_map::empty(),
};
(CurrencyInitializer { currency, is_otw: false, extra_fields: bag::new(ctx) }, treasury_cap)
}
Function new_currency_with_otw
Creates a new currency with using an OTW as proof of uniqueness.
This is a two-step operation:
is constructed in theCurrency
init
function and sent to the
;CoinRegistry
is promoted to a shared object in theCurrency
call;finalize_registration
public fun new_currency_with_otw<T: drop>(otw: T, decimals: u8, symbol: std::string::String, name: std::string::String, description: std::string::String, icon_url: std::string::String, ctx: &mut sui::tx_context::TxContext): (sui::coin_registry::CurrencyInitializer<T>, sui::coin::TreasuryCap<T>)
Implementation
public fun new_currency_with_otw<T: drop>(
otw: T,
decimals: u8,
symbol: String,
name: String,
description: String,
icon_url: String,
ctx: &mut TxContext,
): (CurrencyInitializer<T>, TreasuryCap<T>) {
assert!(sui::types::is_one_time_witness(&otw));
assert!(is_ascii_printable!(&symbol), EInvalidSymbol);
let treasury_cap = coin::new_treasury_cap(ctx);
let currency = Currency<T> {
id: object::new(ctx),
decimals,
name,
symbol,
description,
icon_url,
supply: option::some(SupplyState::Unknown),
regulated: RegulatedState::Unregulated,
treasury_cap_id: option::some(object::id(&treasury_cap)),
metadata_cap_id: MetadataCapState::Unclaimed,
extra_fields: vec_map::empty(),
};
(CurrencyInitializer { currency, is_otw: true, extra_fields: bag::new(ctx) }, treasury_cap)
}
Function claim_metadata_cap
Claim a
MetadataCap
for a coin type.
Only allowed from the owner of TreasuryCap
, and only once.
Aborts if the
MetadataCap
has already been claimed.
Deleted MetadataCap
cannot be reclaimed.
public fun claim_metadata_cap<T>(currency: &mut sui::coin_registry::Currency<T>, _: &sui::coin::TreasuryCap<T>, ctx: &mut sui::tx_context::TxContext): sui::coin_registry::MetadataCap<T>
Implementation
public fun claim_metadata_cap<T>(
currency: &mut Currency<T>,
_: &TreasuryCap<T>,
ctx: &mut TxContext,
): MetadataCap<T> {
assert!(!currency.is_metadata_cap_claimed(), EMetadataCapAlreadyClaimed);
let id = object::new(ctx);
currency.metadata_cap_id = MetadataCapState::Claimed(id.to_inner());
MetadataCap { id }
}
Function make_regulated
Allows converting a currency, on init, to regulated, which creates
a DenyCapV2
object, and a denylist entry. Sets regulated state to
Regulated
.
This action is irreversible.
public fun make_regulated<T>(init: &mut sui::coin_registry::CurrencyInitializer<T>, allow_global_pause: bool, ctx: &mut sui::tx_context::TxContext): sui::coin::DenyCapV2<T>
Implementation
public fun make_regulated<T>(
init: &mut CurrencyInitializer<T>,
allow_global_pause: bool,
ctx: &mut TxContext,
): DenyCapV2<T> {
assert!(init.currency.regulated == RegulatedState::Unregulated, EDenyCapAlreadyCreated);
let deny_cap = coin::new_deny_cap_v2<T>(allow_global_pause, ctx);
init.currency.regulated =
RegulatedState::Regulated {
cap: object::id(&deny_cap),
allow_global_pause: option::some(allow_global_pause),
variant: REGULATED_COIN_VERSION,
};
deny_cap
}
Function make_supply_fixed_init
Initializer function to make the supply fixed.
Aborts if Supply is 0
to enforce minting during initialization.
public fun make_supply_fixed_init<T>(init: &mut sui::coin_registry::CurrencyInitializer<T>, cap: sui::coin::TreasuryCap<T>)
Implementation
public fun make_supply_fixed_init<T>(init: &mut CurrencyInitializer<T>, cap: TreasuryCap<T>) {
assert!(cap.total_supply() > 0, EEmptySupply);
init.currency.make_supply_fixed(cap)
}
Function make_supply_burn_only_init
Initializer function to make the supply burn-only.
Aborts if Supply is 0
to enforce minting during initialization.
public fun make_supply_burn_only_init<T>(init: &mut sui::coin_registry::CurrencyInitializer<T>, cap: sui::coin::TreasuryCap<T>)
Implementation
public fun make_supply_burn_only_init<T>(init: &mut CurrencyInitializer<T>, cap: TreasuryCap<T>) {
assert!(cap.total_supply() > 0, EEmptySupply);
init.currency.make_supply_burn_only(cap)
}
Function make_supply_fixed
Freeze the supply by destroying the TreasuryCap
and storing it in the
Currency
.
public fun make_supply_fixed<T>(currency: &mut sui::coin_registry::Currency<T>, cap: sui::coin::TreasuryCap<T>)
Implementation
public fun make_supply_fixed<T>(currency: &mut Currency<T>, cap: TreasuryCap<T>) {
match (currency.supply.swap(SupplyState::Fixed(cap.into_supply()))) {
// Impossible: We cannot fix a supply or make a supply burn-only twice.
SupplyState::Fixed(_supply) | SupplyState::BurnOnly(_supply) => abort EInvariantViolation,
// We replaced "unknown" with fixed supply.
SupplyState::Unknown => (),
};
}
Function make_supply_burn_only
Make the supply BurnOnly
by giving up the TreasuryCap
, and allowing
burning of Coins through the
Currency
.
public fun make_supply_burn_only<T>(currency: &mut sui::coin_registry::Currency<T>, cap: sui::coin::TreasuryCap<T>)
Implementation
public fun make_supply_burn_only<T>(currency: &mut Currency<T>, cap: TreasuryCap<T>) {
match (currency.supply.swap(SupplyState::BurnOnly(cap.into_supply()))) {
// Impossible: We cannot fix a supply or make a supply burn-only twice.
SupplyState::Fixed(_supply) | SupplyState::BurnOnly(_supply) => abort EInvariantViolation,
// We replaced "unknown" with frozen supply.
SupplyState::Unknown => (),
};
}
Function finalize
Finalize the coin initialization, returning
MetadataCap
public fun finalize<T>(builder: sui::coin_registry::CurrencyInitializer<T>, ctx: &mut sui::tx_context::TxContext): sui::coin_registry::MetadataCap<T>
Implementation
public fun finalize<T>(builder: CurrencyInitializer<T>, ctx: &mut TxContext): MetadataCap<T> {
let CurrencyInitializer { mut currency, is_otw, extra_fields } = builder;
extra_fields.destroy_empty();
let id = object::new(ctx);
currency.metadata_cap_id = MetadataCapState::Claimed(id.to_inner());
if (is_otw) transfer::transfer(currency, coin_registry_id().to_address())
else transfer::share_object(currency);
MetadataCap<T> { id }
}
Function finalize_registration
The second step in the "otw" initialization of coin metadata, that takes in the
Currency<T>
that was transferred from init, and transforms it in to a
"derived address" shared object.
Can be performed by anyone.
public fun finalize_registration<T>(registry: &mut sui::coin_registry::CoinRegistry, currency: sui::transfer::Receiving<sui::coin_registry::Currency<T>>, _ctx: &mut sui::tx_context::TxContext)
Implementation
public fun finalize_registration<T>(
registry: &mut CoinRegistry,
currency: Receiving<Currency<T>>,
_ctx: &mut TxContext,
) {
// 1. Consume Currency
// 2. Re-create it with a "derived" address.
let Currency {
id,
decimals,
name,
symbol,
description,
icon_url,
supply,
regulated,
treasury_cap_id,
metadata_cap_id,
extra_fields,
} = transfer::receive(&mut registry.id, currency);
id.delete();
// Now, create the derived version of the coin currency.
transfer::share_object(Currency {
id: derived_object::claim(&mut registry.id, CurrencyKey<T>()),
decimals,
name,
symbol,
description,
icon_url,
supply,
regulated,
treasury_cap_id,
metadata_cap_id,
extra_fields,
})
}
Function delete_metadata_cap
Delete the metadata cap making further updates of
Currency
metadata impossible.
This action is IRREVERSIBLE, and the MetadataCap
can no longer be claimed.
public fun delete_metadata_cap<T>(currency: &mut sui::coin_registry::Currency<T>, cap: sui::coin_registry::MetadataCap<T>)
Implementation
public fun delete_metadata_cap<T>(currency: &mut Currency<T>, cap: MetadataCap<T>) {
let MetadataCap { id } = cap;
currency.metadata_cap_id = MetadataCapState::Deleted;
id.delete();
}
Function burn
Allows burning coins for burn-only currencies
public fun burn<T>(currency: &mut sui::coin_registry::Currency<T>, coin: sui::coin::Coin<T>)
Implementation
public fun burn<T>(currency: &mut Currency<T>, coin: Coin<T>) {
currency.burn_balance(coin.into_balance());
}
Function burn_balance
Lower level function to burn a Balance
of a burn-only
Currency
.
public fun burn_balance<T>(currency: &mut sui::coin_registry::Currency<T>, balance: sui::balance::Balance<T>)
Implementation
public fun burn_balance<T>(currency: &mut Currency<T>, balance: Balance<T>) {
assert!(currency.is_supply_burn_only(), ESupplyNotBurnOnly);
match (currency.supply.borrow_mut()) {
SupplyState::BurnOnly(supply) => { supply.decrease_supply(balance); },
_ => abort EInvariantViolation,
}
}
Function set_name
Enables a metadata cap holder to update a coin's name.
public fun set_name<T>(currency: &mut sui::coin_registry::Currency<T>, _: &sui::coin_registry::MetadataCap<T>, name: std::string::String)
Function set_symbol
Enables a metadata cap holder to update a coin's symbol.
public fun set_symbol<T>(currency: &mut sui::coin_registry::Currency<T>, _: &sui::coin_registry::MetadataCap<T>, symbol: std::string::String)
Implementation
public fun set_symbol<T>(currency: &mut Currency<T>, _: &MetadataCap<T>, symbol: String) {
assert!(is_ascii_printable!(&symbol), EInvalidSymbol);
currency.symbol = symbol;
}
Function set_description
Enables a metadata cap holder to update a coin's description.
public fun set_description<T>(currency: &mut sui::coin_registry::Currency<T>, _: &sui::coin_registry::MetadataCap<T>, description: std::string::String)
Implementation
public fun set_description<T>(currency: &mut Currency<T>, _: &MetadataCap<T>, description: String) {
currency.description = description;
}
Function set_icon_url
Enables a metadata cap holder to update a coin's icon URL.
public fun set_icon_url<T>(currency: &mut sui::coin_registry::Currency<T>, _: &sui::coin_registry::MetadataCap<T>, icon_url: std::string::String)
Implementation
public fun set_icon_url<T>(currency: &mut Currency<T>, _: &MetadataCap<T>, icon_url: String) {
currency.icon_url = icon_url;
}
Function set_treasury_cap_id
Register the treasury cap ID for a coin type at a later point.
public fun set_treasury_cap_id<T>(currency: &mut sui::coin_registry::Currency<T>, cap: &sui::coin::TreasuryCap<T>)
Implementation
public fun set_treasury_cap_id<T>(currency: &mut Currency<T>, cap: &TreasuryCap<T>) {
currency.treasury_cap_id.fill(object::id(cap));
}
Function migrate_legacy_metadata
Register CoinMetadata
in the Registry
. This can happen only once, if the
Currency
did not exist yet. Further updates are possible through
update_from_legacy_metadata
.
public fun migrate_legacy_metadata<T>(registry: &mut sui::coin_registry::CoinRegistry, legacy: &sui::coin::CoinMetadata<T>, _ctx: &mut sui::tx_context::TxContext)
Implementation
public fun migrate_legacy_metadata<T>(
registry: &mut CoinRegistry,
legacy: &CoinMetadata<T>,
_ctx: &mut TxContext,
) {
assert!(!registry.exists<T>(), ECurrencyAlreadyRegistered);
assert!(is_ascii_printable!(&legacy.get_symbol().to_string()), EInvalidSymbol);
transfer::share_object(Currency<T> {
id: derived_object::claim(&mut registry.id, CurrencyKey<T>()),
decimals: legacy.get_decimals(),
name: legacy.get_name(),
symbol: legacy.get_symbol().to_string(),
description: legacy.get_description(),
icon_url: legacy
.get_icon_url()
.map!(|url| url.inner_url().to_string())
.destroy_or!(b"".to_string()),
supply: option::some(SupplyState::Unknown),
regulated: RegulatedState::Unknown, // We don't know if it's regulated or not!
treasury_cap_id: option::none(),
metadata_cap_id: MetadataCapState::Unclaimed,
extra_fields: vec_map::empty(),
});
}
Function update_from_legacy_metadata
Update
Currency
from CoinMetadata
as long as the MetadataCap
is not claimed.
public fun update_from_legacy_metadata<T>(currency: &mut sui::coin_registry::Currency<T>, legacy: &sui::coin::CoinMetadata<T>)
Implementation
public fun update_from_legacy_metadata<T>(currency: &mut Currency<T>, legacy: &CoinMetadata<T>) {
assert!(!currency.is_metadata_cap_claimed(), ECannotUpdateManagedMetadata);
currency.name = legacy.get_name();
currency.symbol = legacy.get_symbol().to_string();
currency.description = legacy.get_description();
currency.decimals = legacy.get_decimals();
currency.icon_url =
legacy.get_icon_url().map!(|url| url.inner_url().to_string()).destroy_or!(b"".to_string());
}
Function delete_migrated_legacy_metadata
Delete the legacy CoinMetadata
object if the metadata cap for the new registry
has already been claimed.
This function is only callable after there's "proof" that the author of the coin can manage the metadata using the registry system (so having a metadata cap claimed).
public fun delete_migrated_legacy_metadata<T>(currency: &mut sui::coin_registry::Currency<T>, legacy: sui::coin::CoinMetadata<T>)
Implementation
public fun delete_migrated_legacy_metadata<T>(currency: &mut Currency<T>, legacy: CoinMetadata<T>) {
assert!(currency.is_metadata_cap_claimed(), EMetadataCapNotClaimed);
legacy.destroy_metadata();
}
Function migrate_regulated_state_by_metadata
Allow migrating the regulated state by access to RegulatedCoinMetadata
frozen object.
This is a permissionless operation which can be performed only once.
public fun migrate_regulated_state_by_metadata<T>(currency: &mut sui::coin_registry::Currency<T>, metadata: &sui::coin::RegulatedCoinMetadata<T>)
Implementation
public fun migrate_regulated_state_by_metadata<T>(
currency: &mut Currency<T>,
metadata: &RegulatedCoinMetadata<T>,
) {
// Only allow if this hasn't been migrated before.
assert!(currency.regulated == RegulatedState::Unknown, EDenyListStateAlreadySet);
currency.regulated =
RegulatedState::Regulated {
cap: metadata.deny_cap_id(),
allow_global_pause: option::none(),
variant: REGULATED_COIN_VERSION,
};
}
Function migrate_regulated_state_by_cap
Allow migrating the regulated state by a DenyCapV2
object.
public fun migrate_regulated_state_by_cap<T>(currency: &mut sui::coin_registry::Currency<T>, cap: &sui::coin::DenyCapV2<T>)
Implementation
public fun migrate_regulated_state_by_cap<T>(currency: &mut Currency<T>, cap: &DenyCapV2<T>) {
currency.regulated =
RegulatedState::Regulated {
cap: object::id(cap),
allow_global_pause: option::some(cap.allow_global_pause()),
variant: REGULATED_COIN_VERSION,
};
}
Function decimals
Get the number of decimal places for the coin type.
public fun decimals<T>(currency: &sui::coin_registry::Currency<T>): u8
Function name
Get the human-readable name of the coin.
public fun name<T>(currency: &sui::coin_registry::Currency<T>): std::string::String
Function symbol
Get the symbol/ticker of the coin.
public fun symbol<T>(currency: &sui::coin_registry::Currency<T>): std::string::String
Function description
Get the description of the coin.
public fun description<T>(currency: &sui::coin_registry::Currency<T>): std::string::String
Implementation
public fun description<T>(currency: &Currency<T>): String {
currency.description
}
Function icon_url
Get the icon URL for the coin.
public fun icon_url<T>(currency: &sui::coin_registry::Currency<T>): std::string::String
Function is_metadata_cap_claimed
Check if the metadata capability has been claimed for this
Currency
type.
public fun is_metadata_cap_claimed<T>(currency: &sui::coin_registry::Currency<T>): bool
Implementation
public fun is_metadata_cap_claimed<T>(currency: &Currency<T>): bool {
match (currency.metadata_cap_id) {
MetadataCapState::Claimed(_) | MetadataCapState::Deleted => true,
_ => false,
}
}
Function is_metadata_cap_deleted
Check if the metadata capability has been deleted for this
Currency
type.
public fun is_metadata_cap_deleted<T>(currency: &sui::coin_registry::Currency<T>): bool
Implementation
public fun is_metadata_cap_deleted<T>(currency: &Currency<T>): bool {
match (currency.metadata_cap_id) {
MetadataCapState::Deleted => true,
_ => false,
}
}
Function metadata_cap_id
Get the metadata cap ID, or none if it has not been claimed.
public fun metadata_cap_id<T>(currency: &sui::coin_registry::Currency<T>): std::option::Option<sui::object::ID>
Implementation
public fun metadata_cap_id<T>(currency: &Currency<T>): Option<ID> {
match (currency.metadata_cap_id) {
MetadataCapState::Claimed(id) => option::some(id),
_ => option::none(),
}
}
Function treasury_cap_id
Get the treasury cap ID for this coin type, if registered.
public fun treasury_cap_id<T>(currency: &sui::coin_registry::Currency<T>): std::option::Option<sui::object::ID>
Implementation
public fun treasury_cap_id<T>(currency: &Currency<T>): Option<ID> {
currency.treasury_cap_id
}
Function deny_cap_id
Get the deny cap ID for this coin type, if it's a regulated coin.
public fun deny_cap_id<T>(currency: &sui::coin_registry::Currency<T>): std::option::Option<sui::object::ID>
Implementation
public fun deny_cap_id<T>(currency: &Currency<T>): Option<ID> {
match (currency.regulated) {
RegulatedState::Regulated { cap, .. } => option::some(cap),
RegulatedState::Unregulated | RegulatedState::Unknown => option::none(),
}
}
Function is_supply_fixed
Check if the supply is fixed.
public fun is_supply_fixed<T>(currency: &sui::coin_registry::Currency<T>): bool
Implementation
public fun is_supply_fixed<T>(currency: &Currency<T>): bool {
match (currency.supply.borrow()) {
SupplyState::Fixed(_) => true,
_ => false,
}
}
Function is_supply_burn_only
Check if the supply is burn-only.
public fun is_supply_burn_only<T>(currency: &sui::coin_registry::Currency<T>): bool
Implementation
public fun is_supply_burn_only<T>(currency: &Currency<T>): bool {
match (currency.supply.borrow()) {
SupplyState::BurnOnly(_) => true,
_ => false,
}
}
Function is_regulated
Check if the currency is regulated.
public fun is_regulated<T>(currency: &sui::coin_registry::Currency<T>): bool
Implementation
public fun is_regulated<T>(currency: &Currency<T>): bool {
match (currency.regulated) {
RegulatedState::Regulated { .. } => true,
_ => false,
}
}
Function total_supply
Get the total supply for the
Currency<T>
if the Supply is in fixed or
burn-only state. Returns None
if the SupplyState is Unknown.
public fun total_supply<T>(currency: &sui::coin_registry::Currency<T>): std::option::Option<u64>
Implementation
public fun total_supply<T>(currency: &Currency<T>): Option<u64> {
match (currency.supply.borrow()) {
SupplyState::Fixed(supply) => option::some(supply.value()),
SupplyState::BurnOnly(supply) => option::some(supply.value()),
SupplyState::Unknown => option::none(),
}
}
Function exists
Check if coin data exists for the given type T in the registry.
public fun exists<T>(registry: &sui::coin_registry::CoinRegistry): bool
Implementation
public fun exists<T>(registry: &CoinRegistry): bool {
derived_object::exists(®istry.id, CurrencyKey<T>())
}
Function coin_registry_id
Return the ID of the system
CoinRegistry
object located at address 0xc.
public fun coin_registry_id(): sui::object::ID
Implementation
public fun coin_registry_id(): ID {
@0xc.to_id()
}
Function create
Create and share the singleton Registry -- this function is called exactly once, during the upgrade epoch. Only the system address (0x0) can create the registry.
fun create(ctx: &sui::tx_context::TxContext)
Implementation
fun create(ctx: &TxContext) {
assert!(ctx.sender() == @0x0, ENotSystemAddress);
transfer::share_object(CoinRegistry {
id: object::sui_coin_registry_object_id(),
});
}
Macro function is_ascii_printable
Nit: consider adding this function to
std::string
in the future.
macro fun is_ascii_printable($s: &std::string::String): bool
Implementation
macro fun is_ascii_printable($s: &String): bool {
let s = $s;
s.as_bytes().all!(|b| ascii::is_printable_char(*b))
}