Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a notice before staking to top 20 validators to encourage decentralization #831

Merged
merged 1 commit into from May 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/components/AddEscrowForm/__tests__/index.test.tsx
Expand Up @@ -12,7 +12,7 @@ const renderComponent = (store: any, address: string, validatorStatus: Validator
render(
<Provider store={store}>
<ModalProvider>
<AddEscrowForm validatorAddress={address} validatorStatus={validatorStatus} />
<AddEscrowForm validatorAddress={address} validatorStatus={validatorStatus} validatorRank={21} />
</ModalProvider>
</Provider>,
)
Expand Down
70 changes: 45 additions & 25 deletions src/app/components/AddEscrowForm/index.tsx
Expand Up @@ -8,7 +8,7 @@ import { selectMinStaking } from 'app/state/network/selectors'
import { Validator } from 'app/state/staking/types'
import { transactionActions } from 'app/state/transaction'
import { selectTransaction } from 'app/state/transaction/selectors'
import { Box, Button, Form, TextInput } from 'grommet'
import { Box, Button, CheckBox, Form, TextInput } from 'grommet'
import React, { memo, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
Expand All @@ -18,12 +18,15 @@ import { TransactionStatus } from '../TransactionStatus'
interface Props {
validatorAddress: string
validatorStatus: Validator['status']
validatorRank: number
}

export const AddEscrowForm = memo((props: Props) => {
const { t } = useTranslation()
const { launchModal } = useModal()
const { error, success } = useSelector(selectTransaction)
const isTop20 = props.validatorRank <= 20
const [showNotice, setShowNotice] = useState(isTop20)
const [amount, setAmount] = useState('')
const dispatch = useDispatch()
const minStaking = useSelector(selectMinStaking)
Expand Down Expand Up @@ -61,30 +64,47 @@ export const AddEscrowForm = memo((props: Props) => {
}, [dispatch])

return (
<Form onSubmit={submit}>
<Box direction="row" gap="small" pad={{ top: 'small' }}>
<Box background="background-front">
<TextInput
data-testid="amount"
id="amount-id"
name="amount"
placeholder={t('common.amount')}
type="number"
step="any"
min={minStaking}
value={amount}
onChange={event => setAmount(event.target.value)}
required
<>
{showNotice && (
<p>
{t(
'account.addEscrow.confirmDelegatingToTop.description',
'This validator is ranked in the top 20 by stake. Please consider delegating to a smaller validator to increase network security and decentralization.',
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess more of a copy question for product, but my first instinct is the softer approach of prodding the user through giving them context.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it's fine :D

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's merge this as is and work on improving copy in a subsequent PR if necessary 🙂

)}
<CheckBox
label={t('account.addEscrow.confirmDelegatingToTop.acknowledge', 'Delegate anyway')}
checked={!showNotice}
onChange={event => setShowNotice(!event.target.checked)}
/>
</Box>
<Button
label={t('account.addEscrow.delegate', 'Delegate')}
type="submit"
primary
style={{ borderRadius: '4px' }}
/>
</Box>
<TransactionStatus error={error} success={success} />
</Form>
</p>
)}
{!showNotice && (
<Form onSubmit={submit}>
<Box direction="row" gap="small" pad={{ top: 'small' }}>
<Box background="background-front">
<TextInput
data-testid="amount"
id="amount-id"
name="amount"
placeholder={t('common.amount')}
type="number"
step="any"
min={minStaking}
value={amount}
onChange={event => setAmount(event.target.value)}
required
/>
</Box>
<Button
label={t('account.addEscrow.delegate', 'Delegate')}
type="submit"
primary
style={{ borderRadius: '4px' }}
/>
</Box>
<TransactionStatus error={error} success={success} />
</Form>
)}
</>
)
})
Expand Up @@ -19,7 +19,11 @@ export const ValidatorItem = (props: ValidatorProps) => {
<Box pad="medium" background="background-contrast" data-testid="validator-item">
<ValidatorInformations validator={validator} details={details} />
{isWalletOpen && (
<AddEscrowForm validatorAddress={validator.address} validatorStatus={validator.status} />
<AddEscrowForm
validatorAddress={validator.address}
validatorStatus={validator.status}
validatorRank={validator.rank}
/>
)}
</Box>
)
Expand Down
4 changes: 4 additions & 0 deletions src/locales/en/translation.json
Expand Up @@ -5,6 +5,10 @@
"description": "Status of this validator is {{validatorStatus}}. Your delegation might not generate any rewards.",
"title": "Are you sure you want to continue?"
},
"confirmDelegatingToTop": {
"acknowledge": "Delegate anyway",
"description": "This validator is ranked in the top 20 by stake. Please consider delegating to a smaller validator to increase network security and decentralization."
},
"delegate": "Delegate"
},
"loading": "Loading account",
Expand Down