mirror of
https://github.com/Permissionless-Software-Foundation/bch-js.git
synced 2026-09-22 00:52:01 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccc545b1be | ||
|
|
c6301055fa | ||
|
|
13d9f89a82 | ||
|
|
f5de593f89 | ||
|
|
3b0ec95fba | ||
|
|
0a328090ea | ||
|
|
315cb4f254 | ||
|
|
28f08f02ac | ||
|
|
5949e0f6f8 | ||
|
|
617bb16ddb | ||
|
|
83f14f5522 | ||
|
|
b8e22e1c99 | ||
|
|
72d560e407 | ||
|
|
248b2fa2a6 | ||
|
|
563cb297fe | ||
|
|
4c020240e1 | ||
|
|
e070409a95 | ||
|
|
fbbd855145 | ||
|
|
731987b35b | ||
|
|
1e8e7b79f2 | ||
|
|
099eb25e88 | ||
|
|
12a7c666c6 |
+9
-7
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@psf/bch-js",
|
||||
"version": "3.4.0",
|
||||
"version": "4.0.0",
|
||||
"description": "The FullStack.cash JavaScript library for Bitcoin Cash and SLP Tokens",
|
||||
"author": "Chris Troutner <chris.troutner@gmail.com>",
|
||||
"contributors": [
|
||||
@@ -11,13 +11,15 @@
|
||||
"test": "nyc mocha --timeout 30000 test/unit/",
|
||||
"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:abc": "RESTURL=https://abc.fullstack.cash/v4/ 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: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",
|
||||
"test:integration:local": "RESTURL=http://localhost:3000/v4/ mocha --timeout 30000 test/integration",
|
||||
"test:integration:local:bchn": "RESTURL=http://localhost:3000/v4/ bash test/integration/test-bchn-integration.sh",
|
||||
"test:integration:local:testnet": "RESTURL=http://localhost:4000/v4/ mocha --timeout 30000 test/integration/testnet",
|
||||
"test:temp": "RESTURL=https://bchn.fullstack.cash/v4/ mocha --timeout 30000 -g '#validateTxid' test/integration/bchn/",
|
||||
"test:temp2": "RESTURL=https://abc.fullstack.cash/v4/ mocha --timeout 30000 -g '#validateTxid' test/integration/",
|
||||
"test:temp3": "ISBCHN=true RESTURL=http://localhost:3000/v4/ mocha --timeout 30000 -g '#validateTxid' test/integration/bchn/",
|
||||
"test:integration:api": "RESTURL=https://api.fullstack.cash/v4/ mocha --timeout 30000 test/integration",
|
||||
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
||||
"coverage:report": "nyc --reporter=html mocha --timeout 25000 test/unit/",
|
||||
"docs": "./node_modules/.bin/apidoc -i src/ -o docs"
|
||||
|
||||
+18
-1
@@ -6,11 +6,28 @@ const coininfo = require("coininfo")
|
||||
class Address {
|
||||
constructor(config) {
|
||||
const tmp = {}
|
||||
if (!config || !config.restURL) tmp.restURL = `https://api.bchjs.cash/v3/`
|
||||
if (!config || !config.restURL) tmp.restURL = `https://api.bchjs.cash/v4/`
|
||||
else tmp.restURL = config.restURL
|
||||
|
||||
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}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+20
-3
@@ -7,8 +7,7 @@
|
||||
*/
|
||||
|
||||
// bch-api mainnet.
|
||||
// const DEFAULT_REST_API = "https://api.bchjs.cash/v3/"
|
||||
const DEFAULT_REST_API = "https://api.fullstack.cash/v3/"
|
||||
const DEFAULT_REST_API = "https://api.fullstack.cash/v4/"
|
||||
|
||||
// local deps
|
||||
const BitcoinCash = require("./bitcoincash")
|
||||
@@ -55,9 +54,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}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+52
-28
@@ -6,41 +6,30 @@ 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}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.axios = axios
|
||||
}
|
||||
|
||||
/**
|
||||
* @api price.current() current()
|
||||
* @apiName Price.
|
||||
* @apiGroup Price
|
||||
* @apiDescription Return current price of BCH in multiple currencies.
|
||||
* This endpoint will be deprecated in favor of getUSD. It uses the Bitcoin.com
|
||||
* price feed.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
*(async () => {
|
||||
* try {
|
||||
* let current = await bchjs.Price.current('usd');
|
||||
* console.log(current);
|
||||
* } catch(err) {
|
||||
* console.err(err)
|
||||
* }
|
||||
*})()
|
||||
*
|
||||
* // 26681
|
||||
*/
|
||||
// This endpoint is deprecated. Documentation removed.
|
||||
async current(currency = "usd") {
|
||||
try {
|
||||
const response = await this.axios.get(
|
||||
@@ -132,6 +121,41 @@ class Price {
|
||||
else throw err
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api price.getBchaUsd() getBchaUsd()
|
||||
* @apiName Price getBchaUsd()
|
||||
* @apiGroup Price
|
||||
* @apiDescription Return current price of BCHA in USD.
|
||||
* This endpoint gets the USD price of BCHA from the Coinex API. The price
|
||||
* comes from bch-api, so it has a better chance of working in Tor.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
*(async () => {
|
||||
* try {
|
||||
* let current = await bchjs.Price.getBchaUsd();
|
||||
* console.log(current);
|
||||
* } catch(err) {
|
||||
* console.err(err)
|
||||
* }
|
||||
*})()
|
||||
*
|
||||
* // 18.81
|
||||
*/
|
||||
async getBchaUsd() {
|
||||
try {
|
||||
const response = await this.axios.get(
|
||||
`${this.restURL}price/bchausd`,
|
||||
_this.axiosOptions
|
||||
)
|
||||
// console.log(`response.data: ${JSON.stringify(response.data, null, 2)}`)
|
||||
|
||||
return response.data.usd
|
||||
} catch (err) {
|
||||
if (err.response && err.response.data) throw err.response.data
|
||||
else throw err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Price
|
||||
|
||||
+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)
|
||||
|
||||
+158
-15
@@ -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}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,16 +448,6 @@ class Utils {
|
||||
|
||||
const validatedTxids = response.data
|
||||
|
||||
// Handle any null values
|
||||
for (let i = 0; i < validatedTxids.length; i++) {
|
||||
if (validatedTxids[i] === null) {
|
||||
validatedTxids[i] = {
|
||||
txid: txids[i],
|
||||
valid: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return validatedTxids
|
||||
} catch (error) {
|
||||
if (error.response && error.response.data) throw error.response.data
|
||||
@@ -475,7 +475,7 @@ class Utils {
|
||||
* // validate single SLP txid
|
||||
* (async () => {
|
||||
* try {
|
||||
* let validated = await bchjs.SLP.Utils.validateTxid(
|
||||
* let validated = await bchjs.SLP.Utils.validateTxid2(
|
||||
* "df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb"
|
||||
* );
|
||||
* console.log(validated);
|
||||
@@ -515,6 +515,149 @@ class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api SLP.Utils.whitelist() whitelist()
|
||||
* @apiName whitelist
|
||||
* @apiGroup SLP Utils
|
||||
* @apiDescription Get SLP tokens in whitelist
|
||||
* Retrieves a list of the SLP tokens that in the whitelist. Tokens in the
|
||||
* whitelist can be validated with the validateTxid3() function. validateTxid3()
|
||||
* will still work when the SLP network is under stress.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
*
|
||||
* // validate single SLP txid
|
||||
* (async () => {
|
||||
* try {
|
||||
* let list = await bchjs.SLP.Utils.whitelit();
|
||||
* console.log(list);
|
||||
* } catch (error) {
|
||||
* console.error(error);
|
||||
* }
|
||||
* })();
|
||||
*
|
||||
* // returns
|
||||
* [
|
||||
* {
|
||||
* name: 'USDH',
|
||||
* tokenId:
|
||||
* 'c4b0d62156b3fa5c8f3436079b5394f7edc1bef5dc1cd2f9d0c4d46f82cca479'
|
||||
* },
|
||||
* {
|
||||
* name: 'SPICE',
|
||||
* tokenId:
|
||||
* '4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf'
|
||||
* },
|
||||
* {
|
||||
* name: 'PSF',
|
||||
* tokenId:
|
||||
* '38e97c5d7d3585a2cbf3f9580c82ca33985f9cb0845d4dcce220cb709f9538b0'
|
||||
* },
|
||||
* {
|
||||
* name: 'TROUT',
|
||||
* tokenId:
|
||||
* 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
|
||||
* },
|
||||
* {
|
||||
* name: 'PSFTEST',
|
||||
* tokenId:
|
||||
* 'd0ef4de95b78222bfee2326ab11382f4439aa0855936e2fe6ac129a8d778baa0'
|
||||
* }
|
||||
* ]
|
||||
*/
|
||||
async getWhitelist(txid) {
|
||||
try {
|
||||
const path = `${this.restURL}slp/whitelist`
|
||||
|
||||
const response = await axios.get(path, _this.axiosOptions)
|
||||
// console.log(`response.data: ${JSON.stringify(response.data, null, 2)}`)
|
||||
|
||||
return response.data
|
||||
} catch (error) {
|
||||
if (error.response && error.response.data) throw error.response.data
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api SLP.Utils.validateTxid3() validateTxid3()
|
||||
* @apiName validateTxid3
|
||||
* @apiGroup SLP Utils
|
||||
* @apiDescription Validate that txid is an SLP transaction using the SLPDB whitelist server.
|
||||
* Same exact functionality as the validateTxid() function, but this function
|
||||
* calls the whitelist SLPDB. It will only validate SLP tokens that are in the
|
||||
* whitelist. You can retrieve the whitelist with the SLP.Utils.whitelist()
|
||||
* function.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
*
|
||||
* // validate single SLP txid
|
||||
* (async () => {
|
||||
* try {
|
||||
* let validated = await bchjs.SLP.Utils.validateTxid3(
|
||||
* "df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb"
|
||||
* );
|
||||
* console.log(validated);
|
||||
* } catch (error) {
|
||||
* console.error(error);
|
||||
* }
|
||||
* })();
|
||||
*
|
||||
* // returns
|
||||
* [ { txid:
|
||||
* 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb',
|
||||
* valid: true } ]
|
||||
*
|
||||
* // validate multiple SLP txids
|
||||
* (async () => {
|
||||
* try {
|
||||
* let validated = await bchjs.SLP.Utils.validateTxid3([
|
||||
* "df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb",
|
||||
* "00ea27261196a411776f81029c0ebe34362936b4a9847deb1f7a40a02b3a1476"
|
||||
* ]);
|
||||
* console.log(validated);
|
||||
* } catch (error) {
|
||||
* console.error(error);
|
||||
* }
|
||||
* })();
|
||||
*
|
||||
* // returns
|
||||
* [ { txid:
|
||||
* 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb',
|
||||
* valid: true },
|
||||
* { txid:
|
||||
* '00ea27261196a411776f81029c0ebe34362936b4a9847deb1f7a40a02b3a1476',
|
||||
* valid: true } ]
|
||||
*/
|
||||
async validateTxid3(txid) {
|
||||
const path = `${this.restURL}slp/validateTxid3`
|
||||
|
||||
// console.log(`txid: ${JSON.stringify(txid, null, 2)}`)
|
||||
|
||||
// Handle a single TXID or an array of TXIDs.
|
||||
let txids
|
||||
if (typeof txid === "string") txids = [txid]
|
||||
else txids = txid
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
path,
|
||||
{
|
||||
txids: txids
|
||||
},
|
||||
_this.axiosOptions
|
||||
)
|
||||
// console.log(`response.data: ${JSON.stringify(response.data, null, 2)}`)
|
||||
|
||||
const validatedTxids = response.data
|
||||
|
||||
return validatedTxids
|
||||
} catch (error) {
|
||||
if (error.response && error.response.data) throw error.response.data
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api SLP.Utils.tokenStats() tokenStats()
|
||||
* @apiName tokenStats
|
||||
|
||||
+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,12 +5,18 @@
|
||||
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 = `http://localhost:3000/v3/`
|
||||
// const RESTURL = `https://abc.fullstack.cash/v4/`
|
||||
const RESTURL = `https://bchn.fullstack.cash/v4/`
|
||||
// const RESTURL = `http://localhost:3000/v4/`
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
const bchjs = new BCHJS({ restURL: RESTURL })
|
||||
@@ -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/v4/`,
|
||||
restURL: `https://abc.fullstack.cash/v4/`,
|
||||
// restURL: `http://localhost:3000/v4/`,
|
||||
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
|
||||
|
||||
@@ -14,8 +18,8 @@ const JWT_TOKEN =
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
const bchjs = new BCHJS({
|
||||
restURL: `https://api.fullstack.cash/v3/`,
|
||||
// restURL: `http://localhost:3000/v3/`,
|
||||
restURL: `https://api.fullstack.cash/v4/`,
|
||||
// restURL: `http://localhost:3000/v4/`,
|
||||
apiToken: JWT_TOKEN
|
||||
})
|
||||
|
||||
|
||||
@@ -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,15 +18,16 @@ const JWT_TOKEN =
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
const bchjs = new BCHJS({
|
||||
restURL: `https://api.fullstack.cash/v3/`,
|
||||
// restURL: `http://localhost:3000/v3/`,
|
||||
// restURL: `https://bchn.fullstack.cash/v4/`,
|
||||
restURL: `https:/abc.fullstack.cash/v4/`,
|
||||
// restURL: `http://localhost:3000/v4/`,
|
||||
apiToken: JWT_TOKEN
|
||||
})
|
||||
|
||||
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: `http://localhost:3000/v3/`,
|
||||
// restURL: `https://bchn.fullstack.cash/v4/`,
|
||||
restURL: `https://abc.fullstack.cash/v4/`,
|
||||
// restURL: `http://localhost:3000/v4/`,
|
||||
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}`)
|
||||
|
||||
@@ -21,6 +21,15 @@ describe("#price", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getBchaUsd", () => {
|
||||
it("should get the USD price of BCHA", async () => {
|
||||
const result = await bchjs.Price.getBchaUsd()
|
||||
console.log(result)
|
||||
|
||||
assert.isNumber(result)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#rates", () => {
|
||||
it("should get the price of BCH in several currencies", async () => {
|
||||
const result = await bchjs.Price.rates()
|
||||
|
||||
@@ -663,6 +663,151 @@ describe(`#SLP`, () => {
|
||||
assert.equal(result.isValid, true)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getWhitelist", () => {
|
||||
it("should get the whitelist", async () => {
|
||||
const result = await bchjs.SLP.Utils.getWhitelist()
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "name")
|
||||
assert.property(result[1], "tokenId")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#validateTxid3", () => {
|
||||
it("should invalidate a known invalid TXID", async () => {
|
||||
const txid =
|
||||
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a"
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid3(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
|
||||
assert.property(result[0], "txid")
|
||||
assert.equal(result[0].txid, txid)
|
||||
|
||||
assert.property(result[0], "valid")
|
||||
assert.equal(result[0].valid, null)
|
||||
})
|
||||
|
||||
it("should validate a known valid TXID", async () => {
|
||||
const txid =
|
||||
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd"
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid3(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
|
||||
assert.property(result[0], "txid")
|
||||
assert.equal(result[0].txid, txid)
|
||||
|
||||
assert.property(result[0], "valid")
|
||||
assert.equal(result[0].valid, true)
|
||||
})
|
||||
|
||||
it("should handle a mix of valid, invalid, and non-SLP txs", async () => {
|
||||
const txids = [
|
||||
// Malformed SLP tx
|
||||
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
|
||||
// Normal TX (non-SLP)
|
||||
"01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
|
||||
// Valid PSF SLP tx
|
||||
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
|
||||
// Valid SLP token not in whitelist
|
||||
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
|
||||
// Token send on BCHN network.
|
||||
"402c663379d9699b6e2dd38737061e5888c5a49fca77c97ab98e79e08959e019",
|
||||
// Token send on ABC network.
|
||||
"336bfe2168aac4c3303508a9e8548a0d33797a83b85b76a12d845c8d6674f79d",
|
||||
// Known invalid SLP token send of PSF tokens.
|
||||
"2bf691ad3679d928fef880b8a45b93b233f8fa0d0a92cf792313dbe77b1deb74"
|
||||
]
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid3(txids)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.equal(result[0].txid, txids[0])
|
||||
assert.equal(result[0].valid, null)
|
||||
|
||||
assert.equal(result[1].txid, txids[1])
|
||||
assert.equal(result[1].valid, null)
|
||||
|
||||
assert.equal(result[2].txid, txids[2])
|
||||
assert.equal(result[2].valid, true)
|
||||
|
||||
// True in validateTxid() but null in validateTxid3()
|
||||
assert.equal(result[3].txid, txids[3])
|
||||
assert.equal(result[3].valid, null)
|
||||
|
||||
// Note: This should change from null to true once SLPDB finishes indexing.
|
||||
assert.equal(result[4].txid, txids[4])
|
||||
assert.equal(result[4].valid, null)
|
||||
|
||||
assert.equal(result[5].txid, txids[5])
|
||||
assert.equal(result[5].valid, null)
|
||||
|
||||
assert.equal(result[6].txid, txids[6])
|
||||
assert.equal(result[6].valid, false)
|
||||
assert.include(
|
||||
result[6].invalidReason,
|
||||
"Token outputs are greater than valid token inputs"
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#validateTxid", () => {
|
||||
it("should handle a mix of valid, invalid, and non-SLP txs", async () => {
|
||||
const txids = [
|
||||
// Malformed SLP tx
|
||||
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
|
||||
// Normal TX (non-SLP)
|
||||
"01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
|
||||
// Valid PSF SLP tx
|
||||
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
|
||||
// Valid SLP token not in whitelist
|
||||
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
|
||||
// Token send on BCHN network.
|
||||
"402c663379d9699b6e2dd38737061e5888c5a49fca77c97ab98e79e08959e019",
|
||||
// Token send on ABC network.
|
||||
"336bfe2168aac4c3303508a9e8548a0d33797a83b85b76a12d845c8d6674f79d",
|
||||
// Known invalid SLP token send of PSF tokens.
|
||||
"2bf691ad3679d928fef880b8a45b93b233f8fa0d0a92cf792313dbe77b1deb74"
|
||||
]
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid(txids)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.equal(result[0].txid, txids[0])
|
||||
assert.equal(result[0].valid, null)
|
||||
|
||||
assert.equal(result[1].txid, txids[1])
|
||||
assert.equal(result[1].valid, null)
|
||||
|
||||
assert.equal(result[2].txid, txids[2])
|
||||
assert.equal(result[2].valid, true)
|
||||
|
||||
// True in validateTxid() but null in validateTxid3()
|
||||
assert.equal(result[3].txid, txids[3])
|
||||
assert.equal(result[3].valid, true)
|
||||
|
||||
// Note: This should change from null to true once SLPDB finishes indexing.
|
||||
assert.equal(result[4].txid, txids[4])
|
||||
assert.equal(result[4].valid, null)
|
||||
|
||||
assert.equal(result[5].txid, txids[5])
|
||||
assert.equal(result[5].valid, null)
|
||||
|
||||
assert.equal(result[6].txid, txids[6])
|
||||
assert.equal(result[6].valid, false)
|
||||
assert.include(
|
||||
result[6].invalidReason,
|
||||
"Token outputs are greater than valid token inputs"
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#tokentype1", () => {
|
||||
|
||||
@@ -25,6 +25,15 @@ describe("#price", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getBchaUsd", () => {
|
||||
it("should get the USD price of BCHA", async () => {
|
||||
const result = await bchjs.Price.getBchaUsd()
|
||||
console.log(result)
|
||||
|
||||
assert.isNumber(result)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#rates", () => {
|
||||
it("should get the price of BCH in several currencies", async () => {
|
||||
const result = await bchjs.Price.rates()
|
||||
|
||||
@@ -244,7 +244,7 @@ describe("#rawtransaction", () => {
|
||||
//console.log(`err: ${util.inspect(err)}`)
|
||||
|
||||
assert.hasAllKeys(err, ["error"])
|
||||
assert.include(err.error, "bad-txns-inputs-missingorspent (code 16)")
|
||||
assert.include(err.error, "bad-txns-inputs-missingorspent")
|
||||
}
|
||||
})
|
||||
|
||||
@@ -261,7 +261,7 @@ describe("#rawtransaction", () => {
|
||||
// console.log(`err: ${util.inspect(err)}`)
|
||||
|
||||
assert.hasAllKeys(err, ["error"])
|
||||
assert.include(err.error, "bad-txns-inputs-missingorspent (code 16)")
|
||||
assert.include(err.error, "bad-txns-inputs-missingorspent")
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -634,6 +634,94 @@ describe(`#SLP`, () => {
|
||||
assert.equal(result.isValid, true)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getWhitelist", () => {
|
||||
it("should get the whitelist", async () => {
|
||||
const result = await bchjs.SLP.Utils.getWhitelist()
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
assert.property(result[0], "name")
|
||||
assert.property(result[1], "tokenId")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#validateTxid3", () => {
|
||||
it("should invalidate a known invalid TXID", async () => {
|
||||
const txid =
|
||||
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a"
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid3(txid)
|
||||
console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
|
||||
assert.property(result[0], "txid")
|
||||
assert.equal(result[0].txid, txid)
|
||||
|
||||
assert.property(result[0], "valid")
|
||||
assert.equal(result[0].valid, null)
|
||||
})
|
||||
|
||||
it("should validate a known valid TXID", async () => {
|
||||
const txid =
|
||||
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd"
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid3(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
|
||||
assert.property(result[0], "txid")
|
||||
assert.equal(result[0].txid, txid)
|
||||
|
||||
assert.property(result[0], "valid")
|
||||
assert.equal(result[0].valid, true)
|
||||
})
|
||||
|
||||
it("should handle a mix of valid, invalid, and non-SLP txs", async () => {
|
||||
const txids = [
|
||||
// Malformed SLP tx
|
||||
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
|
||||
// Normal TX (non-SLP)
|
||||
"01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
|
||||
// Valid PSF SLP tx
|
||||
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
|
||||
// Valid SLP token not in whitelist
|
||||
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
|
||||
// Unprocessed SLP TX
|
||||
// "a0d6406eecfd8634158efa9314ff15b4cbf451938e9dc7b5678c46b41eabc6ed" // Mint baton
|
||||
"402c663379d9699b6e2dd38737061e5888c5a49fca77c97ab98e79e08959e019"
|
||||
]
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid3(txids)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
})
|
||||
|
||||
describe("#validateTxid", () => {
|
||||
it("should handle a mix of valid, invalid, and non-SLP txs", async () => {
|
||||
const txids = [
|
||||
// Malformed SLP tx
|
||||
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
|
||||
// Normal TX (non-SLP)
|
||||
"01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
|
||||
// Valid PSF SLP tx
|
||||
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
|
||||
// Valid SLP token not in whitelist
|
||||
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
|
||||
// Unprocessed SLP TX
|
||||
// "a0d6406eecfd8634158efa9314ff15b4cbf451938e9dc7b5678c46b41eabc6ed"
|
||||
// Token send on BCHN network.
|
||||
"402c663379d9699b6e2dd38737061e5888c5a49fca77c97ab98e79e08959e019",
|
||||
// Token send on ABC network.
|
||||
"336bfe2168aac4c3303508a9e8548a0d33797a83b85b76a12d845c8d6674f79d"
|
||||
]
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid(txids)
|
||||
console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#tokentype1", () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
export RESTURL=https://bchn.fullstack.cash/v3/
|
||||
#export RESTURL=http://localhost:3000/v3/
|
||||
# export RESTURL=https://bchn.fullstack.cash/v4/
|
||||
#export RESTURL=http://localhost:3000/v4/
|
||||
#export IS_USING_FREE_TIER=true
|
||||
|
||||
cd test/integration/bchn/
|
||||
|
||||
@@ -8,11 +8,11 @@ const assert = chai.assert
|
||||
|
||||
const RESTURL = process.env.RESTURL
|
||||
? process.env.RESTURL
|
||||
: `https://testnet3.fullstack.cash/v3/`
|
||||
: `https://testnet3.fullstack.cash/v4/`
|
||||
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v3/` })
|
||||
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v4/` })
|
||||
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
|
||||
// const bchjs = new BCHJS({ restURL: RESTURL })
|
||||
//const axios = require("axios")
|
||||
|
||||
@@ -12,11 +12,11 @@ const assert = chai.assert
|
||||
|
||||
const RESTURL = process.env.RESTURL
|
||||
? process.env.RESTURL
|
||||
: "https://testnet3.fullstack.cash/v3/"
|
||||
: "https://testnet3.fullstack.cash/v4/"
|
||||
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v3/` })
|
||||
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v4/` })
|
||||
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
|
||||
|
||||
// Inspect utility used for debugging.
|
||||
|
||||
@@ -7,7 +7,7 @@ const assert = chai.assert
|
||||
|
||||
const RESTURL = process.env.RESTURL
|
||||
? process.env.RESTURL
|
||||
: `https://testnet3.fullstack.cash/v3/`
|
||||
: `https://testnet3.fullstack.cash/v4/`
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
|
||||
|
||||
@@ -4,7 +4,7 @@ const sinon = require("sinon")
|
||||
|
||||
const RESTURL = process.env.RESTURL
|
||||
? process.env.RESTURL
|
||||
: `https://testnet3.fullstack.cash/v3/`
|
||||
: `https://testnet3.fullstack.cash/v4/`
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
|
||||
|
||||
@@ -10,11 +10,11 @@ const assert = chai.assert
|
||||
|
||||
const RESTURL = process.env.RESTURL
|
||||
? process.env.RESTURL
|
||||
: `https://testnet3.fullstack.cash/v3/`
|
||||
: `https://testnet3.fullstack.cash/v4/`
|
||||
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v3/` })
|
||||
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v4/` })
|
||||
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
|
||||
|
||||
// Inspect utility used for debugging.
|
||||
|
||||
@@ -7,11 +7,11 @@ const assert = chai.assert
|
||||
|
||||
const RESTURL = process.env.RESTURL
|
||||
? process.env.RESTURL
|
||||
: `https://testnet3.fullstack.cash/v3/`
|
||||
: `https://testnet3.fullstack.cash/v4/`
|
||||
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v3/` })
|
||||
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v4/` })
|
||||
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
|
||||
|
||||
// Inspect utility used for debugging.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
export RESTURL=https://free-test.fullstack.cash/v3/
|
||||
export RESTURL=https://free-test.fullstack.cash/v4/
|
||||
export NETWORK=testnet
|
||||
export IS_USING_FREE_TIER=true
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@ const assert = chai.assert
|
||||
|
||||
const RESTURL = process.env.RESTURL
|
||||
? process.env.RESTURL
|
||||
: `https://testnet3.fullstack.cash/v3/`
|
||||
: `https://testnet3.fullstack.cash/v4/`
|
||||
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
|
||||
|
||||
const BCHJS = require("../../../src/bch-js")
|
||||
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v3/` })
|
||||
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v4/` })
|
||||
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
|
||||
|
||||
// Inspect utility used for debugging.
|
||||
|
||||
@@ -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"
|
||||
])
|
||||
})
|
||||
})
|
||||
@@ -1107,6 +1107,62 @@ const txDetailsSLPNftGenesis = {
|
||||
blocktime: 1591329189
|
||||
}
|
||||
|
||||
const mockWhitelist = [
|
||||
{
|
||||
name: "USDH",
|
||||
tokenId: "c4b0d62156b3fa5c8f3436079b5394f7edc1bef5dc1cd2f9d0c4d46f82cca479"
|
||||
},
|
||||
{
|
||||
name: "SPICE",
|
||||
tokenId: "4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf"
|
||||
},
|
||||
{
|
||||
name: "PSF",
|
||||
tokenId: "38e97c5d7d3585a2cbf3f9580c82ca33985f9cb0845d4dcce220cb709f9538b0"
|
||||
},
|
||||
{
|
||||
name: "TROUT",
|
||||
tokenId: "a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2"
|
||||
},
|
||||
{
|
||||
name: "PSFTEST",
|
||||
tokenId: "d0ef4de95b78222bfee2326ab11382f4439aa0855936e2fe6ac129a8d778baa0"
|
||||
}
|
||||
]
|
||||
|
||||
const mockValidateTxid3Valid = [
|
||||
{
|
||||
txid: "daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
|
||||
valid: true
|
||||
}
|
||||
]
|
||||
|
||||
const mockValidateTxid3Invalid = [
|
||||
{
|
||||
txid: "f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
|
||||
valid: null
|
||||
}
|
||||
]
|
||||
|
||||
const mockValidateTxidArray = [
|
||||
{
|
||||
txid: "daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
|
||||
valid: true
|
||||
},
|
||||
{
|
||||
txid: "3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
|
||||
valid: true
|
||||
},
|
||||
{
|
||||
txid: "f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
|
||||
valid: false
|
||||
},
|
||||
{
|
||||
txid: "01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
|
||||
valid: false
|
||||
}
|
||||
]
|
||||
|
||||
module.exports = {
|
||||
mockList,
|
||||
mockToken,
|
||||
@@ -1131,5 +1187,8 @@ module.exports = {
|
||||
mockTxDetails,
|
||||
mockDualValidation,
|
||||
mockDualOpData,
|
||||
mockInvalidSlpSend
|
||||
mockInvalidSlpSend,
|
||||
mockWhitelist,
|
||||
mockValidateTxid3Valid,
|
||||
mockValidateTxid3Invalid
|
||||
}
|
||||
|
||||
+12
-1
@@ -5,7 +5,7 @@ const sinon = require("sinon")
|
||||
const mockDataLib = require("./fixtures/price-mocks")
|
||||
let mockData
|
||||
|
||||
describe("#Price", () => {
|
||||
describe("#price", () => {
|
||||
let sandbox
|
||||
let bchjs
|
||||
|
||||
@@ -56,4 +56,15 @@ describe("#Price", () => {
|
||||
assert.property(result, "CAD")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getBchaUsd", () => {
|
||||
it("should get the USD price of BCHA", async () => {
|
||||
sandbox.stub(bchjs.Price.axios, "get").resolves({ data: { usd: 18.87 } })
|
||||
|
||||
const result = await bchjs.Price.getBchaUsd()
|
||||
// console.log(result)
|
||||
|
||||
assert.isNumber(result)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
+148
-2
@@ -2,10 +2,10 @@ const assert = require("assert")
|
||||
const assert2 = require("chai").assert
|
||||
|
||||
const SLP = require("../../src/slp/slp")
|
||||
//const slp = new SLP("http://decatur.hopto.org:12400/v3/")
|
||||
//const slp = new SLP("http://decatur.hopto.org:12400/v4/")
|
||||
//const slp = new SLP("https://rest.bitcoin.com/v2/")
|
||||
const slp = new SLP({
|
||||
restURL: "https://api.fullstack.cash/v3/",
|
||||
restURL: "https://api.fullstack.cash/v4/",
|
||||
apiToken: process.env.BCHJSTOKEN
|
||||
})
|
||||
|
||||
@@ -1944,4 +1944,150 @@ describe("#SLP Utils", () => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("#validateTxid", () => {
|
||||
it("should invalidate a known invalid TXID", async () => {
|
||||
const txid =
|
||||
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a"
|
||||
|
||||
// Mock live network calls.
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.mockValidateTxid3Invalid
|
||||
})
|
||||
|
||||
const result = await slp.Utils.validateTxid(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert2.isArray(result)
|
||||
|
||||
assert2.property(result[0], "txid")
|
||||
assert2.equal(result[0].txid, txid)
|
||||
|
||||
assert2.property(result[0], "valid")
|
||||
assert2.equal(result[0].valid, null)
|
||||
})
|
||||
/*
|
||||
it("should handle a mix of valid, invalid, and non-SLP txs", async () => {
|
||||
const txids = [
|
||||
// Malformed SLP tx
|
||||
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
|
||||
// Normal TX (non-SLP)
|
||||
"01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
|
||||
// Valid PSF SLP tx
|
||||
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
|
||||
// Valid SLP token not in whitelist
|
||||
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488"
|
||||
]
|
||||
|
||||
const result = await slp.Utils.validateTxid(txids)
|
||||
console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
})
|
||||
*/
|
||||
})
|
||||
|
||||
describe("#getWhitelist", () => {
|
||||
it("should return the list", async () => {
|
||||
sandbox.stub(axios, "get").resolves({ data: mockData.mockWhitelist })
|
||||
|
||||
const result = await slp.Utils.getWhitelist()
|
||||
|
||||
assert2.isArray(result)
|
||||
assert2.property(result[0], "name")
|
||||
assert2.property(result[1], "tokenId")
|
||||
})
|
||||
|
||||
it("catches and throws an error", async () => {
|
||||
try {
|
||||
sandbox.stub(axios, "get").rejects({
|
||||
error:
|
||||
"Network error: Could not communicate with full node or other external service."
|
||||
})
|
||||
|
||||
await slp.Utils.getWhitelist()
|
||||
|
||||
assert2.equal(true, false, "Unexpected result")
|
||||
} catch (err) {
|
||||
// console.log("err: ", err)
|
||||
assert2.include(err.error, "Network error")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("#validateTxid3", () => {
|
||||
it("should invalidate a known invalid TXID", async () => {
|
||||
const txid =
|
||||
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a"
|
||||
|
||||
// Mock live network calls.
|
||||
sandbox.stub(axios, "post").resolves({
|
||||
data: mockData.mockValidateTxid3Invalid
|
||||
})
|
||||
|
||||
const result = await slp.Utils.validateTxid3(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert2.isArray(result)
|
||||
|
||||
assert2.property(result[0], "txid")
|
||||
assert2.equal(result[0].txid, txid)
|
||||
|
||||
assert2.property(result[0], "valid")
|
||||
assert2.equal(result[0].valid, null)
|
||||
})
|
||||
|
||||
it("should handle an array with a single element", async () => {
|
||||
sandbox
|
||||
.stub(axios, "post")
|
||||
.resolves({ data: mockData.mockValidateTxid3Valid })
|
||||
|
||||
const txid = [
|
||||
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd"
|
||||
]
|
||||
|
||||
const result = await slp.Utils.validateTxid3(txid)
|
||||
|
||||
assert2.isArray(result)
|
||||
|
||||
assert2.property(result[0], "txid")
|
||||
assert2.equal(result[0].txid, txid)
|
||||
|
||||
assert2.property(result[0], "valid")
|
||||
assert2.equal(result[0].valid, true)
|
||||
})
|
||||
|
||||
it("should handle an single string input", async () => {
|
||||
sandbox
|
||||
.stub(axios, "post")
|
||||
.resolves({ data: mockData.mockValidateTxid3Valid })
|
||||
|
||||
const txid =
|
||||
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd"
|
||||
|
||||
const result = await slp.Utils.validateTxid3(txid)
|
||||
|
||||
assert2.isArray(result)
|
||||
|
||||
assert2.property(result[0], "txid")
|
||||
assert2.equal(result[0].txid, txid)
|
||||
|
||||
assert2.property(result[0], "valid")
|
||||
assert2.equal(result[0].valid, true)
|
||||
})
|
||||
|
||||
it("catches and throws an error", async () => {
|
||||
try {
|
||||
sandbox.stub(axios, "post").rejects({
|
||||
error:
|
||||
"Network error: Could not communicate with full node or other external service."
|
||||
})
|
||||
|
||||
await slp.Utils.validateTxid3()
|
||||
|
||||
assert2.equal(true, false, "Unexpected result")
|
||||
} catch (err) {
|
||||
// console.log("err: ", err)
|
||||
assert2.include(err.error, "Network error")
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user