From 446eec29d7a3403dcfe17a4fc1b86679e90841e5 Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Thu, 7 Sep 2023 20:19:07 +0800
Subject: [PATCH 001/351] feat(mfi-v2-ui): bootstrap mobile components tree
---
apps/marginfi-v2-ui/package.json | 1 +
.../src/components/Navbar/index.tsx | 3 -
.../{ => common}/useFirebaseAccount.tsx | 0
.../{ => common}/useWalletContext.tsx | 0
.../AccountSummary/AccountSummary.tsx | 2 +-
.../AccountSummary/GlobalStats.tsx | 2 +-
.../AccountSummary/UserStats.tsx | 2 +-
.../{ => desktop}/AccountSummary/index.tsx | 0
.../AccountSummary/style.module.css | 0
.../AssetsList/AssetRow/AssetRow.tsx | 2 +-
.../AssetsList/AssetRow/AssetRowAction.tsx | 0
.../AssetsList/AssetRow/AssetRowInputBox.tsx | 0
.../AssetsList/AssetRow/index.ts | 0
.../{ => desktop}/AssetsList/AssetsList.tsx | 2 +-
.../AssetsList/BorrowLendToggle.tsx | 0
.../{ => desktop}/AssetsList/index.ts | 0
.../src/components/{ => desktop}/Banner.tsx | 0
.../{ => desktop}/CampaignWizard.tsx | 2 +-
.../{ => desktop}/Countdown.module.css | 0
.../components/{ => desktop}/Countdown.tsx | 0
.../DesktopNavbar}/AirdropZone.module.css | 2 +-
.../DesktopNavbar}/AirdropZone.tsx | 2 +-
.../DesktopNavbar/DesktopNavbar.module.css} | 0
.../DesktopNavbar/DesktopNavbar.tsx} | 8 +-
.../DesktopNavbar}/WalletButton.tsx | 2 +-
.../desktop/DesktopNavbar/index.tsx | 3 +
.../components/{ => desktop}/Earn/index.tsx | 6 +-
.../{ => desktop}/Footer/Footer.tsx | 0
.../components/{ => desktop}/Footer/index.tsx | 0
.../{ => desktop}/OverlaySpinner.tsx | 0
.../components/{ => desktop}/PageHeader.tsx | 0
.../src/components/{ => desktop}/Tooltip.tsx | 0
.../UserPositionRow/UserPositionRow.tsx | 0
.../UserPositionRow/UserPositionRowAction.tsx | 0
.../UserPositionRowInputBox.tsx | 0
.../UserPositions/UserPositionRow/index.tsx | 0
.../UserPositions/UserPositions.tsx | 0
.../{ => desktop}/UserPositions/index.tsx | 0
apps/marginfi-v2-ui/src/components/index.tsx | 8 -
.../DesktopNavbar/AirdropZone.module.css | 98 ++++++++++++
.../mobile/DesktopNavbar/AirdropZone.tsx | 150 ++++++++++++++++++
.../DesktopNavbar/MobileNavbar.module.css | 16 ++
.../mobile/DesktopNavbar/MobileNavbar.tsx | 76 +++++++++
.../mobile/DesktopNavbar/WalletButton.tsx | 22 +++
.../components/mobile/DesktopNavbar/index.tsx | 3 +
apps/marginfi-v2-ui/src/mediaQueries.ts | 14 ++
apps/marginfi-v2-ui/src/pages/_app.tsx | 15 +-
apps/marginfi-v2-ui/src/pages/bridge.tsx | 4 +-
apps/marginfi-v2-ui/src/pages/earn.tsx | 2 +-
apps/marginfi-v2-ui/src/pages/index.tsx | 21 ++-
apps/marginfi-v2-ui/src/pages/lip.tsx | 6 +-
apps/marginfi-v2-ui/src/pages/points.tsx | 6 +-
apps/marginfi-v2-ui/src/pages/swap.tsx | 4 +-
.../marginfi-v2-ui/src/pages/terms/points.tsx | 2 +-
yarn.lock | 31 +++-
55 files changed, 466 insertions(+), 51 deletions(-)
delete mode 100644 apps/marginfi-v2-ui/src/components/Navbar/index.tsx
rename apps/marginfi-v2-ui/src/components/{ => common}/useFirebaseAccount.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => common}/useWalletContext.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AccountSummary/AccountSummary.tsx (94%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AccountSummary/GlobalStats.tsx (99%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AccountSummary/UserStats.tsx (99%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AccountSummary/index.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AccountSummary/style.module.css (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AssetsList/AssetRow/AssetRow.tsx (99%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AssetsList/AssetRow/AssetRowAction.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AssetsList/AssetRow/AssetRowInputBox.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AssetsList/AssetRow/index.ts (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AssetsList/AssetsList.tsx (99%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AssetsList/BorrowLendToggle.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/AssetsList/index.ts (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/Banner.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/CampaignWizard.tsx (99%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/Countdown.module.css (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/Countdown.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{Navbar => desktop/DesktopNavbar}/AirdropZone.module.css (96%)
rename apps/marginfi-v2-ui/src/components/{Navbar => desktop/DesktopNavbar}/AirdropZone.tsx (98%)
rename apps/marginfi-v2-ui/src/components/{Navbar/Navbar.module.css => desktop/DesktopNavbar/DesktopNavbar.module.css} (100%)
rename apps/marginfi-v2-ui/src/components/{Navbar/Navbar.tsx => desktop/DesktopNavbar/DesktopNavbar.tsx} (97%)
rename apps/marginfi-v2-ui/src/components/{Navbar => desktop/DesktopNavbar}/WalletButton.tsx (89%)
create mode 100644 apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/index.tsx
rename apps/marginfi-v2-ui/src/components/{ => desktop}/Earn/index.tsx (99%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/Footer/Footer.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/Footer/index.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/OverlaySpinner.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/PageHeader.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/Tooltip.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/UserPositions/UserPositionRow/UserPositionRow.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/UserPositions/UserPositionRow/UserPositionRowAction.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/UserPositions/UserPositionRow/UserPositionRowInputBox.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/UserPositions/UserPositionRow/index.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/UserPositions/UserPositions.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => desktop}/UserPositions/index.tsx (100%)
delete mode 100644 apps/marginfi-v2-ui/src/components/index.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.module.css
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.module.css
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/index.tsx
create mode 100644 apps/marginfi-v2-ui/src/mediaQueries.ts
diff --git a/apps/marginfi-v2-ui/package.json b/apps/marginfi-v2-ui/package.json
index 4f42be0b9b..3a7b702260 100644
--- a/apps/marginfi-v2-ui/package.json
+++ b/apps/marginfi-v2-ui/package.json
@@ -40,6 +40,7 @@
"react-hotkeys-hook": "^4.4.1",
"react-katex": "^3.0.1",
"react-number-format": "^5.2.2",
+ "react-responsive": "^9.0.2",
"react-spinners": "^0.13.8",
"react-toastify": "^9.1.1",
"sharp": "^0.31.3",
diff --git a/apps/marginfi-v2-ui/src/components/Navbar/index.tsx b/apps/marginfi-v2-ui/src/components/Navbar/index.tsx
deleted file mode 100644
index 78d24d8447..0000000000
--- a/apps/marginfi-v2-ui/src/components/Navbar/index.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-import { Navbar } from "./Navbar";
-
-export { Navbar };
diff --git a/apps/marginfi-v2-ui/src/components/useFirebaseAccount.tsx b/apps/marginfi-v2-ui/src/components/common/useFirebaseAccount.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/useFirebaseAccount.tsx
rename to apps/marginfi-v2-ui/src/components/common/useFirebaseAccount.tsx
diff --git a/apps/marginfi-v2-ui/src/components/useWalletContext.tsx b/apps/marginfi-v2-ui/src/components/common/useWalletContext.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/useWalletContext.tsx
rename to apps/marginfi-v2-ui/src/components/common/useWalletContext.tsx
diff --git a/apps/marginfi-v2-ui/src/components/AccountSummary/AccountSummary.tsx b/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/AccountSummary.tsx
similarity index 94%
rename from apps/marginfi-v2-ui/src/components/AccountSummary/AccountSummary.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/AccountSummary/AccountSummary.tsx
index ade5b63e08..e8f06d0c79 100644
--- a/apps/marginfi-v2-ui/src/components/AccountSummary/AccountSummary.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/AccountSummary.tsx
@@ -2,7 +2,7 @@ import React, { FC } from "react";
import { UserStats } from "./UserStats";
import { useMrgnlendStore } from "~/store";
import dynamic from "next/dynamic";
-import { useWalletContext } from "../useWalletContext";
+import { useWalletContext } from "../../common/useWalletContext";
const GlobalStats = dynamic(async () => (await import("./GlobalStats")).GlobalStats, { ssr: false });
diff --git a/apps/marginfi-v2-ui/src/components/AccountSummary/GlobalStats.tsx b/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/GlobalStats.tsx
similarity index 99%
rename from apps/marginfi-v2-ui/src/components/AccountSummary/GlobalStats.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/AccountSummary/GlobalStats.tsx
index 3ee2b6c0a3..e34da6210c 100644
--- a/apps/marginfi-v2-ui/src/components/AccountSummary/GlobalStats.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/GlobalStats.tsx
@@ -2,7 +2,7 @@ import { Typography, Skeleton } from "@mui/material";
import Image from "next/image";
import Link from "next/link";
import { FC } from "react";
-import { MrgnTooltip } from "~/components/Tooltip";
+import { MrgnTooltip } from "~/components/desktop/Tooltip";
import styles from "./style.module.css";
import { numeralFormatter } from "@mrgnlabs/mrgn-common";
diff --git a/apps/marginfi-v2-ui/src/components/AccountSummary/UserStats.tsx b/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/UserStats.tsx
similarity index 99%
rename from apps/marginfi-v2-ui/src/components/AccountSummary/UserStats.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/AccountSummary/UserStats.tsx
index 73ff1d803f..1fe1c66882 100644
--- a/apps/marginfi-v2-ui/src/components/AccountSummary/UserStats.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/UserStats.tsx
@@ -2,7 +2,7 @@ import { Typography, Skeleton } from "@mui/material";
import Image from "next/image";
import Link from "next/link";
import { FC, useMemo } from "react";
-import { MrgnTooltip } from "~/components/Tooltip";
+import { MrgnTooltip } from "~/components/desktop/Tooltip";
import React from "react";
import { AccountSummary } from "@mrgnlabs/marginfi-v2-ui-state";
import { usdFormatter, numeralFormatter, usdFormatterDyn, percentFormatter } from "@mrgnlabs/mrgn-common";
diff --git a/apps/marginfi-v2-ui/src/components/AccountSummary/index.tsx b/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/index.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/AccountSummary/index.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/AccountSummary/index.tsx
diff --git a/apps/marginfi-v2-ui/src/components/AccountSummary/style.module.css b/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/style.module.css
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/AccountSummary/style.module.css
rename to apps/marginfi-v2-ui/src/components/desktop/AccountSummary/style.module.css
diff --git a/apps/marginfi-v2-ui/src/components/AssetsList/AssetRow/AssetRow.tsx b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
similarity index 99%
rename from apps/marginfi-v2-ui/src/components/AssetsList/AssetRow/AssetRow.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
index d2c5ff5078..828a4da588 100644
--- a/apps/marginfi-v2-ui/src/components/AssetsList/AssetRow/AssetRow.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
@@ -27,7 +27,7 @@ import {
ExtendedBankMetadata,
} from "@mrgnlabs/marginfi-v2-ui-state";
import { MarginfiAccountWrapper, PriceBias } from "@mrgnlabs/marginfi-client-v2";
-import { useWalletContext } from "~/components/useWalletContext";
+import { useWalletContext } from "~/components/common/useWalletContext";
const CLOSE_BALANCE_TOAST_ID = "close-balance";
const BORROW_OR_LEND_TOAST_ID = "borrow-or-lend";
diff --git a/apps/marginfi-v2-ui/src/components/AssetsList/AssetRow/AssetRowAction.tsx b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRowAction.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/AssetsList/AssetRow/AssetRowAction.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRowAction.tsx
diff --git a/apps/marginfi-v2-ui/src/components/AssetsList/AssetRow/AssetRowInputBox.tsx b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRowInputBox.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/AssetsList/AssetRow/AssetRowInputBox.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRowInputBox.tsx
diff --git a/apps/marginfi-v2-ui/src/components/AssetsList/AssetRow/index.ts b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/index.ts
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/AssetsList/AssetRow/index.ts
rename to apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/index.ts
diff --git a/apps/marginfi-v2-ui/src/components/AssetsList/AssetsList.tsx b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
similarity index 99%
rename from apps/marginfi-v2-ui/src/components/AssetsList/AssetsList.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
index 051d270f71..244fdc86cd 100644
--- a/apps/marginfi-v2-ui/src/components/AssetsList/AssetsList.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
@@ -9,7 +9,7 @@ import AssetRow from "./AssetRow";
import { useMrgnlendStore, useUserProfileStore } from "~/store";
import { useHotkeys } from "react-hotkeys-hook";
import { LoadingAsset } from "./AssetRow/AssetRow";
-import { useWalletContext } from "../useWalletContext";
+import { useWalletContext } from "../../common/useWalletContext";
const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
diff --git a/apps/marginfi-v2-ui/src/components/AssetsList/BorrowLendToggle.tsx b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/BorrowLendToggle.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/AssetsList/BorrowLendToggle.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/AssetsList/BorrowLendToggle.tsx
diff --git a/apps/marginfi-v2-ui/src/components/AssetsList/index.ts b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/index.ts
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/AssetsList/index.ts
rename to apps/marginfi-v2-ui/src/components/desktop/AssetsList/index.ts
diff --git a/apps/marginfi-v2-ui/src/components/Banner.tsx b/apps/marginfi-v2-ui/src/components/desktop/Banner.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/Banner.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/Banner.tsx
diff --git a/apps/marginfi-v2-ui/src/components/CampaignWizard.tsx b/apps/marginfi-v2-ui/src/components/desktop/CampaignWizard.tsx
similarity index 99%
rename from apps/marginfi-v2-ui/src/components/CampaignWizard.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/CampaignWizard.tsx
index ee3cc497d7..6c2747e447 100644
--- a/apps/marginfi-v2-ui/src/components/CampaignWizard.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/CampaignWizard.tsx
@@ -20,7 +20,7 @@ import { NumberFormatValues, NumericFormat } from "react-number-format";
import { useMrgnlendStore } from "~/store";
import { computeGuaranteedApy } from "@mrgnlabs/lip-client";
import { EarnAction } from "./Earn";
-import { useWalletContext } from "./useWalletContext";
+import { useWalletContext } from "~/components/common/useWalletContext";
interface CampaignWizardInputBox {
value: number;
diff --git a/apps/marginfi-v2-ui/src/components/Countdown.module.css b/apps/marginfi-v2-ui/src/components/desktop/Countdown.module.css
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/Countdown.module.css
rename to apps/marginfi-v2-ui/src/components/desktop/Countdown.module.css
diff --git a/apps/marginfi-v2-ui/src/components/Countdown.tsx b/apps/marginfi-v2-ui/src/components/desktop/Countdown.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/Countdown.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/Countdown.tsx
diff --git a/apps/marginfi-v2-ui/src/components/Navbar/AirdropZone.module.css b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/AirdropZone.module.css
similarity index 96%
rename from apps/marginfi-v2-ui/src/components/Navbar/AirdropZone.module.css
rename to apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/AirdropZone.module.css
index 93349b375c..ec66d7dcfa 100644
--- a/apps/marginfi-v2-ui/src/components/Navbar/AirdropZone.module.css
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/AirdropZone.module.css
@@ -16,7 +16,7 @@
#overlay {
width: 100%;
height: 100%;
- background-image: url(../../../public/WaveBG2.png);
+ background-image: url(../../../../public/WaveBG2.png);
background-size: 444px;
padding: 20px 30px;
background-repeat: no-repeat;
diff --git a/apps/marginfi-v2-ui/src/components/Navbar/AirdropZone.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/AirdropZone.tsx
similarity index 98%
rename from apps/marginfi-v2-ui/src/components/Navbar/AirdropZone.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/AirdropZone.tsx
index 56e97ce843..a496b30197 100644
--- a/apps/marginfi-v2-ui/src/components/Navbar/AirdropZone.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/AirdropZone.tsx
@@ -10,7 +10,7 @@ import {
getAssociatedTokenAddressSync,
shortenAddress,
} from "@mrgnlabs/mrgn-common";
-import { useWalletContext } from "../useWalletContext";
+import { useWalletContext } from "../../common/useWalletContext";
const SOL_AMOUNT = 2 * 10 ** 9;
diff --git a/apps/marginfi-v2-ui/src/components/Navbar/Navbar.module.css b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.module.css
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/Navbar/Navbar.module.css
rename to apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.module.css
diff --git a/apps/marginfi-v2-ui/src/components/Navbar/Navbar.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
similarity index 97%
rename from apps/marginfi-v2-ui/src/components/Navbar/Navbar.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
index 093a7a21ab..a24713530a 100644
--- a/apps/marginfi-v2-ui/src/components/Navbar/Navbar.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
@@ -10,12 +10,12 @@ import { useMrgnlendStore, useUserProfileStore } from "~/store";
import { useRouter } from "next/router";
import { HotkeysEvent } from "react-hotkeys-hook/dist/types";
import { Badge } from "@mui/material";
-import { useFirebaseAccount } from "../useFirebaseAccount";
+import { useFirebaseAccount } from "../../common/useFirebaseAccount";
import { groupedNumberFormatterDyn, numeralFormatter } from "@mrgnlabs/mrgn-common";
-import { useWalletContext } from "../useWalletContext";
+import { useWalletContext } from "../../common/useWalletContext";
// @todo implement second pretty navbar row
-const Navbar: FC = () => {
+const DesktopNavbar: FC = () => {
useFirebaseAccount();
const { connected, walletAddress } = useWalletContext();
@@ -250,4 +250,4 @@ const Navbar: FC = () => {
);
};
-export { Navbar };
+export { DesktopNavbar };
diff --git a/apps/marginfi-v2-ui/src/components/Navbar/WalletButton.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/WalletButton.tsx
similarity index 89%
rename from apps/marginfi-v2-ui/src/components/Navbar/WalletButton.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/WalletButton.tsx
index dfbd690866..5e0cd4ee7e 100644
--- a/apps/marginfi-v2-ui/src/components/Navbar/WalletButton.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/WalletButton.tsx
@@ -1,6 +1,6 @@
import dynamic from "next/dynamic";
import { FC } from "react";
-import { useWalletContext } from "../useWalletContext";
+import { useWalletContext } from "../../common/useWalletContext";
const WalletMultiButtonDynamic = dynamic(
async () => (await import("@solana/wallet-adapter-react-ui")).WalletMultiButton,
diff --git a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/index.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/index.tsx
new file mode 100644
index 0000000000..5980855102
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/index.tsx
@@ -0,0 +1,3 @@
+import { DesktopNavbar } from "./DesktopNavbar";
+
+export { DesktopNavbar };
diff --git a/apps/marginfi-v2-ui/src/components/Earn/index.tsx b/apps/marginfi-v2-ui/src/components/desktop/Earn/index.tsx
similarity index 99%
rename from apps/marginfi-v2-ui/src/components/Earn/index.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/Earn/index.tsx
index 6d80b532f9..2b0760c16c 100644
--- a/apps/marginfi-v2-ui/src/components/Earn/index.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Earn/index.tsx
@@ -1,6 +1,6 @@
import React, { FC, MouseEventHandler, ReactNode, useCallback, useEffect, useMemo, useState } from "react";
import { useConnection, useWallet } from "@solana/wallet-adapter-react";
-import { PageHeader } from "~/components/PageHeader";
+import { PageHeader } from "~/components/desktop/PageHeader";
import { useLipClient } from "~/context";
import Button from "@mui/material/Button";
import Card from "@mui/material/Card";
@@ -28,10 +28,10 @@ import {
usdFormatterDyn,
} from "@mrgnlabs/mrgn-common";
import { Bank, PriceBias } from "@mrgnlabs/marginfi-client-v2";
-import { Countdown } from "~/components/Countdown";
+import { Countdown } from "~/components/desktop/Countdown";
import { toast } from "react-toastify";
import BigNumber from "bignumber.js";
-import { useWalletContext } from "~/components/useWalletContext";
+import { useWalletContext } from "~/components/common/useWalletContext";
import { useMrgnlendStore } from "~/store";
const Earn = () => {
diff --git a/apps/marginfi-v2-ui/src/components/Footer/Footer.tsx b/apps/marginfi-v2-ui/src/components/desktop/Footer/Footer.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/Footer/Footer.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/Footer/Footer.tsx
diff --git a/apps/marginfi-v2-ui/src/components/Footer/index.tsx b/apps/marginfi-v2-ui/src/components/desktop/Footer/index.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/Footer/index.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/Footer/index.tsx
diff --git a/apps/marginfi-v2-ui/src/components/OverlaySpinner.tsx b/apps/marginfi-v2-ui/src/components/desktop/OverlaySpinner.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/OverlaySpinner.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/OverlaySpinner.tsx
diff --git a/apps/marginfi-v2-ui/src/components/PageHeader.tsx b/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/PageHeader.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx
diff --git a/apps/marginfi-v2-ui/src/components/Tooltip.tsx b/apps/marginfi-v2-ui/src/components/desktop/Tooltip.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/Tooltip.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/Tooltip.tsx
diff --git a/apps/marginfi-v2-ui/src/components/UserPositions/UserPositionRow/UserPositionRow.tsx b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositionRow/UserPositionRow.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/UserPositions/UserPositionRow/UserPositionRow.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositionRow/UserPositionRow.tsx
diff --git a/apps/marginfi-v2-ui/src/components/UserPositions/UserPositionRow/UserPositionRowAction.tsx b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositionRow/UserPositionRowAction.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/UserPositions/UserPositionRow/UserPositionRowAction.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositionRow/UserPositionRowAction.tsx
diff --git a/apps/marginfi-v2-ui/src/components/UserPositions/UserPositionRow/UserPositionRowInputBox.tsx b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositionRow/UserPositionRowInputBox.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/UserPositions/UserPositionRow/UserPositionRowInputBox.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositionRow/UserPositionRowInputBox.tsx
diff --git a/apps/marginfi-v2-ui/src/components/UserPositions/UserPositionRow/index.tsx b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositionRow/index.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/UserPositions/UserPositionRow/index.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositionRow/index.tsx
diff --git a/apps/marginfi-v2-ui/src/components/UserPositions/UserPositions.tsx b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/UserPositions/UserPositions.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx
diff --git a/apps/marginfi-v2-ui/src/components/UserPositions/index.tsx b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/index.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/UserPositions/index.tsx
rename to apps/marginfi-v2-ui/src/components/desktop/UserPositions/index.tsx
diff --git a/apps/marginfi-v2-ui/src/components/index.tsx b/apps/marginfi-v2-ui/src/components/index.tsx
deleted file mode 100644
index 0dfa370c12..0000000000
--- a/apps/marginfi-v2-ui/src/components/index.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import { Navbar } from "./Navbar";
-import { Footer } from "./Footer";
-import { AccountSummary } from "./AccountSummary";
-import { AssetsList } from "./AssetsList";
-import { UserPositions } from "./UserPositions";
-import { Banner } from "./Banner";
-
-export { Navbar, Footer, AccountSummary, AssetsList, UserPositions, Banner };
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.module.css b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.module.css
new file mode 100644
index 0000000000..ec66d7dcfa
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.module.css
@@ -0,0 +1,98 @@
+#container {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ background: linear-gradient(180deg, #101416 0%, #080a0b 95.03%);
+ border-radius: 25px;
+ width: 40%;
+ max-width: 400px;
+ border: 2px solid #000;
+ font-family: "Aeonik Pro";
+ font-weight: 300;
+ font-size: 18px;
+}
+
+#overlay {
+ width: 100%;
+ height: 100%;
+ background-image: url(../../../../public/WaveBG2.png);
+ background-size: 444px;
+ padding: 20px 30px;
+ background-repeat: no-repeat;
+ background-position: right;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+#title {
+ margin: 0;
+ font-size: 25px;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+}
+
+#description {
+ width: 100%;
+ margin-top: 40px;
+ display: flex;
+ gap: 5px;
+ flex-direction: column;
+ text-align: center;
+ justify-content: space-between;
+ font-weight: 200;
+}
+
+#table {
+ width: 60%;
+ margin: 0;
+ justify-content: center;
+ justify-content: space-between;
+ font-weight: 300;
+ line-height: 25px;
+}
+
+.table-cell {
+ width: 100%;
+ padding-left: 0;
+ justify-content: center;
+}
+
+#special-row {
+ width: 90%;
+ margin-top: 30px;
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ gap: 10px;
+}
+
+#second-row {
+ margin-top: 10px;
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ gap: 15px;
+}
+
+#link-text {
+ margin-top: 50px;
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+}
+
+#copy-link {
+ margin-top: 30px;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ gap: 20px;
+}
+
+.action-button-disabled {
+ background-color: #6d6d6d !important;
+}
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.tsx b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.tsx
new file mode 100644
index 0000000000..a496b30197
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.tsx
@@ -0,0 +1,150 @@
+import { Button, Modal } from "@mui/material";
+import { FC, useCallback, useState } from "react";
+import styles from "./AirdropZone.module.css";
+import { PublicKey, Transaction } from "@solana/web3.js";
+import { useConnection, useWallet } from "@solana/wallet-adapter-react";
+import { makeAirdropCollateralIx } from "~/utils";
+import { toast } from "react-toastify";
+import {
+ createAssociatedTokenAccountInstruction,
+ getAssociatedTokenAddressSync,
+ shortenAddress,
+} from "@mrgnlabs/mrgn-common";
+import { useWalletContext } from "../../common/useWalletContext";
+
+const SOL_AMOUNT = 2 * 10 ** 9;
+
+const NOTSOL_AMOUNT = 10 * 10 ** 9;
+const NOTSOL_MINT = new PublicKey("4Bn9Wn1sgaD5KfMRZjxwKFcrUy6NKdyqLPtzddazYc4x");
+const NOTSOL_FAUCET = new PublicKey("tRqMXrkJysM78qhriPH8GmKza75e2ikqWSDwa3soxuB");
+
+const USDC_AMOUNT = 10 * 10 ** 6;
+const USDC_MINT = new PublicKey("F9jRT1xL7PCRepBuey5cQG5vWHFSbnvdWxJWKqtzMDsd");
+const USDC_FAUCET = new PublicKey("3ThaREisq3etoy9cvdzRgKypHsa8iTjMxj19AjETA1Fy");
+
+const AirdropZone: FC = () => {
+ const [isOpen, setIsOpen] = useState(false);
+ const { walletAddress, walletContextState } = useWalletContext();
+ const { connection } = useConnection();
+
+ const open = useCallback(async () => setIsOpen(true), []);
+ const close = useCallback(async () => setIsOpen(false), []);
+
+ const airdropToken = useCallback(
+ async (amount: number, mint: PublicKey, faucet: PublicKey) => {
+ if (faucet && walletAddress) {
+ const ataAddress = getAssociatedTokenAddressSync(mint, walletAddress!);
+ const ixs = [];
+ const solBalance = await connection.getBalance(walletAddress);
+ if (solBalance < 0.05) {
+ await connection.requestAirdrop(walletAddress, 100000000);
+ }
+ const ataAi = await connection.getAccountInfo(ataAddress);
+ if (!ataAi) {
+ ixs.push(createAssociatedTokenAccountInstruction(walletAddress, ataAddress, walletAddress, mint));
+ }
+ ixs.push(makeAirdropCollateralIx(amount, mint, ataAddress, faucet));
+
+ const tx = new Transaction();
+ tx.add(...ixs);
+
+ await walletContextState.sendTransaction(tx, connection, {
+ skipPreflight: true,
+ });
+ }
+ },
+ [connection, walletAddress, walletContextState]
+ );
+
+ if (!walletAddress) return null;
+
+ return (
+
+
+ Airdrop
+
+
+
+
+
💰 Airdrop Zone 💰
+
{
+ const toastId = toast.loading(`Airdropping ${USDC_AMOUNT} USDC`);
+ try {
+ await airdropToken(USDC_AMOUNT, USDC_MINT, USDC_FAUCET);
+ toast.update(toastId, {
+ render: `Airdropped ${USDC_AMOUNT} USDC to ${shortenAddress(walletAddress!)}`,
+ type: toast.TYPE.SUCCESS,
+ autoClose: 5000,
+ isLoading: false,
+ });
+ } catch (error: any) {
+ toast.update(toastId, {
+ render: `Error during USDC airdrop: ${error.message}`,
+ type: toast.TYPE.ERROR,
+ autoClose: 5000,
+ isLoading: false,
+ });
+ }
+ }}
+ >
+ Airdrop USDC
+
+
{
+ const toastId = toast.loading(`Airdropping ${NOTSOL_AMOUNT} SOL`);
+ try {
+ await airdropToken(NOTSOL_AMOUNT, NOTSOL_MINT, NOTSOL_FAUCET);
+ toast.update(toastId, {
+ render: `Airdropped ${NOTSOL_AMOUNT} notSOL to ${shortenAddress(walletAddress!)}`,
+ type: toast.TYPE.SUCCESS,
+ autoClose: 5000,
+ toastId,
+ isLoading: false,
+ });
+ } catch (error: any) {
+ toast.update(toastId, {
+ render: `Error during notSOL airdrop: ${error.message}`,
+ type: toast.TYPE.ERROR,
+ autoClose: 5000,
+ toastId,
+ isLoading: false,
+ });
+ }
+ }}
+ >
+ Airdrop notSOL
+
+
{
+ const toastId = toast.loading(`Airdropping ${SOL_AMOUNT} SOL`);
+ try {
+ await connection.requestAirdrop(walletAddress!, SOL_AMOUNT);
+ toast.update(toastId, {
+ render: `Airdropped ${SOL_AMOUNT} SOL to ${shortenAddress(walletAddress!)}`,
+ type: toast.TYPE.SUCCESS,
+ autoClose: 5000,
+ toastId,
+ isLoading: false,
+ });
+ } catch (error: any) {
+ toast.update(toastId, {
+ render: `Error during SOL airdrop: ${error.message}`,
+ type: toast.TYPE.ERROR,
+ autoClose: 5000,
+ toastId,
+ isLoading: false,
+ });
+ }
+ }}
+ >
+ Airdrop SOL
+
+
+
+
+
+ );
+};
+
+export default AirdropZone;
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.module.css b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.module.css
new file mode 100644
index 0000000000..41065f1898
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.module.css
@@ -0,0 +1,16 @@
+.airdrop-button {
+ background-color: rgba(21, 255, 0, 0.3) !important;
+ color: #c0c0c0 !important;
+ border: 1px solid #c0c0c0 !important;
+ padding: 0 10px !important;
+ height: 38px !important;
+ border-radius: 100px !important;
+}
+
+.airdrop-button:hover {
+ font-weight: bold;
+ background-color: transparent;
+ color: white;
+ border: 1px solid white;
+ border-radius: 100px;
+}
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx
new file mode 100644
index 0000000000..5269b30ee6
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx
@@ -0,0 +1,76 @@
+import { FC, useEffect } from "react";
+import Link from "next/link";
+import Image from "next/image";
+import AirdropZone from "./AirdropZone";
+import { useUserProfileStore } from "~/store";
+import { useRouter } from "next/router";
+import { useFirebaseAccount } from "../../common/useFirebaseAccount";
+import { useWalletContext } from "../../common/useWalletContext";
+
+// @todo implement second pretty navbar row
+const MobileNavbar: FC = () => {
+ useFirebaseAccount();
+
+ const { connected, walletAddress } = useWalletContext();
+ const router = useRouter();
+ const [fetchPoints] = useUserProfileStore((state) => [state.fetchPoints]);
+
+ useEffect(() => {
+ if (!walletAddress) return;
+ fetchPoints(walletAddress.toBase58()).catch(console.error);
+ }, [fetchPoints, walletAddress]);
+
+ return (
+
+
+
+
+
+
+
+
+ lend
+
+
+
+ swap
+
+
+ bridge
+
+
+
+ earn
+
+
+
+ omni
+
+ {process.env.NEXT_PUBLIC_MARGINFI_FEATURES_AIRDROP === "true" && connected &&
}
+
+
+
+
+ );
+};
+
+export { MobileNavbar };
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx
new file mode 100644
index 0000000000..4959bdf3d1
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx
@@ -0,0 +1,22 @@
+import dynamic from "next/dynamic";
+import { FC } from "react";
+import { useWalletContext } from "~/components/common/useWalletContext";
+
+const WalletMultiButtonDynamic = dynamic(
+ async () => (await import("@solana/wallet-adapter-react-ui")).WalletMultiButton,
+ { ssr: false }
+);
+
+const WalletButton: FC = () => {
+ const { connected } = useWalletContext();
+
+ return (
+
+
+ {!connected && CONNECT
}
+
+
+ );
+};
+
+export { WalletButton };
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/index.tsx b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/index.tsx
new file mode 100644
index 0000000000..928ef3dc1b
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/index.tsx
@@ -0,0 +1,3 @@
+import { MobileNavbar } from "./MobileNavbar";
+
+export { MobileNavbar };
diff --git a/apps/marginfi-v2-ui/src/mediaQueries.ts b/apps/marginfi-v2-ui/src/mediaQueries.ts
new file mode 100644
index 0000000000..da2f24058a
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/mediaQueries.ts
@@ -0,0 +1,14 @@
+import { FC } from 'react';
+import { useMediaQuery } from 'react-responsive';
+
+const Desktop: FC<{children: any}> = ({ children }) => {
+ const isDesktop = useMediaQuery({ minWidth: 992 });
+ return isDesktop ? children : null;
+};
+
+const Mobile: FC<{children: any}> = ({ children }) => {
+ const isMobile = useMediaQuery({ maxWidth: 992 });
+ return isMobile ? children : null;
+};
+
+export { Desktop, Mobile };
diff --git a/apps/marginfi-v2-ui/src/pages/_app.tsx b/apps/marginfi-v2-ui/src/pages/_app.tsx
index cc97a8f461..ac0fcccf6f 100644
--- a/apps/marginfi-v2-ui/src/pages/_app.tsx
+++ b/apps/marginfi-v2-ui/src/pages/_app.tsx
@@ -18,6 +18,9 @@ import "react-toastify/dist/ReactToastify.min.css";
import { ToastContainer } from "react-toastify";
import { Analytics } from "@vercel/analytics/react";
import dynamic from "next/dynamic";
+import { Desk } from "@mui/icons-material";
+import { Desktop, Mobile } from "~/mediaQueries";
+import { MobileNavbar } from "~/components/mobile/DesktopNavbar";
// Use require instead of import since order matters
require("@solana/wallet-adapter-react-ui/styles.css");
@@ -25,8 +28,8 @@ require("~/styles/globals.css");
require("~/styles/fonts.css");
require("~/styles/asset-borders.css");
-const Navbar = dynamic(async () => (await import("~/components/Navbar")).Navbar, { ssr: false });
-const Footer = dynamic(async () => (await import("~/components/Footer")).Footer, { ssr: false });
+const DesktopNavbar = dynamic(async () => (await import("~/components/desktop/DesktopNavbar")).DesktopNavbar, { ssr: false });
+const Footer = dynamic(async () => (await import("~/components/desktop/Footer")).Footer, { ssr: false });
// Matomo
const MATOMO_URL = "https://mrgn.matomo.cloud";
@@ -63,7 +66,13 @@ const MyApp = ({ Component, pageProps }: AppProps) => {
-
+
+
+
+
+
+
+
diff --git a/apps/marginfi-v2-ui/src/pages/bridge.tsx b/apps/marginfi-v2-ui/src/pages/bridge.tsx
index 3614d52579..ef0b695dd7 100644
--- a/apps/marginfi-v2-ui/src/pages/bridge.tsx
+++ b/apps/marginfi-v2-ui/src/pages/bridge.tsx
@@ -5,10 +5,10 @@ import config from "~/config";
import Script from "next/script";
import { toast } from "react-toastify";
import { useHotkeys } from "react-hotkeys-hook";
-import { PageHeaderBridge } from "~/components/PageHeader";
+import { PageHeaderBridge } from "~/components/desktop/PageHeader";
import { MayanWidgetColors, MayanWidgetConfigType } from "~/types";
import { useUserProfileStore } from "~/store";
-import { useWalletContext } from "~/components/useWalletContext";
+import { useWalletContext } from "~/components/common/useWalletContext";
const tokens = [
"0x0000000000000000000000000000000000000000", // SOL
diff --git a/apps/marginfi-v2-ui/src/pages/earn.tsx b/apps/marginfi-v2-ui/src/pages/earn.tsx
index a5ed12e3fb..23ed704801 100644
--- a/apps/marginfi-v2-ui/src/pages/earn.tsx
+++ b/apps/marginfi-v2-ui/src/pages/earn.tsx
@@ -2,7 +2,7 @@ import dynamic from "next/dynamic";
import React from "react";
import { LipClientProvider } from "~/context";
-const Earn = dynamic(async () => (await import("~/components/Earn")).Earn, { ssr: false });
+const Earn = dynamic(async () => (await import("~/components/desktop/Earn")).Earn, { ssr: false });
const EarnPage = () => {
return (
diff --git a/apps/marginfi-v2-ui/src/pages/index.tsx b/apps/marginfi-v2-ui/src/pages/index.tsx
index 2817a13d78..a437b76e88 100644
--- a/apps/marginfi-v2-ui/src/pages/index.tsx
+++ b/apps/marginfi-v2-ui/src/pages/index.tsx
@@ -1,19 +1,20 @@
import React, { useEffect } from "react";
-import { Banner } from "~/components";
-import { PageHeader } from "~/components/PageHeader";
-import { useWalletContext } from "~/components/useWalletContext";
+import { Banner } from "~/components/desktop/Banner";
+import { PageHeader } from "~/components/desktop/PageHeader";
+import { useWalletContext } from "~/components/common/useWalletContext";
import { shortenAddress } from "@mrgnlabs/mrgn-common";
import config from "~/config/marginfi";
import { useMrgnlendStore } from "../store";
import dynamic from "next/dynamic";
-import { OverlaySpinner } from "~/components/OverlaySpinner";
+import { OverlaySpinner } from "~/components/desktop/OverlaySpinner";
import { useConnection } from "@solana/wallet-adapter-react";
+import { Desktop, Mobile } from "~/mediaQueries";
-const AccountSummary = dynamic(async () => (await import("~/components/AccountSummary")).AccountSummary, {
+const AccountSummary = dynamic(async () => (await import("~/components/desktop/AccountSummary")).AccountSummary, {
ssr: false,
});
-const AssetsList = dynamic(async () => (await import("~/components/AssetsList")).AssetsList, { ssr: false });
-const UserPositions = dynamic(async () => (await import("~/components/UserPositions")).UserPositions, { ssr: false });
+const AssetsList = dynamic(async () => (await import("~/components/desktop/AssetsList")).AssetsList, { ssr: false });
+const UserPositions = dynamic(async () => (await import("~/components/desktop/UserPositions")).UserPositions, { ssr: false });
const Home = () => {
const { walletAddress, wallet, isOverride } = useWalletContext();
@@ -59,6 +60,7 @@ const Home = () => {
return (
<>
+
{walletAddress && selectedAccount && isOverride && (
@@ -80,6 +82,11 @@ const Home = () => {
{walletAddress && }
+
+
+
+ LETS GOOOOO
+
>
);
};
diff --git a/apps/marginfi-v2-ui/src/pages/lip.tsx b/apps/marginfi-v2-ui/src/pages/lip.tsx
index 85dd283c6a..5fe2c348ff 100644
--- a/apps/marginfi-v2-ui/src/pages/lip.tsx
+++ b/apps/marginfi-v2-ui/src/pages/lip.tsx
@@ -1,7 +1,7 @@
-import { PageHeader } from "~/components/PageHeader";
-import { CampaignWizard } from "~/components/CampaignWizard";
+import { PageHeader } from "~/components/desktop/PageHeader";
+import { CampaignWizard } from "~/components/desktop/CampaignWizard";
import { LipClientProvider } from "~/context";
-import { useWalletContext } from "~/components/useWalletContext";
+import { useWalletContext } from "~/components/common/useWalletContext";
const LIP = () => {
const { connected } = useWalletContext();
diff --git a/apps/marginfi-v2-ui/src/pages/points.tsx b/apps/marginfi-v2-ui/src/pages/points.tsx
index d9a5552134..542bb9cb35 100644
--- a/apps/marginfi-v2-ui/src/pages/points.tsx
+++ b/apps/marginfi-v2-ui/src/pages/points.tsx
@@ -18,20 +18,20 @@ import {
} from "@mui/material";
import { useConnection } from "@solana/wallet-adapter-react";
import { FC, useEffect, useState } from "react";
-import { PageHeader } from "~/components/PageHeader";
+import { PageHeader } from "~/components/desktop/PageHeader";
import FileCopyIcon from "@mui/icons-material/FileCopy";
import Link from "next/link";
import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
import { styled } from "@mui/material/styles";
import Image from "next/image";
import { useRouter } from "next/router";
-import { WalletButton } from "~/components/Navbar/WalletButton";
+import { WalletButton } from "~/components/desktop/DesktopNavbar/WalletButton";
import { grey } from "@mui/material/colors";
import { toast } from "react-toastify";
import { useUserProfileStore } from "~/store";
import { LeaderboardRow, fetchLeaderboardData, firebaseApi } from "@mrgnlabs/marginfi-v2-ui-state";
import { numeralFormatter, groupedNumberFormatterDyn } from "@mrgnlabs/mrgn-common";
-import { useWalletContext } from "~/components/useWalletContext";
+import { useWalletContext } from "~/components/common/useWalletContext";
const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
diff --git a/apps/marginfi-v2-ui/src/pages/swap.tsx b/apps/marginfi-v2-ui/src/pages/swap.tsx
index 3ac0f5ee7a..6c0b12455e 100644
--- a/apps/marginfi-v2-ui/src/pages/swap.tsx
+++ b/apps/marginfi-v2-ui/src/pages/swap.tsx
@@ -2,8 +2,8 @@
import { useEffect } from "react";
import config from "~/config";
-import { PageHeaderSwap } from "~/components/PageHeader";
-import { useWalletContext } from "~/components/useWalletContext";
+import { PageHeaderSwap } from "~/components/desktop/PageHeader";
+import { useWalletContext } from "~/components/common/useWalletContext";
const SwapPage = () => {
const { walletContextState } = useWalletContext();
diff --git a/apps/marginfi-v2-ui/src/pages/terms/points.tsx b/apps/marginfi-v2-ui/src/pages/terms/points.tsx
index 4d80151738..9a8bf555d3 100644
--- a/apps/marginfi-v2-ui/src/pages/terms/points.tsx
+++ b/apps/marginfi-v2-ui/src/pages/terms/points.tsx
@@ -1,5 +1,5 @@
import React from "react";
-import { PageHeader } from "~/components/PageHeader";
+import { PageHeader } from "~/components/desktop/PageHeader";
function Disclaimer() {
return (
diff --git a/yarn.lock b/yarn.lock
index 5e1d91c896..e79dc8ecd8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10653,6 +10653,11 @@ css-loader@^6.5.1:
postcss-value-parser "^4.2.0"
semver "^7.3.8"
+css-mediaquery@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/css-mediaquery/-/css-mediaquery-0.1.2.tgz#6a2c37344928618631c54bd33cedd301da18bea0"
+ integrity sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q==
+
css-minimizer-webpack-plugin@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz#ab78f781ced9181992fe7b6e4f3422e76429878f"
@@ -14058,7 +14063,7 @@ humanize-ms@^1.2.1:
dependencies:
ms "^2.0.0"
-hyphenate-style-name@^1.0.3:
+hyphenate-style-name@^1.0.0, hyphenate-style-name@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
@@ -16255,6 +16260,13 @@ marked@^4.0.10, marked@^4.0.16, marked@^4.2.12:
resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3"
integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==
+matchmediaquery@^0.3.0:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/matchmediaquery/-/matchmediaquery-0.3.1.tgz#8247edc47e499ebb7c58f62a9ff9ccf5b815c6d7"
+ integrity sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==
+ dependencies:
+ css-mediaquery "^0.1.2"
+
md5-file@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/md5-file/-/md5-file-3.2.3.tgz#f9bceb941eca2214a4c0727f5e700314e770f06f"
@@ -18528,7 +18540,7 @@ prompts@^2.0.1, prompts@^2.3.2, prompts@^2.4.0:
kleur "^3.0.3"
sisteransi "^1.0.5"
-prop-types@*, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
+prop-types@*, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -19109,6 +19121,16 @@ react-refresh@^0.4.0:
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.3.tgz#966f1750c191672e76e16c2efa569150cc73ab53"
integrity sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA==
+react-responsive@^9.0.2:
+ version "9.0.2"
+ resolved "https://registry.yarnpkg.com/react-responsive/-/react-responsive-9.0.2.tgz#34531ca77a61e7a8775714016d21241df7e4205c"
+ integrity sha512-+4CCab7z8G8glgJoRjAwocsgsv6VA2w7JPxFWHRc7kvz8mec1/K5LutNC2MG28Mn8mu6+bu04XZxHv5gyfT7xQ==
+ dependencies:
+ hyphenate-style-name "^1.0.0"
+ matchmediaquery "^0.3.0"
+ prop-types "^15.6.1"
+ shallow-equal "^1.2.1"
+
react-shallow-renderer@^16.15.0:
version "16.15.0"
resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457"
@@ -19958,6 +19980,11 @@ shallow-clone@^3.0.0:
dependencies:
kind-of "^6.0.2"
+shallow-equal@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da"
+ integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==
+
sharp@^0.31.3:
version "0.31.3"
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.31.3.tgz#60227edc5c2be90e7378a210466c99aefcf32688"
From 5802a37b948f1d809f573462fbfcc8dfa5f15dc1 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Thu, 7 Sep 2023 23:44:27 +0200
Subject: [PATCH 002/351] WIP: mobile desktop overhaul
- Desktop component restructuring
- Component logic seperation
- Mobile global stats
- Hook logic
- Mobile asset cards WIP
---
.../common/AccountSummary/GlobalStats.tsx | 179 +++++++++
.../AccountSummary/UserStats.tsx | 9 +-
.../components/common/AccountSummary/index.ts | 2 +
.../AccountSummary/style.module.css | 2 +-
.../AssetList}/BorrowLendToggle.tsx | 0
.../src/components/common/AssetList/index.ts | 1 +
.../src/components/common/HtmlTooltip.tsx | 15 +
.../desktop/AccountSummary/GlobalStats.tsx | 180 ----------
.../desktop/AccountSummary/index.tsx | 3 -
.../desktop/AssetsList/AssetRow/AssetRow.tsx | 339 +++---------------
.../desktop/AssetsList/AssetRow/index.ts | 4 +-
.../desktop/AssetsList/AssetsList.tsx | 26 +-
.../src/components/desktop/CampaignWizard.tsx | 2 +-
.../DesktopAccountSummary.tsx | 46 +++
.../desktop/DesktopAccountSummary/index.tsx | 1 +
.../desktop/DesktopNavbar/AirdropZone.tsx | 8 +-
.../desktop/DesktopNavbar/DesktopNavbar.tsx | 28 +-
.../desktop/DesktopNavbar/WalletButton.tsx | 2 +-
.../src/components/desktop/Earn/index.tsx | 2 +-
.../desktop/UserPositions/UserPositions.tsx | 13 +-
.../mobile/DesktopNavbar/AirdropZone.tsx | 6 +-
.../mobile/DesktopNavbar/MobileNavbar.tsx | 4 +-
.../mobile/DesktopNavbar/WalletButton.tsx | 2 +-
.../MobileAccountSummary.tsx} | 18 +-
.../mobile/MobileAccountSummary/index.ts | 1 +
.../MobileAssetsList/AssetCard/AssetCard.tsx | 68 ++++
.../AssetCard/AssetCardStats.tsx | 48 +++
.../MobileAssetsList/AssetCard/index.ts | 1 +
.../MobileAssetsList/MobileAssetsList.tsx | 64 ++++
.../mobile/MobileAssetsList/index.ts | 1 +
.../src/hooks/useAssetItemData.ts | 40 +++
.../common => hooks}/useFirebaseAccount.tsx | 0
.../common => hooks}/useWalletContext.tsx | 0
apps/marginfi-v2-ui/src/pages/bridge.tsx | 2 +-
apps/marginfi-v2-ui/src/pages/index.tsx | 77 ++--
apps/marginfi-v2-ui/src/pages/lip.tsx | 2 +-
apps/marginfi-v2-ui/src/pages/points.tsx | 2 +-
apps/marginfi-v2-ui/src/pages/swap.tsx | 2 +-
apps/marginfi-v2-ui/src/utils/index.ts | 41 +--
apps/marginfi-v2-ui/src/utils/mrgnActions.ts | 196 ++++++++++
apps/marginfi-v2-ui/src/utils/mrgnUtils.ts | 38 ++
apps/marginfi-v2-ui/tailwind.config.js | 7 +-
.../Lend/PoolCard/PoolCardStats.tsx | 4 +-
43 files changed, 866 insertions(+), 620 deletions(-)
create mode 100644 apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx
rename apps/marginfi-v2-ui/src/components/{desktop => common}/AccountSummary/UserStats.tsx (99%)
create mode 100644 apps/marginfi-v2-ui/src/components/common/AccountSummary/index.ts
rename apps/marginfi-v2-ui/src/components/{desktop => common}/AccountSummary/style.module.css (90%)
rename apps/marginfi-v2-ui/src/components/{desktop/AssetsList => common/AssetList}/BorrowLendToggle.tsx (100%)
create mode 100644 apps/marginfi-v2-ui/src/components/common/AssetList/index.ts
create mode 100644 apps/marginfi-v2-ui/src/components/common/HtmlTooltip.tsx
delete mode 100644 apps/marginfi-v2-ui/src/components/desktop/AccountSummary/GlobalStats.tsx
delete mode 100644 apps/marginfi-v2-ui/src/components/desktop/AccountSummary/index.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/DesktopAccountSummary.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/index.tsx
rename apps/marginfi-v2-ui/src/components/{desktop/AccountSummary/AccountSummary.tsx => mobile/MobileAccountSummary/MobileAccountSummary.tsx} (64%)
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/index.ts
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/index.ts
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/index.ts
create mode 100644 apps/marginfi-v2-ui/src/hooks/useAssetItemData.ts
rename apps/marginfi-v2-ui/src/{components/common => hooks}/useFirebaseAccount.tsx (100%)
rename apps/marginfi-v2-ui/src/{components/common => hooks}/useWalletContext.tsx (100%)
create mode 100644 apps/marginfi-v2-ui/src/utils/mrgnActions.ts
create mode 100644 apps/marginfi-v2-ui/src/utils/mrgnUtils.ts
diff --git a/apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx b/apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx
new file mode 100644
index 0000000000..02d898fe9a
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx
@@ -0,0 +1,179 @@
+import { FC } from "react";
+import { Typography, Skeleton } from "@mui/material";
+import { numeralFormatter } from "@mrgnlabs/mrgn-common";
+import Image from "next/image";
+import Link from "next/link";
+
+import { MrgnTooltip } from "~/components/desktop/Tooltip";
+
+import styles from "./style.module.css";
+
+interface GlobalStatsProps {
+ deposits: number;
+ borrows: number;
+ tvl: number;
+ pointsTotal: number | null;
+}
+
+const GlobalStats: FC = ({ borrows, deposits, pointsTotal, tvl }) => {
+ return (
+
+
+
+
+ Supplied
+
+
+
+ Supplied
+
+ Total value supplied across all assets in the marginfi protocol.
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+
+
+
+ {deposits ? (
+ `$${numeralFormatter(deposits)}`
+ ) : (
+
+ )}
+
+
+
+
+
+ Borrowed
+
+
+
+ Global Borrowed
+
+ Total value borrowed across all assets in the marginfi protocol.
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+
+
+
+ {borrows ? (
+ `$${numeralFormatter(borrows)}`
+ ) : (
+
+ )}
+
+
+
+
+
+ TVL
+
+
+
+ Global TVL
+
+
+
Total value locked in the marginfi protocol, calculated as:
+
{"deposits - borrowed"}
+
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+
+
+
+ {tvl ? (
+ `$${numeralFormatter(tvl)}`
+ ) : (
+
+ )}
+
+
+
+
+
+ Points
+
+
+
+ Points
+
+
+
+ Learn more about points{" "}
+
+ here
+
+ .
+
+
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+
+
+
+ {pointsTotal ? (
+ numeralFormatter(pointsTotal)
+ ) : (
+
+ )}
+
+
+
+
+ );
+};
+
+const DividerLine = () =>
;
+
+export { GlobalStats };
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/UserStats.tsx b/apps/marginfi-v2-ui/src/components/common/AccountSummary/UserStats.tsx
similarity index 99%
rename from apps/marginfi-v2-ui/src/components/desktop/AccountSummary/UserStats.tsx
rename to apps/marginfi-v2-ui/src/components/common/AccountSummary/UserStats.tsx
index 1fe1c66882..a735829781 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/UserStats.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/AccountSummary/UserStats.tsx
@@ -1,11 +1,12 @@
+import React, { FC, useMemo } from "react";
+import { AccountSummary } from "@mrgnlabs/marginfi-v2-ui-state";
+import { usdFormatter, numeralFormatter, usdFormatterDyn, percentFormatter } from "@mrgnlabs/mrgn-common";
import { Typography, Skeleton } from "@mui/material";
import Image from "next/image";
import Link from "next/link";
-import { FC, useMemo } from "react";
+
import { MrgnTooltip } from "~/components/desktop/Tooltip";
-import React from "react";
-import { AccountSummary } from "@mrgnlabs/marginfi-v2-ui-state";
-import { usdFormatter, numeralFormatter, usdFormatterDyn, percentFormatter } from "@mrgnlabs/mrgn-common";
+
import styles from "./style.module.css";
interface UserStatsProps {
diff --git a/apps/marginfi-v2-ui/src/components/common/AccountSummary/index.ts b/apps/marginfi-v2-ui/src/components/common/AccountSummary/index.ts
new file mode 100644
index 0000000000..6e02c4c88e
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/common/AccountSummary/index.ts
@@ -0,0 +1,2 @@
+export * from "./GlobalStats";
+export * from "./UserStats";
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/style.module.css b/apps/marginfi-v2-ui/src/components/common/AccountSummary/style.module.css
similarity index 90%
rename from apps/marginfi-v2-ui/src/components/desktop/AccountSummary/style.module.css
rename to apps/marginfi-v2-ui/src/components/common/AccountSummary/style.module.css
index 4fa7c73639..ee1506516a 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/style.module.css
+++ b/apps/marginfi-v2-ui/src/components/common/AccountSummary/style.module.css
@@ -1,7 +1,7 @@
.hide-scrollbar {
-ms-overflow-style: none; /* for Internet Explorer, Edge */
scrollbar-width: none; /* for Firefox */
- overflow-x: scroll;
+ overflow-x: scroll;
}
.hide-scrollbar::-webkit-scrollbar {
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/BorrowLendToggle.tsx b/apps/marginfi-v2-ui/src/components/common/AssetList/BorrowLendToggle.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/desktop/AssetsList/BorrowLendToggle.tsx
rename to apps/marginfi-v2-ui/src/components/common/AssetList/BorrowLendToggle.tsx
diff --git a/apps/marginfi-v2-ui/src/components/common/AssetList/index.ts b/apps/marginfi-v2-ui/src/components/common/AssetList/index.ts
new file mode 100644
index 0000000000..8442d9cd65
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/common/AssetList/index.ts
@@ -0,0 +1 @@
+export * from "./BorrowLendToggle";
diff --git a/apps/marginfi-v2-ui/src/components/common/HtmlTooltip.tsx b/apps/marginfi-v2-ui/src/components/common/HtmlTooltip.tsx
new file mode 100644
index 0000000000..15c924d0bc
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/common/HtmlTooltip.tsx
@@ -0,0 +1,15 @@
+import React from "react";
+import { styled } from "@mui/material/styles";
+import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
+
+export const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
+
+))(({ theme }) => ({
+ [`& .${tooltipClasses.tooltip}`]: {
+ backgroundColor: "rgb(227, 227, 227)",
+ color: "rgba(0, 0, 0, 0.87)",
+ maxWidth: 220,
+ fontSize: theme.typography.pxToRem(12),
+ border: "1px solid #dadde9",
+ },
+}));
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/GlobalStats.tsx b/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/GlobalStats.tsx
deleted file mode 100644
index e34da6210c..0000000000
--- a/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/GlobalStats.tsx
+++ /dev/null
@@ -1,180 +0,0 @@
-import { Typography, Skeleton } from "@mui/material";
-import Image from "next/image";
-import Link from "next/link";
-import { FC } from "react";
-import { MrgnTooltip } from "~/components/desktop/Tooltip";
-import styles from "./style.module.css";
-import { numeralFormatter } from "@mrgnlabs/mrgn-common";
-
-interface GlobalStatsProps {
- deposits: number;
- borrows: number;
- tvl: number;
- pointsTotal: number | null;
-}
-
-const GlobalStats: FC = ({ borrows, deposits, pointsTotal, tvl }) => {
- return (
-
-
Global stats
-
-
-
-
-
- Supplied
-
-
-
- Supplied
-
- Total value supplied across all assets in the marginfi protocol.
- >
- }
- placement="top"
- >
-
-
-
-
-
- {deposits ? (
- `$${numeralFormatter(deposits)}`
- ) : (
-
- )}
-
-
-
-
-
-
-
- Borrowed
-
-
-
- Global Borrowed
-
- Total value borrowed across all assets in the marginfi protocol.
- >
- }
- placement="top"
- >
-
-
-
-
-
- {borrows ? (
- `$${numeralFormatter(borrows)}`
- ) : (
-
- )}
-
-
-
-
-
-
-
- TVL
-
-
-
- Global TVL
-
-
-
Total value locked in the marginfi protocol, calculated as:
-
{"deposits - borrowed"}
-
- >
- }
- placement="top"
- >
-
-
-
-
-
- {tvl ? (
- `$${numeralFormatter(tvl)}`
- ) : (
-
- )}
-
-
-
-
-
-
-
- Points
-
-
-
- Points
-
-
-
- Learn more about points{" "}
-
- here
-
- .
-
-
- >
- }
- placement="top"
- >
-
-
-
-
-
- {pointsTotal ? (
- numeralFormatter(pointsTotal)
- ) : (
-
- )}
-
-
-
-
-
-
- );
-};
-
-const DividerLine = () =>
;
-
-export { GlobalStats };
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/index.tsx b/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/index.tsx
deleted file mode 100644
index 5a0d9fcc26..0000000000
--- a/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/index.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-import { AccountSummary } from "./AccountSummary";
-
-export { AccountSummary };
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
index 828a4da588..33dcd16122 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
@@ -1,15 +1,12 @@
+import React, { FC, useCallback, useEffect, useMemo, useState } from "react";
import Image from "next/image";
import { TableCell, TableRow } from "@mui/material";
-import React, { FC, useCallback, useEffect, useMemo, useState } from "react";
-import { toast } from "react-toastify";
-import { AssetRowInputBox } from "./AssetRowInputBox";
-import { AssetRowAction } from "./AssetRowAction";
import { styled } from "@mui/material/styles";
import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
import Typography from "@mui/material/Typography";
import { useMrgnlendStore, useUserProfileStore } from "~/store";
import Badge from "@mui/material/Badge";
-import { isWholePosition } from "~/utils";
+
import {
WSOL_MINT,
groupedNumberFormatterDyn,
@@ -18,31 +15,16 @@ import {
uiToNative,
usdFormatter,
} from "@mrgnlabs/mrgn-common";
-import {
- ExtendedBankInfo,
- Emissions,
- FEE_MARGIN,
- ActionType,
- getCurrentAction,
- ExtendedBankMetadata,
-} from "@mrgnlabs/marginfi-v2-ui-state";
+import { ExtendedBankInfo, ActionType, getCurrentAction, ExtendedBankMetadata } from "@mrgnlabs/marginfi-v2-ui-state";
import { MarginfiAccountWrapper, PriceBias } from "@mrgnlabs/marginfi-client-v2";
-import { useWalletContext } from "~/components/common/useWalletContext";
-const CLOSE_BALANCE_TOAST_ID = "close-balance";
-const BORROW_OR_LEND_TOAST_ID = "borrow-or-lend";
+import { borrowOrLend, closeBalance } from "~/utils";
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { useAssetItemData } from "~/hooks/useAssetItemData";
+import { HtmlTooltip } from "~/components/common/HtmlTooltip";
-const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
-
-))(({ theme }) => ({
- [`& .${tooltipClasses.tooltip}`]: {
- backgroundColor: "rgb(227, 227, 227)",
- color: "rgba(0, 0, 0, 0.87)",
- maxWidth: 220,
- fontSize: theme.typography.pxToRem(12),
- border: "1px solid #dadde9",
- },
-}));
+import { AssetRowInputBox } from "./AssetRowInputBox";
+import { AssetRowAction } from "./AssetRowAction";
const AssetRow: FC<{
bank: ExtendedBankInfo;
@@ -68,6 +50,16 @@ const AssetRow: FC<{
const [lendZoomLevel, denominationUSD] = useUserProfileStore((state) => [state.lendZoomLevel, state.denominationUSD]);
const setIsRefreshingStore = useMrgnlendStore((state) => state.setIsRefreshingStore);
const [mfiClient, fetchMrgnlendState] = useMrgnlendStore((state) => [state.marginfiClient, state.fetchMrgnlendState]);
+ const { rateAP, assetWeight, isBankFilled, isBankHigh, bankFilled } = useAssetItemData({ bank, isInLendingMode });
+
+ const assetPriceOffset = useMemo(
+ () =>
+ Math.max(
+ bank.info.rawBank.getPrice(bank.info.oraclePrice, PriceBias.Highest).toNumber() - bank.info.state.price,
+ bank.info.state.price - bank.info.rawBank.getPrice(bank.info.oraclePrice, PriceBias.Lowest).toNumber()
+ ),
+ [bank.info]
+ );
const [borrowOrLendAmount, setBorrowOrLendAmount] = useState(0);
@@ -99,42 +91,11 @@ const AssetRow: FC<{
setBorrowOrLendAmount(0);
}, [isInLendingMode]);
- const closeBalance = useCallback(async () => {
- if (!marginfiAccount) {
- toast.error("marginfi account not ready.");
- return;
- }
-
- if (!bank.isActive) {
- toast.error("no position to close.");
- return;
- }
-
- toast.loading("Closing dust balance", {
- toastId: CLOSE_BALANCE_TOAST_ID,
- });
-
+ const handleCloseBalance = useCallback(async () => {
try {
- if (bank.position.isLending) {
- await marginfiAccount.withdraw(0, bank.address, true);
- } else {
- await marginfiAccount.repay(0, bank.address, true);
- }
- toast.update(CLOSE_BALANCE_TOAST_ID, {
- render: "Closing 👍",
- type: toast.TYPE.SUCCESS,
- autoClose: 2000,
- isLoading: false,
- });
- } catch (error: any) {
- toast.update(CLOSE_BALANCE_TOAST_ID, {
- render: `Error while closing balance: ${error.message}`,
- type: toast.TYPE.ERROR,
- autoClose: 5000,
- isLoading: false,
- });
- console.log(`Error while closing balance`);
- console.log(error);
+ closeBalance({ marginfiAccount, bank });
+ } catch (error) {
+ return;
}
setBorrowOrLendAmount(0);
@@ -148,130 +109,8 @@ const AssetRow: FC<{
}
}, [bank, marginfiAccount, fetchMrgnlendState, setIsRefreshingStore]);
- const borrowOrLend = useCallback(async () => {
- if (mfiClient === null) throw Error("Marginfi client not ready");
-
- if (
- currentAction === ActionType.Deposit &&
- bank.info.state.totalDeposits >= bank.info.rawBank.config.depositLimit
- ) {
- toast.error(
- `${bank.meta.tokenSymbol} deposit limit has been been reached. Additional deposits are not currently available.`
- );
- return;
- }
-
- if (currentAction === ActionType.Borrow && bank.info.state.totalBorrows >= bank.info.rawBank.config.borrowLimit) {
- toast.error(
- `${bank.meta.tokenSymbol} borrow limit has been been reached. Additional borrows are not currently available.`
- );
- return;
- }
-
- if (currentAction === ActionType.Deposit && bank.userInfo.maxDeposit === 0) {
- toast.error(`You don't have any ${bank.meta.tokenSymbol} to lend in your wallet.`);
- return;
- }
-
- if (currentAction === ActionType.Borrow && bank.userInfo.maxBorrow === 0) {
- toast.error(`You cannot borrow any ${bank.meta.tokenSymbol} right now.`);
- return;
- }
-
- if (borrowOrLendAmount <= 0) {
- toast.error("Please enter an amount over 0.");
- return;
- }
-
- let _marginfiAccount = marginfiAccount;
-
- if (nativeSolBalance < FEE_MARGIN) {
- toast.error("Not enough sol for fee.");
- return;
- }
-
- // -------- Create marginfi account if needed
- try {
- if (!_marginfiAccount) {
- if (currentAction !== ActionType.Deposit) {
- toast.error("An account is required for anything operation except deposit.");
- return;
- }
-
- toast.loading("Creating account", {
- toastId: BORROW_OR_LEND_TOAST_ID,
- });
-
- _marginfiAccount = await mfiClient.createMarginfiAccount();
- toast.update(BORROW_OR_LEND_TOAST_ID, {
- render: `${currentAction + "ing"} ${borrowOrLendAmount} ${bank.meta.tokenSymbol}`,
- });
- }
- } catch (error: any) {
- toast.update(BORROW_OR_LEND_TOAST_ID, {
- render: `Error while ${currentAction + "ing"}: ${error.message}`,
- type: toast.TYPE.ERROR,
- autoClose: 5000,
- isLoading: false,
- });
- console.log(`Error while ${currentAction + "ing"}`);
- console.log(error);
- return;
- }
-
- // -------- Perform relevant operation
- try {
- if (currentAction === ActionType.Deposit) {
- await _marginfiAccount.deposit(borrowOrLendAmount, bank.address);
-
- toast.update(BORROW_OR_LEND_TOAST_ID, {
- render: `${currentAction + "ing"} ${borrowOrLendAmount} ${bank.meta.tokenSymbol} 👍`,
- type: toast.TYPE.SUCCESS,
- autoClose: 2000,
- isLoading: false,
- });
- }
-
- toast.loading(`${currentAction + "ing"} ${borrowOrLendAmount} ${bank.meta.tokenSymbol}`, {
- toastId: BORROW_OR_LEND_TOAST_ID,
- });
- if (_marginfiAccount === null) {
- // noinspection ExceptionCaughtLocallyJS
- throw Error("Marginfi account not ready");
- }
-
- if (currentAction === ActionType.Borrow) {
- await _marginfiAccount.borrow(borrowOrLendAmount, bank.address);
- } else if (currentAction === ActionType.Repay) {
- await _marginfiAccount.repay(
- borrowOrLendAmount,
- bank.address,
- bank.isActive && isWholePosition(bank, borrowOrLendAmount)
- );
- } else if (currentAction === ActionType.Withdraw) {
- await _marginfiAccount.withdraw(
- borrowOrLendAmount,
- bank.address,
- bank.isActive && isWholePosition(bank, borrowOrLendAmount)
- );
- }
-
- toast.update(BORROW_OR_LEND_TOAST_ID, {
- render: `${currentAction + "ing"} ${borrowOrLendAmount} ${bank.meta.tokenSymbol} 👍`,
- type: toast.TYPE.SUCCESS,
- autoClose: 2000,
- isLoading: false,
- });
- } catch (error: any) {
- toast.update(BORROW_OR_LEND_TOAST_ID, {
- render: `Error while ${currentAction + "ing"}: ${error.message}`,
- type: toast.TYPE.ERROR,
- autoClose: 5000,
- isLoading: false,
- });
- console.log(`Error while ${currentAction + "ing"}`);
- console.log(error);
- }
+ const handleBorrowOrLend = useCallback(async () => {
+ borrowOrLend({ mfiClient, currentAction, bank, borrowOrLendAmount, nativeSolBalance, marginfiAccount });
setBorrowOrLendAmount(0);
@@ -309,6 +148,7 @@ const AssetRow: FC<{
{bank.meta.tokenSymbol}
+
999 && lendZoomLevel < 2 ? "xl:text-xs xl:pl-0" : ""
@@ -323,10 +163,7 @@ const AssetRow: FC<{
Wide oracle price bands
{`${bank.meta.tokenSymbol} price estimates is
- ${usdFormatter.format(bank.info.state.price)} ± ${Math.max(
- bank.info.rawBank.getPrice(bank.info.oraclePrice, PriceBias.Highest).toNumber() - bank.info.state.price,
- bank.info.state.price - bank.info.rawBank.getPrice(bank.info.oraclePrice, PriceBias.Lowest).toNumber()
- ).toFixed(
+ ${usdFormatter.format(bank.info.state.price)} ± ${assetPriceOffset.toFixed(
2
)}, which is wide. Proceed with caution. marginfi prices assets at the bottom of confidence bands and liabilities at the top.`}
@@ -336,50 +173,21 @@ const AssetRow: FC<{
}
placement="right"
- className={`${
- Math.max(
- bank.info.rawBank.getPrice(bank.info.oraclePrice, PriceBias.Highest).toNumber() - bank.info.state.price,
- bank.info.state.price - bank.info.rawBank.getPrice(bank.info.oraclePrice, PriceBias.Lowest).toNumber()
- ) >
- bank.info.state.price * 0.1
- ? "cursor-pointer"
- : "hidden"
- }`}
+ className={`${assetPriceOffset > bank.info.state.price * 0.1 ? "cursor-pointer" : "hidden"}`}
>
- bank.info.state.price * 0.1
- ? "⚠️"
- : ""
- }
+ badgeContent={assetPriceOffset > bank.info.state.price * 0.1 ? "⚠️" : ""}
className="bg-transparent"
sx={{
"& .MuiBadge-badge": {
fontSize: 20,
},
}}
- invisible={
- Math.max(
- bank.info.rawBank.getPrice(bank.info.oraclePrice, PriceBias.Highest).toNumber() - bank.info.state.price,
- bank.info.state.price - bank.info.rawBank.getPrice(bank.info.oraclePrice, PriceBias.Lowest).toNumber()
- ) >
- bank.info.state.price * 0.1
- ? false
- : true
- }
+ invisible={assetPriceOffset > bank.info.state.price * 0.1 ? false : true}
>
{bank.info.state.price >= 0.01
? lendZoomLevel < 2
- ? `${usdFormatter.format(bank.info.state.price)} ± ${Math.max(
- bank.info.rawBank.getPrice(bank.info.oraclePrice, PriceBias.Highest).toNumber() -
- bank.info.state.price,
- bank.info.state.price -
- bank.info.rawBank.getPrice(bank.info.oraclePrice, PriceBias.Lowest).toNumber()
- ).toFixed(2)}`
+ ? `${usdFormatter.format(bank.info.state.price)} ± ${assetPriceOffset.toFixed(2)}`
: usdFormatter.format(bank.info.state.price)
: `$${bank.info.state.price.toExponential(2)}`}
@@ -423,15 +231,7 @@ const AssetRow: FC<{
fontWeight: 400,
}}
>
- {percentFormatter.format(
- (isInLendingMode ? bank.info.state.lendingRate : bank.info.state.borrowingRate) +
- (isInLendingMode && bank.info.state.emissions == Emissions.Lending
- ? bank.info.state.emissionsRate
- : 0) +
- (!isInLendingMode && bank.info.state.emissions == Emissions.Borrowing
- ? bank.info.state.emissionsRate
- : 0)
- )}
+ {rateAP}
@@ -441,11 +241,7 @@ const AssetRow: FC<{
align="right"
style={{ fontWeight: 300 }}
>
- {isInLendingMode
- ? bank.info.rawBank.config.assetWeightInit.toNumber() > 0
- ? (bank.info.rawBank.config.assetWeightInit.toNumber() * 100).toFixed(0) + "%"
- : "-"
- : ((1 / bank.info.rawBank.config.liabilityWeightInit.toNumber()) * 100).toFixed(0) + "%"}
+ {assetWeight}
- {isInLendingMode
- ? bank.info.state.totalDeposits >= bank.info.rawBank.config.depositLimit * 0.99999
- ? "Limit Reached"
- : bank.info.state.totalDeposits >= bank.info.rawBank.config.depositLimit * 0.9
- ? "Approaching Limit"
- : null
- : bank.info.state.totalBorrows >= bank.info.rawBank.config.borrowLimit * 0.99999
- ? "Limit Reached"
- : bank.info.state.totalBorrows >= bank.info.rawBank.config.borrowLimit * 0.9
- ? "Approaching Limit"
- : null}
+ {isBankHigh && (isBankFilled ? "Limit Reached" : "Approaching Limit")}
{`${bank.meta.tokenSymbol} ${isInLendingMode ? "deposits" : "borrows"} are at ${percentFormatter.format(
- isInLendingMode
- ? bank.info.state.totalDeposits / bank.info.rawBank.config.depositLimit
- : bank.info.state.totalBorrows / bank.info.rawBank.config.borrowLimit
+ (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) / bankFilled
)} capacity.`}
@@ -481,45 +265,17 @@ const AssetRow: FC<{
}
placement="right"
- className={`${
- isInLendingMode
- ? bank.info.state.totalDeposits >= bank.info.rawBank.config.depositLimit * 0.9
- ? ""
- : ""
- : bank.info.state.totalBorrows >= bank.info.rawBank.config.borrowLimit * 0.9
- ? ""
- : ""
- }`}
+ className={``}
>
= bank.info.rawBank.config.depositLimit * 0.99999
- ? "💯"
- : bank.info.state.totalDeposits >= bank.info.rawBank.config.depositLimit * 0.9
- ? "❗"
- : null
- : bank.info.state.totalBorrows >= bank.info.rawBank.config.borrowLimit * 0.99999
- ? "💯"
- : bank.info.state.totalBorrows >= bank.info.rawBank.config.borrowLimit * 0.9
- ? "❗"
- : null
- }
+ badgeContent={isBankHigh && (isBankFilled ? "💯" : "❗")}
className="bg-transparent"
sx={{
"& .MuiBadge-badge": {
fontSize: 20,
},
}}
- invisible={
- isInLendingMode
- ? bank.info.state.totalDeposits >= bank.info.rawBank.config.depositLimit * 0.9
- ? false
- : true
- : bank.info.state.totalBorrows >= bank.info.rawBank.config.borrowLimit * 0.9
- ? false
- : true
- }
+ invisible={!isBankHigh}
>
{denominationUSD
? usdFormatter.format(
@@ -562,17 +318,10 @@ const AssetRow: FC<{
style={{ fontWeight: 300 }}
>
{denominationUSD
- ? usdFormatter.format(
- (isInLendingMode ? bank.info.rawBank.config.depositLimit : bank.info.rawBank.config.borrowLimit) *
- bank.info.state.price
- )
+ ? usdFormatter.format(bankFilled * bank.info.state.price)
: lendZoomLevel < 2
- ? groupedNumberFormatterDyn.format(
- isInLendingMode ? bank.info.rawBank.config.depositLimit : bank.info.rawBank.config.borrowLimit
- )
- : numeralFormatter(
- isInLendingMode ? bank.info.rawBank.config.depositLimit : bank.info.rawBank.config.borrowLimit
- )}
+ ? groupedNumberFormatterDyn.format(bankFilled)
+ : numeralFormatter(bankFilled)}
)}
@@ -631,7 +380,7 @@ const AssetRow: FC<{
maxDecimals={bank.info.state.mintDecimals}
inputRefs={inputRefs}
disabled={isDust || currentAction === "Connect" || maxAmount === 0}
- onEnter={borrowOrLend}
+ onEnter={handleBorrowOrLend}
/>
@@ -650,7 +399,9 @@ const AssetRow: FC<{
? "rgb(227, 227, 227)"
: "rgba(0,0,0,0)"
}
- onClick={currentAction === "Connect" ? openWalletSelector : isDust ? closeBalance : borrowOrLend}
+ onClick={
+ currentAction === "Connect" ? openWalletSelector : isDust ? handleCloseBalance : handleBorrowOrLend
+ }
disabled={
currentAction !== "Connect" &&
((isDust && uiToNative(bank.userInfo.tokenAccount.balance, bank.info.state.mintDecimals).isZero()) ||
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/index.ts b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/index.ts
index 15b51ef0e4..0b6ef37c12 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/index.ts
+++ b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/index.ts
@@ -1,3 +1 @@
-import { AssetRow } from "./AssetRow";
-
-export default AssetRow;
+export * from "./AssetRow";
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
index 244fdc86cd..b03c4d3443 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
@@ -1,27 +1,17 @@
-import Image from "next/image";
import React, { FC, useEffect, useRef, useState } from "react";
+import Image from "next/image";
+import { useHotkeys } from "react-hotkeys-hook";
import { Card, Table, TableHead, TableBody, TableContainer, TableCell } from "@mui/material";
import { styled } from "@mui/material/styles";
import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
import Typography from "@mui/material/Typography";
-import { BorrowLendToggle } from "./BorrowLendToggle";
-import AssetRow from "./AssetRow";
+
import { useMrgnlendStore, useUserProfileStore } from "~/store";
-import { useHotkeys } from "react-hotkeys-hook";
-import { LoadingAsset } from "./AssetRow/AssetRow";
-import { useWalletContext } from "../../common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { BorrowLendToggle } from "~/components/common/AssetList/BorrowLendToggle";
-const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
-
-))(({ theme }) => ({
- [`& .${tooltipClasses.tooltip}`]: {
- backgroundColor: "rgb(227, 227, 227)",
- color: "rgba(0, 0, 0, 0.87)",
- maxWidth: 220,
- fontSize: theme.typography.pxToRem(12),
- border: "1px solid #dadde9",
- },
-}));
+import { LoadingAsset, AssetRow } from "./AssetRow";
+import { HtmlTooltip } from "~/components/common/HtmlTooltip";
const AssetsList: FC = () => {
// const { selectedAccount, nativeSolBalance } = useStore();
@@ -97,7 +87,7 @@ const AssetsList: FC = () => {
);
// Hack required to circumvent rehydration error
- const [hasMounted, setHasMounted] = React.useState(false);
+ const [hasMounted, setHasMounted] = useState(false);
useEffect(() => {
setHasMounted(true);
}, []);
diff --git a/apps/marginfi-v2-ui/src/components/desktop/CampaignWizard.tsx b/apps/marginfi-v2-ui/src/components/desktop/CampaignWizard.tsx
index 6c2747e447..a3a2aed5f7 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/CampaignWizard.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/CampaignWizard.tsx
@@ -20,7 +20,7 @@ import { NumberFormatValues, NumericFormat } from "react-number-format";
import { useMrgnlendStore } from "~/store";
import { computeGuaranteedApy } from "@mrgnlabs/lip-client";
import { EarnAction } from "./Earn";
-import { useWalletContext } from "~/components/common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
interface CampaignWizardInputBox {
value: number;
diff --git a/apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/DesktopAccountSummary.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/DesktopAccountSummary.tsx
new file mode 100644
index 0000000000..3e99c6f6fa
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/DesktopAccountSummary.tsx
@@ -0,0 +1,46 @@
+import React, { FC } from "react";
+import { useMrgnlendStore } from "~/store";
+import dynamic from "next/dynamic";
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { UserStats } from "~/components/common/AccountSummary";
+
+const GlobalStats = dynamic(async () => (await import("~/components/common/AccountSummary/GlobalStats")).GlobalStats, {
+ ssr: false,
+});
+
+const AccountSummary: FC = () => {
+ const [isStoreInitialized, accountSummary, protocolStats, selectedAccount] = useMrgnlendStore((state) => [
+ state.initialized,
+ state.accountSummary,
+ state.protocolStats,
+ state.selectedAccount,
+ ]);
+ const { connected } = useWalletContext();
+
+ return (
+
+
+
+
+ {connected && (
+
+ )}
+
+
+ );
+};
+
+export { AccountSummary as DesktopAccountSummary };
diff --git a/apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/index.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/index.tsx
new file mode 100644
index 0000000000..2dcb49a741
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/index.tsx
@@ -0,0 +1 @@
+export * from "./DesktopAccountSummary";
diff --git a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/AirdropZone.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/AirdropZone.tsx
index a496b30197..4d416cc30b 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/AirdropZone.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/AirdropZone.tsx
@@ -2,7 +2,7 @@ import { Button, Modal } from "@mui/material";
import { FC, useCallback, useState } from "react";
import styles from "./AirdropZone.module.css";
import { PublicKey, Transaction } from "@solana/web3.js";
-import { useConnection, useWallet } from "@solana/wallet-adapter-react";
+import { useConnection } from "@solana/wallet-adapter-react";
import { makeAirdropCollateralIx } from "~/utils";
import { toast } from "react-toastify";
import {
@@ -10,7 +10,7 @@ import {
getAssociatedTokenAddressSync,
shortenAddress,
} from "@mrgnlabs/mrgn-common";
-import { useWalletContext } from "../../common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
const SOL_AMOUNT = 2 * 10 ** 9;
@@ -60,9 +60,7 @@ const AirdropZone: FC = () => {
return (
-
- Airdrop
-
+
Airdrop
diff --git a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
index a24713530a..c5da39f773 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
@@ -10,9 +10,9 @@ import { useMrgnlendStore, useUserProfileStore } from "~/store";
import { useRouter } from "next/router";
import { HotkeysEvent } from "react-hotkeys-hook/dist/types";
import { Badge } from "@mui/material";
-import { useFirebaseAccount } from "../../common/useFirebaseAccount";
+import { useFirebaseAccount } from "~/hooks/useFirebaseAccount";
import { groupedNumberFormatterDyn, numeralFormatter } from "@mrgnlabs/mrgn-common";
-import { useWalletContext } from "../../common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
// @todo implement second pretty navbar row
const DesktopNavbar: FC = () => {
@@ -133,7 +133,12 @@ const DesktopNavbar: FC = () => {
badgeContent={"l"}
invisible={!showBadges}
>
-
+
lend
@@ -152,7 +157,10 @@ const DesktopNavbar: FC = () => {
badgeContent={"s"}
invisible={!showBadges}
>
-
+
swap
@@ -170,7 +178,10 @@ const DesktopNavbar: FC = () => {
badgeContent={"b"}
invisible={!showBadges}
>
-
+
bridge
@@ -190,7 +201,12 @@ const DesktopNavbar: FC = () => {
invisible={!showBadges}
className="hidden md:block"
>
-
+
earn
diff --git a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/WalletButton.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/WalletButton.tsx
index 5e0cd4ee7e..e0811cd095 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/WalletButton.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/WalletButton.tsx
@@ -1,6 +1,6 @@
import dynamic from "next/dynamic";
import { FC } from "react";
-import { useWalletContext } from "../../common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
const WalletMultiButtonDynamic = dynamic(
async () => (await import("@solana/wallet-adapter-react-ui")).WalletMultiButton,
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Earn/index.tsx b/apps/marginfi-v2-ui/src/components/desktop/Earn/index.tsx
index 2b0760c16c..866fa32e69 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/Earn/index.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Earn/index.tsx
@@ -31,7 +31,7 @@ import { Bank, PriceBias } from "@mrgnlabs/marginfi-client-v2";
import { Countdown } from "~/components/desktop/Countdown";
import { toast } from "react-toastify";
import BigNumber from "bignumber.js";
-import { useWalletContext } from "~/components/common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
import { useMrgnlendStore } from "~/store";
const Earn = () => {
diff --git a/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx
index 9a7e189556..47d735e7b1 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx
@@ -7,18 +7,7 @@ import Image from "next/image";
import Link from "next/link";
import { useMrgnlendStore } from "~/store";
import { ActiveBankInfo } from "@mrgnlabs/marginfi-v2-ui-state";
-
-const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
-
-))(({ theme }) => ({
- [`& .${tooltipClasses.tooltip}`]: {
- backgroundColor: "rgb(227, 227, 227)",
- color: "rgba(0, 0, 0, 0.87)",
- maxWidth: 220,
- fontSize: theme.typography.pxToRem(12),
- border: "1px solid #dadde9",
- },
-}));
+import { HtmlTooltip } from "~/components/common/HtmlTooltip";
const UserPositions: FC = () => {
const setIsRefreshingStore = useMrgnlendStore((state) => state.setIsRefreshingStore);
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.tsx b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.tsx
index a496b30197..ebc76465b2 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.tsx
@@ -10,7 +10,7 @@ import {
getAssociatedTokenAddressSync,
shortenAddress,
} from "@mrgnlabs/mrgn-common";
-import { useWalletContext } from "../../common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
const SOL_AMOUNT = 2 * 10 ** 9;
@@ -60,9 +60,7 @@ const AirdropZone: FC = () => {
return (
-
- Airdrop
-
+
Airdrop
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx
index 5269b30ee6..947e008c87 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx
@@ -4,8 +4,8 @@ import Image from "next/image";
import AirdropZone from "./AirdropZone";
import { useUserProfileStore } from "~/store";
import { useRouter } from "next/router";
-import { useFirebaseAccount } from "../../common/useFirebaseAccount";
-import { useWalletContext } from "../../common/useWalletContext";
+import { useFirebaseAccount } from "~/hooks/useFirebaseAccount";
+import { useWalletContext } from "~/hooks/useWalletContext";
// @todo implement second pretty navbar row
const MobileNavbar: FC = () => {
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx
index 4959bdf3d1..e0811cd095 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx
@@ -1,6 +1,6 @@
import dynamic from "next/dynamic";
import { FC } from "react";
-import { useWalletContext } from "~/components/common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
const WalletMultiButtonDynamic = dynamic(
async () => (await import("@solana/wallet-adapter-react-ui")).WalletMultiButton,
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/AccountSummary.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
similarity index 64%
rename from apps/marginfi-v2-ui/src/components/desktop/AccountSummary/AccountSummary.tsx
rename to apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
index e8f06d0c79..91183d5353 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/AccountSummary/AccountSummary.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
@@ -1,10 +1,12 @@
import React, { FC } from "react";
-import { UserStats } from "./UserStats";
import { useMrgnlendStore } from "~/store";
import dynamic from "next/dynamic";
-import { useWalletContext } from "../../common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { UserStats } from "~/components/common/AccountSummary";
-const GlobalStats = dynamic(async () => (await import("./GlobalStats")).GlobalStats, { ssr: false });
+const GlobalStats = dynamic(async () => (await import("~/components/common/AccountSummary/GlobalStats")).GlobalStats, {
+ ssr: false,
+});
const AccountSummary: FC = () => {
const [isStoreInitialized, accountSummary, protocolStats, selectedAccount] = useMrgnlendStore((state) => [
@@ -16,8 +18,8 @@ const AccountSummary: FC = () => {
const { connected } = useWalletContext();
return (
-
-
+
+
{
/>
-
+ {/*
{connected && (
)}
-
+
*/}
);
};
-export { AccountSummary };
+export { AccountSummary as MobileAccountSummary };
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/index.ts b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/index.ts
new file mode 100644
index 0000000000..0bdb04e467
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/index.ts
@@ -0,0 +1 @@
+export * from "./MobileAccountSummary";
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
new file mode 100644
index 0000000000..5298fc1bd6
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
@@ -0,0 +1,68 @@
+import React, { FC, useCallback, useEffect, useMemo, useState } from "react";
+import Image from "next/image";
+import { TableCell, TableRow } from "@mui/material";
+import { styled } from "@mui/material/styles";
+import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
+import Typography from "@mui/material/Typography";
+import { useMrgnlendStore, useUserProfileStore } from "~/store";
+import Badge from "@mui/material/Badge";
+
+import {
+ WSOL_MINT,
+ groupedNumberFormatterDyn,
+ numeralFormatter,
+ percentFormatter,
+ uiToNative,
+ usdFormatter,
+} from "@mrgnlabs/mrgn-common";
+import { ExtendedBankInfo, ActionType, getCurrentAction, ExtendedBankMetadata } from "@mrgnlabs/marginfi-v2-ui-state";
+import { MarginfiAccountWrapper, PriceBias } from "@mrgnlabs/marginfi-client-v2";
+
+import { borrowOrLend, closeBalance } from "~/utils";
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { useAssetItemData } from "~/hooks/useAssetItemData";
+import { HtmlTooltip } from "~/components/common/HtmlTooltip";
+
+export const AssetCard: FC<{
+ bank: ExtendedBankInfo;
+ nativeSolBalance: number;
+ isInLendingMode: boolean;
+ isConnected: boolean;
+ marginfiAccount: MarginfiAccountWrapper | null;
+ inputRefs: React.MutableRefObject
>;
+ hasHotkey: boolean;
+ showHotkeyBadges?: boolean;
+ badgeContent?: string;
+}> = ({
+ bank,
+ nativeSolBalance,
+ isInLendingMode,
+ marginfiAccount,
+ inputRefs,
+ hasHotkey,
+ showHotkeyBadges,
+ badgeContent,
+}) => {
+ const { rateAP, assetWeight, isBankFilled, isBankHigh, bankFilled } = useAssetItemData({ bank, isInLendingMode });
+
+ return (
+
+
+
+
+ {bank.meta.tokenLogoUri && (
+
+ )}
+
+
+
{bank.meta.tokenSymbol}
+
{usdFormatter.format(bank.info.state.price)}
+
+
+
+
{rateAP.concat(...[" ", isInLendingMode ? "APY" : "APR"])}
+
+
+
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
new file mode 100644
index 0000000000..62a941a620
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
@@ -0,0 +1,48 @@
+import React, { FC, useCallback, useEffect, useMemo, useState } from "react";
+import Image from "next/image";
+import { TableCell, TableRow } from "@mui/material";
+import { styled } from "@mui/material/styles";
+import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
+import Typography from "@mui/material/Typography";
+import { useMrgnlendStore, useUserProfileStore } from "~/store";
+import Badge from "@mui/material/Badge";
+
+import {
+ WSOL_MINT,
+ groupedNumberFormatterDyn,
+ numeralFormatter,
+ percentFormatter,
+ uiToNative,
+ usdFormatter,
+} from "@mrgnlabs/mrgn-common";
+import { ExtendedBankInfo, ActionType, getCurrentAction, ExtendedBankMetadata } from "@mrgnlabs/marginfi-v2-ui-state";
+import { MarginfiAccountWrapper, PriceBias } from "@mrgnlabs/marginfi-client-v2";
+
+export const AssetStats: FC<{
+ bank: ExtendedBankInfo;
+ assetWeight: string;
+ isInLendingMode: boolean;
+ userBalance: string;
+}> = ({ bank, assetWeight, isInLendingMode, userBalance }) => {
+ return (
+
+
+
Weight
+
{assetWeight}
+
+ {/* TODO: Add seperator */}
+
+
{isInLendingMode ? "Deposits" : "Available"}
+
{0}
+ {/* {isHigh && (
+
{percentFormatter.format(bankFilled)}
+ )} */}
+
+ {/* TODO: Add seperator */}
+
+
Your Balance
+
{userBalance + " " + bank.meta.tokenSymbol}
+
+
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/index.ts b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/index.ts
new file mode 100644
index 0000000000..bc24b443ef
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/index.ts
@@ -0,0 +1 @@
+export * from "./AssetCard";
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
new file mode 100644
index 0000000000..3528673ecf
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
@@ -0,0 +1,64 @@
+import React, { FC, useEffect, useRef, useState } from "react";
+import Image from "next/image";
+import { useHotkeys } from "react-hotkeys-hook";
+import { Card, Table, TableHead, TableBody, TableContainer, TableCell } from "@mui/material";
+import { styled } from "@mui/material/styles";
+import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
+import Typography from "@mui/material/Typography";
+
+import { useMrgnlendStore, useUserProfileStore } from "~/store";
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { BorrowLendToggle } from "~/components/common/AssetList/BorrowLendToggle";
+import { AssetCard } from "./AssetCard";
+
+// import { LoadingAsset, AssetRow } from "./AssetRow";
+
+export const MobileAssetsList: FC = () => {
+ const { connected } = useWalletContext();
+ const [isStoreInitialized, sortedBanks, nativeSolBalance, selectedAccount] = useMrgnlendStore((state) => [
+ state.initialized,
+ state.extendedBankInfos,
+ state.nativeSolBalance,
+ state.selectedAccount,
+ ]);
+ const [lendZoomLevel, showBadges, setShowBadges] = useUserProfileStore((state) => [
+ state.lendZoomLevel,
+ state.showBadges,
+ state.setShowBadges,
+ ]);
+ const inputRefs = useRef>({});
+ const [isInLendingMode, setIsInLendingMode] = useState(true);
+ const [isHotkeyMode, setIsHotkeyMode] = useState(false);
+
+ return (
+ <>
+
+
+
+
+
Global pool
+ {sortedBanks
+ .filter((b) => !b.info.state.isIsolated)
+ .map((bank, i) =>
+ isStoreInitialized ? (
+
+ ) : (
+ // TODO add skeleton lib & component if green light
+ <>>
+ )
+ )}
+
+ >
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/index.ts b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/index.ts
new file mode 100644
index 0000000000..4f65b5a204
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/index.ts
@@ -0,0 +1 @@
+export * from "./MobileAssetsList";
diff --git a/apps/marginfi-v2-ui/src/hooks/useAssetItemData.ts b/apps/marginfi-v2-ui/src/hooks/useAssetItemData.ts
new file mode 100644
index 0000000000..3c469c3d5b
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/hooks/useAssetItemData.ts
@@ -0,0 +1,40 @@
+import { ExtendedBankInfo, Emissions } from "@mrgnlabs/marginfi-v2-ui-state";
+import { PriceBias } from "@mrgnlabs/marginfi-client-v2";
+import { useMemo } from "react";
+import { percentFormatter } from "@mrgnlabs/mrgn-common";
+
+export function useAssetItemData({ bank, isInLendingMode }: { bank: ExtendedBankInfo; isInLendingMode: boolean }) {
+ const rateAP = useMemo(
+ () =>
+ percentFormatter.format(
+ (isInLendingMode ? bank.info.state.lendingRate : bank.info.state.borrowingRate) +
+ (isInLendingMode && bank.info.state.emissions == Emissions.Lending ? bank.info.state.emissionsRate : 0) +
+ (!isInLendingMode && bank.info.state.emissions == Emissions.Borrowing ? bank.info.state.emissionsRate : 0)
+ ),
+ [isInLendingMode, bank.info.state]
+ );
+
+ const assetWeight = useMemo(() => {
+ if (bank.info.rawBank.config.assetWeightInit.toNumber() <= 0) {
+ return "-";
+ }
+ return isInLendingMode
+ ? (bank.info.rawBank.config.assetWeightInit.toNumber() * 100).toFixed(0) + "%"
+ : ((1 / bank.info.rawBank.config.liabilityWeightInit.toNumber()) * 100).toFixed(0) + "%";
+ }, [isInLendingMode, bank.info.rawBank.config]);
+
+ const bankFilled = useMemo(
+ () => (isInLendingMode ? bank.info.rawBank.config.depositLimit : bank.info.rawBank.config.borrowLimit),
+ [isInLendingMode, bank.info.rawBank.config]
+ );
+ const isBankFilled = useMemo(
+ () => (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) >= bankFilled * 0.99999,
+ [bankFilled, isInLendingMode, bank.info.state]
+ );
+ const isBankHigh = useMemo(
+ () => (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) >= bankFilled * 0.9,
+ [bankFilled, isInLendingMode, bank.info.state]
+ );
+
+ return { rateAP, assetWeight, bankFilled, isBankFilled, isBankHigh };
+}
diff --git a/apps/marginfi-v2-ui/src/components/common/useFirebaseAccount.tsx b/apps/marginfi-v2-ui/src/hooks/useFirebaseAccount.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/common/useFirebaseAccount.tsx
rename to apps/marginfi-v2-ui/src/hooks/useFirebaseAccount.tsx
diff --git a/apps/marginfi-v2-ui/src/components/common/useWalletContext.tsx b/apps/marginfi-v2-ui/src/hooks/useWalletContext.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/common/useWalletContext.tsx
rename to apps/marginfi-v2-ui/src/hooks/useWalletContext.tsx
diff --git a/apps/marginfi-v2-ui/src/pages/bridge.tsx b/apps/marginfi-v2-ui/src/pages/bridge.tsx
index ef0b695dd7..96bbb1e082 100644
--- a/apps/marginfi-v2-ui/src/pages/bridge.tsx
+++ b/apps/marginfi-v2-ui/src/pages/bridge.tsx
@@ -8,7 +8,7 @@ import { useHotkeys } from "react-hotkeys-hook";
import { PageHeaderBridge } from "~/components/desktop/PageHeader";
import { MayanWidgetColors, MayanWidgetConfigType } from "~/types";
import { useUserProfileStore } from "~/store";
-import { useWalletContext } from "~/components/common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
const tokens = [
"0x0000000000000000000000000000000000000000", // SOL
diff --git a/apps/marginfi-v2-ui/src/pages/index.tsx b/apps/marginfi-v2-ui/src/pages/index.tsx
index a437b76e88..759d99aea8 100644
--- a/apps/marginfi-v2-ui/src/pages/index.tsx
+++ b/apps/marginfi-v2-ui/src/pages/index.tsx
@@ -1,7 +1,7 @@
import React, { useEffect } from "react";
import { Banner } from "~/components/desktop/Banner";
import { PageHeader } from "~/components/desktop/PageHeader";
-import { useWalletContext } from "~/components/common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
import { shortenAddress } from "@mrgnlabs/mrgn-common";
import config from "~/config/marginfi";
import { useMrgnlendStore } from "../store";
@@ -10,11 +10,26 @@ import { OverlaySpinner } from "~/components/desktop/OverlaySpinner";
import { useConnection } from "@solana/wallet-adapter-react";
import { Desktop, Mobile } from "~/mediaQueries";
-const AccountSummary = dynamic(async () => (await import("~/components/desktop/AccountSummary")).AccountSummary, {
+const DesktopAccountSummary = dynamic(
+ async () => (await import("~/components/desktop/DesktopAccountSummary")).DesktopAccountSummary,
+ {
+ ssr: false,
+ }
+);
+const MobileAccountSummary = dynamic(
+ async () => (await import("~/components/mobile/MobileAccountSummary")).MobileAccountSummary,
+ {
+ ssr: false,
+ }
+);
+const AssetsList = dynamic(async () => (await import("~/components/desktop/AssetsList")).AssetsList, { ssr: false });
+const MobileAssetsList = dynamic(async () => (await import("~/components/mobile/MobileAssetsList")).MobileAssetsList, {
+ ssr: false,
+});
+
+const UserPositions = dynamic(async () => (await import("~/components/desktop/UserPositions")).UserPositions, {
ssr: false,
});
-const AssetsList = dynamic(async () => (await import("~/components/desktop/AssetsList")).AssetsList, { ssr: false });
-const UserPositions = dynamic(async () => (await import("~/components/desktop/UserPositions")).UserPositions, { ssr: false });
const Home = () => {
const { walletAddress, wallet, isOverride } = useWalletContext();
@@ -60,33 +75,37 @@ const Home = () => {
return (
<>
-
-
-
- {walletAddress && selectedAccount && isOverride && (
-
- )}
- {walletAddress && marginfiAccountCount > 1 && (
-
- )}
+
+
+
+ {walletAddress && selectedAccount && isOverride && (
+
+ )}
+ {walletAddress && marginfiAccountCount > 1 && (
+
+ )}
-
-
-
-
- {walletAddress &&
}
-
-
-
+
+
+
+
+ {walletAddress &&
}
+
+
+
-
- LETS GOOOOO
-
+
+ LETS GOOOOO BIG
+
+
+
+
+
>
);
};
diff --git a/apps/marginfi-v2-ui/src/pages/lip.tsx b/apps/marginfi-v2-ui/src/pages/lip.tsx
index 5fe2c348ff..49bcca8277 100644
--- a/apps/marginfi-v2-ui/src/pages/lip.tsx
+++ b/apps/marginfi-v2-ui/src/pages/lip.tsx
@@ -1,7 +1,7 @@
import { PageHeader } from "~/components/desktop/PageHeader";
import { CampaignWizard } from "~/components/desktop/CampaignWizard";
import { LipClientProvider } from "~/context";
-import { useWalletContext } from "~/components/common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
const LIP = () => {
const { connected } = useWalletContext();
diff --git a/apps/marginfi-v2-ui/src/pages/points.tsx b/apps/marginfi-v2-ui/src/pages/points.tsx
index 542bb9cb35..f33ad4cf50 100644
--- a/apps/marginfi-v2-ui/src/pages/points.tsx
+++ b/apps/marginfi-v2-ui/src/pages/points.tsx
@@ -31,7 +31,7 @@ import { toast } from "react-toastify";
import { useUserProfileStore } from "~/store";
import { LeaderboardRow, fetchLeaderboardData, firebaseApi } from "@mrgnlabs/marginfi-v2-ui-state";
import { numeralFormatter, groupedNumberFormatterDyn } from "@mrgnlabs/mrgn-common";
-import { useWalletContext } from "~/components/common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
diff --git a/apps/marginfi-v2-ui/src/pages/swap.tsx b/apps/marginfi-v2-ui/src/pages/swap.tsx
index 6c0b12455e..0ae11ea979 100644
--- a/apps/marginfi-v2-ui/src/pages/swap.tsx
+++ b/apps/marginfi-v2-ui/src/pages/swap.tsx
@@ -3,7 +3,7 @@
import { useEffect } from "react";
import config from "~/config";
import { PageHeaderSwap } from "~/components/desktop/PageHeader";
-import { useWalletContext } from "~/components/common/useWalletContext";
+import { useWalletContext } from "~/hooks/useWalletContext";
const SwapPage = () => {
const { walletContextState } = useWalletContext();
diff --git a/apps/marginfi-v2-ui/src/utils/index.ts b/apps/marginfi-v2-ui/src/utils/index.ts
index b3dc1d121a..638495d45e 100644
--- a/apps/marginfi-v2-ui/src/utils/index.ts
+++ b/apps/marginfi-v2-ui/src/utils/index.ts
@@ -1,40 +1,3 @@
-import { PublicKey, TransactionInstruction } from "@solana/web3.js";
-import BN from "bn.js";
-import { TOKEN_PROGRAM_ID } from "@mrgnlabs/mrgn-common";
-import { ActiveBankInfo } from "@mrgnlabs/marginfi-v2-ui-state";
-
-// ================ development utils ================
-
-export const FAUCET_PROGRAM_ID = new PublicKey("4bXpkKSV8swHSnwqtzuboGPaPDeEgAn4Vt8GfarV5rZt");
-
-export function makeAirdropCollateralIx(
- amount: number,
- mint: PublicKey,
- tokenAccount: PublicKey,
- faucet: PublicKey
-): TransactionInstruction {
- const [faucetPda] = PublicKey.findProgramAddressSync([Buffer.from("faucet")], FAUCET_PROGRAM_ID);
-
- const keys = [
- { pubkey: faucetPda, isSigner: false, isWritable: false },
- { pubkey: mint, isSigner: false, isWritable: true },
- { pubkey: tokenAccount, isSigner: false, isWritable: true },
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
- { pubkey: faucet, isSigner: false, isWritable: false },
- ];
-
- return new TransactionInstruction({
- programId: FAUCET_PROGRAM_ID,
- data: Buffer.from([1, ...new BN(amount).toArray("le", 8)]),
- keys,
- });
-}
-
-export function isWholePosition(activeBankInfo: ActiveBankInfo, amount: number): boolean {
- const positionTokenAmount =
- Math.floor(activeBankInfo.position.amount * Math.pow(10, activeBankInfo.info.state.mintDecimals)) /
- Math.pow(10, activeBankInfo.info.state.mintDecimals);
- return amount >= positionTokenAmount;
-}
-
export { OKXWalletAdapter } from "./OKXWalletAdapter";
+export * from "./mrgnActions";
+export * from "./mrgnUtils";
diff --git a/apps/marginfi-v2-ui/src/utils/mrgnActions.ts b/apps/marginfi-v2-ui/src/utils/mrgnActions.ts
new file mode 100644
index 0000000000..7d9556cfcb
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/utils/mrgnActions.ts
@@ -0,0 +1,196 @@
+import { MarginfiAccountWrapper, MarginfiClient, MarginfiConfig } from "@mrgnlabs/marginfi-client-v2";
+import {
+ ExtendedBankInfo,
+ Emissions,
+ FEE_MARGIN,
+ ActionType,
+ getCurrentAction,
+ ExtendedBankMetadata,
+} from "@mrgnlabs/marginfi-v2-ui-state";
+import { toast } from "react-toastify";
+import { isWholePosition } from "./mrgnUtils";
+
+const CLOSE_BALANCE_TOAST_ID = "close-balance";
+const BORROW_OR_LEND_TOAST_ID = "borrow-or-lend";
+
+export const closeBalance = async ({
+ bank,
+ marginfiAccount,
+}: {
+ bank: ExtendedBankInfo;
+ marginfiAccount?: MarginfiAccountWrapper;
+}) => {
+ if (!marginfiAccount) {
+ toast.error("marginfi account not ready.");
+ throw new Error("marginfi account not ready.");
+ }
+
+ if (!bank.isActive) {
+ toast.error("no position to close.");
+ throw new Error("no position to close.");
+ }
+
+ toast.loading("Closing dust balance", {
+ toastId: CLOSE_BALANCE_TOAST_ID,
+ });
+
+ try {
+ if (bank.position.isLending) {
+ await marginfiAccount.withdraw(0, bank.address, true);
+ } else {
+ await marginfiAccount.repay(0, bank.address, true);
+ }
+ toast.update(CLOSE_BALANCE_TOAST_ID, {
+ render: "Closing 👍",
+ type: toast.TYPE.SUCCESS,
+ autoClose: 2000,
+ isLoading: false,
+ });
+ } catch (error: any) {
+ toast.update(CLOSE_BALANCE_TOAST_ID, {
+ render: `Error while closing balance: ${error.message}`,
+ type: toast.TYPE.ERROR,
+ autoClose: 5000,
+ isLoading: false,
+ });
+ console.log(`Error while closing balance`);
+ console.log(error);
+ }
+};
+
+export const borrowOrLend = async ({
+ mfiClient,
+ currentAction,
+ bank,
+ borrowOrLendAmount,
+ nativeSolBalance,
+ marginfiAccount,
+}: {
+ mfiClient: MarginfiClient;
+ bank: ExtendedBankInfo;
+ currentAction: ActionType | "Connect";
+ borrowOrLendAmount: number;
+ nativeSolBalance: number;
+ marginfiAccount?: MarginfiAccountWrapper;
+}) => {
+ if (mfiClient === null) throw Error("Marginfi client not ready");
+
+ if (currentAction === ActionType.Deposit && bank.info.state.totalDeposits >= bank.info.rawBank.config.depositLimit) {
+ toast.error(
+ `${bank.meta.tokenSymbol} deposit limit has been been reached. Additional deposits are not currently available.`
+ );
+ return;
+ }
+
+ if (currentAction === ActionType.Borrow && bank.info.state.totalBorrows >= bank.info.rawBank.config.borrowLimit) {
+ toast.error(
+ `${bank.meta.tokenSymbol} borrow limit has been been reached. Additional borrows are not currently available.`
+ );
+ return;
+ }
+
+ if (currentAction === ActionType.Deposit && bank.userInfo.maxDeposit === 0) {
+ toast.error(`You don't have any ${bank.meta.tokenSymbol} to lend in your wallet.`);
+ return;
+ }
+
+ if (currentAction === ActionType.Borrow && bank.userInfo.maxBorrow === 0) {
+ toast.error(`You cannot borrow any ${bank.meta.tokenSymbol} right now.`);
+ return;
+ }
+
+ if (borrowOrLendAmount <= 0) {
+ toast.error("Please enter an amount over 0.");
+ return;
+ }
+
+ let _marginfiAccount = marginfiAccount;
+
+ if (nativeSolBalance < FEE_MARGIN) {
+ toast.error("Not enough sol for fee.");
+ return;
+ }
+
+ // -------- Create marginfi account if needed
+ try {
+ if (!_marginfiAccount) {
+ if (currentAction !== ActionType.Deposit) {
+ toast.error("An account is required for anything operation except deposit.");
+ return;
+ }
+
+ toast.loading("Creating account", {
+ toastId: BORROW_OR_LEND_TOAST_ID,
+ });
+
+ _marginfiAccount = await mfiClient.createMarginfiAccount();
+ toast.update(BORROW_OR_LEND_TOAST_ID, {
+ render: `${currentAction + "ing"} ${borrowOrLendAmount} ${bank.meta.tokenSymbol}`,
+ });
+ }
+ } catch (error: any) {
+ toast.update(BORROW_OR_LEND_TOAST_ID, {
+ render: `Error while ${currentAction + "ing"}: ${error.message}`,
+ type: toast.TYPE.ERROR,
+ autoClose: 5000,
+ isLoading: false,
+ });
+ console.log(`Error while ${currentAction + "ing"}`);
+ console.log(error);
+ return;
+ }
+
+ // -------- Perform relevant operation
+ try {
+ if (currentAction === ActionType.Deposit) {
+ await _marginfiAccount.deposit(borrowOrLendAmount, bank.address);
+
+ toast.update(BORROW_OR_LEND_TOAST_ID, {
+ render: `${currentAction + "ing"} ${borrowOrLendAmount} ${bank.meta.tokenSymbol} 👍`,
+ type: toast.TYPE.SUCCESS,
+ autoClose: 2000,
+ isLoading: false,
+ });
+ }
+
+ toast.loading(`${currentAction + "ing"} ${borrowOrLendAmount} ${bank.meta.tokenSymbol}`, {
+ toastId: BORROW_OR_LEND_TOAST_ID,
+ });
+ if (_marginfiAccount === null) {
+ // noinspection ExceptionCaughtLocallyJS
+ throw Error("Marginfi account not ready");
+ }
+
+ if (currentAction === ActionType.Borrow) {
+ await _marginfiAccount.borrow(borrowOrLendAmount, bank.address);
+ } else if (currentAction === ActionType.Repay) {
+ await _marginfiAccount.repay(
+ borrowOrLendAmount,
+ bank.address,
+ bank.isActive && isWholePosition(bank, borrowOrLendAmount)
+ );
+ } else if (currentAction === ActionType.Withdraw) {
+ await _marginfiAccount.withdraw(
+ borrowOrLendAmount,
+ bank.address,
+ bank.isActive && isWholePosition(bank, borrowOrLendAmount)
+ );
+ }
+
+ toast.update(BORROW_OR_LEND_TOAST_ID, {
+ render: `${currentAction + "ing"} ${borrowOrLendAmount} ${bank.meta.tokenSymbol} 👍`,
+ type: toast.TYPE.SUCCESS,
+ autoClose: 2000,
+ isLoading: false,
+ });
+ } catch (error: any) {
+ toast.update(BORROW_OR_LEND_TOAST_ID, {
+ render: `Error while ${currentAction + "ing"}: ${error.message}`,
+ type: toast.TYPE.ERROR,
+ autoClose: 5000,
+ isLoading: false,
+ });
+ console.log(`Error while ${currentAction + "ing"}`);
+ console.log(error);
+ }
+};
diff --git a/apps/marginfi-v2-ui/src/utils/mrgnUtils.ts b/apps/marginfi-v2-ui/src/utils/mrgnUtils.ts
new file mode 100644
index 0000000000..c72e05fdca
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/utils/mrgnUtils.ts
@@ -0,0 +1,38 @@
+import { PublicKey, TransactionInstruction } from "@solana/web3.js";
+import BN from "bn.js";
+import { TOKEN_PROGRAM_ID } from "@mrgnlabs/mrgn-common";
+import { ActiveBankInfo } from "@mrgnlabs/marginfi-v2-ui-state";
+
+// ================ development utils ================
+
+export const FAUCET_PROGRAM_ID = new PublicKey("4bXpkKSV8swHSnwqtzuboGPaPDeEgAn4Vt8GfarV5rZt");
+
+export function makeAirdropCollateralIx(
+ amount: number,
+ mint: PublicKey,
+ tokenAccount: PublicKey,
+ faucet: PublicKey
+): TransactionInstruction {
+ const [faucetPda] = PublicKey.findProgramAddressSync([Buffer.from("faucet")], FAUCET_PROGRAM_ID);
+
+ const keys = [
+ { pubkey: faucetPda, isSigner: false, isWritable: false },
+ { pubkey: mint, isSigner: false, isWritable: true },
+ { pubkey: tokenAccount, isSigner: false, isWritable: true },
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
+ { pubkey: faucet, isSigner: false, isWritable: false },
+ ];
+
+ return new TransactionInstruction({
+ programId: FAUCET_PROGRAM_ID,
+ data: Buffer.from([1, ...new BN(amount).toArray("le", 8)]),
+ keys,
+ });
+}
+
+export function isWholePosition(activeBankInfo: ActiveBankInfo, amount: number): boolean {
+ const positionTokenAmount =
+ Math.floor(activeBankInfo.position.amount * Math.pow(10, activeBankInfo.info.state.mintDecimals)) /
+ Math.pow(10, activeBankInfo.info.state.mintDecimals);
+ return amount >= positionTokenAmount;
+}
diff --git a/apps/marginfi-v2-ui/tailwind.config.js b/apps/marginfi-v2-ui/tailwind.config.js
index 44786fb23f..944cc04293 100644
--- a/apps/marginfi-v2-ui/tailwind.config.js
+++ b/apps/marginfi-v2-ui/tailwind.config.js
@@ -10,7 +10,7 @@ module.exports = {
backgroundImage: {
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
"jup-gradient-colors": "linear-gradient(to right, #A0F0F8, #EEAC55)",
- "mayan-gradient-colors": "linear-gradient(90deg, #5768BD 0.11%, #FFFFFF 100%)"
+ "mayan-gradient-colors": "linear-gradient(90deg, #5768BD 0.11%, #FFFFFF 100%)",
},
borderImage: {
SOL: "linear-gradient(to top right, #9945FF, #19FB9B)",
@@ -28,6 +28,9 @@ module.exports = {
colors: {
"usd-equiv": "rgba(113, 119, 126, 0.3)",
"btn-light": "rgb(227, 227, 227)",
+ success: "#75ba80",
+ warning: "#daa204)",
+ error: "#e07d6f",
},
},
fontFamily: {
@@ -42,7 +45,7 @@ module.exports = {
},
},
plugins: [
- plugin(function({ addUtilities }) {
+ plugin(function ({ addUtilities }) {
addUtilities({
".invisible-scroll": {
"content-visibility": "auto",
diff --git a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx
index bce0af6a5f..619564097e 100644
--- a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx
+++ b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx
@@ -15,11 +15,11 @@ type Props = {
export function PoolCardStats({ bank, isInLendingMode, nativeSolBalance, bankFilled }: Props) {
const assetWeight = useMemo(() => {
- if (bank.info.rawBank.config.assetWeightMaint.toNumber() <= 0) {
+ if (bank.info.rawBank.config.assetWeightInit.toNumber() <= 0) {
return "-";
}
return isInLendingMode
- ? (bank.info.rawBank.config.assetWeightMaint.toNumber() * 100).toFixed(0) + "%"
+ ? (bank.info.rawBank.config.assetWeightInit.toNumber() * 100).toFixed(0) + "%"
: ((1 / bank.info.rawBank.config.liabilityWeightInit.toNumber()) * 100).toFixed(0) + "%";
}, [isInLendingMode, bank]);
From e68176641618085d04ee048eff265d58dd38cae0 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Fri, 8 Sep 2023 11:00:07 +0200
Subject: [PATCH 003/351] fix(mfi-v2-ui): build error
---
.../MobileAssetsList/AssetCard/AssetCard.tsx | 30 +++++++++++++++++
.../AssetCard/AssetCardStats.tsx | 32 +++++++++++++++----
apps/marginfi-v2-ui/src/utils/mrgnActions.ts | 6 ++--
3 files changed, 58 insertions(+), 10 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
index 5298fc1bd6..c106b7bcb8 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
@@ -22,6 +22,7 @@ import { borrowOrLend, closeBalance } from "~/utils";
import { useWalletContext } from "~/hooks/useWalletContext";
import { useAssetItemData } from "~/hooks/useAssetItemData";
import { HtmlTooltip } from "~/components/common/HtmlTooltip";
+import { AssetCardStats } from "./AssetCardStats";
export const AssetCard: FC<{
bank: ExtendedBankInfo;
@@ -45,6 +46,25 @@ export const AssetCard: FC<{
}) => {
const { rateAP, assetWeight, isBankFilled, isBankHigh, bankFilled } = useAssetItemData({ bank, isInLendingMode });
+ const totalDepositsOrBorrows = useMemo(
+ () =>
+ isInLendingMode
+ ? bank.info.state.totalDeposits
+ : Math.max(
+ 0,
+ Math.min(bank.info.state.totalDeposits, bank.info.rawBank.config.borrowLimit) - bank.info.state.totalBorrows
+ ),
+ [isInLendingMode, bank.info]
+ );
+
+ const userBalance = useMemo(
+ () =>
+ bank.info.state.mint.equals(WSOL_MINT)
+ ? bank.userInfo.tokenAccount.balance + nativeSolBalance
+ : bank.userInfo.tokenAccount.balance,
+ [bank.info.state.mint, bank.userInfo.tokenAccount, nativeSolBalance]
+ );
+
return (
@@ -63,6 +83,16 @@ export const AssetCard: FC<{
{rateAP.concat(...[" ", isInLendingMode ? "APY" : "APR"])}
+
);
};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
index 62a941a620..6fb1903b14 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
@@ -18,12 +18,26 @@ import {
import { ExtendedBankInfo, ActionType, getCurrentAction, ExtendedBankMetadata } from "@mrgnlabs/marginfi-v2-ui-state";
import { MarginfiAccountWrapper, PriceBias } from "@mrgnlabs/marginfi-client-v2";
-export const AssetStats: FC<{
+export const AssetCardStats: FC<{
bank: ExtendedBankInfo;
assetWeight: string;
+ totalDepositsOrBorrows: number;
+ userBalance: number;
+ isBankFilled: boolean;
+ isBankHigh: boolean;
+ bankFilled: number;
isInLendingMode: boolean;
- userBalance: string;
-}> = ({ bank, assetWeight, isInLendingMode, userBalance }) => {
+}> = ({
+ bank,
+ assetWeight,
+ totalDepositsOrBorrows,
+ userBalance,
+ isBankFilled,
+ isBankHigh,
+ bankFilled,
+ isInLendingMode,
+}) => {
+ console.log({ totalDepositsOrBorrows });
return (
@@ -33,10 +47,14 @@ export const AssetStats: FC<{
{/* TODO: Add seperator */}
{isInLendingMode ? "Deposits" : "Available"}
-
{0}
- {/* {isHigh && (
-
{percentFormatter.format(bankFilled)}
- )} */}
+
{numeralFormatter(totalDepositsOrBorrows)}
+ {isBankHigh && (
+
+ {percentFormatter.format(
+ (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) / bankFilled
+ )}
+
+ )}
{/* TODO: Add seperator */}
diff --git a/apps/marginfi-v2-ui/src/utils/mrgnActions.ts b/apps/marginfi-v2-ui/src/utils/mrgnActions.ts
index 7d9556cfcb..3ea812020a 100644
--- a/apps/marginfi-v2-ui/src/utils/mrgnActions.ts
+++ b/apps/marginfi-v2-ui/src/utils/mrgnActions.ts
@@ -18,7 +18,7 @@ export const closeBalance = async ({
marginfiAccount,
}: {
bank: ExtendedBankInfo;
- marginfiAccount?: MarginfiAccountWrapper;
+ marginfiAccount: MarginfiAccountWrapper | null;
}) => {
if (!marginfiAccount) {
toast.error("marginfi account not ready.");
@@ -66,12 +66,12 @@ export const borrowOrLend = async ({
nativeSolBalance,
marginfiAccount,
}: {
- mfiClient: MarginfiClient;
+ mfiClient: MarginfiClient | null;
bank: ExtendedBankInfo;
currentAction: ActionType | "Connect";
borrowOrLendAmount: number;
nativeSolBalance: number;
- marginfiAccount?: MarginfiAccountWrapper;
+ marginfiAccount: MarginfiAccountWrapper | null;
}) => {
if (mfiClient === null) throw Error("Marginfi client not ready");
From 4b9f8596c1317d8a421f9d55e2657e7ad26b82f6 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Fri, 8 Sep 2023 20:59:37 +0200
Subject: [PATCH 004/351] feat(mfi-v2-ui): mrgnlend mobile view
---
.../common/AccountSummary/GlobalStats.tsx | 5 +-
.../common/AccountSummary/UserStats.tsx | 430 +++++++++---------
.../AssetList}/AssetRowAction.tsx | 2 +-
.../AssetList}/AssetRowInputBox.tsx | 0
.../src/components/common/AssetList/index.ts | 2 +
.../src/components/common/HtmlTooltip.tsx | 15 -
.../Tooltip.tsx => common/MrgnTooltip.tsx} | 0
.../desktop/AssetsList/AssetRow/AssetRow.tsx | 21 +-
.../desktop/AssetsList/AssetsList.tsx | 52 ++-
.../DesktopAccountSummary.tsx | 16 +-
.../desktop/UserPositions/UserPositions.tsx | 27 +-
.../MobileAccountSummary.tsx | 37 +-
.../MobileAssetsList/AssetCard/AssetCard.tsx | 101 ++--
.../AssetCard/AssetCardActions.tsx | 80 ++++
.../AssetCard/AssetCardHeader.tsx | 59 +++
.../AssetCard/AssetCardPosition.tsx | 44 ++
.../AssetCard/AssetCardStats.tsx | 98 ++--
.../MobileAssetsList/MobileAssetsList.tsx | 110 +++--
apps/marginfi-v2-ui/src/pages/index.tsx | 2 +-
apps/marginfi-v2-ui/tailwind.config.js | 2 +-
apps/marginfi-v2-ui/tsconfig.json | 2 +
21 files changed, 702 insertions(+), 403 deletions(-)
rename apps/marginfi-v2-ui/src/components/{desktop/AssetsList/AssetRow => common/AssetList}/AssetRowAction.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{desktop/AssetsList/AssetRow => common/AssetList}/AssetRowInputBox.tsx (100%)
delete mode 100644 apps/marginfi-v2-ui/src/components/common/HtmlTooltip.tsx
rename apps/marginfi-v2-ui/src/components/{desktop/Tooltip.tsx => common/MrgnTooltip.tsx} (100%)
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardActions.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx
diff --git a/apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx b/apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx
index 02d898fe9a..b24f0ef63e 100644
--- a/apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx
@@ -1,10 +1,11 @@
import { FC } from "react";
import { Typography, Skeleton } from "@mui/material";
-import { numeralFormatter } from "@mrgnlabs/mrgn-common";
import Image from "next/image";
import Link from "next/link";
-import { MrgnTooltip } from "~/components/desktop/Tooltip";
+import { numeralFormatter } from "@mrgnlabs/mrgn-common";
+
+import { MrgnTooltip } from "~/components/common/MrgnTooltip";
import styles from "./style.module.css";
diff --git a/apps/marginfi-v2-ui/src/components/common/AccountSummary/UserStats.tsx b/apps/marginfi-v2-ui/src/components/common/AccountSummary/UserStats.tsx
index a735829781..65cbf7dde2 100644
--- a/apps/marginfi-v2-ui/src/components/common/AccountSummary/UserStats.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/AccountSummary/UserStats.tsx
@@ -1,11 +1,12 @@
import React, { FC, useMemo } from "react";
-import { AccountSummary } from "@mrgnlabs/marginfi-v2-ui-state";
-import { usdFormatter, numeralFormatter, usdFormatterDyn, percentFormatter } from "@mrgnlabs/mrgn-common";
-import { Typography, Skeleton } from "@mui/material";
+import { Typography } from "@mui/material";
import Image from "next/image";
import Link from "next/link";
-import { MrgnTooltip } from "~/components/desktop/Tooltip";
+import { AccountSummary } from "@mrgnlabs/marginfi-v2-ui-state";
+import { usdFormatter, numeralFormatter, usdFormatterDyn, percentFormatter } from "@mrgnlabs/mrgn-common";
+
+import { MrgnTooltip } from "~/components/common/MrgnTooltip";
import styles from "./style.module.css";
@@ -34,240 +35,245 @@ const UserStats: FC = ({ accountSummary, healthFactor }) => {
}, [healthFactor]);
return (
-
-
Your account
-
-
-
-
-
- Account
-
- {accountSummary && (
-
-
- Your account
-
-
- {`Without price bias, your account balance is ${usdFormatter.format(
- accountSummary.balanceUnbiased
- )}. With bias, your account balance is ${usdFormatter.format(accountSummary.balance)}.`}
-
-
- Learn why price bias matters.
-
-
- }
- placement="top"
- >
+
+
+
+
+
+ Account
+
+ {accountSummary && (
+
+
+ Your account
+
+
+ {`Without price bias, your account balance is ${usdFormatter.format(
+ accountSummary.balanceUnbiased
+ )}. With bias, your account balance is ${usdFormatter.format(accountSummary.balance)}.`}
+
+
+ Learn why price bias matters.
+
+
+ }
+ placement="top"
+ >
+
-
- )}
-
-
-
- {accountSummary ? (
- <>
- {`$${numeralFormatter(accountSummary.balanceUnbiased)}`}
-
-
- {Math.round(accountSummary.balanceUnbiased) > 10000
- ? usdFormatterDyn.format(Math.round(accountSummary.balanceUnbiased))
- : usdFormatter.format(accountSummary.balanceUnbiased)}
-
- {usdFormatter.format(accountSummary.balanceUnbiased)}
- >
- ) : (
- "-"
+
)}
-
-
-
-
-
-
-
- Supplying
-
- {accountSummary && (
-
-
- How much are you lending?
-
-
- {`Your assets are worth ${usdFormatter.format(
- accountSummary.lendingAmountUnbiased
- )} without price bias and ${usdFormatter.format(
- accountSummary.lendingAmount
- )} with price bias.`}
-
-
- Learn why price bias matters.
-
-
- }
- placement="top"
- >
-
-
- )}
-
-
-
- {accountSummary ? (
- <>
- {`$${numeralFormatter(accountSummary.lendingAmountUnbiased)}`}
+
+
+
+ {accountSummary ? (
+ <>
+ {`$${numeralFormatter(accountSummary.balanceUnbiased)}`}
-
- {Math.round(accountSummary.lendingAmountUnbiased) > 10000
- ? usdFormatterDyn.format(Math.round(accountSummary.lendingAmountUnbiased))
- : usdFormatter.format(accountSummary.lendingAmountUnbiased)}
-
+
+ {Math.round(accountSummary.balanceUnbiased) > 10000
+ ? usdFormatterDyn.format(Math.round(accountSummary.balanceUnbiased))
+ : usdFormatter.format(accountSummary.balanceUnbiased)}
+
- {usdFormatter.format(accountSummary.lendingAmountUnbiased)}
- >
- ) : (
- "-"
- )}
-
-
+
{usdFormatter.format(accountSummary.balanceUnbiased)}
+ >
+ ) : (
+ "-"
+ )}
+
-
-
-
-
- Borrowing
-
- {accountSummary && (
-
-
- How much are you borrowing?
-
-
- {`Your liabilities are worth ${usdFormatter.format(
- accountSummary.borrowingAmountUnbiased
- )} without price bias and ${usdFormatter.format(
- accountSummary.borrowingAmount
- )} with price bias.`}
-
-
- Learn why price bias matters.
-
-
- }
- placement="top"
- >
+
+
+
+
+
+ Supplying
+
+ {accountSummary && (
+
+
+ How much are you lending?
+
+
+ {`Your assets are worth ${usdFormatter.format(
+ accountSummary.lendingAmountUnbiased
+ )} without price bias and ${usdFormatter.format(
+ accountSummary.lendingAmount
+ )} with price bias.`}
+
+
+ Learn why price bias matters.
+
+
+ }
+ placement="top"
+ >
+
-
- )}
-
-
-
- {accountSummary ? (
- <>
- {`$${numeralFormatter(accountSummary.borrowingAmountUnbiased)}`}
-
-
- {Math.round(accountSummary.borrowingAmountUnbiased) > 10000
- ? usdFormatterDyn.format(Math.round(accountSummary.borrowingAmountUnbiased))
- : usdFormatter.format(accountSummary.borrowingAmountUnbiased)}
-
- {usdFormatter.format(accountSummary.borrowingAmountUnbiased)}
- >
- ) : (
- "-"
+
)}
-
-
+
+
+
+ {accountSummary ? (
+ <>
+ {`$${numeralFormatter(accountSummary.lendingAmountUnbiased)}`}
+
+
+ {Math.round(accountSummary.lendingAmountUnbiased) > 10000
+ ? usdFormatterDyn.format(Math.round(accountSummary.lendingAmountUnbiased))
+ : usdFormatter.format(accountSummary.lendingAmountUnbiased)}
+
+
+ {usdFormatter.format(accountSummary.lendingAmountUnbiased)}
+ >
+ ) : (
+ "-"
+ )}
+
-
-
-
-
- Health
-
- {accountSummary && (
-
-
- Health Factor
-
-
-
- Health factor is based off of price biased and weighted asset and liability
- values.
-
-
The formula is:
-
{"(assets - liabilities) / (assets)"}
-
Your math is:
-
{`(${usdFormatter.format(
- accountSummary.lendingAmountWithBiasAndWeighted
- )} - ${usdFormatter.format(
- accountSummary.borrowingAmountWithBiasAndWeighted
- )}) / (${usdFormatter.format(accountSummary.lendingAmountWithBiasAndWeighted)})`}
-
-
- }
- placement="top"
- >
+
+
+
+
+
+ Borrowing
+
+ {accountSummary && (
+
+
+ How much are you borrowing?
+
+
+ {`Your liabilities are worth ${usdFormatter.format(
+ accountSummary.borrowingAmountUnbiased
+ )} without price bias and ${usdFormatter.format(
+ accountSummary.borrowingAmount
+ )} with price bias.`}
+
+
+ Learn why price bias matters.
+
+
+ }
+ placement="top"
+ >
+
-
- )}
-
-
-
-
- {healthFactor ? percentFormatter.format(healthFactor) : "-"}
-
-
+
+
+ )}
+
+
+
+ {accountSummary ? (
+ <>
+ {`$${numeralFormatter(accountSummary.borrowingAmountUnbiased)}`}
+
+
+ {Math.round(accountSummary.borrowingAmountUnbiased) > 10000
+ ? usdFormatterDyn.format(Math.round(accountSummary.borrowingAmountUnbiased))
+ : usdFormatter.format(accountSummary.borrowingAmountUnbiased)}
+
+
+ {usdFormatter.format(accountSummary.borrowingAmountUnbiased)}
+ >
+ ) : (
+ "-"
+ )}
+
-
-
-
-
- Free
-
+
+
+
+
+
+ Health
+
+ {accountSummary && (
- Free Collateral
+ Health Factor
- Free collateral indicates how much of your collateral is available to open additional
- borrows or withdraw existing collateral.
+ Health factor is based off of price biased and weighted asset and liability
+ values.
-
It is computed from the weighted deposits and weighted borrows.
+
The formula is:
+
{"(assets - liabilities) / (assets)"}
+
Your math is:
+
{`(${usdFormatter.format(
+ accountSummary.lendingAmountWithBiasAndWeighted
+ )} - ${usdFormatter.format(
+ accountSummary.borrowingAmountWithBiasAndWeighted
+ )}) / (${usdFormatter.format(accountSummary.lendingAmountWithBiasAndWeighted)})`}
}
placement="top"
>
-
+
-
-
-
-
= 0 ? "#fff" : "#B8B45F"}
- className="font-aeonik font-[500] text-lg md:text-xl"
- component="div"
- >
- {accountSummary ? usdFormatter.format(accountSummary.signedFreeCollateral) : "-"}
-
-
+ )}
+
+
+
+
+ {healthFactor ? percentFormatter.format(healthFactor) : "-"}
+
+
+
+
+
+
+
+ Free
+
+
+
+ Free Collateral
+
+
+
+ Free collateral indicates how much of your collateral is available to open additional borrows
+ or withdraw existing collateral.
+
+
It is computed from the weighted deposits and weighted borrows.
+
+
+ }
+ placement="top"
+ >
+
+
+
+
+
+
= 0 ? "#fff" : "#B8B45F"}
+ className="font-aeonik font-[500] text-lg md:text-xl"
+ component="div"
+ >
+ {accountSummary ? usdFormatter.format(accountSummary.signedFreeCollateral) : "-"}
+
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRowAction.tsx b/apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowAction.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRowAction.tsx
rename to apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowAction.tsx
index 9b3786bd03..4a91eec146 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRowAction.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowAction.tsx
@@ -1,5 +1,5 @@
-import { Button, ButtonProps } from "@mui/material";
import { FC, ReactNode } from "react";
+import { Button, ButtonProps } from "@mui/material";
interface AssetRowActionProps extends ButtonProps {
children?: ReactNode;
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRowInputBox.tsx b/apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowInputBox.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRowInputBox.tsx
rename to apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowInputBox.tsx
diff --git a/apps/marginfi-v2-ui/src/components/common/AssetList/index.ts b/apps/marginfi-v2-ui/src/components/common/AssetList/index.ts
index 8442d9cd65..b587432a91 100644
--- a/apps/marginfi-v2-ui/src/components/common/AssetList/index.ts
+++ b/apps/marginfi-v2-ui/src/components/common/AssetList/index.ts
@@ -1 +1,3 @@
export * from "./BorrowLendToggle";
+export * from "./AssetRowAction";
+export * from "./AssetRowInputBox";
diff --git a/apps/marginfi-v2-ui/src/components/common/HtmlTooltip.tsx b/apps/marginfi-v2-ui/src/components/common/HtmlTooltip.tsx
deleted file mode 100644
index 15c924d0bc..0000000000
--- a/apps/marginfi-v2-ui/src/components/common/HtmlTooltip.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from "react";
-import { styled } from "@mui/material/styles";
-import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
-
-export const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
-
-))(({ theme }) => ({
- [`& .${tooltipClasses.tooltip}`]: {
- backgroundColor: "rgb(227, 227, 227)",
- color: "rgba(0, 0, 0, 0.87)",
- maxWidth: 220,
- fontSize: theme.typography.pxToRem(12),
- border: "1px solid #dadde9",
- },
-}));
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Tooltip.tsx b/apps/marginfi-v2-ui/src/components/common/MrgnTooltip.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/desktop/Tooltip.tsx
rename to apps/marginfi-v2-ui/src/components/common/MrgnTooltip.tsx
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
index 33dcd16122..13cc94b65d 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
@@ -1,8 +1,7 @@
import React, { FC, useCallback, useEffect, useMemo, useState } from "react";
import Image from "next/image";
import { TableCell, TableRow } from "@mui/material";
-import { styled } from "@mui/material/styles";
-import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
+import Tooltip from "@mui/material/Tooltip";
import Typography from "@mui/material/Typography";
import { useMrgnlendStore, useUserProfileStore } from "~/store";
import Badge from "@mui/material/Badge";
@@ -21,10 +20,8 @@ import { MarginfiAccountWrapper, PriceBias } from "@mrgnlabs/marginfi-client-v2"
import { borrowOrLend, closeBalance } from "~/utils";
import { useWalletContext } from "~/hooks/useWalletContext";
import { useAssetItemData } from "~/hooks/useAssetItemData";
-import { HtmlTooltip } from "~/components/common/HtmlTooltip";
-
-import { AssetRowInputBox } from "./AssetRowInputBox";
-import { AssetRowAction } from "./AssetRowAction";
+import { MrgnTooltip } from "~/components/common/MrgnTooltip";
+import { AssetRowInputBox, AssetRowAction } from "~/components/common/AssetList";
const AssetRow: FC<{
bank: ExtendedBankInfo;
@@ -156,7 +153,7 @@ const AssetRow: FC<{
align="right"
style={{ fontWeight: 300 }}
>
-
@@ -191,7 +188,7 @@ const AssetRow: FC<{
: usdFormatter.format(bank.info.state.price)
: `$${bank.info.state.price.toExponential(2)}`}
-
+
{bank.meta.tokenSymbol === "UXD" && isInLendingMode && (
-
@@ -222,7 +219,7 @@ const AssetRow: FC<{
placement="left"
>
-
+
)}
-
@@ -304,7 +301,7 @@ const AssetRow: FC<{
)
)}
-
+
{/*******************************/}
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
index b03c4d3443..87c0d92618 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
@@ -2,8 +2,6 @@ import React, { FC, useEffect, useRef, useState } from "react";
import Image from "next/image";
import { useHotkeys } from "react-hotkeys-hook";
import { Card, Table, TableHead, TableBody, TableContainer, TableCell } from "@mui/material";
-import { styled } from "@mui/material/styles";
-import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
import Typography from "@mui/material/Typography";
import { useMrgnlendStore, useUserProfileStore } from "~/store";
@@ -11,7 +9,7 @@ import { useWalletContext } from "~/hooks/useWalletContext";
import { BorrowLendToggle } from "~/components/common/AssetList/BorrowLendToggle";
import { LoadingAsset, AssetRow } from "./AssetRow";
-import { HtmlTooltip } from "~/components/common/HtmlTooltip";
+import { MrgnTooltip } from "~/components/common/MrgnTooltip";
const AssetsList: FC = () => {
// const { selectedAccount, nativeSolBalance } = useStore();
@@ -124,19 +122,21 @@ const AssetsList: FC = () => {
>
Price
-
Realtime prices
- Powered by Pyth and Switchboard.
+
+ Powered by Pyth and Switchboard.
+
}
placement="top"
>
-
+
{
>
{isInLendingMode ? "APY" : "APR"}
-
@@ -162,7 +162,7 @@ const AssetsList: FC = () => {
placement="top"
>
-
+
{
>
{isInLendingMode ? "Weight" : "LTV"}
-
{isInLendingMode ? "Weight" : "LTV"}
- {isInLendingMode
- ? "How much your assets count for collateral, relative to their USD value. The higher the weight, the more collateral you can borrow against it."
- : "How much you can borrow against your free collateral. The higher the LTV, the more you can borrow against your free collateral."}
+
+ {isInLendingMode
+ ? "How much your assets count for collateral, relative to their USD value. The higher the weight, the more collateral you can borrow against it."
+ : "How much you can borrow against your free collateral. The higher the LTV, the more you can borrow against your free collateral."}
+
}
placement="top"
>
-
+
{
>
{isInLendingMode ? "Deposits" : "Available"}
-
{isInLendingMode ? "Total deposits" : "Total available"}
- {isInLendingMode
- ? "Total marginfi deposits for each asset. Everything is denominated in native tokens."
- : "The amount of tokens available to borrow for each asset. Calculated as the minimum of the asset's borrow limit and available liquidity that has not yet been borrowed."}
+
+ {isInLendingMode
+ ? "Total marginfi deposits for each asset. Everything is denominated in native tokens."
+ : "The amount of tokens available to borrow for each asset. Calculated as the minimum of the asset's borrow limit and available liquidity that has not yet been borrowed."}
+
}
placement="top"
>
-
+
@@ -226,7 +230,7 @@ const AssetsList: FC = () => {
>
Global limit
-
@@ -239,7 +243,7 @@ const AssetsList: FC = () => {
placement="top"
>
-
+
)}
@@ -252,7 +256,7 @@ const AssetsList: FC = () => {
>
Utilization
-
@@ -265,7 +269,7 @@ const AssetsList: FC = () => {
placement="top"
>
-
+
)}
@@ -315,7 +319,7 @@ const AssetsList: FC = () => {
Isolated pools
-
@@ -329,7 +333,7 @@ const AssetsList: FC = () => {
placement="top"
>
-
+
{sortedBanks
diff --git a/apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/DesktopAccountSummary.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/DesktopAccountSummary.tsx
index 3e99c6f6fa..03ea07858f 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/DesktopAccountSummary.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopAccountSummary/DesktopAccountSummary.tsx
@@ -1,6 +1,7 @@
import React, { FC } from "react";
-import { useMrgnlendStore } from "~/store";
import dynamic from "next/dynamic";
+
+import { useMrgnlendStore } from "~/store";
import { useWalletContext } from "~/hooks/useWalletContext";
import { UserStats } from "~/components/common/AccountSummary";
@@ -19,7 +20,7 @@ const AccountSummary: FC = () => {
return (
-
+
Global stats
{
{connected && (
-
+
+ Your account
+
+
)}
diff --git a/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx
index 47d735e7b1..6ac8beb192 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx
@@ -1,13 +1,14 @@
import React, { FC, useMemo } from "react";
import { Card, Table, TableBody, TableContainer, TableHead, TableCell, Typography } from "@mui/material";
-import UserPositionRow from "./UserPositionRow";
-import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
-import { styled } from "@mui/material/styles";
import Image from "next/image";
import Link from "next/link";
-import { useMrgnlendStore } from "~/store";
+
import { ActiveBankInfo } from "@mrgnlabs/marginfi-v2-ui-state";
-import { HtmlTooltip } from "~/components/common/HtmlTooltip";
+
+import { useMrgnlendStore } from "~/store";
+import { MrgnTooltip } from "~/components/common/MrgnTooltip";
+
+import UserPositionRow from "./UserPositionRow";
const UserPositions: FC = () => {
const setIsRefreshingStore = useMrgnlendStore((state) => state.setIsRefreshingStore);
@@ -60,7 +61,7 @@ const UserPositions: FC = () => {
Wtd
-
@@ -80,7 +81,7 @@ const UserPositions: FC = () => {
placement="top"
>
-
+
@@ -92,7 +93,7 @@ const UserPositions: FC = () => {
USD
-
@@ -114,7 +115,7 @@ const UserPositions: FC = () => {
placement="top"
>
-
+
@@ -169,7 +170,7 @@ const UserPositions: FC = () => {
Wtd
-
@@ -189,7 +190,7 @@ const UserPositions: FC = () => {
placement="top"
>
-
+
@@ -201,7 +202,7 @@ const UserPositions: FC = () => {
USD
-
@@ -223,7 +224,7 @@ const UserPositions: FC = () => {
placement="top"
>
-
+
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
index 91183d5353..c97597934d 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
@@ -1,6 +1,7 @@
import React, { FC } from "react";
-import { useMrgnlendStore } from "~/store";
import dynamic from "next/dynamic";
+
+import { useMrgnlendStore } from "~/store";
import { useWalletContext } from "~/hooks/useWalletContext";
import { UserStats } from "~/components/common/AccountSummary";
@@ -18,24 +19,30 @@ const AccountSummary: FC = () => {
const { connected } = useWalletContext();
return (
-
-
-
+
+
+
+ Global stats
+
+
{" "}
- {/*
+
{connected && (
-
+
+ Your account
+
+
)}
-
*/}
+
);
};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
index c106b7bcb8..6798772788 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
@@ -1,28 +1,19 @@
-import React, { FC, useCallback, useEffect, useMemo, useState } from "react";
-import Image from "next/image";
-import { TableCell, TableRow } from "@mui/material";
-import { styled } from "@mui/material/styles";
-import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
-import Typography from "@mui/material/Typography";
-import { useMrgnlendStore, useUserProfileStore } from "~/store";
-import Badge from "@mui/material/Badge";
+import React, { FC, useCallback, useMemo } from "react";
-import {
- WSOL_MINT,
- groupedNumberFormatterDyn,
- numeralFormatter,
- percentFormatter,
- uiToNative,
- usdFormatter,
-} from "@mrgnlabs/mrgn-common";
-import { ExtendedBankInfo, ActionType, getCurrentAction, ExtendedBankMetadata } from "@mrgnlabs/marginfi-v2-ui-state";
-import { MarginfiAccountWrapper, PriceBias } from "@mrgnlabs/marginfi-client-v2";
+import { WSOL_MINT } from "@mrgnlabs/mrgn-common";
+import { ExtendedBankInfo, ActionType, getCurrentAction } from "@mrgnlabs/marginfi-v2-ui-state";
+import { MarginfiAccountWrapper } from "@mrgnlabs/marginfi-client-v2";
+import { useMrgnlendStore } from "~/store";
import { borrowOrLend, closeBalance } from "~/utils";
import { useWalletContext } from "~/hooks/useWalletContext";
import { useAssetItemData } from "~/hooks/useAssetItemData";
-import { HtmlTooltip } from "~/components/common/HtmlTooltip";
+
import { AssetCardStats } from "./AssetCardStats";
+import { AssetCardActions } from "./AssetCardActions";
+
+import { AssetCardPosition } from "./AssetCardPosition";
+import { AssetCardHeader } from "./AssetCardHeader";
export const AssetCard: FC<{
bank: ExtendedBankInfo;
@@ -45,7 +36,9 @@ export const AssetCard: FC<{
badgeContent,
}) => {
const { rateAP, assetWeight, isBankFilled, isBankHigh, bankFilled } = useAssetItemData({ bank, isInLendingMode });
-
+ const [mfiClient, fetchMrgnlendState] = useMrgnlendStore((state) => [state.marginfiClient, state.fetchMrgnlendState]);
+ const setIsRefreshingStore = useMrgnlendStore((state) => state.setIsRefreshingStore);
+ const { connected } = useWalletContext();
const totalDepositsOrBorrows = useMemo(
() =>
isInLendingMode
@@ -65,24 +58,46 @@ export const AssetCard: FC<{
[bank.info.state.mint, bank.userInfo.tokenAccount, nativeSolBalance]
);
+ const currentAction: ActionType | "Connect" = useMemo(
+ () => (connected ? getCurrentAction(isInLendingMode, bank) : "Connect"),
+ [connected, isInLendingMode, bank]
+ );
+
+ const handleCloseBalance = useCallback(async () => {
+ try {
+ closeBalance({ marginfiAccount, bank });
+ } catch (error) {
+ return;
+ }
+
+ try {
+ setIsRefreshingStore(true);
+ await fetchMrgnlendState();
+ } catch (error: any) {
+ console.log("Error while reloading state");
+ console.log(error);
+ }
+ }, [bank, marginfiAccount, fetchMrgnlendState, setIsRefreshingStore]);
+
+ const handleBorrowOrLend = useCallback(
+ async (borrowOrLendAmount: number) => {
+ borrowOrLend({ mfiClient, currentAction, bank, borrowOrLendAmount, nativeSolBalance, marginfiAccount });
+
+ // -------- Refresh state
+ try {
+ setIsRefreshingStore(true);
+ await fetchMrgnlendState();
+ } catch (error: any) {
+ console.log("Error while reloading state");
+ console.log(error);
+ }
+ },
+ [bank, currentAction, marginfiAccount, mfiClient, nativeSolBalance, fetchMrgnlendState, setIsRefreshingStore]
+ );
+
return (
-
-
-
-
- {bank.meta.tokenLogoUri && (
-
- )}
-
-
-
{bank.meta.tokenSymbol}
-
{usdFormatter.format(bank.info.state.price)}
-
-
-
-
{rateAP.concat(...[" ", isInLendingMode ? "APY" : "APR"])}
-
-
+
+
+ />
+ {bank.isActive &&
}
+
handleCloseBalance()}
+ onBorrowOrLend={(amount) => handleBorrowOrLend(amount)}
+ />
);
};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardActions.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardActions.tsx
new file mode 100644
index 0000000000..0e8134a4d0
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardActions.tsx
@@ -0,0 +1,80 @@
+import React, { FC, useMemo, useState } from "react";
+
+import { ExtendedBankInfo, ActionType } from "@mrgnlabs/marginfi-v2-ui-state";
+import { uiToNative } from "@mrgnlabs/mrgn-common";
+
+import { AssetRowAction, AssetRowInputBox } from "~/components/common/AssetList";
+import { useWalletContext } from "~/hooks/useWalletContext";
+
+export const AssetCardActions: FC<{
+ bank: ExtendedBankInfo;
+ inputRefs: React.MutableRefObject
>;
+ isBankFilled: boolean;
+ isInLendingMode: boolean;
+ currentAction: ActionType | "Connect";
+ onCloseBalance: () => void;
+ onBorrowOrLend: (amount: number) => void;
+}> = ({ bank, inputRefs, isBankFilled, currentAction, onCloseBalance, onBorrowOrLend }) => {
+ const { openWalletSelector } = useWalletContext();
+ const [borrowOrLendAmount, setBorrowOrLendAmount] = useState(0);
+
+ const maxAmount = useMemo(() => {
+ switch (currentAction) {
+ case ActionType.Deposit:
+ return bank.userInfo.maxDeposit;
+ case ActionType.Withdraw:
+ return bank.userInfo.maxWithdraw;
+ case ActionType.Borrow:
+ return bank.userInfo.maxBorrow;
+ case ActionType.Repay:
+ return bank.userInfo.maxRepay;
+ }
+ }, [bank.userInfo, currentAction]);
+
+ const isDust = useMemo(
+ () => bank.isActive && uiToNative(bank.position.amount, bank.info.state.mintDecimals).isZero(),
+ [bank]
+ );
+
+ const isDisabled = useMemo(
+ () =>
+ currentAction !== "Connect" &&
+ ((isDust && uiToNative(bank.userInfo.tokenAccount.balance, bank.info.state.mintDecimals).isZero()) ||
+ maxAmount === 0),
+ [currentAction, isBankFilled, isDust, maxAmount]
+ );
+
+ return (
+ <>
+
+
onBorrowOrLend(borrowOrLendAmount)}
+ />
+
+ currentAction === "Connect"
+ ? openWalletSelector()
+ : isDust
+ ? onCloseBalance()
+ : onBorrowOrLend(borrowOrLendAmount)
+ }
+ disabled={isDisabled}
+ >
+ {isDust ? "Close" : currentAction}
+
+
+ >
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
new file mode 100644
index 0000000000..cdca305912
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
@@ -0,0 +1,59 @@
+import React, { FC } from "react";
+import Image from "next/image";
+
+import { Typography } from "@mui/material";
+
+import { percentFormatter, usdFormatter } from "@mrgnlabs/mrgn-common";
+import { ExtendedBankInfo } from "@mrgnlabs/marginfi-v2-ui-state";
+
+import { MrgnTooltip } from "~/components/common/MrgnTooltip";
+
+export const AssetCardHeader: FC<{
+ bank: ExtendedBankInfo;
+ isInLendingMode: boolean;
+ rateAP: string;
+}> = ({ bank, isInLendingMode, rateAP }) => {
+ return (
+
+
+
+ {bank.meta.tokenLogoUri && (
+
+ )}
+
+
+
{bank.meta.tokenSymbol}
+
{usdFormatter.format(bank.info.state.price)}
+
+
+
+
+ {bank.meta.tokenSymbol === "UXD" && isInLendingMode && (
+
+
+
+ Liquidity rewards
+
+ {`${percentFormatter.format(bank.info.state.lendingRate)} Supply APY + ${percentFormatter.format(
+ bank.info.state.emissionsRate
+ )} UXP rewards.`}
+
+
+ Learn more.
+
+ >
+ }
+ placement="left"
+ >
+
+
+
+ )}
+
+
{rateAP.concat(...[" ", isInLendingMode ? "APY" : "APR"])}
+
+
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx
new file mode 100644
index 0000000000..653a6832cc
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx
@@ -0,0 +1,44 @@
+import React, { FC, useState } from "react";
+
+import { usdFormatter } from "@mrgnlabs/mrgn-common";
+import { ActiveBankInfo } from "@mrgnlabs/marginfi-v2-ui-state";
+
+import ExpandLessIcon from "@mui/icons-material/ExpandLess";
+import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
+
+export const AssetCardPosition: FC<{
+ activeBank: ActiveBankInfo;
+}> = ({ activeBank }) => {
+ const [isCollapsed, setIsCollapsed] = useState(true);
+
+ return (
+
+
+
Your position details
+
setIsCollapsed(!isCollapsed)}>
+ {isCollapsed ? : }
+
+
+ {!isCollapsed && (
+
+
+
+ {(activeBank as ActiveBankInfo).position.isLending ? "Lending" : "Borrowing"}
+
+
+ {(activeBank as ActiveBankInfo).position.amount.toFixed(activeBank.info.state.mintDecimals) +
+ " " +
+ activeBank.meta.tokenSymbol}
+
+
+
+
USD value
+
+ {usdFormatter.format((activeBank as ActiveBankInfo).position.usdValue)}
+
+
+
+ )}
+
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
index 6fb1903b14..ddf9408254 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
@@ -1,22 +1,11 @@
-import React, { FC, useCallback, useEffect, useMemo, useState } from "react";
+import React, { FC } from "react";
import Image from "next/image";
-import { TableCell, TableRow } from "@mui/material";
-import { styled } from "@mui/material/styles";
-import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
import Typography from "@mui/material/Typography";
-import { useMrgnlendStore, useUserProfileStore } from "~/store";
-import Badge from "@mui/material/Badge";
-import {
- WSOL_MINT,
- groupedNumberFormatterDyn,
- numeralFormatter,
- percentFormatter,
- uiToNative,
- usdFormatter,
-} from "@mrgnlabs/mrgn-common";
-import { ExtendedBankInfo, ActionType, getCurrentAction, ExtendedBankMetadata } from "@mrgnlabs/marginfi-v2-ui-state";
-import { MarginfiAccountWrapper, PriceBias } from "@mrgnlabs/marginfi-client-v2";
+import { numeralFormatter, percentFormatterDyn } from "@mrgnlabs/mrgn-common";
+import { ExtendedBankInfo } from "@mrgnlabs/marginfi-v2-ui-state";
+
+import { MrgnTooltip } from "~/components/common/MrgnTooltip";
export const AssetCardStats: FC<{
bank: ExtendedBankInfo;
@@ -37,30 +26,75 @@ export const AssetCardStats: FC<{
bankFilled,
isInLendingMode,
}) => {
- console.log({ totalDepositsOrBorrows });
return (
-
-
-
Weight
-
{assetWeight}
+
+
+
+ {isInLendingMode ? "Weight" : "LTV"}
+
+
+
+ {isInLendingMode ? "Weight" : "LTV"}
+
+
+ {isInLendingMode
+ ? "How much your assets count for collateral, relative to their USD value. The higher the weight, the more collateral you can borrow against it."
+ : "How much you can borrow against your free collateral. The higher the LTV, the more you can borrow against your free collateral."}
+
+
+ }
+ placement="top"
+ >
+
+
+
+
+
{assetWeight}
- {/* TODO: Add seperator */}
-
-
{isInLendingMode ? "Deposits" : "Available"}
-
{numeralFormatter(totalDepositsOrBorrows)}
+
+
+
+ {isInLendingMode ? "Deposits" : "Available"}
+
+
+
+ {isInLendingMode ? "Total deposits" : "Total available"}
+
+
+ {isInLendingMode
+ ? "Total marginfi deposits for each asset. Everything is denominated in native tokens."
+ : "The amount of tokens available to borrow for each asset. Calculated as the minimum of the asset's borrow limit and available liquidity that has not yet been borrowed."}
+
+
+ }
+ placement="top"
+ >
+
+
+
+
+
{numeralFormatter(totalDepositsOrBorrows)}
{isBankHigh && (
-
- {percentFormatter.format(
+
+ {percentFormatterDyn.format(
(isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) / bankFilled
- )}
+ ) + " FILLED"}
)}
- {/* TODO: Add seperator */}
-
-
Your Balance
-
{userBalance + " " + bank.meta.tokenSymbol}
+
+
+
Your Balance
+
{userBalance + " " + bank.meta.tokenSymbol}
);
};
+
+function Separator() {
+ return
;
+}
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
index 3528673ecf..980abbfcca 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
@@ -1,19 +1,18 @@
-import React, { FC, useEffect, useRef, useState } from "react";
+import React, { FC, useRef, useState } from "react";
import Image from "next/image";
-import { useHotkeys } from "react-hotkeys-hook";
-import { Card, Table, TableHead, TableBody, TableContainer, TableCell } from "@mui/material";
-import { styled } from "@mui/material/styles";
-import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
-import Typography from "@mui/material/Typography";
+import { Skeleton, Switch, Typography } from "@mui/material";
import { useMrgnlendStore, useUserProfileStore } from "~/store";
import { useWalletContext } from "~/hooks/useWalletContext";
-import { BorrowLendToggle } from "~/components/common/AssetList/BorrowLendToggle";
-import { AssetCard } from "./AssetCard";
+import { BorrowLendToggle } from "~/components/common/AssetList";
+import { MrgnTooltip } from "~/components/common/MrgnTooltip";
-// import { LoadingAsset, AssetRow } from "./AssetRow";
+import { AssetCard } from "./AssetCard";
export const MobileAssetsList: FC = () => {
+ const [isFiltered, setIsFiltered] = useState(false);
+ const togglePositions = () => setIsFiltered((previousState) => !previousState);
+
const { connected } = useWalletContext();
const [isStoreInitialized, sortedBanks, nativeSolBalance, selectedAccount] = useMrgnlendStore((state) => [
state.initialized,
@@ -35,29 +34,78 @@ export const MobileAssetsList: FC = () => {
+
+
+
Filter my positions
+
+
+
Global pool
+
+ {sortedBanks
+ .filter((b) => !b.info.state.isIsolated)
+ .filter((b) => (isFiltered ? b.isActive : true))
+ .map((bank, i) =>
+ isStoreInitialized ? (
+
+ ) : (
+
+ )
+ )}
+
+
-
Global pool
- {sortedBanks
- .filter((b) => !b.info.state.isIsolated)
- .map((bank, i) =>
- isStoreInitialized ? (
-
- ) : (
- // TODO add skeleton lib & component if green light
- <>>
- )
- )}
+
+ Isolated pool
+
+
+ Isolated pools are risky ⚠️
+
+ Assets in isolated pools cannot be used as collateral. When you borrow an isolated asset, you cannot
+ borrow other assets. Isolated pools should be considered particularly risky. As always, remember that
+ marginfi is a decentralized protocol and all deposited funds are at risk.
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+ {sortedBanks
+ .filter((b) => b.info.state.isIsolated)
+ .filter((b) => (isFiltered ? b.isActive : true))
+ .map((bank, i) =>
+ isStoreInitialized ? (
+
+ ) : (
+
+ )
+ )}
+
>
);
diff --git a/apps/marginfi-v2-ui/src/pages/index.tsx b/apps/marginfi-v2-ui/src/pages/index.tsx
index 759d99aea8..aafa32e979 100644
--- a/apps/marginfi-v2-ui/src/pages/index.tsx
+++ b/apps/marginfi-v2-ui/src/pages/index.tsx
@@ -100,7 +100,7 @@ const Home = () => {
- LETS GOOOOO BIG
+
diff --git a/apps/marginfi-v2-ui/tailwind.config.js b/apps/marginfi-v2-ui/tailwind.config.js
index 944cc04293..3f0c40a196 100644
--- a/apps/marginfi-v2-ui/tailwind.config.js
+++ b/apps/marginfi-v2-ui/tailwind.config.js
@@ -29,7 +29,7 @@ module.exports = {
"usd-equiv": "rgba(113, 119, 126, 0.3)",
"btn-light": "rgb(227, 227, 227)",
success: "#75ba80",
- warning: "#daa204)",
+ warning: "#daa204",
error: "#e07d6f",
},
},
diff --git a/apps/marginfi-v2-ui/tsconfig.json b/apps/marginfi-v2-ui/tsconfig.json
index 5f2861ee6c..5fe65688ee 100644
--- a/apps/marginfi-v2-ui/tsconfig.json
+++ b/apps/marginfi-v2-ui/tsconfig.json
@@ -2,6 +2,8 @@
"extends": "@mrgnlabs/tsconfig/nextjs.json",
"compilerOptions": {
"jsx": "preserve",
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
"downlevelIteration": true,
"paths": {
"~/*": [
From ab9ce245dec2482cf192e649be2ed8a07310fe0a Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Fri, 8 Sep 2023 21:08:03 +0200
Subject: [PATCH 005/351] fix(mfi-v2-ui): build fix
---
.../MobileAssetsList/AssetCard/AssetCard.tsx | 2 +-
.../AssetCard/AssetCardActions.tsx | 2 +-
.../mobile/MobileAssetsList/MobileAssetsList.tsx | 16 ++++++++++++++--
3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
index 6798772788..3f9c98ec22 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
@@ -96,7 +96,7 @@ export const AssetCard: FC<{
);
return (
-
+
{
badgeContent={`${i + 1}`}
/>
) : (
-
+
)
)}
@@ -102,7 +108,13 @@ export const MobileAssetsList: FC = () => {
badgeContent={`${i + 1}`}
/>
) : (
-
+
)
)}
From 03e1ac6548ca8dcd4f02fa7ecedaba4a6120a206 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Sat, 9 Sep 2023 13:17:29 +0200
Subject: [PATCH 006/351] fix(mfi-v2-ui): PR changes
---
.../desktop/AssetsList/AssetRow/AssetRow.tsx | 10 +--
.../MobileAssetsList/AssetCard/AssetCard.tsx | 4 +-
.../AssetCard/AssetCardStats.tsx | 6 +-
.../MobileAssetsList/MobileAssetsList.tsx | 7 ---
.../src/hooks/useAssetItemData.ts | 13 ++--
apps/marginfi-v2-ui/src/pages/index.tsx | 63 +++++++++++++------
.../src/components/Lend/PoolCard/PoolCard.tsx | 2 +-
.../Lend/PoolCard/PoolCardStats.tsx | 12 ++--
8 files changed, 65 insertions(+), 52 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
index 13cc94b65d..a647593acf 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetRow/AssetRow.tsx
@@ -47,7 +47,7 @@ const AssetRow: FC<{
const [lendZoomLevel, denominationUSD] = useUserProfileStore((state) => [state.lendZoomLevel, state.denominationUSD]);
const setIsRefreshingStore = useMrgnlendStore((state) => state.setIsRefreshingStore);
const [mfiClient, fetchMrgnlendState] = useMrgnlendStore((state) => [state.marginfiClient, state.fetchMrgnlendState]);
- const { rateAP, assetWeight, isBankFilled, isBankHigh, bankFilled } = useAssetItemData({ bank, isInLendingMode });
+ const { rateAP, assetWeight, isBankFilled, isBankHigh, bankCap } = useAssetItemData({ bank, isInLendingMode });
const assetPriceOffset = useMemo(
() =>
@@ -253,7 +253,7 @@ const AssetRow: FC<{
{isBankHigh && (isBankFilled ? "Limit Reached" : "Approaching Limit")}
{`${bank.meta.tokenSymbol} ${isInLendingMode ? "deposits" : "borrows"} are at ${percentFormatter.format(
- (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) / bankFilled
+ (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) / bankCap
)} capacity.`}
@@ -315,10 +315,10 @@ const AssetRow: FC<{
style={{ fontWeight: 300 }}
>
{denominationUSD
- ? usdFormatter.format(bankFilled * bank.info.state.price)
+ ? usdFormatter.format(bankCap * bank.info.state.price)
: lendZoomLevel < 2
- ? groupedNumberFormatterDyn.format(bankFilled)
- : numeralFormatter(bankFilled)}
+ ? groupedNumberFormatterDyn.format(bankCap)
+ : numeralFormatter(bankCap)}
)}
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
index 3f9c98ec22..1c9640b099 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
@@ -35,7 +35,7 @@ export const AssetCard: FC<{
showHotkeyBadges,
badgeContent,
}) => {
- const { rateAP, assetWeight, isBankFilled, isBankHigh, bankFilled } = useAssetItemData({ bank, isInLendingMode });
+ const { rateAP, assetWeight, isBankFilled, isBankHigh, bankCap } = useAssetItemData({ bank, isInLendingMode });
const [mfiClient, fetchMrgnlendState] = useMrgnlendStore((state) => [state.marginfiClient, state.fetchMrgnlendState]);
const setIsRefreshingStore = useMrgnlendStore((state) => state.setIsRefreshingStore);
const { connected } = useWalletContext();
@@ -106,7 +106,7 @@ export const AssetCard: FC<{
isInLendingMode={isInLendingMode}
isBankFilled={isBankFilled}
isBankHigh={isBankHigh}
- bankFilled={bankFilled}
+ bankCap={bankCap}
/>
{bank.isActive && }
= ({
bank,
@@ -23,7 +23,7 @@ export const AssetCardStats: FC<{
userBalance,
isBankFilled,
isBankHigh,
- bankFilled,
+ bankCap,
isInLendingMode,
}) => {
return (
@@ -81,7 +81,7 @@ export const AssetCardStats: FC<{
{isBankHigh && (
{percentFormatterDyn.format(
- (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) / bankFilled
+ (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) / bankCap
) + " FILLED"}
)}
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
index 9eed63cc6e..40a7b35cd9 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
@@ -27,7 +27,6 @@ export const MobileAssetsList: FC = () => {
]);
const inputRefs = useRef>({});
const [isInLendingMode, setIsInLendingMode] = useState(true);
- const [isHotkeyMode, setIsHotkeyMode] = useState(false);
return (
<>
@@ -54,9 +53,6 @@ export const MobileAssetsList: FC = () => {
isConnected={connected}
marginfiAccount={selectedAccount}
inputRefs={inputRefs}
- hasHotkey={true}
- showHotkeyBadges={showBadges}
- badgeContent={`${i + 1}`}
/>
) : (
{
isConnected={connected}
marginfiAccount={selectedAccount}
inputRefs={inputRefs}
- hasHotkey={true}
- showHotkeyBadges={showBadges}
- badgeContent={`${i + 1}`}
/>
) : (
(isInLendingMode ? bank.info.rawBank.config.depositLimit : bank.info.rawBank.config.borrowLimit),
[isInLendingMode, bank.info.rawBank.config]
);
const isBankFilled = useMemo(
- () => (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) >= bankFilled * 0.99999,
- [bankFilled, isInLendingMode, bank.info.state]
+ () => (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) >= bankCap * 0.99999,
+ [bankCap, isInLendingMode, bank.info.state]
);
const isBankHigh = useMemo(
- () => (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) >= bankFilled * 0.9,
- [bankFilled, isInLendingMode, bank.info.state]
+ () => (isInLendingMode ? bank.info.state.totalDeposits : bank.info.state.totalBorrows) >= bankCap * 0.9,
+ [bankCap, isInLendingMode, bank.info.state]
);
- return { rateAP, assetWeight, bankFilled, isBankFilled, isBankHigh };
+ return { rateAP, assetWeight, bankCap, isBankFilled, isBankHigh };
}
diff --git a/apps/marginfi-v2-ui/src/pages/index.tsx b/apps/marginfi-v2-ui/src/pages/index.tsx
index aafa32e979..e67f71d5b3 100644
--- a/apps/marginfi-v2-ui/src/pages/index.tsx
+++ b/apps/marginfi-v2-ui/src/pages/index.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect } from "react";
+import React, { FC, useEffect } from "react";
import { Banner } from "~/components/desktop/Banner";
import { PageHeader } from "~/components/desktop/PageHeader";
import { useWalletContext } from "~/hooks/useWalletContext";
@@ -10,26 +10,49 @@ import { OverlaySpinner } from "~/components/desktop/OverlaySpinner";
import { useConnection } from "@solana/wallet-adapter-react";
import { Desktop, Mobile } from "~/mediaQueries";
-const DesktopAccountSummary = dynamic(
- async () => (await import("~/components/desktop/DesktopAccountSummary")).DesktopAccountSummary,
- {
- ssr: false,
- }
-);
-const MobileAccountSummary = dynamic(
- async () => (await import("~/components/mobile/MobileAccountSummary")).MobileAccountSummary,
- {
+const DesktopAccountSummary = () => {
+ const DesktopAccountSummary = dynamic(
+ async () => (await import("~/components/desktop/DesktopAccountSummary")).DesktopAccountSummary,
+ {
+ ssr: false,
+ }
+ );
+
+ return ;
+};
+
+const AssetsList = () => {
+ const AssetsList = dynamic(async () => (await import("~/components/desktop/AssetsList")).AssetsList, { ssr: false });
+ return ;
+};
+
+const UserPositions = () => {
+ const UserPositions = dynamic(async () => (await import("~/components/desktop/UserPositions")).UserPositions, {
ssr: false,
- }
-);
-const AssetsList = dynamic(async () => (await import("~/components/desktop/AssetsList")).AssetsList, { ssr: false });
-const MobileAssetsList = dynamic(async () => (await import("~/components/mobile/MobileAssetsList")).MobileAssetsList, {
- ssr: false,
-});
+ });
-const UserPositions = dynamic(async () => (await import("~/components/desktop/UserPositions")).UserPositions, {
- ssr: false,
-});
+ return ;
+};
+
+const MobileAccountSummary = () => {
+ const MobileAccountSummary = dynamic(
+ async () => (await import("~/components/mobile/MobileAccountSummary")).MobileAccountSummary,
+ {
+ ssr: false,
+ }
+ );
+ return ;
+};
+
+const MobileAssetsList = () => {
+ const MobileAssetsList = dynamic(
+ async () => (await import("~/components/mobile/MobileAssetsList")).MobileAssetsList,
+ {
+ ssr: false,
+ }
+ );
+ return ;
+};
const Home = () => {
const { walletAddress, wallet, isOverride } = useWalletContext();
@@ -89,7 +112,6 @@ const Home = () => {
{walletAddress && marginfiAccountCount > 1 && (
)}
-
@@ -105,6 +127,7 @@ const Home = () => {
+
>
);
diff --git a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx
index 69b6e95bfc..0ad2694268 100644
--- a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx
+++ b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx
@@ -154,7 +154,7 @@ export function PoolCard({
diff --git a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx
index 619564097e..860116b337 100644
--- a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx
+++ b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx
@@ -10,10 +10,10 @@ type Props = {
bank: ExtendedBankInfo;
nativeSolBalance: number;
isInLendingMode: boolean;
- bankFilled: number;
+ bankCap: number;
};
-export function PoolCardStats({ bank, isInLendingMode, nativeSolBalance, bankFilled }: Props) {
+export function PoolCardStats({ bank, isInLendingMode, nativeSolBalance, bankCap }: Props) {
const assetWeight = useMemo(() => {
if (bank.info.rawBank.config.assetWeightInit.toNumber() <= 0) {
return "-";
@@ -43,9 +43,9 @@ export function PoolCardStats({ bank, isInLendingMode, nativeSolBalance, bankFil
[bank, nativeSolBalance]
);
- const isFilled = useMemo(() => bankFilled >= 0.9999, [bankFilled]);
+ const isFilled = useMemo(() => bankCap >= 0.9999, [bankCap]);
- const isHigh = useMemo(() => bankFilled >= 0.9, [bankFilled]);
+ const isHigh = useMemo(() => bankCap >= 0.9, [bankCap]);
return (
@@ -57,9 +57,7 @@ export function PoolCardStats({ bank, isInLendingMode, nativeSolBalance, bankFil
{isInLendingMode ? "Deposits" : "Available"}
{bankAmount}
- {isHigh && (
- {percentFormatter.format(bankFilled)}
- )}
+ {isHigh && {percentFormatter.format(bankCap)} }
From 4954cc145cbad1ce3c8c7f8d34fd6d1c229cd959 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Sat, 9 Sep 2023 15:20:40 +0200
Subject: [PATCH 007/351] feat(mfi-v2-xnft): added icons & cleanup feature
---
apps/marginfi-v2-xnft/App.tsx | 7 +-
.../src/assets/icons/PieChartIcon.tsx | 16 ++++
.../src/assets/icons/ReceiveMoneyIcon.tsx | 19 ++++
.../src/assets/icons/TokenSwapIcon.tsx | 16 ++++
.../src/assets/icons/chevron-down.svg | 3 -
.../src/assets/icons/index.ts | 3 +
.../src/components/Lend/PoolCard/PoolCard.tsx | 46 +++++++++-
.../Lend/PoolCard/PoolCardActions.tsx | 31 +++----
.../Lend/PoolCard/PoolCardSkeleton.tsx | 2 +-
.../Lend/PoolCard/PoolCardStats.tsx | 2 +-
.../src/screens/LendScreen.tsx | 88 ++++++++++---------
11 files changed, 165 insertions(+), 68 deletions(-)
create mode 100644 apps/marginfi-v2-xnft/src/assets/icons/PieChartIcon.tsx
create mode 100644 apps/marginfi-v2-xnft/src/assets/icons/ReceiveMoneyIcon.tsx
create mode 100644 apps/marginfi-v2-xnft/src/assets/icons/TokenSwapIcon.tsx
delete mode 100644 apps/marginfi-v2-xnft/src/assets/icons/chevron-down.svg
diff --git a/apps/marginfi-v2-xnft/App.tsx b/apps/marginfi-v2-xnft/App.tsx
index 8b3921580b..d0f0da9d87 100644
--- a/apps/marginfi-v2-xnft/App.tsx
+++ b/apps/marginfi-v2-xnft/App.tsx
@@ -16,6 +16,7 @@ import { SwapContextProvider } from "~/context";
import { useConnection } from "~/hooks/useConnection";
import { useWallet } from "~/hooks/useWallet";
import { ROUTE_CACHE_DURATION } from "~/consts";
+import { PieChartIcon, ReceiveMoneyIcon, TokenSwapIcon } from "~/assets/icons";
require("~/styles/globals.css");
require("~/styles/fonts.css");
@@ -82,7 +83,7 @@ function TabNavigator() {
options={{
header: (props: BottomTabHeaderProps) => ,
tabBarLabel: "Lend",
- tabBarIcon: ({ color, size }) => ,
+ tabBarIcon: ({ color, size }) => ,
}}
/>
,
tabBarLabel: "Swap",
- tabBarIcon: ({ color, size }) => ,
+ tabBarIcon: ({ color, size }) => ,
}}
/>
,
tabBarLabel: "Portfolio",
- tabBarIcon: ({ color, size }) => ,
+ tabBarIcon: ({ color, size }) => ,
}}
/>
diff --git a/apps/marginfi-v2-xnft/src/assets/icons/PieChartIcon.tsx b/apps/marginfi-v2-xnft/src/assets/icons/PieChartIcon.tsx
new file mode 100644
index 0000000000..7d3c16a0e3
--- /dev/null
+++ b/apps/marginfi-v2-xnft/src/assets/icons/PieChartIcon.tsx
@@ -0,0 +1,16 @@
+import React from "react";
+
+interface PieChartIconProps extends React.SVGAttributes {
+ color?: string;
+}
+
+export const PieChartIcon: React.FC = ({ width = "24", height = "24", color = "white" }) => {
+ return (
+
+
+
+ );
+};
diff --git a/apps/marginfi-v2-xnft/src/assets/icons/ReceiveMoneyIcon.tsx b/apps/marginfi-v2-xnft/src/assets/icons/ReceiveMoneyIcon.tsx
new file mode 100644
index 0000000000..763a18e82a
--- /dev/null
+++ b/apps/marginfi-v2-xnft/src/assets/icons/ReceiveMoneyIcon.tsx
@@ -0,0 +1,19 @@
+import React from "react";
+
+interface ReceiveMoneyIconProps extends React.SVGAttributes {
+ color?: string;
+}
+
+export const ReceiveMoneyIcon: React.FC = ({ width = "24", height = "24", color = "black" }) => {
+ return (
+
+
+
+
+
+ );
+};
diff --git a/apps/marginfi-v2-xnft/src/assets/icons/TokenSwapIcon.tsx b/apps/marginfi-v2-xnft/src/assets/icons/TokenSwapIcon.tsx
new file mode 100644
index 0000000000..c83464147a
--- /dev/null
+++ b/apps/marginfi-v2-xnft/src/assets/icons/TokenSwapIcon.tsx
@@ -0,0 +1,16 @@
+import React from "react";
+
+interface TokenSwapIconProps extends React.SVGAttributes {
+ color?: string;
+}
+
+export const TokenSwapIcon: React.FC = ({ width = "24", height = "24", color = "black" }) => {
+ return (
+
+
+
+ );
+};
diff --git a/apps/marginfi-v2-xnft/src/assets/icons/chevron-down.svg b/apps/marginfi-v2-xnft/src/assets/icons/chevron-down.svg
deleted file mode 100644
index 1b95cdaf65..0000000000
--- a/apps/marginfi-v2-xnft/src/assets/icons/chevron-down.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/apps/marginfi-v2-xnft/src/assets/icons/index.ts b/apps/marginfi-v2-xnft/src/assets/icons/index.ts
index 36e9e1618e..abd3687121 100644
--- a/apps/marginfi-v2-xnft/src/assets/icons/index.ts
+++ b/apps/marginfi-v2-xnft/src/assets/icons/index.ts
@@ -11,3 +11,6 @@ export * from "./RefreshIcon";
export * from "./SettingsIcon";
export * from "./CloseIcon";
export * from "./ErrorIcon";
+export * from "./PieChartIcon";
+export * from "./ReceiveMoneyIcon";
+export * from "./TokenSwapIcon";
diff --git a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx
index 69b6e95bfc..88a72cff52 100644
--- a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx
+++ b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx
@@ -7,7 +7,7 @@ import { MarginfiAccountWrapper, MarginfiClient } from "@mrgnlabs/marginfi-clien
import { PoolCardPosition } from "./PoolCardPosition";
import { useConnection } from "~/hooks/useConnection";
import { ActionType, Emissions, ExtendedBankInfo, FEE_MARGIN, getCurrentAction } from "@mrgnlabs/marginfi-v2-ui-state";
-import { showErrorToast } from "~/utils";
+import { showErrorToast, showSuccessToast } from "~/utils";
import { percentFormatter, usdFormatter } from "@mrgnlabs/mrgn-common";
type Props = {
@@ -120,6 +120,8 @@ export function PoolCard({
const withdrawAll = bankInfo.isActive ? borrowOrLendAmount === bankInfo.position.amount : false;
await _marginfiAccount.withdraw(borrowOrLendAmount, bankInfo.address, withdrawAll);
}
+
+ showSuccessToast(`${currentAction + "ing"} ${borrowOrLendAmount} ${bankInfo.meta.tokenSymbol} 👍`);
} catch (error: any) {
console.log(`Error while ${currentAction + "ing"}`);
console.log(error);
@@ -136,8 +138,46 @@ export function PoolCard({
[bankInfo, connection, currentAction, marginfiAccount, marginfiClient, nativeSolBalance, reloadBanks]
);
+ const closeBalance = useCallback(async () => {
+ if (!marginfiAccount) {
+ showErrorToast("marginfi account not ready.");
+ return;
+ }
+
+ if (!bankInfo.isActive) {
+ showErrorToast("no position to close.");
+ return;
+ }
+
+ try {
+ if (bankInfo.position.isLending) {
+ await marginfiAccount.withdraw(0, bankInfo.address, true);
+ } else {
+ await marginfiAccount.repay(0, bankInfo.address, true);
+ }
+ showSuccessToast("Closing 👍");
+ } catch (error: any) {
+ showSuccessToast(`Error while closing balance: ${error.message}`);
+ console.log(`Error while closing balance`);
+ console.log(error);
+ }
+
+ // TODO: set values back to 0
+ try {
+ await reloadBanks();
+ } catch (error: any) {
+ console.log("Error while reloading state");
+ console.log(error);
+ }
+ }, [bankInfo, marginfiAccount, reloadBanks]);
+
return (
-
+
@@ -163,7 +203,7 @@ export function PoolCard({
currentAction={currentAction}
isBankFilled={isInLendingMode ? depositFilled >= 0.9999 : borrowFilled >= 0.9999}
bank={bankInfo}
- onAction={(amount) => borrowOrLend(amount)}
+ onAction={(amount) => (amount ? borrowOrLend(amount) : closeBalance())}
/>
);
diff --git a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardActions.tsx b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardActions.tsx
index 4546412ead..d2671d033f 100644
--- a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardActions.tsx
+++ b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardActions.tsx
@@ -3,12 +3,13 @@ import { View, Text, Pressable } from "react-native";
import tw from "~/styles/tailwind";
import { NumberInput, PrimaryButton, SecondaryButton } from "~/components/Common";
import { ActionType, ExtendedBankInfo } from "@mrgnlabs/marginfi-v2-ui-state";
+import { uiToNative } from "@mrgnlabs/mrgn-common";
type Props = {
currentAction: ActionType;
bank: ExtendedBankInfo;
isBankFilled: boolean;
- onAction: (amount: string) => void;
+ onAction: (amount?: string) => void;
};
export function PoolCardActions({ currentAction, bank, isBankFilled, onAction }: Props) {
@@ -27,20 +28,20 @@ export function PoolCardActions({ currentAction, bank, isBankFilled, onAction }:
}
}, [bank.userInfo, currentAction]);
- const isDisabled = useMemo(() => {
- switch (currentAction) {
- case ActionType.Deposit:
- return isBankFilled;
- case ActionType.Withdraw:
- return false;
- case ActionType.Borrow:
- return isBankFilled;
- case ActionType.Repay:
- return false;
- }
- }, [currentAction, isBankFilled]);
+ const isDust = useMemo(
+ () => bank.isActive && uiToNative(bank.position.amount, bank.info.state.mintDecimals).isZero(),
+ [bank]
+ );
+
+ const isDisabled = useMemo(
+ () =>
+ (isDust && uiToNative(bank.userInfo.tokenAccount.balance, bank.info.state.mintDecimals).isZero()) ||
+ maxAmount === 0,
+ [currentAction, bank, isDust, maxAmount]
+ );
const buttonText = useMemo(() => {
+ if (isDust) return "Close";
switch (currentAction) {
case ActionType.Deposit:
return isDisabled ? "Deposits reached the limit" : "Supply";
@@ -51,7 +52,7 @@ export function PoolCardActions({ currentAction, bank, isBankFilled, onAction }:
case ActionType.Repay:
return "Repay";
}
- }, [currentAction, isDisabled]);
+ }, [currentAction, isDisabled, isDust]);
return (
<>
@@ -72,7 +73,7 @@ export function PoolCardActions({ currentAction, bank, isBankFilled, onAction }:
{currentAction == ActionType.Withdraw || currentAction == ActionType.Repay ? (
- onAction(amount)} />
+ (isDust ? onAction() : onAction(amount))} />
) : (
onAction(amount)} />
)}
diff --git a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardSkeleton.tsx b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardSkeleton.tsx
index ca9d8e9a53..cae35f07d7 100644
--- a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardSkeleton.tsx
+++ b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardSkeleton.tsx
@@ -4,7 +4,7 @@ import { View } from "react-native";
import tw from "~/styles/tailwind";
export const PoolCardSkeleton = (props?: JSX.IntrinsicAttributes & IContentLoaderProps) => (
-
+
bankFilled >= 0.9, [bankFilled]);
return (
-
+
Weight
{assetWeight}
diff --git a/apps/marginfi-v2-xnft/src/screens/LendScreen.tsx b/apps/marginfi-v2-xnft/src/screens/LendScreen.tsx
index 7b95940b21..e1b967efd1 100644
--- a/apps/marginfi-v2-xnft/src/screens/LendScreen.tsx
+++ b/apps/marginfi-v2-xnft/src/screens/LendScreen.tsx
@@ -68,52 +68,56 @@ export function LendScreen() {
Filter my positions
Global pools
- {extendedBankInfos.length > 0 ? (
- globalPools.length > 0 ? (
- globalPools.map((extendedBankInfo, idx) => (
- {
- if (!connection) return;
- fetchMrgnlendState({ marginfiConfig: config.mfiConfig, connection, wallet });
- }}
- marginfiClient={marginfiClient}
- >
- ))
+ {/*
+ {extendedBankInfos.length > 0 ? (
+ globalPools.length > 0 ? (
+ globalPools.map((extendedBankInfo, idx) => (
+ {
+ if (!connection) return;
+ fetchMrgnlendState({ marginfiConfig: config.mfiConfig, connection, wallet });
+ }}
+ marginfiClient={marginfiClient}
+ >
+ ))
+ ) : (
+ No Global Pools Found
+ )
) : (
- No Global Pools Found
- )
- ) : (
-
- )}
+
+ )}
+ */}
Isolated pools
- {extendedBankInfos.length > 0 ? (
- isolatedPools.length > 0 ? (
- isolatedPools.map((extendedBankInfo, idx) => (
- {
- if (!connection) return;
- fetchMrgnlendState({ marginfiConfig: config.mfiConfig, connection, wallet });
- }}
- marginfiClient={marginfiClient}
- >
- ))
+ {/*
+ {extendedBankInfos.length > 0 ? (
+ isolatedPools.length > 0 ? (
+ isolatedPools.map((extendedBankInfo, idx) => (
+ {
+ if (!connection) return;
+ fetchMrgnlendState({ marginfiConfig: config.mfiConfig, connection, wallet });
+ }}
+ marginfiClient={marginfiClient}
+ >
+ ))
+ ) : (
+ No Isolated Pools Found
+ )
) : (
- No Isolated Pools Found
- )
- ) : (
-
- )}
+
+ )}
+ */}
From e6dd784f3f9075114edbf68e81efe5f4afdf3227 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Sat, 9 Sep 2023 16:32:41 +0200
Subject: [PATCH 008/351] feat(mfi-v2-ui): added navbar
---
apps/marginfi-v2-ui/public/pie_chart.svg | 1 +
apps/marginfi-v2-ui/public/receive_money.svg | 1 +
apps/marginfi-v2-ui/public/token_swap.svg | 1 +
.../Navbar}/WalletButton.tsx | 0
.../src/components/common/Navbar/index.ts | 1 +
.../desktop/DesktopNavbar/DesktopNavbar.tsx | 2 +-
.../mobile/DesktopNavbar/MobileNavbar.tsx | 76 -------------------
.../mobile/DesktopNavbar/WalletButton.tsx | 22 ------
.../AirdropZone.module.css | 0
.../AirdropZone.tsx | 0
.../MobileNavbar.module.css | 0
.../mobile/MobileNavbar/MobileNavbar.tsx | 69 +++++++++++++++++
.../{DesktopNavbar => MobileNavbar}/index.tsx | 0
apps/marginfi-v2-ui/src/pages/_app.tsx | 26 ++++---
apps/marginfi-v2-ui/src/pages/points.tsx | 2 +-
15 files changed, 92 insertions(+), 109 deletions(-)
create mode 100644 apps/marginfi-v2-ui/public/pie_chart.svg
create mode 100644 apps/marginfi-v2-ui/public/receive_money.svg
create mode 100644 apps/marginfi-v2-ui/public/token_swap.svg
rename apps/marginfi-v2-ui/src/components/{desktop/DesktopNavbar => common/Navbar}/WalletButton.tsx (100%)
create mode 100644 apps/marginfi-v2-ui/src/components/common/Navbar/index.ts
delete mode 100644 apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx
delete mode 100644 apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx
rename apps/marginfi-v2-ui/src/components/mobile/{DesktopNavbar => MobileNavbar}/AirdropZone.module.css (100%)
rename apps/marginfi-v2-ui/src/components/mobile/{DesktopNavbar => MobileNavbar}/AirdropZone.tsx (100%)
rename apps/marginfi-v2-ui/src/components/mobile/{DesktopNavbar => MobileNavbar}/MobileNavbar.module.css (100%)
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/MobileNavbar.tsx
rename apps/marginfi-v2-ui/src/components/mobile/{DesktopNavbar => MobileNavbar}/index.tsx (100%)
diff --git a/apps/marginfi-v2-ui/public/pie_chart.svg b/apps/marginfi-v2-ui/public/pie_chart.svg
new file mode 100644
index 0000000000..8027ee53c6
--- /dev/null
+++ b/apps/marginfi-v2-ui/public/pie_chart.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/marginfi-v2-ui/public/receive_money.svg b/apps/marginfi-v2-ui/public/receive_money.svg
new file mode 100644
index 0000000000..e660a612fa
--- /dev/null
+++ b/apps/marginfi-v2-ui/public/receive_money.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/marginfi-v2-ui/public/token_swap.svg b/apps/marginfi-v2-ui/public/token_swap.svg
new file mode 100644
index 0000000000..fc195a0ccd
--- /dev/null
+++ b/apps/marginfi-v2-ui/public/token_swap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/WalletButton.tsx b/apps/marginfi-v2-ui/src/components/common/Navbar/WalletButton.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/WalletButton.tsx
rename to apps/marginfi-v2-ui/src/components/common/Navbar/WalletButton.tsx
diff --git a/apps/marginfi-v2-ui/src/components/common/Navbar/index.ts b/apps/marginfi-v2-ui/src/components/common/Navbar/index.ts
new file mode 100644
index 0000000000..778aed6c06
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/common/Navbar/index.ts
@@ -0,0 +1 @@
+export * from "./WalletButton";
diff --git a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
index c5da39f773..b8439d7f0b 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
@@ -2,7 +2,7 @@ import { FC, useEffect, useState } from "react";
import Link from "next/link";
import Image from "next/image";
import AirdropZone from "./AirdropZone";
-import { WalletButton } from "./WalletButton";
+import { WalletButton } from "~/components/common/Navbar";
import { useHotkeys } from "react-hotkeys-hook";
import { useMrgnlendStore, useUserProfileStore } from "~/store";
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx
deleted file mode 100644
index 947e008c87..0000000000
--- a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import { FC, useEffect } from "react";
-import Link from "next/link";
-import Image from "next/image";
-import AirdropZone from "./AirdropZone";
-import { useUserProfileStore } from "~/store";
-import { useRouter } from "next/router";
-import { useFirebaseAccount } from "~/hooks/useFirebaseAccount";
-import { useWalletContext } from "~/hooks/useWalletContext";
-
-// @todo implement second pretty navbar row
-const MobileNavbar: FC = () => {
- useFirebaseAccount();
-
- const { connected, walletAddress } = useWalletContext();
- const router = useRouter();
- const [fetchPoints] = useUserProfileStore((state) => [state.fetchPoints]);
-
- useEffect(() => {
- if (!walletAddress) return;
- fetchPoints(walletAddress.toBase58()).catch(console.error);
- }, [fetchPoints, walletAddress]);
-
- return (
-
-
-
-
-
-
-
-
- lend
-
-
-
- swap
-
-
- bridge
-
-
-
- earn
-
-
-
- omni
-
- {process.env.NEXT_PUBLIC_MARGINFI_FEATURES_AIRDROP === "true" && connected &&
}
-
-
-
-
- );
-};
-
-export { MobileNavbar };
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx b/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx
deleted file mode 100644
index e0811cd095..0000000000
--- a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/WalletButton.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import dynamic from "next/dynamic";
-import { FC } from "react";
-import { useWalletContext } from "~/hooks/useWalletContext";
-
-const WalletMultiButtonDynamic = dynamic(
- async () => (await import("@solana/wallet-adapter-react-ui")).WalletMultiButton,
- { ssr: false }
-);
-
-const WalletButton: FC = () => {
- const { connected } = useWalletContext();
-
- return (
-
-
- {!connected && CONNECT
}
-
-
- );
-};
-
-export { WalletButton };
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.module.css b/apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/AirdropZone.module.css
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.module.css
rename to apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/AirdropZone.module.css
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/AirdropZone.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/AirdropZone.tsx
rename to apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/AirdropZone.tsx
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.module.css b/apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/MobileNavbar.module.css
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/MobileNavbar.module.css
rename to apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/MobileNavbar.module.css
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/MobileNavbar.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/MobileNavbar.tsx
new file mode 100644
index 0000000000..f2b3d9da95
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/MobileNavbar.tsx
@@ -0,0 +1,69 @@
+import { FC, useEffect } from "react";
+import Link from "next/link";
+import Image from "next/image";
+import AirdropZone from "./AirdropZone";
+import { useUserProfileStore } from "~/store";
+import { useRouter } from "next/router";
+import { useFirebaseAccount } from "~/hooks/useFirebaseAccount";
+import { useWalletContext } from "~/hooks/useWalletContext";
+
+// @todo implement second pretty navbar row
+const MobileNavbar: FC = () => {
+ useFirebaseAccount();
+
+ const { connected, walletAddress } = useWalletContext();
+ const router = useRouter();
+ const [fetchPoints] = useUserProfileStore((state) => [state.fetchPoints]);
+
+ useEffect(() => {
+ if (!walletAddress) return;
+ fetchPoints(walletAddress.toBase58()).catch(console.error);
+ }, [fetchPoints, walletAddress]);
+
+ return (
+
+
+
+
+
+ lend
+
+
+
+
+ swap
+
+
+
+ bridge
+
+
+ {/*
+ earn
+
+
+
+ omni
+ */}
+ {/* {process.env.NEXT_PUBLIC_MARGINFI_FEATURES_AIRDROP === "true" && connected &&
} */}
+
+
+
+ );
+};
+
+export { MobileNavbar };
diff --git a/apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/index.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/index.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/mobile/DesktopNavbar/index.tsx
rename to apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/index.tsx
diff --git a/apps/marginfi-v2-ui/src/pages/_app.tsx b/apps/marginfi-v2-ui/src/pages/_app.tsx
index ac0fcccf6f..30be73c899 100644
--- a/apps/marginfi-v2-ui/src/pages/_app.tsx
+++ b/apps/marginfi-v2-ui/src/pages/_app.tsx
@@ -18,9 +18,9 @@ import "react-toastify/dist/ReactToastify.min.css";
import { ToastContainer } from "react-toastify";
import { Analytics } from "@vercel/analytics/react";
import dynamic from "next/dynamic";
-import { Desk } from "@mui/icons-material";
import { Desktop, Mobile } from "~/mediaQueries";
-import { MobileNavbar } from "~/components/mobile/DesktopNavbar";
+import { MobileNavbar } from "~/components/mobile/MobileNavbar";
+import { WalletButton } from "~/components/common/Navbar";
// Use require instead of import since order matters
require("@solana/wallet-adapter-react-ui/styles.css");
@@ -28,7 +28,9 @@ require("~/styles/globals.css");
require("~/styles/fonts.css");
require("~/styles/asset-borders.css");
-const DesktopNavbar = dynamic(async () => (await import("~/components/desktop/DesktopNavbar")).DesktopNavbar, { ssr: false });
+const DesktopNavbar = dynamic(async () => (await import("~/components/desktop/DesktopNavbar")).DesktopNavbar, {
+ ssr: false,
+});
const Footer = dynamic(async () => (await import("~/components/desktop/Footer")).Footer, { ssr: false });
// Matomo
@@ -68,16 +70,22 @@ const MyApp = ({ Component, pageProps }: AppProps) => {
+
+
+
+
+
+
-
-
-
diff --git a/apps/marginfi-v2-ui/src/pages/points.tsx b/apps/marginfi-v2-ui/src/pages/points.tsx
index f33ad4cf50..34f2b8493f 100644
--- a/apps/marginfi-v2-ui/src/pages/points.tsx
+++ b/apps/marginfi-v2-ui/src/pages/points.tsx
@@ -25,7 +25,7 @@ import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
import { styled } from "@mui/material/styles";
import Image from "next/image";
import { useRouter } from "next/router";
-import { WalletButton } from "~/components/desktop/DesktopNavbar/WalletButton";
+import { WalletButton } from "~/components/common/Navbar";
import { grey } from "@mui/material/colors";
import { toast } from "react-toastify";
import { useUserProfileStore } from "~/store";
From 4873ab5717f9350331fe89b3838d41dcde48fbd1 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Sat, 9 Sep 2023 16:39:15 +0200
Subject: [PATCH 009/351] fix(mfi-v2-ui): build error
---
.../MobileAssetsList/AssetCard/AssetCard.tsx | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
index 1c9640b099..764c638a55 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
@@ -22,19 +22,7 @@ export const AssetCard: FC<{
isConnected: boolean;
marginfiAccount: MarginfiAccountWrapper | null;
inputRefs: React.MutableRefObject>;
- hasHotkey: boolean;
- showHotkeyBadges?: boolean;
- badgeContent?: string;
-}> = ({
- bank,
- nativeSolBalance,
- isInLendingMode,
- marginfiAccount,
- inputRefs,
- hasHotkey,
- showHotkeyBadges,
- badgeContent,
-}) => {
+}> = ({ bank, nativeSolBalance, isInLendingMode, marginfiAccount, inputRefs }) => {
const { rateAP, assetWeight, isBankFilled, isBankHigh, bankCap } = useAssetItemData({ bank, isInLendingMode });
const [mfiClient, fetchMrgnlendState] = useMrgnlendStore((state) => [state.marginfiClient, state.fetchMrgnlendState]);
const setIsRefreshingStore = useMrgnlendStore((state) => state.setIsRefreshingStore);
From 67df5be3970e3d46004975f68ad5052449295ce1 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Sat, 9 Sep 2023 16:54:15 +0200
Subject: [PATCH 010/351] fix(mfi-v2-ui): removed commented code
---
apps/marginfi-v2-xnft/src/screens/LendScreen.tsx | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/apps/marginfi-v2-xnft/src/screens/LendScreen.tsx b/apps/marginfi-v2-xnft/src/screens/LendScreen.tsx
index e1b967efd1..f8c4b18714 100644
--- a/apps/marginfi-v2-xnft/src/screens/LendScreen.tsx
+++ b/apps/marginfi-v2-xnft/src/screens/LendScreen.tsx
@@ -68,7 +68,7 @@ export function LendScreen() {
Filter my positions
Global pools
- {/*
+
{extendedBankInfos.length > 0 ? (
globalPools.length > 0 ? (
globalPools.map((extendedBankInfo, idx) => (
@@ -91,10 +91,10 @@ export function LendScreen() {
) : (
)}
- */}
+
Isolated pools
- {/*
+
{extendedBankInfos.length > 0 ? (
isolatedPools.length > 0 ? (
isolatedPools.map((extendedBankInfo, idx) => (
@@ -117,7 +117,7 @@ export function LendScreen() {
) : (
)}
- */}
+
From 57e68c9e9ec0d62935816b45abdfe040b7b06b73 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Sun, 10 Sep 2023 10:29:35 +0200
Subject: [PATCH 011/351] fix(mfi-v2-ui): small layout fix
---
apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx b/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx
index 57dc641432..f83c60639b 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx
@@ -6,7 +6,7 @@ interface PageHeaderProps {
const PageHeader: FC = ({ text = "mrgnlend" }) => {
return (
-
+
= ({ text = "mrgnlend" }) => {
const PageHeaderSwap: FC = () => {
return (
-
+
{
const PageHeaderBridge: FC = () => {
return (
-
+
Date: Sun, 10 Sep 2023 14:25:31 +0200
Subject: [PATCH 012/351] fix(mfi-v2-ui): changed bankcap name
---
.../src/components/Lend/PoolCard/PoolCardStats.tsx | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx
index 860116b337..970e95465a 100644
--- a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx
+++ b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCardStats.tsx
@@ -10,10 +10,10 @@ type Props = {
bank: ExtendedBankInfo;
nativeSolBalance: number;
isInLendingMode: boolean;
- bankCap: number;
+ bankFilledPercentage: number;
};
-export function PoolCardStats({ bank, isInLendingMode, nativeSolBalance, bankCap }: Props) {
+export function PoolCardStats({ bank, isInLendingMode, nativeSolBalance, bankFilledPercentage }: Props) {
const assetWeight = useMemo(() => {
if (bank.info.rawBank.config.assetWeightInit.toNumber() <= 0) {
return "-";
@@ -43,9 +43,9 @@ export function PoolCardStats({ bank, isInLendingMode, nativeSolBalance, bankCap
[bank, nativeSolBalance]
);
- const isFilled = useMemo(() => bankCap >= 0.9999, [bankCap]);
+ const isFilled = useMemo(() => bankFilledPercentage >= 0.9999, [bankFilledPercentage]);
- const isHigh = useMemo(() => bankCap >= 0.9, [bankCap]);
+ const isHigh = useMemo(() => bankFilledPercentage >= 0.9, [bankFilledPercentage]);
return (
@@ -57,7 +57,11 @@ export function PoolCardStats({ bank, isInLendingMode, nativeSolBalance, bankCap
{isInLendingMode ? "Deposits" : "Available"}
{bankAmount}
- {isHigh && {percentFormatter.format(bankCap)} }
+ {isHigh && (
+
+ {percentFormatter.format(bankFilledPercentage)}
+
+ )}
From bc61ab324fc5f69145a408a3948fbb73c28f0519 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Sun, 10 Sep 2023 14:52:18 +0200
Subject: [PATCH 013/351] fix(mfi-v2-xnft): forgot to save a file
---
apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx
index 0ad2694268..fbf0dedf1c 100644
--- a/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx
+++ b/apps/marginfi-v2-xnft/src/components/Lend/PoolCard/PoolCard.tsx
@@ -154,7 +154,7 @@ export function PoolCard({
From 37b142380d9c97821d459e098365ff683bb819a0 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Sun, 10 Sep 2023 17:48:34 +0200
Subject: [PATCH 014/351] feat(mfi-v2-ui): WIP porfolio page
---
.../MobilePortfolioOverview.tsx | 104 +++++++++++++++++
.../SemiCircleProgress.tsx | 108 ++++++++++++++++++
apps/marginfi-v2-ui/src/pages/portfolio.tsx | 18 +++
3 files changed, 230 insertions(+)
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
create mode 100644 apps/marginfi-v2-ui/src/pages/portfolio.tsx
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
new file mode 100644
index 0000000000..6035d24d0c
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
@@ -0,0 +1,104 @@
+import { FC, useEffect, useMemo } from "react";
+import Link from "next/link";
+import Image from "next/image";
+import { useMrgnlendStore, useUserProfileStore } from "~/store";
+import { useRouter } from "next/router";
+import { useFirebaseAccount } from "~/hooks/useFirebaseAccount";
+import { useWalletContext } from "~/hooks/useWalletContext";
+
+import { MarginRequirementType, MarginfiAccountWrapper } from "@mrgnlabs/marginfi-client-v2";
+import { AccountSummary, UserPointsData } from "@mrgnlabs/marginfi-v2-ui-state";
+import { usdFormatterDyn, usdFormatter, groupedNumberFormatterDyn } from "@mrgnlabs/mrgn-common";
+import { SemiCircleProgress } from "./SemiCircleProgress";
+
+// @todo implement second pretty navbar row
+export const MobilePortfolioOverview: FC = () => {
+ const [
+ marginfiClient,
+ fetchMrgnlendState,
+ selectedAccount,
+ accountSummary,
+ extendedBankInfos,
+ nativeSolBalance,
+ protocolStats,
+ ] = useMrgnlendStore((state) => [
+ state.marginfiClient,
+ state.fetchMrgnlendState,
+ state.selectedAccount,
+ state.accountSummary,
+ state.extendedBankInfos,
+ state.nativeSolBalance,
+ state.protocolStats,
+ ]);
+
+ const [userPointsData, currentFirebaseUser] = useUserProfileStore((state) => [
+ state.userPointsData,
+ state.currentFirebaseUser,
+ ]);
+
+ const healthFactor = useMemo(() => {
+ if (selectedAccount) {
+ const { assets, liabilities } = selectedAccount.computeHealthComponents(MarginRequirementType.Maintenance);
+ return assets.isZero() ? 100 : assets.minus(liabilities).dividedBy(assets).toNumber() * 100;
+ } else {
+ return null;
+ }
+ }, [selectedAccount]);
+
+ const labelStyle = `text-sm font-normal text-[#868E95]`;
+ const valueStyle = `text-xl font-bold text-[#FFF]`;
+
+ return (
+
+
Your overview
+
+
+
+
+
Supplied
+
+ {accountSummary &&
+ (Math.round(accountSummary.lendingAmountUnbiased) > 10000
+ ? usdFormatterDyn.format(Math.round(accountSummary.lendingAmountUnbiased))
+ : usdFormatter.format(accountSummary.lendingAmountUnbiased))}
+
+
+
+
Borrowed
+
+ {accountSummary &&
+ (Math.round(accountSummary.borrowingAmountUnbiased) > 10000
+ ? usdFormatterDyn.format(Math.round(accountSummary.borrowingAmountUnbiased))
+ : usdFormatter.format(accountSummary.borrowingAmountUnbiased))}
+
+
+
+
+
+
Free Collateral
+
+ {accountSummary && usdFormatter.format(accountSummary.signedFreeCollateral)}
+
+
+
+
Points
+
+ {!!currentFirebaseUser
+ ? `${groupedNumberFormatterDyn.format(Math.round(userPointsData.totalPoints))} points`
+ : "P...P...POINTS!"}
+
+
+
+ {/*
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
new file mode 100644
index 0000000000..e13f6db044
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
@@ -0,0 +1,108 @@
+import { keyframes } from "@emotion/react";
+import styled from "@emotion/styled";
+import { percentFormatter } from "@mrgnlabs/mrgn-common";
+import React, { useEffect, useRef, useState } from "react";
+
+type Props = {
+ amount: number;
+};
+
+export const SemiCircleProgress = ({}: Props) => {
+ const amount = 10;
+ const rotationAnimation = useRef(null);
+ const [progressColor, setProgressColor] = useState
("#75BA80");
+
+ useEffect(() => {
+ if (amount) {
+ let color;
+
+ if (amount >= 50) {
+ color = "#75ba80"; // green color
+ } else if (amount >= 25) {
+ color = "#FABD12"; // yellow color
+ } else {
+ color = "#E06D6F"; // red color
+ }
+
+ setProgressColor(color);
+ }
+ }, [amount]);
+
+ const rotateAnimation = keyframes`
+ 0% {
+ transform: translateY(-50px) rotate(0deg) translateY(50px);
+ }
+ 100% {
+ transform: translateY(-50px) rotate(${(amount / 100) * 180}deg) translateY(50px);
+ }
+ `;
+
+ const SemiCircleWrapper = styled.div({
+ position: "relative",
+ ".exteriorCircle": {
+ position: "relative",
+ width: "200px",
+ height: "100px",
+ borderRadius: "100px",
+ backgroundColor: "#3D3D3D",
+ borderBottomLeftRadius: "0",
+ borderBottomRightRadius: "0",
+ alignItems: "center",
+ overflow: "hidden",
+ },
+
+ ".interiorCircle": {
+ position: "relative",
+ width: "180px",
+ height: "90px",
+ borderRadius: "90px",
+ backgroundColor: "#1C2023",
+ top: "10px",
+ marginLeft: "auto",
+ marginRight: "auto",
+ borderBottomLeftRadius: "0",
+ borderBottomRightRadius: "0",
+ alignItems: "center",
+ overflow: "hidden",
+ },
+
+ ".healthLabel": {},
+
+ ".rotatingCircleWrap": {
+ position: "absolute",
+ backgroundColor: "#1C2023",
+ left: "0px",
+ width: "200px",
+ height: "100px",
+ top: "100px",
+ },
+
+ ".rotatingCircle": {
+ // position: "absolute",
+ overflow: "hidden",
+ top: "0px",
+ left: "0px",
+ borderRadius: "100px",
+ borderTopLeftRadius: "0px",
+ borderTopRightRadius: "0px",
+ width: "200px",
+ height: "100px",
+ backgroundColor: progressColor,
+ animation: rotateAnimation,
+ animationDuration: "1s",
+ transform: `translateY(-50px) rotate(${(amount / 100) * 180}deg) translateY(50px)`,
+ },
+ });
+
+ return (
+
+
+
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/pages/portfolio.tsx b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
new file mode 100644
index 0000000000..51adc27d58
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
@@ -0,0 +1,18 @@
+import { useEffect } from "react";
+import config from "~/config";
+import { PageHeaderSwap } from "~/components/desktop/PageHeader";
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { MobilePortfolioOverview } from "~/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview";
+
+const PortfolioPage = () => {
+ return (
+ <>
+
+
+
+
+ >
+ );
+};
+
+export default PortfolioPage;
From b5cd0d4fb33869a54bc55c8a1e5a7c37576da45e Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Mon, 11 Sep 2023 13:55:26 +0200
Subject: [PATCH 015/351] feat(mfi-v2-ui): Point page restructuring
---
.../desktop/Points/PointsCheckingUser.tsx | 24 +
.../desktop/Points/PointsConnectWallet.tsx | 25 +
.../desktop/Points/PointsLeaderBoard.tsx | 154 +++++
.../desktop/Points/PointsOverview.tsx | 155 +++++
.../desktop/Points/PointsSignIn.tsx | 95 +++
.../desktop/Points/PointsSignUp.tsx | 125 ++++
.../src/components/desktop/Points/index.ts | 6 +
.../MobileAccountSummary.tsx | 6 +-
.../MobilePortfolioOverview.tsx | 69 ++-
.../SemiCircleProgress.tsx | 32 +-
apps/marginfi-v2-ui/src/pages/index.tsx | 4 +-
apps/marginfi-v2-ui/src/pages/points.tsx | 564 +-----------------
apps/marginfi-v2-ui/src/pages/portfolio.tsx | 43 +-
13 files changed, 717 insertions(+), 585 deletions(-)
create mode 100644 apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/desktop/Points/PointsLeaderBoard.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignUp.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/desktop/Points/index.ts
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx
new file mode 100644
index 0000000000..aca30f0962
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx
@@ -0,0 +1,24 @@
+import React, { FC } from "react";
+import { Card, CardContent, CircularProgress } from "@mui/material";
+
+interface PointsCheckingUserProps {}
+
+export const PointsCheckingUser: FC = ({}) => {
+ return (
+
+
+
+
+ Access upgraded features
+
+
+
+
+
+
+
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx
new file mode 100644
index 0000000000..0ed8b4afb5
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx
@@ -0,0 +1,25 @@
+import React, { FC } from "react";
+import { Card, CardContent } from "@mui/material";
+
+import { WalletButton } from "~/components/common/Navbar";
+
+interface PointsConnectWalletProps {}
+
+export const PointsConnectWallet: FC = ({}) => {
+ return (
+
+
+
+
+ Access upgraded features
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsLeaderBoard.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsLeaderBoard.tsx
new file mode 100644
index 0000000000..3d6ecd7d56
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsLeaderBoard.tsx
@@ -0,0 +1,154 @@
+import React, { FC } from "react";
+import { Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from "@mui/material";
+
+import { groupedNumberFormatterDyn } from "@mrgnlabs/mrgn-common";
+import { LeaderboardRow } from "@mrgnlabs/marginfi-v2-ui-state";
+
+interface PointsLeaderBoardProps {
+ leaderboardData: LeaderboardRow[];
+ currentUserId: string;
+}
+
+export const PointsLeaderBoard: FC = ({ leaderboardData, currentUserId }) => {
+ return (
+
+
+
+
+
+ Rank
+
+
+ User
+
+
+ Lending Points
+
+
+ Borrowing Points
+
+
+ Referral Points
+
+
+ Social Points
+
+
+ Total Points
+
+
+
+
+ {leaderboardData.map((row: LeaderboardRow, index: number) => (
+
+
+ {index === 0 ? "🥇" : index === 1 ? "🥈" : index === 2 ? "🥉" : index + 1}
+
+
+
+ {`${row.id.slice(0, 5)}...${row.id.slice(-5)}`}
+
+
+
+
+ {groupedNumberFormatterDyn.format(Math.round(row.total_activity_deposit_points))}
+
+
+ {groupedNumberFormatterDyn.format(Math.round(row.total_activity_borrow_points))}
+
+
+ {groupedNumberFormatterDyn.format(
+ Math.round(row.total_referral_deposit_points + row.total_referral_borrow_points)
+ )}
+
+
+ {groupedNumberFormatterDyn.format(Math.round(row.socialPoints ? row.socialPoints : 0))}
+
+
+ {groupedNumberFormatterDyn.format(
+ Math.round(
+ row.total_deposit_points + row.total_borrow_points + (row.socialPoints ? row.socialPoints : 0)
+ )
+ )}
+
+
+ ))}
+
+
+
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx
new file mode 100644
index 0000000000..350fee3bd1
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx
@@ -0,0 +1,155 @@
+import Image from "next/image";
+import { MarginfiAccountWrapper } from "@mrgnlabs/marginfi-client-v2";
+import { Card, CardContent, Skeleton, TableCell, TableRow, Typography } from "@mui/material";
+import React, { FC, useCallback, useMemo, useState } from "react";
+import { toast } from "react-toastify";
+import {
+ groupedNumberFormatter,
+ uiToNative,
+ usdFormatter,
+ numeralFormatter,
+ groupedNumberFormatterDyn,
+} from "@mrgnlabs/mrgn-common";
+import { MrgnTooltip } from "~/components/common/MrgnTooltip";
+import { AccountSummary, UserPointsData } from "@mrgnlabs/marginfi-v2-ui-state";
+
+interface PointsLeaderBoardProps {
+ userPointsData: UserPointsData;
+}
+
+export const PointsOverview: FC = ({ userPointsData }) => {
+ return (
+ <>
+
+
+
+
+ Total Points
+
+
+
+ Points
+
+ Points refresh every 24 hours.
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+
+ {userPointsData.totalPoints > 0 ? (
+ numeralFormatter(userPointsData.totalPoints)
+ ) : (
+
+ )}
+
+
+
+
+
+
+ Global Rank {/* TODO: fix that with dedicated query */}
+
+
+ {userPointsData.userRank && userPointsData.userRank > 0 ? (
+ `#${groupedNumberFormatterDyn.format(userPointsData.userRank)}`
+ ) : (
+
+ )}
+
+
+
+
+
+
+
+
+ Lending Points
+
+
+
+ Lending
+
+ Lending earns 1 point per dollar lent per day.
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+
+ {userPointsData.depositPoints > 0 ? (
+ numeralFormatter(userPointsData.depositPoints)
+ ) : (
+
+ )}
+
+
+
+
+
+
+ Borrowing Points
+
+
+
+ Borrowing
+
+ Borrowing earns 4 points per dollar borrowed per day.
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+
+ {userPointsData.borrowPoints > 0 ? (
+ numeralFormatter(userPointsData.borrowPoints)
+ ) : (
+
+ )}
+
+
+
+
+
+
+ Referral Points
+
+
+
+ Earn more with friends
+
+ Earn 10% of the points any user you refer earns.
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+
+ {userPointsData.referralPoints > 0 ? numeralFormatter(userPointsData.referralPoints) : "-"}
+
+
+
+
+ >
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx
new file mode 100644
index 0000000000..517a06b7e4
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx
@@ -0,0 +1,95 @@
+import React, { useCallback, FC, useState } from "react";
+import Image from "next/image";
+import { Button, Card, CardContent, Checkbox } from "@mui/material";
+import { useConnection } from "@solana/wallet-adapter-react";
+import { grey } from "@mui/material/colors";
+import { toast } from "react-toastify";
+
+import { firebaseApi } from "@mrgnlabs/marginfi-v2-ui-state";
+
+import { WalletButton } from "~/components/common/Navbar";
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { MrgnTooltip } from "~/components/common/MrgnTooltip";
+
+interface PointsSignInProps {}
+
+export const PointsSignIn: FC = ({}) => {
+ const { connection } = useConnection();
+ const { walletContextState, connected } = useWalletContext();
+ const [useAuthTx, setUseAuthTx] = useState(false);
+ const login = useCallback(async () => {
+ toast.info("Logging in...");
+ const blockhashInfo = await connection.getLatestBlockhash();
+ try {
+ await firebaseApi.login(walletContextState, useAuthTx ? "tx" : "memo", blockhashInfo);
+ // localStorage.setItem("authData", JSON.stringify(signedAuthData));
+ toast.success("Logged in successfully");
+ } catch (loginError: any) {
+ toast.error(loginError.message);
+ }
+ }, [connection, useAuthTx, walletContextState]);
+
+ return (
+
+
+
+
+ Access upgraded features
+
+
+ Login to your points account by signing a message.
+
+
+ {connected ? (
+
+
setUseAuthTx((current) => !current)}
+ >
+
+
Use tx signing
+
+
+ Certain hardware wallet versions do not support memo signing.
+
+
+ Use this option if you are unable to proceed with memo signing. It is free as well and will
+ not involve the network.
+
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+ Login
+
+
+ ) : (
+
+ )}
+
+
+
+
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignUp.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignUp.tsx
new file mode 100644
index 0000000000..a9559a003e
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignUp.tsx
@@ -0,0 +1,125 @@
+import React, { FC, useEffect, useState, useCallback, useMemo } from "react";
+import Image from "next/image";
+import { Button, Card, CardContent, TextField, Checkbox } from "@mui/material";
+import { useConnection } from "@solana/wallet-adapter-react";
+import { grey } from "@mui/material/colors";
+import { toast } from "react-toastify";
+
+import { firebaseApi } from "@mrgnlabs/marginfi-v2-ui-state";
+
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { MrgnTooltip } from "~/components/common/MrgnTooltip";
+import { WalletButton } from "~/components/common/Navbar";
+
+interface PointsSignUpProps {
+ referralCode?: string;
+}
+
+export const PointsSignUp: FC = ({ referralCode }) => {
+ const { connection } = useConnection();
+ const { walletContextState, connected } = useWalletContext();
+ const [manualCode, setManualCode] = useState("");
+ const [useAuthTx, setUseAuthTx] = useState(false);
+ const [useManualCode, setUseManualCode] = useState(false);
+
+ const finalReferralCode = useMemo(
+ () => (useManualCode ? manualCode : referralCode),
+ [useManualCode, manualCode, referralCode]
+ );
+
+ useEffect(() => {
+ if (manualCode.length > 0) {
+ setUseManualCode((current) => current || true);
+ }
+ }, [manualCode]);
+
+ const signup = useCallback(async () => {
+ toast.info("Logging in...");
+ const blockhashInfo = await connection.getLatestBlockhash();
+ try {
+ await firebaseApi.signup(walletContextState, useAuthTx ? "tx" : "memo", blockhashInfo, finalReferralCode);
+ // localStorage.setItem("authData", JSON.stringify(signedAuthData));
+ toast.success("Signed up successfully");
+ } catch (signupError: any) {
+ toast.error(signupError.message);
+ }
+ }, [connection, finalReferralCode, useAuthTx, walletContextState]);
+
+ return (
+
+
+
+
+ Access upgraded features
+
+
+ Prove you own this wallet by signing a message.
+
+ Optionally enter a referral code below.
+
+
+ {connected ? (
+
+
{
+ setManualCode(event.target.value);
+ }}
+ />
+ setUseAuthTx((current) => !current)}
+ >
+
+
Use tx signing
+
+
+ Certain hardware wallet versions do not support memo signing.
+
+
+ Use this option if you are unable to proceed with memo signing. It is free as well and will
+ not involve the network.
+
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+ Signup
+
+
+ ) : (
+
+ )}
+
+
+
+
+ );
+};
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/index.ts b/apps/marginfi-v2-ui/src/components/desktop/Points/index.ts
new file mode 100644
index 0000000000..14a637879c
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/index.ts
@@ -0,0 +1,6 @@
+export * from "./PointsOverview";
+export * from "./PointsLeaderBoard";
+export * from "./PointsSignIn";
+export * from "./PointsSignUp";
+export * from "./PointsCheckingUser";
+export * from "./PointsConnectWallet";
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
index c97597934d..a7ab7fac41 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
@@ -22,7 +22,7 @@ const AccountSummary: FC = () => {
- Global stats
+ {/* Global stats */}
{
{" "}
-
+ {/*
{connected && (
Your account
@@ -42,7 +42,7 @@ const AccountSummary: FC = () => {
/>
)}
-
+
*/}
);
};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
index 6035d24d0c..4987bc4d38 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
@@ -10,6 +10,8 @@ import { MarginRequirementType, MarginfiAccountWrapper } from "@mrgnlabs/marginf
import { AccountSummary, UserPointsData } from "@mrgnlabs/marginfi-v2-ui-state";
import { usdFormatterDyn, usdFormatter, groupedNumberFormatterDyn } from "@mrgnlabs/mrgn-common";
import { SemiCircleProgress } from "./SemiCircleProgress";
+import { useConnection, useWallet } from "@solana/wallet-adapter-react";
+import { Typography } from "@mui/material";
// @todo implement second pretty navbar row
export const MobilePortfolioOverview: FC = () => {
@@ -30,12 +32,24 @@ export const MobilePortfolioOverview: FC = () => {
state.nativeSolBalance,
state.protocolStats,
]);
+ const { wallet } = useWallet();
+ const connection = useConnection();
+
+ useEffect(() => {
+ fetchMrgnlendState();
+ const id = setInterval(() => fetchMrgnlendState().catch(console.error), 30_000);
+ return () => clearInterval(id);
+ }, [wallet]); // eslint-disable-line react-hooks/exhaustive-deps
+ // ^ crucial to omit both `connection` and `fetchMrgnlendState` from the dependency array
+ // TODO: fix...
const [userPointsData, currentFirebaseUser] = useUserProfileStore((state) => [
state.userPointsData,
state.currentFirebaseUser,
]);
+ console.log({ selectedAccount });
+
const healthFactor = useMemo(() => {
if (selectedAccount) {
const { assets, liabilities } = selectedAccount.computeHealthComponents(MarginRequirementType.Maintenance);
@@ -45,59 +59,58 @@ export const MobilePortfolioOverview: FC = () => {
}
}, [selectedAccount]);
- const labelStyle = `text-sm font-normal text-[#868E95]`;
- const valueStyle = `text-xl font-bold text-[#FFF]`;
-
return (
-
-
Your overview
-
-
Health factor
+
+
Your overview
+
-
-
+
+
-
Supplied
-
+
+ Supplied
+
+
{accountSummary &&
(Math.round(accountSummary.lendingAmountUnbiased) > 10000
? usdFormatterDyn.format(Math.round(accountSummary.lendingAmountUnbiased))
: usdFormatter.format(accountSummary.lendingAmountUnbiased))}
-
+
-
Borrowed
-
+
+ Borrowed
+
+
{accountSummary &&
(Math.round(accountSummary.borrowingAmountUnbiased) > 10000
? usdFormatterDyn.format(Math.round(accountSummary.borrowingAmountUnbiased))
: usdFormatter.format(accountSummary.borrowingAmountUnbiased))}
-
+
-
+
-
Free Collateral
-
+
+ Free Collateral
+
+
{accountSummary && usdFormatter.format(accountSummary.signedFreeCollateral)}
-
+
-
Points
-
+
+ Points
+
+
{!!currentFirebaseUser
? `${groupedNumberFormatterDyn.format(Math.round(userPointsData.totalPoints))} points`
: "P...P...POINTS!"}
-
+
- {/*
);
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
index e13f6db044..c167ed3264 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
@@ -7,8 +7,7 @@ type Props = {
amount: number;
};
-export const SemiCircleProgress = ({}: Props) => {
- const amount = 10;
+export const SemiCircleProgress = ({ amount }: Props) => {
const rotationAnimation = useRef(null);
const [progressColor, setProgressColor] = useState
("#75BA80");
@@ -56,7 +55,7 @@ export const SemiCircleProgress = ({}: Props) => {
width: "180px",
height: "90px",
borderRadius: "90px",
- backgroundColor: "#1C2023",
+ backgroundColor: "#171C1F",
top: "10px",
marginLeft: "auto",
marginRight: "auto",
@@ -66,11 +65,26 @@ export const SemiCircleProgress = ({}: Props) => {
overflow: "hidden",
},
- ".healthLabel": {},
+ ".healthLabelWrapper": {
+ display: "flex",
+ position: "relative",
+ justifyContent: "center",
+ width: "100%",
+ height: "100%",
+ },
+
+ ".healthLabel": {
+ position: "absolute",
+ bottom: 0,
+ color: progressColor,
+ fontSize: "26px",
+ lineHeight: "26px",
+ fontWeight: 600,
+ },
".rotatingCircleWrap": {
position: "absolute",
- backgroundColor: "#1C2023",
+ backgroundColor: "#171C1F",
left: "0px",
width: "200px",
height: "100px",
@@ -99,9 +113,13 @@ export const SemiCircleProgress = ({}: Props) => {
-
+
+
+
+ {percentFormatter.format(amount / 100)}
+
+
);
diff --git a/apps/marginfi-v2-ui/src/pages/index.tsx b/apps/marginfi-v2-ui/src/pages/index.tsx
index e67f71d5b3..ca27378855 100644
--- a/apps/marginfi-v2-ui/src/pages/index.tsx
+++ b/apps/marginfi-v2-ui/src/pages/index.tsx
@@ -100,7 +100,7 @@ const Home = () => {
<>
-
+
{walletAddress && selectedAccount && isOverride && (
{
-
+
diff --git a/apps/marginfi-v2-ui/src/pages/points.tsx b/apps/marginfi-v2-ui/src/pages/points.tsx
index 34f2b8493f..764e781671 100644
--- a/apps/marginfi-v2-ui/src/pages/points.tsx
+++ b/apps/marginfi-v2-ui/src/pages/points.tsx
@@ -1,49 +1,22 @@
-import { Fragment, useCallback, useMemo } from "react";
-import {
- Button,
- Table,
- TableBody,
- TableCell,
- TableContainer,
- TableHead,
- TableRow,
- Paper,
- Typography,
- Card,
- CardContent,
- Skeleton,
- TextField,
- Checkbox,
- CircularProgress,
-} from "@mui/material";
-import { useConnection } from "@solana/wallet-adapter-react";
-import { FC, useEffect, useState } from "react";
-import { PageHeader } from "~/components/desktop/PageHeader";
-import FileCopyIcon from "@mui/icons-material/FileCopy";
+import React, { useMemo, FC, useEffect, useState } from "react";
import Link from "next/link";
-import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
-import { styled } from "@mui/material/styles";
-import Image from "next/image";
+import { Button } from "@mui/material";
+import FileCopyIcon from "@mui/icons-material/FileCopy";
import { useRouter } from "next/router";
-import { WalletButton } from "~/components/common/Navbar";
-import { grey } from "@mui/material/colors";
-import { toast } from "react-toastify";
+
+import { LeaderboardRow, fetchLeaderboardData } from "@mrgnlabs/marginfi-v2-ui-state";
+
import { useUserProfileStore } from "~/store";
-import { LeaderboardRow, fetchLeaderboardData, firebaseApi } from "@mrgnlabs/marginfi-v2-ui-state";
-import { numeralFormatter, groupedNumberFormatterDyn } from "@mrgnlabs/mrgn-common";
import { useWalletContext } from "~/hooks/useWalletContext";
-
-const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
-
-))(({ theme }: { theme: any }) => ({
- [`& .${tooltipClasses.tooltip}`]: {
- backgroundColor: "rgb(227, 227, 227)",
- color: "rgba(0, 0, 0, 0.87)",
- maxWidth: 220,
- fontSize: theme.typography.pxToRem(12),
- border: "1px solid #dadde9",
- },
-}));
+import { PageHeader } from "~/components/desktop/PageHeader";
+import {
+ PointsLeaderBoard,
+ PointsOverview,
+ PointsSignIn,
+ PointsSignUp,
+ PointsCheckingUser,
+ PointsConnectWallet,
+} from "~/components/desktop/Points";
const Points: FC = () => {
const { connected, walletAddress } = useWalletContext();
@@ -68,146 +41,15 @@ const Points: FC = () => {
{!connected ? (
-
+
) : currentFirebaseUser ? (
- <>
-
-
-
-
- Total Points
-
-
-
- Points
-
- Points refresh every 24 hours.
-
- }
- placement="top"
- >
-
-
-
-
-
- {userPointsData.totalPoints > 0 ? (
- numeralFormatter(userPointsData.totalPoints)
- ) : (
-
- )}
-
-
-
-
-
-
- Global Rank {/* TODO: fix that with dedicated query */}
-
-
- {userPointsData.userRank && userPointsData.userRank > 0 ? (
- `#${groupedNumberFormatterDyn.format(userPointsData.userRank)}`
- ) : (
-
- )}
-
-
-
-
-
-
-
-
- Lending Points
-
-
-
- Lending
-
- Lending earns 1 point per dollar lent per day.
-
- }
- placement="top"
- >
-
-
-
-
-
- {userPointsData.depositPoints > 0 ? (
- numeralFormatter(userPointsData.depositPoints)
- ) : (
-
- )}
-
-
-
-
-
-
- Borrowing Points
-
-
-
- Borrowing
-
- Borrowing earns 4 points per dollar borrowed per day.
-
- }
- placement="top"
- >
-
-
-
-
-
- {userPointsData.borrowPoints > 0 ? (
- numeralFormatter(userPointsData.borrowPoints)
- ) : (
-
- )}
-
-
-
-
-
-
- Referral Points
-
-
-
- Earn more with friends
-
- Earn 10% of the points any user you refer earns.
-
- }
- placement="top"
- >
-
-
-
-
-
- {userPointsData.referralPoints > 0 ? numeralFormatter(userPointsData.referralPoints) : "-"}
-
-
-
-
- >
+
) : hasUser === null ? (
-
+
) : hasUser ? (
-
+
) : (
-
+
)}
{
-
-
-
-
-
-
- Rank
-
-
- User
-
-
- Lending Points
-
-
- Borrowing Points
-
-
- Referral Points
-
-
- Social Points
-
-
- Total Points
-
-
-
-
- {leaderboardData.map((row: LeaderboardRow, index: number) => (
-
-
- {index === 0 ? "🥇" : index === 1 ? "🥈" : index === 2 ? "🥉" : index + 1}
-
-
-
- {`${row.id.slice(0, 5)}...${row.id.slice(-5)}`}
-
-
-
-
- {groupedNumberFormatterDyn.format(Math.round(row.total_activity_deposit_points))}
-
-
- {groupedNumberFormatterDyn.format(Math.round(row.total_activity_borrow_points))}
-
-
- {groupedNumberFormatterDyn.format(
- Math.round(row.total_referral_deposit_points + row.total_referral_borrow_points)
- )}
-
-
- {groupedNumberFormatterDyn.format(Math.round(row.socialPoints ? row.socialPoints : 0))}
-
-
- {groupedNumberFormatterDyn.format(
- Math.round(
- row.total_deposit_points + row.total_borrow_points + (row.socialPoints ? row.socialPoints : 0)
- )
- )}
-
-
- ))}
-
-
-
+
>
);
};
-const ConnectWallet: FC = () => (
-
-
-
-
- Access upgraded features
-
-
-
-
-
-
-
-
-
-);
-
-const CheckingUser: FC = () => (
-
-
-
-
- Access upgraded features
-
-
-
-
-
-
-
-);
-
-const Signup: FC<{ referralCode?: string }> = ({ referralCode }) => {
- const { connection } = useConnection();
- const { walletContextState, connected } = useWalletContext();
- const [manualCode, setManualCode] = useState("");
- const [useAuthTx, setUseAuthTx] = useState(false);
- const [useManualCode, setUseManualCode] = useState(false);
-
- const finalReferralCode = useMemo(
- () => (useManualCode ? manualCode : referralCode),
- [useManualCode, manualCode, referralCode]
- );
-
- useEffect(() => {
- if (manualCode.length > 0) {
- setUseManualCode((current) => current || true);
- }
- }, [manualCode]);
-
- const signup = useCallback(async () => {
- toast.info("Logging in...");
- const blockhashInfo = await connection.getLatestBlockhash();
- try {
- await firebaseApi.signup(walletContextState, useAuthTx ? "tx" : "memo", blockhashInfo, finalReferralCode);
- // localStorage.setItem("authData", JSON.stringify(signedAuthData));
- toast.success("Signed up successfully");
- } catch (signupError: any) {
- toast.error(signupError.message);
- }
- }, [connection, finalReferralCode, useAuthTx, walletContextState]);
-
- return (
-
-
-
-
- Access upgraded features
-
-
- Prove you own this wallet by signing a message.
-
- Optionally enter a referral code below.
-
-
- {connected ? (
-
-
{
- setManualCode(event.target.value);
- }}
- />
- setUseAuthTx((current) => !current)}
- >
-
-
Use tx signing
-
-
- Certain hardware wallet versions do not support memo signing.
-
-
- Use this option if you are unable to proceed with memo signing. It is free as well and will
- not involve the network.
-
- >
- }
- placement="top"
- >
-
-
-
-
- Signup
-
-
- ) : (
-
- )}
-
-
-
-
- );
-};
-
-const Login: FC = () => {
- const { connection } = useConnection();
- const { walletContextState, connected } = useWalletContext();
- const [useAuthTx, setUseAuthTx] = useState(false);
- const login = useCallback(async () => {
- toast.info("Logging in...");
- const blockhashInfo = await connection.getLatestBlockhash();
- try {
- await firebaseApi.login(walletContextState, useAuthTx ? "tx" : "memo", blockhashInfo);
- // localStorage.setItem("authData", JSON.stringify(signedAuthData));
- toast.success("Logged in successfully");
- } catch (loginError: any) {
- toast.error(loginError.message);
- }
- }, [connection, useAuthTx, walletContextState]);
-
- return (
-
-
-
-
- Access upgraded features
-
-
- Login to your points account by signing a message.
-
-
- {connected ? (
-
-
setUseAuthTx((current) => !current)}
- >
-
-
Use tx signing
-
-
- Certain hardware wallet versions do not support memo signing.
-
-
- Use this option if you are unable to proceed with memo signing. It is free as well and will
- not involve the network.
-
- >
- }
- placement="top"
- >
-
-
-
-
- Login
-
-
- ) : (
-
- )}
-
-
-
-
- );
-};
-
export default Points;
diff --git a/apps/marginfi-v2-ui/src/pages/portfolio.tsx b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
index 51adc27d58..4b9101efd6 100644
--- a/apps/marginfi-v2-ui/src/pages/portfolio.tsx
+++ b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
@@ -1,14 +1,53 @@
import { useEffect } from "react";
-import config from "~/config";
import { PageHeaderSwap } from "~/components/desktop/PageHeader";
import { useWalletContext } from "~/hooks/useWalletContext";
import { MobilePortfolioOverview } from "~/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview";
+import { useConnection } from "@solana/wallet-adapter-react";
+import { useMrgnlendStore } from "~/store";
+import config from "~/config/marginfi";
+import { MobileAccountSummary } from "~/components/mobile/MobileAccountSummary";
const PortfolioPage = () => {
+ const { walletAddress, wallet, isOverride } = useWalletContext();
+ const { connection } = useConnection();
+ const [
+ fetchMrgnlendState,
+ setIsRefreshingStore,
+ marginfiAccountCount,
+ selectedAccount,
+ userDataFetched,
+ resetUserData,
+ ] = useMrgnlendStore((state) => [
+ state.fetchMrgnlendState,
+ state.setIsRefreshingStore,
+ state.marginfiAccountCount,
+ state.selectedAccount,
+ state.userDataFetched,
+ state.resetUserData,
+ ]);
+
+ const [isStoreInitialized, isRefreshingStore] = useMrgnlendStore((state) => [
+ state.initialized,
+ state.isRefreshingStore,
+ ]);
+
+ useEffect(() => {
+ setIsRefreshingStore(true);
+ fetchMrgnlendState({ marginfiConfig: config.mfiConfig, connection, wallet, isOverride }).catch(console.error);
+ const id = setInterval(() => {
+ setIsRefreshingStore(true);
+ fetchMrgnlendState().catch(console.error);
+ }, 30_000);
+ return () => clearInterval(id);
+ }, [wallet, isOverride]); // eslint-disable-line react-hooks/exhaustive-deps
+ // ^ crucial to omit both `connection` and `fetchMrgnlendState` from the dependency array
+ // TODO: fix...
+
return (
<>
-
+
+
>
From 4899b14181e8c097e7f4474dcaf3d0d37425701e Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Mon, 11 Sep 2023 15:29:24 +0200
Subject: [PATCH 016/351] feat(mfi-v2-ui): Portfolio page
---
.../desktop/Points/PointsCheckingUser.tsx | 2 +-
.../desktop/Points/PointsConnectWallet.tsx | 2 +-
.../desktop/Points/PointsLeaderBoard.tsx | 2 +-
.../desktop/Points/PointsOverview.tsx | 26 +--
.../desktop/Points/PointsSignIn.tsx | 2 +-
.../desktop/Points/PointsSignUp.tsx | 2 +-
.../MobileAccountSummary.tsx | 12 +-
.../MobileAssetsList/AssetCard/AssetCard.tsx | 2 +-
.../AssetCard/AssetCardActions.tsx | 2 +-
.../MobileAssetsList/MobileAssetsList.tsx | 5 -
.../mobile/MobileNavbar/MobileNavbar.tsx | 8 +-
.../MobilePortfolioOverview.tsx | 53 +-----
.../SemiCircleProgress.tsx | 8 +-
.../mobile/MobilePortfolioOverview/index.ts | 1 +
apps/marginfi-v2-ui/src/pages/_app.tsx | 6 +-
apps/marginfi-v2-ui/src/pages/index.tsx | 18 +-
apps/marginfi-v2-ui/src/pages/portfolio.tsx | 180 +++++++++++++++---
17 files changed, 206 insertions(+), 125 deletions(-)
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/index.ts
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx
index aca30f0962..9a97da8117 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx
@@ -5,7 +5,7 @@ interface PointsCheckingUserProps {}
export const PointsCheckingUser: FC = ({}) => {
return (
-
+
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx
index 0ed8b4afb5..cef8667ee3 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx
@@ -7,7 +7,7 @@ interface PointsConnectWalletProps {}
export const PointsConnectWallet: FC
= ({}) => {
return (
-
+
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsLeaderBoard.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsLeaderBoard.tsx
index 3d6ecd7d56..248b446672 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsLeaderBoard.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsLeaderBoard.tsx
@@ -6,7 +6,7 @@ import { LeaderboardRow } from "@mrgnlabs/marginfi-v2-ui-state";
interface PointsLeaderBoardProps {
leaderboardData: LeaderboardRow[];
- currentUserId: string;
+ currentUserId?: string;
}
export const PointsLeaderBoard: FC
= ({ leaderboardData, currentUserId }) => {
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx
index 350fee3bd1..760f0e4e4e 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx
@@ -1,26 +1,20 @@
+import React, { FC } from "react";
import Image from "next/image";
-import { MarginfiAccountWrapper } from "@mrgnlabs/marginfi-client-v2";
-import { Card, CardContent, Skeleton, TableCell, TableRow, Typography } from "@mui/material";
-import React, { FC, useCallback, useMemo, useState } from "react";
-import { toast } from "react-toastify";
-import {
- groupedNumberFormatter,
- uiToNative,
- usdFormatter,
- numeralFormatter,
- groupedNumberFormatterDyn,
-} from "@mrgnlabs/mrgn-common";
+import { Card, CardContent, Skeleton, Typography } from "@mui/material";
+
+import { numeralFormatter, groupedNumberFormatterDyn } from "@mrgnlabs/mrgn-common";
+import { UserPointsData } from "@mrgnlabs/marginfi-v2-ui-state";
+
import { MrgnTooltip } from "~/components/common/MrgnTooltip";
-import { AccountSummary, UserPointsData } from "@mrgnlabs/marginfi-v2-ui-state";
-interface PointsLeaderBoardProps {
+interface PointsOverviewProps {
userPointsData: UserPointsData;
}
-export const PointsOverview: FC = ({ userPointsData }) => {
+export const PointsOverview: FC = ({ userPointsData }) => {
return (
<>
-
+
@@ -65,7 +59,7 @@ export const PointsOverview: FC = ({ userPointsData }) =
-
+
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx
index 517a06b7e4..1dfff3eed7 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx
@@ -30,7 +30,7 @@ export const PointsSignIn: FC = ({}) => {
}, [connection, useAuthTx, walletContextState]);
return (
-
+
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignUp.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignUp.tsx
index a9559a003e..5f92292d4b 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignUp.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignUp.tsx
@@ -46,7 +46,7 @@ export const PointsSignUp: FC
= ({ referralCode }) => {
}, [connection, finalReferralCode, useAuthTx, walletContextState]);
return (
-
+
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
index a7ab7fac41..c092a55e19 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
@@ -2,21 +2,13 @@ import React, { FC } from "react";
import dynamic from "next/dynamic";
import { useMrgnlendStore } from "~/store";
-import { useWalletContext } from "~/hooks/useWalletContext";
-import { UserStats } from "~/components/common/AccountSummary";
const GlobalStats = dynamic(async () => (await import("~/components/common/AccountSummary/GlobalStats")).GlobalStats, {
ssr: false,
});
const AccountSummary: FC = () => {
- const [isStoreInitialized, accountSummary, protocolStats, selectedAccount] = useMrgnlendStore((state) => [
- state.initialized,
- state.accountSummary,
- state.protocolStats,
- state.selectedAccount,
- ]);
- const { connected } = useWalletContext();
+ const [protocolStats] = useMrgnlendStore((state) => [state.protocolStats]);
return (
@@ -29,7 +21,7 @@ const AccountSummary: FC = () => {
borrows={protocolStats.borrows}
deposits={protocolStats.deposits}
/>
-
{" "}
+
{/*
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
index 764c638a55..427034ee53 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
@@ -21,7 +21,7 @@ export const AssetCard: FC<{
isInLendingMode: boolean;
isConnected: boolean;
marginfiAccount: MarginfiAccountWrapper | null;
- inputRefs: React.MutableRefObject
>;
+ inputRefs?: React.MutableRefObject>;
}> = ({ bank, nativeSolBalance, isInLendingMode, marginfiAccount, inputRefs }) => {
const { rateAP, assetWeight, isBankFilled, isBankHigh, bankCap } = useAssetItemData({ bank, isInLendingMode });
const [mfiClient, fetchMrgnlendState] = useMrgnlendStore((state) => [state.marginfiClient, state.fetchMrgnlendState]);
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardActions.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardActions.tsx
index 2d6be3e2a0..f40a6d6126 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardActions.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardActions.tsx
@@ -8,10 +8,10 @@ import { useWalletContext } from "~/hooks/useWalletContext";
export const AssetCardActions: FC<{
bank: ExtendedBankInfo;
- inputRefs: React.MutableRefObject>;
isBankFilled: boolean;
isInLendingMode: boolean;
currentAction: ActionType | "Connect";
+ inputRefs?: React.MutableRefObject>;
onCloseBalance: () => void;
onBorrowOrLend: (amount: number) => void;
}> = ({ bank, inputRefs, isBankFilled, currentAction, onCloseBalance, onBorrowOrLend }) => {
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
index 40a7b35cd9..8402c4e554 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
@@ -20,11 +20,6 @@ export const MobileAssetsList: FC = () => {
state.nativeSolBalance,
state.selectedAccount,
]);
- const [lendZoomLevel, showBadges, setShowBadges] = useUserProfileStore((state) => [
- state.lendZoomLevel,
- state.showBadges,
- state.setShowBadges,
- ]);
const inputRefs = useRef>({});
const [isInLendingMode, setIsInLendingMode] = useState(true);
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/MobileNavbar.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/MobileNavbar.tsx
index f2b3d9da95..4f66c07862 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/MobileNavbar.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileNavbar/MobileNavbar.tsx
@@ -1,7 +1,7 @@
import { FC, useEffect } from "react";
import Link from "next/link";
import Image from "next/image";
-import AirdropZone from "./AirdropZone";
+
import { useUserProfileStore } from "~/store";
import { useRouter } from "next/router";
import { useFirebaseAccount } from "~/hooks/useFirebaseAccount";
@@ -40,11 +40,11 @@ const MobileNavbar: FC = () => {
swap
- bridge
+ portfolio
{/* {
- const [
- marginfiClient,
- fetchMrgnlendState,
- selectedAccount,
- accountSummary,
- extendedBankInfos,
- nativeSolBalance,
- protocolStats,
- ] = useMrgnlendStore((state) => [
- state.marginfiClient,
- state.fetchMrgnlendState,
- state.selectedAccount,
- state.accountSummary,
- state.extendedBankInfos,
- state.nativeSolBalance,
- state.protocolStats,
- ]);
- const { wallet } = useWallet();
- const connection = useConnection();
-
- useEffect(() => {
- fetchMrgnlendState();
- const id = setInterval(() => fetchMrgnlendState().catch(console.error), 30_000);
- return () => clearInterval(id);
- }, [wallet]); // eslint-disable-line react-hooks/exhaustive-deps
- // ^ crucial to omit both `connection` and `fetchMrgnlendState` from the dependency array
- // TODO: fix...
+ const [selectedAccount, accountSummary] = useMrgnlendStore((state) => [state.selectedAccount, state.accountSummary]);
const [userPointsData, currentFirebaseUser] = useUserProfileStore((state) => [
state.userPointsData,
state.currentFirebaseUser,
]);
- console.log({ selectedAccount });
-
const healthFactor = useMemo(() => {
+ console.log({ selectedAccount });
if (selectedAccount) {
const { assets, liabilities } = selectedAccount.computeHealthComponents(MarginRequirementType.Maintenance);
return assets.isZero() ? 100 : assets.minus(liabilities).dividedBy(assets).toNumber() * 100;
@@ -60,10 +27,10 @@ export const MobilePortfolioOverview: FC = () => {
}, [selectedAccount]);
return (
-
+
Your overview
-
Health factor
+
Health factor
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
index c167ed3264..9e7a1e57f4 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
@@ -1,7 +1,8 @@
+import React, { useEffect, useRef, useState } from "react";
import { keyframes } from "@emotion/react";
import styled from "@emotion/styled";
+
import { percentFormatter } from "@mrgnlabs/mrgn-common";
-import React, { useEffect, useRef, useState } from "react";
type Props = {
amount: number;
@@ -55,7 +56,7 @@ export const SemiCircleProgress = ({ amount }: Props) => {
width: "180px",
height: "90px",
borderRadius: "90px",
- backgroundColor: "#171C1F",
+ backgroundColor: "#131619",
top: "10px",
marginLeft: "auto",
marginRight: "auto",
@@ -84,7 +85,7 @@ export const SemiCircleProgress = ({ amount }: Props) => {
".rotatingCircleWrap": {
position: "absolute",
- backgroundColor: "#171C1F",
+ backgroundColor: "#131619",
left: "0px",
width: "200px",
height: "100px",
@@ -92,7 +93,6 @@ export const SemiCircleProgress = ({ amount }: Props) => {
},
".rotatingCircle": {
- // position: "absolute",
overflow: "hidden",
top: "0px",
left: "0px",
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/index.ts b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/index.ts
new file mode 100644
index 0000000000..f872bac67d
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/index.ts
@@ -0,0 +1 @@
+export * from "./MobilePortfolioOverview";
diff --git a/apps/marginfi-v2-ui/src/pages/_app.tsx b/apps/marginfi-v2-ui/src/pages/_app.tsx
index 30be73c899..c4c67bc8fb 100644
--- a/apps/marginfi-v2-ui/src/pages/_app.tsx
+++ b/apps/marginfi-v2-ui/src/pages/_app.tsx
@@ -77,8 +77,10 @@ const MyApp = ({ Component, pageProps }: AppProps) => {
-
-
+
diff --git a/apps/marginfi-v2-ui/src/pages/index.tsx b/apps/marginfi-v2-ui/src/pages/index.tsx
index ca27378855..bd371a2b33 100644
--- a/apps/marginfi-v2-ui/src/pages/index.tsx
+++ b/apps/marginfi-v2-ui/src/pages/index.tsx
@@ -1,13 +1,15 @@
-import React, { FC, useEffect } from "react";
-import { Banner } from "~/components/desktop/Banner";
-import { PageHeader } from "~/components/desktop/PageHeader";
-import { useWalletContext } from "~/hooks/useWalletContext";
+import React, { useEffect } from "react";
+import dynamic from "next/dynamic";
+import { useConnection } from "@solana/wallet-adapter-react";
+
import { shortenAddress } from "@mrgnlabs/mrgn-common";
+
import config from "~/config/marginfi";
-import { useMrgnlendStore } from "../store";
-import dynamic from "next/dynamic";
+import { useMrgnlendStore } from "~/store";
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { Banner } from "~/components/desktop/Banner";
+import { PageHeader } from "~/components/desktop/PageHeader";
import { OverlaySpinner } from "~/components/desktop/OverlaySpinner";
-import { useConnection } from "@solana/wallet-adapter-react";
import { Desktop, Mobile } from "~/mediaQueries";
const DesktopAccountSummary = () => {
@@ -123,7 +125,7 @@ const Home = () => {
-
+
diff --git a/apps/marginfi-v2-ui/src/pages/portfolio.tsx b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
index 4b9101efd6..d50ccc39e3 100644
--- a/apps/marginfi-v2-ui/src/pages/portfolio.tsx
+++ b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
@@ -1,35 +1,45 @@
-import { useEffect } from "react";
-import { PageHeaderSwap } from "~/components/desktop/PageHeader";
-import { useWalletContext } from "~/hooks/useWalletContext";
-import { MobilePortfolioOverview } from "~/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview";
+import { useEffect, useMemo } from "react";
+import { useRouter } from "next/router";
+import Link from "next/link";
+import FileCopyIcon from "@mui/icons-material/FileCopy";
import { useConnection } from "@solana/wallet-adapter-react";
-import { useMrgnlendStore } from "~/store";
+
+import { useMrgnlendStore, useUserProfileStore } from "~/store";
import config from "~/config/marginfi";
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { PageHeader } from "~/components/desktop/PageHeader";
import { MobileAccountSummary } from "~/components/mobile/MobileAccountSummary";
+import { MobilePortfolioOverview } from "~/components/mobile/MobilePortfolioOverview";
+import {
+ PointsOverview,
+ PointsSignIn,
+ PointsSignUp,
+ PointsCheckingUser,
+ PointsConnectWallet,
+} from "~/components/desktop/Points";
+import { AssetCard } from "~/components/mobile/MobileAssetsList/AssetCard";
+import { Button, Skeleton } from "@mui/material";
const PortfolioPage = () => {
- const { walletAddress, wallet, isOverride } = useWalletContext();
+ const { connected, wallet, isOverride } = useWalletContext();
+ const { query: routerQuery } = useRouter();
const { connection } = useConnection();
- const [
- fetchMrgnlendState,
- setIsRefreshingStore,
- marginfiAccountCount,
- selectedAccount,
- userDataFetched,
- resetUserData,
- ] = useMrgnlendStore((state) => [
- state.fetchMrgnlendState,
- state.setIsRefreshingStore,
- state.marginfiAccountCount,
- state.selectedAccount,
- state.userDataFetched,
- state.resetUserData,
+ const [isStoreInitialized, sortedBanks, nativeSolBalance, selectedAccount, fetchMrgnlendState, setIsRefreshingStore] =
+ useMrgnlendStore((state) => [
+ state.initialized,
+ state.extendedBankInfos,
+ state.nativeSolBalance,
+ state.selectedAccount,
+ state.fetchMrgnlendState,
+ state.setIsRefreshingStore,
+ ]);
+ const [currentFirebaseUser, hasUser, userPointsData] = useUserProfileStore((state) => [
+ state.currentFirebaseUser,
+ state.hasUser,
+ state.userPointsData,
]);
- const [isStoreInitialized, isRefreshingStore] = useMrgnlendStore((state) => [
- state.initialized,
- state.isRefreshingStore,
- ]);
+ const referralCode = useMemo(() => routerQuery.referralCode as string | undefined, [routerQuery.referralCode]);
useEffect(() => {
setIsRefreshingStore(true);
@@ -45,10 +55,128 @@ const PortfolioPage = () => {
return (
<>
-
-
+
+
+ {!connected ? (
+
+ ) : currentFirebaseUser ? (
+
+ ) : hasUser === null ? (
+
+ ) : hasUser ? (
+
+ ) : (
+
+ )}
+
+
+ How do points work?
+
+ {currentFirebaseUser && (
+ {
+ if (userPointsData.referralLink) {
+ navigator.clipboard.writeText(userPointsData.referralLink);
+ }
+ }}
+ >
+ {`${
+ userPointsData.isCustomReferralLink
+ ? userPointsData.referralLink?.replace("https://", "")
+ : "Copy referral link"
+ }`}
+
+
+ )}
+
+
+
We reserve the right to update point calculations at any time.
+
+
+ Terms.
+
+
+
+
+
Lending positions
+
+ {sortedBanks
+ .filter((b) => b.isActive)
+ .map((bank, i) =>
+ isStoreInitialized ? (
+
+ ) : (
+
+ )
+ )}
+
+
+
+
+
Borrowing positions
+
+ {sortedBanks
+ .filter((b) => b.isActive)
+ .map((bank, i) =>
+ isStoreInitialized ? (
+
+ ) : (
+
+ )
+ )}
+
+
>
);
From c8be4eeacf346068155fb0ab050bfb049f4fb643 Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Tue, 12 Sep 2023 12:53:52 +0200
Subject: [PATCH 017/351] fix(mfi-v2-ui): fixed divers console error
- Rehydration error is fixed with ready usestate
- div nested in p & wrong table structure fixes
---
.../common/AccountSummary/UserStats.tsx | 35 +-
.../desktop/AssetsList/AssetsList.tsx | 329 +++++++++---------
.../desktop/UserPositions/UserPositions.tsx | 228 ++++++------
apps/marginfi-v2-ui/src/pages/_app.tsx | 87 ++---
4 files changed, 361 insertions(+), 318 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/common/AccountSummary/UserStats.tsx b/apps/marginfi-v2-ui/src/components/common/AccountSummary/UserStats.tsx
index 65cbf7dde2..bf5b835c16 100644
--- a/apps/marginfi-v2-ui/src/components/common/AccountSummary/UserStats.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/AccountSummary/UserStats.tsx
@@ -39,7 +39,12 @@ const UserStats: FC = ({ accountSummary, healthFactor }) => {
-
+
Account
{accountSummary && (
@@ -90,7 +95,12 @@ const UserStats: FC
= ({ accountSummary, healthFactor }) => {
-
+
Supplying
{accountSummary && (
@@ -143,7 +153,12 @@ const UserStats: FC
= ({ accountSummary, healthFactor }) => {
-
+
Borrowing
{accountSummary && (
@@ -196,7 +211,12 @@ const UserStats: FC
= ({ accountSummary, healthFactor }) => {
-
+
Health
{accountSummary && (
@@ -242,7 +262,12 @@ const UserStats: FC
= ({ accountSummary, healthFactor }) => {
-
+
Free
{
}}
>
-
-
- Global pool
-
-
-
-
- Price
-
-
- Realtime prices
-
-
- Powered by Pyth and Switchboard.
-
-
- }
- placement="top"
- >
-
-
-
-
-
-
- {isInLendingMode ? "APY" : "APR"}
-
-
- {isInLendingMode ? "APY" : "APR"}
-
-
- {isInLendingMode
- ? "What you'll earn on deposits over a year. This includes compounding. All marginfi deposits are compounded hourly."
- : "What you'll pay for your borrows, or the price of a loan. This does not include compounding. All marginfi borrows are compounded hourly."}
-
-
- }
- placement="top"
- >
-
-
-
-
-
-
- {isInLendingMode ? "Weight" : "LTV"}
-
-
- {isInLendingMode ? "Weight" : "LTV"}
-
-
- {isInLendingMode
- ? "How much your assets count for collateral, relative to their USD value. The higher the weight, the more collateral you can borrow against it."
- : "How much you can borrow against your free collateral. The higher the LTV, the more you can borrow against your free collateral."}
-
-
- }
- placement="top"
- >
-
-
-
-
-
-
- {isInLendingMode ? "Deposits" : "Available"}
-
-
- {isInLendingMode ? "Total deposits" : "Total available"}
-
-
- {isInLendingMode
- ? "Total marginfi deposits for each asset. Everything is denominated in native tokens."
- : "The amount of tokens available to borrow for each asset. Calculated as the minimum of the asset's borrow limit and available liquidity that has not yet been borrowed."}
-
-
- }
- placement="top"
- >
-
-
-
-
-
- {/*******************************/}
- {/* [START]: ZOOM-BASED COLUMNS */}
- {/*******************************/}
-
- {lendZoomLevel < 2 && (
+
+
+
+ Global pool
+
+
- Global limit
+ Price
- {isInLendingMode ? "Global deposit cap" : "Global borrow cap"}
+ Realtime prices
- Each marginfi pool has global deposit and borrow limits, also known as caps. This is the
- total amount that all users combined can deposit or borrow of a given token.
+
+ Powered by Pyth and Switchboard.
+
+
+ }
+ placement="top"
+ >
+
+
+
+
+
+
+ {isInLendingMode ? "APY" : "APR"}
+
+
+ {isInLendingMode ? "APY" : "APR"}
+
+
+ {isInLendingMode
+ ? "What you'll earn on deposits over a year. This includes compounding. All marginfi deposits are compounded hourly."
+ : "What you'll pay for your borrows, or the price of a loan. This does not include compounding. All marginfi borrows are compounded hourly."}
+
+
+ }
+ placement="top"
+ >
+
+
+
+
+
+
+ {isInLendingMode ? "Weight" : "LTV"}
+
+
+ {isInLendingMode ? "Weight" : "LTV"}
+
+
+ {isInLendingMode
+ ? "How much your assets count for collateral, relative to their USD value. The higher the weight, the more collateral you can borrow against it."
+ : "How much you can borrow against your free collateral. The higher the LTV, the more you can borrow against your free collateral."}
+
}
placement="top"
@@ -246,24 +192,24 @@ const AssetsList: FC = () => {
- )}
-
- {lendZoomLevel < 3 && (
- Utilization
+ {isInLendingMode ? "Deposits" : "Available"}
- Pool utilization
+ {isInLendingMode ? "Total deposits" : "Total available"}
- What percentage of supplied tokens have been borrowed. This helps determine interest rates.
- This is not based on the global pool limits, which can limit utilization.
+
+ {isInLendingMode
+ ? "Total marginfi deposits for each asset. Everything is denominated in native tokens."
+ : "The amount of tokens available to borrow for each asset. Calculated as the minimum of the asset's borrow limit and available liquidity that has not yet been borrowed."}
+
}
placement="top"
@@ -272,21 +218,77 @@ const AssetsList: FC = () => {
- )}
- {/*******************************/}
- {/* [END]: ZOOM-BASED COLUMNS */}
- {/*******************************/}
+ {/*******************************/}
+ {/* [START]: ZOOM-BASED COLUMNS */}
+ {/*******************************/}
-
- Wallet Amt.
-
-
-
+ {lendZoomLevel < 2 && (
+
+
+ Global limit
+
+
+ {isInLendingMode ? "Global deposit cap" : "Global borrow cap"}
+
+ Each marginfi pool has global deposit and borrow limits, also known as caps. This is the
+ total amount that all users combined can deposit or borrow of a given token.
+
+ }
+ placement="top"
+ >
+
+
+
+
+ )}
+
+ {lendZoomLevel < 3 && (
+
+
+ Utilization
+
+
+ Pool utilization
+
+ What percentage of supplied tokens have been borrowed. This helps determine interest
+ rates. This is not based on the global pool limits, which can limit utilization.
+
+ }
+ placement="top"
+ >
+
+
+
+
+ )}
+
+ {/*******************************/}
+ {/* [END]: ZOOM-BASED COLUMNS */}
+ {/*******************************/}
+
+
+ Wallet Amt.
+
+
+
+
@@ -315,26 +317,33 @@ const AssetsList: FC = () => {
)
)}
-
-
- Isolated pools
-
-
-
- Isolated pools are risky ⚠️
-
- Assets in isolated pools cannot be used as collateral. When you borrow an isolated asset, you
- cannot borrow other assets. Isolated pools should be considered particularly risky. As always,
- remember that marginfi is a decentralized protocol and all deposited funds are at risk.
-
- }
- placement="top"
- >
-
-
-
+
+
+
+
+
+ Isolated pools
+
+
+
+ Isolated pools are risky ⚠️
+
+ Assets in isolated pools cannot be used as collateral. When you borrow an isolated asset,
+ you cannot borrow other assets. Isolated pools should be considered particularly risky. As
+ always, remember that marginfi is a decentralized protocol and all deposited funds are at
+ risk.
+
+ }
+ placement="top"
+ >
+
+
+
+
+
+
{sortedBanks
.filter((b) => b.info.state.isIsolated)
diff --git a/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx
index 6ac8beb192..d68192101a 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/UserPositions/UserPositions.tsx
@@ -1,5 +1,5 @@
import React, { FC, useMemo } from "react";
-import { Card, Table, TableBody, TableContainer, TableHead, TableCell, Typography } from "@mui/material";
+import { Card, Table, TableBody, TableContainer, TableHead, TableCell, Typography, TableRow } from "@mui/material";
import Image from "next/image";
import Link from "next/link";
@@ -45,113 +45,7 @@ const UserPositions: FC = () => {
}}
>
-
-
- Lending
-
-
-
- Wtd
-
-
-
- Weighted values
-
-
- For risk purposes, token values are adjusted by oracle price bias and risk weights.
-
-
- Weighted prices used in risk calculations and are relevant to your health factor.
-
-
- Learn more here.
-
-
- }
- placement="top"
- >
-
-
-
-
-
-
-
- USD
-
-
-
- USD Values
-
-
- Unadjusted USD values are based on oracle mid prices - or the best estimate the oracle has
- of average token price.
-
-
- Unadjusted USD values are not used in risk calculations. Values with price bias are used
- because they are more conservative, and can control for oracle inaccuracies.
-
-
- Learn more here.
-
-
- }
- placement="top"
- >
-
-
-
-
-
-
-
-
-
- {lendPositions.map((bankInfo, index) => (
- {
- setIsRefreshingStore(true);
- fetchMrgnlendState();
- }}
- />
- ))}
-
-
-
-
- )}
-
- {borrowPositions.length > 0 && selectedAccount && (
-
- Borrowing
-
-
-
+
{
align="right"
>
- Borrowing
+ Lending
{
style={{ fontFamily: "Aeonik Pro", fontWeight: 300 }}
align="right"
>
-
+
Wtd
{
style={{ fontFamily: "Aeonik Pro", fontWeight: 300 }}
align="right"
>
-
+
USD
{
+
+
+
+ {lendPositions.map((bankInfo, index) => (
+ {
+ setIsRefreshingStore(true);
+ fetchMrgnlendState();
+ }}
+ />
+ ))}
+
+
+
+
+ )}
+
+ {borrowPositions.length > 0 && selectedAccount && (
+
+ Borrowing
+
+
+
+
+
+
+
+ Borrowing
+
+
+
+
+ Wtd
+
+
+
+ Weighted values
+
+
+ For risk purposes, token values are adjusted by oracle price bias and risk weights.
+
+
+ Weighted prices used in risk calculations and are relevant to your health factor.
+
+
+ Learn more here.
+
+
+ }
+ placement="top"
+ >
+
+
+
+
+
+
+
+ USD
+
+
+
+ USD Values
+
+
+ Unadjusted USD values are based on oracle mid prices - or the best estimate the oracle
+ has of average token price.
+
+
+ Unadjusted USD values are not used in risk calculations. Values with price bias are
+ used because they are more conservative, and can control for oracle inaccuracies.
+
+
+ Learn more here.
+
+
+ }
+ placement="top"
+ >
+
+
+
+
+
+
+
+
{borrowPositions.map((bankInfo, index) => (
diff --git a/apps/marginfi-v2-ui/src/pages/_app.tsx b/apps/marginfi-v2-ui/src/pages/_app.tsx
index c4c67bc8fb..03861dd677 100644
--- a/apps/marginfi-v2-ui/src/pages/_app.tsx
+++ b/apps/marginfi-v2-ui/src/pages/_app.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useMemo } from "react";
+import React, { useEffect, useMemo, useState } from "react";
import type { AppProps } from "next/app";
import Head from "next/head";
import { ConnectionProvider, WalletProvider } from "@solana/wallet-adapter-react";
@@ -46,52 +46,55 @@ const MyApp = ({ Component, pageProps }: AppProps) => {
}
}, []);
+ const [ready, setReady] = useState(false);
+
const wallets = useMemo(
- () => [
- new OKXWalletAdapter(),
- new LedgerWalletAdapter(),
- new SolflareWalletAdapter(),
- new GlowWalletAdapter(),
- new PhantomWalletAdapter(),
- new BackpackWalletAdapter(),
- ],
+ () => [new OKXWalletAdapter(), new LedgerWalletAdapter(), new SolflareWalletAdapter(), new GlowWalletAdapter()],
[]
);
+ useEffect(() => {
+ setReady(true);
+ }, []);
+
return (
-
-
-
-
- marginfi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ <>
+
+ marginfi
+
+
+
+
+ {ready && (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
+ >
);
};
From 86aa856bc24560f36987928e9ed8b77b264e3857 Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Thu, 28 Sep 2023 20:06:12 +0800
Subject: [PATCH 018/351] chore(mfi-v2-ui): clean loose components + format
---
.../marginfi-v2-ui/src/components/Spinner.tsx | 13 ----
.../components/Staking/StakingCard/index.ts | 1 -
.../src/components/common/Spinner.tsx | 15 +++++
.../Staking/StakingCard/LstDepositToggle.tsx | 2 +-
.../Staking/StakingCard/PrimaryButton.tsx | 0
.../Staking/StakingCard/RefreshIcon.tsx | 0
.../Staking/StakingCard/SettingsIcon.tsx | 0
.../Staking/StakingCard/SettingsModal.tsx | 0
.../Staking/StakingCard/StakingCard.tsx | 5 +-
.../Staking/StakingCard/StakingModal.tsx | 5 +-
.../Staking/StakingCard/WalletIcon.tsx | 0
.../common/Staking/StakingCard/index.ts | 1 +
.../{ => common}/Staking/StakingStats.tsx | 0
.../components/{ => common}/Staking/index.ts | 1 +
.../desktop/AssetsList/AssetRow/AssetRow.tsx | 60 ++++++++++---------
apps/marginfi-v2-ui/src/mediaQueries.ts | 8 +--
.../src/pages/api/user/signup.ts | 11 +---
apps/marginfi-v2-ui/src/pages/api/utils.ts | 1 -
apps/marginfi-v2-ui/src/pages/stake.tsx | 3 +-
apps/marginfi-v2-ui/src/store/lstStore.ts | 4 +-
apps/marginfi-v2-ui/src/utils/featureGates.ts | 2 +-
apps/marginfi-v2-ui/src/utils/lstUtils.ts | 12 ++--
apps/marginfi-v2-ui/src/utils/mrgnActions.ts | 6 +-
.../Portfolio/PortfolioOverview.tsx | 4 +-
.../marginfi-client-v2/src/models/balance.ts | 5 +-
25 files changed, 75 insertions(+), 84 deletions(-)
delete mode 100644 apps/marginfi-v2-ui/src/components/Spinner.tsx
delete mode 100644 apps/marginfi-v2-ui/src/components/Staking/StakingCard/index.ts
create mode 100644 apps/marginfi-v2-ui/src/components/common/Spinner.tsx
rename apps/marginfi-v2-ui/src/components/{ => common}/Staking/StakingCard/LstDepositToggle.tsx (98%)
rename apps/marginfi-v2-ui/src/components/{ => common}/Staking/StakingCard/PrimaryButton.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => common}/Staking/StakingCard/RefreshIcon.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => common}/Staking/StakingCard/SettingsIcon.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => common}/Staking/StakingCard/SettingsModal.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => common}/Staking/StakingCard/StakingCard.tsx (99%)
rename apps/marginfi-v2-ui/src/components/{ => common}/Staking/StakingCard/StakingModal.tsx (98%)
rename apps/marginfi-v2-ui/src/components/{ => common}/Staking/StakingCard/WalletIcon.tsx (100%)
create mode 100644 apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/index.ts
rename apps/marginfi-v2-ui/src/components/{ => common}/Staking/StakingStats.tsx (100%)
rename apps/marginfi-v2-ui/src/components/{ => common}/Staking/index.ts (50%)
diff --git a/apps/marginfi-v2-ui/src/components/Spinner.tsx b/apps/marginfi-v2-ui/src/components/Spinner.tsx
deleted file mode 100644
index 3465d54687..0000000000
--- a/apps/marginfi-v2-ui/src/components/Spinner.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-export const Spinner = () => (
-
-
- )
diff --git a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/index.ts b/apps/marginfi-v2-ui/src/components/Staking/StakingCard/index.ts
deleted file mode 100644
index a3b0a8ba48..0000000000
--- a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./StakingCard";
diff --git a/apps/marginfi-v2-ui/src/components/common/Spinner.tsx b/apps/marginfi-v2-ui/src/components/common/Spinner.tsx
new file mode 100644
index 0000000000..ea618118c5
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/common/Spinner.tsx
@@ -0,0 +1,15 @@
+export const Spinner = () => (
+
+
+
+
+);
diff --git a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/LstDepositToggle.tsx b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/LstDepositToggle.tsx
similarity index 98%
rename from apps/marginfi-v2-ui/src/components/Staking/StakingCard/LstDepositToggle.tsx
rename to apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/LstDepositToggle.tsx
index 25f032bf92..a4f36b3ca3 100644
--- a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/LstDepositToggle.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/LstDepositToggle.tsx
@@ -61,7 +61,7 @@ const LstDepositToggle = styled(({ checked, setChecked, ...switchProps }: LstDep
justifyContent: "center",
transitionDuration: "300ms",
transform: "translateX(0%)",
- "& + .MuiSwitch-track": {
+ "& + .MuiSwitch-track": {
opacity: 0,
width: 0,
height: "100%",
diff --git a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/PrimaryButton.tsx b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/PrimaryButton.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/Staking/StakingCard/PrimaryButton.tsx
rename to apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/PrimaryButton.tsx
diff --git a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/RefreshIcon.tsx b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/RefreshIcon.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/Staking/StakingCard/RefreshIcon.tsx
rename to apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/RefreshIcon.tsx
diff --git a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/SettingsIcon.tsx b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/SettingsIcon.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/Staking/StakingCard/SettingsIcon.tsx
rename to apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/SettingsIcon.tsx
diff --git a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/SettingsModal.tsx b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/SettingsModal.tsx
similarity index 100%
rename from apps/marginfi-v2-ui/src/components/Staking/StakingCard/SettingsModal.tsx
rename to apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/SettingsModal.tsx
diff --git a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/StakingCard.tsx b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingCard.tsx
similarity index 99%
rename from apps/marginfi-v2-ui/src/components/Staking/StakingCard/StakingCard.tsx
rename to apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingCard.tsx
index 056db62c9d..756866befd 100644
--- a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/StakingCard.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingCard.tsx
@@ -6,9 +6,7 @@ import { PrimaryButton } from "./PrimaryButton";
import { useLstStore } from "~/pages/stake";
import { useWalletContext } from "~/hooks/useWalletContext";
import {
- TOKEN_PROGRAM_ID,
createAssociatedTokenAccountIdempotentInstruction,
- createCloseAccountInstruction,
getAssociatedTokenAddressSync,
nativeToUi,
numeralFormatter,
@@ -24,7 +22,6 @@ import {
Connection,
Keypair,
PublicKey,
- SYSVAR_RENT_PUBKEY,
Signer,
StakeAuthorizationLayout,
StakeProgram,
@@ -43,7 +40,7 @@ import { SettingsModal } from "./SettingsModal";
import { SettingsIcon } from "./SettingsIcon";
import { LST_MINT, TokenData, TokenDataMap } from "~/store/lstStore";
import { RefreshIcon } from "./RefreshIcon";
-import { Spinner } from "~/components/Spinner";
+import { Spinner } from "~/components/common/Spinner";
import BN from "bn.js";
import debounce from "lodash.debounce";
diff --git a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/StakingModal.tsx b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingModal.tsx
similarity index 98%
rename from apps/marginfi-v2-ui/src/components/Staking/StakingCard/StakingModal.tsx
rename to apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingModal.tsx
index 035fb53fa4..d9ce3f762b 100644
--- a/apps/marginfi-v2-ui/src/components/Staking/StakingCard/StakingModal.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingModal.tsx
@@ -86,7 +86,10 @@ export const StakingModal: FC = ({
/>
) : (
- No eligible stake accounts found
+
+ No eligible stake accounts found
+
+
)
) : (
- {bank.info.state.emissionsRate > 0 && EMISSION_MINT_INFO_MAP.get(bank.meta.tokenSymbol) !== undefined && isInLendingMode && (
-
-
-
- Liquidity rewards
-
- {`${percentFormatter.format(bank.info.state.lendingRate)} Supply APY + ${percentFormatter.format(
- bank.info.state.emissionsRate
- )} ${EMISSION_MINT_INFO_MAP.get(bank.meta.tokenSymbol)!.tokenSymbol} rewards.`}
-
-
- Learn more.
-
-
- }
- placement="left"
- >
-
-
-
- )}
+ {bank.info.state.emissionsRate > 0 &&
+ EMISSION_MINT_INFO_MAP.get(bank.meta.tokenSymbol) !== undefined &&
+ isInLendingMode && (
+
+
+
+ Liquidity rewards
+
+ {`${percentFormatter.format(bank.info.state.lendingRate)} Supply APY + ${percentFormatter.format(
+ bank.info.state.emissionsRate
+ )} ${EMISSION_MINT_INFO_MAP.get(bank.meta.tokenSymbol)!.tokenSymbol} rewards.`}
+
+
+ Learn more.
+
+
+ }
+ placement="left"
+ >
+
+
+
+ )}
= ({ children }) => {
+const Desktop: FC<{ children: any }> = ({ children }) => {
const isDesktop = useMediaQuery({ minWidth: 992 });
return isDesktop ? children : null;
};
-const Mobile: FC<{children: any}> = ({ children }) => {
+const Mobile: FC<{ children: any }> = ({ children }) => {
const isMobile = useMediaQuery({ maxWidth: 992 });
return isMobile ? children : null;
};
diff --git a/apps/marginfi-v2-ui/src/pages/api/user/signup.ts b/apps/marginfi-v2-ui/src/pages/api/user/signup.ts
index 0cdf342ee8..0c5240636b 100644
--- a/apps/marginfi-v2-ui/src/pages/api/user/signup.ts
+++ b/apps/marginfi-v2-ui/src/pages/api/user/signup.ts
@@ -1,14 +1,7 @@
import * as admin from "firebase-admin";
import * as Sentry from "@sentry/nextjs";
-import {
- createFirebaseUser,
- getFirebaseUserByWallet,
- initFirebaseIfNeeded,
- logSignupAttempt,
-} from "./utils";
-import {
- NextApiRequest,
-} from "../utils";
+import { createFirebaseUser, getFirebaseUserByWallet, initFirebaseIfNeeded, logSignupAttempt } from "./utils";
+import { NextApiRequest } from "../utils";
import { is } from "superstruct";
import { MEMO_PROGRAM_ID } from "@mrgnlabs/mrgn-common";
import { PublicKey, Transaction } from "@solana/web3.js";
diff --git a/apps/marginfi-v2-ui/src/pages/api/utils.ts b/apps/marginfi-v2-ui/src/pages/api/utils.ts
index 2835338ce4..4db5623ab0 100644
--- a/apps/marginfi-v2-ui/src/pages/api/utils.ts
+++ b/apps/marginfi-v2-ui/src/pages/api/utils.ts
@@ -1,4 +1,3 @@
-
// ------- Next helpers
import { IncomingMessage } from "http";
diff --git a/apps/marginfi-v2-ui/src/pages/stake.tsx b/apps/marginfi-v2-ui/src/pages/stake.tsx
index b00baf9460..bb320f81ca 100644
--- a/apps/marginfi-v2-ui/src/pages/stake.tsx
+++ b/apps/marginfi-v2-ui/src/pages/stake.tsx
@@ -4,8 +4,7 @@ import { Typography } from "@mui/material";
import { useConnection } from "@solana/wallet-adapter-react";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
-import { StakingStats } from "~/components/Staking";
-import { StakingCard } from "~/components/Staking/StakingCard/StakingCard";
+import { StakingCard, StakingStats } from "~/components/common/Staking";
import { OverlaySpinner } from "~/components/desktop/OverlaySpinner";
import { PageHeader } from "~/components/desktop/PageHeader";
import { useWalletContext } from "~/hooks/useWalletContext";
diff --git a/apps/marginfi-v2-ui/src/store/lstStore.ts b/apps/marginfi-v2-ui/src/store/lstStore.ts
index b0f284050b..90f1699adc 100644
--- a/apps/marginfi-v2-ui/src/store/lstStore.ts
+++ b/apps/marginfi-v2-ui/src/store/lstStore.ts
@@ -248,9 +248,7 @@ async function fetchLstData(connection: Connection): Promise
{
if (projectedApy < 7) {
// temporarily use baseline validator APY waiting for a few epochs to pass
- const baselineValidatorData = apyData.validators.find(
- (validator: any) => validator.id === BASELINE_VALIDATOR_ID
- );
+ const baselineValidatorData = apyData.validators.find((validator: any) => validator.id === BASELINE_VALIDATOR_ID);
if (baselineValidatorData) projectedApy = baselineValidatorData.apy;
}
diff --git a/apps/marginfi-v2-ui/src/utils/featureGates.ts b/apps/marginfi-v2-ui/src/utils/featureGates.ts
index 53607a8123..22a30e8c4b 100644
--- a/apps/marginfi-v2-ui/src/utils/featureGates.ts
+++ b/apps/marginfi-v2-ui/src/utils/featureGates.ts
@@ -1,5 +1,5 @@
enum Features {
- STAKE = 'stake',
+ STAKE = "stake",
}
function isActive(feature: Features) {
diff --git a/apps/marginfi-v2-ui/src/utils/lstUtils.ts b/apps/marginfi-v2-ui/src/utils/lstUtils.ts
index 97e56f560e..298ae94932 100644
--- a/apps/marginfi-v2-ui/src/utils/lstUtils.ts
+++ b/apps/marginfi-v2-ui/src/utils/lstUtils.ts
@@ -17,10 +17,7 @@ export interface StakeData {
validatorVoteAddress: PublicKey;
}
-export async function fetchStakeAccounts(
- connection: Connection,
- walletAddress: PublicKey
-): Promise {
+export async function fetchStakeAccounts(connection: Connection, walletAddress: PublicKey): Promise {
const [parsedAccounts, currentEpoch] = await Promise.all([
connection.getParsedProgramAccounts(StakeProgram.programId, {
filters: [
@@ -42,8 +39,11 @@ export async function fetchStakeAccounts(
const activationEpoch = Number(parsedAccount.data.parsed.info.stake.delegation.activationEpoch);
const deactivationEpoch = Number(parsedAccount.data.parsed.info.stake.delegation.deactivationEpoch);
- let isActive = parsedAccount.data.parsed.type === "delegated" && currentEpoch.epoch >= activationEpoch + 1 && deactivationEpoch > currentEpoch.epoch;
-
+ let isActive =
+ parsedAccount.data.parsed.type === "delegated" &&
+ currentEpoch.epoch >= activationEpoch + 1 &&
+ deactivationEpoch > currentEpoch.epoch;
+
return {
address: pubkey,
lamports: new BN(account.lamports),
diff --git a/apps/marginfi-v2-ui/src/utils/mrgnActions.ts b/apps/marginfi-v2-ui/src/utils/mrgnActions.ts
index 7bc56e87ca..4cce457249 100644
--- a/apps/marginfi-v2-ui/src/utils/mrgnActions.ts
+++ b/apps/marginfi-v2-ui/src/utils/mrgnActions.ts
@@ -1,9 +1,5 @@
import { MarginfiAccountWrapper, MarginfiClient } from "@mrgnlabs/marginfi-client-v2";
-import {
- ExtendedBankInfo,
- FEE_MARGIN,
- ActionType,
-} from "@mrgnlabs/marginfi-v2-ui-state";
+import { ExtendedBankInfo, FEE_MARGIN, ActionType } from "@mrgnlabs/marginfi-v2-ui-state";
import { toast } from "react-toastify";
import { isWholePosition } from "./mrgnUtils";
diff --git a/apps/marginfi-v2-xnft/src/components/Portfolio/PortfolioOverview.tsx b/apps/marginfi-v2-xnft/src/components/Portfolio/PortfolioOverview.tsx
index ae6e908b24..4a6908ce7c 100644
--- a/apps/marginfi-v2-xnft/src/components/Portfolio/PortfolioOverview.tsx
+++ b/apps/marginfi-v2-xnft/src/components/Portfolio/PortfolioOverview.tsx
@@ -64,9 +64,7 @@ export function PortfolioOverview({ selectedAccount, accountSummary, points, isF
Points
- {isFirebaseConnected
- ? `${groupedNumberFormatterDyn.format(Math.round(points.totalPoints))} points`
- : "-"}
+ {isFirebaseConnected ? `${groupedNumberFormatterDyn.format(Math.round(points.totalPoints))} points` : "-"}
diff --git a/packages/marginfi-client-v2/src/models/balance.ts b/packages/marginfi-client-v2/src/models/balance.ts
index 58c4faacd2..df08101488 100644
--- a/packages/marginfi-client-v2/src/models/balance.ts
+++ b/packages/marginfi-client-v2/src/models/balance.ts
@@ -142,7 +142,10 @@ class Balance {
const lastUpdate = this.lastUpdate;
const period = new BigNumber(currentTimestamp - lastUpdate);
const emissionsRate = new BigNumber(bank.emissionsRate);
- const emissions = period.times(balanceAmount).times(emissionsRate).div(31_536_000 * Math.pow(10, bank.mintDecimals));
+ const emissions = period
+ .times(balanceAmount)
+ .times(emissionsRate)
+ .div(31_536_000 * Math.pow(10, bank.mintDecimals));
const emissionsReal = BigNumber.min(emissions, new BigNumber(bank.emissionsRemaining));
return emissionsReal;
From 9409b847ade5704824cccc0a6b4a0604238081ea Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Thu, 28 Sep 2023 20:09:42 +0800
Subject: [PATCH 019/351] fix(mfi-v2-ui): reset input after depositing stake
for LST
---
.../src/components/common/Staking/StakingCard/StakingCard.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingCard.tsx b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingCard.tsx
index 756866befd..9bea40b71e 100644
--- a/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingCard.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/StakingCard.tsx
@@ -349,7 +349,7 @@ export const StakingCard: FC = () => {
} finally {
await Promise.all([refresh(), fetchLstState()]);
setDepositOption((currentDepositOption) =>
- currentDepositOption.type === "stake" ? currentDepositOption : { ...currentDepositOption, amount: new BN(0) }
+ currentDepositOption.type === "stake" ? DEFAULT_DEPOSIT_OPTION : { ...currentDepositOption, amount: new BN(0) }
);
setOngoingAction(null);
}
From a0a41215752f2457b63ed4842bdc47c5e998bbf5 Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Thu, 28 Sep 2023 20:23:22 +0800
Subject: [PATCH 020/351] feat(mfi-v2-ui): staking slippage setting style
---
.../common/Staking/StakingCard/PrimaryButton.tsx | 2 +-
.../common/Staking/StakingCard/SettingsModal.tsx | 6 +++---
apps/marginfi-v2-ui/src/store/lstStore.ts | 10 ----------
3 files changed, 4 insertions(+), 14 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/PrimaryButton.tsx b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/PrimaryButton.tsx
index 6a52435d21..a593fd3073 100644
--- a/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/PrimaryButton.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/PrimaryButton.tsx
@@ -17,7 +17,7 @@ export const PrimaryButton: FC = ({ children, disabled, load
? "wavy-gradient-bg text-black"
: disabled
? "bg-[#808080] text-black"
- : "bg-[#e3e3e3] text-black cursor-pointer"
+ : "bg-[#e3e3e3] hover:bg-[#ccc] text-black cursor-pointer"
}
`}
>
diff --git a/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/SettingsModal.tsx b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/SettingsModal.tsx
index 756351f42b..5f2eaf1bd1 100644
--- a/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/SettingsModal.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/Staking/StakingCard/SettingsModal.tsx
@@ -41,7 +41,7 @@ export const SettingsModal: FC = ({
- Slippage Settings
+ Slippage Settings
{SLIPPAGE_PRESET.map((slippage, idx) => {
const displayText = Number(slippage) + "%";
@@ -49,8 +49,8 @@ export const SettingsModal: FC
= ({
return (
{
setLocalSlippage(slippage);
diff --git a/apps/marginfi-v2-ui/src/store/lstStore.ts b/apps/marginfi-v2-ui/src/store/lstStore.ts
index 90f1699adc..061abfeb58 100644
--- a/apps/marginfi-v2-ui/src/store/lstStore.ts
+++ b/apps/marginfi-v2-ui/src/store/lstStore.ts
@@ -1,4 +1,3 @@
-import { AnchorProvider } from "@coral-xyz/anchor";
import { vendor } from "@mrgnlabs/marginfi-client-v2";
import { ACCOUNT_SIZE, TOKEN_PROGRAM_ID, Wallet, aprToApy, uiToNative } from "@mrgnlabs/mrgn-common";
import { Connection, PublicKey } from "@solana/web3.js";
@@ -8,7 +7,6 @@ import { EPOCHS_PER_YEAR, StakeData, fetchStakeAccounts } from "~/utils";
import { TokenInfo, TokenInfoMap, TokenListContainer } from "@solana/spl-token-registry";
import { TokenAccount, TokenAccountMap, fetchBirdeyePrices } from "@mrgnlabs/marginfi-v2-ui-state";
import { persist } from "zustand/middleware";
-import { StakePoolProxyProgram, getStakePoolProxyProgram } from "~/utils/stakePoolProxy";
import BN from "bn.js";
const STAKEVIEW_APP_URL = "https://stakeview.app/apy/prev3.json";
@@ -49,7 +47,6 @@ interface LstState {
stakeAccounts: StakeData[];
solUsdValue: number | null;
slippagePct: SupportedSlippagePercent;
- stakePoolProxyProgram: StakePoolProxyProgram | null;
// Actions
fetchLstState: (args?: { connection?: Connection; wallet?: Wallet; isOverride?: boolean }) => Promise;
@@ -106,12 +103,6 @@ const stateCreator: StateCreator = (set, get) => ({
const wallet = args?.wallet || get().wallet;
- const provider = new AnchorProvider(connection, wallet ?? ({} as Wallet), {
- ...AnchorProvider.defaultOptions(),
- commitment: connection.commitment ?? AnchorProvider.defaultOptions().commitment,
- });
- const stakePoolProxyProgram = getStakePoolProxyProgram(provider);
-
let lstData: LstData | null = null;
let availableLamports: BN | null = null;
let tokenDataMap: TokenDataMap | null = null;
@@ -195,7 +186,6 @@ const stateCreator: StateCreator = (set, get) => ({
tokenDataMap,
stakeAccounts,
solUsdValue,
- stakePoolProxyProgram,
});
} catch (err) {
console.error("error refreshing state: ", err);
From e1f9dcee147698bbac9b2f13240a12977a4b699f Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Thu, 28 Sep 2023 20:26:25 +0800
Subject: [PATCH 021/351] feat(mfi-v2-ui): lighter font for staking description
---
apps/marginfi-v2-ui/src/pages/stake.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/pages/stake.tsx b/apps/marginfi-v2-ui/src/pages/stake.tsx
index bb320f81ca..a60a24bd74 100644
--- a/apps/marginfi-v2-ui/src/pages/stake.tsx
+++ b/apps/marginfi-v2-ui/src/pages/stake.tsx
@@ -74,16 +74,16 @@ const StakePage = () => {
-
+
$LST , by mrgn
-
+
Introducing the best way to get exposure to SOL. $LST is
built on mrgn's validator network and Jito's MEV rewards. For the first time,{" "}
$LST holders can get the best staking yield available on
Solana, combined with the biggest MEV rewards from Solana's trader network.
-
+
$LST has 0% commission. The yield goes to you. Stop paying
middlemen. Stop using underperforming validators. Stop missing out on MEV rewards.
From 593738644a7e678f1c6945fbb361c8e07da0e09d Mon Sep 17 00:00:00 2001
From: Kobe Leenders
Date: Fri, 29 Sep 2023 01:14:10 +0200
Subject: [PATCH 022/351] fix(mfi-v2-ui): fix merge issues & bugfixes
---
.../src/components/desktop/PageHeader.tsx | 2 +-
.../AssetCard/AssetCardPosition.tsx | 2 +-
.../MobileAssetsList/MobileAssetsList.tsx | 71 ++++++------
apps/marginfi-v2-ui/src/pages/index.tsx | 59 ++++------
apps/marginfi-v2-ui/src/pages/portfolio.tsx | 102 +++++++++++-------
apps/marginfi-v2-ui/src/pages/swap.tsx | 4 +-
6 files changed, 124 insertions(+), 116 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx b/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx
index 9b86ab8497..b7aeaa99aa 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx
@@ -6,7 +6,7 @@ interface PageHeaderProps {
const PageHeader: FC = ({ children }) => {
return (
-
+
);
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx
index 653a6832cc..6418fc1f7a 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx
@@ -16,7 +16,7 @@ export const AssetCardPosition: FC<{
Your position details
setIsCollapsed(!isCollapsed)}>
- {isCollapsed ? : }
+ {isCollapsed ? : }
{!isCollapsed && (
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
index 8402c4e554..d782fd96c5 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
@@ -1,8 +1,8 @@
-import React, { FC, useRef, useState } from "react";
+import React, { FC, useMemo, useRef, useState } from "react";
import Image from "next/image";
import { Skeleton, Switch, Typography } from "@mui/material";
-import { useMrgnlendStore, useUserProfileStore } from "~/store";
+import { useMrgnlendStore } from "~/store";
import { useWalletContext } from "~/hooks/useWalletContext";
import { BorrowLendToggle } from "~/components/common/AssetList";
import { MrgnTooltip } from "~/components/common/MrgnTooltip";
@@ -23,6 +23,19 @@ export const MobileAssetsList: FC = () => {
const inputRefs = useRef
>({});
const [isInLendingMode, setIsInLendingMode] = useState(true);
+ const globalBanks = useMemo(
+ () =>
+ sortedBanks &&
+ sortedBanks.filter((b) => !b.info.state.isIsolated).filter((b) => (isFiltered ? b.isActive : true)),
+ [sortedBanks, isFiltered]
+ );
+
+ const isolatedBanks = useMemo(
+ () =>
+ sortedBanks && sortedBanks.filter((b) => b.info.state.isIsolated).filter((b) => (isFiltered ? b.isActive : true)),
+ [sortedBanks, isFiltered]
+ );
+
return (
<>
@@ -35,11 +48,9 @@ export const MobileAssetsList: FC = () => {
Global pool
- {sortedBanks
- .filter((b) => !b.info.state.isIsolated)
- .filter((b) => (isFiltered ? b.isActive : true))
- .map((bank, i) =>
- isStoreInitialized ? (
+ {isStoreInitialized ? (
+ globalBanks.length > 0 ? (
+ globalBanks.map((bank, i) => (
{
marginfiAccount={selectedAccount}
inputRefs={inputRefs}
/>
- ) : (
-
- )
- )}
+ ))
+ ) : (
+
+ No {isInLendingMode ? "lending" : "borrowing"} {isFiltered ? "positions" : "pools"} found.
+
+ )
+ ) : (
+
+ )}
@@ -81,11 +91,9 @@ export const MobileAssetsList: FC = () => {
- {sortedBanks
- .filter((b) => b.info.state.isIsolated)
- .filter((b) => (isFiltered ? b.isActive : true))
- .map((bank, i) =>
- isStoreInitialized ? (
+ {isStoreInitialized ? (
+ isolatedBanks.length > 0 ? (
+ isolatedBanks.map((bank, i) => (
{
marginfiAccount={selectedAccount}
inputRefs={inputRefs}
/>
- ) : (
-
- )
- )}
+ ))
+ ) : (
+
+ No {isInLendingMode ? "lending" : "borrowing"} {isFiltered ? "positions" : "pools"} found.
+
+ )
+ ) : (
+
+ )}
>
diff --git a/apps/marginfi-v2-ui/src/pages/index.tsx b/apps/marginfi-v2-ui/src/pages/index.tsx
index 3e81cdf384..5ab2b44fcd 100644
--- a/apps/marginfi-v2-ui/src/pages/index.tsx
+++ b/apps/marginfi-v2-ui/src/pages/index.tsx
@@ -12,49 +12,28 @@ import { PageHeader } from "~/components/desktop/PageHeader";
import { OverlaySpinner } from "~/components/desktop/OverlaySpinner";
import { Desktop, Mobile } from "~/mediaQueries";
-const DesktopAccountSummary = () => {
- const DesktopAccountSummary = dynamic(
- async () => (await import("~/components/desktop/DesktopAccountSummary")).DesktopAccountSummary,
- {
- ssr: false,
- }
- );
-
- return ;
-};
-
-const AssetsList = () => {
- const AssetsList = dynamic(async () => (await import("~/components/desktop/AssetsList")).AssetsList, { ssr: false });
- return ;
-};
-
-const UserPositions = () => {
- const UserPositions = dynamic(async () => (await import("~/components/desktop/UserPositions")).UserPositions, {
+const DesktopAccountSummary = dynamic(
+ async () => (await import("~/components/desktop/DesktopAccountSummary")).DesktopAccountSummary,
+ {
ssr: false,
- });
+ }
+);
+const AssetsList = dynamic(async () => (await import("~/components/desktop/AssetsList")).AssetsList, { ssr: false });
- return ;
-};
+const UserPositions = dynamic(async () => (await import("~/components/desktop/UserPositions")).UserPositions, {
+ ssr: false,
+});
-const MobileAccountSummary = () => {
- const MobileAccountSummary = dynamic(
- async () => (await import("~/components/mobile/MobileAccountSummary")).MobileAccountSummary,
- {
- ssr: false,
- }
- );
- return ;
-};
+const MobileAccountSummary = dynamic(
+ async () => (await import("~/components/mobile/MobileAccountSummary")).MobileAccountSummary,
+ {
+ ssr: false,
+ }
+);
-const MobileAssetsList = () => {
- const MobileAssetsList = dynamic(
- async () => (await import("~/components/mobile/MobileAssetsList")).MobileAssetsList,
- {
- ssr: false,
- }
- );
- return ;
-};
+const MobileAssetsList = dynamic(async () => (await import("~/components/mobile/MobileAssetsList")).MobileAssetsList, {
+ ssr: false,
+});
const Home = () => {
const { walletAddress, wallet, isOverride } = useWalletContext();
@@ -122,7 +101,7 @@ const Home = () => {
-
+
diff --git a/apps/marginfi-v2-ui/src/pages/portfolio.tsx b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
index d0b59252f5..2f31b3d12d 100644
--- a/apps/marginfi-v2-ui/src/pages/portfolio.tsx
+++ b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
@@ -18,7 +18,7 @@ import {
PointsConnectWallet,
} from "~/components/desktop/Points";
import { AssetCard } from "~/components/mobile/MobileAssetsList/AssetCard";
-import { Button, Skeleton } from "@mui/material";
+import { Button, Skeleton, Typography } from "@mui/material";
const PortfolioPage = () => {
const { connected, wallet, isOverride } = useWalletContext();
@@ -41,6 +41,30 @@ const PortfolioPage = () => {
const referralCode = useMemo(() => routerQuery.referralCode as string | undefined, [routerQuery.referralCode]);
+ const lendingBanks = useMemo(
+ () =>
+ sortedBanks &&
+ sortedBanks
+ .filter((b) => b.info.rawBank.config.assetWeightInit.toNumber() > 0)
+ .filter((b) => b.isActive && b.position.isLending)
+ .sort(
+ (a, b) => b.info.state.totalDeposits * b.info.state.price - a.info.state.totalDeposits * a.info.state.price
+ ),
+ [sortedBanks]
+ );
+
+ const borrowingBanks = useMemo(
+ () =>
+ sortedBanks &&
+ sortedBanks
+ .filter((b) => b.info.rawBank.config.assetWeightInit.toNumber() > 0)
+ .filter((b) => b.isActive && !b.position.isLending)
+ .sort(
+ (a, b) => b.info.state.totalDeposits * b.info.state.price - a.info.state.totalDeposits * a.info.state.price
+ ),
+ [sortedBanks]
+ );
+
useEffect(() => {
setIsRefreshingStore(true);
fetchMrgnlendState({ marginfiConfig: config.mfiConfig, connection, wallet, isOverride }).catch(console.error);
@@ -56,7 +80,7 @@ const PortfolioPage = () => {
return (
<>
Portfolio
-
+
{!connected ? (
@@ -122,59 +146,57 @@ const PortfolioPage = () => {
-
-
Lending positions
-
- {sortedBanks
- .filter((b) => b.isActive)
- .map((bank, i) =>
- isStoreInitialized ? (
-
+ {sortedBanks && (
+
+
Lending positions
+
+ {isStoreInitialized ? (
+ lendingBanks.length > 0 ? (
+ lendingBanks.map((bank) => (
+
+ ))
) : (
-
+
+ No lending positions found.
+
)
+ ) : (
+
)}
+
-
+ )}
Borrowing positions
- {sortedBanks
- .filter((b) => b.isActive)
- .map((bank, i) =>
- isStoreInitialized ? (
+ {isStoreInitialized ? (
+ borrowingBanks.length > 0 ? (
+ borrowingBanks.map((bank) => (
- ) : (
-
- )
- )}
+ ))
+ ) : (
+
+ No borrowing positions found.
+
+ )
+ ) : (
+
+ )}
diff --git a/apps/marginfi-v2-ui/src/pages/swap.tsx b/apps/marginfi-v2-ui/src/pages/swap.tsx
index a3d1ff7376..0a578ab5d5 100644
--- a/apps/marginfi-v2-ui/src/pages/swap.tsx
+++ b/apps/marginfi-v2-ui/src/pages/swap.tsx
@@ -34,13 +34,13 @@ const SwapPage = () => {
-
+
>
);
From 4969598c2207876f421d844c0e5190a33ca94e27 Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Fri, 29 Sep 2023 16:42:17 +0800
Subject: [PATCH 023/351] feat(mfi-v2-ui): design touch-ups and rehydration fix
---
.../common/AssetList/BorrowLendToggle.tsx | 130 ------------------
.../src/components/common/AssetList/index.ts | 1 -
.../components/common/MrgnContainedSwitch.tsx | 54 ++++++++
.../components/common/MrgnLabeledSwitch.tsx | 82 +++++++++++
.../src/components/common/index.ts | 3 +
.../desktop/AssetsList/AssetsList.tsx | 11 +-
.../src/components/desktop/PageHeader.tsx | 6 +-
.../MobileAccountSummary.tsx | 12 --
.../MobileAssetsList/AssetCard/AssetCard.tsx | 2 +-
.../MobileAssetsList/MobileAssetsList.tsx | 33 +++--
.../mobile/MobileNavbar/MobileNavbar.tsx | 4 +-
apps/marginfi-v2-ui/src/mediaQueries.ts | 4 +-
apps/marginfi-v2-ui/src/pages/_app.tsx | 7 +-
apps/marginfi-v2-ui/src/pages/index.tsx | 10 +-
apps/marginfi-v2-ui/src/pages/portfolio.tsx | 16 ++-
apps/marginfi-v2-ui/src/pages/swap.tsx | 4 +-
16 files changed, 192 insertions(+), 187 deletions(-)
delete mode 100644 apps/marginfi-v2-ui/src/components/common/AssetList/BorrowLendToggle.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/common/MrgnContainedSwitch.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/common/MrgnLabeledSwitch.tsx
create mode 100644 apps/marginfi-v2-ui/src/components/common/index.ts
diff --git a/apps/marginfi-v2-ui/src/components/common/AssetList/BorrowLendToggle.tsx b/apps/marginfi-v2-ui/src/components/common/AssetList/BorrowLendToggle.tsx
deleted file mode 100644
index 20b198aa23..0000000000
--- a/apps/marginfi-v2-ui/src/components/common/AssetList/BorrowLendToggle.tsx
+++ /dev/null
@@ -1,130 +0,0 @@
-import { Badge, styled, Switch, SwitchProps } from "@mui/material";
-import { Dispatch, SetStateAction } from "react";
-import { useUserProfileStore } from "~/store";
-
-type PaddingConfigs = {
- left: string;
- right: string;
-};
-
-interface BorrowLendToggleProps extends SwitchProps {
- isInLendingMode: boolean;
- setIsInLendingMode: Dispatch
>;
- leftTitle?: string;
- rightTitle?: string;
- paddingConfigs?: PaddingConfigs;
-}
-
-const BorrowLendToggle = styled(
- ({
- isInLendingMode,
- setIsInLendingMode,
- leftTitle = "Lend",
- rightTitle = "Borrow",
- paddingConfigs = {
- left: "27px",
- right: "18px",
- },
- ...switchProps
- }: BorrowLendToggleProps) => {
- const showBadges = useUserProfileStore((state) => state.showBadges);
- const handleChange = () => {
- setIsInLendingMode((prev) => !prev);
- };
-
- return (
-
-
-
- );
- }
-)(
- ({
- disabled,
- leftTitle = "Lend",
- rightTitle = "Borrow",
- paddingConfigs = {
- left: "27px",
- right: "18px",
- },
- }) => ({
- width: 166.34, //
- height: 52.04,
- ...(disabled ? { cursor: "not-allowed" } : {}),
- padding: 0,
- borderRadius: 43.61,
- backgroundColor: "rgba(0,0,0,1)", // @todo currently transparency is at 1 to hide the center thing that i can't make disappear
- border: "solid rgba(255, 255, 255, 0.20) 1px",
- display: "flex",
- justifyContent: "center",
- alignItems: "center",
- paddingLeft: paddingConfigs.left,
- paddingRight: paddingConfigs.right,
- "&:after": {
- content: `'${rightTitle}'`,
- zIndex: 10,
- pointerEvents: "none",
- fontFamily: "Aeonik Pro",
- fontWeight: 500,
- },
- "&:before": {
- content: `'${leftTitle}'`,
- zIndex: 10,
- pointerEvents: "none",
- fontFamily: "Aeonik Pro",
- fontWeight: 500,
- },
- "& .MuiSwitch-switchBase": {
- padding: 0,
- marginTop: "0.28rem",
- marginLeft: "0.3rem",
- width: "48%",
- height: "80%",
- borderRadius: 43.61,
- display: "flex",
- justifyContent: "center",
- transitionDuration: "300ms", // ios transition time
- "&.Mui-checked": {
- transform: "translateX(4.66rem)",
- color: "#fff",
- "& + .MuiSwitch-track": {
- backgroundColor: "rgba(0,0,0,0)",
- opacity: 0,
- border: 0,
- },
- "&.Mui-disabled + .MuiSwitch-track": {
- opacity: 0.5,
- },
- },
- },
- "& .MuiSwitch-thumb": {
- boxSizing: "border-box",
- width: "100%",
- height: "100%",
- borderRadius: 43.61,
- backgroundColor: "#2F373D",
- border: "solid rgba(255, 255, 255, 0.2) 1px",
- },
- })
-);
-
-export { BorrowLendToggle };
diff --git a/apps/marginfi-v2-ui/src/components/common/AssetList/index.ts b/apps/marginfi-v2-ui/src/components/common/AssetList/index.ts
index b587432a91..cce6f02e25 100644
--- a/apps/marginfi-v2-ui/src/components/common/AssetList/index.ts
+++ b/apps/marginfi-v2-ui/src/components/common/AssetList/index.ts
@@ -1,3 +1,2 @@
-export * from "./BorrowLendToggle";
export * from "./AssetRowAction";
export * from "./AssetRowInputBox";
diff --git a/apps/marginfi-v2-ui/src/components/common/MrgnContainedSwitch.tsx b/apps/marginfi-v2-ui/src/components/common/MrgnContainedSwitch.tsx
new file mode 100644
index 0000000000..a2604e2a4f
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/common/MrgnContainedSwitch.tsx
@@ -0,0 +1,54 @@
+import { Switch, SwitchProps, styled } from "@mui/material";
+
+const MrgnContainedSwitch = styled((switchProps: SwitchProps) => )(({checked}) => ({
+ padding: 8,
+ marginLeft: -8,
+ "& .MuiSwitch-track": {
+ borderRadius: 22 / 2,
+ opacity: 1,
+ backgroundColor: "#22282C",
+ "&:before, &:after": {
+ content: '""',
+ position: "absolute",
+ top: "50%",
+ transform: "translateY(-50%)",
+ width: 16,
+ height: 16,
+ },
+ "&:before": {
+ backgroundImage: `url('data:image/svg+xml;utf8, ')`,
+ left: 12,
+ },
+ "&:after": {
+ backgroundImage: `url('data:image/svg+xml;utf8, ')`,
+ right: 12,
+ },
+ },
+ "& .MuiSwitch-switchBase": {
+ height: "100%",
+ "& + .MuiSwitch-track": {
+ backgroundColor: "#22282C",
+ height: "100%",
+ },
+ "&.Mui-checked + .MuiSwitch-track": {
+ opacity: 1,
+ backgroundColor: "#DCE85D",
+ },
+ },
+ "& .MuiSwitch-thumb": {
+ boxShadow: "none",
+ width: 16,
+ height: 16,
+ margin: 2,
+ backgroundColor: "#09090B",
+ },
+ "&:hover .MuiSwitch-thumb": {
+ backgroundColor: "#09090B",
+ },
+}));
+
+export { MrgnContainedSwitch };
diff --git a/apps/marginfi-v2-ui/src/components/common/MrgnLabeledSwitch.tsx b/apps/marginfi-v2-ui/src/components/common/MrgnLabeledSwitch.tsx
new file mode 100644
index 0000000000..70b78e1e6f
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/common/MrgnLabeledSwitch.tsx
@@ -0,0 +1,82 @@
+import { styled, Switch, SwitchProps } from "@mui/material";
+
+interface MrgnLabeledSwitchProps extends SwitchProps {
+ labelLeft: string;
+ labelRight: string;
+ trackColor?: string;
+ thumbColor?: string;
+}
+
+const MrgnLabeledSwitch = styled(({ onChange, ...switchProps }: MrgnLabeledSwitchProps) => {
+ return (
+
+ );
+})(({ disabled, labelLeft, labelRight,trackColor, thumbColor }) => ({
+ width: "100%",
+ height: "100%",
+ ...(disabled ? { cursor: "not-allowed" } : {}),
+ padding: 0,
+ backgroundColor: trackColor ?? "#22282C", // @todo currently transparency is at 1 to hide the center thing that i can't make disappear
+ borderRadius: 4,
+ display: "flex",
+ justifyContent: "center",
+ alignItems: "center",
+ fontFamily: "Aeonik Pro",
+ fontWeight: 400,
+ "&:before": {
+ content: `"${labelLeft}"`,
+ width: "50%",
+ height: "100%",
+ display: "flex",
+ justifyContent: "center",
+ alignItems: "center",
+ zIndex: 10,
+ pointerEvents: "none",
+ },
+ "&:after": {
+ content: `"${labelRight}"`,
+ width: "50%",
+ height: "100%",
+ display: "flex",
+ justifyContent: "center",
+ alignItems: "center",
+ zIndex: 10,
+ pointerEvents: "none",
+ },
+ "& .MuiSwitch-switchBase": {
+ padding: "0.3rem",
+ width: "50%",
+ height: "100%",
+ display: "flex",
+ justifyContent: "center",
+ transitionDuration: "200ms",
+ transform: "translateX(0%)",
+ "& + .MuiSwitch-track": {
+ opacity: 0,
+ width: 0,
+ height: "100%",
+ },
+ "&.Mui-disabled + .MuiSwitch-track": {
+ opacity: 0.5,
+ },
+ "&.Mui-checked": {
+ transform: "translateX(100%)",
+ },
+ },
+ "&:hover .MuiSwitch-thumb": {
+ backgroundColor: "#1B1E20",
+ },
+ "& .MuiSwitch-thumb": {
+ boxSizing: "border-box",
+ width: "100%",
+ height: "100%",
+ backgroundColor: thumbColor ?? "#131618",
+ borderRadius: 3,
+ },
+}));
+
+export { MrgnLabeledSwitch as MrgnSwitch };
diff --git a/apps/marginfi-v2-ui/src/components/common/index.ts b/apps/marginfi-v2-ui/src/components/common/index.ts
new file mode 100644
index 0000000000..d0234e61aa
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/common/index.ts
@@ -0,0 +1,3 @@
+export * from "./MrgnLabeledSwitch";
+export * from "./MrgnTooltip";
+export * from "./MrgnContainedSwitch";
diff --git a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
index 590c837195..84972ed54a 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/AssetsList/AssetsList.tsx
@@ -6,10 +6,10 @@ import Typography from "@mui/material/Typography";
import { useMrgnlendStore, useUserProfileStore } from "~/store";
import { useWalletContext } from "~/hooks/useWalletContext";
-import { BorrowLendToggle } from "~/components/common/AssetList/BorrowLendToggle";
import { LoadingAsset, AssetRow } from "./AssetRow";
import { MrgnTooltip } from "~/components/common/MrgnTooltip";
+import { MrgnSwitch } from "~/components/common";
const AssetsList: FC = () => {
// const { selectedAccount, nativeSolBalance } = useStore();
@@ -96,7 +96,14 @@ const AssetsList: FC = () => {
return (
<>
-
+
+ setIsInLendingMode(!isInLendingMode)}
+ />
+
diff --git a/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx b/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx
index b7aeaa99aa..008fd7a80a 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/PageHeader.tsx
@@ -1,4 +1,5 @@
import { FC, ReactNode } from "react";
+import { WalletButton } from "../common/Navbar";
interface PageHeaderProps {
children: ReactNode;
@@ -7,7 +8,10 @@ interface PageHeaderProps {
const PageHeader: FC
= ({ children }) => {
return (
);
};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
index c092a55e19..d1f71d81e0 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
@@ -23,18 +23,6 @@ const AccountSummary: FC = () => {
/>
-
- {/*
- {connected && (
-
- Your account
-
-
- )}
-
*/}
);
};
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
index 427034ee53..85c3fc833a 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCard.tsx
@@ -84,7 +84,7 @@ export const AssetCard: FC<{
);
return (
-
+
{
return (
<>
-
-
-
-
-
-
Filter my positions
+
+
+ setIsInLendingMode(!isInLendingMode)}
+ />
+
+
-
+
Global pool
{isStoreInitialized ? (
@@ -71,7 +80,7 @@ export const MobileAssetsList: FC = () => {
)}
-
+
Isolated pool
{
return (
-
-
+
+
= ({ children }) => {
- const isDesktop = useMediaQuery({ minWidth: 992 });
+ const isDesktop = useMediaQuery({ minWidth: 768 });
return isDesktop ? children : null;
};
const Mobile: FC<{ children: any }> = ({ children }) => {
- const isMobile = useMediaQuery({ maxWidth: 992 });
+ const isMobile = useMediaQuery({ maxWidth: 768 });
return isMobile ? children : null;
};
diff --git a/apps/marginfi-v2-ui/src/pages/_app.tsx b/apps/marginfi-v2-ui/src/pages/_app.tsx
index 03861dd677..6a3d410f33 100644
--- a/apps/marginfi-v2-ui/src/pages/_app.tsx
+++ b/apps/marginfi-v2-ui/src/pages/_app.tsx
@@ -78,13 +78,8 @@ const MyApp = ({ Component, pageProps }: AppProps) => {
-
-
+
diff --git a/apps/marginfi-v2-ui/src/pages/index.tsx b/apps/marginfi-v2-ui/src/pages/index.tsx
index 5ab2b44fcd..e5e6ffc819 100644
--- a/apps/marginfi-v2-ui/src/pages/index.tsx
+++ b/apps/marginfi-v2-ui/src/pages/index.tsx
@@ -24,13 +24,6 @@ const UserPositions = dynamic(async () => (await import("~/components/desktop/Us
ssr: false,
});
-const MobileAccountSummary = dynamic(
- async () => (await import("~/components/mobile/MobileAccountSummary")).MobileAccountSummary,
- {
- ssr: false,
- }
-);
-
const MobileAssetsList = dynamic(async () => (await import("~/components/mobile/MobileAssetsList")).MobileAssetsList, {
ssr: false,
});
@@ -101,8 +94,7 @@ const Home = () => {
-
-
+
diff --git a/apps/marginfi-v2-ui/src/pages/portfolio.tsx b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
index 2f31b3d12d..bfd504c734 100644
--- a/apps/marginfi-v2-ui/src/pages/portfolio.tsx
+++ b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
@@ -43,26 +43,28 @@ const PortfolioPage = () => {
const lendingBanks = useMemo(
() =>
- sortedBanks &&
+ sortedBanks && isStoreInitialized ?
sortedBanks
- .filter((b) => b.info.rawBank.config.assetWeightInit.toNumber() > 0)
+ .filter((b) => {
+ console.log(b.info.rawBank.config.assetWeightInit, typeof b.info.rawBank.config.assetWeightInit)
+ return b.info.rawBank.config.assetWeightInit.toNumber() > 0})
.filter((b) => b.isActive && b.position.isLending)
.sort(
(a, b) => b.info.state.totalDeposits * b.info.state.price - a.info.state.totalDeposits * a.info.state.price
- ),
- [sortedBanks]
+ ) : [],
+ [sortedBanks, isStoreInitialized]
);
const borrowingBanks = useMemo(
() =>
- sortedBanks &&
+ sortedBanks && isStoreInitialized ?
sortedBanks
.filter((b) => b.info.rawBank.config.assetWeightInit.toNumber() > 0)
.filter((b) => b.isActive && !b.position.isLending)
.sort(
(a, b) => b.info.state.totalDeposits * b.info.state.price - a.info.state.totalDeposits * a.info.state.price
- ),
- [sortedBanks]
+ ) : [],
+ [sortedBanks, isStoreInitialized]
);
useEffect(() => {
diff --git a/apps/marginfi-v2-ui/src/pages/swap.tsx b/apps/marginfi-v2-ui/src/pages/swap.tsx
index 0a578ab5d5..dd4a24053c 100644
--- a/apps/marginfi-v2-ui/src/pages/swap.tsx
+++ b/apps/marginfi-v2-ui/src/pages/swap.tsx
@@ -24,7 +24,7 @@ const SwapPage = () => {
swap
-
+
Powered
{/* Different components here by word so spacing can be the same */}
by
@@ -34,7 +34,7 @@ const SwapPage = () => {
-
+
Zero fees.
Always.
From 3a943483e26c447d6c17915ffe9ab13a9a8ed47a Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Fri, 29 Sep 2023 16:57:58 +0800
Subject: [PATCH 024/351] feat(mfi-v2-ui): breathing room and button sizing
---
.../src/components/common/AssetList/AssetRowAction.tsx | 2 +-
.../src/components/common/AssetList/AssetRowInputBox.tsx | 3 ++-
.../mobile/MobileAssetsList/AssetCard/AssetCardActions.tsx | 2 +-
.../mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx | 4 ++--
.../components/mobile/MobileAssetsList/MobileAssetsList.tsx | 4 ++--
5 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowAction.tsx b/apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowAction.tsx
index 4a91eec146..7dc50d4290 100644
--- a/apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowAction.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/AssetList/AssetRowAction.tsx
@@ -8,7 +8,7 @@ interface AssetRowActionProps extends ButtonProps {
const AssetRowAction: FC
= ({ children, disabled, bgColor, ...otherProps }) => (
= ({
);
return (
-
+
-
+
Your Balance
-
{userBalance + " " + bank.meta.tokenSymbol}
+
{groupedNumberFormatterDyn.format(userBalance) + " " + bank.meta.tokenSymbol}
);
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
index e0229a217a..b4a0bb5d0a 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/MobileAssetsList.tsx
@@ -55,8 +55,8 @@ export const MobileAssetsList: FC = () => {
-
Global pool
-
+
Global pool
+
{isStoreInitialized ? (
globalBanks.length > 0 ? (
globalBanks.map((bank, i) => (
From 90b71002c79a3c81b72b54186e8b564dd41a9e75 Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Fri, 29 Sep 2023 17:22:16 +0800
Subject: [PATCH 025/351] feat(mfi-v2-ui): asset card stats alignment
---
.../mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
index 886893f5b6..3999cb0e3a 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
@@ -27,7 +27,7 @@ export const AssetCardStats: FC<{
isInLendingMode,
}) => {
return (
-
+
{isInLendingMode ? "Weight" : "LTV"}
From 39fefa389a861513f1036356ad5c98d705ade179 Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Fri, 29 Sep 2023 17:24:40 +0800
Subject: [PATCH 026/351] feat(mfi-v2-ui): wallet balance wording
---
.../mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
index 3999cb0e3a..f90b46f596 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardStats.tsx
@@ -88,7 +88,7 @@ export const AssetCardStats: FC<{
-
Your Balance
+
Wallet Balance
{groupedNumberFormatterDyn.format(userBalance) + " " + bank.meta.tokenSymbol}
From 8fc6e08905319cabd44df0529e5631f1bbd42d90 Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Fri, 29 Sep 2023 17:39:06 +0800
Subject: [PATCH 027/351] feat(mfi-v2-ui): logo alignment + easier position
reveal click
---
.../mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx | 6 +++---
.../mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
index cdca305912..68659cbc6c 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
@@ -14,8 +14,8 @@ export const AssetCardHeader: FC<{
rateAP: string;
}> = ({ bank, isInLendingMode, rateAP }) => {
return (
-
-
+
+
{bank.meta.tokenLogoUri && (
@@ -52,7 +52,7 @@ export const AssetCardHeader: FC<{
)}
-
{rateAP.concat(...[" ", isInLendingMode ? "APY" : "APR"])}
+
{rateAP.concat(...[" ", isInLendingMode ? "APY" : "APR"])}
);
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx
index 6418fc1f7a..92679a6d3f 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardPosition.tsx
@@ -13,9 +13,9 @@ export const AssetCardPosition: FC<{
return (
-
+
setIsCollapsed(!isCollapsed)}>
Your position details
-
setIsCollapsed(!isCollapsed)}>
+
{isCollapsed ? : }
From 76705bbfcb00e873cacd5663d9023fc01c5eb934 Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Fri, 29 Sep 2023 17:49:53 +0800
Subject: [PATCH 028/351] feat(mfi-v2-ui): reduce horizontal margin in
portfolio
---
.../common/AccountSummary/GlobalStats.tsx | 89 ++++++++++---------
.../MobileAccountSummary.tsx | 1 -
apps/marginfi-v2-ui/src/pages/portfolio.tsx | 2 +-
3 files changed, 47 insertions(+), 45 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx b/apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx
index b24f0ef63e..08948f64a3 100644
--- a/apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/AccountSummary/GlobalStats.tsx
@@ -8,6 +8,7 @@ import { numeralFormatter } from "@mrgnlabs/mrgn-common";
import { MrgnTooltip } from "~/components/common/MrgnTooltip";
import styles from "./style.module.css";
+import { Desktop } from "~/mediaQueries";
interface GlobalStatsProps {
deposits: number;
@@ -19,7 +20,7 @@ interface GlobalStatsProps {
const GlobalStats: FC
= ({ borrows, deposits, pointsTotal, tvl }) => {
return (
-
+
= ({ borrows, deposits, pointsTotal, tvl
)}
-
-
-
- Points
-
-
-
- Points
-
-
-
- Learn more about points{" "}
-
-
here
-
- .
+
+
+
+
+ Points
+
+
+
+ Points
+
+
+
+ Learn more about points{" "}
+
+ here
+
+ .
+
-
- >
- }
- placement="top"
- >
-
-
-
-
-
-
-
- {pointsTotal ? (
- numeralFormatter(pointsTotal)
- ) : (
-
- )}
-
-
+ >
+ }
+ placement="top"
+ >
+
+
+
+
+
+
+
+ {pointsTotal ? (
+ numeralFormatter(pointsTotal)
+ ) : (
+
+ )}
+
+
+
);
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
index d1f71d81e0..0aa0fb1592 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAccountSummary/MobileAccountSummary.tsx
@@ -14,7 +14,6 @@ const AccountSummary: FC = () => {
- {/*
Global stats */}
{
return (
<>
Portfolio
-
+
{!connected ? (
From 7a2d5c0c29e4d2c096a92d3dea8988f7c29e3075 Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Fri, 29 Sep 2023 18:15:10 +0800
Subject: [PATCH 029/351] feat(mfi-v2-ui): emission logo alignment
---
.../mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
index 68659cbc6c..fb1afc4c18 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
@@ -26,7 +26,7 @@ export const AssetCardHeader: FC<{
{usdFormatter.format(bank.info.state.price)}
-
+
{bank.meta.tokenSymbol === "UXD" && isInLendingMode && (
From d4ea56fcf234109e4d239602699c7a64a977afca Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Fri, 29 Sep 2023 18:16:47 +0800
Subject: [PATCH 030/351] fix(mfi-v2-ui): force circular logo
---
.../mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
index fb1afc4c18..3bf5e3c71e 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobileAssetsList/AssetCard/AssetCardHeader.tsx
@@ -18,7 +18,7 @@ export const AssetCardHeader: FC<{
{bank.meta.tokenLogoUri && (
-
+
)}
From 6a2f687c88fe1089078e0c4bb7201333ca1bcd03 Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Fri, 29 Sep 2023 18:18:36 +0800
Subject: [PATCH 031/351] chore(mfi-v2-ui): remove logs
---
.../MobilePortfolioOverview/MobilePortfolioOverview.tsx | 1 -
apps/marginfi-v2-ui/src/pages/portfolio.tsx | 4 +---
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
index 4d95166988..7239b42e4d 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
@@ -17,7 +17,6 @@ export const MobilePortfolioOverview: FC = () => {
]);
const healthFactor = useMemo(() => {
- console.log({ selectedAccount });
if (selectedAccount) {
const { assets, liabilities } = selectedAccount.computeHealthComponents(MarginRequirementType.Maintenance);
return assets.isZero() ? 100 : assets.minus(liabilities).dividedBy(assets).toNumber() * 100;
diff --git a/apps/marginfi-v2-ui/src/pages/portfolio.tsx b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
index 02e077be04..4baa165fb2 100644
--- a/apps/marginfi-v2-ui/src/pages/portfolio.tsx
+++ b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
@@ -45,9 +45,7 @@ const PortfolioPage = () => {
() =>
sortedBanks && isStoreInitialized ?
sortedBanks
- .filter((b) => {
- console.log(b.info.rawBank.config.assetWeightInit, typeof b.info.rawBank.config.assetWeightInit)
- return b.info.rawBank.config.assetWeightInit.toNumber() > 0})
+ .filter((b) => b.info.rawBank.config.assetWeightInit.toNumber() > 0)
.filter((b) => b.isActive && b.position.isLending)
.sort(
(a, b) => b.info.state.totalDeposits * b.info.state.price - a.info.state.totalDeposits * a.info.state.price
From 51ef93db6309493cca558f8dbb0463e8746e7015 Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Sat, 30 Sep 2023 14:38:41 +0800
Subject: [PATCH 032/351] feat(mfi-v2-ui): rewards collection on mobile
---
.../desktop/DesktopNavbar/DesktopNavbar.tsx | 12 +-----
.../desktop/Points/PointsOverview.tsx | 2 -
.../src/components/mobile/EmissionsBanner.tsx | 42 +++++++++++++++++++
.../MobilePortfolioOverview.tsx | 2 +-
.../SemiCircleProgress.tsx | 1 -
apps/marginfi-v2-ui/src/pages/portfolio.tsx | 6 ++-
apps/marginfi-v2-ui/src/pages/swap.tsx | 2 +-
apps/marginfi-v2-ui/src/styles/globals.css | 29 +++++++++++++
apps/marginfi-v2-ui/src/utils/mrgnActions.ts | 15 +++++++
9 files changed, 94 insertions(+), 17 deletions(-)
create mode 100644 apps/marginfi-v2-ui/src/components/mobile/EmissionsBanner.tsx
diff --git a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
index 248efa9c12..feac6be445 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/DesktopNavbar/DesktopNavbar.tsx
@@ -15,6 +15,7 @@ import { PublicKey, Transaction } from "@solana/web3.js";
import { useConnection } from "@solana/wallet-adapter-react";
import { toast } from "react-toastify";
import { EMISSION_MINT_INFO_MAP } from "../AssetsList/AssetRow";
+import { collectRewardsBatch } from "~/utils";
// @todo implement second pretty navbar row
const DesktopNavbar: FC = () => {
@@ -289,16 +290,7 @@ const DesktopNavbar: FC = () => {
}`}
onClick={async () => {
if (!wallet || !selectedAccount || bankAddressesWithEmissions.length === 0) return;
- const tx = new Transaction();
- const ixs = [];
- const signers = [];
- for (const bankAddress of bankAddressesWithEmissions) {
- const ix = await selectedAccount.makeWithdrawEmissionsIx(bankAddress);
- ixs.push(...ix.instructions);
- signers.push(ix.keys);
- }
- tx.add(...ixs);
- await processTransaction(connection, wallet, tx);
+ await collectRewardsBatch(connection, wallet, selectedAccount, bankAddressesWithEmissions)
toast.success("Withdrawal successful");
}}
>
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx
index 760f0e4e4e..a3eccb5e49 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsOverview.tsx
@@ -1,10 +1,8 @@
import React, { FC } from "react";
import Image from "next/image";
import { Card, CardContent, Skeleton, Typography } from "@mui/material";
-
import { numeralFormatter, groupedNumberFormatterDyn } from "@mrgnlabs/mrgn-common";
import { UserPointsData } from "@mrgnlabs/marginfi-v2-ui-state";
-
import { MrgnTooltip } from "~/components/common/MrgnTooltip";
interface PointsOverviewProps {
diff --git a/apps/marginfi-v2-ui/src/components/mobile/EmissionsBanner.tsx b/apps/marginfi-v2-ui/src/components/mobile/EmissionsBanner.tsx
new file mode 100644
index 0000000000..4cf3df2ba5
--- /dev/null
+++ b/apps/marginfi-v2-ui/src/components/mobile/EmissionsBanner.tsx
@@ -0,0 +1,42 @@
+import { useConnection } from "@solana/wallet-adapter-react";
+import { PublicKey } from "@solana/web3.js";
+import { FC, useMemo } from "react";
+import { useWalletContext } from "~/hooks/useWalletContext";
+import { useMrgnlendStore } from "~/store";
+import { collectRewardsBatch } from "~/utils";
+import { EMISSION_MINT_INFO_MAP } from "../desktop/AssetsList/AssetRow";
+import { toast } from "react-toastify";
+
+const EmissionsBanner: FC = () => {
+ const { connection } = useConnection();
+ const { wallet } = useWalletContext();
+ const [selectedAccount, extendedBankInfos] = useMrgnlendStore((state) => [
+ state.selectedAccount,
+ state.extendedBankInfos,
+ ]);
+
+ const bankAddressesWithEmissions: PublicKey[] = useMemo(() => {
+ if (!selectedAccount) return [];
+ return [...EMISSION_MINT_INFO_MAP.keys()]
+ .map((bankMintSymbol) => {
+ const uxdBankInfo = extendedBankInfos?.find((b) => b.isActive && b.meta.tokenSymbol === bankMintSymbol);
+ return uxdBankInfo?.address;
+ })
+ .filter((address) => address !== undefined) as PublicKey[];
+ }, [selectedAccount, extendedBankInfos]);
+
+ return (
+
{
+ if (!wallet || !selectedAccount || bankAddressesWithEmissions.length === 0) return;
+ await collectRewardsBatch(connection, wallet, selectedAccount, bankAddressesWithEmissions);
+ toast.success("Withdrawal successful");
+ }}
+ >
+ Collect LM rewards
+
+ );
+};
+
+export { EmissionsBanner };
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
index 7239b42e4d..4d7a5fea2c 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx
@@ -26,7 +26,7 @@ export const MobilePortfolioOverview: FC = () => {
}, [selectedAccount]);
return (
-
+
Your overview
Health factor
diff --git a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
index 9e7a1e57f4..7ced25402a 100644
--- a/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
+++ b/apps/marginfi-v2-ui/src/components/mobile/MobilePortfolioOverview/SemiCircleProgress.tsx
@@ -1,7 +1,6 @@
import React, { useEffect, useRef, useState } from "react";
import { keyframes } from "@emotion/react";
import styled from "@emotion/styled";
-
import { percentFormatter } from "@mrgnlabs/mrgn-common";
type Props = {
diff --git a/apps/marginfi-v2-ui/src/pages/portfolio.tsx b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
index 4baa165fb2..1dd953df93 100644
--- a/apps/marginfi-v2-ui/src/pages/portfolio.tsx
+++ b/apps/marginfi-v2-ui/src/pages/portfolio.tsx
@@ -19,6 +19,7 @@ import {
} from "~/components/desktop/Points";
import { AssetCard } from "~/components/mobile/MobileAssetsList/AssetCard";
import { Button, Skeleton, Typography } from "@mui/material";
+import { EmissionsBanner } from "~/components/mobile/EmissionsBanner";
const PortfolioPage = () => {
const { connected, wallet, isOverride } = useWalletContext();
@@ -79,9 +80,10 @@ const PortfolioPage = () => {
return (
<>
-
Portfolio
-
+
portfolio
+
+
{!connected ? (
diff --git a/apps/marginfi-v2-ui/src/pages/swap.tsx b/apps/marginfi-v2-ui/src/pages/swap.tsx
index dd4a24053c..6e98c1faaf 100644
--- a/apps/marginfi-v2-ui/src/pages/swap.tsx
+++ b/apps/marginfi-v2-ui/src/pages/swap.tsx
@@ -22,7 +22,7 @@ const SwapPage = () => {
return (
<>
-
+
swap
Powered
diff --git a/apps/marginfi-v2-ui/src/styles/globals.css b/apps/marginfi-v2-ui/src/styles/globals.css
index 94f8b8efc9..2cc8a28866 100644
--- a/apps/marginfi-v2-ui/src/styles/globals.css
+++ b/apps/marginfi-v2-ui/src/styles/globals.css
@@ -166,3 +166,32 @@ a {
background: linear-gradient(90deg, #808080, #DCE85DCC, #808080);
background-size: 200% 100%;
}
+
+.btn-gleam {
+ position: relative;
+ overflow: hidden;
+ /* Other styles remain the same */
+}
+
+.btn-gleam::before {
+ content: "";
+ position: absolute;
+ margin: -50%;
+ top: 0;
+ left: 0;
+ width: 50%; /* width of the gleam, you can adjust this */
+ height: 500%; /* covering the full height of the button */
+ background: linear-gradient(to left, transparent, #ffffff66, transparent); /* Adjust colors for the gleam effect */
+ transform: translateX(-50%) rotate(-40deg);
+ animation: 5s infinite gleam;
+}
+
+
+@keyframes gleam {
+ 0% {
+ transform: translateX(-50%) rotate(-40deg);
+ }
+ 15%, 100% {
+ transform: translateX(350%) rotate(-40deg);
+ }
+}
diff --git a/apps/marginfi-v2-ui/src/utils/mrgnActions.ts b/apps/marginfi-v2-ui/src/utils/mrgnActions.ts
index 4cce457249..6a3ad1409c 100644
--- a/apps/marginfi-v2-ui/src/utils/mrgnActions.ts
+++ b/apps/marginfi-v2-ui/src/utils/mrgnActions.ts
@@ -2,6 +2,8 @@ import { MarginfiAccountWrapper, MarginfiClient } from "@mrgnlabs/marginfi-clien
import { ExtendedBankInfo, FEE_MARGIN, ActionType } from "@mrgnlabs/marginfi-v2-ui-state";
import { toast } from "react-toastify";
import { isWholePosition } from "./mrgnUtils";
+import { Connection, PublicKey, Transaction } from "@solana/web3.js";
+import { Wallet, processTransaction } from "@mrgnlabs/mrgn-common";
const CLOSE_BALANCE_TOAST_ID = "close-balance";
const BORROW_OR_LEND_TOAST_ID = "borrow-or-lend";
@@ -187,3 +189,16 @@ export const borrowOrLend = async ({
console.log(error);
}
};
+
+export async function collectRewardsBatch(connection: Connection, wallet: Wallet, marginfiAccount: MarginfiAccountWrapper, bankAddresses: PublicKey[]) {
+ const tx = new Transaction();
+ const ixs = [];
+ const signers = [];
+ for (const bankAddress of bankAddresses) {
+ const ix = await marginfiAccount.makeWithdrawEmissionsIx(bankAddress);
+ ixs.push(...ix.instructions);
+ signers.push(ix.keys);
+ }
+ tx.add(...ixs);
+ await processTransaction(connection, wallet, tx);
+}
From 5685d29ec694e500d6cdfca4e9c8eca14a4be5ba Mon Sep 17 00:00:00 2001
From: man0s <95379755+losman0s@users.noreply.github.com>
Date: Sat, 30 Sep 2023 14:42:03 +0800
Subject: [PATCH 033/351] feat(mfi-v2-ui): better contrast
---
.../src/components/desktop/Points/PointsCheckingUser.tsx | 2 +-
.../src/components/desktop/Points/PointsConnectWallet.tsx | 2 +-
.../src/components/desktop/Points/PointsSignIn.tsx | 2 +-
.../src/components/desktop/Points/PointsSignUp.tsx | 2 +-
.../mobile/MobilePortfolioOverview/MobilePortfolioOverview.tsx | 2 +-
.../mobile/MobilePortfolioOverview/SemiCircleProgress.tsx | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx
index 9a97da8117..8825de5f33 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsCheckingUser.tsx
@@ -5,7 +5,7 @@ interface PointsCheckingUserProps {}
export const PointsCheckingUser: FC
= ({}) => {
return (
-
+
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx
index cef8667ee3..5d5ce23f58 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsConnectWallet.tsx
@@ -7,7 +7,7 @@ interface PointsConnectWalletProps {}
export const PointsConnectWallet: FC
= ({}) => {
return (
-
+
diff --git a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx
index 1dfff3eed7..8bef18d194 100644
--- a/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx
+++ b/apps/marginfi-v2-ui/src/components/desktop/Points/PointsSignIn.tsx
@@ -30,7 +30,7 @@ export const PointsSignIn: FC
= ({}) => {
}, [connection, useAuthTx, walletContextState]);
return (
-
+