From d65628442c30b573c7b35aafd633abaa4161b740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Tue, 4 Mar 2025 15:33:06 +0100 Subject: [PATCH] feat(#3080): change drep registration transaction confirmation --- CHANGELOG.md | 2 ++ .../backend/sql/get-transaction-status.sql | 20 +++++++++++++- govtool/backend/src/VVA/Transaction.hs | 6 ++--- govtool/backend/src/VVA/Types.hs | 8 +++--- .../usePendingTransaction.ts | 23 +++++++++++++--- .../src/context/pendingTransaction/utils.tsx | 27 ++++++++++++++++--- .../hooks/queries/useGetDrepDetailsQuery.ts | 9 ++++++- govtool/frontend/src/models/api.ts | 27 +++++++++++++++++++ 8 files changed, 106 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ce80483c..ac8f84455 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,8 @@ changes. ### Changed +- Change transaction confirmation to be based on existing off chain data for drep registration [Issue 3080](https://github.com/IntersectMBO/govtool/issues/3080) + ### Removed - Remove ratification threshold for Info Action for Consitutional Committee [Issue 3108](https://github.com/IntersectMBO/govtool/issues/3108) diff --git a/govtool/backend/sql/get-transaction-status.sql b/govtool/backend/sql/get-transaction-status.sql index 219064999..e87a8743a 100644 --- a/govtool/backend/sql/get-transaction-status.sql +++ b/govtool/backend/sql/get-transaction-status.sql @@ -6,4 +6,22 @@ SELECT JOIN tx ON voting_procedure.tx_id = tx.id WHERE tx.hash = decode(?, 'hex') ), '[]'::json - ) AS voting_procedures; + ) AS voting_procedures, + COALESCE( + (SELECT NULLIF(jsonb_agg( + jsonb_build_object( + 'drep_registration', to_jsonb(drep_registration.*), + 'off_chain_vote_drep_data', + (SELECT NULLIF(jsonb_agg(to_jsonb(off_chain_vote_drep_data)), '[]'::jsonb) + FROM off_chain_vote_data + JOIN off_chain_vote_drep_data + ON off_chain_vote_drep_data.off_chain_vote_data_id = off_chain_vote_data.id + WHERE off_chain_vote_data.voting_anchor_id = drep_registration.voting_anchor_id + ) + ) + ), '[]'::jsonb) + FROM drep_registration + JOIN tx ON drep_registration.tx_id = tx.id + WHERE tx.hash = decode(?, 'hex') + ), NULL + ) AS drep_registrations diff --git a/govtool/backend/src/VVA/Transaction.hs b/govtool/backend/src/VVA/Transaction.hs index 11c1e349e..d2e5bd26b 100644 --- a/govtool/backend/src/VVA/Transaction.hs +++ b/govtool/backend/src/VVA/Transaction.hs @@ -35,8 +35,8 @@ getTransactionStatus :: => Text -> m (Maybe TransactionStatus) getTransactionStatus transactionId = withPool $ \conn -> do - result <- liftIO $ SQL.query conn getTransactionStatusSql (transactionId, transactionId) + result <- liftIO $ SQL.query conn getTransactionStatusSql (transactionId, transactionId, transactionId) case result of - [(transactionConfirmed, votingProcedure)] -> do - return $ Just $ TransactionStatus transactionConfirmed votingProcedure + [(transactionConfirmed, votingProcedure, drepRegistration)] -> do + return $ Just $ TransactionStatus transactionConfirmed votingProcedure drepRegistration _ -> return Nothing \ No newline at end of file diff --git a/govtool/backend/src/VVA/Types.hs b/govtool/backend/src/VVA/Types.hs index 5d1f3ca5f..22b78eb62 100644 --- a/govtool/backend/src/VVA/Types.hs +++ b/govtool/backend/src/VVA/Types.hs @@ -188,17 +188,19 @@ instance FromRow Proposal where data TransactionStatus = TransactionStatus { transactionConfirmed :: Bool - , votingProcedure :: Maybe Value + , votingProcedure :: Maybe Value + , drepRegistration :: Maybe Value } instance FromRow TransactionStatus where - fromRow = TransactionStatus <$> field <*> field + fromRow = TransactionStatus <$> field <*> field <*> field instance ToJSON TransactionStatus where - toJSON TransactionStatus {transactionConfirmed, votingProcedure} = + toJSON TransactionStatus {transactionConfirmed, votingProcedure, drepRegistration} = object [ "transactionConfirmed" .= transactionConfirmed , "votingProcedure" .= votingProcedure + , "drepRegistration" .= drepRegistration ] data CacheEnv diff --git a/govtool/frontend/src/context/pendingTransaction/usePendingTransaction.ts b/govtool/frontend/src/context/pendingTransaction/usePendingTransaction.ts index 6d1bb06ca..2924651f3 100644 --- a/govtool/frontend/src/context/pendingTransaction/usePendingTransaction.ts +++ b/govtool/frontend/src/context/pendingTransaction/usePendingTransaction.ts @@ -12,9 +12,14 @@ import { StatusModalState } from "@organisms"; import { useQueryClient } from "react-query"; import { useModal, useSnackbar } from ".."; import { TransactionState } from "./types"; -import { getDesiredResult, getQueryKey, refetchData } from "./utils"; +import { + getDesiredResult, + getQueryKey, + invalidateQuery, + refetchData, +} from "./utils"; -const TIME_TO_EXPIRE_TRANSACTION = 3 * 60 * 1000; // 3 MINUTES +const TIME_TO_EXPIRE_TRANSACTION = 5 * 60 * 1000; // 5 MINUTES const TRANSACTION_REFRESH_TIME = 15 * 1000; // 15 SECONDS const DB_SYNC_REFRESH_TIME = 3 * 1000; // 3 SECONDS const DB_SYNC_MAX_ATTEMPTS = 10; @@ -80,7 +85,15 @@ export const usePendingTransaction = ({ if ( status.transactionConfirmed && - (type === "vote" ? status.votingProcedure.length > 0 : true) + ((type === "vote" && status.votingProcedure.length > 0) || + (type === "registerAsDrep" && + status.drepRegistration[0]?.off_chain_vote_drep_data) || + (type === "retireAsDrep" && + status.drepRegistration[0]?.drep_registration) || + (type === "registerAsDirectVoter" && + status.drepRegistration[0]?.drep_registration) || + (type === "retireAsDirectVoter" && + status.drepRegistration[0]?.drep_registration)) ) { clearInterval(interval); @@ -101,6 +114,8 @@ export const usePendingTransaction = ({ ); if (desiredResult === data) { + // eslint-disable-next-line no-await-in-loop + await invalidateQuery(type, queryClient); addSuccessAlert(t(`alerts.${type}.success`)); resetTransaction(); isDBSyncUpdated = true; @@ -155,7 +170,7 @@ export const usePendingTransaction = ({ setTransaction(newTransaction); setItemToLocalStorage(`${PENDING_TRANSACTION_KEY}_${stakeKey}`, { ...newTransaction, - resourceId: newTransaction.resourceId || null, + resourceId: newTransaction.resourceId ?? null, }); }; diff --git a/govtool/frontend/src/context/pendingTransaction/utils.tsx b/govtool/frontend/src/context/pendingTransaction/utils.tsx index e3fe9e3c2..b1be1cf64 100644 --- a/govtool/frontend/src/context/pendingTransaction/utils.tsx +++ b/govtool/frontend/src/context/pendingTransaction/utils.tsx @@ -48,10 +48,6 @@ export const getQueryKey = ( case "retireAsDirectVoter": return [QUERY_KEYS.useGetDRepInfoKey, transaction?.transactionHash]; case "delegate": - return [ - QUERY_KEYS.getAdaHolderCurrentDelegationKey, - transaction?.transactionHash, - ]; case "vote": return [ QUERY_KEYS.getAdaHolderCurrentDelegationKey, @@ -62,6 +58,21 @@ export const getQueryKey = ( } }; +export const getQueryKeyToInvalidate = (type: TransactionType) => { + switch (type) { + case "registerAsDrep": + case "retireAsDrep": + case "registerAsDirectVoter": + case "retireAsDirectVoter": + return QUERY_KEYS.useGetDRepListInfiniteKey; + case "delegate": + case "vote": + return QUERY_KEYS.useGetProposalsInfiniteKey; + default: + return undefined; + } +}; + export const refetchData = async ( type: TransactionType, queryClient: QueryClient, @@ -94,3 +105,11 @@ export const refetchData = async ( } return undefined; }; + +export const invalidateQuery = async ( + type: TransactionType, + queryClient: QueryClient, +) => { + const queryKey = getQueryKeyToInvalidate(type); + if (queryKey) await queryClient.invalidateQueries(queryKey); +}; diff --git a/govtool/frontend/src/hooks/queries/useGetDrepDetailsQuery.ts b/govtool/frontend/src/hooks/queries/useGetDrepDetailsQuery.ts index 3c99959ff..1b42f285d 100644 --- a/govtool/frontend/src/hooks/queries/useGetDrepDetailsQuery.ts +++ b/govtool/frontend/src/hooks/queries/useGetDrepDetailsQuery.ts @@ -9,7 +9,14 @@ export const useGetDRepDetailsQuery = ( ) => { const { dRepData, isDRepListLoading } = useGetDRepListInfiniteQuery( { searchPhrase: dRepId ?? undefined }, - { enabled: options?.enabled || !!dRepId, ...options }, + { + enabled: options?.enabled || !!dRepId, + ...options, + keepPreviousData: false, + refetchOnWindowFocus: true, + cacheTime: 0, + staleTime: 0, + }, ); return { dRep: dRepData?.[0], isLoading: isDRepListLoading }; diff --git a/govtool/frontend/src/models/api.ts b/govtool/frontend/src/models/api.ts index 60890fd6d..ccfa3c87b 100644 --- a/govtool/frontend/src/models/api.ts +++ b/govtool/frontend/src/models/api.ts @@ -76,6 +76,33 @@ export type TransactionStatus = { voting_anchor_id: number | null; }[] | []; + drepRegistration: + | { + drep_registration: + | { + cert_index: number; + deposit: number; + drep_hash_id: number; + id: number; + tx_id: number; + voting_anchor_id: number; + }[] + | []; + off_chain_vote_drep_data: + | { + given_name: string; + id: number; + image_hash: string | null; + image_url: string | null; + motivations: string; + objectives: string; + off_chain_vote_data_id: number; + payment_address: string | null; + qualifications: string; + }[] + | []; + }[] + | []; }; export enum Network {