@rash2x/bridge-widget 0.6.55 → 0.6.61

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.
@@ -10,15 +10,14 @@ import { create } from "zustand";
10
10
  import { useAccount, usePublicClient, useConnect, useDisconnect, useWalletClient } from "wagmi";
11
11
  import { useWallet } from "@tronweb3/tronwallet-adapter-react-hooks";
12
12
  import { useTonAddress, useTonConnectUI } from "@tonconnect/ui-react";
13
- import { Address, beginCell as beginCell$1, storeMessage, loadMessage, Cell } from "@ton/core";
14
- import { TonClient, Address as Address$1, beginCell } from "@ton/ton";
13
+ import { Address, loadMessage, Cell, beginCell as beginCell$1, storeMessage } from "@ton/core";
15
14
  import { useQuery, useQueryClient } from "@tanstack/react-query";
16
15
  import { cn as cn$2 } from "@/lib/utils";
17
16
  import { Skeleton } from "@/components/ui/skeleton";
18
17
  import { Input } from "@/components/ui/input";
19
18
  import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog";
19
+ import { XIcon, X as X$3, Loader2, AlertCircleIcon, ArrowRight, CheckCircle2, Clock } from "lucide-react";
20
20
  import { Switch } from "@/components/ui/switch";
21
- import { X as X$3, Loader2, AlertCircleIcon, ArrowRight, CheckCircle2, Clock } from "lucide-react";
22
21
  import { AnimatePresence, motion } from "framer-motion";
23
22
  import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from "@/components/ui/accordion";
24
23
  import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
@@ -26,7 +25,8 @@ import { Alert, AlertDescription } from "@/components/ui/alert";
26
25
  import { toast, Toaster } from "sonner";
27
26
  import { Badge } from "@/components/ui/badge";
28
27
  import { DialogDescription as DialogDescription$1 } from "@radix-ui/react-dialog";
29
- import { isAddress, formatUnits, parseUnits } from "viem";
28
+ import { isAddress, formatUnits, parseAbi, parseUnits } from "viem";
29
+ import { TonClient, Address as Address$1, beginCell } from "@ton/ton";
30
30
  import { TronLinkAdapterName } from "@tronweb3/tronwallet-adapters";
31
31
  import { TronWeb } from "tronweb";
32
32
  import { CardHeader, CardTitle, CardAction, Card, CardContent, CardFooter } from "@/components/ui/card";
@@ -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", "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": "LayerZero Scan", "finalFee": "Final Fee", "route": "Route", "estTime": "Est. Time", "slippage": "Slippage", "minimumReceived": "Minimum received", "totalFee": "Total Fee", "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", "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", "estTime": "Est. Time", "slippage": "Slippage", "minimumReceived": "Minimum received", "totalFee": "Total Fee", "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", "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", "gasOnDestinationDescription": "The default amount allows you to perform a couple of transactions (e.g. Approve and Swap).", "slippageTolerance": "Slippage tolerance", "slippageToleranceDescription": "Your transaction will revert if the amount you're receiving is outside of this tolerance", "routePriority": "Route Priority", "routePriorityDescription": "Choose how your transfer is routed. Recommended picks the best overall path for cost. Fastest prioritizes speed above all 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": "Сменит исходную сеть", "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": "LayerZero Scan", "finalFee": "Итоговая комиссия", "route": "Маршрут", "estTime": "Время", "slippage": "Проскальзывание", "minimumReceived": "Минимум к получению", "totalFee": "Общая комиссия", "noRouteFound": "Маршрут не найден", "notEnoughGas": "Недостаточно газа", "pasteAddressToTransfer": "Укажите адрес получателя", "noRouteFoundForSettings": "Маршрут не найден для текущих настроек.", "tryAdjustSettings": "Попробуйте отключить Gas on Destination или измените сумму/сети.", "quoteError": "Ошибка котировки", "steps": { "sent": "Отправлено", "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": "Маршрут", "estTime": "Время", "slippage": "Проскальзывание", "minimumReceived": "Минимум к получению", "totalFee": "Общая комиссия", "noRouteFound": "Маршрут не найден", "notEnoughGas": "Недостаточно газа", "pasteAddressToTransfer": "Укажите адрес получателя", "noRouteFoundForSettings": "Маршрут не найден для текущих настроек.", "tryAdjustSettings": "Попробуйте отключить Gas on Destination или измените сумму/сети.", "quoteError": "Ошибка котировки", "steps": { "sent": "Отправлено", "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": "Газ на назначении", "gasOnDestinationDescription": "Значение по умолчанию позволяет выполнить пару транзакций (например, Approve и Swap).", "slippageTolerance": "Толерантность к проскальзыванию", "slippageToleranceDescription": "Ваша транзакция будет отклонена, если получаемая сумма выйдет за пределы этой допустимой погрешности.", "routePriority": "Приоритет маршрута", "routePriorityDescription": "Выберите, как будет выполняться ваш трансфер. Recommended — выбирает оптимальный маршрут с учётом общей стоимости. Fastest — отдаёт приоритет максимальной скорости.", "highSlippageWarning": "Высокое проскальзывание", "gasPresets": { "auto": "Авто", "none": "Нет", "medium": "Средний", "max": "Макс" }, "routePresets": { "fastest": "Быстрейший", "cheapest": "Дешевейший", "recommended": "Рекомендуемый" } };
@@ -940,375 +940,6 @@ function useChainStrategies() {
940
940
  }
941
941
  return context;
942
942
  }
943
- const truncateToDecimals = (num, decimals) => {
944
- if (!isFinite(num) || isNaN(num)) return "0";
945
- const multiplier = Math.pow(10, decimals);
946
- const truncated = Math.floor(num * multiplier) / multiplier;
947
- return truncated.toFixed(decimals).replace(/\.?0+$/, "");
948
- };
949
- const formatTokenAmount = (amount, symbol, options) => {
950
- const normalizedSymbol = (symbol ?? "").toUpperCase();
951
- if (["USDT", "USDC", "DAI", "BUSD"].includes(normalizedSymbol) && amount >= 1) {
952
- return `${Math.floor(amount)} ${normalizedSymbol}`;
953
- }
954
- if (options?.decimals !== void 0) {
955
- return `${amount.toFixed(options.decimals)} ${normalizedSymbol}`;
956
- }
957
- if (amount >= 1) {
958
- return `${amount.toFixed(0)} ${normalizedSymbol}`;
959
- } else if (amount >= 1e-3) {
960
- return `${amount.toFixed(3)} ${normalizedSymbol}`;
961
- } else {
962
- return `${amount.toFixed(6)} ${normalizedSymbol}`;
963
- }
964
- };
965
- const formatUsd = (value) => {
966
- if (!value || !isFinite(value)) return "$0";
967
- if (value >= 1) return `$${value.toFixed(2)}`;
968
- return `$${value.toFixed(6).replace(/0+$/, "").replace(/\.$/, "")}`;
969
- };
970
- const formatPercentage = (bps, decimals = 2) => {
971
- return `${(bps / 100).toFixed(decimals).replace(/0+$/, "").replace(/\.$/, "")}%`;
972
- };
973
- const formatBalance = (amount, decimals = 2) => {
974
- if (!isFinite(amount) || isNaN(amount) || amount <= 0) {
975
- return "0.00";
976
- }
977
- return amount.toFixed(decimals);
978
- };
979
- const formatHash = (hash, startChars = 4, endChars = 4) => {
980
- if (!hash) return "";
981
- if (hash.length <= startChars + endChars) return hash;
982
- return `${hash.slice(0, startChars)}...${hash.slice(-endChars)}`;
983
- };
984
- const formatAddress = formatHash;
985
- const EVM_CONFIG = {
986
- usdtAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
987
- gasEstimates: {
988
- approve: 65000n,
989
- bridge: 300000n
990
- },
991
- gasBuffer: 1.2,
992
- // 20% buffer
993
- timeout: 3e5,
994
- // 5 minutes (increased for slower networks)
995
- requiredConfirmations: 3
996
- // Wait for 3 confirmations for reorg protection
997
- };
998
- const TON_CONFIG = {
999
- apiUrl: "https://toncenter.com/api/v2",
1000
- timeout: 36e4,
1001
- // 6 minutes
1002
- validUntil: 600,
1003
- // 10 minutes
1004
- pollingInterval: 5e3,
1005
- // 5 seconds between transaction status checks
1006
- estimatedNetworkFee: "100000000"
1007
- // 0.1 TON in nanoton (conservative estimate)
1008
- };
1009
- const TRON_CONFIG = {
1010
- timeout: 12e4,
1011
- // 2 minutes (for 19 confirmations)
1012
- feeLimit: 1e8,
1013
- // 100 TRX in sun
1014
- requiredConfirmations: 19,
1015
- // TRON standard: 19 blocks for confirmation
1016
- pollingInterval: 3e3,
1017
- // 3 seconds between checks
1018
- estimatedNetworkFee: "10000000"
1019
- // 10 TRX in SUN (fallback estimate)
1020
- };
1021
- let tonClientInstance = null;
1022
- function getTonClient(customClient, apiKey) {
1023
- if (customClient) {
1024
- return customClient;
1025
- }
1026
- if (!tonClientInstance) {
1027
- tonClientInstance = new TonClient({
1028
- endpoint: `${TON_CONFIG.apiUrl}/jsonRPC`,
1029
- apiKey
1030
- });
1031
- }
1032
- return tonClientInstance;
1033
- }
1034
- function getQuoteAmounts(quote, srcToken, dstToken) {
1035
- if (!quote || !srcToken || !dstToken) {
1036
- return {
1037
- inputHuman: 0,
1038
- outputHuman: 0,
1039
- outputHumanRounded: "0",
1040
- minReceivedHuman: 0
1041
- };
1042
- }
1043
- const inputHuman = fromLD(quote.srcAmount, srcToken.decimals);
1044
- const outputHuman = fromLD(quote.dstAmount, dstToken.decimals);
1045
- const outputHumanRounded = truncateToDecimals(outputHuman, 2);
1046
- const minReceivedHuman = fromLD(quote.dstAmountMin || "0", dstToken.decimals);
1047
- return {
1048
- inputHuman,
1049
- outputHuman,
1050
- outputHumanRounded,
1051
- minReceivedHuman
1052
- };
1053
- }
1054
- function getQuoteFees(quote, tokens, chains, srcToken, dstToken) {
1055
- if (!quote || !tokens || !chains) {
1056
- return {
1057
- fees: { usd: /* @__PURE__ */ new Map(), original: /* @__PURE__ */ new Map(), formatted: /* @__PURE__ */ new Map() },
1058
- inSrcToken: void 0,
1059
- inDstToken: void 0
1060
- };
1061
- }
1062
- const feeData = computeFeesUsdFromArray(quote.fees, tokens, chains);
1063
- let inSrcToken = void 0;
1064
- let inDstToken = void 0;
1065
- if (srcToken && quote.srcChainKey) {
1066
- const feeInSrcLD = sumFeeByTokenLD(
1067
- quote.fees,
1068
- srcToken.address,
1069
- quote.srcChainKey
1070
- );
1071
- const feeInSrcHuman = fromLD(feeInSrcLD, srcToken.decimals);
1072
- if (feeInSrcHuman > 0) {
1073
- inSrcToken = Number(truncateToDecimals(feeInSrcHuman, 8));
1074
- } else if ((feeData.usd.get("total") || 0) > 0 && srcToken.price?.usd) {
1075
- const feeInSrcApprox = (feeData.usd.get("total") || 0) / srcToken.price.usd;
1076
- inSrcToken = Number(truncateToDecimals(feeInSrcApprox, 8));
1077
- }
1078
- }
1079
- if (dstToken && quote.dstChainKey) {
1080
- const feeInDstLD = sumFeeByTokenLD(
1081
- quote.fees,
1082
- dstToken.address,
1083
- quote.dstChainKey
1084
- );
1085
- const feeInDstHuman = fromLD(feeInDstLD, dstToken.decimals);
1086
- if (feeInDstHuman > 0) {
1087
- inDstToken = Number(truncateToDecimals(feeInDstHuman, 8));
1088
- }
1089
- }
1090
- return {
1091
- fees: feeData,
1092
- inSrcToken,
1093
- inDstToken
1094
- };
1095
- }
1096
- function calculateMinReceived(quote, slippageBps, dstToken) {
1097
- if (!quote || !dstToken) return 0;
1098
- const dstAmountLD = BigInt(quote.dstAmount);
1099
- const minAmountLD = dstAmountLD * BigInt(1e4 - slippageBps) / BigInt(1e4);
1100
- return fromLD(minAmountLD.toString(), dstToken.decimals);
1101
- }
1102
- function estimateTonNetworkFee(quote) {
1103
- try {
1104
- const tonStep = quote.steps?.find(
1105
- (s2) => s2.chainKey.toLowerCase() === "ton" && s2.type === "bridge"
1106
- );
1107
- if (!tonStep?.transaction?.messages) {
1108
- console.warn("No TON messages found in quote, using fallback");
1109
- return TON_CONFIG.estimatedNetworkFee;
1110
- }
1111
- const messages = tonStep.transaction.messages;
1112
- const messageCount = messages.length;
1113
- const baseFeePerMessage = 10000000n;
1114
- let totalFee = 0n;
1115
- for (const message of messages) {
1116
- let messageFee = baseFeePerMessage;
1117
- if (message.payload) {
1118
- const payloadSize = message.payload.length;
1119
- const sizeFee = BigInt(Math.floor(payloadSize / 100)) * 100000n;
1120
- messageFee += sizeFee;
1121
- }
1122
- if (message.amount) {
1123
- const amount = BigInt(message.amount);
1124
- if (amount > 0n && message.payload) {
1125
- messageFee += 5000000n;
1126
- }
1127
- }
1128
- totalFee += messageFee;
1129
- }
1130
- const minBuffer = 50000000n;
1131
- totalFee = totalFee > minBuffer ? totalFee : minBuffer;
1132
- totalFee = totalFee * 120n / 100n;
1133
- const maxFee = 1000000000n;
1134
- if (totalFee > maxFee) {
1135
- totalFee = maxFee;
1136
- }
1137
- console.log(
1138
- `TON fee estimate: ${messageCount} messages = ${Number(totalFee) / 1e9} TON`
1139
- );
1140
- return totalFee.toString();
1141
- } catch (error) {
1142
- console.warn("Failed to estimate TON fee:", error);
1143
- return TON_CONFIG.estimatedNetworkFee;
1144
- }
1145
- }
1146
- function addTonNetworkFee(quote, chains, estimatedFee) {
1147
- if (!quote || quote.srcChainKey.toLowerCase() !== "ton") {
1148
- return quote;
1149
- }
1150
- const tonChain = chains?.find((c2) => c2.chainKey.toLowerCase() === "ton");
1151
- if (!tonChain?.nativeCurrency?.address) {
1152
- console.warn("Could not find TON native currency address");
1153
- return quote;
1154
- }
1155
- const networkFee = {
1156
- token: tonChain.nativeCurrency.address,
1157
- chainKey: "ton",
1158
- amount: estimatedFee || TON_CONFIG.estimatedNetworkFee,
1159
- type: "network"
1160
- };
1161
- const hasNetworkFee = quote.fees?.some(
1162
- (fee) => fee.type === "network" && fee.chainKey === "ton"
1163
- );
1164
- if (hasNetworkFee) {
1165
- return quote;
1166
- }
1167
- return {
1168
- ...quote,
1169
- fees: [...quote.fees || [], networkFee]
1170
- };
1171
- }
1172
- async function estimateTronNetworkFee(tronWeb, quote, userAddress) {
1173
- try {
1174
- const accountResources = await tronWeb.trx.getAccountResources(userAddress);
1175
- const availableEnergy = accountResources.EnergyLimit || 0;
1176
- const tronStep = quote.steps?.find(
1177
- (s2) => s2.chainKey.toLowerCase() === "tron" && s2.type === "bridge"
1178
- );
1179
- if (!tronStep?.transaction?.data || !tronStep.transaction.to) {
1180
- console.warn("No TRON transaction data in quote, using fallback");
1181
- return TRON_CONFIG.estimatedNetworkFee;
1182
- }
1183
- const contractAddress = tronWeb.address.fromHex(
1184
- tronStep.transaction.to.startsWith("41") ? tronStep.transaction.to : "41" + tronStep.transaction.to.slice(2)
1185
- );
1186
- const simulation = await tronWeb.transactionBuilder.triggerSmartContract(
1187
- contractAddress,
1188
- "function signature doesn't matter for energy estimation",
1189
- {
1190
- feeLimit: TRON_CONFIG.feeLimit,
1191
- callValue: tronStep.transaction.value ? Number(tronStep.transaction.value) : 0
1192
- },
1193
- [],
1194
- userAddress
1195
- );
1196
- const requiredEnergy = simulation.energy_used || 0;
1197
- const energyDeficit = Math.max(0, requiredEnergy - availableEnergy);
1198
- if (energyDeficit === 0) {
1199
- return "0";
1200
- }
1201
- const energyPriceInSun = 420;
1202
- const feeSun = energyDeficit * energyPriceInSun;
1203
- console.log(
1204
- `TRON fee estimation: ${requiredEnergy} energy required, ${availableEnergy} available, ${feeSun / 1e6} TRX fee`
1205
- );
1206
- return feeSun.toString();
1207
- } catch (error) {
1208
- console.warn("Failed to estimate TRON network fee:", error);
1209
- return TRON_CONFIG.estimatedNetworkFee;
1210
- }
1211
- }
1212
- function addTronNetworkFee(quote, chains, estimatedFee) {
1213
- if (!quote || quote.srcChainKey.toLowerCase() !== "tron") {
1214
- return quote;
1215
- }
1216
- const tronChain = chains?.find((c2) => c2.chainKey.toLowerCase() === "tron");
1217
- if (!tronChain?.nativeCurrency?.address) {
1218
- console.warn("Could not find TRON native currency address");
1219
- return quote;
1220
- }
1221
- const networkFee = {
1222
- token: tronChain.nativeCurrency.address,
1223
- chainKey: "tron",
1224
- amount: estimatedFee || TRON_CONFIG.estimatedNetworkFee,
1225
- type: "network"
1226
- };
1227
- const hasNetworkFee = quote.fees?.some(
1228
- (fee) => fee.type === "network" && fee.chainKey === "tron"
1229
- );
1230
- if (hasNetworkFee) {
1231
- return quote;
1232
- }
1233
- return {
1234
- ...quote,
1235
- fees: [...quote.fees || [], networkFee]
1236
- };
1237
- }
1238
- async function estimateEvmNetworkFee(publicClient, quote, chainKey) {
1239
- try {
1240
- let totalGasLimit = 0n;
1241
- for (const step of quote.steps || []) {
1242
- if (step.chainKey.toLowerCase() !== chainKey.toLowerCase()) continue;
1243
- if (step.type === "approve") {
1244
- totalGasLimit += EVM_CONFIG.gasEstimates.approve;
1245
- } else if (step.type === "bridge") {
1246
- totalGasLimit += EVM_CONFIG.gasEstimates.bridge;
1247
- }
1248
- }
1249
- if (totalGasLimit === 0n) {
1250
- return "0";
1251
- }
1252
- totalGasLimit = totalGasLimit * BigInt(Math.floor(EVM_CONFIG.gasBuffer * 100)) / 100n;
1253
- const gasPrice = await publicClient.getGasPrice();
1254
- const totalCostWei = totalGasLimit * gasPrice;
1255
- return totalCostWei.toString();
1256
- } catch (error) {
1257
- console.warn("Failed to estimate EVM gas fee:", error);
1258
- return "10000000000000000";
1259
- }
1260
- }
1261
- function addEvmNetworkFee(quote, chains, estimatedFee) {
1262
- if (!quote) return quote;
1263
- const srcChainKey = quote.srcChainKey.toLowerCase();
1264
- if (srcChainKey === "ton" || srcChainKey === "tron") {
1265
- return quote;
1266
- }
1267
- const srcChain = chains?.find(
1268
- (c2) => c2.chainKey.toLowerCase() === srcChainKey
1269
- );
1270
- if (!srcChain?.nativeCurrency?.address) {
1271
- return quote;
1272
- }
1273
- const hasNetworkFee = quote.fees?.some(
1274
- (fee) => fee.type === "network" && fee.chainKey.toLowerCase() === srcChainKey
1275
- );
1276
- if (hasNetworkFee) {
1277
- return quote;
1278
- }
1279
- const networkFee = {
1280
- token: srcChain.nativeCurrency.address,
1281
- chainKey: quote.srcChainKey,
1282
- amount: estimatedFee || "10000000000000000",
1283
- type: "network"
1284
- };
1285
- return {
1286
- ...quote,
1287
- fees: [...quote.fees || [], networkFee]
1288
- };
1289
- }
1290
- function getQuoteDetails(quote, srcToken, dstToken, tokens, chains, slippageBps) {
1291
- const amounts = getQuoteAmounts(quote, srcToken, dstToken);
1292
- const fees = getQuoteFees(quote, tokens, chains, srcToken, dstToken);
1293
- const minimumReceived = calculateMinReceived(quote, slippageBps, dstToken);
1294
- return {
1295
- inputAmount: amounts.inputHuman,
1296
- outputAmount: amounts.outputHuman,
1297
- outputAmountRounded: amounts.outputHumanRounded,
1298
- minimumReceived,
1299
- etaSeconds: quote?.duration?.estimated,
1300
- fees
1301
- };
1302
- }
1303
- function getRouteDisplayName(route) {
1304
- if (!route) return "Stargate Bridge";
1305
- const routeLower = route.toLowerCase();
1306
- if (routeLower.includes("taxi")) return "Stargate V2 Fast";
1307
- if (routeLower.includes("bus")) return "Stargate V2 Economy";
1308
- if (routeLower.includes("oft")) return "OFT Bridge";
1309
- if (routeLower.includes("v2")) return "Stargate V2";
1310
- return route.split(/[/\-_]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
1311
- }
1312
943
  const toSharedDecimals = (amount, fromDecimals, toDecimals) => {
1313
944
  const value = BigInt(amount);
1314
945
  const diff = BigInt(toDecimals) - BigInt(fromDecimals);
@@ -1431,88 +1062,7 @@ function useBridgeQuote() {
1431
1062
  return;
1432
1063
  }
1433
1064
  if (cancelled) return;
1434
- let quoteWithFees = quoteRoute;
1435
- if (quoteRoute.srcChainKey.toLowerCase() === "ton") {
1436
- try {
1437
- const estimatedFee = estimateTonNetworkFee(quoteRoute);
1438
- quoteWithFees = addTonNetworkFee(quoteRoute, chains, estimatedFee);
1439
- } catch (error) {
1440
- console.warn("Failed to estimate TON fee, using fallback:", error);
1441
- quoteWithFees = addTonNetworkFee(quoteRoute, chains);
1442
- }
1443
- }
1444
- if (quoteRoute.srcChainKey.toLowerCase() === "tron") {
1445
- const tronStrategy = chainRegistry.getStrategy("tron");
1446
- if (tronStrategy?.isConnected()) {
1447
- const tronWeb = tronStrategy.getClient();
1448
- const tronAddress = tronStrategy.getAccount();
1449
- if (tronWeb && tronAddress) {
1450
- try {
1451
- const estimatedFee = await estimateTronNetworkFee(
1452
- tronWeb,
1453
- quoteRoute,
1454
- tronAddress
1455
- );
1456
- quoteWithFees = addTronNetworkFee(
1457
- quoteWithFees || quoteRoute,
1458
- chains,
1459
- estimatedFee
1460
- );
1461
- } catch (error) {
1462
- console.warn(
1463
- "Failed to estimate TRON fee, using fallback:",
1464
- error
1465
- );
1466
- quoteWithFees = addTronNetworkFee(
1467
- quoteWithFees || quoteRoute,
1468
- chains
1469
- );
1470
- }
1471
- } else {
1472
- quoteWithFees = addTronNetworkFee(
1473
- quoteWithFees || quoteRoute,
1474
- chains
1475
- );
1476
- }
1477
- } else {
1478
- quoteWithFees = addTronNetworkFee(
1479
- quoteWithFees || quoteRoute,
1480
- chains
1481
- );
1482
- }
1483
- }
1484
- const srcChainKey = quoteRoute.srcChainKey.toLowerCase();
1485
- if (srcChainKey !== "ton" && srcChainKey !== "tron") {
1486
- if (publicClient) {
1487
- try {
1488
- const estimatedFee = await estimateEvmNetworkFee(
1489
- publicClient,
1490
- quoteRoute,
1491
- quoteRoute.srcChainKey
1492
- );
1493
- quoteWithFees = addEvmNetworkFee(
1494
- quoteWithFees || quoteRoute,
1495
- chains,
1496
- estimatedFee
1497
- );
1498
- } catch (error) {
1499
- console.warn(
1500
- "Failed to estimate EVM fee, using fallback:",
1501
- error
1502
- );
1503
- quoteWithFees = addEvmNetworkFee(
1504
- quoteWithFees || quoteRoute,
1505
- chains
1506
- );
1507
- }
1508
- } else {
1509
- quoteWithFees = addEvmNetworkFee(
1510
- quoteWithFees || quoteRoute,
1511
- chains
1512
- );
1513
- }
1514
- }
1515
- setQuote(quoteWithFees || quoteRoute);
1065
+ setQuote(quoteRoute);
1516
1066
  } catch {
1517
1067
  if (!cancelled) {
1518
1068
  resetUi();
@@ -2488,12 +2038,20 @@ const SearchInput = ({
2488
2038
  placeholder,
2489
2039
  className: cn$2(
2490
2040
  "w-full outline-none px-5 py-4 relative pl-16 bg-input border transition-all border-transparent rounded-xs ring-0 leading-0 h-13 text-base focus-visible:border focus-visible:border-ring",
2041
+ value && "pr-16",
2491
2042
  className
2492
2043
  ),
2493
2044
  value,
2494
2045
  onChange: (e2) => onChange(e2.target.value)
2495
2046
  }
2496
- )
2047
+ ),
2048
+ value && /* @__PURE__ */ jsx("div", { className: "absolute z-10 right-4 top-0 bottom-0 my-auto h-5 w-5 bg-accent flex items-center justify-center rounded-full", children: /* @__PURE__ */ jsx(
2049
+ XIcon,
2050
+ {
2051
+ className: "w-4 h-4 text-foreground cursor-pointer hover:opacity-70 transition-opacity",
2052
+ onClick: () => onChange("")
2053
+ }
2054
+ ) })
2497
2055
  ] });
2498
2056
  };
2499
2057
  const ChainSelectModal = ({
@@ -2643,49 +2201,58 @@ const ChainSelectModal = ({
2643
2201
  chain2.chainKey
2644
2202
  );
2645
2203
  };
2646
- return /* @__PURE__ */ jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxs(DialogContent, { className: "md:max-h-[90dvh] md:h-[90dvh] fixed top-0 left-0 right-0 bottom-0 translate-x-0 translate-y-0 md:left-[50%] md:top-[50%] md:translate-x-[-50%] md:translate-y-[-50%] overflow-hidden flex flex-col p-10 pt-7 rounded-none md:rounded-lg", children: [
2647
- /* @__PURE__ */ jsx(DialogHeader, { className: "text-left pb-0", children: /* @__PURE__ */ jsx(DialogTitle, { className: "text-xl leading-8", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0", children: [
2648
- /* @__PURE__ */ jsx("div", { children: t2("bridge.select") }),
2649
- /* @__PURE__ */ jsx("div", { children: t2(isSource ? "bridge.sourceNetwork" : "bridge.destinationNetwork") })
2650
- ] }) }) }),
2651
- /* @__PURE__ */ jsx(
2652
- SearchInput,
2653
- {
2654
- placeholder: t2("bridge.search"),
2655
- value: query,
2656
- onChange: setQuery,
2657
- className: "text-foreground placeholder:text-muted-foreground"
2658
- }
2659
- ),
2660
- /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto [&::-webkit-scrollbar]:w-1 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-muted-foreground/20 [&::-webkit-scrollbar-thumb]:rounded-full hover:[&::-webkit-scrollbar-thumb]:bg-muted-foreground/30", children: [
2661
- groupedChains.available.length > 0 && groupedChains.available.map((c2) => renderChainItem(c2, false)),
2662
- groupedChains.willChangeSrc.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
2663
- /* @__PURE__ */ jsx(
2664
- "p",
2665
- {
2666
- className: `px-5 py-2 leading-4 text-base font-semibold text-muted-foreground uppercase ${groupedChains.available.length > 0 ? "mt-10" : ""}`,
2667
- children: t2("bridge.willChangeSourceChain")
2668
- }
2669
- ),
2670
- groupedChains.willChangeSrc.map(
2671
- (c2) => renderChainItem(c2, true, false)
2672
- )
2673
- ] }),
2674
- groupedChains.willChangeTokenAndSrc.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
2204
+ return /* @__PURE__ */ jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxs(
2205
+ DialogContent,
2206
+ {
2207
+ className: "md:max-h-[90dvh] md:h-[90dvh] fixed top-0 left-0 right-0 bottom-0 translate-x-0 translate-y-0 md:left-[50%] md:top-[50%] md:translate-x-[-50%] md:translate-y-[-50%] overflow-hidden flex flex-col p-6 md:p-10 md:pt-8 rounded-none md:rounded-lg",
2208
+ closeButtonClassName: "right-6 md:right-10",
2209
+ children: [
2210
+ /* @__PURE__ */ jsx(DialogHeader, { className: "text-left pb-2", children: /* @__PURE__ */ jsx(DialogTitle, { className: "text-xl leading-8", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0", children: [
2211
+ /* @__PURE__ */ jsx("div", { children: t2("bridge.select") }),
2212
+ /* @__PURE__ */ jsx("div", { children: t2(
2213
+ isSource ? "bridge.sourceNetwork" : "bridge.destinationNetwork"
2214
+ ) })
2215
+ ] }) }) }),
2675
2216
  /* @__PURE__ */ jsx(
2676
- "p",
2217
+ SearchInput,
2677
2218
  {
2678
- className: `px-5 py-2 leading-4 text-base font-semibold text-muted-foreground uppercase ${groupedChains.available.length > 0 || groupedChains.willChangeSrc.length > 0 ? "mt-10" : ""}`,
2679
- children: t2("bridge.willChangeSourceNetworkAndToken")
2219
+ placeholder: t2("bridge.search"),
2220
+ value: query,
2221
+ onChange: setQuery,
2222
+ className: "text-foreground placeholder:text-muted-foreground"
2680
2223
  }
2681
2224
  ),
2682
- groupedChains.willChangeTokenAndSrc.map(
2683
- (c2) => renderChainItem(c2, false, true)
2684
- )
2685
- ] }),
2686
- groupedChains.available.length === 0 && groupedChains.willChangeSrc.length === 0 && groupedChains.willChangeTokenAndSrc.length === 0 && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground px-12 py-2 h-28 flex items-center justify-center text-center", children: t2("bridge.chainNotFound") })
2687
- ] })
2688
- ] }) });
2225
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto [&::-webkit-scrollbar]:w-1 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-muted-foreground/20 [&::-webkit-scrollbar-thumb]:rounded-full hover:[&::-webkit-scrollbar-thumb]:bg-muted-foreground/30", children: [
2226
+ groupedChains.available.length > 0 && groupedChains.available.map((c2) => renderChainItem(c2, false)),
2227
+ groupedChains.willChangeSrc.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
2228
+ /* @__PURE__ */ jsx(
2229
+ "p",
2230
+ {
2231
+ className: `px-5 py-2 leading-4 text-base font-semibold text-muted-foreground uppercase ${groupedChains.available.length > 0 ? "mt-10" : ""}`,
2232
+ children: t2("bridge.willChangeSourceChain")
2233
+ }
2234
+ ),
2235
+ groupedChains.willChangeSrc.map(
2236
+ (c2) => renderChainItem(c2, true, false)
2237
+ )
2238
+ ] }),
2239
+ groupedChains.willChangeTokenAndSrc.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
2240
+ /* @__PURE__ */ jsx(
2241
+ "p",
2242
+ {
2243
+ className: `px-5 py-2 leading-4 text-base font-semibold text-muted-foreground uppercase ${groupedChains.available.length > 0 || groupedChains.willChangeSrc.length > 0 ? "mt-10" : ""}`,
2244
+ children: t2("bridge.willChangeSourceNetworkAndToken")
2245
+ }
2246
+ ),
2247
+ groupedChains.willChangeTokenAndSrc.map(
2248
+ (c2) => renderChainItem(c2, false, true)
2249
+ )
2250
+ ] }),
2251
+ groupedChains.available.length === 0 && groupedChains.willChangeSrc.length === 0 && groupedChains.willChangeTokenAndSrc.length === 0 && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground px-12 py-2 h-28 flex items-center justify-center text-center", children: t2("bridge.chainNotFound") })
2252
+ ] })
2253
+ ]
2254
+ }
2255
+ ) });
2689
2256
  };
2690
2257
  const useWalletSelectModal = create((set2) => ({
2691
2258
  isOpen: false,
@@ -2693,6 +2260,48 @@ const useWalletSelectModal = create((set2) => ({
2693
2260
  onOpen: (addressType) => set2({ isOpen: true, addressType }),
2694
2261
  onClose: () => set2({ isOpen: false, addressType: void 0 })
2695
2262
  }));
2263
+ const truncateToDecimals = (num, decimals) => {
2264
+ if (!isFinite(num) || isNaN(num)) return "0";
2265
+ const multiplier = Math.pow(10, decimals);
2266
+ const truncated = Math.floor(num * multiplier) / multiplier;
2267
+ return truncated.toFixed(decimals).replace(/\.?0+$/, "");
2268
+ };
2269
+ const formatTokenAmount = (amount, symbol, options) => {
2270
+ const normalizedSymbol = (symbol ?? "").toUpperCase();
2271
+ if (["USDT", "USDC", "DAI", "BUSD"].includes(normalizedSymbol) && amount >= 1) {
2272
+ return `${Math.floor(amount)} ${normalizedSymbol}`;
2273
+ }
2274
+ if (options?.decimals !== void 0) {
2275
+ return `${amount.toFixed(options.decimals)} ${normalizedSymbol}`;
2276
+ }
2277
+ if (amount >= 1) {
2278
+ return `${amount.toFixed(0)} ${normalizedSymbol}`;
2279
+ } else if (amount >= 1e-3) {
2280
+ return `${amount.toFixed(3)} ${normalizedSymbol}`;
2281
+ } else {
2282
+ return `${amount.toFixed(6)} ${normalizedSymbol}`;
2283
+ }
2284
+ };
2285
+ const formatUsd = (value) => {
2286
+ if (!value || !isFinite(value)) return "$0";
2287
+ if (value >= 1) return `$${value.toFixed(2)}`;
2288
+ return `$${value.toFixed(6).replace(/0+$/, "").replace(/\.$/, "")}`;
2289
+ };
2290
+ const formatPercentage = (bps, decimals = 2) => {
2291
+ return `${(bps / 100).toFixed(decimals).replace(/0+$/, "").replace(/\.$/, "")}%`;
2292
+ };
2293
+ const formatBalance = (amount, decimals = 2) => {
2294
+ if (!isFinite(amount) || isNaN(amount) || amount <= 0) {
2295
+ return "0.00";
2296
+ }
2297
+ return amount.toFixed(decimals);
2298
+ };
2299
+ const formatHash = (hash, startChars = 4, endChars = 4) => {
2300
+ if (!hash) return "";
2301
+ if (hash.length <= startChars + endChars) return hash;
2302
+ return `${hash.slice(0, startChars)}...${hash.slice(-endChars)}`;
2303
+ };
2304
+ const formatAddress = formatHash;
2696
2305
  const EditIcon = (props) => {
2697
2306
  return /* @__PURE__ */ jsxs(
2698
2307
  "svg",
@@ -3118,30 +2727,120 @@ const InfoIcon = (props) => {
3118
2727
  {
3119
2728
  d: "M6.56836 5.8519C6.56836 5.06104 7.20948 4.41992 8.00034 4.41992C8.7912 4.41992 9.43232 5.06104 9.43232 5.8519C9.43232 6.13698 9.34902 6.40259 9.20543 6.62574C8.77748 7.29081 8.00034 7.92501 8.00034 8.71587V9.07386M8.00034 11.3159V11.5798",
3120
2729
  stroke: "currentColor",
3121
- "stroke-width": "1.68349",
3122
- "stroke-linecap": "round"
2730
+ strokeWidth: "1.68349",
2731
+ strokeLinecap: "round"
3123
2732
  }
3124
2733
  )
3125
2734
  }
3126
- );
3127
- };
3128
- const Tip = (props) => {
3129
- const { children, text } = props;
3130
- return /* @__PURE__ */ jsxs(Tooltip, { children: [
3131
- /* @__PURE__ */ jsx(TooltipTrigger, { className: "w-4 h-4 rounded-full bg-muted text-muted-foreground", children }),
3132
- /* @__PURE__ */ jsx(TooltipContent, { className: "max-w-64", children: /* @__PURE__ */ jsx("p", { children: text }) })
3133
- ] });
3134
- };
3135
- const BASE_URL = "https://icons-ckg.pages.dev/stargate-light/tokens";
3136
- const TokenSymbol = ({
3137
- symbol,
3138
- className = "w-4 h-4",
3139
- alt
3140
- }) => {
3141
- const normalizedSymbol = normalizeTickerSymbol$1(symbol).toLowerCase();
3142
- const src2 = `${BASE_URL}/${normalizedSymbol}.svg`;
3143
- return /* @__PURE__ */ jsx("img", { src: src2, alt: alt ?? symbol, className });
3144
- };
2735
+ );
2736
+ };
2737
+ const Tip = (props) => {
2738
+ const { children, text } = props;
2739
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
2740
+ /* @__PURE__ */ jsx(TooltipTrigger, { className: "w-4 h-4 rounded-full bg-muted text-muted-foreground", children }),
2741
+ /* @__PURE__ */ jsx(TooltipContent, { className: "max-w-64", children: /* @__PURE__ */ jsx("p", { children: text }) })
2742
+ ] });
2743
+ };
2744
+ const BASE_URL = "https://icons-ckg.pages.dev/stargate-light/tokens";
2745
+ const TokenSymbol = ({
2746
+ symbol,
2747
+ className = "w-4 h-4",
2748
+ alt
2749
+ }) => {
2750
+ const normalizedSymbol = normalizeTickerSymbol$1(symbol).toLowerCase();
2751
+ const src2 = `${BASE_URL}/${normalizedSymbol}.svg`;
2752
+ return /* @__PURE__ */ jsx("img", { src: src2, alt: alt ?? symbol, className });
2753
+ };
2754
+ function getQuoteAmounts(quote, srcToken, dstToken) {
2755
+ if (!quote || !srcToken || !dstToken) {
2756
+ return {
2757
+ inputHuman: 0,
2758
+ outputHuman: 0,
2759
+ outputHumanRounded: "0",
2760
+ minReceivedHuman: 0
2761
+ };
2762
+ }
2763
+ const inputHuman = fromLD(quote.srcAmount, srcToken.decimals);
2764
+ const outputHuman = fromLD(quote.dstAmount, dstToken.decimals);
2765
+ const outputHumanRounded = truncateToDecimals(outputHuman, 2);
2766
+ const minReceivedHuman = fromLD(quote.dstAmountMin || "0", dstToken.decimals);
2767
+ return {
2768
+ inputHuman,
2769
+ outputHuman,
2770
+ outputHumanRounded,
2771
+ minReceivedHuman
2772
+ };
2773
+ }
2774
+ function getQuoteFees(quote, tokens, chains, srcToken, dstToken) {
2775
+ if (!quote || !tokens || !chains) {
2776
+ return {
2777
+ fees: { usd: /* @__PURE__ */ new Map(), original: /* @__PURE__ */ new Map(), formatted: /* @__PURE__ */ new Map() },
2778
+ inSrcToken: void 0,
2779
+ inDstToken: void 0
2780
+ };
2781
+ }
2782
+ const feeData = computeFeesUsdFromArray(quote.fees, tokens, chains);
2783
+ let inSrcToken = void 0;
2784
+ let inDstToken = void 0;
2785
+ if (srcToken && quote.srcChainKey) {
2786
+ const feeInSrcLD = sumFeeByTokenLD(
2787
+ quote.fees,
2788
+ srcToken.address,
2789
+ quote.srcChainKey
2790
+ );
2791
+ const feeInSrcHuman = fromLD(feeInSrcLD, srcToken.decimals);
2792
+ if (feeInSrcHuman > 0) {
2793
+ inSrcToken = Number(truncateToDecimals(feeInSrcHuman, 8));
2794
+ } else if ((feeData.usd.get("total") || 0) > 0 && srcToken.price?.usd) {
2795
+ const feeInSrcApprox = (feeData.usd.get("total") || 0) / srcToken.price.usd;
2796
+ inSrcToken = Number(truncateToDecimals(feeInSrcApprox, 8));
2797
+ }
2798
+ }
2799
+ if (dstToken && quote.dstChainKey) {
2800
+ const feeInDstLD = sumFeeByTokenLD(
2801
+ quote.fees,
2802
+ dstToken.address,
2803
+ quote.dstChainKey
2804
+ );
2805
+ const feeInDstHuman = fromLD(feeInDstLD, dstToken.decimals);
2806
+ if (feeInDstHuman > 0) {
2807
+ inDstToken = Number(truncateToDecimals(feeInDstHuman, 8));
2808
+ }
2809
+ }
2810
+ return {
2811
+ fees: feeData,
2812
+ inSrcToken,
2813
+ inDstToken
2814
+ };
2815
+ }
2816
+ function calculateMinReceived(quote, slippageBps, dstToken) {
2817
+ if (!quote || !dstToken) return 0;
2818
+ const dstAmountLD = BigInt(quote.dstAmount);
2819
+ const minAmountLD = dstAmountLD * BigInt(1e4 - slippageBps) / BigInt(1e4);
2820
+ return fromLD(minAmountLD.toString(), dstToken.decimals);
2821
+ }
2822
+ function getQuoteDetails(quote, srcToken, dstToken, tokens, chains, slippageBps) {
2823
+ const amounts = getQuoteAmounts(quote, srcToken, dstToken);
2824
+ const fees = getQuoteFees(quote, tokens, chains, srcToken, dstToken);
2825
+ const minimumReceived = calculateMinReceived(quote, slippageBps, dstToken);
2826
+ return {
2827
+ inputAmount: amounts.inputHuman,
2828
+ outputAmount: amounts.outputHuman,
2829
+ outputAmountRounded: amounts.outputHumanRounded,
2830
+ minimumReceived,
2831
+ etaSeconds: quote?.duration?.estimated,
2832
+ fees
2833
+ };
2834
+ }
2835
+ function getRouteDisplayName(route) {
2836
+ if (!route) return "Stargate Bridge";
2837
+ const routeLower = route.toLowerCase();
2838
+ if (routeLower.includes("taxi")) return "Stargate V2 Fast";
2839
+ if (routeLower.includes("bus")) return "Stargate V2 Economy";
2840
+ if (routeLower.includes("oft")) return "OFT Bridge";
2841
+ if (routeLower.includes("v2")) return "Stargate V2";
2842
+ return route.split(/[/\-_]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
2843
+ }
3145
2844
  function useGasEstimate(amountNum) {
3146
2845
  const { fromChain } = useChainsStore();
3147
2846
  const { selectedAssetSymbol } = useTokensStore();
@@ -3151,6 +2850,9 @@ function useGasEstimate(amountNum) {
3151
2850
  srcAddress
3152
2851
  );
3153
2852
  const { quote } = useBridgeQuoteStore();
2853
+ const { chainRegistry } = useChainStrategies();
2854
+ const [networkFeeEstimate, setNetworkFeeEstimate] = useState(0);
2855
+ const [networkFeeKnown, setNetworkFeeKnown] = useState(false);
3154
2856
  const balancesKnown = !balancesLoading;
3155
2857
  const chainKey = fromChain?.chainKey;
3156
2858
  const nativeCurrencySymbol = fromChain?.nativeCurrency?.symbol;
@@ -3159,6 +2861,44 @@ function useGasEstimate(amountNum) {
3159
2861
  const quoteFees = quote?.fees;
3160
2862
  const quoteSrcChainKey = quote?.srcChainKey;
3161
2863
  const nativeBalanceValue = nativeCurrencySymbol ? Number(balances[nativeCurrencySymbol.toUpperCase()]?.balance ?? 0) : 0;
2864
+ useEffect(() => {
2865
+ let cancelled = false;
2866
+ const estimate = async () => {
2867
+ setNetworkFeeEstimate(0);
2868
+ setNetworkFeeKnown(false);
2869
+ if (!chainKey || !quote?.steps?.length) {
2870
+ return;
2871
+ }
2872
+ const strategy = chainRegistry.getStrategy(chainKey);
2873
+ if (!strategy) {
2874
+ setNetworkFeeKnown(true);
2875
+ return;
2876
+ }
2877
+ const steps = quote.steps.filter((step) => step.chainKey === chainKey);
2878
+ if (!steps.length) {
2879
+ setNetworkFeeKnown(true);
2880
+ return;
2881
+ }
2882
+ try {
2883
+ const estimateValue = await strategy.estimateNetworkFee(steps);
2884
+ if (cancelled) return;
2885
+ setNetworkFeeEstimate(
2886
+ Number.isFinite(estimateValue) ? estimateValue : 0
2887
+ );
2888
+ } catch {
2889
+ if (cancelled) return;
2890
+ setNetworkFeeEstimate(0);
2891
+ } finally {
2892
+ if (!cancelled) {
2893
+ setNetworkFeeKnown(true);
2894
+ }
2895
+ }
2896
+ };
2897
+ void estimate();
2898
+ return () => {
2899
+ cancelled = true;
2900
+ };
2901
+ }, [chainKey, quote?.steps, chainRegistry]);
3162
2902
  const result = useMemo(() => {
3163
2903
  if (!chainKey || !nativeCurrencySymbol) {
3164
2904
  return {
@@ -3178,7 +2918,7 @@ function useGasEstimate(amountNum) {
3178
2918
  if (quoteFees && quoteSrcChainKey === chainKey) {
3179
2919
  const fees = quoteFees;
3180
2920
  const feesInNative = fees.filter(
3181
- (f4) => f4.chainKey === chainKey && f4.token === nativeCurrencyAddress && f4.type === "network"
2921
+ (f4) => f4.chainKey === chainKey && f4.token === nativeCurrencyAddress
3182
2922
  ).reduce(
3183
2923
  (sum, f4) => sum + BigInt(f4.amount || "0"),
3184
2924
  0n
@@ -3187,13 +2927,16 @@ function useGasEstimate(amountNum) {
3187
2927
  requiredNative = Number(feesInNative) / Math.pow(10, decimals);
3188
2928
  quoteFeesAvailable = true;
3189
2929
  }
2930
+ if (networkFeeKnown) {
2931
+ requiredNative += networkFeeEstimate;
2932
+ }
3190
2933
  let hasEnoughGas = true;
3191
2934
  if (isNativeSelected) {
3192
2935
  hasEnoughGas = nativeBalance - (amountNum ?? 0) >= requiredNative;
3193
2936
  } else {
3194
2937
  hasEnoughGas = nativeBalance >= requiredNative;
3195
2938
  }
3196
- const shouldCheckGas = balancesKnown && quoteFeesAvailable;
2939
+ const shouldCheckGas = balancesKnown && quoteFeesAvailable && networkFeeKnown;
3197
2940
  return {
3198
2941
  nativeSym,
3199
2942
  nativeBalance,
@@ -3212,7 +2955,9 @@ function useGasEstimate(amountNum) {
3212
2955
  quoteSrcChainKey,
3213
2956
  amountNum,
3214
2957
  balancesKnown,
3215
- nativeBalanceValue
2958
+ nativeBalanceValue,
2959
+ networkFeeEstimate,
2960
+ networkFeeKnown
3216
2961
  ]);
3217
2962
  return result;
3218
2963
  }
@@ -3621,33 +3366,6 @@ class TransactionFailedError extends ChainStrategyError {
3621
3366
  this.txHash = txHash;
3622
3367
  }
3623
3368
  }
3624
- class TransactionTimeoutError extends ChainStrategyError {
3625
- constructor(chainKey, txHash) {
3626
- super(
3627
- `${chainKey.toUpperCase()} transaction confirmation timeout: ${txHash}`,
3628
- "TRANSACTION_TIMEOUT",
3629
- chainKey
3630
- );
3631
- __publicField(this, "txHash");
3632
- this.name = "TransactionTimeoutError";
3633
- this.txHash = txHash;
3634
- }
3635
- }
3636
- class TransactionRevertedError extends ChainStrategyError {
3637
- constructor(chainKey, txHash, revertReason) {
3638
- const reason = revertReason ? `: ${revertReason}` : "";
3639
- super(
3640
- `${chainKey.toUpperCase()} transaction reverted on-chain${reason}`,
3641
- "TRANSACTION_REVERTED",
3642
- chainKey
3643
- );
3644
- __publicField(this, "txHash");
3645
- __publicField(this, "revertReason");
3646
- this.name = "TransactionRevertedError";
3647
- this.txHash = txHash;
3648
- this.revertReason = revertReason;
3649
- }
3650
- }
3651
3369
  class ProviderNotAvailableError extends ChainStrategyError {
3652
3370
  constructor(chainKey, reason) {
3653
3371
  const message = reason ? `${chainKey.toUpperCase()} provider not available: ${reason}` : `${chainKey.toUpperCase()} provider not available`;
@@ -3704,6 +3422,38 @@ async function getLayerZeroMessageByTx(txHash) {
3704
3422
  return null;
3705
3423
  }
3706
3424
  }
3425
+ async function waitForLayerZeroCompletion(txHash, timeoutMs = 6e5, pollIntervalMs = 1e4) {
3426
+ const deadline = Date.now() + timeoutMs;
3427
+ while (Date.now() < deadline) {
3428
+ try {
3429
+ const message = await getLayerZeroMessageByTx(txHash);
3430
+ if (message) {
3431
+ const statusName = message.status?.name;
3432
+ if (statusName === "DELIVERED") {
3433
+ return {
3434
+ completed: true,
3435
+ status: "DELIVERED",
3436
+ dstTxHash: message.destination?.tx?.txHash,
3437
+ message
3438
+ };
3439
+ }
3440
+ if (statusName === "FAILED") {
3441
+ return {
3442
+ completed: false,
3443
+ status: "FAILED",
3444
+ message
3445
+ };
3446
+ }
3447
+ }
3448
+ } catch {
3449
+ }
3450
+ await new Promise((r2) => setTimeout(r2, pollIntervalMs));
3451
+ }
3452
+ return {
3453
+ completed: false,
3454
+ status: "TIMEOUT"
3455
+ };
3456
+ }
3707
3457
  function useBridgeTransaction() {
3708
3458
  const { quote } = useBridgeQuoteStore();
3709
3459
  const { chainRegistry } = useChainStrategies();
@@ -3779,59 +3529,76 @@ function useBridgeTransaction() {
3779
3529
  txStore.setSrcHash(hash);
3780
3530
  txStore.updateStatus("processing");
3781
3531
  });
3782
- if (txResult?.tonTransactionHash) {
3783
- txStore.setTonTransactionHash(txResult.tonTransactionHash);
3784
- }
3785
3532
  if (txResult?.hash) {
3786
- strategy.waitForCompletion(txResult.hash, context).then((result) => {
3787
- if (result.completed) {
3788
- if (result.dstTxHash) {
3789
- txStore.setDstHash(result.dstTxHash);
3533
+ const trackWithLayerZero = async () => {
3534
+ let hashForLayerZero = txResult.hash;
3535
+ const messageHash = txResult.hash;
3536
+ if (quote.srcChainKey === "ton" && strategy.convertMessageHashToTxHash) {
3537
+ const tonTxHash = await strategy.convertMessageHashToTxHash(
3538
+ messageHash,
3539
+ 6e4
3540
+ );
3541
+ if (tonTxHash) {
3542
+ hashForLayerZero = tonTxHash;
3543
+ txStore.setTonTransactionHash(tonTxHash);
3544
+ } else {
3545
+ console.warn("Failed to convert TON message hash to tx hash");
3790
3546
  }
3791
- if (result.actualFeeValue) {
3792
- let feeSymbol = result.actualFeeSymbol;
3793
- if (!feeSymbol) {
3794
- const srcChain2 = chains?.find(
3795
- (c2) => c2.chainKey === quote.srcChainKey
3796
- );
3797
- feeSymbol = srcChain2?.nativeCurrency?.symbol || "";
3798
- }
3799
- const feeValue = parseFloat(result.actualFeeValue);
3800
- if (!isNaN(feeValue)) {
3801
- txStore.updateActualFee(feeValue, feeSymbol);
3802
- }
3547
+ }
3548
+ const lzResult = await waitForLayerZeroCompletion(
3549
+ hashForLayerZero,
3550
+ 6e5,
3551
+ 1e4
3552
+ );
3553
+ console.log("LayerZero delivery status:", lzResult.status);
3554
+ if (lzResult.completed) {
3555
+ if (lzResult.dstTxHash) {
3556
+ txStore.setDstHash(lzResult.dstTxHash);
3803
3557
  }
3804
- txStore.updateStatus("completed");
3805
- console.log("Transaction completed successfully");
3806
- if (txResult.hash && strategy.getSourceCost) {
3558
+ if (strategy.getSourceCost) {
3807
3559
  const srcChain2 = chains?.find(
3808
3560
  (c2) => c2.chainKey === quote.srcChainKey
3809
3561
  );
3810
3562
  const feeSymbol = srcChain2?.nativeCurrency?.symbol || "";
3811
3563
  const { priceUsd } = findNativeMeta(allTokens, srcChain2);
3812
- const srcHash = txResult.hash;
3813
- const getSourceCost = strategy.getSourceCost;
3814
- getLayerZeroMessageByTx(srcHash).then((message) => {
3815
- if (quote.srcChainKey === "ton") return srcHash;
3816
- return message?.source?.tx?.txHash ?? srcHash;
3817
- }).then((sourceTxHash) => getSourceCost(sourceTxHash)).then((sourceCost) => {
3564
+ const hashForSourceCost = quote.srcChainKey === "ton" ? messageHash : hashForLayerZero;
3565
+ try {
3566
+ const sourceCost = await strategy.getSourceCost(
3567
+ hashForSourceCost
3568
+ );
3818
3569
  if (sourceCost?.totalNative !== void 0 && isFinite(sourceCost.totalNative)) {
3819
3570
  const feeUsd = priceUsd && priceUsd > 0 ? sourceCost.totalNative * priceUsd : void 0;
3571
+ console.log("Source cost calculated:", {
3572
+ gasFee: sourceCost.breakdown?.gasFee + " " + feeSymbol,
3573
+ layerZeroFee: sourceCost.breakdown?.layerZeroFee + " " + feeSymbol,
3574
+ total: sourceCost.totalNative + " " + feeSymbol,
3575
+ totalUsd: feeUsd ? "$" + feeUsd.toFixed(2) : "N/A"
3576
+ });
3820
3577
  txStore.updateLayerZeroTotalFee(
3821
3578
  sourceCost.totalNative,
3822
3579
  feeSymbol,
3823
3580
  feeUsd
3824
3581
  );
3825
3582
  }
3826
- }).catch((error) => {
3827
- console.warn("Failed to compute LayerZero total fee:", error);
3828
- });
3583
+ } catch (error) {
3584
+ console.warn("Failed to compute source cost:", error);
3585
+ }
3829
3586
  }
3587
+ txStore.updateStatus("completed");
3588
+ console.log("Transaction completed successfully via LayerZero");
3830
3589
  } else {
3831
- txStore.setError("TRANSACTION_FAILED_TO_COMPLETE");
3832
- console.error("Transaction completion failed:", result.error);
3590
+ if (lzResult.status === "FAILED") {
3591
+ txStore.setError("TRANSACTION_FAILED_TO_COMPLETE");
3592
+ console.error("LayerZero delivery failed");
3593
+ } else {
3594
+ txStore.updateStatus("completed");
3595
+ console.warn(
3596
+ "LayerZero tracking timed out, marking as completed"
3597
+ );
3598
+ }
3833
3599
  }
3834
- }).catch((err) => {
3600
+ };
3601
+ trackWithLayerZero().catch((err) => {
3835
3602
  if (isUserRejection(err)) {
3836
3603
  txStore.setError("TRANSACTION_REJECTED");
3837
3604
  } else if (ChainStrategyError.isChainStrategyError(err)) {
@@ -4931,11 +4698,60 @@ class ChainStrategyRegistry {
4931
4698
  await strategy.disconnect(options);
4932
4699
  }
4933
4700
  }
4701
+ const EVM_CONFIG = {
4702
+ usdtAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
4703
+ gasEstimates: {
4704
+ approve: 65000n,
4705
+ bridge: 300000n
4706
+ },
4707
+ gasBuffer: 1.2,
4708
+ // 20% buffer
4709
+ gasFeeMultiplier: 2,
4710
+ // Multiplier for wallet fee estimates
4711
+ timeout: 3e5,
4712
+ // 5 minutes (increased for slower networks)
4713
+ requiredConfirmations: 3
4714
+ // Wait for 3 confirmations for reorg protection
4715
+ };
4716
+ const TON_CONFIG = {
4717
+ apiUrl: "https://toncenter.com/api/v2",
4718
+ timeout: 36e4,
4719
+ // 6 minutes
4720
+ validUntil: 600,
4721
+ // 10 minutes
4722
+ pollingInterval: 5e3,
4723
+ // 5 seconds between transaction status checks
4724
+ estimatedNetworkFee: "1000000000"
4725
+ // 1 TON in nanoton (conservative estimate)
4726
+ };
4727
+ const TRON_CONFIG = {
4728
+ // 2 minutes (for 19 confirmations)
4729
+ feeLimit: 1e8,
4730
+ // 3 seconds between checks
4731
+ estimatedNetworkFee: "10000000"
4732
+ // 10 TRX in SUN (fallback estimate)
4733
+ };
4734
+ let tonClientInstance = null;
4735
+ function getTonClient(customClient, apiKey) {
4736
+ if (customClient) {
4737
+ return customClient;
4738
+ }
4739
+ if (!tonClientInstance) {
4740
+ tonClientInstance = new TonClient({
4741
+ endpoint: `${TON_CONFIG.apiUrl}/jsonRPC`,
4742
+ apiKey
4743
+ });
4744
+ }
4745
+ return tonClientInstance;
4746
+ }
4934
4747
  function isNativeAddress(addr) {
4935
4748
  if (!addr) return false;
4936
4749
  const a2 = addr.toLowerCase();
4937
4750
  return a2 === "native" || a2 === "0x0000000000000000000000000000000000000000" || a2 === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" || addr === "T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb";
4938
4751
  }
4752
+ function sleep(ms2) {
4753
+ return new Promise((resolve) => setTimeout(resolve, ms2));
4754
+ }
4939
4755
  function toTronBase58(addr, tronWeb) {
4940
4756
  if (!addr) throw new Error("Empty TRON address");
4941
4757
  if (addr.startsWith("T")) return addr;
@@ -4982,24 +4798,27 @@ async function getEvmBalances(publicClient, address, tokens) {
4982
4798
  if (!publicClient) {
4983
4799
  throw new Error("No public client provided");
4984
4800
  }
4985
- const nativeTokens = tokens.filter((t2) => isNativeAddress(t2.address));
4986
4801
  const erc20Tokens = tokens.filter(
4987
4802
  (t2) => !isNativeAddress(t2.address) && isAddress(t2.address)
4988
4803
  );
4989
- for (const token of nativeTokens) {
4804
+ const chainNative = publicClient.chain?.nativeCurrency;
4805
+ const nativeSymbol = chainNative?.symbol ?? "ETH";
4806
+ const nativeDecimals = chainNative?.decimals ?? 18;
4807
+ const maxAttempts = 2;
4808
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
4990
4809
  try {
4991
- const ethBalance = await publicClient.getBalance({
4810
+ const nativeBalance = await publicClient.getBalance({
4992
4811
  address
4993
4812
  });
4994
- const balance = parseFloat(formatUnits(ethBalance, token.decimals));
4813
+ const balance = parseFloat(formatUnits(nativeBalance, nativeDecimals));
4995
4814
  if (balance > 0) {
4996
- balances[token.symbol] = { balance, address };
4815
+ balances[nativeSymbol] = { balance, address };
4816
+ }
4817
+ break;
4818
+ } catch {
4819
+ if (attempt !== maxAttempts) {
4820
+ await sleep(250 * attempt);
4997
4821
  }
4998
- } catch (error) {
4999
- console.debug(
5000
- `Failed to get native balance for ${token.symbol}:`,
5001
- error
5002
- );
5003
4822
  }
5004
4823
  }
5005
4824
  if (erc20Tokens.length > 0) {
@@ -5033,11 +4852,7 @@ async function getEvmBalances(publicClient, address, tokens) {
5033
4852
  if (balance > 0) {
5034
4853
  balances[token.symbol] = { balance, address };
5035
4854
  }
5036
- } catch (error) {
5037
- console.debug(
5038
- `Failed to parse balance for ${token.symbol}:`,
5039
- error
5040
- );
4855
+ } catch {
5041
4856
  }
5042
4857
  }
5043
4858
  });
@@ -5068,8 +4883,7 @@ async function getEvmBalances(publicClient, address, tokens) {
5068
4883
  if (balance > 0) {
5069
4884
  balances[token.symbol] = { balance, address };
5070
4885
  }
5071
- } catch (error2) {
5072
- console.debug(`Failed to get balance for ${token.symbol}:`, error2);
4886
+ } catch {
5073
4887
  }
5074
4888
  }
5075
4889
  }
@@ -5129,12 +4943,7 @@ async function getTonBalances(address, tokens, customTonClient, tonApiKey) {
5129
4943
  balances[symbolNorm] = entry;
5130
4944
  }
5131
4945
  }
5132
- } catch (error) {
5133
- const errorMessage = error instanceof Error ? error.message : String(error);
5134
- const isNoWalletError = errorMessage.includes("exit_code: -13") || errorMessage.includes("exit_code:-13") || errorMessage.includes("exitCode: -13");
5135
- if (!isNoWalletError) {
5136
- console.debug(`Failed to get balance for ${token.symbol}:`, error);
5137
- }
4946
+ } catch {
5138
4947
  }
5139
4948
  }
5140
4949
  } catch (error) {
@@ -5156,8 +4965,7 @@ async function getTronBalances(tronWeb, address, tokens) {
5156
4965
  if (trxBalance > 0) {
5157
4966
  balances.TRX = { balance: trxBalance, address: ownerB58 };
5158
4967
  }
5159
- } catch (error) {
5160
- console.warn("Failed to get native TRX balance:", error);
4968
+ } catch {
5161
4969
  }
5162
4970
  for (const token of tokens) {
5163
4971
  try {
@@ -5191,21 +4999,19 @@ async function getTronBalances(tronWeb, address, tokens) {
5191
4999
  if (balance > 0) {
5192
5000
  balances[token.symbol] = { balance, address: ownerB58 };
5193
5001
  }
5194
- } catch (error) {
5195
- console.warn(`Failed to get TRON balance for ${token.symbol}:`, error);
5002
+ } catch {
5196
5003
  }
5197
5004
  }
5198
- } catch (error) {
5199
- console.error("Failed to get Tron balances:", error);
5005
+ } catch {
5200
5006
  }
5201
5007
  return balances;
5202
5008
  }
5203
- const ERC20_ABI = [
5009
+ const ERC20_ABI = parseAbi([
5204
5010
  "function approve(address spender, uint256 amount) returns (bool)",
5205
5011
  "function allowance(address owner, address spender) view returns (uint256)",
5206
5012
  "function decimals() view returns (uint8)",
5207
5013
  "function balanceOf(address owner) view returns (uint256)"
5208
- ];
5014
+ ]);
5209
5015
  class EvmChainStrategy {
5210
5016
  constructor(config) {
5211
5017
  __publicField(this, "config");
@@ -5253,14 +5059,9 @@ class EvmChainStrategy {
5253
5059
  }
5254
5060
  async getBalances(address, tokens) {
5255
5061
  if (!this.publicClient) {
5256
- console.warn("No publicClient available for balance query");
5257
5062
  return {};
5258
5063
  }
5259
- return await getEvmBalances(
5260
- this.publicClient,
5261
- address,
5262
- tokens
5263
- );
5064
+ return await getEvmBalances(this.publicClient, address, tokens);
5264
5065
  }
5265
5066
  isAddressValid(address) {
5266
5067
  if (!address) return false;
@@ -5296,7 +5097,6 @@ class EvmChainStrategy {
5296
5097
  }
5297
5098
  async getSourceCost(txHash) {
5298
5099
  if (!this.publicClient) {
5299
- console.warn("No publicClient available for source cost query");
5300
5100
  return null;
5301
5101
  }
5302
5102
  try {
@@ -5311,18 +5111,61 @@ class EvmChainStrategy {
5311
5111
  const gasFeeWei = gasUsed * gasPrice;
5312
5112
  const txValueWei = tx.value ?? 0n;
5313
5113
  const totalWei = gasFeeWei + txValueWei;
5314
- return {
5114
+ const sourceCost = {
5315
5115
  totalNative: Number(formatUnits(totalWei, 18)),
5316
5116
  breakdown: {
5317
5117
  gasFee: Number(formatUnits(gasFeeWei, 18)),
5318
5118
  layerZeroFee: Number(formatUnits(txValueWei, 18))
5319
5119
  }
5320
5120
  };
5121
+ return sourceCost;
5321
5122
  } catch (error) {
5322
5123
  console.warn("Failed to compute EVM source cost:", error);
5323
5124
  return null;
5324
5125
  }
5325
5126
  }
5127
+ async estimateNetworkFee(steps) {
5128
+ if (!this.walletClient) {
5129
+ return 0;
5130
+ }
5131
+ const account = this.config.evmAddress;
5132
+ const txSteps = steps.filter((step) => step.transaction?.to);
5133
+ if (!txSteps.length) {
5134
+ return 0;
5135
+ }
5136
+ const applyFeeMultiplier = (feePerGas) => {
5137
+ const multiplier = EVM_CONFIG.gasFeeMultiplier;
5138
+ if (!Number.isFinite(multiplier) || multiplier <= 1) {
5139
+ return feePerGas;
5140
+ }
5141
+ const scaled = BigInt(Math.round(multiplier * 100));
5142
+ return (feePerGas * scaled + 99n) / 100n;
5143
+ };
5144
+ let totalFeeWei = 0n;
5145
+ for (const step of txSteps) {
5146
+ const tx = step.transaction;
5147
+ if (!tx?.to) continue;
5148
+ try {
5149
+ const request = await this.walletClient.prepareTransactionRequest({
5150
+ account: tx.from || account,
5151
+ to: tx.to,
5152
+ data: tx.data,
5153
+ value: tx.value ? BigInt(tx.value) : void 0,
5154
+ chain: this.walletClient.chain
5155
+ });
5156
+ const gasLimit = request.gas;
5157
+ const maxFeePerGas = request.maxFeePerGas ?? request.gasPrice;
5158
+ if (gasLimit && maxFeePerGas) {
5159
+ totalFeeWei += gasLimit * applyFeeMultiplier(maxFeePerGas);
5160
+ }
5161
+ } catch {
5162
+ }
5163
+ }
5164
+ if (totalFeeWei === 0n) {
5165
+ return 0;
5166
+ }
5167
+ return Number(formatUnits(totalFeeWei, 18));
5168
+ }
5326
5169
  async executeSteps(steps, _context, onFirstHash) {
5327
5170
  if (!this.isConnected() || !this.walletClient) {
5328
5171
  throw new WalletNotConnectedError("evm");
@@ -5336,134 +5179,32 @@ class EvmChainStrategy {
5336
5179
  );
5337
5180
  if (step.type === "approve") {
5338
5181
  const hash = await this.approveTransaction(step);
5339
- console.log(`Approval transaction hash: ${hash}`);
5340
5182
  if (!firstTxHash) {
5341
5183
  firstTxHash = hash;
5342
5184
  onFirstHash?.(hash);
5343
5185
  }
5344
5186
  } else if (step.type === "bridge") {
5345
5187
  const hash = await this.executeTransaction(step);
5346
- console.log(`Bridge transaction hash: ${hash}`);
5347
5188
  if (!firstTxHash) {
5348
5189
  firstTxHash = hash;
5349
5190
  onFirstHash?.(hash);
5350
5191
  }
5351
5192
  } else {
5352
- throw new InvalidStepsError(
5353
- "evm",
5354
- `Unsupported step type: ${step.type}`
5355
- );
5356
- }
5357
- }
5358
- return {
5359
- hash: firstTxHash,
5360
- chainKey: steps[0]?.chainKey
5361
- };
5362
- } catch (error) {
5363
- if (error instanceof Error && error.name.includes("Error")) {
5364
- throw error;
5365
- }
5366
- throw toChainStrategyError(error, "evm", "transaction");
5367
- }
5368
- }
5369
- async waitForCompletion(txHash) {
5370
- try {
5371
- const publicClient = this.publicClient;
5372
- if (!publicClient) {
5373
- throw new ProviderNotAvailableError("evm");
5374
- }
5375
- console.log(
5376
- `Waiting for ${EVM_CONFIG.requiredConfirmations} confirmations for tx: ${txHash}`
5377
- );
5378
- const receipt = await publicClient.waitForTransactionReceipt({
5379
- hash: txHash,
5380
- confirmations: EVM_CONFIG.requiredConfirmations,
5381
- timeout: EVM_CONFIG.timeout
5382
- });
5383
- if (!receipt) {
5384
- const error = new TransactionTimeoutError("evm", txHash);
5385
- return {
5386
- completed: false,
5387
- error: error.message
5388
- };
5389
- }
5390
- if (receipt.status !== "success") {
5391
- const error = new TransactionRevertedError("evm", txHash);
5392
- return {
5393
- completed: false,
5394
- error: error.message
5395
- };
5396
- }
5397
- console.log(
5398
- `EVM transaction confirmed in block ${receipt.blockNumber} with ${EVM_CONFIG.requiredConfirmations} confirmations`
5399
- );
5400
- let actualFeeValue;
5401
- try {
5402
- const gasUsed = receipt.gasUsed;
5403
- const effectiveGasPrice = receipt.effectiveGasPrice;
5404
- if (gasUsed && effectiveGasPrice) {
5405
- const feeWei = gasUsed * effectiveGasPrice;
5406
- const feeInNative = formatUnits(feeWei, 18);
5407
- actualFeeValue = feeInNative;
5408
- console.log(`EVM transaction fee: ${feeInNative} (native token)`);
5193
+ throw new InvalidStepsError(
5194
+ "evm",
5195
+ `Unsupported step type: ${step.type}`
5196
+ );
5409
5197
  }
5410
- } catch (error) {
5411
- console.warn("Failed to calculate actual fee:", error);
5412
5198
  }
5413
5199
  return {
5414
- completed: true,
5415
- actualFeeValue
5416
- // Symbol will be determined by the caller based on chain info
5200
+ hash: firstTxHash,
5201
+ chainKey: steps[0]?.chainKey
5417
5202
  };
5418
5203
  } catch (error) {
5419
- if (error && typeof error === "object" && "code" in error && error.code === "TRANSACTION_REPLACED") {
5420
- console.log(
5421
- `Transaction was replaced: ${"reason" in error ? String(error.reason) : "unknown"}`
5422
- );
5423
- if ("receipt" in error && error.receipt) {
5424
- const replacementReceipt = error.receipt;
5425
- if (replacementReceipt.status === 1) {
5426
- console.log(
5427
- `Replacement transaction succeeded in block ${replacementReceipt.blockNumber}`
5428
- );
5429
- let actualFeeValue;
5430
- try {
5431
- const receipt = error.receipt;
5432
- const gasUsed = receipt.gasUsed;
5433
- const effectiveGasPrice = receipt.effectiveGasPrice;
5434
- if (gasUsed && effectiveGasPrice) {
5435
- const feeWei = gasUsed * effectiveGasPrice;
5436
- const feeInNative = formatUnits(feeWei, 18);
5437
- actualFeeValue = feeInNative;
5438
- console.log(
5439
- `Replacement transaction fee: ${feeInNative} (native token)`
5440
- );
5441
- }
5442
- } catch (feeError) {
5443
- console.warn("Failed to calculate replacement transaction fee:", feeError);
5444
- }
5445
- return {
5446
- completed: true,
5447
- actualFeeValue
5448
- };
5449
- } else {
5450
- const chainError2 = new TransactionRevertedError("evm", txHash);
5451
- return {
5452
- completed: false,
5453
- error: chainError2.message
5454
- };
5455
- }
5456
- }
5204
+ if (error instanceof Error && error.name.includes("Error")) {
5205
+ throw error;
5457
5206
  }
5458
- const chainError = toChainStrategyError(
5459
- error,
5460
- "evm",
5461
- "waitForCompletion"
5462
- );
5463
- return {
5464
- completed: false,
5465
- error: chainError.message
5466
- };
5207
+ throw toChainStrategyError(error, "evm", "transaction");
5467
5208
  }
5468
5209
  }
5469
5210
  async executeTransaction(step) {
@@ -5620,88 +5361,14 @@ class EvmChainStrategy {
5620
5361
  blockTag: "finalized"
5621
5362
  });
5622
5363
  if (!finalizedBlock) {
5623
- console.debug(
5624
- "Finalized block not available (pre-merge or unsupported)"
5625
- );
5626
5364
  return false;
5627
5365
  }
5628
- const isFinalized = blockNumber <= finalizedBlock.number;
5629
- if (isFinalized) {
5630
- console.log(
5631
- `Block ${blockNumber} has reached finality (finalized block: ${finalizedBlock.number})`
5632
- );
5633
- } else {
5634
- console.debug(
5635
- `Block ${blockNumber} not yet finalized (finalized block: ${finalizedBlock.number})`
5636
- );
5637
- }
5638
- return isFinalized;
5639
- } catch (error) {
5640
- console.debug("Error checking finality:", error);
5366
+ return blockNumber <= finalizedBlock.number;
5367
+ } catch {
5641
5368
  return false;
5642
5369
  }
5643
5370
  }
5644
5371
  }
5645
- function getNormalizedExtMessageHash(message) {
5646
- if (message.info.type !== "external-in") {
5647
- throw new Error(`Expected external-in message, got ${message.info.type}`);
5648
- }
5649
- const normalizedInfo = {
5650
- ...message.info,
5651
- src: void 0,
5652
- importFee: 0n
5653
- };
5654
- const normalizedMessage = {
5655
- ...message,
5656
- info: normalizedInfo,
5657
- init: null
5658
- };
5659
- return beginCell$1().store(storeMessage(normalizedMessage, { forceRef: true })).endCell().hash();
5660
- }
5661
- async function getTonTransactionHash(messageHash, userAddress, searchLimit = 20, options) {
5662
- try {
5663
- const client = options?.client ?? new TonClient({
5664
- endpoint: "https://toncenter.com/api/v2/jsonRPC",
5665
- apiKey: process.env.TONCENTER_API_KEY
5666
- // Optional: for rate limit increase
5667
- });
5668
- const messageHasher = options?.messageHasher ?? getNormalizedExtMessageHash;
5669
- const address = Address.parse(userAddress);
5670
- const transactions = await client.getTransactions(address, {
5671
- limit: searchLimit
5672
- });
5673
- for (const tx of transactions) {
5674
- const inMsg = tx.inMessage;
5675
- if (!inMsg) continue;
5676
- try {
5677
- const inMsgHash = messageHasher(inMsg).toString("hex");
5678
- if (inMsgHash === messageHash.replace("0x", "")) {
5679
- const txHash = tx.hash().toString("hex");
5680
- return {
5681
- transactionHash: `0x${txHash}`,
5682
- messageHash,
5683
- found: true
5684
- };
5685
- }
5686
- } catch {
5687
- continue;
5688
- }
5689
- }
5690
- console.warn(`TON transaction not found for message hash: ${messageHash}`);
5691
- return {
5692
- transactionHash: null,
5693
- messageHash,
5694
- found: false
5695
- };
5696
- } catch (error) {
5697
- console.error("Failed to get TON transaction hash:", error);
5698
- return {
5699
- transactionHash: null,
5700
- messageHash,
5701
- found: false
5702
- };
5703
- }
5704
- }
5705
5372
  class TonChainStrategy {
5706
5373
  constructor(config) {
5707
5374
  __publicField(this, "config");
@@ -5814,40 +5481,17 @@ class TonChainStrategy {
5814
5481
  validUntil: Math.floor(Date.now() / 1e3) + TON_CONFIG.validUntil,
5815
5482
  messages: tonMessages
5816
5483
  };
5817
- const result = await this.config.tonConnectUI.sendTransaction(
5818
- transaction2
5819
- );
5484
+ const result = await this.config.tonConnectUI.sendTransaction(transaction2);
5820
5485
  const bocBase64 = result.boc;
5821
5486
  try {
5822
5487
  const inMessage = loadMessage(Cell.fromBase64(bocBase64).beginParse());
5823
5488
  const messageHash = this.getNormalizedExtMessageHash(inMessage);
5824
5489
  const hexHash = messageHash.toString("hex");
5825
5490
  onFirstHash?.(hexHash);
5826
- let tonTransactionHash;
5827
- if (this.config.tonAddress) {
5828
- try {
5829
- const tonTxResult = await getTonTransactionHash(
5830
- hexHash,
5831
- this.config.tonAddress,
5832
- 20
5833
- );
5834
- if (tonTxResult.found && tonTxResult.transactionHash) {
5835
- tonTransactionHash = tonTxResult.transactionHash;
5836
- } else {
5837
- console.warn(
5838
- `TON transaction hash not found for message hash: ${hexHash}`
5839
- );
5840
- }
5841
- } catch (error) {
5842
- console.error("Failed to convert TON message hash:", error);
5843
- }
5844
- }
5845
5491
  return {
5846
5492
  chainKey: "ton",
5847
- hash: hexHash,
5848
- // Message hash for TONScan
5849
- tonTransactionHash
5850
- // Transaction hash for LayerZero (if found)
5493
+ hash: hexHash
5494
+ // Message hash for TONScan and for finding tx later
5851
5495
  };
5852
5496
  } catch (error) {
5853
5497
  console.error("Error parsing BOC to hex hash:", error);
@@ -5861,39 +5505,45 @@ class TonChainStrategy {
5861
5505
  throw toChainStrategyError(error, "ton", "transaction");
5862
5506
  }
5863
5507
  }
5864
- async waitForCompletion(txHash) {
5865
- try {
5866
- const result = await this.checkTonTransaction(
5867
- txHash,
5868
- TON_CONFIG.timeout
5869
- );
5870
- if (!result.confirmed) {
5871
- const error = new TransactionFailedError(
5872
- "ton",
5873
- "Transaction not confirmed on-chain",
5874
- txHash
5875
- );
5876
- return {
5877
- completed: false,
5878
- error: error.message
5879
- };
5508
+ /**
5509
+ * Convert TON message hash to transaction hash.
5510
+ * LayerZero uses transaction hash, but TonConnect returns message hash.
5511
+ */
5512
+ async convertMessageHashToTxHash(messageHash, timeoutMs = 6e4) {
5513
+ const deadline = Date.now() + timeoutMs;
5514
+ const client = getTonClient(this.config.tonClient, this.config.tonApiKey);
5515
+ if (!this.config.tonAddress) {
5516
+ return null;
5517
+ }
5518
+ const targetMessageHash = Buffer.from(messageHash, "hex");
5519
+ const accountAddress = Address.parse(this.config.tonAddress);
5520
+ while (Date.now() < deadline) {
5521
+ try {
5522
+ const transactions = await client.getTransactions(accountAddress, {
5523
+ limit: 20,
5524
+ archival: true
5525
+ });
5526
+ for (const tx of transactions) {
5527
+ if (tx.inMessage?.info.type === "external-in") {
5528
+ try {
5529
+ const txInMessageHash = this.getNormalizedExtMessageHash(
5530
+ tx.inMessage
5531
+ );
5532
+ if (txInMessageHash.equals(targetMessageHash)) {
5533
+ const txHash = `0x${tx.hash().toString("hex")}`;
5534
+ return txHash;
5535
+ }
5536
+ } catch {
5537
+ continue;
5538
+ }
5539
+ }
5540
+ }
5541
+ await new Promise((r2) => setTimeout(r2, 3e3));
5542
+ } catch {
5543
+ await new Promise((r2) => setTimeout(r2, 3e3));
5880
5544
  }
5881
- return {
5882
- completed: true,
5883
- actualFeeValue: result.fee,
5884
- actualFeeSymbol: "TON"
5885
- };
5886
- } catch (error) {
5887
- const chainError = toChainStrategyError(
5888
- error,
5889
- "ton",
5890
- "waitForCompletion"
5891
- );
5892
- return {
5893
- completed: false,
5894
- error: chainError.message
5895
- };
5896
5545
  }
5546
+ return null;
5897
5547
  }
5898
5548
  getNormalizedExtMessageHash(message) {
5899
5549
  if (message.info.type !== "external-in") {
@@ -5916,6 +5566,9 @@ class TonChainStrategy {
5916
5566
  if (typeof value === "number" && Number.isFinite(value)) {
5917
5567
  return BigInt(Math.trunc(value));
5918
5568
  }
5569
+ if (typeof value === "object" && value !== null && "coins" in value) {
5570
+ return this.toBigInt(value.coins);
5571
+ }
5919
5572
  if (typeof value === "string" && value.trim() !== "") {
5920
5573
  try {
5921
5574
  return BigInt(value);
@@ -5929,12 +5582,16 @@ class TonChainStrategy {
5929
5582
  const candidate = tx.outMessages;
5930
5583
  if (!candidate) return [];
5931
5584
  if (Array.isArray(candidate)) return candidate;
5932
- if (candidate instanceof Map) return Array.from(candidate.values());
5933
5585
  if (typeof candidate === "object" && candidate !== null && "values" in candidate && typeof candidate.values === "function") {
5934
- return Array.from(
5935
- candidate.values()
5936
- );
5586
+ const values = candidate.values();
5587
+ if (Array.isArray(values)) {
5588
+ return [...values];
5589
+ }
5590
+ if (values && typeof values === "object" && Symbol.iterator in values) {
5591
+ return Array.from(values);
5592
+ }
5937
5593
  }
5594
+ if (candidate instanceof Map) return Array.from(candidate.values());
5938
5595
  return [];
5939
5596
  }
5940
5597
  getMessageValue(message) {
@@ -5946,27 +5603,49 @@ class TonChainStrategy {
5946
5603
  }
5947
5604
  return this.toBigInt(value);
5948
5605
  }
5949
- getFirstOutMessageValue(tx) {
5606
+ getTotalOutMessageValue(tx) {
5950
5607
  const outMessages = this.getOutMessages(tx);
5951
5608
  if (!outMessages.length) return 0n;
5952
- const value = this.getMessageValue(outMessages[0]);
5953
- return value ?? 0n;
5609
+ let total = 0n;
5610
+ for (const message of outMessages) {
5611
+ const value = this.getMessageValue(message);
5612
+ if (value) {
5613
+ total += value;
5614
+ }
5615
+ }
5616
+ return total;
5954
5617
  }
5955
- async getSourceCost(txHash) {
5956
- const timeoutMs = Math.min(TON_CONFIG.timeout, 12e4);
5957
- const result = await this.checkTonTransaction(txHash, timeoutMs);
5958
- if (!result.confirmed) return null;
5618
+ async getSourceCost(messageHash) {
5619
+ const timeoutMs = 3e4;
5620
+ const result = await this.checkTonTransaction(messageHash, timeoutMs);
5621
+ if (!result.confirmed) {
5622
+ console.warn("Transaction not found for source cost calculation");
5623
+ return null;
5624
+ }
5959
5625
  const totalFees = result.totalFees ?? 0n;
5960
5626
  const outValue = result.outValue ?? 0n;
5961
5627
  const totalNanotons = totalFees + outValue;
5962
5628
  const toTon = (value) => Number(value) / 1e9;
5963
- return {
5629
+ const sourceCost = {
5964
5630
  totalNative: toTon(totalNanotons),
5965
5631
  breakdown: {
5966
5632
  gasFee: toTon(totalFees),
5967
5633
  layerZeroFee: toTon(outValue)
5968
5634
  }
5969
5635
  };
5636
+ console.log("TON source cost:", {
5637
+ gasFee: `${sourceCost.breakdown.gasFee} TON`,
5638
+ layerZeroFee: `${sourceCost.breakdown.layerZeroFee} TON`,
5639
+ total: `${sourceCost.totalNative} TON`
5640
+ });
5641
+ return sourceCost;
5642
+ }
5643
+ async estimateNetworkFee() {
5644
+ const fee = Number(TON_CONFIG.estimatedNetworkFee);
5645
+ if (!Number.isFinite(fee) || fee <= 0) {
5646
+ return 0;
5647
+ }
5648
+ return fee / 1e9;
5970
5649
  }
5971
5650
  async checkTonTransaction(hashOrBoc, timeoutMs = 36e4) {
5972
5651
  const deadline = Date.now() + timeoutMs;
@@ -5977,10 +5656,6 @@ class TonChainStrategy {
5977
5656
  try {
5978
5657
  const inMessage = loadMessage(Cell.fromBase64(hashOrBoc).beginParse());
5979
5658
  if (inMessage.info.type !== "external-in") {
5980
- console.debug(
5981
- "Expected external-in message, got:",
5982
- inMessage.info.type
5983
- );
5984
5659
  return { confirmed: false };
5985
5660
  }
5986
5661
  accountAddress = inMessage.info.dest;
@@ -5988,63 +5663,50 @@ class TonChainStrategy {
5988
5663
  } catch {
5989
5664
  targetMessageHash = Buffer.from(hashOrBoc, "hex");
5990
5665
  if (!this.config.tonAddress) {
5991
- console.debug("No wallet address available for hex hash lookup");
5992
5666
  return { confirmed: false };
5993
5667
  }
5994
5668
  accountAddress = Address.parse(this.config.tonAddress);
5995
5669
  }
5996
- let lt2 = void 0;
5997
- let hash = void 0;
5998
5670
  while (Date.now() < deadline) {
5999
5671
  try {
6000
5672
  const transactions = await client.getTransactions(accountAddress, {
6001
- lt: lt2,
6002
- hash,
6003
- limit: 10,
5673
+ limit: 20,
5674
+ // Check last 20 transactions
6004
5675
  archival: true
6005
5676
  });
6006
- if (transactions.length === 0) {
6007
- await new Promise((r2) => setTimeout(r2, TON_CONFIG.pollingInterval));
6008
- lt2 = void 0;
6009
- hash = void 0;
6010
- continue;
6011
- }
6012
5677
  for (const tx of transactions) {
6013
5678
  if (tx.inMessage?.info.type === "external-in") {
6014
- const txInMessageHash = this.getNormalizedExtMessageHash(
6015
- tx.inMessage
6016
- );
6017
- if (txInMessageHash.equals(targetMessageHash)) {
6018
- console.debug("Transaction found by in-message hash");
6019
- const totalFees = this.toBigInt(
6020
- tx.totalFees
6021
- ) ?? 0n;
6022
- const outValue = this.getFirstOutMessageValue(tx);
6023
- const feeInTon = Number(totalFees) / 1e9;
6024
- console.log(`TON transaction fee: ${feeInTon} TON`);
6025
- return {
6026
- confirmed: true,
6027
- fee: feeInTon.toString(),
6028
- totalFees,
6029
- outValue
6030
- };
5679
+ try {
5680
+ const txInMessageHash = this.getNormalizedExtMessageHash(
5681
+ tx.inMessage
5682
+ );
5683
+ if (txInMessageHash.equals(targetMessageHash)) {
5684
+ const totalFees = this.toBigInt(tx.totalFees) ?? this.toBigInt(
5685
+ tx.total_fees
5686
+ ) ?? 0n;
5687
+ const outValue = this.getTotalOutMessageValue(tx);
5688
+ const feeInTon = Number(totalFees) / 1e9;
5689
+ const transactionHash = tx.hash().toString("hex");
5690
+ return {
5691
+ confirmed: true,
5692
+ fee: feeInTon.toString(),
5693
+ totalFees,
5694
+ outValue,
5695
+ transactionHash
5696
+ };
5697
+ }
5698
+ } catch {
5699
+ continue;
6031
5700
  }
6032
5701
  }
6033
5702
  }
6034
- const lastTx = transactions[transactions.length - 1];
6035
- lt2 = lastTx.lt.toString();
6036
- hash = lastTx.hash().toString("base64");
6037
5703
  await new Promise((r2) => setTimeout(r2, TON_CONFIG.pollingInterval));
6038
- } catch (error) {
6039
- console.debug("Error fetching transactions:", error);
5704
+ } catch {
6040
5705
  await new Promise((r2) => setTimeout(r2, TON_CONFIG.pollingInterval));
6041
- lt2 = void 0;
6042
- hash = void 0;
6043
5706
  }
6044
5707
  }
6045
5708
  return { confirmed: false };
6046
- } catch (error) {
6047
- console.debug("Error parsing BOC or checking transaction:", error);
5709
+ } catch {
6048
5710
  return { confirmed: false };
6049
5711
  }
6050
5712
  }
@@ -6054,6 +5716,7 @@ class TronChainStrategy {
6054
5716
  constructor(config) {
6055
5717
  __publicField(this, "config");
6056
5718
  __publicField(this, "fallbackClient");
5719
+ __publicField(this, "apiKeyApplied", /* @__PURE__ */ new WeakSet());
6057
5720
  this.config = config;
6058
5721
  }
6059
5722
  canHandle(chainKey) {
@@ -6219,18 +5882,31 @@ class TronChainStrategy {
6219
5882
  const feeTrx = feeSun / 1e6;
6220
5883
  const lzFeeTrx = callValueSun / 1e6;
6221
5884
  const totalTrx = (feeSun + callValueSun) / 1e6;
6222
- return {
5885
+ const sourceCost = {
6223
5886
  totalNative: totalTrx,
6224
5887
  breakdown: {
6225
5888
  gasFee: feeTrx,
6226
5889
  layerZeroFee: lzFeeTrx
6227
5890
  }
6228
5891
  };
5892
+ console.log("TRON source cost:", {
5893
+ gasFee: `${sourceCost.breakdown.gasFee} TRX`,
5894
+ layerZeroFee: `${sourceCost.breakdown.layerZeroFee} TRX`,
5895
+ total: `${sourceCost.totalNative} TRX`
5896
+ });
5897
+ return sourceCost;
6229
5898
  } catch (error) {
6230
5899
  console.warn("Failed to compute TRON source cost:", error);
6231
5900
  return null;
6232
5901
  }
6233
5902
  }
5903
+ async estimateNetworkFee() {
5904
+ const fee = Number(TRON_CONFIG.estimatedNetworkFee);
5905
+ if (!Number.isFinite(fee) || fee <= 0) {
5906
+ return 0;
5907
+ }
5908
+ return fee / 1e6;
5909
+ }
6234
5910
  async executeSteps(steps, _context, onFirstHash) {
6235
5911
  const tronWeb = this.getClient();
6236
5912
  if (!tronWeb) {
@@ -6327,137 +6003,59 @@ class TronChainStrategy {
6327
6003
  }
6328
6004
  return { hash: lastTxId, chainKey: "tron" };
6329
6005
  }
6330
- async waitForCompletion(txHash) {
6331
- try {
6332
- const tronWeb = this.getClient();
6333
- if (!tronWeb) {
6334
- throw new ProviderNotAvailableError("tron");
6335
- }
6336
- console.log(
6337
- `Waiting for ${TRON_CONFIG.requiredConfirmations} confirmations for TRON tx: ${txHash}`
6338
- );
6339
- const deadline = Date.now() + TRON_CONFIG.timeout;
6340
- let txBlockNumber = null;
6341
- let actualFeeTrx = null;
6342
- while (Date.now() < deadline && !txBlockNumber) {
6343
- try {
6344
- const info = await tronWeb.trx.getTransactionInfo(txHash);
6345
- if (info && info.blockNumber) {
6346
- const result = info.receipt?.result;
6347
- if (result !== "SUCCESS") {
6348
- const msg = this.hexToAscii(info.resMessage) || null;
6349
- let reason = msg;
6350
- const cr2 = info.contractResult?.[0];
6351
- if (cr2 && /^0x?08c379a0/i.test(cr2)) {
6352
- try {
6353
- const clean2 = cr2.replace(/^0x/, "");
6354
- const len = parseInt(clean2.slice(8 + 64, 8 + 64 + 64), 16);
6355
- const strHex = clean2.slice(
6356
- 8 + 64 + 64,
6357
- 8 + 64 + 64 + len * 2
6358
- );
6359
- const str = this.hexToAscii("0x" + strHex);
6360
- if (str) reason = str;
6361
- } catch (e2) {
6362
- console.debug("TRON revert string decode error", e2);
6363
- }
6364
- }
6365
- const error2 = new TransactionRevertedError(
6366
- "tron",
6367
- txHash,
6368
- reason || "Unknown error"
6369
- );
6370
- return {
6371
- completed: false,
6372
- error: error2.message
6373
- };
6374
- }
6375
- txBlockNumber = info.blockNumber;
6376
- const feeSun = info.fee || 0;
6377
- actualFeeTrx = feeSun / 1e6;
6378
- console.log(
6379
- `TRON transaction found in block ${txBlockNumber}, fee: ${actualFeeTrx} TRX`
6380
- );
6381
- }
6382
- } catch (e2) {
6383
- console.debug("TRON getTransactionInfo error:", e2);
6384
- }
6385
- if (!txBlockNumber) {
6386
- await new Promise((r2) => setTimeout(r2, TRON_CONFIG.pollingInterval));
6387
- }
6388
- }
6389
- if (!txBlockNumber) {
6390
- const error2 = new TransactionTimeoutError("tron", txHash);
6391
- return {
6392
- completed: false,
6393
- error: error2.message
6394
- };
6395
- }
6396
- let confirmations = 0;
6397
- while (Date.now() < deadline) {
6398
- try {
6399
- const currentBlock = await tronWeb.trx.getCurrentBlock();
6400
- const currentBlockNumber = currentBlock?.block_header?.raw_data?.number;
6401
- if (currentBlockNumber) {
6402
- confirmations = currentBlockNumber - txBlockNumber;
6403
- if (confirmations >= TRON_CONFIG.requiredConfirmations) {
6404
- console.log(
6405
- `TRON transaction confirmed in block ${txBlockNumber} with ${confirmations} confirmations`
6406
- );
6407
- return {
6408
- completed: true,
6409
- actualFeeValue: actualFeeTrx?.toString(),
6410
- actualFeeSymbol: "TRX"
6411
- };
6412
- }
6413
- console.log(
6414
- `TRON transaction confirmations: ${confirmations}/${TRON_CONFIG.requiredConfirmations}`
6415
- );
6416
- }
6417
- } catch (e2) {
6418
- console.debug("TRON getCurrentBlock error:", e2);
6419
- }
6420
- await new Promise((r2) => setTimeout(r2, TRON_CONFIG.pollingInterval));
6421
- }
6422
- const error = new TransactionTimeoutError("tron", txHash);
6423
- return {
6424
- completed: false,
6425
- error: error.message
6426
- };
6427
- } catch (error) {
6428
- const chainError = toChainStrategyError(
6429
- error,
6430
- "tron",
6431
- "waitForCompletion"
6432
- );
6433
- return {
6434
- completed: false,
6435
- error: chainError.message
6436
- };
6437
- }
6438
- }
6439
6006
  getClient() {
6440
6007
  if (typeof window !== "undefined" && window.tronWeb) {
6008
+ this.applyTronApiKey(window.tronWeb);
6441
6009
  return window.tronWeb;
6442
6010
  }
6443
6011
  if (!this.fallbackClient) {
6444
6012
  this.fallbackClient = this.createFallbackClient();
6445
6013
  }
6014
+ if (this.fallbackClient) {
6015
+ this.applyTronApiKey(this.fallbackClient);
6016
+ }
6446
6017
  return this.fallbackClient;
6447
6018
  }
6448
6019
  createFallbackClient() {
6449
6020
  try {
6450
- const tronWeb = new TronWeb(
6451
- DEFAULT_TRON_NODE,
6452
- DEFAULT_TRON_NODE,
6453
- DEFAULT_TRON_NODE
6454
- );
6021
+ if (!this.config.apiKey) {
6022
+ throw new Error("TRON API key is required");
6023
+ }
6024
+ const headers = { "TRON-PRO-API-KEY": this.config.apiKey };
6025
+ const tronWeb = new TronWeb({
6026
+ fullHost: DEFAULT_TRON_NODE,
6027
+ headers
6028
+ });
6455
6029
  return tronWeb;
6456
6030
  } catch (error) {
6457
6031
  console.warn("Failed to create fallback TronWeb client", error);
6458
6032
  return void 0;
6459
6033
  }
6460
6034
  }
6035
+ applyTronApiKey(tronWeb) {
6036
+ if (!this.config.apiKey) {
6037
+ return;
6038
+ }
6039
+ const target = tronWeb;
6040
+ if (this.apiKeyApplied.has(target)) {
6041
+ return;
6042
+ }
6043
+ try {
6044
+ const headers = { "TRON-PRO-API-KEY": this.config.apiKey };
6045
+ if (typeof target.setHeader === "function") {
6046
+ target.setHeader(headers);
6047
+ } else {
6048
+ if (typeof target.setFullNodeHeader === "function") {
6049
+ target.setFullNodeHeader(headers);
6050
+ }
6051
+ if (typeof target.setEventHeader === "function") {
6052
+ target.setEventHeader(headers);
6053
+ }
6054
+ }
6055
+ this.apiKeyApplied.add(target);
6056
+ } catch {
6057
+ }
6058
+ }
6461
6059
  /**
6462
6060
  * Check if TronLink wallet is actually installed
6463
6061
  * This excludes Bybit Wallet which also injects tronLink for compatibility
@@ -6466,14 +6064,8 @@ class TronChainStrategy {
6466
6064
  if (typeof window === "undefined") {
6467
6065
  return false;
6468
6066
  }
6469
- const hasBybitWallet = typeof window.bybitWallet !== "undefined" && typeof window.bybitWallet.tronLink !== "undefined";
6470
- if (hasBybitWallet && !window.tronLink) {
6471
- return false;
6472
- }
6473
- if (!window.tronLink) {
6474
- return false;
6475
- }
6476
- return true;
6067
+ const win = window;
6068
+ return !!(win.tronLink || win.tronWeb || win.tron);
6477
6069
  }
6478
6070
  ensureDefaultAddress(tronWeb, address) {
6479
6071
  if (!address) return;
@@ -6486,18 +6078,7 @@ class TronChainStrategy {
6486
6078
  hex
6487
6079
  };
6488
6080
  }
6489
- } catch (error) {
6490
- console.debug("Failed to set TronWeb default address:", error);
6491
- }
6492
- }
6493
- hexToAscii(h4) {
6494
- if (!h4) return null;
6495
- const clean2 = h4.replace(/^0x/, "");
6496
- const bytes = clean2.match(/.{1,2}/g) || [];
6497
- try {
6498
- return bytes.map((b2) => String.fromCharCode(parseInt(b2, 16))).join("");
6499
6081
  } catch {
6500
- return null;
6501
6082
  }
6502
6083
  }
6503
6084
  toBase58(addr, tronWeb) {
@@ -6804,22 +6385,14 @@ class TronChainStrategy {
6804
6385
  }
6805
6386
  const info = await tronWeb.trx.getTransactionInfo(txHash);
6806
6387
  if (!info || !info.blockNumber) {
6807
- console.debug(
6808
- "Transaction not yet solidified (no blockNumber in info)"
6809
- );
6810
6388
  return false;
6811
6389
  }
6812
6390
  const result = info.receipt?.result;
6813
6391
  if (result === "SUCCESS") {
6814
- console.log(
6815
- `Transaction ${txHash} is solidified in block ${info.blockNumber}`
6816
- );
6817
6392
  return true;
6818
6393
  }
6819
- console.debug(`Transaction solidified but result is: ${result}`);
6820
6394
  return false;
6821
- } catch (error) {
6822
- console.debug("Error checking solidified status:", error);
6395
+ } catch {
6823
6396
  return false;
6824
6397
  }
6825
6398
  }
@@ -6830,7 +6403,8 @@ function ChainStrategyProvider({
6830
6403
  tonWallet,
6831
6404
  tronWallet,
6832
6405
  tonClient,
6833
- tonApiKey
6406
+ tonApiKey,
6407
+ tronApiKey
6834
6408
  }) {
6835
6409
  const evmStrategy = useMemo(
6836
6410
  () => new EvmChainStrategy({
@@ -6873,7 +6447,8 @@ function ChainStrategyProvider({
6873
6447
  connect: tronWallet.walletConnect.connect,
6874
6448
  disconnect: tronWallet.walletConnect.disconnect,
6875
6449
  signTransaction: tronWallet.walletConnect.signTransaction
6876
- } : void 0
6450
+ } : void 0,
6451
+ apiKey: tronApiKey
6877
6452
  }),
6878
6453
  [
6879
6454
  tronWallet.tronLink.address,
@@ -6881,7 +6456,8 @@ function ChainStrategyProvider({
6881
6456
  tronWallet.tronLink.select,
6882
6457
  tronWallet.tronLink.connect,
6883
6458
  tronWallet.tronLink.disconnect,
6884
- tronWallet.walletConnect
6459
+ tronWallet.walletConnect,
6460
+ tronApiKey
6885
6461
  ]
6886
6462
  );
6887
6463
  const chainRegistry = useMemo(
@@ -7066,6 +6642,7 @@ const SettingsModal = ({ isOpen, onClose }) => {
7066
6642
  const TOKEN_ROW_HEIGHT = 52;
7067
6643
  const TokenRow = ({
7068
6644
  symbol,
6645
+ willChangeSrc,
7069
6646
  name,
7070
6647
  isSelected,
7071
6648
  hasAnyWallet,
@@ -7078,7 +6655,7 @@ const TokenRow = ({
7078
6655
  Button,
7079
6656
  {
7080
6657
  onClick: onPick,
7081
- className: `w-full px-5 rounded-xs bg-transparent flex items-center justify-between gap-3 hover:bg-accent hover:scale-100 ${isSelected ? "border border-primary" : ""}`,
6658
+ className: `w-full px-5 rounded-xs bg-transparent flex items-center justify-between gap-3 hover:bg-accent hover:scale-100 ${isSelected ? "border border-primary" : ""} ${willChangeSrc ? "opacity-50 hover:opacity-100" : ""}`,
7082
6659
  children: [
7083
6660
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
7084
6661
  /* @__PURE__ */ jsx(
@@ -7314,7 +6891,7 @@ const TokenSelectModal = ({
7314
6891
  "div",
7315
6892
  {
7316
6893
  style: { ...style, height: TOKEN_ROW_HEIGHT },
7317
- className: "px-5 flex leading-4 text-base py-2 text-muted-foreground uppercase mt-8",
6894
+ className: "px-5 flex leading-4 text-base py-2 text-muted-foreground uppercase mt-3",
7318
6895
  children: /* @__PURE__ */ jsx("p", { children: item.text })
7319
6896
  }
7320
6897
  );
@@ -7333,6 +6910,7 @@ const TokenSelectModal = ({
7333
6910
  balance: bal,
7334
6911
  usdValue: usd,
7335
6912
  isBalanceLoading: balancesQuery.isLoading || balancesQuery.isFetching,
6913
+ willChangeSrc,
7336
6914
  onPick: () => onPick(token.symbol, willChangeSrc)
7337
6915
  }
7338
6916
  ) });
@@ -7357,67 +6935,74 @@ const TokenSelectModal = ({
7357
6935
  },
7358
6936
  [effectiveTab, virtualItems]
7359
6937
  );
7360
- return /* @__PURE__ */ jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxs(DialogContent, { className: "md:max-h-[90dvh] md:h-[90dvh] overflow-hidden flex flex-col fixed top-0 left-0 right-0 bottom-0 translate-x-0 translate-y-0 md:left-[50%] md:top-[50%] md:translate-x-[-50%] md:translate-y-[-50%] p-10 pt-7 rounded-none md:rounded-lg", children: [
7361
- /* @__PURE__ */ jsx(DialogHeader, { className: "text-left", children: /* @__PURE__ */ jsx(DialogTitle, { className: "text-2xl leading-8", children: t2("bridge.selectToken") }) }),
7362
- /* @__PURE__ */ jsx(
7363
- SearchInput,
7364
- {
7365
- placeholder: t2("bridge.searchToken"),
7366
- value: query,
7367
- onChange: setQuery
7368
- }
7369
- ),
7370
- hasSourceWallet() && /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
7371
- /* @__PURE__ */ jsx(
7372
- Button,
7373
- {
7374
- variant: effectiveTab === "my" ? "default" : "ghost",
7375
- onClick: () => {
7376
- setTab("my");
7377
- setManualTabSwitch(true);
7378
- },
7379
- size: "sm",
7380
- className: cn$2(
7381
- "px-4 cursor-pointer",
7382
- effectiveTab !== "my" && "bg-muted hover:bg-accent"
7383
- ),
7384
- children: t2("bridge.myTokens")
7385
- }
7386
- ),
7387
- /* @__PURE__ */ jsx(
7388
- Button,
7389
- {
7390
- variant: effectiveTab === "all" ? "default" : "ghost",
7391
- onClick: () => {
7392
- setTab("all");
7393
- setManualTabSwitch(true);
7394
- },
7395
- size: "sm",
7396
- className: cn$2(
7397
- "px-4 cursor-pointer",
7398
- effectiveTab !== "all" && "bg-muted hover:bg-accent"
6938
+ return /* @__PURE__ */ jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxs(
6939
+ DialogContent,
6940
+ {
6941
+ className: "md:max-h-[90dvh] md:h-[90dvh] overflow-hidden flex flex-col fixed top-0 left-0 right-0 bottom-0 translate-x-0 translate-y-0 md:left-[50%] md:top-[50%] md:translate-x-[-50%] md:translate-y-[-50%] p-6 md:p-10 md:pt-8 rounded-none md:rounded-lg",
6942
+ closeButtonClassName: "right-6 md:right-10",
6943
+ children: [
6944
+ /* @__PURE__ */ jsx(DialogHeader, { className: "text-left pb-2", children: /* @__PURE__ */ jsx(DialogTitle, { className: "text-2xl leading-8", children: t2("bridge.selectToken") }) }),
6945
+ /* @__PURE__ */ jsx(
6946
+ SearchInput,
6947
+ {
6948
+ placeholder: t2("bridge.searchToken"),
6949
+ value: query,
6950
+ onChange: setQuery
6951
+ }
6952
+ ),
6953
+ hasSourceWallet() && /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
6954
+ /* @__PURE__ */ jsx(
6955
+ Button,
6956
+ {
6957
+ variant: effectiveTab === "my" ? "default" : "ghost",
6958
+ onClick: () => {
6959
+ setTab("my");
6960
+ setManualTabSwitch(true);
6961
+ },
6962
+ size: "sm",
6963
+ className: cn$2(
6964
+ "px-4 h-9 cursor-pointer",
6965
+ effectiveTab !== "my" && "bg-muted hover:bg-accent"
6966
+ ),
6967
+ children: t2("bridge.myTokens")
6968
+ }
7399
6969
  ),
7400
- children: t2("bridge.allTokens")
7401
- }
7402
- )
7403
- ] }),
7404
- /* @__PURE__ */ jsx("div", { id: "token-select-list", className: "flex-1 -mx-5 min-h-0", children: hasNoResults ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground px-12 py-2 h-28 flex items-center justify-center text-center", children: t2("bridge.tokenNotFound") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7405
- effectiveTab === "my" && myTokens.length === 0 && /* @__PURE__ */ jsx("p", { className: "leading-4 px-5 text-base text-muted-foreground uppercase py-2", children: t2("bridge.noBalancesFound") }),
7406
- /* @__PURE__ */ jsx(
7407
- FixedSizeList,
7408
- {
7409
- height: listHeight,
7410
- itemCount: virtualItems.length,
7411
- itemSize: TOKEN_ROW_HEIGHT,
7412
- width: "100%",
7413
- itemKey,
7414
- className: "[&::-webkit-scrollbar]:w-1 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-muted-foreground/20 [&::-webkit-scrollbar-thumb]:rounded-full hover:[&::-webkit-scrollbar-thumb]:bg-muted-foreground/30",
7415
- overscanCount: 5,
7416
- children: VirtualRow
7417
- }
7418
- )
7419
- ] }) })
7420
- ] }) });
6970
+ /* @__PURE__ */ jsx(
6971
+ Button,
6972
+ {
6973
+ variant: effectiveTab === "all" ? "default" : "ghost",
6974
+ onClick: () => {
6975
+ setTab("all");
6976
+ setManualTabSwitch(true);
6977
+ },
6978
+ size: "sm",
6979
+ className: cn$2(
6980
+ "px-4 h-9 cursor-pointer",
6981
+ effectiveTab !== "all" && "bg-muted hover:bg-accent"
6982
+ ),
6983
+ children: t2("bridge.allTokens")
6984
+ }
6985
+ )
6986
+ ] }),
6987
+ /* @__PURE__ */ jsx("div", { id: "token-select-list", className: "flex-1 -mx-5 min-h-0", children: hasNoResults ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground px-12 py-2 h-28 flex items-center justify-center text-center", children: t2("bridge.tokenNotFound") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
6988
+ effectiveTab === "my" && myTokens.length === 0 && /* @__PURE__ */ jsx("p", { className: "leading-4 px-5 text-base text-muted-foreground uppercase py-2", children: t2("bridge.noBalancesFound") }),
6989
+ /* @__PURE__ */ jsx(
6990
+ FixedSizeList,
6991
+ {
6992
+ height: listHeight,
6993
+ itemCount: virtualItems.length,
6994
+ itemSize: TOKEN_ROW_HEIGHT,
6995
+ width: "100%",
6996
+ itemKey,
6997
+ className: "[&::-webkit-scrollbar]:w-1 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-muted-foreground/20 [&::-webkit-scrollbar-thumb]:rounded-full hover:[&::-webkit-scrollbar-thumb]:bg-muted-foreground/30",
6998
+ overscanCount: 5,
6999
+ children: VirtualRow
7000
+ }
7001
+ )
7002
+ ] }) })
7003
+ ]
7004
+ }
7005
+ ) });
7421
7006
  };
7422
7007
  function useBridgeRefresh() {
7423
7008
  const qc = useQueryClient();
@@ -26236,7 +25821,7 @@ class WalletConnectModal {
26236
25821
  }
26237
25822
  async initUi() {
26238
25823
  if (typeof window !== "undefined") {
26239
- await import("./index-C_cDfEeV.js");
25824
+ await import("./index-yQkayDGz.js");
26240
25825
  const modal = document.createElement("wcm-modal");
26241
25826
  document.body.insertAdjacentElement("beforeend", modal);
26242
25827
  OptionsCtrl.setIsUiLoaded(true);
@@ -26729,6 +26314,7 @@ const EvaaBridgeWithProviders = (props) => {
26729
26314
  },
26730
26315
  tonClient: props.tonClient,
26731
26316
  tonApiKey: props.tonApiKey,
26317
+ tronApiKey: props.tronApiKey,
26732
26318
  children: /* @__PURE__ */ jsx(EvaaBridgeContent, { ...props })
26733
26319
  }
26734
26320
  ) });
@@ -26942,47 +26528,41 @@ async function pollUntilDelivered(args) {
26942
26528
  }
26943
26529
  }
26944
26530
  export {
26945
- computeFeesUsdFromArray as $,
26946
- estimateTonNetworkFee as A,
26947
- addTonNetworkFee as B,
26531
+ getQuotesByPriority as $,
26532
+ getQuoteDetails as A,
26533
+ getRouteDisplayName as B,
26948
26534
  ConfigCtrl as C,
26949
- estimateTronNetworkFee as D,
26535
+ toLD as D,
26950
26536
  EventsCtrl as E,
26951
- addTronNetworkFee as F,
26952
- estimateEvmNetworkFee as G,
26953
- addEvmNetworkFee as H,
26954
- getQuoteDetails as I,
26955
- getRouteDisplayName as J,
26956
- toLD as K,
26957
- fromLD as L,
26537
+ fromLD as F,
26538
+ buildAssetMatrix as G,
26539
+ listAssetsForSelect as H,
26540
+ resolveTokenOnChain as I,
26541
+ resolveTokenOnChainFromMatrix$2 as J,
26542
+ DEFAULT_SLIPPAGE_BPS as K,
26543
+ tonNorm as L,
26958
26544
  ModalCtrl as M,
26959
- buildAssetMatrix as N,
26545
+ isZeroAddr as N,
26960
26546
  OptionsCtrl as O,
26961
- listAssetsForSelect as P,
26962
- resolveTokenOnChain as Q,
26547
+ addrForApi as P,
26548
+ isNativeAddrEqual as Q,
26963
26549
  RouterCtrl as R,
26964
- resolveTokenOnChainFromMatrix$2 as S,
26550
+ findNativeMeta as S,
26965
26551
  ToastCtrl as T,
26966
- DEFAULT_SLIPPAGE_BPS as U,
26967
- tonNorm as V,
26968
- isZeroAddr as W,
26969
- addrForApi as X,
26970
- isNativeAddrEqual as Y,
26971
- findNativeMeta as Z,
26972
- lookupTokenMeta as _,
26552
+ lookupTokenMeta as U,
26553
+ computeFeesUsdFromArray as V,
26554
+ sumFeeByTokenLD as W,
26555
+ normalizeTickerSymbol$1 as X,
26556
+ getChains as Y,
26557
+ getTokens as Z,
26558
+ getDestTokens as _,
26973
26559
  ThemeCtrl as a,
26974
- sumFeeByTokenLD as a0,
26975
- normalizeTickerSymbol$1 as a1,
26976
- getChains as a2,
26977
- getTokens as a3,
26978
- getDestTokens as a4,
26979
- getQuotesByPriority as a5,
26980
- isNativeAddress as a6,
26981
- getEvmBalances as a7,
26982
- getTonBalances as a8,
26983
- getTronBalances as a9,
26984
- getDeliveryStatus as aa,
26985
- pollUntilDelivered as ab,
26560
+ isNativeAddress as a0,
26561
+ getEvmBalances as a1,
26562
+ getTonBalances as a2,
26563
+ getTronBalances as a3,
26564
+ getDeliveryStatus as a4,
26565
+ pollUntilDelivered as a5,
26986
26566
  ExplorerCtrl as b,
26987
26567
  CoreUtil as c,
26988
26568
  EvaaBridge as d,
@@ -27009,4 +26589,4 @@ export {
27009
26589
  getQuoteFees as y,
27010
26590
  calculateMinReceived as z
27011
26591
  };
27012
- //# sourceMappingURL=index-CePOaHyN.js.map
26592
+ //# sourceMappingURL=index-D0OSdsmf.js.map