@psf/bch-js 4.20.28 → 5.1.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.
@@ -30,965 +30,971 @@ describe('#SLP', () => {
30
30
  })
31
31
 
32
32
  describe('#util', () => {
33
- describe('#list', () => {
34
- it('should get information on the Spice token', async () => {
35
- const tokenId =
36
- '4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf'
37
-
38
- const result = await bchjs.SLP.Utils.list(tokenId)
39
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
40
-
41
- assert.hasAnyKeys(result, [
42
- 'decimals',
43
- 'timestamp',
44
- 'timestamp_unix',
45
- 'versionType',
46
- 'documentUri',
47
- 'symbol',
48
- 'name',
49
- 'containsBaton',
50
- 'id',
51
- 'documentHash',
52
- 'initialTokenQty',
53
- 'blockCreated',
54
- 'blockLastActiveSend',
55
- 'blockLastActiveMint',
56
- 'txnsSinceGenesis',
57
- 'validAddress',
58
- 'totalMinted',
59
- 'totalBurned',
60
- 'circulatingSupply',
61
- 'mintingBatonStatus'
62
- ])
63
- })
64
- })
65
-
66
- // describe("#decodeOpReturn", () => {
67
- // it("should decode the OP_RETURN for a SEND txid", async () => {
68
- // const txid =
69
- // "266844d53e46bbd7dd37134688dffea6e54d944edff27a0add63dd0908839bc1"
70
- //
71
- // const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
72
- // // console.log(`result: ${JSON.stringify(result, null, 2)}`)
73
- //
74
- // assert.hasAllKeys(result, [
75
- // "tokenType",
76
- // "transactionType",
77
- // "tokenId",
78
- // "spendData"
79
- // ])
80
- // })
81
- //
82
- // it("should decode the OP_RETURN for a GENESIS txid", async () => {
83
- // const txid =
84
- // "497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7"
85
- //
86
- // const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
87
- // // console.log(`result: ${JSON.stringify(result, null, 2)}`)
88
- //
89
- // assert.hasAllKeys(result, [
90
- // "tokenType",
91
- // "transactionType",
92
- // "ticker",
93
- // "name",
94
- // "documentUrl",
95
- // "documentHash",
96
- // "decimals",
97
- // "mintBatonVout",
98
- // "initialQty",
99
- // "tokensSentTo",
100
- // "batonHolder"
101
- // ])
102
- // })
103
- //
104
- // it("should decode the OP_RETURN for a MINT txid", async () => {
105
- // const txid =
106
- // "65f21bbfcd545e5eb515e38e861a9dfe2378aaa2c4e458eb9e59e4d40e38f3a4"
107
- //
108
- // const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
109
- // // console.log(`result: ${JSON.stringify(result, null, 2)}`)
110
- //
111
- // assert.hasAllKeys(result, [
112
- // "tokenType",
113
- // "transactionType",
114
- // "tokenId",
115
- // "mintBatonVout",
116
- // "batonStillExists",
117
- // "quantity",
118
- // "tokensSentTo",
119
- // "batonHolder"
120
- // ])
121
- // })
122
- //
123
- // it("should throw an error for a non-SLP transaction", async () => {
124
- // try {
125
- // const txid =
126
- // "3793d4906654f648e659f384c0f40b19c8f10c1e9fb72232a9b8edd61abaa1ec"
127
- //
128
- // await bchjs.SLP.Utils.decodeOpReturn(txid)
129
- //
130
- // assert.equal(true, false, "Unexpected result")
131
- // } catch (err) {
132
- // // console.log(`err: `, err)
133
- // assert.include(err.message, "Not an OP_RETURN")
134
- // }
135
- // })
136
- // })
137
-
138
- describe('#decodeOpReturn', () => {
139
- it('should decode the OP_RETURN for a SEND txid', async () => {
140
- const txid =
141
- '266844d53e46bbd7dd37134688dffea6e54d944edff27a0add63dd0908839bc1'
142
-
143
- const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
144
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
145
-
146
- assert.hasAllKeys(result, ['tokenType', 'txType', 'tokenId', 'amounts'])
147
- assert.equal(
148
- result.tokenId,
149
- '497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7'
150
- )
151
-
152
- // Verify outputs
153
- assert.equal(result.amounts.length, 2)
154
- assert.equal(result.amounts[0], '100000000')
155
- assert.equal(result.amounts[1], '99883300000000')
156
- })
157
-
158
- it('should decode the OP_RETURN for a GENESIS txid', async () => {
159
- const txid =
160
- '497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7'
161
-
162
- const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
163
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
164
-
165
- assert.hasAllKeys(result, [
166
- 'tokenType',
167
- 'txType',
168
- 'tokenId',
169
- 'ticker',
170
- 'name',
171
- 'documentUri',
172
- 'documentHash',
173
- 'decimals',
174
- 'mintBatonVout',
175
- 'qty'
176
- ])
177
- assert.equal(
178
- result.tokenId,
179
- '497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7'
180
- )
181
- assert.equal(result.txType, 'GENESIS')
182
- assert.equal(result.ticker, 'TOK-CH')
183
- assert.equal(result.name, 'TokyoCash')
184
- })
185
-
186
- it('should decode the OP_RETURN for a MINT txid', async () => {
187
- const txid =
188
- '65f21bbfcd545e5eb515e38e861a9dfe2378aaa2c4e458eb9e59e4d40e38f3a4'
189
-
190
- const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
191
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
192
-
193
- assert.hasAllKeys(result, [
194
- 'tokenType',
195
- 'txType',
196
- 'tokenId',
197
- 'mintBatonVout',
198
- 'qty'
199
- ])
200
- })
33
+ if (process.env.TESTSLP) {
34
+ describe('#list', () => {
35
+ it('should get information on the Spice token', async () => {
36
+ const tokenId =
37
+ '4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf'
201
38
 
202
- it('should throw an error for a non-SLP transaction', async () => {
203
- try {
204
- const txid =
205
- '3793d4906654f648e659f384c0f40b19c8f10c1e9fb72232a9b8edd61abaa1ec'
206
-
207
- await bchjs.SLP.Utils.decodeOpReturn(txid)
208
-
209
- assert.equal(true, false, 'Unexpected result')
210
- } catch (err) {
211
- // console.log(`err: `, err)
212
- assert.include(err.message, 'scriptpubkey not op_return')
213
- }
214
- })
39
+ const result = await bchjs.SLP.Utils.list(tokenId)
40
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
215
41
 
216
- // Note: This TX is interpreted as valid by the original decodeOpReturn().
217
- // Fixing this issue and related issues was the reason for creating the
218
- // decodeOpReturn2() method using the slp-parser library.
219
- it('should throw error for invalid SLP transaction', async () => {
220
- try {
42
+ assert.hasAnyKeys(result, [
43
+ 'decimals',
44
+ 'timestamp',
45
+ 'timestamp_unix',
46
+ 'versionType',
47
+ 'documentUri',
48
+ 'symbol',
49
+ 'name',
50
+ 'containsBaton',
51
+ 'id',
52
+ 'documentHash',
53
+ 'initialTokenQty',
54
+ 'blockCreated',
55
+ 'blockLastActiveSend',
56
+ 'blockLastActiveMint',
57
+ 'txnsSinceGenesis',
58
+ 'validAddress',
59
+ 'totalMinted',
60
+ 'totalBurned',
61
+ 'circulatingSupply',
62
+ 'mintingBatonStatus'
63
+ ])
64
+ })
65
+ })
66
+
67
+ // describe("#decodeOpReturn", () => {
68
+ // it("should decode the OP_RETURN for a SEND txid", async () => {
69
+ // const txid =
70
+ // "266844d53e46bbd7dd37134688dffea6e54d944edff27a0add63dd0908839bc1"
71
+ //
72
+ // const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
73
+ // // console.log(`result: ${JSON.stringify(result, null, 2)}`)
74
+ //
75
+ // assert.hasAllKeys(result, [
76
+ // "tokenType",
77
+ // "transactionType",
78
+ // "tokenId",
79
+ // "spendData"
80
+ // ])
81
+ // })
82
+ //
83
+ // it("should decode the OP_RETURN for a GENESIS txid", async () => {
84
+ // const txid =
85
+ // "497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7"
86
+ //
87
+ // const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
88
+ // // console.log(`result: ${JSON.stringify(result, null, 2)}`)
89
+ //
90
+ // assert.hasAllKeys(result, [
91
+ // "tokenType",
92
+ // "transactionType",
93
+ // "ticker",
94
+ // "name",
95
+ // "documentUrl",
96
+ // "documentHash",
97
+ // "decimals",
98
+ // "mintBatonVout",
99
+ // "initialQty",
100
+ // "tokensSentTo",
101
+ // "batonHolder"
102
+ // ])
103
+ // })
104
+ //
105
+ // it("should decode the OP_RETURN for a MINT txid", async () => {
106
+ // const txid =
107
+ // "65f21bbfcd545e5eb515e38e861a9dfe2378aaa2c4e458eb9e59e4d40e38f3a4"
108
+ //
109
+ // const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
110
+ // // console.log(`result: ${JSON.stringify(result, null, 2)}`)
111
+ //
112
+ // assert.hasAllKeys(result, [
113
+ // "tokenType",
114
+ // "transactionType",
115
+ // "tokenId",
116
+ // "mintBatonVout",
117
+ // "batonStillExists",
118
+ // "quantity",
119
+ // "tokensSentTo",
120
+ // "batonHolder"
121
+ // ])
122
+ // })
123
+ //
124
+ // it("should throw an error for a non-SLP transaction", async () => {
125
+ // try {
126
+ // const txid =
127
+ // "3793d4906654f648e659f384c0f40b19c8f10c1e9fb72232a9b8edd61abaa1ec"
128
+ //
129
+ // await bchjs.SLP.Utils.decodeOpReturn(txid)
130
+ //
131
+ // assert.equal(true, false, "Unexpected result")
132
+ // } catch (err) {
133
+ // // console.log(`err: `, err)
134
+ // assert.include(err.message, "Not an OP_RETURN")
135
+ // }
136
+ // })
137
+ // })
138
+
139
+ describe('#decodeOpReturn', () => {
140
+ it('should decode the OP_RETURN for a SEND txid', async () => {
221
141
  const txid =
222
- 'a60a522cc11ad7011b74e57fbabbd99296e4b9346bcb175dcf84efb737030415'
142
+ '266844d53e46bbd7dd37134688dffea6e54d944edff27a0add63dd0908839bc1'
223
143
 
224
- await bchjs.SLP.Utils.decodeOpReturn(txid)
144
+ const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
225
145
  // console.log(`result: ${JSON.stringify(result, null, 2)}`)
226
- } catch (err) {
227
- // console.log(`err: `, err)
228
- assert.include(err.message, 'amount string size not 8 bytes')
229
- }
230
- })
231
- })
232
-
233
- describe('#tokenUtxoDetails', () => {
234
- // // This captures an important corner-case. When an SLP token is created, the
235
- // // change UTXO will contain the same SLP txid, but it is not an SLP UTXO.
236
- it('should return details on minting baton from genesis transaction', async () => {
237
- const utxos = [
238
- {
239
- txid:
240
- 'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
241
- vout: 3,
242
- amount: 0.00002015,
243
- satoshis: 2015,
244
- height: 594892,
245
- confirmations: 5
246
- },
247
- {
248
- txid:
249
- 'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
250
- vout: 2,
251
- amount: 0.00000546,
252
- satoshis: 546,
253
- height: 594892,
254
- confirmations: 5
255
- }
256
- ]
257
-
258
- const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
259
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
260
-
261
- assert.equal(data[0].isValid, false, 'Change UTXO marked as false.')
262
-
263
- assert.property(data[1], 'txid')
264
- assert.property(data[1], 'vout')
265
- assert.property(data[1], 'amount')
266
- assert.property(data[1], 'satoshis')
267
- assert.property(data[1], 'height')
268
- assert.property(data[1], 'confirmations')
269
- assert.property(data[1], 'utxoType')
270
- assert.property(data[1], 'tokenId')
271
- assert.property(data[1], 'tokenTicker')
272
- assert.property(data[1], 'tokenName')
273
- assert.property(data[1], 'tokenDocumentUrl')
274
- assert.property(data[1], 'tokenDocumentHash')
275
- assert.property(data[1], 'decimals')
276
- assert.property(data[1], 'isValid')
277
- assert.equal(data[1].isValid, true)
278
- })
279
146
 
280
- it('should return details for a MINT token utxo', async () => {
281
- // Mock the call to REST API
282
-
283
- const utxos = [
284
- {
285
- txid:
286
- 'cf4b922d1e1aa56b52d752d4206e1448ea76c3ebe69b3b97d8f8f65413bd5c76',
287
- vout: 1,
288
- amount: 0.00000546,
289
- satoshis: 546,
290
- height: 600297,
291
- confirmations: 76
292
- }
293
- ]
294
-
295
- const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
296
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
297
-
298
- assert.property(data[0], 'txid')
299
- assert.property(data[0], 'vout')
300
- assert.property(data[0], 'amount')
301
- assert.property(data[0], 'satoshis')
302
- assert.property(data[0], 'height')
303
- assert.property(data[0], 'confirmations')
304
- assert.property(data[0], 'utxoType')
305
- assert.property(data[0], 'transactionType')
306
- assert.property(data[0], 'tokenId')
307
- assert.property(data[0], 'tokenTicker')
308
- assert.property(data[0], 'tokenName')
309
- assert.property(data[0], 'tokenDocumentUrl')
310
- assert.property(data[0], 'tokenDocumentHash')
311
- assert.property(data[0], 'decimals')
312
- assert.property(data[0], 'mintBatonVout')
313
- assert.property(data[0], 'tokenQty')
314
- assert.property(data[0], 'isValid')
315
- assert.equal(data[0].isValid, true)
316
- })
317
-
318
- it('should return details for a simple SEND SLP token utxo', async () => {
319
- const utxos = [
320
- {
321
- txid:
322
- 'fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb',
323
- vout: 1,
324
- amount: 0.00000546,
325
- satoshis: 546,
326
- height: 596089,
327
- confirmations: 748
328
- }
329
- ]
330
-
331
- const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
332
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
333
-
334
- assert.property(data[0], 'txid')
335
- assert.property(data[0], 'vout')
336
- assert.property(data[0], 'amount')
337
- assert.property(data[0], 'satoshis')
338
- assert.property(data[0], 'height')
339
- assert.property(data[0], 'confirmations')
340
- assert.property(data[0], 'utxoType')
341
- assert.property(data[0], 'tokenId')
342
- assert.property(data[0], 'tokenTicker')
343
- assert.property(data[0], 'tokenName')
344
- assert.property(data[0], 'tokenDocumentUrl')
345
- assert.property(data[0], 'tokenDocumentHash')
346
- assert.property(data[0], 'decimals')
347
- assert.property(data[0], 'tokenQty')
348
- assert.property(data[0], 'isValid')
349
- assert.equal(data[0].isValid, true)
350
- })
351
-
352
- it('should handle BCH and SLP utxos in the same TX', async () => {
353
- const utxos = [
354
- {
355
- txid:
356
- 'd56a2b446d8149c39ca7e06163fe8097168c3604915f631bc58777d669135a56',
357
- vout: 3,
358
- value: '6816',
359
- height: 606848,
360
- confirmations: 13,
361
- satoshis: 6816
362
- },
363
- {
364
- txid:
365
- 'd56a2b446d8149c39ca7e06163fe8097168c3604915f631bc58777d669135a56',
366
- vout: 2,
367
- value: '546',
368
- height: 606848,
369
- confirmations: 13,
370
- satoshis: 546
371
- }
372
- ]
373
-
374
- const result = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
375
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
376
-
377
- assert.isArray(result)
378
- assert.equal(result.length, 2)
379
- assert.equal(result[0].isValid, false)
380
- assert.equal(result[1].isValid, true)
381
- })
382
-
383
- it('should handle problematic utxos', async () => {
384
- const utxos = [
385
- {
386
- txid:
387
- '0e3a217fc22612002031d317b4cecd9b692b66b52951a67b23c43041aefa3959',
388
- vout: 0,
389
- amount: 0.00018362,
390
- satoshis: 18362,
391
- height: 613483,
392
- confirmations: 124
393
- },
394
- {
395
- txid:
396
- '67fd3c7c3a6eb0fea9ab311b91039545086220f7eeeefa367fa28e6e43009f19',
397
- vout: 1,
398
- amount: 0.00000546,
399
- satoshis: 546,
400
- height: 612075,
401
- confirmations: 1532
402
- }
403
- ]
404
-
405
- const result = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
406
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
407
-
408
- assert.isArray(result)
409
- assert.equal(result.length, 2)
410
- assert.equal(result[0].isValid, false)
411
- assert.equal(result[1].isValid, true)
412
- })
413
-
414
- it('should return false for BCH-only UTXOs', async () => {
415
- const utxos = [
416
- {
417
- txid:
418
- 'a937f792c7c9eb23b4f344ce5c233d1ac0909217d0a504d71e6b1e4efb864a3b',
419
- vout: 0,
420
- amount: 0.00001,
421
- satoshis: 1000,
422
- confirmations: 0,
423
- ts: 1578424704
424
- },
425
- {
426
- txid:
427
- '53fd141c2e999e080a5860887441a2c45e9cbe262027e2bd2ac998fc76e43c44',
428
- vout: 0,
429
- amount: 0.00001,
430
- satoshis: 1000,
431
- confirmations: 0,
432
- ts: 1578424634
433
- }
434
- ]
435
-
436
- const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
437
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
438
-
439
- assert.isArray(data)
440
- assert.equal(data[0].isValid, false)
441
- assert.equal(data[1].isValid, false)
442
- })
443
-
444
- it('should handle a dust attack', async () => {
445
- // it("#dustattack", async () => {
446
- const utxos = [
447
- {
448
- height: 655965,
449
- tx_hash:
450
- 'a675af87dcd8d39be782737aa52e0076b52eb2f5ce355ffcb5567a64dd96b77e',
451
- tx_pos: 151,
452
- value: 547,
453
- satoshis: 547,
454
- txid:
455
- 'a675af87dcd8d39be782737aa52e0076b52eb2f5ce355ffcb5567a64dd96b77e',
456
- vout: 151,
457
- address: 'bitcoincash:qq4dw3sm8qvglspy6w2qg0u2ugsy9zcfcqrpeflwww',
458
- hdIndex: 11
459
- }
460
- ]
461
-
462
- const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
463
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
464
-
465
- assert.equal(data[0].isValid, false)
466
- })
467
-
468
- it('should handle null SLPDB validations', async () => {
469
- const utxos = [
470
- {
471
- height: 665577,
472
- tx_hash:
473
- '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419',
474
- tx_pos: 1,
475
- value: 546
476
- },
477
- {
478
- height: 665577,
479
- tx_hash:
480
- '3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488',
481
- tx_pos: 1,
482
- value: 546
483
- }
484
- ]
485
-
486
- const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
487
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
488
-
489
- assert.isArray(data)
490
- // assert.equal(data[0].isValid, null)
491
- })
492
- })
493
-
494
- describe('#tokenUtxoDetailsWL', () => {
495
- it('should return details for a simple SEND SLP token utxo', async () => {
496
- const utxos = [
497
- {
498
- height: 660554,
499
- tx_hash:
500
- '89b3f0c84efe8b01b24e2d7ac08636de5781f31dbb84478e3de868ca0a7ed93a',
501
- tx_pos: 1,
502
- value: 546
503
- }
504
- ]
505
-
506
- const data = await bchjs.SLP.Utils.tokenUtxoDetailsWL(utxos)
507
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
508
-
509
- assert.property(data[0], 'txid')
510
- assert.property(data[0], 'vout')
511
- assert.property(data[0], 'height')
512
- assert.property(data[0], 'utxoType')
513
- assert.property(data[0], 'tokenId')
514
- assert.property(data[0], 'tokenTicker')
515
- assert.property(data[0], 'tokenName')
516
- assert.property(data[0], 'tokenDocumentUrl')
517
- assert.property(data[0], 'tokenDocumentHash')
518
- assert.property(data[0], 'decimals')
519
- assert.property(data[0], 'tokenQty')
520
- assert.property(data[0], 'isValid')
521
- assert.equal(data[0].isValid, true)
522
- })
147
+ assert.hasAllKeys(result, [
148
+ 'tokenType',
149
+ 'txType',
150
+ 'tokenId',
151
+ 'amounts'
152
+ ])
153
+ assert.equal(
154
+ result.tokenId,
155
+ '497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7'
156
+ )
523
157
 
524
- it('should return false for BCH-only UTXOs', async () => {
525
- const utxos = [
526
- {
527
- txid:
528
- 'a937f792c7c9eb23b4f344ce5c233d1ac0909217d0a504d71e6b1e4efb864a3b',
529
- vout: 0,
530
- amount: 0.00001,
531
- satoshis: 1000,
532
- confirmations: 0,
533
- ts: 1578424704
534
- },
535
- {
536
- txid:
537
- '53fd141c2e999e080a5860887441a2c45e9cbe262027e2bd2ac998fc76e43c44',
538
- vout: 0,
539
- amount: 0.00001,
540
- satoshis: 1000,
541
- confirmations: 0,
542
- ts: 1578424634
543
- }
544
- ]
158
+ // Verify outputs
159
+ assert.equal(result.amounts.length, 2)
160
+ assert.equal(result.amounts[0], '100000000')
161
+ assert.equal(result.amounts[1], '99883300000000')
162
+ })
545
163
 
546
- const data = await bchjs.SLP.Utils.tokenUtxoDetailsWL(utxos)
547
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
164
+ it('should decode the OP_RETURN for a GENESIS txid', async () => {
165
+ const txid =
166
+ '497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7'
548
167
 
549
- assert.isArray(data)
550
- assert.equal(data[0].isValid, false)
551
- assert.equal(data[1].isValid, false)
552
- })
168
+ const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
169
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
553
170
 
554
- it('should handle a dust attack', async () => {
555
- // it("#dustattack", async () => {
556
- const utxos = [
557
- {
558
- height: 655965,
559
- tx_hash:
560
- 'a675af87dcd8d39be782737aa52e0076b52eb2f5ce355ffcb5567a64dd96b77e',
561
- tx_pos: 151,
562
- value: 547,
563
- satoshis: 547,
564
- txid:
565
- 'a675af87dcd8d39be782737aa52e0076b52eb2f5ce355ffcb5567a64dd96b77e',
566
- vout: 151,
567
- address: 'bitcoincash:qq4dw3sm8qvglspy6w2qg0u2ugsy9zcfcqrpeflwww',
568
- hdIndex: 11
569
- }
570
- ]
171
+ assert.hasAllKeys(result, [
172
+ 'tokenType',
173
+ 'txType',
174
+ 'tokenId',
175
+ 'ticker',
176
+ 'name',
177
+ 'documentUri',
178
+ 'documentHash',
179
+ 'decimals',
180
+ 'mintBatonVout',
181
+ 'qty'
182
+ ])
183
+ assert.equal(
184
+ result.tokenId,
185
+ '497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7'
186
+ )
187
+ assert.equal(result.txType, 'GENESIS')
188
+ assert.equal(result.ticker, 'TOK-CH')
189
+ assert.equal(result.name, 'TokyoCash')
190
+ })
571
191
 
572
- const data = await bchjs.SLP.Utils.tokenUtxoDetailsWL(utxos)
573
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
192
+ it('should decode the OP_RETURN for a MINT txid', async () => {
193
+ const txid =
194
+ '65f21bbfcd545e5eb515e38e861a9dfe2378aaa2c4e458eb9e59e4d40e38f3a4'
574
195
 
575
- assert.equal(data[0].isValid, false)
576
- })
196
+ const result = await bchjs.SLP.Utils.decodeOpReturn(txid)
197
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
577
198
 
578
- it('should handle null SLPDB validations', async () => {
579
- const utxos = [
580
- {
581
- height: 665577,
582
- tx_hash:
583
- '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419',
584
- tx_pos: 1,
585
- value: 546
586
- },
587
- {
588
- height: 665577,
589
- tx_hash:
590
- '3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488',
591
- tx_pos: 1,
592
- value: 546
199
+ assert.hasAllKeys(result, [
200
+ 'tokenType',
201
+ 'txType',
202
+ 'tokenId',
203
+ 'mintBatonVout',
204
+ 'qty'
205
+ ])
206
+ })
207
+
208
+ it('should throw an error for a non-SLP transaction', async () => {
209
+ try {
210
+ const txid =
211
+ '3793d4906654f648e659f384c0f40b19c8f10c1e9fb72232a9b8edd61abaa1ec'
212
+
213
+ await bchjs.SLP.Utils.decodeOpReturn(txid)
214
+
215
+ assert.equal(true, false, 'Unexpected result')
216
+ } catch (err) {
217
+ // console.log(`err: `, err)
218
+ assert.include(err.message, 'scriptpubkey not op_return')
593
219
  }
594
- ]
595
-
596
- const data = await bchjs.SLP.Utils.tokenUtxoDetailsWL(utxos)
597
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
598
-
599
- assert.isArray(data)
600
- // assert.equal(data[0].isValid, null)
601
- })
602
- })
603
-
604
- describe('#balancesForAddress', () => {
605
- it('should fetch all balances for address: simpleledger:qzv3zz2trz0xgp6a96lu4m6vp2nkwag0kvyucjzqt9', async () => {
606
- const balances = await bchjs.SLP.Utils.balancesForAddress(
607
- 'simpleledger:qzv3zz2trz0xgp6a96lu4m6vp2nkwag0kvyucjzqt9'
608
- )
609
- // console.log(`balances: ${JSON.stringify(balances, null, 2)}`)
610
-
611
- assert.isArray(balances)
612
- assert.hasAllKeys(balances[0], [
613
- 'tokenId',
614
- 'balanceString',
615
- 'balance',
616
- 'decimalCount',
617
- 'slpAddress'
618
- ])
619
- })
620
-
621
- it('should fetch balances for multiple addresses', async () => {
622
- const addresses = [
623
- 'simpleledger:qzv3zz2trz0xgp6a96lu4m6vp2nkwag0kvyucjzqt9',
624
- 'simpleledger:qqss4zp80hn6szsa4jg2s9fupe7g5tcg5ucdyl3r57'
625
- ]
626
-
627
- const balances = await bchjs.SLP.Utils.balancesForAddress(addresses)
628
- // console.log(`balances: ${JSON.stringify(balances, null, 2)}`)
629
-
630
- assert.isArray(balances)
631
- assert.isArray(balances[0])
632
- assert.hasAllKeys(balances[0][0], [
633
- 'tokenId',
634
- 'balanceString',
635
- 'balance',
636
- 'decimalCount',
637
- 'slpAddress'
638
- ])
639
- })
640
- })
641
-
642
- describe('#hydrateUtxos-', () => {
643
- it('should hydrate UTXOs', async () => {
644
- const utxos = [
645
- {
646
- utxos: [
647
- {
648
- txid:
649
- 'd56a2b446d8149c39ca7e06163fe8097168c3604915f631bc58777d669135a56',
650
- vout: 3,
651
- value: '6816',
652
- height: 606848,
653
- confirmations: 13,
654
- satoshis: 6816
655
- },
656
- {
657
- txid:
658
- 'd56a2b446d8149c39ca7e06163fe8097168c3604915f631bc58777d669135a56',
659
- vout: 2,
660
- value: '546',
661
- height: 606848,
662
- confirmations: 13,
663
- satoshis: 546
664
- }
665
- ]
220
+ })
221
+
222
+ // Note: This TX is interpreted as valid by the original decodeOpReturn().
223
+ // Fixing this issue and related issues was the reason for creating the
224
+ // decodeOpReturn2() method using the slp-parser library.
225
+ it('should throw error for invalid SLP transaction', async () => {
226
+ try {
227
+ const txid =
228
+ 'a60a522cc11ad7011b74e57fbabbd99296e4b9346bcb175dcf84efb737030415'
229
+
230
+ await bchjs.SLP.Utils.decodeOpReturn(txid)
231
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
232
+ } catch (err) {
233
+ // console.log(`err: `, err)
234
+ assert.include(err.message, 'amount string size not 8 bytes')
666
235
  }
667
- ]
668
-
669
- const result = await bchjs.SLP.Utils.hydrateUtxos(utxos)
670
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
671
-
672
- // Test the general structure of the output.
673
- assert.isArray(result.slpUtxos)
674
- assert.equal(result.slpUtxos.length, 1)
675
- assert.equal(result.slpUtxos[0].utxos.length, 2)
676
-
677
- // Test the non-slp UTXO.
678
- assert.property(result.slpUtxos[0].utxos[0], 'txid')
679
- assert.property(result.slpUtxos[0].utxos[0], 'vout')
680
- assert.property(result.slpUtxos[0].utxos[0], 'value')
681
- assert.property(result.slpUtxos[0].utxos[0], 'height')
682
- assert.property(result.slpUtxos[0].utxos[0], 'confirmations')
683
- assert.property(result.slpUtxos[0].utxos[0], 'satoshis')
684
- assert.property(result.slpUtxos[0].utxos[0], 'isValid')
685
- assert.equal(result.slpUtxos[0].utxos[0].isValid, false)
686
-
687
- // Test the slp UTXO.
688
- assert.property(result.slpUtxos[0].utxos[1], 'txid')
689
- assert.property(result.slpUtxos[0].utxos[1], 'vout')
690
- assert.property(result.slpUtxos[0].utxos[1], 'value')
691
- assert.property(result.slpUtxos[0].utxos[1], 'height')
692
- assert.property(result.slpUtxos[0].utxos[1], 'confirmations')
693
- assert.property(result.slpUtxos[0].utxos[1], 'satoshis')
694
- assert.property(result.slpUtxos[0].utxos[1], 'isValid')
695
- assert.equal(result.slpUtxos[0].utxos[1].isValid, true)
696
- assert.property(result.slpUtxos[0].utxos[1], 'transactionType')
697
- assert.property(result.slpUtxos[0].utxos[1], 'tokenId')
698
- assert.property(result.slpUtxos[0].utxos[1], 'tokenTicker')
699
- assert.property(result.slpUtxos[0].utxos[1], 'tokenName')
700
- assert.property(result.slpUtxos[0].utxos[1], 'tokenDocumentUrl')
701
- assert.property(result.slpUtxos[0].utxos[1], 'tokenDocumentHash')
702
- assert.property(result.slpUtxos[0].utxos[1], 'decimals')
703
- assert.property(result.slpUtxos[0].utxos[1], 'tokenType')
704
- assert.property(result.slpUtxos[0].utxos[1], 'tokenQty')
705
- })
706
-
707
- it('should process data directly from Electrumx', async () => {
708
- const addrs = [
709
- 'bitcoincash:qqnt53cfw990u6y38xgezm0lfa8hknw0wueezcpagp',
710
- 'bitcoincash:qrh3qgtax6adegzc7zxm6m4sgrv9wq28yqnfn33ce5',
711
- 'bitcoincash:qqcaee5w4ws77n8s2gzy6fwtma6uxd7ctq8553e495'
712
- ]
713
-
714
- const utxos = await bchjs.Electrumx.utxo(addrs)
715
- // console.log(`utxos: ${JSON.stringify(utxos, null, 2)}`)
716
-
717
- const result = await bchjs.SLP.Utils.hydrateUtxos(utxos.utxos)
718
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
236
+ })
237
+ })
238
+
239
+ describe('#tokenUtxoDetails', () => {
240
+ // // This captures an important corner-case. When an SLP token is created, the
241
+ // // change UTXO will contain the same SLP txid, but it is not an SLP UTXO.
242
+ it('should return details on minting baton from genesis transaction', async () => {
243
+ const utxos = [
244
+ {
245
+ txid:
246
+ 'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
247
+ vout: 3,
248
+ amount: 0.00002015,
249
+ satoshis: 2015,
250
+ height: 594892,
251
+ confirmations: 5
252
+ },
253
+ {
254
+ txid:
255
+ 'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
256
+ vout: 2,
257
+ amount: 0.00000546,
258
+ satoshis: 546,
259
+ height: 594892,
260
+ confirmations: 5
261
+ }
262
+ ]
263
+
264
+ const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
265
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
266
+
267
+ assert.equal(data[0].isValid, false, 'Change UTXO marked as false.')
268
+
269
+ assert.property(data[1], 'txid')
270
+ assert.property(data[1], 'vout')
271
+ assert.property(data[1], 'amount')
272
+ assert.property(data[1], 'satoshis')
273
+ assert.property(data[1], 'height')
274
+ assert.property(data[1], 'confirmations')
275
+ assert.property(data[1], 'utxoType')
276
+ assert.property(data[1], 'tokenId')
277
+ assert.property(data[1], 'tokenTicker')
278
+ assert.property(data[1], 'tokenName')
279
+ assert.property(data[1], 'tokenDocumentUrl')
280
+ assert.property(data[1], 'tokenDocumentHash')
281
+ assert.property(data[1], 'decimals')
282
+ assert.property(data[1], 'isValid')
283
+ assert.equal(data[1].isValid, true)
284
+ })
285
+
286
+ it('should return details for a MINT token utxo', async () => {
287
+ // Mock the call to REST API
288
+
289
+ const utxos = [
290
+ {
291
+ txid:
292
+ 'cf4b922d1e1aa56b52d752d4206e1448ea76c3ebe69b3b97d8f8f65413bd5c76',
293
+ vout: 1,
294
+ amount: 0.00000546,
295
+ satoshis: 546,
296
+ height: 600297,
297
+ confirmations: 76
298
+ }
299
+ ]
300
+
301
+ const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
302
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
303
+
304
+ assert.property(data[0], 'txid')
305
+ assert.property(data[0], 'vout')
306
+ assert.property(data[0], 'amount')
307
+ assert.property(data[0], 'satoshis')
308
+ assert.property(data[0], 'height')
309
+ assert.property(data[0], 'confirmations')
310
+ assert.property(data[0], 'utxoType')
311
+ assert.property(data[0], 'transactionType')
312
+ assert.property(data[0], 'tokenId')
313
+ assert.property(data[0], 'tokenTicker')
314
+ assert.property(data[0], 'tokenName')
315
+ assert.property(data[0], 'tokenDocumentUrl')
316
+ assert.property(data[0], 'tokenDocumentHash')
317
+ assert.property(data[0], 'decimals')
318
+ assert.property(data[0], 'mintBatonVout')
319
+ assert.property(data[0], 'tokenQty')
320
+ assert.property(data[0], 'isValid')
321
+ assert.equal(data[0].isValid, true)
322
+ })
323
+
324
+ it('should return details for a simple SEND SLP token utxo', async () => {
325
+ const utxos = [
326
+ {
327
+ txid:
328
+ 'fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb',
329
+ vout: 1,
330
+ amount: 0.00000546,
331
+ satoshis: 546,
332
+ height: 596089,
333
+ confirmations: 748
334
+ }
335
+ ]
336
+
337
+ const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
338
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
339
+
340
+ assert.property(data[0], 'txid')
341
+ assert.property(data[0], 'vout')
342
+ assert.property(data[0], 'amount')
343
+ assert.property(data[0], 'satoshis')
344
+ assert.property(data[0], 'height')
345
+ assert.property(data[0], 'confirmations')
346
+ assert.property(data[0], 'utxoType')
347
+ assert.property(data[0], 'tokenId')
348
+ assert.property(data[0], 'tokenTicker')
349
+ assert.property(data[0], 'tokenName')
350
+ assert.property(data[0], 'tokenDocumentUrl')
351
+ assert.property(data[0], 'tokenDocumentHash')
352
+ assert.property(data[0], 'decimals')
353
+ assert.property(data[0], 'tokenQty')
354
+ assert.property(data[0], 'isValid')
355
+ assert.equal(data[0].isValid, true)
356
+ })
357
+
358
+ it('should handle BCH and SLP utxos in the same TX', async () => {
359
+ const utxos = [
360
+ {
361
+ txid:
362
+ 'd56a2b446d8149c39ca7e06163fe8097168c3604915f631bc58777d669135a56',
363
+ vout: 3,
364
+ value: '6816',
365
+ height: 606848,
366
+ confirmations: 13,
367
+ satoshis: 6816
368
+ },
369
+ {
370
+ txid:
371
+ 'd56a2b446d8149c39ca7e06163fe8097168c3604915f631bc58777d669135a56',
372
+ vout: 2,
373
+ value: '546',
374
+ height: 606848,
375
+ confirmations: 13,
376
+ satoshis: 546
377
+ }
378
+ ]
379
+
380
+ const result = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
381
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
719
382
 
720
- // Test the general structure of the output.
721
- assert.isArray(result.slpUtxos)
722
- assert.equal(result.slpUtxos.length, 3)
723
- assert.equal(result.slpUtxos[0].utxos.length, 1)
724
- assert.equal(result.slpUtxos[1].utxos.length, 1)
725
- assert.equal(result.slpUtxos[2].utxos.length, 2)
383
+ assert.isArray(result)
384
+ assert.equal(result.length, 2)
385
+ assert.equal(result[0].isValid, false)
386
+ assert.equal(result[1].isValid, true)
387
+ })
388
+
389
+ it('should handle problematic utxos', async () => {
390
+ const utxos = [
391
+ {
392
+ txid:
393
+ '0e3a217fc22612002031d317b4cecd9b692b66b52951a67b23c43041aefa3959',
394
+ vout: 0,
395
+ amount: 0.00018362,
396
+ satoshis: 18362,
397
+ height: 613483,
398
+ confirmations: 124
399
+ },
400
+ {
401
+ txid:
402
+ '67fd3c7c3a6eb0fea9ab311b91039545086220f7eeeefa367fa28e6e43009f19',
403
+ vout: 1,
404
+ amount: 0.00000546,
405
+ satoshis: 546,
406
+ height: 612075,
407
+ confirmations: 1532
408
+ }
409
+ ]
410
+
411
+ const result = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
412
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
726
413
 
727
- try {
728
- // Test the expected values.
729
- assert.equal(result.slpUtxos[0].utxos[0].isValid, false)
730
- assert.equal(result.slpUtxos[1].utxos[0].isValid, true)
731
- assert.equal(result.slpUtxos[1].utxos[0].tokenTicker, 'TROUT')
732
- assert.equal(result.slpUtxos[2].utxos[0].isValid, false)
733
- assert.equal(result.slpUtxos[2].utxos[1].isValid, true)
734
- assert.equal(result.slpUtxos[2].utxos[1].tokenTicker, 'VALENTINE')
735
- } catch (err) {
736
- console.error(
737
- 'The hydrateUtxos call may hitting rate limits, or SLPDB may be having issues if "isValid" results are "null"'
414
+ assert.isArray(result)
415
+ assert.equal(result.length, 2)
416
+ assert.equal(result[0].isValid, false)
417
+ assert.equal(result[1].isValid, true)
418
+ })
419
+
420
+ it('should return false for BCH-only UTXOs', async () => {
421
+ const utxos = [
422
+ {
423
+ txid:
424
+ 'a937f792c7c9eb23b4f344ce5c233d1ac0909217d0a504d71e6b1e4efb864a3b',
425
+ vout: 0,
426
+ amount: 0.00001,
427
+ satoshis: 1000,
428
+ confirmations: 0,
429
+ ts: 1578424704
430
+ },
431
+ {
432
+ txid:
433
+ '53fd141c2e999e080a5860887441a2c45e9cbe262027e2bd2ac998fc76e43c44',
434
+ vout: 0,
435
+ amount: 0.00001,
436
+ satoshis: 1000,
437
+ confirmations: 0,
438
+ ts: 1578424634
439
+ }
440
+ ]
441
+
442
+ const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
443
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
444
+
445
+ assert.isArray(data)
446
+ assert.equal(data[0].isValid, false)
447
+ assert.equal(data[1].isValid, false)
448
+ })
449
+
450
+ it('should handle a dust attack', async () => {
451
+ // it("#dustattack", async () => {
452
+ const utxos = [
453
+ {
454
+ height: 655965,
455
+ tx_hash:
456
+ 'a675af87dcd8d39be782737aa52e0076b52eb2f5ce355ffcb5567a64dd96b77e',
457
+ tx_pos: 151,
458
+ value: 547,
459
+ satoshis: 547,
460
+ txid:
461
+ 'a675af87dcd8d39be782737aa52e0076b52eb2f5ce355ffcb5567a64dd96b77e',
462
+ vout: 151,
463
+ address: 'bitcoincash:qq4dw3sm8qvglspy6w2qg0u2ugsy9zcfcqrpeflwww',
464
+ hdIndex: 11
465
+ }
466
+ ]
467
+
468
+ const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
469
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
470
+
471
+ assert.equal(data[0].isValid, false)
472
+ })
473
+
474
+ it('should handle null SLPDB validations', async () => {
475
+ const utxos = [
476
+ {
477
+ height: 665577,
478
+ tx_hash:
479
+ '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419',
480
+ tx_pos: 1,
481
+ value: 546
482
+ },
483
+ {
484
+ height: 665577,
485
+ tx_hash:
486
+ '3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488',
487
+ tx_pos: 1,
488
+ value: 546
489
+ }
490
+ ]
491
+
492
+ const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
493
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
494
+
495
+ assert.isArray(data)
496
+ // assert.equal(data[0].isValid, null)
497
+ })
498
+ })
499
+
500
+ describe('#tokenUtxoDetailsWL', () => {
501
+ it('should return details for a simple SEND SLP token utxo', async () => {
502
+ const utxos = [
503
+ {
504
+ height: 660554,
505
+ tx_hash:
506
+ '89b3f0c84efe8b01b24e2d7ac08636de5781f31dbb84478e3de868ca0a7ed93a',
507
+ tx_pos: 1,
508
+ value: 546
509
+ }
510
+ ]
511
+
512
+ const data = await bchjs.SLP.Utils.tokenUtxoDetailsWL(utxos)
513
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
514
+
515
+ assert.property(data[0], 'txid')
516
+ assert.property(data[0], 'vout')
517
+ assert.property(data[0], 'height')
518
+ assert.property(data[0], 'utxoType')
519
+ assert.property(data[0], 'tokenId')
520
+ assert.property(data[0], 'tokenTicker')
521
+ assert.property(data[0], 'tokenName')
522
+ assert.property(data[0], 'tokenDocumentUrl')
523
+ assert.property(data[0], 'tokenDocumentHash')
524
+ assert.property(data[0], 'decimals')
525
+ assert.property(data[0], 'tokenQty')
526
+ assert.property(data[0], 'isValid')
527
+ assert.equal(data[0].isValid, true)
528
+ })
529
+
530
+ it('should return false for BCH-only UTXOs', async () => {
531
+ const utxos = [
532
+ {
533
+ txid:
534
+ 'a937f792c7c9eb23b4f344ce5c233d1ac0909217d0a504d71e6b1e4efb864a3b',
535
+ vout: 0,
536
+ amount: 0.00001,
537
+ satoshis: 1000,
538
+ confirmations: 0,
539
+ ts: 1578424704
540
+ },
541
+ {
542
+ txid:
543
+ '53fd141c2e999e080a5860887441a2c45e9cbe262027e2bd2ac998fc76e43c44',
544
+ vout: 0,
545
+ amount: 0.00001,
546
+ satoshis: 1000,
547
+ confirmations: 0,
548
+ ts: 1578424634
549
+ }
550
+ ]
551
+
552
+ const data = await bchjs.SLP.Utils.tokenUtxoDetailsWL(utxos)
553
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
554
+
555
+ assert.isArray(data)
556
+ assert.equal(data[0].isValid, false)
557
+ assert.equal(data[1].isValid, false)
558
+ })
559
+
560
+ it('should handle a dust attack', async () => {
561
+ // it("#dustattack", async () => {
562
+ const utxos = [
563
+ {
564
+ height: 655965,
565
+ tx_hash:
566
+ 'a675af87dcd8d39be782737aa52e0076b52eb2f5ce355ffcb5567a64dd96b77e',
567
+ tx_pos: 151,
568
+ value: 547,
569
+ satoshis: 547,
570
+ txid:
571
+ 'a675af87dcd8d39be782737aa52e0076b52eb2f5ce355ffcb5567a64dd96b77e',
572
+ vout: 151,
573
+ address: 'bitcoincash:qq4dw3sm8qvglspy6w2qg0u2ugsy9zcfcqrpeflwww',
574
+ hdIndex: 11
575
+ }
576
+ ]
577
+
578
+ const data = await bchjs.SLP.Utils.tokenUtxoDetailsWL(utxos)
579
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
580
+
581
+ assert.equal(data[0].isValid, false)
582
+ })
583
+
584
+ it('should handle null SLPDB validations', async () => {
585
+ const utxos = [
586
+ {
587
+ height: 665577,
588
+ tx_hash:
589
+ '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419',
590
+ tx_pos: 1,
591
+ value: 546
592
+ },
593
+ {
594
+ height: 665577,
595
+ tx_hash:
596
+ '3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488',
597
+ tx_pos: 1,
598
+ value: 546
599
+ }
600
+ ]
601
+
602
+ const data = await bchjs.SLP.Utils.tokenUtxoDetailsWL(utxos)
603
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
604
+
605
+ assert.isArray(data)
606
+ // assert.equal(data[0].isValid, null)
607
+ })
608
+ })
609
+
610
+ describe('#balancesForAddress', () => {
611
+ it('should fetch all balances for address: simpleledger:qzv3zz2trz0xgp6a96lu4m6vp2nkwag0kvyucjzqt9', async () => {
612
+ const balances = await bchjs.SLP.Utils.balancesForAddress(
613
+ 'simpleledger:qzv3zz2trz0xgp6a96lu4m6vp2nkwag0kvyucjzqt9'
738
614
  )
739
- console.log('Error: ', err)
740
- }
741
- })
742
-
743
- it('should handle null SLPDB validations', async () => {
744
- const utxos = [
745
- {
746
- height: 665577,
747
- tx_hash:
748
- '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419',
749
- tx_pos: 1,
750
- value: 546
751
- },
752
- {
753
- height: 665577,
754
- tx_hash:
755
- 'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a',
756
- tx_pos: 1,
757
- value: 546
758
- }
759
- ]
615
+ // console.log(`balances: ${JSON.stringify(balances, null, 2)}`)
616
+
617
+ assert.isArray(balances)
618
+ assert.hasAllKeys(balances[0], [
619
+ 'tokenId',
620
+ 'balanceString',
621
+ 'balance',
622
+ 'decimalCount',
623
+ 'slpAddress'
624
+ ])
625
+ })
626
+
627
+ it('should fetch balances for multiple addresses', async () => {
628
+ const addresses = [
629
+ 'simpleledger:qzv3zz2trz0xgp6a96lu4m6vp2nkwag0kvyucjzqt9',
630
+ 'simpleledger:qqss4zp80hn6szsa4jg2s9fupe7g5tcg5ucdyl3r57'
631
+ ]
632
+
633
+ const balances = await bchjs.SLP.Utils.balancesForAddress(addresses)
634
+ // console.log(`balances: ${JSON.stringify(balances, null, 2)}`)
635
+
636
+ assert.isArray(balances)
637
+ assert.isArray(balances[0])
638
+ assert.hasAllKeys(balances[0][0], [
639
+ 'tokenId',
640
+ 'balanceString',
641
+ 'balance',
642
+ 'decimalCount',
643
+ 'slpAddress'
644
+ ])
645
+ })
646
+ })
647
+
648
+ describe('#hydrateUtxos-', () => {
649
+ it('should hydrate UTXOs', async () => {
650
+ const utxos = [
651
+ {
652
+ utxos: [
653
+ {
654
+ txid:
655
+ 'd56a2b446d8149c39ca7e06163fe8097168c3604915f631bc58777d669135a56',
656
+ vout: 3,
657
+ value: '6816',
658
+ height: 606848,
659
+ confirmations: 13,
660
+ satoshis: 6816
661
+ },
662
+ {
663
+ txid:
664
+ 'd56a2b446d8149c39ca7e06163fe8097168c3604915f631bc58777d669135a56',
665
+ vout: 2,
666
+ value: '546',
667
+ height: 606848,
668
+ confirmations: 13,
669
+ satoshis: 546
670
+ }
671
+ ]
672
+ }
673
+ ]
674
+
675
+ const result = await bchjs.SLP.Utils.hydrateUtxos(utxos)
676
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
760
677
 
761
- const data = await bchjs.SLP.Utils.hydrateUtxos([{ utxos: utxos }])
762
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
678
+ // Test the general structure of the output.
679
+ assert.isArray(result.slpUtxos)
680
+ assert.equal(result.slpUtxos.length, 1)
681
+ assert.equal(result.slpUtxos[0].utxos.length, 2)
682
+
683
+ // Test the non-slp UTXO.
684
+ assert.property(result.slpUtxos[0].utxos[0], 'txid')
685
+ assert.property(result.slpUtxos[0].utxos[0], 'vout')
686
+ assert.property(result.slpUtxos[0].utxos[0], 'value')
687
+ assert.property(result.slpUtxos[0].utxos[0], 'height')
688
+ assert.property(result.slpUtxos[0].utxos[0], 'confirmations')
689
+ assert.property(result.slpUtxos[0].utxos[0], 'satoshis')
690
+ assert.property(result.slpUtxos[0].utxos[0], 'isValid')
691
+ assert.equal(result.slpUtxos[0].utxos[0].isValid, false)
763
692
 
764
- assert.isArray(data.slpUtxos)
765
- assert.equal(data.slpUtxos[0].isValid, null)
766
- })
767
- })
693
+ // Test the slp UTXO.
694
+ assert.property(result.slpUtxos[0].utxos[1], 'txid')
695
+ assert.property(result.slpUtxos[0].utxos[1], 'vout')
696
+ assert.property(result.slpUtxos[0].utxos[1], 'value')
697
+ assert.property(result.slpUtxos[0].utxos[1], 'height')
698
+ assert.property(result.slpUtxos[0].utxos[1], 'confirmations')
699
+ assert.property(result.slpUtxos[0].utxos[1], 'satoshis')
700
+ assert.property(result.slpUtxos[0].utxos[1], 'isValid')
701
+ assert.equal(result.slpUtxos[0].utxos[1].isValid, true)
702
+ assert.property(result.slpUtxos[0].utxos[1], 'transactionType')
703
+ assert.property(result.slpUtxos[0].utxos[1], 'tokenId')
704
+ assert.property(result.slpUtxos[0].utxos[1], 'tokenTicker')
705
+ assert.property(result.slpUtxos[0].utxos[1], 'tokenName')
706
+ assert.property(result.slpUtxos[0].utxos[1], 'tokenDocumentUrl')
707
+ assert.property(result.slpUtxos[0].utxos[1], 'tokenDocumentHash')
708
+ assert.property(result.slpUtxos[0].utxos[1], 'decimals')
709
+ assert.property(result.slpUtxos[0].utxos[1], 'tokenType')
710
+ assert.property(result.slpUtxos[0].utxos[1], 'tokenQty')
711
+ })
712
+
713
+ it('should process data directly from Electrumx', async () => {
714
+ const addrs = [
715
+ 'bitcoincash:qqnt53cfw990u6y38xgezm0lfa8hknw0wueezcpagp',
716
+ 'bitcoincash:qrh3qgtax6adegzc7zxm6m4sgrv9wq28yqnfn33ce5',
717
+ 'bitcoincash:qqcaee5w4ws77n8s2gzy6fwtma6uxd7ctq8553e495'
718
+ ]
719
+
720
+ const utxos = await bchjs.Electrumx.utxo(addrs)
721
+ // console.log(`utxos: ${JSON.stringify(utxos, null, 2)}`)
722
+
723
+ const result = await bchjs.SLP.Utils.hydrateUtxos(utxos.utxos)
724
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
768
725
 
769
- describe('#hydrateUtxosWL', () => {
770
- it('should hydrate UTXOs', async () => {
771
- const utxos = [
772
- {
773
- utxos: [
774
- {
775
- txid:
776
- '89b3f0c84efe8b01b24e2d7ac08636de5781f31dbb84478e3de868ca0a7ed93a',
777
- vout: 1,
778
- value: 546
779
- }
780
- ]
726
+ // Test the general structure of the output.
727
+ assert.isArray(result.slpUtxos)
728
+ assert.equal(result.slpUtxos.length, 3)
729
+ assert.equal(result.slpUtxos[0].utxos.length, 1)
730
+ assert.equal(result.slpUtxos[1].utxos.length, 1)
731
+ assert.equal(result.slpUtxos[2].utxos.length, 2)
732
+
733
+ try {
734
+ // Test the expected values.
735
+ assert.equal(result.slpUtxos[0].utxos[0].isValid, false)
736
+ assert.equal(result.slpUtxos[1].utxos[0].isValid, true)
737
+ assert.equal(result.slpUtxos[1].utxos[0].tokenTicker, 'TROUT')
738
+ assert.equal(result.slpUtxos[2].utxos[0].isValid, false)
739
+ assert.equal(result.slpUtxos[2].utxos[1].isValid, true)
740
+ assert.equal(result.slpUtxos[2].utxos[1].tokenTicker, 'VALENTINE')
741
+ } catch (err) {
742
+ console.error(
743
+ 'The hydrateUtxos call may hitting rate limits, or SLPDB may be having issues if "isValid" results are "null"'
744
+ )
745
+ console.log('Error: ', err)
781
746
  }
782
- ]
783
-
784
- const result = await bchjs.SLP.Utils.hydrateUtxosWL(utxos)
785
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
786
-
787
- // Test the general structure of the output.
788
- assert.isArray(result.slpUtxos)
789
- assert.equal(result.slpUtxos.length, 1)
790
- assert.equal(result.slpUtxos[0].utxos.length, 1)
791
-
792
- // Test the non-slp UTXO.
793
- assert.property(result.slpUtxos[0].utxos[0], 'txid')
794
- assert.property(result.slpUtxos[0].utxos[0], 'vout')
795
- assert.property(result.slpUtxos[0].utxos[0], 'value')
796
- assert.property(result.slpUtxos[0].utxos[0], 'isValid')
797
- assert.equal(result.slpUtxos[0].utxos[0].isValid, true)
798
- })
799
-
800
- it('should process data directly from Electrumx', async () => {
801
- const addrs = [
802
- 'bitcoincash:qqnt53cfw990u6y38xgezm0lfa8hknw0wueezcpagp',
803
- 'bitcoincash:qrh3qgtax6adegzc7zxm6m4sgrv9wq28yqnfn33ce5',
804
- 'bitcoincash:qqcaee5w4ws77n8s2gzy6fwtma6uxd7ctq8553e495'
805
- ]
806
-
807
- const utxos = await bchjs.Electrumx.utxo(addrs)
808
- // console.log(`utxos: ${JSON.stringify(utxos, null, 2)}`)
809
-
810
- const result = await bchjs.SLP.Utils.hydrateUtxosWL(utxos.utxos)
811
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
812
-
813
- // Test the general structure of the output.
814
- assert.isArray(result.slpUtxos)
815
- assert.equal(result.slpUtxos.length, 3)
816
- assert.equal(result.slpUtxos[0].utxos.length, 1)
817
- assert.equal(result.slpUtxos[1].utxos.length, 1)
818
- assert.equal(result.slpUtxos[2].utxos.length, 2)
747
+ })
748
+
749
+ it('should handle null SLPDB validations', async () => {
750
+ const utxos = [
751
+ {
752
+ height: 665577,
753
+ tx_hash:
754
+ '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419',
755
+ tx_pos: 1,
756
+ value: 546
757
+ },
758
+ {
759
+ height: 665577,
760
+ tx_hash:
761
+ 'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a',
762
+ tx_pos: 1,
763
+ value: 546
764
+ }
765
+ ]
766
+
767
+ const data = await bchjs.SLP.Utils.hydrateUtxos([{ utxos: utxos }])
768
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
769
+
770
+ assert.isArray(data.slpUtxos)
771
+ assert.equal(data.slpUtxos[0].isValid, null)
772
+ })
773
+ })
774
+
775
+ describe('#hydrateUtxosWL', () => {
776
+ it('should hydrate UTXOs', async () => {
777
+ const utxos = [
778
+ {
779
+ utxos: [
780
+ {
781
+ txid:
782
+ '89b3f0c84efe8b01b24e2d7ac08636de5781f31dbb84478e3de868ca0a7ed93a',
783
+ vout: 1,
784
+ value: 546
785
+ }
786
+ ]
787
+ }
788
+ ]
789
+
790
+ const result = await bchjs.SLP.Utils.hydrateUtxosWL(utxos)
791
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
819
792
 
820
- try {
821
- // Test the expected values.
822
- assert.equal(result.slpUtxos[0].utxos[0].isValid, false)
823
- assert.equal(result.slpUtxos[1].utxos[0].isValid, true)
824
- assert.equal(result.slpUtxos[1].utxos[0].tokenTicker, 'TROUT')
825
- assert.equal(result.slpUtxos[2].utxos[0].isValid, false)
826
- // assert.equal(result.slpUtxos[2].utxos[1].isValid, null)
827
- assert.equal(result.slpUtxos[2].utxos[1].tokenTicker, 'VALENTINE')
828
- } catch (err) {
829
- console.error(
830
- 'The hydrateUtxos call may hitting rate limits, or SLPDB may be having issues if "isValid" results are "null"'
831
- )
832
- console.log('Error: ', err)
833
- }
834
- })
793
+ // Test the general structure of the output.
794
+ assert.isArray(result.slpUtxos)
795
+ assert.equal(result.slpUtxos.length, 1)
796
+ assert.equal(result.slpUtxos[0].utxos.length, 1)
797
+
798
+ // Test the non-slp UTXO.
799
+ assert.property(result.slpUtxos[0].utxos[0], 'txid')
800
+ assert.property(result.slpUtxos[0].utxos[0], 'vout')
801
+ assert.property(result.slpUtxos[0].utxos[0], 'value')
802
+ assert.property(result.slpUtxos[0].utxos[0], 'isValid')
803
+ assert.equal(result.slpUtxos[0].utxos[0].isValid, true)
804
+ })
805
+
806
+ it('should process data directly from Electrumx', async () => {
807
+ const addrs = [
808
+ 'bitcoincash:qqnt53cfw990u6y38xgezm0lfa8hknw0wueezcpagp',
809
+ 'bitcoincash:qrh3qgtax6adegzc7zxm6m4sgrv9wq28yqnfn33ce5',
810
+ 'bitcoincash:qqcaee5w4ws77n8s2gzy6fwtma6uxd7ctq8553e495'
811
+ ]
812
+
813
+ const utxos = await bchjs.Electrumx.utxo(addrs)
814
+ // console.log(`utxos: ${JSON.stringify(utxos, null, 2)}`)
815
+
816
+ const result = await bchjs.SLP.Utils.hydrateUtxosWL(utxos.utxos)
817
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
835
818
 
836
- it('should handle null SLPDB validations', async () => {
837
- const utxos = [
838
- {
839
- height: 665577,
840
- tx_hash:
841
- '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419',
842
- tx_pos: 1,
843
- value: 546
844
- },
845
- {
846
- height: 665577,
847
- tx_hash:
848
- 'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a',
849
- tx_pos: 1,
850
- value: 546
819
+ // Test the general structure of the output.
820
+ assert.isArray(result.slpUtxos)
821
+ assert.equal(result.slpUtxos.length, 3)
822
+ assert.equal(result.slpUtxos[0].utxos.length, 1)
823
+ assert.equal(result.slpUtxos[1].utxos.length, 1)
824
+ assert.equal(result.slpUtxos[2].utxos.length, 2)
825
+
826
+ try {
827
+ // Test the expected values.
828
+ assert.equal(result.slpUtxos[0].utxos[0].isValid, false)
829
+ assert.equal(result.slpUtxos[1].utxos[0].isValid, true)
830
+ assert.equal(result.slpUtxos[1].utxos[0].tokenTicker, 'TROUT')
831
+ assert.equal(result.slpUtxos[2].utxos[0].isValid, false)
832
+ // assert.equal(result.slpUtxos[2].utxos[1].isValid, null)
833
+ assert.equal(result.slpUtxos[2].utxos[1].tokenTicker, 'VALENTINE')
834
+ } catch (err) {
835
+ console.error(
836
+ 'The hydrateUtxos call may hitting rate limits, or SLPDB may be having issues if "isValid" results are "null"'
837
+ )
838
+ console.log('Error: ', err)
851
839
  }
852
- ]
853
-
854
- const data = await bchjs.SLP.Utils.hydrateUtxosWL([{ utxos: utxos }])
855
- // console.log(`data: ${JSON.stringify(data, null, 2)}`)
856
-
857
- assert.isArray(data.slpUtxos)
858
- assert.equal(data.slpUtxos[0].isValid, null)
859
- })
860
- })
861
-
862
- describe('#validateTxid', () => {
863
- // This test is not necessary.
864
- it('should handle a null response from SLPDB', async () => {
865
- const txid =
866
- '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419'
840
+ })
841
+
842
+ it('should handle null SLPDB validations', async () => {
843
+ const utxos = [
844
+ {
845
+ height: 665577,
846
+ tx_hash:
847
+ '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419',
848
+ tx_pos: 1,
849
+ value: 546
850
+ },
851
+ {
852
+ height: 665577,
853
+ tx_hash:
854
+ 'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a',
855
+ tx_pos: 1,
856
+ value: 546
857
+ }
858
+ ]
859
+
860
+ const data = await bchjs.SLP.Utils.hydrateUtxosWL([{ utxos: utxos }])
861
+ // console.log(`data: ${JSON.stringify(data, null, 2)}`)
862
+
863
+ assert.isArray(data.slpUtxos)
864
+ assert.equal(data.slpUtxos[0].isValid, null)
865
+ })
866
+ })
867
+
868
+ describe('#validateTxid', () => {
869
+ // This test is not necessary.
870
+ it('should handle a null response from SLPDB', async () => {
871
+ const txid =
872
+ '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419'
867
873
 
868
- const result = await bchjs.SLP.Utils.validateTxid(txid)
869
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
874
+ const result = await bchjs.SLP.Utils.validateTxid(txid)
875
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
870
876
 
871
- assert.isArray(result)
872
- assert.equal(result[0].txid, txid)
873
- // assert.equal(result[0].valid, null)
874
- })
877
+ assert.isArray(result)
878
+ assert.equal(result[0].txid, txid)
879
+ // assert.equal(result[0].valid, null)
880
+ })
875
881
 
876
- it('should handle a null response from SLPDB', async () => {
877
- const txid = [
878
- '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419',
879
- '3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488'
880
- ]
882
+ it('should handle a null response from SLPDB', async () => {
883
+ const txid = [
884
+ '4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419',
885
+ '3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488'
886
+ ]
881
887
 
882
- const result = await bchjs.SLP.Utils.validateTxid(txid)
883
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
888
+ const result = await bchjs.SLP.Utils.validateTxid(txid)
889
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
884
890
 
885
- assert.isArray(result)
886
- assert.equal(result[0].txid, txid[0])
887
- // assert.equal(result[0].valid, null)
891
+ assert.isArray(result)
892
+ assert.equal(result[0].txid, txid[0])
893
+ // assert.equal(result[0].valid, null)
894
+ })
888
895
  })
889
- })
890
896
 
891
- describe('#validateTxid2', () => {
892
- it('should invalidate a known invalid TXID', async () => {
893
- const txid =
894
- 'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a'
897
+ describe('#validateTxid2', () => {
898
+ it('should invalidate a known invalid TXID', async () => {
899
+ const txid =
900
+ 'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a'
895
901
 
896
- const result = await bchjs.SLP.Utils.validateTxid2(txid)
897
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
902
+ const result = await bchjs.SLP.Utils.validateTxid2(txid)
903
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
898
904
 
899
- assert.property(result, 'txid')
900
- assert.equal(result.txid, txid)
905
+ assert.property(result, 'txid')
906
+ assert.equal(result.txid, txid)
901
907
 
902
- assert.property(result, 'isValid')
903
- assert.equal(result.isValid, false)
904
- })
908
+ assert.property(result, 'isValid')
909
+ assert.equal(result.isValid, false)
910
+ })
905
911
 
906
- it('should validate a known valid TXID', async () => {
907
- const txid =
908
- '3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488'
912
+ it('should validate a known valid TXID', async () => {
913
+ const txid =
914
+ '3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488'
909
915
 
910
- const result = await bchjs.SLP.Utils.validateTxid2(txid)
911
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
916
+ const result = await bchjs.SLP.Utils.validateTxid2(txid)
917
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
912
918
 
913
- assert.property(result, 'txid')
914
- assert.equal(result.txid, txid)
919
+ assert.property(result, 'txid')
920
+ assert.equal(result.txid, txid)
915
921
 
916
- assert.property(result, 'isValid')
917
- assert.equal(result.isValid, true)
922
+ assert.property(result, 'isValid')
923
+ assert.equal(result.isValid, true)
924
+ })
918
925
  })
919
- })
920
926
 
921
- describe('#getWhitelist', () => {
922
- it('should get the whitelist', async () => {
923
- const result = await bchjs.SLP.Utils.getWhitelist()
924
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
927
+ describe('#getWhitelist', () => {
928
+ it('should get the whitelist', async () => {
929
+ const result = await bchjs.SLP.Utils.getWhitelist()
930
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
925
931
 
926
- assert.isArray(result)
927
- assert.property(result[0], 'name')
928
- assert.property(result[1], 'tokenId')
932
+ assert.isArray(result)
933
+ assert.property(result[0], 'name')
934
+ assert.property(result[1], 'tokenId')
935
+ })
929
936
  })
930
- })
931
937
 
932
- describe('#getStatus', () => {
933
- it('should return the current block height of the SLPDB indexer', async () => {
934
- const result = await bchjs.SLP.Utils.getStatus()
938
+ describe('#getStatus', () => {
939
+ it('should return the current block height of the SLPDB indexer', async () => {
940
+ const result = await bchjs.SLP.Utils.getStatus()
935
941
 
936
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
942
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
937
943
 
938
- assert.property(result, 'bchBlockHeight')
939
- assert.property(result, 'slpProcessedBlockHeight')
944
+ assert.property(result, 'bchBlockHeight')
945
+ assert.property(result, 'slpProcessedBlockHeight')
946
+ })
940
947
  })
941
- })
942
948
 
943
- describe('#waterfallValidateTxid', () => {
944
- it('should validate known good txid not in whitelist', async () => {
945
- const txid =
946
- '3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488'
949
+ describe('#waterfallValidateTxid', () => {
950
+ it('should validate known good txid not in whitelist', async () => {
951
+ const txid =
952
+ '3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488'
947
953
 
948
- const result = await bchjs.SLP.Utils.waterfallValidateTxid(txid)
949
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
954
+ const result = await bchjs.SLP.Utils.waterfallValidateTxid(txid)
955
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
950
956
 
951
- assert.equal(result, true)
952
- })
957
+ assert.equal(result, true)
958
+ })
953
959
 
954
- it('should invalidate a known invalid TXID', async () => {
955
- const txid =
956
- 'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a'
960
+ it('should invalidate a known invalid TXID', async () => {
961
+ const txid =
962
+ 'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a'
957
963
 
958
- const result = await bchjs.SLP.Utils.waterfallValidateTxid(txid)
959
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
964
+ const result = await bchjs.SLP.Utils.waterfallValidateTxid(txid)
965
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
960
966
 
961
- assert.equal(result, false)
967
+ assert.equal(result, false)
968
+ })
962
969
  })
963
- })
964
- })
965
-
966
- describe('#tokentype1', () => {
967
- describe('#getHexOpReturn', () => {
968
- it('should return OP_RETURN object ', async () => {
969
- const tokenUtxos = [
970
- {
971
- tokenId:
972
- '38e97c5d7d3585a2cbf3f9580c82ca33985f9cb0845d4dcce220cb709f9538b0',
973
- decimals: 8,
974
- tokenQty: 2
975
- }
976
- ]
977
- const sendQty = 1.5
970
+ describe('#tokentype1', () => {
971
+ describe('#getHexOpReturn', () => {
972
+ it('should return OP_RETURN object ', async () => {
973
+ const tokenUtxos = [
974
+ {
975
+ tokenId:
976
+ '38e97c5d7d3585a2cbf3f9580c82ca33985f9cb0845d4dcce220cb709f9538b0',
977
+ decimals: 8,
978
+ tokenQty: 2
979
+ }
980
+ ]
981
+ const sendQty = 1.5
978
982
 
979
- const result = await bchjs.SLP.TokenType1.getHexOpReturn(
980
- tokenUtxos,
981
- sendQty
982
- )
983
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
983
+ const result = await bchjs.SLP.TokenType1.getHexOpReturn(
984
+ tokenUtxos,
985
+ sendQty
986
+ )
987
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
984
988
 
985
- assert.property(result, 'script')
986
- assert.isString(result.script)
989
+ assert.property(result, 'script')
990
+ assert.isString(result.script)
987
991
 
988
- assert.property(result, 'outputs')
989
- assert.isNumber(result.outputs)
992
+ assert.property(result, 'outputs')
993
+ assert.isNumber(result.outputs)
994
+ })
995
+ })
990
996
  })
991
- })
997
+ }
992
998
  })
993
999
  })
994
1000