diff --git a/frontend/src/store/features/gov/govService.ts b/frontend/src/store/features/gov/govService.ts
new file mode 100644
index 000000000..abf6c4bd1
--- /dev/null
+++ b/frontend/src/store/features/gov/govService.ts
@@ -0,0 +1,72 @@
+import Axios, { AxiosResponse } from 'axios';
+import { convertPaginationToParams, cleanURL } from '../../../utils/util';
+
+const proposalsURL = '/cosmos/gov/v1beta1/proposals';
+const proposalTallyURL = (id: string): string =>
+  `/cosmos/gov/v1beta1/proposals/${id}/tally`;
+
+const voterVoteURL = (id: string, voter: string): string =>
+  `/cosmos/gov/v1beta1/proposals/${id}/votes/${voter}`;
+
+const depositParamsURL = `/cosmos/gov/v1beta1/params/deposit`;
+
+const fetchProposals = (
+  baseURL: string,
+  key: string | undefined,
+  limit: number | undefined,
+  status: number
+): Promise<AxiosResponse<GetProposalsInVotingResponse>> => {
+  let uri = `${cleanURL(baseURL)}${proposalsURL}`;
+  uri += `?proposal_status=${status}`;
+
+  const params = convertPaginationToParams({
+    key: key,
+    limit: limit,
+  });
+
+  if (params !== '') uri += `&${params}`;
+  return Axios.get(uri);
+};
+
+const fetchProposalTally = (
+  baseURL: string,
+  proposalId: string
+): Promise<AxiosResponse> => {
+  let uri = `${cleanURL(baseURL)}${proposalTallyURL(proposalId)}`;
+  return Axios.get(uri);
+};
+
+const fetchVoterVote = (
+  baseURL: string,
+  proposalId: string,
+  voter: string,
+  key: string | undefined,
+  limit: number | undefined
+): Promise<AxiosResponse<ProposalVote>> => {
+  let uri = `${cleanURL(baseURL)}${voterVoteURL(proposalId, voter)}`;
+  const params = convertPaginationToParams({
+    key: key,
+    limit: limit,
+  });
+  if (params !== '') uri += `?${params}`;
+  return Axios.get(uri);
+};
+
+const fetchProposal = (
+  baseURL: string,
+  proposalId: number
+): Promise<AxiosResponse> =>
+  Axios.get(`${cleanURL(baseURL)}${proposalsURL}/${proposalId}`);
+
+const fetchDepositParams = (baseURL: string): Promise<AxiosResponse> =>
+  Axios.get(`${cleanURL(baseURL)}${depositParamsURL}`);
+
+const result = {
+  proposals: fetchProposals,
+  tally: fetchProposalTally,
+  votes: fetchVoterVote,
+  proposal: fetchProposal,
+  depositParams: fetchDepositParams,
+};
+
+export default result;
diff --git a/frontend/src/store/features/gov/govSlice.ts b/frontend/src/store/features/gov/govSlice.ts
new file mode 100644
index 000000000..c06ef5b50
--- /dev/null
+++ b/frontend/src/store/features/gov/govSlice.ts
@@ -0,0 +1,191 @@
+'use client';
+
+import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
+import govService from './govService';
+import { cloneDeep } from 'lodash';
+import { AxiosError } from 'axios';
+import { ERR_UNKNOWN } from '@/utils/errors';
+import { TxStatus } from '@/types/enums';
+
+interface Chain {
+  active: {
+    status: string;
+    errMsg: string;
+    proposals: ActiveProposal[];
+  };
+  votes: VotesData;
+  tally: ProposalTallyData;
+}
+
+interface Chains {
+  [key: string]: Chain;
+}
+
+interface GovState {
+  chains: Chains;
+  defaultState: Chain;
+}
+
+const initialState: GovState = {
+  chains: {},
+  defaultState: {
+    active: {
+      status: TxStatus.INIT,
+      errMsg: '',
+      proposals: [],
+    },
+    votes: {
+      status: TxStatus.INIT,
+      errMsg: '',
+      proposals: {},
+    },
+    tally: {
+      status: TxStatus.INIT,
+      errMsg: '',
+      proposalTally: {},
+    },
+  },
+};
+
+export const getProposalsInVoting = createAsyncThunk(
+  'gov/active-proposals',
+  async (data: GetProposalsInVotingInputs, { rejectWithValue, dispatch }) => {
+    try {
+      const response = await govService.proposals(
+        data.baseURL,
+        data.key,
+        data.limit,
+        2
+      );
+
+      if (response?.data?.proposals?.length > 0) {
+        const proposals = response?.data?.proposals;
+        for (let i = 0; i < proposals.length; i++) {
+          dispatch(
+            getProposalTally({
+              baseURL: data.baseURL,
+              proposalId: proposals[i].proposal_id,
+              chainID: data.chainID,
+            })
+          );
+
+          dispatch(
+            getVotes({
+              baseURL: data.baseURL,
+              proposalId: proposals[i].proposal_id,
+              voter: data.voter,
+              chainID: data.chainID,
+            })
+          );
+        }
+      }
+
+      return {
+        chainID: data.chainID,
+        data: response.data,
+      };
+    } catch (error) {
+      if (error instanceof AxiosError) return rejectWithValue(error.message);
+      return rejectWithValue(ERR_UNKNOWN);
+    }
+  }
+);
+
+export const getVotes = createAsyncThunk(
+  'gov/voter-votes',
+  async (data: GetVotesInputs) => {
+    const response = await govService.votes(
+      data.baseURL,
+      data.proposalId,
+      data.voter,
+      data.key,
+      data.limit
+    );
+
+    response.data.vote.proposal_id = data.proposalId;
+
+    return {
+      chainID: data.chainID,
+      data: response.data,
+    };
+  }
+);
+
+export const getProposalTally = createAsyncThunk(
+  'gov/proposal-tally',
+  async (data: GetProposalTallyInputs) => {
+    const response = await govService.tally(data.baseURL, data.proposalId);
+
+    response.data.tally.proposal_id = data.proposalId;
+
+    return {
+      chainID: data.chainID,
+      data: response.data,
+    };
+  }
+);
+
+export const govSlice = createSlice({
+  name: 'gov',
+  initialState,
+  reducers: {},
+  extraReducers: (builder) => {
+    // active proposals
+    builder
+      .addCase(getProposalsInVoting.pending, (state, action) => {
+        const chainID = action.meta?.arg?.chainID;
+        if (!state.chains[chainID])
+          state.chains[chainID] = cloneDeep(initialState.defaultState);
+      })
+      .addCase(getProposalsInVoting.fulfilled, (state, action) => {
+        const chainID = action.payload?.chainID || '';
+        if (chainID.length > 0) {
+          let result = {
+            status: 'idle',
+            errMsg: '',
+            proposals: action.payload?.data?.proposals,
+          };
+          state.chains[chainID].active = result;
+        }
+      })
+      .addCase(getProposalsInVoting.rejected, (state, action) => {});
+
+    // votes
+    builder
+      .addCase(getVotes.pending, () => {})
+      .addCase(getVotes.fulfilled, (state, action) => {
+        const chainID = action.payload.chainID;
+        let result: VotesData = {
+          status: 'idle',
+          errMsg: '',
+          proposals: state.chains[chainID].votes?.proposals || {},
+        };
+
+        result.proposals[action.payload?.data?.vote?.proposal_id] =
+          action.payload.data;
+
+        state.chains[chainID].votes = result;
+      })
+      .addCase(getVotes.rejected, () => {});
+
+    // tally
+    builder
+      .addCase(getProposalTally.pending, () => {})
+      .addCase(getProposalTally.fulfilled, (state, action) => {
+        const chainID = action.payload.chainID;
+        let result = {
+          status: 'idle',
+          errMsg: '',
+          proposalTally: state.chains[chainID].tally?.proposalTally || {},
+        };
+
+        result.proposalTally[action.payload?.data?.tally?.proposal_id] =
+          action.payload?.data.tally;
+        state.chains[chainID].tally = result;
+      })
+      .addCase(getProposalTally.rejected, () => {});
+  },
+});
+
+export const {} = govSlice.actions;
+export default govSlice.reducer;
diff --git a/frontend/src/store/store.ts b/frontend/src/store/store.ts
index 86385af66..06061f865 100644
--- a/frontend/src/store/store.ts
+++ b/frontend/src/store/store.ts
@@ -8,6 +8,7 @@ import stakeSlice from './features/staking/stakeSlice';
 import bankSlice from './features/bank/bankSlice';
 import distributionSlice from './features/distribution/distributionSlice';
 import authSlice from './features/auth/authSlice';
