diff --git a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs index d5cea12ec7..79f92eef64 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs @@ -11,12 +11,11 @@ use tokio::sync::RwLock; #[tauri::command] pub async fn get_pending_delegation_events( - owner_address: String, state: tauri::State<'_, Arc>>, ) -> Result, 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()) diff --git a/nym-wallet/src/pages/delegate/SuccessView.tsx b/nym-wallet/src/pages/delegate/SuccessView.tsx index 1f7fc21f63..d89b185d27 100644 --- a/nym-wallet/src/pages/delegate/SuccessView.tsx +++ b/nym-wallet/src/pages/delegate/SuccessView.tsx @@ -8,8 +8,8 @@ export const SuccessView: React.FC<{ details?: { amount: string; address: string return ( <> {details && ( diff --git a/nym-wallet/src/pages/undelegate/UndelegateForm.tsx b/nym-wallet/src/pages/undelegate/UndelegateForm.tsx index c09625bf91..ba148cd1ad 100644 --- a/nym-wallet/src/pages/undelegate/UndelegateForm.tsx +++ b/nym-wallet/src/pages/undelegate/UndelegateForm.tsx @@ -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={() => ( setValue('identity', value || '')} + getOptionDisabled={(opt) => pendingUndelegations?.some((item) => item.mix_identity === opt) || false} options={delegations?.map((d) => d.node_identity) || []} + renderOption={(props, opt) => ( + ) => { + setValue('identity', opt); + props.onClick!(e); + }} + disablePadding + disableGutters + > + item.mix_identity === opt) + ? `Pending - Expected time of completion: ${format(addHours(new Date(), 1), 'HH:00')}` + : undefined + } + /> + + )} renderInput={(params) => ( { const [status, setStatus] = useState(EnumRequestStatus.initial); const [isLoading, setIsLoading] = useState(true); const [pagedDelegations, setPagesDelegations] = useState(); + const [pendingUndelegations, setPendingUndelegations] = useState(); 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 && ( { setMessage(m); setStatus(EnumRequestStatus.error); @@ -73,8 +83,7 @@ export const Undelegate = () => { } Success={ - {' '} - Undelegation complete + Undelegation request complete {message} } diff --git a/nym-wallet/src/requests/queries.ts b/nym-wallet/src/requests/queries.ts index bcd9c40293..ab83cf9c66 100644 --- a/nym-wallet/src/requests/queries.ts +++ b/nym-wallet/src/requests/queries.ts @@ -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 return res; }; +export const getPendingDelegations = async (): Promise => { + const res: DelegationEvent[] = await invoke('get_pending_delegation_events'); + return res; +}; + export const getMixnodeBondDetails = async (): Promise => { const res: TMixnodeBondDetails = await invoke('mixnode_bond_details'); return res; @@ -67,3 +73,9 @@ export const userBalance = async (): Promise => { const res: Balance = await invoke('get_balance'); return res; }; + +export const getCurrentEpoch = async (): Promise => { + const res: any = await invoke('get_current_epoch'); + console.log(res); + return res; +}; diff --git a/nym-wallet/src/types/rust/delegationevent.ts b/nym-wallet/src/types/rust/delegationevent.ts index b1de3898db..35ba9f0cfb 100644 --- a/nym-wallet/src/types/rust/delegationevent.ts +++ b/nym-wallet/src/types/rust/delegationevent.ts @@ -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 }; \ No newline at end of file +export type DelegationEvent = { Delegate: DelegationResult } | { Undelegate: PendingUndelegate }; diff --git a/nym-wallet/src/types/rust/index.ts b/nym-wallet/src/types/rust/index.ts index 31f0b85833..89bb3211c2 100644 --- a/nym-wallet/src/types/rust/index.ts +++ b/nym-wallet/src/types/rust/index.ts @@ -20,3 +20,5 @@ export * from './transactiondetails'; export * from './vestingaccountinfo'; export * from './pledgedata'; export * from './vestingperiod'; +export * from './pendingundelegate'; +export * from './delegationevent'; diff --git a/nym-wallet/src/types/rust/pendingundelegate.ts b/nym-wallet/src/types/rust/pendingundelegate.ts index 54b4941b1d..70855568cf 100644 --- a/nym-wallet/src/types/rust/pendingundelegate.ts +++ b/nym-wallet/src/types/rust/pendingundelegate.ts @@ -1,2 +1,6 @@ - -export interface PendingUndelegate { mix_identity: string, delegate: string, proxy: string | null, block_height: bigint, } \ No newline at end of file +export interface PendingUndelegate { + mix_identity: string; + delegate: string; + proxy: string | null; + block_height: bigint; +}