Skip to content
This repository has been archived by the owner on Sep 27, 2019. It is now read-only.

Contract events array not being populated #108

Closed
BryceMindLab opened this issue Aug 2, 2018 · 8 comments
Closed

Contract events array not being populated #108

BryceMindLab opened this issue Aug 2, 2018 · 8 comments

Comments

@BryceMindLab
Copy link

BryceMindLab commented Aug 2, 2018

drizzle v1.2.2
node v8.11.3

I would like to use drizzle to monitor events happening from my smart contract. Reading the docs I setup drizzleOptions.js with an array of strings that correspond to the contract's events, but when checking the state there are no events populated in the contract's event array.

// drizzleOptions.js
import SomeToken from '../../build/contracts/SomeToken.json'

const drizzleOptions = {
  web3: {
    block: false,
    fallback: {
      type: 'ws',
      url: 'ws://127.0.0.1:8545'
    }
  },
  contracts: [
    SomeToken
  ],
  events: {
    'SomeToken': [
      'Approval',
      'Transfer',
      'Purchased',
    ]
  },
  polls: {
    accounts: 1500
  }
}

export default drizzleOptions

Here is the state tree (events array being a child of SomeToken contract):
screen shot 2018-08-02 at 2 02 26 pm

@BryceMindLab
Copy link
Author

BryceMindLab commented Aug 2, 2018

After some digging, I found this string of operations being performed during the initialization phase of drizzle.

In contractsReducer.js each contract is generated with the generateContractInitialState() function as seen below. In this function only the objects with type === function are added to the state. This seems fairly normal because we needed to add events to monitor in drizzleOptions.js.

What seems like an issue to me is that once the contract is initialized the events in the contract are set to an empty array. (Maybe we should be passing the events from drizzleOptions here to populate the events array?)

  if (action.type === 'CONTRACT_INITIALIZING') {
    return {
      ...state,
      [action.contractConfig.contractName]: generateContractInitialState(action.contractConfig)
    }
  }

  if (action.type === 'CONTRACT_INITIALIZED')
  {
    return {
      ...state,
      [action.name]: {
        ...state[action.name],
        initialized: true,
        synced: true,
        events: []
      }
    }
  }

drizzle/src/contracts/contractsReducer.js

(As stated above, the initial contract state is created with only functions from the ABI, no events. Because we need to provide events in dirzzleOptions this would appear to be normal behavior)

import getAbi from './getAbi'

export function generateContractInitialState (contractConfig) {
  var state = {
    initialized: false,
    synced: false
  }

  // Constant getters
  var abi = getAbi(contractConfig)
  for (var i2 = 0; i2 < abi.length; i2++) {
    var item = abi[i2];

    if (item.type == "function" && item.constant === true) {
      state[item.name] = {}
    }
  }

  return state

drizzle/src/generateContractInitialState.js

In contractsSaga.js, an eventListener is created for each event passed into drizzleOptions, but it seems to be monitoring contract.events, which as shown above is initialized to an empty array. Could this be the reason why these events are not firing?

function createContractEventChannel({contract, eventName, eventOptions}) {
  const name = contract.contractName

  return eventChannel(emit => {
    const eventListener = contract.events[eventName](eventOptions).on('data', event => {
      emit({type: 'EVENT_FIRED', name, event})
    })
    .on('changed', event => {
      emit({type: 'EVENT_CHANGED', name, event})
    })
    .on('error', error => {
      emit({type: 'EVENT_ERROR', name, error})
      emit(END)
    })

    const unsubscribe = () => {
      eventListener.removeListener(eventName)
    }

    return unsubscribe
  })
}

drizzle/src/contracts/contractsSaga.js

@reime005
Copy link

I ran into the issue that nothing about events was printed to the console. But obviously there must have been an error. Fixed it with that code: reime005@a449f16

@johnmpotter
Copy link
Contributor

For some reason, events aren't working for me either. I logged the error message, similar @reime005's suggestions and received this error:

Error: The current provider doesn't support subscriptions: MetamaskInpageProvider

It may be related to an issue with MetaMask not supporting web3 1.0 yet MetaMask/metamask-extension#3642

According to #10, Drizzle has a work around for this, but i'm not sure if it applies to events.

@pors
Copy link
Contributor

pors commented Oct 5, 2018

@DiscRiskandBisque can you confirm that the #10 fix indeed doesn't cover events? I also get the "not supported" error (after exposing it manually):

screen shot 2018-10-05 at 10 09 03 am

igorline referenced this issue in decentfund/kyodo Oct 9, 2018
+ added proxy logic to smart contracts
* separated smart contracts logic
* fixed frontend calls with proper drizzle events listening using
fallback
Related issue: trufflesuite/drizzle#108
+ added solhint config
* updated migrations for new logic
@nahuely
Copy link

nahuely commented Oct 10, 2018

Hi there, im having the same issue, i would like to know if there is any progress on it? thanks so much

@pors
Copy link
Contributor

pors commented Oct 11, 2018

Good news from MetaMask, subscription support is underway: MetaMask/metamask-extension#5458

@nahuely
Copy link

nahuely commented Oct 12, 2018

update to the latest metamask version, the event array its getting populated, and the websockets provider its working, im so so happy thanks

@BryceMindLab
Copy link
Author

Thanks for the update!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants