feat(@wallet): Display parsed input data

fixes #10793
This commit is contained in:
Emil Sawicki 2023-06-07 16:16:23 +02:00 committed by Anthony Laibe
parent c7ab998ea8
commit 54ae6a3154
5 changed files with 101 additions and 14 deletions

View File

@ -230,16 +230,12 @@ type
const fetchDecodedTxDataTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = const fetchDecodedTxDataTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[FetchDecodedTxDataTaskArg](argEncoded) let arg = decode[FetchDecodedTxDataTaskArg](argEncoded)
var data = %* {
"txHash": arg.txHash
}
try: try:
let response = backend.fetchDecodedTxData(arg.data) let response = backend.fetchDecodedTxData(arg.data)
arg.finish(%* { data["result"] = response.result
"txHash": arg.txHash,
"result": $response.result,
})
except Exception as e: except Exception as e:
error "Error decoding tx input", message = e.msg error "Error decoding tx input", message = e.msg
arg.finish(%* { arg.finish(data)
"txHash": arg.txHash,
"result": "",
})

View File

@ -225,10 +225,17 @@ QtObject:
) )
self.threadpool.start(arg) self.threadpool.start(arg)
proc onFetchDecodedTxData*(self: Service, response: string) {.slot.} = proc onFetchDecodedTxData*(self: Service, response: string) {.slot.} =
var args = TransactionDecodedArgs()
try:
let data = parseJson(response) let data = parseJson(response)
self.events.emit(SIGNAL_TRANSACTION_DECODED, TransactionDecodedArgs(dataDecoded: data["result"].getStr, txHash: data["txHash"].getStr)) if data.hasKey("result"):
args.dataDecoded = $data["result"]
if data.hasKey("txHash"):
args.txHash = data["txHash"].getStr
except Exception as e:
error "Error parsing decoded tx input data", msg = e.msg
self.events.emit(SIGNAL_TRANSACTION_DECODED, args)
proc fetchDecodedTxData*(self: Service, txHash: string, data: string) = proc fetchDecodedTxData*(self: Service, txHash: string, data: string) =
let arg = FetchDecodedTxDataTaskArg( let arg = FetchDecodedTxDataTaskArg(

View File

@ -38,6 +38,7 @@ SplitView {
RootStore.getGasEthValue = (gasAmount, gasPrice) => { return (gasAmount * Math.pow(10, -9)).toPrecision(5) } RootStore.getGasEthValue = (gasAmount, gasPrice) => { return (gasAmount * Math.pow(10, -9)).toPrecision(5) }
RootStore.getNetworkLayer = (chainId) => { return 1 } RootStore.getNetworkLayer = (chainId) => { return 1 }
RootStore.currentCurrency = "USD" RootStore.currentCurrency = "USD"
RootStore.history = historyMockup
root.rootStoreReady = true root.rootStoreReady = true
} }
@ -102,6 +103,37 @@ SplitView {
} }
} }
QtObject {
id: historyMockup
signal txDecoded(txHash: string, dataDecoded: string)
function fetchDecodedTxData(txHash, input) {
decodeTimer.txHash = txHash
decodeTimer.start()
}
readonly property Timer decodeTimer: Timer {
id: decodeTimer
property string txHash: ""
interval: 2000
onTriggered: {
const data = JSON.stringify({
name: "processDepositQueue",
signature: "processDepositQueue(address,uint256)",
id: "0xf94d2",
inputs: {
"0": "0x3030303030303030303030303637306463613632",
"1": "0x40e8d703000000000000000",
"2": "0x60d8f57dh0bcdd0da0a00ad000000",
"3": "0xd8ff5ba7fhfaafbf0fdfa0afaf1d000000"
}
})
historyMockup.txDecoded(txHash, data)
}
}
}
QtObject { QtObject {
id: transactionData id: transactionData
@ -115,7 +147,7 @@ SplitView {
property string to: "0x4de3f6278C0DdFd3F29df9DcD979038F5c7bbc35" property string to: "0x4de3f6278C0DdFd3F29df9DcD979038F5c7bbc35"
property string contract: "0x4de3f6278C0DdFd3F29df9DcD979038F5c7bbc35" property string contract: "0x4de3f6278C0DdFd3F29df9DcD979038F5c7bbc35"
property bool isNFT: false property bool isNFT: false
property string input: "0xdasdja214i12r0uf0jh013rfj01rfj12-09fuj12f012fuj0-129fuj012ujf1209u120912er902iue30912e" property string input: "0x40e8d703000000000000000000000000670dca62b3418bddd08cbc69cb4490a5a3382a9f0000000000000000000000000000000000000000000000000000000000000064ddd08cbc69cb4490a5a3382a9f0000000000"
property string tokenID: "4981676894159712808201908443964193325271219637660871887967796332739046670337" property string tokenID: "4981676894159712808201908443964193325271219637660871887967796332739046670337"
property string nftName: "Happy Meow" property string nftName: "Happy Meow"
property string nftImageUrl: Style.png("collectibles/HappyMeow") property string nftImageUrl: Style.png("collectibles/HappyMeow")

View File

@ -12,6 +12,7 @@ QtObject {
property var currentCurrency property var currentCurrency
property var currencyStore property var currencyStore
property var history
property var getNetworkIcon property var getNetworkIcon
property var getFiatValue property var getFiatValue

View File

@ -30,6 +30,13 @@ Item {
property var sendModal property var sendModal
readonly property bool isTransactionValid: transaction !== undefined && !!transaction readonly property bool isTransactionValid: transaction !== undefined && !!transaction
onTransactionChanged: {
d.decodedInputData = ""
if (!transaction || !transaction.input || !RootStore.history)
return
RootStore.history.fetchDecodedTxData(transaction.txHash, transaction.input)
}
QtObject { QtObject {
id: d id: d
readonly property bool isIncoming: root.isTransactionValid ? root.transaction.recipient.toLowerCase() === root.overview.mixedcaseAddress.toLowerCase() : false readonly property bool isIncoming: root.isTransactionValid ? root.transaction.recipient.toLowerCase() === root.overview.mixedcaseAddress.toLowerCase() : false
@ -60,6 +67,8 @@ Item {
readonly property real feeFiatValue: root.isTransactionValid ? RootStore.getFiatValue(d.feeEthValue, "ETH", RootStore.currentCurrency) : 0 readonly property real feeFiatValue: root.isTransactionValid ? RootStore.getFiatValue(d.feeEthValue, "ETH", RootStore.currentCurrency) : 0
readonly property int transactionType: root.isTransactionValid ? transaction.txType : Constants.TransactionType.Send readonly property int transactionType: root.isTransactionValid ? transaction.txType : Constants.TransactionType.Send
property string decodedInputData: ""
function getNameForSavedWalletAddress(address) { function getNameForSavedWalletAddress(address) {
return RootStore.getNameForSavedWalletAddress(address) return RootStore.getNameForSavedWalletAddress(address)
} }
@ -69,6 +78,25 @@ Item {
} }
} }
Connections {
target: RootStore.history
function onTxDecoded(txHash: string, dataDecoded: string) {
if (!root.isTransactionValid || txHash !== root.transaction.txHash || !dataDecoded)
return
try {
const decodedObject = JSON.parse(dataDecoded)
let text = qsTr("Function: %1").arg(decodedObject.signature)
text += "\n" + qsTr("MethodID: %1").arg(decodedObject.id)
for (const [key, value] of Object.entries(decodedObject.inputs)) {
text += "\n[%1]: %2".arg(key).arg(value)
}
d.decodedInputData = text
} catch(e) {
console.error("Failed to parse decoded tx data. Data:", dataDecoded)
}
}
}
StatusScrollView { StatusScrollView {
id: scrollView id: scrollView
anchors.fill: parent anchors.fill: parent
@ -386,12 +414,35 @@ Item {
} }
} }
TransactionDataTile { TransactionDataTile {
id: inputDataTile
width: parent.width width: parent.width
height: Math.min(implicitHeight + bottomPadding, 112)
title: qsTr("Input data") title: qsTr("Input data")
subTitle: root.isTransactionValid ? root.transaction.input : "" subTitle: {
if (!!d.decodedInputData) {
return d.decodedInputData
} else if (root.isTransactionValid) {
return root.transaction.input
}
return ""
}
visible: !!subTitle visible: !!subTitle
buttonIconName: "more" buttonIconName: "more"
statusListItemSubTitle.maximumLineCount: 4
statusListItemSubTitle.lineHeight: 1.21
onButtonClicked: addressMenu.openInputDataMenu(this, subTitle) onButtonClicked: addressMenu.openInputDataMenu(this, subTitle)
statusListItemSubTitle.layer.enabled: statusListItemSubTitle.lineCount > 3
statusListItemSubTitle.layer.effect: OpacityMask {
maskSource: Rectangle {
width: 10
height: 10
gradient: Gradient {
GradientStop { position: 0.0; color: "#f00" }
GradientStop { position: 0.4; color: "#a0ff0000" }
GradientStop { position: 0.75; color: "#00ff0000" }
}
}
}
} }
TransactionDataTile { TransactionDataTile {
width: parent.width width: parent.width