/** * Gas-Free Error * * Base error class for gas-free transfer operations * * @module features/gas-free/errors/GasFreeError */ import { OrbisError, OrbisErrorCode } from '../../../errors/OrbisError'; /** * Error codes specific to Gas-Free feature */ export enum GasFreeErrorCode { /** Unknown gas-free error */ UNKNOWN = 'GAS_FREE_UNKNOWN', /** Quote expired */ QUOTE_EXPIRED = 'QUOTE_EXPIRED', /** Service unavailable */ SERVICE_UNAVAILABLE = 'SERVICE_UNAVAILABLE', /** Invalid PSBT */ INVALID_PSBT = 'INVALID_PSBT', /** PSBT build failed */ PSBT_BUILD_FAILED = 'PSBT_BUILD_FAILED', /** Consignment verification failed */ CONSIGNMENT_VERIFICATION_FAILED = 'CONSIGNMENT_VERIFICATION_FAILED', /** Insufficient funds */ INSUFFICIENT_FUNDS = 'INSUFFICIENT_FUNDS', /** Invalid request parameters */ INVALID_REQUEST = 'INVALID_REQUEST', /** Backend signing failed */ BACKEND_SIGNING_FAILED = 'BACKEND_SIGNING_FAILED', /** Broadcast failed */ BROADCAST_FAILED = 'BROADCAST_FAILED', /** Timeout error */ TIMEOUT = 'TIMEOUT', } /** * GasFreeError class * * Base error for all gas-free operations. * Extends OrbisError with gas-free specific error codes. */ export class GasFreeError extends OrbisError { /** Gas-Free specific error code */ public readonly gasFreeCode: GasFreeErrorCode; /** * Create a GasFreeError * * @param message - Error message * @param gasFreeCode - Gas-Free error code * @param originalError - Original error (if any) * @param context - Additional context */ constructor( message: string, gasFreeCode: GasFreeErrorCode = GasFreeErrorCode.UNKNOWN, originalError?: Error, context?: Record ) { super(message, OrbisErrorCode.UNKNOWN, originalError, context); this.name = 'GasFreeError'; this.gasFreeCode = gasFreeCode; // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(this, GasFreeError); } } /** * Convert error to JSON */ toJSON(): Record { return { ...super.toJSON(), gasFreeCode: this.gasFreeCode, }; } /** * Create a GasFreeError for invalid request */ static invalidRequest( message: string, context?: Record ): GasFreeError { return new GasFreeError( `Invalid request: ${message}`, GasFreeErrorCode.INVALID_REQUEST, undefined, context ); } /** * Create a GasFreeError for insufficient funds */ static insufficientFunds(required: number, available: number): GasFreeError { return new GasFreeError( `Insufficient funds: required ${required} sats, available ${available} sats`, GasFreeErrorCode.INSUFFICIENT_FUNDS, undefined, { required, available } ); } /** * Create a GasFreeError for timeout */ static timeout(operation: string, timeoutMs: number): GasFreeError { return new GasFreeError( `Operation '${operation}' timed out after ${timeoutMs}ms`, GasFreeErrorCode.TIMEOUT, undefined, { operation, timeoutMs } ); } /** * Create a GasFreeError for module not initialized */ static notInitialized(): GasFreeError { return new GasFreeError( 'GasFreeModule is not initialized. Call initialize() first.', GasFreeErrorCode.INVALID_REQUEST ); } /** * Create a GasFreeError for initialization failure */ static initializationFailed(reason: string): GasFreeError { return new GasFreeError( `Failed to initialize GasFreeModule: ${reason}`, GasFreeErrorCode.UNKNOWN, undefined, { reason } ); } }