@compass-labs/widgets 0.1.32 → 0.1.34

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.mjs CHANGED
@@ -3,7 +3,7 @@ import { useQueryClient, useQuery, QueryClient, QueryClientProvider } from '@tan
3
3
  import { CompassApiSDK } from '@compass-labs/api-sdk';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
  import { arbitrum, base, mainnet } from 'viem/chains';
6
- import { Wallet, Loader2, ArrowDownLeft, ArrowUpRight, Coins, X, ChevronDown, LogOut, AlertCircle, ArrowRight, ExternalLink, Plus, ChevronRight, Minus, Shield, CheckCircle, ArrowDownUp, AlertTriangle, Check, RotateCcw, Equal, ChevronUp, Inbox, Percent, Clock, Calendar, TrendingUp, TrendingDown } from 'lucide-react';
6
+ import { Wallet, Loader2, ArrowDownLeft, ArrowUpRight, X, ChevronDown, Check, Copy, LogOut, AlertCircle, ArrowRight, ExternalLink, ArrowDownUp, ArrowLeftRight, Plus, ChevronRight, Minus, Shield, CheckCircle, AlertTriangle, RotateCcw, Equal, ChevronUp, Inbox, Percent, Clock, Calendar, TrendingUp, TrendingDown } from 'lucide-react';
7
7
 
8
8
  // src/provider/CompassProvider.tsx
9
9
  var ApiContext = createContext(null);
@@ -990,9 +990,52 @@ function ChainSwitcher() {
990
990
  }
991
991
  );
992
992
  }
993
- function truncateAddress(address) {
993
+ function truncateAddr(address) {
994
994
  return `${address.slice(0, 6)}...${address.slice(-4)}`;
995
995
  }
996
+ function CopyableAddress({
997
+ address,
998
+ label,
999
+ truncate = true,
1000
+ textSize = "text-xs"
1001
+ }) {
1002
+ const [copied, setCopied] = useState(false);
1003
+ const handleCopy = useCallback(() => {
1004
+ navigator.clipboard.writeText(address);
1005
+ setCopied(true);
1006
+ setTimeout(() => setCopied(false), 1500);
1007
+ }, [address]);
1008
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", style: { gap: "2px" }, children: [
1009
+ label && /* @__PURE__ */ jsx(
1010
+ "span",
1011
+ {
1012
+ className: "text-xs",
1013
+ style: { color: "var(--compass-color-text-tertiary)", fontSize: "10px" },
1014
+ children: label
1015
+ }
1016
+ ),
1017
+ /* @__PURE__ */ jsxs(
1018
+ "button",
1019
+ {
1020
+ onClick: handleCopy,
1021
+ className: `inline-flex items-center font-mono ${textSize}`,
1022
+ style: {
1023
+ color: "var(--compass-color-text-secondary)",
1024
+ background: "none",
1025
+ border: "none",
1026
+ cursor: "pointer",
1027
+ padding: 0,
1028
+ gap: "4px"
1029
+ },
1030
+ title: copied ? "Copied!" : `Copy: ${address}`,
1031
+ children: [
1032
+ /* @__PURE__ */ jsx("span", { children: truncate ? truncateAddr(address) : address }),
1033
+ copied ? /* @__PURE__ */ jsx(Check, { size: 10, className: "flex-shrink-0", style: { color: "var(--compass-color-success)" } }) : /* @__PURE__ */ jsx(Copy, { size: 10, className: "flex-shrink-0", style: { color: "var(--compass-color-text-tertiary)" } })
1034
+ ]
1035
+ }
1036
+ )
1037
+ ] });
1038
+ }
996
1039
  function WalletStatus({
997
1040
  showFullAddress = false,
998
1041
  showLogout = true,
@@ -1069,11 +1112,11 @@ function WalletStatus({
1069
1112
  }
1070
1113
  ),
1071
1114
  /* @__PURE__ */ jsx(
1072
- "span",
1115
+ CopyableAddress,
1073
1116
  {
1074
- className: `font-mono whitespace-nowrap ${compact ? "text-xs" : "text-sm"}`,
1075
- style: { color: "var(--compass-color-text)" },
1076
- children: showFullAddress ? address : truncateAddress(address)
1117
+ address,
1118
+ truncate: !showFullAddress,
1119
+ textSize: compact ? "text-xs" : "text-sm"
1077
1120
  }
1078
1121
  ),
1079
1122
  showLogout && disconnectFn !== null && /* @__PURE__ */ jsx(
@@ -1109,68 +1152,75 @@ function ActionModal({ isOpen, onClose, title, children }) {
1109
1152
  };
1110
1153
  }, [isOpen, onClose]);
1111
1154
  if (!isOpen) return null;
1112
- return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
1113
- /* @__PURE__ */ jsx(
1114
- "div",
1115
- {
1116
- className: "absolute inset-0",
1117
- style: { backgroundColor: "var(--compass-color-overlay)" },
1118
- onClick: onClose
1119
- }
1120
- ),
1121
- /* @__PURE__ */ jsxs(
1122
- "div",
1123
- {
1124
- className: "relative w-full max-w-md mx-4 overflow-hidden",
1125
- style: {
1126
- backgroundColor: "var(--compass-color-surface)",
1127
- boxShadow: "var(--compass-shadow-lg)",
1128
- borderRadius: "var(--compass-border-radius-xl)",
1129
- fontFamily: "var(--compass-font-family)"
1130
- },
1131
- children: [
1132
- /* @__PURE__ */ jsxs(
1133
- "div",
1134
- {
1135
- className: "flex items-center justify-between border-b",
1136
- style: {
1137
- borderColor: "var(--compass-color-border)",
1138
- padding: "calc(var(--compass-spacing-card) * 0.75) var(--compass-spacing-card)"
1139
- },
1140
- children: [
1141
- /* @__PURE__ */ jsx(
1142
- "h2",
1143
- {
1144
- className: "font-semibold",
1145
- style: {
1146
- fontSize: "var(--compass-font-size-subheading)",
1147
- color: "var(--compass-color-text)"
1148
- },
1149
- children: title
1150
- }
1151
- ),
1152
- /* @__PURE__ */ jsx(
1153
- "button",
1154
- {
1155
- onClick: onClose,
1156
- className: "hover:opacity-70",
1157
- style: {
1158
- color: "var(--compass-color-text-secondary)",
1159
- borderRadius: "var(--compass-border-radius-md)",
1160
- padding: "calc(var(--compass-spacing-unit) * 0.25)",
1161
- transition: "var(--compass-transition-normal)"
1162
- },
1163
- children: /* @__PURE__ */ jsx(X, { size: 20 })
1164
- }
1165
- )
1166
- ]
1167
- }
1168
- ),
1169
- /* @__PURE__ */ jsx("div", { style: { padding: "var(--compass-spacing-card)" }, children })
1170
- ]
1171
- }
1172
- )
1173
- ] });
1155
+ return /* @__PURE__ */ jsxs(
1156
+ "div",
1157
+ {
1158
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
1159
+ style: { overflowY: "auto", scrollbarWidth: "none" },
1160
+ children: [
1161
+ /* @__PURE__ */ jsx(
1162
+ "div",
1163
+ {
1164
+ className: "absolute inset-0",
1165
+ style: { backgroundColor: "var(--compass-color-overlay)" },
1166
+ onClick: onClose
1167
+ }
1168
+ ),
1169
+ /* @__PURE__ */ jsxs(
1170
+ "div",
1171
+ {
1172
+ className: "relative w-full max-w-md",
1173
+ style: {
1174
+ backgroundColor: "var(--compass-color-surface)",
1175
+ boxShadow: "var(--compass-shadow-lg)",
1176
+ borderRadius: "var(--compass-border-radius-xl)",
1177
+ fontFamily: "var(--compass-font-family)"
1178
+ },
1179
+ children: [
1180
+ /* @__PURE__ */ jsxs(
1181
+ "div",
1182
+ {
1183
+ className: "flex items-center justify-between border-b",
1184
+ style: {
1185
+ borderColor: "var(--compass-color-border)",
1186
+ padding: "calc(var(--compass-spacing-card) * 0.75) var(--compass-spacing-card)"
1187
+ },
1188
+ children: [
1189
+ /* @__PURE__ */ jsx(
1190
+ "h2",
1191
+ {
1192
+ className: "font-semibold",
1193
+ style: {
1194
+ fontSize: "var(--compass-font-size-subheading)",
1195
+ color: "var(--compass-color-text)"
1196
+ },
1197
+ children: title
1198
+ }
1199
+ ),
1200
+ /* @__PURE__ */ jsx(
1201
+ "button",
1202
+ {
1203
+ onClick: onClose,
1204
+ className: "hover:opacity-70",
1205
+ style: {
1206
+ color: "var(--compass-color-text-secondary)",
1207
+ borderRadius: "var(--compass-border-radius-md)",
1208
+ padding: "calc(var(--compass-spacing-unit) * 0.25)",
1209
+ transition: "var(--compass-transition-normal)"
1210
+ },
1211
+ children: /* @__PURE__ */ jsx(X, { size: 20 })
1212
+ }
1213
+ )
1214
+ ]
1215
+ }
1216
+ ),
1217
+ /* @__PURE__ */ jsx("div", { style: { padding: "var(--compass-spacing-card)" }, children })
1218
+ ]
1219
+ }
1220
+ )
1221
+ ]
1222
+ }
1223
+ );
1174
1224
  }
1175
1225
  function PnLSummary({ pnl, tokenSymbol, tokenPrice }) {
1176
1226
  const [isExpanded, setIsExpanded] = useState(false);
@@ -2231,226 +2281,98 @@ function AccountBalancesModal({
2231
2281
  balances,
2232
2282
  totalUsdValue,
2233
2283
  isLoading = false,
2234
- earnAccountAddress
2284
+ earnAccountAddress,
2285
+ walletAddress
2235
2286
  }) {
2236
- useEffect(() => {
2237
- const handleEscape = (e) => {
2238
- if (e.key === "Escape") onClose();
2239
- };
2240
- if (isOpen) {
2241
- document.addEventListener("keydown", handleEscape);
2242
- document.body.style.overflow = "hidden";
2243
- }
2244
- return () => {
2245
- document.removeEventListener("keydown", handleEscape);
2246
- document.body.style.overflow = "";
2247
- };
2248
- }, [isOpen, onClose]);
2249
- if (!isOpen) return null;
2250
- return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
2251
- /* @__PURE__ */ jsx(
2287
+ return /* @__PURE__ */ jsx(ActionModal, { isOpen, onClose, title: "Balance Breakdown", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
2288
+ (walletAddress || earnAccountAddress) && /* @__PURE__ */ jsxs(
2252
2289
  "div",
2253
2290
  {
2254
- className: "absolute inset-0",
2255
- style: { backgroundColor: "var(--compass-color-overlay)" },
2256
- onClick: onClose
2291
+ className: "flex flex-col gap-2 pb-3",
2292
+ style: { borderBottom: "1px solid var(--compass-color-border)" },
2293
+ children: [
2294
+ walletAddress && /* @__PURE__ */ jsx(CopyableAddress, { address: walletAddress, label: "Wallet" }),
2295
+ earnAccountAddress && /* @__PURE__ */ jsx(CopyableAddress, { address: earnAccountAddress, label: "Product Account" })
2296
+ ]
2257
2297
  }
2258
2298
  ),
2259
- /* @__PURE__ */ jsxs(
2299
+ isLoading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ jsx(
2300
+ Loader2,
2301
+ {
2302
+ size: 24,
2303
+ className: "animate-spin",
2304
+ style: { color: "var(--compass-color-primary)" }
2305
+ }
2306
+ ) }) : balances.length === 0 ? /* @__PURE__ */ jsx(
2260
2307
  "div",
2261
2308
  {
2262
- className: "relative w-full max-w-md mx-4 overflow-hidden",
2263
- style: {
2264
- backgroundColor: "var(--compass-color-surface)",
2265
- boxShadow: "var(--compass-shadow-lg)",
2266
- borderRadius: "var(--compass-border-radius-xl)",
2267
- fontFamily: "var(--compass-font-family)"
2268
- },
2269
- children: [
2270
- /* @__PURE__ */ jsxs(
2271
- "div",
2272
- {
2273
- className: "flex items-center justify-between border-b",
2274
- style: {
2275
- borderColor: "var(--compass-color-border)",
2276
- padding: "calc(var(--compass-spacing-unit) * 0.75) var(--compass-spacing-card)"
2277
- },
2278
- children: [
2279
- /* @__PURE__ */ jsxs(
2280
- "h2",
2281
- {
2282
- className: "font-semibold flex items-center gap-2",
2283
- style: {
2284
- fontSize: "var(--compass-font-size-subheading)",
2285
- color: "var(--compass-color-text)"
2286
- },
2287
- children: [
2288
- /* @__PURE__ */ jsx(Coins, { size: 20 }),
2289
- "Account Balances"
2290
- ]
2291
- }
2292
- ),
2293
- /* @__PURE__ */ jsx(
2294
- "button",
2295
- {
2296
- onClick: onClose,
2297
- className: "hover:opacity-70",
2298
- style: {
2299
- color: "var(--compass-color-text-secondary)",
2300
- borderRadius: "var(--compass-border-radius-md)",
2301
- padding: "calc(var(--compass-spacing-unit) * 0.25)",
2302
- transition: "var(--compass-transition-normal)"
2303
- },
2304
- children: /* @__PURE__ */ jsx(X, { size: 20 })
2305
- }
2306
- )
2307
- ]
2308
- }
2309
- ),
2310
- /* @__PURE__ */ jsxs("div", { style: { padding: "var(--compass-spacing-card)" }, children: [
2311
- isLoading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", style: { padding: "calc(var(--compass-spacing-unit) * 2) 0" }, children: /* @__PURE__ */ jsx(
2312
- Loader2,
2313
- {
2314
- size: 24,
2315
- className: "animate-spin",
2316
- style: { color: "var(--compass-color-primary)" }
2317
- }
2318
- ) }) : balances.length === 0 ? /* @__PURE__ */ jsx(
2319
- "div",
2320
- {
2321
- className: "text-center",
2322
- style: { color: "var(--compass-color-text-secondary)", padding: "calc(var(--compass-spacing-unit) * 2) 0" },
2323
- children: "No token balances found"
2324
- }
2325
- ) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
2326
- /* @__PURE__ */ jsxs(
2327
- "div",
2328
- {
2329
- className: "flex items-center justify-between border",
2330
- style: {
2331
- borderColor: "var(--compass-color-border)",
2332
- backgroundColor: "var(--compass-color-surface)",
2333
- borderRadius: "var(--compass-border-radius-lg)",
2334
- padding: "calc(var(--compass-spacing-unit) * 1)",
2335
- marginBottom: "calc(var(--compass-spacing-unit) * 0.5)"
2336
- },
2337
- children: [
2338
- /* @__PURE__ */ jsx(
2339
- "span",
2340
- {
2341
- className: "font-medium",
2342
- style: { color: "var(--compass-color-text-secondary)" },
2343
- children: "Total Balance"
2344
- }
2345
- ),
2346
- /* @__PURE__ */ jsx(
2347
- "span",
2348
- {
2349
- className: "font-bold text-xl",
2350
- style: { color: "var(--compass-color-text)" },
2351
- children: formatUSD(totalUsdValue)
2352
- }
2353
- )
2354
- ]
2355
- }
2356
- ),
2357
- /* @__PURE__ */ jsx(
2358
- "div",
2359
- {
2360
- className: "text-xs font-medium uppercase tracking-wide",
2361
- style: {
2362
- color: "var(--compass-color-text-tertiary)",
2363
- padding: "calc(var(--compass-spacing-unit) * 0.5) 0"
2364
- },
2365
- children: "Token Breakdown"
2366
- }
2367
- ),
2368
- balances.map((token) => /* @__PURE__ */ jsxs(
2369
- "div",
2370
- {
2371
- className: "flex items-center justify-between",
2372
- style: {
2373
- backgroundColor: "var(--compass-color-background)",
2374
- borderRadius: "var(--compass-border-radius-lg)",
2375
- padding: "calc(var(--compass-spacing-unit) * 0.75)"
2376
- },
2377
- children: [
2378
- /* @__PURE__ */ jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.75)" }, children: [
2379
- /* @__PURE__ */ jsx(
2380
- "div",
2381
- {
2382
- className: "w-8 h-8 flex items-center justify-center text-xs font-bold",
2383
- style: {
2384
- backgroundColor: "var(--compass-color-primary-muted)",
2385
- color: "var(--compass-color-primary)",
2386
- borderRadius: "var(--compass-border-radius-full)"
2387
- },
2388
- children: token.symbol.slice(0, 2)
2389
- }
2390
- ),
2391
- /* @__PURE__ */ jsxs("div", { children: [
2392
- /* @__PURE__ */ jsx(
2393
- "div",
2394
- {
2395
- className: "font-medium",
2396
- style: { color: "var(--compass-color-text)" },
2397
- children: token.symbol
2398
- }
2399
- ),
2400
- /* @__PURE__ */ jsx(
2401
- "div",
2402
- {
2403
- className: "text-sm font-mono",
2404
- style: { color: "var(--compass-color-text-secondary)" },
2405
- children: formatAmount(token.balance)
2406
- }
2407
- )
2408
- ] })
2409
- ] }),
2410
- /* @__PURE__ */ jsx(
2411
- "div",
2412
- {
2413
- className: "font-medium",
2414
- style: { color: "var(--compass-color-text)" },
2415
- children: formatUSD(token.usdValue)
2416
- }
2417
- )
2418
- ]
2419
- },
2420
- token.symbol
2421
- ))
2422
- ] }),
2423
- earnAccountAddress && /* @__PURE__ */ jsx(
2309
+ className: "text-center py-4",
2310
+ style: { color: "var(--compass-color-text-tertiary)" },
2311
+ children: "No tokens in account"
2312
+ }
2313
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
2314
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
2315
+ /* @__PURE__ */ jsx(
2316
+ "span",
2317
+ {
2318
+ className: "text-xs font-medium uppercase tracking-wide",
2319
+ style: { color: "var(--compass-color-text-tertiary)" },
2320
+ children: "Available in Account"
2321
+ }
2322
+ ),
2323
+ /* @__PURE__ */ jsx(
2324
+ "div",
2325
+ {
2326
+ className: "flex flex-col gap-2",
2327
+ style: {
2328
+ maxHeight: "50vh",
2329
+ overflowY: "auto",
2330
+ scrollbarWidth: "none"
2331
+ },
2332
+ children: balances.map((token) => /* @__PURE__ */ jsxs(
2424
2333
  "div",
2425
2334
  {
2426
- className: "border-t text-center",
2335
+ className: "flex items-center justify-between p-3 rounded-lg",
2427
2336
  style: {
2428
- borderColor: "var(--compass-color-border)",
2429
- marginTop: "var(--compass-spacing-card)",
2430
- paddingTop: "var(--compass-spacing-card)"
2337
+ backgroundColor: "var(--compass-color-surface)",
2338
+ border: "1px solid var(--compass-color-border)",
2339
+ flexShrink: 0
2431
2340
  },
2432
- children: /* @__PURE__ */ jsxs(
2433
- "span",
2434
- {
2435
- className: "text-xs",
2436
- style: { color: "var(--compass-color-text-tertiary)" },
2437
- children: [
2438
- "Earn Account: ",
2439
- earnAccountAddress.slice(0, 6),
2440
- "...",
2441
- earnAccountAddress.slice(-4)
2442
- ]
2443
- }
2444
- )
2341
+ children: [
2342
+ /* @__PURE__ */ jsx("span", { className: "font-medium", style: { color: "var(--compass-color-text)" }, children: token.symbol }),
2343
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end", children: [
2344
+ /* @__PURE__ */ jsx("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-text)" }, children: formatAmount(token.balance) }),
2345
+ /* @__PURE__ */ jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: formatUSD(token.usdValue) })
2346
+ ] })
2347
+ ]
2348
+ },
2349
+ token.symbol
2350
+ ))
2351
+ }
2352
+ )
2353
+ ] }),
2354
+ /* @__PURE__ */ jsxs(
2355
+ "div",
2356
+ {
2357
+ className: "flex items-center justify-between pt-3 mt-2",
2358
+ style: { borderTop: "2px solid var(--compass-color-border)" },
2359
+ children: [
2360
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", style: { color: "var(--compass-color-text)" }, children: "Total" }),
2361
+ /* @__PURE__ */ jsx(
2362
+ "span",
2363
+ {
2364
+ className: "font-bold text-xl",
2365
+ style: { color: "var(--compass-color-text)" },
2366
+ children: formatUSD(totalUsdValue)
2445
2367
  }
2446
2368
  )
2447
- ] })
2448
- ]
2449
- }
2450
- )
2451
- ] });
2369
+ ]
2370
+ }
2371
+ )
2372
+ ] })
2373
+ ] }) });
2452
2374
  }
2453
- var TRANSFER_TOKENS = ["USDC"];
2375
+ var TRANSFER_TOKENS = ["USDC", "SBC"];
2454
2376
  var EarnAccountBalance = forwardRef(function EarnAccountBalance2({
2455
2377
  compact = false,
2456
2378
  hideVisual = false,
@@ -2768,7 +2690,8 @@ var EarnAccountBalance = forwardRef(function EarnAccountBalance2({
2768
2690
  balances: tokenBalances,
2769
2691
  totalUsdValue: totalUsdValue.toString(),
2770
2692
  isLoading: balancesLoading,
2771
- earnAccountAddress: earnAccountAddress ?? void 0
2693
+ earnAccountAddress: earnAccountAddress ?? void 0,
2694
+ walletAddress: address ?? void 0
2772
2695
  }
2773
2696
  ),
2774
2697
  /* @__PURE__ */ jsx(
@@ -2950,7 +2873,459 @@ var EarnAccountBalance = forwardRef(function EarnAccountBalance2({
2950
2873
  }
2951
2874
  )
2952
2875
  ] });
2953
- });
2876
+ });
2877
+ function useSwapQuote({ fromToken, toToken, amount, enabled = true }) {
2878
+ const { chainId } = useChain();
2879
+ const { address } = useEmbeddableWallet();
2880
+ const query = useQuery({
2881
+ queryKey: ["swapQuote", chainId, fromToken, toToken, amount, address],
2882
+ queryFn: async () => {
2883
+ if (!fromToken || !toToken || !amount || parseFloat(amount) <= 0 || !address) {
2884
+ return null;
2885
+ }
2886
+ const params = new URLSearchParams({
2887
+ owner: address,
2888
+ chain: chainId,
2889
+ tokenIn: fromToken,
2890
+ tokenOut: toToken,
2891
+ amountIn: amount
2892
+ });
2893
+ const response = await fetch(`/api/compass/swap/quote?${params}`);
2894
+ if (!response.ok) {
2895
+ const errorData = await response.json();
2896
+ const errorMessage = errorData.message || errorData.error || "Failed to get swap quote";
2897
+ throw new Error(errorMessage);
2898
+ }
2899
+ const data = await response.json();
2900
+ const outputAmount = data.estimatedAmountOut || "0";
2901
+ const inputAmountNum = parseFloat(amount);
2902
+ const outputAmountNum = parseFloat(outputAmount);
2903
+ return {
2904
+ inputAmount: amount,
2905
+ outputAmount,
2906
+ rate: inputAmountNum > 0 ? (outputAmountNum / inputAmountNum).toString() : "0"
2907
+ };
2908
+ },
2909
+ enabled: enabled && !!address && !!fromToken && !!toToken && !!amount && parseFloat(amount) > 0,
2910
+ staleTime: 10 * 1e3,
2911
+ refetchInterval: 15 * 1e3,
2912
+ retry: 1
2913
+ });
2914
+ return {
2915
+ quote: query.data,
2916
+ isLoading: query.isLoading,
2917
+ isError: query.isError,
2918
+ error: query.error,
2919
+ refetch: query.refetch
2920
+ };
2921
+ }
2922
+ var COMMON_TOKENS = [
2923
+ "USDC",
2924
+ "USDT",
2925
+ "DAI",
2926
+ "USDS",
2927
+ "USDE",
2928
+ "sUSDE",
2929
+ "sDAI",
2930
+ "FRAX",
2931
+ "LUSD",
2932
+ "GUSD",
2933
+ "PYUSD",
2934
+ "crvUSD",
2935
+ "GHO",
2936
+ "EURC",
2937
+ "EURS",
2938
+ "EURA",
2939
+ "WETH",
2940
+ "WBTC",
2941
+ "wstETH",
2942
+ "cbETH",
2943
+ "rETH"
2944
+ ];
2945
+ function SwapForm({
2946
+ availableFromTokens,
2947
+ availableToTokens,
2948
+ balances,
2949
+ defaultFromToken,
2950
+ defaultToToken,
2951
+ onSwapSuccess,
2952
+ onSwapError
2953
+ }) {
2954
+ const toTokens = Array.from(/* @__PURE__ */ new Set([
2955
+ ...availableFromTokens,
2956
+ ...COMMON_TOKENS,
2957
+ ...availableToTokens || []
2958
+ ]));
2959
+ const [fromToken, setFromToken] = useState(defaultFromToken || availableFromTokens[0] || "USDC");
2960
+ const [toToken, setToToken] = useState(defaultToToken || toTokens.find((t) => t !== (defaultFromToken || availableFromTokens[0])) || "USDC");
2961
+ const [fromAmount, setFromAmount] = useState("");
2962
+ const [isSwapping, setIsSwapping] = useState(false);
2963
+ const [swapStatus, setSwapStatus] = useState("");
2964
+ const [isFromOpen, setIsFromOpen] = useState(false);
2965
+ const [isToOpen, setIsToOpen] = useState(false);
2966
+ const { address, isConnected, signTypedData } = useEmbeddableWallet();
2967
+ const { chainId } = useChain();
2968
+ const { quote, isLoading: isQuoteLoading, error: quoteError } = useSwapQuote({
2969
+ fromToken,
2970
+ toToken,
2971
+ amount: fromAmount,
2972
+ enabled: !!fromAmount && parseFloat(fromAmount) > 0
2973
+ });
2974
+ const handleReverse = useCallback(() => {
2975
+ const oldFrom = fromToken;
2976
+ const oldTo = toToken;
2977
+ if (availableFromTokens.includes(oldTo)) {
2978
+ setFromToken(oldTo);
2979
+ setToToken(oldFrom);
2980
+ setFromAmount("");
2981
+ }
2982
+ }, [fromToken, toToken, availableFromTokens]);
2983
+ const handleSwap = useCallback(async () => {
2984
+ if (!address || !fromAmount || !quote || !signTypedData) return;
2985
+ setIsSwapping(true);
2986
+ setSwapStatus("Preparing swap...");
2987
+ try {
2988
+ const prepareResponse = await fetch("/api/compass/swap/prepare", {
2989
+ method: "POST",
2990
+ headers: { "Content-Type": "application/json" },
2991
+ body: JSON.stringify({
2992
+ owner: address,
2993
+ chain: chainId,
2994
+ tokenIn: fromToken,
2995
+ tokenOut: toToken,
2996
+ amountIn: fromAmount
2997
+ })
2998
+ });
2999
+ if (!prepareResponse.ok) {
3000
+ const error = await prepareResponse.json();
3001
+ throw new Error(error.error || "Failed to prepare swap");
3002
+ }
3003
+ const prepareData = await prepareResponse.json();
3004
+ const { eip712, normalizedTypes } = prepareData;
3005
+ if (!eip712) {
3006
+ throw new Error("No EIP-712 data returned from prepare");
3007
+ }
3008
+ setSwapStatus("Please sign the transaction...");
3009
+ const signature = await signTypedData({
3010
+ domain: eip712.domain,
3011
+ types: normalizedTypes || eip712.types,
3012
+ primaryType: "SafeTx",
3013
+ message: eip712.message
3014
+ });
3015
+ setSwapStatus("Executing swap...");
3016
+ const executeResponse = await fetch("/api/compass/swap/execute", {
3017
+ method: "POST",
3018
+ headers: { "Content-Type": "application/json" },
3019
+ body: JSON.stringify({
3020
+ owner: address,
3021
+ chain: chainId,
3022
+ eip712,
3023
+ signature
3024
+ })
3025
+ });
3026
+ if (!executeResponse.ok) {
3027
+ const error = await executeResponse.json();
3028
+ throw new Error(error.error || "Failed to execute swap");
3029
+ }
3030
+ const executeData = await executeResponse.json();
3031
+ const txHash = executeData.txHash;
3032
+ setSwapStatus("Swap successful!");
3033
+ onSwapSuccess?.(fromToken, toToken, fromAmount, quote.outputAmount, txHash);
3034
+ setFromAmount("");
3035
+ setTimeout(() => setSwapStatus(""), 3e3);
3036
+ } catch (error) {
3037
+ setSwapStatus("");
3038
+ onSwapError?.(error);
3039
+ } finally {
3040
+ setIsSwapping(false);
3041
+ }
3042
+ }, [address, fromAmount, quote, chainId, fromToken, toToken, signTypedData, onSwapSuccess, onSwapError]);
3043
+ const canReverse = availableFromTokens.includes(toToken);
3044
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", style: { gap: "calc(var(--compass-spacing-unit) * 0.75)" }, children: [
3045
+ /* @__PURE__ */ jsxs(
3046
+ "div",
3047
+ {
3048
+ style: {
3049
+ backgroundColor: "var(--compass-color-surface)",
3050
+ border: "1px solid var(--compass-color-border)",
3051
+ borderRadius: "var(--compass-border-radius-xl)",
3052
+ padding: "calc(var(--compass-spacing-unit) * 0.75)"
3053
+ },
3054
+ children: [
3055
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", style: { marginBottom: "calc(var(--compass-spacing-unit) * 0.25)" }, children: [
3056
+ /* @__PURE__ */ jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: "From" }),
3057
+ balances?.[fromToken] && /* @__PURE__ */ jsxs("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: [
3058
+ "Balance: ",
3059
+ parseFloat(balances[fromToken]).toLocaleString(void 0, { maximumFractionDigits: 6 })
3060
+ ] })
3061
+ ] }),
3062
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
3063
+ /* @__PURE__ */ jsx(
3064
+ "input",
3065
+ {
3066
+ type: "number",
3067
+ value: fromAmount,
3068
+ onChange: (e) => setFromAmount(e.target.value),
3069
+ placeholder: "0.00",
3070
+ disabled: isSwapping,
3071
+ className: "flex-1 bg-transparent outline-none font-medium min-w-0",
3072
+ style: { color: "var(--compass-color-text)", fontSize: "1.25rem" }
3073
+ }
3074
+ ),
3075
+ /* @__PURE__ */ jsxs("div", { className: "relative", style: { flexShrink: 0 }, children: [
3076
+ /* @__PURE__ */ jsxs(
3077
+ "button",
3078
+ {
3079
+ onClick: () => {
3080
+ setIsFromOpen(!isFromOpen);
3081
+ setIsToOpen(false);
3082
+ },
3083
+ disabled: isSwapping,
3084
+ className: "flex items-center font-medium",
3085
+ style: {
3086
+ backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-background))",
3087
+ border: "1px solid var(--compass-color-border)",
3088
+ color: "var(--compass-color-text)",
3089
+ borderRadius: "var(--compass-border-radius-md)",
3090
+ padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
3091
+ gap: "calc(var(--compass-spacing-unit) * 0.25)",
3092
+ fontSize: "0.875rem"
3093
+ },
3094
+ children: [
3095
+ fromToken,
3096
+ /* @__PURE__ */ jsx(ChevronDown, { size: 14, style: { color: "var(--compass-color-text-tertiary)" } })
3097
+ ]
3098
+ }
3099
+ ),
3100
+ isFromOpen && /* @__PURE__ */ jsx(
3101
+ "div",
3102
+ {
3103
+ className: "absolute right-0 mt-1 z-10",
3104
+ style: {
3105
+ backgroundColor: "var(--compass-color-surface)",
3106
+ border: "1px solid var(--compass-color-border)",
3107
+ borderRadius: "var(--compass-border-radius-lg)",
3108
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
3109
+ minWidth: "120px",
3110
+ maxHeight: "200px",
3111
+ overflowY: "auto",
3112
+ scrollbarWidth: "none"
3113
+ },
3114
+ children: availableFromTokens.filter((t) => t !== toToken).map((token) => /* @__PURE__ */ jsx(
3115
+ "button",
3116
+ {
3117
+ onClick: () => {
3118
+ setFromToken(token);
3119
+ setIsFromOpen(false);
3120
+ },
3121
+ className: "w-full text-left font-medium transition-colors",
3122
+ style: {
3123
+ padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
3124
+ color: token === fromToken ? "var(--compass-color-primary)" : "var(--compass-color-text)",
3125
+ backgroundColor: token === fromToken ? "var(--compass-color-primary-muted, rgba(99, 102, 241, 0.1))" : "transparent",
3126
+ fontSize: "0.875rem"
3127
+ },
3128
+ children: token
3129
+ },
3130
+ token
3131
+ ))
3132
+ }
3133
+ )
3134
+ ] })
3135
+ ] })
3136
+ ]
3137
+ }
3138
+ ),
3139
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center relative z-10", style: { margin: "calc(var(--compass-spacing-unit) * -0.25) 0" }, children: /* @__PURE__ */ jsx(
3140
+ "button",
3141
+ {
3142
+ onClick: handleReverse,
3143
+ disabled: !canReverse || isSwapping,
3144
+ className: "border disabled:opacity-30",
3145
+ style: {
3146
+ backgroundColor: "var(--compass-color-surface)",
3147
+ borderColor: "var(--compass-color-border)",
3148
+ borderRadius: "var(--compass-border-radius-full)",
3149
+ padding: "calc(var(--compass-spacing-unit) * 0.5)",
3150
+ transition: "var(--compass-transition-normal)"
3151
+ },
3152
+ children: /* @__PURE__ */ jsx(ArrowDownUp, { size: 16, style: { color: "var(--compass-color-text-secondary)" } })
3153
+ }
3154
+ ) }),
3155
+ /* @__PURE__ */ jsxs(
3156
+ "div",
3157
+ {
3158
+ style: {
3159
+ backgroundColor: "var(--compass-color-surface)",
3160
+ border: "1px solid var(--compass-color-border)",
3161
+ borderRadius: "var(--compass-border-radius-xl)",
3162
+ padding: "calc(var(--compass-spacing-unit) * 0.75)"
3163
+ },
3164
+ children: [
3165
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between", style: { marginBottom: "calc(var(--compass-spacing-unit) * 0.25)" }, children: /* @__PURE__ */ jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: "To" }) }),
3166
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
3167
+ /* @__PURE__ */ jsx(
3168
+ "div",
3169
+ {
3170
+ className: "flex-1 font-medium min-w-0",
3171
+ style: {
3172
+ color: isQuoteLoading ? "var(--compass-color-text-tertiary)" : "var(--compass-color-text)",
3173
+ fontSize: "1.25rem"
3174
+ },
3175
+ children: isQuoteLoading ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
3176
+ /* @__PURE__ */ jsx(Loader2, { size: 16, className: "animate-spin" }),
3177
+ "Loading..."
3178
+ ] }) : quote?.outputAmount ? parseFloat(quote.outputAmount).toFixed(8) : "0.00"
3179
+ }
3180
+ ),
3181
+ /* @__PURE__ */ jsxs("div", { className: "relative", style: { flexShrink: 0 }, children: [
3182
+ /* @__PURE__ */ jsxs(
3183
+ "button",
3184
+ {
3185
+ onClick: () => {
3186
+ setIsToOpen(!isToOpen);
3187
+ setIsFromOpen(false);
3188
+ },
3189
+ disabled: isSwapping,
3190
+ className: "flex items-center font-medium",
3191
+ style: {
3192
+ backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-background))",
3193
+ border: "1px solid var(--compass-color-border)",
3194
+ color: "var(--compass-color-text)",
3195
+ borderRadius: "var(--compass-border-radius-md)",
3196
+ padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
3197
+ gap: "calc(var(--compass-spacing-unit) * 0.25)",
3198
+ fontSize: "0.875rem"
3199
+ },
3200
+ children: [
3201
+ toToken,
3202
+ /* @__PURE__ */ jsx(ChevronDown, { size: 14, style: { color: "var(--compass-color-text-tertiary)" } })
3203
+ ]
3204
+ }
3205
+ ),
3206
+ isToOpen && /* @__PURE__ */ jsx(
3207
+ "div",
3208
+ {
3209
+ className: "absolute right-0 mt-1 z-10",
3210
+ style: {
3211
+ backgroundColor: "var(--compass-color-surface)",
3212
+ border: "1px solid var(--compass-color-border)",
3213
+ borderRadius: "var(--compass-border-radius-lg)",
3214
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
3215
+ minWidth: "140px",
3216
+ maxHeight: "280px",
3217
+ overflowY: "auto",
3218
+ scrollbarWidth: "none"
3219
+ },
3220
+ children: toTokens.filter((t) => t !== fromToken).map((token) => /* @__PURE__ */ jsx(
3221
+ "button",
3222
+ {
3223
+ onClick: () => {
3224
+ setToToken(token);
3225
+ setIsToOpen(false);
3226
+ },
3227
+ className: "w-full text-left font-medium transition-colors",
3228
+ style: {
3229
+ padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
3230
+ color: token === toToken ? "var(--compass-color-primary)" : "var(--compass-color-text)",
3231
+ backgroundColor: token === toToken ? "var(--compass-color-primary-muted, rgba(99, 102, 241, 0.1))" : "transparent",
3232
+ fontSize: "0.875rem"
3233
+ },
3234
+ children: token
3235
+ },
3236
+ token
3237
+ ))
3238
+ }
3239
+ )
3240
+ ] })
3241
+ ] })
3242
+ ]
3243
+ }
3244
+ ),
3245
+ quote && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", style: { color: "var(--compass-color-text-secondary)" }, children: [
3246
+ /* @__PURE__ */ jsx("span", { children: "Rate" }),
3247
+ /* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
3248
+ "1 ",
3249
+ fromToken,
3250
+ " = ",
3251
+ parseFloat(quote.rate).toFixed(6),
3252
+ " ",
3253
+ toToken
3254
+ ] })
3255
+ ] }),
3256
+ quoteError && /* @__PURE__ */ jsxs(
3257
+ "div",
3258
+ {
3259
+ className: "flex items-center text-sm",
3260
+ style: {
3261
+ backgroundColor: "var(--compass-color-error-muted)",
3262
+ color: "var(--compass-color-error)",
3263
+ borderRadius: "var(--compass-border-radius-lg)",
3264
+ padding: "calc(var(--compass-spacing-unit) * 0.75)",
3265
+ gap: "calc(var(--compass-spacing-unit) * 0.5)"
3266
+ },
3267
+ children: [
3268
+ /* @__PURE__ */ jsx(AlertCircle, { size: 16 }),
3269
+ /* @__PURE__ */ jsx("span", { children: quoteError.message })
3270
+ ]
3271
+ }
3272
+ ),
3273
+ swapStatus && /* @__PURE__ */ jsxs(
3274
+ "div",
3275
+ {
3276
+ className: "flex items-center text-sm",
3277
+ style: {
3278
+ backgroundColor: swapStatus.includes("successful") ? "var(--compass-color-success-muted)" : "var(--compass-color-surface)",
3279
+ color: swapStatus.includes("successful") ? "var(--compass-color-success)" : "var(--compass-color-text-secondary)",
3280
+ borderRadius: "var(--compass-border-radius-lg)",
3281
+ padding: "calc(var(--compass-spacing-unit) * 0.75)",
3282
+ gap: "calc(var(--compass-spacing-unit) * 0.5)"
3283
+ },
3284
+ children: [
3285
+ !swapStatus.includes("successful") && /* @__PURE__ */ jsx(Loader2, { size: 14, className: "animate-spin" }),
3286
+ swapStatus
3287
+ ]
3288
+ }
3289
+ ),
3290
+ !isConnected ? /* @__PURE__ */ jsxs(
3291
+ "div",
3292
+ {
3293
+ className: "flex flex-col items-center",
3294
+ style: {
3295
+ backgroundColor: "var(--compass-color-surface)",
3296
+ border: "1px solid var(--compass-color-border)",
3297
+ borderRadius: "var(--compass-border-radius-lg)",
3298
+ padding: "calc(var(--compass-spacing-unit) * 1) var(--compass-spacing-card)",
3299
+ gap: "calc(var(--compass-spacing-unit) * 0.5)"
3300
+ },
3301
+ children: [
3302
+ /* @__PURE__ */ jsx(AlertCircle, { size: 20, style: { color: "var(--compass-color-text-tertiary)" } }),
3303
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-center", style: { color: "var(--compass-color-text-secondary)" }, children: "Connect your wallet to swap" })
3304
+ ]
3305
+ }
3306
+ ) : /* @__PURE__ */ jsxs(
3307
+ "button",
3308
+ {
3309
+ onClick: handleSwap,
3310
+ disabled: isSwapping || !quote || !fromAmount || parseFloat(fromAmount) <= 0,
3311
+ className: "w-full font-semibold flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed",
3312
+ style: {
3313
+ backgroundColor: "var(--compass-color-primary)",
3314
+ color: "var(--compass-color-primary-text, white)",
3315
+ borderRadius: "var(--compass-border-radius-lg)",
3316
+ padding: "calc(var(--compass-spacing-unit) * 0.75)",
3317
+ gap: "calc(var(--compass-spacing-unit) * 0.5)",
3318
+ fontSize: "0.875rem",
3319
+ transition: "var(--compass-transition-normal)"
3320
+ },
3321
+ children: [
3322
+ isSwapping && /* @__PURE__ */ jsx(Loader2, { size: 16, className: "animate-spin" }),
3323
+ isSwapping ? "Swapping..." : "Swap"
3324
+ ]
3325
+ }
3326
+ )
3327
+ ] });
3328
+ }
2954
3329
  var MARKET_TABS = [
2955
3330
  { value: "variable", label: "VARIABLE" },
2956
3331
  { value: "fixed", label: "FIXED" }
@@ -3783,7 +4158,6 @@ var EVM_CHAIN_IDS = {
3783
4158
  base: 8453,
3784
4159
  arbitrum: 42161
3785
4160
  };
3786
- var SUPPORTED_TOKENS = ["USDC", "USDT", "DAI", "WETH", "SBC", "AUSD"];
3787
4161
  function formatCurrency(amount) {
3788
4162
  if (!amount) return "$0.00";
3789
4163
  const num = typeof amount === "string" ? parseFloat(amount) : amount;
@@ -3835,6 +4209,7 @@ function EarnAccount({
3835
4209
  const [isBalancesModalOpen, setIsBalancesModalOpen] = useState(false);
3836
4210
  const [marketTab, setMarketTab] = useState(defaultMarketTab);
3837
4211
  const [selectedMarket, setSelectedMarket] = useState(null);
4212
+ const [isSwapModalOpen, setIsSwapModalOpen] = useState(false);
3838
4213
  const [isEarningsModalOpen, setIsEarningsModalOpen] = useState(false);
3839
4214
  useEffect(() => {
3840
4215
  setSelectedMarket(null);
@@ -3884,6 +4259,7 @@ function EarnAccount({
3884
4259
  enabled: !!address && isDeployed,
3885
4260
  staleTime: 30 * 1e3
3886
4261
  });
4262
+ const balanceTokens = Object.keys(balancesQuery.data?.balances || {});
3887
4263
  const selectedTokenBalance = balancesQuery.data?.balances?.[selectedToken]?.balance || "0";
3888
4264
  const earnAccountTotalUsd = Object.values(balancesQuery.data?.balances || {}).reduce((sum, b) => sum + parseFloat(b.usdValue || "0"), 0).toString();
3889
4265
  const positionQuery = useQuery({
@@ -4553,39 +4929,59 @@ function EarnAccount({
4553
4929
  ]
4554
4930
  }
4555
4931
  ),
4556
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
4557
- /* @__PURE__ */ jsx(
4932
+ /* @__PURE__ */ jsx(
4933
+ "button",
4934
+ {
4935
+ onClick: () => setIsBalancesModalOpen(true),
4936
+ className: "transition-opacity hover:opacity-80",
4937
+ children: /* @__PURE__ */ jsx(
4938
+ "span",
4939
+ {
4940
+ className: "font-bold",
4941
+ style: {
4942
+ color: "var(--compass-color-text)",
4943
+ fontSize: compact ? "2rem" : "2.5rem",
4944
+ lineHeight: "1"
4945
+ },
4946
+ children: formatCurrency(earnAccountTotal)
4947
+ }
4948
+ )
4949
+ }
4950
+ ),
4951
+ (balanceTokens.length > 0 || showTopUpButton) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col", style: { gap: "6px", marginTop: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
4952
+ balanceTokens.length > 0 && /* @__PURE__ */ jsxs(
4558
4953
  "button",
4559
4954
  {
4560
- onClick: () => setIsBalancesModalOpen(true),
4561
- className: "transition-opacity hover:opacity-80",
4562
- children: /* @__PURE__ */ jsx(
4563
- "span",
4564
- {
4565
- className: "font-bold",
4566
- style: {
4567
- color: "var(--compass-color-text)",
4568
- fontSize: compact ? "2rem" : "2.5rem",
4569
- lineHeight: "1"
4570
- },
4571
- children: formatCurrency(earnAccountTotal)
4572
- }
4573
- )
4955
+ onClick: () => setIsSwapModalOpen(true),
4956
+ className: "flex items-center justify-center font-medium transition-all hover:opacity-80 w-full",
4957
+ style: {
4958
+ backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-surface))",
4959
+ border: "1px solid var(--compass-color-border)",
4960
+ color: "var(--compass-color-text-secondary)",
4961
+ borderRadius: "var(--compass-border-radius-md)",
4962
+ padding: "8px 10px",
4963
+ gap: "6px",
4964
+ fontSize: "13px"
4965
+ },
4966
+ children: [
4967
+ /* @__PURE__ */ jsx(ArrowLeftRight, { size: 14 }),
4968
+ "Swap"
4969
+ ]
4574
4970
  }
4575
4971
  ),
4576
4972
  showTopUpButton && /* @__PURE__ */ jsxs(
4577
4973
  "button",
4578
4974
  {
4579
4975
  onClick: () => setIsFundModalOpen(true),
4580
- className: "flex items-center font-medium transition-all hover:opacity-80",
4976
+ className: "flex items-center justify-center font-medium transition-all hover:opacity-80 w-full",
4581
4977
  style: {
4582
4978
  backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-surface))",
4583
4979
  border: "1px solid var(--compass-color-border)",
4584
4980
  color: "var(--compass-color-text-secondary)",
4585
4981
  borderRadius: "var(--compass-border-radius-md)",
4586
- padding: "6px 10px",
4587
- gap: "4px",
4588
- fontSize: "12px"
4982
+ padding: "8px 10px",
4983
+ gap: "6px",
4984
+ fontSize: "13px"
4589
4985
  },
4590
4986
  children: [
4591
4987
  /* @__PURE__ */ jsx(Plus, { size: 14 }),
@@ -4789,7 +5185,7 @@ function EarnAccount({
4789
5185
  boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
4790
5186
  minWidth: "100px"
4791
5187
  },
4792
- children: SUPPORTED_TOKENS.map((token) => /* @__PURE__ */ jsx(
5188
+ children: balanceTokens.map((token) => /* @__PURE__ */ jsx(
4793
5189
  "button",
4794
5190
  {
4795
5191
  onClick: () => {
@@ -5101,391 +5497,123 @@ function EarnAccount({
5101
5497
  ] }) : /* @__PURE__ */ jsxs("span", { className: "flex items-center justify-center gap-2", children: [
5102
5498
  /* @__PURE__ */ jsx(ArrowDownLeft, { size: 20 }),
5103
5499
  needsFundSwap ? `Swap ${fundToken} & Transfer` : "Transfer to Savings"
5104
- ] })
5105
- }
5106
- ),
5107
- /* @__PURE__ */ jsx(
5108
- "p",
5109
- {
5110
- className: "text-xs text-center",
5111
- style: { color: "var(--compass-color-text-tertiary)" },
5112
- children: "Gas fees are sponsored"
5113
- }
5114
- )
5115
- ] })
5116
- }
5117
- ),
5118
- /* @__PURE__ */ jsx(
5119
- ActionModal,
5120
- {
5121
- isOpen: isBalancesModalOpen,
5122
- onClose: () => setIsBalancesModalOpen(false),
5123
- title: "Balance Breakdown",
5124
- children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: balancesQuery.data?.balances && Object.keys(balancesQuery.data.balances).length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
5125
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
5126
- /* @__PURE__ */ jsx(
5127
- "span",
5128
- {
5129
- className: "text-xs font-medium uppercase tracking-wide",
5130
- style: { color: "var(--compass-color-text-tertiary)" },
5131
- children: "Available in Account"
5132
- }
5133
- ),
5134
- Object.entries(balancesQuery.data.balances).map(([symbol, data]) => /* @__PURE__ */ jsxs(
5135
- "div",
5136
- {
5137
- className: "flex items-center justify-between p-3 rounded-lg",
5138
- style: {
5139
- backgroundColor: "var(--compass-color-surface)",
5140
- border: "1px solid var(--compass-color-border)"
5141
- },
5142
- children: [
5143
- /* @__PURE__ */ jsx("span", { className: "font-medium", style: { color: "var(--compass-color-text)" }, children: symbol }),
5144
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end", children: [
5145
- /* @__PURE__ */ jsx("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-text)" }, children: formatAmount2(data.balance) }),
5146
- /* @__PURE__ */ jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: formatCurrency(data.usdValue) })
5147
- ] })
5148
- ]
5149
- },
5150
- symbol
5151
- ))
5152
- ] }),
5153
- /* @__PURE__ */ jsxs(
5154
- "div",
5155
- {
5156
- className: "flex items-center justify-between pt-3 mt-2",
5157
- style: { borderTop: "2px solid var(--compass-color-border)" },
5158
- children: [
5159
- /* @__PURE__ */ jsx("span", { className: "font-semibold", style: { color: "var(--compass-color-text)" }, children: "Total" }),
5160
- /* @__PURE__ */ jsx(
5161
- "span",
5162
- {
5163
- className: "font-bold text-xl",
5164
- style: { color: "var(--compass-color-text)" },
5165
- children: formatCurrency(earnAccountTotalUsd)
5166
- }
5167
- )
5168
- ]
5169
- }
5170
- )
5171
- ] }) : /* @__PURE__ */ jsx(
5172
- "div",
5173
- {
5174
- className: "text-center py-4",
5175
- style: { color: "var(--compass-color-text-tertiary)" },
5176
- children: "No tokens in account"
5177
- }
5178
- ) })
5179
- }
5180
- ),
5181
- /* @__PURE__ */ jsx(
5182
- EarningsModal,
5183
- {
5184
- isOpen: isEarningsModalOpen,
5185
- onClose: () => setIsEarningsModalOpen(false),
5186
- positions,
5187
- totalEarned,
5188
- isLoading: positionQuery.isLoading
5189
- }
5190
- )
5191
- ] });
5192
- }
5193
- function useSwapQuote({ fromToken, toToken, amount, enabled = true }) {
5194
- const { chainId } = useChain();
5195
- const { address } = useCompassWallet();
5196
- const query = useQuery({
5197
- queryKey: ["swapQuote", chainId, fromToken, toToken, amount, address],
5198
- queryFn: async () => {
5199
- if (!fromToken || !toToken || !amount || parseFloat(amount) <= 0 || !address) {
5200
- return null;
5201
- }
5202
- try {
5203
- const params = new URLSearchParams({
5204
- owner: address,
5205
- chain: chainId,
5206
- tokenIn: fromToken,
5207
- tokenOut: toToken,
5208
- amountIn: amount
5209
- });
5210
- const response = await fetch(`/api/compass/swap/quote?${params}`);
5211
- if (!response.ok) {
5212
- const errorData = await response.json();
5213
- const errorMessage = errorData.message || errorData.error || "Failed to get swap quote";
5214
- throw new Error(errorMessage);
5215
- }
5216
- const data = await response.json();
5217
- const outputAmount = data.estimatedAmountOut || "0";
5218
- const inputAmountNum = parseFloat(amount);
5219
- const outputAmountNum = parseFloat(outputAmount);
5220
- return {
5221
- inputAmount: amount,
5222
- outputAmount,
5223
- rate: inputAmountNum > 0 ? (outputAmountNum / inputAmountNum).toString() : "0"
5224
- };
5225
- } catch (error) {
5226
- throw error;
5227
- }
5228
- },
5229
- enabled: enabled && !!address && !!fromToken && !!toToken && !!amount && parseFloat(amount) > 0,
5230
- staleTime: 10 * 1e3,
5231
- refetchInterval: 15 * 1e3,
5232
- retry: 1
5233
- });
5234
- return {
5235
- quote: query.data,
5236
- isLoading: query.isLoading,
5237
- isError: query.isError,
5238
- error: query.error,
5239
- refetch: query.refetch
5240
- };
5241
- }
5242
-
5243
- // src/components/SwapWidget/types.ts
5244
- var DEFAULT_SWAP_TOKENS = ["USDC", "ETH", "WETH", "WBTC", "DAI", "USDT", "AUSD", "SBC"];
5245
- function SwapWidget({
5246
- layout = "full",
5247
- defaultFromToken = "ETH",
5248
- defaultToToken = "USDC",
5249
- allowedTokens = [...DEFAULT_SWAP_TOKENS],
5250
- showReverseButton = true,
5251
- showSettings = false,
5252
- onSwapSuccess,
5253
- onSwapError
5254
- }) {
5255
- const [fromToken, setFromToken] = useState(defaultFromToken);
5256
- const [toToken, setToToken] = useState(defaultToToken);
5257
- const [fromAmount, setFromAmount] = useState("");
5258
- const [isSwapping, setIsSwapping] = useState(false);
5259
- const [swapStatus, setSwapStatus] = useState("");
5260
- const { address, isConnected, signTypedData } = useCompassWallet();
5261
- const { chainId } = useChain();
5262
- const { quote, isLoading: isQuoteLoading, error: quoteError } = useSwapQuote({
5263
- fromToken,
5264
- toToken,
5265
- amount: fromAmount,
5266
- enabled: !!fromAmount && parseFloat(fromAmount) > 0
5267
- });
5268
- const handleReverse = useCallback(() => {
5269
- setFromToken(toToken);
5270
- setToToken(fromToken);
5271
- setFromAmount("");
5272
- }, [fromToken, toToken]);
5273
- const handleSwap = useCallback(async () => {
5274
- if (!address || !fromAmount || !quote) return;
5275
- setIsSwapping(true);
5276
- setSwapStatus("Preparing swap...");
5277
- try {
5278
- const prepareResponse = await fetch("/api/compass/swap/prepare", {
5279
- method: "POST",
5280
- headers: { "Content-Type": "application/json" },
5281
- body: JSON.stringify({
5282
- owner: address,
5283
- chain: chainId,
5284
- tokenIn: fromToken,
5285
- tokenOut: toToken,
5286
- amountIn: fromAmount
5287
- })
5288
- });
5289
- if (!prepareResponse.ok) {
5290
- const error = await prepareResponse.json();
5291
- throw new Error(error.error || "Failed to prepare swap");
5292
- }
5293
- const prepareData = await prepareResponse.json();
5294
- const { eip712, normalizedTypes } = prepareData;
5295
- if (!eip712) {
5296
- throw new Error("No EIP-712 data returned from prepare");
5297
- }
5298
- setSwapStatus("Please sign the transaction...");
5299
- const signature = await signTypedData({
5300
- domain: eip712.domain,
5301
- types: normalizedTypes || eip712.types,
5302
- primaryType: "SafeTx",
5303
- message: eip712.message
5304
- });
5305
- setSwapStatus("Executing swap...");
5306
- const executeResponse = await fetch("/api/compass/swap/execute", {
5307
- method: "POST",
5308
- headers: { "Content-Type": "application/json" },
5309
- body: JSON.stringify({
5310
- owner: address,
5311
- chain: chainId,
5312
- eip712,
5313
- signature
5314
- })
5315
- });
5316
- if (!executeResponse.ok) {
5317
- const error = await executeResponse.json();
5318
- throw new Error(error.error || "Failed to execute swap");
5500
+ ] })
5501
+ }
5502
+ ),
5503
+ /* @__PURE__ */ jsx(
5504
+ "p",
5505
+ {
5506
+ className: "text-xs text-center",
5507
+ style: { color: "var(--compass-color-text-tertiary)" },
5508
+ children: "Gas fees are sponsored"
5509
+ }
5510
+ )
5511
+ ] })
5319
5512
  }
