@compass-labs/widgets 0.1.28 → 0.1.30

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
@@ -6477,7 +6477,7 @@ function useRebalancingData(chainOverride) {
6477
6477
  if (usdValue <= 0) continue;
6478
6478
  balances.push({
6479
6479
  token: symbol,
6480
- balance: parseFloat(td.balance || "0"),
6480
+ balance: parseFloat(td.balanceFormatted || td.balance_formatted || "0"),
6481
6481
  usdValue
6482
6482
  });
6483
6483
  }
@@ -6926,6 +6926,55 @@ var VENUE_LABELS = {
6926
6926
  aave: "Aave",
6927
6927
  pendle_pt: "Pendle PT"
6928
6928
  };
6929
+ function formatPercent(value) {
6930
+ if (value === 0) return "0%";
6931
+ if (Number.isInteger(value)) return `${value}%`;
6932
+ const str = value.toFixed(2).replace(/0+$/, "").replace(/\.$/, "");
6933
+ return `${str}%`;
6934
+ }
6935
+ function PercentInput({ value, onChange }) {
6936
+ const [localValue, setLocalValue] = react.useState(value.toString());
6937
+ const [isFocused, setIsFocused] = react.useState(false);
6938
+ if (!isFocused && localValue !== value.toString()) {
6939
+ const parsed = parseFloat(localValue);
6940
+ if (isNaN(parsed) || Math.abs(parsed - value) > 1e-3) {
6941
+ setLocalValue(value.toString());
6942
+ }
6943
+ }
6944
+ return /* @__PURE__ */ jsxRuntime.jsx(
6945
+ "input",
6946
+ {
6947
+ type: "text",
6948
+ inputMode: "decimal",
6949
+ value: isFocused ? localValue : formatPercent(value).replace("%", ""),
6950
+ onFocus: () => {
6951
+ setIsFocused(true);
6952
+ setLocalValue(value.toString());
6953
+ },
6954
+ onChange: (e) => {
6955
+ const raw = e.target.value;
6956
+ setLocalValue(raw);
6957
+ const parsed = parseFloat(raw);
6958
+ if (!isNaN(parsed)) {
6959
+ onChange(Math.max(0, Math.min(100, parsed)));
6960
+ }
6961
+ },
6962
+ onBlur: () => {
6963
+ setIsFocused(false);
6964
+ const parsed = parseFloat(localValue);
6965
+ if (!isNaN(parsed)) {
6966
+ onChange(Math.max(0, Math.min(100, parsed)));
6967
+ }
6968
+ },
6969
+ className: "w-16 text-center text-xs font-mono rounded bg-transparent outline-none",
6970
+ style: {
6971
+ color: "var(--compass-color-text)",
6972
+ border: "1px solid var(--compass-color-border)",
6973
+ padding: "2px 0"
6974
+ }
6975
+ }
6976
+ );
6977
+ }
6929
6978
  function AllocationEditor({
6930
6979
  portfolio,
6931
6980
  targets,
@@ -7062,20 +7111,10 @@ function AllocationEditor({
7062
7111
  ),
7063
7112
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5 flex-shrink-0", children: [
7064
7113
  /* @__PURE__ */ jsxRuntime.jsx(
7065
- "input",
7114
+ PercentInput,
7066
7115
  {
7067
- type: "number",
7068
- value: target.targetPercent.toFixed(3),
7069
- onChange: (e) => onUpdatePercent(index, parseFloat(e.target.value) || 0),
7070
- className: "w-16 text-center text-xs font-mono rounded bg-transparent outline-none",
7071
- style: {
7072
- color: "var(--compass-color-text)",
7073
- border: "1px solid var(--compass-color-border)",
7074
- padding: "2px 0"
7075
- },
7076
- min: 0,
7077
- max: 100,
7078
- step: 1e-3
7116
+ value: target.targetPercent,
7117
+ onChange: (val) => onUpdatePercent(index, val)
7079
7118
  }
7080
7119
  ),
7081
7120
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)", width: "12px" }, children: "%" })
@@ -7087,10 +7126,9 @@ function AllocationEditor({
7087
7126
  className: "text-xs font-mono",
7088
7127
  style: { color: diff > 0 ? "var(--compass-color-success)" : "var(--compass-color-error)", fontSize: "10px" },
7089
7128
  children: [
7090
- currentPercent.toFixed(3),
7091
- "% \u2192 ",
7092
- target.targetPercent.toFixed(3),
7093
- "%"
7129
+ formatPercent(currentPercent),
7130
+ " \u2192 ",
7131
+ formatPercent(target.targetPercent)
7094
7132
  ]
7095
7133
  }
7096
7134
  ) })
@@ -7132,8 +7170,8 @@ function AllocationEditor({
7132
7170
  color: "var(--compass-color-text-secondary)"
7133
7171
  },
7134
7172
  children: [
7135
- targetSum.toFixed(3),
7136
- "% allocated"
7173
+ formatPercent(targetSum),
7174
+ " allocated"
7137
7175
  ]
7138
7176
  }
7139
7177
  ) })
@@ -7290,11 +7328,22 @@ function RebalancingWidget({
7290
7328
  const handleUpdatePercent = react.useCallback((index, value) => {
7291
7329
  setTargets((prev) => prev.map((t, i) => i === index ? { ...t, targetPercent: Math.max(0, Math.min(100, value)) } : t));
7292
7330
  }, []);
7331
+ const ensureCorrectChain = react.useCallback(async () => {
7332
+ const targetChainId = EVM_CHAIN_IDS2[CHAIN_ID];
7333
+ if (!targetChainId) return;
7334
+ if (walletChainId !== void 0 && walletChainId !== targetChainId) {
7335
+ if (!switchChain) {
7336
+ throw new Error(`Please switch your wallet to ${CHAIN_ID} (chain ${targetChainId})`);
7337
+ }
7338
+ await switchChain(targetChainId);
7339
+ }
7340
+ }, [walletChainId, switchChain, CHAIN_ID]);
7293
7341
  const handlePreview = react.useCallback(async () => {
7294
7342
  if (!portfolio || !hasChanges || !address) return;
7295
7343
  setWidgetState("previewing");
7296
7344
  setErrorMessage(null);
7297
7345
  try {
7346
+ await ensureCorrectChain();
7298
7347
  const response = await fetch("/api/compass/rebalance/preview", {
7299
7348
  method: "POST",
7300
7349
  headers: { "Content-Type": "application/json" },
@@ -7323,7 +7372,7 @@ function RebalancingWidget({
7323
7372
  setWidgetState("error");
7324
7373
  onError?.(err instanceof Error ? err : new Error("Preview failed"));
7325
7374
  }
7326
- }, [portfolio, hasChanges, address, CHAIN_ID, targets, defaultSlippage, clientPreview, onError]);
7375
+ }, [portfolio, hasChanges, address, CHAIN_ID, targets, defaultSlippage, clientPreview, onError, ensureCorrectChain]);
7327
7376
  const handleExecute = react.useCallback(async () => {
7328
7377
  if (!serverPreview?.eip712 || !address) return;
7329
7378
  setWidgetState("signing");
@@ -7370,16 +7419,6 @@ function RebalancingWidget({
7370
7419
  return idleBalance?.balance ?? 0;
7371
7420
  }, [portfolio, selectedToken]);
7372
7421
  const needsSwap = selectedMarket ? selectedToken !== selectedMarket.underlyingToken : false;
7373
- const ensureCorrectChain = react.useCallback(async () => {
7374
- const targetChainId = EVM_CHAIN_IDS2[CHAIN_ID];
7375
- if (!targetChainId) return;
7376
- if (walletChainId !== void 0 && walletChainId !== targetChainId) {
7377
- if (!switchChain) {
7378
- throw new Error(`Please switch your wallet to ${CHAIN_ID} (chain ${targetChainId})`);
7379
- }
7380
- await switchChain(targetChainId);
7381
- }
7382
- }, [walletChainId, switchChain, CHAIN_ID]);
7383
7422
  const rawPositionsQuery = reactQuery.useQuery({
7384
7423
  queryKey: ["rebalancingRawPositions", CHAIN_ID, address],
7385
7424
  queryFn: async () => {
@@ -7483,7 +7522,7 @@ function RebalancingWidget({
7483
7522
  tokenIn: selectedToken,
7484
7523
  tokenOut: underlyingToken,
7485
7524
  amountIn: depositAmount,
7486
- maxSlippagePercent: 1
7525
+ slippage: 1
7487
7526
  }
7488
7527
  },
7489
7528
  {