Bitcoin
Examples:
There are two main ways to interact with Bitcoin on ICP: through the management canister and through the ckBTC canister.
management canister
To sign Bitcoin transactions using threshold ECDSA and interact with the Bitcoin blockchain directly from ICP, make cross-canister calls to the following methods on the management canister: ecdsa_public_key
, sign_with_ecdsa
, bitcoin_get_balance
, bitcoin_get_balance_query
, bitcoin_get_utxos
, bitcoin_get_utxos_query
, bitcoin_send_transaction
, bitcoin_get_current_fee_percentiles
.
To construct your cross-canister calls to these methods, use canister id
aaaaa-aa
and the management canister's Candid type information to construct the arguments to send in the body
of your fetch
call.
Here's an example of doing a test cross-canister call to the bitcoin_get_balance
method:
import { serialize } from 'azle/experimental';
// ...
const response = await fetch(`icp://aaaaa-aa/bitcoin_get_balance`, {
body: serialize({
args: [
{
'bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c',
min_confirmations: [],
network: { regtest: null }
}
],
cycles: 100_000_000n
})
});
const responseJson = await response.json();
// ...
ckBTC
ckBTC is an ICRC canister that wraps underlying bitcoin controlled with threshold ECDSA.
ICRCs are a set of standards for ICP canisters that define the method signatures and corresponding types for those canisters.
You interact with the ckBTC
canister by calling its methods. You can do this from the frontend with @dfinity/agent, or from an Azle canister through cross-canister calls.
Here's an example of doing a test cross-canister call to the ckBTC
icrc1_balance_of
method:
import { ic, serialize } from 'azle/experimental';
// ...
const response = await fetch(
`icp://mc6ru-gyaaa-aaaar-qaaaq-cai/icrc1_balance_of`,
{
body: serialize({
candidPath: `/candid/icp/icrc.did`,
args: [
{
owner: ic.id(),
subaccount: [
padPrincipalWithZeros(ic.caller().toUint8Array())
]
}
]
})
}
);
const responseJson = await response.json();
// ...
function padPrincipalWithZeros(principalBlob: Uint8Array): Uint8Array {
let newUin8Array = new Uint8Array(32);
newUin8Array.set(principalBlob);
return newUin8Array;
}