@remnawave/backend-contract 2.8.0 → 2.8.1

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.
@@ -8,6 +8,7 @@ export declare const BANDWIDTH_STATS_ROUTES: {
8
8
  readonly GET: "";
9
9
  readonly GET_REALTIME: "realtime";
10
10
  readonly GET_USERS: (uuid: string) => string;
11
+ readonly GET_USERS_BY_NODES: "users";
11
12
  };
12
13
  readonly USERS: {
13
14
  readonly GET_BY_UUID: (uuid: string) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"bandwidth-stats.d.ts","sourceRoot":"","sources":["../../../../api/controllers/bandwidth-stats.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,EAAG,iBAA0B,CAAC;AAErE,eAAO,MAAM,2BAA2B,EAAG,OAAgB,CAAC;AAC5D,eAAO,MAAM,2BAA2B,EAAG,OAAgB,CAAC;AAE5D,eAAO,MAAM,gCAAgC,yBAC8B,CAAC;AAC5E,eAAO,MAAM,gCAAgC,yBAC8B,CAAC;AAO5E,eAAO,MAAM,sBAAsB;;;;mCAOT,MAAM;;;qCAIJ,MAAM;;;;uCAKJ,MAAM;;;yCAIJ,MAAM;;;CAG5B,CAAC"}
1
+ {"version":3,"file":"bandwidth-stats.d.ts","sourceRoot":"","sources":["../../../../api/controllers/bandwidth-stats.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,EAAG,iBAA0B,CAAC;AAErE,eAAO,MAAM,2BAA2B,EAAG,OAAgB,CAAC;AAC5D,eAAO,MAAM,2BAA2B,EAAG,OAAgB,CAAC;AAE5D,eAAO,MAAM,gCAAgC,yBAC8B,CAAC;AAC5E,eAAO,MAAM,gCAAgC,yBAC8B,CAAC;AAO5E,eAAO,MAAM,sBAAsB;;;;mCAOT,MAAM;;;;qCAMJ,MAAM;;;;uCAKJ,MAAM;;;yCAIJ,MAAM;;;CAG5B,CAAC"}
@@ -18,6 +18,8 @@ exports.BANDWIDTH_STATS_ROUTES = {
18
18
  GET_REALTIME: 'realtime',
19
19
  // GET /bandwidth-stats/nodes/:nodeUuid/users –– Nodes -> Management -> Show usage
20
20
  GET_USERS: (uuid) => `${uuid}/users`,
21
+ // POST /bandwidth-stats/nodes/users –– Nodes -> Custom Graphs
22
+ GET_USERS_BY_NODES: 'users',
21
23
  },
22
24
  USERS: {
23
25
  // GET /bandwidth-stats/users/:userUuid –– Users -> User -> Show Usage
@@ -278,6 +278,7 @@ export declare const REST_API: {
278
278
  readonly GET: "/api/bandwidth-stats/nodes/";
279
279
  readonly GET_REALTIME: "/api/bandwidth-stats/nodes/realtime";
280
280
  readonly GET_USERS: (uuid: string) => string;
281
+ readonly GET_USERS_BY_NODES: "/api/bandwidth-stats/nodes/users";
281
282
  };
282
283
  readonly USERS: {
283
284
  readonly GET_BY_UUID: (uuid: string) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../api/routes.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI,EAAG,MAAe,CAAC;AACpC,eAAO,MAAM,YAAY,EAAG,UAAmB,CAAC;AAChD,eAAO,MAAM,WAAW,EAAG,SAAkB,CAAC;AAC9C,eAAO,MAAM,cAAc,EAAG,SAAkB,CAAC;AAEjD,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;gCAyBE,MAAM;;;;;;;;;qCAYD,MAAM;;gCAGX,MAAM;;;;;oCAOF,MAAM;qCAIL,MAAM;qCAIN,MAAM;;2CAKA,MAAM;;;;;;;;;;;;;gCAiBjB,MAAM;qCAGD,MAAM;0CAED,MAAM;sDAEM,MAAM;;qCAMvB,MAAM;oCAIP,MAAM;2CAIC,MAAM;iDAIA,MAAM;;;8BAOzB,MAAM;6CAES,MAAM;0CAIT,MAAM;2DAIW,MAAM;+CAIlB,MAAM;oCAIjB,MAAM;gCAIV,MAAM;;;;;;;;;;;;;;;;;;;;;;kCAyBJ,MAAM;uCAED,MAAM;;;;;;qCASR,MAAM;gCAEX,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAqCT,MAAM;;gCAKH,MAAM;;;;;;;;;;;;;;mDAiBa,MAAM;;;;;;;;;0CAYf,MAAM;kCAId,MAAM;6CAIK,MAAM;iDAIF,MAAM;;;6CAMV,MAAM;;qDAKE,MAAM;;;;;;qCAStB,MAAM;gCAIX,MAAM;sDAIgB,MAAM;6DAIC,MAAM;;;;;;;;;;qCAa9B,MAAM;gCAIX,MAAM;0CAII,MAAM;;uCAKT,MAAM;0CAEH,MAAM;;;;;;;;;;yCAWP,MAAM;8CAED,MAAM;;;;6CAMP,MAAM;;;gDAKH,MAAM;;;;;;;;;;;;;;;;qCAiBjB,MAAM;gCAIX,MAAM;;uCAKC,MAAM;0CAEH,MAAM;;;;;;;;;;;6BAYnB,MAAM;;;gCAIH,MAAM;;;;;;;;6BAST,MAAM;;;gCAIH,MAAM;;;;;;;;;;;;;;;;;uCAkBC,MAAM;;;yCAIJ,MAAM;;;;2CAKJ,MAAM;;;6CAIJ,MAAM;;;;;mCAMhB,MAAM;+CAEM,MAAM;;6CAGR,MAAM;qDAEE,MAAM;;;;iCAK1B,MAAM;oCAEH,MAAM;;;iCAIT,MAAM;oCAEH,MAAM;;;CAIvB,CAAC"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../api/routes.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI,EAAG,MAAe,CAAC;AACpC,eAAO,MAAM,YAAY,EAAG,UAAmB,CAAC;AAChD,eAAO,MAAM,WAAW,EAAG,SAAkB,CAAC;AAC9C,eAAO,MAAM,cAAc,EAAG,SAAkB,CAAC;AAEjD,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;gCAyBE,MAAM;;;;;;;;;qCAYD,MAAM;;gCAGX,MAAM;;;;;oCAOF,MAAM;qCAIL,MAAM;qCAIN,MAAM;;2CAKA,MAAM;;;;;;;;;;;;;gCAiBjB,MAAM;qCAGD,MAAM;0CAED,MAAM;sDAEM,MAAM;;qCAMvB,MAAM;oCAIP,MAAM;2CAIC,MAAM;iDAIA,MAAM;;;8BAOzB,MAAM;6CAES,MAAM;0CAIT,MAAM;2DAIW,MAAM;+CAIlB,MAAM;oCAIjB,MAAM;gCAIV,MAAM;;;;;;;;;;;;;;;;;;;;;;kCAyBJ,MAAM;uCAED,MAAM;;;;;;qCASR,MAAM;gCAEX,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAqCT,MAAM;;gCAKH,MAAM;;;;;;;;;;;;;;mDAiBa,MAAM;;;;;;;;;0CAYf,MAAM;kCAId,MAAM;6CAIK,MAAM;iDAIF,MAAM;;;6CAMV,MAAM;;qDAKE,MAAM;;;;;;qCAStB,MAAM;gCAIX,MAAM;sDAIgB,MAAM;6DAIC,MAAM;;;;;;;;;;qCAa9B,MAAM;gCAIX,MAAM;0CAII,MAAM;;uCAKT,MAAM;0CAEH,MAAM;;;;;;;;;;yCAWP,MAAM;8CAED,MAAM;;;;6CAMP,MAAM;;;gDAKH,MAAM;;;;;;;;;;;;;;;;qCAiBjB,MAAM;gCAIX,MAAM;;uCAKC,MAAM;0CAEH,MAAM;;;;;;;;;;;6BAYnB,MAAM;;;gCAIH,MAAM;;;;;;;;6BAST,MAAM;;;gCAIH,MAAM;;;;;;;;;;;;;;;;;uCAkBC,MAAM;;;;yCAKJ,MAAM;;;;2CAKJ,MAAM;;;6CAIJ,MAAM;;;;;mCAMhB,MAAM;+CAEM,MAAM;;6CAGR,MAAM;qDAEE,MAAM;;;;iCAK1B,MAAM;oCAEH,MAAM;;;iCAIT,MAAM;oCAEH,MAAM;;;CAIvB,CAAC"}
@@ -315,6 +315,7 @@ exports.REST_API = {
315
315
  GET: `${exports.ROOT}/${CONTROLLERS.BANDWIDTH_STATS_CONTROLLER}/${CONTROLLERS.BANDWIDTH_STATS_NODES_ROUTE}/${CONTROLLERS.BANDWIDTH_STATS_ROUTES.NODES.GET}`,
316
316
  GET_REALTIME: `${exports.ROOT}/${CONTROLLERS.BANDWIDTH_STATS_CONTROLLER}/${CONTROLLERS.BANDWIDTH_STATS_NODES_ROUTE}/${CONTROLLERS.BANDWIDTH_STATS_ROUTES.NODES.GET_REALTIME}`,
317
317
  GET_USERS: (uuid) => `${exports.ROOT}/${CONTROLLERS.BANDWIDTH_STATS_CONTROLLER}/${CONTROLLERS.BANDWIDTH_STATS_NODES_ROUTE}/${CONTROLLERS.BANDWIDTH_STATS_ROUTES.NODES.GET_USERS(uuid)}`,
318
+ GET_USERS_BY_NODES: `${exports.ROOT}/${CONTROLLERS.BANDWIDTH_STATS_CONTROLLER}/${CONTROLLERS.BANDWIDTH_STATS_NODES_ROUTE}/${CONTROLLERS.BANDWIDTH_STATS_ROUTES.NODES.GET_USERS_BY_NODES}`,
318
319
  },
319
320
  USERS: {
320
321
  GET_BY_UUID: (uuid) => `${exports.ROOT}/${CONTROLLERS.BANDWIDTH_STATS_CONTROLLER}/${CONTROLLERS.BANDWIDTH_STATS_USERS_ROUTE}/${CONTROLLERS.BANDWIDTH_STATS_ROUTES.USERS.GET_BY_UUID(uuid)}`,
@@ -0,0 +1,85 @@
1
+ import { z } from 'zod';
2
+ export declare namespace GetStatsNodesUsersUsageCommand {
3
+ const url: "/api/bandwidth-stats/nodes/users";
4
+ const TSQ_url: "/api/bandwidth-stats/nodes/users";
5
+ const endpointDetails: import("../../../constants").EndpointDetails;
6
+ const RequestQuerySchema: z.ZodObject<{
7
+ start: z.ZodString;
8
+ end: z.ZodString;
9
+ topUsersLimit: z.ZodDefault<z.ZodNumber>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ start: string;
12
+ end: string;
13
+ topUsersLimit: number;
14
+ }, {
15
+ start: string;
16
+ end: string;
17
+ topUsersLimit?: number | undefined;
18
+ }>;
19
+ type RequestQuery = z.infer<typeof RequestQuerySchema>;
20
+ const RequestSchema: z.ZodObject<{
21
+ nodesUuids: z.ZodArray<z.ZodString, "many">;
22
+ }, "strip", z.ZodTypeAny, {
23
+ nodesUuids: string[];
24
+ }, {
25
+ nodesUuids: string[];
26
+ }>;
27
+ type Request = z.infer<typeof RequestSchema>;
28
+ const ResponseSchema: z.ZodObject<{
29
+ response: z.ZodObject<{
30
+ categories: z.ZodArray<z.ZodString, "many">;
31
+ sparklineData: z.ZodArray<z.ZodNumber, "many">;
32
+ topUsers: z.ZodArray<z.ZodObject<{
33
+ color: z.ZodString;
34
+ username: z.ZodString;
35
+ total: z.ZodNumber;
36
+ }, "strip", z.ZodTypeAny, {
37
+ username: string;
38
+ total: number;
39
+ color: string;
40
+ }, {
41
+ username: string;
42
+ total: number;
43
+ color: string;
44
+ }>, "many">;
45
+ }, "strip", z.ZodTypeAny, {
46
+ categories: string[];
47
+ sparklineData: number[];
48
+ topUsers: {
49
+ username: string;
50
+ total: number;
51
+ color: string;
52
+ }[];
53
+ }, {
54
+ categories: string[];
55
+ sparklineData: number[];
56
+ topUsers: {
57
+ username: string;
58
+ total: number;
59
+ color: string;
60
+ }[];
61
+ }>;
62
+ }, "strip", z.ZodTypeAny, {
63
+ response: {
64
+ categories: string[];
65
+ sparklineData: number[];
66
+ topUsers: {
67
+ username: string;
68
+ total: number;
69
+ color: string;
70
+ }[];
71
+ };
72
+ }, {
73
+ response: {
74
+ categories: string[];
75
+ sparklineData: number[];
76
+ topUsers: {
77
+ username: string;
78
+ total: number;
79
+ color: string;
80
+ }[];
81
+ };
82
+ }>;
83
+ type Response = z.infer<typeof ResponseSchema>;
84
+ }
85
+ //# sourceMappingURL=get-stats-nodes-users-usage.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-stats-nodes-users-usage.command.d.ts","sourceRoot":"","sources":["../../../../../commands/bandwidth-stats/nodes/get-stats-nodes-users-usage.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,yBAAiB,8BAA8B,CAAC;IACrC,MAAM,GAAG,oCAAoD,CAAC;IAC9D,MAAM,OAAO,oCAAM,CAAC;IAEpB,MAAM,eAAe,8CAI3B,CAAC;IAEK,MAAM,kBAAkB;;;;;;;;;;;;MAI7B,CAAC;IAEH,KAAY,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;IAEvD,MAAM,aAAa;;;;;;MAExB,CAAC;IAEH,KAAY,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;IAE7C,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAYzB,CAAC;IAEH,KAAY,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;CACzD"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetStatsNodesUsersUsageCommand = void 0;
4
+ const zod_1 = require("zod");
5
+ const api_1 = require("../../../api");
6
+ const constants_1 = require("../../../constants");
7
+ var GetStatsNodesUsersUsageCommand;
8
+ (function (GetStatsNodesUsersUsageCommand) {
9
+ GetStatsNodesUsersUsageCommand.url = api_1.REST_API.BANDWIDTH_STATS.NODES.GET_USERS_BY_NODES;
10
+ GetStatsNodesUsersUsageCommand.TSQ_url = GetStatsNodesUsersUsageCommand.url;
11
+ GetStatsNodesUsersUsageCommand.endpointDetails = (0, constants_1.getEndpointDetails)(api_1.BANDWIDTH_STATS_ROUTES.NODES.GET_USERS_BY_NODES, 'post', 'Get Nodes Users Usage by Nodes UUIDs');
12
+ GetStatsNodesUsersUsageCommand.RequestQuerySchema = zod_1.z.object({
13
+ start: zod_1.z.string().date(),
14
+ end: zod_1.z.string().date(),
15
+ topUsersLimit: zod_1.z.coerce.number().min(1).default(100),
16
+ });
17
+ GetStatsNodesUsersUsageCommand.RequestSchema = zod_1.z.object({
18
+ nodesUuids: zod_1.z.array(zod_1.z.string().uuid()).min(1, 'Must be at least 1 node UUID'),
19
+ });
20
+ GetStatsNodesUsersUsageCommand.ResponseSchema = zod_1.z.object({
21
+ response: zod_1.z.object({
22
+ categories: zod_1.z.array(zod_1.z.string()),
23
+ sparklineData: zod_1.z.array(zod_1.z.number()),
24
+ topUsers: zod_1.z.array(zod_1.z.object({
25
+ color: zod_1.z.string(),
26
+ username: zod_1.z.string(),
27
+ total: zod_1.z.number(),
28
+ })),
29
+ }),
30
+ });
31
+ })(GetStatsNodesUsersUsageCommand || (exports.GetStatsNodesUsersUsageCommand = GetStatsNodesUsersUsageCommand = {}));
@@ -1,3 +1,4 @@
1
1
  export * from './get-stats-node-users-usage.command';
2
2
  export * from './get-stats-nodes-usage.command';
3
+ export * from './get-stats-nodes-users-usage.command';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../commands/bandwidth-stats/nodes/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC;AACrD,cAAc,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../commands/bandwidth-stats/nodes/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC;AACrD,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC"}
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./get-stats-node-users-usage.command"), exports);
18
18
  __exportStar(require("./get-stats-nodes-usage.command"), exports);
19
+ __exportStar(require("./get-stats-nodes-users-usage.command"), exports);
@@ -18,6 +18,8 @@ exports.BANDWIDTH_STATS_ROUTES = {
18
18
  GET_REALTIME: 'realtime',
19
19
  // GET /bandwidth-stats/nodes/:nodeUuid/users –– Nodes -> Management -> Show usage
20
20
  GET_USERS: (uuid) => `${uuid}/users`,
21
+ // POST /bandwidth-stats/nodes/users –– Nodes -> Custom Graphs
22
+ GET_USERS_BY_NODES: 'users',
21
23
  },
22
24
  USERS: {
23
25
  // GET /bandwidth-stats/users/:userUuid –– Users -> User -> Show Usage
@@ -315,6 +315,7 @@ exports.REST_API = {
315
315
  GET: `${exports.ROOT}/${CONTROLLERS.BANDWIDTH_STATS_CONTROLLER}/${CONTROLLERS.BANDWIDTH_STATS_NODES_ROUTE}/${CONTROLLERS.BANDWIDTH_STATS_ROUTES.NODES.GET}`,
316
316
  GET_REALTIME: `${exports.ROOT}/${CONTROLLERS.BANDWIDTH_STATS_CONTROLLER}/${CONTROLLERS.BANDWIDTH_STATS_NODES_ROUTE}/${CONTROLLERS.BANDWIDTH_STATS_ROUTES.NODES.GET_REALTIME}`,
317
317
  GET_USERS: (uuid) => `${exports.ROOT}/${CONTROLLERS.BANDWIDTH_STATS_CONTROLLER}/${CONTROLLERS.BANDWIDTH_STATS_NODES_ROUTE}/${CONTROLLERS.BANDWIDTH_STATS_ROUTES.NODES.GET_USERS(uuid)}`,
318
+ GET_USERS_BY_NODES: `${exports.ROOT}/${CONTROLLERS.BANDWIDTH_STATS_CONTROLLER}/${CONTROLLERS.BANDWIDTH_STATS_NODES_ROUTE}/${CONTROLLERS.BANDWIDTH_STATS_ROUTES.NODES.GET_USERS_BY_NODES}`,
318
319
  },
319
320
  USERS: {
320
321
  GET_BY_UUID: (uuid) => `${exports.ROOT}/${CONTROLLERS.BANDWIDTH_STATS_CONTROLLER}/${CONTROLLERS.BANDWIDTH_STATS_USERS_ROUTE}/${CONTROLLERS.BANDWIDTH_STATS_ROUTES.USERS.GET_BY_UUID(uuid)}`,
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetStatsNodesUsersUsageCommand = void 0;
4
+ const zod_1 = require("zod");
5
+ const api_1 = require("../../../api");
6
+ const constants_1 = require("../../../constants");
7
+ var GetStatsNodesUsersUsageCommand;
8
+ (function (GetStatsNodesUsersUsageCommand) {
9
+ GetStatsNodesUsersUsageCommand.url = api_1.REST_API.BANDWIDTH_STATS.NODES.GET_USERS_BY_NODES;
10
+ GetStatsNodesUsersUsageCommand.TSQ_url = GetStatsNodesUsersUsageCommand.url;
11
+ GetStatsNodesUsersUsageCommand.endpointDetails = (0, constants_1.getEndpointDetails)(api_1.BANDWIDTH_STATS_ROUTES.NODES.GET_USERS_BY_NODES, 'post', 'Get Nodes Users Usage by Nodes UUIDs');
12
+ GetStatsNodesUsersUsageCommand.RequestQuerySchema = zod_1.z.object({
13
+ start: zod_1.z.string().date(),
14
+ end: zod_1.z.string().date(),
15
+ topUsersLimit: zod_1.z.coerce.number().min(1).default(100),
16
+ });
17
+ GetStatsNodesUsersUsageCommand.RequestSchema = zod_1.z.object({
18
+ nodesUuids: zod_1.z.array(zod_1.z.string().uuid()).min(1, 'Must be at least 1 node UUID'),
19
+ });
20
+ GetStatsNodesUsersUsageCommand.ResponseSchema = zod_1.z.object({
21
+ response: zod_1.z.object({
22
+ categories: zod_1.z.array(zod_1.z.string()),
23
+ sparklineData: zod_1.z.array(zod_1.z.number()),
24
+ topUsers: zod_1.z.array(zod_1.z.object({
25
+ color: zod_1.z.string(),
26
+ username: zod_1.z.string(),
27
+ total: zod_1.z.number(),
28
+ })),
29
+ }),
30
+ });
31
+ })(GetStatsNodesUsersUsageCommand || (exports.GetStatsNodesUsersUsageCommand = GetStatsNodesUsersUsageCommand = {}));
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./get-stats-node-users-usage.command"), exports);
18
18
  __exportStar(require("./get-stats-nodes-usage.command"), exports);
19
+ __exportStar(require("./get-stats-nodes-users-usage.command"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnawave/backend-contract",
3
- "version": "2.8.0",
3
+ "version": "2.8.1",
4
4
  "public": true,
5
5
  "license": "AGPL-3.0-only",
6
6
  "description": "A contract library for Remnawave Backend. It can be used in backend and frontend.",