feat(@wallet): toggle network
This commit is contained in:
parent
fc24f16525
commit
92bc1fdab1
|
@ -128,7 +128,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
|||
result.keychainService = keychain_service.newService(statusFoundation.events)
|
||||
result.ethService = eth_service.newService()
|
||||
result.accountsService = accounts_service.newService(statusFoundation.fleetConfiguration)
|
||||
result.networkService = network_service.newService(result.settingsService)
|
||||
result.networkService = network_service.newService(statusFoundation.events, result.settingsService)
|
||||
result.contactsService = contacts_service.newService(
|
||||
statusFoundation.events, statusFoundation.threadpool, result.settingsService
|
||||
)
|
||||
|
@ -304,10 +304,8 @@ proc load(self: AppController) =
|
|||
self.tokenService.init()
|
||||
self.dappPermissionsService.init()
|
||||
self.providerService.init()
|
||||
self.walletAccountService.init()
|
||||
self.transactionService.init()
|
||||
self.stickersService.init()
|
||||
self.networkService.init()
|
||||
self.activityCenterService.init()
|
||||
self.savedAddressService.init()
|
||||
self.aboutService.init()
|
||||
|
@ -321,6 +319,9 @@ proc load(self: AppController) =
|
|||
singletonInstance.engine.setRootContextProperty("localAccountSensitiveSettings", self.localAccountSensitiveSettingsVariant)
|
||||
singletonInstance.engine.setRootContextProperty("globalUtils", self.globalUtilsVariant)
|
||||
|
||||
self.networkService.init()
|
||||
self.walletAccountService.init()
|
||||
|
||||
# other global instances
|
||||
self.buildAndRegisterLocalAccountSensitiveSettings()
|
||||
self.buildAndRegisterUserProfile()
|
||||
|
|
|
@ -14,7 +14,7 @@ include ./private_interfaces/module_app_search_delegate_interface
|
|||
include ./private_interfaces/module_browser_section_delegate_interface
|
||||
include ./private_interfaces/module_communities_section_delegate_interface
|
||||
include ./private_interfaces/module_node_section_delegate_interface
|
||||
|
||||
include ./private_interfaces/module_networks_delegate_interface
|
||||
|
||||
# This way (using concepts) is used only for the modules managed by AppController
|
||||
type
|
||||
|
|
|
@ -19,6 +19,7 @@ import stickers/module as stickers_module
|
|||
import activity_center/module as activity_center_module
|
||||
import communities/module as communities_module
|
||||
import node_section/module as node_section_module
|
||||
import networks/module as networks_module
|
||||
|
||||
import ../../../app_service/service/keychain/service as keychain_service
|
||||
import ../../../app_service/service/chat/service as chat_service
|
||||
|
@ -70,6 +71,7 @@ type
|
|||
communitiesModule: communities_module.AccessInterface
|
||||
appSearchModule: app_search_module.AccessInterface
|
||||
nodeSectionModule: node_section_module.AccessInterface
|
||||
networksModule: networks_module.AccessInterface
|
||||
moduleLoaded: bool
|
||||
|
||||
# Forward declaration
|
||||
|
@ -141,7 +143,7 @@ proc newModule*[T](
|
|||
result.profileSectionModule = profile_section_module.newModule(
|
||||
result, events, accountsService, settingsService,
|
||||
profileService, contactsService, aboutService, languageService, privacyService, nodeConfigurationService,
|
||||
devicesService, mailserversService, chatService, ensService, walletAccountService, networkService,
|
||||
devicesService, mailserversService, chatService, ensService, walletAccountService,
|
||||
)
|
||||
result.stickersModule = stickers_module.newModule(result, events, stickersService)
|
||||
result.activityCenterModule = activity_center_module.newModule(result, events, activityCenterService, contactsService,
|
||||
|
@ -150,6 +152,7 @@ proc newModule*[T](
|
|||
result.appSearchModule = app_search_module.newModule(result, events, contactsService, chatService, communityService,
|
||||
messageService)
|
||||
result.nodeSectionModule = node_section_module.newModule(result, events, settingsService, nodeService, nodeConfigurationService)
|
||||
result.networksModule = networks_module.newModule(result, events, networkService, walletAccountService)
|
||||
|
||||
method delete*[T](self: Module[T]) =
|
||||
self.chatSectionModule.delete
|
||||
|
@ -164,6 +167,7 @@ method delete*[T](self: Module[T]) =
|
|||
self.browserSectionModule.delete
|
||||
self.appSearchModule.delete
|
||||
self.nodeSectionModule.delete
|
||||
self.networksModule.delete
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
self.controller.delete
|
||||
|
@ -342,10 +346,12 @@ method load*[T](
|
|||
self.chatSectionModule.load(events, settingsService, contactsService, chatService, communityService, messageService, gifService, mailserversService)
|
||||
for cModule in self.communitySectionsModule.values:
|
||||
cModule.load(events, settingsService, contactsService, chatService, communityService, messageService, gifService, mailserversService)
|
||||
|
||||
self.browserSectionModule.load()
|
||||
# self.nodeManagementSectionModule.load()
|
||||
self.profileSectionModule.load()
|
||||
self.stickersModule.load()
|
||||
self.networksModule.load()
|
||||
self.activityCenterModule.load()
|
||||
self.communitiesModule.load()
|
||||
self.appSearchModule.load()
|
||||
|
@ -391,6 +397,9 @@ proc checkIfModuleDidLoad [T](self: Module[T]) =
|
|||
if(not self.appSearchModule.isLoaded()):
|
||||
return
|
||||
|
||||
if(not self.networksModule.isLoaded()):
|
||||
return
|
||||
|
||||
self.moduleLoaded = true
|
||||
self.delegate.mainDidLoad()
|
||||
|
||||
|
@ -424,6 +433,9 @@ proc profileSectionDidLoad*[T](self: Module[T]) =
|
|||
method nodeSectionDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method networksModuleDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method viewDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import ./controller_interface
|
||||
import ../../../core/eventemitter
|
||||
import ../../../../app_service/service/network/service as network_service
|
||||
import ../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import ./io_interface
|
||||
|
||||
export controller_interface
|
||||
|
||||
type
|
||||
Controller* = ref object of controller_interface.AccessInterface
|
||||
delegate: io_interface.AccessInterface
|
||||
events: EventEmitter
|
||||
networkService: network_service.Service
|
||||
walletAccountService: wallet_account_service.Service
|
||||
|
||||
proc newController*(
|
||||
delegate: io_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
networkService: network_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
): Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
result.events = events
|
||||
result.networkService = networkService
|
||||
result.walletAccountService = walletAccountService
|
||||
|
||||
method delete*(self: Controller) =
|
||||
discard
|
||||
|
||||
method init*(self: Controller) =
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e: Args):
|
||||
self.delegate.refreshNetworks()
|
||||
|
||||
method getNetworks*(self: Controller): seq[NetworkDto] =
|
||||
return self.networkService.getNetworks()
|
||||
|
||||
method toggleNetwork*(self: Controller, chainId: int) =
|
||||
self.walletAccountService.toggleNetworkEnabled(chainId)
|
|
@ -1,4 +1,4 @@
|
|||
import ../../../../../../app_service/service/network/dto
|
||||
import ../../../../app_service/service/network/dto
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
|
@ -11,4 +11,7 @@ method init*(self: AccessInterface) {.base.} =
|
|||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getNetworks*(self: AccessInterface): seq[NetworkDto] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method toggleNetwork*(self: AccessInterface, chainId: int) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -19,6 +19,11 @@ method isLoaded*(self: AccessInterface): bool {.base.} =
|
|||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method toggleNetwork*(self: AccessInterface, chainId: int) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method refreshNetworks*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
|
@ -11,6 +11,7 @@ type
|
|||
nativeCurrencyName: string
|
||||
nativeCurrencySymbol: string
|
||||
isTest: bool
|
||||
isEnabled: bool
|
||||
|
||||
proc initItem*(
|
||||
chainId: int,
|
||||
|
@ -21,7 +22,8 @@ proc initItem*(
|
|||
blockExplorerURL: string,
|
||||
nativeCurrencyName: string,
|
||||
nativeCurrencySymbol: string,
|
||||
isTest: bool
|
||||
isTest: bool,
|
||||
isEnabled: bool,
|
||||
): Item =
|
||||
result.chainId = chainId
|
||||
result.nativeCurrencyDecimals = nativeCurrencyDecimals
|
||||
|
@ -32,6 +34,7 @@ proc initItem*(
|
|||
result.nativeCurrencyName = nativeCurrencyName
|
||||
result.nativeCurrencySymbol = nativeCurrencySymbol
|
||||
result.isTest = isTest
|
||||
result.isEnabled = isEnabled
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = fmt"""NetworkItem(
|
||||
|
@ -44,6 +47,7 @@ proc `$`*(self: Item): string =
|
|||
nativeCurrencyName:{self.nativeCurrencyName},
|
||||
nativeCurrencySymbol:{self.nativeCurrencySymbol},
|
||||
isTest:{self.isTest}
|
||||
isEnabled:{self.isEnabled}
|
||||
]"""
|
||||
|
||||
proc getChainId*(self: Item): int =
|
||||
|
@ -71,4 +75,7 @@ proc getNativeCurrencySymbol*(self: Item): string =
|
|||
return self.nativeCurrencySymbol
|
||||
|
||||
proc getIsTest*(self: Item): bool =
|
||||
return self.isTest
|
||||
return self.isTest
|
||||
|
||||
proc getIsEnabled*(self: Item): bool =
|
||||
return self.isEnabled
|
|
@ -13,6 +13,7 @@ type
|
|||
NativeCurrencyName
|
||||
NativeCurrencySymbol
|
||||
IsTest
|
||||
IsEnabled
|
||||
|
||||
QtObject:
|
||||
type
|
||||
|
@ -57,6 +58,7 @@ QtObject:
|
|||
ModelRole.NativeCurrencyName.int:"nativeCurrencyName",
|
||||
ModelRole.NativeCurrencySymbol.int:"nativeCurrencySymbol",
|
||||
ModelRole.IsTest.int:"isTest",
|
||||
ModelRole.IsEnabled.int:"isEnabled",
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
|
@ -88,6 +90,8 @@ QtObject:
|
|||
result = newQVariant(item.getNativeCurrencySymbol())
|
||||
of ModelRole.IsTest:
|
||||
result = newQVariant(item.getIsTest())
|
||||
of ModelRole.IsEnabled:
|
||||
result = newQVariant(item.getIsEnabled())
|
||||
|
||||
proc setItems*(self: Model, items: seq[Item]) =
|
||||
self.beginResetModel()
|
|
@ -1,9 +1,10 @@
|
|||
import NimQml
|
||||
import ../io_interface as delegate_interface
|
||||
import io_interface, view, controller
|
||||
import ../../../../../global/global_singleton
|
||||
import ../../../../../core/eventemitter
|
||||
import ../../../../../../app_service/service/network/service as network_service
|
||||
import ../../../global/global_singleton
|
||||
import ../../../core/eventemitter
|
||||
import ../../../../app_service/service/network/service as network_service
|
||||
import ../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
|
||||
export io_interface
|
||||
|
||||
|
@ -19,25 +20,30 @@ proc newModule*(
|
|||
delegate: delegate_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
networkService: networkService.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController(result, events, networkService)
|
||||
result.controller = controller.newController(result, events, networkService, walletAccountService)
|
||||
result.moduleLoaded = false
|
||||
|
||||
singletonInstance.engine.setRootContextProperty("profileSectionWalletNetworkModule", result.viewVariant)
|
||||
singletonInstance.engine.setRootContextProperty("networksModule", result.viewVariant)
|
||||
|
||||
method delete*(self: Module) =
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
self.controller.delete
|
||||
|
||||
method load*(self: Module) =
|
||||
method refreshNetworks*(self: Module) =
|
||||
let networks = self.controller.getNetworks()
|
||||
self.view.load(networks)
|
||||
|
||||
method load*(self: Module) =
|
||||
self.controller.init()
|
||||
self.refreshNetworks()
|
||||
|
||||
method isLoaded*(self: Module): bool =
|
||||
return self.moduleLoaded
|
||||
|
||||
|
@ -46,4 +52,7 @@ proc checkIfModuleDidLoad(self: Module) =
|
|||
self.delegate.networksModuleDidLoad()
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
self.checkIfModuleDidLoad()
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method toggleNetwork*(self: Module, chainId: int) =
|
||||
self.controller.toggleNetwork(chainId)
|
|
@ -1,6 +1,6 @@
|
|||
import NimQml, sequtils, sugar
|
||||
|
||||
import ../../../../../../app_service/service/network/dto
|
||||
import ../../../../app_service/service/network/dto
|
||||
import ./io_interface
|
||||
import ./model
|
||||
import ./item
|
||||
|
@ -9,6 +9,7 @@ QtObject:
|
|||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
enabled: Model
|
||||
layer1: Model
|
||||
layer2: Model
|
||||
test: Model
|
||||
|
@ -25,6 +26,7 @@ QtObject:
|
|||
result.layer1 = newModel()
|
||||
result.layer2 = newModel()
|
||||
result.test = newModel()
|
||||
result.enabled = newModel()
|
||||
result.setup()
|
||||
|
||||
proc layer1Changed*(self: View) {.signal.}
|
||||
|
@ -54,6 +56,15 @@ QtObject:
|
|||
read = getTest
|
||||
notify = testChanged
|
||||
|
||||
proc enabledChanged*(self: View) {.signal.}
|
||||
|
||||
proc getEnabled(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.enabled)
|
||||
|
||||
QtProperty[QVariant] enabled:
|
||||
read = getEnabled
|
||||
notify = enabledChanged
|
||||
|
||||
proc load*(self: View, networks: seq[NetworkDto]) =
|
||||
let items = networks.map(n => initItem(
|
||||
n.chainId,
|
||||
|
@ -64,10 +75,19 @@ QtObject:
|
|||
n.blockExplorerURL,
|
||||
n.nativeCurrencyName,
|
||||
n.nativeCurrencySymbol,
|
||||
n.isTest
|
||||
n.isTest,
|
||||
n.enabled,
|
||||
))
|
||||
self.layer1.setItems(items.filter(i => i.getLayer() == 1 and not i.getIsTest()))
|
||||
self.layer2.setItems(items.filter(i => i.getLayer() == 2 and not i.getIsTest()))
|
||||
self.test.setItems(items.filter(i => i.getIsTest()))
|
||||
self.enabled.setItems(items.filter(i => i.getIsEnabled()))
|
||||
|
||||
self.delegate.viewDidLoad()
|
||||
self.layer1Changed()
|
||||
self.layer2Changed()
|
||||
self.testChanged()
|
||||
|
||||
self.delegate.viewDidLoad()
|
||||
|
||||
proc toggleNetwork*(self: View, chainId: int) {.slot.} =
|
||||
self.delegate.toggleNetwork(chainId)
|
|
@ -0,0 +1,2 @@
|
|||
method networksModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -80,9 +80,6 @@ method ensUsernamesModuleDidLoad*(self: AccessInterface) {.base.} =
|
|||
method getEnsUsernamesModule*(self: AccessInterface): QVariant {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method walletModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
|
|
|
@ -15,7 +15,6 @@ import ../../../../app_service/service/mailservers/service as mailservers_servic
|
|||
import ../../../../app_service/service/chat/service as chat_service
|
||||
import ../../../../app_service/service/ens/service as ens_service
|
||||
import ../../../../app_service/service/wallet_account/service_interface as wallet_account_service
|
||||
import ../../../../app_service/service/network/service as network_service
|
||||
|
||||
import ./profile/module as profile_module
|
||||
import ./contacts/module as contacts_module
|
||||
|
@ -27,7 +26,6 @@ import ./devices/module as devices_module
|
|||
import ./sync/module as sync_module
|
||||
import ./notifications/module as notifications_module
|
||||
import ./ens_usernames/module as ens_usernames_module
|
||||
import ./wallet/module as wallet_module
|
||||
|
||||
export io_interface
|
||||
|
||||
|
@ -49,7 +47,6 @@ type
|
|||
syncModule: sync_module.AccessInterface
|
||||
notificationsModule: notifications_module.AccessInterface
|
||||
ensUsernamesModule: ens_usernames_module.AccessInterface
|
||||
walletModule: wallet_module.AccessInterface
|
||||
|
||||
proc newModule*[T](delegate: T,
|
||||
events: EventEmitter,
|
||||
|
@ -66,7 +63,6 @@ proc newModule*[T](delegate: T,
|
|||
chatService: chat_service.Service,
|
||||
ensService: ens_service.Service,
|
||||
walletAccountService: wallet_account_service.ServiceInterface,
|
||||
networkService: network_service.Service,
|
||||
): Module[T] =
|
||||
result = Module[T]()
|
||||
result.delegate = delegate
|
||||
|
@ -87,7 +83,6 @@ proc newModule*[T](delegate: T,
|
|||
result.ensUsernamesModule = ens_usernames_module.newModule(
|
||||
result, events, settingsService, ensService, walletAccountService
|
||||
)
|
||||
result.walletModule = wallet_module.newModule(result, events, networkService)
|
||||
|
||||
singletonInstance.engine.setRootContextProperty("profileSectionModule", result.viewVariant)
|
||||
|
||||
|
@ -100,7 +95,6 @@ method delete*[T](self: Module[T]) =
|
|||
self.advancedModule.delete
|
||||
self.devicesModule.delete
|
||||
self.syncModule.delete
|
||||
self.walletModule.delete
|
||||
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
|
@ -118,7 +112,6 @@ method load*[T](self: Module[T]) =
|
|||
self.syncModule.load()
|
||||
self.notificationsModule.load()
|
||||
self.ensUsernamesModule.load()
|
||||
self.walletModule.load()
|
||||
|
||||
method isLoaded*[T](self: Module[T]): bool =
|
||||
return self.moduleLoaded
|
||||
|
@ -154,9 +147,6 @@ proc checkIfModuleDidLoad[T](self: Module[T]) =
|
|||
if(not self.ensUsernamesModule.isLoaded()):
|
||||
return
|
||||
|
||||
if(not self.walletModule.isLoaded()):
|
||||
return
|
||||
|
||||
self.moduleLoaded = true
|
||||
self.delegate.profileSectionDidLoad()
|
||||
|
||||
|
@ -169,9 +159,6 @@ method profileModuleDidLoad*[T](self: Module[T]) =
|
|||
method getProfileModule*[T](self: Module[T]): QVariant =
|
||||
self.profileModule.getModuleAsVariant()
|
||||
|
||||
method walletModuleDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method contactsModuleDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
# Defines how parent module accesses this module
|
||||
include ./private_interfaces/module_base_interface
|
||||
include ./private_interfaces/module_access_interface
|
|
@ -1,48 +0,0 @@
|
|||
import NimQml
|
||||
import ./io_interface
|
||||
import ../../../../global/global_singleton
|
||||
import ../../../../core/eventemitter
|
||||
import ../../../../../app_service/service/network/service as network_service
|
||||
import ../io_interface as delegate_interface
|
||||
|
||||
import ./networks/module as networks_module
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
Module* = ref object of io_interface.AccessInterface
|
||||
delegate: delegate_interface.AccessInterface
|
||||
moduleLoaded: bool
|
||||
|
||||
networksModule: networks_module.AccessInterface
|
||||
|
||||
|
||||
proc newModule*(
|
||||
delegate: delegate_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
networkService: network_service.Service,
|
||||
): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.moduleLoaded = false
|
||||
|
||||
result.networksModule = networks_module.newModule(result, events, networkService)
|
||||
|
||||
method delete*(self: Module) =
|
||||
self.networksModule.delete
|
||||
|
||||
method load*(self: Module) =
|
||||
self.networksModule.load()
|
||||
|
||||
method isLoaded*(self: Module): bool =
|
||||
return self.moduleLoaded
|
||||
|
||||
proc checkIfModuleDidLoad(self: Module) =
|
||||
if(not self.networksModule.isLoaded()):
|
||||
return
|
||||
|
||||
self.moduleLoaded = true
|
||||
self.delegate.walletModuleDidLoad()
|
||||
|
||||
method networksModuleDidLoad*(self: Module) =
|
||||
self.checkIfModuleDidLoad()
|
|
@ -1,31 +0,0 @@
|
|||
import ./controller_interface
|
||||
import ../../../../../core/eventemitter
|
||||
import ../../../../../../app_service/service/network/service as network_service
|
||||
import ./io_interface
|
||||
|
||||
export controller_interface
|
||||
|
||||
type
|
||||
Controller* = ref object of controller_interface.AccessInterface
|
||||
delegate: io_interface.AccessInterface
|
||||
events: EventEmitter
|
||||
networkService: network_service.Service
|
||||
|
||||
proc newController*(
|
||||
delegate: io_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
networkService: network_service.Service
|
||||
): Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
result.events = events
|
||||
result.networkService = networkService
|
||||
|
||||
method delete*(self: Controller) =
|
||||
discard
|
||||
|
||||
method init*(self: Controller) =
|
||||
discard
|
||||
|
||||
method getNetworks*(self: Controller): seq[NetworkDto] =
|
||||
return self.networkService.getNetworks()
|
|
@ -1,13 +0,0 @@
|
|||
import NimQml
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method load*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method networksModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -1,5 +0,0 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
|
||||
# Since nim doesn't support using concepts in second level nested types we
|
||||
# define delegate interfaces within access interface.
|
|
@ -55,6 +55,9 @@ method load*(self: Module) =
|
|||
self.events.on(SIGNAL_WALLET_ACCOUNT_TOKEN_VISIBILITY_UPDATED) do(e:Args):
|
||||
self.switchAccount(self.currentAccountIndex)
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e:Args):
|
||||
self.switchAccount(self.currentAccountIndex)
|
||||
|
||||
self.controller.init()
|
||||
self.view.load()
|
||||
|
||||
|
|
|
@ -85,6 +85,9 @@ method load*(self: Module) =
|
|||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_TOKEN_VISIBILITY_UPDATED) do(e:Args):
|
||||
self.refreshWalletAccounts()
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e:Args):
|
||||
self.refreshWalletAccounts()
|
||||
|
||||
self.controller.init()
|
||||
self.view.load()
|
||||
|
|
|
@ -34,6 +34,9 @@ method init*(self: Controller) =
|
|||
self.events.on(SIGNAL_TOKEN_DETAILS_LOADED) do(e:Args):
|
||||
let args = TokenDetailsLoadedArgs(e)
|
||||
self.delegate.tokenDetailsWereResolved(args.tokenDetails)
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e:Args):
|
||||
self.delegate.refreshTokens()
|
||||
|
||||
method getTokens*(self: Controller): seq[token_service.TokenDto] =
|
||||
for tokens in self.tokenService.getTokens().values:
|
||||
|
|
|
@ -47,6 +47,9 @@ method load*(self: Module) =
|
|||
self.events.on(SIGNAL_WALLET_ACCOUNT_TOKEN_VISIBILITY_UPDATED) do(e:Args):
|
||||
self.switchAccount(self.currentAccountIndex)
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e: Args):
|
||||
self.switchAccount(self.currentAccountIndex)
|
||||
|
||||
self.controller.init()
|
||||
self.view.load()
|
||||
|
||||
|
@ -63,4 +66,4 @@ method switchAccount*(self: Module, accountIndex: int) =
|
|||
self.view.setData(walletAccount)
|
||||
|
||||
method update*(self: Module, address: string, accountName: string, color: string) =
|
||||
self.controller.update(address, accountName, color)
|
||||
self.controller.update(address, accountName, color)
|
||||
|
|
|
@ -98,6 +98,8 @@ method load*[T](self: Module[T]) =
|
|||
self.setTotalCurrencyBalance()
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_TOKEN_VISIBILITY_UPDATED) do(e:Args):
|
||||
self.setTotalCurrencyBalance()
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e:Args):
|
||||
self.setTotalCurrencyBalance()
|
||||
|
||||
self.controller.init()
|
||||
self.view.load()
|
||||
|
|
|
@ -238,7 +238,7 @@ var NODE_CONFIG* = %* {
|
|||
{
|
||||
"chainId": 10,
|
||||
"chainName": "Optimistic Ethereum",
|
||||
"rpcUrl": "https://mainnet.infura.io/v3/" & INFURA_TOKEN_RESOLVED,
|
||||
"rpcUrl": "https://optimism-mainnet.infura.io/v3/" & INFURA_TOKEN_RESOLVED,
|
||||
"blockExplorerUrl": "https://optimistic.etherscan.io",
|
||||
"iconUrl": "",
|
||||
"nativeCurrencyName": "Ether",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import json, json_serialization, chronicles, atomics
|
||||
import options
|
||||
|
||||
|
||||
import ../../../app/core/eventemitter
|
||||
import ../../../app/global/global_singleton
|
||||
import ../../../backend/network as status_network
|
||||
import ../settings/service as settings_service
|
||||
|
@ -15,6 +14,7 @@ logScope:
|
|||
|
||||
type
|
||||
Service* = ref object of network_interface.ServiceInterface
|
||||
events: EventEmitter
|
||||
networks: seq[NetworkDto]
|
||||
networksInited: bool
|
||||
dirty: Atomic[bool]
|
||||
|
@ -24,8 +24,9 @@ type
|
|||
method delete*(self: Service) =
|
||||
discard
|
||||
|
||||
proc newService*(settingsService: settings_service.Service): Service =
|
||||
proc newService*(events: EventEmitter, settingsService: settings_service.Service): Service =
|
||||
result = Service()
|
||||
result.events = events
|
||||
result.settingsService = settingsService
|
||||
|
||||
method init*(self: Service) =
|
||||
|
@ -78,3 +79,9 @@ method getNetwork*(self: Service, networkType: NetworkType): NetworkDto =
|
|||
|
||||
# Will be removed, this is used in case of legacy chain Id
|
||||
return NetworkDto(chainId: networkType.toChainId())
|
||||
|
||||
method toggleNetwork*(self: Service, chainId: int) =
|
||||
let network = self.getNetwork(chainId)
|
||||
|
||||
network.enabled = not network.enabled
|
||||
self.upsertNetwork(network)
|
|
@ -29,3 +29,6 @@ method getNetwork*(self: ServiceInterface, networkType: NetworkType): NetworkDto
|
|||
|
||||
method getNetwork*(self: ServiceInterface, chainId: int): NetworkDto {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method toggleNetwork*(self: ServiceInterface, chainId: int) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -23,6 +23,7 @@ include async_tasks
|
|||
const DEFAULT_VISIBLE_TOKENS = {1: @["SNT"], 3: @["STT"], 4: @["STT"]}.toTable()
|
||||
# Signals which may be emitted by this service:
|
||||
const SIGNAL_TOKEN_DETAILS_LOADED* = "tokenDetailsLoaded"
|
||||
const SIGNAL_TOKEN_LIST_RELOADED* = "tokenListReloaded"
|
||||
|
||||
type
|
||||
TokenDetailsLoadedArgs* = ref object of Args
|
||||
|
@ -67,13 +68,16 @@ QtObject:
|
|||
|
||||
proc init*(self: Service) =
|
||||
try:
|
||||
self.tokens = initTable[NetworkDto, seq[TokenDto]]()
|
||||
var activeTokenSymbols = self.settingsService.getWalletVisibleTokens()
|
||||
let networks = self.networkService.getEnabledNetworks()
|
||||
let responseCustomTokens = custom_tokens.getCustomTokens()
|
||||
|
||||
for network in networks:
|
||||
if not activeTokenSymbols.hasKey(network.chainId):
|
||||
if not activeTokenSymbols.hasKey(network.chainId) and DEFAULT_VISIBLE_TOKENS.hasKey(network.chainId):
|
||||
activeTokenSymbols[network.chainId] = DEFAULT_VISIBLE_TOKENS[network.chainId]
|
||||
else:
|
||||
activeTokenSymbols[network.chainId] = @[]
|
||||
|
||||
let responseTokens = token_backend.getTokens(network.chainId)
|
||||
let default_tokens = map(
|
||||
|
@ -93,10 +97,7 @@ QtObject:
|
|||
error "error: ", errDesription
|
||||
return
|
||||
|
||||
proc getTokens*(self: Service, useCache: bool = true): Table[NetworkDto, seq[TokenDto]] =
|
||||
if not useCache:
|
||||
self.init()
|
||||
|
||||
proc getTokens*(self: Service): Table[NetworkDto, seq[TokenDto]] =
|
||||
return self.tokens
|
||||
|
||||
proc getVisibleTokens*(self: Service): seq[TokenDto] =
|
||||
|
|
|
@ -25,6 +25,7 @@ const SIGNAL_WALLET_ACCOUNT_DELETED* = "walletAccount/accountDeleted"
|
|||
const SIGNAL_WALLET_ACCOUNT_CURRENCY_UPDATED* = "walletAccount/currencyUpdated"
|
||||
const SIGNAL_WALLET_ACCOUNT_TOKEN_VISIBILITY_UPDATED* = "walletAccount/tokenVisibilityUpdated"
|
||||
const SIGNAL_WALLET_ACCOUNT_UPDATED* = "walletAccount/walletAccountUpdated"
|
||||
const SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED* = "walletAccount/networkEnabledUpdated"
|
||||
|
||||
var
|
||||
priceCache {.threadvar.}: Table[string, float64]
|
||||
|
@ -76,13 +77,17 @@ proc fetchAccounts(): seq[WalletAccountDto] =
|
|||
).filter(a => not a.isChat)
|
||||
|
||||
proc fetchNativeChainBalance(network: NetworkDto, accountAddress: string): float64 =
|
||||
let key = "0x0" & accountAddress
|
||||
let key = "0x0" & accountAddress & $network.chainId
|
||||
if balanceCache.hasKey(key):
|
||||
return balanceCache[key]
|
||||
|
||||
let nativeBalanceResponse = status_go_eth.getNativeChainBalance(network.chainId, accountAddress)
|
||||
result = parsefloat(hex2Balance(nativeBalanceResponse.result.getStr, network.nativeCurrencyDecimals))
|
||||
balanceCache[key] = result
|
||||
try:
|
||||
let nativeBalanceResponse = status_go_eth.getNativeChainBalance(network.chainId, accountAddress)
|
||||
result = parsefloat(hex2Balance(nativeBalanceResponse.result.getStr, network.nativeCurrencyDecimals))
|
||||
balanceCache[key] = result
|
||||
except Exception as e:
|
||||
error "Error getting balance", message = e.msg
|
||||
result = 0.0
|
||||
|
||||
type AccountSaved = ref object of Args
|
||||
account: WalletAccountDto
|
||||
|
@ -94,6 +99,8 @@ type CurrencyUpdated = ref object of Args
|
|||
|
||||
type TokenVisibilityToggled = ref object of Args
|
||||
|
||||
type NetwordkEnabledToggled = ref object of Args
|
||||
|
||||
type WalletAccountUpdated = ref object of Args
|
||||
account: WalletAccountDto
|
||||
|
||||
|
@ -297,6 +304,12 @@ method toggleTokenVisible*(self: Service, chainId: int, symbol: string) =
|
|||
self.refreshBalances()
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_TOKEN_VISIBILITY_UPDATED, TokenVisibilityToggled())
|
||||
|
||||
method toggleNetworkEnabled*(self: Service, chainId: int) =
|
||||
self.networkService.toggleNetwork(chainId)
|
||||
self.tokenService.init()
|
||||
self.refreshBalances()
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED, NetwordkEnabledToggled())
|
||||
|
||||
method updateWalletAccount*(self: Service, address: string, accountName: string, color: string) =
|
||||
let account = self.accounts[address]
|
||||
status_go_accounts.updateAccount(
|
||||
|
|
|
@ -11,16 +11,12 @@ proc callRPC*(inputJSON: string): string =
|
|||
return $status_go.callRPC(inputJSON)
|
||||
|
||||
proc callPrivateRPCRaw*(inputJSON: string): string {.raises: [].} =
|
||||
result = $status_go.callPrivateRPC(inputJSON)
|
||||
result = $status_go.callPrivateRPC(inputJSON)
|
||||
|
||||
proc callPrivateRPC*(methodName: string, payload = %* []): RpcResponse[JsonNode]
|
||||
{.raises: [RpcException, ValueError, Defect, SerializationError].} =
|
||||
proc makePrivateRpcCall*(
|
||||
methodName: string, inputJSON: JsonNode
|
||||
): RpcResponse[JsonNode] {.raises: [RpcException, ValueError, Defect, SerializationError].} =
|
||||
try:
|
||||
let inputJSON = %* {
|
||||
"jsonrpc": "2.0",
|
||||
"method": methodName,
|
||||
"params": %payload
|
||||
}
|
||||
debug "NewBE_callPrivateRPC", rpc_method=methodName
|
||||
let rpcResponseRaw = status_go.callPrivateRPC($inputJSON)
|
||||
result = Json.decode(rpcResponseRaw, RpcResponse[JsonNode])
|
||||
|
@ -38,6 +34,27 @@ proc callPrivateRPC*(methodName: string, payload = %* []): RpcResponse[JsonNode]
|
|||
error "error doing rpc request", methodName = methodName, exception=e.msg
|
||||
raise newException(RpcException, e.msg)
|
||||
|
||||
proc callPrivateRPCWithChainId*(
|
||||
methodName: string, chainId: int, payload = %* []
|
||||
): RpcResponse[JsonNode] {.raises: [RpcException, ValueError, Defect, SerializationError].} =
|
||||
let inputJSON = %* {
|
||||
"jsonrpc": "2.0",
|
||||
"method": methodName,
|
||||
"chainId": chainId,
|
||||
"params": %payload
|
||||
}
|
||||
return makePrivateRpcCall(methodName, inputJSON)
|
||||
|
||||
proc callPrivateRPC*(
|
||||
methodName: string, payload = %* []
|
||||
): RpcResponse[JsonNode] {.raises: [RpcException, ValueError, Defect, SerializationError].} =
|
||||
let inputJSON = %* {
|
||||
"jsonrpc": "2.0",
|
||||
"method": methodName,
|
||||
"params": %payload
|
||||
}
|
||||
return makePrivateRpcCall(methodName, inputJSON)
|
||||
|
||||
proc signMessage*(rpcParams: string): string =
|
||||
return $status_go.signMessage(rpcParams)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ proc getBlockByNumber*(blockNumber: string): RpcResponse[JsonNode] {.raises: [Ex
|
|||
|
||||
proc getNativeChainBalance*(chainId: int, address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [address, "latest"]
|
||||
return core.callPrivateRPC("eth_getBalance", payload)
|
||||
return core.callPrivateRPCWithChainId("eth_getBalance", chainId, payload)
|
||||
|
||||
proc sendTransaction*(transactionData: string, password: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
core.sendTransaction(transactionData, password)
|
||||
|
|
|
@ -3,7 +3,7 @@ import QtQuick 2.13
|
|||
QtObject {
|
||||
id: root
|
||||
|
||||
property var layer1Networks: profileSectionWalletNetworkModule.layer1
|
||||
property var layer2Networks: profileSectionWalletNetworkModule.layer2
|
||||
property var testNetworks: profileSectionWalletNetworkModule.test
|
||||
property var layer1Networks: networksModule.layer1
|
||||
property var layer2Networks: networksModule.layer2
|
||||
property var testNetworks: networksModule.test
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ Item {
|
|||
id: root
|
||||
width: selectRectangle.width
|
||||
height: childrenRect.height
|
||||
signal toggleNetwork(int chainId)
|
||||
|
||||
property var store
|
||||
|
||||
|
@ -23,7 +22,7 @@ Item {
|
|||
|
||||
StyledText {
|
||||
id: text
|
||||
text: qsTr("All networks")
|
||||
text: qsTr("Select networks")
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
@ -56,10 +55,13 @@ Item {
|
|||
|
||||
Grid {
|
||||
id: enabledNetworks
|
||||
columns: 2
|
||||
columns: 4
|
||||
spacing: 2
|
||||
visible: (chainRepeater.count > 0)
|
||||
|
||||
anchors.top: selectRectangle.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
|
||||
Repeater {
|
||||
id: chainRepeater
|
||||
model: store.enabledNetworks
|
||||
|
@ -87,8 +89,10 @@ Item {
|
|||
NetworkSelectPopup {
|
||||
id: selectPopup
|
||||
x: (parent.width - width)
|
||||
y: (root.height - networkFilterPanel.height)
|
||||
model: store.allNetworks
|
||||
layer1Networks: store.layer1Networks
|
||||
layer2Networks: store.layer2Networks
|
||||
testNetworks: store.testNetworks
|
||||
|
||||
onToggleNetwork: {
|
||||
store.toggleNetwork(chainId)
|
||||
}
|
||||
|
|
|
@ -16,8 +16,11 @@ Popup {
|
|||
modal: false
|
||||
width: 360
|
||||
height: 432
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
property var model
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||
property var layer1Networks
|
||||
property var layer2Networks
|
||||
property var testNetworks
|
||||
|
||||
signal toggleNetwork(int chainId)
|
||||
|
||||
background: Rectangle {
|
||||
|
@ -49,32 +52,51 @@ Popup {
|
|||
width: popup.width
|
||||
spacing: Style.current.padding
|
||||
|
||||
Repeater {
|
||||
id: chainRepeater
|
||||
model: popup.model
|
||||
Repeater {
|
||||
id: chainRepeater1
|
||||
model: popup.layer1Networks
|
||||
|
||||
Item {
|
||||
width: content.width
|
||||
height: 40
|
||||
StatusBaseText {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.bigPadding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
text: model.chainName
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
delegate: chainItem
|
||||
}
|
||||
|
||||
StatusCheckBox {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.bigPadding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: model.enabled
|
||||
onCheckedChanged: {
|
||||
if(checked !== model.enabled){
|
||||
popup.toggleNetwork(model.chainId)
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
id: chainRepeater2
|
||||
model: popup.layer2Networks
|
||||
|
||||
delegate: chainItem
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: chainRepeater3
|
||||
model: popup.testNetworks
|
||||
|
||||
delegate: chainItem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: chainItem
|
||||
Item {
|
||||
width: content.width
|
||||
height: 40
|
||||
StatusBaseText {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.bigPadding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
text: model.chainName
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
|
||||
StatusCheckBox {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.bigPadding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: model.isEnabled
|
||||
onCheckedChanged: {
|
||||
if (model.isEnabled !== checked) {
|
||||
popup.toggleNetwork(model.chainId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,12 @@ QtObject {
|
|||
|
||||
property var savedAddresses: walletSectionSavedAddresses.model
|
||||
|
||||
|
||||
property var layer1Networks: networksModule.layer1
|
||||
property var layer2Networks: networksModule.layer2
|
||||
property var testNetworks: networksModule.test
|
||||
property var enabledNetworks: networksModule.enabled
|
||||
|
||||
// This should be exposed to the UI via "walletModule", WalletModule should use
|
||||
// Accounts Service which keeps the info about that (isFirstTimeAccountLogin).
|
||||
// Then in the View of WalletModule we may have either QtProperty or
|
||||
|
@ -184,4 +190,8 @@ QtObject {
|
|||
function deleteSavedAddress(address) {
|
||||
walletSectionSavedAddresses.deleteSavedAddress(address)
|
||||
}
|
||||
|
||||
function toggleNetwork(chainId) {
|
||||
networksModule.toggleNetwork(chainId)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue