diff --git a/CHANGELOG.md b/CHANGELOG.md index dfef59af1..b938bc1db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features +- [#762](https://github.com/alleslabs/celatone-frontend/pull/762) api v1 - proposal validator votes info - [#745](https://github.com/alleslabs/celatone-frontend/pull/745) Add proposal top - [#758](https://github.com/alleslabs/celatone-frontend/pull/758) api v1 - proposal validator votes - [#757](https://github.com/alleslabs/celatone-frontend/pull/757) api v1 - proposal data diff --git a/src/lib/app-provider/env.ts b/src/lib/app-provider/env.ts index 37ca09c71..d4ac54653 100644 --- a/src/lib/app-provider/env.ts +++ b/src/lib/app-provider/env.ts @@ -52,6 +52,7 @@ export enum CELATONE_QUERY_KEYS { FAUCET_INFO = "CELATONE_QUERY_FAUCET_INFO", // X/GOV PROPOSAL_DATA = "CELATONE_QUERY_PROPOSAL_DATA", + PROPOSAL_VALIDATOR_VOTES_INFO = "CELATONE_QUERY_PROPOSAL_VALIDATOR_VOTES_INFO", PROPOSAL_VALIDATOR_VOTES = "CELATONE_QUERY_PROPOSAL_VALIDATOR_VOTES", RELATED_PROPOSALS_BY_CONTRACT_ADDRESS = "CELATONE_QUERY_RELATED_PROPOSALS_BY_CONTRACT_ADDRESS", PROPOSALS_BY_MODULE_ID = "CELATONE_QUERY_PROPOSALS_BY_MODULE_ID", diff --git a/src/lib/services/proposal.ts b/src/lib/services/proposal.ts index 442ab94dc..8bf099a2f 100644 --- a/src/lib/services/proposal.ts +++ b/src/lib/services/proposal.ts @@ -1,5 +1,6 @@ import type { Coin } from "@cosmjs/stargate"; import axios from "axios"; +import big from "big.js"; import { z } from "zod"; import { @@ -211,6 +212,33 @@ export const getProposalData = async ( .get(`${endpoint}/${encodeURIComponent(id)}/info`) .then(({ data }) => zProposalDataResponse.parse(data)); +const zProposalVotesInfoResponse = z + .object({ + yes: z.string(), + abstain: z.string(), + no: z.string(), + no_with_veto: z.string(), + total_voting_power: z.string(), + }) + .transform((val) => ({ + yes: big(val.yes), + abstain: big(val.abstain), + no: big(val.no), + noWithVeto: big(val.no_with_veto), + totalVotingPower: big(val.total_voting_power), + })); +export type ProposalVotesInfoResponse = z.infer< + typeof zProposalVotesInfoResponse +>; + +export const getProposalVotesInfo = async ( + endpoint: string, + id: number +): Promise => + axios + .get(`${endpoint}/${encodeURIComponent(id)}/votes-info`) + .then(({ data }) => zProposalVotesInfoResponse.parse(data)); + const zProposalVotesResponseItem = z .object({ proposal_id: z.number().nonnegative(), @@ -230,7 +258,6 @@ const zProposalVotesResponse = z.object({ items: z.array(zProposalVotesResponseItem), total: z.number().nonnegative(), }); - export type ProposalVotesResponse = z.infer; export const getProposalValidatorVotes = async ( diff --git a/src/lib/services/proposalService.ts b/src/lib/services/proposalService.ts index 65b4523a1..ef9482751 100644 --- a/src/lib/services/proposalService.ts +++ b/src/lib/services/proposalService.ts @@ -44,6 +44,7 @@ import type { RelatedProposalsResponse, UploadAccess, VotingParamsInternal, + ProposalVotesInfoResponse, } from "./proposal"; import { fetchGovVotingParams, @@ -55,6 +56,7 @@ import { getProposalTypes, getProposalData, getProposalValidatorVotes, + getProposalVotesInfo, } from "./proposal"; export const useProposals = ( @@ -226,16 +228,6 @@ export const useRelatedProposalsCountByModuleId = ( ); }; -export const useProposalData = (id: number) => { - const endpoint = useBaseApiRoute("proposals"); - - return useQuery( - [CELATONE_QUERY_KEYS.PROPOSAL_DATA, endpoint, id], - async () => getProposalData(endpoint, id), - { retry: 1, keepPreviousData: true } - ); -}; - export interface MinDeposit { amount: U>; denom: string; @@ -326,12 +318,30 @@ export const useUploadAccessParams = (): UseQueryResult => { ); }; -export const useProposalValidatorVotes = ( - id: number -): UseQueryResult => { +export const useProposalData = (id: number) => { const endpoint = useBaseApiRoute("proposals"); - return useQuery( + return useQuery( + [CELATONE_QUERY_KEYS.PROPOSAL_DATA, endpoint, id], + async () => getProposalData(endpoint, id), + { retry: 1, keepPreviousData: true } + ); +}; + +export const useProposalVotesInfo = (id: number) => { + const endpoint = useBaseApiRoute("proposals"); + + return useQuery( + [CELATONE_QUERY_KEYS.PROPOSAL_VALIDATOR_VOTES, endpoint, id], + async () => getProposalVotesInfo(endpoint, id), + { retry: 1, refetchOnWindowFocus: false } + ); +}; + +export const useProposalValidatorVotes = (id: number) => { + const endpoint = useBaseApiRoute("proposals"); + + return useQuery( [CELATONE_QUERY_KEYS.PROPOSAL_VALIDATOR_VOTES, endpoint, id], async () => getProposalValidatorVotes(endpoint, id), { retry: 1, refetchOnWindowFocus: false }