Skip to content

Commit

Permalink
feat: Disable dual staking (#2368)
Browse files Browse the repository at this point in the history
  • Loading branch information
rossbulat authored Dec 17, 2024
1 parent af3e1eb commit e94d92d
Show file tree
Hide file tree
Showing 24 changed files with 114 additions and 87 deletions.
1 change: 1 addition & 0 deletions packages/app/src/contexts/Pools/ActivePool/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const defaultPoolNominations = {
}

export const defaultActivePoolContext: ActivePoolContextState = {
inPool: () => false,
isBonding: () => false,
isNominator: () => false,
isOwner: () => false,
Expand Down
4 changes: 4 additions & 0 deletions packages/app/src/contexts/Pools/ActivePool/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ export const ActivePoolProvider = ({ children }: { children: ReactNode }) => {
return String(membership?.poolId || '') === p
}

// Returns whether the active account is in a pool.
const inPool = () => !!membership

// Returns whether the active account is the depositor of the active pool.
const isDepositor = () => {
const roles = activePool?.bondedPool?.roles
Expand Down Expand Up @@ -170,6 +173,7 @@ export const ActivePoolProvider = ({ children }: { children: ReactNode }) => {
<ActivePoolContext.Provider
value={{
isNominator,
inPool,
isOwner,
isMember,
isDepositor,
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/contexts/Pools/ActivePool/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import type { ActivePool, Nominations, PoolRoles, PoolUnlocking } from 'types'

export interface ActivePoolContextState {
inPool: () => boolean
isBonding: () => boolean
isNominator: () => boolean
isOwner: () => boolean
Expand Down
16 changes: 10 additions & 6 deletions packages/app/src/library/CallToAction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,6 @@ export const CallToActionWrapper = styled.div`
}
&.disabled {
opacity: 0.5;
&:hover {
filter: none;
}
Expand Down Expand Up @@ -197,20 +195,26 @@ export const CallToActionWrapper = styled.div`
margin-left: 0.75rem;
}
&:disabled {
cursor: default;
}
> svg {
margin: 0 0.75rem;
}
&:disabled {
opacity: var(--opacity-disabled);
cursor: default;
}
}
&.inactive {
> button {
cursor: default;
}
}
&:disabled {
opacity: var(--opacity-disabled);
cursor: default;
}
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions packages/app/src/library/SideMenu/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useBalances } from 'contexts/Balances'
import { useBonded } from 'contexts/Bonded'
import { useImportedAccounts } from 'contexts/Connect/ImportedAccounts'
import { useNetwork } from 'contexts/Network'
import { useActivePool } from 'contexts/Pools/ActivePool'
import { useSetup } from 'contexts/Setup'
import type { SetupContextInterface } from 'contexts/Setup/types'
import { useStaking } from 'contexts/Staking'
Expand All @@ -26,20 +27,20 @@ export const Main = () => {
const { t, i18n } = useTranslation('base')
const { syncing } = useSyncing()
const { pathname } = useLocation()
const { inPool } = useActivePool()
const { networkData } = useNetwork()
const { getNominations } = useBalances()
const { getBondedAccount } = useBonded()
const { accounts } = useImportedAccounts()
const { formatWithPrefs } = useValidators()
const { activeAccount } = useActiveAccounts()
const { getPoolMembership, getNominations } = useBalances()
const {
getPoolSetupPercent,
getNominatorSetupPercent,
}: SetupContextInterface = useSetup()
const { sideMenuMinimised }: UIContextInterface = useUi()
const { inSetup: inNominatorSetup, addressDifferentToStash } = useStaking()

const membership = getPoolMembership(activeAccount)
const controller = getBondedAccount(activeAccount)
const controllerDifferentToStash = addressDifferentToStash(controller)

Expand Down Expand Up @@ -99,9 +100,8 @@ export const Main = () => {

if (uri === `${import.meta.env.BASE_URL}pools`) {
// configure Pools action
const inPool = membership

if (inPool) {
if (inPool()) {
pages[i].action = {
type: 'text',
status: 'success',
Expand All @@ -122,7 +122,7 @@ export const Main = () => {
accounts,
controllerDifferentToStash,
syncing,
membership,
inPool(),
inNominatorSetup(),
getNominatorSetupPercent(activeAccount),
getPoolSetupPercent(activeAccount),
Expand Down
9 changes: 3 additions & 6 deletions packages/app/src/library/StatusLabel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@

import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { useActiveAccounts } from 'contexts/ActiveAccounts'
import { useBalances } from 'contexts/Balances'
import { useHelp } from 'contexts/Help'
import { usePlugins } from 'contexts/Plugins'
import { useActivePool } from 'contexts/Pools/ActivePool'
import { useStaking } from 'contexts/Staking'
import { useSyncing } from 'hooks/useSyncing'
import { ButtonHelp } from 'ui-buttons'
Expand All @@ -25,13 +24,11 @@ export const StatusLabel = ({
const { syncing } = useSyncing()
const { plugins } = usePlugins()
const { inSetup } = useStaking()
const { getPoolMembership } = useBalances()
const { activeAccount } = useActiveAccounts()
const membership = getPoolMembership(activeAccount)
const { inPool } = useActivePool()

// syncing or not staking
if (status === 'sync_or_setup') {
if (syncing || !inSetup() || membership !== null) {
if (syncing || !inSetup() || inPool()) {
return null
}
}
Expand Down
10 changes: 5 additions & 5 deletions packages/app/src/overlay/canvas/JoinPool/Overview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import { JoinForm } from './JoinForm'

import { useActiveAccounts } from 'contexts/ActiveAccounts'
import { useBalances } from 'contexts/Balances'
import { useActivePool } from 'contexts/Pools/ActivePool'
import { useStaking } from 'contexts/Staking'
import { GraphLayoutWrapper } from '../Wrappers'
import type { OverviewSectionProps } from '../types'
import { Addresses } from './Addresses'
Expand All @@ -13,17 +14,16 @@ import { Roles } from './Roles'
import { Stats } from './Stats'

export const Overview = (props: OverviewSectionProps) => {
const { getPoolMembership } = useBalances()
const { inSetup } = useStaking()
const { inPool } = useActivePool()
const { activeAccount } = useActiveAccounts()

const {
bondedPool: { state },
} = props

const showJoinForm =
activeAccount !== null &&
state === 'Open' &&
getPoolMembership(activeAccount) === null
activeAccount !== null && state === 'Open' && !inPool() && !inSetup()

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { useActiveAccounts } from 'contexts/ActiveAccounts'
import { useApi } from 'contexts/Api'
import { useImportedAccounts } from 'contexts/Connect/ImportedAccounts'
import { useActivePool } from 'contexts/Pools/ActivePool'
import { useOverlay } from 'kits/Overlay/Provider'
import { CallToActionWrapper } from 'library/CallToAction'
import { CallToActionLoader } from 'library/Loader/CallToAction'
Expand All @@ -17,12 +18,13 @@ export const NewNominator = ({ syncing }: NewNominatorProps) => {
const { t } = useTranslation()
const { isReady } = useApi()
const navigate = useNavigate()
const { inPool } = useActivePool()
const { openCanvas } = useOverlay().canvas
const { activeAccount } = useActiveAccounts()
const { isReadOnlyAccount } = useImportedAccounts()

const nominateButtonDisabled =
!isReady || !activeAccount || isReadOnlyAccount(activeAccount)
!isReady || !activeAccount || isReadOnlyAccount(activeAccount) || inPool()

return (
<CallToActionWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { useUnstaking } from 'hooks/useUnstaking'
import { useOverlay } from 'kits/Overlay/Provider'
import { Stat } from 'library/Stat'
import { useTranslation } from 'react-i18next'
import { useActivePool } from '../../../../contexts/Pools/ActivePool'

export const NominationStatus = ({
showButtons = true,
Expand All @@ -23,19 +24,20 @@ export const NominationStatus = ({
buttonType?: string
}) => {
const { t } = useTranslation('pages')
const { inSetup } = useStaking()
const { openModal } = useOverlay().modal
const { getBondedAccount } = useBonded()
const { syncing } = useSyncing(['initialization', 'era-stakers', 'balances'])
const {
isReady,
networkMetrics: { fastUnstakeErasToCheckPerBlock },
} = useApi()
const { inSetup } = useStaking()
const { inPool } = useActivePool()
const { openModal } = useOverlay().modal
const { getBondedAccount } = useBonded()
const { activeAccount } = useActiveAccounts()
const { checking, isExposed } = useFastUnstake()
const { isReadOnlyAccount } = useImportedAccounts()
const { getNominationStatus } = useNominationStatus()
const { getFastUnstakeText, isUnstaking } = useUnstaking()
const { syncing } = useSyncing(['initialization', 'era-stakers', 'balances'])

const fastUnstakeText = getFastUnstakeText()
const controller = getBondedAccount(activeAccount)
Expand Down Expand Up @@ -65,7 +67,7 @@ export const NominationStatus = ({
<Stat
label={t('nominate.status')}
helpKey="Nomination Status"
stat={nominationStatus.message}
stat={inPool() ? t('nominate.alreadyInPool') : nominationStatus.message}
buttons={
!showButtons || syncing
? []
Expand Down
15 changes: 5 additions & 10 deletions packages/app/src/pages/Overview/Payouts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import { useSize } from '@w3ux/hooks'
import { Odometer } from '@w3ux/react-odometer'
import { minDecimalPlaces } from '@w3ux/utils'
import BigNumber from 'bignumber.js'
import { useActiveAccounts } from 'contexts/ActiveAccounts'
import { useBalances } from 'contexts/Balances'
import { useNetwork } from 'contexts/Network'
import { usePlugins } from 'contexts/Plugins'
import { useActivePool } from 'contexts/Pools/ActivePool'
import { useStaking } from 'contexts/Staking'
import { useUi } from 'contexts/UI'
import { formatDistance, fromUnixTime, getUnixTime } from 'date-fns'
Expand Down Expand Up @@ -36,14 +35,10 @@ export const Payouts = () => {
const { inSetup } = useStaking()
const { syncing } = useSyncing()
const { containerRefs } = useUi()
const { inPool } = useActivePool()
const { pluginEnabled } = usePlugins()
const { getPoolMembership } = useBalances()
const { activeAccount } = useActiveAccounts()

const membership = getPoolMembership(activeAccount)
const nominating = !inSetup()
const inPool = membership !== null
const staking = nominating || inPool
const staking = !inSetup() || inPool
const notStaking = !syncing && !staking

const [lastReward, setLastReward] = useState<NominatorReward>()
Expand Down Expand Up @@ -121,8 +116,8 @@ export const Payouts = () => {
>
{staking && pluginEnabled('staking_api') ? (
<ActiveGraph
nominating={nominating}
inPool={inPool}
nominating={!inSetup()}
inPool={inPool()}
lineMarginTop="3rem"
setLastReward={setLastReward}
/>
Expand Down
8 changes: 3 additions & 5 deletions packages/app/src/pages/Overview/StakeStatus/Tips/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { TipsConfig } from 'config/tips'
import { TipsThresholdMedium, TipsThresholdSmall } from 'consts'
import { useActiveAccounts } from 'contexts/ActiveAccounts'
import { useApi } from 'contexts/Api'
import { useBalances } from 'contexts/Balances'
import { useNetwork } from 'contexts/Network'
import { useActivePool } from 'contexts/Pools/ActivePool'
import { useStaking } from 'contexts/Staking'
Expand All @@ -30,15 +29,14 @@ export const Tips = () => {
const {
stakingMetrics: { minNominatorBond },
} = useApi()
const { inPool } = useActivePool()
const { isOwner } = useActivePool()
const { isNominating } = useStaking()
const { getPoolMembership } = useBalances()
const { activeAccount } = useActiveAccounts()
const { fillVariables } = useFillVariables()
const { syncing } = useSyncing(['initialization'])
const { feeReserve, getTransferOptions } = useTransferOptions()

const membership = getPoolMembership(activeAccount)
const transferOptions = getTransferOptions(activeAccount)

// multiple tips per row is currently turned off.
Expand Down Expand Up @@ -101,7 +99,7 @@ export const Tips = () => {
const segments: AnyJson = []
if (!activeAccount) {
segments.push(1)
} else if (!isNominating() && !membership) {
} else if (!isNominating() && !inPool()) {
if (
transferOptions.freeBalance
.minus(feeReserve)
Expand All @@ -116,7 +114,7 @@ export const Tips = () => {
if (isNominating()) {
segments.push(5)
}
if (membership) {
if (inPool()) {
if (!isOwner()) {
segments.push(6)
} else {
Expand Down
36 changes: 26 additions & 10 deletions packages/app/src/pages/Overview/StakeStatus/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// SPDX-License-Identifier: GPL-3.0-only

import { usePlugins } from 'contexts/Plugins'
import { useActivePool } from 'contexts/Pools/ActivePool'
import { useStaking } from 'contexts/Staking'
import { CardWrapper } from 'library/Card/Wrappers'
import { NominationStatus } from 'pages/Nominate/Active/Status/NominationStatus'
import { MembershipStatus } from 'pages/Pools/Status/MembershipStatus'
Expand All @@ -11,21 +13,35 @@ import { StatusWrapper } from './Wrappers'

export const StakeStatus = () => {
const { plugins } = usePlugins()
const { inPool } = useActivePool()
const { inSetup } = useStaking()

const showTips = plugins.includes('tips')
const notStaking = !inPool() && inSetup()
const showNominate = notStaking || !inSetup()
const showMembership = notStaking || inPool()

return (
<CardWrapper style={{ padding: 0 }}>
<StatusWrapper $borderBottom={showTips}>
<RowSection secondary>
<section>
<NominationStatus showButtons={false} />
</section>
</RowSection>
<RowSection hLast vLast>
<section>
<MembershipStatus showButtons={false} />
</section>
</RowSection>
{showNominate && (
<RowSection secondary={showMembership} standalone={!showMembership}>
<section>
<NominationStatus showButtons={false} />
</section>
</RowSection>
)}
{showMembership && (
<RowSection
hLast={showNominate}
vLast={showNominate}
standalone={!showNominate}
>
<section>
<MembershipStatus showButtons={false} />
</section>
</RowSection>
)}
</StatusWrapper>

{showTips ? <Tips /> : null}
Expand Down
Loading

0 comments on commit e94d92d

Please sign in to comment.