diff --git a/govtool/frontend/.eslintrc.cjs b/govtool/frontend/.eslintrc.cjs index 89a5aff94..07d27ff79 100644 --- a/govtool/frontend/.eslintrc.cjs +++ b/govtool/frontend/.eslintrc.cjs @@ -51,6 +51,7 @@ module.exports = { "operator-linebreak": "off", "implicit-arrow-linebreak": "off", "consistent-return": "off", + "no-console": ["error", { allow: ["warn", "error"] }], "no-shadow": "off", "function-paren-newline": "off", "object-curly-newline": "off", diff --git a/govtool/frontend/src/context/getUtxos.ts b/govtool/frontend/src/context/getUtxos.ts index 23fc0a198..6888846a8 100644 --- a/govtool/frontend/src/context/getUtxos.ts +++ b/govtool/frontend/src/context/getUtxos.ts @@ -77,7 +77,6 @@ export const getUtxos = async ( return utxos; } catch (err) { Sentry.captureException(err); - // eslint-disable-next-line no-console console.error(err); } }; diff --git a/govtool/frontend/src/context/pendingTransaction/types.ts b/govtool/frontend/src/context/pendingTransaction/types.ts index f6aae4ade..a44c5f6e0 100644 --- a/govtool/frontend/src/context/pendingTransaction/types.ts +++ b/govtool/frontend/src/context/pendingTransaction/types.ts @@ -15,14 +15,14 @@ export type TransactionType = export type TransactionStateWithoutResource = { type: TransactionTypeWithoutResource; transactionHash: string; - time: Date; + time: string; resourceId?: never; }; export type TransactionStateWithResource = { type: TransactionTypeWithResource; transactionHash: string; - time: Date; + time: string; resourceId: string; }; diff --git a/govtool/frontend/src/context/pendingTransaction/usePendingTransaction.ts b/govtool/frontend/src/context/pendingTransaction/usePendingTransaction.ts index 18f1e4a7c..a2c5af53a 100644 --- a/govtool/frontend/src/context/pendingTransaction/usePendingTransaction.ts +++ b/govtool/frontend/src/context/pendingTransaction/usePendingTransaction.ts @@ -20,7 +20,6 @@ const DB_SYNC_REFRESH_TIME = 3 * 1000; // 3 SECONDS const DB_SYNC_MAX_ATTEMPTS = 10; type UsePendingTransactionProps = { - dRepID: string; isEnabled: boolean; stakeKey: string | undefined; }; @@ -28,7 +27,6 @@ type UsePendingTransactionProps = { export const usePendingTransaction = ({ isEnabled, stakeKey, - dRepID, }: UsePendingTransactionProps) => { const { t } = useTranslation(); const { openModal, closeModal } = useModal(); @@ -57,11 +55,10 @@ export const usePendingTransaction = ({ const fromLocalStorage = getItemFromLocalStorage( `${PENDING_TRANSACTION_KEY}_${stakeKey}` ); - setTransaction( - fromLocalStorage - ? { ...fromLocalStorage, time: new Date(fromLocalStorage.time) } - : null - ); + setTransaction({ + ...fromLocalStorage, + resourceId: fromLocalStorage?.resourceId ?? undefined, + }); } }, [isEnabled, stakeKey]); @@ -84,9 +81,7 @@ export const usePendingTransaction = ({ if (isEnabled) { const desiredResult = getDesiredResult( type, - dRepID, resourceId, - stakeKey ); const queryKey = getQueryKey(type, transaction); @@ -105,13 +100,13 @@ export const usePendingTransaction = ({ await wait(DB_SYNC_REFRESH_TIME); } } - - if (isTransactionExpired(transaction.time)) { - addErrorAlert(t(`alerts.${type}.failed`)); - resetTransaction(); - } } } + + if (isTransactionExpired(transaction.time)) { + addErrorAlert(t(`alerts.${type}.failed`)); + resetTransaction(); + } }; let interval = setInterval(checkTransaction, TRANSACTION_REFRESH_TIME); @@ -120,7 +115,7 @@ export const usePendingTransaction = ({ if (isEnabled && transaction) { addWarningAlert(t("alerts.transactionInProgress"), 10000); } - }, [transaction]); + }, [isEnabled, transaction]); const isPendingTransaction = useCallback(() => { if (transaction) { @@ -144,14 +139,17 @@ export const usePendingTransaction = ({ const updateTransaction = (data: Omit) => { const newTransaction = { - time: new Date(), + time: new Date().toISOString(), ...data, } as TransactionState; setTransaction(newTransaction); setItemToLocalStorage( `${PENDING_TRANSACTION_KEY}_${stakeKey}`, - JSON.stringify(newTransaction) + { + ...newTransaction, + resourceId: newTransaction.resourceId || null, + } ); }; @@ -162,5 +160,5 @@ export const usePendingTransaction = ({ }; }; -const isTransactionExpired = (time: Date): boolean => - Date.now() - time.getTime() > TIME_TO_EXPIRE_TRANSACTION; +const isTransactionExpired = (time: string): boolean => + Date.now() - new Date(time).getTime() > TIME_TO_EXPIRE_TRANSACTION; diff --git a/govtool/frontend/src/context/pendingTransaction/utils.tsx b/govtool/frontend/src/context/pendingTransaction/utils.tsx index 916a994ff..ed7195b3d 100644 --- a/govtool/frontend/src/context/pendingTransaction/utils.tsx +++ b/govtool/frontend/src/context/pendingTransaction/utils.tsx @@ -4,17 +4,14 @@ import { TransactionType, TransactionState } from "./types"; export const getDesiredResult = ( type: TransactionType, - dRepID: string, resourceId: string | undefined, - stakeKey?: string ) => { switch (type) { case "delegate": { // current delegation - if (resourceId === dRepID) return dRepID; if (resourceId === "no confidence") return "drep_always_no_confidence"; if (resourceId === "abstain") return "drep_always_abstain"; - return stakeKey; + return resourceId; } case "registerAsDrep": case "registerAsSoleVoter": @@ -38,9 +35,9 @@ export const getQueryKey = ( case "retireAsDrep": case "registerAsSoleVoter": case "retireAsSoleVoter": - return [QUERY_KEYS.useGetDRepInfoKey, transaction]; + return [QUERY_KEYS.useGetDRepInfoKey, transaction?.transactionHash]; case "delegate": - return [QUERY_KEYS.getAdaHolderCurrentDelegationKey, transaction]; + return [QUERY_KEYS.getAdaHolderCurrentDelegationKey, transaction?.transactionHash]; default: return undefined; } @@ -58,7 +55,7 @@ export const refetchData = async ( // eslint-disable-next-line @typescript-eslint/no-explicit-any const data = await queryClient.getQueryData(queryKey); - if (type === "delegate") return data.currentDelegation; + if (type === "delegate") return data; if (type === "registerAsDrep" || type === "retireAsDrep") return data.isRegisteredAsDRep; if (type === "registerAsSoleVoter" || type === "retireAsSoleVoter") return data.isRegisteredAsSoleVoter; return undefined; diff --git a/govtool/frontend/src/context/wallet.tsx b/govtool/frontend/src/context/wallet.tsx index 75eb48eb0..a6eb929e9 100644 --- a/govtool/frontend/src/context/wallet.tsx +++ b/govtool/frontend/src/context/wallet.tsx @@ -1,6 +1,3 @@ -// TODO: enable eslint and fix all the errors with wallet refactor -/* eslint-disable */ -// @ts-nocheck import { createContext, useCallback, @@ -71,7 +68,8 @@ import { getUtxos } from './getUtxos'; import { useModal, useSnackbar } from '.'; import { PendingTransaction, - TransactionType, + TransactionStateWithResource, + TransactionStateWithoutResource, usePendingTransaction, } from './pendingTransaction'; @@ -97,7 +95,17 @@ type TreasuryProps = { url: string; }; -interface CardanoContext { +type BuildSignSubmitConwayCertTxArgs = { + certBuilder?: CertificatesBuilder; + govActionBuilder?: VotingProposalBuilder; + votingBuilder?: VotingBuilder; + voterDeposit?: string; +} & ( + | Pick + | Pick + ); + +interface CardanoContextType { address?: string; disconnectWallet: () => Promise; enable: (walletName: string) => Promise; @@ -119,24 +127,15 @@ interface CardanoContext { type, votingBuilder, voterDeposit, - }: { - certBuilder?: CertificatesBuilder; - govActionBuilder?: VotingProposalBuilder; - resourceId?: string; - type: TransactionType; - votingBuilder?: VotingBuilder; - voterDeposit?: string; - }) => Promise; + }: BuildSignSubmitConwayCertTxArgs) => Promise; buildDRepRegCert: ( url?: string, hash?: string, - hash?: string, ) => Promise; buildVoteDelegationCert: (vote: string) => Promise; buildDRepUpdateCert: ( url?: string, hash?: string, - hash?: string, ) => Promise; buildDRepRetirementCert: ( voterDeposit: string, @@ -147,7 +146,6 @@ interface CardanoContext { index: number, cip95MetadataURL?: string, cip95MetadataHash?: string, - cip95MetadataHash?: string, ) => Promise; pendingTransaction: PendingTransaction; isPendingTransaction: () => boolean; @@ -160,7 +158,7 @@ interface CardanoContext { } type Utxos = { - txid: any; + txid: unknown; txindx: number; amount: string; str: string; @@ -168,9 +166,9 @@ type Utxos = { TransactionUnspentOutput: TransactionUnspentOutput; }[]; -const NETWORK = import.meta.env.VITE_NETWORK_FLAG; +const NETWORK = +import.meta.env.VITE_NETWORK_FLAG; -const CardanoContext = createContext({} as CardanoContext); +const CardanoContext = createContext({} as CardanoContextType); CardanoContext.displayName = 'CardanoContext'; const CardanoProvider = (props: Props) => { @@ -186,7 +184,6 @@ const CardanoProvider = (props: Props) => { const [stakeKey, setStakeKey] = useState(undefined); const [stakeKeys, setStakeKeys] = useState([]); const [isMainnet, setIsMainnet] = useState(false); - const { openModal, closeModal } = useModal(); const [registeredStakeKeysListState, setRegisteredPubStakeKeysState] = useState([]); const [error, setError] = useState(undefined); @@ -201,7 +198,7 @@ const CardanoProvider = (props: Props) => { const epochParams = getItemFromLocalStorage(PROTOCOL_PARAMS_KEY); const { isPendingTransaction, updateTransaction, pendingTransaction } = - usePendingTransaction({ dRepID, isEnabled, stakeKey }); + usePendingTransaction({ isEnabled, stakeKey }); const getChangeAddress = async (enabledApi: CardanoApiWallet) => { try { @@ -249,7 +246,7 @@ const CardanoProvider = (props: Props) => { throw new Error(t('errors.walletNoCIP30Nor90Support')); } // Enable wallet connection - const enabledApi = await window.cardano[walletName] + const enabledApi: CardanoApiWallet = await window.cardano[walletName] .enable({ extensions: [{ cip: 95 }], }) @@ -267,15 +264,15 @@ const CardanoProvider = (props: Props) => { throw new Error(t('errors.walletNoCIP90FunctionsEnabled')); } const network = await enabledApi.getNetworkId(); - if (network != NETWORK) { + if (network !== NETWORK) { throw new Error( t('errors.tryingConnectTo', { - networkFrom: network == 1 ? 'mainnet' : 'testnet', - networkTo: network != 1 ? 'mainnet' : 'testnet', + networkFrom: network === 1 ? 'mainnet' : 'testnet', + networkTo: network !== 1 ? 'mainnet' : 'testnet', }), ); } - setIsMainnet(network == 1); + setIsMainnet(network === 1); // Check and set wallet address const usedAddresses = await enabledApi.getUsedAddresses(); const unusedAddresses = await enabledApi.getUnusedAddresses(); @@ -297,8 +294,8 @@ const CardanoProvider = (props: Props) => { let stakeKeysList; if (registeredStakeKeysList.length > 0) { - stakeKeysList = registeredStakeKeysList.map((stakeKey) => { - const stakeKeyHash = PublicKey.from_hex(stakeKey).hash(); + stakeKeysList = registeredStakeKeysList.map((key) => { + const stakeKeyHash = PublicKey.from_hex(key).hash(); const stakeCredential = Credential.from_keyhash(stakeKeyHash); if (network === 1) { return RewardAddress.new(1, stakeCredential) @@ -311,8 +308,8 @@ const CardanoProvider = (props: Props) => { }); } else { console.warn(t('warnings.usingUnregisteredStakeKeys')); - stakeKeysList = unregisteredStakeKeysList.map((stakeKey) => { - const stakeKeyHash = PublicKey.from_hex(stakeKey).hash(); + stakeKeysList = unregisteredStakeKeysList.map((key) => { + const stakeKeyHash = PublicKey.from_hex(key).hash(); const stakeCredential = Credential.from_keyhash(stakeKeyHash); if (network === 1) { return RewardAddress.new(1, stakeCredential) @@ -362,14 +359,16 @@ const CardanoProvider = (props: Props) => { setPubDRepKey(''); setStakeKey(undefined); setIsEnabled(false); + // eslint-disable-next-line no-throw-literal throw { status: 'ERROR', - error: `${e == undefined ? t('errors.somethingWentWrong') : e}`, + error: `${e ?? t('errors.somethingWentWrong')}`, }; } finally { setIsEnableLoading(null); } } + // eslint-disable-next-line no-throw-literal throw { status: 'ERROR', error: t('errors.somethingWentWrong') }; }, [isEnabled, stakeKeys], @@ -415,6 +414,7 @@ const CardanoProvider = (props: Props) => { const getTxUnspentOutputs = async (utxos: Utxos) => { const txOutputs = TransactionUnspentOutputs.new(); + // eslint-disable-next-line no-restricted-syntax for (const utxo of utxos) { txOutputs.add(utxo.TransactionUnspentOutput); } @@ -430,14 +430,7 @@ const CardanoProvider = (props: Props) => { type, votingBuilder, voterDeposit, - }: { - certBuilder?: CertificatesBuilder; - govActionBuilder?: VotingProposalBuilder; - resourceId?: string; - type: TransactionType; - votingBuilder?: VotingBuilder; - voterDeposit?: string; - }) => { + }: BuildSignSubmitConwayCertTxArgs) => { await checkIsMaintenanceOn(); const isPendingTx = isPendingTransaction(); if (isPendingTx) return; @@ -539,9 +532,11 @@ const CardanoProvider = (props: Props) => { resourceId, }); + // eslint-disable-next-line no-console console.log(signedTx.to_hex(), 'signed tx cbor'); return resultHash; - // TODO: type error + // TODO: type error + // eslint-disable-next-line @typescript-eslint/no-shadow, @typescript-eslint/no-explicit-any } catch (error: any) { const walletName = getItemFromLocalStorage(`${WALLET_LS_KEY}_name`); const isWalletConnected = await window.cardano[walletName].isEnabled(); @@ -597,7 +592,7 @@ const CardanoProvider = (props: Props) => { return certBuilder; } catch (e) { Sentry.captureException(e); - console.log(e); + console.error(e); throw e; } }, @@ -629,7 +624,7 @@ const CardanoProvider = (props: Props) => { anchor, ); } else { - console.log(t('errors.notUsingAnchor')); + console.error(t('errors.notUsingAnchor')); dRepRegCert = DrepRegistration.new( dRepCred, BigNum.from_str(`${epochParams.drep_deposit}`), @@ -675,7 +670,7 @@ const CardanoProvider = (props: Props) => { return certBuilder; } catch (e) { Sentry.captureException(e); - console.log(e); + console.error(e); throw e; } }, @@ -703,7 +698,7 @@ const CardanoProvider = (props: Props) => { return certBuilder; } catch (e) { Sentry.captureException(e); - console.log(e); + console.error(e); throw e; } }, @@ -756,7 +751,7 @@ const CardanoProvider = (props: Props) => { return votingBuilder; } catch (e) { Sentry.captureException(e); - console.log(e); + console.error(e); throw e; } }, @@ -963,6 +958,8 @@ function useCardano() { } return result; } + // TODO: type error + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (e: any) { Sentry.captureException(e); await context.disconnectWallet(); diff --git a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts index 22843aba7..ff0d505b6 100644 --- a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts +++ b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts @@ -183,7 +183,6 @@ export const useCreateGovernanceActionForm = ( } // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { - // eslint-disable-next-line no-console console.error(error); throw error; } diff --git a/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx b/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx index 7afe6084a..9f7ac6e37 100644 --- a/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx +++ b/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx @@ -37,7 +37,6 @@ export const useRegisterAsdRepForm = () => { console.log(values); // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (e: any) { - // eslint-disable-next-line no-console console.error(e); } finally { setIsLoading(false); diff --git a/govtool/frontend/src/hooks/queries/useGetAdaHolderCurrentDelegationQuery.ts b/govtool/frontend/src/hooks/queries/useGetAdaHolderCurrentDelegationQuery.ts index 94dc2621d..ba2b170af 100644 --- a/govtool/frontend/src/hooks/queries/useGetAdaHolderCurrentDelegationQuery.ts +++ b/govtool/frontend/src/hooks/queries/useGetAdaHolderCurrentDelegationQuery.ts @@ -4,13 +4,13 @@ import { getAdaHolderCurrentDelegation } from "@services"; import { QUERY_KEYS } from "@consts"; import { useCardano } from "@context"; -export const useGetAdaHolderCurrentDelegationQuery = (stakeKey?: string) => { +export const useGetAdaHolderCurrentDelegationQuery = (stakeKey: string | undefined) => { const { pendingTransaction } = useCardano(); const { data, isLoading } = useQuery({ queryKey: [ QUERY_KEYS.getAdaHolderCurrentDelegationKey, - pendingTransaction.delegate, + pendingTransaction.delegate?.transactionHash, ], queryFn: () => getAdaHolderCurrentDelegation({ stakeKey }), enabled: !!stakeKey, diff --git a/govtool/frontend/src/hooks/queries/useGetDRepListQuery.ts b/govtool/frontend/src/hooks/queries/useGetDRepListQuery.ts index 4e9aa0c26..806d55072 100644 --- a/govtool/frontend/src/hooks/queries/useGetDRepListQuery.ts +++ b/govtool/frontend/src/hooks/queries/useGetDRepListQuery.ts @@ -10,10 +10,10 @@ export const useGetDRepListQuery = () => { const { data, isLoading } = useQuery({ queryKey: [ QUERY_KEYS.useGetDRepListKey, - pendingTransaction.registerAsSoleVoter || + (pendingTransaction.registerAsSoleVoter || pendingTransaction.registerAsDrep || pendingTransaction.retireAsSoleVoter || - pendingTransaction.retireAsDrep, + pendingTransaction.retireAsDrep)?.transactionHash, ], queryFn: getDRepList, }); diff --git a/govtool/frontend/src/hooks/queries/useGetDRepVotesQuery.ts b/govtool/frontend/src/hooks/queries/useGetDRepVotesQuery.ts index 034423c29..304c39cff 100644 --- a/govtool/frontend/src/hooks/queries/useGetDRepVotesQuery.ts +++ b/govtool/frontend/src/hooks/queries/useGetDRepVotesQuery.ts @@ -11,7 +11,7 @@ export const useGetDRepVotesQuery = (filters: string[], sorting: string) => { const { data, isLoading, refetch, isRefetching } = useQuery({ queryKey: [ QUERY_KEYS.useGetDRepVotesKey, - pendingTransaction.vote, + pendingTransaction.vote?.transactionHash, filters, sorting, ], diff --git a/govtool/frontend/src/hooks/queries/useGetProposalsInfiniteQuery.ts b/govtool/frontend/src/hooks/queries/useGetProposalsInfiniteQuery.ts index 90e2ac016..7e141842e 100644 --- a/govtool/frontend/src/hooks/queries/useGetProposalsInfiniteQuery.ts +++ b/govtool/frontend/src/hooks/queries/useGetProposalsInfiniteQuery.ts @@ -33,7 +33,7 @@ export const useGetProposalsInfiniteQuery = ({ dRepID, filters, isEnabled, - pendingTransaction.vote, + pendingTransaction.vote?.transactionHash, sorting, ], fetchProposals, diff --git a/govtool/frontend/src/hooks/queries/useGetProposalsQuery.ts b/govtool/frontend/src/hooks/queries/useGetProposalsQuery.ts index 3d0434acd..242add713 100644 --- a/govtool/frontend/src/hooks/queries/useGetProposalsQuery.ts +++ b/govtool/frontend/src/hooks/queries/useGetProposalsQuery.ts @@ -28,7 +28,7 @@ export const useGetProposalsQuery = ({ filters, sorting, dRepID, - pendingTransaction.vote, + pendingTransaction.vote?.transactionHash, ], fetchProposals, ); diff --git a/govtool/frontend/src/hooks/queries/useGetVoterInfoQuery.ts b/govtool/frontend/src/hooks/queries/useGetVoterInfoQuery.ts index 5eab75e42..a21a5cf55 100644 --- a/govtool/frontend/src/hooks/queries/useGetVoterInfoQuery.ts +++ b/govtool/frontend/src/hooks/queries/useGetVoterInfoQuery.ts @@ -10,10 +10,10 @@ export const useGetVoterInfo = () => { const { data } = useQuery({ queryKey: [ QUERY_KEYS.useGetDRepInfoKey, - pendingTransaction.registerAsDrep || + (pendingTransaction.registerAsDrep || pendingTransaction.registerAsSoleVoter || pendingTransaction.retireAsDrep || - pendingTransaction.retireAsSoleVoter, + pendingTransaction.retireAsSoleVoter)?.transactionHash, ], enabled: !!dRepID, queryFn: () => getVoterInfo(dRepID), diff --git a/govtool/frontend/src/utils/getDRepID.ts b/govtool/frontend/src/utils/getDRepID.ts index ccc23d8bd..05561eaf5 100644 --- a/govtool/frontend/src/utils/getDRepID.ts +++ b/govtool/frontend/src/utils/getDRepID.ts @@ -28,7 +28,6 @@ export const getPubDRepID = async (walletApi: CardanoApiWallet) => { dRepIDBech32, }; } catch (err) { - // eslint-disable-next-line no-console console.error(err); return { dRepKey: undefined,