@xyo-network/xl1-rpc-server 1.25.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/createRpcHttpServer.d.ts +14 -0
- package/dist/browser/createRpcHttpServer.d.ts.map +1 -0
- package/dist/browser/createRpcRequestHandler.d.ts +4 -0
- package/dist/browser/createRpcRequestHandler.d.ts.map +1 -0
- package/dist/browser/index.d.ts +3 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.mjs +81 -0
- package/dist/browser/index.mjs.map +1 -0
- package/dist/neutral/createRpcHttpServer.d.ts +14 -0
- package/dist/neutral/createRpcHttpServer.d.ts.map +1 -0
- package/dist/neutral/createRpcRequestHandler.d.ts +4 -0
- package/dist/neutral/createRpcRequestHandler.d.ts.map +1 -0
- package/dist/neutral/index.d.ts +3 -0
- package/dist/neutral/index.d.ts.map +1 -0
- package/dist/neutral/index.mjs +81 -0
- package/dist/neutral/index.mjs.map +1 -0
- package/dist/node/createRpcHttpServer.d.ts +14 -0
- package/dist/node/createRpcHttpServer.d.ts.map +1 -0
- package/dist/node/createRpcRequestHandler.d.ts +4 -0
- package/dist/node/createRpcRequestHandler.d.ts.map +1 -0
- package/dist/node/index.d.ts +3 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.mjs +81 -0
- package/dist/node/index.mjs.map +1 -0
- package/package.json +71 -0
- package/src/createRpcHttpServer.ts +74 -0
- package/src/createRpcRequestHandler.ts +21 -0
- package/src/index.ts +2 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import HTTP from 'node:http';
|
|
2
|
+
import type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2';
|
|
3
|
+
/** Result returned by createRpcHttpServer. */
|
|
4
|
+
export interface RpcHttpServer {
|
|
5
|
+
close: () => Promise<void>;
|
|
6
|
+
port: number;
|
|
7
|
+
server: HTTP.Server;
|
|
8
|
+
}
|
|
9
|
+
/** Creates a standalone Node.js HTTP server that handles JSON-RPC requests at POST /rpc. */
|
|
10
|
+
export declare function createRpcHttpServer(options: {
|
|
11
|
+
engine: JsonRpcEngineV2;
|
|
12
|
+
port: number;
|
|
13
|
+
}): Promise<RpcHttpServer>;
|
|
14
|
+
//# sourceMappingURL=createRpcHttpServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createRpcHttpServer.d.ts","sourceRoot":"","sources":["../../src/createRpcHttpServer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAInE,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CACpB;AAED,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CA2D9G"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2';
|
|
2
|
+
/** Creates a framework-agnostic RPC request handler from a JSON-RPC engine. */
|
|
3
|
+
export declare function createRpcRequestHandler(engine: JsonRpcEngineV2): (body: unknown) => Promise<unknown>;
|
|
4
|
+
//# sourceMappingURL=createRpcRequestHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createRpcRequestHandler.d.ts","sourceRoot":"","sources":["../../src/createRpcRequestHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAGnE,+EAA+E;AAC/E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,eAAe,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAgBpG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAA;AACxC,cAAc,8BAA8B,CAAA"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// src/createRpcHttpServer.ts
|
|
2
|
+
import HTTP from "http";
|
|
3
|
+
|
|
4
|
+
// src/createRpcRequestHandler.ts
|
|
5
|
+
function createRpcRequestHandler(engine) {
|
|
6
|
+
return async (body) => {
|
|
7
|
+
const request = body;
|
|
8
|
+
try {
|
|
9
|
+
const result = await engine.handle(request);
|
|
10
|
+
return {
|
|
11
|
+
jsonrpc: "2.0",
|
|
12
|
+
id: request.id,
|
|
13
|
+
result
|
|
14
|
+
};
|
|
15
|
+
} catch (error) {
|
|
16
|
+
return {
|
|
17
|
+
jsonrpc: "2.0",
|
|
18
|
+
id: request.id,
|
|
19
|
+
error: { code: -32603, message: error.message }
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/createRpcHttpServer.ts
|
|
26
|
+
function createRpcHttpServer(options) {
|
|
27
|
+
const { engine, port } = options;
|
|
28
|
+
const handler = createRpcRequestHandler(engine);
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const server = HTTP.createServer((req, res) => {
|
|
31
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
32
|
+
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
|
|
33
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
34
|
+
if (req.method === "OPTIONS") {
|
|
35
|
+
res.writeHead(204);
|
|
36
|
+
res.end();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (req.method !== "POST" || req.url !== "/rpc") {
|
|
40
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
41
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
let body = "";
|
|
45
|
+
req.on("data", (chunk) => {
|
|
46
|
+
body += chunk.toString();
|
|
47
|
+
});
|
|
48
|
+
req.on("end", () => {
|
|
49
|
+
const parsed = JSON.parse(body);
|
|
50
|
+
handler(parsed).then((response) => {
|
|
51
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
52
|
+
res.end(JSON.stringify(response));
|
|
53
|
+
}).catch((error) => {
|
|
54
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
55
|
+
res.end(JSON.stringify({ error: error.message }));
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
server.on("error", reject);
|
|
60
|
+
server.listen(port, () => {
|
|
61
|
+
resolve({
|
|
62
|
+
server,
|
|
63
|
+
port,
|
|
64
|
+
close: () => new Promise((resolveClose, rejectClose) => {
|
|
65
|
+
server.close((err) => {
|
|
66
|
+
if (err) {
|
|
67
|
+
rejectClose(err);
|
|
68
|
+
} else {
|
|
69
|
+
resolveClose();
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
createRpcHttpServer,
|
|
79
|
+
createRpcRequestHandler
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/createRpcHttpServer.ts","../../src/createRpcRequestHandler.ts"],"sourcesContent":["import HTTP from 'node:http'\n\nimport type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2'\n\nimport { createRpcRequestHandler } from './createRpcRequestHandler.ts'\n\n/** Result returned by createRpcHttpServer. */\nexport interface RpcHttpServer {\n close: () => Promise<void>\n port: number\n server: HTTP.Server\n}\n\n/** Creates a standalone Node.js HTTP server that handles JSON-RPC requests at POST /rpc. */\nexport function createRpcHttpServer(options: { engine: JsonRpcEngineV2; port: number }): Promise<RpcHttpServer> {\n const { engine, port } = options\n const handler = createRpcRequestHandler(engine)\n\n return new Promise((resolve, reject) => {\n const server = HTTP.createServer((req, res) => {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type')\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n if (req.method !== 'POST' || req.url !== '/rpc') {\n res.writeHead(404, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Not found' }))\n return\n }\n\n let body = ''\n req.on('data', (chunk: Buffer) => {\n body += chunk.toString()\n })\n\n req.on('end', () => {\n const parsed = JSON.parse(body)\n handler(parsed)\n .then((response) => {\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(response))\n })\n .catch((error: unknown) => {\n res.writeHead(500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: (error as Error).message }))\n })\n })\n })\n\n server.on('error', reject)\n\n server.listen(port, () => {\n resolve({\n server,\n port,\n close: () => new Promise<void>((resolveClose, rejectClose) => {\n server.close((err) => {\n if (err) {\n rejectClose(err)\n } else {\n resolveClose()\n }\n })\n }),\n })\n })\n })\n}\n","import type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2'\nimport type { JsonRpcRequest } from '@metamask/utils'\n\n/** Creates a framework-agnostic RPC request handler from a JSON-RPC engine. */\nexport function createRpcRequestHandler(engine: JsonRpcEngineV2): (body: unknown) => Promise<unknown> {\n return async (body: unknown) => {\n const request = body as JsonRpcRequest\n try {\n const result = await engine.handle(request)\n return {\n jsonrpc: '2.0', id: request.id, result,\n }\n } catch (error) {\n return {\n jsonrpc: '2.0',\n id: request.id,\n error: { code: -32_603, message: (error as Error).message },\n }\n }\n }\n}\n"],"mappings":";AAAA,OAAO,UAAU;;;ACIV,SAAS,wBAAwB,QAA8D;AACpG,SAAO,OAAO,SAAkB;AAC9B,UAAM,UAAU;AAChB,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,OAAO,OAAO;AAC1C,aAAO;AAAA,QACL,SAAS;AAAA,QAAO,IAAI,QAAQ;AAAA,QAAI;AAAA,MAClC;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,IAAI,QAAQ;AAAA,QACZ,OAAO,EAAE,MAAM,QAAS,SAAU,MAAgB,QAAQ;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AACF;;;ADNO,SAAS,oBAAoB,SAA4E;AAC9G,QAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,QAAM,UAAU,wBAAwB,MAAM;AAE9C,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAS,KAAK,aAAa,CAAC,KAAK,QAAQ;AAC7C,UAAI,UAAU,+BAA+B,GAAG;AAChD,UAAI,UAAU,gCAAgC,eAAe;AAC7D,UAAI,UAAU,gCAAgC,cAAc;AAE5D,UAAI,IAAI,WAAW,WAAW;AAC5B,YAAI,UAAU,GAAG;AACjB,YAAI,IAAI;AACR;AAAA,MACF;AAEA,UAAI,IAAI,WAAW,UAAU,IAAI,QAAQ,QAAQ;AAC/C,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,YAAI,IAAI,KAAK,UAAU,EAAE,OAAO,YAAY,CAAC,CAAC;AAC9C;AAAA,MACF;AAEA,UAAI,OAAO;AACX,UAAI,GAAG,QAAQ,CAAC,UAAkB;AAChC,gBAAQ,MAAM,SAAS;AAAA,MACzB,CAAC;AAED,UAAI,GAAG,OAAO,MAAM;AAClB,cAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,gBAAQ,MAAM,EACX,KAAK,CAAC,aAAa;AAClB,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,QAAQ,CAAC;AAAA,QAClC,CAAC,EACA,MAAM,CAAC,UAAmB;AACzB,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAAA,QAC7D,CAAC;AAAA,MACL,CAAC;AAAA,IACH,CAAC;AAED,WAAO,GAAG,SAAS,MAAM;AAEzB,WAAO,OAAO,MAAM,MAAM;AACxB,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA,OAAO,MAAM,IAAI,QAAc,CAAC,cAAc,gBAAgB;AAC5D,iBAAO,MAAM,CAAC,QAAQ;AACpB,gBAAI,KAAK;AACP,0BAAY,GAAG;AAAA,YACjB,OAAO;AACL,2BAAa;AAAA,YACf;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import HTTP from 'node:http';
|
|
2
|
+
import type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2';
|
|
3
|
+
/** Result returned by createRpcHttpServer. */
|
|
4
|
+
export interface RpcHttpServer {
|
|
5
|
+
close: () => Promise<void>;
|
|
6
|
+
port: number;
|
|
7
|
+
server: HTTP.Server;
|
|
8
|
+
}
|
|
9
|
+
/** Creates a standalone Node.js HTTP server that handles JSON-RPC requests at POST /rpc. */
|
|
10
|
+
export declare function createRpcHttpServer(options: {
|
|
11
|
+
engine: JsonRpcEngineV2;
|
|
12
|
+
port: number;
|
|
13
|
+
}): Promise<RpcHttpServer>;
|
|
14
|
+
//# sourceMappingURL=createRpcHttpServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createRpcHttpServer.d.ts","sourceRoot":"","sources":["../../src/createRpcHttpServer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAInE,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CACpB;AAED,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CA2D9G"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2';
|
|
2
|
+
/** Creates a framework-agnostic RPC request handler from a JSON-RPC engine. */
|
|
3
|
+
export declare function createRpcRequestHandler(engine: JsonRpcEngineV2): (body: unknown) => Promise<unknown>;
|
|
4
|
+
//# sourceMappingURL=createRpcRequestHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createRpcRequestHandler.d.ts","sourceRoot":"","sources":["../../src/createRpcRequestHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAGnE,+EAA+E;AAC/E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,eAAe,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAgBpG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAA;AACxC,cAAc,8BAA8B,CAAA"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// src/createRpcHttpServer.ts
|
|
2
|
+
import HTTP from "http";
|
|
3
|
+
|
|
4
|
+
// src/createRpcRequestHandler.ts
|
|
5
|
+
function createRpcRequestHandler(engine) {
|
|
6
|
+
return async (body) => {
|
|
7
|
+
const request = body;
|
|
8
|
+
try {
|
|
9
|
+
const result = await engine.handle(request);
|
|
10
|
+
return {
|
|
11
|
+
jsonrpc: "2.0",
|
|
12
|
+
id: request.id,
|
|
13
|
+
result
|
|
14
|
+
};
|
|
15
|
+
} catch (error) {
|
|
16
|
+
return {
|
|
17
|
+
jsonrpc: "2.0",
|
|
18
|
+
id: request.id,
|
|
19
|
+
error: { code: -32603, message: error.message }
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/createRpcHttpServer.ts
|
|
26
|
+
function createRpcHttpServer(options) {
|
|
27
|
+
const { engine, port } = options;
|
|
28
|
+
const handler = createRpcRequestHandler(engine);
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const server = HTTP.createServer((req, res) => {
|
|
31
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
32
|
+
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
|
|
33
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
34
|
+
if (req.method === "OPTIONS") {
|
|
35
|
+
res.writeHead(204);
|
|
36
|
+
res.end();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (req.method !== "POST" || req.url !== "/rpc") {
|
|
40
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
41
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
let body = "";
|
|
45
|
+
req.on("data", (chunk) => {
|
|
46
|
+
body += chunk.toString();
|
|
47
|
+
});
|
|
48
|
+
req.on("end", () => {
|
|
49
|
+
const parsed = JSON.parse(body);
|
|
50
|
+
handler(parsed).then((response) => {
|
|
51
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
52
|
+
res.end(JSON.stringify(response));
|
|
53
|
+
}).catch((error) => {
|
|
54
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
55
|
+
res.end(JSON.stringify({ error: error.message }));
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
server.on("error", reject);
|
|
60
|
+
server.listen(port, () => {
|
|
61
|
+
resolve({
|
|
62
|
+
server,
|
|
63
|
+
port,
|
|
64
|
+
close: () => new Promise((resolveClose, rejectClose) => {
|
|
65
|
+
server.close((err) => {
|
|
66
|
+
if (err) {
|
|
67
|
+
rejectClose(err);
|
|
68
|
+
} else {
|
|
69
|
+
resolveClose();
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
createRpcHttpServer,
|
|
79
|
+
createRpcRequestHandler
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/createRpcHttpServer.ts","../../src/createRpcRequestHandler.ts"],"sourcesContent":["import HTTP from 'node:http'\n\nimport type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2'\n\nimport { createRpcRequestHandler } from './createRpcRequestHandler.ts'\n\n/** Result returned by createRpcHttpServer. */\nexport interface RpcHttpServer {\n close: () => Promise<void>\n port: number\n server: HTTP.Server\n}\n\n/** Creates a standalone Node.js HTTP server that handles JSON-RPC requests at POST /rpc. */\nexport function createRpcHttpServer(options: { engine: JsonRpcEngineV2; port: number }): Promise<RpcHttpServer> {\n const { engine, port } = options\n const handler = createRpcRequestHandler(engine)\n\n return new Promise((resolve, reject) => {\n const server = HTTP.createServer((req, res) => {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type')\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n if (req.method !== 'POST' || req.url !== '/rpc') {\n res.writeHead(404, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Not found' }))\n return\n }\n\n let body = ''\n req.on('data', (chunk: Buffer) => {\n body += chunk.toString()\n })\n\n req.on('end', () => {\n const parsed = JSON.parse(body)\n handler(parsed)\n .then((response) => {\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(response))\n })\n .catch((error: unknown) => {\n res.writeHead(500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: (error as Error).message }))\n })\n })\n })\n\n server.on('error', reject)\n\n server.listen(port, () => {\n resolve({\n server,\n port,\n close: () => new Promise<void>((resolveClose, rejectClose) => {\n server.close((err) => {\n if (err) {\n rejectClose(err)\n } else {\n resolveClose()\n }\n })\n }),\n })\n })\n })\n}\n","import type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2'\nimport type { JsonRpcRequest } from '@metamask/utils'\n\n/** Creates a framework-agnostic RPC request handler from a JSON-RPC engine. */\nexport function createRpcRequestHandler(engine: JsonRpcEngineV2): (body: unknown) => Promise<unknown> {\n return async (body: unknown) => {\n const request = body as JsonRpcRequest\n try {\n const result = await engine.handle(request)\n return {\n jsonrpc: '2.0', id: request.id, result,\n }\n } catch (error) {\n return {\n jsonrpc: '2.0',\n id: request.id,\n error: { code: -32_603, message: (error as Error).message },\n }\n }\n }\n}\n"],"mappings":";AAAA,OAAO,UAAU;;;ACIV,SAAS,wBAAwB,QAA8D;AACpG,SAAO,OAAO,SAAkB;AAC9B,UAAM,UAAU;AAChB,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,OAAO,OAAO;AAC1C,aAAO;AAAA,QACL,SAAS;AAAA,QAAO,IAAI,QAAQ;AAAA,QAAI;AAAA,MAClC;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,IAAI,QAAQ;AAAA,QACZ,OAAO,EAAE,MAAM,QAAS,SAAU,MAAgB,QAAQ;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AACF;;;ADNO,SAAS,oBAAoB,SAA4E;AAC9G,QAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,QAAM,UAAU,wBAAwB,MAAM;AAE9C,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAS,KAAK,aAAa,CAAC,KAAK,QAAQ;AAC7C,UAAI,UAAU,+BAA+B,GAAG;AAChD,UAAI,UAAU,gCAAgC,eAAe;AAC7D,UAAI,UAAU,gCAAgC,cAAc;AAE5D,UAAI,IAAI,WAAW,WAAW;AAC5B,YAAI,UAAU,GAAG;AACjB,YAAI,IAAI;AACR;AAAA,MACF;AAEA,UAAI,IAAI,WAAW,UAAU,IAAI,QAAQ,QAAQ;AAC/C,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,YAAI,IAAI,KAAK,UAAU,EAAE,OAAO,YAAY,CAAC,CAAC;AAC9C;AAAA,MACF;AAEA,UAAI,OAAO;AACX,UAAI,GAAG,QAAQ,CAAC,UAAkB;AAChC,gBAAQ,MAAM,SAAS;AAAA,MACzB,CAAC;AAED,UAAI,GAAG,OAAO,MAAM;AAClB,cAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,gBAAQ,MAAM,EACX,KAAK,CAAC,aAAa;AAClB,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,QAAQ,CAAC;AAAA,QAClC,CAAC,EACA,MAAM,CAAC,UAAmB;AACzB,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAAA,QAC7D,CAAC;AAAA,MACL,CAAC;AAAA,IACH,CAAC;AAED,WAAO,GAAG,SAAS,MAAM;AAEzB,WAAO,OAAO,MAAM,MAAM;AACxB,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA,OAAO,MAAM,IAAI,QAAc,CAAC,cAAc,gBAAgB;AAC5D,iBAAO,MAAM,CAAC,QAAQ;AACpB,gBAAI,KAAK;AACP,0BAAY,GAAG;AAAA,YACjB,OAAO;AACL,2BAAa;AAAA,YACf;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import HTTP from 'node:http';
|
|
2
|
+
import type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2';
|
|
3
|
+
/** Result returned by createRpcHttpServer. */
|
|
4
|
+
export interface RpcHttpServer {
|
|
5
|
+
close: () => Promise<void>;
|
|
6
|
+
port: number;
|
|
7
|
+
server: HTTP.Server;
|
|
8
|
+
}
|
|
9
|
+
/** Creates a standalone Node.js HTTP server that handles JSON-RPC requests at POST /rpc. */
|
|
10
|
+
export declare function createRpcHttpServer(options: {
|
|
11
|
+
engine: JsonRpcEngineV2;
|
|
12
|
+
port: number;
|
|
13
|
+
}): Promise<RpcHttpServer>;
|
|
14
|
+
//# sourceMappingURL=createRpcHttpServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createRpcHttpServer.d.ts","sourceRoot":"","sources":["../../src/createRpcHttpServer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAInE,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CACpB;AAED,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CA2D9G"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2';
|
|
2
|
+
/** Creates a framework-agnostic RPC request handler from a JSON-RPC engine. */
|
|
3
|
+
export declare function createRpcRequestHandler(engine: JsonRpcEngineV2): (body: unknown) => Promise<unknown>;
|
|
4
|
+
//# sourceMappingURL=createRpcRequestHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createRpcRequestHandler.d.ts","sourceRoot":"","sources":["../../src/createRpcRequestHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAGnE,+EAA+E;AAC/E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,eAAe,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAgBpG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAA;AACxC,cAAc,8BAA8B,CAAA"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// src/createRpcHttpServer.ts
|
|
2
|
+
import HTTP from "http";
|
|
3
|
+
|
|
4
|
+
// src/createRpcRequestHandler.ts
|
|
5
|
+
function createRpcRequestHandler(engine) {
|
|
6
|
+
return async (body) => {
|
|
7
|
+
const request = body;
|
|
8
|
+
try {
|
|
9
|
+
const result = await engine.handle(request);
|
|
10
|
+
return {
|
|
11
|
+
jsonrpc: "2.0",
|
|
12
|
+
id: request.id,
|
|
13
|
+
result
|
|
14
|
+
};
|
|
15
|
+
} catch (error) {
|
|
16
|
+
return {
|
|
17
|
+
jsonrpc: "2.0",
|
|
18
|
+
id: request.id,
|
|
19
|
+
error: { code: -32603, message: error.message }
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/createRpcHttpServer.ts
|
|
26
|
+
function createRpcHttpServer(options) {
|
|
27
|
+
const { engine, port } = options;
|
|
28
|
+
const handler = createRpcRequestHandler(engine);
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const server = HTTP.createServer((req, res) => {
|
|
31
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
32
|
+
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
|
|
33
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
34
|
+
if (req.method === "OPTIONS") {
|
|
35
|
+
res.writeHead(204);
|
|
36
|
+
res.end();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (req.method !== "POST" || req.url !== "/rpc") {
|
|
40
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
41
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
let body = "";
|
|
45
|
+
req.on("data", (chunk) => {
|
|
46
|
+
body += chunk.toString();
|
|
47
|
+
});
|
|
48
|
+
req.on("end", () => {
|
|
49
|
+
const parsed = JSON.parse(body);
|
|
50
|
+
handler(parsed).then((response) => {
|
|
51
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
52
|
+
res.end(JSON.stringify(response));
|
|
53
|
+
}).catch((error) => {
|
|
54
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
55
|
+
res.end(JSON.stringify({ error: error.message }));
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
server.on("error", reject);
|
|
60
|
+
server.listen(port, () => {
|
|
61
|
+
resolve({
|
|
62
|
+
server,
|
|
63
|
+
port,
|
|
64
|
+
close: () => new Promise((resolveClose, rejectClose) => {
|
|
65
|
+
server.close((err) => {
|
|
66
|
+
if (err) {
|
|
67
|
+
rejectClose(err);
|
|
68
|
+
} else {
|
|
69
|
+
resolveClose();
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
createRpcHttpServer,
|
|
79
|
+
createRpcRequestHandler
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/createRpcHttpServer.ts","../../src/createRpcRequestHandler.ts"],"sourcesContent":["import HTTP from 'node:http'\n\nimport type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2'\n\nimport { createRpcRequestHandler } from './createRpcRequestHandler.ts'\n\n/** Result returned by createRpcHttpServer. */\nexport interface RpcHttpServer {\n close: () => Promise<void>\n port: number\n server: HTTP.Server\n}\n\n/** Creates a standalone Node.js HTTP server that handles JSON-RPC requests at POST /rpc. */\nexport function createRpcHttpServer(options: { engine: JsonRpcEngineV2; port: number }): Promise<RpcHttpServer> {\n const { engine, port } = options\n const handler = createRpcRequestHandler(engine)\n\n return new Promise((resolve, reject) => {\n const server = HTTP.createServer((req, res) => {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type')\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n if (req.method !== 'POST' || req.url !== '/rpc') {\n res.writeHead(404, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Not found' }))\n return\n }\n\n let body = ''\n req.on('data', (chunk: Buffer) => {\n body += chunk.toString()\n })\n\n req.on('end', () => {\n const parsed = JSON.parse(body)\n handler(parsed)\n .then((response) => {\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(response))\n })\n .catch((error: unknown) => {\n res.writeHead(500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: (error as Error).message }))\n })\n })\n })\n\n server.on('error', reject)\n\n server.listen(port, () => {\n resolve({\n server,\n port,\n close: () => new Promise<void>((resolveClose, rejectClose) => {\n server.close((err) => {\n if (err) {\n rejectClose(err)\n } else {\n resolveClose()\n }\n })\n }),\n })\n })\n })\n}\n","import type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2'\nimport type { JsonRpcRequest } from '@metamask/utils'\n\n/** Creates a framework-agnostic RPC request handler from a JSON-RPC engine. */\nexport function createRpcRequestHandler(engine: JsonRpcEngineV2): (body: unknown) => Promise<unknown> {\n return async (body: unknown) => {\n const request = body as JsonRpcRequest\n try {\n const result = await engine.handle(request)\n return {\n jsonrpc: '2.0', id: request.id, result,\n }\n } catch (error) {\n return {\n jsonrpc: '2.0',\n id: request.id,\n error: { code: -32_603, message: (error as Error).message },\n }\n }\n }\n}\n"],"mappings":";AAAA,OAAO,UAAU;;;ACIV,SAAS,wBAAwB,QAA8D;AACpG,SAAO,OAAO,SAAkB;AAC9B,UAAM,UAAU;AAChB,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,OAAO,OAAO;AAC1C,aAAO;AAAA,QACL,SAAS;AAAA,QAAO,IAAI,QAAQ;AAAA,QAAI;AAAA,MAClC;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,IAAI,QAAQ;AAAA,QACZ,OAAO,EAAE,MAAM,QAAS,SAAU,MAAgB,QAAQ;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AACF;;;ADNO,SAAS,oBAAoB,SAA4E;AAC9G,QAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,QAAM,UAAU,wBAAwB,MAAM;AAE9C,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAS,KAAK,aAAa,CAAC,KAAK,QAAQ;AAC7C,UAAI,UAAU,+BAA+B,GAAG;AAChD,UAAI,UAAU,gCAAgC,eAAe;AAC7D,UAAI,UAAU,gCAAgC,cAAc;AAE5D,UAAI,IAAI,WAAW,WAAW;AAC5B,YAAI,UAAU,GAAG;AACjB,YAAI,IAAI;AACR;AAAA,MACF;AAEA,UAAI,IAAI,WAAW,UAAU,IAAI,QAAQ,QAAQ;AAC/C,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,YAAI,IAAI,KAAK,UAAU,EAAE,OAAO,YAAY,CAAC,CAAC;AAC9C;AAAA,MACF;AAEA,UAAI,OAAO;AACX,UAAI,GAAG,QAAQ,CAAC,UAAkB;AAChC,gBAAQ,MAAM,SAAS;AAAA,MACzB,CAAC;AAED,UAAI,GAAG,OAAO,MAAM;AAClB,cAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,gBAAQ,MAAM,EACX,KAAK,CAAC,aAAa;AAClB,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,QAAQ,CAAC;AAAA,QAClC,CAAC,EACA,MAAM,CAAC,UAAmB;AACzB,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAAA,QAC7D,CAAC;AAAA,MACL,CAAC;AAAA,IACH,CAAC;AAED,WAAO,GAAG,SAAS,MAAM;AAEzB,WAAO,OAAO,MAAM,MAAM;AACxB,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA,OAAO,MAAM,IAAI,QAAc,CAAC,cAAc,gBAAgB;AAC5D,iBAAO,MAAM,CAAC,QAAQ;AACpB,gBAAI,KAAK;AACP,0BAAY,GAAG;AAAA,YACjB,OAAO;AACL,2BAAa;AAAA,YACf;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json.schemastore.org/package.json",
|
|
3
|
+
"name": "@xyo-network/xl1-rpc-server",
|
|
4
|
+
"version": "1.25.27",
|
|
5
|
+
"description": "XYO Layer One RPC HTTP Server",
|
|
6
|
+
"homepage": "https://xylabs.com",
|
|
7
|
+
"bugs": {
|
|
8
|
+
"url": "git+https://github.com/xylabs/xyo-chain/issues",
|
|
9
|
+
"email": "support@xylabs.com"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/xylabs/xyo-chain.git"
|
|
14
|
+
},
|
|
15
|
+
"license": "LGPL-3.0-only",
|
|
16
|
+
"author": {
|
|
17
|
+
"name": "XY Labs Development Team",
|
|
18
|
+
"email": "support@xylabs.com",
|
|
19
|
+
"url": "https://xylabs.com"
|
|
20
|
+
},
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"type": "module",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/node/index.d.ts",
|
|
26
|
+
"source": "./src/index.ts",
|
|
27
|
+
"default": "./dist/node/index.mjs"
|
|
28
|
+
},
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"module": "./dist/node/index.mjs",
|
|
32
|
+
"source": "./src/index.ts",
|
|
33
|
+
"types": "./dist/node/index.d.ts",
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"src",
|
|
37
|
+
"!**/*.bench.*",
|
|
38
|
+
"!**/*.spec.*",
|
|
39
|
+
"!**/*.test.*"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "xy build-package",
|
|
43
|
+
"build-tests": "tsc --noEmit --lib dom,esnext",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:ci": "vitest run",
|
|
46
|
+
"types": "tsc --noEmit -p tsconfig.test.json"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@metamask/json-rpc-engine": "~10.2.3"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@metamask/utils": "~11.10.0",
|
|
53
|
+
"@types/node": "^25.5.0",
|
|
54
|
+
"@xylabs/ts-scripts-yarn3": "~7.4.25",
|
|
55
|
+
"@xylabs/tsconfig": "~7.4.25",
|
|
56
|
+
"typescript": "~5.9.3",
|
|
57
|
+
"vitest": "~4.1.1",
|
|
58
|
+
"zod": "~4.3.6"
|
|
59
|
+
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"@metamask/utils": "^11",
|
|
62
|
+
"zod": "^4"
|
|
63
|
+
},
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=22.3 <23"
|
|
66
|
+
},
|
|
67
|
+
"engineStrict": true,
|
|
68
|
+
"publishConfig": {
|
|
69
|
+
"access": "public"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import HTTP from 'node:http'
|
|
2
|
+
|
|
3
|
+
import type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2'
|
|
4
|
+
|
|
5
|
+
import { createRpcRequestHandler } from './createRpcRequestHandler.ts'
|
|
6
|
+
|
|
7
|
+
/** Result returned by createRpcHttpServer. */
|
|
8
|
+
export interface RpcHttpServer {
|
|
9
|
+
close: () => Promise<void>
|
|
10
|
+
port: number
|
|
11
|
+
server: HTTP.Server
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Creates a standalone Node.js HTTP server that handles JSON-RPC requests at POST /rpc. */
|
|
15
|
+
export function createRpcHttpServer(options: { engine: JsonRpcEngineV2; port: number }): Promise<RpcHttpServer> {
|
|
16
|
+
const { engine, port } = options
|
|
17
|
+
const handler = createRpcRequestHandler(engine)
|
|
18
|
+
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const server = HTTP.createServer((req, res) => {
|
|
21
|
+
res.setHeader('Access-Control-Allow-Origin', '*')
|
|
22
|
+
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS')
|
|
23
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
|
|
24
|
+
|
|
25
|
+
if (req.method === 'OPTIONS') {
|
|
26
|
+
res.writeHead(204)
|
|
27
|
+
res.end()
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (req.method !== 'POST' || req.url !== '/rpc') {
|
|
32
|
+
res.writeHead(404, { 'Content-Type': 'application/json' })
|
|
33
|
+
res.end(JSON.stringify({ error: 'Not found' }))
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let body = ''
|
|
38
|
+
req.on('data', (chunk: Buffer) => {
|
|
39
|
+
body += chunk.toString()
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
req.on('end', () => {
|
|
43
|
+
const parsed = JSON.parse(body)
|
|
44
|
+
handler(parsed)
|
|
45
|
+
.then((response) => {
|
|
46
|
+
res.writeHead(200, { 'Content-Type': 'application/json' })
|
|
47
|
+
res.end(JSON.stringify(response))
|
|
48
|
+
})
|
|
49
|
+
.catch((error: unknown) => {
|
|
50
|
+
res.writeHead(500, { 'Content-Type': 'application/json' })
|
|
51
|
+
res.end(JSON.stringify({ error: (error as Error).message }))
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
server.on('error', reject)
|
|
57
|
+
|
|
58
|
+
server.listen(port, () => {
|
|
59
|
+
resolve({
|
|
60
|
+
server,
|
|
61
|
+
port,
|
|
62
|
+
close: () => new Promise<void>((resolveClose, rejectClose) => {
|
|
63
|
+
server.close((err) => {
|
|
64
|
+
if (err) {
|
|
65
|
+
rejectClose(err)
|
|
66
|
+
} else {
|
|
67
|
+
resolveClose()
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
}),
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { JsonRpcEngineV2 } from '@metamask/json-rpc-engine/v2'
|
|
2
|
+
import type { JsonRpcRequest } from '@metamask/utils'
|
|
3
|
+
|
|
4
|
+
/** Creates a framework-agnostic RPC request handler from a JSON-RPC engine. */
|
|
5
|
+
export function createRpcRequestHandler(engine: JsonRpcEngineV2): (body: unknown) => Promise<unknown> {
|
|
6
|
+
return async (body: unknown) => {
|
|
7
|
+
const request = body as JsonRpcRequest
|
|
8
|
+
try {
|
|
9
|
+
const result = await engine.handle(request)
|
|
10
|
+
return {
|
|
11
|
+
jsonrpc: '2.0', id: request.id, result,
|
|
12
|
+
}
|
|
13
|
+
} catch (error) {
|
|
14
|
+
return {
|
|
15
|
+
jsonrpc: '2.0',
|
|
16
|
+
id: request.id,
|
|
17
|
+
error: { code: -32_603, message: (error as Error).message },
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/index.ts
ADDED