Compare commits

..
19 Commits
Author SHA1 Message Date
Chris Troutner 4551d1ca99 Merge pull request #50 from Permissionless-Software-Foundation/ninsight-unconfirmed-utxos
Add Ninsight Unconfirmed UTXOs
2020-11-09 15:47:11 -08:00
Chris Troutner b8083c6b88 fix(ninsight): Adding unconfirmed UTXOs endpoint 2020-11-09 15:45:11 -08:00
Stoyan Zhekov a7564ce611 Add Ninsight Unconfirmed UTXOs 2020-11-09 17:44:09 +09:00
Chris Troutner 601b87cb4a Updating README 2020-11-08 19:14:43 -08:00
Chris Troutner edfcc92b7b Merge pull request #48 from Permissionless-Software-Foundation/ct-unstable
Updating README
2020-11-08 19:04:29 -08:00
Chris Troutner a32e0da9be Updating README 2020-11-08 19:02:30 -08:00
Chris Troutner a1bf617d91 Updating README 2020-11-08 18:56:48 -08:00
Chris Troutner 33d2da503d Updating READMe 2020-11-08 18:49:45 -08:00
Chris Troutner c2ff1e2d68 Updating npm lib 2020-11-08 17:46:40 -08:00
Chris Troutner cc9e8c0319 Fixing links in README 2020-11-08 17:38:11 -08:00
Chris Troutner 83389129d6 Merge pull request #47 from Permissionless-Software-Foundation/ct-unstable
fix(network): Updates for fork
2020-11-08 14:07:01 -08:00
Chris Troutner 360d56e283 fix(network): Updates for fork 2020-11-08 14:05:10 -08:00
Chris Troutner 53a0da4ef1 Merge branch 'master' into ct-unstable 2020-11-08 09:36:41 -08:00
Chris Troutner 6d4534f177 Removing test 2020-11-08 09:36:31 -08:00
Chris Troutner 90ec06adaa Merge pull request #46 from Permissionless-Software-Foundation/ct-unstable
Updating e2e rate limit tests
2020-11-08 09:33:29 -08:00
Chris Troutner a6759cdae5 Testing CI 2020-11-08 09:26:24 -08:00
Chris Troutner 078f157e4e fix(rate limits): Updating e2e rate limit tests for new bch-api rate limits 2020-11-08 09:15:53 -08:00
Chris Troutner 98029f74f8 Merge pull request #45 from Permissionless-Software-Foundation/ct-unstable
fix(integration tests): slowing down integration tests for BVT
2020-11-03 09:40:53 -08:00
Chris Troutner 9348ccb7de fix(integration tests): slowing down integration tests for BVT 2020-11-03 08:14:55 -08:00
18 changed files with 255 additions and 282 deletions
+42 -52
View File
@@ -1,68 +1,71 @@
# bch-js
[![Build Status](https://travis-ci.org/christroutner/bch-js.svg?branch=master)](https://travis-ci.org/christroutner/bch-js)
[![Version](https://img.shields.io/npm/v/@chris.troutner/bch-js)](https://www.npmjs.com/package/@chris.troutner/bch-js)
[![Downloads/week](https://img.shields.io/npm/dw/@chris.troutner/bch-js)](https://npmjs.org/package/@chris.troutner/bch-js)
[![License](https://img.shields.io/npm/l/@chris.troutner/bch-js)](https://github.com/christroutner/bch-js/blob/master/LICENSE.md)
[![Build Status](https://travis-ci.org/Permissionless-Software-Foundation/bch-js.svg?branch=master)](https://travis-ci.org/Permissionless-Software-Foundation/bch-js)
[![Version](https://img.shields.io/npm/v/@psf/bch-js)](https://www.npmjs.com/package/@psf/bch-js)
[![Downloads/week](https://img.shields.io/npm/dw/@psf/bch-js)](https://npmjs.org/package/@psf/bch-js)
[![License](https://img.shields.io/npm/l/@psf/bch-js)](https://github.com/Permissionless-Software-Foundation/bch-js/blob/master/LICENSE.md)
[bch-js](https://www.npmjs.com/package/@chris.troutner/bch-js) is a JavaScript npm library for creating web and mobile apps for interacting with the Bitcoin Cash (BCH) blockchain. It can be used for free, but requires an account on [FullStack.cash](https://fullstack.cash) for increased rate limits. Find out more from [this article](https://troutsblog.com/research/bitcoin-cash/how-to-bch-full-stack-developer).
[bch-js](https://www.npmjs.com/package/@psf/bch-js) is a JavaScript npm library for creating web and mobile apps that can interact with the Bitcoin Cash (BCH) blockchains. It can be used for free, but requires an account on [FullStack.cash](https://fullstack.cash) for increased rate limits. Learn more from [this article](https://troutsblog.com/research/bitcoin-cash/how-to-bch-full-stack-developer) about Full Stack Bitcoin Cash development.
### Quick Start Videos:
Here are two YouTube walk-through videos to help you get started:
- [Introduction to bch-js and the bch-js-examples repository](https://youtu.be/GD2i1ZUiyrk)
- [Working with the FullStack.cash JWT token](https://youtu.be/GD2i1ZUiyrk)
### Quick Links
- [npm Library](https://www.npmjs.com/package/@chris.troutner/bch-js)
- [npm Library](https://www.npmjs.com/package/@psf/bch-js)
- [Documentation](https://bchjs.fullstack.cash/)
- [Examples](https://github.com/Permissionless-Software-Foundation/bch-js-examples)
- [api.fullstack.cash](https://api.fullstack.cash) - The REST API this library talks to by default.
- [bchn.fullstack.cash](https://bchn.fullstack.cash) - The REST API this library talks to by default.
- [FullStack.cash](https://fullstack.cash) - cloud-based infrastructure for application developers.
- [FullStack.cash Account](https://fullstack.cash/login) - Get your API key to unlock increased rate limits.
- [FullStack.cash](https://fullstack.cash) - cloud-based infrastructure for application
developers.
- [Permissionless Software Foundation](https://psfoundation.cash) - The organization that maintains this library.
### Quick Notes
- Install library: `npm install @chris.troutner/bch-js`
- Install library: `npm install @psf/bch-js`
- Instantiate the library in your code:
```
const BCHJS = require("@chris.troutner/bch-js")
let bchjs = new BCHJS()
const BCHJS = require("@psf/bch-js")
let bchjs = new BCHJS() // Defaults to BCHN network.
// testnet
bchjs = new BCHJS({ restURL: 'https://tapi.fullstack.cash/v3/' })
bchjs = new BCHJS({ restURL: 'https://testnet3.fullstack.cash/v3/' })
```
This is a fork of the [BITBOX SDK](https://github.com/Bitcoin-com/bitbox-sdk) (which is maintained by Bitcoin.com). This library is intended to be paired with
the [bch-api](https://github.com/christroutner/bch-api) REST API.
This library is intended to be paired with
the [bch-api](https://github.com/Permissionless-Software-Foundation/bch-api) REST API, and the infrastructure provided by [FullStack.cash](https://fullstack.cash). The `restURL` property can be changed to work with different Bitcoin Cash networks:
If you need a backward-compatible instance of this library, you can use a
'shim'. Do it like this:
```
const BCHJS = require("@chris.troutner/bch-js")
const bitbox = BCHJS.BitboxShim({ restURL: 'https://api.fullstack.cash/v3/' })
```
- BCHN Mainnet REST API server: https://bchn.fullstack.cash/v3/
- ABC Mainnet REST API server: https://abc.fullstack.cash/v3/
- Testnet3 REST API server: https://testnet3.fullstack.cash/v3/
- Check server status: https://metrics.fullstack.cash
### API Key
The [bch-api](https://github.com/christroutner/bch-api) REST API hosted by [FullStack.cash](https://fullstack.cash) uses JWT tokens to pay for increased
rate limits when interacting with the back end server. See [this article](https://troutsblog.com/research/bitcoin-cash/how-to-bch-full-stack-developer) if you want to understand the system-as-a-whole. The JWT token can be fed to bch-js *implicitly* or *explicitly*.
- Implicitly: bch-js will detect your JWT token by setting the `BCHJSTOKEN` environment variable.
The [bch-api](https://github.com/Permissionless-Software-Foundation/bch-api) REST API hosted by [FullStack.cash](https://fullstack.cash) uses JWT tokens to pay for increased
rate limits when interacting with the back end server. See [this article](https://troutsblog.com/research/bitcoin-cash/how-to-bch-full-stack-developer) if you want to understand the system-as-a-whole. The JWT token can be fed to bch-js _implicitly_ or _explicitly_.
- Implicitly: bch-js will detect your JWT token if you set the `BCHJSTOKEN` environment variable.
- Explicitly: You can directly feed in the JWT token with the `apiToken` property when instantiating the library. Here is an example:
```
const BCHJS = require("@chris.troutner/bch-js")
const BCHJS = require("@psf/bch-js")
let bchjs = new BCHJS({
restURL: 'https://api.fullstack.cash/v3/',
restURL: 'https://bchn.fullstack.cash/v3/',
apiToken: 'eyJhbGciO...' // Your JWT token here.
})
```
### Gatsby
bch-js is included in this [gatsby-ipfs-template](https://github.com/Permissionless-Software-Foundation/gatsby-ipfs-template) for building uncensorable web apps that can interact with the blockchain. When building a Gatsby (or other front-end app that uses Webpack), you'll need to add these lines to your `gatsby-node.js` file, as per [this issue](https://github.com/gatsbyjs/gatsby/issues/564):
```
exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
@@ -75,60 +78,47 @@ exports.onCreateWebpackConfig = ({ actions }) => {
This is because the new IPFS class in bch-js uses the fs library for uploading files, which is not supported by Gatsby.
We also provide [minimal-slp-wallet-web](https://www.npmjs.com/package/minimal-slp-wallet-web) as a basic Bitcoin Cash wallet with SLP support, for front end projects. bch-js is encapsulated inside the instantiation of the library Class.
## Features
This library sets itself apart from BITBOX with the following features:
- [ECMAScript 2017 standard JavaScript](https://en.wikipedia.org/wiki/ECMAScript#8th_Edition_-_ECMAScript_2017) used instead of TypeScript. Works
natively with node.js v10 or higher.
natively with node.js v10 or higher.
- Full SLP tokens support: bch-js has full support for all SLP token functionality, including send, mint, and genesis transactions. It also fully support all aspects of [non-fugible tokans (NFTs)](https://www.youtube.com/watch?v=vvlpYUx6HRs).
- [Semantic Release](https://github.com/semantic-release/semantic-release) for
continuous delivery using semantic versioning.
continuous delivery using semantic versioning.
- [Greenkeeper](https://greenkeeper.io/) automatic dependency management for
automatically maintaining the latest, most secure dependencies.
automatically maintaining the latest, most secure dependencies.
- [IPFS uploads](https://ipfs.io) of all files and dependencies, to backup
dependencies in case they are ever inaccessible from GitHub or npm.
dependencies in case they are ever inaccessible from GitHub or npm.
## Documentation:
Full documentation for this library can be found here:
- [Documentation](https://bchjs.fullstack.cash/)
Original documentation on BITBOX is available at:
- [General docs](https://developer.bitcoin.com)
- [BITBOX Introduction](https://developer.bitcoin.com/bitbox)
- [BITBOX API Reference](https://developer.bitcoin.com/bitbox/docs/getting-started)
bch-js uses [APIDOC](http://apidocjs.com/) so that documentation and working code
live in the same repository. To generate the documentation:
- `npm run docs`
- Open the generated `docs/index.html` file in a web browser.
## Support
Have questions? Need help? Join our community support
[Telegram channel](https://t.me/bch_js_toolkit)
## IPFS Releases
I will periodically publish IPFS releases of this repository, including all
dependencies in the `node_modules` folder. This ensures working copies of this
repository can be retrieved in case there is any drift in dependency files, or
if dependencies are pulled from npm or GitHub.
Copies of this repository are also published on IPFS.
- Initial fork on 5/9/2019:
- without node_modules folder: QmQFHfbBQdEHfhtiRLbXtX1NcgnfL45hZb7TbQimTXAuzG (4 MB)
- with node_modules folder: QmXq9Ds6Qdkg9xbRhcF8pay9KabA6QN2y7bx3wvSqiXifk (107 MB)
- v1.0.0 - refactored to pure JavaScript:
- without node_modules folder: QmNjFsiTZRMAUa9rZpXqZqivv9JLaNicwLSPHjyLB7PVDk (1 MB)
- with node_modules folder: Qma9ScApwBtuL7dpdSk7jpBFTxbqRdiR921WjyP75SU7bT (100 MB)
- v3.8.10: QmauhggzKDo9A9je5y2K6WRAp32JmGRFCw2ZFTiSnW8yot
## License
[MIT](LICENSE.md)
+6 -4
View File
@@ -9,14 +9,16 @@
"main": "src/bch-js",
"scripts": {
"test": "nyc mocha --timeout 30000 test/unit/",
"test:integration": "mocha --timeout 30000 test/integration/",
"test:integration:testnet": "mocha --timeout 30000 test/integration/testnet/",
"test:integration": "bash test/integration/test-free-tier-bchn.sh",
"test:integration:abc": "RESTURL=https://abc.fullstack.cash/v3/ IS_USING_FREE_TIER=true mocha --timeout 30000 test/integration/",
"test:integration:testnet": "IS_USING_FREE_TIER=true mocha --timeout 30000 test/integration/testnet/",
"test:integration:local": "RESTURL=http://localhost:3000/v3/ mocha --timeout 30000 test/integration",
"test:integration:local:bchn": "RESTURL=http://localhost:3000/v3/ bash test/integration/test-free-tier-bchn.sh",
"test:integration:testnet:local": "RESTURL=http://localhost:4000/v3/ mocha --timeout 30000 test/integration/testnet",
"test:integration:free": "bash test/integration/test-free-tier.sh",
"test:integration:free:bchn": "bash test/integration/test-free-tier-bchn.sh",
"test:integration:free:bchn": "IS_USING_FREE_TIER=true bash test/integration/test-free-tier-bchn.sh",
"test:integration:free:testnet": "bash test/integration/testnet/test-free-tier.sh",
"test:temp": "mocha --timeout 30000 -g '#hydrateUtxos' test/integration/",
"test:temp": "mocha --timeout 30000 -g '#Encryption' test/integration/",
"test:integration:api": "RESTURL=https://api.fullstack.cash/v3/ mocha --timeout 30000 test/integration",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"coverage:report": "nyc --reporter=html mocha --timeout 25000 test/unit/",
+71 -2
View File
@@ -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 Returns a list of unconfirmed UTXOs for an 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
@@ -4,6 +4,7 @@
To Run Test:
- Update the RESTURL for bch-api you want to test against.
- Ensure the BCHJSTOKEN environment variable is set to an empty string.
*/
const assert = require("chai").assert
@@ -31,11 +32,11 @@ describe("#anonymous rate limits", () => {
it("should throw error when rate limit exceeded", async () => {
try {
for (let i = 0; i < 5; i++) await bchjs.Control.getNetworkInfo()
for (let i = 0; i < 22; i++) await bchjs.Control.getNetworkInfo()
assert.equal(true, false, "unexpected result")
assert.fail("Unexpected result")
} catch (err) {
assert.include(err.error, "Too many requests")
}
}).timeout(5000)
}).timeout(20000)
})
+12 -14
View File
@@ -10,7 +10,7 @@
const assert = require("chai").assert
const JWT_TOKEN =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVlODhhY2YyMDIyMWMxMDAxMmFkOTQwMSIsImVtYWlsIjoiZGVtb0BkZW1vLmNvbSIsImFwaUxldmVsIjoxMCwicmF0ZUxpbWl0IjozLCJpYXQiOjE1OTA1Mjk2NzgsImV4cCI6MTU5MzEyMTY3OH0.4q5MFDCcVx0FusivJPiEIj3w8nhFG7ZV5IhJS7faUlc"
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVlODhhY2YyMDIyMWMxMDAxMmFkOTQwMSIsImVtYWlsIjoiZGVtb0BkZW1vLmNvbSIsImFwaUxldmVsIjoxMCwicmF0ZUxpbWl0IjozLCJpYXQiOjE2MDQ4NTQ2OTEsImV4cCI6MTYwNzQ0NjY5MX0.iwse0z0KDKHx9graCxcOwj6lSlfKQAb1zLhmjvygvts"
const BCHJS = require("../../../src/bch-js")
const bchjs = new BCHJS({
@@ -28,19 +28,6 @@ describe("#free rate limits", () => {
assert.property(result, "balance")
}).timeout(5000)
// it("should throw error when rate limit exceeded 3 RPM for indexer endpoints", async () => {
// const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
//
// try {
// for (let i = 0; i < 5; i++) await bchjs.Blockbook.balance(addr)
//
// assert.equal(true, false, "unexpected result")
// } catch (err) {
// // console.log(`err: `, err)
// assert.include(err.error, "Too many requests")
// }
// }).timeout(10000)
it("should allow up to 10 RPM to indexer, then throw error", async () => {
try {
const addr = "bitcoincash:qrehqueqhw629p6e57994436w730t4rzasnly00ht0"
@@ -87,4 +74,15 @@ describe("#free rate limits", () => {
assert.notInclude(err.error, 3)
}
}).timeout(20000)
it("should throw error when rate limit exceeded 20 RPM for indexer endpoints", async () => {
try {
for (let i = 0; i < 22; i++) await bchjs.Control.getNetworkInfo()
assert.fail("unexpected result")
} catch (err) {
// console.log(`err: `, err)
assert.include(err.error, "Too many requests")
}
}).timeout(20000)
})
+21 -19
View File
@@ -4,17 +4,17 @@
To Run Test:
- Update the restURL for bch-api you want to test against.
- Update the JWT_TOKEN value with a current full-node-level JWT token.
- Update the JWT_TOKEN value with a paid tier JWT token.
*/
const assert = require("chai").assert
const JWT_TOKEN =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVkYmY4MjA1YTYwODliMjliYTlhZjc1OSIsImlhdCI6MTU3MjgzMTgzOSwiZXhwIjoxNTc1NDIzODM5fQ.sFFS4AF04U2aUwmKkBIfnMQIUoygzV9UMVzzQuwctpY"
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVlODhhY2JmMDIyMWMxMDAxMmFkOTNmZiIsImVtYWlsIjoiY2hyaXMudHJvdXRuZXJAZ21haWwuY29tIiwiYXBpTGV2ZWwiOjQwLCJyYXRlTGltaXQiOjMsImlhdCI6MTYwMzIyNzEwNCwiZXhwIjoxNjA1ODE5MTA0fQ.CV36grzdD36Ht3BwZGHG4XU40CVDzMRw9Ars1x1r27M"
const BCHJS = require("../../../src/bch-js")
const bchjs = new BCHJS({
restURL: `https://api.bchjs.cash/v3/`,
restURL: `https://api.fullstack.cash/v3/`,
// restURL: `http://localhost:3000/v3/`,
apiToken: JWT_TOKEN
})
@@ -28,21 +28,22 @@ describe("#full node rate limits", () => {
assert.property(result, "balance")
}).timeout(5000)
it("should throw error when rate limit exceeded 3 RPM for indexer endpoints", async () => {
const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
// CT 11/8/20: New rate limits make this test invalid.
// it("should throw error when rate limit exceeded 20 RPM for indexer endpoints", async () => {
// const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
//
// try {
// for (let i = 0; i < 22; i++) await bchjs.Electrumx.balance(addr)
//
// assert.fail("unexpected result")
// } catch (err) {
// // console.log(`err: `, err)
// assert.include(err.error, "Too many requests")
// }
// }).timeout(10000)
try {
for (let i = 0; i < 5; i++) await bchjs.Blockbook.balance(addr)
assert.equal(true, false, "unexpected result")
} catch (err) {
// console.log(`err: `, err)
assert.include(err.error, "Too many requests")
}
}).timeout(10000)
it("should allow more than 10 RPM to full node", async () => {
for (let i = 0; i < 20; i++) {
it("should allow more than 20 RPM to full node", async () => {
for (let i = 0; i < 22; i++) {
const result = await bchjs.Control.getNetworkInfo()
if (i === 5) {
@@ -55,10 +56,11 @@ describe("#full node rate limits", () => {
assert.property(result, "version", "more than 10 calls allowed")
}
}
}).timeout(10000)
}).timeout(20000)
it("should throw error for more than 100 RPM to fullnode", async () => {
try {
console.log(`This test usually doesn't pass, because of latency.`)
for (let i = 0; i < 100; i++) await bchjs.Control.getNetworkInfo()
} catch (err) {
// console.log(`validating after 10th call`)
@@ -66,5 +68,5 @@ describe("#full node rate limits", () => {
assert.include(err.error, "Too many requests")
assert.include(err.error, 100)
}
}).timeout(30000)
}).timeout(45000)
})
+7 -7
View File
@@ -10,7 +10,7 @@
const assert = require("chai").assert
const JWT_TOKEN =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVlODhhY2JmMDIyMWMxMDAxMmFkOTNmZiIsImVtYWlsIjoiY2hyaXMudHJvdXRuZXJAZ21haWwuY29tIiwiYXBpTGV2ZWwiOjQwLCJyYXRlTGltaXQiOjMsImlhdCI6MTU5MDQzMjIxNywiZXhwIjoxNTkzMDI0MjE3fQ.R0Euhutd5FHCxLlSzjq1TYsGjI6iua_AguWIeLK2xCU"
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVlODhhY2JmMDIyMWMxMDAxMmFkOTNmZiIsImVtYWlsIjoiY2hyaXMudHJvdXRuZXJAZ21haWwuY29tIiwiYXBpTGV2ZWwiOjQwLCJyYXRlTGltaXQiOjMsImlhdCI6MTYwMzIyNzEwNCwiZXhwIjoxNjA1ODE5MTA0fQ.CV36grzdD36Ht3BwZGHG4XU40CVDzMRw9Ars1x1r27M"
const BCHJS = require("../../../src/bch-js")
const bchjs = new BCHJS({
@@ -20,8 +20,8 @@ const bchjs = new BCHJS({
})
describe("#full node rate limits", () => {
it("should allow more than 10 RPM to full node", async () => {
for (let i = 0; i < 20; i++) {
it("should allow more than 20 RPM to full node", async () => {
for (let i = 0; i < 22; i++) {
const result = await bchjs.Control.getNetworkInfo()
if (i === 5) {
@@ -34,12 +34,12 @@ describe("#full node rate limits", () => {
assert.property(result, "version", "more than 10 calls allowed")
}
}
}).timeout(30000)
}).timeout(45000)
it("should allow more than 10 RPM to an indexer", async () => {
it("should allow more than 20 RPM to an indexer", async () => {
const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
for (let i = 0; i < 20; i++) {
for (let i = 0; i < 22; i++) {
const result = await bchjs.Blockbook.balance(addr)
if (i === 5) {
@@ -52,5 +52,5 @@ describe("#full node rate limits", () => {
assert.property(result, "balance", "more than 10 calls allowed")
}
}
}).timeout(30000)
}).timeout(45000)
})
-170
View File
@@ -1,170 +0,0 @@
/*
Integration tests for the Blockbook library.
*/
const chai = require("chai")
const assert = chai.assert
const BCHJS = require("../../../src/bch-js")
const bchjs = new BCHJS()
//const axios = require("axios")
// Inspect utility used for debugging.
const util = require("util")
util.inspect.defaultOptions = {
showHidden: true,
colors: true,
depth: 3
}
describe(`#Blockbook`, () => {
describe(`#Balance`, () => {
it(`should GET balance for a single address`, async () => {
const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
const result = await bchjs.Blockbook.balance(addr)
//console.log(`result: ${util.inspect(result)}`)
assert.hasAnyKeys(result, [
"page",
"totalPages",
"itemsOnPage",
"address",
"balance",
"totalReceived",
"totalSent",
"unconfirmedBalance",
"unconfirmedTxs",
"txs",
"txids"
])
assert.isArray(result.txids)
})
it(`should POST request balances for an array of addresses`, async () => {
const addr = [
"bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf",
"bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v"
]
const result = await bchjs.Blockbook.balance(addr)
//console.log(`result: ${util.inspect(result)}`)
assert.isArray(result)
assert.hasAnyKeys(result[0], [
"page",
"totalPages",
"itemsOnPage",
"address",
"balance",
"totalReceived",
"totalSent",
"unconfirmedBalance",
"unconfirmedTxs",
"txs",
"txids"
])
assert.isArray(result[0].txids)
})
it(`should throw an error for improper input`, async () => {
try {
const addr = 12345
await bchjs.Blockbook.balance(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 throw error on array size rate limit`, async () => {
try {
const addr = []
for (let i = 0; i < 25; i++)
addr.push("bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf")
const result = await bchjs.Blockbook.balance(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")
}
})
})
describe(`#utxo`, () => {
it(`should GET utxos for a single address`, async () => {
const addr = "bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7"
const result = await bchjs.Blockbook.utxo(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.hasAnyKeys(result[0], [
"txid",
"vout",
"value",
"height",
"confirmations"
])
})
it(`should POST utxo details for an array of addresses`, async () => {
const addr = [
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
"bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr"
]
const result = await bchjs.Blockbook.utxo(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.isArray(result[0])
assert.hasAnyKeys(result[0][0], [
"txid",
"vout",
"value",
"height",
"confirmations"
])
})
it(`should throw an error for improper input`, async () => {
try {
const addr = 12345
await bchjs.Blockbook.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 throw error on array size rate limit`, async () => {
try {
const addr = []
for (let i = 0; i < 25; i++)
addr.push("bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr")
const result = await bchjs.Blockbook.utxo(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")
}
})
})
})
+3 -3
View File
@@ -1,8 +1,8 @@
#!/bin/bash
export RESTURL=https://bchn-free-main.fullstack.cash/v3/
#export RESTURL=https://bchn.fullstack.cash/v3/
#export RESTURL=http://localhost:3000/v3/
export IS_USING_FREE_TIER=true
#export IS_USING_FREE_TIER=true
cd test/integration/bchn/
mocha --timeout 30000 blockchain.js control.js electrumx.js ninsight.js openbazaar.js price.js rawtransaction.js slp.js util.js
mocha --timeout 30000 blockchain.js control.js encryption.js electrumx.js ninsight.js openbazaar.js price.js rawtransaction.js slp.js util.js
+1 -1
View File
@@ -8,7 +8,7 @@ const assert = chai.assert
const RESTURL = process.env.RESTURL
? process.env.RESTURL
: `https://tapi.fullstack.cash/v3/`
: `https://testnet3.fullstack.cash/v3/`
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
const BCHJS = require("../../../src/bch-js")
+1 -1
View File
@@ -12,7 +12,7 @@ const assert = chai.assert
const RESTURL = process.env.RESTURL
? process.env.RESTURL
: "https://tapi.fullstack.cash/v3/"
: "https://testnet3.fullstack.cash/v3/"
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
const BCHJS = require("../../../src/bch-js")
+1 -1
View File
@@ -7,7 +7,7 @@ const assert = chai.assert
const RESTURL = process.env.RESTURL
? process.env.RESTURL
: `https://tapi.fullstack.cash/v3/`
: `https://testnet3.fullstack.cash/v3/`
const BCHJS = require("../../../src/bch-js")
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
+1 -1
View File
@@ -4,7 +4,7 @@ const sinon = require("sinon")
const RESTURL = process.env.RESTURL
? process.env.RESTURL
: `https://tapi.fullstack.cash/v3/`
: `https://testnet3.fullstack.cash/v3/`
const BCHJS = require("../../../src/bch-js")
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
+1 -1
View File
@@ -10,7 +10,7 @@ const assert = chai.assert
const RESTURL = process.env.RESTURL
? process.env.RESTURL
: `https://tapi.fullstack.cash/v3/`
: `https://testnet3.fullstack.cash/v3/`
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
const BCHJS = require("../../../src/bch-js")
+1 -1
View File
@@ -7,7 +7,7 @@ const assert = chai.assert
const RESTURL = process.env.RESTURL
? process.env.RESTURL
: `https://tapi.fullstack.cash/v3/`
: `https://testnet3.fullstack.cash/v3/`
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
const BCHJS = require("../../../src/bch-js")
+1 -1
View File
@@ -8,7 +8,7 @@ const assert = chai.assert
const RESTURL = process.env.RESTURL
? process.env.RESTURL
: `https://tapi.fullstack.cash/v3/`
: `https://testnet3.fullstack.cash/v3/`
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
const BCHJS = require("../../../src/bch-js")
+22 -1
View File
@@ -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
}
+60
View File
@@ -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")
})
})
})