feat(@desktop/wallet): Implements auto refresh

fixes #14952
This commit is contained in:
Khushboo Mehta 2024-07-04 00:08:03 +02:00 committed by Khushboo-dev-cpp
parent 3049c6016b
commit 2df35ff0c9
8 changed files with 74 additions and 40 deletions

View File

@ -150,11 +150,7 @@ Item {
// verify loading state was set and no errors currently
verify(!root.swapAdaptor.validSwapProposalReceived)
verify(root.swapAdaptor.swapProposalLoading)
compare(root.swapAdaptor.swapOutputData.fromTokenAmount, "")
compare(root.swapAdaptor.swapOutputData.toTokenAmount, "")
compare(root.swapAdaptor.swapOutputData.totalFees, 0)
compare(root.swapAdaptor.swapOutputData.bestRoutes, [])
compare(root.swapAdaptor.swapOutputData.approvalNeeded, false)
compare(root.swapAdaptor.swapOutputData.rawPaths, [])
compare(root.swapAdaptor.swapOutputData.hasError, false)
// verfy input and output panels
@ -589,7 +585,6 @@ Item {
compare(root.swapAdaptor.swapOutputData.fromTokenAmount, "")
compare(root.swapAdaptor.swapOutputData.toTokenAmount, "")
compare(root.swapAdaptor.swapOutputData.totalFees, 0)
compare(root.swapAdaptor.swapOutputData.bestRoutes, [])
compare(root.swapAdaptor.swapOutputData.approvalNeeded, false)
compare(root.swapAdaptor.swapOutputData.hasError, true)
verify(errorTag.visible)
@ -638,7 +633,6 @@ Item {
let totalFees = root.swapAdaptor.currencyStore.getFiatValue(gasTimeEstimate.totalFeesInEth, Constants.ethToken) + totalTokenFeesInFiat
compare(root.swapAdaptor.swapOutputData.totalFees, totalFees)
compare(root.swapAdaptor.swapOutputData.bestRoutes, txRoutes.suggestedRoutes)
compare(root.swapAdaptor.swapOutputData.approvalNeeded, false)
compare(root.swapAdaptor.swapOutputData.hasError, false)
verify(!errorTag.visible)
@ -686,7 +680,6 @@ Item {
totalFees = root.swapAdaptor.currencyStore.getFiatValue(gasTimeEstimate.totalFeesInEth, Constants.ethToken) + totalTokenFeesInFiat
compare(root.swapAdaptor.swapOutputData.totalFees, totalFees)
compare(root.swapAdaptor.swapOutputData.bestRoutes, txRoutes2.suggestedRoutes)
compare(root.swapAdaptor.swapOutputData.approvalNeeded, true)
compare(root.swapAdaptor.swapOutputData.hasError, false)
verify(!errorTag.visible)
@ -1333,7 +1326,6 @@ Item {
SQUtils.AmountsArithmetic.fromString(txRoutes.amountToReceive),
SQUtils.AmountsArithmetic.fromNumber(1, root.swapAdaptor.toToken.decimals)).toString())
compare(root.swapAdaptor.swapOutputData.totalFees, totalFees)
compare(root.swapAdaptor.swapOutputData.bestRoutes, txRoutes.suggestedRoutes)
compare(root.swapAdaptor.swapOutputData.hasError, false)
compare(root.swapAdaptor.swapOutputData.estimatedTime, bestPath.estimatedTime)
compare(root.swapAdaptor.swapOutputData.txProviderName, bestPath.bridgeName)
@ -1414,7 +1406,7 @@ Item {
let txHasRouteNoApproval = root.dummySwapTransactionRoutes.txHasRouteNoApproval
txHasRouteNoApproval.uuid = root.swapAdaptor.uuid
root.swapStore.suggestedRoutesReady(root.dummySwapTransactionRoutes.txHasRouteNoApproval)
root.swapStore.suggestedRoutesReady(txHasRouteNoApproval)
verify(!root.swapAdaptor.approvalPending)
verify(!root.swapAdaptor.approvalSuccessful)
@ -1571,5 +1563,29 @@ Item {
closeAndVerfyModal()
}
function test_auto_refresh() {
// Asset chosen but no pay value set state -------------------------------------------------------------------------------
root.swapFormData.fromTokenAmount = "0.0001"
root.swapFormData.selectedAccountAddress = "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240"
root.swapFormData.selectedNetworkChainId = 11155111
root.swapFormData.fromTokensKey = "ETH"
// for testing making it 1.5 seconds so as to not make tests running too long
root.swapFormData.autoRefreshTime = 1500
// Launch popup
launchAndVerfyModal()
// check if fetchSuggestedRoutes called
fetchSuggestedRoutesCalled.wait()
// emit routes ready
let txHasRouteNoApproval = root.dummySwapTransactionRoutes.txHasRouteNoApproval
txHasRouteNoApproval.uuid = root.swapAdaptor.uuid
root.swapStore.suggestedRoutesReady(txHasRouteNoApproval)
// check if fetch occurs automatically after 15 seconds
fetchSuggestedRoutesCalled.wait()
}
}
}

View File

@ -87,13 +87,16 @@ QtObject {
The obtained amount can be multiplied or compared.
Provided number is assumed to be an amount in basic units, an integer.
returns NaN in case the conversion fails.
*/
function fromString(numStr) {
console.assert(typeof numStr === "string")
const amount = new Big.Big(numStr)
// TODO: restore assert when permissions handled as bigints
//console.assert(amount.eq(amount.round()))
return amount
try {
return new Big.Big(numStr)
} catch(e) {
return NaN
}
}
/*!

View File

@ -63,6 +63,10 @@ Control {
property int swapExchangeButtonWidth: 44
property string caption: swapSide === SwapInputPanel.SwapSide.Pay ? qsTr("Pay") : qsTr("Receive")
function forceActiveFocus() {
amountToSendInput.input.forceActiveFocus()
}
enum SwapSide {
Pay = 0,
Receive = 1

View File

@ -19,6 +19,8 @@ QtObject {
// default token key
property string defaultToTokenKey: ""
// 15 seconds
property int autoRefreshTime: 15000
onSelectedAccountAddressChanged: root.formValuesChanged()
onSelectedNetworkChainIdChanged: root.formValuesChanged()
@ -50,15 +52,13 @@ QtObject {
}
function isFormFilledCorrectly() {
let bigIntNumber = SQUtils.AmountsArithmetic.fromString(root.fromTokenAmount)
return !!root.selectedAccountAddress &&
root.selectedNetworkChainId !== -1 &&
!!root.fromTokensKey && !!root.toTokenKey &&
((!!root.fromTokenAmount &&
!isNaN(SQUtils.AmountsArithmetic.fromString(root.fromTokenAmount)) &&
SQUtils.AmountsArithmetic.fromString(root.fromTokenAmount) > 0) ||
(!!root.toTokenAmount &&
!isNaN(SQUtils.AmountsArithmetic.fromString(root.toTokenAmount)) &&
SQUtils.AmountsArithmetic.fromString(root.toTokenAmount) > 0 )) &&
(!!root.fromTokenAmount &&
!isNaN(bigIntNumber) &&
SQUtils.AmountsArithmetic.cmp(bigIntNumber, 0) === 1) &&
root.selectedSlippage > 0
}
}

View File

@ -36,13 +36,20 @@ StatusDialog {
root.swapAdaptor.fetchSuggestedRoutes(payPanel.rawValue)
})
property Timer autoRefreshTimer: Timer {
interval: root.swapInputParamsForm.autoRefreshTime
running: false
repeat: false
onTriggered: d.fetchSuggestedRoutes()
}
function fetchSuggestedRoutes() {
if (payPanel.valueValid && root.swapInputParamsForm.isFormFilledCorrectly()) {
root.swapAdaptor.validSwapProposalReceived = false
root.swapAdaptor.swapProposalLoading = true
root.swapAdaptor.approvalPending = false
root.swapAdaptor.approvalSuccessful = false
root.swapAdaptor.swapOutputData.resetAllButReceivedTokenValuesForSwap()
root.swapAdaptor.swapOutputData.resetPathInfoAndError()
debounceFetchSuggestedRoutes()
}
}
@ -71,6 +78,10 @@ StatusDialog {
d.fetchSuggestedRoutes()
}
}
function onSuggestedRoutesReady() {
if(!root.swapAdaptor.swapProposalLoading)
d.autoRefreshTimer.restart()
}
}
Behavior on implicitHeight {
@ -257,6 +268,7 @@ StatusDialog {
root.swapInputParamsForm.fromTokenAmount = !!root.swapAdaptor.swapOutputData.toTokenAmount ? root.swapAdaptor.swapOutputData.toTokenAmount : root.swapInputParamsForm.toTokenAmount
root.swapInputParamsForm.toTokenKey = tempPayToken
root.swapInputParamsForm.toTokenAmount = tempPayAmount
payPanel.forceActiveFocus()
}
}
}

View File

@ -76,6 +76,8 @@ QObject {
filters: ValueFilter { roleName: "isTest"; value: root.swapStore.areTestNetworksEnabled }
}
signal suggestedRoutesReady()
QtObject {
id: d
@ -163,7 +165,6 @@ QObject {
// if valid route was found
if(txRoutes.suggestedRoutes.count === 1) {
root.validSwapProposalReceived = true
root.swapOutputData.bestRoutes = txRoutes.suggestedRoutes
root.swapOutputData.toTokenAmount = AmountsArithmetic.div(AmountsArithmetic.fromString(txRoutes.amountToReceive), AmountsArithmetic.fromNumber(1, root.toToken.decimals)).toString()
let gasTimeEstimate = txRoutes.gasTimeEstimate
@ -171,7 +172,7 @@ QObject {
if (!!root.fromToken && !!root.fromToken.marketDetails && !!root.fromToken.marketDetails.currencyPrice)
totalTokenFeesInFiat = gasTimeEstimate.totalTokenFees * root.fromToken.marketDetails.currencyPrice.amount
root.swapOutputData.totalFees = root.currencyStore.getFiatValue(gasTimeEstimate.totalFeesInEth, Constants.ethToken) + totalTokenFeesInFiat
let bestPath = ModelUtils.get(root.swapOutputData.bestRoutes, 0, "route")
let bestPath = ModelUtils.get(txRoutes.suggestedRoutes, 0, "route")
root.swapOutputData.approvalNeeded = !!bestPath ? bestPath.approvalRequired: false
root.swapOutputData.approvalGasFees = !!bestPath ? bestPath.approvalGasFees.toString() : ""
root.swapOutputData.approvalAmountRequired = !!bestPath ? bestPath.approvalAmountRequired: ""
@ -182,6 +183,7 @@ QObject {
else {
root.swapOutputData.hasError = true
}
root.suggestedRoutesReady()
}
function onTransactionSent(chainId, txHash, uuid, error) {
@ -247,12 +249,12 @@ QObject {
}
function fetchSuggestedRoutes(cryptoValueInRaw) {
root.swapFormData.toTokenAmount = ""
if (root.swapFormData.isFormFilledCorrectly() && !!cryptoValueInRaw) {
// Identify new swap with a different uuid
d.uuid = Utils.uuid()
root.swapProposalLoading = true
root.swapOutputData.reset()
let account = selectedAccountEntry.item
let accountAddress = account.address
@ -263,6 +265,7 @@ QObject {
disabledChainIds, disabledChainIds, Constants.SendType.Swap, "")
} else {
root.swapProposalLoading = false
root.swapOutputData.reset()
}
}

View File

@ -11,7 +11,6 @@ QtObject {
property string toTokenAmount: ""
// TODO: this should be string but backend gas_estimate_item.nim passes this as float
property real totalFees: 0
property var bestRoutes: []
property bool hasError
property var rawPaths: []
// need to check how this is done in new router v2, right now it is Enum type
@ -22,24 +21,22 @@ QtObject {
property string approvalAmountRequired
property string approvalContractAddress
function resetPathInfoAndError() {
root.hasError = false
root.rawPaths = []
}
function reset() {
root.fromTokenAmount = ""
root.toTokenAmount = ""
root.resetAllButReceivedTokenValuesForSwap()
}
function resetAllButReceivedTokenValuesForSwap() {
root.totalFees = 0
root.bestRoutes = []
root.approvalNeeded = false
root.hasError = false
root.rawPaths = []
root.txProviderName = ""
root.estimatedTime = Constants.TransactionEstimatedTime.Unknown
txProviderName = ""
approvalNeeded = false
approvalGasFees = ""
approvalAmountRequired = ""
approvalContractAddress = ""
root.totalFees = 0
root.approvalNeeded = false
root.approvalGasFees = ""
root.approvalAmountRequired = ""
root.approvalContractAddress = ""
resetPathInfoAndError()
}
}

View File

@ -351,7 +351,6 @@ StatusDialog {
Layout.maximumWidth: 60
titleText: qsTr("Max slippage:")
infoText: "%1%".arg(LocaleUtils.numberToLocaleString(root.swapSignApproveInputForm.selectedSlippage))
loading: root.loading
visible: !d.isApproveTx
}
}