Commit ab214a81 authored by cartcrom's avatar cartcrom Committed by GitHub

fix: only use local txs for current account (#6284)

* fix: only use local txs for current account

* refactor: remove unecessary try/catch

* fix: add back try/catch
parent 1b2d86ae
...@@ -101,7 +101,7 @@ export function ActivityTab({ account }: { account: string }) { ...@@ -101,7 +101,7 @@ export function ActivityTab({ account }: { account: string }) {
const [drawerOpen, toggleWalletDrawer] = useWalletDrawer() const [drawerOpen, toggleWalletDrawer] = useWalletDrawer()
const [lastFetched, setLastFetched] = useAtom(lastFetchedAtom) const [lastFetched, setLastFetched] = useAtom(lastFetchedAtom)
const localMap = useLocalActivities() const localMap = useLocalActivities(account)
const { data, loading, refetch } = useTransactionListQuery({ const { data, loading, refetch } = useTransactionListQuery({
variables: { account }, variables: { account },
......
// jest unit tests for the parseLocalActivity function // jest unit tests for the parseLocalActivity function
import { SupportedChainId, Token, TradeType } from '@uniswap/sdk-core' import { SupportedChainId, Token, TradeType as MockTradeType } from '@uniswap/sdk-core'
import { DAI, USDC_MAINNET } from 'constants/tokens' import { DAI as MockDAI, USDC_MAINNET as MockUSDC_MAINNET } from 'constants/tokens'
import { TokenAddressMap } from 'state/lists/hooks' import { TokenAddressMap } from 'state/lists/hooks'
import { WrappedTokenInfo } from 'state/lists/wrappedTokenInfo' import { WrappedTokenInfo } from 'state/lists/wrappedTokenInfo'
import { import {
...@@ -10,23 +10,24 @@ import { ...@@ -10,23 +10,24 @@ import {
TransactionDetails, TransactionDetails,
TransactionType, TransactionType,
} from 'state/transactions/types' } from 'state/transactions/types'
import { renderHook } from 'test-utils'
import { parseLocalActivity } from './parseLocal' import { parseLocalActivity, useLocalActivities } from './parseLocal'
const oneUSDCRaw = '1000000' const oneUSDCRaw = '1000000'
const oneDAIRaw = '1000000000000000000' const oneDAIRaw = '1000000000000000000'
function buildSwapInfo( function mockSwapInfo(
type: TradeType, type: MockTradeType,
inputCurrency: Token, inputCurrency: Token,
inputCurrencyAmountRaw: string, inputCurrencyAmountRaw: string,
outputCurrency: Token, outputCurrency: Token,
outputCurrencyAmountRaw: string outputCurrencyAmountRaw: string
): ExactInputSwapTransactionInfo | ExactOutputSwapTransactionInfo { ): ExactInputSwapTransactionInfo | ExactOutputSwapTransactionInfo {
if (type === TradeType.EXACT_INPUT) { if (type === MockTradeType.EXACT_INPUT) {
return { return {
type: TransactionType.SWAP, type: TransactionType.SWAP,
tradeType: TradeType.EXACT_INPUT, tradeType: MockTradeType.EXACT_INPUT,
inputCurrencyId: inputCurrency.address, inputCurrencyId: inputCurrency.address,
inputCurrencyAmountRaw, inputCurrencyAmountRaw,
outputCurrencyId: outputCurrency.address, outputCurrencyId: outputCurrency.address,
...@@ -36,7 +37,7 @@ function buildSwapInfo( ...@@ -36,7 +37,7 @@ function buildSwapInfo(
} else { } else {
return { return {
type: TransactionType.SWAP, type: TransactionType.SWAP,
tradeType: TradeType.EXACT_OUTPUT, tradeType: MockTradeType.EXACT_OUTPUT,
inputCurrencyId: inputCurrency.address, inputCurrencyId: inputCurrency.address,
expectedInputCurrencyAmountRaw: inputCurrencyAmountRaw, expectedInputCurrencyAmountRaw: inputCurrencyAmountRaw,
maximumInputCurrencyAmountRaw: inputCurrencyAmountRaw, maximumInputCurrencyAmountRaw: inputCurrencyAmountRaw,
...@@ -46,7 +47,44 @@ function buildSwapInfo( ...@@ -46,7 +47,44 @@ function buildSwapInfo(
} }
} }
function buildTokenAddressMap(...tokens: WrappedTokenInfo[]): TokenAddressMap { const mockAccount1 = '0x000000000000000000000000000000000000000001'
const mockAccount2 = '0x000000000000000000000000000000000000000002'
const mockChainId = SupportedChainId.MAINNET
jest.mock('../../../../state/transactions/hooks', () => {
return {
useMultichainTransactions: () => {
return [
[
{
info: mockSwapInfo(MockTradeType.EXACT_INPUT, MockUSDC_MAINNET, oneUSDCRaw, MockDAI, oneDAIRaw),
hash: '0x123',
from: mockAccount1,
} as TransactionDetails,
mockChainId,
],
[
{
info: mockSwapInfo(MockTradeType.EXACT_INPUT, MockUSDC_MAINNET, oneUSDCRaw, MockDAI, oneDAIRaw),
hash: '0x456',
from: mockAccount2,
} as TransactionDetails,
mockChainId,
],
[
{
info: mockSwapInfo(MockTradeType.EXACT_INPUT, MockUSDC_MAINNET, oneUSDCRaw, MockDAI, oneDAIRaw),
hash: '0x789',
from: mockAccount2,
} as TransactionDetails,
mockChainId,
],
]
},
}
})
function mockTokenAddressMap(...tokens: WrappedTokenInfo[]): TokenAddressMap {
return { return {
[SupportedChainId.MAINNET]: Object.fromEntries(tokens.map((token) => [token.address, { token }])), [SupportedChainId.MAINNET]: Object.fromEntries(tokens.map((token) => [token.address, { token }])),
} }
...@@ -55,27 +93,27 @@ function buildTokenAddressMap(...tokens: WrappedTokenInfo[]): TokenAddressMap { ...@@ -55,27 +93,27 @@ function buildTokenAddressMap(...tokens: WrappedTokenInfo[]): TokenAddressMap {
describe('parseLocalActivity', () => { describe('parseLocalActivity', () => {
it('returns swap activity fields with known tokens, exact input', () => { it('returns swap activity fields with known tokens, exact input', () => {
const details = { const details = {
info: buildSwapInfo(TradeType.EXACT_INPUT, USDC_MAINNET, oneUSDCRaw, DAI, oneDAIRaw), info: mockSwapInfo(MockTradeType.EXACT_INPUT, MockUSDC_MAINNET, oneUSDCRaw, MockDAI, oneDAIRaw),
receipt: { receipt: {
transactionHash: '0x123', transactionHash: '0x123',
status: 1, status: 1,
}, },
} as TransactionDetails } as TransactionDetails
const chainId = SupportedChainId.MAINNET const chainId = SupportedChainId.MAINNET
const tokens = buildTokenAddressMap(USDC_MAINNET as WrappedTokenInfo, DAI as WrappedTokenInfo) const tokens = mockTokenAddressMap(MockUSDC_MAINNET as WrappedTokenInfo, MockDAI as WrappedTokenInfo)
expect(parseLocalActivity(details, chainId, tokens)).toEqual({ expect(parseLocalActivity(details, chainId, tokens)).toEqual({
chainId: 1, chainId: 1,
currencies: [USDC_MAINNET, DAI], currencies: [MockUSDC_MAINNET, MockDAI],
descriptor: '1.00 USDC for 1.00 DAI', descriptor: '1.00 USDC for 1.00 DAI',
hash: undefined, hash: undefined,
receipt: { receipt: {
id: '0x123', id: '0x123',
info: { info: {
type: 1, type: 1,
tradeType: TradeType.EXACT_INPUT, tradeType: MockTradeType.EXACT_INPUT,
inputCurrencyId: USDC_MAINNET.address, inputCurrencyId: MockUSDC_MAINNET.address,
inputCurrencyAmountRaw: oneUSDCRaw, inputCurrencyAmountRaw: oneUSDCRaw,
outputCurrencyId: DAI.address, outputCurrencyId: MockDAI.address,
expectedOutputCurrencyAmountRaw: oneDAIRaw, expectedOutputCurrencyAmountRaw: oneDAIRaw,
minimumOutputCurrencyAmountRaw: oneDAIRaw, minimumOutputCurrencyAmountRaw: oneDAIRaw,
}, },
...@@ -91,28 +129,28 @@ describe('parseLocalActivity', () => { ...@@ -91,28 +129,28 @@ describe('parseLocalActivity', () => {
it('returns swap activity fields with known tokens, exact output', () => { it('returns swap activity fields with known tokens, exact output', () => {
const details = { const details = {
info: buildSwapInfo(TradeType.EXACT_OUTPUT, USDC_MAINNET, oneUSDCRaw, DAI, oneDAIRaw), info: mockSwapInfo(MockTradeType.EXACT_OUTPUT, MockUSDC_MAINNET, oneUSDCRaw, MockDAI, oneDAIRaw),
receipt: { receipt: {
transactionHash: '0x123', transactionHash: '0x123',
status: 1, status: 1,
}, },
} as TransactionDetails } as TransactionDetails
const chainId = SupportedChainId.MAINNET const chainId = SupportedChainId.MAINNET
const tokens = buildTokenAddressMap(USDC_MAINNET as WrappedTokenInfo, DAI as WrappedTokenInfo) const tokens = mockTokenAddressMap(MockUSDC_MAINNET as WrappedTokenInfo, MockDAI as WrappedTokenInfo)
expect(parseLocalActivity(details, chainId, tokens)).toEqual({ expect(parseLocalActivity(details, chainId, tokens)).toEqual({
chainId: 1, chainId: 1,
currencies: [USDC_MAINNET, DAI], currencies: [MockUSDC_MAINNET, MockDAI],
descriptor: '1.00 USDC for 1.00 DAI', descriptor: '1.00 USDC for 1.00 DAI',
hash: undefined, hash: undefined,
receipt: { receipt: {
id: '0x123', id: '0x123',
info: { info: {
type: 1, type: 1,
tradeType: TradeType.EXACT_OUTPUT, tradeType: MockTradeType.EXACT_OUTPUT,
inputCurrencyId: USDC_MAINNET.address, inputCurrencyId: MockUSDC_MAINNET.address,
expectedInputCurrencyAmountRaw: oneUSDCRaw, expectedInputCurrencyAmountRaw: oneUSDCRaw,
maximumInputCurrencyAmountRaw: oneUSDCRaw, maximumInputCurrencyAmountRaw: oneUSDCRaw,
outputCurrencyId: DAI.address, outputCurrencyId: MockDAI.address,
outputCurrencyAmountRaw: oneDAIRaw, outputCurrencyAmountRaw: oneDAIRaw,
}, },
receipt: { status: 1, transactionHash: '0x123' }, receipt: { status: 1, transactionHash: '0x123' },
...@@ -127,7 +165,7 @@ describe('parseLocalActivity', () => { ...@@ -127,7 +165,7 @@ describe('parseLocalActivity', () => {
it('returns swap activity fields with unknown tokens', () => { it('returns swap activity fields with unknown tokens', () => {
const details = { const details = {
info: buildSwapInfo(TradeType.EXACT_INPUT, USDC_MAINNET, oneUSDCRaw, DAI, oneDAIRaw), info: mockSwapInfo(MockTradeType.EXACT_INPUT, MockUSDC_MAINNET, oneUSDCRaw, MockDAI, oneDAIRaw),
receipt: { receipt: {
transactionHash: '0x123', transactionHash: '0x123',
status: 1, status: 1,
...@@ -144,10 +182,10 @@ describe('parseLocalActivity', () => { ...@@ -144,10 +182,10 @@ describe('parseLocalActivity', () => {
id: '0x123', id: '0x123',
info: { info: {
type: 1, type: 1,
tradeType: TradeType.EXACT_INPUT, tradeType: MockTradeType.EXACT_INPUT,
inputCurrencyId: USDC_MAINNET.address, inputCurrencyId: MockUSDC_MAINNET.address,
inputCurrencyAmountRaw: oneUSDCRaw, inputCurrencyAmountRaw: oneUSDCRaw,
outputCurrencyId: DAI.address, outputCurrencyId: MockDAI.address,
expectedOutputCurrencyAmountRaw: oneDAIRaw, expectedOutputCurrencyAmountRaw: oneDAIRaw,
minimumOutputCurrencyAmountRaw: oneDAIRaw, minimumOutputCurrencyAmountRaw: oneDAIRaw,
}, },
...@@ -160,4 +198,12 @@ describe('parseLocalActivity', () => { ...@@ -160,4 +198,12 @@ describe('parseLocalActivity', () => {
title: 'Swapped', title: 'Swapped',
}) })
}) })
it('only returns activity for the current account', () => {
const account1Activites = renderHook(() => useLocalActivities(mockAccount1)).result.current
const account2Activites = renderHook(() => useLocalActivities(mockAccount2)).result.current
expect(Object.values(account1Activites)).toHaveLength(1)
expect(Object.values(account2Activites)).toHaveLength(2)
})
}) })
...@@ -2,7 +2,6 @@ import { t } from '@lingui/macro' ...@@ -2,7 +2,6 @@ import { t } from '@lingui/macro'
import { formatCurrencyAmount } from '@uniswap/conedison/format' import { formatCurrencyAmount } from '@uniswap/conedison/format'
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core' import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { nativeOnChain } from '@uniswap/smart-order-router' import { nativeOnChain } from '@uniswap/smart-order-router'
import { useWeb3React } from '@web3-react/core'
import { SupportedChainId } from 'constants/chains' import { SupportedChainId } from 'constants/chains'
import { TransactionPartsFragment, TransactionStatus } from 'graphql/data/__generated__/types-and-hooks' import { TransactionPartsFragment, TransactionStatus } from 'graphql/data/__generated__/types-and-hooks'
import { useMemo } from 'react' import { useMemo } from 'react'
...@@ -135,6 +134,7 @@ export function parseLocalActivity( ...@@ -135,6 +134,7 @@ export function parseLocalActivity(
chainId: SupportedChainId, chainId: SupportedChainId,
tokens: TokenAddressMap tokens: TokenAddressMap
): Activity | undefined { ): Activity | undefined {
try {
const status = !details.receipt const status = !details.receipt
? TransactionStatus.Pending ? TransactionStatus.Pending
: details.receipt.status === 1 || details.receipt?.status === undefined : details.receipt.status === 1 || details.receipt?.status === undefined
...@@ -180,26 +180,23 @@ export function parseLocalActivity( ...@@ -180,26 +180,23 @@ export function parseLocalActivity(
} }
return { ...defaultFields, ...additionalFields } return { ...defaultFields, ...additionalFields }
} catch (error) {
console.debug(`Failed to parse transaction ${details.hash}`, error)
return undefined
}
} }
export function useLocalActivities(): ActivityMap | undefined { export function useLocalActivities(account: string): ActivityMap {
const allTransactions = useMultichainTransactions() const allTransactions = useMultichainTransactions()
const { chainId } = useWeb3React()
const tokens = useCombinedActiveList() const tokens = useCombinedActiveList()
return useMemo( return useMemo(() => {
() => const activityByHash: ActivityMap = {}
chainId for (const [transaction, chainId] of allTransactions) {
? allTransactions.reduce((acc: { [hash: string]: Activity }, [transaction, chainId]) => { if (transaction.from !== account) continue
try {
const localActivity = parseLocalActivity(transaction, chainId, tokens) activityByHash[transaction.hash] = parseLocalActivity(transaction, chainId, tokens)
if (localActivity) acc[localActivity.hash] = localActivity
} catch (error) {
console.error('Failed to parse local activity', transaction)
} }
return acc return activityByHash
}, {}) }, [account, allTransactions, tokens])
: undefined,
[allTransactions, chainId, tokens]
)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment