@pezkuwi/rpc-provider 16.5.20 → 16.5.22

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 (210) hide show
  1. package/package.json +9 -9
  2. package/build/LICENSE +0 -201
  3. package/build/README.md +0 -68
  4. package/build/bizinikiwi-connect/Health.js +0 -259
  5. package/build/bizinikiwi-connect/index.js +0 -319
  6. package/build/bizinikiwi-connect/types.js +0 -1
  7. package/build/bundle.js +0 -5
  8. package/build/cjs/bizinikiwi-connect/Health.d.ts +0 -7
  9. package/build/cjs/bizinikiwi-connect/Health.js +0 -264
  10. package/build/cjs/bizinikiwi-connect/index.d.ts +0 -22
  11. package/build/cjs/bizinikiwi-connect/index.js +0 -323
  12. package/build/cjs/bizinikiwi-connect/types.d.ts +0 -12
  13. package/build/cjs/bizinikiwi-connect/types.js +0 -2
  14. package/build/cjs/bundle.d.ts +0 -5
  15. package/build/cjs/bundle.js +0 -14
  16. package/build/cjs/coder/error.js +0 -53
  17. package/build/cjs/coder/index.js +0 -63
  18. package/build/cjs/defaults.js +0 -8
  19. package/build/cjs/http/index.js +0 -196
  20. package/build/cjs/http/types.js +0 -2
  21. package/build/cjs/index.js +0 -5
  22. package/build/cjs/lru.js +0 -150
  23. package/build/cjs/mock/index.js +0 -196
  24. package/build/cjs/mock/mockHttp.js +0 -17
  25. package/build/cjs/mock/mockWs.js +0 -47
  26. package/build/cjs/mock/types.js +0 -2
  27. package/build/cjs/packageInfo.js +0 -4
  28. package/build/cjs/types.js +0 -2
  29. package/build/cjs/ws/errors.js +0 -41
  30. package/build/cjs/ws/index.js +0 -529
  31. package/build/coder/error.d.ts +0 -29
  32. package/build/coder/error.js +0 -50
  33. package/build/coder/index.d.ts +0 -8
  34. package/build/coder/index.js +0 -58
  35. package/build/defaults.d.ts +0 -5
  36. package/build/defaults.js +0 -6
  37. package/build/http/index.d.ts +0 -81
  38. package/build/http/index.js +0 -191
  39. package/build/http/types.d.ts +0 -7
  40. package/build/http/types.js +0 -1
  41. package/build/index.d.ts +0 -2
  42. package/build/index.js +0 -2
  43. package/build/lru.d.ts +0 -15
  44. package/build/lru.js +0 -146
  45. package/build/mock/index.d.ts +0 -35
  46. package/build/mock/index.js +0 -191
  47. package/build/mock/mockHttp.d.ts +0 -9
  48. package/build/mock/mockHttp.js +0 -12
  49. package/build/mock/mockWs.d.ts +0 -26
  50. package/build/mock/mockWs.js +0 -43
  51. package/build/mock/types.d.ts +0 -23
  52. package/build/mock/types.js +0 -1
  53. package/build/package.json +0 -344
  54. package/build/packageDetect.d.ts +0 -1
  55. package/build/packageDetect.js +0 -4
  56. package/build/packageInfo.d.ts +0 -6
  57. package/build/packageInfo.js +0 -1
  58. package/build/types.d.ts +0 -85
  59. package/build/types.js +0 -1
  60. package/build/ws/errors.d.ts +0 -1
  61. package/build/ws/errors.js +0 -38
  62. package/build/ws/index.d.ts +0 -121
  63. package/build/ws/index.js +0 -524
  64. package/build-deno/README.md +0 -66
  65. package/build-deno/bizinikiwi-connect/Health.ts +0 -323
  66. package/build-deno/bizinikiwi-connect/index.ts +0 -417
  67. package/build-deno/bizinikiwi-connect/types.ts +0 -14
  68. package/build-deno/bundle.ts +0 -6
  69. package/build-deno/coder/error.ts +0 -64
  70. package/build-deno/coder/index.ts +0 -86
  71. package/build-deno/defaults.ts +0 -8
  72. package/build-deno/http/index.ts +0 -236
  73. package/build-deno/http/types.ts +0 -9
  74. package/build-deno/index.ts +0 -4
  75. package/build-deno/lru.ts +0 -189
  76. package/build-deno/mock/index.ts +0 -257
  77. package/build-deno/mock/mockHttp.ts +0 -33
  78. package/build-deno/mock/mockWs.ts +0 -87
  79. package/build-deno/mock/types.ts +0 -34
  80. package/build-deno/mod.ts +0 -2
  81. package/build-deno/packageDetect.ts +0 -8
  82. package/build-deno/packageInfo.ts +0 -3
  83. package/build-deno/types.ts +0 -99
  84. package/build-deno/ws/errors.ts +0 -38
  85. package/build-deno/ws/index.ts +0 -650
  86. package/build-tsc-cjs/packageDetect.js +0 -6
  87. package/src/bizinikiwi-connect/Health.ts +0 -325
  88. package/src/bizinikiwi-connect/index.spec.ts +0 -675
  89. package/src/bizinikiwi-connect/index.ts +0 -427
  90. package/src/bizinikiwi-connect/types.ts +0 -16
  91. package/src/bundle.ts +0 -8
  92. package/src/coder/decodeResponse.spec.ts +0 -70
  93. package/src/coder/encodeJson.spec.ts +0 -20
  94. package/src/coder/encodeObject.spec.ts +0 -25
  95. package/src/coder/error.spec.ts +0 -111
  96. package/src/coder/error.ts +0 -66
  97. package/src/coder/index.ts +0 -88
  98. package/src/defaults.ts +0 -10
  99. package/src/http/index.spec.ts +0 -72
  100. package/src/http/index.ts +0 -238
  101. package/src/http/send.spec.ts +0 -61
  102. package/src/http/types.ts +0 -11
  103. package/src/index.ts +0 -6
  104. package/src/lru.spec.ts +0 -74
  105. package/src/lru.ts +0 -197
  106. package/src/mock/index.ts +0 -259
  107. package/src/mock/mockHttp.ts +0 -35
  108. package/src/mock/mockWs.ts +0 -92
  109. package/src/mock/on.spec.ts +0 -43
  110. package/src/mock/send.spec.ts +0 -38
  111. package/src/mock/subscribe.spec.ts +0 -81
  112. package/src/mock/types.ts +0 -36
  113. package/src/mock/unsubscribe.spec.ts +0 -57
  114. package/src/mod.ts +0 -4
  115. package/src/packageDetect.ts +0 -12
  116. package/src/packageInfo.ts +0 -6
  117. package/src/types.ts +0 -101
  118. package/src/ws/connect.spec.ts +0 -167
  119. package/src/ws/errors.ts +0 -41
  120. package/src/ws/index.spec.ts +0 -97
  121. package/src/ws/index.ts +0 -652
  122. package/src/ws/send.spec.ts +0 -126
  123. package/src/ws/state.spec.ts +0 -20
  124. package/src/ws/subscribe.spec.ts +0 -68
  125. package/src/ws/unsubscribe.spec.ts +0 -100
  126. package/tsconfig.build.json +0 -17
  127. package/tsconfig.build.tsbuildinfo +0 -1
  128. package/tsconfig.spec.json +0 -18
  129. package/tsconfig.spec.tsbuildinfo +0 -1
  130. /package/{build-tsc/bizinikiwi-connect → bizinikiwi-connect}/Health.d.ts +0 -0
  131. /package/{build-tsc-esm/bizinikiwi-connect → bizinikiwi-connect}/Health.js +0 -0
  132. /package/{build-tsc/bizinikiwi-connect → bizinikiwi-connect}/index.d.ts +0 -0
  133. /package/{build-tsc-esm/bizinikiwi-connect → bizinikiwi-connect}/index.js +0 -0
  134. /package/{build-tsc/bizinikiwi-connect → bizinikiwi-connect}/types.d.ts +0 -0
  135. /package/{build-tsc-esm/bizinikiwi-connect → bizinikiwi-connect}/types.js +0 -0
  136. /package/{build-tsc/bundle.d.ts → bundle.d.ts} +0 -0
  137. /package/{build-tsc-esm/bundle.js → bundle.js} +0 -0
  138. /package/{build → cjs}/bizinikiwi-connect/Health.d.ts +0 -0
  139. /package/{build-tsc-cjs → cjs}/bizinikiwi-connect/Health.js +0 -0
  140. /package/{build → cjs}/bizinikiwi-connect/index.d.ts +0 -0
  141. /package/{build-tsc-cjs → cjs}/bizinikiwi-connect/index.js +0 -0
  142. /package/{build → cjs}/bizinikiwi-connect/types.d.ts +0 -0
  143. /package/{build-tsc-cjs → cjs}/bizinikiwi-connect/types.js +0 -0
  144. /package/{build → cjs}/bundle.d.ts +0 -0
  145. /package/{build-tsc-cjs → cjs}/bundle.js +0 -0
  146. /package/{build-tsc → cjs}/coder/error.d.ts +0 -0
  147. /package/{build-tsc-cjs → cjs}/coder/error.js +0 -0
  148. /package/{build-tsc → cjs}/coder/index.d.ts +0 -0
  149. /package/{build-tsc-cjs → cjs}/coder/index.js +0 -0
  150. /package/{build-tsc → cjs}/defaults.d.ts +0 -0
  151. /package/{build-tsc-cjs → cjs}/defaults.js +0 -0
  152. /package/{build-tsc → cjs}/http/index.d.ts +0 -0
  153. /package/{build-tsc-cjs → cjs}/http/index.js +0 -0
  154. /package/{build-tsc → cjs}/http/types.d.ts +0 -0
  155. /package/{build-tsc-cjs → cjs}/http/types.js +0 -0
  156. /package/{build-tsc → cjs}/index.d.ts +0 -0
  157. /package/{build-tsc-cjs → cjs}/index.js +0 -0
  158. /package/{build-tsc → cjs}/lru.d.ts +0 -0
  159. /package/{build-tsc-cjs → cjs}/lru.js +0 -0
  160. /package/{build-tsc → cjs}/mock/index.d.ts +0 -0
  161. /package/{build-tsc-cjs → cjs}/mock/index.js +0 -0
  162. /package/{build-tsc → cjs}/mock/mockHttp.d.ts +0 -0
  163. /package/{build-tsc-cjs → cjs}/mock/mockHttp.js +0 -0
  164. /package/{build-tsc → cjs}/mock/mockWs.d.ts +0 -0
  165. /package/{build-tsc-cjs → cjs}/mock/mockWs.js +0 -0
  166. /package/{build-tsc → cjs}/mock/types.d.ts +0 -0
  167. /package/{build-tsc-cjs → cjs}/mock/types.js +0 -0
  168. /package/{build/cjs → cjs}/package.json +0 -0
  169. /package/{build-tsc → cjs}/packageDetect.d.ts +0 -0
  170. /package/{build/cjs → cjs}/packageDetect.js +0 -0
  171. /package/{build-tsc → cjs}/packageInfo.d.ts +0 -0
  172. /package/{build-tsc-cjs → cjs}/packageInfo.js +0 -0
  173. /package/{build-tsc → cjs}/types.d.ts +0 -0
  174. /package/{build-tsc-cjs → cjs}/types.js +0 -0
  175. /package/{build-tsc → cjs}/ws/errors.d.ts +0 -0
  176. /package/{build-tsc-cjs → cjs}/ws/errors.js +0 -0
  177. /package/{build-tsc → cjs}/ws/index.d.ts +0 -0
  178. /package/{build-tsc-cjs → cjs}/ws/index.js +0 -0
  179. /package/{build/cjs/coder → coder}/error.d.ts +0 -0
  180. /package/{build-tsc-esm/coder → coder}/error.js +0 -0
  181. /package/{build/cjs/coder → coder}/index.d.ts +0 -0
  182. /package/{build-tsc-esm/coder → coder}/index.js +0 -0
  183. /package/{build/cjs/defaults.d.ts → defaults.d.ts} +0 -0
  184. /package/{build-tsc-esm/defaults.js → defaults.js} +0 -0
  185. /package/{build/cjs/http → http}/index.d.ts +0 -0
  186. /package/{build-tsc-esm/http → http}/index.js +0 -0
  187. /package/{build/cjs/http → http}/types.d.ts +0 -0
  188. /package/{build-tsc-esm/http → http}/types.js +0 -0
  189. /package/{build/cjs/index.d.ts → index.d.ts} +0 -0
  190. /package/{build-tsc-esm/index.js → index.js} +0 -0
  191. /package/{build/cjs/lru.d.ts → lru.d.ts} +0 -0
  192. /package/{build-tsc-esm/lru.js → lru.js} +0 -0
  193. /package/{build/cjs/mock → mock}/index.d.ts +0 -0
  194. /package/{build-tsc-esm/mock → mock}/index.js +0 -0
  195. /package/{build/cjs/mock → mock}/mockHttp.d.ts +0 -0
  196. /package/{build-tsc-esm/mock → mock}/mockHttp.js +0 -0
  197. /package/{build/cjs/mock → mock}/mockWs.d.ts +0 -0
  198. /package/{build-tsc-esm/mock → mock}/mockWs.js +0 -0
  199. /package/{build/cjs/mock → mock}/types.d.ts +0 -0
  200. /package/{build-tsc-esm/mock → mock}/types.js +0 -0
  201. /package/{build/cjs/packageDetect.d.ts → packageDetect.d.ts} +0 -0
  202. /package/{build-tsc-esm/packageDetect.js → packageDetect.js} +0 -0
  203. /package/{build/cjs/packageInfo.d.ts → packageInfo.d.ts} +0 -0
  204. /package/{build-tsc-esm/packageInfo.js → packageInfo.js} +0 -0
  205. /package/{build/cjs/types.d.ts → types.d.ts} +0 -0
  206. /package/{build-tsc-esm/types.js → types.js} +0 -0
  207. /package/{build/cjs/ws → ws}/errors.d.ts +0 -0
  208. /package/{build-tsc-esm/ws → ws}/errors.js +0 -0
  209. /package/{build/cjs/ws → ws}/index.d.ts +0 -0
  210. /package/{build-tsc-esm/ws → ws}/index.js +0 -0
