parent
a42ac076ca
commit
db350dc36e
|
@ -3,6 +3,7 @@ import tables, stint, sets
|
|||
|
||||
import model
|
||||
import entry
|
||||
import entry_details
|
||||
import recipients_model
|
||||
import events_handler
|
||||
import status
|
||||
|
@ -41,6 +42,7 @@ QtObject:
|
|||
currentActivityFilter: backend_activity.ActivityFilter
|
||||
currencyService: currency_service.Service
|
||||
tokenService: token_service.Service
|
||||
activityDetails: ActivityDetails
|
||||
|
||||
eventsHandler: EventsHandler
|
||||
status: Status
|
||||
|
@ -183,6 +185,38 @@ QtObject:
|
|||
error "failed to find pending transaction with identity: ", identity
|
||||
ptIndex += 1
|
||||
|
||||
proc fetchTxDetails*(self: Controller, id: string, isMultiTx: bool, isPending: bool) {.slot.} =
|
||||
self.activityDetails = newActivityDetails(id, isMultiTx)
|
||||
if isPending:
|
||||
return
|
||||
|
||||
try:
|
||||
let amountToCurrencyConvertor = proc(amount: UInt256, symbol: string): CurrencyAmount =
|
||||
return currencyAmountToItem(self.currencyService.parseCurrencyValue(symbol, amount),
|
||||
self.currencyService.getCurrencyFormat(symbol))
|
||||
if isMultiTx:
|
||||
let res = backend_activity.getMultiTxDetails(parseInt(id))
|
||||
if res.error != nil:
|
||||
error "failed to fetch multi tx details: ", id
|
||||
return
|
||||
self.activityDetails = newActivityDetails(res.result, amountToCurrencyConvertor)
|
||||
else:
|
||||
let res = backend_activity.getTxDetails(id)
|
||||
if res.error != nil:
|
||||
error "failed to fetch tx details: ", id
|
||||
return
|
||||
self.activityDetails = newActivityDetails(res.result, amountToCurrencyConvertor)
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error: ", errDescription
|
||||
return
|
||||
|
||||
proc getActivityDetails(self: Controller): QVariant {.slot.} =
|
||||
return newQVariant(self.activityDetails)
|
||||
|
||||
QtProperty[QVariant] activityDetails:
|
||||
read = getActivityDetails
|
||||
|
||||
proc processResponse(self: Controller, response: JsonNode) =
|
||||
defer: self.status.setLoadingData(false)
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ QtObject:
|
|||
extradata: ExtraData
|
||||
|
||||
totalFees: CurrencyAmount
|
||||
maxTotalFees: CurrencyAmount
|
||||
amountCurrency: CurrencyAmount
|
||||
noAmount: CurrencyAmount
|
||||
|
||||
|
@ -57,7 +56,6 @@ QtObject:
|
|||
proc delete*(self: ActivityEntry) =
|
||||
self.QObject.delete
|
||||
|
||||
|
||||
proc newMultiTransactionActivityEntry*(mt: MultiTransactionDto, metadata: backend.ActivityEntry, extradata: ExtraData, valueConvertor: AmountToCurrencyConvertor): ActivityEntry =
|
||||
new(result, delete)
|
||||
result.multi_transaction = mt
|
||||
|
@ -83,7 +81,6 @@ QtObject:
|
|||
result.extradata = extradata
|
||||
|
||||
result.totalFees = valueConvertor(stint.fromHex(UInt256, tr.totalFees), "Gwei")
|
||||
result.maxTotalFees = valueConvertor(stint.fromHex(UInt256, tr.maxTotalFees), "Gwei")
|
||||
result.amountCurrency = valueConvertor(
|
||||
if metadata.activityType == backend.ActivityType.Receive: metadata.amountIn else: metadata.amountOut,
|
||||
tr.symbol
|
||||
|
@ -122,6 +119,16 @@ QtObject:
|
|||
raise newException(Defect, "ActivityEntry is not a MultiTransaction")
|
||||
return self.multi_transaction
|
||||
|
||||
proc getId*(self: ActivityEntry): string {.slot.} =
|
||||
if self.isMultiTransaction():
|
||||
return $self.multi_transaction.id
|
||||
elif self.transaction != nil:
|
||||
return self.transaction[].id
|
||||
return ""
|
||||
|
||||
QtProperty[string] id:
|
||||
read = getId
|
||||
|
||||
proc getSender*(self: ActivityEntry): string {.slot.} =
|
||||
return if self.metadata.sender.isSome(): "0x" & self.metadata.sender.unsafeGet().toHex() else: ""
|
||||
|
||||
|
@ -218,26 +225,6 @@ QtObject:
|
|||
QtProperty[QVariant] totalFees:
|
||||
read = getTotalFees
|
||||
|
||||
proc getMaxTotalFees*(self: ActivityEntry): QVariant {.slot.} =
|
||||
if self.transaction == nil:
|
||||
error "getMaxTotalFees: ActivityEntry is not an transaction entry"
|
||||
return newQVariant(self.noAmount)
|
||||
return newQVariant(self.maxTotalFees)
|
||||
|
||||
# TODO: used only in details, move it to a entry_details.nim. See #11598
|
||||
QtProperty[QVariant] maxTotalFees:
|
||||
read = getMaxTotalFees
|
||||
|
||||
proc getInput*(self: ActivityEntry): string {.slot.} =
|
||||
if self.transaction == nil:
|
||||
error "getInput: ActivityEntry is not an transactio entry"
|
||||
return ""
|
||||
return self.transaction[].input
|
||||
|
||||
# TODO: used only in details, move it to a entry_details.nim. See #11598
|
||||
QtProperty[string] input:
|
||||
read = getInput
|
||||
|
||||
proc getTxType*(self: ActivityEntry): int {.slot.} =
|
||||
return self.metadata.activityType.int
|
||||
|
||||
|
@ -245,6 +232,7 @@ QtObject:
|
|||
read = getTxType
|
||||
|
||||
proc getTokenType*(self: ActivityEntry): string {.slot.} =
|
||||
let s = if self.transaction != nil: self.transaction[].symbol else: ""
|
||||
if self.transaction != nil:
|
||||
return self.transaction[].typeValue
|
||||
if self.isInTransactionType() and self.metadata.tokenOut.isSome:
|
||||
|
@ -285,23 +273,6 @@ QtObject:
|
|||
QtProperty[string] tokenAddress:
|
||||
read = getTokenAddress
|
||||
|
||||
proc getContract*(self: ActivityEntry): string {.slot.} =
|
||||
return if self.metadata.contractAddress.isSome(): "0x" & self.metadata.contractAddress.unsafeGet().toHex() else: ""
|
||||
|
||||
QtProperty[string] contract:
|
||||
read = getContract
|
||||
|
||||
proc getTxHash*(self: ActivityEntry): string {.slot.} =
|
||||
if self.transaction != nil and len(self.transaction[].txHash) > 0:
|
||||
return self.transaction[].txHash
|
||||
if self.metadata.transaction.isSome:
|
||||
return self.metadata.transaction.unsafeGet().hash
|
||||
return ""
|
||||
|
||||
# TODO: used only in details, move it to a entry_details.nim. See #11598
|
||||
QtProperty[string] txHash:
|
||||
read = getTxHash
|
||||
|
||||
proc getTokenID*(self: ActivityEntry): string {.slot.} =
|
||||
if self.metadata.payloadType == backend.PayloadType.MultiTransaction:
|
||||
error "getTokenID: ActivityEntry is not a transaction"
|
||||
|
@ -321,26 +292,6 @@ QtObject:
|
|||
QtProperty[string] tokenID:
|
||||
read = getTokenID
|
||||
|
||||
# TODO: used only in details, move it to a entry_details.nim. See #11598
|
||||
proc getNonce*(self: ActivityEntry): string {.slot.} =
|
||||
if self.transaction == nil:
|
||||
error "getNonce: ActivityEntry is not an transaction entry"
|
||||
return ""
|
||||
return $self.transaction[].nonce
|
||||
|
||||
QtProperty[string] nonce:
|
||||
read = getNonce
|
||||
|
||||
proc getBlockNumber*(self: ActivityEntry): string {.slot.} =
|
||||
if self.transaction == nil:
|
||||
error "getBlockNumber: ActivityEntry is not an transaction entry"
|
||||
return ""
|
||||
return $self.transaction[].blockNumber
|
||||
|
||||
# TODO: used only in details, move it to a entry_details.nim. See #11598
|
||||
QtProperty[string] blockNumber:
|
||||
read = getBlockNumber
|
||||
|
||||
proc getOutAmount*(self: ActivityEntry): float {.slot.} =
|
||||
return float(self.extradata.outAmount)
|
||||
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
import NimQml, json, stint, strutils
|
||||
|
||||
import backend/activity as backend
|
||||
|
||||
import app/modules/shared_models/currency_amount
|
||||
|
||||
import web3/ethtypes as eth
|
||||
import web3/conversions
|
||||
|
||||
type
|
||||
AmountToCurrencyConvertor* = proc (amount: UInt256, symbol: string): CurrencyAmount
|
||||
|
||||
QtObject:
|
||||
type
|
||||
ActivityDetails* = ref object of QObject
|
||||
id*: string
|
||||
multiTxId: int
|
||||
nonce*: int
|
||||
blockNumber*: int
|
||||
protocolType*: Option[backend.ProtocolType]
|
||||
txHash*: string
|
||||
input*: string
|
||||
contractAddress: Option[eth.Address]
|
||||
maxTotalFees: CurrencyAmount
|
||||
|
||||
proc setup(self: ActivityDetails) =
|
||||
self.QObject.setup
|
||||
|
||||
proc delete*(self: ActivityDetails) =
|
||||
self.QObject.delete
|
||||
|
||||
proc getMaxTotalFees(maxFee: string, gasLimit: string): string =
|
||||
return (stint.fromHex(Uint256, maxFee) * stint.fromHex(Uint256, gasLimit)).toHex
|
||||
|
||||
proc newActivityDetails*(id: string, isMultiTx: bool): ActivityDetails =
|
||||
new(result, delete)
|
||||
if isMultiTx:
|
||||
result.multiTxId = parseInt(id)
|
||||
else:
|
||||
result.id = id
|
||||
result.maxTotalFees = newCurrencyAmount()
|
||||
result.setup()
|
||||
|
||||
proc newActivityDetails*(e: JsonNode, valueConvertor: AmountToCurrencyConvertor): ActivityDetails =
|
||||
new(result, delete)
|
||||
const protocolTypeField = "protocolType"
|
||||
const hashField = "hash"
|
||||
const contractAddressField = "contractAddress"
|
||||
const inputField = "input"
|
||||
|
||||
result = ActivityDetails(
|
||||
id: e["id"].getStr(),
|
||||
multiTxId: e["multiTxId"].getInt(),
|
||||
nonce: e["nonce"].getInt(),
|
||||
blockNumber: e["blockNumber"].getInt()
|
||||
)
|
||||
let maxFeePerGas = e["maxFeePerGas"].getStr()
|
||||
let gasLimit = e["gasLimit"].getStr()
|
||||
if len(maxFeePerGas) > 0 and len(gasLimit) > 0:
|
||||
let maxTotalFees = getMaxTotalFees(maxFeePerGas, gasLimit)
|
||||
result.maxTotalFees = valueConvertor(stint.fromHex(UInt256, maxTotalFees), "Gwei")
|
||||
else:
|
||||
result.maxTotalFees = newCurrencyAmount()
|
||||
|
||||
if e.hasKey(hashField) and e[hashField].kind != JNull:
|
||||
result.txHash = e[hashField].getStr()
|
||||
if e.hasKey(protocolTypeField) and e[protocolTypeField].kind != JNull:
|
||||
result.protocolType = some(fromJson(e[protocolTypeField], backend.ProtocolType))
|
||||
if e.hasKey(inputField) and e[inputField].kind != JNull:
|
||||
result.input = e[inputField].getStr()
|
||||
if e.hasKey(contractAddressField) and e[contractAddressField].kind != JNull:
|
||||
var contractAddress: eth.Address
|
||||
fromJson(e[contractAddressField], contractAddressField, contractAddress)
|
||||
result.contractAddress = some(contractAddress)
|
||||
result.setup()
|
||||
|
||||
|
||||
proc getNonce*(self: ActivityDetails): int {.slot.} =
|
||||
return self.nonce
|
||||
|
||||
QtProperty[int] nonce:
|
||||
read = getNonce
|
||||
|
||||
proc getBlockNumber*(self: ActivityDetails): int {.slot.} =
|
||||
return self.blockNumber
|
||||
|
||||
QtProperty[int] blockNumber:
|
||||
read = getBlockNumber
|
||||
|
||||
proc getProtocol*(self: ActivityDetails): string {.slot.} =
|
||||
if self.protocolType.isSome():
|
||||
return $self.protocolType.unsafeGet()
|
||||
return ""
|
||||
|
||||
QtProperty[string] protocol:
|
||||
read = getProtocol
|
||||
|
||||
proc getTxHash*(self: ActivityDetails): string {.slot.} =
|
||||
return self.txHash
|
||||
|
||||
QtProperty[string] txHash:
|
||||
read = getTxHash
|
||||
|
||||
proc getInput*(self: ActivityDetails): string {.slot.} =
|
||||
return self.input
|
||||
|
||||
QtProperty[string] input:
|
||||
read = getInput
|
||||
|
||||
proc getContract*(self: ActivityDetails): string {.slot.} =
|
||||
return if self.contractAddress.isSome(): "0x" & self.contractAddress.unsafeGet().toHex() else: ""
|
||||
|
||||
QtProperty[string] contract:
|
||||
read = getContract
|
||||
|
||||
proc getMaxTotalFees*(self: ActivityDetails): QVariant {.slot.} =
|
||||
return newQVariant(self.maxTotalFees)
|
||||
|
||||
QtProperty[QVariant] maxTotalFees:
|
||||
read = getMaxTotalFees
|
|
@ -30,28 +30,28 @@ type
|
|||
id*: string
|
||||
typeValue*: string
|
||||
address*: string
|
||||
blockNumber*: string
|
||||
blockNumber*: string # TODO remove, fetched separately in details
|
||||
blockHash*: string
|
||||
contract*: string
|
||||
timestamp*: UInt256
|
||||
gasPrice*: string
|
||||
gasLimit*: string
|
||||
gasLimit*: string # TODO remove, fetched separately in details
|
||||
gasUsed*: string
|
||||
nonce*: string
|
||||
nonce*: string # TODO remove, fetched separately in details
|
||||
txStatus*: string
|
||||
value*: string
|
||||
tokenId*: UInt256
|
||||
fromAddress*: string
|
||||
to*: string
|
||||
chainId*: int
|
||||
maxFeePerGas*: string
|
||||
maxFeePerGas*: string # TODO remove, fetched separately in details
|
||||
maxPriorityFeePerGas*: string
|
||||
input*: string
|
||||
txHash*: string
|
||||
input*: string # TODO remove, fetched separately in details
|
||||
txHash*: string # TODO remove, fetched separately in details
|
||||
multiTransactionID*: int
|
||||
baseGasFees*: string
|
||||
totalFees*: string
|
||||
maxTotalFees*: string
|
||||
maxTotalFees*: string # TODO remove, fetched separately in details
|
||||
additionalData*: string
|
||||
symbol*: string
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ const noLimitTimestampForPeriod* = 0
|
|||
const eventActivityFilteringDone*: string = "wallet-activity-filtering-done"
|
||||
const eventActivityGetRecipientsDone*: string = "wallet-activity-get-recipients-result"
|
||||
const eventActivityGetOldestTimestampDone*: string = "wallet-activity-get-oldest-timestamp-result"
|
||||
const eventActivityFetchTransactionDetails*: string = "wallet-activity-fetch-transaction-details-result"
|
||||
|
||||
type
|
||||
Period* = object
|
||||
|
@ -218,6 +219,29 @@ proc `%`*(pt: PayloadType): JsonNode {.inline.} =
|
|||
proc fromJson*(jn: JsonNode, T: typedesc[PayloadType]): PayloadType {.inline.} =
|
||||
return cast[PayloadType](jn.getInt())
|
||||
|
||||
# Mirrors status-go/services/wallet/activity/activity.go ProtocolType
|
||||
type
|
||||
ProtocolType* {.pure} = enum
|
||||
Hop = 1
|
||||
Uniswap
|
||||
|
||||
# Define toJson proc for ProtocolType
|
||||
proc `%`*(pt: ProtocolType): JsonNode {.inline.} =
|
||||
return newJInt(ord(pt))
|
||||
|
||||
# Define fromJson proc for ProtocolType
|
||||
proc fromJson*(jn: JsonNode, T: typedesc[ProtocolType]): ProtocolType {.inline.} =
|
||||
return cast[ProtocolType](jn.getInt())
|
||||
|
||||
proc `$`*(pt: ProtocolType): string {.inline.} =
|
||||
case pt:
|
||||
of Hop:
|
||||
return "Hop"
|
||||
of Uniswap:
|
||||
return "Uniswap"
|
||||
else:
|
||||
return ""
|
||||
|
||||
# Mirrors status-go/services/wallet/activity/activity.go TransferType
|
||||
type
|
||||
TransferType* {.pure.} = enum
|
||||
|
@ -259,7 +283,6 @@ type
|
|||
chainIdOut*: Option[ChainId]
|
||||
chainIdIn*: Option[ChainId]
|
||||
transferType*: Option[TransferType]
|
||||
contractAddress*: Option[eth.Address]
|
||||
|
||||
# Mirrors services/wallet/activity/service.go ErrorCode
|
||||
ErrorCode* = enum
|
||||
|
@ -287,7 +310,6 @@ proc fromJson*(e: JsonNode, T: typedesc[ActivityEntry]): ActivityEntry {.inline.
|
|||
const chainIdOutField = "chainIdOut"
|
||||
const chainIdInField = "chainIdIn"
|
||||
const transferTypeField = "transferType"
|
||||
const contractAddressField = "contractAddress"
|
||||
result = T(
|
||||
payloadType: fromJson(e["payloadType"], PayloadType),
|
||||
transaction: if e.hasKey("transaction"):
|
||||
|
@ -325,10 +347,6 @@ proc fromJson*(e: JsonNode, T: typedesc[ActivityEntry]): ActivityEntry {.inline.
|
|||
result.chainIdIn = some(fromJson(e[chainIdInField], ChainId))
|
||||
if e.hasKey(transferTypeField) and e[transferTypeField].kind != JNull:
|
||||
result.transferType = some(fromJson(e[transferTypeField], TransferType))
|
||||
if e.hasKey(contractAddressField) and e[contractAddressField].kind != JNull:
|
||||
var address: eth.Address
|
||||
fromJson(e[contractAddressField], contractAddressField, address)
|
||||
result.contractAddress = some(address)
|
||||
|
||||
proc `$`*(self: ActivityEntry): string =
|
||||
let transactionStr = if self.transaction.isSome: $self.transaction.get()
|
||||
|
@ -420,3 +438,9 @@ proc fromJson*(e: JsonNode, T: typedesc[GetOldestTimestampResponse]): GetOldestT
|
|||
rpc(getOldestActivityTimestampAsync, "wallet"):
|
||||
requestId: int32
|
||||
addresses: seq[string]
|
||||
|
||||
rpc(getMultiTxDetails, "wallet"):
|
||||
id: int
|
||||
|
||||
rpc(getTxDetails, "wallet"):
|
||||
id: string
|
|
@ -33,18 +33,27 @@ Item {
|
|||
|
||||
onTransactionChanged: {
|
||||
d.decodedInputData = ""
|
||||
if (!transaction || !transaction.input)
|
||||
if (!transaction)
|
||||
return
|
||||
d.loadingInputDate = true
|
||||
RootStore.fetchDecodedTxData(transaction.txHash, transaction.input)
|
||||
|
||||
RootStore.fetchTxDetails(transaction.id, transaction.isMultiTransaction, transaction.isPending)
|
||||
d.details = RootStore.getTxDetails()
|
||||
|
||||
if (!!d.details && !!d.details.input) {
|
||||
d.loadingInputDate = true
|
||||
RootStore.fetchDecodedTxData(d.details.txHash, d.details.input)
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property var details: null
|
||||
readonly property bool isDetailsValid: details !== undefined && !!details
|
||||
readonly property bool isIncoming: transactionType === Constants.TransactionType.Received
|
||||
readonly property string networkShortName: root.isTransactionValid ? RootStore.getNetworkShortName(transaction.chainId) : ""
|
||||
readonly property string networkIcon: isTransactionValid ? RootStore.getNetworkIcon(transaction.chainId) : "network/Network=Custom"
|
||||
readonly property int blockNumber: root.isTransactionValid ? RootStore.hex2Dec(root.transaction.blockNumber) : 0
|
||||
readonly property int blockNumber: isDetailsValid ? details.blockNumber : 0
|
||||
readonly property int toBlockNumber: 0 // TODO fill when bridge data is implemented
|
||||
readonly property string networkShortNameOut: networkShortName
|
||||
readonly property string networkShortNameIn: transactionHeader.isMultiTransaction ? RootStore.getNetworkShortName(transaction.chainIdOut) : ""
|
||||
|
@ -61,7 +70,7 @@ Item {
|
|||
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.tokenAddress, 4))
|
||||
return symbol || (!d.isDetailsValid || !d.details.contract) ? formatted : "%1 (%2)".arg(formatted).arg(Utils.compactAddress(transaction.tokenAddress, 4))
|
||||
}
|
||||
readonly property string outFiatValueFormatted: {
|
||||
if (!root.isTransactionValid || !transactionHeader.isMultiTransaction || !outSymbol)
|
||||
|
@ -74,7 +83,7 @@ Item {
|
|||
const formatted = RootStore.formatCurrencyAmount(transaction.outAmount, transaction.outSymbol)
|
||||
return outSymbol || !transaction.tokenOutAddress ? formatted : "%1 (%2)".arg(formatted).arg(Utils.compactAddress(transaction.tokenOutAddress, 4))
|
||||
}
|
||||
readonly property real feeEthValue: root.isTransactionValid ? RootStore.getGasEthValue(transaction.totalFees.amount, 1) : 0 // TODO use directly?
|
||||
readonly property real feeEthValue: root.isTransactionValid ? RootStore.getFeeEthValue(transaction.totalFees) : 0
|
||||
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
|
||||
|
||||
|
@ -89,7 +98,7 @@ Item {
|
|||
Connections {
|
||||
target: RootStore.walletSectionInst
|
||||
function onTxDecoded(txHash: string, dataDecoded: string) {
|
||||
if (!root.isTransactionValid || txHash !== root.transaction.txHash)
|
||||
if (!root.isTransactionValid || (d.isDetailsValid && txHash !== d.details.txHash))
|
||||
return
|
||||
if (!dataDecoded) {
|
||||
d.loadingInputDate = false
|
||||
|
@ -168,7 +177,7 @@ Item {
|
|||
nftUrl: root.isTransactionValid && !!transaction.nftImageUrl ? transaction.nftImageUrl : ""
|
||||
strikethrough: d.transactionType === Constants.TransactionType.Destroy
|
||||
tokenId: root.isTransactionValid ? transaction.tokenID : ""
|
||||
contractAddress: root.isTransactionValid ? transaction.contract : ""
|
||||
contractAddress: d.isDetailsValid ? d.details.contract : ""
|
||||
}
|
||||
|
||||
Column {
|
||||
|
@ -269,7 +278,7 @@ Item {
|
|||
}
|
||||
TransactionDataTile {
|
||||
id: contractDeploymentTile
|
||||
readonly property bool hasValue: root.isTransactionValid && !!root.transaction.contract
|
||||
readonly property bool hasValue: d.isDetailsValid && !!d.details.contract
|
||||
&& transactionHeader.transactionStatus !== Constants.TransactionStatus.Pending
|
||||
&& transactionHeader.transactionStatus !== Constants.TransactionStatus.Failed
|
||||
width: parent.width
|
||||
|
@ -281,11 +290,11 @@ Item {
|
|||
} else if (!hasValue) {
|
||||
return qsTr("Awaiting contract address...")
|
||||
}
|
||||
return qsTr("Contract created") + "\n" + transaction.contract
|
||||
return qsTr("Contract created") + "\n" + d.details.contract
|
||||
}
|
||||
buttonIconName: hasValue ? "more" : ""
|
||||
statusListItemSubTitle.customColor: hasValue ? Theme.palette.directColor1 : Theme.palette.directColor5
|
||||
onButtonClicked: addressMenu.openContractMenu(this, transaction.contract, transactionHeader.networkName, d.symbol)
|
||||
onButtonClicked: addressMenu.openContractMenu(this, d.details.contract, transactionHeader.networkName, d.symbol)
|
||||
components: [
|
||||
Loader {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
@ -308,18 +317,16 @@ Item {
|
|||
TransactionDataTile {
|
||||
width: parent.width
|
||||
title: qsTr("Using")
|
||||
buttonIconName: "external"
|
||||
subTitle: "" // TODO fill protocol name for Swap and Bridge
|
||||
asset.name: "" // TODO fill protocol icon for Bridge and Swap e.g. Style.svg("network/Network=Arbitrum")
|
||||
onButtonClicked: {
|
||||
// TODO handle
|
||||
}
|
||||
subTitle: d.isDetailsValid ? d.details.protocol : ""
|
||||
asset.name: d.isDetailsValid && d.details.protocol ? Style.svg("protocol/Protocol=%1".arg(d.details.protocol)) : Style.svg("network/Network=Custom")
|
||||
iconSettings.bgRadius: iconSettings.bgWidth / 2
|
||||
// buttonIconName: "external" // TODO handle external link #11982
|
||||
visible: !!subTitle
|
||||
}
|
||||
TransactionDataTile {
|
||||
width: parent.width
|
||||
title: qsTr("%1 Tx hash").arg(transactionHeader.networkName)
|
||||
subTitle: root.isTransactionValid ? root.transaction.txHash : ""
|
||||
subTitle: d.isDetailsValid ? d.details.txHash : ""
|
||||
visible: !!subTitle
|
||||
buttonIconName: "more"
|
||||
onButtonClicked: addressMenu.openTxMenu(this, subTitle, d.networkShortName)
|
||||
|
@ -342,7 +349,7 @@ Item {
|
|||
}
|
||||
TransactionContractTile {
|
||||
// Used to display contract address for any network
|
||||
address: root.isTransactionValid ? transaction.contract : ""
|
||||
address: d.isDetailsValid ? d.details.contract : ""
|
||||
symbol: {
|
||||
if (!root.isTransactionValid)
|
||||
return ""
|
||||
|
@ -453,7 +460,7 @@ Item {
|
|||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("Nonce")
|
||||
subTitle: root.isTransactionValid ? RootStore.hex2Dec(root.transaction.nonce) : ""
|
||||
subTitle: d.isDetailsValid ? d.details.nonce : ""
|
||||
visible: !!subTitle
|
||||
}
|
||||
}
|
||||
|
@ -467,8 +474,8 @@ Item {
|
|||
return ""
|
||||
} else if (!!d.decodedInputData) {
|
||||
return d.decodedInputData.substring(0, 200)
|
||||
} else if (root.isTransactionValid) {
|
||||
return String(root.transaction.input).substring(0, 200)
|
||||
} else if (d.isDetailsValid) {
|
||||
return String(d.details.input).substring(0, 200)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
@ -492,7 +499,7 @@ Item {
|
|||
statusListItemTertiaryTitle.anchors.top: undefined
|
||||
statusListItemTertiaryTitle.anchors.baseline: statusListItemTitle.baseline
|
||||
statusListItemTertiaryTitle.font: statusListItemTitle.font
|
||||
onButtonClicked: addressMenu.openInputDataMenu(this, !!d.decodedInputData ? d.decodedInputData : root.transaction.input)
|
||||
onButtonClicked: addressMenu.openInputDataMenu(this, !!d.decodedInputData ? d.decodedInputData : d.details.input)
|
||||
|
||||
Loader {
|
||||
anchors {
|
||||
|
@ -610,10 +617,10 @@ Item {
|
|||
width: parent.width
|
||||
title: d.symbol ? qsTr("Fees") : qsTr("Estimated max fee")
|
||||
subTitle: {
|
||||
if (!root.isTransactionValid || transactionHeader.isNFT)
|
||||
if (!root.isTransactionValid || transactionHeader.isNFT || !!d.isDetailsValid)
|
||||
return ""
|
||||
if (!d.symbol) {
|
||||
const maxFeeEth = RootStore.getGasEthValue(transaction.maxTotalFees.amount, 1)
|
||||
const maxFeeEth = RootStore.getFeeEthValue(d.details.maxTotalFees)
|
||||
return RootStore.formatCurrencyAmount(maxFeeEth, Constants.ethToken)
|
||||
}
|
||||
|
||||
|
@ -631,7 +638,7 @@ Item {
|
|||
return ""
|
||||
let fiatValue
|
||||
if (!d.symbol) {
|
||||
const maxFeeEth = RootStore.getGasEthValue(transaction.maxTotalFees.amount, 1)
|
||||
const maxFeeEth = RootStore.getFeeEthValue(d.details.maxTotalFees)
|
||||
fiatValue = RootStore.getFiatValue(maxFeeEth, Constants.ethToken, RootStore.currentCurrency)
|
||||
} else {
|
||||
fiatValue = d.feeFiatValue
|
||||
|
@ -659,7 +666,7 @@ Item {
|
|||
if (fieldIsHidden)
|
||||
return ""
|
||||
if (showMaxFee) {
|
||||
const maxFeeEth = RootStore.getGasEthValue(transaction.maxTotalFees.amount, 1)
|
||||
const maxFeeEth = RootStore.getFeeEthValue(d.details.maxTotalFees)
|
||||
return RootStore.formatCurrencyAmount(maxFeeEth, Constants.ethToken)
|
||||
} else if (showFee) {
|
||||
return RootStore.formatCurrencyAmount(d.feeEthValue, Constants.ethToken)
|
||||
|
@ -673,7 +680,7 @@ Item {
|
|||
if (fieldIsHidden)
|
||||
return ""
|
||||
if (showMaxFee) {
|
||||
const maxFeeEth = RootStore.getGasEthValue(transaction.maxTotalFees.amount, 1)
|
||||
const maxFeeEth = RootStore.getFeeEthValue(d.details.maxTotalFees)
|
||||
const maxFeeFiat = RootStore.getFiatValue(d.feeEthValue, "ETH", RootStore.currentCurrency)
|
||||
return RootStore.formatCurrencyAmount(maxFeeFiat, RootStore.currentCurrency)
|
||||
} else if (showFee) {
|
||||
|
@ -718,7 +725,7 @@ Item {
|
|||
icon.width: 20
|
||||
icon.height: 20
|
||||
size: StatusButton.Small
|
||||
onClicked: RootStore.copyToClipboard(transactionHeader.getDetailsString())
|
||||
onClicked: RootStore.copyToClipboard(transactionHeader.getDetailsString(d.details))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="18" cy="18" r="17.5" fill="white" stroke="#F6F8FA"/>
|
||||
<g clip-path="url(#clip0_16679_212870)">
|
||||
<path d="M27.1385 14.4178L23.0668 8.48738C22.4274 7.55788 20.9813 8.05131 21.0286 9.18059C21.0719 10.21 21.4561 11.2995 22.3757 12.6366L22.3762 12.6391L22.3751 12.6413L22.3729 12.6426L22.3704 12.6422C21.9943 12.3614 16.3226 8.09704 9.58082 10.3676H9.57321C8.82916 10.6468 8.44931 11.2562 8.63763 11.9707C8.81192 12.6322 9.48947 13.0293 10.163 12.9174C11.595 12.6787 13.0162 12.5652 14.4138 12.688C15.8114 12.8107 17.1785 13.1694 18.4514 13.7956C19.7244 14.4218 20.8775 15.308 21.9373 16.3229C23.1293 17.4634 24.6083 19.8957 24.6083 19.8957C24.6949 20.0498 24.8332 20.1683 24.9986 20.2303C25.1641 20.2923 25.3461 20.2939 25.5126 20.2347C25.9133 20.091 26.0999 19.6285 25.9493 19.2317C25.6351 18.4024 25.2505 17.6016 24.7998 16.838L24.7988 16.8353L24.7997 16.8327L24.8022 16.8313L24.805 16.832C25.3034 17.0197 25.7646 17.2536 26.3103 17.1257C26.7555 17.0209 27.1461 16.7177 27.3276 16.2932C27.4591 15.9905 27.5107 15.6592 27.4776 15.3308C27.4444 15.0024 27.3277 14.688 27.1385 14.4178Z" fill="url(#paint0_linear_16679_212870)"/>
|
||||
<path d="M8.34877 20.9696L12.4205 26.9C13.0599 27.8295 14.506 27.3361 14.4587 26.2068C14.4154 25.1774 14.0312 24.0878 13.1116 22.7508L13.1111 22.7483L13.1122 22.746L13.1144 22.7448L13.1168 22.7451C13.4931 23.0259 19.1647 27.2903 25.9065 25.0198H25.9141C26.6581 24.7406 27.038 24.1312 26.8497 23.4167C26.6754 22.7552 25.9978 22.358 25.3243 22.4699C23.8922 22.7086 22.4711 22.8222 21.0735 22.6994C19.6759 22.5766 18.3088 22.218 17.0359 21.5918C15.7629 20.9656 14.6097 20.0794 13.55 19.0644C12.358 17.9239 10.8791 15.4917 10.8791 15.4917C10.7924 15.3376 10.6541 15.2191 10.4887 15.157C10.3232 15.095 10.1412 15.0935 9.97472 15.1527C9.57404 15.2963 9.38733 15.7589 9.53798 16.1556C9.85218 16.9849 10.2368 17.7858 10.6875 18.5494L10.6886 18.552L10.6876 18.5547L10.6851 18.5561L10.6823 18.5554C10.1839 18.3676 9.7227 18.1338 9.17697 18.2618C8.73182 18.3664 8.34116 18.6698 8.15965 19.0941C8.02825 19.3968 7.97663 19.7282 8.00974 20.0566C8.04286 20.3849 8.15959 20.6993 8.34877 20.9696Z" fill="url(#paint1_linear_16679_212870)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_16679_212870" x1="28.4876" y1="25.8943" x2="4.57995" y2="-3.51434" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.15" stop-color="#B32EFF"/>
|
||||
<stop offset="0.42" stop-color="#CE60D3"/>
|
||||
<stop offset="0.65" stop-color="#E185B3"/>
|
||||
<stop offset="0.84" stop-color="#EE9C9F"/>
|
||||
<stop offset="0.96" stop-color="#F2A498"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_16679_212870" x1="6.99969" y1="9.4931" x2="30.9074" y2="38.9018" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.15" stop-color="#B32EFF"/>
|
||||
<stop offset="0.42" stop-color="#CE60D3"/>
|
||||
<stop offset="0.65" stop-color="#E185B3"/>
|
||||
<stop offset="0.84" stop-color="#EE9C9F"/>
|
||||
<stop offset="0.96" stop-color="#F2A498"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_16679_212870">
|
||||
<rect width="20" height="20" fill="white" transform="translate(8 8)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 3.3 MiB |
|
@ -1,4 +1,5 @@
|
|||
import QtQuick 2.13
|
||||
import QtGraphicalEffects 1.15
|
||||
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
@ -55,6 +56,15 @@ StatusListItem {
|
|||
*/
|
||||
property string buttonIconName
|
||||
|
||||
property StatusAssetSettings iconSettings: StatusAssetSettings {
|
||||
name: root.asset.name
|
||||
color: "transparent"
|
||||
width: root.smallIcon ? 20 : 36
|
||||
height: root.smallIcon ? 20 : 36
|
||||
bgWidth: width
|
||||
bgHeight: height
|
||||
}
|
||||
|
||||
signal buttonClicked()
|
||||
|
||||
leftPadding: 12
|
||||
|
@ -94,13 +104,14 @@ StatusListItem {
|
|||
Component {
|
||||
id: iconComponent
|
||||
StatusRoundIcon {
|
||||
asset: StatusAssetSettings {
|
||||
name: root.asset.name
|
||||
color: "transparent"
|
||||
width: root.smallIcon ? 20 : 36
|
||||
height: root.smallIcon ? 20 : 36
|
||||
bgWidth: width
|
||||
bgHeight: height
|
||||
asset: root.iconSettings
|
||||
layer.enabled: asset.bgRadius > 0
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Rectangle {
|
||||
width: root.iconSettings.bgWidth
|
||||
height: root.iconSettings.bgHeight
|
||||
radius: root.iconSettings.bgRadius
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,11 +143,13 @@ StatusListItem {
|
|||
}
|
||||
|
||||
property StatusAssetSettings tokenIconAsset: StatusAssetSettings {
|
||||
width: 18
|
||||
height: 18
|
||||
bgWidth: width
|
||||
bgHeight: height
|
||||
bgColor: "transparent"
|
||||
width: 20
|
||||
height: 20
|
||||
bgWidth: width + 2
|
||||
bgHeight: height + 2
|
||||
bgRadius: bgWidth / 2
|
||||
bgColor: Style.current.name === Constants.lightThemeName && Constants.isDefaultTokenIcon(root.tokenImage) ?
|
||||
Theme.palette.white : "transparent"
|
||||
color: "transparent"
|
||||
isImage: !loading
|
||||
name: root.tokenImage
|
||||
|
@ -164,7 +166,12 @@ StatusListItem {
|
|||
property bool showRetryButton: false
|
||||
}
|
||||
|
||||
function getDetailsString() {
|
||||
function getDetailsString(detailsObj) {
|
||||
if (!detailsObj) {
|
||||
rootStore.fetchTxDetails(modelData.id, modelData.isMultiTransaction, modelData.isPending)
|
||||
detailsObj = rootStore.getTxDetails()
|
||||
}
|
||||
|
||||
let details = ""
|
||||
const endl = "\n"
|
||||
const endl2 = endl + endl
|
||||
|
@ -246,7 +253,7 @@ StatusListItem {
|
|||
case Constants.TransactionStatus.Verified: {
|
||||
const timestampString = LocaleUtils.formatDateTime(modelData.timestamp * 1000, Locale.LongFormat)
|
||||
details += qsTr("Status") + endl
|
||||
const epoch = parseFloat(Math.abs(walletRootStore.getLatestBlockNumber(modelData.chainId) - rootStore.hex2Dec(modelData.blockNumber)).toFixed(0)).toLocaleString()
|
||||
const epoch = parseFloat(Math.abs(walletRootStore.getLatestBlockNumber(modelData.chainId) - detailsObj.blockNumber).toFixed(0)).toLocaleString()
|
||||
details += qsTr("Finalised in epoch %1").arg(epoch.toFixed(0)) + endl2
|
||||
details += qsTr("Signed") + endl + root.timestampString + endl2
|
||||
details += qsTr("Confirmed") + endl
|
||||
|
@ -256,7 +263,7 @@ StatusListItem {
|
|||
case Constants.TransactionStatus.Finished: {
|
||||
const timestampString = LocaleUtils.formatDateTime(modelData.timestamp * 1000, Locale.LongFormat)
|
||||
details += qsTr("Status") + endl
|
||||
const epoch = Math.abs(walletRootStore.getLatestBlockNumber(modelData.chainId) - rootStore.hex2Dec(modelData.blockNumber))
|
||||
const epoch = Math.abs(walletRootStore.getLatestBlockNumber(modelData.chainId) - detailsObj.blockNumber)
|
||||
details += qsTr("Finalised in epoch %1").arg(epoch.toFixed(0)) + endl2
|
||||
details += qsTr("Signed") + endl + timestampString + endl2
|
||||
details += qsTr("Confirmed") + endl
|
||||
|
@ -298,9 +305,8 @@ StatusListItem {
|
|||
details += qsTr("To") + endl + modelData.recipient + endl2
|
||||
break
|
||||
}
|
||||
const protocolName = "" // TODO fill protocol name for Bridge and Swap
|
||||
if (!!protocolName) {
|
||||
details += qsTr("Using") + endl + protocolName + endl2
|
||||
if (!!detailsObj.protocol) {
|
||||
details += qsTr("Using") + endl + detailsObj.protocol + endl2
|
||||
}
|
||||
if (!!modelData.txHash) {
|
||||
details += qsTr("%1 Tx hash").arg(root.networkName) + endl + modelData.txHash + endl2
|
||||
|
@ -310,18 +316,18 @@ StatusListItem {
|
|||
details += qsTr("%1 Tx hash").arg(networkNameOut) + endl + bridgeTxHash + endl2
|
||||
}
|
||||
const protocolFromContractAddress = "" // TODO fill protocol contract address for 'from' network for Bridge and Swap
|
||||
if (!!protocolName && !!protocolFromContractAddress) {
|
||||
details += qsTr("%1 %2 contract address").arg(root.networkName).arg(protocolName) + endl
|
||||
if (!!detailsObj.protocol && !!protocolFromContractAddress) {
|
||||
details += qsTr("%1 %2 contract address").arg(root.networkName).arg(detailsObj.protocol) + endl
|
||||
details += protocolFromContractAddress + endl2
|
||||
}
|
||||
if (!!modelData.contract && type !== Constants.TransactionType.ContractDeployment && !/0x0+$/.test(modelData.contract)) {
|
||||
if (!!detailsObj.contract && type !== Constants.TransactionType.ContractDeployment && !/0x0+$/.test(detailsObj.contract)) {
|
||||
let symbol = !!modelData.symbol || !modelData.tokenAddress ? modelData.symbol : "(%1)".arg(Utils.compactAddress(modelData.tokenAddress, 4))
|
||||
details += qsTr("%1 %2 contract address").arg(root.networkName).arg(symbol) + endl
|
||||
details += modelData.contract + endl2
|
||||
details += detailsObj.contract + endl2
|
||||
}
|
||||
const protocolToContractAddress = "" // TODO fill protocol contract address for 'to' network for Bridge
|
||||
if (!!protocolToContractAddress && !!protocolName) {
|
||||
details += qsTr("%1 %2 contract address").arg(networkNameOut).arg(protocolName) + endl
|
||||
if (!!protocolToContractAddress && !!detailsObj.protocol) {
|
||||
details += qsTr("%1 %2 contract address").arg(networkNameOut).arg(detailsObj.protocol) + endl
|
||||
details += protocolToContractAddress + endl2
|
||||
}
|
||||
const swapContractAddress = "" // TODO fill swap contract address for Swap
|
||||
|
@ -348,15 +354,17 @@ StatusListItem {
|
|||
details += qsTr("Network") + endl + networkName + endl2
|
||||
}
|
||||
details += qsTr("Token format") + endl + modelData.tokenType.toUpperCase() + endl2
|
||||
details += qsTr("Nonce") + endl + rootStore.hex2Dec(modelData.nonce) + endl2
|
||||
details += qsTr("Nonce") + endl + detailsObj.nonce + endl2
|
||||
if (type === Constants.TransactionType.Bridge) {
|
||||
details += qsTr("Included in Block on %1").arg(networkName) + endl
|
||||
details += rootStore.hex2Dec(modelData.blockNumber) + endl2
|
||||
details += qsTr("Included in Block on %1").arg(networkNameOut) + endl
|
||||
details += detailsObj.blockNumber + endl2
|
||||
const bridgeBlockNumber = 0 // TODO fill when bridge data is implemented
|
||||
details += rootStore.hex2Dec(bridgeBlockNumber) + endl2
|
||||
if (bridgeBlockNumber > 0) {
|
||||
details += qsTr("Included in Block on %1").arg(networkNameOut) + endl
|
||||
details += bridgeBlockNumber + endl2
|
||||
}
|
||||
} else {
|
||||
details += qsTr("Included in Block") + endl + rootStore.hex2Dec(modelData.blockNumber) + endl2
|
||||
details += qsTr("Included in Block") + endl + detailsObj.blockNumber + endl2
|
||||
}
|
||||
|
||||
// VALUES
|
||||
|
@ -409,7 +417,7 @@ StatusListItem {
|
|||
} else if (type === Constants.TransactionType.ContractDeployment) {
|
||||
const isPending = root.transactionStatus === Constants.TransactionStatus.Pending
|
||||
if (isPending) {
|
||||
const maxFeeEthValue = rootStore.getGasEthValue(modelData.maxTotalFees.amount, 1)
|
||||
const maxFeeEthValue = rootStore.getFeeEthValue(detailsObj.maxTotalFees.amount)
|
||||
const maxFeeCrypto = rootStore.formatCurrencyAmount(maxFeeEthValue, "ETH")
|
||||
const maxFeeFiat = rootStore.formatCurrencyAmount(maxFeeCrypto, root.currentCurrency)
|
||||
valuesString += qsTr("Estimated max fee %1 (%2)").arg(maxFeeCrypto).arg(maxFeeFiat) + endl2
|
||||
|
@ -462,8 +470,7 @@ StatusListItem {
|
|||
return qsTr("%1 from %2 to %3").arg(inTransactionValue).arg(networkNameOut).arg(networkNameIn)
|
||||
case Constants.TransactionType.ContractDeployment:
|
||||
const name = addressNameTo || addressNameFrom
|
||||
return !!modelData.contract ? qsTr("Contract %1 via %2 on %3").arg(Utils.compactAddress(modelData.contract, 4)).arg(name).arg(networkName)
|
||||
: qsTr("Via %1 on %2").arg(name).arg(networkName)
|
||||
return qsTr("Via %1 on %2").arg(name).arg(networkName)
|
||||
case Constants.TransactionType.Mint:
|
||||
if (allAccounts)
|
||||
return qsTr("%1 via %2 in %4").arg(transactionValue).arg(networkName).arg(toAddress)
|
||||
|
@ -591,7 +598,7 @@ StatusListItem {
|
|||
bgWidth: width + 2
|
||||
bgHeight: height + 2
|
||||
bgRadius: bgWidth / 2
|
||||
bgColor: root.color
|
||||
bgColor: Theme.palette.white
|
||||
isImage:root.tokenIconAsset.isImage
|
||||
color: root.tokenIconAsset.color
|
||||
name: root.inTokenImage
|
||||
|
@ -801,11 +808,6 @@ StatusListItem {
|
|||
width: 17
|
||||
height: 17
|
||||
}
|
||||
PropertyChanges {
|
||||
target: root.tokenIconAsset
|
||||
width: 20
|
||||
height: 20
|
||||
}
|
||||
PropertyChanges {
|
||||
target: d
|
||||
titlePixelSize: 17
|
||||
|
|
|
@ -230,6 +230,10 @@ QtObject {
|
|||
return currencyStore.getGasEthValue(gweiValue, gasLimit)
|
||||
}
|
||||
|
||||
function getFeeEthValue(feeCurrency) {
|
||||
return currencyStore.getGasEthValue(feeCurrency.amount / Math.pow(10, feeCurrency.displayDecimals), 1)
|
||||
}
|
||||
|
||||
function formatCurrencyAmount(amount, symbol, options = null, locale = null) {
|
||||
return currencyStore.formatCurrencyAmount(amount, symbol, options, locale)
|
||||
}
|
||||
|
@ -243,6 +247,14 @@ QtObject {
|
|||
walletSectionInst.fetchDecodedTxData(txHash, input)
|
||||
}
|
||||
|
||||
function fetchTxDetails(id, isMultiTx, isPending) {
|
||||
walletSectionInst.activityController.fetchTxDetails(id, isMultiTx, isPending)
|
||||
}
|
||||
|
||||
function getTxDetails() {
|
||||
return walletSectionInst.activityController.activityDetails
|
||||
}
|
||||
|
||||
property bool marketHistoryIsLoading: Global.appIsReady? walletSectionAllTokens.marketHistoryIsLoading : false
|
||||
|
||||
function fetchHistoricalBalanceForTokenAsJson(address, tokenSymbol, currencySymbol, timeIntervalEnum) {
|
||||
|
|
|
@ -1114,6 +1114,10 @@ QtObject {
|
|||
return ""
|
||||
}
|
||||
|
||||
function isDefaultTokenIcon(url) {
|
||||
return url.indexOf("DEFAULT-TOKEN") !== -1
|
||||
}
|
||||
|
||||
// Message outgoing status
|
||||
readonly property string sending: "sending"
|
||||
readonly property string sent: "sent"
|
||||
|
|
Loading…
Reference in New Issue