Compare commits

..
4 Commits
5 changed files with 757 additions and 0 deletions
+3
View File
@@ -38,6 +38,7 @@ const Ecash = require('./ecash')
// Indexers
const Ninsight = require('./ninsight')
const Electrumx = require('./electrumx')
const PsfSlpIndexer = require('./psf-slp-indexer')
class BCHJS {
constructor (config) {
@@ -120,6 +121,8 @@ class BCHJS {
this.DSProof = new DSProof(libConfig)
this.eCash = new Ecash()
this.PsfSlpIndexer = new PsfSlpIndexer(libConfig)
}
}
+292
View File
@@ -0,0 +1,292 @@
/*
This library interacts with the PSF slp indexer REST API endpoints operated
by FullStack.cash
*/
// Public npm libraries
const axios = require('axios')
// let _this
class PsfSlpIndexer {
constructor (config) {
this.restURL = config.restURL
this.apiToken = config.apiToken
this.authToken = config.authToken
if (this.authToken) {
// Add Basic Authentication token to the authorization header.
this.axiosOptions = {
headers: {
authorization: this.authToken
}
}
} else {
// Add JWT token to the authorization header.
this.axiosOptions = {
headers: {
authorization: `Token ${this.apiToken}`
}
}
}
// _this = this
}
/**
* @api PsfSlpIndexer.status() status()
* @apiName Status
* @apiGroup PSF SLP
* @apiDescription Return status from psf slp indexer.
*
* @apiExample Example usage:
* (async () => {
* try {
* let status = await bchjs.PsfSlpIndexer.status();
* console.log(status);
* } catch(error) {
* console.error(error)
* }
* })()
*
* {
* "status": {
* "startBlockHeight": 543376,
* "syncedBlockHeight": 723249,
* "chainBlockHeight": 722679
* }
* }
*
*/
async status () {
try {
const response = await axios.get(
`${this.restURL}psf/slp/status`,
this.axiosOptions
)
return response.data
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
}
}
/**
* @api PsfSlpIndexer.balance() balance()
* @apiName SLP Balance
* @apiGroup PSF SLP
* @apiDescription Return slp balance for a single address.
*
* @apiExample Example usage:
* (async () => {
* try {
* let balance = await bchjs.PsfSlpIndexer.balance('bitcoincash:qzmd5vxgh9m22m6fgvm57yd6kjnjl9qnwywsf3583n');
* console.log(balance);
* } catch(error) {
* console.error(error)
* }
* })()
*
* {
* balance: {
* utxos: [
* {
* txid: 'a24a6a4abf06fabd799ecea4f8fac6a9ff21e6a8dd6169a3c2ebc03665329db9',
* vout: 1,
* type: 'token',
* qty: '1800',
* tokenId: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
* address: 'bitcoincash:qrqy3kj7r822ps6628vwqq5k8hyjl6ey3y4eea2m4s'
* }
* ],
* txs: [
* {
* txid: '078b2c48ed1db0d5d5996f2889b8d847a49200d0a781f6aa6752f740f312688f',
* height: 717796
* },
* {
* txid: 'a24a6a4abf06fabd799ecea4f8fac6a9ff21e6a8dd6169a3c2ebc03665329db9',
* height: 717832
* }
* ],
* balances: [
* {
* tokenId: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
* qty: '1800'
* }
* ]
* }
* }
*
*/
async balance (address) {
try {
// Handle single address.
if (typeof address === 'string') {
const response = await axios.post(
`${this.restURL}psf/slp/address`,
{ address },
this.axiosOptions
)
return response.data
}
throw new Error('Input address must be a string.')
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
}
}
/**
* @api PsfSlpIndexer.tokenStats() tokenStats()
* @apiName Token Stats
* @apiGroup PSF SLP
* @apiDescription Return list stats for a single slp token.
*
* @apiExample Example usage:
* (async () => {
* try {
* let tokenStats = await bchjs.PsfSlpIndexer.tokenStats('a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2');
* console.log(tokenStats);
* } catch(error) {
* console.error(error)
* }
* })()
*
* {
* tokenData: {
* type: 1,
* ticker: 'TROUT',
* name: "Trout's test token",
* tokenId: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
* documentUri: 'troutsblog.com',
* documentHash: '',
* decimals: 2,
* mintBatonIsActive: true,
* tokensInCirculationBN: '100098953386',
* tokensInCirculationStr: '100098953386',
* blockCreated: 622414,
* totalBurned: '1046614',
* totalMinted: '100100000000'
* txs: [
* {
* txid: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
* height: 622414,
* type: 'GENESIS',
* qty: '100000000000'
* }
* ]
* }
* }
*
*/
async tokenStats (tokenId) {
try {
// Handle single address.
if (typeof tokenId === 'string') {
const response = await axios.post(
`${this.restURL}psf/slp/token`,
{ tokenId },
this.axiosOptions
)
return response.data
}
throw new Error('Input tokenId must be a string.')
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
}
}
/**
* @api PsfSlpIndexer.tx() tx()
* @apiName SLP Transaction Data
* @apiGroup PSF SLP
* @apiDescription Return slp transaction data.
*
* @apiExample Example usage:
* (async () => {
* try {
* let txData = await bchjs.PsfSlpIndexer.tx('a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2');
* console.log(txData);
* } catch(error) {
* console.error(error)
* }
* })()
*
* {
* txData: {
* txid: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
* hash: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
* version: 2,
* size: 339,
* locktime: 0,
* vin: [
* {
* txid: '8370db30d94761ab9a11b71ecd22541151bf6125c8c613f0f6fab8ab794565a7',
* vout: 0,
* scriptSig: {
* asm: '304402207e9631c53dfc8a9a793d1916469628c6b7c5780c01c2f676d51ef21b0ba4926f022069feb471ec869a49f8d108d0aaba04e7cd36e60a7500109d86537f55698930d4[ALL|FORKID] 02791b19a39165dbd83403d6df268d44fd621da30581b0b6e5cb15a7101ed58851',
* hex: '47304402207e9631c53dfc8a9a793d1916469628c6b7c5780c01c2f676d51ef21b0ba4926f022069feb471ec869a49f8d108d0aaba04e7cd36e60a7500109d86537f55698930d4412102791b19a39165dbd83403d6df268d44fd621da30581b0b6e5cb15a7101ed58851'
* },
* sequence: 4294967295,
* address: 'bitcoincash:qpvsg9vl9a5mlf37a7n3yce6pktdctn73qwgaqm3wq',
* value: 0.00051303,
* tokenQty: 0,
* tokenQtyStr: '0',
* tokenId: null
* }
* ],
* vout: [
* {
* value: 0,
* n: 0,
* scriptPubKey: {
* asm: 'OP_RETURN 5262419 1 47454e45534953 54524f5554 54726f75742773207465737420746f6b656e 74726f757473626c6f672e636f6d 0 2 2 000000174876e800',
* hex: '6a04534c500001010747454e455349530554524f55541254726f75742773207465737420746f6b656e0e74726f757473626c6f672e636f6d4c000102010208000000174876e800',
* type: 'nulldata'
* },
* tokenQtyStr: '0',
* tokenQty: 0
* }
* ],
* hex: '0200000001a7654579abb8faf6f013c6c82561bf51115422cd1eb7119aab6147d930db7083000000006a47304402207e9631c53dfc8a9a793d1916469628c6b7c5780c01c2f676d51ef21b0ba4926f022069feb471ec869a49f8d108d0aaba04e7cd36e60a7500109d86537f55698930d4412102791b19a39165dbd83403d6df268d44fd621da30581b0b6e5cb15a7101ed58851ffffffff040000000000000000476a04534c500001010747454e455349530554524f55541254726f75742773207465737420746f6b656e0e74726f757473626c6f672e636f6d4c000102010208000000174876e80022020000000000001976a914db4d39ceb7794ffe5d06855f249e1d3a7f1b024088ac22020000000000001976a914db4d39ceb7794ffe5d06855f249e1d3a7f1b024088accec20000000000001976a9145904159f2f69bfa63eefa712633a0d96dc2e7e8888ac00000000',
* blockhash: '0000000000000000009f65225a3e12e23a7ea057c869047e0f36563a1f410267',
* confirmations: 97398,
* time: 1581773131,
* blocktime: 1581773131,
* blockheight: 622414,
* isSlpTx: true,
* tokenTxType: 'GENESIS',
* tokenId: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
* tokenType: 1,
* tokenTicker: 'TROUT',
* tokenName: "Trout's test token",
* tokenDecimals: 2,
* tokenUri: 'troutsblog.com',
* tokenDocHash: '',
* isValidSlp: true
* }
* }
*
*/
async tx (txid) {
try {
// Handle single address.
if (typeof txid === 'string') {
const response = await axios.post(
`${this.restURL}psf/slp/txid`,
{ txid },
this.axiosOptions
)
return response.data
}
throw new Error('Input txid must be a string.')
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
}
}
}
module.exports = PsfSlpIndexer
@@ -0,0 +1,74 @@
/*
Integration tests for the psf-slp-indexer.js library
*/
const assert = require('chai').assert
const BCHJS = require('../../../../src/bch-js')
let bchjs
describe('#psf-slp-indexer', () => {
beforeEach(async () => {
// Introduce a delay so that the BVT doesn't trip the rate limits.
if (process.env.IS_USING_FREE_TIER) await sleep(3000)
bchjs = new BCHJS()
})
describe('#status', () => {
it('should return the status of the indexer.', async () => {
const result = await bchjs.PsfSlpIndexer.status()
// console.log('result: ', result)
assert.property(result.status, 'startBlockHeight')
assert.property(result.status, 'syncedBlockHeight')
assert.property(result.status, 'chainBlockHeight')
})
})
describe('#balance', () => {
it('should get balance data for an address.', async () => {
const addr = 'bitcoincash:qzmd5vxgh9m22m6fgvm57yd6kjnjl9qnwywsf3583n'
const result = await bchjs.PsfSlpIndexer.balance(addr)
// console.log('result: ', result)
assert.property(result.balance, 'utxos')
assert.property(result.balance, 'txs')
assert.property(result.balance, 'balances')
})
})
describe('#tokenStats', () => {
it('should get stats on a token', async () => {
const tokenId =
'38e97c5d7d3585a2cbf3f9580c82ca33985f9cb0845d4dcce220cb709f9538b0'
const result = await bchjs.PsfSlpIndexer.tokenStats(tokenId)
// console.log('result: ', result)
assert.property(result.tokenData, 'documentUri')
assert.property(result.tokenData, 'txs')
assert.property(result.tokenData, 'totalBurned')
})
})
describe('#tx', () => {
it('should get hydrated tx data', async () => {
const txid =
'83361c34cac2ea7f9ca287fca57a96cc0763719f0cdf4850f9696c1e68eb635c'
const result = await bchjs.PsfSlpIndexer.tx(txid)
// console.log('result: ', result)
assert.property(result.txData, 'vin')
assert.property(result.txData, 'vout')
assert.property(result.txData, 'isValidSlp')
})
})
})
// Promise-based sleep function
function sleep (ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
+130
View File
@@ -0,0 +1,130 @@
/*
Mocking data for unit tests for the PSF SLP INDEXER library.
*/
'use strict'
const tokenStats = {
tokenData: {
type: 1,
ticker: 'TP03',
name: 'Test Plugin 03',
tokenId: '13cad617d523c8eb4ab11fff19c010e0e0a4ea4360b58e0c8c955a45a146a669',
documentUri: 'fullstack.cash',
documentHash: '',
decimals: 0,
mintBatonIsActive: false,
tokensInCirculationBN: '1',
tokensInCirculationStr: '1',
blockCreated: 722420,
totalBurned: '0',
totalMinted: '1',
txs: [
{
txid: '13cad617d523c8eb4ab11fff19c010e0e0a4ea4360b58e0c8c955a45a146a669',
height: 722420,
type: 'GENESIS',
qty: '1'
}
]
}
}
const txData = {
txData: {
txid: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
hash: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
version: 2,
size: 339,
locktime: 0,
vin: [
{
txid: '8370db30d94761ab9a11b71ecd22541151bf6125c8c613f0f6fab8ab794565a7',
vout: 0,
scriptSig: {
asm: '304402207e9631c53dfc8a9a793d1916469628c6b7c5780c01c2f676d51ef21b0ba4926f022069feb471ec869a49f8d108d0aaba04e7cd36e60a7500109d86537f55698930d4[ALL|FORKID] 02791b19a39165dbd83403d6df268d44fd621da30581b0b6e5cb15a7101ed58851',
hex: '47304402207e9631c53dfc8a9a793d1916469628c6b7c5780c01c2f676d51ef21b0ba4926f022069feb471ec869a49f8d108d0aaba04e7cd36e60a7500109d86537f55698930d4412102791b19a39165dbd83403d6df268d44fd621da30581b0b6e5cb15a7101ed58851'
},
sequence: 4294967295,
address: 'bitcoincash:qpvsg9vl9a5mlf37a7n3yce6pktdctn73qwgaqm3wq',
value: 0.00051303,
tokenQty: 0,
tokenQtyStr: '0',
tokenId: null
}
],
vout: [
{
value: 0,
n: 0,
scriptPubKey: {
asm: 'OP_RETURN 5262419 1 47454e45534953 54524f5554 54726f75742773207465737420746f6b656e 74726f757473626c6f672e636f6d 0 2 2 000000174876e800',
hex: '6a04534c500001010747454e455349530554524f55541254726f75742773207465737420746f6b656e0e74726f757473626c6f672e636f6d4c000102010208000000174876e800',
type: 'nulldata'
},
tokenQtyStr: '0',
tokenQty: 0
}
],
hex: '0200000001a7654579abb8faf6f013c6c82561bf51115422cd1eb7119aab6147d930db7083000000006a47304402207e9631c53dfc8a9a793d1916469628c6b7c5780c01c2f676d51ef21b0ba4926f022069feb471ec869a49f8d108d0aaba04e7cd36e60a7500109d86537f55698930d4412102791b19a39165dbd83403d6df268d44fd621da30581b0b6e5cb15a7101ed58851ffffffff040000000000000000476a04534c500001010747454e455349530554524f55541254726f75742773207465737420746f6b656e0e74726f757473626c6f672e636f6d4c000102010208000000174876e80022020000000000001976a914db4d39ceb7794ffe5d06855f249e1d3a7f1b024088ac22020000000000001976a914db4d39ceb7794ffe5d06855f249e1d3a7f1b024088accec20000000000001976a9145904159f2f69bfa63eefa712633a0d96dc2e7e8888ac00000000',
blockhash: '0000000000000000009f65225a3e12e23a7ea057c869047e0f36563a1f410267',
confirmations: 97398,
time: 1581773131,
blocktime: 1581773131,
blockheight: 622414,
isSlpTx: true,
tokenTxType: 'GENESIS',
tokenId: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
tokenType: 1,
tokenTicker: 'TROUT',
tokenName: "Trout's test token",
tokenDecimals: 2,
tokenUri: 'troutsblog.com',
tokenDocHash: '',
isValidSlp: true
}
}
const balance = {
balance: {
utxos: [
{
txid: 'a24a6a4abf06fabd799ecea4f8fac6a9ff21e6a8dd6169a3c2ebc03665329db9',
vout: 1,
type: 'token',
qty: '1800',
tokenId: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
address: 'bitcoincash:qrqy3kj7r822ps6628vwqq5k8hyjl6ey3y4eea2m4s'
}
],
txs: [
{
txid: '078b2c48ed1db0d5d5996f2889b8d847a49200d0a781f6aa6752f740f312688f',
height: 717796
},
{
txid: 'a24a6a4abf06fabd799ecea4f8fac6a9ff21e6a8dd6169a3c2ebc03665329db9',
height: 717832
}
],
balances: [
{
tokenId: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
qty: '1800'
}
]
}
}
const status = {
status: {
startBlockHeight: 543376,
syncedBlockHeight: 722860,
chainBlockHeight: 722679
}
}
module.exports = {
tokenStats,
txData,
balance,
status
}
+258
View File
@@ -0,0 +1,258 @@
const chai = require('chai')
const assert = chai.assert
const axios = require('axios')
const sinon = require('sinon')
const BCHJS = require('../../src/bch-js')
const bchjs = new BCHJS()
const mockData = require('./fixtures/psf-slp-indexer-mock')
describe('#PsfSlpIndexer', () => {
let sandbox
beforeEach(() => (sandbox = sinon.createSandbox()))
afterEach(() => sandbox.restore())
describe('#status', () => {
it('should GET status', async () => {
// Stub the network call.
sandbox.stub(axios, 'get').resolves({ data: mockData.status })
const result = await bchjs.PsfSlpIndexer.status()
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, 'status')
assert.property(result.status, 'startBlockHeight')
assert.property(result.status, 'syncedBlockHeight')
assert.property(result.status, 'chainBlockHeight')
})
it('should handle axios error', async () => {
try {
// Stub the network call.
sandbox.stub(axios, 'get').throws(new Error('test error'))
await bchjs.PsfSlpIndexer.status()
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
assert.include(err.message, 'test error')
}
})
it('should handle request error', async () => {
try {
// Stub the network call.
const testErr = new Error()
testErr.response = { data: { status: 422 } }
sandbox.stub(axios, 'get').throws(testErr)
await bchjs.PsfSlpIndexer.status()
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
assert.equal(err.status, 422)
}
})
})
describe('#balance', () => {
it('should GET balance', async () => {
// Stub the network call.
sandbox.stub(axios, 'post').resolves({ data: mockData.balance })
const addr = 'bitcoincash:qzmd5vxgh9m22m6fgvm57yd6kjnjl9qnwywsf3583n'
const result = await bchjs.PsfSlpIndexer.balance(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, 'balance')
assert.property(result.balance, 'utxos')
assert.property(result.balance, 'txs')
assert.property(result.balance, 'balances')
assert.isArray(result.balance.utxos)
assert.isArray(result.balance.txs)
assert.isArray(result.balance.balances)
})
it('should throw an error for improper input', async () => {
try {
const addr = 12345
await bchjs.PsfSlpIndexer.balance(addr)
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
// console.log(`err: `, err)
assert.include(err.message, 'Input address must be a string.')
}
})
it('should handle axios error', async () => {
try {
// Stub the network call.
sandbox.stub(axios, 'post').throws(new Error('test error'))
const addr = 'bitcoincash:qzmd5vxgh9m22m6fgvm57yd6kjnjl9qnwywsf3583n'
await bchjs.PsfSlpIndexer.balance(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
assert.include(err.message, 'test error')
}
})
it('should handle request error', async () => {
try {
// Stub the network call.
const testErr = new Error()
testErr.response = { data: { status: 422 } }
sandbox.stub(axios, 'post').throws(testErr)
const addr = 'bitcoincash:qzmd5vxgh9m22m6fgvm57yd6kjnjl9qnwywsf3583n'
await bchjs.PsfSlpIndexer.balance(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
assert.equal(err.status, 422)
}
})
})
describe('#tokenStats', () => {
it('should GET token stats', async () => {
// Stub the network call.
sandbox.stub(axios, 'post').resolves({ data: mockData.tokenStats })
const tokenId =
'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
const result = await bchjs.PsfSlpIndexer.tokenStats(tokenId)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, 'tokenData')
assert.property(result.tokenData, 'type')
assert.property(result.tokenData, 'ticker')
assert.property(result.tokenData, 'name')
assert.property(result.tokenData, 'tokenId')
assert.property(result.tokenData, 'documentUri')
assert.property(result.tokenData, 'documentHash')
assert.property(result.tokenData, 'decimals')
assert.property(result.tokenData, 'mintBatonIsActive')
assert.property(result.tokenData, 'tokensInCirculationBN')
assert.property(result.tokenData, 'tokensInCirculationStr')
assert.property(result.tokenData, 'blockCreated')
assert.property(result.tokenData, 'totalBurned')
assert.property(result.tokenData, 'totalMinted')
assert.property(result.tokenData, 'txs')
})
it('should throw an error for improper input', async () => {
try {
const tokenId = 12345
await bchjs.PsfSlpIndexer.tokenStats(tokenId)
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
// console.log(`err: `, err)
assert.include(err.message, 'Input tokenId must be a string.')
}
})
it('should handle axios error', async () => {
try {
// Stub the network call.
sandbox.stub(axios, 'post').throws(new Error('test error'))
const tokenId =
'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
await bchjs.PsfSlpIndexer.tokenStats(tokenId)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
assert.include(err.message, 'test error')
}
})
it('should handle request error', async () => {
try {
// Stub the network call.
const testErr = new Error()
testErr.response = { data: { status: 422 } }
sandbox.stub(axios, 'post').throws(testErr)
const tokenId =
'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
await bchjs.PsfSlpIndexer.tokenStats(tokenId)
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
assert.equal(err.status, 422)
}
})
})
describe('#tx', () => {
it('should GET transaction data', async () => {
// Stub the network call.
sandbox.stub(axios, 'post').resolves({ data: mockData.txData })
const txid =
'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
const result = await bchjs.PsfSlpIndexer.tx(txid)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, 'txData')
assert.property(result.txData, 'txid')
assert.property(result.txData, 'hash')
assert.property(result.txData, 'version')
assert.property(result.txData, 'size')
assert.property(result.txData, 'locktime')
assert.property(result.txData, 'vin')
assert.property(result.txData, 'vout')
assert.property(result.txData, 'hex')
assert.property(result.txData, 'blockhash')
assert.property(result.txData, 'confirmations')
assert.property(result.txData, 'time')
assert.property(result.txData, 'blocktime')
assert.property(result.txData, 'blockheight')
assert.property(result.txData, 'isSlpTx')
assert.property(result.txData, 'tokenTxType')
assert.property(result.txData, 'tokenId')
assert.property(result.txData, 'tokenType')
assert.property(result.txData, 'tokenTicker')
assert.property(result.txData, 'tokenName')
assert.property(result.txData, 'tokenDecimals')
assert.property(result.txData, 'tokenUri')
assert.property(result.txData, 'tokenDocHash')
assert.property(result.txData, 'isValidSlp')
})
it('should throw an error for improper input', async () => {
try {
const txid = 12345
await bchjs.PsfSlpIndexer.tx(txid)
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
// console.log(`err: `, err)
assert.include(err.message, 'Input txid must be a string.')
}
})
it('should handle axios error', async () => {
try {
// Stub the network call.
sandbox.stub(axios, 'post').throws(new Error('test error'))
const txid =
'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
await bchjs.PsfSlpIndexer.tx(txid)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
assert.include(err.message, 'test error')
}
})
it('should handle request error', async () => {
try {
// Stub the network call.
const testErr = new Error()
testErr.response = { data: { status: 422 } }
sandbox.stub(axios, 'post').throws(testErr)
const txid =
'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
await bchjs.PsfSlpIndexer.tx(txid)
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
assert.equal(err.status, 422)
}
})
})
})