Commit 8e52e6a5 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Auth: Switch the chain before signing the message when the user logs in with their wallet (#2673)

Fixes #2345
parent 0dd6087f
......@@ -3,7 +3,7 @@ import { useQueryClient } from '@tanstack/react-query';
import { useToggle } from '@uidotdev/usehooks';
import { useRouter } from 'next/router';
import React, { createContext, useContext, useEffect, useMemo, useCallback } from 'react';
import { useSignMessage } from 'wagmi';
import { useSignMessage, useSwitchChain } from 'wagmi';
import type {
RewardsUserBalancesResponse, RewardsUserDailyCheckResponse,
......@@ -118,6 +118,7 @@ export function RewardsContextProvider({ children }: Props) {
const apiFetch = useApiFetch();
const { address } = useAccount();
const { signMessageAsync } = useSignMessage();
const { switchChainAsync } = useSwitchChain();
const profileQuery = useProfileQuery();
const [ isLoginModalOpen, setIsLoginModalOpen ] = useToggle(false);
......@@ -220,6 +221,7 @@ export function RewardsContextProvider({ children }: Props) {
reward: null,
};
}
await switchChainAsync({ chainId: Number(config.chain.id) });
const message = getMessageToSign(address, nonceResponse.nonce, checkUserQuery.data?.exists, refCode);
const signature = await signMessageAsync({ message });
const loginResponse = await apiFetch('rewards_login', {
......@@ -241,7 +243,7 @@ export function RewardsContextProvider({ children }: Props) {
errorToast(_error);
throw _error;
}
}, [ apiFetch, address, signMessageAsync, errorToast, saveApiToken, checkUserQuery ]);
}, [ address, apiFetch, checkUserQuery.data?.exists, switchChainAsync, signMessageAsync, saveApiToken, errorToast ]);
// Claim daily reward
const claim = useCallback(async() => {
......
......@@ -29,7 +29,7 @@ export default function useCallMethodWalletClient(): (params: Params) => Promise
}
if (chainId && String(chainId) !== config.chain.id) {
await switchChainAsync?.({ chainId: Number(config.chain.id) });
await switchChainAsync({ chainId: Number(config.chain.id) });
}
const address = getAddress(addressHash);
......
......@@ -3,7 +3,7 @@ import { useAppKit } from '@reown/appkit/react';
import React from 'react';
import type { SubmitHandler } from 'react-hook-form';
import { FormProvider, useForm } from 'react-hook-form';
import { useSignMessage, useAccount } from 'wagmi';
import { useSignMessage, useAccount, useSwitchChain } from 'wagmi';
import type {
AddressVerificationFormSecondStepFields,
......@@ -84,6 +84,7 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
const onSubmit = handleSubmit(onFormSubmit);
const { signMessage, isPending: isSigning } = useSignMessage();
const { switchChainAsync } = useSwitchChain();
const handleSignMethodChange = React.useCallback(({ value }: { value: string | null }) => {
if (!value) {
......@@ -99,13 +100,14 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
openWeb3Modal();
}, [ clearErrors, openWeb3Modal ]);
const handleWeb3SignClick = React.useCallback(() => {
const handleWeb3SignClick = React.useCallback(async() => {
clearErrors('root');
if (!isConnected) {
return setError('root', { type: 'manual', message: 'Please connect to your Web3 wallet first' });
}
await switchChainAsync({ chainId: Number(config.chain.id) });
const message = getValues('message');
signMessage({ message }, {
onSuccess: (data) => {
......@@ -116,7 +118,7 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
return setError('root', { type: 'SIGNING_FAIL', message: (error as Error)?.message || 'Oops! Something went wrong' });
},
});
}, [ clearErrors, isConnected, getValues, signMessage, setError, setValue, onSubmit ]);
}, [ clearErrors, isConnected, getValues, signMessage, setError, setValue, onSubmit, switchChainAsync ]);
const handleManualSignClick = React.useCallback(() => {
clearErrors('root');
......
import React from 'react';
import { useSignMessage } from 'wagmi';
import { useSignMessage, useSwitchChain } from 'wagmi';
import type { UserInfo } from 'types/api/account';
import type { RewardsCheckUserResponse, RewardsConfigResponse, RewardsLoginResponse, RewardsNonceResponse } from 'types/api/rewards';
......@@ -53,6 +53,7 @@ function useSignInWithWallet({ onSuccess, onError, source = 'Login', isAuth, log
const apiFetch = useApiFetch();
const web3Wallet = useWeb3Wallet({ source });
const { signMessageAsync } = useSignMessage();
const { switchChainAsync } = useSwitchChain();
const getSiweMessage = React.useCallback(async(address: string) => {
try {
......@@ -99,6 +100,7 @@ function useSignInWithWallet({ onSuccess, onError, source = 'Login', isAuth, log
const proceedToAuth = React.useCallback(async(address: string) => {
try {
await switchChainAsync({ chainId: Number(config.chain.id) });
const siweMessage = await getSiweMessage(address);
const signature = await signMessageAsync({ message: siweMessage.message });
const recaptchaToken = await executeRecaptchaAsync();
......@@ -143,7 +145,7 @@ function useSignInWithWallet({ onSuccess, onError, source = 'Login', isAuth, log
} finally {
setIsPending(false);
}
}, [ getSiweMessage, signMessageAsync, executeRecaptchaAsync, isAuth, apiFetch, onSuccess, onError ]);
}, [ getSiweMessage, switchChainAsync, signMessageAsync, executeRecaptchaAsync, isAuth, apiFetch, onSuccess, onError ]);
const start = React.useCallback(() => {
setIsPending(true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment