/** * SDK Configuration Types * * Configuration options for the Orbis SDK * * @module types/SDKConfig */ import { z } from 'zod'; import type { Keys, AssetSchema } from '../core/Interfaces'; /** * Wallet configuration for the SDK */ export interface WalletConfig { /** Enable wallet functionality */ enabled: boolean; /** Wallet keys (mnemonic, xpubs, etc.) */ keys: Keys; /** Absolute path to directory where wallet data will be stored. If not provided, defaults to '.orbis1-wallet-data' at project root (alongside node_modules). Recommended to set explicitly for production deployments. */ dataDir?: string; /** Supported asset schemas */ supportedSchemas?: AssetSchema[]; /** Maximum allocations per UTXO */ maxAllocationsPerUtxo?: number; /** Vanilla keychain index */ vanillaKeychain?: number; } /** * Log levels for the SDK */ export enum LogLevel { /** No logging */ NONE = 'none', /** Error messages only */ ERROR = 'error', /** Warnings and errors */ WARN = 'warn', /** Informational messages, warnings, and errors */ INFO = 'info', /** Debug messages and all above */ DEBUG = 'debug', /** Verbose logging (all messages) */ VERBOSE = 'verbose', } /** * SDK Environment * Determines which network and service endpoints to use */ export enum Environment { /** Testnet4 environment */ TESTNET4 = 'TESTNET4', /** Regtest environment */ REGTEST = 'REGTEST', /** Mainnet environment (production) */ MAINNET = 'MAINNET', } /** * Zod schema for Gas-Free feature configuration */ export const GasFreeFeatureConfigSchema = z.object({ enabled: z.boolean().optional(), timeout: z.number().int().positive('Timeout must be positive').optional(), }); /** * Zod schema for Watch Tower feature configuration */ export const WatchTowerFeatureConfigSchema = z.object({ enabled: z.boolean().optional(), }); /** * Zod schema for logging configuration */ export const LoggingConfigSchema = z.object({ level: z.nativeEnum(LogLevel).optional(), logger: z.function().optional(), }); /** * Zod schema for SDK options */ export const SDKOptionsSchema = z.object({ strictMode: z.boolean().optional(), }); /** * Zod schema for SDK configuration */ export const SDKConfigSchema = z.object({ apiKey: z.string().min(1, 'API key is required'), environment: z.nativeEnum(Environment).default(Environment.MAINNET), features: z .object({ gasFree: GasFreeFeatureConfigSchema.optional(), watchTower: WatchTowerFeatureConfigSchema.optional(), }) .passthrough() .optional(), logging: LoggingConfigSchema.optional(), options: SDKOptionsSchema.optional(), }); /** * SDK Configuration */ export interface SDKConfig { /** * API key for Orbis services (Watch Tower, Gas-Free, etc.). * Required for all backend services. */ apiKey: string; /** * SDK environment (testnet or mainnet). * Determines which network and service endpoints to use. * Defaults to mainnet if not specified. */ environment: Environment; /** * Wallet configuration. * Required for RGB operations and wallet-dependent features (Gas-Free). * Network (testnet4 or mainnet) is determined by the environment setting. */ wallet?: WalletConfig; /** * Feature configurations * * Each feature can be configured independently. * Only enabled features will be initialized. */ features?: { /** Gas-Free feature configuration */ gasFree?: { /** Enable the feature */ enabled?: boolean; /** Request timeout in milliseconds */ timeout?: number; }; /** Watch-Tower feature configuration */ watchTower?: { /** Enable the feature */ enabled?: boolean; }; /** Custom features */ [key: string]: { enabled?: boolean; [key: string]: unknown } | undefined; }; /** * Logging configuration */ logging?: { /** Log level */ level?: LogLevel; /** Custom logger function */ logger?: (level: LogLevel, message: string, ...args: unknown[]) => void; }; /** * SDK behavior options */ options?: { /** Enable strict mode (throws on warnings) */ strictMode?: boolean; }; } /** * Default SDK configuration */ export const DEFAULT_SDK_CONFIG: Partial = { environment: Environment.MAINNET, features: {}, logging: { level: LogLevel.INFO, }, options: { strictMode: false, }, }; /** * Validate SDK configuration * * @param config - Configuration to validate * @throws {Error} If configuration is invalid */ export function validateSDKConfig(config: SDKConfig): void { try { SDKConfigSchema.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( `Configuration validation failed:\n - ${messages.join('\n - ')}` ); } throw error; } // Validate API key prefix matches environment const apiKey = config.apiKey; const environment = config.environment ?? Environment.MAINNET; if ( environment === Environment.TESTNET4 || environment === Environment.REGTEST ) { if (!apiKey.startsWith('pk_test')) { throw new Error( `API key mismatch: ${environment} environment requires a testnet API key (prefix: pk_test), but got a key with prefix: ${apiKey.substring( 0, 7 )}` ); } } else if (environment === Environment.MAINNET) { if (!apiKey.startsWith('sk_live')) { throw new Error( `API key mismatch: mainnet environment requires a production API key (prefix: sk_live), but got a key with prefix: ${apiKey.substring( 0, 7 )}` ); } } } /** * Merge configurations with defaults * * @param config - User configuration * @returns Merged configuration with defaults */ export function mergeWithDefaults(config: SDKConfig): SDKConfig { return { ...config, environment: config.environment ?? Environment.MAINNET, features: { ...DEFAULT_SDK_CONFIG.features, ...config.features, }, logging: { ...DEFAULT_SDK_CONFIG.logging, ...config.logging, }, options: { ...DEFAULT_SDK_CONFIG.options, ...config.options, }, }; }