diff --git a/src/app/account/page.tsx b/src/app/account/page.tsx index fd19f8c..d71b848 100644 --- a/src/app/account/page.tsx +++ b/src/app/account/page.tsx @@ -58,7 +58,7 @@ export default function Page() { const totalLocked = getTotalLockedCelo(lockedBalances); const totalBalance = (walletBalance || 0n) + totalLocked; - const totalDelegated = (delegations?.totalPercent || 0n) * totalLocked; + const totalDelegated = BigInt(delegations?.totalPercent || 0) * totalLocked; return (
diff --git a/src/features/delegation/DelegationForm.tsx b/src/features/delegation/DelegationForm.tsx index c2e86f1..08abbb1 100644 --- a/src/features/delegation/DelegationForm.tsx +++ b/src/features/delegation/DelegationForm.tsx @@ -46,7 +46,7 @@ export function DelegationForm({ const { getNextTx, txPlanIndex, numTxs, isPlanStarted, onTxSuccess } = useTransactionPlan({ - createTxPlan: (v) => getDelegateTxPlan(v, delegations), + createTxPlan: (v) => getDelegateTxPlan(v), onStepSuccess: () => refetch(), onPlanSuccess: (v, r) => onConfirmed({ diff --git a/src/features/delegation/delegatePlan.ts b/src/features/delegation/delegatePlan.ts index 55bca92..22b4af3 100644 --- a/src/features/delegation/delegatePlan.ts +++ b/src/features/delegation/delegatePlan.ts @@ -1,18 +1,11 @@ import { lockedGoldABI } from '@celo/abis'; import { Addresses } from 'src/config/contracts'; -import { - DelegateActionType, - DelegateFormValues, - DelegationBalances, -} from 'src/features/delegation/types'; +import { DelegateActionType, DelegateFormValues } from 'src/features/delegation/types'; import { TxPlan } from 'src/features/transactions/types'; import { logger } from 'src/utils/logger'; import { toFixidity } from 'src/utils/numbers'; -export function getDelegateTxPlan( - values: DelegateFormValues, - _delegations?: DelegationBalances, -): TxPlan { +export function getDelegateTxPlan(values: DelegateFormValues): TxPlan { const { action, delegatee, percent } = values; if (action === DelegateActionType.Delegate) { diff --git a/src/features/staking/StakeForm.tsx b/src/features/staking/StakeForm.tsx index a0b2651..57c193f 100644 --- a/src/features/staking/StakeForm.tsx +++ b/src/features/staking/StakeForm.tsx @@ -1,8 +1,9 @@ -import { Form, Formik, FormikErrors, useField, useFormikContext } from 'formik'; +import { Field, Form, Formik, FormikErrors, useField, useFormikContext } from 'formik'; import { SyntheticEvent, useCallback, useEffect, useMemo } from 'react'; import { IconButton } from 'src/components/buttons/IconButton'; import { MultiTxFormSubmitButton } from 'src/components/buttons/MultiTxFormSubmitButton'; import { ChevronIcon } from 'src/components/icons/Chevron'; +import { HelpIcon } from 'src/components/icons/HelpIcon'; import { AmountField } from 'src/components/input/AmountField'; import { RadioField } from 'src/components/input/RadioField'; import { DropdownMenu } from 'src/components/menus/Dropdown'; @@ -11,6 +12,7 @@ import { MIN_GROUP_SCORE_FOR_RANDOM, ZERO_ADDRESS, } from 'src/config/consts'; +import { useDelegationBalances } from 'src/features/delegation/useDelegationBalances'; import { LockedBalances } from 'src/features/locking/types'; import { useLockedStatus } from 'src/features/locking/useLockedStatus'; import { getStakeTxPlan } from 'src/features/staking/stakePlan'; @@ -42,6 +44,7 @@ const initialValues: StakeFormValues = { amount: 0, group: ZERO_ADDRESS, transferGroup: ZERO_ADDRESS, + delegate: false, }; export function StakeForm({ @@ -55,6 +58,7 @@ export function StakeForm({ const { groups, addressToGroup } = useValidatorGroups(); const { lockedBalances } = useLockedStatus(address); const { stakeBalances, groupToStake, refetch } = useStakingBalances(address); + const { delegations } = useDelegationBalances(address); const { getNextTx, txPlanIndex, numTxs, isPlanStarted, onTxSuccess } = useTransactionPlan({ @@ -123,6 +127,9 @@ export function StakeForm({ groupToStake={groupToStake} disabled={isInputDisabled} /> + {values.action === StakeActionType.Stake && delegations?.totalPercent === 0 && ( + + )} + + + + ); +} + function validateForm( values: StakeFormValues, lockedBalances: LockedBalances, diff --git a/src/features/staking/stakePlan.ts b/src/features/staking/stakePlan.ts index 803f14c..d9849d4 100644 --- a/src/features/staking/stakePlan.ts +++ b/src/features/staking/stakePlan.ts @@ -1,6 +1,8 @@ import { electionABI } from '@celo/abis'; import { MIN_INCREMENTAL_VOTE_AMOUNT, ZERO_ADDRESS } from 'src/config/consts'; import { Addresses } from 'src/config/contracts'; +import { getDelegateTxPlan } from 'src/features/delegation/delegatePlan'; +import { DelegateActionType } from 'src/features/delegation/types'; import { GroupToStake, StakeActionType, StakeFormValues } from 'src/features/staking/types'; import { TxPlan } from 'src/features/transactions/types'; import { ValidatorGroup } from 'src/features/validators/types'; @@ -14,12 +16,23 @@ export function getStakeTxPlan( groups: ValidatorGroup[], groupToStake: GroupToStake, ): TxPlan { - const { action, amount, group, transferGroup } = values; + const { action, amount, group, transferGroup, delegate } = values; // TODO toWeiAdjusted here const amountWei = toWeiSafe(amount); if (action === StakeActionType.Stake) { - return getStakeActionPlan(amountWei, group, groups); + let stakePlan = getStakeActionPlan(amountWei, group, groups); + if (delegate) { + // Note: this assumes the user has 100% voting power available + const delegatePlan = getDelegateTxPlan({ + action: DelegateActionType.Delegate, + delegatee: group, + percent: 100, + transferDelegatee: ZERO_ADDRESS, + }); + stakePlan = [...stakePlan, ...delegatePlan]; + } + return stakePlan; } else if (action === StakeActionType.Unstake) { return getUnstakeActionPlan(amountWei, group, groups, groupToStake); } else if (action === StakeActionType.Transfer) { diff --git a/src/features/staking/types.ts b/src/features/staking/types.ts index 6a81fa8..c55caa7 100644 --- a/src/features/staking/types.ts +++ b/src/features/staking/types.ts @@ -38,4 +38,5 @@ export interface StakeFormValues { group: Address; // Only used in transfer actions, the new target group transferGroup: Address; + delegate: boolean; }