@trustware/sdk-staging 1.1.8-staging.4 → 1.1.8-staging.6

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.cjs CHANGED
@@ -442,7 +442,7 @@ var init_constants = __esm({
442
442
  "src/constants.ts"() {
443
443
  "use strict";
444
444
  SDK_NAME = "@trustware/sdk";
445
- SDK_VERSION = "1.1.8-staging.4";
445
+ SDK_VERSION = "1.1.8-staging.6";
446
446
  API_ROOT = "https://bv-staging-api.trustware.io";
447
447
  GTM_ID = "GTM-TZDGNCXB";
448
448
  API_PREFIX = "/api";
@@ -684,6 +684,134 @@ var init_sdkRpc = __esm({
684
684
  });
685
685
 
686
686
  // src/wallets/solana.ts
687
+ function encodeBase58(bytes) {
688
+ const digits = [0];
689
+ for (const byte of bytes) {
690
+ let carry = byte;
691
+ for (let i = 0; i < digits.length; i++) {
692
+ carry += digits[i] << 8;
693
+ digits[i] = carry % 58;
694
+ carry = carry / 58 | 0;
695
+ }
696
+ while (carry > 0) {
697
+ digits.push(carry % 58);
698
+ carry = carry / 58 | 0;
699
+ }
700
+ }
701
+ let result = "";
702
+ for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {
703
+ result += "1";
704
+ }
705
+ for (let i = digits.length - 1; i >= 0; i--) {
706
+ result += BASE58_ALPHABET[digits[i]];
707
+ }
708
+ return result;
709
+ }
710
+ function collectWalletStandardWallets() {
711
+ if (typeof window === "undefined") return [];
712
+ const collected = [];
713
+ const api = {
714
+ register(...wallets) {
715
+ collected.push(...wallets);
716
+ return () => {
717
+ };
718
+ }
719
+ };
720
+ try {
721
+ window.dispatchEvent(
722
+ Object.assign(
723
+ new Event("wallet-standard:app-ready", { bubbles: false }),
724
+ {
725
+ detail: api
726
+ }
727
+ )
728
+ );
729
+ } catch {
730
+ }
731
+ return collected;
732
+ }
733
+ function walletStandardToSolanaProvider(wallet) {
734
+ let currentAccount = wallet.accounts[0] ?? null;
735
+ const provider = {
736
+ get isConnected() {
737
+ return !!currentAccount;
738
+ },
739
+ get publicKey() {
740
+ if (!currentAccount) return void 0;
741
+ const addr = currentAccount.address;
742
+ return { toString: () => addr };
743
+ },
744
+ async connect() {
745
+ const feature = wallet.features["standard:connect"];
746
+ if (!feature?.connect)
747
+ throw new Error("Wallet Standard connect not available");
748
+ const result = await feature.connect({ silent: false });
749
+ currentAccount = result.accounts[0] ?? null;
750
+ if (!currentAccount)
751
+ throw new Error("No Solana account returned from MetaMask");
752
+ return { publicKey: { toString: () => currentAccount.address } };
753
+ },
754
+ async disconnect() {
755
+ const feature = wallet.features["standard:disconnect"];
756
+ await feature?.disconnect?.();
757
+ currentAccount = null;
758
+ },
759
+ async signAndSendTransaction(transaction, options) {
760
+ const feature = wallet.features["solana:signAndSendTransaction"];
761
+ if (!feature?.signAndSendTransaction || !currentAccount) {
762
+ throw new Error("signAndSendTransaction not available");
763
+ }
764
+ const txBytes = transaction.serialize();
765
+ const results = await feature.signAndSendTransaction({
766
+ account: currentAccount,
767
+ transaction: txBytes,
768
+ chain: SOLANA_MAINNET_CHAIN,
769
+ options
770
+ });
771
+ const sig = results[0]?.signature;
772
+ if (!sig) throw new Error("No signature returned");
773
+ return typeof sig === "string" ? sig : encodeBase58(sig);
774
+ },
775
+ async signTransaction(transaction) {
776
+ const feature = wallet.features["solana:signTransaction"];
777
+ if (!feature?.signTransaction || !currentAccount) {
778
+ throw new Error("signTransaction not available");
779
+ }
780
+ const txBytes = transaction.serialize();
781
+ const results = await feature.signTransaction({
782
+ account: currentAccount,
783
+ transaction: txBytes,
784
+ chain: SOLANA_MAINNET_CHAIN
785
+ });
786
+ const signed = results[0]?.signedTransaction;
787
+ if (!signed) throw new Error("No signed transaction returned");
788
+ return { serialize: () => signed };
789
+ },
790
+ on() {
791
+ },
792
+ off() {
793
+ },
794
+ removeListener() {
795
+ }
796
+ };
797
+ return provider;
798
+ }
799
+ function detectMetaMaskSolanaWallet(wallets) {
800
+ const meta = wallets.find((w) => w.id === "metamask-solana");
801
+ if (!meta) return [];
802
+ const standardWallets = collectWalletStandardWallets();
803
+ const mmWallet = standardWallets.find(
804
+ (w) => w.name.toLowerCase().includes("metamask") && w.chains.some((c) => c.startsWith("solana:"))
805
+ );
806
+ if (!mmWallet) return [];
807
+ return [
808
+ {
809
+ meta,
810
+ provider: walletStandardToSolanaProvider(mmWallet),
811
+ via: "solana-window"
812
+ }
813
+ ];
814
+ }
687
815
  function getPublicKeyString(provider) {
688
816
  const publicKey = provider?.publicKey;
689
817
  if (!publicKey) return null;
@@ -745,12 +873,13 @@ function getSolanaProviders() {
745
873
  }
746
874
  function detectSolanaWallets(wallets) {
747
875
  const providers = getSolanaProviders();
748
- return SOLANA_WALLET_IDS.flatMap((walletId) => {
876
+ const windowDetected = SOLANA_WALLET_IDS.flatMap((walletId) => {
749
877
  const provider = providers[walletId];
750
878
  const meta = wallets.find((item) => item.id === walletId);
751
879
  if (!provider || !meta) return [];
752
880
  return [{ meta, provider, via: "solana-window" }];
753
881
  });
882
+ return [...windowDetected, ...detectMetaMaskSolanaWallet(wallets)];
754
883
  }
755
884
  function bindSolanaProviderEvents(provider, handlers) {
756
885
  const onConnect = () => handlers.onConnect?.();
@@ -815,7 +944,7 @@ function toSolanaWalletInterface(provider) {
815
944
  }
816
945
  };
817
946
  }
818
- var SOLANA_WALLET_IDS;
947
+ var SOLANA_WALLET_IDS, SOLANA_MAINNET_CHAIN, BASE58_ALPHABET;
819
948
  var init_solana = __esm({
820
949
  "src/wallets/solana.ts"() {
821
950
  "use strict";
@@ -825,6 +954,8 @@ var init_solana = __esm({
825
954
  "solflare",
826
955
  "backpack"
827
956
  ];
957
+ SOLANA_MAINNET_CHAIN = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
958
+ BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
828
959
  }
829
960
  });
830
961
 
@@ -998,6 +1129,15 @@ var init_metadata = __esm({
998
1129
  ios: "https://apps.apple.com/app/phantom-crypto-wallet/id1598432977",
999
1130
  deepLink: (url) => `phantom://browse/${encodeURIComponent(url)}`
1000
1131
  },
1132
+ {
1133
+ id: "metamask-solana",
1134
+ name: "MetaMask (Solana)",
1135
+ category: "injected",
1136
+ ecosystem: "solana",
1137
+ logo: `${ASSETS_BASE_URL}/assets/wallets/metamask.svg`,
1138
+ emoji: "\u{1F98A}",
1139
+ homepage: "https://metamask.io/"
1140
+ },
1001
1141
  {
1002
1142
  id: "solflare",
1003
1143
  name: "Solflare",
@@ -7283,7 +7423,9 @@ function applyWalletTokenState({
7283
7423
  const selectedTokenStillExists = selectedToken && sortedTokens.some(
7284
7424
  (token) => normalizeChainKey2(token.chainId) === normalizeChainKey2(selectedToken.chainId) && token.address === selectedToken.address
7285
7425
  );
7286
- const nextSelectedToken = selectedTokenStillExists && selectedToken ? selectedToken : sortedTokens.find((token) => Number(token.balance) > 0) ?? null;
7426
+ const nextSelectedToken = selectedTokenStillExists && selectedToken ? sortedTokens.find(
7427
+ (token) => normalizeChainKey2(token.chainId) === normalizeChainKey2(selectedToken.chainId) && token.address === selectedToken.address
7428
+ ) ?? selectedToken : sortedTokens.find((token) => Number(token.balance) > 0) ?? null;
7287
7429
  setSelectedToken(nextSelectedToken);
7288
7430
  if (nextSelectedToken && (!selectedChain || normalizeChainKey2(selectedChain.chainId) !== normalizeChainKey2(
7289
7431
  hasChainData(nextSelectedToken) ? nextSelectedToken.chainData?.chainId ?? null : nextSelectedToken.chainId
@@ -13586,10 +13728,12 @@ function useDepositAmountModel({
13586
13728
  ]);
13587
13729
  const amountWei = amountValidationError ? 0n : amountComputation.fromAmountWei ?? 0n;
13588
13730
  const parsedAmount = parseFloat(fixedFromAmountString ?? amount) || 0;
13589
- const maxTokenAmount = (0, import_react31.useMemo)(
13590
- () => Math.min(normalizedTokenBalance, 1e4),
13591
- [normalizedTokenBalance]
13592
- );
13731
+ const maxTokenAmount = (0, import_react31.useMemo)(() => {
13732
+ const cap = Math.min(normalizedTokenBalance, 1e4);
13733
+ const token = selectedToken;
13734
+ const isSolNative = token?.category === "native" && typeof token.chain_key === "string" && token.chain_key.toLowerCase().includes("solana");
13735
+ return isSolNative ? Math.max(0, cap - 0.01) : cap;
13736
+ }, [normalizedTokenBalance, selectedToken]);
13593
13737
  const maxUsdAmount = (0, import_react31.useMemo)(() => {
13594
13738
  if (!hasUsdPrice) return void 0;
13595
13739
  return Math.min(maxTokenAmount * tokenPriceUSD, 1e4);
@@ -30558,7 +30702,8 @@ function sleep3(ms) {
30558
30702
  }
30559
30703
  function isUserRejection(err) {
30560
30704
  if (!err) return false;
30561
- const code = err?.code;
30705
+ const e2 = err;
30706
+ const code = e2?.code ?? e2?.data?.code;
30562
30707
  if (code === 4001) return true;
30563
30708
  const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();
30564
30709
  return msg.includes("user rejected") || msg.includes("user denied") || msg.includes("cancelled");
@@ -30707,6 +30852,26 @@ function useSwapExecution(fromChain) {
30707
30852
  );
30708
30853
  const canUseSA = !!routeResult.sponsorship && Date.now() >= saFailedUntilRef.current && wallet?.ecosystem === "evm" && wallet.type === "eip1193" && !isNative && !!walletAddress && Number.isFinite(numericChainId);
30709
30854
  if (canUseSA) {
30855
+ if (numericChainId && wallet) {
30856
+ try {
30857
+ const currentChainId = await wallet.getChainId();
30858
+ if (currentChainId !== numericChainId) {
30859
+ await wallet.switchChain(numericChainId);
30860
+ }
30861
+ } catch (switchErr) {
30862
+ if (isUserRejection(switchErr)) {
30863
+ const msg = mapTxError(switchErr);
30864
+ setState((p) => ({
30865
+ ...p,
30866
+ isSubmitting: false,
30867
+ txStatus: "error",
30868
+ errorMessage: msg
30869
+ }));
30870
+ onError(msg);
30871
+ return;
30872
+ }
30873
+ }
30874
+ }
30710
30875
  try {
30711
30876
  const mod = await Promise.resolve().then(() => (init_smart_account2(), smart_account_exports));
30712
30877
  const result = await mod.sendRouteAsUserOperation({
@@ -31254,11 +31419,18 @@ function SwapWalletSelector({
31254
31419
  onBack
31255
31420
  }) {
31256
31421
  const { detected } = useWalletDetection();
31422
+ const {
31423
+ isConnected: managerConnected,
31424
+ walletMetaId,
31425
+ connectedVia,
31426
+ disconnect
31427
+ } = useWalletInfo();
31428
+ const walletConnectCfg = TrustwareConfigStore.peek()?.walletConnect;
31429
+ const connectWC = useWalletConnectConnect(walletConnectCfg);
31430
+ const [wcConnecting, setWcConnecting] = (0, import_react45.useState)(false);
31257
31431
  const [connectingId, setConnectingId] = (0, import_react45.useState)(null);
31258
- const [connectedWalletId, setConnectedWalletId] = (0, import_react45.useState)(
31259
- null
31260
- );
31261
31432
  const [timerExpired, setTimerExpired] = (0, import_react45.useState)(false);
31433
+ const [selectedNamespace, setSelectedNamespace] = (0, import_react45.useState)("evm");
31262
31434
  const prevStatusRef = (0, import_react45.useRef)(walletStatus);
31263
31435
  (0, import_react45.useEffect)(() => {
31264
31436
  const t = setTimeout(() => setTimerExpired(true), 450);
@@ -31273,16 +31445,48 @@ function SwapWalletSelector({
31273
31445
  prevStatusRef.current = walletStatus;
31274
31446
  }
31275
31447
  }, [walletStatus]);
31448
+ const filteredWallets = (0, import_react45.useMemo)(
31449
+ () => detected.filter(
31450
+ (w) => (w.meta?.ecosystem ?? "").toLowerCase() === selectedNamespace
31451
+ ),
31452
+ [detected, selectedNamespace]
31453
+ );
31454
+ const isDetecting = detected.length === 0 && !timerExpired;
31455
+ const handleDisconnect = () => {
31456
+ void disconnect();
31457
+ };
31458
+ const handleWalletConnect = async () => {
31459
+ if (wcConnecting) return;
31460
+ if (connectedVia === "walletconnect" && managerConnected) {
31461
+ onBack();
31462
+ return;
31463
+ }
31464
+ setWcConnecting(true);
31465
+ try {
31466
+ const { error } = await connectWC();
31467
+ if (error) {
31468
+ toast.error("WalletConnect Failed", error);
31469
+ }
31470
+ } catch (err) {
31471
+ const msg = err instanceof Error ? err.message : "WalletConnect failed";
31472
+ toast.error("WalletConnect Failed", msg);
31473
+ } finally {
31474
+ setWcConnecting(false);
31475
+ }
31476
+ };
31276
31477
  const handleClick = async (wallet) => {
31277
31478
  if (walletStatus === "connecting") return;
31278
31479
  if (wallet.meta.id === "walletconnect" || wallet.via === "walletconnect") {
31279
31480
  toast.error("Not Available", "WalletConnect is not currently available.");
31280
31481
  return;
31281
31482
  }
31483
+ if (managerConnected && walletMetaId === wallet.meta.id) {
31484
+ onBack();
31485
+ return;
31486
+ }
31282
31487
  setConnectingId(wallet.meta.id);
31283
31488
  try {
31284
31489
  await connectWallet(wallet);
31285
- setConnectedWalletId(wallet.meta.id);
31286
31490
  } catch (err) {
31287
31491
  setConnectingId(null);
31288
31492
  const msg = err instanceof Error ? err.message : "Failed to connect wallet";
@@ -31296,7 +31500,10 @@ function SwapWalletSelector({
31296
31500
  }
31297
31501
  }
31298
31502
  };
31299
- const isDetecting = detected.length === 0 && !timerExpired;
31503
+ const tabs = [
31504
+ { id: "evm", label: "EVM" },
31505
+ { id: "solana", label: "Solana" }
31506
+ ];
31300
31507
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { style: { display: "flex", flexDirection: "column" }, children: [
31301
31508
  /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
31302
31509
  "div",
@@ -31353,134 +31560,348 @@ function SwapWalletSelector({
31353
31560
  fontSize: fontSize.lg,
31354
31561
  fontWeight: fontWeight.semibold,
31355
31562
  color: colors.foreground,
31356
- textAlign: "center",
31357
- marginRight: "1.75rem"
31563
+ textAlign: "center"
31358
31564
  },
31359
31565
  children: "Connect Wallet"
31360
31566
  }
31361
- )
31362
- ]
31363
- }
31364
- ),
31365
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { style: { padding: spacing[4] }, children: isDetecting ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
31366
- "div",
31367
- {
31368
- style: {
31369
- display: "flex",
31370
- flexDirection: "column",
31371
- gap: spacing[3]
31372
- },
31373
- children: [
31374
- [1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
31567
+ ),
31568
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
31375
31569
  "div",
31376
31570
  {
31377
31571
  style: {
31572
+ position: "relative",
31378
31573
  display: "flex",
31379
31574
  alignItems: "center",
31380
- gap: spacing[4],
31381
- padding: spacing[4],
31382
- borderRadius: borderRadius["2xl"],
31383
- backgroundColor: colors.muted,
31384
- animation: "tw-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
31575
+ borderRadius: "9999px",
31576
+ background: colors.background,
31577
+ border: `1px solid ${colors.mutedForeground}`,
31578
+ padding: "3px"
31385
31579
  },
31386
31580
  children: [
31387
31581
  /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31388
31582
  "div",
31389
31583
  {
31390
31584
  style: {
31391
- width: "3rem",
31392
- height: "3rem",
31393
- borderRadius: borderRadius.xl,
31394
- backgroundColor: "rgba(161,161,170,0.2)"
31585
+ position: "absolute",
31586
+ top: 3,
31587
+ bottom: 3,
31588
+ width: "calc(50% - 3px)",
31589
+ borderRadius: "9999px",
31590
+ background: `linear-gradient(to bottom, ${colors.zinc[100]}, ${colors.zinc[200]})`,
31591
+ border: `1px solid ${colors.mutedForeground}`,
31592
+ transition: "transform 300ms ease-out",
31593
+ transform: selectedNamespace === "evm" ? "translateX(0)" : "translateX(100%)"
31395
31594
  }
31396
31595
  }
31397
31596
  ),
31398
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31399
- "div",
31597
+ tabs.map((t) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31598
+ "button",
31400
31599
  {
31600
+ onClick: () => setSelectedNamespace(t.id),
31401
31601
  style: {
31402
- height: "1rem",
31403
- width: "6rem",
31404
- borderRadius: borderRadius.md,
31405
- backgroundColor: "rgba(161,161,170,0.2)"
31406
- }
31407
- }
31408
- )
31602
+ position: "relative",
31603
+ zIndex: 10,
31604
+ padding: "4px 11px",
31605
+ fontSize: "10px",
31606
+ outline: "none",
31607
+ fontWeight: 600,
31608
+ borderRadius: "9999px",
31609
+ background: "transparent",
31610
+ border: "none",
31611
+ cursor: "pointer",
31612
+ transition: "color 200ms",
31613
+ color: selectedNamespace === t.id ? colors.black : colors.mutedForeground
31614
+ },
31615
+ children: t.label
31616
+ },
31617
+ t.id
31618
+ ))
31409
31619
  ]
31410
- },
31411
- i
31412
- )),
31413
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31414
- "p",
31415
- {
31416
- style: {
31417
- textAlign: "center",
31418
- fontSize: fontSize.sm,
31419
- color: colors.mutedForeground,
31420
- marginTop: spacing[4]
31421
- },
31422
- children: "Detecting wallets..."
31423
31620
  }
31424
31621
  )
31425
31622
  ]
31426
31623
  }
31427
- ) : detected.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { style: { textAlign: "center", padding: `${spacing[8]} 0` }, children: [
31428
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { style: { fontSize: "2.5rem", marginBottom: spacing[4] }, children: "\u{1F45B}" }),
31429
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31430
- "h3",
31624
+ ),
31625
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { style: { padding: spacing[4] }, children: [
31626
+ isDetecting ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
31627
+ "div",
31431
31628
  {
31432
31629
  style: {
31433
- fontSize: fontSize.lg,
31434
- fontWeight: fontWeight.semibold,
31435
- color: colors.foreground,
31436
- marginBottom: spacing[2]
31630
+ display: "flex",
31631
+ flexDirection: "column",
31632
+ gap: spacing[3]
31437
31633
  },
31438
- children: "No Wallets Found"
31634
+ children: [
31635
+ [1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
31636
+ "div",
31637
+ {
31638
+ style: {
31639
+ display: "flex",
31640
+ alignItems: "center",
31641
+ gap: spacing[4],
31642
+ padding: spacing[4],
31643
+ borderRadius: borderRadius["2xl"],
31644
+ backgroundColor: colors.muted,
31645
+ animation: "tw-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
31646
+ },
31647
+ children: [
31648
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31649
+ "div",
31650
+ {
31651
+ style: {
31652
+ width: "3rem",
31653
+ height: "3rem",
31654
+ borderRadius: borderRadius.xl,
31655
+ backgroundColor: "rgba(161,161,170,0.2)"
31656
+ }
31657
+ }
31658
+ ),
31659
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31660
+ "div",
31661
+ {
31662
+ style: {
31663
+ height: "1rem",
31664
+ width: "6rem",
31665
+ borderRadius: borderRadius.md,
31666
+ backgroundColor: "rgba(161,161,170,0.2)"
31667
+ }
31668
+ }
31669
+ )
31670
+ ]
31671
+ },
31672
+ i
31673
+ )),
31674
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31675
+ "p",
31676
+ {
31677
+ style: {
31678
+ textAlign: "center",
31679
+ fontSize: fontSize.sm,
31680
+ color: colors.mutedForeground,
31681
+ marginTop: spacing[4]
31682
+ },
31683
+ children: "Detecting wallets..."
31684
+ }
31685
+ )
31686
+ ]
31439
31687
  }
31440
- ),
31441
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31442
- "p",
31688
+ ) : filteredWallets.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { style: { textAlign: "center", padding: `${spacing[8]} 0` }, children: [
31689
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { style: { fontSize: "2.5rem", marginBottom: spacing[4] }, children: "\u{1F45B}" }),
31690
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31691
+ "h3",
31692
+ {
31693
+ style: {
31694
+ fontSize: fontSize.lg,
31695
+ fontWeight: fontWeight.semibold,
31696
+ color: colors.foreground,
31697
+ marginBottom: spacing[2]
31698
+ },
31699
+ children: "No Wallets Found"
31700
+ }
31701
+ ),
31702
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31703
+ "p",
31704
+ {
31705
+ style: {
31706
+ fontSize: fontSize.sm,
31707
+ color: colors.mutedForeground,
31708
+ marginBottom: spacing[4]
31709
+ },
31710
+ children: "Please install a web3 wallet to continue."
31711
+ }
31712
+ ),
31713
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31714
+ "a",
31715
+ {
31716
+ href: "https://metamask.io/download/",
31717
+ target: "_blank",
31718
+ rel: "noopener noreferrer",
31719
+ style: {
31720
+ display: "inline-flex",
31721
+ alignItems: "center",
31722
+ justifyContent: "center",
31723
+ padding: `${spacing[2]} ${spacing[4]}`,
31724
+ borderRadius: borderRadius.lg,
31725
+ backgroundColor: colors.primary,
31726
+ color: colors.primaryForeground,
31727
+ fontSize: fontSize.sm,
31728
+ fontWeight: fontWeight.medium,
31729
+ textDecoration: "none"
31730
+ },
31731
+ children: "Install MetaMask"
31732
+ }
31733
+ )
31734
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31735
+ "div",
31443
31736
  {
31444
31737
  style: {
31445
- fontSize: fontSize.sm,
31446
- color: colors.mutedForeground,
31447
- marginBottom: spacing[4]
31738
+ display: "flex",
31739
+ flexDirection: "column",
31740
+ gap: spacing[3]
31448
31741
  },
31449
- children: "Please install a web3 wallet to continue."
31742
+ children: filteredWallets.map((wallet) => {
31743
+ const isWalletConnected = managerConnected && walletMetaId === wallet.meta.id;
31744
+ const isConnecting = connectingId === wallet.meta.id && walletStatus === "connecting";
31745
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
31746
+ "div",
31747
+ {
31748
+ style: mergeStyles(
31749
+ {
31750
+ width: "100%",
31751
+ display: "flex",
31752
+ alignItems: "center",
31753
+ gap: spacing[4],
31754
+ padding: spacing[4],
31755
+ borderRadius: borderRadius["2xl"],
31756
+ backgroundColor: colors.card,
31757
+ border: `1px solid ${colors.border}`
31758
+ },
31759
+ isWalletConnected && {
31760
+ boxShadow: `0 0 0 2px ${colors.primary}`,
31761
+ border: `1px solid ${colors.primary}`
31762
+ }
31763
+ ),
31764
+ children: [
31765
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31766
+ "div",
31767
+ {
31768
+ style: {
31769
+ width: "3rem",
31770
+ height: "3rem",
31771
+ borderRadius: borderRadius.xl,
31772
+ backgroundColor: colors.muted,
31773
+ display: "flex",
31774
+ alignItems: "center",
31775
+ justifyContent: "center",
31776
+ overflow: "hidden",
31777
+ flexShrink: 0
31778
+ },
31779
+ children: wallet.meta.logo ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31780
+ "img",
31781
+ {
31782
+ src: wallet.meta.logo,
31783
+ alt: wallet.meta.name,
31784
+ style: {
31785
+ width: "2rem",
31786
+ height: "2rem",
31787
+ objectFit: "contain"
31788
+ }
31789
+ }
31790
+ ) : wallet.detail?.info?.icon ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31791
+ "img",
31792
+ {
31793
+ src: wallet.detail.info.icon,
31794
+ alt: wallet.meta.name,
31795
+ style: {
31796
+ width: "2rem",
31797
+ height: "2rem",
31798
+ objectFit: "contain"
31799
+ }
31800
+ }
31801
+ ) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { style: { fontSize: "1.5rem" }, children: wallet.meta.emoji || "\u{1F45B}" })
31802
+ }
31803
+ ),
31804
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
31805
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31806
+ "p",
31807
+ {
31808
+ style: {
31809
+ fontWeight: fontWeight.semibold,
31810
+ color: colors.foreground
31811
+ },
31812
+ children: wallet.meta.name
31813
+ }
31814
+ ),
31815
+ isWalletConnected && walletAddress && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
31816
+ "p",
31817
+ {
31818
+ style: {
31819
+ fontSize: fontSize.xs,
31820
+ color: colors.mutedForeground
31821
+ },
31822
+ children: [
31823
+ walletAddress.slice(0, 6),
31824
+ "...",
31825
+ walletAddress.slice(-4)
31826
+ ]
31827
+ }
31828
+ )
31829
+ ] }),
31830
+ isConnecting ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31831
+ "div",
31832
+ {
31833
+ style: {
31834
+ width: "1.25rem",
31835
+ height: "1.25rem",
31836
+ border: `2px solid ${colors.mutedForeground}`,
31837
+ borderTopColor: "transparent",
31838
+ borderRadius: "9999px",
31839
+ animation: "tw-spin 1s linear infinite",
31840
+ flexShrink: 0
31841
+ }
31842
+ }
31843
+ ) : isWalletConnected ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31844
+ "button",
31845
+ {
31846
+ onClick: handleDisconnect,
31847
+ style: {
31848
+ padding: `${spacing[1.5]} ${spacing[3]}`,
31849
+ borderRadius: "9999px",
31850
+ backgroundColor: "rgba(239,68,68,0.1)",
31851
+ color: "#ef4444",
31852
+ fontSize: fontSize.xs,
31853
+ fontWeight: fontWeight.medium,
31854
+ border: 0,
31855
+ cursor: "pointer",
31856
+ flexShrink: 0
31857
+ },
31858
+ children: "Disconnect"
31859
+ }
31860
+ ) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31861
+ "button",
31862
+ {
31863
+ onClick: () => void handleClick(wallet),
31864
+ disabled: walletStatus === "connecting",
31865
+ style: mergeStyles(
31866
+ {
31867
+ padding: `${spacing[1.5]} ${spacing[3]}`,
31868
+ borderRadius: "9999px",
31869
+ backgroundColor: "rgba(59,130,246,0.1)",
31870
+ color: colors.primary,
31871
+ fontSize: fontSize.xs,
31872
+ fontWeight: fontWeight.medium,
31873
+ border: 0,
31874
+ cursor: "pointer",
31875
+ flexShrink: 0
31876
+ },
31877
+ walletStatus === "connecting" && {
31878
+ opacity: 0.5,
31879
+ cursor: "not-allowed"
31880
+ }
31881
+ ),
31882
+ children: "Connect"
31883
+ }
31884
+ )
31885
+ ]
31886
+ },
31887
+ wallet.meta.id
31888
+ );
31889
+ })
31450
31890
  }
31451
31891
  ),
31452
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31453
- "a",
31454
- {
31455
- href: "https://metamask.io/download/",
31456
- target: "_blank",
31457
- rel: "noopener noreferrer",
31458
- style: {
31459
- display: "inline-flex",
31460
- alignItems: "center",
31461
- justifyContent: "center",
31462
- padding: `${spacing[2]} ${spacing[4]}`,
31463
- borderRadius: borderRadius.lg,
31464
- backgroundColor: colors.primary,
31465
- color: colors.primaryForeground,
31466
- fontSize: fontSize.sm,
31467
- fontWeight: fontWeight.medium,
31468
- textDecoration: "none"
31469
- },
31470
- children: "Install MetaMask"
31471
- }
31472
- )
31473
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31474
- "div",
31475
- {
31476
- style: {
31477
- display: "flex",
31478
- flexDirection: "column",
31479
- gap: spacing[3]
31480
- },
31481
- children: detected.map((wallet) => {
31482
- const isConnecting = connectingId === wallet.meta.id;
31483
- const isConnected = walletStatus === "connected" && connectingId === null && walletAddress !== null && connectedWalletId === wallet.meta.id;
31892
+ selectedNamespace === "evm" && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
31893
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31894
+ "div",
31895
+ {
31896
+ style: {
31897
+ height: 1,
31898
+ backgroundColor: colors.border,
31899
+ margin: `${spacing[3]} 0`
31900
+ }
31901
+ }
31902
+ ),
31903
+ (() => {
31904
+ const wcConnected = managerConnected && connectedVia === "walletconnect";
31484
31905
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
31485
31906
  "div",
31486
31907
  {
@@ -31493,13 +31914,15 @@ function SwapWalletSelector({
31493
31914
  padding: spacing[4],
31494
31915
  borderRadius: borderRadius["2xl"],
31495
31916
  backgroundColor: colors.card,
31496
- border: `1px solid ${colors.border}`
31917
+ border: `1px solid ${colors.border}`,
31918
+ cursor: "pointer"
31497
31919
  },
31498
- isConnected && {
31920
+ wcConnected && {
31499
31921
  boxShadow: `0 0 0 2px ${colors.primary}`,
31500
31922
  border: `1px solid ${colors.primary}`
31501
31923
  }
31502
31924
  ),
31925
+ onClick: !wcConnected ? () => void handleWalletConnect() : void 0,
31503
31926
  children: [
31504
31927
  /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31505
31928
  "div",
@@ -31512,35 +31935,24 @@ function SwapWalletSelector({
31512
31935
  display: "flex",
31513
31936
  alignItems: "center",
31514
31937
  justifyContent: "center",
31515
- overflow: "hidden",
31516
31938
  flexShrink: 0
31517
31939
  },
31518
- children: wallet.meta.logo ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31519
- "img",
31520
- {
31521
- src: wallet.meta.logo,
31522
- alt: wallet.meta.name,
31523
- style: {
31524
- width: "2rem",
31525
- height: "2rem",
31526
- objectFit: "contain"
31527
- }
31528
- }
31529
- ) : wallet.detail?.info?.icon ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31530
- "img",
31940
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31941
+ "svg",
31531
31942
  {
31532
- src: wallet.detail.info.icon,
31533
- alt: wallet.meta.name,
31534
31943
  style: {
31535
- width: "2rem",
31536
- height: "2rem",
31537
- objectFit: "contain"
31538
- }
31944
+ width: "1.5rem",
31945
+ height: "1.5rem",
31946
+ color: colors.blue[500]
31947
+ },
31948
+ viewBox: "0 0 24 24",
31949
+ fill: "currentColor",
31950
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("path", { d: "M6.09 10.56c3.26-3.2 8.56-3.2 11.82 0l.39.39a.4.4 0 010 .58l-1.34 1.31a.21.21 0 01-.3 0l-.54-.53c-2.28-2.23-5.97-2.23-8.24 0l-.58.56a.21.21 0 01-.3 0L5.66 11.6a.4.4 0 010-.58l.43-.46zm14.6 2.72l1.2 1.17a.4.4 0 010 .58l-5.38 5.27a.43.43 0 01-.6 0l-3.82-3.74a.11.11 0 00-.15 0l-3.82 3.74a.43.43 0 01-.6 0L2.15 15.03a.4.4 0 010-.58l1.2-1.17a.43.43 0 01.6 0l3.82 3.74c.04.04.1.04.15 0l3.82-3.74a.43.43 0 01.6 0l3.82 3.74c.04.04.1.04.15 0l3.82-3.74a.43.43 0 01.6 0z" })
31539
31951
  }
31540
- ) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { style: { fontSize: "1.5rem" }, children: wallet.meta.emoji || "\u{1F45B}" })
31952
+ )
31541
31953
  }
31542
31954
  ),
31543
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { style: { flex: 1 }, children: [
31955
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
31544
31956
  /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31545
31957
  "p",
31546
31958
  {
@@ -31548,10 +31960,10 @@ function SwapWalletSelector({
31548
31960
  fontWeight: fontWeight.semibold,
31549
31961
  color: colors.foreground
31550
31962
  },
31551
- children: wallet.meta.name
31963
+ children: "WalletConnect"
31552
31964
  }
31553
31965
  ),
31554
- isConnected && walletAddress && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
31966
+ wcConnected && walletAddress && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
31555
31967
  "p",
31556
31968
  {
31557
31969
  style: {
@@ -31566,7 +31978,7 @@ function SwapWalletSelector({
31566
31978
  }
31567
31979
  )
31568
31980
  ] }),
31569
- isConnecting ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31981
+ wcConnecting ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31570
31982
  "div",
31571
31983
  {
31572
31984
  style: {
@@ -31575,40 +31987,58 @@ function SwapWalletSelector({
31575
31987
  border: `2px solid ${colors.mutedForeground}`,
31576
31988
  borderTopColor: "transparent",
31577
31989
  borderRadius: "9999px",
31578
- animation: "tw-spin 1s linear infinite"
31990
+ animation: "tw-spin 1s linear infinite",
31991
+ flexShrink: 0
31579
31992
  }
31580
31993
  }
31994
+ ) : wcConnected ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31995
+ "button",
31996
+ {
31997
+ onClick: (e2) => {
31998
+ e2.stopPropagation();
31999
+ handleDisconnect();
32000
+ },
32001
+ style: {
32002
+ padding: `${spacing[1.5]} ${spacing[3]}`,
32003
+ borderRadius: "9999px",
32004
+ backgroundColor: "rgba(239,68,68,0.1)",
32005
+ color: "#ef4444",
32006
+ fontSize: fontSize.xs,
32007
+ fontWeight: fontWeight.medium,
32008
+ border: 0,
32009
+ cursor: "pointer",
32010
+ flexShrink: 0
32011
+ },
32012
+ children: "Disconnect"
32013
+ }
31581
32014
  ) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
31582
32015
  "button",
31583
32016
  {
31584
- onClick: () => handleClick(wallet),
31585
- disabled: walletStatus === "connecting",
31586
- style: mergeStyles(
31587
- {
31588
- padding: `${spacing[1.5]} ${spacing[3]}`,
31589
- borderRadius: "9999px",
31590
- backgroundColor: "rgba(59,130,246,0.1)",
31591
- color: colors.primary,
31592
- fontSize: fontSize.xs,
31593
- fontWeight: fontWeight.medium,
31594
- border: 0,
31595
- cursor: "pointer"
31596
- },
31597
- walletStatus === "connecting" && {
31598
- opacity: 0.5,
31599
- cursor: "not-allowed"
31600
- }
31601
- ),
32017
+ onClick: (e2) => {
32018
+ e2.stopPropagation();
32019
+ void handleWalletConnect();
32020
+ },
32021
+ disabled: wcConnecting,
32022
+ style: {
32023
+ padding: `${spacing[1.5]} ${spacing[3]}`,
32024
+ borderRadius: "9999px",
32025
+ backgroundColor: "rgba(59,130,246,0.1)",
32026
+ color: colors.primary,
32027
+ fontSize: fontSize.xs,
32028
+ fontWeight: fontWeight.medium,
32029
+ border: 0,
32030
+ cursor: "pointer",
32031
+ flexShrink: 0
32032
+ },
31602
32033
  children: "Connect"
31603
32034
  }
31604
32035
  )
31605
32036
  ]
