@compass-labs/widgets 0.1.12 → 0.1.13

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
@@ -3787,6 +3787,7 @@ function AaveMarketsList({
3787
3787
  ] });
3788
3788
  }
3789
3789
  var CHAIN_ID = "ethereum";
3790
+ var SUPPORTED_TOKENS = ["USDC", "USDT", "DAI", "WETH", "SBC", "AUSD"];
3790
3791
  function formatCurrency(amount) {
3791
3792
  if (!amount) return "$0.00";
3792
3793
  const num = typeof amount === "string" ? parseFloat(amount) : amount;
@@ -3823,16 +3824,19 @@ function EarnAccount({
3823
3824
  const { isDeployed } = useEarnAccount();
3824
3825
  const queryClient = useQueryClient();
3825
3826
  const [activeTab, setActiveTab] = useState("deposit");
3827
+ const [selectedToken, setSelectedToken] = useState("USDC");
3826
3828
  const [amount, setAmount] = useState("");
3827
3829
  const [isProcessing, setIsProcessing] = useState(false);
3828
3830
  const [error, setError] = useState(null);
3829
3831
  const [statusMessage, setStatusMessage] = useState("");
3832
+ const [isTokenDropdownOpen, setIsTokenDropdownOpen] = useState(false);
3830
3833
  const [isFundModalOpen, setIsFundModalOpen] = useState(false);
3831
3834
  const [fundAmount, setFundAmount] = useState("");
3832
3835
  const [fundToken, setFundToken] = useState("USDC");
3833
3836
  const [isFunding, setIsFunding] = useState(false);
3834
3837
  const [fundError, setFundError] = useState(null);
3835
3838
  const [fundStatus, setFundStatus] = useState("");
3839
+ const [isBalancesModalOpen, setIsBalancesModalOpen] = useState(false);
3836
3840
  const FUND_TOKENS = ["USDC", "DAI"];
3837
3841
  const walletBalanceQuery = useQuery({
3838
3842
  queryKey: ["walletBalance", CHAIN_ID, address, fundToken],
@@ -3868,7 +3872,8 @@ function EarnAccount({
3868
3872
  enabled: !!address && isDeployed,
3869
3873
  staleTime: 30 * 1e3
3870
3874
  });
3871
- const availableBalance = balancesQuery.data?.balances?.["USDC"]?.balance || "0";
3875
+ const selectedTokenBalance = balancesQuery.data?.balances?.[selectedToken]?.balance || "0";
3876
+ const earnAccountTotalUsd = balancesQuery.data?.totalUsdValue || "0";
3872
3877
  const marketQuery = useQuery({
3873
3878
  queryKey: ["earnAccountUSDC", CHAIN_ID],
3874
3879
  queryFn: async () => {
@@ -3925,10 +3930,10 @@ function EarnAccount({
3925
3930
  const market = marketQuery.data;
3926
3931
  const userPosition = positionQuery.data;
3927
3932
  const depositedBalance = parseFloat(userPosition?.balance || "0");
3928
- const available = parseFloat(availableBalance);
3929
- const totalBalance = available + depositedBalance;
3930
- const earnings = parseFloat(userPosition?.pnl?.totalPnl || "0");
3931
- const needsSwap = fundToken !== "USDC";
3933
+ const earnAccountTotal = parseFloat(earnAccountTotalUsd);
3934
+ const totalBalance = earnAccountTotal + depositedBalance;
3935
+ const needsActionSwap = selectedToken !== "USDC";
3936
+ const needsFundSwap = fundToken !== "USDC";
3932
3937
  const ensureTokenApproval = async (token) => {
3933
3938
  setFundStatus(`Checking ${token} approval...`);
3934
3939
  const approveResponse = await fetch("/api/compass/transfer/approve", {
@@ -3998,7 +4003,7 @@ function EarnAccount({
3998
4003
  setFundError(null);
3999
4004
  try {
4000
4005
  await ensureTokenApproval(fundToken);
4001
- if (needsSwap) {
4006
+ if (needsFundSwap) {
4002
4007
  setFundStatus(`Preparing ${fundToken} transfer...`);
4003
4008
  const transferPrepareResponse = await fetch("/api/compass/transfer/prepare", {
4004
4009
  method: "POST",
@@ -4143,55 +4148,193 @@ function EarnAccount({
4143
4148
  } finally {
4144
4149
  setIsFunding(false);
4145
4150
  }
4146
- }, [address, fundAmount, fundToken, needsSwap, signTypedData, queryClient, balancesQuery]);
4151
+ }, [address, fundAmount, fundToken, needsFundSwap, signTypedData, queryClient, balancesQuery]);
4147
4152
  const handleAction = async () => {
4148
4153
  if (!market || !amount || parseFloat(amount) <= 0 || !address || !signTypedData) return;
4149
4154
  setIsProcessing(true);
4150
4155
  setError(null);
4151
- setStatusMessage(activeTab === "deposit" ? "Preparing deposit..." : "Preparing withdrawal...");
4156
+ const isDeposit = activeTab === "deposit";
4152
4157
  try {
4153
- const isDeposit = activeTab === "deposit";
4154
- const prepareEndpoint = isDeposit ? "/api/compass/deposit/prepare" : "/api/compass/withdraw/prepare";
4155
- const executeEndpoint = isDeposit ? "/api/compass/deposit/execute" : "/api/compass/withdraw/execute";
4156
- const prepareResponse = await fetch(prepareEndpoint, {
4157
- method: "POST",
4158
- headers: { "Content-Type": "application/json" },
4159
- body: JSON.stringify({
4160
- owner: address,
4161
- chain: CHAIN_ID,
4162
- venueType: "AAVE",
4163
- token: "USDC",
4164
- amount
4165
- })
4166
- });
4167
- if (!prepareResponse.ok) {
4168
- const errData = await prepareResponse.json();
4169
- throw new Error(errData.error || "Failed to prepare transaction");
4170
- }
4171
- const prepareData = await prepareResponse.json();
4172
- setStatusMessage("Please sign the transaction...");
4173
- const signature = await signTypedData({
4174
- domain: prepareData.domain,
4175
- types: prepareData.normalizedTypes,
4176
- primaryType: "SafeTx",
4177
- message: prepareData.message
4178
- });
4179
- setStatusMessage("Executing transaction...");
4180
- const executeResponse = await fetch(executeEndpoint, {
4181
- method: "POST",
4182
- headers: { "Content-Type": "application/json" },
4183
- body: JSON.stringify({
4184
- owner: address,
4185
- chain: CHAIN_ID,
4186
- eip712: prepareData.eip712,
4187
- signature
4188
- })
4189
- });
4190
- if (!executeResponse.ok) {
4191
- const errData = await executeResponse.json();
4192
- throw new Error(errData.error || "Transaction failed");
4158
+ let txHash;
4159
+ if (needsActionSwap) {
4160
+ if (isDeposit) {
4161
+ setStatusMessage(`Getting swap quote...`);
4162
+ const quoteResponse = await fetch(
4163
+ `/api/compass/swap/quote?owner=${address}&chain=${CHAIN_ID}&tokenIn=${selectedToken}&tokenOut=USDC&amountIn=${amount}`
4164
+ );
4165
+ if (!quoteResponse.ok) {
4166
+ const errorData = await quoteResponse.json();
4167
+ throw new Error(errorData.error || "Failed to get swap quote");
4168
+ }
4169
+ const quoteData = await quoteResponse.json();
4170
+ const estimatedOutput = quoteData.estimatedAmountOut;
4171
+ if (!estimatedOutput || parseFloat(estimatedOutput) <= 0) {
4172
+ throw new Error("Invalid swap quote - no output amount");
4173
+ }
4174
+ const depositAmount = (parseFloat(estimatedOutput) * 0.99).toString();
4175
+ setStatusMessage(`Preparing swap and deposit...`);
4176
+ const bundleActions = [
4177
+ {
4178
+ body: {
4179
+ actionType: "V2_SWAP",
4180
+ tokenIn: selectedToken,
4181
+ tokenOut: "USDC",
4182
+ amountIn: amount,
4183
+ maxSlippagePercent: 1
4184
+ }
4185
+ },
4186
+ {
4187
+ body: {
4188
+ actionType: "V2_MANAGE",
4189
+ action: "DEPOSIT",
4190
+ venue: { type: "AAVE", token: "USDC" },
4191
+ amount: depositAmount
4192
+ }
4193
+ }
4194
+ ];
4195
+ const prepareResponse = await fetch("/api/compass/bundle/prepare", {
4196
+ method: "POST",
4197
+ headers: { "Content-Type": "application/json" },
4198
+ body: JSON.stringify({
4199
+ owner: address,
4200
+ chain: CHAIN_ID,
4201
+ actions: bundleActions
4202
+ })
4203
+ });
4204
+ if (!prepareResponse.ok) {
4205
+ const errorData = await prepareResponse.json();
4206
+ throw new Error(errorData.error || "Failed to prepare bundle");
4207
+ }
4208
+ const { eip712, normalizedTypes, domain, message } = await prepareResponse.json();
4209
+ setStatusMessage("Please sign the transaction...");
4210
+ const signature = await signTypedData({
4211
+ domain,
4212
+ types: normalizedTypes,
4213
+ primaryType: "SafeTx",
4214
+ message
4215
+ });
4216
+ setStatusMessage("Executing swap and deposit...");
4217
+ const executeResponse = await fetch("/api/compass/bundle/execute", {
4218
+ method: "POST",
4219
+ headers: { "Content-Type": "application/json" },
4220
+ body: JSON.stringify({
4221
+ owner: address,
4222
+ eip712,
4223
+ signature,
4224
+ chain: CHAIN_ID
4225
+ })
4226
+ });
4227
+ if (!executeResponse.ok) {
4228
+ const errorData = await executeResponse.json();
4229
+ throw new Error(errorData.error || "Failed to execute bundle");
4230
+ }
4231
+ const result = await executeResponse.json();
4232
+ txHash = result.txHash;
4233
+ } else {
4234
+ setStatusMessage(`Preparing withdraw and swap...`);
4235
+ const bundleActions = [
4236
+ {
4237
+ body: {
4238
+ actionType: "V2_MANAGE",
4239
+ action: "WITHDRAW",
4240
+ venue: { type: "AAVE", token: "USDC" },
4241
+ amount
4242
+ }
4243
+ },
4244
+ {
4245
+ body: {
4246
+ actionType: "V2_SWAP",
4247
+ tokenIn: "USDC",
4248
+ tokenOut: selectedToken,
4249
+ amountIn: amount,
4250
+ maxSlippagePercent: 1
4251
+ }
4252
+ }
4253
+ ];
4254
+ const prepareResponse = await fetch("/api/compass/bundle/prepare", {
4255
+ method: "POST",
4256
+ headers: { "Content-Type": "application/json" },
4257
+ body: JSON.stringify({
4258
+ owner: address,
4259
+ chain: CHAIN_ID,
4260
+ actions: bundleActions
4261
+ })
4262
+ });
4263
+ if (!prepareResponse.ok) {
4264
+ const errorData = await prepareResponse.json();
4265
+ throw new Error(errorData.error || "Failed to prepare bundle");
4266
+ }
4267
+ const { eip712, normalizedTypes, domain, message } = await prepareResponse.json();
4268
+ setStatusMessage("Please sign the transaction...");
4269
+ const signature = await signTypedData({
4270
+ domain,
4271
+ types: normalizedTypes,
4272
+ primaryType: "SafeTx",
4273
+ message
4274
+ });
4275
+ setStatusMessage("Executing withdraw and swap...");
4276
+ const executeResponse = await fetch("/api/compass/bundle/execute", {
4277
+ method: "POST",
4278
+ headers: { "Content-Type": "application/json" },
4279
+ body: JSON.stringify({
4280
+ owner: address,
4281
+ eip712,
4282
+ signature,
4283
+ chain: CHAIN_ID
4284
+ })
4285
+ });
4286
+ if (!executeResponse.ok) {
4287
+ const errorData = await executeResponse.json();
4288
+ throw new Error(errorData.error || "Failed to execute bundle");
4289
+ }
4290
+ const result = await executeResponse.json();
4291
+ txHash = result.txHash;
4292
+ }
4293
+ } else {
4294
+ setStatusMessage(isDeposit ? "Preparing deposit..." : "Preparing withdrawal...");
4295
+ const prepareEndpoint = isDeposit ? "/api/compass/deposit/prepare" : "/api/compass/withdraw/prepare";
4296
+ const executeEndpoint = isDeposit ? "/api/compass/deposit/execute" : "/api/compass/withdraw/execute";
4297
+ const prepareResponse = await fetch(prepareEndpoint, {
4298
+ method: "POST",
4299
+ headers: { "Content-Type": "application/json" },
4300
+ body: JSON.stringify({
4301
+ owner: address,
4302
+ chain: CHAIN_ID,
4303
+ venueType: "AAVE",
4304
+ token: "USDC",
4305
+ amount
4306
+ })
4307
+ });
4308
+ if (!prepareResponse.ok) {
4309
+ const errData = await prepareResponse.json();
4310
+ throw new Error(errData.error || "Failed to prepare transaction");
4311
+ }
4312
+ const prepareData = await prepareResponse.json();
4313
+ setStatusMessage("Please sign the transaction...");
4314
+ const signature = await signTypedData({
4315
+ domain: prepareData.domain,
4316
+ types: prepareData.normalizedTypes,
4317
+ primaryType: "SafeTx",
4318
+ message: prepareData.message
4319
+ });
4320
+ setStatusMessage("Executing transaction...");
4321
+ const executeResponse = await fetch(executeEndpoint, {
4322
+ method: "POST",
4323
+ headers: { "Content-Type": "application/json" },
4324
+ body: JSON.stringify({
4325
+ owner: address,
4326
+ chain: CHAIN_ID,
4327
+ eip712: prepareData.eip712,
4328
+ signature
4329
+ })
4330
+ });
4331
+ if (!executeResponse.ok) {
4332
+ const errData = await executeResponse.json();
4333
+ throw new Error(errData.error || "Transaction failed");
4334
+ }
4335
+ const result = await executeResponse.json();
4336
+ txHash = result.txHash;
4193
4337
  }
4194
- const { txHash } = await executeResponse.json();
4195
4338
  setStatusMessage("Transaction successful!");
4196
4339
  setAmount("");
4197
4340
  queryClient.invalidateQueries({ queryKey: ["earnAccountBalances"] });
@@ -4206,7 +4349,7 @@ function EarnAccount({
4206
4349
  borrowApy: null,
4207
4350
  tvlUsd: null
4208
4351
  };
4209
- if (activeTab === "deposit") {
4352
+ if (isDeposit) {
4210
4353
  onSupply?.(marketData, amount, txHash || "");
4211
4354
  } else {
4212
4355
  onWithdraw?.(marketData, amount, txHash || "");
@@ -4219,7 +4362,7 @@ function EarnAccount({
4219
4362
  setIsProcessing(false);
4220
4363
  }
4221
4364
  };
4222
- const maxAmount = activeTab === "deposit" ? available : depositedBalance;
4365
+ const maxAmount = activeTab === "deposit" ? parseFloat(selectedTokenBalance) : depositedBalance;
4223
4366
  if (marketQuery.isLoading) {
4224
4367
  return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx(Loader2, { size: 32, className: "animate-spin", style: { color: "var(--compass-color-primary)" } }) });
4225
4368
  }
@@ -4274,28 +4417,39 @@ function EarnAccount({
4274
4417
  padding: compact ? "var(--compass-spacing-card)" : "calc(var(--compass-spacing-card) * 1.25)"
4275
4418
  },
4276
4419
  children: [
4277
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
4278
- /* @__PURE__ */ jsx(
4279
- "span",
4280
- {
4281
- className: "text-xs font-medium uppercase tracking-wide",
4282
- style: { color: "var(--compass-color-text-tertiary)" },
4283
- children: "Total Balance"
4284
- }
4285
- ),
4286
- /* @__PURE__ */ jsx(
4287
- "span",
4288
- {
4289
- className: "font-bold",
4290
- style: {
4291
- color: "var(--compass-color-text)",
4292
- fontSize: compact ? "2rem" : "2.5rem",
4293
- lineHeight: "1"
4294
- },
4295
- children: formatCurrency(totalBalance)
4296
- }
4297
- )
4298
- ] }),
4420
+ /* @__PURE__ */ jsxs(
4421
+ "button",
4422
+ {
4423
+ onClick: () => setIsBalancesModalOpen(true),
4424
+ className: "flex flex-col text-left w-full transition-opacity hover:opacity-80",
4425
+ style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" },
4426
+ children: [
4427
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
4428
+ /* @__PURE__ */ jsx(
4429
+ "span",
4430
+ {
4431
+ className: "text-xs font-medium uppercase tracking-wide",
4432
+ style: { color: "var(--compass-color-text-tertiary)" },
4433
+ children: "Total Balance"
4434
+ }
4435
+ ),
4436
+ /* @__PURE__ */ jsx(ChevronDown, { size: 12, style: { color: "var(--compass-color-text-tertiary)" } })
4437
+ ] }),
4438
+ /* @__PURE__ */ jsx(
4439
+ "span",
4440
+ {
4441
+ className: "font-bold",
4442
+ style: {
4443
+ color: "var(--compass-color-text)",
4444
+ fontSize: compact ? "2rem" : "2.5rem",
4445
+ lineHeight: "1"
4446
+ },
4447
+ children: formatCurrency(totalBalance)
4448
+ }
4449
+ )
4450
+ ]
4451
+ }
4452
+ ),
4299
4453
  /* @__PURE__ */ jsx(
4300
4454
  "div",
4301
4455
  {
@@ -4352,32 +4506,6 @@ function EarnAccount({
4352
4506
  ]
4353
4507
  }
4354
4508
  ),
4355
- showPnL && earnings > 0 && /* @__PURE__ */ jsxs(
4356
- "div",
4357
- {
4358
- className: "flex items-center justify-between",
4359
- style: {
4360
- backgroundColor: "var(--compass-color-surface)",
4361
- border: "1px solid var(--compass-color-border)",
4362
- borderRadius: "var(--compass-border-radius-lg)",
4363
- padding: spacing
4364
- },
4365
- children: [
4366
- /* @__PURE__ */ jsx("span", { style: { color: "var(--compass-color-text-secondary)" }, children: "Total Earnings" }),
4367
- /* @__PURE__ */ jsxs(
4368
- "span",
4369
- {
4370
- className: "font-semibold",
4371
- style: { color: "var(--compass-color-success)" },
4372
- children: [
4373
- "+",
4374
- formatCurrency(earnings)
4375
- ]
4376
- }
4377
- )
4378
- ]
4379
- }
4380
- ),
4381
4509
  userPosition?.pnl && /* @__PURE__ */ jsx(
4382
4510
  PnLSummary,
4383
4511
  {
@@ -4410,6 +4538,7 @@ function EarnAccount({
4410
4538
  {
4411
4539
  onClick: () => {
4412
4540
  setActiveTab("deposit");
4541
+ setSelectedToken("USDC");
4413
4542
  setError(null);
4414
4543
  },
4415
4544
  className: "flex-1 flex items-center justify-center font-medium transition-all",
@@ -4433,6 +4562,7 @@ function EarnAccount({
4433
4562
  {
4434
4563
  onClick: () => {
4435
4564
  setActiveTab("withdraw");
4565
+ setSelectedToken("USDC");
4436
4566
  setError(null);
4437
4567
  },
4438
4568
  className: "flex-1 flex items-center justify-center font-medium transition-all",
@@ -4458,22 +4588,15 @@ function EarnAccount({
4458
4588
  /* @__PURE__ */ jsxs(
4459
4589
  "div",
4460
4590
  {
4461
- className: "flex items-center",
4591
+ className: "flex items-center flex-wrap",
4462
4592
  style: {
4463
4593
  backgroundColor: "var(--compass-color-surface)",
4464
4594
  border: "1px solid var(--compass-color-border)",
4465
4595
  borderRadius: "var(--compass-border-radius-lg)",
4466
- padding: spacing
4596
+ padding: spacing,
4597
+ gap: "calc(var(--compass-spacing-unit) * 0.5)"
4467
4598
  },
4468
4599
  children: [
4469
- /* @__PURE__ */ jsx(
4470
- "span",
4471
- {
4472
- className: "font-medium",
4473
- style: { color: "var(--compass-color-text-secondary)", fontSize: compact ? "1.25rem" : "1.5rem", marginRight: "calc(var(--compass-spacing-unit) * 0.25)" },
4474
- children: "$"
4475
- }
4476
- ),
4477
4600
  /* @__PURE__ */ jsx(
4478
4601
  "input",
4479
4602
  {
@@ -4486,9 +4609,64 @@ function EarnAccount({
4486
4609
  placeholder: "0.00",
4487
4610
  disabled: isProcessing,
4488
4611
  className: "flex-1 font-medium bg-transparent outline-none",
4489
- style: { color: "var(--compass-color-text)", fontSize: compact ? "1.25rem" : "1.5rem" }
4612
+ style: { color: "var(--compass-color-text)", fontSize: compact ? "1.25rem" : "1.5rem", minWidth: 0 }
4490
4613
  }
4491
4614
  ),
4615
+ /* @__PURE__ */ jsxs("div", { className: "relative", style: { flexShrink: 0 }, children: [
4616
+ /* @__PURE__ */ jsxs(
4617
+ "button",
4618
+ {
4619
+ onClick: () => setIsTokenDropdownOpen(!isTokenDropdownOpen),
4620
+ disabled: isProcessing,
4621
+ className: "flex items-center font-medium",
4622
+ style: {
4623
+ backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-background))",
4624
+ border: "1px solid var(--compass-color-border)",
4625
+ color: "var(--compass-color-text)",
4626
+ borderRadius: "var(--compass-border-radius-md)",
4627
+ padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
4628
+ gap: "calc(var(--compass-spacing-unit) * 0.25)",
4629
+ fontSize: compact ? "0.875rem" : "1rem"
4630
+ },
4631
+ children: [
4632
+ selectedToken,
4633
+ /* @__PURE__ */ jsx(ChevronDown, { size: compact ? 14 : 16, style: { color: "var(--compass-color-text-tertiary)" } })
4634
+ ]
4635
+ }
4636
+ ),
4637
+ isTokenDropdownOpen && /* @__PURE__ */ jsx(
4638
+ "div",
4639
+ {
4640
+ className: "absolute right-0 mt-1 z-10",
4641
+ style: {
4642
+ backgroundColor: "var(--compass-color-surface)",
4643
+ border: "1px solid var(--compass-color-border)",
4644
+ borderRadius: "var(--compass-border-radius-lg)",
4645
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
4646
+ minWidth: "100px"
4647
+ },
4648
+ children: SUPPORTED_TOKENS.map((token) => /* @__PURE__ */ jsx(
4649
+ "button",
4650
+ {
4651
+ onClick: () => {
4652
+ setSelectedToken(token);
4653
+ setIsTokenDropdownOpen(false);
4654
+ setError(null);
4655
+ },
4656
+ className: "w-full text-left font-medium transition-colors",
4657
+ style: {
4658
+ padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
4659
+ color: token === selectedToken ? "var(--compass-color-primary)" : "var(--compass-color-text)",
4660
+ backgroundColor: token === selectedToken ? "var(--compass-color-primary-muted, rgba(99, 102, 241, 0.1))" : "transparent",
4661
+ fontSize: compact ? "0.875rem" : "1rem"
4662
+ },
4663
+ children: token
4664
+ },
4665
+ token
4666
+ ))
4667
+ }
4668
+ )
4669
+ ] }),
4492
4670
  /* @__PURE__ */ jsx(
4493
4671
  "button",
4494
4672
  {
@@ -4500,7 +4678,8 @@ function EarnAccount({
4500
4678
  border: "1px solid var(--compass-color-border)",
4501
4679
  color: "var(--compass-color-text-secondary)",
4502
4680
  borderRadius: "var(--compass-border-radius-md)",
4503
- padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)"
4681
+ padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
4682
+ flexShrink: 0
4504
4683
  },
4505
4684
  children: "MAX"
4506
4685
  }
@@ -4508,9 +4687,30 @@ function EarnAccount({
4508
4687
  ]
4509
4688
  }
4510
4689
  ),
4690
+ needsActionSwap && /* @__PURE__ */ jsxs(
4691
+ "div",
4692
+ {
4693
+ className: "flex items-center text-sm",
4694
+ style: {
4695
+ backgroundColor: "var(--compass-color-primary-muted, rgba(99, 102, 241, 0.1))",
4696
+ color: "var(--compass-color-primary)",
4697
+ borderRadius: "var(--compass-border-radius-lg)",
4698
+ padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
4699
+ gap: "calc(var(--compass-spacing-unit) * 0.5)"
4700
+ },
4701
+ children: [
4702
+ /* @__PURE__ */ jsx(ArrowRight, { size: 14 }),
4703
+ /* @__PURE__ */ jsx("span", { children: activeTab === "deposit" ? `Swaps ${selectedToken} to USDC, then deposits` : `Withdraws USDC, then swaps to ${selectedToken}` })
4704
+ ]
4705
+ }
4706
+ ),
4511
4707
  /* @__PURE__ */ jsxs("div", { className: "flex justify-between", style: { padding: "0 calc(var(--compass-spacing-unit) * 0.25)" }, children: [
4512
- /* @__PURE__ */ jsx("span", { className: "text-sm", style: { color: "var(--compass-color-text-tertiary)" }, children: "Available balance" }),
4513
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", style: { color: "var(--compass-color-text-secondary)" }, children: formatCurrency(maxAmount) })
4708
+ /* @__PURE__ */ jsx("span", { className: "text-sm", style: { color: "var(--compass-color-text-tertiary)" }, children: activeTab === "deposit" ? `Available ${selectedToken}` : "Available to withdraw" }),
4709
+ /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium", style: { color: "var(--compass-color-text-secondary)" }, children: [
4710
+ formatAmount2(maxAmount),
4711
+ " ",
4712
+ activeTab === "deposit" ? selectedToken : "USDC"
4713
+ ] })
4514
4714
  ] })
4515
4715
  ] }),
4516
4716
  error && /* @__PURE__ */ jsx(
@@ -4543,7 +4743,7 @@ function EarnAccount({
4543
4743
  children: isProcessing ? /* @__PURE__ */ jsxs("span", { className: "flex items-center justify-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
4544
4744
  /* @__PURE__ */ jsx(Loader2, { size: compact ? 16 : 20, className: "animate-spin" }),
4545
4745
  "Processing..."
4546
- ] }) : activeTab === "deposit" ? "Deposit funds" : "Withdraw funds"
4746
+ ] }) : needsActionSwap ? activeTab === "deposit" ? `Swap & Deposit` : `Withdraw & Swap` : activeTab === "deposit" ? "Deposit funds" : "Withdraw funds"
4547
4747
  }
4548
4748
  ),
4549
4749
  statusMessage && !error && /* @__PURE__ */ jsx(
@@ -4664,7 +4864,7 @@ function EarnAccount({
4664
4864
  }
4665
4865
  )
4666
4866
  ] }),
4667
- needsSwap && /* @__PURE__ */ jsxs(
4867
+ needsFundSwap && /* @__PURE__ */ jsxs(
4668
4868
  "div",
4669
4869
  {
4670
4870
  className: "flex items-center gap-2 p-3 rounded-xl text-sm",
@@ -4776,7 +4976,7 @@ function EarnAccount({
4776
4976
  "Processing..."
4777
4977
  ] }) : /* @__PURE__ */ jsxs("span", { className: "flex items-center justify-center gap-2", children: [
4778
4978
  /* @__PURE__ */ jsx(ArrowDownLeft, { size: 20 }),
4779
- needsSwap ? `Swap ${fundToken} & Transfer` : "Transfer to Savings"
4979
+ needsFundSwap ? `Swap ${fundToken} & Transfer` : "Transfer to Savings"
4780
4980
  ] })
4781
4981
  }
4782
4982
  ),
@@ -4790,6 +4990,115 @@ function EarnAccount({
4790
4990
  )
4791
4991
  ] })
4792
4992
  }
4993
+ ),
4994
+ /* @__PURE__ */ jsx(
4995
+ ActionModal,
4996
+ {
4997
+ isOpen: isBalancesModalOpen,
4998
+ onClose: () => setIsBalancesModalOpen(false),
4999
+ title: "Balance Breakdown",
5000
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
5001
+ balancesQuery.data?.balances && Object.keys(balancesQuery.data.balances).length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
5002
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
5003
+ /* @__PURE__ */ jsx(
5004
+ "span",
5005
+ {
5006
+ className: "text-xs font-medium uppercase tracking-wide",
5007
+ style: { color: "var(--compass-color-text-tertiary)" },
5008
+ children: "Available in Account"
5009
+ }
5010
+ ),
5011
+ Object.entries(balancesQuery.data.balances).map(([symbol, data]) => /* @__PURE__ */ jsxs(
5012
+ "div",
5013
+ {
5014
+ className: "flex items-center justify-between p-3 rounded-lg",
5015
+ style: {
5016
+ backgroundColor: "var(--compass-color-surface)",
5017
+ border: "1px solid var(--compass-color-border)"
5018
+ },
5019
+ children: [
5020
+ /* @__PURE__ */ jsx("span", { className: "font-medium", style: { color: "var(--compass-color-text)" }, children: symbol }),
5021
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end", children: [
5022
+ /* @__PURE__ */ jsx("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-text)" }, children: formatAmount2(data.balance) }),
5023
+ /* @__PURE__ */ jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: formatCurrency(data.usdValue) })
5024
+ ] })
5025
+ ]
5026
+ },
5027
+ symbol
5028
+ ))
5029
+ ] }),
5030
+ /* @__PURE__ */ jsxs(
5031
+ "div",
5032
+ {
5033
+ className: "flex items-center justify-between pt-2",
5034
+ style: { borderTop: "1px solid var(--compass-color-border)" },
5035
+ children: [
5036
+ /* @__PURE__ */ jsx("span", { className: "text-sm", style: { color: "var(--compass-color-text-secondary)" }, children: "Subtotal" }),
5037
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", style: { color: "var(--compass-color-text)" }, children: formatCurrency(earnAccountTotalUsd) })
5038
+ ]
5039
+ }
5040
+ )
5041
+ ] }) : /* @__PURE__ */ jsx(
5042
+ "div",
5043
+ {
5044
+ className: "text-center py-4",
5045
+ style: { color: "var(--compass-color-text-tertiary)" },
5046
+ children: "No tokens in account"
5047
+ }
5048
+ ),
5049
+ depositedBalance > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 pt-2", style: { borderTop: "1px solid var(--compass-color-border)" }, children: [
5050
+ /* @__PURE__ */ jsx(
5051
+ "span",
5052
+ {
5053
+ className: "text-xs font-medium uppercase tracking-wide",
5054
+ style: { color: "var(--compass-color-text-tertiary)" },
5055
+ children: "Earning Interest (Aave)"
5056
+ }
5057
+ ),
5058
+ /* @__PURE__ */ jsxs(
5059
+ "div",
5060
+ {
5061
+ className: "flex items-center justify-between p-3 rounded-lg",
5062
+ style: {
5063
+ backgroundColor: "var(--compass-color-success-muted, rgba(34, 197, 94, 0.1))",
5064
+ border: "1px solid var(--compass-color-success)"
5065
+ },
5066
+ children: [
5067
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
5068
+ /* @__PURE__ */ jsx(TrendingUp, { size: 16, style: { color: "var(--compass-color-success)" } }),
5069
+ /* @__PURE__ */ jsx("span", { className: "font-medium", style: { color: "var(--compass-color-text)" }, children: "USDC" })
5070
+ ] }),
5071
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end", children: [
5072
+ /* @__PURE__ */ jsx("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-text)" }, children: formatAmount2(depositedBalance) }),
5073
+ /* @__PURE__ */ jsxs("span", { className: "text-xs", style: { color: "var(--compass-color-success)" }, children: [
5074
+ formatAPY3(market?.supplyApy || null),
5075
+ "% APY"
5076
+ ] })
5077
+ ] })
5078
+ ]
5079
+ }
5080
+ )
5081
+ ] }),
5082
+ /* @__PURE__ */ jsxs(
5083
+ "div",
5084
+ {
5085
+ className: "flex items-center justify-between pt-3 mt-2",
5086
+ style: { borderTop: "2px solid var(--compass-color-border)" },
5087
+ children: [
5088
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", style: { color: "var(--compass-color-text)" }, children: "Total Balance" }),
5089
+ /* @__PURE__ */ jsx(
5090
+ "span",
5091
+ {
5092
+ className: "font-bold text-xl",
5093
+ style: { color: "var(--compass-color-text)" },
5094
+ children: formatCurrency(totalBalance)
5095
+ }
5096
+ )
5097
+ ]
5098
+ }
5099
+ )
5100
+ ] })
5101
+ }
4793
5102
  )
4794
5103
  ] });
4795
5104
  }