From adb3d77c86c4cc2ea88550e3e5a5d3bfc9f4d04f Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Wed, 17 Feb 2021 16:24:28 -0800 Subject: [PATCH] waddrmgr: extend AccountProperties with watch-only account properties --- waddrmgr/manager.go | 45 ++++++++++++++++++++++++++++++++++++-- waddrmgr/scoped_manager.go | 22 ++++++++++++++----- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/waddrmgr/manager.go b/waddrmgr/manager.go index bf1ca6f..5de694f 100644 --- a/waddrmgr/manager.go +++ b/waddrmgr/manager.go @@ -166,16 +166,57 @@ type accountInfo struct { // could be used to import accounts that use the traditional BIP-0049 // derivation scheme into our KeyScopeBIP-0049Plus manager. addrSchema *ScopeAddrSchema + + // masterKeyFingerprint represents the fingerprint of the root key + // corresponding to the master public key (also known as the key with + // derivation path m/). This may be required by some hardware wallets + // for proper identification and signing. + masterKeyFingerprint uint32 } // AccountProperties contains properties associated with each account, such as // the account name, number, and the nubmer of derived and imported keys. type AccountProperties struct { - AccountNumber uint32 - AccountName string + // AccountNumber is the internal number used to reference the account. + AccountNumber uint32 + + // AccountName is the user-identifying name of the account. + AccountName string + + // ExternalKeyCount is the number of internal keys that have been + // derived for the account. ExternalKeyCount uint32 + + // InternalKeyCount is the number of internal keys that have been + // derived for the account. InternalKeyCount uint32 + + // ImportedKeyCount is the number of imported keys found within the + // account. ImportedKeyCount uint32 + + // AccountPubKey is the account's public key that can be used to + // derive any address relevant to said account. + // + // NOTE: This may be nil for imported accounts. + AccountPubKey *hdkeychain.ExtendedKey + + // MasterKeyFingerprint represents the fingerprint of the root key + // corresponding to the master public key (also known as the key with + // derivation path m/). This may be required by some hardware wallets + // for proper identification and signing. + MasterKeyFingerprint uint32 + + // KeyScope is the key scope the account belongs to. + KeyScope KeyScope + + // IsWatchOnly indicates whether the is set up as watch-only, i.e., it + // doesn't contain any private key information. + IsWatchOnly bool + + // AddrSchema, if non-nil, specifies an address schema override for + // address generation only applicable to the account. + AddrSchema *ScopeAddrSchema } // unlockDeriveInfo houses the information needed to derive a private key for a diff --git a/waddrmgr/scoped_manager.go b/waddrmgr/scoped_manager.go index 239cda6..41b1fba 100644 --- a/waddrmgr/scoped_manager.go +++ b/waddrmgr/scoped_manager.go @@ -71,7 +71,7 @@ type ScopedIndex struct { // String returns a human readable version describing the keypath encapsulated // by the target key scope. -func (k *KeyScope) String() string { +func (k KeyScope) String() string { return fmt.Sprintf("m/%v'/%v'", k.Purpose, k.Coin) } @@ -362,10 +362,11 @@ func (s *ScopedKeyManager) loadAccountInfo(ns walletdb.ReadBucket, case *dbWatchOnlyAccountRow: acctInfo = &accountInfo{ - acctName: row.name, - nextExternalIndex: row.nextExternalIndex, - nextInternalIndex: row.nextInternalIndex, - addrSchema: row.addrSchema, + acctName: row.name, + nextExternalIndex: row.nextExternalIndex, + nextInternalIndex: row.nextInternalIndex, + addrSchema: row.addrSchema, + masterKeyFingerprint: row.masterKeyFingerprint, } // Use the crypto public key to decrypt the account public @@ -442,7 +443,10 @@ func (s *ScopedKeyManager) AccountProperties(ns walletdb.ReadBucket, defer s.mtx.RUnlock() s.mtx.RLock() - props := &AccountProperties{AccountNumber: account} + props := &AccountProperties{ + AccountNumber: account, + KeyScope: s.scope, + } // Until keys can be imported into any account, special handling is // required for the imported account. @@ -463,8 +467,14 @@ func (s *ScopedKeyManager) AccountProperties(ns walletdb.ReadBucket, props.AccountName = acctInfo.acctName props.ExternalKeyCount = acctInfo.nextExternalIndex props.InternalKeyCount = acctInfo.nextInternalIndex + props.AccountPubKey = acctInfo.acctKeyPub + props.MasterKeyFingerprint = acctInfo.masterKeyFingerprint + props.IsWatchOnly = s.rootManager.WatchOnly() || + acctInfo.acctKeyPriv == nil + props.AddrSchema = acctInfo.addrSchema } else { props.AccountName = ImportedAddrAccountName // reserved, nonchangable + props.IsWatchOnly = s.rootManager.WatchOnly() // Could be more efficient if this was tracked by the db. var importedKeyCount uint32