diff --git a/apps/ledger-live-desktop/static/i18n/en/app.json b/apps/ledger-live-desktop/static/i18n/en/app.json index f20aed402c29..dfee194cc87f 100644 --- a/apps/ledger-live-desktop/static/i18n/en/app.json +++ b/apps/ledger-live-desktop/static/i18n/en/app.json @@ -5423,6 +5423,9 @@ "FeeNotLoaded": { "title": "Couldn't load fee rates. Please set manual fees" }, + "FeeNotLoadedSwap": { + "title": "Network fee estimation failed because of technical issues. Try again or change the assets." + }, "FeeRequired": { "title": "Fees are required" }, diff --git a/apps/ledger-live-mobile/src/locales/en/common.json b/apps/ledger-live-mobile/src/locales/en/common.json index 44416cd0e7b8..aadd2e3d0731 100644 --- a/apps/ledger-live-mobile/src/locales/en/common.json +++ b/apps/ledger-live-mobile/src/locales/en/common.json @@ -302,6 +302,9 @@ "FeeNotLoaded": { "title": "Could not load fee rates" }, + "FeeNotLoadedSwap": { + "title": "Network fee estimation failed because of technical issues. Try again or change the assets." + }, "FeeRequired": { "title": "Fees are required" }, diff --git a/libs/coin-evm/src/api/node/ledger.ts b/libs/coin-evm/src/api/node/ledger.ts index 76df05ac7a0d..48398e8da2eb 100644 --- a/libs/coin-evm/src/api/node/ledger.ts +++ b/libs/coin-evm/src/api/node/ledger.ts @@ -15,7 +15,8 @@ import { NodeApi, isLedgerNodeConfig } from "./types"; import { getGasOptions } from "../gasTracker/ledger"; import { padHexString } from "../../logic"; -export const LEDGER_TIMEOUT = 200; // 200ms between 2 calls +export const LEDGER_TIMEOUT = 10000; +export const LEDGER_TIME_BETWEEN_TRIES = 200; // 200ms between 2 calls export const DEFAULT_RETRIES_API = 2; export async function fetchWithRetries( @@ -35,7 +36,7 @@ export async function fetchWithRetries( } catch (e) { if (retries) { // wait the API timeout before trying again - await delay(LEDGER_TIMEOUT); + await delay(LEDGER_TIME_BETWEEN_TRIES); // decrement with prefix here or it won't work return fetchWithRetries(params, --retries); } @@ -182,6 +183,7 @@ export const getGasEstimation: NodeApi["getGasEstimation"] = async (account, tra estimated_gas_limit: string; }>({ method: "POST", + timeout: LEDGER_TIMEOUT, url: `${getEnv("EXPLORER")}/blockchain/v4/${node.explorerId}/tx/estimate-gas-limit`, data: { from: account.freshAddress, // should be necessary for some estimations diff --git a/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts b/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts index 6c8c4fe25d08..1eae6d66b748 100644 --- a/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts +++ b/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts @@ -1,4 +1,10 @@ -import { AmountRequired, NotEnoughGas, NotEnoughGasSwap } from "@ledgerhq/errors"; +import { + AmountRequired, + FeeNotLoaded, + FeeNotLoadedSwap, + NotEnoughGas, + NotEnoughGasSwap, +} from "@ledgerhq/errors"; import { useMemo } from "react"; import { SwapSelectorStateType, @@ -73,6 +79,11 @@ export const useFromAmountStatusMessage = ( }); } + // convert to swap variation of error to display correct message to frontend. + if (relevantStatus instanceof FeeNotLoaded) { + return new FeeNotLoadedSwap(); + } + return relevantStatus; }, [statusEntries, currency, estimatedFees, transaction?.amount, account?.id, parentAccount?.id]); }; @@ -123,7 +134,7 @@ export const useSwapTransaction = ({ const { account: toAccount } = toState; const transaction = bridgeTransaction?.transaction; - const fromAmountError = useFromAmountStatusMessage(bridgeTransaction, ["amount"]); + const fromAmountError = useFromAmountStatusMessage(bridgeTransaction, ["amount", "gasLimit"]); // treat the gasPrice error as a warning for swap. const fromAmountWarning = useFromAmountStatusMessage(bridgeTransaction, ["gasPrice"]); diff --git a/libs/ledgerjs/packages/errors/src/index.ts b/libs/ledgerjs/packages/errors/src/index.ts index bd7aea298cea..db9455b766e2 100644 --- a/libs/ledgerjs/packages/errors/src/index.ts +++ b/libs/ledgerjs/packages/errors/src/index.ts @@ -140,6 +140,7 @@ export const WrongAppForCurrency = createCustomErrorClass("WrongAppForCurrency") export const ETHAddressNonEIP = createCustomErrorClass("ETHAddressNonEIP"); export const CantScanQRCode = createCustomErrorClass("CantScanQRCode"); export const FeeNotLoaded = createCustomErrorClass("FeeNotLoaded"); +export const FeeNotLoadedSwap = createCustomErrorClass("FeeNotLoadedSwap"); export const FeeRequired = createCustomErrorClass("FeeRequired"); export const FeeTooHigh = createCustomErrorClass("FeeTooHigh"); export const PendingOperation = createCustomErrorClass("PendingOperation");