From 9f935e2c2bf8c1272de7a67ef5c4a917761d057b Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Fri, 17 Apr 2020 11:04:58 -0700 Subject: [PATCH] fix(electrumx): Added transaction history endpoints --- src/electrumx.js | 47 +++++++++++++++++++++++ test/integration/electrumx.js | 55 +++++++++++++++++++++++++++ test/integration/testnet/electrumx.js | 55 +++++++++++++++++++++++++++ 3 files changed, 157 insertions(+) diff --git a/src/electrumx.js b/src/electrumx.js index 05b42b2..675fa4b 100644 --- a/src/electrumx.js +++ b/src/electrumx.js @@ -128,6 +128,53 @@ class ElectrumX { else throw error } } + + /** + * @api ElectrumX.transactions() transactions() - Get the transaction history for an address. + * @apiName ElectrumX Transactions + * @apiGroup ElectrumX + * @apiDescription Return a transaction history for an address. + * + * @apiExample Example usage: + * (async () => { + * try { + * let transactions = await bchjs.Electrumx.transactions('bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf'); + * console.log(utxo); + * } catch(error) { + * console.error(error) + * } + * })() + * + */ + async transactions(address) { + try { + // Handle single address. + if (typeof address === "string") { + const response = await axios.get( + `${this.restURL}electrumx/transactions/${address}`, + _this.axiosOptions + ) + return response.data + + // Handle array of addresses. + } else if (Array.isArray(address)) { + const response = await axios.post( + `${this.restURL}electrumx/transactions`, + { + 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 diff --git a/test/integration/electrumx.js b/test/integration/electrumx.js index 5a30d10..e7f9915 100644 --- a/test/integration/electrumx.js +++ b/test/integration/electrumx.js @@ -123,4 +123,59 @@ describe(`#ElectrumX`, () => { } }) }) + + describe(`#transactions`, () => { + it(`should GET transaction history for a single address`, async () => { + const addr = "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v" + + const result = await bchjs.Electrumx.transactions(addr) + // console.log(`result: ${JSON.stringify(result, null, 2)}`) + + assert.property(result, "success") + assert.equal(result.success, true) + + assert.property(result, "transactions") + assert.isArray(result.transactions) + assert.property(result.transactions[0], "height") + assert.property(result.transactions[0], "tx_hash") + }) + + it(`should POST request for transaction history for an array of addresses`, async () => { + const addr = [ + "bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj", + "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v" + ] + + const result = await bchjs.Electrumx.transactions(addr) + // console.log(`result: ${JSON.stringify(result, null, 2)}`) + + assert.property(result, "success") + assert.equal(result.success, true) + + assert.property(result, "transactions") + assert.isArray(result.transactions) + + assert.property(result.transactions[0], "address") + assert.property(result.transactions[0], "transactions") + assert.isArray(result.transactions[0].transactions) + assert.property(result.transactions[0].transactions[0], "height") + assert.property(result.transactions[0].transactions[0], "tx_hash") + }) + + it(`should throw error on array size rate limit`, async () => { + try { + const addr = [] + for (let i = 0; i < 25; i++) + addr.push("bitcoincash:qrehqueqhw629p6e57994436w730t4rzasnly00ht0") + + const result = await bchjs.Electrumx.transactions(addr) + + console.log(`result: ${util.inspect(result)}`) + assert.equal(true, false, "Unexpected result!") + } catch (err) { + assert.hasAnyKeys(err, ["error"]) + assert.include(err.error, "Array too large") + } + }) + }) }) diff --git a/test/integration/testnet/electrumx.js b/test/integration/testnet/electrumx.js index cc69db1..aad0b39 100644 --- a/test/integration/testnet/electrumx.js +++ b/test/integration/testnet/electrumx.js @@ -127,4 +127,59 @@ describe(`#ElectrumX`, () => { } }) }) + + describe(`#transactions`, () => { + it(`should GET transaction history for a single address`, async () => { + const addr = "bchtest:qrvn2n228aa39xupcw9jw0d3fj8axxky656e4j62z2" + + const result = await bchjs.Electrumx.transactions(addr) + // console.log(`result: ${JSON.stringify(result, null, 2)}`) + + assert.property(result, "success") + assert.equal(result.success, true) + + assert.property(result, "transactions") + assert.isArray(result.transactions) + assert.property(result.transactions[0], "height") + assert.property(result.transactions[0], "tx_hash") + }) + + it(`should POST request for transaction history for an array of addresses`, async () => { + const addr = [ + "bchtest:qrvn2n228aa39xupcw9jw0d3fj8axxky656e4j62z2", + "bchtest:qrvn2n228aa39xupcw9jw0d3fj8axxky656e4j62z2" + ] + + const result = await bchjs.Electrumx.transactions(addr) + // console.log(`result: ${JSON.stringify(result, null, 2)}`) + + assert.property(result, "success") + assert.equal(result.success, true) + + assert.property(result, "transactions") + assert.isArray(result.transactions) + + assert.property(result.transactions[0], "address") + assert.property(result.transactions[0], "transactions") + assert.isArray(result.transactions[0].transactions) + assert.property(result.transactions[0].transactions[0], "height") + assert.property(result.transactions[0].transactions[0], "tx_hash") + }) + + it(`should throw error on array size rate limit`, async () => { + try { + const addr = [] + for (let i = 0; i < 25; i++) + addr.push("bchtest:qrvn2n228aa39xupcw9jw0d3fj8axxky656e4j62z2") + + const result = await bchjs.Electrumx.transactions(addr) + + console.log(`result: ${util.inspect(result)}`) + assert.equal(true, false, "Unexpected result!") + } catch (err) { + assert.hasAnyKeys(err, ["error"]) + assert.include(err.error, "Array too large") + } + }) + }) })