Skip to main content

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.

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
Click to open
Fields

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
Click to open
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
Click to open
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
Click to open
Fields

Struct Currency

public struct Currency<phantom T> has key
Click to open
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
SupplyState
does not have drop, meaning we cannot swap out its value at a later state.
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>
Click to open
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
Click to open
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 a RegulatedCoinMetadata 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
Click to open
Variants
Variant Regulated
Coin is regulated with a deny cap for address restrictions. allow_global_pause is None if the information is unknown (has not been migrated from DenyCapV2).
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
coin.move
constructors)

Enum MetadataCapState

State of the

MetadataCap
for a single
Currency
.

public enum MetadataCapState has copy, drop, store
Click to open
Variants
Variant Claimed
The metadata cap has been claimed.
0: sui::object::ID
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>)
Click to open
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:

  1. Currency
    is constructed in the init function and sent to the
    CoinRegistry
    ;
  2. Currency
    is promoted to a shared object in the
    finalize_registration
    call;
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>)
Click to open
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>
Click to open
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>
Click to open
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>)
Click to open
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>)
Click to open
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>)
Click to open
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>)
Click to open
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>
Click to open
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)
Click to open
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>)
Click to open
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>)
Click to open
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>)
Click to open
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)
Click to open
Implementation
public fun set_name<T>(currency: &mut Currency<T>, _: &MetadataCap<T>, name: String) {
    currency.name = name;
}

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)
Click to open
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)
Click to open
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)
Click to open
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>)
Click to open
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)
Click to open
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>)
Click to open
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>)
Click to open
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>)
Click to open
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>)
Click to open
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
Click to open
Implementation
public fun decimals<T>(currency: &Currency<T>): u8 { currency.decimals }

Function name

Get the human-readable name of the coin.

public fun name<T>(currency: &sui::coin_registry::Currency<T>): std::string::String
Click to open
Implementation
public fun name<T>(currency: &Currency<T>): String { currency.name }

Function symbol

Get the symbol/ticker of the coin.

public fun symbol<T>(currency: &sui::coin_registry::Currency<T>): std::string::String
Click to open
Implementation
public fun symbol<T>(currency: &Currency<T>): String { currency.symbol }

Function description

Get the description of the coin.

public fun description<T>(currency: &sui::coin_registry::Currency<T>): std::string::String
Click to open
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
Click to open
Implementation
public fun icon_url<T>(currency: &Currency<T>): String { currency.icon_url }

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
Click to open
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
Click to open
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>
Click to open
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>
Click to open
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>
Click to open
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
Click to open
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
Click to open
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
Click to open
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>
Click to open
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
Click to open
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
Click to open
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)
Click to open
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
Click to open
Implementation
macro fun is_ascii_printable($s: &String): bool {
    let s = $s;
    s.as_bytes().all!(|b| ascii::is_printable_char(*b))
}