Skip to content

Checking access...

DOM Token API Reference ​

Version: 2.0 Date: 2026-04-06 Canister: dom-token Candid Interface: dom_token.did

bl-1404 reconciliation (2026-08-25): this page unifies the former dom-token-api.md (comprehensive guide) and dom-token.md (Candid quick-reference) into a single reference. All method names and signatures below are arbitrated against the live src/dom_token.did on origin/main; drifted signatures were corrected and the full live method surface is listed in Complete method surface.


Overview ​

The dom-token canister implements the ICRC-1 fungible token standard for Decentralized Otter Money (DOM), the native token of the Hello World DAO ecosystem. This API provides standard token operations plus advanced policy-based burn mechanics for deflationary tokenomics.

Key Features ​

  • ICRC-1 Compliance: Full implementation of Internet Computer ICRC-1 fungible token standard
  • Fixed Supply: Genesis-minted supply with admin-gated distribution methods; no open public minting
  • Policy-Based Burns: Five specialized burn policies for ecosystem activities
  • USD-Denominated Burns: Burn a target USD value at the governance-reported DOM price (BL-076.2)
  • Authorization Framework: Role-based access control for burn operations
  • Deflationary Economics: Systematic token burns reduce circulating supply over time
  • Unminting Wallet (HeldBurn): Marketplace burns held for a dispute window; donation burns remain immediate and permanent
  • Upgrade Safety: State persistence through canister upgrades (export_state / import_state)

Token Specifications ​

PropertyValue
NameDecentralized Otter Money
SymbolDOM
Decimals8
Transfer Fee0.0001 DOM (10,000 smallest units)
Minting AccountNone (fixed supply)
StandardICRC-1

⚑ The genesis total-supply figure is set at deployment; confirm the exact live value with icrc1_total_supply() rather than a hard-coded constant.


Authentication ​

All methods use caller principal authentication via ic_cdk::caller(). Administrative operations require the caller to be the admin principal set at canister initialization.

Access Levels ​

  • Public: Any caller can invoke
  • Authenticated: Requires valid account balance
  • Authorized Burner: Caller must be in authorized burners list
  • Admin Only: Caller must be the admin principal

Data Types ​

Core Types ​

Account ​

candid
type Account = record {
    owner : principal;
    subaccount : opt blob;
};

Fields:

  • owner: Principal that owns this account
  • subaccount: Optional 32-byte subaccount identifier for account derivation

Purpose: ICRC-1 standard account identifier combining principal and optional subaccount.

TransferArgs ​

candid
type TransferArgs = record {
    from_subaccount : opt blob;
    to : Account;
    amount : nat;
    fee : opt nat;
    memo : opt blob;
    created_at_time : opt nat64;
};

Fields:

  • from_subaccount: Caller's subaccount to transfer from (optional)
  • to: Recipient account (required)
  • amount: Amount to transfer in smallest units (required)
  • fee: Expected fee, must match icrc1_fee() if provided (optional)
  • memo: Application-specific memo, max 32 bytes recommended (optional)
  • created_at_time: Timestamp for deduplication in nanoseconds (optional)

BurnWithPolicyArgs ​

candid
type BurnWithPolicyArgs = record {
    amount : nat;
    policy : BurnPolicy;
    memo : opt blob;
};

Fields:

  • amount: Base amount for burn calculation in smallest units (required)
  • policy: Which burn policy to apply (required)
  • memo: Optional application-specific memo (optional)

BurnResult ​

candid
type BurnResult = record {
    transaction_index : nat;
    tokens_burned : nat;
    effective_burn_rate : float64;
};

Fields:

  • transaction_index: Transaction index in ledger
  • tokens_burned: Actual number of tokens burned
  • effective_burn_rate: Burn rate applied (1.0, 5.0, 0.05, 0.07)

Enum Types ​

BurnPolicy ​

candid
type BurnPolicy = variant {
    GeneralDonation;
    EcologicalDonation;
    MarketplaceUnder50k;
    MarketplaceOver50k;
    InGamePurchase;
};

Policies:

  • GeneralDonation: 1:1 burn (100%) for standard crowdfunding — immediate and permanent
  • EcologicalDonation: 5:1 amplified burn (500%) for ecological impact — immediate and permanent
  • MarketplaceUnder50k: 5% burn for transactions under $50k USD — held for the dispute window (HeldBurn)
  • MarketplaceOver50k: 7% burn for transactions $50k+ USD — held for the dispute window (HeldBurn)
  • InGamePurchase: 5% burn for virtual goods purchases — immediate and permanent

TransferError ​

candid
type TransferError = variant {
    BadFee : record { expected_fee : nat };
    BadBurn : record { min_burn_amount : nat };
    InsufficientFunds : record { balance : nat };
    TooOld;
    CreatedInFuture : record { ledger_time : nat64 };
    Duplicate : record { duplicate_of : nat };
    TemporarilyUnavailable;
    GenericError : record { error_code : nat; message : text };
};

MetadataValue ​

candid
type MetadataValue = variant {
    Nat : nat;
    Int : int;
    Text : text;
    Blob : blob;
};

Purpose: Metadata value type for the icrc1_metadata() response. (In the live .did this type is named MetadataValue; earlier editions of this page called it Value.)

Standard ​

candid
type Standard = record {
    name : text;
    url : text;
};

Purpose: Token standard declaration for icrc1_supported_standards().


ICRC-1 Standard Methods ​

Metadata Queries ​

icrc1_name ​

Get token name.

candid
icrc1_name : () -> (text) query;

Access: Public · Returns: "Decentralized Otter Money"

icrc1_symbol ​

Get token symbol.

candid
icrc1_symbol : () -> (text) query;

Access: Public · Returns: "DOM"

icrc1_decimals ​

Get number of decimal places.

candid
icrc1_decimals : () -> (nat8) query;

Access: Public · Returns: 8 (smallest unit: 0.00000001 DOM)

icrc1_fee ​

Get transfer fee.

candid
icrc1_fee : () -> (nat) query;

Access: Public · Returns: 10000 (0.0001 DOM)

icrc1_metadata ​

Get token metadata as key-value pairs.

candid
icrc1_metadata : () -> (vec record { text; MetadataValue }) query;

Access: Public · Returns: Vector of metadata entries

javascript
const metadata = await domToken.icrc1_metadata();
// [
//   ["icrc1:name", { Text: "Decentralized Otter Money" }],
//   ["icrc1:symbol", { Text: "DOM" }],
//   ["icrc1:decimals", { Nat: 8n }],
//   ["icrc1:fee", { Nat: 10000n }]
// ]

icrc1_total_supply ​

Get current total supply.

candid
icrc1_total_supply : () -> (nat) query;

Access: Public · Returns: Current total supply (decreases permanently with each burn)

icrc1_minting_account ​

Get minting account.

candid
icrc1_minting_account : () -> (opt Account) query;

Access: Public · Returns: [] (None — no public minting account; DOM has a fixed genesis supply)

icrc1_balance_of ​

Get account balance.

candid
icrc1_balance_of : (Account) -> (nat) query;

Access: Public · Parameters: account: Account · Returns: Balance in smallest units

javascript
const balance = await domToken.icrc1_balance_of({
  owner: Principal.fromText("aaaaa-aa"),
  subaccount: []
});
// 1000000000n (10.00000000 DOM)

icrc1_supported_standards ​

Get list of supported standards.

candid
icrc1_supported_standards : () -> (vec Standard) query;

Access: Public · Returns: Vector of supported standards

Transfer Methods ​

icrc1_transfer ​

Transfer tokens between accounts.

candid
icrc1_transfer : (TransferArgs) -> (variant { Ok: nat; Err: TransferError });

Access: Public · Returns: Result<nat, TransferError> — transaction index on success

javascript
const result = await domToken.icrc1_transfer({
  from_subaccount: [],
  to: { owner: Principal.fromText("recipient-principal"), subaccount: [] },
  amount: 1_000_000_000n,  // 10.00000000 DOM
  fee: [10_000n],
  memo: [],
  created_at_time: []
});
// Success: { Ok: 42n }  (transaction index)
// Failure: { Err: { InsufficientFunds: { balance: 500_000_000n } } }

