Skip to content

Commit 75b796f

Browse files
alfetopitoLeandro Boscariol
andauthored
1029/fix local storage trades (gnosis#1108)
* Storing trades to localStorage by network AND address * Removed duplicated function `setStorageItem` Co-authored-by: Leandro Boscariol <[email protected]>
1 parent 991d689 commit 75b796f

File tree

3 files changed

+74
-66
lines changed

3 files changed

+74
-66
lines changed

src/const.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ export const STORAGE_PENDING_ORDER_TX_HASHES = {
140140
}
141141
export const STORAGE_KEY_DISABLED_TOKENS_ADDRESSES = 'disabledTokens'
142142

143-
export const TRADES_LOCAL_STORAGE_KEY = 'TRADES_PER_NETWORK'
143+
export const TRADES_LOCAL_STORAGE_KEY = 'TRADES_PER_ACCOUNT'
144144

145145
const LIQUIDITY_TOKEN_LIST_VALUES = process.env.LIQUIDITY_TOKEN_LIST || 'USDT,TUSD,USDC,PAX,GUSD,DAI,sUSD'
146146
export const LIQUIDITY_TOKEN_LIST = new Set(LIQUIDITY_TOKEN_LIST_VALUES.split(',').map(symbol => symbol.trim()))

src/hooks/useTrades.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { web3 } from 'api'
77

88
import { getTradesAndTradeReversions } from 'services'
99

10-
import { appendTrades, updateLastCheckedBlock } from 'reducers-actions/trades'
10+
import { appendTrades, updateLastCheckedBlock, buildAccountKey } from 'reducers-actions/trades'
1111

1212
import { useWalletConnection } from 'hooks/useWalletConnection'
1313
import useGlobalState from 'hooks/useGlobalState'
@@ -26,7 +26,10 @@ export function useTrades(): Trade[] {
2626
] = useGlobalState()
2727
const { userAddress, networkId } = useWalletConnection()
2828

29-
const { lastCheckedBlock = undefined, trades = [] } = networkId ? globalStateTrades[networkId] : {}
29+
const accountKey = networkId && userAddress && buildAccountKey({ networkId, userAddress })
30+
31+
const { lastCheckedBlock = undefined, trades = [] } =
32+
accountKey && globalStateTrades[accountKey] ? globalStateTrades[accountKey] : {}
3033

3134
useEffect(() => {
3235
// Flow control. Cancel query/state update on unmount
@@ -60,8 +63,8 @@ export function useTrades(): Trade[] {
6063

6164
dispatch(
6265
newTrades.length > 0 || reverts.length > 0
63-
? appendTrades({ trades: newTrades, reverts, lastCheckedBlock: toBlock, networkId })
64-
: updateLastCheckedBlock(toBlock, networkId),
66+
? appendTrades({ lastCheckedBlock: toBlock, networkId, userAddress, trades: newTrades, reverts })
67+
: updateLastCheckedBlock({ lastCheckedBlock: toBlock, networkId, userAddress }),
6568
)
6669
}
6770
}

src/reducers-actions/trades.ts

Lines changed: 66 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ import { Trade, TradeReversion, EventWithBlockInfo } from 'api/exchange/Exchange
44

55
import { Actions } from 'reducers-actions'
66

7-
import { logDebug, flattenMapOfLists, dateToBatchId, toBN } from 'utils'
7+
import { logDebug, flattenMapOfLists, dateToBatchId, toBN, setStorageItem } from 'utils'
88
import { TRADES_LOCAL_STORAGE_KEY } from 'const'
99

1010
// ******** TYPES/INTERFACES
1111

1212
export type ActionTypes = 'OVERWRITE_TRADES' | 'APPEND_TRADES' | 'UPDATE_BLOCK'
1313

14-
export type TradesState = Record<number, TradesStateSingleNetwork>
14+
export type TradesState = Record<string, TradesStatePerAccount>
1515

16-
interface TradesStateSingleNetwork {
16+
interface TradesStatePerAccount {
1717
trades: Trade[]
1818
pendingTrades: Map<string, Trade[]>
1919
lastCheckedBlock?: number
@@ -23,27 +23,28 @@ interface WithReverts {
2323
reverts: TradeReversion[]
2424
}
2525

26-
interface WithNetworkId {
26+
interface WithAccountInfo {
2727
networkId: number
28+
userAddress: string
2829
}
2930

3031
// ******** ACTION TYPES
3132

3233
type OverwriteTradesActionType = Actions<
3334
'OVERWRITE_TRADES',
34-
Omit<TradesStateSingleNetwork, 'pendingTrades'> & WithReverts & WithNetworkId
35+
Omit<TradesStatePerAccount, 'pendingTrades'> & WithReverts & WithAccountInfo
3536
>
3637
type AppendTradesActionType = Actions<
3738
'APPEND_TRADES',
38-
Required<Omit<TradesStateSingleNetwork, 'pendingTrades'>> & WithReverts & WithNetworkId
39+
Required<Omit<TradesStatePerAccount, 'pendingTrades'>> & WithReverts & WithAccountInfo
3940
>
4041
type UpdateBlockActionType = Actions<
4142
'UPDATE_BLOCK',
42-
Required<Pick<TradesStateSingleNetwork, 'lastCheckedBlock'>> & WithNetworkId
43+
Required<Pick<TradesStatePerAccount, 'lastCheckedBlock'>> & WithAccountInfo
4344
>
44-
type ReducerActionType = Actions<ActionTypes, TradesStateSingleNetwork & WithReverts & WithNetworkId>
45+
type ReducerActionType = Actions<ActionTypes, TradesStatePerAccount & WithReverts & WithAccountInfo>
4546

46-
interface Params extends WithNetworkId {
47+
interface Params extends WithAccountInfo {
4748
trades: Trade[]
4849
reverts: TradeReversion[]
4950
lastCheckedBlock?: number
@@ -61,11 +62,17 @@ export const appendTrades = (params: Required<Params>): AppendTradesActionType =
6162
payload: params,
6263
})
6364

64-
export const updateLastCheckedBlock = (lastCheckedBlock: number, networkId: number): UpdateBlockActionType => ({
65+
export const updateLastCheckedBlock = (
66+
params: Required<Pick<Params, 'lastCheckedBlock'>> & WithAccountInfo,
67+
): UpdateBlockActionType => ({
6568
type: 'UPDATE_BLOCK',
66-
payload: { lastCheckedBlock, networkId },
69+
payload: params,
6770
})
6871

72+
export function buildAccountKey({ networkId, userAddress }: WithAccountInfo): string {
73+
return networkId + '|' + userAddress
74+
}
75+
6976
function buildTradeRevertKey(batchId: number, orderId: string): string {
7077
return batchId + '|' + orderId
7178
}
@@ -186,55 +193,6 @@ function applyRevertsToTrades(
186193
return [flattenMapOfLists(tradesByRevertKey), getPendingTrades(tradesByRevertKey)]
187194
}
188195

189-
// ******** REDUCER
190-
191-
export const reducer = (state: TradesState, action: ReducerActionType): TradesState => {
192-
switch (action.type) {
193-
case 'APPEND_TRADES': {
194-
const { trades: newTrades, reverts, lastCheckedBlock, networkId } = action.payload
195-
const { trades: currTrades, pendingTrades: currPendingTrades } = state[networkId]
196-
197-
const [trades, pendingTrades] = applyRevertsToTrades(newTrades, reverts, currPendingTrades)
198-
199-
return { ...state, [networkId]: { trades: currTrades.concat(trades), lastCheckedBlock, pendingTrades } }
200-
}
201-
case 'OVERWRITE_TRADES': {
202-
const { trades: newTrades, reverts, lastCheckedBlock, networkId } = action.payload
203-
204-
const [trades, pendingTrades] = applyRevertsToTrades(newTrades, reverts)
205-
206-
return { ...state, [networkId]: { trades, lastCheckedBlock, pendingTrades } }
207-
}
208-
case 'UPDATE_BLOCK': {
209-
const { networkId, lastCheckedBlock } = action.payload
210-
211-
return { ...state, [networkId]: { ...state[networkId], lastCheckedBlock } }
212-
}
213-
default: {
214-
return state
215-
}
216-
}
217-
}
218-
219-
// TODO: use the one from David once his changes are merged https://github.com/gnosis/dex-react/pull/1091
220-
function setStorageItem(key: string, data: unknown): void {
221-
// localStorage API accepts only strings
222-
// TODO: consider switching to localForage API (accepts all types)
223-
const formattedData = JSON.stringify(data)
224-
return localStorage.setItem(key, formattedData)
225-
}
226-
227-
// ******** SIDE EFFECT
228-
229-
export async function sideEffect(state: TradesState, action: ReducerActionType): Promise<void> {
230-
switch (action.type) {
231-
case 'APPEND_TRADES':
232-
case 'OVERWRITE_TRADES':
233-
case 'UPDATE_BLOCK':
234-
setStorageItem(TRADES_LOCAL_STORAGE_KEY, state)
235-
}
236-
}
237-
238196
// ******** INITIAL STATE / LOCAL STORAGE
239197

240198
const INITIAL_TRADES_STATE_SINGLE_NETWORK = { trades: [], pendingTrades: new Map<string, Trade[]>() }
@@ -264,7 +222,7 @@ function reviver(key: string, value: unknown): unknown {
264222
}
265223

266224
function loadInitialState(): TradesState {
267-
let state = { 1: INITIAL_TRADES_STATE_SINGLE_NETWORK, 4: INITIAL_TRADES_STATE_SINGLE_NETWORK }
225+
let state = {}
268226

269227
const localStorageOrders = localStorage.getItem(TRADES_LOCAL_STORAGE_KEY)
270228

@@ -280,3 +238,50 @@ function loadInitialState(): TradesState {
280238
}
281239

282240
export const initialState = loadInitialState()
241+
242+
// ******** REDUCER
243+
244+
export const reducer = (state: TradesState, action: ReducerActionType): TradesState => {
245+
switch (action.type) {
246+
case 'APPEND_TRADES': {
247+
const { trades: newTrades, reverts, lastCheckedBlock, networkId, userAddress } = action.payload
248+
249+
const accountKey = buildAccountKey({ networkId, userAddress })
250+
251+
const { trades: currTrades, pendingTrades: currPendingTrades } =
252+
state[accountKey] || INITIAL_TRADES_STATE_SINGLE_NETWORK
253+
254+
const [trades, pendingTrades] = applyRevertsToTrades(newTrades, reverts, currPendingTrades)
255+
256+
return { ...state, [accountKey]: { trades: currTrades.concat(trades), lastCheckedBlock, pendingTrades } }
257+
}
258+
case 'OVERWRITE_TRADES': {
259+
const { trades: newTrades, reverts, lastCheckedBlock, networkId, userAddress } = action.payload
260+
261+
const accountKey = buildAccountKey({ networkId, userAddress })
262+
263+
const [trades, pendingTrades] = applyRevertsToTrades(newTrades, reverts)
264+
265+
return { ...state, [accountKey]: { trades, lastCheckedBlock, pendingTrades } }
266+
}
267+
case 'UPDATE_BLOCK': {
268+
const { networkId, lastCheckedBlock } = action.payload
269+
270+
return { ...state, [networkId]: { ...state[networkId], lastCheckedBlock } }
271+
}
272+
default: {
273+
return state
274+
}
275+
}
276+
}
277+
278+
// ******** SIDE EFFECT
279+
280+
export async function sideEffect(state: TradesState, action: ReducerActionType): Promise<void> {
281+
switch (action.type) {
282+
case 'APPEND_TRADES':
283+
case 'OVERWRITE_TRADES':
284+
case 'UPDATE_BLOCK':
285+
setStorageItem(TRADES_LOCAL_STORAGE_KEY, state)
286+
}
287+
}

0 commit comments

Comments
 (0)