@rash2x/bridge-widget 0.1.4 → 0.1.5

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,10 +44,11 @@ const reactWindow = require("react-window");
44
44
  const SwitchPrimitive = require("@radix-ui/react-switch");
45
45
  const lucideReact = require("lucide-react");
46
46
  const AccordionPrimitive = require("@radix-ui/react-accordion");
47
- const connectkit = require("connectkit");
48
47
  const i18next = require("i18next");
49
48
  const sonner = require("sonner");
50
49
  const ethers = require("ethers");
50
+ const viem = require("viem");
51
+ const ton = require("@ton/ton");
51
52
  const tronwalletAdapters = require("@tronweb3/tronwallet-adapters");
52
53
  function _interopNamespaceDefault(e) {
53
54
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -551,7 +552,7 @@ function cn(...inputs) {
551
552
  return tailwindMerge.twMerge(clsx.clsx(inputs));
552
553
  }
553
554
  const buttonVariants = classVarianceAuthority.cva(
554
- "inline-flex items-center rounded-full justify-center gap-2 whitespace-nowrap text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
555
+ "inline-flex items-center rounded-full text-lg justify-center gap-2 whitespace-nowrap text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
555
556
  {
556
557
  variants: {
557
558
  variant: {
@@ -824,19 +825,6 @@ const Tip = (props) => {
824
825
  /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: text }) })
825
826
  ] });
826
827
  };
827
- function toLD(human, decimals) {
828
- const [i = "0", f = ""] = human.replace(",", ".").split(".");
829
- const frac = (f + "0".repeat(decimals)).slice(0, decimals);
830
- return BigInt(i + frac).toString();
831
- }
832
- function fromLD(ld, decimals) {
833
- const bi = BigInt(ld || "0");
834
- if (decimals === 0) return Number(bi);
835
- const base = BigInt(10) ** BigInt(decimals);
836
- const int = bi / base;
837
- const frac = Number(bi % base) / Number(base);
838
- return Number(int) + frac;
839
- }
840
828
  async function getChains() {
841
829
  const res = await fetch("https://stargate.finance/api/v1/chains", {
842
830
  credentials: "same-origin"
@@ -884,49 +872,16 @@ async function getDestTokens(srcChainKey, srcTokenAddr) {
884
872
  });
885
873
  return unique;
886
874
  }
887
- const isTonFriendly = (a) => !!a && /^[A-Za-z0-9_-]{48,}$/.test(a);
888
- function normalizeTickerSymbol(s) {
875
+ function normalizeTickerSymbol$1(s) {
889
876
  return s.toUpperCase().replace(/₮/g, "T").replace(/[^A-Z0-9]/g, "");
890
877
  }
891
- async function getSwapBalances(accountFriendly) {
892
- if (!isTonFriendly(accountFriendly)) throw new Error("Invalid TON address");
893
- const accRes = await fetch(
894
- `https://tonapi.io/v2/accounts/${accountFriendly}`
895
- );
896
- if (!accRes.ok) throw new Error(`TON account fetch failed: ${accRes.status}`);
897
- const acc = await accRes.json();
898
- const ton = fromLD(String(acc?.balance ?? "0"), 9);
899
- const result = {
900
- TON: { balance: ton, address: "ton-native" }
901
- };
902
- const jetsRes = await fetch(
903
- `https://tonapi.io/v2/accounts/${accountFriendly}/jettons?limit=200`
904
- );
905
- if (!jetsRes.ok) return result;
906
- const jets = await jetsRes.json();
907
- const items = jets?.balances ?? jets?.jettons ?? jets?.items ?? [];
908
- for (const it of items) {
909
- const rawSym = (it?.jetton?.symbol ?? it?.symbol ?? "").toString();
910
- if (!rawSym) continue;
911
- const symUpper = rawSym.toUpperCase();
912
- const symNorm = normalizeTickerSymbol(symUpper);
913
- const master = (it?.jetton?.address ?? it?.address ?? "").toString();
914
- const decimals = Number(it?.jetton?.decimals ?? it?.decimals ?? 9) || 9;
915
- const raw = (it?.balance ?? "0").toString();
916
- const human = fromLD(raw, decimals);
917
- const entry = { balance: human, address: master };
918
- result[symUpper] = entry;
919
- if (symNorm !== symUpper) result[symNorm] = entry;
920
- }
921
- return result;
922
- }
923
878
  const BASE_URL$1 = "https://icons-ckg.pages.dev/stargate-light/tokens";
924
879
  const TokenSymbol = ({
925
880
  symbol,
926
881
  className = "w-4 h-4",
927
882
  alt
928
883
  }) => {
929
- const normalizedSymbol = normalizeTickerSymbol(symbol).toLowerCase();
884
+ const normalizedSymbol = normalizeTickerSymbol$1(symbol).toLowerCase();
930
885
  const src = `${BASE_URL$1}/${normalizedSymbol}.svg`;
931
886
  return /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: alt ?? symbol, className });
932
887
  };
@@ -1340,6 +1295,19 @@ function useChainStrategies() {
1340
1295
  }
1341
1296
  return context;
1342
1297
  }
1298
+ function toLD(human, decimals) {
1299
+ const [i = "0", f = ""] = human.replace(",", ".").split(".");
1300
+ const frac = (f + "0".repeat(decimals)).slice(0, decimals);
1301
+ return BigInt(i + frac).toString();
1302
+ }
1303
+ function fromLD(ld, decimals) {
1304
+ const bi = BigInt(ld || "0");
1305
+ if (decimals === 0) return Number(bi);
1306
+ const base = BigInt(10) ** BigInt(decimals);
1307
+ const int = bi / base;
1308
+ const frac = Number(bi % base) / Number(base);
1309
+ return Number(int) + frac;
1310
+ }
1343
1311
  function resolveTokenOnChainFromMatrix$2(assetMatrix, assetSymbol, chainKey) {
1344
1312
  if (!assetMatrix || !assetSymbol || !chainKey) return void 0;
1345
1313
  const byChain = assetMatrix[assetSymbol.toUpperCase()];
@@ -1521,20 +1489,17 @@ function useBalances(chainKey, address) {
1521
1489
  const data = query.data;
1522
1490
  if (data) {
1523
1491
  for (const [sum, v] of Object.entries(data)) {
1524
- map.set(normalizeTickerSymbol(sum), Number(v.balance ?? 0));
1492
+ map.set(normalizeTickerSymbol$1(sum), Number(v.balance ?? 0));
1525
1493
  }
1526
1494
  }
1527
1495
  return map;
1528
1496
  }, [query.data]);
1529
1497
  const getBalance = require$$0.useCallback(
1530
- (symbol) => balanceBySymbol.get(normalizeTickerSymbol(symbol)) ?? 0,
1498
+ (symbol) => balanceBySymbol.get(normalizeTickerSymbol$1(symbol)) ?? 0,
1531
1499
  [balanceBySymbol]
1532
1500
  );
1533
1501
  const isLoading = query.isLoading || query.isFetching;
