@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":"transaction_v1.js","sources":["../../../src/rpc/transaction_v1.ts"],"sourcesContent":["import type { JsonRpcRequest } from \"@polkadot-api/substrate-client\";\nimport { getParams, getUuid, respond, type RpcMethod } from \"./rpc_utils\";\nimport { Binary, type HexString } from \"polkadot-api\";\n\nexport const transaction_v1_broadcast: RpcMethod = (\n con,\n req: JsonRpcRequest<{\n transaction: HexString;\n }>,\n { txPool }\n) => {\n const { transaction } = getParams(req, [\"transaction\"]);\n\n txPool.addTx(Binary.fromHex(transaction));\n\n const opId = getUuid();\n return con.send(respond(req, opId));\n};\n\nexport const transaction_v1_stop: RpcMethod = (con, req) =>\n con.send(respond(req, null));\n"],"names":[],"mappings":";;;AAIO,MAAM,2BAAsC,CACjD,GAAA,EACA,GAAA,EAGA,EAAE,QAAO,KACN;AACH,EAAA,MAAM,EAAE,WAAA,EAAY,GAAI,UAAU,GAAA,EAAK,CAAC,aAAa,CAAC,CAAA;AAEtD,EAAA,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,OAAA,CAAQ,WAAW,CAAC,CAAA;AAExC,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,OAAO,GAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,IAAI,CAAC,CAAA;AACpC;AAEO,MAAM,mBAAA,GAAiC,CAAC,GAAA,EAAK,GAAA,KAClD,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,IAAI,CAAC;;;;"}
@@ -0,0 +1,88 @@
1
+ import '@polkadot-api/substrate-client';
2
+ import { Subject } from 'rxjs';
3
+ import { logger } from './logger.js';
4
+ import { archive_v1_storageDiff, archive_v1_storage, archive_v1_stopStorageDiff, archive_v1_stopStorage, archive_v1_header, archive_v1_hashByHeight, archive_v1_genesisHash, archive_v1_finalizedHeight, archive_v1_call, archive_v1_body } from './rpc/archive_v1.js';
5
+ import { chainHead_v1_unpin, chainHead_v1_unfollow, chainHead_v1_storage, chainHead_v1_stopOperation, chainHead_v1_header, chainHead_v1_follow, chainHead_v1_call, chainHead_v1_body } from './rpc/chainHead_v1.js';
6
+ import { chainSpec_v1_properties, chainSpec_v1_genesisHash, chainSpec_v1_chainName } from './rpc/chainSpec_v1.js';
7
+ import { dev_setStorage, dev_newBlock } from './rpc/dev.js';
8
+ import { forklift_xcm_push_ump, forklift_xcm_push_hrmp, forklift_xcm_open_hrmp_channel, forklift_xcm_consume_dmp, forklift_xcm_attach_sibling, forklift_xcm_attach_relay } from './rpc/forklift_xcm.js';
9
+ import { transaction_v1_stop, transaction_v1_broadcast } from './rpc/transaction_v1.js';
10
+
11
+ const log = logger.child({ module: "serve" });
12
+ const methods = {
13
+ archive_v1_body,
14
+ archive_v1_call,
15
+ archive_v1_finalizedHeight,
16
+ archive_v1_genesisHash,
17
+ archive_v1_hashByHeight,
18
+ archive_v1_header,
19
+ archive_v1_stopStorage,
20
+ archive_v1_stopStorageDiff,
21
+ archive_v1_storage,
22
+ archive_v1_storageDiff,
23
+ chainHead_v1_body,
24
+ chainHead_v1_call,
25
+ chainHead_v1_follow,
26
+ chainHead_v1_header,
27
+ chainHead_v1_stopOperation,
28
+ chainHead_v1_storage,
29
+ chainHead_v1_unfollow,
30
+ chainHead_v1_unpin,
31
+ chainSpec_v1_chainName,
32
+ chainSpec_v1_genesisHash,
33
+ chainSpec_v1_properties,
34
+ dev_newBlock,
35
+ dev_setStorage,
36
+ forklift_xcm_attach_relay,
37
+ forklift_xcm_attach_sibling,
38
+ forklift_xcm_consume_dmp,
39
+ forklift_xcm_open_hrmp_channel,
40
+ forklift_xcm_push_hrmp,
41
+ forklift_xcm_push_ump,
42
+ transaction_v1_broadcast,
43
+ transaction_v1_stop
44
+ };
45
+ const createServer = (ctx) => {
46
+ const provider = (send) => {
47
+ const disconnect = new Subject();
48
+ const con = {
49
+ send,
50
+ disconnect$: disconnect.asObservable(),
51
+ context: {
52
+ chainHead_v1_subs: {},
53
+ archive_v1_storage_subs: {}
54
+ }
55
+ };
56
+ return {
57
+ disconnect() {
58
+ },
59
+ async send(req) {
60
+ if (req.method === "rpc_methods") {
61
+ return send({
62
+ jsonrpc: "2.0",
63
+ id: req.id,
64
+ result: { methods: Object.keys(methods) }
65
+ });
66
+ }
67
+ const method = methods[req.method];
68
+ if (method) {
69
+ method(con, req, { ...ctx, provider });
70
+ } else {
71
+ log.warn({ method: req.method }, "unknown RPC method");
72
+ send({
73
+ jsonrpc: "2.0",
74
+ id: req.id,
75
+ error: {
76
+ code: -32601,
77
+ message: "Method not found"
78
+ }
79
+ });
80
+ }
81
+ }
82
+ };
83
+ };
84
+ return provider;
85
+ };
86
+
87
+ export { createServer, methods };
88
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sources":["../../src/serve.ts"],"sourcesContent":["import { type JsonRpcProvider } from \"@polkadot-api/substrate-client\";\nimport { Subject } from \"rxjs\";\nimport { logger } from \"./logger\";\nimport {\n archive_v1_body,\n archive_v1_call,\n archive_v1_finalizedHeight,\n archive_v1_genesisHash,\n archive_v1_hashByHeight,\n archive_v1_header,\n archive_v1_stopStorage,\n archive_v1_stopStorageDiff,\n archive_v1_storage,\n archive_v1_storageDiff,\n} from \"./rpc/archive_v1\";\nimport {\n chainHead_v1_body,\n chainHead_v1_call,\n chainHead_v1_follow,\n chainHead_v1_header,\n chainHead_v1_stopOperation,\n chainHead_v1_storage,\n chainHead_v1_unfollow,\n chainHead_v1_unpin,\n} from \"./rpc/chainHead_v1\";\nimport {\n chainSpec_v1_chainName,\n chainSpec_v1_genesisHash,\n chainSpec_v1_properties,\n} from \"./rpc/chainSpec_v1\";\nimport { dev_newBlock, dev_setStorage } from \"./rpc/dev\";\nimport {\n forklift_xcm_attach_relay,\n forklift_xcm_attach_sibling,\n forklift_xcm_consume_dmp,\n forklift_xcm_open_hrmp_channel,\n forklift_xcm_push_hrmp,\n forklift_xcm_push_ump,\n} from \"./rpc/forklift_xcm\";\nimport type { Connection, RpcMethod, ServerContext } from \"./rpc/rpc_utils\";\nimport {\n transaction_v1_broadcast,\n transaction_v1_stop,\n} from \"./rpc/transaction_v1\";\n\nconst log = logger.child({ module: \"serve\" });\n\nexport const methods: Record<string, RpcMethod> = {\n archive_v1_body,\n archive_v1_call,\n archive_v1_finalizedHeight,\n archive_v1_genesisHash,\n archive_v1_hashByHeight,\n archive_v1_header,\n archive_v1_stopStorage,\n archive_v1_stopStorageDiff,\n archive_v1_storage,\n archive_v1_storageDiff,\n chainHead_v1_body,\n chainHead_v1_call,\n chainHead_v1_follow,\n chainHead_v1_header,\n chainHead_v1_stopOperation,\n chainHead_v1_storage,\n chainHead_v1_unfollow,\n chainHead_v1_unpin,\n chainSpec_v1_chainName,\n chainSpec_v1_genesisHash,\n chainSpec_v1_properties,\n dev_newBlock,\n dev_setStorage,\n forklift_xcm_attach_relay,\n forklift_xcm_attach_sibling,\n forklift_xcm_consume_dmp,\n forklift_xcm_open_hrmp_channel,\n forklift_xcm_push_hrmp,\n forklift_xcm_push_ump,\n transaction_v1_broadcast,\n transaction_v1_stop,\n};\n\nexport const createServer = (\n ctx: Omit<ServerContext, \"provider\">\n): JsonRpcProvider => {\n const provider: JsonRpcProvider = (send) => {\n const disconnect = new Subject<void>();\n const con: Connection = {\n send,\n disconnect$: disconnect.asObservable(),\n context: {\n chainHead_v1_subs: {},\n archive_v1_storage_subs: {},\n },\n };\n\n return {\n disconnect() {},\n async send(req) {\n if (req.method === \"rpc_methods\") {\n return send({\n jsonrpc: \"2.0\",\n id: req.id!,\n result: { methods: Object.keys(methods) },\n });\n }\n\n const method = methods[req.method];\n if (method) {\n method(con, req, { ...ctx, provider });\n } else {\n log.warn({ method: req.method }, \"unknown RPC method\");\n send({\n jsonrpc: \"2.0\",\n id: req.id!,\n error: {\n code: -32601,\n message: \"Method not found\",\n },\n });\n }\n },\n };\n };\n return provider;\n};\n"],"names":[],"mappings":";;;;;;;;;;AA6CA,MAAM,MAAM,MAAA,CAAO,KAAA,CAAM,EAAE,MAAA,EAAQ,SAAS,CAAA;AAErC,MAAM,OAAA,GAAqC;AAAA,EAChD,eAAA;AAAA,EACA,eAAA;AAAA,EACA,0BAAA;AAAA,EACA,sBAAA;AAAA,EACA,uBAAA;AAAA,EACA,iBAAA;AAAA,EACA,sBAAA;AAAA,EACA,0BAAA;AAAA,EACA,kBAAA;AAAA,EACA,sBAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,0BAAA;AAAA,EACA,oBAAA;AAAA,EACA,qBAAA;AAAA,EACA,kBAAA;AAAA,EACA,sBAAA;AAAA,EACA,wBAAA;AAAA,EACA,uBAAA;AAAA,EACA,YAAA;AAAA,EACA,cAAA;AAAA,EACA,yBAAA;AAAA,EACA,2BAAA;AAAA,EACA,wBAAA;AAAA,EACA,8BAAA;AAAA,EACA,sBAAA;AAAA,EACA,qBAAA;AAAA,EACA,wBAAA;AAAA,EACA;AACF;AAEO,MAAM,YAAA,GAAe,CAC1B,GAAA,KACoB;AACpB,EAAA,MAAM,QAAA,GAA4B,CAAC,IAAA,KAAS;AAC1C,IAAA,MAAM,UAAA,GAAa,IAAI,OAAA,EAAc;AACrC,IAAA,MAAM,GAAA,GAAkB;AAAA,MACtB,IAAA;AAAA,MACA,WAAA,EAAa,WAAW,YAAA,EAAa;AAAA,MACrC,OAAA,EAAS;AAAA,QACP,mBAAmB,EAAC;AAAA,QACpB,yBAAyB;AAAC;AAC5B,KACF;AAEA,IAAA,OAAO;AAAA,MACL,UAAA,GAAa;AAAA,MAAC,CAAA;AAAA,MACd,MAAM,KAAK,GAAA,EAAK;AACd,QAAA,IAAI,GAAA,CAAI,WAAW,aAAA,EAAe;AAChC,UAAA,OAAO,IAAA,CAAK;AAAA,YACV,OAAA,EAAS,KAAA;AAAA,YACT,IAAI,GAAA,CAAI,EAAA;AAAA,YACR,QAAQ,EAAE,OAAA,EAAS,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAE,WACzC,CAAA;AAAA,QACH;AAEA,QAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA;AACjC,QAAA,IAAI,MAAA,EAAQ;AACV,UAAA,MAAA,CAAO,KAAK,GAAA,EAAK,EAAE,GAAG,GAAA,EAAK,UAAU,CAAA;AAAA,QACvC,CAAA,MAAO;AACL,UAAA,GAAA,CAAI,KAAK,EAAE,MAAA,EAAQ,GAAA,CAAI,MAAA,IAAU,oBAAoB,CAAA;AACrD,UAAA,IAAA,CAAK;AAAA,YACH,OAAA,EAAS,KAAA;AAAA,YACT,IAAI,GAAA,CAAI,EAAA;AAAA,YACR,KAAA,EAAO;AAAA,cACL,IAAA,EAAM,MAAA;AAAA,cACN,OAAA,EAAS;AAAA;AACX,WACD,CAAA;AAAA,QACH;AAAA,MACF;AAAA,KACF;AAAA,EACF,CAAA;AACA,EAAA,OAAO,QAAA;AACT;;;;"}
@@ -0,0 +1,125 @@
1
+ import { blockHeader } from '@polkadot-api/substrate-bindings';
2
+ import { createClient } from '@polkadot-api/substrate-client';
3
+ import { middleware } from '@polkadot-api/ws-middleware';
4
+ import { getWsProvider, SocketEvents } from '@polkadot-api/ws-provider';
5
+ import { Binary } from 'polkadot-api';
6
+ import { logger } from './logger.js';
7
+
8
+ const createRemoteSource = (url, options = {}) => {
9
+ const log = logger.child({ module: "remote-source" });
10
+ const substrateClient = createClient(
11
+ getWsProvider(url, {
12
+ middleware,
13
+ logger: (evt) => {
14
+ switch (evt.type) {
15
+ case SocketEvents.CONNECTING:
16
+ return log.info({ url: evt.url }, evt.type);
17
+ case SocketEvents.ERROR:
18
+ return log.error({ error: evt.error }, evt.type);
19
+ case SocketEvents.IN:
20
+ case SocketEvents.OUT:
21
+ return log.trace({ msg: evt.msg }, evt.type);
22
+ default:
23
+ return log.info(evt.type);
24
+ }
25
+ }
26
+ })
27
+ );
28
+ const archive = substrateClient.archive;
29
+ const block = new Promise(async (resolve, reject) => {
30
+ try {
31
+ let blockHash;
32
+ if (options.atBlock === void 0) {
33
+ const finalizedHeight = await archive.finalizedHeight();
34
+ const hashes = await archive.hashByHeight(finalizedHeight);
35
+ const hash = hashes[0];
36
+ if (!hash) {
37
+ throw new Error(
38
+ `No block found at finalized height ${finalizedHeight}`
39
+ );
40
+ }
41
+ blockHash = hash;
42
+ } else if (typeof options.atBlock === "number") {
43
+ const hashes = await archive.hashByHeight(options.atBlock);
44
+ const hash = hashes[0];
45
+ if (!hash) {
46
+ throw new Error(`No block found at height ${options.atBlock}`);
47
+ }
48
+ blockHash = hash;
49
+ } else {
50
+ blockHash = options.atBlock;
51
+ }
52
+ log.debug({ blockHash }, "loading block");
53
+ const headerHex = await archive.header(blockHash);
54
+ const header = blockHeader.dec(Binary.fromHex(headerHex));
55
+ const body = await archive.body(blockHash);
56
+ const block2 = { blockHash, header, body: body.map(Binary.fromHex) };
57
+ log.debug(block2, "block loaded");
58
+ resolve(block2);
59
+ } catch (ex) {
60
+ log.error(ex, "error loading block");
61
+ reject(ex);
62
+ }
63
+ });
64
+ return {
65
+ block,
66
+ async getStorage(key) {
67
+ const { blockHash } = await block;
68
+ const value = await archive.storage(blockHash, "value", key, null);
69
+ return value ? Binary.fromHex(value) : null;
70
+ },
71
+ async getStorageBatch(keys) {
72
+ const { blockHash } = await block;
73
+ return new Promise((resolve, reject) => {
74
+ const results = /* @__PURE__ */ new Map();
75
+ const inputs = keys.map((key) => ({ key, type: "value" }));
76
+ const unsub = archive.storageSubscription(
77
+ blockHash,
78
+ inputs,
79
+ null,
80
+ (item) => {
81
+ results.set(
82
+ item.key,
83
+ item.value ? Binary.fromHex(item.value) : null
84
+ );
85
+ },
86
+ reject,
87
+ () => {
88
+ resolve(keys.map((key) => results.get(key) ?? null));
89
+ unsub();
90
+ }
91
+ );
92
+ });
93
+ },
94
+ async getStorageDescendants(prefix) {
95
+ const { blockHash } = await block;
96
+ const entries = await archive.storage(
97
+ blockHash,
98
+ "descendantsValues",
99
+ prefix,
100
+ null
101
+ );
102
+ const result = {};
103
+ for (const { key, value } of entries) {
104
+ result[key] = Binary.fromHex(value);
105
+ }
106
+ return result;
107
+ },
108
+ getChainSpecData() {
109
+ return substrateClient.getChainSpecData();
110
+ },
111
+ destroy() {
112
+ substrateClient.destroy();
113
+ },
114
+ archive: {
115
+ getBody: async (hash) => (await archive.body(hash)).map(Binary.fromHex),
116
+ getHeader: async (hash) => blockHeader.dec(Binary.fromHex(await archive.header(hash))),
117
+ call: (hash, fnName, parameters) => archive.call(hash, fnName, parameters),
118
+ getHashByHeight: (height) => archive.hashByHeight(height),
119
+ storageSubscription: archive.storageSubscription
120
+ }
121
+ };
122
+ };
123
+
124
+ export { createRemoteSource };
125
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sources":["../../src/source.ts"],"sourcesContent":["import { blockHeader } from \"@polkadot-api/substrate-bindings\";\nimport {\n createClient,\n type ChainSpecData,\n type SubstrateClient,\n} from \"@polkadot-api/substrate-client\";\nimport { middleware } from \"@polkadot-api/ws-middleware\";\nimport { getWsProvider, SocketEvents } from \"@polkadot-api/ws-provider\";\nimport { Binary, type BlockHeader, type HexString } from \"polkadot-api\";\nimport { logger } from \"./logger\";\n\nexport interface Source {\n block: Promise<{\n blockHash: HexString;\n header: BlockHeader;\n body: Uint8Array[];\n }>;\n\n /** Get a single storage value */\n getStorage(key: HexString): Promise<Uint8Array | null>;\n\n /** Get multiple storage values */\n getStorageBatch(keys: HexString[]): Promise<(Uint8Array | null)[]>;\n\n /** Get all storage entries under a prefix */\n getStorageDescendants(\n prefix: HexString\n ): Promise<Record<HexString, Uint8Array>>;\n\n getChainSpecData(): Promise<ChainSpecData>;\n\n /** Disconnect from the source */\n destroy(): void;\n\n archive?: {\n getBody: (hash: HexString) => Promise<Uint8Array[]>;\n getHeader: (hash: HexString) => Promise<BlockHeader>;\n call: (\n hash: HexString,\n fnName: string,\n parameters: HexString\n ) => Promise<HexString>;\n getHashByHeight: (height: number) => Promise<HexString[]>;\n\n storageSubscription: SubstrateClient[\"archive\"][\"storageSubscription\"];\n };\n}\n\nexport const createRemoteSource = (\n url: string | string[],\n options: {\n atBlock?: number | string;\n } = {}\n): Source => {\n const log = logger.child({ module: \"remote-source\" });\n\n const substrateClient = createClient(\n getWsProvider(url, {\n middleware,\n logger: (evt) => {\n switch (evt.type) {\n case SocketEvents.CONNECTING:\n return log.info({ url: evt.url }, evt.type);\n case SocketEvents.ERROR:\n return log.error({ error: evt.error }, evt.type);\n case SocketEvents.IN:\n case SocketEvents.OUT:\n return log.trace({ msg: evt.msg }, evt.type);\n default:\n return log.info(evt.type);\n }\n },\n })\n );\n const archive = substrateClient.archive;\n\n const block = new Promise<{\n blockHash: HexString;\n header: BlockHeader;\n body: Uint8Array[];\n }>(async (resolve, reject) => {\n try {\n // Resolve the block hash\n let blockHash: HexString;\n\n if (options.atBlock === undefined) {\n const finalizedHeight = await archive.finalizedHeight();\n const hashes = await archive.hashByHeight(finalizedHeight);\n const hash = hashes[0];\n if (!hash) {\n throw new Error(\n `No block found at finalized height ${finalizedHeight}`\n );\n }\n blockHash = hash;\n } else if (typeof options.atBlock === \"number\") {\n const hashes = await archive.hashByHeight(options.atBlock);\n const hash = hashes[0];\n if (!hash) {\n throw new Error(`No block found at height ${options.atBlock}`);\n }\n blockHash = hash;\n } else {\n blockHash = options.atBlock;\n }\n\n // Fetch and decode the header\n log.debug({ blockHash }, \"loading block\");\n const headerHex = await archive.header(blockHash);\n const header = blockHeader.dec(Binary.fromHex(headerHex));\n\n const body = await archive.body(blockHash);\n\n const block = { blockHash, header, body: body.map(Binary.fromHex) };\n log.debug(block, \"block loaded\");\n\n resolve(block);\n } catch (ex) {\n log.error(ex, \"error loading block\");\n reject(ex);\n }\n });\n\n return {\n block,\n\n async getStorage(key: HexString): Promise<Uint8Array | null> {\n const { blockHash } = await block;\n // console.log(\"--\" + key);\n const value = await archive.storage(blockHash, \"value\", key, null);\n return value ? Binary.fromHex(value) : null;\n },\n\n async getStorageBatch(keys: HexString[]): Promise<(Uint8Array | null)[]> {\n const { blockHash } = await block;\n return new Promise((resolve, reject) => {\n const results = new Map<string, Uint8Array | null>();\n const inputs = keys.map((key) => ({ key, type: \"value\" as const }));\n\n const unsub = archive.storageSubscription(\n blockHash,\n inputs,\n null,\n (item) => {\n results.set(\n item.key,\n item.value ? Binary.fromHex(item.value) : null\n );\n },\n reject,\n () => {\n resolve(keys.map((key) => results.get(key) ?? null));\n unsub();\n }\n );\n });\n },\n\n async getStorageDescendants(\n prefix: HexString\n ): Promise<Record<HexString, Uint8Array>> {\n const { blockHash } = await block;\n const entries = await archive.storage(\n blockHash,\n \"descendantsValues\",\n prefix,\n null\n );\n const result: Record<HexString, Uint8Array> = {};\n for (const { key, value } of entries) {\n result[key] = Binary.fromHex(value);\n }\n return result;\n },\n\n getChainSpecData() {\n return substrateClient.getChainSpecData();\n },\n\n destroy(): void {\n substrateClient.destroy();\n },\n\n archive: {\n getBody: async (hash) => (await archive.body(hash)).map(Binary.fromHex),\n getHeader: async (hash) =>\n blockHeader.dec(Binary.fromHex(await archive.header(hash))),\n call: (hash, fnName, parameters) =>\n archive.call(hash, fnName, parameters),\n getHashByHeight: (height) => archive.hashByHeight(height),\n storageSubscription: archive.storageSubscription,\n },\n };\n};\n"],"names":["block"],"mappings":"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"}
@@ -0,0 +1,223 @@
1
+ import { Blake2128, Binary } from '@polkadot-api/substrate-bindings';
2
+ import { logger } from './logger.js';
3
+
4
+ const log = logger.child({ module: "storage" });
5
+ const TRIE_SIZE = 16;
6
+ const emptyHashBin = Blake2128(new Uint8Array());
7
+ const emptyHash = Array.from(emptyHashBin);
8
+ const getHash = (children, value) => {
9
+ if (!value) {
10
+ const realChildren = children.filter((v) => !!v);
11
+ if (realChildren.length === 0) return emptyHashBin;
12
+ if (realChildren.length === 1) return realChildren[0].hash;
13
+ }
14
+ const childHashes = new Array(TRIE_SIZE).fill(0).flatMap(
15
+ (_, i) => children[i] ? Array.from(children[i].hash) : emptyHash
16
+ );
17
+ return Blake2128(
18
+ new Uint8Array([
19
+ ...childHashes,
20
+ value ? 1 : 0,
21
+ ...value ?? new Uint8Array()
22
+ ])
23
+ );
24
+ };
25
+ const getNibble = (key, offset) => {
26
+ const byte = key[Math.floor(offset / 2)];
27
+ if (byte == null) return null;
28
+ return offset % 2 === 0 ? byte >> 4 : byte & 15;
29
+ };
30
+ const setNibble = (key, offset, value) => offset % 2 === 0 ? new Uint8Array([...key, value << 4]) : new Uint8Array(key.map((v, j) => j === key.length - 1 ? v | value : v));
31
+ const createRoot = () => {
32
+ const children = new Array(TRIE_SIZE);
33
+ return {
34
+ hash: getHash(children),
35
+ children
36
+ };
37
+ };
38
+ const insertValue = (root, key, nibbles, value, offset = 0) => {
39
+ if (nibbles === offset)
40
+ return {
41
+ ...root,
42
+ hash: getHash(root.children, value),
43
+ value
44
+ };
45
+ const nibble = getNibble(key, offset);
46
+ if (nibble == null) throw new Error("Key overflow");
47
+ const child = root.children[nibble];
48
+ if (!child) {
49
+ const children2 = [...root.children];
50
+ children2[nibble] = createNodeValue(key, nibbles, value, offset + 1);
51
+ return {
52
+ hash: getHash(children2, root.value),
53
+ children: children2,
54
+ value: root.value,
55
+ exhaustive: root.exhaustive
56
+ };
57
+ }
58
+ const children = [...root.children];
59
+ children[nibble] = insertValue(child, key, nibbles, value, offset + 1);
60
+ return {
61
+ hash: getHash(children, root.value),
62
+ children,
63
+ value: root.value,
64
+ exhaustive: root.exhaustive
65
+ };
66
+ };
67
+ const createNodeValue = (key, nibbles, value, offset) => {
68
+ if (nibbles === offset)
69
+ return {
70
+ hash: getHash([], value),
71
+ children: new Array(TRIE_SIZE),
72
+ value
73
+ };
74
+ const nibble = getNibble(key, offset);
75
+ if (nibble == null) throw new Error("Key overflow");
76
+ const child = createNodeValue(key, nibbles, value, offset + 1);
77
+ const children = new Array(TRIE_SIZE);
78
+ children[nibble] = child;
79
+ return {
80
+ hash: getHash(children),
81
+ children
82
+ };
83
+ };
84
+ const deleteValue = (root, key, nibbles, offset = 0) => {
85
+ if (offset === nibbles)
86
+ return root.value ? {
87
+ ...root,
88
+ // Soft delete to have it marked as removed, otherwise we'd go back to the source
89
+ value: null,
90
+ hash: getHash(root.children, null)
91
+ } : root;
92
+ const nibble = getNibble(key, offset);
93
+ if (nibble == null) throw new Error("Key overflow");
94
+ const child = root.children[nibble];
95
+ if (!child) return root;
96
+ const newChild = deleteValue(child, key, offset + 1);
97
+ if (newChild === child) return root;
98
+ const children = [...root.children];
99
+ children[nibble] = newChild;
100
+ return {
101
+ hash: getHash(children, root.value),
102
+ children,
103
+ value: root.value,
104
+ exhaustive: root.exhaustive
105
+ };
106
+ };
107
+ const getNode = (root, key, nibbles, offset = 0) => {
108
+ if (offset === 0 && Binary.toHex(key) === "0x26aa394eea5630e07c48ae0c9558cef734abf5cb34d6244378cddbf18e849d96") {
109
+ log.debug("Block.Weight requested");
110
+ }
111
+ if (offset === nibbles) return root;
112
+ const nibble = getNibble(key, offset);
113
+ if (nibble == null) throw new Error("Key overflow");
114
+ const child = root.children[nibble];
115
+ if (!child) return null;
116
+ return getNode(child, key, nibbles, offset + 1);
117
+ };
118
+ const getDiff = (base, fallback, other, prefix = new Uint8Array(), nibbles = 0) => {
119
+ const insert = {
120
+ children: new Array(TRIE_SIZE)
121
+ };
122
+ const prev = {
123
+ children: new Array(TRIE_SIZE)
124
+ };
125
+ let deleteNodes = new Array();
126
+ let deleteValues = new Array();
127
+ for (let i = 0; i < TRIE_SIZE; i++) {
128
+ const fallbackNode = fallback?.children[i];
129
+ const baseNode = base.children[i];
130
+ const completeBase = baseNode ?? fallbackNode;
131
+ const otherNode = other.children[i];
132
+ const childPrefix = setNibble(prefix, nibbles, i);
133
+ if (otherNode) {
134
+ if (completeBase) {
135
+ if (arrU8Eq(otherNode.hash, completeBase.hash)) continue;
136
+ const childDiff = getDiff(
137
+ completeBase,
138
+ baseNode ? fallbackNode ?? null : null,
139
+ otherNode,
140
+ childPrefix,
141
+ nibbles + 1
142
+ );
143
+ insert.children[i] = childDiff.insert;
144
+ prev.children[i] = childDiff.prev;
145
+ deleteNodes = [...deleteNodes, ...childDiff.deleteNodes];
146
+ deleteValues = [...deleteValues, ...childDiff.deleteValues];
147
+ } else {
148
+ insert.children[i] = otherNode;
149
+ }
150
+ } else {
151
+ if (completeBase) {
152
+ deleteNodes.push({ key: prefix, nibbles: nibbles + 1 });
153
+ prev.children[i] = completeBase;
154
+ }
155
+ }
156
+ }
157
+ const completeValue = base.value ?? fallback?.value;
158
+ if (other.value) {
159
+ if (!completeValue || completeValue && !arrU8Eq(completeValue, other.value)) {
160
+ insert.value = other.value;
161
+ prev.value = completeValue;
162
+ }
163
+ } else if (completeValue) {
164
+ deleteValues.push({
165
+ key: prefix,
166
+ nibbles
167
+ });
168
+ prev.value = completeValue;
169
+ }
170
+ return {
171
+ insert: {
172
+ ...insert,
173
+ hash: getHash(insert.children, insert.value)
174
+ },
175
+ prev: {
176
+ ...prev,
177
+ hash: getHash(prev.children, prev.value)
178
+ },
179
+ deleteNodes,
180
+ deleteValues
181
+ };
182
+ };
183
+ const getDescendantNodes = (node, prefix, nibbles) => {
184
+ let result = new Array();
185
+ if (node.value) {
186
+ result.push({ key: prefix, nibbles, node });
187
+ }
188
+ node.children.forEach((child, i) => {
189
+ if (!child) return;
190
+ const childPrefix = setNibble(prefix, nibbles, i);
191
+ result = [
192
+ ...result,
193
+ ...getDescendantNodes(child, childPrefix, nibbles + 1)
194
+ ];
195
+ });
196
+ return result;
197
+ };
198
+ const getSoftDeletedDescendantKeys = (node, prefix, nibbles) => {
199
+ let result = new Array();
200
+ if (node.value === null) {
201
+ result.push(prefix);
202
+ }
203
+ node.children.forEach((child, i) => {
204
+ if (!child) return;
205
+ const childPrefix = setNibble(prefix, nibbles, i);
206
+ result = [
207
+ ...result,
208
+ ...getSoftDeletedDescendantKeys(child, childPrefix, nibbles + 1)
209
+ ];
210
+ });
211
+ return result;
212
+ };
213
+ const forEachDescendant = (root, cb) => {
214
+ root.children.forEach((child) => {
215
+ if (!child) return;
216
+ cb(child);
217
+ forEachDescendant(child, cb);
218
+ });
219
+ };
220
+ const arrU8Eq = (a, b) => a.length === b.length && a.every((v, i) => b[i] === v);
221
+
222
+ export { createRoot, deleteValue, forEachDescendant, getDescendantNodes, getDiff, getNode, getSoftDeletedDescendantKeys, insertValue };
223
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sources":["../../src/storage.ts"],"sourcesContent":["import { Binary, Blake2128 } from \"@polkadot-api/substrate-bindings\";\nimport { logger } from \"./logger\";\n\nconst log = logger.child({ module: \"storage\" });\n\nconst TRIE_SIZE = 16;\nexport interface StorageNode {\n hash: Uint8Array;\n children: Array<StorageNode>; // nibble -> node\n value?: Uint8Array | null;\n exhaustive?: boolean;\n}\n\nconst emptyHashBin = Blake2128(new Uint8Array());\nconst emptyHash = Array.from(emptyHashBin);\nconst getHash = (children: Array<StorageNode>, value?: Uint8Array | null) => {\n if (!value) {\n const realChildren = children.filter((v) => !!v);\n if (realChildren.length === 0) return emptyHashBin;\n if (realChildren.length === 1) return realChildren[0]!.hash;\n }\n const childHashes = new Array(TRIE_SIZE)\n .fill(0)\n .flatMap((_, i) =>\n children[i] ? Array.from(children[i].hash) : emptyHash\n );\n\n return Blake2128(\n new Uint8Array([\n ...childHashes,\n value ? 1 : 0,\n ...(value ?? new Uint8Array()),\n ])\n );\n};\nconst getNibble = (key: Uint8Array, offset: number) => {\n const byte = key[Math.floor(offset / 2)];\n if (byte == null) return null;\n return offset % 2 === 0 ? byte >> 4 : byte & 0x0f;\n};\nconst setNibble = (key: Uint8Array, offset: number, value: number) =>\n offset % 2 === 0\n ? new Uint8Array([...key, value << 4])\n : new Uint8Array(key.map((v, j) => (j === key.length - 1 ? v | value : v)));\n\nexport const createRoot = (): StorageNode => {\n const children = new Array(TRIE_SIZE);\n return {\n hash: getHash(children),\n children,\n };\n};\n\nexport const insertValue = (\n root: StorageNode,\n key: Uint8Array,\n nibbles: number,\n value: Uint8Array | null,\n offset = 0\n): StorageNode => {\n // if (offset === 0) console.log(\"insert\", Binary.toHex(key), nibbles, value);\n\n if (nibbles === offset)\n return {\n ...root,\n hash: getHash(root.children, value),\n value,\n };\n\n const nibble = getNibble(key, offset);\n if (nibble == null) throw new Error(\"Key overflow\");\n\n const child = root.children[nibble];\n if (!child) {\n const children = [...root.children];\n children[nibble] = createNodeValue(key, nibbles, value, offset + 1);\n return {\n hash: getHash(children, root.value),\n children,\n value: root.value,\n exhaustive: root.exhaustive,\n };\n }\n\n const children = [...root.children];\n children[nibble] = insertValue(child, key, nibbles, value, offset + 1);\n return {\n hash: getHash(children, root.value),\n children,\n value: root.value,\n exhaustive: root.exhaustive,\n };\n};\n\nconst createNodeValue = (\n key: Uint8Array,\n nibbles: number,\n value: Uint8Array | null,\n offset: number\n): StorageNode => {\n if (nibbles === offset)\n return {\n hash: getHash([], value),\n children: new Array(TRIE_SIZE),\n value,\n };\n const nibble = getNibble(key, offset);\n if (nibble == null) throw new Error(\"Key overflow\");\n\n const child = createNodeValue(key, nibbles, value, offset + 1);\n const children = new Array(TRIE_SIZE);\n children[nibble] = child;\n return {\n hash: getHash(children),\n children,\n };\n};\n\nexport const deleteValue = (\n root: StorageNode,\n key: Uint8Array,\n nibbles: number,\n offset = 0\n): StorageNode => {\n // if (offset === 0) console.log(\"delete\", Binary.toHex(key), nibbles);\n\n if (offset === nibbles)\n return root.value\n ? {\n ...root,\n // Soft delete to have it marked as removed, otherwise we'd go back to the source\n value: null,\n hash: getHash(root.children, null),\n }\n : root;\n const nibble = getNibble(key, offset);\n if (nibble == null) throw new Error(\"Key overflow\");\n\n const child = root.children[nibble];\n if (!child) return root;\n\n const newChild = deleteValue(child, key, offset + 1);\n if (newChild === child) return root;\n\n const children = [...root.children];\n children[nibble] = newChild;\n return {\n hash: getHash(children, root.value),\n children,\n value: root.value,\n exhaustive: root.exhaustive,\n };\n};\n\nexport const getNode = (\n root: StorageNode,\n key: Uint8Array,\n nibbles: number,\n offset = 0\n): StorageNode | null => {\n // if (offset === 0) console.log(\"getNode\", Binary.toHex(key), nibbles);\n if (\n offset === 0 &&\n Binary.toHex(key) ===\n \"0x26aa394eea5630e07c48ae0c9558cef734abf5cb34d6244378cddbf18e849d96\"\n ) {\n log.debug(\"Block.Weight requested\");\n }\n\n if (offset === nibbles) return root;\n const nibble = getNibble(key, offset);\n if (nibble == null) throw new Error(\"Key overflow\");\n\n const child = root.children[nibble];\n if (!child) return null;\n\n return getNode(child, key, nibbles, offset + 1);\n};\n\nexport const getDiff = (\n base: StorageNode,\n // mechanism to overcome we don't have all storage state and it's loaded lazily.\n // if base has `undefined` values, it will fallback to this node (the one\n // that mutates as original data is loaded)\n // `null` means that `base` is already the mutated one.\n fallback: StorageNode | null,\n other: StorageNode,\n prefix = new Uint8Array(),\n nibbles = 0\n): {\n insert: StorageNode;\n prev: StorageNode;\n deleteNodes: Array<{ key: Uint8Array; nibbles: number }>;\n deleteValues: Array<{ key: Uint8Array; nibbles: number }>;\n} => {\n const insert: Omit<StorageNode, \"hash\"> = {\n children: new Array<StorageNode>(TRIE_SIZE),\n };\n const prev: Omit<StorageNode, \"hash\"> = {\n children: new Array<StorageNode>(TRIE_SIZE),\n };\n let deleteNodes = new Array<{ key: Uint8Array; nibbles: number }>();\n let deleteValues = new Array<{ key: Uint8Array; nibbles: number }>();\n\n for (let i = 0; i < TRIE_SIZE; i++) {\n const fallbackNode = fallback?.children[i];\n const baseNode = base.children[i];\n const completeBase = baseNode ?? fallbackNode;\n const otherNode = other.children[i];\n const childPrefix = setNibble(prefix, nibbles, i);\n\n if (otherNode) {\n if (completeBase) {\n if (arrU8Eq(otherNode.hash, completeBase.hash)) continue;\n\n const childDiff = getDiff(\n completeBase,\n baseNode ? fallbackNode ?? null : null,\n otherNode,\n childPrefix,\n nibbles + 1\n );\n insert.children[i] = childDiff.insert;\n prev.children[i] = childDiff.prev;\n deleteNodes = [...deleteNodes, ...childDiff.deleteNodes];\n deleteValues = [...deleteValues, ...childDiff.deleteValues];\n } else {\n insert.children[i] = otherNode;\n }\n } else {\n if (completeBase) {\n deleteNodes.push({ key: prefix, nibbles: nibbles + 1 });\n prev.children[i] = completeBase;\n }\n }\n }\n\n const completeValue = base.value ?? fallback?.value;\n if (other.value) {\n if (\n !completeValue ||\n (completeValue && !arrU8Eq(completeValue, other.value))\n ) {\n insert.value = other.value;\n prev.value = completeValue;\n }\n } else if (completeValue) {\n deleteValues.push({\n key: prefix,\n nibbles,\n });\n prev.value = completeValue;\n }\n\n return {\n insert: {\n ...insert,\n hash: getHash(insert.children, insert.value),\n },\n prev: {\n ...prev,\n hash: getHash(prev.children, prev.value),\n },\n deleteNodes,\n deleteValues,\n };\n};\n\nexport const getDescendantNodes = (\n node: StorageNode,\n prefix: Uint8Array,\n nibbles: number\n): Array<{ key: Uint8Array; nibbles: number; node: StorageNode }> => {\n let result = new Array<{\n key: Uint8Array;\n nibbles: number;\n node: StorageNode;\n }>();\n if (node.value) {\n result.push({ key: prefix, nibbles, node });\n }\n\n node.children.forEach((child, i) => {\n if (!child) return;\n\n const childPrefix = setNibble(prefix, nibbles, i);\n result = [\n ...result,\n ...getDescendantNodes(child, childPrefix, nibbles + 1),\n ];\n });\n return result;\n};\n\nexport const getSoftDeletedDescendantKeys = (\n node: StorageNode,\n prefix: Uint8Array,\n nibbles: number\n): Array<Uint8Array> => {\n let result = new Array<Uint8Array>();\n if (node.value === null) {\n result.push(prefix);\n }\n\n node.children.forEach((child, i) => {\n if (!child) return;\n\n const childPrefix = setNibble(prefix, nibbles, i);\n result = [\n ...result,\n ...getSoftDeletedDescendantKeys(child, childPrefix, nibbles + 1),\n ];\n });\n return result;\n};\n\nexport const forEachDescendant = (\n root: StorageNode,\n cb: (node: StorageNode) => void\n) => {\n root.children.forEach((child) => {\n if (!child) return;\n cb(child);\n forEachDescendant(child, cb);\n });\n};\n\nconst arrU8Eq = (a: Uint8Array, b: Uint8Array) =>\n a.length === b.length && a.every((v, i) => b[i] === v);\n"],"names":["children"],"mappings":"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"}