Replicating BTC Address Derivation Algorithm from ckBTC Minter

Hi everyone,

I’m currently working on implementing functionality to derive Bitcoin addresses on the frontend for the ckBTC minter canister, which is used in the minting process. This address derivation is deterministic, using an owner principal and an optional subaccount to generate a unique BTC address for the account. My objective is to replicate the exact BTC address that the minter would return when I call get_btc_address with the same principal and subaccount pair.

However, I’m running into some challenges replicating the algorithm on the frontend because I don’t have access to the minter’s ecdsa_public_key or ecdsa_key_name, both of which seem essential to the derivation process.

Here’s a summary of the algorithm I’m attempting to implement:

  1. Call the minter canister: Make a call to IC method ecdsa_public_key once with the minter canister ID and store the response somewhere (or even hardcode it).
  2. Convert the account: Use the account to derive a P2WPKH address.
  3. Use the SEC1 compressed public key to compute the hash160, which is the result of applying RIPEMD-160(SHA-256(public_key)).
  4. Encode the result into Bech32 format using encode_bech32("bc", hash160).

Does this approach look feasible and correct? Is there a way I can obtain the minter’s ecdsa_public_key and ecdsa_key_name to complete the derivation, or are there any shortcuts or alternative methods I can use?

Any advice or suggestions would be greatly appreciated!

Thanks in advance!

Is there any code available in Motoko or js that can replicate the derivation done in the ckbtc minter from the ckbtc xpubkey to the users’ deposit address?

And is this derivation bip32 compatible, ie long blobs are chunked up into nat32 derivation step sizes, or is it custom, ie non compatible with bip32?

We have provided Motoko and js code for the derivation here:

mops: Mops • Motoko Package Manager
npm: @research-ag/ckbtc-address-js - npm

To answer the question: long blobs are not chunked up into nat32 derivation steps. The derivation is not compatible with bip32 in the sense that the indices are not limited to 32 bits. Otherwise it is compatible. The derivation indices are [1, principal bytes, subaccount bytes].