@acala-network/chopsticks 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 (61) hide show
  1. package/README.md +52 -0
  2. package/chopsticks.js +2 -0
  3. package/dist/api.d.ts +43 -0
  4. package/dist/api.js +78 -0
  5. package/dist/blockchain/block.d.ts +38 -0
  6. package/dist/blockchain/block.js +178 -0
  7. package/dist/blockchain/head-state.d.ts +13 -0
  8. package/dist/blockchain/head-state.js +57 -0
  9. package/dist/blockchain/index.d.ts +35 -0
  10. package/dist/blockchain/index.js +115 -0
  11. package/dist/blockchain/inherents.d.ts +26 -0
  12. package/dist/blockchain/inherents.js +96 -0
  13. package/dist/blockchain/storage-layer.d.ts +32 -0
  14. package/dist/blockchain/storage-layer.js +168 -0
  15. package/dist/blockchain/txpool.d.ts +13 -0
  16. package/dist/blockchain/txpool.js +165 -0
  17. package/dist/db/entities.d.ts +5 -0
  18. package/dist/db/entities.js +34 -0
  19. package/dist/db/index.d.ts +3 -0
  20. package/dist/db/index.js +41 -0
  21. package/dist/executor.d.ts +16 -0
  22. package/dist/executor.js +25 -0
  23. package/dist/executor.test.d.ts +1 -0
  24. package/dist/executor.test.js +58 -0
  25. package/dist/genesis-provider.d.ts +42 -0
  26. package/dist/genesis-provider.js +141 -0
  27. package/dist/index.d.ts +13 -0
  28. package/dist/index.js +208 -0
  29. package/dist/logger.d.ts +7 -0
  30. package/dist/logger.js +25 -0
  31. package/dist/rpc/dev.d.ts +3 -0
  32. package/dist/rpc/dev.js +33 -0
  33. package/dist/rpc/exec.d.ts +3 -0
  34. package/dist/rpc/exec.js +44 -0
  35. package/dist/rpc/index.d.ts +5 -0
  36. package/dist/rpc/index.js +25 -0
  37. package/dist/rpc/shared.d.ts +30 -0
  38. package/dist/rpc/shared.js +20 -0
  39. package/dist/rpc/substrate/author.d.ts +3 -0
  40. package/dist/rpc/substrate/author.js +42 -0
  41. package/dist/rpc/substrate/chain.d.ts +5 -0
  42. package/dist/rpc/substrate/chain.js +62 -0
  43. package/dist/rpc/substrate/index.d.ts +3 -0
  44. package/dist/rpc/substrate/index.js +20 -0
  45. package/dist/rpc/substrate/state.d.ts +3 -0
  46. package/dist/rpc/substrate/state.js +80 -0
  47. package/dist/rpc/substrate/system.d.ts +3 -0
  48. package/dist/rpc/substrate/system.js +27 -0
  49. package/dist/schema/index.d.ts +183 -0
  50. package/dist/schema/index.js +29 -0
  51. package/dist/server.d.ts +9 -0
  52. package/dist/server.js +148 -0
  53. package/dist/task.d.ts +38 -0
  54. package/dist/task.js +66 -0
  55. package/dist/utils/import-storage.d.ts +4 -0
  56. package/dist/utils/import-storage.js +43 -0
  57. package/dist/utils/index.d.ts +7 -0
  58. package/dist/utils/index.js +32 -0
  59. package/dist/utils/set-storage.d.ts +6 -0
  60. package/dist/utils/set-storage.js +57 -0
  61. package/package.json +91 -0
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const shared_1 = require("../shared");
4
+ const handlers = {
5
+ chain_getBlockHash: async (context, [blockNumber]) => {
6
+ const block = await context.chain.getBlockAt(blockNumber);
7
+ if (!block) {
8
+ throw new shared_1.ResponseError(1, 'Block not found');
9
+ }
10
+ return block.hash;
11
+ },
12
+ chain_getHeader: async (context, [hash]) => {
13
+ return (await context.chain.getBlock(hash))?.header;
14
+ },
15
+ chain_getBlock: async (context, [hash]) => {
16
+ const block = await context.chain.getBlock(hash);
17
+ if (!block) {
18
+ throw new shared_1.ResponseError(1, 'Block not found');
19
+ }
20
+ return {
21
+ block: {
22
+ header: await block.header,
23
+ extrinsics: await block.extrinsics,
24
+ },
25
+ justifications: null,
26
+ };
27
+ },
28
+ chain_getFinalizedHead: async (context) => {
29
+ return context.chain.head.hash;
30
+ },
31
+ chain_subscribeNewHead: async (context, _params, { subscribe }) => {
32
+ let update = () => { };
33
+ const id = context.chain.headState.subscribeHead(() => update());
34
+ const callback = subscribe('chain_newHead', id, () => context.chain.headState.unsubscribeHead(id));
35
+ update = async () => {
36
+ callback(await context.chain.head.header);
37
+ };
38
+ update();
39
+ return id;
40
+ },
41
+ chain_subscribeFinalizedHeads: async (context, _params, { subscribe }) => {
42
+ let update = () => { };
43
+ const id = context.chain.headState.subscribeHead(() => update());
44
+ const callback = subscribe('chain_newFinalizedHead', id, () => context.chain.headState.unsubscribeHead(id));
45
+ update = async () => {
46
+ callback(await context.chain.head.header);
47
+ };
48
+ update();
49
+ return id;
50
+ },
51
+ chain_unsubscribeNewHead: async (_context, [subid], { unsubscribe }) => {
52
+ unsubscribe(subid);
53
+ },
54
+ };
55
+ const alias = {
56
+ chain_subscribeNewHeads: handlers.chain_subscribeNewHead,
57
+ chain_unsubscribeNewHeads: handlers.chain_unsubscribeNewHead,
58
+ };
59
+ exports.default = {
60
+ ...handlers,
61
+ ...alias,
62
+ };
@@ -0,0 +1,3 @@
1
+ import { Handlers } from '../shared';
2
+ declare const handlers: Handlers;
3
+ export default handlers;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const author_1 = __importDefault(require("./author"));
7
+ const chain_1 = __importDefault(require("./chain"));
8
+ const state_1 = __importDefault(require("./state"));
9
+ const system_1 = __importDefault(require("./system"));
10
+ const handlers = {
11
+ ...author_1.default,
12
+ ...chain_1.default,
13
+ ...state_1.default,
14
+ ...system_1.default,
15
+ rpc_methods: async () => ({
16
+ version: 1,
17
+ methods: Object.keys(handlers),
18
+ }),
19
+ };
20
+ exports.default = handlers;
@@ -0,0 +1,3 @@
1
+ import { Handlers } from '../shared';
2
+ declare const handlers: Handlers;
3
+ export default handlers;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const logger_1 = require("../../logger");
4
+ const logger = logger_1.defaultLogger.child({ name: 'rpc-state' });
5
+ const handlers = {
6
+ state_getRuntimeVersion: async (context, [hash]) => {
7
+ const block = await context.chain.getBlock(hash);
8
+ return block?.runtimeVersion;
9
+ },
10
+ state_getMetadata: async (context, [hash]) => {
11
+ const block = await context.chain.getBlock(hash);
12
+ return block?.metadata;
13
+ },
14
+ state_getStorage: async (context, [key, hash]) => {
15
+ const block = await context.chain.getBlock(hash);
16
+ return block?.get(key);
17
+ },
18
+ state_getKeysPaged: async (context, [prefix, pageSize, startKey, hash]) => {
19
+ const block = await context.chain.getBlock(hash);
20
+ return block?.getKeysPaged({ prefix, pageSize, startKey });
21
+ },
22
+ state_queryStorageAt: async (context, [keys, hash]) => {
23
+ const block = await context.chain.getBlock(hash);
24
+ if (!block) {
25
+ return [];
26
+ }
27
+ const values = await Promise.all(keys.map(async (key) => [key, await block.get(key)]));
28
+ return [
29
+ {
30
+ block: block.hash,
31
+ changes: values,
32
+ },
33
+ ];
34
+ },
35
+ state_call: async (context, [method, data, hash]) => {
36
+ const block = await context.chain.getBlock(hash);
37
+ if (!block) {
38
+ return [];
39
+ }
40
+ return (await block.call(method, data)).result;
41
+ },
42
+ state_subscribeRuntimeVersion: async (context, _params, { subscribe }) => {
43
+ let update = (_block) => { };
44
+ const id = context.chain.headState.subscrubeRuntimeVersion((block) => update(block));
45
+ const callback = subscribe('state_runtimeVersion', id);
46
+ update = async (block) => callback(await block.runtimeVersion);
47
+ context.chain.head.runtimeVersion.then(callback);
48
+ return id;
49
+ },
50
+ state_unsubscribeRuntimeVersion: async (_context, [subid], { unsubscribe }) => {
51
+ unsubscribe(subid);
52
+ },
53
+ state_subscribeStorage: async (context, [keys], { subscribe }) => {
54
+ let update = (_block, _pairs) => { };
55
+ const id = await context.chain.headState.subscribeStorage(keys, (block, pairs) => update(block, pairs));
56
+ const callback = subscribe('state_storage', id, () => context.chain.headState.unsubscribeStorage(id));
57
+ update = async (block, pairs) => {
58
+ logger.trace({ hash: block.hash }, 'state_subscribeStorage');
59
+ callback({
60
+ block: block.hash,
61
+ changes: pairs,
62
+ });
63
+ };
64
+ (async () => {
65
+ const pairs = await Promise.all(keys.map(async (key) => {
66
+ const val = await context.chain.head.get(key);
67
+ return [key, val];
68
+ }));
69
+ callback({
70
+ block: context.chain.head.hash,
71
+ changes: pairs,
72
+ });
73
+ })();
74
+ return id;
75
+ },
76
+ state_unsubscribeStorage: async (_context, [subid], { unsubscribe }) => {
77
+ unsubscribe(subid);
78
+ },
79
+ };
80
+ exports.default = handlers;
@@ -0,0 +1,3 @@
1
+ import { Handlers } from '../shared';
2
+ declare const handlers: Handlers;
3
+ export default handlers;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const handlers = {
4
+ system_chain: async (context) => {
5
+ return context.api.getSystemChain();
6
+ },
7
+ system_properties: async (context) => {
8
+ return context.api.getSystemProperties();
9
+ },
10
+ system_name: async (context) => {
11
+ return context.api.getSystemName();
12
+ },
13
+ system_version: async (_context) => {
14
+ return 'chopsticks-1.1.0';
15
+ },
16
+ system_chainType: async (_context) => {
17
+ return 'Development';
18
+ },
19
+ system_health: async () => {
20
+ return {
21
+ peers: 0,
22
+ isSyncing: false,
23
+ shouldhVePeers: false,
24
+ };
25
+ },
26
+ };
27
+ exports.default = handlers;
@@ -0,0 +1,183 @@
1
+ import { BuildBlockMode } from '../blockchain/txpool';
2
+ import { z } from 'zod';
3
+ export declare const genesisSchema: z.ZodObject<{
4
+ id: z.ZodString;
5
+ name: z.ZodString;
6
+ properties: z.ZodObject<{
7
+ ss58Format: z.ZodOptional<z.ZodNumber>;
8
+ tokenDecimals: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodArray<z.ZodNumber, "many">]>>;
9
+ tokenSymbol: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ ss58Format?: number | undefined;
12
+ tokenDecimals?: number | number[] | undefined;
13
+ tokenSymbol?: string | string[] | undefined;
14
+ }, {
15
+ ss58Format?: number | undefined;
16
+ tokenDecimals?: number | number[] | undefined;
17
+ tokenSymbol?: string | string[] | undefined;
18
+ }>;
19
+ genesis: z.ZodObject<{
20
+ raw: z.ZodObject<{
21
+ top: z.ZodRecord<z.ZodString, z.ZodString>;
22
+ }, "strip", z.ZodTypeAny, {
23
+ top: Record<string, string>;
24
+ }, {
25
+ top: Record<string, string>;
26
+ }>;
27
+ }, "strip", z.ZodTypeAny, {
28
+ raw: {
29
+ top: Record<string, string>;
30
+ };
31
+ }, {
32
+ raw: {
33
+ top: Record<string, string>;
34
+ };
35
+ }>;
36
+ }, "strip", z.ZodTypeAny, {
37
+ name: string;
38
+ properties: {
39
+ ss58Format?: number | undefined;
40
+ tokenDecimals?: number | number[] | undefined;
41
+ tokenSymbol?: string | string[] | undefined;
42
+ };
43
+ id: string;
44
+ genesis: {
45
+ raw: {
46
+ top: Record<string, string>;
47
+ };
48
+ };
49
+ }, {
50
+ name: string;
51
+ properties: {
52
+ ss58Format?: number | undefined;
53
+ tokenDecimals?: number | number[] | undefined;
54
+ tokenSymbol?: string | string[] | undefined;
55
+ };
56
+ id: string;
57
+ genesis: {
58
+ raw: {
59
+ top: Record<string, string>;
60
+ };
61
+ };
62
+ }>;
63
+ export type Genesis = z.infer<typeof genesisSchema>;
64
+ export declare const configSchema: z.ZodObject<{
65
+ port: z.ZodOptional<z.ZodNumber>;
66
+ endpoint: z.ZodOptional<z.ZodString>;
67
+ block: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
68
+ 'executor-cmd': z.ZodOptional<z.ZodString>;
69
+ 'build-block-mode': z.ZodOptional<z.ZodNativeEnum<typeof BuildBlockMode>>;
70
+ 'import-storage': z.ZodOptional<z.ZodAny>;
71
+ 'mock-signature-host': z.ZodOptional<z.ZodBoolean>;
72
+ db: z.ZodOptional<z.ZodString>;
73
+ 'wasm-override': z.ZodOptional<z.ZodString>;
74
+ genesis: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodObject<{
75
+ id: z.ZodString;
76
+ name: z.ZodString;
77
+ properties: z.ZodObject<{
78
+ ss58Format: z.ZodOptional<z.ZodNumber>;
79
+ tokenDecimals: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodArray<z.ZodNumber, "many">]>>;
80
+ tokenSymbol: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
81
+ }, "strip", z.ZodTypeAny, {
82
+ ss58Format?: number | undefined;
83
+ tokenDecimals?: number | number[] | undefined;
84
+ tokenSymbol?: string | string[] | undefined;
85
+ }, {
86
+ ss58Format?: number | undefined;
87
+ tokenDecimals?: number | number[] | undefined;
88
+ tokenSymbol?: string | string[] | undefined;
89
+ }>;
90
+ genesis: z.ZodObject<{
91
+ raw: z.ZodObject<{
92
+ top: z.ZodRecord<z.ZodString, z.ZodString>;
93
+ }, "strip", z.ZodTypeAny, {
94
+ top: Record<string, string>;
95
+ }, {
96
+ top: Record<string, string>;
97
+ }>;
98
+ }, "strip", z.ZodTypeAny, {
99
+ raw: {
100
+ top: Record<string, string>;
101
+ };
102
+ }, {
103
+ raw: {
104
+ top: Record<string, string>;
105
+ };
106
+ }>;
107
+ }, "strip", z.ZodTypeAny, {
108
+ name: string;
109
+ properties: {
110
+ ss58Format?: number | undefined;
111
+ tokenDecimals?: number | number[] | undefined;
112
+ tokenSymbol?: string | string[] | undefined;
113
+ };
114
+ id: string;
115
+ genesis: {
116
+ raw: {
117
+ top: Record<string, string>;
118
+ };
119
+ };
120
+ }, {
121
+ name: string;
122
+ properties: {
123
+ ss58Format?: number | undefined;
124
+ tokenDecimals?: number | number[] | undefined;
125
+ tokenSymbol?: string | string[] | undefined;
126
+ };
127
+ id: string;
128
+ genesis: {
129
+ raw: {
130
+ top: Record<string, string>;
131
+ };
132
+ };
133
+ }>]>>;
134
+ }, "strict", z.ZodTypeAny, {
135
+ db?: string | undefined;
136
+ genesis?: string | {
137
+ name: string;
138
+ properties: {
139
+ ss58Format?: number | undefined;
140
+ tokenDecimals?: number | number[] | undefined;
141
+ tokenSymbol?: string | string[] | undefined;
142
+ };
143
+ id: string;
144
+ genesis: {
145
+ raw: {
146
+ top: Record<string, string>;
147
+ };
148
+ };
149
+ } | undefined;
150
+ port?: number | undefined;
151
+ endpoint?: string | undefined;
152
+ block?: string | number | undefined;
153
+ 'executor-cmd'?: string | undefined;
154
+ 'build-block-mode'?: BuildBlockMode | undefined;
155
+ 'import-storage'?: any;
156
+ 'mock-signature-host'?: boolean | undefined;
157
+ 'wasm-override'?: string | undefined;
158
+ }, {
159
+ db?: string | undefined;
160
+ genesis?: string | {
161
+ name: string;
162
+ properties: {
163
+ ss58Format?: number | undefined;
164
+ tokenDecimals?: number | number[] | undefined;
165
+ tokenSymbol?: string | string[] | undefined;
166
+ };
167
+ id: string;
168
+ genesis: {
169
+ raw: {
170
+ top: Record<string, string>;
171
+ };
172
+ };
173
+ } | undefined;
174
+ port?: number | undefined;
175
+ endpoint?: string | undefined;
176
+ block?: string | number | undefined;
177
+ 'executor-cmd'?: string | undefined;
178
+ 'build-block-mode'?: BuildBlockMode | undefined;
179
+ 'import-storage'?: any;
180
+ 'mock-signature-host'?: boolean | undefined;
181
+ 'wasm-override'?: string | undefined;
182
+ }>;
183
+ export type Config = z.infer<typeof configSchema>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configSchema = exports.genesisSchema = void 0;
4
+ const txpool_1 = require("../blockchain/txpool");
5
+ const zod_1 = require("zod");
6
+ exports.genesisSchema = zod_1.z.object({
7
+ id: zod_1.z.string(),
8
+ name: zod_1.z.string(),
9
+ properties: zod_1.z.object({
10
+ ss58Format: zod_1.z.number().optional(),
11
+ tokenDecimals: zod_1.z.union([zod_1.z.number(), zod_1.z.array(zod_1.z.number())]).optional(),
12
+ tokenSymbol: zod_1.z.union([zod_1.z.string(), zod_1.z.array(zod_1.z.string())]).optional(),
13
+ }),
14
+ genesis: zod_1.z.object({ raw: zod_1.z.object({ top: zod_1.z.record(zod_1.z.string()) }) }),
15
+ });
16
+ exports.configSchema = zod_1.z
17
+ .object({
18
+ port: zod_1.z.number().optional(),
19
+ endpoint: zod_1.z.string().optional(),
20
+ block: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]).optional(),
21
+ 'executor-cmd': zod_1.z.string().optional(),
22
+ 'build-block-mode': zod_1.z.nativeEnum(txpool_1.BuildBlockMode).optional(),
23
+ 'import-storage': zod_1.z.any().optional(),
24
+ 'mock-signature-host': zod_1.z.boolean().optional(),
25
+ db: zod_1.z.string().optional(),
26
+ 'wasm-override': zod_1.z.string().optional(),
27
+ genesis: zod_1.z.union([zod_1.z.string(), exports.genesisSchema]).optional(),
28
+ })
29
+ .strict();
@@ -0,0 +1,9 @@
1
+ import { SubscriptionManager } from './rpc/shared';
2
+ export type Handler = (data: {
3
+ method: string;
4
+ params: string[];
5
+ }, subscriptionManager: SubscriptionManager) => Promise<any>;
6
+ export declare const createServer: (port: number, handler: Handler) => {
7
+ port: Promise<number>;
8
+ close: () => Promise<void>;
9
+ };
package/dist/server.js ADDED
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.createServer = void 0;
27
+ const ws_1 = __importStar(require("ws"));
28
+ const logger_1 = require("./logger");
29
+ const logger = logger_1.defaultLogger.child({ name: 'ws' });
30
+ const parseRequest = (request) => {
31
+ try {
32
+ return JSON.parse(request);
33
+ }
34
+ catch (e) {
35
+ return undefined;
36
+ }
37
+ };
38
+ const createServer = (port, handler) => {
39
+ logger.debug('Starting on port %d', port);
40
+ const wss = new ws_1.WebSocketServer({ port, maxPayload: 1024 * 1024 * 100 });
41
+ const promise = new Promise((resolve, reject) => {
42
+ wss.on('listening', () => {
43
+ logger.debug(wss.address(), 'Listening');
44
+ resolve(wss.address().port);
45
+ });
46
+ wss.on('error', (err) => {
47
+ logger.error(err, 'Error');
48
+ reject(err);
49
+ });
50
+ });
51
+ wss.on('connection', (ws) => {
52
+ logger.debug('New connection');
53
+ const send = (data) => {
54
+ if (ws.readyState === ws_1.default.OPEN) {
55
+ ws.send(JSON.stringify(data));
56
+ }
57
+ };
58
+ const subscriptions = {};
59
+ const subscriptionManager = {
60
+ subscribe: (method, subid, onCancel = () => { }) => {
61
+ subscriptions[subid] = onCancel;
62
+ return (data) => {
63
+ if (subscriptions[subid]) {
64
+ send({
65
+ jsonrpc: '2.0',
66
+ method,
67
+ params: {
68
+ result: data,
69
+ subscription: subid,
70
+ },
71
+ });
72
+ }
73
+ };
74
+ },
75
+ unsubscribe: (subid) => {
76
+ if (subscriptions[subid]) {
77
+ subscriptions[subid](subid);
78
+ delete subscriptions[subid];
79
+ }
80
+ },
81
+ };
82
+ ws.on('close', () => {
83
+ logger.debug('Connection closed');
84
+ for (const [subid, onCancel] of Object.entries(subscriptions)) {
85
+ onCancel(subid);
86
+ }
87
+ ws.removeAllListeners();
88
+ });
89
+ ws.on('error', () => {
90
+ logger.debug('Connection error');
91
+ for (const [subid, onCancel] of Object.entries(subscriptions)) {
92
+ onCancel(subid);
93
+ }
94
+ ws.removeAllListeners();
95
+ });
96
+ ws.on('message', async (message) => {
97
+ const req = parseRequest(message.toString());
98
+ if (!req || req.id == null || req.method == null) {
99
+ logger.info('Invalid request: %s', message);
100
+ send({
101
+ id: null,
102
+ jsonrpc: '2.0',
103
+ error: {
104
+ code: -32600,
105
+ message: 'Invalid JSON Request',
106
+ },
107
+ });
108
+ return;
109
+ }
110
+ logger.trace({
111
+ id: req.id,
112
+ method: req.method,
113
+ }, 'Received message');
114
+ try {
115
+ const resp = await handler(req, subscriptionManager);
116
+ logger.trace('Sending response for request %o %o', req.id, req.method);
117
+ send({
118
+ id: req.id,
119
+ jsonrpc: '2.0',
120
+ result: resp || null,
121
+ });
122
+ }
123
+ catch (e) {
124
+ logger.info('Error handling request: %s %o', e, e.stack);
125
+ send({
126
+ id: req.id,
127
+ jsonrpc: '2.0',
128
+ error: e,
129
+ });
130
+ }
131
+ });
132
+ });
133
+ return {
134
+ port: promise,
135
+ close: () => new Promise((resolve, reject) => {
136
+ wss.clients.forEach((socket) => socket.close());
137
+ wss.close((err) => {
138
+ if (err) {
139
+ reject(err);
140
+ }
141
+ else {
142
+ resolve();
143
+ }
144
+ });
145
+ }),
146
+ };
147
+ };
148
+ exports.createServer = createServer;
package/dist/task.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ export interface TaskResponseCall {
2
+ Call: {
3
+ result: string;
4
+ storageDiff: [string, string | null][];
5
+ };
6
+ }
7
+ export interface TaskResponseError {
8
+ Error: string;
9
+ }
10
+ export type TaskResponse = TaskResponseCall | TaskResponseError;
11
+ interface TaskCall {
12
+ wasm: string;
13
+ blockHash: string;
14
+ calls: [string, string][];
15
+ mockSignatureHost?: boolean;
16
+ allowUnresolvedImports?: boolean;
17
+ }
18
+ interface TaskCalculateStateRoot {
19
+ entries: [string, string][];
20
+ }
21
+ type Task = {
22
+ Call: TaskCall;
23
+ } | {
24
+ CalculateStateRoot: TaskCalculateStateRoot;
25
+ };
26
+ export declare class TaskManager {
27
+ #private;
28
+ constructor(listeningPort: number, mockSignatureHost?: boolean, executorCmd?: string, allowUnresolvedImports?: boolean);
29
+ updateListeningPort(port: number): void;
30
+ addTask(task: Task, callback?: (res: TaskResponse) => any): number;
31
+ getTask(taskId: number): {
32
+ task: Task;
33
+ callback: (res: TaskResponse) => any;
34
+ };
35
+ runTask(taskId: number): Promise<void>;
36
+ addAndRunTask(task: Task, callback?: (res: TaskResponse) => any): Promise<void>;
37
+ }
38
+ export {};
package/dist/task.js ADDED
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TaskManager = void 0;
4
+ const node_child_process_1 = require("node:child_process");
5
+ const logger_1 = require("./logger");
6
+ const executor_1 = require("./executor");
7
+ const logger = logger_1.defaultLogger.child({ name: 'task' });
8
+ class TaskManager {
9
+ #tasks = [];
10
+ #listeningPort;
11
+ #mockSignatureHost;
12
+ #executorCmd;
13
+ #allowUnresolvedImports;
14
+ constructor(listeningPort, mockSignatureHost = false, executorCmd, allowUnresolvedImports = false) {
15
+ this.#listeningPort = listeningPort;
16
+ this.#mockSignatureHost = mockSignatureHost;
17
+ this.#executorCmd = executorCmd;
18
+ this.#allowUnresolvedImports = allowUnresolvedImports;
19
+ if (this.#mockSignatureHost) {
20
+ logger.info('Mock signature host enabled');
21
+ }
22
+ if (this.#allowUnresolvedImports) {
23
+ logger.info('Allow unresolved imports enabled. Wasm may expect more host functions, but will not fail on load');
24
+ }
25
+ }
26
+ updateListeningPort(port) {
27
+ this.#listeningPort = port;
28
+ }
29
+ addTask(task, callback = () => { }) {
30
+ logger.debug({
31
+ kind: Object.keys(task)[0],
32
+ }, 'AddTask');
33
+ if ('Call' in task && task.Call.mockSignatureHost === undefined) {
34
+ task.Call.mockSignatureHost = this.#mockSignatureHost;
35
+ }
36
+ if ('Call' in task && task.Call.allowUnresolvedImports === undefined) {
37
+ task.Call.allowUnresolvedImports = this.#allowUnresolvedImports;
38
+ }
39
+ this.#tasks.push({ task, callback });
40
+ return this.#tasks.length - 1;
41
+ }
42
+ getTask(taskId) {
43
+ return this.#tasks[taskId];
44
+ }
45
+ runTask(taskId) {
46
+ if (this.#executorCmd) {
47
+ const cmd = `${this.#executorCmd} --runner-url=ws://localhost:${this.#listeningPort} --task-id=${taskId}`;
48
+ logger.info({ taskId, cmd }, 'RunTask');
49
+ const p = (0, node_child_process_1.spawn)(cmd, { shell: true, stdio: 'inherit' });
50
+ return new Promise((resolve) => {
51
+ p.once('exit', (code) => {
52
+ logger.debug({ taskId, code }, 'RunTask done');
53
+ resolve();
54
+ });
55
+ });
56
+ }
57
+ else {
58
+ return (0, executor_1.runTask)(taskId, `ws://localhost:${this.#listeningPort}`);
59
+ }
60
+ }
61
+ async addAndRunTask(task, callback = () => { }) {
62
+ const taskId = this.addTask(task, callback);
63
+ await this.runTask(taskId);
64
+ }
65
+ }
66
+ exports.TaskManager = TaskManager;
@@ -0,0 +1,4 @@
1
+ import { Blockchain } from '../blockchain';
2
+ import { StorageValues } from './set-storage';
3
+ export declare const importStorage: (chain: Blockchain, storage?: string | StorageValues) => Promise<void>;
4
+ export declare const overrideWasm: (chain: Blockchain, wasmPath?: string) => Promise<void>;