diff --git a/apps/marginfi-api/src/app/layout.tsx b/apps/marginfi-api/src/app/layout.tsx
deleted file mode 100644
index a14e64fcd5..0000000000
--- a/apps/marginfi-api/src/app/layout.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-export const metadata = {
- title: 'Next.js',
- description: 'Generated by Next.js',
-}
-
-export default function RootLayout({
- children,
-}: {
- children: React.ReactNode
-}) {
- return (
-
-
{children}
-
- )
-}
diff --git a/apps/marginfi-api/src/app/notifications/route.ts b/apps/marginfi-api/src/app/notifications/route.ts
index eac43bac1c..d2bdddc176 100644
--- a/apps/marginfi-api/src/app/notifications/route.ts
+++ b/apps/marginfi-api/src/app/notifications/route.ts
@@ -102,3 +102,28 @@ export async function POST(request: Request) {
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
}
}
+
+export async function DELETE(request: Request) {
+ const { searchParams } = new URL(request.url);
+ const wallet = searchParams.get("wallet_address");
+ const apiKey = request.headers.get("X-API-KEY");
+
+ if (!apiKey || apiKey !== process.env.MARGINFI_API_KEY) {
+ return NextResponse.json({ error: "Invalid or missing API key" }, { status: 401 });
+ }
+
+ if (!wallet) {
+ return NextResponse.json({ error: "Missing wallet address parameter" }, { status: 400 });
+ }
+
+ const queryText = `DELETE FROM notification_settings WHERE wallet_address = '${wallet}'`;
+
+ try {
+ const res = await db.query(queryText);
+ console.log(res);
+ return NextResponse.json({ success: true }, { status: 200 });
+ } catch (error) {
+ console.error("Database error:", error);
+ return NextResponse.json({ error: "Internal server error" }, { status: 500 });
+ }
+}
diff --git a/apps/marginfi-v2-ui/src/components/common/Wallet/WalletSettings.tsx b/apps/marginfi-v2-ui/src/components/common/Wallet/WalletSettings.tsx
index 77eaa6b400..b88a6653f5 100644
--- a/apps/marginfi-v2-ui/src/components/common/Wallet/WalletSettings.tsx
+++ b/apps/marginfi-v2-ui/src/components/common/Wallet/WalletSettings.tsx
@@ -10,7 +10,7 @@ import { useConvertkit } from "~/hooks/useConvertkit";
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "~/components/ui/accordion";
import { WalletTokens, Token, WalletOnramp } from "~/components/common/Wallet";
import { Label } from "~/components/ui/label";
-import { IconCheck, IconInfoCircle, IconLoader, IconAlertTriangle } from "~/components/ui/icons";
+import { IconCheck, IconInfoCircle, IconLoader, IconAlertTriangle, IconX } from "~/components/ui/icons";
import { Input } from "~/components/ui/input";
import { Checkbox } from "~/components/ui/checkbox";
import { Button } from "~/components/ui/button";
@@ -38,6 +38,7 @@ export const WalletSettings = ({ walletAddress, tokens }: WalletSettingsProps) =
ybx: false,
});
const [errorMsg, setErrorMsg] = React.useState(null);
+ const [showClearNotifications, setShowClearNotifications] = React.useState(false);
const notificationFormDisabled = React.useMemo(() => {
return walletSettingsState === WalletSettingsState.UPDATING || !email;
@@ -86,6 +87,7 @@ export const WalletSettings = ({ walletAddress, tokens }: WalletSettingsProps) =
setErrorMsg(null);
setWalletSettingsState(WalletSettingsState.SUCCESS);
+ setShowClearNotifications(true);
setTimeout(() => {
setWalletSettingsState(WalletSettingsState.DEFAULT);
@@ -107,7 +109,7 @@ export const WalletSettings = ({ walletAddress, tokens }: WalletSettingsProps) =
if (!res.ok) {
// document not found which means notifications have not been set
- const { success, message } = await res.json();
+ const { success } = await res.json();
if (success) {
return;
}
@@ -123,6 +125,32 @@ export const WalletSettings = ({ walletAddress, tokens }: WalletSettingsProps) =
health: data.account_health,
ybx: data.ybx_updates,
});
+ setShowClearNotifications(Boolean(data.email));
+ }, [walletAddress]);
+
+ const clearNotifications = React.useCallback(async () => {
+ const deleteRes = await fetch(window.location.origin + "/api/user/notifications", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ walletAddress: walletAddress.toBase58(),
+ deleteRecord: true,
+ }),
+ });
+
+ if (!deleteRes.ok) {
+ setErrorMsg("There was an error clearing your notification settings. Please try again.");
+ return;
+ }
+
+ setEmail(null);
+ setNotificationSettings({
+ health: false,
+ ybx: false,
+ });
+ setShowClearNotifications(false);
}, [walletAddress]);
React.useEffect(() => {
@@ -251,6 +279,18 @@ export const WalletSettings = ({ walletAddress, tokens }: WalletSettingsProps) =
>
)}
+
+ {showClearNotifications && (
+
+ )}
diff --git a/apps/marginfi-v2-ui/src/pages/api/user/notifications.ts b/apps/marginfi-v2-ui/src/pages/api/user/notifications.ts
index a841a813f1..6a4fbc23b6 100644
--- a/apps/marginfi-v2-ui/src/pages/api/user/notifications.ts
+++ b/apps/marginfi-v2-ui/src/pages/api/user/notifications.ts
@@ -10,9 +10,29 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
if (req.method === "POST") {
- const { email, walletAddress, accountHealth, ybxUpdates } = req.body;
+ const { email, walletAddress, accountHealth, ybxUpdates, deleteRecord } = req.body;
try {
+ if (deleteRecord) {
+ const response = await fetch(`${apiUrl}/notifications?wallet_address=${walletAddress}`, {
+ method: "DELETE",
+ headers: {
+ "Content-Type": "application/json",
+ "X-API-KEY": apiKey,
+ },
+ });
+
+ if (response.ok) {
+ return res.status(200).json({ success: true, message: "Notification settings deleted" });
+ } else {
+ const errorData = await response.json();
+ console.error("Error deleting notifications settings via API:", errorData);
+ return res
+ .status(response.status)
+ .json({ success: false, message: errorData.message || "Failed to delete notification settings" });
+ }
+ }
+
const response = await fetch(`${apiUrl}/notifications`, {
method: "POST",
headers: {