diff --git a/packages/apps-config/src/api/index.ts b/packages/apps-config/src/api/index.ts index a3dce22b13..a0f9761eef 100644 --- a/packages/apps-config/src/api/index.ts +++ b/packages/apps-config/src/api/index.ts @@ -6,6 +6,7 @@ import typesSpec from './spec'; export { default as typesBundle } from './bundle'; export * from './constants'; +export * from './params'; export { default as typesRpc } from './rpc'; export function getChainTypes (specName: string, chainName: string): Record> { diff --git a/packages/apps-config/src/api/params/index.ts b/packages/apps-config/src/api/params/index.ts new file mode 100644 index 0000000000..4756f23b0e --- /dev/null +++ b/packages/apps-config/src/api/params/index.ts @@ -0,0 +1,5 @@ +// Copyright 2017-2020 @polkadot/app-config authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +export * from './inflation'; +export * from './proposalThresholds'; diff --git a/packages/apps-config/src/api/params/inflation.ts b/packages/apps-config/src/api/params/inflation.ts new file mode 100644 index 0000000000..8cf649e328 --- /dev/null +++ b/packages/apps-config/src/api/params/inflation.ts @@ -0,0 +1,29 @@ +// Copyright 2017-2020 @polkadot/app-config authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { ApiPromise } from '@polkadot/api'; + +import { POLKADOT_GENESIS, KUSAMA_GENESIS } from '../constants'; + +interface InflationParams { + falloff: number; + idealStake: number; + maxInflation: number; + minInflation: number; +} + +const DEFAULT_PARAMS: InflationParams = { + falloff: 0.05, + idealStake: 0.5, + maxInflation: 0.1, + minInflation: 0.025 +}; + +const KNOWN_PARAMS: Record = { + [KUSAMA_GENESIS]: { ...DEFAULT_PARAMS, idealStake: 0.75 }, + [POLKADOT_GENESIS]: { ...DEFAULT_PARAMS, idealStake: 0.75 } +}; + +export function getInflationParams (api: ApiPromise): InflationParams { + return KNOWN_PARAMS[api.genesisHash.toHex()] || DEFAULT_PARAMS; +} diff --git a/packages/page-council/src/thresholds.ts b/packages/apps-config/src/api/params/proposalThresholds.ts similarity index 69% rename from packages/page-council/src/thresholds.ts rename to packages/apps-config/src/api/params/proposalThresholds.ts index 4ba066fdae..2ce8fa36f9 100644 --- a/packages/page-council/src/thresholds.ts +++ b/packages/apps-config/src/api/params/proposalThresholds.ts @@ -1,8 +1,9 @@ -// Copyright 2017-2020 @polkadot/app-council authors & contributors +// Copyright 2017-2020 @polkadot/app-config authors & contributors // SPDX-License-Identifier: Apache-2.0 -import { ApiPromise } from '@polkadot/api'; -import { POLKADOT_GENESIS, KULUPU_GENESIS, KUSAMA_GENESIS } from '@polkadot/apps-config'; +import type { ApiPromise } from '@polkadot/api'; + +import { POLKADOT_GENESIS, KULUPU_GENESIS, KUSAMA_GENESIS } from '../constants'; const PROPOSE_THRESHOLDS: Record = { [KULUPU_GENESIS]: 1, @@ -24,14 +25,14 @@ const TREASURY_THRESHOLDS: Record = { default: 0.6 }; -export function getThreshold (api: ApiPromise): number { +export function getProposalThreshold (api: ApiPromise): number { return PROPOSE_THRESHOLDS[api.genesisHash.toHex()] || PROPOSE_THRESHOLDS.default; } -export function getSlashThreshold (api: ApiPromise): number { +export function getSlashProposalThreshold (api: ApiPromise): number { return SLASH_THRESHOLDS[api.genesisHash.toHex()] || SLASH_THRESHOLDS.default; } -export function getTreasuryThreshold (api: ApiPromise): number { +export function getTreasuryProposalThreshold (api: ApiPromise): number { return TREASURY_THRESHOLDS[api.genesisHash.toHex()] || TREASURY_THRESHOLDS.default; } diff --git a/packages/page-council/src/Motions/ProposeExternal.tsx b/packages/page-council/src/Motions/ProposeExternal.tsx index fe7dbe8a8e..60a2274893 100644 --- a/packages/page-council/src/Motions/ProposeExternal.tsx +++ b/packages/page-council/src/Motions/ProposeExternal.tsx @@ -4,12 +4,12 @@ import type { SubmittableExtrinsic } from '@polkadot/api/types'; import React, { useCallback, useEffect, useState } from 'react'; +import { getProposalThreshold } from '@polkadot/apps-config'; import { Button, Input, InputAddress, Modal, TxButton } from '@polkadot/react-components'; import { useApi, useToggle } from '@polkadot/react-hooks'; import { isHex } from '@polkadot/util'; import { useTranslation } from '../translate'; -import { getThreshold } from '../thresholds'; interface Props { className?: string; @@ -35,7 +35,7 @@ function ProposeExternal ({ className = '', isMember, members }: Props): React.R const [{ proposal, proposalLength }, setProposal] = useState({ proposalLength: 0 }); const [{ hash, isHashValid }, setHash] = useState({ hash: '', isHashValid: false }); - const threshold = Math.ceil((members.length || 0) * getThreshold(api)); + const threshold = Math.ceil((members.length || 0) * getProposalThreshold(api)); const _onChangeHash = useCallback( (hash?: string): void => setHash({ hash, isHashValid: isHex(hash, 256) }), diff --git a/packages/page-council/src/Motions/ProposeMotion.tsx b/packages/page-council/src/Motions/ProposeMotion.tsx index e25121f429..0ee242e00a 100644 --- a/packages/page-council/src/Motions/ProposeMotion.tsx +++ b/packages/page-council/src/Motions/ProposeMotion.tsx @@ -5,12 +5,12 @@ import type { SubmittableExtrinsic } from '@polkadot/api/types'; import BN from 'bn.js'; import React, { useCallback, useEffect, useState } from 'react'; +import { getProposalThreshold } from '@polkadot/apps-config'; import { Button, Extrinsic, InputAddress, InputNumber, Modal, TxButton } from '@polkadot/react-components'; import { useApi, useToggle } from '@polkadot/react-hooks'; import { BN_ZERO } from '@polkadot/util'; import { useTranslation } from '../translate'; -import { getThreshold } from '../thresholds'; interface Props { isMember: boolean; @@ -38,7 +38,7 @@ function Propose ({ isMember, members }: Props): React.ReactElement { useEffect((): void => { members && setThreshold({ isThresholdValid: members.length !== 0, - threshold: new BN(Math.ceil(members.length * getThreshold(api))) + threshold: new BN(Math.ceil(members.length * getProposalThreshold(api))) }); }, [api, members]); diff --git a/packages/page-council/src/Motions/Slashing.tsx b/packages/page-council/src/Motions/Slashing.tsx index 25192773d5..d6c14add78 100644 --- a/packages/page-council/src/Motions/Slashing.tsx +++ b/packages/page-council/src/Motions/Slashing.tsx @@ -4,11 +4,11 @@ import type { SubmittableExtrinsic } from '@polkadot/api/types'; import React, { useEffect, useMemo, useState } from 'react'; +import { getSlashProposalThreshold } from '@polkadot/apps-config'; import { Button, Dropdown, Input, InputAddress, Modal, TxButton } from '@polkadot/react-components'; import { useApi, useAvailableSlashes, useToggle } from '@polkadot/react-hooks'; import { useTranslation } from '../translate'; -import { getSlashThreshold } from '../thresholds'; interface Props { className?: string; @@ -35,7 +35,7 @@ function Slashing ({ className = '', isMember, members }: Props): React.ReactEle const [{ proposal, proposalLength }, setProposal] = useState({ proposal: null, proposalLength: 0 }); const [selectedEra, setSelectedEra] = useState(0); - const threshold = Math.ceil((members.length || 0) * getSlashThreshold(api)); + const threshold = Math.ceil((members.length || 0) * getSlashProposalThreshold(api)); const eras = useMemo( () => (slashes || []).map(([era, slashes]): Option => ({ diff --git a/packages/page-staking/src/Slashes/index.tsx b/packages/page-staking/src/Slashes/index.tsx index 25c373c7c6..5754bce43e 100644 --- a/packages/page-staking/src/Slashes/index.tsx +++ b/packages/page-staking/src/Slashes/index.tsx @@ -7,9 +7,9 @@ import type { Slash, SlashEra } from './types'; import BN from 'bn.js'; import React, { useMemo, useState } from 'react'; +import { getSlashProposalThreshold } from '@polkadot/apps-config'; import { Table, ToggleGroup } from '@polkadot/react-components'; import { useAccounts, useApi, useMembers } from '@polkadot/react-hooks'; -import { getSlashThreshold } from '@polkadot/app-council/thresholds'; import { formatNumber } from '@polkadot/util'; import { useTranslation } from '../translate'; @@ -119,7 +119,7 @@ function Slashes ({ ownStashes = [], slashes }: Props): React.ReactElement { +function extractInfo (api: ApiPromise, allAccounts: string[], electedDerive: DeriveStakingElected, waitingDerive: DeriveStakingWaiting, favorites: string[], totalIssuance: BN, lastReward = BN_ONE): Partial { const perValidatorReward = lastReward.divn(electedDerive.info.length); const [elected, nominators] = extractSingle(allAccounts, electedDerive, favorites, perValidatorReward); const [waiting] = extractSingle(allAccounts, waitingDerive, favorites, perValidatorReward); @@ -151,7 +152,7 @@ function extractInfo (genesisHash: string, allAccounts: string[], electedDerive: .sort((a, b) => a.cmp(b)); const totalStaked = activeTotals.reduce((total: BN, value) => total.iadd(value), new BN(0)); const avgStaked = totalStaked.divn(activeTotals.length); - const inflation = calcInflation(genesisHash, totalStaked, totalIssuance); + const inflation = calcInflation(api, totalStaked, totalIssuance); // add the explicit stakedReturn !avgStaked.isZero() && elected.forEach((e): void => { @@ -194,7 +195,7 @@ export default function useSortedTargets (favorites: string[]): SortedTargets { const partial = useMemo( () => electedInfo && totalIssuance && waitingInfo - ? extractInfo(api.genesisHash.toHex(), allAccounts, electedInfo, waitingInfo, favorites, totalIssuance, lastReward) + ? extractInfo(api, allAccounts, electedInfo, waitingInfo, favorites, totalIssuance, lastReward) : EMPTY_PARTIAL, [api, allAccounts, electedInfo, favorites, lastReward, totalIssuance, waitingInfo] ); diff --git a/packages/page-treasury/src/Overview/Council.tsx b/packages/page-treasury/src/Overview/Council.tsx index 241ceff12a..d1bb9a1037 100644 --- a/packages/page-treasury/src/Overview/Council.tsx +++ b/packages/page-treasury/src/Overview/Council.tsx @@ -5,7 +5,7 @@ import type { SubmittableExtrinsic } from '@polkadot/api/types'; import type { ProposalIndex } from '@polkadot/types/interfaces'; import React, { useEffect, useRef, useState } from 'react'; -import { getTreasuryThreshold } from '@polkadot/app-council/thresholds'; +import { getTreasuryProposalThreshold } from '@polkadot/apps-config'; import { Button, Dropdown, InputAddress, Modal, TxButton } from '@polkadot/react-components'; import { useApi, useToggle } from '@polkadot/react-hooks'; @@ -30,7 +30,7 @@ function Council ({ id, isDisabled, members }: Props): React.ReactElement const [councilType, setCouncilType] = useState('accept'); const [{ proposal, proposalLength }, setProposal] = useState({ proposalLength: 0 }); - const threshold = Math.ceil((members?.length || 0) * getTreasuryThreshold(api)); + const threshold = Math.ceil((members?.length || 0) * getTreasuryProposalThreshold(api)); const councilTypeOptRef = useRef([ { text: t('Acceptance proposal to council'), value: 'accept' }, diff --git a/packages/react-hooks/src/useInflation.ts b/packages/react-hooks/src/useInflation.ts index 2a6ad92643..ee508ba034 100644 --- a/packages/react-hooks/src/useInflation.ts +++ b/packages/react-hooks/src/useInflation.ts @@ -1,36 +1,18 @@ // Copyright 2017-2020 @polkadot/react-hooks authors & contributors // SPDX-License-Identifier: Apache-2.0 +import type { ApiPromise } from '@polkadot/api'; import type { Inflation } from './types'; import BN from 'bn.js'; import { useEffect, useState } from 'react'; -import { KUSAMA_GENESIS, POLKADOT_GENESIS } from '@polkadot/apps-config'; +import { getInflationParams } from '@polkadot/apps-config'; import { useApi } from './useApi'; import { useCall } from './useCall'; -interface Config { - falloff: number; - idealStake: number; - maxInflation: number; - minInflation: number; -} - -const DEFAULT_CONFIG: Config = { - falloff: 0.05, - idealStake: 0.5, - maxInflation: 0.1, - minInflation: 0.025 -}; - -const KNOWN_CONFIG: Record = { - [KUSAMA_GENESIS]: { ...DEFAULT_CONFIG, idealStake: 0.75 }, - [POLKADOT_GENESIS]: { ...DEFAULT_CONFIG, idealStake: 0.75 } -}; - -export function calcInflation (genesisHash: string, totalStaked: BN, totalIssuance: BN): Inflation { - const { falloff, idealStake, maxInflation, minInflation } = KNOWN_CONFIG[genesisHash] || DEFAULT_CONFIG; +export function calcInflation (api: ApiPromise, totalStaked: BN, totalIssuance: BN): Inflation { + const { falloff, idealStake, maxInflation, minInflation } = getInflationParams(api); const stakedFraction = totalStaked.muln(1_000_000).div(totalIssuance).toNumber() / 1_000_000; const idealInterest = maxInflation / idealStake; const inflation = 100 * (minInflation + ( @@ -52,7 +34,7 @@ export function useInflation (totalStaked?: BN): Inflation { useEffect((): void => { totalIssuance && totalStaked && setState( - calcInflation(api.genesisHash.toHex(), totalStaked, totalIssuance) + calcInflation(api, totalStaked, totalIssuance) ); }, [api, totalIssuance, totalStaked]);