@rash2x/bridge-widget 0.1.13 → 0.1.15
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/dist/evaa-bridge.cjs +446 -542
- package/dist/evaa-bridge.cjs.map +1 -1
- package/dist/evaa-bridge.mjs +447 -543
- package/dist/evaa-bridge.mjs.map +1 -1
- package/dist/index.d.ts +2 -10
- package/package.json +1 -1
package/dist/evaa-bridge.cjs
CHANGED
|
@@ -31,16 +31,16 @@ const i18n = require("i18next");
|
|
|
31
31
|
const zustand = require("zustand");
|
|
32
32
|
const button = require("@/components/ui/button");
|
|
33
33
|
const dialog = require("@/components/ui/dialog");
|
|
34
|
+
const badge = require("@/components/ui/badge");
|
|
34
35
|
const tooltip = require("@/components/ui/tooltip");
|
|
35
36
|
const utils = require("@/lib/utils");
|
|
36
|
-
const
|
|
37
|
+
const skeleton = require("@/components/ui/skeleton");
|
|
37
38
|
const wagmi = require("wagmi");
|
|
38
39
|
const tronwalletAdapterReactHooks = require("@tronweb3/tronwallet-adapter-react-hooks");
|
|
39
40
|
const uiReact = require("@tonconnect/ui-react");
|
|
40
41
|
const reactQuery = require("@tanstack/react-query");
|
|
41
42
|
const core = require("@ton/core");
|
|
42
|
-
const
|
|
43
|
-
const skeleton = require("@/components/ui/skeleton");
|
|
43
|
+
const input = require("@/components/ui/input");
|
|
44
44
|
const card = require("@/components/ui/card");
|
|
45
45
|
const _switch = require("@/components/ui/switch");
|
|
46
46
|
const lucideReact = require("lucide-react");
|
|
@@ -53,7 +53,7 @@ const ton = require("@ton/ton");
|
|
|
53
53
|
const tronwalletAdapters = require("@tronweb3/tronwallet-adapters");
|
|
54
54
|
const common$1 = { "connecting": "Connecting…", "initializing": "Initializing...", "loading": "Loading...", "paste": "paste", "close": "Close", "zeroPlaceholder": "0", "nativeToken": "Native Token" };
|
|
55
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", "
|
|
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
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
58
|
const app$1 = { "stargateWidgetName": "Stargate Bridge Widget", "liveWidget": "Live Widget", "getStarted": "Get Started" };
|
|
59
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" } };
|
|
@@ -67,7 +67,7 @@ const en = {
|
|
|
67
67
|
};
|
|
68
68
|
const common = { "connecting": "Подключение…", "initializing": "Инициализация...", "loading": "Загрузка...", "paste": "вставить", "close": "Закрыть", "zeroPlaceholder": "0", "nativeToken": "Нативный токен" };
|
|
69
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": "Вы получите", "
|
|
70
|
+
const bridge = { "sourceNetwork": "Исходная сеть", "destinationNetwork": "Целевая сеть", "selectToken": "Выбрать токен", "selectNetwork": "Выбрать сеть", "searchToken": "Поиск токена", "searchDestinationChain": "Поиск целевой сети", "myTokens": "Мои токены", "allTokens": "Все токены", "willChangeSourceChain": "Сменит исходную сеть", "noBalancesFound": "Балансы не найдены.", "noResults": "Нет результатов", "sendToAnotherAddress": "Отправить на другой адрес", "youWillReceive": "Вы получите", "anotherAddressPlaceholder": "Адрес", "addressDoesntMatch": "Адрес не соответствует сети {{network}}", "checkBeforeTransfer": "Проверьте корректность перед переводом" };
|
|
71
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
72
|
const app = { "stargateWidgetName": "Виджет Stargate Bridge", "liveWidget": "Живой виджет", "getStarted": "Начало работы" };
|
|
73
73
|
const settings = { "title": "Настройки", "gasOnDestination": "Газ на назначении", "slippageTolerance": "Толерантность к проскальзыванию", "routePriority": "Приоритет маршрута", "highSlippageWarning": "Высокое проскальзывание", "gasPresets": { "auto": "Авто", "none": "Нет", "medium": "Средний", "max": "Макс" }, "routePresets": { "fastest": "Быстрейший", "cheapest": "Дешевейший", "recommended": "Рекомендуемый" } };
|
|
@@ -926,16 +926,16 @@ const SettingModal = ({ isOpen, onClose }) => {
|
|
|
926
926
|
toChain?.chainKey,
|
|
927
927
|
dstNativeToken?.decimals || 18
|
|
928
928
|
);
|
|
929
|
-
const activeBtn = "bg-
|
|
930
|
-
const notActiveBtn = "bg-
|
|
929
|
+
const activeBtn = "bg-primary hover:bg-primary/80 text-primary-foreground transition-colors";
|
|
930
|
+
const notActiveBtn = "bg-accent hover:bg-accent/80 text-accent-foreground transition-colors";
|
|
931
931
|
return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { children: [
|
|
932
|
-
/* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("settings.title"
|
|
932
|
+
/* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("settings.title") }) }),
|
|
933
933
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-5", children: [
|
|
934
934
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5", children: [
|
|
935
935
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [
|
|
936
936
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
937
937
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm font-medium leading-3.5", children: t("settings.gasOnDestination") }),
|
|
938
|
-
/* @__PURE__ */ jsxRuntime.jsx(Tip, { text: t("settings.
|
|
938
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tip, { text: t("settings.gasOnDestinationTip"), children: /* @__PURE__ */ jsxRuntime.jsx(TipIcon, { className: "size-4 text-muted-foreground" }) })
|
|
939
939
|
] }),
|
|
940
940
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground text-sm font-medium leading-3.5", children: formatUsd(gasUsdValue) })
|
|
941
941
|
] }),
|
|
@@ -954,12 +954,11 @@ const SettingModal = ({ isOpen, onClose }) => {
|
|
|
954
954
|
) }) })
|
|
955
955
|
] }),
|
|
956
956
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5", children: gasPresets.map((g) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
957
|
-
|
|
957
|
+
badge.Badge,
|
|
958
958
|
{
|
|
959
|
-
type: "button",
|
|
960
959
|
onClick: () => setGasPreset(g),
|
|
961
960
|
className: utils.cn(
|
|
962
|
-
|
|
961
|
+
"cursor-pointer",
|
|
963
962
|
gasPreset === g ? activeBtn : notActiveBtn
|
|
964
963
|
),
|
|
965
964
|
children: t(`settings.gasPresets.${g}`)
|
|
@@ -975,22 +974,21 @@ const SettingModal = ({ isOpen, onClose }) => {
|
|
|
975
974
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm font-medium leading-3.5", children: t("settings.slippageTolerance") }),
|
|
976
975
|
/* @__PURE__ */ jsxRuntime.jsx(Tip, { text: t("settings.slippageTolerance"), children: /* @__PURE__ */ jsxRuntime.jsx(TipIcon, { className: "size-4 text-muted-foreground" }) })
|
|
977
976
|
] }),
|
|
978
|
-
slippageBps >= 500 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-
|
|
977
|
+
slippageBps >= 500 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-destructive text-xs font-medium", children: t("settings.highSlippageWarning", {
|
|
979
978
|
defaultValue: "High slippage warning"
|
|
980
979
|
}) })
|
|
981
980
|
] }),
|
|
982
981
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-6", children: [
|
|
983
982
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg text-foreground leading-4.5 font-semibold h-4.5", children: slippagePercent }) }),
|
|
984
983
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: slippagePresets.map((p) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
985
|
-
|
|
984
|
+
badge.Badge,
|
|
986
985
|
{
|
|
987
|
-
type: "button",
|
|
988
986
|
onClick: () => {
|
|
989
987
|
const bps = parseFloat(p.replace("%", "")) * 100;
|
|
990
988
|
setSlippageBps(bps);
|
|
991
989
|
},
|
|
992
990
|
className: utils.cn(
|
|
993
|
-
|
|
991
|
+
"cursor-pointer",
|
|
994
992
|
activeSlippagePreset === p ? activeBtn : notActiveBtn
|
|
995
993
|
),
|
|
996
994
|
children: p
|
|
@@ -1006,12 +1004,11 @@ const SettingModal = ({ isOpen, onClose }) => {
|
|
|
1006
1004
|
/* @__PURE__ */ jsxRuntime.jsx(Tip, { text: t("settings.routePriority"), children: /* @__PURE__ */ jsxRuntime.jsx(TipIcon, { className: "size-4 text-muted-foreground" }) })
|
|
1007
1005
|
] }) }),
|
|
1008
1006
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end gap-2", children: routePresets.map((r) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1009
|
-
|
|
1007
|
+
badge.Badge,
|
|
1010
1008
|
{
|
|
1011
|
-
type: "button",
|
|
1012
1009
|
onClick: () => setRoutePriority(r),
|
|
1013
1010
|
className: utils.cn(
|
|
1014
|
-
|
|
1011
|
+
"cursor-pointer",
|
|
1015
1012
|
routePriority === r ? activeBtn : notActiveBtn
|
|
1016
1013
|
),
|
|
1017
1014
|
children: t(`settings.routePresets.${r}`)
|
|
@@ -1079,168 +1076,31 @@ function useChainStrategies() {
|
|
|
1079
1076
|
}
|
|
1080
1077
|
return context;
|
|
1081
1078
|
}
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
if (
|
|
1090
|
-
const base = BigInt(10) ** BigInt(decimals);
|
|
1091
|
-
const int = bi / base;
|
|
1092
|
-
const frac = Number(bi % base) / Number(base);
|
|
1093
|
-
return Number(int) + frac;
|
|
1094
|
-
}
|
|
1095
|
-
function resolveTokenOnChainFromMatrix$2(assetMatrix, assetSymbol, chainKey) {
|
|
1096
|
-
if (!assetMatrix || !assetSymbol || !chainKey) return void 0;
|
|
1097
|
-
const byChain = assetMatrix[assetSymbol.toUpperCase()];
|
|
1098
|
-
return byChain?.[chainKey];
|
|
1099
|
-
}
|
|
1100
|
-
const DEFAULT_SLIPPAGE_BPS = 50;
|
|
1101
|
-
const lower = (s) => (s ?? "").toLowerCase();
|
|
1102
|
-
const normSym = (s) => (s ?? "").toUpperCase().replace(/₮/g, "T").replace(/[^A-Z0-9]/g, "");
|
|
1103
|
-
function tonNorm(addr) {
|
|
1104
|
-
if (!addr) return null;
|
|
1079
|
+
const isEvmAddress = (addr) => {
|
|
1080
|
+
return /^0x[0-9a-fA-F]{40}$/.test(addr ?? "");
|
|
1081
|
+
};
|
|
1082
|
+
const isTronAddress = (addr) => {
|
|
1083
|
+
return /^T[1-9A-HJ-NP-Za-km-z]{33}$/.test(addr ?? "");
|
|
1084
|
+
};
|
|
1085
|
+
const isTonAddress = (addr) => {
|
|
1086
|
+
if (!addr) return false;
|
|
1105
1087
|
try {
|
|
1106
1088
|
if (addr.includes(":")) {
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
urlSafe: true
|
|
1110
|
-
});
|
|
1089
|
+
core.Address.parseRaw(addr);
|
|
1090
|
+
return true;
|
|
1111
1091
|
}
|
|
1112
|
-
|
|
1092
|
+
core.Address.parse(addr);
|
|
1093
|
+
return true;
|
|
1113
1094
|
} catch {
|
|
1114
|
-
return
|
|
1095
|
+
return false;
|
|
1115
1096
|
}
|
|
1116
|
-
}
|
|
1117
|
-
const isEvmAddress = (a) => /^0x[0-9a-fA-F]{40}$/.test(a ?? "");
|
|
1118
|
-
const isTronAddress = (a) => /^T[1-9A-HJ-NP-Za-km-z]{33}$/.test(a ?? "");
|
|
1119
|
-
const isZeroAddr = (a) => (
|
|
1120
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1121
|
-
!!a && /^0x0{40}$/i.test(a) || /^0x[eE]{4}e{36}$/i.test(a)
|
|
1122
|
-
);
|
|
1097
|
+
};
|
|
1123
1098
|
function isAddressValidForChain(chainKey, addr) {
|
|
1124
1099
|
if (!chainKey || !addr) return false;
|
|
1125
|
-
if (chainKey === "ton") return
|
|
1100
|
+
if (chainKey === "ton") return isTonAddress(addr);
|
|
1126
1101
|
if (chainKey === "tron") return isTronAddress(addr);
|
|
1127
1102
|
return isEvmAddress(addr);
|
|
1128
1103
|
}
|
|
1129
|
-
function addrForApi(chainKey, addr) {
|
|
1130
|
-
if (chainKey === "ton") return tonNorm(addr);
|
|
1131
|
-
return addr;
|
|
1132
|
-
}
|
|
1133
|
-
function isNativeAddrEqual(chain, tokenAddr) {
|
|
1134
|
-
if (!chain) return false;
|
|
1135
|
-
if (!tokenAddr) return false;
|
|
1136
|
-
if (isZeroAddr(tokenAddr)) return true;
|
|
1137
|
-
const nativeAddr = chain.nativeCurrency?.address;
|
|
1138
|
-
if (!nativeAddr) return false;
|
|
1139
|
-
if (chain.chainKey === "ton") {
|
|
1140
|
-
const a = tonNorm(tokenAddr);
|
|
1141
|
-
const b = tonNorm(nativeAddr);
|
|
1142
|
-
return !!a && !!b && a === b;
|
|
1143
|
-
}
|
|
1144
|
-
return lower(nativeAddr) === lower(tokenAddr);
|
|
1145
|
-
}
|
|
1146
|
-
function findNativeMeta(tokens, chain) {
|
|
1147
|
-
if (!chain) return { decimals: 18, priceUsd: void 0 };
|
|
1148
|
-
const sym = normSym(chain.nativeCurrency?.symbol);
|
|
1149
|
-
if (!sym) {
|
|
1150
|
-
return { decimals: chain.chainKey === "ton" ? 9 : 18, priceUsd: void 0 };
|
|
1151
|
-
}
|
|
1152
|
-
const sameChain = tokens?.find(
|
|
1153
|
-
(t) => t.chainKey === chain.chainKey && normSym(t.symbol) === sym
|
|
1154
|
-
) ?? void 0;
|
|
1155
|
-
if (sameChain)
|
|
1156
|
-
return { decimals: sameChain.decimals, priceUsd: sameChain.price?.usd };
|
|
1157
|
-
const anyChain = tokens?.find((t) => normSym(t.symbol) === sym);
|
|
1158
|
-
if (anyChain)
|
|
1159
|
-
return { decimals: anyChain.decimals, priceUsd: anyChain.price?.usd };
|
|
1160
|
-
return { decimals: chain.chainKey === "ton" ? 9 : 18, priceUsd: void 0 };
|
|
1161
|
-
}
|
|
1162
|
-
function lookupTokenMeta(tokens, chains, chainKey, tokenAddr) {
|
|
1163
|
-
if (!chainKey) return { decimals: 18, priceUsd: void 0 };
|
|
1164
|
-
const chain = chains?.find((c) => c.chainKey === chainKey);
|
|
1165
|
-
const hit = tokens?.find((t) => {
|
|
1166
|
-
if (t.chainKey !== chainKey) return false;
|
|
1167
|
-
if (chainKey === "ton") {
|
|
1168
|
-
const a = tonNorm(t.address);
|
|
1169
|
-
const b = tonNorm(tokenAddr);
|
|
1170
|
-
return !!a && !!b && a === b;
|
|
1171
|
-
}
|
|
1172
|
-
return lower(t.address) === lower(tokenAddr);
|
|
1173
|
-
}) ?? void 0;
|
|
1174
|
-
if (hit) return { decimals: hit.decimals, priceUsd: hit.price?.usd };
|
|
1175
|
-
if (isNativeAddrEqual(chain, tokenAddr)) {
|
|
1176
|
-
return findNativeMeta(tokens, chain);
|
|
1177
|
-
}
|
|
1178
|
-
return { decimals: chainKey === "ton" ? 9 : 18, priceUsd: void 0 };
|
|
1179
|
-
}
|
|
1180
|
-
function computeFeesUsdFromArray(fees, tokens, chains) {
|
|
1181
|
-
if (!fees?.length) return { totalUsd: 0 };
|
|
1182
|
-
let total = 0;
|
|
1183
|
-
let protocolFeeUsd = 0;
|
|
1184
|
-
let messageFeeUsd = 0;
|
|
1185
|
-
const byType = /* @__PURE__ */ new Map();
|
|
1186
|
-
for (const f of fees) {
|
|
1187
|
-
let usd = Number(f.usd ?? 0);
|
|
1188
|
-
if (!usd) {
|
|
1189
|
-
const { decimals, priceUsd } = lookupTokenMeta(
|
|
1190
|
-
tokens,
|
|
1191
|
-
chains,
|
|
1192
|
-
f.chainKey,
|
|
1193
|
-
f.token
|
|
1194
|
-
);
|
|
1195
|
-
const human = fromLD(String(f.amount ?? "0"), decimals);
|
|
1196
|
-
usd = (priceUsd ?? 0) * human;
|
|
1197
|
-
}
|
|
1198
|
-
total += usd;
|
|
1199
|
-
const type = (f.type ?? "other").toLowerCase();
|
|
1200
|
-
byType.set(type, (byType.get(type) ?? 0) + usd);
|
|
1201
|
-
if (type === "protocol" || type === "service") {
|
|
1202
|
-
protocolFeeUsd += usd;
|
|
1203
|
-
} else if (type === "message" || type === "gas" || type === "network") {
|
|
1204
|
-
messageFeeUsd += usd;
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
const serviceUsd = byType.get("protocol") ?? byType.get("service") ?? void 0;
|
|
1208
|
-
const blockchainUsd = byType.get("gas") ?? byType.get("network") ?? byType.get("message") ?? void 0;
|
|
1209
|
-
return {
|
|
1210
|
-
totalUsd: total,
|
|
1211
|
-
protocolFeeUsd: protocolFeeUsd > 0 ? protocolFeeUsd : void 0,
|
|
1212
|
-
messageFeeUsd: messageFeeUsd > 0 ? messageFeeUsd : void 0,
|
|
1213
|
-
serviceUsd,
|
|
1214
|
-
blockchainUsd
|
|
1215
|
-
};
|
|
1216
|
-
}
|
|
1217
|
-
function dollarsFromNativeFees(feeNative, feeLzToken, chain, tokens) {
|
|
1218
|
-
let total = 0;
|
|
1219
|
-
if (feeNative && chain) {
|
|
1220
|
-
const { decimals, priceUsd } = findNativeMeta(tokens, chain);
|
|
1221
|
-
const human = fromLD(String(feeNative), decimals);
|
|
1222
|
-
total += (priceUsd ?? 0) * human;
|
|
1223
|
-
}
|
|
1224
|
-
if (feeLzToken) {
|
|
1225
|
-
const lz = tokens?.find((t) => normSym(t.symbol) === "LZ");
|
|
1226
|
-
if (lz?.price?.usd && lz.decimals != null) {
|
|
1227
|
-
const human = fromLD(String(feeLzToken), lz.decimals);
|
|
1228
|
-
total += lz.price.usd * human;
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
return total;
|
|
1232
|
-
}
|
|
1233
|
-
function sumFeeByTokenLD(fees, dstTokenAddr, dstChainKey) {
|
|
1234
|
-
if (!fees?.length || !dstTokenAddr || !dstChainKey) return "0";
|
|
1235
|
-
let acc = 0n;
|
|
1236
|
-
for (const f of fees) {
|
|
1237
|
-
if (f.chainKey !== dstChainKey) continue;
|
|
1238
|
-
const same = dstChainKey === "ton" ? tonNorm(f.token) === tonNorm(dstTokenAddr) : lower(f.token) === lower(dstTokenAddr);
|
|
1239
|
-
if (!same) continue;
|
|
1240
|
-
acc += BigInt(f.amount ?? "0");
|
|
1241
|
-
}
|
|
1242
|
-
return acc.toString();
|
|
1243
|
-
}
|
|
1244
1104
|
function useBalances(chainKey, address, priorityTokenSymbol) {
|
|
1245
1105
|
const { chainRegistry } = useChainStrategies();
|
|
1246
1106
|
const { assetMatrix } = useTokensStore();
|
|
@@ -1302,10 +1162,92 @@ function useBalances(chainKey, address, priorityTokenSymbol) {
|
|
|
1302
1162
|
query
|
|
1303
1163
|
};
|
|
1304
1164
|
}
|
|
1305
|
-
|
|
1165
|
+
const SearchInput = ({
|
|
1166
|
+
placeholder,
|
|
1167
|
+
value,
|
|
1168
|
+
onChange,
|
|
1169
|
+
className,
|
|
1170
|
+
containerClassName
|
|
1171
|
+
}) => {
|
|
1172
|
+
const [isFocused, setIsFocused] = require$$0.useState(false);
|
|
1173
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1174
|
+
"div",
|
|
1175
|
+
{
|
|
1176
|
+
className: utils.cn(
|
|
1177
|
+
"flex items-center gap-2.5 px-5 py-3.5 bg-input rounded-md h-12.5 transition-all duration-200",
|
|
1178
|
+
isFocused ? "border border-ring" : "border border-transparent",
|
|
1179
|
+
containerClassName
|
|
1180
|
+
),
|
|
1181
|
+
children: [
|
|
1182
|
+
/* @__PURE__ */ jsxRuntime.jsx(SearchIcon, { className: "size-6 text-input-icon" }),
|
|
1183
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1184
|
+
input.Input,
|
|
1185
|
+
{
|
|
1186
|
+
placeholder,
|
|
1187
|
+
className: utils.cn(
|
|
1188
|
+
"w-full outline-none bg-transparent border-none ring-0 leading-0 p-0 h-6 text-base text-input-text placeholder:text-input-placeholder bg-none dark:bg-transparent",
|
|
1189
|
+
className
|
|
1190
|
+
),
|
|
1191
|
+
value,
|
|
1192
|
+
onChange: (e) => onChange(e.target.value),
|
|
1193
|
+
onFocus: () => setIsFocused(true),
|
|
1194
|
+
onBlur: () => setIsFocused(false)
|
|
1195
|
+
}
|
|
1196
|
+
)
|
|
1197
|
+
]
|
|
1198
|
+
}
|
|
1199
|
+
);
|
|
1200
|
+
};
|
|
1201
|
+
const TokenRow = ({
|
|
1202
|
+
symbol,
|
|
1203
|
+
name,
|
|
1204
|
+
isSelected,
|
|
1205
|
+
hasAnyWallet,
|
|
1206
|
+
balance,
|
|
1207
|
+
usdValue,
|
|
1208
|
+
isBalanceLoading,
|
|
1209
|
+
onPick
|
|
1210
|
+
}) => {
|
|
1211
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1212
|
+
button.Button,
|
|
1213
|
+
{
|
|
1214
|
+
onClick: onPick,
|
|
1215
|
+
className: `w-full bg-transparent flex items-center justify-between gap-2.5 px-5 hover:bg-accent hover:scale-100 ${isSelected ? "border border-ring" : ""}`,
|
|
1216
|
+
children: [
|
|
1217
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1218
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1219
|
+
TokenSymbol,
|
|
1220
|
+
{
|
|
1221
|
+
symbol,
|
|
1222
|
+
className: "size-7.5 max-w-7.5 rounded-full",
|
|
1223
|
+
alt: symbol
|
|
1224
|
+
}
|
|
1225
|
+
),
|
|
1226
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-1", children: [
|
|
1227
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-extrabold text-foreground text-lg leading-4 truncate flex items-center gap-1", children: symbol }),
|
|
1228
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs leading-3 font-semibold text-muted-foreground truncate", children: name })
|
|
1229
|
+
] })
|
|
1230
|
+
] }),
|
|
1231
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right space-y-1", children: isBalanceLoading && hasAnyWallet ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end gap-1", children: [
|
|
1232
|
+
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-5 w-16 rounded-md" }),
|
|
1233
|
+
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-3 w-12 rounded-md" })
|
|
1234
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1235
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-extrabold text-foreground text-lg leading-4 truncate", children: hasAnyWallet ? formatBalance(balance) : "—" }),
|
|
1236
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs leading-3 text-muted-foreground", children: hasAnyWallet && balance > 0 && usdValue > 0 ? formatUsd(usdValue) : "—" })
|
|
1237
|
+
] }) })
|
|
1238
|
+
]
|
|
1239
|
+
}
|
|
1240
|
+
);
|
|
1241
|
+
};
|
|
1242
|
+
const TokenSelectModal = ({
|
|
1243
|
+
isOpen,
|
|
1244
|
+
onClose,
|
|
1245
|
+
items,
|
|
1246
|
+
onChangeAsset
|
|
1247
|
+
}) => {
|
|
1248
|
+
const { t } = useBridgeTranslation();
|
|
1306
1249
|
const [query, setQuery] = require$$0.useState("");
|
|
1307
1250
|
const [tab, setTab] = require$$0.useState("my");
|
|
1308
|
-
const [isFocused, setIsFocused] = require$$0.useState(false);
|
|
1309
1251
|
const { srcAddress } = useAddresses();
|
|
1310
1252
|
const { fromChain, setFromChain, chains } = useChainsStore();
|
|
1311
1253
|
const { assetMatrix, selectedAssetSymbol } = useTokensStore();
|
|
@@ -1390,159 +1332,7 @@ function useTokenSelectData(items) {
|
|
|
1390
1332
|
const resetState = require$$0.useCallback(() => {
|
|
1391
1333
|
setQuery("");
|
|
1392
1334
|
setTab("my");
|
|
1393
|
-
setIsFocused(false);
|
|
1394
1335
|
}, []);
|
|
1395
|
-
return {
|
|
1396
|
-
query,
|
|
1397
|
-
setQuery,
|
|
1398
|
-
tab,
|
|
1399
|
-
setTab,
|
|
1400
|
-
isFocused,
|
|
1401
|
-
setIsFocused,
|
|
1402
|
-
effectiveTab,
|
|
1403
|
-
resetState,
|
|
1404
|
-
fromChain,
|
|
1405
|
-
setFromChain,
|
|
1406
|
-
selectedAssetSymbol,
|
|
1407
|
-
balancesQuery,
|
|
1408
|
-
groupedTokens,
|
|
1409
|
-
myTokens,
|
|
1410
|
-
getBalance,
|
|
1411
|
-
getTokenUsdValue,
|
|
1412
|
-
findFirstAvailableChain,
|
|
1413
|
-
hasAnyWallet
|
|
1414
|
-
};
|
|
1415
|
-
}
|
|
1416
|
-
const TokenRow = ({
|
|
1417
|
-
symbol,
|
|
1418
|
-
name,
|
|
1419
|
-
isSelected,
|
|
1420
|
-
hasAnyWallet,
|
|
1421
|
-
balance,
|
|
1422
|
-
usdValue,
|
|
1423
|
-
isBalanceLoading,
|
|
1424
|
-
onPick
|
|
1425
|
-
}) => {
|
|
1426
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1427
|
-
button.Button,
|
|
1428
|
-
{
|
|
1429
|
-
onClick: onPick,
|
|
1430
|
-
className: `w-full h-12.5 rounded-md cursor-pointer bg-transparent flex shadow-none items-center justify-between gap-2.5 px-5 py-2.5 hover:bg-modal-item-hover transition-[300] ${isSelected ? "border border-ring" : ""}`,
|
|
1431
|
-
children: [
|
|
1432
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1433
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1434
|
-
TokenSymbol,
|
|
1435
|
-
{
|
|
1436
|
-
symbol,
|
|
1437
|
-
className: "size-7.5 max-w-7.5 rounded-full",
|
|
1438
|
-
alt: symbol
|
|
1439
|
-
}
|
|
1440
|
-
),
|
|
1441
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-1", children: [
|
|
1442
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-extrabold text-foreground text-lg leading-4 truncate flex items-center gap-1", children: symbol }),
|
|
1443
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs leading-3 font-semibold text-muted-foreground truncate", children: name })
|
|
1444
|
-
] })
|
|
1445
|
-
] }),
|
|
1446
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right space-y-1", children: isBalanceLoading && hasAnyWallet ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end gap-1", children: [
|
|
1447
|
-
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-5 w-16 rounded-md" }),
|
|
1448
|
-
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-3 w-12 rounded-md" })
|
|
1449
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1450
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-extrabold text-foreground text-lg leading-4 truncate", children: hasAnyWallet ? formatBalance(balance) : "—" }),
|
|
1451
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs leading-3 text-muted-foreground", children: hasAnyWallet && balance > 0 && usdValue > 0 ? formatUsd(usdValue) : "—" })
|
|
1452
|
-
] }) })
|
|
1453
|
-
]
|
|
1454
|
-
}
|
|
1455
|
-
);
|
|
1456
|
-
};
|
|
1457
|
-
const HEADER_H = 30;
|
|
1458
|
-
const ROW_H = 50;
|
|
1459
|
-
const HEADER_TOP_GAP = 30;
|
|
1460
|
-
const VirtualizedTokenList = ({
|
|
1461
|
-
nodes,
|
|
1462
|
-
balancesLoading,
|
|
1463
|
-
hasAnyWallet,
|
|
1464
|
-
selectedAssetSymbol,
|
|
1465
|
-
getBalance,
|
|
1466
|
-
getTokenUsdValue,
|
|
1467
|
-
onPick
|
|
1468
|
-
}) => {
|
|
1469
|
-
const Row = ({ index, style }) => {
|
|
1470
|
-
const node = nodes[index];
|
|
1471
|
-
if (node.kind === "header") {
|
|
1472
|
-
const gap = index === 0 ? 0 : HEADER_TOP_GAP;
|
|
1473
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1474
|
-
"div",
|
|
1475
|
-
{
|
|
1476
|
-
style: { ...style, paddingTop: gap },
|
|
1477
|
-
className: "px-5 flex leading-4 text-base py-1.5 font-semibold text-muted-foreground uppercase",
|
|
1478
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: node.title })
|
|
1479
|
-
}
|
|
1480
|
-
);
|
|
1481
|
-
}
|
|
1482
|
-
const bal = getBalance(node.token.symbol);
|
|
1483
|
-
const usd = getTokenUsdValue(node.token.symbol, node.token.price?.usd);
|
|
1484
|
-
const isSelected = selectedAssetSymbol?.toUpperCase() === node.token.symbol.toUpperCase();
|
|
1485
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1486
|
-
TokenRow,
|
|
1487
|
-
{
|
|
1488
|
-
symbol: node.token.symbol,
|
|
1489
|
-
name: node.token.name,
|
|
1490
|
-
isSelected: !!isSelected,
|
|
1491
|
-
hasAnyWallet,
|
|
1492
|
-
balance: bal,
|
|
1493
|
-
usdValue: usd,
|
|
1494
|
-
isBalanceLoading: balancesLoading,
|
|
1495
|
-
onPick: () => onPick(node.token.symbol, node.willChangeSrc)
|
|
1496
|
-
}
|
|
1497
|
-
);
|
|
1498
|
-
};
|
|
1499
|
-
const getItemSize = (index) => {
|
|
1500
|
-
const node = nodes[index];
|
|
1501
|
-
if (node.kind === "header") {
|
|
1502
|
-
const gap = index === 0 ? 0 : HEADER_TOP_GAP;
|
|
1503
|
-
return HEADER_H + gap;
|
|
1504
|
-
}
|
|
1505
|
-
return ROW_H;
|
|
1506
|
-
};
|
|
1507
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1508
|
-
reactWindow.VariableSizeList,
|
|
1509
|
-
{
|
|
1510
|
-
height: 480,
|
|
1511
|
-
width: "100%",
|
|
1512
|
-
itemCount: nodes.length,
|
|
1513
|
-
itemSize: getItemSize,
|
|
1514
|
-
overscanCount: 8,
|
|
1515
|
-
style: { willChange: "transform", paddingBottom: "40px" },
|
|
1516
|
-
children: Row
|
|
1517
|
-
}
|
|
1518
|
-
);
|
|
1519
|
-
};
|
|
1520
|
-
const TokenSelectModal = ({
|
|
1521
|
-
isOpen,
|
|
1522
|
-
onClose,
|
|
1523
|
-
items,
|
|
1524
|
-
onChangeAsset
|
|
1525
|
-
}) => {
|
|
1526
|
-
const { t } = useBridgeTranslation();
|
|
1527
|
-
const {
|
|
1528
|
-
query,
|
|
1529
|
-
setQuery,
|
|
1530
|
-
tab,
|
|
1531
|
-
setTab,
|
|
1532
|
-
isFocused,
|
|
1533
|
-
setIsFocused,
|
|
1534
|
-
effectiveTab,
|
|
1535
|
-
resetState,
|
|
1536
|
-
setFromChain,
|
|
1537
|
-
selectedAssetSymbol,
|
|
1538
|
-
balancesQuery,
|
|
1539
|
-
groupedTokens,
|
|
1540
|
-
myTokens,
|
|
1541
|
-
getBalance,
|
|
1542
|
-
getTokenUsdValue,
|
|
1543
|
-
findFirstAvailableChain,
|
|
1544
|
-
hasAnyWallet
|
|
1545
|
-
} = useTokenSelectData(items);
|
|
1546
1336
|
const handleClose = require$$0.useCallback(() => {
|
|
1547
1337
|
resetState();
|
|
1548
1338
|
onClose();
|
|
@@ -1559,68 +1349,41 @@ const TokenSelectModal = ({
|
|
|
1559
1349
|
onChangeAsset(sym);
|
|
1560
1350
|
handleClose();
|
|
1561
1351
|
};
|
|
1562
|
-
const
|
|
1563
|
-
const out = [];
|
|
1352
|
+
const tokensToRender = require$$0.useMemo(() => {
|
|
1564
1353
|
if (effectiveTab === "my") {
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
token,
|
|
1570
|
-
willChangeSrc: false
|
|
1571
|
-
});
|
|
1572
|
-
}
|
|
1573
|
-
return out;
|
|
1354
|
+
return myTokens.map((token) => ({
|
|
1355
|
+
token,
|
|
1356
|
+
willChangeSrc: false
|
|
1357
|
+
}));
|
|
1574
1358
|
}
|
|
1575
1359
|
const mainTokens = [
|
|
1576
|
-
...groupedTokens.withBalance
|
|
1577
|
-
...groupedTokens.onSrcChain
|
|
1578
|
-
];
|
|
1579
|
-
for (const token of mainTokens) {
|
|
1580
|
-
out.push({
|
|
1581
|
-
kind: "token",
|
|
1582
|
-
key: `main:${token.symbol}`,
|
|
1360
|
+
...groupedTokens.withBalance.map((token) => ({
|
|
1583
1361
|
token,
|
|
1584
1362
|
willChangeSrc: false
|
|
1585
|
-
})
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
return out;
|
|
1603
|
-
}, [effectiveTab, myTokens, groupedTokens, t]);
|
|
1604
|
-
return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { className: "!max-h-[80dvh] overflow-auto", children: [
|
|
1363
|
+
})),
|
|
1364
|
+
...groupedTokens.onSrcChain.map((token) => ({
|
|
1365
|
+
token,
|
|
1366
|
+
willChangeSrc: false
|
|
1367
|
+
}))
|
|
1368
|
+
];
|
|
1369
|
+
return mainTokens;
|
|
1370
|
+
}, [effectiveTab, myTokens, groupedTokens]);
|
|
1371
|
+
const willChangeSrcTokens = require$$0.useMemo(
|
|
1372
|
+
() => groupedTokens.willChangeSrcChain.map((token) => ({
|
|
1373
|
+
token,
|
|
1374
|
+
willChangeSrc: true
|
|
1375
|
+
})),
|
|
1376
|
+
[groupedTokens.willChangeSrcChain]
|
|
1377
|
+
);
|
|
1378
|
+
const hasNoResults = tokensToRender.length === 0 && willChangeSrcTokens.length === 0;
|
|
1379
|
+
return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { className: "!h-[90dvh] overflow-hidden flex flex-col", children: [
|
|
1605
1380
|
/* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("bridge.selectToken") }) }),
|
|
1606
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1607
|
-
|
|
1381
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1382
|
+
SearchInput,
|
|
1608
1383
|
{
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1613
|
-
input.Input,
|
|
1614
|
-
{
|
|
1615
|
-
placeholder: t("bridge.searchToken"),
|
|
1616
|
-
className: "w-full outline-none leading-0 p-0 h-6 text-base text-input-text placeholder:text-input-placeholder bg-none dark:bg-transparent",
|
|
1617
|
-
value: query,
|
|
1618
|
-
onChange: (e) => setQuery(e.target.value),
|
|
1619
|
-
onFocus: () => setIsFocused(true),
|
|
1620
|
-
onBlur: () => setIsFocused(false)
|
|
1621
|
-
}
|
|
1622
|
-
)
|
|
1623
|
-
]
|
|
1384
|
+
placeholder: t("bridge.searchToken"),
|
|
1385
|
+
value: query,
|
|
1386
|
+
onChange: setQuery
|
|
1624
1387
|
}
|
|
1625
1388
|
),
|
|
1626
1389
|
hasAnyWallet() && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
@@ -1643,20 +1406,52 @@ const TokenSelectModal = ({
|
|
|
1643
1406
|
}
|
|
1644
1407
|
)
|
|
1645
1408
|
] }),
|
|
1646
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-
|
|
1409
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-auto -mx-5", children: hasNoResults ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground px-5 py-3.5", children: t("bridge.noResults") }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1647
1410
|
effectiveTab === "my" && myTokens.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "leading-4 text-base font-semibold text-muted-foreground uppercase px-5 py-2", children: t("bridge.noBalancesFound") }),
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1411
|
+
tokensToRender.map(({ token, willChangeSrc }) => {
|
|
1412
|
+
const bal = getBalance(token.symbol);
|
|
1413
|
+
const usd = getTokenUsdValue(token.symbol, token.price?.usd);
|
|
1414
|
+
const isSelected = selectedAssetSymbol?.toUpperCase() === token.symbol.toUpperCase();
|
|
1415
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1416
|
+
TokenRow,
|
|
1417
|
+
{
|
|
1418
|
+
symbol: token.symbol,
|
|
1419
|
+
name: token.name,
|
|
1420
|
+
isSelected: !!isSelected,
|
|
1421
|
+
hasAnyWallet: hasAnyWallet(),
|
|
1422
|
+
balance: bal,
|
|
1423
|
+
usdValue: usd,
|
|
1424
|
+
isBalanceLoading: balancesQuery.isLoading || balancesQuery.isFetching,
|
|
1425
|
+
onPick: () => onPick(token.symbol, willChangeSrc)
|
|
1426
|
+
},
|
|
1427
|
+
`${effectiveTab}:${token.symbol}`
|
|
1428
|
+
);
|
|
1429
|
+
}),
|
|
1430
|
+
effectiveTab === "all" && willChangeSrcTokens.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1431
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-5 flex leading-4 text-base py-1.5 font-semibold text-muted-foreground uppercase mt-7.5", children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: t("bridge.willChangeSourceChain") }) }),
|
|
1432
|
+
willChangeSrcTokens.map(({ token, willChangeSrc }) => {
|
|
1433
|
+
const bal = getBalance(token.symbol);
|
|
1434
|
+
const usd = getTokenUsdValue(
|
|
1435
|
+
token.symbol,
|
|
1436
|
+
token.price?.usd
|
|
1437
|
+
);
|
|
1438
|
+
const isSelected = selectedAssetSymbol?.toUpperCase() === token.symbol.toUpperCase();
|
|
1439
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1440
|
+
TokenRow,
|
|
1441
|
+
{
|
|
1442
|
+
symbol: token.symbol,
|
|
1443
|
+
name: token.name,
|
|
1444
|
+
isSelected: !!isSelected,
|
|
1445
|
+
hasAnyWallet: hasAnyWallet(),
|
|
1446
|
+
balance: bal,
|
|
1447
|
+
usdValue: usd,
|
|
1448
|
+
isBalanceLoading: balancesQuery.isLoading || balancesQuery.isFetching,
|
|
1449
|
+
onPick: () => onPick(token.symbol, willChangeSrc)
|
|
1450
|
+
},
|
|
1451
|
+
`will:${token.symbol}`
|
|
1452
|
+
);
|
|
1453
|
+
})
|
|
1454
|
+
] })
|
|
1660
1455
|
] }) })
|
|
1661
1456
|
] }) });
|
|
1662
1457
|
};
|
|
@@ -1802,7 +1597,7 @@ const FormHeaderComponent = () => {
|
|
|
1802
1597
|
const sum = selectedAssetSymbol.toUpperCase();
|
|
1803
1598
|
return assets.find((a) => a.symbol.toUpperCase() === sum) ?? assets[0];
|
|
1804
1599
|
}, [assets, selectedAssetSymbol]);
|
|
1805
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(card.CardHeader, { className: "gap-y-0 flex justify-between items-center", children: [
|
|
1600
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(card.CardHeader, { className: "gap-y-0 flex flex-row justify-between items-center", children: [
|
|
1806
1601
|
/* @__PURE__ */ jsxRuntime.jsxs(card.CardTitle, { className: "flex items-center gap-2.5", children: [
|
|
1807
1602
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-normal leading-3.5 text-muted-foreground", children: t("bridge.selectToken") }),
|
|
1808
1603
|
/* @__PURE__ */ jsxRuntime.jsx(SelectTokenButton, { token: current, onClick: onOpen })
|
|
@@ -1833,6 +1628,19 @@ const FormHeaderComponent = () => {
|
|
|
1833
1628
|
] });
|
|
1834
1629
|
};
|
|
1835
1630
|
const FormHeader = require$$0.memo(FormHeaderComponent);
|
|
1631
|
+
function toLD(human, decimals) {
|
|
1632
|
+
const [i = "0", f = ""] = human.replace(",", ".").split(".");
|
|
1633
|
+
const frac = (f + "0".repeat(decimals)).slice(0, decimals);
|
|
1634
|
+
return BigInt(i + frac).toString();
|
|
1635
|
+
}
|
|
1636
|
+
function fromLD(ld, decimals) {
|
|
1637
|
+
const bi = BigInt(ld || "0");
|
|
1638
|
+
if (decimals === 0) return Number(bi);
|
|
1639
|
+
const base = BigInt(10) ** BigInt(decimals);
|
|
1640
|
+
const int = bi / base;
|
|
1641
|
+
const frac = Number(bi % base) / Number(base);
|
|
1642
|
+
return Number(int) + frac;
|
|
1643
|
+
}
|
|
1836
1644
|
async function fetchQuotes(req) {
|
|
1837
1645
|
const params = {
|
|
1838
1646
|
srcChainKey: req.srcChainKey,
|
|
@@ -1891,6 +1699,131 @@ async function getQuotesByPriority(req) {
|
|
|
1891
1699
|
const priority = req.routePriority || RoutePriority.RECOMMENDED;
|
|
1892
1700
|
return selectQuoteByPriority(routes, priority);
|
|
1893
1701
|
}
|
|
1702
|
+
function resolveTokenOnChainFromMatrix$2(assetMatrix, assetSymbol, chainKey) {
|
|
1703
|
+
if (!assetMatrix || !assetSymbol || !chainKey) return void 0;
|
|
1704
|
+
const byChain = assetMatrix[assetSymbol.toUpperCase()];
|
|
1705
|
+
return byChain?.[chainKey];
|
|
1706
|
+
}
|
|
1707
|
+
const DEFAULT_SLIPPAGE_BPS = 50;
|
|
1708
|
+
const lower = (s) => (s ?? "").toLowerCase();
|
|
1709
|
+
const normSym = (s) => (s ?? "").toUpperCase().replace(/₮/g, "T").replace(/[^A-Z0-9]/g, "");
|
|
1710
|
+
function tonNorm(addr) {
|
|
1711
|
+
if (!addr) return null;
|
|
1712
|
+
try {
|
|
1713
|
+
if (addr.includes(":")) {
|
|
1714
|
+
return core.Address.parseRaw(addr).toString({
|
|
1715
|
+
bounceable: false,
|
|
1716
|
+
urlSafe: true
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1719
|
+
return core.Address.parse(addr).toString({ bounceable: false, urlSafe: true });
|
|
1720
|
+
} catch {
|
|
1721
|
+
return null;
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
const isZeroAddr = (a) => (
|
|
1725
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1726
|
+
!!a && /^0x0{40}$/i.test(a) || /^0x[eE]{4}e{36}$/i.test(a)
|
|
1727
|
+
);
|
|
1728
|
+
function addrForApi(chainKey, addr) {
|
|
1729
|
+
if (chainKey === "ton") return tonNorm(addr);
|
|
1730
|
+
return addr;
|
|
1731
|
+
}
|
|
1732
|
+
function isNativeAddrEqual(chain, tokenAddr) {
|
|
1733
|
+
if (!chain) return false;
|
|
1734
|
+
if (!tokenAddr) return false;
|
|
1735
|
+
if (isZeroAddr(tokenAddr)) return true;
|
|
1736
|
+
const nativeAddr = chain.nativeCurrency?.address;
|
|
1737
|
+
if (!nativeAddr) return false;
|
|
1738
|
+
if (chain.chainKey === "ton") {
|
|
1739
|
+
const a = tonNorm(tokenAddr);
|
|
1740
|
+
const b = tonNorm(nativeAddr);
|
|
1741
|
+
return !!a && !!b && a === b;
|
|
1742
|
+
}
|
|
1743
|
+
return lower(nativeAddr) === lower(tokenAddr);
|
|
1744
|
+
}
|
|
1745
|
+
function findNativeMeta(tokens, chain) {
|
|
1746
|
+
if (!chain) return { decimals: 18, priceUsd: void 0 };
|
|
1747
|
+
const sym = normSym(chain.nativeCurrency?.symbol);
|
|
1748
|
+
if (!sym) {
|
|
1749
|
+
return { decimals: chain.chainKey === "ton" ? 9 : 18, priceUsd: void 0 };
|
|
1750
|
+
}
|
|
1751
|
+
const sameChain = tokens?.find(
|
|
1752
|
+
(t) => t.chainKey === chain.chainKey && normSym(t.symbol) === sym
|
|
1753
|
+
) ?? void 0;
|
|
1754
|
+
if (sameChain)
|
|
1755
|
+
return { decimals: sameChain.decimals, priceUsd: sameChain.price?.usd };
|
|
1756
|
+
const anyChain = tokens?.find((t) => normSym(t.symbol) === sym);
|
|
1757
|
+
if (anyChain)
|
|
1758
|
+
return { decimals: anyChain.decimals, priceUsd: anyChain.price?.usd };
|
|
1759
|
+
return { decimals: chain.chainKey === "ton" ? 9 : 18, priceUsd: void 0 };
|
|
1760
|
+
}
|
|
1761
|
+
function lookupTokenMeta(tokens, chains, chainKey, tokenAddr) {
|
|
1762
|
+
if (!chainKey) return { decimals: 18, priceUsd: void 0 };
|
|
1763
|
+
const chain = chains?.find((c) => c.chainKey === chainKey);
|
|
1764
|
+
const hit = tokens?.find((t) => {
|
|
1765
|
+
if (t.chainKey !== chainKey) return false;
|
|
1766
|
+
if (chainKey === "ton") {
|
|
1767
|
+
const a = tonNorm(t.address);
|
|
1768
|
+
const b = tonNorm(tokenAddr);
|
|
1769
|
+
return !!a && !!b && a === b;
|
|
1770
|
+
}
|
|
1771
|
+
return lower(t.address) === lower(tokenAddr);
|
|
1772
|
+
}) ?? void 0;
|
|
1773
|
+
if (hit) return { decimals: hit.decimals, priceUsd: hit.price?.usd };
|
|
1774
|
+
if (isNativeAddrEqual(chain, tokenAddr)) {
|
|
1775
|
+
return findNativeMeta(tokens, chain);
|
|
1776
|
+
}
|
|
1777
|
+
return { decimals: chainKey === "ton" ? 9 : 18, priceUsd: void 0 };
|
|
1778
|
+
}
|
|
1779
|
+
function computeFeesUsdFromArray(fees, tokens, chains) {
|
|
1780
|
+
if (!fees?.length) return { totalUsd: 0 };
|
|
1781
|
+
let total = 0;
|
|
1782
|
+
let protocolFeeUsd = 0;
|
|
1783
|
+
let messageFeeUsd = 0;
|
|
1784
|
+
const byType = /* @__PURE__ */ new Map();
|
|
1785
|
+
for (const f of fees) {
|
|
1786
|
+
let usd = Number(f.usd ?? 0);
|
|
1787
|
+
if (!usd) {
|
|
1788
|
+
const { decimals, priceUsd } = lookupTokenMeta(
|
|
1789
|
+
tokens,
|
|
1790
|
+
chains,
|
|
1791
|
+
f.chainKey,
|
|
1792
|
+
f.token
|
|
1793
|
+
);
|
|
1794
|
+
const human = fromLD(String(f.amount ?? "0"), decimals);
|
|
1795
|
+
usd = (priceUsd ?? 0) * human;
|
|
1796
|
+
}
|
|
1797
|
+
total += usd;
|
|
1798
|
+
const type = (f.type ?? "other").toLowerCase();
|
|
1799
|
+
byType.set(type, (byType.get(type) ?? 0) + usd);
|
|
1800
|
+
if (type === "protocol" || type === "service") {
|
|
1801
|
+
protocolFeeUsd += usd;
|
|
1802
|
+
} else if (type === "message" || type === "gas" || type === "network") {
|
|
1803
|
+
messageFeeUsd += usd;
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
const serviceUsd = byType.get("protocol") ?? byType.get("service") ?? void 0;
|
|
1807
|
+
const blockchainUsd = byType.get("gas") ?? byType.get("network") ?? byType.get("message") ?? void 0;
|
|
1808
|
+
return {
|
|
1809
|
+
totalUsd: total,
|
|
1810
|
+
protocolFeeUsd: protocolFeeUsd > 0 ? protocolFeeUsd : void 0,
|
|
1811
|
+
messageFeeUsd: messageFeeUsd > 0 ? messageFeeUsd : void 0,
|
|
1812
|
+
serviceUsd,
|
|
1813
|
+
blockchainUsd
|
|
1814
|
+
};
|
|
1815
|
+
}
|
|
1816
|
+
function sumFeeByTokenLD(fees, dstTokenAddr, dstChainKey) {
|
|
1817
|
+
if (!fees?.length || !dstTokenAddr || !dstChainKey) return "0";
|
|
1818
|
+
let acc = 0n;
|
|
1819
|
+
for (const f of fees) {
|
|
1820
|
+
if (f.chainKey !== dstChainKey) continue;
|
|
1821
|
+
const same = dstChainKey === "ton" ? tonNorm(f.token) === tonNorm(dstTokenAddr) : lower(f.token) === lower(dstTokenAddr);
|
|
1822
|
+
if (!same) continue;
|
|
1823
|
+
acc += BigInt(f.amount ?? "0");
|
|
1824
|
+
}
|
|
1825
|
+
return acc.toString();
|
|
1826
|
+
}
|
|
1894
1827
|
function useBridgeQuote() {
|
|
1895
1828
|
const { assetMatrix, selectedAssetSymbol } = useTokensStore();
|
|
1896
1829
|
const { fromChain, toChain } = useChainsStore();
|
|
@@ -2391,12 +2324,10 @@ const ChainSelectModal = ({
|
|
|
2391
2324
|
}) => {
|
|
2392
2325
|
const { t } = useBridgeTranslation();
|
|
2393
2326
|
const [query, setQuery] = require$$0.useState("");
|
|
2394
|
-
const [isFocused, setIsFocused] = require$$0.useState(false);
|
|
2395
2327
|
const { setFromChain, chains, fromChain, toChain } = useChainsStore();
|
|
2396
2328
|
const { assetMatrix, selectedAssetSymbol } = useTokensStore();
|
|
2397
2329
|
const handleClose = require$$0.useCallback(() => {
|
|
2398
2330
|
setQuery("");
|
|
2399
|
-
setIsFocused(false);
|
|
2400
2331
|
onClose();
|
|
2401
2332
|
}, [onClose]);
|
|
2402
2333
|
const findCompatibleSrcChain = require$$0.useCallback(
|
|
@@ -2456,7 +2387,7 @@ const ChainSelectModal = ({
|
|
|
2456
2387
|
button.Button,
|
|
2457
2388
|
{
|
|
2458
2389
|
onClick: () => onChainPick(chain, willChangeSrc),
|
|
2459
|
-
className: `w-full cursor-pointer flex shadow-none items-center justify-between gap-2.5 px-5 py-3.5 h-12.5 font-extrabold capitalize hover:bg-muted bg-transparent rounded-
|
|
2390
|
+
className: `w-full cursor-pointer flex shadow-none items-center justify-between gap-2.5 px-5 py-3.5 h-12.5 font-extrabold capitalize hover:bg-muted bg-transparent rounded-md transition-[300] ${isSelected ? "border border-ring" : ""}`,
|
|
2460
2391
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
2461
2392
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2462
2393
|
NetworkSymbol,
|
|
@@ -2472,26 +2403,16 @@ const ChainSelectModal = ({
|
|
|
2472
2403
|
chain.chainKey
|
|
2473
2404
|
);
|
|
2474
2405
|
};
|
|
2475
|
-
return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { className: "!
|
|
2406
|
+
return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { className: "!h-[90dvh] flex flex-col", children: [
|
|
2476
2407
|
/* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("bridge.selectNetwork") }) }),
|
|
2477
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2478
|
-
|
|
2408
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2409
|
+
SearchInput,
|
|
2479
2410
|
{
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
{
|
|
2486
|
-
placeholder: t("bridge.searchDestinationChain"),
|
|
2487
|
-
className: "w-full outline-none leading-0 p-0 h-6 text-base text-foreground placeholder:text-muted-foreground bg-none dark:bg-transparent",
|
|
2488
|
-
value: query,
|
|
2489
|
-
onChange: (e) => setQuery(e.target.value),
|
|
2490
|
-
onFocus: () => setIsFocused(true),
|
|
2491
|
-
onBlur: () => setIsFocused(false)
|
|
2492
|
-
}
|
|
2493
|
-
)
|
|
2494
|
-
]
|
|
2411
|
+
placeholder: t("bridge.searchDestinationChain"),
|
|
2412
|
+
value: query,
|
|
2413
|
+
onChange: setQuery,
|
|
2414
|
+
containerClassName: "rounded-md",
|
|
2415
|
+
className: "text-foreground placeholder:text-muted-foreground"
|
|
2495
2416
|
}
|
|
2496
2417
|
),
|
|
2497
2418
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto", children: [
|
|
@@ -2706,63 +2627,30 @@ const useCustomAddressStore = zustand.create((set) => ({
|
|
|
2706
2627
|
setCustomDstAddress: (address) => set({ customDstAddress: address }),
|
|
2707
2628
|
clearCustomDstAddress: () => set({ customDstAddress: void 0 })
|
|
2708
2629
|
}));
|
|
2709
|
-
const
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
bounceable: false,
|
|
2715
|
-
urlSafe: true
|
|
2716
|
-
});
|
|
2717
|
-
}
|
|
2718
|
-
return core.Address.parse(addr).toString({ bounceable: false, urlSafe: true });
|
|
2719
|
-
} catch {
|
|
2720
|
-
return null;
|
|
2721
|
-
}
|
|
2630
|
+
const useIsAddressValid = (address, chainKey) => {
|
|
2631
|
+
const isValid = require$$0.useMemo(() => {
|
|
2632
|
+
return isAddressValidForChain(chainKey, address);
|
|
2633
|
+
}, [address, chainKey]);
|
|
2634
|
+
return { isValid };
|
|
2722
2635
|
};
|
|
2723
|
-
const
|
|
2636
|
+
const AnotherAddress = () => {
|
|
2637
|
+
const [enabled, setEnabled] = require$$0.useState(false);
|
|
2638
|
+
const [isFocused, setIsFocused] = require$$0.useState(false);
|
|
2724
2639
|
const { t } = useBridgeTranslation();
|
|
2725
2640
|
const { toChain } = useChainsStore();
|
|
2726
|
-
const {
|
|
2727
|
-
const { setCustomDstAddress, clearCustomDstAddress } = useCustomAddressStore();
|
|
2641
|
+
const { setCustomDstAddress } = useCustomAddressStore();
|
|
2728
2642
|
const [value, setValue] = require$$0.useState("");
|
|
2729
|
-
const
|
|
2730
|
-
const
|
|
2731
|
-
const prevEnabledRef = require$$0.useRef(enabled);
|
|
2732
|
-
require$$0.useEffect(() => {
|
|
2733
|
-
const wasEnabled = prevEnabledRef.current;
|
|
2734
|
-
if (enabled && !wasEnabled) {
|
|
2735
|
-
prevDstRef.current = dstAddress;
|
|
2736
|
-
setValue(dstAddress ?? "");
|
|
2737
|
-
setInvalid(false);
|
|
2738
|
-
}
|
|
2739
|
-
if (!enabled && wasEnabled) {
|
|
2740
|
-
clearCustomDstAddress();
|
|
2741
|
-
setInvalid(false);
|
|
2742
|
-
}
|
|
2743
|
-
prevEnabledRef.current = enabled;
|
|
2744
|
-
}, [enabled]);
|
|
2643
|
+
const { isValid } = useIsAddressValid(value.trim(), toChain?.chainKey);
|
|
2644
|
+
const invalid = value.trim() && !isValid;
|
|
2745
2645
|
const pushToStoreIfValid = (raw) => {
|
|
2746
2646
|
if (!enabled) return;
|
|
2747
2647
|
const v = raw.trim();
|
|
2748
2648
|
if (!v) {
|
|
2749
2649
|
setCustomDstAddress(void 0);
|
|
2750
|
-
setInvalid(false);
|
|
2751
|
-
return;
|
|
2752
|
-
}
|
|
2753
|
-
const ck = toChain?.chainKey;
|
|
2754
|
-
if (!ck) {
|
|
2755
|
-
setInvalid(true);
|
|
2756
2650
|
return;
|
|
2757
2651
|
}
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
if (valid && valueForStore) {
|
|
2761
|
-
setInvalid(false);
|
|
2762
|
-
setCustomDstAddress(valueForStore);
|
|
2763
|
-
if (ck === "ton") setValue(valueForStore);
|
|
2764
|
-
} else {
|
|
2765
|
-
setInvalid(true);
|
|
2652
|
+
if (isValid) {
|
|
2653
|
+
setCustomDstAddress(v);
|
|
2766
2654
|
}
|
|
2767
2655
|
};
|
|
2768
2656
|
const onChange = (text) => {
|
|
@@ -2777,7 +2665,7 @@ const ToggleRow = ({ enabled, onToggle }) => {
|
|
|
2777
2665
|
} catch {
|
|
2778
2666
|
}
|
|
2779
2667
|
};
|
|
2780
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 flex flex-col rounded-b-lg
|
|
2668
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 flex flex-col rounded-b-lg bg-muted", children: [
|
|
2781
2669
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2782
2670
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm leading-4.5 font-medium text-muted-foreground", children: t("bridge.sendToAnotherAddress") }),
|
|
2783
2671
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2786,7 +2674,7 @@ const ToggleRow = ({ enabled, onToggle }) => {
|
|
|
2786
2674
|
className: "data-[state=unchecked]:bg-switch-inactive data-[state=checked]:bg-switch-active",
|
|
2787
2675
|
"aria-pressed": enabled,
|
|
2788
2676
|
checked: enabled,
|
|
2789
|
-
onClick:
|
|
2677
|
+
onClick: () => setEnabled((v) => !v)
|
|
2790
2678
|
}
|
|
2791
2679
|
)
|
|
2792
2680
|
] }),
|
|
@@ -2801,16 +2689,27 @@ const ToggleRow = ({ enabled, onToggle }) => {
|
|
|
2801
2689
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2802
2690
|
"div",
|
|
2803
2691
|
{
|
|
2804
|
-
className:
|
|
2692
|
+
className: utils.cn(
|
|
2693
|
+
"bg-input py-2 px-4 mt-2 w-full flex items-center gap-4 rounded-md justify-between border border-transparent transition-all",
|
|
2694
|
+
{
|
|
2695
|
+
"py-4": value,
|
|
2696
|
+
"border border-ring": isFocused,
|
|
2697
|
+
"border-destructive": invalid
|
|
2698
|
+
}
|
|
2699
|
+
),
|
|
2805
2700
|
children: [
|
|
2806
2701
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5 w-full", children: [
|
|
2807
2702
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2808
2703
|
input.Input,
|
|
2809
2704
|
{
|
|
2810
|
-
className:
|
|
2811
|
-
|
|
2705
|
+
className: utils.cn(
|
|
2706
|
+
"p-0 h-auto text-base leading-5 font-semibold w-full bg-transparent dark:bg-transparent placeholder:text-muted-foreground/50 border-none"
|
|
2707
|
+
),
|
|
2708
|
+
placeholder: t("bridge.anotherAddressPlaceholder"),
|
|
2812
2709
|
type: "text",
|
|
2813
2710
|
value,
|
|
2711
|
+
onFocus: () => setIsFocused(true),
|
|
2712
|
+
onBlur: () => setIsFocused(false),
|
|
2814
2713
|
onChange: (e) => onChange(e.target.value)
|
|
2815
2714
|
}
|
|
2816
2715
|
),
|
|
@@ -2820,21 +2719,14 @@ const ToggleRow = ({ enabled, onToggle }) => {
|
|
|
2820
2719
|
defaultValue: "Check correctness before transfer"
|
|
2821
2720
|
}) }) })
|
|
2822
2721
|
] }),
|
|
2823
|
-
!value ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2824
|
-
button.Button,
|
|
2825
|
-
{
|
|
2826
|
-
variant: "default",
|
|
2827
|
-
className: "self-center py-2 h-8.5 px-3 hover:bg-input-button bg-input-button text-input-button-foreground text-sm leading-4.5 font-semibold uppercase !rounded-40",
|
|
2828
|
-
onClick: onPaste,
|
|
2829
|
-
children: t("common.paste")
|
|
2830
|
-
}
|
|
2831
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2722
|
+
!value ? /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "secondary", size: "sm", onClick: onPaste, children: t("common.paste") }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2832
2723
|
button.Button,
|
|
2833
2724
|
{
|
|
2834
2725
|
variant: "ghost",
|
|
2835
|
-
|
|
2726
|
+
size: "sm",
|
|
2727
|
+
className: "rounded-full p-0 size-5 self-start",
|
|
2836
2728
|
onClick: () => setValue(""),
|
|
2837
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-
|
|
2729
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4" })
|
|
2838
2730
|
}
|
|
2839
2731
|
)
|
|
2840
2732
|
]
|
|
@@ -3812,7 +3704,7 @@ const WalletSelectModal = () => {
|
|
|
3812
3704
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2 font-semibold text-muted-foreground uppercase", children: t("wallets.connected") }),
|
|
3813
3705
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "", children: connectedWallets.map((wallet) => {
|
|
3814
3706
|
const IconComponent = wallet.icon;
|
|
3815
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "-mx-5", children: /* @__PURE__ */ jsxRuntime.jsxs(button.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-
|
|
3707
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "-mx-5", children: /* @__PURE__ */ jsxRuntime.jsxs(button.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-md transition-[300]", children: [
|
|
3816
3708
|
/* @__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: [
|
|
3817
3709
|
/* @__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" }) }),
|
|
3818
3710
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start min-w-0", children: [
|
|
@@ -3853,7 +3745,7 @@ const WalletSelectModal = () => {
|
|
|
3853
3745
|
}
|
|
3854
3746
|
},
|
|
3855
3747
|
disabled: isEvmConnector ? isPending : !wallet.enabled,
|
|
3856
|
-
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-
|
|
3748
|
+
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-md transition-[300] disabled:opacity-50 disabled:cursor-not-allowed",
|
|
3857
3749
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
3858
3750
|
/* @__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" }) }),
|
|
3859
3751
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start min-w-0", children: [
|
|
@@ -5904,7 +5796,7 @@ class ChainStrategyRegistry {
|
|
|
5904
5796
|
async getBalances(chainKey, address, tokens, priorityToken) {
|
|
5905
5797
|
const strategy = this.getStrategy(chainKey);
|
|
5906
5798
|
if (!strategy) return {};
|
|
5907
|
-
return await strategy.getBalances(address, tokens, priorityToken);
|
|
5799
|
+
return await strategy.getBalances(address, tokens, chainKey, priorityToken);
|
|
5908
5800
|
}
|
|
5909
5801
|
isAddressValid(chainKey, address) {
|
|
5910
5802
|
const strategy = this.getStrategy(chainKey);
|
|
@@ -6015,14 +5907,9 @@ function parseTonAddress(address) {
|
|
|
6015
5907
|
}
|
|
6016
5908
|
return ton.Address.parse(address);
|
|
6017
5909
|
}
|
|
6018
|
-
async function getEvmBalances(publicClient, address, tokens, priorityToken) {
|
|
5910
|
+
async function getEvmBalances(publicClient, address, tokens, chainKey, priorityToken) {
|
|
6019
5911
|
const balances = {};
|
|
6020
5912
|
try {
|
|
6021
|
-
console.log("start getEvmBalances");
|
|
6022
|
-
console.log("publicClient:", publicClient);
|
|
6023
|
-
console.log("isAddress:", viem.isAddress(address));
|
|
6024
|
-
console.log("tokens:", tokens);
|
|
6025
|
-
console.log("priorityToken:", priorityToken);
|
|
6026
5913
|
if (!address || !viem.isAddress(address)) {
|
|
6027
5914
|
console.warn(`Invalid EVM address provided: ${address}`);
|
|
6028
5915
|
return balances;
|
|
@@ -6031,40 +5918,55 @@ async function getEvmBalances(publicClient, address, tokens, priorityToken) {
|
|
|
6031
5918
|
throw new Error("No public client provided");
|
|
6032
5919
|
}
|
|
6033
5920
|
const nativeTokens = tokens.filter((t) => isNativeAddress(t.address));
|
|
6034
|
-
const erc20Tokens = tokens.filter(
|
|
5921
|
+
const erc20Tokens = tokens.filter(
|
|
5922
|
+
(t) => !isNativeAddress(t.address) && viem.isAddress(t.address)
|
|
5923
|
+
);
|
|
6035
5924
|
if (priorityToken) {
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
const
|
|
6043
|
-
if (
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
5925
|
+
if (priorityToken.chainKey !== chainKey) {
|
|
5926
|
+
console.debug(
|
|
5927
|
+
`Skipping priority token ${priorityToken.symbol}: chain mismatch (expected ${chainKey}, got ${priorityToken.chainKey})`
|
|
5928
|
+
);
|
|
5929
|
+
} else {
|
|
5930
|
+
try {
|
|
5931
|
+
const isPriorityNative = isNativeAddress(priorityToken.address);
|
|
5932
|
+
if (isPriorityNative) {
|
|
5933
|
+
const ethBalance = await publicClient.getBalance({
|
|
5934
|
+
address
|
|
5935
|
+
});
|
|
5936
|
+
const balance = parseFloat(
|
|
5937
|
+
viem.formatUnits(ethBalance, priorityToken.decimals)
|
|
5938
|
+
);
|
|
5939
|
+
if (balance > 0) {
|
|
5940
|
+
balances[priorityToken.symbol] = { balance, address };
|
|
5941
|
+
}
|
|
5942
|
+
} else if (viem.isAddress(priorityToken.address)) {
|
|
5943
|
+
const tokenBalance = await publicClient.readContract({
|
|
5944
|
+
address: priorityToken.address,
|
|
5945
|
+
abi: [
|
|
5946
|
+
{
|
|
5947
|
+
name: "balanceOf",
|
|
5948
|
+
type: "function",
|
|
5949
|
+
stateMutability: "view",
|
|
5950
|
+
inputs: [{ name: "owner", type: "address" }],
|
|
5951
|
+
outputs: [{ name: "balance", type: "uint256" }]
|
|
5952
|
+
}
|
|
5953
|
+
],
|
|
5954
|
+
functionName: "balanceOf",
|
|
5955
|
+
args: [address]
|
|
5956
|
+
});
|
|
5957
|
+
const balance = parseFloat(
|
|
5958
|
+
viem.formatUnits(tokenBalance, priorityToken.decimals)
|
|
5959
|
+
);
|
|
5960
|
+
if (balance > 0) {
|
|
5961
|
+
balances[priorityToken.symbol] = { balance, address };
|
|
5962
|
+
}
|
|
6064
5963
|
}
|
|
5964
|
+
} catch (error) {
|
|
5965
|
+
console.debug(
|
|
5966
|
+
`Failed to get priority token balance for ${priorityToken.symbol}:`,
|
|
5967
|
+
error
|
|
5968
|
+
);
|
|
6065
5969
|
}
|
|
6066
|
-
} catch (error) {
|
|
6067
|
-
console.debug(`Failed to get priority token balance for ${priorityToken.symbol}:`, error);
|
|
6068
5970
|
}
|
|
6069
5971
|
}
|
|
6070
5972
|
for (const token of nativeTokens) {
|
|
@@ -6077,7 +5979,10 @@ async function getEvmBalances(publicClient, address, tokens, priorityToken) {
|
|
|
6077
5979
|
balances[token.symbol] = { balance, address };
|
|
6078
5980
|
}
|
|
6079
5981
|
} catch (error) {
|
|
6080
|
-
console.debug(
|
|
5982
|
+
console.debug(
|
|
5983
|
+
`Failed to get native balance for ${token.symbol}:`,
|
|
5984
|
+
error
|
|
5985
|
+
);
|
|
6081
5986
|
}
|
|
6082
5987
|
}
|
|
6083
5988
|
if (erc20Tokens.length > 0) {
|
|
@@ -6105,17 +6010,25 @@ async function getEvmBalances(publicClient, address, tokens, priorityToken) {
|
|
|
6105
6010
|
if (!token) return;
|
|
6106
6011
|
if (result.status === "success" && result.result !== void 0) {
|
|
6107
6012
|
try {
|
|
6108
|
-
const balance = parseFloat(
|
|
6013
|
+
const balance = parseFloat(
|
|
6014
|
+
viem.formatUnits(result.result, token.decimals)
|
|
6015
|
+
);
|
|
6109
6016
|
if (balance > 0) {
|
|
6110
6017
|
balances[token.symbol] = { balance, address };
|
|
6111
6018
|
}
|
|
6112
6019
|
} catch (error) {
|
|
6113
|
-
console.debug(
|
|
6020
|
+
console.debug(
|
|
6021
|
+
`Failed to parse balance for ${token.symbol}:`,
|
|
6022
|
+
error
|
|
6023
|
+
);
|
|
6114
6024
|
}
|
|
6115
6025
|
}
|
|
6116
6026
|
});
|
|
6117
6027
|
} catch (error) {
|
|
6118
|
-
console.warn(
|
|
6028
|
+
console.warn(
|
|
6029
|
+
"Multicall failed, falling back to individual calls:",
|
|
6030
|
+
error
|
|
6031
|
+
);
|
|
6119
6032
|
for (const token of erc20Tokens) {
|
|
6120
6033
|
try {
|
|
6121
6034
|
const tokenBalance = await publicClient.readContract({
|
|
@@ -6149,7 +6062,7 @@ async function getEvmBalances(publicClient, address, tokens, priorityToken) {
|
|
|
6149
6062
|
}
|
|
6150
6063
|
return balances;
|
|
6151
6064
|
}
|
|
6152
|
-
async function getTonBalances(address, tokens, customTonClient, tonApiKey) {
|
|
6065
|
+
async function getTonBalances(address, tokens, chainKey, customTonClient, tonApiKey) {
|
|
6153
6066
|
const balances = {};
|
|
6154
6067
|
try {
|
|
6155
6068
|
if (!isTonFriendlyAddress(address)) {
|
|
@@ -6308,13 +6221,18 @@ class EvmChainStrategy {
|
|
|
6308
6221
|
getConnectLabel(t) {
|
|
6309
6222
|
return t("wallets.connectEvmWallet");
|
|
6310
6223
|
}
|
|
6311
|
-
async getBalances(address, tokens, priorityToken) {
|
|
6224
|
+
async getBalances(address, tokens, chainKey, priorityToken) {
|
|
6312
6225
|
if (!this.publicClient) {
|
|
6313
6226
|
console.warn("No publicClient available for balance query");
|
|
6314
6227
|
return {};
|
|
6315
6228
|
}
|
|
6316
|
-
|
|
6317
|
-
|
|
6229
|
+
return await getEvmBalances(
|
|
6230
|
+
this.publicClient,
|
|
6231
|
+
address,
|
|
6232
|
+
tokens,
|
|
6233
|
+
chainKey,
|
|
6234
|
+
priorityToken
|
|
6235
|
+
);
|
|
6318
6236
|
}
|
|
6319
6237
|
isAddressValid(address) {
|
|
6320
6238
|
if (!address) return false;
|
|
@@ -6670,10 +6588,11 @@ class TonChainStrategy {
|
|
|
6670
6588
|
getConnectLabel(t) {
|
|
6671
6589
|
return t("wallets.connectTonWallet");
|
|
6672
6590
|
}
|
|
6673
|
-
async getBalances(address, tokens) {
|
|
6591
|
+
async getBalances(address, tokens, chainKey) {
|
|
6674
6592
|
return await getTonBalances(
|
|
6675
6593
|
address,
|
|
6676
6594
|
tokens,
|
|
6595
|
+
chainKey,
|
|
6677
6596
|
this.config.tonClient,
|
|
6678
6597
|
this.config.tonApiKey
|
|
6679
6598
|
);
|
|
@@ -6882,7 +6801,6 @@ class TronChainStrategy {
|
|
|
6882
6801
|
__publicField(this, "config");
|
|
6883
6802
|
this.config = config;
|
|
6884
6803
|
}
|
|
6885
|
-
// ========== Identity ==========
|
|
6886
6804
|
canHandle(chainKey) {
|
|
6887
6805
|
return chainKey.toLowerCase() === "tron";
|
|
6888
6806
|
}
|
|
@@ -6892,7 +6810,6 @@ class TronChainStrategy {
|
|
|
6892
6810
|
getName() {
|
|
6893
6811
|
return "TRON Chain Strategy";
|
|
6894
6812
|
}
|
|
6895
|
-
// ========== Wallet Management ==========
|
|
6896
6813
|
async connect() {
|
|
6897
6814
|
const tronWeb = this.getTronWeb();
|
|
6898
6815
|
if (!tronWeb && (typeof window === "undefined" || !window.tronLink)) {
|
|
@@ -6923,7 +6840,6 @@ class TronChainStrategy {
|
|
|
6923
6840
|
getConnectLabel(t) {
|
|
6924
6841
|
return t("wallets.connectTronWallet");
|
|
6925
6842
|
}
|
|
6926
|
-
// ========== Balance & Validation ==========
|
|
6927
6843
|
async getBalances(address, tokens) {
|
|
6928
6844
|
const tronWeb = this.getTronWeb();
|
|
6929
6845
|
if (!tronWeb) return {};
|
|
@@ -6933,7 +6849,6 @@ class TronChainStrategy {
|
|
|
6933
6849
|
if (!address) return false;
|
|
6934
6850
|
return /^T[1-9A-HJ-NP-Za-km-z]{33}$/.test(address);
|
|
6935
6851
|
}
|
|
6936
|
-
// ========== Gas Estimation ==========
|
|
6937
6852
|
async estimateGasRequirement(params) {
|
|
6938
6853
|
const {
|
|
6939
6854
|
selectedToken,
|
|
@@ -7616,7 +7531,6 @@ const EvaaBridgeContent = ({
|
|
|
7616
7531
|
const { t } = useBridgeTranslation();
|
|
7617
7532
|
useTokensRequest();
|
|
7618
7533
|
useChainsRequest();
|
|
7619
|
-
const [sendToAnother, setSendToAnother] = require$$0.useState(false);
|
|
7620
7534
|
const swap = useSwapModel();
|
|
7621
7535
|
const { fromChain, toChain } = swap;
|
|
7622
7536
|
const { selectedAssetSymbol, assetMatrix } = useTokensStore();
|
|
@@ -7744,13 +7658,7 @@ const EvaaBridgeContent = ({
|
|
|
7744
7658
|
onSelect: handleToChainChange
|
|
7745
7659
|
}
|
|
7746
7660
|
),
|
|
7747
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7748
|
-
ToggleRow,
|
|
7749
|
-
{
|
|
7750
|
-
enabled: sendToAnother,
|
|
7751
|
-
onToggle: () => setSendToAnother((v) => !v)
|
|
7752
|
-
}
|
|
7753
|
-
),
|
|
7661
|
+
/* @__PURE__ */ jsxRuntime.jsx(AnotherAddress, {}),
|
|
7754
7662
|
/* @__PURE__ */ jsxRuntime.jsx(SubmitButton, {})
|
|
7755
7663
|
] }),
|
|
7756
7664
|
/* @__PURE__ */ jsxRuntime.jsx(card.CardFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(Details, {}) })
|
|
@@ -7825,7 +7733,6 @@ exports.addrForApi = addrForApi;
|
|
|
7825
7733
|
exports.buildAssetMatrix = buildAssetMatrix;
|
|
7826
7734
|
exports.calculateMinReceived = calculateMinReceived;
|
|
7827
7735
|
exports.computeFeesUsdFromArray = computeFeesUsdFromArray;
|
|
7828
|
-
exports.dollarsFromNativeFees = dollarsFromNativeFees;
|
|
7829
7736
|
exports.findNativeMeta = findNativeMeta;
|
|
7830
7737
|
exports.formatBalance = formatBalance;
|
|
7831
7738
|
exports.formatHash = formatHash;
|
|
@@ -7844,10 +7751,7 @@ exports.getQuotesByPriority = getQuotesByPriority;
|
|
|
7844
7751
|
exports.getTokens = getTokens;
|
|
7845
7752
|
exports.getTonBalances = getTonBalances;
|
|
7846
7753
|
exports.getTronBalances = getTronBalances;
|
|
7847
|
-
exports.isAddressValidForChain = isAddressValidForChain;
|
|
7848
|
-
exports.isEvmAddress = isEvmAddress;
|
|
7849
7754
|
exports.isNativeAddrEqual = isNativeAddrEqual;
|
|
7850
|
-
exports.isTronAddress = isTronAddress;
|
|
7851
7755
|
exports.isZeroAddr = isZeroAddr;
|
|
7852
7756
|
exports.listAssetsForSelect = listAssetsForSelect;
|
|
7853
7757
|
exports.lookupTokenMeta = lookupTokenMeta;
|