MigrateV3ModalContent.tsx
1 import { Trans } from '@lingui/macro'; 2 import { Box, Button } from '@mui/material'; 3 import { useRouter } from 'next/router'; 4 import { useMemo } from 'react'; 5 import { UserMigrationReserves } from 'src/hooks/migration/useUserMigrationReserves'; 6 import { UserSummaryForMigration } from 'src/hooks/migration/useUserSummaryForMigration'; 7 import { useModalContext } from 'src/hooks/useModal'; 8 import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; 9 import { useRootStore } from 'src/store/root'; 10 import { 11 selectedUserSupplyReservesForMigration, 12 selectSelectedBorrowReservesForMigrationV3, 13 } from 'src/store/v3MigrationSelectors'; 14 import { CustomMarket, getNetworkConfig } from 'src/utils/marketsAndNetworksConfig'; 15 import { useShallow } from 'zustand/shallow'; 16 17 import { TxErrorView } from '../FlowCommons/Error'; 18 import { GasEstimationError } from '../FlowCommons/GasEstimationError'; 19 import { TxSuccessView } from '../FlowCommons/Success'; 20 import { TxModalDetails } from '../FlowCommons/TxModalDetails'; 21 import { TxModalTitle } from '../FlowCommons/TxModalTitle'; 22 import { ChangeNetworkWarning } from '../Warnings/ChangeNetworkWarning'; 23 import { MigrateV3Actions } from './MigrateV3Actions'; 24 import { MigrateV3ModalAssetsList } from './MigrateV3ModalAssetsList'; 25 26 interface MigrationV3ModalContentProps { 27 toUserSummaryForMigration: UserSummaryForMigration; 28 userMigrationReserves: UserMigrationReserves; 29 } 30 31 export const MigrateV3ModalContent = ({ 32 toUserSummaryForMigration, 33 userMigrationReserves, 34 }: MigrationV3ModalContentProps) => { 35 const currentChainId = useRootStore((store) => store.currentChainId); 36 const setCurrentMarket = useRootStore((store) => store.setCurrentMarket); 37 const currentMarket = useRootStore((store) => store.currentMarket); 38 39 const { gasLimit, mainTxState: migrateTxState, txError, closeWithCb } = useModalContext(); 40 const { chainId: connectedChainId, readOnlyModeAddress } = useWeb3Context(); 41 const router = useRouter(); 42 const networkConfig = getNetworkConfig(currentChainId); 43 44 const { selectedMigrationSupplyAssets, selectedMigrationBorrowAssets } = useRootStore( 45 useShallow((state) => ({ 46 selectedMigrationSupplyAssets: state.selectedMigrationSupplyAssets, 47 selectedMigrationBorrowAssets: state.selectedMigrationBorrowAssets, 48 })) 49 ); 50 51 const supplyPositions = useMemo( 52 () => 53 selectedUserSupplyReservesForMigration( 54 selectedMigrationSupplyAssets, 55 userMigrationReserves.supplyReserves, 56 userMigrationReserves.isolatedReserveV3 57 ), 58 [selectedMigrationSupplyAssets, userMigrationReserves] 59 ); 60 61 const borrowPositions = useMemo( 62 () => 63 selectSelectedBorrowReservesForMigrationV3( 64 selectedMigrationBorrowAssets, 65 toUserSummaryForMigration, 66 userMigrationReserves 67 ), 68 [selectedMigrationBorrowAssets, toUserSummaryForMigration, userMigrationReserves] 69 ); 70 71 const supplyAssets = supplyPositions.map((supplyAsset) => { 72 return { 73 underlyingAsset: supplyAsset.underlyingAsset, 74 iconSymbol: supplyAsset.reserve.iconSymbol, 75 symbol: supplyAsset.reserve.symbol, 76 amount: supplyAsset.underlyingBalance, 77 amountInUSD: supplyAsset.underlyingBalanceUSD, 78 }; 79 }); 80 81 const borrowsAssets = borrowPositions.map((asset) => { 82 return { 83 underlyingAsset: asset.debtKey, 84 iconSymbol: asset.reserve.iconSymbol, 85 symbol: asset.reserve.symbol, 86 amount: asset.variableBorrows, 87 amountInUSD: asset.variableBorrowsUSD, 88 }; 89 }); 90 91 // is Network mismatched 92 const isWrongNetwork = currentChainId !== connectedChainId; 93 94 if (txError && txError.blocking) { 95 return <TxErrorView txError={txError} />; 96 } 97 98 const handleRoute = (market: CustomMarket) => { 99 if (market === CustomMarket.proto_polygon) { 100 setCurrentMarket('proto_polygon_v3' as CustomMarket); 101 router.push(`/?marketName=${CustomMarket.proto_polygon_v3}`); 102 } else if (market === CustomMarket.proto_avalanche) { 103 setCurrentMarket('proto_avalanche_v3' as CustomMarket); 104 router.push(`/?marketName=${CustomMarket.proto_avalanche_v3}`); 105 } else { 106 setCurrentMarket('proto_mainnet_v3' as CustomMarket); 107 router.push(`/?marketName=${CustomMarket.proto_mainnet_v3}`); 108 } 109 }; 110 111 const handleGoToDashboard = () => { 112 closeWithCb(() => handleRoute(currentMarket)); 113 }; 114 115 if (migrateTxState.success) { 116 return ( 117 <TxSuccessView 118 customAction={ 119 <Box mt={5}> 120 <Button variant="gradient" size="medium" onClick={handleGoToDashboard}> 121 <Trans>Go to V3 Dashboard</Trans> 122 </Button> 123 </Box> 124 } 125 customText={ 126 <Trans> 127 Selected assets have successfully migrated. Visit the Market Dashboard to see them. 128 </Trans> 129 } 130 action={<Trans>Migrated</Trans>} 131 /> 132 ); 133 } 134 135 return ( 136 <> 137 <TxModalTitle title="Migrate to V3" /> 138 {isWrongNetwork && !readOnlyModeAddress && ( 139 <ChangeNetworkWarning networkName={networkConfig.name} chainId={currentChainId} /> 140 )} 141 142 <TxModalDetails gasLimit={gasLimit}> 143 <MigrateV3ModalAssetsList 144 caption={<Trans>Selected supply assets</Trans>} 145 assets={supplyAssets} 146 /> 147 <MigrateV3ModalAssetsList 148 caption={<Trans>Selected borrow assets</Trans>} 149 assets={borrowsAssets} 150 /> 151 </TxModalDetails> 152 153 {txError && <GasEstimationError txError={txError} />} 154 155 {userMigrationReserves && toUserSummaryForMigration && ( 156 <MigrateV3Actions 157 isWrongNetwork={isWrongNetwork} 158 blocked={false} 159 userMigrationReserves={userMigrationReserves} 160 toUserSummaryForMigration={toUserSummaryForMigration} 161 /> 162 )} 163 </> 164 ); 165 };