@rash2x/bridge-widget 0.1.6 → 0.1.7

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.
@@ -689,37 +689,40 @@ const Modal = ({
689
689
  }, [isOpen, onClose]);
690
690
  if (typeof document === "undefined") return null;
691
691
  return reactDom.createPortal(
692
- /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isOpen && /* @__PURE__ */ jsxRuntime.jsx(
692
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isOpen && /* @__PURE__ */ jsxRuntime.jsxs(
693
693
  framerMotion.motion.div,
694
694
  {
695
- className: "fixed inset-0 border border-border z-[100] bg-dialog sm:absolute sm:inset-0 sm:top-0 sm:bottom-0 sm:w-full sm:rounded-3xl",
695
+ className: "fixed m-auto border border-border max-w-md max-h-[80%] z-[100] bg-dialog sm:absolute sm:inset-0 sm:top-0 sm:bottom-0 sm:w-full rounded-xl",
696
696
  initial: { opacity: 0 },
697
697
  animate: { opacity: 1 },
698
698
  exit: { opacity: 0 },
699
- children: /* @__PURE__ */ jsxRuntime.jsx(
700
- framerMotion.motion.div,
701
- {
702
- ref: panelRef,
703
- role: "dialog",
704
- "aria-modal": "true",
705
- tabIndex: -1,
706
- className: cn(
707
- "outline-none overflow-auto w-screen h-screen rounded-none sm:w-full sm:h-full sm:rounded-3xl",
708
- className
709
- ),
710
- initial: { opacity: 0, scale: 0.9 },
711
- animate: { opacity: 1, scale: 1 },
712
- exit: { opacity: 0, scale: 0.9 },
713
- transition: {
714
- type: "spring",
715
- stiffness: 480,
716
- damping: 32,
717
- mass: 0.6
718
- },
719
- onMouseDown: (e) => e.stopPropagation(),
720
- children
721
- }
722
- )
699
+ children: [
700
+ /* @__PURE__ */ jsxRuntime.jsx(
701
+ framerMotion.motion.div,
702
+ {
703
+ ref: panelRef,
704
+ role: "dialog",
705
+ "aria-modal": "true",
706
+ tabIndex: -1,
707
+ className: cn(
708
+ "outline-none overflow-auto relative z-30 w-screen h-screen rounded-none sm:w-full sm:h-full sm:rounded-3xl",
709
+ className
710
+ ),
711
+ initial: { opacity: 0, scale: 0.9 },
712
+ animate: { opacity: 1, scale: 1 },
713
+ exit: { opacity: 0, scale: 0.9 },
714
+ transition: {
715
+ type: "spring",
716
+ stiffness: 480,
717
+ damping: 32,
718
+ mass: 0.6
719
+ },
720
+ onMouseDown: (e) => e.stopPropagation(),
721
+ children
722
+ }
723
+ ),
724
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 backdrop-blur-sm bg-background/10 z-10" })
725
+ ]
723
726
  }
724
727
  ) }),
725
728
  container
@@ -1472,7 +1475,7 @@ function sumFeeByTokenLD(fees, dstTokenAddr, dstChainKey) {
1472
1475
  }
1473
1476
  return acc.toString();
1474
1477
  }
1475
- function useBalances(chainKey, address) {
1478
+ function useBalances(chainKey, address, priorityTokenSymbol) {
1476
1479
  const { chainRegistry } = useChainStrategies();
1477
1480
  const { assetMatrix } = useTokensStore();
1478
1481
  const tokensOnChain = require$$0.useMemo(() => {
@@ -1484,13 +1487,24 @@ function useBalances(chainKey, address) {
1484
1487
  }
1485
1488
  return tokensList;
1486
1489
  }, [assetMatrix, chainKey]);
1490
+ const priorityToken = require$$0.useMemo(() => {
1491
+ if (!priorityTokenSymbol || !chainKey || !assetMatrix) return void 0;
1492
+ const normalizedSymbol = normalizeTickerSymbol$1(priorityTokenSymbol);
1493
+ const token = assetMatrix[normalizedSymbol]?.[chainKey];
1494
+ return token;
1495
+ }, [priorityTokenSymbol, chainKey, assetMatrix]);
1487
1496
  const query = reactQuery.useQuery({
1488
- queryKey: ["balances", chainKey, address],
1497
+ queryKey: ["balances", chainKey, address, priorityTokenSymbol],
1489
1498
  queryFn: async () => {
1490
1499
  if (!address || !chainKey)
1491
1500
  return {};
1492
1501
  if (!isAddressValidForChain(chainKey, address)) return {};
1493
- return await chainRegistry.getBalances(chainKey, address, tokensOnChain);
1502
+ return await chainRegistry.getBalances(
1503
+ chainKey,
1504
+ address,
1505
+ tokensOnChain,
1506
+ priorityToken
1507
+ );
1494
1508
  },
1495
1509
  enabled: !!address && !!chainKey && tokensOnChain.length > 0 && isAddressValidForChain(chainKey, address),
1496
1510
  staleTime: 6e4,
@@ -2455,8 +2469,16 @@ function useSwapModel() {
2455
2469
  const tokensStore = useTokensStore();
2456
2470
  const { srcAddress, dstAddress } = useAddresses();
2457
2471
  const { allowedFromChains, allowedToChains, isLoadingToChains } = useChainDerivations();
2458
- const srcBalances = useBalances(chainsStore.fromChain?.chainKey, srcAddress);
2459
- const dstBalances = useBalances(chainsStore.toChain?.chainKey, dstAddress);
2472
+ const srcBalances = useBalances(
2473
+ chainsStore.fromChain?.chainKey,
2474
+ srcAddress,
2475
+ tokensStore.selectedAssetSymbol
2476
+ );
2477
+ const dstBalances = useBalances(
2478
+ chainsStore.toChain?.chainKey,
2479
+ dstAddress,
2480
+ tokensStore.selectedAssetSymbol
2481
+ );
2460
2482
  const { loading } = useBridgeQuote();
2461
2483
  const { inputAmount, setInputAmount, resetWithIdle } = useBridgeQuoteStore();
2462
2484
  const fromBalance = require$$0.useMemo(
@@ -2539,10 +2561,10 @@ const SwapButton = () => {
2539
2561
  {
2540
2562
  onClick: handleSwap,
2541
2563
  disabled: !canSwap || isSwapping,
2564
+ variant: "secondary",
2565
+ size: "sm",
2542
2566
  className: cn(
2543
- "has-[>svg]:p-0 h-9 bg-swap rounded-full p-2 max-w-9 w-full",
2544
2567
  "absolute top-1/2 -translate-y-1/2 left-1/2 -translate-x-1/2",
2545
- "hover:bg-swap transition-all duration-200 shadow-none select-none",
2546
2568
  !canSwap || isSwapping ? "opacity-50 cursor-not-allowed" : "hover:scale-110"
2547
2569
  ),
2548
2570
  children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -2551,8 +2573,7 @@ const SwapButton = () => {
2551
2573
  style: {
2552
2574
  transform: `rotate(${turns * 180}deg)`,
2553
2575
  transition: "transform 300ms linear"
2554
- },
2555
- className: "size-5 text-swap-foreground will-change-transform"
2576
+ }
2556
2577
  }
2557
2578
  )
2558
2579
  }
@@ -2583,7 +2604,6 @@ const NetworkSymbol = ({
2583
2604
  };
2584
2605
  const SelectNetworkButton = ({
2585
2606
  onClick,
2586
- className,
2587
2607
  network
2588
2608
  }) => {
2589
2609
  const { t } = reactI18next.useTranslation();
@@ -2594,7 +2614,8 @@ const SelectNetworkButton = ({
2594
2614
  Button,
2595
2615
  {
2596
2616
  onClick,
2597
- className: `cursor-pointer hover:scale-[1.1] p-1.5 h-8.5 pr-3 !pl-1.5 bg-secondary hover:bg-secondary shadow-none rounded-full flex items-center justify-between gap-3 w-fit shrink-0 ${className ?? ""}`,
2617
+ size: "sm",
2618
+ variant: "secondary",
2598
2619
  type: "button",
2599
2620
  "aria-label": label,
2600
2621
  children: [
@@ -2961,8 +2982,7 @@ const SwapSection = ({
2961
2982
  SelectNetworkButton,
2962
2983
  {
2963
2984
  network: chain,
2964
- onClick: disableNetworkSelect ? void 0 : onOpen,
2965
- className: disableNetworkSelect ? "opacity-80 cursor-not-allowed" : ""
2985
+ onClick: disableNetworkSelect ? void 0 : onOpen
2966
2986
  }
2967
2987
  ),
2968
2988
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -6289,10 +6309,10 @@ class ChainStrategyRegistry {
6289
6309
  const strategy = this.getStrategy(chainKey);
6290
6310
  return strategy?.isConnected() || false;
6291
6311
  }
6292
- async getBalances(chainKey, address, tokens) {
6312
+ async getBalances(chainKey, address, tokens, priorityToken) {
6293
6313
  const strategy = this.getStrategy(chainKey);
6294
6314
  if (!strategy) return {};
6295
- return await strategy.getBalances(address, tokens);
6315
+ return await strategy.getBalances(address, tokens, priorityToken);
6296
6316
  }
6297
6317
  isAddressValid(chainKey, address) {
6298
6318
  const strategy = this.getStrategy(chainKey);
@@ -6403,13 +6423,14 @@ function parseTonAddress(address) {
6403
6423
  }
6404
6424
  return ton.Address.parse(address);
6405
6425
  }
6406
- async function getEvmBalances(publicClient, address, tokens) {
6426
+ async function getEvmBalances(publicClient, address, tokens, priorityToken) {
6407
6427
  const balances = {};
6408
6428
  try {
6409
6429
  console.log("start getEvmBalances");
6410
6430
  console.log("publicClient:", publicClient);
6411
6431
  console.log("isAddress:", viem.isAddress(address));
6412
6432
  console.log("tokens:", tokens);
6433
+ console.log("priorityToken:", priorityToken);
6413
6434
  if (!address || !viem.isAddress(address)) {
6414
6435
  console.warn(`Invalid EVM address provided: ${address}`);
6415
6436
  return balances;
@@ -6417,25 +6438,93 @@ async function getEvmBalances(publicClient, address, tokens) {
6417
6438
  if (!publicClient) {
6418
6439
  throw new Error("No public client provided");
6419
6440
  }
6420
- for (const token of tokens) {
6441
+ const nativeTokens = tokens.filter((t) => isNativeAddress(t.address));
6442
+ const erc20Tokens = tokens.filter((t) => !isNativeAddress(t.address) && viem.isAddress(t.address));
6443
+ if (priorityToken) {
6421
6444
  try {
6422
- let balance = 0;
6423
- const isNative = isNativeAddress(token.address);
6424
- if (isNative) {
6445
+ const isPriorityNative = isNativeAddress(priorityToken.address);
6446
+ if (isPriorityNative) {
6425
6447
  const ethBalance = await publicClient.getBalance({
6426
6448
  address
6427
6449
  });
6428
- balance = parseFloat(viem.formatUnits(ethBalance, token.decimals));
6429
- } else {
6430
- if (!viem.isAddress(token.address)) {
6431
- continue;
6450
+ const balance = parseFloat(viem.formatUnits(ethBalance, priorityToken.decimals));
6451
+ if (balance > 0) {
6452
+ balances[priorityToken.symbol] = { balance, address };
6432
6453
  }
6433
- const bytecode = await publicClient.getBytecode({
6434
- address: token.address
6454
+ } else if (viem.isAddress(priorityToken.address)) {
6455
+ const tokenBalance = await publicClient.readContract({
6456
+ address: priorityToken.address,
6457
+ abi: [
6458
+ {
6459
+ name: "balanceOf",
6460
+ type: "function",
6461
+ stateMutability: "view",
6462
+ inputs: [{ name: "owner", type: "address" }],
6463
+ outputs: [{ name: "balance", type: "uint256" }]
6464
+ }
6465
+ ],
6466
+ functionName: "balanceOf",
6467
+ args: [address]
6435
6468
  });
6436
- if (!bytecode || bytecode === "0x") {
6437
- continue;
6469
+ const balance = parseFloat(viem.formatUnits(tokenBalance, priorityToken.decimals));
6470
+ if (balance > 0) {
6471
+ balances[priorityToken.symbol] = { balance, address };
6438
6472
  }
6473
+ }
6474
+ } catch (error) {
6475
+ console.debug(`Failed to get priority token balance for ${priorityToken.symbol}:`, error);
6476
+ }
6477
+ }
6478
+ for (const token of nativeTokens) {
6479
+ try {
6480
+ const ethBalance = await publicClient.getBalance({
6481
+ address
6482
+ });
6483
+ const balance = parseFloat(viem.formatUnits(ethBalance, token.decimals));
6484
+ if (balance > 0) {
6485
+ balances[token.symbol] = { balance, address };
6486
+ }
6487
+ } catch (error) {
6488
+ console.debug(`Failed to get native balance for ${token.symbol}:`, error);
6489
+ }
6490
+ }
6491
+ if (erc20Tokens.length > 0) {
6492
+ try {
6493
+ const multicallContracts = erc20Tokens.map((token) => ({
6494
+ address: token.address,
6495
+ abi: [
6496
+ {
6497
+ name: "balanceOf",
6498
+ type: "function",
6499
+ stateMutability: "view",
6500
+ inputs: [{ name: "owner", type: "address" }],
6501
+ outputs: [{ name: "balance", type: "uint256" }]
6502
+ }
6503
+ ],
6504
+ functionName: "balanceOf",
6505
+ args: [address]
6506
+ }));
6507
+ const results = await publicClient.multicall({
6508
+ contracts: multicallContracts,
6509
+ allowFailure: true
6510
+ });
6511
+ results.forEach((result, index) => {
6512
+ const token = erc20Tokens[index];
6513
+ if (!token) return;
6514
+ if (result.status === "success" && result.result !== void 0) {
6515
+ try {
6516
+ const balance = parseFloat(viem.formatUnits(result.result, token.decimals));
6517
+ if (balance > 0) {
6518
+ balances[token.symbol] = { balance, address };
6519
+ }
6520
+ } catch (error) {
6521
+ console.debug(`Failed to parse balance for ${token.symbol}:`, error);
6522
+ }
6523
+ }
6524
+ });
6525
+ } catch (error) {
6526
+ console.warn("Multicall failed, falling back to individual calls:", error);
6527
+ for (const token of erc20Tokens) {
6439
6528
  try {
6440
6529
  const tokenBalance = await publicClient.readContract({
6441
6530
  address: token.address,
@@ -6451,23 +6540,16 @@ async function getEvmBalances(publicClient, address, tokens) {
6451
6540
  functionName: "balanceOf",
6452
6541
  args: [address]
6453
6542
  });
6454
- balance = parseFloat(
6543
+ const balance = parseFloat(
6455
6544
  viem.formatUnits(tokenBalance, token.decimals)
6456
6545
  );
6457
- } catch {
6458
- continue;
6546
+ if (balance > 0) {
6547
+ balances[token.symbol] = { balance, address };
6548
+ }
6549
+ } catch (error2) {
6550
+ console.debug(`Failed to get balance for ${token.symbol}:`, error2);
6459
6551
  }
6460
6552
  }
6461
- if (balance > 0) {
6462
- balances[token.symbol] = { balance, address };
6463
- }
6464
- } catch (error) {
6465
- if (error instanceof Error && !error.message.includes("could not decode")) {
6466
- console.warn(
6467
- `Network error fetching balance for ${token.symbol}:`,
6468
- error
6469
- );
6470
- }
6471
6553
  }
6472
6554
  }
6473
6555
  } catch (error) {
@@ -6529,7 +6611,11 @@ async function getTonBalances(address, tokens, customTonClient, tonApiKey) {
6529
6611
  }
6530
6612
  }
6531
6613
  } catch (error) {
6532
- console.debug(`Failed to get balance for ${token.symbol}:`, error);
6614
+ const errorMessage = error instanceof Error ? error.message : String(error);
6615
+ const isNoWalletError = errorMessage.includes("exit_code: -13") || errorMessage.includes("exit_code:-13") || errorMessage.includes("exitCode: -13");
6616
+ if (!isNoWalletError) {
6617
+ console.debug(`Failed to get balance for ${token.symbol}:`, error);
6618
+ }
6533
6619
  }
6534
6620
  }
6535
6621
  } catch (error) {
@@ -6630,12 +6716,12 @@ class EvmChainStrategy {
6630
6716
  getConnectLabel(t) {
6631
6717
  return t("wallets.connectEvmWallet");
6632
6718
  }
6633
- async getBalances(address, tokens) {
6719
+ async getBalances(address, tokens, priorityToken) {
6634
6720
  if (!this.publicClient) {
6635
6721
  console.warn("No publicClient available for balance query");
6636
6722
  return {};
6637
6723
  }
6638
- return await getEvmBalances(this.publicClient, address, tokens);
6724
+ return await getEvmBalances(this.publicClient, address, tokens, priorityToken);
6639
6725
  }
6640
6726
  isAddressValid(address) {
6641
6727
  if (!address) return false;