feat(@desktop/wallet): Handle missing token metadata (#11433)

closes #11043
This commit is contained in:
Cuteivist 2023-07-18 16:05:22 +02:00 committed by GitHub
parent 3ea5464c33
commit a30678f5ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 16 deletions

View File

@ -197,6 +197,15 @@ QtObject:
QtProperty[QVariant] totalFees: QtProperty[QVariant] totalFees:
read = getTotalFees read = getTotalFees
proc getMaxTotalFees*(self: ActivityEntry): QVariant {.slot.} =
if self.transaction == nil:
error "getMaxTotalFees: ActivityEntry is not an transaction.Item"
return newQVariant(newCurrencyAmount())
return newQVariant(self.transaction[].getMaxTotalFees())
QtProperty[QVariant] maxTotalFees:
read = getMaxTotalFees
proc getInput*(self: ActivityEntry): string {.slot.} = proc getInput*(self: ActivityEntry): string {.slot.} =
if self.transaction == nil: if self.transaction == nil:
error "getInput: ActivityEntry is not an transaction.Item" error "getInput: ActivityEntry is not an transaction.Item"

View File

@ -56,6 +56,8 @@ proc getResolvedSymbol*(self: Module, transaction: TransactionDto): string =
let contractSymbol = self.controller.findTokenSymbolByAddress(transaction.contract) let contractSymbol = self.controller.findTokenSymbolByAddress(transaction.contract)
if contractSymbol != "": if contractSymbol != "":
result = contractSymbol result = contractSymbol
elif transaction.typeValue == "erc20":
result = ""
else: else:
result = "ETH" result = "ETH"

View File

@ -51,12 +51,30 @@ Item {
readonly property string inSymbol: isTransactionValid ? transaction.inSymbol : "" readonly property string inSymbol: isTransactionValid ? transaction.inSymbol : ""
readonly property string outSymbol: isTransactionValid ? transaction.outSymbol : "" readonly property string outSymbol: isTransactionValid ? transaction.outSymbol : ""
readonly property var multichainNetworks: [] // TODO fill icon for networks for multichain readonly property var multichainNetworks: [] // TODO fill icon for networks for multichain
readonly property string fiatValueFormatted: root.isTransactionValid && !transactionHeader.isMultiTransaction ? RootStore.formatCurrencyAmount(transactionHeader.fiatValue, RootStore.currentCurrency) : "" readonly property string fiatValueFormatted: {
readonly property string cryptoValueFormatted: root.isTransactionValid && !transactionHeader.isMultiTransaction ? RootStore.formatCurrencyAmount(transaction.amount, transaction.symbol) : "" if (!root.isTransactionValid || transactionHeader.isMultiTransaction || !symbol)
readonly property string outFiatValueFormatted: root.isTransactionValid && transactionHeader.isMultiTransaction ? RootStore.formatCurrencyAmount(transactionHeader.outFiatValue, RootStore.currentCurrency) : "" return ""
readonly property string outCryptoValueFormatted: root.isTransactionValid && transactionHeader.isMultiTransaction ? RootStore.formatCurrencyAmount(transaction.outAmount, transaction.outSymbol) : "" return RootStore.formatCurrencyAmount(transactionHeader.fiatValue, RootStore.currentCurrency)
}
readonly property string cryptoValueFormatted: {
if (!root.isTransactionValid || transactionHeader.isMultiTransaction)
return ""
const formatted = RootStore.formatCurrencyAmount(transaction.amount, transaction.symbol)
return symbol || !transaction.contract ? formatted : "%1 (%2)".arg(formatted).arg(Utils.compactAddress(transaction.contract, 4))
}
readonly property string outFiatValueFormatted: {
if (!root.isTransactionValid || !transactionHeader.isMultiTransaction || !outSymbol)
return ""
return RootStore.formatCurrencyAmount(transactionHeader.outFiatValue, RootStore.currentCurrency)
}
readonly property string outCryptoValueFormatted: {
if (!root.isTransactionValid || !transactionHeader.isMultiTransaction)
return ""
const formatted = RootStore.formatCurrencyAmount(transaction.outAmount, transaction.outSymbol)
return outSymbol || !transaction.contract ? formatted : "%1 (%2)".arg(formatted).arg(Utils.compactAddress(transaction.contract, 4))
}
readonly property real feeEthValue: root.isTransactionValid ? RootStore.getGasEthValue(transaction.totalFees.amount, 1) : 0 // TODO use directly? readonly property real feeEthValue: root.isTransactionValid ? RootStore.getGasEthValue(transaction.totalFees.amount, 1) : 0 // TODO use directly?
readonly property real feeFiatValue: root.isTransactionValid ? RootStore.getFiatValue(d.feeEthValue, "ETH", RootStore.currentCurrency) : 0 // TODO use directly? readonly property real feeFiatValue: root.isTransactionValid ? RootStore.getFiatValue(d.feeEthValue, Constants.ethToken, RootStore.currentCurrency) : 0 // TODO use directly?
readonly property int transactionType: root.isTransactionValid ? transaction.txType : Constants.TransactionType.Send readonly property int transactionType: root.isTransactionValid ? transaction.txType : Constants.TransactionType.Send
readonly property string toNetworkName: "" // TODO fill network name for bridge readonly property string toNetworkName: "" // TODO fill network name for bridge
@ -294,7 +312,11 @@ Item {
TransactionContractTile { TransactionContractTile {
// Used to display contract address for any network // Used to display contract address for any network
address: root.isTransactionValid ? transaction.contract : "" address: root.isTransactionValid ? transaction.contract : ""
symbol: root.isTransactionValid ? d.symbol : "" symbol: {
if (!root.isTransactionValid)
return ""
return d.symbol ? d.symbol : "(%1)".arg(Utils.compactAddress(transaction.contract, 4))
}
networkName: transactionHeader.networkName networkName: transactionHeader.networkName
shortNetworkName: d.networkShortName shortNetworkName: d.networkShortName
} }
@ -553,10 +575,15 @@ Item {
} }
TransactionDataTile { TransactionDataTile {
width: parent.width width: parent.width
title: qsTr("Fees") title: d.symbol ? qsTr("Fees") : qsTr("Estimated max fee")
subTitle: { subTitle: {
if (!root.isTransactionValid || transactionHeader.isNFT) if (!root.isTransactionValid || transactionHeader.isNFT)
return "" return ""
if (!d.symbol) {
const maxFeeEth = RootStore.getGasEthValue(transaction.maxTotalFees.amount, 1)
return RootStore.formatCurrencyAmount(maxFeeEth, Constants.ethToken)
}
switch(d.transactionType) { switch(d.transactionType) {
case Constants.TransactionType.Send: case Constants.TransactionType.Send:
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
@ -566,7 +593,18 @@ Item {
return "" return ""
} }
} }
tertiaryTitle: !!subTitle ? RootStore.formatCurrencyAmount(d.feeFiatValue, RootStore.currentCurrency) : "" tertiaryTitle: {
if (!subTitle)
return ""
let fiatValue
if (!d.symbol) {
const maxFeeEth = RootStore.getGasEthValue(transaction.maxTotalFees.amount, 1)
fiatValue = RootStore.getFiatValue(maxFeeEth, Constants.ethToken, RootStore.currentCurrency)
} else {
fiatValue = d.feeFiatValue
}
return RootStore.formatCurrencyAmount(fiatValue, RootStore.currentCurrency)
}
visible: !!subTitle visible: !!subTitle
} }
TransactionDataTile { TransactionDataTile {
@ -574,19 +612,19 @@ Item {
// Using fees in this tile because of same higlight and color settings as Total // Using fees in this tile because of same higlight and color settings as Total
title: d.transactionType === Constants.TransactionType.Destroy || transactionHeader.isNFT ? qsTr("Fees") : qsTr("Total") title: d.transactionType === Constants.TransactionType.Destroy || transactionHeader.isNFT ? qsTr("Fees") : qsTr("Total")
subTitle: { subTitle: {
if (transactionHeader.isNFT && d.isIncoming) if ((transactionHeader.isNFT && d.isIncoming) || !d.symbol)
return "" return ""
const type = d.transactionType const type = d.transactionType
if (type === Constants.TransactionType.Destroy || transactionHeader.isNFT) { if (type === Constants.TransactionType.Destroy || transactionHeader.isNFT) {
return RootStore.formatCurrencyAmount(d.feeEthValue, "ETH") return RootStore.formatCurrencyAmount(d.feeEthValue, Constants.ethToken)
} else if (type === Constants.TransactionType.Receive || (type === Constants.TransactionType.Buy && progressBlock.isLayer1)) { } else if (type === Constants.TransactionType.Receive || (type === Constants.TransactionType.Buy && progressBlock.isLayer1)) {
return d.cryptoValueFormatted return d.cryptoValueFormatted
} }
const cryptoValue = transactionHeader.isMultiTransaction ? d.outCryptoValueFormatted : d.cryptoValueFormatted const cryptoValue = transactionHeader.isMultiTransaction ? d.outCryptoValueFormatted : d.cryptoValueFormatted
return "%1 + %2".arg(cryptoValue).arg(RootStore.formatCurrencyAmount(d.feeEthValue, "ETH")) return "%1 + %2".arg(cryptoValue).arg(RootStore.formatCurrencyAmount(d.feeEthValue, Constants.ethToken))
} }
tertiaryTitle: { tertiaryTitle: {
if (transactionHeader.isNFT && d.isIncoming) if ((transactionHeader.isNFT && d.isIncoming) || !d.symbol)
return "" return ""
const type = d.transactionType const type = d.transactionType
if (type === Constants.TransactionType.Destroy || transactionHeader.isNFT) { if (type === Constants.TransactionType.Destroy || transactionHeader.isNFT) {

View File

@ -68,7 +68,10 @@ StatusListItem {
return qsTr("N/A") return qsTr("N/A")
} else if (root.isNFT) { } else if (root.isNFT) {
return modelData.nftName ? modelData.nftName : "#" + modelData.tokenID return modelData.nftName ? modelData.nftName : "#" + modelData.tokenID
} else if (!modelData.symbol) {
return "%1 (%2)".arg(root.rootStore.formatCurrencyAmount(cryptoValue, "")).arg(Utils.compactAddress(modelData.contract, 4))
} }
return root.rootStore.formatCurrencyAmount(cryptoValue, modelData.symbol) return root.rootStore.formatCurrencyAmount(cryptoValue, modelData.symbol)
} }
@ -273,7 +276,8 @@ StatusListItem {
details += protocolFromContractAddress + endl2 details += protocolFromContractAddress + endl2
} }
if (!!modelData.contract) { if (!!modelData.contract) {
details += qsTr("%1 %2 contract address").arg(root.networkName).arg(modelData.symbol) + endl let symbol = !!modelData.symbol || !modelData.contract ? modelData.symbol : "(%1)".arg(Utils.compactAddress(modelData.contract, 4))
details += qsTr("%1 %2 contract address").arg(root.networkName).arg(symbol) + endl
details += modelData.contract + endl2 details += modelData.contract + endl2
} }
const protocolToContractAddress = "" // TODO fill protocol contract address for 'to' network for Bridge const protocolToContractAddress = "" // TODO fill protocol contract address for 'to' network for Bridge
@ -376,8 +380,8 @@ StatusListItem {
details += valuesString + endl2 details += valuesString + endl2
} }
// Remove locale specific number separator // Remove unicode characters
details = details.replace(/\ /, ' ') details = details.replace(/[^\x00-\x7F]/g, " ");
// Remove empty new lines at the end // Remove empty new lines at the end
return details.replace(/[\r\n\s]*$/, '') return details.replace(/[\r\n\s]*$/, '')
} }
@ -602,7 +606,7 @@ StatusListItem {
text: { text: {
if (root.loading) { if (root.loading) {
return "dummy text" return "dummy text"
} else if (!root.isModelDataValid || root.isNFT) { } else if (!root.isModelDataValid || root.isNFT || !modelData.symbol) {
return "" return ""
} }

View File

@ -822,6 +822,8 @@ QtObject {
readonly property string networkMainnet: "Mainnet" readonly property string networkMainnet: "Mainnet"
readonly property string networkRopsten: "Ropsten" readonly property string networkRopsten: "Ropsten"
readonly property string ethToken: "ETH"
readonly property QtObject networkShortChainNames: QtObject { readonly property QtObject networkShortChainNames: QtObject {
readonly property string mainnet: "eth" readonly property string mainnet: "eth"
readonly property string arbiscan: "arb" readonly property string arbiscan: "arb"