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/transaction/service as transaction_service
|
||||||
import ../../app_service/service/collectible/service as collectible_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/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/bookmarks/service as bookmark_service
|
||||||
import ../../app_service/service/dapp_permissions/service as dapp_permissions_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/mnemonic/service as mnemonic_service
|
||||||
import ../../app_service/service/privacy/service as privacy_service
|
import ../../app_service/service/privacy/service as privacy_service
|
||||||
import ../../app_service/service/provider/service as provider_service
|
import ../../app_service/service/provider/service as provider_service
|
||||||
import ../../app_service/service/ens/service as ens_service
|
import ../../app_service/service/ens/service as ens_service
|
||||||
|
|
||||||
import ../../app_service/service/profile/service as profile_service
|
import ../../app_service/service/profile/service as profile_service
|
||||||
import ../../app_service/service/settings/service as settings_service
|
import ../../app_service/service/settings/service as settings_service
|
||||||
import ../../app_service/service/about/service as about_service
|
import ../../app_service/service/about/service as about_service
|
||||||
|
@ -92,7 +90,6 @@ type
|
||||||
transactionService: transaction_service.Service
|
transactionService: transaction_service.Service
|
||||||
collectibleService: collectible_service.Service
|
collectibleService: collectible_service.Service
|
||||||
walletAccountService: wallet_account_service.Service
|
walletAccountService: wallet_account_service.Service
|
||||||
settingService: setting_service.Service
|
|
||||||
bookmarkService: bookmark_service.Service
|
bookmarkService: bookmark_service.Service
|
||||||
dappPermissionsService: dapp_permissions_service.Service
|
dappPermissionsService: dapp_permissions_service.Service
|
||||||
ensService: ens_service.Service
|
ensService: ens_service.Service
|
||||||
|
@ -167,7 +164,6 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
||||||
# Services
|
# Services
|
||||||
result.osNotificationService = os_notification_service.newService(statusFoundation.status.events)
|
result.osNotificationService = os_notification_service.newService(statusFoundation.status.events)
|
||||||
result.keychainService = keychain_service.newService(statusFoundation.status.events)
|
result.keychainService = keychain_service.newService(statusFoundation.status.events)
|
||||||
result.settingService = setting_service.newService()
|
|
||||||
result.settingsService = settings_service.newService()
|
result.settingsService = settings_service.newService()
|
||||||
result.accountsService = accounts_service.newService()
|
result.accountsService = accounts_service.newService()
|
||||||
result.contactsService = contacts_service.newService(statusFoundation.status.events, statusFoundation.threadpool)
|
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.communityService = community_service.newService(result.chatService)
|
||||||
result.messageService = message_service.newService(statusFoundation.status.events, statusFoundation.threadpool)
|
result.messageService = message_service.newService(statusFoundation.status.events, statusFoundation.threadpool)
|
||||||
result.tokenService = token_service.newService(statusFoundation.status.events, statusFoundation.threadpool,
|
result.tokenService = token_service.newService(statusFoundation.status.events, statusFoundation.threadpool,
|
||||||
result.settingService, result.settingsService)
|
result.settingsService)
|
||||||
result.collectibleService = collectible_service.newService(result.settingService)
|
result.collectibleService = collectible_service.newService(result.settingsService)
|
||||||
result.walletAccountService = wallet_account_service.newService(statusFoundation.status.events, result.settingService,
|
result.walletAccountService = wallet_account_service.newService(statusFoundation.status.events, result.settingsService,
|
||||||
result.tokenService)
|
result.tokenService)
|
||||||
result.transactionService = transaction_service.newService(statusFoundation.status.events, statusFoundation.threadpool,
|
result.transactionService = transaction_service.newService(statusFoundation.status.events, statusFoundation.threadpool,
|
||||||
result.walletAccountService)
|
result.walletAccountService)
|
||||||
|
@ -212,7 +208,6 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
||||||
result.collectibleService,
|
result.collectibleService,
|
||||||
result.walletAccountService,
|
result.walletAccountService,
|
||||||
result.bookmarkService,
|
result.bookmarkService,
|
||||||
result.settingService,
|
|
||||||
result.profileService,
|
result.profileService,
|
||||||
result.settingsService,
|
result.settingsService,
|
||||||
result.contactsService,
|
result.contactsService,
|
||||||
|
@ -236,18 +231,6 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
||||||
result.connect()
|
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) =
|
proc delete*(self: AppController) =
|
||||||
self.osNotificationService.delete
|
self.osNotificationService.delete
|
||||||
self.contactsService.delete
|
self.contactsService.delete
|
||||||
|
@ -279,7 +262,7 @@ proc delete*(self: AppController) =
|
||||||
self.tokenService.delete
|
self.tokenService.delete
|
||||||
self.transactionService.delete
|
self.transactionService.delete
|
||||||
self.collectibleService.delete
|
self.collectibleService.delete
|
||||||
self.settingService.delete
|
self.settingsService.delete
|
||||||
self.walletAccountService.delete
|
self.walletAccountService.delete
|
||||||
self.aboutService.delete
|
self.aboutService.delete
|
||||||
self.dappPermissionsService.delete
|
self.dappPermissionsService.delete
|
||||||
|
@ -323,13 +306,12 @@ proc start*(self: AppController) =
|
||||||
self.startupModule.load()
|
self.startupModule.load()
|
||||||
|
|
||||||
proc load(self: AppController) =
|
proc load(self: AppController) =
|
||||||
self.settingService.init()
|
self.settingsService.init()
|
||||||
self.contactsService.init()
|
self.contactsService.init()
|
||||||
self.chatService.init()
|
self.chatService.init()
|
||||||
self.communityService.init()
|
self.communityService.init()
|
||||||
self.bookmarkService.init()
|
self.bookmarkService.init()
|
||||||
self.tokenService.init()
|
self.tokenService.init()
|
||||||
self.settingsService.init()
|
|
||||||
self.dappPermissionsService.init()
|
self.dappPermissionsService.init()
|
||||||
self.ensService.init()
|
self.ensService.init()
|
||||||
self.providerService.init()
|
self.providerService.init()
|
||||||
|
@ -337,12 +319,9 @@ proc load(self: AppController) =
|
||||||
self.transactionService.init()
|
self.transactionService.init()
|
||||||
self.languageService.init()
|
self.languageService.init()
|
||||||
|
|
||||||
#################################################
|
let pubKey = self.settingsService.getPublicKey()
|
||||||
# Once SettingService gets added, `pubKey` should be fetched from there, instead the following line:
|
|
||||||
let pubKey = self.settingsService.getPubKey()
|
|
||||||
singletonInstance.localAccountSensitiveSettings.setFileName(pubKey)
|
singletonInstance.localAccountSensitiveSettings.setFileName(pubKey)
|
||||||
singletonInstance.engine.setRootContextProperty("localAccountSensitiveSettings", self.localAccountSensitiveSettingsVariant)
|
singletonInstance.engine.setRootContextProperty("localAccountSensitiveSettings", self.localAccountSensitiveSettingsVariant)
|
||||||
#################################################
|
|
||||||
|
|
||||||
# other global instances
|
# other global instances
|
||||||
self.buildAndRegisterLocalAccountSensitiveSettings()
|
self.buildAndRegisterLocalAccountSensitiveSettings()
|
||||||
|
@ -361,24 +340,34 @@ proc userLoggedIn*(self: AppController) =
|
||||||
self.load()
|
self.load()
|
||||||
|
|
||||||
proc buildAndRegisterLocalAccountSensitiveSettings(self: AppController) =
|
proc buildAndRegisterLocalAccountSensitiveSettings(self: AppController) =
|
||||||
var pubKey = self.settingsService.getPubKey()
|
var pubKey = self.settingsService.getPublicKey()
|
||||||
singletonInstance.localAccountSensitiveSettings.setFileName(pubKey)
|
singletonInstance.localAccountSensitiveSettings.setFileName(pubKey)
|
||||||
singletonInstance.engine.setRootContextProperty("localAccountSensitiveSettings", self.localAccountSensitiveSettingsVariant)
|
singletonInstance.engine.setRootContextProperty("localAccountSensitiveSettings", self.localAccountSensitiveSettingsVariant)
|
||||||
|
|
||||||
proc buildAndRegisterUserProfile(self: AppController) =
|
proc buildAndRegisterUserProfile(self: AppController) =
|
||||||
let loggedInAccount = self.accountsService.getLoggedInAccount()
|
let pubKey = self.settingsService.getPublicKey()
|
||||||
|
let sendUserStatus = self.settingsService.getSendStatusUpdates()
|
||||||
let pubKey = self.settingsService.getPubKey()
|
|
||||||
let sendUserStatus = self.settingsService.getSendUserStatus()
|
|
||||||
## This is still not in use. Read a comment in UserProfile.
|
## This is still not in use. Read a comment in UserProfile.
|
||||||
## let currentUserStatus = self.settingsService.getCurrentUserStatus()
|
## 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,
|
singletonInstance.userProfile.setFixedData(loggedInAccount.name, loggedInAccount.keyUid, loggedInAccount.identicon,
|
||||||
pubKey)
|
pubKey)
|
||||||
singletonInstance.userProfile.setEnsName("") # in this moment we don't know ens name
|
singletonInstance.userProfile.setEnsName(ensName)
|
||||||
singletonInstance.userProfile.setThumbnailImage(obj.thumbnail)
|
singletonInstance.userProfile.setThumbnailImage(thumbnail)
|
||||||
singletonInstance.userProfile.setLargeImage(obj.large)
|
singletonInstance.userProfile.setLargeImage(large)
|
||||||
singletonInstance.userProfile.setUserStatus(sendUserStatus)
|
singletonInstance.userProfile.setUserStatus(sendUserStatus)
|
||||||
|
|
||||||
singletonInstance.engine.setRootContextProperty("userProfile", self.userProfileVariant)
|
singletonInstance.engine.setRootContextProperty("userProfile", self.userProfileVariant)
|
||||||
|
|
|
@ -12,7 +12,7 @@ QtObject:
|
||||||
thumbnailImage: string
|
thumbnailImage: string
|
||||||
largeImage: string
|
largeImage: string
|
||||||
userStatus: bool
|
userStatus: bool
|
||||||
currentUserStatus: int
|
#currentUserStatus: int
|
||||||
|
|
||||||
proc setup(self: UserProfile) =
|
proc setup(self: UserProfile) =
|
||||||
self.QObject.setup
|
self.QObject.setup
|
||||||
|
|
|
@ -35,11 +35,11 @@ method getDappsAddress*(self: Controller): string =
|
||||||
return self.settingsService.getDappsAddress()
|
return self.settingsService.getDappsAddress()
|
||||||
|
|
||||||
method setDappsAddress*(self: Controller, address: string) =
|
method setDappsAddress*(self: Controller, address: string) =
|
||||||
if self.settingsService.setDappsAddress(address):
|
if self.settingsService.saveDappsAddress(address):
|
||||||
self.delegate.onDappAddressChanged(address)
|
self.delegate.onDappAddressChanged(address)
|
||||||
|
|
||||||
method getCurrentNetworkDetails*(self: Controller): NetworkDetails =
|
method getCurrentNetworkId*(self: Controller): int =
|
||||||
return self.settingsService.getCurrentNetworkDetails()
|
return self.settingsService.getCurrentNetworkId()
|
||||||
|
|
||||||
method disconnect*(self: Controller) =
|
method disconnect*(self: Controller) =
|
||||||
discard self.dappPermissionsService.revoke("web3".toPermission())
|
discard self.dappPermissionsService.revoke("web3".toPermission())
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import ../../../../../app_service/service/settings/service as settings_service
|
|
||||||
|
|
||||||
type
|
type
|
||||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
## Abstract class for any input/interaction with this module.
|
## 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.} =
|
method setDappsAddress*(self: AccessInterface, address: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getCurrentNetworkDetails*(self: AccessInterface): NetworkDetails {.base.} =
|
method getCurrentNetworkId*(self: AccessInterface): int {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method disconnect*(self: AccessInterface) {.base.} =
|
method disconnect*(self: AccessInterface) {.base.} =
|
||||||
|
|
|
@ -36,7 +36,7 @@ method delete*(self: Module) =
|
||||||
method load*(self: Module) =
|
method load*(self: Module) =
|
||||||
singletonInstance.engine.setRootContextProperty("providerModule", self.viewVariant)
|
singletonInstance.engine.setRootContextProperty("providerModule", self.viewVariant)
|
||||||
self.view.dappsAddress = self.controller.getDappsAddress()
|
self.view.dappsAddress = self.controller.getDappsAddress()
|
||||||
self.view.networkId = self.controller.getCurrentNetworkDetails().config.networkId
|
self.view.networkId = self.controller.getCurrentNetworkId()
|
||||||
self.view.load()
|
self.view.load()
|
||||||
|
|
||||||
method isLoaded*(self: Module): bool =
|
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 ../../global/global_singleton
|
||||||
|
|
||||||
import ../../../app_service/service/settings/service_interface as settings_service
|
import ../../../app_service/service/settings/service_interface as settings_service
|
||||||
|
@ -12,6 +12,9 @@ import eventemitter
|
||||||
|
|
||||||
export controller_interface
|
export controller_interface
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topics = "main-module-controller"
|
||||||
|
|
||||||
type
|
type
|
||||||
Controller* = ref object of controller_interface.AccessInterface
|
Controller* = ref object of controller_interface.AccessInterface
|
||||||
delegate: io_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
|
@ -139,5 +142,7 @@ method getNumOfNotificaitonsForCommunity*(self: Controller, communityId: string)
|
||||||
result.mentions += chat.unviewedMentionsCount
|
result.mentions += chat.unviewedMentionsCount
|
||||||
|
|
||||||
method setUserStatus*(self: Controller, status: bool) =
|
method setUserStatus*(self: Controller, status: bool) =
|
||||||
self.settingsService.setSendUserStatus(status)
|
if(self.settingsService.saveSendStatusUpdates(status)):
|
||||||
singletonInstance.userProfile.setUserStatus(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/transaction/service as transaction_service
|
||||||
import ../../../app_service/service/collectible/service as collectible_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/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/bookmarks/service as bookmark_service
|
||||||
import ../../../app_service/service/dapp_permissions/service as dapp_permissions_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/provider/service as provider_service
|
||||||
|
|
||||||
import ../../../app_service/service/profile/service as profile_service
|
import ../../../app_service/service/profile/service as profile_service
|
||||||
import ../../../app_service/service/accounts/service as accounts_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/contacts/service as contacts_service
|
||||||
import ../../../app_service/service/about/service as about_service
|
import ../../../app_service/service/about/service as about_service
|
||||||
import ../../../app_service/service/language/service as language_service
|
import ../../../app_service/service/language/service as language_service
|
||||||
|
@ -63,7 +61,6 @@ proc newModule*[T](
|
||||||
collectibleService: collectible_service.Service,
|
collectibleService: collectible_service.Service,
|
||||||
walletAccountService: wallet_account_service.Service,
|
walletAccountService: wallet_account_service.Service,
|
||||||
bookmarkService: bookmark_service.ServiceInterface,
|
bookmarkService: bookmark_service.ServiceInterface,
|
||||||
settingService: setting_service.Service,
|
|
||||||
profileService: profile_service.ServiceInterface,
|
profileService: profile_service.ServiceInterface,
|
||||||
settingsService: settings_service.ServiceInterface,
|
settingsService: settings_service.ServiceInterface,
|
||||||
contactsService: contacts_service.Service,
|
contactsService: contacts_service.Service,
|
||||||
|
@ -87,7 +84,7 @@ proc newModule*[T](
|
||||||
communityService, messageService)
|
communityService, messageService)
|
||||||
result.communitySectionsModule = initOrderedTable[string, chat_section_module.AccessInterface]()
|
result.communitySectionsModule = initOrderedTable[string, chat_section_module.AccessInterface]()
|
||||||
result.walletSectionModule = wallet_section_module.newModule[Module[T]](result, events, tokenService,
|
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,
|
result.browserSectionModule = browser_section_module.newModule(result, bookmarkService, settingsService,
|
||||||
dappPermissionsService, providerService)
|
dappPermissionsService, providerService)
|
||||||
result.profileSectionModule = profile_section_module.newModule(result, events, accountsService, settingsService,
|
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/profile/service as profile_service
|
||||||
import ../../../../app_service/service/accounts/service as accounts_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/language/service as language_service
|
||||||
import ../../../../app_service/service/mnemonic/service as mnemonic_service
|
import ../../../../app_service/service/mnemonic/service as mnemonic_service
|
||||||
import ../../../../app_service/service/privacy/service as privacy_service
|
import ../../../../app_service/service/privacy/service as privacy_service
|
||||||
|
@ -22,7 +22,10 @@ type
|
||||||
mnemonicService: mnemonic_service.ServiceInterface
|
mnemonicService: mnemonic_service.ServiceInterface
|
||||||
privacyService: privacy_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 = Controller[T]()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.profileService = profileService
|
result.profileService = profileService
|
||||||
|
@ -42,10 +45,14 @@ method enableDeveloperFeatures*[T](self: Controller[T]) =
|
||||||
self.settingsService.enableDeveloperFeatures()
|
self.settingsService.enableDeveloperFeatures()
|
||||||
|
|
||||||
method toggleTelemetry*[T](self: Controller[T]) =
|
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 =
|
method isTelemetryEnabled*[T](self: Controller[T]): bool =
|
||||||
return self.settingsService.isTelemetryEnabled()
|
return self.settingsService.getTelemetryServerUrl().len > 0
|
||||||
|
|
||||||
method toggleAutoMessage*[T](self: Controller[T]) =
|
method toggleAutoMessage*[T](self: Controller[T]) =
|
||||||
self.settingsService.toggleAutoMessage()
|
self.settingsService.toggleAutoMessage()
|
||||||
|
@ -54,7 +61,11 @@ method isAutoMessageEnabled*[T](self: Controller[T]): bool =
|
||||||
return self.settingsService.isAutoMessageEnabled()
|
return self.settingsService.isAutoMessageEnabled()
|
||||||
|
|
||||||
method toggleDebug*[T](self: Controller[T]) =
|
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 =
|
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/profile/service as profile_service
|
||||||
import ../../../../app_service/service/accounts/service as accounts_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/contacts/service as contacts_service
|
||||||
import ../../../../app_service/service/about/service as about_service
|
import ../../../../app_service/service/about/service as about_service
|
||||||
import ../../../../app_service/service/language/service as language_service
|
import ../../../../app_service/service/language/service as language_service
|
||||||
|
|
|
@ -3,7 +3,7 @@ import ./controller_interface
|
||||||
import ../../../../global/global_singleton
|
import ../../../../global/global_singleton
|
||||||
import ../../../../../app_service/service/profile/service as profile_service
|
import ../../../../../app_service/service/profile/service as profile_service
|
||||||
import ../../../../../app_service/service/accounts/service as accounts_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 ./item as item
|
||||||
import status/types/identity_image
|
import status/types/identity_image
|
||||||
|
@ -17,7 +17,8 @@ type
|
||||||
settingsService: settings_service.ServiceInterface
|
settingsService: settings_service.ServiceInterface
|
||||||
accountsService: accounts_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 = Controller[T]()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.profileService = profileService
|
result.profileService = profileService
|
||||||
|
@ -32,7 +33,6 @@ method init*[T](self: Controller[T]) =
|
||||||
|
|
||||||
method getProfile*[T](self: Controller[T]): item.Item =
|
method getProfile*[T](self: Controller[T]): item.Item =
|
||||||
|
|
||||||
var network = self.settingsService.getNetwork()
|
|
||||||
var appearance = self.settingsService.getAppearance()
|
var appearance = self.settingsService.getAppearance()
|
||||||
var messagesFromContactsOnly = self.settingsService.getMessagesFromContactsOnly()
|
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/profile/service as profile_service
|
||||||
import ../../../../../app_service/service/accounts/service as accounts_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
|
import status/types/identity_image
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@ type
|
||||||
viewVariant: QVariant
|
viewVariant: QVariant
|
||||||
moduleLoaded: bool
|
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 = Module[T]()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.view = newView(result)
|
result.view = newView(result)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import ./controller_interface
|
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
|
import ../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||||
|
|
||||||
export controller_interface
|
export controller_interface
|
||||||
|
@ -7,17 +7,17 @@ export controller_interface
|
||||||
type
|
type
|
||||||
Controller*[T: controller_interface.DelegateInterface] = ref object of controller_interface.AccessInterface
|
Controller*[T: controller_interface.DelegateInterface] = ref object of controller_interface.AccessInterface
|
||||||
delegate: T
|
delegate: T
|
||||||
settingService: setting_service.ServiceInterface
|
settingsService: settings_service.ServiceInterface
|
||||||
walletAccountService: wallet_account_service.ServiceInterface
|
walletAccountService: wallet_account_service.ServiceInterface
|
||||||
|
|
||||||
proc newController*[T](
|
proc newController*[T](
|
||||||
delegate: T,
|
delegate: T,
|
||||||
settingService: setting_service.ServiceInterface,
|
settingsService: settings_service.ServiceInterface,
|
||||||
walletAccountService: wallet_account_service.ServiceInterface,
|
walletAccountService: wallet_account_service.ServiceInterface,
|
||||||
): Controller[T] =
|
): Controller[T] =
|
||||||
result = Controller[T]()
|
result = Controller[T]()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.settingService = settingService
|
result.settingsService = settingsService
|
||||||
result.walletAccountService = walletAccountService
|
result.walletAccountService = walletAccountService
|
||||||
|
|
||||||
method delete*[T](self: Controller[T]) =
|
method delete*[T](self: Controller[T]) =
|
||||||
|
@ -26,8 +26,14 @@ method delete*[T](self: Controller[T]) =
|
||||||
method init*[T](self: Controller[T]) =
|
method init*[T](self: Controller[T]) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
method getSetting*[T](self: Controller[T]): setting_service.SettingDto =
|
method getCurrency*[T](self: Controller[T]): string =
|
||||||
return self.settingService.getSetting()
|
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 =
|
method getCurrencyBalance*[T](self: Controller[T]): float64 =
|
||||||
return self.walletAccountService.getCurrencyBalance()
|
return self.walletAccountService.getCurrencyBalance()
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import ../../../../app_service/service/setting/service_interface as setting_service
|
|
||||||
|
|
||||||
type
|
type
|
||||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
## Abstract class for any input/interaction with this module.
|
## Abstract class for any input/interaction with this module.
|
||||||
|
@ -10,7 +8,13 @@ method delete*(self: AccessInterface) {.base.} =
|
||||||
method init*(self: AccessInterface) {.base.} =
|
method init*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getCurrencyBalance*(self: AccessInterface): float64 {.base.} =
|
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/transaction/service as transaction_service
|
||||||
import ../../../../app_service/service/collectible/service as collectible_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/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
|
import io_interface
|
||||||
export io_interface
|
export io_interface
|
||||||
|
@ -44,13 +44,13 @@ proc newModule*[T](
|
||||||
transactionService: transaction_service.Service,
|
transactionService: transaction_service.Service,
|
||||||
collectibleService: collectible_service.ServiceInterface,
|
collectibleService: collectible_service.ServiceInterface,
|
||||||
walletAccountService: wallet_account_service.ServiceInterface,
|
walletAccountService: wallet_account_service.ServiceInterface,
|
||||||
settingService: setting_service.ServiceInterface
|
settingsService: settings_service.ServiceInterface
|
||||||
): Module[T] =
|
): Module[T] =
|
||||||
result = Module[T]()
|
result = Module[T]()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.events = events
|
result.events = events
|
||||||
result.moduleLoaded = false
|
result.moduleLoaded = false
|
||||||
result.controller = newController(result, settingService, walletAccountService)
|
result.controller = newController(result, settingsService, walletAccountService)
|
||||||
result.view = newView(result)
|
result.view = newView(result)
|
||||||
|
|
||||||
result.accountTokensModule = account_tokens_module.newModule[Module[T]](result, events, walletAccountService)
|
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.transactionsModule.load()
|
||||||
|
|
||||||
self.switchAccount(0)
|
self.switchAccount(0)
|
||||||
let setting = self.controller.getSetting()
|
let currency = self.controller.getCurrency()
|
||||||
self.view.updateFromSetting(setting)
|
let signingPhrase = self.controller.getSigningPhrase()
|
||||||
|
let mnemonicBackedUp = self.controller.isMnemonicBackedUp()
|
||||||
|
self.view.setData(currency, signingPhrase, mnemonicBackedUp)
|
||||||
self.setTotalCurrencyBalance()
|
self.setTotalCurrencyBalance()
|
||||||
self.moduleLoaded = true
|
self.moduleLoaded = true
|
||||||
self.delegate.walletSectionDidLoad()
|
self.delegate.walletSectionDidLoad()
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import NimQml
|
import NimQml
|
||||||
|
|
||||||
import ../../../../app_service/service/setting/service as setting_service
|
|
||||||
import ./io_interface
|
import ./io_interface
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
|
@ -65,8 +64,8 @@ QtObject:
|
||||||
self.totalCurrencyBalance = totalCurrencyBalance
|
self.totalCurrencyBalance = totalCurrencyBalance
|
||||||
self.totalCurrencyBalanceChanged()
|
self.totalCurrencyBalanceChanged()
|
||||||
|
|
||||||
proc updateFromSetting*(self: View, setting: setting_service.SettingDto) =
|
proc setData*(self: View, currency, signingPhrase: string, mnemonicBackedUp: bool) =
|
||||||
self.currentCurrency = setting.currency
|
self.currentCurrency = currency
|
||||||
|
self.signingPhrase = signingPhrase
|
||||||
|
self.isMnemonicBackedUp = mnemonicBackedUp
|
||||||
self.currentCurrencyChanged()
|
self.currentCurrencyChanged()
|
||||||
self.signingPhrase = setting.signingPhrase
|
|
||||||
self.isMnemonicBackedUp = setting.isMnemonicBackedUp
|
|
|
@ -1,7 +1,7 @@
|
||||||
import chronicles, sequtils, json
|
import chronicles, sequtils, json
|
||||||
|
|
||||||
import ./service_interface, ./dto
|
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
|
import status/statusgo_backend_new/collectibles as collectibles
|
||||||
|
|
||||||
|
@ -14,21 +14,21 @@ logScope:
|
||||||
|
|
||||||
type
|
type
|
||||||
Service* = ref object of service_interface.ServiceInterface
|
Service* = ref object of service_interface.ServiceInterface
|
||||||
settingService: setting_service.ServiceInterface
|
settingsService: settings_service.ServiceInterface
|
||||||
|
|
||||||
method delete*(self: Service) =
|
method delete*(self: Service) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc newService*(settingService: setting_service.ServiceInterface): Service =
|
proc newService*(settingsService: settings_service.ServiceInterface): Service =
|
||||||
result = Service()
|
result = Service()
|
||||||
result.settingService = settingService
|
result.settingsService = settingsService
|
||||||
|
|
||||||
method init*(self: Service) =
|
method init*(self: Service) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
method getCollections(self: Service, address: string): seq[CollectionDto] =
|
method getCollections(self: Service, address: string): seq[CollectionDto] =
|
||||||
try:
|
try:
|
||||||
let networkId = self.settingService.getSetting().currentNetwork.id
|
let networkId = self.settingsService.getCurrentNetworkId()
|
||||||
let response = collectibles.getOpenseaCollections(networkId, address)
|
let response = collectibles.getOpenseaCollections(networkId, address)
|
||||||
return map(response.result.getElems(), proc(x: JsonNode): CollectionDto = x.toCollectionDto())
|
return map(response.result.getElems(), proc(x: JsonNode): CollectionDto = x.toCollectionDto())
|
||||||
except Exception as e:
|
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] =
|
method getCollectibles(self: Service, address: string, collectionSlug: string): seq[CollectibleDto] =
|
||||||
try:
|
try:
|
||||||
let networkId = self.settingService.getSetting().currentNetwork.id
|
let networkId = self.settingsService.getCurrentNetworkId()
|
||||||
let response = collectibles.getOpenseaAssets(networkId, address, collectionSlug, limit)
|
let response = collectibles.getOpenseaAssets(networkId, address, collectionSlug, limit)
|
||||||
return map(response.result.getElems(), proc(x: JsonNode): CollectibleDto = x.toCollectibleDto())
|
return map(response.result.getElems(), proc(x: JsonNode): CollectibleDto = x.toCollectibleDto())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
@ -4,13 +4,14 @@ import options
|
||||||
import strutils
|
import strutils
|
||||||
include ../../common/json_utils
|
include ../../common/json_utils
|
||||||
import ../dapp_permissions/service as dapp_permissions_service
|
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 ../ens/service as ens_service
|
||||||
import service_interface
|
import service_interface
|
||||||
import status/statusgo_backend_new/permissions as status_go_permissions
|
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/accounts as status_go_accounts
|
||||||
import status/statusgo_backend_new/core as status_go_core
|
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
|
import stew/byteutils
|
||||||
export service_interface
|
export service_interface
|
||||||
|
|
||||||
|
@ -18,6 +19,74 @@ logScope:
|
||||||
topics = "provider-service"
|
topics = "provider-service"
|
||||||
|
|
||||||
const HTTPS_SCHEME* = "https"
|
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
|
type
|
||||||
Service* = ref object of service_interface.ServiceInterface
|
Service* = ref object of service_interface.ServiceInterface
|
||||||
|
@ -39,18 +108,217 @@ proc newService*(dappPermissionsService: dapp_permissions_service.ServiceInterfa
|
||||||
method init*(self: Service) =
|
method init*(self: Service) =
|
||||||
discard
|
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) =
|
if data.payload.rpcMethod == "eth_sendTransaction":
|
||||||
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 =
|
|
||||||
try:
|
try:
|
||||||
return $providerRequest(requestType, message).result
|
let request = data.request.parseJson
|
||||||
except Exception as e:
|
let fromAddress = request["params"][0]["from"].getStr()
|
||||||
let errDescription = e.msg
|
let to = request["params"][0]{"to"}.getStr()
|
||||||
error "error: ", errDescription
|
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 chronicles, json
|
||||||
# import status/statusgo_backend_new/custom_tokens as custom_tokens
|
|
||||||
import json, tables, sugar, sequtils, strutils, atomics, os
|
|
||||||
|
|
||||||
import status/statusgo_backend/settings as status_go_settings
|
import service_interface, ./dto/settings
|
||||||
import status/statusgo_backend/accounts as status_accounts
|
import status/statusgo_backend_new/settings as status_go
|
||||||
from status/types/setting import Setting
|
|
||||||
|
|
||||||
import ./service_interface, ./dto
|
|
||||||
|
|
||||||
import dto/network_details
|
|
||||||
import dto/node_config
|
|
||||||
import dto/upstream_config
|
|
||||||
|
|
||||||
export service_interface
|
export service_interface
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "settings-service"
|
topics = "settings-service"
|
||||||
|
|
||||||
const DEFAULT_NETWORK_NAME = "mainnet_rpc"
|
# Setting keys:
|
||||||
const TELEMETRY_BASE_URL = "https://telemetry.status.im"
|
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
|
type
|
||||||
Service* = ref object of ServiceInterface
|
Service* = ref object of service_interface.ServiceInterface
|
||||||
# profile: Dto
|
settings: SettingsDto
|
||||||
|
|
||||||
method delete*(self: Service) =
|
method delete*(self: Service) =
|
||||||
discard
|
discard
|
||||||
|
@ -32,69 +49,289 @@ proc newService*(): Service =
|
||||||
|
|
||||||
method init*(self: Service) =
|
method init*(self: Service) =
|
||||||
try:
|
try:
|
||||||
echo "init"
|
let response = status_go.getSettings()
|
||||||
|
self.settings = response.result.toSettingsDto()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
let errDesription = e.msg
|
let errDesription = e.msg
|
||||||
error "error: ", errDesription
|
error "error: ", errDesription
|
||||||
return
|
return
|
||||||
|
|
||||||
method getPubKey*(self: Service): string=
|
proc saveSetting(self: Service, attribute: string, value: string | JsonNode | bool | int): bool =
|
||||||
return status_go_settings.getSetting(Setting.PublicKey, "0x0")
|
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 true
|
||||||
return status_go_settings.getSetting(Setting.Networks_CurrentNetwork, DEFAULT_NETWORK_NAME)
|
|
||||||
|
|
||||||
method getAppearance*(self: Service): int =
|
method saveAddress*(self: Service, value: string): bool =
|
||||||
let appearance: int = status_go_settings.getSetting[int](Setting.Appearance, 0)
|
if(self.saveSetting(KEY_ADDRESS, value)):
|
||||||
return appearance
|
self.settings.address = value
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
method getMessagesFromContactsOnly*(self: Service): bool =
|
method getAddress*(self: Service): string =
|
||||||
return status_go_settings.getSetting[bool](Setting.MessagesFromContactsOnly)
|
return self.settings.address
|
||||||
|
|
||||||
method getSendUserStatus*(self: Service): bool =
|
method saveCurrency*(self: Service, value: string): bool =
|
||||||
return status_go_settings.getSetting[bool](Setting.SendUserStatus)
|
if(self.saveSetting(KEY_CURRENCY, value)):
|
||||||
|
self.settings.currency = value
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
method setSendUserStatus*(self: Service, value: bool) =
|
method getCurrency*(self: Service): string =
|
||||||
# this will be done in a proper way in `base_bc`, so far this is just a fix
|
if(self.settings.currency.len == 0):
|
||||||
discard status_go_settings.saveSetting(Setting.SendUserStatus, value)
|
self.settings.currency = DEFAULT_CURRENCY
|
||||||
|
|
||||||
method getCurrentUserStatus*(self: Service): int =
|
return self.settings.currency
|
||||||
let userStatus = status_go_settings.getSetting[JsonNode](Setting.CurrentUserStatus)
|
|
||||||
return userStatus{"statusType"}.getInt()
|
|
||||||
|
|
||||||
method getIdentityImage*(self: Service, address: string): IdentityImage =
|
method saveCurrentNetwork*(self: Service, value: string): bool =
|
||||||
var obj = status_accounts.getIdentityImage(address)
|
if(self.saveSetting(KEY_NETWORKS_CURRENT_NETWORK, value)):
|
||||||
var identityImage = IdentityImage(thumbnail: obj.thumbnail, large: obj.large)
|
self.settings.currentNetwork = value
|
||||||
return identityImage
|
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 =
|
method getDappsAddress*(self: Service): string =
|
||||||
return status_go_settings.getSetting[string](Setting.DappsAddress)
|
return self.settings.dappsAddress
|
||||||
|
|
||||||
method setDappsAddress*(self: Service, address: string): bool =
|
method saveEip1581Address*(self: Service, value: string): bool =
|
||||||
let r = status_go_settings.saveSetting(Setting.DappsAddress, address)
|
if(self.saveSetting(KEY_EIP1581_ADDRESS, value)):
|
||||||
return r.error == ""
|
self.settings.eip1581Address = value
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
method getCurrentNetworkDetails*(self: Service): NetworkDetails =
|
method getEip1581Address*(self: Service): string =
|
||||||
let currNetwork = getSetting[string](Setting.Networks_CurrentNetwork, DEFAULT_NETWORK_NAME)
|
return self.settings.eip1581Address
|
||||||
let networks = getSetting[seq[NetworkDetails]](Setting.Networks_Networks)
|
|
||||||
for n in networks:
|
method saveInstallationId*(self: Service, value: string): bool =
|
||||||
if n.id == currNetwork:
|
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
|
return n
|
||||||
|
|
||||||
method enableDeveloperFeatures*(self: Service) =
|
# we should never be here
|
||||||
discard status_go_settings.saveSetting(Setting.TelemetryServerUrl, TELEMETRY_BASE_URL)
|
error "error: current network is not among available networks"
|
||||||
discard status_go_settings.saveSetting(Setting.AutoMessageEnabled, true)
|
|
||||||
var nodeConfig = status_go_settings.getNodeConfig()
|
method getCurrentNetworkId*(self: Service): int =
|
||||||
nodeConfig["LogLevel"] = newJString($LogLevel.DEBUG)
|
self.getCurrentNetworkDetails().config.networkId
|
||||||
discard status_go_settings.saveSetting(Setting.NodeConfig, nodeConfig)
|
|
||||||
quit(QuitSuccess) # quits the app TODO: change this to logout instead when supported
|
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) =
|
method toggleTelemetry*(self: Service) =
|
||||||
let telemetryServerUrl = status_go_settings.getSetting[string](Setting.TelemetryServerUrl)
|
let telemetryServerUrl = status_go_settings.getSetting[string](Setting.TelemetryServerUrl)
|
||||||
var newValue = ""
|
var newValue = ""
|
||||||
if telemetryServerUrl == "":
|
if telemetryServerUrl == "":
|
||||||
newValue = TELEMETRY_BASE_URL
|
newValue = "https://telemetry.status.im"
|
||||||
|
|
||||||
discard status_go_settings.saveSetting(Setting.TelemetryServerUrl, newValue)
|
discard status_go_settings.saveSetting(Setting.TelemetryServerUrl, newValue)
|
||||||
|
|
||||||
|
@ -116,7 +353,16 @@ method toggleDebug*(self: Service) =
|
||||||
else:
|
else:
|
||||||
nodeConfig["LogLevel"] = newJString($LogLevel.INFO)
|
nodeConfig["LogLevel"] = newJString($LogLevel.INFO)
|
||||||
discard status_go_settings.saveSetting(Setting.NodeConfig, nodeConfig)
|
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 =
|
method isDebugEnabled*(self: Service): bool =
|
||||||
let nodeConfig = status_go_settings.getNodeConfig()
|
let nodeConfig = status_go_settings.getNodeConfig()
|
||||||
return nodeConfig["LogLevel"].getStr() != $LogLevel.INFO
|
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/settings as settings_dto
|
||||||
import dto/network_details
|
|
||||||
import dto/node_config
|
|
||||||
import dto/upstream_config
|
|
||||||
|
|
||||||
export dto
|
export settings_dto
|
||||||
export network_details
|
|
||||||
export node_config
|
# Default values:
|
||||||
export upstream_config
|
const DEFAULT_CURRENT_NETWORK* = "mainnet_rpc"
|
||||||
|
const DEFAULT_CURRENCY* = "usd"
|
||||||
|
const DEFAULT_TELEMETRY_SERVER_URL* = "https://telemetry.status.im"
|
||||||
|
|
||||||
type
|
type
|
||||||
ServiceInterface* {.pure inheritable.} = ref object of RootObj
|
ServiceInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
@ -18,43 +17,106 @@ method delete*(self: ServiceInterface) {.base.} =
|
||||||
method init*(self: ServiceInterface) {.base.} =
|
method init*(self: ServiceInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getNetwork*(self: ServiceInterface): string {.base.} =
|
method getAddress*(self: ServiceInterface): string {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getMessagesFromContactsOnly*(self: ServiceInterface): bool {.base.} =
|
method getCurrency*(self: ServiceInterface): string {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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")
|
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")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getCurrentUserStatus*(self: ServiceInterface): int {.base.} =
|
method saveDappsAddress*(self: ServiceInterface, value: string): bool {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
|
||||||
|
|
||||||
method getIdentityImage*(self: ServiceInterface, address: string): IdentityImage {.base.} =
|
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getDappsAddress*(self: ServiceInterface): string {.base.} =
|
method getDappsAddress*(self: ServiceInterface): string {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getCurrentNetworkDetails*(self: ServiceInterface): NetworkDetails {.base.} =
|
method getEip1581Address*(self: ServiceInterface): string {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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")
|
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")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method toggleAutoMessage*(self: ServiceInterface) {.base.} =
|
method toggleAutoMessage*(self: ServiceInterface) {.base.} =
|
||||||
|
@ -66,8 +128,77 @@ method isAutoMessageEnabled*(self: ServiceInterface): bool {.base.} =
|
||||||
method toggleDebug*(self: ServiceInterface) {.base.} =
|
method toggleDebug*(self: ServiceInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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")
|
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")
|
raise newException(ValueError, "No implementation available")
|
|
@ -4,8 +4,7 @@ from sugar import `=>`
|
||||||
import web3/ethtypes
|
import web3/ethtypes
|
||||||
from web3/conversions import `$`
|
from web3/conversions import `$`
|
||||||
import status/statusgo_backend_new/custom_tokens as custom_tokens
|
import status/statusgo_backend_new/custom_tokens as custom_tokens
|
||||||
import ../setting/service as setting_service
|
import ../settings/service_interface as settings_service
|
||||||
import ../settings/service as settings_service
|
|
||||||
import ../../../app/core/tasks/[qt, threadpool]
|
import ../../../app/core/tasks/[qt, threadpool]
|
||||||
import ./dto, ./static_token
|
import ./dto, ./static_token
|
||||||
|
|
||||||
|
@ -39,8 +38,7 @@ QtObject:
|
||||||
type Service* = ref object of QObject
|
type Service* = ref object of QObject
|
||||||
events: EventEmitter
|
events: EventEmitter
|
||||||
threadpool: ThreadPool
|
threadpool: ThreadPool
|
||||||
settingService: setting_service.Service
|
settingsService: settings_service.ServiceInterface
|
||||||
settingsService: settings_service.Service
|
|
||||||
tokens: seq[TokenDto]
|
tokens: seq[TokenDto]
|
||||||
|
|
||||||
proc delete*(self: Service) =
|
proc delete*(self: Service) =
|
||||||
|
@ -49,21 +47,19 @@ QtObject:
|
||||||
proc newService*(
|
proc newService*(
|
||||||
events: EventEmitter,
|
events: EventEmitter,
|
||||||
threadpool: ThreadPool,
|
threadpool: ThreadPool,
|
||||||
settingService: setting_service.Service,
|
settingsService: settings_service.ServiceInterface
|
||||||
settingsService: settings_service.Service
|
|
||||||
): Service =
|
): Service =
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
result.QObject.setup
|
result.QObject.setup
|
||||||
result.events = events
|
result.events = events
|
||||||
result.threadpool = threadpool
|
result.threadpool = threadpool
|
||||||
result.settingService = settingService
|
|
||||||
result.settingsService = settingsService
|
result.settingsService = settingsService
|
||||||
result.tokens = @[]
|
result.tokens = @[]
|
||||||
|
|
||||||
proc getDefaultVisibleSymbols(self: Service): seq[string] =
|
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"]
|
return @["SNT"]
|
||||||
|
|
||||||
if networkSlug == "testnet_rpc" or networkSlug == "rinkeby_rpc":
|
if networkSlug == "testnet_rpc" or networkSlug == "rinkeby_rpc":
|
||||||
|
@ -74,7 +70,7 @@ QtObject:
|
||||||
|
|
||||||
proc init*(self: Service) =
|
proc init*(self: Service) =
|
||||||
try:
|
try:
|
||||||
var activeTokenSymbols = self.settingService.getSetting().activeTokenSymbols
|
var activeTokenSymbols = self.settingsService.getWalletVisibleTokens()
|
||||||
if activeTokenSymbols.len == 0:
|
if activeTokenSymbols.len == 0:
|
||||||
activeTokenSymbols = self.getDefaultVisibleSymbols()
|
activeTokenSymbols = self.getDefaultVisibleSymbols()
|
||||||
|
|
||||||
|
@ -89,7 +85,7 @@ QtObject:
|
||||||
static_tokens,
|
static_tokens,
|
||||||
map(response.result.getElems(), proc(x: JsonNode): TokenDto = x.toTokenDto(activeTokenSymbols))
|
map(response.result.getElems(), proc(x: JsonNode): TokenDto = x.toTokenDto(activeTokenSymbols))
|
||||||
).filter(
|
).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:
|
except Exception as e:
|
||||||
|
@ -104,7 +100,7 @@ QtObject:
|
||||||
custom_tokens.addCustomToken(address, name, symbol, decimals, "")
|
custom_tokens.addCustomToken(address, name, symbol, decimals, "")
|
||||||
let token = newDto(
|
let token = newDto(
|
||||||
name,
|
name,
|
||||||
self.settingService.getSetting().currentNetwork.id,
|
self.settingsService.getCurrentNetworkId(),
|
||||||
fromHex(Address, address),
|
fromHex(Address, address),
|
||||||
symbol,
|
symbol,
|
||||||
decimals,
|
decimals,
|
||||||
|
@ -123,7 +119,7 @@ QtObject:
|
||||||
break
|
break
|
||||||
|
|
||||||
let visibleSymbols = self.tokens.filter(t => t.isVisible).map(t => t.symbol)
|
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))
|
self.events.emit("token/visibilityToggled", VisibilityToggled(token: tokenChanged))
|
||||||
|
|
||||||
proc removeCustomToken*(self: Service, address: string) =
|
proc removeCustomToken*(self: Service, address: string) =
|
||||||
|
@ -145,7 +141,7 @@ QtObject:
|
||||||
))
|
))
|
||||||
|
|
||||||
proc getTokenDetails*(self: Service, address: string) =
|
proc getTokenDetails*(self: Service, address: string) =
|
||||||
let chainId = self.settingsService.getCurrentNetworkDetails().config.networkId
|
let chainId = self.settingsService.getCurrentNetworkId()
|
||||||
let arg = GetTokenDetailsTaskArg(
|
let arg = GetTokenDetailsTaskArg(
|
||||||
tptr: cast[ByteAddress](getTokenDetailsTask),
|
tptr: cast[ByteAddress](getTokenDetailsTask),
|
||||||
vptr: cast[ByteAddress](self.vptr),
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
|
|
@ -2,14 +2,13 @@ import Tables, json, sequtils, sugar, chronicles, strformat, stint, httpclient,
|
||||||
import web3/[ethtypes, conversions]
|
import web3/[ethtypes, conversions]
|
||||||
import eventemitter
|
import eventemitter
|
||||||
|
|
||||||
import ../setting/service as setting_service
|
import ../settings/service_interface as settings_service
|
||||||
import ../token/service as token_service
|
import ../token/service as token_service
|
||||||
import ../../common/account_constants
|
import ../../common/account_constants
|
||||||
import ../../../constants
|
import ../../../constants
|
||||||
|
|
||||||
import ./service_interface, ./dto
|
import ./service_interface, ./dto
|
||||||
import status/statusgo_backend_new/accounts as status_go_accounts
|
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
|
import status/statusgo_backend_new/eth as status_go_eth
|
||||||
|
|
||||||
export service_interface
|
export service_interface
|
||||||
|
@ -62,6 +61,20 @@ proc fetchAccounts(): seq[WalletAccountDto] =
|
||||||
x => x.toWalletAccountDto()
|
x => x.toWalletAccountDto()
|
||||||
).filter(a => not a.isChat)
|
).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 =
|
proc fetchEthBalance(accountAddress: string): float64 =
|
||||||
let key = "0x0" & accountAddress
|
let key = "0x0" & accountAddress
|
||||||
if balanceCache.hasKey(key):
|
if balanceCache.hasKey(key):
|
||||||
|
@ -88,7 +101,7 @@ type WalletAccountUpdated = ref object of Args
|
||||||
type
|
type
|
||||||
Service* = ref object of service_interface.ServiceInterface
|
Service* = ref object of service_interface.ServiceInterface
|
||||||
events: EventEmitter
|
events: EventEmitter
|
||||||
settingService: setting_service.Service
|
settingsService: settings_service.ServiceInterface
|
||||||
tokenService: token_service.Service
|
tokenService: token_service.Service
|
||||||
accounts: OrderedTable[string, WalletAccountDto]
|
accounts: OrderedTable[string, WalletAccountDto]
|
||||||
|
|
||||||
|
@ -96,11 +109,11 @@ method delete*(self: Service) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc newService*(
|
proc newService*(
|
||||||
events: EventEmitter, settingService: setting_service.Service, tokenService: token_service.Service
|
events: EventEmitter, settingsService: settings_service.ServiceInterface, tokenService: token_service.Service):
|
||||||
): Service =
|
Service =
|
||||||
result = Service()
|
result = Service()
|
||||||
result.events = events
|
result.events = events
|
||||||
result.settingService = settingService
|
result.settingsService = settingsService
|
||||||
result.tokenService = tokenService
|
result.tokenService = tokenService
|
||||||
result.accounts = initOrderedTable[string, WalletAccountDto]()
|
result.accounts = initOrderedTable[string, WalletAccountDto]()
|
||||||
|
|
||||||
|
@ -110,8 +123,7 @@ method getVisibleTokens(self: Service): seq[TokenDto] =
|
||||||
method buildTokens(
|
method buildTokens(
|
||||||
self: Service,
|
self: Service,
|
||||||
account: WalletAccountDto,
|
account: WalletAccountDto,
|
||||||
prices: Table[string, float64],
|
prices: Table[string, float64]
|
||||||
balances: JsonNode,
|
|
||||||
): seq[WalletTokenDto] =
|
): seq[WalletTokenDto] =
|
||||||
let balance = fetchEthBalance(account.address)
|
let balance = fetchEthBalance(account.address)
|
||||||
result = @[WalletTokenDto(
|
result = @[WalletTokenDto(
|
||||||
|
@ -127,7 +139,7 @@ method buildTokens(
|
||||||
)]
|
)]
|
||||||
|
|
||||||
for token in self.getVisibleTokens():
|
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(
|
result.add(
|
||||||
WalletTokenDto(
|
WalletTokenDto(
|
||||||
name: token.name,
|
name: token.name,
|
||||||
|
@ -143,26 +155,18 @@ method buildTokens(
|
||||||
)
|
)
|
||||||
|
|
||||||
method fetchPrices(self: Service): Table[string, float64] =
|
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
|
var prices = {"ETH": fetchPrice("ETH", currency)}.toTable
|
||||||
for token in self.getVisibleTokens():
|
for token in self.getVisibleTokens():
|
||||||
prices[token.symbol] = fetchPrice(token.symbol, currency)
|
prices[token.symbol] = fetchPrice(token.symbol, currency)
|
||||||
|
|
||||||
return prices
|
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) =
|
method refreshBalances(self: Service) =
|
||||||
let prices = self.fetchPrices()
|
let prices = self.fetchPrices()
|
||||||
let accounts = toSeq(self.accounts.keys)
|
|
||||||
let balances = self.fetchBalances(accounts)
|
|
||||||
|
|
||||||
for account in toSeq(self.accounts.values):
|
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) =
|
method init*(self: Service) =
|
||||||
try:
|
try:
|
||||||
|
@ -189,7 +193,33 @@ method getWalletAccount*(self: Service, accountIndex: int): WalletAccountDto =
|
||||||
method getCurrencyBalance*(self: Service): float64 =
|
method getCurrencyBalance*(self: Service): float64 =
|
||||||
return self.getWalletAccounts().map(a => a.getCurrencyBalance()).foldl(a + b, 0.0)
|
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 accounts = fetchAccounts()
|
||||||
let prices = self.fetchPrices()
|
let prices = self.fetchPrices()
|
||||||
|
|
||||||
|
@ -199,64 +229,92 @@ method addNewAccountToLocalStore(self: Service) =
|
||||||
newAccount = account
|
newAccount = account
|
||||||
break
|
break
|
||||||
|
|
||||||
let balances = self.fetchBalances(@[newAccount.address])
|
newAccount.tokens = self.buildTokens(newAccount, prices)
|
||||||
newAccount.tokens = self.buildTokens(newAccount, prices, balances{newAccount.address})
|
|
||||||
self.accounts[newAccount.address] = newAccount
|
self.accounts[newAccount.address] = newAccount
|
||||||
self.events.emit("walletAccount/accountSaved", AccountSaved(account: 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 =
|
method generateNewAccount*(self: Service, password: string, accountName: string, color: string): string =
|
||||||
try:
|
let
|
||||||
discard status_go_accounts.generateAccount(
|
walletRootAddress = self.settingsService.getWalletRootAddress()
|
||||||
password,
|
walletIndex = self.settingsService.getLatestDerivedPath() + 1
|
||||||
accountName,
|
defaultAccount = self.getDefaultAccount()
|
||||||
color,
|
isPasswordOk = status_go_accounts.verifyAccountPassword(defaultAccount, password, KEYSTOREDIR)
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
return fmt"Error generating new account: {e.msg}"
|
|
||||||
|
|
||||||
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 ""
|
return ""
|
||||||
|
|
||||||
method addAccountsFromPrivateKey*(self: Service, privateKey: string, password: string, accountName: string, color: string): string =
|
method addAccountsFromPrivateKey*(self: Service, privateKey: string, password: string, accountName: string, color: string): string =
|
||||||
try:
|
let
|
||||||
discard status_go_accounts.addAccountWithPrivateKey(
|
accountResponse = status_go_accounts.multiAccountImportPrivateKey(privateKey)
|
||||||
privateKey,
|
defaultAccount = self.getDefaultAccount()
|
||||||
password,
|
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,
|
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,
|
password,
|
||||||
accountName,
|
|
||||||
color,
|
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()
|
method addAccountsFromSeed*(self: Service, seedPhrase: string, password: string, accountName: string, color: string): string =
|
||||||
return ""
|
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 =
|
method addWatchOnlyAccount*(self: Service, address: string, accountName: string, color: string): string =
|
||||||
try:
|
return self.saveAccount(address, accountName, "", color, status_go_accounts.WATCH, false)
|
||||||
discard status_go_accounts.addAccountWatch(
|
|
||||||
address,
|
|
||||||
accountName,
|
|
||||||
color,
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
return fmt"Error adding account with mnemonic: {e.msg}"
|
|
||||||
|
|
||||||
self.addNewAccountToLocalStore()
|
|
||||||
return ""
|
|
||||||
|
|
||||||
method deleteAccount*(self: Service, address: string) =
|
method deleteAccount*(self: Service, address: string) =
|
||||||
discard status_go_accounts.deleteAccount(address)
|
discard status_go_accounts.deleteAccount(address)
|
||||||
|
@ -266,7 +324,7 @@ method deleteAccount*(self: Service, address: string) =
|
||||||
self.events.emit("walletAccount/accountDeleted", AccountDeleted(account: accountDeleted))
|
self.events.emit("walletAccount/accountDeleted", AccountDeleted(account: accountDeleted))
|
||||||
|
|
||||||
method updateCurrency*(self: Service, newCurrency: string) =
|
method updateCurrency*(self: Service, newCurrency: string) =
|
||||||
discard self.settingService.saveSetting("currency", newCurrency)
|
discard self.settingsService.saveCurrency(newCurrency)
|
||||||
self.refreshBalances()
|
self.refreshBalances()
|
||||||
self.events.emit("walletAccount/currencyUpdated", CurrencyUpdated())
|
self.events.emit("walletAccount/currencyUpdated", CurrencyUpdated())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue