feat(wallet): Wallet accounts model improvements

This commit is contained in:
Emil Sawicki 2024-06-25 13:39:43 +02:00
parent 42533b8c61
commit d55dfaad9e
27 changed files with 257 additions and 480 deletions

View File

@ -50,6 +50,7 @@ proc switchAccount*(self: Module, accountIndex: int) =
let keycardAccount = self.controller.isKeycardAccount(walletAccount)
let currency = self.controller.getCurrentCurrency()
let enabledChainIds = self.controller.getEnabledChainIds()
let chainIds = self.controller.getChainIds()
let areTestNetworksEnabled = self.controller.areTestNetworksEnabled()
let currencyFormat = self.controller.getCurrencyFormat(currency)
let currencyBalance = self.controller.getTotalCurrencyBalance(walletAccount.address, enabledChainIds)
@ -57,6 +58,8 @@ proc switchAccount*(self: Module, accountIndex: int) =
let accountItem = walletAccountToWalletAccountsItem(
walletAccount,
keycardAccount,
chainIds,
enabledChainIds,
currencyBalance,
currencyFormat,
areTestNetworksEnabled,

View File

@ -73,4 +73,4 @@ proc getTotalCurrencyBalance*(self: Controller, address: string, chainIds: seq[i
return self.walletAccountService.getTotalCurrencyBalance(@[address], chainIds)
proc updateWatchAccountHiddenFromTotalBalance*(self: Controller, address: string, hideFromTotalBalance: bool) =
discard self.walletAccountService.updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance)
discard self.walletAccountService.updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance)

View File

@ -74,3 +74,6 @@ proc updateWatchAccountHiddenFromTotalBalance*(self: Controller, address: string
proc getTokensMarketValuesLoading*(self: Controller): bool =
return self.walletAccountService.getTokensMarketValuesLoading()
proc getChainIds*(self: Controller): seq[int] =
return self.networkService.getCurrentNetworks().map(n => n.chainId)

View File

@ -1,69 +1,127 @@
import NimQml
import ../../../shared_models/wallet_account_item
import ../../../shared_models/currency_amount
export wallet_account_item
type
Item* = ref object of WalletAccountItem
QtObject:
type Item* = ref object of WalletAccountItem
createdAt: int
assetsLoading: bool
currencyBalance: CurrencyAmount
isWallet: bool
canSend: bool
proc initItem*(
name: string = "",
address: string = "",
path: string = "",
colorId: string = "",
walletType: string = "",
currencyBalance: CurrencyAmount = nil,
emoji: string = "",
keyUid: string = "",
createdAt: int = 0,
position: int = 0,
keycardAccount: bool = false,
assetsLoading: bool = true,
isWallet: bool = false,
areTestNetworksEnabled: bool = false,
prodPreferredChainIds: string = "",
testPreferredChainIds: string = "",
hideFromTotalBalance: bool = false
): Item =
result = Item()
result.WalletAccountItem.setup(name,
address,
colorId,
emoji,
walletType,
path,
keyUid,
keycardAccount,
position,
operability = wa_dto.AccountFullyOperable,
areTestNetworksEnabled,
prodPreferredChainIds,
testPreferredChainIds,
hideFromTotalBalance)
result.createdAt = createdAt
result.assetsLoading = assetsLoading
result.currencyBalance = currencyBalance
result.isWallet = isWallet
proc setup*(self: Item,
name: string,
address: string,
path: string,
colorId: string,
walletType: string,
currencyBalance: CurrencyAmount,
emoji: string,
keyUid: string,
createdAt: int,
position: int,
keycardAccount: bool,
assetsLoading: bool,
isWallet: bool,
areTestNetworksEnabled: bool,
prodPreferredChainIds: string,
testPreferredChainIds: string,
hideFromTotalBalance: bool,
canSend: bool
) =
self.QObject.setup
self.WalletAccountItem.setup(name,
address,
colorId,
emoji,
walletType,
path,
keyUid,
keycardAccount,
position,
operability = wa_dto.AccountFullyOperable,
areTestNetworksEnabled,
prodPreferredChainIds,
testPreferredChainIds,
hideFromTotalBalance)
self.createdAt = createdAt
self.assetsLoading = assetsLoading
self.currencyBalance = currencyBalance
self.isWallet = isWallet
self.canSend = canSend
proc `$`*(self: Item): string =
result = "WalletSection-Accounts-Item("
result = result & $self.WalletAccountItem
result = result & "\nassetsLoading: " & $self.assetsLoading
result = result & "\ncurrencyBalance: " & $self.currencyBalance
result = result & ")"
proc delete*(self: Item) =
self.QObject.delete
proc currencyBalance*(self: Item): CurrencyAmount =
return self.currencyBalance
proc newItem*(
name: string = "",
address: string = "",
path: string = "",
colorId: string = "",
walletType: string = "",
currencyBalance: CurrencyAmount = nil,
emoji: string = "",
keyUid: string = "",
createdAt: int = 0,
position: int = 0,
keycardAccount: bool = false,
assetsLoading: bool = true,
isWallet: bool = false,
areTestNetworksEnabled: bool = false,
prodPreferredChainIds: string = "",
testPreferredChainIds: string = "",
hideFromTotalBalance: bool = false,
canSend: bool = true
): Item =
new(result, delete)
result.setup(name,
address,
path,
colorId,
walletType,
currencyBalance,
emoji,
keyUid,
createdAt,
position,
keycardAccount,
assetsLoading,
isWallet,
areTestNetworksEnabled,
prodPreferredChainIds,
testPreferredChainIds,
hideFromTotalBalance,
canSend)
proc assetsLoading*(self: Item): bool =
return self.assetsLoading
proc `$`*(self: Item): string =
result = "WalletSection-Accounts-Item("
result = result & $self.WalletAccountItem
result = result & "\nassetsLoading: " & $self.assetsLoading
result = result & "\ncurrencyBalance: " & $self.currencyBalance
result = result & "\canSend: " & $self.canSend
result = result & ")"
proc createdAt*(self: Item): int =
return self.createdAt
proc currencyBalance*(self: Item): CurrencyAmount =
return self.currencyBalance
proc isWallet*(self: Item): bool =
return self.isWallet
proc assetsLoading*(self: Item): bool =
return self.assetsLoading
proc createdAt*(self: Item): int =
return self.createdAt
proc isWallet*(self: Item): bool =
return self.isWallet
proc currencyBalanceChanged*(self: Item) {.signal.}
proc getCurrencyBalanceAsQVariant*(self: Item): QVariant {.slot.} =
return newQVariant(self.currencyBalance)
QtProperty[QVariant] currencyBalance:
read = getCurrencyBalanceAsQVariant
notify = currencyBalanceChanged
proc canSend*(self: Item): bool =
return self.canSend

View File

@ -19,7 +19,8 @@ type
AssetsLoading,
IsWallet,
PreferredSharingChainIds,
HideFromTotalBalance
HideFromTotalBalance,
CanSend
QtObject:
type
@ -70,7 +71,8 @@ QtObject:
ModelRole.AssetsLoading.int: "assetsLoading",
ModelRole.IsWallet.int: "isWallet",
ModelRole.PreferredSharingChainIds.int: "preferredSharingChainIds",
ModelRole.HideFromTotalBalance.int: "hideFromTotalBalance"
ModelRole.HideFromTotalBalance.int: "hideFromTotalBalance",
ModelRole.CanSend.int: "canSend"
}.toTable
@ -124,6 +126,8 @@ QtObject:
result = newQVariant(item.preferredSharingChainIds())
of ModelRole.HideFromTotalBalance:
result = newQVariant(item.hideFromTotalBalance())
of ModelRole.CanSend:
result = newQVariant(item.canSend())
proc getNameByAddress*(self: Model, address: string): string =
for item in self.items:

View File

@ -42,14 +42,18 @@ method delete*(self: Module) =
method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int]) =
let walletAccounts = self.controller.getWalletAccounts()
let currency = self.controller.getCurrentCurrency()
let allChainIds = self.controller.getChainIds()
let currencyFormat = self.controller.getCurrencyFormat(currency)
let areTestNetworksEnabled = self.controller.areTestNetworksEnabled()
let items = walletAccounts.map(w => (block:
let keycardAccount = self.controller.isKeycardAccount(w)
let currencyBalance = self.controller.getTotalCurrencyBalance(w.address, chainIds)
let keycardAccount = self.controller.isKeycardAccount(w)
walletAccountToWalletAccountsItem(
w,
keycardAccount,
allChainIds,
chainIds,
currencyBalance,
currencyFormat,
areTestNetworksEnabled,

View File

@ -1,77 +0,0 @@
import NimQml
import ../../../shared_models/wallet_account_item
import ../../../shared_models/currency_amount
export wallet_account_item
QtObject:
type AccountItem* = ref object of WalletAccountItem
currencyBalance: CurrencyAmount
canSend: bool
proc setup*(self: AccountItem,
keyUid: string,
name: string,
address: string,
colorId: string,
emoji: string,
walletType: string,
currencyBalance: CurrencyAmount,
position: int,
areTestNetworksEnabled: bool,
prodPreferredChainIds: string,
testPreferredChainIds: string,
canSend: bool
) =
self.QObject.setup
self.WalletAccountItem.setup(name,
address,
colorId,
emoji,
walletType,
path = "",
keyUid = keyUid,
keycardAccount = false,
position,
operability = wa_dto.AccountFullyOperable,
areTestNetworksEnabled,
prodPreferredChainIds,
testPreferredChainIds)
self.currencyBalance = currencyBalance
self.canSend = canSend
proc delete*(self: AccountItem) =
self.QObject.delete
proc newAccountItem*(
keyUid: string = "",
name: string = "",
address: string = "",
colorId: string = "",
emoji: string = "",
walletType: string = "",
currencyBalance: CurrencyAmount = nil,
areTestNetworksEnabled: bool = false,
prodPreferredChainIds: string = "",
testPreferredChainIds: string = "",
position: int = 0,
canSend: bool = true,
): AccountItem =
new(result, delete)
result.setup(keyUid, name, address, colorId, emoji, walletType, currencyBalance, position, areTestNetworksEnabled, prodPreferredChainIds, testPreferredChainIds, canSend)
proc `$`*(self: AccountItem): string =
result = "WalletSection-Send-Item("
result = result & $self.WalletAccountItem
result = result & "\ncurrencyBalance: " & $self.currencyBalance
result = result & ")"
proc currencyBalanceChanged*(self: AccountItem) {.signal.}
proc getCurrencyBalanceAsQVariant*(self: AccountItem): QVariant {.slot.} =
return newQVariant(self.currencyBalance)
QtProperty[QVariant] currencyBalance:
read = getCurrencyBalanceAsQVariant
notify = currencyBalanceChanged
proc canSend*(self: AccountItem): bool =
return self.canSend

View File

@ -1,109 +0,0 @@
import NimQml, Tables, strutils, stew/shims/strformat
import ./account_item
import ../../../shared_models/currency_amount
type
ModelRole {.pure.} = enum
KeyUid = UserRole + 1
Name
Address
ColorId
WalletType
Emoji
CurrencyBalance
Position
PreferredSharingChainIds
QtObject:
type
AccountsModel* = ref object of QAbstractListModel
items*: seq[AccountItem]
proc delete(self: AccountsModel) =
self.items = @[]
self.QAbstractListModel.delete
proc setup(self: AccountsModel) =
self.QAbstractListModel.setup
proc newAccountsModel*(): AccountsModel =
new(result, delete)
result.setup
proc `$`*(self: AccountsModel): string =
for i in 0 ..< self.items.len:
result &= fmt"""[{i}]:({$self.items[i]})"""
proc countChanged(self: AccountsModel) {.signal.}
proc getCount*(self: AccountsModel): int {.slot.} =
self.items.len
QtProperty[int] count:
read = getCount
notify = countChanged
method rowCount(self: AccountsModel, index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: AccountsModel): Table[int, string] =
{
ModelRole.KeyUid.int: "keyUid",
ModelRole.Name.int:"name",
ModelRole.Address.int:"address",
ModelRole.ColorId.int:"colorId",
ModelRole.WalletType.int:"walletType",
ModelRole.Emoji.int: "emoji",
ModelRole.CurrencyBalance.int: "currencyBalance",
ModelRole.Position.int: "position",
ModelRole.PreferredSharingChainIds.int: "preferredSharingChainIds"
}.toTable
proc setItems*(self: AccountsModel, items: seq[AccountItem]) =
self.beginResetModel()
self.items = items
self.endResetModel()
self.countChanged()
method data(self: AccountsModel, index: QModelIndex, role: int): QVariant =
if (not index.isValid):
return
if (index.row < 0 or index.row >= self.items.len):
return
let item = self.items[index.row]
let enumRole = role.ModelRole
case enumRole:
of ModelRole.KeyUid:
result = newQVariant(item.keyUid())
of ModelRole.Name:
result = newQVariant(item.name())
of ModelRole.Address:
result = newQVariant(item.address())
of ModelRole.ColorId:
result = newQVariant(item.colorId())
of ModelRole.WalletType:
result = newQVariant(item.walletType())
of ModelRole.Emoji:
result = newQVariant(item.emoji())
of ModelRole.Position:
result = newQVariant(item.getPosition())
of ModelRole.CurrencyBalance:
result = newQVariant(item.getCurrencyBalanceAsQVariant())
of ModelRole.PreferredSharingChainIds:
result = newQVariant(item.preferredSharingChainIds())
proc getItemByIndex*(self: AccountsModel, index: int): AccountItem =
if index < 0 or index >= self.items.len:
return
return self.items[index]
proc getItemByAddress*(self: AccountsModel, address: string): tuple[account: AccountItem, index: int] =
for i in 0 ..< self.items.len:
if self.items[i].address() == address:
return (self.items[i], i)
if self.items.len > 0:
return (self.items[0], 0)

View File

@ -18,9 +18,6 @@ method load*(self: AccessInterface) {.base.} =
method isLoaded*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
method refreshWalletAccounts*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getTokenBalance*(self: AccessInterface, address: string, chainId: int, tokensKey: string): CurrencyAmount {.base.} =
raise newException(ValueError, "No implementation available")
@ -55,7 +52,7 @@ method authenticateUser*(self: AccessInterface) {.base.} =
method onUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string) {.base.} =
raise newException(ValueError, "No implementation available")
method setSelectedSenderAccountIndex*(self: AccessInterface, index: int) {.base.} =
method notifySelectedSenderAccountChanged*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method setSelectedReceiveAccountIndex*(self: AccessInterface, index: int) {.base.} =

View File

@ -10,10 +10,8 @@ import app_service/service/currency/service as currency_service
import app_service/service/transaction/service as transaction_service
import app_service/service/keycard/service as keycard_service
import app_service/service/keycard/constants as keycard_constants
import app/modules/shared/wallet_utils
import app_service/service/transaction/dto
import app/modules/shared_models/currency_amount
import app_service/service/token/service
import app_service/service/network/network_item as network_service_item
import app/modules/shared_modules/collectibles/controller as collectiblesc
@ -56,9 +54,6 @@ type
tmpSendTransactionDetails: TmpSendTransactionDetails
tmpPin: string
tmpTxHashBeingProcessed: string
senderCurrentAccountIndex: int
# To-do we should create a dedicated module Receive
receiveCurrentAccountIndex: int
# Forward declaration
method getTokenBalance*(self: Module, address: string, chainId: int, tokensKey: string): CurrencyAmount
@ -87,8 +82,6 @@ proc newModule*(
result.view = newView(result)
result.moduleLoaded = false
result.senderCurrentAccountIndex = 0
result.receiveCurrentAccountIndex = 0
method delete*(self: Module) =
self.view.delete
@ -172,30 +165,6 @@ proc convertTransactionPathDtoToSuggestedRouteItem(self: Module, path: Transacti
approvalGasFees = path.approvalGasFees
)
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 areTestNetworksEnabled = self.controller.areTestNetworksEnabled()
let items = walletAccounts.map(w => (block:
let currencyBalance = self.controller.getTotalCurrencyBalance(@[w.address], enabledChainIds)
walletAccountToWalletSendAccountItem(
w,
chainIds,
enabledChainIds,
currencyBalance,
currencyFormat,
areTestNetworksEnabled,
)
))
self.view.setItems(items)
self.view.switchSenderAccount(self.senderCurrentAccountIndex)
self.view.switchReceiveAccount(self.receiveCurrentAccountIndex)
proc refreshNetworks*(self: Module) =
let networks = self.controller.getCurrentNetworks()
let fromNetworks = networks.map(x => self.convertNetworkDtoToNetworkItem(x))
@ -206,43 +175,9 @@ 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_KEYPAIR_SYNCED) do(e: Args):
self.refreshWalletAccounts()
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_UPDATED) do(e:Args):
self.refreshWalletAccounts()
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e:Args):
self.refreshWalletAccounts()
self.refreshNetworks()
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 = KeycardArgs(e)
if not args.success:
return
self.refreshWalletAccounts()
self.events.on(SIGNAL_WALLET_ACCOUNT_PREFERRED_SHARING_CHAINS_UPDATED) do(e:Args):
self.refreshWalletAccounts()
self.events.on(SIGNAL_WALLET_ACCOUNT_HIDDEN_UPDATED) do(e: Args):
self.refreshWalletAccounts()
self.events.on(SIGNAL_TOKENS_PRICES_UPDATED) do(e: Args):
self.refreshWalletAccounts()
self.controller.init()
self.view.load()
@ -250,7 +185,6 @@ method isLoaded*(self: Module): bool =
return self.moduleLoaded
method viewDidLoad*(self: Module) =
self.refreshWalletAccounts()
self.refreshNetworks()
self.moduleLoaded = true
self.delegate.sendModuleDidLoad()
@ -366,23 +300,19 @@ method suggestedRoutesReady*(self: Module, suggestedRoutes: SuggestedRoutesDto)
method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int]) =
if addresses.len == 0:
return
self.view.switchSenderAccountByAddress(addresses[0])
self.view.switchReceiveAccountByAddress(addresses[0])
self.view.setSenderAccount(addresses[0])
self.view.setReceiverAccount(addresses[0])
proc updateCollectiblesFilter*(self: Module) =
let senderAddress = self.view.getSenderAddressByIndex(self.senderCurrentAccountIndex)
let senderAddress = self.view.getSelectedSenderAccountAddress()
let addresses = @[senderAddress]
let chainIds = self.controller.getChainIds()
self.collectiblesController.setFilterAddressesAndChains(addresses, chainIds)
self.nestedCollectiblesModel.setAddress(senderAddress)
method setSelectedSenderAccountIndex*(self: Module, index: int) =
self.senderCurrentAccountIndex = index
method notifySelectedSenderAccountChanged*(self: Module) =
self.updateCollectiblesFilter()
method setSelectedReceiveAccountIndex*(self: Module, index: int) =
self.receiveCurrentAccountIndex = index
method getCollectiblesModel*(self: Module): collectibles.Model =
return self.collectiblesController.getModel()

View File

@ -1,6 +1,6 @@
import NimQml, sequtils, strutils, stint, sugar, options
import NimQml, sequtils, strutils, stint, options
import ./io_interface, ./accounts_model, ./account_item, ./network_model, ./network_item, ./suggested_route_item, ./transaction_routes
import ./io_interface, ./network_model, ./network_item, ./suggested_route_item, ./transaction_routes
import app/modules/shared_models/collectibles_model as collectibles
import app/modules/shared_models/collectibles_nested_model as nested_collectibles
import app_service/service/transaction/dto as transaction_dto
@ -9,14 +9,10 @@ QtObject:
type
View* = ref object of QObject
delegate: io_interface.AccessInterface
accounts: AccountsModel
# this one doesn't include watch accounts and its what the user switches when using the sendModal
senderAccounts: AccountsModel
# list of collectibles owned by the selected sender account
collectiblesModel: collectibles.Model
nestedCollectiblesModel: nested_collectibles.Model
# for send modal
selectedSenderAccount: AccountItem
fromNetworksModel: NetworkModel
toNetworksModel: NetworkModel
transactionRoutes: TransactionRoutes
@ -27,31 +23,24 @@ QtObject:
selectedTokenIsOwnerToken: bool
selectedTokenName: string
selectedRecipient: string
selectedSenderAccountAddress: string
# for receive modal
selectedReceiveAccount: AccountItem
selectedReceiveAccountAddress: string
# Forward declaration
proc updateNetworksDisabledChains(self: View)
proc updateNetworksTokenBalance(self: View)
proc delete*(self: View) =
self.accounts.delete
self.senderAccounts.delete
if self.selectedSenderAccount != nil:
self.selectedSenderAccount.delete
self.fromNetworksModel.delete
self.toNetworksModel.delete
self.transactionRoutes.delete
if self.selectedReceiveAccount != nil:
self.selectedReceiveAccount.delete
self.QObject.delete
proc newView*(delegate: io_interface.AccessInterface): View =
new(result, delete)
result.QObject.setup
result.delegate = delegate
result.accounts = newAccountsModel()
result.senderAccounts = newAccountsModel()
result.fromNetworksModel = newNetworkModel()
result.toNetworksModel = newNetworkModel()
result.transactionRoutes = newTransactionRoutes()
@ -61,19 +50,16 @@ QtObject:
proc load*(self: View) =
self.delegate.viewDidLoad()
proc accountsChanged*(self: View) {.signal.}
proc getAccounts(self: View): QVariant {.slot.} =
return newQVariant(self.accounts)
QtProperty[QVariant] accounts:
read = getAccounts
notify = accountsChanged
proc senderAccountsChanged*(self: View) {.signal.}
proc getSenderAccounts(self: View): QVariant {.slot.} =
return newQVariant(self.senderAccounts)
QtProperty[QVariant] senderAccounts:
read = getSenderAccounts
notify = senderAccountsChanged
proc selectedSenderAccountAddressChanged*(self: View) {.signal.}
proc getSelectedSenderAccountAddress*(self: View): string {.slot.} =
return self.selectedSenderAccountAddress
proc setSelectedSenderAccountAddress*(self: View, address: string) {.slot.} =
self.selectedSenderAccountAddress = address
self.updateNetworksTokenBalance()
self.selectedSenderAccountAddressChanged()
QtProperty[string] selectedSenderAccountAddress:
read = getSelectedSenderAccountAddress
notify = selectedSenderAccountAddressChanged
proc collectiblesModelChanged*(self: View) {.signal.}
proc getCollectiblesModel(self: View): QVariant {.slot.} =
@ -89,29 +75,15 @@ QtObject:
read = getNestedCollectiblesModel
notify = nestedCollectiblesModelChanged
proc selectedSenderAccountChanged*(self: View) {.signal.}
proc getSelectedSenderAccount(self: View): QVariant {.slot.} =
return newQVariant(self.selectedSenderAccount)
proc setSelectedSenderAccount*(self: View, account: AccountItem) =
self.selectedSenderAccount = account
self.updateNetworksTokenBalance()
self.selectedSenderAccountChanged()
QtProperty[QVariant] selectedSenderAccount:
read = getSelectedSenderAccount
notify = selectedSenderAccountChanged
proc getSenderAddressByIndex*(self: View, index: int): string {.slot.} =
return self.senderAccounts.getItemByIndex(index).address()
proc selectedReceiveAccountChanged*(self: View) {.signal.}
proc getSelectedReceiveAccount(self: View): QVariant {.slot.} =
return newQVariant(self.selectedReceiveAccount)
proc setSelectetReceiveAccount*(self: View, account: AccountItem) =
self.selectedReceiveAccount = account
self.selectedReceiveAccountChanged()
QtProperty[QVariant] selectedReceiveAccount:
read = getSelectedReceiveAccount
notify = selectedReceiveAccountChanged
proc selectedReceiveAccountAddressChanged*(self: View) {.signal.}
proc getSelectedReceiveAccountAddress*(self: View): string {.slot.} =
return self.selectedReceiveAccountAddress
proc setSelectedReceiveAccountAddress*(self: View, address: string) {.slot.} =
self.selectedReceiveAccountAddress = address
self.selectedReceiveAccountAddressChanged()
QtProperty[string] selectedReceiveAccountAddress:
read = getSelectedReceiveAccountAddress
notify = selectedReceiveAccountAddressChanged
proc fromNetworksModelChanged*(self: View) {.signal.}
proc getFromNetworksModel(self: View): QVariant {.slot.} =
@ -199,16 +171,8 @@ QtObject:
proc updateNetworksTokenBalance(self: View) =
for chainId in self.toNetworksModel.getAllNetworksChainIds():
self.fromNetworksModel.updateTokenBalanceForSymbol(chainId, self.delegate.getTokenBalance(self.selectedSenderAccount.address(), chainId, self.selectedAssetKey))
self.toNetworksModel.updateTokenBalanceForSymbol(chainId, self.delegate.getTokenBalance(self.selectedSenderAccount.address(), chainId, self.selectedAssetKey))
proc setItems*(self: View, items: seq[AccountItem]) =
self.accounts.setItems(items)
self.accountsChanged()
# need to remove watch only accounts as a user cant send a tx with a watch only account + remove not operable account
self.senderAccounts.setItems(items.filter(a => a.canSend()))
self.senderAccountsChanged()
self.fromNetworksModel.updateTokenBalanceForSymbol(chainId, self.delegate.getTokenBalance(self.selectedSenderAccountAddress, chainId, self.selectedAssetKey))
self.toNetworksModel.updateTokenBalanceForSymbol(chainId, self.delegate.getTokenBalance(self.selectedSenderAccountAddress, chainId, self.selectedAssetKey))
proc setNetworkItems*(self: View, fromNetworks: seq[NetworkItem], toNetworks: seq[NetworkItem]) =
self.fromNetworksModel.setItems(fromNetworks)
@ -233,7 +197,7 @@ QtObject:
return parsedChainIds
proc authenticateAndTransfer*(self: View, uuid: string) {.slot.} =
self.delegate.authenticateAndTransfer(self.selectedSenderAccount.address(), self.selectedRecipient, self.selectedAssetKey,
self.delegate.authenticateAndTransfer(self.selectedSenderAccountAddress, self.selectedRecipient, self.selectedAssetKey,
self.selectedToAssetKey, uuid, self.sendType, self.selectedTokenName, self.selectedTokenIsOwnerToken)
proc suggestedRoutesReady*(self: View, suggestedRoutes: QVariant) {.signal.}
@ -241,54 +205,27 @@ QtObject:
self.transactionRoutes = routes
self.suggestedRoutesReady(newQVariant(self.transactionRoutes))
proc suggestedRoutes*(self: View, amount: string) {.slot.} =
self.delegate.suggestedRoutes(self.selectedSenderAccount.address(), self.selectedRecipient,
parseAmount(amount), self.selectedAssetKey, self.selectedToAssetKey, self.fromNetworksModel.getRouteDisabledNetworkChainIds(),
proc suggestedRoutes*(self: View, amount: string): string {.slot.} =
var parsedAmount = stint.u256(0)
try:
parsedAmount = amount.parse(Uint256)
except Exception as e:
discard
self.delegate.suggestedRoutes(self.selectedSenderAccountAddress, self.selectedRecipient,
parsedAmount, self.selectedAssetKey, self.selectedToAssetKey, self.fromNetworksModel.getRouteDisabledNetworkChainIds(),
self.toNetworksModel.getRouteDisabledNetworkChainIds(), self.toNetworksModel.getRoutePreferredNetworkChainIds(),
self.sendType, self.fromNetworksModel.getRouteLockedChainIds())
proc switchSenderAccountByAddress*(self: View, address: string) {.slot.} =
let (account, index) = self.senderAccounts.getItemByAddress(address)
self.setSelectedSenderAccount(account)
self.delegate.setSelectedSenderAccountIndex(index)
proc switchReceiveAccountByAddress*(self: View, address: string) {.slot.} =
let (account, index) = self.accounts.getItemByAddress(address)
self.setSelectetReceiveAccount(account)
self.delegate.setSelectedReceiveAccountIndex(index)
proc switchSenderAccount*(self: View, index: int) {.slot.} =
var account = self.senderAccounts.getItemByIndex(index)
var idx = index
if account.isNil:
account = self.senderAccounts.getItemByIndex(0)
idx = 0
self.setSelectedSenderAccount(account)
self.delegate.setSelectedSenderAccountIndex(idx)
proc switchReceiveAccount*(self: View, index: int) {.slot.} =
var account = self.accounts.getItemByIndex(index)
var idx = index
if account.isNil:
account = self.accounts.getItemByIndex(0)
idx = 0
self.setSelectetReceiveAccount(account)
self.delegate.setSelectedReceiveAccountIndex(idx)
proc updateRoutePreferredChains*(self: View, chainIds: string) {.slot.} =
self.toNetworksModel.updateRoutePreferredChains(chainIds)
proc getSelectedSenderAccountAddress*(self: View): string =
return self.selectedSenderAccount.address()
proc updatedNetworksWithRoutes*(self: View, paths: seq[SuggestedRouteItem], totalFeesInEth: float) =
self.fromNetworksModel.resetPathData()
self.toNetworksModel.resetPathData()
for path in paths:
let fromChainId = path.getfromNetwork()
let hasGas = self.delegate.hasGas(self.selectedSenderAccount.address, fromChainId, self.fromNetworksModel.getNetworkNativeGasSymbol(fromChainId), totalFeesInEth)
let hasGas = self.delegate.hasGas(self.selectedSenderAccountAddress, fromChainId, self.fromNetworksModel.getNetworkNativeGasSymbol(fromChainId), totalFeesInEth)
self.fromNetworksModel.updateFromNetworks(path, hasGas)
self.toNetworksModel.updateToNetworks(path)
@ -350,4 +287,11 @@ QtObject:
slippagePercentage = slippagePercentageString.parseFloat().some
self.delegate.authenticateAndTransferWithPaths(accountFrom, accountTo, token,
toToken, uuid, sendType, tokenName, tokenIsOwnerToken, rawPaths, slippagePercentage)
toToken, uuid, sendType, tokenName, tokenIsOwnerToken, rawPaths, slippagePercentage)
proc setSenderAccount*(self: View, address: string) {.slot.} =
self.setSelectedSenderAccountAddress(address)
self.delegate.notifySelectedSenderAccountChanged()
proc setReceiverAccount*(self: View, address: string) {.slot.} =
self.setSelectedReceiveAccountAddress(address)

View File

@ -3,7 +3,6 @@ import ../shared_models/[currency_amount, wallet_account_item]
import app_service/service/currency/dto as currency_dto
import ../main/wallet_section/accounts/item as wallet_accounts_item
import ../main/wallet_section/send/account_item as wallet_send_account_item
proc currencyAmountToItem*(amount: float64, format: CurrencyFormatDto) : CurrencyAmount =
return newCurrencyAmount(
@ -35,9 +34,10 @@ proc walletAccountToWalletAccountItem*(w: WalletAccountDto, keycardAccount: bool
)
proc walletAccountToWalletAccountsItem*(w: WalletAccountDto, keycardAccount: bool,
chainIds: seq[int], enabledChainIds: seq[int],
currencyBalance: float64, currencyFormat: CurrencyFormatDto, areTestNetworksEnabled: bool,
marketValuesLoading: bool): wallet_accounts_item.Item =
return wallet_accounts_item.initItem(
return wallet_accounts_item.newItem(
w.name,
w.address,
w.path,
@ -54,21 +54,7 @@ proc walletAccountToWalletAccountsItem*(w: WalletAccountDto, keycardAccount: boo
areTestNetworksEnabled,
w.prodPreferredChainIds,
w.testPreferredChainIds,
w.hideFromTotalBalance
)
proc walletAccountToWalletSendAccountItem*(w: WalletAccountDto, chainIds: seq[int], enabledChainIds: seq[int],
currencyBalance: float64, currencyFormat: CurrencyFormatDto, areTestNetworksEnabled: bool): wallet_send_account_item.AccountItem =
return wallet_send_account_item.newAccountItem(
w.keyUid,
w.name,
w.address,
w.colorId,
w.emoji,
w.walletType,
currencyAmountToItem(currencyBalance, currencyFormat),
areTestNetworksEnabled,
w.prodPreferredChainIds,
w.testPreferredChainIds,
w.hideFromTotalBalance,
canSend=w.walletType != "watch" and (w.operable==AccountFullyOperable or w.operable==AccountPartiallyOperable)
)

View File

@ -217,8 +217,8 @@ SplitView {
}
ComboBox {
textRole: "name"
model: txStore.senderAccounts
onCurrentIndexChanged: loader.preSelectedAccount = txStore.senderAccounts.get(currentIndex)
model: txStore.accounts
onCurrentIndexChanged: loader.preSelectedAccount = txStore.accounts.get(currentIndex)
}
}

View File

@ -13,10 +13,10 @@ QtObject {
id: root
readonly property CurrenciesStore currencyStore: CurrenciesStore {}
readonly property var senderAccounts: WalletSendAccountsModel {
Component.onCompleted: selectedSenderAccount = senderAccounts.get(0)
readonly property var accounts: WalletSendAccountsModel {
Component.onCompleted: selectedSenderAccount = accounts.get(0)
}
property var accounts: senderAccounts
property WalletAssetsStore walletAssetStore
@ -27,7 +27,7 @@ QtObject {
property var flatNetworksModel: NetworksModel.flatNetworks
property var fromNetworksModel: NetworksModel.sendFromNetworks
property var toNetworksModel: NetworksModel.sendToNetworks
property var selectedSenderAccount: senderAccounts.get(0)
property var selectedSenderAccount: accounts.get(0)
readonly property QtObject collectiblesModel: ManageCollectiblesModel {}
readonly property QtObject nestedCollectiblesModel: WalletNestedCollectiblesModel {}
@ -170,10 +170,11 @@ QtObject {
}
}
function switchSenderAccountByAddress(address) {
for (let i = 0; i < senderAccounts.count; i++) {
if (senderAccounts.get(i).address === address) {
selectedSenderAccount = senderAccounts.get(i)
function setSenderAccountByAddress(address) {
for (let i = 0; i < accounts.count; i++) {
const acc = accounts.get(i)
if (acc.address === address && accounts.canSend) {
selectedSenderAccount = accounts.get(i)
break
}
}

View File

@ -486,8 +486,7 @@ QtObject {
}
// Needed for TX in chat for stickers and via contact
property var accounts: walletSectionSendInst.accounts
readonly property var accounts: walletSectionAccounts.accounts
property string currentCurrency: walletSection.currentCurrency
property CurrenciesStore currencyStore: CurrenciesStore {}
property var savedAddressesModel: walletSectionSavedAddresses.model

View File

@ -134,7 +134,7 @@ Item {
root.ensUsernamesStore.authenticateAndReleaseEns(
root.chainId,
root.username,
store.selectedSenderAccount.address,
store.selectedSenderAccountAddress,
path.gasAmount,
eip1559Enabled ? "" : path.gasFees.gasPrice,
eip1559Enabled ? path.gasFees.maxPriorityFeePerGas : "",

View File

@ -78,7 +78,7 @@ Item {
root.ensUsernamesStore.authenticateAndSetPubKey(
root.ensUsernamesStore.chainId,
ensUsername.text + (isStatus ? ".stateofus.eth" : "" ),
store.selectedSenderAccount.address,
store.selectedSenderAccountAddress,
path.gasAmount,
eip1559Enabled ? "" : path.gasFees.gasPrice,
"",

View File

@ -78,7 +78,7 @@ Item {
root.ensUsernamesStore.authenticateAndRegisterEns(
root.ensUsernamesStore.chainId,
username,
store.selectedSenderAccount.address,
store.selectedSenderAccountAddress,
path.gasAmount,
eip1559Enabled ? "" : path.gasFees.gasPrice,
eip1559Enabled ? path.gasFees.maxPriorityFeePerGas : "",

View File

@ -8,6 +8,7 @@ import StatusQ.Core.Utils 0.1 as StatusQUtils
import utils 1.0
import shared.controls 1.0
import shared.popups.keypairimport 1.0
import shared.stores.send 1.0
import "popups"
import "panels"
@ -23,6 +24,7 @@ Item {
property var store
property var contactsStore
property var communitiesStore
required property TransactionStore transactionStore
property var emojiPopup: null
property var sendModalPopup
property var networkConnectionStore
@ -282,6 +284,7 @@ Item {
width: parent.width
height: visible ? 61: implicitHeight
walletStore: RootStore
transactionStore: root.transactionStore
networkConnectionStore: root.networkConnectionStore
isCommunityOwnershipTransfer: footer.isHoldingSelected && footer.isOwnerCommunityCollectible
communityName: {

View File

@ -8,6 +8,7 @@ import StatusQ.Core.Theme 0.1
import utils 1.0
import shared.controls 1.0
import shared.stores.send 1.0
import "../controls"
import "../popups"
@ -17,6 +18,7 @@ Rectangle {
property var walletStore
property var networkConnectionStore
required property TransactionStore transactionStore
// Community-token related properties:
required property bool isCommunityOwnershipTransfer
@ -52,7 +54,10 @@ Rectangle {
icon.name: "send"
text: root.isCommunityOwnershipTransfer ? qsTr("Send Owner token to transfer %1 Community ownership").arg(root.communityName) : qsTr("Send")
interactive: !d.isCollectibleSoulbound && networkConnectionStore.sendBuyBridgeEnabled
onClicked: root.launchSendModal()
onClicked: {
root.transactionStore.setSenderAccount(root.walletStore.selectedAddress)
root.launchSendModal()
}
tooltip.text: d.isCollectibleSoulbound ? qsTr("Soulbound collectibles cannot be sent to another wallet") : networkConnectionStore.sendBuyBridgeToolTipText
visible: !walletStore.overview.isWatchOnlyAccount && walletStore.overview.canSend && !root.walletStore.showAllAccounts
}
@ -62,6 +67,7 @@ Rectangle {
text: qsTr("Receive")
visible: !root.walletStore.showAllAccounts
onClicked: function () {
root.transactionStore.setReceiverAccount(root.walletStore.selectedAddress)
launchShareAddressModal()
}
}

View File

@ -42,9 +42,7 @@ QtObject {
property string backButtonName: ""
property var overview: walletSectionOverview
property bool balanceLoading: overview.balanceLoading
property var accounts: walletSectionAccounts.accounts
property var receiveAccounts: walletSectionSend.accounts
property var selectedReceiveAccount: walletSectionSend.selectedReceiveAccount
readonly property var accounts: walletSectionAccounts.accounts
property var appSettings: localAppSettings
property var accountSensitiveSettings: localAccountSensitiveSettings
property bool hideSignPhraseModal: accountSensitiveSettings.hideSignPhraseModal
@ -65,7 +63,7 @@ QtObject {
}
property var nonWatchAccounts: SortFilterProxyModel {
sourceModel: receiveAccounts
sourceModel: accounts
proxyRoles: [
ExpressionRole {
name: "color"
@ -407,10 +405,6 @@ QtObject {
walletSection.runEditAccountPopup(address)
}
function switchReceiveAccountByAddress(address) {
walletSectionSend.switchReceiveAccountByAddress(address)
}
function toggleWatchOnlyAccounts() {
walletSection.toggleWatchOnlyAccounts()
}

View File

@ -153,8 +153,7 @@ QtObject {
// Not Refactored Yet
// property var walletModelInst: walletModel
property var userProfileInst: userProfile
property var accounts: walletSectionSendInst.accounts
readonly property var accounts: walletSectionAccounts.accounts
// Not Refactored Yet
// property var profileModelInst: profileModel

View File

@ -36,6 +36,8 @@ import StatusQ.Layout 0.1
import StatusQ.Popups 0.1
import StatusQ.Popups.Dialog 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Utils 0.1
import StatusQ 0.1
import AppLayouts.Browser.stores 1.0 as BrowserStores
import AppLayouts.stores 1.0
@ -1284,6 +1286,7 @@ Item {
store: appMain.rootStore
contactsStore: appMain.rootStore.profileSectionStore.contactsStore
communitiesStore: appMain.communitiesStore
transactionStore: appMain.transactionStore
emojiPopup: statusEmojiPopup.item
sendModalPopup: sendModal
networkConnectionStore: appMain.networkConnectionStore
@ -1946,25 +1949,32 @@ Item {
sourceComponent: WalletPopups.ReceiveModal {
ModelEntry {
id: selectedReceiverAccount
key: "address"
sourceModel: appMain.transactionStore.accounts
value: appMain.transactionStore.selectedReceiverAccountAddress
}
accounts: {
if (showQR.showSingleAccount || showQR.showForSavedAddress) {
return null
}
return WalletStore.RootStore.receiveAccounts
return WalletStore.RootStore.accounts
}
selectedAccount: {
if (showQR.showSingleAccount || showQR.showForSavedAddress) {
return showQR.selectedAccount
}
return WalletStore.RootStore.selectedReceiveAccount
return selectedReceiverAccount.item ?? ModelUtils.get(appMain.transactionStore.accounts, 0)
}
onUpdateSelectedAddress: (address) => {
if (showQR.showSingleAccount || showQR.showForSavedAddress) {
return
}
WalletStore.RootStore.switchReceiveAccountByAddress(address)
appMain.transactionStore.setReceiverAccount(address)
}
onUpdatePreferredChains: {

View File

@ -29,7 +29,7 @@ import "./views"
StatusDialog {
id: popup
property var preSelectedAccount: store.selectedSenderAccount
property var preSelectedAccount: selectedAccount
// expected content depends on the preSelectedRecipientType value.
// If type Address this must be a string else it expects an object. See RecipientView.selectedRecipientType
property var preSelectedRecipient
@ -56,6 +56,8 @@ StatusDialog {
standardButtons: StandardButton.Ok
}
readonly property var selectedAccount: selectedSenderAccountEntry.item ?? ModelUtils.get(store.accounts, 0)
property var sendTransaction: function() {
d.isPendingTx = true
popup.store.authenticateAndTransfer(d.uuid)
@ -148,6 +150,13 @@ StatusDialog {
}
}
ModelEntry {
id: selectedSenderAccountEntry
key: "address"
sourceModel: popup.store.accounts
value: popup.store.walletSectionSendInst.selectedSenderAccountAddress
}
bottomPadding: 16
padding: 0
background: StatusDialogBackground {
@ -200,7 +209,15 @@ StatusDialog {
AccountSelectorHeader {
id: accountSelector
model: SortFilterProxyModel {
sourceModel: popup.store.senderAccounts
sourceModel: SortFilterProxyModel {
sourceModel: popup.store.accounts
filters: [
ValueFilter {
roleName: "canSend"
value: true
}
]
}
sorters: RoleSorter { roleName: "position"; sortOrder: Qt.AscendingOrder }
proxyRoles: [
@ -217,7 +234,7 @@ StatusDialog {
}
selectedAddress: !!popup.preSelectedAccount && !!popup.preSelectedAccount.address ? popup.preSelectedAccount.address : ""
onCurrentAccountAddressChanged: {
store.switchSenderAccountByAddress(currentAccountAddress)
store.setSenderAccount(currentAccountAddress)
if (d.isSelectedHoldingValidAsset) {
d.setSelectedHoldingId(d.selectedHolding.symbol, d.selectedHoldingType)
}

View File

@ -220,7 +220,7 @@ Item {
let eip1559Enabled = path.gasFees.eip1559Enabled
let maxFeePerGas = path.gasFees.maxFeePerGasM
root.store.stickersStore.authenticateAndBuy(packId,
store.selectedSenderAccount.address,
store.selectedSenderAccountAddress,
path.gasAmount,
eip1559Enabled ? "" : path.gasFees.gasPrice,
eip1559Enabled ? path.gasFees.maxPriorityFeePerGas : "",

View File

@ -90,7 +90,7 @@ ModalPopup {
let eip1559Enabled = path.gasFees.eip1559Enabled
let maxFeePerGas = path.gasFees.maxFeePerGasM
stickerPackDetailsPopup.store.stickersStore.authenticateAndBuy(packId,
store.selectedSenderAccount.address,
store.selectedSenderAccountAddress,
path.gasAmount,
eip1559Enabled ? "" : path.gasFees.gasPrice,
eip1559Enabled ? path.gasFees.maxPriorityFeePerGas : "",

View File

@ -21,12 +21,13 @@ QtObject {
property var mainModuleInst: mainModule
property var walletSectionSendInst: walletSectionSend
readonly property var accounts: walletSectionAccounts.accounts
property var fromNetworksModel: walletSectionSendInst.fromNetworksModel
property var toNetworksModel: walletSectionSendInst.toNetworksModel
property var flatNetworksModel: networksModule.flatNetworks
property var senderAccounts: walletSectionSendInst.senderAccounts
property var selectedSenderAccount: walletSectionSendInst.selectedSenderAccount
property var accounts: walletSectionSendInst.accounts
readonly property var selectedReceiverAccountAddress: walletSectionSendInst.selectedReceiveAccountAddress
readonly property var selectedSenderAccountAddress: walletSectionSendInst.selectedSenderAccountAddress
property var collectiblesModel: walletSectionSendInst.collectiblesModel
property var nestedCollectiblesModel: walletSectionSendInst.nestedCollectiblesModel
property bool areTestNetworksEnabled: networksModule.areTestNetworksEnabled
@ -188,8 +189,12 @@ QtObject {
}
}
function switchSenderAccountByAddress(address) {
walletSectionSendInst.switchSenderAccountByAddress(address)
function setSenderAccount(address) {
walletSectionSendInst.setSenderAccount(address)
}
function setReceiverAccount(address) {
walletSectionSendInst.setReceiverAccount(address)
}
function getNetworkShortNames(chainIds) {
@ -277,7 +282,7 @@ QtObject {
filters: [
ValueFilter {
roleName: "account"
value: root.selectedSenderAccount.address
value: root.selectedSenderAccountAddress
}
]
}