Skip to content

Instantly share code, notes, and snippets.

@akirattii
Last active July 11, 2018 03:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akirattii/bd39c76e8750eb264eed4b0ff58bccee to your computer and use it in GitHub Desktop.
Save akirattii/bd39c76e8750eb264eed4b0ff58bccee to your computer and use it in GitHub Desktop.
NodeJS: RPC Client module class (either callback and async/await available)
const RpcClient = require("./RpcClient.js");
const rpcClient = new RpcClient({ url: "https://ropsten.infura.io/XXXXXXX" });
// RPC request param
const param = {
method: "eth_getBalance",
params: ["0x5724feec83cec20cc4392033ab2753dc8513e333", "latest"],
};
// callback way:
rpcClient.call(param, (err, res)=>{
console.log("callback result:", err, res);
});
// async/await way:
(async() => {
try {
const result = await rpcClient.call(param);
console.log("async/await result:", result);
} catch(ex) {
console.error(ex);
}
})().catch(console.error);
// Simple JSON RPC Client
const request = require("request");
const requestAsync = require("request-promise");
// const axios = require("axios");
module.exports = class RpcClient {
constructor({
url,
jsonrpc = "2.0",
debug = false,
logger = console,
}) {
if (!RpcClient.isValidUrl(url))
throw Error(`invalid url: "${url}"`);
this.url = url;
this.jsonrpc = jsonrpc;
this.debug = debug;
this.logger = logger;
}
//**************************************************************
// main methods
//**************************************************************
/**
* RPC request. Either callback and async/await available
* Example: `call({method:"getblockhash", params:["1"], id:1}, (err, res)=>{...});
* @param {Object} - params:
* - method {String} - RPC method
* - params {Object} - RPC params
* - id {String|Number} - [Optional] RPC request ID
* - requestOpts {Object} - [Optional] request options.
* @see:https://github.com/request/request#requestoptions-callback
*/
async call({ method, params, id = 1, requestOpts = {} }, cb) {
const self = this;
const p = self._createRequestParam(method, params, id, requestOpts);
if (typeof cb === "function") { // callback
request(p, (err, response, body) => {
if (err) return cb && cb(err);
return cb && cb(err, bodyToResult(body));
});
} else { // async/await
const body = await requestAsync(p);
return bodyToResult(body);
}
function bodyToResult(bodyStr) {
try {
const body = JSON.parse(bodyStr); // parse json string
const err = (body && body.error) ? body.error : null;
const result = (body && body.result) ? body.result : null;
return result;
} catch (ex) {
return null;
}
}
}
//**************************************************************
// sub methods
//**************************************************************
/**
* Creates request parameter
*/
_createRequestParam(method, params, id, requestOpts) {
// RPC Param: looks like this: '{"jsonrpc": "1.0", "id":"curltest", "method": "getinfo", "params": [] }'
const data = {
jsonrpc: this.jsonrpc,
id,
method,
params,
};
let p = {
url: this.url,
body: JSON.stringify(data),
headers: {
"Content-type": "application/json; charset=UTF-8",
"Accept": "application/json, text/javascript",
},
method: "POST", // JSONRPC server handles only POST requests
encoding: "UTF-8",
// json: true,
};
if (requestOpts) p = Object.assign(p, requestOpts);
if (this.debug) this.logger.info("requesting param:", p);
return p;
}
//**************************************************************
// utility static methods
//**************************************************************
static isValidUrl(v) {
return /^https?:\/\/.+$/.test(v);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment