@compass-labs/widgets 0.1.32 → 0.1.34
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 +55 -58
- package/dist/index.d.ts +55 -58
- package/dist/index.js +948 -727
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +948 -727
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.js +20 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +20 -4
- package/dist/server/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -992,9 +992,52 @@ function ChainSwitcher() {
|
|
|
992
992
|
}
|
|
993
993
|
);
|
|
994
994
|
}
|
|
995
|
-
function
|
|
995
|
+
function truncateAddr(address) {
|
|
996
996
|
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
997
997
|
}
|
|
998
|
+
function CopyableAddress({
|
|
999
|
+
address,
|
|
1000
|
+
label,
|
|
1001
|
+
truncate = true,
|
|
1002
|
+
textSize = "text-xs"
|
|
1003
|
+
}) {
|
|
1004
|
+
const [copied, setCopied] = react.useState(false);
|
|
1005
|
+
const handleCopy = react.useCallback(() => {
|
|
1006
|
+
navigator.clipboard.writeText(address);
|
|
1007
|
+
setCopied(true);
|
|
1008
|
+
setTimeout(() => setCopied(false), 1500);
|
|
1009
|
+
}, [address]);
|
|
1010
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", style: { gap: "2px" }, children: [
|
|
1011
|
+
label && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1012
|
+
"span",
|
|
1013
|
+
{
|
|
1014
|
+
className: "text-xs",
|
|
1015
|
+
style: { color: "var(--compass-color-text-tertiary)", fontSize: "10px" },
|
|
1016
|
+
children: label
|
|
1017
|
+
}
|
|
1018
|
+
),
|
|
1019
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1020
|
+
"button",
|
|
1021
|
+
{
|
|
1022
|
+
onClick: handleCopy,
|
|
1023
|
+
className: `inline-flex items-center font-mono ${textSize}`,
|
|
1024
|
+
style: {
|
|
1025
|
+
color: "var(--compass-color-text-secondary)",
|
|
1026
|
+
background: "none",
|
|
1027
|
+
border: "none",
|
|
1028
|
+
cursor: "pointer",
|
|
1029
|
+
padding: 0,
|
|
1030
|
+
gap: "4px"
|
|
1031
|
+
},
|
|
1032
|
+
title: copied ? "Copied!" : `Copy: ${address}`,
|
|
1033
|
+
children: [
|
|
1034
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: truncate ? truncateAddr(address) : address }),
|
|
1035
|
+
copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { size: 10, className: "flex-shrink-0", style: { color: "var(--compass-color-success)" } }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { size: 10, className: "flex-shrink-0", style: { color: "var(--compass-color-text-tertiary)" } })
|
|
1036
|
+
]
|
|
1037
|
+
}
|
|
1038
|
+
)
|
|
1039
|
+
] });
|
|
1040
|
+
}
|
|
998
1041
|
function WalletStatus({
|
|
999
1042
|
showFullAddress = false,
|
|
1000
1043
|
showLogout = true,
|
|
@@ -1071,11 +1114,11 @@ function WalletStatus({
|
|
|
1071
1114
|
}
|
|
1072
1115
|
),
|
|
1073
1116
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1074
|
-
|
|
1117
|
+
CopyableAddress,
|
|
1075
1118
|
{
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1119
|
+
address,
|
|
1120
|
+
truncate: !showFullAddress,
|
|
1121
|
+
textSize: compact ? "text-xs" : "text-sm"
|
|
1079
1122
|
}
|
|
1080
1123
|
),
|
|
1081
1124
|
showLogout && disconnectFn !== null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1111,68 +1154,75 @@ function ActionModal({ isOpen, onClose, title, children }) {
|
|
|
1111
1154
|
};
|
|
1112
1155
|
}, [isOpen, onClose]);
|
|
1113
1156
|
if (!isOpen) return null;
|
|
1114
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1157
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1158
|
+
"div",
|
|
1159
|
+
{
|
|
1160
|
+
className: "fixed inset-0 z-50 flex items-center justify-center p-4",
|
|
1161
|
+
style: { overflowY: "auto", scrollbarWidth: "none" },
|
|
1162
|
+
children: [
|
|
1163
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1164
|
+
"div",
|
|
1165
|
+
{
|
|
1166
|
+
className: "absolute inset-0",
|
|
1167
|
+
style: { backgroundColor: "var(--compass-color-overlay)" },
|
|
1168
|
+
onClick: onClose
|
|
1169
|
+
}
|
|
1170
|
+
),
|
|
1171
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1172
|
+
"div",
|
|
1173
|
+
{
|
|
1174
|
+
className: "relative w-full max-w-md",
|
|
1175
|
+
style: {
|
|
1176
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
1177
|
+
boxShadow: "var(--compass-shadow-lg)",
|
|
1178
|
+
borderRadius: "var(--compass-border-radius-xl)",
|
|
1179
|
+
fontFamily: "var(--compass-font-family)"
|
|
1180
|
+
},
|
|
1181
|
+
children: [
|
|
1182
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1183
|
+
"div",
|
|
1184
|
+
{
|
|
1185
|
+
className: "flex items-center justify-between border-b",
|
|
1186
|
+
style: {
|
|
1187
|
+
borderColor: "var(--compass-color-border)",
|
|
1188
|
+
padding: "calc(var(--compass-spacing-card) * 0.75) var(--compass-spacing-card)"
|
|
1189
|
+
},
|
|
1190
|
+
children: [
|
|
1191
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1192
|
+
"h2",
|
|
1193
|
+
{
|
|
1194
|
+
className: "font-semibold",
|
|
1195
|
+
style: {
|
|
1196
|
+
fontSize: "var(--compass-font-size-subheading)",
|
|
1197
|
+
color: "var(--compass-color-text)"
|
|
1198
|
+
},
|
|
1199
|
+
children: title
|
|
1200
|
+
}
|
|
1201
|
+
),
|
|
1202
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1203
|
+
"button",
|
|
1204
|
+
{
|
|
1205
|
+
onClick: onClose,
|
|
1206
|
+
className: "hover:opacity-70",
|
|
1207
|
+
style: {
|
|
1208
|
+
color: "var(--compass-color-text-secondary)",
|
|
1209
|
+
borderRadius: "var(--compass-border-radius-md)",
|
|
1210
|
+
padding: "calc(var(--compass-spacing-unit) * 0.25)",
|
|
1211
|
+
transition: "var(--compass-transition-normal)"
|
|
1212
|
+
},
|
|
1213
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 20 })
|
|
1214
|
+
}
|
|
1215
|
+
)
|
|
1216
|
+
]
|
|
1217
|
+
}
|
|
1218
|
+
),
|
|
1219
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "var(--compass-spacing-card)" }, children })
|
|
1220
|
+
]
|
|
1221
|
+
}
|
|
1222
|
+
)
|
|
1223
|
+
]
|
|
1224
|
+
}
|
|
1225
|
+
);
|
|
1176
1226
|
}
|
|
1177
1227
|
function PnLSummary({ pnl, tokenSymbol, tokenPrice }) {
|
|
1178
1228
|
const [isExpanded, setIsExpanded] = react.useState(false);
|
|
@@ -2233,226 +2283,98 @@ function AccountBalancesModal({
|
|
|
2233
2283
|
balances,
|
|
2234
2284
|
totalUsdValue,
|
|
2235
2285
|
isLoading = false,
|
|
2236
|
-
earnAccountAddress
|
|
2286
|
+
earnAccountAddress,
|
|
2287
|
+
walletAddress
|
|
2237
2288
|
}) {
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
if (e.key === "Escape") onClose();
|
|
2241
|
-
};
|
|
2242
|
-
if (isOpen) {
|
|
2243
|
-
document.addEventListener("keydown", handleEscape);
|
|
2244
|
-
document.body.style.overflow = "hidden";
|
|
2245
|
-
}
|
|
2246
|
-
return () => {
|
|
2247
|
-
document.removeEventListener("keydown", handleEscape);
|
|
2248
|
-
document.body.style.overflow = "";
|
|
2249
|
-
};
|
|
2250
|
-
}, [isOpen, onClose]);
|
|
2251
|
-
if (!isOpen) return null;
|
|
2252
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
|
|
2253
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2289
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ActionModal, { isOpen, onClose, title: "Balance Breakdown", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
2290
|
+
(walletAddress || earnAccountAddress) && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2254
2291
|
"div",
|
|
2255
2292
|
{
|
|
2256
|
-
className: "
|
|
2257
|
-
style: {
|
|
2258
|
-
|
|
2293
|
+
className: "flex flex-col gap-2 pb-3",
|
|
2294
|
+
style: { borderBottom: "1px solid var(--compass-color-border)" },
|
|
2295
|
+
children: [
|
|
2296
|
+
walletAddress && /* @__PURE__ */ jsxRuntime.jsx(CopyableAddress, { address: walletAddress, label: "Wallet" }),
|
|
2297
|
+
earnAccountAddress && /* @__PURE__ */ jsxRuntime.jsx(CopyableAddress, { address: earnAccountAddress, label: "Product Account" })
|
|
2298
|
+
]
|
|
2259
2299
|
}
|
|
2260
2300
|
),
|
|
2261
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2301
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2302
|
+
lucideReact.Loader2,
|
|
2303
|
+
{
|
|
2304
|
+
size: 24,
|
|
2305
|
+
className: "animate-spin",
|
|
2306
|
+
style: { color: "var(--compass-color-primary)" }
|
|
2307
|
+
}
|
|
2308
|
+
) }) : balances.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2262
2309
|
"div",
|
|
2263
2310
|
{
|
|
2264
|
-
className: "
|
|
2265
|
-
style: {
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
"
|
|
2274
|
-
{
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
},
|
|
2289
|
-
children: [
|
|
2290
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Coins, { size: 20 }),
|
|
2291
|
-
"Account Balances"
|
|
2292
|
-
]
|
|
2293
|
-
}
|
|
2294
|
-
),
|
|
2295
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2296
|
-
"button",
|
|
2297
|
-
{
|
|
2298
|
-
onClick: onClose,
|
|
2299
|
-
className: "hover:opacity-70",
|
|
2300
|
-
style: {
|
|
2301
|
-
color: "var(--compass-color-text-secondary)",
|
|
2302
|
-
borderRadius: "var(--compass-border-radius-md)",
|
|
2303
|
-
padding: "calc(var(--compass-spacing-unit) * 0.25)",
|
|
2304
|
-
transition: "var(--compass-transition-normal)"
|
|
2305
|
-
},
|
|
2306
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 20 })
|
|
2307
|
-
}
|
|
2308
|
-
)
|
|
2309
|
-
]
|
|
2310
|
-
}
|
|
2311
|
-
),
|
|
2312
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "var(--compass-spacing-card)" }, children: [
|
|
2313
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", style: { padding: "calc(var(--compass-spacing-unit) * 2) 0" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2314
|
-
lucideReact.Loader2,
|
|
2315
|
-
{
|
|
2316
|
-
size: 24,
|
|
2317
|
-
className: "animate-spin",
|
|
2318
|
-
style: { color: "var(--compass-color-primary)" }
|
|
2319
|
-
}
|
|
2320
|
-
) }) : balances.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2321
|
-
"div",
|
|
2322
|
-
{
|
|
2323
|
-
className: "text-center",
|
|
2324
|
-
style: { color: "var(--compass-color-text-secondary)", padding: "calc(var(--compass-spacing-unit) * 2) 0" },
|
|
2325
|
-
children: "No token balances found"
|
|
2326
|
-
}
|
|
2327
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
2328
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2329
|
-
"div",
|
|
2330
|
-
{
|
|
2331
|
-
className: "flex items-center justify-between border",
|
|
2332
|
-
style: {
|
|
2333
|
-
borderColor: "var(--compass-color-border)",
|
|
2334
|
-
backgroundColor: "var(--compass-color-surface)",
|
|
2335
|
-
borderRadius: "var(--compass-border-radius-lg)",
|
|
2336
|
-
padding: "calc(var(--compass-spacing-unit) * 1)",
|
|
2337
|
-
marginBottom: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
2338
|
-
},
|
|
2339
|
-
children: [
|
|
2340
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2341
|
-
"span",
|
|
2342
|
-
{
|
|
2343
|
-
className: "font-medium",
|
|
2344
|
-
style: { color: "var(--compass-color-text-secondary)" },
|
|
2345
|
-
children: "Total Balance"
|
|
2346
|
-
}
|
|
2347
|
-
),
|
|
2348
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2349
|
-
"span",
|
|
2350
|
-
{
|
|
2351
|
-
className: "font-bold text-xl",
|
|
2352
|
-
style: { color: "var(--compass-color-text)" },
|
|
2353
|
-
children: formatUSD(totalUsdValue)
|
|
2354
|
-
}
|
|
2355
|
-
)
|
|
2356
|
-
]
|
|
2357
|
-
}
|
|
2358
|
-
),
|
|
2359
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2360
|
-
"div",
|
|
2361
|
-
{
|
|
2362
|
-
className: "text-xs font-medium uppercase tracking-wide",
|
|
2363
|
-
style: {
|
|
2364
|
-
color: "var(--compass-color-text-tertiary)",
|
|
2365
|
-
padding: "calc(var(--compass-spacing-unit) * 0.5) 0"
|
|
2366
|
-
},
|
|
2367
|
-
children: "Token Breakdown"
|
|
2368
|
-
}
|
|
2369
|
-
),
|
|
2370
|
-
balances.map((token) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2371
|
-
"div",
|
|
2372
|
-
{
|
|
2373
|
-
className: "flex items-center justify-between",
|
|
2374
|
-
style: {
|
|
2375
|
-
backgroundColor: "var(--compass-color-background)",
|
|
2376
|
-
borderRadius: "var(--compass-border-radius-lg)",
|
|
2377
|
-
padding: "calc(var(--compass-spacing-unit) * 0.75)"
|
|
2378
|
-
},
|
|
2379
|
-
children: [
|
|
2380
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.75)" }, children: [
|
|
2381
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2382
|
-
"div",
|
|
2383
|
-
{
|
|
2384
|
-
className: "w-8 h-8 flex items-center justify-center text-xs font-bold",
|
|
2385
|
-
style: {
|
|
2386
|
-
backgroundColor: "var(--compass-color-primary-muted)",
|
|
2387
|
-
color: "var(--compass-color-primary)",
|
|
2388
|
-
borderRadius: "var(--compass-border-radius-full)"
|
|
2389
|
-
},
|
|
2390
|
-
children: token.symbol.slice(0, 2)
|
|
2391
|
-
}
|
|
2392
|
-
),
|
|
2393
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2394
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2395
|
-
"div",
|
|
2396
|
-
{
|
|
2397
|
-
className: "font-medium",
|
|
2398
|
-
style: { color: "var(--compass-color-text)" },
|
|
2399
|
-
children: token.symbol
|
|
2400
|
-
}
|
|
2401
|
-
),
|
|
2402
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2403
|
-
"div",
|
|
2404
|
-
{
|
|
2405
|
-
className: "text-sm font-mono",
|
|
2406
|
-
style: { color: "var(--compass-color-text-secondary)" },
|
|
2407
|
-
children: formatAmount(token.balance)
|
|
2408
|
-
}
|
|
2409
|
-
)
|
|
2410
|
-
] })
|
|
2411
|
-
] }),
|
|
2412
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2413
|
-
"div",
|
|
2414
|
-
{
|
|
2415
|
-
className: "font-medium",
|
|
2416
|
-
style: { color: "var(--compass-color-text)" },
|
|
2417
|
-
children: formatUSD(token.usdValue)
|
|
2418
|
-
}
|
|
2419
|
-
)
|
|
2420
|
-
]
|
|
2421
|
-
},
|
|
2422
|
-
token.symbol
|
|
2423
|
-
))
|
|
2424
|
-
] }),
|
|
2425
|
-
earnAccountAddress && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2311
|
+
className: "text-center py-4",
|
|
2312
|
+
style: { color: "var(--compass-color-text-tertiary)" },
|
|
2313
|
+
children: "No tokens in account"
|
|
2314
|
+
}
|
|
2315
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2316
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
2317
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2318
|
+
"span",
|
|
2319
|
+
{
|
|
2320
|
+
className: "text-xs font-medium uppercase tracking-wide",
|
|
2321
|
+
style: { color: "var(--compass-color-text-tertiary)" },
|
|
2322
|
+
children: "Available in Account"
|
|
2323
|
+
}
|
|
2324
|
+
),
|
|
2325
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2326
|
+
"div",
|
|
2327
|
+
{
|
|
2328
|
+
className: "flex flex-col gap-2",
|
|
2329
|
+
style: {
|
|
2330
|
+
maxHeight: "50vh",
|
|
2331
|
+
overflowY: "auto",
|
|
2332
|
+
scrollbarWidth: "none"
|
|
2333
|
+
},
|
|
2334
|
+
children: balances.map((token) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2426
2335
|
"div",
|
|
2427
2336
|
{
|
|
2428
|
-
className: "
|
|
2337
|
+
className: "flex items-center justify-between p-3 rounded-lg",
|
|
2429
2338
|
style: {
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2339
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
2340
|
+
border: "1px solid var(--compass-color-border)",
|
|
2341
|
+
flexShrink: 0
|
|
2433
2342
|
},
|
|
2434
|
-
children:
|
|
2435
|
-
"span",
|
|
2436
|
-
{
|
|
2437
|
-
className: "
|
|
2438
|
-
style: { color: "var(--compass-color-text-tertiary)" },
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2343
|
+
children: [
|
|
2344
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", style: { color: "var(--compass-color-text)" }, children: token.symbol }),
|
|
2345
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end", children: [
|
|
2346
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-text)" }, children: formatAmount(token.balance) }),
|
|
2347
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: formatUSD(token.usdValue) })
|
|
2348
|
+
] })
|
|
2349
|
+
]
|
|
2350
|
+
},
|
|
2351
|
+
token.symbol
|
|
2352
|
+
))
|
|
2353
|
+
}
|
|
2354
|
+
)
|
|
2355
|
+
] }),
|
|
2356
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2357
|
+
"div",
|
|
2358
|
+
{
|
|
2359
|
+
className: "flex items-center justify-between pt-3 mt-2",
|
|
2360
|
+
style: { borderTop: "2px solid var(--compass-color-border)" },
|
|
2361
|
+
children: [
|
|
2362
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", style: { color: "var(--compass-color-text)" }, children: "Total" }),
|
|
2363
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2364
|
+
"span",
|
|
2365
|
+
{
|
|
2366
|
+
className: "font-bold text-xl",
|
|
2367
|
+
style: { color: "var(--compass-color-text)" },
|
|
2368
|
+
children: formatUSD(totalUsdValue)
|
|
2447
2369
|
}
|
|
2448
2370
|
)
|
|
2449
|
-
]
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
)
|
|
2453
|
-
] });
|
|
2371
|
+
]
|
|
2372
|
+
}
|
|
2373
|
+
)
|
|
2374
|
+
] })
|
|
2375
|
+
] }) });
|
|
2454
2376
|
}
|
|
2455
|
-
var TRANSFER_TOKENS = ["USDC"];
|
|
2377
|
+
var TRANSFER_TOKENS = ["USDC", "SBC"];
|
|
2456
2378
|
var EarnAccountBalance = react.forwardRef(function EarnAccountBalance2({
|
|
2457
2379
|
compact = false,
|
|
2458
2380
|
hideVisual = false,
|
|
@@ -2770,7 +2692,8 @@ var EarnAccountBalance = react.forwardRef(function EarnAccountBalance2({
|
|
|
2770
2692
|
balances: tokenBalances,
|
|
2771
2693
|
totalUsdValue: totalUsdValue.toString(),
|
|
2772
2694
|
isLoading: balancesLoading,
|
|
2773
|
-
earnAccountAddress: earnAccountAddress ?? void 0
|
|
2695
|
+
earnAccountAddress: earnAccountAddress ?? void 0,
|
|
2696
|
+
walletAddress: address ?? void 0
|
|
2774
2697
|
}
|
|
2775
2698
|
),
|
|
2776
2699
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2952,7 +2875,459 @@ var EarnAccountBalance = react.forwardRef(function EarnAccountBalance2({
|
|
|
2952
2875
|
}
|
|
2953
2876
|
)
|
|
2954
2877
|
] });
|
|
2955
|
-
});
|
|
2878
|
+
});
|
|
2879
|
+
function useSwapQuote({ fromToken, toToken, amount, enabled = true }) {
|
|
2880
|
+
const { chainId } = useChain();
|
|
2881
|
+
const { address } = useEmbeddableWallet();
|
|
2882
|
+
const query = reactQuery.useQuery({
|
|
2883
|
+
queryKey: ["swapQuote", chainId, fromToken, toToken, amount, address],
|
|
2884
|
+
queryFn: async () => {
|
|
2885
|
+
if (!fromToken || !toToken || !amount || parseFloat(amount) <= 0 || !address) {
|
|
2886
|
+
return null;
|
|
2887
|
+
}
|
|
2888
|
+
const params = new URLSearchParams({
|
|
2889
|
+
owner: address,
|
|
2890
|
+
chain: chainId,
|
|
2891
|
+
tokenIn: fromToken,
|
|
2892
|
+
tokenOut: toToken,
|
|
2893
|
+
amountIn: amount
|
|
2894
|
+
});
|
|
2895
|
+
const response = await fetch(`/api/compass/swap/quote?${params}`);
|
|
2896
|
+
if (!response.ok) {
|
|
2897
|
+
const errorData = await response.json();
|
|
2898
|
+
const errorMessage = errorData.message || errorData.error || "Failed to get swap quote";
|
|
2899
|
+
throw new Error(errorMessage);
|
|
2900
|
+
}
|
|
2901
|
+
const data = await response.json();
|
|
2902
|
+
const outputAmount = data.estimatedAmountOut || "0";
|
|
2903
|
+
const inputAmountNum = parseFloat(amount);
|
|
2904
|
+
const outputAmountNum = parseFloat(outputAmount);
|
|
2905
|
+
return {
|
|
2906
|
+
inputAmount: amount,
|
|
2907
|
+
outputAmount,
|
|
2908
|
+
rate: inputAmountNum > 0 ? (outputAmountNum / inputAmountNum).toString() : "0"
|
|
2909
|
+
};
|
|
2910
|
+
},
|
|
2911
|
+
enabled: enabled && !!address && !!fromToken && !!toToken && !!amount && parseFloat(amount) > 0,
|
|
2912
|
+
staleTime: 10 * 1e3,
|
|
2913
|
+
refetchInterval: 15 * 1e3,
|
|
2914
|
+
retry: 1
|
|
2915
|
+
});
|
|
2916
|
+
return {
|
|
2917
|
+
quote: query.data,
|
|
2918
|
+
isLoading: query.isLoading,
|
|
2919
|
+
isError: query.isError,
|
|
2920
|
+
error: query.error,
|
|
2921
|
+
refetch: query.refetch
|
|
2922
|
+
};
|
|
2923
|
+
}
|
|
2924
|
+
var COMMON_TOKENS = [
|
|
2925
|
+
"USDC",
|
|
2926
|
+
"USDT",
|
|
2927
|
+
"DAI",
|
|
2928
|
+
"USDS",
|
|
2929
|
+
"USDE",
|
|
2930
|
+
"sUSDE",
|
|
2931
|
+
"sDAI",
|
|
2932
|
+
"FRAX",
|
|
2933
|
+
"LUSD",
|
|
2934
|
+
"GUSD",
|
|
2935
|
+
"PYUSD",
|
|
2936
|
+
"crvUSD",
|
|
2937
|
+
"GHO",
|
|
2938
|
+
"EURC",
|
|
2939
|
+
"EURS",
|
|
2940
|
+
"EURA",
|
|
2941
|
+
"WETH",
|
|
2942
|
+
"WBTC",
|
|
2943
|
+
"wstETH",
|
|
2944
|
+
"cbETH",
|
|
2945
|
+
"rETH"
|
|
2946
|
+
];
|
|
2947
|
+
function SwapForm({
|
|
2948
|
+
availableFromTokens,
|
|
2949
|
+
availableToTokens,
|
|
2950
|
+
balances,
|
|
2951
|
+
defaultFromToken,
|
|
2952
|
+
defaultToToken,
|
|
2953
|
+
onSwapSuccess,
|
|
2954
|
+
onSwapError
|
|
2955
|
+
}) {
|
|
2956
|
+
const toTokens = Array.from(/* @__PURE__ */ new Set([
|
|
2957
|
+
...availableFromTokens,
|
|
2958
|
+
...COMMON_TOKENS,
|
|
2959
|
+
...availableToTokens || []
|
|
2960
|
+
]));
|
|
2961
|
+
const [fromToken, setFromToken] = react.useState(defaultFromToken || availableFromTokens[0] || "USDC");
|
|
2962
|
+
const [toToken, setToToken] = react.useState(defaultToToken || toTokens.find((t) => t !== (defaultFromToken || availableFromTokens[0])) || "USDC");
|
|
2963
|
+
const [fromAmount, setFromAmount] = react.useState("");
|
|
2964
|
+
const [isSwapping, setIsSwapping] = react.useState(false);
|
|
2965
|
+
const [swapStatus, setSwapStatus] = react.useState("");
|
|
2966
|
+
const [isFromOpen, setIsFromOpen] = react.useState(false);
|
|
2967
|
+
const [isToOpen, setIsToOpen] = react.useState(false);
|
|
2968
|
+
const { address, isConnected, signTypedData } = useEmbeddableWallet();
|
|
2969
|
+
const { chainId } = useChain();
|
|
2970
|
+
const { quote, isLoading: isQuoteLoading, error: quoteError } = useSwapQuote({
|
|
2971
|
+
fromToken,
|
|
2972
|
+
toToken,
|
|
2973
|
+
amount: fromAmount,
|
|
2974
|
+
enabled: !!fromAmount && parseFloat(fromAmount) > 0
|
|
2975
|
+
});
|
|
2976
|
+
const handleReverse = react.useCallback(() => {
|
|
2977
|
+
const oldFrom = fromToken;
|
|
2978
|
+
const oldTo = toToken;
|
|
2979
|
+
if (availableFromTokens.includes(oldTo)) {
|
|
2980
|
+
setFromToken(oldTo);
|
|
2981
|
+
setToToken(oldFrom);
|
|
2982
|
+
setFromAmount("");
|
|
2983
|
+
}
|
|
2984
|
+
}, [fromToken, toToken, availableFromTokens]);
|
|
2985
|
+
const handleSwap = react.useCallback(async () => {
|
|
2986
|
+
if (!address || !fromAmount || !quote || !signTypedData) return;
|
|
2987
|
+
setIsSwapping(true);
|
|
2988
|
+
setSwapStatus("Preparing swap...");
|
|
2989
|
+
try {
|
|
2990
|
+
const prepareResponse = await fetch("/api/compass/swap/prepare", {
|
|
2991
|
+
method: "POST",
|
|
2992
|
+
headers: { "Content-Type": "application/json" },
|
|
2993
|
+
body: JSON.stringify({
|
|
2994
|
+
owner: address,
|
|
2995
|
+
chain: chainId,
|
|
2996
|
+
tokenIn: fromToken,
|
|
2997
|
+
tokenOut: toToken,
|
|
2998
|
+
amountIn: fromAmount
|
|
2999
|
+
})
|
|
3000
|
+
});
|
|
3001
|
+
if (!prepareResponse.ok) {
|
|
3002
|
+
const error = await prepareResponse.json();
|
|
3003
|
+
throw new Error(error.error || "Failed to prepare swap");
|
|
3004
|
+
}
|
|
3005
|
+
const prepareData = await prepareResponse.json();
|
|
3006
|
+
const { eip712, normalizedTypes } = prepareData;
|
|
3007
|
+
if (!eip712) {
|
|
3008
|
+
throw new Error("No EIP-712 data returned from prepare");
|
|
3009
|
+
}
|
|
3010
|
+
setSwapStatus("Please sign the transaction...");
|
|
3011
|
+
const signature = await signTypedData({
|
|
3012
|
+
domain: eip712.domain,
|
|
3013
|
+
types: normalizedTypes || eip712.types,
|
|
3014
|
+
primaryType: "SafeTx",
|
|
3015
|
+
message: eip712.message
|
|
3016
|
+
});
|
|
3017
|
+
setSwapStatus("Executing swap...");
|
|
3018
|
+
const executeResponse = await fetch("/api/compass/swap/execute", {
|
|
3019
|
+
method: "POST",
|
|
3020
|
+
headers: { "Content-Type": "application/json" },
|
|
3021
|
+
body: JSON.stringify({
|
|
3022
|
+
owner: address,
|
|
3023
|
+
chain: chainId,
|
|
3024
|
+
eip712,
|
|
3025
|
+
signature
|
|
3026
|
+
})
|
|
3027
|
+
});
|
|
3028
|
+
if (!executeResponse.ok) {
|
|
3029
|
+
const error = await executeResponse.json();
|
|
3030
|
+
throw new Error(error.error || "Failed to execute swap");
|
|
3031
|
+
}
|
|
3032
|
+
const executeData = await executeResponse.json();
|
|
3033
|
+
const txHash = executeData.txHash;
|
|
3034
|
+
setSwapStatus("Swap successful!");
|
|
3035
|
+
onSwapSuccess?.(fromToken, toToken, fromAmount, quote.outputAmount, txHash);
|
|
3036
|
+
setFromAmount("");
|
|
3037
|
+
setTimeout(() => setSwapStatus(""), 3e3);
|
|
3038
|
+
} catch (error) {
|
|
3039
|
+
setSwapStatus("");
|
|
3040
|
+
onSwapError?.(error);
|
|
3041
|
+
} finally {
|
|
3042
|
+
setIsSwapping(false);
|
|
3043
|
+
}
|
|
3044
|
+
}, [address, fromAmount, quote, chainId, fromToken, toToken, signTypedData, onSwapSuccess, onSwapError]);
|
|
3045
|
+
const canReverse = availableFromTokens.includes(toToken);
|
|
3046
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", style: { gap: "calc(var(--compass-spacing-unit) * 0.75)" }, children: [
|
|
3047
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3048
|
+
"div",
|
|
3049
|
+
{
|
|
3050
|
+
style: {
|
|
3051
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
3052
|
+
border: "1px solid var(--compass-color-border)",
|
|
3053
|
+
borderRadius: "var(--compass-border-radius-xl)",
|
|
3054
|
+
padding: "calc(var(--compass-spacing-unit) * 0.75)"
|
|
3055
|
+
},
|
|
3056
|
+
children: [
|
|
3057
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", style: { marginBottom: "calc(var(--compass-spacing-unit) * 0.25)" }, children: [
|
|
3058
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: "From" }),
|
|
3059
|
+
balances?.[fromToken] && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: [
|
|
3060
|
+
"Balance: ",
|
|
3061
|
+
parseFloat(balances[fromToken]).toLocaleString(void 0, { maximumFractionDigits: 6 })
|
|
3062
|
+
] })
|
|
3063
|
+
] }),
|
|
3064
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
3065
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3066
|
+
"input",
|
|
3067
|
+
{
|
|
3068
|
+
type: "number",
|
|
3069
|
+
value: fromAmount,
|
|
3070
|
+
onChange: (e) => setFromAmount(e.target.value),
|
|
3071
|
+
placeholder: "0.00",
|
|
3072
|
+
disabled: isSwapping,
|
|
3073
|
+
className: "flex-1 bg-transparent outline-none font-medium min-w-0",
|
|
3074
|
+
style: { color: "var(--compass-color-text)", fontSize: "1.25rem" }
|
|
3075
|
+
}
|
|
3076
|
+
),
|
|
3077
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", style: { flexShrink: 0 }, children: [
|
|
3078
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3079
|
+
"button",
|
|
3080
|
+
{
|
|
3081
|
+
onClick: () => {
|
|
3082
|
+
setIsFromOpen(!isFromOpen);
|
|
3083
|
+
setIsToOpen(false);
|
|
3084
|
+
},
|
|
3085
|
+
disabled: isSwapping,
|
|
3086
|
+
className: "flex items-center font-medium",
|
|
3087
|
+
style: {
|
|
3088
|
+
backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-background))",
|
|
3089
|
+
border: "1px solid var(--compass-color-border)",
|
|
3090
|
+
color: "var(--compass-color-text)",
|
|
3091
|
+
borderRadius: "var(--compass-border-radius-md)",
|
|
3092
|
+
padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
|
|
3093
|
+
gap: "calc(var(--compass-spacing-unit) * 0.25)",
|
|
3094
|
+
fontSize: "0.875rem"
|
|
3095
|
+
},
|
|
3096
|
+
children: [
|
|
3097
|
+
fromToken,
|
|
3098
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: 14, style: { color: "var(--compass-color-text-tertiary)" } })
|
|
3099
|
+
]
|
|
3100
|
+
}
|
|
3101
|
+
),
|
|
3102
|
+
isFromOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3103
|
+
"div",
|
|
3104
|
+
{
|
|
3105
|
+
className: "absolute right-0 mt-1 z-10",
|
|
3106
|
+
style: {
|
|
3107
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
3108
|
+
border: "1px solid var(--compass-color-border)",
|
|
3109
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
3110
|
+
boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
|
|
3111
|
+
minWidth: "120px",
|
|
3112
|
+
maxHeight: "200px",
|
|
3113
|
+
overflowY: "auto",
|
|
3114
|
+
scrollbarWidth: "none"
|
|
3115
|
+
},
|
|
3116
|
+
children: availableFromTokens.filter((t) => t !== toToken).map((token) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3117
|
+
"button",
|
|
3118
|
+
{
|
|
3119
|
+
onClick: () => {
|
|
3120
|
+
setFromToken(token);
|
|
3121
|
+
setIsFromOpen(false);
|
|
3122
|
+
},
|
|
3123
|
+
className: "w-full text-left font-medium transition-colors",
|
|
3124
|
+
style: {
|
|
3125
|
+
padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
|
|
3126
|
+
color: token === fromToken ? "var(--compass-color-primary)" : "var(--compass-color-text)",
|
|
3127
|
+
backgroundColor: token === fromToken ? "var(--compass-color-primary-muted, rgba(99, 102, 241, 0.1))" : "transparent",
|
|
3128
|
+
fontSize: "0.875rem"
|
|
3129
|
+
},
|
|
3130
|
+
children: token
|
|
3131
|
+
},
|
|
3132
|
+
token
|
|
3133
|
+
))
|
|
3134
|
+
}
|
|
3135
|
+
)
|
|
3136
|
+
] })
|
|
3137
|
+
] })
|
|
3138
|
+
]
|
|
3139
|
+
}
|
|
3140
|
+
),
|
|
3141
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center relative z-10", style: { margin: "calc(var(--compass-spacing-unit) * -0.25) 0" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3142
|
+
"button",
|
|
3143
|
+
{
|
|
3144
|
+
onClick: handleReverse,
|
|
3145
|
+
disabled: !canReverse || isSwapping,
|
|
3146
|
+
className: "border disabled:opacity-30",
|
|
3147
|
+
style: {
|
|
3148
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
3149
|
+
borderColor: "var(--compass-color-border)",
|
|
3150
|
+
borderRadius: "var(--compass-border-radius-full)",
|
|
3151
|
+
padding: "calc(var(--compass-spacing-unit) * 0.5)",
|
|
3152
|
+
transition: "var(--compass-transition-normal)"
|
|
3153
|
+
},
|
|
3154
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDownUp, { size: 16, style: { color: "var(--compass-color-text-secondary)" } })
|
|
3155
|
+
}
|
|
3156
|
+
) }),
|
|
3157
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3158
|
+
"div",
|
|
3159
|
+
{
|
|
3160
|
+
style: {
|
|
3161
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
3162
|
+
border: "1px solid var(--compass-color-border)",
|
|
3163
|
+
borderRadius: "var(--compass-border-radius-xl)",
|
|
3164
|
+
padding: "calc(var(--compass-spacing-unit) * 0.75)"
|
|
3165
|
+
},
|
|
3166
|
+
children: [
|
|
3167
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", style: { marginBottom: "calc(var(--compass-spacing-unit) * 0.25)" }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: "To" }) }),
|
|
3168
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
3169
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3170
|
+
"div",
|
|
3171
|
+
{
|
|
3172
|
+
className: "flex-1 font-medium min-w-0",
|
|
3173
|
+
style: {
|
|
3174
|
+
color: isQuoteLoading ? "var(--compass-color-text-tertiary)" : "var(--compass-color-text)",
|
|
3175
|
+
fontSize: "1.25rem"
|
|
3176
|
+
},
|
|
3177
|
+
children: isQuoteLoading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2", children: [
|
|
3178
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 16, className: "animate-spin" }),
|
|
3179
|
+
"Loading..."
|
|
3180
|
+
] }) : quote?.outputAmount ? parseFloat(quote.outputAmount).toFixed(8) : "0.00"
|
|
3181
|
+
}
|
|
3182
|
+
),
|
|
3183
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", style: { flexShrink: 0 }, children: [
|
|
3184
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3185
|
+
"button",
|
|
3186
|
+
{
|
|
3187
|
+
onClick: () => {
|
|
3188
|
+
setIsToOpen(!isToOpen);
|
|
3189
|
+
setIsFromOpen(false);
|
|
3190
|
+
},
|
|
3191
|
+
disabled: isSwapping,
|
|
3192
|
+
className: "flex items-center font-medium",
|
|
3193
|
+
style: {
|
|
3194
|
+
backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-background))",
|
|
3195
|
+
border: "1px solid var(--compass-color-border)",
|
|
3196
|
+
color: "var(--compass-color-text)",
|
|
3197
|
+
borderRadius: "var(--compass-border-radius-md)",
|
|
3198
|
+
padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
|
|
3199
|
+
gap: "calc(var(--compass-spacing-unit) * 0.25)",
|
|
3200
|
+
fontSize: "0.875rem"
|
|
3201
|
+
},
|
|
3202
|
+
children: [
|
|
3203
|
+
toToken,
|
|
3204
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: 14, style: { color: "var(--compass-color-text-tertiary)" } })
|
|
3205
|
+
]
|
|
3206
|
+
}
|
|
3207
|
+
),
|
|
3208
|
+
isToOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3209
|
+
"div",
|
|
3210
|
+
{
|
|
3211
|
+
className: "absolute right-0 mt-1 z-10",
|
|
3212
|
+
style: {
|
|
3213
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
3214
|
+
border: "1px solid var(--compass-color-border)",
|
|
3215
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
3216
|
+
boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
|
|
3217
|
+
minWidth: "140px",
|
|
3218
|
+
maxHeight: "280px",
|
|
3219
|
+
overflowY: "auto",
|
|
3220
|
+
scrollbarWidth: "none"
|
|
3221
|
+
},
|
|
3222
|
+
children: toTokens.filter((t) => t !== fromToken).map((token) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3223
|
+
"button",
|
|
3224
|
+
{
|
|
3225
|
+
onClick: () => {
|
|
3226
|
+
setToToken(token);
|
|
3227
|
+
setIsToOpen(false);
|
|
3228
|
+
},
|
|
3229
|
+
className: "w-full text-left font-medium transition-colors",
|
|
3230
|
+
style: {
|
|
3231
|
+
padding: "calc(var(--compass-spacing-unit) * 0.5) calc(var(--compass-spacing-unit) * 0.75)",
|
|
3232
|
+
color: token === toToken ? "var(--compass-color-primary)" : "var(--compass-color-text)",
|
|
3233
|
+
backgroundColor: token === toToken ? "var(--compass-color-primary-muted, rgba(99, 102, 241, 0.1))" : "transparent",
|
|
3234
|
+
fontSize: "0.875rem"
|
|
3235
|
+
},
|
|
3236
|
+
children: token
|
|
3237
|
+
},
|
|
3238
|
+
token
|
|
3239
|
+
))
|
|
3240
|
+
}
|
|
3241
|
+
)
|
|
3242
|
+
] })
|
|
3243
|
+
] })
|
|
3244
|
+
]
|
|
3245
|
+
}
|
|
3246
|
+
),
|
|
3247
|
+
quote && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm", style: { color: "var(--compass-color-text-secondary)" }, children: [
|
|
3248
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Rate" }),
|
|
3249
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono", children: [
|
|
3250
|
+
"1 ",
|
|
3251
|
+
fromToken,
|
|
3252
|
+
" = ",
|
|
3253
|
+
parseFloat(quote.rate).toFixed(6),
|
|
3254
|
+
" ",
|
|
3255
|
+
toToken
|
|
3256
|
+
] })
|
|
3257
|
+
] }),
|
|
3258
|
+
quoteError && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3259
|
+
"div",
|
|
3260
|
+
{
|
|
3261
|
+
className: "flex items-center text-sm",
|
|
3262
|
+
style: {
|
|
3263
|
+
backgroundColor: "var(--compass-color-error-muted)",
|
|
3264
|
+
color: "var(--compass-color-error)",
|
|
3265
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
3266
|
+
padding: "calc(var(--compass-spacing-unit) * 0.75)",
|
|
3267
|
+
gap: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
3268
|
+
},
|
|
3269
|
+
children: [
|
|
3270
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 16 }),
|
|
3271
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: quoteError.message })
|
|
3272
|
+
]
|
|
3273
|
+
}
|
|
3274
|
+
),
|
|
3275
|
+
swapStatus && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3276
|
+
"div",
|
|
3277
|
+
{
|
|
3278
|
+
className: "flex items-center text-sm",
|
|
3279
|
+
style: {
|
|
3280
|
+
backgroundColor: swapStatus.includes("successful") ? "var(--compass-color-success-muted)" : "var(--compass-color-surface)",
|
|
3281
|
+
color: swapStatus.includes("successful") ? "var(--compass-color-success)" : "var(--compass-color-text-secondary)",
|
|
3282
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
3283
|
+
padding: "calc(var(--compass-spacing-unit) * 0.75)",
|
|
3284
|
+
gap: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
3285
|
+
},
|
|
3286
|
+
children: [
|
|
3287
|
+
!swapStatus.includes("successful") && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 14, className: "animate-spin" }),
|
|
3288
|
+
swapStatus
|
|
3289
|
+
]
|
|
3290
|
+
}
|
|
3291
|
+
),
|
|
3292
|
+
!isConnected ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3293
|
+
"div",
|
|
3294
|
+
{
|
|
3295
|
+
className: "flex flex-col items-center",
|
|
3296
|
+
style: {
|
|
3297
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
3298
|
+
border: "1px solid var(--compass-color-border)",
|
|
3299
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
3300
|
+
padding: "calc(var(--compass-spacing-unit) * 1) var(--compass-spacing-card)",
|
|
3301
|
+
gap: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
3302
|
+
},
|
|
3303
|
+
children: [
|
|
3304
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 20, style: { color: "var(--compass-color-text-tertiary)" } }),
|
|
3305
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-center", style: { color: "var(--compass-color-text-secondary)" }, children: "Connect your wallet to swap" })
|
|
3306
|
+
]
|
|
3307
|
+
}
|
|
3308
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3309
|
+
"button",
|
|
3310
|
+
{
|
|
3311
|
+
onClick: handleSwap,
|
|
3312
|
+
disabled: isSwapping || !quote || !fromAmount || parseFloat(fromAmount) <= 0,
|
|
3313
|
+
className: "w-full font-semibold flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed",
|
|
3314
|
+
style: {
|
|
3315
|
+
backgroundColor: "var(--compass-color-primary)",
|
|
3316
|
+
color: "var(--compass-color-primary-text, white)",
|
|
3317
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
3318
|
+
padding: "calc(var(--compass-spacing-unit) * 0.75)",
|
|
3319
|
+
gap: "calc(var(--compass-spacing-unit) * 0.5)",
|
|
3320
|
+
fontSize: "0.875rem",
|
|
3321
|
+
transition: "var(--compass-transition-normal)"
|
|
3322
|
+
},
|
|
3323
|
+
children: [
|
|
3324
|
+
isSwapping && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 16, className: "animate-spin" }),
|
|
3325
|
+
isSwapping ? "Swapping..." : "Swap"
|
|
3326
|
+
]
|
|
3327
|
+
}
|
|
3328
|
+
)
|
|
3329
|
+
] });
|
|
3330
|
+
}
|
|
2956
3331
|
var MARKET_TABS = [
|
|
2957
3332
|
{ value: "variable", label: "VARIABLE" },
|
|
2958
3333
|
{ value: "fixed", label: "FIXED" }
|
|
@@ -3785,7 +4160,6 @@ var EVM_CHAIN_IDS = {
|
|
|
3785
4160
|
base: 8453,
|
|
3786
4161
|
arbitrum: 42161
|
|
3787
4162
|
};
|
|
3788
|
-
var SUPPORTED_TOKENS = ["USDC", "USDT", "DAI", "WETH", "SBC", "AUSD"];
|
|
3789
4163
|
function formatCurrency(amount) {
|
|
3790
4164
|
if (!amount) return "$0.00";
|
|
3791
4165
|
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
@@ -3837,6 +4211,7 @@ function EarnAccount({
|
|
|
3837
4211
|
const [isBalancesModalOpen, setIsBalancesModalOpen] = react.useState(false);
|
|
3838
4212
|
const [marketTab, setMarketTab] = react.useState(defaultMarketTab);
|
|
3839
4213
|
const [selectedMarket, setSelectedMarket] = react.useState(null);
|
|
4214
|
+
const [isSwapModalOpen, setIsSwapModalOpen] = react.useState(false);
|
|
3840
4215
|
const [isEarningsModalOpen, setIsEarningsModalOpen] = react.useState(false);
|
|
3841
4216
|
react.useEffect(() => {
|
|
3842
4217
|
setSelectedMarket(null);
|
|
@@ -3886,6 +4261,7 @@ function EarnAccount({
|
|
|
3886
4261
|
enabled: !!address && isDeployed,
|
|
3887
4262
|
staleTime: 30 * 1e3
|
|
3888
4263
|
});
|
|
4264
|
+
const balanceTokens = Object.keys(balancesQuery.data?.balances || {});
|
|
3889
4265
|
const selectedTokenBalance = balancesQuery.data?.balances?.[selectedToken]?.balance || "0";
|
|
3890
4266
|
const earnAccountTotalUsd = Object.values(balancesQuery.data?.balances || {}).reduce((sum, b) => sum + parseFloat(b.usdValue || "0"), 0).toString();
|
|
3891
4267
|
const positionQuery = reactQuery.useQuery({
|
|
@@ -4555,39 +4931,59 @@ function EarnAccount({
|
|
|
4555
4931
|
]
|
|
4556
4932
|
}
|
|
4557
4933
|
),
|
|
4558
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4559
|
-
|
|
4934
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4935
|
+
"button",
|
|
4936
|
+
{
|
|
4937
|
+
onClick: () => setIsBalancesModalOpen(true),
|
|
4938
|
+
className: "transition-opacity hover:opacity-80",
|
|
4939
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4940
|
+
"span",
|
|
4941
|
+
{
|
|
4942
|
+
className: "font-bold",
|
|
4943
|
+
style: {
|
|
4944
|
+
color: "var(--compass-color-text)",
|
|
4945
|
+
fontSize: compact ? "2rem" : "2.5rem",
|
|
4946
|
+
lineHeight: "1"
|
|
4947
|
+
},
|
|
4948
|
+
children: formatCurrency(earnAccountTotal)
|
|
4949
|
+
}
|
|
4950
|
+
)
|
|
4951
|
+
}
|
|
4952
|
+
),
|
|
4953
|
+
(balanceTokens.length > 0 || showTopUpButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", style: { gap: "6px", marginTop: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
4954
|
+
balanceTokens.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4560
4955
|
"button",
|
|
4561
4956
|
{
|
|
4562
|
-
onClick: () =>
|
|
4563
|
-
className: "transition-
|
|
4564
|
-
|
|
4565
|
-
"
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
}
|
|
4575
|
-
|
|
4957
|
+
onClick: () => setIsSwapModalOpen(true),
|
|
4958
|
+
className: "flex items-center justify-center font-medium transition-all hover:opacity-80 w-full",
|
|
4959
|
+
style: {
|
|
4960
|
+
backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-surface))",
|
|
4961
|
+
border: "1px solid var(--compass-color-border)",
|
|
4962
|
+
color: "var(--compass-color-text-secondary)",
|
|
4963
|
+
borderRadius: "var(--compass-border-radius-md)",
|
|
4964
|
+
padding: "8px 10px",
|
|
4965
|
+
gap: "6px",
|
|
4966
|
+
fontSize: "13px"
|
|
4967
|
+
},
|
|
4968
|
+
children: [
|
|
4969
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeftRight, { size: 14 }),
|
|
4970
|
+
"Swap"
|
|
4971
|
+
]
|
|
4576
4972
|
}
|
|
4577
4973
|
),
|
|
4578
4974
|
showTopUpButton && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4579
4975
|
"button",
|
|
4580
4976
|
{
|
|
4581
4977
|
onClick: () => setIsFundModalOpen(true),
|
|
4582
|
-
className: "flex items-center font-medium transition-all hover:opacity-80",
|
|
4978
|
+
className: "flex items-center justify-center font-medium transition-all hover:opacity-80 w-full",
|
|
4583
4979
|
style: {
|
|
4584
4980
|
backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-surface))",
|
|
4585
4981
|
border: "1px solid var(--compass-color-border)",
|
|
4586
4982
|
color: "var(--compass-color-text-secondary)",
|
|
4587
4983
|
borderRadius: "var(--compass-border-radius-md)",
|
|
4588
|
-
padding: "
|
|
4589
|
-
gap: "
|
|
4590
|
-
fontSize: "
|
|
4984
|
+
padding: "8px 10px",
|
|
4985
|
+
gap: "6px",
|
|
4986
|
+
fontSize: "13px"
|
|
4591
4987
|
},
|
|
4592
4988
|
children: [
|
|
4593
4989
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { size: 14 }),
|
|
@@ -4791,7 +5187,7 @@ function EarnAccount({
|
|
|
4791
5187
|
boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
|
|
4792
5188
|
minWidth: "100px"
|
|
4793
5189
|
},
|
|
4794
|
-
children:
|
|
5190
|
+
children: balanceTokens.map((token) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4795
5191
|
"button",
|
|
4796
5192
|
{
|
|
4797
5193
|
onClick: () => {
|
|
@@ -5103,391 +5499,123 @@ function EarnAccount({
|
|
|
5103
5499
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
|
|
5104
5500
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDownLeft, { size: 20 }),
|
|
5105
5501
|
needsFundSwap ? `Swap ${fundToken} & Transfer` : "Transfer to Savings"
|
|
5106
|
-
] })
|
|
5107
|
-
}
|
|
5108
|
-
),
|
|
5109
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5110
|
-
"p",
|
|
5111
|
-
{
|
|
5112
|
-
className: "text-xs text-center",
|
|
5113
|
-
style: { color: "var(--compass-color-text-tertiary)" },
|
|
5114
|
-
children: "Gas fees are sponsored"
|
|
5115
|
-
}
|
|
5116
|
-
)
|
|
5117
|
-
] })
|
|
5118
|
-
}
|
|
5119
|
-
),
|
|
5120
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5121
|
-
ActionModal,
|
|
5122
|
-
{
|
|
5123
|
-
isOpen: isBalancesModalOpen,
|
|
5124
|
-
onClose: () => setIsBalancesModalOpen(false),
|
|
5125
|
-
title: "Balance Breakdown",
|
|
5126
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: balancesQuery.data?.balances && Object.keys(balancesQuery.data.balances).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5127
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
5128
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5129
|
-
"span",
|
|
5130
|
-
{
|
|
5131
|
-
className: "text-xs font-medium uppercase tracking-wide",
|
|
5132
|
-
style: { color: "var(--compass-color-text-tertiary)" },
|
|
5133
|
-
children: "Available in Account"
|
|
5134
|
-
}
|
|
5135
|
-
),
|
|
5136
|
-
Object.entries(balancesQuery.data.balances).map(([symbol, data]) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5137
|
-
"div",
|
|
5138
|
-
{
|
|
5139
|
-
className: "flex items-center justify-between p-3 rounded-lg",
|
|
5140
|
-
style: {
|
|
5141
|
-
backgroundColor: "var(--compass-color-surface)",
|
|
5142
|
-
border: "1px solid var(--compass-color-border)"
|
|
5143
|
-
},
|
|
5144
|
-
children: [
|
|
5145
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", style: { color: "var(--compass-color-text)" }, children: symbol }),
|
|
5146
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end", children: [
|
|
5147
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-text)" }, children: formatAmount2(data.balance) }),
|
|
5148
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: formatCurrency(data.usdValue) })
|
|
5149
|
-
] })
|
|
5150
|
-
]
|
|
5151
|
-
},
|
|
5152
|
-
symbol
|
|
5153
|
-
))
|
|
5154
|
-
] }),
|
|
5155
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5156
|
-
"div",
|
|
5157
|
-
{
|
|
5158
|
-
className: "flex items-center justify-between pt-3 mt-2",
|
|
5159
|
-
style: { borderTop: "2px solid var(--compass-color-border)" },
|
|
5160
|
-
children: [
|
|
5161
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", style: { color: "var(--compass-color-text)" }, children: "Total" }),
|
|
5162
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5163
|
-
"span",
|
|
5164
|
-
{
|
|
5165
|
-
className: "font-bold text-xl",
|
|
5166
|
-
style: { color: "var(--compass-color-text)" },
|
|
5167
|
-
children: formatCurrency(earnAccountTotalUsd)
|
|
5168
|
-
}
|
|
5169
|
-
)
|
|
5170
|
-
]
|
|
5171
|
-
}
|
|
5172
|
-
)
|
|
5173
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
5174
|
-
"div",
|
|
5175
|
-
{
|
|
5176
|
-
className: "text-center py-4",
|
|
5177
|
-
style: { color: "var(--compass-color-text-tertiary)" },
|
|
5178
|
-
children: "No tokens in account"
|
|
5179
|
-
}
|
|
5180
|
-
) })
|
|
5181
|
-
}
|
|
5182
|
-
),
|
|
5183
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5184
|
-
EarningsModal,
|
|
5185
|
-
{
|
|
5186
|
-
isOpen: isEarningsModalOpen,
|
|
5187
|
-
onClose: () => setIsEarningsModalOpen(false),
|
|
5188
|
-
positions,
|
|
5189
|
-
totalEarned,
|
|
5190
|
-
isLoading: positionQuery.isLoading
|
|
5191
|
-
}
|
|
5192
|
-
)
|
|
5193
|
-
] });
|
|
5194
|
-
}
|
|
5195
|
-
function useSwapQuote({ fromToken, toToken, amount, enabled = true }) {
|
|
5196
|
-
const { chainId } = useChain();
|
|
5197
|
-
const { address } = useCompassWallet();
|
|
5198
|
-
const query = reactQuery.useQuery({
|
|
5199
|
-
queryKey: ["swapQuote", chainId, fromToken, toToken, amount, address],
|
|
5200
|
-
queryFn: async () => {
|
|
5201
|
-
if (!fromToken || !toToken || !amount || parseFloat(amount) <= 0 || !address) {
|
|
5202
|
-
return null;
|
|
5203
|
-
}
|
|
5204
|
-
try {
|
|
5205
|
-
const params = new URLSearchParams({
|
|
5206
|
-
owner: address,
|
|
5207
|
-
chain: chainId,
|
|
5208
|
-
tokenIn: fromToken,
|
|
5209
|
-
tokenOut: toToken,
|
|
5210
|
-
amountIn: amount
|
|
5211
|
-
});
|
|
5212
|
-
const response = await fetch(`/api/compass/swap/quote?${params}`);
|
|
5213
|
-
if (!response.ok) {
|
|
5214
|
-
const errorData = await response.json();
|
|
5215
|
-
const errorMessage = errorData.message || errorData.error || "Failed to get swap quote";
|
|
5216
|
-
throw new Error(errorMessage);
|
|
5217
|
-
}
|
|
5218
|
-
const data = await response.json();
|
|
5219
|
-
const outputAmount = data.estimatedAmountOut || "0";
|
|
5220
|
-
const inputAmountNum = parseFloat(amount);
|
|
5221
|
-
const outputAmountNum = parseFloat(outputAmount);
|
|
5222
|
-
return {
|
|
5223
|
-
inputAmount: amount,
|
|
5224
|
-
outputAmount,
|
|
5225
|
-
rate: inputAmountNum > 0 ? (outputAmountNum / inputAmountNum).toString() : "0"
|
|
5226
|
-
};
|
|
5227
|
-
} catch (error) {
|
|
5228
|
-
throw error;
|
|
5229
|
-
}
|
|
5230
|
-
},
|
|
5231
|
-
enabled: enabled && !!address && !!fromToken && !!toToken && !!amount && parseFloat(amount) > 0,
|
|
5232
|
-
staleTime: 10 * 1e3,
|
|
5233
|
-
refetchInterval: 15 * 1e3,
|
|
5234
|
-
retry: 1
|
|
5235
|
-
});
|
|
5236
|
-
return {
|
|
5237
|
-
quote: query.data,
|
|
5238
|
-
isLoading: query.isLoading,
|
|
5239
|
-
isError: query.isError,
|
|
5240
|
-
error: query.error,
|
|
5241
|
-
refetch: query.refetch
|
|
5242
|
-
};
|
|
5243
|
-
}
|
|
5244
|
-
|
|
5245
|
-
// src/components/SwapWidget/types.ts
|
|
5246
|
-
var DEFAULT_SWAP_TOKENS = ["USDC", "ETH", "WETH", "WBTC", "DAI", "USDT", "AUSD", "SBC"];
|
|
5247
|
-
function SwapWidget({
|
|
5248
|
-
layout = "full",
|
|
5249
|
-
defaultFromToken = "ETH",
|
|
5250
|
-
defaultToToken = "USDC",
|
|
5251
|
-
allowedTokens = [...DEFAULT_SWAP_TOKENS],
|
|
5252
|
-
showReverseButton = true,
|
|
5253
|
-
showSettings = false,
|
|
5254
|
-
onSwapSuccess,
|
|
5255
|
-
onSwapError
|
|
5256
|
-
}) {
|
|
5257
|
-
const [fromToken, setFromToken] = react.useState(defaultFromToken);
|
|
5258
|
-
const [toToken, setToToken] = react.useState(defaultToToken);
|
|
5259
|
-
const [fromAmount, setFromAmount] = react.useState("");
|
|
5260
|
-
const [isSwapping, setIsSwapping] = react.useState(false);
|
|
5261
|
-
const [swapStatus, setSwapStatus] = react.useState("");
|
|
5262
|
-
const { address, isConnected, signTypedData } = useCompassWallet();
|
|
5263
|
-
const { chainId } = useChain();
|
|
5264
|
-
const { quote, isLoading: isQuoteLoading, error: quoteError } = useSwapQuote({
|
|
5265
|
-
fromToken,
|
|
5266
|
-
toToken,
|
|
5267
|
-
amount: fromAmount,
|
|
5268
|
-
enabled: !!fromAmount && parseFloat(fromAmount) > 0
|
|
5269
|
-
});
|
|
5270
|
-
const handleReverse = react.useCallback(() => {
|
|
5271
|
-
setFromToken(toToken);
|
|
5272
|
-
setToToken(fromToken);
|
|
5273
|
-
setFromAmount("");
|
|
5274
|
-
}, [fromToken, toToken]);
|
|
5275
|
-
const handleSwap = react.useCallback(async () => {
|
|
5276
|
-
if (!address || !fromAmount || !quote) return;
|
|
5277
|
-
setIsSwapping(true);
|
|
5278
|
-
setSwapStatus("Preparing swap...");
|
|
5279
|
-
try {
|
|
5280
|
-
const prepareResponse = await fetch("/api/compass/swap/prepare", {
|
|
5281
|
-
method: "POST",
|
|
5282
|
-
headers: { "Content-Type": "application/json" },
|
|
5283
|
-
body: JSON.stringify({
|
|
5284
|
-
owner: address,
|
|
5285
|
-
chain: chainId,
|
|
5286
|
-
tokenIn: fromToken,
|
|
5287
|
-
tokenOut: toToken,
|
|
5288
|
-
amountIn: fromAmount
|
|
5289
|
-
})
|
|
5290
|
-
});
|
|
5291
|
-
if (!prepareResponse.ok) {
|
|
5292
|
-
const error = await prepareResponse.json();
|
|
5293
|
-
throw new Error(error.error || "Failed to prepare swap");
|
|
5294
|
-
}
|
|
5295
|
-
const prepareData = await prepareResponse.json();
|
|
5296
|
-
const { eip712, normalizedTypes } = prepareData;
|
|
5297
|
-
if (!eip712) {
|
|
5298
|
-
throw new Error("No EIP-712 data returned from prepare");
|
|
5299
|
-
}
|
|
5300
|
-
setSwapStatus("Please sign the transaction...");
|
|
5301
|
-
const signature = await signTypedData({
|
|
5302
|
-
domain: eip712.domain,
|
|
5303
|
-
types: normalizedTypes || eip712.types,
|
|
5304
|
-
primaryType: "SafeTx",
|
|
5305
|
-
message: eip712.message
|
|
5306
|
-
});
|
|
5307
|
-
setSwapStatus("Executing swap...");
|
|
5308
|
-
const executeResponse = await fetch("/api/compass/swap/execute", {
|
|
5309
|
-
method: "POST",
|
|
5310
|
-
headers: { "Content-Type": "application/json" },
|
|
5311
|
-
body: JSON.stringify({
|
|
5312
|
-
owner: address,
|
|
5313
|
-
chain: chainId,
|
|
5314
|
-
eip712,
|
|
5315
|
-
signature
|
|
5316
|
-
})
|
|
5317
|
-
});
|
|
5318
|
-
if (!executeResponse.ok) {
|
|
5319
|
-
const error = await executeResponse.json();
|
|
5320
|
-
throw new Error(error.error || "Failed to execute swap");
|
|
5502
|
+
] })
|
|
5503
|
+
}
|
|
5504
|
+
),
|
|
5505
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5506
|
+
"p",
|
|
5507
|
+
{
|
|
5508
|
+
className: "text-xs text-center",
|
|
5509
|
+
style: { color: "var(--compass-color-text-tertiary)" },
|
|
5510
|
+
children: "Gas fees are sponsored"
|
|
5511
|
+
}
|
|
5512
|
+
)
|
|
5513
|
+
] })
|
|
5321
5514
|
}
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
} finally {
|
|
5332
|
-
setIsSwapping(false);
|
|
5333
|
-
}
|
|
5334
|
-
}, [address, fromAmount, quote, chainId, fromToken, toToken, signTypedData, onSwapSuccess, onSwapError]);
|
|
5335
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", style: { gap: "var(--compass-spacing-card)" }, children: [
|
|
5336
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between flex-wrap", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
5337
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChainSwitcher, {}),
|
|
5338
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
5339
|
-
/* @__PURE__ */ jsxRuntime.jsx(EarnAccountBalance, { compact: true }),
|
|
5340
|
-
/* @__PURE__ */ jsxRuntime.jsx(WalletStatus, { compact: true })
|
|
5341
|
-
] })
|
|
5342
|
-
] }),
|
|
5343
|
-
/* @__PURE__ */ jsxRuntime.jsxs(EarnAccountGuard, { children: [
|
|
5344
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", style: { gap: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
5345
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border relative", style: { backgroundColor: "var(--compass-color-surface)", borderColor: "var(--compass-color-border)", borderRadius: "var(--compass-border-radius-xl)", fontFamily: "var(--compass-font-family)", padding: "var(--compass-spacing-card)" }, children: [
|
|
5346
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", style: { marginBottom: "calc(var(--compass-spacing-unit) * 0.5)" }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: "From" }) }),
|
|
5347
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", style: { gap: "calc(var(--compass-spacing-unit) * 0.75)" }, children: [
|
|
5515
|
+
),
|
|
5516
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5517
|
+
ActionModal,
|
|
5518
|
+
{
|
|
5519
|
+
isOpen: isBalancesModalOpen,
|
|
5520
|
+
onClose: () => setIsBalancesModalOpen(false),
|
|
5521
|
+
title: "Balance Breakdown",
|
|
5522
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: balancesQuery.data?.balances && Object.keys(balancesQuery.data.balances).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5523
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
5348
5524
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5349
|
-
"
|
|
5525
|
+
"span",
|
|
5350
5526
|
{
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
placeholder: "0.00",
|
|
5355
|
-
className: "flex-1 bg-transparent outline-none text-2xl font-mono min-w-0",
|
|
5356
|
-
style: { color: "var(--compass-color-text)" }
|
|
5527
|
+
className: "text-xs font-medium uppercase tracking-wide",
|
|
5528
|
+
style: { color: "var(--compass-color-text-tertiary)" },
|
|
5529
|
+
children: "Available in Account"
|
|
5357
5530
|
}
|
|
5358
5531
|
),
|
|
5359
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5360
|
-
"
|
|
5532
|
+
Object.entries(balancesQuery.data.balances).map(([symbol, data]) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5533
|
+
"div",
|
|
5361
5534
|
{
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5535
|
+
className: "flex items-center justify-between p-3 rounded-lg",
|
|
5536
|
+
style: {
|
|
5537
|
+
backgroundColor: "var(--compass-color-surface)",
|
|
5538
|
+
border: "1px solid var(--compass-color-border)"
|
|
5539
|
+
},
|
|
5540
|
+
children: [
|
|
5541
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", style: { color: "var(--compass-color-text)" }, children: symbol }),
|
|
5542
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end", children: [
|
|
5543
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono font-medium", style: { color: "var(--compass-color-text)" }, children: formatAmount2(data.balance) }),
|
|
5544
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", style: { color: "var(--compass-color-text-tertiary)" }, children: formatCurrency(data.usdValue) })
|
|
5545
|
+
] })
|
|
5546
|
+
]
|
|
5547
|
+
},
|
|
5548
|
+
symbol
|
|
5549
|
+
))
|
|
5550
|
+
] }),
|
|
5551
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5552
|
+
"div",
|
|
5553
|
+
{
|
|
5554
|
+
className: "flex items-center justify-between pt-3 mt-2",
|
|
5555
|
+
style: { borderTop: "2px solid var(--compass-color-border)" },
|
|
5556
|
+
children: [
|
|
5557
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", style: { color: "var(--compass-color-text)" }, children: "Total" }),
|
|
5558
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5559
|
+
"span",
|
|
5560
|
+
{
|
|
5561
|
+
className: "font-bold text-xl",
|
|
5562
|
+
style: { color: "var(--compass-color-text)" },
|
|
5563
|
+
children: formatCurrency(earnAccountTotalUsd)
|
|
5564
|
+
}
|
|
5565
|
+
)
|
|
5566
|
+
]
|
|
5567
|
+
}
|
|
5568
|
+
)
|
|
5569
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
5570
|
+
"div",
|
|
5373
5571
|
{
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDownUp, { size: 16, style: { color: "var(--compass-color-text-secondary)" } })
|
|
5572
|
+
className: "text-center py-4",
|
|
5573
|
+
style: { color: "var(--compass-color-text-tertiary)" },
|
|
5574
|
+
children: "No tokens in account"
|
|
5378
5575
|
}
|
|
5379
|
-
) })
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
children: [
|
|
5423
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 16 }),
|
|
5424
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: quoteError.message })
|
|
5425
|
-
]
|
|
5426
|
-
}
|
|
5427
|
-
),
|
|
5428
|
-
swapStatus && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5429
|
-
"div",
|
|
5430
|
-
{
|
|
5431
|
-
className: "flex items-center text-sm",
|
|
5432
|
-
style: {
|
|
5433
|
-
backgroundColor: swapStatus.includes("successful") ? "var(--compass-color-success-muted)" : "var(--compass-color-surface)",
|
|
5434
|
-
color: swapStatus.includes("successful") ? "var(--compass-color-success)" : "var(--compass-color-text-secondary)",
|
|
5435
|
-
borderRadius: "var(--compass-border-radius-lg)",
|
|
5436
|
-
padding: "calc(var(--compass-spacing-unit) * 0.75)",
|
|
5437
|
-
gap: "calc(var(--compass-spacing-unit) * 0.5)"
|
|
5438
|
-
},
|
|
5439
|
-
children: [
|
|
5440
|
-
!swapStatus.includes("successful") && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 14, className: "animate-spin" }),
|
|
5441
|
-
swapStatus
|
|
5442
|
-
]
|
|
5443
|
-
}
|
|
5444
|
-
),
|
|
5445
|
-
!isConnected ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5446
|
-
"div",
|
|
5447
|
-
{
|
|
5448
|
-
className: "flex flex-col items-center",
|
|
5449
|
-
style: {
|
|
5450
|
-
backgroundColor: "var(--compass-color-surface)",
|
|
5451
|
-
border: "1px solid var(--compass-color-border)",
|
|
5452
|
-
borderRadius: "var(--compass-border-radius-lg)",
|
|
5453
|
-
fontFamily: "var(--compass-font-family)",
|
|
5454
|
-
padding: "calc(var(--compass-spacing-unit) * 1.5) var(--compass-spacing-card)",
|
|
5455
|
-
gap: "calc(var(--compass-spacing-unit) * 0.75)"
|
|
5456
|
-
},
|
|
5457
|
-
children: [
|
|
5458
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 24, style: { color: "var(--compass-color-text-tertiary)" } }),
|
|
5459
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5460
|
-
"p",
|
|
5461
|
-
{
|
|
5462
|
-
className: "text-sm text-center",
|
|
5463
|
-
style: { color: "var(--compass-color-text-secondary)" },
|
|
5464
|
-
children: "Connect your wallet to swap"
|
|
5465
|
-
}
|
|
5466
|
-
)
|
|
5467
|
-
]
|
|
5468
|
-
}
|
|
5469
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5470
|
-
"button",
|
|
5471
|
-
{
|
|
5472
|
-
onClick: handleSwap,
|
|
5473
|
-
disabled: isSwapping || !quote || !fromAmount || parseFloat(fromAmount) <= 0,
|
|
5474
|
-
className: "w-full font-medium flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed",
|
|
5475
|
-
style: {
|
|
5476
|
-
backgroundColor: "var(--compass-color-primary)",
|
|
5477
|
-
color: "var(--compass-color-primary-text)",
|
|
5478
|
-
borderRadius: "var(--compass-border-radius-lg)",
|
|
5479
|
-
fontFamily: "var(--compass-font-family)",
|
|
5480
|
-
padding: "calc(var(--compass-spacing-unit) * 0.75)",
|
|
5481
|
-
gap: "calc(var(--compass-spacing-unit) * 0.5)",
|
|
5482
|
-
transition: "var(--compass-transition-normal)"
|
|
5483
|
-
},
|
|
5484
|
-
children: [
|
|
5485
|
-
isSwapping && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 18, className: "animate-spin" }),
|
|
5486
|
-
isSwapping ? "Swapping..." : "Swap"
|
|
5487
|
-
]
|
|
5488
|
-
}
|
|
5489
|
-
)
|
|
5490
|
-
] })
|
|
5576
|
+
) })
|
|
5577
|
+
}
|
|
5578
|
+
),
|
|
5579
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5580
|
+
ActionModal,
|
|
5581
|
+
{
|
|
5582
|
+
isOpen: isSwapModalOpen,
|
|
5583
|
+
onClose: () => setIsSwapModalOpen(false),
|
|
5584
|
+
title: "Swap Tokens",
|
|
5585
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5586
|
+
SwapForm,
|
|
5587
|
+
{
|
|
5588
|
+
availableFromTokens: balanceTokens,
|
|
5589
|
+
balances: Object.fromEntries(
|
|
5590
|
+
Object.entries(balancesQuery.data?.balances || {}).map(([token, data]) => [token, data.balance])
|
|
5591
|
+
),
|
|
5592
|
+
onSwapSuccess: () => {
|
|
5593
|
+
setIsSwapModalOpen(false);
|
|
5594
|
+
queryClient.invalidateQueries({ queryKey: ["earnAccountBalances"] });
|
|
5595
|
+
balancesQuery.refetch();
|
|
5596
|
+
setTimeout(() => {
|
|
5597
|
+
queryClient.invalidateQueries({ queryKey: ["earnAccountBalances"] });
|
|
5598
|
+
balancesQuery.refetch();
|
|
5599
|
+
}, 5e3);
|
|
5600
|
+
setTimeout(() => {
|
|
5601
|
+
queryClient.invalidateQueries({ queryKey: ["earnAccountBalances"] });
|
|
5602
|
+
balancesQuery.refetch();
|
|
5603
|
+
}, 15e3);
|
|
5604
|
+
}
|
|
5605
|
+
}
|
|
5606
|
+
)
|
|
5607
|
+
}
|
|
5608
|
+
),
|
|
5609
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5610
|
+
EarningsModal,
|
|
5611
|
+
{
|
|
5612
|
+
isOpen: isEarningsModalOpen,
|
|
5613
|
+
onClose: () => setIsEarningsModalOpen(false),
|
|
5614
|
+
positions,
|
|
5615
|
+
totalEarned,
|
|
5616
|
+
isLoading: positionQuery.isLoading
|
|
5617
|
+
}
|
|
5618
|
+
)
|
|
5491
5619
|
] });
|
|
5492
5620
|
}
|
|
5493
5621
|
function getEarliestDepositTimestamp(deposits) {
|
|
@@ -5974,7 +6102,8 @@ function PositionDetailModal({ position, onClose }) {
|
|
|
5974
6102
|
className: "relative w-full max-w-md rounded-xl border overflow-hidden max-h-[90vh] overflow-y-auto",
|
|
5975
6103
|
style: {
|
|
5976
6104
|
backgroundColor: "var(--compass-color-background)",
|
|
5977
|
-
borderColor: "var(--compass-color-border)"
|
|
6105
|
+
borderColor: "var(--compass-color-border)",
|
|
6106
|
+
scrollbarWidth: "none"
|
|
5978
6107
|
},
|
|
5979
6108
|
onClick: (e) => e.stopPropagation(),
|
|
5980
6109
|
children: [
|
|
@@ -6477,7 +6606,7 @@ function useRebalancingData(chainOverride) {
|
|
|
6477
6606
|
if (usdValue <= 0) continue;
|
|
6478
6607
|
balances.push({
|
|
6479
6608
|
token: symbol,
|
|
6480
|
-
balance: parseFloat(td.
|
|
6609
|
+
balance: parseFloat(td.balance || "0"),
|
|
6481
6610
|
usdValue
|
|
6482
6611
|
});
|
|
6483
6612
|
}
|
|
@@ -6759,11 +6888,13 @@ function PortfolioBalanceCard({
|
|
|
6759
6888
|
totalIdleUsd,
|
|
6760
6889
|
idleBalances,
|
|
6761
6890
|
earnAccountAddress,
|
|
6891
|
+
walletAddress,
|
|
6762
6892
|
onViewPositions,
|
|
6763
6893
|
positionCount,
|
|
6764
6894
|
totalEarned = 0,
|
|
6765
6895
|
showTopUp = true,
|
|
6766
|
-
onTopUp
|
|
6896
|
+
onTopUp,
|
|
6897
|
+
onSwap
|
|
6767
6898
|
}) {
|
|
6768
6899
|
const [showBalancesModal, setShowBalancesModal] = react.useState(false);
|
|
6769
6900
|
const tokenBalances = idleBalances.map((b) => ({
|
|
@@ -6804,39 +6935,59 @@ function PortfolioBalanceCard({
|
|
|
6804
6935
|
]
|
|
6805
6936
|
}
|
|
6806
6937
|
),
|
|
6807
|
-
/* @__PURE__ */ jsxRuntime.
|
|
6808
|
-
|
|
6938
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6939
|
+
"button",
|
|
6940
|
+
{
|
|
6941
|
+
onClick: () => setShowBalancesModal(true),
|
|
6942
|
+
className: "transition-opacity hover:opacity-80",
|
|
6943
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6944
|
+
"span",
|
|
6945
|
+
{
|
|
6946
|
+
className: "font-bold",
|
|
6947
|
+
style: {
|
|
6948
|
+
color: "var(--compass-color-text)",
|
|
6949
|
+
fontSize: "2rem",
|
|
6950
|
+
lineHeight: "1"
|
|
6951
|
+
},
|
|
6952
|
+
children: formatUSD(totalUsd)
|
|
6953
|
+
}
|
|
6954
|
+
)
|
|
6955
|
+
}
|
|
6956
|
+
),
|
|
6957
|
+
(onSwap || showTopUp && onTopUp) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", style: { gap: "6px", marginTop: "calc(var(--compass-spacing-unit) * 0.5)" }, children: [
|
|
6958
|
+
onSwap && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6809
6959
|
"button",
|
|
6810
6960
|
{
|
|
6811
|
-
onClick:
|
|
6812
|
-
className: "transition-
|
|
6813
|
-
|
|
6814
|
-
"
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
}
|
|
6824
|
-
|
|
6961
|
+
onClick: onSwap,
|
|
6962
|
+
className: "flex items-center justify-center font-medium transition-all hover:opacity-80 w-full",
|
|
6963
|
+
style: {
|
|
6964
|
+
backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-surface))",
|
|
6965
|
+
border: "1px solid var(--compass-color-border)",
|
|
6966
|
+
color: "var(--compass-color-text-secondary)",
|
|
6967
|
+
borderRadius: "var(--compass-border-radius-md)",
|
|
6968
|
+
padding: "8px 10px",
|
|
6969
|
+
gap: "6px",
|
|
6970
|
+
fontSize: "13px"
|
|
6971
|
+
},
|
|
6972
|
+
children: [
|
|
6973
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeftRight, { size: 14 }),
|
|
6974
|
+
"Swap"
|
|
6975
|
+
]
|
|
6825
6976
|
}
|
|
6826
6977
|
),
|
|
6827
6978
|
showTopUp && onTopUp && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6828
6979
|
"button",
|
|
6829
6980
|
{
|
|
6830
6981
|
onClick: onTopUp,
|
|
6831
|
-
className: "flex items-center font-medium transition-all hover:opacity-80",
|
|
6982
|
+
className: "flex items-center justify-center font-medium transition-all hover:opacity-80 w-full",
|
|
6832
6983
|
style: {
|
|
6833
6984
|
backgroundColor: "var(--compass-color-surface-elevated, var(--compass-color-surface))",
|
|
6834
6985
|
border: "1px solid var(--compass-color-border)",
|
|
6835
6986
|
color: "var(--compass-color-text-secondary)",
|
|
6836
6987
|
borderRadius: "var(--compass-border-radius-md)",
|
|
6837
|
-
padding: "
|
|
6838
|
-
gap: "
|
|
6839
|
-
fontSize: "
|
|
6988
|
+
padding: "8px 10px",
|
|
6989
|
+
gap: "6px",
|
|
6990
|
+
fontSize: "13px"
|
|
6840
6991
|
},
|
|
6841
6992
|
children: [
|
|
6842
6993
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { size: 14 }),
|
|
@@ -6909,7 +7060,8 @@ function PortfolioBalanceCard({
|
|
|
6909
7060
|
onClose: () => setShowBalancesModal(false),
|
|
6910
7061
|
balances: tokenBalances,
|
|
6911
7062
|
totalUsdValue: totalIdleUsd.toString(),
|
|
6912
|
-
earnAccountAddress
|
|
7063
|
+
earnAccountAddress,
|
|
7064
|
+
walletAddress
|
|
6913
7065
|
}
|
|
6914
7066
|
)
|
|
6915
7067
|
] });
|
|
@@ -6935,10 +7087,11 @@ function formatPercent(value) {
|
|
|
6935
7087
|
function PercentInput({ value, onChange }) {
|
|
6936
7088
|
const [localValue, setLocalValue] = react.useState(value.toString());
|
|
6937
7089
|
const [isFocused, setIsFocused] = react.useState(false);
|
|
6938
|
-
|
|
7090
|
+
const roundedStr = parseFloat(value.toFixed(2)).toString();
|
|
7091
|
+
if (!isFocused && localValue !== roundedStr) {
|
|
6939
7092
|
const parsed = parseFloat(localValue);
|
|
6940
7093
|
if (isNaN(parsed) || Math.abs(parsed - value) > 1e-3) {
|
|
6941
|
-
setLocalValue(
|
|
7094
|
+
setLocalValue(roundedStr);
|
|
6942
7095
|
}
|
|
6943
7096
|
}
|
|
6944
7097
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6949,7 +7102,7 @@ function PercentInput({ value, onChange }) {
|
|
|
6949
7102
|
value: isFocused ? localValue : formatPercent(value).replace("%", ""),
|
|
6950
7103
|
onFocus: () => {
|
|
6951
7104
|
setIsFocused(true);
|
|
6952
|
-
setLocalValue(value.toString());
|
|
7105
|
+
setLocalValue(parseFloat(value.toFixed(2)).toString());
|
|
6953
7106
|
},
|
|
6954
7107
|
onChange: (e) => {
|
|
6955
7108
|
const raw = e.target.value;
|
|
@@ -7073,7 +7226,7 @@ function AllocationEditor({
|
|
|
7073
7226
|
currentPos && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7074
7227
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-mono", style: { color: "var(--compass-color-text-secondary)", fontSize: "10px" }, children: formatUSD(currentPos.usdValue) }),
|
|
7075
7228
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: "var(--compass-color-success)", fontSize: "10px" }, children: [
|
|
7076
|
-
currentPos.apy.toFixed(
|
|
7229
|
+
currentPos.apy.toFixed(2),
|
|
7077
7230
|
"%"
|
|
7078
7231
|
] })
|
|
7079
7232
|
] }),
|
|
@@ -7177,7 +7330,6 @@ function AllocationEditor({
|
|
|
7177
7330
|
) })
|
|
7178
7331
|
] });
|
|
7179
7332
|
}
|
|
7180
|
-
var SUPPORTED_TOKENS2 = ["USDC", "USDT", "DAI", "WETH", "SBC", "AUSD"];
|
|
7181
7333
|
var EVM_CHAIN_IDS2 = {
|
|
7182
7334
|
ethereum: 1,
|
|
7183
7335
|
base: 8453,
|
|
@@ -7204,6 +7356,7 @@ function RebalancingWidget({
|
|
|
7204
7356
|
const { chainId: contextChainId, setChainId } = useChain();
|
|
7205
7357
|
const CHAIN_ID = chain || contextChainId;
|
|
7206
7358
|
const { address, signTypedData, isConnected, login, switchChain, walletChainId } = useEmbeddableWallet();
|
|
7359
|
+
const { earnAccountAddress } = useEarnAccount();
|
|
7207
7360
|
const queryClient = reactQuery.useQueryClient();
|
|
7208
7361
|
const { portfolio, earnAccountMarkets, isMarketsLoading, isLoading, isError, error, refetch } = useRebalancingData(chain);
|
|
7209
7362
|
const allowedVariableMarketIds = react.useMemo(() => {
|
|
@@ -7238,7 +7391,12 @@ function RebalancingWidget({
|
|
|
7238
7391
|
const [txHash, setTxHash] = react.useState(null);
|
|
7239
7392
|
const [hasInitializedTargets, setHasInitializedTargets] = react.useState(false);
|
|
7240
7393
|
const [isEarningsModalOpen, setIsEarningsModalOpen] = react.useState(false);
|
|
7394
|
+
const [isSwapModalOpen, setIsSwapModalOpen] = react.useState(false);
|
|
7241
7395
|
const [isAddMarketExpanded, setIsAddMarketExpanded] = react.useState(false);
|
|
7396
|
+
const balanceTokens = react.useMemo(() => {
|
|
7397
|
+
if (!portfolio?.idleBalances) return [];
|
|
7398
|
+
return portfolio.idleBalances.map((b) => b.token);
|
|
7399
|
+
}, [portfolio?.idleBalances]);
|
|
7242
7400
|
const [marketTab, setMarketTab] = react.useState("variable");
|
|
7243
7401
|
const [selectedMarket, setSelectedMarket] = react.useState(null);
|
|
7244
7402
|
const [selectedToken, setSelectedToken] = react.useState("USDC");
|
|
@@ -7257,25 +7415,26 @@ function RebalancingWidget({
|
|
|
7257
7415
|
setTxHash(null);
|
|
7258
7416
|
setHasInitializedTargets(false);
|
|
7259
7417
|
setIsAddMarketExpanded(false);
|
|
7418
|
+
setIsSwapModalOpen(false);
|
|
7260
7419
|
setSelectedMarket(null);
|
|
7261
7420
|
setDepositAmount("");
|
|
7262
7421
|
setDepositError(null);
|
|
7263
7422
|
setDepositStatus("");
|
|
7264
7423
|
}, [CHAIN_ID]);
|
|
7265
7424
|
react.useEffect(() => {
|
|
7266
|
-
if (portfolio && portfolio.positions.length > 0 && !hasInitializedTargets) {
|
|
7425
|
+
if (portfolio && portfolio.positions.length > 0 && !hasInitializedTargets && !isLoading) {
|
|
7267
7426
|
setTargets(
|
|
7268
7427
|
portfolio.positions.map((p) => ({
|
|
7269
7428
|
venueType: p.venueType,
|
|
7270
7429
|
venueAddress: p.venueAddress,
|
|
7271
7430
|
venueName: p.venueName,
|
|
7272
7431
|
token: p.token,
|
|
7273
|
-
targetPercent: p.allocationPercent
|
|
7432
|
+
targetPercent: parseFloat(p.allocationPercent.toFixed(2))
|
|
7274
7433
|
}))
|
|
7275
7434
|
);
|
|
7276
7435
|
setHasInitializedTargets(true);
|
|
7277
7436
|
}
|
|
7278
|
-
}, [portfolio, hasInitializedTargets]);
|
|
7437
|
+
}, [portfolio, hasInitializedTargets, isLoading]);
|
|
7279
7438
|
const state = react.useMemo(() => {
|
|
7280
7439
|
if (isLoading) return "loading";
|
|
7281
7440
|
if (!portfolio || portfolio.positions.length === 0) return "empty";
|
|
@@ -7310,7 +7469,7 @@ function RebalancingWidget({
|
|
|
7310
7469
|
venueAddress: p.venueAddress,
|
|
7311
7470
|
venueName: p.venueName,
|
|
7312
7471
|
token: p.token,
|
|
7313
|
-
targetPercent: p.allocationPercent
|
|
7472
|
+
targetPercent: parseFloat(p.allocationPercent.toFixed(2))
|
|
7314
7473
|
}))
|
|
7315
7474
|
);
|
|
7316
7475
|
setPreviewPlan(null);
|
|
@@ -7326,7 +7485,8 @@ function RebalancingWidget({
|
|
|
7326
7485
|
setTargets((prev) => prev.filter((_, i) => i !== index));
|
|
7327
7486
|
}, []);
|
|
7328
7487
|
const handleUpdatePercent = react.useCallback((index, value) => {
|
|
7329
|
-
|
|
7488
|
+
const rounded = parseFloat(Math.max(0, Math.min(100, value)).toFixed(2));
|
|
7489
|
+
setTargets((prev) => prev.map((t, i) => i === index ? { ...t, targetPercent: rounded } : t));
|
|
7330
7490
|
}, []);
|
|
7331
7491
|
const ensureCorrectChain = react.useCallback(async () => {
|
|
7332
7492
|
const targetChainId = EVM_CHAIN_IDS2[CHAIN_ID];
|
|
@@ -7698,7 +7858,7 @@ function RebalancingWidget({
|
|
|
7698
7858
|
]
|
|
7699
7859
|
}
|
|
7700
7860
|
),
|
|
7701
|
-
state === "empty" && /* @__PURE__ */ jsxRuntime.
|
|
7861
|
+
state === "empty" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7702
7862
|
"div",
|
|
7703
7863
|
{
|
|
7704
7864
|
className: "p-8 text-center",
|
|
@@ -7706,7 +7866,32 @@ function RebalancingWidget({
|
|
|
7706
7866
|
backgroundColor: "var(--compass-color-surface)",
|
|
7707
7867
|
borderRadius: "var(--compass-border-radius-xl)"
|
|
7708
7868
|
},
|
|
7709
|
-
children: [
|
|
7869
|
+
children: !isConnected ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7870
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7871
|
+
"p",
|
|
7872
|
+
{
|
|
7873
|
+
className: "text-lg font-semibold mb-2",
|
|
7874
|
+
style: { color: "var(--compass-color-text)" },
|
|
7875
|
+
children: "Connect your wallet"
|
|
7876
|
+
}
|
|
7877
|
+
),
|
|
7878
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm mb-4", style: { color: "var(--compass-color-text-secondary)" }, children: "Connect your wallet to view and manage your DeFi portfolio." }),
|
|
7879
|
+
login && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7880
|
+
"button",
|
|
7881
|
+
{
|
|
7882
|
+
onClick: login,
|
|
7883
|
+
className: "font-semibold transition-all",
|
|
7884
|
+
style: {
|
|
7885
|
+
backgroundColor: "var(--compass-color-primary)",
|
|
7886
|
+
color: "var(--compass-color-primary-text, white)",
|
|
7887
|
+
borderRadius: "var(--compass-border-radius-lg)",
|
|
7888
|
+
padding: "calc(var(--compass-spacing-unit) * 0.75) calc(var(--compass-spacing-unit) * 1.5)",
|
|
7889
|
+
fontSize: "0.875rem"
|
|
7890
|
+
},
|
|
7891
|
+
children: "Connect Wallet"
|
|
7892
|
+
}
|
|
7893
|
+
)
|
|
7894
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7710
7895
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7711
7896
|
"p",
|
|
7712
7897
|
{
|
|
@@ -7716,7 +7901,7 @@ function RebalancingWidget({
|
|
|
7716
7901
|
}
|
|
7717
7902
|
),
|
|
7718
7903
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", style: { color: "var(--compass-color-text-secondary)" }, children: "Deposit into a vault, Aave market, or Pendle market to start rebalancing." })
|
|
7719
|
-
]
|
|
7904
|
+
] })
|
|
7720
7905
|
}
|
|
7721
7906
|
),
|
|
7722
7907
|
state !== "loading" && state !== "empty" && portfolio && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", style: { gap: "calc(var(--compass-spacing-unit) * 0.75)" }, children: [
|
|
@@ -7726,11 +7911,14 @@ function RebalancingWidget({
|
|
|
7726
7911
|
totalUsd: portfolio.totalUsd,
|
|
7727
7912
|
totalIdleUsd: portfolio.totalIdleUsd,
|
|
7728
7913
|
idleBalances: portfolio.idleBalances,
|
|
7914
|
+
earnAccountAddress: earnAccountAddress ?? void 0,
|
|
7915
|
+
walletAddress: address ?? void 0,
|
|
7729
7916
|
onViewPositions: () => setIsEarningsModalOpen(true),
|
|
7730
7917
|
positionCount: portfolio.positions.length,
|
|
7731
7918
|
totalEarned,
|
|
7732
7919
|
showTopUp,
|
|
7733
|
-
onTopUp: () => earnBalanceRef.current?.openTransferModal()
|
|
7920
|
+
onTopUp: () => earnBalanceRef.current?.openTransferModal(),
|
|
7921
|
+
onSwap: balanceTokens.length > 0 ? () => setIsSwapModalOpen(true) : void 0
|
|
7734
7922
|
}
|
|
7735
7923
|
),
|
|
7736
7924
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7850,7 +8038,7 @@ function RebalancingWidget({
|
|
|
7850
8038
|
boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
|
|
7851
8039
|
minWidth: "100px"
|
|
7852
8040
|
},
|
|
7853
|
-
children:
|
|
8041
|
+
children: balanceTokens.map((token) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
7854
8042
|
"button",
|
|
7855
8043
|
{
|
|
7856
8044
|
onClick: () => {
|
|
@@ -8031,7 +8219,25 @@ function RebalancingWidget({
|
|
|
8031
8219
|
children: [
|
|
8032
8220
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { size: 24, className: "mx-auto mb-2", style: { color: "var(--compass-color-success)" } }),
|
|
8033
8221
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold mb-1", style: { color: "var(--compass-color-success)" }, children: "Rebalance Complete" }),
|
|
8034
|
-
/* @__PURE__ */ jsxRuntime.
|
|
8222
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
8223
|
+
"button",
|
|
8224
|
+
{
|
|
8225
|
+
onClick: () => navigator.clipboard.writeText(txHash),
|
|
8226
|
+
className: "inline-flex items-center justify-center gap-1.5 text-xs font-mono break-all mx-auto",
|
|
8227
|
+
style: {
|
|
8228
|
+
color: "var(--compass-color-text-secondary)",
|
|
8229
|
+
background: "none",
|
|
8230
|
+
border: "none",
|
|
8231
|
+
cursor: "pointer",
|
|
8232
|
+
padding: 0
|
|
8233
|
+
},
|
|
8234
|
+
title: "Copy transaction hash",
|
|
8235
|
+
children: [
|
|
8236
|
+
txHash,
|
|
8237
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { size: 12, className: "flex-shrink-0", style: { color: "var(--compass-color-text-tertiary)" } })
|
|
8238
|
+
]
|
|
8239
|
+
}
|
|
8240
|
+
)
|
|
8035
8241
|
]
|
|
8036
8242
|
}
|
|
8037
8243
|
),
|
|
@@ -8190,6 +8396,30 @@ function RebalancingWidget({
|
|
|
8190
8396
|
}
|
|
8191
8397
|
) }),
|
|
8192
8398
|
/* @__PURE__ */ jsxRuntime.jsx(EarnAccountBalance, { ref: earnBalanceRef, compact: true, hideVisual: true, onTransferComplete: () => refetch() }),
|
|
8399
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8400
|
+
ActionModal,
|
|
8401
|
+
{
|
|
8402
|
+
isOpen: isSwapModalOpen,
|
|
8403
|
+
onClose: () => setIsSwapModalOpen(false),
|
|
8404
|
+
title: "Swap Tokens",
|
|
8405
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8406
|
+
SwapForm,
|
|
8407
|
+
{
|
|
8408
|
+
availableFromTokens: balanceTokens,
|
|
8409
|
+
balances: Object.fromEntries(
|
|
8410
|
+
(portfolio?.idleBalances || []).map((b) => [b.token, b.balance.toString()])
|
|
8411
|
+
),
|
|
8412
|
+
onSwapSuccess: () => {
|
|
8413
|
+
setIsSwapModalOpen(false);
|
|
8414
|
+
refetch();
|
|
8415
|
+
setTimeout(() => refetch(), 5e3);
|
|
8416
|
+
setTimeout(() => refetch(), 15e3);
|
|
8417
|
+
},
|
|
8418
|
+
onSwapError: onError
|
|
8419
|
+
}
|
|
8420
|
+
)
|
|
8421
|
+
}
|
|
8422
|
+
),
|
|
8193
8423
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8194
8424
|
EarningsModal,
|
|
8195
8425
|
{
|
|
@@ -8247,7 +8477,6 @@ function ActionList({ actions }) {
|
|
|
8247
8477
|
|
|
8248
8478
|
// src/components/CompassEarnWidget/presets.ts
|
|
8249
8479
|
var allTabs = [
|
|
8250
|
-
{ id: "swap", label: "Swap", enabled: true },
|
|
8251
8480
|
{ id: "rebalance", label: "Rebalance", enabled: true },
|
|
8252
8481
|
// TODO: Positions tab temporarily disabled - needs more work on API response handling
|
|
8253
8482
|
{ id: "positions", label: "Positions", enabled: false }
|
|
@@ -8256,22 +8485,16 @@ function getTabsForPreset(preset) {
|
|
|
8256
8485
|
switch (preset) {
|
|
8257
8486
|
case "full":
|
|
8258
8487
|
return allTabs;
|
|
8259
|
-
case "swap-only":
|
|
8260
|
-
return allTabs.map((tab) => ({
|
|
8261
|
-
...tab,
|
|
8262
|
-
enabled: tab.id === "swap"
|
|
8263
|
-
}));
|
|
8264
8488
|
default:
|
|
8265
8489
|
return allTabs;
|
|
8266
8490
|
}
|
|
8267
8491
|
}
|
|
8268
8492
|
function getDefaultTab(tabs) {
|
|
8269
8493
|
const enabledTab = tabs.find((t) => t.enabled);
|
|
8270
|
-
return enabledTab?.id || "
|
|
8494
|
+
return enabledTab?.id || "rebalance";
|
|
8271
8495
|
}
|
|
8272
8496
|
function CompassEarnWidget({
|
|
8273
8497
|
preset = "full",
|
|
8274
|
-
enableSwap,
|
|
8275
8498
|
enablePositions,
|
|
8276
8499
|
enableRebalance,
|
|
8277
8500
|
defaultTab,
|
|
@@ -8283,12 +8506,11 @@ function CompassEarnWidget({
|
|
|
8283
8506
|
const baseTabs = getTabsForPreset(preset);
|
|
8284
8507
|
return baseTabs.map((tab) => {
|
|
8285
8508
|
let enabled = tab.enabled;
|
|
8286
|
-
if (tab.id === "swap" && enableSwap !== void 0) enabled = enableSwap;
|
|
8287
8509
|
if (tab.id === "positions" && enablePositions !== void 0) enabled = enablePositions;
|
|
8288
8510
|
if (tab.id === "rebalance" && enableRebalance !== void 0) enabled = enableRebalance;
|
|
8289
8511
|
return { ...tab, enabled };
|
|
8290
8512
|
});
|
|
8291
|
-
}, [preset,
|
|
8513
|
+
}, [preset, enablePositions, enableRebalance]);
|
|
8292
8514
|
const enabledTabs = tabs.filter((t) => t.enabled);
|
|
8293
8515
|
const initialTab = defaultTab && tabs.find((t) => t.id === defaultTab)?.enabled ? defaultTab : getDefaultTab(tabs);
|
|
8294
8516
|
const [activeTab, setActiveTab] = react.useState(initialTab);
|
|
@@ -8329,7 +8551,6 @@ function CompassEarnWidget({
|
|
|
8329
8551
|
}
|
|
8330
8552
|
),
|
|
8331
8553
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
8332
|
-
activeTab === "swap" && /* @__PURE__ */ jsxRuntime.jsx(SwapWidget, {}),
|
|
8333
8554
|
activeTab === "rebalance" && /* @__PURE__ */ jsxRuntime.jsx(RebalancingWidget, {}),
|
|
8334
8555
|
activeTab === "positions" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8335
8556
|
EarnPositionsList,
|
|
@@ -8368,14 +8589,14 @@ exports.CHAINS = CHAINS;
|
|
|
8368
8589
|
exports.ChainSwitcher = ChainSwitcher;
|
|
8369
8590
|
exports.CompassEarnWidget = CompassEarnWidget;
|
|
8370
8591
|
exports.CompassProvider = CompassProvider;
|
|
8371
|
-
exports.
|
|
8592
|
+
exports.CopyableAddress = CopyableAddress;
|
|
8372
8593
|
exports.DepositWithdrawForm = DepositWithdrawForm;
|
|
8373
8594
|
exports.EarnAccount = EarnAccount;
|
|
8374
8595
|
exports.EarnAccountBalance = EarnAccountBalance;
|
|
8375
8596
|
exports.EarnAccountGuard = EarnAccountGuard;
|
|
8376
8597
|
exports.PnLSummary = PnLSummary;
|
|
8377
8598
|
exports.RebalancingWidget = RebalancingWidget;
|
|
8378
|
-
exports.
|
|
8599
|
+
exports.SwapForm = SwapForm;
|
|
8379
8600
|
exports.ThemeProvider = ThemeProvider;
|
|
8380
8601
|
exports.TransactionHistory = TransactionHistory;
|
|
8381
8602
|
exports.WalletStatus = WalletStatus;
|