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  }