fix(@desktop/wallet): Use second chain activity details data (#12705)

This commit is contained in:
Cuteivist 2023-12-01 15:31:47 +01:00 committed by GitHub
parent 320a3a3e3d
commit e552a01d2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 133 additions and 76 deletions

View File

@ -11,6 +11,12 @@ import web3/conversions
type
AmountToCurrencyConvertor* = proc (amount: UInt256, symbol: string): CurrencyAmount
ActivityChainDetails = object
chainId: ChainId
blockNumber: int
txHash: string
contractAddress: Option[eth.Address]
QtObject:
type
ActivityDetails* = ref object of QObject
@ -21,11 +27,14 @@ QtObject:
# TODO use medatada
multiTxId: int
nonce*: int
blockNumber*: int
blockNumberOut*: int
blockNumberIn*: int
protocolType*: Option[backend.ProtocolType]
txHash*: string
txHashOut*: string
txHashIn*: string
input*: string
contractAddress: Option[eth.Address]
contractAddressIn: Option[eth.Address]
contractAddressOut: Option[eth.Address]
maxTotalFees: CurrencyAmount
totalFees: CurrencyAmount
@ -38,6 +47,18 @@ QtObject:
proc getMaxTotalFees(maxFee: string, gasLimit: string): string =
return (stint.fromHex(Uint256, maxFee) * stint.fromHex(Uint256, gasLimit)).toHex
proc fromJson*(e: JsonNode, T: typedesc[ActivityChainDetails]): ActivityChainDetails {.inline.} =
const contractAddressField = "contractAddress"
result = T(
chainId: ChainId(e["chainId"].getInt()),
blockNumber: e["blockNumber"].getInt(),
txHash: e["hash"].getStr(),
)
if e.hasKey(contractAddressField) and e[contractAddressField].kind != JNull:
var contractAddress: eth.Address
fromJson(e[contractAddressField], contractAddressField, contractAddress)
result.contractAddress = some(contractAddress)
proc newActivityDetails*(metadata: backend.ActivityEntry, valueConvertor: AmountToCurrencyConvertor): ActivityDetails =
new(result, delete)
defer: result.setup()
@ -65,15 +86,28 @@ QtObject:
e = res.result
const protocolTypeField = "protocolType"
const hashField = "hash"
const contractAddressField = "contractAddress"
const inputField = "input"
const totalFeesField = "totalFees"
const chainDetailsField = "chainDetails"
result.id = e["id"].getStr()
result.multiTxId = e["multiTxId"].getInt()
result.nonce = e["nonce"].getInt()
result.blockNumber = e["blockNumber"].getInt()
let chainIdOut = metadata.chainIdOut.get(ChainId(0))
let chainIdIn = metadata.chainIdIn.get(ChainId(0))
if e[chainDetailsField].kind == JArray:
for chainDetails in e[chainDetailsField].items:
let chainDetails = fromJson(chainDetails, ActivityChainDetails)
if chainDetails.chainId == chainIdOut:
result.blockNumberOut = chainDetails.blockNumber
result.txHashOut = chainDetails.txHash
result.contractAddressOut = chainDetails.contractAddress
elif chainDetails.chainId == chainIdIn:
result.blockNumberIn = chainDetails.blockNumber
result.txHashIn = chainDetails.txHash
result.contractAddressIn = chainDetails.contractAddress
let maxFeePerGas = e["maxFeePerGas"].getStr()
let gasLimit = e["gasLimit"].getStr()
@ -90,16 +124,10 @@ QtObject:
if resTotalFees != nil:
result.totalFees = resTotalFees
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)
proc getNonce*(self: ActivityDetails): int {.slot.} =
return self.nonce
@ -107,8 +135,22 @@ QtObject:
QtProperty[int] nonce:
read = getNonce
proc getBlockNumberIn*(self: ActivityDetails): int {.slot.} =
return self.blockNumberIn
QtProperty[int] blockNumberIn:
read = getBlockNumberIn
proc getBlockNumberOut*(self: ActivityDetails): int {.slot.} =
return self.blockNumberOut
QtProperty[int] blockNumberOut:
read = getBlockNumberOut
proc getBlockNumber*(self: ActivityDetails): int {.slot.} =
return self.blockNumber
if self.blockNumberOut > 0:
return self.blockNumberOut
return self.blockNumberIn
QtProperty[int] blockNumber:
read = getBlockNumber
@ -121,11 +163,17 @@ QtObject:
QtProperty[string] protocol:
read = getProtocol
proc getTxHash*(self: ActivityDetails): string {.slot.} =
return self.txHash
proc getTxHashOut*(self: ActivityDetails): string {.slot.} =
return self.txHashOut
QtProperty[string] txHash:
read = getTxHash
QtProperty[string] txHashOut:
read = getTxHashOut
proc getTxHashIn*(self: ActivityDetails): string {.slot.} =
return self.txHashIn
QtProperty[string] txHashIn:
read = getTxHashIn
proc getInput*(self: ActivityDetails): string {.slot.} =
return self.input
@ -133,11 +181,17 @@ QtObject:
QtProperty[string] input:
read = getInput
proc getContract*(self: ActivityDetails): string {.slot.} =
return if self.contractAddress.isSome(): "0x" & self.contractAddress.unsafeGet().toHex() else: ""
proc getContractIn*(self: ActivityDetails): string {.slot.} =
return if self.contractAddressIn.isSome(): "0x" & self.contractAddressIn.unsafeGet().toHex() else: ""
QtProperty[string] contract:
read = getContract
QtProperty[string] contractIn:
read = getContractIn
proc getContractOut*(self: ActivityDetails): string {.slot.} =
return if self.contractAddressOut.isSome(): "0x" & self.contractAddressOut.unsafeGet().toHex() else: ""
QtProperty[string] contractOut:
read = getContractOut
proc getMaxTotalFees*(self: ActivityDetails): QVariant {.slot.} =
return newQVariant(self.maxTotalFees)

