Parameterize treasury proposal (#3418)
This commit is contained in:
parent
7644f0b9c0
commit
9e664246ed
@ -10,7 +10,7 @@ import { useApi, useToggle } from '@polkadot/react-hooks';
|
||||
import { isHex } from '@polkadot/util';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import { getThreshold } from './thresholds';
|
||||
import { getThreshold } from '../thresholds';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
@ -35,6 +35,7 @@ function ProposeExternal ({ className = '', isMember, members }: Props): React.R
|
||||
const [accountId, setAcountId] = useState<string | null>(null);
|
||||
const [{ proposal, proposalLength }, setProposal] = useState<ProposalState>({ proposalLength: 0 });
|
||||
const [{ hash, isHashValid }, setHash] = useState<HashState>({ hash: '', isHashValid: false });
|
||||
|
||||
const threshold = Math.ceil((members.length || 0) * getThreshold(api));
|
||||
|
||||
const _onChangeHash = useCallback(
|
||||
|
||||
@ -11,7 +11,7 @@ import { useApi, useToggle } from '@polkadot/react-hooks';
|
||||
import { BN_ZERO } from '@polkadot/util';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import { getThreshold } from './thresholds';
|
||||
import { getThreshold } from '../thresholds';
|
||||
|
||||
interface Props {
|
||||
isMember: boolean;
|
||||
|
||||
@ -9,7 +9,7 @@ import { Button, Dropdown, Input, InputAddress, Modal, TxButton } from '@polkado
|
||||
import { useApi, useAvailableSlashes, useToggle } from '@polkadot/react-hooks';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import { getSlashThreshold } from './thresholds';
|
||||
import { getSlashThreshold } from '../thresholds';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
@ -36,6 +36,7 @@ function Slashing ({ className = '', isMember, members }: Props): React.ReactEle
|
||||
const [{ proposal, proposalLength }, setProposal] = useState<ProposalState>({ proposal: null, proposalLength: 0 });
|
||||
const [eras, setEras] = useState<Option[]>([]);
|
||||
const [selectedEra, setSelectedEra] = useState(0);
|
||||
|
||||
const threshold = Math.ceil((members.length || 0) * getSlashThreshold(api));
|
||||
|
||||
useEffect((): void => {
|
||||
|
||||
@ -15,6 +15,11 @@ const SLASH_THRESHOLDS: Record<string, number> = {
|
||||
[POLKADOT_GENESIS]: 0.75
|
||||
};
|
||||
|
||||
const TREASURY_THRESHOLDS: Record<string, number> = {
|
||||
// Polkadot
|
||||
[POLKADOT_GENESIS]: 0.6
|
||||
};
|
||||
|
||||
export function getThreshold (api: ApiPromise): number {
|
||||
return PROPOSE_THRESHOLDS[api.genesisHash.toHex()] || 0.5;
|
||||
}
|
||||
@ -22,3 +27,7 @@ export function getThreshold (api: ApiPromise): number {
|
||||
export function getSlashThreshold (api: ApiPromise): number {
|
||||
return SLASH_THRESHOLDS[api.genesisHash.toHex()] || 0.5;
|
||||
}
|
||||
|
||||
export function getTreasuryThreshold (api: ApiPromise): number {
|
||||
return TREASURY_THRESHOLDS[api.genesisHash.toHex()] || 0.6;
|
||||
}
|
||||
@ -21,6 +21,7 @@ function Propose ({ className }: Props): React.ReactElement<Props> | null {
|
||||
const [isOpen, toggleOpen] = useToggle();
|
||||
const [value, setValue] = useState<BN | undefined>();
|
||||
const hasValue = value?.gtn(0);
|
||||
|
||||
const bondPercentage = useMemo(
|
||||
() => `${api.consts.treasury.proposalBond.muln(100).divn(1_000_000).toNumber().toFixed(2)}%`,
|
||||
[api]
|
||||
|
||||
@ -7,8 +7,9 @@ import { DeriveCollectiveProposal } from '@polkadot/api-derive/types';
|
||||
import { ProposalIndex } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { getTreasuryThreshold } from '@polkadot/app-council/thresholds';
|
||||
import { Button, Dropdown, InputAddress, Modal, TxButton } from '@polkadot/react-components';
|
||||
import { useApi, useCall, useToggle } from '@polkadot/react-hooks';
|
||||
import { useApi, useToggle } from '@polkadot/react-hooks';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
|
||||
@ -27,15 +28,14 @@ interface ProposalState {
|
||||
function Submission ({ councilProposals, id, isDisabled, members }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const councilThreshold = useCall<number>((api.query.electionsPhragmen || api.query.elections).members, [], {
|
||||
transform: (value: unknown[]): number =>
|
||||
Math.ceil(value.length * 0.6)
|
||||
});
|
||||
const [isOpen, toggleOpen] = useToggle();
|
||||
const [accountId, setAccountId] = useState<string | null>(null);
|
||||
const [councilType, setCouncilType] = useState('reject');
|
||||
const [{ proposal, proposalLength }, setProposal] = useState<ProposalState>({ proposalLength: 0 });
|
||||
const [hasProposals, setHasProposals] = useState(true);
|
||||
|
||||
const threshold = Math.ceil((members?.length || 0) * getTreasuryThreshold(api));
|
||||
|
||||
const councilTypeOpt = useMemo(() => [
|
||||
{ text: t<string>('Acceptance proposal to council'), value: 'accept' },
|
||||
{ text: t<string>('Rejection proposal to council'), value: 'reject' }
|
||||
@ -104,13 +104,13 @@ function Submission ({ councilProposals, id, isDisabled, members }: Props): Reac
|
||||
<TxButton
|
||||
accountId={accountId}
|
||||
icon='check'
|
||||
isDisabled={!accountId || !councilThreshold}
|
||||
isDisabled={!accountId || !threshold}
|
||||
label={t<string>('Send to council')}
|
||||
onStart={toggleOpen}
|
||||
params={
|
||||
api.tx.council.propose.meta.args.length === 3
|
||||
? [councilThreshold, proposal, proposalLength]
|
||||
: [councilThreshold, proposal]
|
||||
? [threshold, proposal, proposalLength]
|
||||
: [threshold, proposal]
|
||||
}
|
||||
tx='council.propose'
|
||||
/>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { useAccounts, useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
interface Result {
|
||||
@ -15,17 +15,16 @@ interface Result {
|
||||
export default function useMembers (collective: 'council' | 'technicalCommittee' = 'council'): Result {
|
||||
const { api } = useApi();
|
||||
const { allAccounts, hasAccounts } = useAccounts();
|
||||
const [state, setState] = useState<Result>({ isMember: false, members: [] });
|
||||
const retrieved = useCall<string[]>(hasAccounts && api.query[collective]?.members, [], {
|
||||
transform: (accounts: AccountId[]) => accounts.map((accountId) => accountId.toString())
|
||||
transform: (accounts: AccountId[]) =>
|
||||
accounts.map((accountId) => accountId.toString())
|
||||
});
|
||||
|
||||
useEffect((): void => {
|
||||
retrieved && setState({
|
||||
isMember: retrieved.some((accountId) => allAccounts.includes(accountId)),
|
||||
members: retrieved
|
||||
});
|
||||
}, [allAccounts, retrieved]);
|
||||
|
||||
return state;
|
||||
return useMemo(
|
||||
() => ({
|
||||
isMember: (retrieved || []).some((accountId) => allAccounts.includes(accountId)),
|
||||
members: (retrieved || [])
|
||||
}),
|
||||
[allAccounts, retrieved]
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user