@compass-labs/widgets 0.1.12 → 0.1.14
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.d.mts +20 -8
- package/dist/index.d.ts +20 -8
- package/dist/index.js +1506 -381
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1507 -382
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -932,7 +932,7 @@ function CompassProvider({
|
|
|
932
932
|
}),
|
|
933
933
|
[]
|
|
934
934
|
);
|
|
935
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsxRuntime.jsx(ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx(ApiProvider, { apiKey, children: /* @__PURE__ */ jsxRuntime.jsx(ChainProvider, { defaultChain, children: /* @__PURE__ */ jsxRuntime.jsx(WalletProvider, { wallet, children: /* @__PURE__ */ jsxRuntime.jsx(EarnAccountProvider, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "compass-widget", children }) }) }) }) }) }) });
|
|
935
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsxRuntime.jsx(ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx(ApiProvider, { apiKey, children: /* @__PURE__ */ jsxRuntime.jsx(ChainProvider, { defaultChain, children: /* @__PURE__ */ jsxRuntime.jsx(WalletProvider, { wallet, children: /* @__PURE__ */ jsxRuntime.jsx(EarnAccountProvider, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "compass-widget", style: { width: "100%", height: "100%" }, children }) }) }) }) }) }) });
|
|
936
936
|
}
|
|
937
937
|
var SUPPORTED_CHAINS = ["ethereum", "base", "arbitrum"];
|
|
938
938
|
function ChainSwitcher() {
|
|
@@ -2341,6 +2341,48 @@ function AccountBalancesModal({
|
|
|
2341
2341
|
children: "No token balances found"
|
|
2342
2342
|
}
|
|
2343
2343
|
) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
2344
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2345
|
+
"div",
|
|
2346
|
+
{
|
|
2347
|
+
className: "flex items-center justify-between border",
|
|
2348
|
+
style: {
|
|
2349
|
+
borderColor: "var(--compass-color-border)",
|
|
2350
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
2351
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
2352
|
+
padding: "calc(var(--compass-spacing-unit) * 1)",
|
|
2353
|
+
marginBottom: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
2354
|
+
},
|
|
2355
|
+
children: [
|
|
2356
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2357
|
+
"span",
|
|
2358
|
+
{
|
|
2359
|
+
className: "font-medium",
|
|
2360
|
+
style: { color: "var(--compass-color-text-secondary)" },
|
|
2361
|
+
children: "Total Balance"
|
|
2362
|
+
}
|
|
2363
|
+
),
|
|
2364
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2365
|
+
"span",
|
|
2366
|
+
{
|
|
2367
|
+
className: "font-bold text-xl",
|
|
2368
|
+
style: { color: "var(--compass-color-text)" },
|
|
2369
|
+
children: formatUSD(totalUsdValue)
|
|
2370
|
+
}
|
|
2371
|
+
)
|
|
2372
|
+
]
|
|
2373
|
+
}
|
|
2374
|
+
),
|
|
2375
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2376
|
+
"div",
|
|
2377
|
+
{
|
|
2378
|
+
className: "text-xs font-medium uppercase tracking-wide",
|
|
2379
|
+
style: {
|
|
2380
|
+
color: "var(--compass-color-text-tertiary)",
|
|
2381
|
+
padding: "calc(var(--compass-spacing-unit) * 0.5) 0"
|
|
2382
|
+
},
|
|
2383
|
+
children: "Token Breakdown"
|
|
2384
|
+
}
|
|
2385
|
+
),
|
|
2344
2386
|
balances.map((token) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2345
2387
|
"div",
|
|
2346
2388
|
{
|
|
@@ -2394,38 +2436,7 @@ function AccountBalancesModal({
|
|
|
2394
2436
|
]
|
|
2395
2437
|
},
|
|
2396
2438
|
token.symbol
|
|
2397
|
-
))
|
|
2398
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2399
|
-
"div",
|
|
2400
|
-
{
|
|
2401
|
-
className: "flex items-center justify-between border",
|
|
2402
|
-
style: {
|
|
2403
|
-
borderColor: "var(--compass-color-border)",
|
|
2404
|
-
backgroundColor: "var(--compass-color-surface)",
|
|
2405
|
-
borderRadius: "var(--compass-border-radius-lg)",
|
|
2406
|
-
padding: "calc(var(--compass-spacing-unit) * 0.75)",
|
|
2407
|
-
marginTop: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
2408
|
-
},
|
|
2409
|
-
children: [
|
|
2410
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2411
|
-
"span",
|
|
2412
|
-
{
|
|
2413
|
-
className: "font-medium",
|
|
2414
|
-
style: { color: "var(--compass-color-text-secondary)" },
|
|
2415
|
-
children: "Total Balance"
|
|
2416
|
-
}
|
|
2417
|
-
),
|
|
2418
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2419
|
-
"span",
|
|
2420
|
-
{
|
|
2421
|
-
className: "font-bold text-lg",
|
|
2422
|
-
style: { color: "var(--compass-color-text)" },
|
|
2423
|
-
children: formatUSD(totalUsdValue)
|
|
2424
|
-
}
|
|
2425
|
-
)
|
|
2426
|
-
]
|
|
2427
|
-
}
|
|
2428
|
-
)
|
|
2439
|
+
))
|
|
2429
2440
|
] }),
|
|
2430
2441
|
earnAccountAddress && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2431
2442
|
"div",
|
|
@@ -3788,202 +3799,949 @@ function AaveMarketsList({
|
|
|
3788
3799
|
)
|
|
3789
3800
|
] });
|
|
3790
3801
|
}
|
|
3791
|
-
var
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
const num = parseFloat(apy);
|
|
3806
|
-
return num.toFixed(2);
|
|
3807
|
-
}
|
|
3808
|
-
function formatAmount2(value) {
|
|
3809
|
-
const num = typeof value === "string" ? parseFloat(value) : value;
|
|
3810
|
-
if (isNaN(num)) return "0";
|
|
3811
|
-
return num.toFixed(6).replace(/\.?0+$/, "");
|
|
3812
|
-
}
|
|
3813
|
-
function EarnAccount({
|
|
3814
|
-
showHeader = true,
|
|
3815
|
-
showInterestRate = true,
|
|
3816
|
-
showPnL = true,
|
|
3817
|
-
showFundButton = true,
|
|
3818
|
-
showTrustBadge = true,
|
|
3819
|
-
compact = false,
|
|
3820
|
-
title = "Savings Account",
|
|
3821
|
-
onSupply,
|
|
3822
|
-
onWithdraw
|
|
3802
|
+
var MARKET_TYPES = [
|
|
3803
|
+
{ value: "aave", label: "AAVE" },
|
|
3804
|
+
{ value: "pendle", label: "PENDLE" },
|
|
3805
|
+
{ value: "vaults", label: "VAULTS" }
|
|
3806
|
+
];
|
|
3807
|
+
function MarketSelector({
|
|
3808
|
+
markets,
|
|
3809
|
+
selectedMarket,
|
|
3810
|
+
onMarketSelect,
|
|
3811
|
+
marketType,
|
|
3812
|
+
onMarketTypeChange,
|
|
3813
|
+
minTvl,
|
|
3814
|
+
onMinTvlChange,
|
|
3815
|
+
isLoading
|
|
3823
3816
|
}) {
|
|
3824
|
-
const
|
|
3825
|
-
const
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
const
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
const
|
|
3833
|
-
const
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3817
|
+
const [isDropdownOpen, setIsDropdownOpen] = react.useState(false);
|
|
3818
|
+
const filteredMarkets = react.useMemo(() => {
|
|
3819
|
+
return markets.filter((m) => m.type === marketType && m.tvl >= minTvl);
|
|
3820
|
+
}, [markets, marketType, minTvl]);
|
|
3821
|
+
const maxTvl = react.useMemo(() => {
|
|
3822
|
+
const typeMarkets = markets.filter((m) => m.type === marketType);
|
|
3823
|
+
return Math.max(...typeMarkets.map((m) => m.tvl), 1e8);
|
|
3824
|
+
}, [markets, marketType]);
|
|
3825
|
+
const hasMarkets = filteredMarkets.length > 0;
|
|
3826
|
+
const formatTvl = (value) => {
|
|
3827
|
+
if (value >= 1e9) return `$${(value / 1e9).toFixed(1)}B`;
|
|
3828
|
+
if (value >= 1e6) return `$${(value / 1e6).toFixed(1)}M`;
|
|
3829
|
+
if (value >= 1e3) return `$${(value / 1e3).toFixed(0)}K`;
|
|
3830
|
+
return `$${value}`;
|
|
3831
|
+
};
|
|
3832
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3833
|
+
"div",
|
|
3834
|
+
{
|
|
3835
|
+
style: {
|
|
3836
|
+
display: "flex",
|
|
3837
|
+
flexDirection: "column",
|
|
3838
|
+
gap: "calc(var(--compass-spacing-unit) * 3)"
|
|
3839
|
+
},
|
|
3840
|
+
children: [
|
|
3841
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3842
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3843
|
+
"label",
|
|
3844
|
+
{
|
|
3845
|
+
style: {
|
|
3846
|
+
display: "block",
|
|
3847
|
+
fontSize: "var(--compass-font-size-sm)",
|
|
3848
|
+
color: "var(--compass-color-text-secondary)",
|
|
3849
|
+
marginBottom: "var(--compass-spacing-unit)"
|
|
3850
|
+
},
|
|
3851
|
+
children: "Market Type"
|
|
3852
|
+
}
|
|
3853
|
+
),
|
|
3854
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3855
|
+
"div",
|
|
3856
|
+
{
|
|
3857
|
+
style: {
|
|
3858
|
+
display: "flex",
|
|
3859
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
3860
|
+
border: "1px solid var(--compass-color-border)",
|
|
3861
|
+
overflow: "hidden"
|
|
3862
|
+
},
|
|
3863
|
+
children: MARKET_TYPES.map((type) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3864
|
+
"button",
|
|
3865
|
+
{
|
|
3866
|
+
onClick: () => onMarketTypeChange(type.value),
|
|
3867
|
+
style: {
|
|
3868
|
+
flex: 1,
|
|
3869
|
+
padding: "calc(var(--compass-spacing-unit) * 2)",
|
|
3870
|
+
backgroundColor: marketType === type.value ? "var(--compass-color-primary)" : "var(--compass-color-surface)",
|
|
3871
|
+
color: marketType === type.value ? "var(--compass-color-primary-foreground)" : "var(--compass-color-text)",
|
|
3872
|
+
border: "none",
|
|
3873
|
+
cursor: "pointer",
|
|
3874
|
+
fontSize: "var(--compass-font-size-sm)",
|
|
3875
|
+
fontWeight: 500,
|
|
3876
|
+
fontFamily: "var(--compass-font-family)",
|
|
3877
|
+
transition: "var(--compass-transition-normal)"
|
|
3878
|
+
},
|
|
3879
|
+
children: type.label
|
|
3880
|
+
},
|
|
3881
|
+
type.value
|
|
3882
|
+
))
|
|
3883
|
+
}
|
|
3884
|
+
)
|
|
3885
|
+
] }),
|
|
3886
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3887
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3888
|
+
"label",
|
|
3889
|
+
{
|
|
3890
|
+
style: {
|
|
3891
|
+
display: "block",
|
|
3892
|
+
fontSize: "var(--compass-font-size-sm)",
|
|
3893
|
+
color: "var(--compass-color-text-secondary)",
|
|
3894
|
+
marginBottom: "var(--compass-spacing-unit)"
|
|
3895
|
+
},
|
|
3896
|
+
children: "Select Market"
|
|
3897
|
+
}
|
|
3898
|
+
),
|
|
3899
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
|
|
3900
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3901
|
+
"button",
|
|
3902
|
+
{
|
|
3903
|
+
onClick: () => hasMarkets && setIsDropdownOpen(!isDropdownOpen),
|
|
3904
|
+
disabled: !hasMarkets || isLoading,
|
|
3905
|
+
style: {
|
|
3906
|
+
width: "100%",
|
|
3907
|
+
padding: "calc(var(--compass-spacing-unit) * 2.5)",
|
|
3908
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
3909
|
+
border: "1px solid var(--compass-color-border)",
|
|
3910
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
3911
|
+
display: "flex",
|
|
3912
|
+
justifyContent: "space-between",
|
|
3913
|
+
alignItems: "center",
|
|
3914
|
+
cursor: hasMarkets ? "pointer" : "not-allowed",
|
|
3915
|
+
opacity: hasMarkets ? 1 : 0.5,
|
|
3916
|
+
fontFamily: "var(--compass-font-family)"
|
|
3917
|
+
},
|
|
3918
|
+
children: [
|
|
3919
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3920
|
+
"span",
|
|
3921
|
+
{
|
|
3922
|
+
style: {
|
|
3923
|
+
color: selectedMarket ? "var(--compass-color-text)" : "var(--compass-color-text-secondary)"
|
|
3924
|
+
},
|
|
3925
|
+
children: isLoading ? "Loading markets..." : !hasMarkets ? `No markets above ${formatTvl(minTvl)}` : selectedMarket ? selectedMarket.name : "Select a market"
|
|
3926
|
+
}
|
|
3927
|
+
),
|
|
3928
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "var(--compass-spacing-unit)" }, children: [
|
|
3929
|
+
selectedMarket && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3930
|
+
"span",
|
|
3931
|
+
{
|
|
3932
|
+
style: {
|
|
3933
|
+
color: "var(--compass-color-success)",
|
|
3934
|
+
fontSize: "var(--compass-font-size-sm)"
|
|
3935
|
+
},
|
|
3936
|
+
children: [
|
|
3937
|
+
selectedMarket.apy.toFixed(2),
|
|
3938
|
+
"%"
|
|
3939
|
+
]
|
|
3940
|
+
}
|
|
3941
|
+
),
|
|
3942
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3943
|
+
lucideReact.ChevronDown,
|
|
3944
|
+
{
|
|
3945
|
+
size: 16,
|
|
3946
|
+
style: {
|
|
3947
|
+
color: "var(--compass-color-text-secondary)",
|
|
3948
|
+
transform: isDropdownOpen ? "rotate(180deg)" : "rotate(0deg)",
|
|
3949
|
+
transition: "var(--compass-transition-normal)"
|
|
3950
|
+
}
|
|
3951
|
+
}
|
|
3952
|
+
)
|
|
3953
|
+
] })
|
|
3954
|
+
]
|
|
3955
|
+
}
|
|
3956
|
+
),
|
|
3957
|
+
isDropdownOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3958
|
+
"div",
|
|
3959
|
+
{
|
|
3960
|
+
style: {
|
|
3961
|
+
position: "absolute",
|
|
3962
|
+
top: "100%",
|
|
3963
|
+
left: 0,
|
|
3964
|
+
right: 0,
|
|
3965
|
+
marginTop: "var(--compass-spacing-unit)",
|
|
3966
|
+
backgroundColor: "var(--compass-color-surface-elevated)",
|
|
3967
|
+
border: "1px solid var(--compass-color-border)",
|
|
3968
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
3969
|
+
boxShadow: "var(--compass-shadow-lg)",
|
|
3970
|
+
zIndex: 50,
|
|
3971
|
+
maxHeight: "200px",
|
|
3972
|
+
overflowY: "auto"
|
|
3973
|
+
},
|
|
3974
|
+
children: filteredMarkets.map((market) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3975
|
+
"button",
|
|
3976
|
+
{
|
|
3977
|
+
onClick: () => {
|
|
3978
|
+
onMarketSelect(market);
|
|
3979
|
+
setIsDropdownOpen(false);
|
|
3980
|
+
},
|
|
3981
|
+
style: {
|
|
3982
|
+
width: "100%",
|
|
3983
|
+
padding: "calc(var(--compass-spacing-unit) * 2)",
|
|
3984
|
+
backgroundColor: selectedMarket?.id === market.id ? "var(--compass-color-primary-muted)" : "transparent",
|
|
3985
|
+
border: "none",
|
|
3986
|
+
borderBottom: "1px solid var(--compass-color-border)",
|
|
3987
|
+
cursor: "pointer",
|
|
3988
|
+
textAlign: "left",
|
|
3989
|
+
fontFamily: "var(--compass-font-family)"
|
|
3990
|
+
},
|
|
3991
|
+
children: [
|
|
3992
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3993
|
+
"div",
|
|
3994
|
+
{
|
|
3995
|
+
style: {
|
|
3996
|
+
display: "flex",
|
|
3997
|
+
justifyContent: "space-between",
|
|
3998
|
+
alignItems: "center"
|
|
3999
|
+
},
|
|
4000
|
+
children: [
|
|
4001
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--compass-color-text)" }, children: market.name }),
|
|
4002
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4003
|
+
"span",
|
|
4004
|
+
{
|
|
4005
|
+
style: {
|
|
4006
|
+
color: "var(--compass-color-success)",
|
|
4007
|
+
fontSize: "var(--compass-font-size-sm)"
|
|
4008
|
+
},
|
|
4009
|
+
children: [
|
|
4010
|
+
market.apy.toFixed(2),
|
|
4011
|
+
"% APY"
|
|
4012
|
+
]
|
|
4013
|
+
}
|
|
4014
|
+
)
|
|
4015
|
+
]
|
|
4016
|
+
}
|
|
4017
|
+
),
|
|
4018
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4019
|
+
"div",
|
|
4020
|
+
{
|
|
4021
|
+
style: {
|
|
4022
|
+
fontSize: "var(--compass-font-size-xs)",
|
|
4023
|
+
color: "var(--compass-color-text-tertiary)",
|
|
4024
|
+
marginTop: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
4025
|
+
},
|
|
4026
|
+
children: [
|
|
4027
|
+
"TVL: ",
|
|
4028
|
+
formatTvl(market.tvl),
|
|
4029
|
+
market.expiry && ` \xB7 Expires: ${market.expiry}`
|
|
4030
|
+
]
|
|
4031
|
+
}
|
|
4032
|
+
)
|
|
4033
|
+
]
|
|
4034
|
+
},
|
|
4035
|
+
market.id
|
|
4036
|
+
))
|
|
4037
|
+
}
|
|
4038
|
+
)
|
|
4039
|
+
] })
|
|
4040
|
+
] }),
|
|
4041
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4042
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4043
|
+
"div",
|
|
4044
|
+
{
|
|
4045
|
+
style: {
|
|
4046
|
+
display: "flex",
|
|
4047
|
+
justifyContent: "space-between",
|
|
4048
|
+
alignItems: "center",
|
|
4049
|
+
marginBottom: "var(--compass-spacing-unit)"
|
|
4050
|
+
},
|
|
4051
|
+
children: [
|
|
4052
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4053
|
+
"label",
|
|
4054
|
+
{
|
|
4055
|
+
style: {
|
|
4056
|
+
fontSize: "var(--compass-font-size-sm)",
|
|
4057
|
+
color: "var(--compass-color-text-secondary)"
|
|
4058
|
+
},
|
|
4059
|
+
children: "Min TVL"
|
|
4060
|
+
}
|
|
4061
|
+
),
|
|
4062
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4063
|
+
"span",
|
|
4064
|
+
{
|
|
4065
|
+
style: {
|
|
4066
|
+
fontSize: "var(--compass-font-size-sm)",
|
|
4067
|
+
color: "var(--compass-color-text)"
|
|
4068
|
+
},
|
|
4069
|
+
children: formatTvl(minTvl)
|
|
4070
|
+
}
|
|
4071
|
+
)
|
|
4072
|
+
]
|
|
4073
|
+
}
|
|
4074
|
+
),
|
|
4075
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4076
|
+
"input",
|
|
4077
|
+
{
|
|
4078
|
+
type: "range",
|
|
4079
|
+
min: 0,
|
|
4080
|
+
max: maxTvl,
|
|
4081
|
+
step: 1e5,
|
|
4082
|
+
value: minTvl,
|
|
4083
|
+
onChange: (e) => onMinTvlChange(Number(e.target.value)),
|
|
4084
|
+
style: {
|
|
4085
|
+
width: "100%",
|
|
4086
|
+
accentColor: "var(--compass-color-primary)"
|
|
4087
|
+
}
|
|
4088
|
+
}
|
|
4089
|
+
)
|
|
4090
|
+
] })
|
|
4091
|
+
]
|
|
4092
|
+
}
|
|
4093
|
+
);
|
|
4094
|
+
}
|
|
4095
|
+
function PositionCard({ position }) {
|
|
4096
|
+
const [isHistoryExpanded, setIsHistoryExpanded] = react.useState(false);
|
|
4097
|
+
const formatDate2 = (dateStr) => {
|
|
4098
|
+
const date = new Date(dateStr);
|
|
4099
|
+
return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
|
|
4100
|
+
};
|
|
4101
|
+
const formatShortDate = (dateStr) => {
|
|
4102
|
+
const date = new Date(dateStr);
|
|
4103
|
+
return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
4104
|
+
};
|
|
4105
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4106
|
+
"div",
|
|
4107
|
+
{
|
|
4108
|
+
style: {
|
|
4109
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
4110
|
+
border: "1px solid var(--compass-color-border)",
|
|
4111
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
4112
|
+
padding: "var(--compass-spacing-card)"
|
|
4113
|
+
},
|
|
4114
|
+
children: [
|
|
4115
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4116
|
+
"div",
|
|
4117
|
+
{
|
|
4118
|
+
style: {
|
|
4119
|
+
display: "flex",
|
|
4120
|
+
justifyContent: "space-between",
|
|
4121
|
+
alignItems: "flex-start",
|
|
4122
|
+
marginBottom: "calc(var(--compass-spacing-unit) * 2)"
|
|
4123
|
+
},
|
|
4124
|
+
children: [
|
|
4125
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4126
|
+
"span",
|
|
4127
|
+
{
|
|
4128
|
+
style: {
|
|
4129
|
+
fontWeight: 600,
|
|
4130
|
+
color: "var(--compass-color-text)",
|
|
4131
|
+
fontSize: "var(--compass-font-size-base)"
|
|
4132
|
+
},
|
|
4133
|
+
children: position.marketName
|
|
4134
|
+
}
|
|
4135
|
+
),
|
|
4136
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4137
|
+
"span",
|
|
4138
|
+
{
|
|
4139
|
+
style: {
|
|
4140
|
+
color: "var(--compass-color-success)",
|
|
4141
|
+
fontSize: "var(--compass-font-size-sm)",
|
|
4142
|
+
backgroundColor: "var(--compass-color-success-muted)",
|
|
4143
|
+
padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 1.5)",
|
|
4144
|
+
borderRadius: "var(--compass-border-radius-full)"
|
|
4145
|
+
},
|
|
4146
|
+
children: [
|
|
4147
|
+
"APY: ",
|
|
4148
|
+
position.apy.toFixed(2),
|
|
4149
|
+
"%"
|
|
4150
|
+
]
|
|
4151
|
+
}
|
|
4152
|
+
)
|
|
4153
|
+
]
|
|
4154
|
+
}
|
|
4155
|
+
),
|
|
4156
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4157
|
+
"div",
|
|
4158
|
+
{
|
|
4159
|
+
style: {
|
|
4160
|
+
display: "grid",
|
|
4161
|
+
gridTemplateColumns: "1fr 1fr",
|
|
4162
|
+
gap: "calc(var(--compass-spacing-unit) * 2)",
|
|
4163
|
+
marginBottom: "calc(var(--compass-spacing-unit) * 2)"
|
|
4164
|
+
},
|
|
4165
|
+
children: [
|
|
4166
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4167
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4168
|
+
"div",
|
|
4169
|
+
{
|
|
4170
|
+
style: {
|
|
4171
|
+
fontSize: "var(--compass-font-size-xs)",
|
|
4172
|
+
color: "var(--compass-color-text-tertiary)",
|
|
4173
|
+
marginBottom: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
4174
|
+
},
|
|
4175
|
+
children: "Amount"
|
|
4176
|
+
}
|
|
4177
|
+
),
|
|
4178
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { color: "var(--compass-color-text)", fontWeight: 500 }, children: [
|
|
4179
|
+
position.amount.toLocaleString(),
|
|
4180
|
+
" ",
|
|
4181
|
+
position.token
|
|
4182
|
+
] })
|
|
4183
|
+
] }),
|
|
4184
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4185
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4186
|
+
"div",
|
|
4187
|
+
{
|
|
4188
|
+
style: {
|
|
4189
|
+
fontSize: "var(--compass-font-size-xs)",
|
|
4190
|
+
color: "var(--compass-color-text-tertiary)",
|
|
4191
|
+
marginBottom: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
4192
|
+
},
|
|
4193
|
+
children: "Entered"
|
|
4194
|
+
}
|
|
4195
|
+
),
|
|
4196
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "var(--compass-color-text)" }, children: formatDate2(position.entryDate) })
|
|
4197
|
+
] })
|
|
4198
|
+
]
|
|
4199
|
+
}
|
|
4200
|
+
),
|
|
4201
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4202
|
+
"div",
|
|
4203
|
+
{
|
|
4204
|
+
style: {
|
|
4205
|
+
display: "flex",
|
|
4206
|
+
justifyContent: "space-between",
|
|
4207
|
+
alignItems: "center",
|
|
4208
|
+
paddingTop: "calc(var(--compass-spacing-unit) * 2)",
|
|
4209
|
+
borderTop: "1px solid var(--compass-color-border)"
|
|
4210
|
+
},
|
|
4211
|
+
children: [
|
|
4212
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4213
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4214
|
+
"span",
|
|
4215
|
+
{
|
|
4216
|
+
style: {
|
|
4217
|
+
fontSize: "var(--compass-font-size-sm)",
|
|
4218
|
+
color: "var(--compass-color-text-secondary)"
|
|
4219
|
+
},
|
|
4220
|
+
children: [
|
|
4221
|
+
"Performance:",
|
|
4222
|
+
" "
|
|
4223
|
+
]
|
|
4224
|
+
}
|
|
4225
|
+
),
|
|
4226
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4227
|
+
"span",
|
|
4228
|
+
{
|
|
4229
|
+
style: {
|
|
4230
|
+
fontWeight: 600,
|
|
4231
|
+
color: position.performance >= 0 ? "var(--compass-color-success)" : "var(--compass-color-error)"
|
|
4232
|
+
},
|
|
4233
|
+
children: [
|
|
4234
|
+
position.performance >= 0 ? "+" : "",
|
|
4235
|
+
"$",
|
|
4236
|
+
position.performance.toFixed(2)
|
|
4237
|
+
]
|
|
4238
|
+
}
|
|
4239
|
+
)
|
|
4240
|
+
] }),
|
|
4241
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4242
|
+
"button",
|
|
4243
|
+
{
|
|
4244
|
+
onClick: () => setIsHistoryExpanded(!isHistoryExpanded),
|
|
4245
|
+
style: {
|
|
4246
|
+
display: "flex",
|
|
4247
|
+
alignItems: "center",
|
|
4248
|
+
gap: "calc(var(--compass-spacing-unit) * 0.5)",
|
|
4249
|
+
padding: "calc(var(--compass-spacing-unit) * 1) calc(var(--compass-spacing-unit) * 2)",
|
|
4250
|
+
backgroundColor: "transparent",
|
|
4251
|
+
border: "1px solid var(--compass-color-border)",
|
|
4252
|
+
borderRadius: "var(--compass-border-radius-md)",
|
|
4253
|
+
cursor: "pointer",
|
|
4254
|
+
fontSize: "var(--compass-font-size-xs)",
|
|
4255
|
+
color: "var(--compass-color-text-secondary)",
|
|
4256
|
+
fontFamily: "var(--compass-font-family)"
|
|
4257
|
+
},
|
|
4258
|
+
children: [
|
|
4259
|
+
"tx history",
|
|
4260
|
+
isHistoryExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { size: 12 }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: 12 })
|
|
4261
|
+
]
|
|
4262
|
+
}
|
|
4263
|
+
)
|
|
4264
|
+
]
|
|
4265
|
+
}
|
|
4266
|
+
),
|
|
4267
|
+
isHistoryExpanded && position.transactions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4268
|
+
"div",
|
|
4269
|
+
{
|
|
4270
|
+
style: {
|
|
4271
|
+
marginTop: "calc(var(--compass-spacing-unit) * 2)",
|
|
4272
|
+
backgroundColor: "var(--compass-color-background)",
|
|
4273
|
+
borderRadius: "var(--compass-border-radius-md)",
|
|
4274
|
+
padding: "calc(var(--compass-spacing-unit) * 2)"
|
|
4275
|
+
},
|
|
4276
|
+
children: position.transactions.map((tx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4277
|
+
"div",
|
|
4278
|
+
{
|
|
4279
|
+
style: {
|
|
4280
|
+
display: "flex",
|
|
4281
|
+
justifyContent: "space-between",
|
|
4282
|
+
alignItems: "center",
|
|
4283
|
+
padding: "calc(var(--compass-spacing-unit) * 1.5) 0",
|
|
4284
|
+
borderBottom: "1px solid var(--compass-color-border)"
|
|
4285
|
+
},
|
|
4286
|
+
children: [
|
|
4287
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "calc(var(--compass-spacing-unit) * 2)" }, children: [
|
|
4288
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4289
|
+
"span",
|
|
4290
|
+
{
|
|
4291
|
+
style: {
|
|
4292
|
+
fontSize: "var(--compass-font-size-xs)",
|
|
4293
|
+
color: "var(--compass-color-text-tertiary)",
|
|
4294
|
+
minWidth: "50px"
|
|
4295
|
+
},
|
|
4296
|
+
children: formatShortDate(tx.date)
|
|
4297
|
+
}
|
|
4298
|
+
),
|
|
4299
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4300
|
+
"span",
|
|
4301
|
+
{
|
|
4302
|
+
style: {
|
|
4303
|
+
fontSize: "var(--compass-font-size-sm)",
|
|
4304
|
+
color: "var(--compass-color-text-secondary)",
|
|
4305
|
+
textTransform: "capitalize"
|
|
4306
|
+
},
|
|
4307
|
+
children: tx.type
|
|
4308
|
+
}
|
|
4309
|
+
)
|
|
4310
|
+
] }),
|
|
4311
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "calc(var(--compass-spacing-unit) * 2)" }, children: [
|
|
4312
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4313
|
+
"span",
|
|
4314
|
+
{
|
|
4315
|
+
style: {
|
|
4316
|
+
fontWeight: 500,
|
|
4317
|
+
color: tx.type === "deposit" ? "var(--compass-color-success)" : "var(--compass-color-error)"
|
|
4318
|
+
},
|
|
4319
|
+
children: [
|
|
4320
|
+
tx.type === "deposit" ? "+" : "-",
|
|
4321
|
+
tx.amount,
|
|
4322
|
+
" ",
|
|
4323
|
+
tx.token
|
|
4324
|
+
]
|
|
4325
|
+
}
|
|
4326
|
+
),
|
|
4327
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4328
|
+
"a",
|
|
4329
|
+
{
|
|
4330
|
+
href: `https://etherscan.io/tx/${tx.txHash}`,
|
|
4331
|
+
target: "_blank",
|
|
4332
|
+
rel: "noopener noreferrer",
|
|
4333
|
+
style: { color: "var(--compass-color-text-tertiary)" },
|
|
4334
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { size: 12 })
|
|
4335
|
+
}
|
|
4336
|
+
)
|
|
4337
|
+
] })
|
|
4338
|
+
]
|
|
4339
|
+
},
|
|
4340
|
+
tx.id
|
|
4341
|
+
))
|
|
4342
|
+
}
|
|
4343
|
+
)
|
|
4344
|
+
]
|
|
4345
|
+
}
|
|
4346
|
+
);
|
|
4347
|
+
}
|
|
4348
|
+
function EarningsModal({ isOpen, onClose, positions, totalEarned, isLoading }) {
|
|
4349
|
+
if (!isOpen) return null;
|
|
4350
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4351
|
+
"div",
|
|
4352
|
+
{
|
|
4353
|
+
style: {
|
|
4354
|
+
position: "fixed",
|
|
4355
|
+
inset: 0,
|
|
4356
|
+
backgroundColor: "var(--compass-color-overlay)",
|
|
4357
|
+
display: "flex",
|
|
4358
|
+
alignItems: "center",
|
|
4359
|
+
justifyContent: "center",
|
|
4360
|
+
zIndex: 50
|
|
4361
|
+
},
|
|
4362
|
+
onClick: onClose,
|
|
4363
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4364
|
+
"div",
|
|
4365
|
+
{
|
|
4366
|
+
style: {
|
|
4367
|
+
backgroundColor: "var(--compass-color-surface-elevated)",
|
|
4368
|
+
borderRadius: "var(--compass-border-radius-xl)",
|
|
4369
|
+
boxShadow: "var(--compass-shadow-lg)",
|
|
4370
|
+
width: "100%",
|
|
4371
|
+
maxWidth: "480px",
|
|
4372
|
+
maxHeight: "80vh",
|
|
4373
|
+
overflow: "hidden",
|
|
4374
|
+
display: "flex",
|
|
4375
|
+
flexDirection: "column"
|
|
4376
|
+
},
|
|
4377
|
+
onClick: (e) => e.stopPropagation(),
|
|
4378
|
+
children: [
|
|
4379
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4380
|
+
"div",
|
|
4381
|
+
{
|
|
4382
|
+
style: {
|
|
4383
|
+
display: "flex",
|
|
4384
|
+
justifyContent: "space-between",
|
|
4385
|
+
alignItems: "center",
|
|
4386
|
+
padding: "var(--compass-spacing-card)",
|
|
4387
|
+
borderBottom: "1px solid var(--compass-color-border)"
|
|
4388
|
+
},
|
|
4389
|
+
children: [
|
|
4390
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4391
|
+
"h2",
|
|
4392
|
+
{
|
|
4393
|
+
style: {
|
|
4394
|
+
fontWeight: 600,
|
|
4395
|
+
fontSize: "var(--compass-font-size-lg)",
|
|
4396
|
+
color: "var(--compass-color-text)",
|
|
4397
|
+
margin: 0
|
|
4398
|
+
},
|
|
4399
|
+
children: "Your Positions"
|
|
4400
|
+
}
|
|
4401
|
+
),
|
|
4402
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4403
|
+
"button",
|
|
4404
|
+
{
|
|
4405
|
+
onClick: onClose,
|
|
4406
|
+
style: {
|
|
4407
|
+
backgroundColor: "transparent",
|
|
4408
|
+
border: "none",
|
|
4409
|
+
cursor: "pointer",
|
|
4410
|
+
padding: "var(--compass-spacing-unit)",
|
|
4411
|
+
color: "var(--compass-color-text-secondary)"
|
|
4412
|
+
},
|
|
4413
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 20 })
|
|
4414
|
+
}
|
|
4415
|
+
)
|
|
4416
|
+
]
|
|
4417
|
+
}
|
|
4418
|
+
),
|
|
4419
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4420
|
+
"div",
|
|
4421
|
+
{
|
|
4422
|
+
style: {
|
|
4423
|
+
padding: "var(--compass-spacing-card)",
|
|
4424
|
+
borderBottom: "1px solid var(--compass-color-border)",
|
|
4425
|
+
backgroundColor: "var(--compass-color-surface)"
|
|
4426
|
+
},
|
|
4427
|
+
children: [
|
|
4428
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4429
|
+
"div",
|
|
4430
|
+
{
|
|
4431
|
+
style: {
|
|
4432
|
+
fontSize: "var(--compass-font-size-sm)",
|
|
4433
|
+
color: "var(--compass-color-text-secondary)",
|
|
4434
|
+
marginBottom: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
4435
|
+
},
|
|
4436
|
+
children: "Total Earned"
|
|
4437
|
+
}
|
|
4438
|
+
),
|
|
4439
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4440
|
+
"div",
|
|
4441
|
+
{
|
|
4442
|
+
style: {
|
|
4443
|
+
fontSize: "var(--compass-font-size-xl)",
|
|
4444
|
+
fontWeight: 600,
|
|
4445
|
+
color: totalEarned >= 0 ? "var(--compass-color-success)" : "var(--compass-color-error)"
|
|
4446
|
+
},
|
|
4447
|
+
children: [
|
|
4448
|
+
totalEarned >= 0 ? "+" : "",
|
|
4449
|
+
"$",
|
|
4450
|
+
totalEarned.toFixed(2)
|
|
4451
|
+
]
|
|
4452
|
+
}
|
|
4453
|
+
)
|
|
4454
|
+
]
|
|
4455
|
+
}
|
|
4456
|
+
),
|
|
4457
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4458
|
+
"div",
|
|
4459
|
+
{
|
|
4460
|
+
style: {
|
|
4461
|
+
flex: 1,
|
|
4462
|
+
overflowY: "auto",
|
|
4463
|
+
padding: "var(--compass-spacing-card)",
|
|
4464
|
+
display: "flex",
|
|
4465
|
+
flexDirection: "column",
|
|
4466
|
+
gap: "calc(var(--compass-spacing-unit) * 3)"
|
|
4467
|
+
},
|
|
4468
|
+
children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4469
|
+
"div",
|
|
4470
|
+
{
|
|
4471
|
+
style: {
|
|
4472
|
+
textAlign: "center",
|
|
4473
|
+
padding: "calc(var(--compass-spacing-unit) * 6)",
|
|
4474
|
+
color: "var(--compass-color-text-secondary)"
|
|
4475
|
+
},
|
|
4476
|
+
children: "Loading positions..."
|
|
4477
|
+
}
|
|
4478
|
+
) : positions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4479
|
+
"div",
|
|
4480
|
+
{
|
|
4481
|
+
style: {
|
|
4482
|
+
textAlign: "center",
|
|
4483
|
+
padding: "calc(var(--compass-spacing-unit) * 6)",
|
|
4484
|
+
color: "var(--compass-color-text-secondary)"
|
|
4485
|
+
},
|
|
4486
|
+
children: [
|
|
4487
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { marginBottom: "var(--compass-spacing-unit)" }, children: "No active positions yet" }),
|
|
4488
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "var(--compass-font-size-sm)", color: "var(--compass-color-text-tertiary)" }, children: "Deposit into a market to start earning" })
|
|
4489
|
+
]
|
|
4490
|
+
}
|
|
4491
|
+
) : positions.map((position) => /* @__PURE__ */ jsxRuntime.jsx(PositionCard, { position }, position.id))
|
|
4492
|
+
}
|
|
4493
|
+
)
|
|
4494
|
+
]
|
|
4495
|
+
}
|
|
4496
|
+
)
|
|
4497
|
+
}
|
|
4498
|
+
);
|
|
4499
|
+
}
|
|
4500
|
+
var CHAIN_ID = "ethereum";
|
|
4501
|
+
var SUPPORTED_TOKENS = ["USDC", "USDT", "DAI", "WETH", "SBC", "AUSD"];
|
|
4502
|
+
function formatCurrency(amount) {
|
|
4503
|
+
if (!amount) return "$0.00";
|
|
4504
|
+
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
4505
|
+
if (isNaN(num)) return "$0.00";
|
|
4506
|
+
return new Intl.NumberFormat("en-US", {
|
|
4507
|
+
style: "currency",
|
|
4508
|
+
currency: "USD",
|
|
4509
|
+
minimumFractionDigits: 2,
|
|
4510
|
+
maximumFractionDigits: 2
|
|
4511
|
+
}).format(num);
|
|
4512
|
+
}
|
|
4513
|
+
function formatAPY3(apy) {
|
|
4514
|
+
if (!apy) return "0.00";
|
|
4515
|
+
const num = parseFloat(apy);
|
|
4516
|
+
return num.toFixed(2);
|
|
4517
|
+
}
|
|
4518
|
+
function formatAmount2(value) {
|
|
4519
|
+
const num = typeof value === "string" ? parseFloat(value) : value;
|
|
4520
|
+
if (isNaN(num)) return "0";
|
|
4521
|
+
return num.toFixed(6).replace(/\.?0+$/, "");
|
|
4522
|
+
}
|
|
4523
|
+
function EarnAccount({
|
|
4524
|
+
showHeader = true,
|
|
4525
|
+
showInterestRate = true,
|
|
4526
|
+
showTopUpButton = true,
|
|
4527
|
+
showTrustBadge = true,
|
|
4528
|
+
compact = false,
|
|
4529
|
+
title = "Savings Account",
|
|
4530
|
+
onDeposit,
|
|
4531
|
+
onWithdraw,
|
|
4532
|
+
defaultMarketType = "aave",
|
|
4533
|
+
defaultMinTvl = 0
|
|
4534
|
+
}) {
|
|
4535
|
+
const { address, signTypedData } = useEmbeddableWallet();
|
|
4536
|
+
const { isDeployed } = useEarnAccount();
|
|
4537
|
+
const queryClient = reactQuery.useQueryClient();
|
|
4538
|
+
const [activeTab, setActiveTab] = react.useState("deposit");
|
|
4539
|
+
const [selectedToken, setSelectedToken] = react.useState("USDC");
|
|
4540
|
+
const [amount, setAmount] = react.useState("");
|
|
4541
|
+
const [isProcessing, setIsProcessing] = react.useState(false);
|
|
4542
|
+
const [error, setError] = react.useState(null);
|
|
4543
|
+
const [statusMessage, setStatusMessage] = react.useState("");
|
|
4544
|
+
const [isTokenDropdownOpen, setIsTokenDropdownOpen] = react.useState(false);
|
|
4545
|
+
const [isFundModalOpen, setIsFundModalOpen] = react.useState(false);
|
|
4546
|
+
const [fundAmount, setFundAmount] = react.useState("");
|
|
4547
|
+
const [fundToken, setFundToken] = react.useState("USDC");
|
|
4548
|
+
const [isFunding, setIsFunding] = react.useState(false);
|
|
4549
|
+
const [fundError, setFundError] = react.useState(null);
|
|
4550
|
+
const [fundStatus, setFundStatus] = react.useState("");
|
|
4551
|
+
const [isBalancesModalOpen, setIsBalancesModalOpen] = react.useState(false);
|
|
4552
|
+
const [marketType, setMarketType] = react.useState(defaultMarketType);
|
|
4553
|
+
const [selectedMarket, setSelectedMarket] = react.useState(null);
|
|
4554
|
+
const [minTvl, setMinTvl] = react.useState(defaultMinTvl);
|
|
4555
|
+
const [isEarningsModalOpen, setIsEarningsModalOpen] = react.useState(false);
|
|
4556
|
+
const FUND_TOKENS = ["USDC", "DAI"];
|
|
4557
|
+
const walletBalanceQuery = reactQuery.useQuery({
|
|
4558
|
+
queryKey: ["walletBalance", CHAIN_ID, address, fundToken],
|
|
4559
|
+
queryFn: async () => {
|
|
4560
|
+
if (!address) return null;
|
|
4561
|
+
try {
|
|
4562
|
+
const response = await fetch(
|
|
4563
|
+
`/api/compass/token/balance?address=${address}&chain=${CHAIN_ID}&token=${fundToken}`
|
|
4564
|
+
);
|
|
4565
|
+
if (!response.ok) return null;
|
|
4566
|
+
const data = await response.json();
|
|
4567
|
+
return data;
|
|
4568
|
+
} catch {
|
|
4569
|
+
return null;
|
|
4570
|
+
}
|
|
4571
|
+
},
|
|
4572
|
+
enabled: !!address && isFundModalOpen,
|
|
4573
|
+
staleTime: 15 * 1e3
|
|
4574
|
+
});
|
|
4575
|
+
const walletBalance = walletBalanceQuery.data?.balance || "0";
|
|
4576
|
+
const balancesQuery = reactQuery.useQuery({
|
|
4577
|
+
queryKey: ["earnAccountBalances", CHAIN_ID, address],
|
|
4578
|
+
queryFn: async () => {
|
|
4579
|
+
if (!address) return null;
|
|
4580
|
+
const response = await fetch(
|
|
4581
|
+
`/api/compass/earn-account/balances?owner=${address}&chain=${CHAIN_ID}`
|
|
4582
|
+
);
|
|
4583
|
+
if (!response.ok) {
|
|
4584
|
+
throw new Error("Failed to fetch balances");
|
|
4585
|
+
}
|
|
4586
|
+
return response.json();
|
|
4587
|
+
},
|
|
4588
|
+
enabled: !!address && isDeployed,
|
|
4589
|
+
staleTime: 30 * 1e3
|
|
4590
|
+
});
|
|
4591
|
+
const selectedTokenBalance = balancesQuery.data?.balances?.[selectedToken]?.balance || "0";
|
|
4592
|
+
const earnAccountTotalUsd = balancesQuery.data?.totalUsdValue || "0";
|
|
4593
|
+
const marketQuery = reactQuery.useQuery({
|
|
4594
|
+
queryKey: ["earnAccountUSDC", CHAIN_ID],
|
|
4595
|
+
queryFn: async () => {
|
|
4596
|
+
const response = await fetch(`/api/compass/aave/markets?chain=${CHAIN_ID}`);
|
|
4597
|
+
if (!response.ok) return null;
|
|
4598
|
+
const data = await response.json();
|
|
4599
|
+
const marketsDict = data.markets || {};
|
|
4600
|
+
const usdcData = marketsDict["USDC"];
|
|
4601
|
+
if (!usdcData) return null;
|
|
4602
|
+
const chainData = usdcData.chains?.[CHAIN_ID];
|
|
4603
|
+
if (!chainData) return null;
|
|
4604
|
+
return {
|
|
4605
|
+
marketAddress: chainData.address || "",
|
|
4606
|
+
supplyApy: chainData.supplyApy?.toString() ?? null
|
|
4607
|
+
};
|
|
4608
|
+
},
|
|
4609
|
+
staleTime: 30 * 1e3
|
|
4610
|
+
});
|
|
4611
|
+
const positionQuery = reactQuery.useQuery({
|
|
4612
|
+
queryKey: ["earnAccountUSDCPosition", CHAIN_ID, address],
|
|
4613
|
+
queryFn: async () => {
|
|
4614
|
+
if (!address) return null;
|
|
4615
|
+
const response = await fetch(`/api/compass/positions?chain=${CHAIN_ID}&owner=${address}`);
|
|
4616
|
+
if (!response.ok) return null;
|
|
4617
|
+
const data = await response.json();
|
|
4618
|
+
const aavePositions = data.aave || [];
|
|
4619
|
+
const usdcPosition = aavePositions.find(
|
|
4620
|
+
(p) => p.reserveSymbol?.toUpperCase() === "USDC"
|
|
4621
|
+
);
|
|
4622
|
+
if (!usdcPosition) return null;
|
|
4623
|
+
return {
|
|
4624
|
+
balance: usdcPosition.balance || "0",
|
|
4625
|
+
pnl: usdcPosition.pnl ? {
|
|
4626
|
+
unrealizedPnl: usdcPosition.pnl.unrealizedPnl || "0",
|
|
4627
|
+
realizedPnl: usdcPosition.pnl.realizedPnl || "0",
|
|
4628
|
+
totalPnl: usdcPosition.pnl.totalPnl || "0",
|
|
4629
|
+
totalDeposited: usdcPosition.pnl.totalDeposited || "0"
|
|
4630
|
+
} : void 0,
|
|
4631
|
+
deposits: (usdcPosition.deposits || []).map((d) => ({
|
|
4632
|
+
amount: d.inputAmount || d.amount || "0",
|
|
4633
|
+
blockNumber: d.blockNumber || 0,
|
|
4634
|
+
txHash: d.transactionHash || d.txHash || ""
|
|
4635
|
+
})),
|
|
4636
|
+
withdrawals: (usdcPosition.withdrawals || []).map((w) => ({
|
|
4637
|
+
amount: w.outputAmount || w.amount || "0",
|
|
4638
|
+
blockNumber: w.blockNumber || 0,
|
|
4639
|
+
txHash: w.transactionHash || w.txHash || ""
|
|
4640
|
+
}))
|
|
4641
|
+
};
|
|
4642
|
+
},
|
|
4643
|
+
enabled: !!address,
|
|
4644
|
+
staleTime: 30 * 1e3
|
|
4645
|
+
});
|
|
4646
|
+
const market = marketQuery.data;
|
|
4647
|
+
const userPosition = positionQuery.data;
|
|
4648
|
+
const depositedBalance = parseFloat(userPosition?.balance || "0");
|
|
4649
|
+
const earnAccountTotal = parseFloat(earnAccountTotalUsd);
|
|
4650
|
+
const totalBalance = earnAccountTotal + depositedBalance;
|
|
4651
|
+
const mockMarkets = [
|
|
4652
|
+
{ id: "aave-usdc", name: "USDC", apy: 4.5, tvl: 5e8, type: "aave" },
|
|
4653
|
+
{ id: "aave-usdt", name: "USDT", apy: 4.2, tvl: 35e7, type: "aave" },
|
|
4654
|
+
{ id: "aave-dai", name: "DAI", apy: 3.8, tvl: 2e8, type: "aave" },
|
|
4655
|
+
{ id: "pendle-usdc-mar25", name: "USDC Mar 2025", apy: 8.5, tvl: 5e7, type: "pendle", expiry: "Mar 2025" },
|
|
4656
|
+
{ id: "pendle-usdc-jun25", name: "USDC Jun 2025", apy: 7.2, tvl: 3e7, type: "pendle", expiry: "Jun 2025" },
|
|
4657
|
+
{ id: "vault-steakhouse", name: "Steakhouse USDC", apy: 6.5, tvl: 15e7, type: "vaults", curator: "Steakhouse" },
|
|
4658
|
+
{ id: "vault-gauntlet", name: "Gauntlet USDC", apy: 5.8, tvl: 2e8, type: "vaults", curator: "Gauntlet" }
|
|
4659
|
+
];
|
|
4660
|
+
const positions = userPosition?.balance && parseFloat(userPosition.balance) > 0 ? [{
|
|
4661
|
+
id: "pos-1",
|
|
4662
|
+
marketType: "aave",
|
|
4663
|
+
marketName: "USDC on Aave",
|
|
4664
|
+
marketId: "aave-usdc",
|
|
4665
|
+
amount: parseFloat(userPosition.balance),
|
|
4666
|
+
token: "USDC",
|
|
4667
|
+
apy: parseFloat(market?.supplyApy || "0"),
|
|
4668
|
+
entryDate: new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
4669
|
+
performance: parseFloat(userPosition.pnl?.totalPnl || "0"),
|
|
4670
|
+
transactions: [
|
|
4671
|
+
...(userPosition.deposits || []).map((d, i) => ({
|
|
4672
|
+
id: `dep-${i}`,
|
|
4673
|
+
date: new Date(Date.now() - (i + 1) * 7 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
4674
|
+
type: "deposit",
|
|
4675
|
+
amount: parseFloat(d.amount),
|
|
4676
|
+
token: "USDC",
|
|
4677
|
+
txHash: d.txHash || ""
|
|
4678
|
+
})),
|
|
4679
|
+
...(userPosition.withdrawals || []).map((w, i) => ({
|
|
4680
|
+
id: `wit-${i}`,
|
|
4681
|
+
date: new Date(Date.now() - i * 3 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
4682
|
+
type: "withdraw",
|
|
4683
|
+
amount: parseFloat(w.amount),
|
|
4684
|
+
token: "USDC",
|
|
4685
|
+
txHash: w.txHash || ""
|
|
4686
|
+
}))
|
|
4687
|
+
]
|
|
4688
|
+
}] : [];
|
|
4689
|
+
const totalEarned = positions.reduce((sum, p) => sum + p.performance, 0);
|
|
4690
|
+
const needsActionSwap = selectedToken !== "USDC";
|
|
4691
|
+
const needsFundSwap = fundToken !== "USDC";
|
|
4692
|
+
const ensureTokenApproval = async (token) => {
|
|
4693
|
+
setFundStatus(`Checking ${token} approval...`);
|
|
4694
|
+
const approveResponse = await fetch("/api/compass/transfer/approve", {
|
|
4695
|
+
method: "POST",
|
|
4696
|
+
headers: { "Content-Type": "application/json" },
|
|
4697
|
+
body: JSON.stringify({
|
|
4698
|
+
owner: address,
|
|
4699
|
+
chain: CHAIN_ID,
|
|
4700
|
+
token
|
|
4701
|
+
})
|
|
4702
|
+
});
|
|
4703
|
+
if (!approveResponse.ok) {
|
|
4704
|
+
const errData = await approveResponse.json();
|
|
4705
|
+
throw new Error(errData.error || "Failed to check approval");
|
|
4706
|
+
}
|
|
4707
|
+
const approvalData = await approveResponse.json();
|
|
4708
|
+
if (approvalData.approved) {
|
|
4709
|
+
return;
|
|
4710
|
+
}
|
|
4711
|
+
if (approvalData.requiresTransaction && approvalData.transaction) {
|
|
4712
|
+
setFundStatus(`Approving ${token} (requires on-chain transaction)...`);
|
|
4713
|
+
const executeApprovalResponse = await fetch("/api/compass/approval/execute", {
|
|
4714
|
+
method: "POST",
|
|
4715
|
+
headers: { "Content-Type": "application/json" },
|
|
4716
|
+
body: JSON.stringify({
|
|
4717
|
+
owner: address,
|
|
4718
|
+
chain: CHAIN_ID,
|
|
4719
|
+
transaction: approvalData.transaction
|
|
4720
|
+
})
|
|
4721
|
+
});
|
|
4722
|
+
if (!executeApprovalResponse.ok) {
|
|
4723
|
+
const errData = await executeApprovalResponse.json();
|
|
4724
|
+
throw new Error(errData.error || "Approval transaction failed");
|
|
4725
|
+
}
|
|
4726
|
+
return;
|
|
4727
|
+
}
|
|
4728
|
+
if (approvalData.eip712) {
|
|
4729
|
+
setFundStatus(`Please approve ${token} for transfers...`);
|
|
4730
|
+
const approvalSignature = await signTypedData({
|
|
4731
|
+
domain: approvalData.domain,
|
|
4732
|
+
types: approvalData.normalizedTypes,
|
|
4733
|
+
primaryType: "Permit",
|
|
4734
|
+
message: approvalData.message
|
|
4735
|
+
});
|
|
4736
|
+
setFundStatus(`Setting up ${token} approval...`);
|
|
4737
|
+
const executeApprovalResponse = await fetch("/api/compass/transfer/execute", {
|
|
4738
|
+
method: "POST",
|
|
4739
|
+
headers: { "Content-Type": "application/json" },
|
|
4740
|
+
body: JSON.stringify({
|
|
4741
|
+
owner: address,
|
|
4742
|
+
chain: CHAIN_ID,
|
|
4743
|
+
eip712: approvalData.eip712,
|
|
4744
|
+
signature: approvalSignature
|
|
3987
4745
|
})
|
|
3988
4746
|
});
|
|
3989
4747
|
if (!executeApprovalResponse.ok) {
|
|
@@ -4000,7 +4758,7 @@ function EarnAccount({
|
|
|
4000
4758
|
setFundError(null);
|
|
4001
4759
|
try {
|
|
4002
4760
|
await ensureTokenApproval(fundToken);
|
|
4003
|
-
if (
|
|
4761
|
+
if (needsFundSwap) {
|
|
4004
4762
|
setFundStatus(`Preparing ${fundToken} transfer...`);
|
|
4005
4763
|
const transferPrepareResponse = await fetch("/api/compass/transfer/prepare", {
|
|
4006
4764
|
method: "POST",
|
|
@@ -4089,32 +4847,233 @@ function EarnAccount({
|
|
|
4089
4847
|
throw new Error(errData.error || "Swap failed");
|
|
4090
4848
|
}
|
|
4091
4849
|
} else {
|
|
4092
|
-
setFundStatus("Preparing transfer...");
|
|
4093
|
-
const prepareResponse = await fetch("/api/compass/transfer/prepare", {
|
|
4850
|
+
setFundStatus("Preparing transfer...");
|
|
4851
|
+
const prepareResponse = await fetch("/api/compass/transfer/prepare", {
|
|
4852
|
+
method: "POST",
|
|
4853
|
+
headers: { "Content-Type": "application/json" },
|
|
4854
|
+
body: JSON.stringify({
|
|
4855
|
+
owner: address,
|
|
4856
|
+
chain: CHAIN_ID,
|
|
4857
|
+
token: "USDC",
|
|
4858
|
+
amount: fundAmount,
|
|
4859
|
+
action: "DEPOSIT"
|
|
4860
|
+
})
|
|
4861
|
+
});
|
|
4862
|
+
if (!prepareResponse.ok) {
|
|
4863
|
+
const errData = await prepareResponse.json();
|
|
4864
|
+
throw new Error(errData.error || "Failed to prepare transfer");
|
|
4865
|
+
}
|
|
4866
|
+
const prepareData = await prepareResponse.json();
|
|
4867
|
+
setFundStatus("Please sign the transfer...");
|
|
4868
|
+
const signature = await signTypedData({
|
|
4869
|
+
domain: prepareData.domain,
|
|
4870
|
+
types: prepareData.normalizedTypes,
|
|
4871
|
+
primaryType: prepareData.primaryType,
|
|
4872
|
+
message: prepareData.message
|
|
4873
|
+
});
|
|
4874
|
+
setFundStatus("Transferring funds...");
|
|
4875
|
+
const executeResponse = await fetch("/api/compass/transfer/execute", {
|
|
4876
|
+
method: "POST",
|
|
4877
|
+
headers: { "Content-Type": "application/json" },
|
|
4878
|
+
body: JSON.stringify({
|
|
4879
|
+
owner: address,
|
|
4880
|
+
chain: CHAIN_ID,
|
|
4881
|
+
eip712: prepareData.eip712,
|
|
4882
|
+
signature
|
|
4883
|
+
})
|
|
4884
|
+
});
|
|
4885
|
+
if (!executeResponse.ok) {
|
|
4886
|
+
const errData = await executeResponse.json();
|
|
4887
|
+
throw new Error(errData.error || "Transfer failed");
|
|
4888
|
+
}
|
|
4889
|
+
}
|
|
4890
|
+
setFundStatus("Success! Funds added to savings.");
|
|
4891
|
+
setFundAmount("");
|
|
4892
|
+
queryClient.invalidateQueries({ queryKey: ["earnAccountBalances"] });
|
|
4893
|
+
queryClient.invalidateQueries({ queryKey: ["walletBalance"] });
|
|
4894
|
+
balancesQuery.refetch();
|
|
4895
|
+
setTimeout(() => {
|
|
4896
|
+
setIsFundModalOpen(false);
|
|
4897
|
+
setFundStatus("");
|
|
4898
|
+
setFundToken("USDC");
|
|
4899
|
+
}, 2e3);
|
|
4900
|
+
} catch (err) {
|
|
4901
|
+
setFundError(err instanceof Error ? err.message : "Transfer failed");
|
|
4902
|
+
setFundStatus("");
|
|
4903
|
+
} finally {
|
|
4904
|
+
setIsFunding(false);
|
|
4905
|
+
}
|
|
4906
|
+
}, [address, fundAmount, fundToken, needsFundSwap, signTypedData, queryClient, balancesQuery]);
|
|
4907
|
+
const handleAction = async () => {
|
|
4908
|
+
if (!market || !amount || parseFloat(amount) <= 0 || !address || !signTypedData) return;
|
|
4909
|
+
setIsProcessing(true);
|
|
4910
|
+
setError(null);
|
|
4911
|
+
const isDeposit = activeTab === "deposit";
|
|
4912
|
+
try {
|
|
4913
|
+
let txHash;
|
|
4914
|
+
if (needsActionSwap) {
|
|
4915
|
+
if (isDeposit) {
|
|
4916
|
+
setStatusMessage(`Getting swap quote...`);
|
|
4917
|
+
const quoteResponse = await fetch(
|
|
4918
|
+
`/api/compass/swap/quote?owner=${address}&chain=${CHAIN_ID}&tokenIn=${selectedToken}&tokenOut=USDC&amountIn=${amount}`
|
|
4919
|
+
);
|
|
4920
|
+
if (!quoteResponse.ok) {
|
|
4921
|
+
const errorData = await quoteResponse.json();
|
|
4922
|
+
throw new Error(errorData.error || "Failed to get swap quote");
|
|
4923
|
+
}
|
|
4924
|
+
const quoteData = await quoteResponse.json();
|
|
4925
|
+
const estimatedOutput = quoteData.estimatedAmountOut;
|
|
4926
|
+
if (!estimatedOutput || parseFloat(estimatedOutput) <= 0) {
|
|
4927
|
+
throw new Error("Invalid swap quote - no output amount");
|
|
4928
|
+
}
|
|
4929
|
+
const depositAmount = (parseFloat(estimatedOutput) * 0.99).toString();
|
|
4930
|
+
setStatusMessage(`Preparing swap and deposit...`);
|
|
4931
|
+
const bundleActions = [
|
|
4932
|
+
{
|
|
4933
|
+
body: {
|
|
4934
|
+
actionType: "V2_SWAP",
|
|
4935
|
+
tokenIn: selectedToken,
|
|
4936
|
+
tokenOut: "USDC",
|
|
4937
|
+
amountIn: amount,
|
|
4938
|
+
maxSlippagePercent: 1
|
|
4939
|
+
}
|
|
4940
|
+
},
|
|
4941
|
+
{
|
|
4942
|
+
body: {
|
|
4943
|
+
actionType: "V2_MANAGE",
|
|
4944
|
+
action: "DEPOSIT",
|
|
4945
|
+
venue: { type: "AAVE", token: "USDC" },
|
|
4946
|
+
amount: depositAmount
|
|
4947
|
+
}
|
|
4948
|
+
}
|
|
4949
|
+
];
|
|
4950
|
+
const prepareResponse = await fetch("/api/compass/bundle/prepare", {
|
|
4951
|
+
method: "POST",
|
|
4952
|
+
headers: { "Content-Type": "application/json" },
|
|
4953
|
+
body: JSON.stringify({
|
|
4954
|
+
owner: address,
|
|
4955
|
+
chain: CHAIN_ID,
|
|
4956
|
+
actions: bundleActions
|
|
4957
|
+
})
|
|
4958
|
+
});
|
|
4959
|
+
if (!prepareResponse.ok) {
|
|
4960
|
+
const errorData = await prepareResponse.json();
|
|
4961
|
+
throw new Error(errorData.error || "Failed to prepare bundle");
|
|
4962
|
+
}
|
|
4963
|
+
const { eip712, normalizedTypes, domain, message } = await prepareResponse.json();
|
|
4964
|
+
setStatusMessage("Please sign the transaction...");
|
|
4965
|
+
const signature = await signTypedData({
|
|
4966
|
+
domain,
|
|
4967
|
+
types: normalizedTypes,
|
|
4968
|
+
primaryType: "SafeTx",
|
|
4969
|
+
message
|
|
4970
|
+
});
|
|
4971
|
+
setStatusMessage("Executing swap and deposit...");
|
|
4972
|
+
const executeResponse = await fetch("/api/compass/bundle/execute", {
|
|
4973
|
+
method: "POST",
|
|
4974
|
+
headers: { "Content-Type": "application/json" },
|
|
4975
|
+
body: JSON.stringify({
|
|
4976
|
+
owner: address,
|
|
4977
|
+
eip712,
|
|
4978
|
+
signature,
|
|
4979
|
+
chain: CHAIN_ID
|
|
4980
|
+
})
|
|
4981
|
+
});
|
|
4982
|
+
if (!executeResponse.ok) {
|
|
4983
|
+
const errorData = await executeResponse.json();
|
|
4984
|
+
throw new Error(errorData.error || "Failed to execute bundle");
|
|
4985
|
+
}
|
|
4986
|
+
const result = await executeResponse.json();
|
|
4987
|
+
txHash = result.txHash;
|
|
4988
|
+
} else {
|
|
4989
|
+
setStatusMessage(`Preparing withdraw and swap...`);
|
|
4990
|
+
const bundleActions = [
|
|
4991
|
+
{
|
|
4992
|
+
body: {
|
|
4993
|
+
actionType: "V2_MANAGE",
|
|
4994
|
+
action: "WITHDRAW",
|
|
4995
|
+
venue: { type: "AAVE", token: "USDC" },
|
|
4996
|
+
amount
|
|
4997
|
+
}
|
|
4998
|
+
},
|
|
4999
|
+
{
|
|
5000
|
+
body: {
|
|
5001
|
+
actionType: "V2_SWAP",
|
|
5002
|
+
tokenIn: "USDC",
|
|
5003
|
+
tokenOut: selectedToken,
|
|
5004
|
+
amountIn: amount,
|
|
5005
|
+
maxSlippagePercent: 1
|
|
5006
|
+
}
|
|
5007
|
+
}
|
|
5008
|
+
];
|
|
5009
|
+
const prepareResponse = await fetch("/api/compass/bundle/prepare", {
|
|
5010
|
+
method: "POST",
|
|
5011
|
+
headers: { "Content-Type": "application/json" },
|
|
5012
|
+
body: JSON.stringify({
|
|
5013
|
+
owner: address,
|
|
5014
|
+
chain: CHAIN_ID,
|
|
5015
|
+
actions: bundleActions
|
|
5016
|
+
})
|
|
5017
|
+
});
|
|
5018
|
+
if (!prepareResponse.ok) {
|
|
5019
|
+
const errorData = await prepareResponse.json();
|
|
5020
|
+
throw new Error(errorData.error || "Failed to prepare bundle");
|
|
5021
|
+
}
|
|
5022
|
+
const { eip712, normalizedTypes, domain, message } = await prepareResponse.json();
|
|
5023
|
+
setStatusMessage("Please sign the transaction...");
|
|
5024
|
+
const signature = await signTypedData({
|
|
5025
|
+
domain,
|
|
5026
|
+
types: normalizedTypes,
|
|
5027
|
+
primaryType: "SafeTx",
|
|
5028
|
+
message
|
|
5029
|
+
});
|
|
5030
|
+
setStatusMessage("Executing withdraw and swap...");
|
|
5031
|
+
const executeResponse = await fetch("/api/compass/bundle/execute", {
|
|
5032
|
+
method: "POST",
|
|
5033
|
+
headers: { "Content-Type": "application/json" },
|
|
5034
|
+
body: JSON.stringify({
|
|
5035
|
+
owner: address,
|
|
5036
|
+
eip712,
|
|
5037
|
+
signature,
|
|
5038
|
+
chain: CHAIN_ID
|
|
5039
|
+
})
|
|
5040
|
+
});
|
|
5041
|
+
if (!executeResponse.ok) {
|
|
5042
|
+
const errorData = await executeResponse.json();
|
|
5043
|
+
throw new Error(errorData.error || "Failed to execute bundle");
|
|
5044
|
+
}
|
|
5045
|
+
const result = await executeResponse.json();
|
|
5046
|
+
txHash = result.txHash;
|
|
5047
|
+
}
|
|
5048
|
+
} else {
|
|
5049
|
+
setStatusMessage(isDeposit ? "Preparing deposit..." : "Preparing withdrawal...");
|
|
5050
|
+
const prepareEndpoint = isDeposit ? "/api/compass/deposit/prepare" : "/api/compass/withdraw/prepare";
|
|
5051
|
+
const executeEndpoint = isDeposit ? "/api/compass/deposit/execute" : "/api/compass/withdraw/execute";
|
|
5052
|
+
const prepareResponse = await fetch(prepareEndpoint, {
|
|
4094
5053
|
method: "POST",
|
|
4095
5054
|
headers: { "Content-Type": "application/json" },
|
|
4096
5055
|
body: JSON.stringify({
|
|
4097
5056
|
owner: address,
|
|
4098
5057
|
chain: CHAIN_ID,
|
|
5058
|
+
venueType: "AAVE",
|
|
4099
5059
|
token: "USDC",
|
|
4100
|
-
amount
|
|
4101
|
-
action: "DEPOSIT"
|
|
5060
|
+
amount
|
|
4102
5061
|
})
|
|
4103
5062
|
});
|
|
4104
5063
|
if (!prepareResponse.ok) {
|
|
4105
5064
|
const errData = await prepareResponse.json();
|
|
4106
|
-
throw new Error(errData.error || "Failed to prepare
|
|
5065
|
+
throw new Error(errData.error || "Failed to prepare transaction");
|
|
4107
5066
|
}
|
|
4108
5067
|
const prepareData = await prepareResponse.json();
|
|
4109
|
-
|
|
5068
|
+
setStatusMessage("Please sign the transaction...");
|
|
4110
5069
|
const signature = await signTypedData({
|
|
4111
5070
|
domain: prepareData.domain,
|
|
4112
5071
|
types: prepareData.normalizedTypes,
|
|
4113
|
-
primaryType:
|
|
5072
|
+
primaryType: "SafeTx",
|
|
4114
5073
|
message: prepareData.message
|
|
4115
5074
|
});
|
|
4116
|
-
|
|
4117
|
-
const executeResponse = await fetch(
|
|
5075
|
+
setStatusMessage("Executing transaction...");
|
|
5076
|
+
const executeResponse = await fetch(executeEndpoint, {
|
|
4118
5077
|
method: "POST",
|
|
4119
5078
|
headers: { "Content-Type": "application/json" },
|
|
4120
5079
|
body: JSON.stringify({
|
|
@@ -4126,74 +5085,11 @@ function EarnAccount({
|
|
|
4126
5085
|
});
|
|
4127
5086
|
if (!executeResponse.ok) {
|
|
4128
5087
|
const errData = await executeResponse.json();
|
|
4129
|
-
throw new Error(errData.error || "
|
|
5088
|
+
throw new Error(errData.error || "Transaction failed");
|
|
4130
5089
|
}
|
|
5090
|
+
const result = await executeResponse.json();
|
|
5091
|
+
txHash = result.txHash;
|
|
4131
5092
|
}
|
|
4132
|
-
setFundStatus("Success! Funds added to savings.");
|
|
4133
|
-
setFundAmount("");
|
|
4134
|
-
queryClient.invalidateQueries({ queryKey: ["earnAccountBalances"] });
|
|
4135
|
-
queryClient.invalidateQueries({ queryKey: ["walletBalance"] });
|
|
4136
|
-
balancesQuery.refetch();
|
|
4137
|
-
setTimeout(() => {
|
|
4138
|
-
setIsFundModalOpen(false);
|
|
4139
|
-
setFundStatus("");
|
|
4140
|
-
setFundToken("USDC");
|
|
4141
|
-
}, 2e3);
|
|
4142
|
-
} catch (err) {
|
|
4143
|
-
setFundError(err instanceof Error ? err.message : "Transfer failed");
|
|
4144
|
-
setFundStatus("");
|
|
4145
|
-
} finally {
|
|
4146
|
-
setIsFunding(false);
|
|
4147
|
-
}
|
|
4148
|
-
}, [address, fundAmount, fundToken, needsSwap, signTypedData, queryClient, balancesQuery]);
|
|
4149
|
-
const handleAction = async () => {
|
|
4150
|
-
if (!market || !amount || parseFloat(amount) <= 0 || !address || !signTypedData) return;
|
|
4151
|
-
setIsProcessing(true);
|
|
4152
|
-
setError(null);
|
|
4153
|
-
setStatusMessage(activeTab === "deposit" ? "Preparing deposit..." : "Preparing withdrawal...");
|
|
4154
|
-
try {
|
|
4155
|
-
const isDeposit = activeTab === "deposit";
|
|
4156
|
-
const prepareEndpoint = isDeposit ? "/api/compass/deposit/prepare" : "/api/compass/withdraw/prepare";
|
|
4157
|
-
const executeEndpoint = isDeposit ? "/api/compass/deposit/execute" : "/api/compass/withdraw/execute";
|
|
4158
|
-
const prepareResponse = await fetch(prepareEndpoint, {
|
|
4159
|
-
method: "POST",
|
|
4160
|
-
headers: { "Content-Type": "application/json" },
|
|
4161
|
-
body: JSON.stringify({
|
|
4162
|
-
owner: address,
|
|
4163
|
-
chain: CHAIN_ID,
|
|
4164
|
-
venueType: "AAVE",
|
|
4165
|
-
token: "USDC",
|
|
4166
|
-
amount
|
|
4167
|
-
})
|
|
4168
|
-
});
|
|
4169
|
-
if (!prepareResponse.ok) {
|
|
4170
|
-
const errData = await prepareResponse.json();
|
|
4171
|
-
throw new Error(errData.error || "Failed to prepare transaction");
|
|
4172
|
-
}
|
|
4173
|
-
const prepareData = await prepareResponse.json();
|
|
4174
|
-
setStatusMessage("Please sign the transaction...");
|
|
4175
|
-
const signature = await signTypedData({
|
|
4176
|
-
domain: prepareData.domain,
|
|
4177
|
-
types: prepareData.normalizedTypes,
|
|
4178
|
-
primaryType: "SafeTx",
|
|
4179
|
-
message: prepareData.message
|
|
4180
|
-
});
|
|
4181
|
-
setStatusMessage("Executing transaction...");
|
|
4182
|
-
const executeResponse = await fetch(executeEndpoint, {
|
|
4183
|
-
method: "POST",
|
|
4184
|
-
headers: { "Content-Type": "application/json" },
|
|
4185
|
-
body: JSON.stringify({
|
|
4186
|
-
owner: address,
|
|
4187
|
-
chain: CHAIN_ID,
|
|
4188
|
-
eip712: prepareData.eip712,
|
|
4189
|
-
signature
|
|
4190
|
-
})
|
|
4191
|
-
});
|
|
4192
|
-
if (!executeResponse.ok) {
|
|
4193
|
-
const errData = await executeResponse.json();
|
|
4194
|
-
throw new Error(errData.error || "Transaction failed");
|
|
4195
|
-
}
|
|
4196
|
-
const { txHash } = await executeResponse.json();
|
|
4197
5093
|
setStatusMessage("Transaction successful!");
|
|
4198
5094
|
setAmount("");
|
|
4199
5095
|
queryClient.invalidateQueries({ queryKey: ["earnAccountBalances"] });
|
|
@@ -4208,10 +5104,24 @@ function EarnAccount({
|
|
|
4208
5104
|
borrowApy: null,
|
|
4209
5105
|
tvlUsd: null
|
|
4210
5106
|
};
|
|
4211
|
-
if (
|
|
4212
|
-
|
|
5107
|
+
if (isDeposit) {
|
|
5108
|
+
const depositMarket = {
|
|
5109
|
+
id: "aave-usdc",
|
|
5110
|
+
name: "USDC",
|
|
5111
|
+
apy: parseFloat(market.supplyApy || "0"),
|
|
5112
|
+
tvl: 0,
|
|
5113
|
+
type: "aave"
|
|
5114
|
+
};
|
|
5115
|
+
onDeposit?.(depositMarket, parseFloat(amount), txHash || "");
|
|
4213
5116
|
} else {
|
|
4214
|
-
|
|
5117
|
+
const withdrawMarket = {
|
|
5118
|
+
id: "aave-usdc",
|
|
5119
|
+
name: "USDC",
|
|
5120
|
+
apy: parseFloat(market.supplyApy || "0"),
|
|
5121
|
+
tvl: 0,
|
|
5122
|
+
type: "aave"
|
|
5123
|
+
};
|
|
5124
|
+
onWithdraw?.(withdrawMarket, parseFloat(amount), txHash || "");
|
|
4215
5125
|
}
|
|
4216
5126
|
setTimeout(() => setStatusMessage(""), 3e3);
|
|
4217
5127
|
} catch (err) {
|
|
@@ -4221,7 +5131,7 @@ function EarnAccount({
|
|
|
4221
5131
|
setIsProcessing(false);
|
|
4222
5132
|
}
|
|
4223
5133
|
};
|
|
4224
|
-
const maxAmount = activeTab === "deposit" ?
|
|
5134
|
+
const maxAmount = activeTab === "deposit" ? parseFloat(selectedTokenBalance) : depositedBalance;
|
|
4225
5135
|
if (marketQuery.isLoading) {
|
|
4226
5136
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 32, className: "animate-spin", style: { color: "var(--compass-color-primary)" } }) });
|
|
4227
5137
|
}
|
|
@@ -4240,7 +5150,7 @@ function EarnAccount({
|
|
|
4240
5150
|
}
|
|
4241
5151
|
const spacing = compact ? "calc(var(--compass-spacing-unit) * 0.75)" : "var(--compass-spacing-card)";
|
|
4242
5152
|
const gapSize = compact ? "calc(var(--compass-spacing-unit) * 0.75)" : "calc(var(--compass-spacing-unit) * 1.5)";
|
|
4243
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", style: { gap: gapSize, fontFamily: "var(--compass-font-family)" }, children: [
|
|
5153
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col w-full", style: { gap: gapSize, fontFamily: "var(--compass-font-family)" }, children: [
|
|
4244
5154
|
showHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
4245
5155
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
4246
5156
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4276,28 +5186,39 @@ function EarnAccount({
|
|
|
4276
5186
|
padding: compact ? "var(--compass-spacing-card)" : "calc(var(--compass-spacing-card) * 1.25)"
|
|
4277
5187
|
},
|
|
4278
5188
|
children: [
|
|
4279
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
},
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
5189
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5190
|
+
"button",
|
|
5191
|
+
{
|
|
5192
|
+
onClick: () => setIsBalancesModalOpen(true),
|
|
5193
|
+
className: "flex flex-col text-left w-full transition-opacity hover:opacity-80",
|
|
5194
|
+
style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" },
|
|
5195
|
+
children: [
|
|
5196
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
5197
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5198
|
+
"span",
|
|
5199
|
+
{
|
|
5200
|
+
className: "text-xs font-medium uppercase tracking-wide",
|
|
5201
|
+
style: { color: "var(--compass-color-text-tertiary)" },
|
|
5202
|
+
children: "Total Balance"
|
|
5203
|
+
}
|
|
5204
|
+
),
|
|
5205
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: 12, style: { color: "var(--compass-color-text-tertiary)" } })
|
|
5206
|
+
] }),
|
|
5207
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5208
|
+
"span",
|
|
5209
|
+
{
|
|
5210
|
+
className: "font-bold",
|
|
5211
|
+
style: {
|
|
5212
|
+
color: "var(--compass-color-text)",
|
|
5213
|
+
fontSize: compact ? "2rem" : "2.5rem",
|
|
5214
|
+
lineHeight: "1"
|
|
5215
|
+
},
|
|
5216
|
+
children: formatCurrency(totalBalance)
|
|
5217
|
+
}
|
|
5218
|
+
)
|
|
5219
|
+
]
|
|
5220
|
+
}
|
|
5221
|
+
),
|
|
4301
5222
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4302
5223
|
"div",
|
|
4303
5224
|
{
|
|
@@ -4354,48 +5275,61 @@ function EarnAccount({
|
|
|
4354
5275
|
]
|
|
4355
5276
|
}
|
|
4356
5277
|
),
|
|
4357
|
-
|
|
4358
|
-
"
|
|
5278
|
+
positions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5279
|
+
"button",
|
|
4359
5280
|
{
|
|
4360
|
-
|
|
5281
|
+
onClick: () => setIsEarningsModalOpen(true),
|
|
5282
|
+
className: "w-full flex items-center justify-between transition-opacity hover:opacity-80",
|
|
4361
5283
|
style: {
|
|
4362
5284
|
backgroundColor: "var(--compass-color-surface)",
|
|
4363
5285
|
border: "1px solid var(--compass-color-border)",
|
|
4364
5286
|
borderRadius: "var(--compass-border-radius-lg)",
|
|
4365
|
-
padding: spacing
|
|
5287
|
+
padding: compact ? "calc(var(--compass-spacing-unit) * 0.75)" : "var(--compass-spacing-card)"
|
|
4366
5288
|
},
|
|
4367
5289
|
children: [
|
|
4368
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
5290
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
5291
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: "var(--compass-color-text)" }, children: [
|
|
5292
|
+
positions.length,
|
|
5293
|
+
" ",
|
|
5294
|
+
positions.length === 1 ? "position" : "positions"
|
|
5295
|
+
] }),
|
|
5296
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--compass-color-text-tertiary)" }, children: "|" }),
|
|
5297
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5298
|
+
"span",
|
|
5299
|
+
{
|
|
5300
|
+
style: {
|
|
5301
|
+
color: totalEarned >= 0 ? "var(--compass-color-success)" : "var(--compass-color-error)",
|
|
5302
|
+
fontWeight: 500
|
|
5303
|
+
},
|
|
5304
|
+
children: [
|
|
5305
|
+
totalEarned >= 0 ? "+" : "",
|
|
5306
|
+
"$",
|
|
5307
|
+
totalEarned.toFixed(2),
|
|
5308
|
+
" earned"
|
|
5309
|
+
]
|
|
5310
|
+
}
|
|
5311
|
+
)
|
|
5312
|
+
] }),
|
|
5313
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { size: 16, style: { color: "var(--compass-color-text-tertiary)" } })
|
|
4380
5314
|
]
|
|
4381
5315
|
}
|
|
4382
5316
|
),
|
|
4383
|
-
|
|
4384
|
-
|
|
5317
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5318
|
+
MarketSelector,
|
|
4385
5319
|
{
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
5320
|
+
markets: mockMarkets,
|
|
5321
|
+
selectedMarket,
|
|
5322
|
+
onMarketSelect: setSelectedMarket,
|
|
5323
|
+
marketType,
|
|
5324
|
+
onMarketTypeChange: (type) => {
|
|
5325
|
+
setMarketType(type);
|
|
5326
|
+
setSelectedMarket(null);
|
|
5327
|
+
},
|
|
5328
|
+
minTvl,
|
|
5329
|
+
onMinTvlChange: setMinTvl,
|
|
5330
|
+
isLoading: marketQuery.isLoading
|
|
4389
5331
|
}
|
|
4390
5332
|
),
|
|
4391
|
-
userPosition?.deposits?.length || userPosition?.withdrawals?.length ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4392
|
-
TransactionHistory,
|
|
4393
|
-
{
|
|
4394
|
-
deposits: userPosition.deposits,
|
|
4395
|
-
withdrawals: userPosition.withdrawals,
|
|
4396
|
-
tokenSymbol: "USDC"
|
|
4397
|
-
}
|
|
4398
|
-
) : null,
|
|
4399
5333
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4400
5334
|
"div",
|
|
4401
5335
|
{
|
|
@@ -4412,6 +5346,7 @@ function EarnAccount({
|
|
|
4412
5346
|
{
|
|
4413
5347
|
onClick: () => {
|
|
4414
5348
|
setActiveTab("deposit");
|
|
5349
|
+
setSelectedToken("USDC");
|
|
4415
5350
|
setError(null);
|
|
4416
5351
|
},
|
|
4417
5352
|
className: "flex-1 flex items-center justify-center font-medium transition-all",
|
|
@@ -4435,6 +5370,7 @@ function EarnAccount({
|
|
|
4435
5370
|
{
|
|
4436
5371
|
onClick: () => {
|
|
4437
5372
|
setActiveTab("withdraw");
|
|
5373
|
+
setSelectedToken("USDC");
|
|
4438
5374
|
setError(null);
|
|
4439
5375
|
},
|
|
4440
5376
|
className: "flex-1 flex items-center justify-center font-medium transition-all",
|
|
@@ -4460,22 +5396,15 @@ function EarnAccount({
|
|
|
4460
5396
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4461
5397
|
"div",
|
|
4462
5398
|
{
|
|
4463
|
-
className: "flex items-center",
|
|
5399
|
+
className: "flex items-center flex-wrap",
|
|
4464
5400
|
style: {
|
|
4465
5401
|
backgroundColor: "var(--compass-color-surface)",
|
|
4466
5402
|
border: "1px solid var(--compass-color-border)",
|
|
4467
5403
|
borderRadius: "var(--compass-border-radius-lg)",
|
|
4468
|
-
padding: spacing
|
|
5404
|
+
padding: spacing,
|
|
5405
|
+
gap: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
4469
5406
|
},
|
|
4470
5407
|
children: [
|
|
4471
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4472
|
-
"span",
|
|
4473
|
-
{
|
|
4474
|
-
className: "font-medium",
|
|
4475
|
-
style: { color: "var(--compass-color-text-secondary)", fontSize: compact ? "1.25rem" : "1.5rem", marginRight: "calc(var(--compass-spacing-unit) * 0.25)" },
|
|
4476
|
-
children: "$"
|
|
4477
|
-
}
|
|
4478
|
-
),
|
|
4479
5408
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4480
5409
|
"input",
|
|
4481
5410
|
{
|
|
@@ -4488,9 +5417,64 @@ function EarnAccount({
|
|
|
4488
5417
|
placeholder: "0.00",
|
|
4489
5418
|
disabled: isProcessing,
|
|
4490
5419
|
className: "flex-1 font-medium bg-transparent outline-none",
|
|
4491
|
-
style: { color: "var(--compass-color-text)", fontSize: compact ? "1.25rem" : "1.5rem" }
|
|
5420
|
+
style: { color: "var(--compass-color-text)", fontSize: compact ? "1.25rem" : "1.5rem", minWidth: 0 }
|
|
4492
5421
|
}
|
|
4493
5422
|
),
|
|
5423
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", style: { flexShrink: 0 }, children: [
|
|
5424
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5425
|
+
"button",
|
|
5426
|
+
{
|
|
5427
|
+
onClick: () => setIsTokenDropdownOpen(!isTokenDropdownOpen),
|
|
5428
|
+
disabled: isProcessing,
|
|
5429
|
+
className: "flex items-center font-medium",
|
|
5430
|
+
style: {
|
|
5431
|
+
backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-background))",
|
|
5432
|
+
border: "1px solid var(--compass-color-border)",
|
|
5433
|
+
color: "var(--compass-color-text)",
|
|
5434
|
+
borderRadius: "var(--compass-border-radius-md)",
|
|
5435
|
+
padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
|
|
5436
|
+
gap: "calc(var(--compass-spacing-unit) * 0.25)",
|
|
5437
|
+
fontSize: compact ? "0.875rem" : "1rem"
|
|
5438
|
+
},
|
|
5439
|
+
children: [
|
|
5440
|
+
selectedToken,
|
|
5441
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: compact ? 14 : 16, style: { color: "var(--compass-color-text-tertiary)" } })
|
|
5442
|
+
]
|
|
5443
|
+
}
|
|
5444
|
+
),
|
|
5445
|
+
isTokenDropdownOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5446
|
+
"div",
|
|
5447
|
+
{
|
|
5448
|
+
className: "absolute right-0 mt-1 z-10",
|
|
5449
|
+
style: {
|
|
5450
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
5451
|
+
border: "1px solid var(--compass-color-border)",
|
|
5452
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
5453
|
+
boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
|
|
5454
|
+
minWidth: "100px"
|
|
5455
|
+
},
|
|
5456
|
+
children: SUPPORTED_TOKENS.map((token) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5457
|
+
"button",
|
|
5458
|
+
{
|
|
5459
|
+
onClick: () => {
|
|
5460
|
+
setSelectedToken(token);
|
|
5461
|
+
setIsTokenDropdownOpen(false);
|
|
5462
|
+
setError(null);
|
|
5463
|
+
},
|
|
5464
|
+
className: "w-full text-left font-medium transition-colors",
|
|
5465
|
+
style: {
|
|
5466
|
+
padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
|
|
5467
|
+
color: token === selectedToken ? "var(--compass-color-primary)" : "var(--compass-color-text)",
|
|
5468
|
+
backgroundColor: token === selectedToken ? "var(--compass-color-primary-muted, rgba(99, 102, 241, 0.1))" : "transparent",
|
|
5469
|
+
fontSize: compact ? "0.875rem" : "1rem"
|
|
5470
|
+
},
|
|
5471
|
+
children: token
|
|
5472
|
+
},
|
|
5473
|
+
token
|
|
5474
|
+
))
|
|
5475
|
+
}
|
|
5476
|
+
)
|
|
5477
|
+
] }),
|
|
4494
5478
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4495
5479
|
"button",
|
|
4496
5480
|
{
|
|
@@ -4502,7 +5486,8 @@ function EarnAccount({
|
|
|
4502
5486
|
border: "1px solid var(--compass-color-border)",
|
|
4503
5487
|
color: "var(--compass-color-text-secondary)",
|
|
4504
5488
|
borderRadius: "var(--compass-border-radius-md)",
|
|
4505
|
-
padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)"
|
|
5489
|
+
padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
|
|
5490
|
+
flexShrink: 0
|
|
4506
5491
|
},
|
|
4507
5492
|
children: "MAX"
|
|
4508
5493
|
}
|
|
@@ -4510,9 +5495,30 @@ function EarnAccount({
|
|
|
4510
5495
|
]
|
|
4511
5496
|
}
|
|
4512
5497
|
),
|
|
5498
|
+
needsActionSwap && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5499
|
+
"div",
|
|
5500
|
+
{
|
|
5501
|
+
className: "flex items-center text-sm",
|
|
5502
|
+
style: {
|
|
5503
|
+
backgroundColor: "var(--compass-color-primary-muted, rgba(99, 102, 241, 0.1))",
|
|
5504
|
+
color: "var(--compass-color-primary)",
|
|
5505
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
5506
|
+
padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
|
|
5507
|
+
gap: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
5508
|
+
},
|
|
5509
|
+
children: [
|
|
5510
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { size: 14 }),
|
|
5511
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: activeTab === "deposit" ? `Swaps ${selectedToken} to USDC, then deposits` : `Withdraws USDC, then swaps to ${selectedToken}` })
|
|
5512
|
+
]
|
|
5513
|
+
}
|
|
5514
|
+
),
|
|
4513
5515
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", style: { padding: "0 calc(var(--compass-spacing-unit) * 0.25)" }, children: [
|
|
4514
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", style: { color: "var(--compass-color-text-tertiary)" }, children: "Available
|
|
4515
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5516
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", style: { color: "var(--compass-color-text-tertiary)" }, children: activeTab === "deposit" ? `Available ${selectedToken}` : "Available to withdraw" }),
|
|
5517
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-medium", style: { color: "var(--compass-color-text-secondary)" }, children: [
|
|
5518
|
+
formatAmount2(maxAmount),
|
|
5519
|
+
" ",
|
|
5520
|
+
activeTab === "deposit" ? selectedToken : "USDC"
|
|
5521
|
+
] })
|
|
4516
5522
|
] })
|
|
4517
5523
|
] }),
|
|
4518
5524
|
error && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4545,7 +5551,7 @@ function EarnAccount({
|
|
|
4545
5551
|
children: isProcessing ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
4546
5552
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: compact ? 16 : 20, className: "animate-spin" }),
|
|
4547
5553
|
"Processing..."
|
|
4548
|
-
] }) : activeTab === "deposit" ? "Deposit funds" : "Withdraw funds"
|
|
5554
|
+
] }) : needsActionSwap ? activeTab === "deposit" ? `Swap & Deposit` : `Withdraw & Swap` : activeTab === "deposit" ? "Deposit funds" : "Withdraw funds"
|
|
4549
5555
|
}
|
|
4550
5556
|
),
|
|
4551
5557
|
statusMessage && !error && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4582,7 +5588,7 @@ function EarnAccount({
|
|
|
4582
5588
|
]
|
|
4583
5589
|
}
|
|
4584
5590
|
),
|
|
4585
|
-
|
|
5591
|
+
showTopUpButton && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4586
5592
|
"button",
|
|
4587
5593
|
{
|
|
4588
5594
|
onClick: () => setIsFundModalOpen(true),
|
|
@@ -4598,7 +5604,7 @@ function EarnAccount({
|
|
|
4598
5604
|
},
|
|
4599
5605
|
children: [
|
|
4600
5606
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { size: compact ? 16 : 18 }),
|
|
4601
|
-
"
|
|
5607
|
+
"Top Up"
|
|
4602
5608
|
]
|
|
4603
5609
|
}
|
|
4604
5610
|
)
|
|
@@ -4666,7 +5672,7 @@ function EarnAccount({
|
|
|
4666
5672
|
}
|
|
4667
5673
|
)
|
|
4668
5674
|
] }),
|
|
4669
|
-
|
|
5675
|
+
needsFundSwap && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4670
5676
|
"div",
|
|
4671
5677
|
{
|
|
4672
5678
|
className: "flex items-center gap-2 p-3 rounded-xl text-sm",
|
|
@@ -4778,7 +5784,7 @@ function EarnAccount({
|
|
|
4778
5784
|
"Processing..."
|
|
4779
5785
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
|
|
4780
5786
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDownLeft, { size: 20 }),
|
|
4781
|
-
|
|
5787
|
+
needsFundSwap ? `Swap ${fundToken} & Transfer` : "Transfer to Savings"
|
|
4782
5788
|
] })
|
|
4783
5789
|
}
|
|
4784
5790
|
),
|
|
@@ -4792,6 +5798,125 @@ function EarnAccount({
|
|
|
4792
5798
|
)
|
|
4793
5799
|
] })
|
|
4794
5800
|
}
|
|
5801
|
+
),
|
|
5802
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5803
|
+
ActionModal,
|
|
5804
|
+
{
|
|
5805
|
+
isOpen: isBalancesModalOpen,
|
|
5806
|
+
onClose: () => setIsBalancesModalOpen(false),
|
|
5807
|
+
title: "Balance Breakdown",
|
|
5808
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
5809
|
+
balancesQuery.data?.balances && Object.keys(balancesQuery.data.balances).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5810
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
5811
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5812
|
+
"span",
|
|
5813
|
+
{
|
|
5814
|
+
className: "text-xs font-medium uppercase tracking-wide",
|
|
5815
|
+
style: { color: "var(--compass-color-text-tertiary)" },
|
|
5816
|
+
children: "Available in Account"
|
|
5817
|
+
}
|
|
5818
|
+
),
|
|
5819
|
+
Object.entries(balancesQuery.data.balances).map(([symbol, data]) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5820
|
+
"div",
|
|
5821
|
+
{
|
|
5822
|
+
className: "flex items-center justify-between p-3 rounded-lg",
|
|
5823
|
+
style: {
|
|
5824
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
5825
|
+
border: "1px solid var(--compass-color-border)"
|
|
5826
|
+
},
|
|
5827
|
+
children: [
|
|
5828
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", style: { color: "var(--compass-color-text)" }, children: symbol }),
|
|
5829
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end", children: [
|
|
5830
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-text)" }, children: formatAmount2(data.balance) }),
|
|
5831
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: formatCurrency(data.usdValue) })
|
|
5832
|
+
] })
|
|
5833
|
+
]
|
|
5834
|
+
},
|
|
5835
|
+
symbol
|
|
5836
|
+
))
|
|
5837
|
+
] }),
|
|
5838
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5839
|
+
"div",
|
|
5840
|
+
{
|
|
5841
|
+
className: "flex items-center justify-between pt-2",
|
|
5842
|
+
style: { borderTop: "1px solid var(--compass-color-border)" },
|
|
5843
|
+
children: [
|
|
5844
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", style: { color: "var(--compass-color-text-secondary)" }, children: "Subtotal" }),
|
|
5845
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", style: { color: "var(--compass-color-text)" }, children: formatCurrency(earnAccountTotalUsd) })
|
|
5846
|
+
]
|
|
5847
|
+
}
|
|
5848
|
+
)
|
|
5849
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
5850
|
+
"div",
|
|
5851
|
+
{
|
|
5852
|
+
className: "text-center py-4",
|
|
5853
|
+
style: { color: "var(--compass-color-text-tertiary)" },
|
|
5854
|
+
children: "No tokens in account"
|
|
5855
|
+
}
|
|
5856
|
+
),
|
|
5857
|
+
depositedBalance > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 pt-2", style: { borderTop: "1px solid var(--compass-color-border)" }, children: [
|
|
5858
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5859
|
+
"span",
|
|
5860
|
+
{
|
|
5861
|
+
className: "text-xs font-medium uppercase tracking-wide",
|
|
5862
|
+
style: { color: "var(--compass-color-text-tertiary)" },
|
|
5863
|
+
children: "Earning Interest (Aave)"
|
|
5864
|
+
}
|
|
5865
|
+
),
|
|
5866
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5867
|
+
"div",
|
|
5868
|
+
{
|
|
5869
|
+
className: "flex items-center justify-between p-3 rounded-lg",
|
|
5870
|
+
style: {
|
|
5871
|
+
backgroundColor: "var(--compass-color-success-muted, rgba(34, 197, 94, 0.1))",
|
|
5872
|
+
border: "1px solid var(--compass-color-success)"
|
|
5873
|
+
},
|
|
5874
|
+
children: [
|
|
5875
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
5876
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrendingUp, { size: 16, style: { color: "var(--compass-color-success)" } }),
|
|
5877
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", style: { color: "var(--compass-color-text)" }, children: "USDC" })
|
|
5878
|
+
] }),
|
|
5879
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end", children: [
|
|
5880
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-text)" }, children: formatAmount2(depositedBalance) }),
|
|
5881
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs", style: { color: "var(--compass-color-success)" }, children: [
|
|
5882
|
+
formatAPY3(market?.supplyApy || null),
|
|
5883
|
+
"% APY"
|
|
5884
|
+
] })
|
|
5885
|
+
] })
|
|
5886
|
+
]
|
|
5887
|
+
}
|
|
5888
|
+
)
|
|
5889
|
+
] }),
|
|
5890
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5891
|
+
"div",
|
|
5892
|
+
{
|
|
5893
|
+
className: "flex items-center justify-between pt-3 mt-2",
|
|
5894
|
+
style: { borderTop: "2px solid var(--compass-color-border)" },
|
|
5895
|
+
children: [
|
|
5896
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", style: { color: "var(--compass-color-text)" }, children: "Total Balance" }),
|
|
5897
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5898
|
+
"span",
|
|
5899
|
+
{
|
|
5900
|
+
className: "font-bold text-xl",
|
|
5901
|
+
style: { color: "var(--compass-color-text)" },
|
|
5902
|
+
children: formatCurrency(totalBalance)
|
|
5903
|
+
}
|
|
5904
|
+
)
|
|
5905
|
+
]
|
|
5906
|
+
}
|
|
5907
|
+
)
|
|
5908
|
+
] })
|
|
5909
|
+
}
|
|
5910
|
+
),
|
|
5911
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5912
|
+
EarningsModal,
|
|
5913
|
+
{
|
|
5914
|
+
isOpen: isEarningsModalOpen,
|
|
5915
|
+
onClose: () => setIsEarningsModalOpen(false),
|
|
5916
|
+
positions,
|
|
5917
|
+
totalEarned,
|
|
5918
|
+
isLoading: positionQuery.isLoading
|
|
5919
|
+
}
|
|
4795
5920
|
)
|
|
4796
5921
|
] });
|
|
4797
5922
|
}
|
|
@@ -5804,7 +6929,7 @@ function usePositionsData() {
|
|
|
5804
6929
|
refetch: positionsQuery.refetch
|
|
5805
6930
|
};
|
|
5806
6931
|
}
|
|
5807
|
-
function
|
|
6932
|
+
function PositionCard2({
|
|
5808
6933
|
position,
|
|
5809
6934
|
showApy = true,
|
|
5810
6935
|
showPnL = true,
|
|
@@ -5979,7 +7104,7 @@ function VenueSection({
|
|
|
5979
7104
|
children: [
|
|
5980
7105
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-3" }),
|
|
5981
7106
|
venuePositions.positions.map((position) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5982
|
-
|
|
7107
|
+
PositionCard2,
|
|
5983
7108
|
{
|
|
5984
7109
|
position,
|
|
5985
7110
|
showApy,
|