1534
- const balances = require$$0.useMemo(
1535
- () => query.data || {},
1536
- [query.data]
1537
- );
1502
+ const balances = require$$0.useMemo(() => query.data || {}, [query.data]);
1538
1503
  return {
1539
1504
  balances,
1540
1505
  getBalance,
@@ -1990,17 +1955,17 @@ const RefreshButton = () => {
1990
1955
  return /* @__PURE__ */ jsxRuntime.jsx(
1991
1956
  Button,
1992
1957
  {
1993
- className: `cursor-pointer py-1.5 h-8.5 hover:scale-110 shadow-none px-8.5 hover:bg-secondary bg-secondary !rounded-40 ${spinning ? "opacity-70" : ""}`,
1994
1958
  onClick: handleRefresh,
1995
1959
  disabled: spinning,
1960
+ variant: "secondary",
1961
+ size: "sm",
1996
1962
  children: /* @__PURE__ */ jsxRuntime.jsx(
1997
1963
  ReloadIcon,
1998
1964
  {
1999
1965
  style: {
2000
1966
  transform: `rotate(${turns * 180}deg)`,
2001
1967
  transition: "transform 300ms linear"
2002
- },
2003
- className: "size-4 text-foreground m-1 will-change-transform"
1968
+ }
2004
1969
  }
2005
1970
  )
2006
1971
  }
@@ -2008,7 +1973,6 @@ const RefreshButton = () => {
2008
1973
  };
2009
1974
  const SelectTokenButton = ({
2010
1975
  onClick,
2011
- className,
2012
1976
  token
2013
1977
  }) => {
2014
1978
  const { t } = reactI18next.useTranslation();
@@ -2019,7 +1983,8 @@ const SelectTokenButton = ({
2019
1983
  Button,
2020
1984
  {
2021
1985
  onClick,
2022
- className: `cursor-pointer hover:scale-[1.1] p-1.5 h-8.5 pr-3 !pl-1.5 bg-secondary hover:bg-secondary shadow-none rounded-full flex items-center justify-between gap-3 w-fit shrink-0 ${className ?? ""}`,
1986
+ size: "sm",
1987
+ variant: "secondary",
2023
1988
  type: "button",
2024
1989
  "aria-label": label,
2025
1990
  children: [
@@ -2039,6 +2004,75 @@ const SelectTokenButton = ({
2039
2004
  }
2040
2005
  );
2041
2006
  };
2007
+ function Card({ className, ...props }) {
2008
+ return /* @__PURE__ */ jsxRuntime.jsx(
2009
+ "div",
2010
+ {
2011
+ "data-slot": "card",
2012
+ className: cn(
2013
+ "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
2014
+ className
2015
+ ),
2016
+ ...props
2017
+ }
2018
+ );
2019
+ }
2020
+ function CardHeader({ className, ...props }) {
2021
+ return /* @__PURE__ */ jsxRuntime.jsx(
2022
+ "div",
2023
+ {
2024
+ "data-slot": "card-header",
2025
+ className: cn(
2026
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
2027
+ className
2028
+ ),
2029
+ ...props
2030
+ }
2031
+ );
2032
+ }
2033
+ function CardTitle({ className, ...props }) {
2034
+ return /* @__PURE__ */ jsxRuntime.jsx(
2035
+ "div",
2036
+ {
2037
+ "data-slot": "card-title",
2038
+ className: cn("leading-none font-semibold", className),
2039
+ ...props
2040
+ }
2041
+ );
2042
+ }
2043
+ function CardAction({ className, ...props }) {
2044
+ return /* @__PURE__ */ jsxRuntime.jsx(
2045
+ "div",
2046
+ {
2047
+ "data-slot": "card-action",
2048
+ className: cn(
2049
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
2050
+ className
2051
+ ),
2052
+ ...props
2053
+ }
2054
+ );
2055
+ }
2056
+ function CardContent({ className, ...props }) {
2057
+ return /* @__PURE__ */ jsxRuntime.jsx(
2058
+ "div",
2059
+ {
2060
+ "data-slot": "card-content",
2061
+ className: cn("px-6", className),
2062
+ ...props
2063
+ }
2064
+ );
2065
+ }
2066
+ function CardFooter({ className, ...props }) {
2067
+ return /* @__PURE__ */ jsxRuntime.jsx(
2068
+ "div",
2069
+ {
2070
+ "data-slot": "card-footer",
2071
+ className: cn("flex items-center px-6 [.border-t]:pt-6", className),
2072
+ ...props
2073
+ }
2074
+ );
2075
+ }
2042
2076
  const FormHeaderComponent = ({ modalContainer }) => {
2043
2077
  const { t } = reactI18next.useTranslation();
2044
2078
  const { isOpen, onClose, onOpen } = useModal();
@@ -2055,29 +2089,14 @@ const FormHeaderComponent = ({ modalContainer }) => {
2055
2089
  const sum = selectedAssetSymbol.toUpperCase();
2056
2090
  return assets.find((a) => a.symbol.toUpperCase() === sum) ?? assets[0];
2057
2091
  }, [assets, selectedAssetSymbol]);
2058
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2059
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2060
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
2061
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-normal leading-3.5 text-muted-foreground", children: t("bridge.selectToken") }),
2062
- /* @__PURE__ */ jsxRuntime.jsx(SelectTokenButton, { token: current, onClick: onOpen })
2063
- ] }),
2064
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
2065
- /* @__PURE__ */ jsxRuntime.jsx(RefreshButton, {}),
2066
- /* @__PURE__ */ jsxRuntime.jsx(
2067
- Button,
2068
- {
2069
- className: "cursor-pointer py-1.5 h-8.5 hover:scale-110 shadow-none px-8.5 hover:bg-secondary bg-secondary !rounded-40",
2070
- onClick: onOpenSettings,
2071
- children: /* @__PURE__ */ jsxRuntime.jsx(
2072
- BoltIcon,
2073
- {
2074
- className: "size-4 text-foreground m-1",
2075
- stroke: "currentColor"
2076
- }
2077
- )
2078
- }
2079
- )
2080
- ] })
2092
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "gap-y-0", children: [
2093
+ /* @__PURE__ */ jsxRuntime.jsxs(CardTitle, { className: "flex items-center gap-2.5", children: [
2094
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-normal leading-3.5 text-muted-foreground", children: t("bridge.selectToken") }),
2095
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTokenButton, { token: current, onClick: onOpen })
2096
+ ] }),
2097
+ /* @__PURE__ */ jsxRuntime.jsxs(CardAction, { className: "flex items-center gap-2.5", children: [
2098
+ /* @__PURE__ */ jsxRuntime.jsx(RefreshButton, {}),
2099
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: onOpenSettings, size: "sm", variant: "secondary", children: /* @__PURE__ */ jsxRuntime.jsx(BoltIcon, { stroke: "currentColor" }) })
2081
2100
  ] }),
2082
2101
  /* @__PURE__ */ jsxRuntime.jsx(
2083
2102
  TokenSelectModal,
@@ -3963,7 +3982,7 @@ function useSilentValidations(amountString) {
3963
3982
  ]);
3964
3983
  return validationResult;
3965
3984
  }
3966
- function useTransferAction() {
3985
+ const SubmitButton = () => {
3967
3986
  const { t } = reactI18next.useTranslation();
3968
3987
  const { chainRegistry } = useChainStrategies();
3969
3988
  const { srcAddress, dstAddress } = useAddresses();
@@ -4039,7 +4058,7 @@ function useTransferAction() {
4039
4058
  maximumAmountFormatted,
4040
4059
  chainRegistry
4041
4060
  ]);
4042
- const onClick = async () => {
4061
+ const handleClick = async () => {
4043
4062
  if (isBusy) return;
4044
4063
  if (missingSrc && srcChainKey) {
4045
4064
  onOpen("src");
@@ -4059,24 +4078,7 @@ function useTransferAction() {
4059
4078
  }
4060
4079
  };
4061
4080
  const disabled = isBusy || amountNum <= 0 || status === "loading" || isBalanceLoading || hasInsufficientBalance || hasAmountTooLarge || !gas.hasEnoughGas || noRoute || !isValidForTransfer;
4062
- return {
4063
- // состояния
4064
- isBusy,
4065
- canTransfer,
4066
- missingSrc,
4067
- missingDst,
4068
- hasEnoughGas: gas.hasEnoughGas,
4069
- noRoute,
4070
- // представление
4071
- label,
4072
- disabled,
4073
- // действие
4074
- onClick
4075
- };
4076
- }
4077
- const SubmitButton = () => {
4078
- const { label, disabled, onClick } = useTransferAction();
4079
- return /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick, disabled, size: "lg", children: label });
4081
+ return /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleClick, disabled, className: "w-full", children: label });
4080
4082
  };
4081
4083
  function short(addr) {
4082
4084
  return addr.slice(0, 4) + "…" + addr.slice(-4);
@@ -4086,6 +4088,7 @@ const WalletSelectModal = ({
4086
4088
  }) => {
4087
4089
  const { t } = reactI18next.useTranslation();
4088
4090
  const { isOpen, onClose } = useWalletSelectModal();
4091
+ const { connect, connectors, isPending } = wagmi.useConnect();
4089
4092
  const { chainRegistry } = useChainStrategies();
4090
4093
  const tonWallet = chainRegistry.getStrategyByType("ton");
4091
4094
  const metaMaskWallet = chainRegistry.getStrategyByType("evm");
@@ -4118,7 +4121,13 @@ const WalletSelectModal = ({
4118
4121
  onDisconnect: () => tronWallet.disconnect()
4119
4122
  });
4120
4123
  }
4121
- const isWalletConnected = (walletId) => connectedWallets.some((w) => w.id === walletId);
4124
+ const isWalletConnected = (walletId) => {
4125
+ const isEvmConnector = connectors.some((c) => c.id === walletId);
4126
+ if (isEvmConnector && metaMaskWallet?.isConnected()) {
4127
+ return true;
4128
+ }
4129
+ return connectedWallets.some((w) => w.id === walletId);
4130
+ };
4122
4131
  const tonWallets = [
4123
4132
  {
4124
4133
  id: "ton",
@@ -4127,14 +4136,15 @@ const WalletSelectModal = ({
4127
4136
  enabled: true
4128
4137
  }
4129
4138
  ];
4130
- const evmWallets = [
4131
- {
4132
- id: "metamask",
4133
- name: t("wallets.metaMask"),
4134
- icon: MetaMaskIcon,
4135
- enabled: true
4136
- }
4137
- ];
4139
+ const evmWallets = connectors.filter(
4140
+ (connector) => connector.id === "walletConnect" || connector.id === "metaMaskSDK"
4141
+ ).map((connector) => ({
4142
+ id: connector.id,
4143
+ name: connector.name,
4144
+ icon: MetaMaskIcon,
4145
+ // You can add a WalletConnect icon here
4146
+ enabled: true
4147
+ }));
4138
4148
  const tronWallets = [
4139
4149
  {
4140
4150
  id: "tronlink",
@@ -4164,9 +4174,6 @@ const WalletSelectModal = ({
4164
4174
  case "ton":
4165
4175
  await tonWallet?.connect();
4166
4176
  break;
4167
- case "metamask":
4168
- await metaMaskWallet?.connect();
4169
- break;
4170
4177
  case "tronlink":
4171
4178
  await tronWallet?.connect();
4172
4179
  break;
@@ -4191,56 +4198,47 @@ const WalletSelectModal = ({
4191
4198
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-5 py-2 leading-4 text-base font-semibold text-muted-foreground uppercase", children: t("wallets.connected") }),
4192
4199
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "", children: connectedWallets.map((wallet) => {
4193
4200
  const IconComponent = wallet.icon;
4194
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "", children: /* @__PURE__ */ jsxRuntime.jsxs(
4195
- Button,
4196
- {
4197
- className: "w-full cursor-pointer bg-transparent flex shadow-none items-center justify-between gap-2.5 px-5 py-2.5 hover:bg-muted h-auto rounded-12 transition-[300]",
4198
- children: [
4199
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
4200
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-7.5 h-7.5 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "size-7.5" }) }),
4201
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start min-w-0", children: [
4202
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-extrabold text-foreground text-sm leading-4 truncate", children: short(wallet.address) }),
4203
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs leading-3 font-semibold text-muted-foreground", children: wallet.name })
4204
- ] })
4205
- ] }) }),
4206
- /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: () => {
4201
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "", children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { className: "w-full cursor-pointer bg-transparent flex shadow-none items-center justify-between gap-2.5 px-5 py-2.5 hover:bg-muted h-auto rounded-12 transition-[300]", children: [
4202
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
4203
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-7.5 h-7.5 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "size-7.5" }) }),
4204
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start min-w-0", children: [
4205
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-extrabold text-foreground text-sm leading-4 truncate", children: short(wallet.address) }),
4206
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs leading-3 font-semibold text-muted-foreground", children: wallet.name })
4207
+ ] })
4208
+ ] }) }),
4209
+ /* @__PURE__ */ jsxRuntime.jsx(
4210
+ "div",
4211
+ {
4212
+ onClick: () => {
4207
4213
  wallet.onDisconnect();
4208
4214
  onClose();
4209
- }, className: "text-sm font-medium text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(ExitIcon, { className: "text-[#808080] size-6" }) })
4210
- ]
4211
- }
4212
- ) }, wallet.id);
4215
+ },
4216
+ className: "text-sm font-medium text-muted-foreground",
4217
+ children: /* @__PURE__ */ jsxRuntime.jsx(ExitIcon, { className: "text-[#808080] size-6" })
4218
+ }
4219
+ )
4220
+ ] }) }, wallet.id);
4213
4221
  }) })
4214
4222
  ] }),
4215
4223
  categories.map((category) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4216
4224
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-5 py-2 leading-4 text-base font-semibold text-muted-foreground uppercase", children: category.title }),
4217
4225
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "", children: category.wallets.map((wallet) => {
4218
4226
  const IconComponent = wallet.icon;
4219
- if (wallet.id === "metamask") {
4220
- return /* @__PURE__ */ jsxRuntime.jsx("div", { id: wallet.id, children: /* @__PURE__ */ jsxRuntime.jsx(connectkit.ConnectKitButton.Custom, { children: ({ isConnecting, show }) => {
4221
- return /* @__PURE__ */ jsxRuntime.jsx(
4222
- Button,
4223
- {
4224
- type: "button",
4225
- onClick: show,
4226
- disabled: isConnecting,
4227
- className: "w-full cursor-pointer bg-transparent flex shadow-none items-center justify-between gap-2.5 px-5 py-2.5 hover:bg-muted h-auto rounded-12 transition-[300] disabled:opacity-50 disabled:cursor-not-allowed",
4228
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
4229
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-7.5 h-7.5 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "size-7.5" }) }),
4230
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start min-w-0", children: [
4231
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-extrabold text-foreground text-sm leading-4 truncate", children: wallet.name }),
4232
- wallet.comingSoon ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs leading-3 font-semibold text-muted-foreground", children: t("wallets.comingSoon") }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs leading-3 font-semibold text-muted-foreground", children: t("wallets.connect") })
4233
- ] })
4234
- ] })
4235
- }
4236
- );
4237
- } }) }, wallet.id);
4238
- }
4227
+ const isEvmConnector = category.title === t("wallets.evmWallets");
4228
+ const connector = isEvmConnector ? connectors.find((c) => c.id === wallet.id) : null;
4239
4229
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "", children: /* @__PURE__ */ jsxRuntime.jsx(
4240
4230
  Button,
4241
4231
  {
4242
- onClick: () => handleWalletSelect(wallet.id),
4243
- disabled: !wallet.enabled,
4232
+ type: "button",
4233
+ onClick: () => {
4234
+ if (connector) {
4235
+ connect({ connector });
4236
+ onClose();
4237
+ } else {
4238
+ handleWalletSelect(wallet.id);
4239
+ }
4240
+ },
4241
+ disabled: isEvmConnector ? isPending : !wallet.enabled,
4244
4242
  className: "w-full cursor-pointer bg-transparent flex shadow-none items-center justify-between gap-2.5 px-5 py-2.5 hover:bg-muted h-auto rounded-12 transition-[300] disabled:opacity-50 disabled:cursor-not-allowed",
4245
4243
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
4246
4244
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-7.5 h-7.5 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "size-7.5" }) }),
@@ -4256,39 +4254,6 @@ const WalletSelectModal = ({
4256
4254
  ] })
4257
4255
  ] }) });
4258
4256
  };
