Skip to content

Commit

Permalink
chore(points): add track points event to transaction watcher (#5441)
Browse files Browse the repository at this point in the history
### Description

In case the transaction is not settled within the same app session, we
should add the points tracking to the transaction watcher as well.

I added the network to the tracked event, in preparation for network
specific activities.

### Test plan

n/a

### Related issues

n/a

### Backwards compatibility

Y

### Network scalability

If a new NetworkId and/or Network are added in the future, the changes
in this PR will:

- [x] Continue to work without code changes, OR trigger a compilation
error (guaranteeing we find it when a new network is added)
  • Loading branch information
kathaypacific committed May 23, 2024
1 parent d35a51b commit cb1b97b
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/points/slice.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { NetworkId } from 'src/transactions/types'
import reducer, {
PendingPointsEvent,
initialState,
Expand All @@ -14,7 +15,7 @@ const pendingCreateWalletEvent: PendingPointsEvent = {
const pendingSwapEvent: PendingPointsEvent = {
id: 'test-id-2',
timestamp: '2024-04-22T12:00:00.000Z',
event: { activityId: 'swap', transactionHash: '0xTEST' },
event: { activityId: 'swap', transactionHash: '0xTEST', networkId: NetworkId['celo-alfajores'] },
}

describe('pending points events', () => {
Expand Down
2 changes: 2 additions & 0 deletions src/points/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'
import { NetworkId } from 'src/transactions/types'

const pointsActivities = ['create-wallet', 'swap', 'more-coming'] as const
export type PointsActivityId = (typeof pointsActivities)[number]
Expand Down Expand Up @@ -84,6 +85,7 @@ interface PointsEventCreateWallet {
interface PointsEventSwap {
activityId: 'swap'
transactionHash: string
networkId: NetworkId
}

export type PointsEvent = PointsEventCreateWallet | PointsEventSwap
8 changes: 8 additions & 0 deletions src/swap/saga.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { EffectProviders, StaticProvider, dynamic } from 'redux-saga-test-plan/p
import { SwapEvents } from 'src/analytics/Events'
import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import { navigate, navigateHome } from 'src/navigator/NavigationService'
import { trackPointsEvent } from 'src/points/slice'
import { getDynamicConfigParams } from 'src/statsig'
import { swapSubmitSaga } from 'src/swap/saga'
import { swapCancel, swapError, swapStart, swapSuccess } from 'src/swap/slice'
Expand Down Expand Up @@ -555,6 +556,13 @@ describe(swapSubmitSaga, () => {
},
})
.call([publicClient.celo, 'waitForTransactionReceipt'], { hash: '0x1' })
.put(
trackPointsEvent({
activityId: 'swap',
transactionHash: '0x1',
networkId: NetworkId['celo-alfajores'],
})
)
.run()

expect(mockViemWallet.signTransaction).toHaveBeenCalledTimes(1)
Expand Down
1 change: 1 addition & 0 deletions src/swap/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ export function* swapSubmitSaga(action: PayloadAction<SwapInfo>) {
trackPointsEvent({
activityId: 'swap',
transactionHash: swapTxReceipt.transactionHash,
networkId,
})
)
ValoraAnalytics.track(SwapEvents.swap_execute_success, {
Expand Down
57 changes: 57 additions & 0 deletions src/transactions/saga.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { expectSaga } from 'redux-saga-test-plan'
import * as matchers from 'redux-saga-test-plan/matchers'
import { EffectProviders, StaticProvider } from 'redux-saga-test-plan/providers'
import { call } from 'redux-saga/effects'
import { trackPointsEvent } from 'src/points/slice'
import { getSupportedNetworkIdsForSend, getSupportedNetworkIdsForSwap } from 'src/tokens/utils'
import {
transactionConfirmed,
Expand All @@ -30,6 +31,7 @@ import { getContractKit, getContractKitAsync } from 'src/web3/contracts'
import { createMockStore } from 'test/utils'
import {
mockAccount,
mockCeurTokenId,
mockCusdAddress,
mockCusdTokenId,
mockEthTokenId,
Expand Down Expand Up @@ -210,6 +212,59 @@ describe('watchPendingTransactions', () => {
1701102971000
)
)
.not.put(trackPointsEvent(expect.any(Object))) // transaction reverted, no points
.run()
})

it('updates and tracks the pending swap transaction', async () => {
const standbySwaptransaction: StandbyTransaction = {
__typename: 'TokenExchangeV3',
context: {
id: transactionId,
},
status: TransactionStatus.Pending,
networkId: NetworkId['celo-alfajores'],
type: TokenTransactionTypeV2.SwapTransaction,
transactionHash,
timestamp: 1234,
inAmount: {
tokenId: mockCeurTokenId,
value: 2.93,
},
outAmount: {
tokenId: mockCusdTokenId,
value: 2.87,
},
metadata: {},
}
await expectSaga(internalWatchPendingTransactionsInNetwork, Network.Celo)
.withState(
createMockStore({
transactions: {
standbyTransactions: [standbySwaptransaction],
},
}).getState()
)
.provide(createDefaultProviders(Network.Celo))
.put(
transactionConfirmed(
transactionId,
{
transactionHash,
block: '123',
status: TransactionStatus.Complete,
fees: [],
},
1701102971000
)
)
.put(
trackPointsEvent({
activityId: 'swap',
transactionHash,
networkId: NetworkId['celo-alfajores'],
})
)
.run()
})

Expand Down Expand Up @@ -243,6 +298,7 @@ describe('watchPendingTransactions', () => {
1701102971000
)
)
.not.put(trackPointsEvent(expect.any(Object))) // not a swap transaction
.run()
})

Expand Down Expand Up @@ -302,6 +358,7 @@ describe('watchPendingTransactions', () => {
...createDefaultProviders(Network.Celo),
])
.not.put(transactionConfirmed(expect.any(String), expect.any(Object), expect.any(Number)))
.not.put(trackPointsEvent(expect.any(Object))) // no receipt, no points
.run()
})

Expand Down
12 changes: 10 additions & 2 deletions src/transactions/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ErrorMessages } from 'src/app/ErrorMessages'
import { Actions as IdentityActions } from 'src/identity/actions'
import { AddressToE164NumberType } from 'src/identity/reducer'
import { addressToE164NumberSelector } from 'src/identity/selectors'
import { trackPointsEvent } from 'src/points/slice'
import { NumberToRecipient } from 'src/recipients/recipient'
import { phoneRecipientCacheSelector } from 'src/recipients/reducer'
import { tokensByIdSelector } from 'src/tokens/selectors'
Expand Down Expand Up @@ -255,7 +256,8 @@ export function* getTransactionReceipt(
transaction: StandbyTransaction & { transactionHash: string },
network: Network
) {
const { feeCurrencyId, transactionHash } = transaction
const { feeCurrencyId, transactionHash, __typename } = transaction
const networkId = networkConfig.networkToNetworkId[network]

try {
const receipt = yield* call([publicClient[network], 'waitForTransactionReceipt'], {
Expand All @@ -267,10 +269,16 @@ export function* getTransactionReceipt(
handleTransactionReceiptReceived,
transaction.context.id,
receipt,
networkConfig.networkToNetworkId[network],
networkId,
feeCurrencyId
)
}

if (receipt.status === 'success') {
if (__typename === 'TokenExchangeV3') {
yield* put(trackPointsEvent({ activityId: 'swap', transactionHash, networkId }))
}
}
} catch (e) {
Logger.warn(
TAG,
Expand Down
4 changes: 4 additions & 0 deletions test/RootStateSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2834,12 +2834,16 @@
"const": "swap",
"type": "string"
},
"networkId": {
"$ref": "#/definitions/NetworkId"
},
"transactionHash": {
"type": "string"
}
},
"required": [
"activityId",
"networkId",
"transactionHash"
],
"type": "object"
Expand Down

0 comments on commit cb1b97b

Please sign in to comment.