@bsv/wallet-toolbox 1.1.0 → 1.1.1

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.
@@ -3,27 +3,38 @@ import { sdk, StorageProvider } from '../../../src/index.client'
3
3
  import {
4
4
  _tu,
5
5
  expectToThrowWERR,
6
+ hexStringToNumberArray,
6
7
  MockData,
7
8
  TestSetup2,
8
9
  TestWalletNoSetup
9
10
  } from '../../utils/TestUtilsWalletStorage'
10
11
 
11
- describe('listActions2 tests', () => {
12
+ const testName = 'listActions'
13
+
14
+ describe('listActions single action tests', () => {
12
15
  jest.setTimeout(99999999)
13
16
 
14
- const storages: StorageProvider[] = []
15
- const chain: sdk.Chain = 'test'
16
- const setups: { setup: TestSetup2; storage: StorageProvider }[] = []
17
+ let ctxs: TestWalletNoSetup[] = []
18
+ let setups: { setup: TestSetup2; storage: StorageProvider }[] = []
17
19
 
18
20
  const env = _tu.getEnv('test')
19
- const ctxs: TestWalletNoSetup[] = []
20
- const testName = () => expect.getState().currentTestName || 'test'
21
21
 
22
- beforeAll(async () => {
22
+ beforeEach(async () => {
23
+ setups = []
24
+ ctxs = []
25
+
26
+ await Promise.all(
27
+ ctxs.map(async ctx => {
28
+ await ctx.storage.destroy()
29
+ })
30
+ )
31
+ ctxs = []
32
+
23
33
  if (env.runMySQL) {
24
- ctxs.push(await _tu.createLegacyWalletMySQLCopy(testName()))
34
+ ctxs.push(await _tu.createLegacyWalletMySQLCopy(testName))
25
35
  }
26
- ctxs.push(await _tu.createLegacyWalletSQLiteCopy(testName()))
36
+ ctxs.push(await _tu.createLegacyWalletSQLiteCopy(testName))
37
+
27
38
  const mockData: MockData = {
28
39
  actions: [
29
40
  {
@@ -34,9 +45,10 @@ describe('listActions2 tests', () => {
34
45
  description: 'Transaction',
35
46
  version: 1,
36
47
  lockTime: 0,
48
+ labels: ['label', 'label2'],
37
49
  inputs: [
38
50
  {
39
- sourceOutpoint: '0',
51
+ sourceOutpoint: 'tx.0',
40
52
  sourceSatoshis: 1,
41
53
  sourceLockingScript: '0123456789abcdef',
42
54
  unlockingScript: '0123456789abcdef',
@@ -44,13 +56,12 @@ describe('listActions2 tests', () => {
44
56
  sequenceNumber: 0
45
57
  }
46
58
  ],
47
- labels: ['label', 'label2'],
48
59
  outputs: [
49
60
  {
50
61
  satoshis: 1,
51
62
  spendable: false,
52
- tags: ['tag'],
53
- outputIndex: 0,
63
+ tags: ['tag', 'tag2'],
64
+ outputIndex: 2,
54
65
  outputDescription: 'description',
55
66
  basket: 'basket',
56
67
  lockingScript: '0123456789abcdef'
@@ -59,6 +70,7 @@ describe('listActions2 tests', () => {
59
70
  }
60
71
  ]
61
72
  }
73
+
62
74
  for (const ctx of ctxs) {
63
75
  const { activeStorage } = ctx
64
76
  await activeStorage.dropAllData()
@@ -67,15 +79,17 @@ describe('listActions2 tests', () => {
67
79
  expect(setups).toBeTruthy()
68
80
 
69
81
  for (const { activeStorage: storage, identityKey } of ctxs) {
70
- // Setup test environment with mock data
71
82
  await _tu.createTestSetup2(storage, identityKey, mockData)
72
83
  }
73
84
  })
74
85
 
75
- afterAll(async () => {
76
- for (const ctx of ctxs) {
77
- await ctx.storage.destroy()
78
- }
86
+ afterEach(async () => {
87
+ await Promise.all(
88
+ ctxs.map(async ctx => {
89
+ await ctx.storage.destroy()
90
+ })
91
+ )
92
+ ctxs = []
79
93
  })
80
94
 
81
95
  test('12_no labels default any', async () => {
@@ -543,19 +557,884 @@ describe('listActions2 tests', () => {
543
557
  expect(await wallet.listActions(args)).toEqual(expectedResult)
544
558
  }
545
559
  })
560
+
561
+ test(`43_inputs requested`, async () => {
562
+ for (const { activeStorage: storage, wallet } of ctxs) {
563
+ await storage.updateTxLabel(1, { label: 'label' })
564
+ await storage.updateTxLabel(2, { label: 'label2' })
565
+ const args: bsv.ListActionsArgs = {
566
+ labels: ['label2'],
567
+ includeInputs: true
568
+ }
569
+
570
+ const expectedResult = JSON.parse(
571
+ '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","inputs":[{"inputDescription":"description","sequenceNumber":0,"sourceOutpoint":"tx.0","sourceSatoshis":1}],"isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}'
572
+ )
573
+
574
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
575
+ }
576
+ })
577
+
578
+ test(`44_inputs not requested`, async () => {
579
+ for (const { activeStorage: storage, wallet } of ctxs) {
580
+ await storage.updateTxLabel(1, { label: 'label' })
581
+ await storage.updateTxLabel(2, { label: 'label2' })
582
+ const args: bsv.ListActionsArgs = {
583
+ labels: ['label2'],
584
+ includeInputs: false
585
+ }
586
+
587
+ const expectedResult = JSON.parse(
588
+ '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}'
589
+ )
590
+
591
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
592
+ }
593
+ })
594
+
595
+ test(`45_inputs requested locking script`, async () => {
596
+ for (const { activeStorage: storage, wallet } of ctxs) {
597
+ await storage.updateTxLabel(1, { label: 'label' })
598
+ await storage.updateTxLabel(2, { label: 'label2' })
599
+ const args: bsv.ListActionsArgs = {
600
+ labels: ['label2'],
601
+ includeInputs: true,
602
+ includeInputSourceLockingScripts: true
603
+ }
604
+
605
+ const expectedResult = JSON.parse(
606
+ '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","inputs":[{"inputDescription":"description","sequenceNumber":0,"sourceLockingScript":"0123456789abcdef","sourceOutpoint":"tx.0","sourceSatoshis":1}],"isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}'
607
+ )
608
+
609
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
610
+ }
611
+ })
612
+
613
+ test(`46_inputs no locking script`, async () => {
614
+ for (const { activeStorage: storage, wallet } of ctxs) {
615
+ await storage.updateTxLabel(1, { label: 'label' })
616
+ await storage.updateTxLabel(2, { label: 'label2' })
617
+ const args: bsv.ListActionsArgs = {
618
+ labels: ['label2'],
619
+ includeInputs: true,
620
+ includeInputSourceLockingScripts: false
621
+ }
622
+
623
+ const expectedResult = JSON.parse(
624
+ '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","inputs":[{"inputDescription":"description","sequenceNumber":0,"sourceOutpoint":"tx.0","sourceSatoshis":1}],"isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}'
625
+ )
626
+
627
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
628
+ }
629
+ })
630
+
631
+ test(`47_inputs empty locking script`, async () => {
632
+ for (const { activeStorage: storage, wallet } of ctxs) {
633
+ await storage.updateTxLabel(1, { label: 'label' })
634
+ await storage.updateTxLabel(2, { label: 'label2' })
635
+ await storage.updateOutput(1, { lockingScript: [] })
636
+ const args: bsv.ListActionsArgs = {
637
+ labels: ['label2'],
638
+ includeInputs: true,
639
+ includeInputSourceLockingScripts: true
640
+ }
641
+
642
+ const expectedResult = JSON.parse(
643
+ '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","inputs":[{"inputDescription":"description","sequenceNumber":0,"sourceLockingScript":"","sourceOutpoint":"tx.0","sourceSatoshis":1}],"isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}'
644
+ )
645
+
646
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
647
+ }
648
+ })
649
+
650
+ // This requires genuine rawTx
651
+ // test(`48_inputs request unlocking script`, async () => {
652
+ // for (const { activeStorage: storage, wallet } of ctxs) {
653
+ // await storage.updateTxLabel(1, { label: 'label' })
654
+ // await storage.updateTxLabel(2, { label: 'label2' })
655
+ // await storage.updateOutput(1, {
656
+ // lockingScript: hexStringToNumberArray(
657
+ // '76a91489abcdefabbaabbaabbaabbaabbaabbaabbaabba88ac'
658
+ // )
659
+ // })
660
+ // const args: bsv.ListActionsArgs = {
661
+ // labels: ['label2'],
662
+ // includeInputs: true,
663
+ // includeInputSourceLockingScripts: true,
664
+ // includeInputUnlockingScripts: true
665
+ // }
666
+
667
+ // const expectedResult = JSON.parse(
668
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","inputs":[{"inputDescription":"description","sequenceNumber":0,"unlockingScript":"47304402207f2e9a6a6d8a5cf3f9d54b4e5fdfbb7a9c75c7e7a22be59d202c4baf1681c6140220219b1c07338fdfc60e949d0b426ce7b8f95de7a9d2e78f587db13fa7a6eb582301 0411db93e1dcdb8a016b49840f8c53bc1eb68a382fd70c81b7c4eeb4c1aab0eedda7e4a3c88ad097448a687ea1f90337e62c23f8cbb4cd7a7b20c54d7e0ceda220","sourceOutpoint":"tx.0","sourceSatoshis":1}],"isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}'
669
+ // )
670
+
671
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
672
+ // }
673
+ // })
674
+
675
+ test(`49_outputs requested`, async () => {
676
+ for (const { activeStorage: storage, wallet } of ctxs) {
677
+ await storage.updateTxLabel(1, { label: 'label' })
678
+ await storage.updateTxLabel(2, { label: 'label2' })
679
+ await storage.updateOutputBasket(1, { name: 'new basket' })
680
+ await storage.updateOutput(2, {
681
+ satoshis: 1,
682
+ spendable: false,
683
+ vout: 2,
684
+ outputDescription: 'new description',
685
+ basketId: 1
686
+ })
687
+ await storage.updateOutputTag(2, { tag: 'new tag' })
688
+ await storage.updateOutputTagMap(1, 2, {})
689
+
690
+ const args: bsv.ListActionsArgs = {
691
+ labels: ['label2'],
692
+ includeOutputs: true
693
+ }
694
+
695
+ const expectedResult = JSON.parse(
696
+ '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
697
+ )
698
+
699
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
700
+ }
701
+ })
702
+
703
+ test(`50_outputs requested`, async () => {
704
+ for (const { activeStorage: storage, wallet } of ctxs) {
705
+ await storage.updateTxLabel(1, { label: 'label' })
706
+ await storage.updateTxLabel(2, { label: 'label2' })
707
+ await storage.updateOutputBasket(1, { name: 'new basket' })
708
+ await storage.updateOutput(2, {
709
+ satoshis: 1,
710
+ spendable: false,
711
+ vout: 2,
712
+ outputDescription: 'new description',
713
+ basketId: 1
714
+ })
715
+ await storage.updateOutputTag(2, { tag: 'new tag' })
716
+ await storage.updateOutputTagMap(1, 2, {})
717
+
718
+ const args: bsv.ListActionsArgs = {
719
+ labels: ['label2'],
720
+ includeOutputs: false
721
+ }
722
+
723
+ const expectedResult = JSON.parse(
724
+ '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}'
725
+ )
726
+
727
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
728
+ }
729
+ })
730
+
731
+ // Cannot empty outputs at storage level
732
+ // test(`51_outputs empty requested`, async () => {
733
+ // for (const { activeStorage: storage, wallet } of ctxs) {
734
+ // await storage.updateTxLabel(1, { label: 'label' })
735
+ // await storage.updateTxLabel(2, { label: 'label2' })
736
+ // await storage.updateOutputBasket(1, { name: 'new basket' })
737
+ // await storage.updateOutput(2, {})
738
+ // await storage.updateOutputTag(2, { tag: 'new tag' })
739
+ // await storage.updateOutputTagMap(1, 2, {})
740
+
741
+ // const args: bsv.ListActionsArgs = {
742
+ // labels: ['label2'],
743
+ // includeOutputs: true
744
+ // }
745
+
746
+ // const expectedResult = JSON.parse(
747
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[]}]}'
748
+ // )
749
+
750
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
751
+ // }
752
+ // })
753
+
754
+ test(`52_outputs locking script requested`, async () => {
755
+ for (const { activeStorage: storage, wallet } of ctxs) {
756
+ await storage.updateTxLabel(1, { label: 'label' })
757
+ await storage.updateTxLabel(2, { label: 'label2' })
758
+ await storage.updateOutputBasket(1, { name: 'new basket' })
759
+ await storage.updateOutput(2, {
760
+ satoshis: 1,
761
+ spendable: false,
762
+ vout: 2,
763
+ outputDescription: 'new description',
764
+ basketId: 1,
765
+ lockingScript: hexStringToNumberArray('0123456789abcdef')
766
+ })
767
+ await storage.updateOutputTag(2, { tag: 'new tag' })
768
+ await storage.updateOutputTagMap(1, 2, {})
769
+
770
+ const args: bsv.ListActionsArgs = {
771
+ labels: ['label2'],
772
+ includeOutputs: true,
773
+ includeOutputLockingScripts: true
774
+ }
775
+
776
+ const expectedResult = JSON.parse(
777
+ '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"lockingScript":"0123456789abcdef","tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
778
+ )
779
+
780
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
781
+ }
782
+ })
783
+
784
+ test(`53_outputs locking script not requested`, async () => {
785
+ for (const { activeStorage: storage, wallet } of ctxs) {
786
+ await storage.updateTxLabel(1, { label: 'label' })
787
+ await storage.updateTxLabel(2, { label: 'label2' })
788
+ await storage.updateOutputBasket(1, { name: 'new basket' })
789
+ await storage.updateOutput(2, {
790
+ satoshis: 1,
791
+ spendable: false,
792
+ vout: 2,
793
+ outputDescription: 'new description',
794
+ basketId: 1,
795
+ lockingScript: hexStringToNumberArray('0123456789abcdef')
796
+ })
797
+ await storage.updateOutputTag(2, { tag: 'new tag' })
798
+ await storage.updateOutputTagMap(1, 2, {})
799
+
800
+ const args: bsv.ListActionsArgs = {
801
+ labels: ['label2'],
802
+ includeOutputs: true,
803
+ includeOutputLockingScripts: false
804
+ }
805
+
806
+ const expectedResult = JSON.parse(
807
+ '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
808
+ )
809
+
810
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
811
+ }
812
+ })
813
+
814
+ test(`54_outputs locking script undefined`, async () => {
815
+ for (const { activeStorage: storage, wallet } of ctxs) {
816
+ await storage.updateTxLabel(1, { label: 'label' })
817
+ await storage.updateTxLabel(2, { label: 'label2' })
818
+ await storage.updateOutputBasket(1, { name: 'new basket' })
819
+ await storage.updateOutput(2, {
820
+ satoshis: 1,
821
+ spendable: false,
822
+ vout: 2,
823
+ outputDescription: 'new description',
824
+ basketId: 1,
825
+ lockingScript: undefined
826
+ })
827
+ await storage.updateOutputTag(2, { tag: 'new tag' })
828
+ await storage.updateOutputTagMap(1, 2, {})
829
+
830
+ const args: bsv.ListActionsArgs = {
831
+ labels: ['label2'],
832
+ includeOutputs: true,
833
+ includeOutputLockingScripts: false
834
+ }
835
+
836
+ const expectedResult = JSON.parse(
837
+ '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
838
+ )
839
+
840
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
841
+ }
842
+ })
843
+
844
+ //TBD requires many mock actions to be performed
845
+ // test(`55_limit is default`, async () => {
846
+ // for (const { activeStorage: storage, wallet } of ctxs) {
847
+ // await storage.updateTxLabel(1, { label: 'label' })
848
+ // await storage.updateTxLabel(2, { label: 'label2' })
849
+ // await storage.updateOutputBasket(1, { name: 'new basket' })
850
+ // await storage.updateOutput(2, {
851
+ // satoshis: 1,
852
+ // spendable: false,
853
+ // vout: 2,
854
+ // outputDescription: 'new description',
855
+ // basketId: 1,
856
+ // lockingScript: undefined
857
+ // })
858
+ // await storage.updateOutputTag(2, { tag: 'new tag' })
859
+ // await storage.updateOutputTagMap(1, 2, {})
860
+
861
+ // const args: bsv.ListActionsArgs = {
862
+ // labels: ['label2'],
863
+ // includeOutputs: true,
864
+ // includeOutputLockingScripts: false
865
+ // }
866
+
867
+ // const expectedResult = JSON.parse(
868
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
869
+ // )
870
+
871
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
872
+ // }
873
+ // })
874
+
875
+ // test(`56_limit 1`, async () => {
876
+ // for (const { activeStorage: storage, wallet } of ctxs) {
877
+ // await storage.updateTxLabel(1, { label: 'label' })
878
+ // await storage.updateTxLabel(2, { label: 'label2' })
879
+ // await storage.updateOutputBasket(1, { name: 'new basket' })
880
+ // await storage.updateOutput(2, {
881
+ // satoshis: 1,
882
+ // spendable: false,
883
+ // vout: 2,
884
+ // outputDescription: 'new description',
885
+ // basketId: 1,
886
+ // lockingScript: undefined
887
+ // })
888
+ // await storage.updateOutputTag(2, { tag: 'new tag' })
889
+ // await storage.updateOutputTagMap(1, 2, {})
890
+
891
+ // const args: bsv.ListActionsArgs = {
892
+ // labels: ['label2'],
893
+ // includeOutputs: true,
894
+ // includeOutputLockingScripts: false
895
+ // }
896
+
897
+ // const expectedResult = JSON.parse(
898
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
899
+ // )
900
+
901
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
902
+ // }
903
+ // })
904
+
905
+ test('57_limit 0', async () => {
906
+ for (const { wallet } of ctxs) {
907
+ const args: bsv.ListActionsArgs = {
908
+ labels: ['label'],
909
+ limit: 0
910
+ }
911
+
912
+ await expectToThrowWERR(
913
+ sdk.WERR_INVALID_PARAMETER,
914
+ async () => await wallet.listActions(args)
915
+ )
916
+ }
917
+ })
918
+
919
+ test('58_limit 10001', async () => {
920
+ for (const { wallet } of ctxs) {
921
+ const args: bsv.ListActionsArgs = {
922
+ labels: ['label'],
923
+ limit: 10001
924
+ }
925
+
926
+ await expectToThrowWERR(
927
+ sdk.WERR_INVALID_PARAMETER,
928
+ async () => await wallet.listActions(args)
929
+ )
930
+ }
931
+ })
932
+
933
+ // TBD requires many mock actions to be performed
934
+ // test(`59_offset less than number of actions`, async () => {
935
+ // for (const { activeStorage: storage, wallet } of ctxs) {
936
+ // await storage.updateTxLabel(1, { label: 'label' })
937
+ // await storage.updateTxLabel(2, { label: 'label2' })
938
+ // await storage.updateOutputBasket(1, { name: 'new basket' })
939
+ // await storage.updateOutput(2, {
940
+ // satoshis: 1,
941
+ // spendable: false,
942
+ // vout: 2,
943
+ // outputDescription: 'new description',
944
+ // basketId: 1,
945
+ // lockingScript: undefined
946
+ // })
947
+ // await storage.updateOutputTag(2, { tag: 'new tag' })
948
+ // await storage.updateOutputTagMap(1, 2, {})
949
+
950
+ // const args: bsv.ListActionsArgs = {
951
+ // labels: ['label2'],
952
+ // includeOutputs: true,
953
+ // includeOutputLockingScripts: false
954
+ // }
955
+
956
+ // const expectedResult = JSON.parse(
957
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
958
+ // )
959
+
960
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
961
+ // }
962
+ // })
963
+
964
+ // test(`60_offset equal to number of actions`, async () => {
965
+ // for (const { activeStorage: storage, wallet } of ctxs) {
966
+ // await storage.updateTxLabel(1, { label: 'label' })
967
+ // await storage.updateTxLabel(2, { label: 'label2' })
968
+ // await storage.updateOutputBasket(1, { name: 'new basket' })
969
+ // await storage.updateOutput(2, {
970
+ // satoshis: 1,
971
+ // spendable: false,
972
+ // vout: 2,
973
+ // outputDescription: 'new description',
974
+ // basketId: 1,
975
+ // lockingScript: undefined
976
+ // })
977
+ // await storage.updateOutputTag(2, { tag: 'new tag' })
978
+ // await storage.updateOutputTagMap(1, 2, {})
979
+
980
+ // const args: bsv.ListActionsArgs = {
981
+ // labels: ['label2'],
982
+ // includeOutputs: true,
983
+ // includeOutputLockingScripts: false
984
+ // }
985
+
986
+ // const expectedResult = JSON.parse(
987
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
988
+ // )
989
+
990
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
991
+ // }
992
+ // })
993
+
994
+ // test(`61_offset above number of actions`, async () => {
995
+ // for (const { activeStorage: storage, wallet } of ctxs) {
996
+ // await storage.updateTxLabel(1, { label: 'label' })
997
+ // await storage.updateTxLabel(2, { label: 'label2' })
998
+ // await storage.updateOutputBasket(1, { name: 'new basket' })
999
+ // await storage.updateOutput(2, {
1000
+ // satoshis: 1,
1001
+ // spendable: false,
1002
+ // vout: 2,
1003
+ // outputDescription: 'new description',
1004
+ // basketId: 1,
1005
+ // lockingScript: undefined
1006
+ // })
1007
+ // await storage.updateOutputTag(2, { tag: 'new tag' })
1008
+ // await storage.updateOutputTagMap(1, 2, {})
1009
+
1010
+ // const args: bsv.ListActionsArgs = {
1011
+ // labels: ['label2'],
1012
+ // includeOutputs: true,
1013
+ // includeOutputLockingScripts: false
1014
+ // }
1015
+
1016
+ // const expectedResult = JSON.parse(
1017
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
1018
+ // )
1019
+
1020
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
1021
+ // }
1022
+ // })
1023
+
1024
+ test('62_offset is invalid', async () => {
1025
+ for (const { wallet } of ctxs) {
1026
+ const args: bsv.ListActionsArgs = {
1027
+ labels: ['label'],
1028
+ offset: -1
1029
+ }
1030
+
1031
+ await expectToThrowWERR(
1032
+ sdk.WERR_INVALID_PARAMETER,
1033
+ async () => await wallet.listActions(args)
1034
+ )
1035
+ }
1036
+ })
1037
+
1038
+ //TBD requires many mock actions to be performed
1039
+ // test(`63_offset below limit with same number of actions`, async () => {
1040
+ // for (const { activeStorage: storage, wallet } of ctxs) {
1041
+ // await storage.updateTxLabel(1, { label: 'label' })
1042
+ // await storage.updateTxLabel(2, { label: 'label2' })
1043
+ // await storage.updateOutputBasket(1, { name: 'new basket' })
1044
+ // await storage.updateOutput(2, {
1045
+ // satoshis: 1,
1046
+ // spendable: false,
1047
+ // vout: 2,
1048
+ // outputDescription: 'new description',
1049
+ // basketId: 1,
1050
+ // lockingScript: undefined
1051
+ // })
1052
+ // await storage.updateOutputTag(2, { tag: 'new tag' })
1053
+ // await storage.updateOutputTagMap(1, 2, {})
1054
+
1055
+ // const args: bsv.ListActionsArgs = {
1056
+ // labels: ['label2'],
1057
+ // includeOutputs: true,
1058
+ // includeOutputLockingScripts: false
1059
+ // }
1060
+
1061
+ // const expectedResult = JSON.parse(
1062
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
1063
+ // )
1064
+
1065
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
1066
+ // }
1067
+ // })
1068
+
1069
+ // test(`64_offset below limit greater than number of actions`, async () => {
1070
+ // for (const { activeStorage: storage, wallet } of ctxs) {
1071
+ // await storage.updateTxLabel(1, { label: 'label' })
1072
+ // await storage.updateTxLabel(2, { label: 'label2' })
1073
+ // await storage.updateOutputBasket(1, { name: 'new basket' })
1074
+ // await storage.updateOutput(2, {
1075
+ // satoshis: 1,
1076
+ // spendable: false,
1077
+ // vout: 2,
1078
+ // outputDescription: 'new description',
1079
+ // basketId: 1,
1080
+ // lockingScript: undefined
1081
+ // })
1082
+ // await storage.updateOutputTag(2, { tag: 'new tag' })
1083
+ // await storage.updateOutputTagMap(1, 2, {})
1084
+
1085
+ // const args: bsv.ListActionsArgs = {
1086
+ // labels: ['label2'],
1087
+ // includeOutputs: true,
1088
+ // includeOutputLockingScripts: false
1089
+ // }
1090
+
1091
+ // const expectedResult = JSON.parse(
1092
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
1093
+ // )
1094
+
1095
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
1096
+ // }
1097
+ // })
1098
+
1099
+ // test(`65_offset skips all actions with limit set`, async () => {
1100
+ // for (const { activeStorage: storage, wallet } of ctxs) {
1101
+ // await storage.updateTxLabel(1, { label: 'label' })
1102
+ // await storage.updateTxLabel(2, { label: 'label2' })
1103
+ // await storage.updateOutputBasket(1, { name: 'new basket' })
1104
+ // await storage.updateOutput(2, {
1105
+ // satoshis: 1,
1106
+ // spendable: false,
1107
+ // vout: 2,
1108
+ // outputDescription: 'new description',
1109
+ // basketId: 1,
1110
+ // lockingScript: undefined
1111
+ // })
1112
+ // await storage.updateOutputTag(2, { tag: 'new tag' })
1113
+ // await storage.updateOutputTagMap(1, 2, {})
1114
+
1115
+ // const args: bsv.ListActionsArgs = {
1116
+ // labels: ['label2'],
1117
+ // includeOutputs: true,
1118
+ // includeOutputLockingScripts: false
1119
+ // }
1120
+
1121
+ // const expectedResult = JSON.parse(
1122
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
1123
+ // )
1124
+
1125
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
1126
+ // }
1127
+ // })
1128
+
1129
+ // test(`66_limit exceeds remaining actions after offset`, async () => {
1130
+ // for (const { activeStorage: storage, wallet } of ctxs) {
1131
+ // await storage.updateTxLabel(1, { label: 'label' })
1132
+ // await storage.updateTxLabel(2, { label: 'label2' })
1133
+ // await storage.updateOutputBasket(1, { name: 'new basket' })
1134
+ // await storage.updateOutput(2, {
1135
+ // satoshis: 1,
1136
+ // spendable: false,
1137
+ // vout: 2,
1138
+ // outputDescription: 'new description',
1139
+ // basketId: 1,
1140
+ // lockingScript: undefined
1141
+ // })
1142
+ // await storage.updateOutputTag(2, { tag: 'new tag' })
1143
+ // await storage.updateOutputTagMap(1, 2, {})
1144
+
1145
+ // const args: bsv.ListActionsArgs = {
1146
+ // labels: ['label2'],
1147
+ // includeOutputs: true,
1148
+ // includeOutputLockingScripts: false
1149
+ // }
1150
+
1151
+ // const expectedResult = JSON.parse(
1152
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
1153
+ // )
1154
+
1155
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
1156
+ // }
1157
+ // })
1158
+
1159
+ // test(`67_limit exceeds remaining actions after offset`, async () => {
1160
+ // for (const { activeStorage: storage, wallet } of ctxs) {
1161
+ // await storage.updateTxLabel(1, { label: 'label' })
1162
+ // await storage.updateTxLabel(2, { label: 'label2' })
1163
+ // await storage.updateOutputBasket(1, { name: 'new basket' })
1164
+ // await storage.updateOutput(2, {
1165
+ // satoshis: 1,
1166
+ // spendable: false,
1167
+ // vout: 2,
1168
+ // outputDescription: 'new description',
1169
+ // basketId: 1,
1170
+ // lockingScript: undefined
1171
+ // })
1172
+ // await storage.updateOutputTag(2, { tag: 'new tag' })
1173
+ // await storage.updateOutputTagMap(1, 2, {})
1174
+
1175
+ // const args: bsv.ListActionsArgs = {
1176
+ // labels: ['label2'],
1177
+ // includeOutputs: true,
1178
+ // includeOutputLockingScripts: false
1179
+ // }
1180
+
1181
+ // const expectedResult = JSON.parse(
1182
+ // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}'
1183
+ // )
1184
+
1185
+ // expect(await wallet.listActions(args)).toEqual(expectedResult)
1186
+ // }
1187
+ // })
1188
+ })
1189
+
1190
+ describe('listActions two action tests', () => {
1191
+ jest.setTimeout(99999999)
1192
+
1193
+ let ctxs: TestWalletNoSetup[] = []
1194
+ let setups: { setup: TestSetup2; storage: StorageProvider }[] = []
1195
+
1196
+ const env = _tu.getEnv('test')
1197
+
1198
+ beforeEach(async () => {
1199
+ setups = []
1200
+ ctxs = []
1201
+
1202
+ await Promise.all(
1203
+ ctxs.map(async ctx => {
1204
+ await ctx.storage.destroy()
1205
+ })
1206
+ )
1207
+ ctxs = []
1208
+
1209
+ if (env.runMySQL) {
1210
+ ctxs.push(await _tu.createLegacyWalletMySQLCopy(testName))
1211
+ }
1212
+ ctxs.push(await _tu.createLegacyWalletSQLiteCopy(testName))
1213
+
1214
+ const mockData: MockData = {
1215
+ actions: [
1216
+ {
1217
+ txid: 'tx1',
1218
+ satoshis: 1,
1219
+ status: 'completed',
1220
+ isOutgoing: true,
1221
+ description: 'Transaction 1',
1222
+ version: 1,
1223
+ lockTime: 0,
1224
+ labels: ['label 1', 'label a'],
1225
+ inputs: [
1226
+ {
1227
+ sourceOutpoint: 'tx1.1',
1228
+ sourceSatoshis: 1,
1229
+ //sourceLockingScript: '0123456789abcdef',
1230
+ //unlockingScript: '0123456789abcdef',
1231
+ inputDescription: 'description 1',
1232
+ sequenceNumber: 1
1233
+ }
1234
+ ],
1235
+ outputs: [
1236
+ {
1237
+ satoshis: 1,
1238
+ spendable: false,
1239
+ tags: ['tag1'],
1240
+ outputIndex: 1,
1241
+ outputDescription: 'description 1',
1242
+ basket: 'basket'
1243
+ //lockingScript: '0123456789abcdef'
1244
+ }
1245
+ ]
1246
+ },
1247
+ {
1248
+ txid: 'tx2',
1249
+ satoshis: 2,
1250
+ status: 'completed',
1251
+ isOutgoing: true,
1252
+ description: 'Transaction 2',
1253
+ version: 1,
1254
+ lockTime: 0,
1255
+ labels: ['label2', 'label b'],
1256
+ inputs: [
1257
+ {
1258
+ sourceOutpoint: 'tx2.2',
1259
+ sourceSatoshis: 2,
1260
+ //sourceLockingScript: '0123456789abcdef',
1261
+ //unlockingScript: '0123456789abcdef',
1262
+ inputDescription: 'description 2',
1263
+ sequenceNumber: 2
1264
+ }
1265
+ ],
1266
+ outputs: [
1267
+ {
1268
+ satoshis: 2,
1269
+ spendable: false,
1270
+ tags: ['tag2'],
1271
+ outputIndex: 2,
1272
+ outputDescription: 'description 2',
1273
+ basket: 'basket 2'
1274
+ //lockingScript: '0123456789abcdef'
1275
+ }
1276
+ ]
1277
+ }
1278
+ ]
1279
+ }
1280
+ for (const ctx of ctxs) {
1281
+ const { activeStorage } = ctx
1282
+ await activeStorage.dropAllData()
1283
+ await activeStorage.migrate('insert tests', '3'.repeat(64))
1284
+ }
1285
+ expect(setups).toBeTruthy()
1286
+
1287
+ for (const { activeStorage: storage, identityKey } of ctxs) {
1288
+ await _tu.createTestSetup2(storage, identityKey, mockData)
1289
+ }
1290
+ })
1291
+
1292
+ afterEach(async () => {
1293
+ await Promise.all(
1294
+ ctxs.map(async ctx => {
1295
+ await ctx.storage.destroy()
1296
+ })
1297
+ )
1298
+ ctxs = []
1299
+ })
1300
+
1301
+ test('100_no labels (default) matched default any', async () => {
1302
+ for (const { wallet } of ctxs) {
1303
+ const args: bsv.ListActionsArgs = {
1304
+ labels: []
1305
+ }
1306
+
1307
+ const expectedResult = JSON.parse(
1308
+ '{"totalActions":2,"actions":[{"txid":"tx1","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction 1","version":1,"lockTime":0},{"txid":"tx2","satoshis":2,"status":"completed","isOutgoing":true,"description":"Transaction 2","version":1,"lockTime":0}]}'
1309
+ )
1310
+
1311
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
1312
+ }
1313
+ })
1314
+
1315
+ test('101_label 1 matched default any', async () => {
1316
+ for (const { activeStorage: storage, wallet } of ctxs) {
1317
+ const label = 'label 1'
1318
+ await storage.updateTxLabel(1, { label })
1319
+ await storage.updateTxLabel(2, { label: 'label a' })
1320
+ await storage.updateTxLabel(3, { label: 'label 2' })
1321
+ await storage.updateTxLabel(4, { label: 'label b' })
1322
+ const args: bsv.ListActionsArgs = {
1323
+ labels: [label]
1324
+ }
1325
+
1326
+ const expectedResult = JSON.parse(
1327
+ '{"totalActions":1,"actions":[{"txid":"tx1","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction 1","version":1,"lockTime":0}]}'
1328
+ )
1329
+
1330
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
1331
+ }
1332
+ })
1333
+
1334
+ test('102_label 2 matched default any', async () => {
1335
+ for (const { activeStorage: storage, wallet } of ctxs) {
1336
+ const label = 'label 2'
1337
+ await storage.updateTxLabel(1, { label: 'label 1' })
1338
+ await storage.updateTxLabel(2, { label: 'label a' })
1339
+ await storage.updateTxLabel(3, { label })
1340
+ await storage.updateTxLabel(4, { label: 'label b' })
1341
+ const args: bsv.ListActionsArgs = {
1342
+ labels: [label]
1343
+ }
1344
+
1345
+ const expectedResult = JSON.parse(
1346
+ '{"totalActions":1,"actions":[{"txid":"tx2","satoshis":2,"status":"completed","isOutgoing":true,"description":"Transaction 2","version":1,"lockTime":0}]}'
1347
+ )
1348
+
1349
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
1350
+ }
1351
+ })
1352
+
1353
+ test('103_no label matched default any', async () => {
1354
+ for (const { activeStorage: storage, wallet } of ctxs) {
1355
+ await storage.updateTxLabel(1, { label: 'label 1' })
1356
+ await storage.updateTxLabel(2, { label: 'label a' })
1357
+ await storage.updateTxLabel(3, { label: 'label 2' })
1358
+ await storage.updateTxLabel(4, { label: 'label b' })
1359
+ const args: bsv.ListActionsArgs = {
1360
+ labels: ['label']
1361
+ }
1362
+
1363
+ const expectedResult = JSON.parse('{"totalActions":0,"actions":[]}')
1364
+
1365
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
1366
+ }
1367
+ })
1368
+
1369
+ test('104_both labels matched default any', async () => {
1370
+ for (const { activeStorage: storage, wallet } of ctxs) {
1371
+ await storage.updateTxLabel(1, { label: 'label 1' })
1372
+ await storage.updateTxLabel(2, { label: 'label a' })
1373
+ await storage.updateTxLabel(3, { label: 'label 2' })
1374
+ await storage.updateTxLabel(4, { label: 'label b' })
1375
+ const args: bsv.ListActionsArgs = {
1376
+ labels: ['label 1', 'label 2']
1377
+ }
1378
+
1379
+ const expectedResult = JSON.parse(
1380
+ '{"totalActions":2,"actions":[{"txid":"tx1","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction 1","version":1,"lockTime":0},{"txid":"tx2","satoshis":2,"status":"completed","isOutgoing":true,"description":"Transaction 2","version":1,"lockTime":0}]}'
1381
+ )
1382
+
1383
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
1384
+ }
1385
+ })
1386
+
1387
+ test('105_first label pair matches mode all', async () => {
1388
+ for (const { activeStorage: storage, wallet } of ctxs) {
1389
+ await storage.updateTxLabel(1, { label: 'label 1' })
1390
+ await storage.updateTxLabel(2, { label: 'label a' })
1391
+ await storage.updateTxLabel(3, { label: 'label 2' })
1392
+ await storage.updateTxLabel(4, { label: 'label b' })
1393
+ const args: bsv.ListActionsArgs = {
1394
+ labels: ['label 1', 'label a'],
1395
+ labelQueryMode: 'all'
1396
+ }
1397
+
1398
+ const expectedResult = JSON.parse(
1399
+ '{"totalActions":1,"actions":[{"txid":"tx1","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction 1","version":1,"lockTime":0}]}'
1400
+ )
1401
+
1402
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
1403
+ }
1404
+ })
1405
+
1406
+ test('106_second label pair matches mode all', async () => {
1407
+ for (const { activeStorage: storage, wallet } of ctxs) {
1408
+ await storage.updateTxLabel(1, { label: 'label 1' })
1409
+ await storage.updateTxLabel(2, { label: 'label a' })
1410
+ await storage.updateTxLabel(3, { label: 'label 2' })
1411
+ await storage.updateTxLabel(4, { label: 'label b' })
1412
+ const args: bsv.ListActionsArgs = {
1413
+ labels: ['label 2', 'label b'],
1414
+ labelQueryMode: 'all'
1415
+ }
1416
+
1417
+ const expectedResult = JSON.parse(
1418
+ '{"totalActions":1,"actions":[{"txid":"tx2","satoshis":2,"status":"completed","isOutgoing":true,"description":"Transaction 2","version":1,"lockTime":0}]}'
1419
+ )
1420
+
1421
+ expect(await wallet.listActions(args)).toEqual(expectedResult)
1422
+ }
1423
+ })
546
1424
  })
1425
+
547
1426
  const generateRandomEmojiString = (bytes: number): string => {
548
1427
  const emojiRange = [
549
- '\u{1F600}', // Grinning face
550
- '\u{1F603}', // Smiling face
551
- '\u{1F604}', // Laughing face
552
- '\u{1F609}', // Winking face
553
- '\u{1F60A}', // Blushing face
554
- '\u{1F60D}', // Heart eyes
555
- '\u{1F618}', // Kissing face
556
- '\u{1F61C}', // Tongue out
557
- '\u{1F923}', // Rolling on the floor laughing
558
- '\u{1F44D}' // Thumbs up
1428
+ '\u{1F600}',
1429
+ '\u{1F603}',
1430
+ '\u{1F604}',
1431
+ '\u{1F609}',
1432
+ '\u{1F60A}',
1433
+ '\u{1F60D}',
1434
+ '\u{1F618}',
1435
+ '\u{1F61C}',
1436
+ '\u{1F923}',
1437
+ '\u{1F44D}'
559
1438
  ]
560
1439
 
561
1440
  const bytesPerEmoji = 4 // Each emoji is 4 bytes in UTF-8