diff --git a/src/accounts/accountsActions.js b/src/accounts/accountsActions.js index 30579bd..cccb1a3 100644 --- a/src/accounts/accountsActions.js +++ b/src/accounts/accountsActions.js @@ -3,20 +3,25 @@ import * as AccountsActions from './constants' export function accountsFetching (results) { return { type: AccountsActions.ACCOUNTS_FETCHING, - payload: results } } export function accountsFetched (results) { return { type: AccountsActions.ACCOUNTS_FETCHED, - payload: results + accounts: results + } +} + +export function accountsListening (results) { + return { + type: AccountsActions.ACCOUNTS_LISTENING, } } export function accountsFailed (error) { return { type: AccountsActions.ACCOUNTS_FAILED, - payload: error + error } } diff --git a/src/accounts/accountsMiddleware.js b/src/accounts/accountsMiddleware.js new file mode 100644 index 0000000..353669c --- /dev/null +++ b/src/accounts/accountsMiddleware.js @@ -0,0 +1,22 @@ +import { WEB3_INITIALIZED } from '../web3/constants' +import { accountsFetched, accountsListening } from './accountsActions' + +export const accountsMiddleware = () => store => next => action => { + const { type } = action + + if (type === WEB3_INITIALIZED) { + if(!window.ethereum) + console.warn('No Metamask detected, not subscribed to account changes!') + else { + store.dispatch(accountsListening()); + window.ethereum.on('accountsChanged', function (accounts) { + console.debug("Account changed") + store.dispatch(accountsFetched(accounts)); + }); + } + } + return next(action) +} + +const initializedMiddleware = accountsMiddleware(undefined) +export default initializedMiddleware diff --git a/src/accounts/accountsSaga.js b/src/accounts/accountsSaga.js index 17c0c55..867f822 100644 --- a/src/accounts/accountsSaga.js +++ b/src/accounts/accountsSaga.js @@ -1,21 +1,18 @@ -import { eventChannel } from 'redux-saga' -import { call, put, take, takeLatest } from 'redux-saga/effects' -import { getAccountBalances } from '../accountBalances/accountBalancesSaga' +import { call, put, takeLatest } from 'redux-saga/effects' + import * as AccountsActions from './constants' /* * Fetch Accounts List */ - export function * getAccounts (action) { const web3 = action.web3 try { const accounts = yield call(web3.eth.getAccounts) - if (!accounts) { + if (!accounts) throw 'No accounts found!' - } yield put({ type: AccountsActions.ACCOUNTS_FETCHED, accounts }) } catch (error) { @@ -25,51 +22,8 @@ export function * getAccounts (action) { } } -/* - * Poll for Account Changes - */ - -function * createAccountsPollChannel ({ interval, web3 }) { - return eventChannel(emit => { - const persistedWeb3 = web3 - - const accountsPoller = setInterval(() => { - emit({ type: AccountsActions.SYNCING_ACCOUNTS, persistedWeb3 }) - }, interval) // options.polls.accounts - - const unsubscribe = () => { - clearInterval(accountsPoller) - } - - return unsubscribe - }) -} - -function * callCreateAccountsPollChannel ({ interval, web3 }) { - const accountsChannel = yield call(createAccountsPollChannel, { - interval, - web3 - }) - - try { - while (true) { - var event = yield take(accountsChannel) - - if (event.type === AccountsActions.SYNCING_ACCOUNTS) { - yield call(getAccounts, { web3: event.persistedWeb3 }) - yield call(getAccountBalances, { web3: event.persistedWeb3 }) - } - - yield put(event) - } - } finally { - accountsChannel.close() - } -} - function * accountsSaga () { yield takeLatest(AccountsActions.ACCOUNTS_FETCHING, getAccounts) - yield takeLatest(AccountsActions.ACCOUNTS_POLLING, callCreateAccountsPollChannel) } export default accountsSaga diff --git a/src/accounts/constants.js b/src/accounts/constants.js index 7b8255d..424ce96 100644 --- a/src/accounts/constants.js +++ b/src/accounts/constants.js @@ -1,5 +1,4 @@ export const ACCOUNTS_FETCHING = 'ACCOUNTS_FETCHING' export const ACCOUNTS_FETCHED = 'ACCOUNTS_FETCHED' export const ACCOUNTS_FAILED = 'ACCOUNTS_FAILED' -export const SYNCING_ACCOUNTS = 'SYNCING_ACCOUNTS' -export const ACCOUNTS_POLLING = 'ACCOUNTS_POLLING' +export const ACCOUNTS_LISTENING = 'ACCOUNTS_LISTENING' diff --git a/src/drizzleStatus/drizzleStatusSaga.js b/src/drizzleStatus/drizzleStatusSaga.js index 3721513..286bed9 100644 --- a/src/drizzleStatus/drizzleStatusSaga.js +++ b/src/drizzleStatus/drizzleStatusSaga.js @@ -49,15 +49,6 @@ export function * initializeDrizzle (action) { } yield put({ type: BlocksActions.BLOCKS_LISTENING, drizzle, web3 }) - - // Accounts Polling - if ('accounts' in options.polls) { - yield put({ - type: AccountsActions.ACCOUNTS_POLLING, - interval: options.polls.accounts, - web3 - }) - } } } } catch (error) { diff --git a/src/index.js b/src/index.js index 6686377..80644c1 100644 --- a/src/index.js +++ b/src/index.js @@ -15,6 +15,17 @@ import transactionsReducer from './transactions/transactionsReducer' import transactionStackReducer from './transactions/transactionStackReducer' import web3Reducer from './web3/web3Reducer' +// Middleware +import drizzleMiddleware from './drizzle-middleware' +import accountsMiddleware from './accounts/accountsMiddleware' + +// Sagas +import accountsSaga from './accounts/accountsSaga' +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, @@ -26,12 +37,10 @@ const drizzleReducers = { web3: web3Reducer } -// Sagas -import accountsSaga from './accounts/accountsSaga' -import accountBalancesSaga from './accountBalances/accountBalancesSaga' -import blocksSaga from './blocks/blocksSaga' -import contractsSaga from './contracts/contractsSaga' -import drizzleStatusSaga from './drizzleStatus/drizzleStatusSaga' +const drizzleMiddlewares = [ + drizzleMiddleware, + accountsMiddleware +] const drizzleSagas = [ accountsSaga, @@ -46,6 +55,7 @@ export { generateContractsInitialState, generateStore, drizzleReducers, + drizzleMiddlewares, drizzleSagas, EventActions }