feat(@wallet): wallet accounts module dedup
Second part of having profile section accounts
This commit is contained in:
parent
eb5423db9c
commit
e6f88758dc
|
@ -52,7 +52,4 @@ proc getCurrentCurrency*(self: Controller): string =
|
||||||
return self.walletAccountService.getCurrency()
|
return self.walletAccountService.getCurrency()
|
||||||
|
|
||||||
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
|
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
|
||||||
return self.currencyService.getCurrencyFormat(symbol)
|
return self.currencyService.getCurrencyFormat(symbol)
|
||||||
|
|
||||||
proc getAllMigratedKeyPairs*(self: Controller): seq[KeyPairDto] =
|
|
||||||
return self.walletAccountService.getAllMigratedKeyPairs()
|
|
|
@ -63,33 +63,18 @@ proc setAssets(self: Module, tokens: seq[WalletTokenDto]) =
|
||||||
method switchAccount*(self: Module, accountIndex: int) =
|
method switchAccount*(self: Module, accountIndex: int) =
|
||||||
self.currentAccountIndex = accountIndex
|
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 walletAccount = self.controller.getWalletAccount(accountIndex)
|
||||||
let migratedKeyPairs = self.controller.getAllMigratedKeyPairs()
|
|
||||||
let currency = self.controller.getCurrentCurrency()
|
let currency = self.controller.getCurrentCurrency()
|
||||||
|
|
||||||
let chainIds = self.controller.getChainIds()
|
|
||||||
let enabledChainIds = self.controller.getEnabledChainIds()
|
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 currencyFormat = self.controller.getCurrencyFormat(currency)
|
||||||
|
|
||||||
let accountItem = walletAccountToItem(
|
let accountItem = walletAccountToItem(
|
||||||
walletAccount,
|
walletAccount,
|
||||||
chainIds,
|
|
||||||
enabledChainIds,
|
enabledChainIds,
|
||||||
currency,
|
currency,
|
||||||
keyPairMigrated(migratedKeyPairs, walletAccount.keyUid),
|
|
||||||
currencyFormat,
|
currencyFormat,
|
||||||
tokenFormats
|
)
|
||||||
)
|
|
||||||
|
|
||||||
self.view.setData(accountItem)
|
self.view.setData(accountItem)
|
||||||
self.setAssets(walletAccount.tokens)
|
self.setAssets(walletAccount.tokens)
|
||||||
|
|
|
@ -15,9 +15,7 @@ QtObject:
|
||||||
address: string
|
address: string
|
||||||
path: string
|
path: string
|
||||||
color: string
|
color: string
|
||||||
publicKey: string
|
|
||||||
walletType: string
|
walletType: string
|
||||||
isChat: bool
|
|
||||||
currencyBalance: CurrencyAmount
|
currencyBalance: CurrencyAmount
|
||||||
assets: token_model.Model
|
assets: token_model.Model
|
||||||
emoji: string
|
emoji: string
|
||||||
|
@ -74,15 +72,6 @@ QtObject:
|
||||||
read = getColor
|
read = getColor
|
||||||
notify = colorChanged
|
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.} =
|
proc getWalletType(self: View): QVariant {.slot.} =
|
||||||
return newQVariant(self.walletType)
|
return newQVariant(self.walletType)
|
||||||
|
|
||||||
|
@ -92,15 +81,6 @@ QtObject:
|
||||||
read = getWalletType
|
read = getWalletType
|
||||||
notify = walletTypeChanged
|
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.} =
|
proc getCurrencyBalance(self: View): QVariant {.slot.} =
|
||||||
return newQVariant(self.currencyBalance)
|
return newQVariant(self.currencyBalance)
|
||||||
|
|
||||||
|
@ -141,9 +121,6 @@ QtObject:
|
||||||
proc hasGas*(self: View, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.slot.} =
|
proc hasGas*(self: View, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.slot.} =
|
||||||
return self.assets.hasGas(chainId, nativeGasSymbol, requiredGas)
|
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) =
|
proc setData*(self: View, item: account_item.Item) =
|
||||||
self.name = item.getName()
|
self.name = item.getName()
|
||||||
self.nameChanged()
|
self.nameChanged()
|
||||||
|
@ -153,12 +130,8 @@ proc setData*(self: View, item: account_item.Item) =
|
||||||
self.pathChanged()
|
self.pathChanged()
|
||||||
self.color = item.getColor()
|
self.color = item.getColor()
|
||||||
self.colorChanged()
|
self.colorChanged()
|
||||||
self.publicKey = item.getPublicKey()
|
|
||||||
self.publicKeyChanged()
|
|
||||||
self.walletType = item.getWalletType()
|
self.walletType = item.getWalletType()
|
||||||
self.walletTypeChanged()
|
self.walletTypeChanged()
|
||||||
self.isChat = item.getIsChat()
|
|
||||||
self.isChatChanged()
|
|
||||||
self.currencyBalance = item.getCurrencyBalance()
|
self.currencyBalance = item.getCurrencyBalance()
|
||||||
self.currencyBalanceChanged()
|
self.currencyBalanceChanged()
|
||||||
self.emoji = item.getEmoji()
|
self.emoji = item.getEmoji()
|
||||||
|
|
|
@ -55,12 +55,6 @@ proc authenticateKeyPair*(self: Controller, keyUid = "") =
|
||||||
keyUid: keyUid)
|
keyUid: keyUid)
|
||||||
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
|
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] =
|
proc getEnabledChainIds*(self: Controller): seq[int] =
|
||||||
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)
|
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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()
|
|
|
@ -13,9 +13,6 @@ method load*(self: AccessInterface) {.base.} =
|
||||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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.} =
|
method deleteAccount*(self: AccessInterface, keyUid: string, address: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
|
|
@ -1,96 +1,50 @@
|
||||||
import strformat
|
import strformat
|
||||||
import ../../../shared_models/token_model as token_model
|
|
||||||
import ../../../shared_models/currency_amount
|
import ../../../shared_models/currency_amount
|
||||||
import ./compact_model as compact_model
|
|
||||||
|
|
||||||
type
|
type
|
||||||
Item* = object
|
Item* = object
|
||||||
name: string
|
name: string
|
||||||
address: string
|
address: string
|
||||||
mixedCaseAddress: string
|
|
||||||
path: string
|
path: string
|
||||||
color: string
|
color: string
|
||||||
publicKey: string
|
|
||||||
walletType: string
|
walletType: string
|
||||||
isWallet: bool
|
|
||||||
isChat: bool
|
|
||||||
currencyBalance: CurrencyAmount
|
currencyBalance: CurrencyAmount
|
||||||
assets: token_model.Model
|
|
||||||
emoji: string
|
emoji: string
|
||||||
derivedfrom: string
|
|
||||||
relatedAccounts: compact_model.Model
|
|
||||||
keyUid: string
|
keyUid: string
|
||||||
migratedToKeycard: bool
|
|
||||||
ens: string
|
|
||||||
assetsLoading: bool
|
assetsLoading: bool
|
||||||
hasBalanceCache: bool
|
|
||||||
hasMarketValuesCache: bool
|
|
||||||
|
|
||||||
proc initItem*(
|
proc initItem*(
|
||||||
name: string = "",
|
name: string = "",
|
||||||
address: string = "",
|
address: string = "",
|
||||||
mixedCaseAddress: string = "",
|
|
||||||
path: string = "",
|
path: string = "",
|
||||||
color: string = "",
|
color: string = "",
|
||||||
publicKey: string = "",
|
|
||||||
walletType: string = "",
|
walletType: string = "",
|
||||||
isWallet: bool = true,
|
|
||||||
isChat: bool = false,
|
|
||||||
currencyBalance: CurrencyAmount = nil,
|
currencyBalance: CurrencyAmount = nil,
|
||||||
assets: token_model.Model = nil,
|
|
||||||
emoji: string = "",
|
emoji: string = "",
|
||||||
derivedfrom: string = "",
|
|
||||||
relatedAccounts: compact_model.Model = nil,
|
|
||||||
keyUid: string = "",
|
keyUid: string = "",
|
||||||
migratedToKeycard: bool = false,
|
|
||||||
ens: string = "",
|
|
||||||
assetsLoading: bool = true,
|
assetsLoading: bool = true,
|
||||||
hasBalanceCache: bool = false,
|
|
||||||
hasMarketValuesCache: bool = false
|
|
||||||
): Item =
|
): Item =
|
||||||
result.name = name
|
result.name = name
|
||||||
result.address = address
|
result.address = address
|
||||||
result.mixedCaseAddress = mixedCaseAddress
|
|
||||||
result.path = path
|
result.path = path
|
||||||
result.color = color
|
result.color = color
|
||||||
result.publicKey = publicKey
|
|
||||||
result.walletType = walletType
|
result.walletType = walletType
|
||||||
result.isWallet = isWallet
|
|
||||||
result.isChat = isChat
|
|
||||||
result.currencyBalance = currencyBalance
|
result.currencyBalance = currencyBalance
|
||||||
result.assets = assets
|
|
||||||
result.emoji = emoji
|
result.emoji = emoji
|
||||||
result.derivedfrom = derivedfrom
|
|
||||||
result.relatedAccounts = relatedAccounts
|
|
||||||
result.keyUid = keyUid
|
result.keyUid = keyUid
|
||||||
result.migratedToKeycard = migratedToKeycard
|
|
||||||
result.ens = ens
|
|
||||||
result.assetsLoading = assetsLoading
|
result.assetsLoading = assetsLoading
|
||||||
result.hasBalanceCache = hasBalanceCache
|
|
||||||
result.hasMarketValuesCache = hasMarketValuesCache
|
|
||||||
|
|
||||||
proc `$`*(self: Item): string =
|
proc `$`*(self: Item): string =
|
||||||
result = fmt"""WalletAccountItem(
|
result = fmt"""WalletAccountItem(
|
||||||
name: {self.name},
|
name: {self.name},
|
||||||
address: {self.address},
|
address: {self.address},
|
||||||
mixedCaseAddress: {self.mixedCaseAddress},
|
|
||||||
path: {self.path},
|
path: {self.path},
|
||||||
color: {self.color},
|
color: {self.color},
|
||||||
publicKey: {self.publicKey},
|
|
||||||
walletType: {self.walletType},
|
walletType: {self.walletType},
|
||||||
isWallet: {self.isWallet},
|
|
||||||
isChat: {self.isChat},
|
|
||||||
currencyBalance: {self.currencyBalance},
|
currencyBalance: {self.currencyBalance},
|
||||||
assets.len: {self.assets.getCount()},
|
|
||||||
emoji: {self.emoji},
|
emoji: {self.emoji},
|
||||||
derivedfrom: {self.derivedfrom},
|
|
||||||
relatedAccounts: {self.relatedAccounts}
|
|
||||||
keyUid: {self.keyUid},
|
keyUid: {self.keyUid},
|
||||||
migratedToKeycard: {self.migratedToKeycard},
|
|
||||||
ens: {self.ens},
|
|
||||||
assetsLoading: {self.assetsLoading},
|
assetsLoading: {self.assetsLoading},
|
||||||
hasBalanceCache: {self.hasBalanceCache},
|
|
||||||
hasMarketValuesCache: {self.hasMarketValuesCache},
|
|
||||||
]"""
|
]"""
|
||||||
|
|
||||||
proc getName*(self: Item): string =
|
proc getName*(self: Item): string =
|
||||||
|
@ -99,9 +53,6 @@ proc getName*(self: Item): string =
|
||||||
proc getAddress*(self: Item): string =
|
proc getAddress*(self: Item): string =
|
||||||
return self.address
|
return self.address
|
||||||
|
|
||||||
proc getMixedCaseAddress*(self: Item): string =
|
|
||||||
return self.mixedCaseAddress
|
|
||||||
|
|
||||||
proc getPath*(self: Item): string =
|
proc getPath*(self: Item): string =
|
||||||
return self.path
|
return self.path
|
||||||
|
|
||||||
|
@ -111,44 +62,14 @@ proc getEmoji*(self: Item): string =
|
||||||
proc getColor*(self: Item): string =
|
proc getColor*(self: Item): string =
|
||||||
return self.color
|
return self.color
|
||||||
|
|
||||||
proc getPublicKey*(self: Item): string =
|
|
||||||
return self.publicKey
|
|
||||||
|
|
||||||
proc getWalletType*(self: Item): string =
|
proc getWalletType*(self: Item): string =
|
||||||
return self.walletType
|
return self.walletType
|
||||||
|
|
||||||
proc getIsWallet*(self: Item): bool =
|
|
||||||
return self.isWallet
|
|
||||||
|
|
||||||
proc getIsChat*(self: Item): bool =
|
|
||||||
return self.isChat
|
|
||||||
|
|
||||||
proc getCurrencyBalance*(self: Item): CurrencyAmount =
|
proc getCurrencyBalance*(self: Item): CurrencyAmount =
|
||||||
return self.currencyBalance
|
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 =
|
proc getKeyUid*(self: Item): string =
|
||||||
return self.keyUid
|
return self.keyUid
|
||||||
|
|
||||||
proc getMigratedToKeycard*(self: Item): bool =
|
|
||||||
return self.migratedToKeycard
|
|
||||||
|
|
||||||
proc getEns*(self: Item): string =
|
|
||||||
return self.ens
|
|
||||||
|
|
||||||
proc getAssetsLoading*(self: Item): bool =
|
proc getAssetsLoading*(self: Item): bool =
|
||||||
return self.assetsLoading
|
return self.assetsLoading
|
||||||
|
|
||||||
proc getHasBalanceCache*(self: Item): bool =
|
|
||||||
return self.hasBalanceCache
|
|
||||||
|
|
||||||
proc getHasMarketValuesCache*(self: Item): bool =
|
|
||||||
return self.hasMarketValuesCache
|
|
||||||
|
|
|
@ -10,20 +10,11 @@ type
|
||||||
Address,
|
Address,
|
||||||
Path,
|
Path,
|
||||||
Color,
|
Color,
|
||||||
PublicKey,
|
|
||||||
WalletType,
|
WalletType,
|
||||||
IsWallet,
|
|
||||||
IsChat,
|
|
||||||
CurrencyBalance,
|
CurrencyBalance,
|
||||||
Assets,
|
|
||||||
Emoji,
|
Emoji,
|
||||||
DerivedFrom,
|
|
||||||
RelatedAccounts,
|
|
||||||
KeyUid,
|
KeyUid,
|
||||||
MigratedToKeycard,
|
|
||||||
AssetsLoading,
|
AssetsLoading,
|
||||||
HasBalanceCache,
|
|
||||||
HasMarketValuesCache
|
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
|
@ -63,20 +54,11 @@ QtObject:
|
||||||
ModelRole.Address.int:"address",
|
ModelRole.Address.int:"address",
|
||||||
ModelRole.Path.int:"path",
|
ModelRole.Path.int:"path",
|
||||||
ModelRole.Color.int:"color",
|
ModelRole.Color.int:"color",
|
||||||
ModelRole.PublicKey.int:"publicKey",
|
|
||||||
ModelRole.WalletType.int:"walletType",
|
ModelRole.WalletType.int:"walletType",
|
||||||
ModelRole.IsWallet.int:"isWallet",
|
|
||||||
ModelRole.IsChat.int:"isChat",
|
|
||||||
ModelRole.Assets.int:"assets",
|
|
||||||
ModelRole.CurrencyBalance.int:"currencyBalance",
|
ModelRole.CurrencyBalance.int:"currencyBalance",
|
||||||
ModelRole.Emoji.int: "emoji",
|
ModelRole.Emoji.int: "emoji",
|
||||||
ModelRole.DerivedFrom.int: "derivedfrom",
|
|
||||||
ModelRole.RelatedAccounts.int: "relatedAccounts",
|
|
||||||
ModelRole.KeyUid.int: "keyUid",
|
ModelRole.KeyUid.int: "keyUid",
|
||||||
ModelRole.MigratedToKeycard.int: "migratedToKeycard",
|
|
||||||
ModelRole.AssetsLoading.int: "assetsLoading",
|
ModelRole.AssetsLoading.int: "assetsLoading",
|
||||||
ModelRole.HasBalanceCache.int: "hasBalanceCache",
|
|
||||||
ModelRole.HasMarketValuesCache.int: "hasMarketValuesCache"
|
|
||||||
}.toTable
|
}.toTable
|
||||||
|
|
||||||
|
|
||||||
|
@ -105,55 +87,13 @@ QtObject:
|
||||||
result = newQVariant(item.getPath())
|
result = newQVariant(item.getPath())
|
||||||
of ModelRole.Color:
|
of ModelRole.Color:
|
||||||
result = newQVariant(item.getColor())
|
result = newQVariant(item.getColor())
|
||||||
of ModelRole.PublicKey:
|
|
||||||
result = newQVariant(item.getPublicKey())
|
|
||||||
of ModelRole.WalletType:
|
of ModelRole.WalletType:
|
||||||
result = newQVariant(item.getWalletType())
|
result = newQVariant(item.getWalletType())
|
||||||
of ModelRole.IsWallet:
|
|
||||||
result = newQVariant(item.getIsWallet())
|
|
||||||
of ModelRole.IsChat:
|
|
||||||
result = newQVariant(item.getIsChat())
|
|
||||||
of ModelRole.CurrencyBalance:
|
of ModelRole.CurrencyBalance:
|
||||||
result = newQVariant(item.getCurrencyBalance())
|
result = newQVariant(item.getCurrencyBalance())
|
||||||
of ModelRole.Assets:
|
|
||||||
result = newQVariant(item.getAssets())
|
|
||||||
of ModelRole.Emoji:
|
of ModelRole.Emoji:
|
||||||
result = newQVariant(item.getEmoji())
|
result = newQVariant(item.getEmoji())
|
||||||
of ModelRole.DerivedFrom:
|
|
||||||
result = newQVariant(item.getDerivedFrom())
|
|
||||||
of ModelRole.RelatedAccounts:
|
|
||||||
result = newQVariant(item.getRelatedAccounts())
|
|
||||||
of ModelRole.KeyUid:
|
of ModelRole.KeyUid:
|
||||||
result = newQVariant(item.getKeyUid())
|
result = newQVariant(item.getKeyUid())
|
||||||
of ModelRole.MigratedToKeycard:
|
|
||||||
result = newQVariant(item.getMigratedToKeycard())
|
|
||||||
of ModelRole.AssetsLoading:
|
of ModelRole.AssetsLoading:
|
||||||
result = newQVariant(item.getAssetsLoading())
|
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()
|
|
||||||
|
|
|
@ -58,33 +58,17 @@ method delete*(self: Module) =
|
||||||
self.controller.delete
|
self.controller.delete
|
||||||
|
|
||||||
method refreshWalletAccounts*(self: Module) =
|
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 walletAccounts = self.controller.getWalletAccounts()
|
||||||
let migratedKeyPairs = self.controller.getAllMigratedKeyPairs()
|
|
||||||
let currency = self.controller.getCurrentCurrency()
|
let currency = self.controller.getCurrentCurrency()
|
||||||
|
|
||||||
let chainIds = self.controller.getChainIds()
|
|
||||||
let enabledChainIds = self.controller.getEnabledChainIds()
|
let enabledChainIds = self.controller.getEnabledChainIds()
|
||||||
|
|
||||||
let currencyFormat = self.controller.getCurrencyFormat(currency)
|
let currencyFormat = self.controller.getCurrencyFormat(currency)
|
||||||
|
|
||||||
let items = walletAccounts.map(w => (block:
|
let items = walletAccounts.map(w => (block:
|
||||||
let tokenFormats = collect(initTable()):
|
|
||||||
for t in w.tokens: {t.symbol: self.controller.getCurrencyFormat(t.symbol)}
|
|
||||||
|
|
||||||
walletAccountToItem(
|
walletAccountToItem(
|
||||||
w,
|
w,
|
||||||
chainIds,
|
enabledChainIds,
|
||||||
enabledChainIds,
|
currency,
|
||||||
currency,
|
currencyFormat,
|
||||||
keyPairMigrated(migratedKeyPairs, w.keyUid),
|
|
||||||
currencyFormat,
|
|
||||||
tokenFormats
|
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@ -138,10 +122,6 @@ method viewDidLoad*(self: Module) =
|
||||||
self.moduleLoaded = true
|
self.moduleLoaded = true
|
||||||
self.delegate.accountsModuleDidLoad()
|
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) =
|
proc authenticateActivityForKeyUid(self: Module, keyUid: string, reason: AuthenticationReason) =
|
||||||
self.authentiactionReason = reason
|
self.authentiactionReason = reason
|
||||||
let keyPair = self.controller.getMigratedKeyPairByKeyUid(keyUid)
|
let keyPair = self.controller.getMigratedKeyPairByKeyUid(keyUid)
|
||||||
|
|
|
@ -1,75 +1,25 @@
|
||||||
import tables, sequtils, sugar
|
|
||||||
|
|
||||||
import ./item
|
import ./item
|
||||||
|
|
||||||
import ../../../../../app_service/service/wallet_account/dto
|
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 ../../../../../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
|
||||||
import ../../../shared_models/currency_amount_utils
|
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*(
|
proc walletAccountToItem*(
|
||||||
w: WalletAccountDto,
|
w: WalletAccountDto,
|
||||||
chainIds: seq[int],
|
|
||||||
enabledChainIds: seq[int],
|
enabledChainIds: seq[int],
|
||||||
currency: string,
|
currency: string,
|
||||||
keyPairMigrated: bool,
|
|
||||||
currencyFormat: CurrencyFormatDto,
|
currencyFormat: CurrencyFormatDto,
|
||||||
tokenFormats: Table[string, CurrencyFormatDto],
|
|
||||||
) : item.Item =
|
) : 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(
|
return item.initItem(
|
||||||
w.name,
|
w.name,
|
||||||
w.address,
|
w.address,
|
||||||
w.mixedCaseAddress,
|
|
||||||
w.path,
|
w.path,
|
||||||
w.color,
|
w.color,
|
||||||
w.publicKey,
|
|
||||||
w.walletType,
|
w.walletType,
|
||||||
w.isWallet,
|
|
||||||
w.isChat,
|
|
||||||
currencyAmountToItem(w.getCurrencyBalance(enabledChainIds, currency), currencyFormat),
|
currencyAmountToItem(w.getCurrencyBalance(enabledChainIds, currency), currencyFormat),
|
||||||
assets,
|
|
||||||
w.emoji,
|
w.emoji,
|
||||||
w.derivedfrom,
|
|
||||||
relatedAccounts,
|
|
||||||
w.keyUid,
|
w.keyUid,
|
||||||
keyPairMigrated,
|
|
||||||
w.ens,
|
|
||||||
w.assetsLoading,
|
w.assetsLoading,
|
||||||
w.hasBalanceCache,
|
|
||||||
w.hasMarketValuesCache
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,191 +5,40 @@ import ../../../../../app_service/service/wallet_account/service as wallet_accou
|
||||||
import ./model
|
import ./model
|
||||||
import ./item
|
import ./item
|
||||||
import ./io_interface
|
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:
|
QtObject:
|
||||||
type
|
type
|
||||||
View* = ref object of QObject
|
View* = ref object of QObject
|
||||||
delegate: io_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
model: Model
|
accounts: Model
|
||||||
generated: Model
|
accountsVariant: QVariant
|
||||||
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
|
|
||||||
|
|
||||||
proc delete*(self: View) =
|
proc delete*(self: View) =
|
||||||
self.model.delete
|
self.accounts.delete
|
||||||
self.modelVariant.delete
|
self.accountsVariant.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.QObject.delete
|
self.QObject.delete
|
||||||
|
|
||||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
result.QObject.setup
|
result.QObject.setup
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.model = newModel()
|
result.accounts = newModel()
|
||||||
result.modelVariant = newQVariant(result.model)
|
result.accountsVariant = newQVariant(result.accounts)
|
||||||
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)
|
|
||||||
|
|
||||||
proc load*(self: View) =
|
proc load*(self: View) =
|
||||||
self.delegate.viewDidLoad()
|
self.delegate.viewDidLoad()
|
||||||
|
|
||||||
proc modelChanged*(self: View) {.signal.}
|
proc accountsChanged*(self: View) {.signal.}
|
||||||
|
|
||||||
proc getModel(self: View): QVariant {.slot.} =
|
proc getAccounts(self: View): QVariant {.slot.} =
|
||||||
return self.modelVariant
|
return self.accountsVariant
|
||||||
|
|
||||||
QtProperty[QVariant] model:
|
QtProperty[QVariant] accounts:
|
||||||
read = getModel
|
read = getAccounts
|
||||||
notify = modelChanged
|
notify = accountsChanged
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
proc setItems*(self: View, items: seq[Item]) =
|
proc setItems*(self: View, items: seq[Item]) =
|
||||||
self.model.setItems(items)
|
self.accounts.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)
|
|
||||||
|
|
||||||
proc deleteAccount*(self: View, keyUid: string, address: string) {.slot.} =
|
proc deleteAccount*(self: View, keyUid: string, address: string) {.slot.} =
|
||||||
self.delegate.deleteAccount(keyUid, address)
|
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)
|
|
|
@ -1,5 +1,4 @@
|
||||||
import strformat
|
import strformat
|
||||||
|
|
||||||
import ../../../shared_models/currency_amount
|
import ../../../shared_models/currency_amount
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -8,38 +7,38 @@ type
|
||||||
address: string
|
address: string
|
||||||
path: string
|
path: string
|
||||||
color: string
|
color: string
|
||||||
publicKey: string
|
|
||||||
walletType: string
|
walletType: string
|
||||||
isWallet: bool
|
|
||||||
isChat: bool
|
|
||||||
currencyBalance: CurrencyAmount
|
currencyBalance: CurrencyAmount
|
||||||
emoji: string
|
emoji: string
|
||||||
derivedfrom: string
|
keyUid: string
|
||||||
|
assetsLoading: bool
|
||||||
|
hasBalanceCache: bool
|
||||||
|
hasMarketValuesCache: bool
|
||||||
|
|
||||||
proc initItem*(
|
proc initItem*(
|
||||||
name: string,
|
name: string = "",
|
||||||
address: string,
|
address: string = "",
|
||||||
path: string,
|
path: string = "",
|
||||||
color: string,
|
color: string = "",
|
||||||
publicKey: string,
|
walletType: string = "",
|
||||||
walletType: string,
|
currencyBalance: CurrencyAmount = nil,
|
||||||
isWallet: bool,
|
emoji: string = "",
|
||||||
isChat: bool,
|
keyUid: string = "",
|
||||||
currencyBalance: CurrencyAmount,
|
assetsLoading: bool = true,
|
||||||
emoji: string,
|
hasBalanceCache: bool = false,
|
||||||
derivedfrom: string
|
hasMarketValuesCache: bool = false
|
||||||
): Item =
|
): Item =
|
||||||
result.name = name
|
result.name = name
|
||||||
result.address = address
|
result.address = address
|
||||||
result.path = path
|
result.path = path
|
||||||
result.color = color
|
result.color = color
|
||||||
result.publicKey = publicKey
|
|
||||||
result.walletType = walletType
|
result.walletType = walletType
|
||||||
result.isWallet = isWallet
|
|
||||||
result.isChat = isChat
|
|
||||||
result.currencyBalance = currencyBalance
|
result.currencyBalance = currencyBalance
|
||||||
result.emoji = emoji
|
result.emoji = emoji
|
||||||
result.derivedfrom = derivedfrom
|
result.keyUid = keyUid
|
||||||
|
result.assetsLoading = assetsLoading
|
||||||
|
result.hasBalanceCache = hasBalanceCache
|
||||||
|
result.hasMarketValuesCache = hasMarketValuesCache
|
||||||
|
|
||||||
proc `$`*(self: Item): string =
|
proc `$`*(self: Item): string =
|
||||||
result = fmt"""WalletAccountItem(
|
result = fmt"""WalletAccountItem(
|
||||||
|
@ -47,13 +46,13 @@ proc `$`*(self: Item): string =
|
||||||
address: {self.address},
|
address: {self.address},
|
||||||
path: {self.path},
|
path: {self.path},
|
||||||
color: {self.color},
|
color: {self.color},
|
||||||
publicKey: {self.publicKey},
|
|
||||||
walletType: {self.walletType},
|
walletType: {self.walletType},
|
||||||
isWallet: {self.isWallet},
|
|
||||||
isChat: {self.isChat},
|
|
||||||
currencyBalance: {self.currencyBalance},
|
currencyBalance: {self.currencyBalance},
|
||||||
emoji: {self.emoji},
|
emoji: {self.emoji},
|
||||||
derivedfrom: {self.derivedfrom}
|
keyUid: {self.keyUid},
|
||||||
|
assetsLoading: {self.assetsLoading},
|
||||||
|
hasBalanceCache: {self.hasBalanceCache},
|
||||||
|
hasMarketValuesCache: {self.hasMarketValuesCache},
|
||||||
]"""
|
]"""
|
||||||
|
|
||||||
proc getName*(self: Item): string =
|
proc getName*(self: Item): string =
|
||||||
|
@ -71,21 +70,20 @@ proc getEmoji*(self: Item): string =
|
||||||
proc getColor*(self: Item): string =
|
proc getColor*(self: Item): string =
|
||||||
return self.color
|
return self.color
|
||||||
|
|
||||||
proc getPublicKey*(self: Item): string =
|
|
||||||
return self.publicKey
|
|
||||||
|
|
||||||
proc getWalletType*(self: Item): string =
|
proc getWalletType*(self: Item): string =
|
||||||
return self.walletType
|
return self.walletType
|
||||||
|
|
||||||
proc getIsWallet*(self: Item): bool =
|
|
||||||
return self.isWallet
|
|
||||||
|
|
||||||
proc getIsChat*(self: Item): bool =
|
|
||||||
return self.isChat
|
|
||||||
|
|
||||||
proc getCurrencyBalance*(self: Item): CurrencyAmount =
|
proc getCurrencyBalance*(self: Item): CurrencyAmount =
|
||||||
return self.currencyBalance
|
return self.currencyBalance
|
||||||
|
|
||||||
proc getDerivedFrom*(self: Item): string =
|
proc getKeyUid*(self: Item): string =
|
||||||
return self.derivedfrom
|
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
|
|
@ -14,9 +14,8 @@ import ../../../shared_models/currency_amount
|
||||||
import ../../../shared_models/token_model as token_model
|
import ../../../shared_models/token_model as token_model
|
||||||
import ../../../shared_models/token_item as token_item
|
import ../../../shared_models/token_item as token_item
|
||||||
import ../../../shared_models/token_utils
|
import ../../../shared_models/token_utils
|
||||||
import ../accounts/compact_item as account_compact_item
|
import ./item as account_item
|
||||||
import ../accounts/item as account_item
|
import ./utils
|
||||||
import ../accounts/utils
|
|
||||||
|
|
||||||
import ./io_interface, ./view, ./controller
|
import ./io_interface, ./view, ./controller
|
||||||
import ../io_interface as delegate_interface
|
import ../io_interface as delegate_interface
|
||||||
|
@ -149,13 +148,10 @@ method switchAccount*(self: Module, accountIndex: int) =
|
||||||
|
|
||||||
let defaultAccountItem = walletAccountToItem(
|
let defaultAccountItem = walletAccountToItem(
|
||||||
defaultAccount,
|
defaultAccount,
|
||||||
chainIds,
|
|
||||||
enabledChainIds,
|
enabledChainIds,
|
||||||
currency,
|
currency,
|
||||||
keyPairMigrated(migratedKeyPairs, defaultAccount.keyUid),
|
|
||||||
currencyFormat,
|
currencyFormat,
|
||||||
defaultAccountTokenFormats
|
)
|
||||||
)
|
|
||||||
|
|
||||||
self.view.setDefaultWalletAccount(defaultAccountItem)
|
self.view.setDefaultWalletAccount(defaultAccountItem)
|
||||||
|
|
||||||
|
@ -166,13 +162,10 @@ method switchAccount*(self: Module, accountIndex: int) =
|
||||||
|
|
||||||
let accountItem = walletAccountToItem(
|
let accountItem = walletAccountToItem(
|
||||||
walletAccount,
|
walletAccount,
|
||||||
chainIds,
|
|
||||||
enabledChainIds,
|
enabledChainIds,
|
||||||
currency,
|
currency,
|
||||||
keyPairMigrated(migratedKeyPairs, walletAccount.keyUid),
|
|
||||||
currencyFormat,
|
currencyFormat,
|
||||||
accountTokenFormats
|
)
|
||||||
)
|
|
||||||
|
|
||||||
self.view.setData(accountItem)
|
self.view.setData(accountItem)
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
)
|
|
@ -4,10 +4,8 @@ import ./io_interface
|
||||||
import ../../../shared_models/token_model as token_model
|
import ../../../shared_models/token_model as token_model
|
||||||
import ../../../shared_models/token_item as token_item
|
import ../../../shared_models/token_item as token_item
|
||||||
import ../../../shared_models/currency_amount
|
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 = "generated"
|
||||||
const GENERATED_FROM_IMPORTED = "generated from imported accounts"
|
const GENERATED_FROM_IMPORTED = "generated from imported accounts"
|
||||||
|
@ -20,20 +18,12 @@ QtObject:
|
||||||
name: string
|
name: string
|
||||||
keyUid: string
|
keyUid: string
|
||||||
address: string
|
address: string
|
||||||
mixedcaseAddress: string
|
|
||||||
path: string
|
path: string
|
||||||
color: string
|
color: string
|
||||||
publicKey: string
|
|
||||||
walletType: string
|
walletType: string
|
||||||
isChat: bool
|
|
||||||
currencyBalance: CurrencyAmount
|
currencyBalance: CurrencyAmount
|
||||||
assets: token_model.Model
|
assets: token_model.Model
|
||||||
emoji: string
|
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
|
assetsLoading: bool
|
||||||
hasBalanceCache: bool
|
hasBalanceCache: bool
|
||||||
hasMarketValuesCache: bool
|
hasMarketValuesCache: bool
|
||||||
|
@ -77,13 +67,6 @@ QtObject:
|
||||||
read = getAddress
|
read = getAddress
|
||||||
notify = addressChanged
|
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.} =
|
proc getPath(self: View): QVariant {.slot.} =
|
||||||
return newQVariant(self.path)
|
return newQVariant(self.path)
|
||||||
|
|
||||||
|
@ -102,15 +85,6 @@ QtObject:
|
||||||
read = getColor
|
read = getColor
|
||||||
notify = colorChanged
|
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.} =
|
proc getWalletType(self: View): QVariant {.slot.} =
|
||||||
return newQVariant(self.walletType)
|
return newQVariant(self.walletType)
|
||||||
|
|
||||||
|
@ -120,15 +94,6 @@ QtObject:
|
||||||
read = getWalletType
|
read = getWalletType
|
||||||
notify = walletTypeChanged
|
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 currencyBalanceChanged(self: View) {.signal.}
|
||||||
proc getCurrencyBalance*(self: View): QVariant {.slot.} =
|
proc getCurrencyBalance*(self: View): QVariant {.slot.} =
|
||||||
return newQVariant(self.currencyBalance)
|
return newQVariant(self.currencyBalance)
|
||||||
|
@ -158,33 +123,6 @@ QtObject:
|
||||||
read = getEmoji
|
read = getEmoji
|
||||||
notify = emojiChanged
|
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.} =
|
proc getAssetsLoading(self: View): QVariant {.slot.} =
|
||||||
return newQVariant(self.assetsLoading)
|
return newQVariant(self.assetsLoading)
|
||||||
proc assetsLoadingChanged(self: View) {.signal.}
|
proc assetsLoadingChanged(self: View) {.signal.}
|
||||||
|
@ -227,46 +165,23 @@ QtObject:
|
||||||
if(self.address != item.getAddress()):
|
if(self.address != item.getAddress()):
|
||||||
self.address = item.getAddress()
|
self.address = item.getAddress()
|
||||||
self.addressChanged()
|
self.addressChanged()
|
||||||
if(self.mixedcaseAddress != item.getMixedCaseAddress()):
|
|
||||||
self.mixedcaseAddress = item.getMixedCaseAddress()
|
|
||||||
self.mixedcaseAddressChanged()
|
|
||||||
if(self.path != item.getPath()):
|
if(self.path != item.getPath()):
|
||||||
self.path = item.getPath()
|
self.path = item.getPath()
|
||||||
self.pathChanged()
|
self.pathChanged()
|
||||||
if(self.color != item.getColor()):
|
if(self.color != item.getColor()):
|
||||||
self.color = item.getColor()
|
self.color = item.getColor()
|
||||||
self.colorChanged()
|
self.colorChanged()
|
||||||
if(self.publicKey != item.getPublicKey()):
|
if(self.walletType != item.getWalletType()):
|
||||||
self.publicKey = item.getPublicKey()
|
self.walletType = item.getWalletType()
|
||||||
self.publicKeyChanged()
|
self.walletTypeChanged()
|
||||||
# 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()):
|
if(self.emoji != item.getEmoji()):
|
||||||
self.emoji = item.getEmoji()
|
self.emoji = item.getEmoji()
|
||||||
self.emojiChanged()
|
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.setAssetsLoading(item.getAssetsLoading())
|
||||||
self.hasBalanceCache = item.getHasBalanceCache()
|
self.hasBalanceCache = item.getHasBalanceCache()
|
||||||
self.hasBalanceCacheChanged()
|
self.hasBalanceCacheChanged()
|
||||||
self.hasMarketValuesCache = item.getHasMarketValuesCache()
|
self.hasMarketValuesCache = item.getHasMarketValuesCache()
|
||||||
self.hasMarketValuesCacheChanged()
|
self.hasMarketValuesCacheChanged()
|
||||||
# Set related accounts
|
|
||||||
self.relatedAccounts = item.getRelatedAccounts()
|
|
||||||
self.relatedAccountsChanged()
|
|
||||||
|
|
||||||
proc findTokenSymbolByAddress*(self: View, address: string): string {.slot.} =
|
proc findTokenSymbolByAddress*(self: View, address: string): string {.slot.} =
|
||||||
return self.delegate.findTokenSymbolByAddress(address)
|
return self.delegate.findTokenSymbolByAddress(address)
|
||||||
|
@ -274,21 +189,6 @@ QtObject:
|
||||||
proc hasGas*(self: View, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.slot.} =
|
proc hasGas*(self: View, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.slot.} =
|
||||||
return self.assets.hasGas(chainId, nativeGasSymbol, requiredGas)
|
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) =
|
proc setCacheValues*(self: View, hasBalanceCache: bool, hasMarketValuesCache: bool) =
|
||||||
self.hasBalanceCache = hasBalanceCache
|
self.hasBalanceCache = hasBalanceCache
|
||||||
self.hasBalanceCacheChanged()
|
self.hasBalanceCacheChanged()
|
||||||
|
|
|
@ -58,6 +58,9 @@ method savedAddressesModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||||
method buySellCryptoModuleDidLoad*(self: AccessInterface) {.base.} =
|
method buySellCryptoModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method sendModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method overviewModuleDidLoad*(self: AccessInterface) {.base.} =
|
method overviewModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import ./saved_addresses/module as saved_addresses_module
|
||||||
import ./buy_sell_crypto/module as buy_sell_crypto_module
|
import ./buy_sell_crypto/module as buy_sell_crypto_module
|
||||||
import ./add_account/module as add_account_module
|
import ./add_account/module as add_account_module
|
||||||
import ./overview/module as overview_module
|
import ./overview/module as overview_module
|
||||||
|
import ./send/module as send_module
|
||||||
|
|
||||||
import ../../../global/global_singleton
|
import ../../../global/global_singleton
|
||||||
import ../../../core/eventemitter
|
import ../../../core/eventemitter
|
||||||
|
@ -47,6 +48,7 @@ type
|
||||||
allTokensModule: all_tokens_module.AccessInterface
|
allTokensModule: all_tokens_module.AccessInterface
|
||||||
collectiblesModule: collectibles_module.AccessInterface
|
collectiblesModule: collectibles_module.AccessInterface
|
||||||
assetsModule: assets_module.AccessInterface
|
assetsModule: assets_module.AccessInterface
|
||||||
|
sendModule: send_module.AccessInterface
|
||||||
transactionsModule: transactions_module.AccessInterface
|
transactionsModule: transactions_module.AccessInterface
|
||||||
savedAddressesModule: saved_addresses_module.AccessInterface
|
savedAddressesModule: saved_addresses_module.AccessInterface
|
||||||
buySellCryptoModule: buy_sell_crypto_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.collectiblesModule = collectibles_module.newModule(result, events, collectibleService, walletAccountService, networkService, nodeService, networkConnectionService)
|
||||||
result.assetsModule = assets_module.newModule(result, events, walletAccountService, networkService, tokenService, currencyService, collectibleService)
|
result.assetsModule = assets_module.newModule(result, events, walletAccountService, networkService, tokenService, currencyService, collectibleService)
|
||||||
result.transactionsModule = transactions_module.newModule(result, events, transactionService, walletAccountService, networkService, currencyService)
|
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.savedAddressesModule = saved_addresses_module.newModule(result, events, savedAddressService)
|
||||||
result.buySellCryptoModule = buy_sell_crypto_module.newModule(result, events, transactionService)
|
result.buySellCryptoModule = buy_sell_crypto_module.newModule(result, events, transactionService)
|
||||||
result.overviewModule = overview_module.newModule(result, events, walletAccountService, networkService, currencyService)
|
result.overviewModule = overview_module.newModule(result, events, walletAccountService, networkService, currencyService)
|
||||||
|
@ -99,6 +102,7 @@ method delete*(self: Module) =
|
||||||
self.transactionsModule.delete
|
self.transactionsModule.delete
|
||||||
self.savedAddressesModule.delete
|
self.savedAddressesModule.delete
|
||||||
self.buySellCryptoModule.delete
|
self.buySellCryptoModule.delete
|
||||||
|
self.sendModule.delete
|
||||||
self.controller.delete
|
self.controller.delete
|
||||||
self.view.delete
|
self.view.delete
|
||||||
if not self.addAccountModule.isNil:
|
if not self.addAccountModule.isNil:
|
||||||
|
@ -151,6 +155,7 @@ method load*(self: Module) =
|
||||||
self.savedAddressesModule.load()
|
self.savedAddressesModule.load()
|
||||||
self.buySellCryptoModule.load()
|
self.buySellCryptoModule.load()
|
||||||
self.overviewModule.load()
|
self.overviewModule.load()
|
||||||
|
self.sendModule.load()
|
||||||
|
|
||||||
method isLoaded*(self: Module): bool =
|
method isLoaded*(self: Module): bool =
|
||||||
return self.moduleLoaded
|
return self.moduleLoaded
|
||||||
|
@ -180,6 +185,9 @@ proc checkIfModuleDidLoad(self: Module) =
|
||||||
if(not self.overviewModule.isLoaded()):
|
if(not self.overviewModule.isLoaded()):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if(not self.sendModule.isLoaded()):
|
||||||
|
return
|
||||||
|
|
||||||
self.switchAccount(0)
|
self.switchAccount(0)
|
||||||
let currency = self.controller.getCurrency()
|
let currency = self.controller.getCurrency()
|
||||||
let signingPhrase = self.controller.getSigningPhrase()
|
let signingPhrase = self.controller.getSigningPhrase()
|
||||||
|
@ -217,6 +225,9 @@ method buySellCryptoModuleDidLoad*(self: Module) =
|
||||||
method overviewModuleDidLoad*(self: Module) =
|
method overviewModuleDidLoad*(self: Module) =
|
||||||
self.checkIfModuleDidLoad()
|
self.checkIfModuleDidLoad()
|
||||||
|
|
||||||
|
method sendModuleDidLoad*(self: Module) =
|
||||||
|
self.checkIfModuleDidLoad()
|
||||||
|
|
||||||
method destroyAddAccountPopup*(self: Module, switchToAccWithAddress: string = "") =
|
method destroyAddAccountPopup*(self: Module, switchToAccWithAddress: string = "") =
|
||||||
if not self.addAccountModule.isNil:
|
if not self.addAccountModule.isNil:
|
||||||
if switchToAccWithAddress.len > 0:
|
if switchToAccWithAddress.len > 0:
|
||||||
|
|
|
@ -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
|
|
@ -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
|
type
|
||||||
ModelRole {.pure.} = enum
|
ModelRole {.pure.} = enum
|
||||||
Name = UserRole + 1,
|
Name = UserRole + 1,
|
||||||
Address,
|
Address,
|
||||||
Path,
|
|
||||||
Color,
|
Color,
|
||||||
PublicKey,
|
|
||||||
WalletType,
|
WalletType,
|
||||||
IsWallet,
|
|
||||||
IsChat,
|
|
||||||
CurrencyBalance,
|
|
||||||
Emoji,
|
Emoji,
|
||||||
DerivedFrom,
|
Assets,
|
||||||
|
CurrencyBalance,
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
Model* = ref object of QAbstractListModel
|
AccountsModel* = ref object of QAbstractListModel
|
||||||
items: seq[Item]
|
items: seq[AccountItem]
|
||||||
|
|
||||||
proc delete(self: Model) =
|
proc delete(self: AccountsModel) =
|
||||||
self.items = @[]
|
self.items = @[]
|
||||||
self.QAbstractListModel.delete
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
proc setup(self: Model) =
|
proc setup(self: AccountsModel) =
|
||||||
self.QAbstractListModel.setup
|
self.QAbstractListModel.setup
|
||||||
|
|
||||||
proc newModel*(): Model =
|
proc newAccountsModel*(): AccountsModel =
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
result.setup
|
result.setup
|
||||||
|
|
||||||
proc `$`*(self: Model): string =
|
proc `$`*(self: AccountsModel): string =
|
||||||
for i in 0 ..< self.items.len:
|
for i in 0 ..< self.items.len:
|
||||||
result &= fmt"""[{i}]:({$self.items[i]})"""
|
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
|
self.items.len
|
||||||
|
|
||||||
QtProperty[int] count:
|
QtProperty[int] count:
|
||||||
read = getCount
|
read = getCount
|
||||||
notify = countChanged
|
notify = countChanged
|
||||||
|
|
||||||
method rowCount(self: Model, index: QModelIndex = nil): int =
|
method rowCount(self: AccountsModel, index: QModelIndex = nil): int =
|
||||||
return self.items.len
|
return self.items.len
|
||||||
|
|
||||||
method roleNames(self: Model): Table[int, string] =
|
method roleNames(self: AccountsModel): Table[int, string] =
|
||||||
{
|
{
|
||||||
ModelRole.Name.int:"name",
|
ModelRole.Name.int:"name",
|
||||||
ModelRole.Address.int:"address",
|
ModelRole.Address.int:"address",
|
||||||
ModelRole.Path.int:"path",
|
|
||||||
ModelRole.Color.int:"color",
|
ModelRole.Color.int:"color",
|
||||||
ModelRole.PublicKey.int:"publicKey",
|
|
||||||
ModelRole.WalletType.int:"walletType",
|
ModelRole.WalletType.int:"walletType",
|
||||||
ModelRole.IsWallet.int:"isWallet",
|
|
||||||
ModelRole.IsChat.int:"isChat",
|
|
||||||
ModelRole.CurrencyBalance.int:"currencyBalance",
|
|
||||||
ModelRole.Emoji.int: "emoji",
|
ModelRole.Emoji.int: "emoji",
|
||||||
ModelRole.DerivedFrom.int: "derivedfrom",
|
ModelRole.Assets.int: "assets",
|
||||||
|
ModelRole.CurrencyBalance.int: "currencyBalance",
|
||||||
}.toTable
|
}.toTable
|
||||||
|
|
||||||
|
|
||||||
proc setItems*(self: Model, items: seq[Item]) =
|
proc setItems*(self: AccountsModel, items: seq[AccountItem]) =
|
||||||
self.beginResetModel()
|
self.beginResetModel()
|
||||||
self.items = items
|
self.items = items
|
||||||
self.endResetModel()
|
self.endResetModel()
|
||||||
self.countChanged()
|
self.countChanged()
|
||||||
|
|
||||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
method data(self: AccountsModel, index: QModelIndex, role: int): QVariant =
|
||||||
if (not index.isValid):
|
if (not index.isValid):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -85,21 +79,14 @@ QtObject:
|
||||||
result = newQVariant(item.getName())
|
result = newQVariant(item.getName())
|
||||||
of ModelRole.Address:
|
of ModelRole.Address:
|
||||||
result = newQVariant(item.getAddress())
|
result = newQVariant(item.getAddress())
|
||||||
of ModelRole.Path:
|
|
||||||
result = newQVariant(item.getPath())
|
|
||||||
of ModelRole.Color:
|
of ModelRole.Color:
|
||||||
result = newQVariant(item.getColor())
|
result = newQVariant(item.getColor())
|
||||||
of ModelRole.PublicKey:
|
|
||||||
result = newQVariant(item.getPublicKey())
|
|
||||||
of ModelRole.WalletType:
|
of ModelRole.WalletType:
|
||||||
result = newQVariant(item.getWalletType())
|
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:
|
of ModelRole.Emoji:
|
||||||
result = newQVariant(item.getEmoji())
|
result = newQVariant(item.getEmoji())
|
||||||
of ModelRole.DerivedFrom:
|
of ModelRole.Assets:
|
||||||
result = newQVariant(item.getDerivedFrom())
|
result = newQVariant(item.getAssets())
|
||||||
|
of ModelRole.CurrencyBalance:
|
||||||
|
result = newQVariant(item.getCurrencyBalance())
|
||||||
|
|
|
@ -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()
|
|
@ -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")
|
|
@ -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
|
|
@ -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),
|
||||||
|
)
|
|
@ -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.}
|
|
@ -10,8 +10,6 @@ import ../../../shared_modules/keycard_popup/io_interface as keycard_shared_modu
|
||||||
import ../../../../core/[main]
|
import ../../../../core/[main]
|
||||||
import ../../../../core/tasks/[qt, threadpool]
|
import ../../../../core/tasks/[qt, threadpool]
|
||||||
|
|
||||||
const UNIQUE_WALLET_SECTION_TRANSACTION_MODULE_IDENTIFIER* = "WalletSection-TransactionModule"
|
|
||||||
|
|
||||||
type
|
type
|
||||||
Controller* = ref object of RootObj
|
Controller* = ref object of RootObj
|
||||||
delegate: io_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
|
@ -45,6 +43,9 @@ proc delete*(self: Controller) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc init*(self: Controller) =
|
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):
|
self.events.on(SIGNAL_HISTORY_FETCHING) do (e:Args):
|
||||||
let args = HistoryArgs(e)
|
let args = HistoryArgs(e)
|
||||||
self.delegate.setHistoryFetchState(args.addresses, isFetching = true)
|
self.delegate.setHistoryFetchState(args.addresses, isFetching = true)
|
||||||
|
@ -69,18 +70,6 @@ proc init*(self: Controller) =
|
||||||
self.delegate.setHistoryFetchState(@[args.address], isFetching = false)
|
self.delegate.setHistoryFetchState(@[args.address], isFetching = false)
|
||||||
self.delegate.setTrxHistoryResult(args.transactions, args.collectibles, args.address, args.wasFetchMore)
|
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):
|
self.events.on(SIGNAL_TRANSACTION_LOADING_COMPLETED_FOR_ALL_NETWORKS) do(e:Args):
|
||||||
let args = TransactionsLoadedArgs(e)
|
let args = TransactionsLoadedArgs(e)
|
||||||
self.delegate.setHistoryFetchState(args.address, args.allTxLoaded, isFetching = false)
|
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 =
|
proc getWalletAccount*(self: Controller, accountIndex: int): WalletAccountDto =
|
||||||
return self.walletAccountService.getWalletAccount(accountIndex)
|
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) =
|
proc loadTransactions*(self: Controller, address: string, toBlock: Uint256, limit: int = 20, loadMore: bool = false) =
|
||||||
self.transactionService.loadTransactions(address, toBlock, limit, loadMore)
|
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] =
|
proc getAllTransactions*(self: Controller, address: string): seq[TransactionDto] =
|
||||||
return self.transactionService.getAllTransactions(address)
|
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 =
|
proc getChainIdForChat*(self: Controller): int =
|
||||||
return self.networkService.getNetworkForChat().chainId
|
return self.networkService.getNetworkForChat().chainId
|
||||||
|
|
||||||
proc getChainIdForBrowser*(self: Controller): int =
|
proc getChainIdForBrowser*(self: Controller): int =
|
||||||
return self.networkService.getNetworkForBrowser().chainId
|
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 =
|
proc getLastTxBlockNumber*(self: Controller): string =
|
||||||
return self.transactionService.getLastTxBlockNumber(self.networkService.getNetworkForBrowser().chainId)
|
return self.transactionService.getLastTxBlockNumber(self.networkService.getNetworkForBrowser().chainId)
|
||||||
|
|
||||||
proc getEnabledChainIds*(self: Controller): seq[int] =
|
proc getEnabledChainIds*(self: Controller): seq[int] =
|
||||||
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)
|
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 =
|
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
|
||||||
return self.currencyService.getCurrencyFormat(symbol)
|
return self.currencyService.getCurrencyFormat(symbol)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import stint
|
|
||||||
import ../../../../../app_service/service/wallet_account/dto as WalletDto
|
import ../../../../../app_service/service/wallet_account/dto as WalletDto
|
||||||
import ../../../../../app_service/service/collectible/dto as CollectibleDto
|
import ../../../../../app_service/service/collectible/dto as CollectibleDto
|
||||||
import ../../../../../app_service/service/transaction/dto
|
import ../../../../../app_service/service/transaction/dto
|
||||||
|
@ -23,9 +22,6 @@ method switchAccount*(self: AccessInterface, accountIndex: int) {.base.} =
|
||||||
method getWalletAccounts*(self: AccessInterface): seq[WalletAccountDto] {.base.} =
|
method getWalletAccounts*(self: AccessInterface): seq[WalletAccountDto] {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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.} =
|
method loadTransactions*(self: AccessInterface, address: string, toBlock: string, limit: int, loadMore: bool) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
@ -44,31 +40,15 @@ method setHistoryFetchState*(self: AccessInterface, address: string, allTxLoaded
|
||||||
method setIsNonArchivalNode*(self: AccessInterface, isNonArchivalNode: bool) {.base.} =
|
method setIsNonArchivalNode*(self: AccessInterface, isNonArchivalNode: bool) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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.} =
|
method transactionWasSent*(self: AccessInterface, result: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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 =
|
method getChainIdForChat*(self: AccessInterface): int =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getChainIdForBrowser*(self: AccessInterface): int =
|
method getChainIdForBrowser*(self: AccessInterface): int =
|
||||||
raise newException(ValueError, "No implementation available")
|
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.} =
|
method refreshTransactions*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
@ -80,6 +60,3 @@ method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
|
||||||
method getLastTxBlockNumber*(self: AccessInterface): string {.base.} =
|
method getLastTxBlockNumber*(self: AccessInterface): string {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method suggestedRoutesReady*(self: AccessInterface, suggestedRoutes: string) {.base.} =
|
|
||||||
raise newException(ValueError, "No implementation available")
|
|
||||||
|
|
|
@ -13,27 +13,14 @@ import ../../../../../app_service/service/collectible/service as collectible_ser
|
||||||
|
|
||||||
export io_interface
|
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
|
type
|
||||||
Module* = ref object of io_interface.AccessInterface
|
Module* = ref object of io_interface.AccessInterface
|
||||||
delegate: delegate_interface.AccessInterface
|
delegate: delegate_interface.AccessInterface
|
||||||
view: View
|
view: View
|
||||||
controller: Controller
|
controller: Controller
|
||||||
moduleLoaded: bool
|
moduleLoaded: bool
|
||||||
tmpSendTransactionDetails: TmpSendTransactionDetails
|
|
||||||
|
|
||||||
# Forward declarations
|
# Forward declarations
|
||||||
method getWalletAccounts*(self: Module): seq[WalletAccountDto]
|
|
||||||
method loadTransactions*(self: Module, address: string, toBlock: string = "0x0", limit: int = 20, loadMore: bool = false)
|
method loadTransactions*(self: Module, address: string, toBlock: string = "0x0", limit: int = 20, loadMore: bool = false)
|
||||||
|
|
||||||
proc newModule*(
|
proc newModule*(
|
||||||
|
@ -120,7 +107,7 @@ method refreshTransactions*(self: Module) =
|
||||||
self.view.setTrxHistoryResult(self.transactionsToItems(transactions, @[]), account.address, wasFetchMore=false)
|
self.view.setTrxHistoryResult(self.transactionsToItems(transactions, @[]), account.address, wasFetchMore=false)
|
||||||
|
|
||||||
method viewDidLoad*(self: Module) =
|
method viewDidLoad*(self: Module) =
|
||||||
let accounts = self.getWalletAccounts()
|
let accounts = self.controller.getWalletAccounts()
|
||||||
|
|
||||||
self.moduleLoaded = true
|
self.moduleLoaded = true
|
||||||
self.delegate.transactionsModuleDidLoad()
|
self.delegate.transactionsModuleDidLoad()
|
||||||
|
@ -131,12 +118,6 @@ method switchAccount*(self: Module, accountIndex: int) =
|
||||||
let walletAccount = self.controller.getWalletAccount(accountIndex)
|
let walletAccount = self.controller.getWalletAccount(accountIndex)
|
||||||
self.view.switchAccount(walletAccount)
|
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) =
|
method loadTransactions*(self: Module, address: string, toBlock: string = "0x0", limit: int = 20, loadMore: bool = false) =
|
||||||
let toBlockParsed = stint.fromHex(Uint256, toBlock)
|
let toBlockParsed = stint.fromHex(Uint256, toBlock)
|
||||||
let txLimit = if toBlock == "0x0":
|
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) =
|
method setHistoryFetchState*(self: Module, address: string, allTxLoaded: bool, isFetching: bool) =
|
||||||
self.view.setHistoryFetchState(address, allTxLoaded, isFetching)
|
self.view.setHistoryFetchState(address, allTxLoaded, isFetching)
|
||||||
|
|
||||||
|
|
||||||
method setIsNonArchivalNode*(self: Module, isNonArchivalNode: bool) =
|
method setIsNonArchivalNode*(self: Module, isNonArchivalNode: bool) =
|
||||||
self.view.setIsNonArchivalNode(isNonArchivalNode)
|
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 =
|
method getChainIdForChat*(self: Module): int =
|
||||||
return self.controller.getChainIdForChat()
|
return self.controller.getChainIdForChat()
|
||||||
|
|
||||||
method getChainIdForBrowser*(self: Module): int =
|
method getChainIdForBrowser*(self: Module): int =
|
||||||
return self.controller.getChainIdForBrowser()
|
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 =
|
method getLastTxBlockNumber*(self: Module): string =
|
||||||
return self.controller.getLastTxBlockNumber()
|
return self.controller.getLastTxBlockNumber()
|
||||||
|
|
||||||
method suggestedRoutesReady*(self: Module, suggestedRoutes: string) =
|
method transactionWasSent*(self: Module, result: string) =
|
||||||
self.view.suggestedRoutesReady(suggestedRoutes)
|
self.view.setPendingTx(self.transactionsToItems(self.controller.getPendingTransactions(), @[]))
|
|
@ -132,63 +132,15 @@ QtObject:
|
||||||
read = getIsNonArchivalNode
|
read = getIsNonArchivalNode
|
||||||
notify = isNonArchivalNodeChanged
|
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.} =
|
proc getChainIdForChat*(self: View): int {.slot.} =
|
||||||
return self.delegate.getChainIdForChat()
|
return self.delegate.getChainIdForChat()
|
||||||
|
|
||||||
proc getChainIdForBrowser*(self: View): int {.slot.} =
|
proc getChainIdForBrowser*(self: View): int {.slot.} =
|
||||||
return self.delegate.getChainIdForBrowser()
|
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.} =
|
proc getLastTxBlockNumber*(self: View): string {.slot.} =
|
||||||
return self.delegate.getLastTxBlockNumber()
|
return self.delegate.getLastTxBlockNumber()
|
||||||
|
|
||||||
proc suggestedRoutesReady*(self: View, suggestedRoutes: string) {.signal.}
|
|
||||||
|
|
||||||
proc setPendingTx*(self: View, pendingTx: seq[Item]) =
|
proc setPendingTx*(self: View, pendingTx: seq[Item]) =
|
||||||
for tx in pendingTx:
|
for tx in pendingTx:
|
||||||
if not self.enabledChainIds.contains(tx.getChainId()):
|
if not self.enabledChainIds.contains(tx.getChainId()):
|
||||||
|
|
|
@ -11,8 +11,8 @@ QtObject:
|
||||||
totalCurrencyBalance: CurrencyAmount
|
totalCurrencyBalance: CurrencyAmount
|
||||||
signingPhrase: string
|
signingPhrase: string
|
||||||
isMnemonicBackedUp: bool
|
isMnemonicBackedUp: bool
|
||||||
tmpAmount: float # 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 prepareCurrencyAmount/getPreparedCurrencyAmount procs
|
tmpSymbol: string # shouldn't be used anywhere except in prepare*/getPrepared* procs
|
||||||
|
|
||||||
proc setup(self: View) =
|
proc setup(self: View) =
|
||||||
self.QObject.setup
|
self.QObject.setup
|
||||||
|
|
|
@ -205,23 +205,3 @@ QtObject:
|
||||||
break
|
break
|
||||||
|
|
||||||
return false
|
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
|
|
||||||
)
|
|
||||||
|
|
|
@ -635,6 +635,14 @@ QtObject:
|
||||||
let accounts = self.getWalletAccounts()
|
let accounts = self.getWalletAccounts()
|
||||||
return accounts.map(a => a.getCurrencyBalance(chainIds, self.getCurrentCurrencyIfEmpty(currency))).foldl(a + b, 0.0)
|
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 = "") =
|
proc addMigratedKeyPairAsync*(self: Service, keyPair: KeyPairDto, password = "") =
|
||||||
# Providing a password corresponding local keystore file will be removed as well, though
|
# 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.
|
# in some contexts we just need to add keypair to the db, so password is not needed.
|
||||||
|
|
|
@ -193,7 +193,7 @@ QtObject {
|
||||||
|
|
||||||
property ListModel addToGroupContacts: ListModel {}
|
property ListModel addToGroupContacts: ListModel {}
|
||||||
|
|
||||||
property var walletSectionTransactionsInst: walletSectionTransactions
|
property var walletSectionSendInst: walletSectionSend
|
||||||
|
|
||||||
property bool isWakuV2StoreEnabled: advancedModule ? advancedModule.isWakuV2StoreEnabled : false
|
property bool isWakuV2StoreEnabled: advancedModule ? advancedModule.isWakuV2StoreEnabled : false
|
||||||
|
|
||||||
|
@ -515,7 +515,7 @@ QtObject {
|
||||||
|
|
||||||
// Needed for TX in chat for stickers and via contact
|
// 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 var currentAccount: walletSectionCurrent
|
||||||
property string currentCurrency: walletSection.currentCurrency
|
property string currentCurrency: walletSection.currentCurrency
|
||||||
property CurrenciesStore currencyStore: CurrenciesStore {}
|
property CurrenciesStore currencyStore: CurrenciesStore {}
|
||||||
|
@ -576,32 +576,19 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
function estimateGas(from_addr, to, assetSymbol, value, chainId, data) {
|
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) {
|
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 getAccountNameByAddress(address) {
|
|
||||||
return walletSectionAccounts.getAccountNameByAddress(address)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAccountIconColorByAddress(address) {
|
|
||||||
return walletSectionAccounts.getAccountIconColorByAddress(address)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAccountAssetsByAddress(address) {
|
|
||||||
walletSectionAccounts.setAddressForAssets(address)
|
|
||||||
return walletSectionAccounts.getAccountAssetsByAddress()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function suggestedFees(chainId) {
|
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) {
|
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) {
|
function resolveENS(value) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ QtObject {
|
||||||
|
|
||||||
property string username: !!Global.userProfile? Global.userProfile.username : ""
|
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) {
|
function setPrefferedEnsUsername(ensName) {
|
||||||
if(!root.ensUsernamesModule)
|
if(!root.ensUsernamesModule)
|
||||||
|
@ -145,7 +145,7 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEstimatedTime(chainId, maxFeePerGas) {
|
function getEstimatedTime(chainId, maxFeePerGas) {
|
||||||
return walletSectionTransactions.getEstimatedTime(chainId, maxFeePerGas)
|
return walletSectionSend.getEstimatedTime(chainId, maxFeePerGas)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStatusToken() {
|
function getStatusToken() {
|
||||||
|
@ -155,7 +155,7 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
function suggestedFees(chainId) {
|
function suggestedFees(chainId) {
|
||||||
return JSON.parse(walletSectionTransactions.suggestedFees(chainId))
|
return JSON.parse(walletSectionSend.suggestedFees(chainId))
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeEnsUsername(chainId, ensUsername) {
|
function removeEnsUsername(chainId, ensUsername) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ QtObject {
|
||||||
property var overview: walletSectionOverview
|
property var overview: walletSectionOverview
|
||||||
property var assets: walletSectionCurrent
|
property var assets: walletSectionCurrent
|
||||||
property var currentAccount: walletSectionCurrent
|
property var currentAccount: walletSectionCurrent
|
||||||
property var accounts: walletSectionAccounts.model
|
property var accounts: walletSectionAccounts.accounts
|
||||||
property var appSettings: localAppSettings
|
property var appSettings: localAppSettings
|
||||||
property var accountSensitiveSettings: localAccountSensitiveSettings
|
property var accountSensitiveSettings: localAccountSensitiveSettings
|
||||||
property bool hideSignPhraseModal: accountSensitiveSettings.hideSignPhraseModal
|
property bool hideSignPhraseModal: accountSensitiveSettings.hideSignPhraseModal
|
||||||
|
@ -126,10 +126,7 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchAccount(newIndex) {
|
function switchAccount(newIndex) {
|
||||||
if(Constants.isCppApp)
|
walletSection.switchAccount(newIndex)
|
||||||
walletSectionAccounts.switchAccount(newIndex)
|
|
||||||
else
|
|
||||||
walletSection.switchAccount(newIndex)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchAccountByAddress(address) {
|
function switchAccountByAddress(address) {
|
||||||
|
|
|
@ -391,7 +391,6 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
model: RootStore.accounts
|
model: RootStore.accounts
|
||||||
// model: RootStore.exampleWalletModel
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ Item {
|
||||||
visible: (stack.currentIndex === 2)
|
visible: (stack.currentIndex === 2)
|
||||||
|
|
||||||
account: RootStore.currentAccount
|
account: RootStore.currentAccount
|
||||||
address: RootStore.currentAccount.mixedcaseAddress
|
address: RootStore.currentAccount.address
|
||||||
networkConnectionStore: root.networkConnectionStore
|
networkConnectionStore: root.networkConnectionStore
|
||||||
}
|
}
|
||||||
TransactionDetailView {
|
TransactionDetailView {
|
||||||
|
|
|
@ -52,7 +52,7 @@ QtObject {
|
||||||
// property var walletModelInst: walletModel
|
// property var walletModelInst: walletModel
|
||||||
property var userProfileInst: userProfile
|
property var userProfileInst: userProfile
|
||||||
|
|
||||||
property var accounts: walletSectionAccounts.model
|
property var accounts: walletSectionSendInst.accounts
|
||||||
property var currentAccount: walletSectionCurrent
|
property var currentAccount: walletSectionCurrent
|
||||||
// Not Refactored Yet
|
// Not Refactored Yet
|
||||||
// property var profileModelInst: profileModel
|
// property var profileModelInst: profileModel
|
||||||
|
@ -67,7 +67,7 @@ QtObject {
|
||||||
property real volume: !!appSettings ? appSettings.volume * 0.01 : 0.5
|
property real volume: !!appSettings ? appSettings.volume * 0.01 : 0.5
|
||||||
property bool notificationSoundsEnabled: !!appSettings ? appSettings.notificationSoundsEnabled : true
|
property bool notificationSoundsEnabled: !!appSettings ? appSettings.notificationSoundsEnabled : true
|
||||||
|
|
||||||
property var walletSectionTransactionsInst: walletSectionTransactions
|
property var walletSectionSendInst: walletSectionSend
|
||||||
|
|
||||||
property var savedAddressesModel: walletSectionSavedAddresses.model
|
property var savedAddressesModel: walletSectionSavedAddresses.model
|
||||||
|
|
||||||
|
@ -117,11 +117,11 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
function suggestedFees(chainId) {
|
function suggestedFees(chainId) {
|
||||||
return JSON.parse(walletSectionTransactions.suggestedFees(chainId))
|
return JSON.parse(walletSectionSendInst.suggestedFees(chainId))
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEstimatedTime(chainId, maxFeePerGas) {
|
function getEstimatedTime(chainId, maxFeePerGas) {
|
||||||
return walletSectionTransactions.getEstimatedTime(chainId, maxFeePerGas)
|
return walletSectionSendInst.getEstimatedTime(chainId, maxFeePerGas)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChainIdForChat() {
|
function getChainIdForChat() {
|
||||||
|
|
|
@ -455,7 +455,7 @@ StatusDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: popup.store.walletSectionTransactionsInst
|
target: popup.store.walletSectionSendInst
|
||||||
function onSuggestedRoutesReady(suggestedRoutes: string) {
|
function onSuggestedRoutesReady(suggestedRoutes: string) {
|
||||||
let response = JSON.parse(suggestedRoutes)
|
let response = JSON.parse(suggestedRoutes)
|
||||||
if(!!response.error) {
|
if(!!response.error) {
|
||||||
|
@ -475,7 +475,7 @@ StatusDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: popup.store.walletSectionTransactionsInst
|
target: popup.store.walletSectionSendInst
|
||||||
function onTransactionSent(txResult: string) {
|
function onTransactionSent(txResult: string) {
|
||||||
d.isPendingTx = false
|
d.isPendingTx = false
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -322,7 +322,7 @@ StatusModal {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Connections {
|
// Connections {
|
||||||
// target: root.store.walletSectionTransactionsInst
|
// target: root.store.walletSectionSendInst
|
||||||
// onTransactionSent: {
|
// onTransactionSent: {
|
||||||
// try {
|
// try {
|
||||||
// let response = JSON.parse(txResult)
|
// let response = JSON.parse(txResult)
|
||||||
|
|
|
@ -15,10 +15,11 @@ QtObject {
|
||||||
|
|
||||||
property var mainModuleInst: mainModule
|
property var mainModuleInst: mainModule
|
||||||
property var walletSectionTransactionsInst: walletSectionTransactions
|
property var walletSectionTransactionsInst: walletSectionTransactions
|
||||||
|
property var walletSectionSendInst: walletSectionSend
|
||||||
|
|
||||||
property string currentCurrency: walletSection.currentCurrency
|
property string currentCurrency: walletSection.currentCurrency
|
||||||
property var allNetworks: networksModule.all
|
property var allNetworks: networksModule.all
|
||||||
property var accounts: walletSectionAccounts.model
|
property var accounts: walletSectionSendInst.accounts
|
||||||
property var currentAccount: walletSectionCurrent
|
property var currentAccount: walletSectionCurrent
|
||||||
property string signingPhrase: walletSection.signingPhrase
|
property string signingPhrase: walletSection.signingPhrase
|
||||||
property var savedAddressesModel: SortFilterProxyModel {
|
property var savedAddressesModel: SortFilterProxyModel {
|
||||||
|
@ -70,15 +71,15 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
function authenticateAndTransfer(from, to, tokenSymbol, amount, uuid, selectedRoutes) {
|
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) {
|
function suggestedFees(chainId) {
|
||||||
return JSON.parse(walletSectionTransactions.suggestedFees(chainId))
|
return JSON.parse(walletSectionSendInst.suggestedFees(chainId))
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEstimatedTime(chainId, maxFeePerGas) {
|
function getEstimatedTime(chainId, maxFeePerGas) {
|
||||||
return walletSectionTransactions.getEstimatedTime(chainId, maxFeePerGas)
|
return walletSectionSendInst.getEstimatedTime(chainId, maxFeePerGas)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChainIdForChat() {
|
function getChainIdForChat() {
|
||||||
|
@ -90,7 +91,7 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
function suggestedRoutes(account, amount, token, disabledFromChainIDs, disabledToChainIDs, preferredChainIds, sendType, lockedInAmounts) {
|
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) {
|
function hex2Eth(value) {
|
||||||
|
@ -265,8 +266,8 @@ QtObject {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
walletSectionAccounts.prepareTokenBalanceOnChain(selectedAccount.address, chainId, tokenSymbol)
|
walletSectionSendInst.prepareTokenBalanceOnChain(selectedAccount.address, chainId, tokenSymbol)
|
||||||
return walletSectionAccounts.getPreparedTokenBalanceOnChain()
|
return walletSectionSendInst.getPreparedTokenBalanceOnChain()
|
||||||
}
|
}
|
||||||
|
|
||||||
function findTokenSymbolByAddress(address) {
|
function findTokenSymbolByAddress(address) {
|
||||||
|
|
|
@ -223,12 +223,14 @@ Item {
|
||||||
fromAddress: transactionParamsObject.fromAddress
|
fromAddress: transactionParamsObject.fromAddress
|
||||||
selectedRecipient: root.selectedRecipient
|
selectedRecipient: root.selectedRecipient
|
||||||
onSendTransaction: {
|
onSendTransaction: {
|
||||||
Global.openPopup(signTxComponent, {selectedAccount: {
|
// TODO: https://github.com/status-im/status-desktop/issues/6778
|
||||||
name: root.store.getAccountNameByAddress(fromAddress),
|
console.log("not implemented")
|
||||||
address: fromAddress,
|
// Global.openPopup(signTxComponent, {selectedAccount: {
|
||||||
color: root.store.getAccountIconColorByAddress(fromAddress),
|
// name: root.store.getAccountNameByAddress(fromAddress),
|
||||||
assets: root.store.getAccountAssetsByAddress(fromAddress)
|
// address: fromAddress,
|
||||||
}})
|
// color: root.store.getAccountIconColorByAddress(fromAddress),
|
||||||
|
// assets: root.store.getAccountAssetsByAddress(fromAddress)
|
||||||
|
// }})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue