@compass-labs/widgets 0.1.27 → 0.1.28

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
@@ -6757,9 +6757,9 @@ function PortfolioBalanceCard({
6757
6757
  totalIdleUsd,
6758
6758
  idleBalances,
6759
6759
  earnAccountAddress,
6760
- isPositionsExpanded,
6761
- onTogglePositions,
6760
+ onViewPositions,
6762
6761
  positionCount,
6762
+ totalEarned = 0,
6763
6763
  showTopUp = true,
6764
6764
  onTopUp
6765
6765
  }) {
@@ -6857,27 +6857,43 @@ function PortfolioBalanceCard({
6857
6857
  /* @__PURE__ */ jsx(
6858
6858
  "button",
6859
6859
  {
6860
- onClick: onTogglePositions,
6861
- className: "flex items-center justify-between w-full text-left transition-opacity hover:opacity-80",
6860
+ onClick: onViewPositions,
6861
+ disabled: positionCount === 0,
6862
+ className: "flex items-center justify-between w-full text-left transition-opacity hover:opacity-80 disabled:hover:opacity-100 disabled:cursor-default",
6862
6863
  children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", style: { gap: "calc(var(--compass-spacing-unit) * 0.25)" }, children: [
6863
6864
  /* @__PURE__ */ jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
6864
6865
  /* @__PURE__ */ jsxs("span", { className: "text-sm", style: { color: "var(--compass-color-text-tertiary)" }, children: [
6865
6866
  "Earning interest",
6866
- positionCount > 0 ? ` \xB7 ${positionCount} ${positionCount === 1 ? "position" : "positions"}` : ""
6867
+ positionCount > 1 ? ` \xB7 ${positionCount} positions` : ""
6867
6868
  ] }),
6868
- positionCount > 0 && (isPositionsExpanded ? /* @__PURE__ */ jsx(ChevronDown, { size: 14, style: { color: "var(--compass-color-text-tertiary)" } }) : /* @__PURE__ */ jsx(ChevronRight, { size: 14, style: { color: "var(--compass-color-text-tertiary)" } }))
6869
+ positionCount > 0 && /* @__PURE__ */ jsx(ChevronRight, { size: 14, style: { color: "var(--compass-color-text-tertiary)" } })
6869
6870
  ] }),
6870
- /* @__PURE__ */ jsx(
6871
- "span",
6872
- {
6873
- className: "font-semibold",
6874
- style: {
6875
- color: "var(--compass-color-text)",
6876
- fontSize: "1rem"
6877
- },
6878
- children: formatUSD(earningInterestUsd)
6879
- }
6880
- )
6871
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.75)" }, children: [
6872
+ /* @__PURE__ */ jsx(
6873
+ "span",
6874
+ {
6875
+ className: "font-semibold",
6876
+ style: {
6877
+ color: "var(--compass-color-text)",
6878
+ fontSize: "1rem"
6879
+ },
6880
+ children: formatUSD(earningInterestUsd)
6881
+ }
6882
+ ),
6883
+ positionCount > 0 && totalEarned !== 0 && /* @__PURE__ */ jsxs(
6884
+ "span",
6885
+ {
6886
+ className: "text-sm font-medium",
6887
+ style: {
6888
+ color: totalEarned >= 0 ? "var(--compass-color-success)" : "var(--compass-color-error)"
6889
+ },
6890
+ children: [
6891
+ totalEarned >= 0 ? "+" : "",
6892
+ formatUSD(totalEarned)
6893
+ ]
6894
+ }
6895
+ )
6896
+ ] })
6881
6897
  ] })
6882
6898
  }
6883
6899
  )
