fix(wallet)_: Handle insufficient gas errors in multi-chain transactions

* Refactored gas checking logic into `getChainsWithNoGasFromError`.
* Removed `hasGas` from `controller.nim` and `module.nim`.
* Updated `updatedNetworksWithRoutes` to use chain-specific error data.

Fixes #15681
This commit is contained in:
belalshehab 2024-07-25 19:57:05 +03:00 committed by Belal Shehab
parent ff005a219a
commit 37f7b45274
5 changed files with 22 additions and 19 deletions

View File

@ -171,5 +171,5 @@ proc runSignFlow*(self: Controller, pin, bip44Path, txHash: string) =
self.connectKeycardReponseSignal()
self.keycardService.startSignFlow(bip44Path, txHash, pin)
proc hasGas*(self: Controller, accountAddress: string, chainId: int, nativeGasSymbol: string, requiredGas: float): bool =
return self.walletAccountService.hasGas(accountAddress, chainId, nativeGasSymbol, requiredGas)
proc getChainsWithNoGasFromError*(self: Controller, errCode: string, errDescription: string): Table[int, string] =
return self.walletAccountService.getChainsWithNoGasFromError(errCode, errDescription)

View File

@ -287,7 +287,7 @@ method suggestedRoutesReady*(self: Module, uuid: string, suggestedRoutes: Sugges
let networks = suggestedRoutes.toNetworks.map(x => self.convertSendToNetworkToNetworkItem(x))
let toNetworksRouteModel = newNetworkRouteModel()
toNetworksRouteModel.setItems(networks)
self.view.updatedNetworksWithRoutes(paths, gasTimeEstimate.getTotalFeesInEth())
self.view.updatedNetworksWithRoutes(paths, self.controller.getChainsWithNoGasFromError(errCode, errDescription))
let transactionRoutes = newTransactionRoutes(
uuid = uuid,
suggestedRoutes = suggestedRouteModel,
@ -392,8 +392,5 @@ method splitAndFormatAddressPrefix*(self: Module, text : string, updateInStore:
editedText = "<a><p>" & editedText & "</a></p>"
return editedText
method hasGas*(self: Module, accountAddress: string, chainId: int, nativeGasSymbol: string, requiredGas: float): bool =
return self.controller.hasGas(accountAddress, chainId, nativeGasSymbol, requiredGas)
method transactionSendingComplete*(self: Module, txHash: string, success: bool) =
self.view.sendtransactionSendingCompleteSignal(txHash, success)

View File

@ -239,14 +239,13 @@ QtObject:
proc updateRoutePreferredChains*(self: View, chainIds: string) {.slot.} =
self.toNetworksRouteModel.updateRoutePreferredChains(chainIds)
proc updatedNetworksWithRoutes*(self: View, paths: seq[SuggestedRouteItem], totalFeesInEth: float) =
proc updatedNetworksWithRoutes*(self: View, paths: seq[SuggestedRouteItem], chainsWithNoGas: Table[int, string]) =
self.fromNetworksRouteModel.resetPathData()
self.toNetworksRouteModel.resetPathData()
for path in paths:
let fromChainId = path.getfromNetwork()
let networkItem = self.delegate.getNetworkItem(fromChainId)
let hasGas = self.delegate.hasGas(self.selectedSenderAccountAddress, fromChainId, networkItem.nativeCurrencySymbol, totalFeesInEth)
self.fromNetworksRouteModel.updateFromNetworks(path, hasGas)
self.fromNetworksRouteModel.updateFromNetworks(path, not chainsWithNoGas.hasKey(fromChainId))
self.toNetworksRouteModel.updateToNetworks(path)
proc resetStoredProperties*(self: View) {.slot.} =
@ -332,4 +331,4 @@ QtObject:
self.delegate.notifySelectedSenderAccountChanged()
proc setReceiverAccount*(self: View, address: string) {.slot.} =
self.setSelectedReceiveAccountAddress(address)
self.setSelectedReceiveAccountAddress(address)

View File

@ -1,3 +1,5 @@
const noGasErrorCode = "WR-017"
# This method will group the account assets by symbol (in case of communiy, the token address)
proc onAllTokensBuilt*(self: Service, response: string) {.slot.} =
var accountAddresses: seq[string] = @[]
@ -115,14 +117,19 @@ proc getTokensMarketValuesLoading*(self: Service): bool =
proc getHasBalanceCache*(self: Service): bool =
return self.hasBalanceCache
proc hasGas*(self: Service, accountAddress: string, chainId: int, nativeGasSymbol: string, requiredGas: float): bool =
for token in self.groupedAccountsTokensList:
if token.symbol == nativeGasSymbol:
for balance in token.balancesPerAccount:
if balance.account == accountAddress and balance.chainId == chainId:
if(self.currencyService.parseCurrencyValue(nativeGasSymbol, balance.balance) >= requiredGas):
return true
return false
proc getChainsWithNoGasFromError*(self: Service, errCode: string, errDescription: string): Table[int, string] =
## Extracts the chainId and token from the error description for chains with no gas.
## If the error code is not "WR-017", an empty table is returned.
result = initTable[int, string]()
if errCode == noGasErrorCode:
try:
let jsonData = parseJson(errDescription)
let token: string = jsonData["token"].getStr()
let chainId: int = jsonData["chainId"].getInt()
result[chainId] = token
except Exception as e:
error "error: ", procName="getChainsWithNoGasFromError", errName=e.name, errDesription=e.msg
proc getCurrency*(self: Service): string =
return self.settingsService.getCurrency()

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit 977a93b0052974ade7f45f2b8f193c9998cc1462
Subproject commit 03cb3ad0ab9245f5c8437be5195b9261c5a14412