2022-03-23 18:47:00 +00:00
|
|
|
package settings
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2023-04-02 23:08:29 +00:00
|
|
|
"reflect"
|
2022-03-23 18:47:00 +00:00
|
|
|
|
2023-03-06 08:51:09 +00:00
|
|
|
accountJson "github.com/status-im/status-go/account/json"
|
2022-03-23 18:47:00 +00:00
|
|
|
"github.com/status-im/status-go/eth-node/types"
|
2024-02-22 19:32:24 +00:00
|
|
|
"github.com/status-im/status-go/params"
|
2022-03-23 18:47:00 +00:00
|
|
|
"github.com/status-im/status-go/protocol/common"
|
|
|
|
"github.com/status-im/status-go/protocol/protobuf"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ValueHandler func(interface{}) (interface{}, error)
|
2024-02-19 12:09:02 +00:00
|
|
|
type ValueCastHandler func(interface{}) (interface{}, error)
|
2022-11-30 09:41:35 +00:00
|
|
|
type SyncSettingProtobufFactoryInterface func(interface{}, uint64, string) (*common.RawMessage, *protobuf.SyncSetting, error)
|
|
|
|
type SyncSettingProtobufFactoryStruct func(Settings, uint64, string) (*common.RawMessage, *protobuf.SyncSetting, error)
|
2022-03-23 18:47:00 +00:00
|
|
|
type SyncSettingProtobufToValue func(setting *protobuf.SyncSetting) interface{}
|
|
|
|
|
|
|
|
// SyncProtobufFactory represents a collection of functionality to generate and parse *protobuf.SyncSetting
|
|
|
|
type SyncProtobufFactory struct {
|
|
|
|
inactive bool
|
|
|
|
fromInterface SyncSettingProtobufFactoryInterface
|
|
|
|
fromStruct SyncSettingProtobufFactoryStruct
|
|
|
|
valueFromProtobuf SyncSettingProtobufToValue
|
|
|
|
protobufType protobuf.SyncSetting_Type
|
|
|
|
}
|
|
|
|
|
|
|
|
func (spf *SyncProtobufFactory) Inactive() bool {
|
|
|
|
return spf.inactive
|
|
|
|
}
|
|
|
|
|
|
|
|
func (spf *SyncProtobufFactory) FromInterface() SyncSettingProtobufFactoryInterface {
|
|
|
|
return spf.fromInterface
|
|
|
|
}
|
|
|
|
|
|
|
|
func (spf *SyncProtobufFactory) FromStruct() SyncSettingProtobufFactoryStruct {
|
|
|
|
return spf.fromStruct
|
|
|
|
}
|
|
|
|
|
|
|
|
func (spf *SyncProtobufFactory) ExtractValueFromProtobuf() SyncSettingProtobufToValue {
|
|
|
|
return spf.valueFromProtobuf
|
|
|
|
}
|
|
|
|
|
|
|
|
func (spf *SyncProtobufFactory) SyncSettingProtobufType() protobuf.SyncSetting_Type {
|
|
|
|
return spf.protobufType
|
|
|
|
}
|
|
|
|
|
|
|
|
// SyncSettingField represents a binding between a Value and a SettingField
|
|
|
|
type SyncSettingField struct {
|
|
|
|
SettingField
|
|
|
|
Value interface{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s SyncSettingField) MarshalJSON() ([]byte, error) {
|
|
|
|
alias := struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
Value interface{} `json:"value"`
|
|
|
|
}{
|
|
|
|
s.reactFieldName,
|
|
|
|
s.Value,
|
|
|
|
}
|
|
|
|
|
|
|
|
return json.Marshal(alias)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SettingField represents an individual setting in the database, it contains context dependant names and optional
|
|
|
|
// pre-store value parsing, along with optional *SyncProtobufFactory
|
|
|
|
type SettingField struct {
|
|
|
|
reactFieldName string
|
|
|
|
dBColumnName string
|
|
|
|
valueHandler ValueHandler
|
|
|
|
syncProtobufFactory *SyncProtobufFactory
|
2024-02-19 12:09:02 +00:00
|
|
|
valueCastHandler ValueCastHandler
|
2022-03-23 18:47:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s SettingField) GetReactName() string {
|
|
|
|
return s.reactFieldName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s SettingField) GetDBName() string {
|
|
|
|
return s.dBColumnName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s SettingField) ValueHandler() ValueHandler {
|
|
|
|
return s.valueHandler
|
|
|
|
}
|
|
|
|
|
2024-02-19 12:09:02 +00:00
|
|
|
func (s SettingField) ValueCastHandler() ValueCastHandler {
|
|
|
|
return s.valueCastHandler
|
|
|
|
}
|
|
|
|
|
2022-03-23 18:47:00 +00:00
|
|
|
func (s SettingField) SyncProtobufFactory() *SyncProtobufFactory {
|
|
|
|
return s.syncProtobufFactory
|
|
|
|
}
|
|
|
|
|
|
|
|
// CanSync checks if a SettingField has functions supporting the syncing of
|
|
|
|
func (s SettingField) CanSync(source SyncSource) bool {
|
|
|
|
spf := s.syncProtobufFactory
|
|
|
|
|
|
|
|
if spf == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
if spf.inactive {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
switch source {
|
|
|
|
case FromInterface:
|
|
|
|
return spf.fromInterface != nil
|
|
|
|
case FromStruct:
|
|
|
|
return spf.fromStruct != nil
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-09 19:31:47 +00:00
|
|
|
func (s SettingField) Equals(other SettingField) bool {
|
|
|
|
return s.reactFieldName == other.reactFieldName
|
|
|
|
}
|
|
|
|
|
2022-03-23 18:47:00 +00:00
|
|
|
// Settings represents the entire setting row stored in the application db
|
|
|
|
type Settings struct {
|
|
|
|
// required
|
|
|
|
Address types.Address `json:"address"`
|
|
|
|
AnonMetricsShouldSend bool `json:"anon-metrics/should-send?,omitempty"`
|
|
|
|
ChaosMode bool `json:"chaos-mode?,omitempty"`
|
|
|
|
Currency string `json:"currency,omitempty"`
|
|
|
|
CurrentNetwork string `json:"networks/current-network"`
|
|
|
|
CustomBootnodes *json.RawMessage `json:"custom-bootnodes,omitempty"`
|
|
|
|
CustomBootnodesEnabled *json.RawMessage `json:"custom-bootnodes-enabled?,omitempty"`
|
|
|
|
DappsAddress types.Address `json:"dapps-address"`
|
2023-06-27 07:54:49 +00:00
|
|
|
DeviceName string `json:"device-name"`
|
2022-03-23 18:47:00 +00:00
|
|
|
DisplayName string `json:"display-name"`
|
2022-08-05 11:22:35 +00:00
|
|
|
Bio string `json:"bio,omitempty"`
|
2022-03-23 18:47:00 +00:00
|
|
|
EIP1581Address types.Address `json:"eip1581-address"`
|
|
|
|
Fleet *string `json:"fleet,omitempty"`
|
|
|
|
HideHomeTooltip bool `json:"hide-home-tooltip?,omitempty"`
|
|
|
|
InstallationID string `json:"installation-id"`
|
|
|
|
KeyUID string `json:"key-uid"`
|
|
|
|
KeycardInstanceUID string `json:"keycard-instance-uid,omitempty"`
|
2022-08-25 15:09:08 +00:00
|
|
|
KeycardPairedOn int64 `json:"keycard-paired-on,omitempty"`
|
2022-03-23 18:47:00 +00:00
|
|
|
KeycardPairing string `json:"keycard-pairing,omitempty"`
|
|
|
|
LastUpdated *int64 `json:"last-updated,omitempty"`
|
2023-05-08 15:14:46 +00:00
|
|
|
LatestDerivedPath uint `json:"latest-derived-path"`
|
2022-03-23 18:47:00 +00:00
|
|
|
LinkPreviewRequestEnabled bool `json:"link-preview-request-enabled,omitempty"`
|
|
|
|
LinkPreviewsEnabledSites *json.RawMessage `json:"link-previews-enabled-sites,omitempty"`
|
|
|
|
LogLevel *string `json:"log-level,omitempty"`
|
|
|
|
MessagesFromContactsOnly bool `json:"messages-from-contacts-only"`
|
|
|
|
Mnemonic *string `json:"mnemonic,omitempty"`
|
2023-12-01 11:30:42 +00:00
|
|
|
// NOTE(rasom): negation here because it safer/simpler to have false by default
|
2024-08-29 14:03:30 +00:00
|
|
|
MnemonicWasNotShown bool `json:"mnemonic-was-not-shown?,omitempty"`
|
|
|
|
MnemonicRemoved bool `json:"mnemonic-removed?,omitempty"`
|
|
|
|
MutualContactEnabled bool `json:"mutual-contact-enabled?"`
|
|
|
|
Name string `json:"name,omitempty"`
|
|
|
|
Networks *json.RawMessage `json:"networks/networks"`
|
2022-03-23 18:47:00 +00:00
|
|
|
// NotificationsEnabled indicates whether local notifications should be enabled (android only)
|
|
|
|
NotificationsEnabled bool `json:"notifications-enabled?,omitempty"`
|
|
|
|
PhotoPath string `json:"photo-path"`
|
|
|
|
PinnedMailserver *json.RawMessage `json:"pinned-mailservers,omitempty"`
|
2024-03-07 11:37:22 +00:00
|
|
|
// PreferredName represents the user's preferred Ethereum Name Service (ENS) name.
|
|
|
|
// If a user has multiple ENS names, they can select one as the PreferredName.
|
|
|
|
// When PreferredName is set, it takes precedence over the DisplayName for displaying the user's name.
|
|
|
|
// If PreferredName is empty or doesn't match any of the user's ENS names, the DisplayName is used instead.
|
|
|
|
//
|
|
|
|
// There is a race condition between updating DisplayName and PreferredName, where the account.Name field
|
|
|
|
// could be incorrectly updated based on the order in which the backup messages (BackedUpProfile/BackedUpSettings) arrive.
|
|
|
|
// To handle this race condition, the code checks the LastSynced clock value for both DisplayName and PreferredName,
|
|
|
|
// and updates account.Name with the value that has the latest clock
|
|
|
|
PreferredName *string `json:"preferred-name,omitempty"`
|
|
|
|
PreviewPrivacy bool `json:"preview-privacy?"`
|
|
|
|
PublicKey string `json:"public-key"`
|
2022-03-23 18:47:00 +00:00
|
|
|
// PushNotificationsServerEnabled indicates whether we should be running a push notification server
|
|
|
|
PushNotificationsServerEnabled bool `json:"push-notifications-server-enabled?,omitempty"`
|
|
|
|
// PushNotificationsFromContactsOnly indicates whether we should only receive push notifications from contacts
|
|
|
|
PushNotificationsFromContactsOnly bool `json:"push-notifications-from-contacts-only?,omitempty"`
|
|
|
|
// PushNotificationsBlockMentions indicates whether we should receive notifications for mentions
|
|
|
|
PushNotificationsBlockMentions bool `json:"push-notifications-block-mentions?,omitempty"`
|
|
|
|
RememberSyncingChoice bool `json:"remember-syncing-choice?,omitempty"`
|
|
|
|
// RemotePushNotificationsEnabled indicates whether we should be using remote notifications (ios only for now)
|
|
|
|
RemotePushNotificationsEnabled bool `json:"remote-push-notifications-enabled?,omitempty"`
|
|
|
|
SigningPhrase string `json:"signing-phrase"`
|
|
|
|
StickerPacksInstalled *json.RawMessage `json:"stickers/packs-installed,omitempty"`
|
|
|
|
StickerPacksPending *json.RawMessage `json:"stickers/packs-pending,omitempty"`
|
|
|
|
StickersRecentStickers *json.RawMessage `json:"stickers/recent-stickers,omitempty"`
|
|
|
|
SyncingOnMobileNetwork bool `json:"syncing-on-mobile-network?,omitempty"`
|
|
|
|
// DefaultSyncPeriod is how far back in seconds we should pull messages from a mailserver
|
|
|
|
DefaultSyncPeriod uint `json:"default-sync-period"`
|
|
|
|
// SendPushNotifications indicates whether we should send push notifications for other clients
|
|
|
|
SendPushNotifications bool `json:"send-push-notifications?,omitempty"`
|
|
|
|
Appearance uint `json:"appearance"`
|
|
|
|
// ProfilePicturesShowTo indicates to whom the user shows their profile picture to (contacts, everyone)
|
|
|
|
ProfilePicturesShowTo ProfilePicturesShowToType `json:"profile-pictures-show-to"`
|
|
|
|
// ProfilePicturesVisibility indicates who we want to see profile pictures of (contacts, everyone or none)
|
2024-01-05 11:12:53 +00:00
|
|
|
ProfilePicturesVisibility ProfilePicturesVisibilityType `json:"profile-pictures-visibility"`
|
|
|
|
UseMailservers bool `json:"use-mailservers?"`
|
|
|
|
Usernames *json.RawMessage `json:"usernames,omitempty"`
|
|
|
|
WalletRootAddress types.Address `json:"wallet-root-address,omitempty"`
|
|
|
|
WalletSetUpPassed bool `json:"wallet-set-up-passed?,omitempty"`
|
|
|
|
WalletVisibleTokens *json.RawMessage `json:"wallet/visible-tokens,omitempty"`
|
|
|
|
WakuBloomFilterMode bool `json:"waku-bloom-filter-mode,omitempty"`
|
|
|
|
WebViewAllowPermissionRequests bool `json:"webview-allow-permission-requests?,omitempty"`
|
|
|
|
SendStatusUpdates bool `json:"send-status-updates?,omitempty"`
|
|
|
|
CurrentUserStatus *json.RawMessage `json:"current-user-status"`
|
|
|
|
GifRecents *json.RawMessage `json:"gifs/recent-gifs"`
|
|
|
|
GifFavorites *json.RawMessage `json:"gifs/favorite-gifs"`
|
|
|
|
OpenseaEnabled bool `json:"opensea-enabled?,omitempty"`
|
|
|
|
TelemetryServerURL string `json:"telemetry-server-url,omitempty"`
|
2024-06-28 10:24:04 +00:00
|
|
|
TelemetrySendPeriodMs int `json:"telemetry-send-period-ms,omitempty"`
|
2024-01-05 11:12:53 +00:00
|
|
|
LastBackup uint64 `json:"last-backup,omitempty"`
|
|
|
|
BackupEnabled bool `json:"backup-enabled?,omitempty"`
|
|
|
|
AutoMessageEnabled bool `json:"auto-message-enabled?,omitempty"`
|
|
|
|
GifAPIKey string `json:"gifs/api-key"`
|
|
|
|
TestNetworksEnabled bool `json:"test-networks-enabled?,omitempty"`
|
|
|
|
ProfileMigrationNeeded bool `json:"profile-migration-needed,omitempty"`
|
|
|
|
TokenGroupByCommunity bool `json:"token-group-by-community?,omitempty"`
|
|
|
|
ShowCommunityAssetWhenSendingTokens bool `json:"show-community-asset-when-sending-tokens?,omitempty"`
|
|
|
|
DisplayAssetsBelowBalance bool `json:"display-assets-below-balance?,omitempty"`
|
|
|
|
DisplayAssetsBelowBalanceThreshold int64 `json:"display-assets-below-balance-threshold,omitempty"`
|
2024-01-17 13:12:49 +00:00
|
|
|
CollectibleGroupByCollection bool `json:"collectible-group-by-collection?,omitempty"`
|
|
|
|
CollectibleGroupByCommunity bool `json:"collectible-group-by-community?,omitempty"`
|
2024-01-05 11:12:53 +00:00
|
|
|
URLUnfurlingMode URLUnfurlingModeType `json:"url-unfurling-mode,omitempty"`
|
2024-03-05 10:44:09 +00:00
|
|
|
PeerSyncingEnabled bool `json:"peer-syncing-enabled?,omitempty"`
|
2022-03-23 18:47:00 +00:00
|
|
|
}
|
2023-01-20 18:51:36 +00:00
|
|
|
|
|
|
|
func (s Settings) MarshalJSON() ([]byte, error) {
|
2023-03-06 08:51:09 +00:00
|
|
|
// We need this typedef in order to overcome stack overflow
|
|
|
|
// when marshaling JSON
|
2023-01-20 18:51:36 +00:00
|
|
|
type Alias Settings
|
|
|
|
|
2023-03-06 08:51:09 +00:00
|
|
|
ext, err := accountJson.ExtendStructWithPubKeyData(s.PublicKey, Alias(s))
|
2023-01-20 18:51:36 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-03-06 08:51:09 +00:00
|
|
|
return json.Marshal(ext)
|
2023-01-20 18:51:36 +00:00
|
|
|
}
|
2023-04-02 23:08:29 +00:00
|
|
|
|
|
|
|
func (s Settings) IsEmpty() bool {
|
|
|
|
empty := reflect.Zero(reflect.TypeOf(s)).Interface()
|
|
|
|
return reflect.DeepEqual(s, empty)
|
|
|
|
}
|
2024-02-22 19:32:24 +00:00
|
|
|
|
|
|
|
func (s Settings) GetFleet() string {
|
|
|
|
if s.Fleet == nil {
|
|
|
|
return params.FleetUndefined
|
|
|
|
}
|
|
|
|
return *s.Fleet
|
|
|
|
}
|