@rash2x/bridge-widget 0.6.93 → 0.6.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34,7 +34,7 @@ import { FixedSizeList } from "react-window";
34
34
  const common$1 = { "connecting": "Connecting…", "initializing": "Initializing...", "loading": "Loading...", "paste": "paste", "close": "Close", "zeroPlaceholder": "0", "nativeToken": "Native Token" };
35
35
  const wallets$1 = { "addTonWallet": "Add TON wallet", "addEvmWallet": "Add EVM wallet", "connectTonWallet": "Connect TON wallet", "connectEvmWallet": "Connect EVM wallet", "initializingMetamask": "Initializing MetaMask SDK...", "initializingTronlink": "Initializing TronLink...", "failedToConnectTon": "Failed to connect to TON wallet", "failedToDisconnect": "Failed to disconnect", "metamaskConnectionError": "MetaMask connection error", "failedToConnectMetamask": "Failed to connect to MetaMask", "failedToDisconnectMetamask": "Failed to disconnect from MetaMask", "selectWallet": "Select Wallet", "tonWallets": "TON", "evmWallets": "EVM", "tronWallets": "TRON", "tonconnect": "TonConnect", "metaMask": "WalletConnect", "walletConnect": "WalletConnect", "tronLink": "TronLink", "addTronWallet": "Add Tron wallet", "comingSoon": "Coming Soon", "connected": "CONNECTED", "connectedStatus": "Connected", "disconnect": "Disconnect", "chooseWallet": "Connect wallet", "oneWalletPerEnv": "You can only connect one wallet per environment.", "connect": "Connect", "connectTronWallet": "Connect Tron wallet", "connectWallet": "Connect wallet" };
36
36
  const bridge$1 = { "max": "Max", "sourceNetwork": "Source network", "destinationNetwork": "Destination network", "selectToken": "Select token", "selectNetwork": "Select network", "selectSourceNetwork": "Select source network", "selectDestinationNetwork": "Select destination network", "searchToken": "Search token", "myTokens": "My tokens", "allTokens": "All tokens", "search": "Search", "select": "Select", "willChangeSourceChain": "Will change source network", "willChangeDestinationChain": "Will change destination network", "willChangeBothChains": "Will change both networks", "willChangeSourceNetworkAndToken": "Will change source token", "noBalancesFound": "No balances found.", "noResults": "No results", "tokenNotFound": "We couldn't find a token with that name or symbol. Please try again.", "chainNotFound": "We couldn't find a chain with that name. Please try again.", "sendToAnotherAddress": "Send to another address", "youWillReceive": "You will receive", "anotherAddressPlaceholder": "Address", "addressDoesntMatch": "Address doesn't match the {{network}} network", "checkBeforeTransfer": "Check correctness before transfer" };
37
- const transaction$1 = { "enterAmount": "Enter amount", "transfer": "Transfer", "getQuote": "Get quote", "failed": "Transaction Failed", "confirm": "Confirm transaction", "signTransaction": "Sign in transaction in wallet", "quoting": "Quoting...", "inProgress": "Transaction in progress...", "checkingBalance": "Checking balance...", "insufficientBalance": "Insufficient balance", "amountTooSmall": "Min {{min}}", "amountTooLarge": "Max {{max}}", "success": "Success", "successTitle": "Success", "done": "Done", "hashCopied": "Hash copied to clipboard", "bridged": "Bridged", "transferTitle": "Transfer", "hash": "Hash", "layerzeroScan": "TxHash", "finalFee": "Final Fee", "route": "Route", "routeTooltip": "Route is the path your transfer takes between networks. The bridge is powered by LayerZero, and the specific path can affect the fee, slippage, and estimated time.", "estTime": "Est. Time", "estTimeTooltip": "Estimated time is the approximate completion time. It depends on the route and network load; actual time may vary.", "slippage": "Slippage", "slippageTooltip": "If the received amount goes below this tolerance, the transaction will be reverted.", "minimumReceived": "Minimum received", "totalFee": "Total Fee", "totalFeeTooltip": "Total fee is the estimated total cost of the transfer. It includes network gas and bridge/route fees. The final fee may vary slightly.", "noRouteFound": "No route found", "notEnoughGas": "Not enough gas", "pasteAddressToTransfer": "Paste address to transfer", "noRouteFoundForSettings": "No route found for current settings.", "tryAdjustSettings": "Try disabling Gas on Destination, or adjust amount/networks.", "quoteError": "Quote error", "steps": { "sent": "Sent", "approving": "Approving Token", "approvingNote": "Step {{current}} of {{total}}: Confirm approval in wallet", "bridging": "Bridging", "processing": "Processing", "processingNote": "Up to 2 minutes", "completed": "Completed" } };
37
+ const transaction$1 = { "enterAmount": "Enter amount", "transfer": "Transfer", "getQuote": "Get quote", "failed": "Transaction Failed", "confirm": "Confirm transaction", "signTransaction": "Sign in transaction in wallet", "quoting": "Quoting...", "inProgress": "Transaction in progress...", "checkingBalance": "Checking balance...", "insufficientBalance": "Insufficient balance", "amountTooSmall": "Min {{min}}", "amountTooLarge": "Max {{max}}", "success": "Success", "successTitle": "Success", "done": "Done", "hashCopied": "Hash copied to clipboard", "bridged": "Bridged", "transferTitle": "Transfer", "hash": "Hash", "layerzeroScan": "TxHash", "finalFee": "Final Fee", "route": "Route", "routeTooltip": "Route is the path your transfer takes between networks. The bridge is powered by LayerZero, and the specific path can affect the fee, slippage, and estimated time.", "estTime": "Est. Time", "estTimeTooltip": "Estimated time is the approximate completion time. It depends on the route and network load; actual time may vary.", "slippage": "Slippage", "slippageTooltip": "If the received amount goes below this tolerance, the transaction will be reverted.", "minimumReceived": "Minimum received", "messageFee": "Message Fee", "messageFeeTooltip": "Message fee is the LayerZero cross-chain messaging cost paid to relay your transaction between networks.", "bridgeFee": "Bridge Fee", "bridgeFeeTooltip": "Bridge fee is the difference between the amount you send and the amount you receive, charged by the bridge protocol.", "totalFee": "Total Fee", "totalFeeTooltip": "Total fee is the estimated total cost of the transfer, including message and bridge fees. The final fee may vary slightly.", "gasEstimate": "Gas: {{gas}}", "noRouteFound": "No route found", "notEnoughGas": "Not enough gas", "pasteAddressToTransfer": "Paste address to transfer", "noRouteFoundForSettings": "No route found for current settings.", "tryAdjustSettings": "Try disabling Gas on Destination, or adjust amount/networks.", "quoteError": "Quote error", "steps": { "sent": "Sent", "approving": "Approving Token", "approvingNote": "Step {{current}} of {{total}}: Confirm approval in wallet", "bridging": "Bridging", "processing": "Processing", "processingNote": "Up to 2 minutes", "completed": "Completed" } };
38
38
  const telegram$1 = { "openWebVersion": "Open EVAA Web to Bridge", "restrictionMessage": "You can bridge between the chosen networks on EVAA web version" };