@@ -1,427 +0,0 @@
1
- // Copyright 2017-2025 @pezkuwi/rpc-provider authors & contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- import type * as ScType from '@bizinikiwi/connect';
5
- import type { JsonRpcResponse, ProviderInterface, ProviderInterfaceCallback, ProviderInterfaceEmitCb, ProviderInterfaceEmitted } from '../types.js';
6
-
7
- import { EventEmitter } from 'eventemitter3';
8
-
9
- import { isError, isFunction, isObject, logger, noop, objectSpread } from '@pezkuwi/util';
10
-
11
- import { RpcCoder } from '../coder/index.js';
12
- import { healthChecker } from './Health.js';
13
-
14
- type ResponseCallback = (response: string | Error) => void;
15
-
16
- // We define the interface with items we use - this means that we don't really
17
- // need to be passed a full `import * as Sc from '@ubstrate/connect'`, but can
18
- // also make do with a { WellKnownChain, createScClient } interface
19
- interface BizinikiwiConnect {
20
- WellKnownChain: typeof ScType['WellKnownChain'];
21
- createScClient: typeof ScType['createScClient'];
22
- }
23
-
24
- const l = logger('api-bizinikiwi-connect');
25
-
26
- // These methods have been taken from:
27
- // https://github.com/pezkuwichain/smoldot/blob/17425040ddda47d539556eeaf62b88c4240d1d42/src/json_rpc/methods.rs#L338-L462
28
- // It's important to take into account that smoldot is adding support to the new
29
- // json-rpc-interface https://pezkuwichain.github.io/json-rpc-interface-spec/
30
- // However, at the moment this list only includes methods that belong to the "old" API
31
- const subscriptionUnsubscriptionMethods = new Map<string, string>([
32
- ['author_submitAndWatchExtrinsic', 'author_unwatchExtrinsic'],
33
- ['chain_subscribeAllHeads', 'chain_unsubscribeAllHeads'],
34
- ['chain_subscribeFinalizedHeads', 'chain_unsubscribeFinalizedHeads'],
35
- ['chain_subscribeFinalisedHeads', 'chain_subscribeFinalisedHeads'],
36
- ['chain_subscribeNewHeads', 'chain_unsubscribeNewHeads'],
37
- ['chain_subscribeNewHead', 'chain_unsubscribeNewHead'],
38
- ['chain_subscribeRuntimeVersion', 'chain_unsubscribeRuntimeVersion'],
39
- ['subscribe_newHead', 'unsubscribe_newHead'],
40
- ['state_subscribeRuntimeVersion', 'state_unsubscribeRuntimeVersion'],
41
- ['state_subscribeStorage', 'state_unsubscribeStorage']
42
- ]);
43
-
44
- const scClients = new WeakMap<ScProvider, ScType.ScClient>();
45
-
46
- interface ActiveSubs {
47
- type: string,
48
- method: string,
49
- params: any[],
50
- callback: ProviderInterfaceCallback
51
- }
52
-
53
- export class ScProvider implements ProviderInterface {
54
- readonly #Sc: BizinikiwiConnect;
55
- readonly #coder: RpcCoder = new RpcCoder();
56
- readonly #spec: string | ScType.WellKnownChain;
57
- readonly #sharedSandbox?: ScProvider | undefined;
58
- readonly #subscriptions = new Map<string, [ResponseCallback, { unsubscribeMethod: string; id: string | number }]>();
59
- readonly #resubscribeMethods = new Map<string, ActiveSubs>();
60
- readonly #requests = new Map<number, ResponseCallback>();
61
- readonly #wellKnownChains: Set<ScType.WellKnownChain>;
62
- readonly #eventemitter: EventEmitter = new EventEmitter();
63
-
64
- #chain: Promise<ScType.Chain> | null = null;
65
- #isChainReady = false;
66
-
67
- public constructor (Sc: BizinikiwiConnect, spec: string | ScType.WellKnownChain, sharedSandbox?: ScProvider) {
68
- if (!isObject(Sc) || !isObject(Sc.WellKnownChain) || !isFunction(Sc.createScClient)) {
69
- throw new Error('Expected an @bizinikiwi/connect interface as first parameter to ScProvider');
70
- }
71
-
72
- this.#Sc = Sc;
73
- this.#spec = spec;
74
- this.#sharedSandbox = sharedSandbox;
75
- this.#wellKnownChains = new Set(Object.values(Sc.WellKnownChain));
76
- }
77
-
78
- public get hasSubscriptions (): boolean {
79
- // Indicates that subscriptions are supported
80
- return !!true;
81
- }
82
-
83
- public get isClonable (): boolean {
84
- return !!false;
85
- }
86
-
87
- public get isConnected (): boolean {
88
- return !!this.#chain && this.#isChainReady;
89
- }
90
-
91
- public clone (): ProviderInterface {
92
- throw new Error('clone() is not supported.');
93
- }
94
-
95
- // Config details can be found in @bizinikiwi/connect repo following the link:
96
- // https://github.com/pezkuwichain/bizinikiwi-connect/blob/main/packages/connect/src/connector/index.ts
97
- async connect (config?: ScType.Config, checkerFactory = healthChecker): Promise<void> {
98
- if (this.isConnected) {
99
- throw new Error('Already connected!');
100
- }
101
-
102
- // it could happen that after emitting `disconnected` due to the fact that
103
- // smoldot is syncing, the consumer tries to reconnect after a certain amount
104
- // of time... In which case we want to make sure that we don't create a new
105
- // chain.
106
- if (this.#chain) {
107
- await this.#chain;
108
-
109
- return;
110
- }
111
-
112
- if (this.#sharedSandbox && !this.#sharedSandbox.isConnected) {
113
- await this.#sharedSandbox.connect();
114
- }
115
-
116
- const client = this.#sharedSandbox
117
- ? scClients.get(this.#sharedSandbox)
118
- : this.#Sc.createScClient(config);
119
-
120
- if (!client) {
121
- throw new Error('Unknown ScProvider!');
122
- }
123
-
124
- scClients.set(this, client);
125
-
126
- const hc = checkerFactory();
127
-
128
- const onResponse = (res: string): void => {
129
- const hcRes = hc.responsePassThrough(res);
130
-
131
- if (!hcRes) {
132
- return;
133
- }
134
-
135
- const response = JSON.parse(hcRes) as JsonRpcResponse<string>;
136
- let decodedResponse: string | Error;
137
-
138
- try {
139
- decodedResponse = this.#coder.decodeResponse(response);
140
- } catch (e) {
141
- decodedResponse = e as Error;
142
- }
143
-
144
- // It's not a subscription message, but rather a standar RPC response
145
- if (response.params?.subscription === undefined || !response.method) {
146
- return this.#requests.get(response.id)?.(decodedResponse);
147
- }
148
-
149
- // We are dealing with a subscription message
150
- const subscriptionId = `${response.method}::${response.params.subscription}`;
151
-
152
- const callback = this.#subscriptions.get(subscriptionId)?.[0];
153
-
154
- callback?.(decodedResponse);
155
- };
156
-
157
- const addChain = this.#sharedSandbox
158
- ? (async (...args) => {
159
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
160
- const source = this.#sharedSandbox!;
161
-
162
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
163
- return (await source.#chain)!.addChain(...args);
164
- }) as ScType.AddChain
165
- : this.#wellKnownChains.has(this.#spec as ScType.WellKnownChain)
166
- ? client.addWellKnownChain
167
- : client.addChain;
168
-
169
- this.#chain = addChain(this.#spec as ScType.WellKnownChain).then((chain) => {
170
- hc.setSendJsonRpc(chain.sendJsonRpc);
171
-
172
- // Start async response processing loop
173
- // This replaces the callback-based API from older @substrate/connect versions
174
- (async () => {
175
- try {
176
- for await (const res of chain.jsonRpcResponses) {
177
- onResponse(res);
178
- }
179
- } catch {
180
- // Chain was removed or connection closed - this is expected
181
- }
182
- })();
183
-
184
- this.#isChainReady = false;
185
-
186
- const cleanup = () => {
187
- // If there are any callbacks left, we have to reject/error them.
188
- // Otherwise, that would cause a memory leak.
189
- const disconnectionError = new Error('Disconnected');
190
-
191
- this.#requests.forEach((cb) => cb(disconnectionError));
192
- this.#subscriptions.forEach(([cb]) => cb(disconnectionError));
193
- this.#subscriptions.clear();
194
- };
195
-
196
- const staleSubscriptions: {
197
- unsubscribeMethod: string
198
- id: number | string
199
- }[] = [];
200
-
201
- const killStaleSubscriptions = () => {
202
- if (staleSubscriptions.length === 0) {
203
- return;
204
- }
205
-
206
- const stale = staleSubscriptions.pop();
207
-
208
- if (!stale) {
209
- throw new Error('Unable to get stale subscription');
210
- }
211
-
212
- const { id, unsubscribeMethod } = stale;
213
-
214
- Promise
215
- .race([
216
- this.send(unsubscribeMethod, [id]).catch(noop),
217
- new Promise((resolve) => setTimeout(resolve, 500))
218
- ])
219
- .then(killStaleSubscriptions)
220
- .catch(noop);
221
- };
222
-
223
- hc.start((health) => {
224
- const isReady =
225
- !health.isSyncing && (health.peers > 0 || !health.shouldHavePeers);
226
-
227
- // if it's the same as before, then nothing has changed and we are done
228
- if (this.#isChainReady === isReady) {
229
- return;
230
- }
231
-
232
- this.#isChainReady = isReady;
233
-
234
- if (!isReady) {
235
- // If we've reached this point, that means that the chain used to be "ready"
236
- // and now we are about to emit `disconnected`.
237
- //
238
- // This will cause the PezkuwiJs API think that the connection is
239
- // actually dead. In reality the smoldot chain is not dead, of course.
240
- // However, we have to cleanup all the existing callbacks because when
241
- // the smoldot chain stops syncing, then we will emit `connected` and
242
- // the PezkuwiJs API will try to re-create the previous
243
- // subscriptions and requests. Although, now is not a good moment
244
- // to be sending unsubscription messages to the smoldot chain, we
245
- // should wait until is no longer syncing to send the unsubscription
246
- // messages from the stale subscriptions of the previous connection.
247
- //
248
- // That's why -before we perform the cleanup of `this.#subscriptions`-
249
- // we keep the necessary information that we will need later on to
250
- // kill the stale subscriptions.
251
- [...this.#subscriptions.values()].forEach((s) => {
252
- staleSubscriptions.push(s[1]);
253
- });
254
- cleanup();
255
-
256
- this.#eventemitter.emit('disconnected');
257
- } else {
258
- killStaleSubscriptions();
259
-
260
- this.#eventemitter.emit('connected');
261
-
262
- if (this.#resubscribeMethods.size) {
263
- this.#resubscribe();
264
- }
265
- }
266
- });
267
-
268
- return objectSpread({}, chain, {
269
- remove: () => {
270
- hc.stop();
271
- chain.remove();
272
- cleanup();
273
- },
274
- sendJsonRpc: hc.sendJsonRpc.bind(hc)
275
- });
276
- });
277
-
278
- try {
279
- await this.#chain;
280
- } catch (e) {
281
- this.#chain = null;
282
- this.#eventemitter.emit('error', e);
283
- throw e;
284
- }
285
- }
286
-
287
- #resubscribe = (): void => {
288
- const promises: any[] = [];
289
-
290
- this.#resubscribeMethods.forEach((subDetails: ActiveSubs): void => {
291
- // only re-create subscriptions which are not in author (only area where
292
- // transactions are created, i.e. submissions such as 'author_submitAndWatchExtrinsic'
293
- // are not included (and will not be re-broadcast)
294
- if (subDetails.type.startsWith('author_')) {
295
- return;
296
- }
297
-
298
- try {
299
- const promise = new Promise<void>((resolve) => {
300
- this.subscribe(subDetails.type, subDetails.method, subDetails.params, subDetails.callback).catch((error) => console.log(error));
301
- resolve();
302
- });
303
-
304
- promises.push(promise);
305
- } catch (error) {
306
- l.error(error);
307
- }
308
- });
309
-
310
- Promise.all(promises).catch((err) => l.log(err));
311
- };
312
-
313
- async disconnect (): Promise<void> {
314
- if (!this.#chain) {
315
- return;
316
- }
317
-
318
- const chain = await this.#chain;
319
-
320
- this.#chain = null;
321
- this.#isChainReady = false;
322
-
323
- try {
324
- chain.remove();
325
- } catch (_) {}
326
-
327
- this.#eventemitter.emit('disconnected');
328
- }
329
-
330
- public on (type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): () => void {
331
- // It's possible. Although, quite unlikely, that by the time that pezkuwi
332
- // subscribes to the `connected` event, the Provider is already connected.
333
- // In that case, we must emit to let the consumer know that we are connected.
334
- if (type === 'connected' && this.isConnected) {
335
- sub();
336
- }
337
-
338
- this.#eventemitter.on(type, sub);
339
-
340
- return (): void => {
341
- this.#eventemitter.removeListener(type, sub);
342
- };
343
- }
344
-
345
- public async send<T = any> (method: string, params: unknown[]): Promise<T> {
346
- if (!this.isConnected || !this.#chain) {
347
- throw new Error('Provider is not connected');
348
- }
349
-
350
- const chain = await this.#chain;
351
- const [id, json] = this.#coder.encodeJson(method, params);
352
-
353
- const result = new Promise<T>((resolve, reject): void => {
354
- this.#requests.set(id, (response) => {
355
- (isError(response) ? reject : resolve)(response as unknown as T);
356
- });
357
-
358
- try {
359
- chain.sendJsonRpc(json);
360
- } catch (e) {
361
- this.#chain = null;
362
-
363
- try {
364
- chain.remove();
365
- } catch (_) {}
366
-
367
- this.#eventemitter.emit('error', e);
368
- }
369
- });
370
-
371
- try {
372
- return await result;
373
- } finally {
374
- // let's ensure that once the Promise is resolved/rejected, then we remove
375
- // remove its entry from the internal #requests
376
- this.#requests.delete(id);
377
- }
378
- }
379
-
380
- public async subscribe (type: string, method: string, params: any[], callback: ProviderInterfaceCallback): Promise<number | string> {
381
- if (!subscriptionUnsubscriptionMethods.has(method)) {
382
- throw new Error(`Unsupported subscribe method: ${method}`);
383
- }
384
-
385
- const id = await this.send<number | string>(method, params);
386
- const subscriptionId = `${type}::${id}`;
387
-
388
- const cb = (response: Error | string) => {
389
- if (response instanceof Error) {
390
- callback(response, undefined);
391
- } else {
392
- callback(null, response);
393
- }
394
- };
395
-
396
- const unsubscribeMethod = subscriptionUnsubscriptionMethods.get(method);
397
-
398
- if (!unsubscribeMethod) {
399
- throw new Error('Invalid unsubscribe method found');
400
- }
401
-
402
- this.#resubscribeMethods.set(subscriptionId, { callback, method, params, type });
403
-
404
- this.#subscriptions.set(subscriptionId, [cb, { id, unsubscribeMethod }]);
405
-
406
- return id;
407
- }
408
-
409
- public unsubscribe (type: string, method: string, id: number | string): Promise<boolean> {
410
- if (!this.isConnected) {
411
- throw new Error('Provider is not connected');
412
- }
413
-
414
- const subscriptionId = `${type}::${id}`;
415
-
416
- if (!this.#subscriptions.has(subscriptionId)) {
417
- return Promise.reject(
418
- new Error(`Unable to find active subscription=${subscriptionId}`)
419
- );
420
- }
421
-
422
- this.#resubscribeMethods.delete(subscriptionId);
423
- this.#subscriptions.delete(subscriptionId);
424
-
425
- return this.send(method, [id]);
426
- }
427
- }
@@ -1,16 +0,0 @@
1
- // Copyright 2017-2025 @pezkuwi/rpc-provider authors & contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- export interface SmoldotHealth {
5
- isSyncing: boolean
6
- peers: number
7
- shouldHavePeers: boolean
8
- }
9
-
10
- export interface HealthChecker {
11
- setSendJsonRpc(sendRequest: (request: string) => void): void
12
- start(healthCallback: (health: SmoldotHealth) => void): void
13
- stop(): void
14
- sendJsonRpc(request: string): void
15
- responsePassThrough(response: string): string | null
16
- }
package/src/bundle.ts DELETED
@@ -1,8 +0,0 @@
1
- // Copyright 2017-2025 @pezkuwi/rpc-provider authors & contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- export { ScProvider } from './bizinikiwi-connect/index.js';
5
- export { HttpProvider } from './http/index.js';
6
- export { DEFAULT_CAPACITY, LRUCache } from './lru.js';
7
- export { packageInfo } from './packageInfo.js';
8
- export { WsProvider } from './ws/index.js';
@@ -1,70 +0,0 @@
1
- // Copyright 2017-2025 @pezkuwi/rpc-provider authors & contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- /// <reference types="@pezkuwi/dev-test/globals.d.ts" />
5
-
6
- import type { JsonRpcResponse } from '../types.js';
7
-
8
- import { RpcCoder } from './index.js';
9
-
10
- describe('decodeResponse', (): void => {
11
- let coder: RpcCoder;
12
-
13
- beforeEach((): void => {
14
- coder = new RpcCoder();
15
- });
16
-
17
- it('expects a non-empty input object', (): void => {
18
- expect(
19
- () => coder.decodeResponse(undefined as unknown as JsonRpcResponse<unknown>)
20
- ).toThrow(/Invalid jsonrpc/);
21
- });
22
-
23
- it('expects a valid jsonrpc field', (): void => {
24
- expect(
25
- () => coder.decodeResponse({} as JsonRpcResponse<unknown>)
26
- ).toThrow(/Invalid jsonrpc/);
27
- });
28
-
29
- it('expects a valid id field', (): void => {
30
- expect(
31
- () => coder.decodeResponse({ jsonrpc: '2.0' } as JsonRpcResponse<unknown>)
32
- ).toThrow(/Invalid id/);
33
- });
34
-
35
- it('expects a valid result field', (): void => {
36
- expect(
37
- () => coder.decodeResponse({ id: 1, jsonrpc: '2.0' } as JsonRpcResponse<unknown>)
38
- ).toThrow(/No result/);
39
- });
40
-
41
- it('throws any error found', (): void => {
42
- expect(
43
- () => coder.decodeResponse({ error: { code: 123, message: 'test error' }, id: 1, jsonrpc: '2.0' } as JsonRpcResponse<unknown>)
44
- ).toThrow(/123: test error/);
45
- });
46
-
47
- it('throws any error found, with data', (): void => {
48
- expect(
49
- () => coder.decodeResponse({ error: { code: 123, data: 'Error("Some random error description")', message: 'test error' }, id: 1, jsonrpc: '2.0' } as JsonRpcResponse<unknown>)
50
- ).toThrow(/123: test error: Some random error description/);
51
- });
52
-
53
- it('allows for number subscription ids', (): void => {
54
- expect(
55
- coder.decodeResponse({ id: 1, jsonrpc: '2.0', method: 'test', params: { result: 'test result', subscription: 1 } } as JsonRpcResponse<unknown>)
56
- ).toEqual('test result');
57
- });
58
-
59
- it('allows for string subscription ids', (): void => {
60
- expect(
61
- coder.decodeResponse({ id: 1, jsonrpc: '2.0', method: 'test', params: { result: 'test result', subscription: 'abc' } } as JsonRpcResponse<unknown>)
62
- ).toEqual('test result');
63
- });
64
-
65
- it('returns the result', (): void => {
66
- expect(
67
- coder.decodeResponse({ id: 1, jsonrpc: '2.0', result: 'some result' } as JsonRpcResponse<unknown>)
68
- ).toEqual('some result');
69
- });
70
- });
@@ -1,20 +0,0 @@
1
- // Copyright 2017-2025 @pezkuwi/rpc-provider authors & contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- /// <reference types="@pezkuwi/dev-test/globals.d.ts" />
5
-
6
- import { RpcCoder } from './index.js';
7
-
8
- describe('encodeJson', (): void => {
9
- let coder: RpcCoder;
10
-
11
- beforeEach((): void => {
12
- coder = new RpcCoder();
13
- });
14
-
15
- it('encodes a valid JsonRPC JSON string', (): void => {
16
- expect(
17
- coder.encodeJson('method', ['params'])
18
- ).toEqual([1, '{"id":1,"jsonrpc":"2.0","method":"method","params":["params"]}']);
19
- });
20
- });
@@ -1,25 +0,0 @@
1
- // Copyright 2017-2025 @pezkuwi/rpc-provider authors & contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- /// <reference types="@pezkuwi/dev-test/globals.d.ts" />
5
-
6
- import { RpcCoder } from './index.js';
7
-
8
- describe('encodeObject', (): void => {
9
- let coder: RpcCoder;
10
-
11
- beforeEach((): void => {
12
- coder = new RpcCoder();
13
- });
14
-
15
- it('encodes a valid JsonRPC object', (): void => {
16
- expect(
17
- coder.encodeObject('method', ['a', 'b'])
18
- ).toEqual([1, {
19
- id: 1,
20
- jsonrpc: '2.0',
21
- method: 'method',
22
- params: ['a', 'b']
23
- }]);
24
- });
25
- });
@@ -1,111 +0,0 @@
1
- // Copyright 2017-2025 @pezkuwi/rpc-provider authors & contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- /// <reference types="@pezkuwi/dev-test/globals.d.ts" />
5
-
6
- import { isError } from '@pezkuwi/util';
7
-
8
- import RpcError from './error.js';
9
-
10
- describe('RpcError', (): void => {
11
- describe('constructor', (): void => {
12
- it('constructs an Error that is still an Error', (): void => {
13
- expect(
14
- isError(
15
- new RpcError()
16
- )
17
- ).toEqual(true);
18
- });
19
- });
20
-
21
- describe('static', (): void => {
22
- it('exposes the .CODES as a static', (): void => {
23
- expect(
24
- Object.keys(RpcError.CODES)
25
- ).not.toEqual(0);
26
- });
27
- });
28
-
29
- describe('constructor properties', (): void => {
30
- it('sets the .message property', (): void => {
31
- expect(
32
- new RpcError('test message').message
33
- ).toEqual('test message');
34
- });
35
-
36
- it("sets the .message to '' when not set", (): void => {
37
- expect(
38
- new RpcError().message
39
- ).toEqual('');
40
- });
41
-
42
- it('sets the .code property', (): void => {
43
- expect(
44
- new RpcError('test message', 1234).code
45
- ).toEqual(1234);
46
- });
47
-
48
- it('sets the .code to UKNOWN when not set', (): void => {
49
- expect(
50
- new RpcError('test message').code
51
- ).toEqual(RpcError.CODES.UNKNOWN);
52
- });
53
-
54
- it('sets the .data property', (): void => {
55
- const data = 'here';
56
-
57
- expect(
58
- new RpcError('test message', 1234, data).data
59
- ).toEqual(data);
60
- });
61
-
62
- it('sets the .data property to generic value', (): void => {
63
- const data = { custom: 'value' } as const;
64
-
65
- expect(
66
- new RpcError('test message', 1234, data).data
67
- ).toEqual(data);
68
- });
69
- });
70
-
71
- describe('stack traces', (): void => {
72
- // eslint-disable-next-line @typescript-eslint/ban-types
73
- let captureStackTrace: (targetObject: Record<string, any>, constructorOpt?: Function | undefined) => void;
74
-
75
- beforeEach((): void => {
76
- captureStackTrace = Error.captureStackTrace;
77
-
78
- Error.captureStackTrace = function (error): void {
79
- Object.defineProperty(error, 'stack', {
80
- configurable: true,
81
- get: function getStack (): string {
82
- const value = 'some stack returned';
83
-
84
- Object.defineProperty(this, 'stack', { value });
85
-
86
- return value;
87
- }
88
- });
89
- };
90
- });
91
-
92
- afterEach((): void => {
93
- Error.captureStackTrace = captureStackTrace;
94
- });
95
-
96
- it('captures via captureStackTrace when available', (): void => {
97
- expect(
98
- new RpcError().stack
99
- ).toEqual('some stack returned');
100
- });
101
-
102
- it('captures via stack when captureStackTrace not available', (): void => {
103
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
104
- Error.captureStackTrace = null as any;
105
-
106
- expect(
107
- new RpcError().stack.length
108
- ).not.toEqual(0);
109
- });
110
- });
111
- });