feat: Web 214 implement the main submit swap event (#4061)
* init commit * add amplitude ts sdk to package.json * add more comments and documentation * respond to vm comments * respond to cmcewen comments * fix: remove unused constants * init commit * adapt to web * add optional event properties to trace * correct telemetry to analytics * init commit * change telemetry to analytics in doc * init commit * fix: respond to cmcewen comments + initialize analytics in app.tsx + add missing return statement * add element name constant * init commit * correct price_impact calculation * resolve vm comments * fixes in response to comments * respond to vm * use ALL significant digits for token amounts * create helper function getPriceImpactPercentageNumber * 4 decimal points for percentages * change percentage to basis points units
This commit is contained in:
parent
c60c028dbe
commit
e01f30c0b4
@ -45,6 +45,13 @@ function TextWithLoadingPlaceholder({
|
||||
)
|
||||
}
|
||||
|
||||
export function getPriceImpactPercent(
|
||||
lpFeePercent: Percent,
|
||||
trade: InterfaceTrade<Currency, Currency, TradeType>
|
||||
): Percent {
|
||||
return trade.priceImpact.subtract(lpFeePercent)
|
||||
}
|
||||
|
||||
export function AdvancedSwapDetails({
|
||||
trade,
|
||||
allowedSlippage,
|
||||
@ -59,7 +66,7 @@ export function AdvancedSwapDetails({
|
||||
if (!trade) return { expectedOutputAmount: undefined, priceImpact: undefined }
|
||||
const expectedOutputAmount = trade.outputAmount
|
||||
const realizedLpFeePercent = computeRealizedLPFeePercent(trade)
|
||||
const priceImpact = trade.priceImpact.subtract(realizedLpFeePercent)
|
||||
const priceImpact = getPriceImpactPercent(realizedLpFeePercent, trade)
|
||||
return { expectedOutputAmount, priceImpact }
|
||||
}, [trade])
|
||||
|
||||
|
@ -61,11 +61,13 @@ export default function ConfirmSwapModal({
|
||||
<SwapModalFooter
|
||||
onConfirm={onConfirm}
|
||||
trade={trade}
|
||||
txHash={txHash}
|
||||
allowedSlippage={allowedSlippage}
|
||||
disabledConfirm={showAcceptChanges}
|
||||
swapErrorMessage={swapErrorMessage}
|
||||
/>
|
||||
) : null
|
||||
}, [onConfirm, showAcceptChanges, swapErrorMessage, trade])
|
||||
}, [onConfirm, showAcceptChanges, swapErrorMessage, trade, allowedSlippage, txHash])
|
||||
|
||||
// text to show while loading
|
||||
const pendingText = (
|
||||
|
@ -1,36 +1,132 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { Trade } from '@uniswap/router-sdk'
|
||||
import { Currency, TradeType } from '@uniswap/sdk-core'
|
||||
import { Currency, CurrencyAmount, Percent, Token, TradeType } from '@uniswap/sdk-core'
|
||||
import { ElementName, EventName } from 'components/AmplitudeAnalytics/constants'
|
||||
import { Event } from 'components/AmplitudeAnalytics/constants'
|
||||
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
|
||||
import { useStablecoinValue } from 'hooks/useStablecoinPrice'
|
||||
import useTransactionDeadline from 'hooks/useTransactionDeadline'
|
||||
import { ReactNode } from 'react'
|
||||
import { Text } from 'rebass'
|
||||
import { InterfaceTrade } from 'state/routing/types'
|
||||
import { useClientSideRouter, useUserSlippageTolerance } from 'state/user/hooks'
|
||||
import { computeRealizedLPFeePercent } from 'utils/prices'
|
||||
|
||||
import { ButtonError } from '../Button'
|
||||
import { AutoRow } from '../Row'
|
||||
import { getPriceImpactPercent } from './AdvancedSwapDetails'
|
||||
import { SwapCallbackError } from './styleds'
|
||||
|
||||
function getDurationTillTimestampSinceEpoch(futureTimestampSinceEpoch?: number): number | undefined {
|
||||
if (!futureTimestampSinceEpoch) return undefined
|
||||
return futureTimestampSinceEpoch - new Date().getTime() / 1000
|
||||
}
|
||||
|
||||
const getNumberFormattedToDecimalPlace = (
|
||||
intialNumberObject: Percent | CurrencyAmount<Token | Currency>,
|
||||
decimalPlace: number
|
||||
): number => parseFloat(intialNumberObject.toFixed(decimalPlace))
|
||||
|
||||
const formatPercentInBasisPointsNumber = (percent: Percent): number => parseFloat(percent.toFixed(2)) * 100
|
||||
|
||||
interface AnalyticsEventProps {
|
||||
trade: InterfaceTrade<Currency, Currency, TradeType>
|
||||
txHash: string | undefined
|
||||
allowedSlippage: Percent
|
||||
transactionDeadlineSecondsSinceEpoch: number | undefined
|
||||
isAutoSlippage: boolean
|
||||
isAutoRouterApi: boolean
|
||||
tokenInAmountUsd: string | undefined
|
||||
tokenOutAmountUsd: string | undefined
|
||||
lpFeePercent: Percent
|
||||
}
|
||||
|
||||
const formatAnalyticsEventProperties = ({
|
||||
trade,
|
||||
txHash,
|
||||
allowedSlippage,
|
||||
transactionDeadlineSecondsSinceEpoch,
|
||||
isAutoSlippage,
|
||||
isAutoRouterApi,
|
||||
tokenInAmountUsd,
|
||||
tokenOutAmountUsd,
|
||||
lpFeePercent,
|
||||
}: AnalyticsEventProps) => ({
|
||||
estimated_network_fee_usd: trade.gasUseEstimateUSD
|
||||
? getNumberFormattedToDecimalPlace(trade.gasUseEstimateUSD, 2)
|
||||
: undefined,
|
||||
transaction_hash: txHash,
|
||||
transaction_deadline_seconds: getDurationTillTimestampSinceEpoch(transactionDeadlineSecondsSinceEpoch),
|
||||
token_in_amount_usd: tokenInAmountUsd ? parseFloat(tokenInAmountUsd) : undefined,
|
||||
token_out_amount_usd: tokenOutAmountUsd ? parseFloat(tokenOutAmountUsd) : undefined,
|
||||
token_in_address: trade.inputAmount.currency.isToken ? trade.inputAmount.currency.address : undefined,
|
||||
token_out_address: trade.outputAmount.currency.isToken ? trade.outputAmount.currency.address : undefined,
|
||||
token_in_symbol: trade.inputAmount.currency.symbol,
|
||||
token_out_symbol: trade.outputAmount.currency.symbol,
|
||||
token_in_amount: getNumberFormattedToDecimalPlace(trade.inputAmount, trade.inputAmount.currency.decimals),
|
||||
token_out_amount: getNumberFormattedToDecimalPlace(trade.outputAmount, trade.outputAmount.currency.decimals),
|
||||
price_impact_basis_points: formatPercentInBasisPointsNumber(getPriceImpactPercent(lpFeePercent, trade)),
|
||||
allowed_slippage_basis_points: formatPercentInBasisPointsNumber(allowedSlippage),
|
||||
is_auto_router_api: isAutoRouterApi,
|
||||
is_auto_slippage: isAutoSlippage,
|
||||
chain_id:
|
||||
trade.inputAmount.currency.chainId === trade.outputAmount.currency.chainId
|
||||
? trade.inputAmount.currency.chainId
|
||||
: undefined,
|
||||
// TODO(lynnshaoyu): implement duration_from_first_quote_to_swap_submission_seconds
|
||||
})
|
||||
|
||||
export default function SwapModalFooter({
|
||||
trade,
|
||||
allowedSlippage,
|
||||
txHash,
|
||||
onConfirm,
|
||||
swapErrorMessage,
|
||||
disabledConfirm,
|
||||
}: {
|
||||
trade: Trade<Currency, Currency, TradeType>
|
||||
trade: InterfaceTrade<Currency, Currency, TradeType>
|
||||
txHash: string | undefined
|
||||
allowedSlippage: Percent
|
||||
onConfirm: () => void
|
||||
swapErrorMessage: ReactNode | undefined
|
||||
disabledConfirm: boolean
|
||||
}) {
|
||||
const transactionDeadlineSecondsSinceEpoch = useTransactionDeadline()?.toNumber() // in seconds since epoch
|
||||
const isAutoSlippage = useUserSlippageTolerance() === 'auto'
|
||||
const [clientSideRouter] = useClientSideRouter()
|
||||
const tokenInAmountUsd = useStablecoinValue(trade.inputAmount)?.toFixed(2)
|
||||
const tokenOutAmountUsd = useStablecoinValue(trade.outputAmount)?.toFixed(2)
|
||||
const lpFeePercent = computeRealizedLPFeePercent(trade)
|
||||
|
||||
return (
|
||||
<>
|
||||
<AutoRow>
|
||||
<ButtonError
|
||||
onClick={onConfirm}
|
||||
disabled={disabledConfirm}
|
||||
style={{ margin: '10px 0 0 0' }}
|
||||
id="confirm-swap-or-send"
|
||||
<TraceEvent
|
||||
events={[Event.onClick]}
|
||||
element={ElementName.CONFIRM_SWAP_BUTTON}
|
||||
name={EventName.SWAP_SUBMITTED}
|
||||
properties={formatAnalyticsEventProperties({
|
||||
trade,
|
||||
txHash,
|
||||
allowedSlippage,
|
||||
transactionDeadlineSecondsSinceEpoch,
|
||||
isAutoSlippage,
|
||||
isAutoRouterApi: !clientSideRouter,
|
||||
tokenInAmountUsd,
|
||||
tokenOutAmountUsd,
|
||||
lpFeePercent,
|
||||
})}
|
||||
>
|
||||
<Text fontSize={20} fontWeight={500}>
|
||||
<Trans>Confirm Swap</Trans>
|
||||
</Text>
|
||||
</ButtonError>
|
||||
<ButtonError
|
||||
onClick={onConfirm}
|
||||
disabled={disabledConfirm}
|
||||
style={{ margin: '10px 0 0 0' }}
|
||||
id={ElementName.CONFIRM_SWAP_BUTTON}
|
||||
>
|
||||
<Text fontSize={20} fontWeight={500}>
|
||||
<Trans>Confirm Swap</Trans>
|
||||
</Text>
|
||||
</ButtonError>
|
||||
</TraceEvent>
|
||||
|
||||
{swapErrorMessage ? <SwapCallbackError error={swapErrorMessage} /> : null}
|
||||
</AutoRow>
|
||||
|
Loading…
Reference in New Issue
Block a user