39
39
  const app$1 = { "stargateWidgetName": "Stargate Bridge Widget", "liveWidget": "Live Widget", "getStarted": "Get Started" };
40
40
  const settings$1 = { "title": "Settings", "gasOnDestination": "Gas on destination", "gasOnDestinationTooltip": "Adds the destination network's native token to cover fees for transactions after bridging. Increases the total fee.", "slippageTolerance": "Slippage tolerance", "slippageToleranceTooltip": "If the received amount goes below this tolerance, the transaction will be reverted.", "routePriority": "Route Priority", "routePriorityTooltip": "Select how the bridge chooses a route. Recommended balances options to find the best overall cost. Fastest prioritizes completion speed over everything else.", "highSlippageWarning": "High slippage warning", "gasPresets": { "auto": "Auto", "none": "None", "medium": "Medium", "max": "Max" }, "routePresets": { "fastest": "Fastest", "cheapest": "Cheapest", "recommended": "Recommended" } };
@@ -52,7 +52,7 @@ const en$3 = {
52
52
  const common = { "connecting": "Подключение…", "initializing": "Инициализация...", "loading": "Загрузка...", "paste": "вставить", "close": "Закрыть", "zeroPlaceholder": "0", "nativeToken": "Нативный токен" };
53
53
  const wallets = { "addTonWallet": "Добавить TON кошелёк", "addEvmWallet": "Добавить EVM кошелёк", "connectTonWallet": "Подключить TON кошелёк", "connectEvmWallet": "Подключить EVM кошелёк", "initializingMetamask": "Инициализация MetaMask SDK...", "initializingTronlink": "Инициализация TronLink...", "failedToConnectTon": "Не удалось подключиться к TON кошельку", "failedToDisconnect": "Не удалось отключиться", "metamaskConnectionError": "Ошибка подключения MetaMask", "failedToConnectMetamask": "Не удалось подключиться к MetaMask", "failedToDisconnectMetamask": "Не удалось отключиться от MetaMask", "selectWallet": "Выберите кошелёк", "tonWallets": "TON", "evmWallets": "EVM", "tronWallets": "TRON", "tonconnect": "TonConnect", "metaMask": "WalletConnect", "walletConnect": "WalletConnect", "tronLink": "TronLink", "addTronWallet": "Добавить Tron кошелёк", "comingSoon": "Скоро", "connected": "ПОДКЛЮЧЕНО", "connectedStatus": "Подключён", "disconnect": "Отключить", "chooseWallet": "Подключите кошелек", "oneWalletPerEnv": "Можно подключить только один кошелёк на окружение.", "connect": "Подключить", "connectTronWallet": "Подключить Tron кошелёк", "connectWallet": "Подключить кошелёк" };
54
54
  const bridge = { "max": "Макс", "sourceNetwork": "Исходная сеть", "destinationNetwork": "Целевая сеть", "selectToken": "Выбрать токен", "selectNetwork": "Выбрать сеть", "selectSourceNetwork": "Выбрать исходную сеть", "selectDestinationNetwork": "Выбрать целевую сеть", "searchToken": "Поиск токена", "myTokens": "Мои токены", "allTokens": "Все токены", "search": "Поиск", "select": "Выбрать", "willChangeSourceChain": "Сменит исходную сеть", "willChangeDestinationChain": "Сменит целевую сеть", "willChangeBothChains": "Сменит обе сети", "willChangeSourceNetworkAndToken": "Сменит исходный токен", "noBalancesFound": "Балансы не найдены.", "noResults": "Нет результатов", "tokenNotFound": "Мы не смогли найти токен с таким названием или символом. Пожалуйста, попробуйте снова.", "chainNotFound": "Мы не смогли найти сеть с таким названием. Пожалуйста, попробуйте снова.", "sendToAnotherAddress": "Отправить на другой адрес", "youWillReceive": "Вы получите", "anotherAddressPlaceholder": "Адрес", "addressDoesntMatch": "Адрес не соответствует сети {{network}}", "checkBeforeTransfer": "Проверьте корректность перед переводом" };
55
- const transaction = { "enterAmount": "Введите сумму", "transfer": "Перевести", "getQuote": "Получить котировку", "quoting": "Расчет котировки...", "failed": "Ошибка транзакции", "confirm": "Подтвердите транзакцию", "signTransaction": "Подпишите транзакцию в кошельке", "inProgress": "Транзакция выполняется...", "checkingBalance": "Проверка баланса...", "insufficientBalance": "Недостаточно средств", "amountTooSmall": "Минимум {{min}}", "amountTooLarge": "Максимум {{max}}", "success": "Успех", "successTitle": "Успех", "done": "Готово", "hashCopied": "Хэш скопирован в буфер обмена", "bridged": "Переведено", "transferTitle": "Перевод", "hash": "Хэш", "layerzeroScan": "TxHash", "finalFee": "Итоговая комиссия", "route": "Маршрут", "routeTooltip": "Маршрут — это путь, по которому будет выполнен перевод. Мост работает на базе LayerZero, а конкретный путь передачи между сетями может влиять на комиссию, проскальзывание и время.", "estTime": "Время", "estTimeTooltip": "Среднее время — примерное время завершения перевода. Зависит от маршрута и нагрузки сети; фактическое время может отличаться.", "slippage": "Проскальзывание", "slippageTooltip": "Если получаемая сумма окажется ниже этого допуска, транзакция будет отклонена.", "minimumReceived": "Минимум к получению", "totalFee": "Общая комиссия", "totalFeeTooltip": "Общая комиссия за перевод. Включает оценку комиссии сети (газ) и комиссии моста/маршрута. Фактическая сумма может немного измениться.", "noRouteFound": "Маршрут не найден", "notEnoughGas": "Недостаточно газа", "pasteAddressToTransfer": "Укажите адрес получателя", "noRouteFoundForSettings": "Маршрут не найден для текущих настроек.", "tryAdjustSettings": "Попробуйте отключить Gas on Destination или измените сумму/сети.", "quoteError": "Ошибка котировки", "steps": { "sent": "Отправлено", "approving": "Одобрение токена", "approvingNote": "Шаг {{current}} из {{total}}: Подтвердите одобрение в кошельке", "bridging": "Перевод через мост", "processing": "Обработка", "processingNote": "До 2 минут", "completed": "Завершено" } };
55
+ const transaction = { "enterAmount": "Введите сумму", "transfer": "Перевести", "getQuote": "Получить котировку", "quoting": "Расчет котировки...", "failed": "Ошибка транзакции", "confirm": "Подтвердите транзакцию", "signTransaction": "Подпишите транзакцию в кошельке", "inProgress": "Транзакция выполняется...", "checkingBalance": "Проверка баланса...", "insufficientBalance": "Недостаточно средств", "amountTooSmall": "Минимум {{min}}", "amountTooLarge": "Максимум {{max}}", "success": "Успех", "successTitle": "Успех", "done": "Готово", "hashCopied": "Хэш скопирован в буфер обмена", "bridged": "Переведено", "transferTitle": "Перевод", "hash": "Хэш", "layerzeroScan": "TxHash", "finalFee": "Итоговая комиссия", "route": "Маршрут", "routeTooltip": "Маршрут — это путь, по которому будет выполнен перевод. Мост работает на базе LayerZero, а конкретный путь передачи между сетями может влиять на комиссию, проскальзывание и время.", "estTime": "Время", "estTimeTooltip": "Среднее время — примерное время завершения перевода. Зависит от маршрута и нагрузки сети; фактическое время может отличаться.", "slippage": "Проскальзывание", "slippageTooltip": "Если получаемая сумма окажется ниже этого допуска, транзакция будет отклонена.", "minimumReceived": "Минимум к получению", "messageFee": "Комиссия сообщения", "messageFeeTooltip": "Комиссия сообщения — стоимость кросс-чейн передачи через LayerZero для ретрансляции транзакции между сетями.", "bridgeFee": "Комиссия моста", "bridgeFeeTooltip": "Комиссия моста — разница между отправленной и полученной суммой, взимаемая протоколом моста.", "totalFee": "Общая комиссия", "totalFeeTooltip": "Общая комиссия за перевод, включая комиссию сообщения и моста. Фактическая сумма может немного измениться.", "gasEstimate": "Газ: {{gas}}", "noRouteFound": "Маршрут не найден", "notEnoughGas": "Недостаточно газа", "pasteAddressToTransfer": "Укажите адрес получателя", "noRouteFoundForSettings": "Маршрут не найден для текущих настроек.", "tryAdjustSettings": "Попробуйте отключить Gas on Destination или измените сумму/сети.", "quoteError": "Ошибка котировки", "steps": { "sent": "Отправлено", "approving": "Одобрение токена", "approvingNote": "Шаг {{current}} из {{total}}: Подтвердите одобрение в кошельке", "bridging": "Перевод через мост", "processing": "Обработка", "processingNote": "До 2 минут", "completed": "Завершено" } };
56
56
  const telegram = { "openWebVersion": "Открыть EVAA веб для трансфера", "restrictionMessage": "Трансфер между выбранными сетями доступен только в веб-версии EVAA" };
57
57
  const app = { "stargateWidgetName": "Виджет Stargate Bridge", "liveWidget": "Живой виджет", "getStarted": "Начало работы" };
58
58
  const settings = { "title": "Настройки", "gasOnDestination": "Газ на назначении", "gasOnDestinationTooltip": "Добавляет нативный токен целевой сети для оплаты комиссий за транзакции после бриджа. Увеличивает общую комиссию.", "slippageTolerance": "Толерантность к проскальзыванию", "slippageToleranceTooltip": "Если получаемая сумма окажется ниже этого допуска, транзакция будет отклонена.", "routePriority": "Приоритет маршрута", "routePriorityTooltip": "Выберите маршрут перевода. Рекомендуемый — подбирает самый выгодный вариант по общей стоимости. Быстрый — выбирает маршрут с приоритетом скорости, даже если это дороже.", "highSlippageWarning": "Высокое проскальзывание", "gasPresets": { "auto": "Авто", "none": "Нет", "medium": "Средний", "max": "Макс" }, "routePresets": { "fastest": "Быстрый", "cheapest": "Дешевый", "recommended": "Рекомендуемый" } };
@@ -2285,62 +2285,6 @@ function lookupTokenMeta(tokens, chains, chainKey, tokenAddr) {
2285
2285
  priceUsd: void 0
2286
2286
  };
2287
2287
  }
2288
- function computeFeesUsdFromArray(fees, tokens, chains) {
2289
- const emptyResult = {
2290
- usd: /* @__PURE__ */ new Map(),
2291
- human: /* @__PURE__ */ new Map(),
2292
- original: void 0
2293
- };
2294
- if (!fees?.length) return emptyResult;
2295
- let totalUsd = 0;
2296
- const byTypeUsd = /* @__PURE__ */ new Map();
2297
- const byTypeHuman = /* @__PURE__ */ new Map();
2298
- for (const f4 of fees) {
2299
- let usd = Number(f4.usd ?? 0);
2300
- let human = 0;
2301
- const amount = String(f4.amount ?? "0");
2302
- if (!usd) {
2303
- const { decimals, priceUsd } = lookupTokenMeta(
2304
- tokens,
2305
- chains,
2306
- f4.chainKey,
2307
- f4.token
2308
- );
2309
- human = fromLD(amount, decimals);
2310
- usd = (priceUsd ?? 0) * human;
2311
- }
2312
- totalUsd += usd;
2313
- const type = (f4.type ?? "other").toLowerCase();
2314
- byTypeUsd.set(type, (byTypeUsd.get(type) ?? 0) + usd);
2315
- const existing = byTypeHuman.get(type);
2316
- if (existing) {
2317
- existing.amount += human;
2318
- } else {
2319
- byTypeHuman.set(type, {
2320
- amount: human,
2321
- token: f4.token,
2322
- chainKey: f4.chainKey
2323
- });
2324
- }
2325
- }
2326
- byTypeUsd.set("total", totalUsd);
2327
- return {
2328
- usd: byTypeUsd,
2329
- human: byTypeHuman,
2330
- original: fees
2331
- };
2332
- }
2333
- function sumFeeByTokenLD(fees, dstTokenAddr, dstChainKey) {
2334
- if (!fees?.length || !dstTokenAddr || !dstChainKey) return "0";
2335
- let acc = 0n;
2336
- for (const f4 of fees) {
2337
- if (f4.chainKey !== dstChainKey) continue;
2338
- const same = dstChainKey === "ton" ? tonNorm(f4.token) === tonNorm(dstTokenAddr) : lower(f4.token) === lower(dstTokenAddr);
2339
- if (!same) continue;
2340
- acc += BigInt(f4.amount ?? "0");
2341
- }
2342
- return acc.toString();
2343
- }
2344
2288
  function getQuoteAmounts(quote, srcToken, dstToken) {
2345
2289
  if (!quote || !srcToken || !dstToken) {
2346
2290
  return {
@@ -2361,48 +2305,6 @@ function getQuoteAmounts(quote, srcToken, dstToken) {
2361
2305
  minReceivedHuman
2362
2306
  };
2363
2307
  }
2364
- function getQuoteFees(quote, tokens, chains, srcToken, dstToken) {
2365
- if (!quote || !tokens || !chains) {
2366
- return {
2367
- fees: { usd: /* @__PURE__ */ new Map(), original: /* @__PURE__ */ new Map(), formatted: /* @__PURE__ */ new Map() },
2368
- inSrcToken: void 0,
2369
- inDstToken: void 0
2370
- };
2371
- }
2372
- const feeData = computeFeesUsdFromArray(quote.fees, tokens, chains);
2373
- let inSrcToken = void 0;
2374
- let inDstToken = void 0;
2375
- if (srcToken && quote.srcChainKey) {
2376
- const feeInSrcLD = sumFeeByTokenLD(
2377
- quote.fees,
2378
- srcToken.address,
2379
- quote.srcChainKey
2380
- );
2381
- const feeInSrcHuman = fromLD(feeInSrcLD, srcToken.decimals);
2382
- if (feeInSrcHuman > 0) {
2383
- inSrcToken = Number(truncateToDecimals(feeInSrcHuman, 8));
2384
- } else if ((feeData.usd.get("total") || 0) > 0 && srcToken.price?.usd) {
2385
- const feeInSrcApprox = (feeData.usd.get("total") || 0) / srcToken.price.usd;
2386
- inSrcToken = Number(truncateToDecimals(feeInSrcApprox, 8));
2387
- }
2388
- }
2389
- if (dstToken && quote.dstChainKey) {
2390
- const feeInDstLD = sumFeeByTokenLD(
2391
- quote.fees,
2392
- dstToken.address,
2393
- quote.dstChainKey
2394
- );
2395
- const feeInDstHuman = fromLD(feeInDstLD, dstToken.decimals);
2396
- if (feeInDstHuman > 0) {
2397
- inDstToken = Number(truncateToDecimals(feeInDstHuman, 8));
2398
- }
2399
- }
2400
- return {
2401
- fees: feeData,
2402
- inSrcToken,
2403
- inDstToken
2404
- };
2405
- }
2406
2308
  function calculateMinReceived(quote, slippageBps, dstToken) {
2407
2309
  if (!quote || !dstToken) return 0;
2408
2310
  const dstAmountLD = BigInt(quote.dstAmount);
@@ -2411,7 +2313,7 @@ function calculateMinReceived(quote, slippageBps, dstToken) {
2411
2313
  }
2412
2314
  function getQuoteDetails(quote, srcToken, dstToken, tokens, chains, slippageBps) {
2413
2315
  const amounts = getQuoteAmounts(quote, srcToken, dstToken);
2414
- const fees = getQuoteFees(quote, tokens, chains, srcToken, dstToken);
2316
+ const fees = computeFeeBreakdownUsd(quote, srcToken, tokens, chains);
2415
2317
  const minimumReceived = calculateMinReceived(quote, slippageBps, dstToken);
2416
2318
  return {
2417
2319
  inputAmount: amounts.inputHuman,
@@ -2431,6 +2333,28 @@ function getRouteDisplayName(route) {
2431
2333
  if (routeLower.includes("v2")) return "Stargate V2";
2432
2334
  return route.split(/[/\-_]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
2433
2335
  }
2336
+ function computeFeeBreakdownUsd(quote, srcToken, tokens, chains) {
2337
+ const empty = { messageFeeUsd: 0, bridgeFeeUsd: 0, totalFeeUsd: 0 };
2338
+ if (!quote || !srcToken) return empty;
2339
+ let messageFeeUsd = 0;
2340
+ const messageFees = quote.fees.filter((f4) => f4.type === "message");
2341
+ for (const f4 of messageFees) {
2342
+ const { decimals, priceUsd } = lookupTokenMeta(tokens, chains, f4.chainKey, f4.token);
2343
+ const human = fromLD(f4.amount || "0", decimals);
2344
+ messageFeeUsd += human * (priceUsd ?? 0);
2345
+ }
2346
+ let bridgeFeeUsd = 0;
2347
+ if (srcToken.price?.usd) {
2348
+ const srcHuman = fromLD(quote.srcAmount, srcToken.decimals);
2349
+ const dstHuman = fromLD(quote.dstAmount, srcToken.decimals);
2350
+ const diff = srcHuman - dstHuman;
2351
+ if (diff > 0) {
2352
+ bridgeFeeUsd = diff * srcToken.price.usd;
2353
+ }
2354
+ }
2355
+ const totalFeeUsd = messageFeeUsd + bridgeFeeUsd;
2356
+ return { messageFeeUsd, bridgeFeeUsd, totalFeeUsd };
2357
+ }
2434
2358
  async function addNetworkFeesToQuote(quote, chainRegistry, chains) {
2435
2359
  if (!quote || !chains) {
2436
2360
  return quote;
@@ -2936,79 +2860,18 @@ const TokenSymbol = ({
2936
2860
  const src2 = `${BASE_URL}/${normalizedSymbol}.svg`;
2937
2861
  return /* @__PURE__ */ jsx("img", { src: src2, alt: alt ?? symbol, className });
2938
2862
  };
2939
- function useGasEstimate(amountNum) {
2940
- const { fromChain } = useChainsStore();
2941
- const { selectedAssetSymbol } = useTokensStore();
2942
- const { srcAddress } = useAddresses();
2943
- const { balances, isLoading: balancesLoading } = useBalances(
2944
- fromChain?.chainKey,
2945
- srcAddress
2946
- );
2863
+ function useFeeBreakdown() {
2947
2864
  const { quote } = useBridgeQuoteStore();
2948
- const balancesKnown = !balancesLoading;
2949
- const chainKey = fromChain?.chainKey;
2950
- const nativeCurrencySymbol = fromChain?.nativeCurrency?.symbol;
2951
- const nativeCurrencyAddress = fromChain?.nativeCurrency?.address;
2952
- const nativeCurrencyDecimals = fromChain?.nativeCurrency?.decimals;
2953
- const quoteFees = quote?.fees;
2954
- const quoteSrcChainKey = quote?.srcChainKey;
2955
- const nativeBalanceValue = nativeCurrencySymbol ? Number(balances[nativeCurrencySymbol.toUpperCase()]?.balance ?? 0) : 0;
2956
- const result = useMemo(() => {
2957
- if (!chainKey || !nativeCurrencySymbol) {
2958
- return {
2959
- nativeSym: "",
2960
- nativeBalance: 0,
2961
- requiredNative: 0,
2962
- balancesKnown,
2963
- isNativeSelected: false,
2964
- hasEnoughGas: true
2965
- };
2966
- }
2967
- const nativeSym = nativeCurrencySymbol.toUpperCase();
2968
- const nativeBalance = nativeBalanceValue;
2969
- const isNativeSelected = nativeSym === (selectedAssetSymbol || "").toUpperCase();
2970
- let requiredNative = 0;
2971
- let quoteFeesAvailable = false;
2972
- if (quoteFees && quoteSrcChainKey === chainKey) {
2973
- const fees = quoteFees;
2974
- const feesInNative = fees.filter(
2975
- (f4) => f4.chainKey === chainKey && f4.token === nativeCurrencyAddress
2976
- ).reduce(
2977
- (sum, f4) => sum + BigInt(f4.amount || "0"),
2978
- 0n
2979
- );
2980
- const decimals = nativeCurrencyDecimals || 18;
2981
- requiredNative = Number(feesInNative) / Math.pow(10, decimals);
2982
- quoteFeesAvailable = true;
2983
- }
2984
- let hasEnoughGas = true;
2985
- if (isNativeSelected) {
2986
- hasEnoughGas = nativeBalance - (amountNum ?? 0) >= requiredNative;
2987
- } else {
2988
- hasEnoughGas = nativeBalance >= requiredNative;
2989
- }
2990
- const shouldCheckGas = balancesKnown && quoteFeesAvailable;
2991
- return {
2992
- nativeSym,
2993
- nativeBalance,
2994
- requiredNative,
2995
- balancesKnown,
2996
- isNativeSelected,
2997
- hasEnoughGas: shouldCheckGas ? hasEnoughGas : true
2998
- };
2999
- }, [
3000
- chainKey,
3001
- nativeCurrencySymbol,
3002
- nativeCurrencyAddress,
3003
- nativeCurrencyDecimals,
3004
- selectedAssetSymbol,
3005
- quoteFees,
3006
- quoteSrcChainKey,
3007
- amountNum,
3008
- balancesKnown,
3009
- nativeBalanceValue
3010
- ]);
3011
- return result;
2865
+ const { tokens, selectedAssetSymbol, assetMatrix } = useTokensStore();
2866
+ const { fromChain, chains } = useChainsStore();
2867
+ return useMemo(() => {
2868
+ const srcToken = resolveTokenOnChainFromMatrix$1(
2869
+ assetMatrix,
2870
+ selectedAssetSymbol,
2871
+ fromChain?.chainKey
2872
+ );
2873
+ return computeFeeBreakdownUsd(quote, srcToken, tokens, chains);
2874
+ }, [quote, tokens, chains, selectedAssetSymbol, assetMatrix, fromChain]);
3012
2875
  }
3013
2876
  function useBridgeExternalData(options) {
3014
2877
  const selectedAssetSymbol = useTokensStore(
@@ -3148,7 +3011,7 @@ const Details = () => {
3148
3011
  const { selectedAssetSymbol } = useTokensStore();
3149
3012
  const { quote, status } = useBridgeQuoteStore();
3150
3013
  const { slippageBps } = useSettingsStore();
3151
- const gas = useGasEstimate();
3014
+ const fees = useFeeBreakdown();
3152
3015
  const bridgeData = useBridgeExternalData();
3153
3016
  const symbol = (selectedAssetSymbol ?? bridgeData.dstToken?.symbol ?? "—").toUpperCase();
3154
3017
  const isLoading = status === "loading";
@@ -3157,7 +3020,7 @@ const Details = () => {
3157
3020
  1,
3158
3021
  Math.round(bridgeData.quoteDetails?.etaSeconds / 60)
3159
3022
  )}m` : "—";
3160
- const totalFeeDisplay = !quote ? "—" : gas.requiredNative > 0 ? `${truncateToDecimals(gas.requiredNative, 6)} ${gas.nativeSym}` : "—";
3023
+ const totalFeeDisplay = !quote ? "—" : formatUsd(fees.totalFeeUsd);
3161
3024
  const currentSlippageText = !quote ? "—" : formatPercentage(slippageBps);
3162
3025
  const routeText = getRouteDisplayName(quote?.route);
3163
3026
  return /* @__PURE__ */ jsx(Accordion, { type: "single", collapsible: true, className: "w-full border-none", children: /* @__PURE__ */ jsxs(AccordionItem, { value: "item-1", className: "bg-muted rounded-sm", children: [
@@ -3203,17 +3066,7 @@ const Details = () => {
3203
3066
  {
3204
3067
  label: t2("transaction.totalFee"),
3205
3068
  tooltip: t2("transaction.totalFeeTooltip"),
3206
- value: /* @__PURE__ */ jsxs("strong", { className: "inline-flex items-center gap-1", children: [
3207
- /* @__PURE__ */ jsx("span", { children: totalFeeDisplay }),
3208
- /* @__PURE__ */ jsx(
3209
- TokenSymbol,
3210
- {
3211
- symbol: gas.nativeSym,
3212
- className: "w-4 h-4",
3213
- alt: "token"
3214
- }
3215
- )
3216
- ] }),
3069
+ value: /* @__PURE__ */ jsx("strong", { children: totalFeeDisplay }),
3217
3070
  isLoading
3218
3071
  }
3219
3072
  )
@@ -3607,6 +3460,93 @@ async function reportBridgeTransaction(params, config) {
3607
3460
  };
3608
3461
  }
3609
3462
  }
3463
+ function useGasEstimate(amountNum) {
3464
+ const { fromChain } = useChainsStore();
3465
+ const { selectedAssetSymbol } = useTokensStore();
3466
+ const { srcAddress } = useAddresses();
3467
+ const { balances, isLoading: balancesLoading } = useBalances(
3468
+ fromChain?.chainKey,
3469
+ srcAddress
3470
+ );
3471
+ const { quote } = useBridgeQuoteStore();
3472
+ const balancesKnown = !balancesLoading;
3473
+ const chainKey = fromChain?.chainKey;
3474
+ const nativeCurrencySymbol = fromChain?.nativeCurrency?.symbol;
3475
+ const nativeCurrencyAddress = fromChain?.nativeCurrency?.address;
3476
+ const nativeCurrencyDecimals = fromChain?.nativeCurrency?.decimals;
3477
+ const quoteFees = quote?.fees;
3478
+ const quoteSrcChainKey = quote?.srcChainKey;
3479
+ const nativeBalanceValue = nativeCurrencySymbol ? Number(balances[nativeCurrencySymbol.toUpperCase()]?.balance ?? 0) : 0;
3480
+ const result = useMemo(() => {
3481
+ if (!chainKey || !nativeCurrencySymbol) {
3482
+ return {
3483
+ nativeSym: "",
3484
+ nativeBalance: 0,
3485
+ requiredNative: 0,
3486
+ gasOnlyNative: 0,
3487
+ gasDisplayText: "",
3488
+ balancesKnown,
3489
+ isNativeSelected: false,
3490
+ hasEnoughGas: true
3491
+ };
3492
+ }
3493
+ const nativeSym = nativeCurrencySymbol.toUpperCase();
3494
+ const nativeBalance = nativeBalanceValue;
3495
+ const isNativeSelected = nativeSym === (selectedAssetSymbol || "").toUpperCase();
3496
+ let requiredNative = 0;
3497
+ let quoteFeesAvailable = false;
3498
+ let gasOnlyNative = 0;
3499
+ if (quoteFees && quoteSrcChainKey === chainKey) {
3500
+ const fees = quoteFees;
3501
+ const feesInNative = fees.filter(
3502
+ (f4) => f4.chainKey === chainKey && f4.token === nativeCurrencyAddress
3503
+ ).reduce(
3504
+ (sum, f4) => sum + BigInt(f4.amount || "0"),
3505
+ 0n
3506
+ );
3507
+ const decimals = nativeCurrencyDecimals || 18;
3508
+ requiredNative = Number(feesInNative) / Math.pow(10, decimals);
3509
+ const networkFeesInNative = fees.filter(
3510
+ (f4) => f4.chainKey === chainKey && f4.token === nativeCurrencyAddress && f4.type === "network"
3511
+ ).reduce(
3512
+ (sum, f4) => sum + BigInt(f4.amount || "0"),
3513
+ 0n
3514
+ );
3515
+ gasOnlyNative = Number(networkFeesInNative) / Math.pow(10, decimals);
3516
+ quoteFeesAvailable = true;
3517
+ }
3518
+ let hasEnoughGas = true;
3519
+ if (isNativeSelected) {
3520
+ hasEnoughGas = nativeBalance - (amountNum ?? 0) >= requiredNative;
3521
+ } else {
3522
+ hasEnoughGas = nativeBalance >= requiredNative;
3523
+ }
3524
+ const shouldCheckGas = balancesKnown && quoteFeesAvailable;
3525
+ const gasDisplayText = gasOnlyNative > 0 ? `~${gasOnlyNative.toFixed(6).replace(/0+$/, "").replace(/\.$/, "")} ${nativeSym}` : "";
3526
+ return {
3527
+ nativeSym,
3528
+ nativeBalance,
3529
+ requiredNative,
3530
+ gasOnlyNative,
3531
+ gasDisplayText,
3532
+ balancesKnown,
3533
+ isNativeSelected,
3534
+ hasEnoughGas: shouldCheckGas ? hasEnoughGas : true
3535
+ };
3536
+ }, [
3537
+ chainKey,
3538
+ nativeCurrencySymbol,
3539
+ nativeCurrencyAddress,
3540
+ nativeCurrencyDecimals,
3541
+ selectedAssetSymbol,
3542
+ quoteFees,
3543
+ quoteSrcChainKey,
3544
+ amountNum,
3545
+ balancesKnown,
3546
+ nativeBalanceValue
3547
+ ]);
3548
+ return result;
3549
+ }
3610
3550
  function useBridgeTransaction() {
3611
3551
  const { quote } = useBridgeQuoteStore();
3612
3552
  const { chainRegistry } = useChainStrategies();
@@ -4137,7 +4077,8 @@ const MainButton = ({
4137
4077
  className: "w-full",
4138
4078
  children: label
4139
4079
  }
4140
- )
4080
+ ),
4081
+ gas.gasDisplayText && quote && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground text-center", children: t2("transaction.gasEstimate", { gas: gas.gasDisplayText }) })
4141
4082
  ] });
4142
4083
  };
4143
4084
  const WalletModalButton = (props) => {
@@ -25782,7 +25723,7 @@ class WalletConnectModal {
25782
25723
  }
25783
25724
  async initUi() {
25784
25725
  if (typeof window !== "undefined") {
25785
- await import("./index-Ba3TMYQR.js");
25726
+ await import("./index-D8kQruAb.js");
25786
25727
  const modal = document.createElement("wcm-modal");
25787
25728
  document.body.insertAdjacentElement("beforeend", modal);
25788
25729
  OptionsCtrl.setIsUiLoaded(true);
@@ -26558,9 +26499,9 @@ const EvaaBridgeContent = ({
26558
26499
  };
26559
26500
  const EvaaBridge = EvaaBridgeWithProviders;
26560
26501
  export {
26561
- getDestTokens as $,
26562
- getQuoteDetails as A,
26563
- getRouteDisplayName as B,
26502
+ isNativeAddress as $,
26503
+ getRouteDisplayName as A,
26504
+ computeFeeBreakdownUsd as B,
26564
26505
  ConfigCtrl as C,
26565
26506
  addNetworkFeesToQuote as D,
26566
26507
  EventsCtrl as E,
@@ -26581,20 +26522,18 @@ export {
26581
26522
  ToastCtrl as T,
26582
26523
  findNativeMeta as U,
26583
26524
  lookupTokenMeta as V,
26584
- computeFeesUsdFromArray as W,
26585
- sumFeeByTokenLD as X,
26586
- normalizeTickerSymbol$1 as Y,
26587
- getChains as Z,
26588
- getTokens as _,
26525
+ normalizeTickerSymbol$1 as W,
26526
+ getChains as X,
26527
+ getTokens as Y,
26528
+ getDestTokens as Z,
26529
+ getQuotesByPriority as _,
26589
26530
  ThemeCtrl as a,
26590
- getQuotesByPriority as a0,
26591
- isNativeAddress as a1,
26592
- getEvmBalances as a2,
26593
- getTonBalances as a3,
26594
- getTronBalances as a4,
26595
- getDeliveryStatus as a5,
26596
- pollUntilDelivered as a6,
26597
- reportBridgeTransaction as a7,
26531
+ getEvmBalances as a0,
26532
+ getTonBalances as a1,
26533
+ getTronBalances as a2,
26534
+ getDeliveryStatus as a3,
26535
+ pollUntilDelivered as a4,
26536
+ reportBridgeTransaction as a5,
26598
26537
  ExplorerCtrl as b,
26599
26538
  CoreUtil as c,
26600
26539
  EvaaBridge as d,
@@ -26618,7 +26557,7 @@ export {
26618
26557
  formatHash as v,
26619
26558
  formatAddress as w,
26620
26559
  getQuoteAmounts as x,
26621
- getQuoteFees as y,
26622
- calculateMinReceived as z
26560
+ calculateMinReceived as y,
26561
+ getQuoteDetails as z
26623
26562
  };
26624
- //# sourceMappingURL=index-BDIi-D7p.js.map
26563
+ //# sourceMappingURL=index-UWqhEblz.js.map