status-desktop/ui/imports/shared/stores/send/TransactionStore.qml

378 lines
13 KiB
QML
Raw Normal View History

import QtQuick 2.13
import SortFilterProxyModel 0.2
import shared.stores 1.0
import utils 1.0
import StatusQ 0.1
import StatusQ.Core.Utils 0.1
import AppLayouts.Wallet.stores 1.0
QtObject {
id: root
property CurrenciesStore currencyStore: CurrenciesStore {}
property WalletAssetsStore walletAssetStore
property TokensStore tokensStore
property var mainModuleInst: mainModule
property var walletSectionSendInst: walletSectionSend
property var fromNetworksModel: walletSectionSendInst.fromNetworksModel
property var toNetworksModel: walletSectionSendInst.toNetworksModel
property var flatNetworksModel: networksModule.flatNetworks
property var senderAccounts: walletSectionSendInst.senderAccounts
property var selectedSenderAccount: walletSectionSendInst.selectedSenderAccount
property var accounts: walletSectionSendInst.accounts
property var collectiblesModel: walletSectionSendInst.collectiblesModel
property var nestedCollectiblesModel: walletSectionSendInst.nestedCollectiblesModel
property bool areTestNetworksEnabled: networksModule.areTestNetworksEnabled
property var tmpActivityController0: walletSection.tmpActivityController0
property var tmpActivityController1: walletSection.tmpActivityController1
property var savedAddressesModel: SortFilterProxyModel {
sourceModel: walletSectionSavedAddresses.model
filters: [
ValueFilter {
roleName: "isTest"
value: areTestNetworksEnabled
}
]
}
property string selectedAssetKey: walletSectionSendInst.selectedAssetKey
property bool showUnPreferredChains: walletSectionSendInst.showUnPreferredChains
property int sendType: walletSectionSendInst.sendType
property string selectedRecipient: walletSectionSendInst.selectedRecipient
function setSendType(sendType) {
walletSectionSendInst.setSendType(sendType)
}
function setSelectedRecipient(recipientAddress) {
walletSectionSendInst.setSelectedRecipient(recipientAddress)
}
function getEtherscanLink(chainID) {
return networksModule.getBlockExplorerURL(chainID)
}
function copyToClipboard(text) {
globalUtils.copyToClipboard(text)
}
function authenticateAndTransfer(uuid) {
walletSectionSendInst.authenticateAndTransfer(uuid)
}
function suggestedRoutes(amount) {
const value = AmountsArithmetic.fromNumber(amount)
walletSectionSendInst.suggestedRoutes(value.toFixed())
}
function resolveENS(value) {
mainModuleInst.resolveENS(value, "")
}
function getWei2Eth(wei, decimals) {
return globalUtils.wei2Eth(wei, decimals)
}
function plainText(text) {
return globalUtils.plainText(text)
}
enum EstimatedTime {
Unknown = 0,
LessThanOneMin,
LessThanThreeMins,
LessThanFiveMins,
MoreThanFiveMins
}
function getLabelForEstimatedTxTime(estimatedFlag) {
switch(estimatedFlag) {
case TransactionStore.EstimatedTime.Unknown:
return qsTr("~ Unknown")
case TransactionStore.EstimatedTime.LessThanOneMin :
return qsTr("< 1 minute")
case TransactionStore.EstimatedTime.LessThanThreeMins :
return qsTr("< 3 minutes")
case TransactionStore.EstimatedTime.LessThanFiveMins:
return qsTr("< 5 minutes")
default:
return qsTr("> 5 minutes")
}
}
function getAsset(assetsList, symbol) {
for(var i=0; i< assetsList.rowCount();i++) {
let asset = assetsList.get(i)
if(symbol === asset.symbol) {
return asset
}
}
return {}
}
function getCollectible(uid) {
const idx = ModelUtils.indexOf(collectiblesModel, "uid", uid)
if (idx < 0) {
return {}
}
return ModelUtils.get(collectiblesModel, idx)
}
function getSelectorCollectible(uid) {
const idx = ModelUtils.indexOf(nestedCollectiblesModel, "uid", uid)
if (idx < 0) {
return {}
}
return ModelUtils.get(nestedCollectiblesModel, idx)
}
function getHolding(holdingId, holdingType) {
if (holdingType === Constants.TokenType.ERC20) {
return getAsset(processedAssetsModel, holdingId)
} else if (holdingType === Constants.TokenType.ERC721 || holdingType === Constants.TokenType.ERC1155) {
return getCollectible(holdingId)
} else {
return {}
}
}
function getSelectorHolding(holdingId, holdingType) {
if (holdingType === Constants.TokenType.ERC20) {
return getAsset(processedAssetsModel, holdingId)
} else if (holdingType === Constants.TokenType.ERC721 || holdingType === Constants.TokenType.ERC1155) {
return getSelectorCollectible(holdingId)
} else {
return {}
}
}
function assetToSelectorAsset(asset) {
return asset
}
function collectibleToSelectorCollectible(collectible) {
var groupId = collectible.collectionUid
var groupName = collectible.collectionName
var itemType = Constants.CollectiblesNestedItemType.Collectible
if (collectible.communityId !== "") {
groupId = collectible.communityId
groupName = collectible.communityName
itemType = Constants.CollectiblesNestedItemType.CommunityCollectible
}
return {
uid: collectible.uid,
chainId: collectible.chainId,
name: collectible.name,
iconUrl: collectible.imageUrl,
groupId: groupId,
groupName: groupName,
tokenType: collectible.tokenType,
itemType: itemType,
count: 1 // TODO: Properly handle count
}
}
function holdingToSelectorHolding(holding, holdingType) {
if (holdingType === Constants.TokenType.ERC20) {
return assetToSelectorAsset(holding)
} else if (holdingType === Constants.TokenType.ERC721 || holdingType === Constants.TokenType.ERC1155) {
return collectibleToSelectorCollectible(holding)
} else {
return {}
}
}
function switchSenderAccount(index) {
walletSectionSendInst.switchSenderAccount(index)
}
function getNetworkShortNames(chainIds) {
return networksModule.getNetworkShortNames(chainIds)
}
function toggleFromDisabledChains(chainId) {
fromNetworksModel.toggleRouteDisabledChains(chainId)
}
function toggleToDisabledChains(chainId) {
toNetworksModel.toggleRouteDisabledChains(chainId)
}
function setRouteDisabledChains(chainId, disabled) {
toNetworksModel.setRouteDisabledChains(chainId, disabled)
}
function setSelectedTokenName(tokenName) {
walletSectionSendInst.setSelectedTokenName(tokenName)
}
function setSelectedTokenIsOwnerToken(isOwnerToken) {
walletSectionSendInst.setSelectedTokenIsOwnerToken(isOwnerToken)
}
function setRouteEnabledFromChains(chainId) {
fromNetworksModel.setRouteEnabledFromChains(chainId)
}
function setSelectedAssetKey(assetsKey) {
walletSectionSendInst.setSelectedAssetKey(assetsKey)
}
function getNetworkName(chainId) {
return fromNetworksModel.getNetworkName(chainId)
}
function updateRoutePreferredChains(chainIds) {
walletSectionSendInst.updateRoutePreferredChains(chainIds)
}
function toggleShowUnPreferredChains() {
walletSectionSendInst.toggleShowUnPreferredChains()
}
function setAllNetworksAsRoutePreferredChains() {
toNetworksModel.setAllNetworksAsRoutePreferredChains()
}
function lockCard(chainId, amount, lock) {
fromNetworksModel.lockCard(chainId, amount, lock)
}
function resetStoredProperties() {
assetSearchString = ""
walletSectionSendInst.resetStoredProperties()
nestedCollectiblesModel.currentCollectionUid = ""
}
function splitAndFormatAddressPrefix(text, updateInStore) {
return {
formattedText: walletSectionSendInst.splitAndFormatAddressPrefix(text, updateInStore),
address: walletSectionSendInst.getAddressFromFormattedString(text)
}
}
function getShortChainIds(chainShortNames) {
return walletSectionSendInst.getShortChainIds(chainShortNames)
}
function formatCurrencyAmountFromBigInt(balance, symbol, decimals) {
let bigIntBalance = AmountsArithmetic.fromString(balance)
let decimalBalance = AmountsArithmetic.toNumber(bigIntBalance, decimals)
return currencyStore.formatCurrencyAmount(decimalBalance, symbol)
}
// Property set from TokenLIstView and HoldingSelector to search token by name, symbol or contract address
property string assetSearchString
// Internal model filtering balances by the account selected on the SendModalPage
property SubmodelProxyModel __assetsWithFilteredBalances: SubmodelProxyModel {
sourceModel: walletAssetStore.groupedAccountAssetsModel
submodelRoleName: "balances"
delegateModel: SortFilterProxyModel {
sourceModel: submodel
filters: FastExpressionFilter {
expression: root.selectedSenderAccount.address === model.account
expectedRoles: ["account"]
}
}
}
readonly property Connections tokensStoreConnections: Connections {
target: tokensStore
function onDisplayAssetsBelowBalanceThresholdChanged() {
processedAssetsModel.displayAssetsBelowBalanceThresholdAmount = tokensStore.getDisplayAssetsBelowBalanceThresholdDisplayAmount()
}
}
// Model prepared to provide filtered and sorted assets as per the advanced Settings in token management
property var processedAssetsModel: SortFilterProxyModel {
property real displayAssetsBelowBalanceThresholdAmount: tokensStore.getDisplayAssetsBelowBalanceThresholdDisplayAmount()
sourceModel: __assetsWithFilteredBalances
proxyRoles: [
FastExpressionRole {
name: "isCommunityAsset"
expression: !!model.communityId
expectedRoles: ["communityId"]
},
FastExpressionRole {
name: "currentBalance"
expression: __getTotalBalance(model.balances, model.decimals, root.selectedSenderAccount)
expectedRoles: ["balances", "decimals"]
},
FastExpressionRole {
name: "currentCurrencyBalance"
expression: {
if (!!model.marketDetails) {
return model.currentBalance * model.marketDetails.currencyPrice.amount
}
return 0
}
expectedRoles: ["marketDetails", "currentBalance"]
}
]
filters: [
FastExpressionFilter {
function search(symbol, name, addressPerChain, searchString) {
return (
symbol.toUpperCase().startsWith(searchString.toUpperCase()) ||
name.toUpperCase().startsWith(searchString.toUpperCase()) || __searchAddressInList(addressPerChain, searchString)
)
}
expression: search(symbol, name, addressPerChain, assetSearchString)
expectedRoles: ["symbol", "name", "addressPerChain"]
},
ValueFilter {
roleName: "isCommunityAsset"
value: false
enabled: !tokensStore.showCommunityAssetsInSend
},
FastExpressionFilter {
expression: {
root.walletAssetStore.assetsController.revision
if (!root.walletAssetStore.assetsController.filterAcceptsSymbol(model.symbol)) // explicitely hidden
return false
if (model.isCommunityAsset)
return true
if (tokensStore.displayAssetsBelowBalance)
return model.currentCurrencyBalance > processedAssetsModel.displayAssetsBelowBalanceThresholdAmount
return true
}
expectedRoles: ["symbol", "isCommunityAsset", "currentCurrencyBalance"]
}
]
sorters: RoleSorter {
roleName: "isCommunityAsset"
}
}
/* Internal function to search token address */
function __searchAddressInList(addressPerChain, searchString) {
let addressFound = false
let tokenAddresses = ModelUtils.modelToFlatArray(addressPerChain, "address")
for (let i =0; i< tokenAddresses.length; i++){
if(tokenAddresses[i].toUpperCase().startsWith(searchString.toUpperCase())) {
addressFound = true
break;
}
}
return addressFound
}
/* Internal function to calculate total balance */
function __getTotalBalance(balances, decimals) {
let totalBalance = 0
for(let i=0; i<balances.count; i++) {
let balancePerAddressPerChain = ModelUtils.get(balances, i)
totalBalance+=AmountsArithmetic.toNumber(balancePerAddressPerChain.balance, decimals)
}
return totalBalance
}
}