Skip to content

Commit

Permalink
Us 1169 - Added transactions as a slice to redux (#364)
Browse files Browse the repository at this point in the history
* US-1169 Initial commit

* US-1169 - Finished implementation

* Fixed RIFSockets.test.tsx after rebase

* useOnSocketChangeEmitted.ts -> changed to switch
types.ts -> fixed any

* Added reset function

* Added init socket event to redux

* Added appStateSlice.ts
Modified reset to use redux socketReset

* Added events to the transactions slice.
I added it so that we'll be able to store the events, and consume them if necessary, but this is not being used anywhere apart from the EventsScreen which is not being used.

* Homescreen will now consume isSetup from appState from redux

* Moved actions to shared/actions dir for better redability

* Removed RIFSockets.tsx
Modified Core.tsx to use new hook without a provider

* Cleaning up tpyes.ts
useRifSockets.ts will receive wallet and mnemonic as props

* Removed unused files
Modified useOnSocketChangeEmitted.ts to inline dispatch actions

* RifWalletServicesSocket.ts - should not return null. Should at least return the originTransaction

* Reorganized useOnSocketChangeEmitted.ts
Fixed types and eslint and typescript errors

* Fixed SendScreen.tsx

* Fixed Core.tsx non null assertion

* Fixed eslint issues with the new redux implementation
  • Loading branch information
Freshenext authored Dec 5, 2022
1 parent 0350054 commit e383570
Show file tree
Hide file tree
Showing 32 changed files with 385 additions and 506 deletions.
111 changes: 57 additions & 54 deletions src/core/Core.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useEffect, useState } from 'react'
import { StatusBar, StyleSheet, View } from 'react-native'
import { AppContext } from '../Context'
import { KeyManagementSystem, RIFWallet } from '../lib/core'
import { i18nInit } from '../lib/i18n'
import { KeyManagementSystem, RIFWallet } from 'lib/core'
import { i18nInit } from 'lib/i18n'

import { hasKeys, hasPin } from '../storage/MainStorage'
import {
Expand All @@ -15,19 +15,18 @@ import {
import {
RootNavigationComponent,
RootStackParamList,
} from '../navigation/rootNavigator'
} from 'navigation/rootNavigator'
import ModalComponent from '../ux/requestsModal/ModalComponent'

import {
createNavigationContainerRef,
NavigationContainer,
NavigationState,
} from '@react-navigation/native'
import { useSetGlobalError } from '../components/GlobalErrorHandler'
import { LoadingScreen } from '../components/loading/LoadingScreen'
import { WalletConnectProviderElement } from '../screens/walletConnect/WalletConnectContext'
import { useSetGlobalError } from 'components/GlobalErrorHandler'
import { LoadingScreen } from 'components/loading/LoadingScreen'
import { WalletConnectProviderElement } from 'screens/walletConnect/WalletConnectContext'
import { colors } from '../styles'
import { RIFSocketsProvider } from '../subscriptions/RIFSockets'
import { Cover } from './components/Cover'
import { RequestPIN } from './components/RequestPIN'
import { useBitcoinCore } from './hooks/bitcoin/useBitcoinCore'
Expand All @@ -36,6 +35,7 @@ import { useKeyManagementSystem } from './hooks/useKeyManagementSystem'
import { useRequests } from './hooks/useRequests'
import { useStateSubscription } from './hooks/useStateSubscription'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { useRifSockets } from 'src/subscriptions/useRifSockets'

export const navigationContainerRef =
createNavigationContainerRef<RootStackParamList>()
Expand Down Expand Up @@ -81,6 +81,14 @@ export const Core = () => {
const retrieveChainId = (wallet: RIFWallet) =>
wallet.getChainId().then(chainId => setState({ ...state, chainId }))

useRifSockets({
rifServiceSocket: rifWalletServicesSocket,
abiEnhancer,
appActive: active,
wallet: state.wallets[state.selectedWallet],
mnemonic: state.kms?.mnemonic,
})

const BitcoinCore = useBitcoinCore(state?.kms?.mnemonic || '', onRequest)

useEffect(() => {
Expand Down Expand Up @@ -138,55 +146,50 @@ export const Core = () => {
onStateChange={handleScreenChange}
ref={navigationContainerRef}>
<WalletConnectProviderElement>
<RIFSocketsProvider
rifServiceSocket={rifWalletServicesSocket}
abiEnhancer={abiEnhancer}
appActive={active}>
<RootNavigationComponent
currentScreen={currentScreen}
hasKeys={state.hasKeys}
hasPin={state.hasPin}
<RootNavigationComponent
currentScreen={currentScreen}
hasKeys={state.hasKeys}
hasPin={state.hasPin}
isKeyboardVisible={isKeyboardVisible}
rifWalletServicesSocket={rifWalletServicesSocket}
keyManagementProps={{
generateMnemonic: () => KeyManagementSystem.create().mnemonic,
createFirstWallet: (mnemonic: string) =>
createFirstWallet(mnemonic).then(wallet => {
setUnlocked(true)
return wallet
}),
}}
createPin={createPin}
editPin={handleUpdatePin}
setWalletIsDeployed={setWalletIsDeployed}
balancesScreenProps={{ fetcher: rifWalletServicesFetcher }}
sendScreenProps={{ rnsResolver }}
activityScreenProps={{
fetcher: rifWalletServicesFetcher,
abiEnhancer,
}}
showMnemonicScreenProps={{
mnemonic: state.kms?.mnemonic || '',
}}
contactsNavigationScreenProps={{ rnsResolver }}
accountsScreenType={{
addNewWallet,
switchActiveWallet,
}}
securityConfigurationScreenProps={{
deleteKeys: resetKeysAndPin,
}}
changeTopColor={setTopColor}
/>

{requests.length !== 0 && (
<ModalComponent
closeModal={closeRequest}
isKeyboardVisible={isKeyboardVisible}
rifWalletServicesSocket={rifWalletServicesSocket}
keyManagementProps={{
generateMnemonic: () => KeyManagementSystem.create().mnemonic,
createFirstWallet: (mnemonic: string) =>
createFirstWallet(mnemonic).then(wallet => {
setUnlocked(true)
return wallet
}),
}}
createPin={createPin}
editPin={handleUpdatePin}
setWalletIsDeployed={setWalletIsDeployed}
balancesScreenProps={{ fetcher: rifWalletServicesFetcher }}
sendScreenProps={{ rnsResolver }}
activityScreenProps={{
fetcher: rifWalletServicesFetcher,
abiEnhancer,
}}
showMnemonicScreenProps={{
mnemonic: state.kms?.mnemonic || '',
}}
contactsNavigationScreenProps={{ rnsResolver }}
accountsScreenType={{
addNewWallet,
switchActiveWallet,
}}
securityConfigurationScreenProps={{
deleteKeys: resetKeysAndPin,
}}
changeTopColor={setTopColor}
request={requests[0]}
/>

{requests.length !== 0 && (
<ModalComponent
closeModal={closeRequest}
isKeyboardVisible={isKeyboardVisible}
request={requests[0]}
/>
)}
</RIFSocketsProvider>
)}
</WalletConnectProviderElement>
</NavigationContainer>
</AppContext.Provider>
Expand Down
9 changes: 6 additions & 3 deletions src/lib/rifWalletServices/RifWalletServicesSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import EventEmitter from 'events'
import { io, Socket } from 'socket.io-client'

import { enhanceTransactionInput } from 'screens/activity/ActivityScreen'
import { MMKVStorage } from '../../storage/MMKVStorage'
import { IActivityTransaction } from '../../subscriptions/types'
import { MMKVStorage } from 'src/storage/MMKVStorage'
import { IActivityTransaction } from 'src/subscriptions/types'
import { IAbiEnhancer } from '../abiEnhancer/AbiEnhancer'
import { RIFWallet } from '../core'
import { IRIFWalletServicesFetcher } from './RifWalletServicesFetcher'
Expand Down Expand Up @@ -77,7 +77,10 @@ export class RifWalletServicesSocket
enhancedTransaction,
}
} else {
return null
return {
originTransaction: tx,
enhancedTransaction: undefined,
}
}
}),
)
Expand Down
2 changes: 1 addition & 1 deletion src/navigation/rootNavigator/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export type RootStackParamList = {
to?: string
displayTo?: string
contractAddress?: string
rnsResolver: Resolver
rnsResolver?: Resolver
}
Receive: undefined
ReceiveBitcoin: {
Expand Down
3 changes: 3 additions & 0 deletions src/redux/shared/actions/resetSocketState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createAction } from '@reduxjs/toolkit'

export const resetSocketState = createAction('RESET_SOCKET_STATE')
24 changes: 24 additions & 0 deletions src/redux/slices/appStateSlice/appStateSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { AppState } from 'store/slices/appStateSlice/types'
import { createSlice } from '@reduxjs/toolkit'
import { resetSocketState } from 'store/shared/actions/resetSocketState'

const initialState: AppState = {
isSetup: false,
}

