// Whoever runs a deployment owns its abuse-vs-friction tradeoff, so these are
// env vars rather than hardcoded. Defaults suit a deployment other people can
// reach; someone running it just for themselves can raise every
// RATE_LIMIT_*_MAX, or set it to 0 to drop that command's limit entirely.
export interface RateLimitConfig {
windowSeconds: number;
maxCount: number;
}
export interface CommandConfig {
maxActiveAddresses: number;
addressTtlSeconds: number;
rateLimits: Record<string, RateLimitConfig | null>;
}
function parseIntEnv(value: string | undefined, fallback: number): number {
if (!value) {
return fallback;
}
const parsed = Number.parseInt(value, 10);
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
}
function rateLimitFromEnv(
env: Record<string, string | undefined>,
prefix: string,
defaultWindowSeconds: number,
defaultMaxCount: number
): RateLimitConfig | null {
const maxCount = parseIntEnv(env[`${prefix}_MAX`], defaultMaxCount);
if (maxCount === 0) {
return null; // explicitly disabled for this command
}
return {
windowSeconds: parseIntEnv(env[`${prefix}_WINDOW_SECONDS`], defaultWindowSeconds),
maxCount,
};
}
export function buildCommandConfig(env: Record<string, string | undefined>): CommandConfig {