@gearbox-protocol/cli-utils 9.3.0 → 9.4.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.
- package/dist/index.d.ts +66 -66
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +28 -29
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +1 -1
- package/dist/schema.js.map +1 -1
- package/package.json +11 -11
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ClientWhitelistItem, WhitelistItem, WhitelistItems, addressArrayLike, addressLike, boolLike, clientWhitelistItemSchema, optionalAddressArrayLike, optionalStringArrayLike, stringArrayLike, whitelistItemSchema, whitelistItemsSchema } from "./schema.js";
|
|
2
2
|
import YAML from "yaml";
|
|
3
|
-
import { ILogger, NetworkType } from "@gearbox-protocol/sdk";
|
|
3
|
+
import { ILogger, NetworkType } from "@gearbox-protocol/sdk/onchain";
|
|
4
4
|
import { z } from "zod/v4";
|
|
5
5
|
import { Address, HttpTransportConfig } from "viem";
|
|
6
6
|
import { Markdown } from "@vlad-yakovlev/telegram-md";
|
|
@@ -8,7 +8,7 @@ import { Command } from "@commander-js/extra-typings";
|
|
|
8
8
|
import * as z4 from "zod/v4/core";
|
|
9
9
|
import { ProviderConfig } from "@gearbox-protocol/sdk/dev";
|
|
10
10
|
//#region src/CensoredString.d.ts
|
|
11
|
-
declare class CensoredString<V extends string = string> {
|
|
11
|
+
export declare class CensoredString<V extends string = string> {
|
|
12
12
|
#private;
|
|
13
13
|
static transform<T extends string>(value: T | CensoredString<T>): CensoredString<T>;
|
|
14
14
|
constructor(value: V);
|
|
@@ -21,7 +21,7 @@ declare class CensoredString<V extends string = string> {
|
|
|
21
21
|
/**
|
|
22
22
|
* Assumes that host is always visible, and the secret part is in path or query
|
|
23
23
|
*/
|
|
24
|
-
declare class CensoredURL {
|
|
24
|
+
export declare class CensoredURL {
|
|
25
25
|
#private;
|
|
26
26
|
static transform(value: string | CensoredURL): CensoredURL;
|
|
27
27
|
constructor(url: string);
|
|
@@ -35,19 +35,19 @@ declare class CensoredURL {
|
|
|
35
35
|
* Compress a plain JS object into a base64url string
|
|
36
36
|
* suitable for env vars.
|
|
37
37
|
*/
|
|
38
|
-
declare function compressObject(obj: unknown): string;
|
|
38
|
+
export declare function compressObject(obj: unknown): string;
|
|
39
39
|
/**
|
|
40
40
|
* Decompress a base64url string back into a JS object
|
|
41
41
|
* Allows to pass template data to resolve promises/env
|
|
42
42
|
*/
|
|
43
|
-
declare function decompressObject<T = unknown>(value: string, templateData?: Record<string, unknown>): Promise<T>;
|
|
43
|
+
export declare function decompressObject<T = unknown>(value: string, templateData?: Record<string, unknown>): Promise<T>;
|
|
44
44
|
//#endregion
|
|
45
45
|
//#region src/createPinoCensor.d.ts
|
|
46
46
|
/**
|
|
47
47
|
* Gathers known secrets from a config and returns a function that replaces each raw secret with its masked representation.
|
|
48
48
|
* Intended for pino's `hooks.streamWrite`
|
|
49
49
|
*/
|
|
50
|
-
declare function createPinoCensor(config: unknown): (s: string) => string;
|
|
50
|
+
export declare function createPinoCensor(config: unknown): (s: string) => string;
|
|
51
51
|
//#endregion
|
|
52
52
|
//#region src/fetchRetry.d.ts
|
|
53
53
|
interface RetrySettings {
|
|
@@ -55,10 +55,10 @@ interface RetrySettings {
|
|
|
55
55
|
retryInterval?: number;
|
|
56
56
|
validateResponse?: (response: Response) => void;
|
|
57
57
|
}
|
|
58
|
-
declare function fetchRetry(input: string | URL, init?: RequestInit & RetrySettings): Promise<Response>;
|
|
58
|
+
export declare function fetchRetry(input: string | URL, init?: RequestInit & RetrySettings): Promise<Response>;
|
|
59
59
|
//#endregion
|
|
60
60
|
//#region src/providers-schema.d.ts
|
|
61
|
-
declare const RpcProvider: z.ZodEnum<{
|
|
61
|
+
export declare const RpcProvider: z.ZodEnum<{
|
|
62
62
|
alchemy: "alchemy";
|
|
63
63
|
ankr: "ankr";
|
|
64
64
|
custom: "custom";
|
|
@@ -66,8 +66,8 @@ declare const RpcProvider: z.ZodEnum<{
|
|
|
66
66
|
erpc: "erpc";
|
|
67
67
|
thirdweb: "thirdweb";
|
|
68
68
|
}>;
|
|
69
|
-
type RpcProvider = z.infer<typeof RpcProvider>;
|
|
70
|
-
declare const ProvidersSchema: z.ZodObject<{
|
|
69
|
+
export type RpcProvider = z.infer<typeof RpcProvider>;
|
|
70
|
+
export declare const ProvidersSchema: z.ZodObject<{
|
|
71
71
|
network: z.ZodEnum<{
|
|
72
72
|
Arbitrum: "Arbitrum";
|
|
73
73
|
Avalanche: "Avalanche";
|
|
@@ -103,57 +103,57 @@ declare const ProvidersSchema: z.ZodObject<{
|
|
|
103
103
|
erpcUrl: z.ZodDefault<z.ZodURL>;
|
|
104
104
|
jsonRpcTimeout: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
105
105
|
}, z.core.$strip>;
|
|
106
|
-
type ProvidersSchema = z.infer<typeof ProvidersSchema>;
|
|
106
|
+
export type ProvidersSchema = z.infer<typeof ProvidersSchema>;
|
|
107
107
|
//#endregion
|
|
108
108
|
//#region src/getFirstHttpTransportOptions.d.ts
|
|
109
|
-
interface HttpTransportOptions {
|
|
109
|
+
export interface HttpTransportOptions {
|
|
110
110
|
url?: string | undefined;
|
|
111
111
|
config: HttpTransportConfig;
|
|
112
112
|
}
|
|
113
|
-
declare function getFirstHttpTransportOptions(config: ProvidersSchema): HttpTransportOptions;
|
|
113
|
+
export declare function getFirstHttpTransportOptions(config: ProvidersSchema): HttpTransportOptions;
|
|
114
114
|
//#endregion
|
|
115
115
|
//#region src/getProviders.d.ts
|
|
116
|
-
declare function getProviders(config: ProvidersSchema, logger?: ILogger): ProviderConfig[];
|
|
116
|
+
export declare function getProviders(config: ProvidersSchema, logger?: ILogger): ProviderConfig[];
|
|
117
117
|
//#endregion
|
|
118
118
|
//#region src/notifications/schema.d.ts
|
|
119
|
-
declare const TelegramConfig: z.ZodObject<{
|
|
119
|
+
export declare const TelegramConfig: z.ZodObject<{
|
|
120
120
|
type: z.ZodLiteral<"telegram">;
|
|
121
|
-
token: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.
|
|
122
|
-
alertsChannel: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.
|
|
123
|
-
notificationsChannel: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.
|
|
121
|
+
token: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodInstanceOf<CensoredString<string>>]>, z.ZodTransform<CensoredString<string>, string | CensoredString<string>>>;
|
|
122
|
+
alertsChannel: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodInstanceOf<CensoredString<string>>]>, z.ZodTransform<CensoredString<string>, string | CensoredString<string>>>;
|
|
123
|
+
notificationsChannel: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodInstanceOf<CensoredString<string>>]>, z.ZodTransform<CensoredString<string>, string | CensoredString<string>>>>;
|
|
124
124
|
prefix: z.ZodOptional<z.ZodString>;
|
|
125
125
|
}, z.core.$strip>;
|
|
126
|
-
type TelegramConfig = z.infer<typeof TelegramConfig>;
|
|
127
|
-
declare const SlackConfig: z.ZodObject<{
|
|
126
|
+
export type TelegramConfig = z.infer<typeof TelegramConfig>;
|
|
127
|
+
export declare const SlackConfig: z.ZodObject<{
|
|
128
128
|
type: z.ZodLiteral<"slack">;
|
|
129
|
-
webhookUrl: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.
|
|
129
|
+
webhookUrl: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodInstanceOf<CensoredString<string>>]>, z.ZodTransform<CensoredString<string>, string | CensoredString<string>>>;
|
|
130
130
|
alertsOnly: z.ZodOptional<z.ZodPipe<z.ZodAny, z.ZodTransform<boolean, any>>>;
|
|
131
131
|
}, z.core.$strip>;
|
|
132
|
-
type SlackConfig = z.infer<typeof SlackConfig>;
|
|
133
|
-
declare const NotificationConfig: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
132
|
+
export type SlackConfig = z.infer<typeof SlackConfig>;
|
|
133
|
+
export declare const NotificationConfig: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
134
134
|
type: z.ZodLiteral<"telegram">;
|
|
135
|
-
token: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.
|
|
136
|
-
alertsChannel: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.
|
|
137
|
-
notificationsChannel: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.
|
|
135
|
+
token: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodInstanceOf<CensoredString<string>>]>, z.ZodTransform<CensoredString<string>, string | CensoredString<string>>>;
|
|
136
|
+
alertsChannel: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodInstanceOf<CensoredString<string>>]>, z.ZodTransform<CensoredString<string>, string | CensoredString<string>>>;
|
|
137
|
+
notificationsChannel: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodInstanceOf<CensoredString<string>>]>, z.ZodTransform<CensoredString<string>, string | CensoredString<string>>>>;
|
|
138
138
|
prefix: z.ZodOptional<z.ZodString>;
|
|
139
139
|
}, z.core.$strip>, z.ZodObject<{
|
|
140
140
|
type: z.ZodLiteral<"slack">;
|
|
141
|
-
webhookUrl: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.
|
|
141
|
+
webhookUrl: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodInstanceOf<CensoredString<string>>]>, z.ZodTransform<CensoredString<string>, string | CensoredString<string>>>;
|
|
142
142
|
alertsOnly: z.ZodOptional<z.ZodPipe<z.ZodAny, z.ZodTransform<boolean, any>>>;
|
|
143
143
|
}, z.core.$strip>], "type">;
|
|
144
|
-
type NotificationConfig = z.infer<typeof NotificationConfig>;
|
|
145
|
-
declare const SignlConfig: z.ZodObject<{
|
|
146
|
-
apiKey: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.
|
|
147
|
-
teamId: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.
|
|
144
|
+
export type NotificationConfig = z.infer<typeof NotificationConfig>;
|
|
145
|
+
export declare const SignlConfig: z.ZodObject<{
|
|
146
|
+
apiKey: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodInstanceOf<CensoredString<string>>]>, z.ZodTransform<CensoredString<string>, string | CensoredString<string>>>;
|
|
147
|
+
teamId: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodInstanceOf<CensoredString<string>>]>, z.ZodTransform<CensoredString<string>, string | CensoredString<string>>>;
|
|
148
148
|
}, z.core.$strip>;
|
|
149
|
-
type SignlConfig = z.infer<typeof SignlConfig>;
|
|
149
|
+
export type SignlConfig = z.infer<typeof SignlConfig>;
|
|
150
150
|
//#endregion
|
|
151
151
|
//#region src/notifications/types.d.ts
|
|
152
|
-
type NotificationSeverity = "alert" | "notification";
|
|
152
|
+
export type NotificationSeverity = "alert" | "notification";
|
|
153
153
|
/**
|
|
154
154
|
* Notification that can be deduplicated
|
|
155
155
|
*/
|
|
156
|
-
interface IDedupableNotification {
|
|
156
|
+
export interface IDedupableNotification {
|
|
157
157
|
/**
|
|
158
158
|
* Messages with the same dedupe key will be throttled to avoid spam
|
|
159
159
|
* If not provided, the message will not be throttled
|
|
@@ -178,11 +178,11 @@ interface IDedupableNotification {
|
|
|
178
178
|
* @param prevWaitMs The wait time of the previous message, 0 for the first message
|
|
179
179
|
* @returns The wait time for the next message in milliseconds
|
|
180
180
|
*/
|
|
181
|
-
type ThrottleFn = (prevWaitMs: number) => number;
|
|
181
|
+
export type ThrottleFn = (prevWaitMs: number) => number;
|
|
182
182
|
/**
|
|
183
183
|
* Implement this interface for your notification classes
|
|
184
184
|
*/
|
|
185
|
-
interface INotification {
|
|
185
|
+
export interface INotification {
|
|
186
186
|
/**
|
|
187
187
|
* Function to generate the message for a recipient. Undefined means global message (gearbox notifications)
|
|
188
188
|
* This allows us to put the logic to fan out message to different recipients inside the class that implements INotificationMessage,
|
|
@@ -196,11 +196,11 @@ interface INotification {
|
|
|
196
196
|
/**
|
|
197
197
|
* A notification message, dumb strings and markdowns are treated as global notifications
|
|
198
198
|
*/
|
|
199
|
-
type NotificationLike = string | IDedupableNotification | INotification;
|
|
199
|
+
export type NotificationLike = string | IDedupableNotification | INotification;
|
|
200
200
|
/**
|
|
201
201
|
* Notification service with deduplication and fan out logic
|
|
202
202
|
*/
|
|
203
|
-
interface INotificationService {
|
|
203
|
+
export interface INotificationService {
|
|
204
204
|
/**
|
|
205
205
|
* Send an alert to Signl
|
|
206
206
|
* @param message
|
|
@@ -229,7 +229,7 @@ interface INotificationService {
|
|
|
229
229
|
*/
|
|
230
230
|
registerRecipient: (address: Address, options: NotificationConfig) => void;
|
|
231
231
|
}
|
|
232
|
-
interface INotifier {
|
|
232
|
+
export interface INotifier {
|
|
233
233
|
/**
|
|
234
234
|
* Sends notification
|
|
235
235
|
* @param message
|
|
@@ -239,7 +239,7 @@ interface INotifier {
|
|
|
239
239
|
}
|
|
240
240
|
//#endregion
|
|
241
241
|
//#region src/notifications/createNotifier.d.ts
|
|
242
|
-
declare function createNotifier(config: NotificationConfig, logger?: ILogger): INotifier | undefined;
|
|
242
|
+
export declare function createNotifier(config: NotificationConfig, logger?: ILogger): INotifier | undefined;
|
|
243
243
|
//#endregion
|
|
244
244
|
//#region src/notifications/SignlNotifier.d.ts
|
|
245
245
|
type SignlServiceOptions = SignlConfig & {
|
|
@@ -249,13 +249,13 @@ type SignlServiceOptions = SignlConfig & {
|
|
|
249
249
|
};
|
|
250
250
|
//#endregion
|
|
251
251
|
//#region src/notifications/NotificationsService.d.ts
|
|
252
|
-
interface NotificationsServiceOptions {
|
|
252
|
+
export interface NotificationsServiceOptions {
|
|
253
253
|
notifications: Array<NotificationConfig & {
|
|
254
254
|
recipient?: Address;
|
|
255
255
|
}>;
|
|
256
256
|
signl?: SignlServiceOptions;
|
|
257
257
|
}
|
|
258
|
-
declare class NotificationsService implements INotificationService {
|
|
258
|
+
export declare class NotificationsService implements INotificationService {
|
|
259
259
|
#private;
|
|
260
260
|
constructor(options: NotificationsServiceOptions, logger?: ILogger);
|
|
261
261
|
registerRecipient(address: Address, options: NotificationConfig): void;
|
|
@@ -265,14 +265,14 @@ declare class NotificationsService implements INotificationService {
|
|
|
265
265
|
}
|
|
266
266
|
//#endregion
|
|
267
267
|
//#region src/providers.d.ts
|
|
268
|
-
declare function getAlchemyUrl(network: NetworkType, apiKey: string, protocol?: "http" | "ws"): string | undefined;
|
|
269
|
-
declare function getDrpcUrl(network: NetworkType, apiKey: string, protocol?: "http" | "ws"): string | undefined;
|
|
270
|
-
declare function getAnkrUrl(network: NetworkType, apiKey: string, protocol?: "http" | "ws"): string | undefined;
|
|
271
|
-
declare function getThirdWebUrl(network: NetworkType, apiKey: string, protocol?: "http" | "ws"): string | undefined;
|
|
272
|
-
declare function getErpcKey(network: NetworkType, projectId?: string, urlBase?: string): string | undefined;
|
|
268
|
+
export declare function getAlchemyUrl(network: NetworkType, apiKey: string, protocol?: "http" | "ws"): string | undefined;
|
|
269
|
+
export declare function getDrpcUrl(network: NetworkType, apiKey: string, protocol?: "http" | "ws"): string | undefined;
|
|
270
|
+
export declare function getAnkrUrl(network: NetworkType, apiKey: string, protocol?: "http" | "ws"): string | undefined;
|
|
271
|
+
export declare function getThirdWebUrl(network: NetworkType, apiKey: string, protocol?: "http" | "ws"): string | undefined;
|
|
272
|
+
export declare function getErpcKey(network: NetworkType, projectId?: string, urlBase?: string): string | undefined;
|
|
273
273
|
//#endregion
|
|
274
274
|
//#region src/resolveYamlFiles.d.ts
|
|
275
|
-
type TemplateData = Record<string, unknown>;
|
|
275
|
+
export type TemplateData = Record<string, unknown>;
|
|
276
276
|
/**
|
|
277
277
|
* Merges yaml files, respecting .extends references.
|
|
278
278
|
* Performs env variable substitution on the config.
|
|
@@ -284,7 +284,7 @@ type TemplateData = Record<string, unknown>;
|
|
|
284
284
|
* @param templateData
|
|
285
285
|
* @returns
|
|
286
286
|
*/
|
|
287
|
-
declare function resolveYamlFiles(file: string, templateData?: TemplateData): Promise<object>;
|
|
287
|
+
export declare function resolveYamlFiles(file: string, templateData?: TemplateData): Promise<object>;
|
|
288
288
|
/**
|
|
289
289
|
* Merges yaml documents, respecting .extends references.
|
|
290
290
|
* Optionally, performs env-style variable substitution on the config.
|
|
@@ -295,7 +295,7 @@ declare function resolveYamlFiles(file: string, templateData?: TemplateData): Pr
|
|
|
295
295
|
* @param templateData
|
|
296
296
|
* @returns
|
|
297
297
|
*/
|
|
298
|
-
declare function resolveYamlDoc(file: string, templateData?: TemplateData): Promise<YAML.Document>;
|
|
298
|
+
export declare function resolveYamlDoc(file: string, templateData?: TemplateData): Promise<YAML.Document>;
|
|
299
299
|
/**
|
|
300
300
|
* Helper function that gets object with templated values
|
|
301
301
|
* Just because async ast already exists in yaml, but not in json reviver
|
|
@@ -303,38 +303,38 @@ declare function resolveYamlDoc(file: string, templateData?: TemplateData): Prom
|
|
|
303
303
|
* @param templateData
|
|
304
304
|
* @returns
|
|
305
305
|
*/
|
|
306
|
-
declare function resolveFromObject(json: object, templateData?: TemplateData): Promise<object>;
|
|
306
|
+
export declare function resolveFromObject(json: object, templateData?: TemplateData): Promise<object>;
|
|
307
307
|
/**
|
|
308
308
|
* Given file and a relative file path, returns full path of the relative file
|
|
309
309
|
* Supports s3 links for base file
|
|
310
310
|
* @param file
|
|
311
311
|
* @param relativeFile
|
|
312
312
|
*/
|
|
313
|
-
declare function getRelativePath(baseFile: string, relativeFile: string): string;
|
|
313
|
+
export declare function getRelativePath(baseFile: string, relativeFile: string): string;
|
|
314
314
|
//#endregion
|
|
315
315
|
//#region src/SecretsManager.d.ts
|
|
316
|
-
declare class SecretsManager {
|
|
316
|
+
export declare class SecretsManager {
|
|
317
317
|
#private;
|
|
318
318
|
secret(key: string): Promise<string>;
|
|
319
319
|
secretRaw(key: string): Promise<unknown>;
|
|
320
320
|
}
|
|
321
|
-
declare const secretsManagerProxy: (mgr?: SecretsManager) => Record<string, Promise<unknown>>;
|
|
321
|
+
export declare const secretsManagerProxy: (mgr?: SecretsManager) => Record<string, Promise<unknown>>;
|
|
322
322
|
//#endregion
|
|
323
323
|
//#region src/SSMManager.d.ts
|
|
324
|
-
declare class SSMManager {
|
|
324
|
+
export declare class SSMManager {
|
|
325
325
|
#private;
|
|
326
326
|
parameter(name: string): Promise<string>;
|
|
327
327
|
}
|
|
328
|
-
declare const ssmManagerProxy: (mgr?: SSMManager) => Record<string, Promise<unknown>>;
|
|
328
|
+
export declare const ssmManagerProxy: (mgr?: SSMManager) => Record<string, Promise<unknown>>;
|
|
329
329
|
//#endregion
|
|
330
330
|
//#region src/sleep.d.ts
|
|
331
|
-
declare function sleep(ms: number): Promise<unknown>;
|
|
331
|
+
export declare function sleep(ms: number): Promise<unknown>;
|
|
332
332
|
//#endregion
|
|
333
333
|
//#region src/uncensorMap.d.ts
|
|
334
|
-
interface IValue<V extends string = string> {
|
|
334
|
+
export interface IValue<V extends string = string> {
|
|
335
335
|
value: V;
|
|
336
336
|
}
|
|
337
|
-
declare function uncensorMap<V extends string = string>(map: Record<string, IValue<V>>): Record<string, V>;
|
|
337
|
+
export declare function uncensorMap<V extends string = string>(map: Record<string, IValue<V>>): Record<string, V>;
|
|
338
338
|
//#endregion
|
|
339
339
|
//#region src/Whitelist.d.ts
|
|
340
340
|
/**
|
|
@@ -343,8 +343,8 @@ declare function uncensorMap<V extends string = string>(map: Record<string, IVal
|
|
|
343
343
|
* - `soft`: entries come from the remote endpoint, do not block the action,
|
|
344
344
|
* but can be used to annotate notifications when the action fails.
|
|
345
345
|
*/
|
|
346
|
-
type WhitelistMode = "soft" | "hard";
|
|
347
|
-
interface WhitelistOptions {
|
|
346
|
+
export type WhitelistMode = "soft" | "hard";
|
|
347
|
+
export interface WhitelistOptions {
|
|
348
348
|
/**
|
|
349
349
|
* Full URL of the remote (soft) whitelist endpoint. When omitted, only the
|
|
350
350
|
* static hard whitelist is used.
|
|
@@ -366,7 +366,7 @@ interface WhitelistOptions {
|
|
|
366
366
|
* On soft fetch failure the previous in-memory copy is retained; if no
|
|
367
367
|
* successful fetch has occurred yet the soft whitelist is considered empty.
|
|
368
368
|
*/
|
|
369
|
-
declare class Whitelist {
|
|
369
|
+
export declare class Whitelist {
|
|
370
370
|
#private;
|
|
371
371
|
constructor({ url, network, hard, logger }: WhitelistOptions);
|
|
372
372
|
/**
|
|
@@ -385,12 +385,12 @@ declare class Whitelist {
|
|
|
385
385
|
}
|
|
386
386
|
//#endregion
|
|
387
387
|
//#region src/Zommand.d.ts
|
|
388
|
-
declare const zommandRegistry: z4.$ZodRegistry<{
|
|
388
|
+
export declare const zommandRegistry: z4.$ZodRegistry<{
|
|
389
389
|
flags: string;
|
|
390
390
|
env?: string;
|
|
391
391
|
description?: string;
|
|
392
392
|
}, z4.$ZodType<unknown, unknown, z4.$ZodTypeInternals<unknown, unknown>>>;
|
|
393
|
-
interface ZommandOptions<T extends z4.$ZodTypes> {
|
|
393
|
+
export interface ZommandOptions<T extends z4.$ZodTypes> {
|
|
394
394
|
schema: T;
|
|
395
395
|
templateData?: TemplateData;
|
|
396
396
|
/**
|
|
@@ -402,11 +402,11 @@ interface ZommandOptions<T extends z4.$ZodTypes> {
|
|
|
402
402
|
*/
|
|
403
403
|
inlineConfig?: boolean;
|
|
404
404
|
}
|
|
405
|
-
declare class Zommand<T extends z4.$ZodTypes, Args extends any[] = []> extends Command<Args, z4.output<T>> {
|
|
405
|
+
export declare class Zommand<T extends z4.$ZodTypes, Args extends any[] = []> extends Command<Args, z4.output<T>> {
|
|
406
406
|
#private;
|
|
407
407
|
constructor(name: string, opts: ZommandOptions<T>);
|
|
408
408
|
action(fn: (this: this, ...args: [...Args, z4.output<T>, this]) => void | Promise<void>): this;
|
|
409
409
|
}
|
|
410
410
|
//#endregion
|
|
411
|
-
export {
|
|
411
|
+
export { ClientWhitelistItem, WhitelistItem, WhitelistItems, addressArrayLike, addressLike, boolLike, clientWhitelistItemSchema, optionalAddressArrayLike, optionalStringArrayLike, stringArrayLike, whitelistItemSchema, whitelistItemsSchema };
|
|
412
412
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/CensoredString.ts","../src/CensoredURL.ts","../src/compressedConfig.ts","../src/createPinoCensor.ts","../src/fetchRetry.ts","../src/providers-schema.ts","../src/getFirstHttpTransportOptions.ts","../src/getProviders.ts","../src/notifications/schema.ts","../src/notifications/types.ts","../src/notifications/createNotifier.ts","../src/notifications/SignlNotifier.ts","../src/notifications/NotificationsService.ts","../src/providers.ts","../src/resolveYamlFiles.ts","../src/SecretsManager.ts","../src/SSMManager.ts","../src/sleep.ts","../src/uncensorMap.ts","../src/Whitelist.ts","../src/Zommand.ts"],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/CensoredString.ts","../src/CensoredURL.ts","../src/compressedConfig.ts","../src/createPinoCensor.ts","../src/fetchRetry.ts","../src/providers-schema.ts","../src/getFirstHttpTransportOptions.ts","../src/getProviders.ts","../src/notifications/schema.ts","../src/notifications/types.ts","../src/notifications/createNotifier.ts","../src/notifications/SignlNotifier.ts","../src/notifications/NotificationsService.ts","../src/providers.ts","../src/resolveYamlFiles.ts","../src/SecretsManager.ts","../src/SSMManager.ts","../src/sleep.ts","../src/uncensorMap.ts","../src/Whitelist.ts","../src/Zommand.ts"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { readFile } from "node:fs/promises";
|
|
|
4
4
|
import { dirname, resolve } from "node:path";
|
|
5
5
|
import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
|
6
6
|
import YAML, { isPair, isScalar, isSeq } from "yaml";
|
|
7
|
-
import { ADDRESS_0X0, AddressMap, SUPPORTED_NETWORKS, chains, getChain } from "@gearbox-protocol/sdk";
|
|
7
|
+
import { ADDRESS_0X0, AddressMap, SUPPORTED_NETWORKS, chains, getChain } from "@gearbox-protocol/sdk/onchain";
|
|
8
8
|
import { prettifyError } from "zod";
|
|
9
9
|
import { z } from "zod/v4";
|
|
10
10
|
import { withRetry } from "viem";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#value","#censored","#value","#censored","pathResolve","DEFAULT_RETRY_INTERVAL","#config","#logger","#sendToSlack","#getState","#state","DEFAULT_RETRY_INTERVAL","DEFAULT_RETRY_COUNT","#logger","#alertsChannel","#notificationsChannel","#botToken","#prefix","#retryInterval","#retryCount","#maxChunkSize","#fetchFn","#queue","#throttleManager","#enqueueTelegram","#toTelegramPayloads","#sendToTelegram","#slicePlainText","#logger","#apiKey","#teamId","#retryInterval","#retryCount","#throttleManager","#throttleFn","#sendAlert","#logger","#notifiers","#signlNotifier","#notify","#toNotification","#toDedupableNotification","#schema","#templatedData","#addOptionsFromObject","#envToObjectKeys","#getSecret","#secrets","#smClient","#parameters","#ssmClient","#url","#network","#logger","#hard","#refresh","#refreshInterval","#soft"],"sources":["../src/CensoredString.ts","../src/CensoredURL.ts","../src/getPromisePath.ts","../src/resolveYamlFiles.ts","../src/compressedConfig.ts","../src/createPinoCensor.ts","../src/sleep.ts","../src/fetchRetry.ts","../src/providers.ts","../src/getProviders.ts","../src/getFirstHttpTransportOptions.ts","../src/notifications/SlackNotifier.ts","../src/notifications/schema.ts","../src/notifications/ThrottleManager.ts","../src/notifications/TelegramNotifier.ts","../src/notifications/createNotifier.ts","../src/notifications/SignlNotifier.ts","../src/notifications/NotificationsService.ts","../src/Zommand.ts","../src/providers-schema.ts","../src/SecretsManager.ts","../src/SSMManager.ts","../src/uncensorMap.ts","../src/Whitelist.ts"],"sourcesContent":["export class CensoredString<V extends string = string> {\n readonly #value: V;\n readonly #censored: string;\n\n public static transform<T extends string>(\n value: T | CensoredString<T>,\n ): CensoredString<T> {\n if (value instanceof CensoredString) {\n return value;\n }\n return new CensoredString(value);\n }\n\n constructor(value: V) {\n this.#value = value;\n const visibleLen = Math.min(4, Math.floor(0.2 * value.length));\n if (visibleLen < 1) {\n this.#censored = \"*\".repeat(Math.min(8, value.length));\n } else {\n this.#censored =\n \"*\".repeat(Math.min(8, value.length - visibleLen)) +\n value.slice(-1 * visibleLen);\n }\n }\n\n public get value(): V {\n return this.#value;\n }\n\n public toString(): string {\n return this.#censored;\n }\n\n public toJSON(): string {\n return this.toString();\n }\n}\n","/**\n * Assumes that host is always visible, and the secret part is in path or query\n */\nexport class CensoredURL {\n readonly #value: string;\n readonly #censored: string;\n\n public static transform(value: string | CensoredURL): CensoredURL {\n if (value instanceof CensoredURL) {\n return value;\n }\n return new CensoredURL(value);\n }\n\n constructor(url: string) {\n this.#value = url;\n if (\n url.includes(\"127.0.0.1\") ||\n url.includes(\"localhost\") ||\n url.includes(\"host.docker.internal\")\n ) {\n this.#censored = url;\n } else {\n try {\n const u = new URL(url);\n if (u.username || u.password) {\n u.username = u.username ? \"****\" : \"\";\n u.password = u.password ? \"****\" : \"\";\n }\n u.pathname = \"/\";\n u.search = \"\";\n this.#censored = `${u.href}******`;\n } catch {\n const visibleLen = Math.min(4, Math.floor(0.2 * url.length));\n if (visibleLen < 1) {\n this.#censored = \"*\".repeat(Math.min(8, url.length));\n } else {\n this.#censored =\n \"*\".repeat(Math.min(8, url.length - visibleLen)) +\n url.slice(-1 * visibleLen);\n }\n }\n }\n }\n\n public get value(): string {\n return this.#value;\n }\n\n public toString(): string {\n return this.#censored;\n }\n\n public toJSON(): string {\n return this.toString();\n }\n}\n","/**\n * Similar to lodash.get, but supports promises\n * @param object\n * @param keys\n * @returns\n */\nexport default async function getPromisePath<V = any>(\n object: any,\n path: string,\n): Promise<V> {\n return getPromised(object, path.split(\".\"));\n}\n\nasync function getPromised<V = any>(object: any, keys: string[]): Promise<V> {\n if (keys.length === 0) {\n return Promise.resolve(object);\n }\n const [key, ...rest] = keys;\n const value = object[key];\n const resolved = await Promise.resolve(value);\n return getPromised(resolved, rest);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { dirname, resolve as pathResolve } from \"node:path\";\nimport { GetObjectCommand, S3Client } from \"@aws-sdk/client-s3\";\nimport YAML, { isPair, isScalar, isSeq } from \"yaml\";\nimport getPromisePath from \"./getPromisePath.js\";\n\nexport type TemplateData = Record<string, unknown>;\n\n/**\n * Template key regexp\n * Consists of alphanumeric+underscore parts separated by dots, all wrappped in env-style brackets\n * e.g. ${KEY} or ${KEY.SUBKEY}\n *\n * Optionally supports a bash-style default value via `:-`, e.g. `${KEY:-fallback}`.\n * The default is used when the resolved value is undefined, null, or an empty string.\n * Capture groups: 1 = key path, 2 = optional default literal (no `}` allowed).\n */\nconst templateKeyRegex = /\\$\\{([\\w-]+(?:\\.[\\w-]+)*)(?::-([^}]*))?\\}/g;\n\n/**\n * Replaces all `${...}` template tokens in a string using the provided template data.\n * Supports bash-style `${KEY:-default}` fallback when the resolved value is missing\n * (undefined, null, or empty string). The default is a literal and is not further\n * interpolated.\n */\nasync function resolveScalarValue(\n val: string,\n templateData?: TemplateData,\n): Promise<string> {\n const matches = val.matchAll(templateKeyRegex);\n for (const match of matches) {\n const [whole, key, defaultValue] = match;\n const resolved = await getPromisePath(templateData, key);\n if (resolved !== undefined && resolved !== null && resolved !== \"\") {\n val = val.replace(whole, String(resolved));\n } else if (defaultValue !== undefined) {\n val = val.replace(whole, defaultValue);\n }\n }\n return val;\n}\n\n/**\n * Merges yaml files, respecting .extends references.\n * Performs env variable substitution on the config.\n * Respects YAML anchors and aliases, and merge keys - so that they can be shared across two files\n *\n * x-* anchors are removed from resulting document (a-la docker compose yaml)\n *\n * @param file\n * @param templateData\n * @returns\n */\nexport async function resolveYamlFiles(\n file: string,\n templateData?: TemplateData,\n): Promise<object> {\n const doc = await resolveYamlDoc(file, templateData);\n const obj = doc.toJSON();\n return Object.fromEntries(\n Object.entries(obj).filter(([k]) => !k.startsWith(\"x-\")),\n );\n}\n\n/**\n * Merges yaml documents, respecting .extends references.\n * Optionally, performs env-style variable substitution on the config.\n * Respects YAML anchors and aliases, and merge keys - so that they can be shared across two files\n * Supports s3 links for file\n *\n * @param file\n * @param templateData\n * @returns\n */\nexport async function resolveYamlDoc(\n file: string,\n templateData?: TemplateData,\n): Promise<YAML.Document> {\n const content = await loadFile(file);\n // if (templateData) {\n // const compiled = template(content);\n // content = compiled(templateData);\n // }\n let cfgRaw: YAML.Document = YAML.parseDocument(content, { merge: true });\n // let cfgRaw = YAML.parse(content, { merge: true });\n if (cfgRaw.has(\"extends\")) {\n const baseFile = cfgRaw.get(\"extends\") as string;\n const extended = cfgRaw;\n // extends is a relative path to the base file\n cfgRaw = await resolveYamlDoc(\n getRelativePath(file, baseFile),\n templateData,\n );\n YAML.visit(extended, {\n Pair(_, pair, rawPath) {\n const path = getNodesPath(rawPath);\n if (isScalar(pair.key) && (isScalar(pair.value) || isSeq(pair.value))) {\n if (pair.key.value === \"extends\") {\n return;\n }\n cfgRaw.setIn([...path, pair.key.value], pair.value);\n return YAML.visit.SKIP;\n }\n },\n });\n }\n\n await YAML.visitAsync(cfgRaw, {\n Scalar: async (_, node) => {\n if (typeof node.value === \"string\") {\n node.value = await resolveScalarValue(node.value, templateData);\n }\n },\n });\n\n return cfgRaw;\n}\n\n/**\n * Helper function that gets object with templated values\n * Just because async ast already exists in yaml, but not in json reviver\n * @param json\n * @param templateData\n * @returns\n */\nexport async function resolveFromObject(\n json: object,\n templateData?: TemplateData,\n): Promise<object> {\n const content = YAML.stringify(json);\n const cfgRaw: YAML.Document = YAML.parseDocument(content, { merge: true });\n\n await YAML.visitAsync(cfgRaw, {\n Scalar: async (_, node) => {\n if (typeof node.value === \"string\") {\n node.value = await resolveScalarValue(node.value, templateData);\n }\n },\n });\n\n return cfgRaw.toJSON();\n}\n\nfunction getNodesPath(\n nodes: readonly (YAML.Node | YAML.Document | YAML.Pair)[],\n): unknown[] {\n return nodes\n .map(n => {\n if (isPair(n) && isScalar(n.key)) {\n return n.key.value;\n }\n return \"\";\n })\n .filter(Boolean);\n}\n\n/**\n * Loads file from s3 or local file system\n * @param file - s3 link or local file path\n * @returns file content\n */\nasync function loadFile(file: string): Promise<string> {\n if (file.startsWith(\"s3://\")) {\n return await loadS3File(file);\n }\n return await readFile(file, \"utf-8\");\n}\n\n/**\n * Loads file from s3\n * @param file - s3 link like s3://bucket/path/to/file.yaml\n * @returns file content\n */\nasync function loadS3File(file: string): Promise<string> {\n const url = new URL(file);\n const bucket = url.hostname;\n const key = url.pathname.slice(1);\n\n const s3 = new S3Client({});\n const response = await s3.send(\n new GetObjectCommand({\n Bucket: bucket,\n Key: key,\n }),\n );\n if (!response.Body) {\n throw new Error(`file ${file} not found`);\n }\n return response.Body.transformToString(\"utf-8\");\n}\n\n/**\n * Given file and a relative file path, returns full path of the relative file\n * Supports s3 links for base file\n * @param file\n * @param relativeFile\n */\nexport function getRelativePath(\n baseFile: string,\n relativeFile: string,\n): string {\n if (baseFile.startsWith(\"s3://\")) {\n const url = new URL(baseFile);\n const relPathname = pathResolve(dirname(url.pathname), relativeFile);\n url.pathname = relPathname;\n return url.toString();\n }\n return pathResolve(dirname(baseFile), relativeFile);\n}\n","import { deflateSync, inflateSync } from \"node:zlib\";\nimport { resolveFromObject } from \"./resolveYamlFiles.js\";\n\n/**\n * Compress a plain JS object into a base64url string\n * suitable for env vars.\n */\nexport function compressObject(obj: unknown): string {\n const json = JSON.stringify(obj);\n const compressed = deflateSync(Buffer.from(json, \"utf8\"));\n return compressed.toString(\"base64url\");\n}\n\n/**\n * Decompress a base64url string back into a JS object\n * Allows to pass template data to resolve promises/env\n */\nexport async function decompressObject<T = unknown>(\n value: string,\n templateData?: Record<string, unknown>,\n): Promise<T> {\n const compressed = Buffer.from(value, \"base64url\");\n const str = inflateSync(compressed).toString(\"utf8\");\n const json = JSON.parse(str);\n const result = await resolveFromObject(json, templateData);\n return result as T;\n}\n","import { CensoredString } from \"./CensoredString.js\";\nimport { CensoredURL } from \"./CensoredURL.js\";\n\n/**\n * Raw values shorter than this are not censored, to avoid masking unrelated\n * substrings throughout the log output.\n */\nconst MIN_SECRET_LENGTH = 4;\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction collectSecrets(value: unknown, out: Map<string, string>): void {\n if (value == null) {\n return;\n }\n if (value instanceof CensoredString || value instanceof CensoredURL) {\n const raw = value.value;\n if (raw.length >= MIN_SECRET_LENGTH) {\n out.set(raw, value.toString());\n }\n return;\n }\n if (typeof value !== \"object\") {\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n collectSecrets(item, out);\n }\n return;\n }\n for (const item of Object.values(value)) {\n collectSecrets(item, out);\n }\n}\n\n/**\n * Gathers known secrets from a config and returns a function that replaces each raw secret with its masked representation.\n * Intended for pino's `hooks.streamWrite`\n */\nexport function createPinoCensor(config: unknown): (s: string) => string {\n const map = new Map<string, string>();\n collectSecrets(config, map);\n if (map.size === 0) {\n return s => s;\n }\n // Longer secrets first so a secret that is a substring of another does not\n // shadow the longer match.\n const pattern = [...map.keys()]\n .sort((a, b) => b.length - a.length)\n .map(escapeRegExp)\n .join(\"|\");\n const re = new RegExp(pattern, \"g\");\n return s => s.replace(re, m => map.get(m) ?? m);\n}\n","// Mirror of packages/shared/src/sleep.ts; keep in sync.\nexport async function sleep(ms: number) {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n","// Mirror of packages/shared/src/fetchRetry.ts; keep in sync.\nimport { sleep } from \"./sleep.js\";\n\nconst DEFAULT_RETRIES = 5;\nconst DEFAULT_RETRY_INTERVAL = 1000;\n\ninterface RetrySettings {\n retries?: number;\n retryInterval?: number;\n validateResponse?: (response: Response) => void;\n}\n\nexport async function fetchRetry(\n input: string | URL,\n init: RequestInit & RetrySettings = {},\n): Promise<Response> {\n const {\n retries = DEFAULT_RETRIES,\n retryInterval = DEFAULT_RETRY_INTERVAL,\n validateResponse,\n ...options\n } = init;\n try {\n const response = await fetch(input, options);\n validateResponse?.(response);\n return response;\n } catch (e: any) {\n if (retries > 0) {\n await sleep(retryInterval);\n return fetchRetry(input, {\n ...options,\n retries: retries - 1,\n retryInterval,\n validateResponse,\n });\n } else {\n throw e;\n }\n }\n}\n","import { chains, getChain, type NetworkType } from \"@gearbox-protocol/sdk\";\n\nexport function getAlchemyUrl(\n network: NetworkType,\n apiKey: string,\n protocol: \"http\" | \"ws\" = \"http\",\n): string | undefined {\n const alchemyDomain = ALCHEMY_DOMAINS[network];\n if (!alchemyDomain) {\n return undefined;\n }\n return `${protocol}s://${alchemyDomain}.g.alchemy.com/v2/${apiKey}`;\n}\n\nconst DRPC_NETS: Record<NetworkType, string | null> = {\n Arbitrum: \"arbitrum\",\n Base: \"base\",\n BNB: \"bsc\",\n Mainnet: \"ethereum\",\n Optimism: \"optimism\",\n Sonic: \"sonic\",\n WorldChain: \"worldchain\",\n Berachain: \"berachain\",\n Avalanche: \"avalanche\",\n Monad: \"monad\",\n Hemi: \"hemi\",\n Lisk: \"lisk\",\n MegaETH: null,\n Etherlink: null,\n Plasma: \"plasma\",\n Somnia: null,\n};\n\nconst ALCHEMY_DOMAINS: Record<NetworkType, string | null> = {\n Mainnet: \"eth-mainnet\",\n Arbitrum: \"arb-mainnet\",\n Optimism: \"opt-mainnet\",\n Base: \"base-mainnet\",\n Sonic: \"sonic-mainnet\",\n Monad: \"monad-mainnet\",\n Berachain: \"berachain-mainnet\",\n Avalanche: \"avax-mainnet\",\n BNB: \"bnb-mainnet\",\n WorldChain: \"worldchain-mainnet\",\n MegaETH: null,\n Etherlink: null,\n Hemi: null,\n Lisk: null,\n Plasma: \"plasma-mainnet\",\n Somnia: null,\n};\n\nexport function getDrpcUrl(\n network: NetworkType,\n apiKey: string,\n protocol: \"http\" | \"ws\" = \"http\",\n): string | undefined {\n const net = DRPC_NETS[network];\n return net ? `${protocol}s://lb.drpc.org/${net}/${apiKey}` : undefined;\n}\n\nconst ANKR_DOMAINS: Record<NetworkType, string | null> = {\n Arbitrum: \"arbitrum\",\n Avalanche: \"avalanche\",\n Base: \"base\",\n Berachain: null,\n BNB: \"bsc\",\n Etherlink: \"etherlink_mainnet\",\n Hemi: null,\n Lisk: null,\n Mainnet: \"eth\",\n MegaETH: null,\n Monad: null,\n Optimism: \"optimism\",\n Plasma: null,\n Sonic: \"sonic_mainnet\",\n WorldChain: null,\n Somnia: \"somnia_mainnet\",\n};\n\nexport function getAnkrUrl(\n network: NetworkType,\n apiKey: string,\n protocol: \"http\" | \"ws\" = \"http\",\n): string | undefined {\n const net = ANKR_DOMAINS[network];\n const sep = protocol === \"ws\" ? \"/ws/\" : \"/\";\n return net ? `${protocol}s://rpc.ankr.com/${net}${sep}${apiKey}` : undefined;\n}\n\nconst THIRDWEB_DOMAINS: Record<NetworkType, string | null> = {\n Arbitrum: chains.Arbitrum.id.toString(),\n Avalanche: chains.Avalanche.id.toString(),\n Base: chains.Base.id.toString(),\n Berachain: chains.Berachain.id.toString(),\n BNB: chains.BNB.id.toString(),\n Etherlink: chains.Etherlink.id.toString(),\n Hemi: chains.Hemi.id.toString(),\n Lisk: chains.Lisk.id.toString(),\n Mainnet: chains.Mainnet.id.toString(),\n MegaETH: chains.MegaETH.id.toString(),\n Monad: chains.Monad.id.toString(),\n Optimism: chains.Optimism.id.toString(),\n Plasma: chains.Plasma.id.toString(),\n Sonic: chains.Sonic.id.toString(),\n WorldChain: chains.WorldChain.id.toString(),\n Somnia: chains.Somnia.id.toString(),\n};\n\nexport function getThirdWebUrl(\n network: NetworkType,\n apiKey: string,\n protocol: \"http\" | \"ws\" = \"http\",\n): string | undefined {\n if (protocol === \"ws\") {\n return undefined;\n }\n const net = THIRDWEB_DOMAINS[network];\n return `https://${net}.rpc.thirdweb.com/${apiKey}`;\n}\n\nexport function getErpcKey(\n network: NetworkType,\n projectId?: string,\n urlBase?: string,\n): string | undefined {\n if (!projectId || !urlBase) {\n return undefined;\n }\n const chain = getChain(network);\n return `${urlBase}/${projectId}/evm/${chain.id}`;\n}\n","import type { ILogger } from \"@gearbox-protocol/sdk\";\nimport type { ProviderConfig } from \"@gearbox-protocol/sdk/dev\";\nimport type { PartialBy } from \"viem\";\nimport { CensoredURL } from \"./CensoredURL.js\";\nimport {\n getAlchemyUrl,\n getAnkrUrl,\n getDrpcUrl,\n getErpcKey,\n getThirdWebUrl,\n} from \"./providers.js\";\nimport type { ProvidersSchema } from \"./providers-schema.js\";\n\nexport function getProviders(\n config: ProvidersSchema,\n logger?: ILogger,\n): ProviderConfig[] {\n const {\n network,\n\n enabledProviders = [\n \"erpc\",\n \"custom\",\n \"drpc\",\n \"alchemy\",\n \"ankr\",\n \"thirdweb\",\n ],\n alchemyKeys = [],\n ankrKeys = [],\n drpcKeys = [],\n thirdwebKeys = [],\n jsonRpcProviders = [],\n\n erpcProjectId,\n erpcUrl,\n } = config;\n const result: PartialBy<ProviderConfig, \"url\">[] = [];\n for (const p of enabledProviders) {\n switch (p) {\n case \"alchemy\":\n result.push(\n ...alchemyKeys.map(k => ({\n name: \"alchemy\",\n url: getAlchemyUrl(network, k.value),\n })),\n );\n break;\n case \"drpc\":\n result.push(\n ...drpcKeys.map(k => ({\n name: \"drpc\",\n url: getDrpcUrl(network, k.value),\n })),\n );\n break;\n case \"ankr\":\n result.push(\n ...ankrKeys.map(k => ({\n name: \"ankr\",\n url: getAnkrUrl(network, k.value),\n })),\n );\n break;\n case \"thirdweb\":\n result.push(\n ...thirdwebKeys.map(k => ({\n name: \"thirdweb\",\n url: getThirdWebUrl(network, k.value),\n })),\n );\n break;\n case \"custom\":\n result.push(\n ...jsonRpcProviders.map((url): ProviderConfig => {\n const urlObj = new URL(url.value);\n const hasCredentials = urlObj.username || urlObj.password;\n\n let cleanUrl = url.value;\n let httpTransportOptions: ProviderConfig[\"httpTransportOptions\"] =\n {};\n\n if (hasCredentials) {\n // Create URL without credentials\n const cleanUrlObj = new URL(url.value);\n cleanUrlObj.username = \"\";\n cleanUrlObj.password = \"\";\n cleanUrl = cleanUrlObj.toString();\n\n // Create Basic Auth header\n const credentials = `${urlObj.username}:${urlObj.password}`;\n const encodedCredentials =\n Buffer.from(credentials).toString(\"base64\");\n\n httpTransportOptions = {\n fetchOptions: {\n headers: {\n Authorization: `Basic ${encodedCredentials}`,\n },\n },\n };\n }\n\n return {\n name: getTopLevelDomain(urlObj),\n url: cleanUrl,\n httpTransportOptions,\n };\n }),\n );\n break;\n case \"erpc\":\n if (erpcProjectId && erpcUrl) {\n result.push({\n name: \"erpc\",\n url: getErpcKey(network, erpcProjectId, erpcUrl),\n });\n }\n break;\n }\n }\n if (logger) {\n const providers = result\n .filter(p => !!p.url)\n .map(p => ({\n name: p.name,\n url: new CensoredURL(p.url!),\n }));\n logger.debug({ providers, network }, \"gathered providers\");\n }\n return result\n .map(p => ({\n ...p,\n httpClientOptions: {\n ...p.httpTransportOptions,\n methods: { exclude: [\"eth_fillTransaction\"] },\n },\n }))\n .filter(p => !!p.url) as ProviderConfig[];\n}\n\n/**\n * Take the last two parts for top-level domain (e.g., \"google.com\" from \"a.b.c.google.com\")\n **/\nfunction getTopLevelDomain({ hostname }: URL): string {\n const parts = hostname.split(\".\");\n return parts.length >= 2 ? parts.slice(-2).join(\".\") : hostname;\n}\n","import type { HttpTransportConfig } from \"viem\";\nimport { getProviders } from \"./getProviders.js\";\nimport type { ProvidersSchema } from \"./providers-schema.js\";\n\nexport interface HttpTransportOptions {\n url?: string | undefined;\n config: HttpTransportConfig;\n}\n\nexport function getFirstHttpTransportOptions(\n config: ProvidersSchema,\n): HttpTransportOptions {\n const [provider] = getProviders(config);\n if (!provider) {\n throw new Error(\"No provider found\");\n }\n return {\n url: provider.url,\n config: {\n ...provider.httpTransportOptions,\n },\n };\n}\n","import type { ILogger } from \"@gearbox-protocol/sdk\";\nimport type { SlackConfig } from \"./schema.js\";\nimport type {\n IDedupableNotification,\n INotifier,\n NotificationSeverity,\n} from \"./types.js\";\n\n// TODO: no throttling or deduplication yet\nexport class SlackNotifier implements INotifier {\n readonly #config: SlackConfig;\n readonly #logger?: ILogger;\n\n constructor(config: SlackConfig, logger?: ILogger) {\n this.#config = config;\n this.#logger = logger;\n }\n\n public notify(\n message: IDedupableNotification,\n severity: NotificationSeverity,\n ): void {\n if (this.#config.alertsOnly && severity === \"notification\") {\n return;\n }\n const emoji = severity === \"alert\" ? \"🚨\" : \"ℹ️\";\n const messageText = typeof message === \"string\" ? message : message.plain;\n\n void this.#sendToSlack(`${emoji} Alert: ${messageText}`);\n }\n\n async #sendToSlack(text: string): Promise<void> {\n try {\n this.#logger?.debug(`Sending message to Slack: ${text}`);\n\n // Use fetch instead of axios to avoid adding dependencies\n const response = await fetch(this.#config.webhookUrl.value, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ text }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n this.#logger?.debug(\"Slack message sent successfully\");\n } catch (error) {\n this.#logger?.error(\"Error sending Slack message:\", error);\n throw error;\n }\n }\n}\n","import { z } from \"zod/v4\";\nimport { CensoredString } from \"../CensoredString.js\";\nimport { boolLike } from \"../schemas/schema-primitives.js\";\n\nexport const TelegramConfig = z.object({\n type: z.literal(\"telegram\"),\n token: z\n .union([z.string(), z.instanceof(CensoredString)])\n .transform(CensoredString.transform),\n alertsChannel: z\n .union([z.string().startsWith(\"-\"), z.instanceof(CensoredString)])\n .transform(CensoredString.transform),\n /**\n * Optional channel to send notifications to\n * If not set, notifications will not be sent\n */\n notificationsChannel: z\n .union([z.string().startsWith(\"-\"), z.instanceof(CensoredString)])\n .transform(CensoredString.transform)\n .optional(),\n prefix: z.string().optional(),\n});\n\nexport type TelegramConfig = z.infer<typeof TelegramConfig>;\n\nexport const SlackConfig = z.object({\n type: z.literal(\"slack\"),\n /**\n * Slack webhook URL for sending notifications\n */\n webhookUrl: z\n .union([z.string(), z.instanceof(CensoredString)])\n .transform(CensoredString.transform),\n /**\n * If true, only alerts will be sent. Informational notifications are suppressed\n */\n alertsOnly: boolLike().optional(),\n});\n\nexport type SlackConfig = z.infer<typeof SlackConfig>;\n\nexport const NotificationConfig = z.discriminatedUnion(\"type\", [\n TelegramConfig,\n SlackConfig,\n]);\n\nexport type NotificationConfig = z.infer<typeof NotificationConfig>;\n\nexport const SignlConfig = z.object({\n apiKey: z\n .union([z.string(), z.instanceof(CensoredString)])\n .transform(CensoredString.transform),\n teamId: z\n .union([z.string(), z.instanceof(CensoredString)])\n .transform(CensoredString.transform),\n});\n\nexport type SignlConfig = z.infer<typeof SignlConfig>;\n","import { LRUCache } from \"lru-cache\";\nimport type { ThrottleFn } from \"./types.js\";\n\ninterface ThrottleState {\n lastAlertTime: number;\n currentWait: number;\n}\n\nexport function defaultBackoffFn(prevWait: number): number {\n return Math.min(\n prevWait ? prevWait * 2 : 10 * 60 * 1000, // 10 minutes\n 24 * 60 * 60 * 1000, // 24 hours\n );\n}\n\n/**\n * Manages per-feed throttling with exponential backoff.\n * Each dedupe key has its own independent throttle timer.\n */\nexport class ThrottleManager {\n #state = new LRUCache<string, ThrottleState>({ max: 5000 });\n\n /**\n * Checks if it's permitted to send a message for the given dedupe key\n * @returns\n */\n public canSend(dedupeKey?: string): boolean {\n if (!dedupeKey) {\n return true;\n }\n const state = this.#getState(dedupeKey);\n const timeSinceLastAlert = Date.now() - state.lastAlertTime;\n return timeSinceLastAlert >= state.currentWait;\n }\n\n /**\n * Records that notification was sent for the given dedupe key\n */\n public onSent(\n dedupeKey?: string,\n throttleFn: ThrottleFn = defaultBackoffFn,\n ): void {\n if (!dedupeKey) {\n return;\n }\n const state = this.#getState(dedupeKey);\n this.#state.set(dedupeKey, {\n lastAlertTime: Date.now(),\n currentWait: throttleFn(state.currentWait),\n });\n }\n\n #getState(dedupeKey: string): ThrottleState {\n return this.#state.get(dedupeKey) ?? { lastAlertTime: 0, currentWait: 0 };\n }\n}\n","import type { ILogger } from \"@gearbox-protocol/sdk\";\nimport { md } from \"@vlad-yakovlev/telegram-md\";\nimport Queue from \"p-queue\";\nimport { withRetry } from \"viem\";\nimport type { TelegramConfig } from \"./schema.js\";\nimport { ThrottleManager } from \"./ThrottleManager.js\";\nimport type {\n IDedupableNotification,\n INotifier,\n NotificationSeverity,\n} from \"./types.js\";\n\nexport type TelegramNotifierOptions = TelegramConfig & {\n retryInterval?: number;\n retryCount?: number;\n maxChunkSize?: number;\n fetchFn?: typeof fetch;\n};\n\ninterface TelegramPayload {\n text: string;\n parse_mode?: \"MarkdownV2\";\n}\n\nconst DEFAULT_RETRY_INTERVAL = 1000;\nconst DEFAULT_RETRY_COUNT = 5;\nconst DEFAULT_MAX_CHUNK_SIZE = 4096;\n\nexport class TelegramNotifier implements INotifier {\n readonly #logger?: ILogger;\n readonly #alertsChannel: string;\n readonly #notificationsChannel?: string;\n readonly #botToken: string;\n readonly #prefix?: string;\n\n readonly #retryInterval: number;\n readonly #retryCount: number;\n readonly #maxChunkSize: number;\n readonly #fetchFn: typeof fetch;\n readonly #queue = new Queue({\n concurrency: 1,\n // https://core.telegram.org/bots/faq#my-bot-is-hitting-limits-how-do-i-avoid-this\n // 20 messages/minute limit\n interval: 60_000,\n intervalCap: 20,\n strict: true,\n });\n readonly #throttleManager = new ThrottleManager();\n\n constructor(opts: TelegramNotifierOptions, logger?: ILogger) {\n this.#logger = logger;\n this.#alertsChannel = opts.alertsChannel.value;\n this.#botToken = opts.token.value;\n this.#notificationsChannel = opts.notificationsChannel?.value;\n this.#prefix = opts.prefix;\n this.#retryInterval = opts.retryInterval ?? DEFAULT_RETRY_INTERVAL;\n this.#retryCount = opts.retryCount ?? DEFAULT_RETRY_COUNT;\n this.#maxChunkSize = opts.maxChunkSize ?? DEFAULT_MAX_CHUNK_SIZE;\n this.#fetchFn = opts.fetchFn ?? fetch;\n }\n\n public notify(\n message: IDedupableNotification,\n severity: NotificationSeverity,\n ): void {\n const dest =\n severity === \"alert\" ? this.#alertsChannel : this.#notificationsChannel;\n if (!dest) {\n return;\n }\n this.#enqueueTelegram(message, dest, severity === \"alert\");\n }\n\n async #enqueueTelegram(\n message: IDedupableNotification,\n channelId: string,\n severe = false,\n ): Promise<void> {\n if (!this.#throttleManager.canSend(message.dedupeKey)) {\n return;\n }\n\n const payloads = this.#toTelegramPayloads(message);\n for (const payload of payloads) {\n this.#queue.add(\n () =>\n this.#sendToTelegram(payload, channelId, severe).catch(e =>\n this.#logger?.error(e),\n ),\n {\n priority: severe ? 100 : 0,\n timeout: this.#retryInterval * this.#retryCount * 2,\n },\n );\n }\n\n this.#throttleManager.onSent(message.dedupeKey, message.throttleFn);\n }\n\n async #sendToTelegram(\n payload: TelegramPayload,\n channelId: string,\n severe = false,\n ): Promise<void> {\n const severity = severe ? \"alert\" : \"notification\";\n this.#logger?.debug(\n `sending telegram ${severity} to channel ${channelId}...`,\n );\n const url = `https://api.telegram.org/bot${this.#botToken}/sendMessage`;\n\n try {\n await withRetry(\n async () => {\n const resp = await this.#fetchFn(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n ...payload,\n chat_id: channelId,\n }),\n });\n if (resp.ok) {\n this.#logger?.debug(`telegram ${severity} sent successfully`);\n } else {\n const txt = await resp.text();\n throw new Error(`api error ${resp.status}: ${txt}`);\n }\n },\n { delay: this.#retryInterval, retryCount: this.#retryCount },\n );\n } catch (e) {\n this.#logger?.error(`cannot send telegram ${severity}: ${e}`);\n }\n }\n\n #toTelegramPayloads(message: IDedupableNotification): TelegramPayload[] {\n const { md: mdMessage, plain } = message;\n if (!mdMessage) {\n return this.#slicePlainText(plain);\n }\n let text = mdMessage;\n if (this.#prefix) {\n text = md.join([md.bold(this.#prefix), text], \" \");\n }\n const mdText = text.toString();\n if (mdText.length > this.#maxChunkSize) {\n return this.#slicePlainText(plain);\n }\n return [{ text: mdText, parse_mode: \"MarkdownV2\" }];\n }\n\n /**\n * Telegram has a limit on message size (default 4096 characters).\n * This function slices the text into chunks respecting the limit.\n * Each chunk is prefixed with the prefix (if set), ensuring the total length <= maxChunkSize.\n * @param text - The text to slice.\n * @returns An array of texts.\n */\n #slicePlainText(text: string): TelegramPayload[] {\n const chunks = [];\n const prefix = this.#prefix ? `${this.#prefix} ` : \"\";\n const maxChunkSize = this.#maxChunkSize - prefix.length;\n\n for (let i = 0; i < text.length; i += maxChunkSize) {\n const chunkText = text.slice(i, i + maxChunkSize);\n chunks.push({ text: `${prefix}${chunkText}` });\n }\n return chunks;\n }\n}\n","import type { ILogger } from \"@gearbox-protocol/sdk\";\nimport { prettifyError } from \"zod\";\nimport { SlackNotifier } from \"./SlackNotifier.js\";\nimport { NotificationConfig } from \"./schema.js\";\nimport { TelegramNotifier } from \"./TelegramNotifier.js\";\nimport type { INotifier } from \"./types.js\";\n\nexport function createNotifier(\n config: NotificationConfig,\n logger?: ILogger,\n): INotifier | undefined {\n const parsed = NotificationConfig.safeParse(config);\n if (!parsed.success) {\n console.log(\">>>>\", parsed.error);\n logger?.warn(`invalid notification config: ${prettifyError(parsed.error)}`);\n return undefined;\n }\n\n switch (parsed.data.type) {\n case \"telegram\":\n return new TelegramNotifier(parsed.data, logger);\n case \"slack\":\n return new SlackNotifier(parsed.data, logger);\n }\n}\n","import type { ILogger } from \"@gearbox-protocol/sdk\";\nimport { withRetry } from \"viem\";\nimport type { CensoredString } from \"../CensoredString.js\";\nimport type { SignlConfig } from \"./schema.js\";\nimport { ThrottleManager } from \"./ThrottleManager.js\";\nimport type { ThrottleFn } from \"./types.js\";\n\nexport type SignlServiceOptions = SignlConfig & {\n retryInterval?: number;\n retryCount?: number;\n throttleFn?: ThrottleFn;\n};\n\nconst DEFAULT_RETRY_INTERVAL = 1000;\nconst DEFAULT_RETRY_COUNT = 5;\n\nexport default class SignlNotifier {\n readonly #logger?: ILogger;\n\n readonly #apiKey: CensoredString;\n readonly #teamId: CensoredString;\n readonly #retryInterval: number;\n readonly #retryCount: number;\n\n readonly #throttleManager = new ThrottleManager();\n readonly #throttleFn?: ThrottleFn;\n\n constructor(opts: SignlServiceOptions, logger?: ILogger) {\n this.#apiKey = opts.apiKey;\n this.#teamId = opts.teamId;\n this.#retryInterval = opts.retryInterval ?? DEFAULT_RETRY_INTERVAL;\n this.#retryCount = opts.retryCount ?? DEFAULT_RETRY_COUNT;\n this.#logger = logger;\n this.#throttleFn = opts.throttleFn;\n this.#logger?.info(opts, \"signl notifier configured\");\n }\n\n public alert(message: string, dedupeKey?: string): void {\n void this.#sendAlert(message, dedupeKey).catch(e => this.#logger?.error(e));\n }\n\n async #sendAlert(message: string, dedupeKey?: string): Promise<void> {\n if (dedupeKey && !this.#throttleManager.canSend(dedupeKey)) {\n return;\n }\n\n const text = message.slice(0, 64); // it's to be shown in mobile notifications anyways\n this.#logger?.debug(\"sending signl alert\");\n\n await withRetry(\n async () => {\n const resp = await fetch(\n `https://connect.signl4.com/api/v2/alerts?x-s4-api-key=${this.#apiKey.value}`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n category: \"emergency\",\n severity: 0,\n teamId: this.#teamId.value,\n text,\n title: \"GEARBOX ALERT\",\n }),\n },\n );\n if (resp.ok) {\n this.#logger?.warn(\"signl alert sent\");\n const data = await resp.json();\n this.#logger?.info(`signl alert response: ${JSON.stringify(data)}`);\n } else {\n throw new Error(`signl api error ${resp.status}: ${resp.statusText}`);\n }\n },\n { delay: this.#retryInterval, retryCount: this.#retryCount },\n );\n\n if (dedupeKey) {\n this.#throttleManager.onSent(dedupeKey, this.#throttleFn);\n }\n }\n}\n","import { ADDRESS_0X0, AddressMap, type ILogger } from \"@gearbox-protocol/sdk\";\nimport type { Address } from \"viem\";\nimport { createNotifier } from \"./createNotifier.js\";\nimport SignlNotifier, { type SignlServiceOptions } from \"./SignlNotifier.js\";\nimport type { NotificationConfig } from \"./schema.js\";\nimport type {\n IDedupableNotification,\n INotification,\n INotificationService,\n INotifier,\n NotificationLike,\n NotificationSeverity,\n} from \"./types.js\";\n\nexport interface NotificationsServiceOptions {\n notifications: Array<NotificationConfig & { recipient?: Address }>;\n signl?: SignlServiceOptions;\n}\n\nexport class NotificationsService implements INotificationService {\n readonly #logger?: ILogger;\n readonly #notifiers = new AddressMap<INotifier>();\n readonly #signlNotifier?: SignlNotifier;\n\n constructor(options: NotificationsServiceOptions, logger?: ILogger) {\n this.#logger = logger;\n for (const n of options.notifications) {\n const recipient = n.recipient ?? ADDRESS_0X0;\n const notifier = createNotifier(n, logger);\n if (notifier) {\n this.#notifiers.upsert(recipient, notifier);\n }\n }\n\n if (options.signl) {\n this.#signlNotifier = new SignlNotifier(options.signl);\n } else {\n this.#logger?.warn(\"signl notifier not configured\");\n }\n }\n\n public registerRecipient(\n address: Address,\n options: NotificationConfig,\n ): void {\n const notifier = createNotifier(options, this.#logger);\n if (notifier) {\n this.#notifiers.upsert(address, notifier);\n }\n }\n\n public signl(message: string, dedupeKey?: string): void {\n this.#signlNotifier?.alert(message, dedupeKey);\n }\n\n public alert(msg: NotificationLike): void {\n this.#notify(msg, \"alert\");\n }\n\n public notify(msg: NotificationLike): void {\n this.#notify(msg, \"notification\");\n }\n\n #notify(msg: NotificationLike, severity: NotificationSeverity): void {\n const message = this.#toNotification(msg);\n for (const [addr, notifier] of this.#notifiers.entries()) {\n const recipient = addr === ADDRESS_0X0 ? undefined : addr;\n const recipientNotification = message.messageFor(recipient);\n if (recipientNotification) {\n const notification = this.#toDedupableNotification(\n recipientNotification,\n );\n notifier.notify(notification, severity);\n // log global notifications\n if (addr === ADDRESS_0X0) {\n if (severity === \"alert\") {\n this.#logger?.warn(notification.plain);\n } else {\n this.#logger?.debug(notification.plain);\n }\n }\n }\n }\n }\n\n #toNotification(message: NotificationLike): INotification {\n // global notification without deduplication\n if (typeof message === \"string\" || !(\"messageFor\" in message)) {\n return {\n messageFor: (recipient?: Address) => (recipient ? undefined : message),\n };\n }\n return message;\n }\n\n #toDedupableNotification(\n msg: string | IDedupableNotification,\n ): IDedupableNotification {\n if (typeof msg === \"string\") {\n return {\n plain: msg,\n };\n }\n return msg;\n }\n}\n","import { Command, Option } from \"@commander-js/extra-typings\";\nimport * as z4 from \"zod/v4/core\";\nimport { decompressObject } from \"./compressedConfig.js\";\nimport type { TemplateData } from \"./resolveYamlFiles.js\";\nimport { resolveYamlFiles } from \"./resolveYamlFiles.js\";\n\nexport const zommandRegistry = z4.registry<{\n flags: string;\n env?: string;\n description?: string;\n}>();\n\nexport interface ZommandOptions<T extends z4.$ZodTypes> {\n schema: T;\n templateData?: TemplateData;\n /**\n * If value is string, it's used as default value for config file\n */\n configFile?: boolean | string;\n /**\n * If true, allows to pass config zlib compressed config as --inline-config=... or INLINE_CONFIG env var\n */\n inlineConfig?: boolean;\n}\n\nexport class Zommand<\n T extends z4.$ZodTypes,\n Args extends any[] = [],\n> extends Command<Args, z4.output<T>> {\n #schema: T;\n #templatedData?: TemplateData;\n #envToObjectKeys: Record<string, string> = {};\n\n constructor(name: string, opts: ZommandOptions<T>) {\n super(name);\n const {\n schema,\n templateData,\n configFile = true,\n inlineConfig = true,\n } = opts;\n this.#schema = schema;\n this.#templatedData = templateData;\n const def = this.#schema._zod.def;\n\n if (def.type === \"object\") {\n this.#addOptionsFromObject(def);\n } else if (def.type === \"union\") {\n for (const o of def.options) {\n const opt = o as z4.$ZodTypes;\n if (opt._zod.def.type === \"object\") {\n this.#addOptionsFromObject(opt._zod.def);\n }\n }\n } else {\n throw new Error(\n `expected object schema, got ${this.#schema._zod.def.type}`,\n );\n }\n\n if (configFile) {\n let opt = new Option(\"--config [file]\", \"config file (or s3 link\");\n if (typeof configFile === \"string\") {\n opt = opt.default(configFile);\n }\n this.addOption(opt);\n }\n\n if (inlineConfig) {\n this.addOption(new Option(\"--inline-config [config]\", \"inline config\"));\n }\n }\n\n #addOptionsFromObject(def: z4.$ZodObjectDef): void {\n const shape = def.shape;\n for (const [key, optionSchema] of Object.entries(shape)) {\n const meta = zommandRegistry.get(optionSchema);\n if (!meta) {\n continue;\n }\n // this avoids duplicate options in case of discriminated unions\n const existing = this.options.find(o => o.flags === meta.flags);\n if (!existing) {\n let description = meta.description;\n if (meta.env) {\n description = `${description} (env variable ${meta.env})`;\n }\n this.addOption(new Option(meta.flags, description));\n if (meta.env) {\n this.#envToObjectKeys[meta.env] = key;\n }\n }\n }\n }\n\n override action(\n fn: (\n this: this,\n ...args: [...Args, z4.output<T>, this]\n ) => void | Promise<void>,\n ): this {\n return super.action(async (...args: [...Args, any, this]) => {\n const argz = args;\n const _cmd = argz.splice(-1);\n const [{ config, inlineConfig, ...opts }] = argz.splice(-1);\n\n let fromYaml: object = {};\n if (config) {\n fromYaml = await resolveYamlFiles(config, {\n ...(process.env as Record<string, string>),\n ...this.#templatedData,\n });\n }\n let fromInlineConfig: object = {};\n if (inlineConfig) {\n fromInlineConfig = await decompressObject(\n inlineConfig,\n this.#templatedData,\n );\n } else if (process.env.INLINE_CONFIG) {\n fromInlineConfig = await decompressObject(\n process.env.INLINE_CONFIG,\n this.#templatedData,\n );\n }\n\n const schemaFromEnv: Record<string, string> = {};\n for (const [env, key] of Object.entries(this.#envToObjectKeys)) {\n if (process.env[env]) {\n schemaFromEnv[key] = process.env[env]!;\n }\n }\n\n // deep merge is not required: env and cli flags are for top-level only\n const combined = {\n ...schemaFromEnv,\n ...fromYaml,\n ...fromInlineConfig,\n ...opts,\n };\n\n const data = z4.parse(this.#schema, combined);\n await fn.apply(this, [...argz, data, this]);\n });\n }\n}\n","import { SUPPORTED_NETWORKS } from \"@gearbox-protocol/sdk\";\nimport { z } from \"zod/v4\";\nimport { CensoredString } from \"./CensoredString.js\";\nimport { CensoredURL } from \"./CensoredURL.js\";\nimport { stringArrayLike } from \"./schemas/schema-primitives.js\";\nimport { zommandRegistry } from \"./Zommand.js\";\n\nexport const RpcProvider = z.enum([\n \"alchemy\",\n \"drpc\",\n \"ankr\",\n \"thirdweb\",\n \"custom\",\n \"erpc\",\n]);\nexport type RpcProvider = z.infer<typeof RpcProvider>;\n\nexport const ProvidersSchema = z.object({\n network: z.enum(SUPPORTED_NETWORKS).register(zommandRegistry, {\n flags: \"--network <network>\",\n description: \"Gearbox-supported network\",\n env: \"NETWORK\",\n }),\n /**\n * RPC providers to use\n */\n jsonRpcProviders: stringArrayLike()\n .pipe(z.array(z.url().transform(CensoredURL.transform)))\n .transform(a => (a.length ? a : undefined))\n .optional()\n .register(zommandRegistry, {\n flags: \"--json-rpc-providers <urls...>\",\n description: \"RPC providers to use, comma separated full http urls.\",\n env: \"JSON_RPC_PROVIDERS\",\n }),\n /**\n * RPC providers to use with their keys\n * Order matters\n */\n enabledProviders: stringArrayLike()\n .pipe(z.array(RpcProvider))\n .optional()\n .register(zommandRegistry, {\n flags: \"--enabled-providers <providers...>\",\n description:\n \"Keyed RPC providers to use, comma separated, order matters. Possible values: custom (for full json rpc urls)/alchemy/drpc/ankr/thirdweb\",\n env: \"ENABLED_PROVIDERS\",\n }),\n /**\n * Alchemy API keys to use\n */\n alchemyKeys: stringArrayLike()\n .pipe(z.array(z.string().transform(CensoredString.transform)))\n .transform(a => (a.length ? a : undefined))\n .optional()\n .register(zommandRegistry, {\n flags: \"--alchemy-keys <keys...>\",\n description: \"Alchemy API keys to use, comma separated\",\n env: \"ALCHEMY_KEYS\",\n }),\n /**\n * DRPC API keys to use\n */\n drpcKeys: stringArrayLike()\n .pipe(z.array(z.string().transform(CensoredString.transform)))\n .transform(a => (a.length ? a : undefined))\n .optional()\n .register(zommandRegistry, {\n flags: \"--drpc-keys <keys...>\",\n description: \"DRPC API keys to use, comma separated\",\n env: \"DRPC_KEYS\",\n }),\n /**\n * Ankr API keys to use\n */\n ankrKeys: stringArrayLike()\n .pipe(z.array(z.string().transform(CensoredString.transform)))\n .transform(a => (a.length ? a : undefined))\n .optional()\n .register(zommandRegistry, {\n flags: \"--ankr-keys <keys...>\",\n description: \"Ankr API keys to use, comma separated\",\n env: \"ANKR_KEYS\",\n }),\n /**\n * Thirdweb API keys to use\n */\n thirdwebKeys: stringArrayLike()\n .pipe(z.array(z.string().transform(CensoredString.transform)))\n .transform(a => (a.length ? a : undefined))\n .optional()\n .register(zommandRegistry, {\n flags: \"--thirdweb-keys <keys...>\",\n description: \"Thirdweb API keys to use, comma separated\",\n env: \"THIRDWEB_KEYS\",\n }),\n /**\n * If set, eRPC will be added as first provider\n */\n erpcProjectId: z.string().optional().register(zommandRegistry, {\n flags: \"--erpc-project-id <project-id>\",\n description: \"If set, eRPC will be added as first provider\",\n env: \"ERPC_PROJECT_ID\",\n }),\n /**\n * eRPC URL to use\n */\n erpcUrl: z.url().default(\"http://erpc.local\").register(zommandRegistry, {\n flags: \"--erpc-url <url>\",\n description: \"eRPC URL to use\",\n env: \"ERPC_URL\",\n }),\n /**\n * Timeout for JSON RPC requests, in milliseconds\n */\n jsonRpcTimeout: z.coerce\n .number()\n .int()\n .positive()\n .optional()\n .register(zommandRegistry, {\n flags: \"--json-rpc-timeout <timeout>\",\n description: \"Timeout for JSON RPC requests, in milliseconds\",\n env: \"JSON_RPC_TIMEOUT\",\n }),\n});\n\nexport type ProvidersSchema = z.infer<typeof ProvidersSchema>;\n","import {\n GetSecretValueCommand,\n SecretsManagerClient,\n} from \"@aws-sdk/client-secrets-manager\";\n\nexport class SecretsManager {\n #smClient?: SecretsManagerClient;\n #secrets: Map<string, string> = new Map();\n\n public async secret(key: string): Promise<string> {\n const [SecretId, ...jsonPath] = key.split(\".\");\n const secretStr = await this.#getSecret(SecretId);\n if (!jsonPath.length) {\n return secretStr;\n }\n let v = JSON.parse(secretStr);\n for (const p of jsonPath) {\n v = v[p];\n }\n if (!v || typeof v !== \"string\") {\n throw new Error(`cannot find secret '${key}'`);\n }\n return v;\n }\n\n public async secretRaw(key: string): Promise<unknown> {\n const val = await this.#getSecret(key);\n try {\n return JSON.parse(val);\n } catch {\n return val;\n }\n }\n\n async #getSecret(SecretId: string): Promise<string> {\n if (this.#secrets.has(SecretId)) {\n return this.#secrets.get(SecretId)!;\n }\n\n if (!this.#smClient) {\n this.#smClient = new SecretsManagerClient({});\n }\n // https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/ssm/command/GetParameterCommand/\n const { SecretString } = await this.#smClient.send(\n new GetSecretValueCommand({ SecretId }),\n );\n if (!SecretString) {\n throw new Error(`secret '${SecretId}' not found`);\n }\n this.#secrets.set(SecretId, SecretString);\n\n return SecretString;\n }\n}\n\nexport const secretsManagerProxy = (\n mgr?: SecretsManager,\n): Record<string, Promise<unknown>> =>\n new Proxy<any>(mgr ?? new SecretsManager(), {\n get(target, prop) {\n if (\n typeof prop === \"string\" &&\n ![\"secret\", \"secretRaw\", \"then\", \"catch\", \"finally\"].includes(prop)\n ) {\n return target.secretRaw(prop);\n }\n },\n });\n","import { GetParameterCommand, SSMClient } from \"@aws-sdk/client-ssm\";\n\nexport class SSMManager {\n #ssmClient?: SSMClient;\n #parameters: Map<string, string> = new Map();\n\n public async parameter(name: string): Promise<string> {\n if (this.#parameters.has(name)) {\n return this.#parameters.get(name)!;\n }\n\n if (!this.#ssmClient) {\n this.#ssmClient = new SSMClient({});\n }\n\n const response = await this.#ssmClient.send(\n new GetParameterCommand({\n Name: name,\n }),\n );\n const value = response.Parameter?.Value;\n if (!value) {\n throw new Error(`parameter ${name} value not found`);\n }\n this.#parameters.set(name, value);\n return value;\n }\n}\n\nexport const ssmManagerProxy = (\n mgr?: SSMManager,\n): Record<string, Promise<unknown>> =>\n new Proxy<any>(mgr ?? new SSMManager(), {\n get(target, prop) {\n if (\n typeof prop === \"string\" &&\n ![\"parameter\", \"then\", \"catch\", \"finally\"].includes(prop)\n ) {\n return target.parameter(prop);\n }\n },\n });\n","export interface IValue<V extends string = string> {\n value: V;\n}\n\nexport function uncensorMap<V extends string = string>(\n map: Record<string, IValue<V>>,\n): Record<string, V> {\n return Object.fromEntries(Object.entries(map).map(([k, v]) => [k, v.value]));\n}\n","import type { ILogger, NetworkType } from \"@gearbox-protocol/sdk\";\nimport { AddressMap } from \"@gearbox-protocol/sdk\";\nimport { z } from \"zod/v4\";\nimport { fetchRetry } from \"./fetchRetry.js\";\nimport {\n type ClientWhitelistItem,\n whitelistItemSchema,\n} from \"./schemas/whitelist-schema.js\";\n\nconst REFRESH_INTERVAL_MS = 10 * 60 * 1000;\n\nconst whitelistResponseSchema = z.array(whitelistItemSchema);\n\n/**\n * Whitelist mode:\n * - `hard`: entries come from static config and block the action entirely.\n * - `soft`: entries come from the remote endpoint, do not block the action,\n * but can be used to annotate notifications when the action fails.\n */\nexport type WhitelistMode = \"soft\" | \"hard\";\n\nexport interface WhitelistOptions {\n /**\n * Full URL of the remote (soft) whitelist endpoint. When omitted, only the\n * static hard whitelist is used.\n */\n url?: string;\n network: NetworkType;\n /**\n * Static (hard) whitelist entries, supplied via config.\n */\n hard?: ClientWhitelistItem[];\n logger?: ILogger;\n}\n\n/**\n * Holds two whitelists:\n * - a `hard` whitelist built once from static config, always available;\n * - a `soft` whitelist fetched from the backend and kept in\n * memory with a periodic refresh.\n *\n * On soft fetch failure the previous in-memory copy is retained; if no\n * successful fetch has occurred yet the soft whitelist is considered empty.\n */\nexport class Whitelist {\n readonly #url?: string;\n readonly #network: NetworkType;\n readonly #logger?: ILogger;\n\n #soft = new AddressMap<ClientWhitelistItem>();\n readonly #hard: AddressMap<ClientWhitelistItem>;\n #refreshInterval?: number;\n\n constructor({ url, network, hard = [], logger }: WhitelistOptions) {\n this.#url = url;\n this.#network = network;\n this.#logger = logger?.child?.({ name: \"whitelist\" }) ?? logger;\n this.#hard = new AddressMap<ClientWhitelistItem>();\n for (const entry of hard) {\n this.#hard.upsert(entry.address, entry);\n }\n }\n\n /**\n * Performs the initial soft fetch and starts the periodic refresh timer.\n * Failure of the initial fetch is non-fatal: the soft whitelist stays empty.\n * When no `url` is configured this is a no-op (only the hard whitelist is used).\n */\n public async start(): Promise<void> {\n if (!this.#url) {\n this.#logger?.debug(\n `no whitelist url configured, using ${this.#hard.size} hard whitelist entries for ${this.#network}`,\n );\n return;\n }\n this.#logger?.info(\n `loading ${this.#network} whitelist from ${this.#url}, refresh every ${REFRESH_INTERVAL_MS / 1000}s`,\n );\n await this.#refresh();\n this.#refreshInterval = setInterval(() => {\n this.#refresh().catch(e => {\n this.#logger?.warn(`unexpected whitelist refresh error: ${e}`);\n });\n }, REFRESH_INTERVAL_MS) as unknown as number;\n }\n\n /** Stops the refresh timer. */\n public stop(): void {\n if (this.#refreshInterval) {\n clearInterval(this.#refreshInterval);\n this.#refreshInterval = undefined;\n }\n }\n\n /**\n * Fetches the soft whitelist from the backend, parses it and atomically\n * replaces the in-memory map. On any error logs a warning and retains\n * the previous map.\n */\n async #refresh(): Promise<void> {\n if (!this.#url) {\n return;\n }\n try {\n const resp = await fetchRetry(this.#url);\n if (!resp.ok) {\n throw new Error(\n `whitelist fetch failed: ${resp.status} ${resp.statusText}`,\n );\n }\n const data = await resp.json();\n const items = whitelistResponseSchema\n .parse(data)\n .filter(i => i.network === this.#network);\n const next = new AddressMap<ClientWhitelistItem>();\n for (const item of items) {\n next.upsert(item.address, {\n address: item.address,\n reason: item.reason,\n expiresAt: item.expiresAt,\n contractType: item.contractType,\n });\n }\n this.#soft = next;\n this.#logger?.debug(\n `loaded ${items.length} soft whitelist entries for ${this.#network}`,\n );\n } catch (e) {\n this.#logger?.warn(\n `failed to refresh whitelist from ${this.#url}, keeping previous version: ${e}`,\n );\n }\n }\n\n /**\n * Returns the matching whitelist entry for the given address in the\n * requested mode, or `undefined` if absent or expired.\n */\n public has(\n address: string,\n mode: WhitelistMode,\n ): ClientWhitelistItem | undefined {\n const list = mode === \"hard\" ? this.#hard : this.#soft;\n const item = list.get(address);\n if (!item) {\n return undefined;\n }\n if (item.expiresAt !== undefined && Date.now() / 1000 >= item.expiresAt) {\n return undefined;\n }\n return item;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["pathResolve","DEFAULT_RETRY_INTERVAL","DEFAULT_RETRY_INTERVAL","DEFAULT_RETRY_COUNT"],"sources":["../src/CensoredString.ts","../src/CensoredURL.ts","../src/getPromisePath.ts","../src/resolveYamlFiles.ts","../src/compressedConfig.ts","../src/createPinoCensor.ts","../src/sleep.ts","../src/fetchRetry.ts","../src/providers.ts","../src/getProviders.ts","../src/getFirstHttpTransportOptions.ts","../src/notifications/SlackNotifier.ts","../src/notifications/schema.ts","../src/notifications/ThrottleManager.ts","../src/notifications/TelegramNotifier.ts","../src/notifications/createNotifier.ts","../src/notifications/SignlNotifier.ts","../src/notifications/NotificationsService.ts","../src/Zommand.ts","../src/providers-schema.ts","../src/SecretsManager.ts","../src/SSMManager.ts","../src/uncensorMap.ts","../src/Whitelist.ts"],"sourcesContent":["export class CensoredString<V extends string = string> {\n readonly #value: V;\n readonly #censored: string;\n\n public static transform<T extends string>(\n value: T | CensoredString<T>,\n ): CensoredString<T> {\n if (value instanceof CensoredString) {\n return value;\n }\n return new CensoredString(value);\n }\n\n constructor(value: V) {\n this.#value = value;\n const visibleLen = Math.min(4, Math.floor(0.2 * value.length));\n if (visibleLen < 1) {\n this.#censored = \"*\".repeat(Math.min(8, value.length));\n } else {\n this.#censored =\n \"*\".repeat(Math.min(8, value.length - visibleLen)) +\n value.slice(-1 * visibleLen);\n }\n }\n\n public get value(): V {\n return this.#value;\n }\n\n public toString(): string {\n return this.#censored;\n }\n\n public toJSON(): string {\n return this.toString();\n }\n}\n","/**\n * Assumes that host is always visible, and the secret part is in path or query\n */\nexport class CensoredURL {\n readonly #value: string;\n readonly #censored: string;\n\n public static transform(value: string | CensoredURL): CensoredURL {\n if (value instanceof CensoredURL) {\n return value;\n }\n return new CensoredURL(value);\n }\n\n constructor(url: string) {\n this.#value = url;\n if (\n url.includes(\"127.0.0.1\") ||\n url.includes(\"localhost\") ||\n url.includes(\"host.docker.internal\")\n ) {\n this.#censored = url;\n } else {\n try {\n const u = new URL(url);\n if (u.username || u.password) {\n u.username = u.username ? \"****\" : \"\";\n u.password = u.password ? \"****\" : \"\";\n }\n u.pathname = \"/\";\n u.search = \"\";\n this.#censored = `${u.href}******`;\n } catch {\n const visibleLen = Math.min(4, Math.floor(0.2 * url.length));\n if (visibleLen < 1) {\n this.#censored = \"*\".repeat(Math.min(8, url.length));\n } else {\n this.#censored =\n \"*\".repeat(Math.min(8, url.length - visibleLen)) +\n url.slice(-1 * visibleLen);\n }\n }\n }\n }\n\n public get value(): string {\n return this.#value;\n }\n\n public toString(): string {\n return this.#censored;\n }\n\n public toJSON(): string {\n return this.toString();\n }\n}\n","/**\n * Similar to lodash.get, but supports promises\n * @param object\n * @param keys\n * @returns\n */\nexport default async function getPromisePath<V = any>(\n object: any,\n path: string,\n): Promise<V> {\n return getPromised(object, path.split(\".\"));\n}\n\nasync function getPromised<V = any>(object: any, keys: string[]): Promise<V> {\n if (keys.length === 0) {\n return Promise.resolve(object);\n }\n const [key, ...rest] = keys;\n const value = object[key];\n const resolved = await Promise.resolve(value);\n return getPromised(resolved, rest);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { dirname, resolve as pathResolve } from \"node:path\";\nimport { GetObjectCommand, S3Client } from \"@aws-sdk/client-s3\";\nimport YAML, { isPair, isScalar, isSeq } from \"yaml\";\nimport getPromisePath from \"./getPromisePath.js\";\n\nexport type TemplateData = Record<string, unknown>;\n\n/**\n * Template key regexp\n * Consists of alphanumeric+underscore parts separated by dots, all wrappped in env-style brackets\n * e.g. ${KEY} or ${KEY.SUBKEY}\n *\n * Optionally supports a bash-style default value via `:-`, e.g. `${KEY:-fallback}`.\n * The default is used when the resolved value is undefined, null, or an empty string.\n * Capture groups: 1 = key path, 2 = optional default literal (no `}` allowed).\n */\nconst templateKeyRegex = /\\$\\{([\\w-]+(?:\\.[\\w-]+)*)(?::-([^}]*))?\\}/g;\n\n/**\n * Replaces all `${...}` template tokens in a string using the provided template data.\n * Supports bash-style `${KEY:-default}` fallback when the resolved value is missing\n * (undefined, null, or empty string). The default is a literal and is not further\n * interpolated.\n */\nasync function resolveScalarValue(\n val: string,\n templateData?: TemplateData,\n): Promise<string> {\n const matches = val.matchAll(templateKeyRegex);\n for (const match of matches) {\n const [whole, key, defaultValue] = match;\n const resolved = await getPromisePath(templateData, key);\n if (resolved !== undefined && resolved !== null && resolved !== \"\") {\n val = val.replace(whole, String(resolved));\n } else if (defaultValue !== undefined) {\n val = val.replace(whole, defaultValue);\n }\n }\n return val;\n}\n\n/**\n * Merges yaml files, respecting .extends references.\n * Performs env variable substitution on the config.\n * Respects YAML anchors and aliases, and merge keys - so that they can be shared across two files\n *\n * x-* anchors are removed from resulting document (a-la docker compose yaml)\n *\n * @param file\n * @param templateData\n * @returns\n */\nexport async function resolveYamlFiles(\n file: string,\n templateData?: TemplateData,\n): Promise<object> {\n const doc = await resolveYamlDoc(file, templateData);\n const obj = doc.toJSON();\n return Object.fromEntries(\n Object.entries(obj).filter(([k]) => !k.startsWith(\"x-\")),\n );\n}\n\n/**\n * Merges yaml documents, respecting .extends references.\n * Optionally, performs env-style variable substitution on the config.\n * Respects YAML anchors and aliases, and merge keys - so that they can be shared across two files\n * Supports s3 links for file\n *\n * @param file\n * @param templateData\n * @returns\n */\nexport async function resolveYamlDoc(\n file: string,\n templateData?: TemplateData,\n): Promise<YAML.Document> {\n const content = await loadFile(file);\n // if (templateData) {\n // const compiled = template(content);\n // content = compiled(templateData);\n // }\n let cfgRaw: YAML.Document = YAML.parseDocument(content, { merge: true });\n // let cfgRaw = YAML.parse(content, { merge: true });\n if (cfgRaw.has(\"extends\")) {\n const baseFile = cfgRaw.get(\"extends\") as string;\n const extended = cfgRaw;\n // extends is a relative path to the base file\n cfgRaw = await resolveYamlDoc(\n getRelativePath(file, baseFile),\n templateData,\n );\n YAML.visit(extended, {\n Pair(_, pair, rawPath) {\n const path = getNodesPath(rawPath);\n if (isScalar(pair.key) && (isScalar(pair.value) || isSeq(pair.value))) {\n if (pair.key.value === \"extends\") {\n return;\n }\n cfgRaw.setIn([...path, pair.key.value], pair.value);\n return YAML.visit.SKIP;\n }\n },\n });\n }\n\n await YAML.visitAsync(cfgRaw, {\n Scalar: async (_, node) => {\n if (typeof node.value === \"string\") {\n node.value = await resolveScalarValue(node.value, templateData);\n }\n },\n });\n\n return cfgRaw;\n}\n\n/**\n * Helper function that gets object with templated values\n * Just because async ast already exists in yaml, but not in json reviver\n * @param json\n * @param templateData\n * @returns\n */\nexport async function resolveFromObject(\n json: object,\n templateData?: TemplateData,\n): Promise<object> {\n const content = YAML.stringify(json);\n const cfgRaw: YAML.Document = YAML.parseDocument(content, { merge: true });\n\n await YAML.visitAsync(cfgRaw, {\n Scalar: async (_, node) => {\n if (typeof node.value === \"string\") {\n node.value = await resolveScalarValue(node.value, templateData);\n }\n },\n });\n\n return cfgRaw.toJSON();\n}\n\nfunction getNodesPath(\n nodes: readonly (YAML.Node | YAML.Document | YAML.Pair)[],\n): unknown[] {\n return nodes\n .map(n => {\n if (isPair(n) && isScalar(n.key)) {\n return n.key.value;\n }\n return \"\";\n })\n .filter(Boolean);\n}\n\n/**\n * Loads file from s3 or local file system\n * @param file - s3 link or local file path\n * @returns file content\n */\nasync function loadFile(file: string): Promise<string> {\n if (file.startsWith(\"s3://\")) {\n return await loadS3File(file);\n }\n return await readFile(file, \"utf-8\");\n}\n\n/**\n * Loads file from s3\n * @param file - s3 link like s3://bucket/path/to/file.yaml\n * @returns file content\n */\nasync function loadS3File(file: string): Promise<string> {\n const url = new URL(file);\n const bucket = url.hostname;\n const key = url.pathname.slice(1);\n\n const s3 = new S3Client({});\n const response = await s3.send(\n new GetObjectCommand({\n Bucket: bucket,\n Key: key,\n }),\n );\n if (!response.Body) {\n throw new Error(`file ${file} not found`);\n }\n return response.Body.transformToString(\"utf-8\");\n}\n\n/**\n * Given file and a relative file path, returns full path of the relative file\n * Supports s3 links for base file\n * @param file\n * @param relativeFile\n */\nexport function getRelativePath(\n baseFile: string,\n relativeFile: string,\n): string {\n if (baseFile.startsWith(\"s3://\")) {\n const url = new URL(baseFile);\n const relPathname = pathResolve(dirname(url.pathname), relativeFile);\n url.pathname = relPathname;\n return url.toString();\n }\n return pathResolve(dirname(baseFile), relativeFile);\n}\n","import { deflateSync, inflateSync } from \"node:zlib\";\nimport { resolveFromObject } from \"./resolveYamlFiles.js\";\n\n/**\n * Compress a plain JS object into a base64url string\n * suitable for env vars.\n */\nexport function compressObject(obj: unknown): string {\n const json = JSON.stringify(obj);\n const compressed = deflateSync(Buffer.from(json, \"utf8\"));\n return compressed.toString(\"base64url\");\n}\n\n/**\n * Decompress a base64url string back into a JS object\n * Allows to pass template data to resolve promises/env\n */\nexport async function decompressObject<T = unknown>(\n value: string,\n templateData?: Record<string, unknown>,\n): Promise<T> {\n const compressed = Buffer.from(value, \"base64url\");\n const str = inflateSync(compressed).toString(\"utf8\");\n const json = JSON.parse(str);\n const result = await resolveFromObject(json, templateData);\n return result as T;\n}\n","import { CensoredString } from \"./CensoredString.js\";\nimport { CensoredURL } from \"./CensoredURL.js\";\n\n/**\n * Raw values shorter than this are not censored, to avoid masking unrelated\n * substrings throughout the log output.\n */\nconst MIN_SECRET_LENGTH = 4;\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction collectSecrets(value: unknown, out: Map<string, string>): void {\n if (value == null) {\n return;\n }\n if (value instanceof CensoredString || value instanceof CensoredURL) {\n const raw = value.value;\n if (raw.length >= MIN_SECRET_LENGTH) {\n out.set(raw, value.toString());\n }\n return;\n }\n if (typeof value !== \"object\") {\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n collectSecrets(item, out);\n }\n return;\n }\n for (const item of Object.values(value)) {\n collectSecrets(item, out);\n }\n}\n\n/**\n * Gathers known secrets from a config and returns a function that replaces each raw secret with its masked representation.\n * Intended for pino's `hooks.streamWrite`\n */\nexport function createPinoCensor(config: unknown): (s: string) => string {\n const map = new Map<string, string>();\n collectSecrets(config, map);\n if (map.size === 0) {\n return s => s;\n }\n // Longer secrets first so a secret that is a substring of another does not\n // shadow the longer match.\n const pattern = [...map.keys()]\n .sort((a, b) => b.length - a.length)\n .map(escapeRegExp)\n .join(\"|\");\n const re = new RegExp(pattern, \"g\");\n return s => s.replace(re, m => map.get(m) ?? m);\n}\n","// Mirror of packages/shared/src/sleep.ts; keep in sync.\nexport async function sleep(ms: number) {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n","// Mirror of packages/shared/src/fetchRetry.ts; keep in sync.\nimport { sleep } from \"./sleep.js\";\n\nconst DEFAULT_RETRIES = 5;\nconst DEFAULT_RETRY_INTERVAL = 1000;\n\ninterface RetrySettings {\n retries?: number;\n retryInterval?: number;\n validateResponse?: (response: Response) => void;\n}\n\nexport async function fetchRetry(\n input: string | URL,\n init: RequestInit & RetrySettings = {},\n): Promise<Response> {\n const {\n retries = DEFAULT_RETRIES,\n retryInterval = DEFAULT_RETRY_INTERVAL,\n validateResponse,\n ...options\n } = init;\n try {\n const response = await fetch(input, options);\n validateResponse?.(response);\n return response;\n } catch (e: any) {\n if (retries > 0) {\n await sleep(retryInterval);\n return fetchRetry(input, {\n ...options,\n retries: retries - 1,\n retryInterval,\n validateResponse,\n });\n } else {\n throw e;\n }\n }\n}\n","import {\n chains,\n getChain,\n type NetworkType,\n} from \"@gearbox-protocol/sdk/onchain\";\n\nexport function getAlchemyUrl(\n network: NetworkType,\n apiKey: string,\n protocol: \"http\" | \"ws\" = \"http\",\n): string | undefined {\n const alchemyDomain = ALCHEMY_DOMAINS[network];\n if (!alchemyDomain) {\n return undefined;\n }\n return `${protocol}s://${alchemyDomain}.g.alchemy.com/v2/${apiKey}`;\n}\n\nconst DRPC_NETS: Record<NetworkType, string | null> = {\n Arbitrum: \"arbitrum\",\n Base: \"base\",\n BNB: \"bsc\",\n Mainnet: \"ethereum\",\n Optimism: \"optimism\",\n Sonic: \"sonic\",\n WorldChain: \"worldchain\",\n Berachain: \"berachain\",\n Avalanche: \"avalanche\",\n Monad: \"monad\",\n Hemi: \"hemi\",\n Lisk: \"lisk\",\n MegaETH: null,\n Etherlink: null,\n Plasma: \"plasma\",\n Somnia: null,\n};\n\nconst ALCHEMY_DOMAINS: Record<NetworkType, string | null> = {\n Mainnet: \"eth-mainnet\",\n Arbitrum: \"arb-mainnet\",\n Optimism: \"opt-mainnet\",\n Base: \"base-mainnet\",\n Sonic: \"sonic-mainnet\",\n Monad: \"monad-mainnet\",\n Berachain: \"berachain-mainnet\",\n Avalanche: \"avax-mainnet\",\n BNB: \"bnb-mainnet\",\n WorldChain: \"worldchain-mainnet\",\n MegaETH: null,\n Etherlink: null,\n Hemi: null,\n Lisk: null,\n Plasma: \"plasma-mainnet\",\n Somnia: null,\n};\n\nexport function getDrpcUrl(\n network: NetworkType,\n apiKey: string,\n protocol: \"http\" | \"ws\" = \"http\",\n): string | undefined {\n const net = DRPC_NETS[network];\n return net ? `${protocol}s://lb.drpc.org/${net}/${apiKey}` : undefined;\n}\n\nconst ANKR_DOMAINS: Record<NetworkType, string | null> = {\n Arbitrum: \"arbitrum\",\n Avalanche: \"avalanche\",\n Base: \"base\",\n Berachain: null,\n BNB: \"bsc\",\n Etherlink: \"etherlink_mainnet\",\n Hemi: null,\n Lisk: null,\n Mainnet: \"eth\",\n MegaETH: null,\n Monad: null,\n Optimism: \"optimism\",\n Plasma: null,\n Sonic: \"sonic_mainnet\",\n WorldChain: null,\n Somnia: \"somnia_mainnet\",\n};\n\nexport function getAnkrUrl(\n network: NetworkType,\n apiKey: string,\n protocol: \"http\" | \"ws\" = \"http\",\n): string | undefined {\n const net = ANKR_DOMAINS[network];\n const sep = protocol === \"ws\" ? \"/ws/\" : \"/\";\n return net ? `${protocol}s://rpc.ankr.com/${net}${sep}${apiKey}` : undefined;\n}\n\nconst THIRDWEB_DOMAINS: Record<NetworkType, string | null> = {\n Arbitrum: chains.Arbitrum.id.toString(),\n Avalanche: chains.Avalanche.id.toString(),\n Base: chains.Base.id.toString(),\n Berachain: chains.Berachain.id.toString(),\n BNB: chains.BNB.id.toString(),\n Etherlink: chains.Etherlink.id.toString(),\n Hemi: chains.Hemi.id.toString(),\n Lisk: chains.Lisk.id.toString(),\n Mainnet: chains.Mainnet.id.toString(),\n MegaETH: chains.MegaETH.id.toString(),\n Monad: chains.Monad.id.toString(),\n Optimism: chains.Optimism.id.toString(),\n Plasma: chains.Plasma.id.toString(),\n Sonic: chains.Sonic.id.toString(),\n WorldChain: chains.WorldChain.id.toString(),\n Somnia: chains.Somnia.id.toString(),\n};\n\nexport function getThirdWebUrl(\n network: NetworkType,\n apiKey: string,\n protocol: \"http\" | \"ws\" = \"http\",\n): string | undefined {\n if (protocol === \"ws\") {\n return undefined;\n }\n const net = THIRDWEB_DOMAINS[network];\n return `https://${net}.rpc.thirdweb.com/${apiKey}`;\n}\n\nexport function getErpcKey(\n network: NetworkType,\n projectId?: string,\n urlBase?: string,\n): string | undefined {\n if (!projectId || !urlBase) {\n return undefined;\n }\n const chain = getChain(network);\n return `${urlBase}/${projectId}/evm/${chain.id}`;\n}\n","import type { ProviderConfig } from \"@gearbox-protocol/sdk/dev\";\nimport type { ILogger } from \"@gearbox-protocol/sdk/onchain\";\nimport type { PartialBy } from \"viem\";\nimport { CensoredURL } from \"./CensoredURL.js\";\nimport {\n getAlchemyUrl,\n getAnkrUrl,\n getDrpcUrl,\n getErpcKey,\n getThirdWebUrl,\n} from \"./providers.js\";\nimport type { ProvidersSchema } from \"./providers-schema.js\";\n\nexport function getProviders(\n config: ProvidersSchema,\n logger?: ILogger,\n): ProviderConfig[] {\n const {\n network,\n\n enabledProviders = [\n \"erpc\",\n \"custom\",\n \"drpc\",\n \"alchemy\",\n \"ankr\",\n \"thirdweb\",\n ],\n alchemyKeys = [],\n ankrKeys = [],\n drpcKeys = [],\n thirdwebKeys = [],\n jsonRpcProviders = [],\n\n erpcProjectId,\n erpcUrl,\n } = config;\n const result: PartialBy<ProviderConfig, \"url\">[] = [];\n for (const p of enabledProviders) {\n switch (p) {\n case \"alchemy\":\n result.push(\n ...alchemyKeys.map(k => ({\n name: \"alchemy\",\n url: getAlchemyUrl(network, k.value),\n })),\n );\n break;\n case \"drpc\":\n result.push(\n ...drpcKeys.map(k => ({\n name: \"drpc\",\n url: getDrpcUrl(network, k.value),\n })),\n );\n break;\n case \"ankr\":\n result.push(\n ...ankrKeys.map(k => ({\n name: \"ankr\",\n url: getAnkrUrl(network, k.value),\n })),\n );\n break;\n case \"thirdweb\":\n result.push(\n ...thirdwebKeys.map(k => ({\n name: \"thirdweb\",\n url: getThirdWebUrl(network, k.value),\n })),\n );\n break;\n case \"custom\":\n result.push(\n ...jsonRpcProviders.map((url): ProviderConfig => {\n const urlObj = new URL(url.value);\n const hasCredentials = urlObj.username || urlObj.password;\n\n let cleanUrl = url.value;\n let httpTransportOptions: ProviderConfig[\"httpTransportOptions\"] =\n {};\n\n if (hasCredentials) {\n // Create URL without credentials\n const cleanUrlObj = new URL(url.value);\n cleanUrlObj.username = \"\";\n cleanUrlObj.password = \"\";\n cleanUrl = cleanUrlObj.toString();\n\n // Create Basic Auth header\n const credentials = `${urlObj.username}:${urlObj.password}`;\n const encodedCredentials =\n Buffer.from(credentials).toString(\"base64\");\n\n httpTransportOptions = {\n fetchOptions: {\n headers: {\n Authorization: `Basic ${encodedCredentials}`,\n },\n },\n };\n }\n\n return {\n name: getTopLevelDomain(urlObj),\n url: cleanUrl,\n httpTransportOptions,\n };\n }),\n );\n break;\n case \"erpc\":\n if (erpcProjectId && erpcUrl) {\n result.push({\n name: \"erpc\",\n url: getErpcKey(network, erpcProjectId, erpcUrl),\n });\n }\n break;\n }\n }\n if (logger) {\n const providers = result\n .filter(p => !!p.url)\n .map(p => ({\n name: p.name,\n url: new CensoredURL(p.url!),\n }));\n logger.debug({ providers, network }, \"gathered providers\");\n }\n return result\n .map(p => ({\n ...p,\n httpClientOptions: {\n ...p.httpTransportOptions,\n methods: { exclude: [\"eth_fillTransaction\"] },\n },\n }))\n .filter(p => !!p.url) as ProviderConfig[];\n}\n\n/**\n * Take the last two parts for top-level domain (e.g., \"google.com\" from \"a.b.c.google.com\")\n **/\nfunction getTopLevelDomain({ hostname }: URL): string {\n const parts = hostname.split(\".\");\n return parts.length >= 2 ? parts.slice(-2).join(\".\") : hostname;\n}\n","import type { HttpTransportConfig } from \"viem\";\nimport { getProviders } from \"./getProviders.js\";\nimport type { ProvidersSchema } from \"./providers-schema.js\";\n\nexport interface HttpTransportOptions {\n url?: string | undefined;\n config: HttpTransportConfig;\n}\n\nexport function getFirstHttpTransportOptions(\n config: ProvidersSchema,\n): HttpTransportOptions {\n const [provider] = getProviders(config);\n if (!provider) {\n throw new Error(\"No provider found\");\n }\n return {\n url: provider.url,\n config: {\n ...provider.httpTransportOptions,\n },\n };\n}\n","import type { ILogger } from \"@gearbox-protocol/sdk/onchain\";\nimport type { SlackConfig } from \"./schema.js\";\nimport type {\n IDedupableNotification,\n INotifier,\n NotificationSeverity,\n} from \"./types.js\";\n\n// TODO: no throttling or deduplication yet\nexport class SlackNotifier implements INotifier {\n readonly #config: SlackConfig;\n readonly #logger?: ILogger;\n\n constructor(config: SlackConfig, logger?: ILogger) {\n this.#config = config;\n this.#logger = logger;\n }\n\n public notify(\n message: IDedupableNotification,\n severity: NotificationSeverity,\n ): void {\n if (this.#config.alertsOnly && severity === \"notification\") {\n return;\n }\n const emoji = severity === \"alert\" ? \"🚨\" : \"ℹ️\";\n const messageText = typeof message === \"string\" ? message : message.plain;\n\n void this.#sendToSlack(`${emoji} Alert: ${messageText}`);\n }\n\n async #sendToSlack(text: string): Promise<void> {\n try {\n this.#logger?.debug(`Sending message to Slack: ${text}`);\n\n // Use fetch instead of axios to avoid adding dependencies\n const response = await fetch(this.#config.webhookUrl.value, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ text }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n this.#logger?.debug(\"Slack message sent successfully\");\n } catch (error) {\n this.#logger?.error(\"Error sending Slack message:\", error);\n throw error;\n }\n }\n}\n","import { z } from \"zod/v4\";\nimport { CensoredString } from \"../CensoredString.js\";\nimport { boolLike } from \"../schemas/schema-primitives.js\";\n\nexport const TelegramConfig = z.object({\n type: z.literal(\"telegram\"),\n token: z\n .union([z.string(), z.instanceof(CensoredString)])\n .transform(CensoredString.transform),\n alertsChannel: z\n .union([z.string().startsWith(\"-\"), z.instanceof(CensoredString)])\n .transform(CensoredString.transform),\n /**\n * Optional channel to send notifications to\n * If not set, notifications will not be sent\n */\n notificationsChannel: z\n .union([z.string().startsWith(\"-\"), z.instanceof(CensoredString)])\n .transform(CensoredString.transform)\n .optional(),\n prefix: z.string().optional(),\n});\n\nexport type TelegramConfig = z.infer<typeof TelegramConfig>;\n\nexport const SlackConfig = z.object({\n type: z.literal(\"slack\"),\n /**\n * Slack webhook URL for sending notifications\n */\n webhookUrl: z\n .union([z.string(), z.instanceof(CensoredString)])\n .transform(CensoredString.transform),\n /**\n * If true, only alerts will be sent. Informational notifications are suppressed\n */\n alertsOnly: boolLike().optional(),\n});\n\nexport type SlackConfig = z.infer<typeof SlackConfig>;\n\nexport const NotificationConfig = z.discriminatedUnion(\"type\", [\n TelegramConfig,\n SlackConfig,\n]);\n\nexport type NotificationConfig = z.infer<typeof NotificationConfig>;\n\nexport const SignlConfig = z.object({\n apiKey: z\n .union([z.string(), z.instanceof(CensoredString)])\n .transform(CensoredString.transform),\n teamId: z\n .union([z.string(), z.instanceof(CensoredString)])\n .transform(CensoredString.transform),\n});\n\nexport type SignlConfig = z.infer<typeof SignlConfig>;\n","import { LRUCache } from \"lru-cache\";\nimport type { ThrottleFn } from \"./types.js\";\n\ninterface ThrottleState {\n lastAlertTime: number;\n currentWait: number;\n}\n\nexport function defaultBackoffFn(prevWait: number): number {\n return Math.min(\n prevWait ? prevWait * 2 : 10 * 60 * 1000, // 10 minutes\n 24 * 60 * 60 * 1000, // 24 hours\n );\n}\n\n/**\n * Manages per-feed throttling with exponential backoff.\n * Each dedupe key has its own independent throttle timer.\n */\nexport class ThrottleManager {\n #state = new LRUCache<string, ThrottleState>({ max: 5000 });\n\n /**\n * Checks if it's permitted to send a message for the given dedupe key\n * @returns\n */\n public canSend(dedupeKey?: string): boolean {\n if (!dedupeKey) {\n return true;\n }\n const state = this.#getState(dedupeKey);\n const timeSinceLastAlert = Date.now() - state.lastAlertTime;\n return timeSinceLastAlert >= state.currentWait;\n }\n\n /**\n * Records that notification was sent for the given dedupe key\n */\n public onSent(\n dedupeKey?: string,\n throttleFn: ThrottleFn = defaultBackoffFn,\n ): void {\n if (!dedupeKey) {\n return;\n }\n const state = this.#getState(dedupeKey);\n this.#state.set(dedupeKey, {\n lastAlertTime: Date.now(),\n currentWait: throttleFn(state.currentWait),\n });\n }\n\n #getState(dedupeKey: string): ThrottleState {\n return this.#state.get(dedupeKey) ?? { lastAlertTime: 0, currentWait: 0 };\n }\n}\n","import type { ILogger } from \"@gearbox-protocol/sdk/onchain\";\nimport { md } from \"@vlad-yakovlev/telegram-md\";\nimport Queue from \"p-queue\";\nimport { withRetry } from \"viem\";\nimport type { TelegramConfig } from \"./schema.js\";\nimport { ThrottleManager } from \"./ThrottleManager.js\";\nimport type {\n IDedupableNotification,\n INotifier,\n NotificationSeverity,\n} from \"./types.js\";\n\nexport type TelegramNotifierOptions = TelegramConfig & {\n retryInterval?: number;\n retryCount?: number;\n maxChunkSize?: number;\n fetchFn?: typeof fetch;\n};\n\ninterface TelegramPayload {\n text: string;\n parse_mode?: \"MarkdownV2\";\n}\n\nconst DEFAULT_RETRY_INTERVAL = 1000;\nconst DEFAULT_RETRY_COUNT = 5;\nconst DEFAULT_MAX_CHUNK_SIZE = 4096;\n\nexport class TelegramNotifier implements INotifier {\n readonly #logger?: ILogger;\n readonly #alertsChannel: string;\n readonly #notificationsChannel?: string;\n readonly #botToken: string;\n readonly #prefix?: string;\n\n readonly #retryInterval: number;\n readonly #retryCount: number;\n readonly #maxChunkSize: number;\n readonly #fetchFn: typeof fetch;\n readonly #queue = new Queue({\n concurrency: 1,\n // https://core.telegram.org/bots/faq#my-bot-is-hitting-limits-how-do-i-avoid-this\n // 20 messages/minute limit\n interval: 60_000,\n intervalCap: 20,\n strict: true,\n });\n readonly #throttleManager = new ThrottleManager();\n\n constructor(opts: TelegramNotifierOptions, logger?: ILogger) {\n this.#logger = logger;\n this.#alertsChannel = opts.alertsChannel.value;\n this.#botToken = opts.token.value;\n this.#notificationsChannel = opts.notificationsChannel?.value;\n this.#prefix = opts.prefix;\n this.#retryInterval = opts.retryInterval ?? DEFAULT_RETRY_INTERVAL;\n this.#retryCount = opts.retryCount ?? DEFAULT_RETRY_COUNT;\n this.#maxChunkSize = opts.maxChunkSize ?? DEFAULT_MAX_CHUNK_SIZE;\n this.#fetchFn = opts.fetchFn ?? fetch;\n }\n\n public notify(\n message: IDedupableNotification,\n severity: NotificationSeverity,\n ): void {\n const dest =\n severity === \"alert\" ? this.#alertsChannel : this.#notificationsChannel;\n if (!dest) {\n return;\n }\n this.#enqueueTelegram(message, dest, severity === \"alert\");\n }\n\n async #enqueueTelegram(\n message: IDedupableNotification,\n channelId: string,\n severe = false,\n ): Promise<void> {\n if (!this.#throttleManager.canSend(message.dedupeKey)) {\n return;\n }\n\n const payloads = this.#toTelegramPayloads(message);\n for (const payload of payloads) {\n this.#queue.add(\n () =>\n this.#sendToTelegram(payload, channelId, severe).catch(e =>\n this.#logger?.error(e),\n ),\n {\n priority: severe ? 100 : 0,\n timeout: this.#retryInterval * this.#retryCount * 2,\n },\n );\n }\n\n this.#throttleManager.onSent(message.dedupeKey, message.throttleFn);\n }\n\n async #sendToTelegram(\n payload: TelegramPayload,\n channelId: string,\n severe = false,\n ): Promise<void> {\n const severity = severe ? \"alert\" : \"notification\";\n this.#logger?.debug(\n `sending telegram ${severity} to channel ${channelId}...`,\n );\n const url = `https://api.telegram.org/bot${this.#botToken}/sendMessage`;\n\n try {\n await withRetry(\n async () => {\n const resp = await this.#fetchFn(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n ...payload,\n chat_id: channelId,\n }),\n });\n if (resp.ok) {\n this.#logger?.debug(`telegram ${severity} sent successfully`);\n } else {\n const txt = await resp.text();\n throw new Error(`api error ${resp.status}: ${txt}`);\n }\n },\n { delay: this.#retryInterval, retryCount: this.#retryCount },\n );\n } catch (e) {\n this.#logger?.error(`cannot send telegram ${severity}: ${e}`);\n }\n }\n\n #toTelegramPayloads(message: IDedupableNotification): TelegramPayload[] {\n const { md: mdMessage, plain } = message;\n if (!mdMessage) {\n return this.#slicePlainText(plain);\n }\n let text = mdMessage;\n if (this.#prefix) {\n text = md.join([md.bold(this.#prefix), text], \" \");\n }\n const mdText = text.toString();\n if (mdText.length > this.#maxChunkSize) {\n return this.#slicePlainText(plain);\n }\n return [{ text: mdText, parse_mode: \"MarkdownV2\" }];\n }\n\n /**\n * Telegram has a limit on message size (default 4096 characters).\n * This function slices the text into chunks respecting the limit.\n * Each chunk is prefixed with the prefix (if set), ensuring the total length <= maxChunkSize.\n * @param text - The text to slice.\n * @returns An array of texts.\n */\n #slicePlainText(text: string): TelegramPayload[] {\n const chunks = [];\n const prefix = this.#prefix ? `${this.#prefix} ` : \"\";\n const maxChunkSize = this.#maxChunkSize - prefix.length;\n\n for (let i = 0; i < text.length; i += maxChunkSize) {\n const chunkText = text.slice(i, i + maxChunkSize);\n chunks.push({ text: `${prefix}${chunkText}` });\n }\n return chunks;\n }\n}\n","import type { ILogger } from \"@gearbox-protocol/sdk/onchain\";\nimport { prettifyError } from \"zod\";\nimport { SlackNotifier } from \"./SlackNotifier.js\";\nimport { NotificationConfig } from \"./schema.js\";\nimport { TelegramNotifier } from \"./TelegramNotifier.js\";\nimport type { INotifier } from \"./types.js\";\n\nexport function createNotifier(\n config: NotificationConfig,\n logger?: ILogger,\n): INotifier | undefined {\n const parsed = NotificationConfig.safeParse(config);\n if (!parsed.success) {\n console.log(\">>>>\", parsed.error);\n logger?.warn(`invalid notification config: ${prettifyError(parsed.error)}`);\n return undefined;\n }\n\n switch (parsed.data.type) {\n case \"telegram\":\n return new TelegramNotifier(parsed.data, logger);\n case \"slack\":\n return new SlackNotifier(parsed.data, logger);\n }\n}\n","import type { ILogger } from \"@gearbox-protocol/sdk/onchain\";\nimport { withRetry } from \"viem\";\nimport type { CensoredString } from \"../CensoredString.js\";\nimport type { SignlConfig } from \"./schema.js\";\nimport { ThrottleManager } from \"./ThrottleManager.js\";\nimport type { ThrottleFn } from \"./types.js\";\n\nexport type SignlServiceOptions = SignlConfig & {\n retryInterval?: number;\n retryCount?: number;\n throttleFn?: ThrottleFn;\n};\n\nconst DEFAULT_RETRY_INTERVAL = 1000;\nconst DEFAULT_RETRY_COUNT = 5;\n\nexport default class SignlNotifier {\n readonly #logger?: ILogger;\n\n readonly #apiKey: CensoredString;\n readonly #teamId: CensoredString;\n readonly #retryInterval: number;\n readonly #retryCount: number;\n\n readonly #throttleManager = new ThrottleManager();\n readonly #throttleFn?: ThrottleFn;\n\n constructor(opts: SignlServiceOptions, logger?: ILogger) {\n this.#apiKey = opts.apiKey;\n this.#teamId = opts.teamId;\n this.#retryInterval = opts.retryInterval ?? DEFAULT_RETRY_INTERVAL;\n this.#retryCount = opts.retryCount ?? DEFAULT_RETRY_COUNT;\n this.#logger = logger;\n this.#throttleFn = opts.throttleFn;\n this.#logger?.info(opts, \"signl notifier configured\");\n }\n\n public alert(message: string, dedupeKey?: string): void {\n void this.#sendAlert(message, dedupeKey).catch(e => this.#logger?.error(e));\n }\n\n async #sendAlert(message: string, dedupeKey?: string): Promise<void> {\n if (dedupeKey && !this.#throttleManager.canSend(dedupeKey)) {\n return;\n }\n\n const text = message.slice(0, 64); // it's to be shown in mobile notifications anyways\n this.#logger?.debug(\"sending signl alert\");\n\n await withRetry(\n async () => {\n const resp = await fetch(\n `https://connect.signl4.com/api/v2/alerts?x-s4-api-key=${this.#apiKey.value}`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n category: \"emergency\",\n severity: 0,\n teamId: this.#teamId.value,\n text,\n title: \"GEARBOX ALERT\",\n }),\n },\n );\n if (resp.ok) {\n this.#logger?.warn(\"signl alert sent\");\n const data = await resp.json();\n this.#logger?.info(`signl alert response: ${JSON.stringify(data)}`);\n } else {\n throw new Error(`signl api error ${resp.status}: ${resp.statusText}`);\n }\n },\n { delay: this.#retryInterval, retryCount: this.#retryCount },\n );\n\n if (dedupeKey) {\n this.#throttleManager.onSent(dedupeKey, this.#throttleFn);\n }\n }\n}\n","import {\n ADDRESS_0X0,\n AddressMap,\n type ILogger,\n} from \"@gearbox-protocol/sdk/onchain\";\nimport type { Address } from \"viem\";\nimport { createNotifier } from \"./createNotifier.js\";\nimport SignlNotifier, { type SignlServiceOptions } from \"./SignlNotifier.js\";\nimport type { NotificationConfig } from \"./schema.js\";\nimport type {\n IDedupableNotification,\n INotification,\n INotificationService,\n INotifier,\n NotificationLike,\n NotificationSeverity,\n} from \"./types.js\";\n\nexport interface NotificationsServiceOptions {\n notifications: Array<NotificationConfig & { recipient?: Address }>;\n signl?: SignlServiceOptions;\n}\n\nexport class NotificationsService implements INotificationService {\n readonly #logger?: ILogger;\n readonly #notifiers = new AddressMap<INotifier>();\n readonly #signlNotifier?: SignlNotifier;\n\n constructor(options: NotificationsServiceOptions, logger?: ILogger) {\n this.#logger = logger;\n for (const n of options.notifications) {\n const recipient = n.recipient ?? ADDRESS_0X0;\n const notifier = createNotifier(n, logger);\n if (notifier) {\n this.#notifiers.upsert(recipient, notifier);\n }\n }\n\n if (options.signl) {\n this.#signlNotifier = new SignlNotifier(options.signl);\n } else {\n this.#logger?.warn(\"signl notifier not configured\");\n }\n }\n\n public registerRecipient(\n address: Address,\n options: NotificationConfig,\n ): void {\n const notifier = createNotifier(options, this.#logger);\n if (notifier) {\n this.#notifiers.upsert(address, notifier);\n }\n }\n\n public signl(message: string, dedupeKey?: string): void {\n this.#signlNotifier?.alert(message, dedupeKey);\n }\n\n public alert(msg: NotificationLike): void {\n this.#notify(msg, \"alert\");\n }\n\n public notify(msg: NotificationLike): void {\n this.#notify(msg, \"notification\");\n }\n\n #notify(msg: NotificationLike, severity: NotificationSeverity): void {\n const message = this.#toNotification(msg);\n for (const [addr, notifier] of this.#notifiers.entries()) {\n const recipient = addr === ADDRESS_0X0 ? undefined : addr;\n const recipientNotification = message.messageFor(recipient);\n if (recipientNotification) {\n const notification = this.#toDedupableNotification(\n recipientNotification,\n );\n notifier.notify(notification, severity);\n // log global notifications\n if (addr === ADDRESS_0X0) {\n if (severity === \"alert\") {\n this.#logger?.warn(notification.plain);\n } else {\n this.#logger?.debug(notification.plain);\n }\n }\n }\n }\n }\n\n #toNotification(message: NotificationLike): INotification {\n // global notification without deduplication\n if (typeof message === \"string\" || !(\"messageFor\" in message)) {\n return {\n messageFor: (recipient?: Address) => (recipient ? undefined : message),\n };\n }\n return message;\n }\n\n #toDedupableNotification(\n msg: string | IDedupableNotification,\n ): IDedupableNotification {\n if (typeof msg === \"string\") {\n return {\n plain: msg,\n };\n }\n return msg;\n }\n}\n","import { Command, Option } from \"@commander-js/extra-typings\";\nimport * as z4 from \"zod/v4/core\";\nimport { decompressObject } from \"./compressedConfig.js\";\nimport type { TemplateData } from \"./resolveYamlFiles.js\";\nimport { resolveYamlFiles } from \"./resolveYamlFiles.js\";\n\nexport const zommandRegistry = z4.registry<{\n flags: string;\n env?: string;\n description?: string;\n}>();\n\nexport interface ZommandOptions<T extends z4.$ZodTypes> {\n schema: T;\n templateData?: TemplateData;\n /**\n * If value is string, it's used as default value for config file\n */\n configFile?: boolean | string;\n /**\n * If true, allows to pass config zlib compressed config as --inline-config=... or INLINE_CONFIG env var\n */\n inlineConfig?: boolean;\n}\n\nexport class Zommand<\n T extends z4.$ZodTypes,\n Args extends any[] = [],\n> extends Command<Args, z4.output<T>> {\n #schema: T;\n #templatedData?: TemplateData;\n #envToObjectKeys: Record<string, string> = {};\n\n constructor(name: string, opts: ZommandOptions<T>) {\n super(name);\n const {\n schema,\n templateData,\n configFile = true,\n inlineConfig = true,\n } = opts;\n this.#schema = schema;\n this.#templatedData = templateData;\n const def = this.#schema._zod.def;\n\n if (def.type === \"object\") {\n this.#addOptionsFromObject(def);\n } else if (def.type === \"union\") {\n for (const o of def.options) {\n const opt = o as z4.$ZodTypes;\n if (opt._zod.def.type === \"object\") {\n this.#addOptionsFromObject(opt._zod.def);\n }\n }\n } else {\n throw new Error(\n `expected object schema, got ${this.#schema._zod.def.type}`,\n );\n }\n\n if (configFile) {\n let opt = new Option(\"--config [file]\", \"config file (or s3 link\");\n if (typeof configFile === \"string\") {\n opt = opt.default(configFile);\n }\n this.addOption(opt);\n }\n\n if (inlineConfig) {\n this.addOption(new Option(\"--inline-config [config]\", \"inline config\"));\n }\n }\n\n #addOptionsFromObject(def: z4.$ZodObjectDef): void {\n const shape = def.shape;\n for (const [key, optionSchema] of Object.entries(shape)) {\n const meta = zommandRegistry.get(optionSchema);\n if (!meta) {\n continue;\n }\n // this avoids duplicate options in case of discriminated unions\n const existing = this.options.find(o => o.flags === meta.flags);\n if (!existing) {\n let description = meta.description;\n if (meta.env) {\n description = `${description} (env variable ${meta.env})`;\n }\n this.addOption(new Option(meta.flags, description));\n if (meta.env) {\n this.#envToObjectKeys[meta.env] = key;\n }\n }\n }\n }\n\n override action(\n fn: (\n this: this,\n ...args: [...Args, z4.output<T>, this]\n ) => void | Promise<void>,\n ): this {\n return super.action(async (...args: [...Args, any, this]) => {\n const argz = args;\n const _cmd = argz.splice(-1);\n const [{ config, inlineConfig, ...opts }] = argz.splice(-1);\n\n let fromYaml: object = {};\n if (config) {\n fromYaml = await resolveYamlFiles(config, {\n ...(process.env as Record<string, string>),\n ...this.#templatedData,\n });\n }\n let fromInlineConfig: object = {};\n if (inlineConfig) {\n fromInlineConfig = await decompressObject(\n inlineConfig,\n this.#templatedData,\n );\n } else if (process.env.INLINE_CONFIG) {\n fromInlineConfig = await decompressObject(\n process.env.INLINE_CONFIG,\n this.#templatedData,\n );\n }\n\n const schemaFromEnv: Record<string, string> = {};\n for (const [env, key] of Object.entries(this.#envToObjectKeys)) {\n if (process.env[env]) {\n schemaFromEnv[key] = process.env[env]!;\n }\n }\n\n // deep merge is not required: env and cli flags are for top-level only\n const combined = {\n ...schemaFromEnv,\n ...fromYaml,\n ...fromInlineConfig,\n ...opts,\n };\n\n const data = z4.parse(this.#schema, combined);\n await fn.apply(this, [...argz, data, this]);\n });\n }\n}\n","import { SUPPORTED_NETWORKS } from \"@gearbox-protocol/sdk/onchain\";\nimport { z } from \"zod/v4\";\nimport { CensoredString } from \"./CensoredString.js\";\nimport { CensoredURL } from \"./CensoredURL.js\";\nimport { stringArrayLike } from \"./schemas/schema-primitives.js\";\nimport { zommandRegistry } from \"./Zommand.js\";\n\nexport const RpcProvider = z.enum([\n \"alchemy\",\n \"drpc\",\n \"ankr\",\n \"thirdweb\",\n \"custom\",\n \"erpc\",\n]);\nexport type RpcProvider = z.infer<typeof RpcProvider>;\n\nexport const ProvidersSchema = z.object({\n network: z.enum(SUPPORTED_NETWORKS).register(zommandRegistry, {\n flags: \"--network <network>\",\n description: \"Gearbox-supported network\",\n env: \"NETWORK\",\n }),\n /**\n * RPC providers to use\n */\n jsonRpcProviders: stringArrayLike()\n .pipe(z.array(z.url().transform(CensoredURL.transform)))\n .transform(a => (a.length ? a : undefined))\n .optional()\n .register(zommandRegistry, {\n flags: \"--json-rpc-providers <urls...>\",\n description: \"RPC providers to use, comma separated full http urls.\",\n env: \"JSON_RPC_PROVIDERS\",\n }),\n /**\n * RPC providers to use with their keys\n * Order matters\n */\n enabledProviders: stringArrayLike()\n .pipe(z.array(RpcProvider))\n .optional()\n .register(zommandRegistry, {\n flags: \"--enabled-providers <providers...>\",\n description:\n \"Keyed RPC providers to use, comma separated, order matters. Possible values: custom (for full json rpc urls)/alchemy/drpc/ankr/thirdweb\",\n env: \"ENABLED_PROVIDERS\",\n }),\n /**\n * Alchemy API keys to use\n */\n alchemyKeys: stringArrayLike()\n .pipe(z.array(z.string().transform(CensoredString.transform)))\n .transform(a => (a.length ? a : undefined))\n .optional()\n .register(zommandRegistry, {\n flags: \"--alchemy-keys <keys...>\",\n description: \"Alchemy API keys to use, comma separated\",\n env: \"ALCHEMY_KEYS\",\n }),\n /**\n * DRPC API keys to use\n */\n drpcKeys: stringArrayLike()\n .pipe(z.array(z.string().transform(CensoredString.transform)))\n .transform(a => (a.length ? a : undefined))\n .optional()\n .register(zommandRegistry, {\n flags: \"--drpc-keys <keys...>\",\n description: \"DRPC API keys to use, comma separated\",\n env: \"DRPC_KEYS\",\n }),\n /**\n * Ankr API keys to use\n */\n ankrKeys: stringArrayLike()\n .pipe(z.array(z.string().transform(CensoredString.transform)))\n .transform(a => (a.length ? a : undefined))\n .optional()\n .register(zommandRegistry, {\n flags: \"--ankr-keys <keys...>\",\n description: \"Ankr API keys to use, comma separated\",\n env: \"ANKR_KEYS\",\n }),\n /**\n * Thirdweb API keys to use\n */\n thirdwebKeys: stringArrayLike()\n .pipe(z.array(z.string().transform(CensoredString.transform)))\n .transform(a => (a.length ? a : undefined))\n .optional()\n .register(zommandRegistry, {\n flags: \"--thirdweb-keys <keys...>\",\n description: \"Thirdweb API keys to use, comma separated\",\n env: \"THIRDWEB_KEYS\",\n }),\n /**\n * If set, eRPC will be added as first provider\n */\n erpcProjectId: z.string().optional().register(zommandRegistry, {\n flags: \"--erpc-project-id <project-id>\",\n description: \"If set, eRPC will be added as first provider\",\n env: \"ERPC_PROJECT_ID\",\n }),\n /**\n * eRPC URL to use\n */\n erpcUrl: z.url().default(\"http://erpc.local\").register(zommandRegistry, {\n flags: \"--erpc-url <url>\",\n description: \"eRPC URL to use\",\n env: \"ERPC_URL\",\n }),\n /**\n * Timeout for JSON RPC requests, in milliseconds\n */\n jsonRpcTimeout: z.coerce\n .number()\n .int()\n .positive()\n .optional()\n .register(zommandRegistry, {\n flags: \"--json-rpc-timeout <timeout>\",\n description: \"Timeout for JSON RPC requests, in milliseconds\",\n env: \"JSON_RPC_TIMEOUT\",\n }),\n});\n\nexport type ProvidersSchema = z.infer<typeof ProvidersSchema>;\n","import {\n GetSecretValueCommand,\n SecretsManagerClient,\n} from \"@aws-sdk/client-secrets-manager\";\n\nexport class SecretsManager {\n #smClient?: SecretsManagerClient;\n #secrets: Map<string, string> = new Map();\n\n public async secret(key: string): Promise<string> {\n const [SecretId, ...jsonPath] = key.split(\".\");\n const secretStr = await this.#getSecret(SecretId);\n if (!jsonPath.length) {\n return secretStr;\n }\n let v = JSON.parse(secretStr);\n for (const p of jsonPath) {\n v = v[p];\n }\n if (!v || typeof v !== \"string\") {\n throw new Error(`cannot find secret '${key}'`);\n }\n return v;\n }\n\n public async secretRaw(key: string): Promise<unknown> {\n const val = await this.#getSecret(key);\n try {\n return JSON.parse(val);\n } catch {\n return val;\n }\n }\n\n async #getSecret(SecretId: string): Promise<string> {\n if (this.#secrets.has(SecretId)) {\n return this.#secrets.get(SecretId)!;\n }\n\n if (!this.#smClient) {\n this.#smClient = new SecretsManagerClient({});\n }\n // https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/ssm/command/GetParameterCommand/\n const { SecretString } = await this.#smClient.send(\n new GetSecretValueCommand({ SecretId }),\n );\n if (!SecretString) {\n throw new Error(`secret '${SecretId}' not found`);\n }\n this.#secrets.set(SecretId, SecretString);\n\n return SecretString;\n }\n}\n\nexport const secretsManagerProxy = (\n mgr?: SecretsManager,\n): Record<string, Promise<unknown>> =>\n new Proxy<any>(mgr ?? new SecretsManager(), {\n get(target, prop) {\n if (\n typeof prop === \"string\" &&\n ![\"secret\", \"secretRaw\", \"then\", \"catch\", \"finally\"].includes(prop)\n ) {\n return target.secretRaw(prop);\n }\n },\n });\n","import { GetParameterCommand, SSMClient } from \"@aws-sdk/client-ssm\";\n\nexport class SSMManager {\n #ssmClient?: SSMClient;\n #parameters: Map<string, string> = new Map();\n\n public async parameter(name: string): Promise<string> {\n if (this.#parameters.has(name)) {\n return this.#parameters.get(name)!;\n }\n\n if (!this.#ssmClient) {\n this.#ssmClient = new SSMClient({});\n }\n\n const response = await this.#ssmClient.send(\n new GetParameterCommand({\n Name: name,\n }),\n );\n const value = response.Parameter?.Value;\n if (!value) {\n throw new Error(`parameter ${name} value not found`);\n }\n this.#parameters.set(name, value);\n return value;\n }\n}\n\nexport const ssmManagerProxy = (\n mgr?: SSMManager,\n): Record<string, Promise<unknown>> =>\n new Proxy<any>(mgr ?? new SSMManager(), {\n get(target, prop) {\n if (\n typeof prop === \"string\" &&\n ![\"parameter\", \"then\", \"catch\", \"finally\"].includes(prop)\n ) {\n return target.parameter(prop);\n }\n },\n });\n","export interface IValue<V extends string = string> {\n value: V;\n}\n\nexport function uncensorMap<V extends string = string>(\n map: Record<string, IValue<V>>,\n): Record<string, V> {\n return Object.fromEntries(Object.entries(map).map(([k, v]) => [k, v.value]));\n}\n","import type { ILogger, NetworkType } from \"@gearbox-protocol/sdk/onchain\";\nimport { AddressMap } from \"@gearbox-protocol/sdk/onchain\";\nimport { z } from \"zod/v4\";\nimport { fetchRetry } from \"./fetchRetry.js\";\nimport {\n type ClientWhitelistItem,\n whitelistItemSchema,\n} from \"./schemas/whitelist-schema.js\";\n\nconst REFRESH_INTERVAL_MS = 10 * 60 * 1000;\n\nconst whitelistResponseSchema = z.array(whitelistItemSchema);\n\n/**\n * Whitelist mode:\n * - `hard`: entries come from static config and block the action entirely.\n * - `soft`: entries come from the remote endpoint, do not block the action,\n * but can be used to annotate notifications when the action fails.\n */\nexport type WhitelistMode = \"soft\" | \"hard\";\n\nexport interface WhitelistOptions {\n /**\n * Full URL of the remote (soft) whitelist endpoint. When omitted, only the\n * static hard whitelist is used.\n */\n url?: string;\n network: NetworkType;\n /**\n * Static (hard) whitelist entries, supplied via config.\n */\n hard?: ClientWhitelistItem[];\n logger?: ILogger;\n}\n\n/**\n * Holds two whitelists:\n * - a `hard` whitelist built once from static config, always available;\n * - a `soft` whitelist fetched from the backend and kept in\n * memory with a periodic refresh.\n *\n * On soft fetch failure the previous in-memory copy is retained; if no\n * successful fetch has occurred yet the soft whitelist is considered empty.\n */\nexport class Whitelist {\n readonly #url?: string;\n readonly #network: NetworkType;\n readonly #logger?: ILogger;\n\n #soft = new AddressMap<ClientWhitelistItem>();\n readonly #hard: AddressMap<ClientWhitelistItem>;\n #refreshInterval?: number;\n\n constructor({ url, network, hard = [], logger }: WhitelistOptions) {\n this.#url = url;\n this.#network = network;\n this.#logger = logger?.child?.({ name: \"whitelist\" }) ?? logger;\n this.#hard = new AddressMap<ClientWhitelistItem>();\n for (const entry of hard) {\n this.#hard.upsert(entry.address, entry);\n }\n }\n\n /**\n * Performs the initial soft fetch and starts the periodic refresh timer.\n * Failure of the initial fetch is non-fatal: the soft whitelist stays empty.\n * When no `url` is configured this is a no-op (only the hard whitelist is used).\n */\n public async start(): Promise<void> {\n if (!this.#url) {\n this.#logger?.debug(\n `no whitelist url configured, using ${this.#hard.size} hard whitelist entries for ${this.#network}`,\n );\n return;\n }\n this.#logger?.info(\n `loading ${this.#network} whitelist from ${this.#url}, refresh every ${REFRESH_INTERVAL_MS / 1000}s`,\n );\n await this.#refresh();\n this.#refreshInterval = setInterval(() => {\n this.#refresh().catch(e => {\n this.#logger?.warn(`unexpected whitelist refresh error: ${e}`);\n });\n }, REFRESH_INTERVAL_MS) as unknown as number;\n }\n\n /** Stops the refresh timer. */\n public stop(): void {\n if (this.#refreshInterval) {\n clearInterval(this.#refreshInterval);\n this.#refreshInterval = undefined;\n }\n }\n\n /**\n * Fetches the soft whitelist from the backend, parses it and atomically\n * replaces the in-memory map. On any error logs a warning and retains\n * the previous map.\n */\n async #refresh(): Promise<void> {\n if (!this.#url) {\n return;\n }\n try {\n const resp = await fetchRetry(this.#url);\n if (!resp.ok) {\n throw new Error(\n `whitelist fetch failed: ${resp.status} ${resp.statusText}`,\n );\n }\n const data = await resp.json();\n const items = whitelistResponseSchema\n .parse(data)\n .filter(i => i.network === this.#network);\n const next = new AddressMap<ClientWhitelistItem>();\n for (const item of items) {\n next.upsert(item.address, {\n address: item.address,\n reason: item.reason,\n expiresAt: item.expiresAt,\n contractType: item.contractType,\n });\n }\n this.#soft = next;\n this.#logger?.debug(\n `loaded ${items.length} soft whitelist entries for ${this.#network}`,\n );\n } catch (e) {\n this.#logger?.warn(\n `failed to refresh whitelist from ${this.#url}, keeping previous version: ${e}`,\n );\n }\n }\n\n /**\n * Returns the matching whitelist entry for the given address in the\n * requested mode, or `undefined` if absent or expired.\n */\n public has(\n address: string,\n mode: WhitelistMode,\n ): ClientWhitelistItem | undefined {\n const list = mode === \"hard\" ? this.#hard : this.#soft;\n const item = list.get(address);\n if (!item) {\n return undefined;\n }\n if (item.expiresAt !== undefined && Date.now() / 1000 >= item.expiresAt) {\n return undefined;\n }\n return item;\n }\n}\n"],"mappings":"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"}
|
package/dist/schema.d.ts
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
1
|
import { z } from "zod/v4";
|
|
2
2
|
//#region src/schemas/schema-primitives.d.ts
|
|
3
|
-
declare const boolLike: () => z.ZodPipe<z.ZodAny, z.ZodTransform<boolean, any>>;
|
|
4
|
-
declare const stringArrayLike: () => z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>]>;
|
|
5
|
-
declare const optionalStringArrayLike: () => z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>]>>, z.ZodTransform<string[] | undefined, string[] | undefined>>;
|
|
3
|
+
export declare const boolLike: () => z.ZodPipe<z.ZodAny, z.ZodTransform<boolean, any>>;
|
|
4
|
+
export declare const stringArrayLike: () => z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>]>;
|
|
5
|
+
export declare const optionalStringArrayLike: () => z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>]>>, z.ZodTransform<string[] | undefined, string[] | undefined>>;
|
|
6
6
|
/**
|
|
7
7
|
* Like Address from abitype/zod, but converts an address into an address that is checksum encoded.
|
|
8
8
|
*/
|
|
9
|
-
declare const addressLike: () => z.ZodPipe<z.ZodString, z.ZodTransform<`0x${string}`, string>>;
|
|
10
|
-
declare const addressArrayLike: () => z.ZodPipe<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>]>, z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<`0x${string}`, string>>>>;
|
|
11
|
-
declare const optionalAddressArrayLike: () => z.ZodPipe<z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>]>, z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<`0x${string}`, string>>>>>, z.ZodTransform<`0x${string}`[] | undefined, `0x${string}`[] | undefined>>;
|
|
9
|
+
export declare const addressLike: () => z.ZodPipe<z.ZodString, z.ZodTransform<`0x${string}`, string>>;
|
|
10
|
+
export declare const addressArrayLike: () => z.ZodPipe<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>]>, z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<`0x${string}`, string>>>>;
|
|
11
|
+
export declare const optionalAddressArrayLike: () => z.ZodPipe<z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>]>, z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<`0x${string}`, string>>>>>, z.ZodTransform<`0x${string}`[] | undefined, `0x${string}`[] | undefined>>;
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/schemas/whitelist-schema.d.ts
|
|
14
14
|
/**
|
|
15
15
|
* Schema for editing whitelist items.
|
|
16
16
|
* We can input multiple addresses at once.
|
|
17
17
|
*/
|
|
18
|
-
declare const whitelistItemsSchema: z.ZodObject<{
|
|
18
|
+
export declare const whitelistItemsSchema: z.ZodObject<{
|
|
19
19
|
network: z.ZodEnum<{
|
|
20
|
-
Mainnet: "Mainnet";
|
|
21
20
|
Arbitrum: "Arbitrum";
|
|
22
|
-
Optimism: "Optimism";
|
|
23
|
-
Base: "Base";
|
|
24
|
-
Sonic: "Sonic";
|
|
25
|
-
MegaETH: "MegaETH";
|
|
26
|
-
Monad: "Monad";
|
|
27
|
-
Berachain: "Berachain";
|
|
28
21
|
Avalanche: "Avalanche";
|
|
29
22
|
BNB: "BNB";
|
|
30
|
-
|
|
23
|
+
Base: "Base";
|
|
24
|
+
Berachain: "Berachain";
|
|
31
25
|
Etherlink: "Etherlink";
|
|
32
26
|
Hemi: "Hemi";
|
|
33
27
|
Lisk: "Lisk";
|
|
28
|
+
Mainnet: "Mainnet";
|
|
29
|
+
MegaETH: "MegaETH";
|
|
30
|
+
Monad: "Monad";
|
|
31
|
+
Optimism: "Optimism";
|
|
34
32
|
Plasma: "Plasma";
|
|
35
33
|
Somnia: "Somnia";
|
|
34
|
+
Sonic: "Sonic";
|
|
35
|
+
WorldChain: "WorldChain";
|
|
36
36
|
}>;
|
|
37
37
|
addresses: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<`0x${string}`, string>>>;
|
|
38
38
|
reason: z.ZodDefault<z.ZodString>;
|
|
39
39
|
issue: z.ZodOptional<z.ZodString>;
|
|
40
40
|
expiresAt: z.ZodOptional<z.ZodNumber>;
|
|
41
41
|
}, z.core.$strip>;
|
|
42
|
-
type WhitelistItems = z.infer<typeof whitelistItemsSchema>;
|
|
42
|
+
export type WhitelistItems = z.infer<typeof whitelistItemsSchema>;
|
|
43
43
|
/**
|
|
44
44
|
* Schema for a single whitelist item as returned by the API
|
|
45
45
|
*/
|
|
46
|
-
declare const whitelistItemSchema: z.ZodObject<{
|
|
46
|
+
export declare const whitelistItemSchema: z.ZodObject<{
|
|
47
47
|
network: z.ZodEnum<{
|
|
48
|
-
Mainnet: "Mainnet";
|
|
49
48
|
Arbitrum: "Arbitrum";
|
|
50
|
-
Optimism: "Optimism";
|
|
51
|
-
Base: "Base";
|
|
52
|
-
Sonic: "Sonic";
|
|
53
|
-
MegaETH: "MegaETH";
|
|
54
|
-
Monad: "Monad";
|
|
55
|
-
Berachain: "Berachain";
|
|
56
49
|
Avalanche: "Avalanche";
|
|
57
50
|
BNB: "BNB";
|
|
58
|
-
|
|
51
|
+
Base: "Base";
|
|
52
|
+
Berachain: "Berachain";
|
|
59
53
|
Etherlink: "Etherlink";
|
|
60
54
|
Hemi: "Hemi";
|
|
61
55
|
Lisk: "Lisk";
|
|
56
|
+
Mainnet: "Mainnet";
|
|
57
|
+
MegaETH: "MegaETH";
|
|
58
|
+
Monad: "Monad";
|
|
59
|
+
Optimism: "Optimism";
|
|
62
60
|
Plasma: "Plasma";
|
|
63
61
|
Somnia: "Somnia";
|
|
62
|
+
Sonic: "Sonic";
|
|
63
|
+
WorldChain: "WorldChain";
|
|
64
64
|
}>;
|
|
65
65
|
category: z.ZodString;
|
|
66
66
|
address: z.ZodPipe<z.ZodString, z.ZodTransform<`0x${string}`, string>>;
|
|
@@ -70,17 +70,16 @@ declare const whitelistItemSchema: z.ZodObject<{
|
|
|
70
70
|
createdAt: z.ZodNumber;
|
|
71
71
|
expiresAt: z.ZodOptional<z.ZodNumber>;
|
|
72
72
|
}, z.core.$strip>;
|
|
73
|
-
type WhitelistItem = z.infer<typeof whitelistItemSchema>;
|
|
73
|
+
export type WhitelistItem = z.infer<typeof whitelistItemSchema>;
|
|
74
74
|
/**
|
|
75
75
|
* Subset of {@link WhitelistItemSchema} actually consumed by client apps.
|
|
76
76
|
*/
|
|
77
|
-
declare const clientWhitelistItemSchema: z.ZodObject<{
|
|
77
|
+
export declare const clientWhitelistItemSchema: z.ZodObject<{
|
|
78
78
|
address: z.ZodPipe<z.ZodString, z.ZodTransform<`0x${string}`, string>>;
|
|
79
79
|
reason: z.ZodDefault<z.ZodString>;
|
|
80
80
|
contractType: z.ZodOptional<z.ZodString>;
|
|
81
81
|
expiresAt: z.ZodOptional<z.ZodNumber>;
|
|
82
82
|
}, z.core.$strip>;
|
|
83
|
-
type ClientWhitelistItem = z.infer<typeof clientWhitelistItemSchema>;
|
|
83
|
+
export type ClientWhitelistItem = z.infer<typeof clientWhitelistItemSchema>;
|
|
84
84
|
//#endregion
|
|
85
|
-
export { ClientWhitelistItem, WhitelistItem, WhitelistItems, addressArrayLike, addressLike, boolLike, clientWhitelistItemSchema, optionalAddressArrayLike, optionalStringArrayLike, stringArrayLike, whitelistItemSchema, whitelistItemsSchema };
|
|
86
85
|
//# sourceMappingURL=schema.d.ts.map
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","names":[],"sources":["../src/schemas/schema-primitives.ts","../src/schemas/whitelist-schema.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","names":[],"sources":["../src/schemas/schema-primitives.ts","../src/schemas/whitelist-schema.ts"],"mappings":";;qBAGa,gBAAQ,EAAA,QAAA,EAAA,QAAA,EAAA;qBAQR,uBAAe,EAAA,mBAAA,EAAA,SAAA,EAAA,YAAA,EAAA,QAAA,EAAA,WAAA,EAAA;qBAGf,+BAAuB,EAAA,QAAA,EAAA,YAAA,EAAA,mBAAA,EAAA,SAAA,EAAA,YAAA,EAAA,QAAA,EAAA,WAAA,EAAA,oCAAA,EAAA;;;;qBAQvB,mBAAW,EAAA,QAAA,EAAA,WAAA,EAAA;qBAaX,wBAAgB,EAAA,QAAA,EAAA,mBAAA,EAAA,SAAA,EAAA,YAAA,EAAA,QAAA,EAAA,WAAA,EAAA,mCAAA,EAAA,SAAA,EAAA,QAAA,EAAA,WAAA,EAAA;qBAGhB,gCAAwB,EAAA,QAAA,EAAA,YAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,SAAA,EAAA,YAAA,EAAA,QAAA,EAAA,WAAA,EAAA,mCAAA,EAAA,SAAA,EAAA,QAAA,EAAA,WAAA,EAAA,yCAAA,EAAA;;;;;;;qBC7BxB,sBAAoB,EAAA;;;;;;;;;;;;;;;;;;;;;;;GAM/B,EAAA,KAAA;YAEU,iBAAiB,EAAE,aAAa;;;;qBAK/B,qBAAmB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GAS9B,EAAA,KAAA;YAEU,gBAAgB,EAAE,aAAa;;;;qBAK9B,2BAAyB,EAAA;;;;;GAKpC,EAAA,KAAA;YAEU,sBAAsB,EAAE,aAAa"}
|
package/dist/schema.js
CHANGED
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","names":[],"sources":["../src/schemas/schema-primitives.ts","../src/schemas/whitelist-schema.ts"],"sourcesContent":["import { getAddress, isAddress } from \"viem\";\nimport { z } from \"zod/v4\";\n\nexport const boolLike = () =>\n z.any().transform(v => {\n if (typeof v === \"string\") {\n return [\"true\", \"1\"].includes(v.toLowerCase());\n }\n return Boolean(v);\n });\n\nexport const stringArrayLike = () =>\n z.union([z.array(z.string()), z.string().transform(val => val.split(\",\"))]);\n\nexport const optionalStringArrayLike = () =>\n stringArrayLike()\n .optional()\n .transform(v => (v?.length ? v : undefined));\n\n/**\n * Like Address from abitype/zod, but converts an address into an address that is checksum encoded.\n */\nexport const addressLike = () =>\n z.string().transform((val, ctx) => {\n if (!isAddress(val)) {\n ctx.issues.push({\n code: \"custom\",\n message: `invalid address ${val}`,\n input: ctx.value,\n });\n }\n\n return getAddress(val);\n });\n\nexport const addressArrayLike = () =>\n stringArrayLike().pipe(z.array(addressLike()));\n\nexport const optionalAddressArrayLike = () =>\n stringArrayLike()\n .pipe(z.array(addressLike()))\n .optional()\n .transform(v => (v?.length ? v : undefined));\n","// Mirror of packages/shared/src/whitelist-schema.ts; keep in sync.\nimport { NetworkType } from \"@gearbox-protocol/sdk\";\nimport { z } from \"zod/v4\";\nimport { addressLike } from \"./schema-primitives.js\";\n\n/**\n * Schema for editing whitelist items.\n * We can input multiple addresses at once.\n */\nexport const whitelistItemsSchema = z.object({\n network: NetworkType,\n addresses: z.array(addressLike()).min(1),\n reason: z.string().default(\"\"),\n issue: z.string().optional(),\n expiresAt: z.number().optional(),\n});\n\nexport type WhitelistItems = z.infer<typeof whitelistItemsSchema>;\n\n/**\n * Schema for a single whitelist item as returned by the API\n */\nexport const whitelistItemSchema = z.object({\n network: NetworkType,\n category: z.string(),\n address: addressLike(),\n reason: z.string().default(\"\"),\n issue: z.string().optional(),\n contractType: z.string().optional(),\n createdAt: z.number(),\n expiresAt: z.number().optional(),\n});\n\nexport type WhitelistItem = z.infer<typeof whitelistItemSchema>;\n\n/**\n * Subset of {@link WhitelistItemSchema} actually consumed by client apps.\n */\nexport const clientWhitelistItemSchema = whitelistItemSchema.pick({\n address: true,\n reason: true,\n expiresAt: true,\n contractType: true,\n});\n\nexport type ClientWhitelistItem = z.infer<typeof clientWhitelistItemSchema>;\n"],"mappings":";;;;AAGA,MAAa,iBACX,EAAE,IAAI,CAAC,CAAC,WAAU,MAAK;CACrB,IAAI,OAAO,MAAM,UACf,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC;CAE/C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAEH,MAAa,wBACX,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,WAAU,QAAO,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC;AAE5E,MAAa,gCACX,gBAAgB,CAAC,CACd,SAAS,CAAC,CACV,WAAU,MAAM,GAAG,SAAS,IAAI,KAAA,CAAU;;;;AAK/C,MAAa,oBACX,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ;CACjC,IAAI,CAAC,UAAU,GAAG,GAChB,IAAI,OAAO,KAAK;EACd,MAAM;EACN,SAAS,mBAAmB;EAC5B,OAAO,IAAI;CACb,CAAC;CAGH,OAAO,WAAW,GAAG;AACvB,CAAC;AAEH,MAAa,yBACX,gBAAgB,CAAC,CAAC,KAAK,EAAE,MAAM,YAAY,CAAC,CAAC;AAE/C,MAAa,iCACX,gBAAgB,CAAC,CACd,KAAK,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,CAC5B,SAAS,CAAC,CACV,WAAU,MAAM,GAAG,SAAS,IAAI,KAAA,CAAU;;;;;;;ACjC/C,MAAa,uBAAuB,EAAE,OAAO;CAC3C,SAAS;CACT,WAAW,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;CACvC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE;CAC7B,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;;;;AAOD,MAAa,sBAAsB,EAAE,OAAO;CAC1C,SAAS;CACT,UAAU,EAAE,OAAO;CACnB,SAAS,YAAY;CACrB,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE;CAC7B,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,cAAc,EAAE,OAAO,CAAC,CAAC,SAAS;CAClC,WAAW,EAAE,OAAO;CACpB,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;;;;AAOD,MAAa,4BAA4B,oBAAoB,KAAK;CAChE,SAAS;CACT,QAAQ;CACR,WAAW;CACX,cAAc;AAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"schema.js","names":[],"sources":["../src/schemas/schema-primitives.ts","../src/schemas/whitelist-schema.ts"],"sourcesContent":["import { getAddress, isAddress } from \"viem\";\nimport { z } from \"zod/v4\";\n\nexport const boolLike = () =>\n z.any().transform(v => {\n if (typeof v === \"string\") {\n return [\"true\", \"1\"].includes(v.toLowerCase());\n }\n return Boolean(v);\n });\n\nexport const stringArrayLike = () =>\n z.union([z.array(z.string()), z.string().transform(val => val.split(\",\"))]);\n\nexport const optionalStringArrayLike = () =>\n stringArrayLike()\n .optional()\n .transform(v => (v?.length ? v : undefined));\n\n/**\n * Like Address from abitype/zod, but converts an address into an address that is checksum encoded.\n */\nexport const addressLike = () =>\n z.string().transform((val, ctx) => {\n if (!isAddress(val)) {\n ctx.issues.push({\n code: \"custom\",\n message: `invalid address ${val}`,\n input: ctx.value,\n });\n }\n\n return getAddress(val);\n });\n\nexport const addressArrayLike = () =>\n stringArrayLike().pipe(z.array(addressLike()));\n\nexport const optionalAddressArrayLike = () =>\n stringArrayLike()\n .pipe(z.array(addressLike()))\n .optional()\n .transform(v => (v?.length ? v : undefined));\n","// Mirror of packages/shared/src/whitelist-schema.ts; keep in sync.\nimport { NetworkType } from \"@gearbox-protocol/sdk/onchain\";\nimport { z } from \"zod/v4\";\nimport { addressLike } from \"./schema-primitives.js\";\n\n/**\n * Schema for editing whitelist items.\n * We can input multiple addresses at once.\n */\nexport const whitelistItemsSchema = z.object({\n network: NetworkType,\n addresses: z.array(addressLike()).min(1),\n reason: z.string().default(\"\"),\n issue: z.string().optional(),\n expiresAt: z.number().optional(),\n});\n\nexport type WhitelistItems = z.infer<typeof whitelistItemsSchema>;\n\n/**\n * Schema for a single whitelist item as returned by the API\n */\nexport const whitelistItemSchema = z.object({\n network: NetworkType,\n category: z.string(),\n address: addressLike(),\n reason: z.string().default(\"\"),\n issue: z.string().optional(),\n contractType: z.string().optional(),\n createdAt: z.number(),\n expiresAt: z.number().optional(),\n});\n\nexport type WhitelistItem = z.infer<typeof whitelistItemSchema>;\n\n/**\n * Subset of {@link WhitelistItemSchema} actually consumed by client apps.\n */\nexport const clientWhitelistItemSchema = whitelistItemSchema.pick({\n address: true,\n reason: true,\n expiresAt: true,\n contractType: true,\n});\n\nexport type ClientWhitelistItem = z.infer<typeof clientWhitelistItemSchema>;\n"],"mappings":";;;;AAGA,MAAa,iBACX,EAAE,IAAI,CAAC,CAAC,WAAU,MAAK;CACrB,IAAI,OAAO,MAAM,UACf,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC;CAE/C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAEH,MAAa,wBACX,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,WAAU,QAAO,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC;AAE5E,MAAa,gCACX,gBAAgB,CAAC,CACd,SAAS,CAAC,CACV,WAAU,MAAM,GAAG,SAAS,IAAI,KAAA,CAAU;;;;AAK/C,MAAa,oBACX,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ;CACjC,IAAI,CAAC,UAAU,GAAG,GAChB,IAAI,OAAO,KAAK;EACd,MAAM;EACN,SAAS,mBAAmB;EAC5B,OAAO,IAAI;CACb,CAAC;CAGH,OAAO,WAAW,GAAG;AACvB,CAAC;AAEH,MAAa,yBACX,gBAAgB,CAAC,CAAC,KAAK,EAAE,MAAM,YAAY,CAAC,CAAC;AAE/C,MAAa,iCACX,gBAAgB,CAAC,CACd,KAAK,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,CAC5B,SAAS,CAAC,CACV,WAAU,MAAM,GAAG,SAAS,IAAI,KAAA,CAAU;;;;;;;ACjC/C,MAAa,uBAAuB,EAAE,OAAO;CAC3C,SAAS;CACT,WAAW,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;CACvC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE;CAC7B,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;;;;AAOD,MAAa,sBAAsB,EAAE,OAAO;CAC1C,SAAS;CACT,UAAU,EAAE,OAAO;CACnB,SAAS,YAAY;CACrB,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE;CAC7B,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,cAAc,EAAE,OAAO,CAAC,CAAC,SAAS;CAClC,WAAW,EAAE,OAAO;CACpB,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;;;;AAOD,MAAa,4BAA4B,oBAAoB,KAAK;CAChE,SAAS;CACT,QAAQ;CACR,WAAW;CACX,cAAc;AAChB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gearbox-protocol/cli-utils",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.4.1",
|
|
4
4
|
"description": "Utils for creating cli apps",
|
|
5
5
|
"homepage": "https://gearbox.fi",
|
|
6
6
|
"keywords": [
|
|
@@ -32,27 +32,27 @@
|
|
|
32
32
|
"dist"
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@aws-sdk/client-s3": "^3.
|
|
36
|
-
"@aws-sdk/client-secrets-manager": "^3.
|
|
37
|
-
"@aws-sdk/client-ssm": "^3.
|
|
35
|
+
"@aws-sdk/client-s3": "^3.1129.0",
|
|
36
|
+
"@aws-sdk/client-secrets-manager": "^3.1129.0",
|
|
37
|
+
"@aws-sdk/client-ssm": "^3.1129.0",
|
|
38
38
|
"@commander-js/extra-typings": "^15.0.0",
|
|
39
|
-
"@gearbox-protocol/sdk": "
|
|
39
|
+
"@gearbox-protocol/sdk": "^16.3.1",
|
|
40
40
|
"@vlad-yakovlev/telegram-md": "^2.1.0",
|
|
41
41
|
"abitype": "^1.3.0",
|
|
42
42
|
"commander": "^15.0.0",
|
|
43
43
|
"lodash-es": "^4.18.1",
|
|
44
44
|
"lru-cache": "^11.5.2",
|
|
45
45
|
"p-queue": "^9.3.3",
|
|
46
|
-
"viem": "^2.
|
|
47
|
-
"yaml": "^2.
|
|
48
|
-
"zod": "^4.
|
|
46
|
+
"viem": "^2.56.3",
|
|
47
|
+
"yaml": "^2.9.0",
|
|
48
|
+
"zod": "^4.6.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/lodash-es": "^4.17.12",
|
|
52
|
-
"@types/node": "^26.
|
|
53
|
-
"tsdown": "^0.
|
|
52
|
+
"@types/node": "^26.5.1",
|
|
53
|
+
"tsdown": "^0.23.0",
|
|
54
54
|
"typescript": "^7.0.2",
|
|
55
|
-
"vitest": "^
|
|
55
|
+
"vitest": "^5.0.0"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "tsdown",
|