Browse Source

Add support for reload on network/account change, refactoring

develop
Ezerous 4 years ago
parent
commit
e47661b94e
  1. 2
      package.json
  2. 9
      src/Drizzle.js
  3. 4
      src/DrizzleContract.js
  4. 5
      src/accounts/accountsActions.js
  5. 9
      src/accounts/accountsMiddleware.js
  6. 4
      src/accounts/accountsReducer.js
  7. 6
      src/accounts/accountsSaga.js
  8. 8
      src/contracts/constants.js
  9. 2
      src/contracts/contractsReducer.js
  10. 8
      src/contracts/contractsSaga.js
  11. 2
      src/defaultOptions.js
  12. 0
      src/drizzle/drizzleActions.js
  13. 28
      src/drizzle/drizzleMiddleware.js
  14. 0
      src/drizzle/drizzleStatusReducer.js
  15. 8
      src/drizzle/drizzleStatusSaga.js
  16. 10
      src/generateStore.js
  17. 18
      src/index.js
  18. 20
      src/reducer.js
  19. 11
      src/root/rootMiddleware.js
  20. 20
      src/root/rootReducer.js
  21. 13
      src/root/rootSaga.js
  22. 11
      src/rootSaga.js
  23. 21
      src/web3/web3Actions.js
  24. 18
      src/web3/web3Middleware.js
  25. 11
      src/web3/web3Reducer.js
  26. 25
      src/web3/web3Saga.js

2
package.json

@ -1,6 +1,6 @@
{ {
"name": "@ezerous/drizzle", "name": "@ezerous/drizzle",
"version": "0.2.1", "version": "0.3.0",
"description": "A reactive data-store for web3 and smart contracts.", "description": "A reactive data-store for web3 and smart contracts.",
"license": "MIT", "license": "MIT",
"author": "Ezerous <ezerous@gmail.com>", "author": "Ezerous <ezerous@gmail.com>",

9
src/Drizzle.js

@ -3,7 +3,7 @@ import defaultOptions from './defaultOptions'
import merge from './mergeOptions' import merge from './mergeOptions'
import DrizzleContract from './DrizzleContract' import DrizzleContract from './DrizzleContract'
import * as ContractActions from './contracts/constants' import * as ContractActions from './contracts/constants'
import * as DrizzleActions from './drizzleStatus/drizzleActions' import * as DrizzleActions from './drizzle/drizzleActions'
// Load as promise so that async Drizzle initialization can still resolve // Load as promise so that async Drizzle initialization can still resolve
const isEnvReadyPromise = new Promise((resolve) => { const isEnvReadyPromise = new Promise((resolve) => {
@ -81,11 +81,8 @@ class Drizzle {
events events
) )
if (this.contracts[drizzleContract.contractName]) { if (this.contracts[drizzleContract.contractName])
throw new Error( console.warn(`Adding an already existing contract: ${drizzleContract.contractName}.\nIgnore this if upon drizzle reinitialization.`);
`Contract already exists: ${drizzleContract.contractName}`
)
}
this.store.dispatch({ type: ContractActions.CONTRACT_INITIALIZING, contractConfig }) this.store.dispatch({ type: ContractActions.CONTRACT_INITIALIZING, contractConfig })

4
src/DrizzleContract.js

@ -38,14 +38,14 @@ class DrizzleContract {
if (typeof event === 'object') { if (typeof event === 'object') {
store.dispatch({ store.dispatch({
type: ContractActions.LISTEN_FOR_EVENT, type: ContractActions.CONTRACT_EVENT_LISTEN,
contract: this, contract: this,
eventName: event.eventName, eventName: event.eventName,
eventOptions: event.eventOptions eventOptions: event.eventOptions
}) })
} else { } else {
store.dispatch({ store.dispatch({
type: ContractActions.LISTEN_FOR_EVENT, type: ContractActions.CONTRACT_EVENT_LISTEN,
contract: this, contract: this,
eventName: event eventName: event
}) })

5
src/accounts/accountsActions.js

@ -1,11 +1,12 @@
export const ACCOUNTS_FETCHING = 'ACCOUNTS_FETCHING' export const ACCOUNTS_FETCHING = 'ACCOUNTS_FETCHING'
export const ACCOUNTS_FETCHED = 'ACCOUNTS_FETCHED' export const ACCOUNTS_FETCHED = 'ACCOUNTS_FETCHED'
export const ACCOUNTS_CHANGED = 'ACCOUNTS_CHANGED'
export const ACCOUNTS_FAILED = 'ACCOUNTS_FAILED' export const ACCOUNTS_FAILED = 'ACCOUNTS_FAILED'
export const ACCOUNTS_LISTENING = 'ACCOUNTS_LISTENING' export const ACCOUNTS_LISTENING = 'ACCOUNTS_LISTENING'
export function accountsFetched (accounts) { export function accountsChanged (accounts) {
return { return {
type: ACCOUNTS_FETCHED, type: ACCOUNTS_CHANGED,
accounts accounts
} }
} }

9
src/accounts/accountsMiddleware.js

@ -1,5 +1,5 @@
import { WEB3_INITIALIZED } from '../web3/web3Actions' import { networkIdChanged, WEB3_INITIALIZED } from '../web3/web3Actions'
import { accountsFetched, accountsListening } from './accountsActions' import { accountsChanged, accountsFetched, accountsListening } from './accountsActions'
export const accountsMiddleware = web3 => store => next => action => { export const accountsMiddleware = web3 => store => next => action => {
const { type } = action const { type } = action
@ -13,7 +13,10 @@ export const accountsMiddleware = web3 => store => next => action => {
// For some reason accounts here are returned with lowercase letters, so we need to patch them // For some reason accounts here are returned with lowercase letters, so we need to patch them
let patchedAccounts = Array.from(accounts); let patchedAccounts = Array.from(accounts);
patchedAccounts.forEach((account, i) => patchedAccounts[i] = web3.utils.toChecksumAddress(account)); patchedAccounts.forEach((account, i) => patchedAccounts[i] = web3.utils.toChecksumAddress(account));
store.dispatch(accountsFetched(patchedAccounts));
const storedAccounts = store.getState().accounts;
if(storedAccounts[0] && (patchedAccounts[0] !== storedAccounts[0]))
store.dispatch(accountsChanged(patchedAccounts));
}); });
store.dispatch(accountsListening()); store.dispatch(accountsListening());
} }

4
src/accounts/accountsReducer.js

@ -1,4 +1,4 @@
import { ACCOUNTS_FETCHED, ACCOUNTS_FETCHING } from './accountsActions' import { ACCOUNTS_CHANGED, ACCOUNTS_FETCHED, ACCOUNTS_FETCHING } from './accountsActions'
const initialState = {} const initialState = {}
@ -7,7 +7,7 @@ const accountsReducer = (state = initialState, action) => {
return state return state
} }
if (action.type === ACCOUNTS_FETCHED) { if (action.type === ACCOUNTS_FETCHED || action.type === ACCOUNTS_CHANGED) {
return Object.assign({}, state, action.accounts) return Object.assign({}, state, action.accounts)
} }

6
src/accounts/accountsSaga.js

@ -9,10 +9,10 @@ export function * getAccounts (action) {
try { try {
yield put({ type: ACCOUNTS_FETCHING }); yield put({ type: ACCOUNTS_FETCHING });
const accounts = yield call(web3.eth.getAccounts) const accounts = yield call(web3.eth.getAccounts);
if (!accounts) if (!accounts.length)
throw 'No accounts found!' throw new Error('No accounts found!');
yield put({ type: ACCOUNTS_FETCHED, accounts }) yield put({ type: ACCOUNTS_FETCHED, accounts })
} catch (error) { } catch (error) {

8
src/contracts/constants.js

@ -1,7 +1,7 @@
export const EVENT_FIRED = 'EVENT_FIRED' export const CONTRACT_EVENT_FIRED = 'CONTRACT_EVENT_FIRED'
export const EVENT_CHANGED = 'EVENT_CHANGED' export const CONTRACT_EVENT_CHANGED = 'CONTRACT_EVENT_CHANGED'
export const EVENT_ERROR = 'EVENT_ERROR' export const CONTRACT_EVENT_ERROR = 'CONTRACT_EVENT_ERROR'
export const LISTEN_FOR_EVENT = 'LISTEN_FOR_EVENT' export const CONTRACT_EVENT_LISTEN = 'CONTRACT_EVENT_LISTEN'
export const CONTRACT_INITIALIZING = 'CONTRACT_INITIALIZING' export const CONTRACT_INITIALIZING = 'CONTRACT_INITIALIZING'
export const CONTRACT_INITIALIZED = 'CONTRACT_INITIALIZED' export const CONTRACT_INITIALIZED = 'CONTRACT_INITIALIZED'
export const CONTRACT_NOT_DEPLOYED = 'CONTRACT_NOT_DEPLOYED' export const CONTRACT_NOT_DEPLOYED = 'CONTRACT_NOT_DEPLOYED'

2
src/contracts/contractsReducer.js

@ -123,7 +123,7 @@ const contractsReducer = (state = initialState, action) => {
* Contract Events * Contract Events
*/ */
if (action.type === ContractActions.EVENT_FIRED) { if (action.type === ContractActions.CONTRACT_EVENT_FIRED) {
return { return {
...state, ...state,
[action.name]: { [action.name]: {

8
src/contracts/contractsSaga.js

@ -16,13 +16,13 @@ export function createContractEventChannel ({
return eventChannel(emit => { return eventChannel(emit => {
const eventListener = contract.events[eventName](eventOptions) const eventListener = contract.events[eventName](eventOptions)
.on('data', event => { .on('data', event => {
emit({ type: ContractActions.EVENT_FIRED, name, event }) emit({ type: ContractActions.CONTRACT_EVENT_FIRED, name, event })
}) })
.on('changed', event => { .on('changed', event => {
emit({ type: ContractActions.EVENT_CHANGED, name, event }) emit({ type: ContractActions.CONTRACT_EVENT_CHANGED, name, event })
}) })
.on('error', error => { .on('error', error => {
emit({ type: ContractActions.EVENT_ERROR, name, error }) emit({ type: ContractActions.CONTRACT_EVENT_ERROR, name, error })
emit(END) emit(END)
}) })
@ -287,7 +287,7 @@ function * contractsSaga () {
yield takeEvery(ContractActions.SEND_CONTRACT_TX, callSendContractTx) yield takeEvery(ContractActions.SEND_CONTRACT_TX, callSendContractTx)
yield takeEvery(ContractActions.CALL_CONTRACT_FN, callCallContractFn) yield takeEvery(ContractActions.CALL_CONTRACT_FN, callCallContractFn)
yield takeEvery(ContractActions.CONTRACT_SYNCING, callSyncContract) yield takeEvery(ContractActions.CONTRACT_SYNCING, callSyncContract)
yield takeEvery(ContractActions.LISTEN_FOR_EVENT, callListenForContractEvent) yield takeEvery(ContractActions.CONTRACT_EVENT_LISTEN, callListenForContractEvent)
} }
export default contractsSaga export default contractsSaga

2
src/defaultOptions.js

@ -9,6 +9,8 @@ const defaultOptions = {
contracts: [], contracts: [],
events: {}, events: {},
syncAlways: false, syncAlways: false,
reloadWindowOnNetworkChange: false,
reloadWindowOnAccountChange: false,
networkWhitelist: [] networkWhitelist: []
} }

0
src/drizzleStatus/drizzleActions.js → src/drizzle/drizzleActions.js

28
src/drizzle-middleware.js → src/drizzle/drizzleMiddleware.js

@ -1,6 +1,7 @@
import * as DrizzleActions from './drizzleStatus/drizzleActions' import * as DrizzleActions from './drizzleActions'
import * as ContractActions from './contracts/constants' import * as ContractActions from '../contracts/constants'
import { ACCOUNTS_FETCHED } from './accounts/accountsActions' import { ACCOUNTS_CHANGED, ACCOUNTS_FETCHED } from '../accounts/accountsActions'
import { WEB3_NETWORK_CHANGED } from '../web3/web3Actions'
export const drizzleMiddleware = drizzleInstance => store => next => action => { export const drizzleMiddleware = drizzleInstance => store => next => action => {
const { type } = action const { type } = action
@ -9,6 +10,23 @@ export const drizzleMiddleware = drizzleInstance => store => next => action => {
drizzleInstance = action.drizzle drizzleInstance = action.drizzle
} }
// If network changes, drizzle should reinitialize
if (type === WEB3_NETWORK_CHANGED) {
// Hard reinitialization
if(drizzleInstance.options.reloadWindowOnNetworkChange)
window.location.reload();
else{ // Soft reinitialization
store.dispatch({
type: DrizzleActions.DRIZZLE_INITIALIZING,
drizzle: drizzleInstance,
options: drizzleInstance.options
})
}
}
if (type === ACCOUNTS_CHANGED && drizzleInstance.options.reloadWindowOnAccountChange)
window.location.reload();
if ( if (
type === ACCOUNTS_FETCHED && type === ACCOUNTS_FETCHED &&
drizzleInstance && drizzleInstance &&
@ -40,8 +58,8 @@ export const drizzleMiddleware = drizzleInstance => store => next => action => {
} }
store.dispatch(notificationAction) store.dispatch(notificationAction)
// Don't propogate current action // Don't propagate current action
return return;
} }
} }
return next(action) return next(action)

0
src/drizzleStatus/drizzleStatusReducer.js → src/drizzle/drizzleStatusReducer.js

8
src/drizzleStatus/drizzleStatusSaga.js → src/drizzle/drizzleStatusSaga.js

@ -1,13 +1,13 @@
import { call, put, takeLatest } from 'redux-saga/effects' import { call, put, takeLatest } from 'redux-saga/effects'
// Initialization Functions // Initialization Functions
import { getNetworkId, initializeWeb3 } from '../web3/web3Saga' import { getNetworkInfo, initializeWeb3 } from '../web3/web3Saga'
import { getAccounts } from '../accounts/accountsSaga' import { getAccounts } from '../accounts/accountsSaga'
import { getAccountBalances } from '../accountBalances/accountBalancesSaga' import { getAccountBalances } from '../accountBalances/accountBalancesSaga'
import * as DrizzleActions from './drizzleActions' import * as DrizzleActions from './drizzleActions'
import * as BlocksActions from '../blocks/blockActions' import * as BlocksActions from '../blocks/blockActions'
import { NETWORK_IDS, NETWORK_MISMATCH } from '../web3/web3Actions' import { NETWORK_IDS, WEB3_NETWORK_MISMATCH } from '../web3/web3Actions'
import { CONTRACT_NOT_DEPLOYED } from '../contracts/constants' import { CONTRACT_NOT_DEPLOYED } from '../contracts/constants'
import { isContractDeployed } from '../contracts/contractsSaga' import { isContractDeployed } from '../contracts/contractsSaga'
@ -23,14 +23,14 @@ export function * initializeDrizzle (action) {
// further web3 interaction, and note web3 will be undefined // further web3 interaction, and note web3 will be undefined
// //
if (web3) { if (web3) {
const networkId = yield call(getNetworkId, { web3 }) const networkId = yield call(getNetworkInfo, { web3 })
// Check whether network is allowed // Check whether network is allowed
const networkWhitelist = options.networkWhitelist const networkWhitelist = options.networkWhitelist
if (networkWhitelist.length && if (networkWhitelist.length &&
networkId !== NETWORK_IDS.ganache && networkId !== NETWORK_IDS.ganache &&
!networkWhitelist.includes(networkId)) { !networkWhitelist.includes(networkId)) {
yield put({ type: NETWORK_MISMATCH, networkId }) yield put({ type: WEB3_NETWORK_MISMATCH, networkId })
} else { } else {
// Get initial accounts list and balances. // Get initial accounts list and balances.
yield call(getAccounts, { web3 }) yield call(getAccounts, { web3 })

10
src/generateStore.js

@ -1,10 +1,10 @@
import { all, fork } from 'redux-saga/effects' import { all, fork } from 'redux-saga/effects'
import { applyMiddleware, combineReducers, compose, createStore } from 'redux' import { applyMiddleware, combineReducers, compose, createStore } from 'redux'
import createSagaMiddleware from 'redux-saga' import createSagaMiddleware from 'redux-saga'
import drizzleSagas from './rootSaga' import drizzleSagas from './root/rootSaga'
import drizzleReducers from './reducer' import drizzleReducers from './root/rootReducer'
import { generateContractsInitialState } from './contractStateUtils' import { generateContractsInitialState } from './contractStateUtils'
import drizzleMW from './drizzle-middleware' import drizzleMiddlewares from './root/rootMiddleware'
const composeSagas = sagas => const composeSagas = sagas =>
function * () { function * () {
@ -28,7 +28,7 @@ export function generateStore ({
drizzleOptions, drizzleOptions,
appReducers = {}, appReducers = {},
appSagas = [], appSagas = [],
appMiddlewares = [], appMiddlewares = drizzleMiddlewares,
disableReduxDevTools = false, disableReduxDevTools = false,
...options ...options
}) { }) {
@ -55,7 +55,7 @@ export function generateStore ({
} }
const sagaMiddleware = createSagaMiddleware() const sagaMiddleware = createSagaMiddleware()
const allMiddlewares = [...appMiddlewares, sagaMiddleware, drizzleMW] const allMiddlewares = [...appMiddlewares, sagaMiddleware]
const allReducers = { ...drizzleReducers, ...appReducers } const allReducers = { ...drizzleReducers, ...appReducers }
const store = createStore( const store = createStore(

18
src/index.js

@ -7,23 +7,13 @@ import * as EventActions from './contracts/constants'
import * as AccountActions from './accounts/accountsActions' import * as AccountActions from './accounts/accountsActions'
// Reducers // Reducers
import drizzleReducers from './reducer' import drizzleReducers from './root/rootReducer'
// Middleware // Middlewares
import drizzleMiddleware from './drizzle-middleware' import drizzleMiddlewares from './root/rootMiddleware'
import accountsMiddleware from './accounts/accountsMiddleware'
import accountBalancesMiddleware from './accountBalances/accountBalancesMiddleware'
import web3Middleware from './web3/web3Middleware'
// Sagas // Sagas
import drizzleSagas from './rootSaga' import drizzleSagas from './root/rootSaga'
const drizzleMiddlewares = [
drizzleMiddleware,
accountsMiddleware,
accountBalancesMiddleware,
web3Middleware
]
const drizzleActions = { const drizzleActions = {
account: AccountActions, account: AccountActions,

20
src/reducer.js

@ -1,20 +0,0 @@
import accountsReducer from './accounts/accountsReducer'
import accountBalancesReducer from './accountBalances/accountBalancesReducer'
import blocksReducer from './blocks/blocksReducer'
import contractsReducer from './contracts/contractsReducer'
import drizzleStatusReducer from './drizzleStatus/drizzleStatusReducer'
import transactionsReducer from './transactions/transactionsReducer'
import transactionStackReducer from './transactions/transactionStackReducer'
import web3Reducer from './web3/web3Reducer'
// All our reducers
export default {
accounts: accountsReducer,
accountBalances: accountBalancesReducer,
contracts: contractsReducer,
currentBlock: blocksReducer,
drizzleStatus: drizzleStatusReducer,
transactions: transactionsReducer,
transactionStack: transactionStackReducer,
web3: web3Reducer
}

11
src/root/rootMiddleware.js

@ -0,0 +1,11 @@
import drizzleMiddleware from '../drizzle/drizzleMiddleware'
import accountsMiddleware from '../accounts/accountsMiddleware'
import accountBalancesMiddleware from '../accountBalances/accountBalancesMiddleware'
import web3Middleware from '../web3/web3Middleware'
export default [
drizzleMiddleware,
accountsMiddleware,
accountBalancesMiddleware,
web3Middleware
]

20
src/root/rootReducer.js

@ -0,0 +1,20 @@
import accountsReducer from '../accounts/accountsReducer'
import accountBalancesReducer from '../accountBalances/accountBalancesReducer'
import blocksReducer from '../blocks/blocksReducer'
import contractsReducer from '../contracts/contractsReducer'
import drizzleStatusReducer from '../drizzle/drizzleStatusReducer'
import transactionsReducer from '../transactions/transactionsReducer'
import transactionStackReducer from '../transactions/transactionStackReducer'
import web3Reducer from '../web3/web3Reducer'
// All our reducers
export default {
accounts: accountsReducer,
accountBalances: accountBalancesReducer,
contracts: contractsReducer,
currentBlock: blocksReducer,
drizzleStatus: drizzleStatusReducer,
transactions: transactionsReducer,
transactionStack: transactionStackReducer,
web3: web3Reducer
}

13
src/root/rootSaga.js

@ -0,0 +1,13 @@
import accountBalancesSaga from '../accountBalances/accountBalancesSaga'
import blocksSaga from '../blocks/blocksSaga'
import contractsSaga from '../contracts/contractsSaga'
import drizzleStatusSaga from '../drizzle/drizzleStatusSaga'
import web3Saga from '../web3/web3Saga'
export default [
accountBalancesSaga,
blocksSaga,
contractsSaga,
drizzleStatusSaga,
web3Saga
]

11
src/rootSaga.js

@ -1,11 +0,0 @@
import accountBalancesSaga from './accountBalances/accountBalancesSaga'
import blocksSaga from './blocks/blocksSaga'
import contractsSaga from './contracts/contractsSaga'
import drizzleStatusSaga from './drizzleStatus/drizzleStatusSaga'
export default [
accountBalancesSaga,
blocksSaga,
contractsSaga,
drizzleStatusSaga
]

21
src/web3/web3Actions.js

@ -3,10 +3,11 @@ export const WEB3_INITIALIZED = 'WEB3_INITIALIZED'
export const WEB3_FAILED = 'WEB3_FAILED' export const WEB3_FAILED = 'WEB3_FAILED'
export const WEB3_USER_DENIED = 'WEB3_USER_DENIED' export const WEB3_USER_DENIED = 'WEB3_USER_DENIED'
export const NETWORK_ID_FETCHED = 'NETWORK_ID_FETCHED' export const WEB3_NETWORK_FETCHING = 'WEB3_NETWORK_FETCHING'
export const NETWORK_ID_CHANGED = 'NETWORK_ID_CHANGED' export const WEB3_NETWORK_FETCHED = 'WEB3_NETWORK_FETCHED'
export const NETWORK_ID_FAILED = 'NETWORK_ID_FAILED' export const WEB3_NETWORK_CHANGED = 'WEB3_NETWORK_CHANGED'
export const NETWORK_MISMATCH = 'NETWORK_MISMATCH' export const WEB3_NETWORK_FAILED = 'WEB3_NETWORK_FAILED'
export const WEB3_NETWORK_MISMATCH = 'WEB3_NETWORK_MISMATCH'
export const NETWORK_IDS = { export const NETWORK_IDS = {
mainnet: 1, mainnet: 1,
@ -17,9 +18,15 @@ export const NETWORK_IDS = {
ganache: 5777 ganache: 5777
} }
export function networkIdChanged (web3, networkId) { export function networkInfoFetching (web3) {
return { return {
type: NETWORK_ID_CHANGED, type: WEB3_NETWORK_FETCHING,
networkId web3
}
}
export function networkChanged () {
return {
type: WEB3_NETWORK_CHANGED
} }
} }

18
src/web3/web3Middleware.js

@ -1,18 +1,18 @@
import { networkIdChanged, WEB3_INITIALIZED } from './web3Actions' import { networkChanged, networkInfoFetching, WEB3_INITIALIZED } from './web3Actions'
export const web3Middleware = () => store => next => action => { export const web3Middleware = web3 => store => next => action => {
const { type } = action const { type } = action
if (type === WEB3_INITIALIZED) { if (type === WEB3_INITIALIZED) {
if(!window.ethereum) if(!window.ethereum)
console.warn('No Metamask detected, not subscribed to network changes!') console.warn('No Metamask detected, not subscribed to network changes!')
else { else {
window.ethereum.on('networkChanged', (networkId) => { web3 = action.web3;
// Warning: 'networkChanged' is deprecated (EIP-1193) window.ethereum.on('chainChanged', (chainId) => {
const storedNetworkId = store.getState().web3.networkId; const storedNetworkId = store.getState().web3.chainId;
if(storedNetworkId && (networkId !== storedNetworkId)){ if(storedNetworkId && (chainId !== storedNetworkId)){
store.dispatch(networkIdChanged(networkId)); // Just to be typical store.dispatch(networkChanged());
window.location.reload(); store.dispatch(networkInfoFetching(web3));
} }
}); });
} }
@ -20,5 +20,5 @@ export const web3Middleware = () => store => next => action => {
return next(action) return next(action)
} }
const initializedMiddleware = web3Middleware() const initializedMiddleware = web3Middleware(undefined)
export default initializedMiddleware export default initializedMiddleware

11
src/web3/web3Reducer.js

@ -33,21 +33,22 @@ const web3Reducer = (state = initialState, action) => {
} }
} }
if (action.type === Action.NETWORK_ID_FETCHED if (action.type === Action.WEB3_NETWORK_FETCHED) {
|| action.type === Action.NETWORK_ID_CHANGED) {
return { return {
...state, ...state,
networkId: action.networkId networkId: action.networkInfo.networkId,
chainId: action.networkInfo.chainId,
nodeInfo: action.networkInfo.nodeInfo
} }
} }
if (action.type === Action.NETWORK_ID_FAILED) { if (action.type === Action.WEB3_NETWORK_FAILED) {
return { return {
...state, ...state,
networkId: action.networkId networkId: action.networkId
} }
} }
if (action.type === Action.NETWORK_MISMATCH) { if (action.type === Action.WEB3_NETWORK_MISMATCH) {
return { return {
...state, ...state,
networkMismatch: true networkMismatch: true

25
src/web3/web3Saga.js

@ -1,4 +1,4 @@
import { call, put } from 'redux-saga/effects' import { call, put, takeLatest } from 'redux-saga/effects'
import * as Action from './web3Actions' import * as Action from './web3Actions'
const Web3 = require('web3'); const Web3 = require('web3');
@ -66,19 +66,30 @@ export function * initializeWeb3 (options) {
} }
/* /*
* Fetch Network ID * Fetch Network Information
*/ */
export function * getNetworkId ({ web3 }) { export function * getNetworkInfo ({ web3 }) {
try { try {
const networkId = yield call(web3.eth.net.getId); const networkId = yield call(web3.eth.net.getId);
const chainId = yield call(web3.eth.getChainId);
const nodeInfo = yield call(web3.eth.getNodeInfo);
yield put({ type: Action.NETWORK_ID_FETCHED, networkId }); const networkInfo = { networkId, chainId, nodeInfo };
return networkId yield put({ type: Action.WEB3_NETWORK_FETCHED, networkInfo });
return networkInfo;
} catch (error) { } catch (error) {
yield put({ type: Action.NETWORK_ID_FAILED, error }); yield put({ type: Action.WEB3_NETWORK_FAILED, error });
console.error('Error fetching network ID:'); console.error('Error fetching network information:');
console.error(error); console.error(error);
} }
} }
function * web3Saga () {
yield takeLatest(Action.WEB3_NETWORK_FETCHING, getNetworkInfo);
}
export default web3Saga;

Loading…
Cancel
Save