@compass-labs/widgets 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1123,7 +1123,7 @@ function PnLSummary({ pnl, tokenSymbol, tokenPrice }) {
1123
1123
  const prefix = value >= 0 ? "+" : "";
1124
1124
  return `${prefix}${value.toFixed(4)}`;
1125
1125
  };
1126
- const formatUSD = (value) => {
1126
+ const formatUSD2 = (value) => {
1127
1127
  const usdValue = value * tokenPrice;
1128
1128
  const prefix = usdValue >= 0 ? "+$" : "-$";
1129
1129
  return `${prefix}${Math.abs(usdValue).toFixed(2)}`;
@@ -1200,7 +1200,7 @@ function PnLSummary({ pnl, tokenSymbol, tokenPrice }) {
1200
1200
  children: formatPnL(unrealizedPnl)
1201
1201
  }
1202
1202
  ),
1203
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono", style: { color: pnlColor(unrealizedPnl) }, children: formatUSD(unrealizedPnl) })
1203
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono", style: { color: pnlColor(unrealizedPnl) }, children: formatUSD2(unrealizedPnl) })
1204
1204
  ] }),
1205
1205
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
1206
1206
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1219,7 +1219,7 @@ function PnLSummary({ pnl, tokenSymbol, tokenPrice }) {
1219
1219
  children: formatPnL(realizedPnl)
1220
1220
  }
1221
1221
  ),
1222
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono", style: { color: pnlColor(realizedPnl) }, children: formatUSD(realizedPnl) })
1222
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono", style: { color: pnlColor(realizedPnl) }, children: formatUSD2(realizedPnl) })
1223
1223
  ] })
1224
1224
  ] }),
1225
1225
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1244,7 +1244,7 @@ function PnLSummary({ pnl, tokenSymbol, tokenPrice }) {
1244
1244
  ] }),
1245
1245
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-mono", style: { color: pnlColor(totalPnl) }, children: [
1246
1246
  "(",
1247
- formatUSD(totalPnl),
1247
+ formatUSD2(totalPnl),
1248
1248
  ")"
1249
1249
  ] })
1250
1250
  ] })
@@ -1256,161 +1256,308 @@ function PnLSummary({ pnl, tokenSymbol, tokenPrice }) {
1256
1256
  )
1257
1257
  ] });
1258
1258
  }
1259
- var CHAINS = {
1260
- ethereum: {
1261
- id: "ethereum",
1262
- name: "Ethereum",
1263
- viemChain: chains.mainnet,
1264
- icon: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/info/logo.png"
1265
- },
1266
- base: {
1267
- id: "base",
1268
- name: "Base",
1269
- viemChain: chains.base,
1270
- icon: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/base/info/logo.png"
1271
- },
1272
- arbitrum: {
1273
- id: "arbitrum",
1274
- name: "Arbitrum",
1275
- viemChain: chains.arbitrum,
1276
- icon: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/arbitrum/info/logo.png"
1277
- }
1278
- };
1279
- var TOKEN_DECIMALS = {
1280
- USDC: 6,
1281
- USDT: 6,
1282
- DAI: 18,
1283
- ETH: 18,
1284
- WETH: 18,
1285
- WBTC: 8,
1286
- cbBTC: 8
1287
- };
1259
+
1260
+ // src/utils/format.ts
1261
+ function formatAmount(value) {
1262
+ const num = typeof value === "string" ? parseFloat(value) : value;
1263
+ if (isNaN(num)) return "0";
1264
+ return parseFloat(num.toFixed(6)).toString();
1265
+ }
1266
+ function TokenSelector({
1267
+ tokens,
1268
+ selectedToken,
1269
+ onSelect,
1270
+ balances,
1271
+ showBalances = true,
1272
+ disabled = false
1273
+ }) {
1274
+ const [isOpen, setIsOpen] = react.useState(false);
1275
+ const dropdownRef = react.useRef(null);
1276
+ react.useEffect(() => {
1277
+ function handleClickOutside(event) {
1278
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
1279
+ setIsOpen(false);
1280
+ }
1281
+ }
1282
+ document.addEventListener("mousedown", handleClickOutside);
1283
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1284
+ }, []);
1285
+ const handleSelect = (token) => {
1286
+ onSelect(token);
1287
+ setIsOpen(false);
1288
+ };
1289
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", ref: dropdownRef, children: [
1290
+ /* @__PURE__ */ jsxRuntime.jsxs(
1291
+ "button",
1292
+ {
1293
+ type: "button",
1294
+ onClick: () => !disabled && setIsOpen(!isOpen),
1295
+ disabled,
1296
+ className: "flex items-center gap-2 px-3 py-2 rounded-lg border transition-colors min-w-[120px]",
1297
+ style: {
1298
+ backgroundColor: "var(--compass-color-background)",
1299
+ borderColor: isOpen ? "var(--compass-color-primary)" : "var(--compass-color-border)",
1300
+ color: "var(--compass-color-text)",
1301
+ cursor: disabled ? "not-allowed" : "pointer",
1302
+ opacity: disabled ? 0.5 : 1
1303
+ },
1304
+ children: [
1305
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium flex-1 text-left", children: selectedToken }),
1306
+ /* @__PURE__ */ jsxRuntime.jsx(
1307
+ lucideReact.ChevronDown,
1308
+ {
1309
+ size: 16,
1310
+ style: {
1311
+ color: "var(--compass-color-text-secondary)",
1312
+ transform: isOpen ? "rotate(180deg)" : "rotate(0deg)",
1313
+ transition: "transform 0.2s"
1314
+ }
1315
+ }
1316
+ )
1317
+ ]
1318
+ }
1319
+ ),
1320
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx(
1321
+ "div",
1322
+ {
1323
+ className: "absolute z-50 mt-1 w-full min-w-[160px] rounded-lg border overflow-y-auto",
1324
+ style: {
1325
+ backgroundColor: "var(--compass-color-surface)",
1326
+ borderColor: "var(--compass-color-border)",
1327
+ boxShadow: "var(--compass-shadow-lg)",
1328
+ maxHeight: "200px"
1329
+ },
1330
+ children: tokens.map((token) => {
1331
+ const balance = balances?.[token];
1332
+ const isSelected = token === selectedToken;
1333
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1334
+ "button",
1335
+ {
1336
+ type: "button",
1337
+ onClick: () => handleSelect(token),
1338
+ className: "w-full px-3 py-2 flex items-center justify-between transition-colors",
1339
+ style: {
1340
+ backgroundColor: isSelected ? "var(--compass-color-primary-muted)" : "transparent",
1341
+ color: "var(--compass-color-text)"
1342
+ },
1343
+ onMouseEnter: (e) => {
1344
+ if (!isSelected) {
1345
+ e.currentTarget.style.backgroundColor = "var(--compass-color-surface-hover)";
1346
+ }
1347
+ },
1348
+ onMouseLeave: (e) => {
1349
+ if (!isSelected) {
1350
+ e.currentTarget.style.backgroundColor = "transparent";
1351
+ }
1352
+ },
1353
+ children: [
1354
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: token }),
1355
+ showBalances && balance && /* @__PURE__ */ jsxRuntime.jsx(
1356
+ "span",
1357
+ {
1358
+ className: "text-sm font-mono",
1359
+ style: { color: "var(--compass-color-text-secondary)" },
1360
+ children: formatAmount(balance)
1361
+ }
1362
+ )
1363
+ ]
1364
+ },
1365
+ token
1366
+ );
1367
+ })
1368
+ }
1369
+ )
1370
+ ] });
1371
+ }
1288
1372
  function DepositWithdrawForm({
1289
1373
  venueType,
1290
1374
  venueAddress,
1291
- tokenSymbol,
1292
- tokenDecimals,
1375
+ venueToken,
1376
+ depositTokens = ["SBC", "AUSD", "USDC", "USDT", "WETH", "DAI"],
1293
1377
  positionBalance = "0",
1294
1378
  onSuccess,
1295
1379
  onError
1296
1380
  }) {
1297
1381
  const [activeTab, setActiveTab] = react.useState("deposit");
1382
+ const [selectedToken, setSelectedToken] = react.useState(venueToken);
1298
1383
  const [amount, setAmount] = react.useState("");
1299
1384
  const [isSubmitting, setIsSubmitting] = react.useState(false);
1300
1385
  const [statusMessage, setStatusMessage] = react.useState("");
1301
1386
  const [error, setError] = react.useState(null);
1302
- const { address, isConnected, signTypedData, switchChain } = useCompassWallet();
1303
- const { client } = useEmbeddableApi();
1387
+ const { address, isConnected, signTypedData } = useCompassWallet();
1304
1388
  const { chainId } = useChain();
1305
1389
  const { earnAccountAddress } = useEarnAccount();
1306
1390
  const queryClient = reactQuery.useQueryClient();
1307
- const chainConfig = CHAINS[chainId];
1308
- const targetChainId = chainConfig?.viemChain?.id;
1391
+ const needsSwap = activeTab === "deposit" && selectedToken !== venueToken;
1309
1392
  const { data: tokenBalance } = reactQuery.useQuery({
1310
- queryKey: ["earnAccountTokenBalance", chainId, earnAccountAddress, tokenSymbol],
1393
+ queryKey: ["earnAccountTokenBalance", chainId, earnAccountAddress, selectedToken],
1311
1394
  queryFn: async () => {
1312
1395
  if (!earnAccountAddress) return "0";
1313
1396
  try {
1314
- const response = await client.token.tokenBalance({
1315
- chain: chainId,
1316
- user: earnAccountAddress,
1317
- token: tokenSymbol
1318
- });
1319
- return response.amount || "0";
1320
- } catch (error2) {
1321
- console.error("Error fetching earn account token balance:", error2);
1397
+ const response = await fetch(
1398
+ `/api/compass/earn-account/balances?owner=${address}&chain=${chainId}&tokens=${selectedToken}`
1399
+ );
1400
+ if (!response.ok) return "0";
1401
+ const data = await response.json();
1402
+ return data.balances?.[selectedToken] || "0";
1403
+ } catch {
1322
1404
  return "0";
1323
1405
  }
1324
1406
  },
1325
- enabled: !!earnAccountAddress,
1407
+ enabled: !!earnAccountAddress && !!address,
1326
1408
  staleTime: 10 * 1e3
1327
1409
  });
1328
1410
  const availableBalance = tokenBalance || "0";
1329
1411
  const maxBalance = activeTab === "deposit" ? availableBalance : positionBalance;
1330
- const handleQuickAmount = react.useCallback((percentage) => {
1331
- const max = parseFloat(maxBalance);
1332
- if (isNaN(max)) return;
1333
- setAmount((max * percentage).toFixed(tokenDecimals > 6 ? 6 : tokenDecimals));
1334
- }, [maxBalance, tokenDecimals]);
1412
+ const handleQuickAmount = react.useCallback(
1413
+ (percentage) => {
1414
+ const max = parseFloat(maxBalance);
1415
+ if (isNaN(max)) return;
1416
+ setAmount(formatAmount(max * percentage));
1417
+ },
1418
+ [maxBalance]
1419
+ );
1335
1420
  const handleSubmit = react.useCallback(async () => {
1336
1421
  if (!address || !amount) return;
1337
1422
  setIsSubmitting(true);
1338
1423
  setStatusMessage("Preparing transaction...");
1339
1424
  setError(null);
1340
1425
  try {
1341
- if (switchChain && targetChainId) {
1342
- setStatusMessage("Checking network...");
1343
- try {
1344
- await switchChain(targetChainId);
1345
- } catch {
1346
- }
1347
- }
1348
1426
  const isDeposit = activeTab === "deposit";
1349
- const prepareEndpoint = isDeposit ? "/api/compass/deposit/prepare" : "/api/compass/withdraw/prepare";
1350
- const executeEndpoint = isDeposit ? "/api/compass/deposit/execute" : "/api/compass/withdraw/execute";
1351
- const prepareBody = {
1352
- amount,
1353
- token: tokenSymbol,
1354
- owner: address,
1355
- chain: chainId,
1356
- venueType
1357
- };
1358
- if (venueType === "VAULT") {
1359
- prepareBody.vaultAddress = venueAddress;
1360
- } else if (venueType === "PENDLE_PT") {
1361
- prepareBody.marketAddress = venueAddress;
1362
- prepareBody.maxSlippagePercent = 1;
1363
- }
1364
- setStatusMessage("Getting transaction data...");
1365
- const prepareResponse = await fetch(prepareEndpoint, {
1366
- method: "POST",
1367
- headers: { "Content-Type": "application/json" },
1368
- body: JSON.stringify(prepareBody)
1369
- });
1370
- if (!prepareResponse.ok) {
1371
- const errorData = await prepareResponse.json();
1372
- throw new Error(errorData.error || "Failed to prepare transaction");
1373
- }
1374
- const { eip712, normalizedTypes, domain, message } = await prepareResponse.json();
1375
- setStatusMessage("Please sign the transaction...");
1376
- const signature = await signTypedData({
1377
- domain,
1378
- types: normalizedTypes,
1379
- primaryType: "SafeTx",
1380
- message
1381
- });
1382
- setStatusMessage("Executing transaction...");
1383
- const executeResponse = await fetch(executeEndpoint, {
1384
- method: "POST",
1385
- headers: { "Content-Type": "application/json" },
1386
- body: JSON.stringify({
1427
+ if (isDeposit && needsSwap) {
1428
+ setStatusMessage("Getting swap quote...");
1429
+ const quoteResponse = await fetch(
1430
+ `/api/compass/swap/quote?owner=${address}&chain=${chainId}&tokenIn=${selectedToken}&tokenOut=${venueToken}&amountIn=${amount}`
1431
+ );
1432
+ if (!quoteResponse.ok) {
1433
+ const errorData = await quoteResponse.json();
1434
+ throw new Error(errorData.error || "Failed to get swap quote");
1435
+ }
1436
+ const quoteData = await quoteResponse.json();
1437
+ const estimatedOutput = quoteData.estimatedAmountOut;
1438
+ if (!estimatedOutput || parseFloat(estimatedOutput) <= 0) {
1439
+ throw new Error("Invalid swap quote - no output amount");
1440
+ }
1441
+ const depositAmount = (parseFloat(estimatedOutput) * 0.99).toString();
1442
+ setStatusMessage("Preparing swap and deposit...");
1443
+ const bundleActions = [
1444
+ {
1445
+ body: {
1446
+ actionType: "V2_SWAP",
1447
+ tokenIn: selectedToken,
1448
+ tokenOut: venueToken,
1449
+ amountIn: amount,
1450
+ maxSlippagePercent: 1
1451
+ }
1452
+ },
1453
+ {
1454
+ body: {
1455
+ actionType: "V2_MANAGE",
1456
+ action: "DEPOSIT",
1457
+ venue: venueType === "VAULT" ? { type: "VAULT", vaultAddress: venueAddress } : venueType === "AAVE" ? { type: "AAVE", token: venueToken } : { type: "PENDLE_PT", marketAddress: venueAddress },
1458
+ amount: depositAmount
1459
+ }
1460
+ }
1461
+ ];
1462
+ const prepareResponse = await fetch("/api/compass/bundle/prepare", {
1463
+ method: "POST",
1464
+ headers: { "Content-Type": "application/json" },
1465
+ body: JSON.stringify({
1466
+ owner: address,
1467
+ chain: chainId,
1468
+ actions: bundleActions
1469
+ })
1470
+ });
1471
+ if (!prepareResponse.ok) {
1472
+ const errorData = await prepareResponse.json();
1473
+ throw new Error(errorData.error || "Failed to prepare bundle");
1474
+ }
1475
+ const { eip712, normalizedTypes, domain, message } = await prepareResponse.json();
1476
+ setStatusMessage("Please sign the transaction...");
1477
+ const signature = await signTypedData({
1478
+ domain,
1479
+ types: normalizedTypes,
1480
+ primaryType: "SafeTx",
1481
+ message
1482
+ });
1483
+ setStatusMessage("Executing swap and deposit...");
1484
+ const executeResponse = await fetch("/api/compass/bundle/execute", {
1485
+ method: "POST",
1486
+ headers: { "Content-Type": "application/json" },
1487
+ body: JSON.stringify({
1488
+ owner: address,
1489
+ eip712,
1490
+ signature,
1491
+ chain: chainId
1492
+ })
1493
+ });
1494
+ if (!executeResponse.ok) {
1495
+ const errorData = await executeResponse.json();
1496
+ throw new Error(errorData.error || "Failed to execute bundle");
1497
+ }
1498
+ const { txHash } = await executeResponse.json();
1499
+ setStatusMessage("Transaction successful!");
1500
+ onSuccess?.(activeTab, amount, txHash);
1501
+ setAmount("");
1502
+ } else {
1503
+ const prepareEndpoint = isDeposit ? "/api/compass/deposit/prepare" : "/api/compass/withdraw/prepare";
1504
+ const executeEndpoint = isDeposit ? "/api/compass/deposit/execute" : "/api/compass/withdraw/execute";
1505
+ const prepareBody = {
1506
+ amount,
1507
+ token: venueToken,
1387
1508
  owner: address,
1388
- eip712,
1389
- signature,
1390
- chain: chainId
1391
- })
1392
- });
1393
- if (!executeResponse.ok) {
1394
- const errorData = await executeResponse.json();
1395
- throw new Error(errorData.error || "Failed to execute transaction");
1509
+ chain: chainId,
1510
+ venueType
1511
+ };
1512
+ if (venueType === "VAULT") {
1513
+ prepareBody.vaultAddress = venueAddress;
1514
+ } else if (venueType === "PENDLE_PT") {
1515
+ prepareBody.marketAddress = venueAddress;
1516
+ prepareBody.maxSlippagePercent = 1;
1517
+ }
1518
+ setStatusMessage("Getting transaction data...");
1519
+ const prepareResponse = await fetch(prepareEndpoint, {
1520
+ method: "POST",
1521
+ headers: { "Content-Type": "application/json" },
1522
+ body: JSON.stringify(prepareBody)
1523
+ });
1524
+ if (!prepareResponse.ok) {
1525
+ const errorData = await prepareResponse.json();
1526
+ throw new Error(errorData.error || "Failed to prepare transaction");
1527
+ }
1528
+ const { eip712, normalizedTypes, domain, message } = await prepareResponse.json();
1529
+ setStatusMessage("Please sign the transaction...");
1530
+ const signature = await signTypedData({
1531
+ domain,
1532
+ types: normalizedTypes,
1533
+ primaryType: "SafeTx",
1534
+ message
1535
+ });
1536
+ setStatusMessage("Executing transaction...");
1537
+ const executeResponse = await fetch(executeEndpoint, {
1538
+ method: "POST",
1539
+ headers: { "Content-Type": "application/json" },
1540
+ body: JSON.stringify({
1541
+ owner: address,
1542
+ eip712,
1543
+ signature,
1544
+ chain: chainId
1545
+ })
1546
+ });
1547
+ if (!executeResponse.ok) {
1548
+ const errorData = await executeResponse.json();
1549
+ throw new Error(errorData.error || "Failed to execute transaction");
1550
+ }
1551
+ const { txHash } = await executeResponse.json();
1552
+ setStatusMessage("Transaction successful!");
1553
+ onSuccess?.(activeTab, amount, txHash);
1554
+ setAmount("");
1396
1555
  }
1397
- const { txHash } = await executeResponse.json();
1398
- setStatusMessage("Transaction successful!");
1399
- onSuccess?.(activeTab, amount, txHash);
1400
- setAmount("");
1401
1556
  queryClient.invalidateQueries({ queryKey: ["earnAccountTokenBalance"] });
1402
1557
  queryClient.invalidateQueries({ queryKey: ["vaults"] });
1403
- queryClient.invalidateQueries({ queryKey: ["vaultPositions"] });
1404
1558
  queryClient.invalidateQueries({ queryKey: ["aaveMarkets"] });
1405
- queryClient.invalidateQueries({ queryKey: ["aavePositions"] });
1406
1559
  queryClient.invalidateQueries({ queryKey: ["pendleMarkets"] });
1407
- queryClient.invalidateQueries({ queryKey: ["pendlePositions"] });
1408
1560
  setTimeout(() => setStatusMessage(""), 3e3);
1409
- setTimeout(() => {
1410
- queryClient.invalidateQueries({ queryKey: ["earnAccountTokenBalance"] });
1411
- queryClient.invalidateQueries({ queryKey: ["vaults"] });
1412
- queryClient.invalidateQueries({ queryKey: ["vaultPositions"] });
1413
- }, 5e3);
1414
1561
  } catch (err) {
1415
1562
  console.error("Transaction failed:", err);
1416
1563
  const errorMessage = err instanceof Error ? err.message : "Transaction failed";
@@ -1423,13 +1570,13 @@ function DepositWithdrawForm({
1423
1570
  address,
1424
1571
  amount,
1425
1572
  chainId,
1426
- targetChainId,
1427
1573
  activeTab,
1574
+ needsSwap,
1575
+ selectedToken,
1576
+ venueToken,
1428
1577
  venueType,
1429
1578
  venueAddress,
1430
- tokenSymbol,
1431
1579
  signTypedData,
1432
- switchChain,
1433
1580
  queryClient,
1434
1581
  onSuccess,
1435
1582
  onError
@@ -1468,6 +1615,7 @@ function DepositWithdrawForm({
1468
1615
  {
1469
1616
  onClick: () => {
1470
1617
  setActiveTab(tab);
1618
+ setSelectedToken(venueToken);
1471
1619
  setError(null);
1472
1620
  setStatusMessage("");
1473
1621
  },
@@ -1482,6 +1630,45 @@ function DepositWithdrawForm({
1482
1630
  ))
1483
1631
  }
1484
1632
  ),
1633
+ activeTab === "deposit" && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1634
+ /* @__PURE__ */ jsxRuntime.jsx(
1635
+ "label",
1636
+ {
1637
+ className: "text-sm font-medium mb-1 block",
1638
+ style: { color: "var(--compass-color-text-secondary)" },
1639
+ children: "From Token"
1640
+ }
1641
+ ),
1642
+ /* @__PURE__ */ jsxRuntime.jsx(
1643
+ TokenSelector,
1644
+ {
1645
+ tokens: depositTokens,
1646
+ selectedToken,
1647
+ onSelect: setSelectedToken,
1648
+ disabled: isSubmitting
1649
+ }
1650
+ )
1651
+ ] }),
1652
+ needsSwap && /* @__PURE__ */ jsxRuntime.jsxs(
1653
+ "div",
1654
+ {
1655
+ className: "flex items-center gap-2 p-2 rounded-lg text-sm",
1656
+ style: {
1657
+ backgroundColor: "var(--compass-color-primary-muted)",
1658
+ color: "var(--compass-color-primary)"
1659
+ },
1660
+ children: [
1661
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { size: 14 }),
1662
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1663
+ "Swaps ",
1664
+ selectedToken,
1665
+ " to ",
1666
+ venueToken,
1667
+ ", then deposits"
1668
+ ] })
1669
+ ]
1670
+ }
1671
+ ),
1485
1672
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1486
1673
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-1", children: [
1487
1674
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1494,9 +1681,9 @@ function DepositWithdrawForm({
1494
1681
  ),
1495
1682
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: [
1496
1683
  "Available: ",
1497
- parseFloat(maxBalance).toFixed(4),
1684
+ formatAmount(maxBalance),
1498
1685
  " ",
1499
- tokenSymbol
1686
+ activeTab === "deposit" ? selectedToken : venueToken
1500
1687
  ] })
1501
1688
  ] }),
1502
1689
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1527,7 +1714,7 @@ function DepositWithdrawForm({
1527
1714
  {
1528
1715
  className: "text-sm font-medium",
1529
1716
  style: { color: "var(--compass-color-text-secondary)" },
1530
- children: tokenSymbol
1717
+ children: activeTab === "deposit" ? selectedToken : venueToken
1531
1718
  }
1532
1719
  )
1533
1720
  ]
@@ -1552,8 +1739,8 @@ function DepositWithdrawForm({
1552
1739
  {
1553
1740
  className: "p-3 rounded-lg text-sm",
1554
1741
  style: {
1555
- backgroundColor: "var(--compass-color-error-muted, rgba(239, 68, 68, 0.1))",
1556
- color: "var(--compass-color-error, #ef4444)"
1742
+ backgroundColor: "var(--compass-color-error-muted)",
1743
+ color: "var(--compass-color-error)"
1557
1744
  },
1558
1745
  children: error
1559
1746
  }
@@ -1563,8 +1750,8 @@ function DepositWithdrawForm({
1563
1750
  {
1564
1751
  className: "p-3 rounded-lg text-sm text-center",
1565
1752
  style: {
1566
- backgroundColor: "var(--compass-color-success-muted, rgba(34, 197, 94, 0.1))",
1567
- color: "var(--compass-color-success, #22c55e)"
1753
+ backgroundColor: "var(--compass-color-success-muted)",
1754
+ color: "var(--compass-color-success)"
1568
1755
  },
1569
1756
  children: statusMessage
1570
1757
  }
@@ -1581,7 +1768,7 @@ function DepositWithdrawForm({
1581
1768
  },
1582
1769
  children: [
1583
1770
  isSubmitting && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 18, className: "animate-spin" }),
1584
- isSubmitting ? "Processing..." : activeTab === "deposit" ? "Deposit" : "Withdraw"
1771
+ isSubmitting ? "Processing..." : needsSwap ? `Swap & ${activeTab === "deposit" ? "Deposit" : "Withdraw"}` : activeTab === "deposit" ? "Deposit" : "Withdraw"
1585
1772
  ]
1586
1773
  }
1587
1774
  )
@@ -1889,6 +2076,434 @@ function EarnAccountGuard({
1889
2076
  }
1890
2077
  );
1891
2078
  }
2079
+ var DEFAULT_TOKENS = ["SBC", "AUSD", "USDC", "USDT", "WETH", "DAI"];
2080
+ var APPROVAL_CACHE_KEY = "compass_approved_tokens";
2081
+ function getApprovalCacheKey(chain, owner) {
2082
+ return `${APPROVAL_CACHE_KEY}_${chain}_${owner}`;
2083
+ }
2084
+ function getCachedApprovals(chain, owner) {
2085
+ try {
2086
+ const key = getApprovalCacheKey(chain, owner);
2087
+ const cached = localStorage.getItem(key);
2088
+ return cached ? new Set(JSON.parse(cached)) : /* @__PURE__ */ new Set();
2089
+ } catch {
2090
+ return /* @__PURE__ */ new Set();
2091
+ }
2092
+ }
2093
+ function cacheApproval(chain, owner, token) {
2094
+ try {
2095
+ const key = getApprovalCacheKey(chain, owner);
2096
+ const approvals = getCachedApprovals(chain, owner);
2097
+ approvals.add(token);
2098
+ localStorage.setItem(key, JSON.stringify([...approvals]));
2099
+ } catch {
2100
+ }
2101
+ }
2102
+ function EarnAccountBalance({
2103
+ tokens = DEFAULT_TOKENS,
2104
+ compact = false,
2105
+ onTransferComplete
2106
+ }) {
2107
+ const [isModalOpen, setIsModalOpen] = react.useState(false);
2108
+ const [activeAction, setActiveAction] = react.useState("deposit");
2109
+ const [selectedToken, setSelectedToken] = react.useState(tokens[0]);
2110
+ const [amount, setAmount] = react.useState("");
2111
+ const [transferState, setTransferState] = react.useState("idle");
2112
+ const [statusMessage, setStatusMessage] = react.useState("");
2113
+ const [error, setError] = react.useState(null);
2114
+ const { address, isConnected, signTypedData } = useEmbeddableWallet();
2115
+ const { chainId } = useChain();
2116
+ const { earnAccountAddress, isDeployed } = useEarnAccount();
2117
+ const queryClient = reactQuery.useQueryClient();
2118
+ const { data: balanceData, isLoading: balancesLoading } = reactQuery.useQuery({
2119
+ queryKey: ["earnAccountBalances", chainId, address, tokens.join(",")],
2120
+ queryFn: async () => {
2121
+ if (!address) return null;
2122
+ const response = await fetch(
2123
+ `/api/compass/earn-account/balances?owner=${address}&chain=${chainId}&tokens=${tokens.join(",")}`
2124
+ );
2125
+ if (!response.ok) {
2126
+ throw new Error("Failed to fetch balances");
2127
+ }
2128
+ return response.json();
2129
+ },
2130
+ enabled: !!address && isDeployed,
2131
+ staleTime: 30 * 1e3
2132
+ });
2133
+ const { data: eoaBalances } = reactQuery.useQuery({
2134
+ queryKey: ["eoaBalances", chainId, address, tokens.join(",")],
2135
+ queryFn: async () => {
2136
+ if (!address) return {};
2137
+ const balances = {};
2138
+ return balances;
2139
+ },
2140
+ enabled: !!address && activeAction === "deposit",
2141
+ staleTime: 30 * 1e3
2142
+ });
2143
+ const earnBalances = balanceData?.balances || {};
2144
+ Object.values(earnBalances).reduce((sum, bal) => {
2145
+ return sum + parseFloat(bal || "0");
2146
+ }, 0);
2147
+ const resetForm = react.useCallback(() => {
2148
+ setAmount("");
2149
+ setTransferState("idle");
2150
+ setStatusMessage("");
2151
+ setError(null);
2152
+ }, []);
2153
+ const handleOpenModal = () => {
2154
+ resetForm();
2155
+ setIsModalOpen(true);
2156
+ };
2157
+ const handleCloseModal = () => {
2158
+ setIsModalOpen(false);
2159
+ resetForm();
2160
+ };
2161
+ const handleActionChange = (action) => {
2162
+ setActiveAction(action);
2163
+ setAmount("");
2164
+ setError(null);
2165
+ };
2166
+ const getMaxBalance = () => {
2167
+ if (activeAction === "deposit") {
2168
+ return eoaBalances?.[selectedToken] || "0";
2169
+ }
2170
+ return earnBalances[selectedToken] || "0";
2171
+ };
2172
+ const handleQuickAmount = (percentage) => {
2173
+ const max = parseFloat(getMaxBalance());
2174
+ if (isNaN(max)) return;
2175
+ setAmount(formatAmount(max * percentage));
2176
+ };
2177
+ const handleTransfer = react.useCallback(async () => {
2178
+ if (!address || !amount || !signTypedData) return;
2179
+ setError(null);
2180
+ try {
2181
+ if (activeAction === "deposit") {
2182
+ const cachedApprovals = getCachedApprovals(chainId, address);
2183
+ if (!cachedApprovals.has(selectedToken)) {
2184
+ setTransferState("checking_approval");
2185
+ setStatusMessage("Checking token approval...");
2186
+ const approveResponse = await fetch("/api/compass/transfer/approve", {
2187
+ method: "POST",
2188
+ headers: { "Content-Type": "application/json" },
2189
+ body: JSON.stringify({
2190
+ owner: address,
2191
+ chain: chainId,
2192
+ token: selectedToken
2193
+ })
2194
+ });
2195
+ if (!approveResponse.ok) {
2196
+ const errData = await approveResponse.json();
2197
+ throw new Error(errData.error || "Failed to check approval");
2198
+ }
2199
+ const approvalData = await approveResponse.json();
2200
+ if (!approvalData.approved) {
2201
+ if (approvalData.requiresTransaction) {
2202
+ throw new Error("This token requires a transaction-based approval. Please approve manually.");
2203
+ }
2204
+ setTransferState("awaiting_approval_signature");
2205
+ setStatusMessage("Please sign the approval...");
2206
+ const approvalSignature = await signTypedData({
2207
+ domain: approvalData.domain,
2208
+ types: approvalData.normalizedTypes,
2209
+ primaryType: "Permit",
2210
+ message: approvalData.message
2211
+ });
2212
+ setTransferState("approving");
2213
+ setStatusMessage("Executing approval...");
2214
+ const executeApprovalResponse = await fetch("/api/compass/transfer/execute", {
2215
+ method: "POST",
2216
+ headers: { "Content-Type": "application/json" },
2217
+ body: JSON.stringify({
2218
+ owner: address,
2219
+ chain: chainId,
2220
+ eip712: approvalData.eip712,
2221
+ signature: approvalSignature
2222
+ })
2223
+ });
2224
+ if (!executeApprovalResponse.ok) {
2225
+ const errData = await executeApprovalResponse.json();
2226
+ throw new Error(errData.error || "Approval failed");
2227
+ }
2228
+ }
2229
+ cacheApproval(chainId, address, selectedToken);
2230
+ }
2231
+ }
2232
+ setTransferState("awaiting_transfer_signature");
2233
+ setStatusMessage("Preparing transfer...");
2234
+ const prepareResponse = await fetch("/api/compass/transfer/prepare", {
2235
+ method: "POST",
2236
+ headers: { "Content-Type": "application/json" },
2237
+ body: JSON.stringify({
2238
+ owner: address,
2239
+ chain: chainId,
2240
+ token: selectedToken,
2241
+ amount,
2242
+ action: activeAction.toUpperCase()
2243
+ })
2244
+ });
2245
+ if (!prepareResponse.ok) {
2246
+ const errData = await prepareResponse.json();
2247
+ throw new Error(errData.error || "Failed to prepare transfer");
2248
+ }
2249
+ const prepareData = await prepareResponse.json();
2250
+ setStatusMessage("Please sign the transfer...");
2251
+ const transferSignature = await signTypedData({
2252
+ domain: prepareData.domain,
2253
+ types: prepareData.normalizedTypes,
2254
+ primaryType: prepareData.primaryType,
2255
+ message: prepareData.message
2256
+ });
2257
+ setTransferState("transferring");
2258
+ setStatusMessage("Executing transfer...");
2259
+ const executeResponse = await fetch("/api/compass/transfer/execute", {
2260
+ method: "POST",
2261
+ headers: { "Content-Type": "application/json" },
2262
+ body: JSON.stringify({
2263
+ owner: address,
2264
+ chain: chainId,
2265
+ eip712: prepareData.eip712,
2266
+ signature: transferSignature
2267
+ })
2268
+ });
2269
+ if (!executeResponse.ok) {
2270
+ const errData = await executeResponse.json();
2271
+ throw new Error(errData.error || "Transfer failed");
2272
+ }
2273
+ const { txHash } = await executeResponse.json();
2274
+ setTransferState("success");
2275
+ setStatusMessage("Transfer successful!");
2276
+ onTransferComplete?.(activeAction, selectedToken, amount, txHash);
2277
+ queryClient.invalidateQueries({ queryKey: ["earnAccountBalances"] });
2278
+ queryClient.invalidateQueries({ queryKey: ["eoaBalances"] });
2279
+ setTimeout(() => {
2280
+ resetForm();
2281
+ }, 2e3);
2282
+ } catch (err) {
2283
+ console.error("Transfer failed:", err);
2284
+ setTransferState("error");
2285
+ setError(err instanceof Error ? err.message : "Transfer failed");
2286
+ }
2287
+ }, [
2288
+ address,
2289
+ amount,
2290
+ activeAction,
2291
+ selectedToken,
2292
+ chainId,
2293
+ signTypedData,
2294
+ queryClient,
2295
+ onTransferComplete,
2296
+ resetForm
2297
+ ]);
2298
+ if (!isConnected) {
2299
+ return null;
2300
+ }
2301
+ const isProcessing = transferState !== "idle" && transferState !== "success" && transferState !== "error";
2302
+ if (!isDeployed) {
2303
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2304
+ "div",
2305
+ {
2306
+ className: `flex items-center gap-2 rounded-lg border ${compact ? "px-2 py-1.5" : "px-3 py-2"}`,
2307
+ style: {
2308
+ backgroundColor: "var(--compass-color-surface)",
2309
+ borderColor: "var(--compass-color-border)"
2310
+ },
2311
+ children: [
2312
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { size: compact ? 14 : 16, style: { color: "var(--compass-color-text-secondary)" } }),
2313
+ /* @__PURE__ */ jsxRuntime.jsx(
2314
+ "span",
2315
+ {
2316
+ className: `${compact ? "text-xs" : "text-sm"}`,
2317
+ style: { color: "var(--compass-color-text-secondary)" },
2318
+ children: "No Earn Account"
2319
+ }
2320
+ )
2321
+ ]
2322
+ }
2323
+ );
2324
+ }
2325
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2326
+ /* @__PURE__ */ jsxRuntime.jsx(
2327
+ "button",
2328
+ {
2329
+ onClick: handleOpenModal,
2330
+ className: `rounded-md font-medium transition-colors ${compact ? "px-2 py-1 text-xs" : "px-3 py-1.5 text-sm"}`,
2331
+ style: {
2332
+ backgroundColor: "var(--compass-color-primary)",
2333
+ color: "var(--compass-color-primary-text)"
2334
+ },
2335
+ children: "Transfer"
2336
+ }
2337
+ ),
2338
+ /* @__PURE__ */ jsxRuntime.jsx(
2339
+ ActionModal,
2340
+ {
2341
+ isOpen: isModalOpen,
2342
+ onClose: handleCloseModal,
2343
+ title: "Transfer Funds",
2344
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
2345
+ /* @__PURE__ */ jsxRuntime.jsx(
2346
+ "div",
2347
+ {
2348
+ className: "flex gap-1 p-1 rounded-lg",
2349
+ style: { backgroundColor: "var(--compass-color-background)" },
2350
+ children: ["deposit", "withdraw"].map((action) => /* @__PURE__ */ jsxRuntime.jsxs(
2351
+ "button",
2352
+ {
2353
+ onClick: () => handleActionChange(action),
2354
+ disabled: isProcessing,
2355
+ className: "flex-1 py-2 rounded-md text-sm font-medium capitalize transition-all flex items-center justify-center gap-2",
2356
+ style: {
2357
+ backgroundColor: activeAction === action ? "var(--compass-color-surface)" : "transparent",
2358
+ color: activeAction === action ? "var(--compass-color-text)" : "var(--compass-color-text-secondary)"
2359
+ },
2360
+ children: [
2361
+ action === "deposit" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDownLeft, { size: 14 }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpRight, { size: 14 }),
2362
+ action
2363
+ ]
2364
+ },
2365
+ action
2366
+ ))
2367
+ }
2368
+ ),
2369
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2370
+ /* @__PURE__ */ jsxRuntime.jsx(
2371
+ "label",
2372
+ {
2373
+ className: "text-sm font-medium mb-1 block",
2374
+ style: { color: "var(--compass-color-text-secondary)" },
2375
+ children: "Token"
2376
+ }
2377
+ ),
2378
+ /* @__PURE__ */ jsxRuntime.jsx(
2379
+ TokenSelector,
2380
+ {
2381
+ tokens,
2382
+ selectedToken,
2383
+ onSelect: setSelectedToken,
2384
+ balances: activeAction === "deposit" ? eoaBalances : earnBalances,
2385
+ disabled: isProcessing
2386
+ }
2387
+ )
2388
+ ] }),
2389
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2390
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-1", children: [
2391
+ /* @__PURE__ */ jsxRuntime.jsx(
2392
+ "label",
2393
+ {
2394
+ className: "text-sm font-medium",
2395
+ style: { color: "var(--compass-color-text-secondary)" },
2396
+ children: "Amount"
2397
+ }
2398
+ ),
2399
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: [
2400
+ "Available: ",
2401
+ formatAmount(getMaxBalance()),
2402
+ " ",
2403
+ selectedToken
2404
+ ] })
2405
+ ] }),
2406
+ /* @__PURE__ */ jsxRuntime.jsxs(
2407
+ "div",
2408
+ {
2409
+ className: "flex items-center gap-2 p-3 rounded-lg border",
2410
+ style: {
2411
+ backgroundColor: "var(--compass-color-background)",
2412
+ borderColor: "var(--compass-color-border)"
2413
+ },
2414
+ children: [
2415
+ /* @__PURE__ */ jsxRuntime.jsx(
2416
+ "input",
2417
+ {
2418
+ type: "number",
2419
+ value: amount,
2420
+ onChange: (e) => {
2421
+ setAmount(e.target.value);
2422
+ setError(null);
2423
+ },
2424
+ placeholder: "0.00",
2425
+ disabled: isProcessing,
2426
+ className: "flex-1 bg-transparent outline-none text-lg font-mono",
2427
+ style: { color: "var(--compass-color-text)" }
2428
+ }
2429
+ ),
2430
+ /* @__PURE__ */ jsxRuntime.jsx(
2431
+ "span",
2432
+ {
2433
+ className: "text-sm font-medium",
2434
+ style: { color: "var(--compass-color-text-secondary)" },
2435
+ children: selectedToken
2436
+ }
2437
+ )
2438
+ ]
2439
+ }
2440
+ )
2441
+ ] }),
2442
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-2", children: [0.25, 0.5, 1].map((pct) => /* @__PURE__ */ jsxRuntime.jsx(
2443
+ "button",
2444
+ {
2445
+ onClick: () => handleQuickAmount(pct),
2446
+ disabled: isProcessing,
2447
+ className: "flex-1 py-1.5 rounded-md text-xs font-medium transition-colors",
2448
+ style: {
2449
+ backgroundColor: "var(--compass-color-secondary)",
2450
+ color: "var(--compass-color-text-secondary)"
2451
+ },
2452
+ children: pct === 1 ? "Max" : `${pct * 100}%`
2453
+ },
2454
+ pct
2455
+ )) }),
2456
+ error && /* @__PURE__ */ jsxRuntime.jsx(
2457
+ "div",
2458
+ {
2459
+ className: "p-3 rounded-lg text-sm",
2460
+ style: {
2461
+ backgroundColor: "var(--compass-color-error-muted)",
2462
+ color: "var(--compass-color-error)"
2463
+ },
2464
+ children: error
2465
+ }
2466
+ ),
2467
+ statusMessage && !error && /* @__PURE__ */ jsxRuntime.jsx(
2468
+ "div",
2469
+ {
2470
+ className: "p-3 rounded-lg text-sm text-center",
2471
+ style: {
2472
+ backgroundColor: transferState === "success" ? "var(--compass-color-success-muted)" : "var(--compass-color-primary-muted)",
2473
+ color: transferState === "success" ? "var(--compass-color-success)" : "var(--compass-color-primary)"
2474
+ },
2475
+ children: statusMessage
2476
+ }
2477
+ ),
2478
+ /* @__PURE__ */ jsxRuntime.jsxs(
2479
+ "button",
2480
+ {
2481
+ onClick: handleTransfer,
2482
+ disabled: isProcessing || !amount || parseFloat(amount) <= 0,
2483
+ className: "w-full py-3 rounded-lg font-medium transition-colors flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed",
2484
+ style: {
2485
+ backgroundColor: "var(--compass-color-primary)",
2486
+ color: "var(--compass-color-primary-text)"
2487
+ },
2488
+ children: [
2489
+ isProcessing && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 18, className: "animate-spin" }),
2490
+ isProcessing ? "Processing..." : activeAction === "deposit" ? "Deposit to Earn Account" : "Withdraw to Wallet"
2491
+ ]
2492
+ }
2493
+ ),
2494
+ /* @__PURE__ */ jsxRuntime.jsx(
2495
+ "p",
2496
+ {
2497
+ className: "text-xs text-center",
2498
+ style: { color: "var(--compass-color-text-tertiary)" },
2499
+ children: "Gas fees are sponsored by Compass"
2500
+ }
2501
+ )
2502
+ ] })
2503
+ }
2504
+ )
2505
+ ] });
2506
+ }
1892
2507
  function formatTVL(tvl) {
1893
2508
  if (!tvl) return "$0";
1894
2509
  const num = parseFloat(tvl);
@@ -2103,15 +2718,6 @@ function useVaultsData(options = {}) {
2103
2718
  }
2104
2719
  };
2105
2720
  }
2106
- var TOKEN_DECIMALS2 = {
2107
- USDC: 6,
2108
- USDT: 6,
2109
- DAI: 18,
2110
- ETH: 18,
2111
- WETH: 18,
2112
- WBTC: 8,
2113
- cbBTC: 8
2114
- };
2115
2721
  function VaultsList({
2116
2722
  showApy = true,
2117
2723
  apyPeriods = ["7d", "30d", "90d"],
@@ -2121,7 +2727,6 @@ function VaultsList({
2121
2727
  showHistory = true,
2122
2728
  showSearch = true,
2123
2729
  showSort = true,
2124
- actionMode = "modal",
2125
2730
  defaultSort = "apy_7d",
2126
2731
  assetFilter,
2127
2732
  minApy,
@@ -2159,7 +2764,10 @@ function VaultsList({
2159
2764
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
2160
2765
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
2161
2766
  /* @__PURE__ */ jsxRuntime.jsx(ChainSwitcher, {}),
2162
- /* @__PURE__ */ jsxRuntime.jsx(WalletStatus, { compact: true })
2767
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2768
+ /* @__PURE__ */ jsxRuntime.jsx(EarnAccountBalance, { compact: true }),
2769
+ /* @__PURE__ */ jsxRuntime.jsx(WalletStatus, { compact: true })
2770
+ ] })
2163
2771
  ] }),
2164
2772
  (showSearch || showSort) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
2165
2773
  showSearch && /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2235,7 +2843,7 @@ function VaultsList({
2235
2843
  },
2236
2844
  vault.vaultAddress
2237
2845
  )) }),
2238
- actionMode === "modal" && selectedVault && /* @__PURE__ */ jsxRuntime.jsx(
2846
+ selectedVault && /* @__PURE__ */ jsxRuntime.jsx(
2239
2847
  ActionModal,
2240
2848
  {
2241
2849
  isOpen: !!selectedVault,
@@ -2263,8 +2871,7 @@ function VaultsList({
2263
2871
  {
2264
2872
  venueType: "VAULT",
2265
2873
  venueAddress: selectedVault.vaultAddress,
2266
- tokenSymbol: selectedVault.assetSymbol,
2267
- tokenDecimals: TOKEN_DECIMALS2[selectedVault.assetSymbol] || 18,
2874
+ venueToken: selectedVault.assetSymbol,
2268
2875
  positionBalance: selectedVault.userPosition?.balance,
2269
2876
  onSuccess: handleActionSuccess
2270
2877
  }
@@ -2364,15 +2971,6 @@ function useAaveData(options = {}) {
2364
2971
  }
2365
2972
  };
2366
2973
  }
2367
- var TOKEN_DECIMALS3 = {
2368
- USDC: 6,
2369
- USDT: 6,
2370
- DAI: 18,
2371
- ETH: 18,
2372
- WETH: 18,
2373
- WBTC: 8,
2374
- cbBTC: 8
2375
- };
2376
2974
  function formatAPY2(apy) {
2377
2975
  if (!apy) return "0.00%";
2378
2976
  const num = parseFloat(apy);
@@ -2396,7 +2994,6 @@ function AaveMarketsList({
2396
2994
  showSearch = true,
2397
2995
  showSort = false,
2398
2996
  // Only one sort option (APY), so hide by default
2399
- actionMode = "modal",
2400
2997
  defaultSort = "supply_apy",
2401
2998
  assetFilter,
2402
2999
  onMarketSelect,
@@ -2429,7 +3026,10 @@ function AaveMarketsList({
2429
3026
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
2430
3027
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
2431
3028
  /* @__PURE__ */ jsxRuntime.jsx(ChainSwitcher, {}),
2432
- /* @__PURE__ */ jsxRuntime.jsx(WalletStatus, { compact: true })
3029
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
3030
+ /* @__PURE__ */ jsxRuntime.jsx(EarnAccountBalance, { compact: true }),
3031
+ /* @__PURE__ */ jsxRuntime.jsx(WalletStatus, { compact: true })
3032
+ ] })
2433
3033
  ] }),
2434
3034
  (showSearch || showSort) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
2435
3035
  showSearch && /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2581,7 +3181,7 @@ function AaveMarketsList({
2581
3181
  market.marketAddress
2582
3182
  );
2583
3183
  }) }),
2584
- actionMode === "modal" && selectedMarket && /* @__PURE__ */ jsxRuntime.jsx(
3184
+ selectedMarket && /* @__PURE__ */ jsxRuntime.jsx(
2585
3185
  ActionModal,
2586
3186
  {
2587
3187
  isOpen: !!selectedMarket,
@@ -2609,8 +3209,7 @@ function AaveMarketsList({
2609
3209
  {
2610
3210
  venueType: "AAVE",
2611
3211
  venueAddress: selectedMarket.marketAddress,
2612
- tokenSymbol: selectedMarket.underlyingSymbol,
2613
- tokenDecimals: TOKEN_DECIMALS3[selectedMarket.underlyingSymbol] || 18,
3212
+ venueToken: selectedMarket.underlyingSymbol,
2614
3213
  positionBalance: selectedMarket.userPosition?.balance,
2615
3214
  onSuccess: handleActionSuccess
2616
3215
  }
@@ -2713,15 +3312,6 @@ function usePendleData(options = {}) {
2713
3312
  }
2714
3313
  };
2715
3314
  }
2716
- var TOKEN_DECIMALS4 = {
2717
- USDC: 6,
2718
- USDT: 6,
2719
- DAI: 18,
2720
- ETH: 18,
2721
- WETH: 18,
2722
- WBTC: 8,
2723
- cbBTC: 8
2724
- };
2725
3315
  function formatAPY3(apy) {
2726
3316
  if (!apy) return "0.00%";
2727
3317
  return `${parseFloat(apy).toFixed(2)}%`;
@@ -2747,7 +3337,6 @@ function PendleMarketsList({
2747
3337
  showHistory = true,
2748
3338
  showSearch = true,
2749
3339
  showSort = true,
2750
- actionMode = "modal",
2751
3340
  defaultSort = "fixed_apy",
2752
3341
  assetFilter,
2753
3342
  onMarketSelect,
@@ -2780,7 +3369,10 @@ function PendleMarketsList({
2780
3369
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
2781
3370
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
2782
3371
  /* @__PURE__ */ jsxRuntime.jsx(ChainSwitcher, {}),
2783
- /* @__PURE__ */ jsxRuntime.jsx(WalletStatus, { compact: true })
3372
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
3373
+ /* @__PURE__ */ jsxRuntime.jsx(EarnAccountBalance, { compact: true }),
3374
+ /* @__PURE__ */ jsxRuntime.jsx(WalletStatus, { compact: true })
3375
+ ] })
2784
3376
  ] }),
2785
3377
  (showSearch || showSort) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
2786
3378
  showSearch && /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2958,7 +3550,7 @@ function PendleMarketsList({
2958
3550
  market.marketAddress
2959
3551
  );
2960
3552
  }) }),