4259
- function Card({ className, ...props }) {
4260
- return /* @__PURE__ */ jsxRuntime.jsx(
4261
- "div",
4262
- {
4263
- "data-slot": "card",
4264
- className: cn(
4265
- "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
4266
- className
4267
- ),
4268
- ...props
4269
- }
4270
- );
4271
- }
4272
- function CardContent({ className, ...props }) {
4273
- return /* @__PURE__ */ jsxRuntime.jsx(
4274
- "div",
4275
- {
4276
- "data-slot": "card-content",
4277
- className: cn("px-6", className),
4278
- ...props
4279
- }
4280
- );
4281
- }
4282
- function CardFooter({ className, ...props }) {
4283
- return /* @__PURE__ */ jsxRuntime.jsx(
4284
- "div",
4285
- {
4286
- "data-slot": "card-footer",
4287
- className: cn("flex items-center px-6 [.border-t]:pt-6", className),
4288
- ...props
4289
- }
4290
- );
4291
- }
4292
4257
  const TransactionProgressVector = (props) => {
4293
4258
  return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "200", height: "200", viewBox: "0 0 200 200", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: [
4294
4259
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -6352,6 +6317,49 @@ class ChainStrategyRegistry {
6352
6317
  await strategy.disconnect();
6353
6318
  }
6354
6319
  }
6320
+ const EVM_CONFIG = {
6321
+ usdtAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
6322
+ gasEstimates: {
6323
+ approve: 65000n,
6324
+ bridge: 300000n
6325
+ },
6326
+ gasBuffer: 1.2,
6327
+ // 20% buffer
6328
+ timeout: 3e5,
6329
+ // 5 minutes (increased for slower networks)
6330
+ requiredConfirmations: 3
6331
+ // Wait for 3 confirmations for reorg protection
6332
+ };
6333
+ const TON_CONFIG = {
6334
+ apiUrl: "https://toncenter.com/api/v2",
6335
+ timeout: 36e4,
6336
+ // 6 minutes
6337
+ validUntil: 600
6338
+ // 10 minutes
6339
+ };
6340
+ const TRON_CONFIG = {
6341
+ timeout: 12e4,
6342
+ // 2 minutes (for 19 confirmations)
6343
+ feeLimit: 1e8,
6344
+ // 100 TRX in sun
6345
+ requiredConfirmations: 19,
6346
+ // TRON standard: 19 blocks for confirmation
6347
+ pollingInterval: 3e3
6348
+ // 3 seconds between checks
6349
+ };
6350
+ let tonClientInstance = null;
6351
+ function getTonClient(customClient, apiKey) {
6352
+ if (customClient) {
6353
+ return customClient;
6354
+ }
6355
+ if (!tonClientInstance) {
6356
+ tonClientInstance = new ton.TonClient({
6357
+ endpoint: `${TON_CONFIG.apiUrl}/jsonRPC`,
6358
+ apiKey
6359
+ });
6360
+ }
6361
+ return tonClientInstance;
6362
+ }
6355
6363
  function isNativeAddress(addr) {
6356
6364
  if (!addr) return false;
6357
6365
  const a = addr.toLowerCase();
@@ -6377,44 +6385,72 @@ function formatUnitsFromBigIntStr(valueStr, decimals) {
6377
6385
  const tail = s.slice(s.length - decimals).replace(/0+$/, "");
6378
6386
  return Number(tail ? `${head}.${tail}` : head);
6379
6387
  }
6380
- async function getEvmBalances(address, tokens) {
6388
+ function isTonFriendlyAddress(address) {
6389
+ return !!address && /^[A-Za-z0-9_-]{48,}$/.test(address);
6390
+ }
6391
+ function normalizeTickerSymbol(symbol) {
6392
+ return symbol.toUpperCase().replace(/₮/g, "T").replace(/[^A-Z0-9]/g, "");
6393
+ }
6394
+ function parseTonAddress(address) {
6395
+ if (address.startsWith("0x")) {
6396
+ const hex = address.slice(2);
6397
+ return ton.Address.parseRaw(`0:${hex}`);
6398
+ }
6399
+ if (address.includes(":")) {
6400
+ return ton.Address.parseRaw(address);
6401
+ }
6402
+ return ton.Address.parse(address);
6403
+ }
6404
+ async function getEvmBalances(publicClient, address, tokens) {
6381
6405
  const balances = {};
6382
6406
  try {
6383
- if (!address || !ethers.ethers.isAddress(address)) {
6407
+ console.log("start getEvmBalances");
6408
+ console.log("publicClient:", publicClient);
6409
+ console.log("isAddress:", viem.isAddress(address));
6410
+ console.log("tokens:", tokens);
6411
+ if (!address || !viem.isAddress(address)) {
6384
6412
  console.warn(`Invalid EVM address provided: ${address}`);
6385
6413
  return balances;
6386
6414
  }
6387
- if (typeof window === "undefined" || !window.ethereum) {
6388
- throw new Error("No ethereum provider found");
6415
+ if (!publicClient) {
6416
+ throw new Error("No public client provided");
6389
6417
  }
6390
- const provider = new ethers.ethers.BrowserProvider(window.ethereum);
6391
6418
  for (const token of tokens) {
6392
6419
  try {
6393
6420
  let balance = 0;
6394
6421
  const isNative = isNativeAddress(token.address);
6395
6422
  if (isNative) {
6396
- const ethBalance = await provider.getBalance(address);
6397
- balance = parseFloat(ethers.ethers.formatUnits(ethBalance, token.decimals));
6423
+ const ethBalance = await publicClient.getBalance({
6424
+ address
6425
+ });
6426
+ balance = parseFloat(viem.formatUnits(ethBalance, token.decimals));
6398
6427
  } else {
6399
- if (!ethers.ethers.isAddress(token.address)) {
6428
+ if (!viem.isAddress(token.address)) {
6400
6429
  continue;
6401
6430
  }
6402
- const code = await provider.getCode(token.address);
6403
- if (code === "0x") {
6431
+ const bytecode = await publicClient.getBytecode({
6432
+ address: token.address
6433
+ });
6434
+ if (!bytecode || bytecode === "0x") {
6404
6435
  continue;
6405
6436
  }
6406
- const contract = new ethers.ethers.Contract(
6407
- token.address,
6408
- [
6409
- "function balanceOf(address owner) view returns (uint256)",
6410
- "function decimals() view returns (uint8)"
6411
- ],
6412
- provider
6413
- );
6414
6437
  try {
6415
- const tokenBalance = await contract.balanceOf(address);
6438
+ const tokenBalance = await publicClient.readContract({
6439
+ address: token.address,
6440
+ abi: [
6441
+ {
6442
+ name: "balanceOf",
6443
+ type: "function",
6444
+ stateMutability: "view",
6445
+ inputs: [{ name: "owner", type: "address" }],
6446
+ outputs: [{ name: "balance", type: "uint256" }]
6447
+ }
6448
+ ],
6449
+ functionName: "balanceOf",
6450
+ args: [address]
6451
+ });
6416
6452
  balance = parseFloat(
6417
- ethers.ethers.formatUnits(tokenBalance, token.decimals)
6453
+ viem.formatUnits(tokenBalance, token.decimals)
6418
6454
  );
6419
6455
  } catch {
6420
6456
  continue;
@@ -6437,6 +6473,68 @@ async function getEvmBalances(address, tokens) {
6437
6473
  }
6438
6474
  return balances;
6439
6475
  }
6476
+ async function getTonBalances(address, tokens, customTonClient, tonApiKey) {
6477
+ const balances = {};
6478
+ try {
6479
+ if (!isTonFriendlyAddress(address)) {
6480
+ console.warn(`Invalid TON address provided: ${address}`);
6481
+ return balances;
6482
+ }
6483
+ const client = getTonClient(customTonClient, tonApiKey);
6484
+ const accountAddress = ton.Address.parse(address);
6485
+ console.log(address);
6486
+ console.log(tokens);
6487
+ try {
6488
+ const balance = await client.getBalance(accountAddress);
6489
+ const tonBalance = Number(balance) / 1e9;
6490
+ console.log("tonBalance", tonBalance);
6491
+ if (tonBalance > 0) {
6492
+ balances.TON = { balance: tonBalance, address: "ton-native" };
6493
+ }
6494
+ } catch (error) {
6495
+ console.warn("Failed to get native TON balance:", error);
6496
+ }
6497
+ for (const token of tokens) {
6498
+ try {
6499
+ if (isNativeAddress(token.address) || token.symbol.toUpperCase() === "TON") {
6500
+ continue;
6501
+ }
6502
+ const jettonMasterAddress = parseTonAddress(token.address);
6503
+ const jettonWalletAddress = await client.runMethod(
6504
+ jettonMasterAddress,
6505
+ "get_wallet_address",
6506
+ [
6507
+ {
6508
+ type: "slice",
6509
+ cell: ton.beginCell().storeAddress(accountAddress).endCell()
6510
+ }
6511
+ ]
6512
+ );
6513
+ const jettonWalletAddr = jettonWalletAddress.stack.readAddress();
6514
+ const jettonData = await client.runMethod(
6515
+ jettonWalletAddr,
6516
+ "get_wallet_data"
6517
+ );
6518
+ const jettonBalance = jettonData.stack.readBigNumber();
6519
+ const humanBalance = Number(jettonBalance) / Math.pow(10, token.decimals);
6520
+ if (humanBalance > 0) {
6521
+ const symbolUpper = token.symbol.toUpperCase();
6522
+ const symbolNorm = normalizeTickerSymbol(symbolUpper);
6523
+ const entry = { balance: humanBalance, address: token.address };
6524
+ balances[symbolUpper] = entry;
6525
+ if (symbolNorm !== symbolUpper) {
6526
+ balances[symbolNorm] = entry;
6527
+ }
6528
+ }
6529
+ } catch (error) {
6530
+ console.debug(`Failed to get balance for ${token.symbol}:`, error);
6531
+ }
6532
+ }
6533
+ } catch (error) {
6534
+ console.error("Failed to get TON balances:", error);
6535
+ }
6536
+ return balances;
6537
+ }
6440
6538
  async function getTronBalances(tronWeb, address, tokens) {
6441
6539
  const balances = {};
6442
6540
  try {
@@ -6480,30 +6578,6 @@ async function getTronBalances(tronWeb, address, tokens) {
6480
6578
  }
6481
6579
  return balances;
6482
6580
  }
6483
- const EVM_CONFIG = {
6484
- usdtAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
6485
- gasEstimates: {
6486
- approve: 65000n,
6487
- bridge: 300000n
6488
- },
6489
- gasBuffer: 1.2,
6490
- // 20% buffer
6491
- timeout: 12e4
6492
- // 2 minutes
6493
- };
6494
- const TON_CONFIG = {
6495
- apiUrl: "https://toncenter.com/api/v2",
6496
- timeout: 36e4,
6497
- // 6 minutes
6498
- validUntil: 600
6499
- // 10 minutes
6500
- };
6501
- const TRON_CONFIG = {
6502
- timeout: 6e4,
6503
- // 1 minute
6504
- feeLimit: 1e8
6505
- // 100 TRX in sun
6506
- };
6507
6581
  const ERC20_ABI = [
6508
6582
  "function approve(address spender, uint256 amount) returns (bool)",
6509
6583
  "function allowance(address owner, address spender) view returns (uint256)",
@@ -6514,7 +6588,9 @@ class EvmChainStrategy {
6514
6588
  constructor(config) {
6515
6589
  __publicField(this, "config");
6516
6590
  __publicField(this, "provider");
6591
+ __publicField(this, "publicClient");
6517
6592
  this.config = config;
6593
+ this.publicClient = config.publicClient;
6518
6594
  if (config.walletClient) {
6519
6595
  this.provider = new ethers.BrowserProvider(config.walletClient.transport);
6520
6596
  }
@@ -6553,7 +6629,11 @@ class EvmChainStrategy {
6553
6629
  return t("wallets.connectEvmWallet");
6554
6630
  }
6555
6631
  async getBalances(address, tokens) {
6556
- return await getEvmBalances(address, tokens);
6632
+ if (!this.publicClient) {
6633
+ console.warn("No publicClient available for balance query");
6634
+ return {};
6635
+ }
6636
+ return await getEvmBalances(this.publicClient, address, tokens);
6557
6637
  }
6558
6638
  isAddressValid(address) {
6559
6639
  if (!address) return false;
@@ -6666,17 +6746,14 @@ class EvmChainStrategy {
6666
6746
  if (!provider) {
6667
6747
  throw new ProviderNotAvailableError("evm");
6668
6748
  }
6669
- const deadline = Date.now() + EVM_CONFIG.timeout;
6670
- let receipt = null;
6671
- while (Date.now() < deadline) {
6672
- try {
6673
- receipt = await provider.getTransactionReceipt(txHash);
6674
- if (receipt) break;
6675
- } catch (e) {
6676
- console.debug("Error fetching receipt:", e);
6677
- }
6678
- await new Promise((r) => setTimeout(r, 2500));
6679
- }
6749
+ console.log(
6750
+ `Waiting for ${EVM_CONFIG.requiredConfirmations} confirmations for tx: ${txHash}`
6751
+ );
6752
+ const receipt = await provider.waitForTransaction(
6753
+ txHash,
6754
+ EVM_CONFIG.requiredConfirmations,
6755
+ EVM_CONFIG.timeout
6756
+ );
6680
6757
  if (!receipt) {
6681
6758
  const error = new TransactionTimeoutError("evm", txHash);
6682
6759
  return {
@@ -6691,11 +6768,35 @@ class EvmChainStrategy {
6691
6768
  error: error.message
6692
6769
  };
6693
6770
  }
6694
- console.log("EVM transaction confirmed on-chain");
6771
+ console.log(
6772
+ `EVM transaction confirmed in block ${receipt.blockNumber} with ${EVM_CONFIG.requiredConfirmations} confirmations`
6773
+ );
6695
6774
  return {
6696
6775
  completed: true
6697
6776
  };
6698
6777
  } catch (error) {
6778
+ if (error && typeof error === "object" && "code" in error && error.code === "TRANSACTION_REPLACED") {
6779
+ console.log(
6780
+ `Transaction was replaced: ${"reason" in error ? String(error.reason) : "unknown"}`
6781
+ );
6782
+ if ("receipt" in error && error.receipt) {
6783
+ const replacementReceipt = error.receipt;
6784
+ if (replacementReceipt.status === 1) {
6785
+ console.log(
6786
+ `Replacement transaction succeeded in block ${replacementReceipt.blockNumber}`
6787
+ );
6788
+ return {
6789
+ completed: true
6790
+ };
6791
+ } else {
6792
+ const chainError2 = new TransactionRevertedError("evm", txHash);
6793
+ return {
6794
+ completed: false,
6795
+ error: chainError2.message
6796
+ };
6797
+ }
6798
+ }
6799
+ }
6699
6800
  const chainError = toChainStrategyError(
6700
6801
  error,
6701
6802
  "evm",
@@ -6809,13 +6910,52 @@ class EvmChainStrategy {
6809
6910
  return false;
6810
6911
  }
6811
6912
  }
6913
+ /**
6914
+ * Check if a block has reached finality status (optional, for critical transactions)
6915
+ * This is more stringent than confirmations and protects against long-range reorgs
6916
+ *
6917
+ * Usage: Call this method after waitForCompletion if you need additional security
6918
+ * for high-value transactions. The method checks if the block has been marked as
6919
+ * "finalized" by the Ethereum consensus layer (2/3 of validators).
6920
+ *
6921
+ * @param blockNumber - The block number to check for finality
6922
+ * @returns true if the block is finalized, false otherwise
6923
+ */
6924
+ async checkFinality(blockNumber) {
6925
+ try {
6926
+ const provider = this.provider;
6927
+ if (!provider) {
6928
+ return false;
6929
+ }
6930
+ const finalizedBlock = await provider.getBlock("finalized");
6931
+ if (!finalizedBlock) {
6932
+ console.debug(
6933
+ "Finalized block not available (pre-merge or unsupported)"
6934
+ );
6935
+ return false;
6936
+ }
6937
+ const isFinalized = blockNumber <= finalizedBlock.number;
6938
+ if (isFinalized) {
6939
+ console.log(
6940
+ `Block ${blockNumber} has reached finality (finalized block: ${finalizedBlock.number})`
6941
+ );
6942
+ } else {
6943
+ console.debug(
6944
+ `Block ${blockNumber} not yet finalized (finalized block: ${finalizedBlock.number})`
6945
+ );
6946
+ }
6947
+ return isFinalized;
6948
+ } catch (error) {
6949
+ console.debug("Error checking finality:", error);
6950
+ return false;
6951
+ }
6952
+ }
6812
6953
  }
6813
6954
  class TonChainStrategy {
6814
6955
  constructor(config) {
6815
6956
  __publicField(this, "config");
6816
6957
  this.config = config;
6817
6958
  }
6818
- // ========== Identity ==========
6819
6959
  canHandle(chainKey) {
6820
6960
  return chainKey.toLowerCase() === "ton";
6821
6961
  }
@@ -6825,7 +6965,6 @@ class TonChainStrategy {
6825
6965
  getName() {
6826
6966
  return "TON Chain Strategy";
6827
6967
  }
6828
- // ========== Wallet Management ==========
6829
6968
  async connect() {
6830
6969
  await this.config.tonConnectUI?.openModal();
6831
6970
  }
@@ -6850,17 +6989,26 @@ class TonChainStrategy {
6850
6989
  getConnectLabel(t) {
6851
6990
  return t("wallets.connectTonWallet");
6852
6991
  }
6853
- // ========== Balance & Validation ==========
6854
- async getBalances(address) {
6855
- return await getSwapBalances(address);
6992
+ async getBalances(address, tokens) {
6993
+ return await getTonBalances(
6994
+ address,
6995
+ tokens,
6996
+ this.config.tonClient,
6997
+ this.config.tonApiKey
6998
+ );
6856
6999
  }
6857
7000
  isAddressValid(address) {
6858
7001
  if (!address) return false;
6859
7002
  return true;
6860
7003
  }
6861
- // ========== Gas Estimation ==========
6862
7004
  async estimateGasRequirement(params) {
6863
- const { selectedToken, nativeTokenSymbol, amount, balances, reserveFallback } = params;
7005
+ const {
7006
+ selectedToken,
7007
+ nativeTokenSymbol,
7008
+ amount,
7009
+ balances,
7010
+ reserveFallback
7011
+ } = params;
6864
7012
  const nativeSym = nativeTokenSymbol.toUpperCase();
6865
7013
  const isNativeSelected = nativeSym === (selectedToken?.symbol ?? "").toUpperCase();
6866
7014
  const nativeBalance = Number(balances[nativeSym]?.balance ?? 0);
@@ -6882,7 +7030,6 @@ class TonChainStrategy {
6882
7030
  isNativeSelected
6883
7031
  };
6884
7032
  }
6885
- // ========== Transaction Execution ==========
6886
7033
  validateSteps(steps) {
6887
7034
  if (!steps || steps.length === 0) {
6888
7035
  throw new InvalidStepsError("ton", "No transaction steps provided");
@@ -6935,19 +7082,17 @@ class TonChainStrategy {
6935
7082
  const result = await this.config.tonConnectUI.sendTransaction(
6936
7083
  transaction
6937
7084
  );
6938
- const hash = this.getTxHash(result.boc);
6939
7085
  return {
6940
7086
  chainKey: "ton",
6941
- hash
7087
+ hash: result.boc
6942
7088
  };
6943
7089
  } catch (error) {
6944
7090
  throw toChainStrategyError(error, "ton", "transaction");
6945
7091
  }
6946
7092
  }
6947
- async waitForCompletion(txHash, context) {
7093
+ async waitForCompletion(txHash) {
6948
7094
  try {
6949
7095
  const confirmed = await this.checkTonTransaction(
6950
- context.srcAddress,
6951
7096
  txHash,
6952
7097
  TON_CONFIG.timeout
6953
7098
  );
@@ -6977,39 +7122,78 @@ class TonChainStrategy {
6977
7122
  };
6978
7123
  }
6979
7124
  }
6980
- // ========== Private Helper Methods ==========
6981
- getTxHash(boc) {
6982
- const cell = core.Cell.fromBase64(boc);
6983
- const buffer = cell.hash();
6984
- return buffer.toString("hex");
7125
+ getNormalizedExtMessageHash(message) {
7126
+ if (message.info.type !== "external-in") {
7127
+ throw new Error(`Expected external-in message, got ${message.info.type}`);
7128
+ }
7129
+ const normalizedInfo = {
7130
+ ...message.info,
7131
+ src: void 0,
7132
+ importFee: 0n
7133
+ };
7134
+ const normalizedMessage = {
7135
+ ...message,
7136
+ info: normalizedInfo,
7137
+ init: null
7138
+ };
7139
+ return core.beginCell().store(core.storeMessage(normalizedMessage, { forceRef: true })).endCell().hash();
6985
7140
  }
6986
- async checkTonTransaction(address, txHash, timeoutMs = 36e4) {
7141
+ async checkTonTransaction(bocBase64, timeoutMs = 36e4) {
6987
7142
  const deadline = Date.now() + timeoutMs;
6988
- const normalizedHash = txHash.toLowerCase();
6989
- while (Date.now() < deadline) {
6990
- try {
6991
- const response = await fetch(
6992
- `${TON_CONFIG.apiUrl}/getTransactions?address=${address}&limit=20`
7143
+ const client = getTonClient(this.config.tonClient, this.config.tonApiKey);
7144
+ try {
7145
+ const inMessage = core.loadMessage(core.Cell.fromBase64(bocBase64).beginParse());
7146
+ if (inMessage.info.type !== "external-in") {
7147
+ console.debug(
7148
+ "Expected external-in message, got:",
7149
+ inMessage.info.type
6993
7150
  );
6994
- if (!response.ok) {
6995
- console.debug("TonCenter API error:", response.status);
6996
- await new Promise((r) => setTimeout(r, 3e3));
6997
- continue;
6998
- }
6999
- const data = await response.json();
7000
- const transactions = data.result || [];
7001
- for (const tx of transactions) {
7002
- const txIdHash = tx.transaction_id?.hash;
7003
- if (txIdHash && txIdHash.toLowerCase() === normalizedHash) {
7004
- return true;
7151
+ return false;
7152
+ }
7153
+ const accountAddress = inMessage.info.dest;
7154
+ const targetMessageHash = this.getNormalizedExtMessageHash(inMessage);
7155
+ let lt = void 0;
7156
+ let hash = void 0;
7157
+ while (Date.now() < deadline) {
7158
+ try {
7159
+ const transactions = await client.getTransactions(accountAddress, {
7160
+ lt,
7161
+ hash,
7162
+ limit: 10,
7163
+ archival: true
7164
+ });
7165
+ if (transactions.length === 0) {
7166
+ await new Promise((r) => setTimeout(r, 3e3));
7167
+ lt = void 0;
7168
+ hash = void 0;
7169
+ continue;
7170
+ }
7171
+ for (const tx of transactions) {
7172
+ if (tx.inMessage?.info.type === "external-in") {
7173
+ const txInMessageHash = this.getNormalizedExtMessageHash(
7174
+ tx.inMessage
7175
+ );
7176
+ if (txInMessageHash.equals(targetMessageHash)) {
7177
+ console.debug("Transaction found by in-message hash");
7178
+ return true;
7179
+ }
7180
+ }
7005
7181
  }
7182
+ const lastTx = transactions[transactions.length - 1];
7183
+ lt = lastTx.lt.toString();
7184
+ hash = lastTx.hash().toString("base64");
7185
+ } catch (error) {
7186
+ console.debug("Error fetching transactions:", error);
7187
+ await new Promise((r) => setTimeout(r, 3e3));
7188
+ lt = void 0;
7189
+ hash = void 0;
7006
7190
  }
7007
- } catch (e) {
7008
- console.debug("TonCenter polling error:", e);
7009
7191
  }
7010
- await new Promise((r) => setTimeout(r, 3e3));
7192
+ return false;
7193
+ } catch (error) {
7194
+ console.debug("Error parsing BOC or checking transaction:", error);
7195
+ return false;
7011
7196
  }
7012
- return false;
7013
7197
  }
7014
7198
  }
7015
7199
  class TronChainStrategy {
@@ -7070,7 +7254,13 @@ class TronChainStrategy {
7070
7254
  }
7071
7255
  // ========== Gas Estimation ==========
7072
7256
  async estimateGasRequirement(params) {
7073
- const { selectedToken, nativeTokenSymbol, amount, balances, reserveFallback } = params;
7257
+ const {
7258
+ selectedToken,
7259
+ nativeTokenSymbol,
7260
+ amount,
7261
+ balances,
7262
+ reserveFallback
7263
+ } = params;
7074
7264
  const nativeSym = nativeTokenSymbol.toUpperCase();
7075
7265
  const isNativeSelected = nativeSym === (selectedToken?.symbol ?? "").toUpperCase();
7076
7266
  const nativeBalance = Number(balances[nativeSym]?.balance ?? 0);
@@ -7092,7 +7282,6 @@ class TronChainStrategy {
7092
7282
  isNativeSelected
7093
7283
  };
7094
7284
  }
7095
- // ========== Transaction Execution ==========
7096
7285
  validateSteps(steps) {
7097
7286
  console.log("validateSteps");
7098
7287
  if (!steps?.length) {
@@ -7127,7 +7316,10 @@ class TronChainStrategy {
7127
7316
  if (String(step.chainKey).toLowerCase() !== "tron") continue;
7128
7317
  const tx = step.transaction;
7129
7318
  if (!tx) {
7130
- throw new InvalidTransactionDataError("tron", "Missing transaction data");
7319
+ throw new InvalidTransactionDataError(
7320
+ "tron",
7321
+ "Missing transaction data"
7322
+ );
7131
7323
  }
7132
7324
  const hexData = typeof tx?.data === "string" ? tx.data : "";
7133
7325
  const parsed = this.parseTronStep(step, tx, hexData);
@@ -7178,13 +7370,19 @@ class TronChainStrategy {
7178
7370
  break;
7179
7371
  }
7180
7372
  default:
7181
- throw new InvalidStepsError("tron", "Unsupported TRON parsed tx kind");
7373
+ throw new InvalidStepsError(
7374
+ "tron",
7375
+ "Unsupported TRON parsed tx kind"
7376
+ );
7182
7377
  }
7183
7378
  const { txid } = await this.signAndBroadcast(tronWeb, unsigned);
7184
7379
  lastTxId = txid;
7185
7380
  }
7186
7381
  if (!lastTxId) {
7187
- throw new TransactionFailedError("tron", "No TRON transaction was executed");
7382
+ throw new TransactionFailedError(
7383
+ "tron",
7384
+ "No TRON transaction was executed"
7385
+ );
7188
7386
  }
7189
7387
  return { hash: lastTxId, chainKey: "tron" };
7190
7388
  }
@@ -7194,47 +7392,84 @@ class TronChainStrategy {
7194
7392
  if (!tronWeb) {
7195
7393
  throw new ProviderNotAvailableError("tron");
7196
7394
  }
7395
+ console.log(
7396
+ `Waiting for ${TRON_CONFIG.requiredConfirmations} confirmations for TRON tx: ${txHash}`
7397
+ );
7197
7398
  const deadline = Date.now() + TRON_CONFIG.timeout;
7198
- while (Date.now() < deadline) {
7399
+ let txBlockNumber = null;
7400
+ while (Date.now() < deadline && !txBlockNumber) {
7199
7401
  try {
7200
7402
  const info = await tronWeb.trx.getTransactionInfo(txHash);
7201
- console.log("TRON transaction info:", info);
7202
- if (info) {
7403
+ if (info && info.blockNumber) {
7203
7404
  const result = info.receipt?.result;
7204
- if (result === "SUCCESS") {
7205
- console.log("TRON transaction confirmed on-chain");
7405
+ if (result !== "SUCCESS") {
7406
+ const msg = this.hexToAscii(info.resMessage) || null;
7407
+ let reason = msg;
7408
+ const cr = info.contractResult?.[0];
7409
+ if (cr && /^0x?08c379a0/i.test(cr)) {
7410
+ try {
7411
+ const clean = cr.replace(/^0x/, "");
7412
+ const len = parseInt(clean.slice(8 + 64, 8 + 64 + 64), 16);
7413
+ const strHex = clean.slice(
7414
+ 8 + 64 + 64,
7415
+ 8 + 64 + 64 + len * 2
7416
+ );
7417
+ const str = this.hexToAscii("0x" + strHex);
7418
+ if (str) reason = str;
7419
+ } catch (e) {
7420
+ console.debug("TRON revert string decode error", e);
7421
+ }
7422
+ }
7423
+ const error2 = new TransactionRevertedError(
7424
+ "tron",
7425
+ txHash,
7426
+ reason || "Unknown error"
7427
+ );
7206
7428
  return {
7207
- completed: true
7429
+ completed: false,
7430
+ error: error2.message
7208
7431
  };
7209
7432
  }
7210
- const msg = this.hexToAscii(info.resMessage) || null;
7211
- let reason = msg;
7212
- const cr = info.contractResult?.[0];
7213
- if (cr && /^0x?08c379a0/i.test(cr)) {
7214
- try {
7215
- const clean = cr.replace(/^0x/, "");
7216
- const len = parseInt(clean.slice(8 + 64, 8 + 64 + 64), 16);
7217
- const strHex = clean.slice(8 + 64 + 64, 8 + 64 + 64 + len * 2);
7218
- const str = this.hexToAscii("0x" + strHex);
7219
- if (str) reason = str;
7220
- } catch (e) {
7221
- console.debug("TRON revert string decode error", e);
7222
- }
7433
+ txBlockNumber = info.blockNumber;
7434
+ console.log(`TRON transaction found in block ${txBlockNumber}`);
7435
+ }
7436
+ } catch (e) {
7437
+ console.debug("TRON getTransactionInfo error:", e);
7438
+ }
7439
+ if (!txBlockNumber) {
7440
+ await new Promise((r) => setTimeout(r, TRON_CONFIG.pollingInterval));
7441
+ }
7442
+ }
7443
+ if (!txBlockNumber) {
7444
+ const error2 = new TransactionTimeoutError("tron", txHash);
7445
+ return {
7446
+ completed: false,
7447
+ error: error2.message
7448
+ };
7449
+ }
7450
+ let confirmations = 0;
7451
+ while (Date.now() < deadline) {
7452
+ try {
7453
+ const currentBlock = await tronWeb.trx.getCurrentBlock();
7454
+ const currentBlockNumber = currentBlock?.block_header?.raw_data?.number;
7455
+ if (currentBlockNumber) {
7456
+ confirmations = currentBlockNumber - txBlockNumber;
7457
+ if (confirmations >= TRON_CONFIG.requiredConfirmations) {
7458
+ console.log(
7459
+ `TRON transaction confirmed in block ${txBlockNumber} with ${confirmations} confirmations`
7460
+ );
7461
+ return {
7462
+ completed: true
7463
+ };
7223
7464
  }
7224
- const error2 = new TransactionRevertedError(
7225
- "tron",
7226
- txHash,
7227
- reason || "Unknown error"
7465
+ console.log(
7466
+ `TRON transaction confirmations: ${confirmations}/${TRON_CONFIG.requiredConfirmations}`
7228
7467
  );
7229
- return {
7230
- completed: false,
7231
- error: error2.message
7232
- };
7233
7468
  }
7234
7469
  } catch (e) {
7235
- console.debug("TRON getTransactionInfo error:", e);
7470
+ console.debug("TRON getCurrentBlock error:", e);
7236
7471
  }
7237
- await new Promise((r) => setTimeout(r, 3e3));
7472
+ await new Promise((r) => setTimeout(r, TRON_CONFIG.pollingInterval));
7238
7473
  }
7239
7474
  const error = new TransactionTimeoutError("tron", txHash);
7240
7475
  return {
@@ -7242,14 +7477,17 @@ class TronChainStrategy {
7242
7477
  error: error.message
7243
7478
  };
7244
7479
  } catch (error) {
7245
- const chainError = toChainStrategyError(error, "tron", "waitForCompletion");
7480
+ const chainError = toChainStrategyError(
7481
+ error,
7482
+ "tron",
7483
+ "waitForCompletion"
7484
+ );
7246
7485
  return {
7247
7486
  completed: false,
7248
7487
  error: chainError.message
7249
7488
  };
7250
7489
  }
7251
7490
  }
7252
- // ========== Private Helper Methods ==========
7253
7491
  getTronWeb() {
7254
7492
  return typeof window !== "undefined" ? window.tronWeb : void 0;
7255
7493
  }
@@ -7302,7 +7540,10 @@ class TronChainStrategy {
7302
7540
  amount: this.extractAmountFromTxData(tx.data)
7303
7541
  };
7304
7542
  }
7305
- throw new InvalidTransactionDataError("tron", "Cannot parse approve transaction");
7543
+ throw new InvalidTransactionDataError(
7544
+ "tron",
7545
+ "Cannot parse approve transaction"
7546
+ );
7306
7547
  }
7307
7548
  if (step?.type === "transfer" || step?.type === "bridge") {
7308
7549
  const s = step;
@@ -7332,7 +7573,10 @@ class TronChainStrategy {
7332
7573
  feeLimit: raw2.feeLimit
7333
7574
  };
7334
7575
  }
7335
- throw new InvalidTransactionDataError("tron", "Cannot parse transfer/bridge transaction");
7576
+ throw new InvalidTransactionDataError(
7577
+ "tron",
7578
+ "Cannot parse transfer/bridge transaction"
7579
+ );
7336
7580
  }
7337
7581
  if (tx?.to && tx?.value && !tx?.data) {
7338
7582
  const v = BigInt(tx.value.toString());
@@ -7352,19 +7596,28 @@ class TronChainStrategy {
7352
7596
  feeLimit: raw.feeLimit
7353
7597
  };
7354
7598
  }
7355
- throw new InvalidTransactionDataError("tron", `Unsupported TRON step type: ${step?.type ?? "unknown"}`);
7599
+ throw new InvalidTransactionDataError(
7600
+ "tron",
7601
+ `Unsupported TRON step type: ${step?.type ?? "unknown"}`
7602
+ );
7356
7603
  }
7357
7604
  extractSpenderFromTxData(data) {
7358
7605
  const clean = data.replace(/^0x/, "");
7359
7606
  if (clean.length < 74) {
7360
- throw new InvalidTransactionDataError("tron", "Invalid transaction data length");
7607
+ throw new InvalidTransactionDataError(
7608
+ "tron",
7609
+ "Invalid transaction data length"
7610
+ );
7361
7611
  }
7362
7612
  return "41" + clean.slice(32, 72);
7363
7613
  }
7364
7614
  extractAmountFromTxData(data) {
7365
7615
  const clean = data.replace(/^0x/, "");
7366
7616
  if (clean.length < 138) {
7367
- throw new InvalidTransactionDataError("tron", "Invalid transaction data length");
7617
+ throw new InvalidTransactionDataError(
7618
+ "tron",
7619
+ "Invalid transaction data length"
7620
+ );
7368
7621
  }
7369
7622
  const amountHex = clean.slice(72, 136);
7370
7623
  return BigInt("0x" + amountHex).toString();
@@ -7372,7 +7625,10 @@ class TronChainStrategy {
7372
7625
  extractRecipientFromTxData(data) {
7373
7626
  const clean = data.replace(/^0x/, "");
7374
7627
  if (clean.length < 74) {
7375
- throw new InvalidTransactionDataError("tron", "Invalid transaction data length");
7628
+ throw new InvalidTransactionDataError(
7629
+ "tron",
7630
+ "Invalid transaction data length"
7631
+ );
7376
7632
  }
7377
7633
  return "41" + clean.slice(32, 72);
7378
7634
  }
@@ -7447,7 +7703,6 @@ class TronChainStrategy {
7447
7703
  return null;
7448
7704
  }
7449
7705
  }
7450
- // ========== Transaction Builders ==========
7451
7706
  async buildApprove(tronWeb, p) {
7452
7707
  const res = await tronWeb.transactionBuilder.triggerSmartContract(
7453
7708
  p.token,
@@ -7460,7 +7715,10 @@ class TronChainStrategy {
7460
7715
  p.from
7461
7716
  );
7462
7717
  if (!res?.transaction) {
7463
- throw new TransactionFailedError("tron", "Failed to build approve transaction");
7718
+ throw new TransactionFailedError(
7719
+ "tron",
7720
+ "Failed to build approve transaction"
7721
+ );
7464
7722
  }
7465
7723
  return res.transaction;
7466
7724
  }
@@ -7476,7 +7734,10 @@ class TronChainStrategy {
7476
7734
  p.from
7477
7735
  );
7478
7736
  if (!res?.transaction) {
7479
- throw new TransactionFailedError("tron", "Failed to build transfer transaction");
7737
+ throw new TransactionFailedError(
7738
+ "tron",
7739
+ "Failed to build transfer transaction"
7740
+ );
7480
7741
  }
7481
7742
  return res.transaction;
7482
7743
  }
@@ -7496,12 +7757,13 @@ class TronChainStrategy {
7496
7757
  p.from
7497
7758
  );
7498
7759
  if (!res?.transaction) {
7499
- throw new TransactionFailedError("tron", "Failed to build raw call transaction");
7760
+ throw new TransactionFailedError(
7761
+ "tron",
7762
+ "Failed to build raw call transaction"
7763
+ );
7500
7764
  }
7501
7765
  return res.transaction;
7502
7766
  }
7503
- // ========== Transaction Sender ==========
7504
- /* eslint-disable @typescript-eslint/no-explicit-any */
7505
7767
  async signAndBroadcast(tronWeb, unsignedTx) {
7506
7768
  const signed = await tronWeb.trx.sign(unsignedTx);
7507
7769
  const sent = await tronWeb.trx.sendRawTransaction(signed);
@@ -7513,33 +7775,77 @@ class TronChainStrategy {
7513
7775
  }
7514
7776
  return { txid: sent.txid };
7515
7777
  }
7778
+ /**
7779
+ * Check if a transaction has been solidified (confirmed by solidityNode)
7780
+ * This is an additional check for critical transactions to ensure they are
7781
+ * truly confirmed and available through the solidityNode API.
7782
+ *
7783
+ * Usage: Call this method after waitForCompletion for high-value transactions
7784
+ * to get additional assurance that the transaction is solidified.
7785
+ *
7786
+ * @param txHash - Transaction hash to check
7787
+ * @returns true if the transaction is solidified, false otherwise
7788
+ */
7789
+ async checkSolidified(txHash) {
7790
+ try {
7791
+ const tronWeb = this.getTronWeb();
7792
+ if (!tronWeb) {
7793
+ return false;
7794
+ }
7795
+ const info = await tronWeb.trx.getTransactionInfo(txHash);
7796
+ if (!info || !info.blockNumber) {
7797
+ console.debug(
7798
+ "Transaction not yet solidified (no blockNumber in info)"
7799
+ );
7800
+ return false;
7801
+ }
7802
+ const result = info.receipt?.result;
7803
+ if (result === "SUCCESS") {
7804
+ console.log(
7805
+ `Transaction ${txHash} is solidified in block ${info.blockNumber}`
7806
+ );
7807
+ return true;
7808
+ }
7809
+ console.debug(`Transaction solidified but result is: ${result}`);
7810
+ return false;
7811
+ } catch (error) {
7812
+ console.debug("Error checking solidified status:", error);
7813
+ return false;
7814
+ }
7815
+ }
7516
7816
  }
7517
7817
  function ChainStrategyProvider({
7518
7818
  children,
7519
7819
  evmWallet,
7520
7820
  tonWallet,
7521
- tronWallet
7821
+ tronWallet,
7822
+ tonClient,
7823
+ tonApiKey
7522
7824
  }) {
7523
7825
  const evmStrategy = require$$0.useMemo(
7524
7826
  () => new EvmChainStrategy({
7525
7827
  evmAddress: evmWallet.address,
7526
7828
  evmIsConnected: evmWallet.isConnected,
7527
7829
  evmDisconnect: evmWallet.disconnect,
7528
- walletClient: evmWallet.walletClient
7830
+ walletClient: evmWallet.walletClient,
7831
+ publicClient: evmWallet.publicClient
7529
7832
  }),
7530
7833
  [
7531
7834
  evmWallet.address,
7532
7835
  evmWallet.isConnected,
7533
7836
  evmWallet.disconnect,
7534
- evmWallet.walletClient
7837
+ evmWallet.walletClient,
7838
+ evmWallet.publicClient
7535
7839
  ]
7536
7840
  );
7537
7841
  const tonStrategy = require$$0.useMemo(
7538
7842
  () => new TonChainStrategy({
7539
7843
  tonConnectUI: tonWallet.tonConnectUI,
7540
- tonAddress: tonWallet.address
7844
+ tonAddress: tonWallet.address,
7845
+ tonClient,
7846
+ tonApiKey
7541
7847
  }),
7542
- [tonWallet.tonConnectUI, tonWallet.address]
7848
+ [tonWallet.tonConnectUI, tonWallet.address, tonClient, tonApiKey]
7543
7849
  );
7544
7850
  const tronStrategy = require$$0.useMemo(
7545
7851
  () => new TronChainStrategy({
@@ -7575,6 +7881,7 @@ const EvaaBridgeWithProviders = (props) => {
7575
7881
  const { address: evmAddress, isConnected: evmIsConnected } = wagmi.useAccount();
7576
7882
  const { disconnect: evmDisconnect } = wagmi.useDisconnect();
7577
7883
  const { data: walletClient } = wagmi.useWalletClient();
7884
+ const publicClient = wagmi.usePublicClient();
7578
7885
  const {
7579
7886
  address: tronAddress,
7580
7887
  connected: tronConnected,
@@ -7599,7 +7906,8 @@ const EvaaBridgeWithProviders = (props) => {
7599
7906
  address: evmAddress,
7600
7907
  isConnected: evmIsConnected,
7601
7908
  disconnect: evmDisconnect,
7602
- walletClient
7909
+ walletClient,
7910
+ publicClient
7603
7911
  },
7604
7912
  tonWallet: {
7605
7913
  tonConnectUI,
@@ -7612,6 +7920,8 @@ const EvaaBridgeWithProviders = (props) => {
7612
7920
  connect: tronConnect,
7613
7921
  disconnect: tronDisconnect
7614
7922
  },
7923
+ tonClient: props.tonClient,
7924
+ tonApiKey: props.tonApiKey,
7615
7925
  children: /* @__PURE__ */ jsxRuntime.jsx(EvaaBridgeContent, { ...props })
7616
7926
  }
7617
7927
  );
@@ -7716,16 +8026,16 @@ const EvaaBridgeContent = ({
7716
8026
  }, [chains, assetMatrix, allowedFromChains]);
7717
8027
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7718
8028
  /* @__PURE__ */ jsxRuntime.jsxs(
7719
- "section",
8029
+ Card,
7720
8030
  {
7721
8031
  className: cn(
7722
- "p-5 bg-card max-w-md w-full rounded-3xl mx-auto flex flex-col gap-4 relative",
8032
+ "max-w-md w-full mx-auto flex flex-col relative",
7723
8033
  className
7724
8034
  ),
7725
8035
  ref: modalContainerRef,
7726
8036
  children: [
7727
8037
  /* @__PURE__ */ jsxRuntime.jsx(FormHeader, { modalContainer: modalContainerRef.current }),
7728
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-[1px]", children: [
8038
+ /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-[1px]", children: [
7729
8039
  /* @__PURE__ */ jsxRuntime.jsx(
7730
8040
  SwapSection,
7731
8041
  {
@@ -7763,10 +8073,10 @@ const EvaaBridgeContent = ({
7763
8073
  enabled: sendToAnother,
7764
8074
  onToggle: () => setSendToAnother((v) => !v)
7765
8075
  }
7766
- )
8076
+ ),
8077
+ /* @__PURE__ */ jsxRuntime.jsx(SubmitButton, {})
7767
8078
  ] }),
7768
- /* @__PURE__ */ jsxRuntime.jsx(SubmitButton, {}),
7769
- /* @__PURE__ */ jsxRuntime.jsx(ReceiveRow, {})
8079
+ /* @__PURE__ */ jsxRuntime.jsx(CardFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(ReceiveRow, {}) })
7770
8080
  ]
7771
8081
  }
7772
8082
  ),
@@ -7854,8 +8164,8 @@ exports.getQuoteAmounts = getQuoteAmounts;
7854
8164
  exports.getQuoteDetails = getQuoteDetails;
7855
8165
  exports.getQuoteFees = getQuoteFees;
7856
8166
  exports.getQuotesByPriority = getQuotesByPriority;
7857
- exports.getSwapBalances = getSwapBalances;
7858
8167
  exports.getTokens = getTokens;
8168
+ exports.getTonBalances = getTonBalances;
7859
8169
  exports.getTronBalances = getTronBalances;
7860
8170
  exports.isAddressValidForChain = isAddressValidForChain;
7861
8171
  exports.isEvmAddress = isEvmAddress;
@@ -7864,7 +8174,7 @@ exports.isTronAddress = isTronAddress;
7864
8174
  exports.isZeroAddr = isZeroAddr;
7865
8175
  exports.listAssetsForSelect = listAssetsForSelect;
7866
8176
  exports.lookupTokenMeta = lookupTokenMeta;
7867
- exports.normalizeTickerSymbol = normalizeTickerSymbol;
8177
+ exports.normalizeTickerSymbol = normalizeTickerSymbol$1;
7868
8178
  exports.pollUntilDelivered = pollUntilDelivered;
7869
8179
  exports.resolveTokenOnChain = resolveTokenOnChain;
7870
8180
  exports.resolveTokenOnChainFromMatrix = resolveTokenOnChainFromMatrix$2;