diff --git a/.env b/.env
deleted file mode 100644
index 572274e..0000000
--- a/.env
+++ /dev/null
@@ -1 +0,0 @@
-NEXT_PUBLIC_NETWORK=testnet
\ No newline at end of file
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..4d3c330
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,2 @@
+NEXT_PUBLIC_NETWORK=NETWORK
+NEXT_PUBLIC_AUTH_URL=AUTH_ENDPOINT
\ No newline at end of file
diff --git a/components/profile/menu-list.tsx b/components/profile/menu-list.tsx
index 7798888..b4b2d2d 100644
--- a/components/profile/menu-list.tsx
+++ b/components/profile/menu-list.tsx
@@ -3,6 +3,9 @@ import { Div } from '@stylin.js/elements';
import { not } from 'ramda';
import { FC, useState } from 'react';
+import { MEMEZ_FUN_TOKEN_AUTH } from '@/constants';
+import { useCookie } from '@/hooks/use-cookie';
+
import {
DocIDSVG,
ExplorerSVG,
@@ -20,9 +23,22 @@ import RPCCollapseMenuInfo from './rpc-collapse-info';
const MenuList: FC = () => {
const [isActiveNSFE, setIsActiveNSFE] = useState(false);
const [isRPCMenuOpen, setIsRPCMenuOpen] = useState(false);
+ const { mutate: disconnectWallet } = useDisconnectWallet();
+ const { cookie: bearerToken } = useCookie(MEMEZ_FUN_TOKEN_AUTH);
const [isAccountMenuOpen, setIsAccountMenuOpen] = useState(false);
const [isExplorerMenuOpen, setIsExplorerMenuOpen] = useState(false);
- const { mutate: disconnectWallet } = useDisconnectWallet();
+
+ const handleDisconnectWallet = () => {
+ fetch(`${process.env.NEXT_PUBLIC_AUTH_URL}/sign-out`, {
+ method: 'DELETE',
+ mode: 'cors',
+ headers: {
+ Authorization: `Bearer ${bearerToken}`,
+ },
+ }).then((res) => {
+ res.ok && disconnectWallet();
+ });
+ };
return (
@@ -58,7 +74,7 @@ const MenuList: FC = () => {
Icon={LogoutSVG}
title="Disconnect"
color="#E85965"
- onClick={() => disconnectWallet()}
+ onClick={handleDisconnectWallet}
/>
);
diff --git a/constants/index.ts b/constants/index.ts
index dadc0b8..4b589b5 100644
--- a/constants/index.ts
+++ b/constants/index.ts
@@ -3,3 +3,5 @@ export * from './math';
export * from './network';
export * from './routes';
export const DROPDOWN_DATA = ['Days', 'Weeks', 'Months'];
+
+export const MEMEZ_FUN_TOKEN_AUTH = 'MEMEZ_FUN_TOKEN_AUTH';
diff --git a/hooks/use-cookie/index.ts b/hooks/use-cookie/index.ts
new file mode 100644
index 0000000..186f97a
--- /dev/null
+++ b/hooks/use-cookie/index.ts
@@ -0,0 +1,34 @@
+import { useState } from 'react';
+const setCookie = (name: string, value: string, days: number) => {
+ const expires = new Date();
+ expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000);
+ document.cookie = `${name}=${value}; expires=${expires.toUTCString()}; path=/`;
+};
+
+const getCookie = (name: string): string | null => {
+ const value = `; ${document.cookie}`;
+ const parts = value.split(`; ${name}=`);
+ if (parts.length === 2) return parts.pop()?.split(';').shift() || null;
+ return null;
+};
+
+const deleteCookie = (name: string) => {
+ document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;
+};
+export const useCookie = (name: string) => {
+ const [cookie, setCookieState] = useState(() =>
+ getCookie(name)
+ );
+
+ const set = (value: string, days: number = 365) => {
+ setCookie(name, value, days);
+ setCookieState(value);
+ };
+
+ const remove = () => {
+ deleteCookie(name);
+ setCookieState(null);
+ };
+
+ return { cookie, set, remove } as const;
+};
diff --git a/pages/_document.tsx b/pages/_document.tsx
index 9a68613..1bbfe76 100644
--- a/pages/_document.tsx
+++ b/pages/_document.tsx
@@ -2,7 +2,12 @@ import { Head, Html, Main, NextScript } from 'next/document';
const Document = () => (
-
+
+
+
diff --git a/views/sign-in/index.tsx b/views/sign-in/index.tsx
index 80fc16f..7b2a4c6 100644
--- a/views/sign-in/index.tsx
+++ b/views/sign-in/index.tsx
@@ -43,8 +43,10 @@ const SignIn: FC = () => {
-
-
+
{
- const { setValue, trigger } = useFormContext
();
const { dialog, handleClose } = useDialog();
const handleOpenConnectModal = useConnectModal();
+ const { mutate: disconnectWallet } = useDisconnectWallet();
+ const { set: setCookie } = useCookie(MEMEZ_FUN_TOKEN_AUTH);
+ const { getValues, handleSubmit } = useFormContext();
+ const { push } = useRouter();
- const handleCreateProfile = () => {
- return new Promise((resolve, reject) => {
- setTimeout(() => {
- const isSuccess = Math.random() > 0.5;
- if (isSuccess) {
- setValue('success', true);
- resolve('success');
- return;
- }
- reject('Error');
- }, 1000);
- });
- };
+ const scheduleTimeToDisconnect = () => {
+ const oneHour = 60 * 60 * 1000;
+ const disconnectTimer = setTimeout(() => {
+ disconnectWallet();
+ push(RoutesEnum.SignIn);
+ }, oneHour);
- const handleSignIn = async () => {
- let fieldsToValidate: (keyof SignInFormProps)[] = [];
+ return disconnectTimer;
+ };
- fieldsToValidate = ['username', 'password'];
- const isValid = await trigger(fieldsToValidate);
+ const onSignIn = async () => {
+ const { username, password } = getValues();
+ const body = JSON.stringify({
+ username,
+ password,
+ });
+ return await fetch(`${process.env.NEXT_PUBLIC_AUTH_URL}/sign-in`, {
+ method: 'POST',
+ mode: 'cors',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body,
+ }).then(async (res) => {
+ const response = await res.json();
+ scheduleTimeToDisconnect();
+ if (!res.ok) {
+ throw new Error(`${response.error}: ${response.message}`);
+ }
+ setCookie(response.accessToken);
+ return;
+ });
+ };
- if (isValid) {
- await dialog.promise(handleCreateProfile(), {
- success: () => ({
- title: 'Sign-in successful',
- button: (
-
- ),
- ghostButton: (
-
- ),
- message: 'Now connect your wallet do see all the function',
- }),
- loading: () => ({
- Icon: ,
- title: 'Signing...',
- message: 'Please wait...',
- }),
- error: (e) => ({
- title: 'Oops! You can not sign in!',
- button: { label: 'Try again', onClick: handleClose },
- message: (
- e.message ||
- 'Make sure you fill every field correctly and try again.'
- ).replace('Invariant failed: ', ''),
- ghostButton: {
- label: 'Do not want to try again!',
- onClick: handleClose,
- },
- }),
- });
- }
- if (!isValid) return;
+ const handleSignIn = () => {
+ dialog.promise(onSignIn(), {
+ success: () => ({
+ title: 'Sign-in successful',
+ button: (
+
+ ),
+ ghostButton: (
+
+ ),
+ message: 'Now connect your wallet do see all the function',
+ }),
+ loading: () => ({
+ Icon: ,
+ title: 'Signing...',
+ message: 'Please wait...',
+ }),
+ error: (e) => ({
+ title: 'Oops! You can not sign in!',
+ button: { label: 'Try again', onClick: handleClose },
+ message: (
+ e.message || 'Make sure you fill every field correctly and try again.'
+ ).replace('Invariant failed: ', ''),
+ ghostButton: {
+ label: 'Do not want to try again!',
+ onClick: handleClose,
+ },
+ }),
+ });
};
return (
-
+