@compass-labs/widgets 0.1.35 → 0.1.37

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
@@ -6744,7 +6744,7 @@ function PositionsView({ allowedCollateralTokens, allowedDebtTokens, onBorrow, o
6744
6744
  "span",
6745
6745
  {
6746
6746
  className: "text-lg font-semibold tabular-nums",
6747
- style: { color: debtPositions.length > 0 ? "var(--compass-color-error)" : "var(--compass-color-text)" },
6747
+ style: { color: "var(--compass-color-text)" },
6748
6748
  children: totalDebtUsd
6749
6749
  }
6750
6750
  ),
@@ -7119,11 +7119,11 @@ function DebtPositionCard({
7119
7119
  ] }),
7120
7120
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
7121
7121
  /* @__PURE__ */ jsx("span", { style: { color: "var(--compass-color-text-tertiary)" }, children: "Borrow APY" }),
7122
- /* @__PURE__ */ jsx("span", { style: { color: "var(--compass-color-error)" }, children: formatApy(position.borrowApy) })
7122
+ /* @__PURE__ */ jsx("span", { style: { color: "var(--compass-color-warning, #f59e0b)" }, children: formatApy(position.borrowApy) })
7123
7123
  ] }),
7124
7124
  position.interestPaid !== null && position.interestPaid !== void 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
7125
7125
  /* @__PURE__ */ jsx("span", { style: { color: "var(--compass-color-text-tertiary)" }, children: "Interest paid" }),
