refactor(@wallet): saved address from wallet2

This commit is contained in:
Anthony Laibe 2021-12-14 09:55:16 +01:00 committed by Sale Djenic
parent 45fddc55ba
commit ad93b9d92b
16 changed files with 410 additions and 14 deletions

4
.gitignore vendored
View File

@ -31,3 +31,7 @@ status-react-translations/
/.update.timestamp
notarization.log
status-desktop.log
<<<<<<< HEAD
=======
nim_status_client.log
>>>>>>> bcc756eb3... refactor(@wallet): saved address from wallet2

View File

@ -28,6 +28,7 @@ import ../../app_service/service/about/service as about_service
import ../../app_service/service/node_configuration/service as node_configuration_service
import ../../app_service/service/network/service as network_service
import ../../app_service/service/activity_center/service as activity_center_service
import ../../app_service/service/saved_address/service as saved_address_service
import ../modules/startup/module as startup_module
import ../modules/main/module as main_module
@ -95,6 +96,7 @@ type
mnemonicService: mnemonic_service.Service
privacyService: privacy_service.Service
nodeConfigurationService: node_configuration_service.Service
savedAddressService: saved_address_service.Service
# Modules
startupModule: startup_module.AccessInterface
@ -169,6 +171,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.privacyService = privacy_service.newService()
result.ensService = ens_service.newService()
result.providerService = provider_service.newService(result.dappPermissionsService, result.settingsService, result.ensService)
result.savedAddressService = saved_address_service.newService()
# Modules
result.startupModule = startup_module.newModule[AppController](
@ -200,7 +203,8 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.privacyService,
result.providerService,
result.stickersService,
result.activityCenterService
result.activityCenterService,
result.savedAddressService
)
# Do connections
@ -237,6 +241,7 @@ proc delete*(self: AppController) =
self.nodeConfigurationService.delete
self.settingsService.delete
self.stickersService.delete
self.savedAddressService.delete
proc startupDidLoad*(self: AppController) =
singletonInstance.engine.setRootContextProperty("localAppSettings", self.localAppSettingsVariant)
@ -276,6 +281,7 @@ proc load(self: AppController) =
self.stickersService.init()
self.networkService.init()
self.activityCenterService.init()
self.savedAddressService.init()
let pubKey = self.settingsService.getPublicKey()
singletonInstance.localAccountSensitiveSettings.setFileName(pubKey)

View File

