@psf/bch-js 6.1.0 → 6.2.2
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 +1 -1
- package/src/slp/utils.js +0 -521
- package/src/transaction.js +9 -467
- package/src/utxo.js +3 -0
- package/test/unit/slp-utils.js +0 -1381
- package/test/unit/transaction-unit.js +4 -688
package/test/unit/slp-utils.js
CHANGED
|
@@ -319,1385 +319,4 @@ describe('#SLP Utils', () => {
|
|
|
319
319
|
}
|
|
320
320
|
})
|
|
321
321
|
})
|
|
322
|
-
|
|
323
|
-
describe('#_hydrateUtxo', () => {
|
|
324
|
-
// // This captures an important corner-case. When an SLP token is created, the
|
|
325
|
-
// // change UTXO will contain the same SLP txid, but it is not an SLP UTXO.
|
|
326
|
-
it('should return details on minting baton from genesis transaction', async () => {
|
|
327
|
-
// Mock the call to REST API
|
|
328
|
-
// sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
329
|
-
|
|
330
|
-
// Stub the calls to decodeOpReturn.
|
|
331
|
-
sandbox.stub(uut.Utils, 'decodeOpReturn').resolves({
|
|
332
|
-
tokenType: 1,
|
|
333
|
-
txType: 'GENESIS',
|
|
334
|
-
ticker: 'SLPSDK',
|
|
335
|
-
name: 'SLP SDK example using BITBOX',
|
|
336
|
-
tokenId:
|
|
337
|
-
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
|
|
338
|
-
documentUri: 'developer.bitcoin.com',
|
|
339
|
-
documentHash: '',
|
|
340
|
-
decimals: 8,
|
|
341
|
-
mintBatonVout: 2,
|
|
342
|
-
qty: '50700000000'
|
|
343
|
-
})
|
|
344
|
-
|
|
345
|
-
const utxos = [
|
|
346
|
-
{
|
|
347
|
-
txid:
|
|
348
|
-
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
|
|
349
|
-
vout: 3,
|
|
350
|
-
amount: 0.00002015,
|
|
351
|
-
satoshis: 2015,
|
|
352
|
-
height: 594892,
|
|
353
|
-
confirmations: 5
|
|
354
|
-
},
|
|
355
|
-
{
|
|
356
|
-
txid:
|
|
357
|
-
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
|
|
358
|
-
vout: 2,
|
|
359
|
-
amount: 0.00000546,
|
|
360
|
-
satoshis: 546,
|
|
361
|
-
height: 594892,
|
|
362
|
-
confirmations: 5
|
|
363
|
-
}
|
|
364
|
-
]
|
|
365
|
-
|
|
366
|
-
const data = await uut.Utils._hydrateUtxo(utxos)
|
|
367
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
368
|
-
|
|
369
|
-
// assert.equal(data[0], false, "Change UTXO marked as false.")
|
|
370
|
-
assert.property(data[0], 'txid')
|
|
371
|
-
assert.property(data[0], 'vout')
|
|
372
|
-
assert.property(data[0], 'amount')
|
|
373
|
-
assert.property(data[0], 'satoshis')
|
|
374
|
-
assert.property(data[0], 'height')
|
|
375
|
-
assert.property(data[0], 'confirmations')
|
|
376
|
-
assert.property(data[0], 'isValid')
|
|
377
|
-
assert.equal(data[0].isValid, false)
|
|
378
|
-
|
|
379
|
-
assert.property(data[1], 'txid')
|
|
380
|
-
assert.property(data[1], 'vout')
|
|
381
|
-
assert.property(data[1], 'amount')
|
|
382
|
-
assert.property(data[1], 'satoshis')
|
|
383
|
-
assert.property(data[1], 'height')
|
|
384
|
-
assert.property(data[1], 'confirmations')
|
|
385
|
-
assert.property(data[1], 'utxoType')
|
|
386
|
-
assert.property(data[1], 'tokenId')
|
|
387
|
-
assert.property(data[1], 'tokenTicker')
|
|
388
|
-
assert.property(data[1], 'tokenName')
|
|
389
|
-
assert.property(data[1], 'tokenDocumentUrl')
|
|
390
|
-
assert.property(data[1], 'tokenDocumentHash')
|
|
391
|
-
assert.property(data[1], 'decimals')
|
|
392
|
-
})
|
|
393
|
-
|
|
394
|
-
// 429 means the user is exceeding the rate limits.
|
|
395
|
-
it('should return isValid=null for 429 rate limit error', async () => {
|
|
396
|
-
// Force decodeOpReturn() to throw a 429 error.
|
|
397
|
-
sandbox.stub(uut.Utils, 'decodeOpReturn').rejects(mockData.mock429Error)
|
|
398
|
-
|
|
399
|
-
const utxos = [
|
|
400
|
-
{
|
|
401
|
-
txid:
|
|
402
|
-
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
|
|
403
|
-
vout: 3,
|
|
404
|
-
amount: 0.00002015,
|
|
405
|
-
satoshis: 2015,
|
|
406
|
-
height: 594892,
|
|
407
|
-
confirmations: 5
|
|
408
|
-
},
|
|
409
|
-
{
|
|
410
|
-
txid:
|
|
411
|
-
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
|
|
412
|
-
vout: 2,
|
|
413
|
-
amount: 0.00000546,
|
|
414
|
-
satoshis: 546,
|
|
415
|
-
height: 594892,
|
|
416
|
-
confirmations: 5
|
|
417
|
-
}
|
|
418
|
-
]
|
|
419
|
-
|
|
420
|
-
const result = await uut.Utils._hydrateUtxo(utxos)
|
|
421
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
422
|
-
|
|
423
|
-
assert.equal(result[0].isValid, null)
|
|
424
|
-
assert.equal(result[1].isValid, null)
|
|
425
|
-
})
|
|
426
|
-
|
|
427
|
-
// 503 means the server is down or is not responding.
|
|
428
|
-
it('should return isValid=null for 503 rate limit error', async () => {
|
|
429
|
-
// Force decodeOpReturn() to throw a 429 error.
|
|
430
|
-
sandbox.stub(uut.Utils, 'decodeOpReturn').rejects(mockData.mock503Error)
|
|
431
|
-
|
|
432
|
-
const utxos = [
|
|
433
|
-
{
|
|
434
|
-
txid:
|
|
435
|
-
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
|
|
436
|
-
vout: 3,
|
|
437
|
-
amount: 0.00002015,
|
|
438
|
-
satoshis: 2015,
|
|
439
|
-
height: 594892,
|
|
440
|
-
confirmations: 5
|
|
441
|
-
},
|
|
442
|
-
{
|
|
443
|
-
txid:
|
|
444
|
-
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
|
|
445
|
-
vout: 2,
|
|
446
|
-
amount: 0.00000546,
|
|
447
|
-
satoshis: 546,
|
|
448
|
-
height: 594892,
|
|
449
|
-
confirmations: 5
|
|
450
|
-
}
|
|
451
|
-
]
|
|
452
|
-
|
|
453
|
-
const result = await uut.Utils._hydrateUtxo(utxos)
|
|
454
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
455
|
-
|
|
456
|
-
assert.equal(result[0].isValid, null)
|
|
457
|
-
assert.equal(result[1].isValid, null)
|
|
458
|
-
})
|
|
459
|
-
|
|
460
|
-
it('should return details for a simple SEND SLP token utxo', async () => {
|
|
461
|
-
// Mock the call to REST API
|
|
462
|
-
// Stub the calls to decodeOpReturn.
|
|
463
|
-
sandbox
|
|
464
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
465
|
-
.onCall(0)
|
|
466
|
-
.resolves({
|
|
467
|
-
tokenType: 1,
|
|
468
|
-
txType: 'SEND',
|
|
469
|
-
tokenId:
|
|
470
|
-
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7',
|
|
471
|
-
amounts: ['200000000', '99887500000000']
|
|
472
|
-
})
|
|
473
|
-
.onCall(1)
|
|
474
|
-
.resolves({
|
|
475
|
-
tokenType: 1,
|
|
476
|
-
txType: 'GENESIS',
|
|
477
|
-
ticker: 'TOK-CH',
|
|
478
|
-
name: 'TokyoCash',
|
|
479
|
-
tokenId:
|
|
480
|
-
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7',
|
|
481
|
-
documentUri: '',
|
|
482
|
-
documentHash: '',
|
|
483
|
-
decimals: 8,
|
|
484
|
-
mintBatonVout: 0,
|
|
485
|
-
qty: '2100000000000000'
|
|
486
|
-
})
|
|
487
|
-
|
|
488
|
-
// sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
489
|
-
|
|
490
|
-
const utxos = [
|
|
491
|
-
{
|
|
492
|
-
txid:
|
|
493
|
-
'fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb',
|
|
494
|
-
vout: 1,
|
|
495
|
-
amount: 0.00000546,
|
|
496
|
-
satoshis: 546,
|
|
497
|
-
height: 596089,
|
|
498
|
-
confirmations: 748
|
|
499
|
-
}
|
|
500
|
-
]
|
|
501
|
-
|
|
502
|
-
const data = await uut.Utils._hydrateUtxo(utxos)
|
|
503
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
504
|
-
|
|
505
|
-
assert.property(data[0], 'txid')
|
|
506
|
-
assert.property(data[0], 'vout')
|
|
507
|
-
assert.property(data[0], 'amount')
|
|
508
|
-
assert.property(data[0], 'satoshis')
|
|
509
|
-
assert.property(data[0], 'height')
|
|
510
|
-
assert.property(data[0], 'confirmations')
|
|
511
|
-
assert.property(data[0], 'utxoType')
|
|
512
|
-
assert.property(data[0], 'tokenId')
|
|
513
|
-
assert.property(data[0], 'tokenTicker')
|
|
514
|
-
assert.property(data[0], 'tokenName')
|
|
515
|
-
assert.property(data[0], 'tokenDocumentUrl')
|
|
516
|
-
assert.property(data[0], 'tokenDocumentHash')
|
|
517
|
-
assert.property(data[0], 'decimals')
|
|
518
|
-
assert.property(data[0], 'tokenQty')
|
|
519
|
-
assert.property(data[0], 'isValid')
|
|
520
|
-
assert.equal(data[0].isValid, null)
|
|
521
|
-
})
|
|
522
|
-
|
|
523
|
-
// I don't know if this is the ideal behavior, but this is the behavior
|
|
524
|
-
// that is in production, so I wanted to capture it in a test case. This
|
|
525
|
-
// behavior can always be changed in the future.
|
|
526
|
-
it('should throw error if 429 when querying Genesis transaction', async () => {
|
|
527
|
-
try {
|
|
528
|
-
// Mock the call to REST API
|
|
529
|
-
// Stub the calls to decodeOpReturn.
|
|
530
|
-
sandbox
|
|
531
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
532
|
-
.onCall(0)
|
|
533
|
-
.resolves({
|
|
534
|
-
tokenType: 1,
|
|
535
|
-
txType: 'SEND',
|
|
536
|
-
tokenId:
|
|
537
|
-
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7',
|
|
538
|
-
amounts: ['200000000', '99887500000000']
|
|
539
|
-
})
|
|
540
|
-
.onCall(1)
|
|
541
|
-
.rejects(mockData.mock429Error)
|
|
542
|
-
|
|
543
|
-
const utxos = [
|
|
544
|
-
{
|
|
545
|
-
txid:
|
|
546
|
-
'fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb',
|
|
547
|
-
vout: 1,
|
|
548
|
-
amount: 0.00000546,
|
|
549
|
-
satoshis: 546,
|
|
550
|
-
height: 596089,
|
|
551
|
-
confirmations: 748
|
|
552
|
-
}
|
|
553
|
-
]
|
|
554
|
-
|
|
555
|
-
await uut.Utils._hydrateUtxo(utxos)
|
|
556
|
-
|
|
557
|
-
assert.fail('Unexpected result')
|
|
558
|
-
} catch (err) {
|
|
559
|
-
// console.log('error: ', err)
|
|
560
|
-
|
|
561
|
-
assert.property(err, 'message')
|
|
562
|
-
assert.property(err, 'response')
|
|
563
|
-
assert.equal(err.response.status, 429)
|
|
564
|
-
assert.equal(err.response.statusText, 'Too Many Requests')
|
|
565
|
-
assert.include(err.response.data.error, 'Too many requests')
|
|
566
|
-
}
|
|
567
|
-
})
|
|
568
|
-
|
|
569
|
-
it('should add delay if delay is specified', async () => {
|
|
570
|
-
// Mock the call to REST API
|
|
571
|
-
// Stub the calls to decodeOpReturn.
|
|
572
|
-
sandbox
|
|
573
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
574
|
-
.onCall(0)
|
|
575
|
-
.resolves({
|
|
576
|
-
tokenType: 1,
|
|
577
|
-
txType: 'SEND',
|
|
578
|
-
tokenId:
|
|
579
|
-
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7',
|
|
580
|
-
amounts: ['200000000', '99887500000000']
|
|
581
|
-
})
|
|
582
|
-
.onCall(1)
|
|
583
|
-
.resolves({
|
|
584
|
-
tokenType: 1,
|
|
585
|
-
txType: 'GENESIS',
|
|
586
|
-
ticker: 'TOK-CH',
|
|
587
|
-
name: 'TokyoCash',
|
|
588
|
-
tokenId:
|
|
589
|
-
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7',
|
|
590
|
-
documentUri: '',
|
|
591
|
-
documentHash: '',
|
|
592
|
-
decimals: 8,
|
|
593
|
-
mintBatonVout: 0,
|
|
594
|
-
qty: '2100000000000000'
|
|
595
|
-
})
|
|
596
|
-
|
|
597
|
-
// sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
598
|
-
|
|
599
|
-
const utxos = [
|
|
600
|
-
{
|
|
601
|
-
txid:
|
|
602
|
-
'fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb',
|
|
603
|
-
vout: 1,
|
|
604
|
-
amount: 0.00000546,
|
|
605
|
-
satoshis: 546,
|
|
606
|
-
height: 596089,
|
|
607
|
-
confirmations: 748
|
|
608
|
-
}
|
|
609
|
-
]
|
|
610
|
-
|
|
611
|
-
const usrObj = {
|
|
612
|
-
utxoDelay: 100
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
await uut.Utils._hydrateUtxo(utxos, usrObj)
|
|
616
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
617
|
-
|
|
618
|
-
// TODO: This test should realy assert that the test took at least 100mS
|
|
619
|
-
// to complete. However, as-is, it exercises the code path, so not
|
|
620
|
-
// throwing an error can be considered a pass.
|
|
621
|
-
assert.equal(true, true)
|
|
622
|
-
})
|
|
623
|
-
})
|
|
624
|
-
|
|
625
|
-
describe('#tokenUtxoDetails', () => {
|
|
626
|
-
it('should throw error if input is not an array.', async () => {
|
|
627
|
-
try {
|
|
628
|
-
await uut.Utils.tokenUtxoDetails('test')
|
|
629
|
-
|
|
630
|
-
assert.equal(true, false, 'Unexpected result.')
|
|
631
|
-
} catch (err) {
|
|
632
|
-
assert.include(
|
|
633
|
-
err.message,
|
|
634
|
-
'Input must be an array',
|
|
635
|
-
'Expected error message.'
|
|
636
|
-
)
|
|
637
|
-
}
|
|
638
|
-
})
|
|
639
|
-
|
|
640
|
-
it('should throw error if utxo does not have txid or tx_hash property.', async () => {
|
|
641
|
-
try {
|
|
642
|
-
const utxos = [
|
|
643
|
-
{
|
|
644
|
-
txid:
|
|
645
|
-
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
|
|
646
|
-
vout: 3,
|
|
647
|
-
amount: 0.00002015,
|
|
648
|
-
satoshis: 2015,
|
|
649
|
-
height: 594892,
|
|
650
|
-
confirmations: 5
|
|
651
|
-
},
|
|
652
|
-
{
|
|
653
|
-
vout: 2,
|
|
654
|
-
amount: 0.00000546,
|
|
655
|
-
satoshis: 546,
|
|
656
|
-
height: 594892,
|
|
657
|
-
confirmations: 5
|
|
658
|
-
}
|
|
659
|
-
]
|
|
660
|
-
|
|
661
|
-
await uut.Utils.tokenUtxoDetails(utxos)
|
|
662
|
-
|
|
663
|
-
assert.equal(true, false, 'Unexpected result.')
|
|
664
|
-
} catch (err) {
|
|
665
|
-
assert.include(
|
|
666
|
-
err.message,
|
|
667
|
-
'utxo 1 does not have a txid or tx_hash property',
|
|
668
|
-
'Expected error message.'
|
|
669
|
-
)
|
|
670
|
-
}
|
|
671
|
-
})
|
|
672
|
-
|
|
673
|
-
// // This captures an important corner-case. When an SLP token is created, the
|
|
674
|
-
// // change UTXO will contain the same SLP txid, but it is not an SLP UTXO.
|
|
675
|
-
it('should return details on minting baton from genesis transaction', async () => {
|
|
676
|
-
// Mock the call to REST API
|
|
677
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
678
|
-
|
|
679
|
-
// Stub the calls to decodeOpReturn.
|
|
680
|
-
sandbox.stub(uut.Utils, 'decodeOpReturn').resolves({
|
|
681
|
-
tokenType: 1,
|
|
682
|
-
txType: 'GENESIS',
|
|
683
|
-
ticker: 'SLPSDK',
|
|
684
|
-
name: 'SLP SDK example using BITBOX',
|
|
685
|
-
tokenId:
|
|
686
|
-
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
|
|
687
|
-
documentUri: 'developer.bitcoin.com',
|
|
688
|
-
documentHash: '',
|
|
689
|
-
decimals: 8,
|
|
690
|
-
mintBatonVout: 2,
|
|
691
|
-
qty: '50700000000'
|
|
692
|
-
})
|
|
693
|
-
|
|
694
|
-
const utxos = [
|
|
695
|
-
{
|
|
696
|
-
txid:
|
|
697
|
-
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
|
|
698
|
-
vout: 3,
|
|
699
|
-
amount: 0.00002015,
|
|
700
|
-
satoshis: 2015,
|
|
701
|
-
height: 594892,
|
|
702
|
-
confirmations: 5
|
|
703
|
-
},
|
|
704
|
-
{
|
|
705
|
-
txid:
|
|
706
|
-
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90',
|
|
707
|
-
vout: 2,
|
|
708
|
-
amount: 0.00000546,
|
|
709
|
-
satoshis: 546,
|
|
710
|
-
height: 594892,
|
|
711
|
-
confirmations: 5
|
|
712
|
-
}
|
|
713
|
-
]
|
|
714
|
-
|
|
715
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
716
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
717
|
-
|
|
718
|
-
// assert.equal(data[0], false, "Change UTXO marked as false.")
|
|
719
|
-
assert.property(data[0], 'txid')
|
|
720
|
-
assert.property(data[0], 'vout')
|
|
721
|
-
assert.property(data[0], 'amount')
|
|
722
|
-
assert.property(data[0], 'satoshis')
|
|
723
|
-
assert.property(data[0], 'height')
|
|
724
|
-
assert.property(data[0], 'confirmations')
|
|
725
|
-
assert.property(data[0], 'isValid')
|
|
726
|
-
assert.equal(data[0].isValid, false)
|
|
727
|
-
|
|
728
|
-
assert.property(data[1], 'txid')
|
|
729
|
-
assert.property(data[1], 'vout')
|
|
730
|
-
assert.property(data[1], 'amount')
|
|
731
|
-
assert.property(data[1], 'satoshis')
|
|
732
|
-
assert.property(data[1], 'height')
|
|
733
|
-
assert.property(data[1], 'confirmations')
|
|
734
|
-
assert.property(data[1], 'utxoType')
|
|
735
|
-
assert.property(data[1], 'tokenId')
|
|
736
|
-
assert.property(data[1], 'tokenTicker')
|
|
737
|
-
assert.property(data[1], 'tokenName')
|
|
738
|
-
assert.property(data[1], 'tokenDocumentUrl')
|
|
739
|
-
assert.property(data[1], 'tokenDocumentHash')
|
|
740
|
-
assert.property(data[1], 'decimals')
|
|
741
|
-
assert.property(data[1], 'isValid')
|
|
742
|
-
assert.equal(data[1].isValid, true)
|
|
743
|
-
})
|
|
744
|
-
|
|
745
|
-
it('should return details for a MINT token utxo', async () => {
|
|
746
|
-
// Mock the call to REST API
|
|
747
|
-
|
|
748
|
-
// Stub the calls to decodeOpReturn.
|
|
749
|
-
sandbox
|
|
750
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
751
|
-
.onCall(0)
|
|
752
|
-
.resolves({
|
|
753
|
-
tokenType: 1,
|
|
754
|
-
txType: 'MINT',
|
|
755
|
-
tokenId:
|
|
756
|
-
'38e97c5d7d3585a2cbf3f9580c82ca33985f9cb0845d4dcce220cb709f9538b0',
|
|
757
|
-
mintBatonVout: 2,
|
|
758
|
-
qty: '1000000000000'
|
|
759
|
-
})
|
|
760
|
-
.onCall(1)
|
|
761
|
-
.resolves({
|
|
762
|
-
tokenType: 1,
|
|
763
|
-
txType: 'GENESIS',
|
|
764
|
-
ticker: 'PSF',
|
|
765
|
-
name: 'Permissionless Software Foundation',
|
|
766
|
-
tokenId:
|
|
767
|
-
'38e97c5d7d3585a2cbf3f9580c82ca33985f9cb0845d4dcce220cb709f9538b0',
|
|
768
|
-
documentUri: 'psfoundation.cash',
|
|
769
|
-
documentHash: '',
|
|
770
|
-
decimals: 8,
|
|
771
|
-
mintBatonVout: 2,
|
|
772
|
-
qty: '1988209163133'
|
|
773
|
-
})
|
|
774
|
-
|
|
775
|
-
// Stub the call to validateTxid
|
|
776
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
777
|
-
|
|
778
|
-
const utxos = [
|
|
779
|
-
{
|
|
780
|
-
txid:
|
|
781
|
-
'cf4b922d1e1aa56b52d752d4206e1448ea76c3ebe69b3b97d8f8f65413bd5c76',
|
|
782
|
-
vout: 1,
|
|
783
|
-
amount: 0.00000546,
|
|
784
|
-
satoshis: 546,
|
|
785
|
-
height: 600297,
|
|
786
|
-
confirmations: 76
|
|
787
|
-
}
|
|
788
|
-
]
|
|
789
|
-
|
|
790
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
791
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
792
|
-
|
|
793
|
-
assert.property(data[0], 'txid')
|
|
794
|
-
assert.property(data[0], 'vout')
|
|
795
|
-
assert.property(data[0], 'amount')
|
|
796
|
-
assert.property(data[0], 'satoshis')
|
|
797
|
-
assert.property(data[0], 'height')
|
|
798
|
-
assert.property(data[0], 'confirmations')
|
|
799
|
-
assert.property(data[0], 'utxoType')
|
|
800
|
-
assert.property(data[0], 'transactionType')
|
|
801
|
-
assert.property(data[0], 'tokenId')
|
|
802
|
-
assert.property(data[0], 'tokenTicker')
|
|
803
|
-
assert.property(data[0], 'tokenName')
|
|
804
|
-
assert.property(data[0], 'tokenDocumentUrl')
|
|
805
|
-
assert.property(data[0], 'tokenDocumentHash')
|
|
806
|
-
assert.property(data[0], 'decimals')
|
|
807
|
-
assert.property(data[0], 'mintBatonVout')
|
|
808
|
-
assert.property(data[0], 'tokenQty')
|
|
809
|
-
assert.property(data[0], 'isValid')
|
|
810
|
-
assert.equal(data[0].isValid, true)
|
|
811
|
-
})
|
|
812
|
-
|
|
813
|
-
it('should return details for a simple SEND SLP token utxo', async () => {
|
|
814
|
-
// Mock the call to REST API
|
|
815
|
-
// Stub the calls to decodeOpReturn.
|
|
816
|
-
sandbox
|
|
817
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
818
|
-
.onCall(0)
|
|
819
|
-
.resolves({
|
|
820
|
-
tokenType: 1,
|
|
821
|
-
txType: 'SEND',
|
|
822
|
-
tokenId:
|
|
823
|
-
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7',
|
|
824
|
-
amounts: ['200000000', '99887500000000']
|
|
825
|
-
})
|
|
826
|
-
.onCall(1)
|
|
827
|
-
.resolves({
|
|
828
|
-
tokenType: 1,
|
|
829
|
-
txType: 'GENESIS',
|
|
830
|
-
ticker: 'TOK-CH',
|
|
831
|
-
name: 'TokyoCash',
|
|
832
|
-
tokenId:
|
|
833
|
-
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7',
|
|
834
|
-
documentUri: '',
|
|
835
|
-
documentHash: '',
|
|
836
|
-
decimals: 8,
|
|
837
|
-
mintBatonVout: 0,
|
|
838
|
-
qty: '2100000000000000'
|
|
839
|
-
})
|
|
840
|
-
|
|
841
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
842
|
-
|
|
843
|
-
const utxos = [
|
|
844
|
-
{
|
|
845
|
-
txid:
|
|
846
|
-
'fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb',
|
|
847
|
-
vout: 1,
|
|
848
|
-
amount: 0.00000546,
|
|
849
|
-
satoshis: 546,
|
|
850
|
-
height: 596089,
|
|
851
|
-
confirmations: 748
|
|
852
|
-
}
|
|
853
|
-
]
|
|
854
|
-
|
|
855
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
856
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
857
|
-
|
|
858
|
-
assert.property(data[0], 'txid')
|
|
859
|
-
assert.property(data[0], 'vout')
|
|
860
|
-
assert.property(data[0], 'amount')
|
|
861
|
-
assert.property(data[0], 'satoshis')
|
|
862
|
-
assert.property(data[0], 'height')
|
|
863
|
-
assert.property(data[0], 'confirmations')
|
|
864
|
-
assert.property(data[0], 'utxoType')
|
|
865
|
-
assert.property(data[0], 'tokenId')
|
|
866
|
-
assert.property(data[0], 'tokenTicker')
|
|
867
|
-
assert.property(data[0], 'tokenName')
|
|
868
|
-
assert.property(data[0], 'tokenDocumentUrl')
|
|
869
|
-
assert.property(data[0], 'tokenDocumentHash')
|
|
870
|
-
assert.property(data[0], 'decimals')
|
|
871
|
-
assert.property(data[0], 'tokenQty')
|
|
872
|
-
assert.property(data[0], 'isValid')
|
|
873
|
-
assert.equal(data[0].isValid, true)
|
|
874
|
-
})
|
|
875
|
-
|
|
876
|
-
it('should handle BCH and SLP utxos in the same TX', async () => {
|
|
877
|
-
// Mock external dependencies.
|
|
878
|
-
// sandbox
|
|
879
|
-
// .stub(uut.Utils, 'validateTxid')
|
|
880
|
-
// .resolves(mockData.mockDualValidation)
|
|
881
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
882
|
-
|
|
883
|
-
sandbox
|
|
884
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
885
|
-
.onCall(0)
|
|
886
|
-
.resolves({
|
|
887
|
-
tokenType: 1,
|
|
888
|
-
txType: 'SEND',
|
|
889
|
-
tokenId:
|
|
890
|
-
'dd84ca78db4d617221b58eabc6667af8fe2f7eadbfcc213d35be9f1b419beb8d',
|
|
891
|
-
amounts: ['1', '5']
|
|
892
|
-
})
|
|
893
|
-
.onCall(1)
|
|
894
|
-
.resolves({
|
|
895
|
-
tokenType: 1,
|
|
896
|
-
txType: 'SEND',
|
|
897
|
-
tokenId:
|
|
898
|
-
'dd84ca78db4d617221b58eabc6667af8fe2f7eadbfcc213d35be9f1b419beb8d',
|
|
899
|
-
amounts: ['1', '5']
|
|
900
|
-
})
|
|
901
|
-
.onCall(2)
|
|
902
|
-
.resolves({
|
|
903
|
-
tokenType: 1,
|
|
904
|
-
txType: 'GENESIS',
|
|
905
|
-
ticker: 'TAP',
|
|
906
|
-
name: 'Thoughts and Prayers',
|
|
907
|
-
tokenId:
|
|
908
|
-
'dd84ca78db4d617221b58eabc6667af8fe2f7eadbfcc213d35be9f1b419beb8d',
|
|
909
|
-
documentUri: '',
|
|
910
|
-
documentHash: '',
|
|
911
|
-
decimals: 0,
|
|
912
|
-
mintBatonVout: 2,
|
|
913
|
-
qty: '1000000'
|
|
914
|
-
})
|
|
915
|
-
|
|
916
|
-
const utxos = [
|
|
917
|
-
{
|
|
918
|
-
txid:
|
|
919
|
-
'd56a2b446d8149c39ca7e06163fe8097168c3604915f631bc58777d669135a56',
|
|
920
|
-
vout: 3,
|
|
921
|
-
value: '6816',
|
|
922
|
-
height: 606848,
|
|
923
|
-
confirmations: 13,
|
|
924
|
-
satoshis: 6816
|
|
925
|
-
},
|
|
926
|
-
{
|
|
927
|
-
txid:
|
|
928
|
-
'd56a2b446d8149c39ca7e06163fe8097168c3604915f631bc58777d669135a56',
|
|
929
|
-
vout: 2,
|
|
930
|
-
value: '546',
|
|
931
|
-
height: 606848,
|
|
932
|
-
confirmations: 13,
|
|
933
|
-
satoshis: 546
|
|
934
|
-
}
|
|
935
|
-
]
|
|
936
|
-
|
|
937
|
-
const result = await uut.Utils.tokenUtxoDetails(utxos)
|
|
938
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
939
|
-
|
|
940
|
-
assert.isArray(result)
|
|
941
|
-
assert.equal(result.length, 2)
|
|
942
|
-
|
|
943
|
-
assert.property(result[0], 'txid')
|
|
944
|
-
assert.property(result[0], 'vout')
|
|
945
|
-
assert.property(result[0], 'value')
|
|
946
|
-
assert.property(result[0], 'satoshis')
|
|
947
|
-
assert.property(result[0], 'height')
|
|
948
|
-
assert.property(result[0], 'confirmations')
|
|
949
|
-
assert.property(result[0], 'isValid')
|
|
950
|
-
assert.equal(result[0].isValid, false)
|
|
951
|
-
|
|
952
|
-
assert.equal(result[1].isValid, true)
|
|
953
|
-
assert.equal(result[1].utxoType, 'token')
|
|
954
|
-
assert.equal(result[1].transactionType, 'send')
|
|
955
|
-
})
|
|
956
|
-
|
|
957
|
-
it('should handle problematic utxos', async () => {
|
|
958
|
-
// Mock external dependencies.
|
|
959
|
-
// Stub the calls to decodeOpReturn.
|
|
960
|
-
sandbox
|
|
961
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
962
|
-
.onCall(0)
|
|
963
|
-
.throws({ message: 'scriptpubkey not op_return' })
|
|
964
|
-
.onCall(1)
|
|
965
|
-
.resolves({
|
|
966
|
-
tokenType: 1,
|
|
967
|
-
txType: 'SEND',
|
|
968
|
-
tokenId:
|
|
969
|
-
'f05faf13a29c7f5e54ab921750aafb6afaa953db863bd2cf432e918661d4132f',
|
|
970
|
-
amounts: ['5000000', '395010942']
|
|
971
|
-
})
|
|
972
|
-
.onCall(2)
|
|
973
|
-
.resolves({
|
|
974
|
-
tokenType: 1,
|
|
975
|
-
txType: 'GENESIS',
|
|
976
|
-
ticker: 'AUDC',
|
|
977
|
-
name: 'AUD Coin',
|
|
978
|
-
tokenId:
|
|
979
|
-
'f05faf13a29c7f5e54ab921750aafb6afaa953db863bd2cf432e918661d4132f',
|
|
980
|
-
documentUri: 'audcoino@gmail.com',
|
|
981
|
-
documentHash: '',
|
|
982
|
-
decimals: 6,
|
|
983
|
-
mintBatonVout: 0,
|
|
984
|
-
qty: '2000000000000000000'
|
|
985
|
-
})
|
|
986
|
-
|
|
987
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
988
|
-
|
|
989
|
-
const utxos = [
|
|
990
|
-
{
|
|
991
|
-
txid:
|
|
992
|
-
'0e3a217fc22612002031d317b4cecd9b692b66b52951a67b23c43041aefa3959',
|
|
993
|
-
vout: 0,
|
|
994
|
-
amount: 0.00018362,
|
|
995
|
-
satoshis: 18362,
|
|
996
|
-
height: 613483,
|
|
997
|
-
confirmations: 124
|
|
998
|
-
},
|
|
999
|
-
{
|
|
1000
|
-
txid:
|
|
1001
|
-
'67fd3c7c3a6eb0fea9ab311b91039545086220f7eeeefa367fa28e6e43009f19',
|
|
1002
|
-
vout: 1,
|
|
1003
|
-
amount: 0.00000546,
|
|
1004
|
-
satoshis: 546,
|
|
1005
|
-
height: 612075,
|
|
1006
|
-
confirmations: 1532
|
|
1007
|
-
}
|
|
1008
|
-
]
|
|
1009
|
-
|
|
1010
|
-
const result = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1011
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
1012
|
-
|
|
1013
|
-
assert.isArray(result)
|
|
1014
|
-
assert.equal(result.length, 2)
|
|
1015
|
-
|
|
1016
|
-
assert.property(result[0], 'txid')
|
|
1017
|
-
assert.property(result[0], 'vout')
|
|
1018
|
-
assert.property(result[0], 'amount')
|
|
1019
|
-
assert.property(result[0], 'satoshis')
|
|
1020
|
-
assert.property(result[0], 'height')
|
|
1021
|
-
assert.property(result[0], 'confirmations')
|
|
1022
|
-
assert.property(result[0], 'isValid')
|
|
1023
|
-
assert.equal(result[0].isValid, false)
|
|
1024
|
-
|
|
1025
|
-
assert.equal(result[1].isValid, true)
|
|
1026
|
-
assert.equal(result[1].utxoType, 'token')
|
|
1027
|
-
assert.equal(result[1].transactionType, 'send')
|
|
1028
|
-
})
|
|
1029
|
-
|
|
1030
|
-
it('should return isValid=false for BCH-only UTXOs', async () => {
|
|
1031
|
-
// Mock live network calls
|
|
1032
|
-
|
|
1033
|
-
sandbox
|
|
1034
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
1035
|
-
.throws(new Error('scriptpubkey not op_return'))
|
|
1036
|
-
|
|
1037
|
-
const utxos = [
|
|
1038
|
-
{
|
|
1039
|
-
txid:
|
|
1040
|
-
'a937f792c7c9eb23b4f344ce5c233d1ac0909217d0a504d71e6b1e4efb864a3b',
|
|
1041
|
-
vout: 0,
|
|
1042
|
-
amount: 0.00001,
|
|
1043
|
-
satoshis: 1000,
|
|
1044
|
-
confirmations: 0,
|
|
1045
|
-
ts: 1578424704
|
|
1046
|
-
},
|
|
1047
|
-
{
|
|
1048
|
-
txid:
|
|
1049
|
-
'53fd141c2e999e080a5860887441a2c45e9cbe262027e2bd2ac998fc76e43c44',
|
|
1050
|
-
vout: 0,
|
|
1051
|
-
amount: 0.00001,
|
|
1052
|
-
satoshis: 1000,
|
|
1053
|
-
confirmations: 0,
|
|
1054
|
-
ts: 1578424634
|
|
1055
|
-
}
|
|
1056
|
-
]
|
|
1057
|
-
|
|
1058
|
-
const result = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1059
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
1060
|
-
|
|
1061
|
-
assert.isArray(result)
|
|
1062
|
-
|
|
1063
|
-
assert.property(result[0], 'txid')
|
|
1064
|
-
assert.property(result[0], 'vout')
|
|
1065
|
-
assert.property(result[0], 'amount')
|
|
1066
|
-
assert.property(result[0], 'satoshis')
|
|
1067
|
-
assert.property(result[0], 'confirmations')
|
|
1068
|
-
assert.property(result[0], 'isValid')
|
|
1069
|
-
assert.equal(result[0].isValid, false)
|
|
1070
|
-
|
|
1071
|
-
assert.property(result[1], 'txid')
|
|
1072
|
-
assert.property(result[1], 'vout')
|
|
1073
|
-
assert.property(result[1], 'amount')
|
|
1074
|
-
assert.property(result[1], 'satoshis')
|
|
1075
|
-
assert.property(result[1], 'confirmations')
|
|
1076
|
-
assert.property(result[1], 'isValid')
|
|
1077
|
-
assert.equal(result[1].isValid, false)
|
|
1078
|
-
})
|
|
1079
|
-
|
|
1080
|
-
it('should decode a Genesis transaction', async () => {
|
|
1081
|
-
const slpData = {
|
|
1082
|
-
tokenType: 1,
|
|
1083
|
-
txType: 'GENESIS',
|
|
1084
|
-
ticker: 'SLPTEST',
|
|
1085
|
-
name: 'SLP Test Token',
|
|
1086
|
-
tokenId:
|
|
1087
|
-
'd2ec6abff5d1c8ed9ab5db6d140dcaebb813463e42933a4a4db171e7222a0954',
|
|
1088
|
-
documentUri: 'https://FullStack.cash',
|
|
1089
|
-
documentHash: '',
|
|
1090
|
-
decimals: 8,
|
|
1091
|
-
mintBatonVout: 2,
|
|
1092
|
-
qty: '10000000000'
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
// Mock external dependencies.
|
|
1096
|
-
// Stub the calls to decodeOpReturn.
|
|
1097
|
-
sandbox.stub(uut.Utils, 'decodeOpReturn').resolves(slpData)
|
|
1098
|
-
|
|
1099
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
1100
|
-
|
|
1101
|
-
const utxos = [
|
|
1102
|
-
{
|
|
1103
|
-
txid:
|
|
1104
|
-
'd2ec6abff5d1c8ed9ab5db6d140dcaebb813463e42933a4a4db171e7222a0954',
|
|
1105
|
-
vout: 1,
|
|
1106
|
-
value: '546',
|
|
1107
|
-
confirmations: 0,
|
|
1108
|
-
satoshis: 546
|
|
1109
|
-
},
|
|
1110
|
-
{
|
|
1111
|
-
txid:
|
|
1112
|
-
'd2ec6abff5d1c8ed9ab5db6d140dcaebb813463e42933a4a4db171e7222a0954',
|
|
1113
|
-
vout: 2,
|
|
1114
|
-
value: '546',
|
|
1115
|
-
confirmations: 0,
|
|
1116
|
-
satoshis: 546
|
|
1117
|
-
},
|
|
1118
|
-
{
|
|
1119
|
-
txid:
|
|
1120
|
-
'd2ec6abff5d1c8ed9ab5db6d140dcaebb813463e42933a4a4db171e7222a0954',
|
|
1121
|
-
vout: 3,
|
|
1122
|
-
value: '12178',
|
|
1123
|
-
confirmations: 0,
|
|
1124
|
-
satoshis: 12178
|
|
1125
|
-
}
|
|
1126
|
-
]
|
|
1127
|
-
|
|
1128
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1129
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
1130
|
-
|
|
1131
|
-
assert.isArray(data)
|
|
1132
|
-
|
|
1133
|
-
assert.equal(data[0].utxoType, 'token')
|
|
1134
|
-
assert.equal(data[0].tokenQty, 100)
|
|
1135
|
-
assert.equal(data[0].isValid, true)
|
|
1136
|
-
assert.equal(data[0].tokenType, 1)
|
|
1137
|
-
|
|
1138
|
-
assert.equal(data[1].utxoType, 'minting-baton')
|
|
1139
|
-
assert.equal(data[1].isValid, true)
|
|
1140
|
-
assert.equal(data[1].tokenType, 1)
|
|
1141
|
-
|
|
1142
|
-
assert.equal(data[2].isValid, false)
|
|
1143
|
-
})
|
|
1144
|
-
|
|
1145
|
-
it('should decode a Mint transaction', async () => {
|
|
1146
|
-
// Define stubbed data.
|
|
1147
|
-
const slpData = {
|
|
1148
|
-
tokenType: 1,
|
|
1149
|
-
txType: 'MINT',
|
|
1150
|
-
tokenId:
|
|
1151
|
-
'9d35c1803ed3ab8bd23c198b027f7b3b530586494dc265de6391b74a6b090136',
|
|
1152
|
-
mintBatonVout: 2,
|
|
1153
|
-
qty: '10000000000'
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
const genesisData = {
|
|
1157
|
-
tokenType: 1,
|
|
1158
|
-
txType: 'GENESIS',
|
|
1159
|
-
ticker: 'SLPTEST',
|
|
1160
|
-
name: 'SLP Test Token',
|
|
1161
|
-
tokenId:
|
|
1162
|
-
'9d35c1803ed3ab8bd23c198b027f7b3b530586494dc265de6391b74a6b090136',
|
|
1163
|
-
documentUri: 'https://FullStack.cash',
|
|
1164
|
-
documentHash: '',
|
|
1165
|
-
decimals: 8,
|
|
1166
|
-
mintBatonVout: 2,
|
|
1167
|
-
qty: '10000000000'
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
// Mock external dependencies.
|
|
1171
|
-
// Stub the calls to decodeOpReturn.
|
|
1172
|
-
sandbox
|
|
1173
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
1174
|
-
.resolves(slpData)
|
|
1175
|
-
.onCall(1)
|
|
1176
|
-
.resolves(genesisData)
|
|
1177
|
-
.onCall(2)
|
|
1178
|
-
.resolves(slpData)
|
|
1179
|
-
.onCall(3)
|
|
1180
|
-
.resolves(genesisData)
|
|
1181
|
-
.onCall(4)
|
|
1182
|
-
.resolves(slpData)
|
|
1183
|
-
|
|
1184
|
-
// Stub the call to validateTxid
|
|
1185
|
-
// sandbox
|
|
1186
|
-
// .stub(uut.Utils, 'validateTxid')
|
|
1187
|
-
// .resolves(stubValid)
|
|
1188
|
-
// .onCall(1)
|
|
1189
|
-
// .resolves(stubValid)
|
|
1190
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
1191
|
-
|
|
1192
|
-
const utxos = [
|
|
1193
|
-
{
|
|
1194
|
-
txid:
|
|
1195
|
-
'880587f01e3112e779c0fdf1b9b859c242a28e56ead85483eeedcaa52f051a04',
|
|
1196
|
-
vout: 1,
|
|
1197
|
-
value: '546',
|
|
1198
|
-
confirmations: 0,
|
|
1199
|
-
satoshis: 546
|
|
1200
|
-
},
|
|
1201
|
-
{
|
|
1202
|
-
txid:
|
|
1203
|
-
'880587f01e3112e779c0fdf1b9b859c242a28e56ead85483eeedcaa52f051a04',
|
|
1204
|
-
vout: 2,
|
|
1205
|
-
value: '546',
|
|
1206
|
-
confirmations: 0,
|
|
1207
|
-
satoshis: 546
|
|
1208
|
-
},
|
|
1209
|
-
{
|
|
1210
|
-
txid:
|
|
1211
|
-
'880587f01e3112e779c0fdf1b9b859c242a28e56ead85483eeedcaa52f051a04',
|
|
1212
|
-
vout: 3,
|
|
1213
|
-
value: '10552',
|
|
1214
|
-
confirmations: 0,
|
|
1215
|
-
satoshis: 10552
|
|
1216
|
-
}
|
|
1217
|
-
]
|
|
1218
|
-
|
|
1219
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1220
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
1221
|
-
|
|
1222
|
-
assert.isArray(data)
|
|
1223
|
-
|
|
1224
|
-
assert.equal(data[0].utxoType, 'token')
|
|
1225
|
-
assert.equal(data[0].tokenQty, 100)
|
|
1226
|
-
assert.equal(data[0].isValid, true)
|
|
1227
|
-
assert.equal(data[0].tokenType, 1)
|
|
1228
|
-
|
|
1229
|
-
assert.equal(data[1].utxoType, 'minting-baton')
|
|
1230
|
-
assert.equal(data[1].isValid, true)
|
|
1231
|
-
assert.equal(data[1].tokenType, 1)
|
|
1232
|
-
|
|
1233
|
-
assert.equal(data[2].isValid, false)
|
|
1234
|
-
})
|
|
1235
|
-
|
|
1236
|
-
it('should decode a NFT Group Genesis transaction', async () => {
|
|
1237
|
-
// Define stubbed data.
|
|
1238
|
-
const slpData = {
|
|
1239
|
-
tokenType: 129,
|
|
1240
|
-
txType: 'GENESIS',
|
|
1241
|
-
ticker: 'NFTTT',
|
|
1242
|
-
name: 'NFT Test Token',
|
|
1243
|
-
tokenId:
|
|
1244
|
-
'4ef6eb92950a13a69e97c2c02c7967d806aa874c0e2a6b5546a8880f2cd14bc4',
|
|
1245
|
-
documentUri: 'https://FullStack.cash',
|
|
1246
|
-
documentHash: '',
|
|
1247
|
-
decimals: 0,
|
|
1248
|
-
mintBatonVout: 2,
|
|
1249
|
-
qty: '1'
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
|
-
// Mock external dependencies.
|
|
1253
|
-
// Stub the calls to decodeOpReturn.
|
|
1254
|
-
sandbox
|
|
1255
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
1256
|
-
.resolves(slpData)
|
|
1257
|
-
.onCall(1)
|
|
1258
|
-
.resolves(slpData)
|
|
1259
|
-
.onCall(2)
|
|
1260
|
-
.resolves(slpData)
|
|
1261
|
-
.onCall(3)
|
|
1262
|
-
.resolves(slpData)
|
|
1263
|
-
.onCall(4)
|
|
1264
|
-
.resolves(slpData)
|
|
1265
|
-
|
|
1266
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
1267
|
-
|
|
1268
|
-
const utxos = [
|
|
1269
|
-
{
|
|
1270
|
-
txid:
|
|
1271
|
-
'4ef6eb92950a13a69e97c2c02c7967d806aa874c0e2a6b5546a8880f2cd14bc4',
|
|
1272
|
-
vout: 3,
|
|
1273
|
-
value: '15620',
|
|
1274
|
-
height: 638207,
|
|
1275
|
-
confirmations: 3,
|
|
1276
|
-
satoshis: 15620
|
|
1277
|
-
},
|
|
1278
|
-
{
|
|
1279
|
-
txid:
|
|
1280
|
-
'4ef6eb92950a13a69e97c2c02c7967d806aa874c0e2a6b5546a8880f2cd14bc4',
|
|
1281
|
-
vout: 2,
|
|
1282
|
-
value: '546',
|
|
1283
|
-
height: 638207,
|
|
1284
|
-
confirmations: 3,
|
|
1285
|
-
satoshis: 546
|
|
1286
|
-
},
|
|
1287
|
-
{
|
|
1288
|
-
txid:
|
|
1289
|
-
'4ef6eb92950a13a69e97c2c02c7967d806aa874c0e2a6b5546a8880f2cd14bc4',
|
|
1290
|
-
vout: 1,
|
|
1291
|
-
value: '546',
|
|
1292
|
-
height: 638207,
|
|
1293
|
-
confirmations: 3,
|
|
1294
|
-
satoshis: 546
|
|
1295
|
-
}
|
|
1296
|
-
]
|
|
1297
|
-
|
|
1298
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1299
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
1300
|
-
|
|
1301
|
-
assert.isArray(data)
|
|
1302
|
-
|
|
1303
|
-
assert.equal(data[0].isValid, false)
|
|
1304
|
-
|
|
1305
|
-
assert.equal(data[1].utxoType, 'minting-baton')
|
|
1306
|
-
assert.equal(data[1].isValid, true)
|
|
1307
|
-
assert.equal(data[1].tokenType, 129)
|
|
1308
|
-
|
|
1309
|
-
assert.equal(data[2].utxoType, 'token')
|
|
1310
|
-
assert.equal(data[2].tokenType, 129)
|
|
1311
|
-
assert.equal(data[1].isValid, true)
|
|
1312
|
-
})
|
|
1313
|
-
|
|
1314
|
-
it('should decode a NFT Group Mint transaction', async () => {
|
|
1315
|
-
// Define stubbed data.
|
|
1316
|
-
const slpData = {
|
|
1317
|
-
tokenType: 129,
|
|
1318
|
-
txType: 'MINT',
|
|
1319
|
-
tokenId:
|
|
1320
|
-
'eee4b82e4bb7113eca433829144363fc45f110693c286494fbf5b5c8043cc981',
|
|
1321
|
-
mintBatonVout: 2,
|
|
1322
|
-
qty: '10'
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
|
-
const genesisData = {
|
|
1326
|
-
tokenType: 129,
|
|
1327
|
-
txType: 'GENESIS',
|
|
1328
|
-
ticker: 'NFTTT',
|
|
1329
|
-
name: 'NFT Test Token',
|
|
1330
|
-
tokenId:
|
|
1331
|
-
'eee4b82e4bb7113eca433829144363fc45f110693c286494fbf5b5c8043cc981',
|
|
1332
|
-
documentUri: 'https://FullStack.cash',
|
|
1333
|
-
documentHash: '',
|
|
1334
|
-
decimals: 0,
|
|
1335
|
-
mintBatonVout: 2,
|
|
1336
|
-
qty: '1'
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1339
|
-
// Mock external dependencies.
|
|
1340
|
-
// Stub the calls to decodeOpReturn.
|
|
1341
|
-
sandbox
|
|
1342
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
1343
|
-
.resolves(slpData)
|
|
1344
|
-
.onCall(1)
|
|
1345
|
-
.resolves(slpData)
|
|
1346
|
-
.onCall(2)
|
|
1347
|
-
.resolves(genesisData)
|
|
1348
|
-
.onCall(3)
|
|
1349
|
-
.resolves(slpData)
|
|
1350
|
-
.onCall(4)
|
|
1351
|
-
.resolves(genesisData)
|
|
1352
|
-
|
|
1353
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
1354
|
-
|
|
1355
|
-
const utxos = [
|
|
1356
|
-
{
|
|
1357
|
-
txid:
|
|
1358
|
-
'35846676e7514658bbd2fd60b1f0d4d86195908f6b2de5328d54c8e4a2d05919',
|
|
1359
|
-
vout: 3,
|
|
1360
|
-
value: '15620',
|
|
1361
|
-
height: 638207,
|
|
1362
|
-
confirmations: 3,
|
|
1363
|
-
satoshis: 15620
|
|
1364
|
-
},
|
|
1365
|
-
{
|
|
1366
|
-
txid:
|
|
1367
|
-
'35846676e7514658bbd2fd60b1f0d4d86195908f6b2de5328d54c8e4a2d05919',
|
|
1368
|
-
vout: 2,
|
|
1369
|
-
value: '546',
|
|
1370
|
-
height: 638207,
|
|
1371
|
-
confirmations: 3,
|
|
1372
|
-
satoshis: 546
|
|
1373
|
-
},
|
|
1374
|
-
{
|
|
1375
|
-
txid:
|
|
1376
|
-
'35846676e7514658bbd2fd60b1f0d4d86195908f6b2de5328d54c8e4a2d05919',
|
|
1377
|
-
vout: 1,
|
|
1378
|
-
value: '546',
|
|
1379
|
-
height: 638207,
|
|
1380
|
-
confirmations: 3,
|
|
1381
|
-
satoshis: 546
|
|
1382
|
-
}
|
|
1383
|
-
]
|
|
1384
|
-
|
|
1385
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1386
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
1387
|
-
|
|
1388
|
-
assert.isArray(data)
|
|
1389
|
-
|
|
1390
|
-
assert.equal(data[0].isValid, false)
|
|
1391
|
-
|
|
1392
|
-
assert.equal(data[1].utxoType, 'minting-baton')
|
|
1393
|
-
assert.equal(data[1].tokenType, 129)
|
|
1394
|
-
assert.equal(data[1].isValid, true)
|
|
1395
|
-
|
|
1396
|
-
assert.equal(data[2].utxoType, 'token')
|
|
1397
|
-
assert.equal(data[2].tokenType, 129)
|
|
1398
|
-
assert.equal(data[2].isValid, true)
|
|
1399
|
-
})
|
|
1400
|
-
|
|
1401
|
-
it('should decode a NFT Child Genesis transaction', async () => {
|
|
1402
|
-
// Define stubbed data.
|
|
1403
|
-
const slpData = {
|
|
1404
|
-
tokenType: 65,
|
|
1405
|
-
txType: 'GENESIS',
|
|
1406
|
-
ticker: 'NFTC',
|
|
1407
|
-
name: 'NFT Child',
|
|
1408
|
-
tokenId:
|
|
1409
|
-
'9b6db26b64aedcedc0bd9a3037b29b3598573ec5cea99eec03faa838616cd683',
|
|
1410
|
-
documentUri: 'https://FullStack.cash',
|
|
1411
|
-
documentHash: '',
|
|
1412
|
-
decimals: 0,
|
|
1413
|
-
mintBatonVout: 0,
|
|
1414
|
-
qty: '1'
|
|
1415
|
-
}
|
|
1416
|
-
|
|
1417
|
-
// Mock external dependencies.
|
|
1418
|
-
// Stub the calls to decodeOpReturn.
|
|
1419
|
-
sandbox
|
|
1420
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
1421
|
-
.resolves(slpData)
|
|
1422
|
-
.onCall(1)
|
|
1423
|
-
.resolves(slpData)
|
|
1424
|
-
|
|
1425
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
1426
|
-
|
|
1427
|
-
const utxos = [
|
|
1428
|
-
{
|
|
1429
|
-
txid:
|
|
1430
|
-
'9b6db26b64aedcedc0bd9a3037b29b3598573ec5cea99eec03faa838616cd683',
|
|
1431
|
-
vout: 1,
|
|
1432
|
-
value: '546',
|
|
1433
|
-
confirmations: 0,
|
|
1434
|
-
satoshis: 546
|
|
1435
|
-
},
|
|
1436
|
-
{
|
|
1437
|
-
txid:
|
|
1438
|
-
'9b6db26b64aedcedc0bd9a3037b29b3598573ec5cea99eec03faa838616cd683',
|
|
1439
|
-
vout: 2,
|
|
1440
|
-
value: '13478',
|
|
1441
|
-
confirmations: 0,
|
|
1442
|
-
satoshis: 13478
|
|
1443
|
-
}
|
|
1444
|
-
]
|
|
1445
|
-
|
|
1446
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1447
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
1448
|
-
|
|
1449
|
-
assert.isArray(data)
|
|
1450
|
-
|
|
1451
|
-
assert.equal(data[0].utxoType, 'token')
|
|
1452
|
-
assert.equal(data[0].tokenType, 65)
|
|
1453
|
-
assert.equal(data[0].isValid, true)
|
|
1454
|
-
|
|
1455
|
-
assert.equal(data[1].isValid, false)
|
|
1456
|
-
})
|
|
1457
|
-
|
|
1458
|
-
it('should decode an NFT Child Send transaction', async () => {
|
|
1459
|
-
// Define stubbed data.
|
|
1460
|
-
const slpData = {
|
|
1461
|
-
tokenType: 65,
|
|
1462
|
-
txType: 'SEND',
|
|
1463
|
-
tokenId:
|
|
1464
|
-
'9b6db26b64aedcedc0bd9a3037b29b3598573ec5cea99eec03faa838616cd683',
|
|
1465
|
-
amounts: ['1']
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
|
-
const genesisData = {
|
|
1469
|
-
tokenType: 65,
|
|
1470
|
-
txType: 'GENESIS',
|
|
1471
|
-
ticker: 'NFTC',
|
|
1472
|
-
name: 'NFT Child',
|
|
1473
|
-
tokenId:
|
|
1474
|
-
'9b6db26b64aedcedc0bd9a3037b29b3598573ec5cea99eec03faa838616cd683',
|
|
1475
|
-
documentUri: 'https://FullStack.cash',
|
|
1476
|
-
documentHash: '',
|
|
1477
|
-
decimals: 0,
|
|
1478
|
-
mintBatonVout: 0,
|
|
1479
|
-
qty: '1'
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
// Mock external dependencies.
|
|
1483
|
-
// Stub the calls to decodeOpReturn.
|
|
1484
|
-
sandbox
|
|
1485
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
1486
|
-
.resolves(slpData)
|
|
1487
|
-
.onCall(1)
|
|
1488
|
-
.resolves(genesisData)
|
|
1489
|
-
.onCall(2)
|
|
1490
|
-
.resolves(slpData)
|
|
1491
|
-
|
|
1492
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
1493
|
-
|
|
1494
|
-
const utxos = [
|
|
1495
|
-
{
|
|
1496
|
-
txid:
|
|
1497
|
-
'6d68a7ffbb63ef851c43025f801a1d365cddda50b00741bca022c743d74cd61a',
|
|
1498
|
-
vout: 1,
|
|
1499
|
-
value: '546',
|
|
1500
|
-
confirmations: 0,
|
|
1501
|
-
satoshis: 546
|
|
1502
|
-
},
|
|
1503
|
-
{
|
|
1504
|
-
txid:
|
|
1505
|
-
'6d68a7ffbb63ef851c43025f801a1d365cddda50b00741bca022c743d74cd61a',
|
|
1506
|
-
vout: 2,
|
|
1507
|
-
value: '12136',
|
|
1508
|
-
confirmations: 0,
|
|
1509
|
-
satoshis: 12136
|
|
1510
|
-
}
|
|
1511
|
-
]
|
|
1512
|
-
|
|
1513
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1514
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
1515
|
-
|
|
1516
|
-
assert.isArray(data)
|
|
1517
|
-
|
|
1518
|
-
assert.equal(data[0].utxoType, 'token')
|
|
1519
|
-
assert.equal(data[0].transactionType, 'send')
|
|
1520
|
-
assert.equal(data[0].tokenType, 65)
|
|
1521
|
-
assert.equal(data[0].isValid, true)
|
|
1522
|
-
|
|
1523
|
-
assert.equal(data[1].isValid, false)
|
|
1524
|
-
})
|
|
1525
|
-
|
|
1526
|
-
it('should decode an NFT Group Send transaction', async () => {
|
|
1527
|
-
// Define stubbed data.
|
|
1528
|
-
const slpData = {
|
|
1529
|
-
tokenType: 129,
|
|
1530
|
-
txType: 'SEND',
|
|
1531
|
-
tokenId:
|
|
1532
|
-
'eee4b82e4bb7113eca433829144363fc45f110693c286494fbf5b5c8043cc981',
|
|
1533
|
-
amounts: ['1', '8']
|
|
1534
|
-
}
|
|
1535
|
-
|
|
1536
|
-
const genesisData = {
|
|
1537
|
-
tokenType: 129,
|
|
1538
|
-
txType: 'GENESIS',
|
|
1539
|
-
ticker: 'NFTTT',
|
|
1540
|
-
name: 'NFT Test Token',
|
|
1541
|
-
tokenId:
|
|
1542
|
-
'eee4b82e4bb7113eca433829144363fc45f110693c286494fbf5b5c8043cc981',
|
|
1543
|
-
documentUri: 'https://FullStack.cash',
|
|
1544
|
-
documentHash: '',
|
|
1545
|
-
decimals: 0,
|
|
1546
|
-
mintBatonVout: 2,
|
|
1547
|
-
qty: '1'
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
// Mock external dependencies.
|
|
1551
|
-
// Stub the calls to decodeOpReturn.
|
|
1552
|
-
sandbox
|
|
1553
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
1554
|
-
.resolves(slpData)
|
|
1555
|
-
.onCall(1)
|
|
1556
|
-
.resolves(genesisData)
|
|
1557
|
-
.onCall(2)
|
|
1558
|
-
.resolves(slpData)
|
|
1559
|
-
.onCall(3)
|
|
1560
|
-
.resolves(genesisData)
|
|
1561
|
-
.onCall(4)
|
|
1562
|
-
.resolves(slpData)
|
|
1563
|
-
|
|
1564
|
-
sandbox.stub(uut.Utils, 'waterfallValidateTxid').resolves(true)
|
|
1565
|
-
|
|
1566
|
-
const utxos = [
|
|
1567
|
-
{
|
|
1568
|
-
txid:
|
|
1569
|
-
'57cc47c265ce878679e95e2cec510d8a1a9840f5c62feb4743cc5947d57d9766',
|
|
1570
|
-
vout: 1,
|
|
1571
|
-
value: '546',
|
|
1572
|
-
confirmations: 0,
|
|
1573
|
-
satoshis: 546
|
|
1574
|
-
},
|
|
1575
|
-
{
|
|
1576
|
-
txid:
|
|
1577
|
-
'57cc47c265ce878679e95e2cec510d8a1a9840f5c62feb4743cc5947d57d9766',
|
|
1578
|
-
vout: 2,
|
|
1579
|
-
value: '546',
|
|
1580
|
-
confirmations: 0,
|
|
1581
|
-
satoshis: 546
|
|
1582
|
-
},
|
|
1583
|
-
{
|
|
1584
|
-
txid:
|
|
1585
|
-
'57cc47c265ce878679e95e2cec510d8a1a9840f5c62feb4743cc5947d57d9766',
|
|
1586
|
-
vout: 3,
|
|
1587
|
-
value: '10794',
|
|
1588
|
-
confirmations: 0,
|
|
1589
|
-
satoshis: 10794
|
|
1590
|
-
}
|
|
1591
|
-
]
|
|
1592
|
-
|
|
1593
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1594
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
1595
|
-
|
|
1596
|
-
assert.isArray(data)
|
|
1597
|
-
|
|
1598
|
-
assert.equal(data[0].utxoType, 'token')
|
|
1599
|
-
assert.equal(data[0].transactionType, 'send')
|
|
1600
|
-
assert.equal(data[0].tokenType, 129)
|
|
1601
|
-
assert.equal(data[0].isValid, true)
|
|
1602
|
-
|
|
1603
|
-
assert.equal(data[1].utxoType, 'token')
|
|
1604
|
-
assert.equal(data[1].transactionType, 'send')
|
|
1605
|
-
assert.equal(data[1].tokenType, 129)
|
|
1606
|
-
assert.equal(data[1].isValid, true)
|
|
1607
|
-
|
|
1608
|
-
assert.equal(data[2].isValid, false)
|
|
1609
|
-
})
|
|
1610
|
-
|
|
1611
|
-
it('should return null value when 429 recieved', async () => {
|
|
1612
|
-
const utxos = [
|
|
1613
|
-
{
|
|
1614
|
-
height: 654522,
|
|
1615
|
-
tx_hash:
|
|
1616
|
-
'072a1e2c2d5f1309bf4eef7f88684e4ecd544a903b386b07f3e04b91b13d8af1',
|
|
1617
|
-
tx_pos: 0,
|
|
1618
|
-
value: 6999,
|
|
1619
|
-
satoshis: 6999,
|
|
1620
|
-
txid:
|
|
1621
|
-
'072a1e2c2d5f1309bf4eef7f88684e4ecd544a903b386b07f3e04b91b13d8af1',
|
|
1622
|
-
vout: 0
|
|
1623
|
-
},
|
|
1624
|
-
{
|
|
1625
|
-
height: 654522,
|
|
1626
|
-
tx_hash:
|
|
1627
|
-
'a72db6a0883ecb8e379f317231b2571e41e041b7b1107e3e54c2e0b3386ac6ca',
|
|
1628
|
-
tx_pos: 1,
|
|
1629
|
-
value: 546,
|
|
1630
|
-
satoshis: 546,
|
|
1631
|
-
txid:
|
|
1632
|
-
'a72db6a0883ecb8e379f317231b2571e41e041b7b1107e3e54c2e0b3386ac6ca',
|
|
1633
|
-
vout: 1
|
|
1634
|
-
}
|
|
1635
|
-
]
|
|
1636
|
-
|
|
1637
|
-
sandbox.stub(uut.Utils, 'decodeOpReturn').rejects({
|
|
1638
|
-
error:
|
|
1639
|
-
'Too many requests. Your limits are currently 3 requests per minute. Increase rate limits at https://fullstack.cash'
|
|
1640
|
-
})
|
|
1641
|
-
|
|
1642
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1643
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
1644
|
-
|
|
1645
|
-
// Values should be 'null' to signal that a determination could not be made
|
|
1646
|
-
// due to a throttling issue.
|
|
1647
|
-
assert.equal(data[0].isValid, null)
|
|
1648
|
-
assert.equal(data[1].isValid, null)
|
|
1649
|
-
})
|
|
1650
|
-
|
|
1651
|
-
// it("should handle a dust attack", async () => {
|
|
1652
|
-
it('should handle dust attack UTXOs', async () => {
|
|
1653
|
-
// Mock external dependencies.
|
|
1654
|
-
// Stub the calls to decodeOpReturn.
|
|
1655
|
-
sandbox
|
|
1656
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
1657
|
-
.rejects(new Error('lokad id wrong size'))
|
|
1658
|
-
|
|
1659
|
-
const utxos = [
|
|
1660
|
-
{
|
|
1661
|
-
height: 655965,
|
|
1662
|
-
tx_hash:
|
|
1663
|
-
'a675af87dcd8d39be782737aa52e0076b52eb2f5ce355ffcb5567a64dd96b77e',
|
|
1664
|
-
tx_pos: 151,
|
|
1665
|
-
value: 547,
|
|
1666
|
-
satoshis: 547,
|
|
1667
|
-
txid:
|
|
1668
|
-
'a675af87dcd8d39be782737aa52e0076b52eb2f5ce355ffcb5567a64dd96b77e',
|
|
1669
|
-
vout: 151,
|
|
1670
|
-
address: 'bitcoincash:qq4dw3sm8qvglspy6w2qg0u2ugsy9zcfcqrpeflwww',
|
|
1671
|
-
hdIndex: 11
|
|
1672
|
-
}
|
|
1673
|
-
]
|
|
1674
|
-
|
|
1675
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1676
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
1677
|
-
|
|
1678
|
-
assert.equal(data[0].isValid, false)
|
|
1679
|
-
})
|
|
1680
|
-
|
|
1681
|
-
it('should invalidate a malformed SLP OP_RETURN', async () => {
|
|
1682
|
-
sandbox
|
|
1683
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
1684
|
-
.rejects(new Error('trailing data'))
|
|
1685
|
-
|
|
1686
|
-
const utxos = [
|
|
1687
|
-
// Malformed SLP tx
|
|
1688
|
-
{
|
|
1689
|
-
note: 'Malformed SLP tx',
|
|
1690
|
-
tx_hash:
|
|
1691
|
-
'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a',
|
|
1692
|
-
tx_pos: 1,
|
|
1693
|
-
value: 546
|
|
1694
|
-
}
|
|
1695
|
-
]
|
|
1696
|
-
|
|
1697
|
-
const data = await uut.Utils.tokenUtxoDetails(utxos)
|
|
1698
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
1699
|
-
|
|
1700
|
-
assert.equal(data[0].isValid, false)
|
|
1701
|
-
})
|
|
1702
|
-
})
|
|
1703
322
|
})
|