@polkadot-api/forklift 0.1.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 (63) hide show
  1. package/README.md +394 -0
  2. package/bin/cli.js +388 -0
  3. package/bin/cli.js.map +1 -0
  4. package/dist/.papi/descriptors/dist/descriptors-CVixQzDI.js +27 -0
  5. package/dist/.papi/descriptors/dist/descriptors-CVixQzDI.js.map +1 -0
  6. package/dist/.papi/descriptors/dist/index.js +40 -0
  7. package/dist/.papi/descriptors/dist/index.js.map +1 -0
  8. package/dist/.papi/descriptors/dist/metadataTypes-OmVFeQs5.js +4 -0
  9. package/dist/.papi/descriptors/dist/metadataTypes-OmVFeQs5.js.map +1 -0
  10. package/dist/.papi/descriptors/dist/parachain_metadata-CQQZadL1.js +4 -0
  11. package/dist/.papi/descriptors/dist/parachain_metadata-CQQZadL1.js.map +1 -0
  12. package/dist/.papi/descriptors/dist/relay_metadata-BAI7pjXf.js +4 -0
  13. package/dist/.papi/descriptors/dist/relay_metadata-BAI7pjXf.js.map +1 -0
  14. package/dist/index.d.ts +64 -0
  15. package/dist/src/block-builder/create-block.js +232 -0
  16. package/dist/src/block-builder/create-block.js.map +1 -0
  17. package/dist/src/block-builder/para-enter.js +21 -0
  18. package/dist/src/block-builder/para-enter.js.map +1 -0
  19. package/dist/src/block-builder/set-validation-data.js +284 -0
  20. package/dist/src/block-builder/set-validation-data.js.map +1 -0
  21. package/dist/src/block-builder/slot-utils.js +68 -0
  22. package/dist/src/block-builder/slot-utils.js.map +1 -0
  23. package/dist/src/block-builder/timestamp.js +20 -0
  24. package/dist/src/block-builder/timestamp.js.map +1 -0
  25. package/dist/src/chain.js +334 -0
  26. package/dist/src/chain.js.map +1 -0
  27. package/dist/src/codecs.js +103 -0
  28. package/dist/src/codecs.js.map +1 -0
  29. package/dist/src/executor.js +87 -0
  30. package/dist/src/executor.js.map +1 -0
  31. package/dist/src/forklift.js +177 -0
  32. package/dist/src/forklift.js.map +1 -0
  33. package/dist/src/index.js +3 -0
  34. package/dist/src/index.js.map +1 -0
  35. package/dist/src/logger.js +11 -0
  36. package/dist/src/logger.js.map +1 -0
  37. package/dist/src/prequeries.js +19 -0
  38. package/dist/src/prequeries.js.map +1 -0
  39. package/dist/src/rpc/archive_v1.js +223 -0
  40. package/dist/src/rpc/archive_v1.js.map +1 -0
  41. package/dist/src/rpc/chainHead_v1.js +383 -0
  42. package/dist/src/rpc/chainHead_v1.js.map +1 -0
  43. package/dist/src/rpc/chainSpec_v1.js +14 -0
  44. package/dist/src/rpc/chainSpec_v1.js.map +1 -0
  45. package/dist/src/rpc/dev.js +32 -0
  46. package/dist/src/rpc/dev.js.map +1 -0
  47. package/dist/src/rpc/forklift_xcm.js +99 -0
  48. package/dist/src/rpc/forklift_xcm.js.map +1 -0
  49. package/dist/src/rpc/rpc_utils.js +20 -0
  50. package/dist/src/rpc/rpc_utils.js.map +1 -0
  51. package/dist/src/rpc/transaction_v1.js +13 -0
  52. package/dist/src/rpc/transaction_v1.js.map +1 -0
  53. package/dist/src/serve.js +88 -0
  54. package/dist/src/serve.js.map +1 -0
  55. package/dist/src/source.js +125 -0
  56. package/dist/src/source.js.map +1 -0
  57. package/dist/src/storage.js +223 -0
  58. package/dist/src/storage.js.map +1 -0
  59. package/dist/src/txPool.js +177 -0
  60. package/dist/src/txPool.js.map +1 -0
  61. package/dist/src/xcm.js +292 -0
  62. package/dist/src/xcm.js.map +1 -0
  63. package/package.json +61 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codecs.js","sources":["../../src/codecs.ts"],"sourcesContent":["import {\n getDynamicBuilder,\n getLookupFn,\n type MetadataLookup,\n} from \"@polkadot-api/metadata-builders\";\nimport {\n compact,\n decAnyMetadata,\n u32,\n unifyMetadata,\n} from \"@polkadot-api/substrate-bindings\";\nimport { getExtrinsicDecoder as txUtilsExtrinsicDecoder } from \"@polkadot-api/tx-utils\";\nimport { Binary } from \"polkadot-api\";\nimport { mergeUint8 } from \"polkadot-api/utils\";\nimport type { Block } from \"./block-builder/create-block\";\nimport type { Chain } from \"./chain\";\nimport { runRuntimeCall } from \"./executor\";\nimport { logger } from \"./logger\";\n\nconst log = logger.child({ module: \"codecs\" });\n\ntype DynamicBuilder = ReturnType<typeof getDynamicBuilder>;\nconst blockMeta = new WeakMap<\n Block,\n Promise<{\n metadataRaw: Uint8Array;\n lookup: MetadataLookup;\n dynamicBuilder: DynamicBuilder;\n }>\n>();\n\nexport const setBlockMeta = async (chain: Chain, block: Block) => {\n const parentMeta = blockMeta.get(chain.getBlock(block.parent)!);\n if (!block.hasNewRuntime && parentMeta) {\n blockMeta.set(block, parentMeta);\n return;\n }\n\n blockMeta.set(\n block,\n new Promise(async (resolve) => {\n const metadata = await runRuntimeCall({\n chain,\n hash: block.hash,\n call: \"Metadata_metadata_at_version\",\n params: Binary.toHex(u32.enc(15)),\n });\n const metadataRaw = Binary.fromHex(metadata.result);\n const lookup = getLookupFn(unifyMetadata(decAnyMetadata(metadataRaw)));\n const dynamicBuilder = getDynamicBuilder(lookup);\n\n resolve({ lookup, dynamicBuilder, metadataRaw });\n })\n );\n};\n\nexport const getConstant = async (\n block: Block,\n palletName: string,\n entryName: string\n) => {\n const meta = await blockMeta.get(block);\n if (!meta) {\n throw new Error(\"Block doesn't have metadata set\");\n }\n\n try {\n const codec = meta.dynamicBuilder.buildConstant(palletName, entryName);\n const pallet = meta.lookup.metadata.pallets.find(\n (p) => p.name === palletName\n )!;\n const entry = pallet.constants.find((ct) => ct.name === entryName)!;\n\n return codec.dec(entry.value);\n } catch (e) {\n // console.error(`getConstant failed for ${palletName}.${entryName}:`, e);\n return null;\n }\n};\n\nexport const getStorageCodecs = async (\n block: Block,\n palletName: string,\n entryName: string\n) => {\n const meta = await blockMeta.get(block);\n if (!meta) {\n throw new Error(\"Block doesn't have metadata set\");\n }\n\n try {\n return meta.dynamicBuilder.buildStorage(palletName, entryName);\n } catch {\n return null;\n }\n};\n\nexport const getTxCodec = async (\n block: Block,\n palletName: string,\n txName: string\n) => {\n const meta = await blockMeta.get(block);\n if (!meta) {\n throw new Error(\"Block doesn't have metadata set\");\n }\n\n try {\n return meta.dynamicBuilder.buildCall(palletName, txName);\n } catch (ex) {\n return null;\n }\n};\n\nexport const getCallCodec = async (\n block: Block,\n palletName: string,\n apiName: string\n) => {\n const meta = await blockMeta.get(block);\n if (!meta) {\n throw new Error(\"Block doesn't have metadata set\");\n }\n\n try {\n return meta.dynamicBuilder.buildRuntimeCall(palletName, apiName);\n } catch (ex) {\n return null;\n }\n};\n\nexport const getCallData = async (\n block: Block,\n palletName: string,\n txName: string,\n params: any\n) => {\n const tx = await getTxCodec(block, palletName, txName);\n if (!tx) return null;\n\n try {\n const { location, codec } = tx;\n\n return mergeUint8([new Uint8Array(location), codec.enc(params)]);\n } catch (ex) {\n log.error(ex, \"getCallData failed\");\n return null;\n }\n};\n\nexport const getExtrinsicDecoder = async (block: Block) => {\n const meta = await blockMeta.get(block);\n if (!meta) {\n throw new Error(\"Block doesn't have metadata set\");\n }\n\n return txUtilsExtrinsicDecoder(meta.metadataRaw);\n};\n\nexport const unsignedExtrinsic = (callData: Uint8Array) =>\n mergeUint8([compact.enc(callData.length + 1), new Uint8Array([4]), callData]);\n"],"names":["txUtilsExtrinsicDecoder"],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import { get_runtime_version, run_task } from '@acala-network/chopsticks-executor';
