Skip to content

Commit

Permalink
Feat: track tx creations and safe views
Browse files Browse the repository at this point in the history
  • Loading branch information
katspaugh committed Nov 9, 2023
1 parent 798e998 commit bd2844b
Show file tree
Hide file tree
Showing 21 changed files with 157 additions and 39 deletions.
2 changes: 2 additions & 0 deletions src/components/tx-flow/flows/AddOwner/ReviewOwner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import PlusIcon from '@/public/images/common/plus.svg'
import MinusIcon from '@/public/images/common/minus.svg'
import EthHashInfo from '@/components/common/EthHashInfo'
import commonCss from '@/components/tx-flow/common/styles.module.css'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'

export const ReviewOwner = ({ params }: { params: AddOwnerFlowProps | ReplaceOwnerFlowProps }) => {
const dispatch = useAppDispatch()
Expand Down Expand Up @@ -49,6 +50,7 @@ export const ReviewOwner = ({ params }: { params: AddOwnerFlowProps | ReplaceOwn

trackEvent({ ...SETTINGS_EVENTS.SETUP.THRESHOLD, label: safe.threshold })
trackEvent({ ...SETTINGS_EVENTS.SETUP.OWNERS, label: safe.owners.length })
trackEvent({ ...TX_EVENTS.CREATE, label: params.removedOwner ? TX_TYPES.owner_swap : TX_TYPES.owner_add })
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import SignOrExecuteForm from '@/components/tx/SignOrExecuteForm'
import { SafeTxContext } from '@/components/tx-flow/SafeTxProvider'
import { ChangeThresholdFlowFieldNames } from '@/components/tx-flow/flows/ChangeThreshold'
import type { ChangeThresholdFlowProps } from '@/components/tx-flow/flows/ChangeThreshold'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'

import commonCss from '@/components/tx-flow/common/styles.module.css'

Expand All @@ -24,6 +25,7 @@ const ReviewChangeThreshold = ({ params }: { params: ChangeThresholdFlowProps })
const onChangeThreshold = () => {
trackEvent({ ...SETTINGS_EVENTS.SETUP.OWNERS, label: safe.owners.length })
trackEvent({ ...SETTINGS_EVENTS.SETUP.THRESHOLD, label: newThreshold })
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.owner_threshold_change })
}

return (
Expand Down
11 changes: 9 additions & 2 deletions src/components/tx-flow/flows/ConfirmBatch/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type ReactElement, useContext, useEffect } from 'react'
import { type ReactElement, useContext, useEffect, useCallback } from 'react'
import { type TransactionDetails } from '@safe-global/safe-gateway-typescript-sdk'
import SignOrExecuteForm from '@/components/tx/SignOrExecuteForm'
import { createMultiSendCallOnlyTx } from '@/services/tx/tx-sender'
Expand All @@ -9,6 +9,8 @@ import TxLayout from '../../common/TxLayout'
import BatchIcon from '@/public/images/common/batch.svg'
import { useDraftBatch } from '@/hooks/useDraftBatch'
import BatchTxList from '@/components/batch/BatchSidebar/BatchTxList'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'
import { trackEvent } from '@/services/analytics'

type ConfirmBatchProps = {
onSubmit: () => void
Expand All @@ -32,8 +34,13 @@ const ConfirmBatch = ({ onSubmit }: ConfirmBatchProps): ReactElement => {
createMultiSendCallOnlyTx(calls).then(setSafeTx).catch(setSafeTxError)
}, [batchTxs, setSafeTx, setSafeTxError])

const onTxSubmit = useCallback(() => {
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.batch })
onSubmit()
}, [onSubmit])

return (
<SignOrExecuteForm onSubmit={onSubmit} isBatch>
<SignOrExecuteForm onSubmit={onTxSubmit} isBatch>
<BatchTxList txItems={batchTxs} />
</SignOrExecuteForm>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type { SpendingLimitState } from '@/store/spendingLimitsSlice'
import type { NewSpendingLimitFlowProps } from '.'
import EthHashInfo from '@/components/common/EthHashInfo'
import { SafeTxContext } from '../../SafeTxProvider'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'

export const ReviewSpendingLimit = ({ params }: { params: NewSpendingLimitFlowProps }) => {
const [existingSpendingLimit, setExistingSpendingLimit] = useState<SpendingLimitState>()
Expand Down Expand Up @@ -53,6 +54,8 @@ export const ReviewSpendingLimit = ({ params }: { params: NewSpendingLimitFlowPr
...SETTINGS_EVENTS.SPENDING_LIMIT.RESET_PERIOD,
label: resetTime,
})

trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.spending_limit_add })
}

const existingAmount = existingSpendingLimit
Expand Down
11 changes: 9 additions & 2 deletions src/components/tx-flow/flows/NftTransfer/ReviewNftBatch.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type ReactElement, useEffect, useContext } from 'react'
import { type ReactElement, useEffect, useContext, useCallback } from 'react'
import { Grid, Typography } from '@mui/material'
import SendToBlock from '@/components/tx-flow/flows/TokenTransfer/SendToBlock'
import { createNftTransferParams } from '@/services/tx/tokenTransferParams'
Expand All @@ -8,6 +8,8 @@ import { createMultiSendCallOnlyTx, createTx } from '@/services/tx/tx-sender'
import SignOrExecuteForm from '@/components/tx/SignOrExecuteForm'
import { SafeTxContext } from '../../SafeTxProvider'
import { NftItems } from '@/components/tx-flow/flows/NftTransfer/SendNftBatch'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'
import { trackEvent } from '@/services/analytics'

type ReviewNftBatchProps = {
params: NftTransferParams
Expand Down Expand Up @@ -38,8 +40,13 @@ const ReviewNftBatch = ({ params, onSubmit, txNonce }: ReviewNftBatchProps): Rea
promise.then(setSafeTx).catch(setSafeTxError)
}, [safeAddress, params, setSafeTx, setSafeTxError])

const onTxSubmit = useCallback(() => {
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.transfer_nft })
onSubmit()
}, [onSubmit])

return (
<SignOrExecuteForm onSubmit={onSubmit}>
<SignOrExecuteForm onSubmit={onTxSubmit}>
<Grid container gap={1} mb={2}>
<Grid item md>
<Typography variant="body2" color="text.secondary">
Expand Down
8 changes: 7 additions & 1 deletion src/components/tx-flow/flows/RejectTx/RejectTx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@ import SignOrExecuteForm from '@/components/tx/SignOrExecuteForm'
import { createRejectTx } from '@/services/tx/tx-sender'
import { useContext, useEffect } from 'react'
import { SafeTxContext } from '../../SafeTxProvider'
import { trackEvent } from '@/services/analytics'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'

type RejectTxProps = {
txNonce: number
}

const onSubmit = () => {
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.rejection })
}

const RejectTx = ({ txNonce }: RejectTxProps): ReactElement => {
const { setSafeTx, setSafeTxError, setNonce } = useContext(SafeTxContext)

Expand All @@ -19,7 +25,7 @@ const RejectTx = ({ txNonce }: RejectTxProps): ReactElement => {
}, [txNonce, setNonce, setSafeTx, setSafeTxError])

return (
<SignOrExecuteForm onSubmit={() => {}} isBatchable={false}>
<SignOrExecuteForm onSubmit={onSubmit} isBatchable={false}>
<Typography mb={2}>
To reject the transaction, a separate rejection transaction will be created to replace the original one.
</Typography>
Expand Down
10 changes: 6 additions & 4 deletions src/components/tx-flow/flows/RemoveGuard/ReviewRemoveGuard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ import { trackEvent, SETTINGS_EVENTS } from '@/services/analytics'
import { createRemoveGuardTx } from '@/services/tx/tx-sender'
import { type RemoveGuardFlowProps } from '.'
import { SafeTxContext } from '@/components/tx-flow/SafeTxProvider'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'

const onFormSubmit = () => {
trackEvent(SETTINGS_EVENTS.MODULES.REMOVE_GUARD)
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.guard_remove })
}

export const ReviewRemoveGuard = ({ params }: { params: RemoveGuardFlowProps }) => {
const { setSafeTx, safeTxError, setSafeTxError } = useContext(SafeTxContext)
Expand All @@ -21,10 +27,6 @@ export const ReviewRemoveGuard = ({ params }: { params: RemoveGuardFlowProps })
}
}, [safeTxError])

const onFormSubmit = () => {
trackEvent(SETTINGS_EVENTS.MODULES.REMOVE_GUARD)
}

return (
<SignOrExecuteForm onSubmit={onFormSubmit}>
<Typography sx={({ palette }) => ({ color: palette.primary.light })}>Transaction guard</Typography>
Expand Down
10 changes: 6 additions & 4 deletions src/components/tx-flow/flows/RemoveModule/ReviewRemoveModule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ import { createRemoveModuleTx } from '@/services/tx/tx-sender'
import { SafeTxContext } from '@/components/tx-flow/SafeTxProvider'
import { type RemoveModuleFlowProps } from '.'
import EthHashInfo from '@/components/common/EthHashInfo'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'

const onFormSubmit = () => {
trackEvent(SETTINGS_EVENTS.MODULES.REMOVE_MODULE)
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.module_remove })
}

export const ReviewRemoveModule = ({ params }: { params: RemoveModuleFlowProps }) => {
const { setSafeTx, safeTxError, setSafeTxError } = useContext(SafeTxContext)
Expand All @@ -21,10 +27,6 @@ export const ReviewRemoveModule = ({ params }: { params: RemoveModuleFlowProps }
}
}, [safeTxError])

const onFormSubmit = () => {
trackEvent(SETTINGS_EVENTS.MODULES.REMOVE_MODULE)
}

return (
<SignOrExecuteForm onSubmit={onFormSubmit}>
<Grid container gap={1} alignItems="center">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import MinusIcon from '@/public/images/common/minus.svg'
import { SafeTxContext } from '../../SafeTxProvider'
import type { RemoveOwnerFlowProps } from '.'
import EthHashInfo from '@/components/common/EthHashInfo'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'

import commonCss from '@/components/tx-flow/common/styles.module.css'

Expand All @@ -29,6 +30,7 @@ export const ReviewRemoveOwner = ({ params }: { params: RemoveOwnerFlowProps }):
const onFormSubmit = () => {
trackEvent({ ...SETTINGS_EVENTS.SETUP.THRESHOLD, label: safe.threshold })
trackEvent({ ...SETTINGS_EVENTS.SETUP.OWNERS, label: safe.owners.length })
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.owner_remove })
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ import SendAmountBlock from '@/components/tx-flow/flows/TokenTransfer/SendAmount
import { safeFormatUnits } from '@/utils/formatters'
import SpendingLimitLabel from '@/components/common/SpendingLimitLabel'
import { createTx } from '@/services/tx/tx-sender'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'

const onFormSubmit = () => {
trackEvent(SETTINGS_EVENTS.SPENDING_LIMIT.LIMIT_REMOVED)
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.spending_limit_remove })
}

export const RemoveSpendingLimit = ({ params }: { params: SpendingLimitState }) => {
const { setSafeTx, setSafeTxError } = useContext(SafeTxContext)
Expand Down Expand Up @@ -42,10 +48,6 @@ export const RemoveSpendingLimit = ({ params }: { params: SpendingLimitState })
createTx(txParams).then(setSafeTx).catch(setSafeTxError)
}, [chainId, params.beneficiary, params.token, setSafeTx, setSafeTxError])

const onFormSubmit = () => {
trackEvent(SETTINGS_EVENTS.SPENDING_LIMIT.LIMIT_REMOVED)
}

