Compare commits

...
13 Commits
27 changed files with 693 additions and 76 deletions
+9 -7
View File
@@ -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"
+1 -1
View File
@@ -6,7 +6,7 @@ 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
+1 -2
View File
@@ -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")
+36 -20
View File
@@ -29,26 +29,7 @@ class Price {
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(
@@ -140,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
+144 -11
View File
@@ -448,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
@@ -485,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);
@@ -525,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,9 +14,9 @@
const assert = require("chai").assert
// const RESTURL = `https://abc.fullstack.cash/v3/`
const RESTURL = `https://bchn.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 })
@@ -13,9 +13,9 @@ 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/`,
// restURL: `https://bchn.fullstack.cash/v4/`,
restURL: `https://abc.fullstack.cash/v4/`,
// restURL: `http://localhost:3000/v4/`,
authPass: PRO_PASS
})
+2 -2
View File
@@ -18,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
})
@@ -18,9 +18,9 @@ const JWT_TOKEN =
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/`,
// restURL: `https://bchn.fullstack.cash/v4/`,
restURL: `https:/abc.fullstack.cash/v4/`,
// restURL: `http://localhost:3000/v4/`,
apiToken: JWT_TOKEN
})
+3 -3
View File
@@ -14,9 +14,9 @@ const JWT_TOKEN =
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/`,
// restURL: `https://bchn.fullstack.cash/v4/`,
restURL: `https://abc.fullstack.cash/v4/`,
// restURL: `http://localhost:3000/v4/`,
apiToken: JWT_TOKEN
})
+9
View File
@@ -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()
+145
View File
@@ -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", () => {
+9
View File
@@ -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()
+2 -2
View File
@@ -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")
}
})
+88
View File
@@ -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", () => {
+2 -2
View File
@@ -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/
+2 -2
View File
@@ -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")
+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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 })
+1 -1
View File
@@ -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 })
+2 -2
View File
@@ -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.
+2 -2
View File
@@ -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 -1
View File
@@ -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
+2 -2
View File
@@ -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.
+60 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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")
}
})
})
})