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.
This commit is contained in:
Sangbida Chaudhuri
2026-01-13 22:52:11 +10:30
committed by Rusty Russell
parent 9b85ce7b03
commit bf43fbb7cc

View File

@@ -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);