2961
- actionMode === "modal" && selectedMarket && /* @__PURE__ */ jsxRuntime.jsx(
3553
+ selectedMarket && /* @__PURE__ */ jsxRuntime.jsx(
2962
3554
  ActionModal,
2963
3555
  {
2964
3556
  isOpen: !!selectedMarket,
@@ -2986,8 +3578,7 @@ function PendleMarketsList({
2986
3578
  {
2987
3579
  venueType: "PENDLE_PT",
2988
3580
  venueAddress: selectedMarket.marketAddress,
2989
- tokenSymbol: selectedMarket.underlyingSymbol,
2990
- tokenDecimals: TOKEN_DECIMALS4[selectedMarket.underlyingSymbol] || 18,
3581
+ venueToken: selectedMarket.underlyingSymbol,
2991
3582
  positionBalance: selectedMarket.userPosition?.balance,
2992
3583
  onSuccess: handleActionSuccess
2993
3584
  }
@@ -3034,12 +3625,12 @@ function useSwapQuote({ fromToken, toToken, amount, enabled = true }) {
3034
3625
  refetch: query.refetch
3035
3626
  };
3036
3627
  }
3037
- var DEFAULT_TOKENS = ["USDC", "ETH", "WETH", "WBTC", "DAI", "USDT"];
3628
+ var DEFAULT_TOKENS2 = ["USDC", "ETH", "WETH", "WBTC", "DAI", "USDT"];
3038
3629
  function SwapWidget({
3039
3630
  layout = "full",
3040
3631
  defaultFromToken = "ETH",
3041
3632
  defaultToToken = "USDC",
3042
- allowedTokens = DEFAULT_TOKENS,
3633
+ allowedTokens = DEFAULT_TOKENS2,
3043
3634
  showReverseButton = true,
3044
3635
  showSettings = false,
3045
3636
  showPriceImpact = true,
@@ -3295,6 +3886,26 @@ function CompassEarnWidget({
3295
3886
  ] })
3296
3887
  ] });
3297
3888
  }
3889
+ var CHAINS = {
3890
+ ethereum: {
3891
+ id: "ethereum",
3892
+ name: "Ethereum",
3893
+ viemChain: chains.mainnet,
3894
+ icon: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/info/logo.png"
3895
+ },
3896
+ base: {
3897
+ id: "base",
3898
+ name: "Base",
3899
+ viemChain: chains.base,
3900
+ icon: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/base/info/logo.png"
3901
+ },
3902
+ arbitrum: {
3903
+ id: "arbitrum",
3904
+ name: "Arbitrum",
3905
+ viemChain: chains.arbitrum,
3906
+ icon: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/arbitrum/info/logo.png"
3907
+ }
3908
+ };
3298
3909
 
3299
3910
  exports.AaveMarketsList = AaveMarketsList;
3300
3911
  exports.ActionModal = ActionModal;
@@ -3304,11 +3915,11 @@ exports.ChainSwitcher = ChainSwitcher;
3304
3915
  exports.CompassEarnWidget = CompassEarnWidget;
3305
3916
  exports.CompassProvider = CompassProvider;
3306
3917
  exports.DepositWithdrawForm = DepositWithdrawForm;
3918
+ exports.EarnAccountBalance = EarnAccountBalance;
3307
3919
  exports.EarnAccountGuard = EarnAccountGuard;
3308
3920
  exports.PendleMarketsList = PendleMarketsList;
3309
3921
  exports.PnLSummary = PnLSummary;
3310
3922
  exports.SwapWidget = SwapWidget;
3311
- exports.TOKEN_DECIMALS = TOKEN_DECIMALS;
3312
3923
  exports.ThemeProvider = ThemeProvider;
3313
3924
  exports.TransactionHistory = TransactionHistory;
3314
3925
  exports.VaultsList = VaultsList;