For AI agents: Documentation index at /llms.txt

Skip to content

Protocol Canisters

Protocol canisters implement platform-level features on the Internet Computer. Unlike system canisters, which govern the network itself, protocol canisters provide infrastructure that applications build on: Bitcoin integration, Ethereum integration, chain-key tokens, and exchange rates. They are controlled by the NNS and run on dedicated system subnets.

For all chain-key token canister IDs (ledger, minter, index), see Chain-Key Token Canister IDs. For deposit, withdrawal, and transfer flows, see Chain-key tokens.

The Bitcoin integration canisters connect ICP to the Bitcoin network. They track the Bitcoin UTXO set and expose an API that other canisters use to read Bitcoin state and submit transactions.

Call the Bitcoin canisters directly using the canister IDs below for better performance and to avoid potential future changes to the management canister Bitcoin API.

FieldValue
Canister IDghsi2-tqaaa-aaaan-aaaca-cai
Subnetw4rem-dv5e3-widiz-wbpea-kbttk-mnzfm-tzrc7-svcj3-kbxyb-zamch-hqe
SpecificationBitcoin canister interface spec
FieldValue
Canister IDg4xu7-jiaaa-aaaan-aaaaq-cai
Subnetw4rem-dv5e3-widiz-wbpea-kbttk-mnzfm-tzrc7-svcj3-kbxyb-zamch-hqe
SpecificationBitcoin canister interface spec
  • bitcoin_get_utxos: returns UTXOs for a Bitcoin address
  • bitcoin_get_balance: returns the balance of a Bitcoin address in satoshi
  • bitcoin_send_transaction: submits a signed Bitcoin transaction
  • bitcoin_get_current_fee_percentiles: returns fee percentiles in millisatoshi/vbyte
  • bitcoin_get_block_headers: returns block headers for a range of heights
  • get_blockchain_info: returns chain tip height, block hash, timestamp, difficulty, and UTXO count

All Bitcoin canister calls require cycles attached. In Rust, the ic-cdk-bitcoin-canister crate handles this automatically. In Motoko, attach cycles explicitly with (with cycles = amount).

EndpointTestnet / RegtestMainnet
bitcoin_get_balance40,000,000100,000,000
bitcoin_get_utxos4,000,000,00010,000,000,000
bitcoin_send_transaction (base)2,000,000,0005,000,000,000
bitcoin_send_transaction (per byte)8,000,00020,000,000
bitcoin_get_current_fee_percentiles40,000,000100,000,000
bitcoin_get_block_headers4,000,000,00010,000,000,000
get_blockchain_info40,000,000100,000,000

For integration patterns and code examples, see the Bitcoin guide.

The Dogecoin canister is a system-level canister that connects ICP to the Dogecoin network using the same architecture as the Bitcoin integration. It syncs blocks from the Dogecoin peer-to-peer network, maintains the UTXO set, and exposes an API for querying Dogecoin state and submitting transactions.

For the current canister ID, see the Dogecoin canister repository.

  • dogecoin_get_utxos: returns UTXOs for a Dogecoin address
  • dogecoin_get_balance: returns the balance of a Dogecoin address in koinu (1 DOGE = 100,000,000 koinu)
  • dogecoin_get_current_fee_percentiles: returns fee percentiles from recent Dogecoin transactions
  • dogecoin_send_transaction: submits a signed transaction to the Dogecoin network

For integration patterns, see the Dogecoin guide.

The ckBTC minter holds real BTC in a threshold ECDSA-controlled wallet and mints or burns ckBTC tokens. It issues a unique Bitcoin deposit address per (owner, subaccount) account and handles withdrawal requests by submitting signed Bitcoin transactions.

For canister IDs, see Chain-Key Token Canister IDs: ckBTC.

