@polkadot-api/substrate-client 0.2.2 → 0.4.0

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 (35) hide show
  1. package/dist/esm/archive/archive.mjs +52 -0
  2. package/dist/esm/archive/archive.mjs.map +1 -0
  3. package/dist/esm/archive/errors.mjs +21 -0
  4. package/dist/esm/archive/errors.mjs.map +1 -0
  5. package/dist/esm/archive/storage-subscription.mjs +55 -0
  6. package/dist/esm/archive/storage-subscription.mjs.map +1 -0
  7. package/dist/esm/archive/storage.mjs +26 -0
  8. package/dist/esm/archive/storage.mjs.map +1 -0
  9. package/dist/esm/chainhead/body.mjs.map +1 -1
  10. package/dist/esm/chainhead/call.mjs.map +1 -1
  11. package/dist/esm/chainhead/chainhead.mjs.map +1 -1
  12. package/dist/esm/chainhead/errors.mjs.map +1 -1
  13. package/dist/esm/chainhead/header.mjs.map +1 -1
  14. package/dist/esm/chainhead/operation-promise.mjs.map +1 -1
  15. package/dist/esm/chainhead/storage-subscription.mjs.map +1 -1
  16. package/dist/esm/chainhead/storage.mjs.map +1 -1
  17. package/dist/esm/chainhead/unpin.mjs.map +1 -1
  18. package/dist/esm/chainspec.mjs.map +1 -1
  19. package/dist/esm/client/DestroyedError.mjs.map +1 -1
  20. package/dist/esm/client/RpcError.mjs.map +1 -1
  21. package/dist/esm/client/createClient.mjs.map +1 -1
  22. package/dist/esm/index.mjs +5 -23
  23. package/dist/esm/index.mjs.map +1 -1
  24. package/dist/esm/internal-utils/abortablePromiseFn.mjs +1 -1
  25. package/dist/esm/internal-utils/abortablePromiseFn.mjs.map +1 -1
  26. package/dist/esm/internal-utils/deferred-promise.mjs.map +1 -1
  27. package/dist/esm/internal-utils/subscriptions-manager.mjs.map +1 -1
  28. package/dist/esm/methods.mjs.map +1 -1
  29. package/dist/esm/substrate-client.mjs +41 -0
  30. package/dist/esm/substrate-client.mjs.map +1 -0
  31. package/dist/esm/transaction/transaction.mjs.map +1 -1
  32. package/dist/index.d.ts +44 -13
  33. package/dist/index.js +286 -129
  34. package/dist/index.js.map +1 -1
  35. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -1,6 +1,13 @@
1
+ export { AbortError } from '@polkadot-api/utils';
1
2
  import { JsonRpcProvider } from '@polkadot-api/json-rpc-provider';
2
3
  export * from '@polkadot-api/json-rpc-provider';
3
- export { AbortError } from '@polkadot-api/utils';
4
+
5
+ type UnsubscribeFn = () => void;
6
+ type WithAbortSignal<T extends Array<any>> = [
7
+ ...args: T,
8
+ abortSignal?: AbortSignal
9
+ ];
10
+ type AbortablePromiseFn<A extends Array<any>, T> = (...args: WithAbortSignal<A>) => Promise<T>;
4
11
 
5
12
  interface IRpcError {
6
13
  code: number;
@@ -13,13 +20,6 @@ declare class RpcError extends Error implements IRpcError {
13
20
  constructor(e: IRpcError);
14
21
  }
15
22
 
16
- type UnsubscribeFn = () => void;
17
- type WithAbortSignal<T extends Array<any>> = [
18
- ...args: T,
19
- abortSignal?: AbortSignal
20
- ];
21
- type AbortablePromiseFn<A extends Array<any>, T> = (...args: WithAbortSignal<A>) => Promise<T>;
22
-
23
23
  interface Subscriber<T> {
24
24
  next: (data: T) => void;
25
25
  error: (e: Error) => void;
@@ -40,6 +40,10 @@ declare class DestroyedError extends Error {
40
40
  constructor();
41
41
  }
42
42
 
43
+ type Transaction = (tx: string, error: (e: Error) => void) => UnsubscribeFn;
44
+
45
+ declare const getTransaction: (request: ClientRequest<string, any>) => (tx: string, error: (e: Error) => void) => () => void;
46
+
43
47
  type FollowInnerSubscriptionCb<T> = (subscriptionId: string, cb: Subscriber<T>) => UnsubscribeFn;
44
48
  type ClientInnerRequestCb<T, TT> = {
45
49
  onSuccess: (result: T, followSubscription: FollowInnerSubscriptionCb<TT>) => void;
@@ -212,10 +216,6 @@ type OperationEventsRpc = OperationBodyDoneRpc | OperationCallDoneRpc | Operatio
212
216
  type FollowEventRpc = FollowEventWithRuntimeRpc | FollowEventWithoutRuntimeRpc | OperationEventsRpc | StopRpc;
213
217
  declare function getChainHead(request: ClientRequest<string, FollowEventRpc>): ChainHead;
214
218
 
215
- type Transaction = (tx: string, error: (e: Error) => void) => UnsubscribeFn;
216
-
217
- declare const getTransaction: (request: ClientRequest<string, any>) => (tx: string, error: (e: Error) => void) => () => void;
218
-
219
219
  interface ChainSpecData {
220
220
  name: string;
221
221
  genesisHash: string;
@@ -223,7 +223,37 @@ interface ChainSpecData {
223
223
  }
224
224
  declare const createGetChainSpec: (clientRequest: ClientRequest<any, any>) => () => Promise<ChainSpecData>;
225
225
 
226
+ type ArchiveStorageItemInput = StorageItemInput & {
227
+ paginationStartKey?: string;
228
+ };
229
+ interface Archive {
230
+ body: AbortablePromiseFn<[hash: string], Array<string>>;
231
+ call: AbortablePromiseFn<[
232
+ hash: string,
233
+ fnName: string,
234
+ callParameters: string
235
+ ], string>;
236
+ header: AbortablePromiseFn<[hash: string], string>;
237
+ finalizedHeight: AbortablePromiseFn<[], number>;
238
+ hashByHeight: AbortablePromiseFn<[height: number], string[]>;
239
+ storage: <Type extends StorageItemInput["type"]>(hash: string, type: Type, key: string, childTrie: string | null, abortSignal?: AbortSignal | undefined) => Promise<StorageResult<Type>>;
240
+ storageSubscription: (hash: string, inputs: Array<ArchiveStorageItemInput>, childTrie: string | null, onItem: (item: StorageItemResponse) => void, onError: (e: Error) => void, onDone: () => void) => () => void;
241
+ }
242
+
243
+ declare class BlockHashNotFoundError extends Error {
244
+ constructor(hash: string);
245
+ }
246
+ declare class StorageError extends Error {
247
+ constructor(message: string);
248
+ }
249
+ declare class CallError extends Error {
250
+ constructor(message: string);
251
+ }
252
+
253
+ declare const getArchive: (request: ClientRequest<any, any>) => Archive;
254
+
226
255
  interface SubstrateClient {
256
+ archive: Archive;
227
257
  chainHead: ChainHead;
228
258
  transaction: Transaction;
229
259
  destroy: UnsubscribeFn;
@@ -233,4 +263,5 @@ interface SubstrateClient {
233
263
  }
234
264
  declare const createClient: (provider: JsonRpcProvider) => SubstrateClient;
235
265
 
236
- export { type AbortablePromiseFn, type BestBlockChanged, type ChainHead, type ChainSpecData, type Client, type ClientInnerRequest, type ClientInnerRequestCb, type ClientRequest, type ClientRequestCb, DestroyedError, DisjointError, type Finalized, type FollowEventWithRuntime, type FollowEventWithoutRuntime, type FollowInnerSubscriptionCb, type FollowResponse, type FollowSubscriptionCb, type IRpcError, type Initialized, type InitializedWithRuntime$1 as InitializedWithRuntime, type NewBlock, type NewBlockWithRuntime$1 as NewBlockWithRuntime, OperationError, OperationInaccessibleError, OperationLimitError, RpcError, type Runtime, StopError, type StorageItemInput, type StorageItemResponse, type StorageResult, type SubstrateClient, type Transaction, type UnsubscribeFn, createClient, createGetChainSpec, getChainHead, getTransaction };
266
+ export { BlockHashNotFoundError, CallError, DestroyedError, DisjointError, OperationError, OperationInaccessibleError, OperationLimitError, RpcError, StopError, StorageError, createClient, createGetChainSpec, getArchive, getChainHead, getTransaction };
267
+ export type { AbortablePromiseFn, Archive, ArchiveStorageItemInput, BestBlockChanged, ChainHead, ChainSpecData, Client, ClientInnerRequest, ClientInnerRequestCb, ClientRequest, ClientRequestCb, Finalized, FollowEventWithRuntime, FollowEventWithoutRuntime, FollowInnerSubscriptionCb, FollowResponse, FollowSubscriptionCb, IRpcError, Initialized, InitializedWithRuntime$1 as InitializedWithRuntime, NewBlock, NewBlockWithRuntime$1 as NewBlockWithRuntime, Runtime, StorageItemInput, StorageItemResponse, StorageResult, SubstrateClient, Transaction, UnsubscribeFn };
package/dist/index.js CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  var utils = require('@polkadot-api/utils');
4
4
 
5
+ var __defProp = Object.defineProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
+ class RpcError extends Error {
9
+ constructor(e) {
10
+ super(e.message);
11
+ __publicField(this, "code");
12
+ __publicField(this, "data");
13
+ this.code = e.code;
14
+ this.data = e.data;
15
+ this.name = "RpcError";
16
+ }
17
+ }
18
+
5
19
  const abortablePromiseFn = (fn) => (...args) => new Promise((res, rej) => {
6
20
  let cancel = utils.noop;
7
21
  const [actualArgs, abortSignal] = args[args.length - 1] instanceof AbortSignal ? [args.slice(0, args.length - 1), args[args.length - 1]] : [args];
@@ -63,49 +77,81 @@ const getSubscriptionsManager = () => {
63
77
  };
64
78
  };
65
79
 
66
- const chainHead = {
67
- body: "",
68
- call: "",
69
- continue: "",
70
- follow: "",
71
- header: "",
72
- stopOperation: "",
73
- storage: "",
74
- unfollow: "",
75
- unpin: "",
76
- followEvent: ""
77
- };
78
- const chainSpec = {
79
- chainName: "",
80
- genesisHash: "",
81
- properties: ""
82
- };
83
- const transaction = {
84
- broadcast: "",
85
- stop: ""
86
- };
87
- Object.entries({ chainHead, chainSpec, transaction }).forEach(
88
- ([fnGroupName, methods]) => {
89
- Object.keys(methods).forEach((methodName) => {
90
- methods[methodName] = `${fnGroupName}_v1_${methodName}`;
91
- });
80
+ class DestroyedError extends Error {
81
+ constructor() {
82
+ super("Client destroyed");
83
+ this.name = "DestroyedError";
92
84
  }
93
- );
85
+ }
94
86
 
95
- const getTransaction = (request) => (tx, error) => {
96
- let cancel = request(transaction.broadcast, [tx], {
97
- onSuccess: (subscriptionId) => {
98
- cancel = subscriptionId === null ? noop : () => {
99
- request(transaction.stop, [subscriptionId]);
100
- };
101
- if (subscriptionId === null) {
102
- error(new Error("Max # of broadcasted transactions has been reached"));
87
+ let nextClientId = 1;
88
+ const createClient$1 = (gProvider) => {
89
+ let clientId = nextClientId++;
90
+ const responses = /* @__PURE__ */ new Map();
91
+ const subscriptions = getSubscriptionsManager();
92
+ let connection = null;
93
+ const send = (id, method, params) => {
94
+ connection.send(
95
+ JSON.stringify({
96
+ jsonrpc: "2.0",
97
+ id,
98
+ method,
99
+ params
100
+ })
101
+ );
102
+ };
103
+ function onMessage(message) {
104
+ try {
105
+ let id, result, error, params, subscription;
106
+ const parsed = JSON.parse(message);
107
+ ({ id, result, error, params } = parsed);
108
+ if (id) {
109
+ const cb = responses.get(id);
110
+ if (!cb) return;
111
+ responses.delete(id);
112
+ return error ? cb.onError(new RpcError(error)) : cb.onSuccess(result, (opaqueId, subscriber) => {
113
+ const subscriptionId2 = opaqueId;
114
+ subscriptions.subscribe(subscriptionId2, subscriber);
115
+ return () => {
116
+ subscriptions.unsubscribe(subscriptionId2);
117
+ };
118
+ });
103
119
  }
104
- },
105
- onError: error
106
- });
107
- return () => {
108
- cancel();
120
+ ;
121
+ ({ subscription, result, error } = params);
122
+ if (!subscription || !error && !Object.hasOwn(params, "result")) throw 0;
123
+ const subscriptionId = subscription;
124
+ if (error) {
125
+ subscriptions.error(subscriptionId, new RpcError(error));
126
+ } else {
127
+ subscriptions.next(subscriptionId, result);
128
+ }
129
+ } catch (e) {
130
+ console.warn("Error parsing incomming message: " + message);
131
+ console.error(e);
132
+ }
133
+ }
134
+ connection = gProvider(onMessage);
135
+ const disconnect = () => {
136
+ connection?.disconnect();
137
+ connection = null;
138
+ subscriptions.errorAll(new DestroyedError());
139
+ responses.forEach((r) => r.onError(new DestroyedError()));
140
+ responses.clear();
141
+ };
142
+ let nextId = 1;
143
+ const request = (method, params, cb) => {
144
+ if (!connection) throw new Error("Not connected");
145
+ const id = `${clientId}-${nextId++}`;
146
+ if (cb) responses.set(id, cb);
147
+ send(id, method, params);
148
+ return () => {
149
+ responses.delete(id);
150
+ };
151
+ };
152
+ return {
153
+ request,
154
+ disconnect
109
155
  };
110
156
  };
111
157
 
@@ -140,6 +186,35 @@ class OperationInaccessibleError extends Error {
140
186
  }
141
187
  }
142
188
 
189
+ const chainHead = {
190
+ body: "",
191
+ call: "",
192
+ continue: "",
193
+ follow: "",
194
+ header: "",
195
+ stopOperation: "",
196
+ storage: "",
197
+ unfollow: "",
198
+ unpin: "",
199
+ followEvent: ""
200
+ };
201
+ const chainSpec = {
202
+ chainName: "",
203
+ genesisHash: "",
204
+ properties: ""
205
+ };
206
+ const transaction = {
207
+ broadcast: "",
208
+ stop: ""
209
+ };
210
+ Object.entries({ chainHead, chainSpec, transaction }).forEach(
211
+ ([fnGroupName, methods]) => {
212
+ Object.keys(methods).forEach((methodName) => {
213
+ methods[methodName] = `${fnGroupName}_v1_${methodName}`;
214
+ });
215
+ }
216
+ );
217
+
143
218
  const createOperationPromise = (operationName, factory) => (request) => abortablePromiseFn((res, rej, ...args) => {
144
219
  let isRunning = true;
145
220
  let cancel = () => {
@@ -218,7 +293,7 @@ const createHeaderFn = (request) => (hash) => new Promise((res, rej) => {
218
293
  });
219
294
  });
220
295
 
221
- const createStorageCb = (request) => (hash, inputs, childTrie, onItems, onError, onDone, onDiscardedItems) => {
296
+ const createStorageCb$1 = (request) => (hash, inputs, childTrie, onItems, onError, onDone, onDiscardedItems) => {
222
297
  if (inputs.length === 0) {
223
298
  onDone();
224
299
  return utils.noop;
@@ -284,8 +359,8 @@ const createStorageCb = (request) => (hash, inputs, childTrie, onItems, onError,
284
359
  };
285
360
  };
286
361
 
287
- const createStorageFn = (request) => {
288
- const cbStore = createStorageCb(request);
362
+ const createStorageFn$1 = (request) => {
363
+ const cbStore = createStorageCb$1(request);
289
364
  return abortablePromiseFn((resolve, reject, hash, type, key, childTrie) => {
290
365
  const isDescendants = type.startsWith("descendants");
291
366
  let result = isDescendants ? [] : null;
@@ -327,13 +402,6 @@ const createUnpinFn = (request) => (hashes) => hashes.length > 0 ? new Promise((
327
402
  });
328
403
  }) : Promise.resolve();
329
404
 
330
- class DestroyedError extends Error {
331
- constructor() {
332
- super("Client destroyed");
333
- this.name = "DestroyedError";
334
- }
335
- }
336
-
337
405
  function isOperationEvent(event) {
338
406
  return event.operationId !== void 0;
339
407
  }
@@ -455,96 +523,164 @@ function getChainHead(request) {
455
523
  body: createBodyFn(fRequest),
456
524
  call: createCallFn(fRequest),
457
525
  header: createHeaderFn(fRequest),
458
- storage: createStorageFn(fRequest),
459
- storageSubscription: createStorageCb(fRequest),
526
+ storage: createStorageFn$1(fRequest),
527
+ storageSubscription: createStorageCb$1(fRequest),
460
528
  unpin: createUnpinFn(fRequest),
461
529
  _request: fRequest
462
530
  };
463
531
  };
464
532
  }
465
533
 
466
- var __defProp = Object.defineProperty;
467
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
468
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
469
- class RpcError extends Error {
470
- constructor(e) {
471
- super(e.message);
472
- __publicField(this, "code");
473
- __publicField(this, "data");
474
- this.code = e.code;
475
- this.data = e.data;
476
- this.name = "RpcError";
534
+ class BlockHashNotFoundError extends Error {
535
+ constructor(hash) {
536
+ super(`Invalid BlockHash: ${hash}`);
537
+ this.name = "BlockHashNotFoundError";
538
+ }
539
+ }
540
+ class StorageError extends Error {
541
+ constructor(message) {
542
+ super(`Storage Error: ${message}`);
543
+ this.name = "StorageError";
544
+ }
545
+ }
546
+ class CallError extends Error {
547
+ constructor(message) {
548
+ super(`Call Error: ${message}`);
549
+ this.name = "CallError";
477
550
  }
478
551
  }
479
552
 
480
- let nextClientId = 1;
481
- const createClient$1 = (gProvider) => {
482
- let clientId = nextClientId++;
483
- const responses = /* @__PURE__ */ new Map();
484
- const subscriptions = getSubscriptionsManager();
485
- let connection = null;
486
- const send = (id, method, params) => {
487
- connection.send(
488
- JSON.stringify({
489
- jsonrpc: "2.0",
490
- id,
491
- method,
492
- params
493
- })
494
- );
495
- };
496
- function onMessage(message) {
497
- try {
498
- let id, result, error, params, subscription;
499
- const parsed = JSON.parse(message);
500
- ({ id, result, error, params } = parsed);
501
- if (id) {
502
- const cb = responses.get(id);
503
- if (!cb) return;
504
- responses.delete(id);
505
- return error ? cb.onError(new RpcError(error)) : cb.onSuccess(result, (opaqueId, subscriber) => {
506
- const subscriptionId2 = opaqueId;
507
- subscriptions.subscribe(subscriptionId2, subscriber);
508
- return () => {
509
- subscriptions.unsubscribe(subscriptionId2);
510
- };
511
- });
512
- }
513
- ;
514
- ({ subscription, result, error } = params);
515
- if (!subscription || !error && !Object.hasOwn(params, "result")) throw 0;
516
- const subscriptionId = subscription;
517
- if (error) {
518
- subscriptions.error(subscriptionId, new RpcError(error));
519
- } else {
520
- subscriptions.next(subscriptionId, result);
521
- }
522
- } catch (e) {
523
- console.warn("Error parsing incomming message: " + message);
524
- console.error(e);
525
- }
553
+ const createStorageCb = (archiveRequest) => (hash, inputs, childTrie, onItem, onError, onDone) => {
554
+ if (inputs.length === 0) {
555
+ onDone();
556
+ return utils.noop;
526
557
  }
527
- connection = gProvider(onMessage);
528
- const disconnect = () => {
529
- connection?.disconnect();
530
- connection = null;
531
- subscriptions.errorAll(new DestroyedError());
532
- responses.forEach((r) => r.onError(new DestroyedError()));
533
- responses.clear();
558
+ let isRunning = true;
559
+ let cancel = () => {
560
+ isRunning = false;
534
561
  };
535
- let nextId = 1;
536
- const request = (method, params, cb) => {
537
- if (!connection) throw new Error("Not connected");
538
- const id = `${clientId}-${nextId++}`;
539
- if (cb) responses.set(id, cb);
540
- send(id, method, params);
541
- return () => {
542
- responses.delete(id);
543
- };
562
+ archiveRequest("storage", [hash, inputs, childTrie], {
563
+ onSuccess: (operationId, followSubscription) => {
564
+ const stopOperation = () => {
565
+ archiveRequest("stopStorage", [operationId]);
566
+ };
567
+ if (!isRunning) return stopOperation();
568
+ const doneListening = followSubscription(operationId, {
569
+ next: (event) => {
570
+ const { event: type } = event;
571
+ if (type === "storage") {
572
+ const { event: _, ...item } = event;
573
+ onItem(item);
574
+ } else if (type === "storageDone") _onDone();
575
+ else _onError(new StorageError(event.error));
576
+ },
577
+ error: onError
578
+ });
579
+ const tearDown = () => {
580
+ cancel = utils.noop;
581
+ doneListening();
582
+ };
583
+ cancel = () => {
584
+ tearDown();
585
+ stopOperation();
586
+ };
587
+ const _onError = (e) => {
588
+ tearDown();
589
+ onError(e);
590
+ };
591
+ const _onDone = () => {
592
+ tearDown();
593
+ onDone();
594
+ };
595
+ },
596
+ onError
597
+ });
598
+ return () => {
599
+ cancel();
544
600
  };
601
+ };
602
+
603
+ const createStorageFn = (cbStore) => abortablePromiseFn((resolve, reject, hash, type, key, childTrie) => {
604
+ const isDescendants = type.startsWith("descendants");
605
+ let result = isDescendants ? [] : null;
606
+ const onItem = isDescendants ? result.push.bind(result) : ({ [type]: res }) => {
607
+ result = res;
608
+ };
609
+ return cbStore(
610
+ hash,
611
+ [{ key, type }],
612
+ childTrie,
613
+ onItem,
614
+ (e) => {
615
+ reject(e);
616
+ result = null;
617
+ },
618
+ () => {
619
+ resolve(result);
620
+ result = null;
621
+ }
622
+ );
623
+ });
624
+
625
+ const identity = () => (x) => x;
626
+ const handleInvalidBlockHash = () => (result, hash) => {
627
+ if (result === null) throw new BlockHashNotFoundError(hash);
628
+ return result;
629
+ };
630
+ const getArchive = (request) => {
631
+ const archiveRequest = (method, ...rest) => request(`archive_v1_${method}`, ...rest);
632
+ const fnCreator = (method) => (mapper) => abortablePromiseFn(
633
+ (res, rej, ...args) => archiveRequest(method, args, {
634
+ onSuccess: (x) => {
635
+ try {
636
+ res(mapper(x, ...args));
637
+ } catch (e) {
638
+ rej(e);
639
+ }
640
+ },
641
+ onError: rej
642
+ })
643
+ );
644
+ const header = fnCreator("header")(
645
+ handleInvalidBlockHash()
646
+ );
647
+ const body = fnCreator("body")(
648
+ handleInvalidBlockHash()
649
+ );
650
+ const storageSubscription = createStorageCb(archiveRequest);
651
+ const storage = createStorageFn(storageSubscription);
652
+ const call = fnCreator("call")((x, hash) => {
653
+ if (!x) throw new BlockHashNotFoundError(hash);
654
+ if (!x.success) throw new CallError(x.error);
655
+ return x.value;
656
+ });
657
+ const finalizedHeight = fnCreator("finalizedHeight")(identity());
658
+ const hashByHeight = fnCreator("hashByHeight")(identity());
545
659
  return {
546
- request,
547
- disconnect
660
+ header,
661
+ body,
662
+ storageSubscription,
663
+ storage,
664
+ call,
665
+ finalizedHeight,
666
+ hashByHeight
667
+ };
668
+ };
669
+
670
+ const getTransaction = (request) => (tx, error) => {
671
+ let cancel = request(transaction.broadcast, [tx], {
672
+ onSuccess: (subscriptionId) => {
673
+ cancel = subscriptionId === null ? noop : () => {
674
+ request(transaction.stop, [subscriptionId]);
675
+ };
676
+ if (subscriptionId === null) {
677
+ error(new Error("Max # of broadcasted transactions has been reached"));
678
+ }
679
+ },
680
+ onError: error
681
+ });
682
+ return () => {
683
+ cancel();
548
684
  };
549
685
  };
550
686
 
@@ -567,24 +703,44 @@ const createGetChainSpec = (clientRequest) => {
567
703
  };
568
704
  };
569
705
 
706
+ const clientCache = /* @__PURE__ */ new Map();
570
707
  const createClient = (provider) => {
708
+ const cached = clientCache.get(provider);
709
+ if (cached) {
710
+ cached.refCount++;
711
+ return cached.client;
712
+ }
571
713
  const { request, disconnect } = createClient$1(provider);
572
- return {
714
+ const destroy = () => {
715
+ const cached2 = clientCache.get(provider);
716
+ if (!cached2 || cached2.refCount <= 1) {
717
+ clientCache.delete(provider);
718
+ disconnect();
719
+ } else {
720
+ cached2.refCount--;
721
+ }
722
+ };
723
+ const client = {
724
+ archive: getArchive(request),
573
725
  chainHead: getChainHead(request),
574
726
  transaction: getTransaction(request),
575
727
  getChainSpecData: createGetChainSpec(request),
576
- destroy: disconnect,
728
+ destroy,
577
729
  request: abortablePromiseFn(
578
730
  (onSuccess, onError, method, params) => request(method, params, { onSuccess, onError })
579
731
  ),
580
732
  _request: request
581
733
  };
734
+ clientCache.set(provider, { client, refCount: 1 });
735
+ return client;
582
736
  };
583
737
 
584
738
  Object.defineProperty(exports, "AbortError", {
585
739
  enumerable: true,
586
740
  get: function () { return utils.AbortError; }
587
741
  });
742
+ exports.BlockHashNotFoundError = BlockHashNotFoundError;
743
+ exports.CallError = CallError;
588
744
  exports.DestroyedError = DestroyedError;
589
745
  exports.DisjointError = DisjointError;
590
746
  exports.OperationError = OperationError;
@@ -592,5 +748,6 @@ exports.OperationInaccessibleError = OperationInaccessibleError;
592
748
  exports.OperationLimitError = OperationLimitError;
593
749
  exports.RpcError = RpcError;
594
750
  exports.StopError = StopError;
751
+ exports.StorageError = StorageError;
595
752
  exports.createClient = createClient;
596
753
  //# sourceMappingURL=index.js.map