@lidofinance/next-pages 0.0.3

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/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # @lidofinance/next-pages
2
+
3
+ Common next pages.
4
+
5
+ ## Installation
6
+
7
+ `yarn add @lidofinance/next-pages`.
8
+
9
+ ## Getting started
10
+
11
+ ### health
12
+
13
+ ```ts
14
+ import { health } from '@lidofinance/next-pages';
15
+
16
+ export default health;
17
+ ```
18
+
19
+ ### metrics
20
+
21
+ ```ts
22
+ import { registry } from 'utilsApi/metrics';
23
+ import { metricsFactory } from '@lidofinance/next-pages';
24
+
25
+ const metrics = metricsFactory({
26
+ registry,
27
+ });
28
+
29
+ export default metrics;
30
+ ```
31
+
32
+ ### rpc
33
+
34
+ ```ts
35
+ import getConfig from 'next/config';
36
+ import { registry } from 'utilsApi/metrics';
37
+ import { rpcFactory } from '@lidofinance/api-pages';
38
+ import { METRICS_PREFIX } from '../../config';
39
+ import { fetchRPC, serverLogger } from 'utilsApi';
40
+
41
+ const { publicRuntimeConfig, serverRuntimeConfig } = getConfig();
42
+ const { defaultChain } = publicRuntimeConfig;
43
+ const { infuraApiKey, alchemyApiKey } = serverRuntimeConfig;
44
+
45
+ // Should be a separate file
46
+ export const enum CHAINS {
47
+ Mainnet = 1,
48
+ Goerli = 5,
49
+ }
50
+
51
+ // Should be a separate file
52
+ export const providers: Record<CHAINS, [string, ...string[]]> = {
53
+ [CHAINS.Mainnet]: [
54
+ `https://mainnet.infura.io/v3/${infuraApiKey}`,
55
+ `https://eth-mainnet.alchemyapi.io/v2/${alchemyApiKey}`,
56
+ ],
57
+ [CHAINS.Goerli]: [
58
+ `https://goerli.infura.io/v3/${infuraApiKey}`,
59
+ `https://eth-goerli.alchemyapi.io/v2/${alchemyApiKey}`,
60
+ ],
61
+ };
62
+
63
+ const rpc = rpcFactory({
64
+ fetchRPC,
65
+ serverLogger,
66
+ metrics: {
67
+ prefix: METRICS_PREFIX,
68
+ registry,
69
+ },
70
+ allowedRPCMethods: [
71
+ 'eth_call',
72
+ 'eth_gasPrice',
73
+ // ...
74
+ ],
75
+ defaultChain,
76
+ providers,
77
+ });
78
+
79
+ export default rpc;
80
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,118 @@
1
+ var $3HXpq$promclient = require("prom-client");
2
+ var $3HXpq$lidofinancerpc = require("@lidofinance/rpc");
3
+
4
+ function $parcel$exportWildcard(dest, source) {
5
+ Object.keys(source).forEach(function(key) {
6
+ if (key === 'default' || key === '__esModule' || dest.hasOwnProperty(key)) {
7
+ return;
8
+ }
9
+
10
+ Object.defineProperty(dest, key, {
11
+ enumerable: true,
12
+ get: function get() {
13
+ return source[key];
14
+ }
15
+ });
16
+ });
17
+
18
+ return dest;
19
+ }
20
+ function $parcel$export(e, n, v, s) {
21
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
22
+ }
23
+ var $c081037d441fc5cd$exports = {};
24
+
25
+ $parcel$export($c081037d441fc5cd$exports, "health", function () { return $c081037d441fc5cd$export$f0784a54fb0af903; });
26
+ const $c081037d441fc5cd$export$f0784a54fb0af903 = (_req, res)=>{
27
+ res.status(200).send({
28
+ status: "ok"
29
+ });
30
+ };
31
+
32
+
33
+ var $a46a7fda392c6f12$exports = {};
34
+
35
+ $parcel$export($a46a7fda392c6f12$exports, "metricsFactory", function () { return $a46a7fda392c6f12$export$fc20b1372f40c2c5; });
36
+ const $a46a7fda392c6f12$export$fc20b1372f40c2c5 = ({ registry: registry })=>async (_req, res)=>{
37
+ const collectedMetrics = await registry.metrics();
38
+ res.send(collectedMetrics);
39
+ };
40
+
41
+
42
+ var $f61917c2527290c5$exports = {};
43
+
44
+ $parcel$export($f61917c2527290c5$exports, "DEFAULT_API_ERROR_MESSAGE", function () { return $f61917c2527290c5$export$c982278a0ddc4dbe; });
45
+ $parcel$export($f61917c2527290c5$exports, "HEALTHY_RPC_SERVICES_ARE_OVER", function () { return $f61917c2527290c5$export$56a189db5508cdcb; });
46
+ $parcel$export($f61917c2527290c5$exports, "UnsupportedChainIdError", function () { return $f61917c2527290c5$export$fc97cac2ba066ec7; });
47
+ $parcel$export($f61917c2527290c5$exports, "UnsupportedHTTPMethodError", function () { return $f61917c2527290c5$export$2dfa2d8949b43fdc; });
48
+ $parcel$export($f61917c2527290c5$exports, "rpcFactory", function () { return $f61917c2527290c5$export$9bfcc39f106ad871; });
49
+
50
+
51
+ const $f61917c2527290c5$export$c982278a0ddc4dbe = "Something went wrong. Sorry, try again later :(";
52
+ const $f61917c2527290c5$export$56a189db5508cdcb = "Healthy RPC services are over!";
53
+ class $f61917c2527290c5$export$fc97cac2ba066ec7 extends Error {
54
+ constructor(message){
55
+ super(message || "Unsupported chainId");
56
+ }
57
+ }
58
+ class $f61917c2527290c5$export$2dfa2d8949b43fdc extends Error {
59
+ constructor(message){
60
+ super(message || "Unsupported HTTP method");
61
+ }
62
+ }
63
+ const $f61917c2527290c5$export$9bfcc39f106ad871 = ({ metrics: { prefix: prefix , registry: registry } , providers: providers , fetchRPC: fetchRPC , serverLogger: serverLogger , defaultChain: defaultChain , allowedRPCMethods: allowedRPCMethods })=>{
64
+ const rpcRequestBlocked = new (0, $3HXpq$promclient.Counter)({
65
+ name: prefix + "rpc_service_request_blocked",
66
+ help: "RPC service request blocked",
67
+ labelNames: [],
68
+ registers: []
69
+ });
70
+ registry.registerMetric(rpcRequestBlocked);
71
+ return async (req, res)=>{
72
+ try {
73
+ // Accept only POST requests
74
+ if (req.method !== "POST") // We don't care about tracking blocked requests here
75
+ throw new $f61917c2527290c5$export$2dfa2d8949b43fdc();
76
+ const chainId = Number(req.query.chainId || defaultChain);
77
+ // Allow only chainId of specified chains
78
+ if (providers[chainId] == null) // We don't care about tracking blocked requests here
79
+ throw new $f61917c2527290c5$export$fc97cac2ba066ec7();
80
+ // TODO: consider returning array of validators instead of throwing error right away
81
+ // Check if provided methods are allowed
82
+ for (const { method: method } of Array.isArray(req.body) ? req.body : [
83
+ req.body
84
+ ]){
85
+ if (typeof method !== "string") throw new Error(`RPC method isn't string`);
86
+ if (!allowedRPCMethods.includes(method)) {
87
+ rpcRequestBlocked.inc();
88
+ throw new Error(`RPC method ${method} isn't allowed`);
89
+ }
90
+ }
91
+ const requested = await (0, $3HXpq$lidofinancerpc.iterateUrls)(providers[chainId], // TODO: consider adding verification that body is actually matches FetchRpcInitBody
92
+ (url)=>fetchRPC(url, {
93
+ body: req.body
94
+ }, {
95
+ chainId: chainId
96
+ }), serverLogger.error);
97
+ var ref;
98
+ res.setHeader("Content-Type", (ref = requested.headers.get("Content-Type")) !== null && ref !== void 0 ? ref : "application/json");
99
+ res.status(requested.status).send(requested.body);
100
+ } catch (error) {
101
+ if (error instanceof Error) {
102
+ var _message;
103
+ // TODO: check if there are errors duplication with iterateUrls
104
+ serverLogger.error((_message = error.message) !== null && _message !== void 0 ? _message : $f61917c2527290c5$export$c982278a0ddc4dbe);
105
+ var _message1;
106
+ res.status(500).json((_message1 = error.message) !== null && _message1 !== void 0 ? _message1 : $f61917c2527290c5$export$c982278a0ddc4dbe);
107
+ } else res.status(500).json($f61917c2527290c5$export$56a189db5508cdcb);
108
+ }
109
+ };
110
+ };
111
+
112
+
113
+ $parcel$exportWildcard(module.exports, $c081037d441fc5cd$exports);
114
+ $parcel$exportWildcard(module.exports, $a46a7fda392c6f12$exports);
115
+ $parcel$exportWildcard(module.exports, $f61917c2527290c5$exports);
116
+
117
+
118
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["packages/next/pages/src/index.ts","packages/next/pages/src/health.ts","packages/next/pages/src/metricsFactory.ts","packages/next/pages/src/rpcFactory.ts"],"sourcesContent":["export * from './health'\nexport * from './metricsFactory'\nexport * from './rpcFactory'\n","import { NextApiRequest, NextApiResponse } from 'next'\n\nexport const health = (_req: NextApiRequest, res: NextApiResponse): void => {\n res.status(200).send({ status: 'ok' })\n}\n","import { NextApiRequest, NextApiResponse } from 'next'\nimport { Registry } from 'prom-client'\n\nexport type MetricsFactoryParameters = {\n registry: Registry\n}\n\nexport const metricsFactory =\n ({ registry }: MetricsFactoryParameters) =>\n async (_req: NextApiRequest, res: NextApiResponse) => {\n const collectedMetrics = await registry.metrics()\n res.send(collectedMetrics)\n }\n","import type { NextApiRequest, NextApiResponse } from 'next'\nimport { Counter, Registry } from 'prom-client'\nimport { TrackedFetchRPC } from '@lidofinance/api-rpc'\nimport { ServerLogger } from '@lidofinance/api-logger'\nimport { FetchRpcInitBody, iterateUrls } from '@lidofinance/rpc'\n\nexport type RpcProviders = Record<string | number, [string, ...string[]]>\n\nexport const DEFAULT_API_ERROR_MESSAGE = 'Something went wrong. Sorry, try again later :('\n\nexport const HEALTHY_RPC_SERVICES_ARE_OVER = 'Healthy RPC services are over!'\n\nexport class UnsupportedChainIdError extends Error {\n constructor(message?: string) {\n super(message || 'Unsupported chainId')\n }\n}\n\nexport class UnsupportedHTTPMethodError extends Error {\n constructor(message?: string) {\n super(message || 'Unsupported HTTP method')\n }\n}\n\nexport type RPCFactoryParams = {\n metrics: {\n prefix: string\n registry: Registry\n }\n providers: RpcProviders\n fetchRPC: TrackedFetchRPC\n serverLogger: ServerLogger\n defaultChain: string | number\n // If we don't specify allowed RPC methods, then we can't use\n // fetchRPC with prometheus, otherwise it will blow up, if someone will send arbitrary\n // methods\n allowedRPCMethods: string[]\n}\n\nexport const rpcFactory = ({\n metrics: { prefix, registry },\n providers,\n fetchRPC,\n serverLogger,\n defaultChain,\n allowedRPCMethods,\n}: RPCFactoryParams) => {\n const rpcRequestBlocked = new Counter({\n name: prefix + 'rpc_service_request_blocked',\n help: 'RPC service request blocked',\n labelNames: [],\n registers: [],\n })\n registry.registerMetric(rpcRequestBlocked)\n\n return async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {\n try {\n // Accept only POST requests\n if (req.method !== 'POST') {\n // We don't care about tracking blocked requests here\n throw new UnsupportedHTTPMethodError()\n }\n\n const chainId = Number(req.query.chainId || defaultChain)\n\n // Allow only chainId of specified chains\n if (providers[chainId] == null) {\n // We don't care about tracking blocked requests here\n throw new UnsupportedChainIdError()\n }\n\n // TODO: consider returning array of validators instead of throwing error right away\n // Check if provided methods are allowed\n for (const { method } of Array.isArray(req.body) ? req.body : [req.body]) {\n if (typeof method !== 'string') {\n throw new Error(`RPC method isn't string`)\n }\n if (!allowedRPCMethods.includes(method)) {\n rpcRequestBlocked.inc()\n throw new Error(`RPC method ${method} isn't allowed`)\n }\n }\n\n const requested = await iterateUrls(\n providers[chainId],\n // TODO: consider adding verification that body is actually matches FetchRpcInitBody\n (url) => fetchRPC(url, { body: req.body as FetchRpcInitBody }, { chainId }),\n serverLogger.error,\n )\n\n res.setHeader('Content-Type', requested.headers.get('Content-Type') ?? 'application/json')\n res.status(requested.status).send(requested.body)\n } catch (error) {\n if (error instanceof Error) {\n // TODO: check if there are errors duplication with iterateUrls\n serverLogger.error(error.message ?? DEFAULT_API_ERROR_MESSAGE)\n res.status(500).json(error.message ?? DEFAULT_API_ERROR_MESSAGE)\n } else {\n res.status(500).json(HEALTHY_RPC_SERVICES_ARE_OVER)\n }\n }\n }\n}\n"],"names":[],"version":3,"file":"index.cjs.map"}
@@ -0,0 +1,32 @@
1
+ import { NextApiRequest, NextApiResponse } from "next";
2
+ import { Registry } from "prom-client";
3
+ import { TrackedFetchRPC } from "@lidofinance/api-rpc";
4
+ import { ServerLogger } from "@lidofinance/api-logger";
5
+ export const health: (_req: NextApiRequest, res: NextApiResponse) => void;
6
+ export type MetricsFactoryParameters = {
7
+ registry: Registry;
8
+ };
9
+ export const metricsFactory: ({ registry }: MetricsFactoryParameters) => (_req: NextApiRequest, res: NextApiResponse) => Promise<void>;
10
+ export type RpcProviders = Record<string | number, [string, ...string[]]>;
11
+ export const DEFAULT_API_ERROR_MESSAGE = "Something went wrong. Sorry, try again later :(";
12
+ export const HEALTHY_RPC_SERVICES_ARE_OVER = "Healthy RPC services are over!";
13
+ export class UnsupportedChainIdError extends Error {
14
+ constructor(message?: string);
15
+ }
16
+ export class UnsupportedHTTPMethodError extends Error {
17
+ constructor(message?: string);
18
+ }
19
+ export type RPCFactoryParams = {
20
+ metrics: {
21
+ prefix: string;
22
+ registry: Registry;
23
+ };
24
+ providers: RpcProviders;
25
+ fetchRPC: TrackedFetchRPC;
26
+ serverLogger: ServerLogger;
27
+ defaultChain: string | number;
28
+ allowedRPCMethods: string[];
29
+ };
30
+ export const rpcFactory: ({ metrics: { prefix, registry }, providers, fetchRPC, serverLogger, defaultChain, allowedRPCMethods, }: RPCFactoryParams) => (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
31
+
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"mappings":";;;;AAEA,OAAO,MAAM,eAAgB,cAAc,OAAO,eAAe,KAAG,IAEnE,CAAA;ACDD,uCAAuC;IACrC,QAAQ,EAAE,QAAQ,CAAA;CACnB,CAAA;AAED,OAAO,MAAM,+BACI,wBAAwB,YAC1B,cAAc,OAAO,eAAe,kBAGhD,CAAA;ACNH,2BAA2B,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAA;AAEzE,OAAO,MAAM,6EAA6E,CAAA;AAE1F,OAAO,MAAM,gEAAgE,CAAA;AAE7E,oCAAqC,SAAQ,KAAK;gBACpC,OAAO,CAAC,EAAE,MAAM;CAG7B;AAED,uCAAwC,SAAQ,KAAK;gBACvC,OAAO,CAAC,EAAE,MAAM;CAG7B;AAED,+BAA+B;IAC7B,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,QAAQ,CAAA;KACnB,CAAA;IACD,SAAS,EAAE,YAAY,CAAA;IACvB,QAAQ,EAAE,eAAe,CAAA;IACzB,YAAY,EAAE,YAAY,CAAA;IAC1B,YAAY,EAAE,MAAM,GAAG,MAAM,CAAA;IAI7B,iBAAiB,EAAE,MAAM,EAAE,CAAA;CAC5B,CAAA;AAED,OAAO,MAAM,qHAOV,gBAAgB,WASE,cAAc,OAAO,eAAe,KAAG,QAAQ,IAAI,CA+CvE,CAAA","sources":["packages/next/pages/src/src/health.ts","packages/next/pages/src/src/metricsFactory.ts","packages/next/pages/src/src/rpcFactory.ts","packages/next/pages/src/src/index.ts","packages/next/pages/src/index.ts"],"sourcesContent":[null,null,null,null,"export * from './health'\nexport * from './metricsFactory'\nexport * from './rpcFactory'\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/dist/index.mjs ADDED
@@ -0,0 +1,100 @@
1
+ import {Counter as $bPUfb$Counter} from "prom-client";
2
+ import {iterateUrls as $bPUfb$iterateUrls} from "@lidofinance/rpc";
3
+
4
+ function $parcel$export(e, n, v, s) {
5
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
6
+ }
7
+ var $bb51b4a554c62d89$exports = {};
8
+
9
+ $parcel$export($bb51b4a554c62d89$exports, "health", function () { return $bb51b4a554c62d89$export$f0784a54fb0af903; });
10
+ const $bb51b4a554c62d89$export$f0784a54fb0af903 = (_req, res)=>{
11
+ res.status(200).send({
12
+ status: "ok"
13
+ });
14
+ };
15
+
16
+
17
+ var $4241956749180479$exports = {};
18
+
19
+ $parcel$export($4241956749180479$exports, "metricsFactory", function () { return $4241956749180479$export$fc20b1372f40c2c5; });
20
+ const $4241956749180479$export$fc20b1372f40c2c5 = ({ registry: registry })=>async (_req, res)=>{
21
+ const collectedMetrics = await registry.metrics();
22
+ res.send(collectedMetrics);
23
+ };
24
+
25
+
26
+ var $2f7bb06869d30d12$exports = {};
27
+
28
+ $parcel$export($2f7bb06869d30d12$exports, "DEFAULT_API_ERROR_MESSAGE", function () { return $2f7bb06869d30d12$export$c982278a0ddc4dbe; });
29
+ $parcel$export($2f7bb06869d30d12$exports, "HEALTHY_RPC_SERVICES_ARE_OVER", function () { return $2f7bb06869d30d12$export$56a189db5508cdcb; });
30
+ $parcel$export($2f7bb06869d30d12$exports, "UnsupportedChainIdError", function () { return $2f7bb06869d30d12$export$fc97cac2ba066ec7; });
31
+ $parcel$export($2f7bb06869d30d12$exports, "UnsupportedHTTPMethodError", function () { return $2f7bb06869d30d12$export$2dfa2d8949b43fdc; });
32
+ $parcel$export($2f7bb06869d30d12$exports, "rpcFactory", function () { return $2f7bb06869d30d12$export$9bfcc39f106ad871; });
33
+
34
+
35
+ const $2f7bb06869d30d12$export$c982278a0ddc4dbe = "Something went wrong. Sorry, try again later :(";
36
+ const $2f7bb06869d30d12$export$56a189db5508cdcb = "Healthy RPC services are over!";
37
+ class $2f7bb06869d30d12$export$fc97cac2ba066ec7 extends Error {
38
+ constructor(message){
39
+ super(message || "Unsupported chainId");
40
+ }
41
+ }
42
+ class $2f7bb06869d30d12$export$2dfa2d8949b43fdc extends Error {
43
+ constructor(message){
44
+ super(message || "Unsupported HTTP method");
45
+ }
46
+ }
47
+ const $2f7bb06869d30d12$export$9bfcc39f106ad871 = ({ metrics: { prefix: prefix , registry: registry } , providers: providers , fetchRPC: fetchRPC , serverLogger: serverLogger , defaultChain: defaultChain , allowedRPCMethods: allowedRPCMethods })=>{
48
+ const rpcRequestBlocked = new (0, $bPUfb$Counter)({
49
+ name: prefix + "rpc_service_request_blocked",
50
+ help: "RPC service request blocked",
51
+ labelNames: [],
52
+ registers: []
53
+ });
54
+ registry.registerMetric(rpcRequestBlocked);
55
+ return async (req, res)=>{
56
+ try {
57
+ // Accept only POST requests
58
+ if (req.method !== "POST") // We don't care about tracking blocked requests here
59
+ throw new $2f7bb06869d30d12$export$2dfa2d8949b43fdc();
60
+ const chainId = Number(req.query.chainId || defaultChain);
61
+ // Allow only chainId of specified chains
62
+ if (providers[chainId] == null) // We don't care about tracking blocked requests here
63
+ throw new $2f7bb06869d30d12$export$fc97cac2ba066ec7();
64
+ // TODO: consider returning array of validators instead of throwing error right away
65
+ // Check if provided methods are allowed
66
+ for (const { method: method } of Array.isArray(req.body) ? req.body : [
67
+ req.body
68
+ ]){
69
+ if (typeof method !== "string") throw new Error(`RPC method isn't string`);
70
+ if (!allowedRPCMethods.includes(method)) {
71
+ rpcRequestBlocked.inc();
72
+ throw new Error(`RPC method ${method} isn't allowed`);
73
+ }
74
+ }
75
+ const requested = await (0, $bPUfb$iterateUrls)(providers[chainId], // TODO: consider adding verification that body is actually matches FetchRpcInitBody
76
+ (url)=>fetchRPC(url, {
77
+ body: req.body
78
+ }, {
79
+ chainId: chainId
80
+ }), serverLogger.error);
81
+ var ref;
82
+ res.setHeader("Content-Type", (ref = requested.headers.get("Content-Type")) !== null && ref !== void 0 ? ref : "application/json");
83
+ res.status(requested.status).send(requested.body);
84
+ } catch (error) {
85
+ if (error instanceof Error) {
86
+ var _message;
87
+ // TODO: check if there are errors duplication with iterateUrls
88
+ serverLogger.error((_message = error.message) !== null && _message !== void 0 ? _message : $2f7bb06869d30d12$export$c982278a0ddc4dbe);
89
+ var _message1;
90
+ res.status(500).json((_message1 = error.message) !== null && _message1 !== void 0 ? _message1 : $2f7bb06869d30d12$export$c982278a0ddc4dbe);
91
+ } else res.status(500).json($2f7bb06869d30d12$export$56a189db5508cdcb);
92
+ }
93
+ };
94
+ };
95
+
96
+
97
+
98
+
99
+ export {$bb51b4a554c62d89$export$f0784a54fb0af903 as health, $4241956749180479$export$fc20b1372f40c2c5 as metricsFactory, $2f7bb06869d30d12$export$c982278a0ddc4dbe as DEFAULT_API_ERROR_MESSAGE, $2f7bb06869d30d12$export$56a189db5508cdcb as HEALTHY_RPC_SERVICES_ARE_OVER, $2f7bb06869d30d12$export$fc97cac2ba066ec7 as UnsupportedChainIdError, $2f7bb06869d30d12$export$2dfa2d8949b43fdc as UnsupportedHTTPMethodError, $2f7bb06869d30d12$export$9bfcc39f106ad871 as rpcFactory};
100
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["packages/next/pages/src/index.ts","packages/next/pages/src/health.ts","packages/next/pages/src/metricsFactory.ts","packages/next/pages/src/rpcFactory.ts"],"sourcesContent":["export * from './health'\nexport * from './metricsFactory'\nexport * from './rpcFactory'\n","import { NextApiRequest, NextApiResponse } from 'next'\n\nexport const health = (_req: NextApiRequest, res: NextApiResponse): void => {\n res.status(200).send({ status: 'ok' })\n}\n","import { NextApiRequest, NextApiResponse } from 'next'\nimport { Registry } from 'prom-client'\n\nexport type MetricsFactoryParameters = {\n registry: Registry\n}\n\nexport const metricsFactory =\n ({ registry }: MetricsFactoryParameters) =>\n async (_req: NextApiRequest, res: NextApiResponse) => {\n const collectedMetrics = await registry.metrics()\n res.send(collectedMetrics)\n }\n","import type { NextApiRequest, NextApiResponse } from 'next'\nimport { Counter, Registry } from 'prom-client'\nimport { TrackedFetchRPC } from '@lidofinance/api-rpc'\nimport { ServerLogger } from '@lidofinance/api-logger'\nimport { FetchRpcInitBody, iterateUrls } from '@lidofinance/rpc'\n\nexport type RpcProviders = Record<string | number, [string, ...string[]]>\n\nexport const DEFAULT_API_ERROR_MESSAGE = 'Something went wrong. Sorry, try again later :('\n\nexport const HEALTHY_RPC_SERVICES_ARE_OVER = 'Healthy RPC services are over!'\n\nexport class UnsupportedChainIdError extends Error {\n constructor(message?: string) {\n super(message || 'Unsupported chainId')\n }\n}\n\nexport class UnsupportedHTTPMethodError extends Error {\n constructor(message?: string) {\n super(message || 'Unsupported HTTP method')\n }\n}\n\nexport type RPCFactoryParams = {\n metrics: {\n prefix: string\n registry: Registry\n }\n providers: RpcProviders\n fetchRPC: TrackedFetchRPC\n serverLogger: ServerLogger\n defaultChain: string | number\n // If we don't specify allowed RPC methods, then we can't use\n // fetchRPC with prometheus, otherwise it will blow up, if someone will send arbitrary\n // methods\n allowedRPCMethods: string[]\n}\n\nexport const rpcFactory = ({\n metrics: { prefix, registry },\n providers,\n fetchRPC,\n serverLogger,\n defaultChain,\n allowedRPCMethods,\n}: RPCFactoryParams) => {\n const rpcRequestBlocked = new Counter({\n name: prefix + 'rpc_service_request_blocked',\n help: 'RPC service request blocked',\n labelNames: [],\n registers: [],\n })\n registry.registerMetric(rpcRequestBlocked)\n\n return async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {\n try {\n // Accept only POST requests\n if (req.method !== 'POST') {\n // We don't care about tracking blocked requests here\n throw new UnsupportedHTTPMethodError()\n }\n\n const chainId = Number(req.query.chainId || defaultChain)\n\n // Allow only chainId of specified chains\n if (providers[chainId] == null) {\n // We don't care about tracking blocked requests here\n throw new UnsupportedChainIdError()\n }\n\n // TODO: consider returning array of validators instead of throwing error right away\n // Check if provided methods are allowed\n for (const { method } of Array.isArray(req.body) ? req.body : [req.body]) {\n if (typeof method !== 'string') {\n throw new Error(`RPC method isn't string`)\n }\n if (!allowedRPCMethods.includes(method)) {\n rpcRequestBlocked.inc()\n throw new Error(`RPC method ${method} isn't allowed`)\n }\n }\n\n const requested = await iterateUrls(\n providers[chainId],\n // TODO: consider adding verification that body is actually matches FetchRpcInitBody\n (url) => fetchRPC(url, { body: req.body as FetchRpcInitBody }, { chainId }),\n serverLogger.error,\n )\n\n res.setHeader('Content-Type', requested.headers.get('Content-Type') ?? 'application/json')\n res.status(requested.status).send(requested.body)\n } catch (error) {\n if (error instanceof Error) {\n // TODO: check if there are errors duplication with iterateUrls\n serverLogger.error(error.message ?? DEFAULT_API_ERROR_MESSAGE)\n res.status(500).json(error.message ?? DEFAULT_API_ERROR_MESSAGE)\n } else {\n res.status(500).json(HEALTHY_RPC_SERVICES_ARE_OVER)\n }\n }\n }\n}\n"],"names":[],"version":3,"file":"index.mjs.map"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@lidofinance/next-pages",
3
+ "description": "Common next pages",
4
+ "repository": "git@github.com:lidofinance/lido-ui-blocks.git",
5
+ "license": "MIT",
6
+ "version": "0.0.3",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "engines": {
11
+ "node": ">= 16",
12
+ "browsers": "> 0.5%, last 2 versions, not dead"
13
+ },
14
+ "source": "./src/index.ts",
15
+ "main": "dist/index.cjs",
16
+ "module": "dist/index.mjs",
17
+ "types": "dist/index.d.ts",
18
+ "scripts": {
19
+ "build": "parcel build",
20
+ "format": "prettier --check src",
21
+ "format:fix": "yarn format --write",
22
+ "types": "tsc --noEmit"
23
+ },
24
+ "peerDependencies": {
25
+ "@lidofinance/api-logger": "0.0.3",
26
+ "@lidofinance/api-rpc": "0.0.3",
27
+ "@lidofinance/rpc": "0.0.3",
28
+ "next": "^12.2.0",
29
+ "prom-client": "^14.0.0"
30
+ },
31
+ "devDependencies": {
32
+ "@lidofinance/config-prettier": "0.0.1",
33
+ "next": "^12.2.0",
34
+ "prom-client": "^14.0.0"
35
+ }
36
+ }