Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(mfi-v2-ui): point improvements #364

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/marginfi-v2-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"cmdk": "^0.2.0",
"firebase": "^9.22.1",
"firebase": "^10.6.0",
"firebase-admin": "^11.9.0",
"jsbi": "^4.3.0",
"lodash.debounce": "^4.0.8",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { firebaseApi } from "@mrgnlabs/marginfi-v2-ui-state";
import { WalletButton } from "~/components/common/Wallet";
import { useWalletContext } from "~/hooks/useWalletContext";
import { MrgnTooltip } from "~/components/common/MrgnTooltip";

interface PointsSignInProps {}

export const PointsSignIn: FC<PointsSignInProps> = ({}) => {
Expand All @@ -23,10 +22,8 @@ export const PointsSignIn: FC<PointsSignInProps> = ({}) => {
return;
}
toast.info("Logging in...");
const blockhashInfo = await connection.getLatestBlockhash();
try {
await firebaseApi.login(wallet, useAuthTx ? "tx" : "memo", blockhashInfo);
// localStorage.setItem("authData", JSON.stringify(signedAuthData));
await firebaseApi.login(wallet.publicKey.toBase58());
toast.success("Logged in successfully");
} catch (loginError: any) {
toast.error(loginError.message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,8 @@ export const PointsSignUp: FC<PointsSignUpProps> = ({ referralCode }) => {
return;
}
toast.info("Logging in...");
const blockhashInfo = await connection.getLatestBlockhash();
try {
await firebaseApi.signup(wallet, useAuthTx ? "tx" : "memo", blockhashInfo, finalReferralCode);
// localStorage.setItem("authData", JSON.stringify(signedAuthData));
await firebaseApi.signup(wallet.publicKey.toBase58(), finalReferralCode);
toast.success("Signed up successfully");
} catch (signupError: any) {
toast.error(signupError.message);
Expand Down
18 changes: 13 additions & 5 deletions apps/marginfi-v2-ui/src/hooks/useFirebaseAccount.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import { firebaseApi } from "@mrgnlabs/marginfi-v2-ui-state";
import { onAuthStateChanged } from "firebase/auth";
import { useEffect } from "react";
import { useRouter } from "next/router";

import { toast } from "react-toastify";
import { useUserProfileStore } from "~/store";
import { useWalletContext } from "./useWalletContext";
import React from "react";

const useFirebaseAccount = () => {
const { connected, walletAddress } = useWalletContext();
const { query: routerQuery } = useRouter();

const referralCode = React.useMemo(() => routerQuery.referralCode as string | undefined, [routerQuery.referralCode]);

const [checkForFirebaseUser, setFirebaseUser, signoutFirebaseUser, fetchPoints, resetPoints] = useUserProfileStore(
(state) => [
const [checkForFirebaseUser, setFirebaseUser, signoutFirebaseUser, fetchPoints, resetPoints, hasUser] =
useUserProfileStore((state) => [
state.checkForFirebaseUser,
state.setFirebaseUser,
state.signoutFirebaseUser,
state.fetchPoints,
state.resetPoints,
]
);
state.hasUser,
]);

useEffect(() => {
// NOTE: if more point-specific logic is added, move this to a separate hook
Expand All @@ -35,8 +41,10 @@ const useFirebaseAccount = () => {
// Wallet connection side effect (auto-login attempt)
useEffect(() => {
if (!walletAddress) return;

firebaseApi.loginOrSignup(walletAddress.toBase58(), referralCode).catch(console.error);
checkForFirebaseUser(walletAddress.toBase58());
}, [walletAddress, checkForFirebaseUser]);
}, [walletAddress, checkForFirebaseUser, referralCode]);

// Wallet disconnection/change side effect (auto-logout)
useEffect(() => {
Expand Down
26 changes: 14 additions & 12 deletions apps/marginfi-v2-ui/src/pages/api/user/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ import {
initFirebaseIfNeeded();

export interface LoginRequest {
method: SigningMethod;
signedAuthDataRaw: string;
walletAddress: string;
}

export default async function handler(req: NextApiRequest<LoginRequest>, res: any) {
const { method, signedAuthDataRaw } = req.body;
const { walletAddress } = req.body;

/* signing logic
let signer;
try {
const loginData = validateAndUnpackLoginData(signedAuthDataRaw, method);
Expand All @@ -46,32 +46,34 @@ export default async function handler(req: NextApiRequest<LoginRequest>, res: an
status = STATUS_INTERNAL_ERROR;
}
return res.status(status).json({ error: error.message });
}
}*/

let user;
try {
const userResult = await getFirebaseUserByWallet(signer);
const userResult = await getFirebaseUserByWallet(walletAddress);
if (userResult === undefined) {
await logLoginAttempt(signer, null, signedAuthDataRaw, false);
await logLoginAttempt(walletAddress, null, "", false);
Sentry.captureException({ message: "User not found" });
return res.status(STATUS_NOT_FOUND).json({ error: "User not found" });
} else {
await logLoginAttempt(walletAddress, userResult.uid, "", true);
}
user = userResult;
} catch (error: any) {
Sentry.captureException(error);
return res.status(STATUS_INTERNAL_ERROR).json({ error: error.message }); // An unexpected error occurred
}

await logLoginAttempt(signer, user.uid, signedAuthDataRaw, true);

// Generate a custom token for the client to log in
const customToken = await admin.auth().createCustomToken(signer);
const customToken = await admin.auth().createCustomToken(walletAddress);

return res.status(STATUS_OK).json({ status: "success", uid: signer, token: customToken });
return res.status(STATUS_OK).json({ status: "success", uid: walletAddress, token: customToken });
}

// -------- Helpers

/**
* @deprecated
* Signing functionality
*/
export function validateAndUnpackLoginData(
signedAuthDataRaw: string,
signingMethod: SigningMethod
Expand Down
30 changes: 16 additions & 14 deletions apps/marginfi-v2-ui/src/pages/api/user/signup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,19 @@ import {
initFirebaseIfNeeded();

export interface SignupRequest {
method: SigningMethod;
signedAuthDataRaw: string;
walletAddress: string;
payload: firebaseApi.SignupPayload;
}

export default async function handler(req: NextApiRequest<SignupRequest>, res: any) {
const { method, signedAuthDataRaw } = req.body;
const { walletAddress, payload } = req.body;

Sentry.setContext("signup_args", {
method,
signedAuthDataRaw,
walletAddress,
});

let signer;
let payload;
try {
/* signing logic
try {
const signupData = validateAndUnpackSignupData(signedAuthDataRaw, method);
signer = signupData.signer.toBase58();
payload = signupData.payload;
Expand All @@ -52,10 +50,10 @@ export default async function handler(req: NextApiRequest<SignupRequest>, res: a
status = STATUS_INTERNAL_ERROR;
}
return res.status(status).json({ error: error.message });
}
}*/

try {
const user = await getFirebaseUserByWallet(signer);
const user = await getFirebaseUserByWallet(walletAddress);
if (user) {
Sentry.captureException({ message: "User already exists" });
return res.status(STATUS_BAD_REQUEST).json({ error: "User already exists" });
Expand All @@ -66,23 +64,27 @@ export default async function handler(req: NextApiRequest<SignupRequest>, res: a
}

try {
await createFirebaseUser(signer, payload.referralCode);
await createFirebaseUser(walletAddress, payload.referralCode);
console.log("successfully created new user");
} catch (createUserError: any) {
Sentry.captureException(createUserError);
return res.status(STATUS_INTERNAL_ERROR).json({ error: createUserError.message });
}

await logSignupAttempt(signer, payload.uuid, signedAuthDataRaw, true);
await logSignupAttempt(walletAddress, payload.uuid, "", true);

// Generate a custom token for the client to sign in
const customToken = await admin.auth().createCustomToken(signer);
const customToken = await admin.auth().createCustomToken(walletAddress);

return res.status(STATUS_OK).json({ status: "success", uid: signer, token: customToken });
return res.status(STATUS_OK).json({ status: "success", uid: walletAddress, token: customToken });
}

// -------- Helpers

/**
* @deprecated
* Signing functionality
*/
export function validateAndUnpackSignupData(
signedAuthDataRaw: string,
signingMethod: SigningMethod
Expand Down
12 changes: 2 additions & 10 deletions apps/marginfi-v2-ui/src/pages/points.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from "react";

import Link from "next/link";
import { useRouter } from "next/router";

import { Button } from "@mui/material";
import FileCopyIcon from "@mui/icons-material/FileCopy";
Expand All @@ -14,22 +13,19 @@ import { PageHeader } from "~/components/common/PageHeader";
import {
PointsLeaderBoard,
PointsOverview,
PointsSignIn,
PointsSignUp,
PointsCheckingUser,
PointsConnectWallet,
} from "~/components/desktop/Points";

const Points = () => {
const { connected } = useWalletContext();
const { query: routerQuery } = useRouter();

const [currentFirebaseUser, hasUser, userPointsData] = useUserProfileStore((state) => [
state.currentFirebaseUser,
state.hasUser,
state.userPointsData,
]);

const referralCode = React.useMemo(() => routerQuery.referralCode as string | undefined, [routerQuery.referralCode]);
const [isReferralCopied, setIsReferralCopied] = React.useState(false);

return (
Expand All @@ -40,12 +36,8 @@ const Points = () => {
<PointsConnectWallet />
) : currentFirebaseUser ? (
<PointsOverview userPointsData={userPointsData} />
) : hasUser === null ? (
<PointsCheckingUser />
) : hasUser ? (
<PointsSignIn />
) : (
<PointsSignUp referralCode={referralCode} />
<PointsCheckingUser />
)}
<div className="w-2/3 flex justify-center items-center gap-5">
<Button
Expand Down
Loading