Compare commits

..
9 Commits
45 changed files with 2783 additions and 3533 deletions
+709 -807
View File
File diff suppressed because it is too large Load Diff
+9 -13
View File
@@ -1,6 +1,6 @@
{
"name": "@psf/bch-js",
"version": "4.0.0",
"version": "3.4.0",
"description": "The FullStack.cash JavaScript library for Bitcoin Cash and SLP Tokens",
"author": "Chris Troutner <chris.troutner@gmail.com>",
"contributors": [
@@ -8,19 +8,16 @@
],
"main": "src/bch-js",
"scripts": {
"test": "nyc mocha --trace-warnings --unhandled-rejections=strict --timeout 30000 test/unit/",
"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/v4/ IS_USING_FREE_TIER=true mocha --timeout 30000 test/integration/",
"test:integration:abc": "RESTURL=https://abc.fullstack.cash/v3/ IS_USING_FREE_TIER=true mocha --timeout 30000 test/integration/",
"test:integration:testnet": "IS_USING_FREE_TIER=true mocha --timeout 30000 test/integration/testnet/",
"test:integration:local": "RESTURL=http://localhost:3000/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:integration:api": "RESTURL=https://api.fullstack.cash/v4/ mocha --timeout 30000 test/integration",
"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:temp4": "mocha --timeout=30000 -g '#tokenUtxoDetails' test/unit/",
"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",
"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"
@@ -85,13 +82,12 @@
"eslint-config-prettier": "^6.0.0",
"eslint-plugin-node": "^9.1.0",
"eslint-plugin-prettier": "^3.1.0",
"lodash.clonedeep": "^4.5.0",
"mocha": "^6.1.4",
"nock": "^10.0.6",
"node-mocks-http": "^1.7.0",
"nyc": "^14.1.0",
"prettier": "^1.18.2",
"semantic-release": "^17.3.0",
"semantic-release": "^15.13.19",
"sinon": "^7.3.2"
},
"apidoc": {
+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/v4/`
if (!config || !config.restURL) tmp.restURL = `https://api.bchjs.cash/v3/`
else tmp.restURL = config.restURL
this.restURL = tmp.restURL
+2 -2
View File
@@ -7,8 +7,8 @@
*/
// bch-api mainnet.
const DEFAULT_REST_API = "https://api.fullstack.cash/v4/"
// const DEFAULT_REST_API = "http://localhost:3000/v4/"
// const DEFAULT_REST_API = "https://api.bchjs.cash/v3/"
const DEFAULT_REST_API = "https://api.fullstack.cash/v3/"
// local deps
const BitcoinCash = require("./bitcoincash")
+84 -82
View File
@@ -68,34 +68,10 @@ class Ninsight {
*/
async utxo(address) {
try {
// Handle single address.
if (typeof address === "string") {
const response = await axios.post(
`${this.ninsightURL}/address/utxo`,
{
addresses: [address]
},
_this.axiosOptions
)
return response.data
// Handle array of addresses.
} else if (Array.isArray(address)) {
const response = await axios.post(
`${this.ninsightURL}/address/utxo`,
{
addresses: address
},
_this.axiosOptions
)
return response.data
}
throw new Error(`Input address must be a string or array of strings.`)
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
_this._validateParam(address)
return _this._callAxios(address, 'utxo')
} catch (e) {
_this._handleError(e)
}
}
@@ -137,32 +113,10 @@ class Ninsight {
*/
async unconfirmed(address) {
try {
if (typeof address === "string") {
const response = await axios.post(
`${this.ninsightURL}/address/unconfirmed`,
{
addresses: [address]
},
_this.axiosOptions
)
return response.data
} else if (Array.isArray(address)) {
const response = await axios.post(
`${this.ninsightURL}/address/unconfirmed`,
{
addresses: address
},
_this.axiosOptions
)
return response.data
}
throw new Error(`Input address must be a string or array of strings.`)
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
_this._validateParam(address)
return _this._callAxios(address, 'unconfirmed')
} catch (e) {
_this._handleError(e)
}
}
@@ -213,32 +167,10 @@ class Ninsight {
*/
async transactions(address) {
try {
if (typeof address === "string") {
const response = await axios.post(
`${this.ninsightURL}/address/transactions`,
{
addresses: [address]
},
_this.axiosOptions
)
return response.data
} else if (Array.isArray(address)) {
const response = await axios.post(
`${this.ninsightURL}/address/transactions`,
{
addresses: address
},
_this.axiosOptions
)
return response.data
}
throw new Error(`Input address must be a string or array of strings.`)
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
_this._validateParam(address)
return _this._callAxios(address, 'transactions')
} catch (e) {
_this._handleError(e)
}
}
@@ -288,7 +220,7 @@ class Ninsight {
try {
if (typeof txid === "string") {
const response = await axios.post(
`${this.ninsightURL}/transaction/details`,
`${_this.ninsightURL}/transaction/details`,
{
txids: [txid]
},
@@ -298,7 +230,7 @@ class Ninsight {
return response.data
} else if (Array.isArray(txid)) {
const response = await axios.post(
`${this.ninsightURL}/transaction/details`,
`${_this.ninsightURL}/transaction/details`,
{
txids: txid
},
@@ -314,6 +246,76 @@ class Ninsight {
else throw error
}
}
/**
* @api Ninsight.details() details()
* @apiName Ninsight Details
* @apiGroup Ninsight
* @apiDescription Return details of address.
*
* @apiExample Example usage:
* (async () => {
* try {
* let details = await bchjs.Ninsight.details('bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c');
* let details = await bchjs.Ninsight.details(['bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c','bitcoincash:qzs02v05l7qs5s24srqju498qu55dwuj0cx5ehjm2c']);
* console.log(details);
* } catch(error) {
* console.error(error)
* }
* })()
*
* // [
* // {
* //"balance": 0.00001,
* //"balanceSat": 1000,
* //"totalReceived": 0.00001,
* //"totalReceivedSat": 1000,
* //"totalSent": 0,
* //"totalSentSat": 0,
* //"unconfirmedBalance": 0,
* //"unconfirmedBalanceSat": 0,
* //"unconfirmedTxApperances": 0,
* //"txApperances": 1,
* //"transactions": [
* //"5f09d317e24c5d376f737a2711f3bd1d381abdb41743fff3819b4f76382e1eac" ],
* //"legacyAddress": "1FZrK8HohEKyKCTM24NkAzPnX9WD9Ujhw7",
* //"cashAddress": "bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr",
* //"slpAddress": "simpleledger:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ylynt40sa",
* //"currentPage": 0,
* //"pagesTotal": 1
* // }
* // ]
*
*/
async details(address) {
try {
_this._validateParam(address)
return _this._callAxios(address, 'details')
} catch (e) {
_this._handleError(e)
}
}
_validateParam(address) {
if (typeof address !== "string" && !Array.isArray(address))
throw new Error(`Input address must be a string or array of strings.`)
}
_handleError(error) {
if (error.response && error.response.data) throw error.response.data
else throw error
}
async _callAxios(address, type) {
const response = await axios.post(
`${_this.ninsightURL}/address/${type}`,
{
addresses: Array.isArray(address) ? address : [address]
},
_this.axiosOptions
)
//console.log(`SAMPLE: ${response.data}`);
return response.data
}
}
module.exports = Ninsight
+20 -36
View File
@@ -29,7 +29,26 @@ class Price {
this.axios = axios
}
// This endpoint is deprecated. Documentation removed.
/**
* @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
*/
async current(currency = "usd") {
try {
const response = await this.axios.get(
@@ -121,41 +140,6 @@ 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
+2 -5
View File
@@ -24,9 +24,6 @@ class RawTransactions {
}
}
// Encapsulate dependencies
this.axios = axios
_this = this
}
@@ -325,7 +322,7 @@ class RawTransactions {
try {
// Single tx hex.
if (typeof hex === "string") {
const response = await this.axios.get(
const response = await axios.get(
`${this.restURL}rawtransactions/sendRawTransaction/${hex}`,
_this.axiosOptions
)
@@ -350,7 +347,7 @@ class RawTransactions {
},
headers: _this.axiosOptions.headers
}
const response = await _this.axios(options)
const response = await axios(options)
return response.data
}
+37 -254
View File
@@ -1,4 +1,3 @@
// Public npm libraries
const axios = require("axios")
const slpParser = require("slp-parser")
@@ -15,7 +14,6 @@ class Utils {
this.apiToken = config.apiToken
this.slpParser = slpParser
this.authToken = config.authToken
this.axios = axios
if (this.authToken) {
// Add Basic Authentication token to the authorization header.
@@ -34,8 +32,6 @@ class Utils {
}
_this = this
this.whitelist = []
}
/**
@@ -197,7 +193,6 @@ class Utils {
async list(id) {
let path
let method
if (!id) {
method = "get"
path = `${this.restURL}slp/list`
@@ -214,9 +209,9 @@ class Utils {
try {
let response
if (method === "get") {
response = await _this.axios.get(path, _this.axiosOptions)
response = await axios.get(path, _this.axiosOptions)
} else {
response = await _this.axios.post(
response = await axios.post(
path,
{
tokenIds: id
@@ -312,7 +307,7 @@ class Utils {
if (typeof address === "string") {
const path = `${this.restURL}slp/balancesForAddress/${address}`
const response = await _this.axios.get(path, _this.axiosOptions)
const response = await axios.get(path, _this.axiosOptions)
return response.data
// Array of addresses.
@@ -320,7 +315,7 @@ class Utils {
const path = `${this.restURL}slp/balancesForAddress`
// Dev note: must use axios.post for unit test stubbing.
const response = await _this.axios.post(
const response = await axios.post(
path,
{
addresses: address
@@ -374,10 +369,10 @@ class Utils {
*/
// Retrieve token balances for a given tokenId.
async balancesForToken(tokenId) {
try {
const path = `${this.restURL}slp/balancesForToken/${tokenId}`
const path = `${this.restURL}slp/balancesForToken/${tokenId}`
const response = await _this.axios.get(path, _this.axiosOptions)
try {
const response = await axios.get(path, _this.axiosOptions)
return response.data
} catch (error) {
if (error.response && error.response.data) throw error.response.data
@@ -442,7 +437,7 @@ class Utils {
else txids = txid
try {
const response = await _this.axios.post(
const response = await axios.post(
path,
{
txids: txids
@@ -453,6 +448,16 @@ 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
@@ -480,7 +485,7 @@ class Utils {
* // validate single SLP txid
* (async () => {
* try {
* let validated = await bchjs.SLP.Utils.validateTxid2(
* let validated = await bchjs.SLP.Utils.validateTxid(
* "df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb"
* );
* console.log(validated);
@@ -508,7 +513,7 @@ class Utils {
const path = `${this.restURL}slp/validateTxid2/${txid}`
const response = await _this.axios.get(path, _this.axiosOptions)
const response = await axios.get(path, _this.axiosOptions)
return response.data
} catch (error) {
if (error.response && error.response.data) throw error.response.data
@@ -520,154 +525,6 @@ 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() {
try {
const path = `${this.restURL}slp/whitelist`
// Retrieve the whitelist from the REST API if we haven't gotten it yet.
if (this.whitelist.length === 0) {
const response = await _this.axios.get(path, _this.axiosOptions)
// console.log(`response.data: ${JSON.stringify(response.data, null, 2)}`)
this.whitelist = response.data
}
return this.whitelist
} 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 _this.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
@@ -704,11 +561,10 @@ class Utils {
* }
*/
async tokenStats(tokenId) {
const path = `${this.restURL}slp/tokenStats/${tokenId}`
try {
const path = `${this.restURL}slp/tokenStats/${tokenId}`
const response = await _this.axios.get(path, _this.axiosOptions)
const response = await axios.get(path, _this.axiosOptions)
return response.data
} catch (error) {
if (error.response && error.response.data) throw error.response.data
@@ -775,11 +631,10 @@ class Utils {
*/
// Retrieve token transactions for a given tokenId and address.
async transactions(tokenId, address) {
const path = `${this.restURL}slp/transactions/${tokenId}/${address}`
try {
const path = `${this.restURL}slp/transactions/${tokenId}/${address}`
const response = await _this.axios.get(path, _this.axiosOptions)
const response = await axios.get(path, _this.axiosOptions)
return response.data
} catch (error) {
if (error.response && error.response.data) throw error.response.data
@@ -815,11 +670,10 @@ class Utils {
* }
*/
async burnTotal(transactionId) {
const path = `${this.restURL}slp/burnTotal/${transactionId}`
try {
const path = `${this.restURL}slp/burnTotal/${transactionId}`
const response = await _this.axios.get(path, _this.axiosOptions)
const response = await axios.get(path, _this.axiosOptions)
return response.data
} catch (error) {
if (error.response && error.response.data) throw error.response.data
@@ -861,7 +715,7 @@ class Utils {
// console.log(`this.restURL: ${this.restURL}`)
const path = `${this.restURL}slp/txDetails/${txid}`
const response = await _this.axios.get(path, _this.axiosOptions)
const response = await axios.get(path, _this.axiosOptions)
return response.data
} catch (error) {
if (error.response && error.response.data) throw error.response.data
@@ -936,7 +790,7 @@ class Utils {
// Retrieve the transaction object from the full node.
const path = `${this.restURL}rawtransactions/getRawTransaction/${txid}?verbose=true`
const response = await _this.axios.get(path, _this.axiosOptions)
const response = await axios.get(path, _this.axiosOptions)
const txDetails = response.data
// console.log(`txDetails: ${JSON.stringify(txDetails, null, 2)}`)
@@ -1087,7 +941,6 @@ class Utils {
}
}
// Ensure the UTXO has a vout or tx_pos property.
if (!Number.isInteger(utxo.vout)) {
if (Number.isInteger(utxo.tx_pos)) {
utxo.vout = utxo.tx_pos
@@ -1122,13 +975,9 @@ class Utils {
if (
!err.message ||
(err.message.indexOf("scriptpubkey not op_return") === -1 &&
err.message.indexOf("lokad id") === -1 &&
err.message.indexOf("trailing data") === -1)
err.message.indexOf("lokad id") === -1)
) {
// console.log(
// `unknown error from decodeOpReturn(). Marking as 'null'`,
// err
// )
// console.log(`error from decodeOpReturn(${utxo.txid}): `, err)
utxo.isValid = null
outAry.push(utxo)
@@ -1137,7 +986,6 @@ class Utils {
// an SLP UTXO.
// Mark as false and continue the loop.
} else {
// console.log("marking as invalid")
utxo.isValid = false
outAry.push(utxo)
}
@@ -1281,81 +1129,16 @@ class Utils {
}
}
// *After* the UTXO has been hydrated with SLP data,
// validate the TXID with SLPDB.
// Finally, validate the SLP txid with SLPDB.
if (outAry[i].tokenType) {
// Only execute this block if the current UTXO has a 'tokenType'
// property. i.e. it has been successfully hydrated with SLP
// information.
// If the value has been cached, use the cached version first.
let isValid = cachedTxValidation[utxo.txid]
// If not in the cache, try the general SLPDB.
var isValid = cachedTxValidation[utxo.txid]
if (isValid == null) {
isValid = await this.validateTxid(utxo.txid)
isValid = isValid[0].valid
// Save the result to the local cache.
cachedTxValidation[utxo.txid] = isValid
}
// console.log(`isValid: ${JSON.stringify(isValid, null, 2)}`)
// If still null, check the whitelist SLPDB
if (isValid === null) {
// console.log(
// `checking against whitelist SLPDB. outAry[${i}]: ${JSON.stringify(
// outAry[i],
// null,
// 2
// )}`
// )
// Figure out if the token UTXO is in the whitelist.
let utxoInWhitelist = false
for (let j = 0; j < this.whitelist.length; j++) {
if (outAry[i].tokenId === this.whitelist[j].tokenId) {
utxoInWhitelist = true
break
}
}
// If the utxo.tokenId is in the whitelist, check the validity with
// the whitelist SLPDB. This should still be functioning properly
// if the general SLPDB is not.
if (utxoInWhitelist) {
isValid = await this.validateTxid3(utxo.txid)
// console.log(
// `whitelist-SLPDB for ${utxo.txid}: ${JSON.stringify(
// isValid,
// null,
// 2
// )}`
// )
isValid = isValid[0].valid
// Save the result to the local cache.
cachedTxValidation[utxo.txid] = isValid
}
}
// If still null, as a last resort, check it against slp-validate
if (isValid === null) {
isValid = await this.validateTxid2(utxo.txid)
// console.log(
// `slp-validate isValid: ${JSON.stringify(isValid, null, 2)}`
// )
isValid = isValid.isValid
// Save the result to the local cache.
cachedTxValidation[utxo.txid] = isValid
}
// console.log(`isValid: ${JSON.stringify(isValid, null, 2)}`)
outAry[i].isValid = isValid
outAry[i].isValid = isValid[0].valid
}
}
@@ -1536,7 +1319,7 @@ class Utils {
// Throw error if input is not an array.
if (!Array.isArray(utxos)) throw new Error("Input must be an array.")
const response = await _this.axios.post(
const response = await axios.post(
`${this.restURL}slp/hydrateUtxos`,
{
utxos: utxos
@@ -14,9 +14,9 @@
const assert = require("chai").assert
// const RESTURL = `https://abc.fullstack.cash/v4/`
const RESTURL = `https://bchn.fullstack.cash/v4/`
// const RESTURL = `http://localhost:3000/v4/`
// const RESTURL = `https://abc.fullstack.cash/v3/`
const RESTURL = `https://bchn.fullstack.cash/v3/`
// const RESTURL = `http://localhost:3000/v3/`
const BCHJS = require("../../../src/bch-js")
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/v4/`,
restURL: `https://abc.fullstack.cash/v4/`,
// restURL: `http://localhost:3000/v4/`,
// restURL: `https://bchn.fullstack.cash/v3/`,
restURL: `https://abc.fullstack.cash/v3/`,
// restURL: `http://localhost:3000/v3/`,
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/v4/`,
// restURL: `http://localhost:3000/v4/`,
restURL: `https://api.fullstack.cash/v3/`,
// restURL: `http://localhost:3000/v3/`,
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/v4/`,
restURL: `https:/abc.fullstack.cash/v4/`,
// restURL: `http://localhost:3000/v4/`,
// restURL: `https://bchn.fullstack.cash/v3/`,
restURL: `https:/abc.fullstack.cash/v3/`,
// restURL: `http://localhost:3000/v3/`,
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/v4/`,
restURL: `https://abc.fullstack.cash/v4/`,
// restURL: `http://localhost:3000/v4/`,
// restURL: `https://bchn.fullstack.cash/v3/`,
restURL: `https://abc.fullstack.cash/v3/`,
// restURL: `http://localhost:3000/v3/`,
apiToken: JWT_TOKEN
})
+87
View File
@@ -126,4 +126,91 @@ describe(`#Ninsight`, () => {
assert.property(result[0], "vout")
})
})
describe(`#detailsAddress`, () => {
it(`should throw an error for improper input`, async () => {
try {
const addr = 12345
await bchjs.Ninsight.details(addr)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
//console.log(`err: `, err)
assert.include(
err.message,
`Input address must be a string or array of strings.`
)
}
})
it(`should POST address details for a single address`, async () => {
const addr = "bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7"
const result = await bchjs.Ninsight.details(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.property(result[0], "balance")
assert.property(result[0], "balanceSat")
assert.property(result[0], "totalReceived")
assert.property(result[0], "totalReceivedSat")
assert.property(result[0], "totalSent")
assert.property(result[0], "totalSentSat")
assert.property(result[0], "unconfirmedBalance")
assert.property(result[0], "unconfirmedBalanceSat")
assert.property(result[0], "unconfirmedTxApperances")
assert.property(result[0], "txApperances")
assert.property(result[0], "transactions")
assert.property(result[0], "legacyAddress")
assert.property(result[0], "cashAddress")
assert.property(result[0], "slpAddress")
assert.property(result[0], "currentPage")
assert.property(result[0], "pagesTotal")
})
it(`should POST address details for an array of addresses`, async () => {
const addr = [
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
"bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr"
]
const result = await bchjs.Ninsight.details(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.property(result[0], "balance")
assert.property(result[0], "balanceSat")
assert.property(result[0], "totalReceived")
assert.property(result[0], "totalReceivedSat")
assert.property(result[0], "totalSent")
assert.property(result[0], "totalSentSat")
assert.property(result[0], "unconfirmedBalance")
assert.property(result[0], "unconfirmedBalanceSat")
assert.property(result[0], "unconfirmedTxApperances")
assert.property(result[0], "txApperances")
assert.property(result[0], "transactions")
assert.property(result[0], "legacyAddress")
assert.property(result[1], "cashAddress")
assert.property(result[1], "slpAddress")
assert.property(result[1], "currentPage")
assert.property(result[1], "pagesTotal")
/*
If in any way possible, I would like to refactor this test
according to the DRY principle to share it with the integration tests too
Would that make sense or does that implicate anything unwanted?
assertDetails(result[0])
assertDetails(data) {
assert.property(data, "balance")
assert.property(data, "balanceSat")
assert.property(data, "totalReceived")
assert.property(data, "totalReceivedSat")
assert.property(data, "totalSent")
assert.property(data, "totalSentSat")
}
*/
})
})
})
-9
View File
@@ -21,15 +21,6 @@ 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()
+1 -265
View File
@@ -35,7 +35,7 @@ describe(`#SLP`, () => {
const tokenId = `4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf`
const result = await bchjs.SLP.Utils.list(tokenId)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.hasAnyKeys(result, [
"decimals",
@@ -60,34 +60,6 @@ describe(`#SLP`, () => {
"mintingBatonStatus"
])
})
it("should NOT get a list of all tokens in existence", async () => {
try {
await bchjs.SLP.Utils.list()
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.fail("Unexpected result!")
} catch (err) {
// console.log(err)
assert.include(err.message, "Not Found")
}
})
it("should get information on multiple tokens", async () => {
const tokenIds = [
// Spice
`4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf`,
// PSF
"38e97c5d7d3585a2cbf3f9580c82ca33985f9cb0845d4dcce220cb709f9538b0"
]
const result = await bchjs.SLP.Utils.list(tokenIds)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.equal(result[0].symbol, "SPICE")
assert.equal(result[1].symbol, "PSF")
})
})
// describe("#decodeOpReturn", () => {
@@ -491,98 +463,6 @@ describe(`#SLP`, () => {
assert.equal(data[0].isValid, false)
})
it("should handle a range of UTXO types", async () => {
const utxos = [
// Malformed SLP tx
{
note: "Malformed SLP tx",
tx_hash:
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
tx_pos: 1,
value: 546
},
// Normal TX (non-SLP)
{
note: "Normal TX (non-SLP)",
tx_hash:
"01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
tx_pos: 0,
value: 400000
},
// Valid PSF SLP tx
{
note: "Valid PSF SLP tx",
tx_hash:
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
tx_pos: 1,
value: 546
},
// Valid SLP token not in whitelist
{
note: "Valid SLP token not in whitelist",
tx_hash:
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
tx_pos: 1,
value: 546
},
// Token send on BCHN network.
{
note: "Token send on BCHN network",
tx_hash:
"402c663379d9699b6e2dd38737061e5888c5a49fca77c97ab98e79e08959e019",
tx_pos: 1,
value: 546
},
// Token send on ABC network.
{
note: "Token send on ABC network",
tx_hash:
"336bfe2168aac4c3303508a9e8548a0d33797a83b85b76a12d845c8d6674f79d",
tx_pos: 1,
value: 546
},
// Known invalid SLP token send of PSF tokens.
{
note: "Known invalid SLP token send of PSF tokens",
tx_hash:
"2bf691ad3679d928fef880b8a45b93b233f8fa0d0a92cf792313dbe77b1deb74",
tx_pos: 1,
value: 546
}
]
const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
// Malformed SLP tx
assert.equal(data[0].tx_hash, utxos[0].tx_hash)
assert.equal(data[0].isValid, false)
// Normal TX (non-SLP)
assert.equal(data[1].tx_hash, utxos[1].tx_hash)
assert.equal(data[1].isValid, false)
// Valid PSF SLP tx
assert.equal(data[2].tx_hash, utxos[2].tx_hash)
assert.equal(data[2].isValid, true)
// Valid SLP token not in whitelist
assert.equal(data[3].tx_hash, utxos[3].tx_hash)
assert.equal(data[3].isValid, true)
// Token send on BCHN network
assert.equal(data[4].tx_hash, utxos[4].tx_hash)
assert.equal(data[4].isValid, true)
// Token send on ABC network
assert.equal(data[5].tx_hash, utxos[5].tx_hash)
assert.equal(data[5].isValid, null)
// Known invalid SLP token send of PSF tokens
assert.equal(data[6].tx_hash, utxos[6].tx_hash)
assert.equal(data[6].isValid, false)
})
})
describe("#balancesForAddress", () => {
@@ -783,150 +663,6 @@ 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)
assert.equal(result[4].txid, txids[4])
assert.equal(result[4].valid, true)
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", () => {
+88 -1
View File
@@ -3,7 +3,9 @@ const assert = chai.assert
const sinon = require("sinon")
const BCHJS = require("../../src/bch-js")
const bchjs = new BCHJS({ ninsightURL: "https://rest.bitcoin.com/v2" })
const bchjs = new BCHJS({
ninsightURL: "https://rest.bitcoin.com/v2"
})
describe(`#Ninsight`, () => {
let sandbox
@@ -131,6 +133,91 @@ describe(`#Ninsight`, () => {
assert.property(result[0], "vout")
})
})
describe(`#detailsAddress`, () => {
it(`should throw an error for improper input`, async () => {
try {
const addr = 12345
await bchjs.Ninsight.details(addr)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
//console.log(`err: `, err)
assert.include(
err.message,
`Input address must be a string or array of strings.`
)
}
})
it(`should POST address details for a single address`, async () => {
const addr = "bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7"
const result = await bchjs.Ninsight.details(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.property(result[0], "balance")
assert.property(result[0], "balanceSat")
assert.property(result[0], "totalReceived")
assert.property(result[0], "totalReceivedSat")
assert.property(result[0], "totalSent")
assert.property(result[0], "totalSentSat")
assert.property(result[0], "unconfirmedBalance")
assert.property(result[0], "unconfirmedBalanceSat")
assert.property(result[0], "unconfirmedTxApperances")
assert.property(result[0], "txApperances")
assert.property(result[0], "transactions")
assert.property(result[0], "legacyAddress")
assert.property(result[0], "cashAddress")
assert.property(result[0], "slpAddress")
assert.property(result[0], "currentPage")
assert.property(result[0], "pagesTotal")
})
it(`should POST address details for an array of addresses`, async () => {
const addr = [
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
"bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr"
]
const result = await bchjs.Ninsight.details(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.property(result[0], "balance")
assert.property(result[0], "balanceSat")
assert.property(result[0], "totalReceived")
assert.property(result[0], "totalReceivedSat")
assert.property(result[0], "totalSent")
assert.property(result[0], "totalSentSat")
assert.property(result[0], "unconfirmedBalance")
assert.property(result[0], "unconfirmedBalanceSat")
assert.property(result[0], "unconfirmedTxApperances")
assert.property(result[0], "txApperances")
assert.property(result[0], "transactions")
assert.property(result[0], "legacyAddress")
assert.property(result[1], "cashAddress")
assert.property(result[1], "slpAddress")
assert.property(result[1], "currentPage")
assert.property(result[1], "pagesTotal")
/*
If in any way possible, I would like to refactor this test
according to the DRY principle to share it with the integration tests too
Would that make sense or does that implicate anything unwanted?
assertDetails(result[0])
assertDetails(data) {
assert.property(data, "balance")
assert.property(data, "balanceSat")
assert.property(data, "totalReceived")
assert.property(data, "totalReceivedSat")
assert.property(data, "totalSent")
assert.property(data, "totalSentSat")
}
*/
})
})
})
function sleep(ms) {
-9
View File
@@ -25,15 +25,6 @@ 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")
assert.include(err.error, "bad-txns-inputs-missingorspent (code 16)")
}
})
@@ -261,7 +261,7 @@ describe("#rawtransaction", () => {
// console.log(`err: ${util.inspect(err)}`)
assert.hasAllKeys(err, ["error"])
assert.include(err.error, "bad-txns-inputs-missingorspent")
assert.include(err.error, "bad-txns-inputs-missingorspent (code 16)")
}
})
-180
View File
@@ -463,98 +463,6 @@ describe(`#SLP`, () => {
assert.equal(data[0].isValid, false)
})
it("should handle a range of UTXO types", async () => {
const utxos = [
// Malformed SLP tx
{
note: "Malformed SLP tx",
tx_hash:
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
tx_pos: 1,
value: 546
},
// Normal TX (non-SLP)
{
note: "Normal TX (non-SLP)",
tx_hash:
"01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
tx_pos: 0,
value: 400000
},
// Valid PSF SLP tx
{
note: "Valid PSF SLP tx",
tx_hash:
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
tx_pos: 1,
value: 546
},
// Valid SLP token not in whitelist
{
note: "Valid SLP token not in whitelist",
tx_hash:
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
tx_pos: 1,
value: 546
},
// Token send on BCHN network.
{
note: "Token send on BCHN network",
tx_hash:
"402c663379d9699b6e2dd38737061e5888c5a49fca77c97ab98e79e08959e019",
tx_pos: 1,
value: 546
},
// Token send on ABC network.
{
note: "Token send on ABC network",
tx_hash:
"336bfe2168aac4c3303508a9e8548a0d33797a83b85b76a12d845c8d6674f79d",
tx_pos: 1,
value: 546
},
// Known invalid SLP token send of PSF tokens.
{
note: "Known invalid SLP token send of PSF tokens",
tx_hash:
"2bf691ad3679d928fef880b8a45b93b233f8fa0d0a92cf792313dbe77b1deb74",
tx_pos: 1,
value: 546
}
]
const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
// Malformed SLP tx
assert.equal(data[0].tx_hash, utxos[0].tx_hash)
assert.equal(data[0].isValid, false)
// Normal TX (non-SLP)
assert.equal(data[1].tx_hash, utxos[1].tx_hash)
assert.equal(data[1].isValid, false)
// Valid PSF SLP tx
assert.equal(data[2].tx_hash, utxos[2].tx_hash)
assert.equal(data[2].isValid, true)
// Valid SLP token not in whitelist
assert.equal(data[3].tx_hash, utxos[3].tx_hash)
assert.equal(data[3].isValid, true)
// Token send on BCHN network
assert.equal(data[4].tx_hash, utxos[4].tx_hash)
assert.equal(data[4].isValid, null)
// Token send on ABC network
assert.equal(data[5].tx_hash, utxos[5].tx_hash)
assert.equal(data[5].isValid, true)
// Known invalid SLP token send of PSF tokens
assert.equal(data[6].tx_hash, utxos[6].tx_hash)
assert.equal(data[6].isValid, false)
})
})
describe("#balancesForAddress", () => {
@@ -726,94 +634,6 @@ 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 -3
View File
@@ -1,9 +1,8 @@
#!/bin/bash
# export RESTURL=https://bchn.fullstack.cash/v4/
#export RESTURL=http://localhost:3000/v4/
export RESTURL=https://bchn.fullstack.cash/v3/
#export RESTURL=http://localhost:3000/v3/
#export IS_USING_FREE_TIER=true
cd test/integration/bchn/
mocha --timeout 30000 blockchain.js control.js encryption.js electrumx.js ninsight.js openbazaar.js price.js rawtransaction.js slp.js util.js
#mocha --timeout 30000 slp.js
+2 -2
View File
@@ -8,11 +8,11 @@ const assert = chai.assert
const RESTURL = process.env.RESTURL
? process.env.RESTURL
: `https://testnet3.fullstack.cash/v4/`
: `https://testnet3.fullstack.cash/v3/`
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
const BCHJS = require("../../../src/bch-js")
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v4/` })
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v3/` })
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/v4/"
: "https://testnet3.fullstack.cash/v3/"
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
const BCHJS = require("../../../src/bch-js")
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v4/` })
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v3/` })
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/v4/`
: `https://testnet3.fullstack.cash/v3/`
const BCHJS = require("../../../src/bch-js")
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
+1 -1
View File
@@ -4,7 +4,7 @@ const sinon = require("sinon")
const RESTURL = process.env.RESTURL
? process.env.RESTURL
: `https://testnet3.fullstack.cash/v4/`
: `https://testnet3.fullstack.cash/v3/`
const BCHJS = require("../../../src/bch-js")
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
+89 -1
View File
@@ -3,7 +3,9 @@ const assert = chai.assert
const sinon = require("sinon")
const BCHJS = require("../../../src/bch-js")
const bchjs = new BCHJS({ ninsightURL: "https://trest.bitcoin.com/v2" })
const bchjs = new BCHJS({
ninsightURL: "https://trest.bitcoin.com/v2"
})
describe(`#Ninsight`, () => {
let sandbox
@@ -139,6 +141,92 @@ describe(`#Ninsight`, () => {
assert.property(result[0], "vout")
})
})
describe(`#detailsAddress`, () => {
it(`should throw an error for improper input`, async () => {
try {
const addr = 12345
await bchjs.Ninsight.details(addr)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
//console.log(`err: `, err)
assert.include(
err.message,
`Input address must be a string or array of strings.`
)
}
})
it(`should POST address details for a single address`, async () => {
const addr = "bchtest:qzjtnzcvzxx7s0na88yrg3zl28wwvfp97538sgrrmr"
const result = await bchjs.Ninsight.details(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.property(result[0], "balance")
assert.property(result[0], "balanceSat")
assert.property(result[0], "totalReceived")
assert.property(result[0], "totalReceivedSat")
assert.property(result[0], "totalSent")
assert.property(result[0], "totalSentSat")
assert.property(result[0], "unconfirmedBalance")
assert.property(result[0], "unconfirmedBalanceSat")
assert.property(result[0], "unconfirmedTxApperances")
assert.property(result[0], "txApperances")
assert.property(result[0], "transactions")
assert.property(result[0], "legacyAddress")
assert.property(result[0], "cashAddress")
assert.property(result[0], "slpAddress")
assert.property(result[0], "currentPage")
assert.property(result[0], "pagesTotal")
})
it(`should POST address details for an array of addresses`, async () => {
const addr = [
"bchtest:qzjtnzcvzxx7s0na88yrg3zl28wwvfp97538sgrrmr",
"bchtest:qp6hgvevf4gzz6l7pgcte3gaaud9km0l459fa23dul"
]
const result = await bchjs.Ninsight.details(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.property(result[0], "balance")
assert.property(result[0], "balanceSat")
assert.property(result[0], "totalReceived")
assert.property(result[0], "totalReceivedSat")
assert.property(result[0], "totalSent")
assert.property(result[0], "totalSentSat")
assert.property(result[0], "unconfirmedBalance")
assert.property(result[0], "unconfirmedBalanceSat")
assert.property(result[0], "unconfirmedTxApperances")
assert.property(result[0], "txApperances")
assert.property(result[0], "transactions")
assert.property(result[0], "legacyAddress")
assert.property(result[1], "cashAddress")
assert.property(result[1], "slpAddress")
assert.property(result[1], "currentPage")
assert.property(result[1], "pagesTotal")
/*
If in any way possible, I would like to refactor this test
according to the DRY principle to share it with the integration tests too
Would that make sense or does that implicate anything unwanted?
assertDetails(result[0])
assertDetails(data) {
assert.property(data, "balance")
assert.property(data, "balanceSat")
assert.property(data, "totalReceived")
assert.property(data, "totalReceivedSat")
assert.property(data, "totalSent")
assert.property(data, "totalSentSat")
}
*/
})
})
})
function sleep(ms) {
+2 -2
View File
@@ -10,11 +10,11 @@ const assert = chai.assert
const RESTURL = process.env.RESTURL
? process.env.RESTURL
: `https://testnet3.fullstack.cash/v4/`
: `https://testnet3.fullstack.cash/v3/`
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
const BCHJS = require("../../../src/bch-js")
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v4/` })
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v3/` })
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/v4/`
: `https://testnet3.fullstack.cash/v3/`
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
const BCHJS = require("../../../src/bch-js")
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v4/` })
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v3/` })
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/v4/
export RESTURL=https://free-test.fullstack.cash/v3/
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/v4/`
: `https://testnet3.fullstack.cash/v3/`
// if (process.env.RESTURL) RESTURL = process.env.RESTURL
const BCHJS = require("../../../src/bch-js")
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v4/` })
// const bchjs = new BCHJS({ restURL: `https://testnet.bchjs.cash/v3/` })
const bchjs = new BCHJS({ restURL: RESTURL, apiToken: process.env.BCHJSTOKEN })
// Inspect utility used for debugging.
+773 -803
View File
File diff suppressed because it is too large Load Diff
+37 -37
View File
@@ -1,13 +1,7 @@
// Public npm libraries
const assert = require("assert")
// Mocks
const fixtures = require("./fixtures/bitcoincash.json")
// Unit under test (uut)
const assert = require("assert")
const BCHJS = require("../../src/bch-js")
// const bchjs = new BCHJS()
let bchjs
const bchjs = new BCHJS()
// TODO
// 1. generate testnet p2sh
@@ -26,26 +20,28 @@ let bchjs
// 6. More error test cases.
describe("#BitcoinCash", () => {
beforeEach(() => {
bchjs = new BCHJS()
})
describe("price conversion", () => {
it("should exercise toBitcoinCash", () => {
describe("#toBitcoinCash", () => {
fixtures.conversion.toBCH.satoshis.forEach(satoshi => {
it(`should convert ${satoshi[0]} Satoshis to ${satoshi[1]} $BCH`, () => {
it(`should convert ${satoshi[0]} Satoshis to ${
satoshi[1]
} $BCH`, () => {
assert.equal(bchjs.BitcoinCash.toBitcoinCash(satoshi[0]), satoshi[1])
})
})
fixtures.conversion.toBCH.strings.forEach(satoshi => {
it(`should convert "${satoshi[0]}" Satoshis as a string to ${satoshi[1]} $BCH`, () => {
it(`should convert "${satoshi[0]}" Satoshis as a string to ${
satoshi[1]
} $BCH`, () => {
assert.equal(bchjs.BitcoinCash.toBitcoinCash(satoshi[0]), satoshi[1])
})
})
fixtures.conversion.toBCH.not.forEach(bch => {
it(`converts ${bch[0]} to Bitcoin Cash, not to ${bch[1]} Satoshi`, () => {
it(`converts ${bch[0]} to Bitcoin Cash, not to ${
bch[1]
} Satoshi`, () => {
assert.notEqual(bchjs.BitcoinCash.toBitcoinCash(bch[0]), bch[1])
})
})
@@ -57,7 +53,7 @@ describe("#BitcoinCash", () => {
})
})
it("should exercise toSatoshi", () => {
describe("#toSatoshi", () => {
fixtures.conversion.toSatoshi.bch.forEach(bch => {
it(`should convert ${bch[0]} $BCH to ${bch[1]} Satoshis`, () => {
assert.equal(bchjs.BitcoinCash.toSatoshi(bch[0]), bch[1])
@@ -65,13 +61,17 @@ describe("#BitcoinCash", () => {
})
fixtures.conversion.toSatoshi.strings.forEach(bch => {
it(`should convert "${bch[0]}" $BCH as a string to ${bch[1]} Satoshis`, () => {
it(`should convert "${bch[0]}" $BCH as a string to ${
bch[1]
} Satoshis`, () => {
assert.equal(bchjs.BitcoinCash.toSatoshi(bch[0]), bch[1])
})
})
fixtures.conversion.toSatoshi.not.forEach(satoshi => {
it(`converts ${satoshi[0]} to Satoshi, not to ${satoshi[1]} Bitcoin Cash`, () => {
it(`converts ${satoshi[0]} to Satoshi, not to ${
satoshi[1]
} Bitcoin Cash`, () => {
assert.notEqual(bchjs.BitcoinCash.toSatoshi(satoshi[0]), satoshi[1])
})
})
@@ -83,7 +83,7 @@ describe("#BitcoinCash", () => {
})
})
it("should exercise satsToBits", () => {
describe("#satsToBits", () => {
fixtures.conversion.satsToBits.bch.forEach(bch => {
it(`should convert ${bch[0]} BCH to ${bch[1]} bits`, () => {
assert.equal(
@@ -94,7 +94,9 @@ describe("#BitcoinCash", () => {
})
fixtures.conversion.satsToBits.strings.forEach(bch => {
it(`should convert "${bch[0]}" BCH as a string to ${bch[1]} bits`, () => {
it(`should convert "${bch[0]}" BCH as a string to ${
bch[1]
} bits`, () => {
assert.equal(
bchjs.BitcoinCash.satsToBits(bchjs.BitcoinCash.toSatoshi(bch[0])),
bch[1]
@@ -119,7 +121,7 @@ describe("#BitcoinCash", () => {
})
describe("sign and verify messages", () => {
it("should exercise signMessageWithPrivKey", () => {
describe("#signMessageWithPrivKey", () => {
fixtures.signatures.sign.forEach(sign => {
it(`should sign a message w/ ${sign.network} ${sign.privateKeyWIF}`, () => {
const privateKeyWIF = sign.privateKeyWIF
@@ -133,7 +135,7 @@ describe("#BitcoinCash", () => {
})
})
it("shoudl exercise verifyMessage", () => {
describe("#verifyMessage", () => {
fixtures.signatures.verify.forEach(sign => {
it(`should verify a valid signed message from ${sign.network} cashaddr address ${sign.address}`, () => {
assert.equal(
@@ -147,24 +149,22 @@ describe("#BitcoinCash", () => {
})
})
it("should verify legacy addresses", () => {
fixtures.signatures.verify.forEach(sign => {
const legacyAddress = bchjs.Address.toLegacyAddress(sign.address)
it(`should verify a valid signed message from ${sign.network} legacy address ${legacyAddress}`, () => {
assert.equal(
bchjs.BitcoinCash.verifyMessage(
legacyAddress,
sign.signature,
sign.message
),
true
)
})
fixtures.signatures.verify.forEach(sign => {
const legacyAddress = bchjs.Address.toLegacyAddress(sign.address)
it(`should verify a valid signed message from ${sign.network} legacy address ${legacyAddress}`, () => {
assert.equal(
bchjs.BitcoinCash.verifyMessage(
legacyAddress,
sign.signature,
sign.message
),
true
)
})
})
fixtures.signatures.verify.forEach(sign => {
// const legacyAddress = bchjs.Address.toLegacyAddress(sign.address)
const legacyAddress = bchjs.Address.toLegacyAddress(sign.address)
it(`should not verify an invalid signed message from ${sign.network} cashaddr address ${sign.address}`, () => {
assert.equal(
bchjs.BitcoinCash.verifyMessage(
+4 -11
View File
@@ -1,20 +1,13 @@
// Public npm libraries.
const assert = require("assert")
const BCHJS = require("../../src/bch-js")
const bchjs = new BCHJS()
const Buffer = require("safe-buffer").Buffer
// Mocks
const fixtures = require("./fixtures/ecpair.json")
// Unit under test (uut)
const BCHJS = require("../../src/bch-js")
// const bchjs = new BCHJS()
let bchjs
describe("#ECPair", () => {
beforeEach(() => {
bchjs = new BCHJS()
})
describe("#fromWIF", () => {
fixtures.fromWIF.forEach(fixture => {
it(`should create ECPair from WIF ${fixture.privateKeyWIF}`, () => {
+27 -1
View File
@@ -158,6 +158,30 @@ const details = {
const detailsPost = [details, details]
const addrDetail =
{
"balance": 0.00001,
"balanceSat": 1000,
"totalReceived": 0.00001,
"totalReceivedSat": 1000,
"totalSent": 0,
"totalSentSat": 0,
"unconfirmedBalance": 0,
"unconfirmedBalanceSat": 0,
"unconfirmedTxApperances": 0,
"txApperances": 1,
"transactions": [
"5f09d317e24c5d376f737a2711f3bd1d381abdb41743fff3819b4f76382e1eac"
],
"legacyAddress": "1FZrK8HohEKyKCTM24NkAzPnX9WD9Ujhw7",
"cashAddress": "bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr",
"slpAddress": "simpleledger:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ylynt40sa",
"currentPage": 0,
"pagesTotal": 1
}
const addrDetailArray = [addrDetail, addrDetail]
module.exports = {
utxo,
utxoPost,
@@ -166,5 +190,7 @@ module.exports = {
transactions,
transactionsPost,
details,
detailsPost
detailsPost,
addrDetail,
addrDetailArray
}
+1 -88
View File
@@ -1107,89 +1107,6 @@ 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
}
]
const whitelist = [
{
name: "USDH",
tokenId: "c4b0d62156b3fa5c8f3436079b5394f7edc1bef5dc1cd2f9d0c4d46f82cca479"
},
{
name: "SPICE",
tokenId: "4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf"
},
{
name: "PSF",
tokenId: "38e97c5d7d3585a2cbf3f9580c82ca33985f9cb0845d4dcce220cb709f9538b0"
},
{
name: "TROUT",
tokenId: "a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2"
},
{
name: "PSFTEST",
tokenId: "d0ef4de95b78222bfee2326ab11382f4439aa0855936e2fe6ac129a8d778baa0"
},
{
name: "TOK-CH",
tokenId: "497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7"
}
]
module.exports = {
mockList,
mockToken,
@@ -1214,9 +1131,5 @@ module.exports = {
mockTxDetails,
mockDualValidation,
mockDualOpData,
mockInvalidSlpSend,
mockWhitelist,
mockValidateTxid3Valid,
mockValidateTxid3Invalid,
whitelist
mockInvalidSlpSend
}
+2 -10
View File
@@ -1,18 +1,10 @@
// Public npm libraries
const assert = require("assert")
const axios = require("axios")
const BCHJS = require("../../src/bch-js")
const bchjs = new BCHJS()
const sinon = require("sinon")
// Unit under test (uut)
const BCHJS = require("../../src/bch-js")
// const bchjs = new BCHJS()
let bchjs
describe("#Generating", () => {
beforeEach(() => {
bchjs = new BCHJS()
})
describe("#generateToAddress", () => {
let sandbox
beforeEach(() => (sandbox = sinon.createSandbox()))
+48 -61
View File
@@ -1,20 +1,11 @@
// Public npm libraries
const assert = require("assert")
const Buffer = require("safe-buffer").Buffer
// Mocks
const fixtures = require("./fixtures/hdnode.json")
const slpFixtures = require("./fixtures/slp/address.json")
// Unit under test (uut)
const assert = require("assert")
const BCHJS = require("../../src/bch-js")
let bchjs
const bchjs = new BCHJS()
const Buffer = require("safe-buffer").Buffer
describe("#HDNode", () => {
beforeEach(() => {
bchjs = new BCHJS()
})
describe("#fromSeed", () => {
fixtures.fromSeed.forEach(mnemonic => {
it(`should create an HDNode from root seed buffer`, async () => {
@@ -187,75 +178,71 @@ describe("#HDNode", () => {
})
describe("#fromXPriv", () => {
it("should exercise fromXPriv", () => {
fixtures.fromXPriv.forEach(fixture => {
const hdNode = bchjs.HDNode.fromXPriv(fixture.xpriv)
it(`should create HDNode from xpriv ${fixture.xpriv}`, () => {
assert.notEqual(hdNode, null)
})
fixtures.fromXPriv.forEach(fixture => {
const hdNode = bchjs.HDNode.fromXPriv(fixture.xpriv)
it(`should create HDNode from xpriv ${fixture.xpriv}`, () => {
assert.notEqual(hdNode, null)
})
it(`should export xpriv ${fixture.xpriv}`, () => {
assert.equal(bchjs.HDNode.toXPriv(hdNode), fixture.xpriv)
})
it(`should export xpriv ${fixture.xpriv}`, () => {
assert.equal(bchjs.HDNode.toXPriv(hdNode), fixture.xpriv)
})
it(`should export xpub ${fixture.xpub}`, () => {
assert.equal(bchjs.HDNode.toXPub(hdNode), fixture.xpub)
})
it(`should export xpub ${fixture.xpub}`, () => {
assert.equal(bchjs.HDNode.toXPub(hdNode), fixture.xpub)
})
it(`should export legacy address ${fixture.legacy}`, () => {
assert.equal(bchjs.HDNode.toLegacyAddress(hdNode), fixture.legacy)
})
it(`should export legacy address ${fixture.legacy}`, () => {
assert.equal(bchjs.HDNode.toLegacyAddress(hdNode), fixture.legacy)
})
it(`should export cashaddress ${fixture.cashaddress}`, () => {
assert.equal(bchjs.HDNode.toCashAddress(hdNode), fixture.cashaddress)
})
it(`should export cashaddress ${fixture.cashaddress}`, () => {
assert.equal(bchjs.HDNode.toCashAddress(hdNode), fixture.cashaddress)
})
it(`should export regtest cashaddress ${fixture.regtestaddress}`, () => {
assert.equal(
bchjs.HDNode.toCashAddress(hdNode, true),
fixture.regtestaddress
)
})
it(`should export regtest cashaddress ${fixture.regtestaddress}`, () => {
assert.equal(
bchjs.HDNode.toCashAddress(hdNode, true),
fixture.regtestaddress
)
})
it(`should export privateKeyWIF ${fixture.privateKeyWIF}`, () => {
assert.equal(bchjs.HDNode.toWIF(hdNode), fixture.privateKeyWIF)
})
it(`should export privateKeyWIF ${fixture.privateKeyWIF}`, () => {
assert.equal(bchjs.HDNode.toWIF(hdNode), fixture.privateKeyWIF)
})
})
})
describe("#fromXPub", () => {
it("should exercise fromXPub", () => {
fixtures.fromXPub.forEach(fixture => {
const hdNode = bchjs.HDNode.fromXPub(fixture.xpub)
it(`should create HDNode from xpub ${fixture.xpub}`, () => {
assert.notEqual(hdNode, null)
})
fixtures.fromXPub.forEach(fixture => {
const hdNode = bchjs.HDNode.fromXPub(fixture.xpub)
it(`should create HDNode from xpub ${fixture.xpub}`, () => {
assert.notEqual(hdNode, null)
})
it(`should export xpub ${fixture.xpub}`, () => {
assert.equal(bchjs.HDNode.toXPub(hdNode), fixture.xpub)
})
it(`should export xpub ${fixture.xpub}`, () => {
assert.equal(bchjs.HDNode.toXPub(hdNode), fixture.xpub)
})
it(`should export legacy address ${fixture.legacy}`, () => {
assert.equal(bchjs.HDNode.toLegacyAddress(hdNode), fixture.legacy)
})
it(`should export legacy address ${fixture.legacy}`, () => {
assert.equal(bchjs.HDNode.toLegacyAddress(hdNode), fixture.legacy)
})
it(`should export cashaddress ${fixture.cashaddress}`, () => {
assert.equal(bchjs.HDNode.toCashAddress(hdNode), fixture.cashaddress)
})
it(`should export cashaddress ${fixture.cashaddress}`, () => {
assert.equal(bchjs.HDNode.toCashAddress(hdNode), fixture.cashaddress)
})
it(`should export regtest cashaddress ${fixture.regtestaddress}`, () => {
assert.equal(
bchjs.HDNode.toCashAddress(hdNode, true),
fixture.regtestaddress
)
})
it(`should export regtest cashaddress ${fixture.regtestaddress}`, () => {
assert.equal(
bchjs.HDNode.toCashAddress(hdNode, true),
fixture.regtestaddress
)
})
})
})
describe("#bip32", () => {
it("should create accounts and addresses", () => {
describe("create accounts and addresses", () => {
fixtures.accounts.forEach(async fixture => {
const seedBuffer = await bchjs.Mnemonic.toSeed(fixture.mnemonic)
console.log(`seedBuffer: ${seedBuffer.toString()}`)
+2 -9
View File
@@ -1,17 +1,10 @@
// Public npm libraries
const assert = require("assert")
const axios = require("axios")
const BCHJS = require("../../src/bch-js")
const bchjs = new BCHJS()
const sinon = require("sinon")
// Unit under test (uut)
const BCHJS = require("../../src/bch-js")
let bchjs
describe("#Mining", () => {
beforeEach(() => {
bchjs = new BCHJS()
})
describe("#getBlockTemplate", () => {
let sandbox
beforeEach(() => (sandbox = sinon.createSandbox()))
+125 -8
View File
@@ -31,7 +31,9 @@ describe(`#Ninsight`, () => {
it(`should GET utxos for a single address`, async () => {
// Stub the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.utxo })
sandbox.stub(axios, "post").resolves({
data: mockData.utxo
})
const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9"
@@ -57,7 +59,9 @@ describe(`#Ninsight`, () => {
it(`should POST utxo details for an array of addresses`, async () => {
// Mock the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.utxoPost })
sandbox.stub(axios, "post").resolves({
data: mockData.utxoPost
})
const addr = [
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
@@ -96,7 +100,9 @@ describe(`#Ninsight`, () => {
it(`should POST utxos for a single address`, async () => {
// Stub the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.unconfirmed })
sandbox.stub(axios, "post").resolves({
data: mockData.unconfirmed
})
const addr = "bitcoincash:qpkkjkhe29mqhqmu3evtq3dsnruuzl3rku6usknlh5"
@@ -121,7 +127,9 @@ describe(`#Ninsight`, () => {
it(`should POST utxo details for an array of addresses`, async () => {
// Mock the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.unconfirmedPost })
sandbox.stub(axios, "post").resolves({
data: mockData.unconfirmedPost
})
const addr = [
"bitcoincash:qpkkjkhe29mqhqmu3evtq3dsnruuzl3rku6usknlh5",
@@ -159,7 +167,9 @@ describe(`#Ninsight`, () => {
})
it(`should POST transaction history for a single address`, async () => {
// Stub the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.transactionsPost })
sandbox.stub(axios, "post").resolves({
data: mockData.transactionsPost
})
const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9"
@@ -177,7 +187,9 @@ describe(`#Ninsight`, () => {
})
it(`should POST transaction history for an array of addresses`, async () => {
// Mock the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.transactionsPost })
sandbox.stub(axios, "post").resolves({
data: mockData.transactionsPost
})
const addr = [
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
@@ -212,7 +224,9 @@ describe(`#Ninsight`, () => {
})
it(`should POST transaction details for a single TxID`, async () => {
// Stub the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.detailsPost })
sandbox.stub(axios, "post").resolves({
data: mockData.detailsPost
})
const txid = "fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33"
@@ -236,7 +250,9 @@ describe(`#Ninsight`, () => {
})
it(`should POST transaction details for an array of TxIDs`, async () => {
// Stub the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.detailsPost })
sandbox.stub(axios, "post").resolves({
data: mockData.detailsPost
})
const txid = [
"fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33",
@@ -252,4 +268,105 @@ describe(`#Ninsight`, () => {
assert.property(result[0], "vout")
})
})
describe(`#addrDetails`, () => {
it(`should throw an error for improper input`, async () => {
try {
const addr = 12345
await bchjs.Ninsight.details(addr)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
//console.log(`err: `, err)
assert.include(
err.message,
`Input address must be a string or array of strings.`
)
}
})
it(`should POST address details for a single address`, async () => {
// Stub the network call.
sandbox.stub(axios, "post").resolves({
data: mockData.addrDetailArray
})
const result = await bchjs.Ninsight.details("addr")
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result[0], "balance")
assert.property(result[0], "balanceSat")
assert.property(result[0], "totalReceived")
assert.property(result[0], "totalReceivedSat")
assert.property(result[0], "totalSent")
assert.property(result[0], "totalSentSat")
assert.property(result[0], "unconfirmedBalance")
assert.property(result[0], "unconfirmedBalanceSat")
assert.property(result[0], "unconfirmedTxApperances")
assert.property(result[0], "txApperances")
assert.property(result[0], "transactions")
assert.property(result[0], "legacyAddress")
assert.property(result[0], "cashAddress")
assert.property(result[0], "slpAddress")
assert.property(result[0], "currentPage")
assert.property(result[0], "pagesTotal")
})
it(`should call constructor with null args`, async () => {
new bchjs.Ninsight.constructor({})
})
it(`should POST address details for an array of addresses`, async () => {
// Mock the network call.
sandbox.stub(axios, "post").resolves({
data: mockData.addrDetailArray
})
const addr = [
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
"bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr"
]
const result = await bchjs.Ninsight.details(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.property(result[0], "balance")
assert.property(result[0], "balanceSat")
assert.property(result[0], "totalReceived")
assert.property(result[0], "totalReceivedSat")
assert.property(result[0], "totalSent")
assert.property(result[0], "totalSentSat")
assert.property(result[0], "unconfirmedBalance")
assert.property(result[0], "unconfirmedBalanceSat")
assert.property(result[0], "unconfirmedTxApperances")
assert.property(result[0], "txApperances")
assert.property(result[0], "transactions")
assert.property(result[0], "legacyAddress")
assert.property(result[1], "cashAddress")
assert.property(result[1], "slpAddress")
assert.property(result[1], "currentPage")
assert.property(result[1], "pagesTotal")
/*
If in any way possible, I would like to refactor this test
according to the DRY principle to share it with the integration tests too
Would that make sense or does that implicate anything unwanted?
assertDetails(result[0])
assertDetails(data) {
assert.property(data, "satoshis")
assert.property(data, "height")
assert.property(data, "confirmations")
assert.property(data, "timestamp")
assert.property(data, "fees")
assert.property(data, "outputIndexes")
assert.property(data, "inputIndexes")
assert.property(data, "tx")
}
*/
})
})
})
+1 -12
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,15 +56,4 @@ 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)
})
})
})
+22 -28
View File
@@ -1,28 +1,23 @@
/*
TODO:
-Replace old unit tests mocking axios with the more generalized nock library.
See the sendRawTransaction test for an example.
-Create a mocking library of data to compare unit and integration tests.
*/
// Public npm libraries
const assert = require("assert")
const axios = require("axios")
const sinon = require("sinon")
// const nock = require("nock") // HTTP mocking
// Unit under test (uut)
const BCHJS = require("../../src/bch-js")
// const bchjs = new BCHJS()
let bchjs
const bchjs = new BCHJS()
const sinon = require("sinon")
const nock = require("nock") // HTTP mocking
// Used for debugging
// const util = require("util")
// util.inspect.defaultOptions = { depth: 1 }
const util = require("util")
util.inspect.defaultOptions = { depth: 1 }
describe("#RawTransactions", () => {
beforeEach(() => {
bchjs = new BCHJS()
})
describe("#decodeRawTransaction", () => {
let sandbox
beforeEach(() => (sandbox = sinon.createSandbox()))
@@ -116,20 +111,19 @@ describe("#RawTransactions", () => {
assert.equal(data, result)
})
// it("should send an array of raw transactions", async () => {
// const data = "Error: transaction already in block chain"
//
// // Mock the http call to rest.bitcoin.com
// // nock(`${bchjs.RawTransactions.restURL}`)
// // .post(uri => uri.includes(`/`))
// // .reply(200, { data: data })
// sandbox.stub(bchjs, "axios").resolves({ data: data })
//
// const result = await bchjs.RawTransactions.sendRawTransaction([
// "020000000160d663961c63c7f0a07f22ec07b8f55b3935bfdbed8b1d8454916e8932fbf109010000006b4830450221008479fab4cfdcb111833d250a43f98ac26d43272b7a29cb1b9a0491eae5c44b3502203448b17253632395c29a7d62058bbfe93efb20fc8636ba6837002d464195aec04121029123258f7cdcd45b864066bcaa9b71f24d5ed1fa1dd36eaf107d8432b5014658ffffffff016d180000000000001976a91479d3297d1823149f4ec61df31d19f2fad5390c0288ac00000000"
// ])
//
// assert.equal(data, result.data)
// })
it("should send an array of raw transactions", async () => {
const data = "Error: transaction already in block chain"
// Mock the http call to rest.bitcoin.com
nock(`${bchjs.RawTransactions.restURL}`)
.post(uri => uri.includes(`/`))
.reply(200, { data: data })
const result = await bchjs.RawTransactions.sendRawTransaction([
"020000000160d663961c63c7f0a07f22ec07b8f55b3935bfdbed8b1d8454916e8932fbf109010000006b4830450221008479fab4cfdcb111833d250a43f98ac26d43272b7a29cb1b9a0491eae5c44b3502203448b17253632395c29a7d62058bbfe93efb20fc8636ba6837002d464195aec04121029123258f7cdcd45b864066bcaa9b71f24d5ed1fa1dd36eaf107d8432b5014658ffffffff016d180000000000001976a91479d3297d1823149f4ec61df31d19f2fad5390c0288ac00000000"
])
assert.equal(data, result.data)
})
})
})
+20 -31
View File
@@ -1,19 +1,10 @@
// Public npm libraries
const fixtures = require("./fixtures/script.json")
const assert = require("assert")
const BCHJS = require("../../src/bch-js")
const bchjs = new BCHJS()
const Buffer = require("safe-buffer").Buffer
// Mocks
const fixtures = require("./fixtures/script.json")
// Unit under test (uut)
const BCHJS = require("../../src/bch-js")
let bchjs
describe("#Script", () => {
beforeEach(() => {
bchjs = new BCHJS()
})
describe("#decode", () => {
describe("P2PKH scriptSig", () => {
fixtures.decodeScriptSig.forEach(fixture => {
@@ -330,27 +321,25 @@ describe("#Script", () => {
})
describe("#pubKeyHashOutputTemplate", () => {
it("should exercise pubKeyHashOutputTemplate", () => {
fixtures.pubKeyHashOutputTemplate.forEach(fixture => {
const node = bchjs.HDNode.fromXPriv(fixture.xpriv)
const identifier = bchjs.HDNode.toIdentifier(node)
it(`should encode pubKeyHash output`, () => {
const buf = bchjs.Script.pubKeyHash.output.encode(identifier)
assert.equal(buf.toString("hex"), fixture.hex)
})
fixtures.pubKeyHashOutputTemplate.forEach(fixture => {
const node = bchjs.HDNode.fromXPriv(fixture.xpriv)
const identifier = bchjs.HDNode.toIdentifier(node)
it(`should encode pubKeyHash output`, () => {
const buf = bchjs.Script.pubKeyHash.output.encode(identifier)
assert.equal(buf.toString("hex"), fixture.hex)
})
it(`should decode pubKeyHash output`, () => {
const buf = bchjs.Script.pubKeyHash.output.decode(
Buffer.from(`${fixture.hex}`, "hex")
)
assert.equal(buf.toString("hex"), identifier.toString("hex"))
})
it(`should decode pubKeyHash output`, () => {
const buf = bchjs.Script.pubKeyHash.output.decode(
Buffer.from(`${fixture.hex}`, "hex")
)
assert.equal(buf.toString("hex"), identifier.toString("hex"))
})
it(`should confirm correctly formatted pubKeyHash output`, () => {
const buf = bchjs.Script.pubKeyHash.output.encode(identifier)
const valid = bchjs.Script.pubKeyHash.output.check(buf)
assert.equal(valid, true)
})
it(`should confirm correctly formatted pubKeyHash output`, () => {
const buf = bchjs.Script.pubKeyHash.output.encode(identifier)
const valid = bchjs.Script.pubKeyHash.output.check(buf)
assert.equal(valid, true)
})
})
})
+74 -82
View File
@@ -1,9 +1,7 @@
const assert = require("assert")
const BCHJS = require("../../src/bch-js")
// const SLP = require("../../src/slp/slp")
// const SLP = new slp({ restURL: "http://fakeurl.com/" })
let slp
const slp = require("../../src/slp/slp")
const SLP = new slp({ restURL: "http://fakeurl.com/" })
const fixtures = require("./fixtures/slp/address.json")
//const axios = require("axios")
@@ -88,18 +86,12 @@ const SLP_TESTNET_ADDRESSES_NO_PREFIX = SLP_TESTNET_ADDRESSES.map(address => {
})
*/
describe("#SLP Address", () => {
beforeEach(() => {
const bchjs = new BCHJS()
// console.log(`bchjs.restURL: ${bchjs.restURL}`)
slp = bchjs.SLP
})
describe("#mainnet", () => {
describe("#toLegacyAddress", () => {
it("should convert mainnet legacy address format to itself correctly", () => {
assert.deepEqual(
LEGACY_MAINNET_ADDRESSES.map(address =>
slp.Address.toLegacyAddress(address)
SLP.Address.toLegacyAddress(address)
),
LEGACY_MAINNET_ADDRESSES
)
@@ -108,7 +100,7 @@ describe("#SLP Address", () => {
it(`should convert cashAddr to legacyAddr`, async () => {
assert.deepEqual(
CASH_MAINNET_ADDRESSES.map(address =>
slp.Address.toLegacyAddress(address)
SLP.Address.toLegacyAddress(address)
),
LEGACY_MAINNET_ADDRESSES
)
@@ -117,7 +109,7 @@ describe("#SLP Address", () => {
it(`should convert slpAddr to legacyAddr`, async () => {
assert.deepEqual(
SLP_MAINNET_ADDRESSES.map(address =>
slp.Address.toLegacyAddress(address)
SLP.Address.toLegacyAddress(address)
),
LEGACY_MAINNET_ADDRESSES
)
@@ -128,7 +120,7 @@ describe("#SLP Address", () => {
it("should convert mainnet cash address format to itself correctly", () => {
assert.deepEqual(
CASH_MAINNET_ADDRESSES.map(address =>
slp.Address.toCashAddress(address)
SLP.Address.toCashAddress(address)
),
CASH_MAINNET_ADDRESSES
)
@@ -137,7 +129,7 @@ describe("#SLP Address", () => {
it(`should convert legacyAddr to cashAddr`, async () => {
assert.deepEqual(
LEGACY_MAINNET_ADDRESSES.map(address =>
slp.Address.toCashAddress(address)
SLP.Address.toCashAddress(address)
),
CASH_MAINNET_ADDRESSES
)
@@ -146,7 +138,7 @@ describe("#SLP Address", () => {
it(`should convert slpAddr to cashAddr`, async () => {
assert.deepEqual(
SLP_MAINNET_ADDRESSES.map(address =>
slp.Address.toCashAddress(address)
SLP.Address.toCashAddress(address)
),
CASH_MAINNET_ADDRESSES
)
@@ -157,7 +149,7 @@ describe("#SLP Address", () => {
it("should convert mainnet slp address format to itself correctly", () => {
assert.deepEqual(
SLP_MAINNET_ADDRESSES.map(address =>
slp.Address.toSLPAddress(address)
SLP.Address.toSLPAddress(address)
),
SLP_MAINNET_ADDRESSES
)
@@ -166,7 +158,7 @@ describe("#SLP Address", () => {
it(`should convert legacyAddr to slpAddr`, async () => {
assert.deepEqual(
LEGACY_MAINNET_ADDRESSES.map(address =>
slp.Address.toSLPAddress(address)
SLP.Address.toSLPAddress(address)
),
SLP_MAINNET_ADDRESSES
)
@@ -175,7 +167,7 @@ describe("#SLP Address", () => {
it(`should convert cashAddr to slpAddr`, async () => {
assert.deepEqual(
CASH_MAINNET_ADDRESSES.map(address =>
slp.Address.toSLPAddress(address)
SLP.Address.toSLPAddress(address)
),
SLP_MAINNET_ADDRESSES
)
@@ -186,7 +178,7 @@ describe("#SLP Address", () => {
describe("is legacy addr", () => {
LEGACY_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a legacy address`, () => {
const isLegacyaddr = slp.Address.isLegacyAddress(address)
const isLegacyaddr = SLP.Address.isLegacyAddress(address)
assert.equal(isLegacyaddr, true)
})
})
@@ -195,7 +187,7 @@ describe("#SLP Address", () => {
describe("cashaddr is not legacy addr", () => {
CASH_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a legacy address`, () => {
const isLegacyaddr = slp.Address.isLegacyAddress(address)
const isLegacyaddr = SLP.Address.isLegacyAddress(address)
assert.equal(isLegacyaddr, false)
})
})
@@ -204,7 +196,7 @@ describe("#SLP Address", () => {
describe("slpaddr is not legacy addr", () => {
SLP_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a legacy address`, () => {
const isLegacyaddr = slp.Address.isLegacyAddress(address)
const isLegacyaddr = SLP.Address.isLegacyAddress(address)
assert.equal(isLegacyaddr, false)
})
})
@@ -215,7 +207,7 @@ describe("#SLP Address", () => {
describe("is cashaddr", () => {
CASH_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a cashaddr address`, () => {
const isCashaddr = slp.Address.isCashAddress(address)
const isCashaddr = SLP.Address.isCashAddress(address)
assert.equal(isCashaddr, true)
})
})
@@ -224,7 +216,7 @@ describe("#SLP Address", () => {
describe("legacy is not cash addr", () => {
LEGACY_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a cash address`, () => {
const isCashaddr = slp.Address.isCashAddress(address)
const isCashaddr = SLP.Address.isCashAddress(address)
assert.equal(isCashaddr, false)
})
})
@@ -233,7 +225,7 @@ describe("#SLP Address", () => {
describe("slpaddr is not cash addr", () => {
SLP_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a cash address`, () => {
const isCashaddr = slp.Address.isCashAddress(address)
const isCashaddr = SLP.Address.isCashAddress(address)
assert.equal(isCashaddr, false)
})
})
@@ -244,7 +236,7 @@ describe("#SLP Address", () => {
describe("is slpaddr", () => {
SLP_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is an slp address`, () => {
const isSLPaddr = slp.Address.isSLPAddress(address)
const isSLPaddr = SLP.Address.isSLPAddress(address)
assert.equal(isSLPaddr, true)
})
})
@@ -253,7 +245,7 @@ describe("#SLP Address", () => {
describe("legacy is not slp addr", () => {
LEGACY_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not an slp address`, () => {
const isSLPaddr = slp.Address.isSLPAddress(address)
const isSLPaddr = SLP.Address.isSLPAddress(address)
assert.equal(isSLPaddr, false)
})
})
@@ -262,7 +254,7 @@ describe("#SLP Address", () => {
describe("cash is not slp addr", () => {
CASH_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not an slp address`, () => {
const isSLPaddr = slp.Address.isSLPAddress(address)
const isSLPaddr = SLP.Address.isSLPAddress(address)
assert.equal(isSLPaddr, false)
})
})
@@ -273,7 +265,7 @@ describe("#SLP Address", () => {
describe("mainnet legacy addr", () => {
LEGACY_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a mainnet address`, () => {
const isMainnetaddr = slp.Address.isMainnetAddress(address)
const isMainnetaddr = SLP.Address.isMainnetAddress(address)
assert.equal(isMainnetaddr, true)
})
})
@@ -282,7 +274,7 @@ describe("#SLP Address", () => {
describe("mainnet cash addr", () => {
CASH_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a mainnet address`, () => {
const isMainnetaddr = slp.Address.isMainnetAddress(address)
const isMainnetaddr = SLP.Address.isMainnetAddress(address)
assert.equal(isMainnetaddr, true)
})
})
@@ -291,7 +283,7 @@ describe("#SLP Address", () => {
describe("mainnet slp addr", () => {
SLP_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a mainnet address`, () => {
const isMainnetaddr = slp.Address.isMainnetAddress(address)
const isMainnetaddr = SLP.Address.isMainnetAddress(address)
assert.equal(isMainnetaddr, true)
})
})
@@ -300,7 +292,7 @@ describe("#SLP Address", () => {
describe("testnet legacy addr", () => {
LEGACY_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a mainnet address`, () => {
const isMainnetaddr = slp.Address.isMainnetAddress(address)
const isMainnetaddr = SLP.Address.isMainnetAddress(address)
assert.equal(isMainnetaddr, false)
})
})
@@ -309,7 +301,7 @@ describe("#SLP Address", () => {
describe("testnet cash addr", () => {
CASH_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a mainnet address`, () => {
const isMainnetaddr = slp.Address.isMainnetAddress(address)
const isMainnetaddr = SLP.Address.isMainnetAddress(address)
assert.equal(isMainnetaddr, false)
})
})
@@ -318,7 +310,7 @@ describe("#SLP Address", () => {
describe("testnet slp addr", () => {
SLP_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a mainnet address`, () => {
const isMainnetaddr = slp.Address.isMainnetAddress(address)
const isMainnetaddr = SLP.Address.isMainnetAddress(address)
assert.equal(isMainnetaddr, false)
})
})
@@ -329,7 +321,7 @@ describe("#SLP Address", () => {
describe("mainnet legacy addr", () => {
MAINNET_P2PKH_ADDRESSES.forEach(address => {
it(`should detect ${address} is a P2PKH address`, () => {
const isP2PKHaddr = slp.Address.isP2PKHAddress(address)
const isP2PKHaddr = SLP.Address.isP2PKHAddress(address)
assert.equal(isP2PKHaddr, true)
})
})
@@ -340,7 +332,7 @@ describe("#SLP Address", () => {
describe("mainnet legacy addr", () => {
MAINNET_P2SH_ADDRESSES.forEach(address => {
it(`should detect ${address} is a P2SH address`, () => {
const isP2SHaddr = slp.Address.isP2SHAddress(address)
const isP2SHaddr = SLP.Address.isP2SHAddress(address)
assert.equal(isP2SHaddr, true)
})
})
@@ -350,21 +342,21 @@ describe("#SLP Address", () => {
describe("#detectAddressFormat", () => {
LEGACY_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a legacy address`, () => {
const isLegacy = slp.Address.detectAddressFormat(address)
const isLegacy = SLP.Address.detectAddressFormat(address)
assert.equal(isLegacy, "legacy")
})
})
CASH_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a cash address`, () => {
const isCashaddr = slp.Address.detectAddressFormat(address)
const isCashaddr = SLP.Address.detectAddressFormat(address)
assert.equal(isCashaddr, "cashaddr")
})
})
SLP_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is an slp address`, () => {
const isSlpaddr = slp.Address.detectAddressFormat(address)
const isSlpaddr = SLP.Address.detectAddressFormat(address)
assert.equal(isSlpaddr, "slpaddr")
})
})
@@ -373,21 +365,21 @@ describe("#SLP Address", () => {
describe("#detectAddressNetwork", () => {
LEGACY_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a mainnet address`, () => {
const isMainnet = slp.Address.detectAddressNetwork(address)
const isMainnet = SLP.Address.detectAddressNetwork(address)
assert.equal(isMainnet, "mainnet")
})
})
CASH_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a mainnet address`, () => {
const isMainnet = slp.Address.detectAddressNetwork(address)
const isMainnet = SLP.Address.detectAddressNetwork(address)
assert.equal(isMainnet, "mainnet")
})
})
SLP_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a mainnet address`, () => {
const isMainnet = slp.Address.detectAddressNetwork(address)
const isMainnet = SLP.Address.detectAddressNetwork(address)
assert.equal(isMainnet, "mainnet")
})
})
@@ -396,14 +388,14 @@ describe("#SLP Address", () => {
describe("#detectAddressType", () => {
MAINNET_P2PKH_ADDRESSES.forEach(address => {
it(`should detect ${address} is a p2pkh address`, () => {
const isp2pkh = slp.Address.detectAddressType(address)
const isp2pkh = SLP.Address.detectAddressType(address)
assert.equal(isp2pkh, "p2pkh")
})
})
MAINNET_P2SH_ADDRESSES.forEach(address => {
it(`should detect ${address} is a p2sh address`, () => {
const isp2sh = slp.Address.detectAddressType(address)
const isp2sh = SLP.Address.detectAddressType(address)
assert.equal(isp2sh, "p2sh")
})
})
@@ -415,7 +407,7 @@ describe("#SLP Address", () => {
it("should convert testnet legacy address format to itself correctly", () => {
assert.deepEqual(
LEGACY_TESTNET_ADDRESSES.map(address =>
slp.Address.toLegacyAddress(address)
SLP.Address.toLegacyAddress(address)
),
LEGACY_TESTNET_ADDRESSES
)
@@ -424,7 +416,7 @@ describe("#SLP Address", () => {
it(`should convert cashAddr to legacyAddr`, async () => {
assert.deepEqual(
CASH_TESTNET_ADDRESSES.map(address =>
slp.Address.toLegacyAddress(address)
SLP.Address.toLegacyAddress(address)
),
LEGACY_TESTNET_ADDRESSES
)
@@ -433,7 +425,7 @@ describe("#SLP Address", () => {
it(`should convert slpAddr to legacyAddr`, async () => {
assert.deepEqual(
SLP_TESTNET_ADDRESSES.map(address =>
slp.Address.toLegacyAddress(address)
SLP.Address.toLegacyAddress(address)
),
LEGACY_TESTNET_ADDRESSES
)
@@ -444,7 +436,7 @@ describe("#SLP Address", () => {
it("should convert testnet cash address format to itself correctly", () => {
assert.deepEqual(
CASH_TESTNET_ADDRESSES.map(address =>
slp.Address.toCashAddress(address)
SLP.Address.toCashAddress(address)
),
CASH_TESTNET_ADDRESSES
)
@@ -453,7 +445,7 @@ describe("#SLP Address", () => {
it(`should convert legacyAddr to cashAddr`, async () => {
assert.deepEqual(
LEGACY_TESTNET_ADDRESSES.map(address =>
slp.Address.toCashAddress(address)
SLP.Address.toCashAddress(address)
),
CASH_TESTNET_ADDRESSES
)
@@ -462,7 +454,7 @@ describe("#SLP Address", () => {
it(`should convert slpAddr to cashAddr`, async () => {
assert.deepEqual(
SLP_TESTNET_ADDRESSES.map(address =>
slp.Address.toCashAddress(address)
SLP.Address.toCashAddress(address)
),
CASH_TESTNET_ADDRESSES
)
@@ -473,7 +465,7 @@ describe("#SLP Address", () => {
it("should convert testnet slp address format to itself correctly", () => {
assert.deepEqual(
SLP_TESTNET_ADDRESSES.map(address =>
slp.Address.toSLPAddress(address)
SLP.Address.toSLPAddress(address)
),
SLP_TESTNET_ADDRESSES
)
@@ -482,7 +474,7 @@ describe("#SLP Address", () => {
it(`should convert legacyAddr to slpAddr`, async () => {
assert.deepEqual(
LEGACY_TESTNET_ADDRESSES.map(address =>
slp.Address.toSLPAddress(address)
SLP.Address.toSLPAddress(address)
),
SLP_TESTNET_ADDRESSES
)
@@ -491,7 +483,7 @@ describe("#SLP Address", () => {
it(`should convert cashAddr to slpAddr`, async () => {
assert.deepEqual(
CASH_TESTNET_ADDRESSES.map(address =>
slp.Address.toSLPAddress(address)
SLP.Address.toSLPAddress(address)
),
SLP_TESTNET_ADDRESSES
)
@@ -502,7 +494,7 @@ describe("#SLP Address", () => {
describe("is legacy addr", () => {
LEGACY_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a legacy address`, () => {
const isLegacyaddr = slp.Address.isLegacyAddress(address)
const isLegacyaddr = SLP.Address.isLegacyAddress(address)
assert.equal(isLegacyaddr, true)
})
})
@@ -511,7 +503,7 @@ describe("#SLP Address", () => {
describe("cashaddr is not legacy addr", () => {
CASH_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a legacy address`, () => {
const isLegacyaddr = slp.Address.isLegacyAddress(address)
const isLegacyaddr = SLP.Address.isLegacyAddress(address)
assert.equal(isLegacyaddr, false)
})
})
@@ -520,7 +512,7 @@ describe("#SLP Address", () => {
describe("slpaddr is not legacy addr", () => {
SLP_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a legacy address`, () => {
const isLegacyaddr = slp.Address.isLegacyAddress(address)
const isLegacyaddr = SLP.Address.isLegacyAddress(address)
assert.equal(isLegacyaddr, false)
})
})
@@ -531,7 +523,7 @@ describe("#SLP Address", () => {
describe("is cashaddr", () => {
CASH_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a cashaddr address`, () => {
const isCashaddr = slp.Address.isCashAddress(address)
const isCashaddr = SLP.Address.isCashAddress(address)
assert.equal(isCashaddr, true)
})
})
@@ -540,7 +532,7 @@ describe("#SLP Address", () => {
describe("legacy is not cash addr", () => {
LEGACY_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a cash address`, () => {
const isCashaddr = slp.Address.isCashAddress(address)
const isCashaddr = SLP.Address.isCashAddress(address)
assert.equal(isCashaddr, false)
})
})
@@ -549,7 +541,7 @@ describe("#SLP Address", () => {
describe("slpaddr is not cash addr", () => {
SLP_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a cash address`, () => {
const isCashaddr = slp.Address.isCashAddress(address)
const isCashaddr = SLP.Address.isCashAddress(address)
assert.equal(isCashaddr, false)
})
})
@@ -560,7 +552,7 @@ describe("#SLP Address", () => {
describe("is slpaddr", () => {
SLP_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is an slp address`, () => {
const isSLPaddr = slp.Address.isSLPAddress(address)
const isSLPaddr = SLP.Address.isSLPAddress(address)
assert.equal(isSLPaddr, true)
})
})
@@ -569,7 +561,7 @@ describe("#SLP Address", () => {
describe("legacy is not slp addr", () => {
LEGACY_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not an slp address`, () => {
const isSLPaddr = slp.Address.isSLPAddress(address)
const isSLPaddr = SLP.Address.isSLPAddress(address)
assert.equal(isSLPaddr, false)
})
})
@@ -578,7 +570,7 @@ describe("#SLP Address", () => {
describe("cash is not slp addr", () => {
CASH_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not an slp address`, () => {
const isSLPaddr = slp.Address.isSLPAddress(address)
const isSLPaddr = SLP.Address.isSLPAddress(address)
assert.equal(isSLPaddr, false)
})
})
@@ -589,7 +581,7 @@ describe("#SLP Address", () => {
describe("testnet legacy addr", () => {
LEGACY_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a testnet address`, () => {
const isTestnetaddr = slp.Address.isTestnetAddress(address)
const isTestnetaddr = SLP.Address.isTestnetAddress(address)
assert.equal(isTestnetaddr, true)
})
})
@@ -598,7 +590,7 @@ describe("#SLP Address", () => {
describe("testnet cash addr", () => {
CASH_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a testnet address`, () => {
const isTestnetaddr = slp.Address.isTestnetAddress(address)
const isTestnetaddr = SLP.Address.isTestnetAddress(address)
assert.equal(isTestnetaddr, true)
})
})
@@ -607,7 +599,7 @@ describe("#SLP Address", () => {
describe("testnet slp addr", () => {
SLP_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a testnet address`, () => {
const isTestnetaddr = slp.Address.isTestnetAddress(address)
const isTestnetaddr = SLP.Address.isTestnetAddress(address)
assert.equal(isTestnetaddr, true)
})
})
@@ -616,7 +608,7 @@ describe("#SLP Address", () => {
describe("mainnet legacy addr", () => {
LEGACY_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a testnet address`, () => {
const isTestnetaddr = slp.Address.isTestnetAddress(address)
const isTestnetaddr = SLP.Address.isTestnetAddress(address)
assert.equal(isTestnetaddr, false)
})
})
@@ -625,7 +617,7 @@ describe("#SLP Address", () => {
describe("mainnet cash addr", () => {
CASH_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a testnet address`, () => {
const isTestnetaddr = slp.Address.isTestnetAddress(address)
const isTestnetaddr = SLP.Address.isTestnetAddress(address)
assert.equal(isTestnetaddr, false)
})
})
@@ -634,7 +626,7 @@ describe("#SLP Address", () => {
describe("mainnet slp addr", () => {
SLP_MAINNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is not a testnet address`, () => {
const isTestnetaddr = slp.Address.isTestnetAddress(address)
const isTestnetaddr = SLP.Address.isTestnetAddress(address)
assert.equal(isTestnetaddr, false)
})
})
@@ -645,7 +637,7 @@ describe("#SLP Address", () => {
describe("testnet legacy addr", () => {
TESTNET_P2PKH_ADDRESSES.forEach(address => {
it(`should detect ${address} is a P2PKH address`, () => {
const isP2PKHaddr = slp.Address.isP2PKHAddress(address)
const isP2PKHaddr = SLP.Address.isP2PKHAddress(address)
assert.equal(isP2PKHaddr, true)
})
})
@@ -656,7 +648,7 @@ describe("#SLP Address", () => {
describe("testnet legacy addr", () => {
TESTNET_P2SH_ADDRESSES.forEach(address => {
it(`should detect ${address} is a P2SH address`, () => {
const isP2SHaddr = slp.Address.isP2SHAddress(address)
const isP2SHaddr = SLP.Address.isP2SHAddress(address)
assert.equal(isP2SHaddr, true)
})
})
@@ -666,21 +658,21 @@ describe("#SLP Address", () => {
describe("#detectAddressFormat", () => {
LEGACY_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a legacy address`, () => {
const isLegacy = slp.Address.detectAddressFormat(address)
const isLegacy = SLP.Address.detectAddressFormat(address)
assert.equal(isLegacy, "legacy")
})
})
CASH_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a cash address`, () => {
const isCashaddr = slp.Address.detectAddressFormat(address)
const isCashaddr = SLP.Address.detectAddressFormat(address)
assert.equal(isCashaddr, "cashaddr")
})
})
SLP_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is an slp address`, () => {
const isSlpaddr = slp.Address.detectAddressFormat(address)
const isSlpaddr = SLP.Address.detectAddressFormat(address)
assert.equal(isSlpaddr, "slpaddr")
})
})
@@ -689,21 +681,21 @@ describe("#SLP Address", () => {
describe("#detectAddressNetwork", () => {
LEGACY_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a testnet address`, () => {
const isTestnet = slp.Address.detectAddressNetwork(address)
const isTestnet = SLP.Address.detectAddressNetwork(address)
assert.equal(isTestnet, "testnet")
})
})
CASH_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a testnet address`, () => {
const isTestnet = slp.Address.detectAddressNetwork(address)
const isTestnet = SLP.Address.detectAddressNetwork(address)
assert.equal(isTestnet, "testnet")
})
})
SLP_TESTNET_ADDRESSES.forEach(address => {
it(`should detect ${address} is a testnet address`, () => {
const isTestnet = slp.Address.detectAddressNetwork(address)
const isTestnet = SLP.Address.detectAddressNetwork(address)
assert.equal(isTestnet, "testnet")
})
})
@@ -712,7 +704,7 @@ describe("#SLP Address", () => {
describe("#detectAddressType", () => {
TESTNET_P2PKH_ADDRESSES.forEach(address => {
it(`should detect ${address} is a p2pkh address`, () => {
const isp2pkh = slp.Address.detectAddressType(address)
const isp2pkh = SLP.Address.detectAddressType(address)
assert.equal(isp2pkh, "p2pkh")
})
})
@@ -721,7 +713,7 @@ describe("#SLP Address", () => {
describe("#detectAddressType", () => {
TESTNET_P2SH_ADDRESSES.forEach(address => {
it(`should detect ${address} is a p2sh address`, () => {
const isp2sh = slp.Address.detectAddressType(address)
const isp2sh = SLP.Address.detectAddressType(address)
assert.equal(isp2sh, "p2sh")
})
})
@@ -761,7 +753,7 @@ describe("#details", () => {
const resolved = new Promise(r => r({ data: data }))
sandbox.stub(axios, "get").returns(resolved)
slp.Address.details(
SLP.Address.details(
"simpleledger:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3gev5wtnm6"
)
.then(result => {
@@ -796,7 +788,7 @@ describe("#utxo", () => {
const resolved = new Promise(r => r({ data: data }))
sandbox.stub(axios, "get").returns(resolved)
slp.Address.utxo("simpleledger:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3gev5wtnm6")
SLP.Address.utxo("simpleledger:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3gev5wtnm6")
.then(result => {
assert.deepEqual(
"467969e067f5612863d0bf2daaa70dede2c6be03abb6fd401c5ef6e1e1f1f5c5",
@@ -823,7 +815,7 @@ describe("#unconfirmed", () => {
const resolved = new Promise(r => r({ data: data }))
sandbox.stub(axios, "get").returns(resolved)
slp.Address.unconfirmed(
SLP.Address.unconfirmed(
"simpleledger:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3gev5wtnm6"
)
.then(result => {
@@ -836,7 +828,7 @@ describe("#unconfirmed", () => {
// (async () => {
// try {
// const details = await slp.Address.unconfirmed(
// const details = await SLP.Address.unconfirmed(
// "simpleledger:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3gev5wtnm6"
// )
// console.log(details)
+3 -12
View File
@@ -1,19 +1,10 @@
const fixtures = require("./fixtures/slp/ecpair.json")
const assert = require("assert")
const fixtures = require("./fixtures/slp/ecpair.json")
const BCHJS = require("../../src/bch-js")
let slp
// const SLP = require("../../src/slp/slp")
// const slp = new SLP({ restURL: "http://fakeurl.com/" })
const SLP = require("../../src/slp/slp")
const slp = new SLP({ restURL: "http://fakeurl.com/" })
describe("#SLP ECPair", () => {
beforeEach(() => {
const bchjs = new BCHJS()
slp = bchjs.SLP
})
describe("#toSLPAddress", () => {
it(`should return slp address for ecpair`, async () => {
fixtures.wif.forEach((wif, index) => {
+484 -643
View File
File diff suppressed because it is too large Load Diff