@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,383 @@
1
+ import { blockHeader } from '@polkadot-api/substrate-bindings';
2
+ import { Binary } from 'polkadot-api';
3
+ import { Subscription, firstValueFrom, combineLatest, withLatestFrom, from, map, merge, filter } from 'rxjs';
4
+ import { finalizedAndPruned$ } from '../chain.js';
5
+ import { logger } from '../logger.js';
6
+ import { runRuntimeCall } from '../executor.js';
7
+ import { getParams, respond, errorResponse, getUuid } from './rpc_utils.js';
8
+
9
+ const log = logger.child({ module: "chainHead_v1" });
10
+ const followEvent = (subscription, result) => ({
11
+ jsonrpc: "2.0",
12
+ method: "chainHead_v1_followEvent",
13
+ params: {
14
+ subscription,
15
+ result
16
+ }
17
+ });
18
+ const blockNotPinned = (req) => errorResponse(req, {
19
+ code: -32801,
20
+ message: "Block not pinned"
21
+ });
22
+ const blockNotReadable = (req) => errorResponse(req, {
23
+ code: -32603,
24
+ message: "Block not readable"
25
+ });
26
+ const chainHead_v1_follow = async (con, req, { chain }) => {
27
+ const { withRuntime } = getParams(req, ["withRuntime"]);
28
+ const subId = getUuid();
29
+ const ctx = con.context.chainHead_v1_subs[subId] = {
30
+ pinnedBlocks: /* @__PURE__ */ new Set(),
31
+ operations: {},
32
+ subscription: new Subscription()
33
+ };
34
+ con.send(respond(req, subId));
35
+ const [finalized, blocks] = await firstValueFrom(
36
+ combineLatest([chain.finalized$, chain.blocks$])
37
+ );
38
+ const finalizedBlockHashes = [finalized];
39
+ ctx.pinnedBlocks.add(finalized);
40
+ let block = finalized;
41
+ let nextBlockHeight = blocks[block].header.number;
42
+ for (let i = 0; i < 5 && blocks[block]?.parent in blocks; i++) {
43
+ block = blocks[block].parent;
44
+ if (!blocks[block] || blocks[block].header.number !== nextBlockHeight - 1)
45
+ break;
46
+ nextBlockHeight = blocks[block].header.number;
47
+ ctx.pinnedBlocks.add(block);
48
+ finalizedBlockHashes.push(block);
49
+ }
50
+ finalizedBlockHashes.reverse();
51
+ con.send(
52
+ followEvent(subId, {
53
+ event: "initialized",
54
+ finalizedBlockHashes,
55
+ finalizedBlockRuntime: withRuntime ? blocks[finalized].runtime : void 0
56
+ })
57
+ );
58
+ const sendChildren = (hash) => {
59
+ const block2 = blocks[hash];
60
+ for (const child of block2.children) {
61
+ const childBlock = blocks[child];
62
+ if (!childBlock) {
63
+ log.error({ parent: hash, child }, "child block not found");
64
+ continue;
65
+ }
66
+ ctx.pinnedBlocks.add(child);
67
+ con.send(
68
+ followEvent(subId, {
69
+ event: "newBlock",
70
+ blockHash: child,
71
+ parentBlockHash: hash,
72
+ newRuntime: withRuntime ? childBlock.hasNewRuntime : void 0
73
+ })
74
+ );
75
+ sendChildren(child);
76
+ }
77
+ };
78
+ sendChildren(finalized);
79
+ ctx.subscription.add(
80
+ con.disconnect$.subscribe(() => ctx.subscription.unsubscribe())
81
+ );
82
+ ctx.subscription.add(
83
+ chain.newBlocks$.pipe(withLatestFrom(chain.blocks$)).subscribe(([blockHash, blocks2]) => {
84
+ const block2 = blocks2[blockHash];
85
+ const prevBlock = blocks2[block2.parent];
86
+ if (prevBlock) {
87
+ if (block2.header.number != prevBlock.header.number + 1) {
88
+ for (const op of Object.values(ctx.operations)) {
89
+ op.unsubscribe();
90
+ }
91
+ ctx.subscription.unsubscribe();
92
+ delete con.context.chainHead_v1_subs[subId];
93
+ setTimeout(() => {
94
+ con.send(
95
+ followEvent(subId, {
96
+ event: "stop"
97
+ })
98
+ );
99
+ });
100
+ return;
101
+ }
102
+ }
103
+ ctx.pinnedBlocks.add(blockHash);
104
+ con.send(
105
+ followEvent(subId, {
106
+ event: "newBlock",
107
+ blockHash,
108
+ parentBlockHash: block2.parent,
109
+ newRuntime: withRuntime && block2.hasNewRuntime ? block2.runtime : void 0
110
+ })
111
+ );
112
+ })
113
+ );
114
+ ctx.subscription.add(
115
+ chain.best$.subscribe((bestBlockHash) => {
116
+ con.send(
117
+ followEvent(subId, { event: "bestBlockChanged", bestBlockHash })
118
+ );
119
+ })
120
+ );
121
+ ctx.subscription.add(
122
+ finalizedAndPruned$(chain).subscribe(({ finalized: finalized2, pruned }) => {
123
+ con.send(
124
+ followEvent(subId, {
125
+ event: "finalized",
126
+ finalizedBlockHashes: finalized2,
127
+ prunedBlockHashes: pruned
128
+ })
129
+ );
130
+ })
131
+ );
132
+ };
133
+ const chainHead_v1_unfollow = async (con, req) => {
134
+ const { followSubscription } = getParams(req, ["followSubscription"]);
135
+ const followSub = con.context.chainHead_v1_subs[followSubscription];
136
+ con.send(respond(req, null));
137
+ if (!followSub) return;
138
+ for (const op of Object.values(followSub.operations)) {
139
+ op.unsubscribe();
140
+ }
141
+ followSub.subscription.unsubscribe();
142
+ delete con.context.chainHead_v1_subs[followSubscription];
143
+ };
144
+ const chainHead_v1_header = (con, req, { chain }) => {
145
+ const { followSubscription, hash } = getParams(req, [
146
+ "followSubscription",
147
+ "hash"
148
+ ]);
149
+ const sub = con.context.chainHead_v1_subs[followSubscription];
150
+ if (!sub) return con.send(respond(req, null));
151
+ if (!sub.pinnedBlocks.has(hash)) return con.send(blockNotPinned(req));
152
+ const block = chain.getBlock(hash);
153
+ if (!block) return con.send(blockNotReadable(req));
154
+ con.send(respond(req, Binary.toHex(blockHeader.enc(block.header))));
155
+ };
156
+ const chainHead_v1_storage = (con, req, { chain }) => {
157
+ const { followSubscription, hash, items, childTrie } = getParams(req, [
158
+ "followSubscription",
159
+ "hash",
160
+ "items",
161
+ "childTrie"
162
+ ]);
163
+ const sub = con.context.chainHead_v1_subs[followSubscription];
164
+ if (!sub) return con.send(respond(req, { result: "limitReached" }));
165
+ if (!sub.pinnedBlocks.has(hash)) return con.send(blockNotPinned(req));
166
+ if (childTrie)
167
+ return con.send(blockNotReadable(req));
168
+ const block = chain.getBlock(hash);
169
+ if (!block) return con.send(blockNotReadable(req));
170
+ const opId = getUuid();
171
+ const subscription = new Subscription();
172
+ sub.operations[opId] = subscription;
173
+ const cleanup = () => {
174
+ delete sub.operations[opId];
175
+ subscription.unsubscribe();
176
+ };
177
+ con.send(
178
+ respond(req, {
179
+ result: "started",
180
+ operationId: opId,
181
+ discardedItems: []
182
+ })
183
+ );
184
+ subscription.add(
185
+ resolveStorageOperation(chain, hash, items).subscribe({
186
+ next: (items2) => con.send(
187
+ followEvent(followSubscription, {
188
+ event: "operationStorageItems",
189
+ operationId: opId,
190
+ items: items2
191
+ })
192
+ ),
193
+ error: (e) => {
194
+ log.error(e, "storage operation error");
195
+ con.send(
196
+ followEvent(followSubscription, {
197
+ event: "operationError",
198
+ operationId: opId,
199
+ error: e.message
200
+ })
201
+ );
202
+ cleanup();
203
+ },
204
+ complete: () => {
205
+ con.send(
206
+ followEvent(followSubscription, {
207
+ event: "operationStorageDone",
208
+ operationId: opId
209
+ })
210
+ );
211
+ cleanup();
212
+ }
213
+ })
214
+ );
215
+ };
216
+ const resolveStorageOperation = (chain, hash, items) => {
217
+ const nodeQueries = items.filter(
218
+ (it) => it.type === "closestDescendantMerkleValue" || it.type === "hash" || it.type === "value"
219
+ );
220
+ const nodeQueries$ = from(
221
+ nodeQueries.length ? chain.getStorageBatch(
222
+ hash,
223
+ nodeQueries.map((it) => it.key)
224
+ ) : []
225
+ ).pipe(
226
+ map(
227
+ (nodes) => nodes.flatMap((node, i) => {
228
+ const { key, type } = nodeQueries[i];
229
+ if (type === "closestDescendantMerkleValue") {
230
+ return [{ key, [type]: Binary.toHex(node.hash) }];
231
+ }
232
+ if (!node.value) return [];
233
+ return [
234
+ type === "hash" ? { key, hash: Binary.toHex(node.hash) } : { key, value: Binary.toHex(node.value) }
235
+ ];
236
+ })
237
+ )
238
+ );
239
+ const descendantQueries = items.filter(
240
+ (it) => it.type === "descendantsHashes" || it.type === "descendantsValues"
241
+ );
242
+ const descendantQueries$ = descendantQueries.map(
243
+ (query) => from(chain.getStorageDescendants(hash, query.key)).pipe(
244
+ map(
245
+ (nodes) => Object.entries(nodes).map(
246
+ ([key, node]) => query.type === "descendantsHashes" ? {
247
+ key,
248
+ hash: Binary.toHex(node.hash)
249
+ } : node.value ? {
250
+ key,
251
+ value: Binary.toHex(node.value)
252
+ } : null
253
+ ).filter((v) => v != null)
254
+ )
255
+ )
256
+ );
257
+ return merge(nodeQueries$, ...descendantQueries$).pipe(
258
+ filter((v) => v.length > 0)
259
+ );
260
+ };
261
+ const chainHead_v1_call = (con, req, { chain }) => {
262
+ const {
263
+ followSubscription,
264
+ hash,
265
+ function: fnName,
266
+ callParameters
267
+ } = getParams(req, [
268
+ "followSubscription",
269
+ "hash",
270
+ "function",
271
+ "callParameters"
272
+ ]);
273
+ const sub = con.context.chainHead_v1_subs[followSubscription];
274
+ if (!sub) return con.send(respond(req, { result: "limitReached" }));
275
+ if (!sub.pinnedBlocks.has(hash)) return con.send(blockNotPinned(req));
276
+ const block = chain.getBlock(hash);
277
+ if (!block) return con.send(blockNotReadable(req));
278
+ const opId = getUuid();
279
+ const subscription = new Subscription();
280
+ sub.operations[opId] = subscription;
281
+ const cleanup = () => {
282
+ delete sub.operations[opId];
283
+ subscription.unsubscribe();
284
+ };
285
+ con.send(
286
+ respond(req, {
287
+ result: "started",
288
+ operationId: opId
289
+ })
290
+ );
291
+ subscription.add(
292
+ from(
293
+ runRuntimeCall({
294
+ chain,
295
+ hash,
296
+ call: fnName,
297
+ params: callParameters
298
+ })
299
+ ).subscribe({
300
+ next: (output) => con.send(
301
+ followEvent(followSubscription, {
302
+ event: "operationCallDone",
303
+ operationId: opId,
304
+ output: output.result
305
+ })
306
+ ),
307
+ error: (e) => {
308
+ log.error(e, "call operation error");
309
+ con.send(
310
+ followEvent(followSubscription, {
311
+ event: "operationError",
312
+ operationId: opId,
313
+ error: e.message
314
+ })
315
+ );
316
+ cleanup();
317
+ },
318
+ complete: () => {
319
+ cleanup();
320
+ }
321
+ })
322
+ );
323
+ };
324
+ const chainHead_v1_body = (con, req, { chain }) => {
325
+ const { followSubscription, hash } = getParams(req, [
326
+ "followSubscription",
327
+ "hash"
328
+ ]);
329
+ const sub = con.context.chainHead_v1_subs[followSubscription];
330
+ if (!sub) return con.send(respond(req, { result: "limitReached" }));
331
+ if (!sub.pinnedBlocks.has(hash)) return con.send(blockNotPinned(req));
332
+ const block = chain.getBlock(hash);
333
+ if (!block) return con.send(blockNotReadable(req));
334
+ const opId = getUuid();
335
+ con.send(
336
+ respond(req, {
337
+ result: "started",
338
+ operationId: opId
339
+ })
340
+ );
341
+ con.send(
342
+ followEvent(followSubscription, {
343
+ event: "operationBodyDone",
344
+ operationId: opId,
345
+ value: block.body.map(Binary.toHex)
346
+ })
347
+ );
348
+ };
349
+ const chainHead_v1_stopOperation = (con, req) => {
350
+ const { followSubscription, operationId } = getParams(req, [
351
+ "followSubscription",
352
+ "operationId"
353
+ ]);
354
+ con.send(respond(req, null));
355
+ const sub = con.context.chainHead_v1_subs[followSubscription];
356
+ if (!sub?.operations[operationId]) return;
357
+ sub.operations[operationId].unsubscribe();
358
+ delete sub.operations[operationId];
359
+ };
360
+ const chainHead_v1_unpin = (con, req) => {
361
+ const { followSubscription, hashOrHashes } = getParams(req, [
362
+ "followSubscription",
363
+ "hashOrHashes"
364
+ ]);
365
+ const sub = con.context.chainHead_v1_subs[followSubscription];
366
+ if (!sub) return con.send(respond(req, null));
367
+ const hashes = Array.isArray(hashOrHashes) ? hashOrHashes : [hashOrHashes];
368
+ const uniqueHashes = new Set(hashes);
369
+ if (uniqueHashes.size != hashes.length)
370
+ return con.send(
371
+ errorResponse(req, {
372
+ code: -32804,
373
+ message: "Duplicate hashes"
374
+ })
375
+ );
376
+ if (hashes.some((hash) => !sub.pinnedBlocks.has(hash)))
377
+ return con.send(blockNotPinned(req));
378
+ hashes.forEach((hash) => sub.pinnedBlocks.delete(hash));
379
+ return con.send(respond(req, null));
380
+ };
381
+
382
+ export { chainHead_v1_body, chainHead_v1_call, chainHead_v1_follow, chainHead_v1_header, chainHead_v1_stopOperation, chainHead_v1_storage, chainHead_v1_unfollow, chainHead_v1_unpin, resolveStorageOperation };
383
+ //# sourceMappingURL=chainHead_v1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chainHead_v1.js","sources":["../../../src/rpc/chainHead_v1.ts"],"sourcesContent":["import { blockHeader } from \"@polkadot-api/substrate-bindings\";\nimport type {\n JsonRpcMessage,\n JsonRpcRequest,\n} from \"@polkadot-api/substrate-client\";\nimport type { HexString } from \"polkadot-api\";\nimport { Binary } from \"polkadot-api\";\nimport {\n combineLatest,\n filter,\n firstValueFrom,\n from,\n map,\n merge,\n Subscription,\n withLatestFrom,\n} from \"rxjs\";\nimport { finalizedAndPruned$, type Chain } from \"../chain\";\nimport { logger } from \"../logger\";\n\nconst log = logger.child({ module: \"chainHead_v1\" });\nimport { runRuntimeCall } from \"../executor\";\nimport {\n errorResponse,\n getParams,\n getUuid,\n respond,\n type RpcMethod,\n} from \"./rpc_utils\";\nimport type { Block } from \"../block-builder/create-block\";\n\nconst followEvent = (subscription: string, result: any): JsonRpcMessage => ({\n jsonrpc: \"2.0\",\n method: \"chainHead_v1_followEvent\",\n params: {\n subscription,\n result,\n },\n});\nconst blockNotPinned = (req: JsonRpcRequest) =>\n errorResponse(req, {\n code: -32801,\n message: \"Block not pinned\",\n });\nconst blockNotReadable = (req: JsonRpcRequest) =>\n errorResponse(req, {\n code: -32603,\n message: \"Block not readable\",\n });\n\nexport const chainHead_v1_follow: RpcMethod<{\n withRuntime: boolean;\n}> = async (con, req, { chain }) => {\n const { withRuntime } = getParams(req, [\"withRuntime\"]);\n\n const subId = getUuid();\n const ctx: (typeof con.context.chainHead_v1_subs)[string] =\n (con.context.chainHead_v1_subs[subId] = {\n pinnedBlocks: new Set<string>(),\n operations: {},\n subscription: new Subscription(),\n });\n con.send(respond(req, subId));\n\n const [finalized, blocks] = await firstValueFrom(\n combineLatest([chain.finalized$, chain.blocks$])\n );\n\n const finalizedBlockHashes = [finalized];\n ctx.pinnedBlocks.add(finalized);\n let block = finalized;\n let nextBlockHeight = blocks[block]!.header.number;\n for (let i = 0; i < 5 && blocks[block]?.parent! in blocks; i++) {\n block = blocks[block]!.parent;\n // due to unsafeBlockHeight there could be gaps we can't expose\n if (!blocks[block] || blocks[block]!.header.number !== nextBlockHeight - 1)\n break;\n nextBlockHeight = blocks[block]!.header.number;\n ctx.pinnedBlocks.add(block);\n finalizedBlockHashes.push(block);\n }\n finalizedBlockHashes.reverse();\n con.send(\n followEvent(subId, {\n event: \"initialized\",\n finalizedBlockHashes,\n finalizedBlockRuntime: withRuntime\n ? blocks[finalized]!.runtime\n : undefined,\n })\n );\n\n const sendChildren = (hash: HexString) => {\n const block = blocks[hash]!;\n for (const child of block.children) {\n const childBlock = blocks[child];\n if (!childBlock) {\n log.error({ parent: hash, child }, \"child block not found\");\n continue;\n }\n ctx.pinnedBlocks.add(child);\n con.send(\n followEvent(subId, {\n event: \"newBlock\",\n blockHash: child,\n parentBlockHash: hash,\n newRuntime: withRuntime ? childBlock.hasNewRuntime : undefined,\n })\n );\n sendChildren(child);\n }\n };\n sendChildren(finalized);\n\n ctx.subscription.add(\n con.disconnect$.subscribe(() => ctx.subscription.unsubscribe())\n );\n\n ctx.subscription.add(\n chain.newBlocks$\n .pipe(withLatestFrom(chain.blocks$))\n .subscribe(([blockHash, blocks]) => {\n const block = blocks[blockHash!]!;\n const prevBlock = blocks[block.parent];\n if (prevBlock) {\n if (block.header.number != prevBlock.header.number + 1) {\n for (const op of Object.values(ctx.operations)) {\n op.unsubscribe();\n }\n ctx.subscription.unsubscribe();\n delete con.context.chainHead_v1_subs[subId];\n\n // Enqueue in a macrotask because block needs to be finalized before re-subscription\n // and we risk having synchronous re-entry.\n setTimeout(() => {\n con.send(\n followEvent(subId, {\n event: \"stop\",\n })\n );\n });\n return;\n }\n }\n\n ctx.pinnedBlocks.add(blockHash!);\n con.send(\n followEvent(subId, {\n event: \"newBlock\",\n blockHash,\n parentBlockHash: block.parent,\n newRuntime:\n withRuntime && block.hasNewRuntime ? block.runtime : undefined,\n })\n );\n })\n );\n ctx.subscription.add(\n chain.best$.subscribe((bestBlockHash) => {\n con.send(\n followEvent(subId, { event: \"bestBlockChanged\", bestBlockHash })\n );\n })\n );\n ctx.subscription.add(\n finalizedAndPruned$(chain).subscribe(({ finalized, pruned }) => {\n con.send(\n followEvent(subId, {\n event: \"finalized\",\n finalizedBlockHashes: finalized,\n prunedBlockHashes: pruned,\n })\n );\n })\n );\n};\n\nexport const chainHead_v1_unfollow: RpcMethod<{\n followSubscription: string;\n}> = async (con, req) => {\n const { followSubscription } = getParams(req, [\"followSubscription\"]);\n\n const followSub = con.context.chainHead_v1_subs[followSubscription];\n con.send(respond(req, null));\n\n if (!followSub) return;\n for (const op of Object.values(followSub.operations)) {\n op.unsubscribe();\n }\n followSub.subscription.unsubscribe();\n delete con.context.chainHead_v1_subs[followSubscription];\n};\n\nexport const chainHead_v1_header: RpcMethod<{\n followSubscription: string;\n hash: string;\n}> = (con, req, { chain }) => {\n const { followSubscription, hash } = getParams(req, [\n \"followSubscription\",\n \"hash\",\n ]);\n\n const sub = con.context.chainHead_v1_subs[followSubscription];\n if (!sub) return con.send(respond(req, null));\n\n if (!sub.pinnedBlocks.has(hash)) return con.send(blockNotPinned(req));\n\n const block = chain.getBlock(hash);\n if (!block) return con.send(blockNotReadable(req));\n\n con.send(respond(req, Binary.toHex(blockHeader.enc(block.header))));\n};\n\nexport const chainHead_v1_storage: RpcMethod = (\n con,\n req: JsonRpcRequest<{\n followSubscription: string;\n hash: HexString;\n items: Array<{\n key: HexString;\n type:\n | \"value\"\n | \"hash\"\n | \"closestDescendantMerkleValue\"\n | \"descendantsValues\"\n | \"descendantsHashes\";\n }>;\n childTrie: HexString | null;\n }>,\n { chain }\n) => {\n const { followSubscription, hash, items, childTrie } = getParams(req, [\n \"followSubscription\",\n \"hash\",\n \"items\",\n \"childTrie\",\n ]);\n\n const sub = con.context.chainHead_v1_subs[followSubscription];\n if (!sub) return con.send(respond(req, { result: \"limitReached\" }));\n\n if (!sub.pinnedBlocks.has(hash)) return con.send(blockNotPinned(req));\n\n if (childTrie)\n // TODO\n return con.send(blockNotReadable(req));\n\n const block = chain.getBlock(hash);\n if (!block) return con.send(blockNotReadable(req));\n\n const opId = getUuid();\n const subscription = new Subscription();\n sub.operations[opId] = subscription;\n const cleanup = () => {\n delete sub.operations[opId];\n subscription.unsubscribe();\n };\n\n con.send(\n respond(req, {\n result: \"started\",\n operationId: opId,\n discardedItems: [],\n })\n );\n\n subscription.add(\n resolveStorageOperation(chain, hash, items).subscribe({\n next: (items) =>\n con.send(\n followEvent(followSubscription, {\n event: \"operationStorageItems\",\n operationId: opId,\n items,\n })\n ),\n error: (e) => {\n log.error(e, \"storage operation error\");\n con.send(\n followEvent(followSubscription, {\n event: \"operationError\",\n operationId: opId,\n error: e.message,\n })\n );\n cleanup();\n },\n complete: () => {\n con.send(\n followEvent(followSubscription, {\n event: \"operationStorageDone\",\n operationId: opId,\n })\n );\n cleanup();\n },\n })\n );\n};\n\nexport type StorageItem = {\n key: HexString;\n value?: HexString;\n hash?: HexString;\n closestDescendantMerkleValue?: HexString;\n};\nexport const resolveStorageOperation = (\n chain: Chain,\n hash: HexString,\n items: Array<{\n key: HexString;\n type:\n | \"value\"\n | \"hash\"\n | \"closestDescendantMerkleValue\"\n | \"descendantsValues\"\n | \"descendantsHashes\";\n }>\n) => {\n const nodeQueries = items.filter(\n (it) =>\n it.type === \"closestDescendantMerkleValue\" ||\n it.type === \"hash\" ||\n it.type === \"value\"\n );\n\n // TODO pagination\n const nodeQueries$ = from(\n nodeQueries.length\n ? chain.getStorageBatch(\n hash,\n nodeQueries.map((it) => it.key)\n )\n : []\n ).pipe(\n map((nodes) =>\n nodes.flatMap((node, i): Array<StorageItem> => {\n const { key, type } = nodeQueries[i]!;\n if (type === \"closestDescendantMerkleValue\") {\n return [{ key, [type]: Binary.toHex(node.hash) }];\n }\n if (!node.value) return [];\n return [\n type === \"hash\"\n ? { key, hash: Binary.toHex(node.hash) }\n : { key, value: Binary.toHex(node.value) },\n ];\n })\n )\n );\n\n const descendantQueries = items.filter(\n (it) => it.type === \"descendantsHashes\" || it.type === \"descendantsValues\"\n );\n const descendantQueries$ = descendantQueries.map((query) =>\n from(chain.getStorageDescendants(hash, query.key)).pipe(\n map(\n (nodes): Array<StorageItem> =>\n Object.entries(nodes)\n .map(([key, node]) =>\n query.type === \"descendantsHashes\"\n ? {\n key,\n hash: Binary.toHex(node.hash),\n }\n : node.value\n ? {\n key,\n value: Binary.toHex(node.value),\n }\n : null\n )\n .filter((v) => v != null)\n )\n )\n );\n\n return merge(nodeQueries$, ...descendantQueries$).pipe(\n filter((v) => v.length > 0)\n );\n};\n\nexport const chainHead_v1_call: RpcMethod<{\n followSubscription: string;\n hash: HexString;\n function: HexString;\n callParameters: HexString;\n}> = (con, req, { chain }) => {\n const {\n followSubscription,\n hash,\n function: fnName,\n callParameters,\n } = getParams(req, [\n \"followSubscription\",\n \"hash\",\n \"function\",\n \"callParameters\",\n ]);\n\n const sub = con.context.chainHead_v1_subs[followSubscription];\n if (!sub) return con.send(respond(req, { result: \"limitReached\" }));\n\n if (!sub.pinnedBlocks.has(hash)) return con.send(blockNotPinned(req));\n\n const block = chain.getBlock(hash);\n if (!block) return con.send(blockNotReadable(req));\n\n const opId = getUuid();\n const subscription = new Subscription();\n sub.operations[opId] = subscription;\n const cleanup = () => {\n delete sub.operations[opId];\n subscription.unsubscribe();\n };\n\n con.send(\n respond(req, {\n result: \"started\",\n operationId: opId,\n })\n );\n\n subscription.add(\n from(\n runRuntimeCall({\n chain,\n hash,\n call: fnName,\n params: callParameters,\n })\n ).subscribe({\n next: (output) =>\n con.send(\n followEvent(followSubscription, {\n event: \"operationCallDone\",\n operationId: opId,\n output: output.result,\n })\n ),\n error: (e) => {\n log.error(e, \"call operation error\");\n con.send(\n followEvent(followSubscription, {\n event: \"operationError\",\n operationId: opId,\n error: e.message,\n })\n );\n cleanup();\n },\n complete: () => {\n cleanup();\n },\n })\n );\n};\n\nexport const chainHead_v1_body: RpcMethod<{\n followSubscription: string;\n hash: string;\n}> = (con, req, { chain }) => {\n const { followSubscription, hash } = getParams(req, [\n \"followSubscription\",\n \"hash\",\n ]);\n\n const sub = con.context.chainHead_v1_subs[followSubscription];\n if (!sub) return con.send(respond(req, { result: \"limitReached\" }));\n\n if (!sub.pinnedBlocks.has(hash)) return con.send(blockNotPinned(req));\n\n const block = chain.getBlock(hash);\n if (!block) return con.send(blockNotReadable(req));\n\n const opId = getUuid();\n con.send(\n respond(req, {\n result: \"started\",\n operationId: opId,\n })\n );\n\n con.send(\n followEvent(followSubscription, {\n event: \"operationBodyDone\",\n operationId: opId,\n value: block.body.map(Binary.toHex),\n })\n );\n};\n\nexport const chainHead_v1_stopOperation: RpcMethod<{\n followSubscription: string;\n operationId: string;\n}> = (con, req) => {\n const { followSubscription, operationId } = getParams(req, [\n \"followSubscription\",\n \"operationId\",\n ]);\n\n con.send(respond(req, null));\n\n const sub = con.context.chainHead_v1_subs[followSubscription];\n if (!sub?.operations[operationId]) return;\n sub.operations[operationId].unsubscribe();\n delete sub.operations[operationId];\n};\n\nexport const chainHead_v1_unpin: RpcMethod<{\n followSubscription: string;\n hashOrHashes: HexString | HexString[];\n}> = (con, req) => {\n const { followSubscription, hashOrHashes } = getParams(req, [\n \"followSubscription\",\n \"hashOrHashes\",\n ]);\n\n const sub = con.context.chainHead_v1_subs[followSubscription];\n if (!sub) return con.send(respond(req, null));\n\n const hashes = Array.isArray(hashOrHashes) ? hashOrHashes : [hashOrHashes];\n const uniqueHashes = new Set(hashes);\n if (uniqueHashes.size != hashes.length)\n return con.send(\n errorResponse(req, {\n code: -32804,\n message: \"Duplicate hashes\",\n })\n );\n if (hashes.some((hash) => !sub.pinnedBlocks.has(hash)))\n return con.send(blockNotPinned(req));\n\n hashes.forEach((hash) => sub.pinnedBlocks.delete(hash));\n\n return con.send(respond(req, null));\n};\n"],"names":["block","blocks","finalized","items"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { respond } from './rpc_utils.js';
2
+
3
+ const chainSpec_v1_chainName = async (con, req, { source }) => {
4
+ con.send(respond(req, (await source.getChainSpecData()).name));
5
+ };
6
+ const chainSpec_v1_genesisHash = async (con, req, { source }) => {
7
+ con.send(respond(req, (await source.getChainSpecData()).genesisHash));
8
+ };
9
+ const chainSpec_v1_properties = async (con, req, { source }) => {
10
+ con.send(respond(req, (await source.getChainSpecData()).properties));
11
+ };
12
+
13
+ export { chainSpec_v1_chainName, chainSpec_v1_genesisHash, chainSpec_v1_properties };
14
+ //# sourceMappingURL=chainSpec_v1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chainSpec_v1.js","sources":["../../../src/rpc/chainSpec_v1.ts"],"sourcesContent":["import { respond, type RpcMethod } from \"./rpc_utils\";\n\nexport const chainSpec_v1_chainName: RpcMethod = async (\n con,\n req,\n { source }\n) => {\n con.send(respond(req, (await source.getChainSpecData()).name));\n};\n\nexport const chainSpec_v1_genesisHash: RpcMethod = async (\n con,\n req,\n { source }\n) => {\n con.send(respond(req, (await source.getChainSpecData()).genesisHash));\n};\n\nexport const chainSpec_v1_properties: RpcMethod = async (\n con,\n req,\n { source }\n) => {\n con.send(respond(req, (await source.getChainSpecData()).properties));\n};\n"],"names":[],"mappings":";;AAEO,MAAM,yBAAoC,OAC/C,GAAA,EACA,GAAA,EACA,EAAE,QAAO,KACN;AACH,EAAA,GAAA,CAAI,IAAA,CAAK,QAAQ,GAAA,EAAA,CAAM,MAAM,OAAO,gBAAA,EAAiB,EAAG,IAAI,CAAC,CAAA;AAC/D;AAEO,MAAM,2BAAsC,OACjD,GAAA,EACA,GAAA,EACA,EAAE,QAAO,KACN;AACH,EAAA,GAAA,CAAI,IAAA,CAAK,QAAQ,GAAA,EAAA,CAAM,MAAM,OAAO,gBAAA,EAAiB,EAAG,WAAW,CAAC,CAAA;AACtE;AAEO,MAAM,0BAAqC,OAChD,GAAA,EACA,GAAA,EACA,EAAE,QAAO,KACN;AACH,EAAA,GAAA,CAAI,IAAA,CAAK,QAAQ,GAAA,EAAA,CAAM,MAAM,OAAO,gBAAA,EAAiB,EAAG,UAAU,CAAC,CAAA;AACrE;;;;"}
@@ -0,0 +1,32 @@
1
+ import { Binary } from 'polkadot-api';
2
+ import { firstValueFrom } from 'rxjs';
3
+ import { getParams, respond } from './rpc_utils.js';
4
+
5
+ const dev_newBlock = async (con, req, { newBlock }) => {
6
+ const { params } = getParams(req, ["params"]);
7
+ const hash = await newBlock({
8
+ parent: params?.parent,
9
+ unsafeBlockHeight: params?.unsafeBlockHeight
10
+ });
11
+ con.send(respond(req, hash));
12
+ };
13
+ const dev_setStorage = async (con, req, { chain }) => {
14
+ const { storageValues, blockHash } = getParams(req, [
15
+ "storageValues",
16
+ "blockHash"
17
+ ]);
18
+ let targetHash = blockHash ?? await firstValueFrom(chain.best$);
19
+ chain.setStorage(
20
+ targetHash,
21
+ Object.fromEntries(
22
+ storageValues.map(([key, value]) => [
23
+ key,
24
+ value ? Binary.fromHex(value) : null
25
+ ])
26
+ )
27
+ );
28
+ con.send(respond(req, targetHash));
29
+ };
30
+
31
+ export { dev_newBlock, dev_setStorage };
32
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.js","sources":["../../../src/rpc/dev.ts"],"sourcesContent":["import { Binary, type HexString } from \"polkadot-api\";\nimport { firstValueFrom } from \"rxjs\";\nimport { getParams, respond, type RpcMethod } from \"./rpc_utils\";\n\nexport const dev_newBlock: RpcMethod<{\n params?: {\n parent?: string;\n unsafeBlockHeight?: number;\n };\n}> = async (con, req, { newBlock }) => {\n const { params } = getParams(req, [\"params\"]);\n const hash = await newBlock({\n parent: params?.parent,\n unsafeBlockHeight: params?.unsafeBlockHeight,\n });\n\n con.send(respond(req, hash));\n};\n\nexport const dev_setStorage: RpcMethod<{\n storageValues: Array<[HexString, HexString | null]>;\n blockHash?: HexString;\n}> = async (con, req, { chain }) => {\n const { storageValues, blockHash } = getParams(req, [\n \"storageValues\",\n \"blockHash\",\n ]);\n\n let targetHash = blockHash ?? (await firstValueFrom(chain.best$));\n\n chain.setStorage(\n targetHash,\n Object.fromEntries(\n storageValues.map(([key, value]) => [\n key,\n value ? Binary.fromHex(value) : null,\n ])\n )\n );\n\n con.send(respond(req, targetHash));\n};\n"],"names":[],"mappings":";;;;AAIO,MAAM,eAKR,OAAO,GAAA,EAAK,GAAA,EAAK,EAAE,UAAS,KAAM;AACrC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,UAAU,GAAA,EAAK,CAAC,QAAQ,CAAC,CAAA;AAC5C,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS;AAAA,IAC1B,QAAQ,MAAA,EAAQ,MAAA;AAAA,IAChB,mBAAmB,MAAA,EAAQ;AAAA,GAC5B,CAAA;AAED,EAAA,GAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,IAAI,CAAC,CAAA;AAC7B;AAEO,MAAM,iBAGR,OAAO,GAAA,EAAK,GAAA,EAAK,EAAE,OAAM,KAAM;AAClC,EAAA,MAAM,EAAE,aAAA,EAAe,SAAA,EAAU,GAAI,UAAU,GAAA,EAAK;AAAA,IAClD,eAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,IAAI,UAAA,GAAa,SAAA,IAAc,MAAM,cAAA,CAAe,MAAM,KAAK,CAAA;AAE/D,EAAA,KAAA,CAAM,UAAA;AAAA,IACJ,UAAA;AAAA,IACA,MAAA,CAAO,WAAA;AAAA,MACL,cAAc,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AAAA,QAClC,GAAA;AAAA,QACA,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,GAAI;AAAA,OACjC;AAAA;AACH,GACF;AAEA,EAAA,GAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,UAAU,CAAC,CAAA;AACnC;;;;"}
@@ -0,0 +1,99 @@
1
+ import { Binary, createClient } from 'polkadot-api';
2
+ import { createWsClient } from 'polkadot-api/ws';
3
+ import { consumeDmp, attachSibling, attachRelay } from '../xcm.js';
4
+ import { getParams, respond, errorResponse } from './rpc_utils.js';
5
+ import { logger } from '../logger.js';
6
+
7
+ const log = logger.child({ module: "forklift_xcm" });
8
+ const forklift_xcm_attach_relay = async (con, req, { chain, xcm, provider }) => {
9
+ try {
10
+ const { url } = getParams(req, ["url"]);
11
+ const relayClient = createWsClient(url);
12
+ const parachainClient = createClient(provider);
13
+ await Promise.race([
14
+ await attachRelay(relayClient, parachainClient, chain, xcm),
15
+ new Promise(
16
+ (_, rej) => setTimeout(() => rej(new Error("Timed out")), 1e4)
17
+ )
18
+ ]);
19
+ con.send(respond(req, null));
20
+ } catch (ex) {
21
+ log.error(ex, "attach_relay failed");
22
+ con.send(
23
+ errorResponse(req, {
24
+ code: -1,
25
+ message: ex.message
26
+ })
27
+ );
28
+ }
29
+ };
30
+ const forklift_xcm_attach_sibling = async (con, req, { chain, xcm, provider }) => {
31
+ try {
32
+ const { url } = getParams(req, ["url"]);
33
+ const siblingClient = createWsClient(url);
34
+ const selfClient = createClient(provider);
35
+ await Promise.race([
36
+ attachSibling(siblingClient, selfClient, chain, xcm),
37
+ new Promise(
38
+ (_, rej) => setTimeout(() => rej(new Error("Timed out")), 1e4)
39
+ )
40
+ ]);
41
+ con.send(respond(req, null));
42
+ } catch (ex) {
43
+ log.error(ex, "attach_sibling failed");
44
+ con.send(
45
+ errorResponse(req, {
46
+ code: -1,
47
+ message: ex.message
48
+ })
49
+ );
50
+ }
51
+ };
52
+ const forklift_xcm_consume_dmp = async (con, req, { chain }) => {
53
+ const { hash, paraId } = getParams(req, ["hash", "paraId"]);
54
+ try {
55
+ await consumeDmp(chain, hash, paraId);
56
+ con.send(respond(req, null));
57
+ } catch (ex) {
58
+ log.error(ex, "consume_dmp failed");
59
+ con.send(
60
+ errorResponse(req, {
61
+ code: -1,
62
+ message: ex.message
63
+ })
64
+ );
65
+ }
66
+ };
67
+ const forklift_xcm_push_hrmp = async (con, req, { xcm }) => {
68
+ const { senderId, messages } = getParams(req, ["senderId", "messages"]);
69
+ try {
70
+ xcm.pushHrmp(senderId, messages.map(Binary.fromHex));
71
+ con.send(respond(req, null));
72
+ } catch (ex) {
73
+ log.error(ex, "push_hrmp failed");
74
+ con.send(errorResponse(req, { code: -1, message: ex.message }));
75
+ }
76
+ };
77
+ const forklift_xcm_open_hrmp_channel = async (con, req, { chain }) => {
78
+ const { recipientId } = getParams(req, ["recipientId"]);
79
+ chain.openHrmpChannel(recipientId);
80
+ con.send(respond(req, null));
81
+ };
82
+ const forklift_xcm_push_ump = async (con, req, { xcm }) => {
83
+ const { paraId, messages } = getParams(req, ["paraId", "messages"]);
84
+ try {
85
+ xcm.pushUmp(paraId, messages.map(Binary.fromHex));
86
+ con.send(respond(req, null));
87
+ } catch (ex) {
88
+ log.error(ex, "push_ump failed");
89
+ con.send(
90
+ errorResponse(req, {
91
+ code: -1,
92
+ message: ex.message
93
+ })
94
+ );
95
+ }
96
+ };
97
+
98
+ export { forklift_xcm_attach_relay, forklift_xcm_attach_sibling, forklift_xcm_consume_dmp, forklift_xcm_open_hrmp_channel, forklift_xcm_push_hrmp, forklift_xcm_push_ump };
99
+ //# sourceMappingURL=forklift_xcm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forklift_xcm.js","sources":["../../../src/rpc/forklift_xcm.ts"],"sourcesContent":["import { Binary, createClient, type HexString } from \"polkadot-api\";\nimport { createWsClient } from \"polkadot-api/ws\";\nimport { attachRelay, attachSibling, consumeDmp } from \"../xcm\";\nimport { errorResponse, getParams, respond, type RpcMethod } from \"./rpc_utils\";\nimport { logger } from \"../logger\";\n\nconst log = logger.child({ module: \"forklift_xcm\" });\n\n/*** Para -> Relay ***/\n\n/**\n * Attaches the current forklift as a parachain to a forklift relay chain.\n */\nexport const forklift_xcm_attach_relay: RpcMethod<{ url: string }> = async (\n con,\n req,\n { chain, xcm, provider }\n) => {\n try {\n const { url } = getParams(req, [\"url\"]);\n\n const relayClient = createWsClient(url);\n const parachainClient = createClient(provider);\n await Promise.race([\n await attachRelay(relayClient, parachainClient, chain, xcm),\n new Promise((_, rej) =>\n setTimeout(() => rej(new Error(\"Timed out\")), 10_000)\n ),\n ]);\n\n con.send(respond(req, null));\n } catch (ex: any) {\n log.error(ex, \"attach_relay failed\");\n con.send(\n errorResponse(req, {\n code: -1,\n message: ex.message,\n })\n );\n }\n};\n\n/**\n * Attaches the current forklift as a sibling parachain to a another parachain (for HRMP).\n */\nexport const forklift_xcm_attach_sibling: RpcMethod<{ url: string }> = async (\n con,\n req,\n { chain, xcm, provider }\n) => {\n try {\n const { url } = getParams(req, [\"url\"]);\n\n const siblingClient = createWsClient(url);\n const selfClient = createClient(provider);\n await Promise.race([\n attachSibling(siblingClient, selfClient, chain, xcm),\n new Promise((_, rej) =>\n setTimeout(() => rej(new Error(\"Timed out\")), 10_000)\n ),\n ]);\n\n con.send(respond(req, null));\n } catch (ex: any) {\n log.error(ex, \"attach_sibling failed\");\n con.send(\n errorResponse(req, {\n code: -1,\n message: ex.message,\n })\n );\n }\n};\n\n/**\n * Consumes the DMP XCM messages for that parachain at a specific block\n *\n * This is needed because it can't be done simply with dev_setStorage, as new\n * blocks would not get the DMP entry reset.\n */\nexport const forklift_xcm_consume_dmp: RpcMethod<{\n hash: HexString;\n paraId: number;\n}> = async (con, req, { chain }) => {\n const { hash, paraId } = getParams(req, [\"hash\", \"paraId\"]);\n\n try {\n await consumeDmp(chain, hash, paraId);\n con.send(respond(req, null));\n } catch (ex: any) {\n log.error(ex, \"consume_dmp failed\");\n\n con.send(\n errorResponse(req, {\n code: -1,\n message: ex.message,\n })\n );\n }\n};\n\n/**\n * Pushes HRMP XCM messages into the parachain's ingress queue from a sibling.\n */\nexport const forklift_xcm_push_hrmp: RpcMethod<{\n senderId: number;\n messages: HexString[];\n}> = async (con, req, { xcm }) => {\n const { senderId, messages } = getParams(req, [\"senderId\", \"messages\"]);\n\n try {\n xcm.pushHrmp(senderId, messages.map(Binary.fromHex));\n con.send(respond(req, null));\n } catch (ex: any) {\n log.error(ex, \"push_hrmp failed\");\n con.send(errorResponse(req, { code: -1, message: ex.message }));\n }\n};\n\n/**\n * Registers an open outbound HRMP channel from this chain to a recipient parachain.\n * Subsequent blocks will include this channel in the relay chain proof so the runtime\n * allows sending XCM messages to the recipient.\n */\nexport const forklift_xcm_open_hrmp_channel: RpcMethod<{\n recipientId: number;\n}> = async (con, req, { chain }) => {\n const { recipientId } = getParams(req, [\"recipientId\"]);\n chain.openHrmpChannel(recipientId);\n con.send(respond(req, null));\n};\n\n/**\n * Pushes UMP XCM messages into the relay dispatch queue at a specific block.\n */\nexport const forklift_xcm_push_ump: RpcMethod<{\n paraId: number;\n messages: HexString[];\n}> = async (con, req, { xcm }) => {\n const { paraId, messages } = getParams(req, [\"paraId\", \"messages\"]);\n\n try {\n xcm.pushUmp(paraId, messages.map(Binary.fromHex));\n con.send(respond(req, null));\n } catch (ex: any) {\n log.error(ex, \"push_ump failed\");\n\n con.send(\n errorResponse(req, {\n code: -1,\n message: ex.message,\n })\n );\n }\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import 'rxjs';
2
+
3
+ const getParams = (req, params) => Array.isArray(req.params) ? Object.fromEntries(
4
+ params.map((key, i) => [key, req.params[i]])
5
+ ) : req.params;
6
+ let uuid = 0;
7
+ const getUuid = () => `${uuid++}`;
8
+ const respond = (req, result) => ({
9
+ jsonrpc: "2.0",
10
+ id: req.id,
11
+ result
12
+ });
13
+ const errorResponse = (req, error) => ({
14
+ jsonrpc: "2.0",
15
+ id: req.id,
16
+ error
17
+ });
18
+
19
+ export { errorResponse, getParams, getUuid, respond };
20
+ //# sourceMappingURL=rpc_utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc_utils.js","sources":["../../../src/rpc/rpc_utils.ts"],"sourcesContent":["import type {\n JsonRpcError,\n JsonRpcMessage,\n JsonRpcProvider,\n JsonRpcRequest,\n JsonRpcResponse,\n} from \"@polkadot-api/substrate-client\";\nimport { Subscription, type Observable } from \"rxjs\";\nimport type { DmpMessage } from \"../block-builder/create-block\";\nimport type { Chain } from \"../chain\";\nimport type { Forklift } from \"../forklift\";\nimport type { Source } from \"../source\";\nimport type { TxPool } from \"../txPool\";\n\nexport interface Connection {\n disconnect$: Observable<void>;\n send: (msg: JsonRpcMessage) => void;\n context: {\n chainHead_v1_subs: Record<\n string,\n {\n pinnedBlocks: Set<string>;\n operations: Record<string, Subscription>;\n subscription: Subscription;\n }\n >;\n archive_v1_storage_subs: Record<string, Subscription>;\n };\n}\n\nexport type ServerContext = {\n source: Source;\n chain: Chain;\n provider: JsonRpcProvider;\n txPool: TxPool;\n newBlock: Forklift[\"newBlock\"];\n xcm: {\n pushDmp: (messages: Array<DmpMessage>) => void;\n pushUmp: (paraId: number, messages: Array<Uint8Array>) => void;\n pushHrmp: (paraId: number, messages: Array<Uint8Array>) => void;\n };\n};\n\nexport type RpcMethod<T = any> = (\n con: Connection,\n req: JsonRpcRequest<T>,\n ctx: ServerContext\n) => void;\n\nexport const getParams = <T>(req: JsonRpcRequest<T>, params: string[]): T =>\n Array.isArray(req.params)\n ? (Object.fromEntries(\n params.map((key, i) => [key, (req.params as any)[i]])\n ) as T)\n : req.params!;\n\nlet uuid = 0;\nexport const getUuid = () => `${uuid++}`;\n\nexport const respond = (req: JsonRpcRequest, result: any): JsonRpcResponse => ({\n jsonrpc: \"2.0\",\n id: req.id!,\n result,\n});\n\nexport const errorResponse = (\n req: JsonRpcRequest,\n error: JsonRpcError\n): JsonRpcResponse => ({\n jsonrpc: \"2.0\",\n id: req.id!,\n error,\n});\n"],"names":[],"mappings":";;AAiDO,MAAM,SAAA,GAAY,CAAI,GAAA,EAAwB,MAAA,KACnD,MAAM,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,GACnB,MAAA,CAAO,WAAA;AAAA,EACN,MAAA,CAAO,GAAA,CAAI,CAAC,GAAA,EAAK,CAAA,KAAM,CAAC,GAAA,EAAM,GAAA,CAAI,MAAA,CAAe,CAAC,CAAC,CAAC;AACtD,CAAA,GACA,GAAA,CAAI;AAEV,IAAI,IAAA,GAAO,CAAA;AACJ,MAAM,OAAA,GAAU,MAAM,CAAA,EAAG,IAAA,EAAM,CAAA;AAE/B,MAAM,OAAA,GAAU,CAAC,GAAA,EAAqB,MAAA,MAAkC;AAAA,EAC7E,OAAA,EAAS,KAAA;AAAA,EACT,IAAI,GAAA,CAAI,EAAA;AAAA,EACR;AACF,CAAA;AAEO,MAAM,aAAA,GAAgB,CAC3B,GAAA,EACA,KAAA,MACqB;AAAA,EACrB,OAAA,EAAS,KAAA;AAAA,EACT,IAAI,GAAA,CAAI,EAAA;AAAA,EACR;AACF,CAAA;;;;"}
@@ -0,0 +1,13 @@
1
+ import { respond, getParams, getUuid } from './rpc_utils.js';
2
+ import { Binary } from 'polkadot-api';
3
+
4
+ const transaction_v1_broadcast = (con, req, { txPool }) => {
5
+ const { transaction } = getParams(req, ["transaction"]);
6
+ txPool.addTx(Binary.fromHex(transaction));
7
+ const opId = getUuid();
8
+ return con.send(respond(req, opId));
9
+ };
10
+ const transaction_v1_stop = (con, req) => con.send(respond(req, null));
11
+
12
+ export { transaction_v1_broadcast, transaction_v1_stop };
13
+ //# sourceMappingURL=transaction_v1.js.map