31606
- },
31607
- wallet.meta.id
32037
+ }
31608
32038
  );
31609
- })
31610
- }
31611
- ) })
32039
+ })()
32040
+ ] })
32041
+ ] })
31612
32042
  ] });
31613
32043
  }
31614
32044
  var import_react45, import_jsx_runtime55;
@@ -31619,6 +32049,7 @@ var init_SwapWalletSelector = __esm({
31619
32049
  init_styles();
31620
32050
  init_utils();
31621
32051
  init_wallets();
32052
+ init_config2();
31622
32053
  init_Toast();
31623
32054
  import_jsx_runtime55 = require("react/jsx-runtime");
31624
32055
  }
@@ -31834,6 +32265,7 @@ function SwapMode({
31834
32265
  );
31835
32266
  const settingsRef = (0, import_react46.useRef)(null);
31836
32267
  const currencyDropdownRef = (0, import_react46.useRef)(null);
32268
+ const { emitEvent } = useTrustware();
31837
32269
  const { features } = useTrustwareConfig();
31838
32270
  const defaultDestRef = features.swapDefaultDestToken;
31839
32271
  const lockDestToken = features.swapLockDestToken && !!defaultDestRef;
@@ -31902,7 +32334,7 @@ function SwapMode({
31902
32334
  (c) => setFromChain(c),
31903
32335
  []
31904
32336
  );
31905
- const { yourWalletTokens } = useWalletTokenState({
32337
+ const { yourWalletTokens, reloadWalletTokens } = useWalletTokenState({
31906
32338
  walletAddress,
31907
32339
  selectedChain: fromChain,
31908
32340
  setSelectedChain: setFromChainStable,
@@ -31974,8 +32406,16 @@ function SwapMode({
31974
32406
  setAmountInputMode("usd");
31975
32407
  }
31976
32408
  setStage("home");
32409
+ emitEvent?.({
32410
+ type: "swap_route_changed",
32411
+ fromChain: String(chain.chainId),
32412
+ fromToken: token.address,
32413
+ toChain: String(toChain?.chainId ?? ""),
32414
+ toToken: toToken?.address ?? "",
32415
+ ...amount ? { amount } : {}
32416
+ });
31977
32417
  },
31978
- [route]
32418
+ [route, emitEvent, toToken, toChain, amount]
31979
32419
  );
31980
32420
  const handleSelectToToken = (0, import_react46.useCallback)(
31981
32421
  (token, chain) => {
@@ -31983,18 +32423,35 @@ function SwapMode({
31983
32423
  setToChain(chain);
31984
32424
  route.clear();
31985
32425
  setStage("home");
32426
+ emitEvent?.({
32427
+ type: "swap_route_changed",
32428
+ fromChain: String(fromChain?.chainId ?? ""),
32429
+ fromToken: fromToken?.address ?? "",
32430
+ toChain: String(chain.chainId),
32431
+ toToken: token.address,
32432
+ ...amount ? { amount } : {}
32433
+ });
31986
32434
  },
31987
- [route]
32435
+ [route, emitEvent, fromToken, fromChain, amount]
31988
32436
  );
31989
32437
  const handleFlip = (0, import_react46.useCallback)(() => {
31990
32438
  if (lockDestToken) return;
32439
+ const newFrom = toToken ?? fromToken;
32440
+ const newFromChain = toChain ?? fromChain;
31991
32441
  setFromToken((prev) => toToken ?? prev);
31992
32442
  setFromChain((prev) => toChain ?? prev);
31993
32443
  setToToken(fromToken);
31994
32444
  setToChain(fromChain);
31995
32445
  setAmount("");
31996
32446
  route.clear();
31997
- }, [lockDestToken, fromToken, fromChain, toToken, toChain, route]);
32447
+ emitEvent?.({
32448
+ type: "swap_route_changed",
32449
+ fromChain: String(newFromChain?.chainId ?? ""),
32450
+ fromToken: newFrom?.address ?? "",
32451
+ toChain: String(fromChain?.chainId ?? ""),
32452
+ toToken: fromToken?.address ?? ""
32453
+ });
32454
+ }, [lockDestToken, fromToken, fromChain, toToken, toChain, route, emitEvent]);
31998
32455
  const fromChainType = normalizeChainType2(fromChain);
31999
32456
  const toChainType = normalizeChainType2(toChain);
32000
32457
  const needsDestAddress = !!fromChainType && !!toChainType && fromChainType !== toChainType;
@@ -32067,7 +32524,8 @@ function SwapMode({
32067
32524
  setCompletedAt(null);
32068
32525
  setCopiedHash(null);
32069
32526
  setStage("home");
32070
- }, [execution, route]);
32527
+ reloadWalletTokens();
32528
+ }, [execution, route, reloadWalletTokens]);
32071
32529
  const handleSwapBack = (0, import_react46.useCallback)(() => {
32072
32530
  const prevFrom = fromToken;
32073
32531
  const prevFromChain = fromChain;
@@ -32082,7 +32540,16 @@ function SwapMode({
32082
32540
  setCompletedAt(null);
32083
32541
  setCopiedHash(null);
32084
32542
  setStage("home");
32085
- }, [fromToken, fromChain, toToken, toChain, execution, route]);
32543
+ reloadWalletTokens();
32544
+ }, [
32545
+ fromToken,
32546
+ fromChain,
32547
+ toToken,
32548
+ toChain,
32549
+ execution,
32550
+ route,
32551
+ reloadWalletTokens
32552
+ ]);
32086
32553
  const handleCopyHash = (0, import_react46.useCallback)((hash) => {
32087
32554
  if (!navigator?.clipboard?.writeText) return;
32088
32555
  void navigator.clipboard.writeText(hash).then(() => {
@@ -34464,9 +34931,15 @@ function SwapMode({
34464
34931
  fromToken.address,
34465
34932
  fromChainType ?? ""
34466
34933
  ) || isZeroAddrLike(fromToken.address, fromChainType));
34467
- const effectivePct = isNative && p.value === 1 ? 0.995 : p.value;
34934
+ const isSolana = normalizeChainType2(fromChain) === "solana";
34935
+ const effectiveAmount = (() => {
34936
+ if (!isNative || p.value !== 1)
34937
+ return fromBalance * p.value;
34938
+ if (isSolana) return Math.max(0, fromBalance - 0.01);
34939
+ return fromBalance * 0.995;
34940
+ })();
34468
34941
  if (amountInputMode === "usd" && hasFromUsdPrice) {
34469
- const fiatVal = fromBalance * effectivePct * fromTokenPriceUSD * currencyRate;
34942
+ const fiatVal = effectiveAmount * fromTokenPriceUSD * currencyRate;
34470
34943
  const dp = fiatVal > 0 ? Math.min(
34471
34944
  8,
34472
34945
  Math.max(
@@ -34478,7 +34951,7 @@ function SwapMode({
34478
34951
  } else {
34479
34952
  setAmount(
34480
34953
  truncateDecimal(
34481
- fromBalance * effectivePct,
34954
+ effectiveAmount,
34482
34955
  Math.min(decimals, 6)
34483
34956
  )
34484
34957
  );
@@ -35737,6 +36210,7 @@ var init_SwapMode = __esm({
35737
36210
  init_tokenAmount();
35738
36211
  init_chainHelpers();
35739
36212
  init_hooks();
36213
+ init_provider();
35740
36214
  init_useSwapRoute();
35741
36215
  init_useSwapExecution();
35742
36216
  init_useForex();