refactor wallet views
add getSettings methods to src/status fix issue with calling getSettings; document issue remove most direct references to libstatus; document some common issues remove most references to libstatus wallet add mailserver layer to status lib; remove references to libstatus mailservers remove libstatus accounts references move types out of libstatus; remove libstatus types references remove libstatus browser references refactor libstatus utils references remove more references to libstatus stickers remove references to libstatus constants from src/app remove more libstatus references from src/app refactor token_list usage of libstatus refactor stickers usage of libstatus refactor chat usage of libstatus remove libstatus references from the wallet view remove logic from ens manager view fix issue with import & namespace conflict remove unnecessary imports refactor provider view to not depend on libstatus refactor provider view refactor: move accounts specific code to its own section fix account selection move collectibles to their own module update references to wallet transactions refactor: move gas methods to their own file refactor: extract tokens into their own file refactor: extract ens to its own file refactor: extract dappbrowser code to its own file refactor: extract history related code to its own file refactor: extract balance to its own file refactor: extract utils to its own file clean up wallet imports fix: identicon for transaction commands Fixes #2533
This commit is contained in:
parent
d5dc7c29ca
commit
6bcdb9ca54
|
@ -96,10 +96,23 @@ Typically this means the method has no return type and so `result =` isn't neces
|
|||
|
||||
This usually means a method that has no return type is being discarded
|
||||
|
||||
### required type for <variable>: <Type> but expression '<variable>' is of type: <Type>
|
||||
### required type for <variable>: <Type> but expression '<variable>' is of type: <Type>
|
||||
|
||||
This tpyically means there is an import missing
|
||||
|
||||
### type mismatch: got <Type>
|
||||
|
||||
```
|
||||
Error: type mismatch: got <WalletView>
|
||||
but expected one of:
|
||||
template `.`(a: Wrapnil; b): untyped
|
||||
first type mismatch at position: 1
|
||||
required type for a: Wrapnil
|
||||
but expression 'self' is of type: WalletView
|
||||
```
|
||||
|
||||
There is likely a typo or the method is not public
|
||||
|
||||
## Warnings
|
||||
|
||||
### QML anchor warnings
|
||||
|
|
|
@ -2,7 +2,6 @@ import NimQml, Tables, std/wrapnils
|
|||
import ../../../status/[chat/chat, status, ens, accounts, settings]
|
||||
from ../../../status/types import Setting
|
||||
import ../../../status/utils as status_utils
|
||||
# import ../../../status/settings as status_settings
|
||||
|
||||
import chat_members
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import ../../utils/image_utils
|
|||
import ../../../status/signals/types as signal_types
|
||||
import ../../../status/types
|
||||
|
||||
|
||||
logScope:
|
||||
topics = "communities-view"
|
||||
|
||||
|
|
|
@ -7,12 +7,6 @@ import nbaser
|
|||
import stew/byteutils
|
||||
from base32 import nil
|
||||
|
||||
const HTTPS_SCHEME = "https"
|
||||
const IPFS_GATEWAY = ".infura.status.im"
|
||||
const SWARM_GATEWAY = "swarm-gateways.net"
|
||||
|
||||
const base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
|
||||
logScope:
|
||||
topics = "provider-view"
|
||||
|
||||
|
@ -68,21 +62,8 @@ QtObject:
|
|||
self.status.permissions.clearPermissions()
|
||||
|
||||
proc ensResourceURL*(self: Web3ProviderView, ens: string, url: string): string {.slot.} =
|
||||
let contentHash = contenthash(ens)
|
||||
if contentHash == "": # ENS does not have a content hash
|
||||
return url_replaceHostAndAddPath(url, url_host(url), HTTPS_SCHEME)
|
||||
|
||||
let decodedHash = contentHash.decodeENSContentHash()
|
||||
case decodedHash[0]:
|
||||
of ENSType.IPFS:
|
||||
let base32Hash = base32.encode(string.fromBytes(base58.decode(decodedHash[1]))).toLowerAscii().replace("=", "")
|
||||
result = url_replaceHostAndAddPath(url, base32Hash & IPFS_GATEWAY, HTTPS_SCHEME)
|
||||
of ENSType.SWARM:
|
||||
result = url_replaceHostAndAddPath(url, SWARM_GATEWAY, HTTPS_SCHEME, "/bzz:/" & decodedHash[1] & "/")
|
||||
of ENSType.IPNS:
|
||||
result = url_replaceHostAndAddPath(url, decodedHash[1], HTTPS_SCHEME)
|
||||
else:
|
||||
warn "Unknown content for", ens, contentHash
|
||||
let (url, base, http_scheme, path_prefix, hasContentHash) = self.status.provider.ensResourceURL(ens, url)
|
||||
result = url_replaceHostAndAddPath(url, (if hasContentHash: base else: url_host(base)), http_scheme, path_prefix)
|
||||
|
||||
proc replaceHostByENS*(self: Web3ProviderView, url: string, ens: string): string {.slot.} =
|
||||
result = url_replaceHostAndAddPath(url, ens)
|
||||
|
@ -90,8 +71,5 @@ QtObject:
|
|||
proc getHost*(self: Web3ProviderView, url: string): string {.slot.} =
|
||||
result = url_host(url)
|
||||
|
||||
proc signMessage*(self: Web3ProviderView, payload: string, password: string) {.slot.} =
|
||||
let jsonPayload = payload.parseJson
|
||||
|
||||
proc init*(self: Web3ProviderView) =
|
||||
self.setDappsAddress(self.status.settings.getSetting[:string](Setting.DappsAddress))
|
||||
|
|
|
@ -40,7 +40,7 @@ proc init*(self: WalletController) =
|
|||
|
||||
self.status.events.on("newAccountAdded") do(e: Args):
|
||||
var account = WalletTypes.AccountArgs(e)
|
||||
self.view.accounts.addAccountToList(account.account)
|
||||
self.view.addAccountToList(account.account)
|
||||
self.view.updateView()
|
||||
|
||||
self.status.events.on("assetChanged") do(e: Args):
|
||||
|
|
|
@ -1,630 +1,153 @@
|
|||
import # std libs
|
||||
algorithm, atomics, sequtils, strformat, strutils, sugar, sequtils, json,
|
||||
parseUtils, std/wrapnils, tables
|
||||
import atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, tables
|
||||
import NimQml, chronicles, stint
|
||||
|
||||
import # vendor libs
|
||||
NimQml, chronicles, stint
|
||||
|
||||
import # status-desktop libs
|
||||
../../status/[status, wallet, settings, tokens],
|
||||
../../status/wallet/collectibles as status_collectibles,
|
||||
../../status/wallet as status_wallet,
|
||||
../../status/types,
|
||||
../../status/utils as status_utils,
|
||||
../../status/tokens as status_tokens,
|
||||
../../status/ens as status_ens,
|
||||
views/[asset_list, account_list, account_item, token_list, transaction_list, collectibles_list],
|
||||
../../status/tasks/[qt, task_runner_impl], ../../status/signals/types as signal_types
|
||||
|
||||
const ZERO_ADDRESS* = "0x0000000000000000000000000000000000000000"
|
||||
|
||||
type
|
||||
SendTransactionTaskArg = ref object of QObjectTaskArg
|
||||
from_addr: string
|
||||
to: string
|
||||
assetAddress: string
|
||||
value: string
|
||||
gas: string
|
||||
gasPrice: string
|
||||
password: string
|
||||
uuid: string
|
||||
InitBalancesTaskArg = ref object of QObjectTaskArg
|
||||
address: string
|
||||
tokenList: seq[string]
|
||||
LoadCollectiblesTaskArg = ref object of QObjectTaskArg
|
||||
address: string
|
||||
collectiblesType: string
|
||||
running*: ByteAddress # pointer to threadpool's `.running` Atomic[bool]
|
||||
GasPredictionsTaskArg = ref object of QObjectTaskArg
|
||||
LoadTransactionsTaskArg = ref object of QObjectTaskArg
|
||||
address: string
|
||||
toBlock: Uint256
|
||||
limit: int
|
||||
loadMore: bool
|
||||
ResolveEnsTaskArg = ref object of QObjectTaskArg
|
||||
ens: string
|
||||
uuid: string
|
||||
WatchTransactionTaskArg = ref object of QObjectTaskArg
|
||||
transactionHash: string
|
||||
|
||||
const sendTransactionTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[SendTransactionTaskArg](argEncoded)
|
||||
var
|
||||
success: bool
|
||||
response: string
|
||||
if arg.assetAddress != ZERO_ADDRESS and not arg.assetAddress.isEmptyOrWhitespace:
|
||||
response = wallet.sendTokenTransaction(arg.from_addr, arg.to, arg.assetAddress, arg.value, arg.gas, arg.gasPrice, arg.password, success)
|
||||
else:
|
||||
response = wallet.sendTransaction(arg.from_addr, arg.to, arg.value, arg.gas, arg.gasPrice, arg.password, success)
|
||||
let output = %* { "result": %response, "success": %success, "uuid": %arg.uuid }
|
||||
arg.finish(output)
|
||||
|
||||
proc sendTransaction[T](self: T, slot: string, from_addr: string, to: string, assetAddress: string, value: string, gas: string, gasPrice: string, password: string, uuid: string) =
|
||||
let arg = SendTransactionTaskArg(
|
||||
tptr: cast[ByteAddress](sendTransactionTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot,
|
||||
from_addr: from_addr,
|
||||
to: to,
|
||||
assetAddress: assetAddress,
|
||||
value: value,
|
||||
gas: gas,
|
||||
gasPrice: gasPrice,
|
||||
password: password,
|
||||
uuid: uuid
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
const initBalancesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[InitBalancesTaskArg](argEncoded)
|
||||
var tokenBalances = initTable[string, string]()
|
||||
for token in arg.tokenList:
|
||||
tokenBalances[token] = status_tokens.getTokenBalance(token, arg.address)
|
||||
let output = %* {
|
||||
"address": arg.address,
|
||||
"eth": getEthBalance(arg.address),
|
||||
"tokens": tokenBalances
|
||||
}
|
||||
arg.finish(output)
|
||||
|
||||
proc initBalances[T](self: T, slot: string, address: string, tokenList: seq[string]) =
|
||||
let arg = InitBalancesTaskArg(
|
||||
tptr: cast[ByteAddress](initBalancesTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot,
|
||||
address: address,
|
||||
tokenList: tokenList
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
const loadCollectiblesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[LoadCollectiblesTaskArg](argEncoded)
|
||||
var running = cast[ptr Atomic[bool]](arg.running)
|
||||
var collectiblesOrError = ""
|
||||
case arg.collectiblesType:
|
||||
of status_collectibles.CRYPTOKITTY:
|
||||
collectiblesOrError = status_collectibles.getCryptoKitties(arg.address)
|
||||
of status_collectibles.KUDO:
|
||||
collectiblesOrError = status_collectibles.getKudos(arg.address)
|
||||
of status_collectibles.ETHERMON:
|
||||
collectiblesOrError = status_collectibles.getEthermons(arg.address)
|
||||
of status_collectibles.STICKER:
|
||||
collectiblesOrError = status_collectibles.getStickers(arg.address, running[])
|
||||
|
||||
let output = %*{
|
||||
"address": arg.address,
|
||||
"collectibleType": arg.collectiblesType,
|
||||
"collectiblesOrError": collectiblesOrError
|
||||
}
|
||||
arg.finish(output)
|
||||
|
||||
proc loadCollectibles[T](self: T, slot: string, address: string, collectiblesType: string) =
|
||||
let arg = LoadCollectiblesTaskArg(
|
||||
tptr: cast[ByteAddress](loadCollectiblesTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot,
|
||||
address: address,
|
||||
collectiblesType: collectiblesType,
|
||||
running: cast[ByteAddress](addr self.status.tasks.threadpool.running)
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
const getGasPredictionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let
|
||||
arg = decode[GasPredictionsTaskArg](argEncoded)
|
||||
output = %getGasPricePredictions()
|
||||
arg.finish(output)
|
||||
|
||||
proc getGasPredictions[T](self: T, slot: string) =
|
||||
let arg = GasPredictionsTaskArg(
|
||||
tptr: cast[ByteAddress](getGasPredictionsTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
const loadTransactionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let
|
||||
arg = decode[LoadTransactionsTaskArg](argEncoded)
|
||||
output = %*{
|
||||
"address": arg.address,
|
||||
"history": status_wallet.getTransfersByAddress(arg.address, arg.toBlock, arg.limit, arg.loadMore),
|
||||
"loadMore": arg.loadMore
|
||||
}
|
||||
arg.finish(output)
|
||||
|
||||
proc loadTransactions[T](self: T, slot: string, address: string, toBlock: Uint256, limit: int, loadMore: bool) =
|
||||
let arg = LoadTransactionsTaskArg(
|
||||
tptr: cast[ByteAddress](loadTransactionsTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot,
|
||||
address: address,
|
||||
toBlock: toBlock,
|
||||
limit: limit,
|
||||
loadMore: loadMore
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
const resolveEnsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let
|
||||
arg = decode[ResolveEnsTaskArg](argEncoded)
|
||||
output = %* { "address": status_ens.address(arg.ens), "uuid": arg.uuid }
|
||||
arg.finish(output)
|
||||
|
||||
proc resolveEns[T](self: T, slot: string, ens: string, uuid: string) =
|
||||
let arg = ResolveEnsTaskArg(
|
||||
tptr: cast[ByteAddress](resolveEnsTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot,
|
||||
ens: ens,
|
||||
uuid: uuid
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
const watchTransactionTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let
|
||||
arg = decode[WatchTransactionTaskArg](argEncoded)
|
||||
response = status_wallet.watchTransaction(arg.transactionHash)
|
||||
output = %* { "result": response }
|
||||
arg.finish(output)
|
||||
|
||||
proc watchTransaction[T](self: T, slot: string, transactionHash: string) =
|
||||
let arg = WatchTransactionTaskArg(
|
||||
tptr: cast[ByteAddress](watchTransactionTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot,
|
||||
transactionHash: transactionHash
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
import
|
||||
../../status/[status, wallet],
|
||||
views/[accounts, collectibles, transactions, tokens, gas, ens, dapp_browser, history, balance, utils, asset_list, account_list]
|
||||
|
||||
QtObject:
|
||||
type
|
||||
WalletView* = ref object of QAbstractListModel
|
||||
accounts*: AccountList
|
||||
currentAssetList*: AssetList
|
||||
currentCollectiblesLists*: CollectiblesList
|
||||
currentAccount: AccountItemView
|
||||
focusedAccount: AccountItemView
|
||||
dappBrowserAccount: AccountItemView
|
||||
currentTransactions: TransactionList
|
||||
defaultTokenList: TokenList
|
||||
customTokenList: TokenList
|
||||
status: Status
|
||||
totalFiatBalance: string
|
||||
etherscanLink: string
|
||||
safeLowGasPrice: string
|
||||
standardGasPrice: string
|
||||
fastGasPrice: string
|
||||
fastestGasPrice: string
|
||||
defaultGasLimit: string
|
||||
signingPhrase: string
|
||||
fetchingHistoryState: Table[string, bool]
|
||||
accountsView: AccountsView
|
||||
collectiblesView: CollectiblesView
|
||||
transactionsView*: TransactionsView
|
||||
tokensView*: TokensView
|
||||
dappBrowserView*: DappBrowserView
|
||||
gasView*: GasView
|
||||
ensView*: EnsView
|
||||
historyView*: HistoryView
|
||||
balanceView*: BalanceView
|
||||
utilsView*: UtilsView
|
||||
isNonArchivalNode: bool
|
||||
|
||||
proc delete(self: WalletView) =
|
||||
self.accounts.delete
|
||||
self.currentAssetList.delete
|
||||
self.currentAccount.delete
|
||||
self.focusedAccount.delete
|
||||
self.dappBrowserAccount.delete
|
||||
self.currentTransactions.delete
|
||||
self.defaultTokenList.delete
|
||||
self.customTokenList.delete
|
||||
self.accountsView.delete
|
||||
self.gasView.delete
|
||||
self.ensView.delete
|
||||
self.utilsView.delete
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: WalletView) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc setDappBrowserAddress*(self: WalletView)
|
||||
|
||||
proc newWalletView*(status: Status): WalletView =
|
||||
new(result, delete)
|
||||
result.status = status
|
||||
result.accounts = newAccountList()
|
||||
result.currentAccount = newAccountItemView()
|
||||
result.focusedAccount = newAccountItemView()
|
||||
result.dappBrowserAccount = newAccountItemView()
|
||||
result.currentAssetList = newAssetList()
|
||||
result.currentTransactions = newTransactionList()
|
||||
result.currentCollectiblesLists = newCollectiblesList()
|
||||
result.defaultTokenList = newTokenList(status)
|
||||
result.customTokenList = newTokenList(status)
|
||||
result.totalFiatBalance = ""
|
||||
result.etherscanLink = ""
|
||||
result.safeLowGasPrice = "0"
|
||||
result.standardGasPrice = "0"
|
||||
result.fastGasPrice = "0"
|
||||
result.fastestGasPrice = "0"
|
||||
result.defaultGasLimit = "21000"
|
||||
result.signingPhrase = ""
|
||||
result.fetchingHistoryState = initTable[string, bool]()
|
||||
|
||||
result.accountsView = newAccountsView(status)
|
||||
result.collectiblesView = newCollectiblesView(status, result.accountsView)
|
||||
result.transactionsView = newTransactionsView(status, result.accountsView)
|
||||
result.tokensView = newTokensView(status, result.accountsView)
|
||||
result.gasView = newGasView(status)
|
||||
result.ensView = newEnsView(status)
|
||||
result.dappBrowserView = newDappBrowserView(status, result.accountsView)
|
||||
result.historyView = newHistoryView(status, result.accountsView, result.transactionsView)
|
||||
result.balanceView = newBalanceView(status, result.accountsView, result.transactionsView, result.historyView)
|
||||
result.utilsView = newUtilsView()
|
||||
result.isNonArchivalNode = false
|
||||
|
||||
result.setup
|
||||
|
||||
proc etherscanLinkChanged*(self: WalletView) {.signal.}
|
||||
proc getAccounts(self: WalletView): QVariant {.slot.} = newQVariant(self.accountsView)
|
||||
QtProperty[QVariant] accountsView:
|
||||
read = getAccounts
|
||||
|
||||
proc getEtherscanLink*(self: WalletView): QVariant {.slot.} =
|
||||
newQVariant(self.etherscanLink.replace("/address", "/tx"))
|
||||
proc getCollectibles(self: WalletView): QVariant {.slot.} = newQVariant(self.collectiblesView)
|
||||
QtProperty[QVariant] collectiblesView:
|
||||
read = getCollectibles
|
||||
|
||||
proc setEtherscanLink*(self: WalletView, link: string) =
|
||||
self.etherscanLink = link
|
||||
self.etherscanLinkChanged()
|
||||
proc getTransactions(self: WalletView): QVariant {.slot.} = newQVariant(self.transactionsView)
|
||||
QtProperty[QVariant] transactionsView:
|
||||
read = getTransactions
|
||||
|
||||
proc signingPhraseChanged*(self: WalletView) {.signal.}
|
||||
proc getGas(self: WalletView): QVariant {.slot.} = newQVariant(self.gasView)
|
||||
QtProperty[QVariant] gasView:
|
||||
read = getGas
|
||||
|
||||
proc getSigningPhrase*(self: WalletView): QVariant {.slot.} =
|
||||
newQVariant(self.signingPhrase)
|
||||
proc getTokens(self: WalletView): QVariant {.slot.} = newQVariant(self.tokensView)
|
||||
QtProperty[QVariant] tokensView:
|
||||
read = getTokens
|
||||
|
||||
proc setSigningPhrase*(self: WalletView, signingPhrase: string) =
|
||||
self.signingPhrase = signingPhrase
|
||||
self.signingPhraseChanged()
|
||||
proc getEns(self: WalletView): QVariant {.slot.} = newQVariant(self.ensView)
|
||||
QtProperty[QVariant] ensView:
|
||||
read = getEns
|
||||
|
||||
QtProperty[QVariant] etherscanLink:
|
||||
read = getEtherscanLink
|
||||
notify = etherscanLinkChanged
|
||||
proc getHistory(self: WalletView): QVariant {.slot.} = newQVariant(self.historyView)
|
||||
QtProperty[QVariant] historyView:
|
||||
read = getHistory
|
||||
|
||||
QtProperty[QVariant] signingPhrase:
|
||||
read = getSigningPhrase
|
||||
notify = signingPhraseChanged
|
||||
proc getBalance(self: WalletView): QVariant {.slot.} = newQVariant(self.balanceView)
|
||||
QtProperty[QVariant] balanceView:
|
||||
read = getBalance
|
||||
|
||||
proc getStatusToken*(self: WalletView): string {.slot.} = self.status.wallet.getStatusToken
|
||||
|
||||
proc setCurrentAssetList*(self: WalletView, assetList: seq[Asset])
|
||||
|
||||
proc currentCollectiblesListsChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc getCurrentCollectiblesLists(self: WalletView): QVariant {.slot.} =
|
||||
return newQVariant(self.currentCollectiblesLists)
|
||||
|
||||
proc setCurrentCollectiblesLists*(self: WalletView, collectiblesLists: seq[CollectibleList]) =
|
||||
self.currentCollectiblesLists.setNewData(collectiblesLists)
|
||||
self.currentCollectiblesListsChanged()
|
||||
|
||||
QtProperty[QVariant] collectiblesLists:
|
||||
read = getCurrentCollectiblesLists
|
||||
write = setCurrentCollectiblesLists
|
||||
notify = currentCollectiblesListsChanged
|
||||
|
||||
proc currentTransactionsChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc getCurrentTransactions*(self: WalletView): QVariant {.slot.} =
|
||||
return newQVariant(self.currentTransactions)
|
||||
|
||||
proc setCurrentTransactions*(self: WalletView, transactionList: seq[Transaction]) =
|
||||
self.currentTransactions.setNewData(transactionList)
|
||||
self.currentTransactionsChanged()
|
||||
|
||||
QtProperty[QVariant] transactions:
|
||||
read = getCurrentTransactions
|
||||
write = setCurrentTransactions
|
||||
notify = currentTransactionsChanged
|
||||
|
||||
proc loadCollectiblesForAccount*(self: WalletView, address: string, currentCollectiblesList: seq[CollectibleList])
|
||||
proc currentAccountChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc setCurrentAccountByIndex*(self: WalletView, index: int) {.slot.} =
|
||||
if(self.accounts.rowCount() == 0): return
|
||||
|
||||
let selectedAccount = self.accounts.getAccount(index)
|
||||
if self.currentAccount.address == selectedAccount.address: return
|
||||
self.currentAccount.setAccountItem(selectedAccount)
|
||||
self.currentAccountChanged()
|
||||
self.setCurrentAssetList(selectedAccount.assetList)
|
||||
|
||||
# Display currently known collectibles, and get latest from API/Contracts
|
||||
self.setCurrentCollectiblesLists(selectedAccount.collectiblesLists)
|
||||
self.loadCollectiblesForAccount(selectedAccount.address, selectedAccount.collectiblesLists)
|
||||
|
||||
self.currentTransactions.setHasMore(selectedAccount.transactions.hasMore)
|
||||
self.setCurrentTransactions(selectedAccount.transactions.data)
|
||||
|
||||
proc getCurrentAccount*(self: WalletView): QVariant {.slot.} =
|
||||
result = newQVariant(self.currentAccount)
|
||||
|
||||
QtProperty[QVariant] currentAccount:
|
||||
read = getCurrentAccount
|
||||
write = setCurrentAccountByIndex
|
||||
notify = currentAccountChanged
|
||||
|
||||
proc focusedAccountChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc setFocusedAccountByAddress*(self: WalletView, address: string) {.slot.} =
|
||||
if(self.accounts.rowCount() == 0): return
|
||||
|
||||
var index = self.accounts.getAccountindexByAddress(address)
|
||||
if index == -1: index = 0
|
||||
let selectedAccount = self.accounts.getAccount(index)
|
||||
if self.focusedAccount.address == selectedAccount.address: return
|
||||
self.focusedAccount.setAccountItem(selectedAccount)
|
||||
self.focusedAccountChanged()
|
||||
|
||||
proc getFocusedAccount*(self: WalletView): QVariant {.slot.} =
|
||||
result = newQVariant(self.focusedAccount)
|
||||
|
||||
QtProperty[QVariant] focusedAccount:
|
||||
read = getFocusedAccount
|
||||
write = setFocusedAccountByAddress
|
||||
notify = focusedAccountChanged
|
||||
|
||||
proc currentAssetListChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc getCurrentAssetList(self: WalletView): QVariant {.slot.} =
|
||||
return newQVariant(self.currentAssetList)
|
||||
|
||||
proc setCurrentAssetList*(self: WalletView, assetList: seq[Asset]) =
|
||||
self.currentAssetList.setNewData(assetList)
|
||||
self.currentAssetListChanged()
|
||||
|
||||
QtProperty[QVariant] assets:
|
||||
read = getCurrentAssetList
|
||||
write = setCurrentAssetList
|
||||
notify = currentAssetListChanged
|
||||
|
||||
proc totalFiatBalanceChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc getTotalFiatBalance(self: WalletView): string {.slot.} =
|
||||
self.status.wallet.getTotalFiatBalance()
|
||||
|
||||
proc setTotalFiatBalance*(self: WalletView, newBalance: string) =
|
||||
self.totalFiatBalance = newBalance
|
||||
self.totalFiatBalanceChanged()
|
||||
|
||||
QtProperty[string] totalFiatBalance:
|
||||
read = getTotalFiatBalance
|
||||
write = setTotalFiatBalance
|
||||
notify = totalFiatBalanceChanged
|
||||
|
||||
proc accountListChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc addAccountToList*(self: WalletView, account: WalletAccount) =
|
||||
self.accounts.addAccountToList(account)
|
||||
# If it's the first account we ever get, use its list as our first lists
|
||||
if (self.accounts.rowCount == 1):
|
||||
self.setCurrentAssetList(account.assetList)
|
||||
self.setCurrentAccountByIndex(0)
|
||||
self.accountListChanged()
|
||||
|
||||
proc getFiatValue*(self: WalletView, cryptoBalance: string, cryptoSymbol: string, fiatSymbol: string): string {.slot.} =
|
||||
if (cryptoBalance == "" or cryptoSymbol == "" or fiatSymbol == ""): return "0.00"
|
||||
let val = self.status.wallet.convertValue(cryptoBalance, cryptoSymbol, fiatSymbol)
|
||||
result = fmt"{val:.2f}"
|
||||
|
||||
proc getCryptoValue*(self: WalletView, fiatBalance: string, fiatSymbol: string, cryptoSymbol: string): string {.slot.} =
|
||||
result = fmt"{self.status.wallet.convertValue(fiatBalance, fiatSymbol, cryptoSymbol)}"
|
||||
|
||||
proc getGasEthValue*(self: WalletView, gweiValue: string, gasLimit: string): string {.slot.} =
|
||||
var gweiValueInt:int
|
||||
var gasLimitInt:int
|
||||
|
||||
discard gweiValue.parseInt(gweiValueInt)
|
||||
discard gasLimit.parseInt(gasLimitInt)
|
||||
|
||||
let weiValue = gweiValueInt.u256 * 1000000000.u256 * gasLimitInt.u256
|
||||
let ethValue = wei2Eth(weiValue)
|
||||
result = fmt"{ethValue}"
|
||||
|
||||
proc generateNewAccount*(self: WalletView, password: string, accountName: string, color: string): string {.slot.} =
|
||||
try:
|
||||
self.status.wallet.generateNewAccount(password, accountName, color)
|
||||
except StatusGoException as e:
|
||||
result = StatusGoError(error: e.msg).toJson
|
||||
|
||||
proc addAccountsFromSeed*(self: WalletView, seed: string, password: string, accountName: string, color: string): string {.slot.} =
|
||||
try:
|
||||
self.status.wallet.addAccountsFromSeed(seed.strip(), password, accountName, color)
|
||||
except StatusGoException as e:
|
||||
result = StatusGoError(error: e.msg).toJson
|
||||
|
||||
proc addAccountsFromPrivateKey*(self: WalletView, privateKey: string, password: string, accountName: string, color: string): string {.slot.} =
|
||||
try:
|
||||
self.status.wallet.addAccountsFromPrivateKey(privateKey, password, accountName, color)
|
||||
except StatusGoException as e:
|
||||
result = StatusGoError(error: e.msg).toJson
|
||||
|
||||
proc addWatchOnlyAccount*(self: WalletView, address: string, accountName: string, color: string): string {.slot.} =
|
||||
self.status.wallet.addWatchOnlyAccount(address, accountName, color)
|
||||
|
||||
proc changeAccountSettings*(self: WalletView, address: string, accountName: string, color: string): string {.slot.} =
|
||||
result = self.status.wallet.changeAccountSettings(address, accountName, color)
|
||||
if (result == ""):
|
||||
self.currentAccountChanged()
|
||||
self.accountListChanged()
|
||||
self.accounts.forceUpdate()
|
||||
|
||||
proc deleteAccount*(self: WalletView, address: string): string {.slot.} =
|
||||
result = self.status.wallet.deleteAccount(address)
|
||||
if (result == ""):
|
||||
let index = self.accounts.getAccountindexByAddress(address)
|
||||
if (index == -1):
|
||||
return fmt"Unable to find the account with the address {address}"
|
||||
self.accounts.deleteAccountAtIndex(index)
|
||||
self.accountListChanged()
|
||||
self.accounts.forceUpdate()
|
||||
|
||||
proc getAccountList(self: WalletView): QVariant {.slot.} =
|
||||
return newQVariant(self.accounts)
|
||||
|
||||
QtProperty[QVariant] accounts:
|
||||
read = getAccountList
|
||||
notify = accountListChanged
|
||||
|
||||
proc estimateGas*(self: WalletView, from_addr: string, to: string, assetAddress: string, value: string, data: string = ""): string {.slot.} =
|
||||
var
|
||||
response: string
|
||||
success: bool
|
||||
if assetAddress != ZERO_ADDRESS and not assetAddress.isEmptyOrWhitespace:
|
||||
response = self.status.wallet.estimateTokenGas(from_addr, to, assetAddress, value, success)
|
||||
else:
|
||||
response = self.status.wallet.estimateGas(from_addr, to, value, data, success)
|
||||
|
||||
if success == true:
|
||||
let res = fromHex[int](response)
|
||||
result = $(%* { "result": %res, "success": %success })
|
||||
else:
|
||||
result = $(%* { "result": "-1", "success": %success, "error": { "message": %response } })
|
||||
|
||||
proc transactionWasSent*(self: WalletView, txResult: string) {.signal.}
|
||||
|
||||
proc transactionSent(self: WalletView, txResult: string) {.slot.} =
|
||||
self.transactionWasSent(txResult)
|
||||
let jTxRes = txResult.parseJSON()
|
||||
let txHash = jTxRes{"result"}.getStr()
|
||||
if txHash != "":
|
||||
self.watchTransaction("transactionWatchResultReceived", txHash)
|
||||
|
||||
proc sendTransaction*(self: WalletView, from_addr: string, to: string, assetAddress: string, value: string, gas: string, gasPrice: string, password: string, uuid: string) {.slot.} =
|
||||
self.sendTransaction("transactionSent", from_addr, to, assetAddress, value, gas, gasPrice, password, uuid)
|
||||
|
||||
proc getDefaultAccount*(self: WalletView): string {.slot.} =
|
||||
self.currentAccount.address
|
||||
|
||||
proc defaultCurrency*(self: WalletView): string {.slot.} =
|
||||
self.status.wallet.getDefaultCurrency()
|
||||
|
||||
proc defaultCurrencyChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc setDefaultCurrency*(self: WalletView, currency: string) {.slot.} =
|
||||
self.status.wallet.setDefaultCurrency(currency)
|
||||
self.defaultCurrencyChanged()
|
||||
|
||||
QtProperty[string] defaultCurrency:
|
||||
read = defaultCurrency
|
||||
write = setDefaultCurrency
|
||||
notify = defaultCurrencyChanged
|
||||
|
||||
proc hasAsset*(self: WalletView, symbol: string): bool {.slot.} =
|
||||
self.status.wallet.hasAsset(symbol)
|
||||
|
||||
proc toggleAsset*(self: WalletView, symbol: string) {.slot.} =
|
||||
self.status.wallet.toggleAsset(symbol)
|
||||
for account in self.status.wallet.accounts:
|
||||
if account.address == self.currentAccount.address:
|
||||
self.currentAccount.setAccountItem(account)
|
||||
else:
|
||||
self.accounts.updateAssetsInList(account.address, account.assetList)
|
||||
self.accountListChanged()
|
||||
self.currentAccountChanged()
|
||||
|
||||
proc removeCustomToken*(self: WalletView, tokenAddress: string) {.slot.} =
|
||||
let t = self.status.tokens.getCustomTokens().getErc20ContractByAddress(parseAddress(tokenAddress))
|
||||
if t == nil: return
|
||||
self.status.wallet.hideAsset(t.symbol)
|
||||
self.status.tokens.removeCustomToken(tokenAddress)
|
||||
self.customTokenList.loadCustomTokens()
|
||||
for account in self.status.wallet.accounts:
|
||||
if account.address == self.currentAccount.address:
|
||||
self.currentAccount.setAccountItem(account)
|
||||
else:
|
||||
self.accounts.updateAssetsInList(account.address, account.assetList)
|
||||
self.accountListChanged()
|
||||
self.currentAccountChanged()
|
||||
|
||||
proc addCustomToken*(self: WalletView, address: string, name: string, symbol: string, decimals: string) {.slot.} =
|
||||
self.status.wallet.addCustomToken(symbol, true, address, name, parseInt(decimals), "")
|
||||
proc getUtils(self: WalletView): QVariant {.slot.} = newQVariant(self.utilsView)
|
||||
QtProperty[QVariant] utilsView:
|
||||
read = getUtils
|
||||
|
||||
proc updateView*(self: WalletView) =
|
||||
self.setTotalFiatBalance(self.status.wallet.getTotalFiatBalance())
|
||||
self.totalFiatBalanceChanged()
|
||||
self.currentAccount.assetList.setNewData(self.currentAccount.account.assetList)
|
||||
self.currentAccountChanged()
|
||||
self.accountListChanged()
|
||||
self.accounts.forceUpdate()
|
||||
self.setCurrentAssetList(self.currentAccount.account.assetList)
|
||||
self.balanceView.setTotalFiatBalance(self.status.wallet.getTotalFiatBalance())
|
||||
self.balanceView.totalFiatBalanceChanged()
|
||||
|
||||
proc checkRecentHistory*(self:WalletView) {.slot.} =
|
||||
var addresses:seq[string] = @[]
|
||||
for acc in self.status.wallet.accounts:
|
||||
addresses.add(acc.address)
|
||||
discard self.status.wallet.checkRecentHistory(addresses)
|
||||
self.accountsView.currentAccount.assetList.setNewData(self.accountsView.currentAccount.account.assetList)
|
||||
self.accountsView.triggerUpdateAccounts()
|
||||
|
||||
proc transactionWatchResultReceived(self: WalletView, watchResult: string) {.slot.} =
|
||||
let wTxRes = watchResult.parseJSON()["result"].getStr().parseJson(){"result"}
|
||||
if wTxRes.kind == JNull:
|
||||
self.checkRecentHistory()
|
||||
else:
|
||||
discard #TODO: Ask Simon if should we show an error popup indicating the trx wasn't mined in 10m or something
|
||||
self.tokensView.setCurrentAssetList(self.accountsView.currentAccount.account.assetList)
|
||||
|
||||
proc getAccountBalanceSuccess*(self: WalletView, jsonResponse: string) {.slot.} =
|
||||
let jsonObj = jsonResponse.parseJson()
|
||||
self.status.wallet.update(jsonObj["address"].getStr(), jsonObj["eth"].getStr(), jsonObj["tokens"])
|
||||
self.setTotalFiatBalance(self.status.wallet.getTotalFiatBalance())
|
||||
self.accounts.forceUpdate()
|
||||
self.currentAccountChanged()
|
||||
self.balanceView.getAccountBalanceSuccess(jsonResponse)
|
||||
self.updateView()
|
||||
|
||||
proc getDefaultAddress*(self: WalletView): string {.slot.} =
|
||||
result = $self.status.wallet.getWalletAccounts()[0].address
|
||||
|
||||
proc loadCollectiblesForAccount*(self: WalletView, address: string, currentCollectiblesList: seq[CollectibleList]) =
|
||||
if (currentCollectiblesList.len > 0):
|
||||
return
|
||||
# Add loading state if it is the current account
|
||||
if address == self.currentAccount.address:
|
||||
for collectibleType in status_collectibles.COLLECTIBLE_TYPES:
|
||||
self.currentCollectiblesLists.addCollectibleListToList(CollectibleList(
|
||||
collectibleType: collectibleType,
|
||||
collectiblesJSON: "[]",
|
||||
error: "",
|
||||
loading: 1
|
||||
))
|
||||
proc setInitialRange*(self: WalletView) {.slot.} =
|
||||
discard self.status.wallet.setInitialBlocksRange()
|
||||
|
||||
# TODO find a way to use a loop to streamline this code
|
||||
# Create a thread in the threadpool for each collectible. They can end in whichever order
|
||||
self.loadCollectibles("setCollectiblesResult", address, status_collectibles.CRYPTOKITTY)
|
||||
self.loadCollectibles("setCollectiblesResult", address, status_collectibles.KUDO)
|
||||
self.loadCollectibles("setCollectiblesResult", address, status_collectibles.ETHERMON)
|
||||
self.loadCollectibles("setCollectiblesResult", address, status_collectibles.STICKER)
|
||||
proc setCurrentAccountByIndex*(self: WalletView, index: int) {.slot.} =
|
||||
if self.accountsView.setCurrentAccountByIndex(index):
|
||||
let selectedAccount = self.accountsView.accounts.getAccount(index)
|
||||
|
||||
proc setCollectiblesResult(self: WalletView, collectiblesJSON: string) {.slot.} =
|
||||
let collectibleData = parseJson(collectiblesJSON)
|
||||
let address = collectibleData["address"].getStr
|
||||
let collectibleType = collectibleData["collectibleType"].getStr
|
||||
|
||||
var collectibles: JSONNode
|
||||
try:
|
||||
collectibles = parseJson(collectibleData["collectiblesOrError"].getStr)
|
||||
except Exception as e:
|
||||
# We failed parsing, this means the result is an error string
|
||||
self.currentCollectiblesLists.setErrorByType(
|
||||
collectibleType,
|
||||
$collectibleData["collectiblesOrError"]
|
||||
)
|
||||
return
|
||||
self.tokensView.setCurrentAssetList(selectedAccount.assetList)
|
||||
|
||||
# Add the collectibles to the WalletAccount
|
||||
let index = self.accounts.getAccountindexByAddress(address)
|
||||
if index == -1: return
|
||||
self.accounts.addCollectibleListToAccount(index, collectibleType, $collectibles)
|
||||
|
||||
if address == self.currentAccount.address:
|
||||
# Add CollectibleListJSON to the right list
|
||||
self.currentCollectiblesLists.setCollectiblesJSONByType(
|
||||
collectibleType,
|
||||
$collectibles
|
||||
)
|
||||
self.collectiblesView.setCurrentCollectiblesLists(selectedAccount.collectiblesLists)
|
||||
self.collectiblesView.loadCollectiblesForAccount(selectedAccount.address, selectedAccount.collectiblesLists)
|
||||
|
||||
proc reloadCollectible*(self: WalletView, collectibleType: string) {.slot.} =
|
||||
let address = self.currentAccount.address
|
||||
self.loadCollectibles("setCollectiblesResult", address, collectibleType)
|
||||
self.currentCollectiblesLists.setLoadingByType(collectibleType, 1)
|
||||
self.transactionsView.setCurrentTransactions(selectedAccount.transactions.data)
|
||||
|
||||
proc addAccountToList*(self: WalletView, account: WalletAccount) =
|
||||
self.accountsView.addAccountToList(account)
|
||||
# If it's the first account we ever get, use its list as our first lists
|
||||
if (self.accountsView.accounts.rowCount == 1):
|
||||
self.tokensView.setCurrentAssetList(account.assetList)
|
||||
discard self.accountsView.setCurrentAccountByIndex(0)
|
||||
|
||||
proc transactionCompleted*(self: WalletView, success: bool, txHash: string, revertReason: string = "") {.signal.}
|
||||
|
||||
proc setDappBrowserAddress*(self: WalletView) {.slot.} =
|
||||
self.dappBrowserView.setDappBrowserAddress()
|
||||
|
||||
proc loadTransactionsForAccount*(self: WalletView, address: string) {.slot.} =
|
||||
self.historyView.loadTransactionsForAccount(address)
|
||||
|
||||
proc setHistoryFetchState*(self: WalletView, accounts: seq[string], isFetching: bool) =
|
||||
self.historyView.setHistoryFetchState(accounts, isFetching)
|
||||
|
||||
proc initBalances*(self: WalletView, loadTransactions: bool = true) =
|
||||
self.balanceView.initBalances(loadTransactions)
|
||||
|
||||
proc setSigningPhrase*(self: WalletView, signingPhrase: string) =
|
||||
self.utilsView.setSigningPhrase(signingPhrase)
|
||||
|
||||
proc setEtherscanLink*(self: WalletView, link: string) =
|
||||
self.utilsView.setEtherscanLink(link)
|
||||
|
||||
proc checkRecentHistory*(self: WalletView) =
|
||||
self.transactionsView.checkRecentHistory()
|
||||
|
||||
proc initBalances*(self: WalletView, accounts: seq[string], loadTransactions: bool = true) =
|
||||
for acc in accounts:
|
||||
self.balanceView.initBalance(acc, loadTransactions)
|
||||
|
||||
proc isNonArchivalNodeChanged*(self: WalletView) {.signal.}
|
||||
|
||||
|
@ -637,184 +160,3 @@ QtObject:
|
|||
read = isNonArchivalNode
|
||||
write = setNonArchivalNode
|
||||
notify = isNonArchivalNodeChanged
|
||||
|
||||
proc gasPricePredictionsChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc getGasPricePredictions*(self: WalletView) {.slot.} =
|
||||
self.getGasPredictions("getGasPricePredictionsResult")
|
||||
|
||||
proc getGasPricePredictionsResult(self: WalletView, gasPricePredictionsJson: string) {.slot.} =
|
||||
let prediction = Json.decode(gasPricePredictionsJson, GasPricePrediction)
|
||||
self.safeLowGasPrice = fmt"{prediction.safeLow:.3f}"
|
||||
self.standardGasPrice = fmt"{prediction.standard:.3f}"
|
||||
self.fastGasPrice = fmt"{prediction.fast:.3f}"
|
||||
self.fastestGasPrice = fmt"{prediction.fastest:.3f}"
|
||||
self.gasPricePredictionsChanged()
|
||||
|
||||
proc safeLowGasPrice*(self: WalletView): string {.slot.} = result = ?.self.safeLowGasPrice
|
||||
QtProperty[string] safeLowGasPrice:
|
||||
read = safeLowGasPrice
|
||||
notify = gasPricePredictionsChanged
|
||||
|
||||
proc standardGasPrice*(self: WalletView): string {.slot.} = result = ?.self.standardGasPrice
|
||||
QtProperty[string] standardGasPrice:
|
||||
read = standardGasPrice
|
||||
notify = gasPricePredictionsChanged
|
||||
|
||||
proc fastGasPrice*(self: WalletView): string {.slot.} = result = ?.self.fastGasPrice
|
||||
QtProperty[string] fastGasPrice:
|
||||
read = fastGasPrice
|
||||
notify = gasPricePredictionsChanged
|
||||
|
||||
proc fastestGasPrice*(self: WalletView): string {.slot.} = result = ?.self.fastestGasPrice
|
||||
QtProperty[string] fastestGasPrice:
|
||||
read = fastestGasPrice
|
||||
notify = gasPricePredictionsChanged
|
||||
|
||||
proc defaultGasLimit*(self: WalletView): string {.slot.} = result = ?.self.defaultGasLimit
|
||||
QtProperty[string] defaultGasLimit:
|
||||
read = defaultGasLimit
|
||||
|
||||
proc getDefaultAddress*(self: WalletView): string {.slot.} =
|
||||
result = $self.status.wallet.getWalletAccounts()[0].address
|
||||
|
||||
proc getDefaultTokenList(self: WalletView): QVariant {.slot.} =
|
||||
self.defaultTokenList.loadDefaultTokens()
|
||||
result = newQVariant(self.defaultTokenList)
|
||||
|
||||
QtProperty[QVariant] defaultTokenList:
|
||||
read = getDefaultTokenList
|
||||
|
||||
proc loadCustomTokens(self: WalletView) {.slot.} =
|
||||
self.customTokenList.loadCustomTokens()
|
||||
|
||||
proc getCustomTokenList(self: WalletView): QVariant {.slot.} =
|
||||
result = newQVariant(self.customTokenList)
|
||||
|
||||
QtProperty[QVariant] customTokenList:
|
||||
read = getCustomTokenList
|
||||
|
||||
proc isKnownTokenContract*(self: WalletView, address: string): bool {.slot.} =
|
||||
return self.status.wallet.getKnownTokenContract(parseAddress(address)) != nil
|
||||
|
||||
proc decodeTokenApproval*(self: WalletView, tokenAddress: string, data: string): string {.slot.} =
|
||||
let amount = data[74..len(data)-1]
|
||||
let token = self.status.tokens.getToken(tokenAddress)
|
||||
|
||||
if(token != nil):
|
||||
let amountDec = $self.status.wallet.hex2Token(amount, token.decimals)
|
||||
return $(%* {"symbol": token.symbol, "amount": amountDec})
|
||||
|
||||
return """{"error":"Unknown token address"}""";
|
||||
|
||||
proc isFetchingHistory*(self: WalletView): bool {.slot.} =
|
||||
if self.fetchingHistoryState.hasKey(self.currentAccount.address):
|
||||
return self.fetchingHistoryState[self.currentAccount.address]
|
||||
return false
|
||||
|
||||
proc loadingTrxHistoryChanged*(self: WalletView, isLoading: bool, address: string) {.signal.}
|
||||
|
||||
proc loadTransactionsForAccount*(self: WalletView, address: string, toBlock: string = "0x0", limit: int = 20, loadMore: bool = false) {.slot.} =
|
||||
self.loadingTrxHistoryChanged(true, address)
|
||||
let toBlockParsed = stint.fromHex(Uint256, toBlock)
|
||||
self.loadTransactions("setTrxHistoryResult", address, toBlockParsed, limit, loadMore)
|
||||
|
||||
proc setHistoryFetchState*(self: WalletView, accounts: seq[string], isFetching: bool) =
|
||||
for acc in accounts:
|
||||
self.fetchingHistoryState[acc] = isFetching
|
||||
self.loadingTrxHistoryChanged(isFetching, acc)
|
||||
|
||||
proc initBalance(self: WalletView, acc: WalletAccount, loadTransactions: bool = true) =
|
||||
let
|
||||
accountAddress = acc.address
|
||||
tokenList = acc.assetList.filter(proc(x:Asset): bool = x.address != "").map(proc(x: Asset): string = x.address)
|
||||
self.initBalances("getAccountBalanceSuccess", accountAddress, tokenList)
|
||||
if loadTransactions:
|
||||
self.loadTransactionsForAccount(accountAddress)
|
||||
|
||||
proc initBalance(self: WalletView, accountAddress: string, loadTransactions: bool = true) =
|
||||
var found = false
|
||||
let acc = self.status.wallet.accounts.find(acc => acc.address.toLowerAscii == accountAddress.toLowerAscii, found)
|
||||
if not found:
|
||||
error "Failed to init balance: could not find account", account=accountAddress
|
||||
return
|
||||
self.initBalance(acc, loadTransactions)
|
||||
|
||||
proc initBalances*(self: WalletView, loadTransactions: bool = true) =
|
||||
for acc in self.status.wallet.accounts:
|
||||
self.initBalance(acc, loadTransactions)
|
||||
|
||||
proc initBalances*(self: WalletView, accounts: seq[string], loadTransactions: bool = true) =
|
||||
for acc in accounts:
|
||||
self.initBalance(acc, loadTransactions)
|
||||
|
||||
proc setTrxHistoryResult(self: WalletView, historyJSON: string) {.slot.} =
|
||||
let
|
||||
historyData = parseJson(historyJSON)
|
||||
transactions = historyData["history"].to(seq[Transaction])
|
||||
address = historyData["address"].getStr
|
||||
wasFetchMore = historyData["loadMore"].getBool
|
||||
isCurrentAccount = address.toLowerAscii == self.currentAccount.address.toLowerAscii
|
||||
index = self.accounts.getAccountindexByAddress(address)
|
||||
if index == -1: return
|
||||
|
||||
let account = self.accounts.getAccount(index)
|
||||
# concatenate the new page of txs to existing account transactions,
|
||||
# sort them by block number and nonce, then deduplicate them based on their
|
||||
# transaction id.
|
||||
let existingAcctTxIds = account.transactions.data.map(tx => tx.id)
|
||||
let hasNewTxs = transactions.len > 0 and transactions.any(tx => not existingAcctTxIds.contains(tx.id))
|
||||
if hasNewTxs or not wasFetchMore:
|
||||
var allTxs: seq[Transaction] = account.transactions.data.concat(transactions)
|
||||
allTxs.sort(cmpTransactions, SortOrder.Descending)
|
||||
allTxs.deduplicate(tx => tx.id)
|
||||
account.transactions.data = allTxs
|
||||
account.transactions.hasMore = true
|
||||
if isCurrentAccount:
|
||||
self.currentTransactions.setHasMore(true)
|
||||
self.setCurrentTransactions(allTxs)
|
||||
else:
|
||||
account.transactions.hasMore = false
|
||||
if isCurrentAccount:
|
||||
self.currentTransactions.setHasMore(false)
|
||||
self.currentTransactionsChanged()
|
||||
self.loadingTrxHistoryChanged(false, address)
|
||||
|
||||
proc resolveENS*(self: WalletView, ens: string, uuid: string) {.slot.} =
|
||||
self.resolveEns("ensResolved", ens, uuid)
|
||||
|
||||
proc ensWasResolved*(self: WalletView, resolvedAddress: string, uuid: string) {.signal.}
|
||||
|
||||
proc ensResolved(self: WalletView, addressUuidJson: string) {.slot.} =
|
||||
var
|
||||
parsed = addressUuidJson.parseJson
|
||||
address = parsed["address"].to(string)
|
||||
uuid = parsed["uuid"].to(string)
|
||||
if address == "0x":
|
||||
address = ""
|
||||
self.ensWasResolved(address, uuid)
|
||||
|
||||
proc transactionCompleted*(self: WalletView, success: bool, txHash: string, revertReason: string = "") {.signal.}
|
||||
|
||||
proc dappBrowserAccountChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc setDappBrowserAddress*(self: WalletView) {.slot.} =
|
||||
if(self.accounts.rowCount() == 0): return
|
||||
|
||||
let dappAddress = self.status.settings.getSetting[:string](Setting.DappsAddress)
|
||||
var index = self.accounts.getAccountIndexByAddress(dappAddress)
|
||||
if index == -1: index = 0
|
||||
let selectedAccount = self.accounts.getAccount(index)
|
||||
if self.dappBrowserAccount.address == selectedAccount.address: return
|
||||
self.dappBrowserAccount.setAccountItem(selectedAccount)
|
||||
self.dappBrowserAccountChanged()
|
||||
|
||||
proc getDappBrowserAccount*(self: WalletView): QVariant {.slot.} =
|
||||
result = newQVariant(self.dappBrowserAccount)
|
||||
|
||||
QtProperty[QVariant] dappBrowserAccount:
|
||||
read = getDappBrowserAccount
|
||||
notify = dappBrowserAccountChanged
|
||||
|
||||
proc setInitialRange*(self: WalletView) {.slot.} =
|
||||
discard self.status.wallet.setInitialBlocksRange()
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
import NimQml, json, sequtils, chronicles, strutils, strformat, json
|
||||
|
||||
import
|
||||
../../../status/[status, settings, types],
|
||||
../../../status/signals/types as signal_types,
|
||||
../../../status/wallet as status_wallet
|
||||
|
||||
import account_list, account_item
|
||||
|
||||
logScope:
|
||||
topics = "accounts-view"
|
||||
|
||||
QtObject:
|
||||
type AccountsView* = ref object of QObject
|
||||
status: Status
|
||||
accounts*: AccountList
|
||||
currentAccount*: AccountItemView
|
||||
focusedAccount*: AccountItemView
|
||||
|
||||
proc setup(self: AccountsView) = self.QObject.setup
|
||||
proc delete(self: AccountsView) =
|
||||
self.accounts.delete
|
||||
self.currentAccount.delete
|
||||
self.focusedAccount.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newAccountsView*(status: Status): AccountsView =
|
||||
new(result, delete)
|
||||
result.status = status
|
||||
result.accounts = newAccountList()
|
||||
result.currentAccount = newAccountItemView()
|
||||
result.focusedAccount = newAccountItemView()
|
||||
result.setup
|
||||
|
||||
proc generateNewAccount*(self: AccountsView, password: string, accountName: string, color: string): string {.slot.} =
|
||||
try:
|
||||
self.status.wallet.generateNewAccount(password, accountName, color)
|
||||
except StatusGoException as e:
|
||||
result = StatusGoError(error: e.msg).toJson
|
||||
|
||||
proc addAccountsFromSeed*(self: AccountsView, seed: string, password: string, accountName: string, color: string): string {.slot.} =
|
||||
try:
|
||||
self.status.wallet.addAccountsFromSeed(seed.strip(), password, accountName, color)
|
||||
except StatusGoException as e:
|
||||
result = StatusGoError(error: e.msg).toJson
|
||||
|
||||
proc addAccountsFromPrivateKey*(self: AccountsView, privateKey: string, password: string, accountName: string, color: string): string {.slot.} =
|
||||
try:
|
||||
self.status.wallet.addAccountsFromPrivateKey(privateKey, password, accountName, color)
|
||||
except StatusGoException as e:
|
||||
result = StatusGoError(error: e.msg).toJson
|
||||
|
||||
proc addWatchOnlyAccount*(self: AccountsView, address: string, accountName: string, color: string): string {.slot.} =
|
||||
self.status.wallet.addWatchOnlyAccount(address, accountName, color)
|
||||
|
||||
proc currentAccountChanged*(self: AccountsView) {.signal.}
|
||||
|
||||
proc accountListChanged*(self: AccountsView) {.signal.}
|
||||
|
||||
proc addAccountToList*(self: AccountsView, account: WalletAccount) =
|
||||
self.accounts.addAccountToList(account)
|
||||
self.accountListChanged()
|
||||
|
||||
proc changeAccountSettings*(self: AccountsView, address: string, accountName: string, color: string): string {.slot.} =
|
||||
result = self.status.wallet.changeAccountSettings(address, accountName, color)
|
||||
if (result == ""):
|
||||
self.currentAccountChanged()
|
||||
self.accountListChanged()
|
||||
self.accounts.forceUpdate()
|
||||
|
||||
proc deleteAccount*(self: AccountsView, address: string): string {.slot.} =
|
||||
result = self.status.wallet.deleteAccount(address)
|
||||
if (result == ""):
|
||||
let index = self.accounts.getAccountindexByAddress(address)
|
||||
if (index == -1):
|
||||
return fmt"Unable to find the account with the address {address}"
|
||||
self.accounts.deleteAccountAtIndex(index)
|
||||
self.accountListChanged()
|
||||
self.accounts.forceUpdate()
|
||||
|
||||
proc getCurrentAccount*(self: AccountsView): QVariant {.slot.} =
|
||||
result = newQVariant(self.currentAccount)
|
||||
|
||||
proc focusedAccountChanged*(self: AccountsView) {.signal.}
|
||||
|
||||
proc setFocusedAccountByAddress*(self: AccountsView, address: string) {.slot.} =
|
||||
if (self.accounts.rowCount() == 0): return
|
||||
|
||||
var index = self.accounts.getAccountindexByAddress(address)
|
||||
if index == -1: index = 0
|
||||
let selectedAccount = self.accounts.getAccount(index)
|
||||
if self.focusedAccount.address == selectedAccount.address: return
|
||||
self.focusedAccount.setAccountItem(selectedAccount)
|
||||
self.focusedAccountChanged()
|
||||
|
||||
proc getFocusedAccount*(self: AccountsView): QVariant {.slot.} =
|
||||
result = newQVariant(self.focusedAccount)
|
||||
|
||||
QtProperty[QVariant] focusedAccount:
|
||||
read = getFocusedAccount
|
||||
write = setFocusedAccountByAddress
|
||||
notify = focusedAccountChanged
|
||||
|
||||
#TODO: use an Option here
|
||||
proc setCurrentAccountByIndex*(self: AccountsView, index: int): bool =
|
||||
if(self.accounts.rowCount() == 0): return false
|
||||
|
||||
let selectedAccount = self.accounts.getAccount(index)
|
||||
if self.currentAccount.address == selectedAccount.address: return false
|
||||
self.currentAccount.setAccountItem(selectedAccount)
|
||||
self.currentAccountChanged()
|
||||
return true
|
||||
|
||||
QtProperty[QVariant] currentAccount:
|
||||
read = getCurrentAccount
|
||||
write = setCurrentAccountByIndex
|
||||
notify = currentAccountChanged
|
||||
|
||||
proc getAccountList(self: AccountsView): QVariant {.slot.} =
|
||||
return newQVariant(self.accounts)
|
||||
|
||||
QtProperty[QVariant] accounts:
|
||||
read = getAccountList
|
||||
notify = accountListChanged
|
||||
|
||||
proc getDefaultAccount*(self: AccountsView): string {.slot.} =
|
||||
self.currentAccount.address
|
||||
|
||||
proc setAccountItems*(self: AccountsView) =
|
||||
for account in self.status.wallet.accounts:
|
||||
if account.address == self.currentAccount.address:
|
||||
self.currentAccount.setAccountItem(account)
|
||||
else:
|
||||
self.accounts.updateAssetsInList(account.address, account.assetList)
|
||||
self.accountListChanged()
|
||||
self.currentAccountChanged()
|
||||
|
||||
proc triggerUpdateAccounts*(self: AccountsView) =
|
||||
self.currentAccountChanged()
|
||||
self.accountListChanged()
|
||||
self.accounts.forceUpdate()
|
|
@ -0,0 +1,117 @@
|
|||
import atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, tables, chronicles, web3/[ethtypes, conversions], stint
|
||||
from sugar import `=>`, `->`
|
||||
import NimQml, json, sequtils, chronicles, strutils, strformat, json
|
||||
|
||||
import
|
||||
../../../status/[status, settings, wallet, tokens],
|
||||
../../../status/tokens as status_tokens,
|
||||
../../../status/tasks/[qt, task_runner_impl]
|
||||
|
||||
import account_list, account_item, transaction_list, accounts, asset_list, token_list, transactions, history
|
||||
|
||||
logScope:
|
||||
topics = "balance-view"
|
||||
|
||||
type
|
||||
InitBalancesTaskArg = ref object of QObjectTaskArg
|
||||
address: string
|
||||
tokenList: seq[string]
|
||||
|
||||
const initBalancesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[InitBalancesTaskArg](argEncoded)
|
||||
var tokenBalances = initTable[string, string]()
|
||||
for token in arg.tokenList:
|
||||
tokenBalances[token] = status_tokens.getTokenBalance(token, arg.address)
|
||||
let output = %* {
|
||||
"address": arg.address,
|
||||
"eth": getEthBalance(arg.address),
|
||||
"tokens": tokenBalances
|
||||
}
|
||||
arg.finish(output)
|
||||
|
||||
proc initBalances[T](self: T, slot: string, address: string, tokenList: seq[string]) =
|
||||
let arg = InitBalancesTaskArg(
|
||||
tptr: cast[ByteAddress](initBalancesTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot, address: address, tokenList: tokenList
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
QtObject:
|
||||
type BalanceView* = ref object of QObject
|
||||
status: Status
|
||||
totalFiatBalance: string
|
||||
accountsView: AccountsView
|
||||
transactionsView*: TransactionsView
|
||||
historyView*: HistoryView
|
||||
|
||||
proc setup(self: BalanceView) = self.QObject.setup
|
||||
proc delete(self: BalanceView) = self.QObject.delete
|
||||
|
||||
proc newBalanceView*(status: Status, accountsView: AccountsView, transactionsView: TransactionsView, historyView: HistoryView): BalanceView =
|
||||
new(result, delete)
|
||||
result.status = status
|
||||
result.totalFiatBalance = ""
|
||||
result.accountsView = accountsView
|
||||
result.transactionsView = transactionsView
|
||||
result.historyView = historyView
|
||||
result.setup
|
||||
|
||||
proc totalFiatBalanceChanged*(self: BalanceView) {.signal.}
|
||||
|
||||
proc getTotalFiatBalance(self: BalanceView): string {.slot.} =
|
||||
self.status.wallet.getTotalFiatBalance()
|
||||
|
||||
proc setTotalFiatBalance*(self: BalanceView, newBalance: string) =
|
||||
self.totalFiatBalance = newBalance
|
||||
self.totalFiatBalanceChanged()
|
||||
|
||||
QtProperty[string] totalFiatBalance:
|
||||
read = getTotalFiatBalance
|
||||
write = setTotalFiatBalance
|
||||
notify = totalFiatBalanceChanged
|
||||
|
||||
proc getFiatValue*(self: BalanceView, cryptoBalance: string, cryptoSymbol: string, fiatSymbol: string): string {.slot.} =
|
||||
if (cryptoBalance == "" or cryptoSymbol == "" or fiatSymbol == ""): return "0.00"
|
||||
let val = self.status.wallet.convertValue(cryptoBalance, cryptoSymbol, fiatSymbol)
|
||||
result = fmt"{val:.2f}"
|
||||
|
||||
proc getCryptoValue*(self: BalanceView, fiatBalance: string, fiatSymbol: string, cryptoSymbol: string): string {.slot.} =
|
||||
result = fmt"{self.status.wallet.convertValue(fiatBalance, fiatSymbol, cryptoSymbol)}"
|
||||
|
||||
proc defaultCurrency*(self: BalanceView): string {.slot.} =
|
||||
self.status.wallet.getDefaultCurrency()
|
||||
|
||||
proc defaultCurrencyChanged*(self: BalanceView) {.signal.}
|
||||
|
||||
proc setDefaultCurrency*(self: BalanceView, currency: string) {.slot.} =
|
||||
self.status.wallet.setDefaultCurrency(currency)
|
||||
self.defaultCurrencyChanged()
|
||||
|
||||
QtProperty[string] defaultCurrency:
|
||||
read = defaultCurrency
|
||||
write = setDefaultCurrency
|
||||
notify = defaultCurrencyChanged
|
||||
|
||||
proc initBalances*(self: BalanceView, loadTransactions: bool = true) =
|
||||
for acc in self.status.wallet.accounts:
|
||||
let accountAddress = acc.address
|
||||
let tokenList = acc.assetList.filter(proc(x:Asset): bool = x.address != "").map(proc(x: Asset): string = x.address)
|
||||
self.initBalances("getAccountBalanceSuccess", accountAddress, tokenList)
|
||||
if loadTransactions:
|
||||
self.historyView.loadTransactionsForAccount(accountAddress)
|
||||
|
||||
proc initBalance*(self: BalanceView, accountAddress: string, loadTransactions: bool = true) =
|
||||
echo "initBalance"
|
||||
#var found = false
|
||||
#let acc = self.status.wallet.accounts.find(acc => acc.address.toLowerAscii == accountAddress.toLowerAscii, found)
|
||||
#if not found:
|
||||
# error "Failed to init balance: could not find account", account=accountAddress
|
||||
# return
|
||||
#self.initBalance(acc, loadTransactions)
|
||||
|
||||
proc getAccountBalanceSuccess*(self: BalanceView, jsonResponse: string) {.slot.} =
|
||||
let jsonObj = jsonResponse.parseJson()
|
||||
self.status.wallet.update(jsonObj["address"].getStr(), jsonObj["eth"].getStr(), jsonObj["tokens"])
|
||||
self.setTotalFiatBalance(self.status.wallet.getTotalFiatBalance())
|
||||
self.accountsView.triggerUpdateAccounts()
|
|
@ -0,0 +1,133 @@
|
|||
import atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, tables
|
||||
import NimQml, json, sequtils, chronicles, strutils, strformat, json
|
||||
|
||||
import
|
||||
../../../status/[status, settings, wallet, tokens, utils, types],
|
||||
../../../status/wallet/collectibles as status_collectibles,
|
||||
../../../status/tasks/[qt, task_runner_impl]
|
||||
|
||||
import collectibles_list, accounts, account_list, account_item
|
||||
|
||||
logScope:
|
||||
topics = "collectibles-view"
|
||||
|
||||
type
|
||||
LoadCollectiblesTaskArg = ref object of QObjectTaskArg
|
||||
address: string
|
||||
collectiblesType: string
|
||||
running*: ByteAddress # pointer to threadpool's `.running` Atomic[bool]
|
||||
|
||||
const loadCollectiblesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[LoadCollectiblesTaskArg](argEncoded)
|
||||
var running = cast[ptr Atomic[bool]](arg.running)
|
||||
var collectiblesOrError = ""
|
||||
case arg.collectiblesType:
|
||||
of status_collectibles.CRYPTOKITTY:
|
||||
collectiblesOrError = status_collectibles.getCryptoKitties(arg.address)
|
||||
of status_collectibles.KUDO:
|
||||
collectiblesOrError = status_collectibles.getKudos(arg.address)
|
||||
of status_collectibles.ETHERMON:
|
||||
collectiblesOrError = status_collectibles.getEthermons(arg.address)
|
||||
of status_collectibles.STICKER:
|
||||
collectiblesOrError = status_collectibles.getStickers(arg.address, running[])
|
||||
|
||||
let output = %*{
|
||||
"address": arg.address,
|
||||
"collectibleType": arg.collectiblesType,
|
||||
"collectiblesOrError": collectiblesOrError
|
||||
}
|
||||
arg.finish(output)
|
||||
|
||||
proc loadCollectibles[T](self: T, slot: string, address: string, collectiblesType: string) =
|
||||
let arg = LoadCollectiblesTaskArg(
|
||||
tptr: cast[ByteAddress](loadCollectiblesTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot, address: address, collectiblesType: collectiblesType,
|
||||
running: cast[ByteAddress](addr self.status.tasks.threadpool.running)
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
QtObject:
|
||||
type CollectiblesView* = ref object of QObject
|
||||
status: Status
|
||||
accountsView*: AccountsView
|
||||
currentCollectiblesLists*: CollectiblesList
|
||||
|
||||
proc setup(self: CollectiblesView) = self.QObject.setup
|
||||
proc delete(self: CollectiblesView) =
|
||||
self.currentCollectiblesLists.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newCollectiblesView*(status: Status, accountsView: AccountsView): CollectiblesView =
|
||||
new(result, delete)
|
||||
result.status = status
|
||||
result.currentCollectiblesLists = newCollectiblesList()
|
||||
result.accountsView = accountsView # TODO: not ideal but a solution for now
|
||||
result.setup
|
||||
|
||||
proc currentCollectiblesListsChanged*(self: CollectiblesView) {.signal.}
|
||||
|
||||
proc getCurrentCollectiblesLists(self: CollectiblesView): QVariant {.slot.} =
|
||||
return newQVariant(self.currentCollectiblesLists)
|
||||
|
||||
proc setCurrentCollectiblesLists*(self: CollectiblesView, collectiblesLists: seq[CollectibleList]) =
|
||||
self.currentCollectiblesLists.setNewData(collectiblesLists)
|
||||
self.currentCollectiblesListsChanged()
|
||||
|
||||
QtProperty[QVariant] collectiblesLists:
|
||||
read = getCurrentCollectiblesLists
|
||||
write = setCurrentCollectiblesLists
|
||||
notify = currentCollectiblesListsChanged
|
||||
|
||||
proc loadCollectiblesForAccount*(self: CollectiblesView, address: string, currentCollectiblesList: seq[CollectibleList]) =
|
||||
if (currentCollectiblesList.len > 0):
|
||||
return
|
||||
# Add loading state if it is the current account
|
||||
if address == self.accountsView.currentAccount.address:
|
||||
for collectibleType in status_collectibles.COLLECTIBLE_TYPES:
|
||||
self.currentCollectiblesLists.addCollectibleListToList(CollectibleList(
|
||||
collectibleType: collectibleType,
|
||||
collectiblesJSON: "[]",
|
||||
error: "",
|
||||
loading: 1
|
||||
))
|
||||
|
||||
# TODO find a way to use a loop to streamline this code
|
||||
# Create a thread in the threadpool for each collectible. They can end in whichever order
|
||||
self.loadCollectibles("setCollectiblesResult", address, status_collectibles.CRYPTOKITTY)
|
||||
self.loadCollectibles("setCollectiblesResult", address, status_collectibles.KUDO)
|
||||
self.loadCollectibles("setCollectiblesResult", address, status_collectibles.ETHERMON)
|
||||
self.loadCollectibles("setCollectiblesResult", address, status_collectibles.STICKER)
|
||||
|
||||
proc setCollectiblesResult(self: CollectiblesView, collectiblesJSON: string) {.slot.} =
|
||||
let collectibleData = parseJson(collectiblesJSON)
|
||||
let address = collectibleData["address"].getStr
|
||||
let collectibleType = collectibleData["collectibleType"].getStr
|
||||
|
||||
var collectibles: JSONNode
|
||||
try:
|
||||
collectibles = parseJson(collectibleData["collectiblesOrError"].getStr)
|
||||
except Exception as e:
|
||||
# We failed parsing, this means the result is an error string
|
||||
self.currentCollectiblesLists.setErrorByType(
|
||||
collectibleType,
|
||||
$collectibleData["collectiblesOrError"]
|
||||
)
|
||||
return
|
||||
|
||||
# Add the collectibles to the WalletAccount
|
||||
let index = self.accountsView.accounts.getAccountindexByAddress(address)
|
||||
if index == -1: return
|
||||
self.accountsView.accounts.addCollectibleListToAccount(index, collectibleType, $collectibles)
|
||||
|
||||
if address == self.accountsView.currentAccount.address:
|
||||
# Add CollectibleListJSON to the right list
|
||||
self.currentCollectiblesLists.setCollectiblesJSONByType(
|
||||
collectibleType,
|
||||
$collectibles
|
||||
)
|
||||
|
||||
proc reloadCollectible*(self: CollectiblesView, collectibleType: string) {.slot.} =
|
||||
let address = self.accountsView.currentAccount.address
|
||||
self.loadCollectibles("setCollectiblesResult", address, collectibleType)
|
||||
self.currentCollectiblesLists.setLoadingByType(collectibleType, 1)
|
|
@ -0,0 +1,47 @@
|
|||
import atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, tables, chronicles, web3/[ethtypes, conversions], stint
|
||||
import NimQml, json, sequtils, chronicles, strutils, strformat, json
|
||||
|
||||
import ../../../status/[status, settings, wallet, tokens, types]
|
||||
|
||||
import account_list, account_item, transaction_list, accounts, asset_list, token_list
|
||||
|
||||
logScope:
|
||||
topics = "ens-view"
|
||||
|
||||
QtObject:
|
||||
type DappBrowserView* = ref object of QObject
|
||||
status: Status
|
||||
accountsView: AccountsView
|
||||
dappBrowserAccount*: AccountItemView
|
||||
|
||||
proc setup(self: DappBrowserView) = self.QObject.setup
|
||||
proc delete(self: DappBrowserView) =
|
||||
self.dappBrowserAccount.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newDappBrowserView*(status: Status, accountsView: AccountsView): DappBrowserView =
|
||||
new(result, delete)
|
||||
result.status = status
|
||||
result.accountsView = accountsView
|
||||
result.dappBrowserAccount = newAccountItemView()
|
||||
result.setup
|
||||
|
||||
proc dappBrowserAccountChanged*(self: DappBrowserView) {.signal.}
|
||||
|
||||
proc setDappBrowserAddress*(self: DappBrowserView) {.slot.} =
|
||||
if(self.accountsView.accounts.rowCount() == 0): return
|
||||
|
||||
let dappAddress = self.status.settings.getSetting[:string](Setting.DappsAddress)
|
||||
var index = self.accountsView.accounts.getAccountIndexByAddress(dappAddress)
|
||||
if index == -1: index = 0
|
||||
let selectedAccount = self.accountsView.accounts.getAccount(index)
|
||||
if self.dappBrowserAccount.address == selectedAccount.address: return
|
||||
self.dappBrowserAccount.setAccountItem(selectedAccount)
|
||||
self.dappBrowserAccountChanged()
|
||||
|
||||
proc getDappBrowserAccount*(self: DappBrowserView): QVariant {.slot.} =
|
||||
result = newQVariant(self.dappBrowserAccount)
|
||||
|
||||
QtProperty[QVariant] dappBrowserAccount:
|
||||
read = getDappBrowserAccount
|
||||
notify = dappBrowserAccountChanged
|
|
@ -0,0 +1,57 @@
|
|||
import atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, tables, chronicles, web3/[ethtypes, conversions], stint
|
||||
import NimQml, json, sequtils, chronicles, strutils, strformat, json
|
||||
|
||||
import
|
||||
../../../status/[status, settings, wallet, tokens],
|
||||
../../../status/ens as status_ens,
|
||||
../../../status/tasks/[qt, task_runner_impl]
|
||||
|
||||
import account_list, account_item, transaction_list, accounts, asset_list, token_list
|
||||
|
||||
logScope:
|
||||
topics = "ens-view"
|
||||
|
||||
type
|
||||
ResolveEnsTaskArg = ref object of QObjectTaskArg
|
||||
ens: string
|
||||
uuid: string
|
||||
|
||||
const resolveEnsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let
|
||||
arg = decode[ResolveEnsTaskArg](argEncoded)
|
||||
output = %* { "address": status_ens.address(arg.ens), "uuid": arg.uuid }
|
||||
arg.finish(output)
|
||||
|
||||
proc resolveEns[T](self: T, slot: string, ens: string, uuid: string) =
|
||||
let arg = ResolveEnsTaskArg(
|
||||
tptr: cast[ByteAddress](resolveEnsTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot, ens: ens, uuid: uuid
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
QtObject:
|
||||
type EnsView* = ref object of QObject
|
||||
status: Status
|
||||
|
||||
proc setup(self: EnsView) = self.QObject.setup
|
||||
proc delete(self: EnsView) = self.QObject.delete
|
||||
|
||||
proc newEnsView*(status: Status): EnsView =
|
||||
new(result, delete)
|
||||
result.status = status
|
||||
result.setup
|
||||
|
||||
proc resolveENS*(self: EnsView, ens: string, uuid: string) {.slot.} =
|
||||
self.resolveEns("ensResolved", ens, uuid)
|
||||
|
||||
proc ensWasResolved*(self: EnsView, resolvedAddress: string, uuid: string) {.signal.}
|
||||
|
||||
proc ensResolved(self: EnsView, addressUuidJson: string) {.slot.} =
|
||||
var
|
||||
parsed = addressUuidJson.parseJson
|
||||
address = parsed["address"].to(string)
|
||||
uuid = parsed["uuid"].to(string)
|
||||
if address == "0x":
|
||||
address = ""
|
||||
self.ensWasResolved(address, uuid)
|
|
@ -0,0 +1,115 @@
|
|||
import atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, tables, chronicles, web3/[ethtypes, conversions], stint
|
||||
import NimQml, json, sequtils, chronicles, strutils, strformat, json
|
||||
|
||||
import
|
||||
../../../status/[status, settings, wallet, tokens, utils, types],
|
||||
../../../status/tasks/[qt, task_runner_impl]
|
||||
|
||||
import account_list, account_item, transaction_list, accounts
|
||||
|
||||
const ZERO_ADDRESS* = "0x0000000000000000000000000000000000000000"
|
||||
|
||||
type
|
||||
GasPredictionsTaskArg = ref object of QObjectTaskArg
|
||||
|
||||
const getGasPredictionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let
|
||||
arg = decode[GasPredictionsTaskArg](argEncoded)
|
||||
output = %getGasPricePredictions()
|
||||
arg.finish(output)
|
||||
|
||||
proc getGasPredictions[T](self: T, slot: string) =
|
||||
let arg = GasPredictionsTaskArg(
|
||||
tptr: cast[ByteAddress](getGasPredictionsTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
logScope:
|
||||
topics = "gas-view"
|
||||
|
||||
QtObject:
|
||||
type GasView* = ref object of QObject
|
||||
status: Status
|
||||
safeLowGasPrice: string
|
||||
standardGasPrice: string
|
||||
fastGasPrice: string
|
||||
fastestGasPrice: string
|
||||
defaultGasLimit: string
|
||||
|
||||
proc setup(self: GasView) = self.QObject.setup
|
||||
proc delete(self: GasView) = self.QObject.delete
|
||||
|
||||
proc newGasView*(status: Status): GasView =
|
||||
new(result, delete)
|
||||
result.status = status
|
||||
result.safeLowGasPrice = "0"
|
||||
result.standardGasPrice = "0"
|
||||
result.fastGasPrice = "0"
|
||||
result.fastestGasPrice = "0"
|
||||
result.defaultGasLimit = "21000"
|
||||
result.setup
|
||||
|
||||
proc getGasEthValue*(self: GasView, gweiValue: string, gasLimit: string): string {.slot.} =
|
||||
var gweiValueInt:int
|
||||
var gasLimitInt:int
|
||||
|
||||
discard gweiValue.parseInt(gweiValueInt)
|
||||
discard gasLimit.parseInt(gasLimitInt)
|
||||
|
||||
let weiValue = gweiValueInt.u256 * 1000000000.u256 * gasLimitInt.u256
|
||||
let ethValue = wei2Eth(weiValue)
|
||||
result = fmt"{ethValue}"
|
||||
|
||||
proc estimateGas*(self: GasView, from_addr: string, to: string, assetAddress: string, value: string, data: string = ""): string {.slot.} =
|
||||
var
|
||||
response: string
|
||||
success: bool
|
||||
if assetAddress != ZERO_ADDRESS and not assetAddress.isEmptyOrWhitespace:
|
||||
response = self.status.wallet.estimateTokenGas(from_addr, to, assetAddress, value, success)
|
||||
else:
|
||||
response = self.status.wallet.estimateGas(from_addr, to, value, data, success)
|
||||
|
||||
if success == true:
|
||||
let res = fromHex[int](response)
|
||||
result = $(%* { "result": %res, "success": %success })
|
||||
else:
|
||||
result = $(%* { "result": "-1", "success": %success, "error": { "message": %response } })
|
||||
|
||||
proc gasPricePredictionsChanged*(self: GasView) {.signal.}
|
||||
|
||||
proc getGasPricePredictions*(self: GasView) {.slot.} =
|
||||
self.getGasPredictions("getGasPricePredictionsResult")
|
||||
|
||||
proc getGasPricePredictionsResult(self: GasView, gasPricePredictionsJson: string) {.slot.} =
|
||||
let prediction = Json.decode(gasPricePredictionsJson, GasPricePrediction)
|
||||
self.safeLowGasPrice = fmt"{prediction.safeLow:.3f}"
|
||||
self.standardGasPrice = fmt"{prediction.standard:.3f}"
|
||||
self.fastGasPrice = fmt"{prediction.fast:.3f}"
|
||||
self.fastestGasPrice = fmt"{prediction.fastest:.3f}"
|
||||
self.gasPricePredictionsChanged()
|
||||
|
||||
proc safeLowGasPrice*(self: GasView): string {.slot.} = result = ?.self.safeLowGasPrice
|
||||
QtProperty[string] safeLowGasPrice:
|
||||
read = safeLowGasPrice
|
||||
notify = gasPricePredictionsChanged
|
||||
|
||||
proc standardGasPrice*(self: GasView): string {.slot.} = result = ?.self.standardGasPrice
|
||||
QtProperty[string] standardGasPrice:
|
||||
read = standardGasPrice
|
||||
notify = gasPricePredictionsChanged
|
||||
|
||||
proc fastGasPrice*(self: GasView): string {.slot.} = result = ?.self.fastGasPrice
|
||||
QtProperty[string] fastGasPrice:
|
||||
read = fastGasPrice
|
||||
notify = gasPricePredictionsChanged
|
||||
|
||||
proc fastestGasPrice*(self: GasView): string {.slot.} = result = ?.self.fastestGasPrice
|
||||
QtProperty[string] fastestGasPrice:
|
||||
read = fastestGasPrice
|
||||
notify = gasPricePredictionsChanged
|
||||
|
||||
proc defaultGasLimit*(self: GasView): string {.slot.} = result = ?.self.defaultGasLimit
|
||||
QtProperty[string] defaultGasLimit:
|
||||
read = defaultGasLimit
|
|
@ -0,0 +1,92 @@
|
|||
import algorithm, atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, tables, chronicles, web3/[ethtypes, conversions], stint, sugar
|
||||
from sugar import `=>`, `->`
|
||||
import NimQml, json, sequtils, chronicles, strutils, strformat, json
|
||||
|
||||
import
|
||||
../../../status/[status, settings, wallet, tokens, types, utils],
|
||||
../../../status/tasks/[qt, task_runner_impl]
|
||||
|
||||
import account_list, account_item, transaction_list, accounts, asset_list, token_list, transactions
|
||||
|
||||
logScope:
|
||||
topics = "history-view"
|
||||
|
||||
QtObject:
|
||||
type HistoryView* = ref object of QObject
|
||||
status: Status
|
||||
accountsView: AccountsView
|
||||
transactionsView*: TransactionsView
|
||||
fetchingHistoryState: Table[string, bool]
|
||||
|
||||
proc setup(self: HistoryView) = self.QObject.setup
|
||||
proc delete(self: HistoryView) = self.QObject.delete
|
||||
|
||||
proc newHistoryView*(status: Status, accountsView: AccountsView, transactionsView: TransactionsView): HistoryView =
|
||||
new(result, delete)
|
||||
result.status = status
|
||||
result.fetchingHistoryState = initTable[string, bool]()
|
||||
result.accountsView = accountsView
|
||||
result.transactionsView = transactionsView
|
||||
result.setup
|
||||
|
||||
proc historyWasFetched*(self: HistoryView) {.signal.}
|
||||
|
||||
proc setHistoryFetchState*(self: HistoryView, accounts: seq[string], isFetching: bool) =
|
||||
for acc in accounts:
|
||||
self.fetchingHistoryState[acc] = isFetching
|
||||
if not isFetching: self.historyWasFetched()
|
||||
|
||||
proc isFetchingHistory*(self: HistoryView, address: string): bool {.slot.} =
|
||||
if self.fetchingHistoryState.hasKey(address):
|
||||
return self.fetchingHistoryState[address]
|
||||
return true
|
||||
|
||||
proc isHistoryFetched*(self: HistoryView, address: string): bool {.slot.} =
|
||||
return self.transactionsView.currentTransactions.rowCount() > 0
|
||||
|
||||
proc loadingTrxHistoryChanged*(self: HistoryView, isLoading: bool, address: string) {.signal.}
|
||||
|
||||
# proc loadTransactionsForAccount*(self: HistoryView, address: string) {.slot.} =
|
||||
# self.loadingTrxHistoryChanged(true)
|
||||
# self.transactionsView.loadTransactions("setTrxHistoryResult", address)
|
||||
|
||||
proc loadTransactionsForAccount*(self: HistoryView, address: string, toBlock: string = "0x0", limit: int = 20, loadMore: bool = false) {.slot.} =
|
||||
self.loadingTrxHistoryChanged(true, address)
|
||||
let toBlockParsed = stint.fromHex(Uint256, toBlock)
|
||||
self.loadTransactions("setTrxHistoryResult", address, toBlockParsed, limit, loadMore)
|
||||
|
||||
# proc getLatestTransactionHistory*(self: HistoryView, accounts: seq[string]) =
|
||||
# for acc in accounts:
|
||||
# self.loadTransactionsForAccount(acc)
|
||||
|
||||
proc setTrxHistoryResult(self: HistoryView, historyJSON: string) {.slot.} =
|
||||
let
|
||||
historyData = parseJson(historyJSON)
|
||||
transactions = historyData["history"].to(seq[Transaction])
|
||||
address = historyData["address"].getStr
|
||||
wasFetchMore = historyData["loadMore"].getBool
|
||||
isCurrentAccount = address.toLowerAscii == self.accountsView.currentAccount.address.toLowerAscii
|
||||
index = self.accountsView.accounts.getAccountindexByAddress(address)
|
||||
if index == -1: return
|
||||
|
||||
let account = self.accountsView.accounts.getAccount(index)
|
||||
# concatenate the new page of txs to existing account transactions,
|
||||
# sort them by block number and nonce, then deduplicate them based on their
|
||||
# transaction id.
|
||||
let existingAcctTxIds = account.transactions.data.map(tx => tx.id)
|
||||
let hasNewTxs = transactions.len > 0 and transactions.any(tx => not existingAcctTxIds.contains(tx.id))
|
||||
if hasNewTxs or not wasFetchMore:
|
||||
var allTxs: seq[Transaction] = account.transactions.data.concat(transactions)
|
||||
allTxs.sort(cmpTransactions, SortOrder.Descending)
|
||||
allTxs.deduplicate(tx => tx.id)
|
||||
account.transactions.data = allTxs
|
||||
account.transactions.hasMore = true
|
||||
if isCurrentAccount:
|
||||
self.transactionsView.currentTransactions.setHasMore(true)
|
||||
self.transactionsView.setCurrentTransactions(allTxs)
|
||||
else:
|
||||
account.transactions.hasMore = false
|
||||
if isCurrentAccount:
|
||||
self.transactionsView.currentTransactions.setHasMore(false)
|
||||
self.transactionsView.currentTransactionsChanged()
|
||||
self.loadingTrxHistoryChanged(false, address)
|
|
@ -0,0 +1,96 @@
|
|||
import atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, tables, chronicles, web3/[ethtypes, conversions], stint
|
||||
import NimQml, json, sequtils, chronicles, strutils, strformat, json
|
||||
|
||||
import ../../../status/[status, settings, wallet, tokens, utils, types]
|
||||
|
||||
import account_list, account_item, transaction_list, accounts, asset_list, token_list
|
||||
|
||||
logScope:
|
||||
topics = "tokens-view"
|
||||
|
||||
QtObject:
|
||||
type TokensView* = ref object of QObject
|
||||
status: Status
|
||||
accountsView: AccountsView
|
||||
currentAssetList*: AssetList
|
||||
defaultTokenList: TokenList
|
||||
customTokenList: TokenList
|
||||
|
||||
proc setup(self: TokensView) = self.QObject.setup
|
||||
proc delete(self: TokensView) =
|
||||
self.currentAssetList.delete
|
||||
self.defaultTokenList.delete
|
||||
self.customTokenList.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newTokensView*(status: Status, accountsView: AccountsView): TokensView =
|
||||
new(result, delete)
|
||||
result.status = status
|
||||
result.accountsView = accountsView
|
||||
result.currentAssetList = newAssetList()
|
||||
result.defaultTokenList = newTokenList(status)
|
||||
result.customTokenList = newTokenList(status)
|
||||
result.setup
|
||||
|
||||
proc hasAsset*(self: TokensView, symbol: string): bool {.slot.} =
|
||||
self.status.wallet.hasAsset(symbol)
|
||||
|
||||
proc toggleAsset*(self: TokensView, symbol: string) {.slot.} =
|
||||
self.status.wallet.toggleAsset(symbol)
|
||||
self.accountsView.setAccountItems()
|
||||
|
||||
proc removeCustomToken*(self: TokensView, tokenAddress: string) {.slot.} =
|
||||
let t = self.status.tokens.getCustomTokens().getErc20ContractByAddress(parseAddress(tokenAddress))
|
||||
if t == nil: return
|
||||
self.status.wallet.hideAsset(t.symbol)
|
||||
self.status.tokens.removeCustomToken(tokenAddress)
|
||||
self.customTokenList.loadCustomTokens()
|
||||
self.accountsView.setAccountItems()
|
||||
|
||||
proc addCustomToken*(self: TokensView, address: string, name: string, symbol: string, decimals: string) {.slot.} =
|
||||
self.status.wallet.addCustomToken(symbol, true, address, name, parseInt(decimals), "")
|
||||
|
||||
proc getDefaultTokenList(self: TokensView): QVariant {.slot.} =
|
||||
self.defaultTokenList.loadDefaultTokens()
|
||||
result = newQVariant(self.defaultTokenList)
|
||||
|
||||
QtProperty[QVariant] defaultTokenList:
|
||||
read = getDefaultTokenList
|
||||
|
||||
proc loadCustomTokens(self: TokensView) {.slot.} =
|
||||
self.customTokenList.loadCustomTokens()
|
||||
|
||||
proc getCustomTokenList(self: TokensView): QVariant {.slot.} =
|
||||
result = newQVariant(self.customTokenList)
|
||||
|
||||
QtProperty[QVariant] customTokenList:
|
||||
read = getCustomTokenList
|
||||
|
||||
proc isKnownTokenContract*(self: TokensView, address: string): bool {.slot.} =
|
||||
return self.status.wallet.getKnownTokenContract(parseAddress(address)) != nil
|
||||
|
||||
proc decodeTokenApproval*(self: TokensView, tokenAddress: string, data: string): string {.slot.} =
|
||||
let amount = data[74..len(data)-1]
|
||||
let token = self.status.tokens.getToken(tokenAddress)
|
||||
|
||||
if(token != nil):
|
||||
let amountDec = $self.status.wallet.hex2Token(amount, token.decimals)
|
||||
return $(%* {"symbol": token.symbol, "amount": amountDec})
|
||||
|
||||
return """{"error":"Unknown token address"}""";
|
||||
|
||||
proc getStatusToken*(self: TokensView): string {.slot.} = self.status.wallet.getStatusToken
|
||||
|
||||
proc currentAssetListChanged*(self: TokensView) {.signal.}
|
||||
|
||||
proc getCurrentAssetList(self: TokensView): QVariant {.slot.} =
|
||||
return newQVariant(self.currentAssetList)
|
||||
|
||||
proc setCurrentAssetList*(self: TokensView, assetList: seq[Asset]) =
|
||||
self.currentAssetList.setNewData(assetList)
|
||||
self.currentAssetListChanged()
|
||||
|
||||
QtProperty[QVariant] assets:
|
||||
read = getCurrentAssetList
|
||||
write = setCurrentAssetList
|
||||
notify = currentAssetListChanged
|
|
@ -0,0 +1,148 @@
|
|||
import algorithm, atomics, sequtils, strformat, strutils, sugar, sequtils, json, parseUtils, std/wrapnils, tables
|
||||
import NimQml, json, sequtils, chronicles, strutils, strformat, json, stint
|
||||
|
||||
import
|
||||
../../../status/[status, settings, wallet, tokens],
|
||||
../../../status/wallet as status_wallet,
|
||||
../../../status/tasks/[qt, task_runner_impl]
|
||||
|
||||
import account_list, account_item, transaction_list, accounts
|
||||
|
||||
const ZERO_ADDRESS* = "0x0000000000000000000000000000000000000000"
|
||||
|
||||
logScope:
|
||||
topics = "transactions-view"
|
||||
|
||||
type
|
||||
SendTransactionTaskArg = ref object of QObjectTaskArg
|
||||
from_addr: string
|
||||
to: string
|
||||
assetAddress: string
|
||||
value: string
|
||||
gas: string
|
||||
gasPrice: string
|
||||
password: string
|
||||
uuid: string
|
||||
LoadTransactionsTaskArg = ref object of QObjectTaskArg
|
||||
address: string
|
||||
toBlock: Uint256
|
||||
limit: int
|
||||
loadMore: bool
|
||||
WatchTransactionTaskArg = ref object of QObjectTaskArg
|
||||
transactionHash: string
|
||||
|
||||
const sendTransactionTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[SendTransactionTaskArg](argEncoded)
|
||||
var
|
||||
success: bool
|
||||
response: string
|
||||
if arg.assetAddress != ZERO_ADDRESS and not arg.assetAddress.isEmptyOrWhitespace:
|
||||
response = wallet.sendTokenTransaction(arg.from_addr, arg.to, arg.assetAddress, arg.value, arg.gas, arg.gasPrice, arg.password, success)
|
||||
else:
|
||||
response = wallet.sendTransaction(arg.from_addr, arg.to, arg.value, arg.gas, arg.gasPrice, arg.password, success)
|
||||
let output = %* { "result": %response, "success": %success, "uuid": %arg.uuid }
|
||||
arg.finish(output)
|
||||
|
||||
proc sendTransaction[T](self: T, slot: string, from_addr: string, to: string, assetAddress: string, value: string, gas: string, gasPrice: string, password: string, uuid: string) =
|
||||
let arg = SendTransactionTaskArg(
|
||||
tptr: cast[ByteAddress](sendTransactionTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot, from_addr: from_addr, to: to,
|
||||
assetAddress: assetAddress, value: value, gas: gas,
|
||||
gasPrice: gasPrice, password: password, uuid: uuid
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
const loadTransactionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let
|
||||
arg = decode[LoadTransactionsTaskArg](argEncoded)
|
||||
output = %*{
|
||||
"address": arg.address,
|
||||
"history": status_wallet.getTransfersByAddress(arg.address, arg.toBlock, arg.limit, arg.loadMore),
|
||||
"loadMore": arg.loadMore
|
||||
}
|
||||
arg.finish(output)
|
||||
|
||||
proc loadTransactions*[T](self: T, slot: string, address: string, toBlock: Uint256, limit: int, loadMore: bool) =
|
||||
let arg = LoadTransactionsTaskArg(
|
||||
tptr: cast[ByteAddress](loadTransactionsTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot, address: address,
|
||||
toBlock: toBlock, limit: limit, loadMore: loadMore
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
const watchTransactionTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let
|
||||
arg = decode[WatchTransactionTaskArg](argEncoded)
|
||||
response = status_wallet.watchTransaction(arg.transactionHash)
|
||||
output = %* { "result": response }
|
||||
arg.finish(output)
|
||||
|
||||
proc watchTransaction[T](self: T, slot: string, transactionHash: string) =
|
||||
let arg = WatchTransactionTaskArg(
|
||||
tptr: cast[ByteAddress](watchTransactionTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot, transactionHash: transactionHash
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
QtObject:
|
||||
type TransactionsView* = ref object of QObject
|
||||
status: Status
|
||||
accountsView*: AccountsView
|
||||
transactionsView*: TransactionsView
|
||||
currentTransactions*: TransactionList
|
||||
|
||||
proc setup(self: TransactionsView) = self.QObject.setup
|
||||
proc delete(self: TransactionsView) =
|
||||
self.currentTransactions.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newTransactionsView*(status: Status, accountsView: AccountsView): TransactionsView =
|
||||
new(result, delete)
|
||||
result.status = status
|
||||
result.accountsView = accountsView # TODO: not ideal but a solution for now
|
||||
result.currentTransactions = newTransactionList()
|
||||
result.setup
|
||||
|
||||
proc currentTransactionsChanged*(self: TransactionsView) {.signal.}
|
||||
|
||||
proc getCurrentTransactions*(self: TransactionsView): QVariant {.slot.} =
|
||||
return newQVariant(self.currentTransactions)
|
||||
|
||||
proc setCurrentTransactions*(self: TransactionsView, transactionList: seq[Transaction]) =
|
||||
self.currentTransactions.setNewData(transactionList)
|
||||
self.currentTransactionsChanged()
|
||||
|
||||
QtProperty[QVariant] transactions:
|
||||
read = getCurrentTransactions
|
||||
write = setCurrentTransactions
|
||||
notify = currentTransactionsChanged
|
||||
|
||||
proc transactionWasSent*(self: TransactionsView, txResult: string) {.signal.}
|
||||
|
||||
proc transactionSent(self: TransactionsView, txResult: string) {.slot.} =
|
||||
self.transactionWasSent(txResult)
|
||||
let jTxRes = txResult.parseJSON()
|
||||
let txHash = jTxRes{"result"}.getStr()
|
||||
if txHash != "":
|
||||
self.watchTransaction("transactionWatchResultReceived", txHash)
|
||||
|
||||
proc sendTransaction*(self: TransactionsView, from_addr: string, to: string, assetAddress: string, value: string, gas: string, gasPrice: string, password: string, uuid: string) {.slot.} =
|
||||
self.sendTransaction("transactionSent", from_addr, to, assetAddress, value, gas, gasPrice, password, uuid)
|
||||
|
||||
proc checkRecentHistory*(self: TransactionsView) {.slot.} =
|
||||
var addresses:seq[string] = @[]
|
||||
for acc in self.status.wallet.accounts:
|
||||
addresses.add(acc.address)
|
||||
discard self.status.wallet.checkRecentHistory(addresses)
|
||||
|
||||
proc transactionWatchResultReceived(self: TransactionsView, watchResult: string) {.slot.} =
|
||||
let wTxRes = watchResult.parseJSON()["result"].getStr().parseJson(){"result"}
|
||||
if wTxRes.kind == JNull:
|
||||
self.checkRecentHistory()
|
||||
else:
|
||||
discard #TODO: Ask Simon if should we show an error popup indicating the trx wasn't mined in 10m or something
|
||||
|
||||
proc transactionCompleted*(self: TransactionsView, success: bool, txHash: string, revertReason: string = "") {.signal.}
|
|
@ -0,0 +1,45 @@
|
|||
import atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, tables, chronicles, web3/[ethtypes, conversions], stint
|
||||
import NimQml, json, sequtils, chronicles, strutils, strformat, json
|
||||
|
||||
logScope:
|
||||
topics = "utils-view"
|
||||
|
||||
QtObject:
|
||||
type UtilsView* = ref object of QObject
|
||||
etherscanLink: string
|
||||
signingPhrase: string
|
||||
|
||||
proc setup(self: UtilsView) = self.QObject.setup
|
||||
proc delete(self: UtilsView) = self.QObject.delete
|
||||
|
||||
proc newUtilsView*(): UtilsView =
|
||||
new(result, delete)
|
||||
result.etherscanLink = ""
|
||||
result.signingPhrase = ""
|
||||
result.setup
|
||||
|
||||
proc etherscanLinkChanged*(self: UtilsView) {.signal.}
|
||||
|
||||
proc getEtherscanLink*(self: UtilsView): QVariant {.slot.} =
|
||||
newQVariant(self.etherscanLink.replace("/address", "/tx"))
|
||||
|
||||
proc setEtherscanLink*(self: UtilsView, link: string) =
|
||||
self.etherscanLink = link
|
||||
self.etherscanLinkChanged()
|
||||
|
||||
proc signingPhraseChanged*(self: UtilsView) {.signal.}
|
||||
|
||||
proc getSigningPhrase*(self: UtilsView): QVariant {.slot.} =
|
||||
newQVariant(self.signingPhrase)
|
||||
|
||||
proc setSigningPhrase*(self: UtilsView, signingPhrase: string) =
|
||||
self.signingPhrase = signingPhrase
|
||||
self.signingPhraseChanged()
|
||||
|
||||
QtProperty[QVariant] etherscanLink:
|
||||
read = getEtherscanLink
|
||||
notify = etherscanLinkChanged
|
||||
|
||||
QtProperty[QVariant] signingPhrase:
|
||||
read = getSigningPhrase
|
||||
notify = signingPhraseChanged
|
|
@ -10,6 +10,12 @@ import nbaser
|
|||
import stew/byteutils
|
||||
from base32 import nil
|
||||
|
||||
const HTTPS_SCHEME = "https"
|
||||
const IPFS_GATEWAY = ".infura.status.im"
|
||||
const SWARM_GATEWAY = "swarm-gateways.net"
|
||||
|
||||
const base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
|
||||
logScope:
|
||||
topics = "provider-model"
|
||||
|
||||
|
@ -238,3 +244,20 @@ proc postMessage*(self: ProviderModel, message: string): string =
|
|||
of RequestTypes.HistoryStateChanged: """{"type":"TODO-IMPLEMENT-THIS"}""" ############# TODO:
|
||||
of RequestTypes.APIRequest: self.process(message.toAPIRequest())
|
||||
else: """{"type":"TODO-IMPLEMENT-THIS"}""" ##################### TODO:
|
||||
|
||||
proc ensResourceURL*(self: ProviderModel, ens: string, url: string): (string, string, string, string, bool) =
|
||||
let contentHash = contenthash(ens)
|
||||
if contentHash == "": # ENS does not have a content hash
|
||||
return (url, url, HTTPS_SCHEME, "", false)
|
||||
|
||||
let decodedHash = contentHash.decodeENSContentHash()
|
||||
case decodedHash[0]:
|
||||
of ENSType.IPFS:
|
||||
let base32Hash = base32.encode(string.fromBytes(base58.decode(decodedHash[1]))).toLowerAscii().replace("=", "")
|
||||
result = (url, base32Hash & IPFS_GATEWAY, HTTPS_SCHEME, "", true)
|
||||
of ENSType.SWARM:
|
||||
result = (url, SWARM_GATEWAY, HTTPS_SCHEME, "/bzz:/" & decodedHash[1] & "/", true)
|
||||
of ENSType.IPNS:
|
||||
result = (url, decodedHash[1], HTTPS_SCHEME, "", true)
|
||||
else:
|
||||
warn "Unknown content for", ens, contentHash
|
||||
|
|
|
@ -117,9 +117,9 @@ Popup {
|
|||
width: 190
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
showAccountDetails: false
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
selectedAccount: walletModel.dappBrowserAccount
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
onSelectedAccountChanged: {
|
||||
if (!root.currentAddress) {
|
||||
// We just set the account for the first time. Nothing to do here
|
||||
|
|
|
@ -212,7 +212,7 @@ property Component sendTransactionModalComponent: SignTransactionModal {}
|
|||
toastMessage.source = "../../img/loading.svg"
|
||||
toastMessage.iconColor = Style.current.primary
|
||||
toastMessage.iconRotates = true
|
||||
toastMessage.link = `${_walletModel.etherscanLink}/${responseObj.result.result}`
|
||||
toastMessage.link = `${_walletModel.utilsView.etherscanLink}/${responseObj.result.result}`
|
||||
toastMessage.open()
|
||||
} catch (e) {
|
||||
if (Utils.isInvalidPasswordMessage(e.message)){
|
||||
|
@ -229,7 +229,7 @@ property Component sendTransactionModalComponent: SignTransactionModal {}
|
|||
}
|
||||
|
||||
sendDialog.open();
|
||||
walletModel.getGasPricePredictions()
|
||||
walletModel.gasView.getGasPricePredictions()
|
||||
} else if (request.type === Constants.web3SendAsyncReadOnly && ["eth_sign", "personal_sign", "eth_signTypedData", "eth_signTypedData_v3"].indexOf(request.payload.method) > -1) {
|
||||
const signDialog = signMessageModalComponent.createObject(browserWindow, {
|
||||
request,
|
||||
|
|
|
@ -109,9 +109,9 @@ Popup {
|
|||
anchors.left: parent.left
|
||||
anchors.right: copyBtn.left
|
||||
anchors.rightMargin: Style.current.padding
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
selectedAccount: walletModel.dappBrowserAccount
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
onSelectedAccountChanged: {
|
||||
if (!accountSelectorRow.currentAddress) {
|
||||
// We just set the account for the first time. Nothing to do here
|
||||
|
|
|
@ -72,7 +72,7 @@ ModalPopup {
|
|||
TransactionSigner {
|
||||
id: transactionSigner
|
||||
width: parent.width
|
||||
signingPhrase: walletModel.signingPhrase
|
||||
signingPhrase: walletModel.utilsView.signingPhrase
|
||||
visible: showSigningPhrase
|
||||
}
|
||||
|
||||
|
|
|
@ -439,7 +439,7 @@ StackLayout {
|
|||
return {
|
||||
address: Constants.zeroAddress, // Setting as zero address since we don't have the address yet
|
||||
alias: chatsModel.activeChannel.alias,
|
||||
identicon: activeChatIdenticon,
|
||||
identicon: chatsModel.activeChannel.identicon,
|
||||
name: chatsModel.activeChannel.name,
|
||||
type: RecipientSelector.Type.Contact
|
||||
}
|
||||
|
@ -466,7 +466,7 @@ StackLayout {
|
|||
return {
|
||||
address: Constants.zeroAddress, // Setting as zero address since we don't have the address yet
|
||||
alias: chatsModel.activeChannel.alias,
|
||||
identicon: activeChatIdenticon,
|
||||
identicon: chatsModel.activeChannel.identicon,
|
||||
name: chatsModel.activeChannel.name,
|
||||
type: RecipientSelector.Type.Contact
|
||||
}
|
||||
|
@ -480,7 +480,7 @@ StackLayout {
|
|||
SendModal {
|
||||
id: sendTransactionWithEns
|
||||
onOpened: {
|
||||
walletModel.getGasPricePredictions()
|
||||
walletModel.gasView.getGasPricePredictions()
|
||||
}
|
||||
onClosed: {
|
||||
txModalLoader.closed()
|
||||
|
@ -490,7 +490,7 @@ StackLayout {
|
|||
return {
|
||||
address: "",
|
||||
alias: chatsModel.activeChannel.alias,
|
||||
identicon: activeChatIdenticon,
|
||||
identicon: chatsModel.activeChannel.identicon,
|
||||
name: chatsModel.activeChannel.name,
|
||||
type: RecipientSelector.Type.Contact,
|
||||
ensVerified: true
|
||||
|
|
|
@ -35,15 +35,15 @@ ModalPopup {
|
|||
|
||||
AccountSelector {
|
||||
id: selectFromAccount
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
selectedAccount: {
|
||||
const currAcc = walletModel.currentAccount
|
||||
const currAcc = walletModel.accountsView.currentAccount
|
||||
if (currAcc.walletType !== Constants.watchWalletType) {
|
||||
return currAcc
|
||||
}
|
||||
return null
|
||||
}
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
width: stack.width
|
||||
label: {
|
||||
return root.isRequested ?
|
||||
|
@ -73,7 +73,7 @@ ModalPopup {
|
|||
|
||||
RecipientSelector {
|
||||
id: selectRecipient
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
contacts: profileModel.contacts.addedContacts
|
||||
label: root.isRequested ?
|
||||
//% "From"
|
||||
|
@ -97,9 +97,9 @@ ModalPopup {
|
|||
AssetAndAmountInput {
|
||||
id: txtAmount
|
||||
selectedAccount: selectFromAccount.selectedAccount
|
||||
defaultCurrency: walletModel.defaultCurrency
|
||||
getFiatValue: walletModel.getFiatValue
|
||||
getCryptoValue: walletModel.getCryptoValue
|
||||
defaultCurrency: walletModel.balanceView.defaultCurrency
|
||||
getFiatValue: walletModel.balanceView.getFiatValue
|
||||
getCryptoValue: walletModel.balanceView.getCryptoValue
|
||||
validateBalance: !root.isRequested
|
||||
width: stack.width
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ ModalPopup {
|
|||
asset: txtAmount.selectedAsset
|
||||
amount: { "value": txtAmount.selectedAmount, "fiatValue": txtAmount.selectedFiatAmount }
|
||||
toWarn: addressRequiredValidator.isWarn
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
}
|
||||
|
||||
AddressRequiredValidator {
|
||||
|
|
|
@ -19,7 +19,7 @@ ModalPopup {
|
|||
property alias transactionSigner: transactionSigner
|
||||
|
||||
property var sendTransaction: function(selectedGasLimit, selectedGasPrice, enteredPassword) {
|
||||
let responseStr = walletModel.sendTransaction(selectFromAccount.selectedAccount.address,
|
||||
let responseStr = walletModel.transactionsView.sendTransaction(selectFromAccount.selectedAccount.address,
|
||||
selectRecipient.selectedRecipient.address,
|
||||
root.selectedAsset.address,
|
||||
root.selectedAmount,
|
||||
|
@ -64,7 +64,7 @@ ModalPopup {
|
|||
id: groupSelectAcct
|
||||
headerText: {
|
||||
if(trxData.startsWith("0x095ea7b3")){
|
||||
const approveData = JSON.parse(walletModel.decodeTokenApproval(selectedRecipient.address, trxData))
|
||||
const approveData = JSON.parse(walletModel.tokensView.decodeTokenApproval(selectedRecipient.address, trxData))
|
||||
if(approveData.symbol)
|
||||
//% "Authorize %1 %2"
|
||||
return qsTrId("authorize--1--2").arg(approveData.amount).arg(approveData.symbol)
|
||||
|
@ -81,8 +81,8 @@ ModalPopup {
|
|||
}
|
||||
AccountSelector {
|
||||
id: selectFromAccount
|
||||
accounts: walletModel.accounts
|
||||
currency: walletModel.defaultCurrency
|
||||
accounts: walletModel.accountsView.accounts
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
width: stack.width
|
||||
selectedAccount: root.selectedAccount
|
||||
//% "Choose account"
|
||||
|
@ -94,7 +94,7 @@ ModalPopup {
|
|||
RecipientSelector {
|
||||
id: selectRecipient
|
||||
visible: false
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
contacts: profileModel.contacts.addedContacts
|
||||
selectedRecipient: root.selectedRecipient
|
||||
readOnly: true
|
||||
|
@ -113,11 +113,11 @@ ModalPopup {
|
|||
GasSelector {
|
||||
id: gasSelector
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
slowestGasPrice: parseFloat(walletModel.safeLowGasPrice)
|
||||
fastestGasPrice: parseFloat(walletModel.fastestGasPrice)
|
||||
getGasEthValue: walletModel.getGasEthValue
|
||||
getFiatValue: walletModel.getFiatValue
|
||||
defaultCurrency: walletModel.defaultCurrency
|
||||
slowestGasPrice: parseFloat(walletModel.gasView.safeLowGasPrice)
|
||||
fastestGasPrice: parseFloat(walletModel.gasView.fastestGasPrice)
|
||||
getGasEthValue: walletModel.gasView.getGasEthValue
|
||||
getFiatValue: walletModel.balanceView.getFiatValue
|
||||
defaultCurrency: walletModel.balanceView.defaultCurrency
|
||||
width: stack.width
|
||||
|
||||
property var estimateGas: Backpressure.debounce(gasSelector, 600, function() {
|
||||
|
@ -129,7 +129,7 @@ ModalPopup {
|
|||
return
|
||||
}
|
||||
|
||||
let gasEstimate = JSON.parse(walletModel.estimateGas(
|
||||
let gasEstimate = JSON.parse(walletModel.gasView.estimateGas(
|
||||
selectFromAccount.selectedAccount.address,
|
||||
selectRecipient.selectedRecipient.address,
|
||||
root.selectedAsset.address,
|
||||
|
@ -183,7 +183,7 @@ ModalPopup {
|
|||
toAccount: selectRecipient.selectedRecipient
|
||||
asset: root.selectedAsset
|
||||
amount: { "value": root.selectedAmount, "fiatValue": root.selectedFiatAmount }
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
isFromEditable: false
|
||||
trxData: root.trxData
|
||||
isGasEditable: true
|
||||
|
@ -224,7 +224,7 @@ ModalPopup {
|
|||
TransactionSigner {
|
||||
id: transactionSigner
|
||||
width: stack.width
|
||||
signingPhrase: walletModel.signingPhrase
|
||||
signingPhrase: walletModel.utilsView.signingPhrase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ ModalPopup {
|
|||
}
|
||||
|
||||
Connections {
|
||||
target: walletModel
|
||||
target: walletModel.transactionsView
|
||||
onTransactionWasSent: {
|
||||
try {
|
||||
let response = JSON.parse(txResult)
|
||||
|
@ -297,7 +297,7 @@ ModalPopup {
|
|||
toastMessage.source = "../../../../img/loading.svg"
|
||||
toastMessage.iconColor = Style.current.primary
|
||||
toastMessage.iconRotates = true
|
||||
toastMessage.link = `${walletModel.etherscanLink}/${response.result}`
|
||||
toastMessage.link = `${walletModel.utilsView.etherscanLink}/${response.result}`
|
||||
toastMessage.open()
|
||||
root.close()
|
||||
} catch (e) {
|
||||
|
|
|
@ -31,8 +31,8 @@ Item {
|
|||
if (!tokenAmount || !token.symbol) {
|
||||
return "0"
|
||||
}
|
||||
var defaultFiatSymbol = walletModel.defaultCurrency
|
||||
return walletModel.getFiatValue(tokenAmount, token.symbol, defaultFiatSymbol) + " " + defaultFiatSymbol.toUpperCase()
|
||||
var defaultFiatSymbol = walletModel.balanceView.defaultCurrency
|
||||
return walletModel.balanceView.getFiatValue(tokenAmount, token.symbol, defaultFiatSymbol) + " " + defaultFiatSymbol.toUpperCase()
|
||||
}
|
||||
property int state: commandParametersObject.commandState
|
||||
property bool outgoing: {
|
||||
|
|
|
@ -89,7 +89,7 @@ Item {
|
|||
id: signTxComponent
|
||||
SignTransactionModal {
|
||||
onOpened: {
|
||||
walletModel.getGasPricePredictions()
|
||||
walletModel.gasView.getGasPricePredictions()
|
||||
}
|
||||
onClosed: {
|
||||
destroy();
|
||||
|
|
|
@ -20,8 +20,8 @@ ModalPopup {
|
|||
anchors.rightMargin: Style.current.padding
|
||||
AccountSelector {
|
||||
id: selectFromAccount
|
||||
accounts: walletModel.accounts
|
||||
currency: walletModel.defaultCurrency
|
||||
accounts: walletModel.accountsView.accounts
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
width: parent.width
|
||||
//% "Choose account"
|
||||
//% "Select account to share and receive assets"
|
||||
|
|
|
@ -30,8 +30,8 @@ Item {
|
|||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
walletModel.setFocusedAccountByAddress(commandParametersObject.fromAddress)
|
||||
var acc = walletModel.focusedAccount
|
||||
walletModel.accountsView.setFocusedAccountByAddress(commandParametersObject.fromAddress)
|
||||
var acc = walletModel.accountsView.focusedAccount
|
||||
openPopup(signTxComponent, {selectedAccount: {
|
||||
name: acc.name,
|
||||
address: commandParametersObject.fromAddress,
|
||||
|
@ -46,7 +46,7 @@ Item {
|
|||
id: signTxComponent
|
||||
SignTransactionModal {
|
||||
onOpened: {
|
||||
walletModel.getGasPricePredictions()
|
||||
walletModel.gasView.getGasPricePredictions()
|
||||
}
|
||||
onClosed: {
|
||||
destroy();
|
||||
|
|
|
@ -63,15 +63,15 @@ ModalPopup {
|
|||
|
||||
AccountSelector {
|
||||
id: selectFromAccount
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
selectedAccount: {
|
||||
const currAcc = walletModel.currentAccount
|
||||
const currAcc = walletModel.accountsView.currentAccount
|
||||
if (currAcc.walletType !== Constants.watchWalletType) {
|
||||
return currAcc
|
||||
}
|
||||
return null
|
||||
}
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
width: stack.width
|
||||
//% "Choose account"
|
||||
label: qsTrId("choose-account")
|
||||
|
@ -82,7 +82,7 @@ ModalPopup {
|
|||
RecipientSelector {
|
||||
id: selectRecipient
|
||||
visible: false
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
contacts: profileModel.contacts.addedContacts
|
||||
selectedRecipient: { "address": utilsModel.ensRegisterAddress, "type": RecipientSelector.Type.Address }
|
||||
readOnly: true
|
||||
|
@ -91,11 +91,11 @@ ModalPopup {
|
|||
GasSelector {
|
||||
id: gasSelector
|
||||
visible: false
|
||||
slowestGasPrice: parseFloat(walletModel.safeLowGasPrice)
|
||||
fastestGasPrice: parseFloat(walletModel.fastestGasPrice)
|
||||
getGasEthValue: walletModel.getGasEthValue
|
||||
getFiatValue: walletModel.getFiatValue
|
||||
defaultCurrency: walletModel.defaultCurrency
|
||||
slowestGasPrice: parseFloat(walletModel.gasView.safeLowGasPrice)
|
||||
fastestGasPrice: parseFloat(walletModel.gasView.fastestGasPrice)
|
||||
getGasEthValue: walletModel.gasView.getGasEthValue
|
||||
getFiatValue: walletModel.balanceView.getFiatValue
|
||||
defaultCurrency: walletModel.balanceView.defaultCurrency
|
||||
property var estimateGas: Backpressure.debounce(gasSelector, 600, function() {
|
||||
if (!(root.ensUsername !== "" && selectFromAccount.selectedAccount)) {
|
||||
selectedGasLimit = 380000
|
||||
|
@ -132,9 +132,9 @@ ModalPopup {
|
|||
}
|
||||
toAccount: selectRecipient.selectedRecipient
|
||||
asset: root.asset
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
amount: {
|
||||
const fiatValue = walletModel.getFiatValue(root.ensPrice || 0, root.asset.symbol, currency)
|
||||
const fiatValue = walletModel.balanceView.getFiatValue(root.ensPrice || 0, root.asset.symbol, currency)
|
||||
return { "value": root.ensPrice, "fiatValue": fiatValue }
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ ModalPopup {
|
|||
TransactionSigner {
|
||||
id: transactionSigner
|
||||
width: stack.width
|
||||
signingPhrase: walletModel.signingPhrase
|
||||
signingPhrase: walletModel.utilsView.signingPhrase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,15 +68,15 @@ ModalPopup {
|
|||
|
||||
AccountSelector {
|
||||
id: selectFromAccount
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
selectedAccount: {
|
||||
const currAcc = walletModel.currentAccount
|
||||
const currAcc = walletModel.accountsView.currentAccount
|
||||
if (currAcc.walletType !== Constants.watchWalletType) {
|
||||
return currAcc
|
||||
}
|
||||
return null
|
||||
}
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
width: stack.width
|
||||
//% "Choose account"
|
||||
label: qsTrId("choose-account")
|
||||
|
@ -87,7 +87,7 @@ ModalPopup {
|
|||
RecipientSelector {
|
||||
id: selectRecipient
|
||||
visible: false
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
contacts: profileModel.contacts.addedContacts
|
||||
selectedRecipient: { "address": utilsModel.ensRegisterAddress, "type": RecipientSelector.Type.Address }
|
||||
readOnly: true
|
||||
|
@ -96,11 +96,11 @@ ModalPopup {
|
|||
GasSelector {
|
||||
id: gasSelector
|
||||
visible: false
|
||||
slowestGasPrice: parseFloat(walletModel.safeLowGasPrice)
|
||||
fastestGasPrice: parseFloat(walletModel.fastestGasPrice)
|
||||
getGasEthValue: walletModel.getGasEthValue
|
||||
getFiatValue: walletModel.getFiatValue
|
||||
defaultCurrency: walletModel.defaultCurrency
|
||||
slowestGasPrice: parseFloat(walletModel.gasView.safeLowGasPrice)
|
||||
fastestGasPrice: parseFloat(walletModel.gasView.fastestGasPrice)
|
||||
getGasEthValue: walletModel.gasView.getGasEthValue
|
||||
getFiatValue: walletModel.balanceView.getFiatValue
|
||||
defaultCurrency: walletModel.balanceView.defaultCurrency
|
||||
property var estimateGas: Backpressure.debounce(gasSelector, 600, function() {
|
||||
if (!(root.ensUsername !== "" && selectFromAccount.selectedAccount)) {
|
||||
selectedGasLimit = 80000;
|
||||
|
@ -137,9 +137,9 @@ ModalPopup {
|
|||
}
|
||||
toAccount: selectRecipient.selectedRecipient
|
||||
asset: root.asset
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
amount: {
|
||||
const fiatValue = walletModel.getFiatValue(0, root.asset.symbol, currency)
|
||||
const fiatValue = walletModel.balanceView.getFiatValue(0, root.asset.symbol, currency)
|
||||
return { "value": 0, "fiatValue": fiatValue }
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ ModalPopup {
|
|||
TransactionSigner {
|
||||
id: transactionSigner
|
||||
width: stack.width
|
||||
signingPhrase: walletModel.signingPhrase
|
||||
signingPhrase: walletModel.utilsView.signingPhrase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ Item {
|
|||
|
||||
StyledText {
|
||||
//% "<a href='%1%2'>Look up on Etherscan</a>"
|
||||
text: qsTrId("-a-href---1-2--look-up-on-etherscan--a-").arg(walletModel.etherscanLink.replace("/tx", "/address")).arg(profileModel.ens.getUsernameRegistrar())
|
||||
text: qsTrId("-a-href---1-2--look-up-on-etherscan--a-").arg(walletModel.utilsView.etherscanLink.replace("/tx", "/address")).arg(profileModel.ens.getUsernameRegistrar())
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
onLinkActivated: appMain.openLink(link)
|
||||
|
@ -158,7 +158,7 @@ Item {
|
|||
|
||||
StyledText {
|
||||
//% "<a href='%1%2'>Look up on Etherscan</a>"
|
||||
text: qsTrId("-a-href---1-2--look-up-on-etherscan--a-").arg(walletModel.etherscanLink.replace("/tx", "/address")).arg(profileModel.ens.getENSRegistry())
|
||||
text: qsTrId("-a-href---1-2--look-up-on-etherscan--a-").arg(walletModel.utilsView.etherscanLink.replace("/tx", "/address")).arg(profileModel.ens.getENSRegistry())
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
onLinkActivated: appMain.openLink(link)
|
||||
|
|
|
@ -283,7 +283,7 @@ Item {
|
|||
toastMessage.source = "../../../img/loading.svg"
|
||||
toastMessage.iconColor = Style.current.primary
|
||||
toastMessage.iconRotates = true
|
||||
toastMessage.link = `${walletModel.etherscanLink}/${txResult}`
|
||||
toastMessage.link = `${walletModel.utilsView.etherscanLink}/${txResult}`
|
||||
toastMessage.open()
|
||||
}
|
||||
onTransactionCompleted: {
|
||||
|
@ -314,7 +314,7 @@ Item {
|
|||
toastMessage.iconColor = Style.current.danger
|
||||
}
|
||||
|
||||
toastMessage.link = `${walletModel.etherscanLink}/${txHash}`
|
||||
toastMessage.link = `${walletModel.utilsView.etherscanLink}/${txHash}`
|
||||
toastMessage.open()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import "../../../shared"
|
|||
import "../../../shared/status"
|
||||
|
||||
ModalPopup {
|
||||
property var currentAccount: walletModel.currentAccount
|
||||
property var currentAccount: walletModel.accountsView.currentAccount
|
||||
property var changeSelectedAccount
|
||||
id: popup
|
||||
// TODO add icon when we have that feature
|
||||
|
@ -138,7 +138,7 @@ ModalPopup {
|
|||
icon: StandardIcon.Warning
|
||||
standardButtons: StandardButton.Yes | StandardButton.No
|
||||
onAccepted: {
|
||||
const error = walletModel.deleteAccount(currentAccount.address);
|
||||
const error = walletModel.accountsView.deleteAccount(currentAccount.address);
|
||||
if (error) {
|
||||
errorSound.play()
|
||||
deleteError.text = error
|
||||
|
@ -178,7 +178,7 @@ ModalPopup {
|
|||
return
|
||||
}
|
||||
|
||||
const error = walletModel.changeAccountSettings(currentAccount.address, accountNameInput.text, accountColorInput.selectedColor);
|
||||
const error = walletModel.accountsView.changeAccountSettings(currentAccount.address, accountNameInput.text, accountColorInput.selectedColor);
|
||||
|
||||
if (error) {
|
||||
errorSound.play()
|
||||
|
|
|
@ -51,7 +51,7 @@ ModalPopup {
|
|||
}
|
||||
|
||||
property var getTokenDetails: Backpressure.debounce(popup, 500, function (tokenAddress){
|
||||
walletModel.customTokenList.getTokenDetails(tokenAddress)
|
||||
walletModel.tokensView.customTokenList.getTokenDetails(tokenAddress)
|
||||
});
|
||||
|
||||
function onKeyReleased(){
|
||||
|
@ -64,7 +64,7 @@ ModalPopup {
|
|||
|
||||
Item {
|
||||
Connections {
|
||||
target: walletModel.customTokenList
|
||||
target: walletModel.tokensView.customTokenList
|
||||
onTokenDetailsWereResolved: {
|
||||
const jsonObj = JSON.parse(tokenDetails)
|
||||
if (jsonObj.error) {
|
||||
|
@ -153,7 +153,7 @@ ModalPopup {
|
|||
enabled: validationError === "" && addressInput.text !== "" && nameInput.text !== "" && symbolInput.text !== "" && decimalsInput.text !== ""
|
||||
|
||||
onClicked : {
|
||||
const error = walletModel.addCustomToken(addressInput.text, nameInput.text, symbolInput.text, decimalsInput.text);
|
||||
const error = walletModel.tokensView.addCustomToken(addressInput.text, nameInput.text, symbolInput.text, decimalsInput.text);
|
||||
|
||||
if (error) {
|
||||
errorSound.play()
|
||||
|
@ -162,7 +162,7 @@ ModalPopup {
|
|||
return
|
||||
}
|
||||
|
||||
walletModel.loadCustomTokens()
|
||||
walletModel.tokensView.loadCustomTokens()
|
||||
popup.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ Item {
|
|||
StyledText {
|
||||
id: assetFiatValue
|
||||
color: Style.current.secondaryText
|
||||
text: Utils.toLocaleString(fiatBalance, globalSettings.locale) + " " + walletModel.defaultCurrency.toUpperCase()
|
||||
text: Utils.toLocaleString(fiatBalance, globalSettings.locale) + " " + walletModel.balanceView.defaultCurrency.toUpperCase()
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 0
|
||||
anchors.bottom: parent.bottom
|
||||
|
@ -93,7 +93,7 @@ Item {
|
|||
spacing: Style.current.padding * 2
|
||||
anchors.fill: parent
|
||||
// model: exampleModel
|
||||
model: walletModel.assets
|
||||
model: walletModel.tokensView.assets
|
||||
delegate: assetViewDelegate
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ Item {
|
|||
|
||||
Repeater {
|
||||
id: collectiblesRepeater
|
||||
model: walletModel.collectiblesLists
|
||||
model: walletModel.collectiblesView.collectiblesLists
|
||||
|
||||
CollectiblesContainer {
|
||||
property var collectibleData: CollectiblesData.collectiblesData[model.collectibleType]
|
||||
|
@ -63,7 +63,7 @@ Item {
|
|||
}
|
||||
|
||||
Connections {
|
||||
target: walletModel.collectiblesLists
|
||||
target: walletModel.collectiblesView.collectiblesLists
|
||||
onDataChanged: {
|
||||
checkCollectiblesVisibility()
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ import "../../../shared/status"
|
|||
Item {
|
||||
property int pageSize: 20 // number of transactions per page
|
||||
property var tokens: {
|
||||
let count = walletModel.defaultTokenList.rowCount()
|
||||
const count = walletModel.tokensView.defaultTokenList.rowCount()
|
||||
const toks = []
|
||||
for (var i = 0; i < count; i++) {
|
||||
toks.push({
|
||||
"address": walletModel.defaultTokenList.rowData(i, 'address'),
|
||||
"symbol": walletModel.defaultTokenList.rowData(i, 'symbol')
|
||||
"address": walletModel.tokensView.defaultTokenList.rowData(i, 'address'),
|
||||
"symbol": walletModel.tokensView.defaultTokenList.rowData(i, 'symbol')
|
||||
})
|
||||
}
|
||||
count = walletModel.customTokenList.rowCount()
|
||||
|
@ -41,6 +41,17 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
// function checkIfHistoryIsBeingFetched() {
|
||||
// loadMoreButton.loadedMore = false;
|
||||
|
||||
// // prevent history from being fetched everytime you click on
|
||||
// // the history tab
|
||||
// if (walletModel.historyView.isHistoryFetched(walletModel.accountsView.currentAccount.account))
|
||||
// return;
|
||||
|
||||
// fetchHistory();
|
||||
// }
|
||||
|
||||
id: root
|
||||
|
||||
Loader {
|
||||
|
@ -58,7 +69,8 @@ Item {
|
|||
}
|
||||
|
||||
Connections {
|
||||
target: walletModel
|
||||
target: walletModel.historyView
|
||||
// onHistoryWasFetched: checkIfHistoryIsBeingFetched()
|
||||
onLoadingTrxHistoryChanged: {
|
||||
if (walletModel.currentAccount.address.toLowerCase() === address.toLowerCase()) {
|
||||
loadingImg.active = isLoading
|
||||
|
@ -73,7 +85,7 @@ Item {
|
|||
id: transactionListItem
|
||||
property bool isHovered: false
|
||||
property string symbol: ""
|
||||
property bool isIncoming: to === walletModel.currentAccount.address
|
||||
property bool isIncoming: to === walletModel.accountsView.currentAccount.address
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
height: 64
|
||||
|
@ -237,7 +249,7 @@ Item {
|
|||
width: parent.width
|
||||
clip: true
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
model: walletModel.transactions
|
||||
model: walletModel.transactionsView.transactions
|
||||
delegate: transactionListItemCmp
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
id: scrollBar
|
||||
|
|
|
@ -9,7 +9,7 @@ import "./components"
|
|||
Rectangle {
|
||||
property int selectedAccount: 0
|
||||
property var changeSelectedAccount: function(newIndex) {
|
||||
if (newIndex > walletModel.accounts) {
|
||||
if (newIndex > walletModel.accountsView.accounts) {
|
||||
return
|
||||
}
|
||||
selectedAccount = newIndex
|
||||
|
@ -43,7 +43,7 @@ Rectangle {
|
|||
StyledTextEdit {
|
||||
id: walletAmountValue
|
||||
color: Style.current.textColor
|
||||
text: Utils.toLocaleString(walletModel.totalFiatBalance, globalSettings.locale) + " " + walletModel.defaultCurrency.toUpperCase()
|
||||
text: Utils.toLocaleString(walletModel.balanceView.totalFiatBalance, globalSettings.locale) + " " + walletModel.balanceView.defaultCurrency.toUpperCase()
|
||||
selectByMouse: true
|
||||
cursorVisible: true
|
||||
readOnly: true
|
||||
|
@ -141,7 +141,7 @@ Rectangle {
|
|||
}
|
||||
StyledText {
|
||||
id: walletBalance
|
||||
text: isLoading ? "..." : Utils.toLocaleString(fiatBalance, globalSettings.locale) + " " + walletModel.defaultCurrency.toUpperCase()
|
||||
text: isLoading ? "..." : Utils.toLocaleString(fiatBalance, globalSettings.locale) + " " + walletModel.balanceView.defaultCurrency.toUpperCase()
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.smallPadding
|
||||
anchors.right: parent.right
|
||||
|
@ -210,7 +210,7 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
model: walletModel.accounts
|
||||
model: walletModel.accountsView.accounts
|
||||
// model: exampleWalletModel
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@ ModalPopup {
|
|||
id: accountSelector
|
||||
label: ""
|
||||
showAccountDetails: false
|
||||
accounts: walletModel.accounts
|
||||
currency: walletModel.defaultCurrency
|
||||
accounts: walletModel.accountsView.accounts
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
anchors.top: qrCodeBox.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
|
|
@ -27,7 +27,7 @@ ModalPopup {
|
|||
|
||||
function sendTransaction() {
|
||||
stack.currentGroup.isPending = true
|
||||
walletModel.sendTransaction(selectFromAccount.selectedAccount.address,
|
||||
walletModel.transactionsView.sendTransaction(selectFromAccount.selectedAccount.address,
|
||||
selectRecipient.selectedRecipient.address,
|
||||
txtAmount.selectedAsset.address,
|
||||
txtAmount.selectedAmount,
|
||||
|
@ -55,15 +55,15 @@ ModalPopup {
|
|||
|
||||
AccountSelector {
|
||||
id: selectFromAccount
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
selectedAccount: {
|
||||
const currAcc = walletModel.currentAccount
|
||||
const currAcc = walletModel.accountsView.currentAccount
|
||||
if (currAcc.walletType !== Constants.watchWalletType) {
|
||||
return currAcc
|
||||
}
|
||||
return null
|
||||
}
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
width: stack.width
|
||||
//% "From account"
|
||||
label: qsTrId("from-account")
|
||||
|
@ -76,7 +76,7 @@ ModalPopup {
|
|||
}
|
||||
RecipientSelector {
|
||||
id: selectRecipient
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
contacts: profileModel.contacts.addedContacts
|
||||
//% "Recipient"
|
||||
label: qsTrId("recipient")
|
||||
|
@ -96,9 +96,9 @@ ModalPopup {
|
|||
AssetAndAmountInput {
|
||||
id: txtAmount
|
||||
selectedAccount: selectFromAccount.selectedAccount
|
||||
defaultCurrency: walletModel.defaultCurrency
|
||||
getFiatValue: walletModel.getFiatValue
|
||||
getCryptoValue: walletModel.getCryptoValue
|
||||
defaultCurrency: walletModel.balanceView.defaultCurrency
|
||||
getFiatValue: walletModel.balanceView.getFiatValue
|
||||
getCryptoValue: walletModel.balanceView.getCryptoValue
|
||||
width: stack.width
|
||||
onSelectedAssetChanged: if (isValid) { gasSelector.estimateGas() }
|
||||
onSelectedAmountChanged: if (isValid) { gasSelector.estimateGas() }
|
||||
|
@ -107,11 +107,11 @@ ModalPopup {
|
|||
id: gasSelector
|
||||
anchors.top: txtAmount.bottom
|
||||
anchors.topMargin: Style.current.bigPadding * 2
|
||||
slowestGasPrice: parseFloat(walletModel.safeLowGasPrice)
|
||||
fastestGasPrice: parseFloat(walletModel.fastestGasPrice)
|
||||
getGasEthValue: walletModel.getGasEthValue
|
||||
getFiatValue: walletModel.getFiatValue
|
||||
defaultCurrency: walletModel.defaultCurrency
|
||||
slowestGasPrice: parseFloat(walletModel.gasView.safeLowGasPrice)
|
||||
fastestGasPrice: parseFloat(walletModel.gasView.fastestGasPrice)
|
||||
getGasEthValue: walletModel.gasView.getGasEthValue
|
||||
getFiatValue: walletModel.balanceView.getFiatValue
|
||||
defaultCurrency: walletModel.balanceView.defaultCurrency
|
||||
width: stack.width
|
||||
property var estimateGas: Backpressure.debounce(gasSelector, 600, function() {
|
||||
if (!(selectFromAccount.selectedAccount && selectFromAccount.selectedAccount.address &&
|
||||
|
@ -119,7 +119,7 @@ ModalPopup {
|
|||
txtAmount.selectedAsset && txtAmount.selectedAsset.address &&
|
||||
txtAmount.selectedAmount)) return
|
||||
|
||||
let gasEstimate = JSON.parse(walletModel.estimateGas(
|
||||
let gasEstimate = JSON.parse(walletModel.gasView.estimateGas(
|
||||
selectFromAccount.selectedAccount.address,
|
||||
selectRecipient.selectedRecipient.address,
|
||||
txtAmount.selectedAsset.address,
|
||||
|
@ -163,7 +163,7 @@ ModalPopup {
|
|||
toAccount: selectRecipient.selectedRecipient
|
||||
asset: txtAmount.selectedAsset
|
||||
amount: { "value": txtAmount.selectedAmount, "fiatValue": txtAmount.selectedFiatAmount }
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
}
|
||||
SendToContractWarning {
|
||||
id: sendToContractWarning
|
||||
|
@ -181,7 +181,7 @@ ModalPopup {
|
|||
TransactionSigner {
|
||||
id: transactionSigner
|
||||
width: stack.width
|
||||
signingPhrase: walletModel.signingPhrase
|
||||
signingPhrase: walletModel.utilsView.signingPhrase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ ModalPopup {
|
|||
}
|
||||
|
||||
Connections {
|
||||
target: walletModel
|
||||
target: walletModel.transactionsView
|
||||
onTransactionWasSent: {
|
||||
try {
|
||||
let response = JSON.parse(txResult)
|
||||
|
@ -245,7 +245,7 @@ ModalPopup {
|
|||
toastMessage.source = "../../img/loading.svg"
|
||||
toastMessage.iconColor = Style.current.primary
|
||||
toastMessage.iconRotates = true
|
||||
toastMessage.link = `${walletModel.etherscanLink}/${response.result}`
|
||||
toastMessage.link = `${walletModel.utilsView.etherscanLink}/${response.result}`
|
||||
toastMessage.open()
|
||||
root.close()
|
||||
} catch (e) {
|
||||
|
@ -264,7 +264,7 @@ ModalPopup {
|
|||
toastMessage.source = "../../img/block-icon.svg"
|
||||
toastMessage.iconColor = Style.current.danger
|
||||
}
|
||||
toastMessage.link = `${walletModel.etherscanLink}/${txHash}`
|
||||
toastMessage.link = `${walletModel.utilsView.etherscanLink}/${txHash}`
|
||||
toastMessage.open()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ ModalPopup {
|
|||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 15
|
||||
text: walletModel.signingPhrase
|
||||
text: walletModel.utilsView.signingPhrase
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import "../../../shared/status"
|
|||
import "./components"
|
||||
|
||||
Item {
|
||||
property var currentAccount: walletModel.currentAccount
|
||||
property var currentAccount: walletModel.accountsView.currentAccount
|
||||
property var changeSelectedAccount
|
||||
|
||||
id: walletHeader
|
||||
|
@ -175,7 +175,7 @@ Item {
|
|||
icon.height: 16
|
||||
onTriggered: {
|
||||
openPopup(tokenSettingsModalComponent)
|
||||
walletModel.loadCustomTokens()
|
||||
walletModel.tokensView.loadCustomTokens()
|
||||
}
|
||||
}
|
||||
Action {
|
||||
|
@ -186,7 +186,7 @@ Item {
|
|||
icon.height: 16
|
||||
onTriggered: {
|
||||
openPopup(setCurrencyModalComponent, {
|
||||
defaultCurrency: walletModel.defaultCurrency
|
||||
defaultCurrency: walletModel.balanceView.defaultCurrency
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ ColumnLayout {
|
|||
onboardingModel.firstTimeLogin = false
|
||||
walletModel.setInitialRange()
|
||||
}
|
||||
walletModel.transactionsView.checkRecentHistory()
|
||||
}
|
||||
|
||||
Timer {
|
||||
|
@ -30,7 +31,7 @@ ColumnLayout {
|
|||
interval: Constants.walletFetchRecentHistoryInterval
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: walletModel.checkRecentHistory()
|
||||
onTriggered: walletModel.transactionsView.checkRecentHistory()
|
||||
}
|
||||
|
||||
SeedPhraseBackupWarning { }
|
||||
|
|
|
@ -127,7 +127,7 @@ ModalPopup {
|
|||
return loading = false
|
||||
}
|
||||
|
||||
const result = walletModel.addAccountsFromPrivateKey(accountPKeyInput.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
|
||||
const result = walletModel.accountsView.addAccountsFromPrivateKey(accountPKeyInput.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
|
||||
|
||||
loading = false
|
||||
if (result) {
|
||||
|
|
|
@ -129,7 +129,7 @@ ModalPopup {
|
|||
return loading = false
|
||||
}
|
||||
|
||||
const result = walletModel.addAccountsFromSeed(seedPhraseTextArea.textArea.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
|
||||
const result = walletModel.accountsView.addAccountsFromSeed(seedPhraseTextArea.textArea.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
|
||||
loading = false
|
||||
if (result) {
|
||||
let resultJson = JSON.parse(result);
|
||||
|
|
|
@ -101,7 +101,7 @@ ModalPopup {
|
|||
return loading = false
|
||||
}
|
||||
|
||||
const error = walletModel.addWatchOnlyAccount(addressInput.text, accountNameInput.text, accountColorInput.selectedColor);
|
||||
const error = walletModel.accountsView.addWatchOnlyAccount(addressInput.text, accountNameInput.text, accountColorInput.selectedColor);
|
||||
loading = false
|
||||
if (error) {
|
||||
errorSound.play()
|
||||
|
|
|
@ -101,7 +101,7 @@ ModalPopup {
|
|||
return loading = false
|
||||
}
|
||||
|
||||
const result = walletModel.generateNewAccount(passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
|
||||
const result = walletModel.accountsView.generateNewAccount(passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
|
||||
loading = false
|
||||
if (result) {
|
||||
let resultJson = JSON.parse(result);
|
||||
|
|
|
@ -59,7 +59,7 @@ Item {
|
|||
anchors.rightMargin: Style.current.padding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
ButtonGroup.group: currencyGroup
|
||||
onClicked: { walletModel.setDefaultCurrency(key) }
|
||||
onClicked: { walletModel.balanceView.setDefaultCurrency(key) }
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
|
@ -75,7 +75,7 @@ Item {
|
|||
onClicked: {
|
||||
currencyRadioBtn.checked = !currencyRadioBtn.checked
|
||||
modalBody.currency = key
|
||||
walletModel.setDefaultCurrency(key)
|
||||
walletModel.balanceView.setDefaultCurrency(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,10 +62,10 @@ Item {
|
|||
}
|
||||
StatusCheckBox {
|
||||
id: assetCheck
|
||||
checked: walletModel.hasAsset(symbol)
|
||||
checked: walletModel.tokensView.hasAsset(symbol)
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.smallPadding
|
||||
onClicked: walletModel.toggleAsset(symbol)
|
||||
onClicked: walletModel.tokensView.toggleAsset(symbol)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ Item {
|
|||
return contextMenu.popup(assetSymbol.x - 100, assetSymbol.y + 25)
|
||||
}
|
||||
assetCheck.checked = !assetCheck.checked
|
||||
walletModel.toggleAsset(symbol)
|
||||
walletModel.tokensView.toggleAsset(symbol)
|
||||
}
|
||||
onEntered: {
|
||||
tokenContainer.hovered = true
|
||||
|
@ -101,7 +101,7 @@ Item {
|
|||
enabled: isCustom
|
||||
//% "Remove token"
|
||||
text: qsTrId("remove-token")
|
||||
onTriggered: walletModel.removeCustomToken(address)
|
||||
onTriggered: walletModel.tokensView.removeCustomToken(address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,14 +142,14 @@ Item {
|
|||
|
||||
Repeater {
|
||||
id: customTokensRepeater
|
||||
model: walletModel.customTokenList
|
||||
model: walletModel.tokensView.customTokenList
|
||||
delegate: tokenComponent
|
||||
anchors.top: customLbl.bottom
|
||||
anchors.topMargin: Style.current.smallPadding
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: walletModel.customTokenList
|
||||
target: walletModel.tokensView.customTokenList
|
||||
onTokensLoaded: {
|
||||
customLbl.visible = cnt > 0
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ Item {
|
|||
}
|
||||
|
||||
Repeater {
|
||||
model: walletModel.defaultTokenList
|
||||
model: walletModel.tokensView.defaultTokenList
|
||||
delegate: tokenComponent
|
||||
anchors.top: defaultLbl.bottom
|
||||
anchors.topMargin: Style.current.smallPadding
|
||||
|
|
|
@ -57,7 +57,7 @@ ScrollView {
|
|||
anchors.top: somethingWentWrongText.bottom
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
onClicked: {
|
||||
walletModel.reloadCollectible(collectibleType)
|
||||
walletModel.collectiblesView.reloadCollectible(collectibleType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,7 +311,7 @@ RowLayout {
|
|||
}
|
||||
sourceComponent: SendModal {
|
||||
onOpened: {
|
||||
walletModel.getGasPricePredictions()
|
||||
walletModel.gasView.getGasPricePredictions()
|
||||
}
|
||||
onClosed: {
|
||||
sendModal.closed()
|
||||
|
|
|
@ -14,7 +14,7 @@ Item {
|
|||
readonly property var validateAsync: Backpressure.debounce(inpAddress, debounceDelay, function (inputValue) {
|
||||
root.isPending = true
|
||||
var name = inputValue.startsWith("@") ? inputValue.substring(1) : inputValue
|
||||
walletModel.resolveENS(name, uuid)
|
||||
walletModel.ensView.resolveENS(name, uuid)
|
||||
});
|
||||
signal resolved(string resolvedAddress)
|
||||
|
||||
|
@ -41,7 +41,7 @@ Item {
|
|||
}
|
||||
|
||||
Connections {
|
||||
target: walletModel
|
||||
target: walletModel.ensView
|
||||
onEnsWasResolved: {
|
||||
if (uuid !== root.uuid) {
|
||||
return
|
||||
|
|
|
@ -21,7 +21,7 @@ Item {
|
|||
return root.isValid
|
||||
}
|
||||
txtValidationError.text = ""
|
||||
if (walletModel.isKnownTokenContract(selectedRecipient.address)) {
|
||||
if (walletModel.tokensView.isKnownTokenContract(selectedRecipient.address)) {
|
||||
// do not set isValid = false here because it would make the
|
||||
// TransactionStackGroup invalid and therefore not let the user
|
||||
// continue in the modal
|
||||
|
|
|
@ -14,7 +14,7 @@ ModalPopup {
|
|||
property bool showBackBtn: false
|
||||
|
||||
Component.onCompleted: {
|
||||
walletModel.getGasPricePredictions()
|
||||
walletModel.gasView.getGasPricePredictions()
|
||||
}
|
||||
|
||||
//% "Authorize %1 %2"
|
||||
|
@ -72,15 +72,15 @@ ModalPopup {
|
|||
|
||||
AccountSelector {
|
||||
id: selectFromAccount
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
selectedAccount: {
|
||||
const currAcc = walletModel.currentAccount
|
||||
const currAcc = walletModel.accountsView.currentAccount
|
||||
if (currAcc.walletType !== Constants.watchWalletType) {
|
||||
return currAcc
|
||||
}
|
||||
return null
|
||||
}
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
width: stack.width
|
||||
//% "Choose account"
|
||||
label: qsTrId("choose-account")
|
||||
|
@ -91,7 +91,7 @@ ModalPopup {
|
|||
RecipientSelector {
|
||||
id: selectRecipient
|
||||
visible: false
|
||||
accounts: walletModel.accounts
|
||||
accounts: walletModel.accountsView.accounts
|
||||
contacts: profileModel.contacts.addedContacts
|
||||
selectedRecipient: { "address": utilsModel.stickerMarketAddress, "type": RecipientSelector.Type.Address }
|
||||
readOnly: true
|
||||
|
@ -100,11 +100,11 @@ ModalPopup {
|
|||
GasSelector {
|
||||
id: gasSelector
|
||||
visible: false
|
||||
slowestGasPrice: parseFloat(walletModel.safeLowGasPrice)
|
||||
fastestGasPrice: parseFloat(walletModel.fastestGasPrice)
|
||||
getGasEthValue: walletModel.getGasEthValue
|
||||
getFiatValue: walletModel.getFiatValue
|
||||
defaultCurrency: walletModel.defaultCurrency
|
||||
slowestGasPrice: parseFloat(walletModel.gasView.safeLowGasPrice)
|
||||
fastestGasPrice: parseFloat(walletModel.gasView.fastestGasPrice)
|
||||
getGasEthValue: walletModel.gasView.getGasEthValue
|
||||
getFiatValue: walletModel.balanceView.getFiatValue
|
||||
defaultCurrency: walletModel.balanceView.defaultCurrency
|
||||
property var estimateGas: Backpressure.debounce(gasSelector, 600, function() {
|
||||
if (!(root.stickerPackId > -1 && selectFromAccount.selectedAccount && root.packPrice && parseFloat(root.packPrice) > 0)) {
|
||||
selectedGasLimit = 325000
|
||||
|
@ -153,9 +153,9 @@ ModalPopup {
|
|||
}
|
||||
toAccount: selectRecipient.selectedRecipient
|
||||
asset: root.asset
|
||||
currency: walletModel.defaultCurrency
|
||||
currency: walletModel.balanceView.defaultCurrency
|
||||
amount: {
|
||||
const fiatValue = walletModel.getFiatValue(root.packPrice || 0, root.asset.symbol, currency)
|
||||
const fiatValue = walletModel.balanceView.getFiatValue(root.packPrice || 0, root.asset.symbol, currency)
|
||||
return { "value": root.packPrice, "fiatValue": fiatValue }
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ ModalPopup {
|
|||
TransactionSigner {
|
||||
id: transactionSigner
|
||||
width: stack.width
|
||||
signingPhrase: walletModel.signingPhrase
|
||||
signingPhrase: walletModel.utilsView.signingPhrase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ ModalPopup {
|
|||
toastMessage.source = "../../../img/loading.svg"
|
||||
toastMessage.iconColor = Style.current.primary
|
||||
toastMessage.iconRotates = true
|
||||
toastMessage.link = `${walletModel.etherscanLink}/${txResult}`
|
||||
toastMessage.link = `${walletModel.utilsView.etherscanLink}/${txResult}`
|
||||
toastMessage.open()
|
||||
}
|
||||
onTransactionCompleted: {
|
||||
|
@ -238,7 +238,7 @@ ModalPopup {
|
|||
toastMessage.iconColor = Style.current.danger
|
||||
}
|
||||
|
||||
toastMessage.link = `${walletModel.etherscanLink}/${txHash}`
|
||||
toastMessage.link = `${walletModel.utilsView.etherscanLink}/${txHash}`
|
||||
toastMessage.open()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue