From f19c934faec71f9deb7e742dfdae51aef36ccd56 Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Thu, 25 Jul 2024 16:44:33 +0100 Subject: [PATCH] finish migrate vested bonded node work --- .../src/components/Bonding/BondedMixnode.tsx | 1 + .../components/VestingWarningModal/index.tsx | 9 +-- nym-wallet/src/context/bonding.tsx | 13 ++++ nym-wallet/src/pages/bonding/Bonding.tsx | 59 +++++++++++++++++-- nym-wallet/src/pages/delegation/index.tsx | 8 +-- nym-wallet/src/requests/actions.ts | 2 + 6 files changed, 77 insertions(+), 15 deletions(-) diff --git a/nym-wallet/src/components/Bonding/BondedMixnode.tsx b/nym-wallet/src/components/Bonding/BondedMixnode.tsx index 199c8f5653..e569cd7aec 100644 --- a/nym-wallet/src/components/Bonding/BondedMixnode.tsx +++ b/nym-wallet/src/components/Bonding/BondedMixnode.tsx @@ -127,6 +127,7 @@ export const BondedMixnode = ({ ), id: 'actions-cell', diff --git a/nym-wallet/src/components/VestingWarningModal/index.tsx b/nym-wallet/src/components/VestingWarningModal/index.tsx index a594ad25b2..58fc4d30b4 100644 --- a/nym-wallet/src/components/VestingWarningModal/index.tsx +++ b/nym-wallet/src/components/VestingWarningModal/index.tsx @@ -9,8 +9,9 @@ import DialogTitle from '@mui/material/DialogTitle'; export const VestingWarningModal: FC<{ kind: 'delegations' | 'bond'; isVisible: boolean; - handleClose: (result: 'yes' | 'no') => void; -}> = ({ kind, isVisible, handleClose }) => ( + handleClose: () => void; + handleMigrate: () => Promise; +}> = ({ kind, isVisible, handleClose, handleMigrate }) => ( Migrate your {kind}? @@ -23,8 +24,8 @@ export const VestingWarningModal: FC<{ - - + diff --git a/nym-wallet/src/context/bonding.tsx b/nym-wallet/src/context/bonding.tsx index 687c754ff7..58c212a4e8 100644 --- a/nym-wallet/src/context/bonding.tsx +++ b/nym-wallet/src/context/bonding.tsx @@ -53,6 +53,7 @@ import { generateGatewayMsgPayload as generateGatewayMsgPayloadReq, updateBond as updateBondReq, vestingUpdateBond as vestingUpdateBondReq, + migrateVestedMixnode as tauriMigrateVestedMixnode, } from '../requests'; import { useCheckOwnership } from '../hooks/useCheckOwnership'; import { AppContext } from './main'; @@ -128,6 +129,7 @@ export type TBondingContext = { generateMixnodeMsgPayload: (data: TBondMixnodeSignatureArgs) => Promise; generateGatewayMsgPayload: (data: TBondGatewaySignatureArgs) => Promise; isVestingAccount: boolean; + migrateVestedMixnode: () => Promise; }; export const BondingContext = createContext({ @@ -157,6 +159,9 @@ export const BondingContext = createContext({ generateGatewayMsgPayload: async () => { throw new Error('Not implemented'); }, + migrateVestedMixnode: async () => { + throw new Error('Not implemented'); + }, isVestingAccount: false, }); @@ -599,6 +604,13 @@ export const BondingContextProvider: FCWithChildren = ({ children }): JSX.Elemen return message; }; + const migrateVestedMixnode = async () => { + setIsLoading(true); + const tx = await tauriMigrateVestedMixnode(); + setIsLoading(false); + return tx; + }; + const memoizedValue = useMemo( () => ({ isLoading: isLoading || isOwnershipLoading, @@ -613,6 +625,7 @@ export const BondingContextProvider: FCWithChildren = ({ children }): JSX.Elemen updateBondAmount, generateMixnodeMsgPayload, generateGatewayMsgPayload, + migrateVestedMixnode, isVestingAccount, }), [isLoading, isOwnershipLoading, error, bondedNode, isVestingAccount], diff --git a/nym-wallet/src/pages/bonding/Bonding.tsx b/nym-wallet/src/pages/bonding/Bonding.tsx index 24aeb768ee..3ab472d1e4 100644 --- a/nym-wallet/src/pages/bonding/Bonding.tsx +++ b/nym-wallet/src/pages/bonding/Bonding.tsx @@ -1,7 +1,7 @@ import React, { useContext, useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { FeeDetails } from '@nymproject/types'; -import { Box } from '@mui/material'; +import { Alert, AlertTitle, Box, Button, Typography } from '@mui/material'; import { TPoolOption } from 'src/components'; import { Bond } from 'src/components/Bonding/Bond'; import { BondedMixnode } from 'src/components/Bonding/BondedMixnode'; @@ -17,15 +17,16 @@ import { AppContext, urls } from 'src/context/main'; import { isGateway, isMixnode, TBondGatewayArgs, TBondMixNodeArgs, TUpdateBondArgs } from 'src/types'; import { BondedGateway } from 'src/components/Bonding/BondedGateway'; import { RedeemRewardsModal } from 'src/components/Bonding/modals/RedeemRewardsModal'; +import { VestingWarningModal } from 'src/components/VestingWarningModal'; import { BondingContextProvider, useBondingContext } from '../../context'; -const Bonding = () => { +export const Bonding = () => { const [showModal, setShowModal] = useState< 'bond-mixnode' | 'bond-gateway' | 'update-bond' | 'update-bond-oversaturated' | 'unbond' | 'redeem' >(); const [confirmationDetails, setConfirmationDetails] = useState(); const [uncappedSaturation, setUncappedSaturation] = useState(); - + const [showMigrationModal, setShowMigrationModal] = useState(false); const { network, clientDetails, @@ -34,8 +35,17 @@ const Bonding = () => { const navigate = useNavigate(); - const { bondedNode, bondMixnode, bondGateway, redeemRewards, isLoading, updateBondAmount, error, refresh } = - useBondingContext(); + const { + bondedNode, + bondMixnode, + bondGateway, + redeemRewards, + isLoading, + updateBondAmount, + error, + refresh, + migrateVestedMixnode, + } = useBondingContext(); useEffect(() => { if (bondedNode && isMixnode(bondedNode) && bondedNode.uncappedStakeSaturation) { @@ -43,6 +53,18 @@ const Bonding = () => { } }, [bondedNode]); + const handleMigrateVestedMixnode = async () => { + setShowMigrationModal(false); + const tx = await migrateVestedMixnode(); + if (tx) { + setConfirmationDetails({ + status: 'success', + title: 'Migration successful', + txUrl: `${urls(network).blockExplorer}/transaction/${tx?.transaction_hash}`, + }); + } + }; + const handleCloseModal = async () => { setShowModal(undefined); refresh(); @@ -138,6 +160,33 @@ const Bonding = () => { return ( + {bondedNode?.proxy && ( + + Your bonded node is using tokens from the vesting contract! + + In order to claim your rewards, you will need to migrate it out of the vesting contract.{' '} + + + Never fear, if you do not migrate them, you will continue to get rewards. + However, please migrate your bonded node as soon as possible. + + + + )} + + { + setShowMigrationModal(false); + }} + handleMigrate={async () => { + await handleMigrateVestedMixnode(); + }} + /> + {!bondedNode && setShowModal('bond-mixnode')} />} {bondedNode && isMixnode(bondedNode) && ( diff --git a/nym-wallet/src/pages/delegation/index.tsx b/nym-wallet/src/pages/delegation/index.tsx index b77873bad1..b51ebcf60f 100644 --- a/nym-wallet/src/pages/delegation/index.tsx +++ b/nym-wallet/src/pages/delegation/index.tsx @@ -352,12 +352,8 @@ export const Delegation: FC<{ isStorybook?: boolean }> = ({ isStorybook }) => { { - setShowVestingWarningModal(false); - if (result === 'yes') { - doMigrateNow(); - } - }} + handleMigrate={doMigrateNow} + handleClose={() => setShowVestingWarningModal(false)} /> {showVestingMigrationProgressModal && } diff --git a/nym-wallet/src/requests/actions.ts b/nym-wallet/src/requests/actions.ts index cf09085d5f..7361841f3f 100644 --- a/nym-wallet/src/requests/actions.ts +++ b/nym-wallet/src/requests/actions.ts @@ -52,3 +52,5 @@ export const unbond = async (type: EnumNodeType) => { export const updateBond = async (args: TUpdateBondArgs) => invokeWrapper('update_pledge', args); + +export const migrateVestedMixnode = async () => invokeWrapper('migrate_vested_mixnode');