/ src / components / transactions / Swap / SwapActions.tsx
SwapActions.tsx
  1  import {
  2    API_ETH_MOCK_ADDRESS,
  3    gasLimitRecommendations,
  4    ProtocolAction,
  5  } from '@aave/contract-helpers';
  6  import { SignatureLike } from '@ethersproject/bytes';
  7  import { Trans } from '@lingui/macro';
  8  import { BoxProps } from '@mui/material';
  9  import { useParaSwapTransactionHandler } from 'src/helpers/useParaSwapTransactionHandler';
 10  import { ComputedReserveData } from 'src/hooks/app-data-provider/useAppDataProvider';
 11  import { calculateSignedAmount, SwapTransactionParams } from 'src/hooks/paraswap/common';
 12  import { useRootStore } from 'src/store/root';
 13  import { useShallow } from 'zustand/shallow';
 14  
 15  import { TxActionsWrapper } from '../TxActionsWrapper';
 16  
 17  interface SwapBaseProps extends BoxProps {
 18    amountToSwap: string;
 19    amountToReceive: string;
 20    poolReserve: ComputedReserveData;
 21    targetReserve: ComputedReserveData;
 22    isWrongNetwork: boolean;
 23    customGasPrice?: string;
 24    symbol: string;
 25    blocked: boolean;
 26    isMaxSelected: boolean;
 27    useFlashLoan: boolean;
 28    loading?: boolean;
 29    signature?: SignatureLike;
 30    deadline?: string;
 31    signedAmount?: string;
 32  }
 33  
 34  export interface SwapActionProps extends SwapBaseProps {
 35    swapCallData: string;
 36    augustus: string;
 37  }
 38  
 39  export const SwapActions = ({
 40    amountToSwap,
 41    amountToReceive,
 42    isWrongNetwork,
 43    sx,
 44    poolReserve,
 45    targetReserve,
 46    isMaxSelected,
 47    useFlashLoan,
 48    loading,
 49    symbol,
 50    blocked,
 51    buildTxFn,
 52    ...props
 53  }: SwapBaseProps & { buildTxFn: () => Promise<SwapTransactionParams> }) => {
 54    const [swapCollateral, currentMarketData] = useRootStore(
 55      useShallow((state) => [state.swapCollateral, state.currentMarketData])
 56    );
 57  
 58    const { approval, action, approvalTxState, mainTxState, loadingTxns, requiresApproval } =
 59      useParaSwapTransactionHandler({
 60        protocolAction: ProtocolAction.swapCollateral,
 61        handleGetTxns: async (signature, deadline) => {
 62          const route = await buildTxFn();
 63          return swapCollateral({
 64            amountToSwap,
 65            amountToReceive,
 66            poolReserve,
 67            targetReserve,
 68            isWrongNetwork,
 69            symbol,
 70            blocked,
 71            isMaxSelected,
 72            useFlashLoan,
 73            swapCallData: route.swapCallData,
 74            augustus: route.augustus,
 75            signature,
 76            deadline,
 77            signedAmount: calculateSignedAmount(amountToSwap, poolReserve.decimals),
 78          });
 79        },
 80        handleGetApprovalTxns: async () => {
 81          return swapCollateral({
 82            amountToSwap,
 83            amountToReceive,
 84            poolReserve,
 85            targetReserve,
 86            isWrongNetwork,
 87            symbol,
 88            blocked,
 89            isMaxSelected,
 90            useFlashLoan: false,
 91            swapCallData: '0x',
 92            augustus: API_ETH_MOCK_ADDRESS,
 93          });
 94        },
 95        gasLimitRecommendation: gasLimitRecommendations[ProtocolAction.swapCollateral].limit,
 96        skip: loading || !amountToSwap || parseFloat(amountToSwap) === 0,
 97        spender: currentMarketData.addresses.SWAP_COLLATERAL_ADAPTER ?? '',
 98        deps: [targetReserve.symbol, amountToSwap],
 99      });
100  
101    return (
102      <TxActionsWrapper
103        mainTxState={mainTxState}
104        approvalTxState={approvalTxState}
105        isWrongNetwork={isWrongNetwork}
106        preparingTransactions={loadingTxns}
107        handleAction={action}
108        requiresAmount
109        amount={amountToSwap}
110        blocked={blocked}
111        handleApproval={() =>
112          approval({
113            amount: calculateSignedAmount(amountToSwap, poolReserve.decimals),
114            underlyingAsset: poolReserve.aTokenAddress,
115          })
116        }
117        requiresApproval={requiresApproval}
118        actionText={<Trans>Switch</Trans>}
119        actionInProgressText={<Trans>Switching</Trans>}
120        sx={sx}
121        fetchingData={loading}
122        errorParams={{
123          loading: false,
124          disabled: blocked,
125          content: <Trans>Switch</Trans>,
126          handleClick: action,
127        }}
128        tryPermit
129        {...props}
130      />
131    );
132  };