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 = `http://rustchat.com:3000/api`;
const BASE_URL = `https://rustchat.com:3000/api`;
export const ContentTypes = {
text: "text/plain",
image: "image/png",
json: "application/json",
text: 'text/plain',
image: 'image/png',
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;
+11 -1
View File
@@ -25,10 +25,20 @@ export const authApi = createApi({
body: { magic_token: token }
})
}),
getMetamaskNonce: builder.query({
query: (address) => ({
url: `/token/metamask/nonce?public_address=${address}`
})
}),
logout: builder.query({
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 MetaMaskOnboarding from '@metamask/onboarding';
const ONBOARD_TEXT = 'Click here to install MetaMask!';
const CONNECT_TEXT = 'Sign in with MetaMask';
const CONNECTED_TEXT = 'Connected';
export default function MetamaskLoginButton() {
const [btnTxt, setBtnTxt] = useState(ONBOARD_TEXT);
const [isDisabled, setIsDisabled] = useState(false);
const [accounts, setAccounts] = useState([]);
import { useLazyGetMetamaskNonceQuery } from '../../app/services/auth';
export default function MetamaskLoginButton({ login }) {
const [requesting, setRequesting] = useState(false);
const [getNonce] = useLazyGetMetamaskNonceQuery();
const onboarding = useRef();
useEffect(() => {
if (!onboarding.current) {
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()) {
console.log(accounts);
if (accounts.length > 0) {
setBtnTxt(CONNECTED_TEXT);
setIsDisabled(true);
onboarding.current.stopOnboarding();
} else {
setBtnTxt(CONNECT_TEXT);
setIsDisabled(false);
setRequesting(true);
const [address] = await ethereum.request({
method: 'eth_requestAccounts'
});
const { data: nonce, isSuccess } = await getNonce(address);
if (isSuccess) {
const signature = await getSignature(address, nonce);
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 {
onboarding.current.startOnboarding();
}
};
return (
<button disabled={isDisabled} onClick={handleMetamaskLogin} href="#" className="btn social">
<button disabled={requesting} onClick={handleMetamaskLogin} href="#" className="btn social">
<img
className="icon"
src="https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg"
alt="meta mask icon"
/>
{btnTxt}
Sign in with MetaMask
</button>
);
}
+1 -1
View File
@@ -108,7 +108,7 @@ export default function LoginPage() {
</form>
<hr className="or" />
<GoogleLoginButton login={login} />
<MetamaskLoginButton />
<MetamaskLoginButton login={login} />
</div>
</StyledWrapper>
);