APL Token Program
Complete reference for the Arch Program Library Token Program - creating and managing fungible tokens
The APL Token Program is the foundation for creating and managing fungible tokens on the Arch Network. This documentation provides a comprehensive guide for developers implementing token functionality in their applications.
Overview
The Token Program enables:
- Creation and management of fungible tokens (mints)
- Token account management
- Token transfers and delegations
- Multisignature authorities
- Account freezing and thawing
Program ID
TokenT4em53UrV4gSvZ3nCS2mZeHaqTLapwt6iZt6MkIn Rust, use apl_token::id().
Account Types
Mint Account
The central record for a token type, containing:
| Field | Type | Description |
|---|---|---|
mint_authority | COption<Pubkey> | Optional authority to mint new tokens |
supply | u64 | Total number of tokens in circulation |
decimals | u8 | Number of decimal places |
is_initialized | bool | Has this mint been initialized |
freeze_authority | COption<Pubkey> | Optional authority to freeze token accounts |
Token Account
Holds token balances for a specific mint:
| Field | Type | Description |
|---|---|---|
mint | Pubkey | The token mint this account holds |
owner | Pubkey | Owner of this account |
amount | u64 | Number of tokens held |
delegate | COption<Pubkey> | Optional delegate authority |
state | AccountState | Account state (Uninitialized/Initialized/Frozen) |
is_native | COption<u64> | Rent-exempt reserve for wrapped native accounts |
delegated_amount | u64 | Amount delegated |
close_authority | COption<Pubkey> | Optional authority to close the account |
Multisig Account
Enables shared authority over token operations:
| Field | Type | Description |
|---|---|---|
m | u8 | Number of required signers |
n | u8 | Number of valid signers |
is_initialized | bool | Has this multisig been initialized |
signers | [Pubkey; MAX_SIGNERS] | Array of valid signer addresses |
Instructions
Token Creation and Initialization
InitializeMint
Creates a new token type.
pub struct InitializeMint {
pub decimals: u8,
pub mint_authority: Pubkey,
pub freeze_authority: COption<Pubkey>,
}Required accounts:
[writable]The mint to initialize
Example:
let mint = Keypair::new();
let mint_authority = Keypair::new();
let decimals = 9;
let instruction = apl_token::instruction::initialize_mint(
&apl_token::id(),
&mint.pubkey(),
&mint_authority.pubkey(),
None, // No freeze authority
decimals,
)?;InitializeAccount
Creates a new account to hold tokens.
Required accounts:
[writable]The account to initialize[]The mint this account is for[]The owner of the new account
Example:
let account = Keypair::new();
let owner = Keypair::new();
let instruction = apl_token::instruction::initialize_account(
&apl_token::id(),
&account.pubkey(),
&mint.pubkey(),
&owner.pubkey(),
)?;Token Operations
MintTo
Creates new tokens and adds them to a token account.
pub struct MintTo {
pub amount: u64,
}Required accounts:
[writable]The mint[writable]The destination token account[signer]The mint authority
Example:
let instruction = apl_token::instruction::mint_to(
&apl_token::id(),
&mint.pubkey(),
&destination_account.pubkey(),
&mint_authority.pubkey(),
&[],
1000000000, // 1 token with 9 decimals
)?;Transfer
Transfers tokens from one account to another.
pub struct Transfer {
pub amount: u64,
}Required accounts:
[writable]The source token account[writable]The destination token account[signer]The source account owner
Example:
let instruction = apl_token::instruction::transfer(
&apl_token::id(),
&source_account.pubkey(),
&destination_account.pubkey(),
&owner.pubkey(),
&[],
500000000, // 0.5 tokens
)?;TransferChecked
Transfers tokens with additional validation.
pub struct TransferChecked {
pub amount: u64,
pub decimals: u8,
}Required accounts:
[writable]The source token account[]The mint[writable]The destination token account[signer]The source account owner
Example:
let instruction = apl_token::instruction::transfer_checked(
&apl_token::id(),
&source_account.pubkey(),
&mint.pubkey(),
&destination_account.pubkey(),
&owner.pubkey(),
&[],
500000000, // 0.5 tokens
9, // decimals
)?;Delegation
Approve
Allows a delegate to transfer tokens on behalf of the owner.
pub struct Approve {
pub amount: u64,
}Required accounts:
[writable]The token account[]The delegate[signer]The account owner
Example:
let delegate = Keypair::new();
let instruction = apl_token::instruction::approve(
&apl_token::id(),
&token_account.pubkey(),
&delegate.pubkey(),
&owner.pubkey(),
&[],
1000000000, // 1 token
)?;Revoke
Removes delegation authority.
Required accounts:
[writable]The token account[signer]The account owner
Example:
let instruction = apl_token::instruction::revoke(
&apl_token::id(),
&token_account.pubkey(),
&owner.pubkey(),
&[],
)?;Account Management
FreezeAccount
Freezes a token account, preventing transfers.
Required accounts:
[writable]The token account[]The mint[signer]The freeze authority
Example:
let instruction = apl_token::instruction::freeze_account(
&apl_token::id(),
&token_account.pubkey(),
&mint.pubkey(),
&freeze_authority.pubkey(),
&[],
)?;ThawAccount
Unfreezes a frozen token account.
Required accounts:
[writable]The token account[]The mint[signer]The freeze authority
Example:
let instruction = apl_token::instruction::thaw_account(
&apl_token::id(),
&token_account.pubkey(),
&mint.pubkey(),
&freeze_authority.pubkey(),
&[],
)?;CloseAccount
Closes a token account and reclaims rent.
Required accounts:
[writable]The token account[writable]The destination for reclaimed rent[signer]The account owner
Example:
let instruction = apl_token::instruction::close_account(
&apl_token::id(),
&token_account.pubkey(),
&destination_account.pubkey(),
&owner.pubkey(),
&[],
)?;Multisig Operations
InitializeMultisig
Creates a multisig account for shared authority.
pub struct InitializeMultisig {
pub m: u8, // Required signatures
}Required accounts:
[writable]The multisig account[]Signer public keys for the multisig
Example:
let multisig = Keypair::new();
let signers = vec![signer1.pubkey(), signer2.pubkey(), signer3.pubkey()];
let instruction = apl_token::instruction::initialize_multisig(
&apl_token::id(),
&multisig.pubkey(),
&signers,
2, // Require 2 of 3 signatures
)?;Error Codes
| Code | Name | Description |
|---|---|---|
| 0 | NotRentExempt | Lamport balance below rent-exempt threshold |
| 1 | InsufficientFunds | Insufficient funds for the operation |
| 2 | InvalidMint | The mint provided is not valid |
| 3 | MintMismatch | Account is not associated with this mint |
| 4 | OwnerMismatch | Owner does not match |
| 5 | FixedSupply | This token's supply is fixed |
| 6 | AlreadyInUse | Account cannot be initialized because it is already in use |
| 7 | InvalidNumberOfProvidedSigners | Invalid number of provided signers |
| 8 | InvalidNumberOfRequiredSigners | Invalid number of required signers |
| 9 | UninitializedState | State is uninitialized |
| 10 | NativeNotSupported | Instruction does not support native tokens |
| 11 | NonNativeHasBalance | Non-native account can only be closed when balance is zero |
| 12 | InvalidInstruction | Invalid instruction |
| 13 | InvalidState | State is invalid for the requested operation |
| 14 | Overflow | Operation overflowed |
| 15 | AuthorityTypeNotSupported | Account does not support specified authority type |
| 16 | MintCannotFreeze | This token mint cannot freeze accounts |
| 17 | AccountFrozen | Account is frozen |
| 18 | MintDecimalsMismatch | Mint decimals mismatch |
| 19 | NonNativeNotSupported | Instruction does not support non-native tokens |
Rust Usage
The package is published as apl-token and imported as the apl_token crate. Use explicit modules such as apl_token::instruction, apl_token::state, and apl_token::id(); the crate does not expose a prelude module.
[dependencies]
apl-token = "0.6.4"let transfer_ix = apl_token::instruction::transfer(
&apl_token::id(),
source_account,
destination_account,
owner,
&[],
amount,
)?;CLI Usage
Create a Token Mint
# Create a new token mint
arch-cli token create-mint \
--decimals 9 \
--mint-authority ~/mint_authority.key \
--keypair-path ~/payer.keyCreate a Token Account
# Create a token account
arch-cli token create-account \
--mint <MINT_ADDRESS> \
--owner ~/owner.key \
--keypair-path ~/payer.keyMint Tokens
# Mint tokens to an account
arch-cli token mint \
<MINT_ADDRESS> \
1000000000 \
--account-address <TOKEN_ACCOUNT> \
--authority ~/mint_authority.key \
--keypair-path ~/payer.keyTransfer Tokens
# Transfer tokens between accounts
arch-cli token transfer \
<SOURCE_ACCOUNT> \
<DESTINATION_ACCOUNT> \
500000000 \
--owner ~/owner.key \
--keypair-path ~/payer.keyBest Practices
Security
- Secure Key Management: Store private keys securely and never share them
- Use Multisig: Implement multisig for important operations
- Regular Audits: Regularly audit token operations and balances
- Access Control: Implement proper access controls for mint authorities
Performance
- Batch Operations: Use batch operations for multiple transfers
- Account Management: Close unused accounts to reclaim rent
- Efficient Decimals: Choose appropriate decimal places for your use case
- Monitor Gas: Monitor transaction costs and optimize accordingly
Development
- Test Thoroughly: Test all operations in development before production
- Error Handling: Implement proper error handling in your applications
- Documentation: Document your token's purpose and operations
- Community: Follow community best practices and standards
Next Steps
Associated Token Account
Learn about associated token accounts
Token Guide
Complete guide to creating tokens
SDK Reference
Learn to use the SDKs
Examples
Explore example implementations