Usage docs Reference Examples


import { END, eventChannel } from 'redux-saga';
import * as transactionsAT from './AT';

 * Open a TX channel: this channel maps web3 events to our redux tracking system.
 * @param promiEvent The event emitter to read transaction status updates from.
 * @param txID The ID of the transaction, used in the tracking system.
 * @returns {Channel<any>} The redux saga channel.
const openTxChannel = (promiEvent, txID) => eventChannel((emit) => {
  // Web3 returns a "promise combined with an event emitter": we map this to redux events.
    .on('transactionHash', (hash) => {
      emit({type: transactionsAT.TX_BROADCAST, txID, txHash: hash});
    .on('receipt', (receipt) => {
      // TODO: first receipt is probably double, as it's also the initial confirmation.
      // This can be ignored for now, but maybe we can remove this listener altogether.
      emit({type: transactionsAT.TX_RECEIPT, txID, receipt});
    .on('confirmation', (confirmationNumber, receipt) => {
      // re-fire the TX_RECEIPT
      emit({type: transactionsAT.TX_RECEIPT, txID, receipt});
      // We can safely close the channel once we received enough confirmations
      if (confirmationNumber >= 12) {
    .on('error', (error, receipt) => {
      emit({type: transactionsAT.TX_FAILED, txID, receipt});
      // TODO This is tricky, an out-of-gas transaction technically did not fail until it's final,
      // as it could still be orphaned, and mined with a context
      // that does not make it run out of gas.
  // Return unsubscribe function (wrap for future compatibility)
  return () =>;

export default openTxChannel;