status-go
status-go copied to clipboard
RPC PUB SUB support
Problem
New ethereum provider introduces notifications in https://eips.ethereum.org/EIPS/eip-1193, which use RPC PUB SUB https://github.com/ethereum/go-ethereum/wiki/RPC-PUB-SUB#supported-subscriptions, we need support for this in status-go
Ethereum Improvement Proposals[Ethereum Provider JavaScript API](http://eips.ethereum.org/EIPS/eip-1193)Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platform, including core protocol specifications, client APIs, and contract standards.
GitHub[ethereum/go-ethereum](https://github.com/ethereum/go-ethereum)Official Go implementation of the Ethereum protocol - ethereum/go-ethereum
I would make switching to gomobile a blocker for this taks. When we have gomobile, the implementation will be much nicer.
I would make switching to gomobile a blocker for this taks. When we have gomobile, the implementation will be much nicer.
can you clarify why it will be easier?
@dshulyak we will be able to do stuff like this. It will be possible to write something like:
// Objective-C
StatusgoSubscribe(@"networkChanged", callback)
where callback is a function or an object matching an interface defined in status-go.
With CGO we can't pass anything else than a byte array.
@adambabik i guess you have different implementation in mind. i assumed that we will have to use signals as a subscription channel.
as i understand rpc returns ID when subscription is created. i thought that we will implement another rpc transport that will deliver data to subscribers through signals. subscriber, in this case signals handlers in clojure code, will have to keep IDs somewhere in web3 state. and dispatch payload based on ID received from the signal.
as for the payload it makes sense to use json, probably we won't have to change this part anyway, as rpc marshalls everything as json anyway.
Yes, I have a different implementation in mind. I am not sure if using signals is the best experience from Clojure side. In the examples from @flexsurfer there is something like this for subscriptions:
const logAccounts = accounts => {
console.log(`Accounts:\n${accounts.join('\n')}`);
};
ethereum.on('accountsChanged', logAccounts);
With signals, we probably need something like this:
ethereum.on('accountsChanged', handleSubscriptionSignal(subscriptionID, logAccounts));
but the problem is that subscriptionID is unknown yet, it's returned by on().
That's why I though about gomobile because a callback in Clojure/JS can be used. on() will be a React Native method which will have a callback and in ObjC/Java this callback will be passed to status-go.
but the problem is that subscriptionID is unknown yet, it's returned by on().
subscriptioID needs to be known anyway. i think it is stored somewhere inside of the ethereum object. so by this call you just subscribe with callback, ethereum object makes a call, but subscriptionID is unknown to a subscriber.
unless ethereum is not stateful object nothing changes dramatically, but internally signals can be used instead of ipc or websockets.
Oh yeah, I did not notice that:
let subId;
ethereum
.send('eth_subscribe', ['newHeads'])
.then(subscriptionId => {
subId = subscriptionId;
ethereum.on('notification', result => {
if (result.subscription === subscriptionId) {
if (result.result instanceof Error) {
const error = result.result;
console.error(
`Error from newHeads subscription: ${error.message}.
Code: ${error.code}. Data: ${error.data}`
);
} else {
const block = result.result;
console.log(`New block ${block.number}:`, block);
}
}
});
})
So actually it's on user to properly filter received notifications. In terms of events, there is a finite set of them: notification, connect, close, networkChanged, and accountsChanged and each can correspond to a signal with a type.
Missed the comments here somehow (I think I had this page open since yesterday and it didn't refresh) and already started looking into this today, and yeah, things are working fine in the way @dshulyak explained, now it's only a question of implementing the required code on the react side. Pushing the current state so you can take a look.
@jeluard @flexsurfer if you want to give this a spin, there's a status-go build in progress. You'll just need to add the 3 new signals to https://github.com/status-im/status-react/blob/develop/src/status_im/signals/core.cljs#L78 and handle them appropriately. Please let me know if you have any questions.
GitHub
a free (libre) open source, mobile OS for Ethereum - status-im/status-react
@PombeirP Thanks! @flexsurfer Can you take a look?
yep
@PombeirP looks like build is failed ?
@flexsurfer please try this one: https://ci.status.im/job/status-go/job/parallel/213/. Seems like there's a flaky unit test.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.