@@ -37,15 +37,6 @@ import (
3737 "github.com/ethereum/go-ethereum/params"
3838)
3939
40- // Set the `watch` setting on new accounts to this default value.
41- // For now we keep it unset, and have users opt-in to watching specific accounts.
42- //
43- // We set it to `nil` not `false` so that we reserve the possibility to default all accounts to
44- // watch-only for accounts where the user hasn't made an active decision (e.g. turn on watch-only
45- // for all accounts of a keystore if the user did not activate/deactivate watch-only manually on any
46- // of them).
47- var defaultWatch * bool = nil
48-
4940// hardenedKeystart is the BIP44 offset to make a keypath element hardened.
5041const hardenedKeystart uint32 = hdkeychain .HardenedKeyStart
5142
@@ -488,16 +479,28 @@ func (backend *Backend) RenameAccount(accountCode accountsTypes.Code, name strin
488479 return nil
489480}
490481
482+ // copyBool makes a copy, so that multiple values do not share the same reference. This avoids
483+ // potential future bugs if someone modified a flag like `*account.Watch = X`,
484+ // accidentally changing the value for many accounts that share the same reference.
485+ func copyBool (b * bool ) * bool {
486+ if b == nil {
487+ return nil
488+ }
489+ cpy := * b
490+ return & cpy
491+ }
492+
491493// AccountSetWatch sets the account's persisted watch flag to `watch`. Set to `true` if the account
492494// should be loaded even if its keystore is not connected.
493495// If `watch` is set to `false`, the account is unloaded and the frontend notified.
494- func (backend * Backend ) AccountSetWatch (accountCode accountsTypes. Code , watch bool ) error {
496+ func (backend * Backend ) AccountSetWatch (filter func ( * config. Account ) bool , watch * bool ) error {
495497 err := backend .config .ModifyAccountsConfig (func (accountsConfig * config.AccountsConfig ) error {
496- acct := accountsConfig .Lookup (accountCode )
497- if acct == nil {
498- return errp .Newf ("Could not find account %s" , accountCode )
498+ for _ , acct := range accountsConfig .Accounts {
499+ if ! filter (acct ) {
500+ continue
501+ }
502+ acct .Watch = copyBool (watch )
499503 }
500- acct .Watch = & watch
501504 return nil
502505 })
503506 if err != nil {
@@ -510,18 +513,18 @@ func (backend *Backend) AccountSetWatch(accountCode accountsTypes.Code, watch bo
510513 //
511514 // This ensures that removing a keystore after setting an ETH account including tokens to
512515 // watchonly results in the account *and* the tokens remaining loaded.
513- if acct := backend .accounts . lookup ( accountCode ); acct != nil {
516+ for _ , acct := range backend .accounts {
514517 if acct .Config ().Config .CoinCode == coinpkg .CodeETH {
515518 for _ , erc20TokenCode := range acct .Config ().Config .ActiveTokens {
516- erc20AccountCode := Erc20AccountCode (accountCode , erc20TokenCode )
519+ erc20AccountCode := Erc20AccountCode (acct . Config (). Config . Code , erc20TokenCode )
517520 if tokenAcct := backend .accounts .lookup (erc20AccountCode ); tokenAcct != nil {
518- tokenAcct .Config ().Config .Watch = & watch
521+ tokenAcct .Config ().Config .Watch = copyBool ( watch )
519522 }
520523 }
521524 }
522525 }
523526
524- if ! watch {
527+ if watch == nil || ! * watch {
525528 backend .initAccounts (false )
526529 backend .emitAccountsStatusChanged ()
527530 }
@@ -753,6 +756,12 @@ func (backend *Backend) persistBTCAccountConfig(
753756 return err
754757 }
755758
759+ var accountWatch * bool
760+ if backend .config .AppConfig ().Backend .Watchonly {
761+ t := true
762+ accountWatch = & t
763+ }
764+
756765 var signingConfigurations signing.Configurations
757766 for _ , cfg := range supportedConfigs {
758767 extendedPublicKey , err := keystore .ExtendedPublicKey (coin , cfg .keypath )
@@ -774,7 +783,7 @@ func (backend *Backend) persistBTCAccountConfig(
774783 if keystore .SupportsUnifiedAccounts () {
775784 return backend .persistAccount (config.Account {
776785 HiddenBecauseUnused : hiddenBecauseUnused ,
777- Watch : defaultWatch ,
786+ Watch : accountWatch ,
778787 CoinCode : coin .Code (),
779788 Name : name ,
780789 Code : code ,
@@ -794,7 +803,7 @@ func (backend *Backend) persistBTCAccountConfig(
794803
795804 err := backend .persistAccount (config.Account {
796805 HiddenBecauseUnused : hiddenBecauseUnused ,
797- Watch : defaultWatch ,
806+ Watch : copyBool ( accountWatch ) ,
798807 CoinCode : coin .Code (),
799808 Name : suffixedName ,
800809 Code : splitAccountCode (code , cfg .ScriptType ()),
@@ -849,9 +858,15 @@ func (backend *Backend) persistETHAccountConfig(
849858 ),
850859 }
851860
861+ var accountWatch * bool
862+ if backend .config .AppConfig ().Backend .Watchonly {
863+ t := true
864+ accountWatch = & t
865+ }
866+
852867 return backend .persistAccount (config.Account {
853868 HiddenBecauseUnused : hiddenBecauseUnused ,
854- Watch : defaultWatch ,
869+ Watch : accountWatch ,
855870 CoinCode : coin .Code (),
856871 Name : name ,
857872 Code : code ,
@@ -864,7 +879,7 @@ func (backend *Backend) persistETHAccountConfig(
864879func (backend * Backend ) initPersistedAccounts () {
865880 // Only load accounts which belong to connected keystores or for which watchonly is enabled.
866881 keystoreConnectedOrWatch := func (account * config.Account ) bool {
867- if account .IsWatch () {
882+ if account .IsWatch (backend . config . AppConfig (). Backend . Watchonly ) {
868883 return true
869884 }
870885
@@ -900,7 +915,7 @@ outer:
900915 // Watch-only accounts are loaded regardless, and if later e.g. a BitBox02 BTC-only is
901916 // inserted with the same seed as a Multi, we will need to catch that mismatch when the
902917 // keystore will be used to e.g. display an Ethereum address etc.
903- if backend .keystore != nil && ! account .IsWatch () {
918+ if backend .keystore != nil && ! account .IsWatch (backend . config . AppConfig (). Backend . Watchonly ) {
904919 switch coin .(type ) {
905920 case * btc.Coin :
906921 for _ , cfg := range account .SigningConfigurations {
@@ -1033,6 +1048,26 @@ func (backend *Backend) maybeAddP2TR(keystore keystore.Keystore, accounts []*con
10331048// were created (persisted) before the introduction of taproot support.
10341049func (backend * Backend ) updatePersistedAccounts (
10351050 keystore keystore.Keystore , accounts []* config.Account ) error {
1051+
1052+ // setWatch, if the global Watchonly flag is enabled, sets the `Watch`
1053+ // flag to `true`, turning this account into a watch-only account.
1054+ setWatch := func () error {
1055+ if ! backend .config .AppConfig ().Backend .Watchonly {
1056+ return nil
1057+ }
1058+ for _ , account := range accounts {
1059+ if account .Watch == nil {
1060+ t := true
1061+ account .Watch = & t
1062+ }
1063+ }
1064+ return nil
1065+ }
1066+
1067+ if err := setWatch (); err != nil {
1068+ return err
1069+ }
1070+
10361071 return backend .maybeAddP2TR (keystore , accounts )
10371072}
10381073
@@ -1069,7 +1104,18 @@ func (backend *Backend) uninitAccounts(force bool) {
10691104 keep := []accounts.Interface {}
10701105 for _ , account := range backend .accounts {
10711106 account := account
1072- if ! force && account .Config ().Config .IsWatch () {
1107+
1108+ belongsToKeystore := false
1109+ if backend .keystore != nil {
1110+ fingerprint , err := backend .keystore .RootFingerprint ()
1111+ if err != nil {
1112+ backend .log .WithError (err ).Error ("could not retrieve keystore fingerprint" )
1113+ } else {
1114+ belongsToKeystore = account .Config ().Config .SigningConfigurations .ContainsRootFingerprint (fingerprint )
1115+ }
1116+ }
1117+
1118+ if ! force && (belongsToKeystore || account .Config ().Config .IsWatch (backend .config .AppConfig ().Backend .Watchonly )) {
10731119 // Do not uninit/remove account that is being watched.
10741120 keep = append (keep , account )
10751121 continue
0 commit comments