@rash2x/bridge-widget 0.1.13 → 0.1.16
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 +481 -583
- package/dist/evaa-bridge.cjs.map +1 -1
- package/dist/evaa-bridge.mjs +482 -584
- 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,21 +926,21 @@ 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
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-
|
|
937
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm font-medium leading-
|
|
936
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
937
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm font-medium leading-4", children: t("settings.gasOnDestination") }),
|
|
938
938
|
/* @__PURE__ */ jsxRuntime.jsx(Tip, { text: t("settings.gasOnDestination"), children: /* @__PURE__ */ jsxRuntime.jsx(TipIcon, { className: "size-4 text-muted-foreground" }) })
|
|
939
939
|
] }),
|
|
940
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground text-sm font-medium leading-
|
|
940
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground text-sm font-medium leading-4", children: formatUsd(gasUsdValue) })
|
|
941
941
|
] }),
|
|
942
942
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
943
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center w-1/3 gap-
|
|
943
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center w-1/3 gap-2 shrink-0", children: [
|
|
944
944
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
945
945
|
TokenSymbol,
|
|
946
946
|
{
|
|
@@ -953,13 +953,12 @@ const SettingModal = ({ isOpen, onClose }) => {
|
|
|
953
953
|
gasDisplayAmount < 1e-3 ? 6 : 3
|
|
954
954
|
) }) })
|
|
955
955
|
] }),
|
|
956
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-
|
|
957
|
-
|
|
956
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: gasPresets.map((g) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
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}`)
|
|
@@ -971,26 +970,25 @@ const SettingModal = ({ isOpen, onClose }) => {
|
|
|
971
970
|
/* @__PURE__ */ jsxRuntime.jsx("hr", {}),
|
|
972
971
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5", children: [
|
|
973
972
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [
|
|
974
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-
|
|
973
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
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
|
|
@@ -1001,17 +999,16 @@ const SettingModal = ({ isOpen, onClose }) => {
|
|
|
1001
999
|
] }),
|
|
1002
1000
|
/* @__PURE__ */ jsxRuntime.jsx("hr", {}),
|
|
1003
1001
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5", children: [
|
|
1004
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-between items-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-
|
|
1002
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-between items-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1005
1003
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm font-medium leading-3.5", children: t("settings.routePriority") }),
|
|
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-3 px-5 py-4 bg-input rounded-md h-13 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-3 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-8 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
|
-
out.push({
|
|
1567
|
-
kind: "token",
|
|
1568
|
-
key: `my:${token.symbol}`,
|
|
1569
|
-
token,
|
|
1570
|
-
willChangeSrc: false
|
|
1571
|
-
});
|
|
1572
|
-
}
|
|
1573
|
-
return out;
|
|
1574
|
-
}
|
|
1575
|
-
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}`,
|
|
1354
|
+
return myTokens.map((token) => ({
|
|
1583
1355
|
token,
|
|
1584
1356
|
willChangeSrc: false
|
|
1585
|
-
});
|
|
1586
|
-
}
|
|
1587
|
-
if (groupedTokens.willChangeSrcChain.length > 0) {
|
|
1588
|
-
out.push({
|
|
1589
|
-
kind: "header",
|
|
1590
|
-
key: "hdr:willChange",
|
|
1591
|
-
title: t("bridge.willChangeSourceChain")
|
|
1592
|
-
});
|
|
1593
|
-
for (const token of groupedTokens.willChangeSrcChain) {
|
|
1594
|
-
out.push({
|
|
1595
|
-
kind: "token",
|
|
1596
|
-
key: `will:${token.symbol}`,
|
|
1597
|
-
token,
|
|
1598
|
-
willChangeSrc: true
|
|
1599
|
-
});
|
|
1600
|
-
}
|
|
1357
|
+
}));
|
|
1601
1358
|
}
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1359
|
+
const mainTokens = [
|
|
1360
|
+
...groupedTokens.withBalance.map((token) => ({
|
|
1361
|
+
token,
|
|
1362
|
+
willChangeSrc: false
|
|
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-4", 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-2 font-semibold text-muted-foreground uppercase mt-8", 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
|
};
|
|
@@ -1770,7 +1565,7 @@ const SelectTokenButton = ({
|
|
|
1770
1565
|
type: "button",
|
|
1771
1566
|
"aria-label": label,
|
|
1772
1567
|
children: [
|
|
1773
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-
|
|
1568
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 items-center", children: [
|
|
1774
1569
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1775
1570
|
TokenSymbol,
|
|
1776
1571
|
{
|
|
@@ -1779,7 +1574,7 @@ const SelectTokenButton = ({
|
|
|
1779
1574
|
alt: label
|
|
1780
1575
|
}
|
|
1781
1576
|
),
|
|
1782
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-secondary-foreground text-sm
|
|
1577
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-secondary-foreground text-sm font-semibold", children: label })
|
|
1783
1578
|
] }),
|
|
1784
1579
|
/* @__PURE__ */ jsxRuntime.jsx(ArrowDownIcon, { className: "size-4 text-secondary-foreground" })
|
|
1785
1580
|
]
|
|
@@ -1802,12 +1597,12 @@ 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: [
|
|
1806
|
-
/* @__PURE__ */ jsxRuntime.jsxs(card.CardTitle, { className: "flex items-center gap-
|
|
1807
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-normal leading-
|
|
1600
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(card.CardHeader, { className: "gap-y-0 flex flex-row justify-between items-center", children: [
|
|
1601
|
+
/* @__PURE__ */ jsxRuntime.jsxs(card.CardTitle, { className: "flex items-center gap-3", children: [
|
|
1602
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-normal leading-4 text-muted-foreground", children: t("bridge.selectToken") }),
|
|
1808
1603
|
/* @__PURE__ */ jsxRuntime.jsx(SelectTokenButton, { token: current, onClick: onOpen })
|
|
1809
1604
|
] }),
|
|
1810
|
-
/* @__PURE__ */ jsxRuntime.jsxs(card.CardAction, { className: "flex items-center gap-
|
|
1605
|
+
/* @__PURE__ */ jsxRuntime.jsxs(card.CardAction, { className: "flex items-center gap-3", children: [
|
|
1811
1606
|
/* @__PURE__ */ jsxRuntime.jsx(RefreshButton, {}),
|
|
1812
1607
|
/* @__PURE__ */ jsxRuntime.jsx(button.Button, { onClick: onOpenSettings, size: "sm", variant: "secondary", children: /* @__PURE__ */ jsxRuntime.jsx(BoltIcon, { stroke: "currentColor" }) })
|
|
1813
1608
|
] }),
|
|
@@ -1823,16 +1618,23 @@ const FormHeaderComponent = () => {
|
|
|
1823
1618
|
}
|
|
1824
1619
|
}
|
|
1825
1620
|
),
|
|
1826
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1827
|
-
SettingModal,
|
|
1828
|
-
{
|
|
1829
|
-
isOpen: isOpenSettings,
|
|
1830
|
-
onClose: onCloseSettings
|
|
1831
|
-
}
|
|
1832
|
-
)
|
|
1621
|
+
/* @__PURE__ */ jsxRuntime.jsx(SettingModal, { isOpen: isOpenSettings, onClose: onCloseSettings })
|
|
1833
1622
|
] });
|
|
1834
1623
|
};
|
|
1835
1624
|
const FormHeader = require$$0.memo(FormHeaderComponent);
|
|
1625
|
+
function toLD(human, decimals) {
|
|
1626
|
+
const [i = "0", f = ""] = human.replace(",", ".").split(".");
|
|
1627
|
+
const frac = (f + "0".repeat(decimals)).slice(0, decimals);
|
|
1628
|
+
return BigInt(i + frac).toString();
|
|
1629
|
+
}
|
|
1630
|
+
function fromLD(ld, decimals) {
|
|
1631
|
+
const bi = BigInt(ld || "0");
|
|
1632
|
+
if (decimals === 0) return Number(bi);
|
|
1633
|
+
const base = BigInt(10) ** BigInt(decimals);
|
|
1634
|
+
const int = bi / base;
|
|
1635
|
+
const frac = Number(bi % base) / Number(base);
|
|
1636
|
+
return Number(int) + frac;
|
|
1637
|
+
}
|
|
1836
1638
|
async function fetchQuotes(req) {
|
|
1837
1639
|
const params = {
|
|
1838
1640
|
srcChainKey: req.srcChainKey,
|
|
@@ -1891,6 +1693,131 @@ async function getQuotesByPriority(req) {
|
|
|
1891
1693
|
const priority = req.routePriority || RoutePriority.RECOMMENDED;
|
|
1892
1694
|
return selectQuoteByPriority(routes, priority);
|
|
1893
1695
|
}
|
|
1696
|
+
function resolveTokenOnChainFromMatrix$2(assetMatrix, assetSymbol, chainKey) {
|
|
1697
|
+
if (!assetMatrix || !assetSymbol || !chainKey) return void 0;
|
|
1698
|
+
const byChain = assetMatrix[assetSymbol.toUpperCase()];
|
|
1699
|
+
return byChain?.[chainKey];
|
|
1700
|
+
}
|
|
1701
|
+
const DEFAULT_SLIPPAGE_BPS = 50;
|
|
1702
|
+
const lower = (s) => (s ?? "").toLowerCase();
|
|
1703
|
+
const normSym = (s) => (s ?? "").toUpperCase().replace(/₮/g, "T").replace(/[^A-Z0-9]/g, "");
|
|
1704
|
+
function tonNorm(addr) {
|
|
1705
|
+
if (!addr) return null;
|
|
1706
|
+
try {
|
|
1707
|
+
if (addr.includes(":")) {
|
|
1708
|
+
return core.Address.parseRaw(addr).toString({
|
|
1709
|
+
bounceable: false,
|
|
1710
|
+
urlSafe: true
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1713
|
+
return core.Address.parse(addr).toString({ bounceable: false, urlSafe: true });
|
|
1714
|
+
} catch {
|
|
1715
|
+
return null;
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
const isZeroAddr = (a) => (
|
|
1719
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1720
|
+
!!a && /^0x0{40}$/i.test(a) || /^0x[eE]{4}e{36}$/i.test(a)
|
|
1721
|
+
);
|
|
1722
|
+
function addrForApi(chainKey, addr) {
|
|
1723
|
+
if (chainKey === "ton") return tonNorm(addr);
|
|
1724
|
+
return addr;
|
|
1725
|
+
}
|
|
1726
|
+
function isNativeAddrEqual(chain, tokenAddr) {
|
|
1727
|
+
if (!chain) return false;
|
|
1728
|
+
if (!tokenAddr) return false;
|
|
1729
|
+
if (isZeroAddr(tokenAddr)) return true;
|
|
1730
|
+
const nativeAddr = chain.nativeCurrency?.address;
|
|
1731
|
+
if (!nativeAddr) return false;
|
|
1732
|
+
if (chain.chainKey === "ton") {
|
|
1733
|
+
const a = tonNorm(tokenAddr);
|
|
1734
|
+
const b = tonNorm(nativeAddr);
|
|
1735
|
+
return !!a && !!b && a === b;
|
|
1736
|
+
}
|
|
1737
|
+
return lower(nativeAddr) === lower(tokenAddr);
|
|
1738
|
+
}
|
|
1739
|
+
function findNativeMeta(tokens, chain) {
|
|
1740
|
+
if (!chain) return { decimals: 18, priceUsd: void 0 };
|
|
1741
|
+
const sym = normSym(chain.nativeCurrency?.symbol);
|
|
1742
|
+
if (!sym) {
|
|
1743
|
+
return { decimals: chain.chainKey === "ton" ? 9 : 18, priceUsd: void 0 };
|
|
1744
|
+
}
|
|
1745
|
+
const sameChain = tokens?.find(
|
|
1746
|
+
(t) => t.chainKey === chain.chainKey && normSym(t.symbol) === sym
|
|
1747
|
+
) ?? void 0;
|
|
1748
|
+
if (sameChain)
|
|
1749
|
+
return { decimals: sameChain.decimals, priceUsd: sameChain.price?.usd };
|
|
1750
|
+
const anyChain = tokens?.find((t) => normSym(t.symbol) === sym);
|
|
1751
|
+
if (anyChain)
|
|
1752
|
+
return { decimals: anyChain.decimals, priceUsd: anyChain.price?.usd };
|
|
1753
|
+
return { decimals: chain.chainKey === "ton" ? 9 : 18, priceUsd: void 0 };
|
|
1754
|
+
}
|
|
1755
|
+
function lookupTokenMeta(tokens, chains, chainKey, tokenAddr) {
|
|
1756
|
+
if (!chainKey) return { decimals: 18, priceUsd: void 0 };
|
|
1757
|
+
const chain = chains?.find((c) => c.chainKey === chainKey);
|
|
1758
|
+
const hit = tokens?.find((t) => {
|
|
1759
|
+
if (t.chainKey !== chainKey) return false;
|
|
1760
|
+
if (chainKey === "ton") {
|
|
1761
|
+
const a = tonNorm(t.address);
|
|
1762
|
+
const b = tonNorm(tokenAddr);
|
|
1763
|
+
return !!a && !!b && a === b;
|
|
1764
|
+
}
|
|
1765
|
+
return lower(t.address) === lower(tokenAddr);
|
|
1766
|
+
}) ?? void 0;
|
|
1767
|
+
if (hit) return { decimals: hit.decimals, priceUsd: hit.price?.usd };
|
|
1768
|
+
if (isNativeAddrEqual(chain, tokenAddr)) {
|
|
1769
|
+
return findNativeMeta(tokens, chain);
|
|
1770
|
+
}
|
|
1771
|
+
return { decimals: chainKey === "ton" ? 9 : 18, priceUsd: void 0 };
|
|
1772
|
+
}
|
|
1773
|
+
function computeFeesUsdFromArray(fees, tokens, chains) {
|
|
1774
|
+
if (!fees?.length) return { totalUsd: 0 };
|
|
1775
|
+
let total = 0;
|
|
1776
|
+
let protocolFeeUsd = 0;
|
|
1777
|
+
let messageFeeUsd = 0;
|
|
1778
|
+
const byType = /* @__PURE__ */ new Map();
|
|
1779
|
+
for (const f of fees) {
|
|
1780
|
+
let usd = Number(f.usd ?? 0);
|
|
1781
|
+
if (!usd) {
|
|
1782
|
+
const { decimals, priceUsd } = lookupTokenMeta(
|
|
1783
|
+
tokens,
|
|
1784
|
+
chains,
|
|
1785
|
+
f.chainKey,
|
|
1786
|
+
f.token
|
|
1787
|
+
);
|
|
1788
|
+
const human = fromLD(String(f.amount ?? "0"), decimals);
|
|
1789
|
+
usd = (priceUsd ?? 0) * human;
|
|
1790
|
+
}
|
|
1791
|
+
total += usd;
|
|
1792
|
+
const type = (f.type ?? "other").toLowerCase();
|
|
1793
|
+
byType.set(type, (byType.get(type) ?? 0) + usd);
|
|
1794
|
+
if (type === "protocol" || type === "service") {
|
|
1795
|
+
protocolFeeUsd += usd;
|
|
1796
|
+
} else if (type === "message" || type === "gas" || type === "network") {
|
|
1797
|
+
messageFeeUsd += usd;
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
const serviceUsd = byType.get("protocol") ?? byType.get("service") ?? void 0;
|
|
1801
|
+
const blockchainUsd = byType.get("gas") ?? byType.get("network") ?? byType.get("message") ?? void 0;
|
|
1802
|
+
return {
|
|
1803
|
+
totalUsd: total,
|
|
1804
|
+
protocolFeeUsd: protocolFeeUsd > 0 ? protocolFeeUsd : void 0,
|
|
1805
|
+
messageFeeUsd: messageFeeUsd > 0 ? messageFeeUsd : void 0,
|
|
1806
|
+
serviceUsd,
|
|
1807
|
+
blockchainUsd
|
|
1808
|
+
};
|
|
1809
|
+
}
|
|
1810
|
+
function sumFeeByTokenLD(fees, dstTokenAddr, dstChainKey) {
|
|
1811
|
+
if (!fees?.length || !dstTokenAddr || !dstChainKey) return "0";
|
|
1812
|
+
let acc = 0n;
|
|
1813
|
+
for (const f of fees) {
|
|
1814
|
+
if (f.chainKey !== dstChainKey) continue;
|
|
1815
|
+
const same = dstChainKey === "ton" ? tonNorm(f.token) === tonNorm(dstTokenAddr) : lower(f.token) === lower(dstTokenAddr);
|
|
1816
|
+
if (!same) continue;
|
|
1817
|
+
acc += BigInt(f.amount ?? "0");
|
|
1818
|
+
}
|
|
1819
|
+
return acc.toString();
|
|
1820
|
+
}
|
|
1894
1821
|
function useBridgeQuote() {
|
|
1895
1822
|
const { assetMatrix, selectedAssetSymbol } = useTokensStore();
|
|
1896
1823
|
const { fromChain, toChain } = useChainsStore();
|
|
@@ -2268,14 +2195,14 @@ const SwapButton = () => {
|
|
|
2268
2195
|
const WalletBalance = (props) => {
|
|
2269
2196
|
const { value, isLoading = false } = props;
|
|
2270
2197
|
if (isLoading) {
|
|
2271
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-
|
|
2198
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 items-center", children: [
|
|
2272
2199
|
/* @__PURE__ */ jsxRuntime.jsx(WalletIcon, { className: "text-muted-foreground" }),
|
|
2273
2200
|
/* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-16 rounded-md" })
|
|
2274
2201
|
] });
|
|
2275
2202
|
}
|
|
2276
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-
|
|
2203
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 items-center", children: [
|
|
2277
2204
|
/* @__PURE__ */ jsxRuntime.jsx(WalletIcon, { className: "text-muted-foreground" }),
|
|
2278
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-
|
|
2205
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-5 font-medium text-muted-foreground", children: value })
|
|
2279
2206
|
] });
|
|
2280
2207
|
};
|
|
2281
2208
|
const BASE_URL = "https://icons-ckg.pages.dev/stargate-light/networks";
|
|
@@ -2305,7 +2232,7 @@ const SelectNetworkButton = ({
|
|
|
2305
2232
|
type: "button",
|
|
2306
2233
|
"aria-label": label,
|
|
2307
2234
|
children: [
|
|
2308
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-
|
|
2235
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 items-center", children: [
|
|
2309
2236
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2310
2237
|
NetworkSymbol,
|
|
2311
2238
|
{
|
|
@@ -2314,7 +2241,7 @@ const SelectNetworkButton = ({
|
|
|
2314
2241
|
alt: label
|
|
2315
2242
|
}
|
|
2316
2243
|
),
|
|
2317
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-secondary-foreground text-sm leading-
|
|
2244
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-secondary-foreground text-sm leading-5 font-semibold ", children: label })
|
|
2318
2245
|
] }),
|
|
2319
2246
|
/* @__PURE__ */ jsxRuntime.jsx(ArrowDownIcon, { className: "size-4 text-secondary-foreground" })
|
|
2320
2247
|
]
|
|
@@ -2372,7 +2299,7 @@ const CurrencyInput = require$$0.forwardRef(
|
|
|
2372
2299
|
pattern: "[0-9]*[.,]?[0-9]*",
|
|
2373
2300
|
readOnly,
|
|
2374
2301
|
className: utils.cn(
|
|
2375
|
-
"text-[32px] h-
|
|
2302
|
+
"text-[32px] h-12 font-medium leading-9 rounded-none text-end bg-transparent dark:bg-transparent text-foreground shadow-none border-none outline-none ring-0 focus:outline-none",
|
|
2376
2303
|
className
|
|
2377
2304
|
),
|
|
2378
2305
|
max,
|
|
@@ -2391,12 +2318,10 @@ const ChainSelectModal = ({
|
|
|
2391
2318
|
}) => {
|
|
2392
2319
|
const { t } = useBridgeTranslation();
|
|
2393
2320
|
const [query, setQuery] = require$$0.useState("");
|
|
2394
|
-
const [isFocused, setIsFocused] = require$$0.useState(false);
|
|
2395
2321
|
const { setFromChain, chains, fromChain, toChain } = useChainsStore();
|
|
2396
2322
|
const { assetMatrix, selectedAssetSymbol } = useTokensStore();
|
|
2397
2323
|
const handleClose = require$$0.useCallback(() => {
|
|
2398
2324
|
setQuery("");
|
|
2399
|
-
setIsFocused(false);
|
|
2400
2325
|
onClose();
|
|
2401
2326
|
}, [onClose]);
|
|
2402
2327
|
const findCompatibleSrcChain = require$$0.useCallback(
|
|
@@ -2456,8 +2381,8 @@ const ChainSelectModal = ({
|
|
|
2456
2381
|
button.Button,
|
|
2457
2382
|
{
|
|
2458
2383
|
onClick: () => onChainPick(chain, willChangeSrc),
|
|
2459
|
-
className: `w-full cursor-pointer flex shadow-none items-center justify-between gap-
|
|
2460
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-
|
|
2384
|
+
className: `w-full cursor-pointer flex shadow-none items-center justify-between gap-3 px-5 py-3.5 h-12.5 font-extrabold capitalize hover:bg-muted bg-transparent rounded-md transition-[300] ${isSelected ? "border border-ring" : ""}`,
|
|
2385
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2461
2386
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2462
2387
|
NetworkSymbol,
|
|
2463
2388
|
{
|
|
@@ -2472,26 +2397,16 @@ const ChainSelectModal = ({
|
|
|
2472
2397
|
chain.chainKey
|
|
2473
2398
|
);
|
|
2474
2399
|
};
|
|
2475
|
-
return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { className: "!
|
|
2400
|
+
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
2401
|
/* @__PURE__ */ jsxRuntime.jsx(dialog.DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: t("bridge.selectNetwork") }) }),
|
|
2477
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2478
|
-
|
|
2402
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2403
|
+
SearchInput,
|
|
2479
2404
|
{
|
|
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
|
-
]
|
|
2405
|
+
placeholder: t("bridge.searchDestinationChain"),
|
|
2406
|
+
value: query,
|
|
2407
|
+
onChange: setQuery,
|
|
2408
|
+
containerClassName: "rounded-md",
|
|
2409
|
+
className: "text-foreground placeholder:text-muted-foreground"
|
|
2495
2410
|
}
|
|
2496
2411
|
),
|
|
2497
2412
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto", children: [
|
|
@@ -2516,9 +2431,9 @@ function short$1(addr) {
|
|
|
2516
2431
|
return addr.slice(0, 4) + "…" + addr.slice(-4);
|
|
2517
2432
|
}
|
|
2518
2433
|
const prefixIcons = {
|
|
2519
|
-
tronlink: /* @__PURE__ */ jsxRuntime.jsx(TronLinkIcon, { className: "size-
|
|
2520
|
-
metamask: /* @__PURE__ */ jsxRuntime.jsx(MetaMaskIcon, { className: "size-
|
|
2521
|
-
ton: /* @__PURE__ */ jsxRuntime.jsx(TonKeeperIcon, { className: "size-
|
|
2434
|
+
tronlink: /* @__PURE__ */ jsxRuntime.jsx(TronLinkIcon, { className: "size-5" }),
|
|
2435
|
+
metamask: /* @__PURE__ */ jsxRuntime.jsx(MetaMaskIcon, { className: "size-5" }),
|
|
2436
|
+
ton: /* @__PURE__ */ jsxRuntime.jsx(TonKeeperIcon, { className: "size-5" })
|
|
2522
2437
|
};
|
|
2523
2438
|
const mapWalletToType = (wallet) => {
|
|
2524
2439
|
switch (wallet) {
|
|
@@ -2567,7 +2482,7 @@ const WalletButton = ({
|
|
|
2567
2482
|
e.preventDefault();
|
|
2568
2483
|
},
|
|
2569
2484
|
disabled: isButtonDisabled,
|
|
2570
|
-
className: "p-0 !px-0 py-0 flex gap-1 cursor-pointer shadow-none hover:bg-transparent bg-transparent rounded-none h-
|
|
2485
|
+
className: "p-0 !px-0 py-0 flex gap-1 cursor-pointer shadow-none hover:bg-transparent bg-transparent rounded-none h-5",
|
|
2571
2486
|
children: [
|
|
2572
2487
|
isConnected ? prefixIcons[wallet] : null,
|
|
2573
2488
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "leading-4 text-sm font-medium text-link border-b-2 border-dotted border-link", children: buttonText })
|
|
@@ -2643,7 +2558,7 @@ const SwapSection = ({
|
|
|
2643
2558
|
),
|
|
2644
2559
|
children: [
|
|
2645
2560
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [
|
|
2646
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-
|
|
2561
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-5 font-medium text-muted-foreground", children: label }),
|
|
2647
2562
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2648
2563
|
WalletBalance,
|
|
2649
2564
|
{
|
|
@@ -2706,63 +2621,30 @@ const useCustomAddressStore = zustand.create((set) => ({
|
|
|
2706
2621
|
setCustomDstAddress: (address) => set({ customDstAddress: address }),
|
|
2707
2622
|
clearCustomDstAddress: () => set({ customDstAddress: void 0 })
|
|
2708
2623
|
}));
|
|
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
|
-
}
|
|
2624
|
+
const useIsAddressValid = (address, chainKey) => {
|
|
2625
|
+
const isValid = require$$0.useMemo(() => {
|
|
2626
|
+
return isAddressValidForChain(chainKey, address);
|
|
2627
|
+
}, [address, chainKey]);
|
|
2628
|
+
return { isValid };
|
|
2722
2629
|
};
|
|
2723
|
-
const
|
|
2630
|
+
const AnotherAddress = () => {
|
|
2631
|
+
const [enabled, setEnabled] = require$$0.useState(false);
|
|
2632
|
+
const [isFocused, setIsFocused] = require$$0.useState(false);
|
|
2724
2633
|
const { t } = useBridgeTranslation();
|
|
2725
2634
|
const { toChain } = useChainsStore();
|
|
2726
|
-
const {
|
|
2727
|
-
const { setCustomDstAddress, clearCustomDstAddress } = useCustomAddressStore();
|
|
2635
|
+
const { setCustomDstAddress } = useCustomAddressStore();
|
|
2728
2636
|
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]);
|
|
2637
|
+
const { isValid } = useIsAddressValid(value.trim(), toChain?.chainKey);
|
|
2638
|
+
const invalid = value.trim() && !isValid;
|
|
2745
2639
|
const pushToStoreIfValid = (raw) => {
|
|
2746
2640
|
if (!enabled) return;
|
|
2747
2641
|
const v = raw.trim();
|
|
2748
2642
|
if (!v) {
|
|
2749
2643
|
setCustomDstAddress(void 0);
|
|
2750
|
-
setInvalid(false);
|
|
2751
|
-
return;
|
|
2752
|
-
}
|
|
2753
|
-
const ck = toChain?.chainKey;
|
|
2754
|
-
if (!ck) {
|
|
2755
|
-
setInvalid(true);
|
|
2756
2644
|
return;
|
|
2757
2645
|
}
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
if (valid && valueForStore) {
|
|
2761
|
-
setInvalid(false);
|
|
2762
|
-
setCustomDstAddress(valueForStore);
|
|
2763
|
-
if (ck === "ton") setValue(valueForStore);
|
|
2764
|
-
} else {
|
|
2765
|
-
setInvalid(true);
|
|
2646
|
+
if (isValid) {
|
|
2647
|
+
setCustomDstAddress(v);
|
|
2766
2648
|
}
|
|
2767
2649
|
};
|
|
2768
2650
|
const onChange = (text) => {
|
|
@@ -2777,16 +2659,16 @@ const ToggleRow = ({ enabled, onToggle }) => {
|
|
|
2777
2659
|
} catch {
|
|
2778
2660
|
}
|
|
2779
2661
|
};
|
|
2780
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 flex flex-col rounded-b-lg
|
|
2662
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 flex flex-col rounded-b-lg bg-muted", children: [
|
|
2781
2663
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2782
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm leading-
|
|
2664
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm leading-5 font-medium text-muted-foreground", children: t("bridge.sendToAnotherAddress") }),
|
|
2783
2665
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2784
2666
|
_switch.Switch,
|
|
2785
2667
|
{
|
|
2786
2668
|
className: "data-[state=unchecked]:bg-switch-inactive data-[state=checked]:bg-switch-active",
|
|
2787
2669
|
"aria-pressed": enabled,
|
|
2788
2670
|
checked: enabled,
|
|
2789
|
-
onClick:
|
|
2671
|
+
onClick: () => setEnabled((v) => !v)
|
|
2790
2672
|
}
|
|
2791
2673
|
)
|
|
2792
2674
|
] }),
|
|
@@ -2801,16 +2683,27 @@ const ToggleRow = ({ enabled, onToggle }) => {
|
|
|
2801
2683
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2802
2684
|
"div",
|
|
2803
2685
|
{
|
|
2804
|
-
className:
|
|
2686
|
+
className: utils.cn(
|
|
2687
|
+
"bg-input py-2 px-4 mt-2 w-full flex items-center gap-4 rounded-md justify-between border border-transparent transition-all",
|
|
2688
|
+
{
|
|
2689
|
+
"py-4": value,
|
|
2690
|
+
"border border-ring": isFocused,
|
|
2691
|
+
"border-destructive": invalid
|
|
2692
|
+
}
|
|
2693
|
+
),
|
|
2805
2694
|
children: [
|
|
2806
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-
|
|
2695
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 w-full", children: [
|
|
2807
2696
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2808
2697
|
input.Input,
|
|
2809
2698
|
{
|
|
2810
|
-
className:
|
|
2811
|
-
|
|
2699
|
+
className: utils.cn(
|
|
2700
|
+
"p-0 h-auto text-base leading-5 font-semibold w-full bg-transparent dark:bg-transparent placeholder:text-muted-foreground/50 border-none"
|
|
2701
|
+
),
|
|
2702
|
+
placeholder: t("bridge.anotherAddressPlaceholder"),
|
|
2812
2703
|
type: "text",
|
|
2813
2704
|
value,
|
|
2705
|
+
onFocus: () => setIsFocused(true),
|
|
2706
|
+
onBlur: () => setIsFocused(false),
|
|
2814
2707
|
onChange: (e) => onChange(e.target.value)
|
|
2815
2708
|
}
|
|
2816
2709
|
),
|
|
@@ -2820,21 +2713,14 @@ const ToggleRow = ({ enabled, onToggle }) => {
|
|
|
2820
2713
|
defaultValue: "Check correctness before transfer"
|
|
2821
2714
|
}) }) })
|
|
2822
2715
|
] }),
|
|
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(
|
|
2716
|
+
!value ? /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "secondary", size: "sm", onClick: onPaste, children: t("common.paste") }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2832
2717
|
button.Button,
|
|
2833
2718
|
{
|
|
2834
2719
|
variant: "ghost",
|
|
2835
|
-
|
|
2720
|
+
size: "sm",
|
|
2721
|
+
className: "rounded-full p-0 size-5 self-start",
|
|
2836
2722
|
onClick: () => setValue(""),
|
|
2837
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-
|
|
2723
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4" })
|
|
2838
2724
|
}
|
|
2839
2725
|
)
|
|
2840
2726
|
]
|
|
@@ -2993,10 +2879,10 @@ const Details = () => {
|
|
|
2993
2879
|
const routeText = quote?.route ? getRouteDisplayName(quote.route) : t(`settings.routePresets.${routePriority}`);
|
|
2994
2880
|
return /* @__PURE__ */ jsxRuntime.jsx(accordion.Accordion, { type: "single", collapsible: true, className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(accordion.AccordionItem, { value: "item-1", className: "bg-muted rounded-lg", children: [
|
|
2995
2881
|
/* @__PURE__ */ jsxRuntime.jsx(accordion.AccordionTrigger, { className: "w-full gap-1 items-center py-6 px-5 rounded-b-lg data-[state=open]:pb-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex items-center justify-between", children: [
|
|
2996
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-normal text-priority leading-
|
|
2997
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-transparent hover:bg-transparent shadow-none h-4 p-0 px-0 py-0 flex items-center gap-
|
|
2882
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-normal text-priority leading-4", children: t("bridge.youWillReceive", { defaultValue: "You will receive" }) }),
|
|
2883
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-transparent hover:bg-transparent shadow-none h-4 p-0 px-0 py-0 flex items-center gap-2", children: [
|
|
2998
2884
|
/* @__PURE__ */ jsxRuntime.jsx(TokenSymbol, { symbol, className: "w-4 h-4", alt: "token" }),
|
|
2999
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-24 rounded-md" }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-semibold leading-
|
|
2885
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-24 rounded-md" }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-semibold leading-4 text-foreground", children: [
|
|
3000
2886
|
receiveText,
|
|
3001
2887
|
" ",
|
|
3002
2888
|
symbol
|
|
@@ -3008,7 +2894,7 @@ const Details = () => {
|
|
|
3008
2894
|
DetailsRow,
|
|
3009
2895
|
{
|
|
3010
2896
|
label: t("transaction.route"),
|
|
3011
|
-
value: /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "flex items-center gap-
|
|
2897
|
+
value: /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "flex items-center gap-2", children: [
|
|
3012
2898
|
/* @__PURE__ */ jsxRuntime.jsx(StargateIcon, { className: "size-4" }),
|
|
3013
2899
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "", children: routeText })
|
|
3014
2900
|
] })
|
|
@@ -3048,7 +2934,7 @@ const DetailsRow = ({
|
|
|
3048
2934
|
value,
|
|
3049
2935
|
isLoading = false
|
|
3050
2936
|
}) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [
|
|
3051
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-
|
|
2937
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3052
2938
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-priority font-normal", children: label }),
|
|
3053
2939
|
/* @__PURE__ */ jsxRuntime.jsx(Tip, { text: label, children: /* @__PURE__ */ jsxRuntime.jsx(TipIcon, { className: "size-4 text-receive-icon" }) })
|
|
3054
2940
|
] }),
|
|
@@ -3812,9 +3698,9 @@ const WalletSelectModal = () => {
|
|
|
3812
3698
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2 font-semibold text-muted-foreground uppercase", children: t("wallets.connected") }),
|
|
3813
3699
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "", children: connectedWallets.map((wallet) => {
|
|
3814
3700
|
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-
|
|
3816
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-
|
|
3817
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
3701
|
+
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-3 px-5 py-3 hover:bg-muted h-auto rounded-md transition-[300]", children: [
|
|
3702
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
3703
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-8 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "size-8" }) }),
|
|
3818
3704
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start min-w-0", children: [
|
|
3819
3705
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-extrabold text-foreground text-sm leading-4 truncate", children: short(wallet.address) }),
|
|
3820
3706
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs leading-3 font-semibold text-muted-foreground", children: wallet.name })
|
|
@@ -3853,9 +3739,9 @@ const WalletSelectModal = () => {
|
|
|
3853
3739
|
}
|
|
3854
3740
|
},
|
|
3855
3741
|
disabled: isEvmConnector ? isPending : !wallet.enabled,
|
|
3856
|
-
className: "w-full cursor-pointer bg-transparent flex shadow-none items-center justify-between gap-
|
|
3742
|
+
className: "w-full cursor-pointer bg-transparent flex shadow-none items-center justify-between gap-3 px-5 py-3 hover:bg-muted h-auto rounded-md transition-[300] disabled:opacity-50 disabled:cursor-not-allowed",
|
|
3857
3743
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
3858
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-
|
|
3744
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "size-8" }) }),
|
|
3859
3745
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start min-w-0", children: [
|
|
3860
3746
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-extrabold text-foreground text-sm leading-4 truncate", children: wallet.name }),
|
|
3861
3747
|
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") })
|
|
@@ -5904,7 +5790,7 @@ class ChainStrategyRegistry {
|
|
|
5904
5790
|
async getBalances(chainKey, address, tokens, priorityToken) {
|
|
5905
5791
|
const strategy = this.getStrategy(chainKey);
|
|
5906
5792
|
if (!strategy) return {};
|
|
5907
|
-
return await strategy.getBalances(address, tokens, priorityToken);
|
|
5793
|
+
return await strategy.getBalances(address, tokens, chainKey, priorityToken);
|
|
5908
5794
|
}
|
|
5909
5795
|
isAddressValid(chainKey, address) {
|
|
5910
5796
|
const strategy = this.getStrategy(chainKey);
|
|
@@ -6015,14 +5901,9 @@ function parseTonAddress(address) {
|
|
|
6015
5901
|
}
|
|
6016
5902
|
return ton.Address.parse(address);
|
|
6017
5903
|
}
|
|
6018
|
-
async function getEvmBalances(publicClient, address, tokens, priorityToken) {
|
|
5904
|
+
async function getEvmBalances(publicClient, address, tokens, chainKey, priorityToken) {
|
|
6019
5905
|
const balances = {};
|
|
6020
5906
|
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
5907
|
if (!address || !viem.isAddress(address)) {
|
|
6027
5908
|
console.warn(`Invalid EVM address provided: ${address}`);
|
|
6028
5909
|
return balances;
|
|
@@ -6031,40 +5912,55 @@ async function getEvmBalances(publicClient, address, tokens, priorityToken) {
|
|
|
6031
5912
|
throw new Error("No public client provided");
|
|
6032
5913
|
}
|
|
6033
5914
|
const nativeTokens = tokens.filter((t) => isNativeAddress(t.address));
|
|
6034
|
-
const erc20Tokens = tokens.filter(
|
|
5915
|
+
const erc20Tokens = tokens.filter(
|
|
5916
|
+
(t) => !isNativeAddress(t.address) && viem.isAddress(t.address)
|
|
5917
|
+
);
|
|
6035
5918
|
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
|
-
|
|
5919
|
+
if (priorityToken.chainKey !== chainKey) {
|
|
5920
|
+
console.debug(
|
|
5921
|
+
`Skipping priority token ${priorityToken.symbol}: chain mismatch (expected ${chainKey}, got ${priorityToken.chainKey})`
|
|
5922
|
+
);
|
|
5923
|
+
} else {
|
|
5924
|
+
try {
|
|
5925
|
+
const isPriorityNative = isNativeAddress(priorityToken.address);
|
|
5926
|
+
if (isPriorityNative) {
|
|
5927
|
+
const ethBalance = await publicClient.getBalance({
|
|
5928
|
+
address
|
|
5929
|
+
});
|
|
5930
|
+
const balance = parseFloat(
|
|
5931
|
+
viem.formatUnits(ethBalance, priorityToken.decimals)
|
|
5932
|
+
);
|
|
5933
|
+
if (balance > 0) {
|
|
5934
|
+
balances[priorityToken.symbol] = { balance, address };
|
|
5935
|
+
}
|
|
5936
|
+
} else if (viem.isAddress(priorityToken.address)) {
|
|
5937
|
+
const tokenBalance = await publicClient.readContract({
|
|
5938
|
+
address: priorityToken.address,
|
|
5939
|
+
abi: [
|
|
5940
|
+
{
|
|
5941
|
+
name: "balanceOf",
|
|
5942
|
+
type: "function",
|
|
5943
|
+
stateMutability: "view",
|
|
5944
|
+
inputs: [{ name: "owner", type: "address" }],
|
|
5945
|
+
outputs: [{ name: "balance", type: "uint256" }]
|
|
5946
|
+
}
|
|
5947
|
+
],
|
|
5948
|
+
functionName: "balanceOf",
|
|
5949
|
+
args: [address]
|
|
5950
|
+
});
|
|
5951
|
+
const balance = parseFloat(
|
|
5952
|
+
viem.formatUnits(tokenBalance, priorityToken.decimals)
|
|
5953
|
+
);
|
|
5954
|
+
if (balance > 0) {
|
|
5955
|
+
balances[priorityToken.symbol] = { balance, address };
|
|
5956
|
+
}
|
|
6064
5957
|
}
|
|
5958
|
+
} catch (error) {
|
|
5959
|
+
console.debug(
|
|
5960
|
+
`Failed to get priority token balance for ${priorityToken.symbol}:`,
|
|
5961
|
+
error
|
|
5962
|
+
);
|
|
6065
5963
|
}
|
|
6066
|
-
} catch (error) {
|
|
6067
|
-
console.debug(`Failed to get priority token balance for ${priorityToken.symbol}:`, error);
|
|
6068
5964
|
}
|
|
6069
5965
|
}
|
|
6070
5966
|
for (const token of nativeTokens) {
|
|
@@ -6077,7 +5973,10 @@ async function getEvmBalances(publicClient, address, tokens, priorityToken) {
|
|
|
6077
5973
|
balances[token.symbol] = { balance, address };
|
|
6078
5974
|
}
|
|
6079
5975
|
} catch (error) {
|
|
6080
|
-
console.debug(
|
|
5976
|
+
console.debug(
|
|
5977
|
+
`Failed to get native balance for ${token.symbol}:`,
|
|
5978
|
+
error
|
|
5979
|
+
);
|
|
6081
5980
|
}
|
|
6082
5981
|
}
|
|
6083
5982
|
if (erc20Tokens.length > 0) {
|
|
@@ -6105,17 +6004,25 @@ async function getEvmBalances(publicClient, address, tokens, priorityToken) {
|
|
|
6105
6004
|
if (!token) return;
|
|
6106
6005
|
if (result.status === "success" && result.result !== void 0) {
|
|
6107
6006
|
try {
|
|
6108
|
-
const balance = parseFloat(
|
|
6007
|
+
const balance = parseFloat(
|
|
6008
|
+
viem.formatUnits(result.result, token.decimals)
|
|
6009
|
+
);
|
|
6109
6010
|
if (balance > 0) {
|
|
6110
6011
|
balances[token.symbol] = { balance, address };
|
|
6111
6012
|
}
|
|
6112
6013
|
} catch (error) {
|
|
6113
|
-
console.debug(
|
|
6014
|
+
console.debug(
|
|
6015
|
+
`Failed to parse balance for ${token.symbol}:`,
|
|
6016
|
+
error
|
|
6017
|
+
);
|
|
6114
6018
|
}
|
|
6115
6019
|
}
|
|
6116
6020
|
});
|
|
6117
6021
|
} catch (error) {
|
|
6118
|
-
console.warn(
|
|
6022
|
+
console.warn(
|
|
6023
|
+
"Multicall failed, falling back to individual calls:",
|
|
6024
|
+
error
|
|
6025
|
+
);
|
|
6119
6026
|
for (const token of erc20Tokens) {
|
|
6120
6027
|
try {
|
|
6121
6028
|
const tokenBalance = await publicClient.readContract({
|
|
@@ -6149,7 +6056,7 @@ async function getEvmBalances(publicClient, address, tokens, priorityToken) {
|
|
|
6149
6056
|
}
|
|
6150
6057
|
return balances;
|
|
6151
6058
|
}
|
|
6152
|
-
async function getTonBalances(address, tokens, customTonClient, tonApiKey) {
|
|
6059
|
+
async function getTonBalances(address, tokens, chainKey, customTonClient, tonApiKey) {
|
|
6153
6060
|
const balances = {};
|
|
6154
6061
|
try {
|
|
6155
6062
|
if (!isTonFriendlyAddress(address)) {
|
|
@@ -6308,13 +6215,18 @@ class EvmChainStrategy {
|
|
|
6308
6215
|
getConnectLabel(t) {
|
|
6309
6216
|
return t("wallets.connectEvmWallet");
|
|
6310
6217
|
}
|
|
6311
|
-
async getBalances(address, tokens, priorityToken) {
|
|
6218
|
+
async getBalances(address, tokens, chainKey, priorityToken) {
|
|
6312
6219
|
if (!this.publicClient) {
|
|
6313
6220
|
console.warn("No publicClient available for balance query");
|
|
6314
6221
|
return {};
|
|
6315
6222
|
}
|
|
6316
|
-
|
|
6317
|
-
|
|
6223
|
+
return await getEvmBalances(
|
|
6224
|
+
this.publicClient,
|
|
6225
|
+
address,
|
|
6226
|
+
tokens,
|
|
6227
|
+
chainKey,
|
|
6228
|
+
priorityToken
|
|
6229
|
+
);
|
|
6318
6230
|
}
|
|
6319
6231
|
isAddressValid(address) {
|
|
6320
6232
|
if (!address) return false;
|
|
@@ -6670,10 +6582,11 @@ class TonChainStrategy {
|
|
|
6670
6582
|
getConnectLabel(t) {
|
|
6671
6583
|
return t("wallets.connectTonWallet");
|
|
6672
6584
|
}
|
|
6673
|
-
async getBalances(address, tokens) {
|
|
6585
|
+
async getBalances(address, tokens, chainKey) {
|
|
6674
6586
|
return await getTonBalances(
|
|
6675
6587
|
address,
|
|
6676
6588
|
tokens,
|
|
6589
|
+
chainKey,
|
|
6677
6590
|
this.config.tonClient,
|
|
6678
6591
|
this.config.tonApiKey
|
|
6679
6592
|
);
|
|
@@ -6882,7 +6795,6 @@ class TronChainStrategy {
|
|
|
6882
6795
|
__publicField(this, "config");
|
|
6883
6796
|
this.config = config;
|
|
6884
6797
|
}
|
|
6885
|
-
// ========== Identity ==========
|
|
6886
6798
|
canHandle(chainKey) {
|
|
6887
6799
|
return chainKey.toLowerCase() === "tron";
|
|
6888
6800
|
}
|
|
@@ -6892,7 +6804,6 @@ class TronChainStrategy {
|
|
|
6892
6804
|
getName() {
|
|
6893
6805
|
return "TRON Chain Strategy";
|
|
6894
6806
|
}
|
|
6895
|
-
// ========== Wallet Management ==========
|
|
6896
6807
|
async connect() {
|
|
6897
6808
|
const tronWeb = this.getTronWeb();
|
|
6898
6809
|
if (!tronWeb && (typeof window === "undefined" || !window.tronLink)) {
|
|
@@ -6923,7 +6834,6 @@ class TronChainStrategy {
|
|
|
6923
6834
|
getConnectLabel(t) {
|
|
6924
6835
|
return t("wallets.connectTronWallet");
|
|
6925
6836
|
}
|
|
6926
|
-
// ========== Balance & Validation ==========
|
|
6927
6837
|
async getBalances(address, tokens) {
|
|
6928
6838
|
const tronWeb = this.getTronWeb();
|
|
6929
6839
|
if (!tronWeb) return {};
|
|
@@ -6933,7 +6843,6 @@ class TronChainStrategy {
|
|
|
6933
6843
|
if (!address) return false;
|
|
6934
6844
|
return /^T[1-9A-HJ-NP-Za-km-z]{33}$/.test(address);
|
|
6935
6845
|
}
|
|
6936
|
-
// ========== Gas Estimation ==========
|
|
6937
6846
|
async estimateGasRequirement(params) {
|
|
6938
6847
|
const {
|
|
6939
6848
|
selectedToken,
|
|
@@ -7616,7 +7525,6 @@ const EvaaBridgeContent = ({
|
|
|
7616
7525
|
const { t } = useBridgeTranslation();
|
|
7617
7526
|
useTokensRequest();
|
|
7618
7527
|
useChainsRequest();
|
|
7619
|
-
const [sendToAnother, setSendToAnother] = require$$0.useState(false);
|
|
7620
7528
|
const swap = useSwapModel();
|
|
7621
7529
|
const { fromChain, toChain } = swap;
|
|
7622
7530
|
const { selectedAssetSymbol, assetMatrix } = useTokensStore();
|
|
@@ -7744,13 +7652,7 @@ const EvaaBridgeContent = ({
|
|
|
7744
7652
|
onSelect: handleToChainChange
|
|
7745
7653
|
}
|
|
7746
7654
|
),
|
|
7747
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7748
|
-
ToggleRow,
|
|
7749
|
-
{
|
|
7750
|
-
enabled: sendToAnother,
|
|
7751
|
-
onToggle: () => setSendToAnother((v) => !v)
|
|
7752
|
-
}
|
|
7753
|
-
),
|
|
7655
|
+
/* @__PURE__ */ jsxRuntime.jsx(AnotherAddress, {}),
|
|
7754
7656
|
/* @__PURE__ */ jsxRuntime.jsx(SubmitButton, {})
|
|
7755
7657
|
] }),
|
|
7756
7658
|
/* @__PURE__ */ jsxRuntime.jsx(card.CardFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(Details, {}) })
|
|
@@ -7825,7 +7727,6 @@ exports.addrForApi = addrForApi;
|
|
|
7825
7727
|
exports.buildAssetMatrix = buildAssetMatrix;
|
|
7826
7728
|
exports.calculateMinReceived = calculateMinReceived;
|
|
7827
7729
|
exports.computeFeesUsdFromArray = computeFeesUsdFromArray;
|
|
7828
|
-
exports.dollarsFromNativeFees = dollarsFromNativeFees;
|
|
7829
7730
|
exports.findNativeMeta = findNativeMeta;
|
|
7830
7731
|
exports.formatBalance = formatBalance;
|
|
7831
7732
|
exports.formatHash = formatHash;
|
|
@@ -7844,10 +7745,7 @@ exports.getQuotesByPriority = getQuotesByPriority;
|
|
|
7844
7745
|
exports.getTokens = getTokens;
|
|
7845
7746
|
exports.getTonBalances = getTonBalances;
|
|
7846
7747
|
exports.getTronBalances = getTronBalances;
|
|
7847
|
-
exports.isAddressValidForChain = isAddressValidForChain;
|
|
7848
|
-
exports.isEvmAddress = isEvmAddress;
|
|
7849
7748
|
exports.isNativeAddrEqual = isNativeAddrEqual;
|
|
7850
|
-
exports.isTronAddress = isTronAddress;
|
|
7851
7749
|
exports.isZeroAddr = isZeroAddr;
|
|
7852
7750
|
exports.listAssetsForSelect = listAssetsForSelect;
|
|
7853
7751
|
exports.lookupTokenMeta = lookupTokenMeta;
|