Skip to content

Instantly share code, notes, and snippets.

@athallarizky
Created August 18, 2024 11:51
Show Gist options
  • Select an option

  • Save athallarizky/fb4612a614c7b47d195e11ca107d5c89 to your computer and use it in GitHub Desktop.

Select an option

Save athallarizky/fb4612a614c7b47d195e11ca107d5c89 to your computer and use it in GitHub Desktop.
useWallet.ts
import React, { useCallback, useMemo, useEffect, useState } from 'react';
import { useAccount, useDisconnect, useSignMessage } from 'wagmi';
import useFetch from 'use-http';
// Zustand Store
import { useStore, useWeb3AuthStore } from 'store';
// Helper
import { encryptWallet } from 'utils/helper';
import { useToken } from './useHttp';
interface WalletContextObject {
handleDisconnect: () => void;
isFetchingAuth: boolean;
signStatus: 'idle' | 'error' | 'loading' | 'success';
accountStatus: 'connecting' | 'reconnecting' | 'connected' | 'disconnected';
}
type WalletProviderProps = {
children?: React.ReactNode;
};
export const WalletContext = React.createContext<WalletContextObject>({} as WalletContextObject);
export const WalletProvider: React.FC<WalletProviderProps> = ({ children }) => {
const { post: doLogin } = useFetch('/authorization/handheld/v2/login', {
data: [],
});
const { address, isConnected, status: accountStatus, isDisconnected } = useAccount();
const { disconnect } = useDisconnect();
const [isFetchingAuth, setIsFetchingAuth] = useState<boolean>(false);
/** Zustand Store */
const { setWallet, setLoggedIn, setProfile, setWalletSignature, cleanStore, wallet } = useStore();
const { actions } = useWeb3AuthStore();
const signMessageText = `
Welcome to Kometh!
Please sign this message to log in.
This won't cost you any ETH.
Your authentication status will reset after 24 hours.
If you're connecting a hardware wallet,
you'll need to sign the message on your device, too.`;
const {
data: signData,
status: signStatus,
signMessage,
} = useSignMessage({
message: signMessageText,
});
const { createToken } = useToken();
const revokeAccess = useCallback(() => {
cleanStore();
disconnect();
setIsFetchingAuth(false);
}, [address]);
const isDifferentAccount = useMemo(() => {
if (wallet && address) {
return Boolean(address?.toLowerCase() !== wallet?.toLowerCase());
}
return undefined;
}, [address, wallet]);
const fetchLogin = useCallback(async addressWallet => {
setIsFetchingAuth(true);
try {
if (addressWallet) {
const store = JSON.parse(localStorage.getItem('store'));
const { state } = store;
let currToken = state?.token;
if (!state?.token) {
currToken = await createToken();
}
/**
* encrypting wallet
*/
const encryptedWallet = await encryptWallet(currToken, addressWallet?.toLowerCase());
const response = await doLogin({
wallet_address: encryptedWallet,
});
const { data } = response;
if (data?.is_active) {
setWallet(data?.wallet_address);
setProfile(data);
setLoggedIn(true);
setIsFetchingAuth(false);
signMessage();
} else {
revokeAccess();
}
} else {
revokeAccess();
}
} catch (error) {
revokeAccess();
}
}, []);
const handleDisconnect = useCallback(() => {
revokeAccess();
disconnect();
actions.clearUserInformationState();
// onClose();
}, [isDisconnected]);
useEffect(() => {
if (isConnected) {
if (wallet) {
if (isDifferentAccount) {
fetchLogin(address);
}
} else {
fetchLogin(address);
}
}
}, [isConnected, address]);
useEffect(() => {
if (signStatus === 'success') {
setWalletSignature(signData);
const htmlTag = document.documentElement as HTMLElement;
htmlTag.style.overflow = 'auto';
} else if (signStatus === 'error') {
revokeAccess();
}
}, [signStatus]);
return (
<>
<WalletContext.Provider
value={{
handleDisconnect,
isFetchingAuth,
signStatus,
accountStatus,
}}
>
{children}
</WalletContext.Provider>
</>
);
};
WalletProvider.defaultProps = {
children: undefined,
};
export const useWallet = () => {
const { handleDisconnect, isFetchingAuth, signStatus, accountStatus } = React.useContext(WalletContext);
return {
handleDisconnect,
isFetchingAuth,
signStatus,
accountStatus,
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment