@polkadot-api/substrate-client 0.0.2 → 0.1.1

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.
package/dist/index.d.mts CHANGED
@@ -23,7 +23,7 @@ interface Subscriber<T> {
23
23
  error: (e: Error) => void;
24
24
  }
25
25
 
26
- type FollowSubscriptionCb<T> = (methodName: string, subscriptionId: string, cb: Subscriber<T>) => UnsubscribeFn;
26
+ type FollowSubscriptionCb<T> = (subscriptionId: string, cb: Subscriber<T>) => UnsubscribeFn;
27
27
  type ClientRequestCb<T, TT> = {
28
28
  onSuccess: (result: T, followSubscription: FollowSubscriptionCb<TT>) => void;
29
29
  onError: (e: Error) => void;
@@ -215,15 +215,23 @@ declare function getChainHead(request: ClientRequest<string, FollowEventRpc>): C
215
215
 
216
216
  type Transaction = (tx: string, error: (e: Error) => void) => UnsubscribeFn;
217
217
 
218
- declare const getTransaction: (request: ClientRequest<string, any>, rpcMethods: Promise<Set<string>> | Set<string>) => (tx: string, error: (e: Error) => void) => () => void;
218
+ declare const getTransaction: (request: ClientRequest<string, any>) => (tx: string, error: (e: Error) => void) => () => void;
219
+
220
+ interface ChainSpecData {
221
+ name: string;
222
+ genesisHash: string;
223
+ properties: any;
224
+ }
225
+ declare const createGetChainSpec: (clientRequest: ClientRequest<any, any>) => () => Promise<ChainSpecData>;
219
226
 
220
227
  interface SubstrateClient {
221
228
  chainHead: ChainHead;
222
229
  transaction: Transaction;
223
230
  destroy: UnsubscribeFn;
231
+ getChainSpecData: () => Promise<ChainSpecData>;
224
232
  request: <T>(method: string, params: any[], abortSignal?: AbortSignal) => Promise<T>;
225
233
  _request: <Reply, Notification>(method: string, params: any[], cb?: ClientRequestCb<Reply, Notification>) => UnsubscribeFn;
226
234
  }
227
235
  declare const createClient: (provider: JsonRpcProvider) => SubstrateClient;
228
236
 
229
- export { type AbortablePromiseFn, type BestBlockChanged, type ChainHead, 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, getChainHead, getTransaction };
237
+ 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 };
package/dist/index.d.ts CHANGED
@@ -23,7 +23,7 @@ interface Subscriber<T> {
23
23
  error: (e: Error) => void;
24
24
  }
25
25
 
26
- type FollowSubscriptionCb<T> = (methodName: string, subscriptionId: string, cb: Subscriber<T>) => UnsubscribeFn;
26
+ type FollowSubscriptionCb<T> = (subscriptionId: string, cb: Subscriber<T>) => UnsubscribeFn;
27
27
  type ClientRequestCb<T, TT> = {
28
28
  onSuccess: (result: T, followSubscription: FollowSubscriptionCb<TT>) => void;
29
29
  onError: (e: Error) => void;
@@ -215,15 +215,23 @@ declare function getChainHead(request: ClientRequest<string, FollowEventRpc>): C
215
215
 
216
216
  type Transaction = (tx: string, error: (e: Error) => void) => UnsubscribeFn;
217
217
 
218
- declare const getTransaction: (request: ClientRequest<string, any>, rpcMethods: Promise<Set<string>> | Set<string>) => (tx: string, error: (e: Error) => void) => () => void;
218
+ declare const getTransaction: (request: ClientRequest<string, any>) => (tx: string, error: (e: Error) => void) => () => void;
219
+
220
+ interface ChainSpecData {
221
+ name: string;
222
+ genesisHash: string;
223
+ properties: any;
224
+ }
225
+ declare const createGetChainSpec: (clientRequest: ClientRequest<any, any>) => () => Promise<ChainSpecData>;
219
226
 
220
227
  interface SubstrateClient {
221
228
  chainHead: ChainHead;
222
229
  transaction: Transaction;
223
230
  destroy: UnsubscribeFn;
231
+ getChainSpecData: () => Promise<ChainSpecData>;
224
232
  request: <T>(method: string, params: any[], abortSignal?: AbortSignal) => Promise<T>;
225
233
  _request: <Reply, Notification>(method: string, params: any[], cb?: ClientRequestCb<Reply, Notification>) => UnsubscribeFn;
226
234
  }
227
235
  declare const createClient: (provider: JsonRpcProvider) => SubstrateClient;
228
236
 
229
- export { type AbortablePromiseFn, type BestBlockChanged, type ChainHead, 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, getChainHead, getTransaction };
237
+ 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 };
package/dist/index.js CHANGED
@@ -102,43 +102,54 @@ var getSubscriptionsManager = () => {
102
102
  };
