Can I send to Bech32 testnet address?

I have the basic-bitcoin tutorial deployed at cfza3-5aaaa-aaaag-qa7lq-cai.
Everything works except the send function. When I try to send my btc back to the test net faucet
dfx canister --network=ic call basic_bitcoin send '(record { destination_address = “tb1qndnfnxvjupgyfut6skz8mdj6zcmgu9r65rv7lr”; amount_in_satoshi = 321; }) ’
I get the following error:
WARN: The default identity is not stored securely. Do not use it to control a lot of cycles/ICP. Create a new identity with dfx identity create and use it in mainnet-facing commands with the --identity flag
Error: Failed update call.
Caused by: Failed update call.
The Replica returned an error: code 4, message: “IC0503: Canister cfza3-5aaaa-aaaag-qa7lq-cai trapped explicitly: assertion failed at”

It seems like the code is not able to send to a Bech32 address (tb1…).

Have to support address converting before sending txn

Thanks, but how is that done?

So yeah, that appears to be a bug and not a feature:

I was able to send sats to a testnet faucet address starting with an m. No change of code.

According to this document, Bech32 is not supported in current implementation

According to that document P2WPKH, P2WSH, P2TR are all supported and they are bech32.

The limitation is not in the Bitcoin integration, it is only in the basic_bitcoin example code. See here:

An outer function is taking dst_address and is assuming it is p2pkh when passing it to an inner function. Unfortunately, the inner function only accepts the p2pkh type:

Not sure how necessary that restriction is. There is a whole file for bech32 in that repo:

Looking at the bitcoin_canister, it seems supported, let me do a local and mainnet test shortly

Thanks for looking into it!

I’m using an address derived this way

  // Get BTC address for a given user:
  public func get_btc_address_for_a_given_user(user_principal : Principal) : async Text {
    let derivation_path_with_double_array : [[Nat8]] = await get_btc_derivation_path_for_a_given_user(user_principal);
    let bitcoin_address : Text = await get_p2pkh_address_for_a_given_derivation_path(derivation_path_with_double_array);
    return bitcoin_address;

  // Get BTC derivation path for a given user:
  public func get_btc_derivation_path_for_a_given_user(user_principal : Principal) : async [[Nat8]] {
    let user_principal_blob : Blob = Principal.toBlob(user_principal);
    let user_principal_array : [Nat8] = Blob.toArray(user_principal_blob);
    let derivation_path_with_double_array : [[Nat8]] = [user_principal_array];
    return derivation_path_with_double_array;

  // Adapted from BasicBitcoin example:
  /// Returns the P2PKH address of this canister for a given (as an argument) derivation path.
  public func get_p2pkh_address_for_a_given_derivation_path(derivation_path : [[Nat8]]) : async BitcoinAddress {
    await BitcoinWallet.get_p2pkh_address(NETWORK, KEY_NAME, derivation_path);

And on send I’m seeing

Uncaught (in promise) Error: Call was rejected:
  Request ID: bdd267afdeb9a1abda78fd1627bbdae5ea7654a2ef1e03e7ab43f64f7fa63ab6
  Reject code: 4
  Reject text: IC0503: Canister rrkah-fqaaa-aaaaa-aaaaq-cai trapped explicitly: Error building transaction.


[Canister rrkah-fqaaa-aaaaa-aaaaq-cai] Fetching UTXOs...
[Canister rrkah-fqaaa-aaaaa-aaaaq-cai] Building transaction...
[Canister rrkah-fqaaa-aaaaa-aaaaq-cai] pattern failed

How might I fix this?

The problem arises only on send. Address generation throws no errors.