Skip to content

Commit

Permalink
Refactor code and update dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
truemiller committed Feb 18, 2024
1 parent c3c1a07 commit cfad86a
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 48 deletions.
2 changes: 1 addition & 1 deletion frontend/components/Spawn/SpawnDone/SpawnDone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useRouter } from "next/router";
export const SpawnDone = () => {
const router = useRouter();

const { resetSpawn } = useSpawn();
const { resetSpawnScreenState: resetSpawn } = useSpawn();
const { resetTabs } = useTabs();
const { updateServicesState } = useServices();

Expand Down
38 changes: 24 additions & 14 deletions frontend/components/Spawn/SpawnRPC/SpawnRPC.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
} from "@ant-design/icons";
import { Service, ServiceTemplate } from "@/client";
import { InputStatus } from "antd/es/_util/statusUtils";
import _ from "lodash";

enum RPCState {
LOADING,
Expand All @@ -44,33 +45,42 @@ export const SpawnRPC = ({
setService: Dispatch<SetStateAction<Service | undefined>>;
nextPage: SpawnScreenState;
}) => {
const { setSpawnScreenState } = useSpawn();
const { setSpawnScreenState } = useSpawn(isStaking);
const { createService } = useServices();
const { checkRPC } = useEthers();

const [rpc, setRpc] = useState("http://localhost:8545"); // default to hardhat node during development
const [continueIsLoading, setContinueIsLoading] = useState(false);
const [isCheckingRpc, setIsCheckingRpc] = useState(false);
const [rpcState, setRpcState] = useState<RPCState>(RPCState.INVALID);

const handlePaste = () => {
navigator.clipboard.readText().then((text) => setRpc(text));
};

const handleRpcChange = useCallback(
async (e: React.ChangeEvent<HTMLInputElement>) => {
setRpcState(RPCState.LOADING);
setRpc(e.target.value);
checkRPC(e.target.value).then((isValid) => {
try {
isValid ? setRpcState(RPCState.VALID) : setRpcState(RPCState.INVALID);
} catch (e) {
setRpcState(RPCState.INVALID);
}
});
},
[checkRPC],
// eslint-disable-next-line react-hooks/exhaustive-deps
const debounceCheckRpc = useCallback(
_.debounce((rpc: string) => {
if (isCheckingRpc) return;
setIsCheckingRpc(true);
checkRPC(rpc)
.then((valid) => setRpcState(valid ? RPCState.VALID : RPCState.INVALID))
.catch(() => {
message.error("Failed to check RPC");
})
.finally(() => setIsCheckingRpc(false));
}, 1000),
// eslint-disable-next-line react-hooks/exhaustive-deps
[],
);

// eslint-disable-next-line react-hooks/exhaustive-deps
const handleRpcChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setRpc(e.target.value);
setRpcState(RPCState.LOADING);
debounceCheckRpc(e.target.value);
};

const handleContinue = useCallback(async () => {
if (continueIsLoading)
return message.info("Please wait for the current action to complete");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@ export const SpawnStakingCheck = ({
};

return (
<Flex gap={8} vertical justify="center">
<Typography.Text strong>Would you like to stake OLAS?</Typography.Text>
<Flex gap={8} vertical>
<Flex justify="center">
<Typography.Text strong>Would you like to stake OLAS?</Typography.Text>
</Flex>
<Flex gap={8} justify="center">
<Button onClick={handleYes}>Yes</Button>
<Button type="primary" onClick={handleYes}>
Yes
</Button>
<Button onClick={handleNo}>No</Button>
</Flex>
</Flex>
Expand Down
7 changes: 5 additions & 2 deletions frontend/context/SpawnProvider/SpawnProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import {

type SpawnContextType = {
spawnScreenState: SpawnScreenState;
firstSpawnScreenState: SpawnScreenState;
setSpawnScreenState: Dispatch<SetStateAction<SpawnScreenState>>;
};

const FIRST_PAGE = SpawnScreenState.STAKING_CHECK;

export const SpawnContext = createContext<SpawnContextType>({
spawnScreenState: FIRST_PAGE,
firstSpawnScreenState: FIRST_PAGE,
setSpawnScreenState: () => {},
});

Expand All @@ -25,8 +27,9 @@ export const SpawnProvider = ({ children }: PropsWithChildren) => {
return (
<SpawnContext.Provider
value={{
spawnScreenState: spawnScreenState,
setSpawnScreenState: setSpawnScreenState,
firstSpawnScreenState: FIRST_PAGE,
spawnScreenState,
setSpawnScreenState,
}}
>
{children}
Expand Down
6 changes: 5 additions & 1 deletion frontend/hooks/useEthers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ export const useEthers = () => {
* @param rpc string
* @returns Promise<number>
*/
const getETHBalance = (address: string, rpc: string): Promise<number> => {
const getETHBalance = async (
address: string,
rpc: string,
): Promise<number> => {
const provider = new providers.JsonRpcProvider(rpc, {
name: "Gnosis",
chainId: 100, // we currently only support Gnosis Trader agent
Expand Down Expand Up @@ -54,6 +57,7 @@ export const useEthers = () => {
* @returns Promise<boolean>
*/
const checkRPC = async (rpc: string): Promise<boolean> => {
if (!rpc) return false;
const provider = new providers.JsonRpcProvider(rpc, {
name: "Gnosis",
chainId: 100, // we currently only support Gnosis Trader agent
Expand Down
6 changes: 4 additions & 2 deletions frontend/hooks/useMarketplace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { serviceTemplates } from "@/constants/serviceTemplates";

export const useMarketplace = () => {
const getServiceTemplates = (): ServiceTemplate[] => serviceTemplates;
const getServiceTemplate = (hash: string): ServiceTemplate | undefined =>
serviceTemplates.find((template) => template.hash === hash);
const getServiceTemplate = (hash: string): ServiceTemplate =>
serviceTemplates.find(
(template) => template.hash === hash,
) as ServiceTemplate;

return {
getServiceTemplate,
Expand Down
9 changes: 4 additions & 5 deletions frontend/hooks/useMulticall.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MULTICALL_CONTRACT } from "@/constants/contracts";
import { BigNumber, ethers } from "ethers";
import { Contract, Provider } from "ethers-multicall";
import { Contract, ContractCall, Provider } from "ethers-multicall";
import { multicall3Abi } from "@/abi/multicall3Abi";

export const useMulticall = () => {
Expand All @@ -10,12 +10,11 @@ export const useMulticall = () => {
): Promise<{ [address: string]: number }> => {
const provider = new ethers.providers.JsonRpcProvider(rpc);
const multicallProvider = new Provider(provider, 100);

const multicallContract = new Contract(MULTICALL_CONTRACT, multicall3Abi);

const callData = addresses.map((address) => {
return multicallContract.getEthBalance(address);
});
const callData: ContractCall[] = addresses.map((address: string) =>
multicallContract.getEthBalance(address),
);

return multicallProvider.all(callData).then((r: BigNumber[]) =>
r.reduce(
Expand Down
50 changes: 38 additions & 12 deletions frontend/hooks/useSpawn.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,51 @@
import { SpawnContext } from "@/context";
import { SpawnScreenState } from "@/enums";
import { useContext, useMemo } from "react";
import { useCallback, useContext, useMemo } from "react";

export const useSpawn = () => {
const { spawnScreenState, setSpawnScreenState } = useContext(SpawnContext);
export const useSpawn = (isStaking?: boolean) => {
const { spawnScreenState, setSpawnScreenState, firstSpawnScreenState } =
useContext(SpawnContext);

const spawnPercentage = useMemo(() => {
if (spawnScreenState === SpawnScreenState.RPC) return 33;
if (spawnScreenState === SpawnScreenState.AGENT_FUNDING) return 66;
if (spawnScreenState === SpawnScreenState.DONE) return 100;
const spawnPercentage: number = useMemo(() => {
if (spawnScreenState === SpawnScreenState.STAKING_CHECK) return 0;
// Staking path
if (isStaking) {
switch (spawnScreenState) {
case SpawnScreenState.RPC:
return 25;
case SpawnScreenState.STAKING_FUNDING:
return 50;
case SpawnScreenState.AGENT_FUNDING:
return 75;
case SpawnScreenState.DONE:
return 100;
default:
break;
}
}
// Non-staking path
switch (spawnScreenState) {
case SpawnScreenState.RPC:
return 33;
case SpawnScreenState.AGENT_FUNDING:
return 66;
case SpawnScreenState.DONE:
return 100;
default:
break;
}
return 0;
}, [spawnScreenState]);
}, [isStaking, spawnScreenState]);

const resetSpawn = () => {
setSpawnScreenState(SpawnScreenState.STAKING_CHECK);
};
const resetSpawnScreenState = useCallback(
(): void => setSpawnScreenState(firstSpawnScreenState),
[firstSpawnScreenState, setSpawnScreenState],
);

return {
spawnScreenState,
setSpawnScreenState,
spawnPercentage,
resetSpawn,
resetSpawnScreenState,
};
};
5 changes: 1 addition & 4 deletions frontend/hooks/useTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import { useContext } from "react";
export const useTabs = () => {
const { activeTab, setActiveTab } = useContext(TabsContext);

const resetTabs = () => {
setActiveTab(Tab.YOUR_AGENTS);
};

const resetTabs = () => setActiveTab(Tab.YOUR_AGENTS);
return { activeTab, setActiveTab, resetTabs };
};
2 changes: 2 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"@ant-design/icons": "^5.3.0",
"antd": "^5.14.0",
"ethers": "5.7.2",
"lodash": "^4.17.21",
"next": "14.1.0",
"react": "^18",
"react-dom": "^18",
Expand All @@ -15,6 +16,7 @@
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.1",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.14.202",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
Expand Down
6 changes: 3 additions & 3 deletions frontend/pages/spawn/[serviceTemplateHash].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ export const SpawnPage = ({
const { spawnScreenState, setSpawnScreenState } = useSpawn();
const { getServiceTemplate } = useMarketplace();

const [service, setService] = useState<Service | undefined>();
const [service, setService] = useState<Service>();
const [isStaking, setIsStaking] = useState<boolean>(false);

const serviceTemplate = useMemo(
const serviceTemplate: ServiceTemplate = useMemo(
() => getServiceTemplate(serviceTemplateHash),
[getServiceTemplate, serviceTemplateHash],
) as ServiceTemplate;
);

const [agentFundRequirements, setAgentFundRequirements] = useState<{
[address: string]: number;
Expand Down
7 changes: 6 additions & 1 deletion frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1374,6 +1374,11 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==

"@types/lodash@^4.14.202":
version "4.14.202"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8"
integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==

"@types/node@*", "@types/node@^20":
version "20.11.18"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.18.tgz#06912d152e47c2ac0a393c62141e623ca6005d46"
Expand Down Expand Up @@ -4247,7 +4252,7 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==

lodash@^4.17.15:
lodash@^4.17.15, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
Expand Down
15 changes: 15 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "es6",
"module": "ESNext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
// "resolveJsonModule": true,
"moduleResolution": "Bundler",
"outDir": "./dist" // Output directory for compiled JavaScript files
},
"include": ["electron/**/*.ts", "electron/main.js"], // Path to your TypeScript source files
"exclude": ["node_modules", "backend", "frontend", "dist"]
}

0 comments on commit cfad86a

Please sign in to comment.