feat: metamask login
This commit is contained in:
+8
-5
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user