status-desktop/ui/app/AppLayouts/Wallet/stores/RootStore.qml

389 lines
12 KiB
QML

pragma Singleton
import QtQuick 2.13
import utils 1.0
import SortFilterProxyModel 0.2
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as SQUtils
QtObject {
id: root
readonly property TokensStore tokensStore: TokensStore {}
readonly property string defaultSelectedKeyUid: userProfile.keyUid
readonly property bool defaultSelectedKeyUidMigratedToKeycard: userProfile.isKeycardUser
property string backButtonName: ""
property var overview: walletSectionOverview
property var assets: walletSectionAssets.assets
property bool assetsLoading: walletSectionAssets.assetsLoading
property var accounts: walletSectionAccounts.accounts
property var receiveAccounts: walletSectionSend.accounts
property var selectedReceiveAccount: walletSectionSend.selectedReceiveAccount
property var appSettings: localAppSettings
property var accountSensitiveSettings: localAccountSensitiveSettings
property bool hideSignPhraseModal: accountSensitiveSettings.hideSignPhraseModal
property var walletSectionInst: walletSection
property var totalCurrencyBalance: walletSection.totalCurrencyBalance
property var activityController: walletSection.activityController
property var tmpActivityController: walletSection.tmpActivityController
property string signingPhrase: walletSection.signingPhrase
property string mnemonicBackedUp: walletSection.isMnemonicBackedUp
property CollectiblesStore collectiblesStore: CollectiblesStore {}
property var areTestNetworksEnabled: networksModule.areTestNetworksEnabled
property var savedAddresses: SortFilterProxyModel {
sourceModel: walletSectionSavedAddresses.model
filters: [
ValueFilter {
roleName: "isTest"
value: networksModule.areTestNetworksEnabled
}
]
}
property var nonWatchAccounts: SortFilterProxyModel {
sourceModel: receiveAccounts
proxyRoles: [
ExpressionRole {
name: "color"
function getColor(colorId) {
return Utils.getColorForId(colorId)
}
// Direct call for singleton function is not handled properly by
// SortFilterProxyModel that's why helper function is used instead.
expression: { return getColor(model.colorId) }
}
]
filters: ValueFilter {
roleName: "walletType"
value: Constants.watchWalletType
inverted: true
}
}
readonly property var currentActivityFiltersStore: {
const address = root.overview.mixedcaseAddress
if (address in d.activityFiltersStoreDictionary) {
return d.activityFiltersStoreDictionary[address]
}
let store = d.activityFilterStoreComponent.createObject(root)
d.activityFiltersStoreDictionary[address] = store
return store
}
property QtObject _d: QtObject {
id: d
property var activityFiltersStoreDictionary: ({})
readonly property Component activityFilterStoreComponent: ActivityFiltersStore{}
property var chainColors: ({})
function initChainColors(model) {
for (let i = 0; i < model.count; i++) {
chainColors[model.rowData(i, "shortName")] = model.rowData(i, "chainColor")
}
}
readonly property Connections walletSectionConnections: Connections {
target: root.walletSectionInst
function onWalletAccountRemoved(address) {
address = address.toLowerCase();
for (var addressKey in d.activityFiltersStoreDictionary){
if (address === addressKey.toLowerCase()){
delete d.activityFiltersStoreDictionary[addressKey]
return
}
}
}
}
}
function colorForChainShortName(chainShortName) {
return d.chainColors[chainShortName]
}
property var layer1Networks: networksModule.layer1
property var layer2Networks: networksModule.layer2
property var enabledNetworks: networksModule.enabled
property var allNetworks: networksModule.all
onAllNetworksChanged: {
d.initChainColors(allNetworks)
}
property var cryptoRampServicesModel: walletSectionBuySellCrypto.model
function resetCurrentViewedHolding() {
currentViewedHoldingID = ""
currentViewedHoldingType = Constants.HoldingType.Unknown
}
function setCurrentViewedHoldingType(type) {
currentViewedHoldingID = ""
currentViewedHoldingType = type
}
function setCurrentViewedHolding(id, type) {
currentViewedHoldingID = id
currentViewedHoldingType = type
}
property string currentViewedHoldingID: ""
property int currentViewedHoldingType
readonly property var currentViewedCollectible: collectiblesStore.detailedCollectible
// This should be exposed to the UI via "walletModule", WalletModule should use
// Accounts Service which keeps the info about that (isFirstTimeAccountLogin).
// Then in the View of WalletModule we may have either QtProperty or
// Q_INVOKABLE function (proc marked as slot) depends on logic/need.
// The only need for onboardingModel here is actually to check if an account
// has been just created or an old one.
//property bool firstTimeLogin: onboardingModel.isFirstTimeLogin
// example wallet model
property ListModel exampleWalletModel: ListModel {
ListElement {
name: "Status account"
address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f"
balance: "12.00 USD"
color: "#7CDA00"
}
ListElement {
name: "Test account 1"
address: "0x2Ef1...E0Ba"
balance: "12.00 USD"
color: "#FA6565"
}
ListElement {
name: "Status account"
address: "0x2Ef1...E0Ba"
balance: "12.00 USD"
color: "#7CDA00"
}
}
property ListModel exampleAssetModel: ListModel {
ListElement {
name: "Ethereum"
symbol: "ETH"
balance: "3423 ETH"
address: "token-icons/eth"
currencyBalance: "123 USD"
}
}
function setHideSignPhraseModal(value) {
localAccountSensitiveSettings.hideSignPhraseModal = value;
}
function getLatestBlockNumber(chainId) {
// NOTE returns hex
return walletSection.getLatestBlockNumber(chainId)
}
function getEstimatedLatestBlockNumber(chainId) {
// NOTE returns decimal
return walletSection.getEstimatedLatestBlockNumber(chainId)
}
function setFilterAddress(address) {
walletSection.setFilterAddress(address)
}
function setFillterAllAddresses() {
walletSection.setFillterAllAddresses()
}
function deleteAccount(address) {
return walletSectionAccounts.deleteAccount(address)
}
function updateCurrentAccount(address, accountName, colorId, emoji) {
return walletSectionAccounts.updateAccount(address, accountName, colorId, emoji)
}
function updateCurrency(newCurrency) {
walletSection.updateCurrency(newCurrency)
}
function getQrCode(address) {
return globalUtils.qrCode(address)
}
function hex2Dec(value) {
return globalUtils.hex2Dec(value)
}
function getNameForSavedWalletAddress(address) {
return walletSectionSavedAddresses.getNameByAddress(address)
}
function getNameForWalletAddress(address) {
return walletSectionAccounts.getNameByAddress(address)
}
function getNameForAddress(address) {
var name = getNameForWalletAddress(address)
if (name.length === 0) {
name = getNameForSavedWalletAddress(address)
}
return name
}
enum LookupType {
Account = 0,
SavedAddress = 1
}
// Returns object of type {type: null, object: null} or null if lookup didn't find anything
function lookupAddressObject(address) {
let res = null
let acc = SQUtils.ModelUtils.getByKey(root.accounts, "address", address)
if (acc) {
res = {type: RootStore.LookupType.Account, object: acc}
} else {
let sa = SQUtils.ModelUtils.getByKey(walletSectionSavedAddresses.model, "address", address)
if (sa) {
res = {type: RootStore.LookupType.SavedAddress, object: sa}
}
}
return res
}
function getAssetForSendTx(tx) {
if (tx.isNFT) {
return {
uid: tx.tokenID,
chainId: tx.chainId,
name: tx.nftName,
imageUrl: tx.nftImageUrl,
collectionUid: "",
collectionName: ""
}
} else {
return tx.symbol
}
}
function isTxRepeatable(tx) {
if (!tx || tx.txType !== Constants.TransactionType.Send)
return false
let res = root.lookupAddressObject(tx.sender)
if (!res || res.type !== RootStore.LookupType.Account || res.object.walletType == Constants.watchWalletType)
return false
if (tx.isNFT) {
// TODO #12275: check if account owns enough NFT
} else {
// TODO #12275: Check if account owns enough tokens
}
return true
}
function isOwnedAccount(address) {
return walletSectionAccounts.isOwnedAccount(address)
}
function getEmojiForWalletAddress(address) {
return walletSectionAccounts.getEmojiByAddress(address)
}
function getColorForWalletAddress(address) {
return walletSectionAccounts.getColorByAddress(address)
}
function createOrUpdateSavedAddress(name, address, favourite, chainShortNames, ens) {
return walletSectionSavedAddresses.createOrUpdateSavedAddress(name, address, favourite, chainShortNames, ens)
}
function deleteSavedAddress(address, ens) {
return walletSectionSavedAddresses.deleteSavedAddress(address, ens)
}
function toggleNetwork(chainId) {
networksModule.toggleNetwork(chainId)
}
function copyToClipboard(text) {
globalUtils.copyToClipboard(text)
}
function runAddAccountPopup() {
walletSection.runAddAccountPopup(false)
}
function runAddWatchOnlyAccountPopup() {
walletSection.runAddAccountPopup(true)
}
function runEditAccountPopup(address) {
walletSection.runEditAccountPopup(address)
}
function switchReceiveAccount(index) {
walletSectionSend.switchReceiveAccount(index)
}
function toggleWatchOnlyAccounts() {
walletSection.toggleWatchOnlyAccounts()
}
function getAllNetworksChainIds() {
return networksModule.getAllNetworksChainIds()
}
function getNetworkShortNames(chainIds) {
return networksModule.getNetworkShortNames(chainIds)
}
function updateWalletAccountPreferredChains(address, preferredChainIds) {
if(areTestNetworksEnabled) {
walletSectionAccounts.updateWalletAccountTestPreferredChains(address, preferredChainIds)
}
else {
walletSectionAccounts.updateWalletAccountProdPreferredChains(address, preferredChainIds)
}
}
function processPreferredSharingNetworkToggle(preferredSharingNetworks, toggledNetwork) {
let prefChains = preferredSharingNetworks
if(prefChains.length === allNetworks.count) {
prefChains = [toggledNetwork.chainId.toString()]
}
else if(!prefChains.includes(toggledNetwork.chainId.toString())) {
prefChains.push(toggledNetwork.chainId.toString())
}
else {
if(prefChains.length === 1) {
prefChains = getAllNetworksChainIds().split(":")
}
else {
for(var i = 0; i < prefChains.length;i++) {
if(prefChains[i] === toggledNetwork.chainId.toString()) {
prefChains.splice(i, 1)
}
}
}
}
return prefChains
}
function updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance) {
walletSectionAccounts.updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance)
}
}