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