Skip to content

Instantly share code, notes, and snippets.

@00-matt
Created September 21, 2019 16:09
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 00-matt/e7d2fb97ed055f1cdd5f4392ebc74b43 to your computer and use it in GitHub Desktop.
Save 00-matt/e7d2fb97ed055f1cdd5f4392ebc74b43 to your computer and use it in GitHub Desktop.
A Node.js JSON-RPC client
const { createClient } = require('./JsonRpcClient')
;(async () => {
const client = createClient('node.supportxmr.com', 18081)
const { height } = await client.getInfo()
console.log('The last block height was %d.', height)
})()
/*
* JsonRpcClient.js 1.0 - A Node.js JSON-RPC client
*
* Written in 2019 by Matt Smith <matt@offtopica.uk>
*
* To the extent possible under law, the author(s) have dedicated all
* copyright and related and neighboring rights to this software to
* the public domain worldwide. This software is distributed without
* any warranty.
*
* See https://creativecommons.org/publicdomain/zero/1.0/ for more
* info.
*/
const http = require('http')
const JSONRPC = '2.0'
class JsonRpcClient {
constructor (hostname, port, path = '/json_rpc') {
this._agent = new http.Agent({ keepAlive: true })
this._hostname = hostname
this._path = path
this._port = port
}
call (method, params = {}) {
return new Promise((resolve, reject) => {
const payload = JSON.stringify({
jsonrpc: JSONRPC,
id: '0',
method,
params
})
const options = {
agent: this._agent,
hostname: this._hostname,
port: this._port,
path: this._path,
method: 'POST',
headers: {
'Content-Length': Buffer.byteLength(payload),
'Content-Type': 'application/json'
}
}
const req = http.request(options, res => {
let response = ''
res.setEncoding('utf8')
res.on('data', chunk => {
response += chunk
})
res.on('end', () => {
try {
const decoded = JSON.parse(response)
if (decoded.error) {
return reject(new Error(decoded.error.message))
} else if (decoded.result) {
return resolve(decoded.result)
} else {
return reject(new Error('Malformed response'))
}
} catch (err) {
reject(err)
}
})
})
req.on('error', err => { return reject(err) })
req.write(payload)
req.end()
})
}
}
const snakeCase = x =>
x.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase()
const createClient = (hostname, port, path) =>
new Proxy(new JsonRpcClient(hostname, port, path), {
get: (target, prop) =>
target[prop]
? target[prop]
: params => target.call(snakeCase(prop), params)
})
module.exports = { createClient }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment