import BigNumber from 'bignumber.js' import React, { RefObject, useMemo } from 'react' import { Trans, useTranslation } from 'react-i18next' import { StyleSheet, Text, View } from 'react-native' import AppAnalytics from 'src/analytics/AppAnalytics' import { EarnEvents } from 'src/analytics/Events' import { openUrl } from 'src/app/actions' import BottomSheet, { BottomSheetModalRefType } from 'src/components/BottomSheet' import Button, { BtnSizes, BtnTypes } from 'src/components/Button' import { LabelWithInfo } from 'src/components/LabelWithInfo' import TokenDisplay from 'src/components/TokenDisplay' import { depositStatusSelector } from 'src/earn/selectors' import { depositStart } from 'src/earn/slice' import { EarnActiveMode } from 'src/earn/types' import { getSwapToAmountInDecimals, getTotalYieldRate, isGasSubsidizedForNetwork, } from 'src/earn/utils' import ArrowRightThick from 'src/icons/ArrowRightThick' import { EarnPosition } from 'src/positions/types' import { useDispatch, useSelector } from 'src/redux/hooks' import { NETWORK_NAMES } from 'src/shared/conts' import Colors from 'src/styles/colors' import { typeScale } from 'src/styles/fonts' import { Spacing } from 'src/styles/styles' import { SwapTransaction } from 'src/swap/types' import { PreparedTransactionsPossible, getFeeCurrencyAndAmounts, } from 'src/viem/prepareTransactions' import { getSerializablePreparedTransactions } from 'src/viem/preparedTransactionSerialization' const APP_ID_TO_PROVIDER_DOCUMENTS_URL: Record = { beefy: 'https://docs.beefy.finance/', } const APP_TERMS_AND_CONDITIONS_URL = 'https://valora.xyz/terms' export default function EarnDepositBottomSheet({ forwardedRef, preparedTransaction, inputAmount, inputTokenId, pool, mode, swapTransaction, }: { forwardedRef: RefObject preparedTransaction: PreparedTransactionsPossible inputTokenId: string inputAmount: BigNumber pool: EarnPosition mode: EarnActiveMode swapTransaction?: SwapTransaction }) { const { t } = useTranslation() const dispatch = useDispatch() const depositStatus = useSelector(depositStatusSelector) const transactionSubmitted = depositStatus === 'loading' const depositAmount = useMemo( () => mode === 'swap-deposit' && swapTransaction ? getSwapToAmountInDecimals({ swapTransaction, fromAmount: inputAmount }) : inputAmount, [inputAmount, swapTransaction] ) const commonAnalyticsProperties = { providerId: pool.appId, depositTokenId: pool.dataProps.depositTokenId, depositTokenAmount: depositAmount.toString(), fromTokenId: inputTokenId, fromTokenAmount: inputAmount.toString(), fromNetworkId: preparedTransaction.feeCurrency.networkId, networkId: pool.networkId, poolId: pool.positionId, mode, swapType: swapTransaction?.swapType, } const { estimatedFeeAmount, feeCurrency } = getFeeCurrencyAndAmounts(preparedTransaction) if (!estimatedFeeAmount || !feeCurrency) { // should never happen since a possible prepared tx should include fee currency and amount return null } const isGasSubsidized = isGasSubsidizedForNetwork(preparedTransaction.feeCurrency.networkId) const { termsUrl } = pool.dataProps const onPressProviderIcon = () => { AppAnalytics.track(EarnEvents.earn_deposit_provider_info_press, commonAnalyticsProperties) termsUrl && dispatch(openUrl(termsUrl, true)) } const onPressTermsAndConditions = () => { AppAnalytics.track(EarnEvents.earn_deposit_terms_and_conditions_press, { type: 'providerTermsAndConditions', ...commonAnalyticsProperties, }) termsUrl && dispatch(openUrl(termsUrl, true)) } const onPressProviderDocuments = () => { AppAnalytics.track(EarnEvents.earn_deposit_terms_and_conditions_press, { type: 'providerDocuments', ...commonAnalyticsProperties, }) const providerDocumentsUrl = APP_ID_TO_PROVIDER_DOCUMENTS_URL[pool.appId] providerDocumentsUrl && dispatch(openUrl(providerDocumentsUrl, true)) } const onPressAppTermsAndConditions = () => { AppAnalytics.track(EarnEvents.earn_deposit_terms_and_conditions_press, { type: 'appTermsAndConditions', ...commonAnalyticsProperties, }) dispatch(openUrl(APP_TERMS_AND_CONDITIONS_URL, true)) } const onPressComplete = () => { dispatch( depositStart({ amount: depositAmount.toString(), pool, preparedTransactions: getSerializablePreparedTransactions(preparedTransaction.transactions), mode, fromTokenId: inputTokenId, fromTokenAmount: inputAmount.toString(), }) ) AppAnalytics.track(EarnEvents.earn_deposit_complete, commonAnalyticsProperties) // Dismiss the bottom sheet when transaction is submitted. This avoids a handful of issues, // such as needing to manually dismiss the sheet for PIN entry, and the bottom sheet // persisting onto the home screen. forwardedRef.current?.close() } const onPressCancel = () => { AppAnalytics.track(EarnEvents.earn_deposit_cancel, commonAnalyticsProperties) forwardedRef.current?.close() } return ( {t('earnFlow.depositBottomSheet.title')} {t('earnFlow.depositBottomSheet.descriptionV1_93', { providerName: pool.appName })} {t('earnFlow.depositBottomSheet.apy', { apy: getTotalYieldRate(pool).toFixed(2), })} {'('} {')'} {mode === 'swap-deposit' && ( )} {'('} {')'} {isGasSubsidized && ( {t('earnFlow.gasSubsidized')} )} {termsUrl ? ( ) : ( {pool.appName} )} {NETWORK_NAMES[pool.networkId]} {termsUrl ? ( ) : ( APP_ID_TO_PROVIDER_DOCUMENTS_URL[pool.appId] && ( ) )}