Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Chores (#73)
Browse files Browse the repository at this point in the history
* chore: restructure App

* chore: suffix page components with "Page"

* chore: add Recoil

* chore: rename WalletContext to AppContext and add useContract

* chore: lazy load pages

* chore: upgrade React to 18.1.0
  • Loading branch information
AlicanC committed May 3, 2022
1 parent 321cbde commit b752ae1
Show file tree
Hide file tree
Showing 18 changed files with 257 additions and 254 deletions.
10 changes: 6 additions & 4 deletions client/package.json
Expand Up @@ -10,17 +10,19 @@
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.4.0",
"@types/node": "^16.11.22",
"@types/react": "^18.0.7",
"@types/react-dom": "^18.0.0",
"@types/react": "^18.0.8",
"@types/react-dom": "^18.0.3",
"classnames": "^2.3.1",
"ethers": "^5.5.4",
"fuels": "^0.0.0-master-0177b66",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-icons": "^4.3.1",
"react-number-format": "^4.9.1",
"react-router-dom": "6",
"react-scripts": "5.0.1",
"recoil": "^0.7.2",
"recoil-persist": "^4.1.0",
"typescript": "^4.5.5",
"url-join": "^4.0.1",
"web-vitals": "^2.1.4"
Expand Down
58 changes: 15 additions & 43 deletions client/src/App.tsx
@@ -1,47 +1,19 @@
import "./index.css";
import { Routes as Router, Route, Navigate } from "react-router-dom";
import { Setup } from "src/pages/Setup";
import { Swap } from "src/pages/Swap";
import { Assets } from "src/pages/Assets";
import { Pages } from "src/types/pages";
import { Pool } from "src/pages/Pool";
import { MintToken } from "src/pages/MintToken";
import { RequireWallet } from "./components/RequireWallet";
import { MainLayout } from "./layouts/MainLayout";
import { RemoveLiquidity } from "./pages/RemoveLiquidity";
import { BrowserRouter } from "react-router-dom";
import { RecoilRoot } from "recoil";
import { AppContextProvider } from "src/context/AppContext";

function App() {
import AppRoutes from "./AppRoutes";

const { PUBLIC_URL } = process.env;

export default function App() {
return (
<Router>
<Route element={<MainLayout />}>
<Route
path="*"
element={<RequireWallet children={<Navigate to={Pages.assets} />} />}
/>
<Route path={Pages.setup} element={<Setup />} />
<Route
path={Pages.assets}
element={<RequireWallet children={<Assets />} />}
/>
<Route
path={Pages.swap}
element={<RequireWallet children={<Swap />} />}
/>
<Route
path={Pages.pool}
element={<RequireWallet children={<Pool />} />}
/>
<Route
path={Pages.mintToken}
element={<RequireWallet children={<MintToken />} />}
/>
<Route
path={Pages.removeLiquidity}
element={<RequireWallet children={<RemoveLiquidity />} />}
/>
</Route>
</Router>
<RecoilRoot>
<BrowserRouter basename={PUBLIC_URL}>
<AppContextProvider>
<AppRoutes />
</AppContextProvider>
</BrowserRouter>
</RecoilRoot>
);
}

export default App;
46 changes: 46 additions & 0 deletions client/src/AppRoutes.tsx
@@ -0,0 +1,46 @@
import { lazy } from "react";
import { Routes, Route, Navigate } from "react-router-dom";
import { RequireWallet } from "./components/RequireWallet";
import { MainLayout } from "./layouts/MainLayout";
import { Pages } from "./types/pages";

const SetupPage = lazy(() => import("src/pages/SetupPage"));
const SwapPage = lazy(() => import("src/pages/SwapPage"));
const AssetsPage = lazy(() => import("src/pages/AssetsPage"));
const PoolPage = lazy(() => import("src/pages/PoolPage"));
const MintTokenPage = lazy(() => import("src/pages/MintTokenPage"));
const RemoveLiquidityPage = lazy(() => import("./pages/RemoveLiquidityPage"));

export default function AppRoutes() {
return (
<Routes>
<Route element={<MainLayout />}>
<Route
path="*"
element={<RequireWallet children={<Navigate to={Pages.assets} />} />}
/>
<Route path={Pages.setup} element={<SetupPage />} />
<Route
path={Pages.assets}
element={<RequireWallet children={<AssetsPage />} />}
/>
<Route
path={Pages.swap}
element={<RequireWallet children={<SwapPage />} />}
/>
<Route
path={Pages.pool}
element={<RequireWallet children={<PoolPage />} />}
/>
<Route
path={Pages.mintToken}
element={<RequireWallet children={<MintTokenPage />} />}
/>
<Route
path={Pages.removeLiquidity}
element={<RequireWallet children={<RemoveLiquidityPage />} />}
/>
</Route>
</Routes>
);
}
6 changes: 2 additions & 4 deletions client/src/components/Header.tsx
@@ -1,7 +1,6 @@
import { useContext } from "react";
import fuelLogo from "src/assets/fuel-logo-512x512.png";
import { useLocation, useNavigate } from "react-router-dom";
import { WalletContext } from "src/context/WalletContext";
import { useWallet } from "src/context/AppContext";
import { Pages } from "src/types/pages";

const style = {
Expand All @@ -21,8 +20,7 @@ const Header = () => {
const navigate = useNavigate();
const location = useLocation();
const exists = Object.values(Pages).includes(location.pathname as Pages);
const { getWallet } = useContext(WalletContext);
const wallet = getWallet?.();
const wallet = useWallet();

return (
<div className={style.wrapper}>
Expand Down
5 changes: 2 additions & 3 deletions client/src/components/RequireWallet.tsx
@@ -1,10 +1,9 @@
import { Navigate } from "react-router-dom";
import { Pages } from "src/types/pages";
import { useWallet } from "src/context/WalletContext";
import { useWallet } from "src/context/AppContext";

export const RequireWallet = ({ children }: { children: JSX.Element }) => {
const { getWallet } = useWallet();
const wallet = getWallet();
const wallet = useWallet();

if (!wallet) {
return <Navigate to={Pages.setup} replace={true} />;
Expand Down
94 changes: 94 additions & 0 deletions client/src/context/AppContext.tsx
@@ -0,0 +1,94 @@
import React, { PropsWithChildren, useContext, useMemo } from "react";
import { Wallet, ScriptTransactionRequest, TransactionResult } from "fuels";
import { CoinETH } from "src/lib/constants";
import { randomBytes } from "ethers/lib/utils";
import { CONTRACT_ID, FAUCET_AMOUNT, FUEL_PROVIDER_URL } from "src/config";
import { atom, useRecoilState } from "recoil";
import { persistEffect } from "src/lib/recoilEffects";
import {
SwayswapContractAbi,
SwayswapContractAbi__factory,
} from "src/types/contracts";

interface AppContextValue {
wallet: Wallet | null;
contract: SwayswapContractAbi | null;
createWallet: () => void;
faucet: () => Promise<TransactionResult>;
}

const walletPrivateKeyState = atom<string | null>({
key: "privateKey",
default: null,
effects_UNSTABLE: [persistEffect],
});

export const AppContext = React.createContext<AppContextValue | null>(null);

export const useAppContext = () => useContext(AppContext)!;

export const useWallet = () => {
const { wallet } = useContext(AppContext)!;
return wallet;
};

export const useContract = () => {
const { contract } = useContext(AppContext)!;
return contract;
};

export const AppContextProvider = ({ children }: PropsWithChildren<{}>) => {
const [privateKey, setPrivateKey] = useRecoilState(walletPrivateKeyState);

const wallet = useMemo(() => {
if (!privateKey) return null;
return new Wallet(privateKey, FUEL_PROVIDER_URL);
}, [privateKey]);

const contract = useMemo(() => {
if (!wallet) return null;
return SwayswapContractAbi__factory.connect(CONTRACT_ID, wallet);
}, [wallet]);

return (
<AppContext.Provider
value={{
wallet,
contract,
createWallet: () => {
const wallet = Wallet.generate({
provider: FUEL_PROVIDER_URL,
});
setPrivateKey(wallet.privateKey);
return wallet;
},
faucet: async () => {
const transactionRequest = new ScriptTransactionRequest({
gasPrice: 0,
gasLimit: "0x0F4240",
script: "0x24400000",
scriptData: randomBytes(32),
});
// @ts-ignore
transactionRequest.addCoin({
id: "0x000000000000000000000000000000000000000000000000000000000000000000",
assetId: CoinETH,
amount: FAUCET_AMOUNT,
owner:
"0xf1e92c42b90934aa6372e30bc568a326f6e66a1a0288595e6e3fbd392a4f3e6e",
});
transactionRequest.addCoinOutput(
wallet!.address,
FAUCET_AMOUNT,
CoinETH
);
const submit = await wallet!.sendTransaction(transactionRequest);

return submit.wait();
},
}}
>
{children}
</AppContext.Provider>
);
};
86 changes: 0 additions & 86 deletions client/src/context/WalletContext.tsx

This file was deleted.

13 changes: 3 additions & 10 deletions client/src/index.tsx
@@ -1,22 +1,15 @@
import "./index.css";

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";
import { WalletProvider } from "src/context/WalletContext";

const { PUBLIC_URL } = process.env;

const container = document.getElementById("root");
const root = ReactDOM.createRoot(container!);
root.render(
<React.StrictMode>
<BrowserRouter basename={PUBLIC_URL}>
<WalletProvider>
<App />
</WalletProvider>
</BrowserRouter>
<App />
</React.StrictMode>
);

Expand Down
5 changes: 4 additions & 1 deletion client/src/layouts/MainLayout.tsx
@@ -1,5 +1,6 @@
import Header from "src/components/Header";
import { Outlet } from "react-router-dom";
import { Suspense } from "react";

const style = {
wrapper: `h-screen max-h-screen h-min-screen w-screen bg-[#282c34] text-white select-none flex flex-col justify-between`,
Expand All @@ -9,7 +10,9 @@ export function MainLayout() {
return (
<div className={style.wrapper}>
<Header />
<Outlet />
<Suspense fallback={<div>Loading...</div>}>
<Outlet />
</Suspense>
</div>
);
}
7 changes: 7 additions & 0 deletions client/src/lib/recoilEffects.ts
@@ -0,0 +1,7 @@
import { recoilPersist } from 'recoil-persist';
import { LocalStorageKey } from './constants';

export const persistEffect = recoilPersist({
key: `${LocalStorageKey}-state`,
storage: localStorage,
}).persistAtom;

0 comments on commit b752ae1

Please sign in to comment.