@@ -37,15 +37,6 @@ import (
37
37
"github.com/ethereum/go-ethereum/params"
38
38
)
39
39
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
-
49
40
// hardenedKeystart is the BIP44 offset to make a keypath element hardened.
50
41
const hardenedKeystart uint32 = hdkeychain .HardenedKeyStart
51
42
@@ -488,16 +479,28 @@ func (backend *Backend) RenameAccount(accountCode accountsTypes.Code, name strin
488
479
return nil
489
480
}
490
481
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
+
491
493
// AccountSetWatch sets the account's persisted watch flag to `watch`. Set to `true` if the account
492
494
// should be loaded even if its keystore is not connected.
493
495
// 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 {
495
497
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 )
499
503
}
500
- acct .Watch = & watch
501
504
return nil
502
505
})
503
506
if err != nil {
@@ -510,18 +513,18 @@ func (backend *Backend) AccountSetWatch(accountCode accountsTypes.Code, watch bo
510
513
//
511
514
// This ensures that removing a keystore after setting an ETH account including tokens to
512
515
// 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 {
514
517
if acct .Config ().Config .CoinCode == coinpkg .CodeETH {
515
518
for _ , erc20TokenCode := range acct .Config ().Config .ActiveTokens {
516
- erc20AccountCode := Erc20AccountCode (accountCode , erc20TokenCode )
519
+ erc20AccountCode := Erc20AccountCode (acct . Config (). Config . Code , erc20TokenCode )
517
520
if tokenAcct := backend .accounts .lookup (erc20AccountCode ); tokenAcct != nil {
518
- tokenAcct .Config ().Config .Watch = & watch
521
+ tokenAcct .Config ().Config .Watch = copyBool ( watch )
519
522
}
520
523
}
521
524
}
522
525
}
523
526
524
- if ! watch {
527
+ if watch == nil || ! * watch {
525
528
backend .initAccounts (false )
526
529
backend .emitAccountsStatusChanged ()
527
530
}
@@ -753,6 +756,12 @@ func (backend *Backend) persistBTCAccountConfig(
753
756
return err
754
757
}
755
758
759
+ var accountWatch * bool
760
+ if backend .config .AppConfig ().Backend .Watchonly {
761
+ t := true
762
+ accountWatch = & t
763
+ }
764
+
756
765
var signingConfigurations signing.Configurations
757
766
for _ , cfg := range supportedConfigs {
758
767
extendedPublicKey , err := keystore .ExtendedPublicKey (coin , cfg .keypath )
@@ -774,7 +783,7 @@ func (backend *Backend) persistBTCAccountConfig(
774
783
if keystore .SupportsUnifiedAccounts () {
775
784
return backend .persistAccount (config.Account {
776
785
HiddenBecauseUnused : hiddenBecauseUnused ,
777
- Watch : defaultWatch ,
786
+ Watch : accountWatch ,
778
787
CoinCode : coin .Code (),
779
788
Name : name ,
780
789
Code : code ,
@@ -794,7 +803,7 @@ func (backend *Backend) persistBTCAccountConfig(
794
803
795
804
err := backend .persistAccount (config.Account {
796
805
HiddenBecauseUnused : hiddenBecauseUnused ,
797
- Watch : defaultWatch ,
806
+ Watch : copyBool ( accountWatch ) ,
798
807
CoinCode : coin .Code (),
799
808
Name : suffixedName ,
800
809
Code : splitAccountCode (code , cfg .ScriptType ()),
@@ -849,9 +858,15 @@ func (backend *Backend) persistETHAccountConfig(
849
858
),
850
859
}
851
860
861
+ var accountWatch * bool
862
+ if backend .config .AppConfig ().Backend .Watchonly {
863
+ t := true
864
+ accountWatch = & t
865
+ }
866
+
852
867
return backend .persistAccount (config.Account {
853
868
HiddenBecauseUnused : hiddenBecauseUnused ,
854
- Watch : defaultWatch ,
869
+ Watch : accountWatch ,
855
870
CoinCode : coin .Code (),
856
871
Name : name ,
857
872
Code : code ,
@@ -864,7 +879,7 @@ func (backend *Backend) persistETHAccountConfig(
864
879
func (backend * Backend ) initPersistedAccounts () {
865
880
// Only load accounts which belong to connected keystores or for which watchonly is enabled.
866
881
keystoreConnectedOrWatch := func (account * config.Account ) bool {
867
- if account .IsWatch () {
882
+ if account .IsWatch (backend . config . AppConfig (). Backend . Watchonly ) {
868
883
return true
869
884
}
870
885
@@ -900,7 +915,7 @@ outer:
900
915
// Watch-only accounts are loaded regardless, and if later e.g. a BitBox02 BTC-only is
901
916
// inserted with the same seed as a Multi, we will need to catch that mismatch when the
902
917
// 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 ) {
904
919
switch coin .(type ) {
905
920
case * btc.Coin :
906
921
for _ , cfg := range account .SigningConfigurations {
@@ -1033,6 +1048,26 @@ func (backend *Backend) maybeAddP2TR(keystore keystore.Keystore, accounts []*con
1033
1048
// were created (persisted) before the introduction of taproot support.
1034
1049
func (backend * Backend ) updatePersistedAccounts (
1035
1050
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
+
1036
1071
return backend .maybeAddP2TR (keystore , accounts )
1037
1072
}
1038
1073
@@ -1069,7 +1104,18 @@ func (backend *Backend) uninitAccounts(force bool) {
1069
1104
keep := []accounts.Interface {}
1070
1105
for _ , account := range backend .accounts {
1071
1106
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 )) {
1073
1119
// Do not uninit/remove account that is being watched.
1074
1120
keep = append (keep , account )
1075
1121
continue
0 commit comments