@gearbox-protocol/cli-utils 9.2.3 → 9.2.5

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.js CHANGED
@@ -245,7 +245,8 @@ function compressObject(obj) {
245
245
  * Allows to pass template data to resolve promises/env
246
246
  */
247
247
  async function decompressObject(value, templateData) {
248
- const str = inflateSync(Buffer.from(value, "base64url")).toString("utf8");
248
+ const compressed = Buffer.from(value, "base64url");
249
+ const str = inflateSync(compressed).toString("utf8");
249
250
  return await resolveFromObject(JSON.parse(str), templateData);
250
251
  }
251
252
  //#endregion
@@ -466,12 +467,10 @@ function getProviders(config, logger) {
466
467
  };
467
468
  }));
468
469
  break;
469
- case "erpc":
470
- if (erpcProjectId && erpcUrl) result.push({
471
- name: "erpc",
472
- url: getErpcKey(network, erpcProjectId, erpcUrl)
473
- });
474
- break;
470
+ case "erpc": if (erpcProjectId && erpcUrl) result.push({
471
+ name: "erpc",
472
+ url: getErpcKey(network, erpcProjectId, erpcUrl)
473
+ });
475
474
  }
476
475
  if (logger) {
477
476
  const providers = result.filter((p) => !!p.url).map((p) => ({
@@ -571,7 +570,7 @@ const SignlConfig = z.object({
571
570
  //#endregion
572
571
  //#region src/notifications/ThrottleManager.ts
573
572
  function defaultBackoffFn(prevWait) {
574
- return Math.min(prevWait ? prevWait * 2 : 600 * 1e3, 1440 * 60 * 1e3);
573
+ return Math.min(prevWait ? prevWait * 2 : 6e5, 864e5);
575
574
  }
576
575
  /**
577
576
  * Manages per-feed throttling with exponential backoff.
@@ -1055,7 +1054,7 @@ function uncensorMap(map) {
1055
1054
  }
1056
1055
  //#endregion
1057
1056
  //#region src/Whitelist.ts
1058
- const REFRESH_INTERVAL_MS = 600 * 1e3;
1057
+ const REFRESH_INTERVAL_MS = 6e5;
1059
1058
  const whitelistResponseSchema = z.array(whitelistItemSchema);
1060
1059
  /**
1061
1060
  * Holds two whitelists:
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":["#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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/cli-utils",
3
- "version": "9.2.3",
3
+ "version": "9.2.5",
4
4
  "description": "Utils for creating cli apps",
5
5
  "homepage": "https://gearbox.fi",
6
6
  "keywords": [
@@ -32,11 +32,11 @@
32
32
  "dist"
33
33
  ],
34
34
  "dependencies": {
35
- "@aws-sdk/client-s3": "^3.1092.0",
36
- "@aws-sdk/client-secrets-manager": "^3.1092.0",
37
- "@aws-sdk/client-ssm": "^3.1092.0",
35
+ "@aws-sdk/client-s3": "^3.1102.0",
36
+ "@aws-sdk/client-secrets-manager": "^3.1102.0",
37
+ "@aws-sdk/client-ssm": "^3.1102.0",
38
38
  "@commander-js/extra-typings": "^15.0.0",
39
- "@gearbox-protocol/sdk": "^14.11.13",
39
+ "@gearbox-protocol/sdk": "^14.11.17",
40
40
  "@vlad-yakovlev/telegram-md": "^2.1.0",
41
41
  "abitype": "^1.3.0",
42
42
  "commander": "^15.0.0",