This example demonstrates deploying KRC20 tokens on Kaspa using the commit-reveal pattern from an ICP canister. Successfully tested on Kaspa Testnet 10.
dfx start --background
dfx deploy krc20_exampledfx canister call krc20_example getAddressGet testnet KAS from the faucet (need ~2100+ KAS for deploy):
Faucet: https://faucet-tn10.kaspanet.io/
dfx canister call krc20_example deployTokenWithBroadcast '("MYTOKEN", "21000000000000000", "100000000000", opt 8, "YOUR_KASPA_ADDRESS")'Parameters:
"MYTOKEN"- Token ticker (4-6 characters)"21000000000000000"- Max supply (with decimals)"100000000000"- Mint limit per operation (with decimals)opt 8- Decimals (optional, default 8)"YOUR_KASPA_ADDRESS"- Your kaspatest: address
Wait ~10 seconds for commit to confirm, then reveal:
dfx canister call krc20_example revealOperation '("COMMIT_TX_ID", "YOUR_KASPA_ADDRESS")'- Token info: https://tn10api.kasplex.org/v1/krc20/token/MYTOKEN
- Operation status: https://tn10api.kasplex.org/v1/krc20/op/REVEAL_TX_ID
- Look for
"opAccept": "1"to confirm success
| Operation | Commit Fee | Reveal Fee | Total |
|---|---|---|---|
| Deploy | 1,000 KAS | 1,000 KAS | ~2,000 KAS |
| Mint | 1 KAS | Network fee | ~1 KAS |
| Transfer | Network fee | Network fee | Minimal |
Successfully deployed ICWIN token on Kaspa Testnet 10:
- Commit TX:
bb376669116b98f3c6d625aad054a7552c7c06eb40eb9907f90ddc2d622b3f6b - Reveal TX:
f418464bdd8001655b320f3605f007d4fa2a5297d3dfe9f6a96e0155c60c679f - Token API: https://tn10api.kasplex.org/v1/krc20/token/ICWIN
Every KRC20 operation requires two transactions:
-
Commit Transaction
- Creates a P2SH output with BLAKE2B hash of redeem script
- Locks funds that will be spent in reveal
- Pays commit fee (1000 KAS for deploy)
-
Reveal Transaction
- Spends the P2SH output
- Provides the redeem script containing the KRC20 data
- Pays reveal fee (burned as protocol fee)
<pubkey>
OP_CHECKSIG_ECDSA
OP_FALSE
OP_IF
OP_PUSH "kasplex"
OP_1 // Metadata marker
OP_0 // Empty metadata
OP_0 // Content marker
OP_PUSH <json_data> // KRC20 JSON
OP_ENDIF
Uses ICP's threshold ECDSA for signing - no private keys stored in the canister!
After deploying your token, you can mint new tokens up to the mint limit (lim parameter).
# Mint tokens to the canister's address (default)
dfx canister call krc20_example mintTokenWithBroadcast '("ICWIN", null)'This will:
- Create a commit transaction with 1 KAS fee
- Broadcast it to the network
- Store the redeem script for reveal
- Return the commit TX ID
Wait ~10 seconds for commit confirmation, then reveal:
dfx canister call krc20_example revealOperation '("COMMIT_TX_ID", "YOUR_KASPA_ADDRESS")'# Mint tokens to a specific recipient
dfx canister call krc20_example mintTokenWithBroadcast '("ICWIN", opt "kaspatest:recipient_address_here")'Before minting, verify the token is still mintable:
# Get token info (max supply, current minted, mint limit, etc.)
dfx canister call krc20_example getTokenInfo '("ICWIN")'
# Check mint status
dfx canister call krc20_example checkMintStatus '("ICWIN")'
# Check specific token balance
dfx canister call krc20_example getKRC20TokenBalance '("kaspatest:YOUR_ADDRESS", "ICWIN")'
# OR check all tokens you hold
dfx canister call krc20_example getKRC20TokenList '("kaspatest:YOUR_ADDRESS")'After reveal, check your mint operation:
# Get operation status (look for "opAccept": "1")
dfx canister call krc20_example getOperationStatus '("REVEAL_TX_ID")'Or visit:
- Operation status: https://tn10api.kasplex.org/v1/krc20/op/REVEAL_TX_ID
- Token info: https://tn10api.kasplex.org/v1/krc20/token/ICWIN
- Your token balance: https://tn10api.kasplex.org/v1/krc20/address/kaspatest:YOUR_ADDRESS/token/ICWIN
- All your tokens: https://tn10api.kasplex.org/v1/krc20/address/kaspatest:YOUR_ADDRESS/tokenlist
Each mint operation mints the lim amount specified during deployment:
- ICWIN example:
lim = "100000000000"(1,000 ICWIN with 8 decimals) - You can mint multiple times until reaching
maxsupply - Fee: 1 KAS per mint operation
# 1. Check if token is mintable
dfx canister call krc20_example getTokenInfo '("ICWIN")'
# 2. Mint tokens (commit transaction)
dfx canister call krc20_example mintTokenWithBroadcast '("ICWIN", null)'
# Output: (variant { ok = record { commit_tx_id = "abc123..."; ... }})
# 3. Wait 10 seconds...
# 4. Reveal the mint
dfx canister call krc20_example revealOperation '("abc123...", "kaspatest:YOUR_ADDRESS")'
# Output: (variant { ok = record { reveal_tx_id = "xyz789..."; ... }})
# 5. Check operation status
dfx canister call krc20_example getOperationStatus '("xyz789...")'
# Look for: "opAccept": "1"
# 6. Verify your balance
dfx canister call krc20_example getKRC20TokenBalance '("kaspatest:YOUR_ADDRESS", "ICWIN")'
# OR see all your tokens
dfx canister call krc20_example getKRC20TokenList '("kaspatest:YOUR_ADDRESS")'Get balance for a specific token:
dfx canister call krc20_example getKRC20TokenBalance '("kaspatest:YOUR_ADDRESS", "ICWIN")'Example response:
{
"tick": "ICWIN",
"balance": "100000000000",
"locked": "0",
"dec": "8"
}Get all tokens you hold:
dfx canister call krc20_example getKRC20TokenList '("kaspatest:YOUR_ADDRESS")'Example response:
{
"message": "successful",
"result": [
{
"tick": "ICWIN",
"balance": "100000000000",
"locked": "0",
"dec": "8"
}
]
}Get token metadata (max supply, minted, etc.):
dfx canister call krc20_example getTokenInfo '("ICWIN")'Verify if your mint/transfer/burn succeeded:
dfx canister call krc20_example getOperationStatus '("REVEAL_TX_ID")'Look for "opAccept": "1" to confirm success! ✅
Token information:
https://tn10api.kasplex.org/v1/krc20/token/ICWIN
Operation status:
https://tn10api.kasplex.org/v1/krc20/op/REVEAL_TX_ID
Your token balance (specific):
https://tn10api.kasplex.org/v1/krc20/address/kaspatest:YOUR_ADDRESS/token/ICWIN
All your tokens (list):
https://tn10api.kasplex.org/v1/krc20/address/kaspatest:YOUR_ADDRESS/tokenlist
dfx canister call krc20_example buildTransferCommit '("MYTOKEN", "50000000000", "recipient_address")'dfx canister call krc20_example buildBurnCommit '("MYTOKEN", "10000000000")'# Check balance
dfx canister call krc20_example getBalance '("kaspatest:...")'
# Get pending reveals
dfx canister call krc20_example getPendingReveals
# Consolidate UTXOs
dfx canister call krc20_example consolidateUTXOs '("kaspatest:...")'