Commit ae8c0377 authored by Christine Legge's avatar Christine Legge Committed by GitHub

refactor: move state/transactions to createSlice (#3758)

* use slice in transactions reducer

* update transaction reducer tests

* chore: move state/transactions types into their own folder

* fix: fix broken transaction/reducer tests
parent 8eaf1f49
......@@ -25,7 +25,7 @@ import {
VoteTransactionInfo,
WithdrawLiquidityStakingTransactionInfo,
WrapTransactionInfo,
} from '../../state/transactions/actions'
} from '../../state/transactions/types'
function formatAmount(amountRaw: string, decimals: number, sigFigs: number): string {
return new Fraction(amountRaw, JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(decimals))).toSignificant(sigFigs)
......
......@@ -10,7 +10,7 @@ import { AbstractConnector } from 'web3-react-abstract-connector'
import { ReactComponent as Close } from '../../assets/images/x.svg'
import { injected, walletlink } from '../../connectors'
import { SUPPORTED_WALLETS } from '../../constants/wallet'
import { clearAllTransactions } from '../../state/transactions/actions'
import { clearAllTransactions } from '../../state/transactions/reducer'
import { ExternalLink, LinkStyledButton, ThemedText } from '../../theme'
import { shortenAddress } from '../../utils'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
......
......@@ -13,7 +13,7 @@ import useENSName from '../../hooks/useENSName'
import { useHasSocks } from '../../hooks/useSocksBalance'
import { useWalletModalToggle } from '../../state/application/hooks'
import { isTransactionRecent, useAllTransactions } from '../../state/transactions/hooks'
import { TransactionDetails } from '../../state/transactions/reducer'
import { TransactionDetails } from '../../state/transactions/types'
import { shortenAddress } from '../../utils'
import { ButtonSecondary } from '../Button'
import StatusIcon from '../Identicon/StatusIcon'
......
......@@ -7,8 +7,8 @@ import styled from 'styled-components/macro'
import { useContract } from '../../hooks/useContract'
import { StakingInfo } from '../../state/stake/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { TransactionType } from '../../state/transactions/types'
import { CloseIcon, ThemedText } from '../../theme'
import { ButtonError } from '../Button'
import { AutoColumn } from '../Column'
......
......@@ -12,8 +12,8 @@ import { ApprovalState, useApproveCallback } from '../../hooks/useApproveCallbac
import { useContract, usePairContract, useV2RouterContract } from '../../hooks/useContract'
import useTransactionDeadline from '../../hooks/useTransactionDeadline'
import { StakingInfo, useDerivedStakeInfo } from '../../state/stake/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { TransactionType } from '../../state/transactions/types'
import { CloseIcon, ThemedText } from '../../theme'
import { formatCurrencyAmount } from '../../utils/formatCurrencyAmount'
import { maxAmountSpend } from '../../utils/maxAmountSpend'
......
......@@ -7,8 +7,8 @@ import styled from 'styled-components/macro'
import { useContract } from '../../hooks/useContract'
import { StakingInfo } from '../../state/stake/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { TransactionType } from '../../state/transactions/types'
import { CloseIcon, ThemedText } from '../../theme'
import { ButtonError } from '../Button'
import { AutoColumn } from '../Column'
......
......@@ -6,8 +6,8 @@ import useSwapApproval, { useSwapApprovalOptimizedTrade } from 'lib/hooks/swap/u
import { ApprovalState, useApproval } from 'lib/hooks/useApproval'
import { useCallback } from 'react'
import { TransactionType } from '../state/transactions/actions'
import { useHasPendingApproval, useTransactionAdder } from '../state/transactions/hooks'
import { TransactionType } from '../state/transactions/types'
export { ApprovalState } from 'lib/hooks/useApproval'
function useGetAndTrackApproval(getApproval: ReturnType<typeof useApproval>[1]) {
......
......@@ -3,7 +3,7 @@ import { initializeApp } from 'firebase/app'
import { getDatabase, push, ref } from 'firebase/database'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useCallback } from 'react'
import { TransactionInfo, TransactionType } from 'state/transactions/actions'
import { TransactionInfo, TransactionType } from 'state/transactions/types'
type PartialTransactionResponse = Pick<TransactionResponse, 'hash' | 'v' | 'r' | 's'>
......
......@@ -4,8 +4,8 @@ import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { SwapCallbackState, useSwapCallback as useLibSwapCallBack } from 'lib/hooks/swap/useSwapCallback'
import { ReactNode, useMemo } from 'react'
import { TransactionType } from '../state/transactions/actions'
import { useTransactionAdder } from '../state/transactions/hooks'
import { TransactionType } from '../state/transactions/types'
import { currencyId } from '../utils/currencyId'
import useENS from './useENS'
import { SignatureData } from './useERC20Permit'
......
......@@ -6,8 +6,8 @@ import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount'
import { useMemo } from 'react'
import { WRAPPED_NATIVE_CURRENCY } from '../constants/tokens'
import { TransactionType } from '../state/transactions/actions'
import { useTransactionAdder } from '../state/transactions/hooks'
import { TransactionType } from '../state/transactions/types'
import { useCurrencyBalance } from '../state/wallet/hooks'
import { useWETHContract } from './useContract'
......
......@@ -47,8 +47,8 @@ import { useUSDCValue } from '../../hooks/useUSDCPrice'
import { useV3PositionFromTokenId } from '../../hooks/useV3Positions'
import { useWalletModalToggle } from '../../state/application/hooks'
import { Bound, Field } from '../../state/mint/v3/actions'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { TransactionType } from '../../state/transactions/types'
import { useIsExpertMode, useUserSlippageToleranceWithDefault } from '../../state/user/hooks'
import { ExternalLink, ThemedText } from '../../theme'
import approveAmountCalldata from '../../utils/approveAmountCalldata'
......
......@@ -32,8 +32,8 @@ import { PairState } from '../../hooks/useV2Pairs'
import { useWalletModalToggle } from '../../state/application/hooks'
import { Field } from '../../state/mint/actions'
import { useDerivedMintInfo, useMintActionHandlers, useMintState } from '../../state/mint/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { TransactionType } from '../../state/transactions/types'
import { useIsExpertMode, useUserSlippageToleranceWithDefault } from '../../state/user/hooks'
import { ThemedText } from '../../theme'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
......
......@@ -44,7 +44,7 @@ import { useToken } from '../../hooks/Tokens'
import { usePairContract, useV2MigratorContract } from '../../hooks/useContract'
import useIsArgentWallet from '../../hooks/useIsArgentWallet'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { TransactionType } from '../../state/transactions/actions'
import { TransactionType } from '../../state/transactions/types'
import { useTokenBalance } from '../../state/wallet/hooks'
import { BackArrow, ExternalLink, ThemedText } from '../../theme'
import { isAddress } from '../../utils'
......
......@@ -42,7 +42,7 @@ import RateToggle from '../../components/RateToggle'
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
import { usePositionTokenURI } from '../../hooks/usePositionTokenURI'
import useTheme from '../../hooks/useTheme'
import { TransactionType } from '../../state/transactions/actions'
import { TransactionType } from '../../state/transactions/types'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { LoadingRows } from './styleds'
......
......@@ -34,7 +34,7 @@ import { ThemedText } from 'theme'
import TransactionConfirmationModal, { ConfirmationModalContent } from '../../components/TransactionConfirmationModal'
import { WRAPPED_NATIVE_CURRENCY } from '../../constants/tokens'
import { TransactionType } from '../../state/transactions/actions'
import { TransactionType } from '../../state/transactions/types'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { currencyId } from '../../utils/currencyId'
import AppBody from '../AppBody'
......
......@@ -33,8 +33,8 @@ import useTransactionDeadline from '../../hooks/useTransactionDeadline'
import { useWalletModalToggle } from '../../state/application/hooks'
import { Field } from '../../state/burn/actions'
import { useBurnActionHandlers, useBurnState, useDerivedBurnInfo } from '../../state/burn/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { TransactionType } from '../../state/transactions/types'
import { useUserSlippageToleranceWithDefault } from '../../state/user/hooks'
import { StyledInternalLink, ThemedText } from '../../theme'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
......
......@@ -11,8 +11,8 @@ import { UNI } from '../../constants/tokens'
import { useContract } from '../../hooks/useContract'
import { isAddress } from '../../utils'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { TransactionType } from '../transactions/actions'
import { useTransactionAdder } from '../transactions/hooks'
import { TransactionType } from '../transactions/types'
function useMerkleDistributorContract() {
return useContract(MERKLE_DISTRIBUTOR_ADDRESS, MERKLE_DISTRIBUTOR_ABI, true)
......
......@@ -32,8 +32,8 @@ import {
} from '../../constants/proposals'
import { UNI } from '../../constants/tokens'
import { useLogs } from '../logs/hooks'
import { TransactionType } from '../transactions/actions'
import { useTransactionAdder } from '../transactions/hooks'
import { TransactionType } from '../transactions/types'
import { VoteOption } from './types'
function useGovernanceV0Contract(): Contract | null {
......
......@@ -5,8 +5,8 @@ import { useTransactionMonitoringEventCallback } from 'hooks/useMonitoringEventC
import { useCallback, useMemo } from 'react'
import { useAppDispatch, useAppSelector } from 'state/hooks'
import { addTransaction, TransactionInfo, TransactionType } from './actions'
import { TransactionDetails } from './reducer'
import { addTransaction } from './reducer'
import { TransactionDetails, TransactionInfo, TransactionType } from './types'
// helper that can take a ethers library transaction response and add it to the list of transactions
export function useTransactionAdder(): (response: TransactionResponse, info: TransactionInfo) => void {
......
import { createStore, Store } from 'redux'
import { updateVersion } from '../global/actions'
import {
import reducer, {
addTransaction,
checkedTransaction,
clearAllTransactions,
finalizeTransaction,
TransactionType,
} from './actions'
import reducer, { initialState, TransactionState } from './reducer'
initialState,
TransactionState,
} from './reducer'
import { TransactionType } from './types'
describe('transaction reducer', () => {
let store: Store<TransactionState>
......
import { createReducer } from '@reduxjs/toolkit'
import { createSlice } from '@reduxjs/toolkit'
import { updateVersion } from '../global/actions'
import {
addTransaction,
checkedTransaction,
clearAllTransactions,
finalizeTransaction,
SerializableTransactionReceipt,
TransactionInfo,
} from './actions'
import { TransactionDetails } from './types'
const now = () => new Date().getTime()
export interface TransactionDetails {
hash: string
receipt?: SerializableTransactionReceipt
lastCheckedBlockNumber?: number
addedTime: number
confirmedTime?: number
from: string
info: TransactionInfo
}
export interface TransactionState {
[chainId: number]: {
[txHash: string]: TransactionDetails
......@@ -30,33 +13,23 @@ export interface TransactionState {
export const initialState: TransactionState = {}
export default createReducer(initialState, (builder) =>
builder
.addCase(updateVersion, (transactions) => {
// in case there are any transactions in the store with the old format, remove them
Object.keys(transactions).forEach((chainId) => {
const chainTransactions = transactions[chainId as unknown as number]
Object.keys(chainTransactions).forEach((hash) => {
if (!('info' in chainTransactions[hash])) {
// clear old transactions that don't have the right format
delete chainTransactions[hash]
}
})
})
})
.addCase(addTransaction, (transactions, { payload: { chainId, from, hash, info } }) => {
const transactionSlice = createSlice({
name: 'transactions',
initialState,
reducers: {
addTransaction(transactions, { payload: { chainId, from, hash, info } }) {
if (transactions[chainId]?.[hash]) {
throw Error('Attempted to add existing transaction.')
}
const txs = transactions[chainId] ?? {}
txs[hash] = { hash, info, from, addedTime: now() }
transactions[chainId] = txs
})
.addCase(clearAllTransactions, (transactions, { payload: { chainId } }) => {
},
clearAllTransactions(transactions, { payload: { chainId } }) {
if (!transactions[chainId]) return
transactions[chainId] = {}
})
.addCase(checkedTransaction, (transactions, { payload: { chainId, hash, blockNumber } }) => {
},
checkedTransaction(transactions, { payload: { chainId, hash, blockNumber } }) {
const tx = transactions[chainId]?.[hash]
if (!tx) {
return
......@@ -66,13 +39,32 @@ export default createReducer(initialState, (builder) =>
} else {
tx.lastCheckedBlockNumber = Math.max(blockNumber, tx.lastCheckedBlockNumber)
}
})
.addCase(finalizeTransaction, (transactions, { payload: { hash, chainId, receipt } }) => {
},
finalizeTransaction(transactions, { payload: { hash, chainId, receipt } }) {
const tx = transactions[chainId]?.[hash]
if (!tx) {
return
}
tx.receipt = receipt
tx.confirmedTime = now()
},
},
extraReducers: (builder) => {
builder.addCase(updateVersion, (transactions) => {
// in case there are any transactions in the store with the old format, remove them
Object.keys(transactions).forEach((chainId) => {
const chainTransactions = transactions[chainId as unknown as number]
Object.keys(chainTransactions).forEach((hash) => {
if (!('info' in chainTransactions[hash])) {
// clear old transactions that don't have the right format
delete chainTransactions[hash]
}
})
)
})
})
},
})
export const { addTransaction, clearAllTransactions, checkedTransaction, finalizeTransaction } =
transactionSlice.actions
export default transactionSlice.reducer
import { createAction } from '@reduxjs/toolkit'
import { TradeType } from '@uniswap/sdk-core'
import { VoteOption } from '../governance/types'
export interface SerializableTransactionReceipt {
interface SerializableTransactionReceipt {
to: string
from: string
contractAddress: string
......@@ -171,20 +170,12 @@ export type TransactionInfo =
| RemoveLiquidityV3TransactionInfo
| SubmitProposalTransactionInfo
export const addTransaction = createAction<{
chainId: number
export interface TransactionDetails {
hash: string
receipt?: SerializableTransactionReceipt
lastCheckedBlockNumber?: number
addedTime: number
confirmedTime?: number
from: string
info: TransactionInfo
}>('transactions/addTransaction')
export const clearAllTransactions = createAction<{ chainId: number }>('transactions/clearAllTransactions')
export const finalizeTransaction = createAction<{
chainId: number
hash: string
receipt: SerializableTransactionReceipt
}>('transactions/finalizeTransaction')
export const checkedTransaction = createAction<{
chainId: number
hash: string
blockNumber: number
}>('transactions/checkedTransaction')
}
......@@ -6,7 +6,7 @@ import { useAppDispatch, useAppSelector } from 'state/hooks'
import { L2_CHAIN_IDS } from '../../constants/chains'
import { useAddPopup } from '../application/hooks'
import { checkedTransaction, finalizeTransaction } from './actions'
import { checkedTransaction, finalizeTransaction } from './reducer'
export default function Updater() {
const { chainId } = useActiveWeb3React()
......
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