Skip to content

Commit

Permalink
switch to use router context
Browse files Browse the repository at this point in the history
  • Loading branch information
oveddan committed Feb 2, 2024
1 parent 3d30478 commit 0a9d734
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 155 deletions.
7 changes: 3 additions & 4 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { FormControl, Button, TextField, Divider, View, Card } from "reshaped";
import { useFormik } from "formik";
import { isAddress } from "viem";
import { useNavigate } from "react-router-dom";
import { useContext } from "react";
import { CurrentNetwork } from "./Root";
import { useNavigate, useOutletContext } from "react-router-dom";
import { NetworkContext } from "../components/Contexts";

function FormAddressInput() {
const navigate = useNavigate();

const network = useContext(CurrentNetwork);
const { currentNetwork: network } = useOutletContext<NetworkContext>();

const formik = useFormik({
initialValues: {
Expand Down
14 changes: 7 additions & 7 deletions src/app/CreateSafe.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { useCallback, useContext, useEffect, useState } from "react";
import { CurrentNetwork, WalletProviderContext } from "./Root";
import { useCallback, useEffect, useState } from "react";
import { Field, FieldArray, Formik } from "formik";
import { Text, Button, FormControl, TextField, View, useToast } from "reshaped";
import { allowedNetworks, contractNetworks } from "../chains";
import { isAddress } from "viem";
import { ethers } from "ethers";
import { EthersAdapter, SafeFactory } from "@safe-global/protocol-kit";
import { useNavigate } from "react-router-dom";
import { useNavigate, useOutletContext } from "react-router-dom";
import { AbstractSigner } from "ethers";
import { BrowserProvider } from "ethers";
import { NetworkContext } from "../components/Contexts";

function validateAddress(value: string) {
if (!isAddress(value)) {
Expand All @@ -30,8 +30,8 @@ function validateSafeArguments(values: any) {
}

export function CreateSafe() {
const provider = useContext(WalletProviderContext);
const network = useContext(CurrentNetwork);
const { walletProvider: provider } = useOutletContext<NetworkContext>();
const { currentNetwork: network } = useOutletContext<NetworkContext>();
const toaster = useToast();
const navigate = useNavigate();
const [signerInfo, setSignerInfo] = useState<
Expand All @@ -51,7 +51,7 @@ export function CreateSafe() {
if (provider) {
updateSignerInfo(provider);
}
}, [provider]);
}, [provider, updateSignerInfo]);

const submitCallback = useCallback(
async (data: any) => {
Expand Down Expand Up @@ -86,7 +86,7 @@ export function CreateSafe() {
});
}
},
[provider, signerInfo],
[navigate, network, signerInfo, toaster]
);

return (
Expand Down
55 changes: 10 additions & 45 deletions src/app/NewSafeProposal.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
import { Field, FieldArray, Formik } from "formik";
import { SafeInformation } from "../components/SafeInformation";
import { Card, View, Text, Button, useToast } from "reshaped";
import {
SyntheticEvent,
useCallback,
useContext,
useEffect,
useState,
} from "react";
import { SyntheticEvent, useCallback, useEffect, useState } from "react";
import { Address, Hex, formatEther } from "viem";
import { validateAddress, validateETH } from "../utils/validators";
import { GenericField } from "../components/GenericField";
import { DataActionPreview } from "../components/DataActionPreview";
import Safe, { EthersAdapter } from "@safe-global/protocol-kit";
import { WalletProviderContext } from "./Root";
import { ethers } from "ethers";
import { contractNetworks } from "../chains";
import { SafeInformationContext } from "./ViewSafe";
import {
DEFAULT_ACTION_ITEM,
DEFAULT_PROPOSAL,
Expand All @@ -30,6 +22,8 @@ import {
transformValuesToWei,
} from "../utils/etherFormatting";
import { BrowserProvider } from "ethers";
import { useOutletContext } from "react-router-dom";
import { NetworkContext, SafeContext } from "../components/Contexts";

const FormActionItem = ({
name,
Expand Down Expand Up @@ -140,36 +134,11 @@ const signAndExecuteTx = async ({
return executedTxn;
};

const useSafe = ({
provider,
safeAddress,
}: {
provider: BrowserProvider | null;
safeAddress: Address | undefined;
}) => {
const [safe, setSafe] = useState<Safe>();

useEffect(() => {
if (!provider || !safeAddress) {
return;
}

const loadSafe = async () => {
const adapter = await createSafeAdapter({ provider, safeAddress });
setSafe(adapter);
};

loadSafe();
}, [provider, safeAddress]);

return safe;
};

const useGetSafeTxApprovals = ({ proposal }: { proposal: Proposal }) => {
const safeInformation = useContext(SafeInformationContext);
const { safeInformation } = useOutletContext<SafeContext>();

const safeSdk = safeInformation?.safeSdk;
const safeSdk2 = safeInformation?.safeSdk2;
const safeSdk = safeInformation.safeSdk;
const safeSdk2 = safeInformation.safeSdk2;

const [approvers, setApprovers] = useState<Address[]>([]);

Expand All @@ -196,7 +165,7 @@ const useGetSafeTxApprovals = ({ proposal }: { proposal: Proposal }) => {
};

const useAccountAddress = () => {
const walletProvider = useContext(WalletProviderContext);
const { walletProvider } = useOutletContext<NetworkContext>();

const [address, setAddress] = useState<Address>();

Expand Down Expand Up @@ -244,12 +213,8 @@ const ViewProposal = ({
proposal: Proposal;
handleEditClicked: (evt: SyntheticEvent) => void;
}) => {
const safeInformation = useContext(SafeInformationContext);
const walletProvider = useContext(WalletProviderContext);
const safe = useSafe({
provider: walletProvider,
safeAddress: safeInformation?.address,
});
const { safeInformation } = useOutletContext<SafeContext>();
const safe = safeInformation.safeSdk;

const toaster = useToast();

Expand Down Expand Up @@ -380,7 +345,7 @@ const EditProposal = ({
}
setIsEditing(false);
},
[setIsEditing, setProposal],
[proposal, setIsEditing, setProposal, setProposalParams]
);

const defaultActions = proposal || DEFAULT_PROPOSAL;
Expand Down
49 changes: 34 additions & 15 deletions src/app/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { ethers } from "ethers";
import { createContext, useCallback, useEffect, useState } from "react";
import { Outlet } from "react-router-dom";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Outlet, useParams } from "react-router-dom";
import { Button, View } from "reshaped";
import { NetworkSwitcher } from "../components/NetworkSwitcher";
import { BrowserProvider } from "ethers";

export const WalletProviderContext =
createContext<null | ethers.BrowserProvider>(null);
export const CurrentNetwork = createContext(0);
import { NetworkContext } from "../components/Contexts";

export const Root = () => {
const [provider, setProvider] = useState<
ethers.BrowserProvider | undefined
>();
const networkIdFromRoute = useParams().networkId;

const [currentNetwork, setCurrentNetwork] = useState<number>(0);

const connectMetamask = useCallback(async () => {
Expand Down Expand Up @@ -43,7 +42,29 @@ export const Root = () => {
connectMetamask();
}, [connectMetamask]);

if (!provider) {
const networkContext: NetworkContext | undefined = useMemo(() => {
if (!provider) return;

return {
walletProvider: provider,
currentNetwork,
};
}, [provider, currentNetwork]);

useEffect(() => {
if (!networkIdFromRoute) return;
if (currentNetwork !== Number(networkIdFromRoute)) {
provider?.send("wallet_switchEthereumChain", [
{
chainId: `0x${parseInt(networkIdFromRoute).toString(16)}`,
},
]);

setCurrentNetwork(Number(networkIdFromRoute));
}
}, [currentNetwork, networkIdFromRoute, setCurrentNetwork, provider]);

if (!networkContext) {
return (
<View padding={10} justify="space-between" gap={6} direction="column">
<Button onClick={connectMetamask}>Connect Web3</Button>
Expand All @@ -52,13 +73,11 @@ export const Root = () => {
}

return (
<WalletProviderContext.Provider value={provider}>
<CurrentNetwork.Provider value={currentNetwork}>
<br />
<br />
<NetworkSwitcher {...{ currentNetwork, setCurrentNetwork, provider }} />
<Outlet />
</CurrentNetwork.Provider>
</WalletProviderContext.Provider>
<>
<br />
<br />
<NetworkSwitcher currentNetwork={networkIdFromRoute} />
<Outlet context={networkContext} />
</>
);
};
2 changes: 1 addition & 1 deletion src/app/SafeInformationPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Button, View } from "reshaped";
import { SafeInformation } from "../components/SafeInformation";
import { Link, useNavigate, useParams } from "react-router-dom";
import { useNavigate, useParams } from "react-router-dom";

export const SafeInformationPage = () => {
const { networkId, safeAddress } = useParams();
Expand Down
59 changes: 21 additions & 38 deletions src/app/ViewSafe.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import {
useState,
createContext,
useContext,
useEffect,
useCallback,
} from "react";
import { Outlet, useParams } from "react-router-dom";
import { WalletProviderContext } from "./Root";
import { useState, useEffect, useCallback, useMemo } from "react";
import { Outlet, useOutletContext, useParams } from "react-router-dom";
import { Signer, ethers } from "ethers";
import Safe, { EthersAdapter } from "@safe-global/protocol-kit";
import { contractNetworks } from "../chains";
import { Button, View, Text } from "reshaped";
import { Address } from "viem";
import { NetworkContext, SafeContext, SafeInformationType } from "../components/Contexts";

type SafeData = Awaited<ReturnType<typeof getSafeSDK>>;

Expand All @@ -35,27 +29,12 @@ async function getSafeSDK(safeAddress: string, signer: Signer) {
return { safeSdk, safeSdk2, signer };
}

type SafeInformationType = {
owners: string[];
threshold: number;
chainId: number;
nonce: number;
address: Address;
safeSdk: Safe;
safeSdk2: Safe;
};

export const SafeInformationContext = createContext<
SafeInformationType | undefined
>(undefined);

const useLoadSafeInformation = ({
safeData,
}: {
safeData: SafeData | undefined;
}) => {
const [safeInformation, setSafeInformation] = useState<SafeInformationType>();

useEffect(() => {
if (!safeData) return;

Expand All @@ -79,16 +58,15 @@ const useLoadSafeInformation = ({
};

loadSafeInfo();
}, [safeData]);
}, [safeData, setSafeInformation]);

return safeInformation;
};

export const ViewSafe = () => {
const params = useParams();
const [safeData, setSafeData] = useState<SafeData>();
const providerContext = useContext(WalletProviderContext);
// const currentNetwork = useContext(CurrentNetwork);
const { walletProvider: providerContext } = useOutletContext<NetworkContext>();

const setupSafe = useCallback(async () => {
if (params.safeAddress && providerContext) {
Expand Down Expand Up @@ -117,17 +95,22 @@ export const ViewSafe = () => {

const safeInformation = useLoadSafeInformation({ safeData });

const safeInformationContext: SafeContext |undefined = useMemo(() => {
if (!safeInformation) return;
return {
safeInformation
};
}, [safeInformation]);

return (
<SafeInformationContext.Provider value={safeInformation}>
<View paddingTop={8} paddingBottom={8}>
<Text variant="featured-2">View Safe</Text>
<View paddingTop={4} />
{safeData ? (
<Outlet />
) : (
<Button onClick={switchNetwork}>Switch network</Button>
)}
</View>
</SafeInformationContext.Provider>
<View paddingTop={8} paddingBottom={8}>
<Text variant="featured-2">View Safe</Text>
<View paddingTop={4} />
{safeInformationContext ? (
<Outlet context={safeInformationContext} />
) : (
<Button onClick={switchNetwork}>Switch network</Button>
)}
</View>
);
};
4 changes: 2 additions & 2 deletions src/app/Wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ const router = createHashRouter([
Component: Root,
children: [
{
path: "/",
path: "/safe/:networkId",
index: true,
Component: App,
},
{
path: "/create",
path: "/safe/:networkId/create",
Component: CreateSafe,
},
{
Expand Down
6 changes: 3 additions & 3 deletions src/components/AddressView.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useContext } from "react";
import { CurrentNetwork } from "../app/Root";
import { goerli, mainnet, optimism, zora, zoraTestnet } from "viem/chains";
import { useOutletContext } from "react-router-dom";
import { NetworkContext } from "./Contexts";

export const networkToExplorer = {
[mainnet.id]: "https://etherscan.io/",
Expand All @@ -17,7 +17,7 @@ export const AddressView = ({
address: `0x${string}`;
prettyName?: string;
}) => {
const currentNetwork = useContext(CurrentNetwork);
const currentNetwork = useOutletContext<NetworkContext>().currentNetwork;
// const { data: ensName } = useEns({ address, enabled: !prettyName });
const ensName = null;

Expand Down
Loading

0 comments on commit 0a9d734

Please sign in to comment.