diff --git a/frontend/src/app/(routes)/multisig/components/multisig-account/MultisigAccount.tsx b/frontend/src/app/(routes)/multisig/components/multisig-account/MultisigAccount.tsx index 471293d0b..27c753abb 100644 --- a/frontend/src/app/(routes)/multisig/components/multisig-account/MultisigAccount.tsx +++ b/frontend/src/app/(routes)/multisig/components/multisig-account/MultisigAccount.tsx @@ -1,6 +1,7 @@ import { useAppDispatch, useAppSelector } from '@/custom-hooks/StateHooks'; import useGetChainInfo from '@/custom-hooks/useGetChainInfo'; import { + getDelegations as getMultisigDelegations, getMultisigAccounts, getMultisigBalances, multisigByAddress, @@ -10,7 +11,6 @@ import { resetUpdateTxnState, setVerifyDialogOpen, } from '@/store/features/multisig/multisigSlice'; -import { getDelegations } from '@/store/features/staking/stakeSlice'; import { useEffect, useState } from 'react'; import MultisigAccountHeader from './MultisigAccountHeader'; import Copy from '@/components/common/Copy'; @@ -92,7 +92,7 @@ const MultisigAccount = ({ }) ); dispatch( - getDelegations({ + getMultisigDelegations({ baseURLs: restURLs, address: multisigAddress, chainID, @@ -202,7 +202,7 @@ const MultisigAccountInfo = ({ (state) => state.multisig.multisigAccounts ); const totalStaked = useAppSelector( - (state) => state.staking.chains?.[chainID]?.delegations.totalStaked + (state) => state.multisig?.delegations.totalStaked ); const balance = useAppSelector((state) => state.multisig.balance.balance); diff --git a/frontend/src/app/(routes)/multisig/components/txns/ReDelegate.tsx b/frontend/src/app/(routes)/multisig/components/txns/ReDelegate.tsx index 00b9b3697..80f41df52 100644 --- a/frontend/src/app/(routes)/multisig/components/txns/ReDelegate.tsx +++ b/frontend/src/app/(routes)/multisig/components/txns/ReDelegate.tsx @@ -48,7 +48,7 @@ const ReDelegate: React.FC = (props) => { ); const delegations = useAppSelector( - (state: RootState) => state.staking.chains[chainID].delegations + (state: RootState) => state.multisig.delegations ) useEffect(() => { diff --git a/frontend/src/app/(routes)/multisig/components/txns/UnDelegate.tsx b/frontend/src/app/(routes)/multisig/components/txns/UnDelegate.tsx index 85dea220a..e8b459fd8 100644 --- a/frontend/src/app/(routes)/multisig/components/txns/UnDelegate.tsx +++ b/frontend/src/app/(routes)/multisig/components/txns/UnDelegate.tsx @@ -46,7 +46,7 @@ const UnDelegate: React.FC = (props) => { ); const delegations = useAppSelector( - (state: RootState) => state.staking.chains[chainID].delegations + (state: RootState) => state.multisig.delegations ); useEffect(() => { diff --git a/frontend/src/store/features/multisig/multisigSlice.ts b/frontend/src/store/features/multisig/multisigSlice.ts index 8a7b7eb44..59fa950c0 100644 --- a/frontend/src/store/features/multisig/multisigSlice.ts +++ b/frontend/src/store/features/multisig/multisigSlice.ts @@ -48,6 +48,7 @@ import { get } from 'lodash'; import { getAuthToken } from '@/utils/localStorage'; import multisigSigning from '@/app/(routes)/multisig/utils/multisigSigning'; import { setError } from '../common/commonSlice'; +import stakingService from '../staking/stakingService'; const initialState: MultisigState = { createMultisigAccountRes: { @@ -88,6 +89,21 @@ const initialState: MultisigState = { status: TxStatus.INIT, error: '', }, + delegations: { + status: TxStatus.INIT, + delegations: { + delegation_responses: [], + pagination: { + next_key: '', + total: '', + }, + }, + hasDelegations: false, + errMsg: '', + pagination: undefined, + delegatedTo: {}, + totalStaked: 0.0, + }, createTxnRes: { status: TxStatus.INIT, error: '', @@ -287,6 +303,49 @@ export const getMultisigBalances = createAsyncThunk( } ); +export const getDelegations = createAsyncThunk( + 'multisig/delegations', + async ( + data: { + baseURLs: string[]; + address: string; + chainID: string; + }, + { rejectWithValue } + ) => { + try { + const delegations = []; + let nextKey = null; + const limit = 100; + while (true) { + const response = await stakingService.delegations( + data.baseURLs, + data.address, + data.chainID, + nextKey + ? { + key: nextKey, + limit: limit, + } + : {} + ); + delegations.push(...(response.data?.delegation_responses || [])); + if (!response.data.pagination?.next_key) { + break; + } + nextKey = response.data.pagination.next_key; + } + + return { + delegations: delegations, + }; + } catch (error) { + if (error instanceof AxiosError) return rejectWithValue(error.message); + return rejectWithValue(ERR_UNKNOWN); + } + } +); + export const createTxn = createAsyncThunk( 'multisig/createTxn', async (data: CreateTxnInputs, { rejectWithValue }) => { @@ -731,6 +790,35 @@ export const multisigSlice = createSlice({ const payload = action.payload as { message: string }; state.balance.error = payload.message || ''; }); + builder + .addCase(getDelegations.pending, (state) => { + state.delegations.status = TxStatus.PENDING; + state.delegations.errMsg = ''; + }) + .addCase(getDelegations.fulfilled, (state, action) => { + const delegation_responses = action.payload.delegations; + if (delegation_responses?.length) { + state.delegations.hasDelegations = true; + } + state.delegations.status = TxStatus.IDLE; + state.delegations.delegations.delegation_responses = + delegation_responses; + state.delegations.errMsg = ''; + + let total = 0.0; + for (let i = 0; i < delegation_responses.length; i++) { + const delegation = delegation_responses[i]; + state.delegations.delegatedTo[ + delegation?.delegation?.validator_address + ] = true; + total += parseFloat(delegation?.delegation?.shares); + } + state.delegations.totalStaked = total; + }) + .addCase(getDelegations.rejected, (state, action) => { + state.delegations.status = TxStatus.REJECTED; + state.delegations.errMsg = action.error.message || ''; + }); builder .addCase(createTxn.pending, (state) => { state.createTxnRes.status = TxStatus.PENDING; diff --git a/frontend/src/types/multisig.d.ts b/frontend/src/types/multisig.d.ts index 500825a5b..426cef9bc 100644 --- a/frontend/src/types/multisig.d.ts +++ b/frontend/src/types/multisig.d.ts @@ -117,6 +117,15 @@ interface MultisigState { deleteMultisigRes: TxRes; multisigAccount: MultisigAccount; balance: Balance; + delegations: { + status: TxStatus; + delegations: GetDelegationsResponse; + hasDelegations: boolean; + errMsg: string; + pagination: Pagination | undefined; + delegatedTo: Record; + totalStaked: number; + }; createTxnRes: TxRes; updateTxnRes: TxRes; txns: Txns;