Skip to content

Commit 16a4dbb

Browse files
Merge pull request #118 from threshold-network/min-stake-validation
Minimum Stake validation This PR adds validation to the staking form. To stake in T network the minimum stake amount is required. Currently it is 40,000 T. Main changes: - set the placeholder for input in staking form- Minimum stake <amount> T, - create a hook that returns the min stake amount- it fetches the min stake amount if needed and saves in a redux store. If a value already exists in redux store a hook will return a value from redux store, otherwise fetches the value from chain, - update the TokenAmountForm - allow to set the placeholder for an input and set the required minimum amount to submit a form.
2 parents 184639b + d0d368f commit 16a4dbb

File tree

6 files changed

+56
-4
lines changed

6 files changed

+56
-4
lines changed

src/components/Forms/TokenAmountForm.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import ThresholdCircleBrand from "../../static/icons/ThresholdCircleBrand"
55
import { FormikTokenBalanceInput } from "./FormikTokenBalanceInput"
66
import SubmitTxButton from "../SubmitTxButton"
77
import { Form } from "./Form"
8-
import { getErrorsObj, validateAmountInRange } from "../../utils/forms"
8+
import {
9+
DEFAULT_MIN_VALUE,
10+
getErrorsObj,
11+
validateAmountInRange,
12+
} from "../../utils/forms"
913
import { formatTokenAmount } from "../../utils/formatAmount"
1014

1115
export type FormValues = {
@@ -25,6 +29,8 @@ type TokenAmountFormProps = {
2529
shouldDisplayMaxAmountInLabel?: boolean
2630
token?: { decimals: number; symbol: string }
2731
innerRef?: Ref<FormikProps<FormValues>>
32+
placeholder?: string
33+
minTokenAmount?: string | number
2834
}
2935

3036
const TokenAmountFormBase: FC<
@@ -39,6 +45,7 @@ const TokenAmountFormBase: FC<
3945
isDisabled = false,
4046
shouldValidateForm = true,
4147
shouldDisplayMaxAmountInLabel = false,
48+
placeholder,
4249
...formikProps
4350
}) => {
4451
return (
@@ -60,7 +67,7 @@ const TokenAmountFormBase: FC<
6067
label
6168
)
6269
}
63-
placeholder={`${token.symbol} amount`}
70+
placeholder={placeholder || `${token.symbol} amount`}
6471
icon={icon}
6572
mb={2}
6673
max={maxTokenAmount}
@@ -88,7 +95,8 @@ export const TokenAmountForm = withFormik<TokenAmountFormProps, FormValues>({
8895

8996
errors.tokenAmount = validateAmountInRange(
9097
values.tokenAmount,
91-
props.maxTokenAmount.toString()
98+
props.maxTokenAmount.toString(),
99+
props.minTokenAmount ? props.minTokenAmount.toString() : DEFAULT_MIN_VALUE
92100
)
93101
return getErrorsObj(errors)
94102
},
@@ -100,4 +108,5 @@ export const TokenAmountForm = withFormik<TokenAmountFormProps, FormValues>({
100108

101109
TokenAmountForm.defaultProps = {
102110
shouldValidateForm: true,
111+
minTokenAmount: DEFAULT_MIN_VALUE,
103112
}

src/hooks/useMinStakeAmount.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { useEffect } from "react"
2+
import { useDispatch } from "react-redux"
3+
import { setMinStake } from "../store/staking"
4+
import { useTStakingContract } from "../web3/hooks"
5+
import { useStakingState } from "./useStakingState"
6+
7+
export const useMinStakeAmount = () => {
8+
const tStakingContract = useTStakingContract()
9+
const { minStakeAmount } = useStakingState()
10+
const dispatch = useDispatch()
11+
12+
useEffect(() => {
13+
const fetchMinStakeAmount = async () => {
14+
try {
15+
const minStakeAmount = await tStakingContract?.minTStakeAmount()
16+
dispatch(setMinStake({ amount: minStakeAmount.toString() }))
17+
} catch (error) {
18+
console.error("Could not fetch the min stake amount: ", error)
19+
}
20+
}
21+
if (minStakeAmount === "0" && tStakingContract) fetchMinStakeAmount()
22+
}, [tStakingContract, dispatch, minStakeAmount])
23+
24+
return minStakeAmount
25+
}

src/pages/Staking/StakedPortfolioCard.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ import { useModal } from "../../hooks/useModal"
1212
import { useTokenBalance } from "../../hooks/useTokenBalance"
1313
import { ModalType, Token } from "../../enums"
1414
import { formatTokenAmount } from "../../utils/formatAmount"
15+
import { useMinStakeAmount } from "../../hooks/useMinStakeAmount"
1516

1617
const StakedPortfolioCard: FC<ComponentProps<typeof Card>> = (props) => {
1718
const { openModal } = useModal()
1819
const tBalance = useTokenBalance(Token.T)
20+
const minStakeAmount = useMinStakeAmount()
1921

2022
const openStakingModal = async (stakeAmount: string) => {
2123
openModal(ModalType.StakingChecklist, { stakeAmount })
@@ -47,6 +49,12 @@ const StakedPortfolioCard: FC<ComponentProps<typeof Card>> = (props) => {
4749
label="Stake Amount"
4850
submitButtonText="Stake"
4951
maxTokenAmount={tBalance}
52+
placeholder={`Minimum stake ${
53+
minStakeAmount === "0"
54+
? "loading..."
55+
: `${formatTokenAmount(minStakeAmount)} T`
56+
}`}
57+
minTokenAmount={minStakeAmount}
5058
/>
5159
<StakingContractLearnMore mt="3" />
5260
</Card>

src/store/staking/stakingSlice.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ interface StakingState {
2424
stakedBalance: BigNumberish
2525
totalRewardsBalance: string
2626
totalBonusBalance: string
27+
minStakeAmount: string
2728
}
2829

2930
const calculateStakedBalance = (stakes: StakeData[]): BigNumberish => {
@@ -64,6 +65,7 @@ export const stakingSlice = createSlice({
6465
stakedBalance: 0,
6566
totalRewardsBalance: "0",
6667
totalBonusBalance: "0",
68+
minStakeAmount: "0",
6769
} as StakingState,
6870
reducers: {
6971
updateState: (state, action: PayloadAction<UpdateStateActionPayload>) => {
@@ -215,6 +217,12 @@ export const stakingSlice = createSlice({
215217
state.totalBonusBalance = calculateTotalBonusBalance(state.stakes)
216218
state.totalRewardsBalance = calculateTotalRewardsBalance(state)
217219
},
220+
setMinStake: (
221+
state: StakingState,
222+
action: PayloadAction<{ amount: string }>
223+
) => {
224+
state.minStakeAmount = action.payload.amount
225+
},
218226
},
219227
})
220228

@@ -224,4 +232,5 @@ export const {
224232
providerStaked,
225233
updateStakeAmountForProvider,
226234
unstaked,
235+
setMinStake,
227236
} = stakingSlice.actions

src/types/staking.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export interface UseStakingState {
2727
beneficiary: string
2828
authorizer: string
2929
updateState: (key: StakingStateKey, value: any) => UpdateState
30+
minStakeAmount: string
3031
}
3132
}
3233

src/utils/forms.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ type ValidationOptions = {
99
lessThanValidationMsg: ValidationMsg
1010
requiredMsg: string
1111
}
12-
const DEFAULT_MIN_VALUE = WeiPerEther.toString()
12+
export const DEFAULT_MIN_VALUE = WeiPerEther.toString()
1313

1414
const defaultLessThanMsg: ValidationMsg = (minAmount) => {
1515
return `The value should be less than or equal ${formatTokenAmount(

0 commit comments

Comments
 (0)