feat: metamask login

This commit is contained in:
zerosoul
2022-02-17 14:26:52 +08:00
parent f14d978bcd
commit edb9c94b52
4 changed files with 51 additions and 46 deletions
+8 -5
View File
@@ -1,10 +1,13 @@
// const BASE_URL = `${location.origin}/api`; // const BASE_URL = `${location.origin}/api`;
const BASE_URL = `http://rustchat.com:3000/api`; const BASE_URL = `https://rustchat.com:3000/api`;
export const ContentTypes = { export const ContentTypes = {
text: "text/plain", text: 'text/plain',
image: "image/png", image: 'image/png',
json: "application/json", json: 'application/json'
}; };
export const tokenHeader = "X-API-Key"; export const googleClientID =
'418687074928-naojba82n9ktf0rkvnqoor4nhr54ql1b.apps.googleusercontent.com';
// "840319286941-6ds7lbvk55eq8mjortf68cb2ll65lprt.apps.googleusercontent.com";
export const tokenHeader = 'X-API-Key';
export default BASE_URL; export default BASE_URL;
+11 -1
View File
@@ -25,10 +25,20 @@ export const authApi = createApi({
body: { magic_token: token } body: { magic_token: token }
}) })
}), }),
getMetamaskNonce: builder.query({
query: (address) => ({
url: `/token/metamask/nonce?public_address=${address}`
})
}),
logout: builder.query({ logout: builder.query({
query: () => ({ url: `token/logout` }) query: () => ({ url: `token/logout` })
}) })
}) })
}); });
export const { useLoginMutation, useLazyLogoutQuery, useCheckInviteTokenValidMutation } = authApi; export const {
useLazyGetMetamaskNonceQuery,
useLoginMutation,
useLazyLogoutQuery,
useCheckInviteTokenValidMutation
} = authApi;
+31 -39
View File
@@ -1,62 +1,54 @@
/* eslint-disable no-undef */
import { useState, useEffect, useRef } from 'react'; import { useState, useEffect, useRef } from 'react';
import MetaMaskOnboarding from '@metamask/onboarding'; import MetaMaskOnboarding from '@metamask/onboarding';
const ONBOARD_TEXT = 'Click here to install MetaMask!'; import { useLazyGetMetamaskNonceQuery } from '../../app/services/auth';
const CONNECT_TEXT = 'Sign in with MetaMask'; export default function MetamaskLoginButton({ login }) {
const CONNECTED_TEXT = 'Connected'; const [requesting, setRequesting] = useState(false);
export default function MetamaskLoginButton() { const [getNonce] = useLazyGetMetamaskNonceQuery();
const [btnTxt, setBtnTxt] = useState(ONBOARD_TEXT);
const [isDisabled, setIsDisabled] = useState(false);
const [accounts, setAccounts] = useState([]);
const onboarding = useRef(); const onboarding = useRef();
useEffect(() => { useEffect(() => {
if (!onboarding.current) { if (!onboarding.current) {
onboarding.current = new MetaMaskOnboarding(); onboarding.current = new MetaMaskOnboarding();
} }
}, []); }, []);
useEffect(() => { const getSignature = async (address, nonce) => {
console.log('get sn');
const signature = await ethereum.request({
method: 'personal_sign',
params: [nonce, address, 'hello from rustchat']
});
return signature;
};
const handleMetamaskLogin = async () => {
if (MetaMaskOnboarding.isMetaMaskInstalled()) { if (MetaMaskOnboarding.isMetaMaskInstalled()) {
console.log(accounts); setRequesting(true);
if (accounts.length > 0) { const [address] = await ethereum.request({
setBtnTxt(CONNECTED_TEXT); method: 'eth_requestAccounts'
setIsDisabled(true); });
onboarding.current.stopOnboarding(); const { data: nonce, isSuccess } = await getNonce(address);
} else { if (isSuccess) {
setBtnTxt(CONNECT_TEXT); const signature = await getSignature(address, nonce);
setIsDisabled(false); login({
public_address: address,
nonce,
signature,
type: 'metamask'
});
setRequesting(false);
} }
}
}, [accounts]);
useEffect(() => {
function handleNewAccounts(newAccounts) {
setAccounts(newAccounts);
}
if (MetaMaskOnboarding.isMetaMaskInstalled()) {
window.ethereum.request({ method: 'eth_requestAccounts' }).then(handleNewAccounts);
window.ethereum.on('accountsChanged', handleNewAccounts);
return () => {
window.ethereum.off('accountsChanged', handleNewAccounts);
};
}
}, []);
const handleMetamaskLogin = () => {
if (MetaMaskOnboarding.isMetaMaskInstalled()) {
window.ethereum
.request({ method: 'eth_requestAccounts' })
.then((newAccounts) => setAccounts(newAccounts));
} else { } else {
onboarding.current.startOnboarding(); onboarding.current.startOnboarding();
} }
}; };
return ( return (
<button disabled={isDisabled} onClick={handleMetamaskLogin} href="#" className="btn social"> <button disabled={requesting} onClick={handleMetamaskLogin} href="#" className="btn social">
<img <img
className="icon" className="icon"
src="https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg" src="https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg"
alt="meta mask icon" alt="meta mask icon"
/> />
{btnTxt} Sign in with MetaMask
</button> </button>
); );
} }
+1 -1
View File
@@ -108,7 +108,7 @@ export default function LoginPage() {
</form> </form>
<hr className="or" /> <hr className="or" />
<GoogleLoginButton login={login} /> <GoogleLoginButton login={login} />
<MetamaskLoginButton /> <MetamaskLoginButton login={login} />
</div> </div>
</StyledWrapper> </StyledWrapper>
); );