Demonstrates reading Bitcoin balance from a canister on the Internet Computer using the Bitcoin canister API.
| IC Network | Bitcoin Network | Bitcoin Canister ID |
|---|---|---|
| Local (PocketIC) | regtest | g4xu7-jiaaa-aaaan-aaaaq-cai |
| IC mainnet | testnet | g4xu7-jiaaa-aaaan-aaaaq-cai |
| IC mainnet | mainnet | ghsi2-tqaaa-aaaan-aaaca-cai |
The BITCOIN_NETWORK environment variable controls which network and canister to use. It is configured per environment in icp.yaml.
Note: Docker is used in this guide to run
bitcoindfor simplicity. If you prefer, you can install and runbitcoindnatively instead — just make sure it is listening on the same ports (18443for RPC,18444for P2P) with the same credentials.
Start a Bitcoin regtest node:
docker run -d --name bitcoind \
-p 18443:18443 -p 18444:18444 \
lncm/bitcoind:v27.2 \
-regtest -server -rpcbind=0.0.0.0 -rpcallowip=0.0.0.0/0 \
-rpcuser=ic-btc-integration -rpcpassword=ic-btc-integration \
-fallbackfee=0.00001 -txindex=1Start the local IC network and deploy:
icp network start -d
icp deployVerify the configured network and Bitcoin canister ID:
icp canister call backend get_config '()'Create a wallet and get a Bitcoin address:
docker exec bitcoind bitcoin-cli -regtest \
-rpcuser=ic-btc-integration -rpcpassword=ic-btc-integration \
createwallet "default"
ADDR=$(docker exec bitcoind bitcoin-cli -regtest \
-rpcuser=ic-btc-integration -rpcpassword=ic-btc-integration \
getnewaddress)Check the balance (should be 0):
icp canister call backend get_balance "(\"$ADDR\")"Mine a block to the address (each block rewards 50 BTC):
docker exec bitcoind bitcoin-cli -regtest \
-rpcuser=ic-btc-integration -rpcpassword=ic-btc-integration \
generatetoaddress 1 "$ADDR"Check the balance again (should be 5,000,000,000 satoshis = 50 BTC):
Note: Coinbase rewards require 100 confirmations before they can be spent. If you extend this example to send transactions, mine at least 101 blocks so the first block's reward becomes spendable.
icp canister call backend get_balance "(\"$ADDR\")"icp network stop
docker stop bitcoind && docker rm bitcoind| Environment | IC Network | Bitcoin Network | Usage |
|---|---|---|---|
local |
Local (PocketIC) | regtest | icp deploy |
staging |
IC mainnet | testnet | icp deploy --env staging |
production |
IC mainnet | mainnet | icp deploy --env production |
Bitcoin canister API calls require cycles. The canister must attach cycles when calling the Bitcoin canister — the Rust CDK handles this automatically, while the Motoko backend attaches them explicitly via (with cycles = amount).
| API Call | Testnet / Regtest | Mainnet |
|---|---|---|
bitcoin_get_balance |
40,000,000 | 100,000,000 |
bitcoin_get_utxos |
4,000,000,000 | 10,000,000,000 |
bitcoin_send_transaction |
2,000,000,000 | 5,000,000,000 |
See Bitcoin API costs for the full reference.
- Bitcoin Canister API Specification — full API reference (get_utxos, send_transaction, fee percentiles, etc.)
- Developer Docs - How to build on Bitcoin