@rash2x/bridge-widget 0.2.10 → 0.2.11

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.
@@ -44,16 +44,17 @@ const lucideReact = require("lucide-react");
44
44
  const framerMotion = require("framer-motion");
45
45
  const accordion = require("@/components/ui/accordion");
46
46
  const tooltip = require("@/components/ui/tooltip");
47
+ const ton = require("@ton/ton");
47
48
  const sonner = require("sonner");
49
+ const reactDialog = require("@radix-ui/react-dialog");
48
50
  const ethers = require("ethers");
49
51
  const viem = require("viem");
50
- const ton = require("@ton/ton");
51
52
  const tronwalletAdapters = require("@tronweb3/tronwallet-adapters");
52
53
  const card = require("@/components/ui/card");
53
54
  const badge = require("@/components/ui/badge");
54
55
  const common$1 = { "connecting": "Connecting…", "initializing": "Initializing...", "loading": "Loading...", "paste": "paste", "close": "Close", "zeroPlaceholder": "0", "nativeToken": "Native Token" };
55
56
  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", "tonKeeper": "TonKeeper", "metaMask": "WalletConnect", "tronLink": "TronLink", "addTronWallet": "Add Tron wallet", "comingSoon": "Coming Soon", "connected": "CONNECTED", "disconnect": "Disconnect", "chooseWallet": "Choose wallet", "oneWalletPerEnv": "You can only connect one wallet per environment.", "connect": "Connect", "connectTronWallet": "Connect Tron wallet", "connectWallet": "Connect wallet" };
56
- const bridge$1 = { "sourceNetwork": "Source network", "destinationNetwork": "Destination network", "selectToken": "Select token", "selectNetwork": "Select network", "searchToken": "Search token", "searchDestinationChain": "Search destination chain", "myTokens": "My tokens", "allTokens": "All tokens", "willChangeSourceChain": "Will Change Source Chain", "noBalancesFound": "No balances found.", "noResults": "No results", "sendToAnotherAddress": "Send to another address", "youWillReceive": "You will receive", "anotherAddressPlaceholder": "Address", "addressDoesntMatch": "Address doesn't match the {{network}} network", "checkBeforeTransfer": "Check correctness before transfer" };
57
+ const bridge$1 = { "max": "Max", "sourceNetwork": "Source network", "destinationNetwork": "Destination network", "selectToken": "Select token", "selectNetwork": "Select network", "searchToken": "Search token", "searchDestinationChain": "Search destination chain", "myTokens": "My tokens", "allTokens": "All tokens", "willChangeSourceChain": "Will Change Source Chain", "noBalancesFound": "No balances found.", "noResults": "No results", "sendToAnotherAddress": "Send to another address", "youWillReceive": "You will receive", "anotherAddressPlaceholder": "Address", "addressDoesntMatch": "Address doesn't match the {{network}} network", "checkBeforeTransfer": "Check correctness before transfer" };
57
58
  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": "Processing...", "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", "finalFee": "Final Fee", "route": "Route", "estTime": "Est. Time", "slippage": "Slippage", "minimumReceived": "Minimum received", "totalFee": "Total Fee", "noRouteFound": "No route found", "notEnoughGas": "Not enough gas", "noRouteFoundForSettings": "No route found for current settings.", "tryAdjustSettings": "Try disabling Gas on Destination, or adjust amount/networks.", "quoteError": "Quote error" };
58
59
  const app$1 = { "stargateWidgetName": "Stargate Bridge Widget", "liveWidget": "Live Widget", "getStarted": "Get Started" };
59
60
  const settings$1 = { "title": "Settings", "gasOnDestination": "Gas on destination", "slippageTolerance": "Slippage tolerance", "routePriority": "Route Priority", "highSlippageWarning": "High slippage warning", "gasPresets": { "auto": "Auto", "none": "None", "medium": "Medium", "max": "Max" }, "routePresets": { "fastest": "Fastest", "cheapest": "Cheapest", "recommended": "Recommended" } };
@@ -69,7 +70,7 @@ const en = {
69
70
  };
70
71
  const common = { "connecting": "Подключение…", "initializing": "Инициализация...", "loading": "Загрузка...", "paste": "вставить", "close": "Закрыть", "zeroPlaceholder": "0", "nativeToken": "Нативный токен" };
71
72
  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", "tonKeeper": "TonKeeper", "metaMask": "WalletConnect", "tronLink": "TronLink", "addTronWallet": "Добавить Tron кошелёк", "comingSoon": "Скоро", "connected": "ПОДКЛЮЧЕНО", "disconnect": "Отключить", "chooseWallet": "Выберите кошелёк", "oneWalletPerEnv": "Можно подключить только один кошелёк на окружение.", "connect": "Подключить", "connectTronWallet": "Подключить Tron кошелёк", "connectWallet": "Подключить кошелёк" };
72
- const bridge = { "sourceNetwork": "Исходная сеть", "destinationNetwork": "Целевая сеть", "selectToken": "Выбрать токен", "selectNetwork": "Выбрать сеть", "searchToken": "Поиск токена", "searchDestinationChain": "Поиск целевой сети", "myTokens": "Мои токены", "allTokens": "Все токены", "willChangeSourceChain": "Сменит исходную сеть", "noBalancesFound": "Балансы не найдены.", "noResults": "Нет результатов", "sendToAnotherAddress": "Отправить на другой адрес", "youWillReceive": "Вы получите", "anotherAddressPlaceholder": "Адрес", "addressDoesntMatch": "Адрес не соответствует сети {{network}}", "checkBeforeTransfer": "Проверьте корректность перед переводом" };
73
+ const bridge = { "max": "Макс", "sourceNetwork": "Исходная сеть", "destinationNetwork": "Целевая сеть", "selectToken": "Выбрать токен", "selectNetwork": "Выбрать сеть", "searchToken": "Поиск токена", "searchDestinationChain": "Поиск целевой сети", "myTokens": "Мои токены", "allTokens": "Все токены", "willChangeSourceChain": "Сменит исходную сеть", "noBalancesFound": "Балансы не найдены.", "noResults": "Нет результатов", "sendToAnotherAddress": "Отправить на другой адрес", "youWillReceive": "Вы получите", "anotherAddressPlaceholder": "Адрес", "addressDoesntMatch": "Адрес не соответствует сети {{network}}", "checkBeforeTransfer": "Проверьте корректность перед переводом" };
73
74
  const transaction = { "enterAmount": "Введите сумму", "transfer": "Перевести", "getQuote": "Получить котировку", "quoting": "Расчет котировки...", "failed": "Ошибка транзакции", "confirm": "Подтвердите транзакцию", "signTransaction": "Подпишите транзакцию в кошельке", "inProgress": "Выполнение...", "checkingBalance": "Проверка баланса...", "insufficientBalance": "Недостаточно средств", "amountTooSmall": "Минимум {{min}}", "amountTooLarge": "Максимум {{max}}", "success": "Успех", "successTitle": "Успех", "done": "Готово", "hashCopied": "Хэш скопирован в буфер обмена", "bridged": "Переведено", "transferTitle": "Перевод", "hash": "Хэш", "finalFee": "Итоговая комиссия", "route": "Маршрут", "estTime": "Время", "slippage": "Проскальзывание", "minimumReceived": "Минимум к получению", "totalFee": "Общая комиссия", "noRouteFound": "Маршрут не найден", "notEnoughGas": "Недостаточно газа", "noRouteFoundForSettings": "Маршрут не найден для текущих настроек.", "tryAdjustSettings": "Попробуйте отключить Gas on Destination или измените сумму/сети.", "quoteError": "Ошибка котировки" };
74
75
  const app = { "stargateWidgetName": "Виджет Stargate Bridge", "liveWidget": "Живой виджет", "getStarted": "Начало работы" };
75
76
  const settings = { "title": "Настройки", "gasOnDestination": "Газ на назначении", "slippageTolerance": "Толерантность к проскальзыванию", "routePriority": "Приоритет маршрута", "highSlippageWarning": "Высокое проскальзывание", "gasPresets": { "auto": "Авто", "none": "Нет", "medium": "Средний", "max": "Макс" }, "routePresets": { "fastest": "Быстрейший", "cheapest": "Дешевейший", "recommended": "Рекомендуемый" } };
@@ -1607,18 +1608,30 @@ const SwapButton = () => {
1607
1608
  ) });
1608
1609
  };
1609
1610
  const WalletBalance = (props) => {
1610
- const { value, isLoading = false } = props;
1611
+ const { value, isLoading = false, showMax = false, onMaxClick } = props;
1612
+ const { t } = useBridgeTranslation();
1611
1613
  const hasNoData = !value || value === "0" || value === "0.00" || value === "0.0";
1612
1614
  const shouldShowSkeleton = isLoading && hasNoData;
1615
+ const shouldShowMaxButton = showMax && !hasNoData && !isLoading;
1613
1616
  if (shouldShowSkeleton) {
1614
1617
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 items-center", children: [
1615
1618
  /* @__PURE__ */ jsxRuntime.jsx(WalletIcon, { className: "text-muted-foreground" }),
1616
- /* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-16 rounded-md" })
1619
+ /* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-12 rounded-md" })
1617
1620
  ] });
1618
1621
  }
1619
1622
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 items-center", children: [
1620
1623
  /* @__PURE__ */ jsxRuntime.jsx(WalletIcon, { className: "text-muted-foreground" }),
1621
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-5 font-medium text-muted-foreground", children: value })
1624
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-5 font-medium text-muted-foreground", children: value }),
1625
+ shouldShowMaxButton && /* @__PURE__ */ jsxRuntime.jsx(
1626
+ button.Button,
1627
+ {
1628
+ variant: "ghost",
1629
+ size: "sm",
1630
+ onClick: onMaxClick,
1631
+ className: "h-auto p-0 px-0 text-xs font-medium border-b border-foreground rounded-none",
1632
+ children: t("bridge.max")
1633
+ }
1634
+ )
1622
1635
  ] });
1623
1636
  };
1624
1637
  const BASE_URL$1 = "https://icons-ckg.pages.dev/stargate-light/networks";
@@ -1859,7 +1872,7 @@ const ChainSelectModal = ({
1859
1872
  );
1860
1873
  };
1861
1874
  return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { className: "max-h-[90dvh] h-[90dvh] overflow-hidden flex flex-col", children: [
1862
- /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("bridge.selectNetwork") }) }),
1875
+ /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { className: "text-left", children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("bridge.selectNetwork") }) }),
1863
1876
  /* @__PURE__ */ jsxRuntime.jsx(
1864
1877
  SearchInput,
1865
1878
  {
@@ -1984,7 +1997,7 @@ const WalletInlineButton = ({
1984
1997
  disabled: isButtonDisabled,
1985
1998
  variant: "ghost",
1986
1999
  size: "sm",
1987
- className: "flex gap-1 cursor-pointer px-0 pr-1 h-5",
2000
+ className: "flex gap-1 cursor-pointer !px-0 pr-1 h-5",
1988
2001
  children: [
1989
2002
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: isConnected ? prefixIcons[wallet] : null }),
1990
2003
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "leading-3 text-sm border-b border-dotted border-link text-link", children: buttonText })
@@ -2049,6 +2062,11 @@ const SwapSection = ({
2049
2062
  },
2050
2063
  [onSelect, onClose]
2051
2064
  );
2065
+ const handleMaxClick = react.useCallback(() => {
2066
+ if (balance.balance && onAmountChange) {
2067
+ onAmountChange(balance.balance.toString());
2068
+ }
2069
+ }, [balance.balance, onAmountChange]);
2052
2070
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2053
2071
  /* @__PURE__ */ jsxRuntime.jsxs(
2054
2072
  "div",
@@ -2065,7 +2083,9 @@ const SwapSection = ({
2065
2083
  WalletBalance,
2066
2084
  {
2067
2085
  value: truncateToDecimals(balance.balance, 2),
2068
- isLoading: balance.isLoading
2086
+ isLoading: balance.isLoading,
2087
+ showMax: isSource,
2088
+ onMaxClick: handleMaxClick
2069
2089
  }
2070
2090
  )
2071
2091
  ] }),
@@ -2315,6 +2335,53 @@ const TokenSymbol = ({
2315
2335
  const src = `${BASE_URL}/${normalizedSymbol}.svg`;
2316
2336
  return /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: alt ?? symbol, className });
2317
2337
  };
2338
+ const EVM_CONFIG = {
2339
+ usdtAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
2340
+ gasEstimates: {
2341
+ approve: 65000n,
2342
+ bridge: 300000n
2343
+ },
2344
+ gasBuffer: 1.2,
2345
+ // 20% buffer
2346
+ timeout: 3e5,
2347
+ // 5 minutes (increased for slower networks)
2348
+ requiredConfirmations: 3
2349
+ // Wait for 3 confirmations for reorg protection
2350
+ };
2351
+ const TON_CONFIG = {
2352
+ apiUrl: "https://toncenter.com/api/v2",
2353
+ timeout: 36e4,
2354
+ // 6 minutes
2355
+ validUntil: 600,
2356
+ // 10 minutes
2357
+ pollingInterval: 5e3,
2358
+ // 5 seconds between transaction status checks
2359
+ estimatedNetworkFee: "100000000"
2360
+ // 0.1 TON in nanoton (conservative estimate)
2361
+ };
2362
+ const TRON_CONFIG = {
2363
+ timeout: 12e4,
2364
+ // 2 minutes (for 19 confirmations)
2365
+ feeLimit: 1e8,
2366
+ // 100 TRX in sun
2367
+ requiredConfirmations: 19,
2368
+ // TRON standard: 19 blocks for confirmation
2369
+ pollingInterval: 3e3
2370
+ // 3 seconds between checks
2371
+ };
2372
+ let tonClientInstance = null;
2373
+ function getTonClient(customClient, apiKey) {
2374
+ if (customClient) {
2375
+ return customClient;
2376
+ }
2377
+ if (!tonClientInstance) {
2378
+ tonClientInstance = new ton.TonClient({
2379
+ endpoint: `${TON_CONFIG.apiUrl}/jsonRPC`,
2380
+ apiKey
2381
+ });
2382
+ }
2383
+ return tonClientInstance;
2384
+ }
2318
2385
  function getQuoteAmounts(quote, srcToken, dstToken) {
2319
2386
  if (!quote || !srcToken || !dstToken) {
2320
2387
  return {
@@ -2394,6 +2461,34 @@ function calculateMinReceived(quote, slippageBps, dstToken) {
2394
2461
  const minAmountLD = dstAmountLD * BigInt(1e4 - slippageBps) / BigInt(1e4);
2395
2462
  return fromLD(minAmountLD.toString(), dstToken.decimals);
2396
2463
  }
2464
+ function addTonNetworkFee(quote, chains) {
2465
+ if (!quote || quote.srcChainKey.toLowerCase() !== "ton") {
2466
+ return quote;
2467
+ }
2468
+ const tonChain = chains?.find(
2469
+ (c) => c.chainKey.toLowerCase() === "ton"
2470
+ );
2471
+ if (!tonChain?.nativeCurrency?.address) {
2472
+ console.warn("Could not find TON native currency address");
2473
+ return quote;
2474
+ }
2475
+ const networkFee = {
2476
+ token: tonChain.nativeCurrency.address,
2477
+ chainKey: "ton",
2478
+ amount: TON_CONFIG.estimatedNetworkFee,
2479
+ type: "network"
2480
+ };
2481
+ const hasNetworkFee = quote.fees?.some(
2482
+ (fee) => fee.type === "network" && fee.chainKey === "ton"
2483
+ );
2484
+ if (hasNetworkFee) {
2485
+ return quote;
2486
+ }
2487
+ return {
2488
+ ...quote,
2489
+ fees: [...quote.fees || [], networkFee]
2490
+ };
2491
+ }
2397
2492
  function getQuoteDetails(quote, srcToken, dstToken, tokens, chains, slippageBps) {
2398
2493
  const amounts = getQuoteAmounts(quote, srcToken, dstToken);
2399
2494
  const fees = getQuoteFees(quote, tokens, chains, srcToken, dstToken);
@@ -2432,8 +2527,9 @@ const Details = () => {
2432
2527
  selectedAssetSymbol,
2433
2528
  fromChain?.chainKey
2434
2529
  );
2530
+ const quoteWithFees = addTonNetworkFee(quote, chains);
2435
2531
  const quoteDetails = getQuoteDetails(
2436
- quote,
2532
+ quoteWithFees || quote,
2437
2533
  srcToken,
2438
2534
  dstToken,
2439
2535
  tokens,
@@ -2461,7 +2557,7 @@ const Details = () => {
2461
2557
  })();
2462
2558
  const currentSlippageText = formatPercentage(slippageBps);
2463
2559
  const routeText = quote?.route ? getRouteDisplayName(quote.route) : t(`settings.routePresets.${routePriority}`);
2464
- return /* @__PURE__ */ jsxRuntime.jsx(accordion.Accordion, { type: "single", collapsible: true, className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(accordion.AccordionItem, { value: "item-1", className: "bg-muted rounded-sm", children: [
2560
+ return /* @__PURE__ */ jsxRuntime.jsx(accordion.Accordion, { type: "single", collapsible: true, className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(accordion.AccordionItem, { value: "item-1", className: "bg-muted/50 rounded-sm", children: [
2465
2561
  /* @__PURE__ */ jsxRuntime.jsx(accordion.AccordionTrigger, { className: "w-full gap-1 items-center py-6 px-5 rounded-b-sm data-[state=open]:pb-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex items-center justify-between", children: [
2466
2562
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-normal text-priority leading-4", children: t("bridge.youWillReceive", { defaultValue: "You will receive" }) }),
2467
2563
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-transparent hover:bg-transparent shadow-none h-4 p-0 px-0 py-0 flex items-center gap-2", children: [
@@ -2778,8 +2874,9 @@ function useBridgeTransaction() {
2778
2874
  }
2779
2875
  const srcChain = chains?.find((c) => c.chainKey === quote.srcChainKey);
2780
2876
  const dstChain = chains?.find((c) => c.chainKey === quote.dstChainKey);
2781
- const amounts = getQuoteAmounts(quote, srcToken, dstToken);
2782
- const fees = getQuoteFees(quote, tokens, chains, srcToken, dstToken);
2877
+ const quoteWithFees = addTonNetworkFee(quote, chains) || quote;
2878
+ const amounts = getQuoteAmounts(quoteWithFees, srcToken, dstToken);
2879
+ const fees = getQuoteFees(quoteWithFees, tokens, chains, srcToken, dstToken);
2783
2880
  const metadata = {
2784
2881
  srcChainName: srcChain?.name || quote.srcChainKey,
2785
2882
  dstChainName: dstChain?.name || quote.dstChainKey,
@@ -3178,6 +3275,7 @@ const WalletModalButton = (props) => {
3178
3275
  const { icon: IconComponent, name, onClose } = props;
3179
3276
  const { chainRegistry } = useChainStrategies();
3180
3277
  const { connect, isPending } = wagmi.useConnect();
3278
+ const [isConnecting, setIsConnecting] = react.useState(false);
3181
3279
  if (props.variant === "connected") {
3182
3280
  const { address, onDisconnect } = props;
3183
3281
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "-mx-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: buttonBaseClasses, children: [
@@ -3201,6 +3299,7 @@ const WalletModalButton = (props) => {
3201
3299
  }
3202
3300
  const { walletId, connector } = props;
3203
3301
  const handleConnect = async () => {
3302
+ setIsConnecting(true);
3204
3303
  try {
3205
3304
  if (connector) {
3206
3305
  connect({ connector });
@@ -3213,9 +3312,13 @@ const WalletModalButton = (props) => {
3213
3312
  onClose?.();
3214
3313
  } catch (error) {
3215
3314
  console.error("Failed to connect wallet:", error);
3315
+ const errorMessage = error instanceof Error ? error.message : "Failed to connect wallet. Please try again.";
3316
+ sonner.toast.error(errorMessage);
3317
+ } finally {
3318
+ setIsConnecting(false);
3216
3319
  }
3217
3320
  };
3218
- const isDisabled = connector ? isPending : false;
3321
+ const isDisabled = connector ? isPending : isConnecting;
3219
3322
  return /* @__PURE__ */ jsxRuntime.jsxs(
3220
3323
  button.Button,
3221
3324
  {
@@ -3326,7 +3429,7 @@ const WalletSelectModal = () => {
3326
3429
  }
3327
3430
  ].filter((category) => category.wallets.length > 0);
3328
3431
  return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { children: [
3329
- /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogHeader, { children: [
3432
+ /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogHeader, { className: "text-left", children: [
3330
3433
  /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("wallets.chooseWallet") }),
3331
3434
  /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogDescription, { children: t("wallets.oneWalletPerEnv") })
3332
3435
  ] }),
@@ -3369,7 +3472,7 @@ const WalletSelectModal = () => {
3369
3472
  ] }) });
3370
3473
  };
3371
3474
  const ProgressStep = ({
3372
- icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "w-12 h-12 animate-spin" })
3475
+ icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "w-16 h-16 animate-spin" })
3373
3476
  }) => {
3374
3477
  const { t } = useBridgeTranslation();
3375
3478
  return /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogContent, { showCloseButton: false, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex relative flex-col gap-4 py-10 px-8 flex-1 items-center justify-start text-center noise bg-background", children: [
@@ -3379,33 +3482,123 @@ const ProgressStep = ({
3379
3482
  ] }) });
3380
3483
  };
3381
3484
  const FailedStep = ({
3382
- icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircleIcon, { className: "w-12 h-12" })
3485
+ icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircleIcon, { className: "w-16 h-16" })
3383
3486
  }) => {
3384
3487
  const { current, reset } = useTransactionStore();
3385
3488
  const { t } = useBridgeTranslation();
3386
3489
  return /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { showCloseButton: false, children: [
3387
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col relative gap-4 pt-10 px-8 flex-1 items-center justify-start text-center noise", children: [
3490
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col relative gap-4 py-10 px-8 flex-1 items-center justify-start text-center noise", children: [
3388
3491
  icon,
3389
- /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("transaction.failed") }) }),
3390
- current?.errorCode && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full space-y-2 mt-6 relative z-10", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: t(
3391
- `errors.${current.errorCode}`,
3392
- current.errorParams || {}
3393
- ) }) })
3492
+ /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogHeader, { children: [
3493
+ /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("transaction.failed") }),
3494
+ current?.errorCode && /* @__PURE__ */ jsxRuntime.jsx(reactDialog.DialogDescription, { children: t(
3495
+ `errors.${current.errorCode}`,
3496
+ current.errorParams || {}
3497
+ ) })
3498
+ ] })
3394
3499
  ] }),