7126
- /* @__PURE__ */ jsxs("span", { style: { color: "var(--compass-color-error)" }, children: [
7126
+ /* @__PURE__ */ jsxs("span", { style: { color: "var(--compass-color-text)" }, children: [
7127
7127
  formatNumber(position.interestPaid),
7128
7128
  " ",
7129
7129
  position.symbol
@@ -7285,7 +7285,7 @@ function BorrowModal({ isOpen, onClose, initialToken, allowedTokens }) {
7285
7285
  },
7286
7286
  children: isBusy ? /* @__PURE__ */ jsxs(Fragment, { children: [
7287
7287
  /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
7288
- txState.status === "preparing" ? "Preparing..." : txState.status === "signing" ? "Sign SafeTx..." : "Broadcasting..."
7288
+ txState.status === "preparing" ? "Preparing..." : txState.status === "signing" ? "Signing Borrow..." : "Broadcasting..."
7289
7289
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7290
7290
  /* @__PURE__ */ jsx(TrendingUp, { className: "h-4 w-4" }),
7291
7291
  "Borrow"
@@ -7441,7 +7441,7 @@ function RepayModal({ isOpen, onClose, initialToken, allowedTokens }) {
7441
7441
  },
7442
7442
  children: isBusy ? /* @__PURE__ */ jsxs(Fragment, { children: [
7443
7443
  /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
7444
- txState.status === "preparing" ? "Preparing..." : txState.status === "signing" ? "Sign SafeTx..." : "Broadcasting..."
7444
+ txState.status === "preparing" ? "Preparing..." : txState.status === "signing" ? "Signing Repay..." : "Broadcasting..."
7445
7445
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7446
7446
  /* @__PURE__ */ jsx(ArrowDownLeft, { className: "h-4 w-4" }),
7447
7447
  "Repay"
@@ -7597,7 +7597,7 @@ function SupplyModal({ isOpen, onClose, initialToken, allowedTokens }) {
7597
7597
  },
7598
7598
  children: isBusy ? /* @__PURE__ */ jsxs(Fragment, { children: [
7599
7599
  /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
7600
- txState.status === "preparing" ? "Preparing..." : txState.status === "signing" ? "Sign SafeTx..." : "Broadcasting..."
7600
+ txState.status === "preparing" ? "Preparing..." : txState.status === "signing" ? "Signing Supply..." : "Broadcasting..."
7601
7601
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7602
7602
  /* @__PURE__ */ jsx(ArrowUpCircle, { className: "h-4 w-4" }),
7603
7603
  "Supply"
@@ -7611,12 +7611,20 @@ function WithdrawModal({ isOpen, onClose, initialToken, allowedTokens }) {
7611
7611
  const { address } = useEmbeddableWallet();
7612
7612
  const { isDeployed } = useCreditAccount();
7613
7613
  const { txState, executeBundle, resetState } = useCreditBundle();
7614
+ const { data: positionsData } = useCreditPositions();
7614
7615
  const prices = useTokenPrices();
7615
7616
  const [token, setToken] = useState(initialToken || "USDC");
7616
7617
  const [amount, setAmount] = useState("");
7617
7618
  useEffect(() => {
7618
7619
  if (initialToken) setToken(initialToken);
7619
7620
  }, [initialToken]);
7621
+ const suppliedAmount = (() => {
7622
+ if (!positionsData) return null;
7623
+ const pos = positionsData.collateralPositions.find((p) => p.symbol === token);
7624
+ if (!pos || !pos.amountSupplied) return null;
7625
+ const amt = parseFloat(pos.amountSupplied);
7626
+ return amt > 0 ? amt : null;
7627
+ })();
7620
7628
  const isValid = Number(amount) > 0 && !!address && isDeployed;
7621
7629
  const isBusy = txState.status === "preparing" || txState.status === "signing" || txState.status === "broadcasting";
7622
7630
  useEffect(() => {
@@ -7671,7 +7679,19 @@ function WithdrawModal({ isOpen, onClose, initialToken, allowedTokens }) {
7671
7679
  )
7672
7680
  ] }),
7673
7681
  /* @__PURE__ */ jsxs("div", { children: [
7674
- /* @__PURE__ */ jsx("label", { className: "block text-sm mb-1.5", style: labelStyle, children: "Amount" }),
7682
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [
7683
+ /* @__PURE__ */ jsx("label", { className: "text-sm", style: labelStyle, children: "Amount" }),
7684
+ suppliedAmount !== null && /* @__PURE__ */ jsx(
7685
+ "button",
7686
+ {
7687
+ type: "button",
7688
+ onClick: () => setAmount(suppliedAmount.toFixed(6).replace(/\.?0+$/, "")),
7689
+ className: "text-xs font-medium transition-opacity hover:opacity-80",
7690
+ style: { color: "var(--compass-color-primary)" },
7691
+ children: "MAX"
7692
+ }
7693
+ )
7694
+ ] }),
7675
7695
  /* @__PURE__ */ jsxs("div", { className: "relative", children: [
7676
7696
  /* @__PURE__ */ jsx(
7677
7697
  "input",
@@ -7693,18 +7713,33 @@ function WithdrawModal({ isOpen, onClose, initialToken, allowedTokens }) {
7693
7713
  }
7694
7714
  )
7695
7715
  ] }),
7696
- formatUsdEstimate(amount, token, prices) && /* @__PURE__ */ jsxs(
7697
- "p",
7698
- {
7699
- className: "text-xs mt-1",
7700
- style: { color: "var(--compass-color-text-tertiary)" },
7701
- children: [
7702
- "\u2248",
7703
- " ",
7704
- formatUsdEstimate(amount, token, prices)
7705
- ]
7706
- }
7707
- )
7716
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-1", children: [
7717
+ formatUsdEstimate(amount, token, prices) ? /* @__PURE__ */ jsxs(
7718
+ "span",
7719
+ {
7720
+ className: "text-xs",
7721
+ style: { color: "var(--compass-color-text-tertiary)" },
7722
+ children: [
7723
+ "\u2248",
7724
+ " ",
7725
+ formatUsdEstimate(amount, token, prices)
7726
+ ]
7727
+ }
7728
+ ) : /* @__PURE__ */ jsx("span", {}),
7729
+ suppliedAmount !== null && /* @__PURE__ */ jsxs(
7730
+ "span",
7731
+ {
7732
+ className: "text-xs",
7733
+ style: { color: "var(--compass-color-text-tertiary)" },
7734
+ children: [
7735
+ "Supplied: ",
7736
+ suppliedAmount.toLocaleString(void 0, { maximumFractionDigits: 4 }),
7737
+ " ",
7738
+ token
7739
+ ]
7740
+ }
7741
+ )
7742
+ ] })
7708
7743
  ] })
7709
7744
  ] }),
7710
7745
  /* @__PURE__ */ jsx(
@@ -7722,7 +7757,7 @@ function WithdrawModal({ isOpen, onClose, initialToken, allowedTokens }) {
7722
7757
  },
7723
7758
  children: isBusy ? /* @__PURE__ */ jsxs(Fragment, { children: [
7724
7759
  /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
7725
- txState.status === "preparing" ? "Preparing..." : txState.status === "signing" ? "Sign SafeTx..." : "Broadcasting..."
7760
+ txState.status === "preparing" ? "Preparing..." : txState.status === "signing" ? "Signing Withdraw..." : "Broadcasting..."
7726
7761
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7727
7762
  /* @__PURE__ */ jsx(ArrowDownCircle, { className: "h-4 w-4" }),
7728
7763
  "Withdraw"
@@ -7734,13 +7769,18 @@ function WithdrawModal({ isOpen, onClose, initialToken, allowedTokens }) {
7734
7769
  }
7735
7770
  function getPhase2(step) {
7736
7771
  if (step === "idle" || step === "failed") return 0;
7737
- if (step === "preparing-permit" || step === "signing-permit") return 1;
7772
+ if (step === "approving" || step === "signing-approval") return 1;
7738
7773
  return 2;
7739
7774
  }
7775
+ var EVM_CHAIN_IDS3 = {
7776
+ ethereum: 1,
7777
+ base: 8453,
7778
+ arbitrum: 42161
7779
+ };
7740
7780
  function TopUpModal({ isOpen, onClose }) {
7741
7781
  const { address, signTypedData, switchChain, walletChainId } = useEmbeddableWallet();
7742
- const { chainId, chain } = useChain();
7743
- const { creditAccountAddress, isDeployed } = useCreditAccount();
7782
+ const { chainId } = useChain();
7783
+ const { isDeployed } = useCreditAccount();
7744
7784
  const queryClient = useQueryClient();
7745
7785
  const prices = useTokenPrices();
7746
7786
  const token = "USDC";
@@ -7758,13 +7798,14 @@ function TopUpModal({ isOpen, onClose }) {
7758
7798
  useEffect(() => {
7759
7799
  return () => clearPolling();
7760
7800
  }, [clearPolling]);
7801
+ const CHAIN_ID = chainId;
7761
7802
  const { data: walletBalance } = useQuery({
7762
- queryKey: ["walletTokenBalance", chainId, address, token],
7803
+ queryKey: ["walletTokenBalance", CHAIN_ID, address, token],
7763
7804
  queryFn: async () => {
7764
7805
  if (!address) return "0";
7765
7806
  try {
7766
7807
  const res = await fetch(
7767
- `/api/compass/token/balance?address=${address}&chain=${chainId}&token=${token}`
7808
+ `/api/compass/token/balance?address=${address}&chain=${CHAIN_ID}&token=${token}`
7768
7809
  );
7769
7810
  if (!res.ok) return "0";
7770
7811
  const data = await res.json();
@@ -7790,142 +7831,175 @@ function TopUpModal({ isOpen, onClose }) {
7790
7831
  setTxState({ status: "idle" });
7791
7832
  };
7792
7833
  const isValid = Number(amount) > 0 && !!address && isDeployed;
7793
- const isBusy = step === "preparing-permit" || step === "signing-permit" || step === "preparing-bundle" || step === "signing-bundle" || step === "broadcasting";
7834
+ const isBusy = step === "approving" || step === "signing-approval" || step === "preparing-transfer" || step === "signing-transfer" || step === "executing";
7835
+ const ensureCorrectChain = useCallback(async () => {
7836
+ const targetChainId = EVM_CHAIN_IDS3[CHAIN_ID];
7837
+ if (!targetChainId) return;
7838
+ if (walletChainId !== void 0 && walletChainId !== targetChainId) {
7839
+ if (!switchChain) {
7840
+ throw new Error(`Please switch your wallet to ${CHAIN_ID} (chain ${targetChainId})`);
7841
+ }
7842
+ await switchChain(targetChainId);
7843
+ }
7844
+ }, [walletChainId, switchChain, CHAIN_ID]);
7794
7845
  const handleTransfer = async () => {
7795
- if (!isValid) return;
7846
+ if (!isValid || !signTypedData) return;
7847
+ setTxState({ status: "idle" });
7796
7848
  try {
7797
- if (switchChain && walletChainId !== chain.viemChain.id) {
7798
- await switchChain(chain.viemChain.id);
7799
- }
7849
+ await ensureCorrectChain();
7800
7850
  if (action === "deposit") {
7801
- setStep("preparing-permit");
7851
+ setStep("approving");
7802
7852
  setTxState({ status: "preparing" });
7803
- const transferResponse = await fetch("/api/compass/credit/transfer", {
7853
+ const approveResponse = await fetch("/api/compass/transfer/approve", {
7804
7854
  method: "POST",
7805
7855
  headers: { "Content-Type": "application/json" },
7806
7856
  body: JSON.stringify({
7807
7857
  owner: address,
7808
- chain: chainId,
7809
- token,
7810
- amount: Number(amount)
7858
+ chain: CHAIN_ID,
7859
+ token
7811
7860
  })
7812
7861
  });
7813
- if (!transferResponse.ok) {
7814
- const errorData = await transferResponse.json();
7815
- throw new Error(errorData.error || "Failed to prepare permit");
7862
+ if (!approveResponse.ok) {
7863
+ const errData = await approveResponse.json();
7864
+ throw new Error(errData.error || "Failed to check approval");
7816
7865
  }
7817
- const transferData = await transferResponse.json();
7818
- const permit2Eip712 = transferData.eip712;
7819
- setStep("signing-permit");
7820
- setTxState({ status: "signing" });
7821
- const permit2Signature = await signTypedData({
7822
- domain: permit2Eip712.domain,
7823
- types: {
7824
- PermitTransferFrom: transferData.normalizedTypes.PermitTransferFrom,
7825
- TokenPermissions: transferData.normalizedTypes.TokenPermissions
7826
- },
7827
- primaryType: "PermitTransferFrom",
7828
- message: permit2Eip712.message
7829
- });
7830
- setStep("preparing-bundle");
7866
+ const approvalData = await approveResponse.json();
7867
+ if (!approvalData.approved) {
7868
+ if (approvalData.requiresTransaction && approvalData.transaction) {
7869
+ setTxState({ status: "broadcasting" });
7870
+ const executeApprovalResponse = await fetch("/api/compass/approval/execute", {
7871
+ method: "POST",
7872
+ headers: { "Content-Type": "application/json" },
7873
+ body: JSON.stringify({
7874
+ owner: address,
7875
+ chain: CHAIN_ID,
7876
+ transaction: approvalData.transaction
7877
+ })
7878
+ });
7879
+ if (!executeApprovalResponse.ok) {
7880
+ const errData = await executeApprovalResponse.json();
7881
+ throw new Error(errData.error || "Approval transaction failed");
7882
+ }
7883
+ } else if (approvalData.eip712) {
7884
+ setStep("signing-approval");
7885
+ setTxState({ status: "signing" });
7886
+ const approvalSignature = await signTypedData({
7887
+ domain: approvalData.domain,
7888
+ types: approvalData.normalizedTypes,
7889
+ primaryType: "Permit",
7890
+ message: approvalData.message
7891
+ });
7892
+ setTxState({ status: "broadcasting" });
7893
+ const executeApprovalResponse = await fetch("/api/compass/transfer/execute", {
7894
+ method: "POST",
7895
+ headers: { "Content-Type": "application/json" },
7896
+ body: JSON.stringify({
7897
+ owner: address,
7898
+ chain: CHAIN_ID,
7899
+ eip712: approvalData.eip712,
7900
+ signature: approvalSignature
7901
+ })
7902
+ });
7903
+ if (!executeApprovalResponse.ok) {
7904
+ const errData = await executeApprovalResponse.json();
7905
+ throw new Error(errData.error || "Approval failed");
7906
+ }
7907
+ } else {
7908
+ throw new Error("Unable to approve token for transfers");
7909
+ }
7910
+ }
7911
+ setStep("preparing-transfer");
7831
7912
  setTxState({ status: "preparing" });
7832
- const bundlePrepareResponse = await fetch("/api/compass/credit/bundle/prepare", {
7913
+ const prepareResponse = await fetch("/api/compass/transfer/prepare", {
7833
7914
  method: "POST",
7834
7915
  headers: { "Content-Type": "application/json" },
7835
7916
  body: JSON.stringify({
7836
7917
  owner: address,
7837
- chain: chainId,
7838
- actions: [
7839
- {
7840
- actionType: "V2_TRANSFER_FROM_EOA",
7841
- token,
7842
- amount: Number(amount),
7843
- permit2Signature,
7844
- permit2Nonce: permit2Eip712.message.nonce,
7845
- permit2Deadline: permit2Eip712.message.deadline
7846
- }
7847
- ]
7918
+ chain: CHAIN_ID,
7919
+ token,
7920
+ amount,
7921
+ action: "DEPOSIT",
7922
+ product: "credit"
7848
7923
  })
7849
7924
  });
7850
- if (!bundlePrepareResponse.ok) {
7851
- const errorData = await bundlePrepareResponse.json();
7852
- throw new Error(errorData.error || "Failed to prepare bundle");
7925
+ if (!prepareResponse.ok) {
7926
+ const errData = await prepareResponse.json();
7927
+ throw new Error(errData.error || "Failed to prepare transfer");
7853
7928
  }
7854
- const { eip712, normalizedTypes, domain, message } = await bundlePrepareResponse.json();
7855
- setStep("signing-bundle");
7929
+ const prepareData = await prepareResponse.json();
7930
+ setStep("signing-transfer");
7856
7931
  setTxState({ status: "signing" });
7857
- const safeTxSignature = await signTypedData({
7858
- domain,
7859
- types: normalizedTypes,
7860
- primaryType: "SafeTx",
7861
- message
7932
+ await ensureCorrectChain();
7933
+ const signature = await signTypedData({
7934
+ domain: prepareData.domain,
7935
+ types: prepareData.normalizedTypes,
7936
+ primaryType: prepareData.primaryType,
7937
+ message: prepareData.message
7862
7938
  });
7863
- setStep("broadcasting");
7939
+ setStep("executing");
7864
7940
  setTxState({ status: "broadcasting" });
7865
- const executeResponse = await fetch("/api/compass/credit/bundle/execute", {
7941
+ const executeResponse = await fetch("/api/compass/transfer/execute", {
7866
7942
  method: "POST",
7867
7943
  headers: { "Content-Type": "application/json" },
7868
7944
  body: JSON.stringify({
7869
7945
  owner: address,
7870
- eip712,
7871
- signature: safeTxSignature,
7872
- chain: chainId,
7873
- creditAccountAddress
7946
+ chain: CHAIN_ID,
7947
+ eip712: prepareData.eip712,
7948
+ signature,
7949
+ product: "credit"
7874
7950
  })
7875
7951
  });
7876
7952
  if (!executeResponse.ok) {
7877
- const errorData = await executeResponse.json();
7878
- throw new Error(errorData.error || "Failed to execute");
7953
+ const errData = await executeResponse.json();
7954
+ throw new Error(errData.error || "Transfer failed");
7879
7955
  }
7880
7956
  const { txHash } = await executeResponse.json();
7881
7957
  handleSuccess(txHash);
7882
7958
  } else {
7883
- setStep("preparing-bundle");
7959
+ setStep("preparing-transfer");
7884
7960
  setTxState({ status: "preparing" });
7885
- const bundlePrepareResponse = await fetch("/api/compass/credit/bundle/prepare", {
7961
+ const prepareResponse = await fetch("/api/compass/transfer/prepare", {
7886
7962
  method: "POST",
7887
7963
  headers: { "Content-Type": "application/json" },
7888
7964
  body: JSON.stringify({
7889
7965
  owner: address,
7890
- chain: chainId,
7891
- actions: [
7892
- {
7893
- actionType: "V2_TRANSFER_TO_EOA",
7894
- token,
7895
- amount: Number(amount)
7896
- }
7897
- ]
7966
+ chain: CHAIN_ID,
7967
+ token,
7968
+ amount,
7969
+ action: "WITHDRAW",
7970
+ product: "credit"
7898
7971
  })
7899
7972
  });
7900
- if (!bundlePrepareResponse.ok) {
7901
- const errorData = await bundlePrepareResponse.json();
7902
- throw new Error(errorData.error || "Failed to prepare withdrawal");
7973
+ if (!prepareResponse.ok) {
7974
+ const errData = await prepareResponse.json();
7975
+ throw new Error(errData.error || "Failed to prepare withdrawal");
7903
7976
  }
7904
- const { eip712, normalizedTypes, domain, message } = await bundlePrepareResponse.json();
7905
- setStep("signing-bundle");
7977
+ const prepareData = await prepareResponse.json();
7978
+ setStep("signing-transfer");
7906
7979
  setTxState({ status: "signing" });
7907
- const safeTxSignature = await signTypedData({
7908
- domain,
7909
- types: normalizedTypes,
7910
- primaryType: "SafeTx",
7911
- message
7980
+ await ensureCorrectChain();
7981
+ const signature = await signTypedData({
7982
+ domain: prepareData.domain,
7983
+ types: prepareData.normalizedTypes,
7984
+ primaryType: prepareData.primaryType,
7985
+ message: prepareData.message
7912
7986
  });
7913
- setStep("broadcasting");
7987
+ setStep("executing");
7914
7988
  setTxState({ status: "broadcasting" });
7915
- const executeResponse = await fetch("/api/compass/credit/bundle/execute", {
7989
+ const executeResponse = await fetch("/api/compass/transfer/execute", {
7916
7990
  method: "POST",
7917
7991
  headers: { "Content-Type": "application/json" },
7918
7992
  body: JSON.stringify({
7919
7993
  owner: address,
7920
- eip712,
7921
- signature: safeTxSignature,
7922
- chain: chainId,
7923
- creditAccountAddress
7994
+ chain: CHAIN_ID,
7995
+ eip712: prepareData.eip712,
7996
+ signature,
7997
+ product: "credit"
7924
7998
  })
7925
7999
  });
7926
8000
  if (!executeResponse.ok) {
7927
- const errorData = await executeResponse.json();
7928
- throw new Error(errorData.error || "Failed to execute withdrawal");
8001
+ const errData = await executeResponse.json();
8002
+ throw new Error(errData.error || "Withdrawal failed");
7929
8003
  }
7930
8004
  const { txHash } = await executeResponse.json();
7931
8005
  handleSuccess(txHash);
@@ -7948,8 +8022,9 @@ function TopUpModal({ isOpen, onClose }) {
7948
8022
  polls++;
7949
8023
  queryClient.invalidateQueries({ queryKey: ["creditBalances"] });
7950
8024
  queryClient.invalidateQueries({ queryKey: ["creditPositions"] });
8025
+ queryClient.invalidateQueries({ queryKey: ["walletTokenBalance"] });
7951
8026
  try {
7952
- const res = await fetch(`/api/compass/tx/receipt?hash=${txHash}&chain=${chainId}`);
8027
+ const res = await fetch(`/api/compass/tx/receipt?hash=${txHash}&chain=${CHAIN_ID}`);
7953
8028
  const data = await res.json();
7954
8029
  if (data.status === "success") {
7955
8030
  clearPolling();
@@ -7964,23 +8039,23 @@ function TopUpModal({ isOpen, onClose }) {
7964
8039
  }
7965
8040
  if (polls >= 24) {
7966
8041
  clearPolling();
7967
- setTxState({ status: "confirmed", txHash });
8042
+ setTxState({ status: "failed", error: "Unable to confirm transaction. Please check your wallet for status." });
7968
8043
  }
7969
8044
  }, 5e3);
7970
8045
  };
7971
8046
  const phase = getPhase2(step);
7972
8047
  const buttonLabel = () => {
7973
8048
  switch (step) {
7974
- case "preparing-permit":
7975
- return "Preparing approval...";
7976
- case "signing-permit":
8049
+ case "approving":
8050
+ return "Checking approval...";
8051
+ case "signing-approval":
7977
8052
  return "Sign Approval (1/2)...";
7978
- case "preparing-bundle":
8053
+ case "preparing-transfer":
7979
8054
  return action === "deposit" ? "Preparing transfer..." : "Preparing withdrawal...";
7980
- case "signing-bundle":
8055
+ case "signing-transfer":
7981
8056
  return action === "deposit" ? "Sign Transfer (2/2)..." : "Sign Withdrawal...";
7982
- case "broadcasting":
7983
- return "Broadcasting...";
8057
+ case "executing":
8058
+ return "Executing...";
7984
8059
  default:
7985
8060
  return null;
7986
8061
  }
@@ -8063,7 +8138,10 @@ function TopUpModal({ isOpen, onClose }) {
8063
8138
  {
8064
8139
  type: "number",
8065
8140
  value: amount,
8066
- onChange: (e) => setAmount(e.target.value),
8141
+ onChange: (e) => {
8142
+ setAmount(e.target.value);
8143
+ setTxState({ status: "idle" });
8144
+ },
8067
8145
  disabled: isBusy,
8068
8146
  placeholder: "0.00",
8069
8147
  className: "w-full border px-3 py-2.5 pr-14 text-sm focus:outline-none disabled:opacity-50",
@@ -8105,7 +8183,7 @@ function TopUpModal({ isOpen, onClose }) {
8105
8183
  }
8106
8184
  )
8107
8185
  ] }),
8108
- !isBusy && step !== "confirmed" && step !== "failed" && /* @__PURE__ */ jsx(
8186
+ !isBusy && step !== "confirmed" && step !== "failed" && txState.status === "idle" && /* @__PURE__ */ jsx(
8109
8187
  "p",
8110
8188
  {
8111
8189
  className: "text-xs",
@@ -8394,7 +8472,7 @@ function CreditSwapModal({ isOpen, onClose }) {
8394
8472
  },
8395
8473
  children: isBusy ? /* @__PURE__ */ jsxs(Fragment, { children: [
8396
8474
  /* @__PURE__ */ jsx(Loader2, { size: 16, className: "animate-spin" }),
8397
- txState.status === "preparing" ? "Preparing..." : txState.status === "signing" ? "Sign SafeTx..." : "Broadcasting..."
8475
+ txState.status === "preparing" ? "Preparing..." : txState.status === "signing" ? "Signing Swap..." : "Broadcasting..."
8398
8476
  ] }) : "Swap"
8399
8477
  }
8400
8478
  ),
@@ -8448,8 +8526,28 @@ function CreditAccount({
8448
8526
  const price = tokenPrices[b.tokenSymbol];
8449
8527
  const usdValue = amount > 0 && price != null ? amount * price : 0;
8450
8528
  return { ...b, usdValue };
8451
- }).filter((b) => b.usdValue >= 0.01);
8529
+ }).filter((b) => b.usdValue >= 0.01).sort((a, b) => a.tokenSymbol.localeCompare(b.tokenSymbol));
8452
8530
  const totalIdleUsd = balancesWithUsd.reduce((sum, b) => sum + b.usdValue, 0);
8531
+ const totalInterestEarnedUsd = (() => {
8532
+ if (!positions) return 0;
8533
+ let total = 0;
8534
+ for (const pos of positions.collateralPositions) {
8535
+ const interest = parseFloat(pos.interestEarned ?? "0");
8536
+ const price = tokenPrices[pos.symbol] ?? 0;
8537
+ if (interest > 0 && price > 0) total += interest * price;
8538
+ }
8539
+ return total;
8540
+ })();
8541
+ const totalInterestPaidUsd = (() => {
8542
+ if (!positions) return 0;
8543
+ let total = 0;
8544
+ for (const pos of positions.debtPositions) {
8545
+ const interest = parseFloat(pos.interestPaid ?? "0");
8546
+ const price = tokenPrices[pos.symbol] ?? 0;
8547
+ if (interest > 0 && price > 0) total += interest * price;
8548
+ }
8549
+ return total;
8550
+ })();
8453
8551
  const netPositionUsd = totalCollateral - totalDebt;
8454
8552
  const totalBalance = netPositionUsd + totalIdleUsd;
8455
8553
  const netInterestUsdPerYear = (() => {
@@ -8686,15 +8784,28 @@ function CreditAccount({
8686
8784
  /* @__PURE__ */ jsx(CopyableAddress, { address: creditAccountAddress, label: "Credit Account" })
8687
8785
  ] }),
8688
8786
  positions && positions.collateralPositions.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
8689
- /* @__PURE__ */ jsx(
8690
- "span",
8691
- {
8692
- className: "text-xs font-medium uppercase tracking-wide",
8693
- style: { color: "var(--compass-color-text-tertiary)" },
8694
- children: "Collateral"
8695
- }
8696
- ),
8697
- positions.collateralPositions.filter((p) => parseFloat(p.usdValue ?? "0") >= 0.01).map((p) => /* @__PURE__ */ jsxs(
8787
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
8788
+ /* @__PURE__ */ jsx(
8789
+ "span",
8790
+ {
8791
+ className: "text-xs font-medium uppercase tracking-wide",
8792
+ style: { color: "var(--compass-color-text-tertiary)" },
8793
+ children: "Collateral"
8794
+ }
8795
+ ),
8796
+ totalInterestEarnedUsd > 0 && /* @__PURE__ */ jsxs(
8797
+ "span",
8798
+ {
8799
+ className: "text-xs font-medium",
8800
+ style: { color: "var(--compass-color-success)" },
8801
+ children: [
8802
+ "Interest: +",
8803
+ formatUsd2(totalInterestEarnedUsd)
8804
+ ]
8805
+ }
8806
+ )
8807
+ ] }),
8808
+ [...positions.collateralPositions].filter((p) => parseFloat(p.usdValue ?? "0") >= 0.01).sort((a, b) => a.symbol.localeCompare(b.symbol)).map((p) => /* @__PURE__ */ jsxs(
8698
8809
  "div",
8699
8810
  {
8700
8811
  className: "flex items-center justify-between p-3 rounded-lg",
@@ -8717,15 +8828,28 @@ function CreditAccount({
8717
8828
  ))
8718
8829
  ] }),
8719
8830
  positions && positions.debtPositions.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
8720
- /* @__PURE__ */ jsx(
8721
- "span",
8722
- {
8723
- className: "text-xs font-medium uppercase tracking-wide",
8724
- style: { color: "var(--compass-color-text-tertiary)" },
8725
- children: "Debt"
8726
- }
8727
- ),
8728
- positions.debtPositions.filter((p) => parseFloat(p.usdValue ?? "0") >= 0.01).map((p) => /* @__PURE__ */ jsxs(
8831
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
8832
+ /* @__PURE__ */ jsx(
8833
+ "span",
8834
+ {
8835
+ className: "text-xs font-medium uppercase tracking-wide",
8836
+ style: { color: "var(--compass-color-text-tertiary)" },
8837
+ children: "Debt"
8838
+ }
8839
+ ),
8840
+ totalInterestPaidUsd > 0 && /* @__PURE__ */ jsxs(
8841
+ "span",
8842
+ {
8843
+ className: "text-xs font-medium",
8844
+ style: { color: "var(--compass-color-error, #ef4444)" },
8845
+ children: [
8846
+ "Interest: -",
8847
+ formatUsd2(totalInterestPaidUsd)
8848
+ ]
8849
+ }
8850
+ )
8851
+ ] }),
8852
+ [...positions.debtPositions].filter((p) => parseFloat(p.usdValue ?? "0") >= 0.01).sort((a, b) => a.symbol.localeCompare(b.symbol)).map((p) => /* @__PURE__ */ jsxs(
8729
8853
  "div",
8730
8854
  {
8731
8855
  className: "flex items-center justify-between p-3 rounded-lg",
@@ -8734,19 +8858,13 @@ function CreditAccount({
8734
8858
  border: "1px solid var(--compass-color-border)"
8735
8859
  },
8736
8860
  children: [
8737
- /* @__PURE__ */ jsx("span", { className: "font-medium", style: { color: "var(--compass-color-error, #ef4444)" }, children: p.symbol }),
8861
+ /* @__PURE__ */ jsx("span", { className: "font-medium", style: { color: "var(--compass-color-text)" }, children: p.symbol }),
8738
8862
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end", children: [
8739
- /* @__PURE__ */ jsxs("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-error, #ef4444)" }, children: [
8740
- "-",
8741
- parseFloat(p.amountBorrowed ?? "0").toLocaleString(void 0, {
8742
- minimumFractionDigits: 2,
8743
- maximumFractionDigits: 4
8744
- })
8745
- ] }),
8746
- /* @__PURE__ */ jsxs("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: [
8747
- "-$",
8748
- parseFloat(p.usdValue ?? "0").toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
8749
- ] })
8863
+ /* @__PURE__ */ jsx("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-text)" }, children: parseFloat(p.amountBorrowed ?? "0").toLocaleString(void 0, {
8864
+ minimumFractionDigits: 2,
8865
+ maximumFractionDigits: 4
8866
+ }) }),
8867
+ /* @__PURE__ */ jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: formatUsd2(p.usdValue) })
8750
8868
  ] })
8751
8869
  ]
8752
8870
  },
@@ -8754,14 +8872,24 @@ function CreditAccount({
8754
8872
  ))
8755
8873
  ] }),
8756
8874
  balancesWithUsd.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
8757
- /* @__PURE__ */ jsx(
8758
- "span",
8759
- {
8760
- className: "text-xs font-medium uppercase tracking-wide",
8761
- style: { color: "var(--compass-color-text-tertiary)" },
8762
- children: "Available in Account"
8763
- }
8764
- ),
8875
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
8876
+ /* @__PURE__ */ jsx(
8877
+ "span",
8878
+ {
8879
+ className: "text-xs font-medium uppercase tracking-wide",
8880
+ style: { color: "var(--compass-color-text-tertiary)" },
8881
+ children: "Available in Account"
8882
+ }
8883
+ ),
8884
+ /* @__PURE__ */ jsx(
8885
+ "span",
8886
+ {
8887
+ className: "text-sm font-semibold",
8888
+ style: { color: "var(--compass-color-text)" },
8889
+ children: formatUsd2(totalIdleUsd)
8890
+ }
8891
+ )
8892
+ ] }),
8765
8893
  balancesWithUsd.map((b) => /* @__PURE__ */ jsxs(
8766
8894
  "div",
8767
8895
  {
@@ -10684,7 +10812,7 @@ function AllocationEditor({
10684
10812
  ) })
10685
10813
  ] });
10686
10814
  }
10687
- var EVM_CHAIN_IDS3 = {
10815
+ var EVM_CHAIN_IDS4 = {
10688
10816
  ethereum: 1,
10689
10817
  base: 8453,
10690
10818
  arbitrum: 42161
@@ -10863,7 +10991,7 @@ function RebalancingWidget({
10863
10991
  setTargets((prev) => prev.map((t, i) => i === index ? { ...t, targetPercent: rounded } : t));
10864
10992
  }, []);
10865
10993
  const ensureCorrectChain = useCallback(async () => {
10866
- const targetChainId = EVM_CHAIN_IDS3[CHAIN_ID];
10994
+ const targetChainId = EVM_CHAIN_IDS4[CHAIN_ID];
10867
10995
  if (!targetChainId) return;
10868
10996
  if (walletChainId !== void 0 && walletChainId !== targetChainId) {
10869
10997
  if (!switchChain) {