@ -33,6 +33,7 @@ import ../../../app_service/service/mnemonic/service as mnemonic_service
import ../../../app_service/service/privacy/service as privacy_service
import ../../../app_service/service/stickers/service as stickers_service
import ../../../app_service/service/activity_center/service as activity_center_service
import ../../../app_service/service/saved_address/service as saved_address_service
import eventemitter
@ -77,22 +78,27 @@ proc newModule*[T](
privacyService: privacy_service.ServiceInterface,
providerService: provider_service.ServiceInterface,
stickersService: stickers_service.Service,
activityCenterService: activity_center_service.Service
activityCenterService: activity_center_service.Service,
savedAddressService: saved_address_service.ServiceInterface
): Module[T] =
result = Module[T]()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, events, settingsService, keychainService, accountsService,
chatService, communityService)
result.controller = controller.newController(
result, events, settingsService, keychainService, accountsService, chatService, communityService
)
result.moduleLoaded = false
# Submodules
result.chatSectionModule = chat_section_module.newModule(result, events, conf.CHAT_SECTION_ID, false, contactsService,
chatService, communityService, messageService)
result.communitySectionsModule = initOrderedTable[string, chat_section_module.AccessInterface]()
result.walletSectionModule = wallet_section_module.newModule[Module[T]](result, events, tokenService,
transactionService, collectible_service, walletAccountService, settingsService)
result.walletSectionModule = wallet_section_module.newModule[Module[T]](
result, events, tokenService,
transactionService, collectible_service, walletAccountService,
settingsService, savedAddressService
)
result.browserSectionModule = browser_section_module.newModule(result, bookmarkService, settingsService,
dappPermissionsService, providerService)
result.profileSectionModule = profile_section_module.newModule(result, events, accountsService, settingsService,

View File

@ -45,6 +45,9 @@ method currentAccountModuleDidLoad*(self: AccessInterface) {.base.} =
method transactionsModuleDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method savedAddressesModuleDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
type
## Abstract class (concept) which must be implemented by object/s used in this
## module.

View File

@ -11,6 +11,7 @@ import ./all_tokens/module as all_tokens_module
import ./collectibles/module as collectibles_module
import ./current_account/module as current_account_module
import ./transactions/module as transactions_module
import ./saved_addresses/module as saved_addresses_module
import ../../../../app_service/service/token/service as token_service
@ -18,6 +19,7 @@ import ../../../../app_service/service/transaction/service as transaction_servic
import ../../../../app_service/service/collectible/service as collectible_service
import ../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../app_service/service/settings/service_interface as settings_service
import ../../../../app_service/service/saved_address/service_interface as saved_address_service
import io_interface
export io_interface
@ -36,6 +38,7 @@ type
collectiblesModule: collectibles_module.AccessInterface
currentAccountModule: current_account_module.AccessInterface
transactionsModule: transactions_module.AccessInterface
savedAddressesModule: saved_addresses_module.AccessInterface
proc newModule*[T](
delegate: T,
@ -44,7 +47,8 @@ proc newModule*[T](
transactionService: transaction_service.Service,
collectibleService: collectible_service.ServiceInterface,
walletAccountService: wallet_account_service.ServiceInterface,
settingsService: settings_service.ServiceInterface
settingsService: settings_service.ServiceInterface,
savedAddressService: saved_address_service.ServiceInterface,
): Module[T] =
result = Module[T]()
result.delegate = delegate
@ -59,6 +63,7 @@ proc newModule*[T](
result.collectiblesModule = collectibles_module.newModule(result, events, collectibleService, walletAccountService)
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService)
result.transactionsModule = transactions_module.newModule(result, events, transactionService, walletAccountService)
result.savedAddressesModule = saved_addresses_module.newModule(result, events, savedAddressService)
method delete*[T](self: Module[T]) =
self.accountTokensModule.delete
@ -67,6 +72,7 @@ method delete*[T](self: Module[T]) =
self.collectiblesModule.delete
self.currentAccountModule.delete
self.transactionsModule.delete
self.savedAddressesModule.delete
self.controller.delete
self.view.delete
@ -102,6 +108,7 @@ method load*[T](self: Module[T]) =
self.collectiblesModule.load()
self.currentAccountModule.load()
self.transactionsModule.load()
self.savedAddressesModule.load()
method isLoaded*[T](self: Module[T]): bool =
return self.moduleLoaded
@ -125,6 +132,9 @@ proc checkIfModuleDidLoad[T](self: Module[T]) =
if(not self.transactionsModule.isLoaded()):
return
if(not self.savedAddressesModule.isLoaded()):
return
self.switchAccount(0)
let currency = self.controller.getCurrency()
let signingPhrase = self.controller.getSigningPhrase()
@ -155,3 +165,6 @@ method currentAccountModuleDidLoad*[T](self: Module[T]) =
method transactionsModuleDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()
method savedAddressesModuleDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()

View File

@ -0,0 +1,33 @@
import ./controller_interface
import io_interface
import ../../../../../app_service/service/saved_address/service as saved_address_service
export controller_interface
type
Controller* = ref object of controller_interface.AccessInterface
delegate: io_interface.AccessInterface
savedAddressService: saved_address_service.ServiceInterface
proc newController*(
delegate: io_interface.AccessInterface,
savedAddressService: saved_address_service.ServiceInterface
): Controller =
result = Controller()
result.delegate = delegate
result.savedAddressService = savedAddressService
method delete*(self: Controller) =
discard
method init*(self: Controller) =
discard
method getSavedAddresses*(self: Controller): seq[saved_address_service.SavedAddressDto] =
return self.savedAddressService.getSavedAddresses()
method addSavedAddress*(self: Controller, name, address: string) =
self.savedAddressService.addSavedAddress(name, address)
method deleteSavedAddress*(self: Controller, address: string) =
self.savedAddressService.deleteSavedAddress(address)

View File

@ -0,0 +1,26 @@
import ../../../../../app_service/service/saved_address/service_interface as saved_address_service
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
## Abstract class for any input/interaction with this module.
method delete*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method init*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getSavedAddresses*(self: AccessInterface): seq[saved_address_service.SavedAddressDto] {.base.} =
raise newException(ValueError, "No implementation available")
method addSavedAddresses*(self: AccessInterface, name, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
method deleteSavedAddresses*(self: AccessInterface, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
type
## Abstract class (concept) which must be implemented by object/s used in this
## module.
DelegateInterface* = concept c

View File

@ -0,0 +1,20 @@
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
## Abstract class for any input/interaction with this module.
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 viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
type
## Abstract class (concept) which must be implemented by object/s used in this
## module.
DelegateInterface* = concept c

View File

@ -0,0 +1,25 @@
import strformat
type
Item* = object
name: string
address: string
proc initItem*(
name: string,
address: string,
): Item =
result.name = name
result.address = address
proc `$`*(self: Item): string =
result = fmt"""AllTokensItem(
name: {self.name},
address: {self.address},
]"""
proc getName*(self: Item): string =
return self.name
proc getAddress*(self: Item): string =
return self.address

View File

@ -0,0 +1,76 @@
import NimQml, Tables, strutils, strformat
import ./item
type
ModelRole {.pure.} = enum
Name = UserRole + 1,
Address
QtObject:
type
Model* = ref object of QAbstractListModel
items: seq[Item]
proc delete(self: Model) =
self.items = @[]
self.QAbstractListModel.delete
proc setup(self: Model) =
self.QAbstractListModel.setup
proc newModel*(): Model =
new(result, delete)
result.setup
proc `$`*(self: Model): string =
for i in 0 ..< self.items.len:
result &= fmt"""[{i}]:({$self.items[i]})"""
proc countChanged(self: Model) {.signal.}
proc getCount*(self: Model): int {.slot.} =
self.items.len
QtProperty[int] count:
read = getCount
notify = countChanged
method rowCount(self: Model, index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: Model): Table[int, string] =
{
ModelRole.Name.int:"name",
ModelRole.Address.int:"address",
}.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant =
if (not index.isValid):
return
if (index.row < 0 or index.row >= self.items.len):
return
let item = self.items[index.row]
let enumRole = role.ModelRole
case enumRole:
of ModelRole.Name:
result = newQVariant(item.getName())
of ModelRole.Address:
result = newQVariant(item.getAddress())
proc rowData(self: Model, index: int, column: string): string {.slot.} =
if (index >= self.items.len):
return
let item = self.items[index]
case column:
of "name": result = $item.getName()
of "address": result = $item.getAddress()
proc setItems*(self: Model, items: seq[Item]) =
self.beginResetModel()
self.items = items
self.endResetModel()
self.countChanged()

View File

@ -0,0 +1,53 @@
import NimQml, sugar, sequtils
import eventemitter
import ../io_interface as delegate_interface
import ../../../../global/global_singleton
import ../../../../../app_service/service/saved_address/service as saved_address_service
import ./io_interface, ./view, ./controller, ./item
export io_interface
type
Module* = ref object of io_interface.AccessInterface
delegate: delegate_interface.AccessInterface
events: EventEmitter
view: View
moduleLoaded: bool
controller: controller.AccessInterface
proc newModule*(
delegate: delegate_interface.AccessInterface,
events: EventEmitter,
savedAddressService: saved_address_service.ServiceInterface,
): Module =
result = Module()
result.delegate = delegate
result.events = events
result.view = newView(result)
result.controller = newController(result, savedAddressService)
result.moduleLoaded = false
method delete*(self: Module) =
self.view.delete
method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("walletSectionSavedAddresses", newQVariant(self.view))
let savedAddresses = self.controller.getSavedAddresses()
self.view.setItems(
savedAddresses.map(s => initItem(
s.name,
s.address,
))
)
self.controller.init()
self.view.load()
method isLoaded*(self: Module): bool =
return self.moduleLoaded
method viewDidLoad*(self: Module) =
self.moduleLoaded = true
self.delegate.savedAddressesModuleDidLoad()

View File

@ -0,0 +1,38 @@
import NimQml
import ./model, ./item
import ./io_interface
QtObject:
type
View* = ref object of QObject
delegate: io_interface.AccessInterface
model: Model
modelVariant: QVariant
proc delete*(self: View) =
self.model.delete
self.modelVariant.delete
self.QObject.delete
proc newView*(delegate: io_interface.AccessInterface): View =
new(result, delete)
result.QObject.setup
result.delegate = delegate
result.model = newModel()
result.modelVariant = newQVariant(result.model)
proc load*(self: View) =
self.delegate.viewDidLoad()
proc modelChanged*(self: View) {.signal.}
proc getModel(self: View): QVariant {.slot.} =
return self.modelVariant
QtProperty[QVariant] model:
read = getModel
notify = modelChanged
proc setItems*(self: View, items: seq[Item]) =
self.model.setItems(items)

View File

@ -0,0 +1,22 @@
import json, sequtils, sugar
include ../../common/json_utils
type
SavedAddressDto* = ref object of RootObj
name*: string
address*: string
proc newSavedAddressDto*(
name: string,
address: string,
): SavedAddressDto =
return SavedAddressDto(
name: name,
address: address,
)
proc toSavedAddressDto*(jsonObj: JsonNode): SavedAddressDto =
result = SavedAddressDto()
discard jsonObj.getProp("name", result.name)
discard jsonObj.getProp("address", result.address)

View File

@ -0,0 +1,49 @@
import chronicles, sequtils, json
import ./service_interface, ./dto
import status/statusgo_backend_new/saved_addresses as backend
export service_interface
logScope:
topics = "saved-address-service"
type
Service* = ref object of service_interface.ServiceInterface
savedAddresses: seq[SavedAddressDto]
method delete*(self: Service) =
discard
proc newService*(): Service =
result = Service()
method init*(self: Service) =
try:
let response = backend.getSavedAddresses()
self.savedAddresses = map(
response.result.getElems(),
proc(x: JsonNode): SavedAddressDto = toSavedAddressDto(x)
)
except Exception as e:
error "error: ", methodName="init", errName = e.name, errDesription = e.msg
method getSavedAddresses(self: Service): seq[SavedAddressDto] =
return self.savedAddresses
method addSavedAddress(self: Service, name, address: string) =
try:
discard backend.addSavedAddress(name, address)
except Exception as e:
let errDesription = e.msg
error "error: ", errDesription
return
method deleteSavedAddress(self: Service, address: string) =
try:
discard backend.deleteSavedAddress(address)
except Exception as e:
let errDesription = e.msg

View File

@ -0,0 +1,22 @@
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 getSavedAddresses*(self: ServiceInterface): seq[SavedAddressDto] {.base.} =
raise newException(ValueError, "No implementation available")
method addSavedAddress*(self: ServiceInterface, name: string, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
method deleteSavedAddress*(self: ServiceInterface, address: string) {.base.} =
raise newException(ValueError, "No implementation available")