Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I filter on events from contracts? #4

Open
2 tasks
wahlforss opened this issue Dec 11, 2017 · 14 comments
Open
2 tasks

How do I filter on events from contracts? #4

wahlforss opened this issue Dec 11, 2017 · 14 comments

Comments

@wahlforss
Copy link

I've been trying for hours to listen to events from contracts. There is nothing in the docs on how it is done. Please tell me how.

ethjs-filter

Before opening a new issue, please take a moment to review our community guidelines to make the contribution process easy and effective for everyone involved.

Before opening a new issue, you may find an answer in already closed issues:
https://github.com/ethjs/ethjs-filter/issues?q=is%3Aissue+is%3Aclosed

Issue Type

Description

(Add images if possible)

Steps to reproduce

(Add link to a demo on https://jsfiddle.net or similar if possible)

Versions

  • Node/NPM:
  • Browser:
@wahlforss
Copy link
Author

Also, what options do I have for the filters? How do options work? Could the examples be a bit more fleshed out?

I love ETHJS other than that.

@SilentCicero
Copy link
Member

@wahlforss thanks! Okay, so contract filtering is fairly straight forward and you can use it and learn more about it by using/viewing ethjs-contract.

Module:
https://github.com/ethjs/ethjs-contract

API Example:

const filter = simpleStore.SetComplete()
.new({ toBlock: 'latest' }, (error, result) => {
  // result null <BigNumber ...> filterId
});
filter.watch((err, result) => {
  // result null FilterResult {...}
});
filter.uninstall()
.then(result) => {
  // result Boolean
});

The contract object uses ethjs-filter inside it.

The filter code is available here, you can see we produce the solidity event SHA3 signature, that filter for it.

https://github.com/ethjs/ethjs-contract/blob/master/src/index.js#L90-L99

Lastly, ethjs-filter does not work with stateless API's like the infura endpoint. But will work with extensions like metamask that polyfill the stateful API with a stateless version.

We will soon address this by providing stateless API filtering, that does not require the node/endpoint to keep track of events.

Thanks for use ETHJS!

@wahlforss
Copy link
Author

wahlforss commented Dec 11, 2017 via email

@SilentCicero
Copy link
Member

SilentCicero commented Dec 11, 2017

See the example above (similar to web3).

  1. Setup Eth instance
  2. Setup your contract object
  3. Listen for your event

Example here using ethjs-query + ethjs-contract:

https://github.com/ethjs/ethjs-contract#usage

and an example here using ethjs interface module:

https://github.com/ethjs/ethjs#usage

So it would be something like:

yourContract.NewBet()
.new({ toBlock: 'latest' }, (error, result) => {
  // result null <BigNumber ...> filterId
});
filter.watch((err, result) => {
  // result null FilterResult {...}
});
filter.uninstall()
.then(result) => {
  // result Boolean
});

More examples here in the ethjs user-guide.

https://github.com/ethjs/ethjs/blob/master/docs/user-guide.md#contract-instance

@lgaroche
Copy link

Hello,
I can't make this example work either.
When I call myContract.Event().new() I get a Promise that resolves to the filter id.
On the promise object, there is no function watch: TypeError: filter.watch is not a function

On the other hand, I can do
let filter = myContract.Event().watch((err, res) => { console.log(res) })
But the events are not captured, and filter.filterId is null.
Any idea?

@SilentCicero
Copy link
Member

SilentCicero commented Dec 18, 2017 via email

@SilentCicero
Copy link
Member

SilentCicero commented Dec 19, 2017 via email

@SilentCicero
Copy link
Member

@lgaroche @wahlforss did you manage to get things working here?

@wahlforss
Copy link
Author

wahlforss commented Dec 20, 2017 via email

@arispen
Copy link

arispen commented Jan 20, 2018

Hey @SilentCicero Same issue here. "filter.watch is not a function" It also says uknown field 'to'. Hope that helps:

Error: [ethjs-rpc] rpc error with payload {"id":6297886148885,"jsonrpc":"2.0","params":[{"to":"0x2CC25bDaBD264aB306d47938F3c701A6dF0e883A","topics":["0x92ebdf1fe2f64daffddb436aae297d78fe97201925117af65ae23ee5e5e5d36d"],"fromBlock":"0x0","toBlock":"latest"}],"method":"eth_newFilter"} {"message":"[ethjs-rpc] rpc error with payload {\"id\":7500219143375,\"jsonrpc\":\"2.0\",\"params\":[{\"to\":\"0x2cc25bdabd264ab306d47938f3c701a6df0e883a\",\"fromBlock\":\"0x0\",\"toBlock\":\"0x53923c\",\"topics\":[\"0x92ebdf1fe2f64daffddb436aae297d78fe97201925117af65ae23ee5e5e5d36d\"]}],\"method\":\"eth_getLogs\"} Error: Invalid params: unknown field 'to', expected one of 'fromBlock', 'toBlock', 'address', 'topics', 'limit'.","code":-32603}

@gasolin
Copy link

gasolin commented Apr 18, 2018

@SilentCicero the above mentioned format works

const filter = contract.SomeEvent();
filter.new()
filter.watch((err, result) => {
  if(result[0]) {
    // do something
  }
});

Though I saw 2 things unidentical:

  1. it's the callback, not a promise
  2. the event watch keeping update every seconds with empty result, need extra filter(as above) for it.

@SilentCicero
Copy link
Member

SilentCicero commented Apr 18, 2018 via email

@gasolin
Copy link

gasolin commented Apr 21, 2018

@SilentCicero I found the event watch keeping update every seconds issue might be related to
https://github.com/ethjs/ethjs-filter/blob/master/src/index.js#L48

Moving watcher.callback into (Array.isArray(decodedChangeResults) && changeResult.length > 0) might fix that issue (haven't test that)

@soundyogi
Copy link

soundyogi commented Jun 12, 2018

Error: Invalid params: unknown field 'to', expected one of 'fromBlock', 'toBlock', 'address', 'topics', 'limit'.","code":-32603}

i get this error too :< did the api change? seem like 'to' should be 'address'

I made the RPC error go away like this but it seems I cant watch for events (watch callback is never called)

  componentDidMount(){
    console.log('mount')
    this.freed = getAPI().freedEvent()
    
    if(!this.props.address) throw new Error('no address')
    
    this.freed
      .new({ toBlock: 'latest', address: this.props.address, to: undefined })
      .then((result) => {
        console.log(result)
      })
      .catch((error) => {
        throw new Error(error)
      });

    this.freed.watch((err, result) => {
      console.log("WATCH!");
      if(err) throw new Error()
    });

  }
  onComponentWillUnmount() {
    this.freed.uninstall();
  }

legobeat added a commit to legobeat/ethjs-filter that referenced this issue Nov 14, 2023
* devDeps: ganache-core@2.1.0 -> ganache-cli@^6.12.2
  Necessary to make tests pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants