feat(@wallet): wallet accounts module dedup

Second part of having profile section accounts
This commit is contained in:
Anthony Laibe 2023-04-20 10:41:45 +02:00 committed by Anthony Laibe
parent eb5423db9c
commit e6f88758dc
44 changed files with 726 additions and 1176 deletions

View File

@ -53,6 +53,3 @@ proc getCurrentCurrency*(self: Controller): string =
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
return self.currencyService.getCurrencyFormat(symbol)
proc getAllMigratedKeyPairs*(self: Controller): seq[KeyPairDto] =
return self.walletAccountService.getAllMigratedKeyPairs()

View File

@ -63,32 +63,17 @@ proc setAssets(self: Module, tokens: seq[WalletTokenDto]) =
method switchAccount*(self: Module, accountIndex: int) =
self.currentAccountIndex = accountIndex
let keyPairMigrated = proc(migratedKeyPairs: seq[KeyPairDto], keyUid: string): bool =
for kp in migratedKeyPairs:
if kp.keyUid == keyUid:
return true
return false
let walletAccount = self.controller.getWalletAccount(accountIndex)
let migratedKeyPairs = self.controller.getAllMigratedKeyPairs()
let currency = self.controller.getCurrentCurrency()
let chainIds = self.controller.getChainIds()
let enabledChainIds = self.controller.getEnabledChainIds()
let tokenFormats = collect(initTable()):
for t in walletAccount.tokens: {t.symbol: self.controller.getCurrencyFormat(t.symbol)}
let currencyFormat = self.controller.getCurrencyFormat(currency)
let accountItem = walletAccountToItem(
walletAccount,
chainIds,
enabledChainIds,
currency,
keyPairMigrated(migratedKeyPairs, walletAccount.keyUid),
currencyFormat,
tokenFormats
)
self.view.setData(accountItem)

View File

@ -15,9 +15,7 @@ QtObject:
address: string
path: string
color: string
publicKey: string
walletType: string
isChat: bool
currencyBalance: CurrencyAmount
assets: token_model.Model
emoji: string
@ -74,15 +72,6 @@ QtObject:
read = getColor
notify = colorChanged
proc getPublicKey(self: View): QVariant {.slot.} =
return newQVariant(self.publicKey)
proc publicKeyChanged(self: View) {.signal.}
QtProperty[QVariant] publicKey:
read = getPublicKey
notify = publicKeyChanged
proc getWalletType(self: View): QVariant {.slot.} =
return newQVariant(self.walletType)
@ -92,15 +81,6 @@ QtObject:
read = getWalletType
notify = walletTypeChanged
proc getIsChat(self: View): QVariant {.slot.} =
return newQVariant(self.isChat)
proc isChatChanged(self: View) {.signal.}
QtProperty[QVariant] isChat:
read = getIsChat
notify = isChatChanged
proc getCurrencyBalance(self: View): QVariant {.slot.} =
return newQVariant(self.currencyBalance)
@ -141,9 +121,6 @@ QtObject:
proc hasGas*(self: View, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.slot.} =
return self.assets.hasGas(chainId, nativeGasSymbol, requiredGas)
# proc getTokenBalanceOnChain*(self: View, chainId: int, tokenSymbol: string): QVariant {.slot.} =
# return newQVariant(self.assets.getTokenBalanceOnChain(chainId, tokenSymbol))
proc setData*(self: View, item: account_item.Item) =
self.name = item.getName()
self.nameChanged()
@ -153,12 +130,8 @@ proc setData*(self: View, item: account_item.Item) =
self.pathChanged()
self.color = item.getColor()
self.colorChanged()
self.publicKey = item.getPublicKey()
self.publicKeyChanged()
self.walletType = item.getWalletType()
self.walletTypeChanged()
self.isChat = item.getIsChat()
self.isChatChanged()
self.currencyBalance = item.getCurrencyBalance()
self.currencyBalanceChanged()
self.emoji = item.getEmoji()

View File

@ -55,12 +55,6 @@ proc authenticateKeyPair*(self: Controller, keyUid = "") =
keyUid: keyUid)
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
proc getAllMigratedKeyPairs*(self: Controller): seq[KeyPairDto] =
return self.walletAccountService.getAllMigratedKeyPairs()
proc getChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().map(n => n.chainId)
proc getEnabledChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)

View File

@ -1,41 +0,0 @@
import strformat
type
DerivedAddressItem* = object
address: string
path: string
hasActivity: bool
alreadyCreated: bool
proc initDerivedAddressItem*(
address: string,
path: string,
hasActivity: bool,
alreadyCreated: bool
): DerivedAddressItem =
result.address = address
result.path = path
result.hasActivity = hasActivity
result.alreadyCreated = alreadyCreated
proc `$`*(self: DerivedAddressItem): string =
result = fmt"""DerivedAddressItem(
address: {self.address},
path: {self.path},
hasActivity: {self.hasActivity}
alreadyCreated: {self.alreadyCreated}
]"""
proc getAddress*(self: DerivedAddressItem): string =
return self.address
proc getPath*(self: DerivedAddressItem): string =
return self.path
proc getHasActivity*(self: DerivedAddressItem): bool =
return self.hasActivity
proc getAlreadyCreated*(self: DerivedAddressItem): bool =
return self.alreadyCreated

View File

@ -1,111 +0,0 @@
import NimQml, Tables, strutils, strformat
import ./derived_address_item
type
ModelRole {.pure.} = enum
Address = UserRole + 1,
Path,
HasActivity,
AlreadyCreated,
QtObject:
type
DerivedAddressModel* = ref object of QAbstractListModel
derivedWalletAddresses: seq[DerivedAddressItem]
proc delete(self: DerivedAddressModel) =
self.derivedWalletAddresses = @[]
self.QAbstractListModel.delete
proc setup(self: DerivedAddressModel) =
self.QAbstractListModel.setup
proc newDerivedAddressModel*(): DerivedAddressModel =
new(result, delete)
result.setup
proc `$`*(self: DerivedAddressModel): string =
for i in 0 ..< self.derivedWalletAddresses.len:
result &= fmt"""[{i}]:({$self.derivedWalletAddresses[i]})"""
proc countChanged(self: DerivedAddressModel) {.signal.}
proc getCount(self: DerivedAddressModel): int {.slot.} =
self.derivedWalletAddresses.len
QtProperty[int] count:
read = getCount
notify = countChanged
method rowCount(self: DerivedAddressModel, index: QModelIndex = nil): int =
return self.derivedWalletAddresses.len
method roleNames(self: DerivedAddressModel): Table[int, string] =
{
ModelRole.Address.int: "address",
ModelRole.Path.int: "path",
ModelRole.HasActivity.int: "hasActivity",
ModelRole.AlreadyCreated.int: "alreadyCreated"
}.toTable
method data(self: DerivedAddressModel, index: QModelIndex, role: int): QVariant =
if (not index.isValid):
return
if (index.row < 0 or index.row >= self.derivedWalletAddresses.len):
return
let item = self.derivedWalletAddresses[index.row]
let enumRole = role.ModelRole
case enumRole:
of ModelRole.Address:
result = newQVariant(item.getAddress())
of ModelRole.Path:
result = newQVariant(item.getPath())
of ModelRole.HasActivity:
result = newQVariant(item.getHasActivity())
of ModelRole.AlreadyCreated:
result = newQVariant(item.getAlreadyCreated())
proc setItems*(self: DerivedAddressModel, items: seq[DerivedAddressItem]) =
self.beginResetModel()
self.derivedWalletAddresses = items
self.endResetModel()
self.countChanged()
proc getDerivedAddressAtIndex*(self: DerivedAddressModel, index: int): string =
if (index < 0 or index > self.getCount()):
return
let item = self.derivedWalletAddresses[index]
result = item.getAddress()
proc getDerivedAddressPathAtIndex*(self: DerivedAddressModel, index: int): string =
if (index < 0 or index > self.getCount()):
return
let item = self.derivedWalletAddresses[index]
result = item.getPath()
proc getDerivedAddressHasActivityAtIndex*(self: DerivedAddressModel, index: int): bool =
if (index < 0 or index > self.getCount()):
return
let item = self.derivedWalletAddresses[index]
result = item.getHasActivity()
proc getDerivedAddressAlreadyCreatedAtIndex*(self: DerivedAddressModel, index: int): bool =
if (index < 0 or index > self.getCount()):
return
let item = self.derivedWalletAddresses[index]
result = item.getAlreadyCreated()
proc getNextSelectableDerivedAddressIndex*(self: DerivedAddressModel): int =
for i in 0 ..< self.derivedWalletAddresses.len:
if(not self.derivedWalletAddresses[i].getAlreadyCreated()):
return i
return -1

View File

@ -1,54 +0,0 @@
import strformat
import ./model
type
GeneratedWalletItem* = object
name: string
iconName: string
generatedModel: Model
derivedfrom: string
keyUid: string
migratedToKeycard: bool
proc initGeneratedWalletItem*(
name: string,
iconName: string,
generatedModel: Model,
derivedfrom: string,
keyUid: string,
migratedToKeycard: bool
): GeneratedWalletItem =
result.name = name
result.iconName = iconName
result.generatedModel = generatedModel
result.derivedfrom = derivedfrom
result.keyUid = keyUid
result.migratedToKeycard = migratedToKeycard
proc `$`*(self: GeneratedWalletItem): string =
result = fmt"""GeneratedWalletItem(
name: {self.name},
iconName: {self.iconName},
generatedModel: {self.generatedModel},
derivedfrom: {self.derivedfrom},
keyUid: {self.keyUid},
migratedToKeycard: {self.migratedToKeycard}
]"""
proc getName*(self: GeneratedWalletItem): string =
return self.name
proc getIconName*(self: GeneratedWalletItem): string =
return self.iconName
proc getGeneratedModel*(self: GeneratedWalletItem): Model =
return self.generatedModel
proc getDerivedfrom*(self: GeneratedWalletItem): string =
return self.derivedfrom
proc getKeyUid*(self: GeneratedWalletItem): string =
return self.keyUid
proc getMigratedToKeycard*(self: GeneratedWalletItem): bool =
return self.migratedToKeycard

View File

@ -1,84 +0,0 @@
import NimQml, Tables, strutils, strformat
import ./generated_wallet_item
type
ModelRole {.pure.} = enum
Name = UserRole + 1,
IconName,
GeneratedModel,
DerivedFrom,
KeyUid,
MigratedToKeycard
QtObject:
type
GeneratedWalletModel* = ref object of QAbstractListModel
generatedWalletItems: seq[GeneratedWalletItem]
proc delete(self: GeneratedWalletModel) =
self.generatedWalletItems = @[]
self.QAbstractListModel.delete
proc setup(self: GeneratedWalletModel) =
self.QAbstractListModel.setup
proc newGeneratedWalletModel*(): GeneratedWalletModel =
new(result, delete)
result.setup
proc `$`*(self: GeneratedWalletModel): string =
for i in 0 ..< self.generatedWalletItems.len:
result &= fmt"""[{i}]:({$self.generatedWalletItems[i]})"""
proc countChanged(self: GeneratedWalletModel) {.signal.}
proc getCount(self: GeneratedWalletModel): int {.slot.} =
self.generatedWalletItems.len
QtProperty[int] count:
read = getCount
notify = countChanged
method rowCount(self: GeneratedWalletModel, index: QModelIndex = nil): int =
return self.generatedWalletItems.len
method roleNames(self: GeneratedWalletModel): Table[int, string] =
{
ModelRole.Name.int: "name",
ModelRole.IconName.int: "iconName",
ModelRole.GeneratedModel.int: "generatedModel",
ModelRole.DerivedFrom.int: "derivedfrom",
ModelRole.KeyUid.int: "keyUid",
ModelRole.MigratedToKeycard.int: "migratedToKeycard"
}.toTable
method data(self: GeneratedWalletModel, index: QModelIndex, role: int): QVariant =
if (not index.isValid):
return
if (index.row < 0 or index.row >= self.generatedWalletItems.len):
return
let item = self.generatedWalletItems[index.row]
let enumRole = role.ModelRole
case enumRole:
of ModelRole.Name:
result = newQVariant(item.getName())
of ModelRole.IconName:
result = newQVariant(item.getIconName())
of ModelRole.GeneratedModel:
result = newQVariant(item.getGeneratedModel())
of ModelRole.DerivedFrom:
result = newQVariant(item.getDerivedFrom())
of ModelRole.KeyUid:
result = newQVariant(item.getKeyUid())
of ModelRole.MigratedToKeycard:
result = newQVariant(item.getMigratedToKeycard())
proc setItems*(self: GeneratedWalletModel, items: seq[GeneratedWalletItem]) =
self.beginResetModel()
self.generatedWalletItems = items
self.endResetModel()
self.countChanged()

View File

@ -13,9 +13,6 @@ method load*(self: AccessInterface) {.base.} =
method isLoaded*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
method syncKeycard*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method deleteAccount*(self: AccessInterface, keyUid: string, address: string) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -1,96 +1,50 @@
import strformat
import ../../../shared_models/token_model as token_model
import ../../../shared_models/currency_amount
import ./compact_model as compact_model
type
Item* = object
name: string
address: string
mixedCaseAddress: string
path: string
color: string
publicKey: string
walletType: string
isWallet: bool
isChat: bool
currencyBalance: CurrencyAmount
assets: token_model.Model
emoji: string
derivedfrom: string
relatedAccounts: compact_model.Model
keyUid: string
migratedToKeycard: bool
ens: string
assetsLoading: bool
hasBalanceCache: bool
hasMarketValuesCache: bool
proc initItem*(
name: string = "",
address: string = "",
mixedCaseAddress: string = "",
path: string = "",
color: string = "",
publicKey: string = "",
walletType: string = "",
isWallet: bool = true,
isChat: bool = false,
currencyBalance: CurrencyAmount = nil,
assets: token_model.Model = nil,
emoji: string = "",
derivedfrom: string = "",
relatedAccounts: compact_model.Model = nil,
keyUid: string = "",
migratedToKeycard: bool = false,
ens: string = "",
assetsLoading: bool = true,
hasBalanceCache: bool = false,
hasMarketValuesCache: bool = false
): Item =
result.name = name
result.address = address
result.mixedCaseAddress = mixedCaseAddress
result.path = path
result.color = color
result.publicKey = publicKey
result.walletType = walletType
result.isWallet = isWallet
result.isChat = isChat
result.currencyBalance = currencyBalance
result.assets = assets
result.emoji = emoji
result.derivedfrom = derivedfrom
result.relatedAccounts = relatedAccounts
result.keyUid = keyUid
result.migratedToKeycard = migratedToKeycard
result.ens = ens
result.assetsLoading = assetsLoading
result.hasBalanceCache = hasBalanceCache
result.hasMarketValuesCache = hasMarketValuesCache
proc `$`*(self: Item): string =
result = fmt"""WalletAccountItem(
name: {self.name},
address: {self.address},
mixedCaseAddress: {self.mixedCaseAddress},
path: {self.path},
color: {self.color},
publicKey: {self.publicKey},
walletType: {self.walletType},
isWallet: {self.isWallet},
isChat: {self.isChat},
currencyBalance: {self.currencyBalance},
assets.len: {self.assets.getCount()},
emoji: {self.emoji},
derivedfrom: {self.derivedfrom},
relatedAccounts: {self.relatedAccounts}
keyUid: {self.keyUid},
migratedToKeycard: {self.migratedToKeycard},
ens: {self.ens},
assetsLoading: {self.assetsLoading},
hasBalanceCache: {self.hasBalanceCache},
hasMarketValuesCache: {self.hasMarketValuesCache},
]"""
proc getName*(self: Item): string =
@ -99,9 +53,6 @@ proc getName*(self: Item): string =
proc getAddress*(self: Item): string =
return self.address
proc getMixedCaseAddress*(self: Item): string =
return self.mixedCaseAddress
proc getPath*(self: Item): string =
return self.path
@ -111,44 +62,14 @@ proc getEmoji*(self: Item): string =
proc getColor*(self: Item): string =
return self.color
proc getPublicKey*(self: Item): string =
return self.publicKey
proc getWalletType*(self: Item): string =
return self.walletType
proc getIsWallet*(self: Item): bool =
return self.isWallet
proc getIsChat*(self: Item): bool =
return self.isChat
proc getCurrencyBalance*(self: Item): CurrencyAmount =
return self.currencyBalance
proc getAssets*(self: Item): token_model.Model =
return self.assets
proc getDerivedFrom*(self: Item): string =
return self.derivedfrom
proc getRelatedAccounts*(self: Item): compact_model.Model =
return self.relatedAccounts
proc getKeyUid*(self: Item): string =
return self.keyUid
proc getMigratedToKeycard*(self: Item): bool =
return self.migratedToKeycard
proc getEns*(self: Item): string =
return self.ens
proc getAssetsLoading*(self: Item): bool =
return self.assetsLoading
proc getHasBalanceCache*(self: Item): bool =
return self.hasBalanceCache
proc getHasMarketValuesCache*(self: Item): bool =
return self.hasMarketValuesCache

View File

@ -10,20 +10,11 @@ type
Address,
Path,
Color,
PublicKey,
WalletType,
IsWallet,
IsChat,
CurrencyBalance,
Assets,
Emoji,
DerivedFrom,
RelatedAccounts,
KeyUid,
MigratedToKeycard,
AssetsLoading,
HasBalanceCache,
HasMarketValuesCache
QtObject:
type
@ -63,20 +54,11 @@ QtObject:
ModelRole.Address.int:"address",
ModelRole.Path.int:"path",
ModelRole.Color.int:"color",
ModelRole.PublicKey.int:"publicKey",
ModelRole.WalletType.int:"walletType",
ModelRole.IsWallet.int:"isWallet",
ModelRole.IsChat.int:"isChat",
ModelRole.Assets.int:"assets",
ModelRole.CurrencyBalance.int:"currencyBalance",
ModelRole.Emoji.int: "emoji",
ModelRole.DerivedFrom.int: "derivedfrom",
ModelRole.RelatedAccounts.int: "relatedAccounts",
ModelRole.KeyUid.int: "keyUid",
ModelRole.MigratedToKeycard.int: "migratedToKeycard",
ModelRole.AssetsLoading.int: "assetsLoading",
ModelRole.HasBalanceCache.int: "hasBalanceCache",
ModelRole.HasMarketValuesCache.int: "hasMarketValuesCache"
}.toTable
@ -105,55 +87,13 @@ QtObject:
result = newQVariant(item.getPath())
of ModelRole.Color:
result = newQVariant(item.getColor())
of ModelRole.PublicKey:
result = newQVariant(item.getPublicKey())
of ModelRole.WalletType:
result = newQVariant(item.getWalletType())
of ModelRole.IsWallet:
result = newQVariant(item.getIsWallet())
of ModelRole.IsChat:
result = newQVariant(item.getIsChat())
of ModelRole.CurrencyBalance:
result = newQVariant(item.getCurrencyBalance())
of ModelRole.Assets:
result = newQVariant(item.getAssets())
of ModelRole.Emoji:
result = newQVariant(item.getEmoji())
of ModelRole.DerivedFrom:
result = newQVariant(item.getDerivedFrom())
of ModelRole.RelatedAccounts:
result = newQVariant(item.getRelatedAccounts())
of ModelRole.KeyUid:
result = newQVariant(item.getKeyUid())
of ModelRole.MigratedToKeycard:
result = newQVariant(item.getMigratedToKeycard())
of ModelRole.AssetsLoading:
result = newQVariant(item.getAssetsLoading())
of ModelRole.HasBalanceCache:
result = newQVariant(item.getHasBalanceCache())
of ModelRole.HasMarketValuesCache:
result = newQVariant(item.getHasMarketValuesCache())
proc getAccountNameByAddress*(self: Model, address: string): string =
for account in self.items:
if(account.getAddress() == address):
return account.getName()
return ""
proc getAccountIconColorByAddress*(self: Model, address: string): string =
for account in self.items:
if(account.getAddress() == address):
return account.getColor()
return ""
proc getAccountAssetsByAddress*(self: Model, address: string): QVariant =
for account in self.items:
if(account.getAddress() == address):
return newQVariant(account.getAssets())
return nil
proc getTokenBalanceOnChain*(self: Model, address: string, chainId: int, tokenSymbol: string): CurrencyAmount =
for account in self.items:
if(account.getAddress() == address):
return account.getAssets().getTokenBalanceOnChain(chainId, tokenSymbol)
return newCurrencyAmount()

View File

@ -58,33 +58,17 @@ method delete*(self: Module) =
self.controller.delete
method refreshWalletAccounts*(self: Module) =
let keyPairMigrated = proc(migratedKeyPairs: seq[KeyPairDto], keyUid: string): bool =
for kp in migratedKeyPairs:
if kp.keyUid == keyUid:
return true
return false
let walletAccounts = self.controller.getWalletAccounts()
let migratedKeyPairs = self.controller.getAllMigratedKeyPairs()
let currency = self.controller.getCurrentCurrency()
let chainIds = self.controller.getChainIds()
let enabledChainIds = self.controller.getEnabledChainIds()
let currencyFormat = self.controller.getCurrencyFormat(currency)
let items = walletAccounts.map(w => (block:
let tokenFormats = collect(initTable()):
for t in w.tokens: {t.symbol: self.controller.getCurrencyFormat(t.symbol)}
walletAccountToItem(
w,
chainIds,
enabledChainIds,
currency,
keyPairMigrated(migratedKeyPairs, w.keyUid),
currencyFormat,
tokenFormats
)
))
@ -138,10 +122,6 @@ method viewDidLoad*(self: Module) =
self.moduleLoaded = true
self.delegate.accountsModuleDidLoad()
proc tryKeycardSync(self: Module, keyUid, pin: string) =
let dataForKeycardToSync = SharedKeycarModuleArgs(pin: pin, keyUid: keyUid)
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_TRY_KEYCARD_SYNC, dataForKeycardToSync)
proc authenticateActivityForKeyUid(self: Module, keyUid: string, reason: AuthenticationReason) =
self.authentiactionReason = reason
let keyPair = self.controller.getMigratedKeyPairByKeyUid(keyUid)

View File

@ -1,75 +1,25 @@
import tables, sequtils, sugar
import ./item
import ../../../../../app_service/service/wallet_account/dto
import ../../../../../app_service/service/token/dto as token_dto
import ../../../../../app_service/service/currency/dto as currency_dto
import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item
import ../../../shared_models/token_utils
import ../../../shared_models/currency_amount
import ../../../shared_models/currency_amount_utils
import ./compact_item as compact_item
import ./compact_model as compact_model
proc walletAccountToCompactItem*(w: WalletAccountDto, enabledChainIds: seq[int], currency: string, currencyFormat: CurrencyFormatDto) : compact_item.Item =
return compact_item.initItem(
w.name,
w.address,
w.path,
w.color,
w.publicKey,
w.walletType,
w.isWallet,
w.isChat,
currencyAmountToItem(w.getCurrencyBalance(enabledChainIds, currency), currencyFormat),
w.emoji,
w.derivedfrom)
proc walletAccountToItem*(
w: WalletAccountDto,
chainIds: seq[int],
enabledChainIds: seq[int],
currency: string,
keyPairMigrated: bool,
currencyFormat: CurrencyFormatDto,
tokenFormats: Table[string, CurrencyFormatDto],
) : item.Item =
let assets = token_model.newModel()
let relatedAccounts = compact_model.newModel()
if w.isNil:
return item.initItem()
assets.setItems(
w.tokens.map(t => walletTokenToItem(t, chainIds, enabledChainIds, currency, currencyFormat, tokenFormats[t.symbol]))
)
relatedAccounts.setItems(
w.relatedAccounts.map(x => walletAccountToCompactItem(x, enabledChainIds, currency, currencyFormat))
)
return item.initItem(
w.name,
w.address,
w.mixedCaseAddress,
w.path,
w.color,
w.publicKey,
w.walletType,
w.isWallet,
w.isChat,
currencyAmountToItem(w.getCurrencyBalance(enabledChainIds, currency), currencyFormat),
assets,
w.emoji,
w.derivedfrom,
relatedAccounts,
w.keyUid,
keyPairMigrated,
w.ens,
w.assetsLoading,
w.hasBalanceCache,
w.hasMarketValuesCache
)

View File

@ -5,191 +5,40 @@ import ../../../../../app_service/service/wallet_account/service as wallet_accou
import ./model
import ./item
import ./io_interface
import ./generated_wallet_model
import ./generated_wallet_item
import ./derived_address_model
import ./derived_address_item
const WATCH = "watch"
const GENERATED = "generated"
const SEED = "seed"
const KEY = "key"
QtObject:
type
View* = ref object of QObject
delegate: io_interface.AccessInterface
model: Model
generated: Model
watchOnly: Model
imported: Model
generatedAccounts: GeneratedWalletModel
modelVariant: QVariant
generatedVariant: QVariant
importedVariant: QVariant
watchOnlyVariant: QVariant
generatedAccountsVariant: QVariant
tmpAddress: string
tmpChainID: int # shouldn't be used anywhere except in prepareCurrencyAmount/getPreparedCurrencyAmount procs
tmpSymbol: string # shouldn't be used anywhere except in prepareCurrencyAmount/getPreparedCurrencyAmount procs
accounts: Model
accountsVariant: QVariant
proc delete*(self: View) =
self.model.delete
self.modelVariant.delete
self.imported.delete
self.importedVariant.delete
self.generated.delete
self.generatedVariant.delete
self.watchOnly.delete
self.watchOnlyVariant.delete
self.generatedAccounts.delete
self.generatedAccountsVariant.delete
self.accounts.delete
self.accountsVariant.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)
result.imported = newModel()
result.importedVariant = newQVariant(result.imported)
result.generated = newModel()
result.generatedVariant = newQVariant(result.generated)
result.watchOnly = newModel()
result.watchOnlyVariant = newQVariant(result.watchOnly)
result.generatedAccounts = newGeneratedWalletModel()
result.generatedAccountsVariant = newQVariant(result.generatedAccounts)
result.accounts = newModel()
result.accountsVariant = newQVariant(result.accounts)
proc load*(self: View) =
self.delegate.viewDidLoad()
proc modelChanged*(self: View) {.signal.}
proc accountsChanged*(self: View) {.signal.}
proc getModel(self: View): QVariant {.slot.} =
return self.modelVariant
proc getAccounts(self: View): QVariant {.slot.} =
return self.accountsVariant
QtProperty[QVariant] model:
read = getModel
notify = modelChanged
proc watchOnlyChanged*(self: View) {.signal.}
proc getWatchOnly(self: View): QVariant {.slot.} =
return self.watchOnlyVariant
QtProperty[QVariant] watchOnly:
read = getWatchOnly
notify = watchOnlyChanged
proc importedChanged*(self: View) {.signal.}
proc getImported(self: View): QVariant {.slot.} =
return self.importedVariant
QtProperty[QVariant] imported:
read = getImported
notify = importedChanged
proc generatedChanged*(self: View) {.signal.}
proc getGenereated(self: View): QVariant {.slot.} =
return self.generatedVariant
QtProperty[QVariant] generated:
read = getGenereated
notify = generatedChanged
proc generatedAccountsChanged*(self: View) {.signal.}
proc getGeneratedAccounts(self: View): QVariant {.slot.} =
return self.generatedAccountsVariant
QtProperty[QVariant] generatedAccounts:
read = getGeneratedAccounts
notify = generatedAccountsChanged
QtProperty[QVariant] accounts:
read = getAccounts
notify = accountsChanged
proc setItems*(self: View, items: seq[Item]) =
self.model.setItems(items)
var statusDefaultAccountDerivedFrom: string = ""
var importedSeedIndex: int = 1
var watchOnly: seq[Item] = @[]
var imported: seq[Item] = @[]
var generated: seq[Item] = @[]
# create a list of imported seeds/default account created from where more accounts can be derived
var generatedAccounts: seq[GeneratedWalletItem] = @[]
for item in items:
let item = item # TODO https://github.com/nim-lang/Nim/issues/16740
# Default Account
if item.getWalletType() == "":
statusDefaultAccountDerivedFrom = item.getDerivedFrom()
var generatedAccs: Model = newModel()
generatedAccs.setItems(items.filter(x => cmpIgnoreCase(x.getDerivedFrom(), item.getDerivedFrom()) == 0))
generatedAccounts.add(initGeneratedWalletItem("Default", "status", generatedAccs, item.getDerivedFrom(),
item.getKeyUid(), item.getMigratedToKeycard()))
generated.add(item)
# Account generated from profile seed phrase
elif item.getWalletType() == GENERATED and cmpIgnoreCase(item.getDerivedFrom(), statusDefaultAccountDerivedFrom) == 0 :
generated.add(item)
# Watch only accounts
elif item.getWalletType() == WATCH:
watchOnly.add(item)
# Accounts imported with Seed phrase
elif item.getWalletType() == SEED and imported.all(x => cmpIgnoreCase(x.getDerivedfrom(), item.getDerivedFrom()) != 0):
var generatedAccs1: Model = newModel()
var filterItems: seq[Item] = items.filter(x => cmpIgnoreCase(x.getDerivedFrom(), item.getDerivedFrom()) == 0)
generatedAccs1.setItems(filterItems)
generatedAccounts.add(initGeneratedWalletItem("Seed " & $importedSeedIndex , "seed-phrase", generatedAccs1, item.getDerivedFrom(),
item.getKeyUid(), item.getMigratedToKeycard()))
imported.add(item)
importedSeedIndex += 1
# Accounts imported with Key OR accounts generated from a seed thats not the profile seed
else:
imported.add(item)
self.watchOnly.setItems(watchOnly)
self.imported.setItems(imported)
self.generated.setItems(generated)
self.generatedAccounts.setItems(generatedAccounts)
self.accounts.setItems(items)
proc deleteAccount*(self: View, keyUid: string, address: string) {.slot.} =
self.delegate.deleteAccount(keyUid, address)
proc getAccountNameByAddress*(self: View, address: string): string {.slot.} =
return self.model.getAccountNameByAddress(address)
proc getAccountIconColorByAddress*(self: View, address: string): string {.slot.} =
return self.model.getAccountIconColorByAddress(address)
proc setAddressForAssets*(self: View, address: string) {.slot.} =
self.tmpAddress = address
proc getAccountAssetsByAddress*(self: View): QVariant {.slot.} =
self.tmpAddress = ""
return self.model.getAccountAssetsByAddress(self.tmpAddress)
# Returning a QVariant from a slot with parameters other than "self" won't compile
#proc getTokenBalanceOnChain*(self: View, chainId: int, tokenSymbol: string): QVariant {.slot.} =
# return newQVariant(self.assets.getTokenBalanceOnChain(chainId, tokenSymbol))
# As a workaround, we do it in two steps: First call prepareTokenBalanceOnChain, then getPreparedTokenBalanceOnChain
proc prepareTokenBalanceOnChain*(self: View, address: string, chainId: int, tokenSymbol: string) {.slot.} =
self.tmpAddress = address
self.tmpChainId = chainId
self.tmpSymbol = tokenSymbol
proc getPreparedTokenBalanceOnChain*(self: View): QVariant {.slot.} =
let currencyAmount = self.model.getTokenBalanceOnChain(self.tmpAddress, self.tmpChainId, self.tmpSymbol)
self.tmpAddress = ""
self.tmpChainId = 0
self.tmpSymbol = "ERROR"
return newQVariant(currencyAmount)

View File

@ -1,5 +1,4 @@
import strformat
import ../../../shared_models/currency_amount
type
@ -8,38 +7,38 @@ type
address: string
path: string
color: string
publicKey: string
walletType: string
isWallet: bool
isChat: bool
currencyBalance: CurrencyAmount
emoji: string
derivedfrom: string
keyUid: string
assetsLoading: bool
hasBalanceCache: bool
hasMarketValuesCache: bool
proc initItem*(
name: string,
address: string,
path: string,
color: string,
publicKey: string,
walletType: string,
isWallet: bool,
isChat: bool,
currencyBalance: CurrencyAmount,
emoji: string,
derivedfrom: string
name: string = "",
address: string = "",
path: string = "",
color: string = "",
walletType: string = "",
currencyBalance: CurrencyAmount = nil,
emoji: string = "",
keyUid: string = "",
assetsLoading: bool = true,
hasBalanceCache: bool = false,
hasMarketValuesCache: bool = false
): Item =
result.name = name
result.address = address
result.path = path
result.color = color
result.publicKey = publicKey
result.walletType = walletType
result.isWallet = isWallet
result.isChat = isChat
result.currencyBalance = currencyBalance
result.emoji = emoji
result.derivedfrom = derivedfrom
result.keyUid = keyUid
result.assetsLoading = assetsLoading
result.hasBalanceCache = hasBalanceCache
result.hasMarketValuesCache = hasMarketValuesCache
proc `$`*(self: Item): string =
result = fmt"""WalletAccountItem(
@ -47,13 +46,13 @@ proc `$`*(self: Item): string =
address: {self.address},
path: {self.path},
color: {self.color},
publicKey: {self.publicKey},
walletType: {self.walletType},
isWallet: {self.isWallet},
isChat: {self.isChat},
currencyBalance: {self.currencyBalance},
emoji: {self.emoji},
derivedfrom: {self.derivedfrom}
keyUid: {self.keyUid},
assetsLoading: {self.assetsLoading},
hasBalanceCache: {self.hasBalanceCache},
hasMarketValuesCache: {self.hasMarketValuesCache},
]"""
proc getName*(self: Item): string =
@ -71,21 +70,20 @@ proc getEmoji*(self: Item): string =
proc getColor*(self: Item): string =
return self.color
proc getPublicKey*(self: Item): string =
return self.publicKey
proc getWalletType*(self: Item): string =
return self.walletType
proc getIsWallet*(self: Item): bool =
return self.isWallet
proc getIsChat*(self: Item): bool =
return self.isChat
proc getCurrencyBalance*(self: Item): CurrencyAmount =
return self.currencyBalance
proc getDerivedFrom*(self: Item): string =
return self.derivedfrom
proc getKeyUid*(self: Item): string =
return self.keyUid
proc getAssetsLoading*(self: Item): bool =
return self.assetsLoading
proc getHasBalanceCache*(self: Item): bool =
return self.hasBalanceCache
proc getHasMarketValuesCache*(self: Item): bool =
return self.hasMarketValuesCache

View File

@ -14,9 +14,8 @@ import ../../../shared_models/currency_amount
import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item
import ../../../shared_models/token_utils
import ../accounts/compact_item as account_compact_item
import ../accounts/item as account_item
import ../accounts/utils
import ./item as account_item
import ./utils
import ./io_interface, ./view, ./controller
import ../io_interface as delegate_interface
@ -149,12 +148,9 @@ method switchAccount*(self: Module, accountIndex: int) =
let defaultAccountItem = walletAccountToItem(
defaultAccount,
chainIds,
enabledChainIds,
currency,
keyPairMigrated(migratedKeyPairs, defaultAccount.keyUid),
currencyFormat,
defaultAccountTokenFormats
)
self.view.setDefaultWalletAccount(defaultAccountItem)
@ -166,12 +162,9 @@ method switchAccount*(self: Module, accountIndex: int) =
let accountItem = walletAccountToItem(
walletAccount,
chainIds,
enabledChainIds,
currency,
keyPairMigrated(migratedKeyPairs, walletAccount.keyUid),
currencyFormat,
accountTokenFormats
)
self.view.setData(accountItem)

View File

@ -0,0 +1,25 @@
import ./item
import ../../../../../app_service/service/wallet_account/dto
import ../../../../../app_service/service/currency/dto as currency_dto
import ../../../shared_models/currency_amount
import ../../../shared_models/currency_amount_utils
proc walletAccountToItem*(
w: WalletAccountDto,
enabledChainIds: seq[int],
currency: string,
currencyFormat: CurrencyFormatDto,
) : item.Item =
return item.initItem(
w.name,
w.address,
w.path,
w.color,
w.walletType,
currencyAmountToItem(w.getCurrencyBalance(enabledChainIds, currency), currencyFormat),
w.emoji,
w.keyUid,
w.assetsLoading,
)

View File

@ -4,10 +4,8 @@ import ./io_interface
import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item
import ../../../shared_models/currency_amount
import ../accounts/compact_model
import ../accounts/compact_item
import ../accounts/item as account_item
import ./item as account_item
const GENERATED = "generated"
const GENERATED_FROM_IMPORTED = "generated from imported accounts"
@ -20,20 +18,12 @@ QtObject:
name: string
keyUid: string
address: string
mixedcaseAddress: string
path: string
color: string
publicKey: string
walletType: string
isChat: bool
currencyBalance: CurrencyAmount
assets: token_model.Model
emoji: string
derivedfrom: string
relatedAccounts: compact_model.Model
ens: string
tmpChainID: int # shouldn't be used anywhere except in prepareCurrencyAmount/getPreparedCurrencyAmount procs
tmpSymbol: string # shouldn't be used anywhere except in prepareCurrencyAmount/getPreparedCurrencyAmount procs
assetsLoading: bool
hasBalanceCache: bool
hasMarketValuesCache: bool
@ -77,13 +67,6 @@ QtObject:
read = getAddress
notify = addressChanged
proc getMixedcaseAddress(self: View): string {.slot.} =
return self.mixedcaseAddress
proc mixedcaseAddressChanged(self: View) {.signal.}
QtProperty[string] mixedcaseAddress:
read = getMixedcaseAddress
notify = mixedcaseAddressChanged
proc getPath(self: View): QVariant {.slot.} =
return newQVariant(self.path)
@ -102,15 +85,6 @@ QtObject:
read = getColor
notify = colorChanged
proc getPublicKey(self: View): QVariant {.slot.} =
return newQVariant(self.publicKey)
proc publicKeyChanged(self: View) {.signal.}
QtProperty[QVariant] publicKey:
read = getPublicKey
notify = publicKeyChanged
proc getWalletType(self: View): QVariant {.slot.} =
return newQVariant(self.walletType)
@ -120,15 +94,6 @@ QtObject:
read = getWalletType
notify = walletTypeChanged
proc getIsChat(self: View): QVariant {.slot.} =
return newQVariant(self.isChat)
proc isChatChanged(self: View) {.signal.}
QtProperty[QVariant] isChat:
read = getIsChat
notify = isChatChanged
proc currencyBalanceChanged(self: View) {.signal.}
proc getCurrencyBalance*(self: View): QVariant {.slot.} =
return newQVariant(self.currencyBalance)
@ -158,33 +123,6 @@ QtObject:
read = getEmoji
notify = emojiChanged
proc getEns(self: View): QVariant {.slot.} =
return newQVariant(self.ens)
proc ensChanged(self: View) {.signal.}
QtProperty[QVariant] ens:
read = getEns
notify = ensChanged
proc getDerivedfrom(self: View): QVariant {.slot.} =
return newQVariant(self.derivedfrom)
proc derivedfromChanged(self: View) {.signal.}
QtProperty[QVariant] derivedfrom:
read = getDerivedfrom
notify = derivedfromChanged
proc getRelatedAccounts(self: View): QVariant {.slot.} =
return newQVariant(self.relatedAccounts)
proc relatedAccountsChanged(self: View) {.signal.}
QtProperty[QVariant] relatedAccounts:
read = getRelatedAccounts
notify = relatedAccountsChanged
proc getAssetsLoading(self: View): QVariant {.slot.} =
return newQVariant(self.assetsLoading)
proc assetsLoadingChanged(self: View) {.signal.}
@ -227,46 +165,23 @@ QtObject:
if(self.address != item.getAddress()):
self.address = item.getAddress()
self.addressChanged()
if(self.mixedcaseAddress != item.getMixedCaseAddress()):
self.mixedcaseAddress = item.getMixedCaseAddress()
self.mixedcaseAddressChanged()
if(self.path != item.getPath()):
self.path = item.getPath()
self.pathChanged()
if(self.color != item.getColor()):
self.color = item.getColor()
self.colorChanged()
if(self.publicKey != item.getPublicKey()):
self.publicKey = item.getPublicKey()
self.publicKeyChanged()
# Check if the account is generated from default wallet account else change wallettype
if item.getWalletType() == GENERATED and item.getDerivedfrom() != self.defaultAccount.getDerivedfrom():
self.walletType = GENERATED_FROM_IMPORTED
self.walletTypeChanged()
else:
if(self.walletType != item.getWalletType()):
self.walletType = item.getWalletType()
self.walletTypeChanged()
if(self.isChat != item.getIsChat()):
self.isChat = item.getIsChat()
self.isChatChanged()
if(self.emoji != item.getEmoji()):
self.emoji = item.getEmoji()
self.emojiChanged()
if(self.derivedfrom != item.getDerivedFrom()):
self.derivedfrom = item.getDerivedFrom()
self.derivedfromChanged()
if(self.ens != item.getEns()):
self.ens = item.getEns()
self.ensChanged()
self.setAssetsLoading(item.getAssetsLoading())
self.hasBalanceCache = item.getHasBalanceCache()
self.hasBalanceCacheChanged()
self.hasMarketValuesCache = item.getHasMarketValuesCache()
self.hasMarketValuesCacheChanged()
# Set related accounts
self.relatedAccounts = item.getRelatedAccounts()
self.relatedAccountsChanged()
proc findTokenSymbolByAddress*(self: View, address: string): string {.slot.} =
return self.delegate.findTokenSymbolByAddress(address)
@ -274,21 +189,6 @@ QtObject:
proc hasGas*(self: View, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.slot.} =
return self.assets.hasGas(chainId, nativeGasSymbol, requiredGas)
# Returning a QVariant from a slot with parameters other than "self" won't compile
#proc getTokenBalanceOnChain*(self: View, chainId: int, tokenSymbol: string): QVariant {.slot.} =
# return newQVariant(self.assets.getTokenBalanceOnChain(chainId, tokenSymbol))
# As a workaround, we do it in two steps: First call prepareTokenBalanceOnChain, then getPreparedTokenBalanceOnChain
proc prepareTokenBalanceOnChain*(self: View, chainId: int, tokenSymbol: string) {.slot.} =
self.tmpChainId = chainId
self.tmpSymbol = tokenSymbol
proc getPreparedTokenBalanceOnChain*(self: View): QVariant {.slot.} =
let currencyAmount = self.assets.getTokenBalanceOnChain(self.tmpChainId, self.tmpSymbol)
self.tmpChainId = 0
self.tmpSymbol = "ERROR"
return newQVariant(currencyAmount)
proc setCacheValues*(self: View, hasBalanceCache: bool, hasMarketValuesCache: bool) =
self.hasBalanceCache = hasBalanceCache
self.hasBalanceCacheChanged()

View File

@ -58,6 +58,9 @@ method savedAddressesModuleDidLoad*(self: AccessInterface) {.base.} =
method buySellCryptoModuleDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method sendModuleDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method overviewModuleDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -13,6 +13,7 @@ import ./saved_addresses/module as saved_addresses_module
import ./buy_sell_crypto/module as buy_sell_crypto_module
import ./add_account/module as add_account_module
import ./overview/module as overview_module
import ./send/module as send_module
import ../../../global/global_singleton
import ../../../core/eventemitter
@ -47,6 +48,7 @@ type
allTokensModule: all_tokens_module.AccessInterface
collectiblesModule: collectibles_module.AccessInterface
assetsModule: assets_module.AccessInterface
sendModule: send_module.AccessInterface
transactionsModule: transactions_module.AccessInterface
savedAddressesModule: saved_addresses_module.AccessInterface
buySellCryptoModule: buy_sell_crypto_module.AccessInterface
@ -87,6 +89,7 @@ proc newModule*(
result.collectiblesModule = collectibles_module.newModule(result, events, collectibleService, walletAccountService, networkService, nodeService, networkConnectionService)
result.assetsModule = assets_module.newModule(result, events, walletAccountService, networkService, tokenService, currencyService, collectibleService)
result.transactionsModule = transactions_module.newModule(result, events, transactionService, walletAccountService, networkService, currencyService)
result.sendModule = send_module.newModule(result, events, walletAccountService, networkService, currencyService, transactionService)
result.savedAddressesModule = saved_addresses_module.newModule(result, events, savedAddressService)
result.buySellCryptoModule = buy_sell_crypto_module.newModule(result, events, transactionService)
result.overviewModule = overview_module.newModule(result, events, walletAccountService, networkService, currencyService)
@ -99,6 +102,7 @@ method delete*(self: Module) =
self.transactionsModule.delete
self.savedAddressesModule.delete
self.buySellCryptoModule.delete
self.sendModule.delete
self.controller.delete
self.view.delete
if not self.addAccountModule.isNil:
@ -151,6 +155,7 @@ method load*(self: Module) =
self.savedAddressesModule.load()
self.buySellCryptoModule.load()
self.overviewModule.load()
self.sendModule.load()
method isLoaded*(self: Module): bool =
return self.moduleLoaded
@ -180,6 +185,9 @@ proc checkIfModuleDidLoad(self: Module) =
if(not self.overviewModule.isLoaded()):
return
if(not self.sendModule.isLoaded()):
return
self.switchAccount(0)
let currency = self.controller.getCurrency()
let signingPhrase = self.controller.getSigningPhrase()
@ -217,6 +225,9 @@ method buySellCryptoModuleDidLoad*(self: Module) =
method overviewModuleDidLoad*(self: Module) =
self.checkIfModuleDidLoad()
method sendModuleDidLoad*(self: Module) =
self.checkIfModuleDidLoad()
method destroyAddAccountPopup*(self: Module, switchToAccWithAddress: string = "") =
if not self.addAccountModule.isNil:
if switchToAccWithAddress.len > 0:

View File

@ -0,0 +1,63 @@
import strformat
import ../../../shared_models/token_model as token_model
import ../../../shared_models/currency_amount
type
AccountItem* = object
name: string
address: string
color: string
walletType: string
emoji: string
assets: token_model.Model
currencyBalance: CurrencyAmount
proc initAccountItem*(
name: string = "",
address: string = "",
color: string = "",
walletType: string = "",
emoji: string = "",
assets: token_model.Model = nil,
currencyBalance: CurrencyAmount = nil,
): AccountItem =
result.name = name
result.address = address
result.color = color
result.walletType = walletType
result.emoji = emoji
result.assets = assets
result.currencyBalance = currencyBalance
proc `$`*(self: AccountItem): string =
result = fmt"""WalletAccountItem(
name: {self.name},
address: {self.address},
color: {self.color},
walletType: {self.walletType},
emoji: {self.emoji},
assets: {self.assets},
currencyBalance: {self.currencyBalance},
]"""
proc getName*(self: AccountItem): string =
return self.name
proc getAddress*(self: AccountItem): string =
return self.address
proc getEmoji*(self: AccountItem): string =
return self.emoji
proc getColor*(self: AccountItem): string =
return self.color
proc getWalletType*(self: AccountItem): string =
return self.walletType
proc getAssets*(self: AccountItem): token_model.Model =
return self.assets
proc getCurrencyBalance*(self: AccountItem): CurrencyAmount =
return self.currencyBalance

View File

@ -1,76 +1,70 @@
import NimQml, Tables, strutils, strformat, sequtils
import NimQml, Tables, strutils, strformat
import ./compact_item
import ./account_item
import ../../../shared_models/currency_amount
import ../../../shared_models/token_model
type
ModelRole {.pure.} = enum
Name = UserRole + 1,
Address,
Path,
Color,
PublicKey,
WalletType,
IsWallet,
IsChat,
CurrencyBalance,
Emoji,
DerivedFrom,
Assets,
CurrencyBalance,
QtObject:
type
Model* = ref object of QAbstractListModel
items: seq[Item]
AccountsModel* = ref object of QAbstractListModel
items: seq[AccountItem]
proc delete(self: Model) =
proc delete(self: AccountsModel) =
self.items = @[]
self.QAbstractListModel.delete
proc setup(self: Model) =
proc setup(self: AccountsModel) =
self.QAbstractListModel.setup
proc newModel*(): Model =
proc newAccountsModel*(): AccountsModel =
new(result, delete)
result.setup
proc `$`*(self: Model): string =
proc `$`*(self: AccountsModel): string =
for i in 0 ..< self.items.len:
result &= fmt"""[{i}]:({$self.items[i]})"""
proc countChanged(self: Model) {.signal.}
proc countChanged(self: AccountsModel) {.signal.}
proc getCount*(self: Model): int {.slot.} =
proc getCount*(self: AccountsModel): int {.slot.} =
self.items.len
QtProperty[int] count:
read = getCount
notify = countChanged
method rowCount(self: Model, index: QModelIndex = nil): int =
method rowCount(self: AccountsModel, index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: Model): Table[int, string] =
method roleNames(self: AccountsModel): Table[int, string] =
{
ModelRole.Name.int:"name",
ModelRole.Address.int:"address",
ModelRole.Path.int:"path",
ModelRole.Color.int:"color",
ModelRole.PublicKey.int:"publicKey",
ModelRole.WalletType.int:"walletType",
ModelRole.IsWallet.int:"isWallet",
ModelRole.IsChat.int:"isChat",
ModelRole.CurrencyBalance.int:"currencyBalance",
ModelRole.Emoji.int: "emoji",
ModelRole.DerivedFrom.int: "derivedfrom",
ModelRole.Assets.int: "assets",
ModelRole.CurrencyBalance.int: "currencyBalance",
}.toTable
proc setItems*(self: Model, items: seq[Item]) =
proc setItems*(self: AccountsModel, items: seq[AccountItem]) =
self.beginResetModel()
self.items = items
self.endResetModel()
self.countChanged()
method data(self: Model, index: QModelIndex, role: int): QVariant =
method data(self: AccountsModel, index: QModelIndex, role: int): QVariant =
if (not index.isValid):
return
@ -85,21 +79,14 @@ QtObject:
result = newQVariant(item.getName())
of ModelRole.Address:
result = newQVariant(item.getAddress())
of ModelRole.Path:
result = newQVariant(item.getPath())
of ModelRole.Color:
result = newQVariant(item.getColor())
of ModelRole.PublicKey:
result = newQVariant(item.getPublicKey())
of ModelRole.WalletType:
result = newQVariant(item.getWalletType())
of ModelRole.IsWallet:
result = newQVariant(item.getIsWallet())
of ModelRole.IsChat:
result = newQVariant(item.getIsChat())
of ModelRole.CurrencyBalance:
result = newQVariant(item.getCurrencyBalance())
of ModelRole.Emoji:
result = newQVariant(item.getEmoji())
of ModelRole.DerivedFrom:
result = newQVariant(item.getDerivedFrom())
of ModelRole.Assets:
result = newQVariant(item.getAssets())
of ModelRole.CurrencyBalance:
result = newQVariant(item.getCurrencyBalance())

View File

@ -0,0 +1,101 @@
import sugar, sequtils, tables, stint, json, json_serialization
import io_interface
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/network/service as network_service
import ../../../../../app_service/service/transaction/service as transaction_service
import ../../../../../app_service/service/currency/service as currency_service
import ../../../../../app_service/service/currency/dto as currency_dto
import ../../../../global/global_singleton
import ../../../shared_modules/keycard_popup/io_interface as keycard_shared_module
import ../../../shared_models/currency_amount
import ../../../shared_models/currency_amount_utils
import ../../../../core/eventemitter
const UNIQUE_WALLET_SECTION_SEND_MODULE_IDENTIFIER* = "WalletSection-SendModule"
type
Controller* = ref object of RootObj
delegate: io_interface.AccessInterface
events: EventEmitter
walletAccountService: wallet_account_service.Service
networkService: network_service.Service
currencyService: currency_service.Service
transactionService: transaction_service.Service
proc newController*(
delegate: io_interface.AccessInterface,
events: EventEmitter,
walletAccountService: wallet_account_service.Service,
networkService: network_service.Service,
currencyService: currency_service.Service,
transactionService: transaction_service.Service,
): Controller =
result = Controller()
result.delegate = delegate
result.events = events
result.walletAccountService = walletAccountService
result.networkService = networkService
result.currencyService = currencyService
result.transactionService = transactionService
proc delete*(self: Controller) =
discard
proc init*(self: Controller) =
self.events.on(SIGNAL_TRANSACTION_SENT) do(e:Args):
self.delegate.transactionWasSent(TransactionSentArgs(e).result)
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
let args = SharedKeycarModuleArgs(e)
if args.uniqueIdentifier != UNIQUE_WALLET_SECTION_SEND_MODULE_IDENTIFIER:
return
self.delegate.onUserAuthenticated(args.password)
self.events.on(SIGNAL_SUGGESTED_ROUTES_READY) do(e:Args):
self.delegate.suggestedRoutesReady(SuggestedRoutesArgs(e).suggestedRoutes)
proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
return self.walletAccountService.getWalletAccounts()
proc getChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().map(n => n.chainId)
proc getEnabledChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)
proc getCurrentCurrency*(self: Controller): string =
return self.walletAccountService.getCurrency()
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
return self.currencyService.getCurrencyFormat(symbol)
proc getMigratedKeyPairByKeyUid*(self: Controller, keyUid: string): seq[KeyPairDto] =
return self.walletAccountService.getMigratedKeyPairByKeyUid(keyUid)
proc getWalletAccount*(self: Controller, address: string): WalletAccountDto =
return self.walletAccountService.getAccountByAddress(address)
proc getTokenBalanceOnChain*(self: Controller, address: string, chainId: int, symbol: string): CurrencyAmount =
return currencyAmountToItem(self.walletAccountService.getTokenBalanceOnChain(address, chainId, symbol), self.currencyService.getCurrencyFormat(symbol))
proc authenticateUser*(self: Controller, keyUid = "") =
let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_WALLET_SECTION_SEND_MODULE_IDENTIFIER,
keyUid: keyUid)
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
proc getEstimatedTime*(self: Controller, chainId: int, maxFeePerGas: string): EstimatedTime =
return self.transactionService.getEstimatedTime(chainId, maxFeePerGas)
proc suggestedRoutes*(self: Controller, account: string, amount: Uint256, token: string, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[uint64], sendType: int, lockedInAmounts: string): string =
let suggestedRoutes = self.transactionService.suggestedRoutes(account, amount, token, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts)
return suggestedRoutes.toJson()
proc transfer*(self: Controller, from_addr: string, to_addr: string, tokenSymbol: string,
value: string, uuid: string, selectedRoutes: string, password: string) =
self.transactionService.transfer(from_addr, to_addr, tokenSymbol, value, uuid, selectedRoutes, password)
proc suggestedFees*(self: Controller, chainId: int): string =
let suggestedFees = self.transactionService.suggestedFees(chainId)
return suggestedFees.toJson()

View File

@ -0,0 +1,59 @@
import stint
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../shared_models/currency_amount
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 deleteAccount*(self: AccessInterface, keyUid: string, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
method refreshWalletAccounts*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getTokenBalanceOnChain*(self: AccessInterface, address: string, chainId: int, symbol: string): CurrencyAmount {.base.} =
raise newException(ValueError, "No implementation available")
method suggestedRoutes*(self: AccessInterface, account: string, amount: UInt256, token: string, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[uint64], sendType: int, lockedInAmounts: string): string {.base.} =
raise newException(ValueError, "No implementation available")
method suggestedRoutesReady*(self: AccessInterface, suggestedRoutes: string) {.base.} =
raise newException(ValueError, "No implementation available")
method getEstimatedTime*(self: AccessInterface, chainId: int, maxFeePerGas: string): int {.base.} =
raise newException(ValueError, "No implementation available")
method suggestedFees*(self: AccessInterface, chainId: int): string {.base.} =
raise newException(ValueError, "No implementation available")
method authenticateAndTransfer*(self: AccessInterface, from_addr: string, to_addr: string,
tokenSymbol: string, value: string, uuid: string, selectedRoutes: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onUserAuthenticated*(self: AccessInterface, password: string) {.base.} =
raise newException(ValueError, "No implementation available")
method transactionWasSent*(self: AccessInterface, result: string) {.base.} =
raise newException(ValueError, "No implementation available")
# View Delegate Interface
# Delegate for the view must be declared here due to use of QtObject and multi
# inheritance, which is not well supported in Nim.
method viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method authenticateUser*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method onUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,189 @@
import tables, NimQml, sequtils, sugar, chronicles, json, stint
import ./io_interface, ./view, ./account_item, ./controller, ./utils
import ../io_interface as delegate_interface
import ../../../../global/global_singleton
import ../../../../core/eventemitter
import ../../../../../app_service/common/account_constants
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/network/service as network_service
import ../../../../../app_service/service/currency/service as currency_service
import ../../../../../app_service/service/transaction/service as transaction_service
export io_interface
const cancelledRequest* = "cancelled"
# Shouldn't be public ever, use only within this module.
type TmpSendTransactionDetails = object
fromAddr: string
toAddr: string
tokenSymbol: string
value: string
uuid: string
selectedRoutes: string
type
Module* = ref object of io_interface.AccessInterface
delegate: delegate_interface.AccessInterface
events: EventEmitter
view: View
controller: Controller
moduleLoaded: bool
tmpSendTransactionDetails: TmpSendTransactionDetails
proc newModule*(
delegate: delegate_interface.AccessInterface,
events: EventEmitter,
walletAccountService: wallet_account_service.Service,
networkService: network_service.Service,
currencyService: currency_service.Service,
transactionService: transaction_service.Service,
): Module =
result = Module()
result.delegate = delegate
result.events = events
result.view = newView(result)
result.controller = controller.newController(result, events, walletAccountService, networkService, currencyService, transactionService)
result.moduleLoaded = false
method delete*(self: Module) =
self.view.delete
self.controller.delete
method refreshWalletAccounts*(self: Module) =
let walletAccounts = self.controller.getWalletAccounts()
let currency = self.controller.getCurrentCurrency()
let enabledChainIds = self.controller.getEnabledChainIds()
let currencyFormat = self.controller.getCurrencyFormat(currency)
let chainIds = self.controller.getChainIds()
let items = walletAccounts.map(w => (block:
let tokenFormats = collect(initTable()):
for t in w.tokens: {t.symbol: self.controller.getCurrencyFormat(t.symbol)}
walletAccountToItem(
w,
chainIds,
enabledChainIds,
currency,
currencyFormat,
tokenFormats,
)
))
self.view.setItems(items)
method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("walletSectionSend", newQVariant(self.view))
# these connections should be part of the controller's init method
self.events.on(SIGNAL_WALLET_ACCOUNT_SAVED) do(e:Args):
self.refreshWalletAccounts()
self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e:Args):
self.refreshWalletAccounts()
self.events.on(SIGNAL_WALLET_ACCOUNT_CURRENCY_UPDATED) do(e:Args):
self.refreshWalletAccounts()
self.events.on(SIGNAL_WALLET_ACCOUNT_UPDATED) do(e:Args):
self.refreshWalletAccounts()
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e:Args):
self.refreshWalletAccounts()
self.events.on(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT) do(e:Args):
self.refreshWalletAccounts()
self.events.on(SIGNAL_CURRENCY_FORMATS_UPDATED) do(e:Args):
self.refreshWalletAccounts()
self.events.on(SIGNAL_NEW_KEYCARD_SET) do(e: Args):
let args = KeycardActivityArgs(e)
if not args.success:
return
self.refreshWalletAccounts()
self.events.on(SIGNAL_KEYCARDS_SYNCHRONIZED) do(e: Args):
let args = KeycardActivityArgs(e)
if not args.success:
return
self.refreshWalletAccounts()
self.controller.init()
self.view.load()
method isLoaded*(self: Module): bool =
return self.moduleLoaded
method viewDidLoad*(self: Module) =
self.refreshWalletAccounts()
self.moduleLoaded = true
self.delegate.sendModuleDidLoad()
method getTokenBalanceOnChain*(self: Module, address: string, chainId: int, symbol: string): CurrencyAmount =
return self.controller.getTokenBalanceOnChain(address, chainId, symbol)
method authenticateAndTransfer*(
self: Module, from_addr: string, to_addr: string, tokenSymbol: string, value: string, uuid: string, selectedRoutes: string
) =
self.tmpSendTransactionDetails.fromAddr = from_addr
self.tmpSendTransactionDetails.toAddr = to_addr
self.tmpSendTransactionDetails.tokenSymbol = tokenSymbol
self.tmpSendTransactionDetails.value = value
self.tmpSendTransactionDetails.uuid = uuid
self.tmpSendTransactionDetails.selectedRoutes = selectedRoutes
if singletonInstance.userProfile.getIsKeycardUser():
let keyUid = singletonInstance.userProfile.getKeyUid()
self.controller.authenticateUser(keyUid)
else:
self.controller.authenticateUser()
##################################
## Do Not Delete
##
## Once we start with signing a transactions we shold check if the address we want to send a transaction from is migrated
## or not. In case it's not we should just authenticate logged in user, otherwise we should use one of the keycards that
## address (key pair) is migrated to and sign the transaction using it.
##
## The code bellow is an example how we can achieve that in future, when we start with signing transactions.
##
## let acc = self.controller.getAccountByAddress(from_addr)
## if acc.isNil:
## echo "error: selected account to send a transaction from is not known"
## return
## let keyPair = self.controller.getMigratedKeyPairByKeyUid(acc.keyUid)
## if keyPair.len == 0:
## self.controller.authenticateUser()
## else:
## self.controller.authenticateUser(acc.keyUid, acc.path)
##
##################################
method onUserAuthenticated*(self: Module, password: string) =
if password.len == 0:
let response = %* {"uuid": self.tmpSendTransactionDetails.uuid, "success": false, "error": cancelledRequest}
self.view.transactionWasSent($response)
else:
self.controller.transfer(
self.tmpSendTransactionDetails.fromAddr, self.tmpSendTransactionDetails.toAddr,
self.tmpSendTransactionDetails.tokenSymbol, self.tmpSendTransactionDetails.value, self.tmpSendTransactionDetails.uuid,
self.tmpSendTransactionDetails.selectedRoutes, password
)
method transactionWasSent*(self: Module, result: string) =
self.view.transactionWasSent(result)
method suggestedFees*(self: Module, chainId: int): string =
return self.controller.suggestedFees(chainId)
method suggestedRoutes*(self: Module, account: string, amount: UInt256, token: string, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[uint64], sendType: int, lockedInAmounts: string): string =
return self.controller.suggestedRoutes(account, amount, token, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts)
method suggestedRoutesReady*(self: Module, suggestedRoutes: string) =
self.view.suggestedRoutesReady(suggestedRoutes)
method getEstimatedTime*(self: Module, chainId: int, maxFeePerGas: string): int =
return self.controller.getEstimatedTime(chainId, maxFeePerGas).int

View File

@ -0,0 +1,32 @@
import Tables, sequtils, sugar
import ./account_item
import ../../../../../app_service/service/wallet_account/dto
import ../../../../../app_service/service/currency/dto as currency_dto
import ../../../shared_models/currency_amount
import ../../../shared_models/currency_amount_utils
import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item
import ../../../shared_models/token_utils
proc walletAccountToItem*(
w: WalletAccountDto,
chainIds: seq[int],
enabledChainIds: seq[int],
currency: string,
currencyFormat: CurrencyFormatDto,
tokenFormats: Table[string, CurrencyFormatDto],
) : account_item.AccountItem =
let assets = token_model.newModel()
assets.setItems(
w.tokens.map(t => walletTokenToItem(t, chainIds, enabledChainIds, currency, currencyFormat, tokenFormats[t.symbol]))
)
return account_item.initAccountItem(
w.name,
w.address,
w.color,
w.walletType,
w.emoji,
assets,
currencyAmountToItem(w.getCurrencyBalance(enabledChainIds, currency), currencyFormat),
)

View File

@ -0,0 +1,105 @@
import NimQml, sequtils, strutils, sugar, stint
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ./accounts_model
import ./account_item
import ./io_interface
QtObject:
type
View* = ref object of QObject
delegate: io_interface.AccessInterface
accounts: AccountsModel
accountsVariant: QVariant
tmpAddress: string # shouldn't be used anywhere except in prepare*/getPrepared* procs
tmpSymbol: string # shouldn't be used anywhere except in prepare*/getPrepared* procs
tmpChainID: int # shouldn't be used anywhere except in prepare*/getPrepared* procs
proc delete*(self: View) =
self.accounts.delete
self.accountsVariant.delete
self.QObject.delete
proc newView*(delegate: io_interface.AccessInterface): View =
new(result, delete)
result.QObject.setup
result.delegate = delegate
result.accounts = newAccountsModel()
result.accountsVariant = newQVariant(result.accounts)
proc load*(self: View) =
self.delegate.viewDidLoad()
proc accountsChanged*(self: View) {.signal.}
proc getAccounts(self: View): QVariant {.slot.} =
return self.accountsVariant
QtProperty[QVariant] accounts:
read = getAccounts
notify = accountsChanged
proc setItems*(self: View, items: seq[AccountItem]) =
self.accounts.setItems(items)
proc prepareTokenBalanceOnChain*(self: View, address: string, chainId: int, tokenSymbol: string) {.slot.} =
self.tmpAddress = address
self.tmpChainId = chainId
self.tmpSymbol = tokenSymbol
proc getPreparedTokenBalanceOnChain*(self: View): QVariant {.slot.} =
let currencyAmount = self.delegate.getTokenBalanceOnChain(self.tmpAddress, self.tmpChainId, self.tmpSymbol)
self.tmpAddress = ""
self.tmpChainId = 0
self.tmpSymbol = "ERROR"
return newQVariant(currencyAmount)
proc transactionSent*(self: View, txResult: string) {.signal.}
proc transactionWasSent*(self: View,txResult: string) {.slot} =
self.transactionSent(txResult)
proc authenticateAndTransfer*(self: View, from_addr: string, to_addr: string, tokenSymbol: string,
value: string, uuid: string, selectedRoutes: string) {.slot.} =
self.delegate.authenticateAndTransfer(from_addr, to_addr, tokenSymbol, value, uuid, selectedRoutes)
proc suggestedFees*(self: View, chainId: int): string {.slot.} =
return self.delegate.suggestedFees(chainId)
proc suggestedRoutes*(self: View, account: string, amount: string, token: string, disabledFromChainIDs: string, disabledToChainIDs: string, preferredChainIDs: string, sendType: int, lockedInAmounts: string): string {.slot.} =
var parsedAmount = stint.u256("0")
var seqPreferredChainIDs = seq[uint64] : @[]
var seqDisabledFromChainIDs = seq[uint64] : @[]
var seqDisabledToChainIDs = seq[uint64] : @[]
try:
for chainID in disabledFromChainIDs.split(','):
seqDisabledFromChainIDs.add(parseUInt(chainID))
except:
discard
try:
for chainID in disabledToChainIDs.split(','):
seqDisabledToChainIDs.add(parseUInt(chainID))
except:
discard
try:
for chainID in preferredChainIDs.split(','):
seqPreferredChainIDs.add(parseUInt(chainID))
except:
discard
try:
parsedAmount = fromHex(Stuint[256], amount)
except Exception as e:
discard
return self.delegate.suggestedRoutes(account, parsedAmount, token, seqDisabledFromChainIDs, seqDisabledToChainIDs, seqPreferredChainIDs, sendType, lockedInAmounts)
proc getEstimatedTime*(self: View, chainId: int, maxFeePerGas: string): int {.slot.} =
return self.delegate.getEstimatedTime(chainId, maxFeePerGas)
proc suggestedRoutesReady*(self: View, suggestedRoutes: string) {.signal.}

View File

@ -10,8 +10,6 @@ import ../../../shared_modules/keycard_popup/io_interface as keycard_shared_modu
import ../../../../core/[main]
import ../../../../core/tasks/[qt, threadpool]
const UNIQUE_WALLET_SECTION_TRANSACTION_MODULE_IDENTIFIER* = "WalletSection-TransactionModule"
type
Controller* = ref object of RootObj
delegate: io_interface.AccessInterface
@ -45,6 +43,9 @@ proc delete*(self: Controller) =
discard
proc init*(self: Controller) =
self.events.on(SIGNAL_TRANSACTION_SENT) do(e:Args):
self.delegate.transactionWasSent(TransactionSentArgs(e).result)
self.events.on(SIGNAL_HISTORY_FETCHING) do (e:Args):
let args = HistoryArgs(e)
self.delegate.setHistoryFetchState(args.addresses, isFetching = true)
@ -69,18 +70,6 @@ proc init*(self: Controller) =
self.delegate.setHistoryFetchState(@[args.address], isFetching = false)
self.delegate.setTrxHistoryResult(args.transactions, args.collectibles, args.address, args.wasFetchMore)
self.events.on(SIGNAL_TRANSACTION_SENT) do(e:Args):
self.delegate.transactionWasSent(TransactionSentArgs(e).result)
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
let args = SharedKeycarModuleArgs(e)
if args.uniqueIdentifier != UNIQUE_WALLET_SECTION_TRANSACTION_MODULE_IDENTIFIER:
return
self.delegate.onUserAuthenticated(args.password)
self.events.on(SIGNAL_SUGGESTED_ROUTES_READY) do(e:Args):
self.delegate.suggestedRoutesReady(SuggestedRoutesArgs(e).suggestedRoutes)
self.events.on(SIGNAL_TRANSACTION_LOADING_COMPLETED_FOR_ALL_NETWORKS) do(e:Args):
let args = TransactionsLoadedArgs(e)
self.delegate.setHistoryFetchState(args.address, args.allTxLoaded, isFetching = false)
@ -108,50 +97,24 @@ proc getWalletAccounts*(self: Controller): seq[WalletAccountDto] =
proc getWalletAccount*(self: Controller, accountIndex: int): WalletAccountDto =
return self.walletAccountService.getWalletAccount(accountIndex)
proc getAccountByAddress*(self: Controller, address: string): WalletAccountDto =
self.walletAccountService.getAccountByAddress(address)
proc getMigratedKeyPairByKeyUid*(self: Controller, keyUid: string): seq[KeyPairDto] =
return self.walletAccountService.getMigratedKeyPairByKeyUid(keyUid)
proc loadTransactions*(self: Controller, address: string, toBlock: Uint256, limit: int = 20, loadMore: bool = false) =
self.transactionService.loadTransactions(address, toBlock, limit, loadMore)
proc transfer*(self: Controller, from_addr: string, to_addr: string, tokenSymbol: string,
value: string, uuid: string, selectedRoutes: string, password: string) =
self.transactionService.transfer(from_addr, to_addr, tokenSymbol, value, uuid, selectedRoutes, password)
proc suggestedFees*(self: Controller, chainId: int): string =
let suggestedFees = self.transactionService.suggestedFees(chainId)
return suggestedFees.toJson()
proc getAllTransactions*(self: Controller, address: string): seq[TransactionDto] =
return self.transactionService.getAllTransactions(address)
proc suggestedRoutes*(self: Controller, account: string, amount: Uint256, token: string, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[uint64], sendType: int, lockedInAmounts: string): string =
let suggestedRoutes = self.transactionService.suggestedRoutes(account, amount, token, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts)
return suggestedRoutes.toJson()
proc getChainIdForChat*(self: Controller): int =
return self.networkService.getNetworkForChat().chainId
proc getChainIdForBrowser*(self: Controller): int =
return self.networkService.getNetworkForBrowser().chainId
proc getEstimatedTime*(self: Controller, chainId: int, maxFeePerGas: string): EstimatedTime =
return self.transactionService.getEstimatedTime(chainId, maxFeePerGas)
proc getLastTxBlockNumber*(self: Controller): string =
return self.transactionService.getLastTxBlockNumber(self.networkService.getNetworkForBrowser().chainId)
proc getEnabledChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)
proc authenticateUser*(self: Controller, keyUid = "") =
let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_WALLET_SECTION_TRANSACTION_MODULE_IDENTIFIER,
keyUid: keyUid)
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
return self.currencyService.getCurrencyFormat(symbol)

View File

@ -1,4 +1,3 @@
import stint
import ../../../../../app_service/service/wallet_account/dto as WalletDto
import ../../../../../app_service/service/collectible/dto as CollectibleDto
import ../../../../../app_service/service/transaction/dto
@ -23,9 +22,6 @@ method switchAccount*(self: AccessInterface, accountIndex: int) {.base.} =
method getWalletAccounts*(self: AccessInterface): seq[WalletAccountDto] {.base.} =
raise newException(ValueError, "No implementation available")
method getAccountByAddress*(self: AccessInterface, address: string): WalletAccountDto {.base.} =
raise newException(ValueError, "No implementation available")
method loadTransactions*(self: AccessInterface, address: string, toBlock: string, limit: int, loadMore: bool) {.base.} =
raise newException(ValueError, "No implementation available")
@ -44,31 +40,15 @@ method setHistoryFetchState*(self: AccessInterface, address: string, allTxLoaded
method setIsNonArchivalNode*(self: AccessInterface, isNonArchivalNode: bool) {.base.} =
raise newException(ValueError, "No implementation available")
method onUserAuthenticated*(self: AccessInterface, password: string) {.base.} =
raise newException(ValueError, "No implementation available")
method authenticateAndTransfer*(self: AccessInterface, from_addr: string, to_addr: string,
tokenSymbol: string, value: string, uuid: string, selectedRoutes: string) {.base.} =
raise newException(ValueError, "No implementation available")
method transactionWasSent*(self: AccessInterface, result: string) {.base.} =
raise newException(ValueError, "No implementation available")
method suggestedFees*(self: AccessInterface, chainId: int): string {.base.} =
raise newException(ValueError, "No implementation available")
method suggestedRoutes*(self: AccessInterface, account: string, amount: UInt256, token: string, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[uint64], sendType: int, lockedInAmounts: string): string {.base.} =
raise newException(ValueError, "No implementation available")
method getChainIdForChat*(self: AccessInterface): int =
raise newException(ValueError, "No implementation available")
method getChainIdForBrowser*(self: AccessInterface): int =
raise newException(ValueError, "No implementation available")
method getEstimatedTime*(self: AccessInterface, chainId: int, maxFeePerGas: string): int {.base.} =
raise newException(ValueError, "No implementation available")
method refreshTransactions*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
@ -80,6 +60,3 @@ method viewDidLoad*(self: AccessInterface) {.base.} =
method getLastTxBlockNumber*(self: AccessInterface): string {.base.} =
raise newException(ValueError, "No implementation available")
method suggestedRoutesReady*(self: AccessInterface, suggestedRoutes: string) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -13,27 +13,14 @@ import ../../../../../app_service/service/collectible/service as collectible_ser
export io_interface
const cancelledRequest* = "cancelled"
# Shouldn't be public ever, use only within this module.
type TmpSendTransactionDetails = object
fromAddr: string
toAddr: string
tokenSymbol: string
value: string
uuid: string
selectedRoutes: string
type
Module* = ref object of io_interface.AccessInterface
delegate: delegate_interface.AccessInterface
view: View
controller: Controller
moduleLoaded: bool
tmpSendTransactionDetails: TmpSendTransactionDetails
# Forward declarations
method getWalletAccounts*(self: Module): seq[WalletAccountDto]
method loadTransactions*(self: Module, address: string, toBlock: string = "0x0", limit: int = 20, loadMore: bool = false)
proc newModule*(
@ -120,7 +107,7 @@ method refreshTransactions*(self: Module) =
self.view.setTrxHistoryResult(self.transactionsToItems(transactions, @[]), account.address, wasFetchMore=false)
method viewDidLoad*(self: Module) =
let accounts = self.getWalletAccounts()
let accounts = self.controller.getWalletAccounts()
self.moduleLoaded = true
self.delegate.transactionsModuleDidLoad()
@ -131,12 +118,6 @@ method switchAccount*(self: Module, accountIndex: int) =
let walletAccount = self.controller.getWalletAccount(accountIndex)
self.view.switchAccount(walletAccount)
method getWalletAccounts*(self: Module): seq[WalletAccountDto] =
self.controller.getWalletAccounts()
method getAccountByAddress*(self: Module, address: string): WalletAccountDto =
self.controller.getAccountByAddress(address)
method loadTransactions*(self: Module, address: string, toBlock: string = "0x0", limit: int = 20, loadMore: bool = false) =
let toBlockParsed = stint.fromHex(Uint256, toBlock)
let txLimit = if toBlock == "0x0":
@ -158,76 +139,17 @@ method setHistoryFetchState*(self: Module, addresses: seq[string], isFetching: b
method setHistoryFetchState*(self: Module, address: string, allTxLoaded: bool, isFetching: bool) =
self.view.setHistoryFetchState(address, allTxLoaded, isFetching)
method setIsNonArchivalNode*(self: Module, isNonArchivalNode: bool) =
self.view.setIsNonArchivalNode(isNonArchivalNode)
method authenticateAndTransfer*(self: Module, from_addr: string, to_addr: string,
tokenSymbol: string, value: string, uuid: string, selectedRoutes: string) =
self.tmpSendTransactionDetails.fromAddr = from_addr
self.tmpSendTransactionDetails.toAddr = to_addr
self.tmpSendTransactionDetails.tokenSymbol = tokenSymbol
self.tmpSendTransactionDetails.value = value
self.tmpSendTransactionDetails.uuid = uuid
self.tmpSendTransactionDetails.selectedRoutes = selectedRoutes
if singletonInstance.userProfile.getIsKeycardUser():
let keyUid = singletonInstance.userProfile.getKeyUid()
self.controller.authenticateUser(keyUid)
else:
self.controller.authenticateUser()
##################################
## Do Not Delete
##
## Once we start with signing a transactions we shold check if the address we want to send a transaction from is migrated
## or not. In case it's not we should just authenticate logged in user, otherwise we should use one of the keycards that
## address (key pair) is migrated to and sign the transaction using it.
##
## The code bellow is an example how we can achieve that in future, when we start with signing transactions.
##
## let acc = self.controller.getAccountByAddress(from_addr)
## if acc.isNil:
## echo "error: selected account to send a transaction from is not known"
## return
## let keyPair = self.controller.getMigratedKeyPairByKeyUid(acc.keyUid)
## if keyPair.len == 0:
## self.controller.authenticateUser()
## else:
## self.controller.authenticateUser(acc.keyUid, acc.path)
##
##################################
method onUserAuthenticated*(self: Module, password: string) =
if password.len == 0:
let response = %* {"uuid": self.tmpSendTransactionDetails.uuid, "success": false, "error": cancelledRequest}
self.view.transactionWasSent($response)
else:
self.controller.transfer(self.tmpSendTransactionDetails.fromAddr, self.tmpSendTransactionDetails.toAddr,
self.tmpSendTransactionDetails.tokenSymbol, self.tmpSendTransactionDetails.value, self.tmpSendTransactionDetails.uuid,
self.tmpSendTransactionDetails.selectedRoutes, password)
method transactionWasSent*(self: Module, result: string) =
self.view.transactionWasSent(result)
self.view.setPendingTx(self.transactionsToItems(self.controller.getPendingTransactions(), @[]))
method suggestedFees*(self: Module, chainId: int): string =
return self.controller.suggestedFees(chainId)
method suggestedRoutes*(self: Module, account: string, amount: UInt256, token: string, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[uint64], sendType: int, lockedInAmounts: string): string =
return self.controller.suggestedRoutes(account, amount, token, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts)
method getChainIdForChat*(self: Module): int =
return self.controller.getChainIdForChat()
method getChainIdForBrowser*(self: Module): int =
return self.controller.getChainIdForBrowser()
method getEstimatedTime*(self: Module, chainId: int, maxFeePerGas: string): int =
return self.controller.getEstimatedTime(chainId, maxFeePerGas).int
method getLastTxBlockNumber*(self: Module): string =
return self.controller.getLastTxBlockNumber()
method suggestedRoutesReady*(self: Module, suggestedRoutes: string) =
self.view.suggestedRoutesReady(suggestedRoutes)
method transactionWasSent*(self: Module, result: string) =
self.view.setPendingTx(self.transactionsToItems(self.controller.getPendingTransactions(), @[]))

View File

@ -132,63 +132,15 @@ QtObject:
read = getIsNonArchivalNode
notify = isNonArchivalNodeChanged
proc transactionSent*(self: View, txResult: string) {.signal.}
proc transactionWasSent*(self: View,txResult: string) {.slot} =
self.transactionSent(txResult)
proc authenticateAndTransfer*(self: View, from_addr: string, to_addr: string, tokenSymbol: string,
value: string, uuid: string, selectedRoutes: string) {.slot.} =
self.delegate.authenticateAndTransfer(from_addr, to_addr, tokenSymbol, value, uuid, selectedRoutes)
proc suggestedFees*(self: View, chainId: int): string {.slot.} =
return self.delegate.suggestedFees(chainId)
proc suggestedRoutes*(self: View, account: string, amount: string, token: string, disabledFromChainIDs: string, disabledToChainIDs: string, preferredChainIDs: string, sendType: int, lockedInAmounts: string): string {.slot.} =
var parsedAmount = stint.u256("0")
var seqPreferredChainIDs = seq[uint64] : @[]
var seqDisabledFromChainIDs = seq[uint64] : @[]
var seqDisabledToChainIDs = seq[uint64] : @[]
try:
for chainID in disabledFromChainIDs.split(','):
seqDisabledFromChainIDs.add(parseUInt(chainID))
except:
discard
try:
for chainID in disabledToChainIDs.split(','):
seqDisabledToChainIDs.add(parseUInt(chainID))
except:
discard
try:
for chainID in preferredChainIDs.split(','):
seqPreferredChainIDs.add(parseUInt(chainID))
except:
discard
try:
parsedAmount = fromHex(Stuint[256], amount)
except Exception as e:
discard
return self.delegate.suggestedRoutes(account, parsedAmount, token, seqDisabledFromChainIDs, seqDisabledToChainIDs, seqPreferredChainIDs, sendType, lockedInAmounts)
proc getChainIdForChat*(self: View): int {.slot.} =
return self.delegate.getChainIdForChat()
proc getChainIdForBrowser*(self: View): int {.slot.} =
return self.delegate.getChainIdForBrowser()
proc getEstimatedTime*(self: View, chainId: int, maxFeePerGas: string): int {.slot.} =
return self.delegate.getEstimatedTime(chainId, maxFeePerGas)
proc getLastTxBlockNumber*(self: View): string {.slot.} =
return self.delegate.getLastTxBlockNumber()
proc suggestedRoutesReady*(self: View, suggestedRoutes: string) {.signal.}
proc setPendingTx*(self: View, pendingTx: seq[Item]) =
for tx in pendingTx:
if not self.enabledChainIds.contains(tx.getChainId()):

View File

@ -11,8 +11,8 @@ QtObject:
totalCurrencyBalance: CurrencyAmount
signingPhrase: string
isMnemonicBackedUp: bool
tmpAmount: float # shouldn't be used anywhere except in prepareCurrencyAmount/getPreparedCurrencyAmount procs
tmpSymbol: string # shouldn't be used anywhere except in prepareCurrencyAmount/getPreparedCurrencyAmount procs
tmpAmount: float # shouldn't be used anywhere except in prepare*/getPrepared* procs
tmpSymbol: string # shouldn't be used anywhere except in prepare*/getPrepared* procs
proc setup(self: View) =
self.QObject.setup

View File

@ -205,23 +205,3 @@ QtObject:
break
return false
proc getTokenBalanceOnChain*(self: Model, chainId: int, tokenSymbol: string): CurrencyAmount =
for item in self.items:
if(item.getSymbol() != tokenSymbol):
continue
for balance in item.getBalances().items:
if (balance.chainId != chainId):
continue
return balance.balance
break
return newCurrencyAmount(
0.0,
tokenSymbol,
0,
false
)

View File

@ -635,6 +635,14 @@ QtObject:
let accounts = self.getWalletAccounts()
return accounts.map(a => a.getCurrencyBalance(chainIds, self.getCurrentCurrencyIfEmpty(currency))).foldl(a + b, 0.0)
proc getTokenBalanceOnChain*(self: Service, address: string, chainId: int, symbol: string): float64 =
let account = self.getAccountByAddress(address)
for token in account.tokens:
if token.symbol == symbol:
return token.balancesPerChain[chainId].balance
return 0.0
proc addMigratedKeyPairAsync*(self: Service, keyPair: KeyPairDto, password = "") =
# Providing a password corresponding local keystore file will be removed as well, though
# in some contexts we just need to add keypair to the db, so password is not needed.

View File

@ -193,7 +193,7 @@ QtObject {
property ListModel addToGroupContacts: ListModel {}
property var walletSectionTransactionsInst: walletSectionTransactions
property var walletSectionSendInst: walletSectionSend
property bool isWakuV2StoreEnabled: advancedModule ? advancedModule.isWakuV2StoreEnabled : false
@ -515,7 +515,7 @@ QtObject {
// Needed for TX in chat for stickers and via contact
property var accounts: walletSectionAccounts.model
property var accounts: walletSectionSendInst.accounts
property var currentAccount: walletSectionCurrent
property string currentCurrency: walletSection.currentCurrency
property CurrenciesStore currencyStore: CurrenciesStore {}
@ -576,32 +576,19 @@ QtObject {
}
function estimateGas(from_addr, to, assetSymbol, value, chainId, data) {
return walletSectionTransactions.estimateGas(from_addr, to, assetSymbol, value === "" ? "0.00" : value, chainId, data)
return walletSectionSendInst.estimateGas(from_addr, to, assetSymbol, value === "" ? "0.00" : value, chainId, data)
}
function authenticateAndTransfer(from, to, tokenSymbol, amount, uuid, selectedRoutes) {
walletSectionTransactions.authenticateAndTransfer(from, to, tokenSymbol, amount, uuid, selectedRoutes)
}
function getAccountNameByAddress(address) {
return walletSectionAccounts.getAccountNameByAddress(address)
}
function getAccountIconColorByAddress(address) {
return walletSectionAccounts.getAccountIconColorByAddress(address)
}
function getAccountAssetsByAddress(address) {
walletSectionAccounts.setAddressForAssets(address)
return walletSectionAccounts.getAccountAssetsByAddress()
walletSectionSendInst.authenticateAndTransfer(from, to, tokenSymbol, amount, uuid, selectedRoutes)
}
function suggestedFees(chainId) {
return JSON.parse(walletSectionTransactions.suggestedFees(chainId))
return JSON.parse(walletSectionSendInst.suggestedFees(chainId))
}
function suggestedRoutes(account, amount, token, disabledFromChainIDs, disabledToChainIDs, preferredChainIds, sendType, lockedInAmounts) {
walletSectionTransactions.suggestedRoutes(account, amount, token, disabledFromChainIDs, disabledToChainIDs, preferredChainIds, sendType, lockedInAmounts)
walletSectionSendInst.suggestedRoutes(account, amount, token, disabledFromChainIDs, disabledToChainIDs, preferredChainIds, sendType, lockedInAmounts)
}
function resolveENS(value) {

View File

@ -24,7 +24,7 @@ QtObject {
property string username: !!Global.userProfile? Global.userProfile.username : ""
property var walletAccounts: Global.appIsReady? walletSectionAccounts.model : null
property var walletAccounts: Global.appIsReady? walletSectionSend.accounts : null
function setPrefferedEnsUsername(ensName) {
if(!root.ensUsernamesModule)
@ -145,7 +145,7 @@ QtObject {
}
function getEstimatedTime(chainId, maxFeePerGas) {
return walletSectionTransactions.getEstimatedTime(chainId, maxFeePerGas)
return walletSectionSend.getEstimatedTime(chainId, maxFeePerGas)
}
function getStatusToken() {
@ -155,7 +155,7 @@ QtObject {
}
function suggestedFees(chainId) {
return JSON.parse(walletSectionTransactions.suggestedFees(chainId))
return JSON.parse(walletSectionSend.suggestedFees(chainId))
}
function removeEnsUsername(chainId, ensUsername) {

View File

@ -20,7 +20,7 @@ QtObject {
property var overview: walletSectionOverview
property var assets: walletSectionCurrent
property var currentAccount: walletSectionCurrent
property var accounts: walletSectionAccounts.model
property var accounts: walletSectionAccounts.accounts
property var appSettings: localAppSettings
property var accountSensitiveSettings: localAccountSensitiveSettings
property bool hideSignPhraseModal: accountSensitiveSettings.hideSignPhraseModal
@ -126,9 +126,6 @@ QtObject {
}
function switchAccount(newIndex) {
if(Constants.isCppApp)
walletSectionAccounts.switchAccount(newIndex)
else
walletSection.switchAccount(newIndex)
}

View File

@ -391,7 +391,6 @@ Rectangle {
}
model: RootStore.accounts
// model: RootStore.exampleWalletModel
}
}
}

View File

@ -127,7 +127,7 @@ Item {
visible: (stack.currentIndex === 2)
account: RootStore.currentAccount
address: RootStore.currentAccount.mixedcaseAddress
address: RootStore.currentAccount.address
networkConnectionStore: root.networkConnectionStore
}
TransactionDetailView {

View File

@ -52,7 +52,7 @@ QtObject {
// property var walletModelInst: walletModel
property var userProfileInst: userProfile
property var accounts: walletSectionAccounts.model
property var accounts: walletSectionSendInst.accounts
property var currentAccount: walletSectionCurrent
// Not Refactored Yet
// property var profileModelInst: profileModel
@ -67,7 +67,7 @@ QtObject {
property real volume: !!appSettings ? appSettings.volume * 0.01 : 0.5
property bool notificationSoundsEnabled: !!appSettings ? appSettings.notificationSoundsEnabled : true
property var walletSectionTransactionsInst: walletSectionTransactions
property var walletSectionSendInst: walletSectionSend
property var savedAddressesModel: walletSectionSavedAddresses.model
@ -117,11 +117,11 @@ QtObject {
}
function suggestedFees(chainId) {
return JSON.parse(walletSectionTransactions.suggestedFees(chainId))
return JSON.parse(walletSectionSendInst.suggestedFees(chainId))
}
function getEstimatedTime(chainId, maxFeePerGas) {
return walletSectionTransactions.getEstimatedTime(chainId, maxFeePerGas)
return walletSectionSendInst.getEstimatedTime(chainId, maxFeePerGas)
}
function getChainIdForChat() {

View File

@ -455,7 +455,7 @@ StatusDialog {
}
Connections {
target: popup.store.walletSectionTransactionsInst
target: popup.store.walletSectionSendInst
function onSuggestedRoutesReady(suggestedRoutes: string) {
let response = JSON.parse(suggestedRoutes)
if(!!response.error) {
@ -475,7 +475,7 @@ StatusDialog {
}
Connections {
target: popup.store.walletSectionTransactionsInst
target: popup.store.walletSectionSendInst
function onTransactionSent(txResult: string) {
d.isPendingTx = false
try {

View File

@ -322,7 +322,7 @@ StatusModal {
// }
// Connections {
// target: root.store.walletSectionTransactionsInst
// target: root.store.walletSectionSendInst
// onTransactionSent: {
// try {
// let response = JSON.parse(txResult)

View File

@ -15,10 +15,11 @@ QtObject {
property var mainModuleInst: mainModule
property var walletSectionTransactionsInst: walletSectionTransactions
property var walletSectionSendInst: walletSectionSend
property string currentCurrency: walletSection.currentCurrency
property var allNetworks: networksModule.all
property var accounts: walletSectionAccounts.model
property var accounts: walletSectionSendInst.accounts
property var currentAccount: walletSectionCurrent
property string signingPhrase: walletSection.signingPhrase
property var savedAddressesModel: SortFilterProxyModel {
@ -70,15 +71,15 @@ QtObject {
}
function authenticateAndTransfer(from, to, tokenSymbol, amount, uuid, selectedRoutes) {
walletSectionTransactions.authenticateAndTransfer(from, to, tokenSymbol, amount, uuid, selectedRoutes)
walletSectionSendInst.authenticateAndTransfer(from, to, tokenSymbol, amount, uuid, selectedRoutes)
}
function suggestedFees(chainId) {
return JSON.parse(walletSectionTransactions.suggestedFees(chainId))
return JSON.parse(walletSectionSendInst.suggestedFees(chainId))
}
function getEstimatedTime(chainId, maxFeePerGas) {
return walletSectionTransactions.getEstimatedTime(chainId, maxFeePerGas)
return walletSectionSendInst.getEstimatedTime(chainId, maxFeePerGas)
}
function getChainIdForChat() {
@ -90,7 +91,7 @@ QtObject {
}
function suggestedRoutes(account, amount, token, disabledFromChainIDs, disabledToChainIDs, preferredChainIds, sendType, lockedInAmounts) {
walletSectionTransactions.suggestedRoutes(account, amount, token, disabledFromChainIDs, disabledToChainIDs, preferredChainIds, sendType, JSON.stringify(lockedInAmounts))
walletSectionSendInst.suggestedRoutes(account, amount, token, disabledFromChainIDs, disabledToChainIDs, preferredChainIds, sendType, JSON.stringify(lockedInAmounts))
}
function hex2Eth(value) {
@ -265,8 +266,8 @@ QtObject {
return undefined
}
walletSectionAccounts.prepareTokenBalanceOnChain(selectedAccount.address, chainId, tokenSymbol)
return walletSectionAccounts.getPreparedTokenBalanceOnChain()
walletSectionSendInst.prepareTokenBalanceOnChain(selectedAccount.address, chainId, tokenSymbol)
return walletSectionSendInst.getPreparedTokenBalanceOnChain()
}
function findTokenSymbolByAddress(address) {

View File

@ -223,12 +223,14 @@ Item {
fromAddress: transactionParamsObject.fromAddress
selectedRecipient: root.selectedRecipient
onSendTransaction: {
Global.openPopup(signTxComponent, {selectedAccount: {
name: root.store.getAccountNameByAddress(fromAddress),
address: fromAddress,
color: root.store.getAccountIconColorByAddress(fromAddress),
assets: root.store.getAccountAssetsByAddress(fromAddress)
}})
// TODO: https://github.com/status-im/status-desktop/issues/6778
console.log("not implemented")
// Global.openPopup(signTxComponent, {selectedAccount: {
// name: root.store.getAccountNameByAddress(fromAddress),
// address: fromAddress,
// color: root.store.getAccountIconColorByAddress(fromAddress),
// assets: root.store.getAccountAssetsByAddress(fromAddress)
// }})
}
}
}