@rash2x/bridge-widget 0.1.12 → 0.1.13

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.
package/README.md CHANGED
@@ -99,10 +99,11 @@ function App() {
99
99
  }
100
100
  ```
101
101
 
102
- ### 2. With Event Handlers
102
+ ### 2. With Event Handlers and Language
103
103
 
104
104
  ```tsx
105
105
  <EvaaBridge
106
+ defaultLanguage="ru" // Set default language (en, ru)
106
107
  onSwapSuccess={(data) => {
107
108
  console.log('Swap completed:', data);
108
109
  }}
@@ -128,7 +129,9 @@ function App() {
128
129
  | Prop | Type | Description |
129
130
  |------|------|-------------|
130
131
  | `className` | `string` | Optional CSS class for custom styling |
131
- | `theme` | `'light' \| 'dark'` | Theme mode |
132
+ | `defaultLanguage` | `string` | Language for the widget UI (default: `'en'`). Supported: `'en'`, `'ru'` |
133
+ | `tonClient` | `TonClient` | Optional TON client instance |
134
+ | `tonApiKey` | `string` | Optional TON API key |
132
135
  | `onInitialized` | `() => void` | Callback when bridge is initialized |
133
136
  | `onSwapStart` | `(data: SwapStartData) => void` | Callback when swap starts |
134
137
  | `onSwapSuccess` | `(data: SwapSuccessData) => void` | Callback when swap succeeds |
@@ -25,8 +25,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
25
25
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
26
26
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
27
27
  const jsxRuntime = require("react/jsx-runtime");
28
- const reactI18next = require("react-i18next");
29
28
  const require$$0 = require("react");
29
+ const reactI18next = require("react-i18next");
30
+ const i18n = require("i18next");
30
31
  const zustand = require("zustand");
31
32
  const button = require("@/components/ui/button");
32
33
  const dialog = require("@/components/ui/dialog");
@@ -45,12 +46,76 @@ const _switch = require("@/components/ui/switch");
45
46
  const lucideReact = require("lucide-react");
46
47
  const framerMotion = require("framer-motion");
47
48
  const accordion = require("@/components/ui/accordion");
48
- const i18next = require("i18next");
49
49
  const sonner = require("sonner");
50
50
  const ethers = require("ethers");
51
51
  const viem = require("viem");
52
52
  const ton = require("@ton/ton");
53
53
  const tronwalletAdapters = require("@tronweb3/tronwallet-adapters");
54
+ const common$1 = { "connecting": "Connecting…", "initializing": "Initializing...", "loading": "Loading...", "paste": "paste", "close": "Close", "zeroPlaceholder": "0", "nativeToken": "Native Token" };
55
+ 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", "tonAddressPlaceholder": "TON address", "evmAddressPlaceholder": "0x… EVM address", "addressDoesntMatch": "Address doesn't match the {{network}} network", "checkBeforeTransfer": "Check correctness before transfer" };
57
+ 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}}", "successTitle": "Success", "bridged": "Bridged", "transferTitle": "Transfer", "hash": "Hash", "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
+ const app$1 = { "stargateWidgetName": "Stargate Bridge Widget", "liveWidget": "Live Widget", "getStarted": "Get Started" };
59
+ 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" } };
60
+ const en = {
61
+ common: common$1,
62
+ wallets: wallets$1,
63
+ bridge: bridge$1,
64
+ transaction: transaction$1,
65
+ app: app$1,
66
+ settings: settings$1
67
+ };
68
+ const common = { "connecting": "Подключение…", "initializing": "Инициализация...", "loading": "Загрузка...", "paste": "вставить", "close": "Закрыть", "zeroPlaceholder": "0", "nativeToken": "Нативный токен" };
69
+ 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": "Подключить кошелёк" };
70
+ const bridge = { "sourceNetwork": "Исходная сеть", "destinationNetwork": "Целевая сеть", "selectToken": "Выбрать токен", "selectNetwork": "Выбрать сеть", "searchToken": "Поиск токена", "searchDestinationChain": "Поиск целевой сети", "myTokens": "Мои токены", "allTokens": "Все токены", "willChangeSourceChain": "Сменит исходную сеть", "noBalancesFound": "Балансы не найдены.", "noResults": "Нет результатов", "sendToAnotherAddress": "Отправить на другой адрес", "youWillReceive": "Вы получите", "tonAddressPlaceholder": "TON адрес", "evmAddressPlaceholder": "0x… EVM адрес", "addressDoesntMatch": "Адрес не соответствует сети {{network}}", "checkBeforeTransfer": "Проверьте корректность перед переводом" };
71
+ const transaction = { "enterAmount": "Введите сумму", "transfer": "Перевести", "getQuote": "Получить котировку", "quoting": "Расчет котировки...", "failed": "Ошибка транзакции", "confirm": "Подтвердите транзакцию", "signTransaction": "Подпишите транзакцию в кошельке", "inProgress": "Выполнение...", "checkingBalance": "Проверка баланса...", "insufficientBalance": "Недостаточно средств", "amountTooSmall": "Минимум {{min}}", "amountTooLarge": "Максимум {{max}}", "successTitle": "Успех", "bridged": "Переведено", "transferTitle": "Перевод", "hash": "Хэш", "route": "Маршрут", "estTime": "Время", "slippage": "Проскальзывание", "minimumReceived": "Минимум к получению", "totalFee": "Общая комиссия", "noRouteFound": "Маршрут не найден", "notEnoughGas": "Недостаточно газа", "noRouteFoundForSettings": "Маршрут не найден для текущих настроек.", "tryAdjustSettings": "Попробуйте отключить Gas on Destination или измените сумму/сети.", "quoteError": "Ошибка котировки" };
72
+ const app = { "stargateWidgetName": "Виджет Stargate Bridge", "liveWidget": "Живой виджет", "getStarted": "Начало работы" };
73
+ const settings = { "title": "Настройки", "gasOnDestination": "Газ на назначении", "slippageTolerance": "Толерантность к проскальзыванию", "routePriority": "Приоритет маршрута", "highSlippageWarning": "Высокое проскальзывание", "gasPresets": { "auto": "Авто", "none": "Нет", "medium": "Средний", "max": "Макс" }, "routePresets": { "fastest": "Быстрейший", "cheapest": "Дешевейший", "recommended": "Рекомендуемый" } };
74
+ const ru = {
75
+ common,
76
+ wallets,
77
+ bridge,
78
+ transaction,
79
+ app,
80
+ settings
81
+ };
82
+ const bridgeI18n = i18n.createInstance();
83
+ const resources = {
84
+ en: {
85
+ "evaa-bridge": en
86
+ },
87
+ ru: {
88
+ "evaa-bridge": ru
89
+ }
90
+ };
91
+ bridgeI18n.use(reactI18next.initReactI18next).init({
92
+ resources,
93
+ lng: "en",
94
+ // Will be overridden by defaultLanguage prop
95
+ fallbackLng: "en",
96
+ debug: false,
97
+ // Use a dedicated namespace to avoid conflicts
98
+ defaultNS: "evaa-bridge",
99
+ ns: ["evaa-bridge"],
100
+ interpolation: {
101
+ escapeValue: false
102
+ // react already does escaping
103
+ }
104
+ });
105
+ function BridgeI18nProvider({
106
+ children,
107
+ defaultLanguage = "en"
108
+ }) {
109
+ require$$0.useEffect(() => {
110
+ if (bridgeI18n.language !== defaultLanguage) {
111
+ bridgeI18n.changeLanguage(defaultLanguage);
112
+ }
113
+ }, [defaultLanguage]);
114
+ return /* @__PURE__ */ jsxRuntime.jsx(reactI18next.I18nextProvider, { i18n: bridgeI18n, children });
115
+ }
116
+ function useBridgeTranslation() {
117
+ return reactI18next.useTranslation("evaa-bridge", { i18n: bridgeI18n });
118
+ }
54
119
  const norm = (s) => (s ?? "").toUpperCase().replace(/₮/g, "T").replace(/[^A-Z0-9]/g, "");
55
120
  const POPULAR_ORDER = [
56
121
  "USDT",
@@ -831,7 +896,7 @@ const routePresets = [
831
896
  RoutePriority.RECOMMENDED
832
897
  ];
833
898
  const SettingModal = ({ isOpen, onClose }) => {
834
- const { t } = reactI18next.useTranslation();
899
+ const { t } = useBridgeTranslation();
835
900
  const { toChain } = useChainsStore();
836
901
  const { tokens } = useTokensStore();
837
902
  const {
@@ -1458,7 +1523,7 @@ const TokenSelectModal = ({
1458
1523
  items,
1459
1524
  onChangeAsset
1460
1525
  }) => {
1461
- const { t } = reactI18next.useTranslation();
1526
+ const { t } = useBridgeTranslation();
1462
1527
  const {
1463
1528
  query,
1464
1529
  setQuery,
@@ -1692,7 +1757,7 @@ const SelectTokenButton = ({
1692
1757
  onClick,
1693
1758
  token
1694
1759
  }) => {
1695
- const { t } = reactI18next.useTranslation();
1760
+ const { t } = useBridgeTranslation();
1696
1761
  const label = require$$0.useMemo(() => {
1697
1762
  return token?.symbol ?? t("bridge.selectToken");
1698
1763
  }, [token, t]);
@@ -1722,7 +1787,7 @@ const SelectTokenButton = ({
1722
1787
  );
1723
1788
  };
1724
1789
  const FormHeaderComponent = () => {
1725
- const { t } = reactI18next.useTranslation();
1790
+ const { t } = useBridgeTranslation();
1726
1791
  const { isOpen, onClose, onOpen } = useModal();
1727
1792
  const {
1728
1793
  isOpen: isOpenSettings,
@@ -2227,7 +2292,7 @@ const SelectNetworkButton = ({
2227
2292
  onClick,
2228
2293
  network
2229
2294
  }) => {
2230
- const { t } = reactI18next.useTranslation();
2295
+ const { t } = useBridgeTranslation();
2231
2296
  const label = require$$0.useMemo(() => {
2232
2297
  return network?.name ?? t("bridge.selectNetwork");
2233
2298
  }, [network, t]);
@@ -2324,7 +2389,7 @@ const ChainSelectModal = ({
2324
2389
  allowedItems,
2325
2390
  onChangeChain
2326
2391
  }) => {
2327
- const { t } = reactI18next.useTranslation();
2392
+ const { t } = useBridgeTranslation();
2328
2393
  const [query, setQuery] = require$$0.useState("");
2329
2394
  const [isFocused, setIsFocused] = require$$0.useState(false);
2330
2395
  const { setFromChain, chains, fromChain, toChain } = useChainsStore();
@@ -2469,7 +2534,7 @@ const WalletButton = ({
2469
2534
  wallet,
2470
2535
  addressType
2471
2536
  }) => {
2472
- const { t } = reactI18next.useTranslation();
2537
+ const { t } = useBridgeTranslation();
2473
2538
  const { onOpen } = useWalletSelectModal();
2474
2539
  const { chainRegistry } = useChainStrategies();
2475
2540
  const walletType = mapWalletToType(wallet);
@@ -2656,7 +2721,7 @@ const tonNormalize = (addr) => {
2656
2721
  }
2657
2722
  };
2658
2723
  const ToggleRow = ({ enabled, onToggle }) => {
2659
- const { t } = reactI18next.useTranslation();
2724
+ const { t } = useBridgeTranslation();
2660
2725
  const { toChain } = useChainsStore();
2661
2726
  const { dstAddress } = useAddresses();
2662
2727
  const { setCustomDstAddress, clearCustomDstAddress } = useCustomAddressStore();
@@ -2882,7 +2947,7 @@ function getRouteDisplayName(route) {
2882
2947
  return route.split(/[/\-_]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
2883
2948
  }
2884
2949
  const Details = () => {
2885
- const { t } = reactI18next.useTranslation();
2950
+ const { t } = useBridgeTranslation();
2886
2951
  const { selectedAssetSymbol, assetMatrix, tokens } = useTokensStore();
2887
2952
  const { toChain, fromChain, chains } = useChainsStore();
2888
2953
  const { quote, status } = useBridgeQuoteStore();
@@ -3528,7 +3593,7 @@ function useSilentValidations(amountString) {
3528
3593
  return validationResult;
3529
3594
  }
3530
3595
  const SubmitButton = () => {
3531
- const { t } = reactI18next.useTranslation();
3596
+ const { t } = useBridgeTranslation();
3532
3597
  const { chainRegistry } = useChainStrategies();
3533
3598
  const { srcAddress, dstAddress } = useAddresses();
3534
3599
  const { quote, status, inputAmount, noRoute } = useBridgeQuoteStore();
@@ -3623,13 +3688,22 @@ const SubmitButton = () => {
3623
3688
  }
3624
3689
  };
3625
3690
  const disabled = isBusy || amountNum <= 0 || status === "loading" || isBalanceLoading || hasInsufficientBalance || hasAmountTooLarge || !gas.hasEnoughGas || noRoute || !isValidForTransfer;
3626
- return /* @__PURE__ */ jsxRuntime.jsx(button.Button, { onClick: handleClick, disabled, className: "w-full mt-4", children: label });
3691
+ return /* @__PURE__ */ jsxRuntime.jsx(
3692
+ button.Button,
3693
+ {
3694
+ onClick: handleClick,
3695
+ disabled,
3696
+ size: "lg",
3697
+ className: "w-full mt-4",
3698
+ children: label
3699
+ }
3700
+ );
3627
3701
  };
3628
3702
  function short(addr) {
3629
3703
  return addr.slice(0, 4) + "…" + addr.slice(-4);
3630
3704
  }
3631
3705
  const WalletSelectModal = () => {
3632
- const { t } = reactI18next.useTranslation();
3706
+ const { t } = useBridgeTranslation();
3633
3707
  const { isOpen, onClose } = useWalletSelectModal();
3634
3708
  const { connect, connectors, isPending } = wagmi.useConnect();
3635
3709
  const { chainRegistry } = useChainStrategies();
@@ -3866,7 +3940,7 @@ const ProgressStep = () => {
3866
3940
  /* @__PURE__ */ jsxRuntime.jsx("span", {}),
3867
3941
  /* @__PURE__ */ jsxRuntime.jsx("span", {})
3868
3942
  ] }),
3869
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-display font-black relative z-10", children: i18next.t("transaction.inProgress") }),
3943
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-display font-black relative z-10", children: i18n.t("transaction.inProgress") }),
3870
3944
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative mt-5 z-10", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute dot-vertical h-full left-5 top-0 bottom-0 z-0" }) })
3871
3945
  ] }) });
3872
3946
  };
@@ -4123,10 +4197,10 @@ const FailedStep = () => {
4123
4197
  /* @__PURE__ */ jsxRuntime.jsx(TransactionFailedVector, {}),
4124
4198
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "on-circle on-circle-failed-small under-noise" }),
4125
4199
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "on-circle on-circle-failed-big under-noise" }),
4126
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-display font-black relative z-10", children: i18next.t("transaction.failed") }),
4200
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-display font-black relative z-10", children: i18n.t("transaction.failed") }),
4127
4201
  current?.error && /* @__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: current.error }) })
4128
4202
  ] }),
4129
- /* @__PURE__ */ jsxRuntime.jsx(card.CardFooter, { className: "flex-col gap-3 pb-10 px-8", children: /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "outline", className: "w-full", onClick: reset, children: i18next.t("common.close") }) })
4203
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardFooter, { className: "flex-col gap-3 pb-10 px-8", children: /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "outline", className: "w-full", onClick: reset, children: i18n.t("common.close") }) })
4130
4204
  ] });
4131
4205
  };
4132
4206
  const TransactionSuccessVector = (props) => {
@@ -5488,7 +5562,7 @@ var fireworksExports = requireFireworks();
5488
5562
  const Fireworks = /* @__PURE__ */ getDefaultExportFromCjs(fireworksExports);
5489
5563
  const SuccessStep = () => {
5490
5564
  const { current, reset } = useTransactionStore();
5491
- const { t } = reactI18next.useTranslation();
5565
+ const { t } = useBridgeTranslation();
5492
5566
  const metadata = current?.metadata;
5493
5567
  const srcTxHash = current?.srcTxHash;
5494
5568
  const handleCopyHash = () => {
@@ -5707,7 +5781,7 @@ const useCountdown = (initialSeconds) => {
5707
5781
  };
5708
5782
  };
5709
5783
  const ConfirmStep = () => {
5710
- const { t } = reactI18next.useTranslation();
5784
+ const { t } = useBridgeTranslation();
5711
5785
  const { formatTime } = useCountdown(90);
5712
5786
  return /* @__PURE__ */ jsxRuntime.jsx(card.Card, { className: "flex flex-col border-none h-full bg-background overflow-hidden rounded-none md:rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsxs(card.CardContent, { className: "flex flex-col relative gap-4 py-10 px-8 flex-1 items-center justify-start text-center noise", children: [
5713
5787
  /* @__PURE__ */ jsxRuntime.jsx(TransactionConfirmVector, {}),
@@ -6682,12 +6756,12 @@ class TonChainStrategy {
6682
6756
  payload: msg.payload
6683
6757
  })
6684
6758
  );
6685
- const transaction = {
6759
+ const transaction2 = {
6686
6760
  validUntil: Math.floor(Date.now() / 1e3) + TON_CONFIG.validUntil,
6687
6761
  messages: tonMessages
6688
6762
  };
6689
6763
  const result = await this.config.tonConnectUI.sendTransaction(
6690
- transaction
6764
+ transaction2
6691
6765
  );
6692
6766
  return {
6693
6767
  chainKey: "ton",
@@ -7506,7 +7580,7 @@ const EvaaBridgeWithProviders = (props) => {
7506
7580
  require$$0.useEffect(() => {
7507
7581
  setTronConnected(!!tronConnected);
7508
7582
  }, [tronConnected, setTronConnected]);
7509
- return /* @__PURE__ */ jsxRuntime.jsx(
7583
+ return /* @__PURE__ */ jsxRuntime.jsx(BridgeI18nProvider, { defaultLanguage: props.defaultLanguage, children: /* @__PURE__ */ jsxRuntime.jsx(
7510
7584
  ChainStrategyProvider,
7511
7585
  {
7512
7586
  evmWallet: {
@@ -7531,7 +7605,7 @@ const EvaaBridgeWithProviders = (props) => {
7531
7605
  tonApiKey: props.tonApiKey,
7532
7606
  children: /* @__PURE__ */ jsxRuntime.jsx(EvaaBridgeContent, { ...props })
7533
7607
  }
7534
- );
7608
+ ) });
7535
7609
  };
7536
7610
  const EvaaBridgeContent = ({
7537
7611
  className,
@@ -7539,7 +7613,7 @@ const EvaaBridgeContent = ({
7539
7613
  onAmountChange,
7540
7614
  onChainChange
7541
7615
  } = {}) => {
7542
- const { t } = reactI18next.useTranslation();
7616
+ const { t } = useBridgeTranslation();
7543
7617
  useTokensRequest();
7544
7618
  useChainsRequest();
7545
7619
  const [sendToAnother, setSendToAnother] = require$$0.useState(false);