feat(@desktop/wallet): Implements and handles errors in the new simple send modal

fies #17000
This commit is contained in:
Khushboo Mehta 2024-12-20 11:30:24 +01:00
parent acb07859b0
commit 8ece500dde
5 changed files with 86 additions and 9 deletions

View File

@ -66,7 +66,19 @@ SplitView {
simpleSend.estimatedTime = "~60s" simpleSend.estimatedTime = "~60s"
simpleSend.estimatedFiatFees = "1.45 EUR" simpleSend.estimatedFiatFees = "1.45 EUR"
simpleSend.estimatedCryptoFees = "0.0007 ETH" simpleSend.estimatedCryptoFees = "0.0007 ETH"
simpleSend.routerErrorCode = Constants.routerErrorCodes.router.errNotEnoughNativeBalance
simpleSend.routerError = qsTr("Not enough ETH to pay gas fees")
simpleSend.routerErrorDetails = ""
}) })
function resetRouterValues() {
simpleSend.estimatedCryptoFees = ""
simpleSend.estimatedFiatFees = ""
simpleSend.estimatedTime = ""
simpleSend.routerErrorCode = ""
simpleSend.routerError = ""
simpleSend.routerErrorDetails = ""
}
} }
PopupBackground { PopupBackground {
@ -123,9 +135,7 @@ SplitView {
}) })
onFormChanged: { onFormChanged: {
estimatedCryptoFees = "" d.resetRouterValues()
estimatedFiatFees = ""
estimatedTime = ""
if(allValuesFilledCorrectly()) { if(allValuesFilledCorrectly()) {
console.log("Fetch fees...") console.log("Fetch fees...")
routesLoading = true routesLoading = true
@ -134,6 +144,7 @@ SplitView {
} }
onReviewSendClicked: console.log("Review send clicked") onReviewSendClicked: console.log("Review send clicked")
onLaunchBuyFlow: console.log("launch buy flow clicked")
Binding on selectedAccountAddress { Binding on selectedAccountAddress {
value: accountsCombobox.currentValue ?? "" value: accountsCombobox.currentValue ?? ""

View File

@ -142,7 +142,7 @@ QtObject {
case Constants.routerErrorCodes.router.errNotEnoughTokenBalance: case Constants.routerErrorCodes.router.errNotEnoughTokenBalance:
return qsTr("not enough token balance") return qsTr("not enough token balance")
case Constants.routerErrorCodes.router.errNotEnoughNativeBalance: case Constants.routerErrorCodes.router.errNotEnoughNativeBalance:
return qsTr("not enough ETH") return qsTr("Not enough ETH to pay gas fees")
case Constants.routerErrorCodes.router.errLowAmountInForHopBridge: case Constants.routerErrorCodes.router.errLowAmountInForHopBridge:
return qsTr("amount in too low") return qsTr("amount in too low")
case Constants.routerErrorCodes.router.errNoPositiveBalance: case Constants.routerErrorCodes.router.errNoPositiveBalance:
@ -278,7 +278,6 @@ QtObject {
case Constants.routerErrorCodes.router.errCannotCheckLockedAmounts: case Constants.routerErrorCodes.router.errCannotCheckLockedAmounts:
return qsTr("cannot check locked amounts") return qsTr("cannot check locked amounts")
case Constants.routerErrorCodes.router.errNotEnoughTokenBalance: case Constants.routerErrorCodes.router.errNotEnoughTokenBalance:
case Constants.routerErrorCodes.router.errNotEnoughNativeBalance:
try { try {
const jsonObj = JSON.parse(details) const jsonObj = JSON.parse(details)
@ -299,6 +298,8 @@ QtObject {
catch (e) { catch (e) {
return "" return ""
} }
case Constants.routerErrorCodes.router.errNotEnoughNativeBalance:
return details
case Constants.routerErrorCodes.router.errLowAmountInForHopBridge: case Constants.routerErrorCodes.router.errLowAmountInForHopBridge:
return qsTr("bonder fee greater than estimated received, a higher amount is needed to cover fees") return qsTr("bonder fee greater than estimated received, a higher amount is needed to cover fees")
case Constants.routerErrorCodes.router.errNoPositiveBalance: case Constants.routerErrorCodes.router.errNoPositiveBalance:

View File

@ -1,5 +1,6 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Layouts 1.14 import QtQuick.Layouts 1.14
import QtQml.Models 2.15
import StatusQ 0.1 import StatusQ 0.1
import StatusQ.Core 0.1 import StatusQ.Core 0.1
@ -90,6 +91,12 @@ StatusDialog {
property string estimatedFiatFees property string estimatedFiatFees
/** input property to set estimated fees in crypto **/ /** input property to set estimated fees in crypto **/
property string estimatedCryptoFees property string estimatedCryptoFees
/** input property to set router error title **/
property string routerError: ""
/** input property to set router error details **/
property string routerErrorDetails: ""
/** input property to set router error code **/
property string routerErrorCode
/** property to set currently selected send type **/ /** property to set currently selected send type **/
property string sendType: Constants.SendType.Transfer property string sendType: Constants.SendType.Transfer
@ -122,6 +129,8 @@ StatusDialog {
signal reviewSendClicked() signal reviewSendClicked()
/** Output signal to inform that the forms been updated **/ /** Output signal to inform that the forms been updated **/
signal formChanged() signal formChanged()
/** Output signal to launch buy flow **/
signal launchBuyFlow()
/** function exposed to check if the form is filled correctly **/ /** function exposed to check if the form is filled correctly **/
function allValuesFilledCorrectly() { function allValuesFilledCorrectly() {
@ -229,6 +238,8 @@ StatusDialog {
root.selectedRecipientAddress, root.selectedRecipientAddress,
root.selectedAmount] root.selectedAmount]
onCombinedPropertyChangedHandlerChanged: Qt.callLater(() => root.formChanged()) onCombinedPropertyChangedHandlerChanged: Qt.callLater(() => root.formChanged())
readonly property bool errNotEnoughGas: root.routerErrorCode === Constants.routerErrorCodes.router.errNotEnoughNativeBalance
} }
width: 556 width: 556
@ -467,6 +478,7 @@ StatusDialog {
cryptoFees: root.estimatedCryptoFees cryptoFees: root.estimatedCryptoFees
fiatFees: root.estimatedFiatFees fiatFees: root.estimatedFiatFees
loading: root.routesLoading && root.allValuesFilledCorrectly() loading: root.routesLoading && root.allValuesFilledCorrectly()
error: d.errNotEnoughGas
} }
visible: root.allValuesFilledCorrectly() visible: root.allValuesFilledCorrectly()
} }
@ -480,8 +492,33 @@ StatusDialog {
estimateTime: root.estimatedTime estimateTime: root.estimatedTime
estimatedFees: root.estimatedFiatFees estimatedFees: root.estimatedFiatFees
error: d.errNotEnoughGas
errorTags: amountToSend.markAsInvalid || !!root.routerErrorCode ?
errorTagsModel: null
loading: root.routesLoading && root.allValuesFilledCorrectly() loading: root.routesLoading && root.allValuesFilledCorrectly()
onReviewSendClicked: root.reviewSendClicked() onReviewSendClicked: root.reviewSendClicked()
} }
ObjectModel {
id: errorTagsModel
RouterErrorTag {
errorTitle: qsTr("Insufficient funds for send transaction")
buttonText: qsTr("Add assets")
onButtonClicked: root.launchBuyFlow()
visible: amountToSend.markAsInvalid
}
RouterErrorTag {
errorTitle: root.routerError
errorDetails: !d.errNotEnoughGas ?
root.routerErrorDetails: ""
buttonText: qsTr("Add ETH")
expandable: !d.errNotEnoughGas
onButtonClicked: root.launchBuyFlow()
visible: !!root.routerErrorCode
}
}
} }

View File

@ -44,6 +44,7 @@ import AppLayouts.Communities.stores 1.0
import AppLayouts.Profile.stores 1.0 as ProfileStores import AppLayouts.Profile.stores 1.0 as ProfileStores
import AppLayouts.Wallet.popups 1.0 as WalletPopups import AppLayouts.Wallet.popups 1.0 as WalletPopups
import AppLayouts.Wallet.popups.dapps 1.0 as DAppsPopups import AppLayouts.Wallet.popups.dapps 1.0 as DAppsPopups
import AppLayouts.Wallet.popups.buy 1.0
import AppLayouts.Wallet.stores 1.0 as WalletStores import AppLayouts.Wallet.stores 1.0 as WalletStores
import AppLayouts.stores 1.0 as AppStores import AppLayouts.stores 1.0 as AppStores
@ -601,6 +602,9 @@ Item {
} }
return username return username
} }
// TODO: Remove this and adapt new mechanism to launch BuyModal as done for SendModal
property BuyCryptoParamsForm buyFormData: BuyCryptoParamsForm {}
} }
Settings { Settings {
@ -683,6 +687,13 @@ Item {
savedAddressesModel: WalletStores.RootStore.savedAddresses savedAddressesModel: WalletStores.RootStore.savedAddresses
recentRecipientsModel: appMain.transactionStore.tempActivityController1Model recentRecipientsModel: appMain.transactionStore.tempActivityController1Model
onLaunchBuyFlowRequested: {
d.buyFormData.selectedWalletAddress = accountAddress
d.buyFormData.selectedNetworkChainId = chainId
d.buyFormData.selectedTokenKey = tokenKey
Global.openBuyCryptoModalRequested(d.buyFormData)
}
Component.onCompleted: { Component.onCompleted: {
// It's requested from many nested places, so as a workaround we use // It's requested from many nested places, so as a workaround we use
// Global to shorten the path via global signal. // Global to shorten the path via global signal.

View File

@ -107,6 +107,8 @@ QtObject {
/** required signal to receive resolved ens name address **/ /** required signal to receive resolved ens name address **/
signal ensNameResolved(string resolvedPubKey, string resolvedAddress, string uuid) signal ensNameResolved(string resolvedPubKey, string resolvedAddress, string uuid)
signal launchBuyFlowRequested(string accountAddress, string chainId, string tokenKey)
function openSend(params = {}) { function openSend(params = {}) {
// TODO remove once simple send is feature complete // TODO remove once simple send is feature complete
let sendModalCmp = root.simpleSendEnabled ? simpleSendModalComponent: sendModalComponent let sendModalCmp = root.simpleSendEnabled ? simpleSendModalComponent: sendModalComponent
@ -250,9 +252,7 @@ QtObject {
} }
onFormChanged: { onFormChanged: {
estimatedCryptoFees = "" backendHandler.resetRouterValues()
estimatedFiatFees = ""
estimatedTime = ""
if(allValuesFilledCorrectly()) { if(allValuesFilledCorrectly()) {
backendHandler.uuid = Utils.uuid() backendHandler.uuid = Utils.uuid()
simpleSendModal.routesLoading = true simpleSendModal.routesLoading = true
@ -268,7 +268,11 @@ QtObject {
// TODO: this should be called from the Reiew and Sign Modal instead // TODO: this should be called from the Reiew and Sign Modal instead
onReviewSendClicked: { onReviewSendClicked: {
root.transactionStoreNew.authenticateAndTransfer(uuid, selectedAccountAddress) root.transactionStoreNew.authenticateAndTransfer(backendHandler.uuid, selectedAccountAddress)
}
onLaunchBuyFlow: {
root.launchBuyFlowRequested(selectedAccountAddress, selectedChainId, selectedTokenKey)
} }
readonly property var backendHandler: QtObject { readonly property var backendHandler: QtObject {
@ -286,6 +290,10 @@ QtObject {
// Suggested routes for a different fetch, ignore // Suggested routes for a different fetch, ignore
return return
} }
simpleSendModal.routerErrorCode = errCode
simpleSendModal.routerError = WalletUtils.getRouterErrorBasedOnCode(errCode)
simpleSendModal.routerErrorDetails = "%1 - %2".arg(errCode).arg(
WalletUtils.getRouterErrorDetailsOnCode(errCode, errDescription))
fetchedPathModel = pathModel fetchedPathModel = pathModel
// TODO: Handle errors here // TODO: Handle errors here
} }
@ -377,6 +385,15 @@ QtObject {
root.transactionStoreNew.suggestedRoutesReady.connect(routesFetched) root.transactionStoreNew.suggestedRoutesReady.connect(routesFetched)
root.transactionStoreNew.transactionSent.connect(transactionSent) root.transactionStoreNew.transactionSent.connect(transactionSent)
} }
function resetRouterValues() {
simpleSendModal.estimatedCryptoFees = ""
simpleSendModal.estimatedFiatFees = ""
simpleSendModal.estimatedTime = ""
simpleSendModal.routerErrorCode = ""
simpleSendModal.routerError = ""
simpleSendModal.routerErrorDetails = ""
}
} }
} }
} }