set up compound rewards

This commit is contained in:
fmtabbara
2022-06-06 16:06:29 +01:00
parent bf91e8995a
commit 3e9aa02264
7 changed files with 142 additions and 47 deletions
@@ -142,14 +142,6 @@ export const DelegationsActionsMenu: React.FC<{
onClick={() => handleActionSelect?.('undelegate')}
disabled={false}
/>
<DelegationActionsMenuItem
title="Compound"
description="Add your rewards to this delegation"
Icon={<Typography sx={{ pl: 1 }}>C</Typography>}
onClick={() => handleActionSelect?.('compound')}
disabled={disableRedeemingRewards}
/>
<DelegationActionsMenuItem
title="Redeem"
description="Trasfer your rewards to your balance"
@@ -157,6 +149,13 @@ export const DelegationsActionsMenu: React.FC<{
onClick={() => handleActionSelect?.('redeem')}
disabled={disableRedeemingRewards}
/>
<DelegationActionsMenuItem
title="Compound"
description="Add your rewards to this delegation"
Icon={<Typography sx={{ pl: 1 }}>C</Typography>}
onClick={() => handleActionSelect?.('compound')}
disabled={disableRedeemingRewards}
/>
</Menu>
</>
);
@@ -1,6 +1,7 @@
import React from 'react';
import {
Box,
Chip,
CircularProgress,
Link,
Table,
@@ -172,10 +173,15 @@ export const DelegationList: React.FC<{
<DelegationsActionsMenu
isPending={undefined}
onActionClick={(action) => (onItemActionClick ? onItemActionClick(item, action) : undefined)}
disableRedeemingRewards={!item.accumulated_rewards}
disableRedeemingRewards={!item.accumulated_rewards || item.accumulated_rewards.amount === '0'}
/>
) : (
'Pending events..'
<Tooltip
title="There will be a new epoch roughly every hour when your changes will take effect"
arrow
>
<Chip label="Pending events" />
</Tooltip>
)}
</TableCell>
</TableRow>
@@ -2,7 +2,7 @@ import React from 'react';
import { Box, Button, CircularProgress, Link, Modal, Stack, Typography } from '@mui/material';
import { modalStyle } from '../Modals/styles';
export type ActionType = 'delegate' | 'undelegate' | 'redeem' | 'redeem-all';
export type ActionType = 'delegate' | 'undelegate' | 'redeem' | 'redeem-all' | 'compound';
const actionToHeader = (action: ActionType): string => {
// eslint-disable-next-line default-case
@@ -0,0 +1,62 @@
import React from 'react';
import { Alert, AlertTitle, Stack, Typography } from '@mui/material';
import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField';
import WarningIcon from '@mui/icons-material/Warning';
import { SimpleModal } from '../Modals/SimpleModal';
export const CompoundModal: React.FC<{
open: boolean;
onClose?: () => void;
onOk?: (identityKey: string) => void;
identityKey: string;
amount: number;
fee: number;
minimum?: number;
currency: string;
message: string;
}> = ({ open, onClose, onOk, identityKey, amount, fee, currency, message }) => {
const handleOk = () => {
if (onOk) {
onOk(identityKey);
}
};
return (
<SimpleModal
open={open}
onClose={onClose}
onOk={handleOk}
header={message}
subHeader="Compound rewards from delegations"
okLabel="Compound rewards"
>
{identityKey && <IdentityKeyFormField readOnly fullWidth initialValue={identityKey} showTickOnValid={false} />}
<Stack direction="row" justifyContent="space-between" mb={4} mt={identityKey && 4}>
<Typography>Rewards amount:</Typography>
<Typography>
{amount} {currency}
</Typography>
</Stack>
<Typography mb={5} fontSize="smaller">
Rewards will be transferred to account you are logged in with now
</Typography>
<Stack direction="row" justifyContent="space-between">
<Typography fontSize="smaller" color={(theme) => theme.palette.nym.fee}>
Fee for this transaction:
</Typography>
<Typography fontSize="smaller" color={(theme) => theme.palette.nym.fee}>
{fee} {currency}
</Typography>
</Stack>
{amount < fee && (
<Alert color="warning" sx={{ mt: 3 }} icon={<WarningIcon />}>
<AlertTitle>Warning: fees are greater than the reward</AlertTitle>
The fees for redeeming rewards will cost more than the rewards. Are you sure you want to continue?
</Alert>
)}
</SimpleModal>
);
};
+21 -1
View File
@@ -9,9 +9,11 @@ import {
import type { Network } from 'src/types';
import {
claimDelegatorRewards,
compoundDelegatorRewards,
delegateToMixnode,
getAllPendingDelegations,
vestingClaimDelegatorRewards,
vestingCompoundDelegatorRewards,
vestingDelegateToMixnode,
vestingUndelegateFromMixnode,
} from 'src/requests';
@@ -31,6 +33,7 @@ export type TDelegationContext = {
) => Promise<TransactionExecuteResult>;
undelegate: (identity: string, proxy: string | null) => Promise<TransactionExecuteResult>;
redeemRewards: (identity: string, proxy: string | null) => Promise<void>;
compoundRewards: (identity: string, proxy: string | null) => Promise<void>;
};
export type TDelegationTransaction = {
@@ -49,6 +52,9 @@ export const DelegationContext = createContext<TDelegationContext>({
redeemRewards: async () => {
throw new Error('Not implemented');
},
compoundRewards: async () => {
throw new Error('Not implemented');
},
});
export const DelegationContextProvider: FC<{
@@ -100,7 +106,20 @@ export const DelegationContextProvider: FC<{
await vestingClaimDelegatorRewards(identity);
}
} catch (e) {
console.log(e);
throw new Error(e as string);
}
};
const compoundRewards = async (identity: string, proxy: string | null) => {
try {
if ((proxy || '').trim().length === 0) {
// the owner of the delegation is main account (the owner of the vesting account), so it is delegation with unlocked tokens
await compoundDelegatorRewards(identity);
} else {
// the delegation is with locked tokens, so use the vesting contract
await vestingCompoundDelegatorRewards(identity);
}
} catch (e) {
throw new Error(e as string);
}
};
@@ -145,6 +164,7 @@ export const DelegationContextProvider: FC<{
addDelegation,
undelegate,
redeemRewards,
compoundRewards,
}),
[isLoading, error, delegations, pendingDelegations, totalDelegations],
);
@@ -176,6 +176,10 @@ export const MockDelegationContextProvider: FC<{}> = ({ children }) => {
throw new Error('Not implemented');
};
const compoundRewards = async () => {
throw new Error('Not implemented');
};
const resetState = () => {
setIsLoading(true);
setError(undefined);
@@ -214,6 +218,7 @@ export const MockDelegationContextProvider: FC<{}> = ({ children }) => {
updateDelegation,
undelegate,
redeemRewards,
compoundRewards,
}),
[isLoading, error, delegations, totalDelegations, trigger],
);
+38 -35
View File
@@ -14,6 +14,7 @@ import { UndelegateModal } from '../../components/Delegation/UndelegateModal';
import { DelegationListItemActions } from '../../components/Delegation/DelegationActions';
import { RedeemModal } from '../../components/Rewards/RedeemModal';
import { DelegationModal, DelegationModalProps } from '../../components/Delegation/DelegationModal';
import { CompoundModal } from 'src/components/Rewards/CompoundModal';
const explorerUrl = 'https://sandbox-explorer.nymtech.net';
@@ -22,6 +23,7 @@ export const Delegation: FC = () => {
const [showDelegateMoreModal, setShowDelegateMoreModal] = useState<boolean>(false);
const [showUndelegateModal, setShowUndelegateModal] = useState<boolean>(false);
const [showRedeemRewardsModal, setShowRedeemRewardsModal] = useState<boolean>(false);
const [showCompoundRewardsModal, setShowCompoundRewardsModal] = useState<boolean>(false);
const [confirmationModalProps, setConfirmationModalProps] = useState<DelegationModalProps | undefined>();
const [currentDelegationListActionItem, setCurrentDelegationListActionItem] = useState<DelegationWithEverything>();
@@ -40,6 +42,7 @@ export const Delegation: FC = () => {
addDelegation,
undelegate,
redeemRewards,
compoundRewards,
refresh,
} = useDelegationContext();
@@ -67,7 +70,7 @@ export const Delegation: FC = () => {
setShowRedeemRewardsModal(true);
break;
case 'compound':
setShowRedeemRewardsModal(true);
setShowCompoundRewardsModal(true);
break;
}
};
@@ -144,7 +147,8 @@ export const Delegation: FC = () => {
setConfirmationModalProps({
status: 'success',
action: 'delegate',
balance: tokenPool === 'locked' ? `${spendableLocked} ${clientDetails?.denom}` : bal?.printable_balance || '-',
balance:
tokenPool === 'locked' ? `${spendableLocked?.amount} ${clientDetails?.denom}` : bal?.printable_balance || '-',
transactionUrl: `${urls(network).blockExplorer}/transaction/${tx.transaction_hash}`,
});
} catch (e) {
@@ -208,32 +212,30 @@ export const Delegation: FC = () => {
}
};
// const handleRedeemAll = async () => {
// setConfirmationModalProps({
// status: 'loading',
// action: 'redeem-all',
// });
// setShowRedeemAllRewardsModal(false);
// setCurrentDelegationListActionItem(undefined);
// try {
// const tx = await redeemAllRewards();
// const bal = await userBalance();
const handleCompound = async (identityKey: string, proxy: string | null) => {
setConfirmationModalProps({
status: 'loading',
action: 'compound',
});
setShowCompoundRewardsModal(false);
setCurrentDelegationListActionItem(undefined);
// setConfirmationModalProps({
// status: 'success',
// action: 'redeem-all',
// balance: bal?.printable_balance || '-',
// recipient: clientDetails?.client_address,
// transactionUrl: tx.transactionUrl,
// });
// } catch (e) {
// setConfirmationModalProps({
// status: 'error',
// action: 'redeem-all',
// message: (e as Error).message,
// });
// }
// };
try {
await compoundRewards(identityKey, proxy);
const bal = await userBalance();
setConfirmationModalProps({
status: 'success',
action: 'compound',
balance: bal?.printable_balance || '-',
});
} catch (e) {
setConfirmationModalProps({
status: 'error',
action: 'redeem',
message: (e as Error).message,
});
}
};
return (
<>
@@ -342,17 +344,18 @@ export const Delegation: FC = () => {
/>
)}
{/* {currentDelegationListActionItem && showRedeemAllRewardsModal && (
<RedeemModal
open={showRedeemAllRewardsModal}
onClose={() => setShowRedeemAllRewardsModal(false)}
onOk={handleRedeemAll}
{currentDelegationListActionItem?.accumulated_rewards && showCompoundRewardsModal && (
<CompoundModal
open={showCompoundRewardsModal}
onClose={() => setShowCompoundRewardsModal(false)}
onOk={(identity) => handleCompound(identity, currentDelegationListActionItem.proxy)}
message="Compound rewards"
currency="NYM"
currency={clientDetails!.denom}
identityKey={currentDelegationListActionItem?.node_identity}
fee={0.004375}
amount={currentDelegationListActionItem?.amount.amount}
amount={+currentDelegationListActionItem.accumulated_rewards.amount}
/>
)} */}
)}
{confirmationModalProps && (
<DelegationModal