2
+ import { Binary } from 'polkadot-api';
3
+
4
+ let nextTaskId = 0;
5
+ const runRuntimeCall = async ({
6
+ chain,
7
+ hash,
8
+ call,
9
+ params,
10
+ storageOverrides = {},
11
+ mockSignatureHost = false
12
+ }) => {
13
+ const code = chain.getBlock(hash)?.code;
14
+ if (!code) {
15
+ throw new Error(`No runtime code found at block ${hash}`);
16
+ }
17
+ const codeHex = Binary.toHex(code);
18
+ const jsCallback = createJsCallback(chain, hash, storageOverrides);
19
+ const task = {
20
+ id: nextTaskId++,
21
+ wasm: codeHex,
22
+ calls: [[call, [params]]],
23
+ // 0: no mock, 1: require magic signature, 2: always valid
24
+ mockSignatureHost: mockSignatureHost ? 2 : 0,
25
+ allowUnresolvedImports: true,
26
+ runtimeLogLevel: 0,
27
+ storageProofSize: 1e3
28
+ };
29
+ const response = await run_task(task, jsCallback);
30
+ if (response.Error) {
31
+ throw new Error(`Runtime call failed: ${response.Error}`);
32
+ }
33
+ if (!response.Call) {
34
+ throw new Error("Unexpected response format from runtime");
35
+ }
36
+ return response.Call;
37
+ };
38
+ const getRuntimeVersion = async (code) => {
39
+ const codeHex = Binary.toHex(code);
40
+ const version = await get_runtime_version(codeHex);
41
+ return version;
42
+ };
43
+ const MIN_PREFIX_LEN = 32 * 2 + 2;
44
+ const createJsCallback = (chain, hash, overlay) => {
45
+ return {
46
+ async getStorage(key) {
47
+ if (key in overlay) {
48
+ return overlay[key] ?? void 0;
49
+ }
50
+ const node = await chain.getStorage(hash, key);
51
+ return node.value ? Binary.toHex(node.value) : void 0;
52
+ },
53
+ async getNextKey(prefix, key) {
54
+ prefix = prefix.length < MIN_PREFIX_LEN ? key.slice(0, MIN_PREFIX_LEN) : prefix;
55
+ const descendants = await chain.getStorageDescendants(hash, prefix);
56
+ const allKeys = /* @__PURE__ */ new Set([
57
+ ...Object.keys(descendants),
58
+ ...Object.keys(overlay).filter(
59
+ (k) => k.startsWith(prefix) && overlay[k] !== null
60
+ )
61
+ ]);
62
+ for (const k of Object.keys(overlay)) {
63
+ if (overlay[k] === null) allKeys.delete(k);
64
+ }
65
+ const keys = [...allKeys].sort();
66
+ const idx = keys.findIndex((k) => k > key);
67
+ return idx >= 0 ? keys[idx] : void 0;
68
+ },
69
+ async offchainGetStorage(_key) {
70
+ return void 0;
71
+ },
72
+ async offchainTimestamp() {
73
+ return Date.now();
74
+ },
75
+ async offchainRandomSeed() {
76
+ const bytes = new Uint8Array(32);
77
+ crypto.getRandomValues(bytes);
78
+ return Binary.toHex(bytes);
79
+ },
80
+ async offchainSubmitTransaction(_tx) {
81
+ return false;
82
+ }
83
+ };
84
+ };
85
+
86
+ export { getRuntimeVersion, runRuntimeCall };
87
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sources":["../../src/executor.ts"],"sourcesContent":["import {\n get_runtime_version,\n run_task,\n type JsCallback,\n} from \"@acala-network/chopsticks-executor\";\nimport { Binary, type HexString } from \"polkadot-api\";\nimport type { Chain } from \"./chain\";\n\nexport interface ExecutorParams {\n chain: Chain;\n hash: HexString;\n call: string;\n params: HexString;\n storageOverrides?: Record<HexString, HexString | null>;\n mockSignatureHost?: boolean;\n}\n\nexport interface RuntimeVersion {\n specName: string;\n implName: string;\n authoringVersion: number;\n specVersion: number;\n implVersion: number;\n apis: Array<[HexString, number]>;\n transactionVersion: number;\n stateVersion: number;\n}\n\nexport interface RuntimeCallResult {\n result: HexString;\n storageDiff: Array<[HexString, HexString | null]>;\n offchainStorageDiff: Array<[HexString, HexString | null]>;\n runtimeLogs: string[];\n}\n\ninterface TaskResponse {\n Call?: RuntimeCallResult;\n Error?: string;\n}\n\nlet nextTaskId = 0;\nexport const runRuntimeCall = async ({\n chain,\n hash,\n call,\n params,\n storageOverrides = {},\n mockSignatureHost = false,\n}: ExecutorParams): Promise<RuntimeCallResult> => {\n // Get the runtime code for the target block\n const code = chain.getBlock(hash)?.code;\n if (!code) {\n throw new Error(`No runtime code found at block ${hash}`);\n }\n const codeHex = Binary.toHex(code);\n\n // Create the callback object for storage access\n const jsCallback = createJsCallback(chain, hash, storageOverrides);\n\n // Build the task\n const task = {\n id: nextTaskId++,\n wasm: codeHex,\n calls: [[call, [params]]],\n // 0: no mock, 1: require magic signature, 2: always valid\n mockSignatureHost: mockSignatureHost ? 2 : 0,\n allowUnresolvedImports: true,\n runtimeLogLevel: 0,\n storageProofSize: 1000,\n };\n\n // Run the task\n const response = (await run_task(task, jsCallback)) as TaskResponse;\n\n if (response.Error) {\n throw new Error(`Runtime call failed: ${response.Error}`);\n }\n\n if (!response.Call) {\n throw new Error(\"Unexpected response format from runtime\");\n }\n\n return response.Call;\n};\n\nexport const getRuntimeVersion = async (\n code: Uint8Array\n): Promise<RuntimeVersion> => {\n const codeHex = Binary.toHex(code);\n\n const version = await get_runtime_version(codeHex);\n return version as RuntimeVersion;\n};\n\nconst MIN_PREFIX_LEN = 32 * 2 + 2; // module + method + 0x\nconst createJsCallback = (\n chain: Chain,\n hash: HexString,\n overlay: Record<HexString, HexString | null>\n): JsCallback => {\n return {\n async getStorage(key: HexString): Promise<string | undefined> {\n // console.log(\"get\", key);\n\n // Check overlay first\n if (key in overlay) {\n return overlay[key] ?? undefined;\n }\n const node = await chain.getStorage(hash, key);\n return node.value ? Binary.toHex(node.value) : undefined;\n },\n\n async getNextKey(\n prefix: HexString,\n key: HexString\n ): Promise<string | undefined> {\n prefix =\n prefix.length < MIN_PREFIX_LEN ? key.slice(0, MIN_PREFIX_LEN) : prefix;\n\n // Get all descendants under the prefix and find the next key after `key`\n const descendants = await chain.getStorageDescendants(hash, prefix);\n\n // Merge with overlay\n const allKeys = new Set([\n ...Object.keys(descendants),\n ...Object.keys(overlay).filter(\n (k) => k.startsWith(prefix) && overlay[k] !== null\n ),\n ]);\n // Remove keys that are deleted in overlay\n for (const k of Object.keys(overlay)) {\n if (overlay[k] === null) allKeys.delete(k);\n }\n const keys = [...allKeys].sort();\n const idx = keys.findIndex((k) => k > key);\n return idx >= 0 ? keys[idx] : undefined;\n },\n\n async offchainGetStorage(_key: HexString): Promise<string | undefined> {\n return undefined;\n },\n\n async offchainTimestamp(): Promise<number> {\n return Date.now();\n },\n\n async offchainRandomSeed(): Promise<`0x${string}`> {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return Binary.toHex(bytes) as `0x${string}`;\n },\n\n async offchainSubmitTransaction(_tx: HexString): Promise<boolean> {\n return false;\n },\n };\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,177 @@
1
+ import '@polkadot-api/substrate-client';
2
+ import { Enum } from 'polkadot-api';
3
+ import { Subject, merge, firstValueFrom, combineLatest } from 'rxjs';
4
+ import { createChain } from './chain.js';
5
+ import { runPrequeries } from './prequeries.js';
6
+ import { createServer } from './serve.js';
7
+ import { createRemoteSource } from './source.js';
8
+ import { createTxPool } from './txPool.js';
9
+ import { logger } from './logger.js';
10
+ import { pushUmp } from './xcm.js';
11
+
12
+ const log = logger.child({ module: "forklift" });
13
+ const defaultOptions = {
14
+ buildBlockMode: Enum("timer", 100),
15
+ finalizeMode: Enum("timer", 2e3)
16
+ };
17
+ function forklift(sourceDef, opts) {
18
+ const source = createRemoteSource(sourceDef.value.url, {
19
+ atBlock: sourceDef.value.atBlock
20
+ });
21
+ let options = { ...defaultOptions, ...removeUndefinedProperties(opts) };
22
+ const chain = createChain(source, options.key);
23
+ const txPool = createTxPool(chain);
24
+ runPrequeries(chain);
25
+ const dmpSubject = new Subject();
26
+ let dmpMsgQueue = [];
27
+ const dmpSub = dmpSubject.subscribe((messages) => {
28
+ dmpMsgQueue = [...dmpMsgQueue, ...messages];
29
+ });
30
+ const umpSubject = new Subject();
31
+ let umpMsgQueues = {};
32
+ const umpSub = umpSubject.subscribe((msg) => {
33
+ umpMsgQueues = {
34
+ ...umpMsgQueues,
35
+ [msg.paraId]: [...umpMsgQueues[msg.paraId] ?? [], ...msg.messages]
36
+ };
37
+ });
38
+ const hrmpSubject = new Subject();
39
+ let hrmpMsgQueues = {};
40
+ const hrmpSub = hrmpSubject.subscribe(({ paraId, messages }) => {
41
+ hrmpMsgQueues = {
42
+ ...hrmpMsgQueues,
43
+ [paraId]: [...hrmpMsgQueues[paraId] ?? [], ...messages]
44
+ };
45
+ });
46
+ let buildBlockQueue = null;
47
+ let blocksEnqueued = 0;
48
+ const finalizeTimers = /* @__PURE__ */ new Set();
49
+ const newBlock = async (opts2, automatic) => {
50
+ if (buildBlockQueue) {
51
+ blocksEnqueued++;
52
+ while (buildBlockQueue) {
53
+ await buildBlockQueue;
54
+ }
55
+ blocksEnqueued--;
56
+ }
57
+ let resolve = () => {
58
+ };
59
+ buildBlockQueue = new Promise(async (res) => resolve = res);
60
+ const dmp = dmpMsgQueue;
61
+ dmpMsgQueue = [];
62
+ const ump = umpMsgQueues;
63
+ umpMsgQueues = {};
64
+ for (const paraId in ump) {
65
+ await pushUmp(chain, Number(paraId), ump[paraId]);
66
+ }
67
+ const hrmp = hrmpMsgQueues;
68
+ hrmpMsgQueues = {};
69
+ try {
70
+ const type = opts2?.unsafeBlockHeight != null ? "finalized" : opts2?.type || (options.finalizeMode.type === "timer" && options.finalizeMode.value === 0 ? "finalized" : void 0);
71
+ const parent = opts2?.parent ?? await firstValueFrom(chain.best$);
72
+ const parentBlock = chain.getBlock(parent);
73
+ const transactions = await txPool.getTxsForBlock(parentBlock);
74
+ if (automatic && transactions.length + dmp.length + Object.keys(ump).length + Object.keys(hrmp).length === 0) {
75
+ log.debug("skipped automatic block: no transactions ready");
76
+ return parent;
77
+ }
78
+ logger.info("creating block");
79
+ const block = await chain.newBlock(type ?? "fork", {
80
+ parent,
81
+ transactions,
82
+ disableOnIdle: opts2?.disableOnIdle ?? options.disableOnIdle ?? false,
83
+ xcm: { dmp, hrmp },
84
+ storage: opts2?.storage ?? {},
85
+ unsafeBlockHeight: opts2?.unsafeBlockHeight
86
+ });
87
+ logger.info(`block ${block.hash} created`);
88
+ if (type == null) {
89
+ const [best, blocks] = await firstValueFrom(
90
+ combineLatest([chain.best$, chain.blocks$])
91
+ );
92
+ if (block.header.number > blocks[best].header.number) {
93
+ chain.changeBest(block.hash);
94
+ }
95
+ if (options.finalizeMode.type === "timer") {
96
+ const timer = setTimeout(() => {
97
+ try {
98
+ chain.changeFinalized(block.hash);
99
+ } catch {
100
+ }
101
+ finalizeTimers.delete(timer);
102
+ }, options.finalizeMode.value);
103
+ finalizeTimers.add(timer);
104
+ }
105
+ }
106
+ return block.hash;
107
+ } catch (ex) {
108
+ logger.error(ex, "failed creating block");
109
+ dmpMsgQueue = [...dmp, ...dmpMsgQueue];
110
+ for (const senderId in hrmp) {
111
+ hrmpMsgQueues[senderId] = [
112
+ ...hrmp[senderId] ?? [],
113
+ ...hrmpMsgQueues[senderId] ?? []
114
+ ];
115
+ }
116
+ throw ex;
117
+ } finally {
118
+ buildBlockQueue = null;
119
+ resolve();
120
+ }
121
+ };
122
+ let txBlockPending = false;
123
+ const txPoolSub = merge(
124
+ txPool.txAdded$,
125
+ dmpSubject,
126
+ umpSubject,
127
+ hrmpSubject
128
+ ).subscribe(() => {
129
+ if (options.buildBlockMode.type === "manual") return;
130
+ if (txBlockPending || blocksEnqueued) {
131
+ return;
132
+ }
133
+ const delay = options.buildBlockMode.value;
134
+ if (delay === 0) {
135
+ return newBlock(void 0, true);
136
+ }
137
+ txBlockPending = true;
138
+ setTimeout(() => {
139
+ txBlockPending = false;
140
+ if (!blocksEnqueued) newBlock(void 0, true);
141
+ }, delay);
142
+ });
143
+ const xcm = {
144
+ pushDmp: (messages) => dmpSubject.next(messages),
145
+ pushUmp: (paraId, messages) => umpSubject.next({ paraId, messages }),
146
+ pushHrmp: (paraId, messages) => hrmpSubject.next({ paraId, messages })
147
+ };
148
+ return {
149
+ serve: createServer({ source, chain, txPool, newBlock, xcm }),
150
+ newBlock: (opts2) => newBlock(opts2),
151
+ changeBest: async (hash) => chain.changeBest(hash),
152
+ changeFinalized: async (hash) => {
153
+ finalizeTimers.forEach(clearTimeout);
154
+ finalizeTimers.clear();
155
+ return chain.changeFinalized(hash);
156
+ },
157
+ setStorage: async (hash, changes) => chain.setStorage(hash, changes),
158
+ getStorageDiff: (hash, baseHash) => chain.getStorageDiff(hash, baseHash),
159
+ changeOptions(opts2) {
160
+ options = { ...options, ...removeUndefinedProperties(opts2) };
161
+ },
162
+ destroy() {
163
+ dmpSub.unsubscribe();
164
+ umpSub.unsubscribe();
165
+ hrmpSub.unsubscribe();
166
+ txPoolSub.unsubscribe();
167
+ txPool.destroy();
168
+ source.destroy();
169
+ }
170
+ };
171
+ }
172
+ const removeUndefinedProperties = (value) => value && Object.fromEntries(
173
+ Object.entries(value).filter(([, value2]) => value2 !== void 0)
174
+ );
175
+
176
+ export { forklift };
177
+ //# sourceMappingURL=forklift.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forklift.js","sources":["../../src/forklift.ts"],"sourcesContent":["import { type JsonRpcProvider } from \"@polkadot-api/substrate-client\";\nimport { Enum, type HexString } from \"polkadot-api\";\nimport { combineLatest, firstValueFrom, merge, Subject } from \"rxjs\";\nimport type {\n CreateBlockParams,\n DmpMessage,\n} from \"./block-builder/create-block\";\nimport { createChain } from \"./chain\";\nimport { runPrequeries } from \"./prequeries\";\nimport type { ServerContext } from \"./rpc/rpc_utils\";\nimport { createServer } from \"./serve\";\nimport { createRemoteSource } from \"./source\";\nimport { createTxPool } from \"./txPool\";\nimport { logger } from \"./logger\";\nimport { pushUmp } from \"./xcm\";\n\nconst log = logger.child({ module: \"forklift\" });\n\nexport interface NewBlockOptions {\n type: \"best\" | \"finalized\" | \"fork\";\n unsafeBlockHeight?: number;\n parent: HexString;\n disableOnIdle: boolean;\n storage: CreateBlockParams[\"storage\"];\n}\n\nexport interface Forklift {\n serve: JsonRpcProvider;\n\n newBlock: (opts?: Partial<NewBlockOptions>) => Promise<HexString>;\n changeBest: (hash: HexString) => Promise<void>;\n changeFinalized: (hash: HexString) => Promise<void>;\n setStorage: (\n hash: HexString,\n changes: Record<string, Uint8Array>\n ) => Promise<void>;\n getStorageDiff: (\n hash: HexString,\n baseHash?: HexString\n ) => Promise<\n Record<string, { value: Uint8Array | null; prev?: Uint8Array | null }>\n >;\n\n changeOptions: (options: Partial<ForkliftOptions>) => void;\n destroy: () => void;\n}\n\nexport type ForkliftSource = Enum<{\n remote: {\n url: string | string[];\n atBlock?: number | string;\n };\n // genesis: Record<string, string>;\n}>;\n\nexport type DelayMode = Enum<{\n manual: undefined;\n timer: number;\n}>;\n\nexport interface ForkliftOptions {\n buildBlockMode: DelayMode;\n finalizeMode: DelayMode;\n disableOnIdle?: boolean;\n mockSignatureHost?: (signature: Uint8Array) => boolean;\n key?: string;\n}\n\nconst defaultOptions: ForkliftOptions = {\n buildBlockMode: Enum(\"timer\", 100),\n finalizeMode: Enum(\"timer\", 2000),\n};\n\ntype Timeout = ReturnType<typeof setTimeout>;\nexport function forklift(\n sourceDef: ForkliftSource,\n opts?: Partial<ForkliftOptions>\n): Forklift {\n const source = createRemoteSource(sourceDef.value.url, {\n atBlock: sourceDef.value.atBlock,\n });\n let options = { ...defaultOptions, ...removeUndefinedProperties(opts) };\n const chain = createChain(source, options.key);\n const txPool = createTxPool(chain);\n\n runPrequeries(chain);\n\n const dmpSubject = new Subject<Array<DmpMessage>>();\n let dmpMsgQueue: DmpMessage[] = [];\n const dmpSub = dmpSubject.subscribe((messages) => {\n dmpMsgQueue = [...dmpMsgQueue, ...messages];\n });\n\n const umpSubject = new Subject<{ paraId: number; messages: Uint8Array[] }>();\n let umpMsgQueues: Record<number, Uint8Array[]> = {};\n const umpSub = umpSubject.subscribe((msg) => {\n umpMsgQueues = {\n ...umpMsgQueues,\n [msg.paraId]: [...(umpMsgQueues[msg.paraId] ?? []), ...msg.messages],\n };\n });\n\n const hrmpSubject = new Subject<{\n paraId: number;\n messages: Uint8Array[];\n }>();\n let hrmpMsgQueues: Record<number, Uint8Array[]> = {};\n const hrmpSub = hrmpSubject.subscribe(({ paraId, messages }) => {\n hrmpMsgQueues = {\n ...hrmpMsgQueues,\n [paraId]: [...(hrmpMsgQueues[paraId] ?? []), ...messages],\n };\n });\n\n let buildBlockQueue: Promise<void> | null = null;\n let blocksEnqueued = 0;\n const finalizeTimers = new Set<Timeout>();\n const newBlock = async (\n opts?: Partial<Omit<NewBlockOptions, \"xcm\">>,\n automatic?: boolean\n ) => {\n if (buildBlockQueue) {\n blocksEnqueued++;\n while (buildBlockQueue) {\n await buildBlockQueue;\n }\n blocksEnqueued--;\n }\n\n let resolve: () => void = () => {};\n buildBlockQueue = new Promise<void>(async (res) => (resolve = res));\n\n const dmp = dmpMsgQueue;\n dmpMsgQueue = [];\n\n const ump = umpMsgQueues;\n umpMsgQueues = {};\n for (const paraId in ump) {\n // This sets the storage of all live blocks, as technically any block being\n // produced past finalized should have these messages\n await pushUmp(chain, Number(paraId), ump[paraId]!);\n }\n\n const hrmp = hrmpMsgQueues;\n hrmpMsgQueues = {};\n\n try {\n const type =\n opts?.unsafeBlockHeight != null\n ? \"finalized\"\n : opts?.type ||\n (options.finalizeMode.type === \"timer\" &&\n options.finalizeMode.value === 0\n ? \"finalized\"\n : undefined);\n const parent = opts?.parent ?? (await firstValueFrom(chain.best$));\n const parentBlock = chain.getBlock(parent)!;\n\n const transactions = await txPool.getTxsForBlock(parentBlock);\n // An automatic trigger from tx pool should not produce the block if the block won't have any tx\n if (\n automatic &&\n transactions.length +\n dmp.length +\n Object.keys(ump).length +\n Object.keys(hrmp).length ===\n 0\n ) {\n log.debug(\"skipped automatic block: no transactions ready\");\n return parent;\n }\n\n logger.info(\"creating block\");\n const block = await chain.newBlock(type ?? \"fork\", {\n parent,\n transactions,\n disableOnIdle: opts?.disableOnIdle ?? options.disableOnIdle ?? false,\n xcm: { dmp, hrmp },\n storage: opts?.storage ?? {},\n unsafeBlockHeight: opts?.unsafeBlockHeight,\n });\n logger.info(`block ${block.hash} created`);\n\n if (type == null) {\n // best changes immediately if it became higher\n const [best, blocks] = await firstValueFrom(\n combineLatest([chain.best$, chain.blocks$])\n );\n if (block.header.number > blocks[best]!.header.number) {\n chain.changeBest(block.hash);\n }\n\n if (options.finalizeMode.type === \"timer\") {\n const timer = setTimeout(() => {\n try {\n chain.changeFinalized(block.hash);\n // in cases of competing forks it can fail\n } catch {}\n finalizeTimers.delete(timer);\n }, options.finalizeMode.value);\n finalizeTimers.add(timer);\n }\n }\n\n return block.hash;\n } catch (ex) {\n logger.error(ex, \"failed creating block\");\n\n // Restore messages that were dequeued but couldn't be processed\n dmpMsgQueue = [...dmp, ...dmpMsgQueue];\n for (const senderId in hrmp) {\n hrmpMsgQueues[senderId] = [\n ...(hrmp[senderId] ?? []),\n ...(hrmpMsgQueues[senderId] ?? []),\n ];\n }\n throw ex;\n } finally {\n buildBlockQueue = null;\n resolve();\n }\n };\n\n let txBlockPending = false;\n const txPoolSub = merge(\n txPool.txAdded$,\n dmpSubject,\n umpSubject,\n hrmpSubject\n ).subscribe(() => {\n if (options.buildBlockMode.type === \"manual\") return;\n if (txBlockPending || blocksEnqueued) {\n // Another tx has triggered a new block, this will get included\n return;\n }\n\n const delay = options.buildBlockMode.value;\n if (delay === 0) {\n return newBlock(undefined, true);\n }\n txBlockPending = true;\n setTimeout(() => {\n txBlockPending = false;\n if (!blocksEnqueued) newBlock(undefined, true);\n }, delay);\n });\n\n const xcm: ServerContext[\"xcm\"] = {\n pushDmp: (messages) => dmpSubject.next(messages),\n pushUmp: (paraId, messages) => umpSubject.next({ paraId, messages }),\n pushHrmp: (paraId, messages) => hrmpSubject.next({ paraId, messages }),\n };\n\n return {\n serve: createServer({ source, chain, txPool, newBlock, xcm }),\n newBlock: (opts) => newBlock(opts),\n changeBest: async (hash) => chain.changeBest(hash),\n changeFinalized: async (hash) => {\n finalizeTimers.forEach(clearTimeout);\n finalizeTimers.clear();\n return chain.changeFinalized(hash);\n },\n setStorage: async (hash, changes) => chain.setStorage(hash, changes),\n getStorageDiff: (hash, baseHash) => chain.getStorageDiff(hash, baseHash),\n changeOptions(opts) {\n options = { ...options, ...removeUndefinedProperties(opts) };\n },\n destroy() {\n dmpSub.unsubscribe();\n umpSub.unsubscribe();\n hrmpSub.unsubscribe();\n txPoolSub.unsubscribe();\n txPool.destroy();\n source.destroy();\n },\n };\n}\n\nconst removeUndefinedProperties = <T extends object>(value: T | undefined) =>\n value &&\n Object.fromEntries(\n Object.entries(value).filter(([, value]) => value !== undefined)\n );\n"],"names":["opts","value"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { forklift } from './forklift.js';
2
+ export { logger } from './logger.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1,11 @@
1
+ import pino from 'pino';
2
+
3
+ const logger = pino({
4
+ level: process.env.LOG_LEVEL ?? "info",
5
+ transport: process.env.LOG_JSON ? void 0 : {
6
+ target: "pino-pretty"
7
+ }
8
+ });
9
+
10
+ export { logger };
11
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sources":["../../src/logger.ts"],"sourcesContent":["import pino from \"pino\";\n\nexport const logger = pino({\n level: process.env.LOG_LEVEL ?? \"info\",\n transport: process.env.LOG_JSON\n ? undefined\n : {\n target: \"pino-pretty\",\n },\n});\n"],"names":[],"mappings":";;AAEO,MAAM,SAAS,IAAA,CAAK;AAAA,EACzB,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,SAAA,IAAa,MAAA;AAAA,EAChC,SAAA,EAAW,OAAA,CAAQ,GAAA,CAAI,QAAA,GACnB,MAAA,GACA;AAAA,IACE,MAAA,EAAQ;AAAA;AAEhB,CAAC;;;;"}
@@ -0,0 +1,19 @@
1
+ import { take } from 'rxjs';
2
+ import { getStorageCodecs } from './codecs.js';
3
+
4
+ const prequeries = ["Mmr.Nodes", "Paras.Heads"];
5
+ const runPrequeries = (chain) => {
6
+ chain.finalized$.pipe(take(1)).subscribe(async (hash) => {
7
+ const block = chain.getBlock(hash);
8
+ for (const pre of prequeries) {
9
+ const [pallet, entry] = pre.split(".");
10
+ const codec = await getStorageCodecs(block, pallet, entry);
11
+ if (codec) {
12
+ chain.getStorageDescendants(hash, codec.keys.enc());
13
+ }
14
+ }
15
+ });
16
+ };
17
+
18
+ export { runPrequeries };
19
+ //# sourceMappingURL=prequeries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prequeries.js","sources":["../../src/prequeries.ts"],"sourcesContent":["import { switchMap, take, withLatestFrom } from \"rxjs\";\nimport type { Chain } from \"./chain\";\nimport { getStorageCodecs } from \"./codecs\";\n\nconst prequeries = [\"Mmr.Nodes\", \"Paras.Heads\"];\n\nexport const runPrequeries = (chain: Chain) => {\n chain.finalized$.pipe(take(1)).subscribe(async (hash) => {\n const block = chain.getBlock(hash)!;\n for (const pre of prequeries) {\n const [pallet, entry] = pre.split(\".\");\n const codec = await getStorageCodecs(block, pallet!, entry!);\n if (codec) {\n chain.getStorageDescendants(hash, codec.keys.enc());\n }\n }\n });\n};\n"],"names":[],"mappings":";;;AAIA,MAAM,UAAA,GAAa,CAAC,WAAA,EAAa,aAAa,CAAA;AAEvC,MAAM,aAAA,GAAgB,CAAC,KAAA,KAAiB;AAC7C,EAAA,KAAA,CAAM,UAAA,CAAW,KAAK,IAAA,CAAK,CAAC,CAAC,CAAA,CAAE,SAAA,CAAU,OAAO,IAAA,KAAS;AACvD,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA;AACjC,IAAA,KAAA,MAAW,OAAO,UAAA,EAAY;AAC5B,MAAA,MAAM,CAAC,MAAA,EAAQ,KAAK,CAAA,GAAI,GAAA,CAAI,MAAM,GAAG,CAAA;AACrC,MAAA,MAAM,KAAA,GAAQ,MAAM,gBAAA,CAAiB,KAAA,EAAO,QAAS,KAAM,CAAA;AAC3D,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,KAAA,CAAM,qBAAA,CAAsB,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA;AAAA,MACpD;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH;;;;"}
@@ -0,0 +1,223 @@
1
+ import { blockHeader } from '@polkadot-api/substrate-bindings';
2
+ import { Binary } from 'polkadot-api';
3
+ import { Subscription, Observable, map, toArray, filter, firstValueFrom, combineLatest } from 'rxjs';
4
+ import { runRuntimeCall } from '../executor.js';
5
+ import { resolveStorageOperation } from './chainHead_v1.js';
6
+ import { errorResponse, getParams, respond, getUuid } from './rpc_utils.js';
7
+
8
+ const archiveStorageEvent = (subscription, result) => ({
9
+ jsonrpc: "2.0",
10
+ method: "archive_v1_storageEvent",
11
+ params: {
12
+ subscription,
13
+ result
14
+ }
15
+ });
16
+ const getSingleParam = (req) => Array.isArray(req.params) ? req.params[0] : req.params && typeof req.params === "object" ? Object.values(req.params)[0] : void 0;
17
+ const sendStorageError = (con, subscription, subscriptionId, error) => {
18
+ if (subscription.closed) return;
19
+ const message = error instanceof Error ? error.message : String(error);
20
+ con.send(
21
+ archiveStorageEvent(subscriptionId, {
22
+ event: "storageError",
23
+ error: message
24
+ })
25
+ );
26
+ };
27
+ const internalError = (req, error) => errorResponse(req, {
28
+ code: -32603,
29
+ message: error instanceof Error ? error.message : String(error)
30
+ });
31
+ const archive_v1_body = async (con, req, { chain, source }) => {
32
+ const { hash } = getParams(req, ["hash"]);
33
+ const block = chain.getBlock(hash);
34
+ if (block) {
35
+ con.send(respond(req, block.body.map(Binary.toHex)));
36
+ return;
37
+ }
38
+ try {
39
+ const body = await source.archive?.getBody(hash);
40
+ con.send(respond(req, body?.map(Binary.toHex) ?? null));
41
+ } catch (error) {
42
+ con.send(internalError(req, error));
43
+ }
44
+ };
45
+ const archive_v1_call = async (con, req, { chain, source }) => {
46
+ const {
47
+ hash,
48
+ function: fnName,
49
+ callParameters
50
+ } = getParams(req, ["hash", "function", "callParameters"]);
51
+ const block = chain.getBlock(hash);
52
+ if (block) {
53
+ try {
54
+ const output = await runRuntimeCall({
55
+ chain,
56
+ hash,
57
+ call: fnName,
58
+ params: callParameters
59
+ });
60
+ con.send(respond(req, { success: true, value: output.result }));
61
+ } catch (error) {
62
+ con.send(internalError(req, error));
63
+ }
64
+ return;
65
+ }
66
+ try {
67
+ const value = await source.archive?.call(hash, fnName, callParameters);
68
+ con.send(respond(req, value == null ? null : { success: true, value }));
69
+ } catch (error) {
70
+ con.send(internalError(req, error));
71
+ }
72
+ };
73
+ const archive_v1_finalizedHeight = async (con, req, { chain }) => {
74
+ const [finalizedHash, blocks] = await firstValueFrom(
75
+ combineLatest([chain.finalized$, chain.blocks$])
76
+ );
77
+ con.send(respond(req, blocks[finalizedHash].header.number));
78
+ };
79
+ const archive_v1_genesisHash = async (con, req, { source }) => {
80
+ try {
81
+ con.send(respond(req, (await source.getChainSpecData()).genesisHash));
82
+ } catch (error) {
83
+ con.send(internalError(req, error));
84
+ }
85
+ };
86
+ const archive_v1_hashByHeight = async (con, req, { chain, source }) => {
87
+ const { height } = getParams(req, ["height"]);
88
+ const [finalizedHash, blocks] = await firstValueFrom(
89
+ combineLatest([chain.finalized$, chain.blocks$])
90
+ );
91
+ const finalized = blocks[finalizedHash];
92
+ if (finalized.header.number < height) {
93
+ const result = [];
94
+ let children = [blocks[finalizedHash]];
95
+ while (children.length) {
96
+ const block2 = children.pop();
97
+ if (block2.header.number === height) {
98
+ result.push(block2.hash);
99
+ } else {
100
+ children = [
101
+ ...children,
102
+ ...block2.children.map((hash) => blocks[hash]).filter((v) => v != null)
103
+ ];
104
+ }
105
+ }
106
+ return con.send(respond(req, result));
107
+ }
108
+ let block = finalized;
109
+ while (block && block.header.number !== height) {
110
+ block = blocks[block.parent];
111
+ }
112
+ if (block) {
113
+ return con.send(respond(req, [block.hash]));
114
+ }
115
+ try {
116
+ const result = await source.archive?.getHashByHeight(height) ?? [];
117
+ con.send(respond(req, result));
118
+ } catch (error) {
119
+ con.send(internalError(req, error));
120
+ }
121
+ };
122
+ const archive_v1_header = async (con, req, { chain, source }) => {
123
+ const { hash } = getParams(req, ["hash"]);
124
+ const block = chain.getBlock(hash);
125
+ if (block) {
126
+ con.send(respond(req, Binary.toHex(blockHeader.enc(block.header))));
127
+ return;
128
+ }
129
+ try {
130
+ const header = await source.archive?.getHeader(hash);
131
+ con.send(
132
+ respond(req, header ? Binary.toHex(blockHeader.enc(header)) : null)
133
+ );
134
+ } catch (error) {
135
+ con.send(internalError(req, error));
136
+ }
137
+ };
138
+ const archive_v1_storage = (con, req, { chain, source }) => {
139
+ const { hash, items, childTrie } = getParams(req, [
140
+ "hash",
141
+ "items",
142
+ "childTrie"
143
+ ]);
144
+ if (childTrie)
145
+ return con.send(
146
+ errorResponse(req, {
147
+ code: -1,
148
+ message: "Child trie not implemented"
149
+ })
150
+ );
151
+ const subscriptionId = getUuid();
152
+ const subscription = new Subscription();
153
+ con.context.archive_v1_storage_subs[subscriptionId] = subscription;
154
+ const cleanup = () => {
155
+ delete con.context.archive_v1_storage_subs[subscriptionId];
156
+ subscription.unsubscribe();
157
+ };
158
+ con.send(respond(req, subscriptionId));
159
+ const items$ = chain.getBlock(hash) ? resolveStorageOperation(chain, hash, items) : (() => {
160
+ if (!source.archive) {
161
+ throw new Error("Archive source not available");
162
+ }
163
+ return new Observable((obs) => {
164
+ source.archive.storageSubscription(
165
+ hash,
166
+ items,
167
+ childTrie,
168
+ (item) => obs.next(item),
169
+ (e) => obs.error(e),
170
+ () => obs.complete()
171
+ );
172
+ }).pipe(
173
+ map((item) => item),
174
+ toArray(),
175
+ filter((v) => v.length > 0)
176
+ );
177
+ })();
178
+ subscription.add(
179
+ items$.subscribe({
180
+ next: (items2) => items2.forEach(
181
+ (item) => con.send(
182
+ archiveStorageEvent(subscriptionId, {
183
+ event: "storage",
184
+ ...item
185
+ })
186
+ )
187
+ ),
188
+ error: (error) => {
189
+ sendStorageError(con, subscription, subscriptionId, error);
190
+ cleanup();
191
+ },
192
+ complete: () => {
193
+ con.send(archiveStorageEvent(subscriptionId, { event: "storageDone" }));
194
+ cleanup();
195
+ }
196
+ })
197
+ );
198
+ };
199
+ const archive_v1_stopStorage = (con, req) => {
200
+ const subscriptionId = getSingleParam(req);
201
+ con.send(respond(req, null));
202
+ if (!subscriptionId) return;
203
+ con.context.archive_v1_storage_subs[subscriptionId]?.unsubscribe();
204
+ };
205
+ const archive_v1_storageDiff = (con, req) => {
206
+ con.send(
207
+ errorResponse(req, {
208
+ code: -1,
209
+ message: "Not implemented"
210
+ })
211
+ );
212
+ };
213
+ const archive_v1_stopStorageDiff = (con, req) => {
214
+ con.send(
215
+ errorResponse(req, {
216
+ code: -1,
217
+ message: "Not implemented"
218
+ })
219
+ );
220
+ };
221
+
222
+ export { archive_v1_body, archive_v1_call, archive_v1_finalizedHeight, archive_v1_genesisHash, archive_v1_hashByHeight, archive_v1_header, archive_v1_stopStorage, archive_v1_stopStorageDiff, archive_v1_storage, archive_v1_storageDiff };
223
+ //# sourceMappingURL=archive_v1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive_v1.js","sources":["../../../src/rpc/archive_v1.ts"],"sourcesContent":["import { blockHeader } from \"@polkadot-api/substrate-bindings\";\nimport type {\n JsonRpcMessage,\n JsonRpcRequest,\n StorageItemResponse,\n} from \"@polkadot-api/substrate-client\";\nimport { Binary, type HexString } from \"polkadot-api\";\nimport {\n combineLatest,\n filter,\n firstValueFrom,\n map,\n Observable,\n Subscription,\n toArray,\n} from \"rxjs\";\nimport type { Block } from \"../block-builder/create-block\";\nimport { runRuntimeCall } from \"../executor\";\nimport { resolveStorageOperation, type StorageItem } from \"./chainHead_v1\";\nimport {\n errorResponse,\n getParams,\n getUuid,\n respond,\n type RpcMethod,\n} from \"./rpc_utils\";\n\ntype ArchiveStorageItem = {\n key: HexString;\n type:\n | \"value\"\n | \"hash\"\n | \"closestDescendantMerkleValue\"\n | \"descendantsValues\"\n | \"descendantsHashes\";\n paginationStartKey?: HexString;\n};\n\nconst archiveStorageEvent = (\n subscription: string,\n result: any\n): JsonRpcMessage => ({\n jsonrpc: \"2.0\",\n method: \"archive_v1_storageEvent\",\n params: {\n subscription,\n result,\n },\n});\n\nconst getSingleParam = (req: JsonRpcRequest): string | undefined =>\n Array.isArray(req.params)\n ? req.params[0]\n : req.params && typeof req.params === \"object\"\n ? (Object.values(req.params)[0] as string | undefined)\n : undefined;\n\nconst sendStorageError = (\n con: Parameters<RpcMethod>[0],\n subscription: Subscription,\n subscriptionId: string,\n error: unknown\n) => {\n if (subscription.closed) return;\n const message = error instanceof Error ? error.message : String(error);\n con.send(\n archiveStorageEvent(subscriptionId, {\n event: \"storageError\",\n error: message,\n })\n );\n};\n\nconst internalError = (req: JsonRpcRequest, error: unknown) =>\n errorResponse(req, {\n code: -32603,\n message: error instanceof Error ? error.message : String(error),\n });\n\nexport const archive_v1_body: RpcMethod<{\n hash: HexString;\n}> = async (con, req, { chain, source }) => {\n const { hash } = getParams(req, [\"hash\"]);\n\n const block = chain.getBlock(hash);\n if (block) {\n con.send(respond(req, block.body.map(Binary.toHex)));\n return;\n }\n\n try {\n const body = await source.archive?.getBody(hash);\n con.send(respond(req, body?.map(Binary.toHex) ?? null));\n } catch (error) {\n con.send(internalError(req, error));\n }\n};\n\nexport const archive_v1_call: RpcMethod<{\n hash: HexString;\n function: string;\n callParameters: HexString;\n}> = async (con, req, { chain, source }) => {\n const {\n hash,\n function: fnName,\n callParameters,\n } = getParams(req, [\"hash\", \"function\", \"callParameters\"]);\n\n const block = chain.getBlock(hash);\n if (block) {\n try {\n const output = await runRuntimeCall({\n chain,\n hash,\n call: fnName,\n params: callParameters,\n });\n con.send(respond(req, { success: true, value: output.result }));\n } catch (error) {\n con.send(internalError(req, error));\n }\n return;\n }\n\n try {\n const value = await source.archive?.call(hash, fnName, callParameters);\n con.send(respond(req, value == null ? null : { success: true, value }));\n } catch (error) {\n con.send(internalError(req, error));\n }\n};\n\nexport const archive_v1_finalizedHeight: RpcMethod = async (\n con,\n req,\n { chain }\n) => {\n const [finalizedHash, blocks] = await firstValueFrom(\n combineLatest([chain.finalized$, chain.blocks$])\n );\n con.send(respond(req, blocks[finalizedHash]!.header.number));\n};\n\nexport const archive_v1_genesisHash: RpcMethod = async (\n con,\n req,\n { source }\n) => {\n try {\n con.send(respond(req, (await source.getChainSpecData()).genesisHash));\n } catch (error) {\n con.send(internalError(req, error));\n }\n};\n\nexport const archive_v1_hashByHeight: RpcMethod<{\n height: number;\n}> = async (con, req, { chain, source }) => {\n const { height } = getParams(req, [\"height\"]);\n const [finalizedHash, blocks] = await firstValueFrom(\n combineLatest([chain.finalized$, chain.blocks$])\n );\n\n const finalized = blocks[finalizedHash]!;\n if (finalized.header.number < height) {\n // Get all matching blocks under finalized\n const result: HexString[] = [];\n let children = [blocks[finalizedHash]];\n while (children.length) {\n const block = children.pop()!;\n if (block.header.number === height) {\n result.push(block.hash);\n } else {\n children = [\n ...children,\n ...block.children\n .map((hash) => blocks[hash])\n .filter((v) => v != null),\n ];\n }\n }\n return con.send(respond(req, result));\n }\n\n // Find block\n let block: Block | undefined = finalized;\n while (block && block.header.number !== height) {\n block = blocks[block.parent];\n }\n if (block) {\n return con.send(respond(req, [block.hash]));\n }\n\n try {\n const result = (await source.archive?.getHashByHeight(height)) ?? [];\n con.send(respond(req, result));\n } catch (error) {\n con.send(internalError(req, error));\n }\n};\n\nexport const archive_v1_header: RpcMethod<{\n hash: HexString;\n}> = async (con, req, { chain, source }) => {\n const { hash } = getParams(req, [\"hash\"]);\n\n const block = chain.getBlock(hash);\n if (block) {\n con.send(respond(req, Binary.toHex(blockHeader.enc(block.header))));\n return;\n }\n\n try {\n const header = await source.archive?.getHeader(hash);\n con.send(\n respond(req, header ? Binary.toHex(blockHeader.enc(header)) : null)\n );\n } catch (error) {\n con.send(internalError(req, error));\n }\n};\n\nexport const archive_v1_storage: RpcMethod<{\n hash: HexString;\n items: ArchiveStorageItem[];\n childTrie: HexString | null;\n}> = (con, req, { chain, source }) => {\n const { hash, items, childTrie } = getParams(req, [\n \"hash\",\n \"items\",\n \"childTrie\",\n ]);\n\n if (childTrie)\n // TODO\n return con.send(\n errorResponse(req, {\n code: -1,\n message: \"Child trie not implemented\",\n })\n );\n\n const subscriptionId = getUuid();\n const subscription = new Subscription();\n con.context.archive_v1_storage_subs[subscriptionId] = subscription;\n const cleanup = () => {\n delete con.context.archive_v1_storage_subs[subscriptionId];\n subscription.unsubscribe();\n };\n con.send(respond(req, subscriptionId));\n\n const items$ = chain.getBlock(hash)\n ? resolveStorageOperation(chain, hash, items)\n : (() => {\n if (!source.archive) {\n throw new Error(\"Archive source not available\");\n }\n\n return new Observable<StorageItemResponse>((obs) => {\n source.archive!.storageSubscription(\n hash,\n items,\n childTrie,\n (item) => obs.next(item),\n (e) => obs.error(e),\n () => obs.complete()\n );\n }).pipe(\n map((item): StorageItem => item),\n toArray(),\n filter((v) => v.length > 0)\n );\n })();\n\n subscription.add(\n items$.subscribe({\n next: (items) =>\n items.forEach((item) =>\n con.send(\n archiveStorageEvent(subscriptionId, {\n event: \"storage\",\n ...item,\n })\n )\n ),\n error: (error) => {\n sendStorageError(con, subscription, subscriptionId, error);\n cleanup();\n },\n complete: () => {\n con.send(archiveStorageEvent(subscriptionId, { event: \"storageDone\" }));\n cleanup();\n },\n })\n );\n};\n\nexport const archive_v1_stopStorage: RpcMethod = (con, req) => {\n const subscriptionId = getSingleParam(req);\n con.send(respond(req, null));\n if (!subscriptionId) return;\n\n con.context.archive_v1_storage_subs[subscriptionId]?.unsubscribe();\n};\n\nexport const archive_v1_storageDiff: RpcMethod = (con, req) => {\n con.send(\n errorResponse(req, {\n code: -1,\n message: \"Not implemented\",\n })\n );\n};\n\nexport const archive_v1_stopStorageDiff: RpcMethod = (con, req) => {\n con.send(\n errorResponse(req, {\n code: -1,\n message: \"Not implemented\",\n })\n );\n};\n"],"names":["block","items"],"mappings":"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"}