fix(@desktop/wallet): estimated time for transaction is always Unknown
Fixes #5938
This commit is contained in:
parent
2251f870a0
commit
60ed62231e
|
@ -106,3 +106,6 @@ proc getChainIdForChat*(self: Controller): int =
|
|||
|
||||
proc getChainIdForBrowser*(self: Controller): int =
|
||||
return self.networkService.getNetworkForBrowser().chainId
|
||||
|
||||
proc getEstimatedTime*(self: Controller, priorityFeePerGas: string, maxFeePerGas: string): EstimatedTime =
|
||||
return self.transactionService.getEstimatedTime(priorityFeePerGas, maxFeePerGas)
|
|
@ -64,6 +64,9 @@ method getChainIdForChat*(self: AccessInterface): int =
|
|||
method getChainIdForBrowser*(self: AccessInterface): int =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getEstimatedTime*(self: AccessInterface, priorityFeePerGas: string, maxFeePerGas: string): int {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
# View Delegate Interface
|
||||
# Delegate for the view must be declared here due to use of QtObject and multi
|
||||
# inheritance, which is not well supported in Nim.
|
||||
|
|
|
@ -110,3 +110,6 @@ method getChainIdForChat*(self: Module): int =
|
|||
|
||||
method getChainIdForBrowser*(self: Module): int =
|
||||
return self.controller.getChainIdForBrowser()
|
||||
|
||||
method getEstimatedTime*(self: Module, priorityFeePerGas: string, maxFeePerGas: string): int =
|
||||
return self.controller.getEstimatedTime(priorityFeePerGas, maxFeePerGas).int
|
|
@ -140,3 +140,6 @@ QtObject:
|
|||
|
||||
proc getChainIdForBrowser*(self: View): int {.slot.} =
|
||||
return self.delegate.getChainIdForBrowser()
|
||||
|
||||
proc getEstimatedTime*(self: View, priorityFeePerGas: string, maxFeePerGas: string): int {.slot.} =
|
||||
return self.delegate.getEstimatedTime(priorityFeePerGas, maxFeePerGas)
|
|
@ -33,6 +33,13 @@ include ../../common/json_utils
|
|||
const SIGNAL_TRANSACTIONS_LOADED* = "transactionsLoaded"
|
||||
const SIGNAL_TRANSACTION_SENT* = "transactionSent"
|
||||
|
||||
type
|
||||
EstimatedTime* {.pure.} = enum
|
||||
Unknown = -1
|
||||
LessThanOneMin
|
||||
LessThanThreeMins
|
||||
LessThanFiveMins
|
||||
|
||||
type
|
||||
TransactionMinedArgs* = ref object of Args
|
||||
data*: string
|
||||
|
@ -394,3 +401,69 @@ QtObject:
|
|||
except Exception as e:
|
||||
error "Error fetching crypto services", message = e.msg
|
||||
return @[]
|
||||
|
||||
proc addToAllTransactionsAndSetNewMinMax(self: Service, myTip: float, numOfTransactionWithTipLessThanMine: var int,
|
||||
transactions: JsonNode) =
|
||||
if transactions.kind != JArray:
|
||||
return
|
||||
for t in transactions:
|
||||
let gasPriceUnparsed = $fromHex(Stuint[256], t{"gasPrice"}.getStr)
|
||||
let gasPrice = parseFloat(wei2gwei(gasPriceUnparsed))
|
||||
if gasPrice < myTip:
|
||||
numOfTransactionWithTipLessThanMine.inc
|
||||
|
||||
proc getEstimatedTime*(self: Service, priorityFeePerGas: string, maxFeePerGas: string): EstimatedTime =
|
||||
let priorityFeePerGasF = priorityFeePerGas.parseFloat
|
||||
let maxFeePerGasF = maxFeePerGas.parseFloat
|
||||
var transactionsProcessed = 0
|
||||
var numOfTransactionWithTipLessThanMine = 0
|
||||
var latestBlockNumber: Option[Uint256]
|
||||
var expectedBaseFeeForNextBlock: float
|
||||
try:
|
||||
let response = eth.getBlockByNumber("latest", true)
|
||||
if response.error.isNil:
|
||||
let transactionsJson = response.result{"transactions"}
|
||||
self.addToAllTransactionsAndSetNewMinMax(priorityFeePerGasF, numOfTransactionWithTipLessThanMine, transactionsJson)
|
||||
transactionsProcessed = transactionsJson.len
|
||||
latestBlockNumber = some(stint.fromHex(Uint256, response.result{"number"}.getStr))
|
||||
let latestBlockBaseFeePerGasUnparsed = $fromHex(Stuint[256], response.result{"baseFeePerGas"}.getStr)
|
||||
let latestBlockBaseFeePerGas = parseFloat(wei2gwei(latestBlockBaseFeePerGasUnparsed))
|
||||
let latestBlockGasUsedUnparsed = $fromHex(Stuint[256], response.result{"gasUsed"}.getStr)
|
||||
let latestBlockGasUsed = parseFloat(wei2gwei(latestBlockGasUsedUnparsed))
|
||||
let latestBlockGasLimitUnparsed = $fromHex(Stuint[256], response.result{"gasLimit"}.getStr)
|
||||
let latestBlockGasLimit = parseFloat(wei2gwei(latestBlockGasLimitUnparsed))
|
||||
|
||||
let ratio = latestBlockGasUsed / latestBlockGasLimit * 0.01
|
||||
let maxFeeChange = latestBlockBaseFeePerGas * 0.125
|
||||
if(ratio > 50):
|
||||
expectedBaseFeeForNextBlock = latestBlockBaseFeePerGas + maxFeeChange * (ratio - 50) * 0.01
|
||||
else:
|
||||
expectedBaseFeeForNextBlock = latestBlockBaseFeePerGas - maxFeeChange * (50 - ratio) * 0.01
|
||||
except Exception as e:
|
||||
error "error fetching latest block", msg=e.msg
|
||||
|
||||
if latestBlockNumber.isNone or
|
||||
priorityFeePerGasF + expectedBaseFeeForNextBlock > maxFeePerGasF:
|
||||
return EstimatedTime.Unknown
|
||||
|
||||
var blockNumber = latestBlockNumber.get
|
||||
while (transactionsProcessed < 100 and latestBlockNumber.get < blockNumber + 10):
|
||||
blockNumber = blockNumber - 1
|
||||
try:
|
||||
let hexPrevNum = "0x" & stint.toHex(blockNumber)
|
||||
let response = getBlockByNumber(hexPrevNum, true)
|
||||
let transactionsJson = response.result{"transactions"}
|
||||
self.addToAllTransactionsAndSetNewMinMax(priorityFeePerGasF, numOfTransactionWithTipLessThanMine, transactionsJson)
|
||||
transactionsProcessed += transactionsJson.len
|
||||
except Exception as e:
|
||||
error "error fetching block number", blockNumber=blockNumber, msg=e.msg
|
||||
|
||||
let p = numOfTransactionWithTipLessThanMine / transactionsProcessed
|
||||
if p > 0.5:
|
||||
return EstimatedTime.LessThanOneMin
|
||||
elif p > 0.35:
|
||||
return EstimatedTime.LessThanThreeMins
|
||||
elif p > 0.15:
|
||||
return EstimatedTime.LessThanFiveMins
|
||||
else:
|
||||
return EstimatedTime.Unknown
|
|
@ -6,8 +6,8 @@ export response_type
|
|||
proc getAccounts*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
return core.callPrivateRPC("eth_accounts")
|
||||
|
||||
proc getBlockByNumber*(blockNumber: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [blockNumber, false]
|
||||
proc getBlockByNumber*(blockNumber: string, fullTransactionObject = false): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [blockNumber, fullTransactionObject]
|
||||
return core.callPrivateRPC("eth_getBlockByNumber", payload)
|
||||
|
||||
proc getNativeChainBalance*(chainId: int, address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
|
|
|
@ -99,6 +99,10 @@ QtObject {
|
|||
return JSON.parse(walletSectionTransactions.suggestedFees(chainId))
|
||||
}
|
||||
|
||||
function getEstimatedTime(priorityFeePerGas, maxFeePerGas) {
|
||||
return walletSectionTransactions.getEstimatedTime(priorityFeePerGas, maxFeePerGas)
|
||||
}
|
||||
|
||||
function getChainIdForChat() {
|
||||
return walletSectionTransactions.getChainIdForChat()
|
||||
}
|
||||
|
|
|
@ -21,11 +21,13 @@ Item {
|
|||
property var getGasGweiValue: function () {}
|
||||
property var getGasEthValue: function () {}
|
||||
property var getFiatValue: function () {}
|
||||
property var getEstimatedTime: function () {}
|
||||
property string defaultCurrency: "USD"
|
||||
property alias selectedGasPrice: inputGasPrice.text
|
||||
property alias selectedGasLimit: inputGasLimit.text
|
||||
property string defaultGasLimit: "0"
|
||||
property string maxFiatFees: selectedGasFiatValue + root.defaultCurrency.toUpperCase()
|
||||
property int estimatedTxTimeFlag: Constants.transactionEstimatedTime.unknown
|
||||
|
||||
|
||||
property alias selectedTipLimit: inputPerGasTipLimit.text
|
||||
|
@ -62,11 +64,15 @@ Item {
|
|||
return
|
||||
|
||||
}
|
||||
|
||||
Qt.callLater(function () {
|
||||
let ethValue = root.getGasEthValue(inputGasPrice.text, inputGasLimit.text)
|
||||
|
||||
let fiatValue = root.getFiatValue(ethValue, "ETH", root.defaultCurrency)
|
||||
selectedGasEthValue = ethValue
|
||||
selectedGasFiatValue = fiatValue
|
||||
root.estimatedTxTimeFlag = root.getEstimatedTime(inputPerGasTipLimit.text, inputGasPrice.text)
|
||||
})
|
||||
}
|
||||
|
||||
function appendError(accum, error, nonBlocking = false) {
|
||||
|
@ -111,6 +117,11 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
updateGasEthValue()
|
||||
checkLimits()
|
||||
}
|
||||
|
||||
function validate() {
|
||||
// causes error on application load without a null check
|
||||
if (!inputGasLimit || !inputGasPrice || !inputPerGasTipLimit) {
|
||||
|
|
|
@ -176,6 +176,7 @@ StatusModal {
|
|||
anchors.top: networkSelector.bottom
|
||||
getGasEthValue: popup.store.getGasEthValue
|
||||
getFiatValue: popup.store.getFiatValue
|
||||
getEstimatedTime: popup.store.getEstimatedTime
|
||||
defaultCurrency: popup.store.currentCurrency
|
||||
|
||||
width: stack.width
|
||||
|
@ -239,6 +240,7 @@ StatusModal {
|
|||
|
||||
advancedFooterComponent: SendModalFooter {
|
||||
maxFiatFees: gasSelector.maxFiatFees
|
||||
estimatedTxTimeFlag: gasSelector.estimatedTxTimeFlag
|
||||
currentGroupPending: popup.contentItem.currentGroup.isPending
|
||||
currentGroupValid: popup.contentItem.currentGroup.isValid
|
||||
isLastGroup: popup.contentItem.isLastGroup
|
||||
|
|
|
@ -12,15 +12,18 @@ import StatusQ.Core.Theme 0.1
|
|||
Rectangle {
|
||||
id: footer
|
||||
|
||||
//% "Unknown"
|
||||
property string estimatedTime: qsTr("Unknown")
|
||||
property string maxFiatFees: ""
|
||||
property int estimatedTxTimeFlag: Constants.transactionEstimatedTime.unknown
|
||||
property bool currentGroupPending: true
|
||||
property bool currentGroupValid: false
|
||||
property bool isLastGroup: false
|
||||
|
||||
signal nextButtonClicked()
|
||||
|
||||
onEstimatedTxTimeFlagChanged: {
|
||||
estimatedTime.text = Utils.getLabelForEstimatedTxTime(estimatedTxTimeFlag)
|
||||
}
|
||||
|
||||
width: parent.width
|
||||
height: 82
|
||||
radius: 8
|
||||
|
@ -55,9 +58,9 @@ Rectangle {
|
|||
}
|
||||
// To-do not implemented yet
|
||||
StatusBaseText {
|
||||
id: estimatedTime
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.directColor1
|
||||
text: estimatedTime
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +82,7 @@ Rectangle {
|
|||
wrapMode: Text.WordWrap
|
||||
}
|
||||
StatusBaseText {
|
||||
id: fiatFees
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.directColor1
|
||||
text: maxFiatFees
|
||||
|
|
|
@ -189,6 +189,13 @@ QtObject {
|
|||
readonly property int success: 1
|
||||
}
|
||||
|
||||
readonly property QtObject transactionEstimatedTime: QtObject {
|
||||
readonly property int unknown: -1
|
||||
readonly property int lessThanOneMin: 0
|
||||
readonly property int lessThanThreeMins: 1
|
||||
readonly property int lessThanFiveMins: 2
|
||||
}
|
||||
|
||||
readonly property int communityImported: 0
|
||||
readonly property int communityImportingInProgress: 1
|
||||
readonly property int communityImportingError: 2
|
||||
|
|
|
@ -618,6 +618,19 @@ QtObject {
|
|||
|
||||
/* Validation section end */
|
||||
|
||||
function getLabelForEstimatedTxTime(estimatedFlag) {
|
||||
if (estimatedFlag === Constants.transactionEstimatedTime.lessThanOneMin) {
|
||||
return qsTr("< 1 min")
|
||||
}
|
||||
if (estimatedFlag === Constants.transactionEstimatedTime.lessThanThreeMins) {
|
||||
return qsTr("< 3 mins")
|
||||
}
|
||||
if (estimatedFlag === Constants.transactionEstimatedTime.lessThanFiveMins) {
|
||||
return qsTr("< 5 mins")
|
||||
}
|
||||
|
||||
return qsTr("> 5 mins")
|
||||
}
|
||||
|
||||
function getContactDetailsAsJson(publicKey) {
|
||||
let jsonObj = mainModule.getContactDetailsAsJson(publicKey)
|
||||
|
|
Loading…
Reference in New Issue