@psf/bch-js 6.2.12 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@psf/bch-js",
3
- "version": "6.2.12",
3
+ "version": "6.3.0",
4
4
  "description": "A JavaScript library for working with Bitcoin Cash, eCash, and SLP Tokens",
5
5
  "author": "Chris Troutner <chris.troutner@gmail.com>",
6
6
  "contributors": [
@@ -41,7 +41,7 @@ class PsfSlpIndexer {
41
41
  this.rawTransaction = new RawTransaction(config)
42
42
  this.slpUtils = new SlpUtils(config)
43
43
 
44
- // _this = this
44
+ // _this = this
45
45
  }
46
46
 
47
47
  /**
@@ -374,6 +374,73 @@ class PsfSlpIndexer {
374
374
  return false
375
375
  }
376
376
  }
377
+
378
+ /**
379
+ * @api PsfSlpIndexer.getTokenData() getTokenData()
380
+ * @apiName Token Data
381
+ * @apiGroup PSF SLP
382
+ * @apiDescription Get mutable and immutable data if the token contains them.
383
+ *
384
+ * @apiExample Example usage:
385
+ * (async () => {
386
+ * try {
387
+ * let tokenData = await bchjs.PsfSlpIndexer.getTokenData('a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2')
388
+ * console.log(tokenData)
389
+ * } catch(error) {
390
+ * console.error(error)
391
+ * }
392
+ * })()
393
+ *
394
+ * {
395
+ * genesisData: {
396
+ * type: 1,
397
+ * ticker: 'TROUT',
398
+ * name: "Trout's test token",
399
+ * tokenId: 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2',
400
+ * documentUri: 'troutsblog.com',
401
+ * documentHash: '',
402
+ * decimals: 2,
403
+ * mintBatonIsActive: true,
404
+ * tokensInCirculationBN: '100098953386',
405
+ * tokensInCirculationStr: '100098953386',
406
+ * blockCreated: 622414,
407
+ * totalBurned: '1046614',
408
+ * totalMinted: '100100000000'
409
+ * ]
410
+ * },
411
+ * immutableData :{
412
+ * issuer:"FullStack.cash.",
413
+ * website:"https://fullstack.cash/",
414
+ * dateCreated:"2022-01-11"
415
+ * },
416
+ * mutableData :{
417
+ * "tokenIcon":"https://gateway.ipfs.io/ipfs/bafybeiehitanirn5gmhqjg44xrmdtomn4n5lu5yjoepsvgpswk5mggaw6i/LP_logo-1.png",
418
+ * "about":"Mutable data managed with npm package: https://www.npmjs.com/package/slp-mutable-data"
419
+ * }
420
+ * }
421
+ *
422
+ */
423
+ async getTokenData (tokenId) {
424
+ try {
425
+ const url = `${this.restURL}psf/slp/token/data`
426
+ // console.log(`url: ${url}`)
427
+
428
+ // Handle single address.
429
+ if (typeof tokenId === 'string') {
430
+ const response = await axios.post(
431
+ // 'https://bchn.fullstack.cash/v5/psf/slp/token/data/',
432
+ url,
433
+ { tokenId },
434
+ this.axiosOptions
435
+ )
436
+ return response.data
437
+ }
438
+ throw new Error('Input tokenId must be a string.')
439
+ } catch (error) {
440
+ if (error.response && error.response.data) throw error.response.data
441
+ else throw error
442
+ }
443
+ }
377
444
  }
378
445
 
379
446
  module.exports = PsfSlpIndexer
package/src/slp/nft1.js CHANGED
@@ -147,7 +147,7 @@ class Nft1 {
147
147
  // Loop through the tokenUtxos array and find the minting baton.
148
148
  let mintBatonUtxo
149
149
  for (let i = 0; i < tokenUtxos.length; i++) {
150
- if (tokenUtxos[i].utxoType === 'minting-baton') {
150
+ if (tokenUtxos[i].utxoType === 'minting-baton' || tokenUtxos[i].type === 'baton') {
151
151
  mintBatonUtxo = tokenUtxos[i]
152
152
  }
153
153
  }
package/src/utxo.js CHANGED
@@ -92,7 +92,7 @@ class UTXO {
92
92
  // Get SLP UTXOs from the psf-slp-indexer
93
93
  try {
94
94
  const slpUtxoData = await this.psfSlpIndexer.balance(addr)
95
- console.log(`slpUtxoData: ${JSON.stringify(slpUtxoData, null, 2)}`)
95
+ // console.log(`slpUtxoData: ${JSON.stringify(slpUtxoData, null, 2)}`)
96
96
 
97
97
  slpUtxos = slpUtxoData.balance.utxos
98
98
  } catch (err) {
@@ -124,6 +124,24 @@ describe('#psf-slp-indexer', () => {
124
124
  }
125
125
  })
126
126
  })
127
+
128
+ describe('#getTokenData', () => {
129
+ it('should get token data', async () => {
130
+ const tokenId =
131
+ 'f055256b938f1ecfa270459d6f12c7c8c82b66d3263c03d5074445a2b1a498a3'
132
+
133
+ const result = await bchjs.PsfSlpIndexer.getTokenData(tokenId)
134
+ // console.log('result: ', result)
135
+
136
+ assert.property(result, 'genesisData')
137
+ assert.property(result, 'immutableData')
138
+ assert.property(result, 'mutableData')
139
+
140
+ assert.isObject(result.genesisData)
141
+ assert.isObject(result.immutableData)
142
+ assert.isObject(result.mutableData)
143
+ })
144
+ })
127
145
  })
128
146
 
129
147
  // Promise-based sleep function
@@ -87,7 +87,7 @@ describe('#UTXO', () => {
87
87
  const addr = 'simpleledger:qz5l5yzz9r09hw9aadcz53elp2knx6gyg5qk3s8md7'
88
88
 
89
89
  const result = await bchjs.Utxo.get(addr)
90
- console.log(`result: ${JSON.stringify(result, null, 2)}`)
90
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
91
91
 
92
92
  // Assert that minting batons are correctly identified.
93
93
  assert.isAbove(result.slpUtxos.type1.mintBatons.length, 0)
@@ -113,15 +113,14 @@ describe('#UTXO', () => {
113
113
  assert.isAbove(result.slpUtxos.group.mintBatons.length, 0)
114
114
  })
115
115
 
116
- // it('should filter NFTs', async () => {
117
- // const addr = 'bitcoincash:qq7vp2kvejsql898a2760kuq6xz00h0a5vs4h72ysz'
118
- //
119
- // const result = await bchjs.Utxo.get(addr)
120
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
121
- //
122
- // // assert.isAbove(result.slpUtxos.group.tokens.length, 0)
123
- // // assert.isAbove(result.slpUtxos.group.mintBatons.length, 0)
124
- // })
116
+ it('should filter NFTs', async () => {
117
+ const addr = 'simpleledger:qq7vp2kvejsql898a2760kuq6xz00h0a5vuwu9lywu'
118
+
119
+ const result = await bchjs.Utxo.get(addr)
120
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
121
+
122
+ assert.isAbove(result.slpUtxos.nft.tokens.length, 0)
123
+ })
125
124
  })
126
125
  })
127
126
 
@@ -144,10 +144,23 @@ const tokenData01 = {
144
144
  qty: {}
145
145
  }
146
146
 
147
+ const tokenData = {
148
+ genesisData: tokenStats.tokenData,
149
+ immutableData: {
150
+ issuer: 'Launchpad Intellectual Property, Inc.',
151
+ website: 'http://launchpadip.com/',
152
+ dateCreated: '2022-01-11'
153
+ },
154
+ mutableData: {
155
+ tokenIcon: 'https://gateway.ipfs.io/ipfs/bafybeiehitanirn5gmhqjg44xrmdtomn4n5lu5yjoepsvgpswk5mggaw6i/LP_logo-1.png',
156
+ about: 'Mutable data managed with npm package: https://www.npmjs.com/package/slp-mutable-data'
157
+ }
158
+ }
147
159
  module.exports = {
148
160
  tokenStats,
149
161
  txData,
150
162
  balance,
151
163
  status,
152
- tokenData01
164
+ tokenData01,
165
+ tokenData
153
166
  }
@@ -336,4 +336,79 @@ describe('#PsfSlpIndexer', () => {
336
336
  assert.equal(result, false)
337
337
  })
338
338
  })
339
+
340
+ describe('#getTokenData', () => {
341
+ it('should GET token data', async () => {
342
+ // Stub the network call.
343
+ sandbox.stub(axios, 'post').resolves({ data: mockData.tokenData })
344
+
345
+ const tokenId =
346
+ 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
347
+ const result = await bchjs.PsfSlpIndexer.getTokenData(tokenId)
348
+ assert.property(result, 'genesisData')
349
+ assert.property(result, 'immutableData')
350
+ assert.property(result, 'mutableData')
351
+
352
+ assert.isObject(result.genesisData)
353
+ assert.isObject(result.immutableData)
354
+ assert.isObject(result.mutableData)
355
+
356
+ assert.property(result.genesisData, 'type')
357
+ assert.property(result.genesisData, 'ticker')
358
+ assert.property(result.genesisData, 'name')
359
+ assert.property(result.genesisData, 'tokenId')
360
+ assert.property(result.genesisData, 'documentUri')
361
+ assert.property(result.genesisData, 'documentHash')
362
+ assert.property(result.genesisData, 'decimals')
363
+ assert.property(result.genesisData, 'mintBatonIsActive')
364
+ assert.property(result.genesisData, 'tokensInCirculationBN')
365
+ assert.property(result.genesisData, 'tokensInCirculationStr')
366
+ assert.property(result.genesisData, 'blockCreated')
367
+ assert.property(result.genesisData, 'totalBurned')
368
+ assert.property(result.genesisData, 'totalMinted')
369
+ })
370
+
371
+ it('should throw an error for improper input', async () => {
372
+ try {
373
+ const tokenId = 12345
374
+
375
+ await bchjs.PsfSlpIndexer.getTokenData(tokenId)
376
+ assert.equal(true, false, 'Unexpected result!')
377
+ } catch (err) {
378
+ // console.log(`err: `, err)
379
+ assert.include(err.message, 'Input tokenId must be a string.')
380
+ }
381
+ })
382
+
383
+ it('should handle axios error', async () => {
384
+ try {
385
+ // Stub the network call.
386
+ sandbox.stub(axios, 'post').throws(new Error('test error'))
387
+
388
+ const tokenId =
389
+ 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
390
+ await bchjs.PsfSlpIndexer.getTokenData(tokenId)
391
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
392
+ assert.equal(true, false, 'Unexpected result!')
393
+ } catch (err) {
394
+ assert.include(err.message, 'test error')
395
+ }
396
+ })
397
+
398
+ it('should handle request error', async () => {
399
+ try {
400
+ // Stub the network call.
401
+ const testErr = new Error()
402
+ testErr.response = { data: { status: 422 } }
403
+ sandbox.stub(axios, 'post').throws(testErr)
404
+
405
+ const tokenId =
406
+ 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
407
+ await bchjs.PsfSlpIndexer.getTokenData(tokenId)
408
+ assert.equal(true, false, 'Unexpected result!')
409
+ } catch (err) {
410
+ assert.equal(err.status, 422)
411
+ }
412
+ })
413
+ })
339
414
  })