func (m *Manager) keyToManaged(pubKey []byte, account, branch, index uint32) (ManagedAddress, error) {
	ma, err := newManagedAddressWithoutPrivKey(m, account, pubKey)
	if err != nil {
		return nil, err
	}
	if branch == InternalBranch {
		ma.internal = true
	}
	ma.index = index
	return ma, nil
}
keyToManaged returns a new managed address for a public key and its BIP0044
derivation path from the coin type key.

This function MUST be called with the manager lock held for writes.
package udb
import (
	"crypto/rand"
	"crypto/subtle"
	"fmt"
	"hash"
	"io"
	"sync"
	"decred.org/dcrwallet/v2/errors"
	"decred.org/dcrwallet/v2/internal/compat"
	"decred.org/dcrwallet/v2/kdf"
	"decred.org/dcrwallet/v2/wallet/internal/snacl"
	"decred.org/dcrwallet/v2/wallet/walletdb"
	"github.com/decred/dcrd/chaincfg/v3"
	"github.com/decred/dcrd/dcrec/secp256k1/v4"
	"github.com/decred/dcrd/dcrutil/v4"
	"github.com/decred/dcrd/hdkeychain/v3"
	"github.com/decred/dcrd/txscript/v4/stdaddr"
	"github.com/decred/dcrd/wire"
	"golang.org/x/crypto/blake2b"
	"golang.org/x/crypto/chacha20poly1305"
)
const (
	MaxAccountNum = hdkeychain.HardenedKeyStart - 2  
	MaxAddressesPerAccount = hdkeychain.HardenedKeyStart - 1
	ImportedAddrAccount = MaxAccountNum + 1  
	ImportedAddrAccountName = "imported"
	DefaultAccountNum = 0
	defaultAccountName = "default"
	maxCoinType = hdkeychain.HardenedKeyStart - 1
	ExternalBranch uint32 = 0
	InternalBranch uint32 = 1
)
func isReservedAccountName(name string) bool {
	return name == ImportedAddrAccountName
}
func isReservedAccountNum(acct uint32) bool {
	return acct == ImportedAddrAccount
}
func normalizeAddress(addr stdaddr.Address) stdaddr.Address {
	switch addr := addr.(type) {
	case *stdaddr.AddressPubKeyEcdsaSecp256k1V0:
		return addr.AddressPubKeyHash()
	default:
		return addr
	}
}
type scryptOptions struct {
	N, R, P int
}
func scryptOptionsForNet(net wire.CurrencyNet) *scryptOptions {
	if net == wire.SimNet {
		return &scryptOptions{N: 2, R: 1, P: 1}
	}
	return &scryptOptions{
		N: 262144,  
		R: 8,
		P: 1,
	}
}
type accountInfo struct {
	acctName string
	acctKeyEncrypted []byte
	acctKeyPriv      *hdkeychain.ExtendedKey
	acctKeyPub       *hdkeychain.ExtendedKey
	uniqueKey        *kdf.Argon2idParams
	uniquePassHasher hash.Hash  
	uniquePassHash   []byte
}
func argon2idKey(password []byte, k *kdf.Argon2idParams) keyType {
	return keyType(kdf.DeriveKey(password, k, 32))
}
const (
	xchacha20NonceSize        = 24
	poly1305TagSize           = 16
	xchacha20poly1305Overhead = xchacha20NonceSize + poly1305TagSize
)
type keyType []byte
func seal(rand io.Reader, key keyType, plaintext []byte) ([]byte, error) {
	sealedLen := len(plaintext) + xchacha20poly1305Overhead
	nonce := make([]byte, xchacha20NonceSize, sealedLen)
	_, err := io.ReadFull(rand, nonce)
	if err != nil {
		return nil, errors.E(errors.IO, err)
	}
	aead, err := chacha20poly1305.NewX(key)
	if err != nil {
		panic(err)
	}
	sealed := aead.Seal(nonce, nonce, plaintext, nil)
	return sealed, nil
}
func unseal(key keyType, ciphertext []byte) ([]byte, error) {
	aead, err := chacha20poly1305.NewX(key)
	if err != nil {
		panic(err)
	}
	if len(ciphertext) < xchacha20poly1305Overhead {
		e := errors.Errorf("ciphertext too short (len %d) "+
			"to encode nonce and MAC tag", len(ciphertext))
		return nil, errors.E(errors.Crypto, e)
	}
	nonce := ciphertext[:xchacha20NonceSize]
	ciphertext = ciphertext[xchacha20NonceSize:]
	plaintext, err := aead.Open(nil, nonce, ciphertext, nil)
	if err != nil {
		return nil, errors.E(errors.Passphrase)
	}
	return plaintext, nil
}
type AccountProperties = struct {
	AccountNumber             uint32
	AccountName               string
	LastUsedExternalIndex     uint32
	LastUsedInternalIndex     uint32
	LastReturnedExternalIndex uint32
	LastReturnedInternalIndex uint32
	ImportedKeyCount          uint32
	AccountEncrypted          bool
	AccountUnlocked           bool
}
func defaultNewSecretKey(passphrase *[]byte, config *scryptOptions) (*snacl.SecretKey, error) {
	return snacl.NewSecretKey(passphrase, config.N, config.R, config.P)
}
var newSecretKey = defaultNewSecretKey
type EncryptorDecryptor interface {
	Encrypt(in []byte) ([]byte, error)
	Decrypt(in []byte) ([]byte, error)
	Bytes() []byte
	CopyBytes([]byte)
	Zero()
}
type cryptoKey struct {
	snacl.CryptoKey
}
func (ck *cryptoKey) Bytes() []byte {
	return ck.CryptoKey[:]
}
func (ck *cryptoKey) CopyBytes(from []byte) {
	copy(ck.CryptoKey[:], from)
}
func defaultNewCryptoKey() (EncryptorDecryptor, error) {
	key, err := snacl.GenerateCryptoKey()
	if err != nil {
		return nil, err
	}
	return &cryptoKey{*key}, nil
}
type CryptoKeyType byte
const (
	CKTPrivate CryptoKeyType = iota
	_  
	CKTPublic
)
var newCryptoKey = defaultNewCryptoKey
type Manager struct {
	mtx sync.RWMutex
	chainParams  *chaincfg.Params
	watchingOnly bool
	locked       bool
	closed       bool
	acctInfo map[uint32]*accountInfo
	masterKeyPub  *snacl.SecretKey
	masterKeyPriv *snacl.SecretKey
	cryptoKeyPub EncryptorDecryptor
	cryptoKeyPrivEncrypted []byte
	cryptoKeyPriv          EncryptorDecryptor
	privPassphraseHasher   hash.Hash
	privPassphraseHasherMu sync.Mutex  
	privPassphraseHash     []byte      
}
func zero(b []byte) {
	for i := range b {
		b[i] = 0
	}
}
func (m *Manager) lock() {
	for _, acctInfo := range m.acctInfo {
		if acctInfo.acctKeyPriv != nil {
			acctInfo.acctKeyPriv.Zero()
		}
		acctInfo.acctKeyPriv = nil
	}
	m.cryptoKeyPriv.Zero()
	m.masterKeyPriv.Zero()
	m.locked = true
	m.privPassphraseHash = nil
}
func (m *Manager) zeroSensitivePublicData() {
	for _, acctInfo := range m.acctInfo {
		acctInfo.acctKeyPub.Zero()
		acctInfo.acctKeyPub = nil
	}
	m.cryptoKeyPub.Zero()
	m.masterKeyPub.Zero()
}
func (m *Manager) WatchingOnly() bool {
	return m.watchingOnly
}
func (m *Manager) Close() error {
	m.mtx.Lock()
	defer m.mtx.Unlock()
	if !m.watchingOnly && !m.locked {
		m.lock()
	}
	m.zeroSensitivePublicData()
	m.closed = true
	return nil
}