@lidofinance/next-pages 0.20.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 +57 -8
- package/README.mdx +4 -0
- package/dist/api/health.d.ts +3 -0
- package/dist/api/health.d.ts.map +1 -0
- package/dist/api/health.js +7 -0
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +13 -0
- package/dist/api/metricsFactory.d.ts +7 -0
- package/dist/api/metricsFactory.d.ts.map +1 -0
- package/dist/api/metricsFactory.js +8 -0
- package/dist/api/rpcFactory.d.ts +26 -0
- package/dist/api/rpcFactory.d.ts.map +1 -0
- package/dist/api/rpcFactory.js +70 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +9 -0
- package/dist/ui/page404.d.ts +4 -0
- package/dist/ui/page404.d.ts.map +1 -0
- package/dist/ui/page404.js +7 -0
- package/dist/ui/page500.d.ts +4 -0
- package/dist/ui/page500.d.ts.map +1 -0
- package/dist/ui/page500.js +7 -0
- package/dist/ui/pageError.d.ts +4 -0
- package/dist/ui/pageError.d.ts.map +1 -0
- package/dist/ui/pageError.js +11 -0
- package/dist/ui/types.d.ts +6 -0
- package/dist/ui/types.d.ts.map +1 -0
- package/dist/ui/types.js +2 -0
- package/package.json +35 -17
- package/dist/index.cjs +0 -118
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -32
- package/dist/index.d.ts.map +0 -1
- package/dist/index.mjs +0 -100
- package/dist/index.mjs.map +0 -1
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
+
```
|
package/README.mdx
ADDED
|
@@ -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,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 @@
|
|
|
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"}
|
package/dist/ui/index.js
ADDED
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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"}
|
package/dist/ui/types.js
ADDED
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.
|
|
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": "
|
|
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.
|
|
26
|
-
"@lidofinance/api-rpc": "~0.
|
|
27
|
-
"@lidofinance/rpc": "~0.
|
|
28
|
-
"
|
|
29
|
-
"
|
|
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/
|
|
33
|
-
"@lidofinance/api-
|
|
34
|
-
"@lidofinance/
|
|
35
|
-
"@lidofinance/rpc": "~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
|
package/dist/index.cjs.map
DELETED
|
@@ -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
|
package/dist/index.d.ts.map
DELETED
|
@@ -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
|
package/dist/index.mjs.map
DELETED
|
@@ -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"}
|