View File

@ -123,6 +123,9 @@ proc fromJson*(jn: JsonNode, T: typedesc[ChainId]): ChainId {.inline.} =
proc `$`*(cid: ChainId): string = $(int(cid))
proc `==`*(c1, c2: ChainId): bool =
return int(c1) == int(c2)
const addressField = "address"
const tokenIdField = "tokenId"

View File

@ -45,7 +45,8 @@ Item {
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: isDetailsValid ? details.blockNumber : 0
readonly property int toBlockNumber: 0 // TODO fill when bridge data is implemented
readonly property int blockNumberIn: isDetailsValid ? details.blockNumberIn : 0
readonly property int blockNumberOut: isDetailsValid ? details.blockNumberOut : 0
readonly property string networkShortNameOut: networkShortName
readonly property string networkShortNameIn: transactionHeader.isMultiTransaction ? RootStore.getNetworkShortName(transaction.chainIdIn) : ""
readonly property string symbol: isTransactionValid ? transaction.symbol : ""
@ -75,7 +76,7 @@ Item {
return outSymbol || !transaction.tokenOutAddress ? formatted : "%1 (%2)".arg(formatted).arg(Utils.compactAddress(transaction.tokenOutAddress, 4))
}
readonly property real feeEthValue: d.details ? RootStore.getFeeEthValue(d.details.totalFees) : 0
readonly property real feeFiatValue: root.isTransactionValid ? RootStore.getFiatValue(d.feeEthValue, Constants.ethToken, RootStore.currentCurrency) : 0 // TODO use directly?
readonly property real feeFiatValue: root.isTransactionValid ? RootStore.getFiatValue(d.feeEthValue, Constants.ethToken, RootStore.currentCurrency) : 0
readonly property int transactionType: root.isTransactionValid ? transaction.txType : Constants.TransactionType.Send
readonly property bool isBridge: d.transactionType === Constants.TransactionType.Bridge
@ -96,7 +97,7 @@ Item {
if (!!d.details && !!d.details.input) {
d.loadingInputDate = true
RootStore.fetchDecodedTxData(d.details.txHash, d.details.input)
RootStore.fetchDecodedTxData(d.details.txHashOut, d.details.input)
}
}
}
@ -104,7 +105,7 @@ Item {
Connections {
target: RootStore.walletSectionInst
function onTxDecoded(txHash: string, dataDecoded: string) {
if (!root.isTransactionValid || (d.isDetailsValid && txHash !== d.details.txHash))
if (!root.isTransactionValid || (d.isDetailsValid && txHash !== d.details.txHashOut))
return
if (!dataDecoded) {
d.loadingInputDate = false
@ -174,8 +175,8 @@ Item {
inNetworkTimestamp: root.isTransactionValid ? root.transaction.timestamp : 0
outChainName: transactionHeader.isMultiTransaction ? transactionHeader.networkNameOut : transactionHeader.networkName
inChainName: transactionHeader.isMultiTransaction && d.isBridge ? transactionHeader.networkNameIn : ""
outNetworkConfirmations: root.isTransactionValid && latestBlockNumber > 0 ? latestBlockNumber - d.blockNumber : 0
inNetworkConfirmations: root.isTransactionValid && latestBlockNumberIn > 0 ? latestBlockNumberIn - d.blockNumber : 0
outNetworkConfirmations: root.isTransactionValid && latestBlockNumber > 0 ? latestBlockNumber - d.blockNumberOut : 0
inNetworkConfirmations: root.isTransactionValid && latestBlockNumberIn > 0 ? latestBlockNumberIn - d.blockNumberIn : 0
}
Separator {
@ -292,7 +293,7 @@ Item {
}
TransactionDataTile {
id: contractDeploymentTile
readonly property bool hasValue: d.isDetailsValid && !!d.details.contract
readonly property bool hasValue: d.isDetailsValid && !!d.details.contractOut
&& transactionHeader.transactionStatus !== Constants.TransactionStatus.Pending
&& transactionHeader.transactionStatus !== Constants.TransactionStatus.Failed
width: parent.width
@ -340,7 +341,7 @@ Item {
TransactionDataTile {
width: parent.width
title: qsTr("%1 Tx hash").arg(transactionHeader.networkName)
subTitle: d.isDetailsValid ? d.details.txHash : ""
subTitle: d.isDetailsValid ? d.details.txHashOut : ""
visible: !!subTitle
buttonIconName: "more"
onButtonClicked: addressMenu.openTxMenu(this, subTitle, [d.networkShortName])
@ -348,22 +349,22 @@ Item {
TransactionDataTile {
width: parent.width
title: qsTr("%1 Tx hash").arg(transactionHeader.networkNameIn)
subTitle: "" // TODO fill tx hash for Bridge
subTitle: d.isDetailsValid ? d.details.txHashIn : ""
visible: !!subTitle
buttonIconName: "more"
onButtonClicked: addressMenu.openTxMenu(this, subTitle, [d.networkShortNameIn])
}
TransactionContractTile {
// Used for Bridge and Swap to display 'From' network Protocol contract address
address: "" // TODO fill protocol contract address for 'from' network for Bridge and Swap
symbol: "" // TODO fill protocol name for Bridge and Swap
networkName: transactionHeader.networkName
shortNetworkName: d.networkShortName
visible: !!subTitle && (d.transactionType === Constants.TransactionType.Bridge || d.transactionType === Constants.TransactionType.Swap)
}
// TransactionContractTile {
// // Used for Bridge and Swap to display 'From' network Protocol contract address
// address: "" // TODO fill protocol contract address for 'from' network for Bridge and Swap
// symbol: "" // TODO fill protocol name for Bridge and Swap
// networkName: transactionHeader.networkName
// shortNetworkName: d.networkShortName
// visible: !!subTitle && (d.transactionType === Constants.TransactionType.Bridge || d.transactionType === Constants.TransactionType.Swap)
// }
TransactionContractTile {
// Used to display contract address for any network
address: d.isDetailsValid ? d.details.contract : ""
address: d.isDetailsValid ? d.details.contractIn : ""
symbol: {
if (!root.isTransactionValid)
return ""
@ -373,14 +374,14 @@ Item {
shortNetworkName: d.networkShortName
visible: !!subTitle && d.transactionType !== Constants.TransactionType.ContractDeployment
}
TransactionContractTile {
// Used for Bridge to display 'To' network Protocol contract address
address: "" // TODO fill protocol contract address for 'to' network for Bridge
symbol: "" // TODO fill protocol name for Bridge
networkName: transactionHeader.networkNameOut
shortNetworkName: d.networkShortNameOut
visible: !!subTitle && d.transactionType === Constants.TransactionType.Bridge
}
// TransactionContractTile {
// // Used for Bridge to display 'To' network Protocol contract address
// address: "" // TODO fill protocol contract address for 'to' network for Bridge
// symbol: "" // TODO fill protocol name for Bridge
// networkName: transactionHeader.networkNameOut
// shortNetworkName: d.networkShortNameOut
// visible: !!subTitle && d.transactionType === Constants.TransactionType.Bridge
// }
TransactionContractTile {
// Used for Bridge and Swap to display 'To' network token contract address
address: {
@ -388,9 +389,8 @@ Item {
return ""
switch(d.transactionType) {
case Constants.TransactionType.Swap:
return "" // TODO fill swap contract address for Swap
case Constants.TransactionType.Bridge:
return "" // TODO fill swap token's contract address for 'to' network for Bridge
return d.isDetailsValid ? d.details.contractOut : ""
default:
return ""
}
@ -541,18 +541,22 @@ Item {
}
}
TransactionDataTile {
// Tile used only for multiTx
width: parent.width
title: !!transactionHeader.networkName ? qsTr("Included in Block on %1").arg(transactionHeader.networkName) : qsTr("Included on Block")
subTitle: d.blockNumber
title: !!transactionHeader.networkNameOut ? qsTr("Included in Block on %1").arg(transactionHeader.networkNameOut) : qsTr("Included on Block")
subTitle: d.blockNumberOut
tertiaryTitle: root.isTransactionValid ? LocaleUtils.formatDateTime(transaction.timestamp * 1000, Locale.LongFormat) : ""
visible: d.blockNumber > 0
visible: d.blockNumberOut > 0 && transactionHeader.isMultiTransaction
}
TransactionDataTile {
// Tile used for multiTx and normal tx
width: parent.width
title: !!d.toNetworkName ? qsTr("Included in Block on %1").arg(d.toNetworkName) : qsTr("Included on Block")
subTitle: d.toBlockNumber
readonly property int blockNumber: transactionHeader.isMultiTransaction ? d.blockNumberIn : d.blockNumber
readonly property string networkName: transactionHeader.isMultiTransaction ? transactionHeader.networkNameIn : transactionHeader.networkName
title: !!networkName ? qsTr("Included in Block on %1").arg(networkName) : qsTr("Included on Block")
subTitle: blockNumber
tertiaryTitle: root.isTransactionValid ? LocaleUtils.formatDateTime(transaction.timestamp * 1000, Locale.LongFormat) : ""
visible: d.toBlockNumber > 0
visible: blockNumber > 0
}
}
}
@ -614,7 +618,7 @@ Item {
return RootStore.formatCurrencyAmount(transactionHeader.inCryptoValue, d.inSymbol)
} else if (type === Constants.TransactionType.Bridge) {
// Reduce crypto value by fee value
const valueInCrypto = RootStore.getCryptoValue(transactionHeader.fiatValue - d.feeFiatValue, d.inSymbol, RootStore.currentCurrency)
const valueInCrypto = RootStore.getCryptoValue(transactionHeader.outFiatValue - d.feeFiatValue, d.inSymbol, RootStore.currentCurrency)
return RootStore.formatCurrencyAmount(valueInCrypto, d.inSymbol)
}
return ""
@ -624,7 +628,7 @@ Item {
if (type === Constants.TransactionType.Swap) {
return RootStore.formatCurrencyAmount(transactionHeader.inFiatValue, RootStore.currentCurrency)
} else if (type === Constants.TransactionType.Bridge) {
return RootStore.formatCurrencyAmount(transactionHeader.fiatValue - d.feeFiatValue, RootStore.currentCurrency)
return RootStore.formatCurrencyAmount(transactionHeader.outFiatValue - d.feeFiatValue, RootStore.currentCurrency)
}
return ""
}

View File

@ -279,7 +279,7 @@ StatusListItem {
const confirmationTimeStamp = WalletUtils.calculateConfirmationTimestamp(networkLayer, modelData.timestamp)
const finalisationTimeStamp = WalletUtils.calculateFinalisationTimestamp(networkLayer, modelData.timestamp)
details += qsTr("Status") + endl
const epoch = Math.abs(walletRootStore.getEstimatedLatestBlockNumber(modelData.chainId) - detailsObj.blockNumber)
const epoch = Math.abs(walletRootStore.getEstimatedLatestBlockNumber(modelData.chainId) - detailsObj.blockNumberOut)
details += qsTr("Finalised in epoch %1 on %2").arg(epoch.toFixed(0)).arg(root.networkName) + endl2
details += qsTr("Signed on %1").arg(root.networkName) + endl + timestampString + endl2
details += qsTr("Confirmed on %1").arg(root.networkName) + endl
@ -290,7 +290,7 @@ StatusListItem {
const networkInLayer = rootStore.getNetworkLayer(modelData.chainIdIn)
const confirmationTimeStampIn = WalletUtils.calculateConfirmationTimestamp(networkInLayer, modelData.timestamp)
const finalisationTimeStampIn = WalletUtils.calculateFinalisationTimestamp(networkInLayer, modelData.timestamp)
const epochIn = Math.abs(walletRootStore.getEstimatedLatestBlockNumber(modelData.chainIdIn) - detailsObj.blockNumber)
const epochIn = Math.abs(walletRootStore.getEstimatedLatestBlockNumber(modelData.chainIdIn) - detailsObj.blockNumberIn)
details += qsTr("Finalised in epoch %1 on %2").arg(epochIn.toFixed(0)).arg(root.networkNameIn) + endl2
details += qsTr("Signed on %1").arg(root.networkNameIn) + endl + timestampString + endl2
details += qsTr("Confirmed on %1").arg(root.networkNameIn) + endl
@ -337,12 +337,11 @@ StatusListItem {
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
if (!!detailsObj.txHashOut) {
details += qsTr("%1 Tx hash").arg(root.networkName) + endl + detailsObj.txHashOut + endl2
}
const bridgeTxHash = "" // TODO fill tx hash for Bridge
if (!!bridgeTxHash) {
details += qsTr("%1 Tx hash").arg(networkNameOut) + endl + bridgeTxHash + endl2
if (!!detailsObj.txHashIn) {
details += qsTr("%1 Tx hash").arg(networkNameIn) + endl + detailsObj.txHashIn + endl2
}
const protocolFromContractAddress = "" // TODO fill protocol contract address for 'from' network for Bridge and Swap
if (!!detailsObj.protocol && !!protocolFromContractAddress) {
@ -359,19 +358,17 @@ StatusListItem {
details += qsTr("%1 %2 contract address").arg(networkNameOut).arg(detailsObj.protocol) + endl
details += protocolToContractAddress + endl2
}
const swapContractAddress = "" // TODO fill swap contract address for Swap
const bridgeContractAddress = "" // TODO fill token's contract address for 'to' network for Bridge
switch (type) {
case Constants.TransactionType.Swap:
if (!!swapContractAddress) {
if (!!detailsObj.contractOut) {
details += qsTr("%1 %2 contract address").arg(root.networkName).arg(modelData.toSymbol) + endl
details += swapContractAddress + endl2
details += detailsObj.contractOut + endl2
}
break
case Constants.TransactionType.Bridge:
if (!!bridgeContractAddress) {
if (!!detailsObj.contractOut) {
details += qsTr("%1 %2 contract address").arg(networkNameOut).arg(modelData.symbol) + endl
details += bridgeContractAddress + endl2
details += detailsObj.contractOut + endl2
}
break
default:
@ -388,14 +385,13 @@ StatusListItem {
details += qsTr("Nonce") + endl + detailsObj.nonce + endl2
if (type === Constants.TransactionType.Bridge) {
details += qsTr("Included in Block on %1").arg(networkName) + endl
details += detailsObj.blockNumber + endl2
const bridgeBlockNumber = 0 // TODO fill when bridge data is implemented
if (bridgeBlockNumber > 0) {
details += detailsObj.blockNumberOut + endl2
if (detailsObj.blockNumberIn > 0) {
details += qsTr("Included in Block on %1").arg(networkNameOut) + endl
details += bridgeBlockNumber + endl2
details += detailsObj.blockNumberIn + endl2
}
} else {
details += qsTr("Included in Block") + endl + detailsObj.blockNumber + endl2
details += qsTr("Included in Block") + endl + detailsObj.blockNumberOut + endl2
}
// VALUES

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit c433908834ad2d55e40b67da1cbd88014319315f
Subproject commit 9acabc69955b6a1884154a133083e62f05406892