@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.
@@ -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
  })