@rosen-bridge/bitcoin-scanner 0.1.0-52fc0239

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 (52) hide show
  1. package/.eslintignore +1 -0
  2. package/CHANGELOG.md +11 -0
  3. package/README.md +24 -0
  4. package/dist/index.d.ts +9 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +9 -0
  7. package/dist/network/BitcoinRpcNetwork.d.ts +30 -0
  8. package/dist/network/BitcoinRpcNetwork.d.ts.map +1 -0
  9. package/dist/network/BitcoinRpcNetwork.js +88 -0
  10. package/dist/network/DogeRpcNetwork.d.ts +30 -0
  11. package/dist/network/DogeRpcNetwork.d.ts.map +1 -0
  12. package/dist/network/DogeRpcNetwork.js +88 -0
  13. package/dist/network/EsploraNetwork.d.ts +28 -0
  14. package/dist/network/EsploraNetwork.d.ts.map +1 -0
  15. package/dist/network/EsploraNetwork.js +64 -0
  16. package/dist/scanner/BitcoinEsploraScanner.d.ts +6 -0
  17. package/dist/scanner/BitcoinEsploraScanner.d.ts.map +1 -0
  18. package/dist/scanner/BitcoinEsploraScanner.js +7 -0
  19. package/dist/scanner/BitcoinRpcScanner.d.ts +6 -0
  20. package/dist/scanner/BitcoinRpcScanner.d.ts.map +1 -0
  21. package/dist/scanner/BitcoinRpcScanner.js +7 -0
  22. package/dist/scanner/DogeEsploraScanner.d.ts +6 -0
  23. package/dist/scanner/DogeEsploraScanner.d.ts.map +1 -0
  24. package/dist/scanner/DogeEsploraScanner.js +7 -0
  25. package/dist/scanner/DogeRpcScanner.d.ts +6 -0
  26. package/dist/scanner/DogeRpcScanner.d.ts.map +1 -0
  27. package/dist/scanner/DogeRpcScanner.js +7 -0
  28. package/dist/types.d.ts +142 -0
  29. package/dist/types.d.ts.map +1 -0
  30. package/dist/types.js +2 -0
  31. package/lib/index.ts +8 -0
  32. package/lib/network/BitcoinRpcNetwork.ts +111 -0
  33. package/lib/network/DogeRpcNetwork.ts +112 -0
  34. package/lib/network/EsploraNetwork.ts +92 -0
  35. package/lib/scanner/BitcoinEsploraScanner.ts +15 -0
  36. package/lib/scanner/BitcoinRpcScanner.ts +16 -0
  37. package/lib/scanner/DogeEsploraScanner.ts +15 -0
  38. package/lib/scanner/DogeRpcScanner.ts +16 -0
  39. package/lib/types.ts +155 -0
  40. package/package.json +35 -0
  41. package/tests/bitcoinEsploraTestData.ts +1773 -0
  42. package/tests/bitcoinRpcTestData.ts +305 -0
  43. package/tests/dogeRpcTestData.ts +659 -0
  44. package/tests/mocked/axiosEsplora.mock.ts +28 -0
  45. package/tests/mocked/axiosRpc.mock.ts +28 -0
  46. package/tests/network/BitcoinRpcNetwork.spec.ts +112 -0
  47. package/tests/network/DogeRpcNetwork.spec.ts +111 -0
  48. package/tests/network/EsploraNetwork.spec.ts +106 -0
  49. package/tsconfig.build.json +11 -0
  50. package/tsconfig.build.tsbuildinfo +1 -0
  51. package/tsconfig.json +11 -0
  52. package/vitest.config.ts +18 -0
@@ -0,0 +1,28 @@
1
+ import RateLimitedAxios from '@rosen-bridge/rate-limited-axios';
2
+ import axios from '@rosen-bridge/rate-limited-axios';
3
+ import { vi } from 'vitest';
4
+
5
+ export const axiosInstance = {
6
+ get: vi.fn(),
7
+ post: vi.fn(),
8
+ };
9
+
10
+ /**
11
+ * mocks axios.get function
12
+ * @param result
13
+ */
14
+ export const mockAxiosPost = (result: unknown) => {
15
+ axiosInstance.post.mockResolvedValueOnce({
16
+ data: result,
17
+ });
18
+ };
19
+
20
+ /**
21
+ * resets axios functions mocks and call counts
22
+ */
23
+ export const resetAxiosMock = () => {
24
+ axiosInstance.post.mockReset();
25
+ vi.spyOn(axios, 'create').mockReturnValue(
26
+ axiosInstance as unknown as RateLimitedAxios
27
+ );
28
+ };
@@ -0,0 +1,112 @@
1
+ import {
2
+ axiosInstance,
3
+ mockAxiosPost,
4
+ resetAxiosMock,
5
+ } from '../mocked/axiosRpc.mock';
6
+ import * as testData from '../bitcoinRpcTestData';
7
+ import { BitcoinRpcNetwork } from '../../lib/network/BitcoinRpcNetwork';
8
+
9
+ describe('BitcoinRpcNetwork', () => {
10
+ let network: BitcoinRpcNetwork;
11
+
12
+ beforeEach(() => {
13
+ resetAxiosMock();
14
+ network = new BitcoinRpcNetwork('', 1);
15
+ network['generateRandomId'] = () =>
16
+ '19774cdc6bc663926590dc2fe7bfe77ba57a5343aaa16db5ffc377e95663fd4e';
17
+ });
18
+
19
+ describe('getBlockAtHeight', () => {
20
+ /**
21
+ * @target `BitcoinRpcNetwork.getBlockAtHeight` should return block info successfully
22
+ * @dependencies
23
+ * @scenario
24
+ * - mock axios to return block hash
25
+ * - mock axios to return block header
26
+ * - run test
27
+ * - check returned value
28
+ * - check if function got called
29
+ * @expected
30
+ * - it should be expected block info
31
+ * - axios.post should got called 2 times
32
+ * - to get block hash with mocked block height
33
+ * - to get block header with mocked block hash
34
+ */
35
+ it('should return block info successfully', async () => {
36
+ mockAxiosPost(testData.getBlockHashResponse);
37
+ mockAxiosPost(testData.getBlockHeaderResponse);
38
+
39
+ const result = await network.getBlockAtHeight(testData.blockHeight);
40
+
41
+ expect(result).toEqual(testData.block);
42
+ expect(axiosInstance.post).toHaveBeenCalledTimes(2);
43
+ expect(axiosInstance.post).toHaveBeenCalledWith('', {
44
+ method: 'getblockhash',
45
+ params: [testData.blockHeight],
46
+ id: '19774cdc6bc663926590dc2fe7bfe77ba57a5343aaa16db5ffc377e95663fd4e',
47
+ });
48
+ expect(axiosInstance.post).toHaveBeenCalledWith('', {
49
+ method: 'getblockheader',
50
+ params: [testData.blockHash, true],
51
+ id: '19774cdc6bc663926590dc2fe7bfe77ba57a5343aaa16db5ffc377e95663fd4e',
52
+ });
53
+ });
54
+ });
55
+
56
+ describe('getCurrentHeight', () => {
57
+ /**
58
+ * @target `BitcoinRpcNetwork.getCurrentHeight` should return current height successfully
59
+ * @dependencies
60
+ * @scenario
61
+ * - mock axios to return blockchain info
62
+ * - run test
63
+ * - check returned value
64
+ * - check if function got called
65
+ * @expected
66
+ * - it should be expected height
67
+ * - axios.post should got called once to get chain info with no param
68
+ */
69
+ it('should return current height successfully', async () => {
70
+ mockAxiosPost(testData.getBlockchainInfoResponse);
71
+
72
+ const result = await network.getCurrentHeight();
73
+
74
+ expect(result).toEqual(testData.currentBlockHeight);
75
+ expect(axiosInstance.post).toHaveBeenCalledTimes(1);
76
+ expect(axiosInstance.post).toHaveBeenCalledWith('', {
77
+ method: 'getblockchaininfo',
78
+ params: [],
79
+ id: '19774cdc6bc663926590dc2fe7bfe77ba57a5343aaa16db5ffc377e95663fd4e',
80
+ });
81
+ });
82
+ });
83
+
84
+ describe('getBlockTxs', () => {
85
+ /**
86
+ * @target `BitcoinRpcNetwork.getBlockTxs` should return block transactions successfully
87
+ * @dependencies
88
+ * @scenario
89
+ * - mock axios to return block header
90
+ * - mock axios to return block transactions 3 times (3 pages)
91
+ * - run test
92
+ * - check returned value
93
+ * - check if function got called
94
+ * @expected
95
+ * - it should be expected txs
96
+ * - axios.post should got called once to get block with mocked block hash and verbosity 2
97
+ */
98
+ it('should return block transactions successfully', async () => {
99
+ mockAxiosPost(testData.getBlockResponse);
100
+
101
+ const result = await network.getBlockTxs(testData.blockHash);
102
+
103
+ expect(result).toEqual(testData.getBlockResponse.result.tx);
104
+ expect(axiosInstance.post).toHaveBeenCalledTimes(1);
105
+ expect(axiosInstance.post).toHaveBeenCalledWith('', {
106
+ method: 'getblock',
107
+ params: [testData.blockHash, 2],
108
+ id: '19774cdc6bc663926590dc2fe7bfe77ba57a5343aaa16db5ffc377e95663fd4e',
109
+ });
110
+ });
111
+ });
112
+ });
@@ -0,0 +1,111 @@
1
+ import {
2
+ axiosInstance,
3
+ mockAxiosPost,
4
+ resetAxiosMock,
5
+ } from '../mocked/axiosRpc.mock';
6
+ import * as testData from '../dogeRpcTestData';
7
+ import { DogeRpcNetwork } from '../../lib/network/DogeRpcNetwork';
8
+
9
+ describe('DogeRpcNetwork', () => {
10
+ let network: DogeRpcNetwork;
11
+
12
+ beforeEach(() => {
13
+ resetAxiosMock();
14
+ network = new DogeRpcNetwork('', 1);
15
+ network['generateRandomId'] = () =>
16
+ '19774cdc6bc663926590dc2fe7bfe77ba57a5343aaa16db5ffc377e95663fd4e';
17
+ });
18
+
19
+ describe('getBlockAtHeight', () => {
20
+ /**
21
+ * @target `DogeRpcNetwork.getBlockAtHeight` should return block info successfully
22
+ * @dependencies
23
+ * @scenario
24
+ * - mock axios to return block hash
25
+ * - mock axios to return block header
26
+ * - run test
27
+ * - check returned value
28
+ * - check if function got called
29
+ * @expected
30
+ * - it should be expected block info
31
+ * - axios.post should got called 2 times
32
+ * - to get block hash with mocked block height
33
+ * - to get block header with mocked block hash
34
+ */
35
+ it('should return block info successfully', async () => {
36
+ mockAxiosPost(testData.getBlockHashResponse);
37
+ mockAxiosPost(testData.getBlockSummaryResponse);
38
+
39
+ const result = await network.getBlockAtHeight(testData.blockHeight);
40
+
41
+ expect(result).toEqual(testData.block);
42
+ expect(axiosInstance.post).toHaveBeenCalledTimes(2);
43
+ expect(axiosInstance.post).toHaveBeenCalledWith('', {
44
+ method: 'getblockhash',
45
+ params: [testData.blockHeight],
46
+ id: '19774cdc6bc663926590dc2fe7bfe77ba57a5343aaa16db5ffc377e95663fd4e',
47
+ });
48
+ expect(axiosInstance.post).toHaveBeenCalledWith('', {
49
+ method: 'getblock',
50
+ params: [testData.blockHash, 1],
51
+ id: '19774cdc6bc663926590dc2fe7bfe77ba57a5343aaa16db5ffc377e95663fd4e',
52
+ });
53
+ });
54
+ });
55
+
56
+ describe('getCurrentHeight', () => {
57
+ /**
58
+ * @target `DogeRpcNetwork.getCurrentHeight` should return current height successfully
59
+ * @dependencies
60
+ * @scenario
61
+ * - mock axios to return blockchain info
62
+ * - run test
63
+ * - check returned value
64
+ * - check if function got called
65
+ * @expected
66
+ * - it should be expected height
67
+ * - axios.post should got called once to get chain info with no param
68
+ */
69
+ it('should return current height successfully', async () => {
70
+ mockAxiosPost(testData.getBlockchainInfoResponse);
71
+
72
+ const result = await network.getCurrentHeight();
73
+
74
+ expect(result).toEqual(testData.currentBlockHeight);
75
+ expect(axiosInstance.post).toHaveBeenCalledTimes(1);
76
+ expect(axiosInstance.post).toHaveBeenCalledWith('', {
77
+ method: 'getblockchaininfo',
78
+ params: [],
79
+ id: '19774cdc6bc663926590dc2fe7bfe77ba57a5343aaa16db5ffc377e95663fd4e',
80
+ });
81
+ });
82
+ });
83
+
84
+ describe('getBlockTxs', () => {
85
+ /**
86
+ * @target `DogeRpcNetwork.getBlockTxs` should return block transactions successfully
87
+ * @dependencies
88
+ * @scenario
89
+ * - mock axios to return block with transactions
90
+ * - run test
91
+ * - check returned value
92
+ * - check if function got called
93
+ * @expected
94
+ * - it should be expected txs
95
+ * - axios.post should got called once to get block with mocked block hash and verbosity 2
96
+ */
97
+ it('should return block transactions successfully', async () => {
98
+ mockAxiosPost(testData.getBlockResponse);
99
+
100
+ const result = await network.getBlockTxs(testData.blockHash);
101
+
102
+ expect(result).toEqual(testData.getBlockResponse.result.tx);
103
+ expect(axiosInstance.post).toHaveBeenCalledTimes(1);
104
+ expect(axiosInstance.post).toHaveBeenCalledWith('', {
105
+ method: 'getblock',
106
+ params: [testData.blockHash, 2],
107
+ id: '19774cdc6bc663926590dc2fe7bfe77ba57a5343aaa16db5ffc377e95663fd4e',
108
+ });
109
+ });
110
+ });
111
+ });
@@ -0,0 +1,106 @@
1
+ import {
2
+ axiosInstance,
3
+ mockAxiosGet,
4
+ resetAxiosMock,
5
+ } from '../mocked/axiosEsplora.mock';
6
+ import * as testData from '../bitcoinEsploraTestData';
7
+ import { EsploraNetwork } from '../../lib/network/EsploraNetwork';
8
+
9
+ describe('EsploraNetwork', () => {
10
+ let network: EsploraNetwork;
11
+
12
+ beforeEach(() => {
13
+ resetAxiosMock();
14
+ network = new EsploraNetwork('', 1);
15
+ });
16
+
17
+ describe('getBlockAtHeight', () => {
18
+ /**
19
+ * @target `EsploraNetwork.getBlockAtHeight` should return block info successfully
20
+ * @dependencies
21
+ * @scenario
22
+ * - mock axios to return block hash
23
+ * - mock axios to return block header
24
+ * - run test
25
+ * - check returned value
26
+ * - check if function got called
27
+ * @expected
28
+ * - it should be expected block info
29
+ * - axios.get should got called 2 times
30
+ * - with mocked block height
31
+ * - with mocked block hash
32
+ */
33
+ it('should return block info successfully', async () => {
34
+ mockAxiosGet(testData.blockHash);
35
+ mockAxiosGet(testData.blockResponse);
36
+
37
+ const result = await network.getBlockAtHeight(testData.blockHeight);
38
+
39
+ expect(result).toEqual(testData.block);
40
+ expect(axiosInstance.get).toHaveBeenCalledTimes(2);
41
+ expect(axiosInstance.get).toHaveBeenCalledWith(
42
+ expect.stringContaining(String(testData.blockHeight))
43
+ );
44
+ expect(axiosInstance.get).toHaveBeenCalledWith(
45
+ expect.stringContaining(testData.blockHash)
46
+ );
47
+ });
48
+ });
49
+
50
+ describe('getCurrentHeight', () => {
51
+ /**
52
+ * @target `EsploraNetwork.getCurrentHeight` should return current height successfully
53
+ * @dependencies
54
+ * @scenario
55
+ * - mock axios to return block height
56
+ * - run test
57
+ * - check returned value
58
+ * @expected
59
+ * - it should be expected height
60
+ */
61
+ it('should return current height successfully', async () => {
62
+ mockAxiosGet(testData.blockHeight);
63
+
64
+ const result = await network.getCurrentHeight();
65
+
66
+ expect(result).toEqual(testData.blockHeight);
67
+ });
68
+ });
69
+
70
+ describe('getBlockTxs', () => {
71
+ /**
72
+ * @target `EsploraNetwork.getBlockTxs` should return block transactions successfully
73
+ * @dependencies
74
+ * @scenario
75
+ * - mock axios to return block header
76
+ * - mock axios to return block transactions 3 times (3 pages)
77
+ * - run test
78
+ * - check returned value
79
+ * - check if function got called
80
+ * @expected
81
+ * - it should be expected height
82
+ * - axios.get should got called 3 times
83
+ * - with mocked block hash and starting index 0
84
+ * - with mocked block hash and starting index 25
85
+ */
86
+ it('should return block transactions successfully', async () => {
87
+ mockAxiosGet(testData.blockResponse);
88
+ mockAxiosGet(testData.blockTxsPage0);
89
+ mockAxiosGet(testData.blockTxsPage1);
90
+
91
+ const result = await network.getBlockTxs(testData.blockHash);
92
+
93
+ expect(result).toEqual([
94
+ ...testData.blockTxsPage0,
95
+ ...testData.blockTxsPage1,
96
+ ]);
97
+ expect(axiosInstance.get).toHaveBeenCalledTimes(3);
98
+ expect(axiosInstance.get).toHaveBeenCalledWith(
99
+ expect.stringContaining(`${testData.blockHash}/txs/0`)
100
+ );
101
+ expect(axiosInstance.get).toHaveBeenCalledWith(
102
+ expect.stringContaining(`${testData.blockHash}/txs/25`)
103
+ );
104
+ });
105
+ });
106
+ });
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "rootDir": "./lib"
5
+ },
6
+ "exclude": ["tests", "vitest.config.ts"],
7
+ "references": [
8
+ { "path": "../../abstract-scanner" },
9
+ { "path": "../../scanner-interfaces/tsconfig.build.json" }
10
+ ]
11
+ }