mirror of
https://github.com/Permissionless-Software-Foundation/bch-js.git
synced 2026-09-22 09:02:01 -07:00
Compare commits
23
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bcbd7bfd8 | ||
|
|
248b2fa2a6 | ||
|
|
563cb297fe | ||
|
|
788b07914e | ||
|
|
9aefdbf6be | ||
|
|
481c254061 | ||
|
|
bc62510b28 | ||
|
|
4c020240e1 | ||
|
|
e070409a95 | ||
|
|
fbbd855145 | ||
|
|
731987b35b | ||
|
|
1e8e7b79f2 | ||
|
|
a71192257e | ||
|
|
0fd9f9ec89 | ||
|
|
97361b8edd | ||
|
|
263ee1b6e1 | ||
|
|
099eb25e88 | ||
|
|
12a7c666c6 | ||
|
|
e482e09e77 | ||
|
|
7ca6498ca0 | ||
|
|
f89b52ac86 | ||
|
|
7990d0bffd | ||
|
|
c0eaaf77c8 |
@@ -115,7 +115,7 @@ Have questions? Need help? Join our community support
|
||||
|
||||
## IPFS Releases
|
||||
|
||||
Copies of this repository are also published on IPFS.
|
||||
Copies of this repository are also published on [IPFS](https://ipfs.io).
|
||||
|
||||
- v3.8.10: QmauhggzKDo9A9je5y2K6WRAp32JmGRFCw2ZFTiSnW8yot
|
||||
|
||||
|
||||
+3
-5
@@ -9,15 +9,13 @@
|
||||
"main": "src/bch-js",
|
||||
"scripts": {
|
||||
"test": "nyc mocha --timeout 30000 test/unit/",
|
||||
"test:integration": "bash test/integration/test-free-tier-bchn.sh",
|
||||
"test:integration": "bash test/integration/test-bchn-integration.sh",
|
||||
"test:integration:bchn": "bash test/integration/test-bchn-integration.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": "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:integration:local:testnet": "RESTURL=http://localhost:4000/v3/ mocha --timeout 30000 test/integration/testnet",
|
||||
"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",
|
||||
|
||||
@@ -11,6 +11,23 @@ class Address {
|
||||
|
||||
this.restURL = tmp.restURL
|
||||
this.apiToken = tmp.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+19
-1
@@ -55,9 +55,27 @@ class BCHJS {
|
||||
else if (process.env.BCHJSTOKEN && process.env.BCHJSTOKEN !== "")
|
||||
this.apiToken = process.env.BCHJSTOKEN
|
||||
|
||||
// Retrieve the Basic Authentication password.
|
||||
this.authPass = "" // default value.
|
||||
if (config && config.authPass && config.authPass !== "")
|
||||
this.authPass = config.authPass
|
||||
else if (process.env.BCHJSAUTHPASS && process.env.BCHJSAUTHPASS !== "")
|
||||
this.authPass = process.env.BCHJSAUTHPASS
|
||||
|
||||
// Generate a Basic Authentication token from an auth password
|
||||
this.authToken = ""
|
||||
if (this.authPass) {
|
||||
// console.log(`bch-js initialized with authPass: ${this.authPass}`)
|
||||
// Generate the header for Basic Authentication.
|
||||
const combined = `fullstackcash:${this.authPass}`
|
||||
var base64Credential = Buffer.from(combined).toString("base64")
|
||||
this.authToken = `Basic ${base64Credential}`
|
||||
}
|
||||
|
||||
const libConfig = {
|
||||
restURL: this.restURL,
|
||||
apiToken: this.apiToken
|
||||
apiToken: this.apiToken,
|
||||
authToken: this.authToken
|
||||
}
|
||||
|
||||
// console.log(`apiToken: ${this.apiToken}`)
|
||||
|
||||
+18
-243
@@ -1,6 +1,10 @@
|
||||
/*
|
||||
This library interacts with the REST API endpoints in bch-api that communicate
|
||||
with the Blockbook API.
|
||||
|
||||
CT 11/10/20
|
||||
These endpoints will be soon be deprecated. Blockbook is being fazed out in
|
||||
favor of Fulcrum.
|
||||
*/
|
||||
|
||||
const axios = require("axios")
|
||||
@@ -11,184 +15,28 @@ class Blockbook {
|
||||
constructor(config) {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
// console.log(`Blockbook apiToken: ${this.apiToken}`)
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_this = this
|
||||
}
|
||||
|
||||
/**
|
||||
* @api Blockbook.balance() balance()
|
||||
* @apiName Blockbook Balance
|
||||
* @apiGroup Blockbook
|
||||
* @apiDescription Return Balance about an address.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* (async () => {
|
||||
* try {
|
||||
* let balance = await bchjs.Blockbook.balance('bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c');
|
||||
* console.log(balance)
|
||||
* } catch(error) {
|
||||
* console.error(error)
|
||||
* }
|
||||
* })()
|
||||
*
|
||||
* //{
|
||||
* // "page": 1,
|
||||
* // "totalPages": 1,
|
||||
* // "itemsOnPage": 1000,
|
||||
* // "address": "bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c",
|
||||
* // "balance": "6000000",
|
||||
* // "totalReceived": "10185868",
|
||||
* // "totalSent": "4185868",
|
||||
* // "unconfirmedBalance": "0",
|
||||
* // "unconfirmedTxs": 0,
|
||||
* // "txs": 41,
|
||||
* // "txids": [
|
||||
* // "d31dc2cf66fe4d3d3ae18e1065def58a64920746b1702b52f060e5edeea9883b",
|
||||
* // "41e9a118765ecf7a1ba4487c0863e23dba343cc5880381a72f0365ac2546c5fa",
|
||||
* // "2f902dec880568511cefa87b9dd761563edeba9c8ba784dc9fca2f7c8c4e6f97",
|
||||
* // "eea57285462dd70dadcd431fc814857b3f81fe4d0a059a8c02c12fd7d33c02d1",
|
||||
* // "282b3b296b6aed7122586ed69f7a57d35584eaf94a4d1b1ad7d1b05d36cb79d1",
|
||||
* // "ac444896b3e32d17824fa6573eed3b89768c5c9085b7a71f3ba88e9d5ba67355",
|
||||
* // "a5f972572ee1753e2fd2457dd61ce5f40fa2f8a30173d417e49feef7542c96a1",
|
||||
* // "5165dc531aad05d1149bb0f0d9b7bda99c73e2f05e314bcfb5b4bb9ca5e1af5e",
|
||||
* // "54edaa42ff3d6559884a84ebb9bf5ef255635902f5f23b4854245d6b093d41d4",
|
||||
* // "2b0825188e909410a20a6fbdc58ff5ccf368844273f93f551222c91e6d0fa888",
|
||||
* // "7a12ea2c83d0c8a5d0f643974b0f04bc19be185c9011ed8fc33255a61d3198bb",
|
||||
* // "bd6aeeb0748251bb5dba7252ac766fb208c9909d7663c099568225d3bc998a7f",
|
||||
* // "7898bb1a8c5d933f9c2b24270522e8705b897c2f8d5b1c3477a6b952f2fe22ae",
|
||||
* // "8d35668a6838de8faa8dff5d8dedeb114bd8ffe6ae73d926264bc8328b2c46b5",
|
||||
* // "741b4692a14088438ab142cf0865fcbf3977aa7dbd2aafa9bf5f45e75e5e199a",
|
||||
* // "15f6a584080b04911121fbaca7bfcf3dd64ef2bfa5a01daf31e05a296c3e5e9e",
|
||||
* // "376de807f63253584c3edb80f92832ea90e8fdd7d8e68b2602e230d1b015e311",
|
||||
* // "eb5d0902e4a303f38223ecebb06bbf14da8a07d1ebb2d77a89dfb9e00e286c10",
|
||||
* // "11205c557af139f382c43f1f09f223cf28c64d939951fd569e5a30eee6178ccd",
|
||||
* // "ae05a78086b8d64db26d3047de3d6959a68f2a1ed3017ddf927e2c3b20a80b31",
|
||||
* // "7e0fc3cac7504d45b0f2ce68e807e592f0edf17914ab618a4cb4d93403d11c98",
|
||||
* // "1cafaacdfb85b0c33f496bf2c03c4f2ede508479bbad56ae99164dfd823a823f",
|
||||
* // "788add6a5cd961bdf7ca6145a3112462e0e51523d84a4a48047407a795433947",
|
||||
* // "49f09b616824a05eb14ae50c9fbc5d6a0c414d66a7d0b217aa75340c00ed8b85",
|
||||
* // "00f075805adf2a34563ecca33071d660a4c1e91d7d7045282c54554ee4844739",
|
||||
* // "8d048fd00cf375ba9bbea43730da1ce86fc3cb4026e1dd0e751c07fa50a652c6",
|
||||
* // "ac0e82ea84f93444602a99199dd80793f79a8ece5ac86156d2fff34f0bad44b2",
|
||||
* // "342f6815845797e0748f4716c923a0dc9b87de649b69925b36422f6d2dc23b7f",
|
||||
* // "0839a16b2411a1220c64c4d32a4c9b1e77ac5f47558921cf7c0a2adf25e0eb41",
|
||||
* // "62f42995711cb0308dac4203c5deaa2985f120559131e66aebc5164426fb6cee",
|
||||
* // "2ada093fe13c9c04da9582bb304923ce08312eaec92560b9128cdb9e93c5f52f",
|
||||
* // "e0aadd861a06993e39af932bb0b9ad69e7b37ef5843a13c6724789e1c94f3513",
|
||||
* // "925490ce60334aca204d82a61b634d89fe4cc9de429c7b6cb5ec420df3e3be5e",
|
||||
* // "60cb69f29c150378abe21d157858713f82c4e2122867597a2573474763a9e94e",
|
||||
* // "369a589173969c1c882cfb2d82b1e0ec90076ec827ff9d0f32ffc115690c93c3",
|
||||
* // "43324ef3f5fdd55b645ba14de8c0667be9b223d60b3d1dcd76cf8fdeb0fd32e4",
|
||||
* // "d2985c9b1c5c18fc2f6a963b7cb850606c4a18fcb85619057211ce3c8bcec696",
|
||||
* // "dded59fe377517e52918deae8912a096658ebf5ae61992d39953c8bc3932a11b",
|
||||
* // "2dc053f55a666a3d2a08b1c680b704d62a55506d14ad884add87edcc56b9277d",
|
||||
* // "544c15ce35c0f2e808d28f29d6587f1ec9276233e29856b7f2938cf0daef0026",
|
||||
* // "81039b1d7b855b133f359f9dc65f776bd105650153a941675fedc504228ddbd3"
|
||||
* // ]
|
||||
* //}
|
||||
*
|
||||
*(async () => {
|
||||
* try {
|
||||
* let balance = await bchjs.Blockbook.balance(['bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c','1BFHGm4HzqgXXyNX8n7DsQno5DAC4iLMRA']);
|
||||
* console.log(balance)
|
||||
* } catch(error) {
|
||||
* console.error(error)
|
||||
* }
|
||||
* })()
|
||||
*
|
||||
* //[
|
||||
* // {
|
||||
* // "page": 1,
|
||||
* // "totalPages": 1,
|
||||
* // "itemsOnPage": 1000,
|
||||
* // "address": "bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c",
|
||||
* // "balance": "6000000",
|
||||
* // "totalReceived": "10185868",
|
||||
* // "totalSent": "4185868",
|
||||
* // "unconfirmedBalance": "0",
|
||||
* // "unconfirmedTxs": 0,
|
||||
* // "txs": 41,
|
||||
* // "txids": [
|
||||
* // "d31dc2cf66fe4d3d3ae18e1065def58a64920746b1702b52f060e5edeea9883b",
|
||||
* // "41e9a118765ecf7a1ba4487c0863e23dba343cc5880381a72f0365ac2546c5fa",
|
||||
* // "2f902dec880568511cefa87b9dd761563edeba9c8ba784dc9fca2f7c8c4e6f97",
|
||||
* // "eea57285462dd70dadcd431fc814857b3f81fe4d0a059a8c02c12fd7d33c02d1",
|
||||
* // "282b3b296b6aed7122586ed69f7a57d35584eaf94a4d1b1ad7d1b05d36cb79d1",
|
||||
* // "ac444896b3e32d17824fa6573eed3b89768c5c9085b7a71f3ba88e9d5ba67355",
|
||||
* // "a5f972572ee1753e2fd2457dd61ce5f40fa2f8a30173d417e49feef7542c96a1",
|
||||
* // "5165dc531aad05d1149bb0f0d9b7bda99c73e2f05e314bcfb5b4bb9ca5e1af5e",
|
||||
* // "54edaa42ff3d6559884a84ebb9bf5ef255635902f5f23b4854245d6b093d41d4",
|
||||
* // "2b0825188e909410a20a6fbdc58ff5ccf368844273f93f551222c91e6d0fa888",
|
||||
* // "7a12ea2c83d0c8a5d0f643974b0f04bc19be185c9011ed8fc33255a61d3198bb",
|
||||
* // "bd6aeeb0748251bb5dba7252ac766fb208c9909d7663c099568225d3bc998a7f",
|
||||
* // "7898bb1a8c5d933f9c2b24270522e8705b897c2f8d5b1c3477a6b952f2fe22ae",
|
||||
* // "8d35668a6838de8faa8dff5d8dedeb114bd8ffe6ae73d926264bc8328b2c46b5",
|
||||
* // "741b4692a14088438ab142cf0865fcbf3977aa7dbd2aafa9bf5f45e75e5e199a",
|
||||
* // "15f6a584080b04911121fbaca7bfcf3dd64ef2bfa5a01daf31e05a296c3e5e9e",
|
||||
* // "376de807f63253584c3edb80f92832ea90e8fdd7d8e68b2602e230d1b015e311",
|
||||
* // "eb5d0902e4a303f38223ecebb06bbf14da8a07d1ebb2d77a89dfb9e00e286c10",
|
||||
* // "11205c557af139f382c43f1f09f223cf28c64d939951fd569e5a30eee6178ccd",
|
||||
* // "ae05a78086b8d64db26d3047de3d6959a68f2a1ed3017ddf927e2c3b20a80b31",
|
||||
* // "7e0fc3cac7504d45b0f2ce68e807e592f0edf17914ab618a4cb4d93403d11c98",
|
||||
* // "1cafaacdfb85b0c33f496bf2c03c4f2ede508479bbad56ae99164dfd823a823f",
|
||||
* // "788add6a5cd961bdf7ca6145a3112462e0e51523d84a4a48047407a795433947",
|
||||
* // "49f09b616824a05eb14ae50c9fbc5d6a0c414d66a7d0b217aa75340c00ed8b85",
|
||||
* // "00f075805adf2a34563ecca33071d660a4c1e91d7d7045282c54554ee4844739",
|
||||
* // "8d048fd00cf375ba9bbea43730da1ce86fc3cb4026e1dd0e751c07fa50a652c6",
|
||||
* // "ac0e82ea84f93444602a99199dd80793f79a8ece5ac86156d2fff34f0bad44b2",
|
||||
* // "342f6815845797e0748f4716c923a0dc9b87de649b69925b36422f6d2dc23b7f",
|
||||
* // "0839a16b2411a1220c64c4d32a4c9b1e77ac5f47558921cf7c0a2adf25e0eb41",
|
||||
* // "62f42995711cb0308dac4203c5deaa2985f120559131e66aebc5164426fb6cee",
|
||||
* // "2ada093fe13c9c04da9582bb304923ce08312eaec92560b9128cdb9e93c5f52f",
|
||||
* // "e0aadd861a06993e39af932bb0b9ad69e7b37ef5843a13c6724789e1c94f3513",
|
||||
* // "925490ce60334aca204d82a61b634d89fe4cc9de429c7b6cb5ec420df3e3be5e",
|
||||
* // "60cb69f29c150378abe21d157858713f82c4e2122867597a2573474763a9e94e",
|
||||
* // "369a589173969c1c882cfb2d82b1e0ec90076ec827ff9d0f32ffc115690c93c3",
|
||||
* // "43324ef3f5fdd55b645ba14de8c0667be9b223d60b3d1dcd76cf8fdeb0fd32e4",
|
||||
* // "d2985c9b1c5c18fc2f6a963b7cb850606c4a18fcb85619057211ce3c8bcec696",
|
||||
* // "dded59fe377517e52918deae8912a096658ebf5ae61992d39953c8bc3932a11b",
|
||||
* // "2dc053f55a666a3d2a08b1c680b704d62a55506d14ad884add87edcc56b9277d",
|
||||
* // "544c15ce35c0f2e808d28f29d6587f1ec9276233e29856b7f2938cf0daef0026",
|
||||
* // "81039b1d7b855b133f359f9dc65f776bd105650153a941675fedc504228ddbd3"
|
||||
* // ]
|
||||
* // },
|
||||
* // {
|
||||
* // "page": 1,
|
||||
* // "totalPages": 1,
|
||||
* // "itemsOnPage": 1000,
|
||||
* // "address": "bitcoincash:qpcxf2sv9hjw08nvpgffpamfus9nmksm3chv5zqtnz",
|
||||
* // "balance": "0",
|
||||
* // "totalReceived": "36781097",
|
||||
* // "totalSent": "36781097",
|
||||
* // "unconfirmedBalance": "0",
|
||||
* // "unconfirmedTxs": 0,
|
||||
* // "txs": 11,
|
||||
* // "txids": [
|
||||
* // "11205c557af139f382c43f1f09f223cf28c64d939951fd569e5a30eee6178ccd",
|
||||
* // "ae05a78086b8d64db26d3047de3d6959a68f2a1ed3017ddf927e2c3b20a80b31",
|
||||
* // "7e0fc3cac7504d45b0f2ce68e807e592f0edf17914ab618a4cb4d93403d11c98",
|
||||
* // "60cb69f29c150378abe21d157858713f82c4e2122867597a2573474763a9e94e",
|
||||
* // "f737485aaee3c10b13013fa109bb6294b099246134ca9885f4cc332dbc6c9bb4",
|
||||
* // "decd5b9c0c959e4e543182093e8f7f8bc7a6ecd96a8a062daaeff3667f8feca7",
|
||||
* // "94e69a627a34ae27fca81d15fff4323a7ce1f7c275c7485762ce018221017632",
|
||||
* // "e67c70787af7f3506263c9eda007f3d2d24bd750ff95b5c50a120d9118dfd807",
|
||||
* // "8e5e00704a147d54028f94d52df7730e821b9c6cd4bd29494e5636f49c199d6a",
|
||||
* // "15102827c108566ea5daf725c09079c1a3f42ef99d1eb68ea8c584f7b16ab87a",
|
||||
* // "cc27be8846276612dfce5924b7be96556212f0f0e62bd17641732175edb9911e"
|
||||
* // ]
|
||||
* // }
|
||||
* //
|
||||
*
|
||||
*/
|
||||
|
||||
async balance(address) {
|
||||
try {
|
||||
// Handle single address.
|
||||
@@ -220,62 +68,6 @@ class Blockbook {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api Blockbook.utxo() utxo()
|
||||
* @apiName Blockbook Utxo
|
||||
* @apiGroup Blockbook
|
||||
* @apiDescription Return list of uxto for address.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* (async () => {
|
||||
* try {
|
||||
* let utxo = await bchjs.Blockbook.utxo('bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf');
|
||||
* console.log(utxo);
|
||||
* } catch(error) {
|
||||
* console.error(error)
|
||||
* }
|
||||
* })()
|
||||
*
|
||||
* [{
|
||||
* "txid": "7774e449c5a3065144cefbc4c0c21e6b69c987f095856778ef9f45ddd8ae1a41",
|
||||
* "vout": 0,
|
||||
* "value": "1000",
|
||||
* "height": 604392,
|
||||
* "confirmations": 25530,
|
||||
* "satoshis": 1000
|
||||
* }]
|
||||
*
|
||||
*
|
||||
* (async () => {
|
||||
* try {
|
||||
* let utxo = await bchjs.Blockbook.utxo([
|
||||
* "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf",
|
||||
* "bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c"
|
||||
* ]);
|
||||
* console.log(utxo);
|
||||
* } catch(error) {
|
||||
* console.error(error)
|
||||
* }
|
||||
* })()
|
||||
*
|
||||
* [
|
||||
* [{
|
||||
* "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 {
|
||||
// Handle single address.
|
||||
@@ -306,23 +98,6 @@ class Blockbook {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api Blockbook.tx() tx()
|
||||
* @apiName Blockbook Tx
|
||||
* @apiGroup Blockbook
|
||||
* @apiDescription Get details on a transaction.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* (async () => {
|
||||
* try {
|
||||
* let txDetails = await bchjs.Blockbook.tx(`5fe9b74056319a8c87f45cc745030715a6180758b94938dbf90d639d55652392`);
|
||||
* console.log(txDetails);
|
||||
* } catch(error) {
|
||||
* console.error(error)
|
||||
* }
|
||||
* })()
|
||||
*
|
||||
*/
|
||||
async tx(txid) {
|
||||
try {
|
||||
// Handle single txid.
|
||||
|
||||
+14
-4
@@ -11,11 +11,21 @@ class Blockchain {
|
||||
constructor(config) {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-4
@@ -10,11 +10,21 @@ class Control {
|
||||
constructor(config) {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-5
@@ -11,12 +11,21 @@ class ElectrumX {
|
||||
constructor(config) {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`,
|
||||
timeout: 15000
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-5
@@ -11,12 +11,21 @@ class Encryption {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.axios = axios
|
||||
// console.log(`Blockbook apiToken: ${this.apiToken}`)
|
||||
this.authToken = config.authToken
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-4
@@ -6,11 +6,21 @@ class Generating {
|
||||
constructor(config) {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-4
@@ -6,11 +6,21 @@ class Mining {
|
||||
constructor(config) {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+136
-61
@@ -68,34 +68,10 @@ class Ninsight {
|
||||
*/
|
||||
async utxo(address) {
|
||||
try {
|
||||
// Handle single address.
|
||||
if (typeof address === "string") {
|
||||
const response = await axios.post(
|
||||
`${this.ninsightURL}/address/utxo`,
|
||||
{
|
||||
addresses: [address]
|
||||
},
|
||||
_this.axiosOptions
|
||||
)
|
||||
return response.data
|
||||
|
||||
// Handle array of addresses.
|
||||
} else if (Array.isArray(address)) {
|
||||
const response = await axios.post(
|
||||
`${this.ninsightURL}/address/utxo`,
|
||||
{
|
||||
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
|
||||
_this._validateParam(address)
|
||||
return _this._callAxios(address, 'utxo')
|
||||
} catch (e) {
|
||||
_this._handleError(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,32 +113,10 @@ class Ninsight {
|
||||
*/
|
||||
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
|
||||
_this._validateParam(address)
|
||||
return _this._callAxios(address, 'unconfirmed')
|
||||
} catch (e) {
|
||||
_this._handleError(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,21 +167,72 @@ class Ninsight {
|
||||
*/
|
||||
async transactions(address) {
|
||||
try {
|
||||
if (typeof address === "string") {
|
||||
_this._validateParam(address)
|
||||
return _this._callAxios(address, 'transactions')
|
||||
} catch (e) {
|
||||
_this._handleError(e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api Ninsight.txDetails() txDetails()
|
||||
* @apiName Ninsight TX Details
|
||||
* @apiGroup Ninsight
|
||||
* @apiDescription Return transactions details for address(es).
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* (async () => {
|
||||
* try {
|
||||
* let result = await bchjs.Ninsight.txDetails('fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33');
|
||||
* console.log(result);
|
||||
* } catch(error) {
|
||||
* console.error(error)
|
||||
* }
|
||||
* })()
|
||||
*
|
||||
* // [
|
||||
* // {
|
||||
* // "txid": "fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33",
|
||||
* // "version": 1,
|
||||
* // "locktime": 0,
|
||||
* // "vin": [
|
||||
* // {
|
||||
* // "sequence": 4294967295,
|
||||
* // "n": 0
|
||||
* // }
|
||||
* // ],
|
||||
* // "vout": [
|
||||
* // ...
|
||||
* // ],
|
||||
* // "blockhash": "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09",
|
||||
* // "blockheight": 1000,
|
||||
* // "confirmations": 659909,
|
||||
* // "time": 1232346882,
|
||||
* // "blocktime": 1232346882,
|
||||
* // "firstSeenTime": null,
|
||||
* // "valueOut": 50,
|
||||
* // "size": 135
|
||||
* // }
|
||||
* // ]
|
||||
*
|
||||
*/
|
||||
async txDetails(txid) {
|
||||
try {
|
||||
if (typeof txid === "string") {
|
||||
const response = await axios.post(
|
||||
`${this.ninsightURL}/address/transactions`,
|
||||
`${_this.ninsightURL}/transaction/details`,
|
||||
{
|
||||
addresses: [address]
|
||||
txids: [txid]
|
||||
},
|
||||
_this.axiosOptions
|
||||
)
|
||||
|
||||
return response.data
|
||||
} else if (Array.isArray(address)) {
|
||||
} else if (Array.isArray(txid)) {
|
||||
const response = await axios.post(
|
||||
`${this.ninsightURL}/address/transactions`,
|
||||
`${_this.ninsightURL}/transaction/details`,
|
||||
{
|
||||
addresses: address
|
||||
txids: txid
|
||||
},
|
||||
_this.axiosOptions
|
||||
)
|
||||
@@ -235,12 +240,82 @@ class Ninsight {
|
||||
return response.data
|
||||
}
|
||||
|
||||
throw new Error(`Input address must be a string or array of strings.`)
|
||||
throw new Error(`Transaction ID must be a string or array of strings.`)
|
||||
} catch (error) {
|
||||
if (error.response && error.response.data) throw error.response.data
|
||||
else throw error
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @api Ninsight.details() details()
|
||||
* @apiName Ninsight Details
|
||||
* @apiGroup Ninsight
|
||||
* @apiDescription Return details of address.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* (async () => {
|
||||
* try {
|
||||
* let details = await bchjs.Ninsight.details('bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c');
|
||||
* let details = await bchjs.Ninsight.details(['bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c','bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c']);
|
||||
* console.log(details);
|
||||
* } catch(error) {
|
||||
* console.error(error)
|
||||
* }
|
||||
* })()
|
||||
*
|
||||
* // [
|
||||
* // {
|
||||
* //"balance": 0.00001,
|
||||
* //"balanceSat": 1000,
|
||||
* //"totalReceived": 0.00001,
|
||||
* //"totalReceivedSat": 1000,
|
||||
* //"totalSent": 0,
|
||||
* //"totalSentSat": 0,
|
||||
* //"unconfirmedBalance": 0,
|
||||
* //"unconfirmedBalanceSat": 0,
|
||||
* //"unconfirmedTxApperances": 0,
|
||||
* //"txApperances": 1,
|
||||
* //"transactions": [
|
||||
* //"5f09d317e24c5d376f737a2711f3bd1d381abdb41743fff3819b4f76382e1eac" ],
|
||||
* //"legacyAddress": "1FZrK8HohEKyKCTM24NkAzPnX9WD9Ujhw7",
|
||||
* //"cashAddress": "bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr",
|
||||
* //"slpAddress": "simpleledger:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ylynt40sa",
|
||||
* //"currentPage": 0,
|
||||
* //"pagesTotal": 1
|
||||
* // }
|
||||
* // ]
|
||||
*
|
||||
*/
|
||||
async details(address) {
|
||||
try {
|
||||
_this._validateParam(address)
|
||||
return _this._callAxios(address, 'details')
|
||||
} catch (e) {
|
||||
_this._handleError(e)
|
||||
}
|
||||
}
|
||||
|
||||
_validateParam(address) {
|
||||
if (typeof address !== "string" && !Array.isArray(address))
|
||||
throw new Error(`Input address must be a string or array of strings.`)
|
||||
}
|
||||
|
||||
_handleError(error) {
|
||||
if (error.response && error.response.data) throw error.response.data
|
||||
else throw error
|
||||
}
|
||||
|
||||
async _callAxios(address, type) {
|
||||
const response = await axios.post(
|
||||
`${_this.ninsightURL}/address/${type}`,
|
||||
{
|
||||
addresses: Array.isArray(address) ? address : [address]
|
||||
},
|
||||
_this.axiosOptions
|
||||
)
|
||||
//console.log(`SAMPLE: ${response.data}`);
|
||||
return response.data
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Ninsight
|
||||
|
||||
+16
-8
@@ -6,15 +6,23 @@ class Price {
|
||||
constructor(config) {
|
||||
_this = this
|
||||
|
||||
if (config) {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
}
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-10
@@ -6,11 +6,21 @@ class RawTransactions {
|
||||
constructor(config) {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,9 +272,7 @@ class RawTransactions {
|
||||
txids: txid,
|
||||
verbose: verbose
|
||||
},
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
headers: _this.axiosOptions.headers
|
||||
}
|
||||
const response = await axios(options)
|
||||
|
||||
@@ -337,9 +345,7 @@ class RawTransactions {
|
||||
data: {
|
||||
hexes: hex
|
||||
},
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
headers: _this.axiosOptions.headers
|
||||
}
|
||||
const response = await axios(options)
|
||||
|
||||
|
||||
+14
-4
@@ -4,11 +4,21 @@ class Schnorr {
|
||||
constructor(config) {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-11
@@ -18,22 +18,31 @@ const Utils = require("./utils")
|
||||
// SLP is a superset of BITBOX
|
||||
class SLP {
|
||||
constructor(config) {
|
||||
const tmp = {}
|
||||
if (!config || !config.restURL) {
|
||||
tmp.restURL = `https://api.fullstack.cash/v3/`
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tmp.restURL = config.restURL
|
||||
tmp.apiToken = config.apiToken
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.restURL = tmp.restURL
|
||||
this.apiToken = tmp.apiToken
|
||||
|
||||
this.Address = new Address(tmp)
|
||||
this.Address = new Address(config)
|
||||
this.ECPair = ECPair
|
||||
this.TokenType1 = new TokenType1(tmp)
|
||||
this.TokenType1 = new TokenType1(config)
|
||||
this.NFT1 = new NFT1(this.restURL)
|
||||
this.Utils = new Utils(tmp)
|
||||
this.Utils = new Utils(config)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-6
@@ -18,17 +18,28 @@ class TokenType1 {
|
||||
constructor(config) {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addy = new Address(config)
|
||||
this.Script = new Script()
|
||||
|
||||
this.axios = axios
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate the transaction builder.
|
||||
TransactionBuilder.setAddress(addy)
|
||||
|
||||
+14
-4
@@ -13,11 +13,21 @@ class Utils {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.slpParser = slpParser
|
||||
this.authToken = config.authToken
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-4
@@ -6,11 +6,21 @@ class Util {
|
||||
constructor(config) {
|
||||
this.restURL = config.restURL
|
||||
this.apiToken = config.apiToken
|
||||
this.authToken = config.authToken
|
||||
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
if (this.authToken) {
|
||||
// Add Basic Authentication token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: this.authToken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add JWT token to the authorization header.
|
||||
this.axiosOptions = {
|
||||
headers: {
|
||||
authorization: `Token ${this.apiToken}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,17 @@
|
||||
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.
|
||||
- If working with bch-api locally, eliminate the local IP address from the
|
||||
whitelist in bch-api/src/middleware/route-ratelimit.js
|
||||
|
||||
Run this test with this command:
|
||||
mocha --timeout=30000 anonymous-rate-limits.js
|
||||
*/
|
||||
|
||||
const assert = require("chai").assert
|
||||
|
||||
const RESTURL = `https://api.fullstack.cash/v3/`
|
||||
// const RESTURL = `https://abc.fullstack.cash/v3/`
|
||||
const RESTURL = `https://bchn.fullstack.cash/v3/`
|
||||
// const RESTURL = `http://localhost:3000/v3/`
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
@@ -24,7 +30,7 @@ describe("#anonymous rate limits", () => {
|
||||
|
||||
it("should allow an anonymous call to an indexer", async () => {
|
||||
const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
|
||||
const result = await bchjs.Blockbook.balance(addr)
|
||||
const result = await bchjs.Electrumx.balance(addr)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.property(result, "balance")
|
||||
@@ -32,7 +38,7 @@ describe("#anonymous rate limits", () => {
|
||||
|
||||
it("should throw error when rate limit exceeded", async () => {
|
||||
try {
|
||||
for (let i = 0; i < 22; i++) await bchjs.Control.getNetworkInfo()
|
||||
for (let i = 0; i < 35; i++) await bchjs.Control.getNetworkInfo()
|
||||
|
||||
assert.fail("Unexpected result")
|
||||
} catch (err) {
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Mocha test that verifies that the bch-api server is enforcing its
|
||||
access rules for Basic Authentication.
|
||||
|
||||
To Run Test:
|
||||
- Update the restURL for bch-api you want to test against.
|
||||
- Update the PRO_PASS value with a current PRO_PASSES string used by bch-api.
|
||||
*/
|
||||
|
||||
const assert = require("chai").assert
|
||||
|
||||
const PRO_PASS = "testpassword"
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
const bchjs = new BCHJS({
|
||||
// restURL: `https://bchn.fullstack.cash/v3/`,
|
||||
restURL: `https://abc.fullstack.cash/v3/`,
|
||||
// restURL: `http://localhost:3000/v3/`,
|
||||
authPass: PRO_PASS
|
||||
})
|
||||
|
||||
describe("#Basic Authentication rate limits", () => {
|
||||
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) {
|
||||
// console.log(`validating 5th call: ${i}`)
|
||||
assert.property(result, "version", "more than 3 calls allowed")
|
||||
}
|
||||
|
||||
if (i === 15) {
|
||||
// console.log(`validating 5th call: ${i}`)
|
||||
assert.property(result, "version", "more than 10 calls allowed")
|
||||
}
|
||||
}
|
||||
}).timeout(45000)
|
||||
|
||||
it("should allow more than 20 RPM to an indexer", async () => {
|
||||
const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
|
||||
|
||||
for (let i = 0; i < 22; i++) {
|
||||
const result = await bchjs.Blockbook.balance(addr)
|
||||
|
||||
if (i === 5) {
|
||||
// console.log(`validating 5th call: ${i}`)
|
||||
assert.property(result, "balance", "more than 3 calls allowed")
|
||||
}
|
||||
|
||||
if (i === 15) {
|
||||
// console.log(`validating 5th call: ${i}`)
|
||||
assert.property(result, "balance", "more than 10 calls allowed")
|
||||
}
|
||||
}
|
||||
}).timeout(45000)
|
||||
})
|
||||
@@ -1,4 +1,8 @@
|
||||
/*
|
||||
CT 11/11/2020:
|
||||
There is no longer a free tier. These tests have been deprecated.
|
||||
|
||||
--------
|
||||
Mocha test that verifies that the bch-api server is enforcing its
|
||||
FREE access rules
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
/*
|
||||
CT 11/11/2020:
|
||||
There is no longer a free tier. These tests have been deprecated.
|
||||
|
||||
----
|
||||
Mocha test that verifies that the bch-api server is enforcing its
|
||||
full-node access rules
|
||||
|
||||
@@ -14,7 +18,8 @@ const JWT_TOKEN =
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
const bchjs = new BCHJS({
|
||||
restURL: `https://api.fullstack.cash/v3/`,
|
||||
// restURL: `https://bchn.fullstack.cash/v3/`,
|
||||
restURL: `https:/abc.fullstack.cash/v3/`,
|
||||
// restURL: `http://localhost:3000/v3/`,
|
||||
apiToken: JWT_TOKEN
|
||||
})
|
||||
@@ -22,7 +27,7 @@ const bchjs = new BCHJS({
|
||||
describe("#full node rate limits", () => {
|
||||
it("should allow an free call to an indexer", async () => {
|
||||
const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
|
||||
const result = await bchjs.Blockbook.balance(addr)
|
||||
const result = await bchjs.Electrumx.balance(addr)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.property(result, "balance")
|
||||
|
||||
@@ -14,12 +14,13 @@ const JWT_TOKEN =
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
const bchjs = new BCHJS({
|
||||
restURL: `https://api.fullstack.cash/v3/`,
|
||||
// restURL: `https://bchn.fullstack.cash/v3/`,
|
||||
restURL: `https://abc.fullstack.cash/v3/`,
|
||||
// restURL: `http://localhost:3000/v3/`,
|
||||
apiToken: JWT_TOKEN
|
||||
})
|
||||
|
||||
describe("#full node rate limits", () => {
|
||||
describe("#Indexer rate limits", () => {
|
||||
it("should allow more than 20 RPM to full node", async () => {
|
||||
for (let i = 0; i < 22; i++) {
|
||||
const result = await bchjs.Control.getNetworkInfo()
|
||||
@@ -40,7 +41,7 @@ describe("#full node rate limits", () => {
|
||||
const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
|
||||
|
||||
for (let i = 0; i < 22; i++) {
|
||||
const result = await bchjs.Blockbook.balance(addr)
|
||||
const result = await bchjs.Electrumx.balance(addr)
|
||||
|
||||
if (i === 5) {
|
||||
// console.log(`validating 5th call: ${i}`)
|
||||
|
||||
@@ -89,4 +89,128 @@ describe(`#Ninsight`, () => {
|
||||
assert.property(result[0].txs[0], "vout")
|
||||
})
|
||||
})
|
||||
describe(`#txDetails`, () => {
|
||||
it(`should POST transactions details for a single address`, async () => {
|
||||
const txid = "fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33"
|
||||
|
||||
const result = await bchjs.Ninsight.txDetails(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "txid")
|
||||
assert.property(result[0], "version")
|
||||
assert.property(result[0], "locktime")
|
||||
assert.property(result[0], "vin")
|
||||
assert.property(result[0], "vout")
|
||||
assert.property(result[0], "blockhash")
|
||||
assert.property(result[0], "blockheight")
|
||||
assert.property(result[0], "confirmations")
|
||||
assert.property(result[0], "time")
|
||||
assert.property(result[0], "blocktime")
|
||||
assert.property(result[0], "isCoinBase")
|
||||
assert.property(result[0], "valueOut")
|
||||
assert.property(result[0], "size")
|
||||
})
|
||||
it(`should POST transactions details for an array of addresses`, async () => {
|
||||
const txid = [
|
||||
"fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33",
|
||||
"4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251"
|
||||
]
|
||||
|
||||
const result = await bchjs.Ninsight.txDetails(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "txid")
|
||||
assert.property(result[0], "vin")
|
||||
assert.property(result[0], "vout")
|
||||
})
|
||||
})
|
||||
|
||||
describe(`#detailsAddress`, () => {
|
||||
it(`should throw an error for improper input`, async () => {
|
||||
try {
|
||||
const addr = 12345
|
||||
|
||||
await bchjs.Ninsight.details(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 POST address details for a single address`, async () => {
|
||||
const addr = "bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7"
|
||||
|
||||
const result = await bchjs.Ninsight.details(addr)
|
||||
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "balance")
|
||||
assert.property(result[0], "balanceSat")
|
||||
assert.property(result[0], "totalReceived")
|
||||
assert.property(result[0], "totalReceivedSat")
|
||||
assert.property(result[0], "totalSent")
|
||||
assert.property(result[0], "totalSentSat")
|
||||
assert.property(result[0], "unconfirmedBalance")
|
||||
assert.property(result[0], "unconfirmedBalanceSat")
|
||||
assert.property(result[0], "unconfirmedTxApperances")
|
||||
assert.property(result[0], "txApperances")
|
||||
assert.property(result[0], "transactions")
|
||||
assert.property(result[0], "legacyAddress")
|
||||
assert.property(result[0], "cashAddress")
|
||||
assert.property(result[0], "slpAddress")
|
||||
assert.property(result[0], "currentPage")
|
||||
assert.property(result[0], "pagesTotal")
|
||||
})
|
||||
|
||||
it(`should POST address details for an array of addresses`, async () => {
|
||||
const addr = [
|
||||
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
|
||||
"bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr"
|
||||
]
|
||||
|
||||
const result = await bchjs.Ninsight.details(addr)
|
||||
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "balance")
|
||||
assert.property(result[0], "balanceSat")
|
||||
assert.property(result[0], "totalReceived")
|
||||
assert.property(result[0], "totalReceivedSat")
|
||||
assert.property(result[0], "totalSent")
|
||||
assert.property(result[0], "totalSentSat")
|
||||
assert.property(result[0], "unconfirmedBalance")
|
||||
assert.property(result[0], "unconfirmedBalanceSat")
|
||||
assert.property(result[0], "unconfirmedTxApperances")
|
||||
assert.property(result[0], "txApperances")
|
||||
assert.property(result[0], "transactions")
|
||||
assert.property(result[0], "legacyAddress")
|
||||
assert.property(result[1], "cashAddress")
|
||||
assert.property(result[1], "slpAddress")
|
||||
assert.property(result[1], "currentPage")
|
||||
assert.property(result[1], "pagesTotal")
|
||||
|
||||
/*
|
||||
If in any way possible, I would like to refactor this test
|
||||
according to the DRY principle to share it with the integration tests too
|
||||
Would that make sense or does that implicate anything unwanted?
|
||||
|
||||
assertDetails(result[0])
|
||||
|
||||
assertDetails(data) {
|
||||
assert.property(data, "balance")
|
||||
assert.property(data, "balanceSat")
|
||||
assert.property(data, "totalReceived")
|
||||
assert.property(data, "totalReceivedSat")
|
||||
assert.property(data, "totalSent")
|
||||
assert.property(data, "totalSentSat")
|
||||
}
|
||||
*/
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,7 +3,9 @@ const assert = chai.assert
|
||||
const sinon = require("sinon")
|
||||
|
||||
const BCHJS = require("../../src/bch-js")
|
||||
const bchjs = new BCHJS({ ninsightURL: "https://rest.bitcoin.com/v2" })
|
||||
const bchjs = new BCHJS({
|
||||
ninsightURL: "https://rest.bitcoin.com/v2"
|
||||
})
|
||||
|
||||
describe(`#Ninsight`, () => {
|
||||
let sandbox
|
||||
@@ -95,6 +97,127 @@ describe(`#Ninsight`, () => {
|
||||
assert.property(result[0].txs[0], "vout")
|
||||
})
|
||||
})
|
||||
describe(`#txDetails`, () => {
|
||||
it(`should POST transactions details for a single address`, async () => {
|
||||
const txid = "fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33"
|
||||
|
||||
const result = await bchjs.Ninsight.txDetails(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "txid")
|
||||
assert.property(result[0], "version")
|
||||
assert.property(result[0], "locktime")
|
||||
assert.property(result[0], "vin")
|
||||
assert.property(result[0], "vout")
|
||||
assert.property(result[0], "blockhash")
|
||||
assert.property(result[0], "blockheight")
|
||||
assert.property(result[0], "confirmations")
|
||||
assert.property(result[0], "time")
|
||||
assert.property(result[0], "blocktime")
|
||||
assert.property(result[0], "valueOut")
|
||||
assert.property(result[0], "size")
|
||||
})
|
||||
it(`should POST transactions details for an array of addresses`, async () => {
|
||||
const txid = [
|
||||
"fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33",
|
||||
"4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251"
|
||||
]
|
||||
|
||||
const result = await bchjs.Ninsight.txDetails(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "txid")
|
||||
assert.property(result[0], "vin")
|
||||
assert.property(result[0], "vout")
|
||||
})
|
||||
})
|
||||
describe(`#detailsAddress`, () => {
|
||||
it(`should throw an error for improper input`, async () => {
|
||||
try {
|
||||
const addr = 12345
|
||||
|
||||
await bchjs.Ninsight.details(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 POST address details for a single address`, async () => {
|
||||
const addr = "bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7"
|
||||
|
||||
const result = await bchjs.Ninsight.details(addr)
|
||||
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "balance")
|
||||
assert.property(result[0], "balanceSat")
|
||||
assert.property(result[0], "totalReceived")
|
||||
assert.property(result[0], "totalReceivedSat")
|
||||
assert.property(result[0], "totalSent")
|
||||
assert.property(result[0], "totalSentSat")
|
||||
assert.property(result[0], "unconfirmedBalance")
|
||||
assert.property(result[0], "unconfirmedBalanceSat")
|
||||
assert.property(result[0], "unconfirmedTxApperances")
|
||||
assert.property(result[0], "txApperances")
|
||||
assert.property(result[0], "transactions")
|
||||
assert.property(result[0], "legacyAddress")
|
||||
assert.property(result[0], "cashAddress")
|
||||
assert.property(result[0], "slpAddress")
|
||||
assert.property(result[0], "currentPage")
|
||||
assert.property(result[0], "pagesTotal")
|
||||
})
|
||||
|
||||
it(`should POST address details for an array of addresses`, async () => {
|
||||
const addr = [
|
||||
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
|
||||
"bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr"
|
||||
]
|
||||
|
||||
const result = await bchjs.Ninsight.details(addr)
|
||||
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "balance")
|
||||
assert.property(result[0], "balanceSat")
|
||||
assert.property(result[0], "totalReceived")
|
||||
assert.property(result[0], "totalReceivedSat")
|
||||
assert.property(result[0], "totalSent")
|
||||
assert.property(result[0], "totalSentSat")
|
||||
assert.property(result[0], "unconfirmedBalance")
|
||||
assert.property(result[0], "unconfirmedBalanceSat")
|
||||
assert.property(result[0], "unconfirmedTxApperances")
|
||||
assert.property(result[0], "txApperances")
|
||||
assert.property(result[0], "transactions")
|
||||
assert.property(result[0], "legacyAddress")
|
||||
assert.property(result[1], "cashAddress")
|
||||
assert.property(result[1], "slpAddress")
|
||||
assert.property(result[1], "currentPage")
|
||||
assert.property(result[1], "pagesTotal")
|
||||
|
||||
/*
|
||||
If in any way possible, I would like to refactor this test
|
||||
according to the DRY principle to share it with the integration tests too
|
||||
Would that make sense or does that implicate anything unwanted?
|
||||
|
||||
assertDetails(result[0])
|
||||
|
||||
assertDetails(data) {
|
||||
assert.property(data, "balance")
|
||||
assert.property(data, "balanceSat")
|
||||
assert.property(data, "totalReceived")
|
||||
assert.property(data, "totalReceivedSat")
|
||||
assert.property(data, "totalSent")
|
||||
assert.property(data, "totalSentSat")
|
||||
}
|
||||
*/
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function sleep(ms) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
#export RESTURL=https://bchn.fullstack.cash/v3/
|
||||
export RESTURL=https://bchn.fullstack.cash/v3/
|
||||
#export RESTURL=http://localhost:3000/v3/
|
||||
#export IS_USING_FREE_TIER=true
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
export RESTURL=https://free-main.fullstack.cash/v3/
|
||||
#export RESTURL=http://localhost:3000/v3/
|
||||
export IS_USING_FREE_TIER=true
|
||||
|
||||
cd test/integration/
|
||||
mocha --timeout 30000 blockchain.js control.js electrumx.js ninsight.js openbazaar.js price.js rawtransaction.js slp.js util.js
|
||||
@@ -3,7 +3,9 @@ const assert = chai.assert
|
||||
const sinon = require("sinon")
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
const bchjs = new BCHJS({ ninsightURL: "https://trest.bitcoin.com/v2" })
|
||||
const bchjs = new BCHJS({
|
||||
ninsightURL: "https://trest.bitcoin.com/v2"
|
||||
})
|
||||
|
||||
describe(`#Ninsight`, () => {
|
||||
let sandbox
|
||||
@@ -103,6 +105,128 @@ describe(`#Ninsight`, () => {
|
||||
assert.property(result[0].txs[0], "vout")
|
||||
})
|
||||
})
|
||||
describe(`#txDetails`, () => {
|
||||
it(`should POST transactions details for a single address`, async () => {
|
||||
const txid = "76856d82e00b2696acd8d989e1fa6c46b431005046a285ce905814cac0ff8fea"
|
||||
|
||||
const result = await bchjs.Ninsight.txDetails(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "txid")
|
||||
assert.property(result[0], "version")
|
||||
assert.property(result[0], "locktime")
|
||||
assert.property(result[0], "vin")
|
||||
assert.property(result[0], "vout")
|
||||
assert.property(result[0], "blockhash")
|
||||
assert.property(result[0], "blockheight")
|
||||
assert.property(result[0], "confirmations")
|
||||
assert.property(result[0], "time")
|
||||
assert.property(result[0], "blocktime")
|
||||
assert.property(result[0], "valueOut")
|
||||
assert.property(result[0], "size")
|
||||
})
|
||||
it(`should POST transactions details for an array of addresses`, async () => {
|
||||
const txid = [
|
||||
"f191d1062789d7071da6f2168ba306869a829294f6b1c09d03492db4ca3a8e77",
|
||||
"76856d82e00b2696acd8d989e1fa6c46b431005046a285ce905814cac0ff8fea"
|
||||
]
|
||||
|
||||
const result = await bchjs.Ninsight.txDetails(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "txid")
|
||||
assert.property(result[0], "vin")
|
||||
assert.property(result[0], "vout")
|
||||
})
|
||||
})
|
||||
|
||||
describe(`#detailsAddress`, () => {
|
||||
it(`should throw an error for improper input`, async () => {
|
||||
try {
|
||||
const addr = 12345
|
||||
|
||||
await bchjs.Ninsight.details(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 POST address details for a single address`, async () => {
|
||||
const addr = "bchtest:qzjtnzcvzxx7s0na88yrg3zl28wwvfp97538sgrrmr"
|
||||
|
||||
const result = await bchjs.Ninsight.details(addr)
|
||||
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "balance")
|
||||
assert.property(result[0], "balanceSat")
|
||||
assert.property(result[0], "totalReceived")
|
||||
assert.property(result[0], "totalReceivedSat")
|
||||
assert.property(result[0], "totalSent")
|
||||
assert.property(result[0], "totalSentSat")
|
||||
assert.property(result[0], "unconfirmedBalance")
|
||||
assert.property(result[0], "unconfirmedBalanceSat")
|
||||
assert.property(result[0], "unconfirmedTxApperances")
|
||||
assert.property(result[0], "txApperances")
|
||||
assert.property(result[0], "transactions")
|
||||
assert.property(result[0], "legacyAddress")
|
||||
assert.property(result[0], "cashAddress")
|
||||
assert.property(result[0], "slpAddress")
|
||||
assert.property(result[0], "currentPage")
|
||||
assert.property(result[0], "pagesTotal")
|
||||
})
|
||||
|
||||
it(`should POST address details for an array of addresses`, async () => {
|
||||
const addr = [
|
||||
"bchtest:qzjtnzcvzxx7s0na88yrg3zl28wwvfp97538sgrrmr",
|
||||
"bchtest:qp6hgvevf4gzz6l7pgcte3gaaud9km0l459fa23dul"
|
||||
]
|
||||
|
||||
const result = await bchjs.Ninsight.details(addr)
|
||||
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "balance")
|
||||
assert.property(result[0], "balanceSat")
|
||||
assert.property(result[0], "totalReceived")
|
||||
assert.property(result[0], "totalReceivedSat")
|
||||
assert.property(result[0], "totalSent")
|
||||
assert.property(result[0], "totalSentSat")
|
||||
assert.property(result[0], "unconfirmedBalance")
|
||||
assert.property(result[0], "unconfirmedBalanceSat")
|
||||
assert.property(result[0], "unconfirmedTxApperances")
|
||||
assert.property(result[0], "txApperances")
|
||||
assert.property(result[0], "transactions")
|
||||
assert.property(result[0], "legacyAddress")
|
||||
assert.property(result[1], "cashAddress")
|
||||
assert.property(result[1], "slpAddress")
|
||||
assert.property(result[1], "currentPage")
|
||||
assert.property(result[1], "pagesTotal")
|
||||
|
||||
/*
|
||||
If in any way possible, I would like to refactor this test
|
||||
according to the DRY principle to share it with the integration tests too
|
||||
Would that make sense or does that implicate anything unwanted?
|
||||
|
||||
assertDetails(result[0])
|
||||
|
||||
assertDetails(data) {
|
||||
assert.property(data, "balance")
|
||||
assert.property(data, "balanceSat")
|
||||
assert.property(data, "totalReceived")
|
||||
assert.property(data, "totalReceivedSat")
|
||||
assert.property(data, "totalSent")
|
||||
assert.property(data, "totalSentSat")
|
||||
}
|
||||
*/
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function sleep(ms) {
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
const chai = require("chai")
|
||||
const assert = chai.assert
|
||||
const BCHJS = require("../../src/bch-js")
|
||||
|
||||
// Used for debugging and iterrogating JS objects.
|
||||
const util = require("util")
|
||||
util.inspect.defaultOptions = { depth: 1 }
|
||||
|
||||
describe(`#BitboxShim`, () => {
|
||||
it("should create the shim library", () => {
|
||||
const BitboxShim = BCHJS.BitboxShim()
|
||||
const bitbox = new BitboxShim()
|
||||
|
||||
//console.log(`bitbox.Address: ${util.inspect(bitbox.Address)}`)
|
||||
|
||||
assert.hasAnyKeys(bitbox.Address, [
|
||||
// "details",
|
||||
// "utxo",
|
||||
// "unconfirmed",
|
||||
// "transactions",
|
||||
// "toLegacyAddress"
|
||||
"restURL"
|
||||
])
|
||||
})
|
||||
})
|
||||
@@ -116,11 +116,81 @@ const transactions = {
|
||||
|
||||
const transactionsPost = [transactions, transactions]
|
||||
|
||||
const details = {
|
||||
txid: "fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33",
|
||||
version: 1,
|
||||
locktime: 0,
|
||||
vin: [
|
||||
{
|
||||
coinbase: "04ffff001d02fd04",
|
||||
sequence: 4294967295,
|
||||
n: 0
|
||||
}
|
||||
],
|
||||
vout: [
|
||||
{
|
||||
value: "50.00000000",
|
||||
n: 0,
|
||||
scriptPubKey: {
|
||||
hex:
|
||||
"4104f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446aac",
|
||||
asm:
|
||||
"04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a OP_CHECKSIG",
|
||||
addresses: ["1BW18n7MfpU35q4MTBSk8pse3XzQF8XvzT"],
|
||||
type: "pubkeyhash",
|
||||
cashAddrs: ["bitcoincash:qpej6mkrwca4tvy2snq4crhrf88v4ljspysx0ueetk"]
|
||||
},
|
||||
spentTxId: null,
|
||||
spentIndex: null,
|
||||
spentHeight: null
|
||||
}
|
||||
],
|
||||
blockhash:
|
||||
"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09",
|
||||
blockheight: 1000,
|
||||
confirmations: 585610,
|
||||
time: 1232346882,
|
||||
blocktime: 1232346882,
|
||||
isCoinBase: true,
|
||||
valueOut: 50,
|
||||
size: 135
|
||||
}
|
||||
|
||||
const detailsPost = [details, details]
|
||||
|
||||
const addrDetail =
|
||||
{
|
||||
"balance": 0.00001,
|
||||
"balanceSat": 1000,
|
||||
"totalReceived": 0.00001,
|
||||
"totalReceivedSat": 1000,
|
||||
"totalSent": 0,
|
||||
"totalSentSat": 0,
|
||||
"unconfirmedBalance": 0,
|
||||
"unconfirmedBalanceSat": 0,
|
||||
"unconfirmedTxApperances": 0,
|
||||
"txApperances": 1,
|
||||
"transactions": [
|
||||
"5f09d317e24c5d376f737a2711f3bd1d381abdb41743fff3819b4f76382e1eac"
|
||||
],
|
||||
"legacyAddress": "1FZrK8HohEKyKCTM24NkAzPnX9WD9Ujhw7",
|
||||
"cashAddress": "bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr",
|
||||
"slpAddress": "simpleledger:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ylynt40sa",
|
||||
"currentPage": 0,
|
||||
"pagesTotal": 1
|
||||
}
|
||||
|
||||
const addrDetailArray = [addrDetail, addrDetail]
|
||||
|
||||
module.exports = {
|
||||
utxo,
|
||||
utxoPost,
|
||||
unconfirmed,
|
||||
unconfirmedPost,
|
||||
transactions,
|
||||
transactionsPost
|
||||
transactionsPost,
|
||||
details,
|
||||
detailsPost,
|
||||
addrDetail,
|
||||
addrDetailArray
|
||||
}
|
||||
|
||||
+180
-6
@@ -31,7 +31,9 @@ describe(`#Ninsight`, () => {
|
||||
|
||||
it(`should GET utxos for a single address`, async () => {
|
||||
// Stub the network call.
|
||||
sandbox.stub(axios, "post").resolves({ data: mockData.utxo })
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.utxo
|
||||
})
|
||||
|
||||
const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9"
|
||||
|
||||
@@ -57,7 +59,9 @@ describe(`#Ninsight`, () => {
|
||||
|
||||
it(`should POST utxo details for an array of addresses`, async () => {
|
||||
// Mock the network call.
|
||||
sandbox.stub(axios, "post").resolves({ data: mockData.utxoPost })
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.utxoPost
|
||||
})
|
||||
|
||||
const addr = [
|
||||
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
|
||||
@@ -96,7 +100,9 @@ describe(`#Ninsight`, () => {
|
||||
|
||||
it(`should POST utxos for a single address`, async () => {
|
||||
// Stub the network call.
|
||||
sandbox.stub(axios, "post").resolves({ data: mockData.unconfirmed })
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.unconfirmed
|
||||
})
|
||||
|
||||
const addr = "bitcoincash:qpkkjkhe29mqhqmu3evtq3dsnruuzl3rku6usknlh5"
|
||||
|
||||
@@ -121,7 +127,9 @@ describe(`#Ninsight`, () => {
|
||||
|
||||
it(`should POST utxo details for an array of addresses`, async () => {
|
||||
// Mock the network call.
|
||||
sandbox.stub(axios, "post").resolves({ data: mockData.unconfirmedPost })
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.unconfirmedPost
|
||||
})
|
||||
|
||||
const addr = [
|
||||
"bitcoincash:qpkkjkhe29mqhqmu3evtq3dsnruuzl3rku6usknlh5",
|
||||
@@ -159,7 +167,9 @@ describe(`#Ninsight`, () => {
|
||||
})
|
||||
it(`should POST transaction history for a single address`, async () => {
|
||||
// Stub the network call.
|
||||
sandbox.stub(axios, "post").resolves({ data: mockData.transactionsPost })
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.transactionsPost
|
||||
})
|
||||
|
||||
const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9"
|
||||
|
||||
@@ -177,7 +187,9 @@ describe(`#Ninsight`, () => {
|
||||
})
|
||||
it(`should POST transaction history for an array of addresses`, async () => {
|
||||
// Mock the network call.
|
||||
sandbox.stub(axios, "post").resolves({ data: mockData.transactionsPost })
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.transactionsPost
|
||||
})
|
||||
|
||||
const addr = [
|
||||
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
|
||||
@@ -195,4 +207,166 @@ describe(`#Ninsight`, () => {
|
||||
assert.property(result[0].txs[0], "txid")
|
||||
})
|
||||
})
|
||||
describe(`#txDetails`, () => {
|
||||
it(`should throw an error for improper input`, async () => {
|
||||
try {
|
||||
const txid = 12345
|
||||
|
||||
await bchjs.Ninsight.txDetails(txid)
|
||||
assert.equal(true, false, "Unexpected result!")
|
||||
} catch (err) {
|
||||
//console.log(`err: `, err)
|
||||
assert.include(
|
||||
err.message,
|
||||
`Transaction ID must be a string or array of strings.`
|
||||
)
|
||||
}
|
||||
})
|
||||
it(`should POST transaction details for a single TxID`, async () => {
|
||||
// Stub the network call.
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.detailsPost
|
||||
})
|
||||
|
||||
const txid = "fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33"
|
||||
|
||||
const result = await bchjs.Ninsight.txDetails(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "txid")
|
||||
assert.property(result[0], "version")
|
||||
assert.property(result[0], "locktime")
|
||||
assert.property(result[0], "vin")
|
||||
assert.property(result[0], "vout")
|
||||
assert.property(result[0], "blockhash")
|
||||
assert.property(result[0], "blockheight")
|
||||
assert.property(result[0], "confirmations")
|
||||
assert.property(result[0], "time")
|
||||
assert.property(result[0], "blocktime")
|
||||
assert.property(result[0], "isCoinBase")
|
||||
assert.property(result[0], "valueOut")
|
||||
assert.property(result[0], "size")
|
||||
})
|
||||
it(`should POST transaction details for an array of TxIDs`, async () => {
|
||||
// Stub the network call.
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.detailsPost
|
||||
})
|
||||
|
||||
const txid = [
|
||||
"fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33",
|
||||
"fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33"
|
||||
]
|
||||
|
||||
const result = await bchjs.Ninsight.txDetails(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "txid")
|
||||
assert.property(result[0], "vin")
|
||||
assert.property(result[0], "vout")
|
||||
})
|
||||
})
|
||||
|
||||
describe(`#addrDetails`, () => {
|
||||
it(`should throw an error for improper input`, async () => {
|
||||
try {
|
||||
const addr = 12345
|
||||
|
||||
await bchjs.Ninsight.details(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 POST address details for a single address`, async () => {
|
||||
// Stub the network call.
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.addrDetailArray
|
||||
})
|
||||
|
||||
const result = await bchjs.Ninsight.details("addr")
|
||||
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.property(result[0], "balance")
|
||||
assert.property(result[0], "balanceSat")
|
||||
assert.property(result[0], "totalReceived")
|
||||
assert.property(result[0], "totalReceivedSat")
|
||||
assert.property(result[0], "totalSent")
|
||||
assert.property(result[0], "totalSentSat")
|
||||
assert.property(result[0], "unconfirmedBalance")
|
||||
assert.property(result[0], "unconfirmedBalanceSat")
|
||||
assert.property(result[0], "unconfirmedTxApperances")
|
||||
assert.property(result[0], "txApperances")
|
||||
assert.property(result[0], "transactions")
|
||||
assert.property(result[0], "legacyAddress")
|
||||
assert.property(result[0], "cashAddress")
|
||||
assert.property(result[0], "slpAddress")
|
||||
assert.property(result[0], "currentPage")
|
||||
assert.property(result[0], "pagesTotal")
|
||||
})
|
||||
|
||||
it(`should call constructor with null args`, async () => {
|
||||
new bchjs.Ninsight.constructor({})
|
||||
})
|
||||
|
||||
it(`should POST address details for an array of addresses`, async () => {
|
||||
// Mock the network call.
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.addrDetailArray
|
||||
})
|
||||
|
||||
const addr = [
|
||||
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
|
||||
"bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr"
|
||||
]
|
||||
|
||||
const result = await bchjs.Ninsight.details(addr)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
|
||||
assert.property(result[0], "balance")
|
||||
assert.property(result[0], "balanceSat")
|
||||
assert.property(result[0], "totalReceived")
|
||||
assert.property(result[0], "totalReceivedSat")
|
||||
assert.property(result[0], "totalSent")
|
||||
assert.property(result[0], "totalSentSat")
|
||||
assert.property(result[0], "unconfirmedBalance")
|
||||
assert.property(result[0], "unconfirmedBalanceSat")
|
||||
assert.property(result[0], "unconfirmedTxApperances")
|
||||
assert.property(result[0], "txApperances")
|
||||
assert.property(result[0], "transactions")
|
||||
assert.property(result[0], "legacyAddress")
|
||||
assert.property(result[1], "cashAddress")
|
||||
assert.property(result[1], "slpAddress")
|
||||
assert.property(result[1], "currentPage")
|
||||
assert.property(result[1], "pagesTotal")
|
||||
|
||||
/*
|
||||
If in any way possible, I would like to refactor this test
|
||||
according to the DRY principle to share it with the integration tests too
|
||||
Would that make sense or does that implicate anything unwanted?
|
||||
|
||||
assertDetails(result[0])
|
||||
|
||||
assertDetails(data) {
|
||||
assert.property(data, "satoshis")
|
||||
assert.property(data, "height")
|
||||
assert.property(data, "confirmations")
|
||||
assert.property(data, "timestamp")
|
||||
assert.property(data, "fees")
|
||||
assert.property(data, "outputIndexes")
|
||||
assert.property(data, "inputIndexes")
|
||||
assert.property(data, "tx")
|
||||
}
|
||||
*/
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user