improve analytics (#428)

* checkpoint

* fix

* analitics

* analitics
This commit is contained in:
Adrian Brzeziński 2024-05-21 23:19:11 +02:00 committed by GitHub
parent d4d38aef15
commit 69649b0eec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 181 additions and 4 deletions

View File

@ -344,6 +344,7 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
undefined, // mangoAccount
onlyDirect ? 'JUPITER_DIRECT' : 'JUPITER',
connection,
undefined,
)
},
[wallet.publicKey, connection],

View File

@ -65,6 +65,7 @@ import {
import { isTokenInsured } from '@components/DepositForm'
import UninsuredNotification from '@components/shared/UninsuredNotification'
import { sendTxAndConfirm } from 'utils/governance/tools'
import useAnalytics from 'hooks/useAnalytics'
type JupiterRouteInfoProps = {
amountIn: Decimal
@ -302,6 +303,7 @@ const SwapReviewRouteInfo = ({
INITIAL_SOUND_SETTINGS,
)
const focusRef = useRef<HTMLButtonElement>(null)
const { sendAnalytics } = useAnalytics()
const [refetchRoutePercentage, setRefetchRoutePercentage] = useState(0)
@ -430,7 +432,7 @@ const SwapReviewRouteInfo = ({
)
return
setSubmitting(true)
let tx = ''
const [ixs, alts] =
// selectedRoute.routerName === 'Mango'
// ? await prepareMangoRouterInstructions(
@ -452,7 +454,15 @@ const SwapReviewRouteInfo = ({
)
try {
const { signature: tx, slot } = await client.marginTrade({
sendAnalytics(
{
inputMintPk: inputBank.mint,
amountIn: amountIn.toNumber(),
outputMintPk: outputBank.mint,
},
'swapping',
)
const { signature, slot } = await client.marginTrade({
group,
mangoAccount,
inputMintPk: inputBank.mint,
@ -462,6 +472,7 @@ const SwapReviewRouteInfo = ({
userDefinedAlts: alts,
flashLoanType: { swap: {} },
})
tx = signature
set((s) => {
s.successAnimation.swap = true
s.swap.amountIn = ''
@ -470,10 +481,16 @@ const SwapReviewRouteInfo = ({
if (soundSettings['swap-success']) {
successSound.play()
}
sendAnalytics(
{
tx: `${tx}`,
},
'swapSuccess',
)
notify({
title: 'Transaction confirmed',
type: 'success',
txid: tx,
txid: signature,
noSound: true,
})
actions.fetchGroup()
@ -483,6 +500,13 @@ const SwapReviewRouteInfo = ({
onSuccess()
}
} catch (e) {
sendAnalytics(
{
e: `${e}`,
tx: `${tx}`,
},
'onSwapError',
)
console.error('onSwap error: ', e)
sentry.captureException(e)
if (isMangoError(e)) {
@ -547,6 +571,7 @@ const SwapReviewRouteInfo = ({
}
}
}, [
sendAnalytics,
selectedRoute,
wallet.publicKey,
slippage,

View File

@ -11,6 +11,7 @@ import { MangoAccount, toUiDecimals } from '@blockworks-foundation/mango-v4'
import { findRaydiumPoolInfo, getSwapTransaction } from 'utils/swap/raydium'
import mangoStore from '@store/mangoStore'
import { fetchJupiterTransaction } from './SwapReviewRouteInfo'
import useAnalytics from 'hooks/useAnalytics'
type SwapModes = 'ExactIn' | 'ExactOut'
@ -58,6 +59,7 @@ const fetchJupiterRoute = async (
maxAccounts = 64,
connection: Connection,
wallet: string,
sendAnalytics?: (data: object, tag: string) => Promise<void>,
) => {
return new Promise<{ bestRoute: JupiterV6RouteInfo }>(
// eslint-disable-next-line no-async-promise-executor
@ -88,6 +90,15 @@ const fetchJupiterRoute = async (
const response = await fetch(
`${JUPITER_V6_QUOTE_API_MAINNET}/quote?${paramsString}`,
)
if (sendAnalytics) {
sendAnalytics(
{
url: `${JUPITER_V6_QUOTE_API_MAINNET}/quote?${paramsString}`,
},
'fetchJupiterRoute',
)
}
const res: JupiterV6RouteInfo = await response.json()
if (res.error) {
throw res.error
@ -111,6 +122,14 @@ const fetchJupiterRoute = async (
bestRoute: res,
})
} catch (e) {
if (sendAnalytics) {
sendAnalytics(
{
error: `${e}`,
},
'fetchJupiterRouteError',
)
}
console.log('jupiter route error:', e)
reject(e)
}
@ -126,11 +145,24 @@ const fetchRaydiumRoute = async (
connection: Connection,
wallet: string,
isInWalletSwap: boolean,
sendAnalytics?: (data: object, tag: string) => Promise<void>,
) => {
return new Promise<{ bestRoute: JupiterV6RouteInfo }>(
// eslint-disable-next-line no-async-promise-executor
async (resolve, reject) => {
try {
if (sendAnalytics) {
sendAnalytics(
{
inputMint,
outputMint,
amount,
slippage,
},
'fetchRaydiumRoute',
)
}
if (!inputMint || !outputMint) return
const poolKeys = await findRaydiumPoolInfo(
@ -154,6 +186,14 @@ const fetchRaydiumRoute = async (
throw 'No route found'
}
} catch (e) {
if (sendAnalytics) {
sendAnalytics(
{
error: `${e}`,
},
'raydiumRouteError',
)
}
console.log('raydium route error:', e)
reject(e)
}
@ -167,6 +207,7 @@ const fetchMangoRoute = async (
amount = 0,
slippage = 50,
swapMode = 'ExactIn',
sendAnalytics?: (data: object, tag: string) => Promise<void>,
) => {
return new Promise<{ bestRoute: JupiterV6RouteInfo }>(
// eslint-disable-next-line no-async-promise-executor
@ -183,7 +224,14 @@ const fetchMangoRoute = async (
const response = await fetch(
`${MANGO_ROUTER_API_URL}/quote?${paramsString}`,
)
if (sendAnalytics) {
sendAnalytics(
{
url: `${MANGO_ROUTER_API_URL}/quote?${paramsString}`,
},
'fetchMangoRoute',
)
}
if (response.status === 500) {
throw 'No route found'
}
@ -196,6 +244,14 @@ const fetchMangoRoute = async (
reject('No route found')
}
} catch (e) {
if (sendAnalytics) {
sendAnalytics(
{
error: `${e}`,
},
'mangoRouteError',
)
}
console.log('mango router error:', e)
reject(e)
}
@ -213,6 +269,7 @@ export async function handleGetRoutes(
mangoAccount: MangoAccount | undefined,
routingMode: MultiRoutingMode | RaydiumRoutingMode,
connection: Connection,
sendAnalytics: ((data: object, tag: string) => Promise<void>) | undefined,
inputTokenDecimals: number,
): Promise<{ bestRoute: JupiterV6RouteInfo }>
@ -226,6 +283,7 @@ export async function handleGetRoutes(
mangoAccount: MangoAccount | undefined,
routingMode: JupiterRoutingMode | MangoRoutingMode,
connection: Connection,
sendAnalytics: ((data: object, tag: string) => Promise<void>) | undefined,
): Promise<{ bestRoute: JupiterV6RouteInfo }>
export async function handleGetRoutes(
@ -238,6 +296,7 @@ export async function handleGetRoutes(
mangoAccount: MangoAccount | undefined,
routingMode: RaydiumRoutingMode,
connection: Connection,
sendAnalytics: ((data: object, tag: string) => Promise<void>) | undefined,
inputTokenDecimals: number,
): Promise<{ bestRoute: JupiterV6RouteInfo }>
@ -251,9 +310,25 @@ export async function handleGetRoutes(
mangoAccount: MangoAccount | undefined,
routingMode: RoutingMode = 'ALL',
connection: Connection,
sendAnalytics: ((data: object, tag: string) => Promise<void>) | undefined,
inputTokenDecimals?: number,
) {
try {
if (sendAnalytics) {
sendAnalytics(
{
inputMint,
outputMint,
amount,
slippage,
swapMode,
wallet,
routingMode,
},
'handleGetRoutes',
)
}
wallet ||= PublicKey.default.toBase58()
let maxAccounts: number
@ -282,6 +357,7 @@ export async function handleGetRoutes(
connection,
wallet,
!mangoAccount,
sendAnalytics,
)
routes.push(raydiumRoute)
}
@ -300,6 +376,7 @@ export async function handleGetRoutes(
maxAccounts,
connection,
wallet,
sendAnalytics,
)
routes.push(jupiterDirectRoute)
@ -316,6 +393,7 @@ export async function handleGetRoutes(
maxAccounts,
connection,
wallet,
sendAnalytics,
)
routes.push(jupiterRoute)
}
@ -327,6 +405,7 @@ export async function handleGetRoutes(
amount,
slippage,
swapMode,
sendAnalytics,
)
routes.push(mangoRoute)
}
@ -354,6 +433,14 @@ export async function handleGetRoutes(
: null,
}
} catch (e) {
if (sendAnalytics) {
sendAnalytics(
{
error: `${e}`,
},
'noRouteFoundError',
)
}
return {
bestRoute: null,
}
@ -372,6 +459,7 @@ const useQuoteRoutes = ({
enabled,
}: useQuoteRoutesPropTypes) => {
const connection = mangoStore((s) => s.connection)
const { sendAnalytics } = useAnalytics()
const { inputTokenInfo, outputTokenInfo } = useJupiterSwapData()
const decimals = useMemo(() => {
return swapMode === 'ExactIn'
@ -419,6 +507,7 @@ const useQuoteRoutes = ({
mangoAccount,
routingMode,
connection,
sendAnalytics,
decimals,
)
} else {
@ -432,6 +521,7 @@ const useQuoteRoutes = ({
mangoAccount,
routingMode,
connection,
sendAnalytics,
)
}
},

View File

@ -49,6 +49,7 @@ import { findSerum3MarketPkInOpenOrders } from './OpenOrders'
import { Transition } from '@headlessui/react'
import useThemeWrapper from 'hooks/useThemeWrapper'
import { handleCancelTriggerOrder } from '@components/swap/SwapTriggerOrders'
import useAnalytics from 'hooks/useAnalytics'
export interface ChartContainerProps {
container: ChartingLibraryWidgetOptions['container']
@ -93,6 +94,8 @@ const TradingViewChart = () => {
const [orderToModify, setOrderToModify] = useState<Order | PerpOrder | null>(
null,
)
const { sendAnalytics } = useAnalytics()
const [modifiedPrice, setModifiedPrice] = useState('')
const [showOrderLinesLocalStorage, toggleShowOrderLinesLocalStorage] =
useLocalStorageState(SHOW_ORDER_LINES_KEY, true)
@ -174,6 +177,10 @@ const TradingViewChart = () => {
}
}, [chartReady, selectedMarketName, showOrderLinesLocalStorage])
useEffect(() => {
sendAnalytics({ selectedMarketName: selectedMarketName }, 'chart_page')
}, [selectedMarketName, sendAnalytics])
useEffect(() => {
if (showOrderLines !== showOrderLinesLocalStorage) {
toggleShowOrderLinesLocalStorage(showOrderLines)

54
hooks/useAnalytics.ts Normal file
View File

@ -0,0 +1,54 @@
import useMangoAccount from './useMangoAccount'
import { useWallet } from '@solana/wallet-adapter-react'
import { WHITE_LIST_API } from 'utils/constants'
import useMangoGroup from './useMangoGroup'
import { PublicKey } from '@metaplex-foundation/js'
import { useCallback } from 'react'
export default function useAnalytics() {
const { group } = useMangoGroup()
const { mangoAccountAddress, mangoAccount } = useMangoAccount()
const { publicKey } = useWallet()
const analyticsTokenBank = group?.getFirstBankByMint(
new PublicKey('EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm'),
)
const val =
mangoAccount && analyticsTokenBank
? mangoAccount.getTokenBalanceUi(analyticsTokenBank) *
analyticsTokenBank.uiPrice
: 0
const sendAnalytics = useCallback(
async (data: object, tag: string) => {
if (
publicKey?.toBase58() &&
tag &&
data &&
mangoAccountAddress &&
val >= 10000
) {
const enchantedData = JSON.stringify({
mangoAccountAddress: mangoAccountAddress,
...data,
})
await fetch(`${WHITE_LIST_API}analytics/add`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
wallet: publicKey.toBase58(),
data: enchantedData,
tag: tag,
}),
})
}
},
[val, mangoAccountAddress, publicKey],
)
return {
sendAnalytics,
}
}