ParameterValueDescription
retrieve_btc_min_amount50,000 satoshiMinimum amount for BTC withdrawal
max_time_in_queue_nanos10 minutesMaximum time a retrieval request waits
min_confirmations4Bitcoin confirmations required before minting
kyt_fee100 satoshiFee for know-your-transaction (KYT) check
  • get_btc_address(owner, subaccount): returns a unique Bitcoin deposit address for the given principal and subaccount
  • update_balance(owner, subaccount): checks for newly confirmed UTXOs and mints ckBTC
  • get_known_utxos(owner, subaccount): returns UTXOs already processed for the given account
  • estimate_withdrawal_fee(amount): estimates the fee for retrieving a given BTC amount
  • get_deposit_fee: returns the current fee charged when minting ckBTC (the KYT fee)
  • retrieve_btc_with_approval(address, amount, from_subaccount): burns ckBTC via ICRC-2 approval and sends BTC to the given Bitcoin address
  • retrieve_btc_status_v2(block_index): returns the status of a previous withdrawal request
  • retrieve_btc_status_v2_by_account(account): returns statuses for all recent withdrawal requests from the given account
  • get_minter_info: returns current minter parameters
  • get_events(start, length): returns the minter’s internal event log

The minter fee for a Bitcoin withdrawal transaction is 146 × inputs + 4 × outputs + 26 satoshi. This formula covers the cost of threshold ECDSA signatures and Bitcoin transaction broadcasting. When multiple withdrawal requests are batched into one transaction, the fee is split among all outputs.

As deposits accumulate, the minter manages a growing set of UTXOs. If the UTXO count exceeds 10,000, the minter periodically creates consolidation transactions that merge the 1,000 smallest UTXOs into 2 new outputs, funded from the minter’s fee subaccount. This prevents the UTXO set from growing large enough to make withdrawals impossible (a Bitcoin transaction is limited to 100 KB).

The ckBTC checker canister (oltsj-fqaaa-aaaar-qal5q-cai) performs know-your-transaction compliance checks on incoming Bitcoin UTXOs. It is called internally by the minter on deposit and is not part of the developer-facing API.

The ckETH minter bridges ETH and all ERC-20 tokens between Ethereum and ICP. It monitors the ckETH helper contract on Ethereum via HTTPS outcalls to detect deposits, and submits signed Ethereum transactions for withdrawals using threshold ECDSA.

For canister IDs, see Chain-Key Token Canister IDs: ckETH.

The minter uses a helper smart contract on Ethereum to receive deposits for both ETH and ERC-20 tokens. Always verify the current address before constructing a deposit transaction:

Terminal window
icp canister call sv3dd-oaaaa-aaaar-qacoa-cai get_minter_info '()' -n ic

Check deposit_with_subaccount_helper_contract_address in the response.

  • get_minter_info: returns current minter info including the helper contract address and supported_ckerc20_tokens
  • withdraw_eth(address, amount): burns ckETH or ckERC20 and submits an Ethereum withdrawal transaction; used for both ETH and all ERC-20 withdrawals
  • get_canister_status: returns the minter’s current status

ckERC20 tokens share the ckETH minter. Each ERC-20 token has its own ICRC-1 ledger canister. New tokens are added via NNS governance proposals.

To get the authoritative current list of supported tokens and their ledger canister IDs at runtime:

Terminal window
icp canister call sv3dd-oaaaa-aaaar-qacoa-cai get_minter_info '()' -n ic

Check supported_ckerc20_tokens in the response. For a static reference table, see Chain-Key Token Canister IDs: ckERC20.

The ckDOGE minter follows the same UTXO-based model as ckBTC. It holds real DOGE in a threshold ECDSA-controlled wallet and issues a unique Dogecoin deposit address per (owner, subaccount) account.

For canister IDs, see Chain-Key Token Canister IDs: ckDOGE.

  • get_deposit_address(owner, subaccount): returns a unique Dogecoin deposit address for the given principal and subaccount
  • update_balance(owner, subaccount): checks for newly confirmed UTXOs and mints ckDOGE
  • retrieve_doge_with_approval(address, amount, from_subaccount): burns ckDOGE via ICRC-2 approval and sends DOGE to the given Dogecoin address
  • get_minter_info: returns current minter parameters

Amounts are denominated in koinu (1 DOGE = 100,000,000 koinu).

Source: dfinity/ic rs/dogecoin/ckdoge

The ckSOL minter bridges SOL between Solana and ICP. It issues a unique Solana deposit address per (owner, subaccount) account and verifies deposits via the SOL RPC canister using threshold signatures (Ed25519).

