lnwallet+lnrpc: add derivation info for P2TR change addrs
In some situations (for example in Taproot Assets), we need to be able to prove that an address is a bare BIP-0086 address that doesn't commit to any script. We can do that by providing the BIP-0032 derivation info and internal key.
This commit is contained in:
4 files changed
+250
-1
No files matched your search
@@ -9,12 +9,14 @@ import (
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/btcutil/hdkeychain"
|
||||
"github.com/btcsuite/btcd/btcutil/psbt"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcwallet/waddrmgr"
|
||||
"github.com/btcsuite/btcwallet/wallet"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
@@ -640,3 +642,78 @@ func (b *BtcWallet) lookupFirstCustomAccount(
|
||||
|
||||
return keyScope, account.AccountNumber, nil
|
||||
}
|
||||
|
||||
// Bip32DerivationFromKeyDesc returns the default and Taproot BIP-0032 key
|
||||
// derivation information from the given key descriptor information.
|
||||
func Bip32DerivationFromKeyDesc(keyDesc keychain.KeyDescriptor,
|
||||
coinType uint32) (*psbt.Bip32Derivation, *psbt.TaprootBip32Derivation,
|
||||
string) {
|
||||
|
||||
bip32Derivation := &psbt.Bip32Derivation{
|
||||
PubKey: keyDesc.PubKey.SerializeCompressed(),
|
||||
Bip32Path: []uint32{
|
||||
keychain.BIP0043Purpose + hdkeychain.HardenedKeyStart,
|
||||
coinType + hdkeychain.HardenedKeyStart,
|
||||
uint32(keyDesc.Family) +
|
||||
uint32(hdkeychain.HardenedKeyStart),
|
||||
0,
|
||||
keyDesc.Index,
|
||||
},
|
||||
}
|
||||
|
||||
derivationPath := fmt.Sprintf(
|
||||
"m/%d'/%d'/%d'/%d/%d", keychain.BIP0043Purpose, coinType,
|
||||
keyDesc.Family, 0, keyDesc.Index,
|
||||
)
|
||||
|
||||
return bip32Derivation, &psbt.TaprootBip32Derivation{
|
||||
XOnlyPubKey: bip32Derivation.PubKey[1:],
|
||||
MasterKeyFingerprint: bip32Derivation.MasterKeyFingerprint,
|
||||
Bip32Path: bip32Derivation.Bip32Path,
|
||||
LeafHashes: make([][]byte, 0),
|
||||
}, derivationPath
|
||||
}
|
||||
|
||||
// Bip32DerivationFromAddress returns the default and Taproot BIP-0032 key
|
||||
// derivation information from the given managed address.
|
||||
func Bip32DerivationFromAddress(
|
||||
addr waddrmgr.ManagedAddress) (*psbt.Bip32Derivation,
|
||||
*psbt.TaprootBip32Derivation, string, error) {
|
||||
|
||||
pubKeyAddr, ok := addr.(waddrmgr.ManagedPubKeyAddress)
|
||||
if !ok {
|
||||
return nil, nil, "", fmt.Errorf("address is not a pubkey " +
|
||||
"address")
|
||||
}
|
||||
|
||||
scope, derivationInfo, haveInfo := pubKeyAddr.DerivationInfo()
|
||||
if !haveInfo {
|
||||
return nil, nil, "", fmt.Errorf("address is an imported " +
|
||||
"public key, can't derive BIP32 path")
|
||||
}
|
||||
|
||||
bip32Derivation := &psbt.Bip32Derivation{
|
||||
PubKey: pubKeyAddr.PubKey().SerializeCompressed(),
|
||||
Bip32Path: []uint32{
|
||||
scope.Purpose + hdkeychain.HardenedKeyStart,
|
||||
scope.Coin + hdkeychain.HardenedKeyStart,
|
||||
derivationInfo.InternalAccount +
|
||||
hdkeychain.HardenedKeyStart,
|
||||
derivationInfo.Branch,
|
||||
derivationInfo.Index,
|
||||
},
|
||||
}
|
||||
|
||||
derivationPath := fmt.Sprintf(
|
||||
"m/%d'/%d'/%d'/%d/%d", scope.Purpose, scope.Coin,
|
||||
derivationInfo.InternalAccount, derivationInfo.Branch,
|
||||
derivationInfo.Index,
|
||||
)
|
||||
|
||||
return bip32Derivation, &psbt.TaprootBip32Derivation{
|
||||
XOnlyPubKey: bip32Derivation.PubKey[1:],
|
||||
MasterKeyFingerprint: bip32Derivation.MasterKeyFingerprint,
|
||||
Bip32Path: bip32Derivation.Bip32Path,
|
||||
LeafHashes: make([][]byte, 0),
|
||||
}, derivationPath, nil
|
||||
}
|
||||
Reference in new issue
Block a user