Add confirmation models
This commit is contained in:
@@ -1,29 +1,25 @@
|
||||
import React, { useCallback, useContext, useState, useEffect, ChangeEvent } from 'react';
|
||||
import React, { useState, useEffect, ChangeEvent } from 'react';
|
||||
import { Box, Typography, SxProps, TextField } from '@mui/material';
|
||||
import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField';
|
||||
import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField';
|
||||
import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation, Coin } from '@nymproject/types';
|
||||
|
||||
import { CurrencyDenom, DecCoin } from '@nymproject/types';
|
||||
import { SimpleModal } from './SimpleModal';
|
||||
import { ModalListItem } from './ModalListItem';
|
||||
|
||||
import { TPoolOption, validateAmount } from '../utils';
|
||||
|
||||
import { Console, urls, validateAmount } from '../utils';
|
||||
import { useChain } from '@cosmos-kit/react';
|
||||
import { StdFee } from '@cosmjs/amino';
|
||||
import { ExecuteResult } from '@cosmjs/cosmwasm-stargate';
|
||||
|
||||
import { uNYMtoNYM } from '../utils';
|
||||
import { ErrorModal } from './ErrorModal';
|
||||
import { DelegationModalProps } from './DelegationModal';
|
||||
|
||||
const MIN_AMOUNT_TO_DELEGATE = 10;
|
||||
const MIXNET_CONTRACT_ADDRESS = 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr';
|
||||
const sandboxContractAddress = 'n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav';
|
||||
// const sandboxContractAddress = 'n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav';
|
||||
|
||||
export const DelegateModal: FCWithChildren<{
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onOk?: () => void;
|
||||
onOk?: (delegationModalProps: DelegationModalProps) => void;
|
||||
identityKey?: string;
|
||||
onIdentityKeyChanged?: (identityKey: string) => void;
|
||||
onAmountChanged?: (amount: string) => void;
|
||||
@@ -61,8 +57,10 @@ export const DelegateModal: FCWithChildren<{
|
||||
const [errorIdentityKey, setErrorIdentityKey] = useState<string>();
|
||||
const [mixIdError, setMixIdError] = useState<string>();
|
||||
const [cosmWasmSignerClient, setCosmWasmSignerClient] = useState<any>();
|
||||
|
||||
// const { fee, getFee, resetFeeState, feeError } = useGetFee();
|
||||
const [balance, setBalance] = useState<{
|
||||
status: 'loading' | 'success';
|
||||
data?: string;
|
||||
}>({ status: 'loading', data: undefined });
|
||||
|
||||
const {
|
||||
username,
|
||||
@@ -77,11 +75,6 @@ export const DelegateModal: FCWithChildren<{
|
||||
estimateFee,
|
||||
} = useChain('nyx');
|
||||
|
||||
const [balance, setBalance] = useState<{
|
||||
status: 'loading' | 'success';
|
||||
data?: string;
|
||||
}>({ status: 'loading', data: undefined });
|
||||
|
||||
useEffect(() => {
|
||||
const getClient = async () => {
|
||||
await getSigningCosmWasmClient()
|
||||
@@ -95,15 +88,14 @@ export const DelegateModal: FCWithChildren<{
|
||||
isWalletConnected && getClient();
|
||||
}, [isWalletConnected]);
|
||||
|
||||
const getBalance = async (walletAddress: string) => {
|
||||
const account = await getCosmWasmClient();
|
||||
const uNYMBalance = await account.getBalance(walletAddress, 'unym');
|
||||
const NYMBalance = uNYMtoNYM(uNYMBalance.amount).asString();
|
||||
|
||||
setBalance({ status: 'success', data: NYMBalance });
|
||||
};
|
||||
useEffect(() => {
|
||||
const getBalance = async (walletAddress: string) => {
|
||||
const account = await getCosmWasmClient();
|
||||
const uNYMBalance = await account.getBalance(walletAddress, 'unym');
|
||||
const NYMBalance = uNYMtoNYM(uNYMBalance.amount).asString();
|
||||
|
||||
setBalance({ status: 'success', data: NYMBalance });
|
||||
};
|
||||
|
||||
if (address) {
|
||||
getBalance(address);
|
||||
}
|
||||
@@ -182,14 +174,32 @@ export const DelegateModal: FCWithChildren<{
|
||||
const fee = { gas: '1000000', amount: [{ amount: '25000', denom: 'unym' }] };
|
||||
|
||||
if (mixId && amount && onOk && cosmWasmSignerClient) {
|
||||
console.log('trying to delegate :>> ');
|
||||
console.log('balance.data :>> ', balance.data);
|
||||
onOk();
|
||||
console.log('amount :>> ', amount);
|
||||
console.log('fee :>> ', fee);
|
||||
await delegateToMixnode({ mixId }, fee, memo, [amount])
|
||||
.then((res) => console.log('res :>> ', res))
|
||||
.catch((err) => console.log('err :>> ', err));
|
||||
onOk({
|
||||
status: 'loading',
|
||||
action: 'delegate',
|
||||
});
|
||||
try {
|
||||
await delegateToMixnode({ mixId }, fee, memo, [amount]).then((res) => {
|
||||
console.log('res :>> ', res);
|
||||
});
|
||||
const tx = await delegateToMixnode({ mixId }, fee, memo, [amount]);
|
||||
|
||||
onOk({
|
||||
status: 'success',
|
||||
action: 'delegate',
|
||||
message: 'This operation can take up to one hour to process',
|
||||
transactions: [
|
||||
{ url: `${urls('MAINNET').blockExplorer}/transaction/${tx.transactionHash}`, hash: tx.transactionHash },
|
||||
],
|
||||
});
|
||||
} catch (e) {
|
||||
Console.error('Failed to addDelegation', e);
|
||||
onOk({
|
||||
status: 'error',
|
||||
action: 'delegate',
|
||||
message: (e as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -218,39 +228,6 @@ export const DelegateModal: FCWithChildren<{
|
||||
validate();
|
||||
}, [amount, identityKey, mixId]);
|
||||
|
||||
// if (fee) {
|
||||
// return (
|
||||
// <ConfirmTx
|
||||
// open
|
||||
// header="Delegation details"
|
||||
// fee={fee}
|
||||
// onClose={onClose}
|
||||
// onPrev={resetFeeState}
|
||||
// onConfirm={handleOk}
|
||||
// >
|
||||
// {balance.data && fee?.amount?.amount && (
|
||||
// <Box sx={{ my: 2 }}>
|
||||
// <BalanceWarning fee={fee?.amount?.amount} tx={amount} />
|
||||
// </Box>
|
||||
// )}
|
||||
// <ModalListItem label="Node identity key" value={identityKey} divider />
|
||||
// <ModalListItem label="Amount" value={`${amount} ${denom.toUpperCase()}`} divider />
|
||||
// </ConfirmTx>
|
||||
// );
|
||||
// }
|
||||
|
||||
// if (feeError) {
|
||||
// return (
|
||||
// <ErrorModal
|
||||
// title="Something went wrong while calculating fee. Are you sure you entered a valid node address?"
|
||||
// message={feeError}
|
||||
// sx={sx}
|
||||
// open={open}
|
||||
// onClose={onClose}
|
||||
// />
|
||||
// );
|
||||
// }
|
||||
|
||||
return (
|
||||
<SimpleModal
|
||||
open={open}
|
||||
@@ -316,26 +293,6 @@ export const DelegateModal: FCWithChildren<{
|
||||
<ModalListItem label="Account balance" value={`${balance.data} NYM`} divider fontWeight={600} />
|
||||
</Box>
|
||||
|
||||
{/* <ModalListItem label="Rewards payout interval" value={rewardInterval} hidden divider /> */}
|
||||
{/* <ModalListItem
|
||||
label="Node profit margin"
|
||||
value={`${profitMarginPercentage ? `${profitMarginPercentage}%` : '-'}`}
|
||||
hidden={profitMarginPercentage === undefined}
|
||||
divider
|
||||
/>
|
||||
<ModalListItem
|
||||
label="Node avg. uptime"
|
||||
value={`${nodeUptimePercentage ? `${nodeUptimePercentage}%` : '-'}`}
|
||||
hidden={nodeUptimePercentage === undefined}
|
||||
divider
|
||||
/> */}
|
||||
|
||||
{/* <ModalListItem
|
||||
label="Node est. reward per epoch"
|
||||
value={`${estimatedReward} ${denom.toUpperCase()}`}
|
||||
hidden
|
||||
divider
|
||||
/> */}
|
||||
<ModalListItem label="Est. fee for this transaction will be calculated in the next page" />
|
||||
</SimpleModal>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import React from 'react';
|
||||
import { Typography, SxProps, Stack } from '@mui/material';
|
||||
import { Link } from '@nymproject/react/link/Link';
|
||||
import { LoadingModal } from './LoadingModal';
|
||||
import { ConfirmationModal } from './ConfirmationModal';
|
||||
import { ErrorModal } from './ErrorModal';
|
||||
|
||||
export type ActionType = 'delegate' | 'undelegate' | 'redeem' | 'redeem-all' | 'compound';
|
||||
|
||||
const actionToHeader = (action: ActionType): string => {
|
||||
// eslint-disable-next-line default-case
|
||||
switch (action) {
|
||||
case 'redeem':
|
||||
return 'Rewards redeemed successfully';
|
||||
case 'redeem-all':
|
||||
return 'All rewards redeemed successfully';
|
||||
case 'delegate':
|
||||
return 'Delegation successful';
|
||||
case 'undelegate':
|
||||
return 'Undelegation successful';
|
||||
case 'compound':
|
||||
return 'Rewards compounded successfully';
|
||||
default:
|
||||
throw new Error('Unknown type');
|
||||
}
|
||||
};
|
||||
|
||||
export type DelegationModalProps = {
|
||||
status: 'loading' | 'success' | 'error';
|
||||
action: ActionType;
|
||||
message?: string;
|
||||
transactions?: {
|
||||
url: string;
|
||||
hash: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
export const DelegationModal: FCWithChildren<
|
||||
DelegationModalProps & {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
sx?: SxProps;
|
||||
backdropProps?: object;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
> = ({ status, action, message, transactions, open, onClose, children, sx, backdropProps }) => {
|
||||
if (status === 'loading') return <LoadingModal sx={sx} backdropProps={backdropProps} />;
|
||||
|
||||
if (status === 'error') {
|
||||
return (
|
||||
<ErrorModal message={message} sx={sx} open={open} onClose={onClose}>
|
||||
{children}
|
||||
</ErrorModal>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ConfirmationModal
|
||||
open={open}
|
||||
onConfirm={onClose || (() => {})}
|
||||
title={actionToHeader(action)}
|
||||
confirmButton="Done"
|
||||
>
|
||||
<Stack alignItems="center" spacing={2} mb={0}>
|
||||
{message && <Typography>{message}</Typography>}
|
||||
{transactions?.length === 1 && (
|
||||
<Link href={transactions[0].url} target="_blank" sx={{ ml: 1 }} text="View on blockchain" noIcon />
|
||||
)}
|
||||
{transactions && transactions.length > 1 && (
|
||||
<Stack alignItems="center" spacing={1}>
|
||||
<Typography>View the transactions on blockchain:</Typography>
|
||||
{transactions.map(({ url, hash }) => (
|
||||
<Link href={url} target="_blank" sx={{ ml: 1 }} text={hash.slice(0, 6)} key={hash} noIcon />
|
||||
))}
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
</ConfirmationModal>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import { Box, CircularProgress, Modal, Stack, Typography, SxProps } from '@mui/material';
|
||||
|
||||
const modalStyle: SxProps = {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
width: 500,
|
||||
bgcolor: 'background.paper',
|
||||
boxShadow: 24,
|
||||
borderRadius: '16px',
|
||||
p: 4,
|
||||
};
|
||||
|
||||
export const LoadingModal: FCWithChildren<{
|
||||
text?: string;
|
||||
sx?: SxProps;
|
||||
backdropProps?: object;
|
||||
}> = ({ sx, backdropProps, text = 'Please wait...' }) => (
|
||||
<Modal open BackdropProps={backdropProps}>
|
||||
<Box sx={{ border: (t) => `1px solid grey`, ...modalStyle, ...sx }} textAlign="center">
|
||||
<Stack spacing={4} direction="row" alignItems="center">
|
||||
<CircularProgress />
|
||||
<Typography sx={{ color: 'text.primary' }}>{text}</Typography>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Modal>
|
||||
);
|
||||
@@ -6,6 +6,7 @@ import { add, format, fromUnixTime } from 'date-fns';
|
||||
import { DecCoin, isValidRawCoin, MixNodeCostParams } from '@nymproject/types';
|
||||
import { getCurrentInterval, getDefaultMixnodeCostParams, getLockedCoins, getSpendableCoins } from '../requests';
|
||||
import { Console } from './console';
|
||||
import { Network } from '../types';
|
||||
|
||||
export type TPoolOption = 'balance' | 'locked';
|
||||
|
||||
@@ -253,3 +254,15 @@ export const getIntervalAsDate = async () => {
|
||||
|
||||
return { nextEpoch, nextInterval };
|
||||
};
|
||||
|
||||
export const urls = (networkName?: Network) =>
|
||||
networkName === 'MAINNET'
|
||||
? {
|
||||
mixnetExplorer: 'https://mixnet.explorers.guru/',
|
||||
blockExplorer: 'https://blocks.nymtech.net',
|
||||
networkExplorer: 'https://explorer.nymtech.net',
|
||||
}
|
||||
: {
|
||||
blockExplorer: `https://${networkName}-blocks.nymtech.net`,
|
||||
networkExplorer: `https://${networkName}-explorer.nymtech.net`,
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ import { DelegateModal } from './Delegations/components/DelegateModal';
|
||||
import { ChainProvider } from '@cosmos-kit/react';
|
||||
import { assets, chains } from 'chain-registry';
|
||||
import { wallets as keplr } from '@cosmos-kit/keplr';
|
||||
import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation, Coin } from '@nymproject/types';
|
||||
import { DelegationModal } from './Delegations/components/DelegationModal';
|
||||
|
||||
const fieldsHeight = '42.25px';
|
||||
|
||||
@@ -45,9 +45,9 @@ export const TableToolbar: FCWithChildren<TableToolBarProps> = ({
|
||||
const [confirmationModalProps, setConfirmationModalProps] = useState<DelegationModalProps | undefined>();
|
||||
|
||||
const assetsFixedUp = useMemo(() => {
|
||||
const nyx = assets.find((a) => a.chain_name === 'sandbox');
|
||||
const nyx = assets.find((a) => a.chain_name === 'nyx');
|
||||
if (nyx) {
|
||||
const nyxCoin = nyx.assets.find((a) => a.name === 'sandbox');
|
||||
const nyxCoin = nyx.assets.find((a) => a.name === 'nyx');
|
||||
if (nyxCoin) {
|
||||
nyxCoin.coingecko_id = 'nyx';
|
||||
}
|
||||
@@ -72,42 +72,10 @@ export const TableToolbar: FCWithChildren<TableToolBarProps> = ({
|
||||
return chains;
|
||||
}, [chains]);
|
||||
|
||||
const handleNewDelegation = () => {
|
||||
// setConfirmationModalProps({
|
||||
// status: 'loading',
|
||||
// action: 'delegate',
|
||||
// });
|
||||
const handleNewDelegation = (delegationModalProps: DelegationModalProps) => {
|
||||
setShowNewDelegationModal(false);
|
||||
// setCurrentDelegationListActionItem(undefined);
|
||||
// try {
|
||||
// const tx = await addDelegation(
|
||||
// {
|
||||
// mix_id,
|
||||
// amount,
|
||||
// },
|
||||
// tokenPool,
|
||||
// fee,
|
||||
// );
|
||||
|
||||
// const balances = await getAllBalances();
|
||||
|
||||
// setConfirmationModalProps({
|
||||
// status: 'success',
|
||||
// action: 'delegate',
|
||||
// message: 'This operation can take up to one hour to process',
|
||||
// ...balances,
|
||||
// transactions: [
|
||||
// { url: `${urls(network).blockExplorer}/transaction/${tx.transaction_hash}`, hash: tx.transaction_hash },
|
||||
// ],
|
||||
// });
|
||||
// } catch (e) {
|
||||
// Console.error('Failed to addDelegation', e);
|
||||
// setConfirmationModalProps({
|
||||
// status: 'error',
|
||||
// action: 'delegate',
|
||||
// message: (e as Error).message,
|
||||
// });
|
||||
// }
|
||||
console.log('res In Toolbar:>> ', delegationModalProps);
|
||||
setConfirmationModalProps(delegationModalProps);
|
||||
};
|
||||
|
||||
const isMobile = useIsMobile();
|
||||
@@ -200,12 +168,22 @@ export const TableToolbar: FCWithChildren<TableToolBarProps> = ({
|
||||
header="Delegate"
|
||||
buttonText="Delegate stake"
|
||||
denom={'nym'} // clientDetails?.display_mix_denom || 'nym'}
|
||||
onOk={handleNewDelegation}
|
||||
onOk={(delegationModalProps: DelegationModalProps) => handleNewDelegation(delegationModalProps)}
|
||||
// accountBalance={balance?.printable_balance}
|
||||
{...confirmationModalProps}
|
||||
/>
|
||||
</ChainProvider>
|
||||
)}
|
||||
|
||||
{confirmationModalProps && (
|
||||
<DelegationModal
|
||||
{...confirmationModalProps}
|
||||
open={Boolean(confirmationModalProps)}
|
||||
onClose={async () => {
|
||||
setConfirmationModalProps(undefined);
|
||||
// await fetchBalance();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user