Validation:

  • Caller must have balance >= amount + fee
  • If fee provided, must match icrc1_fee()
  • Amount must be > 0

Burn Methods ​

icrc1_burn ​

Burn tokens from caller's account.

candid
icrc1_burn : (nat) -> (variant { Ok: nat; Err: TransferError });

Access: Public (burns caller's tokens) · Parameters: amount: nat · Returns: Result<nat, TransferError> — transaction index on success

javascript
// Burn 1 DOM (100,000,000 smallest units)
const result = await domToken.icrc1_burn(100_000_000n);
// Success: { Ok: 42n }
// Failure: { Err: { InsufficientFunds: { balance: 50_000_000n } } }

Use Case: Users voluntarily burning their own tokens to support deflationary tokenomics.

burn_with_policy ​

Policy-based token burn by authorized canisters.

candid
burn_with_policy : (BurnWithPolicyArgs) -> (variant { Ok: BurnResult; Err: TransferError });

Access: Authorized burners only · Returns: Result<BurnResult, TransferError>

javascript
// Ecological donation: 5x amplified burn
const result = await domToken.burn_with_policy({
  amount: 100_000_000n,  // 1.00000000 DOM
  policy: { EcologicalDonation: null },
  memo: []
});
// { Ok: { transaction_index: 42n, tokens_burned: 500_000_000n, effective_burn_rate: 5.0 } }

Policy Rates:

PolicyBurn RateUse Case
GeneralDonation1:1 (100%)Standard donations
EcologicalDonation5:1 (500%)Environmental causes
MarketplaceUnder50k5%Small purchases
MarketplaceOver50k7%Large purchases
InGamePurchase5%Otter Camp games

Only principals in the authorized burners list can call this method.

burn_usd_value ​

Burn a target USD value of DOM at the governance-reported price (BL-076.2). Requires the governance canister to be configured (set_governance_canister) so a live DOM price is available.

candid
burn_usd_value : (BurnUsdValueArgs) -> (variant { Ok: BurnUsdValueResult; Err: BurnUsdValueError });

type BurnUsdValueArgs = record {
    usd_cents : nat64;
    policy    : BurnPolicy;
    memo      : opt blob;
};

type BurnUsdValueResult = record {
    transaction_index : nat;
    tokens_burned     : nat;
    usd_cents_burned  : nat64;
    dom_price_used    : float64;
};

type BurnUsdValueError = variant {
    GovernanceNotConfigured;
    PriceNotAvailable;
    InsufficientFunds : record { balance : nat };
    PolicyDisabled    : record { policy_name : text };
    AmountTooSmall    : record { min_usd_cents : nat64 };
    Unauthorized      : record { message : text };
    InterCanisterError : record { message : text };
};

Access: Authorized burners only · Returns: Result<BurnUsdValueResult, BurnUsdValueError>

usd_burn_history ​

candid
usd_burn_history : (opt nat64, opt nat64) -> (vec BurnUsdEvent) query;

type BurnUsdEvent = record {
    timestamp         : nat64;
    usd_cents         : nat64;
    tokens_burned     : nat;
    dom_price_used    : float64;
    policy            : text;
    caller            : principal;
    transaction_index : nat;
};

Access: Public (read-only) · Parameters: optional (start_time, end_time) filter (nanoseconds)


Burn Policy Management (Admin Only) ​

enable_policy ​

candid
enable_policy : (text) -> (variant { Ok; Err: text });

Enable a burn policy by name.

disable_policy ​

candid
disable_policy : (text) -> (variant { Ok; Err: text });

Disable a burn policy by name. burn_with_policy / burn_usd_value return a policy-disabled error while a policy is off.

get_policy_states (query) ​

candid
get_policy_states : () -> (vec record { text; bool }) query;

Access: Public (read-only) · Returns: policy-name → enabled flag pairs.


Analytics ​

total_burned (query) ​

Total tokens burned across all time.

candid
total_burned : () -> (nat) query;

circulating_supply (query) ​

Current circulating supply (total supply minus tokens held in the treasury/unminting accounts).

candid
circulating_supply : () -> (nat) query;

burn_history (query) ​

Get burn-event history, optionally filtered by a (start_time, end_time) window in nanoseconds.

candid
burn_history : (opt nat64, opt nat64) -> (vec BurnEvent) query;

type BurnEvent = record {
    timestamp : nat64;
    policy : text;
    amount : nat;
    caller : principal;
    transaction_index : nat;
};

admin_event_history (query) ​

Get the history of administrative actions (authorizations, distributions, config changes).

candid
admin_event_history : (opt nat64, opt nat64) -> (vec AdminEvent) query;

type AdminEvent = record {
    timestamp : nat64;
    action : text;
    caller : principal;
    amount : nat;
    recipient : opt Account;
    source : opt Account;
    transaction_index : nat;
    detail : opt text;
};

Token Distribution (Admin Only) ​

mint_tokens ​

Mint tokens to an account (genesis / admin distribution only — there is no open public minting).

candid
mint_tokens : (Account, nat) -> (variant { Ok: nat; Err: text });

Returns: transaction index on success.

batch_distribute ​

Distribute tokens to multiple accounts in one call.

candid
batch_distribute : (vec record { Account; nat }) -> (variant { Ok: nat64; Err: text });

Returns: distribution ID on success.

admin_transfer ​

Admin-authorized transfer between two accounts.

candid
admin_transfer : (Account, Account, nat) -> (variant { Ok: nat; Err: text });

admin_burn ​

Admin-authorized burn from a specific account.

candid
admin_burn : (Account, nat) -> (variant { Ok: nat; Err: text });

Authorization Methods ​

authorize_burner ​

Add a principal to the authorized burners list.

candid
authorize_burner : (principal) -> (variant { Ok; Err: TransferError });

Access: Admin only

javascript
const otterCamp = Principal.fromText("otter-camp-principal");
const result = await domToken.authorize_burner(otterCamp);
// Success: { Ok: null }

revoke_burner ​

Remove a principal from the authorized burners list.

candid
revoke_burner : (principal) -> (variant { Ok; Err: TransferError });

Access: Admin only

get_burners (query) ​

List all authorized burner principals.

candid
get_burners : () -> (vec principal) query;

Access: Public (read-only) — anyone can verify which canisters are authorized to burn.

get_admin_principal (query) ​

candid
get_admin_principal : () -> (opt principal) query;

Access: Public (read-only) · Note: admin principal is set once at initialization.

get_treasury_account (query) ​

Query the configured treasury account.

candid
get_treasury_account : () -> (opt Account) query;

set_governance_canister / get_governance_canister ​

Configure (admin) and read the governance canister principal used by burn_usd_value to fetch the live DOM price.

candid
set_governance_canister : (principal) -> (variant { Ok; Err: text });
get_governance_canister : () -> (opt principal) query;

Unminting Wallet (HeldBurn) ​

Marketplace burns (MarketplaceUnder50k and MarketplaceOver50k policies) are placed in a dispute hold rather than burned immediately. During the hold period an admin can refund the tokens if a buyer dispute is upheld. Donation and in-game burns (GeneralDonation, EcologicalDonation, InGamePurchase) are immediate and permanent.

HeldBurn Data Type ​

candid
type HeldBurnStatus = variant {
    Held;
    Refunded;
    Finalized;
};

type HeldBurn = record {
    id : nat64;
    source_tx_index : nat;
    amount_e8s : nat;
    policy : text;
    requester : principal;
    held_at : nat64;       // nanoseconds
    expires_at : nat64;    // nanoseconds
    status : HeldBurnStatus;
};

get_pending_burns (query) ​

List held burns currently awaiting finalization or refund.

candid
get_pending_burns : () -> (vec HeldBurn) query;

get_refund_eligible (query) ​

Check whether a specific held burn is still within its dispute window and eligible for refund.

candid
get_refund_eligible : (nat64) -> (variant { Ok: bool; Err: text }) query;

refund_held_burn ​

Refund a held marketplace burn within its dispute window.

candid
refund_held_burn : (nat64) -> (variant { Ok: text; Err: text });

Access: Admin only · Parameters: burn_id: nat64 · Returns: Result<text, text>

finalize_expired_burns ​

Permanently burn all held burns whose dispute deadline has passed. Has no effect on burns still within their window.

candid
finalize_expired_burns : () -> (variant { Ok: nat64; Err: text });

Returns: Result<nat64, text> — the count of burns finalized, on success.

get_dispute_window_duration / set_dispute_window_duration ​

Read and configure (admin) the marketplace-burn hold period. The duration is expressed in nanoseconds (30 days = 2_592_000_000_000_000 ns).

candid
get_dispute_window_duration : () -> (nat64) query;
set_dispute_window_duration : (nat64) -> (variant { Ok; Err: text });

get_unminting_wallet_subaccount (query) ​

Return the subaccount that holds tokens pending finalization.

candid
get_unminting_wallet_subaccount : () -> (opt blob) query;

Burn Wallet & Donation Tracking ​

set_burn_wallet / get_burn_wallet ​

Configure (admin) and read the burn wallet principal.

candid
set_burn_wallet : (principal) -> (variant { Ok; Err: text });
get_burn_wallet : () -> (opt principal) query;

get_donation_burns (query) ​

Paginated donation-burn records.

candid
get_donation_burns : (nat64, nat64) -> (vec DonationBurnRecord) query;

type DonationBurnRecord = record {
    id : nat64;
    donor : principal;
    amount_e8s : nat;
    policy : text;
    burn_amount_e8s : nat;
    timestamp : nat64;
    tx_index : nat;
};

get_donation_burn_stats (query) ​

Aggregate donation-burn statistics.

candid
get_donation_burn_stats : () -> (DonationBurnStats) query;

type DonationBurnStats = record {
    total_donated : nat;
    total_burned : nat;
    count_general : nat64;
    count_ecological : nat64;
};

Utility & Backup ​

health (query) ​

candid
health : () -> (text) query;

Access: Public · Returns: "ok"

export_state / import_state ​

State backup and recovery (FOS-5.6.19). export_state is a public query (token balances are auditable); import_state is controller-only.

candid
export_state : () -> (blob) query;
import_state : (blob) -> (variant { Ok; Err: text });

Complete method surface ​

Every method exposed by the live dom_token.did. Methods with a detailed section above are marked ✓; the rest carry their exact live signature here.

MethodSignatureDetailed above
icrc1_name() -> (text) query✓
icrc1_symbol() -> (text) query✓
icrc1_decimals() -> (nat8) query✓
icrc1_fee() -> (nat) query✓
icrc1_metadata() -> (vec record { text; MetadataValue }) query✓
icrc1_total_supply() -> (nat) query✓
icrc1_minting_account() -> (opt Account) query✓
icrc1_balance_of(Account) -> (nat) query✓
icrc1_supported_standards() -> (vec Standard) query✓
icrc1_transfer(TransferArgs) -> (variant { Ok: nat; Err: TransferError })✓
icrc1_burn(nat) -> (variant { Ok: nat; Err: TransferError })✓
burn_with_policy(BurnWithPolicyArgs) -> (variant { Ok: BurnResult; Err: TransferError })✓
burn_usd_value(BurnUsdValueArgs) -> (variant { Ok: BurnUsdValueResult; Err: BurnUsdValueError })✓
usd_burn_history(opt nat64, opt nat64) -> (vec BurnUsdEvent) query✓
authorize_burner(principal) -> (variant { Ok; Err: TransferError })✓
revoke_burner(principal) -> (variant { Ok; Err: TransferError })✓
get_burners() -> (vec principal) query✓
get_admin_principal() -> (opt principal) query✓
get_treasury_account() -> (opt Account) query✓
set_governance_canister(principal) -> (variant { Ok; Err: text })✓
get_governance_canister() -> (opt principal) query✓
enable_policy(text) -> (variant { Ok; Err: text })✓
disable_policy(text) -> (variant { Ok; Err: text })✓
get_policy_states() -> (vec record { text; bool }) query✓
total_burned() -> (nat) query✓
burn_history(opt nat64, opt nat64) -> (vec BurnEvent) query✓
circulating_supply() -> (nat) query✓
admin_event_history(opt nat64, opt nat64) -> (vec AdminEvent) query✓
mint_tokens(Account, nat) -> (variant { Ok: nat; Err: text })✓
batch_distribute(vec record { Account; nat }) -> (variant { Ok: nat64; Err: text })✓
admin_transfer(Account, Account, nat) -> (variant { Ok: nat; Err: text })✓
admin_burn(Account, nat) -> (variant { Ok: nat; Err: text })✓
set_burn_wallet(principal) -> (variant { Ok; Err: text })✓
get_burn_wallet() -> (opt principal) query✓
get_donation_burns(nat64, nat64) -> (vec DonationBurnRecord) query✓
get_donation_burn_stats() -> (DonationBurnStats) query✓
get_pending_burns() -> (vec HeldBurn) query✓
get_refund_eligible(nat64) -> (variant { Ok: bool; Err: text }) query✓
get_dispute_window_duration() -> (nat64) query✓
set_dispute_window_duration(nat64) -> (variant { Ok; Err: text })✓
refund_held_burn(nat64) -> (variant { Ok: text; Err: text })✓
finalize_expired_burns() -> (variant { Ok: nat64; Err: text })✓
get_unminting_wallet_subaccount() -> (opt blob) query✓
health() -> (text) query✓
export_state() -> (blob) query✓
import_state(blob) -> (variant { Ok; Err: text })✓

Error Handling ​

Error Categories ​

CategoryError VariantsSeverity
ValidationBadFee, BadBurnClient Error
BalanceInsufficientFundsClient Error
TimingTooOld, CreatedInFutureClient Error
DeduplicationDuplicateClient Error
AuthorizationGenericError (403), UnauthorizedClient Error
SystemTemporarilyUnavailableServer Error

Error Handling Example ​

javascript
try {
  const result = await domToken.icrc1_transfer(args);
  if ('Ok' in result) {
    console.log(`Transfer successful: tx ${result.Ok}`);
  } else {
    const err = result.Err;
    if ('InsufficientFunds' in err) {
      console.error(`Insufficient balance: ${err.InsufficientFunds.balance}`);
    } else if ('BadFee' in err) {
      console.error(`Wrong fee. Expected: ${err.BadFee.expected_fee}`);
    } else if ('Duplicate' in err) {
      console.warn(`Already processed: tx ${err.Duplicate.duplicate_of}`);
    } else if ('GenericError' in err) {
      console.error(`Error ${err.GenericError.error_code}: ${err.GenericError.message}`);
    }
  }
} catch (e) {
  console.error('Call failed:', e);
}

Common Error Resolutions ​

ErrorResolution
InsufficientFundsCheck balance with icrc1_balance_of()
BadFeeUse fee from icrc1_fee() or omit the fee field
UnauthorizedCheck get_burners() for authorization status
DuplicateTransaction already processed, check duplicate_of
CreatedInFutureVerify client clock synchronization
TooOldUse current timestamp or omit created_at_time
PolicyDisabledCheck get_policy_states(); the policy is currently disabled

Frontend Integration ​

javascript
import { Actor, HttpAgent } from '@dfinity/agent';
import { Principal } from '@dfinity/principal';
import { idlFactory } from './declarations/dom-token';

const agent = new HttpAgent({ host: 'https://ic0.app' });
const domToken = Actor.createActor(idlFactory, {
  agent,
  canisterId: 'dom-token-canister-id',
});

// Transfer tokens
async function transferDOM(to, amount) {
  const result = await domToken.icrc1_transfer({
    from_subaccount: [],
    to: { owner: Principal.fromText(to), subaccount: [] },
    amount: BigInt(amount),
    fee: [10_000n],
    memo: [],
    created_at_time: []
  });
  if ('Ok' in result) return result.Ok;
  throw new Error(`Transfer failed: ${JSON.stringify(result.Err)}`);
}

// Check balance
async function getBalance(principal) {
  const balance = await domToken.icrc1_balance_of({
    owner: Principal.fromText(principal),
    subaccount: []
  });
  return Number(balance) / 100_000_000; // convert to DOM (8 decimals)
}

Rust Integration (Inter-Canister Calls) ​

rust
use candid::{CandidType, Deserialize, Nat, Principal};
use ic_cdk::api::call::call;

#[derive(CandidType, Deserialize)]
struct Account {
    owner: Principal,
    subaccount: Option<Vec<u8>>,
}

#[derive(CandidType, Deserialize)]
struct TransferArgs {
    from_subaccount: Option<Vec<u8>>,
    to: Account,
    amount: Nat,
    fee: Option<Nat>,
    memo: Option<Vec<u8>>,
    created_at_time: Option<u64>,
}

#[derive(CandidType, Deserialize)]
enum BurnPolicy {
    GeneralDonation,
    EcologicalDonation,
    MarketplaceUnder50k,
    MarketplaceOver50k,
    InGamePurchase,
}

#[derive(CandidType, Deserialize)]
struct BurnWithPolicyArgs {
    amount: Nat,
    policy: BurnPolicy,
    memo: Option<Vec<u8>>,
}

#[derive(CandidType, Deserialize)]
struct BurnResult {
    transaction_index: Nat,
    tokens_burned: Nat,
    effective_burn_rate: f64,
}

// Policy-based burn (authorized canister only)
async fn burn_with_policy(
    dom_token: Principal,
    amount: u64,
    policy: BurnPolicy,
) -> Result<BurnResult, String> {
    let args = BurnWithPolicyArgs { amount: Nat::from(amount), policy, memo: None };
    let (result,): (Result<BurnResult, String>,) =
        call(dom_token, "burn_with_policy", (args,))
            .await
            .map_err(|e| format!("Call failed: {:?}", e))?;
    result.map_err(|e| format!("Burn failed: {:?}", e))
}

Burn Policy Guide ​

Policy Selection Matrix ​

Use CasePolicyBurn RateExample
Crowdfunding campaignGeneralDonation1:1 (100%)User donates 100 DOM → 100 DOM burned
River cleanup projectEcologicalDonation5:1 (500%)User donates 100 DOM → 500 DOM burned
$1,000 marketplace saleMarketplaceUnder50k5%100 DOM sale → 5 DOM burned (held)
$100,000 wholesale orderMarketplaceOver50k7%100 DOM sale → 7 DOM burned (held)
In-game sword purchaseInGamePurchase5%100 DOM spent → 5 DOM burned

Authorization Setup ​

bash
# Get canister IDs
DOM_TOKEN=$(icp canister id dom-token)
OTTER_CAMP=$(icp canister id otter-camp)
MARKETPLACE=$(icp canister id marketplace)

# Authorize ecosystem canisters
icp canister call dom-token authorize_burner "(principal \"$OTTER_CAMP\")"
icp canister call dom-token authorize_burner "(principal \"$MARKETPLACE\")"

# Verify
icp canister call dom-token get_burners


Changelog ​

bl-1404 (2026-08-25) ​

  • Unified the comprehensive dom-token-api.md and the Candid quick-ref dom-token.md into this single page.
  • Arbitrated all method names/signatures against the live src/dom_token.did:
    • Renamed metadata value type Value → MetadataValue (matches the live .did).
    • Corrected the HeldBurn record to its live shape (id, source_tx_index, amount_e8s, policy: text, requester, held_at, expires_at, status: HeldBurnStatus).
    • Fixed refund_held_burn return to variant { Ok: text; Err: text }.
    • Fixed finalize_expired_burns return to variant { Ok: nat64; Err: text }.
    • Corrected the dispute-window duration unit to nanoseconds (was documented as seconds).
    • Documented the previously-missing live surface: burn_usd_value + USD burn types, set/get_governance_canister, usd_burn_history, admin_event_history, admin_transfer, admin_burn, set/get_burn_wallet, get_donation_burns, get_donation_burn_stats, get_treasury_account, get_pending_burns, get_refund_eligible, get/set_dispute_window_duration, get_unminting_wallet_subaccount, export_state, import_state.

Version 2.0 (2026-04-06) ​

  • Added HeldBurn / unminting wallet system for marketplace burns
  • Added refund_held_burn, finalize_expired_burns, set_dispute_window_duration methods
  • Clarified burn immediacy by policy (donation = immediate, marketplace = held)

Version 1.0 (2025-11-15) ​

  • Initial API documentation: ICRC-1 methods, policy-based burn system, authorization framework, integration examples

Last Updated: 2026-08-25 (bl-1404) API Version: 2.0

Hello World DAO