diff --git a/apps/autonolas-registry/common-util/Details/DetailsSubInfo/RewardsSection.tsx b/apps/autonolas-registry/common-util/Details/DetailsSubInfo/RewardsSection.tsx index 151750cd..2a32616c 100644 --- a/apps/autonolas-registry/common-util/Details/DetailsSubInfo/RewardsSection.tsx +++ b/apps/autonolas-registry/common-util/Details/DetailsSubInfo/RewardsSection.tsx @@ -6,7 +6,7 @@ import { Address } from 'viem'; import { getPendingIncentives, useClaimableIncentives } from 'libs/common-contract-functions/src'; import { UNICODE_SYMBOLS } from 'libs/util-constants/src/lib/symbols'; import { TOKENOMICS } from 'libs/util-contracts/src'; -import { notifyError, notifySuccess } from 'libs/util-functions/src'; +import { areAddressesEqual, notifyError, notifySuccess } from 'libs/util-functions/src'; import { getEthersProviderForEthereum, getTokenomicsEthersContract } from 'common-util/Contracts'; import { claimOwnerIncentivesRequest } from 'common-util/functions/requests'; @@ -78,9 +78,9 @@ export const RewardsSection: FC = ({ ownerAddress, id, type const { reward: claimableReward, - rewardEth: claimableRewardEth, + rewardWei: claimableRewardWei, topUp: claimableTopUp, - topUpEth: claimableTopUpEth, + topUpWei: claimableTopUpWei, isFetching: isClaimableIncentivesLoading, refetch, } = useClaimableIncentives( @@ -142,11 +142,11 @@ export const RewardsSection: FC = ({ ownerAddress, id, type ]); const canClaim = useMemo(() => { - if (account !== ownerAddress) return false; - if (claimableRewardEth === undefined || claimableTopUpEth === undefined) return false; + if (!areAddressesEqual(account.toString(), ownerAddress)) return false; + if (claimableRewardWei === undefined || claimableTopUpWei === undefined) return false; - return claimableRewardEth > 0 || claimableTopUpEth > 0; - }, [account, ownerAddress, claimableRewardEth, claimableTopUpEth]); + return claimableRewardWei > 0 || claimableTopUpWei > 0; + }, [account, ownerAddress, claimableRewardWei, claimableTopUpWei]); const handleClaim = useCallback(async () => { if (!account) return; @@ -181,7 +181,7 @@ export const RewardsSection: FC = ({ ownerAddress, id, type pagination={false} style={{ maxWidth: '550px' }} /> - + Make donation {UNICODE_SYMBOLS.EXTERNAL_LINK} diff --git a/apps/autonolas-registry/common-util/Details/index.tsx b/apps/autonolas-registry/common-util/Details/index.tsx index a05b817d..d1bbbe7d 100644 --- a/apps/autonolas-registry/common-util/Details/index.tsx +++ b/apps/autonolas-registry/common-util/Details/index.tsx @@ -2,6 +2,7 @@ import { Button, Col, Row, Typography } from 'antd'; import capitalize from 'lodash/capitalize'; import get from 'lodash/get'; import { FC, useCallback, useState } from 'react'; +import { Address } from 'viem'; import { GenericObject, Loader, NA } from '@autonolas/frontend-library'; @@ -14,14 +15,13 @@ import { DetailsSubInfo } from './DetailsSubInfo'; import { NftImage } from './NFTImage'; import { DetailsTitle, Header } from './styles'; import { useDetails } from './useDetails'; -import { Address } from 'viem'; const { Text } = Typography; type DetailsProps = { id: string; type: NavTypesValues; - getDetails: (id: string) => Promise<{ unitHash: Address, dependencies: string[]}>; + getDetails: (id: string) => Promise<{ unitHash: Address; dependencies: string[] }>; getTokenUri: (id: string) => Promise; getOwner: (id: string) => Promise; handleUpdate?: () => void; diff --git a/apps/autonolas-registry/common-util/Details/useDetails.ts b/apps/autonolas-registry/common-util/Details/useDetails.ts index e1855040..a81d81bc 100644 --- a/apps/autonolas-registry/common-util/Details/useDetails.ts +++ b/apps/autonolas-registry/common-util/Details/useDetails.ts @@ -1,7 +1,8 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import { Address } from 'viem'; -import { NA, areAddressesEqual, notifyError } from '@autonolas/frontend-library'; +import { NA } from 'libs/util-constants/src/lib/symbols'; +import { areAddressesEqual, notifyError } from 'libs/util-functions/src'; import { NavTypesValues } from 'util/constants'; @@ -38,7 +39,6 @@ export const useDetails = ({ try { const tempDetails = await getDetails(id); - console.log('tempDetails', tempDetails); setInfo(tempDetails); const ownerAccount = await getOwner(id); @@ -73,13 +73,13 @@ export const useDetails = ({ const isOwner = useMemo(() => { if (isSvm) { if (walletPublicKey && ownerAddress) { - return areAddressesEqual(`${walletPublicKey}`, ownerAddress); + return areAddressesEqual(walletPublicKey.toString(), ownerAddress); } return false; } if (account && ownerAddress) { - return areAddressesEqual(`${account}`, ownerAddress); + return areAddressesEqual(account.toString(), ownerAddress); } return false; diff --git a/apps/autonolas-registry/common-util/Login/config.tsx b/apps/autonolas-registry/common-util/Login/config.tsx index 90876702..3990910e 100644 --- a/apps/autonolas-registry/common-util/Login/config.tsx +++ b/apps/autonolas-registry/common-util/Login/config.tsx @@ -83,7 +83,7 @@ export const EVM_SUPPORTED_CHAINS = SUPPORTED_CHAINS.map((chain) => { }; }); -type SolanaChain = { +export type SolanaChain = { id: number | null; networkDisplayName: string; networkName: string; diff --git a/apps/autonolas-registry/common-util/functions/index.ts b/apps/autonolas-registry/common-util/functions/index.ts index 1ad15d3c..7855b4ab 100644 --- a/apps/autonolas-registry/common-util/functions/index.ts +++ b/apps/autonolas-registry/common-util/functions/index.ts @@ -1,30 +1,30 @@ -// TODO: provide all the rest types -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-nocheck import { PublicKey } from '@solana/web3.js'; -import { Contract, ethers } from 'ethers'; +import { RuleObject } from 'antd/es/form'; +import { StoreValue } from 'antd/es/form/interface'; +import { Contract, FallbackProvider, JsonRpcProvider, ethers } from 'ethers'; import { isString } from 'lodash'; import { Address } from 'viem'; - - -import { getChainIdOrDefaultToMainnet as getChainIdOrDefaultToMainnetFn, getIsValidChainId as getIsValidChainIdFn, isValidAddress, notifyError, notifyWarning } from '@autonolas/frontend-library'; - - +import { + getChainIdOrDefaultToMainnet as getChainIdOrDefaultToMainnetFn, + getIsValidChainId as getIsValidChainIdFn, + isValidAddress, + notifyError, + notifyWarning, +} from '@autonolas/frontend-library'; import { sendTransaction as sendTransactionFn } from 'libs/util-functions/src'; - - +import { RpcUrl } from 'libs/util-functions/src/lib/sendTransaction/types'; import { VM_TYPE } from '../../util/constants'; import { RPC_URLS } from '../Contracts'; import { SUPPORTED_CHAINS } from '../Login'; -import { EVM_SUPPORTED_CHAINS, SVM_SUPPORTED_CHAINS } from '../Login/config'; +import { EVM_SUPPORTED_CHAINS, SVM_SUPPORTED_CHAINS, SolanaChain } from '../Login/config'; +// TODO: provide types for MODAL_PROVIDER +export const getModalProvider = () => (window as any)?.MODAL_PROVIDER; -export const getModalProvider = () => window?.MODAL_PROVIDER; - -export const getWindowEthereum = () => window?.ethereum; +export const getWindowEthereum = () => (window as any)?.ethereum; export const getChainId = (chainId = null) => { if (chainId) return chainId; @@ -43,7 +43,7 @@ export const getChainId = (chainId = null) => { export const getProvider = () => { const defaultChainId = getChainId(); - const rpcUrl = RPC_URLS[defaultChainId]; + const rpcUrl = typeof defaultChainId === 'number' ? (RPC_URLS as RpcUrl)[defaultChainId] : null; if (!rpcUrl) { throw new Error(`No RPC URL found for chainId: ${defaultChainId}`); @@ -105,7 +105,10 @@ export const getChainIdOrDefaultToMainnet = (chainId: string | number) => { * @param {object} builderIns - The object to check. * @returns {boolean} - True if the object is a MethodsBuilder object, false otherwise. */ -const isMethodsBuilderInstance = (builderIns, registryAddress) => { +const isMethodsBuilderInstance = ( + builderIns: object & { _args?: any }, // TODO: provide better type + registryAddress: Address, +) => { if (typeof builderIns !== 'object' || builderIns === null) { throw new Error('sendTransaction: Input must be an object.'); } @@ -139,10 +142,10 @@ const isMethodsBuilderInstance = (builderIns, registryAddress) => { export const sendTransaction = ( method: Contract, account: Address, - extra?: { vmType: string; registryAddress: string }, + extra?: { vmType: string; registryAddress: Address }, ) => { const { vmType, registryAddress } = extra || {}; - if (vmType === VM_TYPE.SVM) { + if (vmType === VM_TYPE.SVM && registryAddress) { // Check if something resembling an SVM method is being passed if (!isMethodsBuilderInstance(method, registryAddress)) { notifyError('Invalid method object'); @@ -153,12 +156,12 @@ export const sendTransaction = ( return sendTransactionFn(method, account, { supportedChains: SUPPORTED_CHAINS, - rpcUrls: RPC_URLS, + rpcUrls: RPC_URLS as RpcUrl, }); }; export const addressValidator = () => ({ - validator(_, value) { + validator(_: RuleObject, value: StoreValue) { return isValidAddress(value) ? Promise.resolve() : Promise.reject(new Error('Please enter valid addresses.')); @@ -166,7 +169,10 @@ export const addressValidator = () => ({ }); // check if the provider is gnosis safe -export const checkIfGnosisSafe = async (account, provider) => { +export const checkIfGnosisSafe = async ( + account: Address, + provider: JsonRpcProvider | FallbackProvider, +) => { try { if (provider && provider.getCode) { // TODO: getCode has some issues and throws error in console @@ -177,6 +183,7 @@ export const checkIfGnosisSafe = async (account, provider) => { console.error(error); return false; } + return false; }; /** @@ -185,12 +192,12 @@ export const checkIfGnosisSafe = async (account, provider) => { * but now all networks have service manager token. Hence, this function * defaults to true BUT can be overridden for specific networks in the future. */ -export const doesNetworkHaveValidServiceManagerTokenFn = (chainId) => !!chainId; +export const doesNetworkHaveValidServiceManagerTokenFn = (chainId: number) => !!chainId; -const doesPathIncludesComponents = (path) => !!path?.includes('components'); -const doesPathIncludesAgents = (path) => !!path?.includes('agents'); -export const doesPathIncludesServices = (path) => !!path?.includes('services'); -export const doesPathIncludesComponentsOrAgents = (path) => { +const doesPathIncludesComponents = (path: string) => !!path?.includes('components'); +const doesPathIncludesAgents = (path: string) => !!path?.includes('agents'); +export const doesPathIncludesServices = (path: string) => !!path?.includes('services'); +export const doesPathIncludesComponentsOrAgents = (path: string) => { if (!path) return false; return doesPathIncludesComponents(path) || doesPathIncludesAgents(path); }; @@ -200,19 +207,20 @@ export const notifyWrongNetwork = () => { }; // functions for solana -export const isPageWithSolana = (path) => { +export const isPageWithSolana = (path: string) => { if (!path) return false; if (!isString(path)) return false; - const checkPath = (chain) => path.toLowerCase().includes(chain.networkName.toLowerCase()); + const checkPath = (chain: SolanaChain) => + path.toLowerCase().includes(chain.networkName.toLowerCase()); return SVM_SUPPORTED_CHAINS.some(checkPath); }; -export const isValidSolanaPublicKey = (publicKey) => { +export const isValidSolanaPublicKey = (publicKey: PublicKey) => { try { const isValid = PublicKey.isOnCurve(publicKey); return isValid; } catch (e) { return false; } -}; \ No newline at end of file +}; diff --git a/apps/autonolas-registry/common-util/functions/requests.ts b/apps/autonolas-registry/common-util/functions/requests.ts index e54b6bab..bd60a3f0 100644 --- a/apps/autonolas-registry/common-util/functions/requests.ts +++ b/apps/autonolas-registry/common-util/functions/requests.ts @@ -1,8 +1,6 @@ import { Address, TransactionReceipt } from 'viem'; -import { notifyError, sendTransaction } from '@autonolas/frontend-library'; - -import { getEstimatedGasLimit } from 'libs/util-functions/src'; +import { getEstimatedGasLimit, notifyError, sendTransaction } from 'libs/util-functions/src'; import { SUPPORTED_CHAINS } from 'common-util/Login'; @@ -72,7 +70,7 @@ export const claimOwnerIncentivesRequest = async ({ supportedChains: SUPPORTED_CHAINS, rpcUrls: RPC_URLS as Record, }); - return (response as TransactionReceipt)?.transactionHash; + return response?.transactionHash; } catch (error) { window.console.log('Error occurred on claiming owner incentives'); throw error; diff --git a/apps/autonolas-registry/components/ListServices/index.jsx b/apps/autonolas-registry/components/ListServices/index.jsx index 2322b875..07c09f42 100644 --- a/apps/autonolas-registry/components/ListServices/index.jsx +++ b/apps/autonolas-registry/components/ListServices/index.jsx @@ -1,25 +1,18 @@ -import { useState, useEffect } from 'react'; import { Tabs } from 'antd'; import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; + import { notifyError } from '@autonolas/frontend-library'; -import { NAV_TYPES } from '../../util/constants'; -import { - ListTable, - useExtraTabContent, - isMyTab, -} from '../../common-util/List/ListTable'; import { getMyListOnPagination } from '../../common-util/ContractUtils/myList'; +import { ListTable, isMyTab, useExtraTabContent } from '../../common-util/List/ListTable'; import { useHelpers } from '../../common-util/hooks'; -import { - useAllServices, - useMyServices, - useSearchServices, -} from './hooks/useServicesList'; +import { NAV_TYPES } from '../../util/constants'; +import { useAllServices, useMyServices, useSearchServices } from './hooks/useServicesList'; import { useServiceInfo } from './hooks/useSvmService'; import { - getServices, getFilteredServices, + getServices, getTotalForAllServices, getTotalForMyServices, } from './utils'; @@ -29,9 +22,7 @@ const MY_SERVICES = 'my-services'; const ListServices = () => { const router = useRouter(); - const [currentTab, setCurrentTab] = useState( - isMyTab(router) ? MY_SERVICES : ALL_SERVICES, - ); + const [currentTab, setCurrentTab] = useState(isMyTab(router) ? MY_SERVICES : ALL_SERVICES); const { account, links, isSvm, chainId, isMainnet } = useHelpers(); @@ -58,12 +49,8 @@ const ListServices = () => { const [currentPage, setCurrentPage] = useState(1); const [list, setList] = useState([]); - const { - getTotalForAllSvmServices, - getTotalForMySvmServices, - getSvmServices, - getMySvmServices, - } = useServiceInfo(); + const { getTotalForAllSvmServices, getTotalForMySvmServices, getSvmServices, getMySvmServices } = + useServiceInfo(); // fetch total (All services & My services) useEffect(() => { @@ -72,9 +59,7 @@ const ListServices = () => { let totalTemp = null; if (currentTab === ALL_SERVICES) { - totalTemp = isSvm - ? await getTotalForAllSvmServices() - : await getTotalForAllServices(); + totalTemp = isSvm ? await getTotalForAllSvmServices() : await getTotalForAllServices(); } else if (currentTab === MY_SERVICES && account) { totalTemp = isSvm ? await getTotalForMySvmServices(account) @@ -207,15 +192,7 @@ const ListServices = () => { setIsLoading(false); } })(); - }, [ - account, - searchValue, - currentTab, - currentPage, - getServicesBySearch, - isMainnet, - chainId, - ]); + }, [account, searchValue, currentTab, currentPage, getServicesBySearch, isMainnet, chainId]); const tableCommonProps = { type: NAV_TYPES.SERVICE, @@ -225,16 +202,13 @@ const ListServices = () => { setCurrentPage, onViewClick, searchValue, - onUpdateClick: (serviceId) => - router.push(`${links.UPDATE_SERVICE}/${serviceId}`), + onUpdateClick: (serviceId) => router.push(`${links.UPDATE_SERVICE}/${serviceId}`), }; const getMyServiceList = () => { if (isMainnet) return list; - return searchValue - ? list - : getMyListOnPagination({ total, nextPage: currentPage, list }); + return searchValue ? list : getMyListOnPagination({ total, nextPage: currentPage, list }); }; return ( @@ -265,11 +239,7 @@ const ListServices = () => { label: 'All', disabled: isLoading, children: ( - + ), }, { diff --git a/apps/autonolas-registry/tests/components/ListAgents/details.test.jsx b/apps/autonolas-registry/tests/components/ListAgents/details.test.jsx index 221085c3..9c3bed0d 100644 --- a/apps/autonolas-registry/tests/components/ListAgents/details.test.jsx +++ b/apps/autonolas-registry/tests/components/ListAgents/details.test.jsx @@ -37,9 +37,9 @@ jest.mock('wagmi', () => ({ jest.mock('libs/common-contract-functions/src', () => ({ useClaimableIncentives: jest.fn().mockReturnValue({ reward: '0.85', - rewardEth: 850000000000000000, + rewardWei: 850000000000000000, topUp: '222,777.30', - topUpEth: 222777300000000000000000000, + topUpWei: 222777300000000000000000000, }), getPendingIncentives: jest.fn().mockResolvedValue({ pendingReward: '0.95555', diff --git a/apps/autonolas-registry/tests/components/ListComponents/details.test.jsx b/apps/autonolas-registry/tests/components/ListComponents/details.test.jsx index b237769d..3c719411 100644 --- a/apps/autonolas-registry/tests/components/ListComponents/details.test.jsx +++ b/apps/autonolas-registry/tests/components/ListComponents/details.test.jsx @@ -38,9 +38,9 @@ jest.mock('wagmi', () => ({ jest.mock('libs/common-contract-functions/src', () => ({ useClaimableIncentives: jest.fn().mockReturnValue({ reward: '0.25', - rewardEth: 250000000000000000, + rewardWei: 250000000000000000, topUp: '111,555.70', - topUpEth: 111555700000000000000000000, + topUpWei: 111555700000000000000000000, }), getPendingIncentives: jest.fn().mockResolvedValue({ pendingReward: '0.5', diff --git a/libs/common-contract-functions/src/lib/useRewards.ts b/libs/common-contract-functions/src/lib/useRewards.ts index ddc524be..6a0c7989 100644 --- a/libs/common-contract-functions/src/lib/useRewards.ts +++ b/libs/common-contract-functions/src/lib/useRewards.ts @@ -29,9 +29,9 @@ export const useClaimableIncentives = ( const [reward, topup] = data as [bigint, bigint]; return { reward: rewardsFormatter(reward, 4), - rewardEth: reward, + rewardWei: reward, topUp: rewardsFormatter(topup, 2), - topUpEth: topup, + topUpWei: topup, }; }, refetchOnWindowFocus: false, diff --git a/libs/util-functions/src/lib/ethers.ts b/libs/util-functions/src/lib/ethers.ts index 2869b63f..1d21da0f 100644 --- a/libs/util-functions/src/lib/ethers.ts +++ b/libs/util-functions/src/lib/ethers.ts @@ -1,4 +1,5 @@ import { ethers } from 'ethers'; +import toLower from 'lodash/toLower'; import { Address } from 'viem'; export const getBytes32FromAddress = (address: Address | string) => { @@ -6,3 +7,6 @@ export const getBytes32FromAddress = (address: Address | string) => { }; export const isValidAddress = (address: string) => ethers.isAddress(address); + +export const areAddressesEqual = (a1: string | Address, a2: string | Address) => + toLower(a1) === toLower(a2);