From a7564ce61146a7f817793b01f58116c51ae8e7fb Mon Sep 17 00:00:00 2001 From: Stoyan Zhekov Date: Mon, 9 Nov 2020 17:44:09 +0900 Subject: [PATCH 1/2] Add Ninsight Unconfirmed UTXOs --- src/ninsight.js | 73 ++++++++++++++++++++++++++++- test/unit/fixtures/ninsight-mock.js | 23 ++++++++- test/unit/ninsight.js | 60 ++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 3 deletions(-) diff --git a/src/ninsight.js b/src/ninsight.js index 8611d71..3322510 100644 --- a/src/ninsight.js +++ b/src/ninsight.js @@ -50,14 +50,16 @@ class Ninsight { * // { * // "txid": "d31dc2cf66fe4d3d3ae18e1065def58a64920746b1702b52f060e5edeea9883b", * // "vout": 1, - * // "value": "1000000", + * // "amount": 0.03608203, + * // "satoshis": 3608203, * // "height": 585570, * // "confirmations": 10392 * // }, * // { * // "txid": "41e9a118765ecf7a1ba4487c0863e23dba343cc5880381a72f0365ac2546c5fa", * // "vout": 0, - * // "value": "1000000", + * // "amount": 0.03608203, + * // "satoshis": 3608203, * // "height": 577125, * // "confirmations": 18837 * // } @@ -96,6 +98,73 @@ class Ninsight { else throw error } } + + /** + * @api Ninsight.unconfirmed() unconfirmed() + * @apiName Ninsight Unconfirmed Utxo + * @apiGroup Ninsight + * @apiDescription Return list of unconfirmed uxto for address. + * + * @apiExample Example usage: + * (async () => { + * try { + * let utxo = await bchjs.Ninsight.unconfirmed('bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c'); + * console.log(utxo); + * } catch(error) { + * console.error(error) + * } + * })() + * + * // [ + * // { + * // "txid": "d31dc2cf66fe4d3d3ae18e1065def58a64920746b1702b52f060e5edeea9883b", + * // "vout": 1, + * // "amount": 0.03608203, + * // "satoshis": 3608203, + * // "confirmations": 0 + * // "ts": 1559670801 + * // }, + * // { + * // "txid": "41e9a118765ecf7a1ba4487c0863e23dba343cc5880381a72f0365ac2546c5fa", + * // "vout": 0, + * // "amount": 0.03608203, + * // "satoshis": 3608203, + * // "confirmations": 0 + * // "ts": 1559670902 + * // } + * // ] + * + */ + async unconfirmed(address) { + try { + if (typeof address === "string") { + const response = await axios.post( + `${this.ninsightURL}/address/unconfirmed`, + { + addresses: [address] + }, + _this.axiosOptions + ) + + return response.data + } else if (Array.isArray(address)) { + const response = await axios.post( + `${this.ninsightURL}/address/unconfirmed`, + { + 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 = Ninsight diff --git a/test/unit/fixtures/ninsight-mock.js b/test/unit/fixtures/ninsight-mock.js index cfc4f62..9fa3afb 100644 --- a/test/unit/fixtures/ninsight-mock.js +++ b/test/unit/fixtures/ninsight-mock.js @@ -21,9 +21,30 @@ const utxo = { "OP_DUP OP_HASH160 2fe2c4c5ef359bb2fe1a849f891cecffbcfb4f77 OP_EQUALVERIFY OP_CHECKSIG" } +const unconfirmed = { + utxos: [ + { + txid: + "3904ffe6f8fba4ceda5e887130f60fcb18bdc7dcee10392a57f89475c5c108f1", + vout: 0, + amount: 0.03608203, + satoshis: 3608203, + confirmations: 0, + ts: 1559670801 + } + ], + legacyAddress: "1AyWs8U4HUnTLmxxFiGoJbsXauRsvBrcKW", + cashAddress: "bitcoincash:qpkkjkhe29mqhqmu3evtq3dsnruuzl3rku6usknlh5", + slpAddress: "simpleledger:qpkkjkhe29mqhqmu3evtq3dsnruuzl3rkuk8mdxlf2", + scriptPubKey: "76a9146d695af951760b837c8e58b045b098f9c17e23b788ac" +} + const utxoPost = [utxo, utxo] +const unconfirmedPost = [unconfirmed, unconfirmed] module.exports = { utxo, - utxoPost + utxoPost, + unconfirmed, + unconfirmedPost } diff --git a/test/unit/ninsight.js b/test/unit/ninsight.js index d71896f..a0c2fb9 100644 --- a/test/unit/ninsight.js +++ b/test/unit/ninsight.js @@ -78,4 +78,64 @@ describe(`#Ninsight`, () => { assert.property(result[0], "asm") }) }) + describe("#unconfirmed", () => { + it("should throw an error for improper input", async () => { + try { + const addr = 12345 + + await bchjs.Ninsight.unconfirmed(addr) + assert.equal(true, false, "Unexpected result!") + } catch (err) { + assert.include( + err.message, + "Input address must be a string or array of strings." + ) + } + }) + it(`should POST utxos for a single address`, async () => { + // Stub the network call. + sandbox.stub(axios, "post").resolves({ data: mockData.unconfirmed }) + + const addr = "bitcoincash:qpkkjkhe29mqhqmu3evtq3dsnruuzl3rku6usknlh5" + + const result = await bchjs.Ninsight.unconfirmed(addr) + // console.log(`result: ${JSON.stringify(result, null, 2)}`) + + assert.property(result, "utxos") + assert.property(result, "legacyAddress") + assert.property(result, "cashAddress") + assert.property(result, "slpAddress") + assert.property(result, "scriptPubKey") + + assert.isArray(result.utxos) + + assert.property(result.utxos[0], "txid") + assert.property(result.utxos[0], "vout") + assert.property(result.utxos[0], "amount") + assert.property(result.utxos[0], "satoshis") + assert.property(result.utxos[0], "confirmations") + assert.property(result.utxos[0], "ts") + }) + it(`should POST utxo details for an array of addresses`, async () => { + // Mock the network call. + sandbox.stub(axios, "post").resolves({ data: mockData.unconfirmedPost }) + + const addr = [ + "bitcoincash:qpkkjkhe29mqhqmu3evtq3dsnruuzl3rku6usknlh5", + "bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr" + ] + + const result = await bchjs.Ninsight.unconfirmed(addr) + // console.log(`result: ${JSON.stringify(result, null, 2)}`) + + assert.isArray(result) + assert.isArray(result[0].utxos) + + assert.property(result[0], "utxos") + assert.property(result[0], "legacyAddress") + assert.property(result[0], "cashAddress") + assert.property(result[0], "slpAddress") + assert.property(result[0], "scriptPubKey") + }) + }) }) From b8083c6b889c646cc1b07e849f0520959808de9c Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Mon, 9 Nov 2020 15:45:11 -0800 Subject: [PATCH 2/2] fix(ninsight): Adding unconfirmed UTXOs endpoint --- src/ninsight.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ninsight.js b/src/ninsight.js index 3322510..baeaa5f 100644 --- a/src/ninsight.js +++ b/src/ninsight.js @@ -103,7 +103,7 @@ class Ninsight { * @api Ninsight.unconfirmed() unconfirmed() * @apiName Ninsight Unconfirmed Utxo * @apiGroup Ninsight - * @apiDescription Return list of unconfirmed uxto for address. + * @apiDescription Returns a list of unconfirmed UTXOs for an address. * * @apiExample Example usage: * (async () => {