3395
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-col gap-3 pb-10 px-8", children: /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "outline", className: "w-full", onClick: reset, children: t("common.close") }) })
3500
+ /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "outline", className: "w-full min-w-40", onClick: reset, children: t("common.close") }) })
3396
3501
  ] });
3397
3502
  };
3503
+ const EXPLORER_CONFIGS = {
3504
+ // TON
3505
+ ton: {
3506
+ baseUrl: "https://tonscan.org",
3507
+ txPath: "/tx/"
3508
+ },
3509
+ // TRON
3510
+ tron: {
3511
+ baseUrl: "https://tronscan.org",
3512
+ txPath: "/#/transaction/"
3513
+ },
3514
+ // Ethereum & EVM chains
3515
+ ethereum: {
3516
+ baseUrl: "https://etherscan.io",
3517
+ txPath: "/tx/"
3518
+ },
3519
+ eth: {
3520
+ baseUrl: "https://etherscan.io",
3521
+ txPath: "/tx/"
3522
+ },
3523
+ // BSC (Binance Smart Chain)
3524
+ bsc: {
3525
+ baseUrl: "https://bscscan.com",
3526
+ txPath: "/tx/"
3527
+ },
3528
+ "binance-smart-chain": {
3529
+ baseUrl: "https://bscscan.com",
3530
+ txPath: "/tx/"
3531
+ },
3532
+ // Polygon
3533
+ polygon: {
3534
+ baseUrl: "https://polygonscan.com",
3535
+ txPath: "/tx/"
3536
+ },
3537
+ matic: {
3538
+ baseUrl: "https://polygonscan.com",
3539
+ txPath: "/tx/"
3540
+ },
3541
+ // Avalanche
3542
+ avalanche: {
3543
+ baseUrl: "https://snowtrace.io",
3544
+ txPath: "/tx/"
3545
+ },
3546
+ avax: {
3547
+ baseUrl: "https://snowtrace.io",
3548
+ txPath: "/tx/"
3549
+ },
3550
+ // Arbitrum
3551
+ arbitrum: {
3552
+ baseUrl: "https://arbiscan.io",
3553
+ txPath: "/tx/"
3554
+ },
3555
+ // Optimism
3556
+ optimism: {
3557
+ baseUrl: "https://optimistic.etherscan.io",
3558
+ txPath: "/tx/"
3559
+ },
3560
+ // Base
3561
+ base: {
3562
+ baseUrl: "https://basescan.org",
3563
+ txPath: "/tx/"
3564
+ },
3565
+ // Fantom
3566
+ fantom: {
3567
+ baseUrl: "https://ftmscan.com",
3568
+ txPath: "/tx/"
3569
+ }
3570
+ };
3571
+ function getExplorerTxUrl(chainKey, txHash) {
3572
+ if (!chainKey || !txHash) {
3573
+ return null;
3574
+ }
3575
+ const normalizedChainKey = chainKey.toLowerCase();
3576
+ const config = EXPLORER_CONFIGS[normalizedChainKey];
3577
+ if (!config) {
3578
+ console.warn(
3579
+ `No explorer config found for chain: ${chainKey}. Please add it to EXPLORER_CONFIGS.`
3580
+ );
3581
+ return null;
3582
+ }
3583
+ return `${config.baseUrl}${config.txPath}${txHash}`;
3584
+ }
3585
+ function openTransactionInExplorer(chainKey, txHash) {
3586
+ const url = getExplorerTxUrl(chainKey, txHash);
3587
+ if (url && typeof window !== "undefined") {
3588
+ window.open(url, "_blank", "noopener,noreferrer");
3589
+ }
3590
+ }
3398
3591
  const SuccessStep = ({
3399
- icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "w-12 h-12" })
3592
+ icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "w-16 h-16" })
3400
3593
  }) => {
3401
3594
  const { current, reset } = useTransactionStore();
3402
3595
  const { t } = useBridgeTranslation();
3403
3596
  const metadata = current?.metadata;
3404
3597
  const srcTxHash = current?.srcTxHash;
3405
- const handleCopyHash = () => {
3406
- if (srcTxHash) {
3407
- navigator.clipboard.writeText(srcTxHash);
3408
- sonner.toast.success(t("transaction.hashCopied"));
3598
+ const srcChainKey = current?.quote?.srcChainKey;
3599
+ const handleOpenExplorer = () => {
3600
+ if (srcTxHash && srcChainKey) {
3601
+ openTransactionInExplorer(srcChainKey, srcTxHash);
3409
3602
  }
3410
3603
  };
3411
3604
  return /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { showCloseButton: false, children: [
@@ -3445,8 +3638,8 @@ const SuccessStep = ({
3445
3638
  /* @__PURE__ */ jsxRuntime.jsx(
3446
3639
  "button",
3447
3640
  {
3448
- onClick: handleCopyHash,
3449
- className: "font-medium hover:underline cursor-pointer",
3641
+ onClick: handleOpenExplorer,
3642
+ className: "font-medium hover:underline cursor-pointer inline-flex items-center gap-1",
3450
3643
  children: formatHash(srcTxHash)
3451
3644
  }
3452
3645
  )
@@ -3482,7 +3675,7 @@ const useCountdown = (initialSeconds) => {
3482
3675
  };
3483
3676
  };
3484
3677
  const ConfirmStep = ({
3485
- icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "w-12 h-12" })
3678
+ icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "w-16 h-16" })
3486
3679
  }) => {
3487
3680
  const { t } = useBridgeTranslation();
3488
3681
  const { formatTime } = useCountdown(90);
@@ -3636,49 +3829,6 @@ class ChainStrategyRegistry {
3636
3829
  await strategy.disconnect();
3637
3830
  }
3638
3831
  }
3639
- const EVM_CONFIG = {
3640
- usdtAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
3641
- gasEstimates: {
3642
- approve: 65000n,
3643
- bridge: 300000n
3644
- },
3645
- gasBuffer: 1.2,
3646
- // 20% buffer
3647
- timeout: 3e5,
3648
- // 5 minutes (increased for slower networks)
3649
- requiredConfirmations: 3
3650
- // Wait for 3 confirmations for reorg protection
3651
- };
3652
- const TON_CONFIG = {
3653
- apiUrl: "https://toncenter.com/api/v2",
3654
- timeout: 36e4,
3655
- // 6 minutes
3656
- validUntil: 600
3657
- // 10 minutes
3658
- };
3659
- const TRON_CONFIG = {
3660
- timeout: 12e4,
3661
- // 2 minutes (for 19 confirmations)
3662
- feeLimit: 1e8,
3663
- // 100 TRX in sun
3664
- requiredConfirmations: 19,
3665
- // TRON standard: 19 blocks for confirmation
3666
- pollingInterval: 3e3
3667
- // 3 seconds between checks
3668
- };
3669
- let tonClientInstance = null;
3670
- function getTonClient(customClient, apiKey) {
3671
- if (customClient) {
3672
- return customClient;
3673
- }
3674
- if (!tonClientInstance) {
3675
- tonClientInstance = new ton.TonClient({
3676
- endpoint: `${TON_CONFIG.apiUrl}/jsonRPC`,
3677
- apiKey
3678
- });
3679
- }
3680
- return tonClientInstance;
3681
- }
3682
3832
  function isNativeAddress(addr) {
3683
3833
  if (!addr) return false;
3684
3834
  const a = addr.toLowerCase();
@@ -4422,13 +4572,17 @@ class TonChainStrategy {
4422
4572
  nativeTokenSymbol,
4423
4573
  amount,
4424
4574
  balances,
4575
+ nativeDecimals = 9,
4425
4576
  reserveFallback
4426
4577
  } = params;
4427
4578
  const nativeSym = nativeTokenSymbol.toUpperCase();
4428
4579
  const isNativeSelected = nativeSym === (selectedToken?.symbol ?? "").toUpperCase();
4429
4580
  const nativeBalance = Number(balances[nativeSym]?.balance ?? 0);
4430
- const estimatedGas = null;
4431
- const requiredNative = reserveFallback;
4581
+ const { formatUnits } = await import("ethers");
4582
+ const estimatedGas = Number(
4583
+ formatUnits(TON_CONFIG.estimatedNetworkFee, nativeDecimals)
4584
+ );
4585
+ const requiredNative = estimatedGas > 0 ? estimatedGas : reserveFallback;
4432
4586
  const amountNum = amount ?? 0;
4433
4587
  let hasEnoughGas = true;
4434
4588
  if (isNativeSelected) {
@@ -4497,12 +4651,24 @@ class TonChainStrategy {
4497
4651
  const result = await this.config.tonConnectUI.sendTransaction(
4498
4652
  transaction2
4499
4653
  );
4500
- const hash = result.boc;
4501
- onFirstHash?.(hash);
4502
- return {
4503
- chainKey: "ton",
4504
- hash
4505
- };
4654
+ const bocBase64 = result.boc;
4655
+ try {
4656
+ const inMessage = core.loadMessage(core.Cell.fromBase64(bocBase64).beginParse());
4657
+ const messageHash = this.getNormalizedExtMessageHash(inMessage);
4658
+ const hexHash = messageHash.toString("hex");
4659
+ onFirstHash?.(hexHash);
4660
+ return {
4661
+ chainKey: "ton",
4662
+ hash: hexHash
4663
+ };
4664
+ } catch (error) {
4665
+ console.error("Error parsing BOC to hex hash:", error);
4666
+ onFirstHash?.(bocBase64);
4667
+ return {
4668
+ chainKey: "ton",
4669
+ hash: bocBase64
4670
+ };
4671
+ }
4506
4672
  } catch (error) {
4507
4673
  throw toChainStrategyError(error, "ton", "transaction");
4508
4674
  }
@@ -4555,20 +4721,31 @@ class TonChainStrategy {
4555
4721
  };
4556
4722
  return core.beginCell().store(core.storeMessage(normalizedMessage, { forceRef: true })).endCell().hash();
4557
4723
  }
4558
- async checkTonTransaction(bocBase64, timeoutMs = 36e4) {
4724
+ async checkTonTransaction(hashOrBoc, timeoutMs = 36e4) {
4559
4725
  const deadline = Date.now() + timeoutMs;
4560
4726
  const client = getTonClient(this.config.tonClient, this.config.tonApiKey);
4561
4727
  try {
4562
- const inMessage = core.loadMessage(core.Cell.fromBase64(bocBase64).beginParse());
4563
- if (inMessage.info.type !== "external-in") {
4564
- console.debug(
4565
- "Expected external-in message, got:",
4566
- inMessage.info.type
4567
- );
4568
- return false;
4728
+ let targetMessageHash;
4729
+ let accountAddress;
4730
+ try {
4731
+ const inMessage = core.loadMessage(core.Cell.fromBase64(hashOrBoc).beginParse());
4732
+ if (inMessage.info.type !== "external-in") {
4733
+ console.debug(
4734
+ "Expected external-in message, got:",
4735
+ inMessage.info.type
4736
+ );
4737
+ return false;
4738
+ }
4739
+ accountAddress = inMessage.info.dest;
4740
+ targetMessageHash = this.getNormalizedExtMessageHash(inMessage);
4741
+ } catch {
4742
+ targetMessageHash = Buffer.from(hashOrBoc, "hex");
4743
+ if (!this.config.tonAddress) {
4744
+ console.debug("No wallet address available for hex hash lookup");
4745
+ return false;
4746
+ }
4747
+ accountAddress = core.Address.parse(this.config.tonAddress);
4569
4748
  }
4570
- const accountAddress = inMessage.info.dest;
4571
- const targetMessageHash = this.getNormalizedExtMessageHash(inMessage);
4572
4749
  let lt = void 0;
4573
4750
  let hash = void 0;
4574
4751
  while (Date.now() < deadline) {
@@ -4580,7 +4757,7 @@ class TonChainStrategy {
4580
4757
  archival: true
4581
4758
  });
4582
4759
  if (transactions.length === 0) {
4583
- await new Promise((r) => setTimeout(r, 3e3));
4760
+ await new Promise((r) => setTimeout(r, TON_CONFIG.pollingInterval));
4584
4761
  lt = void 0;
4585
4762
  hash = void 0;
4586
4763
  continue;
@@ -4599,9 +4776,10 @@ class TonChainStrategy {
4599
4776
  const lastTx = transactions[transactions.length - 1];
4600
4777
  lt = lastTx.lt.toString();
4601
4778
  hash = lastTx.hash().toString("base64");
4779
+ await new Promise((r) => setTimeout(r, TON_CONFIG.pollingInterval));
4602
4780
  } catch (error) {
4603
4781
  console.debug("Error fetching transactions:", error);
4604
- await new Promise((r) => setTimeout(r, 3e3));
4782
+ await new Promise((r) => setTimeout(r, TON_CONFIG.pollingInterval));
4605
4783
  lt = void 0;
4606
4784
  hash = void 0;
4607
4785
  }
@@ -4628,9 +4806,14 @@ class TronChainStrategy {
4628
4806
  return "TRON Chain Strategy";
4629
4807
  }
4630
4808
  async connect() {
4631
- const tronWeb = this.getTronWeb();
4632
- if (!tronWeb && (typeof window === "undefined" || !window.tronLink)) {
4633
- throw new WalletNotFoundError("tron", "TronLink");
4809
+ if (!this.isTronLinkInstalled()) {
4810
+ if (typeof window !== "undefined") {
4811
+ window.open("https://www.tronlink.org/", "_blank");
4812
+ }
4813
+ throw new WalletNotFoundError(
4814
+ "tron",
4815
+ "TronLink wallet is not installed. Please install TronLink extension and try again."
4816
+ );
4634
4817
  }
4635
4818
  this.config.tronSelect(tronwalletAdapters.TronLinkAdapterName);
4636
4819
  await new Promise((resolve) => setTimeout(resolve, 100));
@@ -4909,6 +5092,23 @@ class TronChainStrategy {
4909
5092
  getTronWeb() {
4910
5093
  return typeof window !== "undefined" ? window.tronWeb : void 0;
4911
5094
  }
5095
+ /**
5096
+ * Check if TronLink wallet is actually installed
5097
+ * This excludes Bybit Wallet which also injects tronLink for compatibility
5098
+ */
5099
+ isTronLinkInstalled() {
5100
+ if (typeof window === "undefined") {
5101
+ return false;
5102
+ }
5103
+ const hasBybitWallet = typeof window.bybitWallet !== "undefined" && typeof window.bybitWallet.tronLink !== "undefined";
5104
+ if (hasBybitWallet && !window.tronLink) {
5105
+ return false;
5106
+ }
5107
+ if (!window.tronLink) {
5108
+ return false;
5109
+ }
5110
+ return true;
5111
+ }
4912
5112
  hexToAscii(h) {
4913
5113
  if (!h) return null;
4914
5114
  const clean = h.replace(/^0x/, "");
@@ -5312,7 +5512,7 @@ const routePresets = [
5312
5512
  RoutePriority.CHEAPEST,
5313
5513
  RoutePriority.RECOMMENDED
5314
5514
  ];
5315
- const SettingModal = ({ isOpen, onClose }) => {
5515
+ const SettingsModal = ({ isOpen, onClose }) => {
5316
5516
  const { t } = useBridgeTranslation();
5317
5517
  const { toChain } = useChainsStore();
5318
5518
  const { tokens } = useTokensStore();
@@ -5345,8 +5545,8 @@ const SettingModal = ({ isOpen, onClose }) => {
5345
5545
  );
5346
5546
  const activeBtn = "bg-primary hover:bg-primary/80 text-primary-foreground transition-colors";
5347
5547
  const notActiveBtn = "bg-accent hover:bg-accent/80 text-accent-foreground transition-colors";
5348
- return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { children: [
5349
- /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("settings.title") }) }),
5548
+ return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { onOpenAutoFocus: (e) => e.preventDefault(), children: [
5549
+ /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { className: "text-left", children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("settings.title") }) }),
5350
5550
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-5", children: [
5351
5551
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5", children: [
5352
5552
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [
@@ -5374,6 +5574,7 @@ const SettingModal = ({ isOpen, onClose }) => {
5374
5574
  badge.Badge,
5375
5575
  {
5376
5576
  onClick: () => setGasPreset(g),
5577
+ size: "lg",
5377
5578
  className: utils.cn(
5378
5579
  "cursor-pointer",
5379
5580
  gasPreset === g ? activeBtn : notActiveBtn
@@ -5400,6 +5601,7 @@ const SettingModal = ({ isOpen, onClose }) => {
5400
5601
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: slippagePresets.map((p) => /* @__PURE__ */ jsxRuntime.jsx(
5401
5602
  badge.Badge,
5402
5603
  {
5604
+ size: "lg",
5403
5605
  onClick: () => {
5404
5606
  const bps = parseFloat(p.replace("%", "")) * 100;
5405
5607
  setSlippageBps(bps);
@@ -5423,6 +5625,7 @@ const SettingModal = ({ isOpen, onClose }) => {
5423
5625
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end gap-2", children: routePresets.map((r) => /* @__PURE__ */ jsxRuntime.jsx(
5424
5626
  badge.Badge,
5425
5627
  {
5628
+ size: "lg",
5426
5629
  onClick: () => setRoutePriority(r),
5427
5630
  className: utils.cn(
5428
5631
  "cursor-pointer",
@@ -5615,7 +5818,7 @@ const TokenSelectModal = ({
5615
5818
  );
5616
5819
  const hasNoResults = tokensToRender.length === 0 && willChangeSrcTokens.length === 0;
5617
5820
  return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { className: "max-h-[90dvh] h-[90dvh] overflow-hidden flex flex-col", children: [
5618
- /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("bridge.selectToken") }) }),
5821
+ /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { className: "text-left", children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("bridge.selectToken") }) }),
5619
5822
  /* @__PURE__ */ jsxRuntime.jsx(
5620
5823
  SearchInput,
5621
5824
  {
@@ -5839,7 +6042,7 @@ const Toolbar = () => {
5839
6042
  }
5840
6043
  }
5841
6044
  ),
5842
- /* @__PURE__ */ jsxRuntime.jsx(SettingModal, { isOpen: isOpenSettings, onClose: onCloseSettings })
6045
+ /* @__PURE__ */ jsxRuntime.jsx(SettingsModal, { isOpen: isOpenSettings, onClose: onCloseSettings })
5843
6046
  ] });
5844
6047
  };
5845
6048
  const EvaaBridgeWithProviders = (props) => {
@@ -6101,6 +6304,7 @@ exports.DEFAULT_SLIPPAGE_BPS = DEFAULT_SLIPPAGE_BPS;
6101
6304
  exports.EvaaBridge = EvaaBridge;
6102
6305
  exports.RoutePriority = RoutePriority;
6103
6306
  exports.RouteType = RouteType;
6307
+ exports.addTonNetworkFee = addTonNetworkFee;
6104
6308
  exports.addrForApi = addrForApi;
6105
6309
  exports.buildAssetMatrix = buildAssetMatrix;
6106
6310
  exports.calculateMinReceived = calculateMinReceived;