@dedot/api 0.17.1-next.9d03d21b.3 → 0.18.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.
- package/cjs/client/DedotClient.js +28 -10
- package/cjs/client/LegacyClient.js +14 -2
- package/cjs/extrinsic/submittable/SubmittableExtrinsicV2.js +9 -0
- package/client/DedotClient.js +29 -11
- package/client/LegacyClient.js +14 -2
- package/extrinsic/submittable/SubmittableExtrinsicV2.js +10 -1
- package/package.json +9 -9
|
@@ -186,24 +186,42 @@ class DedotClient// prettier-end-here
|
|
|
186
186
|
const cached = this._apiAtCache.get(hash);
|
|
187
187
|
if (cached)
|
|
188
188
|
return cached;
|
|
189
|
-
let
|
|
189
|
+
let parentVersion;
|
|
190
|
+
let parentHash;
|
|
190
191
|
// Try to get block info from ChainHead first (for pinned blocks)
|
|
191
192
|
const targetBlock = this.chainHead.findBlock(hash);
|
|
192
193
|
if (targetBlock) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
194
|
+
if (hash === this.genesisHash) {
|
|
195
|
+
parentHash = hash;
|
|
196
|
+
parentVersion = targetBlock.runtime;
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
parentHash = targetBlock.parent;
|
|
200
|
+
const parentBlock = this.chainHead.findBlock(parentHash);
|
|
201
|
+
parentVersion = parentBlock?.runtime;
|
|
202
|
+
}
|
|
203
|
+
// fallback to fetching on-chain runtime if we can't find it in the block
|
|
204
|
+
if (!parentVersion) {
|
|
205
|
+
parentVersion = this.toSubstrateRuntimeVersion(await this.callAt(parentHash).core.version());
|
|
197
206
|
}
|
|
198
207
|
}
|
|
199
208
|
else {
|
|
200
209
|
// Block not pinned, try via Archive fallback if supported
|
|
201
210
|
if (this._archive && (await this._archive.supported())) {
|
|
202
211
|
try {
|
|
212
|
+
if (hash === this.genesisHash) {
|
|
213
|
+
parentHash = hash;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
const rawHeader = await this._archive.header(hash);
|
|
217
|
+
(0, utils_1.assert)(rawHeader, `Header for block ${hash} not found`);
|
|
218
|
+
const header = codecs_1.$Header.tryDecode(rawHeader);
|
|
219
|
+
parentHash = header.parentHash;
|
|
220
|
+
}
|
|
203
221
|
// Fetch runtime version via Archive
|
|
204
|
-
const runtimeRaw = await this._archive.call('Core_version', '0x',
|
|
222
|
+
const runtimeRaw = await this._archive.call('Core_version', '0x', parentHash);
|
|
205
223
|
(0, utils_1.assert)(runtimeRaw, 'Runtime Version Not Found');
|
|
206
|
-
|
|
224
|
+
parentVersion = this.toSubstrateRuntimeVersion(codecs_1.$RuntimeVersion.tryDecode(runtimeRaw));
|
|
207
225
|
}
|
|
208
226
|
catch (error) {
|
|
209
227
|
throw new utils_1.DedotError(`Unable to fetch runtime version for block ${hash}: ${error}`);
|
|
@@ -215,8 +233,8 @@ class DedotClient// prettier-end-here
|
|
|
215
233
|
}
|
|
216
234
|
let metadata = this.metadata;
|
|
217
235
|
let registry = this.registry;
|
|
218
|
-
if (
|
|
219
|
-
metadata = await this.fetchMetadata(
|
|
236
|
+
if (parentVersion && parentVersion.specVersion !== this.runtimeVersion.specVersion) {
|
|
237
|
+
metadata = await this.fetchMetadata(parentHash, parentVersion);
|
|
220
238
|
registry = new codecs_1.PortableRegistry(metadata.latest, this.options.hasher);
|
|
221
239
|
}
|
|
222
240
|
const api = {
|
|
@@ -224,7 +242,7 @@ class DedotClient// prettier-end-here
|
|
|
224
242
|
atBlockHash: hash,
|
|
225
243
|
options: this.options,
|
|
226
244
|
genesisHash: this.genesisHash,
|
|
227
|
-
runtimeVersion:
|
|
245
|
+
runtimeVersion: parentVersion,
|
|
228
246
|
metadata,
|
|
229
247
|
registry,
|
|
230
248
|
rpc: this.rpc,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LegacyClient = void 0;
|
|
4
4
|
const codecs_1 = require("@dedot/codecs");
|
|
5
|
+
const utils_1 = require("@dedot/utils");
|
|
5
6
|
const index_js_1 = require("../executor/index.js");
|
|
6
7
|
const proxychain_js_1 = require("../proxychain.js");
|
|
7
8
|
const index_js_2 = require("../storage/index.js");
|
|
@@ -233,11 +234,12 @@ class LegacyClient// prettier-end-here
|
|
|
233
234
|
const cached = this._apiAtCache.get(hash);
|
|
234
235
|
if (cached)
|
|
235
236
|
return cached;
|
|
236
|
-
const
|
|
237
|
+
const parentHash = await this.#findParentHash(hash);
|
|
238
|
+
const targetVersion = await this.#getRuntimeVersion(parentHash);
|
|
237
239
|
let metadata = this.metadata;
|
|
238
240
|
let registry = this.registry;
|
|
239
241
|
if (targetVersion.specVersion !== this.runtimeVersion.specVersion) {
|
|
240
|
-
metadata = await this.fetchMetadata(
|
|
242
|
+
metadata = await this.fetchMetadata(parentHash, targetVersion);
|
|
241
243
|
registry = new codecs_1.PortableRegistry(metadata.latest, this.options.hasher);
|
|
242
244
|
}
|
|
243
245
|
const api = {
|
|
@@ -265,5 +267,15 @@ class LegacyClient// prettier-end-here
|
|
|
265
267
|
getStorageQuery() {
|
|
266
268
|
return new index_js_2.LegacyStorageQuery(this);
|
|
267
269
|
}
|
|
270
|
+
async #findParentHash(hash) {
|
|
271
|
+
if (hash === this.genesisHash) {
|
|
272
|
+
return this.genesisHash;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
const header = await this.rpc.chain_getHeader(hash);
|
|
276
|
+
(0, utils_1.assert)(header, `Header for ${hash} not found`);
|
|
277
|
+
return header.parentHash;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
268
280
|
}
|
|
269
281
|
exports.LegacyClient = LegacyClient;
|
|
@@ -22,6 +22,15 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
22
22
|
const txHash = this.hash;
|
|
23
23
|
// validate the transaction
|
|
24
24
|
// https://github.com/paritytech/json-rpc-interface-spec/issues/55#issuecomment-1609011150
|
|
25
|
+
// ensure at least 2 finalized blocks, this is to make sure the api.at can find the parent hash & block to fetch runtime
|
|
26
|
+
while (true) {
|
|
27
|
+
const block = await this.client.chainHead.finalizedBlock();
|
|
28
|
+
const parentBlock = this.client.chainHead.findBlock(block.parent);
|
|
29
|
+
if (parentBlock) {
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
await (0, utils_1.waitFor)(100);
|
|
33
|
+
}
|
|
25
34
|
const finalizedHash = await this.client.chainHead.finalizedHash();
|
|
26
35
|
const validateTx = async (hash) => {
|
|
27
36
|
const apiAt = await api.at(hash);
|
package/client/DedotClient.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $H256, $RuntimeVersion, PortableRegistry } from '@dedot/codecs';
|
|
1
|
+
import { $H256, $Header, $RuntimeVersion, PortableRegistry } from '@dedot/codecs';
|
|
2
2
|
import { u32 } from '@dedot/shape';
|
|
3
3
|
import { assert, concatU8a, DedotError, noop, twox64Concat, u8aToHex, xxhashAsU8a } from '@dedot/utils';
|
|
4
4
|
import { ConstantExecutor, ErrorExecutor, EventExecutor, RuntimeApiExecutorV2, StorageQueryExecutorV2, TxExecutorV2, ViewFunctionExecutorV2, } from '../executor/index.js';
|
|
@@ -183,24 +183,42 @@ export class DedotClient// prettier-end-here
|
|
|
183
183
|
const cached = this._apiAtCache.get(hash);
|
|
184
184
|
if (cached)
|
|
185
185
|
return cached;
|
|
186
|
-
let
|
|
186
|
+
let parentVersion;
|
|
187
|
+
let parentHash;
|
|
187
188
|
// Try to get block info from ChainHead first (for pinned blocks)
|
|
188
189
|
const targetBlock = this.chainHead.findBlock(hash);
|
|
189
190
|
if (targetBlock) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
if (hash === this.genesisHash) {
|
|
192
|
+
parentHash = hash;
|
|
193
|
+
parentVersion = targetBlock.runtime;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
parentHash = targetBlock.parent;
|
|
197
|
+
const parentBlock = this.chainHead.findBlock(parentHash);
|
|
198
|
+
parentVersion = parentBlock?.runtime;
|
|
199
|
+
}
|
|
200
|
+
// fallback to fetching on-chain runtime if we can't find it in the block
|
|
201
|
+
if (!parentVersion) {
|
|
202
|
+
parentVersion = this.toSubstrateRuntimeVersion(await this.callAt(parentHash).core.version());
|
|
194
203
|
}
|
|
195
204
|
}
|
|
196
205
|
else {
|
|
197
206
|
// Block not pinned, try via Archive fallback if supported
|
|
198
207
|
if (this._archive && (await this._archive.supported())) {
|
|
199
208
|
try {
|
|
209
|
+
if (hash === this.genesisHash) {
|
|
210
|
+
parentHash = hash;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
const rawHeader = await this._archive.header(hash);
|
|
214
|
+
assert(rawHeader, `Header for block ${hash} not found`);
|
|
215
|
+
const header = $Header.tryDecode(rawHeader);
|
|
216
|
+
parentHash = header.parentHash;
|
|
217
|
+
}
|
|
200
218
|
// Fetch runtime version via Archive
|
|
201
|
-
const runtimeRaw = await this._archive.call('Core_version', '0x',
|
|
219
|
+
const runtimeRaw = await this._archive.call('Core_version', '0x', parentHash);
|
|
202
220
|
assert(runtimeRaw, 'Runtime Version Not Found');
|
|
203
|
-
|
|
221
|
+
parentVersion = this.toSubstrateRuntimeVersion($RuntimeVersion.tryDecode(runtimeRaw));
|
|
204
222
|
}
|
|
205
223
|
catch (error) {
|
|
206
224
|
throw new DedotError(`Unable to fetch runtime version for block ${hash}: ${error}`);
|
|
@@ -212,8 +230,8 @@ export class DedotClient// prettier-end-here
|
|
|
212
230
|
}
|
|
213
231
|
let metadata = this.metadata;
|
|
214
232
|
let registry = this.registry;
|
|
215
|
-
if (
|
|
216
|
-
metadata = await this.fetchMetadata(
|
|
233
|
+
if (parentVersion && parentVersion.specVersion !== this.runtimeVersion.specVersion) {
|
|
234
|
+
metadata = await this.fetchMetadata(parentHash, parentVersion);
|
|
217
235
|
registry = new PortableRegistry(metadata.latest, this.options.hasher);
|
|
218
236
|
}
|
|
219
237
|
const api = {
|
|
@@ -221,7 +239,7 @@ export class DedotClient// prettier-end-here
|
|
|
221
239
|
atBlockHash: hash,
|
|
222
240
|
options: this.options,
|
|
223
241
|
genesisHash: this.genesisHash,
|
|
224
|
-
runtimeVersion:
|
|
242
|
+
runtimeVersion: parentVersion,
|
|
225
243
|
metadata,
|
|
226
244
|
registry,
|
|
227
245
|
rpc: this.rpc,
|
package/client/LegacyClient.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PortableRegistry } from '@dedot/codecs';
|
|
2
|
+
import { assert } from '@dedot/utils';
|
|
2
3
|
import { ConstantExecutor, ErrorExecutor, EventExecutor, RuntimeApiExecutor, StorageQueryExecutor, TxExecutor, ViewFunctionExecutor, } from '../executor/index.js';
|
|
3
4
|
import { newProxyChain } from '../proxychain.js';
|
|
4
5
|
import { LegacyStorageQuery } from '../storage/index.js';
|
|
@@ -230,11 +231,12 @@ export class LegacyClient// prettier-end-here
|
|
|
230
231
|
const cached = this._apiAtCache.get(hash);
|
|
231
232
|
if (cached)
|
|
232
233
|
return cached;
|
|
233
|
-
const
|
|
234
|
+
const parentHash = await this.#findParentHash(hash);
|
|
235
|
+
const targetVersion = await this.#getRuntimeVersion(parentHash);
|
|
234
236
|
let metadata = this.metadata;
|
|
235
237
|
let registry = this.registry;
|
|
236
238
|
if (targetVersion.specVersion !== this.runtimeVersion.specVersion) {
|
|
237
|
-
metadata = await this.fetchMetadata(
|
|
239
|
+
metadata = await this.fetchMetadata(parentHash, targetVersion);
|
|
238
240
|
registry = new PortableRegistry(metadata.latest, this.options.hasher);
|
|
239
241
|
}
|
|
240
242
|
const api = {
|
|
@@ -262,4 +264,14 @@ export class LegacyClient// prettier-end-here
|
|
|
262
264
|
getStorageQuery() {
|
|
263
265
|
return new LegacyStorageQuery(this);
|
|
264
266
|
}
|
|
267
|
+
async #findParentHash(hash) {
|
|
268
|
+
if (hash === this.genesisHash) {
|
|
269
|
+
return this.genesisHash;
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
const header = await this.rpc.chain_getHeader(hash);
|
|
273
|
+
assert(header, `Header for ${hash} not found`);
|
|
274
|
+
return header.parentHash;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
265
277
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AsyncQueue, noop } from '@dedot/utils';
|
|
1
|
+
import { AsyncQueue, noop, waitFor } from '@dedot/utils';
|
|
2
2
|
import { BaseSubmittableExtrinsic } from './BaseSubmittableExtrinsic.js';
|
|
3
3
|
import { SubmittableResult } from './SubmittableResult.js';
|
|
4
4
|
import { InvalidTxError } from './errors.js';
|
|
@@ -19,6 +19,15 @@ export class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic {
|
|
|
19
19
|
const txHash = this.hash;
|
|
20
20
|
// validate the transaction
|
|
21
21
|
// https://github.com/paritytech/json-rpc-interface-spec/issues/55#issuecomment-1609011150
|
|
22
|
+
// ensure at least 2 finalized blocks, this is to make sure the api.at can find the parent hash & block to fetch runtime
|
|
23
|
+
while (true) {
|
|
24
|
+
const block = await this.client.chainHead.finalizedBlock();
|
|
25
|
+
const parentBlock = this.client.chainHead.findBlock(block.parent);
|
|
26
|
+
if (parentBlock) {
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
await waitFor(100);
|
|
30
|
+
}
|
|
22
31
|
const finalizedHash = await this.client.chainHead.finalizedHash();
|
|
23
32
|
const validateTx = async (hash) => {
|
|
24
33
|
const apiAt = await api.at(hash);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dedot/api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "A delightful JavaScript/TypeScript client for Polkadot & Substrate",
|
|
5
5
|
"author": "Thang X. Vu <thang@dedot.dev>",
|
|
6
6
|
"homepage": "https://dedot.dev",
|
|
@@ -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.18.0",
|
|
17
|
+
"@dedot/providers": "0.18.0",
|
|
18
|
+
"@dedot/runtime-specs": "0.18.0",
|
|
19
|
+
"@dedot/shape": "0.18.0",
|
|
20
|
+
"@dedot/storage": "0.18.0",
|
|
21
|
+
"@dedot/types": "0.18.0",
|
|
22
|
+
"@dedot/utils": "0.18.0"
|
|
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": "32395b356a4febaac0d52506742947c916ac9895",
|
|
52
52
|
"module": "./index.js",
|
|
53
53
|
"types": "./index.d.ts"
|
|
54
54
|
}
|