return (
<SignOrExecuteForm onSubmit={onFormSubmit}>
{token && (
Expand Down
7 changes: 6 additions & 1 deletion src/components/tx-flow/flows/SafeAppsTx/ReviewSafeAppsTx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ import { asError } from '@/services/exceptions/utils'

type ReviewSafeAppsTxProps = {
safeAppsTx: SafeAppsTxParams
onSubmit?: (txId: string, safeTxHash: string) => void
}

const ReviewSafeAppsTx = ({
safeAppsTx: { txs, requestId, params, appId, app },
onSubmit,
}: ReviewSafeAppsTxProps): ReactElement => {
const { safe } = useSafeInfo()
const onboard = useOnboard()
Expand Down Expand Up @@ -54,11 +56,14 @@ const ReviewSafeAppsTx = ({
if (!safeTx || !onboard) return
trackSafeAppTxCount(Number(appId))

let safeTxHash = ''
try {
await dispatchSafeAppsTx(safeTx, requestId, onboard, safe.chainId, txId)
safeTxHash = await dispatchSafeAppsTx(safeTx, requestId, onboard, safe.chainId, txId)
} catch (error) {
setSafeTxError(asError(error))
}

onSubmit?.(txId, safeTxHash)
}

const origin = useMemo(() => getTxOrigin(app), [app])
Expand Down
10 changes: 8 additions & 2 deletions src/components/tx-flow/flows/SafeAppsTx/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,20 @@ export type SafeAppsTxParams = {
params?: SendTransactionRequestParams
}

const SafeAppsTxFlow = ({ data }: { data: SafeAppsTxParams }) => {
const SafeAppsTxFlow = ({
data,
onSubmit,
}: {
data: SafeAppsTxParams
onSubmit?: (txId: string, safeTxHash: string) => void
}) => {
return (
<TxLayout
title="Confirm transaction"
subtitle={<AppTitle name={data.app?.name} logoUri={data.app?.iconUrl} />}
step={0}
>
<ReviewSafeAppsTx safeAppsTx={data} />
<ReviewSafeAppsTx safeAppsTx={data} onSubmit={onSubmit} />
</TxLayout>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import useHighlightHiddenTab from '@/hooks/useHighlightHiddenTab'
import { type SafeAppData } from '@safe-global/safe-gateway-typescript-sdk'
import { SafeTxContext } from '@/components/tx-flow/SafeTxProvider'
import { asError } from '@/services/exceptions/utils'
import { trackEvent } from '@/services/analytics'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'

export type SignMessageOnChainProps = {
app?: SafeAppData
Expand Down Expand Up @@ -98,6 +100,9 @@ const ReviewSignMessageOnChain = ({ message, method, requestId }: SignMessageOnC

const handleSubmit = async () => {
if (!safeTx || !onboard) return

trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.message })

try {
await dispatchSafeAppsTx(safeTx, requestId, onboard, safe.chainId)
} catch (error) {
Expand Down
18 changes: 15 additions & 3 deletions src/components/tx-flow/flows/TokenTransfer/ReviewTokenTx.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { type ReactElement } from 'react'
import { useCallback, type ReactElement } from 'react'
import { type TokenTransferParams, TokenTransferType } from '@/components/tx-flow/flows/TokenTransfer/index'
import ReviewTokenTransfer from '@/components/tx-flow/flows/TokenTransfer/ReviewTokenTransfer'
import ReviewSpendingLimitTx from '@/components/tx-flow/flows/TokenTransfer/ReviewSpendingLimitTx'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'
import { trackEvent } from '@/services/analytics'

// TODO: Split this into separate flows
const ReviewTokenTx = ({
Expand All @@ -15,10 +17,20 @@ const ReviewTokenTx = ({
}): ReactElement => {
const isSpendingLimitTx = params.type === TokenTransferType.spendingLimit

const onTxSubmit = useCallback(() => {
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.transfer_token })
onSubmit()
}, [onSubmit])

const onSpendingLimitTxSubmit = useCallback(() => {
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.spending_limit_transfer })
onSubmit()
}, [onSubmit])

return isSpendingLimitTx ? (
<ReviewSpendingLimitTx params={params} onSubmit={onSubmit} />
<ReviewSpendingLimitTx params={params} onSubmit={onSpendingLimitTxSubmit} />
) : (
<ReviewTokenTransfer params={params} onSubmit={onSubmit} txNonce={txNonce} />
<ReviewTokenTransfer params={params} onSubmit={onTxSubmit} txNonce={txNonce} />
)
}

Expand Down
8 changes: 7 additions & 1 deletion src/components/tx-flow/flows/UpdateSafe/UpdateSafeReview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ import { createUpdateSafeTxs } from '@/services/tx/safeUpdateParams'
import { createMultiSendCallOnlyTx } from '@/services/tx/tx-sender'
import { SafeTxContext } from '../../SafeTxProvider'
import SignOrExecuteForm from '@/components/tx/SignOrExecuteForm'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'
import { trackEvent } from '@/services/analytics'

const onSubmit = () => {
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.safe_update })
}

export const UpdateSafeReview = () => {
const { safe, safeLoaded } = useSafeInfo()
Expand All @@ -25,7 +31,7 @@ export const UpdateSafeReview = () => {
}, [chain, safe, safeLoaded, setNonce, setSafeTx, setSafeTxError])

return (
<SignOrExecuteForm onSubmit={() => null}>
<SignOrExecuteForm onSubmit={onSubmit}>
<Typography mb={2}>
Update now to take advantage of new features and the highest security standards available.
</Typography>
Expand Down
5 changes: 5 additions & 0 deletions src/hooks/messages/useSafeMsgTracking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useEffect } from 'react'

import { trackEvent, WALLET_EVENTS } from '@/services/analytics'
import { SafeMsgEvent, safeMsgSubscribe } from '@/services/safe-messages/safeMsgEvents'
import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions'

const safeMsgEvents = {
[SafeMsgEvent.PROPOSE]: WALLET_EVENTS.SIGN_MESSAGE,
Expand All @@ -13,6 +14,10 @@ export const useSafeMsgTracking = (): void => {
const unsubFns = Object.entries(safeMsgEvents).map(([safeMsgEvent, analyticsEvent]) =>
safeMsgSubscribe(safeMsgEvent as SafeMsgEvent, () => {
trackEvent(analyticsEvent)

if (analyticsEvent === WALLET_EVENTS.SIGN_MESSAGE) {
trackEvent({ ...TX_EVENTS.CREATE, label: TX_TYPES.message })
}
}),
)

Expand Down
4 changes: 4 additions & 0 deletions src/services/analytics/events/overview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,8 @@ export const OVERVIEW_EVENTS = {
action: 'Click on SEP5 allocation button',
category: OVERVIEW_CATEGORY,
},
SAFE_VIEWED: {
action: 'Safe viewed',
category: OVERVIEW_CATEGORY,
},
}
Loading

0 comments on commit bd2844b

Please sign in to comment.