/** * Gas-Free Configuration Types * * Configuration options for the Gas-Free transfer feature * * @module features/gas-free/types/GasFreeConfig */ import { z } from 'zod'; import type { IFeatureConfig } from '../../../types/IFeatureModule'; import { Feature } from '../../../types/Feature'; import { Environment } from '../../../types/SDKConfig'; /** * Gas-Free feature configuration */ export interface GasFreeConfig extends IFeatureConfig { /** Feature name (must be 'gasFree') */ name: Feature.GAS_FREE; /** Whether the feature is enabled */ enabled: boolean; /** API key for authentication */ apiKey: string; /** Request timeout in milliseconds */ timeout?: number; /** Maximum number of retry attempts */ maxRetries?: number; /** Base delay for exponential backoff (ms) */ retryBaseDelay?: number; /** Maximum delay for exponential backoff (ms) */ retryMaxDelay?: number; /** Whether to use jitter in retry delays */ retryJitter?: boolean; /** Quote expiration buffer (ms) - reject quotes expiring within this time */ quoteExpirationBuffer?: number; /** Custom HTTP headers */ headers?: Record; } /** * Zod schema for Gas-Free configuration validation */ export const GasFreeConfigSchema = z.object({ name: z.literal(Feature.GAS_FREE, { errorMap: () => ({ message: 'Gas-Free config must have name "gasFree"' }), }), enabled: z.boolean(), apiKey: z.string().min(1, 'API key is required'), timeout: z.number().int().positive('timeout must be positive').optional(), maxRetries: z .number() .int() .nonnegative('maxRetries must be non-negative') .optional(), retryBaseDelay: z .number() .int() .positive('retryBaseDelay must be positive') .optional(), retryMaxDelay: z .number() .int() .positive('retryMaxDelay must be positive') .optional(), retryJitter: z.boolean().optional(), quoteExpirationBuffer: z .number() .int() .nonnegative('quoteExpirationBuffer must be non-negative') .optional(), headers: z.record(z.string()).optional(), }); /** * Default Gas-Free configuration */ export const DEFAULT_GAS_FREE_CONFIG: Partial = { timeout: 30000, // 30 seconds maxRetries: 3, retryBaseDelay: 1000, // 1 second retryMaxDelay: 10000, // 10 seconds retryJitter: true, quoteExpirationBuffer: 30000, // 30 seconds }; /** * Get the hardcoded service URL as a function of environment * * @param environment - SDK environment (mainnet or testnet) * @returns Service URL for the specified environment */ export function getGasFreeServiceUrl(environment: Environment): string { return environment === Environment.MAINNET ? 'https://gasfree.orbis1.io' : 'https://gasfree-dev.orbis1.io'; } /** * Merge Gas-Free config with defaults * * @param config - User configuration * @returns Merged configuration with defaults */ export function mergeGasFreeConfig( config: Partial ): GasFreeConfig { return { name: 'gasFree', enabled: config.enabled ?? true, ...DEFAULT_GAS_FREE_CONFIG, ...config, } as GasFreeConfig; } /** * Validate Gas-Free configuration * * @param config - Configuration to validate * @throws {Error} If configuration is invalid */ export function validateGasFreeConfig(config: GasFreeConfig): void { try { GasFreeConfigSchema.parse(config); } catch (error) { if (error instanceof z.ZodError) { const messages = error.errors.map((err) => { const path = err.path.join('.'); return path ? `${path}: ${err.message}` : err.message; }); throw new Error( `Gas-Free configuration validation failed:\n - ${messages.join( '\n - ' )}` ); } throw error; } }