display pending undelegations

This commit is contained in:
fmtabbara
2022-03-22 10:24:14 +00:00
parent bec7814756
commit 2ad65fc455
8 changed files with 77 additions and 17 deletions
@@ -11,12 +11,11 @@ use tokio::sync::RwLock;
#[tauri::command]
pub async fn get_pending_delegation_events(
owner_address: String,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<Vec<DelegationEvent>, BackendError> {
Ok(
nymd_client!(state)
.get_pending_delegation_events(owner_address)
.get_pending_delegation_events(nymd_client!(state).address().to_string())
.await?
.into_iter()
.map(|delegation_event| delegation_event.into())
@@ -8,8 +8,8 @@ export const SuccessView: React.FC<{ details?: { amount: string; address: string
return (
<>
<SuccessReponse
title="Delegation Complete"
subtitle="Successfully delegated to node with following details"
title="Delegation Request Complete"
subtitle="Successfully requested delegation to node. Note it may take up to 1 hour to take effect "
caption={`Your current balance is: ${userBalance.balance?.printable_balance}`}
/>
{details && (
@@ -1,9 +1,20 @@
import React from 'react';
import { useForm, Controller } from 'react-hook-form';
import { Box, Autocomplete, Button, CircularProgress, FormControl, Grid, TextField } from '@mui/material';
import {
ListItem,
ListItemText,
Box,
Autocomplete,
Button,
CircularProgress,
FormControl,
Grid,
TextField,
} from '@mui/material';
import { yupResolver } from '@hookform/resolvers/yup';
import { addHours, format } from 'date-fns';
import { validationSchema } from './validationSchema';
import { EnumNodeType, TDelegation } from '../../types';
import { EnumNodeType, PendingUndelegate, TDelegation } from '../../types';
import { undelegate, vestingUnelegateFromMixnode } from '../../requests';
import { Fee } from '../../components';
@@ -19,10 +30,12 @@ const defaultValues = {
export const UndelegateForm = ({
delegations,
pendingUndelegations,
onError,
onSuccess,
}: {
delegations?: TDelegation[];
pendingUndelegations?: PendingUndelegate[];
onError: (message?: string) => void;
onSuccess: (message?: string) => void;
}) => {
@@ -50,9 +63,10 @@ export const UndelegateForm = ({
if (!res) {
onError('An error occurred when undelegating');
return;
}
onSuccess(`Successfully undelegated from ${res.target_address}`);
onSuccess(`Successfully requested undelegation from ${res.target_address}`);
} catch (e) {
onError(e as string);
}
@@ -69,8 +83,28 @@ export const UndelegateForm = ({
render={() => (
<Autocomplete
disabled={isSubmitting}
onChange={(_, value) => setValue('identity', value || '')}
getOptionDisabled={(opt) => pendingUndelegations?.some((item) => item.mix_identity === opt) || false}
options={delegations?.map((d) => d.node_identity) || []}
renderOption={(props, opt) => (
<ListItem
{...props}
onClick={(e: React.MouseEvent<HTMLLIElement>) => {
setValue('identity', opt);
props.onClick!(e);
}}
disablePadding
disableGutters
>
<ListItemText
primary={opt}
secondary={
pendingUndelegations?.some((item) => item.mix_identity === opt)
? `Pending - Expected time of completion: ${format(addHours(new Date(), 1), 'HH:00')}`
: undefined
}
/>
</ListItem>
)}
renderInput={(params) => (
<TextField
{...params}
+13 -4
View File
@@ -2,8 +2,8 @@ import React, { useContext, useEffect, useState } from 'react';
import { Alert, AlertTitle, Box, Button, CircularProgress } from '@mui/material';
import { EnumRequestStatus, NymCard, RequestStatus } from '../../components';
import { UndelegateForm } from './UndelegateForm';
import { getReverseMixDelegations } from '../../requests';
import { TPagedDelegations } from '../../types';
import { getCurrentEpoch, getPendingDelegations, getReverseMixDelegations } from '../../requests';
import { PendingUndelegate, TPagedDelegations } from '../../types';
import { ClientContext } from '../../context/main';
import { PageLayout } from '../../layouts';
@@ -12,6 +12,7 @@ export const Undelegate = () => {
const [status, setStatus] = useState<EnumRequestStatus>(EnumRequestStatus.initial);
const [isLoading, setIsLoading] = useState(true);
const [pagedDelegations, setPagesDelegations] = useState<TPagedDelegations>();
const [pendingUndelegations, setPendingUndelegations] = useState<PendingUndelegate[]>();
const { clientDetails } = useContext(ClientContext);
@@ -21,6 +22,14 @@ export const Undelegate = () => {
try {
const mixnodeDelegations = await getReverseMixDelegations();
const pendingEvents = await getPendingDelegations();
await getCurrentEpoch();
console.log({ mixnodeDelegations, pendingEvents });
const pendingUndelegationEvents = pendingEvents
.filter((evt): evt is { Undelegate: PendingUndelegate } => 'Undelegate' in evt)
.map((e) => ({ ...e.Undelegate }));
setPendingUndelegations(pendingUndelegationEvents);
setPagesDelegations(mixnodeDelegations);
} catch (e) {
setStatus(EnumRequestStatus.error);
@@ -52,6 +61,7 @@ export const Undelegate = () => {
{status === EnumRequestStatus.initial && pagedDelegations && (
<UndelegateForm
delegations={pagedDelegations?.delegations}
pendingUndelegations={pendingUndelegations}
onError={(m) => {
setMessage(m);
setStatus(EnumRequestStatus.error);
@@ -73,8 +83,7 @@ export const Undelegate = () => {
}
Success={
<Alert severity="success">
{' '}
<AlertTitle data-testid="undelegate-success">Undelegation complete</AlertTitle>
<AlertTitle data-testid="undelegate-success">Undelegation request complete</AlertTitle>
{message}
</Alert>
}
+12
View File
@@ -1,4 +1,5 @@
import { invoke } from '@tauri-apps/api';
import { DelegationEvent } from 'src/types/rust/delegationevent';
import {
Balance,
Coin,
@@ -21,6 +22,11 @@ export const getReverseGatewayDelegations = async (): Promise<TPagedDelegations>
return res;
};
export const getPendingDelegations = async (): Promise<DelegationEvent[]> => {
const res: DelegationEvent[] = await invoke('get_pending_delegation_events');
return res;
};
export const getMixnodeBondDetails = async (): Promise<TMixnodeBondDetails | null> => {
const res: TMixnodeBondDetails = await invoke('mixnode_bond_details');
return res;
@@ -67,3 +73,9 @@ export const userBalance = async (): Promise<Balance> => {
const res: Balance = await invoke('get_balance');
return res;
};
export const getCurrentEpoch = async (): Promise<any> => {
const res: any = await invoke('get_current_epoch');
console.log(res);
return res;
};
+3 -3
View File
@@ -1,4 +1,4 @@
import type { DelegationResult } from "./delegationresult";
import type { PendingUndelegate } from "./pendingundelegate";
import type { DelegationResult } from './delegationresult';
import type { PendingUndelegate } from './pendingundelegate';
export type DelegationEvent = { Delegate: DelegationResult } | { Undelegate: PendingUndelegate };
export type DelegationEvent = { Delegate: DelegationResult } | { Undelegate: PendingUndelegate };
+2
View File
@@ -20,3 +20,5 @@ export * from './transactiondetails';
export * from './vestingaccountinfo';
export * from './pledgedata';
export * from './vestingperiod';
export * from './pendingundelegate';
export * from './delegationevent';
@@ -1,2 +1,6 @@
export interface PendingUndelegate { mix_identity: string, delegate: string, proxy: string | null, block_height: bigint, }
export interface PendingUndelegate {
mix_identity: string;
delegate: string;
proxy: string | null;
block_height: bigint;
}