In web3 0.x I could send requests directly to the provider with (for example) web3.currentProvider.send({ jsonrpc: '2.0', method: 'evm_increaseTime', params: ['60'], id: 0 }) however attempts to do this with web3 1.0 are failing (and returning null). Is there a new way of doing this with web3 1.0?
Hi @mcdee, according to the docs for v0.2 and v1.0 web3.currentProvider has not changed. It returns the current provider object if it exist and null otherwise.
The send method you are trying to call should belong to the currentProvider object, so I suspect you are getting the null return value due to the currentProvider not existing and therefore web3 returning null.
Could you please log out web3.currentProvider at the point when the call to web3.currentProvider.send fails to confirm my theory please?
@Huanzhang89 thank you for the response. If currentProvider was null the error would be about attempting to call a property of a null object. Printing currentProvider shows that it is set as the expected provider:
HttpProvider {
host: 'http://localhost:8545',
httpAgent:
Agent {
domain: null,
_events: { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 80,
protocol: 'http:',
options: { keepAlive: true, path: null },
requests: {},
sockets: {},
freeSockets: { 'localhost:8545:': [Array] },
keepAliveMsecs: 1000,
keepAlive: true,
maxSockets: Infinity,
maxFreeSockets: 256 },
timeout: 0,
headers: undefined,
connected: true,
send: [Function],
_alreadyWrapped: true,
sendAsync: [Function] }
aha you are right.
Okay I had a look at the send method and it looks like it did indeed change.
The new send method takes in 2 params, method and params
send(method: string, params: any[]): Promise<any>;
Try web3.currentProvider.send('evm_increaseTime', ['60'])
I believe that is provider-specific. The HTTP provider takes a single object.
ah yes, apologies.
The httpProvider.send should take a callback as the second argument and pass the error object to the callback. Could you add a callback and paste back what the error is please?
web3.currentProvider.send({ jsonrpc: '2.0', method: 'evm_increaseTime', params: ['60'], id: 0 }, (err) => { console.log(err) })
No error. It looks as though the evm_increaseTime command gets through to the node (ganache, in case it matters), no idea if it works or not though because of the lack of return information.
Hmm that is very strange, which version of web3 are you using? I'm looking at the sourcecode for the http-provider and it looks like that if the request errored, the callback will receive either an InvalidResponse, ConnectionTimeout, or InvalidConnection error.
The other other possibility is that the request succeeded in which case the second argument of the callback will be the result.
Also as far as I can see the send method does not have a return value.
Could you try the following and let me know if the result is being passed to the callback?
web3.currentProvider.send({ jsonrpc: '2.0', method: 'evm_increaseTime', params: ['60'], id: 0 }, (err, res) => { console.log(err, res) })
Using that the result does show up:
null { id: 0, jsonrpc: '2.0', result: '00060' }
So the question now is how to access this information using await on the method, i.e.
await web3.currentProvider.send({ jsonrpc: '2.0', method: 'evm_increaseTime', params: ['60'], id: 0 })
I think right now that is not possible since the send method does not return a promise.
@nivida has actually done the work to improve all the providers today to support promises as well as callbacks today but it won't be released just yet!
has actually done the work to improve all the providers today to support promises as well as callbacks today but it won't be released just yet!
@Huanzhang89 @mcdee All send() methods of the providers will return a rejected or resolved Promise when the PR #2000 is merged and released. The possibility to use callbacks for the send() method will no longer exist.
I stand corrected :)
Although why not extend it to support callbacks as well? Can just check if the callback exists and return a Promise if it doesn't
@nivida @mcdee I think we have got to the bottom of the issue, can we close this?
I'd rather wait until the proposed fix is merged so I can test it.
Closed because of the ongoing clean up of the issue list. Feel free to ask this in our gitter channel or on stackoverflow.
It seems like this is still broken in "web3": "^1.0.0-beta.55". Is there a new way to do this that isn't documented?
I've tried the following:
web3.currentProvider.send(method, { jsonrpc: '2.0', params }, (err, result) => {
console.log(err, result);
});
web3.currentProvider.send({ method, jsonrpc: '2.0', params }, (err, result) => {
console.log(err, result);
});
try {
const result = await web3.currentProvider.send(method, {
params,
from: accounts[0],
});
} catch (err) {
return console.error(err);
}
If I specify the method outside the object, I get an error that the method takes 2 params and only one is given even if I provide a callback.
Error: Node error: {"message":"Incorrect number of arguments. Method 'eth_signTypedData' requires exactly 2 arguments. Request specified 1 arguments
If I specify the method within the object given to send, I get this error:
Error: Node error: {"message":"Method [object Object] not supported.","code":-32000,"data":{"stack":"Error: Method [object Object]
Thanks for any help!
Hey, did you ever get this working?
Most helpful comment
I'd rather wait until the proposed fix is merged so I can test it.