From 1b551ea58981de7dc7f479d5d1b70bdbcef1f42b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Thu, 13 Mar 2025 21:42:04 +0100 Subject: [PATCH] feat(#3189): exclude network information from network metrics endpoint --- CHANGELOG.md | 6 +- govtool/backend/README.md | 34 +++---- govtool/backend/app/Main.hs | 5 + govtool/backend/sql/get-network-info.sql | 6 ++ govtool/backend/sql/get-network-metrics.sql | 48 +--------- .../backend/sql/get-network-total-stake.sql | 93 +++++++++++++++++++ govtool/backend/src/VVA/API.hs | 38 ++++++-- govtool/backend/src/VVA/API/Types.hs | 62 ++++++++++--- govtool/backend/src/VVA/Network.hs | 58 ++++++++---- govtool/backend/src/VVA/Types.hs | 48 ++++++---- govtool/backend/vva-be.cabal | 2 + .../components/molecules/VotesSubmitted.tsx | 29 ++++-- .../organisms/AutomatedVotingOptions.tsx | 16 ++-- govtool/frontend/src/consts/queryKeys.ts | 2 + govtool/frontend/src/context/appContext.tsx | 28 +++--- govtool/frontend/src/hooks/queries/index.ts | 4 +- .../src/hooks/queries/useGetNetworkInfo.ts | 14 +++ .../hooks/queries/useGetNetworkTotalStake.ts | 16 ++++ govtool/frontend/src/models/api.ts | 18 ++-- govtool/frontend/src/services/AdaHandle.ts | 4 +- .../src/services/requests/getNetworkInfo.ts | 8 ++ .../services/requests/getNetworkTotalStake.ts | 8 ++ .../frontend/src/services/requests/index.ts | 8 +- govtool/frontend/src/utils/localStorage.ts | 2 + 24 files changed, 389 insertions(+), 168 deletions(-) create mode 100644 govtool/backend/sql/get-network-info.sql create mode 100644 govtool/backend/sql/get-network-total-stake.sql create mode 100644 govtool/frontend/src/hooks/queries/useGetNetworkInfo.ts create mode 100644 govtool/frontend/src/hooks/queries/useGetNetworkTotalStake.ts create mode 100644 govtool/frontend/src/services/requests/getNetworkInfo.ts create mode 100644 govtool/frontend/src/services/requests/getNetworkTotalStake.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 34361b48a..1c586129c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,12 +12,14 @@ changes. ### Added -### Fixed +- Add support for preprod in matomo analytics [Issue 3173](https://github.com/IntersectMBO/govtool/issues/3173) -- hotfix for ada handle and payment address validation order [Issue 3155](https://github.com/IntersectMBO/govtool/issues/3155) +### Fixed ### Changed +- Exclude network total stake and info from network metrics [Issue 3189](https://github.com/IntersectMBO/govtool/issues/3189) + ### Removed ## [v2.0.15](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.15) 2025-03-11 diff --git a/govtool/backend/README.md b/govtool/backend/README.md index 566293184..cc5a9a285 100644 --- a/govtool/backend/README.md +++ b/govtool/backend/README.md @@ -6,9 +6,9 @@ This is a backend application of GovTool project. In order to run `backend` your host machine will need access to the `cardano-db-sync` postgres database. To have this database running locally you'll need: -- `cardano-node` -- `cardano-db-sync` -- PostgreSQL database +- [cardano-node](https://github.com/IntersectMBO/cardano-node) +- [cardano-db-sync](https://github.com/IntersectMBO/cardano-db-sync) +- [PostgreSQL database](https://www.postgresql.org/download/) (psql needs to be installed on your machine in order to compile the project) You will need your `cardano-node` and `cardano-db-sync` to be compatible with Sancho testnet. Until these features will be merged to the master branch the new Sancho compatible versions are available as releases on [github](https://github.com/IntersectMBO/cardano-db-sync/releases). You will also need a correct `cardano-node` version. The release notes for `cardano-db-sync` usualy specify that. @@ -30,44 +30,44 @@ Due to problems with openapi3 package it's hard to build this project with plain 2. Get [direnv](https://direnv.net/). -3. Set GHC version to 9.10.1: +3. Set GHC version to 9.2.8: ```sh - ghcup install ghc 9.10.1 + ghcup install ghc 9.2.8 - ghcup set ghc 9.10.1 + ghcup set ghc 9.2.8 ``` 4. Install cabal - ```sh - ghcup install cabal - ghcup set cabal - ``` + ```sh + ghcup install cabal + ghcup set cabal + ``` 5. Enter `govtool/backend` directory: ```sh - cd govtool/backend + cd govtool/backend ``` 6. Allow direnv to setup your environment: ```sh - direnv allow + direnv allow ``` 7. Update cabal & build project ```sh - cabal update - cabal build all + cabal update + cabal build all ``` 8. Create a config file. You can use `example-config.json` as a template. 9. Run project - `sh - cabal run vva-be -- --config start-app - ` + ```sh + cabal run vva-be -- --config start-app + ``` > [!WARNING] > In the context of our ongoing project enhancements, it is assumed that the executable previously known as 'vva-be' should be now officially renamed to 'govtool-backend'. This change is necessary for aligning with the updated branding and functional scope of the application and it has to be implemented in the near future as a chore and refactoring ticket. Make sure that the documentation matches the actual name of the executable. diff --git a/govtool/backend/app/Main.hs b/govtool/backend/app/Main.hs index 6311288f0..66514e170 100644 --- a/govtool/backend/app/Main.hs +++ b/govtool/backend/app/Main.hs @@ -122,6 +122,8 @@ startApp vvaConfig sentryService = do dRepVotingPowerCache <- newCache dRepListCache <- newCache networkMetricsCache <- newCache + networkInfoCache <- newCache + networkTotalStakeCache <- newCache return $ CacheEnv { proposalListCache , getProposalCache @@ -133,6 +135,8 @@ startApp vvaConfig sentryService = do , dRepVotingPowerCache , dRepListCache , networkMetricsCache + , networkInfoCache + , networkTotalStakeCache } let connectionString = encodeUtf8 (dbSyncConnectionString $ getter vvaConfig) @@ -144,6 +148,7 @@ startApp vvaConfig sentryService = do exceptionHandler :: VVAConfig -> SentryService -> Maybe Request -> SomeException -> IO () exceptionHandler vvaConfig sentryService mRequest exception = do + print exception let isNotTimeoutThread x = case fromException x of Just TimeoutThread -> False _ -> True diff --git a/govtool/backend/sql/get-network-info.sql b/govtool/backend/sql/get-network-info.sql new file mode 100644 index 000000000..86953993e --- /dev/null +++ b/govtool/backend/sql/get-network-info.sql @@ -0,0 +1,6 @@ +SELECT + (SELECT MAX(no) FROM epoch) AS current_epoch, + (SELECT MAX(block_no) FROM block) AS current_block, + network_name +FROM + meta; \ No newline at end of file diff --git a/govtool/backend/sql/get-network-metrics.sql b/govtool/backend/sql/get-network-metrics.sql index 21efd2a91..4aa9c8cbb 100644 --- a/govtool/backend/sql/get-network-metrics.sql +++ b/govtool/backend/sql/get-network-metrics.sql @@ -110,23 +110,6 @@ TotalActiveCIP119CompliantDReps AS ( AND lve.epoch_no >= (SELECT epoch_no FROM ActiveDRepBoundaryEpoch) ))) ), -TotalStakeControlledByActiveDReps AS ( - SELECT - COALESCE(SUM(dd.amount), 0)::bigint AS total - FROM - drep_hash dh - LEFT JOIN DRepDistr dd ON dd.hash_id = dh.id AND dd.rn = 1 - LEFT JOIN RankedDRepRegistration rd ON dd.hash_id = rd.drep_hash_id AND rd.rn = 1 - LEFT JOIN LatestVoteEpoch lve ON lve.drep_id = dh.id - CROSS JOIN DRepActivity - WHERE - dd.epoch_no = (SELECT no FROM CurrentEpoch) - AND COALESCE(rd.deposit, 0) >= 0 - AND ((DRepActivity.epoch_no - GREATEST(COALESCE(lve.epoch_no, 0), COALESCE(rd.epoch_no, 0))) <= DRepActivity.drep_activity) -), -CurrentBlock AS ( - SELECT MAX(block_no) AS block_no FROM block -), UniqueDelegators AS ( SELECT COUNT(DISTINCT addr_id) AS count FROM delegation_vote ), @@ -139,9 +122,6 @@ TotalGovActionProposals AS ( TotalDRepVotes AS ( SELECT COUNT(*) AS count FROM voting_procedure WHERE voter_role = 'DRep' ), -TotalStakeControlledBySPOs AS ( - SELECT SUM(ps.stake)::bigint AS total FROM pool_stat ps WHERE ps.epoch_no = (SELECT no FROM CurrentEpoch) -), LatestExistingVotingAnchor AS ( SELECT subquery.drep_registration_id, @@ -192,18 +172,6 @@ TotalRegisteredDirectVoters AS ( LEFT JOIN HasNonDeregisterVotingAnchor hndva ON hndva.drep_hash_id = rdr.drep_hash_id WHERE rdr.rn = 1 AND COALESCE(rdr.deposit, 0) >= 0 AND (leva.url IS NULL OR hndva.value = true) ), -AlwaysAbstainVotingPower AS ( - SELECT COALESCE((SELECT amount FROM drep_hash - LEFT JOIN drep_distr ON drep_hash.id = drep_distr.hash_id - WHERE drep_hash.view = 'drep_always_abstain' - ORDER BY epoch_no DESC LIMIT 1), 0) AS amount -), -AlwaysNoConfidenceVotingPower AS ( - SELECT COALESCE((SELECT amount FROM drep_hash - LEFT JOIN drep_distr ON drep_hash.id = drep_distr.hash_id - WHERE drep_hash.view = 'drep_always_no_confidence' - ORDER BY epoch_no DESC LIMIT 1), 0) AS amount -), TotalDRepDistr AS ( SELECT SUM(COALESCE(amount, 0))::bigint total_drep_distr FROM drep_distr where epoch_no = (SELECT no from CurrentEpoch) ), @@ -223,42 +191,28 @@ CommitteeThreshold AS ( OR (c.gov_action_proposal_id IS NULL) ) SELECT - CurrentEpoch.no AS epoch_no, - CurrentBlock.block_no, UniqueDelegators.count AS unique_delegators, TotalDelegations.count AS total_delegations, TotalGovActionProposals.count AS total_gov_action_proposals, TotalDRepVotes.count AS total_drep_votes, TotalRegisteredDReps.unique_registrations AS total_registered_dreps, TotalDRepDistr.total_drep_distr, - COALESCE(TotalStakeControlledByActiveDReps.total, 0) + COALESCE(AlwaysNoConfidenceVotingPower.amount, 0) AS total_stake_controlled_by_active_dreps, - COALESCE(TotalStakeControlledBySPOs.total, 0) AS total_stake_controlled_by_spos, TotalActiveDReps.unique_active_drep_registrations AS total_active_dreps, TotalInactiveDReps.total_inactive_dreps AS total_inactive_dreps, TotalActiveCIP119CompliantDReps.unique_active_cip119_compliant_drep_registrations AS total_active_cip119_compliant_dreps, TotalRegisteredDirectVoters.unique_direct_voters AS total_registered_direct_voters, - AlwaysAbstainVotingPower.amount AS always_abstain_voting_power, - AlwaysNoConfidenceVotingPower.amount AS always_no_confidence_voting_power, - meta.network_name, NoOfCommitteeMembers.total no_of_committee_members, CommitteeThreshold.quorum_numerator, CommitteeThreshold.quorum_denominator -FROM CurrentEpoch -CROSS JOIN CurrentBlock -CROSS JOIN UniqueDelegators +FROM UniqueDelegators CROSS JOIN TotalDRepDistr CROSS JOIN TotalDelegations CROSS JOIN TotalGovActionProposals CROSS JOIN TotalDRepVotes CROSS JOIN TotalRegisteredDReps -CROSS JOIN TotalStakeControlledByActiveDReps -CROSS JOIN TotalStakeControlledBySPOs CROSS JOIN TotalActiveDReps CROSS JOIN TotalInactiveDReps CROSS JOIN TotalActiveCIP119CompliantDReps CROSS JOIN TotalRegisteredDirectVoters -CROSS JOIN AlwaysAbstainVotingPower -CROSS JOIN AlwaysNoConfidenceVotingPower CROSS JOIN NoOfCommitteeMembers CROSS JOIN CommitteeThreshold -CROSS JOIN meta; diff --git a/govtool/backend/sql/get-network-total-stake.sql b/govtool/backend/sql/get-network-total-stake.sql new file mode 100644 index 000000000..9399df5c3 --- /dev/null +++ b/govtool/backend/sql/get-network-total-stake.sql @@ -0,0 +1,93 @@ +WITH DRepActivity AS ( + SELECT + drep_activity AS drep_activity, + epoch_no AS epoch_no + FROM + epoch_param + WHERE + epoch_no IS NOT NULL + ORDER BY + epoch_no DESC + LIMIT 1 +), +LatestVotingProcedure AS ( + SELECT + vp.*, + ROW_NUMBER() OVER (PARTITION BY drep_voter ORDER BY tx_id DESC) AS rn + FROM + voting_procedure vp +), +DRepDistr AS ( + SELECT + drep_distr.*, + ROW_NUMBER() OVER (PARTITION BY drep_hash.id ORDER BY drep_distr.epoch_no DESC) AS rn + FROM + drep_distr + JOIN drep_hash ON drep_hash.id = drep_distr.hash_id +), +CurrentEpoch AS ( + SELECT MAX(no) AS no FROM epoch +), +LatestVoteEpoch AS ( + SELECT + block.epoch_no, + lvp.drep_voter AS drep_id + FROM + LatestVotingProcedure lvp + JOIN tx ON tx.id = lvp.tx_id + JOIN block ON block.id = tx.block_id + WHERE + lvp.rn = 1 +), +RankedDRepRegistration AS ( + SELECT + dr.id, + dr.drep_hash_id, + dr.deposit, + dr.voting_anchor_id, + ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn, + encode(tx.hash, 'hex') AS tx_hash, + block.epoch_no + FROM + drep_registration dr + JOIN tx ON tx.id = dr.tx_id + JOIN block ON block.id = tx.block_id +), +TotalStakeControlledByActiveDReps AS ( + SELECT + COALESCE(SUM(dd.amount), 0)::bigint AS total + FROM + drep_hash dh + LEFT JOIN DRepDistr dd ON dd.hash_id = dh.id AND dd.rn = 1 + LEFT JOIN RankedDRepRegistration rd ON dd.hash_id = rd.drep_hash_id AND rd.rn = 1 + LEFT JOIN LatestVoteEpoch lve ON lve.drep_id = dh.id + CROSS JOIN DRepActivity + WHERE + dd.epoch_no = (SELECT no FROM CurrentEpoch) + AND COALESCE(rd.deposit, 0) >= 0 + AND ((DRepActivity.epoch_no - GREATEST(COALESCE(lve.epoch_no, 0), COALESCE(rd.epoch_no, 0))) <= DRepActivity.drep_activity) +), +TotalStakeControlledBySPOs AS ( + SELECT SUM(ps.stake)::bigint AS total FROM pool_stat ps WHERE ps.epoch_no = (SELECT no FROM CurrentEpoch) +), +AlwaysAbstainVotingPower AS ( + SELECT COALESCE((SELECT amount FROM drep_hash + LEFT JOIN drep_distr ON drep_hash.id = drep_distr.hash_id + WHERE drep_hash.view = 'drep_always_abstain' + ORDER BY epoch_no DESC LIMIT 1), 0) AS amount +), +AlwaysNoConfidenceVotingPower AS ( + SELECT COALESCE((SELECT amount FROM drep_hash + LEFT JOIN drep_distr ON drep_hash.id = drep_distr.hash_id + WHERE drep_hash.view = 'drep_always_no_confidence' + ORDER BY epoch_no DESC LIMIT 1), 0) AS amount +) +SELECT + COALESCE(TotalStakeControlledByActiveDReps.total, 0) + COALESCE(AlwaysNoConfidenceVotingPower.amount, 0) AS total_stake_controlled_by_active_dreps, + COALESCE(TotalStakeControlledBySPOs.total, 0) AS total_stake_controlled_by_spos, + AlwaysAbstainVotingPower.amount AS always_abstain_voting_power, + AlwaysNoConfidenceVotingPower.amount AS always_no_confidence_voting_power +FROM TotalStakeControlledByActiveDReps +LEFT JOIN TotalStakeControlledBySPOs ON TRUE +LEFT JOIN AlwaysAbstainVotingPower ON TRUE +LEFT JOIN AlwaysNoConfidenceVotingPower ON TRUE \ No newline at end of file diff --git a/govtool/backend/src/VVA/API.hs b/govtool/backend/src/VVA/API.hs index 0e553cfaf..5bfbd304d 100644 --- a/govtool/backend/src/VVA/API.hs +++ b/govtool/backend/src/VVA/API.hs @@ -79,6 +79,9 @@ type VVAApi = :<|> "transaction" :> "status" :> Capture "transactionId" HexText :> Get '[JSON] GetTransactionStatusResponse :<|> "throw500" :> Get '[JSON] () :<|> "network" :> "metrics" :> Get '[JSON] GetNetworkMetricsResponse + :<|> "network" :> "info" :> Get '[JSON] GetNetworkInfoResponse + :<|> "network" :> "total-stake" :> Get '[JSON] GetNetworkTotalStakeResponse + server :: App m => ServerT VVAApi m server = drepList :<|> getVotingPower @@ -92,7 +95,8 @@ server = drepList :<|> getTransactionStatus :<|> throw500 :<|> getNetworkMetrics - + :<|> getNetworkInfo + :<|> getNetworkTotalStake mapDRepType :: Types.DRepType -> DRepType mapDRepType Types.DRep = NormalDRep @@ -428,29 +432,43 @@ getTransactionStatus (unHexText -> transactionId) = do throw500 :: App m => m () throw500 = throwError $ CriticalError "intentional system break for testing purposes" +getNetworkInfo :: App m => m GetNetworkInfoResponse +getNetworkInfo = do + CacheEnv {networkInfoCache} <- asks vvaCache + Types.NetworkInfo {..} <- Network.networkInfo + return $ GetNetworkInfoResponse + { getNetworkInfoResponseCurrentTime = networkInfoCurrentTime + , getNetworkInfoResponseEpochNo = networkInfoEpochNo + , getNetworkInfoResponseBlockNo = networkInfoBlockNo + , getNetworkInfoResponseNetworkName = networkInfoNetworkName + } + +getNetworkTotalStake :: App m => m GetNetworkTotalStakeResponse +getNetworkTotalStake = do + CacheEnv {networkTotalStakeCache} <- asks vvaCache + Types.NetworkTotalStake {..} <- Network.networkTotalStake + return $ GetNetworkTotalStakeResponse + { getNetworkTotalStakeResponseTotalStakeControlledByDReps = networkTotalStakeControlledByDReps + , getNetworkTotalStakeResponseTotalStakeControlledBySPOs = networkTotalStakeControlledBySPOs + , getNetworkTotalStakeResponseAlwaysAbstainVotingPower = networkTotalAlwaysAbstainVotingPower + , getNetworkTotalStakeResponseAlwaysNoConfidenceVotingPower = networkTotalAlwaysNoConfidenceVotingPower + } + getNetworkMetrics :: App m => m GetNetworkMetricsResponse getNetworkMetrics = do CacheEnv {networkMetricsCache} <- asks vvaCache Types.NetworkMetrics {..} <- Network.networkMetrics return $ GetNetworkMetricsResponse - { getNetworkMetricsResponseCurrentTime = networkMetricsCurrentTime - , getNetworkMetricsResponseCurrentEpoch = networkMetricsCurrentEpoch - , getNetworkMetricsResponseCurrentBlock = networkMetricsCurrentBlock - , getNetworkMetricsResponseUniqueDelegators = networkMetricsUniqueDelegators + { getNetworkMetricsResponseUniqueDelegators = networkMetricsUniqueDelegators , getNetworkMetricsResponseTotalDelegations = networkMetricsTotalDelegations , getNetworkMetricsResponseTotalGovernanceActions = networkMetricsTotalGovernanceActions , getNetworkMetricsResponseTotalDRepVotes = networkMetricsTotalDRepVotes , getNetworkMetricsResponseTotalRegisteredDReps = networkMetricsTotalRegisteredDReps , getNetworkMetricsResponseTotalDRepDistr = networkMetricsTotalDRepDistr - , getNetworkMetricsResponseTotalStakeControlledByDReps = networkMetricsTotalStakeControlledByDReps - , getNetworkMetricsResponseTotalStakeControlledBySPOs = networkMetricsTotalStakeControlledBySPOs , getNetworkMetricsResponseTotalActiveDReps = networkMetricsTotalActiveDReps , getNetworkMetricsResponseTotalInactiveDReps = networkMetricsTotalInactiveDReps , getNetworkMetricsResponseTotalActiveCIP119CompliantDReps = networkMetricsTotalActiveCIP119CompliantDReps , getNetworkMetricsResponseTotalRegisteredDirectVoters = networkMetricsTotalRegisteredDirectVoters - , getNetworkMetricsResponseAlwaysAbstainVotingPower = networkMetricsAlwaysAbstainVotingPower - , getNetworkMetricsResponseAlwaysNoConfidenceVotingPower = networkMetricsAlwaysNoConfidenceVotingPower - , getNetworkMetricsResponseNetworkName = networkMetricsNetworkName , getNetworkMetricsResponseNoOfCommitteeMembers = networkMetricsNoOfCommitteeMembers , getNetworkMetricsResponseQuorumNumerator = networkMetricsQuorumNumerator , getNetworkMetricsResponseQuorumDenominator = networkMetricsQuorumDenominator diff --git a/govtool/backend/src/VVA/API/Types.hs b/govtool/backend/src/VVA/API/Types.hs index 461ca5dfe..ec95925e9 100644 --- a/govtool/backend/src/VVA/API/Types.hs +++ b/govtool/backend/src/VVA/API/Types.hs @@ -874,26 +874,66 @@ instance ToSchema DelegationResponse where & example ?~ toJSON exampleDelegationResponse +data GetNetworkInfoResponse + = GetNetworkInfoResponse + { getNetworkInfoResponseCurrentTime :: UTCTime + , getNetworkInfoResponseEpochNo :: Integer + , getNetworkInfoResponseBlockNo :: Integer + , getNetworkInfoResponseNetworkName :: Text + } + +deriveJSON (jsonOptions "getNetworkInfoResponse") ''GetNetworkInfoResponse + +exampleGetNetworkInfoResponse :: Text +exampleGetNetworkInfoResponse = + "{\"currentTime\": \"1970-01-01T00:00:00Z\"," + <> "\"currentEpoch\": 0," + <> "\"currentBlock\": 0," + <> "\"networkName\": \"Mainnet\"}" + +instance ToSchema GetNetworkInfoResponse where + declareNamedSchema _ = pure $ NamedSchema (Just "GetNetworkInfoResponse") $ mempty + & type_ ?~ OpenApiObject + & description ?~ "GetNetworkInfoResponse" + & example + ?~ toJSON exampleGetNetworkInfoResponse + +data GetNetworkTotalStakeResponse + = GetNetworkTotalStakeResponse + { getNetworkTotalStakeResponseTotalStakeControlledByDReps :: Integer + , getNetworkTotalStakeResponseTotalStakeControlledBySPOs :: Integer + , getNetworkTotalStakeResponseAlwaysAbstainVotingPower :: Integer + , getNetworkTotalStakeResponseAlwaysNoConfidenceVotingPower :: Integer + } + +deriveJSON (jsonOptions "getNetworkTotalStakeResponse") ''GetNetworkTotalStakeResponse + +exampleGetNetworkTotalStakeResponse :: Text +exampleGetNetworkTotalStakeResponse = + "{\"totalStakeControlledByDReps\": 0," + <> "\"totalStakeControlledBySPOs\": 0," + <> "\"alwaysAbstainVotingPower\": 0," + <> "\"alwaysNoConfidenceVotingPower\": 0}" + +instance ToSchema GetNetworkTotalStakeResponse where + declareNamedSchema _ = pure $ NamedSchema (Just "GetNetworkTotalStakeResponse") $ mempty + & type_ ?~ OpenApiObject + & description ?~ "GetNetworkTotalStakeResponse" + & example + ?~ toJSON exampleGetNetworkTotalStakeResponse + data GetNetworkMetricsResponse = GetNetworkMetricsResponse - { getNetworkMetricsResponseCurrentTime :: UTCTime - , getNetworkMetricsResponseCurrentEpoch :: Integer - , getNetworkMetricsResponseCurrentBlock :: Integer - , getNetworkMetricsResponseUniqueDelegators :: Integer + { getNetworkMetricsResponseUniqueDelegators :: Integer , getNetworkMetricsResponseTotalDelegations :: Integer , getNetworkMetricsResponseTotalGovernanceActions :: Integer , getNetworkMetricsResponseTotalDRepVotes :: Integer , getNetworkMetricsResponseTotalRegisteredDReps :: Integer , getNetworkMetricsResponseTotalDRepDistr :: Integer - , getNetworkMetricsResponseTotalStakeControlledByDReps :: Integer - , getNetworkMetricsResponseTotalStakeControlledBySPOs :: Integer , getNetworkMetricsResponseTotalActiveDReps :: Integer , getNetworkMetricsResponseTotalInactiveDReps :: Integer , getNetworkMetricsResponseTotalActiveCIP119CompliantDReps :: Integer , getNetworkMetricsResponseTotalRegisteredDirectVoters :: Integer - , getNetworkMetricsResponseAlwaysAbstainVotingPower :: Integer - , getNetworkMetricsResponseAlwaysNoConfidenceVotingPower :: Integer - , getNetworkMetricsResponseNetworkName :: Text , getNetworkMetricsResponseNoOfCommitteeMembers :: Integer , getNetworkMetricsResponseQuorumNumerator :: Integer , getNetworkMetricsResponseQuorumDenominator :: Integer @@ -912,14 +952,10 @@ exampleGetNetworkMetricsResponse = <> "\"totalDRepVotes\": 0," <> "\"totalRegisteredDReps\": 0," <> "\"totalDRepDistr\": 0," - <> "\"totalStakeControlledByDReps\": 0," - <> "\"totalStakeControlledBySPOs\": 0," <> "\"totalActiveDReps\": 0," <> "\"totalInactiveDReps\": 0," <> "\"totalActiveCIP119CompliantDReps\": 0," <> "\"totalRegisteredDirectVoters\": 0," - <> "\"alwaysAbstainVotingPower\": 0," - <> "\"alwaysNoConfidenceVotingPower\": 0," <> "\"networkName\": \"Mainnet\"," <> "\"noOfCommitteeMembers\": 7," <> "\"quorumNumerator\": 2," diff --git a/govtool/backend/src/VVA/Network.hs b/govtool/backend/src/VVA/Network.hs index 550c354c2..797d47ac3 100644 --- a/govtool/backend/src/VVA/Network.hs +++ b/govtool/backend/src/VVA/Network.hs @@ -25,6 +25,46 @@ import VVA.Types sqlFrom :: ByteString -> SQL.Query sqlFrom bs = fromString $ unpack $ Text.decodeUtf8 bs +networkInfoSql :: SQL.Query +networkInfoSql = sqlFrom $(embedFile "sql/get-network-info.sql") + +networkInfo :: + (Has ConnectionPool r, Has VVAConfig r, MonadReader r m, MonadIO m, MonadError AppError m) => + m NetworkInfo +networkInfo = withPool $ \conn -> do + result <- liftIO $ SQL.query_ conn networkInfoSql + current_time <- liftIO getCurrentTime + case result of + [( network_epoch + , network_block_no + , network_name + )] -> return $ NetworkInfo + current_time + network_epoch + network_block_no + network_name + _ -> throwError $ CriticalError "Could not query the network info. This should never happen." + +networkTotalStakeSql :: SQL.Query +networkTotalStakeSql = sqlFrom $(embedFile "sql/get-network-total-stake.sql") + +networkTotalStake :: + (Has ConnectionPool r, Has VVAConfig r, MonadReader r m, MonadIO m, MonadError AppError m) => + m NetworkTotalStake +networkTotalStake = withPool $ \conn -> do + result <- liftIO $ SQL.query_ conn networkTotalStakeSql + case result of + [( total_stake_controlled_by_dreps + , total_stake_controlled_by_spos + , always_abstain_voting_power + , always_no_confidence_voting_power + )] -> return $ NetworkTotalStake + total_stake_controlled_by_dreps + total_stake_controlled_by_spos + always_abstain_voting_power + always_no_confidence_voting_power + _ -> throwError $ CriticalError "Could not query the network total stake. This should never happen." + networkMetricsSql :: SQL.Query networkMetricsSql = sqlFrom $(embedFile "sql/get-network-metrics.sql") @@ -33,47 +73,31 @@ networkMetrics :: m NetworkMetrics networkMetrics = withPool $ \conn -> do result <- liftIO $ SQL.query_ conn networkMetricsSql - current_time <- liftIO getCurrentTime case result of - [( epoch_no - , block_no - , unique_delegators + [( unique_delegators , total_delegations , total_gov_action_proposals , total_drep_votes , total_registered_dreps , total_drep_distr - , total_stake_controlled_by_dreps - , total_stake_controlled_by_spos , total_active_dreps , total_inactive_dreps , total_active_cip119_compliant_dreps , total_registered_direct_voters - , always_abstain_voting_power - , always_no_confidence_voting_power - , network_name , no_of_committee_members , quorum_numerator , quorum_denominator )] -> return $ NetworkMetrics - current_time - epoch_no - block_no unique_delegators total_delegations total_gov_action_proposals total_drep_votes total_registered_dreps total_drep_distr - total_stake_controlled_by_dreps - total_stake_controlled_by_spos total_active_dreps total_inactive_dreps total_active_cip119_compliant_dreps total_registered_direct_voters - always_abstain_voting_power - always_no_confidence_voting_power - network_name no_of_committee_members quorum_numerator quorum_denominator diff --git a/govtool/backend/src/VVA/Types.hs b/govtool/backend/src/VVA/Types.hs index 0e69988d6..5d1f3ca5f 100644 --- a/govtool/backend/src/VVA/Types.hs +++ b/govtool/backend/src/VVA/Types.hs @@ -203,38 +203,48 @@ instance ToJSON TransactionStatus where data CacheEnv = CacheEnv - { proposalListCache :: Cache.Cache () [Proposal] - , getProposalCache :: Cache.Cache (Text, Integer) Proposal - , currentEpochCache :: Cache.Cache () (Maybe Value) - , adaHolderVotingPowerCache :: Cache.Cache Text Integer - , adaHolderGetCurrentDelegationCache :: Cache.Cache Text (Maybe Delegation) - , dRepGetVotesCache :: Cache.Cache Text ([Vote], [Proposal]) - , dRepInfoCache :: Cache.Cache Text DRepInfo - , dRepVotingPowerCache :: Cache.Cache Text Integer - , dRepListCache :: Cache.Cache Text [DRepRegistration] - , networkMetricsCache :: Cache.Cache () NetworkMetrics + { proposalListCache :: Cache.Cache () [Proposal] + , getProposalCache :: Cache.Cache (Text, Integer) Proposal + , currentEpochCache :: Cache.Cache () (Maybe Value) + , adaHolderVotingPowerCache :: Cache.Cache Text Integer + , adaHolderGetCurrentDelegationCache :: Cache.Cache Text (Maybe Delegation) + , dRepGetVotesCache :: Cache.Cache Text ([Vote], [Proposal]) + , dRepInfoCache :: Cache.Cache Text DRepInfo + , dRepVotingPowerCache :: Cache.Cache Text Integer + , dRepListCache :: Cache.Cache Text [DRepRegistration] + , networkMetricsCache :: Cache.Cache () NetworkMetrics + , networkInfoCache :: Cache.Cache () NetworkInfo + , networkTotalStakeCache :: Cache.Cache () NetworkTotalStake + } + +data NetworkInfo + = NetworkInfo + { networkInfoCurrentTime :: UTCTime + , networkInfoEpochNo :: Integer + , networkInfoBlockNo :: Integer + , networkInfoNetworkName :: Text + } + +data NetworkTotalStake + = NetworkTotalStake + { networkTotalStakeControlledByDReps :: Integer + , networkTotalStakeControlledBySPOs :: Integer + , networkTotalAlwaysAbstainVotingPower :: Integer + , networkTotalAlwaysNoConfidenceVotingPower :: Integer } data NetworkMetrics = NetworkMetrics - { networkMetricsCurrentTime :: UTCTime - , networkMetricsCurrentEpoch :: Integer - , networkMetricsCurrentBlock :: Integer - , networkMetricsUniqueDelegators :: Integer + { networkMetricsUniqueDelegators :: Integer , networkMetricsTotalDelegations :: Integer , networkMetricsTotalGovernanceActions :: Integer , networkMetricsTotalDRepVotes :: Integer , networkMetricsTotalRegisteredDReps :: Integer , networkMetricsTotalDRepDistr :: Integer - , networkMetricsTotalStakeControlledByDReps :: Integer - , networkMetricsTotalStakeControlledBySPOs :: Integer , networkMetricsTotalActiveDReps :: Integer , networkMetricsTotalInactiveDReps :: Integer , networkMetricsTotalActiveCIP119CompliantDReps :: Integer , networkMetricsTotalRegisteredDirectVoters :: Integer - , networkMetricsAlwaysAbstainVotingPower :: Integer - , networkMetricsAlwaysNoConfidenceVotingPower :: Integer - , networkMetricsNetworkName :: Text , networkMetricsNoOfCommitteeMembers :: Integer , networkMetricsQuorumNumerator :: Integer , networkMetricsQuorumDenominator :: Integer diff --git a/govtool/backend/vva-be.cabal b/govtool/backend/vva-be.cabal index a3e807dc6..3ad2bd4e5 100644 --- a/govtool/backend/vva-be.cabal +++ b/govtool/backend/vva-be.cabal @@ -32,6 +32,8 @@ extra-source-files: sql/get-transaction-status.sql sql/get-stake-key-voting-power.sql sql/get-network-metrics.sql + sql/get-network-info.sql + sql/get-network-total-stake.sql executable vva-be main-is: Main.hs diff --git a/govtool/frontend/src/components/molecules/VotesSubmitted.tsx b/govtool/frontend/src/components/molecules/VotesSubmitted.tsx index c04f5aa60..87f3ab8a0 100644 --- a/govtool/frontend/src/components/molecules/VotesSubmitted.tsx +++ b/govtool/frontend/src/components/molecules/VotesSubmitted.tsx @@ -1,9 +1,13 @@ -import { useCallback } from "react"; +import { useCallback, useEffect } from "react"; import { Box } from "@mui/material"; import { IMAGES, SECURITY_RELEVANT_PARAMS_MAP } from "@consts"; import { Typography, VotePill } from "@atoms"; -import { useTranslation } from "@hooks"; +import { + useGetNetworkMetrics, + useGetNetworkTotalStake, + useTranslation, +} from "@hooks"; import { getGovActionVotingThresholdKey, correctAdaFormatWithSuffix, @@ -48,7 +52,18 @@ export const VotesSubmitted = ({ areCCVoteTotalsDisplayed, } = useFeatureFlag(); const { t } = useTranslation(); - const { epochParams, networkMetrics } = useAppContext(); + const { networkTotalStake, fetchNetworkTotalStake } = + useGetNetworkTotalStake(); + const { networkMetrics, fetchNetworkMetrics } = useGetNetworkMetrics(); + const { epochParams } = useAppContext(); + + useEffect(() => { + const init = async () => { + await fetchNetworkTotalStake(); + await fetchNetworkMetrics(); + }; + init(); + }, []); const noOfCommitteeMembers = networkMetrics?.noOfCommitteeMembers ?? 0; const ccThreshold = ( @@ -60,13 +75,13 @@ export const VotesSubmitted = ({ // Coming from be // Equal to: total active drep stake + auto no-confidence stake const totalStakeControlledByDReps = - (networkMetrics?.totalStakeControlledByDReps ?? 0) - + (networkTotalStake?.totalStakeControlledByDReps ?? 0) - // As this being voted for the action becomes part of the total active stake dRepAbstainVotes; // Governance action abstain votesa + auto abstain votes const totalAbstainVotes = - dRepAbstainVotes + (networkMetrics?.alwaysAbstainVotingPower ?? 0); + dRepAbstainVotes + (networkTotalStake?.alwaysAbstainVotingPower ?? 0); // TODO: Move this logic to backend const dRepYesVotesPercentage = totalStakeControlledByDReps @@ -82,13 +97,13 @@ export const VotesSubmitted = ({ (dRepYesVotes - // As this is already added on backend (govActionType === GovernanceActionType.NoConfidence - ? networkMetrics?.alwaysNoConfidenceVotingPower ?? 0 + ? networkTotalStake?.alwaysNoConfidenceVotingPower ?? 0 : 0)) - (dRepNoVotes - // As this is already added on backend (govActionType === GovernanceActionType.NoConfidence ? 0 - : networkMetrics?.alwaysNoConfidenceVotingPower ?? 0)) + : networkTotalStake?.alwaysNoConfidenceVotingPower ?? 0)) : undefined; const dRepNotVotedVotesPercentage = 100 - (dRepYesVotesPercentage ?? 0) - (dRepNoVotesPercentage ?? 0); diff --git a/govtool/frontend/src/components/organisms/AutomatedVotingOptions.tsx b/govtool/frontend/src/components/organisms/AutomatedVotingOptions.tsx index 411d8d2d3..bbcf7d5ca 100644 --- a/govtool/frontend/src/components/organisms/AutomatedVotingOptions.tsx +++ b/govtool/frontend/src/components/organisms/AutomatedVotingOptions.tsx @@ -9,7 +9,7 @@ import { import { Typography } from "@atoms"; import { ICONS } from "@consts"; import { PendingTransaction } from "@context"; -import { useGetNetworkMetrics, useTranslation } from "@hooks"; +import { useGetNetworkTotalStake, useTranslation } from "@hooks"; import { AutomatedVotingCard } from "@molecules"; import { correctDRepDirectoryFormat, openInNewTab } from "@/utils"; import { @@ -40,8 +40,8 @@ export const AutomatedVotingOptions = ({ txHash, }: AutomatedVotingOptionsProps) => { const { t } = useTranslation(); - // TODO: Get network metrics from useAppContext - const { networkMetrics, fetchNetworkMetrics } = useGetNetworkMetrics(); + const { networkTotalStake, fetchNetworkTotalStake } = + useGetNetworkTotalStake(); const [isOpen, setIsOpen] = useState(false); @@ -57,7 +57,7 @@ export const AutomatedVotingOptions = ({ delegationInProgress === AutomatedVotingOptionDelegationId.no_confidence; useEffect(() => { - fetchNetworkMetrics(); + fetchNetworkTotalStake(); }, []); useEffect(() => { @@ -128,9 +128,9 @@ export const AutomatedVotingOptions = ({ : t("dRepDirectory.abstainCardDefaultTitle") } votingPower={ - networkMetrics + networkTotalStake ? correctDRepDirectoryFormat( - networkMetrics?.alwaysAbstainVotingPower, + networkTotalStake?.alwaysAbstainVotingPower, ) : "" } @@ -171,9 +171,9 @@ export const AutomatedVotingOptions = ({ : t("dRepDirectory.noConfidenceDefaultTitle") } votingPower={ - networkMetrics + networkTotalStake ? correctDRepDirectoryFormat( - networkMetrics?.alwaysNoConfidenceVotingPower, + networkTotalStake?.alwaysNoConfidenceVotingPower, ) : "" } diff --git a/govtool/frontend/src/consts/queryKeys.ts b/govtool/frontend/src/consts/queryKeys.ts index c6cfa2cec..825b5f316 100644 --- a/govtool/frontend/src/consts/queryKeys.ts +++ b/govtool/frontend/src/consts/queryKeys.ts @@ -7,6 +7,8 @@ export const QUERY_KEYS = { useGetDRepVotingPowerKey: "useGetDRepVotingPowerKey", useGetEpochParamsKey: "useGetEpochParamsKey", useGetNetworkMetricsKey: "useGetNetworkMetricsKey", + useGetNetworkTotalStakeKey: "useGetNetworkTotalStakeKey", + useGetNetworkInfoKey: "useGetNetworkInfoKey", useGetProposalKey: "useGetProposalKey", useGetProposalsInfiniteKey: "useGetProposalsInfiniteKey", useGetProposalsKey: "useGetProposalsKey", diff --git a/govtool/frontend/src/context/appContext.tsx b/govtool/frontend/src/context/appContext.tsx index 14c18c9ea..dff1684f1 100644 --- a/govtool/frontend/src/context/appContext.tsx +++ b/govtool/frontend/src/context/appContext.tsx @@ -9,13 +9,13 @@ import { import * as Sentry from "@sentry/react"; import { NETWORK_NAMES, CEXPLORER_BASE_URLS } from "@/consts"; -import { useGetNetworkMetrics, useGetEpochParams } from "@/hooks"; +import { useGetEpochParams, useGetNetworkInfo } from "@/hooks"; import { - NETWORK_METRICS_KEY, + NETWORK_INFO_KEY, PROTOCOL_PARAMS_KEY, setItemToLocalStorage, } from "@/utils"; -import { EpochParams, NetworkMetrics, Network } from "@/models"; +import { EpochParams, Network } from "@/models"; import { adaHandleService } from "@/services/AdaHandle"; const BOOTSTRAPPING_PHASE_MAJOR = 9; @@ -29,7 +29,6 @@ type AppContextType = { network: Network; cExplorerBaseUrl: string; epochParams?: EpochParams; - networkMetrics?: NetworkMetrics; }; const AppContext = createContext(null); @@ -44,7 +43,7 @@ const AppContextProvider = ({ children }: PropsWithChildren) => { Sentry.setTag("component_name", "AppContextProvider"); }, []); const { fetchEpochParams, epochParams } = useGetEpochParams(); - const { fetchNetworkMetrics, networkMetrics } = useGetNetworkMetrics(); + const { fetchNetworkInfo, networkInfo } = useGetNetworkInfo(); const [isAppInitializing, setIsAppInitializing] = useState(true); @@ -56,12 +55,12 @@ const AppContextProvider = ({ children }: PropsWithChildren) => { setItemToLocalStorage(PROTOCOL_PARAMS_KEY, epochParamsData); } - const { data: networkMetricsData } = await fetchNetworkMetrics(); - if (networkMetricsData) { - setItemToLocalStorage(NETWORK_METRICS_KEY, networkMetricsData); + const { data: networkInfoData } = await fetchNetworkInfo(); + if (networkInfoData) { + setItemToLocalStorage(NETWORK_INFO_KEY, networkInfoData); // Initialize ada handle service - adaHandleService.initialize(networkMetricsData.networkName); + adaHandleService.initialize(networkInfoData?.networkName); } setIsAppInitializing(false); @@ -76,23 +75,20 @@ const AppContextProvider = ({ children }: PropsWithChildren) => { const value = useMemo( () => ({ isAppInitializing, - isMainnet: networkMetrics?.networkName === "mainnet", + isMainnet: networkInfo?.networkName === "mainnet", isInBootstrapPhase: epochParams?.protocol_major === BOOTSTRAPPING_PHASE_MAJOR, isFullGovernance: Number(epochParams?.protocol_major) >= 10, networkName: NETWORK_NAMES[ - (networkMetrics?.networkName as keyof typeof NETWORK_NAMES) || - "preview" + (networkInfo?.networkName as keyof typeof NETWORK_NAMES) || "preview" ], - network: networkMetrics?.networkName ?? Network.preview, + network: networkInfo?.networkName ?? Network.preview, cExplorerBaseUrl: CEXPLORER_BASE_URLS[ - (networkMetrics?.networkName as keyof typeof NETWORK_NAMES) || - "preview" + (networkInfo?.networkName as keyof typeof NETWORK_NAMES) || "preview" ], epochParams, - networkMetrics, }), [isAppInitializing], ); diff --git a/govtool/frontend/src/hooks/queries/index.ts b/govtool/frontend/src/hooks/queries/index.ts index aa02b7321..db72778d2 100644 --- a/govtool/frontend/src/hooks/queries/index.ts +++ b/govtool/frontend/src/hooks/queries/index.ts @@ -1,11 +1,13 @@ export * from "./useGetAdaHolderCurrentDelegationQuery"; export * from "./useGetAdaHolderVotingPowerQuery"; -export * from "./useGetDrepDetailsQuery"; export * from "./useGetDRepListQuery"; export * from "./useGetDRepVotesQuery"; export * from "./useGetDRepVotingPowerQuery"; +export * from "./useGetDrepDetailsQuery"; export * from "./useGetEpochParams"; +export * from "./useGetNetworkInfo"; export * from "./useGetNetworkMetrics"; +export * from "./useGetNetworkTotalStake"; export * from "./useGetProposalQuery"; export * from "./useGetProposalsInfiniteQuery"; export * from "./useGetProposalsQuery"; diff --git a/govtool/frontend/src/hooks/queries/useGetNetworkInfo.ts b/govtool/frontend/src/hooks/queries/useGetNetworkInfo.ts new file mode 100644 index 000000000..b0e0d940a --- /dev/null +++ b/govtool/frontend/src/hooks/queries/useGetNetworkInfo.ts @@ -0,0 +1,14 @@ +import { useQuery } from "react-query"; + +import { getNetworkInfo } from "@services"; +import { QUERY_KEYS } from "@consts"; + +export const useGetNetworkInfo = () => { + const { data: networkInfo, refetch: fetchNetworkInfo } = useQuery({ + queryKey: QUERY_KEYS.useGetNetworkInfoKey, + queryFn: () => getNetworkInfo(), + enabled: false, + }); + + return { networkInfo, fetchNetworkInfo }; +}; diff --git a/govtool/frontend/src/hooks/queries/useGetNetworkTotalStake.ts b/govtool/frontend/src/hooks/queries/useGetNetworkTotalStake.ts new file mode 100644 index 000000000..c6b3df59e --- /dev/null +++ b/govtool/frontend/src/hooks/queries/useGetNetworkTotalStake.ts @@ -0,0 +1,16 @@ +import { useQuery } from "react-query"; + +import { getNetworkTotalStake } from "@services"; +import { QUERY_KEYS } from "@consts"; + +export const useGetNetworkTotalStake = () => { + const { data: networkTotalStake, refetch: fetchNetworkTotalStake } = useQuery( + { + queryKey: QUERY_KEYS.useGetNetworkTotalStakeKey, + queryFn: () => getNetworkTotalStake(), + enabled: false, + }, + ); + + return { networkTotalStake, fetchNetworkTotalStake }; +}; diff --git a/govtool/frontend/src/models/api.ts b/govtool/frontend/src/models/api.ts index 32f710f41..60890fd6d 100644 --- a/govtool/frontend/src/models/api.ts +++ b/govtool/frontend/src/models/api.ts @@ -86,25 +86,31 @@ export enum Network { mainnet = "mainnet", } -export type NetworkMetrics = { +export type NetworkInfo = { currentTime: string; currentEpoch: number; currentBlock: number; + networkName: Network; +}; + +export type NetworkTotalStake = { + totalStakeControlledByDReps: number; + totalStakeControlledBySPOs: number; + alwaysAbstainVotingPower: number; + alwaysNoConfidenceVotingPower: number; +}; + +export type NetworkMetrics = { uniqueDelegators: number; totalDelegations: number; totalGovernanceActions: number; totalDRepVotes: number; totalRegisteredDReps: number; totalDRepDistr: number; - totalStakeControlledByDReps: number; - totalStakeControlledBySPOs: number; totalActiveDReps: number; totalInactiveDReps: number; totalActiveCIP119CompliantDReps: number; totalRegisteredDirectVoters: number; - alwaysAbstainVotingPower: number; - alwaysNoConfidenceVotingPower: number; - networkName: Network; noOfCommitteeMembers: number; quorumNumerator: number; quorumDenominator: number; diff --git a/govtool/frontend/src/services/AdaHandle.ts b/govtool/frontend/src/services/AdaHandle.ts index a130ad1aa..9a4f93874 100644 --- a/govtool/frontend/src/services/AdaHandle.ts +++ b/govtool/frontend/src/services/AdaHandle.ts @@ -1,4 +1,4 @@ -import { NetworkMetrics } from "@/models"; +import { NetworkInfo } from "@/models"; import { HandleObject } from "@/models/adaHandle"; export const ADAHANDLE_BASE_URL = { @@ -38,7 +38,7 @@ class AdaHandleService { * Initialize the AdaHandleService with the base URL for a specific network. * @param network - The name of the network. */ - initialize(network: NetworkMetrics["networkName"]): void { + initialize(network: NetworkInfo["networkName"]): void { if (this.adaHandleBaseUrl !== ADAHANDLE_BASE_URL[network]) { this.adaHandleBaseUrl = ADAHANDLE_BASE_URL[network]; } diff --git a/govtool/frontend/src/services/requests/getNetworkInfo.ts b/govtool/frontend/src/services/requests/getNetworkInfo.ts new file mode 100644 index 000000000..2ec061d11 --- /dev/null +++ b/govtool/frontend/src/services/requests/getNetworkInfo.ts @@ -0,0 +1,8 @@ +import { NetworkInfo } from "@/models"; +import { API } from "../API"; + +export const getNetworkInfo = async () => { + const response = await API.get("/network/info"); + + return response.data; +}; diff --git a/govtool/frontend/src/services/requests/getNetworkTotalStake.ts b/govtool/frontend/src/services/requests/getNetworkTotalStake.ts new file mode 100644 index 000000000..ed1899d5d --- /dev/null +++ b/govtool/frontend/src/services/requests/getNetworkTotalStake.ts @@ -0,0 +1,8 @@ +import { NetworkTotalStake } from "@models"; +import { API } from "../API"; + +export const getNetworkTotalStake = async () => { + const response = await API.get("/network/total-stake"); + + return response.data; +}; diff --git a/govtool/frontend/src/services/requests/index.ts b/govtool/frontend/src/services/requests/index.ts index f6721175a..20047744c 100644 --- a/govtool/frontend/src/services/requests/index.ts +++ b/govtool/frontend/src/services/requests/index.ts @@ -1,14 +1,18 @@ export * from "./getAdaHolderCurrentDelegation"; export * from "./getAdaHolderVotingPower"; -export * from "./getVoterInfo"; export * from "./getDRepList"; export * from "./getDRepVotes"; export * from "./getDRepVotingPower"; export * from "./getEpochParams"; +export * from "./getNetworkInfo"; +export * from "./getNetworkMetrics"; +export * from "./getNetworkTotalStake"; export * from "./getProposal"; export * from "./getProposals"; export * from "./getTransactionStatus"; export * from "./getVoteContextTextFromFile"; +export * from "./getVoterInfo"; +export * from "./metadataValidation"; export * from "./postAdaHolderDelegate"; export * from "./postAdaHolderDelegateAbstain"; export * from "./postAdaHolderDelegateNo"; @@ -17,5 +21,3 @@ export * from "./postDRepRegister"; export * from "./postDRepRemoveVote"; export * from "./postDRepRetire"; export * from "./postDRepVote"; -export * from "./metadataValidation"; -export * from "./getNetworkMetrics"; diff --git a/govtool/frontend/src/utils/localStorage.ts b/govtool/frontend/src/utils/localStorage.ts index 692a857b5..0bc866244 100644 --- a/govtool/frontend/src/utils/localStorage.ts +++ b/govtool/frontend/src/utils/localStorage.ts @@ -2,6 +2,8 @@ export const PENDING_TRANSACTION_KEY = "pending_transaction"; export const PROTOCOL_PARAMS_KEY = "protocol_params"; export const NETWORK_METRICS_KEY = "network_metrics"; export const NETWORK_INFO_KEY = "network_info"; +export const NETWORK_TOTAL_STAKE_KEY = "network_total_stake"; + export const WALLET_LS_KEY = "wallet_data"; export function getItemFromLocalStorage(key: string) {