For canister IDs, see Chain-Key Token Canister IDs: ckSOL.

  • get_deposit_address(owner, subaccount): returns a unique Solana deposit address for the given principal and subaccount
  • process_deposit(tx_signature, owner, subaccount): verifies a Solana deposit transaction and mints ckSOL; requires cycles to cover RPC verification
  • withdraw(address, amount): burns ckSOL via ICRC-2 approval and signs a Solana transaction using threshold Ed25519
  • withdrawal_status(burn_block_index): returns the status of a pending withdrawal

Amounts are denominated in lamports (1 SOL = 1,000,000,000 lamports).

Source: dfinity/cksol

The EVM RPC canister proxies JSON-RPC calls to Ethereum and EVM-compatible chains via HTTPS outcalls. Your canister sends a request to the EVM RPC canister, which fans the request out to multiple RPC providers, compares responses for consensus, and returns the result. No API keys are required for the default providers.

FieldValue
Canister ID7hfb6-caaaa-aaaar-qadga-cai
Subnet34-node fiduciary subnet
Candid interfaceevm_rpc.did
ChainChain ID
Ethereum Mainnet1
Ethereum Sepolia11155111
Arbitrum One42161
Base Mainnet8453
Optimism Mainnet10
Custom EVM chainany

The following providers are available without API keys:

ProviderEthereumSepoliaArbitrumBaseOptimism
Alchemyyesyesyesyesyes
Ankryes-yesyesyes
BlockPiyesyesyesyesyes
Cloudflareyes----
LlamaNodesyes-yesyesyes
PublicNodeyesyesyesyesyes

Each call requires cycles attached. The cost formula is:

(5_912_000 + 60_000 * nodes + 2400 * request_bytes + 800 * max_response_bytes) * nodes * rpc_count

Where nodes = 34 (fiduciary subnet) and rpc_count = number of providers queried. For a practical starting budget, attach 10B cycles per call: unused cycles are refunded. Use the requestCost method to get an exact estimate before calling.

By default, the canister requires all providers to agree (Equality consensus). For calls like eth_getBlockByNumber("latest") where providers may be 1-2 blocks apart, use threshold consensus instead: 2-of-3 agreement. Multi-provider results are returned as MultiRpcResult::Consistent(result) or MultiRpcResult::Inconsistent(results): always handle both variants.

For integration examples, see the Ethereum guide.

The SOL RPC canister proxies JSON-RPC calls to the Solana network via HTTPS outcalls. It follows the same pattern as the EVM RPC canister: each request is forwarded to multiple independent RPC providers and the results are compared for consensus before being returned to the caller. No API keys are required.

FieldValue
Canister ID2xib7-jqaaa-aaaar-qai6q-cai
Sourcedfinity/sol-rpc-canister
Provider
Alchemy
Ankr
Chainstack
dRPC
Helius
PublicNode

For integration examples, see the Solana guide.

The exchange rate canister (XRC) uses HTTPS outcalls to fetch cryptocurrency and foreign exchange rates from major exchanges. It runs on the uzr34 system subnet and is used by the cycles minting canister (CMC) to convert ICP to cycles at a stable XDR-pegged price.

FieldValue
Canister IDuf6dk-hyaaa-aaaaq-qaaaq-cai
Subnetuzr34-akd3s-xrdag-3ql62-ocgoh-ld2ao-tamcv-54e7j-krwgb-2gm4z-oqe
SpecificationXRC interface spec

The XRC pulls from the following exchanges: Coinbase, Kucoin, OKX, Gate.io, MEXC, Poloniex, Crypto.com, Bitget, and DigiFinex.

For forex rates, it queries public APIs from foreign exchange data providers worldwide on a periodic basis.

The XRC calculates rates using candlestick chart data for specific one-minute intervals across exchanges. Rather than time-weighted or volume-weighted averages, it collects, combines, and filters rates from all sources and returns the median. This approach minimizes manipulation risk. The XRC can also derive rates for pairs not directly traded (e.g., A/B from A/C and B/C rates).

The XRC exposes a single endpoint:

get_exchange_rate : (GetExchangeRateRequest) -> (GetExchangeRateResult)

Request:

type GetExchangeRateRequest = record {
base_asset : Asset;
quote_asset : Asset;
timestamp : opt nat64;
};

