Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nominate contract page #45

Merged
merged 49 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
353d706
refactor: Update launch store to include my staking contracts
mohandast52 Jun 18, 2024
2fa474b
refactor: Update import paths for components and hooks in autonolas-r…
mohandast52 Jun 18, 2024
09b03a2
refactor: Remove unnecessary CSS padding in GlobalStyles.tsx
mohandast52 Jun 18, 2024
b86c423
feat: Add dummy data for my staking contracts in launch store
mohandast52 Jun 18, 2024
88ff227
refactor: Update MyStakingContracts component to include loading stat…
mohandast52 Jun 18, 2024
6c111c3
feat: Add MyStakingContracts/List component for displaying staking co…
mohandast52 Jun 18, 2024
ddc3949
refactor: Update URL constant for my-staking-contracts and add popove…
mohandast52 Jun 18, 2024
d6a81c4
feat: Add useGetMyStakingContracts hook for fetching staking contract…
mohandast52 Jun 19, 2024
91de9fc
refactor: Update clip-path attribute to clipPath in LogoSvg component
mohandast52 Jun 19, 2024
716fedb
chore: add hooks to fetch my staking contracts
mohandast52 Jun 19, 2024
c55ca7c
refactor: Add ethers utility function for converting address to bytes32
mohandast52 Jun 19, 2024
4341e8f
refactor: Update MyStakingContracts List component to display a succe…
mohandast52 Jun 19, 2024
cb815f5
refactor: Update MyStakingContracts component to use GOVERN_URL inste…
mohandast52 Jun 19, 2024
095e3ae
refactor: Add nominate contract functionality to MyStakingContracts L…
mohandast52 Jun 19, 2024
0a45d9c
refactor: Improve useGetMyStakingContractsMetadata hook to handle err…
mohandast52 Jun 19, 2024
ea60f05
chore: address Tanya's review comments
mohandast52 Jun 20, 2024
1f8672e
refactor: Hide menu on certain pages in Layout component
mohandast52 Jun 20, 2024
bfc737f
refactor: Update useGetMyStakingContractsMetadata hook to handle erro…
mohandast52 Jun 20, 2024
876e720
refactor: Filter out null values in useGetMyStakingContracts and fix …
mohandast52 Jun 20, 2024
79077db
refactor: Update useGetMyStakingContracts to use ChainId instead of S…
mohandast52 Jun 20, 2024
2b0accc
refactor: Update useGetMyStakingContracts to use ChainId instead of S…
mohandast52 Jun 20, 2024
b174b5e
chore: renames
mohandast52 Jun 20, 2024
b75b923
Fix defining is nominated
Jun 20, 2024
1cd801e
Add nominate tx
Jun 20, 2024
d131175
conflict fixes
mohandast52 Jun 20, 2024
acd076b
chore: move useHandleRoute hook to _app.jsx
mohandast52 Jun 21, 2024
13314e1
refactor: Remove unused import in web3.ts
mohandast52 Jun 21, 2024
4c48a0a
refactor: Update import path for NominatedContract component
mohandast52 Jun 21, 2024
faf7963
chore: Update NominatedContract component
mohandast52 Jun 21, 2024
83aec77
refactor: Update NominatedContract component import path and move pre…
mohandast52 Jun 21, 2024
d1fbc8e
refactor: Update import path for useHandleRoute hook and networkHelpe…
mohandast52 Jun 21, 2024
0d77622
refactor: Update import path for useHandleRoute hook in _app.tsx
mohandast52 Jun 21, 2024
d5a8e98
refractor: ErrorAlert component updated for nominate
mohandast52 Jun 21, 2024
cc7d64f
refactor: Update NominateContract component with additional checks an…
mohandast52 Jun 21, 2024
68879c3
chore: switch network
mohandast52 Jun 21, 2024
46dbba9
chore: add more error states
mohandast52 Jun 24, 2024
2a1c69d
refactor: Update networkHelpers functions and useHandleRoute hook imp…
mohandast52 Jun 24, 2024
47c89dc
refactor: Update NominateContract component with LoginV2 integration …
mohandast52 Jun 24, 2024
3e55ce8
chore: add more checks and improve
mohandast52 Jun 24, 2024
4c4760e
Finish nominate flow
Jun 24, 2024
fc0cd42
Move page, fix grammatical error
Jun 24, 2024
792123d
Add some fixes
Jun 24, 2024
f59cb11
Add some fixes
Jun 24, 2024
c2253b0
chore: add logs
mohandast52 Jun 24, 2024
89111c3
refactor: Update useGetMyStakingContracts.ts to use networkId instead…
mohandast52 Jun 25, 2024
3a18e0e
refactor: Update useGetMyStakingContracts.ts to use networkId instead…
mohandast52 Jun 25, 2024
4ee2013
refactor: Remove unused code and fix networkId usage in useGetMyStaki…
mohandast52 Jun 25, 2024
083e536
Merge pull request #46 from valory-xyz/mohan/debug-switch-error
mohandast52 Jun 25, 2024
640913e
Review fixes
Jun 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/autonolas-registry/common-util/Login/LoginV2.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const LoginV2 = ({
const { disconnect } = useDisconnect();
const { chainId, isConnectedToWrongNetwork } = useHelpers();
const { chain: walletConnectedChain } = useAccount();
const { switchChainAsync, isLoading } = useSwitchChain();
const { switchChainAsync, isPending } = useSwitchChain();

const screens = useBreakpoint();

Expand Down Expand Up @@ -142,7 +142,7 @@ export const LoginV2 = ({
<>
{!hideWrongNetwork && (
<YellowButton
loading={isLoading}
loading={isPending}
type="default"
onClick={onSwitchNetwork}
icon={<SwapOutlined />}>
Expand Down
34 changes: 34 additions & 0 deletions apps/launch/common-util/ErrorAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Alert } from 'antd';
import { mainnet } from 'viem/chains';

import { EXPLORER_URLS, UNICODE_SYMBOLS } from 'libs/util-constants/src';

import { ErrorType } from 'types/index';

export const ErrorAlert = ({
error,
networkId,
}: {
error: NonNullable<ErrorType>;
networkId?: number | null;
}) => (
<Alert
className="mb-24"
type="error"
showIcon
message={
<>
{error.message}
{error.transactionHash && (
<>
<br />
<a
href={`${[EXPLORER_URLS[networkId || mainnet.id]]}/tx/${error.transactionHash}`}
target="_blank"
>{`Explore transaction hash ${UNICODE_SYMBOLS.EXTERNAL_LINK}`}</a>
</>
)}
</>
}
/>
);
64 changes: 49 additions & 15 deletions apps/launch/common-util/functions/frontend-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,37 +36,71 @@ export const notifyConnectWallet = () => {
notifyWarning('Please connect your wallet');
};

const METAMASK_ERRORS: Record<number, string> = {
4001: 'Transaction rejected by user. The contract hasn’t been created.',
export enum Feature {
CREATE = 'create',
NOMINATE = 'nominate',
}

const METAMASK_ERRORS = {
create: [
{
code: 4001,
name: '',
message: 'Transaction rejected by user. The contract hasn’t been created.',
},
],
nominate: [
{
code: 4001,
name: 'Transaction rejected by user',
message: 'Transaction rejected by user. The contract hasn’t been nominated',
},
],
};

const EVM_ERRORS = [
{
errorText: 'Transaction has been reverted by the EVM',
displayText: 'Transaction failed. The contract hasn’t been created.',
},
];
const EVM_ERRORS = {
create: [
{
errorText: 'Transaction has been reverted by the EVM',
name: '',
displayText: 'Transaction failed. The contract hasn’t been created.',
},
],
nominate: [
{
errorText: 'Transaction has been reverted by the EVM',
name: 'Transaction failed',
displayText: 'Transaction failed. The contract hasn’t been nominated',
},
],
};

export const getErrorInfo = (error: Error | { code: number; message: string }) => {
export const getErrorInfo = (type: Feature, error: Error | { code: number; message: string }) => {
const defaultMessage = 'Some error occurred. Please try again';

let name;
let message = defaultMessage;
let transactionHash;

if ('code' in error && METAMASK_ERRORS[error.code]) {
message = METAMASK_ERRORS[error.code];
if ('code' in error) {
const metamaskError = METAMASK_ERRORS[type].find((item) => item.code === error.code);
if (metamaskError) {
name = metamaskError.name;
message = metamaskError.message;
}
}

if ('message' in error) {
const foundError = EVM_ERRORS.find((item) => error.message.indexOf(item.errorText) !== -1);
if (foundError) {
message = foundError.displayText;
const evmError = EVM_ERRORS[type].find((item) => error.message === item.errorText);
if (evmError) {
name = evmError.name;
message = evmError.displayText;
}
}

if ('receipt' in error) {
transactionHash = (error.receipt as TransactionReceipt).transactionHash as Address;
}

return { message, transactionHash };
return { name, message, transactionHash };
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@ export const getChainIdFromPath = (networkName: string | undefined) => {
const network = ALL_SUPPORTED_CHAINS.find((e) => toLower(e.networkName) === toLower(networkName));
return network?.id;
};

export const getDisplayNameFromPath = (networkName: string | undefined) => {
if (!networkName) return null;

const network = ALL_SUPPORTED_CHAINS.find((e) => toLower(e.networkName) === toLower(networkName));
return network?.networkDisplayName;
};
17 changes: 16 additions & 1 deletion apps/launch/common-util/functions/web3.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { BaseContractMethod, Contract } from 'ethers';
import { Address } from 'viem';
import Web3 from 'web3';
import { AbiItem } from 'web3-utils';
Expand Down Expand Up @@ -48,6 +47,7 @@ export const getStakingFactoryContract = () => {
return contract;
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const sendTransaction = async (methodFn: any, account: Address) => {
const estimatedGas = await getEstimatedGasLimit(methodFn, account);
const fn = methodFn.send({ from: account, estimatedGas });
Expand All @@ -63,6 +63,7 @@ type CreateContractParams = {
initPayload: string;
account: Address;
};

export const createStakingContract = async ({
implementation,
initPayload,
Expand All @@ -74,3 +75,17 @@ export const createStakingContract = async ({

return result;
};

type AddNomineeParams = {
address: Address;
chainId: number;
account: Address;
};

export const addNominee = async ({ address, chainId, account }: AddNomineeParams) => {
const contract = getVoteWeightingContract();
const createFn = contract.methods.addNomineeEVM(address, chainId);
const result = await sendTransaction(createFn, account);

return result;
};
5 changes: 0 additions & 5 deletions apps/launch/components/Layout/SwitchNetworkSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import {
PAGES_TO_LOAD_WITH_CHAIN_ID,
} from 'common-util/config/supportedChains';

import { useHandleRoute } from './useHandleRoute';

const networkSelectOptions = ALL_SUPPORTED_CHAINS.map((e) => ({
label: e.networkDisplayName,
value: e.networkName,
Expand All @@ -25,9 +23,6 @@ export const SwitchNetworkSelect: FC = () => {

const chainName = (router?.query?.network || 'ethereum') as string;

// handle the routing
useHandleRoute();

return (
<div style={{ marginRight: isMobile ? 8 : 0 }}>
<Select
Expand Down
55 changes: 53 additions & 2 deletions apps/launch/components/Login/LoginV2.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { SwapOutlined } from '@ant-design/icons';
import { GetAccountReturnType, watchAccount } from '@wagmi/core';
import { useCallback, useEffect } from 'react';
import { isNil, isNumber } from 'lodash';
import { useCallback, useEffect, useMemo } from 'react';
import styled from 'styled-components';
import { useAccountEffect, useConfig, useDisconnect } from 'wagmi';
import { useAccount, useAccountEffect, useConfig, useDisconnect, useSwitchChain } from 'wagmi';

import { useScreen } from 'libs/ui-theme/src';
import { isAddressProhibited } from 'libs/util-prohibited-data/src/index';

import { useAppSelector } from 'store/index';

import { YellowButton } from './YellowButton';

const LoginContainer = styled.div`
display: flex;
align-items: center;
Expand All @@ -15,6 +22,10 @@ const LoginContainer = styled.div`
export const LoginV2 = () => {
const { disconnect } = useDisconnect();
const config = useConfig();
const { isMobile } = useScreen();
const { chain: walletConnectedChain } = useAccount();
const { networkId } = useAppSelector((state) => state.network);
const { switchChainAsync, isPending } = useSwitchChain();

const handleConnect = useCallback(
({ address }: Pick<GetAccountReturnType, 'address' | 'chainId'>) => {
Expand Down Expand Up @@ -43,8 +54,48 @@ export const LoginV2 = () => {
return () => unwatch();
}, [config, clearOnDisconnect, handleConnect]);

/**
* @returns {boolean} - true if the wallet is connected to wrong network
* (ie. chain ID from wallet is different from the chain ID selected in the dropdown)
*/
const isConnectedToWrongNetwork = useMemo(() => {
if (!isNumber(walletConnectedChain?.id) || !isNumber(networkId)) return false;

return walletConnectedChain?.id !== networkId;
}, [walletConnectedChain, networkId]);

const onSwitchNetwork = useCallback(async () => {
if (!networkId) return;

try {
await switchChainAsync({ chainId: networkId });
} catch (error) {
console.error(error);
}
}, [networkId, switchChainAsync]);

useEffect(() => {
if (isConnectedToWrongNetwork) {
onSwitchNetwork();
}
}, [isConnectedToWrongNetwork, onSwitchNetwork]);

const hideWrongNetwork =
isNil(walletConnectedChain?.id) || walletConnectedChain?.id === networkId;

return (
<LoginContainer>
{!hideWrongNetwork && (
<YellowButton
loading={isPending}
type="default"
onClick={onSwitchNetwork}
icon={<SwapOutlined />}
>
{!isMobile && 'Switch network'}
</YellowButton>
)}
&nbsp;&nbsp;
<w3m-button balance="hide" />
</LoginContainer>
);
Expand Down
22 changes: 22 additions & 0 deletions apps/launch/components/Login/YellowButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Button, ButtonProps, ConfigProvider } from 'antd';
import { FC, ReactNode } from 'react';

import { COLOR } from 'libs/ui-theme/src';

// TODO: move to ui library
type YellowButtonProps = { children: ReactNode } & ButtonProps;

export const YellowButton: FC<YellowButtonProps> = ({ children, ...props }) => (
<ConfigProvider
theme={{
token: {
colorPrimary: COLOR.YELLOW_PRIMARY,
colorBgBase: COLOR.YELLOW_SECONDARY,
colorTextBase: COLOR.YELLOW_PRIMARY,
colorBorder: COLOR.YELLOW_PRIMARY,
},
}}
>
<Button {...props}>{children}</Button>
</ConfigProvider>
);
18 changes: 9 additions & 9 deletions apps/launch/components/MyStakingContracts/Create/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,28 @@ import { useAccount } from 'wagmi';

import { CHAIN_NAMES, EXPLORER_URLS, UNICODE_SYMBOLS } from 'libs/util-constants/src';

import { ErrorAlert } from 'common-util/ErrorAlert';
import {
CONTRACT_TEMPLATES,
IMPLEMENTATION_ADDRESSES,
isSupportedChainId,
} from 'common-util/constants/stakingContract';
import { URL } from 'common-util/constants/urls';
import {
Feature,
createStakingContract,
getErrorInfo,
getIpfsHash,
getStakingContractInitPayload,
notifyConnectWallet,
notifyWrongNetwork,
} from 'common-util/functions';
import { getChainIdFromPath } from 'common-util/hooks/useNetworkHelpers';
import { getChainIdFromPath } from 'common-util/functions/networkHelpers';
import { ErrorType } from 'types/index';

import { Hint, StyledMain, Title } from './styles';
import {
DESCRIPTION_FIELD_RULES,
ErrorAlert,
ErrorType,
FormValues,
MAX_NUM_SERVICES_FIELD_RULES,
MaxNumServicesLabel,
Expand All @@ -63,11 +64,11 @@ export const CreateStakingContract = () => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<ErrorType>(null);
const params = useParams<{ network: string }>();
const chainName = params?.network as string;
const networkName = params?.network as string;

const { address: account, chain } = useAccount();

const networkId = getChainIdFromPath(chainName);
const networkId = getChainIdFromPath(networkName);
const wrongNetwork = chain && networkId ? networkId !== chain.id : false;

const handleCreate = async (values: FormValues) => {
Expand Down Expand Up @@ -110,16 +111,15 @@ export const CreateStakingContract = () => {
}

const result = await createStakingContract({ implementation, initPayload, account });

if (result) {
// TODO: once request contracts list task is done, need to update
// the staking contracts list with result.events.InstanceCreated data
router.push(`/${chainName}/${URL.myStakingContracts}`);
router.push(`/${networkName}/${URL.myStakingContracts}`);
}
} catch (error) {
console.log(error);

const { message, transactionHash } = getErrorInfo(error as Error);
const { message, transactionHash } = getErrorInfo(Feature.CREATE, error as Error);
setError({ message, transactionHash });
} finally {
setIsLoading(false);
Expand Down Expand Up @@ -197,7 +197,7 @@ export const CreateStakingContract = () => {
</Col>
</Row>
<Flex justify="end" gap={12}>
<Link href={`/${chainName}/${URL.myStakingContracts}`} passHref>
<Link href={`/${networkName}/${URL.myStakingContracts}`} passHref>
<Button>Cancel</Button>
</Link>
<Button type="primary" htmlType="submit" loading={isLoading}>
Expand Down
Loading
Loading