@lidofinance/next-pages 0.21.0 → 0.22.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.
package/README.md CHANGED
@@ -1,26 +1,40 @@
1
1
  # @lidofinance/next-pages
2
2
 
3
- Common next pages.
3
+ Common API and UI next pages.
4
4
 
5
5
  ## Installation
6
6
 
7
- `yarn add @lidofinance/next-pages`.
7
+ ```bash
8
+ yarn add @lidofinance/next-pages
9
+
10
+ # and react 17
11
+ yarn add react@^17.0.0
12
+ # or react 18
13
+ yarn add react@^18.0.0
14
+
15
+ # and additional
16
+ yarn add next@^12.3.0 prom-client@^14.0.0 @lidofinance/lido-ui@^3.6.1
17
+ ```
8
18
 
9
19
  ## Getting started
10
20
 
11
- ### health
21
+ ### API pages
22
+
23
+ #### Health
12
24
 
13
25
  ```ts
14
26
  import { health } from '@lidofinance/next-pages';
27
+ // or import { health } from '@lidofinance/next-pages/api';
15
28
 
16
29
  export default health;
17
30
  ```
18
31
 
19
- ### metrics
32
+ #### Metrics
20
33
 
21
34
  ```ts
22
35
  import { registry } from 'utilsApi/metrics';
23
36
  import { metricsFactory } from '@lidofinance/next-pages';
37
+ // or import { metricsFactory } from '@lidofinance/next-pages/api';
24
38
 
25
39
  const metrics = metricsFactory({
26
40
  registry,
@@ -29,14 +43,15 @@ const metrics = metricsFactory({
29
43
  export default metrics;
30
44
  ```
31
45
 
32
- ### rpc
46
+ #### RPC
33
47
 
34
48
  ```ts
35
49
  import getConfig from 'next/config';
36
- import { registry } from 'utilsApi/metrics';
37
50
  import { rpcFactory } from '@lidofinance/api-pages';
38
- import { METRICS_PREFIX } from '../../config';
51
+ // or import { rpcFactory } from '@lidofinance/next-pages/api';
39
52
  import { fetchRPC, serverLogger } from 'utilsApi';
53
+ import { registry } from 'utilsApi/metrics';
54
+ import { METRICS_PREFIX } from '../../config';
40
55
 
41
56
  const { publicRuntimeConfig, serverRuntimeConfig } = getConfig();
42
57
  const { defaultChain } = publicRuntimeConfig;
@@ -77,4 +92,38 @@ const rpc = rpcFactory({
77
92
  });
78
93
 
79
94
  export default rpc;
80
- ```
95
+ ```
96
+
97
+ ### UI pages
98
+
99
+ #### Page Error (ready implementations)
100
+
101
+ - **Page404**
102
+ - **Page500**
103
+
104
+ Example for `pages/404.tsx`
105
+ ```tsx
106
+ import { Page404 } from '@lidofinance/next-ui-pages/ui';
107
+
108
+ export default Page404;
109
+ ```
110
+
111
+ Example for `pages/500.tsx`
112
+ ```tsx
113
+ import { Page500 } from '@lidofinance/next-ui-pages/ui';
114
+
115
+ export default Page500;
116
+ ```
117
+
118
+ #### Error page as generic component
119
+
120
+ Example for `pages/404.tsx`
121
+
122
+ ```tsx
123
+ import { FC } from 'react';
124
+ import { PageError } from '@lidofinance/next-ui-pages/ui';
125
+
126
+ const Page404: FC = () => <PageError title="404" content="Page Not Found" />;
127
+
128
+ export default Page404;
129
+ ```
@@ -0,0 +1,3 @@
1
+ import { NextApiRequest, NextApiResponse } from 'next';
2
+ export declare const health: (_req: NextApiRequest, res: NextApiResponse) => void;
3
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/api/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,MAAM,CAAA;AAEtD,eAAO,MAAM,MAAM,SAAU,cAAc,OAAO,eAAe,KAAG,IAEnE,CAAA"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.health = void 0;
4
+ const health = (_req, res) => {
5
+ res.status(200).send({ status: 'ok' });
6
+ };
7
+ exports.health = health;
@@ -0,0 +1,4 @@
1
+ export { health } from './health';
2
+ export { type MetricsFactoryParameters, metricsFactory } from './metricsFactory';
3
+ export { type RpcProviders, DEFAULT_API_ERROR_MESSAGE, HEALTHY_RPC_SERVICES_ARE_OVER, UnsupportedChainIdError, UnsupportedHTTPMethodError, type RPCFactoryParams, rpcFactory, } from './rpcFactory';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,KAAK,wBAAwB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAChF,OAAO,EACL,KAAK,YAAY,EACjB,yBAAyB,EACzB,6BAA6B,EAC7B,uBAAuB,EACvB,0BAA0B,EAC1B,KAAK,gBAAgB,EACrB,UAAU,GACX,MAAM,cAAc,CAAA"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rpcFactory = exports.UnsupportedHTTPMethodError = exports.UnsupportedChainIdError = exports.HEALTHY_RPC_SERVICES_ARE_OVER = exports.DEFAULT_API_ERROR_MESSAGE = exports.metricsFactory = exports.health = void 0;
4
+ var health_1 = require("./health");
5
+ Object.defineProperty(exports, "health", { enumerable: true, get: function () { return health_1.health; } });
6
+ var metricsFactory_1 = require("./metricsFactory");
7
+ Object.defineProperty(exports, "metricsFactory", { enumerable: true, get: function () { return metricsFactory_1.metricsFactory; } });
8
+ var rpcFactory_1 = require("./rpcFactory");
9
+ Object.defineProperty(exports, "DEFAULT_API_ERROR_MESSAGE", { enumerable: true, get: function () { return rpcFactory_1.DEFAULT_API_ERROR_MESSAGE; } });
10
+ Object.defineProperty(exports, "HEALTHY_RPC_SERVICES_ARE_OVER", { enumerable: true, get: function () { return rpcFactory_1.HEALTHY_RPC_SERVICES_ARE_OVER; } });
11
+ Object.defineProperty(exports, "UnsupportedChainIdError", { enumerable: true, get: function () { return rpcFactory_1.UnsupportedChainIdError; } });
12
+ Object.defineProperty(exports, "UnsupportedHTTPMethodError", { enumerable: true, get: function () { return rpcFactory_1.UnsupportedHTTPMethodError; } });
13
+ Object.defineProperty(exports, "rpcFactory", { enumerable: true, get: function () { return rpcFactory_1.rpcFactory; } });
@@ -0,0 +1,7 @@
1
+ import { NextApiRequest, NextApiResponse } from 'next';
2
+ import { Registry } from 'prom-client';
3
+ export type MetricsFactoryParameters = {
4
+ registry: Registry;
5
+ };
6
+ export declare const metricsFactory: ({ registry }: MetricsFactoryParameters) => (_req: NextApiRequest, res: NextApiResponse) => Promise<void>;
7
+ //# sourceMappingURL=metricsFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metricsFactory.d.ts","sourceRoot":"","sources":["../../src/api/metricsFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,MAAM,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE,QAAQ,CAAA;CACnB,CAAA;AAED,eAAO,MAAM,cAAc,iBACV,wBAAwB,YAC1B,cAAc,OAAO,eAAe,kBAGhD,CAAA"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.metricsFactory = void 0;
4
+ const metricsFactory = ({ registry }) => async (_req, res) => {
5
+ const collectedMetrics = await registry.metrics();
6
+ res.send(collectedMetrics);
7
+ };
8
+ exports.metricsFactory = metricsFactory;
@@ -0,0 +1,26 @@
1
+ import type { 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 type RpcProviders = Record<string | number, [string, ...string[]]>;
6
+ export declare const DEFAULT_API_ERROR_MESSAGE = "Something went wrong. Sorry, try again later :(";
7
+ export declare const HEALTHY_RPC_SERVICES_ARE_OVER = "Healthy RPC services are over!";
8
+ export declare class UnsupportedChainIdError extends Error {
9
+ constructor(message?: string);
10
+ }
11
+ export declare class UnsupportedHTTPMethodError extends Error {
12
+ constructor(message?: string);
13
+ }
14
+ export type RPCFactoryParams = {
15
+ metrics: {
16
+ prefix: string;
17
+ registry: Registry;
18
+ };
19
+ providers: RpcProviders;
20
+ fetchRPC: TrackedFetchRPC;
21
+ serverLogger: ServerLogger;
22
+ defaultChain: string | number;
23
+ allowedRPCMethods: string[];
24
+ };
25
+ export declare const rpcFactory: ({ metrics: { prefix, registry }, providers, fetchRPC, serverLogger, defaultChain, allowedRPCMethods, }: RPCFactoryParams) => (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
26
+ //# sourceMappingURL=rpcFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpcFactory.d.ts","sourceRoot":"","sources":["../../src/api/rpcFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,MAAM,CAAA;AAC3D,OAAO,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAGtD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAA;AAEzE,eAAO,MAAM,yBAAyB,oDAAoD,CAAA;AAE1F,eAAO,MAAM,6BAA6B,mCAAmC,CAAA;AAE7E,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,CAAC,EAAE,MAAM;CAG7B;AAED,qBAAa,0BAA2B,SAAQ,KAAK;gBACvC,OAAO,CAAC,EAAE,MAAM;CAG7B;AAED,MAAM,MAAM,gBAAgB,GAAG;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,eAAO,MAAM,UAAU,2GAOpB,gBAAgB,WASE,cAAc,OAAO,eAAe,KAAG,QAAQ,IAAI,CA+CvE,CAAA"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rpcFactory = exports.UnsupportedHTTPMethodError = exports.UnsupportedChainIdError = exports.HEALTHY_RPC_SERVICES_ARE_OVER = exports.DEFAULT_API_ERROR_MESSAGE = void 0;
4
+ const prom_client_1 = require("prom-client");
5
+ const rpc_1 = require("@lidofinance/rpc");
6
+ exports.DEFAULT_API_ERROR_MESSAGE = 'Something went wrong. Sorry, try again later :(';
7
+ exports.HEALTHY_RPC_SERVICES_ARE_OVER = 'Healthy RPC services are over!';
8
+ class UnsupportedChainIdError extends Error {
9
+ constructor(message) {
10
+ super(message || 'Unsupported chainId');
11
+ }
12
+ }
13
+ exports.UnsupportedChainIdError = UnsupportedChainIdError;
14
+ class UnsupportedHTTPMethodError extends Error {
15
+ constructor(message) {
16
+ super(message || 'Unsupported HTTP method');
17
+ }
18
+ }
19
+ exports.UnsupportedHTTPMethodError = UnsupportedHTTPMethodError;
20
+ const rpcFactory = ({ metrics: { prefix, registry }, providers, fetchRPC, serverLogger, defaultChain, allowedRPCMethods, }) => {
21
+ const rpcRequestBlocked = new prom_client_1.Counter({
22
+ name: prefix + 'rpc_service_request_blocked',
23
+ help: 'RPC service request blocked',
24
+ labelNames: [],
25
+ registers: [],
26
+ });
27
+ registry.registerMetric(rpcRequestBlocked);
28
+ return async (req, res) => {
29
+ try {
30
+ // Accept only POST requests
31
+ if (req.method !== 'POST') {
32
+ // We don't care about tracking blocked requests here
33
+ throw new UnsupportedHTTPMethodError();
34
+ }
35
+ const chainId = Number(req.query.chainId || defaultChain);
36
+ // Allow only chainId of specified chains
37
+ if (providers[chainId] == null) {
38
+ // We don't care about tracking blocked requests here
39
+ throw new UnsupportedChainIdError();
40
+ }
41
+ // TODO: consider returning array of validators instead of throwing error right away
42
+ // Check if provided methods are allowed
43
+ for (const { method } of Array.isArray(req.body) ? req.body : [req.body]) {
44
+ if (typeof method !== 'string') {
45
+ throw new Error(`RPC method isn't string`);
46
+ }
47
+ if (!allowedRPCMethods.includes(method)) {
48
+ rpcRequestBlocked.inc();
49
+ throw new Error(`RPC method ${method} isn't allowed`);
50
+ }
51
+ }
52
+ const requested = await (0, rpc_1.iterateUrls)(providers[chainId],
53
+ // TODO: consider adding verification that body is actually matches FetchRpcInitBody
54
+ (url) => fetchRPC(url, { body: req.body }, { chainId }), serverLogger.error);
55
+ res.setHeader('Content-Type', requested.headers.get('Content-Type') ?? 'application/json');
56
+ res.status(requested.status).send(requested.body);
57
+ }
58
+ catch (error) {
59
+ if (error instanceof Error) {
60
+ // TODO: check if there are errors duplication with iterateUrls
61
+ serverLogger.error(error.message ?? exports.DEFAULT_API_ERROR_MESSAGE);
62
+ res.status(500).json(error.message ?? exports.DEFAULT_API_ERROR_MESSAGE);
63
+ }
64
+ else {
65
+ res.status(500).json(exports.HEALTHY_RPC_SERVICES_ARE_OVER);
66
+ }
67
+ }
68
+ };
69
+ };
70
+ exports.rpcFactory = rpcFactory;
@@ -0,0 +1,4 @@
1
+ export { PageError } from './pageError';
2
+ export { Page404 } from './page404';
3
+ export { Page500 } from './page500';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Page500 = exports.Page404 = exports.PageError = void 0;
4
+ var pageError_1 = require("./pageError");
5
+ Object.defineProperty(exports, "PageError", { enumerable: true, get: function () { return pageError_1.PageError; } });
6
+ var page404_1 = require("./page404");
7
+ Object.defineProperty(exports, "Page404", { enumerable: true, get: function () { return page404_1.Page404; } });
8
+ var page500_1 = require("./page500");
9
+ Object.defineProperty(exports, "Page500", { enumerable: true, get: function () { return page500_1.Page500; } });
@@ -0,0 +1,4 @@
1
+ import { FC } from 'react';
2
+ import { PageErrorProps } from './types';
3
+ export declare const Page404: FC<Partial<PageErrorProps>>;
4
+ //# sourceMappingURL=page404.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page404.d.ts","sourceRoot":"","sources":["../../src/ui/page404.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAGxC,eAAO,MAAM,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,CAE/C,CAAA"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Page404 = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const pageError_1 = require("./pageError");
6
+ const Page404 = ({ title, content }) => ((0, jsx_runtime_1.jsx)(pageError_1.PageError, { title: title ?? 'Page Not Found', content: content ?? '¯\\_(ツ)_/¯' }));
7
+ exports.Page404 = Page404;
@@ -0,0 +1,4 @@
1
+ import { FC } from 'react';
2
+ import { PageErrorProps } from './types';
3
+ export declare const Page500: FC<Partial<PageErrorProps>>;
4
+ //# sourceMappingURL=page500.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page500.d.ts","sourceRoot":"","sources":["../../src/ui/page500.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAGxC,eAAO,MAAM,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,CAE/C,CAAA"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Page500 = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const pageError_1 = require("./pageError");
6
+ const Page500 = ({ title, content }) => ((0, jsx_runtime_1.jsx)(pageError_1.PageError, { title: title ?? 'Internal Server Error', content: content ?? 'Oops! Something went wrong.' }));
7
+ exports.Page500 = Page500;
@@ -0,0 +1,4 @@
1
+ import { FC } from 'react';
2
+ import { PageErrorProps } from './types';
3
+ export declare const PageError: FC<PageErrorProps>;
4
+ //# sourceMappingURL=pageError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pageError.d.ts","sourceRoot":"","sources":["../../src/ui/pageError.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAGjC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAExC,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CAOxC,CAAA"}
@@ -0,0 +1,11 @@
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
+ exports.PageError = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const head_1 = __importDefault(require("next/head"));
9
+ const lido_ui_1 = require("@lidofinance/lido-ui");
10
+ const PageError = ({ title, content }) => ((0, jsx_runtime_1.jsxs)(lido_ui_1.ServicePage, { title: title, children: [(0, jsx_runtime_1.jsx)(head_1.default, { children: (0, jsx_runtime_1.jsx)("title", { children: title }) }), content] }));
11
+ exports.PageError = PageError;
@@ -0,0 +1,6 @@
1
+ import { ReactNode } from 'react';
2
+ export type PageErrorProps = {
3
+ title: string;
4
+ content: ReactNode;
5
+ };
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ui/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEjC,MAAM,MAAM,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,CAAA;CAAE,CAAA"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@lidofinance/next-pages",
3
- "description": "Common next pages",
3
+ "description": "Common next API and UI pages",
4
4
  "repository": "git@github.com:lidofinance/warehouse.git",
5
5
  "license": "MIT",
6
- "version": "0.21.0",
6
+ "version": "0.22.0",
7
7
  "files": [
8
8
  "dist"
9
9
  ],
@@ -11,29 +11,47 @@
11
11
  "node": ">= 16",
12
12
  "browsers": "> 0.5%, last 2 versions, not dead"
13
13
  },
14
- "source": "./src/index.ts",
15
- "main": "dist/index.cjs",
16
- "module": "dist/index.mjs",
17
- "types": "dist/index.d.ts",
18
14
  "scripts": {
19
- "build": "parcel build",
15
+ "build": "tsc",
20
16
  "lint": "eslint . && prettier --check src",
21
17
  "lint:fix": "eslint --fix . && prettier --check src --write",
22
18
  "types": "tsc --noEmit"
23
19
  },
20
+ "exports": {
21
+ ".": "./dist/api/index.js",
22
+ "./api": "./dist/api/index.js",
23
+ "./ui": "./dist/ui/index.js"
24
+ },
25
+ "typesVersions": {
26
+ "*": {
27
+ "*": [
28
+ "./dist/api/index.d.ts"
29
+ ],
30
+ "api": [
31
+ "./dist/api/index.d.ts"
32
+ ],
33
+ "ui": [
34
+ "./dist/ui/index.d.ts"
35
+ ]
36
+ }
37
+ },
24
38
  "peerDependencies": {
25
- "@lidofinance/api-logger": "~0.21.0",
26
- "@lidofinance/api-rpc": "~0.21.0",
27
- "@lidofinance/rpc": "~0.21.0",
28
- "next": "^12.2.0",
29
- "prom-client": "^14.0.0"
39
+ "@lidofinance/api-logger": "~0.22.0",
40
+ "@lidofinance/api-rpc": "~0.22.0",
41
+ "@lidofinance/rpc": "~0.22.0",
42
+ "@lidofinance/lido-ui": "^3.6.1",
43
+ "next": "12 || 13",
44
+ "prom-client": "^14.1.0",
45
+ "react": "17 || 18"
30
46
  },
31
47
  "devDependencies": {
32
- "@lidofinance/api-logger": "~0.21.0",
33
- "@lidofinance/api-rpc": "~0.21.0",
34
- "@lidofinance/config-prettier": "~0.21.0",
35
- "@lidofinance/rpc": "~0.21.0",
48
+ "@lidofinance/config-prettier": "~0.22.0",
49
+ "@lidofinance/api-logger": "~0.22.0",
50
+ "@lidofinance/api-rpc": "~0.22.0",
51
+ "@lidofinance/rpc": "~0.22.0",
52
+ "@lidofinance/lido-ui": "^3.6.1",
36
53
  "next": "^12.3.1",
37
- "prom-client": "^14.1.0"
54
+ "prom-client": "^14.1.0",
55
+ "@types/react": "^18.0.25"
38
56
  }
39
57
  }
package/dist/index.cjs DELETED
@@ -1,118 +0,0 @@
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 _requested_headers_get;
98
- res.setHeader("Content-Type", (_requested_headers_get = requested.headers.get("Content-Type")) !== null && _requested_headers_get !== void 0 ? _requested_headers_get : "application/json");
99
- res.status(requested.status).send(requested.body);
100
- } catch (error) {
101
- if (error instanceof Error) {
102
- var _error_message;
103
- // TODO: check if there are errors duplication with iterateUrls
104
- serverLogger.error((_error_message = error.message) !== null && _error_message !== void 0 ? _error_message : $f61917c2527290c5$export$c982278a0ddc4dbe);
105
- var _error_message1;
106
- res.status(500).json((_error_message1 = error.message) !== null && _error_message1 !== void 0 ? _error_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
@@ -1 +0,0 @@
1
- {"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;ACEO,MAAM,4CAAS,CAAC,MAAsB,MAA+B;IAC1E,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC;QAAE,QAAQ;IAAK;AACtC;;ADJA;;;;AEOO,MAAM,4CACX,CAAC,YAAE,SAAQ,EAA4B,GACvC,OAAO,MAAsB,MAAyB;QACpD,MAAM,mBAAmB,MAAM,SAAS,OAAO;QAC/C,IAAI,IAAI,CAAC;IACX;;;;;;;;;;ACZF;;AAQO,MAAM,4CAA4B;AAElC,MAAM,4CAAgC;AAEtC,MAAM,kDAAgC;IAC3C,YAAY,OAAgB,CAAE;QAC5B,KAAK,CAAC,WAAW;IACnB;AACF;AAEO,MAAM,kDAAmC;IAC9C,YAAY,OAAgB,CAAE;QAC5B,KAAK,CAAC,WAAW;IACnB;AACF;AAiBO,MAAM,4CAAa,CAAC,EACzB,SAAS,UAAE,OAAM,YAAE,SAAQ,EAAE,CAAA,aAC7B,UAAS,YACT,SAAQ,gBACR,aAAY,gBACZ,aAAY,qBACZ,kBAAiB,EACA,GAAK;IACtB,MAAM,oBAAoB,IAAI,CAAA,GAAA,yBAAM,EAAE;QACpC,MAAM,SAAS;QACf,MAAM;QACN,YAAY,EAAE;QACd,WAAW,EAAE;IACf;IACA,SAAS,cAAc,CAAC;IAExB,OAAO,OAAO,KAAqB,MAAwC;QACzE,IAAI;YACF,4BAA4B;YAC5B,IAAI,IAAI,MAAM,KAAK,QACjB,qDAAqD;YACrD,MAAM,IAAI,4CAA4B;YAGxC,MAAM,UAAU,OAAO,IAAI,KAAK,CAAC,OAAO,IAAI;YAE5C,yCAAyC;YACzC,IAAI,SAAS,CAAC,QAAQ,IAAI,IAAI,EAC5B,qDAAqD;YACrD,MAAM,IAAI,4CAAyB;YAGrC,oFAAoF;YACpF,wCAAwC;YACxC,KAAK,MAAM,UAAE,OAAM,EAAE,IAAI,MAAM,OAAO,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG;gBAAC,IAAI,IAAI;aAAC,CAAE;gBACxE,IAAI,OAAO,WAAW,UACpB,MAAM,IAAI,MAAM,CAAC,uBAAuB,CAAC,EAAC;gBAE5C,IAAI,CAAC,kBAAkB,QAAQ,CAAC,SAAS;oBACvC,kBAAkB,GAAG;oBACrB,MAAM,IAAI,MAAM,CAAC,WAAW,EAAE,OAAO,cAAc,CAAC,EAAC;gBACvD,CAAC;YACH;YAEA,MAAM,YAAY,MAAM,CAAA,GAAA,iCAAU,EAChC,SAAS,CAAC,QAAQ,EAClB,oFAAoF;YACpF,CAAC,MAAQ,SAAS,KAAK;oBAAE,MAAM,IAAI,IAAI;gBAAqB,GAAG;6BAAE;gBAAQ,IACzE,aAAa,KAAK;gBAGU;YAA9B,IAAI,SAAS,CAAC,gBAAgB,CAAA,yBAAA,UAAU,OAAO,CAAC,GAAG,CAAC,6BAAtB,oCAAA,yBAAyC,kBAAkB;YACzF,IAAI,MAAM,CAAC,UAAU,MAAM,EAAE,IAAI,CAAC,UAAU,IAAI;QAClD,EAAE,OAAO,OAAO;YACd,IAAI,iBAAiB,OAAO;oBAEP;gBADnB,+DAA+D;gBAC/D,aAAa,KAAK,CAAC,CAAA,iBAAA,MAAM,OAAO,cAAb,4BAAA,iBAAiB,yCAAyB;oBACxC;gBAArB,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,CAAA,kBAAA,MAAM,OAAO,cAAb,6BAAA,kBAAiB,yCAAyB;YACjE,OACE,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC;QAEzB;IACF;AACF;;","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"}
package/dist/index.d.ts DELETED
@@ -1,32 +0,0 @@
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
@@ -1 +0,0 @@
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 DELETED
@@ -1,100 +0,0 @@
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 _requested_headers_get;
82
- res.setHeader("Content-Type", (_requested_headers_get = requested.headers.get("Content-Type")) !== null && _requested_headers_get !== void 0 ? _requested_headers_get : "application/json");
83
- res.status(requested.status).send(requested.body);
84
- } catch (error) {
85
- if (error instanceof Error) {
86
- var _error_message;
87
- // TODO: check if there are errors duplication with iterateUrls
88
- serverLogger.error((_error_message = error.message) !== null && _error_message !== void 0 ? _error_message : $2f7bb06869d30d12$export$c982278a0ddc4dbe);
89
- var _error_message1;
90
- res.status(500).json((_error_message1 = error.message) !== null && _error_message1 !== void 0 ? _error_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
@@ -1 +0,0 @@
1
- {"mappings":";;;;;;;;;ACEO,MAAM,4CAAS,CAAC,MAAsB,MAA+B;IAC1E,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC;QAAE,QAAQ;IAAK;AACtC;;ADJA;;;;AEOO,MAAM,4CACX,CAAC,YAAE,SAAQ,EAA4B,GACvC,OAAO,MAAsB,MAAyB;QACpD,MAAM,mBAAmB,MAAM,SAAS,OAAO;QAC/C,IAAI,IAAI,CAAC;IACX;;;;;;;;;;ACZF;;AAQO,MAAM,4CAA4B;AAElC,MAAM,4CAAgC;AAEtC,MAAM,kDAAgC;IAC3C,YAAY,OAAgB,CAAE;QAC5B,KAAK,CAAC,WAAW;IACnB;AACF;AAEO,MAAM,kDAAmC;IAC9C,YAAY,OAAgB,CAAE;QAC5B,KAAK,CAAC,WAAW;IACnB;AACF;AAiBO,MAAM,4CAAa,CAAC,EACzB,SAAS,UAAE,OAAM,YAAE,SAAQ,EAAE,CAAA,aAC7B,UAAS,YACT,SAAQ,gBACR,aAAY,gBACZ,aAAY,qBACZ,kBAAiB,EACA,GAAK;IACtB,MAAM,oBAAoB,IAAI,CAAA,GAAA,cAAM,EAAE;QACpC,MAAM,SAAS;QACf,MAAM;QACN,YAAY,EAAE;QACd,WAAW,EAAE;IACf;IACA,SAAS,cAAc,CAAC;IAExB,OAAO,OAAO,KAAqB,MAAwC;QACzE,IAAI;YACF,4BAA4B;YAC5B,IAAI,IAAI,MAAM,KAAK,QACjB,qDAAqD;YACrD,MAAM,IAAI,4CAA4B;YAGxC,MAAM,UAAU,OAAO,IAAI,KAAK,CAAC,OAAO,IAAI;YAE5C,yCAAyC;YACzC,IAAI,SAAS,CAAC,QAAQ,IAAI,IAAI,EAC5B,qDAAqD;YACrD,MAAM,IAAI,4CAAyB;YAGrC,oFAAoF;YACpF,wCAAwC;YACxC,KAAK,MAAM,UAAE,OAAM,EAAE,IAAI,MAAM,OAAO,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG;gBAAC,IAAI,IAAI;aAAC,CAAE;gBACxE,IAAI,OAAO,WAAW,UACpB,MAAM,IAAI,MAAM,CAAC,uBAAuB,CAAC,EAAC;gBAE5C,IAAI,CAAC,kBAAkB,QAAQ,CAAC,SAAS;oBACvC,kBAAkB,GAAG;oBACrB,MAAM,IAAI,MAAM,CAAC,WAAW,EAAE,OAAO,cAAc,CAAC,EAAC;gBACvD,CAAC;YACH;YAEA,MAAM,YAAY,MAAM,CAAA,GAAA,kBAAU,EAChC,SAAS,CAAC,QAAQ,EAClB,oFAAoF;YACpF,CAAC,MAAQ,SAAS,KAAK;oBAAE,MAAM,IAAI,IAAI;gBAAqB,GAAG;6BAAE;gBAAQ,IACzE,aAAa,KAAK;gBAGU;YAA9B,IAAI,SAAS,CAAC,gBAAgB,CAAA,yBAAA,UAAU,OAAO,CAAC,GAAG,CAAC,6BAAtB,oCAAA,yBAAyC,kBAAkB;YACzF,IAAI,MAAM,CAAC,UAAU,MAAM,EAAE,IAAI,CAAC,UAAU,IAAI;QAClD,EAAE,OAAO,OAAO;YACd,IAAI,iBAAiB,OAAO;oBAEP;gBADnB,+DAA+D;gBAC/D,aAAa,KAAK,CAAC,CAAA,iBAAA,MAAM,OAAO,cAAb,4BAAA,iBAAiB,yCAAyB;oBACxC;gBAArB,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,CAAA,kBAAA,MAAM,OAAO,cAAb,6BAAA,kBAAiB,yCAAyB;YACjE,OACE,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC;QAEzB;IACF;AACF;;","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"}