| title | Tokens and Cycles |
|---|---|
| description | Manage ICP tokens and cycles, including conversions, balance checks, and topping up canisters. |
This is a command reference for managing ICP tokens and cycles. If you're deploying to mainnet for the first time, start with Deploying to Mainnet instead.
The Internet Computer uses two primary currencies:
| Currency | Purpose | Used For |
|---|---|---|
| ICP | Governance token | Trading, staking, converting to cycles |
| Cycles | Computational fuel | Running canisters, paying for storage and compute |
Canisters consume cycles to operate on mainnet. To obtain cycles, you convert ICP tokens at the current ICP/XDR exchange rate. XDR (Special Drawing Rights) is an international reserve asset used for stable pricing. One trillion cycles (1T) costs approximately 1 XDR worth of ICP.
All cycle and token amounts support human-readable suffixes for convenience:
korK= thousand (1,000)morM= million (1,000,000)borB= billion (1,000,000,000)torT= trillion (1,000,000,000,000)
Suffixes are case-insensitive. Examples: 1.5T, 500m, 1_234.5B, 2K
Understanding when to use -n (network) vs -e (environment) is essential:
| Flag | Purpose | Used With | Example |
|---|---|---|---|
-n ic |
Network flag | Token and cycles operations | icp token balance -n icicp cycles mint -n ic |
-e ic |
Environment flag | Deployment and canister operations | icp deploy -e icicp canister status my-canister -e ic |
For canister operations:
The flag you use depends on whether you're referencing canisters by name or by ID:
-
Canister names (like
my-canister) — Must use-e <environment>- Environment knows about your project's canister mappings
- Examples:
icp canister status my-canister -e ic
-
Canister IDs (like
ryjl3-tyaaa-aaaaa-aaaba-cai) — Can use either-eor-n- Use
-ewhen working within your project context - Use
-nwhen working with arbitrary canisters on a network - Examples:
icp canister status ryjl3-tyaaa-aaaaa-aaaba-cai -n ic
- Use
# ✓ Works - canister name with environment
icp canister status my-canister -e ic
icp canister top-up my-canister --amount 1T -e ic
# ✗ Fails - canister name with network (no project context)
icp canister status my-canister -n ic
# ✓ Works - canister ID with network
icp canister status ryjl3-tyaaa-aaaaa-aaaba-cai -n ic
icp canister top-up ryjl3-tyaaa-aaaaa-aaaba-cai --amount 1T -n ic
# ✓ Also works - canister ID with environment
icp canister status ryjl3-tyaaa-aaaaa-aaaba-cai -e icCheck your ICP balance:
# On IC mainnet
icp token balance -n ic
# On local network (for testing)
icp token balanceCheck your cycles balance:
# On IC mainnet
icp cycles balance -n ic
# On local network
icp cycles balanceCheck a canister's cycles balance:
# By canister name (in your project environment)
icp canister status my-canister -e ic
# By canister ID (on any network)
icp canister status ryjl3-tyaaa-aaaaa-aaaba-cai -n icThe output includes the canister's cycles balance.
Convert ICP tokens to cycles for use with canisters:
# Convert a specific amount of ICP
icp cycles mint --icp 5 -n ic
# Or request a specific amount of cycles (ICP calculated automatically)
icp cycles mint --cycles 5T -n icVerify your cycles balance:
icp cycles balance -n icSend ICP tokens to another principal:
# The 'icp' token is used by default
icp token transfer <AMOUNT> <RECEIVER> -n ic
# Explicitly specifying 'icp' is equivalent
icp token icp transfer <AMOUNT> <RECEIVER> -n icExamples:
# Send 1 ICP
icp token transfer 1 aaaaa-aa -n ic
# Send 0.5 ICP
icp token transfer 0.5 xxxxx-xxxxx-xxxxx-xxxxx-cai -n ic
# Using human-readable amounts
icp token transfer 1.5m xxxxx-xxxxx-xxxxx-xxxxx-cai -n icThe receiver can be a principal ID or canister ID.
To get your ICP ledger account identifier (for transfers to/from exchanges or wallets that don't support principals yet):
icp identity account-idSee Managing Identities for more details on account identifiers.
icp-cli supports ICRC-1 tokens by specifying the token's ledger canister ID. ICRC-1 is a fungible token standard on the Internet Computer, which means all ICRC-1 tokens work with the same commands.
To transfer ICRC-1 tokens, specify the ledger canister ID. Example with ckBTC (ledger: mxzaz-hqaaa-aaaar-qaada-cai):
# Check ckBTC balance
icp token mxzaz-hqaaa-aaaar-qaada-cai balance -n ic
# Transfer 0.001 ckBTC
icp token mxzaz-hqaaa-aaaar-qaada-cai transfer 0.001 xxxxx-xxxxx-xxxxx-xxxxx-cai -n icThis works with any ICRC-1 compatible token ledger on the Internet Computer.
Finding Token Ledger IDs: You can find ledger canister IDs for various tokens on the ICP Dashboard.
Beyond direct transfers, ICP and ICRC-2 compatible tokens support allowances: you authorize another principal — the spender, typically a canister — to transfer a limited amount of tokens from your account on your behalf. This is the foundation for many payment and recurring-billing flows, where a canister pulls funds only when needed (for example, an exchange platform settling a trade or a service charging per use) rather than requiring you to send tokens up front.
Allowances follow the ICRC-2 standard and work with any ICRC-2 compatible ledger, including the ICP ledger.
Use icp token approve to authorize a spender:
# Approve a canister to spend up to 5 ICP on your behalf
icp token approve 5 <SPENDER> -n ic
# Approve 0.01 ckBTC (any ICRC-2 ledger, by canister id)
icp token mxzaz-hqaaa-aaaar-qaada-cai approve 0.01 <SPENDER> -n ic<SPENDER> is the principal you are authorizing (usually a canister ID). The amount is in whole tokens and supports the same human-readable suffixes as transfers.
Approvals overwrite, they do not add. Each approve call sets the allowance to the amount you specify, replacing any previous value. Approving 5 and then 2 leaves an allowance of 2, not 7. To revoke an allowance, approve 0:
icp token approve 0 <SPENDER> -n icThe allowance is granted from your account, which pays the standard ledger fee (0.0001 ICP for the ICP ledger).
For safety, you can make an allowance expire automatically with --expires-in. It accepts a relative duration (suffixes s, m, h, d, w; a bare number is seconds), the same format used elsewhere in the CLI:
# Allow spending for the next 24 hours only
icp token approve 5 <SPENDER> --expires-in 24h -n ic
# Expire in 30 days
icp token approve 5 <SPENDER> --expires-in 30d -n icA short expiry limits your exposure if the spender is ever compromised. Without --expires-in, the allowance stays in effect until you change or revoke it.
Use icp token allowance to see how much a spender is currently authorized to transfer:
# Allowance you granted to a spender
icp token allowance <SPENDER> -n icThis is a read-only query, so you can inspect any allowance — not just your own. Use --of-principal to look up the allowance another account granted:
# Allowance that <OWNER> granted to <SPENDER>
icp token allowance <SPENDER> --of-principal <OWNER> -n icThe output includes the expiry, if one was set.
Both commands accept subaccount flags, specified as hex strings just like balance and transfer:
| Flag | Command | Meaning |
|---|---|---|
--from-subaccount <hex> |
approve |
Your subaccount the allowance is granted from (the account debited) |
--subaccount <hex> |
allowance |
The owner subaccount that granted the allowance |
--spender-subaccount <hex> |
both | The spender's subaccount |
# Approve from your subaccount 1, to the spender's subaccount 2
icp token approve 5 <SPENDER> --from-subaccount 1 --spender-subaccount 2 -n ic
# Check that same allowance
icp token allowance <SPENDER> --subaccount 1 --spender-subaccount 2 -n icTransfer cycles directly to another principal via the cycles ledger:
icp cycles transfer <AMOUNT> <RECEIVER> -n icExamples:
# Transfer 1 trillion cycles
icp cycles transfer 1T aaaaa-aa -n ic
# Transfer 500 million cycles
icp cycles transfer 500m xxxxx-xxxxx-xxxxx-xxxxx-cai -n icThe receiver can be a principal ID or canister ID.
Regularly check canister cycles to avoid running out. If a canister runs out of cycles, it will be frozen and eventually deleted along with all its code and state.
# Check all canisters in an environment
icp canister status -e ic
# Check specific canister by name (in your project)
icp canister status my-canister -e ic
# Check specific canister by ID (on any network)
icp canister status ryjl3-tyaaa-aaaaa-aaaba-cai -n icAdd cycles to a canister to keep it running:
# Top up by canister name (in your project)
icp canister top-up my-canister --amount 1T -e ic
# Top up by canister ID (on any network)
icp canister top-up ryjl3-tyaaa-aaaaa-aaaba-cai --amount 1T -n icThe --amount is specified in cycles (not ICP) and supports human-readable suffixes like 1T, 500m, etc.
Understanding the difference between these two commands helps you choose the right one for your use case.
The cycles ledger is an ICP system canister that tracks cycles balances for principals, similar to how the ICP ledger tracks ICP token balances.
There are two ways to send cycles:
| Command | Destination | Use Case |
|---|---|---|
icp cycles transfer |
Recipient's cycles balance | Transfer cycles to another principal's cycles ledger balance (similar to sending tokens) |
icp canister top-up |
Canister's operating balance | Add cycles directly to a canister to pay for its compute and storage |
When to use each:
cycles transfer: Send cycles to another person/identity through the cycles ledger, similar to how you transfer ICP tokenscanister top-up: Directly fund a canister to keep it running (most common for maintaining canisters)
Specify which identity to use for token operations:
# Check balance for a specific identity
icp token balance --identity my-other-identity -n ic
# Transfer using a specific identity
icp token transfer 1 <RECEIVER> --identity my-wallet -n icSee Managing Identities for more details.
A subaccount is a 32-byte namespace under a principal. Subaccounts let a single principal manage multiple independent balances — useful for separating funds by purpose, managing deposits from multiple users, or interacting with exchanges.
Subaccounts are specified as hex strings (up to 64 characters). Shorter values are left-padded with zeros. For example, 1 becomes a 32-byte value with 01 in the last byte.
# ICP token balance for a subaccount
icp token balance --subaccount 1 -n ic
# Cycles balance for a subaccount
icp cycles balance --subaccount 1 -n icSend from a subaccount using --from-subaccount:
# Transfer ICP from a subaccount
icp token transfer 1 <RECEIVER> --from-subaccount 1 -n ic
# Transfer cycles from a subaccount
icp cycles transfer 1T <RECEIVER> --from-subaccount 1 -n ic
# Mint cycles from a specific ICP subaccount
icp cycles mint --icp 5 --from-subaccount 1 -n icSend to a receiver's subaccount using --to-subaccount:
# Send ICP to subaccount 1 of the receiver
icp token transfer 1 rrkah-fqaaa-aaaaa-aaaaq-cai --to-subaccount 1 -n ic
# Send cycles to subaccount 1 of the receiver
icp cycles transfer 1T rrkah-fqaaa-aaaaa-aaaaq-cai --to-subaccount 1 -n icAlternatively, you can use the ICRC-1 account format, which embeds the subaccount directly in the address. This format appends a CRC32 checksum to the principal, followed by the subaccount hex after a . separator. For example, 2vxsx-fae-22yutvy.1 is the anonymous principal (2vxsx-fae) with checksum 22yutvy and subaccount 1.
Use icp identity account-id --of-subaccount <hex> to get both the ICP ledger account ID and the ICRC-1 account format for a subaccount, rather than constructing them manually.
Transfer commands accept multiple receiver formats:
| Format | Example | Description |
|---|---|---|
| Principal | rrkah-fqaaa-aaaaa-aaaaq-cai |
Sends to the principal's default subaccount |
| ICRC-1 account | 2vxsx-fae-22yutvy.1 |
Principal + CRC32 checksum + subaccount hex |
| ICP ledger account ID | 64-character hex string |
32-byte account identifier (used by exchanges and the NNS) |
The ICRC-1 account format works for both icp token transfer and icp cycles transfer. Use icp identity account-id to obtain correctly formatted addresses. ICP ledger account IDs are only accepted by icp token transfer.
# Show account identifiers for a subaccount
icp identity account-id --of-subaccount 1
# Show the icrc1 format
icp identity account-id --of-subaccount 1 --format icrc1You can choose to the output format as either ledger (the default) or icrc1.
All transfers incur small fees:
- ICP transfers: 0.0001 ICP fee
- Cycles transfers: Small fee in cycles (varies by operation)
- ICRC-1 tokens: Fee varies by token (typically minimal)
Fees are automatically deducted from your balance when you initiate a transfer.
Transfers are irreversible. Once sent, transactions cannot be undone. To minimize risk:
- Verify receiver addresses — Double-check the principal or canister ID before sending
- Test with small amounts — For large transfers or new recipients, send a small test amount first
- Confirm the target network —
-n ictargets IC mainnet; omitting it uses your local network
Insufficient balance: If you don't have enough funds (including fees), the transfer will fail with an error.
"Insufficient balance"
Your account doesn't have enough ICP or cycles. Check your balance:
icp token balance -n ic
icp cycles balance -n ic"Canister out of cycles"
Top up the canister:
# By canister name (in your project environment)
icp canister top-up my-canister --amount 1T -e ic
# By canister ID (on any network)
icp canister top-up ryjl3-tyaaa-aaaaa-aaaba-cai --amount 1T -n icTransfer fails
Verify:
- The receiver address is correct
- You have sufficient balance (including fees)
- You're using the correct identity
- Deploying to Mainnet — Complete mainnet deployment guide
- Managing Identities — Manage keys and principals