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

feature: add delegation and undelegation flow #846

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fixed deploys tab and deploys details page for staking
ost-ptk committed Nov 7, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit b263908af7a4d0d0ee8400250154d1a5e2ec8767
29 changes: 20 additions & 9 deletions src/apps/popup/pages/activity-details/content.tsx
Original file line number Diff line number Diff line change
@@ -41,16 +41,17 @@ import {
} from '@libs/ui/utils/formatters';
import {
getBlockExplorerContractUrl,
TransferType,
TypeName
ActivityType,
ActivityTypeName,
AuctionManagerEntryPoint
} from '@src/constants';
import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors';

interface ActivityDetailsPageContentProps {
fromAccount?: string;
toAccount?: string;
deployInfo?: ExtendedDeploy | null;
type?: TransferType | null;
type?: ActivityType | null;
amount?: string | null;
symbol?: string | null;
}
@@ -80,8 +81,11 @@ const AddressContainer = styled(FlexColumn)`
padding: 16px 12px 16px 0;
`;

const AmountContainer = styled(AlignedSpaceBetweenFlexRow)`
padding: 8px 16px 8px 0;
const AmountContainer = styled(AlignedSpaceBetweenFlexRow)<{
emptyAmount?: boolean;
}>`
padding: ${({ emptyAmount }) =>
emptyAmount ? '16px 16px 16px 0' : '8px 16px 8px 0'};
`;

const RowsContainer = styled(FlexColumn)<BorderBottomPseudoElementProps>`
@@ -117,7 +121,10 @@ export const ActivityDetailsPageContent = ({
[Erc20EventType.erc20_transfer_from]: t('Transfer from'),
[Erc20EventType.erc20_approve]: t('Approve of'),
[Erc20EventType.erc20_burn]: t('Burn of'),
[Erc20EventType.erc20_mint]: t('Mint of')
[Erc20EventType.erc20_mint]: t('Mint of'),
[AuctionManagerEntryPoint.delegate]: t('Delegate with'),
[AuctionManagerEntryPoint.undelegate]: t('Undelegate with'),
[AuctionManagerEntryPoint.redelegate]: t('Redelegate with')
};

const decimals = deployInfo.contractPackage?.metadata?.decimals;
@@ -173,7 +180,7 @@ export const ActivityDetailsPageContent = ({
<ContentContainer>
<ParagraphContainer top={SpacingSize.XL}>
<Typography type="header">
{type && <Trans t={t}>{TypeName[type]}</Trans>}
{type && <Trans t={t}>{ActivityTypeName[type]}</Trans>}
</Typography>
</ParagraphContainer>
<Tile>
@@ -285,7 +292,11 @@ export const ActivityDetailsPageContent = ({
}
/>
<Typography type="captionRegular">
<Trans t={t}>contract</Trans>
<Trans t={t}>
{deployInfo.contractPackage.contract_name === 'Auction'
? 'System Contract'
: 'contract'}
</Trans>
</Typography>
</AlignedFlexRow>
</RightAlignedFlexColumn>
@@ -295,7 +306,7 @@ export const ActivityDetailsPageContent = ({
</Typography>
)}
</ItemContainer>
<AmountContainer>
<AmountContainer emptyAmount={formattedTransferAmount === '-'}>
<Typography type="captionRegular" color="contentSecondary">
<Trans t={t}>Amount</Trans>
</Typography>
39 changes: 17 additions & 22 deletions src/apps/popup/pages/stakes/amount-step.tsx
Original file line number Diff line number Diff line change
@@ -19,15 +19,9 @@ import {
selectAccountBalance,
selectAccountCurrencyRate
} from '@background/redux/account-info/selectors';
import { STAKE_COST_MOTES } from '@src/constants';
import { AuctionManagerEntryPoint } from '@libs/services/deployer-service';

const StakeMaxButton = styled.div`
background: ${({ theme }) => theme.color.backgroundPrimary};
border-radius: ${({ theme }) => theme.borderRadius.base}px;

padding: 4px 12px;
import { AuctionManagerEntryPoint, STAKE_COST_MOTES } from '@src/constants';

const StakeMaxButton = styled(AlignedFlexRow)`
cursor: pointer;
`;

@@ -37,7 +31,7 @@ interface AmountStepProps {
stakeAmountMotes: string;
headerText: string;
amountStepText: string;
amountStepMaxButtonText: string;
amountStepMaxAmountValue: string | null;
}

export const AmountStep = ({
@@ -46,7 +40,7 @@ export const AmountStep = ({
stakeAmountMotes,
headerText,
amountStepText,
amountStepMaxButtonText
amountStepMaxAmountValue
}: AmountStepProps) => {
const [maxAmountMotes, setMaxAmountMotes] = useState('0');

@@ -117,21 +111,22 @@ export const AmountStep = ({
/>
</VerticalSpaceContainer>
<ParagraphContainer top={SpacingSize.Small}>
<AlignedFlexRow gap={SpacingSize.Small}>
<Typography type="captionRegular" color="contentSecondary">
<Trans t={t}>{amountStepText}</Trans>
<StakeMaxButton
gap={SpacingSize.Small}
onClick={() => {
setValue('amount', motesToCSPR(maxAmountMotes));
trigger('amount');
}}
>
<Typography type="captionRegular" color="contentAction">
{amountStepText}
</Typography>
<StakeMaxButton
onClick={() => {
setValue('amount', motesToCSPR(maxAmountMotes));
trigger('amount');
}}
>
{amountStepMaxAmountValue && (
<Typography type="captionHash" color="contentAction">
{amountStepMaxButtonText}
{amountStepMaxAmountValue}
</Typography>
</StakeMaxButton>
</AlignedFlexRow>
)}
</StakeMaxButton>
</ParagraphContainer>
{errors.amount && (
<VerticalSpaceContainer top={SpacingSize.XL}>
6 changes: 2 additions & 4 deletions src/apps/popup/pages/stakes/confirm-step.tsx
Original file line number Diff line number Diff line change
@@ -19,10 +19,8 @@ import {
} from '@libs/ui/utils/formatters';
import { selectAccountCurrencyRate } from '@background/redux/account-info/selectors';
import { ValidatorResult } from '@libs/services/validators-service/types';
import {
AuctionManagerEntryPoint,
getAuctionManagerDeployCost
} from '@libs/services/deployer-service';
import { getAuctionManagerDeployCost } from '@libs/services/deployer-service';
import { AuctionManagerEntryPoint } from '@src/constants';

export const ListItemContainer = styled(SpaceBetweenFlexRow)`
padding: 12px 16px;
17 changes: 9 additions & 8 deletions src/apps/popup/pages/stakes/content.tsx
Original file line number Diff line number Diff line change
@@ -9,9 +9,8 @@ import {
} from '@libs/ui/forms/stakes-form';
import { ConfirmStep } from '@popup/pages/stakes/confirm-step';
import { TransferSuccessScreen, ValidatorDropdownInput } from '@libs/ui';
import { StakeSteps } from '@src/constants';
import { AuctionManagerEntryPoint, StakeSteps } from '@src/constants';
import { ValidatorResultWithId } from '@libs/services/validators-service/types';
import { AuctionManagerEntryPoint } from '@libs/services/deployer-service';
import { formatNumber, motesToCSPR } from '@libs/ui/utils/formatters';

interface DelegateStakePageContentProps {
@@ -47,11 +46,14 @@ export const StakesPageContent = ({
const [successStepHeaderText, setSuccessStepHeaderText] = useState('');
const [confirmStepText, setConfirmStepText] = useState('');
const [amountStepText, setAmountStepText] = useState('');
const [amountStepMaxButtonText, setAmountStepMaxButtonText] = useState('');
const [amountStepMaxAmountValue, setAmountStepMaxAmountValue] = useState<
string | null
>(null);

useEffect(() => {
const formattedAmountCSPR =
stakeAmountMotes && formatNumber(motesToCSPR(stakeAmountMotes));
stakeAmountMotes &&
formatNumber(motesToCSPR(stakeAmountMotes), { precision: { max: 4 } });

switch (stakesType) {
case AuctionManagerEntryPoint.delegate: {
@@ -60,8 +62,7 @@ export const StakesPageContent = ({
setConfirmStepHeaderText('Confirm delegation');
setSuccessStepHeaderText('You’ve submitted a delegation');

setAmountStepText('Delegate:');
setAmountStepMaxButtonText('Max');
setAmountStepText('Delegate max');
setConfirmStepText('You’ll delegate');
break;
}
@@ -72,7 +73,7 @@ export const StakesPageContent = ({
setSuccessStepHeaderText('You’ve submitted an undelegation');

setAmountStepText('Undelegate max:');
setAmountStepMaxButtonText(`${formattedAmountCSPR} CSPR`);
setAmountStepMaxAmountValue(`${formattedAmountCSPR} CSPR`);
setConfirmStepText('You’ll undelegate');
break;
}
@@ -105,7 +106,7 @@ export const StakesPageContent = ({
stakeAmountMotes={stakeAmountMotes}
headerText={amountStepHeaderText}
amountStepText={amountStepText}
amountStepMaxButtonText={amountStepMaxButtonText}
amountStepMaxAmountValue={amountStepMaxAmountValue}
/>
);
}
11 changes: 6 additions & 5 deletions src/apps/popup/pages/stakes/index.tsx
Original file line number Diff line number Diff line change
@@ -18,14 +18,15 @@ import { Button, HomePageTabsId, Typography } from '@libs/ui';
import { selectVaultActiveAccount } from '@background/redux/vault/selectors';
import { createAsymmetricKey } from '@libs/crypto/create-asymmetric-key';
import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors';
import { STAKE_COST_MOTES, StakeSteps } from '@src/constants';
import {
AuctionManagerEntryPoint,
STAKE_COST_MOTES,
StakeSteps
} from '@src/constants';
import { dispatchToMainStore } from '@background/redux/utils';
import { accountPendingTransactionsChanged } from '@background/redux/account-info/actions';
import { dispatchFetchExtendedDeploysInfo } from '@libs/services/account-activity-service';
import {
AuctionManagerEntryPoint,
makeAuctionManagerDeploy
} from '@libs/services/deployer-service';
import { makeAuctionManagerDeploy } from '@libs/services/deployer-service';
import { RouterPath, useTypedLocation, useTypedNavigate } from '@popup/router';
import { useStakesForm } from '@libs/ui/forms/stakes-form';
import { selectAccountBalance } from '@background/redux/account-info/selectors';
4 changes: 2 additions & 2 deletions src/apps/popup/router/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TransferType } from '@src/constants';
import { ActivityType } from '@src/constants';
import { TokenType } from '@src/hooks';

export type LocationState = {
@@ -7,7 +7,7 @@ export type LocationState = {
fromAccount: string;
toAccount: string;
deployHash: string;
type: TransferType | null;
type: ActivityType | null;
amount?: string;
symbol?: string;
isDeploysList?: boolean;
3 changes: 3 additions & 0 deletions src/assets/icons/burn.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 54 additions & 18 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -86,34 +86,59 @@ export enum AuctionManagerContractHash {
Testnet = '93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2'
}

export enum TransferType {
export enum ActivityType {
Sent = 'Sent',
Received = 'Received',
Unknown = 'Unknown'
Unknown = 'Unknown',
Delegated = 'Delegated',
Undelegated = 'Undelegated',
Redelegated = 'Redelegated',
Mint = 'Mint',
Burn = 'Burn'
}

export const ShortTypeName = {
[TransferType.Sent]: 'Sent',
[TransferType.Received]: 'Recv',
[TransferType.Unknown]: 'Unk'
export const ActivityShortTypeName = {
[ActivityType.Sent]: 'Sent',
[ActivityType.Received]: 'Recv',
[ActivityType.Unknown]: 'Unk',
[ActivityType.Delegated]: 'Deleg',
[ActivityType.Undelegated]: 'Undeleg',
[ActivityType.Redelegated]: 'Redeleg',
[ActivityType.Mint]: 'Mint',
[ActivityType.Burn]: 'Burn'
};

export const TypeName = {
[TransferType.Sent]: 'Sent',
[TransferType.Received]: 'Received',
[TransferType.Unknown]: 'Unknown'
export const ActivityTypeName = {
[ActivityType.Sent]: 'Sent',
[ActivityType.Received]: 'Received',
[ActivityType.Unknown]: 'Unknown',
[ActivityType.Delegated]: 'Delegated',
[ActivityType.Undelegated]: 'Undelegated',
[ActivityType.Redelegated]: 'Redelegated',
[ActivityType.Mint]: 'Mint',
[ActivityType.Burn]: 'Burn'
};

export const TypeIcons = {
[TransferType.Sent]: 'assets/icons/transfer.svg',
[TransferType.Received]: 'assets/icons/receive.svg',
[TransferType.Unknown]: 'assets/icons/info.svg'
export const ActivityTypeIcons = {
[ActivityType.Sent]: 'assets/icons/transfer.svg',
[ActivityType.Received]: 'assets/icons/receive.svg',
[ActivityType.Unknown]: 'assets/icons/info.svg',
[ActivityType.Delegated]: 'assets/icons/delegate.svg',
[ActivityType.Undelegated]: 'assets/icons/undelegate.svg',
[ActivityType.Redelegated]: 'assets/icons/undelegate.svg',
[ActivityType.Mint]: 'assets/icons/info.svg',
[ActivityType.Burn]: 'assets/icons/burn.svg'
};

export const TypeColors = {
[TransferType.Sent]: 'contentAction',
[TransferType.Received]: 'contentPositive',
[TransferType.Unknown]: 'contentDisabled'
export const ActivityTypeColors = {
[ActivityType.Sent]: 'contentAction',
[ActivityType.Received]: 'contentPositive',
[ActivityType.Unknown]: 'contentDisabled',
[ActivityType.Delegated]: 'contentAction',
[ActivityType.Undelegated]: 'contentAction',
[ActivityType.Redelegated]: 'contentAction',
[ActivityType.Mint]: 'contentDisabled',
[ActivityType.Burn]: 'contentAction'
};

export enum HomePageTabName {
@@ -128,3 +153,14 @@ export enum StakeSteps {
Confirm = 'confirm',
Success = 'success'
}

export enum AuctionManagerEntryPoint {
delegate = 'delegate',
undelegate = 'undelegate',
redelegate = 'redelegate'
}

export enum TokenEntryPoint {
mint = 'mint',
burn = 'burn'
}
1 change: 1 addition & 0 deletions src/libs/services/account-activity-service/types.ts
Original file line number Diff line number Diff line change
@@ -52,6 +52,7 @@ export type ExtendedDeployArgsResult = {
to?: ExtendedDeployClTypeResult;
validator?: ExtendedDeployClTypeResult;
new_validator?: ExtendedDeployClTypeResult;
delegator?: ExtendedDeployClTypeResult;
};

export interface ExtendedDeployResult {
8 changes: 1 addition & 7 deletions src/libs/services/deployer-service/index.ts
Original file line number Diff line number Diff line change
@@ -10,18 +10,12 @@ import { sub } from 'date-fns';

import { signDeploy } from '@libs/crypto';
import { getRawPublicKey } from '@libs/entities/Account';
import { STAKE_COST_MOTES } from '@src/constants';
import { AuctionManagerEntryPoint, STAKE_COST_MOTES } from '@src/constants';

import { RPCResponse } from './types';

const casperService = (url: string) => new CasperServiceByJsonRPC(url);

export enum AuctionManagerEntryPoint {
delegate = 'delegate',
undelegate = 'undelegate',
redelegate = 'redelegate'
}

export const getAuctionManagerDeployCost = (
entryPoint: AuctionManagerEntryPoint
) => {
Original file line number Diff line number Diff line change
@@ -6,12 +6,12 @@ import styled from 'styled-components';
import {
AccountActivityPlateContainer,
ActivityPlateContentContainer,
ActivityPlateDivider,
ActivityPlateIconCircleContainer,
AlignedFlexRow,
AlignedSpaceBetweenFlexRow,
ActivityPlateIconCircleContainer,
ActivityPlateDivider,
SpacingSize,
RightAlignedCenteredFlexRow
RightAlignedCenteredFlexRow,
SpacingSize
} from '@libs/layout';
import {
ContentColor,
@@ -36,11 +36,13 @@ import {
} from '@libs/services/account-activity-service';
import { RouterPath, useTypedNavigate } from '@popup/router';
import {
ShortTypeName,
TransferType,
TypeColors,
TypeIcons,
TypeName
ActivityShortTypeName,
ActivityType,
ActivityTypeColors,
ActivityTypeIcons,
ActivityTypeName,
AuctionManagerEntryPoint,
TokenEntryPoint
} from '@src/constants';
import { getAccountHashFromPublicKey } from '@libs/entities/Account';
import { getRecipientAddressFromTransaction } from '@libs/ui/utils/utils';
@@ -59,7 +61,11 @@ type Ref = HTMLDivElement;

export const AccountActivityPlate = forwardRef<Ref, AccountActivityPlateProps>(
({ transactionInfo, onClick, isDeploysList }, ref) => {
const [type, setType] = useState<TransferType | null>(null);
const [type, setType] = useState<ActivityType | null>(null);
const [fromAccount, setFromAccount] = useState<string | undefined>(
undefined
);
const [toAccount, setToAccount] = useState<string | undefined>(undefined);

const navigate = useTypedNavigate();
const { t } = useTranslation();
@@ -119,21 +125,57 @@ export const AccountActivityPlate = forwardRef<Ref, AccountActivityPlateProps>(
: '-';

useEffect(() => {
if ('entryPoint' in transactionInfo) {
switch (transactionInfo.entryPoint?.name) {
case AuctionManagerEntryPoint.undelegate: {
setType(ActivityType.Undelegated);
setFromAccount(transactionInfo.args.validator?.parsed as string);
setToAccount(transactionInfo.args.delegator?.parsed as string);
return;
}
case AuctionManagerEntryPoint.delegate: {
setType(ActivityType.Delegated);
setFromAccount(transactionInfo.args.delegator?.parsed as string);
setToAccount(transactionInfo.args.validator?.parsed as string);
return;
}
case AuctionManagerEntryPoint.redelegate: {
setType(ActivityType.Redelegated);
setFromAccount(transactionInfo.args.validator?.parsed as string);
setToAccount(transactionInfo.args.new_validator?.parsed as string);
return;
}
case TokenEntryPoint.mint: {
setType(ActivityType.Mint);
setFromAccount(transactionInfo.callerPublicKey);
setToAccount(recipientAddress);
return;
}
case TokenEntryPoint.burn: {
setType(ActivityType.Burn);
setFromAccount(transactionInfo.callerPublicKey);
setToAccount(undefined);
return;
}
}
}

if (fromAccountPublicKey === activeAccount?.publicKey) {
setType(TransferType.Sent);
setType(ActivityType.Sent);
} else if (
recipientAddress === activeAccount?.publicKey ||
recipientAddress === activeAccountHash
) {
setType(TransferType.Received);
setType(ActivityType.Received);
} else {
setType(TransferType.Unknown);
setType(ActivityType.Unknown);
}
}, [
fromAccountPublicKey,
activeAccount?.publicKey,
recipientAddress,
activeAccountHash
activeAccountHash,
transactionInfo
]);

return (
@@ -144,8 +186,8 @@ export const AccountActivityPlate = forwardRef<Ref, AccountActivityPlateProps>(
navigate(RouterPath.ActivityDetails, {
state: {
activityDetailsData: {
fromAccount: fromAccountPublicKey,
toAccount: recipientAddress,
fromAccount: fromAccount || fromAccountPublicKey,
toAccount: toAccount || recipientAddress,
deployHash,
type,
amount: formattedAmount,
@@ -162,9 +204,9 @@ export const AccountActivityPlate = forwardRef<Ref, AccountActivityPlateProps>(
<ActivityPlateIconCircleContainer>
{type != null && (
<SvgIcon
src={TypeIcons[type]}
src={ActivityTypeIcons[type]}
size={16}
color={TypeColors[type] as ContentColor}
color={ActivityTypeColors[type] as ContentColor}
/>
)}
</ActivityPlateIconCircleContainer>
@@ -175,8 +217,8 @@ export const AccountActivityPlate = forwardRef<Ref, AccountActivityPlateProps>(
<Trans t={t}>
{type != null &&
(formattedAmount.length >= 13
? ShortTypeName[type]
: TypeName[type])}
? ActivityShortTypeName[type]
: ActivityTypeName[type])}
</Trans>
</Typography>
<DeployStatus deployResult={transactionInfo} />
@@ -186,7 +228,9 @@ export const AccountActivityPlate = forwardRef<Ref, AccountActivityPlateProps>(
formattedAmount
) : (
<>
{type === TransferType.Sent ? '-' : ''}
{type === ActivityType.Sent || type === ActivityType.Delegated
? '-'
: ''}
{formattedAmount}
</>
)}
Original file line number Diff line number Diff line change
@@ -28,11 +28,11 @@ import {
SpacingSize
} from '@libs/layout';
import {
ShortTypeName,
TransferType,
TypeColors,
TypeIcons,
TypeName
ActivityShortTypeName,
ActivityType,
ActivityTypeColors,
ActivityTypeIcons,
ActivityTypeName
} from '@src/constants';
import { TransferResultWithId } from '@libs/services/account-activity-service';
import { getAccountHashFromPublicKey } from '@libs/entities/Account';
@@ -47,7 +47,7 @@ export const AccountCasperActivityPlate = forwardRef<
Ref,
AccountCasperActivityPlateProps
>(({ transactionInfo, onClick }, ref) => {
const [type, setType] = useState<TransferType | null>(null);
const [type, setType] = useState<ActivityType | null>(null);

const navigate = useTypedNavigate();
const { t } = useTranslation();
@@ -77,14 +77,14 @@ export const AccountCasperActivityPlate = forwardRef<
fromAccountPublicKey === activeAccount?.publicKey ||
fromAccount === activeAccountHash
) {
setType(TransferType.Sent);
setType(ActivityType.Sent);
} else if (
toAccountPublicKey === activeAccount?.publicKey ||
toAccount === activeAccountHash
) {
setType(TransferType.Received);
setType(ActivityType.Received);
} else {
setType(TransferType.Unknown);
setType(ActivityType.Unknown);
}
}, [
fromAccountPublicKey,
@@ -119,9 +119,9 @@ export const AccountCasperActivityPlate = forwardRef<
<ActivityPlateIconCircleContainer>
{type != null && (
<SvgIcon
src={TypeIcons[type]}
src={ActivityTypeIcons[type]}
size={16}
color={TypeColors[type] as ContentColor}
color={ActivityTypeColors[type] as ContentColor}
/>
)}
</ActivityPlateIconCircleContainer>
@@ -132,13 +132,13 @@ export const AccountCasperActivityPlate = forwardRef<
<Trans t={t}>
{type != null &&
(formattedAmount.length >= 13
? ShortTypeName[type]
: TypeName[type])}
? ActivityShortTypeName[type]
: ActivityTypeName[type])}
</Trans>
</Typography>
</AlignedFlexRow>
<Typography type="captionHash">
{type === TransferType.Sent ? '-' : ''}
{type === ActivityType.Sent ? '-' : ''}
{formattedAmount}
</Typography>
</AlignedSpaceBetweenFlexRow>
4 changes: 2 additions & 2 deletions src/libs/ui/components/hash/utils.ts
Original file line number Diff line number Diff line change
@@ -12,8 +12,8 @@ export function truncateKey(
break;
case 'small':
default:
beginOfKey = key.slice(0, 5);
endOfKey = key.slice(key.length - 5);
beginOfKey = key.slice(0, 4);
endOfKey = key.slice(key.length - 4);
break;

case 'medium':
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ import { SvgIcon, Input, List, ValidatorPlate, Typography } from '@libs/ui';
import { StakeValidatorFormValues } from '@libs/ui/forms/stakes-form';
import { useClickAway } from '@libs/ui/hooks/use-click-away';
import { ValidatorResultWithId } from '@libs/services/validators-service/types';
import { AuctionManagerEntryPoint } from '@libs/services/deployer-service';
import { AuctionManagerEntryPoint } from '@src/constants';

const DropDownHeader = styled(AlignedSpaceBetweenFlexRow)`
padding: 8px 16px;
@@ -199,7 +199,7 @@ export const ValidatorDropdownInput = ({
<Trans t={t}>Validator</Trans>
</Typography>
<Typography type="labelMedium" color="contentSecondary">
<Trans t={t}>Total stake & fee</Trans>
<Trans t={t}>Total stake, fee, delegators</Trans>
</Typography>
</DropDownHeader>
)}
29 changes: 21 additions & 8 deletions src/libs/ui/components/validator-plate/validator-plate.tsx
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ const ValidatorPlateContainer = styled(AlignedSpaceBetweenFlexRow)<{
`;

const NameContainer = styled(FlexColumn)`
max-width: 110px;
max-width: 93px;
`;

const IconContainer = styled.div`
@@ -84,6 +84,17 @@ export const ValidatorPlate = ({
const formattedFee = formatNumber(fee, {
precision: { min: 2 }
});
const getFormattedDelegatorsNumber = () => {
if (delegatorsNumber && delegatorsNumber >= 1000) {
return (
formatNumber(delegatorsNumber / 1000, {
precision: { max: 2 }
}) + 'k'
);
}

return delegatorsNumber;
};

const plateWithFullPublicKey = (
<ValidatorPlateContainer onClick={handleClick} withBackground>
@@ -140,15 +151,17 @@ export const ValidatorPlate = ({
</NameContainer>
</AlignedFlexRow>
<RightAlignedFlexColumn>
<Typography type="captionRegular" color="contentPrimary">
<Typography type="captionHash" color="contentPrimary">
{`${formattedTotalStake} CSPR`}
</Typography>
<Typography type="captionRegular" color="contentSecondary">
{`${formattedFee}% fee`}
</Typography>
<Typography type="captionRegular" color="contentSecondary">
{delegatorsNumber} delegators
</Typography>
<AlignedFlexRow gap={SpacingSize.Small}>
<Typography type="listSubtext" color="contentSecondary">
{`${formattedFee}% fee`}
</Typography>
<Typography type="listSubtext" color="contentSecondary">
{getFormattedDelegatorsNumber()} delegators
</Typography>
</AlignedFlexRow>
</RightAlignedFlexColumn>
</ValidatorPlateContainer>
);
4 changes: 2 additions & 2 deletions src/libs/ui/forms/form-validation-rules.ts
Original file line number Diff line number Diff line change
@@ -13,11 +13,11 @@ import {
LOGIN_RETRY_ATTEMPTS_LIMIT,
MAX_DELEGATORS,
TRANSFER_COST_MOTES,
TRANSFER_MIN_AMOUNT_MOTES
TRANSFER_MIN_AMOUNT_MOTES,
AuctionManagerEntryPoint
} from '@src/constants';
import { isValidPublicKey, isValidU64 } from '@src/utils';
import { CSPRtoMotes, motesToCSPR } from '@libs/ui/utils/formatters';
import { AuctionManagerEntryPoint } from '@libs/services/deployer-service';

export const minPasswordLength = 16;

2 changes: 1 addition & 1 deletion src/libs/ui/forms/stakes-form.ts
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ import {
useCSPRStakeAmountRule,
useValidatorPublicKeyRule
} from '@libs/ui/forms/form-validation-rules';
import { AuctionManagerEntryPoint } from '@libs/services/deployer-service';
import { AuctionManagerEntryPoint } from '@src/constants';

export type StakeValidatorFormValues = {
validatorPublicKey: string;