diff --git a/src/routes/v5/psf-slp-indexer.js b/src/routes/v5/psf-slp-indexer.js index ebff388..1dc759e 100644 --- a/src/routes/v5/psf-slp-indexer.js +++ b/src/routes/v5/psf-slp-indexer.js @@ -225,6 +225,18 @@ class PsfSlpIndexer { } } + /** + * @api {post} /psf/slp/token/data Get token data + * @apiName Get token data + * @apiGroup PSF SLP + * @apiDescription Get mutable and immutable data if the token contains them. + * + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST -d '{ "tokenId": "f055256b938f1ecfa270459d6f12c7c8c82b66d3263c03d5074445a2b1a498a3" }' localhost:3000/v5/psf/slp/token/data + * + * + */ // Get mutable and immutable data for a token, if the token was created with // such data. // @@ -276,6 +288,7 @@ class PsfSlpIndexer { res.status(200) return res.json(tokenData) } catch (err) { + console.log('Error in getTokenData(): ', err) return _this.errorHandler(err, res) } } diff --git a/test/v5/psf-slp-indexer.js b/test/v5/psf-slp-indexer.js index 7215a7b..1fe7d7f 100644 --- a/test/v5/psf-slp-indexer.js +++ b/test/v5/psf-slp-indexer.js @@ -498,6 +498,7 @@ describe('#PsfSlpIndexer', () => { assert.property(status, 'chainBlockHeight') }) }) + describe('#errorHandler', () => { it('should handle unexpected errors', () => { sandbox.stub(uut.routeUtils, 'decodeError').returns({ msg: false }) @@ -507,6 +508,7 @@ describe('#PsfSlpIndexer', () => { assert.equal(res.statusCode, 400, 'HTTP status code 400 expected.') assert.property(result, 'error') }) + it('should handle unknow errors', () => { sandbox.stub(uut.routeUtils, 'decodeError').returns({ msg: false }) @@ -516,6 +518,7 @@ describe('#PsfSlpIndexer', () => { assert.property(result, 'error') }) }) + describe('#checkEnvVar', () => { it('should throw errors if SLP_INDEXER_API env var is not provided', () => { const savedSlpIndexerUrl = process.env.SLP_INDEXER_API @@ -533,6 +536,7 @@ describe('#PsfSlpIndexer', () => { process.env.SLP_INDEXER_API = savedSlpIndexerUrl }) }) + describe('#getCIDData', () => { it('should throw errors if cid is not provided', async () => { try { @@ -546,6 +550,7 @@ describe('#PsfSlpIndexer', () => { ) } }) + it('should handle axios error', async () => { try { sandbox.stub(uut.axios, 'get').throws(new Error('test error')) @@ -560,6 +565,7 @@ describe('#PsfSlpIndexer', () => { ) } }) + it('should return cid object data', async () => { sandbox.stub(uut.axios, 'get').resolves({ data: mockData.immutableData }) const cid = 'bafybeigp3bfmj6woms7pywb7s7r6npcdudvsabvzne2chyspxtdendrwmy' @@ -581,6 +587,7 @@ describe('#PsfSlpIndexer', () => { ) } }) + it('should handle bchjs error', async () => { try { sandbox.stub(uut.bchjs.Electrumx, 'txData').throws(new Error('test error')) @@ -595,12 +602,14 @@ describe('#PsfSlpIndexer', () => { ) } }) + it('should return data', async () => { sandbox.stub(uut.bchjs.Electrumx, 'txData').resolves({ details: mockData.txData.txData }) const txid = 'c37ba29f40ecc61662ea56324fdb72a5f1e66add2078854c2144765b9030358a' const result = await uut.decodeOpReturn(txid) assert.isString(result) }) + it('should return false if data is not found', async () => { sandbox.stub(uut.bchjs.Electrumx, 'txData').resolves({ details: { vout: [] } }) const txid = 'c37ba29f40ecc61662ea56324fdb72a5f1e66add2078854c2144765b9030358a' @@ -608,6 +617,7 @@ describe('#PsfSlpIndexer', () => { assert.isFalse(result) }) }) + describe('#getTokenData', async () => { it('should throw 400 error if tokenId is missing', async () => { const result = await uut.getTokenData(req, res) @@ -715,6 +725,7 @@ describe('#PsfSlpIndexer', () => { assert.property(genesisData, 'totalMinted') assert.property(genesisData, 'txs') }) + it('should GET tokens data if immutableData data not found', async function () { req.body.tokenId = 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2' @@ -752,6 +763,7 @@ describe('#PsfSlpIndexer', () => { assert.property(genesisData, 'totalMinted') assert.property(genesisData, 'txs') }) + it('should GET tokens data if mutable data not found', async function () { req.body.tokenId = 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2' @@ -790,6 +802,7 @@ describe('#PsfSlpIndexer', () => { assert.property(genesisData, 'txs') }) }) + describe('#getMutableData', () => { it('should throw errors if documentHash is not provided', async () => { try { @@ -803,6 +816,7 @@ describe('#PsfSlpIndexer', () => { ) } }) + it('should throw errors if cid is not provided in OP Return', async () => { try { sandbox.stub(uut, 'decodeOpReturn').resolves('{}') @@ -838,6 +852,7 @@ describe('#PsfSlpIndexer', () => { ) } }) + it('should handle bchjs error', async () => { try { sandbox.stub(uut, 'decodeOpReturn').resolves(mockData.decodedOpReturn) @@ -854,6 +869,7 @@ describe('#PsfSlpIndexer', () => { ) } }) + it('should skip mutable data if was not generated by the MDA private key', async () => { try { sandbox.stub(uut, 'decodeOpReturn').resolves(mockData.decodedOpReturn) @@ -873,6 +889,7 @@ describe('#PsfSlpIndexer', () => { ) } }) + it('should return mutable data', async () => { sandbox.stub(uut, 'decodeOpReturn') .onFirstCall().resolves(mockData.decodedOpReturn)