refactor(settings-service): settings improved
Since we had 2 services dealing with the same `status-go` settings, this commit merges them into a single one. Also we have new public methods exposed what minimizes a possibility for error since a key for each setting is kept in the service.
This commit is contained in:
parent
7c36e98cf3
commit
7a9784b854
|
@ -12,14 +12,12 @@ import ../../app_service/service/token/service as token_service
|
|||
import ../../app_service/service/transaction/service as transaction_service
|
||||
import ../../app_service/service/collectible/service as collectible_service
|
||||
import ../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import ../../app_service/service/setting/service as setting_service
|
||||
import ../../app_service/service/bookmarks/service as bookmark_service
|
||||
import ../../app_service/service/dapp_permissions/service as dapp_permissions_service
|
||||
import ../../app_service/service/mnemonic/service as mnemonic_service
|
||||
import ../../app_service/service/privacy/service as privacy_service
|
||||
import ../../app_service/service/provider/service as provider_service
|
||||
import ../../app_service/service/ens/service as ens_service
|
||||
|
||||
import ../../app_service/service/profile/service as profile_service
|
||||
import ../../app_service/service/settings/service as settings_service
|
||||
import ../../app_service/service/about/service as about_service
|
||||
|
@ -92,7 +90,6 @@ type
|
|||
transactionService: transaction_service.Service
|
||||
collectibleService: collectible_service.Service
|
||||
walletAccountService: wallet_account_service.Service
|
||||
settingService: setting_service.Service
|
||||
bookmarkService: bookmark_service.Service
|
||||
dappPermissionsService: dapp_permissions_service.Service
|
||||
ensService: ens_service.Service
|
||||
|
@ -167,7 +164,6 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
|||
# Services
|
||||
result.osNotificationService = os_notification_service.newService(statusFoundation.status.events)
|
||||
result.keychainService = keychain_service.newService(statusFoundation.status.events)
|
||||
result.settingService = setting_service.newService()
|
||||
result.settingsService = settings_service.newService()
|
||||
result.accountsService = accounts_service.newService()
|
||||
result.contactsService = contacts_service.newService(statusFoundation.status.events, statusFoundation.threadpool)
|
||||
|
@ -175,9 +171,9 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
|||
result.communityService = community_service.newService(result.chatService)
|
||||
result.messageService = message_service.newService(statusFoundation.status.events, statusFoundation.threadpool)
|
||||
result.tokenService = token_service.newService(statusFoundation.status.events, statusFoundation.threadpool,
|
||||
result.settingService, result.settingsService)
|
||||
result.collectibleService = collectible_service.newService(result.settingService)
|
||||
result.walletAccountService = wallet_account_service.newService(statusFoundation.status.events, result.settingService,
|
||||
result.settingsService)
|
||||
result.collectibleService = collectible_service.newService(result.settingsService)
|
||||
result.walletAccountService = wallet_account_service.newService(statusFoundation.status.events, result.settingsService,
|
||||
result.tokenService)
|
||||
result.transactionService = transaction_service.newService(statusFoundation.status.events, statusFoundation.threadpool,
|
||||
result.walletAccountService)
|
||||
|
@ -212,7 +208,6 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
|||
result.collectibleService,
|
||||
result.walletAccountService,
|
||||
result.bookmarkService,
|
||||
result.settingService,
|
||||
result.profileService,
|
||||
result.settingsService,
|
||||
result.contactsService,
|
||||
|
@ -236,18 +231,6 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
|||
result.connect()
|
||||
#################################################
|
||||
|
||||
# Adding status and statusFoundation here now is just because of having a controll
|
||||
# over order of execution while we integrating this refactoring architecture
|
||||
# into the current app state.
|
||||
# Once we complete refactoring process we will get rid of "status" part/lib.
|
||||
#
|
||||
# This to will be adapted to appropriate modules later:
|
||||
# result.login = login.newController(statusFoundation.status, statusFoundation)
|
||||
# result.onboarding = onboarding.newController(statusFoundation.status)
|
||||
# singletonInstance.engine.setRootContextProperty("loginModel", result.login.variant)
|
||||
# singletonInstance.engine.setRootContextProperty("onboardingModel", result.onboarding.variant)
|
||||
#result.connect()
|
||||
|
||||
proc delete*(self: AppController) =
|
||||
self.osNotificationService.delete
|
||||
self.contactsService.delete
|
||||
|
@ -279,7 +262,7 @@ proc delete*(self: AppController) =
|
|||
self.tokenService.delete
|
||||
self.transactionService.delete
|
||||
self.collectibleService.delete
|
||||
self.settingService.delete
|
||||
self.settingsService.delete
|
||||
self.walletAccountService.delete
|
||||
self.aboutService.delete
|
||||
self.dappPermissionsService.delete
|
||||
|
@ -323,13 +306,12 @@ proc start*(self: AppController) =
|
|||
self.startupModule.load()
|
||||
|
||||
proc load(self: AppController) =
|
||||
self.settingService.init()
|
||||
self.settingsService.init()
|
||||
self.contactsService.init()
|
||||
self.chatService.init()
|
||||
self.communityService.init()
|
||||
self.bookmarkService.init()
|
||||
self.tokenService.init()
|
||||
self.settingsService.init()
|
||||
self.dappPermissionsService.init()
|
||||
self.ensService.init()
|
||||
self.providerService.init()
|
||||
|
@ -337,12 +319,9 @@ proc load(self: AppController) =
|
|||
self.transactionService.init()
|
||||
self.languageService.init()
|
||||
|
||||
#################################################
|
||||
# Once SettingService gets added, `pubKey` should be fetched from there, instead the following line:
|
||||
let pubKey = self.settingsService.getPubKey()
|
||||
let pubKey = self.settingsService.getPublicKey()
|
||||
singletonInstance.localAccountSensitiveSettings.setFileName(pubKey)
|
||||
singletonInstance.engine.setRootContextProperty("localAccountSensitiveSettings", self.localAccountSensitiveSettingsVariant)
|
||||
#################################################
|
||||
|
||||
# other global instances
|
||||
self.buildAndRegisterLocalAccountSensitiveSettings()
|
||||
|
@ -361,24 +340,34 @@ proc userLoggedIn*(self: AppController) =
|
|||
self.load()
|
||||
|
||||
proc buildAndRegisterLocalAccountSensitiveSettings(self: AppController) =
|
||||
var pubKey = self.settingsService.getPubKey()
|
||||
var pubKey = self.settingsService.getPublicKey()
|
||||
singletonInstance.localAccountSensitiveSettings.setFileName(pubKey)
|
||||
singletonInstance.engine.setRootContextProperty("localAccountSensitiveSettings", self.localAccountSensitiveSettingsVariant)
|
||||
|
||||
proc buildAndRegisterUserProfile(self: AppController) =
|
||||
let loggedInAccount = self.accountsService.getLoggedInAccount()
|
||||
|
||||
let pubKey = self.settingsService.getPubKey()
|
||||
let sendUserStatus = self.settingsService.getSendUserStatus()
|
||||
let pubKey = self.settingsService.getPublicKey()
|
||||
let sendUserStatus = self.settingsService.getSendStatusUpdates()
|
||||
## This is still not in use. Read a comment in UserProfile.
|
||||
## let currentUserStatus = self.settingsService.getCurrentUserStatus()
|
||||
let obj = self.settingsService.getIdentityImage(loggedInAccount.keyUid)
|
||||
|
||||
let loggedInAccount = self.accountsService.getLoggedInAccount()
|
||||
var thumbnail, large: string
|
||||
for img in loggedInAccount.images:
|
||||
if(img.imgType == "large"):
|
||||
large = img.uri
|
||||
elif(img.imgType == "thumbnail"):
|
||||
thumbnail = img.uri
|
||||
|
||||
let meAsContact = self.contactsService.getContactById(pubKey)
|
||||
var ensName: string
|
||||
if(meAsContact.ensVerified):
|
||||
ensName = prettyEnsName(meAsContact.name)
|
||||
|
||||
singletonInstance.userProfile.setFixedData(loggedInAccount.name, loggedInAccount.keyUid, loggedInAccount.identicon,
|
||||
pubKey)
|
||||
singletonInstance.userProfile.setEnsName("") # in this moment we don't know ens name
|
||||
singletonInstance.userProfile.setThumbnailImage(obj.thumbnail)
|
||||
singletonInstance.userProfile.setLargeImage(obj.large)
|
||||
singletonInstance.userProfile.setEnsName(ensName)
|
||||
singletonInstance.userProfile.setThumbnailImage(thumbnail)
|
||||
singletonInstance.userProfile.setLargeImage(large)
|
||||
singletonInstance.userProfile.setUserStatus(sendUserStatus)
|
||||
|
||||
singletonInstance.engine.setRootContextProperty("userProfile", self.userProfileVariant)
|
||||
|
|
|
@ -12,7 +12,7 @@ QtObject:
|
|||
thumbnailImage: string
|
||||
largeImage: string
|
||||
userStatus: bool
|
||||
currentUserStatus: int
|
||||
#currentUserStatus: int
|
||||
|
||||
proc setup(self: UserProfile) =
|
||||
self.QObject.setup
|
||||
|
|
|
@ -35,11 +35,11 @@ method getDappsAddress*(self: Controller): string =
|
|||
return self.settingsService.getDappsAddress()
|
||||
|
||||
method setDappsAddress*(self: Controller, address: string) =
|
||||
if self.settingsService.setDappsAddress(address):
|
||||
if self.settingsService.saveDappsAddress(address):
|
||||
self.delegate.onDappAddressChanged(address)
|
||||
|
||||
method getCurrentNetworkDetails*(self: Controller): NetworkDetails =
|
||||
return self.settingsService.getCurrentNetworkDetails()
|
||||
method getCurrentNetworkId*(self: Controller): int =
|
||||
return self.settingsService.getCurrentNetworkId()
|
||||
|
||||
method disconnect*(self: Controller) =
|
||||
discard self.dappPermissionsService.revoke("web3".toPermission())
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import ../../../../../app_service/service/settings/service as settings_service
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
@ -16,7 +14,7 @@ method getDappsAddress*(self: AccessInterface): string {.base.} =
|
|||
method setDappsAddress*(self: AccessInterface, address: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getCurrentNetworkDetails*(self: AccessInterface): NetworkDetails {.base.} =
|
||||
method getCurrentNetworkId*(self: AccessInterface): int {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method disconnect*(self: AccessInterface) {.base.} =
|
||||
|
|
|
@ -36,7 +36,7 @@ method delete*(self: Module) =
|
|||
method load*(self: Module) =
|
||||
singletonInstance.engine.setRootContextProperty("providerModule", self.viewVariant)
|
||||
self.view.dappsAddress = self.controller.getDappsAddress()
|
||||
self.view.networkId = self.controller.getCurrentNetworkDetails().config.networkId
|
||||
self.view.networkId = self.controller.getCurrentNetworkId()
|
||||
self.view.load()
|
||||
|
||||
method isLoaded*(self: Module): bool =
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import item, controller_interface, io_interface
|
||||
import item, controller_interface, io_interface, chronicles
|
||||
import ../../global/global_singleton
|
||||
|
||||
import ../../../app_service/service/settings/service_interface as settings_service
|
||||
|
@ -12,6 +12,9 @@ import eventemitter
|
|||
|
||||
export controller_interface
|
||||
|
||||
logScope:
|
||||
topics = "main-module-controller"
|
||||
|
||||
type
|
||||
Controller* = ref object of controller_interface.AccessInterface
|
||||
delegate: io_interface.AccessInterface
|
||||
|
@ -139,5 +142,7 @@ method getNumOfNotificaitonsForCommunity*(self: Controller, communityId: string)
|
|||
result.mentions += chat.unviewedMentionsCount
|
||||
|
||||
method setUserStatus*(self: Controller, status: bool) =
|
||||
self.settingsService.setSendUserStatus(status)
|
||||
if(self.settingsService.saveSendStatusUpdates(status)):
|
||||
singletonInstance.userProfile.setUserStatus(status)
|
||||
else:
|
||||
error "error updating user status"
|
|
@ -18,14 +18,12 @@ import ../../../app_service/service/token/service as token_service
|
|||
import ../../../app_service/service/transaction/service as transaction_service
|
||||
import ../../../app_service/service/collectible/service as collectible_service
|
||||
import ../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import ../../../app_service/service/setting/service as setting_service
|
||||
import ../../../app_service/service/bookmarks/service as bookmark_service
|
||||
import ../../../app_service/service/dapp_permissions/service as dapp_permissions_service
|
||||
import ../../../app_service/service/provider/service as provider_service
|
||||
|
||||
import ../../../app_service/service/profile/service as profile_service
|
||||
import ../../../app_service/service/accounts/service as accounts_service
|
||||
import ../../../app_service/service/settings/service as settings_service
|
||||
import ../../../app_service/service/settings/service_interface as settings_service
|
||||
import ../../../app_service/service/contacts/service as contacts_service
|
||||
import ../../../app_service/service/about/service as about_service
|
||||
import ../../../app_service/service/language/service as language_service
|
||||
|
@ -63,7 +61,6 @@ proc newModule*[T](
|
|||
collectibleService: collectible_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
bookmarkService: bookmark_service.ServiceInterface,
|
||||
settingService: setting_service.Service,
|
||||
profileService: profile_service.ServiceInterface,
|
||||
settingsService: settings_service.ServiceInterface,
|
||||
contactsService: contacts_service.Service,
|
||||
|
@ -87,7 +84,7 @@ proc newModule*[T](
|
|||
communityService, messageService)
|
||||
result.communitySectionsModule = initOrderedTable[string, chat_section_module.AccessInterface]()
|
||||
result.walletSectionModule = wallet_section_module.newModule[Module[T]](result, events, tokenService,
|
||||
transactionService, collectible_service, walletAccountService, settingService)
|
||||
transactionService, collectible_service, walletAccountService, settingsService)
|
||||
result.browserSectionModule = browser_section_module.newModule(result, bookmarkService, settingsService,
|
||||
dappPermissionsService, providerService)
|
||||
result.profileSectionModule = profile_section_module.newModule(result, events, accountsService, settingsService,
|
||||
|
|
|
@ -4,7 +4,7 @@ import controller_interface
|
|||
|
||||
import ../../../../app_service/service/profile/service as profile_service
|
||||
import ../../../../app_service/service/accounts/service as accounts_service
|
||||
import ../../../../app_service/service/settings/service as settings_service
|
||||
import ../../../../app_service/service/settings/service_interface as settings_service
|
||||
import ../../../../app_service/service/language/service as language_service
|
||||
import ../../../../app_service/service/mnemonic/service as mnemonic_service
|
||||
import ../../../../app_service/service/privacy/service as privacy_service
|
||||
|
@ -22,7 +22,10 @@ type
|
|||
mnemonicService: mnemonic_service.ServiceInterface
|
||||
privacyService: privacy_service.ServiceInterface
|
||||
|
||||
proc newController*[T](delegate: T, accountsService: accounts_service.ServiceInterface, settingsService: settings_service.ServiceInterface, profileService: profile_service.ServiceInterface, languageService: language_service.ServiceInterface, mnemonicService: mnemonic_service.ServiceInterface, privacyService: privacy_service.ServiceInterface): Controller[T] =
|
||||
proc newController*[T](delegate: T, accountsService: accounts_service.ServiceInterface,
|
||||
settingsService: settings_service.ServiceInterface, profileService: profile_service.ServiceInterface,
|
||||
languageService: language_service.ServiceInterface, mnemonicService: mnemonic_service.ServiceInterface,
|
||||
privacyService: privacy_service.ServiceInterface): Controller[T] =
|
||||
result = Controller[T]()
|
||||
result.delegate = delegate
|
||||
result.profileService = profileService
|
||||
|
@ -42,10 +45,14 @@ method enableDeveloperFeatures*[T](self: Controller[T]) =
|
|||
self.settingsService.enableDeveloperFeatures()
|
||||
|
||||
method toggleTelemetry*[T](self: Controller[T]) =
|
||||
self.settingsService.toggleTelemetry()
|
||||
var value = ""
|
||||
if(not self.isTelemetryEnabled()):
|
||||
value = DEFAULT_TELEMETRY_SERVER_URL
|
||||
|
||||
discard self.settingsService.saveTelemetryServerUrl(value)
|
||||
|
||||
method isTelemetryEnabled*[T](self: Controller[T]): bool =
|
||||
return self.settingsService.isTelemetryEnabled()
|
||||
return self.settingsService.getTelemetryServerUrl().len > 0
|
||||
|
||||
method toggleAutoMessage*[T](self: Controller[T]) =
|
||||
self.settingsService.toggleAutoMessage()
|
||||
|
@ -54,7 +61,11 @@ method isAutoMessageEnabled*[T](self: Controller[T]): bool =
|
|||
return self.settingsService.isAutoMessageEnabled()
|
||||
|
||||
method toggleDebug*[T](self: Controller[T]) =
|
||||
self.settingsService.toggleDebug()
|
||||
discard
|
||||
# Need to sort out this
|
||||
#self.settingsService.toggleDebug()
|
||||
|
||||
method isDebugEnabled*[T](self: Controller[T]): bool =
|
||||
return self.settingsService.isDebugEnabled()
|
||||
return true
|
||||
# Need to sort out this
|
||||
#return self.settingsService.isDebugEnabled()
|
||||
|
|
|
@ -4,7 +4,7 @@ import ../../../global/global_singleton
|
|||
|
||||
import ../../../../app_service/service/profile/service as profile_service
|
||||
import ../../../../app_service/service/accounts/service as accounts_service
|
||||
import ../../../../app_service/service/settings/service as settings_service
|
||||
import ../../../../app_service/service/settings/service_interface as settings_service
|
||||
import ../../../../app_service/service/contacts/service as contacts_service
|
||||
import ../../../../app_service/service/about/service as about_service
|
||||
import ../../../../app_service/service/language/service as language_service
|
||||
|
|
|
@ -3,7 +3,7 @@ import ./controller_interface
|
|||
import ../../../../global/global_singleton
|
||||
import ../../../../../app_service/service/profile/service as profile_service
|
||||
import ../../../../../app_service/service/accounts/service as accounts_service
|
||||
import ../../../../../app_service/service/settings/service as settings_service
|
||||
import ../../../../../app_service/service/settings/service_interface as settings_service
|
||||
|
||||
import ./item as item
|
||||
import status/types/identity_image
|
||||
|
@ -17,7 +17,8 @@ type
|
|||
settingsService: settings_service.ServiceInterface
|
||||
accountsService: accounts_service.ServiceInterface
|
||||
|
||||
proc newController*[T](delegate: T, accountsService: accounts_service.ServiceInterface, settingsService: settings_service.ServiceInterface, profileService: profile_service.ServiceInterface): Controller[T] =
|
||||
proc newController*[T](delegate: T, accountsService: accounts_service.ServiceInterface,
|
||||
settingsService: settings_service.ServiceInterface, profileService: profile_service.ServiceInterface): Controller[T] =
|
||||
result = Controller[T]()
|
||||
result.delegate = delegate
|
||||
result.profileService = profileService
|
||||
|
@ -32,7 +33,6 @@ method init*[T](self: Controller[T]) =
|
|||
|
||||
method getProfile*[T](self: Controller[T]): item.Item =
|
||||
|
||||
var network = self.settingsService.getNetwork()
|
||||
var appearance = self.settingsService.getAppearance()
|
||||
var messagesFromContactsOnly = self.settingsService.getMessagesFromContactsOnly()
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import ../../../../global/global_singleton
|
|||
|
||||
import ../../../../../app_service/service/profile/service as profile_service
|
||||
import ../../../../../app_service/service/accounts/service as accounts_service
|
||||
import ../../../../../app_service/service/settings/service as settings_service
|
||||
import ../../../../../app_service/service/settings/service_interface as settings_service
|
||||
|
||||
import status/types/identity_image
|
||||
|
||||
|
@ -19,7 +19,8 @@ type
|
|||
viewVariant: QVariant
|
||||
moduleLoaded: bool
|
||||
|
||||
proc newModule*[T](delegate: T, accountsService: accounts_service.ServiceInterface, settingsService: settings_service.ServiceInterface, profileService: profile_service.ServiceInterface): Module[T] =
|
||||
proc newModule*[T](delegate: T, accountsService: accounts_service.ServiceInterface,
|
||||
settingsService: settings_service.ServiceInterface, profileService: profile_service.ServiceInterface): Module[T] =
|
||||
result = Module[T]()
|
||||
result.delegate = delegate
|
||||
result.view = newView(result)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import ./controller_interface
|
||||
import ../../../../app_service/service/setting/service as setting_service
|
||||
import ../../../../app_service/service/settings/service_interface as settings_service
|
||||
import ../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
|
||||
export controller_interface
|
||||
|
@ -7,17 +7,17 @@ export controller_interface
|
|||
type
|
||||
Controller*[T: controller_interface.DelegateInterface] = ref object of controller_interface.AccessInterface
|
||||
delegate: T
|
||||
settingService: setting_service.ServiceInterface
|
||||
settingsService: settings_service.ServiceInterface
|
||||
walletAccountService: wallet_account_service.ServiceInterface
|
||||
|
||||
proc newController*[T](
|
||||
delegate: T,
|
||||
settingService: setting_service.ServiceInterface,
|
||||
settingsService: settings_service.ServiceInterface,
|
||||
walletAccountService: wallet_account_service.ServiceInterface,
|
||||
): Controller[T] =
|
||||
result = Controller[T]()
|
||||
result.delegate = delegate
|
||||
result.settingService = settingService
|
||||
result.settingsService = settingsService
|
||||
result.walletAccountService = walletAccountService
|
||||
|
||||
method delete*[T](self: Controller[T]) =
|
||||
|
@ -26,8 +26,14 @@ method delete*[T](self: Controller[T]) =
|
|||
method init*[T](self: Controller[T]) =
|
||||
discard
|
||||
|
||||
method getSetting*[T](self: Controller[T]): setting_service.SettingDto =
|
||||
return self.settingService.getSetting()
|
||||
method getCurrency*[T](self: Controller[T]): string =
|
||||
return self.settingsService.getCurrency()
|
||||
|
||||
method getSigningPhrase*[T](self: Controller[T]): string =
|
||||
return self.settingsService.getSigningPhrase()
|
||||
|
||||
method isMnemonicBackedUp*[T](self: Controller[T]): bool =
|
||||
return self.settingsService.getMnemonic().len > 0
|
||||
|
||||
method getCurrencyBalance*[T](self: Controller[T]): float64 =
|
||||
return self.walletAccountService.getCurrencyBalance()
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import ../../../../app_service/service/setting/service_interface as setting_service
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
@ -10,7 +8,13 @@ method delete*(self: AccessInterface) {.base.} =
|
|||
method init*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getSetting*(self: AccessInterface): setting_service.SettingDto {.base.} =
|
||||
method getCurrency*(self: AccessInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getSigningPhrase*(self: AccessInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isMnemonicBackedUp*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getCurrencyBalance*(self: AccessInterface): float64 {.base.} =
|
||||
|
|
|
@ -17,7 +17,7 @@ import ../../../../app_service/service/token/service as token_service
|
|||
import ../../../../app_service/service/transaction/service as transaction_service
|
||||
import ../../../../app_service/service/collectible/service as collectible_service
|
||||
import ../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import ../../../../app_service/service/setting/service as setting_service
|
||||
import ../../../../app_service/service/settings/service_interface as settings_service
|
||||
|
||||
import io_interface
|
||||
export io_interface
|
||||
|
@ -44,13 +44,13 @@ proc newModule*[T](
|
|||
transactionService: transaction_service.Service,
|
||||
collectibleService: collectible_service.ServiceInterface,
|
||||
walletAccountService: wallet_account_service.ServiceInterface,
|
||||
settingService: setting_service.ServiceInterface
|
||||
settingsService: settings_service.ServiceInterface
|
||||
): Module[T] =
|
||||
result = Module[T]()
|
||||
result.delegate = delegate
|
||||
result.events = events
|
||||
result.moduleLoaded = false
|
||||
result.controller = newController(result, settingService, walletAccountService)
|
||||
result.controller = newController(result, settingsService, walletAccountService)
|
||||
result.view = newView(result)
|
||||
|
||||
result.accountTokensModule = account_tokens_module.newModule[Module[T]](result, events, walletAccountService)
|
||||
|
@ -102,8 +102,10 @@ method load*[T](self: Module[T]) =
|
|||
self.transactionsModule.load()
|
||||
|
||||
self.switchAccount(0)
|
||||
let setting = self.controller.getSetting()
|
||||
self.view.updateFromSetting(setting)
|
||||
let currency = self.controller.getCurrency()
|
||||
let signingPhrase = self.controller.getSigningPhrase()
|
||||
let mnemonicBackedUp = self.controller.isMnemonicBackedUp()
|
||||
self.view.setData(currency, signingPhrase, mnemonicBackedUp)
|
||||
self.setTotalCurrencyBalance()
|
||||
self.moduleLoaded = true
|
||||
self.delegate.walletSectionDidLoad()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import NimQml
|
||||
|
||||
import ../../../../app_service/service/setting/service as setting_service
|
||||
import ./io_interface
|
||||
|
||||
QtObject:
|
||||
|
@ -65,8 +64,8 @@ QtObject:
|
|||
self.totalCurrencyBalance = totalCurrencyBalance
|
||||
self.totalCurrencyBalanceChanged()
|
||||
|
||||
proc updateFromSetting*(self: View, setting: setting_service.SettingDto) =
|
||||
self.currentCurrency = setting.currency
|
||||
proc setData*(self: View, currency, signingPhrase: string, mnemonicBackedUp: bool) =
|
||||
self.currentCurrency = currency
|
||||
self.signingPhrase = signingPhrase
|
||||
self.isMnemonicBackedUp = mnemonicBackedUp
|
||||
self.currentCurrencyChanged()
|
||||
self.signingPhrase = setting.signingPhrase
|
||||
self.isMnemonicBackedUp = setting.isMnemonicBackedUp
|
|
@ -1,7 +1,7 @@
|
|||
import chronicles, sequtils, json
|
||||
|
||||
import ./service_interface, ./dto
|
||||
import ../setting/service as setting_service
|
||||
import ../settings/service_interface as settings_service
|
||||
|
||||
import status/statusgo_backend_new/collectibles as collectibles
|
||||
|
||||
|
@ -14,21 +14,21 @@ logScope:
|
|||
|
||||
type
|
||||
Service* = ref object of service_interface.ServiceInterface
|
||||
settingService: setting_service.ServiceInterface
|
||||
settingsService: settings_service.ServiceInterface
|
||||
|
||||
method delete*(self: Service) =
|
||||
discard
|
||||
|
||||
proc newService*(settingService: setting_service.ServiceInterface): Service =
|
||||
proc newService*(settingsService: settings_service.ServiceInterface): Service =
|
||||
result = Service()
|
||||
result.settingService = settingService
|
||||
result.settingsService = settingsService
|
||||
|
||||
method init*(self: Service) =
|
||||
discard
|
||||
|
||||
method getCollections(self: Service, address: string): seq[CollectionDto] =
|
||||
try:
|
||||
let networkId = self.settingService.getSetting().currentNetwork.id
|
||||
let networkId = self.settingsService.getCurrentNetworkId()
|
||||
let response = collectibles.getOpenseaCollections(networkId, address)
|
||||
return map(response.result.getElems(), proc(x: JsonNode): CollectionDto = x.toCollectionDto())
|
||||
except Exception as e:
|
||||
|
@ -38,7 +38,7 @@ method getCollections(self: Service, address: string): seq[CollectionDto] =
|
|||
|
||||
method getCollectibles(self: Service, address: string, collectionSlug: string): seq[CollectibleDto] =
|
||||
try:
|
||||
let networkId = self.settingService.getSetting().currentNetwork.id
|
||||
let networkId = self.settingsService.getCurrentNetworkId()
|
||||
let response = collectibles.getOpenseaAssets(networkId, address, collectionSlug, limit)
|
||||
return map(response.result.getElems(), proc(x: JsonNode): CollectibleDto = x.toCollectibleDto())
|
||||
except Exception as e:
|
||||
|
|
|
@ -4,13 +4,14 @@ import options
|
|||
import strutils
|
||||
include ../../common/json_utils
|
||||
import ../dapp_permissions/service as dapp_permissions_service
|
||||
import ../settings/service as settings_service
|
||||
import ../settings/service_interface as settings_service
|
||||
import ../ens/service as ens_service
|
||||
import service_interface
|
||||
import status/statusgo_backend_new/permissions as status_go_permissions
|
||||
import status/statusgo_backend_new/accounts as status_go_accounts
|
||||
import status/statusgo_backend_new/core as status_go_core
|
||||
import status/statusgo_backend_new/provider as status_go_provider
|
||||
from stew/base32 import nil
|
||||
from stew/base58 import nil
|
||||
import stew/byteutils
|
||||
export service_interface
|
||||
|
||||
|
@ -18,6 +19,74 @@ logScope:
|
|||
topics = "provider-service"
|
||||
|
||||
const HTTPS_SCHEME* = "https"
|
||||
const IPFS_GATEWAY* = ".infura.status.im"
|
||||
const SWARM_GATEWAY* = "swarm-gateways.net"
|
||||
|
||||
type
|
||||
RequestTypes {.pure.} = enum
|
||||
Web3SendAsyncReadOnly = "web3-send-async-read-only",
|
||||
HistoryStateChanged = "history-state-changed",
|
||||
APIRequest = "api-request"
|
||||
Unknown = "unknown"
|
||||
|
||||
ResponseTypes {.pure.} = enum
|
||||
Web3SendAsyncCallback = "web3-send-async-callback",
|
||||
APIResponse = "api-response",
|
||||
Web3ResponseError = "web3-response-error"
|
||||
|
||||
type
|
||||
Payload = ref object
|
||||
id: JsonNode
|
||||
rpcMethod: string
|
||||
|
||||
Web3SendAsyncReadOnly = ref object
|
||||
messageId: JsonNode
|
||||
payload: Payload
|
||||
request: string
|
||||
hostname: string
|
||||
|
||||
APIRequest = ref object
|
||||
isAllowed: bool
|
||||
messageId: JsonNode
|
||||
permission: Permission
|
||||
hostname: string
|
||||
|
||||
const AUTH_METHODS = toHashSet(["eth_accounts", "eth_coinbase", "eth_sendTransaction", "eth_sign", "keycard_signTypedData", "eth_signTypedData", "eth_signTypedData_v3", "personal_sign", "personal_ecRecover"])
|
||||
const SIGN_METHODS = toHashSet(["eth_sign", "personal_sign", "eth_signTypedData", "eth_signTypedData_v3"])
|
||||
const ACC_METHODS = toHashSet(["eth_accounts", "eth_coinbase"])
|
||||
|
||||
proc requestType(message: string): RequestTypes =
|
||||
let data = message.parseJson
|
||||
result = RequestTypes.Unknown
|
||||
try:
|
||||
result = parseEnum[RequestTypes](data["type"].getStr())
|
||||
except:
|
||||
warn "Unknown request type received", value=data["permission"].getStr()
|
||||
|
||||
|
||||
proc toWeb3SendAsyncReadOnly(message: string): Web3SendAsyncReadOnly =
|
||||
let data = message.parseJson
|
||||
result = Web3SendAsyncReadOnly(
|
||||
messageId: data["messageId"],
|
||||
request: $data["payload"],
|
||||
hostname: data{"hostname"}.getStr(),
|
||||
payload: Payload(
|
||||
id: data["payload"]{"id"},
|
||||
rpcMethod: data["payload"]["method"].getStr()
|
||||
)
|
||||
)
|
||||
|
||||
proc toAPIRequest(message: string): APIRequest =
|
||||
let data = message.parseJson
|
||||
|
||||
result = APIRequest(
|
||||
messageId: data["messageId"],
|
||||
isAllowed: data{"isAllowed"}.getBool(),
|
||||
permission: data["permission"].getStr().toPermission(),
|
||||
hostname: data{"hostname"}.getStr()
|
||||
)
|
||||
|
||||
|
||||
|
||||
type
|
||||
Service* = ref object of service_interface.ServiceInterface
|
||||
|
@ -39,18 +108,217 @@ proc newService*(dappPermissionsService: dapp_permissions_service.ServiceInterfa
|
|||
method init*(self: Service) =
|
||||
discard
|
||||
|
||||
proc process(self: Service, data: Web3SendAsyncReadOnly): string =
|
||||
if AUTH_METHODS.contains(data.payload.rpcMethod) and not self.dappPermissionsService.hasPermission(data.hostname, Permission.Web3):
|
||||
return $ %* {
|
||||
"type": ResponseTypes.Web3SendAsyncCallback,
|
||||
"messageId": data.messageId,
|
||||
"error": {
|
||||
"code": 4100
|
||||
}
|
||||
}
|
||||
|
||||
method ensResourceURL*(self: Service, username: string, url: string): (string, string, string, string, bool) =
|
||||
let (scheme, host, path) = self.ensService.resourceUrl(username)
|
||||
if host == "":
|
||||
return (url, url, HTTPS_SCHEME, "", false)
|
||||
return (url, host, scheme, path, true)
|
||||
|
||||
|
||||
method postMessage*(self: Service, requestType: string, message: string): string =
|
||||
if data.payload.rpcMethod == "eth_sendTransaction":
|
||||
try:
|
||||
return $providerRequest(requestType, message).result
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error: ", errDescription
|
||||
let request = data.request.parseJson
|
||||
let fromAddress = request["params"][0]["from"].getStr()
|
||||
let to = request["params"][0]{"to"}.getStr()
|
||||
let value = if (request["params"][0]["value"] != nil):
|
||||
request["params"][0]["value"].getStr()
|
||||
else:
|
||||
"0"
|
||||
let password = request["password"].getStr()
|
||||
let selectedGasLimit = request["selectedGasLimit"].getStr()
|
||||
let selectedGasPrice = request["selectedGasPrice"].getStr()
|
||||
let selectedTipLimit = request{"selectedTipLimit"}.getStr()
|
||||
let selectedOverallLimit = request{"selectedOverallLimit"}.getStr()
|
||||
let txData = if (request["params"][0].hasKey("data") and request["params"][0]["data"].kind != JNull):
|
||||
request["params"][0]["data"].getStr()
|
||||
else:
|
||||
""
|
||||
|
||||
var success: bool
|
||||
var errorMessage = ""
|
||||
var response = ""
|
||||
var validInput: bool = true
|
||||
|
||||
|
||||
# TODO: use the transaction service to send the trx
|
||||
|
||||
#[
|
||||
let eip1559Enabled = self.wallet.isEIP1559Enabled()
|
||||
|
||||
try:
|
||||
validateTransactionInput(fromAddress, to, "", value, selectedGasLimit, selectedGasPrice, txData, eip1559Enabled, selectedTipLimit, selectedOverallLimit, "dummy")
|
||||
except Exception as e:
|
||||
validInput = false
|
||||
success = false
|
||||
errorMessage = e.msg
|
||||
|
||||
if validInput:
|
||||
# TODO make this async
|
||||
response = wallet.sendTransaction(fromAddress, to, value, selectedGasLimit, selectedGasPrice, eip1559Enabled, selectedTipLimit, selectedOverallLimit, password, success, txData)
|
||||
errorMessage = if not success:
|
||||
if response == "":
|
||||
"web3-response-error"
|
||||
else:
|
||||
response
|
||||
else:
|
||||
""
|
||||
|
||||
return $ %* {
|
||||
"type": ResponseTypes.Web3SendAsyncCallback,
|
||||
"messageId": data.messageId,
|
||||
"error": errorMessage,
|
||||
"result": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": data.payload.id,
|
||||
"result": if (success): response else: ""
|
||||
}
|
||||
}
|
||||
|
||||
]#
|
||||
# TODO: delete this:
|
||||
return $ %* {
|
||||
"type": ResponseTypes.Web3SendAsyncCallback,
|
||||
"messageId": data.messageId,
|
||||
"error": "",
|
||||
"result": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": data.payload.id,
|
||||
"result": ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
except Exception as e:
|
||||
error "Error sending the transaction", msg = e.msg
|
||||
return $ %* {
|
||||
"type": ResponseTypes.Web3SendAsyncCallback,
|
||||
"messageId": data.messageId,
|
||||
"error": {
|
||||
"code": 4100,
|
||||
"message": e.msg
|
||||
}
|
||||
}
|
||||
|
||||
if SIGN_METHODS.contains(data.payload.rpcMethod):
|
||||
try:
|
||||
let request = data.request.parseJson
|
||||
var params = request["params"]
|
||||
let password = hashPassword(request["password"].getStr())
|
||||
let dappAddress = self.settingsService.getDappsAddress()
|
||||
var rpcResult = "{}"
|
||||
|
||||
case data.payload.rpcMethod:
|
||||
of "eth_signTypedData", "eth_signTypedData_v3":
|
||||
rpcResult = signTypedData(params[1].getStr(), dappAddress, password)
|
||||
else:
|
||||
rpcResult = signMessage($ %* {
|
||||
"data": params[0].getStr(),
|
||||
"password": password,
|
||||
"account": dappAddress
|
||||
})
|
||||
|
||||
let jsonRpcResult = rpcResult.parseJson
|
||||
let success: bool = not jsonRpcResult.hasKey("error")
|
||||
let errorMessage = if success: "" else: jsonRpcResult["error"]{"message"}.getStr()
|
||||
let response = if success: jsonRpcResult["result"].getStr() else: ""
|
||||
|
||||
return $ %* {
|
||||
"type": ResponseTypes.Web3SendAsyncCallback,
|
||||
"messageId": data.messageId,
|
||||
"error": errorMessage,
|
||||
"result": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": if data.payload.id == nil: newJNull() else: data.payload.id,
|
||||
"result": if (success): response else: ""
|
||||
}
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
error "Error signing message", msg = e.msg
|
||||
return $ %* {
|
||||
"type": ResponseTypes.Web3SendAsyncCallback,
|
||||
"messageId": data.messageId,
|
||||
"error": {
|
||||
"code": 4100,
|
||||
"message": e.msg
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ACC_METHODS.contains(data.payload.rpcMethod):
|
||||
let dappAddress = self.settingsService.getDappsAddress()
|
||||
return $ %* {
|
||||
"type": ResponseTypes.Web3SendAsyncCallback,
|
||||
"messageId": data.messageId,
|
||||
"result": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": data.payload.id,
|
||||
"result": if data.payload.rpcMethod == "eth_coinbase": newJString(dappAddress) else: %*[dappAddress]
|
||||
}
|
||||
}
|
||||
|
||||
let rpcResult = callRPC(data.request)
|
||||
|
||||
return $ %* {
|
||||
"type": ResponseTypes.Web3SendAsyncCallback,
|
||||
"messageId": data.messageId,
|
||||
"error": (if rpcResult == "": newJString("web3-response-error") else: newJNull()),
|
||||
"result": rpcResult.parseJson
|
||||
}
|
||||
|
||||
proc process(self: Service, data: APIRequest): string =
|
||||
var value:JsonNode = case data.permission
|
||||
of Permission.Web3: %* [self.settingsService.getDappsAddress()]
|
||||
of Permission.ContactCode: %* self.settingsService.getPublicKey()
|
||||
of Permission.Unknown: newJNull()
|
||||
|
||||
let isAllowed = data.isAllowed and data.permission != Permission.Unknown
|
||||
|
||||
info "API request received", host=data.hostname, value=data.permission, isAllowed
|
||||
|
||||
if isAllowed:
|
||||
discard self.dappPermissionsService.addPermission(data.hostname, data.permission)
|
||||
|
||||
return $ %* {
|
||||
"type": ResponseTypes.APIResponse,
|
||||
"isAllowed": isAllowed,
|
||||
"permission": data.permission,
|
||||
"messageId": data.messageId,
|
||||
"data": value
|
||||
}
|
||||
|
||||
method postMessage*(self: Service, message: string): string =
|
||||
case message.requestType():
|
||||
of RequestTypes.Web3SendAsyncReadOnly: self.process(message.toWeb3SendAsyncReadOnly())
|
||||
of RequestTypes.HistoryStateChanged: """{"type":"TODO-IMPLEMENT-THIS"}""" ############# TODO:
|
||||
of RequestTypes.APIRequest: self.process(message.toAPIRequest())
|
||||
else: """{"type":"TODO-IMPLEMENT-THIS"}""" ##################### TODO:
|
||||
|
||||
method ensResourceURL*(self: Service, ens: string, url: string): (string, string, string, string, bool) =
|
||||
let contentHash = self.ensService.getContentHash(ens)
|
||||
if contentHash.isNone(): # ENS does not have a content hash
|
||||
return (url, url, HTTPS_SCHEME, "", false)
|
||||
|
||||
let decodedHash = self.ensService.decodeENSContentHash(contentHash.get())
|
||||
|
||||
case decodedHash[0]:
|
||||
of ENSType.IPFS:
|
||||
let
|
||||
base58bytes = base58.decode(base58.BTCBase58, decodedHash[1])
|
||||
base32Hash = base32.encode(base32.Base32Lower, base58bytes)
|
||||
|
||||
result = (url, base32Hash & IPFS_GATEWAY, HTTPS_SCHEME, "", true)
|
||||
|
||||
of ENSType.SWARM:
|
||||
result = (url, SWARM_GATEWAY, HTTPS_SCHEME,
|
||||
"/bzz:/" & decodedHash[1] & "/", true)
|
||||
|
||||
of ENSType.IPNS:
|
||||
result = (url, decodedHash[1], HTTPS_SCHEME, "", true)
|
||||
|
||||
else:
|
||||
warn "Unknown content for", ens, contentHash
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
import json, options
|
||||
|
||||
include ../../common/json_utils
|
||||
|
||||
const DEFAULT_NETWORK_SLUG = "mainnet_rpc"
|
||||
const DEFAULT_CURRENCY = "usd"
|
||||
|
||||
type NetworkDto* = ref object of RootObj
|
||||
id*: int
|
||||
slug*: string
|
||||
etherscanLink*: string
|
||||
name*: string
|
||||
|
||||
type
|
||||
SettingDto* = ref object of RootObj
|
||||
currentNetwork*: NetworkDto
|
||||
activeTokenSymbols*: seq[string]
|
||||
rawActiveTokenSymbols*: JsonNode
|
||||
signingPhrase*: string
|
||||
currency*: string
|
||||
mnemonic*: string
|
||||
walletRootAddress*: string
|
||||
latestDerivedPath*: int
|
||||
|
||||
proc toSettingDto*(jsonObj: JsonNode): SettingDto =
|
||||
result = SettingDto()
|
||||
|
||||
discard jsonObj.getProp("signing-phrase", result.signingPhrase)
|
||||
discard jsonObj.getProp("wallet-root-address", result.walletRootAddress)
|
||||
discard jsonObj.getProp("latest-derived-path", result.latestDerivedPath)
|
||||
discard jsonObj.getProp("mnemonic", result.mnemonic)
|
||||
|
||||
if not jsonObj.getProp("currency", result.currency):
|
||||
result.currency = DEFAULT_CURRENCY
|
||||
|
||||
var currentNetworkSlug: string
|
||||
if not jsonObj.getProp("networks/current-network", currentNetworkSlug):
|
||||
currentNetworkSlug = DEFAULT_NETWORK_SLUG
|
||||
|
||||
var networks: JsonNode
|
||||
discard jsonObj.getProp("networks/networks", networks)
|
||||
for networkJson in networks.getElems():
|
||||
if networkJson{"id"}.getStr != currentNetworkSlug:
|
||||
continue
|
||||
|
||||
var networkDto = NetworkDto()
|
||||
discard networkJson{"config"}.getProp("NetworkId", networkDto.id)
|
||||
discard networkJson.getProp("id", networkDto.slug)
|
||||
discard networkJson.getProp("name", networkDto.name)
|
||||
discard networkJson.getProp("etherscan-link", networkDto.etherscanLink)
|
||||
result.currentNetwork = networkDto
|
||||
break
|
||||
|
||||
result.rawActiveTokenSymbols = newJObject()
|
||||
result.activeTokenSymbols = @[]
|
||||
if jsonObj.hasKey("wallet/visible-tokens"):
|
||||
result.rawActiveTokenSymbols = parseJson(jsonObj{"wallet/visible-tokens"}.getStr)
|
||||
|
||||
for symbol in result.rawActiveTokenSymbols{$result.currentNetwork.id}.getElems():
|
||||
result.activeTokenSymbols.add(symbol.getStr)
|
||||
|
||||
proc isMnemonicBackedUp*(self: SettingDto): bool =
|
||||
return self.mnemonic == ""
|
|
@ -1,51 +0,0 @@
|
|||
import chronicles, json
|
||||
|
||||
import ./service_interface, ./dto
|
||||
import status/statusgo_backend_new/settings as status_go
|
||||
|
||||
export service_interface
|
||||
|
||||
logScope:
|
||||
topics = "setting-service"
|
||||
|
||||
type
|
||||
Service* = ref object of service_interface.ServiceInterface
|
||||
setting: SettingDto
|
||||
|
||||
method delete*(self: Service) =
|
||||
discard
|
||||
|
||||
proc newService*(): Service =
|
||||
result = Service()
|
||||
|
||||
method init*(self: Service) =
|
||||
try:
|
||||
let response = status_go.getSettings()
|
||||
self.setting = response.result.toSettingDto()
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error: ", errDesription
|
||||
return
|
||||
|
||||
method saveSetting*(
|
||||
self: Service, attribute: string, value: string | JsonNode | bool | int | seq[string]
|
||||
): SettingDto =
|
||||
case attribute:
|
||||
of "latest-derived-path":
|
||||
self.setting.latestDerivedPath = cast[int](value)
|
||||
status_go.saveSettings(attribute, self.setting.latestDerivedPath)
|
||||
of "currency":
|
||||
self.setting.currency = cast[string](value)
|
||||
status_go.saveSettings(attribute, self.setting.currency)
|
||||
of "wallet/visible-tokens":
|
||||
let newValue = cast[seq[string]](value)
|
||||
self.setting.activeTokenSymbols = newValue
|
||||
self.setting.rawActiveTokenSymbols[$self.setting.currentNetwork.id] = newJArray()
|
||||
self.setting.rawActiveTokenSymbols[$self.setting.currentNetwork.id] = %* newValue
|
||||
|
||||
status_go.saveSettings(attribute, $self.setting.rawActiveTokenSymbols)
|
||||
|
||||
return self.setting
|
||||
|
||||
method getSetting*(self: Service): SettingDto =
|
||||
return self.setting
|
|
@ -1,22 +0,0 @@
|
|||
import json
|
||||
import ./dto
|
||||
|
||||
export dto
|
||||
|
||||
type
|
||||
ServiceInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for this service access.
|
||||
|
||||
method delete*(self: ServiceInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method init*(self: ServiceInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getSetting*(self: ServiceInterface): SettingDto {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveSetting*(
|
||||
self: ServiceInterface, attribute: string, value: string | JsonNode | bool | int | seq[string]
|
||||
): SettingDto {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
type
|
||||
IdentityImage* = ref object
|
||||
thumbnail*: string
|
||||
large*: string
|
|
@ -1,12 +0,0 @@
|
|||
{.used.}
|
||||
|
||||
import json_serialization
|
||||
|
||||
import node_config
|
||||
|
||||
type
|
||||
NetworkDetails* = object
|
||||
id*: string
|
||||
name*: string
|
||||
etherscanLink* {.serializedFieldName("etherscan-link").}: string
|
||||
config*: NodeConfig
|
|
@ -1,9 +0,0 @@
|
|||
import json_serialization
|
||||
|
||||
import upstream_config
|
||||
|
||||
type
|
||||
NodeConfig* = object
|
||||
networkId* {.serializedFieldName("NetworkId").}: int
|
||||
dataDir* {.serializedFieldName("DataDir").}: string
|
||||
upstreamConfig* {.serializedFieldName("UpstreamConfig").}: UpstreamConfig
|
|
@ -0,0 +1,147 @@
|
|||
import json, options
|
||||
|
||||
include ../../../common/json_utils
|
||||
|
||||
type UpstreamConfig* = object
|
||||
enabled*: bool
|
||||
url*: string
|
||||
|
||||
type Config* = object
|
||||
networkId*: int
|
||||
dataDir*: string
|
||||
upstreamConfig*: UpstreamConfig
|
||||
|
||||
type Network* = object
|
||||
id*: string
|
||||
etherscanLink*: string
|
||||
name*: string
|
||||
config*: Config
|
||||
|
||||
type PinnedMailservers* = object
|
||||
ethProd*: string
|
||||
|
||||
type CurrentUserStatus* = object
|
||||
statusType*: int
|
||||
clock*: int64
|
||||
text*: string
|
||||
|
||||
type WalletVisibleTokens* = object
|
||||
tokens*: seq[string]
|
||||
|
||||
type
|
||||
SettingsDto* = object # There is no point to keep all these info as settings, but we must follow status-go response
|
||||
address*: string
|
||||
currency*: string
|
||||
currentNetwork*: string
|
||||
availableNetworks*: seq[Network]
|
||||
dappsAddress*: string
|
||||
eip1581Address*: string
|
||||
installationId*: string
|
||||
keyUid*: string
|
||||
latestDerivedPath*: int
|
||||
linkPreviewRequestEnabled*: bool
|
||||
messagesFromContactsOnly*: bool
|
||||
mnemonic*: string
|
||||
name*: string # user alias
|
||||
photoPath*: string
|
||||
pinnedMailservers*: PinnedMailservers
|
||||
previewPrivacy*: bool
|
||||
publicKey*: string
|
||||
signingPhrase*: string
|
||||
defaultSyncPeriod*: int
|
||||
sendPushNotifications*: bool
|
||||
appearance*: int
|
||||
profilePicturesShowTo*: int
|
||||
profilePicturesVisibility*: int
|
||||
useMailservers*: bool
|
||||
walletRootAddress*: string
|
||||
sendStatusUpdates*: bool
|
||||
telemetryServerUrl*: string
|
||||
fleet*: string
|
||||
currentUserStatus*: CurrentUserStatus
|
||||
walletVisibleTokens*: WalletVisibleTokens
|
||||
|
||||
proc toUpstreamConfig*(jsonObj: JsonNode): UpstreamConfig =
|
||||
discard jsonObj.getProp("Enabled", result.enabled)
|
||||
discard jsonObj.getProp("URL", result.url)
|
||||
|
||||
proc toConfig*(jsonObj: JsonNode): Config =
|
||||
discard jsonObj.getProp("NetworkId", result.networkId)
|
||||
discard jsonObj.getProp("DataDir", result.dataDir)
|
||||
|
||||
var upstreamConfigObj: JsonNode
|
||||
if(jsonObj.getProp("UpstreamConfig", upstreamConfigObj)):
|
||||
result.upstreamConfig = toUpstreamConfig(upstreamConfigObj)
|
||||
|
||||
proc toNetwork*(jsonObj: JsonNode): Network =
|
||||
discard jsonObj.getProp("id", result.id)
|
||||
discard jsonObj.getProp("etherscan-link", result.etherscanLink)
|
||||
discard jsonObj.getProp("name", result.name)
|
||||
|
||||
var configObj: JsonNode
|
||||
if(jsonObj.getProp("config", configObj)):
|
||||
result.config = toConfig(configObj)
|
||||
|
||||
proc toPinnedMailservers*(jsonObj: JsonNode): PinnedMailservers =
|
||||
discard jsonObj.getProp("eth.prod", result.ethProd)
|
||||
|
||||
proc toCurrentUserStatus*(jsonObj: JsonNode): CurrentUserStatus =
|
||||
discard jsonObj.getProp("statusType", result.statusType)
|
||||
discard jsonObj.getProp("clock", result.clock)
|
||||
discard jsonObj.getProp("text", result.text)
|
||||
|
||||
proc toWalletVisibleTokens*(jsonObj: JsonNode, networkId: string): WalletVisibleTokens =
|
||||
for netId, tokenArr in jsonObj:
|
||||
if(netId != networkId or tokenArr.kind != JArray):
|
||||
continue
|
||||
|
||||
for token in tokenArr:
|
||||
result.tokens.add(token.getStr)
|
||||
|
||||
proc toSettingsDto*(jsonObj: JsonNode): SettingsDto =
|
||||
|
||||
discard jsonObj.getProp("address", result.address)
|
||||
discard jsonObj.getProp("currency", result.currency)
|
||||
discard jsonObj.getProp("networks/current-network", result.currentNetwork)
|
||||
|
||||
var networksArr: JsonNode
|
||||
if(jsonObj.getProp("networks/networks", networksArr)):
|
||||
if(networksArr.kind == JArray):
|
||||
for networkObj in networksArr:
|
||||
result.availableNetworks.add(toNetwork(networkObj))
|
||||
|
||||
discard jsonObj.getProp("dapps-address", result.dappsAddress)
|
||||
discard jsonObj.getProp("eip1581-address", result.eip1581Address)
|
||||
discard jsonObj.getProp("installation-id", result.installationId)
|
||||
discard jsonObj.getProp("key-uid", result.keyUid)
|
||||
discard jsonObj.getProp("latest-derived-path", result.latestDerivedPath)
|
||||
discard jsonObj.getProp("link-preview-request-enabled", result.linkPreviewRequestEnabled)
|
||||
discard jsonObj.getProp("messages-from-contacts-only", result.messagesFromContactsOnly)
|
||||
discard jsonObj.getProp("mnemonic", result.mnemonic)
|
||||
discard jsonObj.getProp("name", result.name)
|
||||
discard jsonObj.getProp("photo-path", result.photoPath)
|
||||
discard jsonObj.getProp("preview-privacy?", result.previewPrivacy)
|
||||
discard jsonObj.getProp("public-key", result.publicKey)
|
||||
discard jsonObj.getProp("signing-phrase", result.signingPhrase)
|
||||
discard jsonObj.getProp("default-sync-period", result.defaultSyncPeriod)
|
||||
discard jsonObj.getProp("send-push-notifications?", result.sendPushNotifications)
|
||||
discard jsonObj.getProp("appearance", result.appearance)
|
||||
discard jsonObj.getProp("profile-pictures-show-to", result.profilePicturesShowTo)
|
||||
discard jsonObj.getProp("profile-pictures-visibility", result.profilePicturesVisibility)
|
||||
discard jsonObj.getProp("use-mailservers?", result.useMailservers)
|
||||
discard jsonObj.getProp("wallet-root-address", result.walletRootAddress)
|
||||
discard jsonObj.getProp("send-status-updates?", result.sendStatusUpdates)
|
||||
discard jsonObj.getProp("telemetry-server-url", result.telemetryServerUrl)
|
||||
discard jsonObj.getProp("fleet", result.fleet)
|
||||
|
||||
var pinnedMailserversObj: JsonNode
|
||||
if(jsonObj.getProp("pinned-mailservers", pinnedMailserversObj)):
|
||||
result.pinnedMailservers = toPinnedMailservers(pinnedMailserversObj)
|
||||
|
||||
var currentUserStatusObj: JsonNode
|
||||
if(jsonObj.getProp("current-user-status", currentUserStatusObj)):
|
||||
result.currentUserStatus = toCurrentUserStatus(currentUserStatusObj)
|
||||
|
||||
var walletVisibleTokensObj: JsonNode
|
||||
if(jsonObj.getProp("wallet/visible-tokens", walletVisibleTokensObj)):
|
||||
result.walletVisibleTokens = toWalletVisibleTokens(walletVisibleTokensObj, result.currentNetwork)
|
|
@ -1,6 +0,0 @@
|
|||
import json_serialization
|
||||
|
||||
type
|
||||
UpstreamConfig* = object
|
||||
enabled* {.serializedFieldName("Enabled").}: bool
|
||||
url* {.serializedFieldName("URL").}: string
|
|
@ -1,28 +1,45 @@
|
|||
import json, json_serialization, sugar, sequtils, chronicles
|
||||
# import status/statusgo_backend_new/custom_tokens as custom_tokens
|
||||
import json, tables, sugar, sequtils, strutils, atomics, os
|
||||
import chronicles, json
|
||||
|
||||
import status/statusgo_backend/settings as status_go_settings
|
||||
import status/statusgo_backend/accounts as status_accounts
|
||||
from status/types/setting import Setting
|
||||
|
||||
import ./service_interface, ./dto
|
||||
|
||||
import dto/network_details
|
||||
import dto/node_config
|
||||
import dto/upstream_config
|
||||
import service_interface, ./dto/settings
|
||||
import status/statusgo_backend_new/settings as status_go
|
||||
|
||||
export service_interface
|
||||
|
||||
logScope:
|
||||
topics = "settings-service"
|
||||
|
||||
const DEFAULT_NETWORK_NAME = "mainnet_rpc"
|
||||
const TELEMETRY_BASE_URL = "https://telemetry.status.im"
|
||||
# Setting keys:
|
||||
const KEY_ADDRESS = "address"
|
||||
const KEY_CURRENCY = "currency"
|
||||
const KEY_NETWORKS_CURRENT_NETWORK = "networks/current-network"
|
||||
const KEY_DAPPS_ADDRESS = "dapps-address"
|
||||
const KEY_EIP1581_ADDRESS = "eip1581-address"
|
||||
const KEY_INSTALLATION_ID = "installation-id"
|
||||
const KEY_KEY_UID = "key-uid"
|
||||
const KEY_LATEST_DERIVED_PATH = "latest-derived-path"
|
||||
const KEY_LINK_PREVIEW_REQUEST_ENABLED = "link-preview-request-enabled"
|
||||
const KEY_MESSAGES_FROM_CONTACTS_ONLY = "messages-from-contacts-only"
|
||||
const KEY_MNEMONIC = "mnemonic"
|
||||
const KEY_NAME = "name"
|
||||
const KEY_PHOTO_PATH = "photo-path"
|
||||
const KEY_PREVIEW_PRIVACY = "preview-privacy?"
|
||||
const KEY_PUBLIC_KEY = "public-key"
|
||||
const KEY_SIGNING_PHRASE = "signing-phrase"
|
||||
const KEY_DEFAULT_SYNC_PERIOD = "default-sync-period"
|
||||
const KEY_SEND_PUSH_NOTIFICATIONS = "send-push-notifications?"
|
||||
const KEY_APPEARANCE = "appearance"
|
||||
const KEY_PROFILE_PICTURES_SHOW_TO = "profile-pictures-show-to"
|
||||
const KEY_PROFILE_PICTURES_VISIBILITY = "profile-pictures-visibility"
|
||||
const KEY_USE_MAILSERVERS = "use-mailservers?"
|
||||
const KEY_WALLET_ROOT_ADDRESS = "wallet-root-address"
|
||||
const KEY_SEND_STATUS_UPDATES = "send-status-updates?"
|
||||
const KEY_TELEMETRY_SERVER_URL = "telemetry-server-url"
|
||||
const KEY_FLEET = "fleet"
|
||||
const KEY_WALLET_VISIBLE_TOKENS = "wallet/visible-tokens"
|
||||
|
||||
type
|
||||
Service* = ref object of ServiceInterface
|
||||
# profile: Dto
|
||||
Service* = ref object of service_interface.ServiceInterface
|
||||
settings: SettingsDto
|
||||
|
||||
method delete*(self: Service) =
|
||||
discard
|
||||
|
@ -32,69 +49,289 @@ proc newService*(): Service =
|
|||
|
||||
method init*(self: Service) =
|
||||
try:
|
||||
echo "init"
|
||||
|
||||
let response = status_go.getSettings()
|
||||
self.settings = response.result.toSettingsDto()
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error: ", errDesription
|
||||
return
|
||||
|
||||
method getPubKey*(self: Service): string=
|
||||
return status_go_settings.getSetting(Setting.PublicKey, "0x0")
|
||||
proc saveSetting(self: Service, attribute: string, value: string | JsonNode | bool | int): bool =
|
||||
let response = status_go.saveSettings(attribute, value)
|
||||
if(not response.error.isNil):
|
||||
error "error saving settings: ", errDescription = response.error.message
|
||||
return false
|
||||
|
||||
method getNetwork*(self: Service): string =
|
||||
return status_go_settings.getSetting(Setting.Networks_CurrentNetwork, DEFAULT_NETWORK_NAME)
|
||||
return true
|
||||
|
||||
method getAppearance*(self: Service): int =
|
||||
let appearance: int = status_go_settings.getSetting[int](Setting.Appearance, 0)
|
||||
return appearance
|
||||
method saveAddress*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_ADDRESS, value)):
|
||||
self.settings.address = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getMessagesFromContactsOnly*(self: Service): bool =
|
||||
return status_go_settings.getSetting[bool](Setting.MessagesFromContactsOnly)
|
||||
method getAddress*(self: Service): string =
|
||||
return self.settings.address
|
||||
|
||||
method getSendUserStatus*(self: Service): bool =
|
||||
return status_go_settings.getSetting[bool](Setting.SendUserStatus)
|
||||
method saveCurrency*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_CURRENCY, value)):
|
||||
self.settings.currency = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method setSendUserStatus*(self: Service, value: bool) =
|
||||
# this will be done in a proper way in `base_bc`, so far this is just a fix
|
||||
discard status_go_settings.saveSetting(Setting.SendUserStatus, value)
|
||||
method getCurrency*(self: Service): string =
|
||||
if(self.settings.currency.len == 0):
|
||||
self.settings.currency = DEFAULT_CURRENCY
|
||||
|
||||
method getCurrentUserStatus*(self: Service): int =
|
||||
let userStatus = status_go_settings.getSetting[JsonNode](Setting.CurrentUserStatus)
|
||||
return userStatus{"statusType"}.getInt()
|
||||
return self.settings.currency
|
||||
|
||||
method getIdentityImage*(self: Service, address: string): IdentityImage =
|
||||
var obj = status_accounts.getIdentityImage(address)
|
||||
var identityImage = IdentityImage(thumbnail: obj.thumbnail, large: obj.large)
|
||||
return identityImage
|
||||
method saveCurrentNetwork*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_NETWORKS_CURRENT_NETWORK, value)):
|
||||
self.settings.currentNetwork = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getCurrentNetwork*(self: Service): string =
|
||||
if(self.settings.currentNetwork.len == 0):
|
||||
self.settings.currentNetwork = DEFAULT_CURRENT_NETWORK
|
||||
|
||||
return self.settings.currentNetwork
|
||||
|
||||
method saveDappsAddress*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_DAPPS_ADDRESS, value)):
|
||||
self.settings.dappsAddress = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getDappsAddress*(self: Service): string =
|
||||
return status_go_settings.getSetting[string](Setting.DappsAddress)
|
||||
return self.settings.dappsAddress
|
||||
|
||||
method setDappsAddress*(self: Service, address: string): bool =
|
||||
let r = status_go_settings.saveSetting(Setting.DappsAddress, address)
|
||||
return r.error == ""
|
||||
method saveEip1581Address*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_EIP1581_ADDRESS, value)):
|
||||
self.settings.eip1581Address = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getCurrentNetworkDetails*(self: Service): NetworkDetails =
|
||||
let currNetwork = getSetting[string](Setting.Networks_CurrentNetwork, DEFAULT_NETWORK_NAME)
|
||||
let networks = getSetting[seq[NetworkDetails]](Setting.Networks_Networks)
|
||||
for n in networks:
|
||||
if n.id == currNetwork:
|
||||
method getEip1581Address*(self: Service): string =
|
||||
return self.settings.eip1581Address
|
||||
|
||||
method saveInstallationId*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_INSTALLATION_ID, value)):
|
||||
self.settings.installationId = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getInstallationId*(self: Service): string =
|
||||
return self.settings.installationId
|
||||
|
||||
method saveKeyUid*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_KEY_UID, value)):
|
||||
self.settings.keyUid = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getKeyUid*(self: Service): string =
|
||||
return self.settings.keyUid
|
||||
|
||||
method saveLatestDerivedPath*(self: Service, value: int): bool =
|
||||
if(self.saveSetting(KEY_LATEST_DERIVED_PATH, value)):
|
||||
self.settings.latestDerivedPath = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getLatestDerivedPath*(self: Service): int =
|
||||
self.settings.latestDerivedPath
|
||||
|
||||
method saveLinkPreviewRequestEnabled*(self: Service, value: bool): bool =
|
||||
if(self.saveSetting(KEY_LINK_PREVIEW_REQUEST_ENABLED, value)):
|
||||
self.settings.linkPreviewRequestEnabled = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getLinkPreviewRequestEnabled*(self: Service): bool =
|
||||
self.settings.linkPreviewRequestEnabled
|
||||
|
||||
method saveMessagesFromContactsOnly*(self: Service, value: bool): bool =
|
||||
if(self.saveSetting(KEY_MESSAGES_FROM_CONTACTS_ONLY, value)):
|
||||
self.settings.messagesFromContactsOnly = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getMessagesFromContactsOnly*(self: Service): bool =
|
||||
self.settings.messagesFromContactsOnly
|
||||
|
||||
method saveMnemonic*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_MNEMONIC, value)):
|
||||
self.settings.mnemonic = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getMnemonic*(self: Service): string =
|
||||
return self.settings.mnemonic
|
||||
|
||||
method saveName*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_NAME, value)):
|
||||
self.settings.name = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getName*(self: Service): string =
|
||||
return self.settings.name
|
||||
|
||||
method savePhotoPath*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_PHOTO_PATH, value)):
|
||||
self.settings.photoPath = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getPhotoPath*(self: Service): string =
|
||||
return self.settings.photoPath
|
||||
|
||||
method savePreviewPrivacy*(self: Service, value: bool): bool =
|
||||
if(self.saveSetting(KEY_PREVIEW_PRIVACY, value)):
|
||||
self.settings.previewPrivacy = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getPreviewPrivacy*(self: Service): bool =
|
||||
self.settings.previewPrivacy
|
||||
|
||||
method savePublicKey*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_PUBLIC_KEY, value)):
|
||||
self.settings.publicKey = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getPublicKey*(self: Service): string =
|
||||
return self.settings.publicKey
|
||||
|
||||
method saveSigningPhrase*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_SIGNING_PHRASE, value)):
|
||||
self.settings.signingPhrase = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getSigningPhrase*(self: Service): string =
|
||||
return self.settings.signingPhrase
|
||||
|
||||
method saveDefaultSyncPeriod*(self: Service, value: int): bool =
|
||||
if(self.saveSetting(KEY_DEFAULT_SYNC_PERIOD, value)):
|
||||
self.settings.defaultSyncPeriod = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getDefaultSyncPeriod*(self: Service): int =
|
||||
self.settings.defaultSyncPeriod
|
||||
|
||||
method saveSendPushNotifications*(self: Service, value: bool): bool =
|
||||
if(self.saveSetting(KEY_SEND_PUSH_NOTIFICATIONS, value)):
|
||||
self.settings.sendPushNotifications = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getSendPushNotifications*(self: Service): bool =
|
||||
self.settings.sendPushNotifications
|
||||
|
||||
method saveAppearance*(self: Service, value: int): bool =
|
||||
if(self.saveSetting(KEY_APPEARANCE, value)):
|
||||
self.settings.appearance = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getAppearance*(self: Service): int =
|
||||
self.settings.appearance
|
||||
|
||||
method saveProfilePicturesShowTo*(self: Service, value: int): bool =
|
||||
if(self.saveSetting(KEY_PROFILE_PICTURES_SHOW_TO, value)):
|
||||
self.settings.profilePicturesShowTo = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getProfilePicturesShowTo*(self: Service): int =
|
||||
self.settings.profilePicturesShowTo
|
||||
|
||||
method saveProfilePicturesVisibility*(self: Service, value: int): bool =
|
||||
if(self.saveSetting(KEY_PROFILE_PICTURES_VISIBILITY, value)):
|
||||
self.settings.profilePicturesVisibility = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getProfilePicturesVisibility*(self: Service): int =
|
||||
self.settings.profilePicturesVisibility
|
||||
|
||||
method saveUseMailservers*(self: Service, value: bool): bool =
|
||||
if(self.saveSetting(KEY_USE_MAILSERVERS, value)):
|
||||
self.settings.useMailservers = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getUseMailservers*(self: Service): bool =
|
||||
self.settings.useMailservers
|
||||
|
||||
method saveWalletRootAddress*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_WALLET_ROOT_ADDRESS, value)):
|
||||
self.settings.walletRootAddress = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getWalletRootAddress*(self: Service): string =
|
||||
return self.settings.walletRootAddress
|
||||
|
||||
method saveSendStatusUpdates*(self: Service, value: bool): bool =
|
||||
if(self.saveSetting(KEY_SEND_STATUS_UPDATES, value)):
|
||||
self.settings.sendStatusUpdates = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getSendStatusUpdates*(self: Service): bool =
|
||||
self.settings.sendStatusUpdates
|
||||
|
||||
method saveTelemetryServerUrl*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_TELEMETRY_SERVER_URL, value)):
|
||||
self.settings.telemetryServerUrl = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getTelemetryServerUrl*(self: Service): string =
|
||||
return self.settings.telemetryServerUrl
|
||||
|
||||
method saveFleet*(self: Service, value: string): bool =
|
||||
if(self.saveSetting(KEY_FLEET, value)):
|
||||
self.settings.fleet = value
|
||||
return true
|
||||
return false
|
||||
|
||||
method getFleet*(self: Service): string =
|
||||
return self.settings.fleet
|
||||
|
||||
method getAvailableNetworks*(self: Service): seq[Network] =
|
||||
return self.settings.availableNetworks
|
||||
|
||||
method getCurrentNetworkDetails*(self: Service): Network =
|
||||
for n in self.settings.availableNetworks:
|
||||
if(n.id == self.getCurrentNetwork()):
|
||||
return n
|
||||
|
||||
method enableDeveloperFeatures*(self: Service) =
|
||||
discard status_go_settings.saveSetting(Setting.TelemetryServerUrl, TELEMETRY_BASE_URL)
|
||||
discard status_go_settings.saveSetting(Setting.AutoMessageEnabled, true)
|
||||
var nodeConfig = status_go_settings.getNodeConfig()
|
||||
nodeConfig["LogLevel"] = newJString($LogLevel.DEBUG)
|
||||
discard status_go_settings.saveSetting(Setting.NodeConfig, nodeConfig)
|
||||
quit(QuitSuccess) # quits the app TODO: change this to logout instead when supported
|
||||
# we should never be here
|
||||
error "error: current network is not among available networks"
|
||||
|
||||
method getCurrentNetworkId*(self: Service): int =
|
||||
self.getCurrentNetworkDetails().config.networkId
|
||||
|
||||
method getCurrentUserStatus*(self: Service): CurrentUserStatus =
|
||||
self.settings.currentUserStatus
|
||||
|
||||
method getPinnedMailservers*(self: Service): PinnedMailservers =
|
||||
self.settings.pinnedMailservers
|
||||
|
||||
method getWalletVisibleTokens*(self: Service): seq[string] =
|
||||
self.settings.walletVisibleTokens.tokens
|
||||
|
||||
method toggleTelemetry*(self: Service) =
|
||||
let telemetryServerUrl = status_go_settings.getSetting[string](Setting.TelemetryServerUrl)
|
||||
var newValue = ""
|
||||
if telemetryServerUrl == "":
|
||||
newValue = TELEMETRY_BASE_URL
|
||||
newValue = "https://telemetry.status.im"
|
||||
|
||||
discard status_go_settings.saveSetting(Setting.TelemetryServerUrl, newValue)
|
||||
|
||||
|
@ -116,7 +353,16 @@ method toggleDebug*(self: Service) =
|
|||
else:
|
||||
nodeConfig["LogLevel"] = newJString($LogLevel.INFO)
|
||||
discard status_go_settings.saveSetting(Setting.NodeConfig, nodeConfig)
|
||||
quit(QuitSuccess) # quits the app TODO: change this to logout instead when supported
|
||||
|
||||
method isDebugEnabled*(self: Service): bool =
|
||||
let nodeConfig = status_go_settings.getNodeConfig()
|
||||
return nodeConfig["LogLevel"].getStr() != $LogLevel.INFO
|
||||
|
||||
method saveWalletVisibleTokens*(self: Service, tokens: seq[string]): bool =
|
||||
var obj = newJObject()
|
||||
obj[self.getCurrentNetwork()] = %* tokens
|
||||
if(self.saveSetting(KEY_WALLET_VISIBLE_TOKENS, obj)):
|
||||
self.settings.walletVisibleTokens.tokens = tokens
|
||||
return true
|
||||
return false
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import dto
|
||||
import dto/network_details
|
||||
import dto/node_config
|
||||
import dto/upstream_config
|
||||
import ./dto/settings as settings_dto
|
||||
|
||||
export dto
|
||||
export network_details
|
||||
export node_config
|
||||
export upstream_config
|
||||
export settings_dto
|
||||
|
||||
# Default values:
|
||||
const DEFAULT_CURRENT_NETWORK* = "mainnet_rpc"
|
||||
const DEFAULT_CURRENCY* = "usd"
|
||||
const DEFAULT_TELEMETRY_SERVER_URL* = "https://telemetry.status.im"
|
||||
|
||||
type
|
||||
ServiceInterface* {.pure inheritable.} = ref object of RootObj
|
||||
|
@ -18,43 +17,106 @@ method delete*(self: ServiceInterface) {.base.} =
|
|||
method init*(self: ServiceInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getPubKey*(self: ServiceInterface): string {.base.} =
|
||||
method saveAddress*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getNetwork*(self: ServiceInterface): string {.base.} =
|
||||
method getAddress*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getAppearance*(self: ServiceInterface): int {.base.} =
|
||||
method saveCurrency*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getMessagesFromContactsOnly*(self: ServiceInterface): bool {.base.} =
|
||||
method getCurrency*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getSendUserStatus*(self: ServiceInterface): bool {.base.} =
|
||||
method saveCurrentNetwork*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method setSendUserStatus*(self: ServiceInterface, value: bool) {.base.} =
|
||||
method getCurrentNetwork*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getCurrentUserStatus*(self: ServiceInterface): int {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getIdentityImage*(self: ServiceInterface, address: string): IdentityImage {.base.} =
|
||||
method saveDappsAddress*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getDappsAddress*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method setDappsAddress*(self: ServiceInterface, address: string): bool {.base.} =
|
||||
method saveEip1581Address*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getCurrentNetworkDetails*(self: ServiceInterface): NetworkDetails {.base.} =
|
||||
method getEip1581Address*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method toggleTelemetry*(self: ServiceInterface) {.base.} =
|
||||
method saveInstallationId*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isTelemetryEnabled*(self: ServiceInterface): bool {.base.} =
|
||||
method getInstallationId*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveKeyUid*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getKeyUid*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveLatestDerivedPath*(self: ServiceInterface, value: int): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getLatestDerivedPath*(self: ServiceInterface): int {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveLinkPreviewRequestEnabled*(self: ServiceInterface, value: bool): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getLinkPreviewRequestEnabled*(self: ServiceInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveMessagesFromContactsOnly*(self: ServiceInterface, value: bool): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getMessagesFromContactsOnly*(self: ServiceInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveMnemonic*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getMnemonic*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveName*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getName*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method savePhotoPath*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getPhotoPath*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method savePreviewPrivacy*(self: ServiceInterface, value: bool): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getPreviewPrivacy*(self: ServiceInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method savePublicKey*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getPublicKey*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveSigningPhrase*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getSigningPhrase*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveDefaultSyncPeriod*(self: ServiceInterface, value: int): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getDefaultSyncPeriod*(self: ServiceInterface): int {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method toggleAutoMessage*(self: ServiceInterface) {.base.} =
|
||||
|
@ -66,8 +128,77 @@ method isAutoMessageEnabled*(self: ServiceInterface): bool {.base.} =
|
|||
method toggleDebug*(self: ServiceInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isDebugEnabled*(self: ServiceInterface): bool {.base.} =
|
||||
method saveSendPushNotifications*(self: ServiceInterface, value: bool): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method enableDeveloperFeatures*(self: ServiceInterface) {.base.} =
|
||||
method getSendPushNotifications*(self: ServiceInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveAppearance*(self: ServiceInterface, value: int): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getAppearance*(self: ServiceInterface): int {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveProfilePicturesShowTo*(self: ServiceInterface, value: int): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getProfilePicturesShowTo*(self: ServiceInterface): int {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveProfilePicturesVisibility*(self: ServiceInterface, value: int): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getProfilePicturesVisibility*(self: ServiceInterface): int {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveUseMailservers*(self: ServiceInterface, value: bool): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getUseMailservers*(self: ServiceInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveWalletRootAddress*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getWalletRootAddress*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveSendStatusUpdates*(self: ServiceInterface, value: bool): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getSendStatusUpdates*(self: ServiceInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveTelemetryServerUrl*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getTelemetryServerUrl*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveFleet*(self: ServiceInterface, value: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getFleet*(self: ServiceInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getAvailableNetworks*(self: ServiceInterface): seq[Network] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getCurrentNetworkDetails*(self: ServiceInterface): Network {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getCurrentNetworkId*(self: ServiceInterface): int {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getCurrentUserStatus*(self: ServiceInterface): CurrentUserStatus {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getPinnedMailservers*(self: ServiceInterface): PinnedMailservers {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getWalletVisibleTokens*(self: ServiceInterface): seq[string] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method saveWalletVisibleTokens*(self: ServiceInterface, tokens: seq[string]): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -4,8 +4,7 @@ from sugar import `=>`
|
|||
import web3/ethtypes
|
||||
from web3/conversions import `$`
|
||||
import status/statusgo_backend_new/custom_tokens as custom_tokens
|
||||
import ../setting/service as setting_service
|
||||
import ../settings/service as settings_service
|
||||
import ../settings/service_interface as settings_service
|
||||
import ../../../app/core/tasks/[qt, threadpool]
|
||||
import ./dto, ./static_token
|
||||
|
||||
|
@ -39,8 +38,7 @@ QtObject:
|
|||
type Service* = ref object of QObject
|
||||
events: EventEmitter
|
||||
threadpool: ThreadPool
|
||||
settingService: setting_service.Service
|
||||
settingsService: settings_service.Service
|
||||
settingsService: settings_service.ServiceInterface
|
||||
tokens: seq[TokenDto]
|
||||
|
||||
proc delete*(self: Service) =
|
||||
|
@ -49,21 +47,19 @@ QtObject:
|
|||
proc newService*(
|
||||
events: EventEmitter,
|
||||
threadpool: ThreadPool,
|
||||
settingService: setting_service.Service,
|
||||
settingsService: settings_service.Service
|
||||
settingsService: settings_service.ServiceInterface
|
||||
): Service =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.events = events
|
||||
result.threadpool = threadpool
|
||||
result.settingService = settingService
|
||||
result.settingsService = settingsService
|
||||
result.tokens = @[]
|
||||
|
||||
proc getDefaultVisibleSymbols(self: Service): seq[string] =
|
||||
let networkSlug = self.settingService.getSetting().currentNetwork.slug
|
||||
let networkSlug = self.settingsService.getCurrentNetwork()
|
||||
|
||||
if networkSlug == "mainnet_rpc":
|
||||
if networkSlug == DEFAULT_CURRENT_NETWORK:
|
||||
return @["SNT"]
|
||||
|
||||
if networkSlug == "testnet_rpc" or networkSlug == "rinkeby_rpc":
|
||||
|
@ -74,7 +70,7 @@ QtObject:
|
|||
|
||||
proc init*(self: Service) =
|
||||
try:
|
||||
var activeTokenSymbols = self.settingService.getSetting().activeTokenSymbols
|
||||
var activeTokenSymbols = self.settingsService.getWalletVisibleTokens()
|
||||
if activeTokenSymbols.len == 0:
|
||||
activeTokenSymbols = self.getDefaultVisibleSymbols()
|
||||
|
||||
|
@ -89,7 +85,7 @@ QtObject:
|
|||
static_tokens,
|
||||
map(response.result.getElems(), proc(x: JsonNode): TokenDto = x.toTokenDto(activeTokenSymbols))
|
||||
).filter(
|
||||
proc(x: TokenDto): bool = x.chainId == self.settingService.getSetting().currentNetwork.id
|
||||
proc(x: TokenDto): bool = x.chainId == self.settingsService.getCurrentNetworkId()
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -104,7 +100,7 @@ QtObject:
|
|||
custom_tokens.addCustomToken(address, name, symbol, decimals, "")
|
||||
let token = newDto(
|
||||
name,
|
||||
self.settingService.getSetting().currentNetwork.id,
|
||||
self.settingsService.getCurrentNetworkId(),
|
||||
fromHex(Address, address),
|
||||
symbol,
|
||||
decimals,
|
||||
|
@ -123,7 +119,7 @@ QtObject:
|
|||
break
|
||||
|
||||
let visibleSymbols = self.tokens.filter(t => t.isVisible).map(t => t.symbol)
|
||||
discard self.settingService.saveSetting("wallet/visible-tokens", visibleSymbols)
|
||||
discard self.settingsService.saveWalletVisibleTokens(visibleSymbols)
|
||||
self.events.emit("token/visibilityToggled", VisibilityToggled(token: tokenChanged))
|
||||
|
||||
proc removeCustomToken*(self: Service, address: string) =
|
||||
|
@ -145,7 +141,7 @@ QtObject:
|
|||
))
|
||||
|
||||
proc getTokenDetails*(self: Service, address: string) =
|
||||
let chainId = self.settingsService.getCurrentNetworkDetails().config.networkId
|
||||
let chainId = self.settingsService.getCurrentNetworkId()
|
||||
let arg = GetTokenDetailsTaskArg(
|
||||
tptr: cast[ByteAddress](getTokenDetailsTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
|
|
|
@ -2,14 +2,13 @@ import Tables, json, sequtils, sugar, chronicles, strformat, stint, httpclient,
|
|||
import web3/[ethtypes, conversions]
|
||||
import eventemitter
|
||||
|
||||
import ../setting/service as setting_service
|
||||
import ../settings/service_interface as settings_service
|
||||
import ../token/service as token_service
|
||||
import ../../common/account_constants
|
||||
import ../../../constants
|
||||
|
||||
import ./service_interface, ./dto
|
||||
import status/statusgo_backend_new/accounts as status_go_accounts
|
||||
import status/statusgo_backend_new/tokens as status_go_tokens
|
||||
import status/statusgo_backend_new/eth as status_go_eth
|
||||
|
||||
export service_interface
|
||||
|
@ -62,6 +61,20 @@ proc fetchAccounts(): seq[WalletAccountDto] =
|
|||
x => x.toWalletAccountDto()
|
||||
).filter(a => not a.isChat)
|
||||
|
||||
|
||||
proc fetchTokenBalance(tokenAddress, accountAddress: string, decimals: int): float64 =
|
||||
let key = tokenAddress & accountAddress
|
||||
if balanceCache.hasKey(key):
|
||||
return balanceCache[key]
|
||||
|
||||
try:
|
||||
let tokenBalanceResponse = status_go_eth.getTokenBalance(tokenAddress, accountAddress)
|
||||
result = parsefloat(hex2Balance(tokenBalanceResponse.result.getStr, decimals))
|
||||
balanceCache[key] = result
|
||||
except Exception as e:
|
||||
error "Error getting token balance", msg = e.msg
|
||||
|
||||
|
||||
proc fetchEthBalance(accountAddress: string): float64 =
|
||||
let key = "0x0" & accountAddress
|
||||
if balanceCache.hasKey(key):
|
||||
|
@ -88,7 +101,7 @@ type WalletAccountUpdated = ref object of Args
|
|||
type
|
||||
Service* = ref object of service_interface.ServiceInterface
|
||||
events: EventEmitter
|
||||
settingService: setting_service.Service
|
||||
settingsService: settings_service.ServiceInterface
|
||||
tokenService: token_service.Service
|
||||
accounts: OrderedTable[string, WalletAccountDto]
|
||||
|
||||
|
@ -96,11 +109,11 @@ method delete*(self: Service) =
|
|||
discard
|
||||
|
||||
proc newService*(
|
||||
events: EventEmitter, settingService: setting_service.Service, tokenService: token_service.Service
|
||||
): Service =
|
||||
events: EventEmitter, settingsService: settings_service.ServiceInterface, tokenService: token_service.Service):
|
||||
Service =
|
||||
result = Service()
|
||||
result.events = events
|
||||
result.settingService = settingService
|
||||
result.settingsService = settingsService
|
||||
result.tokenService = tokenService
|
||||
result.accounts = initOrderedTable[string, WalletAccountDto]()
|
||||
|
||||
|
@ -110,8 +123,7 @@ method getVisibleTokens(self: Service): seq[TokenDto] =
|
|||
method buildTokens(
|
||||
self: Service,
|
||||
account: WalletAccountDto,
|
||||
prices: Table[string, float64],
|
||||
balances: JsonNode,
|
||||
prices: Table[string, float64]
|
||||
): seq[WalletTokenDto] =
|
||||
let balance = fetchEthBalance(account.address)
|
||||
result = @[WalletTokenDto(
|
||||
|
@ -127,7 +139,7 @@ method buildTokens(
|
|||
)]
|
||||
|
||||
for token in self.getVisibleTokens():
|
||||
let balance = parsefloat(hex2Balance(balances{token.addressAsString()}.getStr, token.decimals))
|
||||
let balance = fetchTokenBalance($token.address, account.address, token.decimals)
|
||||
result.add(
|
||||
WalletTokenDto(
|
||||
name: token.name,
|
||||
|
@ -143,26 +155,18 @@ method buildTokens(
|
|||
)
|
||||
|
||||
method fetchPrices(self: Service): Table[string, float64] =
|
||||
let currency = self.settingService.getSetting().currency
|
||||
let currency = self.settingsService.getCurrency()
|
||||
var prices = {"ETH": fetchPrice("ETH", currency)}.toTable
|
||||
for token in self.getVisibleTokens():
|
||||
prices[token.symbol] = fetchPrice(token.symbol, currency)
|
||||
|
||||
return prices
|
||||
|
||||
method fetchBalances(self: Service, accounts: seq[string]): JsonNode =
|
||||
let network = self.settingService.getSetting().currentNetwork
|
||||
let tokens = self.getVisibleTokens().map(t => t.addressAsString())
|
||||
|
||||
return status_go_tokens.getBalances(network.id, accounts, tokens).result
|
||||
|
||||
method refreshBalances(self: Service) =
|
||||
let prices = self.fetchPrices()
|
||||
let accounts = toSeq(self.accounts.keys)
|
||||
let balances = self.fetchBalances(accounts)
|
||||
|
||||
for account in toSeq(self.accounts.values):
|
||||
account.tokens = self.buildTokens(account, prices, balances{account.address})
|
||||
account.tokens = self.buildTokens(account, prices)
|
||||
|
||||
method init*(self: Service) =
|
||||
try:
|
||||
|
@ -189,7 +193,33 @@ method getWalletAccount*(self: Service, accountIndex: int): WalletAccountDto =
|
|||
method getCurrencyBalance*(self: Service): float64 =
|
||||
return self.getWalletAccounts().map(a => a.getCurrencyBalance()).foldl(a + b, 0.0)
|
||||
|
||||
method addNewAccountToLocalStore(self: Service) =
|
||||
method getDefaultAccount(self: Service): string =
|
||||
return status_go_eth.getAccounts().result[0].getStr
|
||||
|
||||
method saveAccount(
|
||||
self: Service,
|
||||
address: string,
|
||||
name: string,
|
||||
password: string,
|
||||
color: string,
|
||||
accountType: string,
|
||||
isADerivedAccount = true,
|
||||
walletIndex: int = 0,
|
||||
id: string = "",
|
||||
publicKey: string = "",
|
||||
): string =
|
||||
try:
|
||||
status_go_accounts.saveAccount(
|
||||
address,
|
||||
name,
|
||||
password,
|
||||
color,
|
||||
accountType,
|
||||
isADerivedAccount = true,
|
||||
walletIndex,
|
||||
id,
|
||||
publicKey,
|
||||
)
|
||||
let accounts = fetchAccounts()
|
||||
let prices = self.fetchPrices()
|
||||
|
||||
|
@ -199,64 +229,92 @@ method addNewAccountToLocalStore(self: Service) =
|
|||
newAccount = account
|
||||
break
|
||||
|
||||
let balances = self.fetchBalances(@[newAccount.address])
|
||||
newAccount.tokens = self.buildTokens(newAccount, prices, balances{newAccount.address})
|
||||
newAccount.tokens = self.buildTokens(newAccount, prices)
|
||||
self.accounts[newAccount.address] = newAccount
|
||||
self.events.emit("walletAccount/accountSaved", AccountSaved(account: newAccount))
|
||||
except Exception as e:
|
||||
return fmt"Error adding new account: {e.msg}"
|
||||
|
||||
method generateNewAccount*(self: Service, password: string, accountName: string, color: string): string =
|
||||
try:
|
||||
discard status_go_accounts.generateAccount(
|
||||
password,
|
||||
accountName,
|
||||
color,
|
||||
)
|
||||
except Exception as e:
|
||||
return fmt"Error generating new account: {e.msg}"
|
||||
let
|
||||
walletRootAddress = self.settingsService.getWalletRootAddress()
|
||||
walletIndex = self.settingsService.getLatestDerivedPath() + 1
|
||||
defaultAccount = self.getDefaultAccount()
|
||||
isPasswordOk = status_go_accounts.verifyAccountPassword(defaultAccount, password, KEYSTOREDIR)
|
||||
|
||||
self.addNewAccountToLocalStore()
|
||||
if not isPasswordOk:
|
||||
return "Error generating new account: invalid password"
|
||||
|
||||
let accountResponse = status_go_accounts.loadAccount(walletRootAddress, password)
|
||||
let accountId = accountResponse.result{"id"}.getStr
|
||||
let path = "m/" & $walletIndex
|
||||
let deriveResponse = status_go_accounts.deriveAccounts(accountId, @[path])
|
||||
let errMsg = self.saveAccount(
|
||||
deriveResponse.result[path]{"address"}.getStr,
|
||||
accountName,
|
||||
password,
|
||||
color,
|
||||
status_go_accounts.GENERATED,
|
||||
true,
|
||||
walletIndex,
|
||||
accountId,
|
||||
deriveResponse.result[path]{"publicKey"}.getStr
|
||||
)
|
||||
if errMsg != "":
|
||||
return errMsg
|
||||
|
||||
discard self.settingsService.saveLatestDerivedPath(walletIndex)
|
||||
return ""
|
||||
|
||||
method addAccountsFromPrivateKey*(self: Service, privateKey: string, password: string, accountName: string, color: string): string =
|
||||
try:
|
||||
discard status_go_accounts.addAccountWithPrivateKey(
|
||||
privateKey,
|
||||
password,
|
||||
let
|
||||
accountResponse = status_go_accounts.multiAccountImportPrivateKey(privateKey)
|
||||
defaultAccount = self.getDefaultAccount()
|
||||
isPasswordOk = status_go_accounts.verifyAccountPassword(defaultAccount, password, KEYSTOREDIR)
|
||||
|
||||
if not isPasswordOk:
|
||||
return "Error generating new account: invalid password"
|
||||
|
||||
return self.saveAccount(
|
||||
accountResponse.result{"address"}.getStr,
|
||||
accountName,
|
||||
color,
|
||||
)
|
||||
except Exception as e:
|
||||
return fmt"Error adding account with private key: {e.msg}"
|
||||
|
||||
self.addNewAccountToLocalStore()
|
||||
return ""
|
||||
|
||||
method addAccountsFromSeed*(self: Service, mnemonic: string, password: string, accountName: string, color: string): string =
|
||||
try:
|
||||
discard status_go_accounts.addAccountWithMnemonic(
|
||||
mnemonic,
|
||||
password,
|
||||
accountName,
|
||||
color,
|
||||
status_go_accounts.KEY,
|
||||
false,
|
||||
0,
|
||||
accountResponse.result{"accountId"}.getStr,
|
||||
accountResponse.result{"publicKey"}.getStr,
|
||||
)
|
||||
except Exception as e:
|
||||
return fmt"Error adding account with mnemonic: {e.msg}"
|
||||
|
||||
self.addNewAccountToLocalStore()
|
||||
return ""
|
||||
method addAccountsFromSeed*(self: Service, seedPhrase: string, password: string, accountName: string, color: string): string =
|
||||
let mnemonic = replace(seedPhrase, ',', ' ')
|
||||
let paths = @[PATH_WALLET_ROOT, PATH_EIP_1581, PATH_WHISPER, PATH_DEFAULT_WALLET]
|
||||
let accountResponse = status_go_accounts.multiAccountImportMnemonic(mnemonic)
|
||||
let accountId = accountResponse.result{"id"}.getStr
|
||||
let deriveResponse = status_go_accounts.deriveAccounts(accountId, paths)
|
||||
|
||||
let
|
||||
defaultAccount = self.getDefaultAccount()
|
||||
isPasswordOk = status_go_accounts.verifyAccountPassword(defaultAccount, password, KEYSTOREDIR)
|
||||
|
||||
if not isPasswordOk:
|
||||
return "Error generating new account: invalid password"
|
||||
|
||||
return self.saveAccount(
|
||||
deriveResponse.result[PATH_DEFAULT_WALLET]{"address"}.getStr,
|
||||
accountName,
|
||||
password,
|
||||
color,
|
||||
status_go_accounts.SEED,
|
||||
true,
|
||||
0,
|
||||
accountId,
|
||||
deriveResponse.result[PATH_DEFAULT_WALLET]{"publicKey"}.getStr
|
||||
)
|
||||
|
||||
method addWatchOnlyAccount*(self: Service, address: string, accountName: string, color: string): string =
|
||||
try:
|
||||
discard status_go_accounts.addAccountWatch(
|
||||
address,
|
||||
accountName,
|
||||
color,
|
||||
)
|
||||
except Exception as e:
|
||||
return fmt"Error adding account with mnemonic: {e.msg}"
|
||||
|
||||
self.addNewAccountToLocalStore()
|
||||
return ""
|
||||
return self.saveAccount(address, accountName, "", color, status_go_accounts.WATCH, false)
|
||||
|
||||
method deleteAccount*(self: Service, address: string) =
|
||||
discard status_go_accounts.deleteAccount(address)
|
||||
|
@ -266,7 +324,7 @@ method deleteAccount*(self: Service, address: string) =
|
|||
self.events.emit("walletAccount/accountDeleted", AccountDeleted(account: accountDeleted))
|
||||
|
||||
method updateCurrency*(self: Service, newCurrency: string) =
|
||||
discard self.settingService.saveSetting("currency", newCurrency)
|
||||
discard self.settingsService.saveCurrency(newCurrency)
|
||||
self.refreshBalances()
|
||||
self.events.emit("walletAccount/currencyUpdated", CurrencyUpdated())
|
||||
|
||||
|
|
Loading…
Reference in New Issue