waddrmgr: add ImportPublicKey
This commit is contained in:
parent
ee9a1fb0ce
commit
dead1a89d9
1 changed files with 61 additions and 5 deletions
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
"github.com/btcsuite/btcutil/hdkeychain"
|
"github.com/btcsuite/btcutil/hdkeychain"
|
||||||
"github.com/btcsuite/btcwallet/internal/zero"
|
"github.com/btcsuite/btcwallet/internal/zero"
|
||||||
|
@ -1527,7 +1528,10 @@ func (s *ScopedKeyManager) ImportPrivateKey(ns walletdb.ReadWriteBucket,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.importPublicKey(ns, wif.SerializePubKey(), encryptedPrivKey, bs)
|
err := s.importPublicKey(
|
||||||
|
ns, wif.SerializePubKey(), encryptedPrivKey,
|
||||||
|
s.addrSchema.ExternalAddrType, bs,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -1550,15 +1554,67 @@ func (s *ScopedKeyManager) ImportPrivateKey(ns walletdb.ReadWriteBucket,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImportPublicKey imports a public key into the address manager.
|
||||||
|
//
|
||||||
|
// All imported addresses will be part of the account defined by the
|
||||||
|
// ImportedAddrAccount constant.
|
||||||
|
func (s *ScopedKeyManager) ImportPublicKey(ns walletdb.ReadWriteBucket,
|
||||||
|
pubKey *btcec.PublicKey, bs *BlockStamp) (ManagedAddress, error) {
|
||||||
|
|
||||||
|
s.mtx.Lock()
|
||||||
|
defer s.mtx.Unlock()
|
||||||
|
|
||||||
|
serializedPubKey := pubKey.SerializeCompressed()
|
||||||
|
err := s.importPublicKey(
|
||||||
|
ns, serializedPubKey, nil, s.addrSchema.ExternalAddrType, bs,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The full derivation path for an imported key is incomplete as we
|
||||||
|
// don't know exactly how it was derived.
|
||||||
|
importedDerivationPath := DerivationPath{
|
||||||
|
Account: ImportedAddrAccount,
|
||||||
|
}
|
||||||
|
return s.toPublicManagedAddress(
|
||||||
|
pubKey, true, true, importedDerivationPath,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// importPublicKey imports a public key into the address manager and updates the
|
// importPublicKey imports a public key into the address manager and updates the
|
||||||
// wallet's start block if necessary. An error is returned if the public key
|
// wallet's start block if necessary. An error is returned if the public key
|
||||||
// already exists.
|
// already exists.
|
||||||
func (s *ScopedKeyManager) importPublicKey(ns walletdb.ReadWriteBucket,
|
func (s *ScopedKeyManager) importPublicKey(ns walletdb.ReadWriteBucket,
|
||||||
serializedPubKey, encryptedPrivKey []byte, bs *BlockStamp) error {
|
serializedPubKey, encryptedPrivKey []byte, addrType AddressType,
|
||||||
|
bs *BlockStamp) error {
|
||||||
|
|
||||||
|
// Compute the addressID for our key based on its address type.
|
||||||
|
var addressID []byte
|
||||||
|
switch addrType {
|
||||||
|
case PubKeyHash, WitnessPubKey:
|
||||||
|
addressID = btcutil.Hash160(serializedPubKey)
|
||||||
|
|
||||||
|
case NestedWitnessPubKey:
|
||||||
|
pubKeyHash := btcutil.Hash160(serializedPubKey)
|
||||||
|
p2wkhAddr, err := btcutil.NewAddressWitnessPubKeyHash(
|
||||||
|
pubKeyHash, s.rootManager.chainParams,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
witnessScript, err := txscript.PayToAddrScript(p2wkhAddr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
addressID = btcutil.Hash160(witnessScript)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported address type %v", addrType)
|
||||||
|
}
|
||||||
|
|
||||||
// Prevent duplicates.
|
// Prevent duplicates.
|
||||||
pubKeyHash := btcutil.Hash160(serializedPubKey)
|
alreadyExists := s.existsAddress(ns, addressID)
|
||||||
alreadyExists := s.existsAddress(ns, pubKeyHash)
|
|
||||||
if alreadyExists {
|
if alreadyExists {
|
||||||
str := fmt.Sprintf("address for public key %x already exists",
|
str := fmt.Sprintf("address for public key %x already exists",
|
||||||
serializedPubKey)
|
serializedPubKey)
|
||||||
|
@ -1584,7 +1640,7 @@ func (s *ScopedKeyManager) importPublicKey(ns walletdb.ReadWriteBucket,
|
||||||
// Save the new imported address to the db and update start block (if
|
// Save the new imported address to the db and update start block (if
|
||||||
// needed) in a single transaction.
|
// needed) in a single transaction.
|
||||||
err = putImportedAddress(
|
err = putImportedAddress(
|
||||||
ns, &s.scope, pubKeyHash, ImportedAddrAccount, ssNone,
|
ns, &s.scope, addressID, ImportedAddrAccount, ssNone,
|
||||||
encryptedPubKey, encryptedPrivKey,
|
encryptedPubKey, encryptedPrivKey,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue