diff --git a/components/admins/components/__tests__/stakingParams.test.tsx b/components/admins/components/__tests__/stakingParams.test.tsx deleted file mode 100644 index ad214d84..00000000 --- a/components/admins/components/__tests__/stakingParams.test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { afterEach, describe, expect, test } from 'bun:test'; -import React from 'react'; -import { screen, cleanup, within, fireEvent } from '@testing-library/react'; -import StakingParams from '@/components/admins/components/stakingParams'; -import matchers from '@testing-library/jest-dom/matchers'; -import { mockStakingParams } from '@/tests/mock'; -import { renderWithChainProvider } from '@/tests/render'; - -expect.extend(matchers); - -const renderWithProps = (props = {}) => { - const defaultProps = { - stakingParams: mockStakingParams, - isLoading: false, - address: 'test_address', - admin: 'admin1', - }; - return renderWithChainProvider(); -}; - -describe('StakingParams', () => { - afterEach(cleanup); - - test('renders correctly when not loading', () => { - renderWithProps(); - const stakingParamsContainer = screen.getByLabelText('Staking Params'); - expect(within(stakingParamsContainer).getByText('UNBONDING TIME')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('1')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('MAX VALIDATORS')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('100')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('BOND DENOM')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('upoa')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('MINIMUM COMMISSION')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('5 %')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('MAX ENTRIES')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('7')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('HISTORICAL ENTRIES')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('200')).toBeInTheDocument(); - }); - - test('renders loading state correctly', () => { - renderWithProps({ isLoading: true }); - const stakingParamsContainer = screen.getByLabelText('Skeleton Staking Params'); - expect(within(stakingParamsContainer).getByText('Staking Params')).toBeInTheDocument(); - expect(within(stakingParamsContainer).getByText('Update')).toBeInTheDocument(); - }); - - test('opens update modal on button click', () => { - renderWithProps(); - const stakingParamsContainer = screen.getByLabelText('Skeleton Staking Params'); - fireEvent.click(within(stakingParamsContainer).getByText('Update')); - const modal = document.getElementById('update-params-modal') as HTMLDialogElement; - expect(modal).toBeInTheDocument(); - expect(modal.open).toBe(true); - }); -}); diff --git a/components/admins/components/index.tsx b/components/admins/components/index.tsx index b2a1351d..bb4c3844 100644 --- a/components/admins/components/index.tsx +++ b/components/admins/components/index.tsx @@ -1,2 +1 @@ -export * from './stakingParams'; export * from './validatorList'; diff --git a/components/admins/components/stakingParams.tsx b/components/admins/components/stakingParams.tsx deleted file mode 100644 index 5c4b845a..00000000 --- a/components/admins/components/stakingParams.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import React from 'react'; -import { ParamsSDKType } from '@liftedinit/manifestjs/dist/codegen/cosmos/staking/v1beta1/staking'; -import { UpdateStakingParamsModal } from '../modals/updateStakingParamsModal'; - -interface StakingParamsProps { - stakingParams: ParamsSDKType; - isLoading: boolean; - address: string; - admin: string; -} - -export default function StakingParams({ - stakingParams, - isLoading, - address, - admin, -}: StakingParamsProps) { - const openParamsModal = () => { - const modal = document.getElementById(`update-params-modal`) as HTMLDialogElement; - modal?.showModal(); - }; - - return ( -
-
-

Staking Params

- - -
-
- {isLoading &&
} - {!isLoading && ( -
-
-
- UNBONDING TIME - - - {Number( - BigInt(stakingParams.unbonding_time?.seconds ?? 1) / BigInt(86400) - ).toString()} - - -
-
- MAX VALIDATORS - - {stakingParams.max_validators} - -
-
-
-
- BOND DENOM - - {stakingParams.bond_denom} - -
-
- MINIMUM COMMISSION - - - {(Number(stakingParams.min_commission_rate) * 100).toFixed(0).toString()} % - - -
-
-
-
- MAX ENTRIES - - {stakingParams.max_entries} - -
-
- HISTORICAL ENTRIES - - {stakingParams.historical_entries} - -
-
-
- )} - - -
- ); -} diff --git a/components/admins/modals/__tests__/updateStakingParamsModal.test.tsx b/components/admins/modals/__tests__/updateStakingParamsModal.test.tsx deleted file mode 100644 index 9e90916f..00000000 --- a/components/admins/modals/__tests__/updateStakingParamsModal.test.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { describe, test, afterEach, expect } from 'bun:test'; -import React from 'react'; -import { screen, fireEvent, cleanup } from '@testing-library/react'; -import { UpdateStakingParamsModal } from '@/components/admins/modals/updateStakingParamsModal'; -import matchers from '@testing-library/jest-dom/matchers'; -import { renderWithChainProvider } from '@/tests/render'; -import { DurationSDKType } from '@liftedinit/manifestjs/src/codegen/google/protobuf/duration'; - -expect.extend(matchers); - -const modalId = 'test-modal'; -const stakingParams: { - unbonding_time: DurationSDKType; - max_validators: number; - bond_denom: string; - min_commission_rate: string; - max_entries: number; - historical_entries: number; -} = { - unbonding_time: { seconds: BigInt(86400), nanos: 0 }, - max_validators: 100, - bond_denom: 'stake', - min_commission_rate: '0.05', - max_entries: 7, - historical_entries: 100, -}; -const admin = 'manifest1adminaddress'; -const address = 'manifest1useraddress'; - -function renderWithProps(props = {}) { - renderWithChainProvider( - - ); -} - -describe('UpdateStakingParamsModal Component', () => { - afterEach(cleanup); - - test('renders modal with correct details', () => { - renderWithProps(); - expect(screen.getByText('Update Staking Parameters')).toBeInTheDocument(); - expect(screen.getByText('UNBONDING TIME')).toBeInTheDocument(); - expect(screen.getByText('MAX VALIDATORS')).toBeInTheDocument(); - expect(screen.getByText('BOND DENOM')).toBeInTheDocument(); - expect(screen.getByText('MINIMUM COMMISSION')).toBeInTheDocument(); - expect(screen.getByText('MAX ENTRIES')).toBeInTheDocument(); - expect(screen.getByText('HISTORICAL ENTRIES')).toBeInTheDocument(); - }); - - test('updates input fields correctly', () => { - renderWithProps(); - const unbondingTimeInput = screen.getByPlaceholderText('1'); - fireEvent.change(unbondingTimeInput, { target: { value: 2 } }); - expect(unbondingTimeInput).toHaveValue(2); - }); - - test('disables update button when no changes are made', () => { - renderWithProps(); - const updateButton = screen.getByText('Update'); - expect(updateButton).toBeDisabled(); - }); - - test('enables update button when changes are made', () => { - renderWithProps(); - const unbondingTimeInput = screen.getByPlaceholderText('1'); - fireEvent.change(unbondingTimeInput, { target: { value: 2 } }); - const updateButton = screen.getByText('Update'); - expect(updateButton).toBeEnabled(); - }); - - // // TODO: Why is this test failing? - // // https://github.com/capricorn86/happy-dom/issues/1184 - // test('closes modal when close button is clicked', async () => { - // renderWithProps(); - // const closeButton = screen.getByText('✕'); - // fireEvent.click(closeButton); - // await waitFor(() => expect(screen.queryByText('Update Staking Parameters')).not.toBeInTheDocument()); - // }); -}); diff --git a/components/admins/modals/updateStakingParamsModal.tsx b/components/admins/modals/updateStakingParamsModal.tsx deleted file mode 100644 index b0b5c3d8..00000000 --- a/components/admins/modals/updateStakingParamsModal.tsx +++ /dev/null @@ -1,185 +0,0 @@ -import { chainName } from '@/config'; -import { useFeeEstimation, useTx } from '@/hooks'; -import { strangelove_ventures, cosmos } from '@liftedinit/manifestjs'; -import { ParamsSDKType } from '@liftedinit/manifestjs/dist/codegen/cosmos/staking/v1beta1/staking'; -import { MsgUpdateStakingParams } from '@liftedinit/manifestjs/dist/codegen/strangelove_ventures/poa/v1/tx'; -import { Any } from '@liftedinit/manifestjs/dist/codegen/google/protobuf/any'; -import React, { useState, useEffect } from 'react'; - -interface UpdateStakingParamsModalProps { - modalId: string; - stakingParams: ParamsSDKType; - admin: string; - address: string; -} - -export function UpdateStakingParamsModal({ - modalId, - stakingParams, - admin, - address, -}: Readonly) { - const [unbondingTime, setUnbondingTime] = useState(''); - const [maxValidators, setMaxValidators] = useState(''); - const [bondDenom, setBondDenom] = useState(''); - const [minCommissionRate, setMinCommissionRate] = useState(''); - const [maxEntries, setMaxEntries] = useState(''); - const [historicalEntries, setHistoricalEntries] = useState(''); - - const [isChanged, setIsChanged] = useState(false); - - const { estimateFee } = useFeeEstimation(chainName); - const { tx } = useTx(chainName); - const { updateStakingParams } = strangelove_ventures.poa.v1.MessageComposer.withTypeUrl; - const { submitProposal } = cosmos.group.v1.MessageComposer.withTypeUrl; - - useEffect(() => { - setIsChanged( - unbondingTime !== '' || - maxValidators !== '' || - bondDenom !== '' || - minCommissionRate !== '' || - maxEntries !== '' || - historicalEntries !== '' - ); - }, [unbondingTime, maxValidators, bondDenom, minCommissionRate, maxEntries, historicalEntries]); - - const handleUpdate = async () => { - const msgUpdateStakingParams = updateStakingParams({ - sender: admin ?? '', - params: { - unbondingTime: unbondingTime - ? { seconds: BigInt(parseInt(unbondingTime) * 86400), nanos: 0 } - : stakingParams.unbonding_time, - maxValidators: maxValidators ? parseInt(maxValidators) : stakingParams.max_validators, - bondDenom: bondDenom || stakingParams.bond_denom, - minCommissionRate: minCommissionRate || stakingParams.min_commission_rate, - maxEntries: maxEntries ? parseInt(maxEntries) : stakingParams.max_entries, - historicalEntries: historicalEntries - ? parseInt(historicalEntries) - : stakingParams.historical_entries, - }, - }); - - const anyMessage = Any.fromPartial({ - typeUrl: msgUpdateStakingParams.typeUrl, - value: MsgUpdateStakingParams.encode(msgUpdateStakingParams.value).finish(), - }); - - const groupProposalMsg = submitProposal({ - groupPolicyAddress: admin, - messages: [anyMessage], - metadata: '', - proposers: [address ?? ''], - title: `Update Staking Params`, - summary: `This proposal will update various staking parameters.`, - exec: 0, - }); - - const fee = await estimateFee(address ?? '', [groupProposalMsg]); - await tx([groupProposalMsg], { - fee, - onSuccess: () => {}, - }); - }; - - const renderInput = ( - label: string, - value: string, - setter: React.Dispatch>, - tip: string, - placeholder: string, - type: string = 'text' - ) => ( -
- {label} - setter(e.target.value)} - placeholder={placeholder} - /> - {tip} -
- ); - - return ( - -
- -

Update Staking Parameters

-
-
-
-
- {renderInput( - 'UNBONDING TIME', - unbondingTime, - setUnbondingTime, - 'Enter time in days', - '1', - 'number' - )} - {renderInput( - 'MAX VALIDATORS', - maxValidators, - setMaxValidators, - 'Maximum number of validators', - stakingParams.max_validators.toString(), - 'number' - )} -
-
- {renderInput( - 'BOND DENOM', - bondDenom, - setBondDenom, - 'Token denomination for bonding', - stakingParams.bond_denom - )} - {renderInput( - 'MINIMUM COMMISSION', - minCommissionRate, - setMinCommissionRate, - 'Commission rate (e.g., 0.05 for 5%)', - stakingParams.min_commission_rate - )} -
-
- {renderInput( - 'MAX ENTRIES', - maxEntries, - setMaxEntries, - 'Maximum entries for either unbonding delegation or redelegation', - stakingParams.max_entries.toString(), - 'number' - )} - {renderInput( - 'HISTORICAL ENTRIES', - historicalEntries, - setHistoricalEntries, - 'Number of historical entries to persist', - stakingParams.historical_entries.toString(), - 'number' - )} -
-
-
-
- -
-
-
- -
-
- ); -}