const appStateSlice = createSlice({
name: 'appState',
initialState,
reducers: {
setIsSetup: (state, { payload }: { payload: boolean }) => {
state.isSetup = payload
return state
},
},
extraReducers: builder => {
builder.addCase(resetSocketState, () => initialState)
},
})

export const { setIsSetup } = appStateSlice.actions
export const appStateReducer = appStateSlice.reducer
3 changes: 3 additions & 0 deletions src/redux/slices/appStateSlice/selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { RootState } from 'src/redux'

export const selectAppState = (state: RootState) => state.appState
3 changes: 3 additions & 0 deletions src/redux/slices/appStateSlice/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type AppState = {
isSetup: boolean
}
16 changes: 15 additions & 1 deletion src/redux/slices/balancesSlice/balancesSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
BalanceState,
ITokenWithoutLogo,
} from 'store/slices/balancesSlice/types'
import { resetSocketState } from 'store/shared/actions/resetSocketState'

const initialState: BalanceState = {}

Expand All @@ -19,8 +20,21 @@ export const balancesSlice = createSlice({
}
return state
},
addOrUpdateBalances: (
state,
{ payload }: PayloadAction<ITokenWithoutLogo[]>,
) => {
payload.map(token => {
state[token.contractAddress] = token
})
return state
},
},
extraReducers: builder => {
builder.addCase(resetSocketState, () => initialState)
},
})

export const { addOrUpdateNewBalance } = balancesSlice.actions
export const { addOrUpdateNewBalance, addOrUpdateBalances } =
balancesSlice.actions
export const balancesReducer = balancesSlice.reducer
Empty file.
3 changes: 3 additions & 0 deletions src/redux/slices/transactionsSlice/selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { RootState } from 'src/redux'

export const selectTransactions = (state: RootState) => state.transactions
61 changes: 61 additions & 0 deletions src/redux/slices/transactionsSlice/transactionsSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { ITransactionsState } from 'store/slices/transactionsSlice/types'
import {
filterEnhancedTransactions,
sortEnhancedTransactions,
} from 'src/subscriptions/utils'
import {
IActivityTransaction,
IEvent,
TransactionsServerResponseWithActivityTransactions,
} from 'src/subscriptions/types'
import { resetSocketState } from 'store/shared/actions/resetSocketState'

const initialState: ITransactionsState = {
next: '',
prev: '',
transactions: [],
events: [],
}

const deserializeTransactions = (transactions: IActivityTransaction[]) =>
transactions.sort(sortEnhancedTransactions).filter(filterEnhancedTransactions)

const transactionsSlice = createSlice({
name: 'transactions',
initialState,
reducers: {
addNewTransactions: (
state,
{
payload,
}: PayloadAction<TransactionsServerResponseWithActivityTransactions>,
) => {
state.transactions = deserializeTransactions(
state.transactions.concat(payload.activityTransactions || []),
)
state.next = payload.next || null
state.prev = payload.prev || null
return state
},
addNewTransaction: (
state,
{ payload }: PayloadAction<IActivityTransaction>,
) => {
state.transactions.push(payload)
state.transactions = deserializeTransactions(state.transactions || [])
return state
},
addNewEvent: (state, { payload }: PayloadAction<IEvent>) => {
state.events.push(payload)
return state
},
},
extraReducers: builder => {
builder.addCase(resetSocketState, () => initialState)
},
})

export const { addNewTransactions, addNewTransaction, addNewEvent } =
transactionsSlice.actions
export const transactionsReducer = transactionsSlice.reducer
8 changes: 8 additions & 0 deletions src/redux/slices/transactionsSlice/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { IActivityTransaction, IEvent } from 'src/subscriptions/types'

export interface ITransactionsState {
prev: string | null
next: string | null
transactions: IActivityTransaction[]
events: IEvent[]
}
4 changes: 4 additions & 0 deletions src/redux/store.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { configureStore } from '@reduxjs/toolkit'
import createDebugger from 'redux-flipper'
import { usdPriceReducer } from './slices/usdPricesSlice/usdPricesSlice'
import { transactionsReducer } from 'store/slices/transactionsSlice/transactionsSlice'
import { balancesReducer } from 'store/slices/balancesSlice/balancesSlice'
import { appStateReducer } from 'store/slices/appStateSlice/appStateSlice'

// Must use redux-debugger plugin in flipper for the redux debugger to work

export const store = configureStore({
reducer: {
usdPrices: usdPriceReducer,
transactions: transactionsReducer,
balances: balancesReducer,
appState: appStateReducer,
},
middleware: getDefaultMiddlewares => {
const middlewares = getDefaultMiddlewares()
Expand Down
Loading

0 comments on commit e383570

Please sign in to comment.