Merge pull request #16 from christroutner/unstable

fix(ElectrumX): Added ElectrumX library and first endpoint
This commit is contained in:
Chris Troutner
2020-04-07 19:12:11 -07:00
committed by GitHub
7 changed files with 639 additions and 317 deletions
+417 -209
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -34,6 +34,7 @@ const SLP = require("./slp/slp")
const Blockbook = require("./blockbook")
const OpenBazaar = require("./openbazaar")
const Ninsight = require("./ninsight")
const Electrumx = require("./electrumx")
class BCHJS {
constructor(config) {
@@ -67,6 +68,9 @@ class BCHJS {
// Bitcoin.com Ninsight indexer
this.Ninsight = new Ninsight()
// ElectrumX indexer
this.Electrumx = new Electrumx(libConfig)
// Populate Full Node
this.Control = new Control(libConfig)
this.Mining = new Mining(libConfig)
@@ -174,6 +178,7 @@ class BitboxShim {
// Bitcoin.com Ninsight indexer
this.Ninsight = new Ninsight()
this.Electrumx = new Electrumx(libConfig)
}
}
+26 -108
View File
@@ -229,57 +229,21 @@ class Blockbook {
* @apiExample Example usage:
* (async () => {
* try {
* let utxo = await bchjs.Blockbook.utxo('bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c');
* let utxo = await bchjs.Blockbook.utxo('bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf');
* console.log(utxo);
* } catch(error) {
* console.error(error)
* }
* })()
*
* // [
* // {
* // "txid": "d31dc2cf66fe4d3d3ae18e1065def58a64920746b1702b52f060e5edeea9883b",
* // "vout": 1,
* // "value": "1000000",
* // "height": 585570,
* // "confirmations": 10392
* // },
* // {
* // "txid": "41e9a118765ecf7a1ba4487c0863e23dba343cc5880381a72f0365ac2546c5fa",
* // "vout": 0,
* // "value": "1000000",
* // "height": 577125,
* // "confirmations": 18837
* // },
* // {
* // "txid": "2f902dec880568511cefa87b9dd761563edeba9c8ba784dc9fca2f7c8c4e6f97",
* // "vout": 0,
* // "value": "1000000",
* // "height": 569922,
* // "confirmations": 26040
* // },
* // {
* // "txid": "eea57285462dd70dadcd431fc814857b3f81fe4d0a059a8c02c12fd7d33c02d1",
* // "vout": 0,
* // "value": "1000000",
* // "height": 566900,
* // "confirmations": 29062
* // },
* // {
* // "txid": "282b3b296b6aed7122586ed69f7a57d35584eaf94a4d1b1ad7d1b05d36cb79d1",
* // "vout": 0,
* // "value": "1000000",
* // "height": 563858,
* // "confirmations": 32104
* // },
* // {
* // "txid": "ac444896b3e32d17824fa6573eed3b89768c5c9085b7a71f3ba88e9d5ba67355",
* // "vout": 13,
* // "value": "1000000",
* // "height": 558992,
* // "confirmations": 36970
* // }
* // ]
* [{
* "txid": "7774e449c5a3065144cefbc4c0c21e6b69c987f095856778ef9f45ddd8ae1a41",
* "vout": 0,
* "value": "1000",
* "height": 604392,
* "confirmations": 25530,
* "satoshis": 1000
* }]
*
*
* (async () => {
@@ -294,69 +258,23 @@ class Blockbook {
* }
* })()
*
* //[
* // [
* // {
* // "txid": "27ec8512c1a9ee9e9ae9b98eb60375f1d2bd60e2e76a1eff5a45afdbc517cf9c",
* // "vout": 0,
* // "value": "100000",
* // "height": 560430,
* // "confirmations": 35535
* // },
* // {
* // "txid": "6e1ae1bf7db6de799ec1c05ab2816ac65549bd80141567af088e6f291385b07d",
* // "vout": 0,
* // "value": "130000",
* // "height": 560039,
* // "confirmations": 35926
* // }
* // ],
* // [
* // {
* // "txid": "d31dc2cf66fe4d3d3ae18e1065def58a64920746b1702b52f060e5edeea9883b",
* // "vout": 1,
* // "value": "1000000",
* // "height": 585570,
* // "confirmations": 10395
* // },
* // {
* // "txid": "41e9a118765ecf7a1ba4487c0863e23dba343cc5880381a72f0365ac2546c5fa",
* // "vout": 0,
* // "value": "1000000",
* // "height": 577125,
* // "confirmations": 18840
* // },
* // {
* // "txid": "2f902dec880568511cefa87b9dd761563edeba9c8ba784dc9fca2f7c8c4e6f97",
* // "vout": 0,
* // "value": "1000000",
* // "height": 569922,
* // "confirmations": 26043
* // },
* // {
* // "txid": "eea57285462dd70dadcd431fc814857b3f81fe4d0a059a8c02c12fd7d33c02d1",
* // "vout": 0,
* // "value": "1000000",
* // "height": 566900,
* // "confirmations": 29065
* // },
* // {
* // "txid": "282b3b296b6aed7122586ed69f7a57d35584eaf94a4d1b1ad7d1b05d36cb79d1",
* // "vout": 0,
* // "value": "1000000",
* // "height": 563858,
* // "confirmations": 32107
* // },
* // {
* // "txid": "ac444896b3e32d17824fa6573eed3b89768c5c9085b7a71f3ba88e9d5ba67355",
* // "vout": 13,
* // "value": "1000000",
* // "height": 558992,
* // "confirmations": 36973
* // }
* // ]
* //]
* //
* [
* [{
* "txid": "7774e449c5a3065144cefbc4c0c21e6b69c987f095856778ef9f45ddd8ae1a41",
* "vout": 0,
* "value": "1000",
* "height": 604392,
* "confirmations": 25530,
* "satoshis": 1000
* }],
* [{
* "txid": "d5228d2cdc77fbe5a9aa79f19b0933b6802f9f0067f42847fc4fe343664723e5",
* "vout": 0,
* "value": "6000",
* "confirmations": 0,
* "satoshis": 6000
* }]
* ]
*/
async utxo(address) {
try {
+86
View File
@@ -0,0 +1,86 @@
/*
This library interacts with the ElectrumX bch-api REST API endpoints operated
by FullStack.cash
*/
const axios = require("axios")
let _this
class ElectrumX {
constructor(config) {
this.restURL = config.restURL
this.apiToken = config.apiToken
// Add JWT token to the authorization header.
this.axiosOptions = {
headers: {
authorization: `Token ${this.apiToken}`,
timeout: 15000
}
}
_this = this
}
/**
* @api ElectrumX.utxo() utxo() - Get a list of uxto for an address.
* @apiName ElectrumX Utxo
* @apiGroup ElectrumX
* @apiDescription Return a list of uxtos for an address.
*
* @apiExample Example usage:
* (async () => {
* try {
* let utxo = await bchjs.Electrumx.utxo('bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf');
* console.log(utxo);
* } catch(error) {
* console.error(error)
* }
* })()
*
* utxo = {
* success: true,
* utxos: [
* {
* height: 602405,
* tx_hash:
* "2b37bdb3b63dd0bca720437754a36671431a950e684b64c44ea910ea9d5297c7",
* tx_pos: 0,
* value: 1000
* }
* ]
* }
*/
async utxo(address) {
try {
// Handle single address.
if (typeof address === "string") {
const response = await axios.get(
`${this.restURL}electrumx/utxos/${address}`,
_this.axiosOptions
)
return response.data
// Handle array of addresses.
} else if (Array.isArray(address)) {
const response = await axios.post(
`${this.restURL}electrumx/utxos`,
{
addresses: address
},
_this.axiosOptions
)
return response.data
}
throw new Error(`Input address must be a string or array of strings.`)
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
}
}
}
module.exports = ElectrumX
+32
View File
@@ -0,0 +1,32 @@
const chai = require("chai")
const assert = chai.assert
const sinon = require("sinon")
const BCHJS = require("../../src/bch-js")
const bchjs = new BCHJS()
describe(`#ElectrumX`, () => {
let sandbox
beforeEach(() => (sandbox = sinon.createSandbox()))
afterEach(() => sandbox.restore())
describe(`#utxo`, () => {
it(`should GET utxos for a single address`, async () => {
const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9"
const result = await bchjs.Electrumx.utxo(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "success")
assert.equal(result.success, true)
assert.property(result, "utxos")
assert.isArray(result.utxos)
assert.property(result.utxos[0], "height")
assert.property(result.utxos[0], "tx_hash")
assert.property(result.utxos[0], "tx_pos")
assert.property(result.utxos[0], "value")
})
})
})
+53
View File
@@ -0,0 +1,53 @@
const chai = require("chai")
const assert = chai.assert
const axios = require("axios")
const sinon = require("sinon")
const BCHJS = require("../../src/bch-js")
const bchjs = new BCHJS()
const mockData = require("./fixtures/electrumx-mock")
describe(`#ElectrumX`, () => {
let sandbox
beforeEach(() => (sandbox = sinon.createSandbox()))
afterEach(() => sandbox.restore())
describe(`#utxo`, () => {
it(`should throw an error for improper input`, async () => {
try {
const addr = 12345
await bchjs.Electrumx.utxo(addr)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
// console.log(`err: `, err)
assert.include(
err.message,
`Input address must be a string or array of strings`
)
}
})
it(`should GET utxos for a single address`, async () => {
// Stub the network call.
sandbox.stub(axios, "get").resolves({ data: mockData.utxo })
const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9"
const result = await bchjs.Electrumx.utxo(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "success")
assert.equal(result.success, true)
assert.property(result, "utxos")
assert.isArray(result.utxos)
assert.property(result.utxos[0], "height")
assert.property(result.utxos[0], "tx_hash")
assert.property(result.utxos[0], "tx_pos")
assert.property(result.utxos[0], "value")
})
})
})
+20
View File
@@ -0,0 +1,20 @@
/*
Mocking data for unit tests for the ElectrumX library.
*/
const utxo = {
success: true,
utxos: [
{
height: 602405,
tx_hash:
"2b37bdb3b63dd0bca720437754a36671431a950e684b64c44ea910ea9d5297c7",
tx_pos: 0,
value: 1000
}
]
}
module.exports = {
utxo
}