Asset is a record with a symbol (e.g., "BTC") and class (Cryptocurrency or FiatCurrency). Any combination of digital asset and fiat is supported (e.g., ICP/USD, BTC/ICP, USD/EUR). If timestamp is omitted, the current rate is returned.

Response:

type GetExchangeRateResult = variant {
Ok : ExchangeRate;
Err : ExchangeRateError;
};

Each request requires 1B cycles attached. If insufficient cycles are provided, the canister returns ExchangeRateError::NotEnoughCycles. The actual cost depends on the asset types and cache state:

ConditionActual cost
Served from cache20M cycles
Both assets are fiat currencies20M cycles
One asset is fiat or USDT260M cycles
Both assets are cryptocurrencies500M cycles

Unused cycles are refunded. At least 1M cycles are charged even on error, to prevent denial-of-service attacks.

Calling the XRC requires attaching cycles, which is only possible from canister-to-canister calls. The CLI cannot attach cycles to direct calls. Call the XRC from a canister using the Candid interface: pass the required cycles in the ic_cdk::api::call::call_with_payment128 call or equivalent.

To query the current rate without attaching cycles (for inspection only, expect a NotEnoughCycles error on mainnet):

Terminal window
icp canister call uf6dk-hyaaa-aaaaq-qaaaq-cai get_exchange_rate \
'(record {
base_asset = record { symbol = "BTC"; class = variant { Cryptocurrency } };
quote_asset = record { symbol = "USD"; class = variant { FiatCurrency } };
})' \
-n ic

The SNS Wasm canister (SNS-W) manages the deployment and upgrade of Service Nervous System (SNS) instances. The NNS controls which SNS Wasm binaries are blessed for deployment.

FieldValue
Canister IDqaa6y-5yaaa-aaaaa-aaafa-cai
Subnettdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe (NNS subnet)

The SNS-W canister stores blessed SNS Wasm binaries, creates new SNS instances, and coordinates SNS upgrades. When the NNS passes an SNS upgrade proposal, it installs the new Wasms on each SNS canister via SNS-W.

For governance context, see the SNS documentation.

CanisterIDPurpose
Bitcoin mainnetghsi2-tqaaa-aaaan-aaaca-caiBitcoin mainnet UTXO tracking
Bitcoin testnet (v4)g4xu7-jiaaa-aaaan-aaaaq-caiBitcoin testnet UTXO tracking
ckBTC Mintermqygn-kiaaa-aaaar-qaadq-caiBTC ↔ ckBTC minting and burning
ckBTC KYT Checkeroltsj-fqaaa-aaaar-qal5q-caiKnow-your-transaction compliance
ckETH Mintersv3dd-oaaaa-aaaar-qacoa-caiETH and ERC-20 ↔ ckETH/ckERC20 minting and burning
ckDOGE Mintereqltq-xqaaa-aaaar-qb3vq-caiDOGE ↔ ckDOGE minting and burning
ckSOL Minterlh22c-kyaaa-aaaar-qb5nq-caiSOL ↔ ckSOL minting and burning
EVM RPC7hfb6-caaaa-aaaar-qadga-caiEthereum JSON-RPC proxy
SOL RPC2xib7-jqaaa-aaaar-qai6q-caiSolana JSON-RPC proxy
Exchange Rate (XRC)uf6dk-hyaaa-aaaaq-qaaaq-caiCrypto and forex exchange rates
SNS-Wqaa6y-5yaaa-aaaaa-aaafa-caiSNS deployment and upgrades

For ledger, index, and testnet canister IDs for all chain-key tokens, see Chain-Key Token Canister IDs.

  • Chain-Key Token Canister IDs: ledger, minter, and index IDs for all chain-key tokens
  • Chain-key tokens: deposit, withdrawal, and transfer flows for all chain-key tokens
  • Bitcoin guide: integrating Bitcoin in canisters using the Bitcoin canister and ckBTC
  • Ethereum guide: integrating Ethereum in canisters using the EVM RPC canister and ckETH
  • System canisters: NNS canisters, Internet Identity, ICP ledger, and other network-level canisters
  • Management canister: the virtual canister for canister lifecycle, signing, and platform APIs