@dedot/api 0.8.2-next.6cfafabd.24 → 0.9.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/cjs/client/BaseSubstrateClient.js +9 -10
- package/cjs/client/DedotClient.js +9 -0
- package/cjs/client/LegacyClient.js +11 -2
- package/cjs/extrinsic/submittable/SubmittableExtrinsicV2.js +2 -2
- package/cjs/storage/LegacyStorageQuery.js +7 -5
- package/cjs/storage/NewStorageQuery.js +4 -4
- package/client/BaseSubstrateClient.d.ts +3 -1
- package/client/BaseSubstrateClient.js +10 -11
- package/client/DedotClient.d.ts +5 -3
- package/client/DedotClient.js +10 -1
- package/client/LegacyClient.d.ts +3 -1
- package/client/LegacyClient.js +11 -2
- package/extrinsic/submittable/SubmittableExtrinsicV2.js +2 -2
- package/package.json +9 -9
- package/storage/LegacyStorageQuery.js +7 -5
- package/storage/NewStorageQuery.js +4 -4
- package/types.d.ts +2 -0
|
@@ -197,9 +197,12 @@ class BaseSubstrateClient extends index_js_2.JsonRpcClient {
|
|
|
197
197
|
await this._localCache?.clear();
|
|
198
198
|
}
|
|
199
199
|
async doConnect() {
|
|
200
|
+
// @ts-ignore
|
|
200
201
|
this.on('connected', this.onConnected);
|
|
202
|
+
// @ts-ignore
|
|
201
203
|
this.on('disconnected', this.onDisconnected);
|
|
202
204
|
return new Promise((resolve) => {
|
|
205
|
+
// @ts-ignore
|
|
203
206
|
this.once('ready', () => {
|
|
204
207
|
resolve(this);
|
|
205
208
|
});
|
|
@@ -212,6 +215,7 @@ class BaseSubstrateClient extends index_js_2.JsonRpcClient {
|
|
|
212
215
|
async initialize() {
|
|
213
216
|
await this.initializeLocalCache();
|
|
214
217
|
await this.doInitialize();
|
|
218
|
+
// @ts-ignore
|
|
215
219
|
this.emit('ready');
|
|
216
220
|
}
|
|
217
221
|
async doInitialize() {
|
|
@@ -318,24 +322,19 @@ class BaseSubstrateClient extends index_js_2.JsonRpcClient {
|
|
|
318
322
|
// Decode the value
|
|
319
323
|
return entry.decodeValue(rawValue);
|
|
320
324
|
};
|
|
321
|
-
// Create service directly when needed
|
|
322
|
-
let service;
|
|
323
|
-
if (this.rpcVersion === 'v2') {
|
|
324
|
-
service = new index_js_3.NewStorageQuery(this);
|
|
325
|
-
}
|
|
326
|
-
else {
|
|
327
|
-
service = new index_js_3.LegacyStorageQuery(this);
|
|
328
|
-
}
|
|
329
325
|
// If a callback is provided, set up a subscription
|
|
330
326
|
if (callback) {
|
|
331
|
-
return
|
|
327
|
+
return this.getStorageQuery().subscribe(keys, (results) => {
|
|
332
328
|
callback(queries.map((q, i) => decodeValue(q.fn, results[keys[i]])));
|
|
333
329
|
});
|
|
334
330
|
}
|
|
335
331
|
else {
|
|
336
|
-
const results = await
|
|
332
|
+
const results = await this.getStorageQuery().query(keys);
|
|
337
333
|
return queries.map((q, i) => decodeValue(q.fn, results[keys[i]]));
|
|
338
334
|
}
|
|
339
335
|
}
|
|
336
|
+
getStorageQuery() {
|
|
337
|
+
throw new Error('Unimplemented!');
|
|
338
|
+
}
|
|
340
339
|
}
|
|
341
340
|
exports.BaseSubstrateClient = BaseSubstrateClient;
|
|
@@ -7,6 +7,7 @@ const utils_1 = require("@dedot/utils");
|
|
|
7
7
|
const index_js_1 = require("../executor/index.js");
|
|
8
8
|
const index_js_2 = require("../json-rpc/index.js");
|
|
9
9
|
const proxychain_js_1 = require("../proxychain.js");
|
|
10
|
+
const index_js_3 = require("../storage/index.js");
|
|
10
11
|
const BaseSubstrateClient_js_1 = require("./BaseSubstrateClient.js");
|
|
11
12
|
/**
|
|
12
13
|
* @name DedotClient
|
|
@@ -84,6 +85,11 @@ class DedotClient// prettier-end-here
|
|
|
84
85
|
}
|
|
85
86
|
await this.setupMetadata(metadata);
|
|
86
87
|
this.subscribeRuntimeUpgrades();
|
|
88
|
+
// relegate events
|
|
89
|
+
this.chainHead.on('newBlock', (...args) => this.emit('newBlock', ...args));
|
|
90
|
+
this.chainHead.on('bestBlock', (...args) => this.emit('bestBlock', ...args));
|
|
91
|
+
this.chainHead.on('finalizedBlock', (...args) => this.emit('finalizedBlock', ...args));
|
|
92
|
+
this.chainHead.on('bestChainChanged', (...args) => this.emit('bestChainChanged', ...args));
|
|
87
93
|
}
|
|
88
94
|
/**
|
|
89
95
|
* Ref: https://github.com/paritytech/polkadot-sdk/blob/bbd51ce867967f71657b901f1a956ad4f75d352e/substrate/frame/system/src/lib.rs#L909-L913
|
|
@@ -183,5 +189,8 @@ class DedotClient// prettier-end-here
|
|
|
183
189
|
this.#apiAtCache[hash] = api;
|
|
184
190
|
return api;
|
|
185
191
|
}
|
|
192
|
+
getStorageQuery() {
|
|
193
|
+
return new index_js_3.NewStorageQuery(this);
|
|
194
|
+
}
|
|
186
195
|
}
|
|
187
196
|
exports.DedotClient = DedotClient;
|
|
@@ -4,6 +4,7 @@ exports.LegacyClient = void 0;
|
|
|
4
4
|
const codecs_1 = require("@dedot/codecs");
|
|
5
5
|
const index_js_1 = require("../executor/index.js");
|
|
6
6
|
const proxychain_js_1 = require("../proxychain.js");
|
|
7
|
+
const index_js_2 = require("../storage/index.js");
|
|
7
8
|
const BaseSubstrateClient_js_1 = require("./BaseSubstrateClient.js");
|
|
8
9
|
const KEEP_ALIVE_INTERVAL = 10_000; // in ms
|
|
9
10
|
/**
|
|
@@ -137,8 +138,13 @@ class LegacyClient// prettier-end-here
|
|
|
137
138
|
if (!this.#runtimeSubscriptionUnsub) {
|
|
138
139
|
return;
|
|
139
140
|
}
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
try {
|
|
142
|
+
await this.#runtimeSubscriptionUnsub();
|
|
143
|
+
this.#runtimeSubscriptionUnsub = undefined;
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// ignore
|
|
147
|
+
}
|
|
142
148
|
}
|
|
143
149
|
#subscribeUpdates() {
|
|
144
150
|
this.#subscribeRuntimeUpgrades();
|
|
@@ -250,5 +256,8 @@ class LegacyClient// prettier-end-here
|
|
|
250
256
|
this.#apiAtCache[hash] = api;
|
|
251
257
|
return api;
|
|
252
258
|
}
|
|
259
|
+
getStorageQuery() {
|
|
260
|
+
return new index_js_2.LegacyStorageQuery(this);
|
|
261
|
+
}
|
|
253
262
|
}
|
|
254
263
|
exports.LegacyClient = LegacyClient;
|
|
@@ -163,8 +163,8 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
163
163
|
status: { type: 'Broadcasting' },
|
|
164
164
|
txHash,
|
|
165
165
|
}));
|
|
166
|
-
const stopBestBlockTrackingFn = api.
|
|
167
|
-
const stopFinalizedBlockTrackingFn = api.
|
|
166
|
+
const stopBestBlockTrackingFn = api.on('bestBlock', checkBestBlockIncluded);
|
|
167
|
+
const stopFinalizedBlockTrackingFn = api.on('finalizedBlock', checkFinalizedBlockIncluded);
|
|
168
168
|
const stopTracking = () => {
|
|
169
169
|
stopBestBlockTrackingFn();
|
|
170
170
|
stopFinalizedBlockTrackingFn();
|
|
@@ -23,14 +23,15 @@ class LegacyStorageQuery extends BaseStorageQuery_js_1.BaseStorageQuery {
|
|
|
23
23
|
* @returns Promise resolving to a record mapping storage keys to their values
|
|
24
24
|
*/
|
|
25
25
|
async query(keys, at) {
|
|
26
|
+
const client = this.client;
|
|
26
27
|
// Query storage at the specified block or current block
|
|
27
28
|
const changeSets = at
|
|
28
|
-
? await
|
|
29
|
-
: await
|
|
29
|
+
? await client.rpc.state_queryStorageAt(keys, at)
|
|
30
|
+
: await client.rpc.state_queryStorageAt(keys);
|
|
30
31
|
// Create a map of key -> value for easy lookup
|
|
31
32
|
const results = {};
|
|
32
33
|
// Initialize all keys with undefined
|
|
33
|
-
keys.forEach(key => results[key] = undefined);
|
|
34
|
+
keys.forEach((key) => (results[key] = undefined));
|
|
34
35
|
// Update with actual values from the response
|
|
35
36
|
if (changeSets && changeSets.length > 0) {
|
|
36
37
|
changeSets[0].changes.forEach(([key, value]) => {
|
|
@@ -50,9 +51,10 @@ class LegacyStorageQuery extends BaseStorageQuery_js_1.BaseStorageQuery {
|
|
|
50
51
|
// Track the latest changes for each key
|
|
51
52
|
const lastChanges = {};
|
|
52
53
|
// Initialize all keys with undefined
|
|
53
|
-
keys.forEach(key => lastChanges[key] = undefined);
|
|
54
|
+
keys.forEach((key) => (lastChanges[key] = undefined));
|
|
54
55
|
// Subscribe to storage changes
|
|
55
|
-
|
|
56
|
+
const client = this.client;
|
|
57
|
+
return client.rpc.state_subscribeStorage(keys, (changeSet) => {
|
|
56
58
|
// Update the latest changes
|
|
57
59
|
changeSet.changes.forEach(([key, value]) => {
|
|
58
60
|
if (lastChanges[key] !== value) {
|
|
@@ -24,7 +24,7 @@ class NewStorageQuery extends BaseStorageQuery_js_1.BaseStorageQuery {
|
|
|
24
24
|
*/
|
|
25
25
|
async query(keys, at) {
|
|
26
26
|
// Query storage using ChainHead API
|
|
27
|
-
const storageQueries = keys.map(key => ({ type: 'value', key }));
|
|
27
|
+
const storageQueries = keys.map((key) => ({ type: 'value', key }));
|
|
28
28
|
// Use the provided block hash or skip it in tests
|
|
29
29
|
const rawResults = at
|
|
30
30
|
? await this.client.chainHead.storage(storageQueries, undefined, at)
|
|
@@ -32,7 +32,7 @@ class NewStorageQuery extends BaseStorageQuery_js_1.BaseStorageQuery {
|
|
|
32
32
|
// Create a map of key -> value for easy lookup
|
|
33
33
|
const results = {};
|
|
34
34
|
// Initialize all keys with undefined
|
|
35
|
-
keys.forEach(key => results[key] = undefined);
|
|
35
|
+
keys.forEach((key) => (results[key] = undefined));
|
|
36
36
|
// Update with actual values from the response
|
|
37
37
|
rawResults.forEach((result) => {
|
|
38
38
|
results[result.key] = result.value ?? undefined;
|
|
@@ -54,7 +54,7 @@ class NewStorageQuery extends BaseStorageQuery_js_1.BaseStorageQuery {
|
|
|
54
54
|
// Function to pull storage values and call the callback if there are changes
|
|
55
55
|
const pull = async ({ hash }) => {
|
|
56
56
|
// Query storage using ChainHead API
|
|
57
|
-
const storageQueries = keys.map(key => ({ type: 'value', key }));
|
|
57
|
+
const storageQueries = keys.map((key) => ({ type: 'value', key }));
|
|
58
58
|
const rawResults = await this.client.chainHead.storage(storageQueries, undefined, hash);
|
|
59
59
|
let changed = false;
|
|
60
60
|
// Create a map for easy lookup
|
|
@@ -76,7 +76,7 @@ class NewStorageQuery extends BaseStorageQuery_js_1.BaseStorageQuery {
|
|
|
76
76
|
// Initial pull
|
|
77
77
|
await pull(best);
|
|
78
78
|
// Subscribe to best block events
|
|
79
|
-
const unsub = this.client.
|
|
79
|
+
const unsub = this.client.on('bestBlock', pull);
|
|
80
80
|
return async () => {
|
|
81
81
|
unsub();
|
|
82
82
|
};
|
|
@@ -5,13 +5,14 @@ import { Callback, GenericStorageQuery, GenericSubstrateApi, InjectedSigner, Que
|
|
|
5
5
|
import { Deferred } from '@dedot/utils';
|
|
6
6
|
import type { SubstrateApi } from '../chaintypes/index.js';
|
|
7
7
|
import { JsonRpcClient } from '../json-rpc/index.js';
|
|
8
|
+
import { BaseStorageQuery } from '../storage/index.js';
|
|
8
9
|
import type { ApiEvent, ApiOptions, ISubstrateClient, ISubstrateClientAt, JsonRpcClientOptions, MetadataKey, SubstrateRuntimeVersion } from '../types.js';
|
|
9
10
|
export declare function ensurePresence<T>(value: T): NonNullable<T>;
|
|
10
11
|
/**
|
|
11
12
|
* @name BaseSubstrateClient
|
|
12
13
|
* @description Base & shared abstraction for Substrate API Clients
|
|
13
14
|
*/
|
|
14
|
-
export declare abstract class BaseSubstrateClient<Rv extends RpcVersion, ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> extends JsonRpcClient<ChainApi,
|
|
15
|
+
export declare abstract class BaseSubstrateClient<Rv extends RpcVersion, ChainApi extends VersionedGenericSubstrateApi = SubstrateApi, Events extends string = ApiEvent> extends JsonRpcClient<ChainApi, Events> implements ISubstrateClient<ChainApi[Rv], Events> {
|
|
15
16
|
rpcVersion: RpcVersion;
|
|
16
17
|
protected _options: ApiOptions;
|
|
17
18
|
protected _registry?: PortableRegistry;
|
|
@@ -104,4 +105,5 @@ export declare abstract class BaseSubstrateClient<Rv extends RpcVersion, ChainAp
|
|
|
104
105
|
}, callback: Callback<{
|
|
105
106
|
[K in keyof Fns]: QueryFnResult<Fns[K]>;
|
|
106
107
|
}>): Promise<Unsub>;
|
|
108
|
+
protected getStorageQuery(): BaseStorageQuery<RpcVersion>;
|
|
107
109
|
}
|
|
@@ -4,7 +4,7 @@ import { calcRuntimeApiHash, deferred, ensurePresence as _ensurePresence, u8aToH
|
|
|
4
4
|
import { ConstantExecutor, ErrorExecutor, EventExecutor } from '../executor/index.js';
|
|
5
5
|
import { isJsonRpcProvider, JsonRpcClient } from '../json-rpc/index.js';
|
|
6
6
|
import { newProxyChain } from '../proxychain.js';
|
|
7
|
-
import {
|
|
7
|
+
import { QueryableStorage } from '../storage/index.js';
|
|
8
8
|
const SUPPORTED_METADATA_VERSIONS = [15, 14];
|
|
9
9
|
const MetadataApiHash = calcRuntimeApiHash('Metadata'); // 0x37e397fc7c91f5e4
|
|
10
10
|
const MESSAGE = 'Make sure to call `.connect()` method first before using the API interfaces.';
|
|
@@ -193,9 +193,12 @@ export class BaseSubstrateClient extends JsonRpcClient {
|
|
|
193
193
|
await this._localCache?.clear();
|
|
194
194
|
}
|
|
195
195
|
async doConnect() {
|
|
196
|
+
// @ts-ignore
|
|
196
197
|
this.on('connected', this.onConnected);
|
|
198
|
+
// @ts-ignore
|
|
197
199
|
this.on('disconnected', this.onDisconnected);
|
|
198
200
|
return new Promise((resolve) => {
|
|
201
|
+
// @ts-ignore
|
|
199
202
|
this.once('ready', () => {
|
|
200
203
|
resolve(this);
|
|
201
204
|
});
|
|
@@ -208,6 +211,7 @@ export class BaseSubstrateClient extends JsonRpcClient {
|
|
|
208
211
|
async initialize() {
|
|
209
212
|
await this.initializeLocalCache();
|
|
210
213
|
await this.doInitialize();
|
|
214
|
+
// @ts-ignore
|
|
211
215
|
this.emit('ready');
|
|
212
216
|
}
|
|
213
217
|
async doInitialize() {
|
|
@@ -314,23 +318,18 @@ export class BaseSubstrateClient extends JsonRpcClient {
|
|
|
314
318
|
// Decode the value
|
|
315
319
|
return entry.decodeValue(rawValue);
|
|
316
320
|
};
|
|
317
|
-
// Create service directly when needed
|
|
318
|
-
let service;
|
|
319
|
-
if (this.rpcVersion === 'v2') {
|
|
320
|
-
service = new NewStorageQuery(this);
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
service = new LegacyStorageQuery(this);
|
|
324
|
-
}
|
|
325
321
|
// If a callback is provided, set up a subscription
|
|
326
322
|
if (callback) {
|
|
327
|
-
return
|
|
323
|
+
return this.getStorageQuery().subscribe(keys, (results) => {
|
|
328
324
|
callback(queries.map((q, i) => decodeValue(q.fn, results[keys[i]])));
|
|
329
325
|
});
|
|
330
326
|
}
|
|
331
327
|
else {
|
|
332
|
-
const results = await
|
|
328
|
+
const results = await this.getStorageQuery().query(keys);
|
|
333
329
|
return queries.map((q, i) => decodeValue(q.fn, results[keys[i]]));
|
|
334
330
|
}
|
|
335
331
|
}
|
|
332
|
+
getStorageQuery() {
|
|
333
|
+
throw new Error('Unimplemented!');
|
|
334
|
+
}
|
|
336
335
|
}
|
package/client/DedotClient.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { BlockHash } from '@dedot/codecs';
|
|
2
2
|
import type { JsonRpcProvider } from '@dedot/providers';
|
|
3
|
-
import { GenericSubstrateApi, RpcV2, VersionedGenericSubstrateApi } from '@dedot/types';
|
|
3
|
+
import { GenericSubstrateApi, RpcV2, RpcVersion, VersionedGenericSubstrateApi } from '@dedot/types';
|
|
4
4
|
import type { SubstrateApi } from '../chaintypes/index.js';
|
|
5
5
|
import { ChainHead, ChainSpec, PinnedBlock } from '../json-rpc/index.js';
|
|
6
|
-
import
|
|
6
|
+
import { BaseStorageQuery } from '../storage/index.js';
|
|
7
|
+
import type { ApiOptions, DedotClientEvent, ISubstrateClientAt, TxBroadcaster } from '../types.js';
|
|
7
8
|
import { BaseSubstrateClient } from './BaseSubstrateClient.js';
|
|
8
9
|
/**
|
|
9
10
|
* @name DedotClient
|
|
@@ -12,7 +13,7 @@ import { BaseSubstrateClient } from './BaseSubstrateClient.js';
|
|
|
12
13
|
* __Unstable, use with caution.__
|
|
13
14
|
*/
|
|
14
15
|
export declare class DedotClient<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi>// prettier-end-here
|
|
15
|
-
extends BaseSubstrateClient<RpcV2, ChainApi> {
|
|
16
|
+
extends BaseSubstrateClient<RpcV2, ChainApi, DedotClientEvent> {
|
|
16
17
|
#private;
|
|
17
18
|
protected _chainHead?: ChainHead;
|
|
18
19
|
protected _chainSpec?: ChainSpec;
|
|
@@ -58,4 +59,5 @@ export declare class DedotClient<ChainApi extends VersionedGenericSubstrateApi =
|
|
|
58
59
|
* @param hash
|
|
59
60
|
*/
|
|
60
61
|
at<ChainApiAt extends GenericSubstrateApi = ChainApi[RpcV2]>(hash: BlockHash): Promise<ISubstrateClientAt<ChainApiAt>>;
|
|
62
|
+
protected getStorageQuery(): BaseStorageQuery<RpcVersion>;
|
|
61
63
|
}
|
package/client/DedotClient.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { $H256, PortableRegistry } from '@dedot/codecs';
|
|
2
2
|
import { u32 } from '@dedot/shape';
|
|
3
3
|
import { assert, concatU8a, noop, twox64Concat, u8aToHex, xxhashAsU8a } from '@dedot/utils';
|
|
4
|
-
import { ConstantExecutor, ErrorExecutor, EventExecutor, RuntimeApiExecutorV2, StorageQueryExecutorV2, TxExecutorV2 } from '../executor/index.js';
|
|
4
|
+
import { ConstantExecutor, ErrorExecutor, EventExecutor, RuntimeApiExecutorV2, StorageQueryExecutorV2, TxExecutorV2, } from '../executor/index.js';
|
|
5
5
|
import { ChainHead, ChainSpec, Transaction, TransactionWatch } from '../json-rpc/index.js';
|
|
6
6
|
import { newProxyChain } from '../proxychain.js';
|
|
7
|
+
import { NewStorageQuery } from '../storage/index.js';
|
|
7
8
|
import { BaseSubstrateClient, ensurePresence } from './BaseSubstrateClient.js';
|
|
8
9
|
/**
|
|
9
10
|
* @name DedotClient
|
|
@@ -81,6 +82,11 @@ export class DedotClient// prettier-end-here
|
|
|
81
82
|
}
|
|
82
83
|
await this.setupMetadata(metadata);
|
|
83
84
|
this.subscribeRuntimeUpgrades();
|
|
85
|
+
// relegate events
|
|
86
|
+
this.chainHead.on('newBlock', (...args) => this.emit('newBlock', ...args));
|
|
87
|
+
this.chainHead.on('bestBlock', (...args) => this.emit('bestBlock', ...args));
|
|
88
|
+
this.chainHead.on('finalizedBlock', (...args) => this.emit('finalizedBlock', ...args));
|
|
89
|
+
this.chainHead.on('bestChainChanged', (...args) => this.emit('bestChainChanged', ...args));
|
|
84
90
|
}
|
|
85
91
|
/**
|
|
86
92
|
* Ref: https://github.com/paritytech/polkadot-sdk/blob/bbd51ce867967f71657b901f1a956ad4f75d352e/substrate/frame/system/src/lib.rs#L909-L913
|
|
@@ -180,4 +186,7 @@ export class DedotClient// prettier-end-here
|
|
|
180
186
|
this.#apiAtCache[hash] = api;
|
|
181
187
|
return api;
|
|
182
188
|
}
|
|
189
|
+
getStorageQuery() {
|
|
190
|
+
return new NewStorageQuery(this);
|
|
191
|
+
}
|
|
183
192
|
}
|
package/client/LegacyClient.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BlockHash } from '@dedot/codecs';
|
|
2
2
|
import type { JsonRpcProvider } from '@dedot/providers';
|
|
3
|
-
import { GenericSubstrateApi, RpcLegacy, VersionedGenericSubstrateApi } from '@dedot/types';
|
|
3
|
+
import { GenericSubstrateApi, RpcLegacy, RpcVersion, VersionedGenericSubstrateApi } from '@dedot/types';
|
|
4
4
|
import type { SubstrateApi } from '../chaintypes/index.js';
|
|
5
|
+
import { BaseStorageQuery } from '../storage/index.js';
|
|
5
6
|
import type { ApiOptions, ISubstrateClientAt } from '../types.js';
|
|
6
7
|
import { BaseSubstrateClient } from './BaseSubstrateClient.js';
|
|
7
8
|
/**
|
|
@@ -129,4 +130,5 @@ export declare class LegacyClient<ChainApi extends VersionedGenericSubstrateApi
|
|
|
129
130
|
* @param hash
|
|
130
131
|
*/
|
|
131
132
|
at<ChainApiAt extends GenericSubstrateApi = ChainApi[RpcLegacy]>(hash: BlockHash): Promise<ISubstrateClientAt<ChainApiAt>>;
|
|
133
|
+
protected getStorageQuery(): BaseStorageQuery<RpcVersion>;
|
|
132
134
|
}
|
package/client/LegacyClient.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PortableRegistry } from '@dedot/codecs';
|
|
2
2
|
import { ConstantExecutor, ErrorExecutor, EventExecutor, RuntimeApiExecutor, StorageQueryExecutor, TxExecutor, } from '../executor/index.js';
|
|
3
3
|
import { newProxyChain } from '../proxychain.js';
|
|
4
|
+
import { LegacyStorageQuery } from '../storage/index.js';
|
|
4
5
|
import { BaseSubstrateClient } from './BaseSubstrateClient.js';
|
|
5
6
|
const KEEP_ALIVE_INTERVAL = 10_000; // in ms
|
|
6
7
|
/**
|
|
@@ -134,8 +135,13 @@ export class LegacyClient// prettier-end-here
|
|
|
134
135
|
if (!this.#runtimeSubscriptionUnsub) {
|
|
135
136
|
return;
|
|
136
137
|
}
|
|
137
|
-
|
|
138
|
-
|
|
138
|
+
try {
|
|
139
|
+
await this.#runtimeSubscriptionUnsub();
|
|
140
|
+
this.#runtimeSubscriptionUnsub = undefined;
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// ignore
|
|
144
|
+
}
|
|
139
145
|
}
|
|
140
146
|
#subscribeUpdates() {
|
|
141
147
|
this.#subscribeRuntimeUpgrades();
|
|
@@ -247,4 +253,7 @@ export class LegacyClient// prettier-end-here
|
|
|
247
253
|
this.#apiAtCache[hash] = api;
|
|
248
254
|
return api;
|
|
249
255
|
}
|
|
256
|
+
getStorageQuery() {
|
|
257
|
+
return new LegacyStorageQuery(this);
|
|
258
|
+
}
|
|
250
259
|
}
|
|
@@ -160,8 +160,8 @@ export class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic {
|
|
|
160
160
|
status: { type: 'Broadcasting' },
|
|
161
161
|
txHash,
|
|
162
162
|
}));
|
|
163
|
-
const stopBestBlockTrackingFn = api.
|
|
164
|
-
const stopFinalizedBlockTrackingFn = api.
|
|
163
|
+
const stopBestBlockTrackingFn = api.on('bestBlock', checkBestBlockIncluded);
|
|
164
|
+
const stopFinalizedBlockTrackingFn = api.on('finalizedBlock', checkFinalizedBlockIncluded);
|
|
165
165
|
const stopTracking = () => {
|
|
166
166
|
stopBestBlockTrackingFn();
|
|
167
167
|
stopFinalizedBlockTrackingFn();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dedot/api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "A delightful JavaScript/TypeScript client for Polkadot & Substrate",
|
|
5
5
|
"author": "Thang X. Vu <thang@coongcrafts.io>",
|
|
6
6
|
"homepage": "https://github.com/dedotdev/dedot/tree/main/packages/api",
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"sideEffects": false,
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@dedot/codecs": "0.
|
|
17
|
-
"@dedot/providers": "0.
|
|
18
|
-
"@dedot/runtime-specs": "0.
|
|
19
|
-
"@dedot/shape": "0.
|
|
20
|
-
"@dedot/storage": "0.
|
|
21
|
-
"@dedot/types": "0.
|
|
22
|
-
"@dedot/utils": "0.
|
|
16
|
+
"@dedot/codecs": "0.9.1",
|
|
17
|
+
"@dedot/providers": "0.9.1",
|
|
18
|
+
"@dedot/runtime-specs": "0.9.1",
|
|
19
|
+
"@dedot/shape": "0.9.1",
|
|
20
|
+
"@dedot/storage": "0.9.1",
|
|
21
|
+
"@dedot/types": "0.9.1",
|
|
22
|
+
"@dedot/utils": "0.9.1"
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "tsc --project tsconfig.build.json && tsc --project tsconfig.build.cjs.json",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"node": ">=18"
|
|
49
49
|
},
|
|
50
50
|
"license": "Apache-2.0",
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "9329cadcd2062d0f10dc1d8f700d8ade25214199",
|
|
52
52
|
"module": "./index.js",
|
|
53
53
|
"types": "./index.d.ts"
|
|
54
54
|
}
|
|
@@ -20,14 +20,15 @@ export class LegacyStorageQuery extends BaseStorageQuery {
|
|
|
20
20
|
* @returns Promise resolving to a record mapping storage keys to their values
|
|
21
21
|
*/
|
|
22
22
|
async query(keys, at) {
|
|
23
|
+
const client = this.client;
|
|
23
24
|
// Query storage at the specified block or current block
|
|
24
25
|
const changeSets = at
|
|
25
|
-
? await
|
|
26
|
-
: await
|
|
26
|
+
? await client.rpc.state_queryStorageAt(keys, at)
|
|
27
|
+
: await client.rpc.state_queryStorageAt(keys);
|
|
27
28
|
// Create a map of key -> value for easy lookup
|
|
28
29
|
const results = {};
|
|
29
30
|
// Initialize all keys with undefined
|
|
30
|
-
keys.forEach(key => results[key] = undefined);
|
|
31
|
+
keys.forEach((key) => (results[key] = undefined));
|
|
31
32
|
// Update with actual values from the response
|
|
32
33
|
if (changeSets && changeSets.length > 0) {
|
|
33
34
|
changeSets[0].changes.forEach(([key, value]) => {
|
|
@@ -47,9 +48,10 @@ export class LegacyStorageQuery extends BaseStorageQuery {
|
|
|
47
48
|
// Track the latest changes for each key
|
|
48
49
|
const lastChanges = {};
|
|
49
50
|
// Initialize all keys with undefined
|
|
50
|
-
keys.forEach(key => lastChanges[key] = undefined);
|
|
51
|
+
keys.forEach((key) => (lastChanges[key] = undefined));
|
|
51
52
|
// Subscribe to storage changes
|
|
52
|
-
|
|
53
|
+
const client = this.client;
|
|
54
|
+
return client.rpc.state_subscribeStorage(keys, (changeSet) => {
|
|
53
55
|
// Update the latest changes
|
|
54
56
|
changeSet.changes.forEach(([key, value]) => {
|
|
55
57
|
if (lastChanges[key] !== value) {
|
|
@@ -21,7 +21,7 @@ export class NewStorageQuery extends BaseStorageQuery {
|
|
|
21
21
|
*/
|
|
22
22
|
async query(keys, at) {
|
|
23
23
|
// Query storage using ChainHead API
|
|
24
|
-
const storageQueries = keys.map(key => ({ type: 'value', key }));
|
|
24
|
+
const storageQueries = keys.map((key) => ({ type: 'value', key }));
|
|
25
25
|
// Use the provided block hash or skip it in tests
|
|
26
26
|
const rawResults = at
|
|
27
27
|
? await this.client.chainHead.storage(storageQueries, undefined, at)
|
|
@@ -29,7 +29,7 @@ export class NewStorageQuery extends BaseStorageQuery {
|
|
|
29
29
|
// Create a map of key -> value for easy lookup
|
|
30
30
|
const results = {};
|
|
31
31
|
// Initialize all keys with undefined
|
|
32
|
-
keys.forEach(key => results[key] = undefined);
|
|
32
|
+
keys.forEach((key) => (results[key] = undefined));
|
|
33
33
|
// Update with actual values from the response
|
|
34
34
|
rawResults.forEach((result) => {
|
|
35
35
|
results[result.key] = result.value ?? undefined;
|
|
@@ -51,7 +51,7 @@ export class NewStorageQuery extends BaseStorageQuery {
|
|
|
51
51
|
// Function to pull storage values and call the callback if there are changes
|
|
52
52
|
const pull = async ({ hash }) => {
|
|
53
53
|
// Query storage using ChainHead API
|
|
54
|
-
const storageQueries = keys.map(key => ({ type: 'value', key }));
|
|
54
|
+
const storageQueries = keys.map((key) => ({ type: 'value', key }));
|
|
55
55
|
const rawResults = await this.client.chainHead.storage(storageQueries, undefined, hash);
|
|
56
56
|
let changed = false;
|
|
57
57
|
// Create a map for easy lookup
|
|
@@ -73,7 +73,7 @@ export class NewStorageQuery extends BaseStorageQuery {
|
|
|
73
73
|
// Initial pull
|
|
74
74
|
await pull(best);
|
|
75
75
|
// Subscribe to best block events
|
|
76
|
-
const unsub = this.client.
|
|
76
|
+
const unsub = this.client.on('bestBlock', pull);
|
|
77
77
|
return async () => {
|
|
78
78
|
unsub();
|
|
79
79
|
};
|
package/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ChainHeadEvent } from '@dedot/api/json-rpc';
|
|
1
2
|
import { BlockHash, Hash, Metadata, PortableRegistry } from '@dedot/codecs';
|
|
2
3
|
import type { ConnectionStatus, JsonRpcProvider, ProviderEvent } from '@dedot/providers';
|
|
3
4
|
import type { AnyShape } from '@dedot/shape';
|
|
@@ -61,6 +62,7 @@ export interface ApiOptions extends JsonRpcClientOptions {
|
|
|
61
62
|
signer?: InjectedSigner;
|
|
62
63
|
}
|
|
63
64
|
export type ApiEvent = ProviderEvent | 'ready' | 'runtimeUpgraded';
|
|
65
|
+
export type DedotClientEvent = ApiEvent | ChainHeadEvent;
|
|
64
66
|
export interface SubstrateRuntimeVersion {
|
|
65
67
|
specName: string;
|
|
66
68
|
implName: string;
|