@embarkai/ui-kit 0.4.37 → 0.4.39

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/index.js CHANGED
@@ -5420,9 +5420,9 @@ var init_en = __esm({
5420
5420
  confirmBridge: "I confirm bridging {{amount}} {{asset}} to {{destinationChain}}"
5421
5421
  },
5422
5422
  statuses: {
5423
+ balanceInsufficient: "Insufficient balance",
5423
5424
  txPrepare: "Preparing transactions...",
5424
- txSending: "Sending {{txCount}} transactions...",
5425
- txSent: "Transactions sent. Delivery to {{destination}}",
5425
+ txExecuting: "Executing transactions...",
5426
5426
  txWaitingReceipt: "Waiting for receipt...",
5427
5427
  txPatching: "Patching transaction..."
5428
5428
  },
@@ -5739,12 +5739,9 @@ var init_ru = __esm({
5739
5739
  confirmBridge: "\u041F\u041E\u0414\u0422\u0412\u0415\u0420\u0414\u0418\u0422\u042C \u041F\u0415\u0420\u0415\u041C\u0415\u0429\u0415\u041D\u0418\u0415"
5740
5740
  },
5741
5741
  statuses: {
5742
- qouteEstimating: "\u041E\u0446\u0435\u043D\u043A\u0430 \u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u0438...",
5743
- switchingWalletChain: "\u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u0441\u0435\u0442\u0438...",
5742
+ balanceInsufficient: "\u041D\u0435\u0434\u043E\u0441\u0442\u0430\u0442\u043E\u0447\u043D\u043E \u0441\u0440\u0435\u0434\u0441\u0442\u0432",
5744
5743
  txPrepare: "\u041F\u043E\u0434\u0433\u043E\u0442\u043E\u0432\u043A\u0430 \u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u0439...",
5745
- txSending: "\u041E\u0442\u043F\u0440\u0430\u0432\u043A\u0430 {{txCount}} \u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u0439...",
5746
- txSent: "\u0422\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u0438 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u044B. \u0414\u043E\u0441\u0442\u0430\u0432\u043A\u0430 \u0432 {{destination}}",
5747
- txExecuting: "\u0412\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435 \u043F\u0435\u0440\u0435\u043C\u0435\u0449\u0435\u043D\u0438\u044F...",
5744
+ txExecuting: "\u0412\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435 \u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u0439...",
5748
5745
  txWaitingReceipt: "\u041E\u0436\u0438\u0434\u0430\u043D\u0438\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F...",
5749
5746
  txPatching: "\u041E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u0438..."
5750
5747
  },
@@ -6061,12 +6058,9 @@ var init_zh = __esm({
6061
6058
  confirmBridge: "\u786E\u8BA4\u8DE8\u94FE"
6062
6059
  },
6063
6060
  statuses: {
6064
- qouteEstimating: "\u6B63\u5728\u4F30\u7B97\u62A5\u4EF7...",
6065
- switchingWalletChain: "\u6B63\u5728\u5207\u6362\u94FE...",
6061
+ balanceInsufficient: "\u4F59\u989D\u4E0D\u8DB3",
6066
6062
  txPrepare: "\u6B63\u5728\u51C6\u5907\u4EA4\u6613...",
6067
- txSending: "\u6B63\u5728\u53D1\u9001 {{txCount}} \u7B14\u4EA4\u6613...",
6068
- txSent: "\u4EA4\u6613\u5DF2\u53D1\u9001\u3002\u6B63\u5728\u4F20\u8F93\u81F3 {{destination}}",
6069
- txExecuting: "\u6B63\u5728\u6267\u884C\u8DE8\u94FE...",
6063
+ txExecuting: "\u6B63\u5728\u6267\u884C\u4EA4\u6613...",
6070
6064
  txWaitingReceipt: "\u7B49\u5F85\u6536\u636E...",
6071
6065
  txPatching: "\u66F4\u65B0\u4EA4\u6613..."
6072
6066
  },
@@ -19093,7 +19087,6 @@ var init_useBridgeStore = __esm({
19093
19087
  bridgeStep: "select",
19094
19088
  bridgeType: "hyper",
19095
19089
  bridgeSender: "embarkai-wallet",
19096
- bridgeSenders: [],
19097
19090
  amount: "",
19098
19091
  quote: null,
19099
19092
  isQuoteEstimating: false,
@@ -19102,6 +19095,7 @@ var init_useBridgeStore = __esm({
19102
19095
  useBridgeStore = create10()(
19103
19096
  persist3(
19104
19097
  (set, get) => ({
19098
+ bridgeSenders: [],
19105
19099
  hyperRoute: null,
19106
19100
  recipient: null,
19107
19101
  originChain: null,
@@ -19416,7 +19410,6 @@ var init_wallets = __esm({
19416
19410
  import { useEffect as useEffect34, useRef as useRef18 } from "react";
19417
19411
  function useAvailableSenders() {
19418
19412
  const address = useSession((st) => st.address);
19419
- const activeChainId = useSession((st) => st.activeChainId);
19420
19413
  const { profiles } = useLinkedProfiles();
19421
19414
  const lastCalcedSenders = useRef18([]);
19422
19415
  useEffect34(() => {
@@ -19424,7 +19417,7 @@ function useAvailableSenders() {
19424
19417
  {
19425
19418
  type: "embarkai-wallet",
19426
19419
  name: "embarkAI",
19427
- chainId: activeChainId,
19420
+ chainId: null,
19428
19421
  address,
19429
19422
  Icon: TOKENS_ICONS["EMBARKAI"]
19430
19423
  }
@@ -19443,9 +19436,10 @@ function useAvailableSenders() {
19443
19436
  return;
19444
19437
  }
19445
19438
  lastCalcedSenders.current = sendersAccumulator.map((s) => `${s.name}-${s.address}`);
19439
+ console.info("[SENDER SELECTOR] setting bridge senders", sendersAccumulator);
19446
19440
  useBridgeStore.getState().setBridgeSenders(sendersAccumulator);
19447
19441
  useFlowSelectorStore.getState().setRenderKey(`sender-selected-${Date.now()}`);
19448
- }, [address, profiles, activeChainId]);
19442
+ }, [address, profiles]);
19449
19443
  return {
19450
19444
  directWalletProfile: profiles.filter((p) => p.provider === "wallet")[0] || null
19451
19445
  };
@@ -19525,16 +19519,145 @@ var init_api3 = __esm({
19525
19519
  }
19526
19520
  });
19527
19521
 
19522
+ // src/clients/bundler/getUserOperationByHash.ts
19523
+ import { bundlerRpc } from "@embarkai/core";
19524
+ import { getChainConfig as getChainConfig9 } from "@embarkai/core/read";
19525
+ async function getUserOperationByHash(userOpHash, chainId) {
19526
+ const targetChainId = chainId ?? requireActiveChainId();
19527
+ const chainConfig = getChainConfig9(targetChainId);
19528
+ if (!chainConfig) {
19529
+ throw new Error(`Chain ${targetChainId} is not supported`);
19530
+ }
19531
+ if (!chainConfig.bundlerUrl) {
19532
+ throw new Error(`Chain ${targetChainId} has no bundlerUrl configured`);
19533
+ }
19534
+ if (!userOpHash) {
19535
+ throw new Error("Operation hash is required");
19536
+ }
19537
+ try {
19538
+ const result = await bundlerRpc("eth_getUserOperationByHash", [userOpHash], chainConfig.bundlerUrl);
19539
+ if (!result) {
19540
+ return null;
19541
+ }
19542
+ console.log("[getUserOperationByHash] Receipt:", JSON.stringify(result, null, 2));
19543
+ return {
19544
+ entryPoint: result.entryPoint,
19545
+ userOperation: result.userOperation,
19546
+ transactionHash: result.transactionHash,
19547
+ blockNumber: result.blockNumber,
19548
+ blockHash: result.blockHash
19549
+ };
19550
+ } catch (error) {
19551
+ console.warn("[getUserOperationByHash] Failed to get user operation:", error);
19552
+ return null;
19553
+ }
19554
+ }
19555
+ var init_getUserOperationByHash = __esm({
19556
+ "src/clients/bundler/getUserOperationByHash.ts"() {
19557
+ init_SessionContext();
19558
+ }
19559
+ });
19560
+
19561
+ // src/clients/bundler/getUserOperationReceipt.ts
19562
+ import { bundlerRpc as bundlerRpc2 } from "@embarkai/core";
19563
+ import { getChainConfig as getChainConfig10 } from "@embarkai/core/read";
19564
+ async function getUserOperationReceipt(userOpHash, chainId) {
19565
+ const targetChainId = chainId ?? requireActiveChainId();
19566
+ const chainConfig = getChainConfig10(targetChainId);
19567
+ if (!chainConfig) {
19568
+ throw new Error(`Chain ${targetChainId} is not supported`);
19569
+ }
19570
+ if (!chainConfig.bundlerUrl) {
19571
+ throw new Error(`Chain ${targetChainId} has no bundlerUrl configured`);
19572
+ }
19573
+ if (!userOpHash) {
19574
+ throw new Error("Operation hash is required");
19575
+ }
19576
+ try {
19577
+ const result = await bundlerRpc2("eth_getUserOperationReceipt", [userOpHash], chainConfig.bundlerUrl);
19578
+ if (!result) {
19579
+ return null;
19580
+ }
19581
+ console.log("[getUserOperationReceipt] Receipt:", JSON.stringify(result, null, 2));
19582
+ return {
19583
+ userOpHash: result.userOpHash,
19584
+ entryPoint: result.entryPoint,
19585
+ sender: result.sender,
19586
+ nonce: result.nonce,
19587
+ success: result.success,
19588
+ actualGasCost: result.actualGasCost,
19589
+ actualGasUsed: result.actualGasUsed,
19590
+ paymaster: result.paymaster,
19591
+ receipt: result.receipt,
19592
+ logs: result.logs,
19593
+ reason: result.reason
19594
+ };
19595
+ } catch (error) {
19596
+ console.warn("[getUserOperationReceipt] Failed to get receipt:", error);
19597
+ return null;
19598
+ }
19599
+ }
19600
+ var init_getUserOperationReceipt = __esm({
19601
+ "src/clients/bundler/getUserOperationReceipt.ts"() {
19602
+ init_SessionContext();
19603
+ }
19604
+ });
19605
+
19606
+ // src/clients/bundler/waitForUserOperationReceipt.ts
19607
+ async function waitForUserOperationReceipt(userOpHash, options) {
19608
+ const pollIntervalMs = options?.pollIntervalMs ?? 1e3;
19609
+ const maxPollTimeMs = options?.maxPollTimeMs ?? 6e4;
19610
+ const targetChainId = options?.chainId ?? requireActiveChainId();
19611
+ const startTime = Date.now();
19612
+ while (true) {
19613
+ const elapsed = Date.now() - startTime;
19614
+ if (elapsed >= maxPollTimeMs) {
19615
+ throw new UserOperationTimeoutError(userOpHash, targetChainId, maxPollTimeMs);
19616
+ }
19617
+ const receipt = await getUserOperationReceipt(userOpHash, targetChainId);
19618
+ if (receipt) {
19619
+ return receipt;
19620
+ }
19621
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
19622
+ }
19623
+ }
19624
+ var UserOperationTimeoutError;
19625
+ var init_waitForUserOperationReceipt = __esm({
19626
+ "src/clients/bundler/waitForUserOperationReceipt.ts"() {
19627
+ init_SessionContext();
19628
+ init_getUserOperationReceipt();
19629
+ UserOperationTimeoutError = class extends Error {
19630
+ constructor(userOpHash, chainId, timeoutMs) {
19631
+ super(`Timeout waiting for UserOperation receipt after ${timeoutMs}ms (hash: ${userOpHash}, chainId: ${chainId})`);
19632
+ this.name = "UserOperationTimeoutError";
19633
+ this.userOpHash = userOpHash;
19634
+ this.chainId = chainId;
19635
+ this.timeoutMs = timeoutMs;
19636
+ }
19637
+ };
19638
+ }
19639
+ });
19640
+
19641
+ // src/clients/bundler/index.ts
19642
+ var init_bundler = __esm({
19643
+ "src/clients/bundler/index.ts"() {
19644
+ init_getUserOperationByHash();
19645
+ init_getUserOperationReceipt();
19646
+ init_waitForUserOperationReceipt();
19647
+ }
19648
+ });
19649
+
19528
19650
  // src/internal/components/SendMenu/hyperbridge/lib/executeWarpTxs.ts
19651
+ import { CHAINS_BROWSERS_TRANSPORTS, wagmiConfig, waitForWagmiTransactionReceipt } from "@embarkai/core";
19529
19652
  import { createPublicClient, http as http2 } from "viem";
19530
19653
  async function executeWarpTransactions(txs, walletClient) {
19531
19654
  const originChain = useBridgeStore.getState().originChain;
19532
19655
  const session = useSession.getState().session;
19533
19656
  const bridgeSender = useBridgeStore.getState().bridgeSender;
19657
+ const externalWalletChain = CHAINS_UI_META[originChain].chain;
19534
19658
  const publicClient = bridgeSender === "embarkai-wallet" ? useSession.getState().publicClient : createPublicClient({
19535
- chain: CHAINS_UI_META[originChain].chain,
19536
- // transport: http(this.rpcUrl)
19537
- transport: http2(CHAINS_UI_META[originChain].chain.rpcUrls.default.http[0])
19659
+ chain: externalWalletChain,
19660
+ transport: CHAINS_BROWSERS_TRANSPORTS[externalWalletChain.id] || http2(externalWalletChain.rpcUrls.default.http[0])
19538
19661
  });
19539
19662
  if (!session) {
19540
19663
  throw new Error("No active session");
@@ -19545,6 +19668,9 @@ async function executeWarpTransactions(txs, walletClient) {
19545
19668
  const hashes = [];
19546
19669
  const errorsStack = [];
19547
19670
  for (const tx of txs) {
19671
+ if (tx.type !== "ethers-v5" /* EthersV5 */) {
19672
+ throw new Error(`Unsupported transaction provider: ${tx.type}`);
19673
+ }
19548
19674
  const populated = tx.transaction;
19549
19675
  if (!populated.to) {
19550
19676
  throw new Error("Transaction missing `to` address");
@@ -19557,28 +19683,69 @@ async function executeWarpTransactions(txs, walletClient) {
19557
19683
  BigInt(rawValue.hex)
19558
19684
  ) : BigInt(rawValue.toString())
19559
19685
  );
19560
- if (bridgeSender === "embarkai-wallet") {
19561
- const operationHash = await sendUserOperation(session, {
19562
- to: populated.to,
19563
- data: populated.data ?? "0x",
19564
- value: valueBigInt.toString(),
19565
- chainId: publicClient.chain.id
19566
- }).catch((error) => {
19567
- errorsStack.push(error);
19568
- throw error;
19569
- });
19570
- hashes.push(operationHash);
19571
- } else {
19572
- const walletOpHash = await walletClient?.sendTransaction?.({
19573
- to: populated.to,
19574
- value: valueBigInt.toString(),
19575
- data: populated.data,
19576
- chain: walletClient.chain
19577
- }).catch((error) => {
19578
- errorsStack.push(error);
19579
- throw error;
19580
- });
19581
- hashes.push(walletOpHash);
19686
+ switch (bridgeSender) {
19687
+ case "embarkai-wallet":
19688
+ useBridgeStore.getState().setBridgeTxStatus(`Tx: ${tx.category || ""}...`);
19689
+ const embarkOpHash = await sendUserOperation(session, {
19690
+ to: populated.to,
19691
+ data: populated.data ?? "0x",
19692
+ value: valueBigInt.toString(),
19693
+ chainId: publicClient.chain.id
19694
+ }).catch((error) => {
19695
+ errorsStack.push(error);
19696
+ throw error;
19697
+ });
19698
+ if (TARGET_TX_CATEGORIES.includes(tx.category)) {
19699
+ console.warn("[HYPERLANE] embarkai-wallet tx done", tx.category, embarkOpHash);
19700
+ hashes.push(embarkOpHash);
19701
+ }
19702
+ if (!TARGET_TX_CATEGORIES.includes(tx.category)) {
19703
+ useBridgeStore.getState().setBridgeTxStatus(`Tx receipt: ${tx.category || ""}...`);
19704
+ const embarkNonTransferReceipt = await waitForUserOperationReceipt(embarkOpHash, {
19705
+ chainId: publicClient.chain.id
19706
+ }).catch((error) => {
19707
+ errorsStack.push(error);
19708
+ throw error;
19709
+ });
19710
+ if (!embarkNonTransferReceipt.success) {
19711
+ throw new Error(
19712
+ `Approval transaction failed: ${embarkNonTransferReceipt?.receipt?.transactionHash || "unknown hash"}`
19713
+ );
19714
+ }
19715
+ }
19716
+ break;
19717
+ case "direct-wallet":
19718
+ useBridgeStore.getState().setBridgeTxStatus(`Tx: ${tx.category || ""}...`);
19719
+ const walletOpHash = await walletClient?.sendTransaction?.({
19720
+ to: populated.to,
19721
+ value: valueBigInt.toString(),
19722
+ data: populated.data,
19723
+ chain: walletClient.chain
19724
+ }).catch((error) => {
19725
+ errorsStack.push(error);
19726
+ throw error;
19727
+ });
19728
+ if (TARGET_TX_CATEGORIES.includes(tx.category)) {
19729
+ console.warn("[HYPERLANE] direct-wallet tx done", tx.category, walletOpHash);
19730
+ hashes.push(walletOpHash);
19731
+ }
19732
+ if (!TARGET_TX_CATEGORIES.includes(tx.category)) {
19733
+ useBridgeStore.getState().setBridgeTxStatus(`Tx receipt: ${tx.category || ""}...`);
19734
+ const wagmiNonTransferReceipt = await waitForWagmiTransactionReceipt(wagmiConfig, {
19735
+ chainId: publicClient.chain.id,
19736
+ hash: walletOpHash,
19737
+ pollingInterval: 2500
19738
+ }).catch((error) => {
19739
+ errorsStack.push(error);
19740
+ throw error;
19741
+ });
19742
+ if (!wagmiNonTransferReceipt.success) {
19743
+ throw new Error(
19744
+ `Approval transaction failed: ${wagmiNonTransferReceipt?.transactionHash || "unknown hash"}`
19745
+ );
19746
+ }
19747
+ }
19748
+ break;
19582
19749
  }
19583
19750
  }
19584
19751
  if (errorsStack.length > 0) {
@@ -19587,12 +19754,15 @@ async function executeWarpTransactions(txs, walletClient) {
19587
19754
  }
19588
19755
  return hashes;
19589
19756
  }
19757
+ var TARGET_TX_CATEGORIES;
19590
19758
  var init_executeWarpTxs = __esm({
19591
19759
  "src/internal/components/SendMenu/hyperbridge/lib/executeWarpTxs.ts"() {
19760
+ init_bundler();
19592
19761
  init_SessionContext();
19593
19762
  init_account2();
19594
19763
  init_useBridgeStore();
19595
19764
  init_chains();
19765
+ TARGET_TX_CATEGORIES = ["transfer"];
19596
19766
  }
19597
19767
  });
19598
19768
 
@@ -19781,6 +19951,7 @@ function useBridge() {
19781
19951
  warpTxs,
19782
19952
  bridgeSender.type === "direct-wallet" ? walletClient : null
19783
19953
  );
19954
+ setBridgeTxStatus(t("passport:bridgeMenu.statuses.txPatching"));
19784
19955
  await Promise.all([
19785
19956
  patchInitiatedBridgeTxOpHashes({ txId: hyperlaneDbTx.id, txOpHashes: operationHashes }),
19786
19957
  patchInitiatedBridgeTxStatus({ txId: hyperlaneDbTx.id, txStatus: "SENDING" })
@@ -19788,18 +19959,14 @@ function useBridge() {
19788
19959
  return operationHashes;
19789
19960
  },
19790
19961
  onSuccess: (operationHashes) => {
19791
- const { setBridgeStep, setBridgeTxStatus, destinationChain } = useBridgeStore.getState();
19792
- setBridgeTxStatus(
19793
- // @ts-expect-error i18n typing
19794
- t("passport:bridgeMenu.statuses.txSent", { destination: destinationChain })
19795
- );
19962
+ const { setBridgeStep, setBridgeTxStatus } = useBridgeStore.getState();
19796
19963
  useOperationHashesStore.getState().setOperationHashes(operationHashes);
19797
19964
  useLayoutStore.getState().setIsDialogForced(false);
19798
19965
  useFlowSelectorStore.getState().setIsUiLocked(false);
19966
+ setBridgeTxStatus(null);
19799
19967
  setBridgeStep("success");
19800
19968
  },
19801
19969
  onError: (error) => {
19802
- const { setBridgeTxStatus } = useBridgeStore.getState();
19803
19970
  console.error("[HYPERLANE SDK] Bridge execution error", error);
19804
19971
  const hyperlaneDbTx = useOperationHashesStore.getState().hyperlaneDatabaseTx;
19805
19972
  if (hyperlaneDbTx?.id) {
@@ -19807,9 +19974,9 @@ function useBridge() {
19807
19974
  console.log("[HYPERLANE SDK] initiated tx patched as REJECTED: ", hyperlaneDbTx.id, "ok: ", ok);
19808
19975
  });
19809
19976
  }
19810
- setBridgeTxStatus(null);
19811
19977
  useLayoutStore.getState().setIsDialogForced(false);
19812
19978
  useFlowSelectorStore.getState().setIsUiLocked(false);
19979
+ useBridgeStore.getState().setBridgeTxStatus(null);
19813
19980
  useFlowSelectorStore.getState().setError(error instanceof Error ? error.message : String(error));
19814
19981
  }
19815
19982
  });
@@ -19952,6 +20119,7 @@ var init_ResolveChainIcon = __esm({
19952
20119
  });
19953
20120
 
19954
20121
  // src/internal/components/SendMenu/hyperbridge/hooks/useBridgeBalance.ts
20122
+ import { CHAINS_BROWSERS_TRANSPORTS as CHAINS_BROWSERS_TRANSPORTS2 } from "@embarkai/core";
19955
20123
  import { useQuery as useQuery20, useQueryClient as useQueryClient21 } from "@tanstack/react-query";
19956
20124
  import { useCallback as useCallback23, useEffect as useEffect37 } from "react";
19957
20125
  import { createPublicClient as createPublicClient2, erc20Abi as erc20Abi2, formatUnits as formatUnits7, http as http3 } from "viem";
@@ -19985,13 +20153,14 @@ function useBridgeBalance(hyperlaneWarpRoutes) {
19985
20153
  const originChainMeta = CHAINS_UI_META[originChain];
19986
20154
  const isSelectedTokenNative = selectedWarpRoute?.symbol?.toUpperCase() === originChainMeta?.chain?.nativeCurrency?.symbol?.toUpperCase();
19987
20155
  const { data: externalBalanceData, isLoading: isExternalBalanceLoading } = useQuery20({
19988
- enabled: bridgeSender === "direct-wallet" && !isSelectedTokenNative && !!directWalletAddress && !!routeTokenAddress && !!originChain,
19989
20156
  retry: false,
20157
+ enabled: bridgeSender === "direct-wallet" && !isSelectedTokenNative && !!directWalletAddress && !!routeTokenAddress && !!originChain,
19990
20158
  queryKey: [EXTERNAL_WALLET_BRIDGING_BALANCE_QUERY, originChain, directWalletAddress, routeTokenAddress],
19991
20159
  queryFn: async () => {
20160
+ const chainTransport = CHAINS_BROWSERS_TRANSPORTS2[originChainMeta.chain.id] || http3(originChainMeta.chain.rpcUrls.default.http[0]);
19992
20161
  const client = createPublicClient2({
19993
20162
  chain: originChainMeta.chain,
19994
- transport: http3(originChainMeta.chain.rpcUrls.default.http[0])
20163
+ transport: chainTransport
19995
20164
  });
19996
20165
  const [value, decimals, symbol] = await Promise.all([
19997
20166
  client.readContract({
@@ -20107,17 +20276,16 @@ function SelectStep(props) {
20107
20276
  const { swapChains, hyperlaneWarpRoutes, isLoadingWarpRoutes, handleQuoteEstimation } = props;
20108
20277
  const { t } = useT();
20109
20278
  const {
20279
+ bridgeSenders,
20280
+ bridgeSender,
20110
20281
  originChain,
20111
20282
  destinationChain,
20112
20283
  hyperRoute,
20113
20284
  amount,
20114
20285
  isQuoteEstimating,
20115
- recipient,
20116
- setBridgeStep,
20117
- setAmount,
20118
- setRecipient
20286
+ recipient
20119
20287
  } = useBridgeStore();
20120
- const selectedSender = useBridgeStore((st) => st.bridgeSenders?.find((s) => s.type === st.bridgeSender)) || null;
20288
+ const selectedSender = bridgeSenders?.find((s) => s.type === bridgeSender) || null;
20121
20289
  const { routeTokenBalance, isRouteTokenBalanceLoading } = useBridgeBalance(hyperlaneWarpRoutes);
20122
20290
  const selectedWarpRoute = hyperlaneWarpRoutes.find((route) => {
20123
20291
  const { routeId, chainPair } = route;
@@ -20129,6 +20297,9 @@ function SelectStep(props) {
20129
20297
  if (isLoadingWarpRoutes) {
20130
20298
  return /* @__PURE__ */ jsx93("div", { className: "w-full flex items-center justify-center p-[var(--ui-kit-pd)]", children: /* @__PURE__ */ jsx93(LoaderIcon8, { className: "w-4 h-4 animate-spin" }) });
20131
20299
  }
20300
+ const isBalanceInsufficient = !routeTokenBalance || Number(amount || 0) > Number(routeTokenBalance || 0);
20301
+ const isFalsyAmount = !amount || !Number(amount) || Number(amount) <= 0;
20302
+ const isQuoteEstimationDisabled = isQuoteEstimating || !hyperlaneWarpRoutes.length || !selectedSender || !originChain || !destinationChain || !hyperRoute || isFalsyAmount || isBalanceInsufficient;
20132
20303
  return /* @__PURE__ */ jsxs85("div", { className: "w-full flex flex-col gap-[var(--ui-kit-gap)] items-center", children: [
20133
20304
  /* @__PURE__ */ jsxs85("div", { className: "w-full flex flex-col gap-[var(--ui-kit-gap)]", children: [
20134
20305
  /* @__PURE__ */ jsx93(
@@ -20149,7 +20320,7 @@ function SelectStep(props) {
20149
20320
  className: "w-full justify-between",
20150
20321
  onClick: () => {
20151
20322
  useFlowSelectorStore.getState().setError(null);
20152
- setBridgeStep("sender-selector");
20323
+ useBridgeStore.getState().setBridgeStep("sender-selector");
20153
20324
  },
20154
20325
  children: [
20155
20326
  /* @__PURE__ */ jsxs85("div", { className: "flex items-center gap-[var(--ui-kit-gap)]", children: [
@@ -20173,7 +20344,7 @@ function SelectStep(props) {
20173
20344
  ": "
20174
20345
  ] }),
20175
20346
  isRouteTokenBalanceLoading && /* @__PURE__ */ jsx93(LoaderIcon8, { className: "w-4 h-4 animate-spin text-[var(--ui-kit-fg-muted)]" }),
20176
- !isRouteTokenBalanceLoading && /* @__PURE__ */ jsxs85("span", { className: "font-semibold", children: [
20347
+ !isRouteTokenBalanceLoading && /* @__PURE__ */ jsxs85("span", { className: cn("font-semibold", { "text-[var(--ui-kit-bg-error)]": isBalanceInsufficient }), children: [
20177
20348
  formatPrice(Number(routeTokenBalance || 0)),
20178
20349
  " ",
20179
20350
  selectedWarpRoute?.symbol
@@ -20188,7 +20359,7 @@ function SelectStep(props) {
20188
20359
  className: "w-full justify-between",
20189
20360
  onClick: () => {
20190
20361
  useFlowSelectorStore.getState().setError(null);
20191
- setBridgeStep("select-token");
20362
+ useBridgeStore.getState().setBridgeStep("select-token");
20192
20363
  },
20193
20364
  children: [
20194
20365
  selectedWarpRoute ? /* @__PURE__ */ jsxs85("div", { className: "flex items-center gap-[var(--ui-kit-gap)]", children: [
@@ -20272,9 +20443,9 @@ function SelectStep(props) {
20272
20443
  }
20273
20444
  if (regex.test(value) || value === "") {
20274
20445
  if (value === "") {
20275
- setAmount("0");
20446
+ useBridgeStore.getState().setAmount("0");
20276
20447
  } else {
20277
- setAmount(value);
20448
+ useBridgeStore.getState().setAmount(value);
20278
20449
  }
20279
20450
  }
20280
20451
  },
@@ -20305,7 +20476,7 @@ function SelectStep(props) {
20305
20476
  Icon: Wallet2Icon2,
20306
20477
  onChange: (e) => {
20307
20478
  useFlowSelectorStore.getState().setError(null);
20308
- setRecipient(e.target.value);
20479
+ useBridgeStore.getState().setRecipient(e.target.value);
20309
20480
  },
20310
20481
  element: /* @__PURE__ */ jsx93(
20311
20482
  Button,
@@ -20315,7 +20486,7 @@ function SelectStep(props) {
20315
20486
  variant: "ghost",
20316
20487
  onClick: (e) => {
20317
20488
  e.stopPropagation();
20318
- setRecipient(null);
20489
+ useBridgeStore.getState().setRecipient(null);
20319
20490
  },
20320
20491
  children: /* @__PURE__ */ jsx93(XIcon, { className: "w-4 h-4" })
20321
20492
  }
@@ -20333,10 +20504,10 @@ function SelectStep(props) {
20333
20504
  variant: "default",
20334
20505
  className: "w-full",
20335
20506
  onClick: () => handleQuoteEstimation(amount),
20336
- disabled: isQuoteEstimating || !hyperlaneWarpRoutes.length || !selectedSender || !amount || !Number(amount) || !originChain || !destinationChain || !hyperRoute,
20507
+ disabled: isQuoteEstimationDisabled,
20337
20508
  children: [
20338
20509
  isQuoteEstimating && /* @__PURE__ */ jsx93(LoaderIcon8, { className: "h-4 w-4 animate-spin" }),
20339
- /* @__PURE__ */ jsx93("span", { children: t("passport:bridgeMenu.actions.estimateQuote") })
20510
+ /* @__PURE__ */ jsx93("span", { children: isBalanceInsufficient ? t("passport:bridgeMenu.statuses.balanceInsufficient") : t("passport:bridgeMenu.actions.estimateQuote") })
20340
20511
  ]
20341
20512
  }
20342
20513
  )
@@ -24015,7 +24186,7 @@ var init_package = __esm({
24015
24186
  "package.json"() {
24016
24187
  package_default = {
24017
24188
  name: "@embarkai/ui-kit",
24018
- version: "0.4.37",
24189
+ version: "0.4.39",
24019
24190
  description: "React UI components and hooks for EmbarkAI authentication and Account Abstraction",
24020
24191
  type: "module",
24021
24192
  main: "./dist/index.cjs",
@@ -25023,7 +25194,7 @@ import {
25023
25194
  createBundlerClientForChain,
25024
25195
  createPublicClientForChain as createPublicClientForChain6,
25025
25196
  DEFAULT_CHAIN_ID as DEFAULT_CHAIN_ID2,
25026
- getChainConfig as getChainConfig9,
25197
+ getChainConfig as getChainConfig11,
25027
25198
  getViemChain as getViemChain2
25028
25199
  } from "@embarkai/core/read";
25029
25200
  import { Fragment as Fragment45 } from "react";
@@ -25132,7 +25303,7 @@ var init_SessionContext = __esm({
25132
25303
  // Set default chainId after hydration if not persisted
25133
25304
  onRehydrateStorage: () => (state) => {
25134
25305
  if (!state) return;
25135
- const hydartedChain = getChainParams(getChainConfig9(state.activeChainId || DEFAULT_CHAIN_ID2));
25306
+ const hydartedChain = getChainParams(getChainConfig11(state.activeChainId || DEFAULT_CHAIN_ID2));
25136
25307
  state.activeChainId = hydartedChain.activeChainId;
25137
25308
  state.publicClient = hydartedChain.publicClient;
25138
25309
  state.bundlerClient = hydartedChain.bundlerClient;
@@ -25179,7 +25350,7 @@ var init_env = __esm({
25179
25350
  });
25180
25351
 
25181
25352
  // src/internal/clients/base.ts
25182
- import { getChainConfig as getChainConfig10, getViemChain as getViemChain3, lumiaMainnetChain, lumiaTestnetChain } from "@embarkai/core/read";
25353
+ import { getChainConfig as getChainConfig12, getViemChain as getViemChain3, lumiaMainnetChain, lumiaTestnetChain } from "@embarkai/core/read";
25183
25354
  import { http as http4 } from "viem";
25184
25355
  import { createBundlerClient } from "viem/account-abstraction";
25185
25356
  function getTssUrl2() {
@@ -25210,13 +25381,13 @@ function getExplorerUrl() {
25210
25381
  const paramUrl = typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("explorerUrl") || void 0 : void 0;
25211
25382
  const net = getSelectedNetwork();
25212
25383
  const chainId = requireActiveChainId();
25213
- const chainConfig = getChainConfig10(chainId);
25384
+ const chainConfig = getChainConfig12(chainId);
25214
25385
  console.log("[getExplorerUrl] ", paramUrl, chainConfig.blockExplorerUrl);
25215
25386
  return paramUrl || chainConfig.blockExplorerUrl;
25216
25387
  }
25217
25388
  function getBundlerClient() {
25218
25389
  const chainId = requireActiveChainId();
25219
- const chainConfig = getChainConfig10(chainId);
25390
+ const chainConfig = getChainConfig12(chainId);
25220
25391
  const viemChain = getViemChain3(chainId);
25221
25392
  return createBundlerClient({
25222
25393
  chain: viemChain,
@@ -27488,7 +27659,12 @@ var init_iframe_manager = __esm({
27488
27659
  // src/config/rainbowkit.ts
27489
27660
  import { lumiaMainnetChain as lumiaMainnetChain2, lumiaTestnetChain as lumiaTestnetChain2 } from "@embarkai/core/read";
27490
27661
  import { getDefaultConfig as getDefaultConfig2 } from "@rainbow-me/rainbowkit";
27491
- import { coinbaseWallet, metaMaskWallet, rainbowWallet, walletConnectWallet } from "@rainbow-me/rainbowkit/wallets";
27662
+ import {
27663
+ binanceWallet,
27664
+ metaMaskWallet,
27665
+ rainbowWallet,
27666
+ walletConnectWallet
27667
+ } from "@rainbow-me/rainbowkit/wallets";
27492
27668
  import { createStorage } from "wagmi";
27493
27669
  import { arbitrum, avalanche, base, bsc as bsc2, mainnet, optimism, polygon, zora } from "wagmi/chains";
27494
27670
  var getProjectId2, WALLET_MAP, getWagmiStorageKey, buildRainbowChains, createRainbowConfig, rainbowTheme;
@@ -27504,8 +27680,9 @@ var init_rainbowkit = __esm({
27504
27680
  WALLET_MAP = {
27505
27681
  walletconnect: walletConnectWallet,
27506
27682
  metamask: metaMaskWallet,
27507
- coinbase: coinbaseWallet,
27508
- rainbow: rainbowWallet
27683
+ // coinbase: coinbaseWallet,
27684
+ rainbow: rainbowWallet,
27685
+ binance: binanceWallet
27509
27686
  };
27510
27687
  getWagmiStorageKey = (options) => {
27511
27688
  const projectId = options?.projectId || "default";
@@ -27801,54 +27978,15 @@ var init_utils11 = __esm({
27801
27978
  }
27802
27979
  });
27803
27980
 
27804
- // src/config/wagmi.ts
27805
- import { lumiaMainnetChain as lumiaprism2, lumiaTestnetChain as lumiaTestnetChain3 } from "@embarkai/core/read";
27806
- import { fallback } from "viem";
27807
- import { createConfig, createStorage as createStorage2, http as http5 } from "wagmi";
27808
- import { bsc as bsc3, mainnet as ethereum2 } from "wagmi/chains";
27809
- function buildTransport(urls) {
27810
- const transports = urls.map(
27811
- (url) => http5(url, {
27812
- timeout: 1e4,
27813
- retryCount: 0,
27814
- batch: false,
27815
- // Disable batch requests
27816
- fetchOptions: { mode: "cors" }
27817
- })
27818
- );
27819
- if (transports.length === 1) {
27820
- return transports[0];
27821
- }
27822
- return fallback(transports, {
27823
- rank: false,
27824
- retryCount: 0
27825
- });
27826
- }
27827
- var wagmiConfig;
27828
- var init_wagmi = __esm({
27829
- "src/config/wagmi.ts"() {
27830
- wagmiConfig = createConfig({
27831
- chains: [lumiaprism2, lumiaTestnetChain3, bsc3, ethereum2],
27832
- storage: createStorage2({ key: "embark-wagmi-static-v2" }),
27833
- transports: {
27834
- [lumiaTestnetChain3.id]: buildTransport(lumiaTestnetChain3.rpcUrls.default.http),
27835
- [lumiaprism2.id]: buildTransport(lumiaprism2.rpcUrls.default.http),
27836
- [bsc3.id]: http5(),
27837
- [ethereum2.id]: http5()
27838
- }
27839
- });
27840
- }
27841
- });
27842
-
27843
27981
  // src/context/WagmiContext.tsx
27982
+ import { wagmiConfig as wagmiConfig2 } from "@embarkai/core";
27844
27983
  import { WagmiProvider as NativeWagmiProvider } from "wagmi";
27845
27984
  import { jsx as jsx123 } from "react/jsx-runtime";
27846
27985
  var WagmiProvider2;
27847
27986
  var init_WagmiContext = __esm({
27848
27987
  "src/context/WagmiContext.tsx"() {
27849
- init_wagmi();
27850
27988
  WagmiProvider2 = ({ children }) => {
27851
- return /* @__PURE__ */ jsx123(NativeWagmiProvider, { config: wagmiConfig, children });
27989
+ return /* @__PURE__ */ jsx123(NativeWagmiProvider, { config: wagmiConfig2, children });
27852
27990
  };
27853
27991
  }
27854
27992
  });
@@ -28011,6 +28149,7 @@ var built_default = `.container{width:100%}@media (min-width:640px){.container{m
28011
28149
 
28012
28150
  // src/index.ts
28013
28151
  init_ProviderContext();
28152
+ import { wagmiConfig as wagmiConfig3 } from "@embarkai/core";
28014
28153
 
28015
28154
  // src/components/ConnectWalletButton.tsx
28016
28155
  init_LumiaIcon3();
@@ -28419,88 +28558,12 @@ function LangToggle(props) {
28419
28558
  init_useLayoutDataStore();
28420
28559
 
28421
28560
  // src/internal/components/UserOpStatus.tsx
28561
+ init_getUserOperationByHash();
28562
+ init_getUserOperationReceipt();
28563
+ init_cn();
28422
28564
  import { AlertCircle as AlertCircle8, CheckCircle2 as CheckCircle27, Clock as Clock2, Copy as Copy7, ExternalLink as ExternalLink3, RefreshCw as RefreshCw4 } from "lucide-react";
28423
28565
  import * as React11 from "react";
28424
28566
 
28425
- // src/clients/bundler/getUserOperationByHash.ts
28426
- init_SessionContext();
28427
- import { bundlerRpc } from "@embarkai/core";
28428
- import { getChainConfig as getChainConfig11 } from "@embarkai/core/read";
28429
- async function getUserOperationByHash(userOpHash, chainId) {
28430
- const targetChainId = chainId ?? requireActiveChainId();
28431
- const chainConfig = getChainConfig11(targetChainId);
28432
- if (!chainConfig) {
28433
- throw new Error(`Chain ${targetChainId} is not supported`);
28434
- }
28435
- if (!chainConfig.bundlerUrl) {
28436
- throw new Error(`Chain ${targetChainId} has no bundlerUrl configured`);
28437
- }
28438
- if (!userOpHash) {
28439
- throw new Error("Operation hash is required");
28440
- }
28441
- try {
28442
- const result = await bundlerRpc("eth_getUserOperationByHash", [userOpHash], chainConfig.bundlerUrl);
28443
- if (!result) {
28444
- return null;
28445
- }
28446
- console.log("[getUserOperationByHash] Receipt:", JSON.stringify(result, null, 2));
28447
- return {
28448
- entryPoint: result.entryPoint,
28449
- userOperation: result.userOperation,
28450
- transactionHash: result.transactionHash,
28451
- blockNumber: result.blockNumber,
28452
- blockHash: result.blockHash
28453
- };
28454
- } catch (error) {
28455
- console.warn("[getUserOperationByHash] Failed to get user operation:", error);
28456
- return null;
28457
- }
28458
- }
28459
-
28460
- // src/clients/bundler/getUserOperationReceipt.ts
28461
- init_SessionContext();
28462
- import { bundlerRpc as bundlerRpc2 } from "@embarkai/core";
28463
- import { getChainConfig as getChainConfig12 } from "@embarkai/core/read";
28464
- async function getUserOperationReceipt(userOpHash, chainId) {
28465
- const targetChainId = chainId ?? requireActiveChainId();
28466
- const chainConfig = getChainConfig12(targetChainId);
28467
- if (!chainConfig) {
28468
- throw new Error(`Chain ${targetChainId} is not supported`);
28469
- }
28470
- if (!chainConfig.bundlerUrl) {
28471
- throw new Error(`Chain ${targetChainId} has no bundlerUrl configured`);
28472
- }
28473
- if (!userOpHash) {
28474
- throw new Error("Operation hash is required");
28475
- }
28476
- try {
28477
- const result = await bundlerRpc2("eth_getUserOperationReceipt", [userOpHash], chainConfig.bundlerUrl);
28478
- if (!result) {
28479
- return null;
28480
- }
28481
- console.log("[getUserOperationReceipt] Receipt:", JSON.stringify(result, null, 2));
28482
- return {
28483
- userOpHash: result.userOpHash,
28484
- entryPoint: result.entryPoint,
28485
- sender: result.sender,
28486
- nonce: result.nonce,
28487
- success: result.success,
28488
- actualGasCost: result.actualGasCost,
28489
- actualGasUsed: result.actualGasUsed,
28490
- paymaster: result.paymaster,
28491
- receipt: result.receipt,
28492
- logs: result.logs,
28493
- reason: result.reason
28494
- };
28495
- } catch (error) {
28496
- console.warn("[getUserOperationReceipt] Failed to get receipt:", error);
28497
- return null;
28498
- }
28499
- }
28500
-
28501
- // src/internal/components/UserOpStatus.tsx
28502
- init_cn();
28503
-
28504
28567
  // src/internal/components/Address.tsx
28505
28568
  init_cn();
28506
28569
  init_button();
@@ -29017,38 +29080,8 @@ init_vaultClient();
29017
29080
  init_useSendTransaction();
29018
29081
 
29019
29082
  // src/hooks/useUserOpStatus.ts
29083
+ init_bundler();
29020
29084
  import * as React14 from "react";
29021
-
29022
- // src/clients/bundler/waitForUserOperationReceipt.ts
29023
- init_SessionContext();
29024
- var UserOperationTimeoutError = class extends Error {
29025
- constructor(userOpHash, chainId, timeoutMs) {
29026
- super(`Timeout waiting for UserOperation receipt after ${timeoutMs}ms (hash: ${userOpHash}, chainId: ${chainId})`);
29027
- this.name = "UserOperationTimeoutError";
29028
- this.userOpHash = userOpHash;
29029
- this.chainId = chainId;
29030
- this.timeoutMs = timeoutMs;
29031
- }
29032
- };
29033
- async function waitForUserOperationReceipt(userOpHash, options) {
29034
- const pollIntervalMs = options?.pollIntervalMs ?? 1e3;
29035
- const maxPollTimeMs = options?.maxPollTimeMs ?? 6e4;
29036
- const targetChainId = options?.chainId ?? requireActiveChainId();
29037
- const startTime = Date.now();
29038
- while (true) {
29039
- const elapsed = Date.now() - startTime;
29040
- if (elapsed >= maxPollTimeMs) {
29041
- throw new UserOperationTimeoutError(userOpHash, targetChainId, maxPollTimeMs);
29042
- }
29043
- const receipt = await getUserOperationReceipt(userOpHash, targetChainId);
29044
- if (receipt) {
29045
- return receipt;
29046
- }
29047
- await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
29048
- }
29049
- }
29050
-
29051
- // src/hooks/useUserOpStatus.ts
29052
29085
  function useUserOpStatus(options = {}) {
29053
29086
  const {
29054
29087
  userOpHash,
@@ -29468,13 +29501,17 @@ function useLogout() {
29468
29501
  // src/index.ts
29469
29502
  init_useNicknameResolve();
29470
29503
  init_account2();
29504
+
29505
+ // src/clients/index.ts
29506
+ init_bundler();
29507
+
29508
+ // src/index.ts
29471
29509
  init_auth();
29472
29510
  init_profile();
29473
29511
  init_hooks2();
29474
29512
  init_linkedProfiles();
29475
29513
  init_nickname_fingerprint();
29476
29514
  init_errors();
29477
- init_wagmi();
29478
29515
  init_base();
29479
29516
  init_useBlockscoutAssets();
29480
29517
 
@@ -29866,7 +29903,7 @@ export {
29866
29903
  useWalletMode,
29867
29904
  verifyFingerprint,
29868
29905
  verifyFingerprintDetailed,
29869
- wagmiConfig,
29906
+ wagmiConfig3 as wagmiConfig,
29870
29907
  waitForStoreHydration,
29871
29908
  waitForUserOperationReceipt
29872
29909
  };