+import govSlice from './features/gov/govSlice';
 
 export const store = configureStore({
   reducer: {
@@ -18,6 +19,7 @@ export const store = configureStore({
     bank: bankSlice,
     auth: authSlice,
     distribution: distributionSlice,
+    gov: govSlice,
   },
 });
 
diff --git a/frontend/src/types/gov.d.ts b/frontend/src/types/gov.d.ts
new file mode 100644
index 000000000..e96fdeec2
--- /dev/null
+++ b/frontend/src/types/gov.d.ts
@@ -0,0 +1,116 @@
+interface ActiveProposal {
+  proposal_id: string;
+  content: {
+    '@type': string;
+    title: string;
+    description: string;
+    changes?: {
+      subspace: string;
+      key: string;
+      value: string;
+    }[];
+  };
+  status: string;
+  final_tally_result: {
+    yes: string;
+    abstain: string;
+    no: string;
+    no_with_veto: string;
+  };
+  submit_time: string;
+  deposit_end_time: string;
+  total_deposit: {
+    denom: string;
+    amount: string;
+  }[];
+  voting_start_time: string;
+  voting_end_time: string;
+}
+
+interface CosmosHubProposal {
+  status: string;
+  errMsg: string;
+  proposals: ActiveProposal[];
+}
+
+interface GovPagination {
+  next_key: string | undefined;
+  total: string;
+}
+
+interface GetProposalsInVotingResponse {
+  proposals: ActiveProposal[];
+  pagination: GovPagination;
+}
+
+interface VoteOption {
+  option: string;
+  weight: string;
+}
+
+interface Vote {
+  proposal_id: string;
+  voter: string;
+  option: string;
+  options: VoteOption[];
+}
+
+interface ProposalVote {
+  vote: Vote;
+}
+
+interface VotesData {
+  status: string;
+  errMsg: string;
+  proposals: {
+    [key: string]: ProposalVote;
+  };
+}
+
+interface ProposalTally {
+  [key: string]: {
+    yes: string;
+    abstain: string;
+    no: string;
+    no_with_veto: string;
+    proposal_id: string;
+  };
+}
+
+interface GetProposalTallyResponse {
+  [key: string]: {
+    yes: string;
+    abstain: string;
+    no: string;
+    no_with_veto: string;
+  };
+}
+
+interface ProposalTallyData {
+  status: string;
+  errMsg: string;
+  proposalTally: ProposalTally;
+}
+
+interface GetProposalsInVotingInputs {
+  baseURL: string;
+  chainID: string;
+  voter: string;
+  key?: string;
+  limit?: number;
+}
+
+interface GetVotesInputs {
+  baseURL: string;
+  proposalId: string;
+  voter: string;
+  chainID: string;
+  key?: string;
+  limit?: number;
+}
+
+interface GetProposalTallyInputs {
+  baseURL: string;
+  proposalId: string;
+  chainID: string;
+}