Browse Source

Listen to network changes

develop
Ezerous 4 years ago
parent
commit
a4bf2c5994
  1. 2
      package.json
  2. 2
      src/Drizzle.js
  3. 2
      src/accountBalances/accountBalancesMiddleware.js
  4. 6
      src/accounts/accountsMiddleware.js
  5. 10
      src/drizzleStatus/drizzleStatusSaga.js
  6. 40
      src/index.js
  7. 4
      src/rootSaga.js
  8. 8
      src/web3/web3Actions.js
  9. 21
      src/web3/web3Middleware.js
  10. 5
      src/web3/web3Reducer.js
  11. 26
      src/web3/web3Saga.js

2
package.json

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

2
src/Drizzle.js

@ -6,7 +6,7 @@ import * as ContractActions from './contracts/constants'
import * as DrizzleActions from './drizzleStatus/drizzleActions'
// Load as promise so that async Drizzle initialization can still resolve
var isEnvReadyPromise = new Promise((resolve, reject) => {
const isEnvReadyPromise = new Promise((resolve) => {
const hasNavigator = typeof navigator !== 'undefined'
const hasWindow = typeof window !== 'undefined'
const hasDocument = typeof document !== 'undefined'

2
src/accountBalances/accountBalancesMiddleware.js

@ -1,4 +1,4 @@
import { WEB3_INITIALIZED } from '../web3/constants'
import { WEB3_INITIALIZED } from '../web3/web3Actions'
import { accountBalancesFetching } from './accountBalancesActions'
import { ACCOUNTS_FETCHED } from '../accounts/accountsActions'

6
src/accounts/accountsMiddleware.js

@ -1,14 +1,14 @@
import { WEB3_INITIALIZED } from '../web3/constants'
import { WEB3_INITIALIZED } from '../web3/web3Actions'
import { accountsFetched, accountsListening } from './accountsActions'
export const accountsMiddleware = () => store => next => action => {
export const accountsMiddleware = web3 => store => next => action => {
const { type } = action
if (type === WEB3_INITIALIZED) {
if(!window.ethereum)
console.warn('No Metamask detected, not subscribed to account changes!')
else {
const { web3 } = action;
web3 = action.web3;
window.ethereum.on('accountsChanged', accounts => {
// For some reason accounts here are returned with lowercase letters, so we need to patch them
let patchedAccounts = Array.from(accounts);

10
src/drizzleStatus/drizzleStatusSaga.js

@ -7,7 +7,7 @@ import { getAccountBalances } from '../accountBalances/accountBalancesSaga'
import * as DrizzleActions from './drizzleActions'
import * as BlocksActions from '../blocks/blockActions'
import { NETWORK_IDS, NETWORK_MISMATCH } from '../web3/constants'
import { NETWORK_IDS, NETWORK_MISMATCH } from '../web3/web3Actions'
export function * initializeDrizzle (action) {
try {
@ -35,10 +35,10 @@ export function * initializeDrizzle (action) {
yield call(getAccountBalances, { web3 })
// Instantiate contracts passed through via options.
for (var i = 0; i < options.contracts.length; i++) {
var contractConfig = options.contracts[i]
var events = []
var contractName = contractConfig.contractName
for (let i = 0; i < options.contracts.length; i++) {
const contractConfig = options.contracts[i]
let events = []
const contractName = contractConfig.contractName
if (contractName in options.events) {
events = options.events[contractName]

40
src/index.js

@ -7,53 +7,27 @@ import * as EventActions from './contracts/constants'
import * as AccountActions from './accounts/accountsActions'
// Reducers
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'
import drizzleReducers from './reducer'
// Middleware
import drizzleMiddleware from './drizzle-middleware'
import accountsMiddleware from './accounts/accountsMiddleware'
import accountBalancesMiddleware from './accountBalances/accountBalancesMiddleware'
import web3Middleware from './web3/web3Middleware'
// Sagas
import accountBalancesSaga from './accountBalances/accountBalancesSaga'
import blocksSaga from './blocks/blocksSaga'
import contractsSaga from './contracts/contractsSaga'
import drizzleStatusSaga from './drizzleStatus/drizzleStatusSaga'
const drizzleReducers = {
accounts: accountsReducer,
accountBalances: accountBalancesReducer,
contracts: contractsReducer,
currentBlock: blocksReducer,
drizzleStatus: drizzleStatusReducer,
transactions: transactionsReducer,
transactionStack: transactionStackReducer,
web3: web3Reducer
}
import drizzleSagas from './rootSaga'
const drizzleMiddlewares = [
drizzleMiddleware,
accountsMiddleware,
accountBalancesMiddleware
]
const drizzleSagas = [
accountBalancesSaga,
blocksSaga,
contractsSaga,
drizzleStatusSaga
accountBalancesMiddleware,
web3Middleware
]
const drizzleActions = {
AccountActions,
EventActions
account: AccountActions,
event: EventActions
}
export {

4
src/rootSaga.js

@ -2,10 +2,12 @@ import accountBalancesSaga from './accountBalances/accountBalancesSaga'
import blocksSaga from './blocks/blocksSaga'
import contractsSaga from './contracts/contractsSaga'
import drizzleStatusSaga from './drizzleStatus/drizzleStatusSaga'
import web3Saga from './web3/web3Saga'
export default [
accountBalancesSaga,
blocksSaga,
contractsSaga,
drizzleStatusSaga
drizzleStatusSaga,
web3Saga
]

8
src/web3/constants.js → src/web3/web3Actions.js

@ -4,6 +4,7 @@ export const WEB3_FAILED = 'WEB3_FAILED'
export const WEB3_USER_DENIED = 'WEB3_USER_DENIED'
export const NETWORK_ID_FETCHED = 'NETWORK_ID_FETCHED'
export const NETWORK_ID_CHANGED = 'NETWORK_ID_CHANGED'
export const NETWORK_ID_FAILED = 'NETWORK_ID_FAILED'
export const NETWORK_MISMATCH = 'NETWORK_MISMATCH'
@ -15,3 +16,10 @@ export const NETWORK_IDS = {
kovan: 42,
ganache: 5777
}
export function networkIdChanged (web3) {
return {
type: NETWORK_ID_CHANGED,
web3
}
}

21
src/web3/web3Middleware.js

@ -0,0 +1,21 @@
import { networkIdChanged, WEB3_INITIALIZED } from './web3Actions'
export const web3Middleware = web3 => store => next => action => {
const { type } = action
if (type === WEB3_INITIALIZED) {
if(!window.ethereum)
console.warn('No Metamask detected, not subscribed to network changes!')
else {
web3 = action.web3;
window.ethereum.on('networkChanged', () => {
// We could have listened to 'networkChanged' but it is deprecated (EIP-1193)
store.dispatch(networkIdChanged(web3));
});
}
}
return next(action)
}
const initializedMiddleware = web3Middleware(undefined)
export default initializedMiddleware

5
src/web3/web3Reducer.js

@ -1,4 +1,4 @@
import * as Action from './constants'
import * as Action from './web3Actions'
const initialState = {
status: ''
@ -33,7 +33,8 @@ const web3Reducer = (state = initialState, action) => {
}
}
if (action.type === Action.NETWORK_ID_FETCHED) {
if (action.type === Action.NETWORK_ID_FETCHED
|| action.type === Action.NETWORK_ID_CHANGED) {
return {
...state,
networkId: action.networkId

26
src/web3/web3Saga.js

@ -1,12 +1,11 @@
import { call, put } from 'redux-saga/effects'
import * as Action from './constants'
import { call, put, takeLatest } from 'redux-saga/effects'
import * as Action from './web3Actions'
const Web3 = require('web3');
/*
* Initialization
*/
export function * initializeWeb3 (options) {
try {
let web3 = {}
@ -35,7 +34,6 @@ export function * initializeWeb3 (options) {
} catch (error) {
console.error(error)
yield put({ type: Action.WEB3_FAILED })
return
}
} else if (typeof window.web3 !== 'undefined') {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
@ -71,20 +69,26 @@ export function * initializeWeb3 (options) {
}
/*
* Network ID
* Fetch Network ID
*/
export function * getNetworkId ({ web3 }) {
try {
const networkId = yield call(web3.eth.net.getId)
const networkId = yield call(web3.eth.net.getId);
yield put({ type: Action.NETWORK_ID_FETCHED, networkId })
yield put({ type: Action.NETWORK_ID_FETCHED, networkId });
return networkId
} catch (error) {
yield put({ type: Action.NETWORK_ID_FAILED, error })
yield put({ type: Action.NETWORK_ID_FAILED, error });
console.error('Error fetching network ID:')
console.error(error)
console.error('Error fetching network ID:');
console.error(error);
}
}
function * web3Saga () {
yield takeLatest(Action.NETWORK_ID_CHANGED, getNetworkId);
}
export default web3Saga

Loading…
Cancel
Save