From bf43fbb7ccdc4282aa532664d372351a90f41603 Mon Sep 17 00:00:00 2001 From: Sangbida Chaudhuri <101164840+sangbida@users.noreply.github.com> Date: Tue, 13 Jan 2026 22:52:11 +1030 Subject: [PATCH] lightningd: Fix penalty tx output derivation for BIP86 wallets When using the new BIP39 mnemonic HSM secret format, the wallet uses BIP86 derivation for taproot addresses. However, onchaind_tx_unsigned() was always using bip32_pubkey() to derive the final key for penalty transaction outputs. --- lightningd/onchain_control.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index f62a673a4..1e04cebd5 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -882,15 +882,29 @@ static struct bitcoin_tx *onchaind_tx_unsigned(const tal_t *ctx, struct lightningd *ld = channel->peer->ld; bool keypath_ok; - bip32_pubkey(ld, &final_key, channel->final_key_idx); - if (bip32_key_from_parent(ld->bip32_base, - channel->final_key_idx, - BIP32_FLAG_KEY_PUBLIC, - &final_wallet_ext_key) != WALLY_OK) { - channel_internal_error(channel, - "Could not derive final_wallet_ext_key %"PRIu64, - channel->final_key_idx); - return NULL; + /* Use BIP86 derivation for P2TR if available, otherwise BIP32 */ + if (ld->bip86_base) { + bip86_pubkey(ld, &final_key, channel->final_key_idx); + if (bip32_key_from_parent(ld->bip86_base, + channel->final_key_idx, + BIP32_FLAG_KEY_PUBLIC, + &final_wallet_ext_key) != WALLY_OK) { + channel_internal_error(channel, + "Could not derive final_wallet_ext_key (bip86) %"PRIu64, + channel->final_key_idx); + return NULL; + } + } else { + bip32_pubkey(ld, &final_key, channel->final_key_idx); + if (bip32_key_from_parent(ld->bip32_base, + channel->final_key_idx, + BIP32_FLAG_KEY_PUBLIC, + &final_wallet_ext_key) != WALLY_OK) { + channel_internal_error(channel, + "Could not derive final_wallet_ext_key %"PRIu64, + channel->final_key_idx); + return NULL; + } } tx = bitcoin_tx(ctx, chainparams, 1, 1, info->locktime);