@@ -7181,7 +7197,8 @@ function RebalancingWidget({
7181
7197
  const [errorMessage, setErrorMessage] = useState(null);
7182
7198
  const [txHash, setTxHash] = useState(null);
7183
7199
  const [hasInitializedTargets, setHasInitializedTargets] = useState(false);
7184
- const [isPositionsExpanded, setIsPositionsExpanded] = useState(false);
7200
+ const [isEarningsModalOpen, setIsEarningsModalOpen] = useState(false);
7201
+ const [isAddMarketExpanded, setIsAddMarketExpanded] = useState(false);
7185
7202
  const [marketTab, setMarketTab] = useState("variable");
7186
7203
  const [selectedMarket, setSelectedMarket] = useState(null);
7187
7204
  const [selectedToken, setSelectedToken] = useState("USDC");
@@ -7199,7 +7216,7 @@ function RebalancingWidget({
7199
7216
  setErrorMessage(null);
7200
7217
  setTxHash(null);
7201
7218
  setHasInitializedTargets(false);
7202
- setIsPositionsExpanded(false);
7219
+ setIsAddMarketExpanded(false);
7203
7220
  setSelectedMarket(null);
7204
7221
  setDepositAmount("");
7205
7222
  setDepositError(null);
@@ -7361,6 +7378,59 @@ function RebalancingWidget({
7361
7378
  await switchChain(targetChainId);
7362
7379
  }
7363
7380
  }, [walletChainId, switchChain, CHAIN_ID]);
7381
+ const rawPositionsQuery = useQuery({
7382
+ queryKey: ["rebalancingRawPositions", CHAIN_ID, address],
7383
+ queryFn: async () => {
7384
+ if (!address) return [];
7385
+ const response = await fetch(`/api/compass/positions?chain=${CHAIN_ID}&owner=${address}`);
7386
+ if (!response.ok) return [];
7387
+ const data = await response.json();
7388
+ return data.positions || [];
7389
+ },
7390
+ enabled: !!address,
7391
+ staleTime: 3e4
7392
+ });
7393
+ const earningsPositions = useMemo(() => {
7394
+ return (rawPositionsQuery.data || []).map((pos, index) => ({
7395
+ id: `pos-${index}`,
7396
+ marketType: pos.protocol,
7397
+ marketName: pos.name,
7398
+ marketId: `${pos.protocol}-${index}`,
7399
+ amount: parseFloat(pos.balance || "0"),
7400
+ token: pos.symbol,
7401
+ apy: pos.apy || 0,
7402
+ performance: parseFloat(pos.pnl?.totalPnl || "0"),
7403
+ pnl: pos.pnl ? {
7404
+ unrealizedPnl: parseFloat(pos.pnl.unrealizedPnl || "0"),
7405
+ realizedPnl: parseFloat(pos.pnl.realizedPnl || "0"),
7406
+ totalPnl: parseFloat(pos.pnl.totalPnl || "0")
7407
+ } : void 0,
7408
+ transactions: [
7409
+ ...(pos.deposits || []).map((d, i) => ({
7410
+ id: `dep-${index}-${i}`,
7411
+ type: "deposit",
7412
+ amount: parseFloat(d.amount || "0"),
7413
+ token: pos.symbol,
7414
+ txHash: d.txHash || "",
7415
+ timestamp: d.timestamp || void 0
7416
+ })),
7417
+ ...(pos.withdrawals || []).map((w, i) => ({
7418
+ id: `wit-${index}-${i}`,
7419
+ type: "withdraw",
7420
+ amount: parseFloat(w.amount || "0"),
7421
+ token: pos.symbol,
7422
+ txHash: w.txHash || "",
7423
+ timestamp: w.timestamp || void 0
7424
+ }))
7425
+ ].sort((a, b) => {
7426
+ if (a.timestamp && b.timestamp) return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
7427
+ if (a.timestamp) return -1;
7428
+ if (b.timestamp) return 1;
7429
+ return 0;
7430
+ })
7431
+ }));
7432
+ }, [rawPositionsQuery.data]);
7433
+ const totalEarned = useMemo(() => earningsPositions.reduce((sum, p) => sum + p.performance, 0), [earningsPositions]);
7364
7434
  const buildVenueParamsFromMarket = (market) => {
7365
7435
  switch (market.type) {
7366
7436
  case "aave":
@@ -7615,14 +7685,14 @@ function RebalancingWidget({
7615
7685
  totalUsd: portfolio.totalUsd,
7616
7686
  totalIdleUsd: portfolio.totalIdleUsd,
7617
7687
  idleBalances: portfolio.idleBalances,
7618
- isPositionsExpanded,
7619
- onTogglePositions: () => setIsPositionsExpanded((prev) => !prev),
7688
+ onViewPositions: () => setIsEarningsModalOpen(true),
7620
7689
  positionCount: portfolio.positions.length,
7690
+ totalEarned,
7621
7691
  showTopUp,
7622
7692
  onTopUp: () => earnBalanceRef.current?.openTransferModal()
7623
7693
  }
7624
7694
  ),
7625
- isPositionsExpanded && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
7695
+ /* @__PURE__ */ jsx(
7626
7696
  AllocationEditor,
7627
7697
  {
7628
7698
  portfolio,
@@ -7635,8 +7705,30 @@ function RebalancingWidget({
7635
7705
  onResetToCurrent: handleResetToCurrent,
7636
7706
  onEqualSplit: handleEqualSplit
7637
7707
  }
7638
- ) }),
7639
- !isPositionsExpanded && /* @__PURE__ */ jsxs(Fragment, { children: [
7708
+ ),
7709
+ /* @__PURE__ */ jsxs(
7710
+ "button",
7711
+ {
7712
+ onClick: () => setIsAddMarketExpanded((prev) => !prev),
7713
+ className: "flex items-center font-medium transition-all hover:opacity-80",
7714
+ style: {
7715
+ backgroundColor: "var(--compass-color-surface)",
7716
+ border: "1px solid var(--compass-color-border)",
7717
+ color: "var(--compass-color-text-secondary)",
7718
+ borderRadius: "var(--compass-border-radius-lg)",
7719
+ padding: "calc(var(--compass-spacing-unit) * 0.75) calc(var(--compass-spacing-unit) * 1)",
7720
+ gap: "calc(var(--compass-spacing-unit) * 0.5)",
7721
+ fontSize: "0.8125rem",
7722
+ width: "100%",
7723
+ justifyContent: "center"
7724
+ },
7725
+ children: [
7726
+ isAddMarketExpanded ? /* @__PURE__ */ jsx(ChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(Plus, { size: 14 }),
7727
+ isAddMarketExpanded ? "Hide" : "Add new market"
7728
+ ]
7729
+ }
7730
+ ),
7731
+ isAddMarketExpanded && /* @__PURE__ */ jsxs(Fragment, { children: [
7640
7732
  /* @__PURE__ */ jsx(
7641
7733
  MarketSelector,
7642
7734
  {
@@ -8056,7 +8148,17 @@ function RebalancingWidget({
8056
8148
  ]
8057
8149
  }
8058
8150
  ) }),
8059
- /* @__PURE__ */ jsx(EarnAccountBalance, { ref: earnBalanceRef, compact: true, hideVisual: true, onTransferComplete: () => refetch() })
8151
+ /* @__PURE__ */ jsx(EarnAccountBalance, { ref: earnBalanceRef, compact: true, hideVisual: true, onTransferComplete: () => refetch() }),
8152
+ /* @__PURE__ */ jsx(
8153
+ EarningsModal,
8154
+ {
8155
+ isOpen: isEarningsModalOpen,
8156
+ onClose: () => setIsEarningsModalOpen(false),
8157
+ positions: earningsPositions,
8158
+ totalEarned,
8159
+ isLoading: rawPositionsQuery.isLoading
8160
+ }
8161
+ )
8060
8162
  ]
8061
8163
  }
8062
8164
  );