From d144b135005fcbfd2c20ddce0a63a0b7d9f99d91 Mon Sep 17 00:00:00 2001 From: Daniel Gonzalez Date: Wed, 4 May 2022 18:29:54 -0400 Subject: [PATCH 1/2] feat(slpindexer): Added bchjs.PsfSlpIndexer.getTokenData() --- src/psf-slp-indexer.js | 65 +++++++++++++++- .../bchn/psf-slp-indexer.integration.js | 18 +++++ test/unit/fixtures/psf-slp-indexer-mock.js | 15 +++- test/unit/psf-slp-indexer.js | 74 +++++++++++++++++++ 4 files changed, 170 insertions(+), 2 deletions(-) diff --git a/src/psf-slp-indexer.js b/src/psf-slp-indexer.js index 683d3d2..75296b3 100644 --- a/src/psf-slp-indexer.js +++ b/src/psf-slp-indexer.js @@ -41,7 +41,7 @@ class PsfSlpIndexer { this.rawTransaction = new RawTransaction(config) this.slpUtils = new SlpUtils(config) - // _this = this + // _this = this } /** @@ -374,6 +374,69 @@ class PsfSlpIndexer { return false } } + + /** + * @api PsfSlpIndexer.getTokenData() getTokenData() + * @apiName Token Data + * @apiGroup PSF SLP + * @apiDescription Get mutable and immutable data if the token contains them. + * + * @apiExample Example usage: + * (async () => { + * try { + * let tokenData = await bchjs.PsfSlpIndexer.getTokenData('a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2') + * console.log(tokenData) + * } catch(error) { + * console.error(error) + * } + * })() + * + * { + * genesisData: { + * 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' + * ] + * }, + * immutableData :{ + * issuer:"FullStack.cash.", + * website:"https://fullstack.cash/", + * dateCreated:"2022-01-11" + * }, + * mutableData :{ + * "tokenIcon":"https://gateway.ipfs.io/ipfs/bafybeiehitanirn5gmhqjg44xrmdtomn4n5lu5yjoepsvgpswk5mggaw6i/LP_logo-1.png", + * "about":"Mutable data managed with npm package: https://www.npmjs.com/package/slp-mutable-data" + * } + * } + * + */ + async getTokenData (tokenId) { + try { + // Handle single address. + if (typeof tokenId === 'string') { + const response = await axios.post( + 'https://bchn.fullstack.cash/v5/psf/slp/token/data/', + { 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 + } + } } module.exports = PsfSlpIndexer diff --git a/test/integration/chains/bchn/psf-slp-indexer.integration.js b/test/integration/chains/bchn/psf-slp-indexer.integration.js index 34ec0e2..2bfe17b 100644 --- a/test/integration/chains/bchn/psf-slp-indexer.integration.js +++ b/test/integration/chains/bchn/psf-slp-indexer.integration.js @@ -124,6 +124,24 @@ describe('#psf-slp-indexer', () => { } }) }) + + describe('#getTokenData', () => { + it('should get token data', async () => { + const tokenId = + 'f055256b938f1ecfa270459d6f12c7c8c82b66d3263c03d5074445a2b1a498a3' + + const result = await bchjs.PsfSlpIndexer.getTokenData(tokenId) + console.log('result: ', result) + + assert.property(result, 'genesisData') + assert.property(result, 'immutableData') + assert.property(result, 'mutableData') + + assert.isObject(result.genesisData) + assert.isObject(result.immutableData) + assert.isObject(result.mutableData) + }) + }) }) // Promise-based sleep function diff --git a/test/unit/fixtures/psf-slp-indexer-mock.js b/test/unit/fixtures/psf-slp-indexer-mock.js index 255e5ec..8f9dbcb 100644 --- a/test/unit/fixtures/psf-slp-indexer-mock.js +++ b/test/unit/fixtures/psf-slp-indexer-mock.js @@ -144,10 +144,23 @@ const tokenData01 = { qty: {} } +const tokenData = { + genesisData: tokenStats.tokenData, + immutableData: { + issuer: 'Launchpad Intellectual Property, Inc.', + website: 'http://launchpadip.com/', + dateCreated: '2022-01-11' + }, + mutableData: { + tokenIcon: 'https://gateway.ipfs.io/ipfs/bafybeiehitanirn5gmhqjg44xrmdtomn4n5lu5yjoepsvgpswk5mggaw6i/LP_logo-1.png', + about: 'Mutable data managed with npm package: https://www.npmjs.com/package/slp-mutable-data' + } +} module.exports = { tokenStats, txData, balance, status, - tokenData01 + tokenData01, + tokenData } diff --git a/test/unit/psf-slp-indexer.js b/test/unit/psf-slp-indexer.js index cd14ea0..49c1295 100644 --- a/test/unit/psf-slp-indexer.js +++ b/test/unit/psf-slp-indexer.js @@ -336,4 +336,78 @@ describe('#PsfSlpIndexer', () => { assert.equal(result, false) }) }) + describe('#getTokenData', () => { + it('should GET token data', async () => { + // Stub the network call. + sandbox.stub(axios, 'post').resolves({ data: mockData.tokenData }) + + const tokenId = + 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2' + const result = await bchjs.PsfSlpIndexer.getTokenData(tokenId) + assert.property(result, 'genesisData') + assert.property(result, 'immutableData') + assert.property(result, 'mutableData') + + assert.isObject(result.genesisData) + assert.isObject(result.immutableData) + assert.isObject(result.mutableData) + + assert.property(result.genesisData, 'type') + assert.property(result.genesisData, 'ticker') + assert.property(result.genesisData, 'name') + assert.property(result.genesisData, 'tokenId') + assert.property(result.genesisData, 'documentUri') + assert.property(result.genesisData, 'documentHash') + assert.property(result.genesisData, 'decimals') + assert.property(result.genesisData, 'mintBatonIsActive') + assert.property(result.genesisData, 'tokensInCirculationBN') + assert.property(result.genesisData, 'tokensInCirculationStr') + assert.property(result.genesisData, 'blockCreated') + assert.property(result.genesisData, 'totalBurned') + assert.property(result.genesisData, 'totalMinted') + }) + + it('should throw an error for improper input', async () => { + try { + const tokenId = 12345 + + await bchjs.PsfSlpIndexer.getTokenData(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.getTokenData(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.getTokenData(tokenId) + assert.equal(true, false, 'Unexpected result!') + } catch (err) { + assert.equal(err.status, 422) + } + }) + }) }) From 7da010e7af6ff4c2f5ea45e7f36ce567e789574f Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Sat, 7 May 2022 20:20:30 -0700 Subject: [PATCH 2/2] Using config.restURL instead of hard-coded URL --- src/psf-slp-indexer.js | 6 +++++- test/integration/chains/bchn/psf-slp-indexer.integration.js | 2 +- test/unit/psf-slp-indexer.js | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/psf-slp-indexer.js b/src/psf-slp-indexer.js index 75296b3..6484906 100644 --- a/src/psf-slp-indexer.js +++ b/src/psf-slp-indexer.js @@ -422,10 +422,14 @@ class PsfSlpIndexer { */ async getTokenData (tokenId) { try { + const url = `${this.restURL}psf/slp/token/data` + // console.log(`url: ${url}`) + // Handle single address. if (typeof tokenId === 'string') { const response = await axios.post( - 'https://bchn.fullstack.cash/v5/psf/slp/token/data/', + // 'https://bchn.fullstack.cash/v5/psf/slp/token/data/', + url, { tokenId }, this.axiosOptions ) diff --git a/test/integration/chains/bchn/psf-slp-indexer.integration.js b/test/integration/chains/bchn/psf-slp-indexer.integration.js index 2bfe17b..95b8ad9 100644 --- a/test/integration/chains/bchn/psf-slp-indexer.integration.js +++ b/test/integration/chains/bchn/psf-slp-indexer.integration.js @@ -131,7 +131,7 @@ describe('#psf-slp-indexer', () => { 'f055256b938f1ecfa270459d6f12c7c8c82b66d3263c03d5074445a2b1a498a3' const result = await bchjs.PsfSlpIndexer.getTokenData(tokenId) - console.log('result: ', result) + // console.log('result: ', result) assert.property(result, 'genesisData') assert.property(result, 'immutableData') diff --git a/test/unit/psf-slp-indexer.js b/test/unit/psf-slp-indexer.js index 49c1295..7fc29f2 100644 --- a/test/unit/psf-slp-indexer.js +++ b/test/unit/psf-slp-indexer.js @@ -336,6 +336,7 @@ describe('#PsfSlpIndexer', () => { assert.equal(result, false) }) }) + describe('#getTokenData', () => { it('should GET token data', async () => { // Stub the network call.