- {walletContext.connected && (
+ {connected && (
@@ -625,21 +624,21 @@ interface EarnActionProps extends ButtonProps {
}
export const EarnAction: FC
= ({ children, spinning, disabled, ...otherProps }) => {
- const walletContext = useWallet();
+ const { connected } = useWalletContext();
- return walletContext.connected ? (
+ return connected ? (
diff --git a/apps/marginfi-v2-ui/src/components/Navbar/AirdropZone.tsx b/apps/marginfi-v2-ui/src/components/Navbar/AirdropZone.tsx
index b87ff1e074..0600bf1d28 100644
--- a/apps/marginfi-v2-ui/src/components/Navbar/AirdropZone.tsx
+++ b/apps/marginfi-v2-ui/src/components/Navbar/AirdropZone.tsx
@@ -10,6 +10,7 @@ import {
getAssociatedTokenAddressSync,
shortenAddress,
} from "@mrgnlabs/mrgn-common";
+import { useWalletContext } from "../useWalletContext";
const SOL_AMOUNT = 2 * 10 ** 9;
@@ -23,7 +24,7 @@ const USDC_FAUCET = new PublicKey("3ThaREisq3etoy9cvdzRgKypHsa8iTjMxj19AjETA1Fy"
const AirdropZone: FC = () => {
const [isOpen, setIsOpen] = useState(false);
- const wallet = useWallet();
+ const { walletAddress, walletContextState } = useWalletContext();
const { connection } = useConnection();
const open = useCallback(async () => setIsOpen(true), []);
@@ -31,31 +32,31 @@ const AirdropZone: FC = () => {
const airdropToken = useCallback(
async (amount: number, mint: PublicKey, faucet: PublicKey) => {
- if (faucet && wallet.publicKey) {
- const ataAddress = getAssociatedTokenAddressSync(mint, wallet.publicKey!);
+ if (faucet && walletAddress) {
+ const ataAddress = getAssociatedTokenAddressSync(mint, walletAddress!);
const ixs = [];
- const solBalance = await connection.getBalance(wallet.publicKey);
+ const solBalance = await connection.getBalance(walletAddress);
if (solBalance < 0.05) {
- await connection.requestAirdrop(wallet.publicKey, 100000000);
+ await connection.requestAirdrop(walletAddress, 100000000);
}
const ataAi = await connection.getAccountInfo(ataAddress);
if (!ataAi) {
- ixs.push(createAssociatedTokenAccountInstruction(wallet.publicKey, ataAddress, wallet.publicKey, mint));
+ ixs.push(createAssociatedTokenAccountInstruction(walletAddress, ataAddress, walletAddress, mint));
}
ixs.push(makeAirdropCollateralIx(amount, mint, ataAddress, faucet));
const tx = new Transaction();
tx.add(...ixs);
- await wallet.sendTransaction(tx, connection, {
+ await walletContextState.sendTransaction(tx, connection, {
skipPreflight: true,
});
}
},
- [connection, wallet]
+ [connection, walletAddress, walletContextState]
);
- if (!wallet?.publicKey) return null;
+ if (!walletAddress) return null;
return (
@@ -72,7 +73,7 @@ const AirdropZone: FC = () => {
try {
await airdropToken(USDC_AMOUNT, USDC_MINT, USDC_FAUCET);
toast.update(toastId, {
- render: `Airdropped ${USDC_AMOUNT} USDC to ${shortenAddress(wallet.publicKey!)}`,
+ render: `Airdropped ${USDC_AMOUNT} USDC to ${shortenAddress(walletAddress!)}`,
type: toast.TYPE.SUCCESS,
autoClose: 5000,
isLoading: false,
@@ -95,7 +96,7 @@ const AirdropZone: FC = () => {
try {
await airdropToken(NOTSOL_AMOUNT, NOTSOL_MINT, NOTSOL_FAUCET);
toast.update(toastId, {
- render: `Airdropped ${NOTSOL_AMOUNT} notSOL to ${shortenAddress(wallet.publicKey!)}`,
+ render: `Airdropped ${NOTSOL_AMOUNT} notSOL to ${shortenAddress(walletAddress!)}`,
type: toast.TYPE.SUCCESS,
autoClose: 5000,
toastId,
@@ -118,9 +119,9 @@ const AirdropZone: FC = () => {
onClick={async () => {
const toastId = toast.loading(`Airdropping ${SOL_AMOUNT} SOL`);
try {
- await connection.requestAirdrop(wallet.publicKey!, SOL_AMOUNT);
+ await connection.requestAirdrop(walletAddress!, SOL_AMOUNT);
toast.update(toastId, {
- render: `Airdropped ${SOL_AMOUNT} SOL to ${shortenAddress(wallet.publicKey!)}`,
+ render: `Airdropped ${SOL_AMOUNT} SOL to ${shortenAddress(walletAddress!)}`,
type: toast.TYPE.SUCCESS,
autoClose: 5000,
toastId,
diff --git a/apps/marginfi-v2-ui/src/components/Navbar/Navbar.tsx b/apps/marginfi-v2-ui/src/components/Navbar/Navbar.tsx
index 3c1f63ceb4..25495a6d27 100644
--- a/apps/marginfi-v2-ui/src/components/Navbar/Navbar.tsx
+++ b/apps/marginfi-v2-ui/src/components/Navbar/Navbar.tsx
@@ -3,7 +3,6 @@ import Link from "next/link";
import Image from "next/image";
import AirdropZone from "./AirdropZone";
import { WalletButton } from "./WalletButton";
-import { useWallet } from "@solana/wallet-adapter-react";
import { useHotkeys } from "react-hotkeys-hook";
import { useMrgnlendStore, useUserProfileStore } from "~/store";
@@ -13,12 +12,13 @@ import { HotkeysEvent } from "react-hotkeys-hook/dist/types";
import { Badge } from "@mui/material";
import { useFirebaseAccount } from "../useFirebaseAccount";
import { groupedNumberFormatterDyn, numeralFormatter } from "@mrgnlabs/mrgn-common";
+import { useWalletContext } from "../useWalletContext";
// @todo implement second pretty navbar row
const Navbar: FC = () => {
useFirebaseAccount();
- const wallet = useWallet();
+ const { connected, walletAddress } = useWalletContext();
const router = useRouter();
const [accountSummary, selectedAccount, extendedBankInfos] = useMrgnlendStore((state) => [
state.accountSummary,
@@ -37,10 +37,9 @@ const Navbar: FC = () => {
const [currentRoute, setCurrentRoute] = useState(router.pathname);
useEffect(() => {
- const walletAddress = wallet.publicKey?.toBase58();
if (!walletAddress) return;
- fetchPoints(walletAddress).catch(console.error);
- }, [fetchPoints, wallet.publicKey]);
+ fetchPoints(walletAddress.toBase58()).catch(console.error);
+ }, [fetchPoints, walletAddress]);
useEffect(() => {
setCurrentRoute(router.pathname);
@@ -215,7 +214,7 @@ const Navbar: FC = () => {
omni
- {process.env.NEXT_PUBLIC_MARGINFI_FEATURES_AIRDROP === "true" && wallet.connected &&
}
+ {process.env.NEXT_PUBLIC_MARGINFI_FEATURES_AIRDROP === "true" && connected &&
}
{
- {wallet.connected && currentFirebaseUser
+ {connected && currentFirebaseUser
? `${groupedNumberFormatterDyn.format(Math.round(userPointsData.totalPoints))} points`
: "P...P...POINTS!"}
diff --git a/apps/marginfi-v2-ui/src/components/Navbar/WalletButton.tsx b/apps/marginfi-v2-ui/src/components/Navbar/WalletButton.tsx
index 601e5d4436..dfbd690866 100644
--- a/apps/marginfi-v2-ui/src/components/Navbar/WalletButton.tsx
+++ b/apps/marginfi-v2-ui/src/components/Navbar/WalletButton.tsx
@@ -1,6 +1,6 @@
import dynamic from "next/dynamic";
import { FC } from "react";
-import { useWallet } from "@solana/wallet-adapter-react";
+import { useWalletContext } from "../useWalletContext";
const WalletMultiButtonDynamic = dynamic(
async () => (await import("@solana/wallet-adapter-react-ui")).WalletMultiButton,
@@ -8,14 +8,12 @@ const WalletMultiButtonDynamic = dynamic(
);
const WalletButton: FC = () => {
- const wallet = useWallet();
+ const { connected } = useWalletContext();
return (
-
- {!wallet.connected && "CONNECT"}
+
+ {!connected && CONNECT
}
);
diff --git a/apps/marginfi-v2-ui/src/components/useFirebaseAccount.tsx b/apps/marginfi-v2-ui/src/components/useFirebaseAccount.tsx
index a63e5d9b0e..73055004fd 100644
--- a/apps/marginfi-v2-ui/src/components/useFirebaseAccount.tsx
+++ b/apps/marginfi-v2-ui/src/components/useFirebaseAccount.tsx
@@ -1,12 +1,12 @@
import { firebaseApi } from "@mrgnlabs/marginfi-v2-ui-state";
-import { useWallet } from "@solana/wallet-adapter-react";
import { onAuthStateChanged } from "firebase/auth";
import { useEffect } from "react";
import { toast } from "react-toastify";
import { useUserProfileStore } from "~/store";
+import { useWalletContext } from "./useWalletContext";
const useFirebaseAccount = () => {
- const wallet = useWallet();
+ const {connected, walletAddress} = useWalletContext();
const [checkForFirebaseUser, setFirebaseUser, signoutFirebaseUser, fetchPoints, resetPoints] = useUserProfileStore(
(state) => [
@@ -34,16 +34,16 @@ const useFirebaseAccount = () => {
// Wallet connection side effect (auto-login attempt)
useEffect(() => {
- if (!wallet.publicKey) return;
- checkForFirebaseUser(wallet.publicKey.toBase58());
- }, [wallet.publicKey, checkForFirebaseUser]);
+ if (!walletAddress) return;
+ checkForFirebaseUser(walletAddress.toBase58());
+ }, [walletAddress, checkForFirebaseUser]);
// Wallet disconnection/change side effect (auto-logout)
useEffect(() => {
- signoutFirebaseUser(wallet.connected, wallet.publicKey?.toBase58()).catch((error) =>
+ signoutFirebaseUser(connected, walletAddress?.toBase58()).catch((error) =>
toast.error(`Error signing out: ${error}`)
),
- [wallet];
+ [connected, walletAddress];
});
};
diff --git a/apps/marginfi-v2-ui/src/components/useWalletWithOverride.tsx b/apps/marginfi-v2-ui/src/components/useWalletContext.tsx
similarity index 52%
rename from apps/marginfi-v2-ui/src/components/useWalletWithOverride.tsx
rename to apps/marginfi-v2-ui/src/components/useWalletContext.tsx
index 6c8e6de9df..00401ca5b2 100644
--- a/apps/marginfi-v2-ui/src/components/useWalletWithOverride.tsx
+++ b/apps/marginfi-v2-ui/src/components/useWalletContext.tsx
@@ -1,13 +1,20 @@
import { Wallet } from "@mrgnlabs/mrgn-common";
-import { useAnchorWallet } from "@solana/wallet-adapter-react";
+import { useAnchorWallet, useWallet } from "@solana/wallet-adapter-react";
+import { useWalletModal } from "@solana/wallet-adapter-react-ui";
import { PublicKey } from "@solana/web3.js";
import { useRouter } from "next/router";
-import { useMemo } from "react";
+import { useCallback, useMemo } from "react";
-const useWalletWithOverride = () => {
+const useWalletContext = () => {
+ const walletContextState = useWallet();
+ const walletModal = useWalletModal();
const anchorWallet = useAnchorWallet();
const { query } = useRouter();
+ const openWalletSelector = useCallback(() => {
+ walletModal.setVisible(true);
+ }, [walletModal]);
+
const { wallet, isOverride }: { wallet: Wallet | undefined; isOverride: boolean } = useMemo(() => {
const override = query?.wallet as string;
if (anchorWallet && override) {
@@ -22,7 +29,7 @@ const useWalletWithOverride = () => {
return { wallet: anchorWallet, isOverride: false };
}, [anchorWallet, query]);
- return { wallet, isOverride };
+ return { wallet, walletAddress: wallet?.publicKey, isOverride, connected: walletContextState.connected, openWalletSelector, walletContextState };
};
-export { useWalletWithOverride };
+export { useWalletContext };
diff --git a/apps/marginfi-v2-ui/src/pages/bridge.tsx b/apps/marginfi-v2-ui/src/pages/bridge.tsx
index 639d5d9029..371ae523a9 100644
--- a/apps/marginfi-v2-ui/src/pages/bridge.tsx
+++ b/apps/marginfi-v2-ui/src/pages/bridge.tsx
@@ -1,15 +1,14 @@
"use client";
import { useState, useEffect, useCallback } from "react";
-import { useWallet } from "@solana/wallet-adapter-react";
import config from "~/config";
import Script from "next/script";
-import { useWalletModal } from "@solana/wallet-adapter-react-ui";
import { toast } from "react-toastify";
import { useHotkeys } from "react-hotkeys-hook";
import { PageHeaderBridge } from "~/components/PageHeader";
import { MayanWidgetColors, MayanWidgetConfigType } from "~/types";
import { useUserProfileStore } from "~/store";
+import { useWalletContext } from "~/components/useWalletContext";
const tokens = [
"0x0000000000000000000000000000000000000000", // SOL
@@ -65,8 +64,7 @@ const configs: MayanWidgetConfigType[] = [
},
];
const BridgePage = () => {
- const { publicKey, signTransaction, connect, disconnect, wallet } = useWallet();
- const { setVisible, visible } = useWalletModal();
+ const { walletAddress, walletContextState, openWalletSelector } = useWalletContext();
const [isBridgeIn, setIsBridgeIn] = useState
(true);
const setShowBadges = useUserProfileStore((state) => state.setShowBadges);
@@ -85,36 +83,36 @@ const BridgePage = () => {
const handleConnect = useCallback(async () => {
try {
- if (!wallet) {
- setVisible(!visible);
+ if (!walletContextState.wallet) {
+ openWalletSelector();
} else {
- await connect();
+ await walletContextState.connect();
}
} catch (err) {
console.error(err);
}
- }, [connect, setVisible, visible, wallet]);
+ }, [walletContextState, openWalletSelector]);
useEffect(() => {
if (typeof window !== "undefined" && typeof window.MayanSwap !== "undefined") {
window.MayanSwap.updateSolanaWallet({
- signTransaction,
- publicKey: publicKey ? publicKey.toString() : null,
+ signTransaction: walletContextState.signTransaction,
+ publicKey: walletAddress ? walletAddress.toString() : null,
onClickOnConnect: handleConnect,
- onClickOnDisconnect: disconnect,
+ onClickOnDisconnect: walletContextState.disconnect,
});
}
- }, [disconnect, handleConnect, publicKey, signTransaction]);
+ }, [walletContextState, handleConnect, walletAddress]);
const handleLoadMayanWidget = () => {
const configIndex = isBridgeIn ? 0 : 1;
const config = {
...configs[configIndex],
solanaWallet: {
- publicKey: publicKey ? publicKey.toString() : null,
- signTransaction,
+ publicKey: walletAddress ? walletAddress.toString() : null,
+ signTransaction: walletContextState.signTransaction,
onClickOnConnect: handleConnect,
- onClickOnDisconnect: disconnect,
+ onClickOnDisconnect: walletContextState.disconnect,
},
};
window.MayanSwap.init("swap_widget", config);
@@ -148,10 +146,10 @@ const BridgePage = () => {
const config = {
...configs[newConfigIndex],
solanaWallet: {
- publicKey: publicKey ? publicKey.toString() : null,
- signTransaction,
+ publicKey: walletAddress ? walletAddress.toString() : null,
+ signTransaction: walletContextState.signTransaction,
onClickOnConnect: handleConnect,
- onClickOnDisconnect: disconnect,
+ onClickOnDisconnect: walletContextState.disconnect,
},
};
if (window.MayanSwap) {
@@ -160,7 +158,7 @@ const BridgePage = () => {
return;
}
setIsBridgeIn((prevState) => !prevState);
- }, [disconnect, handleConnect, isBridgeIn, publicKey, signTransaction]);
+ }, [handleConnect, isBridgeIn, walletAddress, walletContextState]);
useEffect(() => {
handleUpdateConfig;
diff --git a/apps/marginfi-v2-ui/src/pages/index.tsx b/apps/marginfi-v2-ui/src/pages/index.tsx
index 7492ddf375..f88c00f3a0 100644
--- a/apps/marginfi-v2-ui/src/pages/index.tsx
+++ b/apps/marginfi-v2-ui/src/pages/index.tsx
@@ -1,13 +1,13 @@
import React, { useEffect } from "react";
-import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { Banner } from "~/components";
import { PageHeader } from "~/components/PageHeader";
-import { useWalletWithOverride } from "~/components/useWalletWithOverride";
+import { useWalletContext } from "~/components/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 { useConnection } from "@solana/wallet-adapter-react";
const AccountSummary = dynamic(async () => (await import("~/components/AccountSummary")).AccountSummary, {
ssr: false,
@@ -16,19 +16,21 @@ const AssetsList = dynamic(async () => (await import("~/components/AssetsList"))
const UserPositions = dynamic(async () => (await import("~/components/UserPositions")).UserPositions, { ssr: false });
const Home = () => {
- const walletContext = useWallet();
- const { wallet, isOverride } = useWalletWithOverride();
+ const { walletAddress, wallet, isOverride } = useWalletContext();
const { connection } = useConnection();
- const fetchMrgnlendState = useMrgnlendStore((state) => state.fetchMrgnlendState);
- const setIsRefreshingStore = useMrgnlendStore((state) => state.setIsRefreshingStore);
- const marginfiAccountCount = useMrgnlendStore((state) => state.marginfiAccountCount);
- const selectedAccount = useMrgnlendStore((state) => state.selectedAccount);
+ 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(() => {
+ if (!walletAddress && userDataFetched) {
+ resetUserData();
+ }
+ }, [walletAddress, userDataFetched, resetUserData]);
+
useEffect(() => {
setIsRefreshingStore(true);
fetchMrgnlendState({ marginfiConfig: config.mfiConfig, connection, wallet, isOverride }).catch(console.error);
@@ -48,18 +50,18 @@ const Home = () => {
suppressHydrationWarning={true}
className="flex flex-col h-full justify-start content-start pt-[64px] sm:pt-[16px] w-4/5 max-w-7xl gap-4"
>
- {walletContext.publicKey &&
+ {walletAddress &&
wallet &&
selectedAccount &&
- !selectedAccount.authority.equals(walletContext.publicKey) && (
+ !selectedAccount.authority.equals(walletAddress) && (
)}
- {walletContext.connected && marginfiAccountCount > 1 && (
+ {walletAddress && marginfiAccountCount > 1 && (
)}
@@ -67,7 +69,7 @@ const Home = () => {
- {walletContext.connected &&
}
+ {walletAddress &&
}
>
diff --git a/apps/marginfi-v2-ui/src/pages/lip.tsx b/apps/marginfi-v2-ui/src/pages/lip.tsx
index b58b185ee2..85dd283c6a 100644
--- a/apps/marginfi-v2-ui/src/pages/lip.tsx
+++ b/apps/marginfi-v2-ui/src/pages/lip.tsx
@@ -1,15 +1,15 @@
-import { useWallet } from "@solana/wallet-adapter-react";
import { PageHeader } from "~/components/PageHeader";
import { CampaignWizard } from "~/components/CampaignWizard";
import { LipClientProvider } from "~/context";
+import { useWalletContext } from "~/components/useWalletContext";
const LIP = () => {
- const wallet = useWallet();
+ const { connected } = useWalletContext();
return (
- {wallet.connected && }
+ {connected && }
);
};
diff --git a/apps/marginfi-v2-ui/src/pages/points.tsx b/apps/marginfi-v2-ui/src/pages/points.tsx
index 701db8efc0..5b55d2ef3c 100644
--- a/apps/marginfi-v2-ui/src/pages/points.tsx
+++ b/apps/marginfi-v2-ui/src/pages/points.tsx
@@ -16,7 +16,7 @@ import {
Checkbox,
CircularProgress,
} from "@mui/material";
-import { useConnection, useWallet } from "@solana/wallet-adapter-react";
+import { useConnection } from "@solana/wallet-adapter-react";
import { FC, useEffect, useState } from "react";
import { PageHeader } from "~/components/PageHeader";
import FileCopyIcon from "@mui/icons-material/FileCopy";
@@ -31,6 +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/useWalletContext";
const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
@@ -45,7 +46,7 @@ const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
}));
const Points: FC = () => {
- const wallet = useWallet();
+ const { connected, walletAddress } = useWalletContext();
const { query: routerQuery } = useRouter();
const [currentFirebaseUser, hasUser, userPointsData] = useUserProfileStore((state) => [
state.currentFirebaseUser,
@@ -60,13 +61,13 @@ const Points: FC = () => {
useEffect(() => {
fetchLeaderboardData().then(setLeaderboardData); // TODO: cache leaderboard and avoid call
- }, [wallet.connected, wallet.publicKey]); // Dependency array to re-fetch when these variables change
+ }, [connected, walletAddress]); // Dependency array to re-fetch when these variables change
return (
<>
- {!wallet.connected ? (
+ {!connected ? (
) : currentFirebaseUser ? (
<>
@@ -442,7 +443,7 @@ const CheckingUser: FC = () => (
const Signup: FC<{ referralCode?: string }> = ({ referralCode }) => {
const { connection } = useConnection();
- const wallet = useWallet();
+ const { walletContextState, connected } = useWalletContext();
const [manualCode, setManualCode] = useState("");
const [useAuthTx, setUseAuthTx] = useState(false);
const [useManualCode, setUseManualCode] = useState(false);
@@ -462,13 +463,13 @@ const Signup: FC<{ referralCode?: string }> = ({ referralCode }) => {
toast.info("Logging in...");
const blockhashInfo = await connection.getLatestBlockhash();
try {
- await firebaseApi.signup(wallet, useAuthTx ? "tx" : "memo", blockhashInfo, finalReferralCode);
+ 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, wallet]);
+ }, [connection, finalReferralCode, useAuthTx, walletContextState]);
return (
@@ -483,7 +484,7 @@ const Signup: FC<{ referralCode?: string }> = ({ referralCode }) => {
Optionally enter a referral code below.
- {wallet.connected ? (
+ {connected ? (
= ({ referralCode }) => {
const Login: FC = () => {
const { connection } = useConnection();
- const wallet = useWallet();
+ 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(wallet, useAuthTx ? "tx" : "memo", blockhashInfo);
+ 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, wallet]);
+ }, [connection, useAuthTx, walletContextState]);
return (
@@ -576,7 +577,7 @@ const Login: FC = () => {
Login to your points account by signing a message.
- {wallet.connected ? (
+ {connected ? (
{
- const { wallet } = useWallet();
+ const { wallet } = useWalletContext();
useEffect(() => {
if (wallet) {
diff --git a/apps/marginfi-v2-ui/src/utils/OKXWalletAdapter.tsx b/apps/marginfi-v2-ui/src/utils/OKXWalletAdapter.tsx
index 90733828e2..3343c483fe 100644
--- a/apps/marginfi-v2-ui/src/utils/OKXWalletAdapter.tsx
+++ b/apps/marginfi-v2-ui/src/utils/OKXWalletAdapter.tsx
@@ -6,15 +6,19 @@ import {
WalletConnectionError,
WalletDisconnectedError,
WalletDisconnectionError,
+ WalletNotConnectedError,
WalletNotReadyError,
WalletPublicKeyError,
WalletReadyState,
+ WalletSignMessageError,
+ WalletSignTransactionError,
} from "@solana/wallet-adapter-base";
-import { PublicKey } from "@solana/web3.js";
+import { PublicKey, Transaction, TransactionVersion, VersionedTransaction } from "@solana/web3.js";
interface OKXWalletEvents {
connect(...args: unknown[]): unknown;
disconnect(...args: unknown[]): unknown;
+ accountChanged(address: PublicKey, ...args: unknown[]): unknown;
}
interface OKXWallet extends EventEmitter
{
@@ -24,6 +28,9 @@ interface OKXWallet extends EventEmitter {
publicKey?: PublicKey;
connect(): Promise;
disconnect(): Promise;
+ signMessage(message: Uint8Array, encoding: string): Promise;
+ signTransaction(transaction: Transaction | VersionedTransaction): Promise;
+ signAllTransactions(transactions: (Transaction | VersionedTransaction)[]): Promise<(Transaction | VersionedTransaction)[]>;
}
interface OKXWindow extends Window {
@@ -38,13 +45,12 @@ interface OKXWalletAdapterConfig {}
const OKXWalletName = "OKX Wallet" as WalletName<"OKX Wallet">;
-//@ts-ignore
export class OKXWalletAdapter extends BaseMessageSignerWalletAdapter {
name = OKXWalletName;
url = "https://www.okx.com/web3";
icon =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAJDSURBVHgB7Zq9jtpAEMfHlhEgQLiioXEkoAGECwoKxMcTRHmC5E3IoyRPkPAEkI7unJYmTgEFTYwA8a3NTKScLnCHN6c9r1e3P2llWQy7M/s1Gv1twCP0ej37dDq9x+Zut1t3t9vZjDEHIiSRSPg4ZpDL5fxkMvn1cDh8m0wmfugfO53OoFQq/crn8wxfY9EymQyrVCqMfHvScZx1p9ls3pFxXBy/bKlUipGPrVbLuQqAfsCliq3zl0H84zwtjQrOw4Mt1W63P5LvBm2d+Xz+YzqdgkqUy+WgWCy+Mc/nc282m4FqLBYL+3g8fjDxenq72WxANZbLJeA13zDX67UDioL5ybXwafMYu64Ltn3bdDweQ5R97fd7GyhBQMipx4POeEDHIu2LfDdBIGGz+hJ9CQ1ABjoA2egAZPM6AgiCAEQhsi/C4jHyPA/6/f5NG3Ks2+3CYDC4aTccDrn6ojG54MnEvG00GoVmWLIRNZ7wTCwDHYBsdACy0QHIhiuRETxlICWpMMhGZHmqS8qH6JLyGegAZKMDkI0uKf8X4SWlaZo+Pp1bRrwlJU8ZKLIvUjKh0WiQ3sRUbNVq9c5Ebew7KEo2m/1p4jJ4qAmDaqDQBzj5XyiAT4VCQezJigAU+IDU+z8vJFnGWeC+bKQV/5VZ71FV6L7PA3gg3tXrdQ+DgLhC+75Wq3no69P3MC0NFQpx2lL04Ql9gHK1bRDjsSBIvScBnDTk1WrlGIZBorIDEYJj+rhdgnQ67VmWRe0zlplXl81vcyEt0rSoYDUAAAAASUVORK5CYII=";
- readonly supportedTransactionVersions = null;
+ readonly supportedTransactionVersions: ReadonlySet = new Set(['legacy', 0]);
private _connecting: boolean;
private _wallet: OKXWallet | null;
@@ -119,6 +125,7 @@ export class OKXWalletAdapter extends BaseMessageSignerWalletAdapter {
}
wallet.on("disconnect", this._disconnected);
+ wallet.on('accountChanged', this._accountChanged);
this._wallet = wallet;
this._publicKey = publicKey;
@@ -135,7 +142,8 @@ export class OKXWalletAdapter extends BaseMessageSignerWalletAdapter {
async disconnect(): Promise {
const wallet = this._wallet;
if (wallet) {
- wallet.on("disconnect", this._disconnected);
+ wallet.off("disconnect", this._disconnected);
+ wallet.off('accountChanged', this._accountChanged);
this._wallet = null;
this._publicKey = null;
@@ -150,10 +158,58 @@ export class OKXWalletAdapter extends BaseMessageSignerWalletAdapter {
this.emit("disconnect");
}
+ async signTransaction(transaction: T): Promise {
+ try {
+ const wallet = this._wallet;
+ if (!wallet) throw new WalletNotConnectedError();
+
+ try {
+ return ((await wallet.signTransaction(transaction)) as T) || transaction;
+ } catch (error: any) {
+ throw new WalletSignTransactionError(error?.message, error);
+ }
+ } catch (error: any) {
+ this.emit('error', error);
+ throw error;
+ }
+}
+
+async signAllTransactions(transactions: T[]): Promise {
+ try {
+ const wallet = this._wallet;
+ if (!wallet) throw new WalletNotConnectedError();
+
+ try {
+ return ((await wallet.signAllTransactions(transactions)) as T[]) || transactions;
+ } catch (error: any) {
+ throw new WalletSignTransactionError(error?.message, error);
+ }
+ } catch (error: any) {
+ this.emit('error', error);
+ throw error;
+ }
+}
+
+async signMessage(message: Uint8Array): Promise {
+ try {
+ const wallet = this._wallet;
+ if (!wallet) throw new WalletNotConnectedError();
+
+ try {
+ return await wallet.signMessage(message, 'utf8');
+ } catch (error: any) {
+ throw new WalletSignMessageError(error?.message, error);
+ }
+ } catch (error: any) {
+ this.emit('error', error);
+ throw error;
+ }
+}
+
private _disconnected = () => {
const wallet = this._wallet;
if (wallet) {
- wallet.on("disconnect", this._disconnected);
+ wallet.off("disconnect", this._disconnected);
this._wallet = null;
this._publicKey = null;
@@ -162,4 +218,23 @@ export class OKXWalletAdapter extends BaseMessageSignerWalletAdapter {
this.emit("disconnect");
}
};
+
+ private _accountChanged = (newPublicKey?: PublicKey) => {
+ if (!newPublicKey) return;
+
+ const publicKey = this._publicKey;
+ if (!publicKey) return;
+
+ try {
+ newPublicKey = new PublicKey(newPublicKey.toBytes());
+ } catch (error: any) {
+ this.emit('error', new WalletPublicKeyError(error?.message, error));
+ return;
+ }
+
+ if (publicKey.equals(newPublicKey)) return;
+
+ this._publicKey = newPublicKey;
+ this.emit('connect', newPublicKey);
+};
}
diff --git a/apps/omni/src/pages/index.tsx b/apps/omni/src/pages/index.tsx
index b6eed7a1d0..c1495abacc 100644
--- a/apps/omni/src/pages/index.tsx
+++ b/apps/omni/src/pages/index.tsx
@@ -35,9 +35,8 @@ const AiUI: FC = () => {
const [failed, setFailed] = useState(false);
const wallet = useWallet();
- const [marginfiClient, fetchMrgnlendState, selectedAccount, extendedBankInfos] = useMrgnlendStore((state) => [
+ const [marginfiClient, selectedAccount, extendedBankInfos] = useMrgnlendStore((state) => [
state.marginfiClient,
- state.fetchMrgnlendState,
state.selectedAccount,
state.extendedBankInfos,
]);
diff --git a/packages/marginfi-v2-ui-state/src/store/mrgnlendStore.ts b/packages/marginfi-v2-ui-state/src/store/mrgnlendStore.ts
index 63d4a98233..30fe207d28 100644
--- a/packages/marginfi-v2-ui-state/src/store/mrgnlendStore.ts
+++ b/packages/marginfi-v2-ui-state/src/store/mrgnlendStore.ts
@@ -35,6 +35,7 @@ interface ProtocolStats {
interface MrgnlendState {
// State
initialized: boolean;
+ userDataFetched: boolean;
isRefreshingStore: boolean;
marginfiClient: MarginfiClient | null;
bankMetadataMap: BankMetadataMap;
@@ -55,6 +56,7 @@ interface MrgnlendState {
isOverride?: boolean;
}) => Promise;
setIsRefreshingStore: (isRefreshingStore: boolean) => void;
+ resetUserData: () => void;
}
function createMrgnlendStore() {
@@ -78,6 +80,7 @@ function createPersistentMrgnlendStore() {
const stateCreator: StateCreator = (set, get) => ({
// State
initialized: false,
+ userDataFetched: false,
isRefreshingStore: false,
marginfiClient: null,
bankMetadataMap: {},
@@ -102,6 +105,8 @@ const stateCreator: StateCreator = (set, get) => ({
wallet?: Wallet;
isOverride?: boolean;
}) => {
+ let userDataFetched = false;
+
const connection = args?.connection ?? get().marginfiClient?.provider.connection;
if (!connection) throw new Error("Connection not found");
@@ -138,6 +143,7 @@ const stateCreator: StateCreator = (set, get) => ({
tokenAccountMap = tokenData.tokenAccountMap;
marginfiAccounts = marginfiAccountWrappers;
selectedAccount = marginfiAccounts[0];
+ userDataFetched = true;
}
const banksWithPriceAndToken = banks.map((bank) => {
@@ -204,6 +210,7 @@ const stateCreator: StateCreator = (set, get) => ({
set({
initialized: true,
+ userDataFetched,
isRefreshingStore: false,
marginfiClient,
bankMetadataMap,
@@ -223,6 +230,31 @@ const stateCreator: StateCreator = (set, get) => ({
});
},
setIsRefreshingStore: (isRefreshingStore: boolean) => set({ isRefreshingStore }),
+ resetUserData: () => {
+ const extendedBankInfos = get().extendedBankInfos.map((extendedBankInfo) => ({
+ ...extendedBankInfo,
+ userInfo: {
+ tokenAccount: {
+ created: false,
+ mint: extendedBankInfo.info.state.mint,
+ balance: 0,
+ },
+ maxDeposit: 0,
+ maxRepay: 0,
+ maxWithdraw: 0,
+ maxBorrow: 0,
+ },
+ }));
+
+ set({
+ userDataFetched: false,
+ selectedAccount: null,
+ nativeSolBalance: 0,
+ accountSummary: DEFAULT_ACCOUNT_SUMMARY,
+ extendedBankInfos,
+ marginfiClient: null,
+ });
+ },
});
export { createMrgnlendStore, createPersistentMrgnlendStore };
diff --git a/yarn.lock b/yarn.lock
index 4df56603bf..5e1d91c896 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6509,7 +6509,7 @@
dependencies:
"@solana/wallet-adapter-base" "^0.9.23"
-"@solana/wallet-adapter-react-ui@^0.9.27", "@solana/wallet-adapter-react-ui@^0.9.33":
+"@solana/wallet-adapter-react-ui@^0.9.27":
version "0.9.33"
resolved "https://registry.yarnpkg.com/@solana/wallet-adapter-react-ui/-/wallet-adapter-react-ui-0.9.33.tgz#30ad1638f700a47386ff709d5e855fc792b32e25"
integrity sha512-Wf2yAYpmzxWE3f8IMNed7wz+JALEwY2eIKcDtviLhvs/MXHw74fXA0mLzf5GB3EgHZq5zgWZI4kdYGTT8/yY1w==
@@ -6653,7 +6653,7 @@
"@jnwng/walletconnect-solana" "^0.2.0"
"@solana/wallet-adapter-base" "^0.9.23"
-"@solana/wallet-adapter-wallets@^0.19.10", "@solana/wallet-adapter-wallets@^0.19.20":
+"@solana/wallet-adapter-wallets@^0.19.10":
version "0.19.20"
resolved "https://registry.yarnpkg.com/@solana/wallet-adapter-wallets/-/wallet-adapter-wallets-0.19.20.tgz#25bbbbf2349f9c8ee169de1db34c74900f0e8a35"
integrity sha512-bE7tS6UykCSiWmudo8DYe/mZV0HoyqI+XifIjPaY/BNSgXQ3u1cwbqvqcLURuixBRnOka7FE6VuT90PhRsosqA==