From 62ac05e40f3a1c08cca11fe97127fa6e99c4ef75 Mon Sep 17 00:00:00 2001 From: Josh Miller Date: Thu, 22 Feb 2024 14:34:30 +0000 Subject: [PATCH] Fix variable naming conventions --- .../copyToClipboard.ts | 0 frontend/components/Modals/QRModal.tsx | 2 +- .../FundRequirement/FundRequirement.tsx | 9 ++++- .../FundRequirement/FundRequirementERC20.tsx | 2 +- .../FundRequirement/FundRequirementETH.tsx | 2 +- frontend/components/Spawn/SpawnRPC.tsx | 39 +++++++++++++++++-- .../components/Spawn/SpawnStakingCheck.tsx | 26 +++++-------- frontend/components/YourAgents/HasAgents.tsx | 3 +- .../ServiceCard/ServiceCardTotalBalance.tsx | 4 +- .../context/ModalsProvider/ModalsProvider.tsx | 4 +- .../context/TabsProvider/TabsProvider.tsx | 6 +-- frontend/hooks/useEthers.tsx | 19 +++++---- frontend/hooks/useModals.tsx | 2 +- frontend/hooks/useMulticall.tsx | 6 +-- frontend/hooks/useTabs.tsx | 4 +- frontend/pages/index.tsx | 30 +++++++------- frontend/types/QRModalData.ts | 2 +- 17 files changed, 98 insertions(+), 62 deletions(-) rename frontend/{helpers => common-util}/copyToClipboard.ts (100%) diff --git a/frontend/helpers/copyToClipboard.ts b/frontend/common-util/copyToClipboard.ts similarity index 100% rename from frontend/helpers/copyToClipboard.ts rename to frontend/common-util/copyToClipboard.ts diff --git a/frontend/components/Modals/QRModal.tsx b/frontend/components/Modals/QRModal.tsx index a605ec461..41191dd22 100644 --- a/frontend/components/Modals/QRModal.tsx +++ b/frontend/components/Modals/QRModal.tsx @@ -9,7 +9,7 @@ type QRModalProps = { }; export const QRModal = ({ - data: { amount, chainId, address, open, isERC20 }, + data: { amount, chainId, address, open, isErc20: isERC20 }, }: QRModalProps) => { const { setQrModalData } = useModals(); diff --git a/frontend/components/Spawn/Funding/FundRequirement/FundRequirement.tsx b/frontend/components/Spawn/Funding/FundRequirement/FundRequirement.tsx index 27804576e..989d58dc2 100644 --- a/frontend/components/Spawn/Funding/FundRequirement/FundRequirement.tsx +++ b/frontend/components/Spawn/Funding/FundRequirement/FundRequirement.tsx @@ -1,4 +1,4 @@ -import { copyToClipboard } from '@/helpers/copyToClipboard'; +import { copyToClipboard } from '@/common-util/copyToClipboard'; import { useModals, useServices } from '@/hooks'; import { Address } from '@/types'; import { FundsReceivedMap } from '@/types'; @@ -70,7 +70,12 @@ export const FundRequirement = ({ const handleQr = useCallback( (): void => - qrModalOpen({ amount: requirement, chainId: 100, address, isERC20 }), // hardcoded chainId for now + qrModalOpen({ + amount: requirement, + chainId: 100, + address, + isErc20: isERC20, + }), // hardcoded chainId for now [address, isERC20, qrModalOpen, requirement], ); diff --git a/frontend/components/Spawn/Funding/FundRequirement/FundRequirementERC20.tsx b/frontend/components/Spawn/Funding/FundRequirement/FundRequirementERC20.tsx index 1a15c049f..df633b0dc 100644 --- a/frontend/components/Spawn/Funding/FundRequirement/FundRequirementERC20.tsx +++ b/frontend/components/Spawn/Funding/FundRequirement/FundRequirementERC20.tsx @@ -14,7 +14,7 @@ type FundRequirementERC20Props = { }; export const FundRequirementERC20 = (props: FundRequirementERC20Props) => { - const { getERC20Balance } = useEthers(); + const { getErc20Balance: getERC20Balance } = useEthers(); return ( ); diff --git a/frontend/components/Spawn/Funding/FundRequirement/FundRequirementETH.tsx b/frontend/components/Spawn/Funding/FundRequirement/FundRequirementETH.tsx index a50b5c174..d3a0e091f 100644 --- a/frontend/components/Spawn/Funding/FundRequirement/FundRequirementETH.tsx +++ b/frontend/components/Spawn/Funding/FundRequirement/FundRequirementETH.tsx @@ -13,7 +13,7 @@ type FundRequirementETHProps = { }; export const FundRequirementETH = (props: FundRequirementETHProps) => { - const { getETHBalance } = useEthers(); + const { getEthBalance: getETHBalance } = useEthers(); return ( ); diff --git a/frontend/components/Spawn/SpawnRPC.tsx b/frontend/components/Spawn/SpawnRPC.tsx index e86e95ca6..ca519ecaf 100644 --- a/frontend/components/Spawn/SpawnRPC.tsx +++ b/frontend/components/Spawn/SpawnRPC.tsx @@ -17,7 +17,7 @@ import { useMemo, useState, } from 'react'; -import { useSpawn, useEthers } from '@/hooks'; +import { useSpawn, useEthers, useAppInfo } from '@/hooks'; import { SpawnScreenState } from '@/enums'; import { CheckSquareTwoTone, WarningFilled } from '@ant-design/icons'; import { InputStatus } from 'antd/es/_util/statusUtils'; @@ -37,7 +37,8 @@ type SpawnRPCProps = { export const SpawnRPC = ({ rpc, setRpc, nextPage }: SpawnRPCProps) => { const { setSpawnScreenState } = useSpawn(); - const { checkRPC } = useEthers(); + const { checkRPC, getEthBalance } = useEthers(); + const { userPublicKey } = useAppInfo(); const [isCheckingRpc, setIsCheckingRpc] = useState(false); const [rpcState, setRpcState] = useState(RPCState.INVALID); @@ -82,12 +83,44 @@ export const SpawnRPC = ({ rpc, setRpc, nextPage }: SpawnRPCProps) => { ); const handleContinue = useCallback(async () => { + if (!userPublicKey) { + message.error( + 'Error retrieving user public key, please ensure your master wallet key is set correctly', + ); + return; + } + if (!rpc || rpcState !== RPCState.VALID) { message.error('Invalid RPC'); return; } + + const ethBalance: number | undefined = await getEthBalance( + userPublicKey, + rpc, + ).catch(() => undefined); + + if (ethBalance === undefined) { + message.error('Failed to get master wallet balance'); + return; + } + + if (ethBalance < 1) { + message.error( + 'Insufficient master wallet balance, you need at least 1 XDAI.', + ); + return; + } + setSpawnScreenState(nextPage); - }, [nextPage, rpc, rpcState, setSpawnScreenState]); + }, [ + getEthBalance, + nextPage, + rpc, + rpcState, + setSpawnScreenState, + userPublicKey, + ]); const isContinueDisabled: boolean = useMemo( () => !rpc || rpcState !== RPCState.VALID, diff --git a/frontend/components/Spawn/SpawnStakingCheck.tsx b/frontend/components/Spawn/SpawnStakingCheck.tsx index 5990cda6b..7c1a219f2 100644 --- a/frontend/components/Spawn/SpawnStakingCheck.tsx +++ b/frontend/components/Spawn/SpawnStakingCheck.tsx @@ -39,7 +39,7 @@ export const SpawnStakingCheck = ({ }: SpawnStakingCheckProps) => { const { createService } = useServices(); const { userPublicKey } = useAppInfo(); - const { getERC20Balance } = useEthers(); + const { getErc20Balance } = useEthers(); const [isCreating, setIsCreating] = useState(false); const [buttonClicked, setButtonClicked] = useState(); @@ -112,7 +112,7 @@ export const SpawnStakingCheck = ({ if (!userPublicKey) { return Promise.reject('No public key found'); } - return getERC20Balance(userPublicKey, rpc, TOKENS.gnosis.OLAS) + return getErc20Balance(userPublicKey, rpc, TOKENS.gnosis.OLAS) .then((olasBalance: number) => { const { olas_required_to_stake, olas_cost_of_bond } = serviceTemplate.configuration; @@ -132,7 +132,7 @@ export const SpawnStakingCheck = ({ .catch((e) => { return Promise.reject(e); }); - }, [getERC20Balance, userPublicKey, rpc, serviceTemplate.configuration]); + }, [getErc20Balance, userPublicKey, rpc, serviceTemplate.configuration]); const handleYes = async () => { setButtonClicked(ButtonOptions.YES); @@ -180,19 +180,13 @@ export const SpawnStakingCheck = ({ setButtonClicked(undefined); }; - const stakingRequirement = useMemo( - () => - ethers.utils.formatUnits( - `${ - serviceTemplate.configuration.olas_cost_of_bond + - serviceTemplate.configuration.olas_required_to_stake - }`, - ), - [ - serviceTemplate.configuration.olas_cost_of_bond, - serviceTemplate.configuration.olas_required_to_stake, - ], - ); + const stakingRequirement = useMemo(() => { + const { olas_required_to_stake, olas_cost_of_bond } = + serviceTemplate.configuration; + return ethers.utils.formatUnits( + `${olas_required_to_stake + olas_cost_of_bond}`, + ); + }, [serviceTemplate.configuration]); return ( diff --git a/frontend/components/YourAgents/HasAgents.tsx b/frontend/components/YourAgents/HasAgents.tsx index 3c351b04e..8face25e4 100644 --- a/frontend/components/YourAgents/HasAgents.tsx +++ b/frontend/components/YourAgents/HasAgents.tsx @@ -1,12 +1,13 @@ import { Service } from '@/client'; import { Flex } from 'antd'; import { ServiceCard } from './ServiceCard/ServiceCard'; +import { ReactElement } from 'react'; export const HasAgents = ({ services, }: { services: Service[]; -}): JSX.Element => { +}): ReactElement => { return ( {services.map((service: Service) => ( diff --git a/frontend/components/YourAgents/ServiceCard/ServiceCardTotalBalance.tsx b/frontend/components/YourAgents/ServiceCard/ServiceCardTotalBalance.tsx index 2e13025b3..5d4cec4fc 100644 --- a/frontend/components/YourAgents/ServiceCard/ServiceCardTotalBalance.tsx +++ b/frontend/components/YourAgents/ServiceCard/ServiceCardTotalBalance.tsx @@ -8,7 +8,7 @@ import { useInterval } from 'usehooks-ts'; const BALANCE_POLLING_INTERVAL = 5000; export const ServiceCardTotalBalance = ({ service }: { service: Service }) => { - const { getETHBalances } = useMulticall(); + const { getEthBalances } = useMulticall(); const [hasInitialLoaded, setHasInitialLoaded] = useState(false); const [balances, setBalances] = useState({}); @@ -27,7 +27,7 @@ export const ServiceCardTotalBalance = ({ service }: { service: Service }) => { service.chain_data?.multisig && service.ledger?.rpc ) - getETHBalances( + getEthBalances( [...service.chain_data.instances, service.chain_data.multisig], service.ledger.rpc, ) diff --git a/frontend/context/ModalsProvider/ModalsProvider.tsx b/frontend/context/ModalsProvider/ModalsProvider.tsx index 5277a9b19..4662a379f 100644 --- a/frontend/context/ModalsProvider/ModalsProvider.tsx +++ b/frontend/context/ModalsProvider/ModalsProvider.tsx @@ -24,7 +24,7 @@ export const ModalsContext = createContext({ address: undefined, amount: undefined, chainId: undefined, - isERC20: false, + isErc20: false, }, setQrModalData: () => {}, }); @@ -35,7 +35,7 @@ export const ModalsProvider = ({ children }: PropsWithChildren) => { address: undefined, amount: undefined, chainId: undefined, - isERC20: false, + isErc20: false, }); return ( >; + setActiveTab: Dispatch>; }; export const TabsContext = createContext({ @@ -18,9 +18,9 @@ export const TabsContext = createContext({ }); export const TabsProvider = ({ children }: PropsWithChildren) => { - const [activeTab, setActiveTab] = useState(Tab.YOUR_AGENTS); + const [activeTab, setActiveTab] = useState(Tab.YOUR_AGENTS); return ( - + {children} ); diff --git a/frontend/hooks/useEthers.tsx b/frontend/hooks/useEthers.tsx index d8970f3ce..0e60e80ee 100644 --- a/frontend/hooks/useEthers.tsx +++ b/frontend/hooks/useEthers.tsx @@ -1,5 +1,5 @@ import { Address } from '@/types'; -import { BigNumber, ethers, providers, utils } from 'ethers'; +import { ethers, providers, utils } from 'ethers'; export const useEthers = () => { /** @@ -8,7 +8,7 @@ export const useEthers = () => { * @param rpc string * @returns Promise */ - const getETHBalance = async ( + const getEthBalance = async ( address: Address, rpc: string, ): Promise => { @@ -17,9 +17,10 @@ export const useEthers = () => { name: 'Gnosis', chainId: 100, // we currently only support Gnosis Trader agent }); - return provider - .getBalance(address) - .then((balance: BigNumber) => Number(utils.formatEther(balance))); + return provider.getBalance(address).then((balance) => { + const formattedBalance = utils.formatEther(balance); + return Number(formattedBalance); + }); } catch (e) { return Promise.reject('Failed to get ETH balance'); } @@ -32,7 +33,7 @@ export const useEthers = () => { * @param contractAddress Address * @returns Promise */ - const getERC20Balance = async ( + const getErc20Balance = async ( address: Address, rpc: string, contractAddress?: Address, @@ -87,5 +88,9 @@ export const useEthers = () => { } }; - return { getETHBalance, checkRPC, getERC20Balance }; + return { + getEthBalance, + checkRPC, + getErc20Balance, + }; }; diff --git a/frontend/hooks/useModals.tsx b/frontend/hooks/useModals.tsx index ff289df5b..cb5e94620 100644 --- a/frontend/hooks/useModals.tsx +++ b/frontend/hooks/useModals.tsx @@ -13,7 +13,7 @@ export const useModals = () => { address: undefined, amount: undefined, chainId: undefined, - isERC20: false, + isErc20: false, }); const qrModalOpen = (data: Omit, 'open'>) => diff --git a/frontend/hooks/useMulticall.tsx b/frontend/hooks/useMulticall.tsx index a1b0c58fa..707830387 100644 --- a/frontend/hooks/useMulticall.tsx +++ b/frontend/hooks/useMulticall.tsx @@ -11,7 +11,7 @@ export const useMulticall = () => { * @param rpc * @returns Promise<{ [address: string]: number }> */ - const getETHBalances = async ( + const getEthBalances = async ( addresses: Address[], rpc: string, ): Promise<{ [address: Address]: number }> => { @@ -45,7 +45,7 @@ export const useMulticall = () => { * @param contractAddress * @returns Promise<{ [address: string]: number }> */ - const getERC20Balances = async ( + const getErc20Balances = async ( addresses: Address[], rpc: string, contractAddress: Address, @@ -75,5 +75,5 @@ export const useMulticall = () => { ); }; - return { getETHBalances, getERC20Balances }; + return { getEthBalances, getErc20Balances }; }; diff --git a/frontend/hooks/useTabs.tsx b/frontend/hooks/useTabs.tsx index 2171c0ad4..00179ebaa 100644 --- a/frontend/hooks/useTabs.tsx +++ b/frontend/hooks/useTabs.tsx @@ -3,8 +3,10 @@ import { Tab } from '@/enums'; import { useContext } from 'react'; export const useTabs = () => { - const { activeTab, setActiveTab } = useContext(TabsContext); + const { activeTab, setActiveTab: setTab } = useContext(TabsContext); const resetTabs = () => setActiveTab(Tab.YOUR_AGENTS); + const setActiveTab = (tab: string) => setTab(tab as Tab); // casting needed to meet context useState requirements + return { activeTab, setActiveTab, resetTabs }; }; diff --git a/frontend/pages/index.tsx b/frontend/pages/index.tsx index c8767fd5c..681077e59 100644 --- a/frontend/pages/index.tsx +++ b/frontend/pages/index.tsx @@ -4,27 +4,23 @@ import { YourAgents } from '@/components/YourAgents/YourAgents'; import { Tab } from '@/enums'; import { useTabs } from '@/hooks/useTabs'; import { Tabs, type TabsProps } from 'antd'; -import { useMemo } from 'react'; + +const tabs: TabsProps['items'] = [ + { + key: Tab.YOUR_AGENTS, + label: 'Your Agents', + children: , + }, + { + key: Tab.MARKETPLACE, + label: 'Marketplace', + children: , + }, +]; export default function Home() { const { activeTab, setActiveTab } = useTabs(); - const tabs: TabsProps['items'] = useMemo( - () => [ - { - key: Tab.YOUR_AGENTS, - label: 'Your Agents', - children: , - }, - { - key: Tab.MARKETPLACE, - label: 'Marketplace', - children: , - }, - ], - [], - ); - return (