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