5320
- const executeData = await executeResponse.json();
5321
- const txHash = executeData.txHash;
5322
- setSwapStatus("Swap successful!");
5323
- onSwapSuccess?.(fromToken, toToken, fromAmount, quote.outputAmount, txHash);
5324
- setFromAmount("");
5325
- setTimeout(() => setSwapStatus(""), 3e3);
5326
- } catch (error) {
5327
- setSwapStatus("");
5328
- onSwapError?.(error);
5329
- } finally {
5330
- setIsSwapping(false);
5331
- }
5332
- }, [address, fromAmount, quote, chainId, fromToken, toToken, signTypedData, onSwapSuccess, onSwapError]);
5333
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", style: { gap: "var(--compass-spacing-card)" }, children: [
5334
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between flex-wrap", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
5335
- /* @__PURE__ */ jsx(ChainSwitcher, {}),
5336
- /* @__PURE__ */ jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
5337
- /* @__PURE__ */ jsx(EarnAccountBalance, { compact: true }),
5338
- /* @__PURE__ */ jsx(WalletStatus, { compact: true })
5339
- ] })
5340
- ] }),
5341
- /* @__PURE__ */ jsxs(EarnAccountGuard, { children: [
5342
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
5343
- /* @__PURE__ */ jsxs("div", { className: "border relative", style: { backgroundColor: "var(--compass-color-surface)", borderColor: "var(--compass-color-border)", borderRadius: "var(--compass-border-radius-xl)", fontFamily: "var(--compass-font-family)", padding: "var(--compass-spacing-card)" }, children: [
5344
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between", style: { marginBottom: "calc(var(--compass-spacing-unit) * 0.5)" }, children: /* @__PURE__ */ jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: "From" }) }),
5345
- /* @__PURE__ */ jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.75)" }, children: [
5513
+ ),
5514
+ /* @__PURE__ */ jsx(
5515
+ ActionModal,
5516
+ {
5517
+ isOpen: isBalancesModalOpen,
5518
+ onClose: () => setIsBalancesModalOpen(false),
5519
+ title: "Balance Breakdown",
5520
+ children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: balancesQuery.data?.balances && Object.keys(balancesQuery.data.balances).length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
5521
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
5346
5522
  /* @__PURE__ */ jsx(
5347
- "input",
5523
+ "span",
5348
5524
  {
5349
- type: "number",
5350
- value: fromAmount,
5351
- onChange: (e) => setFromAmount(e.target.value),
5352
- placeholder: "0.00",
5353
- className: "flex-1 bg-transparent outline-none text-2xl font-mono min-w-0",
5354
- style: { color: "var(--compass-color-text)" }
5525
+ className: "text-xs font-medium uppercase tracking-wide",
5526
+ style: { color: "var(--compass-color-text-tertiary)" },
5527
+ children: "Available in Account"
5355
5528
  }
5356
5529
  ),
5357
- /* @__PURE__ */ jsx(
5358
- "select",
5530
+ Object.entries(balancesQuery.data.balances).map(([symbol, data]) => /* @__PURE__ */ jsxs(
5531
+ "div",
5359
5532
  {
5360
- value: fromToken,
5361
- onChange: (e) => setFromToken(e.target.value),
5362
- className: "border text-sm font-medium cursor-pointer flex-shrink-0",
5363
- style: { backgroundColor: "var(--compass-color-background)", borderColor: "var(--compass-color-border)", color: "var(--compass-color-text)", borderRadius: "var(--compass-border-radius-lg)", padding: "var(--compass-spacing-input)" },
5364
- children: allowedTokens.filter((t) => t !== toToken).map((token) => /* @__PURE__ */ jsx("option", { value: token, children: token }, token))
5365
- }
5366
- )
5367
- ] })
5368
- ] }),
5369
- showReverseButton && /* @__PURE__ */ jsx("div", { className: "flex justify-center relative z-10", style: { margin: "calc(var(--compass-spacing-unit) * -0.25) 0" }, children: /* @__PURE__ */ jsx(
5370
- "button",
5533
+ className: "flex items-center justify-between p-3 rounded-lg",
5534
+ style: {
5535
+ backgroundColor: "var(--compass-color-surface)",
5536
+ border: "1px solid var(--compass-color-border)"
5537
+ },
5538
+ children: [
5539
+ /* @__PURE__ */ jsx("span", { className: "font-medium", style: { color: "var(--compass-color-text)" }, children: symbol }),
5540
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end", children: [
5541
+ /* @__PURE__ */ jsx("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-text)" }, children: formatAmount2(data.balance) }),
5542
+ /* @__PURE__ */ jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: formatCurrency(data.usdValue) })
5543
+ ] })
5544
+ ]
5545
+ },
5546
+ symbol
5547
+ ))
5548
+ ] }),
5549
+ /* @__PURE__ */ jsxs(
5550
+ "div",
5551
+ {
5552
+ className: "flex items-center justify-between pt-3 mt-2",
5553
+ style: { borderTop: "2px solid var(--compass-color-border)" },
5554
+ children: [
5555
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", style: { color: "var(--compass-color-text)" }, children: "Total" }),
5556
+ /* @__PURE__ */ jsx(
5557
+ "span",
5558
+ {
5559
+ className: "font-bold text-xl",
5560
+ style: { color: "var(--compass-color-text)" },
5561
+ children: formatCurrency(earnAccountTotalUsd)
5562
+ }
5563
+ )
5564
+ ]
5565
+ }
5566
+ )
5567
+ ] }) : /* @__PURE__ */ jsx(
5568
+ "div",
5371
5569
  {
5372
- onClick: handleReverse,
5373
- className: "border hover:opacity-80",
5374
- style: { backgroundColor: "var(--compass-color-surface)", borderColor: "var(--compass-color-border)", borderRadius: "var(--compass-border-radius-full)", padding: "calc(var(--compass-spacing-unit) * 0.5)", transition: "var(--compass-transition-normal)" },
5375
- children: /* @__PURE__ */ jsx(ArrowDownUp, { size: 16, style: { color: "var(--compass-color-text-secondary)" } })
5570
+ className: "text-center py-4",
5571
+ style: { color: "var(--compass-color-text-tertiary)" },
5572
+ children: "No tokens in account"
5376
5573
  }
5377
- ) }),
5378
- /* @__PURE__ */ jsxs("div", { className: "border", style: { backgroundColor: "var(--compass-color-surface)", borderColor: "var(--compass-color-border)", borderRadius: "var(--compass-border-radius-xl)", fontFamily: "var(--compass-font-family)", padding: "var(--compass-spacing-card)" }, children: [
5379
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between", style: { marginBottom: "calc(var(--compass-spacing-unit) * 0.5)" }, children: /* @__PURE__ */ jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: "To" }) }),
5380
- /* @__PURE__ */ jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.75)" }, children: [
5381
- /* @__PURE__ */ jsx("div", { className: "flex-1 text-2xl font-mono", style: { color: isQuoteLoading ? "var(--compass-color-text-tertiary)" : "var(--compass-color-text)" }, children: isQuoteLoading ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
5382
- /* @__PURE__ */ jsx(Loader2, { size: 16, className: "animate-spin" }),
5383
- "Loading..."
5384
- ] }) : quote?.outputAmount ? parseFloat(quote.outputAmount).toFixed(8) : "0.00000000" }),
5385
- /* @__PURE__ */ jsx(
5386
- "select",
5387
- {
5388
- value: toToken,
5389
- onChange: (e) => setToToken(e.target.value),
5390
- className: "border text-sm font-medium cursor-pointer",
5391
- style: { backgroundColor: "var(--compass-color-background)", borderColor: "var(--compass-color-border)", color: "var(--compass-color-text)", borderRadius: "var(--compass-border-radius-lg)", padding: "var(--compass-spacing-input)" },
5392
- children: allowedTokens.filter((t) => t !== fromToken).map((token) => /* @__PURE__ */ jsx("option", { value: token, children: token }, token))
5393
- }
5394
- )
5395
- ] })
5396
- ] })
5397
- ] }),
5398
- quote && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", style: { color: "var(--compass-color-text-secondary)" }, children: [
5399
- /* @__PURE__ */ jsx("span", { children: "Rate" }),
5400
- /* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
5401
- "1 ",
5402
- fromToken,
5403
- " = ",
5404
- parseFloat(quote.rate).toFixed(6),
5405
- " ",
5406
- toToken
5407
- ] })
5408
- ] }),
5409
- quoteError && /* @__PURE__ */ jsxs(
5410
- "div",
5411
- {
5412
- className: "flex items-center text-sm",
5413
- style: {
5414
- backgroundColor: "var(--compass-color-error-muted)",
5415
- color: "var(--compass-color-error)",
5416
- borderRadius: "var(--compass-border-radius-lg)",
5417
- padding: "calc(var(--compass-spacing-unit) * 0.75)",
5418
- gap: "calc(var(--compass-spacing-unit) * 0.5)"
5419
- },
5420
- children: [
5421
- /* @__PURE__ */ jsx(AlertCircle, { size: 16 }),
5422
- /* @__PURE__ */ jsx("span", { children: quoteError.message })
5423
- ]
5424
- }
5425
- ),
5426
- swapStatus && /* @__PURE__ */ jsxs(
5427
- "div",
5428
- {
5429
- className: "flex items-center text-sm",
5430
- style: {
5431
- backgroundColor: swapStatus.includes("successful") ? "var(--compass-color-success-muted)" : "var(--compass-color-surface)",
5432
- color: swapStatus.includes("successful") ? "var(--compass-color-success)" : "var(--compass-color-text-secondary)",
5433
- borderRadius: "var(--compass-border-radius-lg)",
5434
- padding: "calc(var(--compass-spacing-unit) * 0.75)",
5435
- gap: "calc(var(--compass-spacing-unit) * 0.5)"
5436
- },
5437
- children: [
5438
- !swapStatus.includes("successful") && /* @__PURE__ */ jsx(Loader2, { size: 14, className: "animate-spin" }),
5439
- swapStatus
5440
- ]
5441
- }
5442
- ),
5443
- !isConnected ? /* @__PURE__ */ jsxs(
5444
- "div",
5445
- {
5446
- className: "flex flex-col items-center",
5447
- style: {
5448
- backgroundColor: "var(--compass-color-surface)",
5449
- border: "1px solid var(--compass-color-border)",
5450
- borderRadius: "var(--compass-border-radius-lg)",
5451
- fontFamily: "var(--compass-font-family)",
5452
- padding: "calc(var(--compass-spacing-unit) * 1.5) var(--compass-spacing-card)",
5453
- gap: "calc(var(--compass-spacing-unit) * 0.75)"
5454
- },
5455
- children: [
5456
- /* @__PURE__ */ jsx(AlertCircle, { size: 24, style: { color: "var(--compass-color-text-tertiary)" } }),
5457
- /* @__PURE__ */ jsx(
5458
- "p",
5459
- {
5460
- className: "text-sm text-center",
5461
- style: { color: "var(--compass-color-text-secondary)" },
5462
- children: "Connect your wallet to swap"
5463
- }
5464
- )
5465
- ]
5466
- }
5467
- ) : /* @__PURE__ */ jsxs(
5468
- "button",
5469
- {
5470
- onClick: handleSwap,
5471
- disabled: isSwapping || !quote || !fromAmount || parseFloat(fromAmount) <= 0,
5472
- className: "w-full font-medium flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed",
5473
- style: {
5474
- backgroundColor: "var(--compass-color-primary)",
5475
- color: "var(--compass-color-primary-text)",
5476
- borderRadius: "var(--compass-border-radius-lg)",
5477
- fontFamily: "var(--compass-font-family)",
5478
- padding: "calc(var(--compass-spacing-unit) * 0.75)",
5479
- gap: "calc(var(--compass-spacing-unit) * 0.5)",
5480
- transition: "var(--compass-transition-normal)"
5481
- },
5482
- children: [
5483
- isSwapping && /* @__PURE__ */ jsx(Loader2, { size: 18, className: "animate-spin" }),
5484
- isSwapping ? "Swapping..." : "Swap"
5485
- ]
5486
- }
5487
- )
5488
- ] })
5574
+ ) })
5575
+ }
5576
+ ),
5577
+ /* @__PURE__ */ jsx(
5578
+ ActionModal,
5579
+ {
5580
+ isOpen: isSwapModalOpen,
5581
+ onClose: () => setIsSwapModalOpen(false),
5582
+ title: "Swap Tokens",
5583
+ children: /* @__PURE__ */ jsx(
5584
+ SwapForm,
5585
+ {
5586
+ availableFromTokens: balanceTokens,
5587
+ balances: Object.fromEntries(
5588
+ Object.entries(balancesQuery.data?.balances || {}).map(([token, data]) => [token, data.balance])
5589
+ ),
5590
+ onSwapSuccess: () => {
5591
+ setIsSwapModalOpen(false);
5592
+ queryClient.invalidateQueries({ queryKey: ["earnAccountBalances"] });
5593
+ balancesQuery.refetch();
5594
+ setTimeout(() => {
5595
+ queryClient.invalidateQueries({ queryKey: ["earnAccountBalances"] });
5596
+ balancesQuery.refetch();
5597
+ }, 5e3);
5598
+ setTimeout(() => {
5599
+ queryClient.invalidateQueries({ queryKey: ["earnAccountBalances"] });
5600
+ balancesQuery.refetch();
5601
+ }, 15e3);
5602
+ }
5603
+ }
5604
+ )
5605
+ }
5606
+ ),
5607
+ /* @__PURE__ */ jsx(
5608
+ EarningsModal,
5609
+ {
5610
+ isOpen: isEarningsModalOpen,
5611
+ onClose: () => setIsEarningsModalOpen(false),
5612
+ positions,
5613
+ totalEarned,
5614
+ isLoading: positionQuery.isLoading
5615
+ }
5616
+ )
5489
5617
  ] });
5490
5618
  }
5491
5619
  function getEarliestDepositTimestamp(deposits) {
@@ -5972,7 +6100,8 @@ function PositionDetailModal({ position, onClose }) {
5972
6100
  className: "relative w-full max-w-md rounded-xl border overflow-hidden max-h-[90vh] overflow-y-auto",
5973
6101
  style: {
5974
6102
  backgroundColor: "var(--compass-color-background)",
5975
- borderColor: "var(--compass-color-border)"
6103
+ borderColor: "var(--compass-color-border)",
6104
+ scrollbarWidth: "none"
5976
6105
  },
5977
6106
  onClick: (e) => e.stopPropagation(),
5978
6107
  children: [
@@ -6475,7 +6604,7 @@ function useRebalancingData(chainOverride) {
6475
6604
  if (usdValue <= 0) continue;
6476
6605
  balances.push({
6477
6606
  token: symbol,
6478
- balance: parseFloat(td.balanceFormatted || td.balance_formatted || "0"),
6607
+ balance: parseFloat(td.balance || "0"),
6479
6608
  usdValue
6480
6609
  });
6481
6610
  }
@@ -6757,11 +6886,13 @@ function PortfolioBalanceCard({
6757
6886
  totalIdleUsd,
6758
6887
  idleBalances,
6759
6888
  earnAccountAddress,
6889
+ walletAddress,
6760
6890
  onViewPositions,
6761
6891
  positionCount,
6762
6892
  totalEarned = 0,
6763
6893
  showTopUp = true,
6764
- onTopUp
6894
+ onTopUp,
6895
+ onSwap
6765
6896
  }) {
6766
6897
  const [showBalancesModal, setShowBalancesModal] = useState(false);
6767
6898
  const tokenBalances = idleBalances.map((b) => ({
@@ -6802,39 +6933,59 @@ function PortfolioBalanceCard({
6802
6933
  ]
6803
6934
  }
6804
6935
  ),
6805
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
6806
- /* @__PURE__ */ jsx(
6936
+ /* @__PURE__ */ jsx(
6937
+ "button",
6938
+ {
6939
+ onClick: () => setShowBalancesModal(true),
6940
+ className: "transition-opacity hover:opacity-80",
6941
+ children: /* @__PURE__ */ jsx(
6942
+ "span",
6943
+ {
6944
+ className: "font-bold",
6945
+ style: {
6946
+ color: "var(--compass-color-text)",
6947
+ fontSize: "2rem",
6948
+ lineHeight: "1"
6949
+ },
6950
+ children: formatUSD(totalUsd)
6951
+ }
6952
+ )
6953
+ }
6954
+ ),
6955
+ (onSwap || showTopUp && onTopUp) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col", style: { gap: "6px", marginTop: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
6956
+ onSwap && /* @__PURE__ */ jsxs(
6807
6957
  "button",
6808
6958
  {
6809
- onClick: () => setShowBalancesModal(true),
6810
- className: "transition-opacity hover:opacity-80",
6811
- children: /* @__PURE__ */ jsx(
6812
- "span",
6813
- {
6814
- className: "font-bold",
6815
- style: {
6816
- color: "var(--compass-color-text)",
6817
- fontSize: "2rem",
6818
- lineHeight: "1"
6819
- },
6820
- children: formatUSD(totalUsd)
6821
- }
6822
- )
6959
+ onClick: onSwap,
6960
+ className: "flex items-center justify-center font-medium transition-all hover:opacity-80 w-full",
6961
+ style: {
6962
+ backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-surface))",
6963
+ border: "1px solid var(--compass-color-border)",
6964
+ color: "var(--compass-color-text-secondary)",
6965
+ borderRadius: "var(--compass-border-radius-md)",
6966
+ padding: "8px 10px",
6967
+ gap: "6px",
6968
+ fontSize: "13px"
6969
+ },
6970
+ children: [
6971
+ /* @__PURE__ */ jsx(ArrowLeftRight, { size: 14 }),
6972
+ "Swap"
6973
+ ]
6823
6974
  }
6824
6975
  ),
6825
6976
  showTopUp && onTopUp && /* @__PURE__ */ jsxs(
6826
6977
  "button",
6827
6978
  {
6828
6979
  onClick: onTopUp,
6829
- className: "flex items-center font-medium transition-all hover:opacity-80",
6980
+ className: "flex items-center justify-center font-medium transition-all hover:opacity-80 w-full",
6830
6981
  style: {
6831
6982
  backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-surface))",
6832
6983
  border: "1px solid var(--compass-color-border)",
6833
6984
  color: "var(--compass-color-text-secondary)",
6834
6985
  borderRadius: "var(--compass-border-radius-md)",
6835
- padding: "6px 10px",
6836
- gap: "4px",
6837
- fontSize: "12px"
6986
+ padding: "8px 10px",
6987
+ gap: "6px",
6988
+ fontSize: "13px"
6838
6989
  },
6839
6990
  children: [
6840
6991
  /* @__PURE__ */ jsx(Plus, { size: 14 }),
@@ -6907,7 +7058,8 @@ function PortfolioBalanceCard({
6907
7058
  onClose: () => setShowBalancesModal(false),
6908
7059
  balances: tokenBalances,
6909
7060
  totalUsdValue: totalIdleUsd.toString(),
6910
- earnAccountAddress
7061
+ earnAccountAddress,
7062
+ walletAddress
6911
7063
  }
6912
7064
  )
6913
7065
  ] });
@@ -6933,10 +7085,11 @@ function formatPercent(value) {
6933
7085
  function PercentInput({ value, onChange }) {
6934
7086
  const [localValue, setLocalValue] = useState(value.toString());
6935
7087
  const [isFocused, setIsFocused] = useState(false);
6936
- if (!isFocused && localValue !== value.toString()) {
7088
+ const roundedStr = parseFloat(value.toFixed(2)).toString();
7089
+ if (!isFocused && localValue !== roundedStr) {
6937
7090
  const parsed = parseFloat(localValue);
6938
7091
  if (isNaN(parsed) || Math.abs(parsed - value) > 1e-3) {
6939
- setLocalValue(value.toString());
7092
+ setLocalValue(roundedStr);
6940
7093
  }
6941
7094
  }
6942
7095
  return /* @__PURE__ */ jsx(
@@ -6947,7 +7100,7 @@ function PercentInput({ value, onChange }) {
6947
7100
  value: isFocused ? localValue : formatPercent(value).replace("%", ""),
6948
7101
  onFocus: () => {
6949
7102
  setIsFocused(true);
6950
- setLocalValue(value.toString());
7103
+ setLocalValue(parseFloat(value.toFixed(2)).toString());
6951
7104
  },
6952
7105
  onChange: (e) => {
6953
7106
  const raw = e.target.value;
@@ -7071,7 +7224,7 @@ function AllocationEditor({
7071
7224
  currentPos && /* @__PURE__ */ jsxs(Fragment, { children: [
7072
7225
  /* @__PURE__ */ jsx("span", { className: "text-xs font-mono", style: { color: "var(--compass-color-text-secondary)", fontSize: "10px" }, children: formatUSD(currentPos.usdValue) }),
7073
7226
  /* @__PURE__ */ jsxs("span", { style: { color: "var(--compass-color-success)", fontSize: "10px" }, children: [
7074
- currentPos.apy.toFixed(1),
7227
+ currentPos.apy.toFixed(2),
7075
7228
  "%"
7076
7229
  ] })
7077
7230
  ] }),
@@ -7175,7 +7328,6 @@ function AllocationEditor({
7175
7328
  ) })
7176
7329
  ] });
7177
7330
  }
7178
- var SUPPORTED_TOKENS2 = ["USDC", "USDT", "DAI", "WETH", "SBC", "AUSD"];
7179
7331
  var EVM_CHAIN_IDS2 = {
7180
7332
  ethereum: 1,
7181
7333
  base: 8453,
@@ -7202,6 +7354,7 @@ function RebalancingWidget({
7202
7354
  const { chainId: contextChainId, setChainId } = useChain();
7203
7355
  const CHAIN_ID = chain || contextChainId;
7204
7356
  const { address, signTypedData, isConnected, login, switchChain, walletChainId } = useEmbeddableWallet();
7357
+ const { earnAccountAddress } = useEarnAccount();
7205
7358
  const queryClient = useQueryClient();
7206
7359
  const { portfolio, earnAccountMarkets, isMarketsLoading, isLoading, isError, error, refetch } = useRebalancingData(chain);
7207
7360
  const allowedVariableMarketIds = useMemo(() => {
@@ -7236,7 +7389,12 @@ function RebalancingWidget({
7236
7389
  const [txHash, setTxHash] = useState(null);
7237
7390
  const [hasInitializedTargets, setHasInitializedTargets] = useState(false);
7238
7391
  const [isEarningsModalOpen, setIsEarningsModalOpen] = useState(false);
7392
+ const [isSwapModalOpen, setIsSwapModalOpen] = useState(false);
7239
7393
  const [isAddMarketExpanded, setIsAddMarketExpanded] = useState(false);
7394
+ const balanceTokens = useMemo(() => {
7395
+ if (!portfolio?.idleBalances) return [];
7396
+ return portfolio.idleBalances.map((b) => b.token);
7397
+ }, [portfolio?.idleBalances]);
7240
7398
  const [marketTab, setMarketTab] = useState("variable");
7241
7399
  const [selectedMarket, setSelectedMarket] = useState(null);
7242
7400
  const [selectedToken, setSelectedToken] = useState("USDC");
@@ -7255,25 +7413,26 @@ function RebalancingWidget({
7255
7413
  setTxHash(null);
7256
7414
  setHasInitializedTargets(false);
7257
7415
  setIsAddMarketExpanded(false);
7416
+ setIsSwapModalOpen(false);
7258
7417
  setSelectedMarket(null);
7259
7418
  setDepositAmount("");
7260
7419
  setDepositError(null);
7261
7420
  setDepositStatus("");
7262
7421
  }, [CHAIN_ID]);
7263
7422
  useEffect(() => {
7264
- if (portfolio && portfolio.positions.length > 0 && !hasInitializedTargets) {
7423
+ if (portfolio && portfolio.positions.length > 0 && !hasInitializedTargets && !isLoading) {
7265
7424
  setTargets(
7266
7425
  portfolio.positions.map((p) => ({
7267
7426
  venueType: p.venueType,
7268
7427
  venueAddress: p.venueAddress,
7269
7428
  venueName: p.venueName,
7270
7429
  token: p.token,
7271
- targetPercent: p.allocationPercent
7430
+ targetPercent: parseFloat(p.allocationPercent.toFixed(2))
7272
7431
  }))
7273
7432
  );
7274
7433
  setHasInitializedTargets(true);
7275
7434
  }
7276
- }, [portfolio, hasInitializedTargets]);
7435
+ }, [portfolio, hasInitializedTargets, isLoading]);
7277
7436
  const state = useMemo(() => {
7278
7437
  if (isLoading) return "loading";
7279
7438
  if (!portfolio || portfolio.positions.length === 0) return "empty";
@@ -7308,7 +7467,7 @@ function RebalancingWidget({
7308
7467
  venueAddress: p.venueAddress,
7309
7468
  venueName: p.venueName,
7310
7469
  token: p.token,
7311
- targetPercent: p.allocationPercent
7470
+ targetPercent: parseFloat(p.allocationPercent.toFixed(2))
7312
7471
  }))
7313
7472
  );
7314
7473
  setPreviewPlan(null);
@@ -7324,7 +7483,8 @@ function RebalancingWidget({
7324
7483
  setTargets((prev) => prev.filter((_, i) => i !== index));
7325
7484
  }, []);
7326
7485
  const handleUpdatePercent = useCallback((index, value) => {
7327
- setTargets((prev) => prev.map((t, i) => i === index ? { ...t, targetPercent: Math.max(0, Math.min(100, value)) } : t));
7486
+ const rounded = parseFloat(Math.max(0, Math.min(100, value)).toFixed(2));
7487
+ setTargets((prev) => prev.map((t, i) => i === index ? { ...t, targetPercent: rounded } : t));
7328
7488
  }, []);
7329
7489
  const ensureCorrectChain = useCallback(async () => {
7330
7490
  const targetChainId = EVM_CHAIN_IDS2[CHAIN_ID];
@@ -7696,7 +7856,7 @@ function RebalancingWidget({
7696
7856
  ]
7697
7857
  }
7698
7858
  ),
7699
- state === "empty" && /* @__PURE__ */ jsxs(
7859
+ state === "empty" && /* @__PURE__ */ jsx(
7700
7860
  "div",
7701
7861
  {
7702
7862
  className: "p-8 text-center",
@@ -7704,7 +7864,32 @@ function RebalancingWidget({
7704
7864
  backgroundColor: "var(--compass-color-surface)",
7705
7865
  borderRadius: "var(--compass-border-radius-xl)"
7706
7866
  },
7707
- children: [
7867
+ children: !isConnected ? /* @__PURE__ */ jsxs(Fragment, { children: [
7868
+ /* @__PURE__ */ jsx(
7869
+ "p",
7870
+ {
7871
+ className: "text-lg font-semibold mb-2",
7872
+ style: { color: "var(--compass-color-text)" },
7873
+ children: "Connect your wallet"
7874
+ }
7875
+ ),
7876
+ /* @__PURE__ */ jsx("p", { className: "text-sm mb-4", style: { color: "var(--compass-color-text-secondary)" }, children: "Connect your wallet to view and manage your DeFi portfolio." }),
7877
+ login && /* @__PURE__ */ jsx(
7878
+ "button",
7879
+ {
7880
+ onClick: login,
7881
+ className: "font-semibold transition-all",
7882
+ style: {
7883
+ backgroundColor: "var(--compass-color-primary)",
7884
+ color: "var(--compass-color-primary-text, white)",
7885
+ borderRadius: "var(--compass-border-radius-lg)",
7886
+ padding: "calc(var(--compass-spacing-unit) * 0.75) calc(var(--compass-spacing-unit) * 1.5)",
7887
+ fontSize: "0.875rem"
7888
+ },
7889
+ children: "Connect Wallet"
7890
+ }
7891
+ )
7892
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7708
7893
  /* @__PURE__ */ jsx(
7709
7894
  "p",
7710
7895
  {
@@ -7714,7 +7899,7 @@ function RebalancingWidget({
7714
7899
  }
7715
7900
  ),
7716
7901
  /* @__PURE__ */ jsx("p", { className: "text-sm", style: { color: "var(--compass-color-text-secondary)" }, children: "Deposit into a vault, Aave market, or Pendle market to start rebalancing." })
7717
- ]
7902
+ ] })
7718
7903
  }
7719
7904
  ),
7720
7905
  state !== "loading" && state !== "empty" && portfolio && /* @__PURE__ */ jsxs("div", { className: "flex flex-col", style: { gap: "calc(var(--compass-spacing-unit) * 0.75)" }, children: [
@@ -7724,11 +7909,14 @@ function RebalancingWidget({
7724
7909
  totalUsd: portfolio.totalUsd,
7725
7910
  totalIdleUsd: portfolio.totalIdleUsd,
7726
7911
  idleBalances: portfolio.idleBalances,
7912
+ earnAccountAddress: earnAccountAddress ?? void 0,
7913
+ walletAddress: address ?? void 0,
7727
7914
  onViewPositions: () => setIsEarningsModalOpen(true),
7728
7915
  positionCount: portfolio.positions.length,
7729
7916
  totalEarned,
7730
7917
  showTopUp,
7731
- onTopUp: () => earnBalanceRef.current?.openTransferModal()
7918
+ onTopUp: () => earnBalanceRef.current?.openTransferModal(),
7919
+ onSwap: balanceTokens.length > 0 ? () => setIsSwapModalOpen(true) : void 0
7732
7920
  }
7733
7921
  ),
7734
7922
  /* @__PURE__ */ jsx(
@@ -7848,7 +8036,7 @@ function RebalancingWidget({
7848
8036
  boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
7849
8037
  minWidth: "100px"
7850
8038
  },
7851
- children: SUPPORTED_TOKENS2.map((token) => /* @__PURE__ */ jsx(
8039
+ children: balanceTokens.map((token) => /* @__PURE__ */ jsx(
7852
8040
  "button",
7853
8041
  {
7854
8042
  onClick: () => {
@@ -8029,7 +8217,25 @@ function RebalancingWidget({
8029
8217
  children: [
8030
8218
  /* @__PURE__ */ jsx(Check, { size: 24, className: "mx-auto mb-2", style: { color: "var(--compass-color-success)" } }),
8031
8219
  /* @__PURE__ */ jsx("p", { className: "font-semibold mb-1", style: { color: "var(--compass-color-success)" }, children: "Rebalance Complete" }),
8032
- /* @__PURE__ */ jsx("p", { className: "text-xs font-mono break-all", style: { color: "var(--compass-color-text-secondary)" }, children: txHash })
8220
+ /* @__PURE__ */ jsxs(
8221
+ "button",
8222
+ {
8223
+ onClick: () => navigator.clipboard.writeText(txHash),
8224
+ className: "inline-flex items-center justify-center gap-1.5 text-xs font-mono break-all mx-auto",
8225
+ style: {
8226
+ color: "var(--compass-color-text-secondary)",
8227
+ background: "none",
8228
+ border: "none",
8229
+ cursor: "pointer",
8230
+ padding: 0
8231
+ },
8232
+ title: "Copy transaction hash",
8233
+ children: [
8234
+ txHash,
8235
+ /* @__PURE__ */ jsx(Copy, { size: 12, className: "flex-shrink-0", style: { color: "var(--compass-color-text-tertiary)" } })
8236
+ ]
8237
+ }
8238
+ )
8033
8239
  ]
8034
8240
  }
8035
8241
  ),
@@ -8188,6 +8394,30 @@ function RebalancingWidget({
8188
8394
  }
8189
8395
  ) }),
8190
8396
  /* @__PURE__ */ jsx(EarnAccountBalance, { ref: earnBalanceRef, compact: true, hideVisual: true, onTransferComplete: () => refetch() }),
8397
+ /* @__PURE__ */ jsx(
8398
+ ActionModal,
8399
+ {
8400
+ isOpen: isSwapModalOpen,
8401
+ onClose: () => setIsSwapModalOpen(false),
8402
+ title: "Swap Tokens",
8403
+ children: /* @__PURE__ */ jsx(
8404
+ SwapForm,
8405
+ {
8406
+ availableFromTokens: balanceTokens,
8407
+ balances: Object.fromEntries(
8408
+ (portfolio?.idleBalances || []).map((b) => [b.token, b.balance.toString()])
8409
+ ),
8410
+ onSwapSuccess: () => {
8411
+ setIsSwapModalOpen(false);
8412
+ refetch();
8413
+ setTimeout(() => refetch(), 5e3);
8414
+ setTimeout(() => refetch(), 15e3);
8415
+ },
8416
+ onSwapError: onError
8417
+ }
8418
+ )
8419
+ }
8420
+ ),
8191
8421
  /* @__PURE__ */ jsx(
8192
8422
  EarningsModal,
8193
8423
  {
@@ -8245,7 +8475,6 @@ function ActionList({ actions }) {
8245
8475
 
8246
8476
  // src/components/CompassEarnWidget/presets.ts
8247
8477
  var allTabs = [
8248
- { id: "swap", label: "Swap", enabled: true },
8249
8478
  { id: "rebalance", label: "Rebalance", enabled: true },
8250
8479
  // TODO: Positions tab temporarily disabled - needs more work on API response handling
8251
8480
  { id: "positions", label: "Positions", enabled: false }
@@ -8254,22 +8483,16 @@ function getTabsForPreset(preset) {
8254
8483
  switch (preset) {
8255
8484
  case "full":
8256
8485
  return allTabs;
8257
- case "swap-only":
8258
- return allTabs.map((tab) => ({
8259
- ...tab,
8260
- enabled: tab.id === "swap"
8261
- }));
8262
8486
  default:
8263
8487
  return allTabs;
8264
8488
  }
8265
8489
  }
8266
8490
  function getDefaultTab(tabs) {
8267
8491
  const enabledTab = tabs.find((t) => t.enabled);
8268
- return enabledTab?.id || "swap";
8492
+ return enabledTab?.id || "rebalance";
8269
8493
  }
8270
8494
  function CompassEarnWidget({
8271
8495
  preset = "full",
8272
- enableSwap,
8273
8496
  enablePositions,
8274
8497
  enableRebalance,
8275
8498
  defaultTab,
@@ -8281,12 +8504,11 @@ function CompassEarnWidget({
8281
8504
  const baseTabs = getTabsForPreset(preset);
8282
8505
  return baseTabs.map((tab) => {
8283
8506
  let enabled = tab.enabled;
8284
- if (tab.id === "swap" && enableSwap !== void 0) enabled = enableSwap;
8285
8507
  if (tab.id === "positions" && enablePositions !== void 0) enabled = enablePositions;
8286
8508
  if (tab.id === "rebalance" && enableRebalance !== void 0) enabled = enableRebalance;
8287
8509
  return { ...tab, enabled };
8288
8510
  });
8289
- }, [preset, enableSwap, enablePositions, enableRebalance]);
8511
+ }, [preset, enablePositions, enableRebalance]);
8290
8512
  const enabledTabs = tabs.filter((t) => t.enabled);
8291
8513
  const initialTab = defaultTab && tabs.find((t) => t.id === defaultTab)?.enabled ? defaultTab : getDefaultTab(tabs);
8292
8514
  const [activeTab, setActiveTab] = useState(initialTab);
@@ -8327,7 +8549,6 @@ function CompassEarnWidget({
8327
8549
  }
8328
8550
  ),
8329
8551
  /* @__PURE__ */ jsxs("div", { children: [
8330
- activeTab === "swap" && /* @__PURE__ */ jsx(SwapWidget, {}),
8331
8552
  activeTab === "rebalance" && /* @__PURE__ */ jsx(RebalancingWidget, {}),
8332
8553
  activeTab === "positions" && /* @__PURE__ */ jsx(
8333
8554
  EarnPositionsList,
@@ -8359,6 +8580,6 @@ var CHAINS = {
8359
8580
  }
8360
8581
  };
8361
8582
 
8362
- export { AccountBalancesModal, ActionModal, ApiProvider, CHAINS, ChainSwitcher, CompassEarnWidget, CompassProvider, DEFAULT_SWAP_TOKENS, DepositWithdrawForm, EarnAccount, EarnAccountBalance, EarnAccountGuard, PnLSummary, RebalancingWidget, SwapWidget, ThemeProvider, TransactionHistory, WalletStatus, themePresets, useChain, useCompassApi, useCompassChain, useCompassWallet, useEarnAccount, useEmbeddableApi, useEmbeddableWallet, useRebalancingData, useSwapQuote, useTheme };
8583
+ export { AccountBalancesModal, ActionModal, ApiProvider, CHAINS, ChainSwitcher, CompassEarnWidget, CompassProvider, CopyableAddress, DepositWithdrawForm, EarnAccount, EarnAccountBalance, EarnAccountGuard, PnLSummary, RebalancingWidget, SwapForm, ThemeProvider, TransactionHistory, WalletStatus, themePresets, useChain, useCompassApi, useCompassChain, useCompassWallet, useEarnAccount, useEmbeddableApi, useEmbeddableWallet, useRebalancingData, useSwapQuote, useTheme };
8363
8584
  //# sourceMappingURL=index.mjs.map
8364
8585
  //# sourceMappingURL=index.mjs.map