@mr-zwets/bchn-api-wrapper 1.0.1 → 1.0.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 (45) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/.github/workflows/ci.yaml +36 -0
  3. package/CLAUDE.md +70 -0
  4. package/README.md +121 -129
  5. package/dist/interfaces/interfaces.d.ts +13 -0
  6. package/dist/interfaces/restInterfaces/interfaces.d.ts +124 -18
  7. package/dist/interfaces/rpcInterfaces/blockchain.d.ts +293 -102
  8. package/dist/interfaces/rpcInterfaces/control.d.ts +6 -0
  9. package/dist/interfaces/rpcInterfaces/generating.d.ts +2 -0
  10. package/dist/interfaces/rpcInterfaces/mining.d.ts +9 -0
  11. package/dist/interfaces/rpcInterfaces/network.d.ts +18 -0
  12. package/dist/interfaces/rpcInterfaces/rawtransactions.d.ts +21 -0
  13. package/dist/interfaces/rpcInterfaces/util.d.ts +5 -0
  14. package/dist/interfaces/rpcInterfaces/wallet.d.ts +54 -0
  15. package/dist/interfaces/rpcInterfaces/zmq.d.ts +1 -0
  16. package/dist/restClient.d.ts +13 -1
  17. package/dist/restClient.js +19 -6
  18. package/dist/rpcClient.d.ts +7 -0
  19. package/dist/rpcClient.js +7 -0
  20. package/package.json +7 -8
  21. package/pnpm-lock.yaml +1279 -0
  22. package/src/index.ts +3 -3
  23. package/src/interfaces/interfaces.ts +96 -86
  24. package/src/interfaces/restInterfaces/interfaces.ts +235 -116
  25. package/src/interfaces/rpcInterfaces/blockchain.ts +932 -758
  26. package/src/interfaces/rpcInterfaces/control.ts +68 -62
  27. package/src/interfaces/rpcInterfaces/generating.ts +23 -21
  28. package/src/interfaces/rpcInterfaces/index.ts +13 -13
  29. package/src/interfaces/rpcInterfaces/mining.ts +151 -143
  30. package/src/interfaces/rpcInterfaces/network.ts +213 -195
  31. package/src/interfaces/rpcInterfaces/rawtransactions.ts +332 -314
  32. package/src/interfaces/rpcInterfaces/util.ts +56 -52
  33. package/src/interfaces/rpcInterfaces/wallet.ts +728 -674
  34. package/src/interfaces/rpcInterfaces/zmq.ts +12 -11
  35. package/src/restClient.ts +134 -119
  36. package/src/rpcClient.ts +100 -93
  37. package/src/utils/errors.ts +6 -6
  38. package/src/utils/utils.ts +55 -55
  39. package/test/restClient.test.ts +33 -31
  40. package/test/rpcClient.test.ts +119 -115
  41. package/test/setupTests.ts +56 -54
  42. package/test/tsconfig.json +4 -4
  43. package/tsconfig.json +13 -13
  44. package/vitest.config.ts +8 -8
  45. package/CHANGELOG.md +0 -7
@@ -1,32 +1,34 @@
1
- import { BchnRestClient } from '../src/index.js';
2
-
3
- describe('BchnRestClient URL validation tests', () => {
4
- it('should create an instance with a valid URL', () => {
5
- const client = new BchnRestClient({url: 'http://localhost:8332'});
6
- expect(client).toBeInstanceOf(BchnRestClient);
7
- });
8
-
9
- it('should throw an error for an invalid URL', () => {
10
- expect(() => new BchnRestClient({url: 'invalid-url'})).toThrow('Invalid URL');
11
- });
12
-
13
- it('should throw an error if the URL is missing', () => {
14
- expect(() => new BchnRestClient({url: ''})).toThrow('URL is required');
15
- });
16
- });
17
-
18
- describe('BchnRestClient Timeout Handling', () => {
19
- const config = {
20
- url: 'http://localhost:8332',
21
- timeoutMs: 1000, // 1 second timeout
22
- };
23
- const restClient = new BchnRestClient(config);
24
-
25
- it('should throw a timeout error if the request exceeds the timeout limit', async () => {
26
- await expect(restClient.getChainInfo()).rejects.toThrow('Request timed out');
27
- });
28
-
29
- it('should not return a timeout error if the request completes in time', async () => {
30
- await expect(restClient.getMempoolInfo()).resolves.toEqual({});
31
- });
1
+ import { BchnRestClient } from '../src/index.js';
2
+
3
+ const localhostUrl = 'http://localhost:8332';
4
+
5
+ describe('BchnRestClient URL validation tests', () => {
6
+ it('should create an instance with a valid URL', () => {
7
+ const client = new BchnRestClient({url: localhostUrl});
8
+ expect(client).toBeInstanceOf(BchnRestClient);
9
+ });
10
+
11
+ it('should throw an error for an invalid URL', () => {
12
+ expect(() => new BchnRestClient({url: 'invalid-url'})).toThrow('Invalid URL');
13
+ });
14
+
15
+ it('should throw an error if the URL is missing', () => {
16
+ expect(() => new BchnRestClient({url: ''})).toThrow('URL is required');
17
+ });
18
+ });
19
+
20
+ describe('BchnRestClient Timeout Handling', () => {
21
+ const config = {
22
+ url: localhostUrl,
23
+ timeoutMs: 1000, // 1 second timeout
24
+ };
25
+ const restClient = new BchnRestClient(config);
26
+
27
+ it('should throw a timeout error if the request exceeds the timeout limit', async () => {
28
+ await expect(restClient.getChainInfo()).rejects.toThrow('Request timed out');
29
+ });
30
+
31
+ it('should not return a timeout error if the request completes in time', async () => {
32
+ await expect(restClient.getMempoolInfo()).resolves.toEqual({});
33
+ });
32
34
  });
@@ -1,115 +1,119 @@
1
- import { BchnRpcClient, type GetBestBlockHash, type GetBlockCount, type GetBlockHash, type RpcClientConfig } from '../src/index.js';
2
-
3
- describe('BchnRpcClient should have the correct constructor arguments', () => {
4
- it('should create an instance with a valid URL', () => {
5
- const config = {
6
- url: 'http://localhost:8332',
7
- rpcUser: 'rpcUser',
8
- rpcPassword: 'rpcPassword'
9
- }
10
- const client = new BchnRpcClient(config);
11
- expect(client).toBeInstanceOf(BchnRpcClient);
12
- });
13
-
14
- it('should throw an error for an invalid URL', () => {
15
- const config = {
16
- url: 'invalid-url',
17
- rpcUser: 'rpcUser',
18
- rpcPassword: 'rpcPassword'
19
- }
20
- expect(() => new BchnRpcClient(config)).toThrow('Invalid URL');
21
- });
22
-
23
- it('should throw an error if the URL is empty', () => {
24
- const config = {
25
- url: '',
26
- rpcUser: 'rpcUser',
27
- rpcPassword: 'rpcPassword'
28
- }
29
- expect(() => new BchnRpcClient(config)).toThrow('URL is required');
30
- });
31
-
32
- it('should throw an error if the URL is missing', () => {
33
- const config = {
34
- rpcUser: 'rpcUser',
35
- rpcPassword: 'rpcPassword'
36
- } as RpcClientConfig
37
- expect(() => new BchnRpcClient(config)).toThrow('Invalid configuration: Either provide the url or protocol/host/port');
38
- });
39
-
40
- it('should throw an error if rpcUser is missing', () => {
41
- const config = {
42
- url: 'http://localhost:8332',
43
- rpcPassword: 'rpcPassword'
44
- } as RpcClientConfig
45
- expect(() => new BchnRpcClient(config)).toThrow('Need to provide rpcUser in config');
46
- });
47
-
48
- it('should throw an error if rpcPassword is missing', () => {
49
- const config = {
50
- url: 'http://localhost:8332',
51
- rpcUser: 'rpcUser'
52
- } as RpcClientConfig
53
- expect(() => new BchnRpcClient(config)).toThrow('Need to provide rpcPassword in config');
54
- });
55
- });
56
-
57
- describe('BchnRpcClient Timeout and Retry Handling', () => {
58
- it('should throw a timeout error if the request exceeds the timeout limit', async () => {
59
- const config = {
60
- url: 'http://localhost:8332',
61
- rpcUser: 'rpcUser',
62
- rpcPassword: 'rpcPassword',
63
- timeoutMs: 1000,
64
- }
65
- const rpcClient = new BchnRpcClient(config);
66
-
67
- await expect(rpcClient.request("getbestblockhash")).rejects.toThrow('Request failed after 1 attempts: The operation was aborted due to timeout');
68
- });
69
-
70
- it('should not return a timeout error if the request completes in time', async () => {
71
- const config = {
72
- url: 'http://localhost:8332',
73
- rpcUser: 'rpcUser',
74
- rpcPassword: 'rpcPassword',
75
- timeoutMs: 1000,
76
- }
77
- const rpcClient = new BchnRpcClient(config);
78
-
79
- await expect(rpcClient.request<GetBlockCount>("getblockcount")).resolves.toEqual({});
80
- });
81
-
82
- it('should return an RetryLimitExceededError if all retries fail', async () => {
83
- const config = {
84
- url: 'http://localhost:8332',
85
- rpcUser: 'rpcUser',
86
- rpcPassword: 'rpcPassword',
87
- maxRetries: 3,
88
- timeoutMs: 1000,
89
- }
90
- const rpcClient = new BchnRpcClient(config);
91
- await expect(rpcClient.request<GetBestBlockHash>("getbestblockhash")).rejects.toThrow("Request failed after 4 attempts: The operation was aborted due to timeout");
92
- });
93
- });
94
-
95
- describe('BchnRpcClient Handling of Parameters', () => {
96
- it('should error with incorrect number of params', async () => {
97
- const config = {
98
- url: 'http://localhost:8332',
99
- rpcUser: 'rpcUser',
100
- rpcPassword: 'rpcPassword',
101
- }
102
- const rpcClient = new BchnRpcClient(config);
103
- await expect(rpcClient.request("getblockhash")).rejects.toThrow("Request failed after 1 attempts: Error: Invalid Request");
104
- })
105
-
106
- it('should not error with correct number of params', async () => {
107
- const config = {
108
- url: 'http://localhost:8332',
109
- rpcUser: 'rpcUser',
110
- rpcPassword: 'rpcPassword',
111
- }
112
- const rpcClient = new BchnRpcClient(config);
113
- await expect(rpcClient.request<GetBlockHash>("getblockhash", 5)).resolves.toEqual({});
114
- })
115
- })
1
+ import { BchnRpcClient, type GetBestBlockHash, type GetBlockCount, type GetBlockHash, type RpcClientConfig } from '../src/index.js';
2
+
3
+ const localhostUrl = 'http://localhost:8332';
4
+ const testRpcUser = 'rpcUser';
5
+ const testRpcPassword = 'rpcPassword';
6
+
7
+ describe('BchnRpcClient should have the correct constructor arguments', () => {
8
+ it('should create an instance with a valid URL', () => {
9
+ const config = {
10
+ url: localhostUrl,
11
+ rpcUser: testRpcUser,
12
+ rpcPassword: testRpcPassword
13
+ }
14
+ const client = new BchnRpcClient(config);
15
+ expect(client).toBeInstanceOf(BchnRpcClient);
16
+ });
17
+
18
+ it('should throw an error for an invalid URL', () => {
19
+ const config = {
20
+ url: 'invalid-url',
21
+ rpcUser: testRpcUser,
22
+ rpcPassword: testRpcPassword
23
+ }
24
+ expect(() => new BchnRpcClient(config)).toThrow('Invalid URL');
25
+ });
26
+
27
+ it('should throw an error if the URL is empty', () => {
28
+ const config = {
29
+ url: '',
30
+ rpcUser: testRpcUser,
31
+ rpcPassword: testRpcPassword
32
+ }
33
+ expect(() => new BchnRpcClient(config)).toThrow('URL is required');
34
+ });
35
+
36
+ it('should throw an error if the URL is missing', () => {
37
+ const config = {
38
+ rpcUser: testRpcUser,
39
+ rpcPassword: testRpcPassword
40
+ } as RpcClientConfig
41
+ expect(() => new BchnRpcClient(config)).toThrow('Invalid configuration: Either provide the url or protocol/host/port');
42
+ });
43
+
44
+ it('should throw an error if rpcUser is missing', () => {
45
+ const config = {
46
+ url: localhostUrl,
47
+ rpcPassword: testRpcPassword
48
+ } as RpcClientConfig
49
+ expect(() => new BchnRpcClient(config)).toThrow('Need to provide rpcUser in config');
50
+ });
51
+
52
+ it('should throw an error if rpcPassword is missing', () => {
53
+ const config = {
54
+ url: localhostUrl,
55
+ rpcUser: testRpcUser
56
+ } as RpcClientConfig
57
+ expect(() => new BchnRpcClient(config)).toThrow('Need to provide rpcPassword in config');
58
+ });
59
+ });
60
+
61
+ describe('BchnRpcClient Timeout and Retry Handling', () => {
62
+ it('should throw a timeout error if the request exceeds the timeout limit', async () => {
63
+ const config = {
64
+ url: localhostUrl,
65
+ rpcUser: testRpcUser,
66
+ rpcPassword: testRpcPassword,
67
+ timeoutMs: 1000,
68
+ }
69
+ const rpcClient = new BchnRpcClient(config);
70
+
71
+ await expect(rpcClient.request("getbestblockhash")).rejects.toThrow('Request failed after 1 attempts: The operation was aborted due to timeout');
72
+ });
73
+
74
+ it('should not return a timeout error if the request completes in time', async () => {
75
+ const config = {
76
+ url: localhostUrl,
77
+ rpcUser: testRpcUser,
78
+ rpcPassword: testRpcPassword,
79
+ timeoutMs: 1000,
80
+ }
81
+ const rpcClient = new BchnRpcClient(config);
82
+
83
+ await expect(rpcClient.request<GetBlockCount>("getblockcount")).resolves.toEqual({});
84
+ });
85
+
86
+ it('should return an RetryLimitExceededError if all retries fail', async () => {
87
+ const config = {
88
+ url: localhostUrl,
89
+ rpcUser: testRpcUser,
90
+ rpcPassword: testRpcPassword,
91
+ maxRetries: 3,
92
+ timeoutMs: 1000,
93
+ }
94
+ const rpcClient = new BchnRpcClient(config);
95
+ await expect(rpcClient.request<GetBestBlockHash>("getbestblockhash")).rejects.toThrow("Request failed after 4 attempts: The operation was aborted due to timeout");
96
+ });
97
+ });
98
+
99
+ describe('BchnRpcClient Handling of Parameters', () => {
100
+ it('should error with incorrect number of params', async () => {
101
+ const config = {
102
+ url: localhostUrl,
103
+ rpcUser: testRpcUser,
104
+ rpcPassword: testRpcPassword,
105
+ }
106
+ const rpcClient = new BchnRpcClient(config);
107
+ await expect(rpcClient.request("getblockhash")).rejects.toThrow("Request failed after 1 attempts: Error: Invalid Request");
108
+ })
109
+
110
+ it('should not error with correct number of params', async () => {
111
+ const config = {
112
+ url: localhostUrl,
113
+ rpcUser: testRpcUser,
114
+ rpcPassword: testRpcPassword,
115
+ }
116
+ const rpcClient = new BchnRpcClient(config);
117
+ await expect(rpcClient.request<GetBlockHash>("getblockhash", 5)).resolves.toEqual({});
118
+ })
119
+ })
@@ -1,54 +1,56 @@
1
- import { http, delay, HttpResponse } from 'msw';
2
- import { setupServer, SetupServerApi } from 'msw/node';
3
-
4
- type jsonResult = { method: string; params?: unknown[] } | null | undefined
5
-
6
- const server: SetupServerApi = setupServer(
7
- // Mock endpoint with a delay to simulate timeout
8
- http.get('http://localhost:8332/rest/chaininfo.json', async() => {
9
- // Introduce a delay longer than the timeout setting to simulate a timeout scenario
10
- await delay(3000)
11
- return HttpResponse.json({})
12
- }),
13
-
14
- http.get('http://localhost:8332/rest/mempool/info.json', async() => {
15
- // Mock normally working REST endpoint
16
- await delay(500)
17
- return HttpResponse.json({})
18
- }),
19
-
20
- http.post('http://localhost:8332', async ({ request }) => {
21
- const json = await request.json() as jsonResult;
22
-
23
- if (json === null || json === undefined) {
24
- throw new Error('Invalid JSON response');
25
- }
26
-
27
- // Introduce a delay longer than the timeout setting to simulate a timeout scenario
28
- if (json.method === 'getbestblockhash') {
29
- await delay(3000)
30
- return HttpResponse.json({"jsonrpc": "2.0", "result": {}, "id": 4})
31
- }
32
-
33
- if (json.method === 'getblockcount') {
34
- // Mock normally working RPC command
35
- await delay(500)
36
- return HttpResponse.json({"jsonrpc": "2.0", "result": {}, "id": 5})
37
- }
38
-
39
- if (json.method === 'getblockhash') {
40
- // Mock normally working RPC command
41
- await delay(500)
42
- if (json.params?.[0]) {
43
- return HttpResponse.json({"jsonrpc": "2.0", "result": {}, "id": 6})
44
- } else {
45
- return HttpResponse.json({"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": 7})
46
- }
47
- }
48
- })
49
- );
50
-
51
- // Start the server before tests and reset handlers after each test
52
- beforeAll(() => server.listen());
53
- afterEach(() => server.resetHandlers());
54
- afterAll(() => server.close());
1
+ import { http, delay, HttpResponse } from 'msw';
2
+ import { setupServer, SetupServerApi } from 'msw/node';
3
+
4
+ type jsonResult = { method: string; params?: unknown[] } | null | undefined
5
+
6
+ const localhostUrl = 'http://localhost:8332';
7
+
8
+ const server: SetupServerApi = setupServer(
9
+ // Mock endpoint with a delay to simulate timeout
10
+ http.get(`${localhostUrl}/rest/chaininfo.json`, async() => {
11
+ // Introduce a delay longer than the timeout setting to simulate a timeout scenario
12
+ await delay(3000)
13
+ return HttpResponse.json({})
14
+ }),
15
+
16
+ http.get(`${localhostUrl}/rest/mempool/info.json`, async() => {
17
+ // Mock normally working REST endpoint
18
+ await delay(500)
19
+ return HttpResponse.json({})
20
+ }),
21
+
22
+ http.post(`${localhostUrl}`, async ({ request }) => {
23
+ const json = await request.json() as jsonResult;
24
+
25
+ if (json === null || json === undefined) {
26
+ throw new Error('Invalid JSON response');
27
+ }
28
+
29
+ // Introduce a delay longer than the timeout setting to simulate a timeout scenario
30
+ if (json.method === 'getbestblockhash') {
31
+ await delay(3000)
32
+ return HttpResponse.json({"jsonrpc": "2.0", "result": {}, "id": 4})
33
+ }
34
+
35
+ if (json.method === 'getblockcount') {
36
+ // Mock normally working RPC command
37
+ await delay(500)
38
+ return HttpResponse.json({"jsonrpc": "2.0", "result": {}, "id": 5})
39
+ }
40
+
41
+ if (json.method === 'getblockhash') {
42
+ // Mock normally working RPC command
43
+ await delay(500)
44
+ if (json.params?.[0]) {
45
+ return HttpResponse.json({"jsonrpc": "2.0", "result": {}, "id": 6})
46
+ } else {
47
+ return HttpResponse.json({"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": 7})
48
+ }
49
+ }
50
+ })
51
+ );
52
+
53
+ // Start the server before tests and reset handlers after each test
54
+ beforeAll(() => server.listen());
55
+ afterEach(() => server.resetHandlers());
56
+ afterAll(() => server.close());
@@ -1,4 +1,4 @@
1
- {
2
- "extends": "../tsconfig.json",
3
- "include": ["**/*"],
4
- }
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "include": ["**/*"],
4
+ }
package/tsconfig.json CHANGED
@@ -1,13 +1,13 @@
1
- {
2
- "compilerOptions": {
3
- "module": "NodeNext",
4
- "verbatimModuleSyntax": true,
5
- "moduleResolution": "NodeNext",
6
- "target": "ES6",
7
- "strict": true,
8
- "outDir": "./dist",
9
- "declaration": true,
10
- "types": ["vitest/globals"],
11
- },
12
- "include": ["src"]
13
- }
1
+ {
2
+ "compilerOptions": {
3
+ "module": "NodeNext",
4
+ "verbatimModuleSyntax": true,
5
+ "moduleResolution": "NodeNext",
6
+ "target": "ES6",
7
+ "strict": true,
8
+ "outDir": "./dist",
9
+ "declaration": true,
10
+ "types": ["vitest/globals", "node"],
11
+ },
12
+ "include": ["src"]
13
+ }
package/vitest.config.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { defineConfig } from 'vitest/config';
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: 'node',
7
- setupFiles: ['./test/setupTests.ts']
8
- },
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ environment: 'node',
7
+ setupFiles: ['./test/setupTests.ts']
8
+ },
9
9
  })
package/CHANGELOG.md DELETED
@@ -1,7 +0,0 @@
1
- ## v1.0.1
2
-
3
- ❗️ Fix for huge list of unneeded dependencies accidentally introduced by `nmp@9.5.1` on `npm init`
4
-
5
- ## v1.0.0
6
-
7
- First Release 🥳