@rash2x/bridge-widget 0.6.55 → 0.6.58

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,8 +10,7 @@ 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";
@@ -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();
@@ -2693,6 +2243,48 @@ const useWalletSelectModal = create((set2) => ({
2693
2243
  onOpen: (addressType) => set2({ isOpen: true, addressType }),
2694
2244
  onClose: () => set2({ isOpen: false, addressType: void 0 })
2695
2245
  }));
2246
+ const truncateToDecimals = (num, decimals) => {
2247
+ if (!isFinite(num) || isNaN(num)) return "0";
2248
+ const multiplier = Math.pow(10, decimals);
2249
+ const truncated = Math.floor(num * multiplier) / multiplier;
2250
+ return truncated.toFixed(decimals).replace(/\.?0+$/, "");
2251
+ };
2252
+ const formatTokenAmount = (amount, symbol, options) => {
2253
+ const normalizedSymbol = (symbol ?? "").toUpperCase();
2254
+ if (["USDT", "USDC", "DAI", "BUSD"].includes(normalizedSymbol) && amount >= 1) {
2255
+ return `${Math.floor(amount)} ${normalizedSymbol}`;
2256
+ }
2257
+ if (options?.decimals !== void 0) {
2258
+ return `${amount.toFixed(options.decimals)} ${normalizedSymbol}`;
2259
+ }
2260
+ if (amount >= 1) {
2261
+ return `${amount.toFixed(0)} ${normalizedSymbol}`;
2262
+ } else if (amount >= 1e-3) {
2263
+ return `${amount.toFixed(3)} ${normalizedSymbol}`;
2264
+ } else {
2265
+ return `${amount.toFixed(6)} ${normalizedSymbol}`;
2266
+ }
2267
+ };
2268
+ const formatUsd = (value) => {
2269
+ if (!value || !isFinite(value)) return "$0";
2270
+ if (value >= 1) return `$${value.toFixed(2)}`;
2271
+ return `$${value.toFixed(6).replace(/0+$/, "").replace(/\.$/, "")}`;
2272
+ };
2273
+ const formatPercentage = (bps, decimals = 2) => {
2274
+ return `${(bps / 100).toFixed(decimals).replace(/0+$/, "").replace(/\.$/, "")}%`;
2275
+ };
2276
+ const formatBalance = (amount, decimals = 2) => {
2277
+ if (!isFinite(amount) || isNaN(amount) || amount <= 0) {
2278
+ return "0.00";
2279
+ }
2280
+ return amount.toFixed(decimals);
2281
+ };
2282
+ const formatHash = (hash, startChars = 4, endChars = 4) => {
2283
+ if (!hash) return "";
2284
+ if (hash.length <= startChars + endChars) return hash;
2285
+ return `${hash.slice(0, startChars)}...${hash.slice(-endChars)}`;
2286
+ };
2287
+ const formatAddress = formatHash;
2696
2288
  const EditIcon = (props) => {
2697
2289
  return /* @__PURE__ */ jsxs(
2698
2290
  "svg",
@@ -3118,8 +2710,8 @@ const InfoIcon = (props) => {
3118
2710
  {
3119
2711
  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
2712
  stroke: "currentColor",
3121
- "stroke-width": "1.68349",
3122
- "stroke-linecap": "round"
2713
+ strokeWidth: "1.68349",
2714
+ strokeLinecap: "round"
3123
2715
  }
3124
2716
  )
3125
2717
  }
@@ -3142,6 +2734,96 @@ const TokenSymbol = ({
3142
2734
  const src2 = `${BASE_URL}/${normalizedSymbol}.svg`;
3143
2735
  return /* @__PURE__ */ jsx("img", { src: src2, alt: alt ?? symbol, className });
3144
2736
  };
2737
+ function getQuoteAmounts(quote, srcToken, dstToken) {
2738
+ if (!quote || !srcToken || !dstToken) {
2739
+ return {
2740
+ inputHuman: 0,
2741
+ outputHuman: 0,
2742
+ outputHumanRounded: "0",
2743
+ minReceivedHuman: 0
2744
+ };
2745
+ }
2746
+ const inputHuman = fromLD(quote.srcAmount, srcToken.decimals);
2747
+ const outputHuman = fromLD(quote.dstAmount, dstToken.decimals);
2748
+ const outputHumanRounded = truncateToDecimals(outputHuman, 2);
2749
+ const minReceivedHuman = fromLD(quote.dstAmountMin || "0", dstToken.decimals);
2750
+ return {
2751
+ inputHuman,
2752
+ outputHuman,
2753
+ outputHumanRounded,
2754
+ minReceivedHuman
2755
+ };
2756
+ }
2757
+ function getQuoteFees(quote, tokens, chains, srcToken, dstToken) {
2758
+ if (!quote || !tokens || !chains) {
2759
+ return {
2760
+ fees: { usd: /* @__PURE__ */ new Map(), original: /* @__PURE__ */ new Map(), formatted: /* @__PURE__ */ new Map() },
2761
+ inSrcToken: void 0,
2762
+ inDstToken: void 0
2763
+ };
2764
+ }
2765
+ const feeData = computeFeesUsdFromArray(quote.fees, tokens, chains);
2766
+ let inSrcToken = void 0;
2767
+ let inDstToken = void 0;
2768
+ if (srcToken && quote.srcChainKey) {
2769
+ const feeInSrcLD = sumFeeByTokenLD(
2770
+ quote.fees,
2771
+ srcToken.address,
2772
+ quote.srcChainKey
2773
+ );
2774
+ const feeInSrcHuman = fromLD(feeInSrcLD, srcToken.decimals);
2775
+ if (feeInSrcHuman > 0) {
2776
+ inSrcToken = Number(truncateToDecimals(feeInSrcHuman, 8));
2777
+ } else if ((feeData.usd.get("total") || 0) > 0 && srcToken.price?.usd) {
2778
+ const feeInSrcApprox = (feeData.usd.get("total") || 0) / srcToken.price.usd;
2779
+ inSrcToken = Number(truncateToDecimals(feeInSrcApprox, 8));
2780
+ }
2781
+ }
2782
+ if (dstToken && quote.dstChainKey) {
2783
+ const feeInDstLD = sumFeeByTokenLD(
2784
+ quote.fees,
2785
+ dstToken.address,
2786
+ quote.dstChainKey
2787
+ );
2788
+ const feeInDstHuman = fromLD(feeInDstLD, dstToken.decimals);
2789
+ if (feeInDstHuman > 0) {
2790
+ inDstToken = Number(truncateToDecimals(feeInDstHuman, 8));
2791
+ }
2792
+ }
2793
+ return {
2794
+ fees: feeData,
2795
+ inSrcToken,
2796
+ inDstToken
2797
+ };
2798
+ }
2799
+ function calculateMinReceived(quote, slippageBps, dstToken) {
2800
+ if (!quote || !dstToken) return 0;
2801
+ const dstAmountLD = BigInt(quote.dstAmount);
2802
+ const minAmountLD = dstAmountLD * BigInt(1e4 - slippageBps) / BigInt(1e4);
2803
+ return fromLD(minAmountLD.toString(), dstToken.decimals);
2804
+ }
2805
+ function getQuoteDetails(quote, srcToken, dstToken, tokens, chains, slippageBps) {
2806
+ const amounts = getQuoteAmounts(quote, srcToken, dstToken);
2807
+ const fees = getQuoteFees(quote, tokens, chains, srcToken, dstToken);
2808
+ const minimumReceived = calculateMinReceived(quote, slippageBps, dstToken);
2809
+ return {
2810
+ inputAmount: amounts.inputHuman,
2811
+ outputAmount: amounts.outputHuman,
2812
+ outputAmountRounded: amounts.outputHumanRounded,
2813
+ minimumReceived,
2814
+ etaSeconds: quote?.duration?.estimated,
2815
+ fees
2816
+ };
2817
+ }
2818
+ function getRouteDisplayName(route) {
2819
+ if (!route) return "Stargate Bridge";
2820
+ const routeLower = route.toLowerCase();
2821
+ if (routeLower.includes("taxi")) return "Stargate V2 Fast";
2822
+ if (routeLower.includes("bus")) return "Stargate V2 Economy";
2823
+ if (routeLower.includes("oft")) return "OFT Bridge";
2824
+ if (routeLower.includes("v2")) return "Stargate V2";
2825
+ return route.split(/[/\-_]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
2826
+ }
3145
2827
  function useGasEstimate(amountNum) {
3146
2828
  const { fromChain } = useChainsStore();
3147
2829
  const { selectedAssetSymbol } = useTokensStore();
@@ -3151,6 +2833,9 @@ function useGasEstimate(amountNum) {
3151
2833
  srcAddress
3152
2834
  );
3153
2835
  const { quote } = useBridgeQuoteStore();
2836
+ const { chainRegistry } = useChainStrategies();
2837
+ const [networkFeeEstimate, setNetworkFeeEstimate] = useState(0);
2838
+ const [networkFeeKnown, setNetworkFeeKnown] = useState(false);
3154
2839
  const balancesKnown = !balancesLoading;
3155
2840
  const chainKey = fromChain?.chainKey;
3156
2841
  const nativeCurrencySymbol = fromChain?.nativeCurrency?.symbol;
@@ -3159,6 +2844,42 @@ function useGasEstimate(amountNum) {
3159
2844
  const quoteFees = quote?.fees;
3160
2845
  const quoteSrcChainKey = quote?.srcChainKey;
3161
2846
  const nativeBalanceValue = nativeCurrencySymbol ? Number(balances[nativeCurrencySymbol.toUpperCase()]?.balance ?? 0) : 0;
2847
+ useEffect(() => {
2848
+ let cancelled = false;
2849
+ const estimate = async () => {
2850
+ setNetworkFeeEstimate(0);
2851
+ setNetworkFeeKnown(false);
2852
+ if (!chainKey || !quote?.steps?.length) {
2853
+ return;
2854
+ }
2855
+ const strategy = chainRegistry.getStrategy(chainKey);
2856
+ if (!strategy) {
2857
+ setNetworkFeeKnown(true);
2858
+ return;
2859
+ }
2860
+ const steps = quote.steps.filter((step) => step.chainKey === chainKey);
2861
+ if (!steps.length) {
2862
+ setNetworkFeeKnown(true);
2863
+ return;
2864
+ }
2865
+ try {
2866
+ const estimateValue = await strategy.estimateNetworkFee(steps);
2867
+ if (cancelled) return;
2868
+ setNetworkFeeEstimate(Number.isFinite(estimateValue) ? estimateValue : 0);
2869
+ } catch {
2870
+ if (cancelled) return;
2871
+ setNetworkFeeEstimate(0);
2872
+ } finally {
2873
+ if (!cancelled) {
2874
+ setNetworkFeeKnown(true);
2875
+ }
2876
+ }
2877
+ };
2878
+ void estimate();
2879
+ return () => {
2880
+ cancelled = true;
2881
+ };
2882
+ }, [chainKey, quote?.steps, chainRegistry]);
3162
2883
  const result = useMemo(() => {
3163
2884
  if (!chainKey || !nativeCurrencySymbol) {
3164
2885
  return {
@@ -3178,7 +2899,7 @@ function useGasEstimate(amountNum) {
3178
2899
  if (quoteFees && quoteSrcChainKey === chainKey) {
3179
2900
  const fees = quoteFees;
3180
2901
  const feesInNative = fees.filter(
3181
- (f4) => f4.chainKey === chainKey && f4.token === nativeCurrencyAddress && f4.type === "network"
2902
+ (f4) => f4.chainKey === chainKey && f4.token === nativeCurrencyAddress
3182
2903
  ).reduce(
3183
2904
  (sum, f4) => sum + BigInt(f4.amount || "0"),
3184
2905
  0n
@@ -3187,13 +2908,16 @@ function useGasEstimate(amountNum) {
3187
2908
  requiredNative = Number(feesInNative) / Math.pow(10, decimals);
3188
2909
  quoteFeesAvailable = true;
3189
2910
  }
2911
+ if (networkFeeKnown) {
2912
+ requiredNative += networkFeeEstimate;
2913
+ }
3190
2914
  let hasEnoughGas = true;
3191
2915
  if (isNativeSelected) {
3192
2916
  hasEnoughGas = nativeBalance - (amountNum ?? 0) >= requiredNative;
3193
2917
  } else {
3194
2918
  hasEnoughGas = nativeBalance >= requiredNative;
3195
2919
  }
3196
- const shouldCheckGas = balancesKnown && quoteFeesAvailable;
2920
+ const shouldCheckGas = balancesKnown && quoteFeesAvailable && networkFeeKnown;
3197
2921
  return {
3198
2922
  nativeSym,
3199
2923
  nativeBalance,
@@ -3212,7 +2936,9 @@ function useGasEstimate(amountNum) {
3212
2936
  quoteSrcChainKey,
3213
2937
  amountNum,
3214
2938
  balancesKnown,
3215
- nativeBalanceValue
2939
+ nativeBalanceValue,
2940
+ networkFeeEstimate,
2941
+ networkFeeKnown
3216
2942
  ]);
3217
2943
  return result;
3218
2944
  }
@@ -3621,33 +3347,6 @@ class TransactionFailedError extends ChainStrategyError {
3621
3347
  this.txHash = txHash;
3622
3348
  }
3623
3349
  }
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
3350
  class ProviderNotAvailableError extends ChainStrategyError {
3652
3351
  constructor(chainKey, reason) {
3653
3352
  const message = reason ? `${chainKey.toUpperCase()} provider not available: ${reason}` : `${chainKey.toUpperCase()} provider not available`;
@@ -3704,6 +3403,38 @@ async function getLayerZeroMessageByTx(txHash) {
3704
3403
  return null;
3705
3404
  }
3706
3405
  }
3406
+ async function waitForLayerZeroCompletion(txHash, timeoutMs = 6e5, pollIntervalMs = 1e4) {
3407
+ const deadline = Date.now() + timeoutMs;
3408
+ while (Date.now() < deadline) {
3409
+ try {
3410
+ const message = await getLayerZeroMessageByTx(txHash);
3411
+ if (message) {
3412
+ const statusName = message.status?.name;
3413
+ if (statusName === "DELIVERED") {
3414
+ return {
3415
+ completed: true,
3416
+ status: "DELIVERED",
3417
+ dstTxHash: message.destination?.tx?.txHash,
3418
+ message
3419
+ };
3420
+ }
3421
+ if (statusName === "FAILED") {
3422
+ return {
3423
+ completed: false,
3424
+ status: "FAILED",
3425
+ message
3426
+ };
3427
+ }
3428
+ }
3429
+ } catch {
3430
+ }
3431
+ await new Promise((r2) => setTimeout(r2, pollIntervalMs));
3432
+ }
3433
+ return {
3434
+ completed: false,
3435
+ status: "TIMEOUT"
3436
+ };
3437
+ }
3707
3438
  function useBridgeTransaction() {
3708
3439
  const { quote } = useBridgeQuoteStore();
3709
3440
  const { chainRegistry } = useChainStrategies();
@@ -3779,59 +3510,76 @@ function useBridgeTransaction() {
3779
3510
  txStore.setSrcHash(hash);
3780
3511
  txStore.updateStatus("processing");
3781
3512
  });
3782
- if (txResult?.tonTransactionHash) {
3783
- txStore.setTonTransactionHash(txResult.tonTransactionHash);
3784
- }
3785
3513
  if (txResult?.hash) {
3786
- strategy.waitForCompletion(txResult.hash, context).then((result) => {
3787
- if (result.completed) {
3788
- if (result.dstTxHash) {
3789
- txStore.setDstHash(result.dstTxHash);
3514
+ const trackWithLayerZero = async () => {
3515
+ let hashForLayerZero = txResult.hash;
3516
+ const messageHash = txResult.hash;
3517
+ if (quote.srcChainKey === "ton" && strategy.convertMessageHashToTxHash) {
3518
+ const tonTxHash = await strategy.convertMessageHashToTxHash(
3519
+ messageHash,
3520
+ 6e4
3521
+ );
3522
+ if (tonTxHash) {
3523
+ hashForLayerZero = tonTxHash;
3524
+ txStore.setTonTransactionHash(tonTxHash);
3525
+ } else {
3526
+ console.warn("Failed to convert TON message hash to tx hash");
3790
3527
  }
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
- }
3528
+ }
3529
+ const lzResult = await waitForLayerZeroCompletion(
3530
+ hashForLayerZero,
3531
+ 6e5,
3532
+ 1e4
3533
+ );
3534
+ console.log("LayerZero delivery status:", lzResult.status);
3535
+ if (lzResult.completed) {
3536
+ if (lzResult.dstTxHash) {
3537
+ txStore.setDstHash(lzResult.dstTxHash);
3803
3538
  }
3804
- txStore.updateStatus("completed");
3805
- console.log("Transaction completed successfully");
3806
- if (txResult.hash && strategy.getSourceCost) {
3539
+ if (strategy.getSourceCost) {
3807
3540
  const srcChain2 = chains?.find(
3808
3541
  (c2) => c2.chainKey === quote.srcChainKey
3809
3542
  );
3810
3543
  const feeSymbol = srcChain2?.nativeCurrency?.symbol || "";
3811
3544
  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) => {
3545
+ const hashForSourceCost = quote.srcChainKey === "ton" ? messageHash : hashForLayerZero;
3546
+ try {
3547
+ const sourceCost = await strategy.getSourceCost(
3548
+ hashForSourceCost
3549
+ );
3818
3550
  if (sourceCost?.totalNative !== void 0 && isFinite(sourceCost.totalNative)) {
3819
3551
  const feeUsd = priceUsd && priceUsd > 0 ? sourceCost.totalNative * priceUsd : void 0;
3552
+ console.log("Source cost calculated:", {
3553
+ gasFee: sourceCost.breakdown?.gasFee + " " + feeSymbol,
3554
+ layerZeroFee: sourceCost.breakdown?.layerZeroFee + " " + feeSymbol,
3555
+ total: sourceCost.totalNative + " " + feeSymbol,
3556
+ totalUsd: feeUsd ? "$" + feeUsd.toFixed(2) : "N/A"
3557
+ });
3820
3558
  txStore.updateLayerZeroTotalFee(
3821
3559
  sourceCost.totalNative,
3822
3560
  feeSymbol,
3823
3561
  feeUsd
3824
3562
  );
3825
3563
  }
3826
- }).catch((error) => {
3827
- console.warn("Failed to compute LayerZero total fee:", error);
3828
- });
3564
+ } catch (error) {
3565
+ console.warn("Failed to compute source cost:", error);
3566
+ }
3829
3567
  }
3568
+ txStore.updateStatus("completed");
3569
+ console.log("Transaction completed successfully via LayerZero");
3830
3570
  } else {
3831
- txStore.setError("TRANSACTION_FAILED_TO_COMPLETE");
3832
- console.error("Transaction completion failed:", result.error);
3571
+ if (lzResult.status === "FAILED") {
3572
+ txStore.setError("TRANSACTION_FAILED_TO_COMPLETE");
3573
+ console.error("LayerZero delivery failed");
3574
+ } else {
3575
+ txStore.updateStatus("completed");
3576
+ console.warn(
3577
+ "LayerZero tracking timed out, marking as completed"
3578
+ );
3579
+ }
3833
3580
  }
3834
- }).catch((err) => {
3581
+ };
3582
+ trackWithLayerZero().catch((err) => {
3835
3583
  if (isUserRejection(err)) {
3836
3584
  txStore.setError("TRANSACTION_REJECTED");
3837
3585
  } else if (ChainStrategyError.isChainStrategyError(err)) {
@@ -4931,11 +4679,60 @@ class ChainStrategyRegistry {
4931
4679
  await strategy.disconnect(options);
4932
4680
  }
4933
4681
  }
4682
+ const EVM_CONFIG = {
4683
+ usdtAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
4684
+ gasEstimates: {
4685
+ approve: 65000n,
4686
+ bridge: 300000n
4687
+ },
4688
+ gasBuffer: 1.2,
4689
+ // 20% buffer
4690
+ gasFeeMultiplier: 2,
4691
+ // Multiplier for wallet fee estimates
4692
+ timeout: 3e5,
4693
+ // 5 minutes (increased for slower networks)
4694
+ requiredConfirmations: 3
4695
+ // Wait for 3 confirmations for reorg protection
4696
+ };
4697
+ const TON_CONFIG = {
4698
+ apiUrl: "https://toncenter.com/api/v2",
4699
+ timeout: 36e4,
4700
+ // 6 minutes
4701
+ validUntil: 600,
4702
+ // 10 minutes
4703
+ pollingInterval: 5e3,
4704
+ // 5 seconds between transaction status checks
4705
+ estimatedNetworkFee: "1000000000"
4706
+ // 1 TON in nanoton (conservative estimate)
4707
+ };
4708
+ const TRON_CONFIG = {
4709
+ // 2 minutes (for 19 confirmations)
4710
+ feeLimit: 1e8,
4711
+ // 3 seconds between checks
4712
+ estimatedNetworkFee: "10000000"
4713
+ // 10 TRX in SUN (fallback estimate)
4714
+ };
4715
+ let tonClientInstance = null;
4716
+ function getTonClient(customClient, apiKey) {
4717
+ if (customClient) {
4718
+ return customClient;
4719
+ }
4720
+ if (!tonClientInstance) {
4721
+ tonClientInstance = new TonClient({
4722
+ endpoint: `${TON_CONFIG.apiUrl}/jsonRPC`,
4723
+ apiKey
4724
+ });
4725
+ }
4726
+ return tonClientInstance;
4727
+ }
4934
4728
  function isNativeAddress(addr) {
4935
4729
  if (!addr) return false;
4936
4730
  const a2 = addr.toLowerCase();
4937
4731
  return a2 === "native" || a2 === "0x0000000000000000000000000000000000000000" || a2 === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" || addr === "T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb";
4938
4732
  }
4733
+ function sleep(ms2) {
4734
+ return new Promise((resolve) => setTimeout(resolve, ms2));
4735
+ }
4939
4736
  function toTronBase58(addr, tronWeb) {
4940
4737
  if (!addr) throw new Error("Empty TRON address");
4941
4738
  if (addr.startsWith("T")) return addr;
@@ -4982,24 +4779,27 @@ async function getEvmBalances(publicClient, address, tokens) {
4982
4779
  if (!publicClient) {
4983
4780
  throw new Error("No public client provided");
4984
4781
  }
4985
- const nativeTokens = tokens.filter((t2) => isNativeAddress(t2.address));
4986
4782
  const erc20Tokens = tokens.filter(
4987
4783
  (t2) => !isNativeAddress(t2.address) && isAddress(t2.address)
4988
4784
  );
4989
- for (const token of nativeTokens) {
4785
+ const chainNative = publicClient.chain?.nativeCurrency;
4786
+ const nativeSymbol = chainNative?.symbol ?? "ETH";
4787
+ const nativeDecimals = chainNative?.decimals ?? 18;
4788
+ const maxAttempts = 2;
4789
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
4990
4790
  try {
4991
- const ethBalance = await publicClient.getBalance({
4791
+ const nativeBalance = await publicClient.getBalance({
4992
4792
  address
4993
4793
  });
4994
- const balance = parseFloat(formatUnits(ethBalance, token.decimals));
4794
+ const balance = parseFloat(formatUnits(nativeBalance, nativeDecimals));
4995
4795
  if (balance > 0) {
4996
- balances[token.symbol] = { balance, address };
4796
+ balances[nativeSymbol] = { balance, address };
4797
+ }
4798
+ break;
4799
+ } catch {
4800
+ if (attempt !== maxAttempts) {
4801
+ await sleep(250 * attempt);
4997
4802
  }
4998
- } catch (error) {
4999
- console.debug(
5000
- `Failed to get native balance for ${token.symbol}:`,
5001
- error
5002
- );
5003
4803
  }
5004
4804
  }
5005
4805
  if (erc20Tokens.length > 0) {
@@ -5033,11 +4833,7 @@ async function getEvmBalances(publicClient, address, tokens) {
5033
4833
  if (balance > 0) {
5034
4834
  balances[token.symbol] = { balance, address };
5035
4835
  }
5036
- } catch (error) {
5037
- console.debug(
5038
- `Failed to parse balance for ${token.symbol}:`,
5039
- error
5040
- );
4836
+ } catch {
5041
4837
  }
5042
4838
  }
5043
4839
  });
@@ -5068,8 +4864,7 @@ async function getEvmBalances(publicClient, address, tokens) {
5068
4864
  if (balance > 0) {
5069
4865
  balances[token.symbol] = { balance, address };
5070
4866
  }
5071
- } catch (error2) {
5072
- console.debug(`Failed to get balance for ${token.symbol}:`, error2);
4867
+ } catch {
5073
4868
  }
5074
4869
  }
5075
4870
  }
@@ -5129,12 +4924,7 @@ async function getTonBalances(address, tokens, customTonClient, tonApiKey) {
5129
4924
  balances[symbolNorm] = entry;
5130
4925
  }
5131
4926
  }
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
- }
4927
+ } catch {
5138
4928
  }
5139
4929
  }
5140
4930
  } catch (error) {
@@ -5156,8 +4946,7 @@ async function getTronBalances(tronWeb, address, tokens) {
5156
4946
  if (trxBalance > 0) {
5157
4947
  balances.TRX = { balance: trxBalance, address: ownerB58 };
5158
4948
  }
5159
- } catch (error) {
5160
- console.warn("Failed to get native TRX balance:", error);
4949
+ } catch {
5161
4950
  }
5162
4951
  for (const token of tokens) {
5163
4952
  try {
@@ -5191,21 +4980,19 @@ async function getTronBalances(tronWeb, address, tokens) {
5191
4980
  if (balance > 0) {
5192
4981
  balances[token.symbol] = { balance, address: ownerB58 };
5193
4982
  }
5194
- } catch (error) {
5195
- console.warn(`Failed to get TRON balance for ${token.symbol}:`, error);
4983
+ } catch {
5196
4984
  }
5197
4985
  }
5198
- } catch (error) {
5199
- console.error("Failed to get Tron balances:", error);
4986
+ } catch {
5200
4987
  }
5201
4988
  return balances;
5202
4989
  }
5203
- const ERC20_ABI = [
4990
+ const ERC20_ABI = parseAbi([
5204
4991
  "function approve(address spender, uint256 amount) returns (bool)",
5205
4992
  "function allowance(address owner, address spender) view returns (uint256)",
5206
4993
  "function decimals() view returns (uint8)",
5207
4994
  "function balanceOf(address owner) view returns (uint256)"
5208
- ];
4995
+ ]);
5209
4996
  class EvmChainStrategy {
5210
4997
  constructor(config) {
5211
4998
  __publicField(this, "config");
@@ -5253,14 +5040,9 @@ class EvmChainStrategy {
5253
5040
  }
5254
5041
  async getBalances(address, tokens) {
5255
5042
  if (!this.publicClient) {
5256
- console.warn("No publicClient available for balance query");
5257
5043
  return {};
5258
5044
  }
5259
- return await getEvmBalances(
5260
- this.publicClient,
5261
- address,
5262
- tokens
5263
- );
5045
+ return await getEvmBalances(this.publicClient, address, tokens);
5264
5046
  }
5265
5047
  isAddressValid(address) {
5266
5048
  if (!address) return false;
@@ -5296,7 +5078,6 @@ class EvmChainStrategy {
5296
5078
  }
5297
5079
  async getSourceCost(txHash) {
5298
5080
  if (!this.publicClient) {
5299
- console.warn("No publicClient available for source cost query");
5300
5081
  return null;
5301
5082
  }
5302
5083
  try {
@@ -5311,18 +5092,61 @@ class EvmChainStrategy {
5311
5092
  const gasFeeWei = gasUsed * gasPrice;
5312
5093
  const txValueWei = tx.value ?? 0n;
5313
5094
  const totalWei = gasFeeWei + txValueWei;
5314
- return {
5095
+ const sourceCost = {
5315
5096
  totalNative: Number(formatUnits(totalWei, 18)),
5316
5097
  breakdown: {
5317
5098
  gasFee: Number(formatUnits(gasFeeWei, 18)),
5318
5099
  layerZeroFee: Number(formatUnits(txValueWei, 18))
5319
5100
  }
5320
5101
  };
5102
+ return sourceCost;
5321
5103
  } catch (error) {
5322
5104
  console.warn("Failed to compute EVM source cost:", error);
5323
5105
  return null;
5324
5106
  }
5325
5107
  }
5108
+ async estimateNetworkFee(steps) {
5109
+ if (!this.walletClient) {
5110
+ return 0;
5111
+ }
5112
+ const account = this.config.evmAddress;
5113
+ const txSteps = steps.filter((step) => step.transaction?.to);
5114
+ if (!txSteps.length) {
5115
+ return 0;
5116
+ }
5117
+ const applyFeeMultiplier = (feePerGas) => {
5118
+ const multiplier = EVM_CONFIG.gasFeeMultiplier;
5119
+ if (!Number.isFinite(multiplier) || multiplier <= 1) {
5120
+ return feePerGas;
5121
+ }
5122
+ const scaled = BigInt(Math.round(multiplier * 100));
5123
+ return (feePerGas * scaled + 99n) / 100n;
5124
+ };
5125
+ let totalFeeWei = 0n;
5126
+ for (const step of txSteps) {
5127
+ const tx = step.transaction;
5128
+ if (!tx?.to) continue;
5129
+ try {
5130
+ const request = await this.walletClient.prepareTransactionRequest({
5131
+ account: tx.from || account,
5132
+ to: tx.to,
5133
+ data: tx.data,
5134
+ value: tx.value ? BigInt(tx.value) : void 0,
5135
+ chain: this.walletClient.chain
5136
+ });
5137
+ const gasLimit = request.gas;
5138
+ const maxFeePerGas = request.maxFeePerGas ?? request.gasPrice;
5139
+ if (gasLimit && maxFeePerGas) {
5140
+ totalFeeWei += gasLimit * applyFeeMultiplier(maxFeePerGas);
5141
+ }
5142
+ } catch {
5143
+ }
5144
+ }
5145
+ if (totalFeeWei === 0n) {
5146
+ return 0;
5147
+ }
5148
+ return Number(formatUnits(totalFeeWei, 18));
5149
+ }
5326
5150
  async executeSteps(steps, _context, onFirstHash) {
5327
5151
  if (!this.isConnected() || !this.walletClient) {
5328
5152
  throw new WalletNotConnectedError("evm");
@@ -5336,14 +5160,12 @@ class EvmChainStrategy {
5336
5160
  );
5337
5161
  if (step.type === "approve") {
5338
5162
  const hash = await this.approveTransaction(step);
5339
- console.log(`Approval transaction hash: ${hash}`);
5340
5163
  if (!firstTxHash) {
5341
5164
  firstTxHash = hash;
5342
5165
  onFirstHash?.(hash);
5343
5166
  }
5344
5167
  } else if (step.type === "bridge") {
5345
5168
  const hash = await this.executeTransaction(step);
5346
- console.log(`Bridge transaction hash: ${hash}`);
5347
5169
  if (!firstTxHash) {
5348
5170
  firstTxHash = hash;
5349
5171
  onFirstHash?.(hash);
@@ -5366,106 +5188,6 @@ class EvmChainStrategy {
5366
5188
  throw toChainStrategyError(error, "evm", "transaction");
5367
5189
  }
5368
5190
  }
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)`);
5409
- }
5410
- } catch (error) {
5411
- console.warn("Failed to calculate actual fee:", error);
5412
- }
5413
- return {
5414
- completed: true,
5415
- actualFeeValue
5416
- // Symbol will be determined by the caller based on chain info
5417
- };
5418
- } 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
- }
5457
- }
5458
- const chainError = toChainStrategyError(
5459
- error,
5460
- "evm",
5461
- "waitForCompletion"
5462
- );
5463
- return {
5464
- completed: false,
5465
- error: chainError.message
5466
- };
5467
- }
5468
- }
5469
5191
  async executeTransaction(step) {
5470
5192
  const walletClient = this.walletClient;
5471
5193
  if (!walletClient) {
@@ -5620,88 +5342,14 @@ class EvmChainStrategy {
5620
5342
  blockTag: "finalized"
5621
5343
  });
5622
5344
  if (!finalizedBlock) {
5623
- console.debug(
5624
- "Finalized block not available (pre-merge or unsupported)"
5625
- );
5626
5345
  return false;
5627
5346
  }
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);
5347
+ return blockNumber <= finalizedBlock.number;
5348
+ } catch {
5641
5349
  return false;
5642
5350
  }
5643
5351
  }
5644
5352
  }
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
5353
  class TonChainStrategy {
5706
5354
  constructor(config) {
5707
5355
  __publicField(this, "config");
@@ -5814,40 +5462,17 @@ class TonChainStrategy {
5814
5462
  validUntil: Math.floor(Date.now() / 1e3) + TON_CONFIG.validUntil,
5815
5463
  messages: tonMessages
5816
5464
  };
5817
- const result = await this.config.tonConnectUI.sendTransaction(
5818
- transaction2
5819
- );
5465
+ const result = await this.config.tonConnectUI.sendTransaction(transaction2);
5820
5466
  const bocBase64 = result.boc;
5821
5467
  try {
5822
5468
  const inMessage = loadMessage(Cell.fromBase64(bocBase64).beginParse());
5823
5469
  const messageHash = this.getNormalizedExtMessageHash(inMessage);
5824
5470
  const hexHash = messageHash.toString("hex");
5825
5471
  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
5472
  return {
5846
5473
  chainKey: "ton",
5847
- hash: hexHash,
5848
- // Message hash for TONScan
5849
- tonTransactionHash
5850
- // Transaction hash for LayerZero (if found)
5474
+ hash: hexHash
5475
+ // Message hash for TONScan and for finding tx later
5851
5476
  };
5852
5477
  } catch (error) {
5853
5478
  console.error("Error parsing BOC to hex hash:", error);
@@ -5861,39 +5486,45 @@ class TonChainStrategy {
5861
5486
  throw toChainStrategyError(error, "ton", "transaction");
5862
5487
  }
5863
5488
  }
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
- };
5489
+ /**
5490
+ * Convert TON message hash to transaction hash.
5491
+ * LayerZero uses transaction hash, but TonConnect returns message hash.
5492
+ */
5493
+ async convertMessageHashToTxHash(messageHash, timeoutMs = 6e4) {
5494
+ const deadline = Date.now() + timeoutMs;
5495
+ const client = getTonClient(this.config.tonClient, this.config.tonApiKey);
5496
+ if (!this.config.tonAddress) {
5497
+ return null;
5498
+ }
5499
+ const targetMessageHash = Buffer.from(messageHash, "hex");
5500
+ const accountAddress = Address.parse(this.config.tonAddress);
5501
+ while (Date.now() < deadline) {
5502
+ try {
5503
+ const transactions = await client.getTransactions(accountAddress, {
5504
+ limit: 20,
5505
+ archival: true
5506
+ });
5507
+ for (const tx of transactions) {
5508
+ if (tx.inMessage?.info.type === "external-in") {
5509
+ try {
5510
+ const txInMessageHash = this.getNormalizedExtMessageHash(
5511
+ tx.inMessage
5512
+ );
5513
+ if (txInMessageHash.equals(targetMessageHash)) {
5514
+ const txHash = `0x${tx.hash().toString("hex")}`;
5515
+ return txHash;
5516
+ }
5517
+ } catch {
5518
+ continue;
5519
+ }
5520
+ }
5521
+ }
5522
+ await new Promise((r2) => setTimeout(r2, 3e3));
5523
+ } catch {
5524
+ await new Promise((r2) => setTimeout(r2, 3e3));
5880
5525
  }
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
5526
  }
5527
+ return null;
5897
5528
  }
5898
5529
  getNormalizedExtMessageHash(message) {
5899
5530
  if (message.info.type !== "external-in") {
@@ -5916,6 +5547,9 @@ class TonChainStrategy {
5916
5547
  if (typeof value === "number" && Number.isFinite(value)) {
5917
5548
  return BigInt(Math.trunc(value));
5918
5549
  }
5550
+ if (typeof value === "object" && value !== null && "coins" in value) {
5551
+ return this.toBigInt(value.coins);
5552
+ }
5919
5553
  if (typeof value === "string" && value.trim() !== "") {
5920
5554
  try {
5921
5555
  return BigInt(value);
@@ -5929,12 +5563,16 @@ class TonChainStrategy {
5929
5563
  const candidate = tx.outMessages;
5930
5564
  if (!candidate) return [];
5931
5565
  if (Array.isArray(candidate)) return candidate;
5932
- if (candidate instanceof Map) return Array.from(candidate.values());
5933
5566
  if (typeof candidate === "object" && candidate !== null && "values" in candidate && typeof candidate.values === "function") {
5934
- return Array.from(
5935
- candidate.values()
5936
- );
5567
+ const values = candidate.values();
5568
+ if (Array.isArray(values)) {
5569
+ return [...values];
5570
+ }
5571
+ if (values && typeof values === "object" && Symbol.iterator in values) {
5572
+ return Array.from(values);
5573
+ }
5937
5574
  }
5575
+ if (candidate instanceof Map) return Array.from(candidate.values());
5938
5576
  return [];
5939
5577
  }
5940
5578
  getMessageValue(message) {
@@ -5946,27 +5584,49 @@ class TonChainStrategy {
5946
5584
  }
5947
5585
  return this.toBigInt(value);
5948
5586
  }
5949
- getFirstOutMessageValue(tx) {
5587
+ getTotalOutMessageValue(tx) {
5950
5588
  const outMessages = this.getOutMessages(tx);
5951
5589
  if (!outMessages.length) return 0n;
5952
- const value = this.getMessageValue(outMessages[0]);
5953
- return value ?? 0n;
5590
+ let total = 0n;
5591
+ for (const message of outMessages) {
5592
+ const value = this.getMessageValue(message);
5593
+ if (value) {
5594
+ total += value;
5595
+ }
5596
+ }
5597
+ return total;
5954
5598
  }
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;
5599
+ async getSourceCost(messageHash) {
5600
+ const timeoutMs = 3e4;
5601
+ const result = await this.checkTonTransaction(messageHash, timeoutMs);
5602
+ if (!result.confirmed) {
5603
+ console.warn("Transaction not found for source cost calculation");
5604
+ return null;
5605
+ }
5959
5606
  const totalFees = result.totalFees ?? 0n;
5960
5607
  const outValue = result.outValue ?? 0n;
5961
5608
  const totalNanotons = totalFees + outValue;
5962
5609
  const toTon = (value) => Number(value) / 1e9;
5963
- return {
5610
+ const sourceCost = {
5964
5611
  totalNative: toTon(totalNanotons),
5965
5612
  breakdown: {
5966
5613
  gasFee: toTon(totalFees),
5967
5614
  layerZeroFee: toTon(outValue)
5968
5615
  }
5969
5616
  };
5617
+ console.log("TON source cost:", {
5618
+ gasFee: `${sourceCost.breakdown.gasFee} TON`,
5619
+ layerZeroFee: `${sourceCost.breakdown.layerZeroFee} TON`,
5620
+ total: `${sourceCost.totalNative} TON`
5621
+ });
5622
+ return sourceCost;
5623
+ }
5624
+ async estimateNetworkFee() {
5625
+ const fee = Number(TON_CONFIG.estimatedNetworkFee);
5626
+ if (!Number.isFinite(fee) || fee <= 0) {
5627
+ return 0;
5628
+ }
5629
+ return fee / 1e9;
5970
5630
  }
5971
5631
  async checkTonTransaction(hashOrBoc, timeoutMs = 36e4) {
5972
5632
  const deadline = Date.now() + timeoutMs;
@@ -5977,10 +5637,6 @@ class TonChainStrategy {
5977
5637
  try {
5978
5638
  const inMessage = loadMessage(Cell.fromBase64(hashOrBoc).beginParse());
5979
5639
  if (inMessage.info.type !== "external-in") {
5980
- console.debug(
5981
- "Expected external-in message, got:",
5982
- inMessage.info.type
5983
- );
5984
5640
  return { confirmed: false };
5985
5641
  }
5986
5642
  accountAddress = inMessage.info.dest;
@@ -5988,63 +5644,50 @@ class TonChainStrategy {
5988
5644
  } catch {
5989
5645
  targetMessageHash = Buffer.from(hashOrBoc, "hex");
5990
5646
  if (!this.config.tonAddress) {
5991
- console.debug("No wallet address available for hex hash lookup");
5992
5647
  return { confirmed: false };
5993
5648
  }
5994
5649
  accountAddress = Address.parse(this.config.tonAddress);
5995
5650
  }
5996
- let lt2 = void 0;
5997
- let hash = void 0;
5998
5651
  while (Date.now() < deadline) {
5999
5652
  try {
6000
5653
  const transactions = await client.getTransactions(accountAddress, {
6001
- lt: lt2,
6002
- hash,
6003
- limit: 10,
5654
+ limit: 20,
5655
+ // Check last 20 transactions
6004
5656
  archival: true
6005
5657
  });
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
5658
  for (const tx of transactions) {
6013
5659
  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
- };
5660
+ try {
5661
+ const txInMessageHash = this.getNormalizedExtMessageHash(
5662
+ tx.inMessage
5663
+ );
5664
+ if (txInMessageHash.equals(targetMessageHash)) {
5665
+ const totalFees = this.toBigInt(tx.totalFees) ?? this.toBigInt(
5666
+ tx.total_fees
5667
+ ) ?? 0n;
5668
+ const outValue = this.getTotalOutMessageValue(tx);
5669
+ const feeInTon = Number(totalFees) / 1e9;
5670
+ const transactionHash = tx.hash().toString("hex");
5671
+ return {
5672
+ confirmed: true,
5673
+ fee: feeInTon.toString(),
5674
+ totalFees,
5675
+ outValue,
5676
+ transactionHash
5677
+ };
5678
+ }
5679
+ } catch {
5680
+ continue;
6031
5681
  }
6032
5682
  }
6033
5683
  }
6034
- const lastTx = transactions[transactions.length - 1];
6035
- lt2 = lastTx.lt.toString();
6036
- hash = lastTx.hash().toString("base64");
6037
5684
  await new Promise((r2) => setTimeout(r2, TON_CONFIG.pollingInterval));
6038
- } catch (error) {
6039
- console.debug("Error fetching transactions:", error);
5685
+ } catch {
6040
5686
  await new Promise((r2) => setTimeout(r2, TON_CONFIG.pollingInterval));
6041
- lt2 = void 0;
6042
- hash = void 0;
6043
5687
  }
6044
5688
  }
6045
5689
  return { confirmed: false };
6046
- } catch (error) {
6047
- console.debug("Error parsing BOC or checking transaction:", error);
5690
+ } catch {
6048
5691
  return { confirmed: false };
6049
5692
  }
6050
5693
  }
@@ -6054,6 +5697,7 @@ class TronChainStrategy {
6054
5697
  constructor(config) {
6055
5698
  __publicField(this, "config");
6056
5699
  __publicField(this, "fallbackClient");
5700
+ __publicField(this, "apiKeyApplied", /* @__PURE__ */ new WeakSet());
6057
5701
  this.config = config;
6058
5702
  }
6059
5703
  canHandle(chainKey) {
@@ -6219,18 +5863,31 @@ class TronChainStrategy {
6219
5863
  const feeTrx = feeSun / 1e6;
6220
5864
  const lzFeeTrx = callValueSun / 1e6;
6221
5865
  const totalTrx = (feeSun + callValueSun) / 1e6;
6222
- return {
5866
+ const sourceCost = {
6223
5867
  totalNative: totalTrx,
6224
5868
  breakdown: {
6225
5869
  gasFee: feeTrx,
6226
5870
  layerZeroFee: lzFeeTrx
6227
5871
  }
6228
5872
  };
5873
+ console.log("TRON source cost:", {
5874
+ gasFee: `${sourceCost.breakdown.gasFee} TRX`,
5875
+ layerZeroFee: `${sourceCost.breakdown.layerZeroFee} TRX`,
5876
+ total: `${sourceCost.totalNative} TRX`
5877
+ });
5878
+ return sourceCost;
6229
5879
  } catch (error) {
6230
5880
  console.warn("Failed to compute TRON source cost:", error);
6231
5881
  return null;
6232
5882
  }
6233
5883
  }
5884
+ async estimateNetworkFee() {
5885
+ const fee = Number(TRON_CONFIG.estimatedNetworkFee);
5886
+ if (!Number.isFinite(fee) || fee <= 0) {
5887
+ return 0;
5888
+ }
5889
+ return fee / 1e6;
5890
+ }
6234
5891
  async executeSteps(steps, _context, onFirstHash) {
6235
5892
  const tronWeb = this.getClient();
6236
5893
  if (!tronWeb) {
@@ -6327,137 +5984,59 @@ class TronChainStrategy {
6327
5984
  }
6328
5985
  return { hash: lastTxId, chainKey: "tron" };
6329
5986
  }
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
5987
  getClient() {
6440
5988
  if (typeof window !== "undefined" && window.tronWeb) {
5989
+ this.applyTronApiKey(window.tronWeb);
6441
5990
  return window.tronWeb;
6442
5991
  }
6443
5992
  if (!this.fallbackClient) {
6444
5993
  this.fallbackClient = this.createFallbackClient();
6445
5994
  }
5995
+ if (this.fallbackClient) {
5996
+ this.applyTronApiKey(this.fallbackClient);
5997
+ }
6446
5998
  return this.fallbackClient;
6447
5999
  }
6448
6000
  createFallbackClient() {
6449
6001
  try {
6450
- const tronWeb = new TronWeb(
6451
- DEFAULT_TRON_NODE,
6452
- DEFAULT_TRON_NODE,
6453
- DEFAULT_TRON_NODE
6454
- );
6002
+ if (!this.config.apiKey) {
6003
+ throw new Error("TRON API key is required");
6004
+ }
6005
+ const headers = { "TRON-PRO-API-KEY": this.config.apiKey };
6006
+ const tronWeb = new TronWeb({
6007
+ fullHost: DEFAULT_TRON_NODE,
6008
+ headers
6009
+ });
6455
6010
  return tronWeb;
6456
6011
  } catch (error) {
6457
6012
  console.warn("Failed to create fallback TronWeb client", error);
6458
6013
  return void 0;
6459
6014
  }
6460
6015
  }
6016
+ applyTronApiKey(tronWeb) {
6017
+ if (!this.config.apiKey) {
6018
+ return;
6019
+ }
6020
+ const target = tronWeb;
6021
+ if (this.apiKeyApplied.has(target)) {
6022
+ return;
6023
+ }
6024
+ try {
6025
+ const headers = { "TRON-PRO-API-KEY": this.config.apiKey };
6026
+ if (typeof target.setHeader === "function") {
6027
+ target.setHeader(headers);
6028
+ } else {
6029
+ if (typeof target.setFullNodeHeader === "function") {
6030
+ target.setFullNodeHeader(headers);
6031
+ }
6032
+ if (typeof target.setEventHeader === "function") {
6033
+ target.setEventHeader(headers);
6034
+ }
6035
+ }
6036
+ this.apiKeyApplied.add(target);
6037
+ } catch {
6038
+ }
6039
+ }
6461
6040
  /**
6462
6041
  * Check if TronLink wallet is actually installed
6463
6042
  * This excludes Bybit Wallet which also injects tronLink for compatibility
@@ -6466,14 +6045,8 @@ class TronChainStrategy {
6466
6045
  if (typeof window === "undefined") {
6467
6046
  return false;
6468
6047
  }
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;
6048
+ const win = window;
6049
+ return !!(win.tronLink || win.tronWeb || win.tron);
6477
6050
  }
6478
6051
  ensureDefaultAddress(tronWeb, address) {
6479
6052
  if (!address) return;
@@ -6486,18 +6059,7 @@ class TronChainStrategy {
6486
6059
  hex
6487
6060
  };
6488
6061
  }
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
6062
  } catch {
6500
- return null;
6501
6063
  }
6502
6064
  }
6503
6065
  toBase58(addr, tronWeb) {
@@ -6804,22 +6366,14 @@ class TronChainStrategy {
6804
6366
  }
6805
6367
  const info = await tronWeb.trx.getTransactionInfo(txHash);
6806
6368
  if (!info || !info.blockNumber) {
6807
- console.debug(
6808
- "Transaction not yet solidified (no blockNumber in info)"
6809
- );
6810
6369
  return false;
6811
6370
  }
6812
6371
  const result = info.receipt?.result;
6813
6372
  if (result === "SUCCESS") {
6814
- console.log(
6815
- `Transaction ${txHash} is solidified in block ${info.blockNumber}`
6816
- );
6817
6373
  return true;
6818
6374
  }
6819
- console.debug(`Transaction solidified but result is: ${result}`);
6820
6375
  return false;
6821
- } catch (error) {
6822
- console.debug("Error checking solidified status:", error);
6376
+ } catch {
6823
6377
  return false;
6824
6378
  }
6825
6379
  }
@@ -6830,7 +6384,8 @@ function ChainStrategyProvider({
6830
6384
  tonWallet,
6831
6385
  tronWallet,
6832
6386
  tonClient,
6833
- tonApiKey
6387
+ tonApiKey,
6388
+ tronApiKey
6834
6389
  }) {
6835
6390
  const evmStrategy = useMemo(
6836
6391
  () => new EvmChainStrategy({
@@ -6873,7 +6428,8 @@ function ChainStrategyProvider({
6873
6428
  connect: tronWallet.walletConnect.connect,
6874
6429
  disconnect: tronWallet.walletConnect.disconnect,
6875
6430
  signTransaction: tronWallet.walletConnect.signTransaction
6876
- } : void 0
6431
+ } : void 0,
6432
+ apiKey: tronApiKey
6877
6433
  }),
6878
6434
  [
6879
6435
  tronWallet.tronLink.address,
@@ -6881,7 +6437,8 @@ function ChainStrategyProvider({
6881
6437
  tronWallet.tronLink.select,
6882
6438
  tronWallet.tronLink.connect,
6883
6439
  tronWallet.tronLink.disconnect,
6884
- tronWallet.walletConnect
6440
+ tronWallet.walletConnect,
6441
+ tronApiKey
6885
6442
  ]
6886
6443
  );
6887
6444
  const chainRegistry = useMemo(
@@ -26236,7 +25793,7 @@ class WalletConnectModal {
26236
25793
  }
26237
25794
  async initUi() {
26238
25795
  if (typeof window !== "undefined") {
26239
- await import("./index-C_cDfEeV.js");
25796
+ await import("./index-D8sxoZ5P.js");
26240
25797
  const modal = document.createElement("wcm-modal");
26241
25798
  document.body.insertAdjacentElement("beforeend", modal);
26242
25799
  OptionsCtrl.setIsUiLoaded(true);
@@ -26729,6 +26286,7 @@ const EvaaBridgeWithProviders = (props) => {
26729
26286
  },
26730
26287
  tonClient: props.tonClient,
26731
26288
  tonApiKey: props.tonApiKey,
26289
+ tronApiKey: props.tronApiKey,
26732
26290
  children: /* @__PURE__ */ jsx(EvaaBridgeContent, { ...props })
26733
26291
  }
26734
26292
  ) });
@@ -26942,47 +26500,41 @@ async function pollUntilDelivered(args) {
26942
26500
  }
26943
26501
  }
26944
26502
  export {
26945
- computeFeesUsdFromArray as $,
26946
- estimateTonNetworkFee as A,
26947
- addTonNetworkFee as B,
26503
+ getQuotesByPriority as $,
26504
+ getQuoteDetails as A,
26505
+ getRouteDisplayName as B,
26948
26506
  ConfigCtrl as C,
26949
- estimateTronNetworkFee as D,
26507
+ toLD as D,
26950
26508
  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,
26509
+ fromLD as F,
26510
+ buildAssetMatrix as G,
26511
+ listAssetsForSelect as H,
26512
+ resolveTokenOnChain as I,
26513
+ resolveTokenOnChainFromMatrix$2 as J,
26514
+ DEFAULT_SLIPPAGE_BPS as K,
26515
+ tonNorm as L,
26958
26516
  ModalCtrl as M,
26959
- buildAssetMatrix as N,
26517
+ isZeroAddr as N,
26960
26518
  OptionsCtrl as O,
26961
- listAssetsForSelect as P,
26962
- resolveTokenOnChain as Q,
26519
+ addrForApi as P,
26520
+ isNativeAddrEqual as Q,
26963
26521
  RouterCtrl as R,
26964
- resolveTokenOnChainFromMatrix$2 as S,
26522
+ findNativeMeta as S,
26965
26523
  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 _,
26524
+ lookupTokenMeta as U,
26525
+ computeFeesUsdFromArray as V,
26526
+ sumFeeByTokenLD as W,
26527
+ normalizeTickerSymbol$1 as X,
26528
+ getChains as Y,
26529
+ getTokens as Z,
26530
+ getDestTokens as _,
26973
26531
  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,
26532
+ isNativeAddress as a0,
26533
+ getEvmBalances as a1,
26534
+ getTonBalances as a2,
26535
+ getTronBalances as a3,
26536
+ getDeliveryStatus as a4,
26537
+ pollUntilDelivered as a5,
26986
26538
  ExplorerCtrl as b,
26987
26539
  CoreUtil as c,
26988
26540
  EvaaBridge as d,
@@ -27009,4 +26561,4 @@ export {
27009
26561
  getQuoteFees as y,
27010
26562
  calculateMinReceived as z
27011
26563
  };
27012
- //# sourceMappingURL=index-CePOaHyN.js.map
26564
+ //# sourceMappingURL=index-CDUxAooI.js.map