103
103
  };
104
104
 
105
- // src/transaction/transaction.ts
106
- var getTxBroadcastNames = (input) => {
107
- if (input.has("transaction_v1_broadcast"))
108
- return ["transaction_v1_broadcast", "transaction_v1_stop"];
109
- if (input.has("transactionWatch_unstable_submitAndWatch"))
110
- return [
111
- "transactionWatch_unstable_submitAndWatch",
112
- "transactionWatch_unstable_unwatch"
113
- ];
114
- return ["transaction_unstable_submitAndWatch", "transaction_unstable_unwatch"];
105
+ // src/methods.ts
106
+ var chainHead = {
107
+ body: "",
108
+ call: "",
109
+ continue: "",
110
+ follow: "",
111
+ header: "",
112
+ stopOperation: "",
113
+ storage: "",
114
+ unfollow: "",
115
+ unpin: "",
116
+ followEvent: ""
117
+ };
118
+ var chainSpec = {
119
+ chainName: "",
120
+ genesisHash: "",
121
+ properties: ""
122
+ };
123
+ var transaction = {
124
+ broadcast: "",
125
+ stop: ""
126
+ };
127
+ var transactionWatch = {
128
+ submitAndWatch: "",
129
+ unwatch: ""
115
130
  };
116
- var getTransaction = (request, rpcMethods) => (tx, error) => {
117
- const broadcast = (tx2, broadcastFn, cancelBroadcastFn) => request(broadcastFn, [tx2], {
131
+ Object.entries({ chainHead, chainSpec, transaction, transactionWatch }).forEach(
132
+ ([fnGroupName, methods]) => {
133
+ Object.keys(methods).forEach((methodName) => {
134
+ ;
135
+ methods[methodName] = `${fnGroupName}_v1_${methodName}`;
136
+ });
137
+ }
138
+ );
139
+
140
+ // src/transaction/transaction.ts
141
+ var getTransaction = (request) => (tx, error) => {
142
+ let cancel = request(transaction.broadcast, [tx], {
118
143
  onSuccess: (subscriptionId) => {
119
144
  cancel = subscriptionId === null ? noop2 : () => {
120
- request(cancelBroadcastFn, [subscriptionId]);
145
+ request(transaction.stop, [subscriptionId]);
121
146
  };
122
147
  if (subscriptionId === null) {
123
- error(
124
- new Error("Max # of broadcasted transactions has been reached")
125
- );
148
+ error(new Error("Max # of broadcasted transactions has been reached"));
126
149
  }
127
150
  },
128
151
  onError: error
129
152
  });
130
- let isActive = true;
131
- let cancel = () => {
132
- isActive = false;
133
- };
134
- if (rpcMethods instanceof Promise) {
135
- rpcMethods.then(getTxBroadcastNames).then((names) => {
136
- if (!isActive)
137
- return;
138
- cancel = broadcast(tx, ...names);
139
- });
140
- } else
141
- cancel = broadcast(tx, ...getTxBroadcastNames(rpcMethods));
142
153
  return () => {
143
154
  cancel();
144
155
  };
@@ -214,7 +225,7 @@ var createOperationPromise = (operationName, factory) => (request) => abortableP
214
225
  if (!isOperationGoing)
215
226
  return;
216
227
  done();
217
- request("chainHead_unstable_stopOperation", [response.operationId]);
228
+ request(chainHead.stopOperation, [response.operationId]);
218
229
  };
219
230
  },
220
231
  onError: rej
@@ -226,7 +237,7 @@ var createOperationPromise = (operationName, factory) => (request) => abortableP
226
237
 
227
238
  // src/chainhead/body.ts
228
239
  var createBodyFn = createOperationPromise(
229
- "chainHead_unstable_body",
240
+ chainHead.body,
230
241
  (hash) => [
231
242
  [hash],
232
243
  (e, res) => {
@@ -237,7 +248,7 @@ var createBodyFn = createOperationPromise(
237
248
 
238
249
  // src/chainhead/call.ts
239
250
  var createCallFn = createOperationPromise(
240
- "chainHead_unstable_call",
251
+ chainHead.call,
241
252
  (hash, fnName, callParameters) => [
242
253
  [hash, fnName, callParameters],
243
254
  (e, res) => {
@@ -248,7 +259,7 @@ var createCallFn = createOperationPromise(
248
259
 
249
260
  // src/chainhead/header.ts
250
261
  var createHeaderFn = (request) => (hash) => new Promise((res, rej) => {
251
- request("chainHead_unstable_header", [hash], {
262
+ request(chainHead.header, [hash], {
252
263
  onSuccess: res,
253
264
  onError: rej
254
265
  });
@@ -261,57 +272,53 @@ var createStorageCb = (request) => (hash, inputs, childTrie, onItems, onError, o
261
272
  onDone();
262
273
  return import_utils2.noop;
263
274
  }
264
- let cancel = request(
265
- "chainHead_unstable_storage",
266
- [hash, inputs, childTrie],
267
- {
268
- onSuccess: (response, followSubscription) => {
269
- if (response.result === "limitReached" || response.discardedItems === inputs.length)
270
- return onError(new OperationLimitError());
271
- const doneListening = followSubscription(response.operationId, {
272
- next: (event) => {
273
- switch (event.event) {
274
- case "operationStorageItems": {
275
- onItems(event.items);
276
- break;
277
- }
278
- case "operationStorageDone": {
279
- _onDone();
280
- break;
281
- }
282
- case "operationError": {
283
- _onError(new OperationError(event.error));
284
- break;
285
- }
286
- case "operationInaccessible": {
287
- _onError(new OperationInaccessibleError());
288
- break;
289
- }
290
- default:
291
- request("chainHead_unstable_continue", [event.operationId]);
275
+ let cancel = request(chainHead.storage, [hash, inputs, childTrie], {
276
+ onSuccess: (response, followSubscription) => {
277
+ if (response.result === "limitReached" || response.discardedItems === inputs.length)
278
+ return onError(new OperationLimitError());
279
+ const doneListening = followSubscription(response.operationId, {
280
+ next: (event) => {
281
+ switch (event.event) {
282
+ case "operationStorageItems": {
283
+ onItems(event.items);
284
+ break;
292
285
  }
293
- },
294
- error: onError
295
- });
296
- cancel = () => {
297
- doneListening();
298
- request("chainHead_unstable_stopOperation", [response.operationId]);
299
- };
300
- const _onError = (e) => {
301
- cancel = import_utils2.noop;
302
- doneListening();
303
- onError(e);
304
- };
305
- const _onDone = () => {
306
- cancel = import_utils2.noop;
307
- doneListening();
308
- onDone();
309
- };
310
- onDiscardedItems(response.discardedItems);
311
- },
312
- onError
313
- }
314
- );
286
+ case "operationStorageDone": {
287
+ _onDone();
288
+ break;
289
+ }
290
+ case "operationError": {
291
+ _onError(new OperationError(event.error));
292
+ break;
293
+ }
294
+ case "operationInaccessible": {
295
+ _onError(new OperationInaccessibleError());
296
+ break;
297
+ }
298
+ default:
299
+ request(chainHead.continue, [event.operationId]);
300
+ }
301
+ },
302
+ error: onError
303
+ });
304
+ cancel = () => {
305
+ doneListening();
306
+ request(chainHead.stopOperation, [response.operationId]);
307
+ };
308
+ const _onError = (e) => {
309
+ cancel = import_utils2.noop;
310
+ doneListening();
311
+ onError(e);
312
+ };
313
+ const _onDone = () => {
314
+ cancel = import_utils2.noop;
315
+ doneListening();
316
+ onDone();
317
+ };
318
+ onDiscardedItems(response.discardedItems);
319
+ },
320
+ onError
321
+ });
315
322
  return () => {
316
323
  cancel();
317
324
  };
@@ -354,7 +361,7 @@ var createStorageFn = (request) => {
354
361
 
355
362
  // src/chainhead/unpin.ts
356
363
  var createUnpinFn = (request) => (hashes) => hashes.length > 0 ? new Promise((res, rej) => {
357
- request("chainHead_unstable_unpin", [hashes], {
364
+ request(chainHead.unpin, [hashes], {
358
365
  onSuccess() {
359
366
  res();
360
367
  },
@@ -405,7 +412,7 @@ function getChainHead(request) {
405
412
  unfollow(!(error instanceof DestroyedError));
406
413
  };
407
414
  const onFollowRequestSuccess = (subscriptionId, follow) => {
408
- const done = follow("chainHead_unstable_followEvent", subscriptionId, {
415
+ const done = follow(subscriptionId, {
409
416
  next: onAllFollowEventsNext,
410
417
  error: onAllFollowEventsError
411
418
  });
@@ -413,7 +420,7 @@ function getChainHead(request) {
413
420
  followSubscription = null;
414
421
  unfollow = noop2;
415
422
  done();
416
- sendUnfollow && request("chainHead_unstable_unfollow", [subscriptionId]);
423
+ sendUnfollow && request(chainHead.unfollow, [subscriptionId]);
417
424
  subscriptions.errorAll(new DisjointError());
418
425
  ongoingRequests.forEach((cb) => {
419
426
  cb();
@@ -433,7 +440,7 @@ function getChainHead(request) {
433
440
  deferredFollow.res(e);
434
441
  };
435
442
  let unfollow = request(
436
- "chainHead_unstable_follow",
443
+ chainHead.follow,
437
444
  [withRuntime],
438
445
  { onSuccess: onFollowRequestSuccess, onError: onFollowRequestError }
439
446
  );
@@ -542,8 +549,8 @@ var createClient = (gProvider) => {
542
549
  if (!cb)
543
550
  return;
544
551
  responses.delete(id);
545
- return error ? cb.onError(new RpcError(error)) : cb.onSuccess(result, (methodName, opaqueId, subscriber) => {
546
- const subscriptionId2 = methodName + opaqueId;
552
+ return error ? cb.onError(new RpcError(error)) : cb.onSuccess(result, (opaqueId, subscriber) => {
553
+ const subscriptionId2 = opaqueId;
547
554
  subscriptions.subscribe(subscriptionId2, subscriber);
548
555
  return () => {
549
556
  subscriptions.unsubscribe(subscriptionId2);
@@ -554,7 +561,7 @@ var createClient = (gProvider) => {
554
561
  ({ subscription, result, error } = params);
555
562
  if (!subscription || !error && !Object.hasOwn(params, "result"))
556
563
  throw 0;
557
- const subscriptionId = parsed.method + subscription;
564
+ const subscriptionId = subscription;
558
565
  if (error) {
559
566
  subscriptions.error(subscriptionId, new RpcError(error));
560
567
  } else {
@@ -591,21 +598,105 @@ var createClient = (gProvider) => {
591
598
  };
592
599
  };
593
600
 
601
+ // src/chainspec.ts
602
+ var createGetChainSpec = (clientRequest) => {
603
+ const request = abortablePromiseFn(
604
+ (onSuccess, onError, method, params) => clientRequest(method, params, { onSuccess, onError })
605
+ );
606
+ let cachedPromise = null;
607
+ return async () => {
608
+ if (cachedPromise)
609
+ return cachedPromise;
610
+ return cachedPromise = Promise.all([
611
+ request(chainSpec.chainName, []),
612
+ request(chainSpec.genesisHash, []),
613
+ request(chainSpec.properties, [])
614
+ ]).then(([name, genesisHash, properties]) => ({
615
+ name,
616
+ genesisHash,
617
+ properties
618
+ }));
619
+ };
620
+ };
621
+
622
+ // src/request-compatibility-enhancer.ts
623
+ var getCompatibilityEnhancer = (rpcMethodsP, request) => (methods) => {
624
+ let translations = {};
625
+ let enhancedRequest = null;
626
+ return (method, ...rest) => {
627
+ if (enhancedRequest)
628
+ return enhancedRequest(method, ...rest);
629
+ let isRunning = true;
630
+ let cleanup = () => {
631
+ isRunning = false;
632
+ };
633
+ rpcMethodsP.then((rpcMethods) => {
634
+ enhancedRequest = (method_, ...iRest) => {
635
+ const method2 = translations[method_] ?? method_;
636
+ if (rpcMethods.has(method2))
637
+ return request(method2, ...iRest);
638
+ iRest[1]?.onError(new Error(`Unsupported method ${method2}`));
639
+ return noop2;
640
+ };
641
+ if (rpcMethods.has(method))
642
+ return;
643
+ const parts = method.split("_");
644
+ if (parts[1] !== "v1")
645
+ return;
646
+ parts[1] = "unstable";
647
+ if (rpcMethods.has(parts.join("_")))
648
+ Object.values(methods).forEach((value) => {
649
+ translations[value] = value.replace("_v1_", "_unstable_");
650
+ });
651
+ else if (parts[0] === "transaction") {
652
+ let unwatch;
653
+ let version;
654
+ const txGroup = ["transactionWatch", "transaction"].find(
655
+ (group) => {
656
+ version = ["v1", "unstable"].find(
657
+ (v) => rpcMethods.has(unwatch = `${group}_${v}_unwatch`)
658
+ );
659
+ return !!version;
660
+ }
661
+ );
662
+ if (txGroup) {
663
+ translations[methods.broadcast] = `${txGroup}_${version}_submitAndWatch`;
664
+ translations[methods.stop] = unwatch;
665
+ }
666
+ }
667
+ }).then(() => {
668
+ if (isRunning)
669
+ cleanup = enhancedRequest(method, ...rest);
670
+ });
671
+ return () => {
672
+ cleanup();
673
+ };
674
+ };
675
+ };
676
+
594
677
  // src/index.ts
595
678
  var createClient2 = (provider) => {
596
679
  const client = createClient(provider);
597
680
  const request = abortablePromiseFn(
598
681
  (onSuccess, onError, method, params) => client.request(method, params, { onSuccess, onError })
599
682
  );
600
- let rpcMethods = request("rpc_methods", []).then(
601
- (x) => rpcMethods = new Set(Array.isArray(x) ? x : x.methods)
683
+ const rpcMethods = request("rpc_methods", []).then(
684
+ (x) => new Set(Array.isArray(x) ? x : x.methods),
685
+ () => /* @__PURE__ */ new Set()
686
+ );
687
+ const compatibilityEnhancer = getCompatibilityEnhancer(
688
+ rpcMethods,
689
+ client.request
602
690
  );
603
- rpcMethods.catch(noop2);
604
691
  return {
605
- chainHead: getChainHead(client.request),
692
+ chainHead: getChainHead(
693
+ compatibilityEnhancer(chainHead)
694
+ ),
606
695
  transaction: getTransaction(
607
- client.request,
608
- rpcMethods
696
+ compatibilityEnhancer(transaction)
697
+ ),
698
+ getChainSpecData: createGetChainSpec(
699
+ compatibilityEnhancer(chainSpec)
609
700
  ),
610
701
  destroy: () => {
611
702
  client.disconnect();