github.com/status-im/status-go@v1.1.0/multiaccounts/settings/structs.go (about) 1 package settings 2 3 import ( 4 "encoding/json" 5 "reflect" 6 7 accountJson "github.com/status-im/status-go/account/json" 8 "github.com/status-im/status-go/eth-node/types" 9 "github.com/status-im/status-go/params" 10 "github.com/status-im/status-go/protocol/common" 11 "github.com/status-im/status-go/protocol/protobuf" 12 ) 13 14 type ValueHandler func(interface{}) (interface{}, error) 15 type ValueCastHandler func(interface{}) (interface{}, error) 16 type SyncSettingProtobufFactoryInterface func(interface{}, uint64, string) (*common.RawMessage, *protobuf.SyncSetting, error) 17 type SyncSettingProtobufFactoryStruct func(Settings, uint64, string) (*common.RawMessage, *protobuf.SyncSetting, error) 18 type SyncSettingProtobufToValue func(setting *protobuf.SyncSetting) interface{} 19 20 // SyncProtobufFactory represents a collection of functionality to generate and parse *protobuf.SyncSetting 21 type SyncProtobufFactory struct { 22 inactive bool 23 fromInterface SyncSettingProtobufFactoryInterface 24 fromStruct SyncSettingProtobufFactoryStruct 25 valueFromProtobuf SyncSettingProtobufToValue 26 protobufType protobuf.SyncSetting_Type 27 } 28 29 func (spf *SyncProtobufFactory) Inactive() bool { 30 return spf.inactive 31 } 32 33 func (spf *SyncProtobufFactory) FromInterface() SyncSettingProtobufFactoryInterface { 34 return spf.fromInterface 35 } 36 37 func (spf *SyncProtobufFactory) FromStruct() SyncSettingProtobufFactoryStruct { 38 return spf.fromStruct 39 } 40 41 func (spf *SyncProtobufFactory) ExtractValueFromProtobuf() SyncSettingProtobufToValue { 42 return spf.valueFromProtobuf 43 } 44 45 func (spf *SyncProtobufFactory) SyncSettingProtobufType() protobuf.SyncSetting_Type { 46 return spf.protobufType 47 } 48 49 // SyncSettingField represents a binding between a Value and a SettingField 50 type SyncSettingField struct { 51 SettingField 52 Value interface{} 53 } 54 55 func (s SyncSettingField) MarshalJSON() ([]byte, error) { 56 alias := struct { 57 Name string `json:"name"` 58 Value interface{} `json:"value"` 59 }{ 60 s.reactFieldName, 61 s.Value, 62 } 63 64 return json.Marshal(alias) 65 } 66 67 // SettingField represents an individual setting in the database, it contains context dependant names and optional 68 // pre-store value parsing, along with optional *SyncProtobufFactory 69 type SettingField struct { 70 reactFieldName string 71 dBColumnName string 72 valueHandler ValueHandler 73 syncProtobufFactory *SyncProtobufFactory 74 valueCastHandler ValueCastHandler 75 } 76 77 func (s SettingField) GetReactName() string { 78 return s.reactFieldName 79 } 80 81 func (s SettingField) GetDBName() string { 82 return s.dBColumnName 83 } 84 85 func (s SettingField) ValueHandler() ValueHandler { 86 return s.valueHandler 87 } 88 89 func (s SettingField) ValueCastHandler() ValueCastHandler { 90 return s.valueCastHandler 91 } 92 93 func (s SettingField) SyncProtobufFactory() *SyncProtobufFactory { 94 return s.syncProtobufFactory 95 } 96 97 // CanSync checks if a SettingField has functions supporting the syncing of 98 func (s SettingField) CanSync(source SyncSource) bool { 99 spf := s.syncProtobufFactory 100 101 if spf == nil { 102 return false 103 } 104 105 if spf.inactive { 106 return false 107 } 108 109 switch source { 110 case FromInterface: 111 return spf.fromInterface != nil 112 case FromStruct: 113 return spf.fromStruct != nil 114 default: 115 return false 116 } 117 } 118 119 func (s SettingField) Equals(other SettingField) bool { 120 return s.reactFieldName == other.reactFieldName 121 } 122 123 // Settings represents the entire setting row stored in the application db 124 type Settings struct { 125 // required 126 Address types.Address `json:"address"` 127 AnonMetricsShouldSend bool `json:"anon-metrics/should-send?,omitempty"` 128 ChaosMode bool `json:"chaos-mode?,omitempty"` 129 Currency string `json:"currency,omitempty"` 130 CurrentNetwork string `json:"networks/current-network"` 131 CustomBootnodes *json.RawMessage `json:"custom-bootnodes,omitempty"` 132 CustomBootnodesEnabled *json.RawMessage `json:"custom-bootnodes-enabled?,omitempty"` 133 DappsAddress types.Address `json:"dapps-address"` 134 DeviceName string `json:"device-name"` 135 DisplayName string `json:"display-name"` 136 Bio string `json:"bio,omitempty"` 137 EIP1581Address types.Address `json:"eip1581-address"` 138 Fleet *string `json:"fleet,omitempty"` 139 HideHomeTooltip bool `json:"hide-home-tooltip?,omitempty"` 140 InstallationID string `json:"installation-id"` 141 KeyUID string `json:"key-uid"` 142 KeycardInstanceUID string `json:"keycard-instance-uid,omitempty"` 143 KeycardPairedOn int64 `json:"keycard-paired-on,omitempty"` 144 KeycardPairing string `json:"keycard-pairing,omitempty"` 145 LastUpdated *int64 `json:"last-updated,omitempty"` 146 LatestDerivedPath uint `json:"latest-derived-path"` 147 LinkPreviewRequestEnabled bool `json:"link-preview-request-enabled,omitempty"` 148 LinkPreviewsEnabledSites *json.RawMessage `json:"link-previews-enabled-sites,omitempty"` 149 LogLevel *string `json:"log-level,omitempty"` 150 MessagesFromContactsOnly bool `json:"messages-from-contacts-only"` 151 Mnemonic *string `json:"mnemonic,omitempty"` 152 // NOTE(rasom): negation here because it safer/simpler to have false by default 153 MnemonicWasNotShown bool `json:"mnemonic-was-not-shown?,omitempty"` 154 MnemonicRemoved bool `json:"mnemonic-removed?,omitempty"` 155 MutualContactEnabled bool `json:"mutual-contact-enabled?"` 156 Name string `json:"name,omitempty"` 157 Networks *json.RawMessage `json:"networks/networks"` 158 // NotificationsEnabled indicates whether local notifications should be enabled (android only) 159 NotificationsEnabled bool `json:"notifications-enabled?,omitempty"` 160 PhotoPath string `json:"photo-path"` 161 PinnedMailserver *json.RawMessage `json:"pinned-mailservers,omitempty"` 162 // PreferredName represents the user's preferred Ethereum Name Service (ENS) name. 163 // If a user has multiple ENS names, they can select one as the PreferredName. 164 // When PreferredName is set, it takes precedence over the DisplayName for displaying the user's name. 165 // If PreferredName is empty or doesn't match any of the user's ENS names, the DisplayName is used instead. 166 // 167 // There is a race condition between updating DisplayName and PreferredName, where the account.Name field 168 // could be incorrectly updated based on the order in which the backup messages (BackedUpProfile/BackedUpSettings) arrive. 169 // To handle this race condition, the code checks the LastSynced clock value for both DisplayName and PreferredName, 170 // and updates account.Name with the value that has the latest clock 171 PreferredName *string `json:"preferred-name,omitempty"` 172 PreviewPrivacy bool `json:"preview-privacy?"` 173 PublicKey string `json:"public-key"` 174 // PushNotificationsServerEnabled indicates whether we should be running a push notification server 175 PushNotificationsServerEnabled bool `json:"push-notifications-server-enabled?,omitempty"` 176 // PushNotificationsFromContactsOnly indicates whether we should only receive push notifications from contacts 177 PushNotificationsFromContactsOnly bool `json:"push-notifications-from-contacts-only?,omitempty"` 178 // PushNotificationsBlockMentions indicates whether we should receive notifications for mentions 179 PushNotificationsBlockMentions bool `json:"push-notifications-block-mentions?,omitempty"` 180 RememberSyncingChoice bool `json:"remember-syncing-choice?,omitempty"` 181 // RemotePushNotificationsEnabled indicates whether we should be using remote notifications (ios only for now) 182 RemotePushNotificationsEnabled bool `json:"remote-push-notifications-enabled?,omitempty"` 183 SigningPhrase string `json:"signing-phrase"` 184 StickerPacksInstalled *json.RawMessage `json:"stickers/packs-installed,omitempty"` 185 StickerPacksPending *json.RawMessage `json:"stickers/packs-pending,omitempty"` 186 StickersRecentStickers *json.RawMessage `json:"stickers/recent-stickers,omitempty"` 187 SyncingOnMobileNetwork bool `json:"syncing-on-mobile-network?,omitempty"` 188 // DefaultSyncPeriod is how far back in seconds we should pull messages from a mailserver 189 DefaultSyncPeriod uint `json:"default-sync-period"` 190 // SendPushNotifications indicates whether we should send push notifications for other clients 191 SendPushNotifications bool `json:"send-push-notifications?,omitempty"` 192 Appearance uint `json:"appearance"` 193 // ProfilePicturesShowTo indicates to whom the user shows their profile picture to (contacts, everyone) 194 ProfilePicturesShowTo ProfilePicturesShowToType `json:"profile-pictures-show-to"` 195 // ProfilePicturesVisibility indicates who we want to see profile pictures of (contacts, everyone or none) 196 ProfilePicturesVisibility ProfilePicturesVisibilityType `json:"profile-pictures-visibility"` 197 UseMailservers bool `json:"use-mailservers?"` 198 Usernames *json.RawMessage `json:"usernames,omitempty"` 199 WalletRootAddress types.Address `json:"wallet-root-address,omitempty"` 200 WalletSetUpPassed bool `json:"wallet-set-up-passed?,omitempty"` 201 WalletVisibleTokens *json.RawMessage `json:"wallet/visible-tokens,omitempty"` 202 WakuBloomFilterMode bool `json:"waku-bloom-filter-mode,omitempty"` 203 WebViewAllowPermissionRequests bool `json:"webview-allow-permission-requests?,omitempty"` 204 SendStatusUpdates bool `json:"send-status-updates?,omitempty"` 205 CurrentUserStatus *json.RawMessage `json:"current-user-status"` 206 GifRecents *json.RawMessage `json:"gifs/recent-gifs"` 207 GifFavorites *json.RawMessage `json:"gifs/favorite-gifs"` 208 OpenseaEnabled bool `json:"opensea-enabled?,omitempty"` 209 TelemetryServerURL string `json:"telemetry-server-url,omitempty"` 210 TelemetrySendPeriodMs int `json:"telemetry-send-period-ms,omitempty"` 211 LastBackup uint64 `json:"last-backup,omitempty"` 212 BackupEnabled bool `json:"backup-enabled?,omitempty"` 213 AutoMessageEnabled bool `json:"auto-message-enabled?,omitempty"` 214 GifAPIKey string `json:"gifs/api-key"` 215 TestNetworksEnabled bool `json:"test-networks-enabled?,omitempty"` 216 ProfileMigrationNeeded bool `json:"profile-migration-needed,omitempty"` 217 IsGoerliEnabled bool `json:"is-goerli-enabled?,omitempty"` 218 TokenGroupByCommunity bool `json:"token-group-by-community?,omitempty"` 219 ShowCommunityAssetWhenSendingTokens bool `json:"show-community-asset-when-sending-tokens?,omitempty"` 220 DisplayAssetsBelowBalance bool `json:"display-assets-below-balance?,omitempty"` 221 DisplayAssetsBelowBalanceThreshold int64 `json:"display-assets-below-balance-threshold,omitempty"` 222 CollectibleGroupByCollection bool `json:"collectible-group-by-collection?,omitempty"` 223 CollectibleGroupByCommunity bool `json:"collectible-group-by-community?,omitempty"` 224 URLUnfurlingMode URLUnfurlingModeType `json:"url-unfurling-mode,omitempty"` 225 PeerSyncingEnabled bool `json:"peer-syncing-enabled?,omitempty"` 226 } 227 228 func (s Settings) MarshalJSON() ([]byte, error) { 229 // We need this typedef in order to overcome stack overflow 230 // when marshaling JSON 231 type Alias Settings 232 233 ext, err := accountJson.ExtendStructWithPubKeyData(s.PublicKey, Alias(s)) 234 if err != nil { 235 return nil, err 236 } 237 return json.Marshal(ext) 238 } 239 240 func (s Settings) IsEmpty() bool { 241 empty := reflect.Zero(reflect.TypeOf(s)).Interface() 242 return reflect.DeepEqual(s, empty) 243 } 244 245 func (s Settings) GetFleet() string { 246 if s.Fleet == nil { 247 return params.FleetUndefined 248 } 249 return *s.Fleet 250 }