@routstr/sdk 0.3.11 → 0.3.13
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/browser.d.mts +2 -1
- package/dist/browser.d.ts +2 -1
- package/dist/browser.js +360 -28
- package/dist/browser.js.map +1 -1
- package/dist/browser.mjs +355 -29
- package/dist/browser.mjs.map +1 -1
- package/dist/bun.d.mts +2 -1
- package/dist/bun.d.ts +2 -1
- package/dist/bun.js +367 -31
- package/dist/bun.js.map +1 -1
- package/dist/bun.mjs +362 -32
- package/dist/bun.mjs.map +1 -1
- package/dist/client/index.d.mts +85 -1
- package/dist/client/index.d.ts +85 -1
- package/dist/client/index.js +358 -27
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +353 -28
- package/dist/client/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +360 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +355 -29
- package/dist/index.mjs.map +1 -1
- package/dist/node.d.mts +2 -1
- package/dist/node.d.ts +2 -1
- package/dist/node.js +367 -31
- package/dist/node.js.map +1 -1
- package/dist/node.mjs +362 -32
- package/dist/node.mjs.map +1 -1
- package/dist/storage/bun.js +6 -1
- package/dist/storage/bun.js.map +1 -1
- package/dist/storage/bun.mjs +6 -1
- package/dist/storage/bun.mjs.map +1 -1
- package/dist/storage/index.js +2 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/index.mjs +2 -1
- package/dist/storage/index.mjs.map +1 -1
- package/dist/storage/node.js +6 -1
- package/dist/storage/node.js.map +1 -1
- package/dist/storage/node.mjs +6 -1
- package/dist/storage/node.mjs.map +1 -1
- package/dist/wallet/index.js +36 -8
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +36 -8
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +9 -3
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../core/types.ts","../../core/errors.ts","../../wallet/AuditLogger.ts","../../wallet/tokenUtils.ts","../../wallet/CashuSpender.ts","../../wallet/BalanceManager.ts","../../utils/torUtils.ts","../../client/ProviderManager.ts","../../storage/drivers/localStorage.ts","../../storage/drivers/memory.ts","../../storage/keys.ts","../../storage/usageTracking/aggregate.ts","../../storage/usageTracking/indexedDB.ts","../../storage/usageTracking/memory.ts","../../storage/store.ts","../../storage/index.ts","../../client/usage.ts","../../client/sse.ts","../../client/RoutstrClient.ts","../../client/StreamProcessor.ts","../../client/fetchAIResponse.ts"],"names":["amount","unit","getDecodedToken","mintUrl","options","normalizeBaseUrl","matchesFilters","createStore","isBrowser","msats","cost","StringDecoder","Transform","spendResult"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Core types for the Routstr SDK\n * These types are shared across wallet and client modules\n */\n\nexport interface SdkLogger {\n log(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n debug(...args: unknown[]): void;\n child(prefix: string): SdkLogger;\n}\n\nfunction makeConsoleLogger(prefix?: string): SdkLogger {\n const fmt = (args: unknown[]) => (prefix ? [prefix, ...args] : args);\n return {\n log: (...args) => console.log(...fmt(args)),\n warn: (...args) => console.warn(...fmt(args)),\n error: (...args) => console.error(...fmt(args)),\n debug: (...args) => console.log(...fmt(args)),\n child: (p) => makeConsoleLogger(prefix ? `${prefix}:${p}` : p),\n };\n}\n\nexport const consoleLogger: SdkLogger = makeConsoleLogger();\n\nexport const noopLogger: SdkLogger = {\n log: () => {},\n warn: () => {},\n error: () => {},\n debug: () => {},\n child: () => noopLogger,\n};\n\nexport interface MessageContentType {\n type: \"text\" | \"image_url\" | \"file\";\n text?: string;\n image_url?: {\n url: string;\n storageId?: string;\n };\n file?: {\n url: string;\n name?: string;\n mimeType?: string;\n size?: number;\n };\n hidden?: boolean;\n thinking?: string;\n citations?: string[];\n}\n\nexport interface Message {\n role: string;\n content: string | MessageContentType[];\n _eventId?: string;\n _prevId?: string;\n _createdAt?: number;\n _modelId?: string;\n satsSpent?: number;\n}\n\nexport interface TransactionHistory {\n type: \"spent\" | \"mint\" | \"send\" | \"import\" | \"refund\";\n amount: number;\n timestamp: number;\n status: \"success\" | \"failed\";\n model?: string;\n message?: string;\n balance?: number;\n}\n\nexport interface ModelPricing {\n prompt: number;\n completion: number;\n request: number;\n image: number;\n web_search: number;\n internal_reasoning: number;\n}\n\nexport interface ModelSatsPricing extends ModelPricing {\n max_completion_cost: number;\n max_prompt_cost: number;\n max_cost: number;\n}\n\nexport interface ModelArchitecture {\n modality: string;\n input_modalities: readonly string[];\n output_modalities: readonly string[];\n tokenizer: string;\n instruct_type: string | null;\n}\n\nexport interface PerRequestLimits {\n readonly prompt_tokens?: number;\n readonly completion_tokens?: number;\n readonly requests_per_minute?: number;\n readonly images_per_minute?: number;\n readonly web_searches_per_minute?: number;\n readonly [key: string]: number | undefined;\n}\n\nexport interface Model {\n id: string;\n name: string;\n created?: number;\n description?: string;\n context_length?: number;\n architecture?: ModelArchitecture;\n pricing?: ModelPricing;\n sats_pricing: ModelSatsPricing;\n per_request_limits?: PerRequestLimits;\n}\n\n/**\n * Result from spending cashu tokens\n */\nexport interface SpendResult {\n token: string | null;\n status: \"success\" | \"failed\";\n balance: number;\n unit?: \"sat\" | \"msat\";\n error?: string;\n errorDetails?: {\n required: number;\n available: number;\n maxMintBalance: number;\n maxMintUrl: string;\n };\n}\n\n/**\n * Result from refund operations\n */\nexport interface RefundResult {\n success: boolean;\n refundedAmount?: number;\n message?: string;\n requestId?: string;\n}\n\n/**\n * Result from top up operations\n */\nexport interface TopUpResult {\n success: boolean;\n toppedUpAmount?: number;\n message?: string;\n requestId?: string;\n recoveredToken?: boolean;\n}\n\n/**\n * API error verdict for retry logic\n */\nexport interface APIErrorVerdict {\n retry: boolean;\n reason: string;\n newBaseUrl?: string; // New provider to retry with (for 50X errors)\n}\n\n/**\n * Image data from API response\n */\nexport interface ImageData {\n type: \"image_url\";\n image_url: {\n url: string;\n };\n index?: number;\n}\n\n/**\n * Annotation data from API response\n */\nexport interface AnnotationData {\n type: \"url_citation\";\n start_index: number;\n end_index: number;\n url: string;\n title: string;\n}\n\n/**\n * Usage statistics from API response\n */\nexport interface UsageStats {\n total_tokens?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n cost?: number;\n sats_cost?: number;\n}\n\n/**\n * Result from streaming response processing\n */\nexport interface StreamingResult {\n content: string;\n thinking?: string;\n images?: ImageData[];\n usage?: UsageStats;\n model?: string;\n responseId?: string;\n finish_reason?: string;\n citations?: string[];\n annotations?: AnnotationData[];\n}\n\n/**\n * Parameters for fetching AI response\n */\nexport interface FetchAIResponseParams {\n messageHistory: Message[];\n selectedModel: Model;\n baseUrl: string;\n mintUrl: string;\n balance: number;\n transactionHistory: TransactionHistory[];\n}\n\n/**\n * Candidate provider for failover\n */\nexport interface CandidateProvider {\n baseUrl: string;\n model: Model;\n cost: number;\n}\n\n/**\n * Mint selection result\n */\nexport interface MintSelection {\n selectedMintUrl: string | null;\n selectedMintBalance: number;\n}\n\n/**\n * Pending token entry\n */\nexport interface PendingTokenEntry {\n baseUrl: string;\n amount: number;\n}\n\n/**\n * Provider information from /v1/info endpoint\n */\nexport interface ProviderInfo {\n mints?: string[];\n [key: string]: any;\n}\n\n/**\n * Model discovery result\n */\nexport interface ModelDiscoveryResult {\n models: Model[];\n bestById: Map<string, { model: Model; base: string }>;\n totalProcessed: number;\n}\n\n/**\n * Mint discovery result\n */\nexport interface MintDiscoveryResult {\n mintsFromProviders: Record<string, string[]>;\n infoFromProviders: Record<string, ProviderInfo>;\n}\n","/**\n * Custom error classes for the Routstr SDK\n * Provides specific error types for different failure modes\n */\n\n/**\n * Error thrown when balance is insufficient for an operation\n */\nexport class InsufficientBalanceError extends Error {\n constructor(\n public required: number,\n public available: number,\n public maxMintBalance: number = 0,\n public maxMintUrl: string = \"\",\n customMessage?: string\n ) {\n super(\n customMessage ??\n (`Insufficient balance: need ${required} sats, have ${available} sats available. ` +\n (maxMintBalance > 0\n ? `Largest mint balance: ${maxMintBalance} sats from ${maxMintUrl}`\n : \"\"))\n );\n this.name = \"InsufficientBalanceError\";\n }\n}\n\n/**\n * Error thrown when a provider returns an error response\n */\nexport class ProviderError extends Error {\n constructor(\n public baseUrl: string,\n public statusCode: number,\n message: string,\n public requestId?: string\n ) {\n super(\n `Provider ${baseUrl} returned ${statusCode}: ${message}` +\n (requestId ? ` (Request ID: ${requestId})` : \"\")\n );\n this.name = \"ProviderError\";\n }\n}\n\n/**\n * Error thrown when a mint is unreachable\n */\nexport class MintUnreachableError extends Error {\n constructor(public mintUrl: string) {\n super(\n `Your mint ${mintUrl} is unreachable or is blocking your IP. Please try again later or switch mints.`\n );\n this.name = \"MintUnreachableError\";\n }\n}\n\n/**\n * Error thrown when a token operation fails\n */\nexport class TokenOperationError extends Error {\n constructor(\n message: string,\n public operation: \"send\" | \"receive\" | \"refund\",\n public mintUrl?: string\n ) {\n super(message);\n this.name = \"TokenOperationError\";\n }\n}\n\n/**\n * Error thrown when provider failover fails\n */\nexport class FailoverError extends Error {\n constructor(\n public originalProvider: string,\n public failedProviders: string[],\n message?: string\n ) {\n super(\n message ||\n `All providers failed. Original: ${originalProvider}, Failed: ${failedProviders.join(\", \")}`\n );\n this.name = \"FailoverError\";\n }\n}\n\n/**\n * Error thrown when streaming response processing fails\n */\nexport class StreamingError extends Error {\n constructor(\n message: string,\n public finishReason?: string,\n public accumulatedContent?: string\n ) {\n super(message);\n this.name = \"StreamingError\";\n }\n}\n\n/**\n * Error thrown when model is not found on a provider\n */\nexport class ModelNotFoundError extends Error {\n constructor(public modelId: string, public baseUrl: string) {\n super(`Model '${modelId}' not found on provider ${baseUrl}`);\n this.name = \"ModelNotFoundError\";\n }\n}\n\n/**\n * Error thrown when provider bootstrap fails\n */\nexport class ProviderBootstrapError extends Error {\n constructor(\n public failedProviders: string[],\n message?: string\n ) {\n super(\n message || `Failed to bootstrap providers. Tried: ${failedProviders.join(\", \")}`\n );\n this.name = \"ProviderBootstrapError\";\n }\n}\n\n/**\n * Error thrown when no providers are available\n */\nexport class NoProvidersAvailableError extends Error {\n constructor() {\n super(\"No providers are available for model discovery\");\n this.name = \"NoProvidersAvailableError\";\n }\n}\n\n/**\n * Error thrown when mint discovery fails\n */\nexport class MintDiscoveryError extends Error {\n constructor(\n public baseUrl: string,\n message?: string\n ) {\n super(message || `Failed to discover mints from provider ${baseUrl}`);\n this.name = \"MintDiscoveryError\";\n }\n}\n","/**\n * AuditLogger - Transaction audit logging utility\n * Writes JSON-formatted transaction logs to audit.log\n */\n\nexport interface AuditLogEntry {\n timestamp: string;\n action: \"spend\" | \"topup\" | \"refund\" | \"receive\" | \"balance_check\";\n totalBalance: number;\n providerBalances: Record<string, number>;\n mintBalances: Record<string, number>;\n amount?: number;\n mintUrl?: string;\n baseUrl?: string;\n status: \"success\" | \"failed\";\n details?: string;\n}\n\nexport class AuditLogger {\n private static instance: AuditLogger | null = null;\n\n static getInstance(): AuditLogger {\n if (!AuditLogger.instance) {\n AuditLogger.instance = new AuditLogger();\n }\n return AuditLogger.instance;\n }\n\n async log(entry: Omit<AuditLogEntry, \"timestamp\">): Promise<void> {\n const fullEntry: AuditLogEntry = {\n ...entry,\n timestamp: new Date().toISOString(),\n };\n\n const logLine = JSON.stringify(fullEntry) + \"\\n\";\n\n if (typeof window === \"undefined\") {\n try {\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n const logPath = path.join(process.cwd(), \"audit.log\");\n fs.appendFileSync(logPath, logLine);\n } catch (error) {\n console.error(\"[AuditLogger] Failed to write to file:\", error);\n }\n } else {\n console.log(\"[AUDIT]\", logLine.trim());\n }\n }\n\n async logBalanceSnapshot(\n action: AuditLogEntry[\"action\"],\n amounts: {\n totalBalance: number;\n providerBalances: Record<string, number>;\n mintBalances: Record<string, number>;\n },\n options?: {\n amount?: number;\n mintUrl?: string;\n baseUrl?: string;\n status?: \"success\" | \"failed\";\n details?: string;\n }\n ): Promise<void> {\n await this.log({\n action,\n totalBalance: amounts.totalBalance,\n providerBalances: amounts.providerBalances,\n mintBalances: amounts.mintBalances,\n amount: options?.amount,\n mintUrl: options?.mintUrl,\n baseUrl: options?.baseUrl,\n status: options?.status ?? \"success\",\n details: options?.details,\n });\n }\n}\n\nexport const auditLogger = AuditLogger.getInstance();\n","import type { MintSelection } from \"../core/types\";\n\nexport function isNetworkErrorMessage(message: string): boolean {\n return (\n message.includes(\"NetworkError when attempting to fetch resource\") ||\n message.includes(\"Failed to fetch\") ||\n message.includes(\"Load failed\") ||\n message.includes(\"ERR_TLS_CERT_ALTNAME_INVALID\") ||\n message.includes(\"ERR_TLS_CERT_NOT_YET_VALID\") ||\n message.includes(\"ERR_TLS_CERT_EXPIRED\") ||\n message.includes(\"UNABLE_TO_VERIFY_LEAF_SIGNATURE\") ||\n message.includes(\"SELF_SIGNED_CERT_IN_CHAIN\")\n );\n}\n\nexport function getBalanceInSats(\n balance: number,\n unit: \"sat\" | \"msat\" | string | undefined\n): number {\n return unit === \"msat\" ? balance / 1000 : balance;\n}\n\nexport function getTotalMintBalanceInSats(\n balances: Record<string, number>,\n units: Record<string, \"sat\" | \"msat\">\n): number {\n let total = 0;\n for (const mintUrl in balances) {\n total += getBalanceInSats(balances[mintUrl], units[mintUrl]);\n }\n return total;\n}\n\nexport function selectMintWithBalance(\n balances: Record<string, number>,\n units: Record<string, string>,\n amount: number,\n excludeMints: string[] = []\n): MintSelection {\n for (const mintUrl in balances) {\n if (excludeMints.includes(mintUrl)) {\n continue;\n }\n\n const balanceInSats = getBalanceInSats(balances[mintUrl], units[mintUrl]);\n if (balanceInSats >= amount) {\n return { selectedMintUrl: mintUrl, selectedMintBalance: balanceInSats };\n }\n }\n\n return { selectedMintUrl: null, selectedMintBalance: 0 };\n}\n","/**\n * CashuSpender - Core spending logic for Cashu tokens\n *\n * Handles:\n * - Mint selection with sufficient balance\n * - Provider mint compatibility checks\n * - Retry logic with alternate mints\n * - Critical section management (busy state)\n *\n * Extracted from hooks/useCashuWithXYZ.ts\n */\n\nimport type { WalletAdapter, StorageAdapter } from \"./interfaces\";\nimport type { SpendResult, SdkLogger } from \"../core/types\";\nimport { consoleLogger } from \"../core/types\";\nimport { InsufficientBalanceError } from \"../core/errors\";\nimport { BalanceManager } from \"./BalanceManager\";\nimport { auditLogger } from \"./AuditLogger\";\nimport { getBalanceInSats, isNetworkErrorMessage } from \"./tokenUtils\";\nimport { getDecodedToken } from \"@cashu/cashu-ts\";\n\n/**\n * Options for spending cashu tokens\n */\nexport interface SpendOptions {\n /** The mint URL to send from (can be overridden if insufficient balance) */\n mintUrl: string;\n\n /** The amount to spend in sats */\n amount: number;\n\n /** The provider base URL (for token storage and provider mint checks) */\n baseUrl: string;\n\n /** Whether to reuse an existing token if available */\n reuseToken?: boolean;\n\n /** Optional P2PK public key */\n p2pkPubkey?: string;\n\n /** Array of mint URLs to exclude (for retry logic) */\n excludeMints?: string[];\n\n /** Current retry count (for internal recursion) */\n retryCount?: number;\n\n /** Specific provider baseUrls to refund (if not provided, refunds all except current) */\n refundBaseUrls?: string[];\n}\n\ntype DebugLevel = \"DEBUG\" | \"WARN\" | \"ERROR\";\n\n/**\n * CashuSpender manages the spending of Cashu tokens\n */\nexport class CashuSpender {\n private _isBusy = false;\n private debugLevel: DebugLevel = \"WARN\";\n private readonly logger: SdkLogger;\n\n constructor(\n private walletAdapter: WalletAdapter,\n private storageAdapter: StorageAdapter,\n private _providerRegistry?: unknown,\n private balanceManager?: BalanceManager,\n logger?: SdkLogger\n ) {\n this.logger = (logger ?? consoleLogger).child(\"CashuSpender\");\n }\n\n async receiveToken(token: string): Promise<{\n success: boolean;\n amount: number;\n unit: \"sat\" | \"msat\";\n message?: string;\n }> {\n try {\n const result = await this.walletAdapter.receiveToken(token);\n return result;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n\n if (errorMessage.includes(\"Failed to fetch mint\")) {\n const cachedTokens = this.storageAdapter.getCachedReceiveTokens();\n const existingIndex = cachedTokens.findIndex((t) => t.token === token);\n if (existingIndex === -1) {\n const { amount, unit } = this._decodeTokenAmount(token);\n this.storageAdapter.setCachedReceiveTokens([\n ...cachedTokens,\n {\n token,\n amount,\n unit,\n createdAt: Date.now(),\n },\n ]);\n }\n }\n\n const { amount, unit } = this._decodeTokenAmount(token);\n return { success: false, amount, unit, message: errorMessage };\n }\n }\n\n private _decodeTokenAmount(token: string): {\n amount: number;\n unit: \"sat\" | \"msat\";\n } {\n try {\n const decoded = getDecodedToken(token);\n const amount = decoded.proofs.reduce(\n (acc, proof) => acc + proof.amount,\n 0\n );\n const unit = (decoded.unit as \"sat\" | \"msat\") || \"sat\";\n return { amount, unit };\n } catch {\n return { amount: 0, unit: \"sat\" };\n }\n }\n\n private async _getBalanceState(): Promise<{\n totalBalance: number;\n providerBalances: Record<string, number>;\n mintBalances: Record<string, number>;\n }> {\n if (this.balanceManager) {\n return this.balanceManager.getBalanceState();\n }\n\n const mintBalances = await this.walletAdapter.getBalances();\n const units = this.walletAdapter.getMintUnits();\n\n let totalMintBalance = 0;\n const normalizedMintBalances: Record<string, number> = {};\n for (const url in mintBalances) {\n const balance = mintBalances[url];\n const unit = units[url];\n const balanceInSats = getBalanceInSats(balance, unit);\n normalizedMintBalances[url] = balanceInSats;\n totalMintBalance += balanceInSats;\n }\n\n const providerBalances: Record<string, number> = {};\n let totalProviderBalance = 0;\n\n const apiKeys = this.storageAdapter.getAllApiKeys();\n for (const apiKey of apiKeys) {\n if (!providerBalances[apiKey.baseUrl]) {\n providerBalances[apiKey.baseUrl] = 0;\n }\n providerBalances[apiKey.baseUrl] += apiKey.balance;\n totalProviderBalance += apiKey.balance;\n }\n\n return {\n totalBalance: totalMintBalance + totalProviderBalance,\n providerBalances,\n mintBalances: normalizedMintBalances,\n };\n }\n\n private async _logTransaction(\n action: \"spend\" | \"topup\" | \"refund\" | \"receive\" | \"balance_check\",\n options?: {\n amount?: number;\n mintUrl?: string;\n baseUrl?: string;\n status?: \"success\" | \"failed\";\n details?: string;\n }\n ): Promise<void> {\n const balanceState = await this._getBalanceState();\n await auditLogger.logBalanceSnapshot(action, balanceState, options);\n }\n\n /**\n * Check if the spender is currently in a critical operation\n */\n get isBusy(): boolean {\n return this._isBusy;\n }\n\n getDebugLevel(): DebugLevel {\n return this.debugLevel;\n }\n\n setDebugLevel(level: DebugLevel): void {\n this.debugLevel = level;\n }\n\n private _log(level: \"DEBUG\" | \"WARN\" | \"ERROR\", ...args: unknown[]): void {\n const levelPriority: Record<DebugLevel, number> = {\n DEBUG: 0,\n WARN: 1,\n ERROR: 2,\n };\n\n if (levelPriority[level] >= levelPriority[this.debugLevel]) {\n switch (level) {\n case \"DEBUG\":\n this.logger.log(...args);\n break;\n case \"WARN\":\n this.logger.warn(...args);\n break;\n case \"ERROR\":\n this.logger.error(...args);\n break;\n }\n }\n }\n\n /**\n * Spend Cashu tokens with automatic mint selection and retry logic\n * Throws errors on failure instead of returning failed SpendResult\n */\n async spend(options: SpendOptions): Promise<SpendResult> {\n const {\n mintUrl,\n amount,\n baseUrl,\n reuseToken = false,\n p2pkPubkey,\n excludeMints = [],\n retryCount = 0,\n } = options;\n\n this._isBusy = true;\n\n try {\n const result = await this._spendInternal({\n mintUrl,\n amount,\n baseUrl,\n reuseToken,\n p2pkPubkey,\n excludeMints,\n retryCount,\n });\n\n if (result.status === \"failed\" || !result.token) {\n const errorMsg =\n result.error || `Insufficient balance. Need ${amount} sats.`;\n\n if (this._isNetworkError(errorMsg)) {\n throw new Error(\n `Your mint ${mintUrl} is unreachable or is blocking your IP. Please try again later or switch mints.`\n );\n }\n\n if (result.errorDetails) {\n throw new InsufficientBalanceError(\n result.errorDetails.required,\n result.errorDetails.available,\n result.errorDetails.maxMintBalance,\n result.errorDetails.maxMintUrl\n );\n }\n\n throw new Error(errorMsg);\n }\n\n return result;\n } finally {\n this._isBusy = false;\n }\n }\n\n /**\n * Check if error message indicates a network error\n */\n private _isNetworkError(message: string): boolean {\n return (\n isNetworkErrorMessage(message) ||\n (message.includes(\"Your mint\") && message.includes(\"unreachable\"))\n );\n }\n\n /**\n * Internal spending logic\n */\n private async _spendInternal(options: SpendOptions): Promise<SpendResult> {\n let {\n mintUrl,\n amount,\n baseUrl,\n reuseToken,\n p2pkPubkey,\n excludeMints,\n retryCount,\n } = options;\n\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: amount=${amount}, mintUrl=${mintUrl}, baseUrl=${baseUrl}, reuseToken=${reuseToken}`\n );\n\n // Validate amount\n let adjustedAmount = Math.ceil(amount);\n if (!adjustedAmount || isNaN(adjustedAmount)) {\n this._log(\n \"ERROR\",\n `[CashuSpender] _spendInternal: Invalid amount: ${amount}`\n );\n return {\n token: null,\n status: \"failed\",\n balance: 0,\n error: \"Please enter a valid amount\",\n };\n }\n\n // Try to get existing token for reuse\n if (reuseToken && baseUrl) {\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: Attempting to reuse token for ${baseUrl}`\n );\n const existingResult = await this._tryReuseToken(\n baseUrl,\n adjustedAmount,\n mintUrl\n );\n if (existingResult) {\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: Successfully reused token, balance: ${existingResult.balance}`\n );\n return existingResult;\n }\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: Could not reuse token, will create new token`\n );\n }\n\n // Get current balance state\n const balanceState = await this._getBalanceState();\n const totalAvailableBalance = balanceState.totalBalance;\n\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: totalAvailableBalance=${totalAvailableBalance}, adjustedAmount=${adjustedAmount}`\n );\n\n // Check total balance\n if (totalAvailableBalance < adjustedAmount) {\n this._log(\n \"ERROR\",\n `[CashuSpender] _spendInternal: Insufficient balance, have=${totalAvailableBalance}, need=${adjustedAmount}`\n );\n return this._createInsufficientBalanceError(\n adjustedAmount,\n balanceState.mintBalances,\n totalAvailableBalance\n );\n }\n\n let token: string | null = null;\n let selectedMintUrl: string | undefined;\n let spentAmount = adjustedAmount;\n\n if (this.balanceManager) {\n const tokenResult = await this.balanceManager.createProviderToken({\n mintUrl,\n baseUrl,\n amount: adjustedAmount,\n p2pkPubkey,\n excludeMints,\n retryCount,\n });\n\n if (!tokenResult.success || !tokenResult.token) {\n if ((tokenResult.error || \"\").includes(\"Insufficient balance\")) {\n return this._createInsufficientBalanceError(\n adjustedAmount,\n balanceState.mintBalances,\n totalAvailableBalance\n );\n }\n\n return {\n token: null,\n status: \"failed\",\n balance: 0,\n error: tokenResult.error || \"Failed to create token\",\n };\n }\n\n token = tokenResult.token;\n selectedMintUrl = tokenResult.selectedMintUrl;\n spentAmount = tokenResult.amountSpent || adjustedAmount;\n } else {\n try {\n token = await this.walletAdapter.sendToken(\n mintUrl,\n adjustedAmount,\n p2pkPubkey\n );\n selectedMintUrl = mintUrl;\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n return {\n token: null,\n status: \"failed\",\n balance: 0,\n error: `Error generating token: ${errorMsg}`,\n };\n }\n }\n\n // Store token and return\n if (token) {\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`\n );\n }\n\n this._logTransaction(\"spend\", {\n amount: spentAmount,\n mintUrl: selectedMintUrl || mintUrl,\n baseUrl,\n status: \"success\",\n });\n\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`\n );\n\n const units = this.walletAdapter.getMintUnits();\n\n return {\n token,\n status: \"success\",\n balance: spentAmount,\n unit:\n (selectedMintUrl ? units[selectedMintUrl] : units[mintUrl]) || \"sat\",\n };\n }\n\n /**\n * Try to reuse an existing API key\n */\n private async _tryReuseToken(\n baseUrl: string,\n amount: number,\n mintUrl: string\n ): Promise<SpendResult | null> {\n const apiKeyEntry = this.storageAdapter.getApiKey(baseUrl);\n if (!apiKeyEntry) return null;\n\n // Get pending distribution to check balance\n const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();\n const balanceForBaseUrl =\n apiKeyDistribution.find((b) => b.baseUrl === baseUrl)?.amount || 0;\n\n this._log(\"DEBUG\", \"Reusing API key\", balanceForBaseUrl, amount);\n\n if (balanceForBaseUrl > amount) {\n const units = this.walletAdapter.getMintUnits();\n const unit = units[mintUrl] || \"sat\";\n return {\n token: apiKeyEntry.key,\n status: \"success\",\n balance: balanceForBaseUrl,\n unit,\n };\n }\n\n // API key exists but insufficient balance - attempt topup\n if (this.balanceManager) {\n const topUpAmount = Math.ceil(amount * 1.2 - balanceForBaseUrl);\n const topUpResult = await this.balanceManager.topUp({\n mintUrl,\n baseUrl,\n amount: topUpAmount,\n token: apiKeyEntry.key,\n });\n this._log(\"DEBUG\", \"TOPUP \", topUpResult);\n\n if (topUpResult.success && topUpResult.toppedUpAmount) {\n const newBalance = balanceForBaseUrl + topUpResult.toppedUpAmount;\n const units = this.walletAdapter.getMintUnits();\n const unit = units[mintUrl] || \"sat\";\n\n this._logTransaction(\"topup\", {\n amount: topUpResult.toppedUpAmount,\n mintUrl,\n baseUrl,\n status: \"success\",\n });\n\n return {\n token: apiKeyEntry.key,\n status: \"success\",\n balance: newBalance,\n unit,\n };\n }\n\n const providerBalance = await this._getProviderTokenBalance(\n baseUrl,\n apiKeyEntry.key\n );\n this._log(\"DEBUG\", providerBalance);\n if (providerBalance <= 0) {\n this.storageAdapter.removeApiKey(baseUrl);\n }\n }\n\n return null;\n }\n\n /**\n * Refund all xcashu tokens from storage by calling the provider's refund endpoint.\n * The xcashu token acts as an API key to claim the refund, and the response contains\n * the actual refunded Cashu token which is then received into the wallet.\n * @param mintUrl - The mint URL for receiving tokens\n * @param excludeBaseUrls - Base URLs to exclude from refund (optional)\n * @returns Results for each xcashu token refund attempt\n */\n async refundXcashuTokens(\n mintUrl: string,\n excludeBaseUrls?: string[]\n ): Promise<\n { baseUrl: string; token: string; success: boolean; error?: string }[]\n > {\n const results: {\n baseUrl: string;\n token: string;\n success: boolean;\n error?: string;\n }[] = [];\n const xcashuTokens = this.storageAdapter.getXcashuTokens();\n const excludedUrls = new Set(excludeBaseUrls || []);\n\n for (const [baseUrl, tokens] of Object.entries(xcashuTokens)) {\n if (excludedUrls.has(baseUrl)) continue;\n\n for (const xcashuToken of tokens) {\n try {\n // XCashu tokens need to be sent to the provider's refund endpoint\n // The xcashu token acts as an API key, and the response contains the actual refunded token\n if (!this.balanceManager) {\n throw new Error(\"BalanceManager not available for xcashu refund\");\n }\n\n // Call the refund endpoint using the xcashu token as the API key\n const fetchResult = await this.balanceManager.fetchRefundToken(\n baseUrl,\n xcashuToken.token,\n true\n );\n\n if (!fetchResult.success || !fetchResult.token) {\n throw new Error(\n fetchResult.error || \"Failed to fetch refund token from provider\"\n );\n }\n\n // Receive the refunded Cashu token into the wallet\n const receiveResult = await this.receiveToken(fetchResult.token);\n\n if (receiveResult.success) {\n // Remove successfully refunded token from storage\n this.storageAdapter.removeXcashuToken(baseUrl, xcashuToken.token);\n results.push({\n baseUrl,\n token: xcashuToken.token,\n success: true,\n });\n this._log(\n \"DEBUG\",\n `[CashuSpender] refundXcashuTokens: Successfully refunded xcashu token for ${baseUrl}, amount=${receiveResult.amount}`\n );\n } else {\n // Refund failed - increment tryCount\n const currentTryCount = xcashuToken.tryCount ?? 0;\n const newTryCount = currentTryCount + 1;\n this.storageAdapter.updateXcashuTokenTryCount(\n xcashuToken.token,\n newTryCount\n );\n results.push({\n baseUrl,\n token: xcashuToken.token,\n success: false,\n error: receiveResult.message ?? \"Refund failed\",\n });\n this._log(\n \"DEBUG\",\n `[CashuSpender] refundXcashuTokens: Failed to receive refund token for ${baseUrl}, incremented tryCount to ${newTryCount}: ${receiveResult.message}`\n );\n }\n } catch (error) {\n // Exception occurred - increment tryCount\n const currentTryCount = xcashuToken.tryCount ?? 0;\n const newTryCount = currentTryCount + 1;\n this.storageAdapter.updateXcashuTokenTryCount(\n xcashuToken.token,\n newTryCount\n );\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n results.push({\n baseUrl,\n token: xcashuToken.token,\n success: false,\n error: errorMessage,\n });\n this._log(\n \"ERROR\",\n `[CashuSpender] refundXcashuTokens: Exception during refund for ${baseUrl}: ${errorMessage}, incremented tryCount to ${newTryCount}`\n );\n }\n }\n }\n\n return results;\n }\n\n /**\n * Refund specific providers without retrying spend\n */\n async refundProviders(\n mintUrl: string,\n forceRefund?: boolean\n ): Promise<{ baseUrl: string; success: boolean }[]> {\n const results: { baseUrl: string; success: boolean }[] = [];\n\n const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();\n\n // Refresh balances from providers before refunding\n for (const apiKeyEntry of apiKeyDistribution) {\n const apiKeyEntryFull = this.storageAdapter.getApiKey(\n apiKeyEntry.baseUrl\n );\n\n if (apiKeyEntryFull && this.balanceManager) {\n try {\n const balanceResult = await this.balanceManager.getTokenBalance(\n apiKeyEntryFull.key,\n apiKeyEntry.baseUrl\n );\n\n if (balanceResult.isInvalidApiKey) {\n // Key is invalid/expired on the provider side — clean it up\n this.logger.warn(\n `refundProviders: ${apiKeyEntry.baseUrl} returned invalid API key; removing local key and treating as success`\n );\n this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);\n results.push({\n baseUrl: apiKeyEntry.baseUrl,\n success: true,\n });\n continue;\n }\n\n if (balanceResult.amount >= 0 && !balanceResult.balanceUnknown) {\n const balanceSat = balanceResult.unit === \"msat\"\n ? Math.floor(balanceResult.amount / 1000)\n : balanceResult.amount;\n this.storageAdapter.updateApiKeyBalance(\n apiKeyEntry.baseUrl,\n balanceSat\n );\n } else {\n this.logger.warn(\n `refundProviders: balance refresh for ${apiKeyEntry.baseUrl} returned negative amount; keeping stale local balance=${apiKeyEntryFull.balance}`\n );\n }\n } catch (error) {\n // Balance check failed — proceed with stale local balance\n this.logger.warn(\n `refundProviders: balance refresh threw for ${apiKeyEntry.baseUrl}; proceeding with stale local balance`,\n error\n );\n }\n\n // Re-read the entry after balance refresh (may have been removed above)\n const refreshedEntry = this.storageAdapter.getApiKey(\n apiKeyEntry.baseUrl\n );\n if (!refreshedEntry) {\n continue;\n }\n\n const refundResult = await this.balanceManager.refundApiKey({\n mintUrl,\n baseUrl: apiKeyEntry.baseUrl,\n apiKey: refreshedEntry.key,\n forceRefund,\n });\n\n if (refundResult.success) {\n this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);\n } else {\n const currentEntry = this.storageAdapter.getApiKey(\n apiKeyEntry.baseUrl\n );\n this.logger.warn(\n `refundProviders: refund failed for ${apiKeyEntry.baseUrl}; currentEntry=${Boolean(currentEntry)} balance=${currentEntry?.balance ?? \"none\"}. Touching lastUsed to rate-limit retries.`\n );\n if (currentEntry) {\n this.storageAdapter.updateApiKeyBalance(\n apiKeyEntry.baseUrl,\n currentEntry.balance\n ); // update lastUsed so we only try to refund every 5 mins.\n }\n }\n\n results.push({\n baseUrl: apiKeyEntry.baseUrl,\n success: refundResult.success,\n });\n } else {\n this.logger.warn(\n `refundProviders: cannot refund ${apiKeyEntry.baseUrl}; apiKeyEntryFull=${Boolean(apiKeyEntryFull)} balanceManager=${Boolean(this.balanceManager)}`\n );\n results.push({\n baseUrl: apiKeyEntry.baseUrl,\n success: false,\n });\n }\n }\n\n return results;\n }\n\n /**\n * Create an insufficient balance error result\n */\n private _createInsufficientBalanceError(\n required: number,\n normalizedBalances: Record<string, number>,\n availableBalance?: number\n ): SpendResult {\n let maxBalance = 0;\n let maxMintUrl = \"\";\n\n for (const mintUrl in normalizedBalances) {\n const balanceInSats = normalizedBalances[mintUrl];\n\n if (balanceInSats > maxBalance) {\n maxBalance = balanceInSats;\n maxMintUrl = mintUrl;\n }\n }\n\n const error = new InsufficientBalanceError(\n required,\n availableBalance ?? maxBalance,\n maxBalance,\n maxMintUrl\n );\n\n return {\n token: null,\n status: \"failed\",\n balance: 0,\n error: error.message,\n errorDetails: {\n required,\n available: availableBalance ?? maxBalance,\n maxMintBalance: maxBalance,\n maxMintUrl,\n },\n };\n }\n\n private async _getProviderTokenBalance(\n baseUrl: string,\n token: string\n ): Promise<number> {\n try {\n const response = await fetch(`${baseUrl}v1/wallet/info`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (response.ok) {\n const data = await response.json();\n return data.balance / 1000;\n }\n } catch {\n return 0;\n }\n return 0;\n }\n}\n","/**\n * BalanceManager - Handles refunding and topping up tokens from providers\n *\n * Handles:\n * - Fetching refund tokens from provider API\n * - Receiving/storing refunded tokens\n * - Topping up API key balances with cashu tokens\n * - Error handling for various refund/topup failure modes\n *\n * Extracted from utils/cashuUtils.ts\n */\n\nimport type {\n WalletAdapter,\n StorageAdapter,\n ProviderRegistry,\n} from \"./interfaces\";\nimport type { RefundResult, TopUpResult, SdkLogger } from \"../core/types\";\nimport { consoleLogger } from \"../core/types\";\nimport { InsufficientBalanceError } from \"../core/errors\";\nimport { CashuSpender } from \"./CashuSpender\";\nimport {\n getBalanceInSats,\n isNetworkErrorMessage,\n selectMintWithBalance,\n} from \"./tokenUtils\";\n\n/**\n * Options for refunding API key balance\n */\nexport interface RefundApiKeyOptions {\n /** The mint URL (for NIP-60 wallet operations) */\n mintUrl: string;\n\n /** The provider base URL */\n baseUrl: string;\n\n /** The API key to use for authentication */\n apiKey: string;\n\n /** If true, forces refund even if the API key was used recently */\n forceRefund?: boolean;\n}\n\n/**\n * Options for topping up API key balance\n */\nexport interface TopUpOptions {\n /** The mint URL to spend from */\n mintUrl: string;\n\n /** The provider base URL */\n baseUrl: string;\n\n /** Amount to top up in sats */\n amount: number;\n\n /** Optional specific API key to top up (if not provided, uses stored token) */\n token?: string;\n}\n\nexport interface CreateProviderTokenOptions {\n mintUrl: string;\n baseUrl: string;\n amount: number;\n p2pkPubkey?: string;\n excludeMints?: string[];\n retryCount?: number;\n}\n\nexport interface ProviderTokenResult {\n success: boolean;\n token?: string;\n error?: string;\n selectedMintUrl?: string;\n amountSpent?: number;\n}\n\nexport interface BalanceState {\n totalBalance: number;\n providerBalances: Record<string, number>;\n mintBalances: Record<string, number>;\n}\n\n/**\n * BalanceManager handles token refunds and topups from providers\n */\nexport class BalanceManager {\n private cashuSpender: CashuSpender;\n /** In-memory guard for per-provider wallet mutations (topup / refund) */\n private providerWalletOps: Map<\n string,\n { type: \"topup\" | \"refund\"; startTime: number; endTime?: number }\n > = new Map();\n /** Cooldown (ms) between opposite operations on the same provider */\n private static readonly PROVIDER_WALLET_COOLDOWN_MS = 10_000;\n private readonly logger: SdkLogger;\n\n constructor(\n private walletAdapter: WalletAdapter,\n private storageAdapter: StorageAdapter,\n private providerRegistry?: ProviderRegistry,\n cashuSpender?: CashuSpender,\n logger?: SdkLogger\n ) {\n this.logger = (logger ?? consoleLogger).child(\"BalanceManager\");\n if (cashuSpender) {\n this.cashuSpender = cashuSpender;\n } else {\n this.cashuSpender = new CashuSpender(\n walletAdapter,\n storageAdapter,\n providerRegistry,\n this,\n this.logger\n );\n }\n }\n\n /**\n * Check whether a wallet operation (topup/refund) may run for a provider.\n * Returns the reason when blocked.\n */\n private _canRunProviderWalletOperation(\n baseUrl: string,\n type: \"topup\" | \"refund\"\n ): { allowed: boolean; reason?: string } {\n const existing = this.providerWalletOps.get(baseUrl);\n if (!existing) {\n return { allowed: true };\n }\n if (existing.type === type) {\n return { allowed: true };\n }\n // Opposite type in progress or recently completed\n if (!existing.endTime) {\n return {\n allowed: false,\n reason: `Provider wallet operation locked; ${existing.type} in progress`,\n };\n }\n const elapsed = Date.now() - existing.endTime;\n if (elapsed < BalanceManager.PROVIDER_WALLET_COOLDOWN_MS) {\n return {\n allowed: false,\n reason: `Provider wallet operation locked; recent ${existing.type} completed ${Math.round(elapsed / 1000)}s ago`,\n };\n }\n // Cooldown expired — clean up stale entry\n this.providerWalletOps.delete(baseUrl);\n return { allowed: true };\n }\n\n private _beginProviderWalletOperation(\n baseUrl: string,\n type: \"topup\" | \"refund\"\n ): void {\n this.providerWalletOps.set(baseUrl, { type, startTime: Date.now() });\n }\n\n private _endProviderWalletOperation(\n baseUrl: string,\n type: \"topup\" | \"refund\"\n ): void {\n const existing = this.providerWalletOps.get(baseUrl);\n if (existing && existing.type === type) {\n existing.endTime = Date.now();\n }\n }\n\n async getBalanceState(): Promise<BalanceState> {\n const mintBalances = await this.walletAdapter.getBalances();\n const units = this.walletAdapter.getMintUnits();\n\n let totalMintBalance = 0;\n const normalizedMintBalances: Record<string, number> = {};\n for (const url in mintBalances) {\n const balance = mintBalances[url];\n const unit = units[url];\n const balanceInSats = getBalanceInSats(balance, unit);\n normalizedMintBalances[url] = balanceInSats;\n totalMintBalance += balanceInSats;\n }\n\n const providerBalances: Record<string, number> = {};\n let totalProviderBalance = 0;\n\n const apiKeys = this.storageAdapter.getAllApiKeys();\n for (const apiKey of apiKeys) {\n if (!providerBalances[apiKey.baseUrl]) {\n providerBalances[apiKey.baseUrl] = 0;\n }\n providerBalances[apiKey.baseUrl] += apiKey.balance;\n totalProviderBalance += apiKey.balance;\n }\n\n return {\n totalBalance: totalMintBalance + totalProviderBalance,\n providerBalances,\n mintBalances: normalizedMintBalances,\n };\n }\n\n /**\n * Refund API key balance - convert remaining API key balance to cashu token\n * @param options - Refund options including forceRefund flag\n * @returns Refund result\n */\n async refundApiKey(options: RefundApiKeyOptions): Promise<RefundResult> {\n const { mintUrl, baseUrl, apiKey, forceRefund } = options;\n\n const guard = this._canRunProviderWalletOperation(baseUrl, \"refund\");\n if (!guard.allowed) {\n this.logger.log(`Skipping refund for ${baseUrl} - ${guard.reason}`);\n return { success: false, message: guard.reason };\n }\n\n this._beginProviderWalletOperation(baseUrl, \"refund\");\n\n try {\n return await this._refundApiKeyImpl({ mintUrl, baseUrl, apiKey, forceRefund });\n } finally {\n this._endProviderWalletOperation(baseUrl, \"refund\");\n }\n }\n\n private async _refundApiKeyImpl(options: RefundApiKeyOptions): Promise<RefundResult> {\n const { mintUrl, baseUrl, apiKey, forceRefund } = options;\n\n if (!apiKey) {\n this.logger.warn(`refundApiKey: aborting for ${baseUrl} - no API key`);\n return { success: false, message: \"No API key to refund\" };\n }\n\n // If forceRefund is not true, skip refund if the API key was used in the last 5 minutes\n if (!forceRefund) {\n const apiKeyEntry = this.storageAdapter.getApiKey(baseUrl);\n if (apiKeyEntry?.lastUsed) {\n const fiveMinutesAgo = Date.now() - 5 * 60 * 1000;\n if (apiKeyEntry.lastUsed > fiveMinutesAgo) {\n this.logger.log(\n `refundApiKey: skipping ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1000)}s ago`\n );\n return {\n success: false,\n message: \"API key was used recently, skipping refund\",\n };\n }\n }\n }\n\n let fetchResult:\n | { success: boolean; token?: string; requestId?: string; error?: string }\n | undefined;\n\n try {\n fetchResult = await this.fetchRefundToken(baseUrl, apiKey);\n\n if (fetchResult.error === \"No balance to refund\") {\n this.logger.log(`refundApiKey: provider says no balance for ${baseUrl}; removing API key`);\n this.storageAdapter.removeApiKey(baseUrl);\n return { success: true, message: \"No balance to refund, key cleaned up\" };\n }\n\n if (!fetchResult.success) {\n this.logger.warn(\n `refundApiKey: fetch failed for ${baseUrl}: ${fetchResult.error || \"API key refund failed\"}`\n );\n return {\n success: false,\n message: fetchResult.error || \"API key refund failed\",\n requestId: fetchResult.requestId,\n };\n }\n\n if (!fetchResult.token) {\n this.logger.warn(`refundApiKey: no token received for ${baseUrl}`);\n return {\n success: false,\n message: \"No token received from API key refund\",\n requestId: fetchResult.requestId,\n };\n }\n\n const receiveResult = await this.cashuSpender.receiveToken(\n fetchResult.token\n );\n const totalAmountMsat =\n receiveResult.unit === \"msat\"\n ? receiveResult.amount\n : receiveResult.amount * 1000;\n\n if (receiveResult.success) {\n this.storageAdapter.removeApiKey(baseUrl);\n } else {\n this.logger.warn(\n `refundApiKey: receive failed for ${baseUrl}; keeping API key. message=${receiveResult.message ?? \"none\"}`\n );\n }\n\n return {\n success: receiveResult.success,\n refundedAmount: totalAmountMsat,\n message: receiveResult.message,\n requestId: fetchResult.requestId,\n };\n } catch (error) {\n this.logger.error(\"API key refund error\", error);\n return this._handleRefundError(error, mintUrl, fetchResult?.requestId);\n }\n }\n\n /**\n * Fetch refund token from provider API using API key (or xcashu token) authentication\n */\n async fetchRefundToken(\n baseUrl: string,\n apiKeyOrToken: string,\n xCashu: boolean = false\n ): Promise<{\n success: boolean;\n token?: string;\n requestId?: string;\n error?: string;\n }> {\n if (!baseUrl) {\n return {\n success: false,\n error: \"No base URL configured\",\n };\n }\n\n const normalizedBaseUrl = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const url = `${normalizedBaseUrl}v1/wallet/refund`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, 60000);\n\n try {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (xCashu) {\n headers[\"X-Cashu\"] = apiKeyOrToken;\n } else {\n headers[\"Authorization\"] = `Bearer ${apiKeyOrToken}`;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const requestId =\n response.headers.get(\"x-routstr-request-id\") || undefined;\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n this.logger.warn(\n `fetchRefundToken: non-ok response for ${url} status=${response.status} statusText=${response.statusText}`,\n errorData\n );\n return {\n success: false,\n requestId,\n error: `API key refund failed: ${\n errorData?.detail || response.statusText\n }`,\n };\n }\n\n const data = await response.json();\n return {\n success: true,\n token: data.token,\n requestId,\n };\n } catch (error) {\n clearTimeout(timeoutId);\n this.logger.error(\"fetchRefundToken fetch error\", error);\n\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n return {\n success: false,\n error: \"Request timed out after 1 minute\",\n };\n }\n return {\n success: false,\n error: error.message,\n };\n }\n\n return {\n success: false,\n error: \"Unknown error occurred during API key refund request\",\n };\n }\n }\n\n /**\n * Top up API key balance with a cashu token\n */\n async topUp(options: TopUpOptions): Promise<TopUpResult> {\n const { mintUrl, baseUrl, amount, token: providedToken } = options;\n\n const guard = this._canRunProviderWalletOperation(baseUrl, \"topup\");\n if (!guard.allowed) {\n this.logger.log(`Skipping topup for ${baseUrl} - ${guard.reason}`);\n return { success: false, message: guard.reason };\n }\n\n this._beginProviderWalletOperation(baseUrl, \"topup\");\n\n try {\n return await this._topUpImpl({ mintUrl, baseUrl, amount, token: providedToken });\n } finally {\n this._endProviderWalletOperation(baseUrl, \"topup\");\n }\n }\n\n private async _topUpImpl(options: TopUpOptions): Promise<TopUpResult> {\n const { mintUrl, baseUrl, amount, token: providedToken } = options;\n\n if (!amount || amount <= 0) {\n return { success: false, message: \"Invalid top up amount\" };\n }\n\n const apiKeyEntry = providedToken\n ? null // providedToken is now the apiKey for apikeys mode\n : this.storageAdapter.getApiKey(baseUrl);\n const apiKey = providedToken || apiKeyEntry?.key;\n\n if (!apiKey) {\n return { success: false, message: \"No API key available for top up\" };\n }\n\n let cashuToken: string | null = null;\n let requestId: string | undefined;\n\n try {\n const tokenResult = await this.createProviderToken({\n mintUrl,\n baseUrl,\n amount,\n });\n\n if (!tokenResult.success || !tokenResult.token) {\n return {\n success: false,\n message: tokenResult.error || \"Unable to create top up token\",\n };\n }\n\n cashuToken = tokenResult.token;\n\n const topUpResult = await this._postTopUp(baseUrl, apiKey, cashuToken);\n requestId = topUpResult.requestId;\n this.logger.log(\"topUpResult:\", topUpResult);\n\n if (!topUpResult.success) {\n await this._recoverFailedTopUp(cashuToken);\n return {\n success: false,\n message: topUpResult.error || \"Top up failed\",\n requestId,\n recoveredToken: true,\n };\n }\n\n return {\n success: true,\n toppedUpAmount: amount,\n requestId,\n };\n } catch (error) {\n this.logger.log(`topup error for ${baseUrl}: ${error}`);\n if (cashuToken) {\n await this._recoverFailedTopUp(cashuToken);\n }\n\n return this._handleTopUpError(error, mintUrl, requestId);\n }\n }\n\n async createProviderToken(\n options: CreateProviderTokenOptions\n ): Promise<ProviderTokenResult> {\n const {\n mintUrl,\n baseUrl,\n amount,\n retryCount = 0,\n excludeMints = [],\n p2pkPubkey,\n } = options;\n\n const adjustedAmount = Math.ceil(amount);\n this.logger.log(`createProviderToken: baseUrl=${baseUrl} mintUrl=${mintUrl} amount=${amount} adjustedAmount=${adjustedAmount} retryCount=${retryCount}`);\n if (!adjustedAmount || isNaN(adjustedAmount)) {\n this.logger.error(`createProviderToken: invalid amount=${amount}`);\n return { success: false, error: \"Invalid top up amount\" };\n }\n\n const balanceState = await this.getBalanceState();\n const balances = await this.walletAdapter.getBalances();\n const units = this.walletAdapter.getMintUnits();\n\n const totalMintBalance = Object.values(balanceState.mintBalances).reduce(\n (sum, value) => sum + value,\n 0\n );\n const targetProviderBalance = balanceState.providerBalances[baseUrl] || 0;\n const refundableProviderBalance = Object.entries(\n balanceState.providerBalances\n )\n .filter(([providerBaseUrl]) => providerBaseUrl !== baseUrl)\n .reduce((sum, [, value]) => sum + value, 0);\n\n if (\n totalMintBalance + targetProviderBalance < adjustedAmount &&\n totalMintBalance + targetProviderBalance + refundableProviderBalance >=\n adjustedAmount &&\n retryCount < 3\n ) {\n await this._refundOtherProvidersForTopUp(baseUrl, mintUrl, retryCount, adjustedAmount);\n return this.createProviderToken({\n ...options,\n retryCount: retryCount + 1,\n });\n }\n\n if (totalMintBalance + targetProviderBalance < adjustedAmount) {\n const error = new InsufficientBalanceError(\n adjustedAmount,\n totalMintBalance + targetProviderBalance,\n totalMintBalance,\n Object.entries(balanceState.mintBalances).reduce(\n (max, [url, balance]) =>\n balance > max.balance ? { url, balance } : max,\n { url: \"\", balance: 0 }\n ).url\n );\n this.logger.error(`createProviderToken: insufficient balance required=${adjustedAmount} available=${totalMintBalance + targetProviderBalance} totalMint=${totalMintBalance} targetProvider=${targetProviderBalance}`);\n return { success: false, error: error.message };\n }\n\n const providerMints =\n baseUrl && this.providerRegistry\n ? this.providerRegistry.getProviderMints(baseUrl)\n : [];\n\n let requiredAmount = adjustedAmount;\n const supportedMintsOnly = providerMints.length > 0;\n\n let candidates = this._selectCandidateMints({\n balances,\n units,\n amount: requiredAmount,\n preferredMintUrl: mintUrl,\n excludeMints,\n allowedMints: supportedMintsOnly ? providerMints : undefined,\n });\n\n if (candidates.length === 0 && supportedMintsOnly) {\n requiredAmount += 2;\n candidates = this._selectCandidateMints({\n balances,\n units,\n amount: requiredAmount,\n preferredMintUrl: mintUrl,\n excludeMints,\n });\n }\n\n if (candidates.length === 0) {\n let maxBalance = 0;\n let maxMintUrl = \"\";\n for (const mintUrl in balances) {\n const balance = balances[mintUrl];\n const unit = units[mintUrl];\n const balanceInSats = getBalanceInSats(balance, unit);\n if (balanceInSats > maxBalance) {\n maxBalance = balanceInSats;\n maxMintUrl = mintUrl;\n }\n }\n\n this.logger.error(`createProviderToken: no candidate mints required=${requiredAmount} totalMint=${totalMintBalance} maxBalance=${maxBalance} maxMint=${maxMintUrl}`);\n const error = new InsufficientBalanceError(\n adjustedAmount,\n totalMintBalance,\n maxBalance,\n maxMintUrl\n );\n\n return { success: false, error: error.message };\n }\n\n let lastError: string | undefined;\n for (const candidateMint of candidates) {\n try {\n this.logger.log(`createProviderToken: attempting mint=${candidateMint} amount=${requiredAmount}`);\n const token = await this.walletAdapter.sendToken(\n candidateMint,\n requiredAmount,\n p2pkPubkey\n );\n this.logger.log(`createProviderToken: success from mint=${candidateMint}`);\n return {\n success: true,\n token,\n selectedMintUrl: candidateMint,\n amountSpent: requiredAmount,\n };\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n this.logger.error(`createProviderToken: mint=${candidateMint} failed: ${errorMsg}`);\n if (error instanceof Error) {\n lastError = errorMsg;\n\n if (isNetworkErrorMessage(error.message)) {\n this.logger.warn(`createProviderToken: network error from ${candidateMint}, trying next mint...`);\n continue;\n }\n }\n\n return {\n success: false,\n error: lastError || \"Failed to create top up token\",\n };\n }\n }\n\n this.logger.error(`createProviderToken: all candidate mints exhausted lastError=${lastError}`);\n return {\n success: false,\n error:\n lastError || \"All candidate mints failed while creating top up token\",\n };\n }\n\n private _selectCandidateMints(options: {\n balances: Record<string, number>;\n units: Record<string, \"sat\" | \"msat\">;\n amount: number;\n preferredMintUrl: string;\n excludeMints: string[];\n allowedMints?: string[];\n }): string[] {\n const {\n balances,\n units,\n amount,\n preferredMintUrl,\n excludeMints,\n allowedMints,\n } = options;\n\n const candidates: string[] = [];\n\n const { selectedMintUrl: firstMint } = selectMintWithBalance(\n balances,\n units,\n amount,\n excludeMints\n );\n\n if (\n firstMint &&\n (!allowedMints ||\n allowedMints.length === 0 ||\n allowedMints.includes(firstMint))\n ) {\n candidates.push(firstMint);\n }\n\n const canUseMint = (mint: string): boolean => {\n if (excludeMints.includes(mint)) return false;\n if (\n allowedMints &&\n allowedMints.length > 0 &&\n !allowedMints.includes(mint)\n ) {\n return false;\n }\n const rawBalance = balances[mint] || 0;\n const unit = units[mint];\n const balanceInSats = getBalanceInSats(rawBalance, unit);\n return balanceInSats >= amount;\n };\n\n if (\n preferredMintUrl &&\n canUseMint(preferredMintUrl) &&\n !candidates.includes(preferredMintUrl)\n ) {\n candidates.push(preferredMintUrl);\n }\n\n for (const mint in balances) {\n if (mint === preferredMintUrl || candidates.includes(mint)) continue;\n if (canUseMint(mint)) {\n candidates.push(mint);\n }\n }\n\n return candidates;\n }\n\n private async _refundOtherProvidersForTopUp(\n baseUrl: string,\n mintUrl: string,\n retryCount: number,\n requiredAmount: number\n ): Promise<void> {\n const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();\n\n // If retryCount >= 2, force refund even if API keys were used recently\n const forceRefund = retryCount >= 2;\n\n // Build full candidate list sorted by lastUsed, oldest first.\n // This way providers outside the 5-min window are tried first (natural\n // refund succeeds), and if we must force-refund, we target the oldest\n // (closest to expiring) locked providers first.\n const candidates = apiKeyDistribution\n .filter((apiKey) => apiKey.baseUrl !== baseUrl && apiKey.amount > 0)\n .map((apiKey) => {\n const full = this.storageAdapter.getApiKey(apiKey.baseUrl);\n return {\n baseUrl: apiKey.baseUrl,\n amount: apiKey.amount,\n lastUsed: full?.lastUsed ?? 0,\n key: full?.key,\n } as const;\n })\n .filter((c) => c.key != null)\n .sort((a, b) => a.lastUsed - b.lastUsed); // oldest first\n\n if (candidates.length === 0) return;\n\n if (forceRefund) {\n // Sequential: refund one at a time until we have enough liquid balance\n // for the target provider, so we only force-refund as few providers as\n // necessary.\n //\n // NOTE: refundApiKey() already calls removeApiKey() on success, so we\n // don't need to update the balance here — the key is gone.\n for (const candidate of candidates) {\n await this.refundApiKey({\n mintUrl,\n baseUrl: candidate.baseUrl,\n apiKey: candidate.key!,\n forceRefund: true,\n });\n\n // Check if we've freed enough balance for the target provider\n const newState = await this.getBalanceState();\n const newAvailable =\n (newState.mintBalances[mintUrl] || 0) +\n (newState.providerBalances[baseUrl] || 0);\n\n if (newAvailable >= requiredAmount) {\n this.logger.log(\n `_refundOtherProvidersForTopUp: freed enough balance (${newAvailable} >= ${requiredAmount}), stopping early`\n );\n return;\n }\n }\n } else {\n // Non-force: try all in parallel (existing behavior, now sorted by\n // lastUsed for determinism). Providers outside the 5-min window will\n // succeed and be cleaned up by refundApiKey; recently-used ones are\n // skipped without side effects.\n await Promise.allSettled(\n candidates.map((candidate) =>\n this.refundApiKey({\n mintUrl,\n baseUrl: candidate.baseUrl,\n apiKey: candidate.key!,\n forceRefund: false,\n })\n )\n );\n }\n }\n\n /**\n * Post topup request to provider API\n */\n private async _postTopUp(\n baseUrl: string,\n storedToken: string,\n cashuToken: string\n ): Promise<{\n success: boolean;\n requestId?: string;\n error?: string;\n }> {\n if (!baseUrl) {\n return {\n success: false,\n error: \"No base URL configured\",\n };\n }\n\n const normalizedBaseUrl = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const url = `${normalizedBaseUrl}v1/wallet/topup?cashu_token=${encodeURIComponent(\n cashuToken\n )}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, 60000);\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${storedToken}`,\n \"Content-Type\": \"application/json\",\n },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const requestId =\n response.headers.get(\"x-routstr-request-id\") || undefined;\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n return {\n success: false,\n requestId,\n error:\n errorData?.detail || `Top up failed with status ${response.status}`,\n };\n }\n\n return { success: true, requestId };\n } catch (error) {\n clearTimeout(timeoutId);\n this.logger.error(\"_postTopUp fetch error\", error);\n\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n return {\n success: false,\n error: \"Request timed out after 1 minute\",\n };\n }\n return {\n success: false,\n error: error.message,\n };\n }\n\n return {\n success: false,\n error: \"Unknown error occurred during top up request\",\n };\n }\n }\n\n /**\n * Attempt to receive token back after failed top up\n */\n private async _recoverFailedTopUp(cashuToken: string): Promise<void> {\n try {\n await this.cashuSpender.receiveToken(cashuToken);\n } catch (error) {\n this.logger.error(\"_recoverFailedTopUp: failed to recover token\", error);\n }\n }\n\n /**\n * Handle refund errors with specific error types\n */\n private _handleRefundError(\n error: unknown,\n mintUrl: string,\n requestId?: string\n ): RefundResult {\n if (error instanceof Error) {\n // Network errors\n if (isNetworkErrorMessage(error.message)) {\n return {\n success: false,\n message: `Failed to connect to the mint: ${mintUrl}`,\n requestId,\n };\n }\n\n // Wallet not found error\n if (error.message.includes(\"Wallet not found\")) {\n return {\n success: false,\n message: `Wallet couldn't be loaded. Please save this refunded cashu token manually.`,\n requestId,\n };\n }\n\n return {\n success: false,\n message: error.message,\n requestId,\n };\n }\n\n return {\n success: false,\n message: \"Refund failed\",\n requestId,\n };\n }\n\n /**\n * Get token balance from provider\n */\n async getTokenBalance(\n token: string,\n baseUrl: string\n ): Promise<{\n amount: number;\n reserved: number;\n unit: \"sat\" | \"msat\";\n apiKey: string;\n isInvalidApiKey?: boolean;\n /** True when the balance could not be determined (network error, non-OK\n * response, etc.). Callers MUST NOT use `amount` in arithmetic when\n * this flag is set — it is 0, not a real balance. */\n balanceUnknown?: boolean;\n }> {\n try {\n const response = await fetch(`${baseUrl}v1/wallet/info`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (response.ok) {\n const data = await response.json();\n return {\n amount: data.balance,\n reserved: data.reserved ?? 0,\n unit: \"msat\",\n apiKey: data.api_key,\n };\n } else {\n this.logger.warn(`getTokenBalance: status=${response.status}`);\n const data = await response.json();\n this.logger.warn(\"getTokenBalance: FAILED\", data);\n\n // Check for invalid/expired API key error (proofs already spent)\n const isInvalidApiKey =\n response.status === 401 &&\n data?.detail?.error?.code === \"invalid_api_key\" &&\n data?.detail?.error?.message?.includes(\"proofs already spent\");\n\n return {\n amount: 0,\n reserved: data.reserved ?? 0,\n unit: \"msat\",\n apiKey: data.api_key,\n isInvalidApiKey,\n balanceUnknown: true,\n };\n }\n } catch (error) {\n this.logger.error(\"getTokenBalance error\", error);\n }\n\n return {\n amount: 0,\n reserved: 0,\n unit: \"sat\",\n apiKey: \"\",\n balanceUnknown: true,\n };\n }\n\n /**\n * Handle topup errors with specific error types\n */\n private _handleTopUpError(\n error: unknown,\n mintUrl: string,\n requestId?: string\n ): TopUpResult {\n if (error instanceof Error) {\n if (isNetworkErrorMessage(error.message)) {\n return {\n success: false,\n message: `Failed to connect to the mint: ${mintUrl}`,\n requestId,\n };\n }\n\n if (error.message.includes(\"Wallet not found\")) {\n return {\n success: false,\n message:\n \"Wallet couldn't be loaded. The cashu token was recovered locally.\",\n requestId,\n };\n }\n\n return {\n success: false,\n message: error.message,\n requestId,\n };\n }\n\n return {\n success: false,\n message: \"Top up failed\",\n requestId,\n };\n }\n}\n","export type ProviderDirectoryEntry = {\n endpoint_url?: string | null;\n endpoint_urls?: string[] | null;\n onion_url?: string | null;\n onion_urls?: string[] | null;\n name?: string | null;\n};\n\nconst TOR_ONION_SUFFIX = \".onion\";\n\nexport const isTorContext = (): boolean => {\n if (typeof window === \"undefined\") return false;\n const hostname = window.location.hostname.toLowerCase();\n return hostname.endsWith(TOR_ONION_SUFFIX);\n};\n\nexport const isOnionUrl = (url: string): boolean => {\n if (!url) return false;\n const trimmed = url.trim().toLowerCase();\n if (!trimmed) return false;\n try {\n const candidate = trimmed.startsWith(\"http\")\n ? trimmed\n : `http://${trimmed}`;\n return new URL(candidate).hostname.endsWith(TOR_ONION_SUFFIX);\n } catch {\n return trimmed.includes(TOR_ONION_SUFFIX);\n }\n};\n\nconst shouldAllowHttp = (url: string, torMode: boolean): boolean => {\n if (!url.startsWith(\"http://\")) return true;\n if (url.includes(\"localhost\") || url.includes(\"127.0.0.1\")) return true;\n return torMode && isOnionUrl(url);\n};\n\nexport const normalizeProviderUrl = (\n url?: string | null,\n torMode: boolean = false\n): string | null => {\n if (!url || typeof url !== \"string\") return null;\n const trimmed = url.trim();\n if (!trimmed) return null;\n if (/^https?:\\/\\//i.test(trimmed)) {\n return trimmed.endsWith(\"/\") ? trimmed : `${trimmed}/`;\n }\n const useHttpForOnion = torMode && isOnionUrl(trimmed);\n const withProto = `${useHttpForOnion ? \"http\" : \"https\"}://${trimmed}`;\n return withProto.endsWith(\"/\") ? withProto : `${withProto}/`;\n};\n\nconst dedupePreserveOrder = (urls: string[]): string[] => {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const url of urls) {\n if (!seen.has(url)) {\n seen.add(url);\n out.push(url);\n }\n }\n return out;\n};\n\nexport const getProviderEndpoints = (\n provider: ProviderDirectoryEntry,\n torMode: boolean\n): string[] => {\n const rawUrls: (string | null | undefined)[] = [\n provider.endpoint_url,\n ...(Array.isArray(provider.endpoint_urls) ? provider.endpoint_urls : []),\n provider.onion_url,\n ...(Array.isArray(provider.onion_urls) ? provider.onion_urls : []),\n ];\n\n const normalized = rawUrls\n .map((value) => normalizeProviderUrl(value, torMode))\n .filter((value): value is string => Boolean(value));\n\n const unique = dedupePreserveOrder(normalized).filter((value) =>\n shouldAllowHttp(value, torMode)\n );\n\n if (unique.length === 0) return [];\n\n const onion = unique.filter((value) => isOnionUrl(value));\n const clearnet = unique.filter((value) => !isOnionUrl(value));\n\n if (torMode) {\n return onion.length > 0 ? onion : clearnet;\n }\n\n return clearnet;\n};\n\nexport const filterBaseUrlsForTor = (\n baseUrls: string[],\n torMode: boolean\n): string[] => {\n if (!Array.isArray(baseUrls)) return [];\n\n const normalized = baseUrls\n .map((value) => normalizeProviderUrl(value, torMode))\n .filter((value): value is string => Boolean(value));\n\n const filtered = normalized.filter((value) =>\n torMode ? true : !isOnionUrl(value)\n );\n\n return dedupePreserveOrder(\n filtered.filter((value) => shouldAllowHttp(value, torMode))\n );\n};\n","/**\n * ProviderManager - Handles provider selection and failover logic\n *\n * Handles:\n * - Finding the best provider for a model based on price\n * - Provider failover when errors occur\n * - Tracking failed providers to avoid retry loops\n * - Provider version compatibility\n *\n * Extracted from utils/apiUtils.ts findNextBestProvider and related logic\n */\n\nimport type { ProviderRegistry } from \"../wallet/interfaces\";\nimport type { Model, SdkLogger } from \"../core/types\";\nimport { consoleLogger } from \"../core/types\";\nimport type { SdkStore } from \"../storage/store\";\nimport { isOnionUrl, isTorContext } from \"../utils/torUtils\";\n\nexport interface ModelProviderPrice {\n baseUrl: string;\n model: Model;\n promptPerMillion: number;\n completionPerMillion: number;\n totalPerMillion: number;\n}\n\n/**\n * Extract image resolution (width, height) from a base64 data URL without DOM.\n * Supports PNG and JPEG. Returns null if format unsupported or parsing fails.\n */\nfunction getImageResolutionFromDataUrl(\n dataUrl: string\n): { width: number; height: number } | null {\n try {\n if (typeof dataUrl !== \"string\" || !dataUrl.startsWith(\"data:\"))\n return null;\n\n const commaIdx = dataUrl.indexOf(\",\");\n if (commaIdx === -1) return null;\n\n const meta = dataUrl.slice(5, commaIdx); // e.g. \"image/png;base64\"\n const base64 = dataUrl.slice(commaIdx + 1);\n\n // Decode base64 to binary\n const binary =\n typeof atob === \"function\"\n ? atob(base64)\n : Buffer.from(base64, \"base64\").toString(\"binary\");\n\n const len = binary.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) bytes[i] = binary.charCodeAt(i);\n\n const isPNG = meta.includes(\"image/png\");\n const isJPEG = meta.includes(\"image/jpeg\") || meta.includes(\"image/jpg\");\n\n // PNG: width/height are 4-byte big-endian at offsets 16 and 20\n if (isPNG) {\n // Validate PNG signature\n const sig = [137, 80, 78, 71, 13, 10, 26, 10];\n for (let i = 0; i < sig.length; i++) {\n if (bytes[i] !== sig[i]) return null;\n }\n const view = new DataView(\n bytes.buffer,\n bytes.byteOffset,\n bytes.byteLength\n );\n const width = view.getUint32(16, false);\n const height = view.getUint32(20, false);\n if (width > 0 && height > 0) return { width, height };\n return null;\n }\n\n // JPEG: parse markers to SOF0/SOF2 for dimensions\n if (isJPEG) {\n let offset = 0;\n // JPEG SOI 0xFFD8\n if (bytes[offset++] !== 0xff || bytes[offset++] !== 0xd8) return null;\n\n while (offset < bytes.length) {\n // Find marker\n while (offset < bytes.length && bytes[offset] !== 0xff) offset++;\n if (offset + 1 >= bytes.length) break;\n\n // Skip fill bytes 0xFF\n while (bytes[offset] === 0xff) offset++;\n const marker = bytes[offset++];\n\n // Standalone markers without length\n if (marker === 0xd8 || marker === 0xd9) continue; // SOI/EOI\n\n if (offset + 1 >= bytes.length) break;\n const length = (bytes[offset] << 8) | bytes[offset + 1];\n offset += 2;\n\n // SOF0 (0xC0) or SOF2 (0xC2) contain dimensions\n if (marker === 0xc0 || marker === 0xc2) {\n if (length < 7 || offset + length - 2 > bytes.length) return null;\n const precision = bytes[offset];\n const height = (bytes[offset + 1] << 8) | bytes[offset + 2];\n const width = (bytes[offset + 3] << 8) | bytes[offset + 4];\n if (precision > 0 && width > 0 && height > 0)\n return { width, height };\n return null;\n } else {\n // Skip this segment\n offset += length - 2;\n }\n }\n return null;\n }\n\n // Unsupported formats (e.g., webp/gif) - skip for now\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Calculate image tokens based on OpenAI's vision pricing.\n *\n * For low detail: 85 tokens\n * For high detail/auto: 85 base tokens + 170 tokens per 512px tile\n */\nfunction calculateImageTokens(\n width: number,\n height: number,\n detail: \"low\" | \"high\" | \"auto\" = \"auto\"\n): number {\n if (detail === \"low\") return 85;\n\n let w = width;\n let h = height;\n\n // Clamp longest side to 2048 while preserving aspect ratio\n if (w > 2048 || h > 2048) {\n const aspectRatio = w / h;\n if (w > h) {\n w = 2048;\n h = Math.floor(w / aspectRatio);\n } else {\n h = 2048;\n w = Math.floor(h * aspectRatio);\n }\n }\n\n // Then clamp longest side to 768 while preserving aspect ratio\n if (w > 768 || h > 768) {\n const aspectRatio = w / h;\n if (w > h) {\n w = 768;\n h = Math.floor(w / aspectRatio);\n } else {\n h = 768;\n w = Math.floor(h * aspectRatio);\n }\n }\n\n // Number of 512px tiles, ceil division using (x + 511) // 512\n const tilesWidth = Math.floor((w + 511) / 512);\n const tilesHeight = Math.floor((h + 511) / 512);\n const numTiles = tilesWidth * tilesHeight;\n\n return 85 + 170 * numTiles;\n}\n\n/**\n * Candidate provider for failover\n */\ninterface CandidateProvider {\n baseUrl: string;\n model: Model;\n cost: number;\n}\n\n/**\n * ProviderManager handles provider selection and failover\n */\nexport class ProviderManager {\n private failedProviders = new Set<string>();\n /** Track when each provider last failed (provider URL -> timestamp) */\n private lastFailed = new Map<string, number>();\n /** Providers on cooldown: [provider_url, cooldown_started_timestamp][] */\n private providersOnCoolDown: [string, number][] = [];\n /** Cooldown duration in milliseconds (42 seconds) */\n private static readonly COOLDOWN_DURATION_MS = 42 * 1000;\n /** Optional persistent store for failure tracking */\n private store: SdkStore | null = null;\n /** Instance ID for debugging */\n private readonly instanceId: string;\n private readonly logger: SdkLogger;\n\n constructor(\n private providerRegistry: ProviderRegistry,\n store?: SdkStore,\n logger?: SdkLogger\n ) {\n this.instanceId = `pm_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n this.logger = (logger ?? consoleLogger).child(`ProviderManager:${this.instanceId}`);\n if (store) {\n this.store = store;\n this.hydrateFromStore();\n }\n }\n\n /**\n * Hydrate in-memory state from persistent store\n */\n private hydrateFromStore(): void {\n if (!this.store) return;\n const state = this.store.getState();\n\n // Hydrate failedProviders\n this.failedProviders = new Set(state.failedProviders);\n\n // Hydrate lastFailed\n this.lastFailed = new Map(Object.entries(state.lastFailed));\n\n // Hydrate providersOnCooldown (filter out expired)\n const now = Date.now();\n this.providersOnCoolDown = state.providersOnCooldown\n .filter(\n (entry) => now - entry.timestamp < ProviderManager.COOLDOWN_DURATION_MS\n )\n .map((entry) => [entry.baseUrl, entry.timestamp] as [string, number]);\n\n this.logger.log(`Hydrated from store: failedProviders=${this.failedProviders.size} lastFailed=${this.lastFailed.size} providersOnCooldown=${this.providersOnCoolDown.length}`);\n }\n\n /**\n * Get instance ID for debugging\n */\n getInstanceId(): string {\n return this.instanceId;\n }\n\n /**\n * Clean up expired cooldown entries\n * Also removes the provider from failedProviders so it can be retried\n */\n private cleanupExpiredCooldowns(): void {\n const now = Date.now();\n const before = this.providersOnCoolDown.length;\n this.providersOnCoolDown = this.providersOnCoolDown.filter(\n ([url, timestamp]) => {\n const age = now - timestamp;\n const isExpired = age >= ProviderManager.COOLDOWN_DURATION_MS;\n if (isExpired) {\n this.logger.log(`Removing expired cooldown for ${url} (age: ${age}ms)`);\n // Also remove from failedProviders so the provider can be retried\n this.failedProviders.delete(url);\n // Persist to store\n if (this.store) {\n this.store.getState().removeFailedProvider(url);\n }\n }\n return !isExpired;\n }\n );\n const after = this.providersOnCoolDown.length;\n if (before !== after) {\n this.logger.log(`Cleaned up ${before - after} expired cooldown(s), ${after} remaining`);\n }\n }\n\n /**\n * Get the cooldown duration in milliseconds\n */\n getCooldownDurationMs(): number {\n return ProviderManager.COOLDOWN_DURATION_MS;\n }\n\n /**\n * Check if a provider is currently on cooldown\n */\n isOnCooldown(baseUrl: string): boolean {\n this.cleanupExpiredCooldowns();\n\n const result = this.providersOnCoolDown.some(([url]) => url === baseUrl);\n return result;\n }\n\n /**\n * Get all providers currently on cooldown\n */\n getProvidersOnCooldown(): [string, number][] {\n this.cleanupExpiredCooldowns();\n return [...this.providersOnCoolDown];\n }\n\n /**\n * Reset the failed providers list\n */\n resetFailedProviders(): void {\n this.failedProviders.clear();\n // Persist to store\n if (this.store) {\n this.store.getState().setFailedProviders([]);\n }\n }\n\n /**\n * Get the last failed timestamp for a provider\n */\n getLastFailed(baseUrl: string): number | undefined {\n return this.lastFailed.get(baseUrl);\n }\n\n /**\n * Get all providers with their last failed timestamps\n */\n getAllLastFailed(): Map<string, number> {\n return new Map(this.lastFailed);\n }\n\n /**\n * Mark a provider as failed\n * If a provider fails twice within 5 minutes, it's added to cooldown\n */\n markFailed(baseUrl: string): void {\n const now = Date.now();\n const lastFailure = this.lastFailed.get(baseUrl);\n\n this.logger.log(`markFailed: ${baseUrl} lastFailure=${lastFailure} now=${now}`);\n\n if (lastFailure !== undefined) {\n const timeSinceLastFailure = now - lastFailure;\n this.logger.log(`markFailed: timeSinceLastFailure=${timeSinceLastFailure}ms withinCooldown=${timeSinceLastFailure < ProviderManager.COOLDOWN_DURATION_MS}`);\n }\n\n // Track this failure in memory\n this.lastFailed.set(baseUrl, now);\n this.failedProviders.add(baseUrl);\n\n // Persist to store\n if (this.store) {\n this.store.getState().setLastFailedTimestamp(baseUrl, now);\n this.store.getState().addFailedProvider(baseUrl);\n }\n\n this.logger.log(`markFailed: updated ${baseUrl} to ${now}, failedProviders=${this.failedProviders.size}`);\n\n // Check if this is a second failure within the cooldown window\n if (\n lastFailure !== undefined &&\n now - lastFailure < ProviderManager.COOLDOWN_DURATION_MS\n ) {\n // Second failure within 5 minutes - add to cooldown\n this.logger.log(`markFailed: second failure within cooldown window for ${baseUrl}`);\n if (!this.isOnCooldown(baseUrl)) {\n this.providersOnCoolDown.push([baseUrl, now]);\n // Persist to store\n if (this.store) {\n this.store.getState().addProviderOnCooldown(baseUrl, now);\n }\n this.logger.log(`markFailed: ${baseUrl} added to cooldown`);\n } else {\n this.logger.log(`markFailed: ${baseUrl} already on cooldown`);\n }\n } else {\n if (lastFailure === undefined) {\n this.logger.log(`markFailed: first failure for ${baseUrl}`);\n } else {\n this.logger.log(`markFailed: failure outside cooldown window for ${baseUrl} (${now - lastFailure}ms ago)`);\n }\n }\n }\n\n /**\n * Remove a provider from cooldown (e.g., after successful request)\n */\n removeFromCooldown(baseUrl: string): void {\n this.providersOnCoolDown = this.providersOnCoolDown.filter(\n ([url]) => url !== baseUrl\n );\n // Persist to store\n if (this.store) {\n this.store.getState().removeProviderFromCooldown(baseUrl);\n }\n }\n\n /**\n * Clear all cooldown tracking\n */\n clearCooldowns(): void {\n this.providersOnCoolDown = [];\n // Persist to store\n if (this.store) {\n this.store.getState().clearProvidersOnCooldown();\n }\n }\n\n /**\n * Clear all failure tracking (lastFailed timestamps)\n */\n clearFailureHistory(): void {\n this.lastFailed.clear();\n // Persist to store\n if (this.store) {\n this.store.getState().setLastFailed({});\n }\n }\n\n /**\n * Check if a provider has failed\n */\n hasFailed(baseUrl: string): boolean {\n return this.failedProviders.has(baseUrl);\n }\n\n /**\n * Get a copy of the failed providers set\n */\n getFailedProviders(): Set<string> {\n return new Set(this.failedProviders);\n }\n\n /**\n * Find the next best provider for a model\n * @param modelId The model ID to find a provider for\n * @param currentBaseUrl The current provider to exclude\n * @returns The best provider URL or null if none available\n */\n findNextBestProvider(modelId: string, currentBaseUrl: string): string | null {\n try {\n const torMode = isTorContext();\n const disabledProviders = new Set(\n this.providerRegistry.getDisabledProviders()\n );\n\n this.logger.log(`findNextBestProvider: model=${modelId} disabled=${[...disabledProviders].length} onCooldown=${this.providersOnCoolDown.length}`);\n\n // Get all providers with their models\n const allProviders = this.providerRegistry.getAllProvidersModels();\n this.logger.log(`findNextBestProvider: total providers=${Object.keys(allProviders).length}`);\n\n // Find all candidate providers\n const candidates: CandidateProvider[] = [];\n\n for (const [baseUrl, models] of Object.entries(allProviders)) {\n // Skip current, failed, disabled, and cooldown providers\n if (baseUrl === currentBaseUrl) {\n continue;\n }\n // if (this.failedProviders.has(baseUrl)) {\n // console.log(`[findNextBestProvider:${this.instanceId}] SKIP (failed): ${baseUrl}`);\n // skippedFailed++;\n // continue;\n // }\n if (disabledProviders.has(baseUrl)) {\n continue;\n }\n if (this.isOnCooldown(baseUrl)) {\n continue;\n }\n\n // Skip onion URLs if not in Tor mode\n if (!torMode && isOnionUrl(baseUrl)) {\n continue;\n }\n\n // Find the model in this provider's list\n const model = models.find((m: Model) => m.id === modelId);\n if (!model) {\n continue;\n }\n\n // Calculate cost (using completion price as the metric)\n const cost = model.sats_pricing?.completion ?? 0;\n candidates.push({ baseUrl, model, cost });\n }\n\n // Sort by price (lowest first)\n candidates.sort((a, b) => a.cost - b.cost);\n\n if (candidates.length > 0) {\n return candidates[0].baseUrl;\n } else {\n return null;\n }\n } catch (error) {\n this.logger.error(\"findNextBestProvider error:\", error);\n return null;\n }\n }\n\n /**\n * Find the best model for a provider\n * Useful when switching providers and need to find equivalent model\n */\n async getModelForProvider(\n baseUrl: string,\n modelId: string\n ): Promise<Model | null> {\n // Get models for this provider\n const models = this.providerRegistry.getModelsForProvider(baseUrl);\n\n // First try exact match\n const exactMatch = models.find((m) => m.id === modelId);\n if (exactMatch) return exactMatch;\n\n // Try matching by ID suffix (for backward compatibility with v0.1.x providers)\n const providerInfo = await this.providerRegistry.getProviderInfo(baseUrl);\n if (providerInfo?.version && /^0\\.1\\./.test(providerInfo.version)) {\n const suffix = modelId.split(\"/\").pop();\n const suffixMatch = models.find((m) => m.id === suffix);\n if (suffixMatch) return suffixMatch;\n }\n\n return null;\n }\n\n /**\n * Get all available providers for a model\n * Returns sorted list by price\n */\n getAllProvidersForModel(modelId: string): Array<{\n baseUrl: string;\n model: Model;\n cost: number;\n }> {\n const candidates: CandidateProvider[] = [];\n const allProviders = this.providerRegistry.getAllProvidersModels();\n const disabledProviders = new Set(\n this.providerRegistry.getDisabledProviders()\n );\n const torMode = isTorContext();\n\n for (const [baseUrl, models] of Object.entries(allProviders)) {\n if (disabledProviders.has(baseUrl)) continue;\n if (this.isOnCooldown(baseUrl)) continue;\n if (!torMode && isOnionUrl(baseUrl))\n continue;\n\n const model = models.find((m: Model) => m.id === modelId);\n if (!model) continue;\n\n const cost = model.sats_pricing?.completion ?? 0;\n candidates.push({ baseUrl, model, cost });\n }\n\n return candidates.sort((a, b) => a.cost - b.cost);\n }\n\n /**\n * Get providers for a model sorted by prompt+completion pricing\n */\n getProviderPriceRankingForModel(\n modelId: string,\n options: { torMode?: boolean; includeDisabled?: boolean } = {}\n ): ModelProviderPrice[] {\n const includeDisabled = options.includeDisabled ?? false;\n const torMode = options.torMode ?? false;\n const disabledProviderList = this.providerRegistry.getDisabledProviders();\n const disabledProviders = new Set(disabledProviderList);\n if (disabledProviderList.length > 0) {\n this.logger.log(`getProviderPriceRankingForModel: disabled providers (${disabledProviderList.length}): ${disabledProviderList.join(\", \")}`);\n }\n const allModels = this.providerRegistry.getAllProvidersModels();\n const results: ModelProviderPrice[] = [];\n\n for (const [baseUrl, models] of Object.entries(allModels)) {\n if (!includeDisabled && disabledProviders.has(baseUrl)) continue;\n if (this.isOnCooldown(baseUrl)) continue;\n if (torMode && !baseUrl.includes(\".onion\")) continue;\n if (\n !torMode &&\n baseUrl.includes(\".onion\")\n )\n continue;\n\n const match = models.find((model) => model.id === modelId);\n if (!match?.sats_pricing) continue;\n\n const prompt = match.sats_pricing.prompt;\n const completion = match.sats_pricing.completion;\n if (typeof prompt !== \"number\" || typeof completion !== \"number\") {\n continue;\n }\n\n const promptPerMillion = prompt * 1_000_000;\n const completionPerMillion = completion * 1_000_000;\n const totalPerMillion = promptPerMillion + completionPerMillion;\n\n results.push({\n baseUrl,\n model: match,\n promptPerMillion,\n completionPerMillion,\n totalPerMillion,\n });\n }\n\n results.sort((a, b) => {\n if (a.totalPerMillion !== b.totalPerMillion) {\n return a.totalPerMillion - b.totalPerMillion;\n }\n return a.baseUrl.localeCompare(b.baseUrl);\n });\n\n if (results.length > 0) {\n const ranking = results\n .map((r, i) => ` ${i + 1}. ${r.baseUrl} total=${r.totalPerMillion.toFixed(2)} sats/M (prompt=${r.promptPerMillion.toFixed(2)} completion=${r.completionPerMillion.toFixed(2)})`)\n .join(\"\\n\");\n this.logger.log(`getProviderPriceRankingForModel: ${modelId} ranking (${results.length} providers):\\n${ranking}`);\n } else {\n this.logger.log(`getProviderPriceRankingForModel: ${modelId} no providers found`);\n }\n\n return results;\n }\n\n /**\n * Get best-priced provider for a specific model\n */\n getBestProviderForModel(\n modelId: string,\n options: { torMode?: boolean; includeDisabled?: boolean } = {}\n ): string | null {\n const ranking = this.getProviderPriceRankingForModel(modelId, options);\n return ranking[0]?.baseUrl ?? null;\n }\n\n private normalizeModelId(modelId: string): string {\n return modelId.includes(\"/\")\n ? modelId.split(\"/\").pop() || modelId\n : modelId;\n }\n\n /**\n * Check if a provider accepts a specific mint\n */\n providerAcceptsMint(baseUrl: string, mintUrl: string): boolean {\n const providerMints = this.providerRegistry.getProviderMints(baseUrl);\n if (providerMints.length === 0) {\n // If no mints specified, provider accepts all\n return true;\n }\n return providerMints.includes(mintUrl);\n }\n\n /**\n * Get required sats for a model based on message history\n * Simple estimation based on typical usage\n */\n getRequiredSatsForModel(\n model: Model,\n apiMessages: any[],\n maxTokens?: number\n ): number {\n try {\n let imageTokens = 0;\n if (apiMessages) {\n for (const msg of apiMessages as any[]) {\n const content = (msg as any)?.content;\n if (Array.isArray(content)) {\n for (const part of content) {\n const isImage =\n part && typeof part === \"object\" && part.type === \"image_url\";\n const url: string | undefined = isImage\n ? typeof part.image_url === \"string\"\n ? part.image_url\n : part.image_url?.url\n : undefined;\n\n // Expecting a base64 data URL for local image inputs\n if (url && typeof url === \"string\" && url.startsWith(\"data:\")) {\n const res = getImageResolutionFromDataUrl(url);\n if (res) {\n const tokensFromImage = calculateImageTokens(\n res.width,\n res.height\n );\n // const patchSize = 32;\n // const patchesW = Math.floor((res.width + patchSize - 1) / patchSize);\n // const patchesH = Math.floor((res.height + patchSize - 1) / patchSize);\n // const tokensFromImage = patchesW * patchesH;\n imageTokens += tokensFromImage;\n this.logger.log(`IMAGE INPUT RESOLUTION width=${res.width} height=${res.height} tokens=${tokensFromImage}`);\n } else {\n this.logger.log(\"IMAGE INPUT RESOLUTION: unknown format\");\n }\n }\n }\n }\n }\n }\n // Remove image_url parts from apiMessages when estimating text token count\n const apiMessagesNoImages = apiMessages // SWITCH AFTER NODE UPDAATES\n ? (apiMessages as any[]).map((m: any) => {\n if (Array.isArray(m?.content)) {\n const filtered = m.content.filter(\n (p: any) =>\n !(p && typeof p === \"object\" && p.type === \"image_url\")\n );\n return { ...m, content: filtered };\n }\n return m;\n })\n : undefined;\n\n const approximateTokens = apiMessagesNoImages // SWITCH AFTER NODE UPDAATES\n ? Math.ceil(JSON.stringify(apiMessagesNoImages, null, 2).length / 2.84)\n : 10000; // Assumed tokens for minimum balance calculation\n\n const totalInputTokens = approximateTokens + imageTokens;\n\n const sp: any = model?.sats_pricing as any;\n\n if (!sp) {\n return 0;\n }\n\n // If we don't have max_completion_cost, fall back to max_cost\n if (!sp.max_completion_cost) {\n return sp.max_cost ?? 50;\n }\n\n // Calculate based on token usage (similar to getTokenAmountForModel in apiUtils.ts)\n const promptCosts = (sp.prompt || 0) * totalInputTokens;\n let completionCost = sp.max_completion_cost;\n if (maxTokens !== undefined && sp.completion) {\n completionCost = sp.completion * maxTokens;\n }\n const totalEstimatedCosts = (promptCosts + completionCost) * 1.05;\n // return totalEstimatedCosts > sp.max_cost ? sp.max_cost : totalEstimatedCosts; // in some image input calculations, this cost balloons up. Now includes image tokens via 32px patches.\n return totalEstimatedCosts; // Backend has a bug here.it's calculating image tokens wrong. gotta switch to different logic once its fixed\n } catch (e) {\n this.logger.error(\"getRequiredSatsForModel error:\", e);\n return 0;\n }\n }\n}\n","import type { StorageDriver } from \"../types\";\n\nconst canUseLocalStorage = (): boolean => {\n return (\n typeof window !== \"undefined\" && typeof window.localStorage !== \"undefined\"\n );\n};\n\nconst isQuotaExceeded = (error: unknown): boolean => {\n const e = error as { name?: string; code?: number } | null;\n return (\n !!e &&\n (e?.name === \"QuotaExceededError\" || e?.code === 22 || e?.code === 1014)\n );\n};\n\nconst NON_CRITICAL_KEYS = new Set<string>([\"modelsFromAllProviders\"]);\n\nexport const localStorageDriver: StorageDriver = {\n async getItem<T>(key: string, defaultValue: T): Promise<T> {\n if (!canUseLocalStorage()) return defaultValue;\n try {\n const item = window.localStorage.getItem(key);\n if (item === null) return defaultValue;\n try {\n return JSON.parse(item) as T;\n } catch (parseError) {\n if (typeof defaultValue === \"string\") {\n return item as T;\n }\n throw parseError;\n }\n } catch (error) {\n console.error(`Error retrieving item with key \"${key}\":`, error);\n if (canUseLocalStorage()) {\n try {\n window.localStorage.removeItem(key);\n } catch (removeError) {\n console.error(\n `Error removing corrupted item with key \"${key}\":`,\n removeError\n );\n }\n }\n return defaultValue;\n }\n },\n async setItem<T>(key: string, value: T): Promise<void> {\n if (!canUseLocalStorage()) return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch (error) {\n if (isQuotaExceeded(error)) {\n if (NON_CRITICAL_KEYS.has(key)) {\n console.warn(\n `Storage quota exceeded; skipping non-critical key \"${key}\".`\n );\n return;\n }\n try {\n window.localStorage.removeItem(\"modelsFromAllProviders\");\n } catch {}\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n return;\n } catch (retryError) {\n console.warn(\n `Storage quota exceeded; unable to persist key \"${key}\" after cleanup attempt.`,\n retryError\n );\n return;\n }\n }\n console.error(`Error storing item with key \"${key}\":`, error);\n }\n },\n async removeItem(key: string): Promise<void> {\n if (!canUseLocalStorage()) return;\n try {\n window.localStorage.removeItem(key);\n } catch (error) {\n console.error(`Error removing item with key \"${key}\":`, error);\n }\n },\n};\n","import type { StorageDriver } from \"../types\";\n\nexport const createMemoryDriver = (\n seed?: Record<string, string>\n): StorageDriver => {\n const store = new Map<string, string>();\n\n if (seed) {\n for (const [key, value] of Object.entries(seed)) {\n store.set(key, value);\n }\n }\n\n return {\n async getItem<T>(key: string, defaultValue: T): Promise<T> {\n const item = store.get(key);\n if (item === undefined) return defaultValue;\n try {\n return JSON.parse(item) as T;\n } catch (parseError) {\n if (typeof defaultValue === \"string\") {\n return item as T;\n }\n throw parseError;\n }\n },\n async setItem<T>(key: string, value: T): Promise<void> {\n store.set(key, JSON.stringify(value));\n },\n async removeItem(key: string): Promise<void> {\n store.delete(key);\n },\n };\n};\n","export const SDK_STORAGE_KEYS = {\n MODELS_FROM_ALL_PROVIDERS: \"modelsFromAllProviders\",\n LAST_USED_MODEL: \"lastUsedModel\",\n BASE_URLS_LIST: \"base_urls_list\",\n DISABLED_PROVIDERS: \"disabled_providers\",\n MINTS_FROM_ALL_PROVIDERS: \"mints_from_all_providers\",\n INFO_FROM_ALL_PROVIDERS: \"info_from_all_providers\",\n LAST_MODELS_UPDATE: \"lastModelsUpdate\",\n LAST_BASE_URLS_UPDATE: \"lastBaseUrlsUpdate\",\n API_KEYS: \"api_keys\",\n CHILD_KEYS: \"child_keys\",\n XCASHU_TOKENS: \"xcashu_tokens\",\n ROUTSTR21_MODELS: \"routstr21Models\",\n LAST_ROUTSTR21_MODELS_UPDATE: \"lastRoutstr21ModelsUpdate\",\n CACHED_RECEIVE_TOKENS: \"cached_receive_tokens\",\n USAGE_TRACKING: \"usage_tracking\",\n CLIENT_IDS: \"client_ids\",\n FAILED_PROVIDERS: \"failed_providers\",\n LAST_FAILED: \"last_failed\",\n PROVIDERS_ON_COOLDOWN: \"providers_on_cooldown\",\n} as const;\n\nexport type SdkStorageKey =\n (typeof SDK_STORAGE_KEYS)[keyof typeof SDK_STORAGE_KEYS];\n","import type {\n AggregateUsageOptions,\n UsageAggregateRow,\n UsageGroupBy,\n} from \"./interfaces\";\nimport type { UsageTrackingEntry } from \"./types\";\n\n// Shared, platform-agnostic aggregation helpers used by every usage tracking\n// driver. SQL drivers (bunSqlite/sqlite) push the work down to SQLite via\n// buildAggregateSql/mapAggregateRow; in-memory drivers (memory/indexedDB)\n// reduce in JS via reduceAggregate. Both paths must produce identical group\n// keys and ordering so callers get the same result regardless of backend.\n\nconst pad2 = (n: number): string => String(n).padStart(2, \"0\");\n\nconst aggregateColumns =\n \"COUNT(*) AS requests, \" +\n \"COALESCE(SUM(prompt_tokens), 0) AS promptTokens, \" +\n \"COALESCE(SUM(completion_tokens), 0) AS completionTokens, \" +\n \"COALESCE(SUM(total_tokens), 0) AS totalTokens, \" +\n \"COALESCE(SUM(cost), 0) AS cost, \" +\n \"COALESCE(SUM(sats_cost), 0) AS satsCost, \" +\n \"COALESCE(SUM(base_msats), 0) AS baseMsats, \" +\n \"COALESCE(SUM(input_msats), 0) AS inputMsats, \" +\n \"COALESCE(SUM(output_msats), 0) AS outputMsats, \" +\n \"COALESCE(SUM(total_msats), 0) AS totalMsats, \" +\n \"COALESCE(SUM(total_usd), 0) AS totalUsd, \" +\n \"COALESCE(SUM(cache_read_input_tokens), 0) AS cacheReadInputTokens, \" +\n \"COALESCE(SUM(cache_creation_input_tokens), 0) AS cacheCreationInputTokens, \" +\n \"COALESCE(SUM(cache_read_msats), 0) AS cacheReadMsats, \" +\n \"COALESCE(SUM(cache_creation_msats), 0) AS cacheCreationMsats\";\n\n/**\n * SQL expression producing the group key. `day`/`hour` shift the (millisecond)\n * timestamp by the timezone offset before bucketing so buckets land on the\n * caller's local-day/hour boundaries rather than UTC.\n */\nconst sqlGroupExpr = (\n groupBy: UsageGroupBy,\n): { expr: string; usesTz: boolean } => {\n switch (groupBy) {\n case \"modelId\":\n return { expr: \"model_id\", usesTz: false };\n case \"baseUrl\":\n return { expr: \"base_url\", usesTz: false };\n case \"client\":\n return { expr: \"client\", usesTz: false };\n case \"sessionId\":\n return { expr: \"session_id\", usesTz: false };\n case \"provider\":\n return { expr: \"provider\", usesTz: false };\n case \"day\":\n return {\n expr: \"strftime('%Y-%m-%d', (timestamp - ? * 60000) / 1000, 'unixepoch')\",\n usesTz: true,\n };\n case \"hour\":\n return {\n expr: \"strftime('%H', (timestamp - ? * 60000) / 1000, 'unixepoch')\",\n usesTz: true,\n };\n }\n};\n\n/**\n * Build an aggregation query from a driver-supplied WHERE clause. When\n * `groupBy` is omitted a single grand-total row is returned. Timezone params\n * (day/hour grouping) bind before the WHERE params because the group\n * expression appears earlier in the statement (the SELECT list).\n */\nexport const buildAggregateSql = (\n tableName: string,\n where: { sql: string; params: unknown[] },\n options: AggregateUsageOptions = {},\n): { sql: string; params: unknown[] } => {\n if (!options.groupBy) {\n return {\n sql: `SELECT NULL AS grp, ${aggregateColumns} FROM ${tableName} ${where.sql}`,\n params: where.params,\n };\n }\n\n const { expr, usesTz } = sqlGroupExpr(options.groupBy);\n const tzParams = usesTz ? [options.tzOffsetMinutes ?? 0] : [];\n const orderBy =\n options.groupBy === \"day\" || options.groupBy === \"hour\"\n ? \"ORDER BY grp ASC\"\n : \"ORDER BY satsCost DESC\";\n\n return {\n sql: `SELECT ${expr} AS grp, ${aggregateColumns} FROM ${tableName} ${where.sql} GROUP BY grp ${orderBy}`,\n params: [...tzParams, ...where.params],\n };\n};\n\n/** Map a raw SQL aggregate row into a `UsageAggregateRow`. */\nexport const mapAggregateRow = (row: Record<string, unknown>): UsageAggregateRow => ({\n group: row.grp == null ? null : String(row.grp),\n requests: Number(row.requests ?? 0),\n promptTokens: Number(row.promptTokens ?? 0),\n completionTokens: Number(row.completionTokens ?? 0),\n totalTokens: Number(row.totalTokens ?? 0),\n cost: Number(row.cost ?? 0),\n satsCost: Number(row.satsCost ?? 0),\n baseMsats: Number(row.baseMsats ?? 0),\n inputMsats: Number(row.inputMsats ?? 0),\n outputMsats: Number(row.outputMsats ?? 0),\n totalMsats: Number(row.totalMsats ?? 0),\n totalUsd: Number(row.totalUsd ?? 0),\n cacheReadInputTokens: Number(row.cacheReadInputTokens ?? 0),\n cacheCreationInputTokens: Number(row.cacheCreationInputTokens ?? 0),\n cacheReadMsats: Number(row.cacheReadMsats ?? 0),\n cacheCreationMsats: Number(row.cacheCreationMsats ?? 0),\n});\n\nconst jsGroupKey = (\n entry: UsageTrackingEntry,\n groupBy: UsageGroupBy,\n tzOffsetMinutes: number,\n): string | null => {\n switch (groupBy) {\n case \"modelId\":\n return entry.modelId ?? null;\n case \"baseUrl\":\n return entry.baseUrl ?? null;\n case \"client\":\n return entry.client ?? null;\n case \"sessionId\":\n return entry.sessionId ?? null;\n case \"provider\":\n return entry.provider ?? null;\n case \"day\": {\n const d = new Date(entry.timestamp - tzOffsetMinutes * 60000);\n return `${d.getUTCFullYear()}-${pad2(d.getUTCMonth() + 1)}-${pad2(d.getUTCDate())}`;\n }\n case \"hour\": {\n const d = new Date(entry.timestamp - tzOffsetMinutes * 60000);\n return pad2(d.getUTCHours());\n }\n }\n};\n\n/**\n * Reduce already-filtered entries into aggregate rows, mirroring the SQL\n * drivers' grouping and ordering. With no `groupBy`, returns a single\n * grand-total row (even for an empty input).\n */\nexport const reduceAggregate = (\n entries: UsageTrackingEntry[],\n options: AggregateUsageOptions = {},\n): UsageAggregateRow[] => {\n const emptyRow = (group: string | null): UsageAggregateRow => ({\n group,\n requests: 0,\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n cost: 0,\n satsCost: 0,\n baseMsats: 0,\n inputMsats: 0,\n outputMsats: 0,\n totalMsats: 0,\n totalUsd: 0,\n cacheReadInputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadMsats: 0,\n cacheCreationMsats: 0,\n });\n\n const accumulate = (row: UsageAggregateRow, entry: UsageTrackingEntry): void => {\n row.requests += 1;\n row.promptTokens += entry.promptTokens;\n row.completionTokens += entry.completionTokens;\n row.totalTokens += entry.totalTokens;\n row.cost += entry.cost;\n row.satsCost += entry.satsCost;\n row.baseMsats += entry.baseMsats ?? 0;\n row.inputMsats += entry.inputMsats ?? 0;\n row.outputMsats += entry.outputMsats ?? 0;\n row.totalMsats += entry.totalMsats ?? 0;\n row.totalUsd += entry.totalUsd ?? 0;\n row.cacheReadInputTokens += entry.cacheReadInputTokens ?? 0;\n row.cacheCreationInputTokens += entry.cacheCreationInputTokens ?? 0;\n row.cacheReadMsats += entry.cacheReadMsats ?? 0;\n row.cacheCreationMsats += entry.cacheCreationMsats ?? 0;\n };\n\n if (!options.groupBy) {\n const total = emptyRow(null);\n for (const entry of entries) accumulate(total, entry);\n return [total];\n }\n\n const tz = options.tzOffsetMinutes ?? 0;\n const groups = new Map<string | null, UsageAggregateRow>();\n for (const entry of entries) {\n const key = jsGroupKey(entry, options.groupBy, tz);\n let row = groups.get(key);\n if (!row) {\n row = emptyRow(key);\n groups.set(key, row);\n }\n accumulate(row, entry);\n }\n\n const rows = [...groups.values()];\n if (options.groupBy === \"day\" || options.groupBy === \"hour\") {\n rows.sort((a, b) => (a.group ?? \"\").localeCompare(b.group ?? \"\"));\n } else {\n rows.sort((a, b) => b.satsCost - a.satsCost);\n }\n return rows;\n};\n","import { SDK_STORAGE_KEYS } from \"../keys\";\nimport type { StorageDriver } from \"../types\";\nimport type {\n AggregateUsageOptions,\n ListUsageTrackingOptions,\n UsageAggregateRow,\n UsageTrackingDriver,\n} from \"./interfaces\";\nimport type { UsageTrackingEntry } from \"./types\";\nimport { reduceAggregate } from \"./aggregate\";\n\nexport interface IndexedDBUsageTrackingDriverOptions {\n dbName?: string;\n storeName?: string;\n legacyStorageDriver?: StorageDriver;\n}\n\nconst DEFAULT_DB_NAME = \"routstr-sdk\";\nconst DEFAULT_STORE_NAME = \"usage_tracking\";\nconst MIGRATION_MARKER_KEY = \"usage_tracking_migration_v1\";\n\nconst isBrowser = typeof indexedDB !== \"undefined\";\n\nconst normalizeBaseUrl = (baseUrl: string): string =>\n baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n\nconst openDatabase = (\n dbName: string,\n storeName: string\n): Promise<IDBDatabase> => {\n if (!isBrowser) {\n return Promise.reject(new Error(\"IndexedDB is not available\"));\n }\n\n return new Promise((resolve, reject) => {\n // Version 3 — adds a `provider` index on the usage_tracking store.\n const request = indexedDB.open(dbName, 3);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n const tx = request.transaction;\n // Create our own store\n if (!db.objectStoreNames.contains(storeName)) {\n const store = db.createObjectStore(storeName, { keyPath: \"id\" });\n store.createIndex(\"timestamp\", \"timestamp\", { unique: false });\n store.createIndex(\"modelId\", \"modelId\", { unique: false });\n store.createIndex(\"baseUrl\", \"baseUrl\", { unique: false });\n store.createIndex(\"sessionId\", \"sessionId\", { unique: false });\n store.createIndex(\"client\", \"client\", { unique: false });\n store.createIndex(\"provider\", \"provider\", { unique: false });\n } else if (tx) {\n // Existing store from an older version — add the new index in place.\n const store = tx.objectStore(storeName);\n if (!store.indexNames.contains(\"provider\")) {\n store.createIndex(\"provider\", \"provider\", { unique: false });\n }\n }\n // Also create sdk_storage if it doesn't exist (cross-driver init)\n if (storeName !== \"sdk_storage\" && !db.objectStoreNames.contains(\"sdk_storage\")) {\n db.createObjectStore(\"sdk_storage\");\n }\n };\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n request.onblocked = () => {\n console.warn(\n `[usageTracking IndexedDB] open blocked for \"${dbName}\" — close other tabs using this DB`\n );\n reject(new Error(`IndexedDB \"${dbName}\" blocked by another connection`));\n };\n });\n};\n\nconst matchesFilters = (\n entry: UsageTrackingEntry,\n options: Omit<ListUsageTrackingOptions, \"limit\"> = {}\n): boolean => {\n if (typeof options.before === \"number\" && entry.timestamp >= options.before) {\n return false;\n }\n if (typeof options.after === \"number\" && entry.timestamp <= options.after) {\n return false;\n }\n if (options.modelId && entry.modelId !== options.modelId) {\n return false;\n }\n if (options.baseUrl && normalizeBaseUrl(entry.baseUrl) !== normalizeBaseUrl(options.baseUrl)) {\n return false;\n }\n if (options.sessionId && entry.sessionId !== options.sessionId) {\n return false;\n }\n if (options.client && entry.client !== options.client) {\n return false;\n }\n if (\n options.clients &&\n options.clients.length > 0 &&\n (entry.client == null || !options.clients.includes(entry.client))\n ) {\n return false;\n }\n if (options.provider && entry.provider !== options.provider) {\n return false;\n }\n return true;\n};\n\nexport const createIndexedDBUsageTrackingDriver = (\n options: IndexedDBUsageTrackingDriverOptions = {}\n): UsageTrackingDriver => {\n const dbName = options.dbName || DEFAULT_DB_NAME;\n const storeName = options.storeName || DEFAULT_STORE_NAME;\n const legacyStorageDriver = options.legacyStorageDriver;\n\n let dbPromise: Promise<IDBDatabase> | null = null;\n let migrationPromise: Promise<void> | null = null;\n\n const getDb = (): Promise<IDBDatabase> => {\n if (!dbPromise) {\n dbPromise = openDatabase(dbName, storeName);\n }\n return dbPromise;\n };\n\n const putMany = async (entries: UsageTrackingEntry[]): Promise<void> => {\n if (entries.length === 0) return;\n const db = await getDb();\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(storeName, \"readwrite\");\n const store = tx.objectStore(storeName);\n for (const entry of entries) {\n store.put({ ...entry, baseUrl: normalizeBaseUrl(entry.baseUrl) });\n }\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n };\n\n const ensureMigrated = async (): Promise<void> => {\n if (!legacyStorageDriver) return;\n if (!migrationPromise) {\n migrationPromise = (async () => {\n const migrated = await legacyStorageDriver.getItem<boolean>(\n MIGRATION_MARKER_KEY,\n false\n );\n if (migrated) return;\n\n const legacyEntries = await legacyStorageDriver.getItem<UsageTrackingEntry[]>(\n SDK_STORAGE_KEYS.USAGE_TRACKING,\n []\n );\n\n if (legacyEntries.length > 0) {\n await putMany(legacyEntries);\n await legacyStorageDriver.removeItem(SDK_STORAGE_KEYS.USAGE_TRACKING);\n }\n\n await legacyStorageDriver.setItem(MIGRATION_MARKER_KEY, true);\n })();\n }\n await migrationPromise;\n };\n\n return {\n async migrate(): Promise<void> {\n await ensureMigrated();\n },\n\n async append(entry: UsageTrackingEntry): Promise<void> {\n await ensureMigrated();\n await putMany([entry]);\n },\n\n async appendMany(entries: UsageTrackingEntry[]): Promise<void> {\n await ensureMigrated();\n await putMany(entries);\n },\n\n async list(options: ListUsageTrackingOptions = {}): Promise<UsageTrackingEntry[]> {\n await ensureMigrated();\n const db = await getDb();\n return new Promise<UsageTrackingEntry[]>((resolve, reject) => {\n const tx = db.transaction(storeName, \"readonly\");\n const store = tx.objectStore(storeName);\n const index = store.index(\"timestamp\");\n const direction: IDBCursorDirection = \"prev\";\n const request = index.openCursor(null, direction);\n const results: UsageTrackingEntry[] = [];\n const limit = options.limit;\n\n request.onsuccess = () => {\n const cursor = request.result;\n if (!cursor) {\n resolve(results);\n return;\n }\n\n const value = cursor.value as UsageTrackingEntry;\n if (matchesFilters(value, options)) {\n results.push(value);\n if (typeof limit === \"number\" && results.length >= limit) {\n resolve(results);\n return;\n }\n }\n cursor.continue();\n };\n\n request.onerror = () => reject(request.error);\n });\n },\n\n async count(options: Omit<ListUsageTrackingOptions, \"limit\"> = {}): Promise<number> {\n const results = await this.list(options);\n return results.length;\n },\n\n async aggregate(options: AggregateUsageOptions = {}): Promise<UsageAggregateRow[]> {\n const entries = await this.list(options);\n return reduceAggregate(entries, options);\n },\n\n async deleteOlderThan(timestamp: number): Promise<number> {\n await ensureMigrated();\n const db = await getDb();\n return new Promise<number>((resolve, reject) => {\n const tx = db.transaction(storeName, \"readwrite\");\n const store = tx.objectStore(storeName);\n const index = store.index(\"timestamp\");\n const range = IDBKeyRange.upperBound(timestamp, true);\n const request = index.openCursor(range);\n let deleted = 0;\n\n request.onsuccess = () => {\n const cursor = request.result;\n if (!cursor) {\n resolve(deleted);\n return;\n }\n deleted += 1;\n cursor.delete();\n cursor.continue();\n };\n\n request.onerror = () => reject(request.error);\n });\n },\n\n async clear(): Promise<void> {\n await ensureMigrated();\n const db = await getDb();\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(storeName, \"readwrite\");\n tx.objectStore(storeName).clear();\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n },\n };\n};\n","import type {\n AggregateUsageOptions,\n ListUsageTrackingOptions,\n UsageAggregateRow,\n UsageTrackingDriver,\n} from \"./interfaces\";\nimport type { UsageTrackingEntry } from \"./types\";\nimport { reduceAggregate } from \"./aggregate\";\n\nconst normalizeBaseUrl = (baseUrl: string): string =>\n baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n\nconst matchesFilters = (\n entry: UsageTrackingEntry,\n options: Omit<ListUsageTrackingOptions, \"limit\"> = {}\n): boolean => {\n if (typeof options.before === \"number\" && entry.timestamp >= options.before) {\n return false;\n }\n if (typeof options.after === \"number\" && entry.timestamp <= options.after) {\n return false;\n }\n if (options.modelId && entry.modelId !== options.modelId) {\n return false;\n }\n if (options.baseUrl && normalizeBaseUrl(entry.baseUrl) !== normalizeBaseUrl(options.baseUrl)) {\n return false;\n }\n if (options.sessionId && entry.sessionId !== options.sessionId) {\n return false;\n }\n if (options.client && entry.client !== options.client) {\n return false;\n }\n if (\n options.clients &&\n options.clients.length > 0 &&\n (entry.client == null || !options.clients.includes(entry.client))\n ) {\n return false;\n }\n if (options.provider && entry.provider !== options.provider) {\n return false;\n }\n return true;\n};\n\nexport const createMemoryUsageTrackingDriver = (\n seed: UsageTrackingEntry[] = []\n): UsageTrackingDriver => {\n const store = new Map<string, UsageTrackingEntry>();\n\n for (const entry of seed) {\n store.set(entry.id, { ...entry, baseUrl: normalizeBaseUrl(entry.baseUrl) });\n }\n\n return {\n async migrate(): Promise<void> {\n return;\n },\n\n async append(entry: UsageTrackingEntry): Promise<void> {\n store.set(entry.id, { ...entry, baseUrl: normalizeBaseUrl(entry.baseUrl) });\n },\n\n async appendMany(entries: UsageTrackingEntry[]): Promise<void> {\n for (const entry of entries) {\n store.set(entry.id, { ...entry, baseUrl: normalizeBaseUrl(entry.baseUrl) });\n }\n },\n\n async list(options: ListUsageTrackingOptions = {}): Promise<UsageTrackingEntry[]> {\n const entries = [...store.values()]\n .filter((entry) => matchesFilters(entry, options))\n .sort((a, b) => b.timestamp - a.timestamp);\n if (typeof options.limit === \"number\") {\n return entries.slice(0, options.limit);\n }\n return entries;\n },\n\n async count(options: Omit<ListUsageTrackingOptions, \"limit\"> = {}): Promise<number> {\n return (await this.list(options)).length;\n },\n\n async aggregate(options: AggregateUsageOptions = {}): Promise<UsageAggregateRow[]> {\n const entries = [...store.values()].filter((entry) => matchesFilters(entry, options));\n return reduceAggregate(entries, options);\n },\n\n async deleteOlderThan(timestamp: number): Promise<number> {\n let deleted = 0;\n for (const [id, entry] of store.entries()) {\n if (entry.timestamp < timestamp) {\n store.delete(id);\n deleted += 1;\n }\n }\n return deleted;\n },\n\n async clear(): Promise<void> {\n store.clear();\n },\n };\n};\n","import { createStore, type StoreApi } from \"zustand/vanilla\";\nimport type { DiscoveryAdapter } from \"../discovery/interfaces\";\nimport type { StorageAdapter, ProviderRegistry } from \"../wallet/interfaces\";\nimport type { ProviderInfo, Model, SdkLogger } from \"../core\";\nimport { consoleLogger } from \"../core/types\";\nimport { SDK_STORAGE_KEYS } from \"./keys\";\nimport type { StorageDriver, SdkStorageState } from \"./types\";\n\nconst normalizeBaseUrl = (baseUrl: string): string =>\n baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n\nexport interface SdkStoreOptions {\n driver: StorageDriver;\n}\n\nexport interface SdkStorageStore extends SdkStorageState {\n setModelsFromAllProviders: (value: Record<string, Model[]>) => void;\n setLastUsedModel: (value: string | null) => void;\n setBaseUrlsList: (value: string[]) => void;\n setBaseUrlsLastUpdate: (value: number | null) => void;\n setDisabledProviders: (value: string[]) => void;\n setMintsFromAllProviders: (value: Record<string, string[]>) => void;\n setInfoFromAllProviders: (value: Record<string, ProviderInfo>) => void;\n setLastModelsUpdate: (value: Record<string, number>) => void;\n setApiKeys: (\n value:\n | Array<{\n baseUrl: string;\n key: string;\n balance?: number;\n lastUsed?: number | null;\n }>\n | ((current: SdkStorageStore[\"apiKeys\"]) => SdkStorageStore[\"apiKeys\"])\n ) => void;\n setChildKeys: (\n value: Array<{\n parentBaseUrl: string;\n childKey: string;\n balance?: number;\n balanceLimit?: number;\n validityDate?: number;\n createdAt?: number;\n }>\n ) => void;\n setXcashuTokens: (\n value: Record<\n string,\n Array<{\n baseUrl: string;\n token: string;\n createdAt?: number;\n tryCount?: number;\n }>\n >\n ) => void;\n updateXcashuTokenTryCount: (token: string, tryCount: number) => void;\n setRoutstr21Models: (value: string[]) => void;\n setRoutstr21ModelsLastUpdate: (value: number | null) => void;\n setCachedReceiveTokens: (\n value: Array<{\n token: string;\n amount: number;\n unit: \"sat\" | \"msat\";\n createdAt?: number;\n }>\n ) => void;\n setClientIds: (\n value:\n | Array<{\n clientId: string;\n name: string;\n apiKey: string;\n createdAt?: number;\n lastUsed?: number | null;\n }>\n | ((\n current: SdkStorageStore[\"clientIds\"]\n ) => SdkStorageStore[\"clientIds\"])\n ) => void;\n // ========== Failure Tracking ==========\n setFailedProviders: (value: string[]) => void;\n addFailedProvider: (baseUrl: string) => void;\n removeFailedProvider: (baseUrl: string) => void;\n setLastFailed: (value: Record<string, number>) => void;\n setLastFailedTimestamp: (baseUrl: string, timestamp: number) => void;\n setProvidersOnCooldown: (\n value: Array<{ baseUrl: string; timestamp: number }>\n ) => void;\n addProviderOnCooldown: (baseUrl: string, timestamp: number) => void;\n removeProviderFromCooldown: (baseUrl: string) => void;\n clearProvidersOnCooldown: () => void;\n}\n\n/** Store type returned after async initialization */\nexport type SdkStore = StoreApi<SdkStorageStore>;\n\nconst createEmptyStore = (driver: StorageDriver): SdkStore =>\n createStore<SdkStorageStore>((set, get) => ({\n modelsFromAllProviders: {},\n lastUsedModel: null,\n baseUrlsList: [],\n lastBaseUrlsUpdate: null,\n disabledProviders: [],\n mintsFromAllProviders: {},\n infoFromAllProviders: {},\n lastModelsUpdate: {},\n apiKeys: [],\n childKeys: [],\n xcashuTokens: {},\n routstr21Models: [],\n lastRoutstr21ModelsUpdate: null,\n cachedReceiveTokens: [],\n clientIds: [],\n failedProviders: [],\n lastFailed: {},\n providersOnCooldown: [],\n setModelsFromAllProviders: (value) => {\n const normalized: Record<string, Model[]> = {};\n for (const [baseUrl, models] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = models;\n }\n void driver.setItem(\n SDK_STORAGE_KEYS.MODELS_FROM_ALL_PROVIDERS,\n normalized\n );\n set({ modelsFromAllProviders: normalized });\n },\n setLastUsedModel: (value) => {\n void driver.setItem(SDK_STORAGE_KEYS.LAST_USED_MODEL, value);\n set({ lastUsedModel: value });\n },\n setBaseUrlsList: (value) => {\n const normalized = value.map((url) => normalizeBaseUrl(url));\n void driver.setItem(SDK_STORAGE_KEYS.BASE_URLS_LIST, normalized);\n set({ baseUrlsList: normalized });\n },\n setBaseUrlsLastUpdate: (value) => {\n void driver.setItem(SDK_STORAGE_KEYS.LAST_BASE_URLS_UPDATE, value);\n set({ lastBaseUrlsUpdate: value });\n },\n setDisabledProviders: (value) => {\n const normalized = value.map((url) => normalizeBaseUrl(url));\n void driver.setItem(SDK_STORAGE_KEYS.DISABLED_PROVIDERS, normalized);\n set({ disabledProviders: normalized });\n },\n setMintsFromAllProviders: (value) => {\n const normalized: Record<string, string[]> = {};\n for (const [baseUrl, mints] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = mints.map((mint) =>\n mint.endsWith(\"/\") ? mint.slice(0, -1) : mint\n );\n }\n void driver.setItem(\n SDK_STORAGE_KEYS.MINTS_FROM_ALL_PROVIDERS,\n normalized\n );\n set({ mintsFromAllProviders: normalized });\n },\n setInfoFromAllProviders: (value) => {\n const normalized: Record<string, ProviderInfo> = {};\n for (const [baseUrl, info] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = info;\n }\n void driver.setItem(SDK_STORAGE_KEYS.INFO_FROM_ALL_PROVIDERS, normalized);\n set({ infoFromAllProviders: normalized });\n },\n setLastModelsUpdate: (value) => {\n const normalized: Record<string, number> = {};\n for (const [baseUrl, timestamp] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = timestamp;\n }\n void driver.setItem(SDK_STORAGE_KEYS.LAST_MODELS_UPDATE, normalized);\n set({ lastModelsUpdate: normalized });\n },\n setApiKeys: (value) => {\n set((state) => {\n const updates =\n typeof value === \"function\" ? value(state.apiKeys) : value;\n const normalized = updates.map((entry) => ({\n ...entry,\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n balance: entry.balance ?? 0,\n lastUsed: entry.lastUsed ?? null,\n }));\n void driver.setItem(SDK_STORAGE_KEYS.API_KEYS, normalized);\n return { apiKeys: normalized };\n });\n },\n setChildKeys: (\n value:\n | Array<{\n parentBaseUrl: string;\n childKey: string;\n balance?: number;\n balanceLimit?: number;\n validityDate?: number;\n createdAt?: number;\n }>\n | ((\n current: SdkStorageStore[\"childKeys\"]\n ) => SdkStorageStore[\"childKeys\"])\n ) => {\n set((state) => {\n const updates =\n typeof value === \"function\" ? value(state.childKeys) : value;\n const normalized = updates.map((entry) => ({\n parentBaseUrl: normalizeBaseUrl(entry.parentBaseUrl),\n childKey: entry.childKey,\n balance: entry.balance ?? 0,\n balanceLimit: entry.balanceLimit,\n validityDate: entry.validityDate,\n createdAt: entry.createdAt ?? Date.now(),\n }));\n void driver.setItem(SDK_STORAGE_KEYS.CHILD_KEYS, normalized);\n return { childKeys: normalized };\n });\n },\n setXcashuTokens: (value) => {\n const normalized: Record<\n string,\n Array<{\n baseUrl: string;\n token: string;\n createdAt: number;\n tryCount: number;\n }>\n > = {};\n for (const [baseUrl, tokens] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = tokens.map((entry) => ({\n ...entry,\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n createdAt: entry.createdAt ?? Date.now(),\n tryCount: entry.tryCount ?? 0,\n }));\n }\n void driver.setItem(SDK_STORAGE_KEYS.XCASHU_TOKENS, normalized);\n set({ xcashuTokens: normalized });\n },\n updateXcashuTokenTryCount: (token, tryCount) => {\n const currentTokens = get().xcashuTokens;\n const updatedTokens: Record<\n string,\n Array<{\n baseUrl: string;\n token: string;\n createdAt: number;\n tryCount: number;\n }>\n > = {};\n\n for (const [baseUrl, tokens] of Object.entries(currentTokens)) {\n updatedTokens[baseUrl] = tokens.map((entry) =>\n entry.token === token ? { ...entry, tryCount } : entry\n );\n }\n\n void driver.setItem(SDK_STORAGE_KEYS.XCASHU_TOKENS, updatedTokens);\n set({ xcashuTokens: updatedTokens });\n },\n setRoutstr21Models: (value) => {\n void driver.setItem(SDK_STORAGE_KEYS.ROUTSTR21_MODELS, value);\n set({ routstr21Models: value });\n },\n setRoutstr21ModelsLastUpdate: (value) => {\n void driver.setItem(SDK_STORAGE_KEYS.LAST_ROUTSTR21_MODELS_UPDATE, value);\n set({ lastRoutstr21ModelsUpdate: value });\n },\n setCachedReceiveTokens: (value) => {\n const normalized = value.map((entry) => ({\n token: entry.token,\n amount: entry.amount,\n unit: entry.unit || \"sat\",\n createdAt: entry.createdAt ?? Date.now(),\n }));\n void driver.setItem(SDK_STORAGE_KEYS.CACHED_RECEIVE_TOKENS, normalized);\n set({ cachedReceiveTokens: normalized });\n },\n setClientIds: (value) => {\n set((state) => {\n const updates =\n typeof value === \"function\" ? value(state.clientIds) : value;\n const normalized = updates.map((entry) => ({\n ...entry,\n createdAt: entry.createdAt ?? Date.now(),\n lastUsed: entry.lastUsed ?? null,\n }));\n void driver.setItem(SDK_STORAGE_KEYS.CLIENT_IDS, normalized);\n return { clientIds: normalized };\n });\n },\n // ========== Failure Tracking ==========\n setFailedProviders: (value) => {\n const normalized = value.map((url) => normalizeBaseUrl(url));\n void driver.setItem(SDK_STORAGE_KEYS.FAILED_PROVIDERS, normalized);\n set({ failedProviders: normalized });\n },\n addFailedProvider: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const current = get().failedProviders;\n if (!current.includes(normalized)) {\n const updated = [...current, normalized];\n void driver.setItem(SDK_STORAGE_KEYS.FAILED_PROVIDERS, updated);\n set({ failedProviders: updated });\n }\n },\n removeFailedProvider: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const current = get().failedProviders;\n const updated = current.filter((url) => url !== normalized);\n void driver.setItem(SDK_STORAGE_KEYS.FAILED_PROVIDERS, updated);\n set({ failedProviders: updated });\n },\n setLastFailed: (value) => {\n const normalized: Record<string, number> = {};\n for (const [baseUrl, timestamp] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = timestamp;\n }\n void driver.setItem(SDK_STORAGE_KEYS.LAST_FAILED, normalized);\n set({ lastFailed: normalized });\n },\n setLastFailedTimestamp: (baseUrl, timestamp) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const current = get().lastFailed;\n const updated = { ...current, [normalized]: timestamp };\n void driver.setItem(SDK_STORAGE_KEYS.LAST_FAILED, updated);\n set({ lastFailed: updated });\n },\n setProvidersOnCooldown: (value) => {\n const normalized = value.map((entry) => ({\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n timestamp: entry.timestamp,\n }));\n void driver.setItem(SDK_STORAGE_KEYS.PROVIDERS_ON_COOLDOWN, normalized);\n set({ providersOnCooldown: normalized });\n },\n addProviderOnCooldown: (baseUrl, timestamp) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const current = get().providersOnCooldown;\n if (!current.some((entry) => entry.baseUrl === normalized)) {\n const updated = [...current, { baseUrl: normalized, timestamp }];\n void driver.setItem(SDK_STORAGE_KEYS.PROVIDERS_ON_COOLDOWN, updated);\n set({ providersOnCooldown: updated });\n }\n },\n removeProviderFromCooldown: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const current = get().providersOnCooldown;\n const updated = current.filter((entry) => entry.baseUrl !== normalized);\n void driver.setItem(SDK_STORAGE_KEYS.PROVIDERS_ON_COOLDOWN, updated);\n set({ providersOnCooldown: updated });\n },\n clearProvidersOnCooldown: () => {\n void driver.setItem(SDK_STORAGE_KEYS.PROVIDERS_ON_COOLDOWN, []);\n set({ providersOnCooldown: [] });\n },\n }));\n\nconst hydrateStoreFromDriver = async (\n store: SdkStore,\n driver: StorageDriver\n): Promise<void> => {\n const [\n rawModels,\n lastUsedModel,\n rawBaseUrls,\n lastBaseUrlsUpdate,\n rawDisabledProviders,\n rawMints,\n rawInfo,\n rawLastModelsUpdate,\n rawApiKeys,\n rawChildKeys,\n rawXcashuTokens,\n rawRoutstr21Models,\n rawLastRoutstr21ModelsUpdate,\n rawCachedReceiveTokens,\n rawClientIds,\n rawFailedProviders,\n rawLastFailed,\n rawProvidersOnCooldown,\n ] = await Promise.all([\n driver.getItem<Record<string, Model[]>>(\n SDK_STORAGE_KEYS.MODELS_FROM_ALL_PROVIDERS,\n {}\n ),\n driver.getItem<string | null>(SDK_STORAGE_KEYS.LAST_USED_MODEL, null),\n driver.getItem<string[]>(SDK_STORAGE_KEYS.BASE_URLS_LIST, []),\n driver.getItem<number | null>(SDK_STORAGE_KEYS.LAST_BASE_URLS_UPDATE, null),\n driver.getItem<string[]>(SDK_STORAGE_KEYS.DISABLED_PROVIDERS, []),\n driver.getItem<Record<string, string[]>>(\n SDK_STORAGE_KEYS.MINTS_FROM_ALL_PROVIDERS,\n {}\n ),\n driver.getItem<Record<string, ProviderInfo>>(\n SDK_STORAGE_KEYS.INFO_FROM_ALL_PROVIDERS,\n {}\n ),\n driver.getItem<Record<string, number>>(\n SDK_STORAGE_KEYS.LAST_MODELS_UPDATE,\n {}\n ),\n driver.getItem<\n Array<{\n baseUrl: string;\n key: string;\n balance?: number;\n lastUsed?: number | null;\n }>\n >(SDK_STORAGE_KEYS.API_KEYS, []),\n driver.getItem<\n Array<{\n parentBaseUrl: string;\n childKey: string;\n balance?: number;\n balanceLimit?: number;\n validityDate?: number;\n createdAt?: number;\n }>\n >(SDK_STORAGE_KEYS.CHILD_KEYS, []),\n driver.getItem<\n Record<\n string,\n Array<{\n baseUrl: string;\n token: string;\n createdAt?: number;\n tryCount?: number;\n }>\n >\n >(SDK_STORAGE_KEYS.XCASHU_TOKENS, {}),\n driver.getItem<string[]>(SDK_STORAGE_KEYS.ROUTSTR21_MODELS, []),\n driver.getItem<number | null>(\n SDK_STORAGE_KEYS.LAST_ROUTSTR21_MODELS_UPDATE,\n null\n ),\n driver.getItem<\n Array<{\n token: string;\n amount: number;\n unit: \"sat\" | \"msat\";\n createdAt?: number;\n }>\n >(SDK_STORAGE_KEYS.CACHED_RECEIVE_TOKENS, []),\n driver.getItem<\n Array<{\n clientId: string;\n name: string;\n apiKey: string;\n createdAt?: number;\n lastUsed?: number | null;\n }>\n >(SDK_STORAGE_KEYS.CLIENT_IDS, []),\n driver.getItem<string[]>(SDK_STORAGE_KEYS.FAILED_PROVIDERS, []),\n driver.getItem<Record<string, number>>(SDK_STORAGE_KEYS.LAST_FAILED, {}),\n driver.getItem<Array<{ baseUrl: string; timestamp: number }>>(\n SDK_STORAGE_KEYS.PROVIDERS_ON_COOLDOWN,\n []\n ),\n ]);\n\n const modelsFromAllProviders = Object.fromEntries(\n Object.entries(rawModels).map(([baseUrl, models]) => [\n normalizeBaseUrl(baseUrl),\n models,\n ])\n );\n\n const baseUrlsList = rawBaseUrls.map((url) => normalizeBaseUrl(url));\n\n const disabledProviders = rawDisabledProviders.map((url) =>\n normalizeBaseUrl(url)\n );\n\n const mintsFromAllProviders = Object.fromEntries(\n Object.entries(rawMints).map(([baseUrl, mints]) => [\n normalizeBaseUrl(baseUrl),\n mints.map((mint) => (mint.endsWith(\"/\") ? mint.slice(0, -1) : mint)),\n ])\n );\n\n const infoFromAllProviders = Object.fromEntries(\n Object.entries(rawInfo).map(([baseUrl, info]) => [\n normalizeBaseUrl(baseUrl),\n info,\n ])\n );\n\n const lastModelsUpdate = Object.fromEntries(\n Object.entries(rawLastModelsUpdate).map(([baseUrl, timestamp]) => [\n normalizeBaseUrl(baseUrl),\n timestamp,\n ])\n );\n\n const apiKeys = rawApiKeys.map((entry) => ({\n ...entry,\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n balance: entry.balance ?? 0,\n lastUsed: entry.lastUsed ?? null,\n }));\n\n const childKeys = rawChildKeys.map((entry) => ({\n parentBaseUrl: normalizeBaseUrl(entry.parentBaseUrl),\n childKey: entry.childKey,\n balance: entry.balance ?? 0,\n balanceLimit: entry.balanceLimit,\n validityDate: entry.validityDate,\n createdAt: entry.createdAt ?? Date.now(),\n }));\n\n const xcashuTokens = Object.fromEntries(\n Object.entries(rawXcashuTokens).map(([baseUrl, tokens]) => [\n normalizeBaseUrl(baseUrl),\n tokens.map((entry) => ({\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n token: entry.token,\n createdAt: entry.createdAt ?? Date.now(),\n tryCount: entry.tryCount ?? 0,\n })),\n ])\n );\n\n const routstr21Models = rawRoutstr21Models;\n const lastRoutstr21ModelsUpdate = rawLastRoutstr21ModelsUpdate;\n\n const cachedReceiveTokens = rawCachedReceiveTokens?.map((entry) => ({\n token: entry.token,\n amount: entry.amount,\n unit: entry.unit || \"sat\",\n createdAt: entry.createdAt ?? Date.now(),\n }));\n\n const clientIds = rawClientIds.map((entry) => ({\n ...entry,\n createdAt: entry.createdAt ?? Date.now(),\n lastUsed: entry.lastUsed ?? null,\n }));\n\n const failedProviders = rawFailedProviders.map((url) =>\n normalizeBaseUrl(url)\n );\n const lastFailed = Object.fromEntries(\n Object.entries(rawLastFailed).map(([baseUrl, timestamp]) => [\n normalizeBaseUrl(baseUrl),\n timestamp,\n ])\n );\n const providersOnCooldown = rawProvidersOnCooldown.map((entry) => ({\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n timestamp: entry.timestamp,\n }));\n\n store.setState({\n modelsFromAllProviders,\n lastUsedModel,\n baseUrlsList,\n lastBaseUrlsUpdate,\n disabledProviders,\n mintsFromAllProviders,\n infoFromAllProviders,\n lastModelsUpdate,\n apiKeys,\n childKeys,\n xcashuTokens,\n routstr21Models,\n lastRoutstr21ModelsUpdate,\n cachedReceiveTokens,\n clientIds,\n failedProviders,\n lastFailed,\n providersOnCooldown,\n });\n};\n\nexport const createSdkStore = ({\n driver,\n}: SdkStoreOptions): { store: SdkStore; hydrate: Promise<void> } => {\n const store = createEmptyStore(driver);\n return {\n store,\n hydrate: hydrateStoreFromDriver(store, driver),\n };\n};\n\nexport const createDiscoveryAdapterFromStore = (\n store: SdkStore\n): DiscoveryAdapter => ({\n getCachedModels: () => store.getState().modelsFromAllProviders,\n setCachedModels: (models) =>\n store.getState().setModelsFromAllProviders(models),\n getCachedMints: () => store.getState().mintsFromAllProviders,\n setCachedMints: (mints) => store.getState().setMintsFromAllProviders(mints),\n getCachedProviderInfo: () => store.getState().infoFromAllProviders,\n setCachedProviderInfo: (info) =>\n store.getState().setInfoFromAllProviders(info),\n getProviderLastUpdate: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const timestamps = store.getState().lastModelsUpdate;\n return timestamps[normalized] || null;\n },\n setProviderLastUpdate: (baseUrl, timestamp) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const timestamps = { ...store.getState().lastModelsUpdate };\n timestamps[normalized] = timestamp;\n store.getState().setLastModelsUpdate(timestamps);\n },\n getLastUsedModel: () => store.getState().lastUsedModel,\n setLastUsedModel: (modelId) => store.getState().setLastUsedModel(modelId),\n getDisabledProviders: () => store.getState().disabledProviders,\n setDisabledProviders: (urls) => store.getState().setDisabledProviders(urls),\n getBaseUrlsList: () => store.getState().baseUrlsList,\n setBaseUrlsList: (urls) => store.getState().setBaseUrlsList(urls),\n getBaseUrlsLastUpdate: () => store.getState().lastBaseUrlsUpdate,\n setBaseUrlsLastUpdate: (timestamp) =>\n store.getState().setBaseUrlsLastUpdate(timestamp),\n getRoutstr21Models: () => store.getState().routstr21Models,\n setRoutstr21Models: (models) => store.getState().setRoutstr21Models(models),\n getRoutstr21ModelsLastUpdate: () =>\n store.getState().lastRoutstr21ModelsUpdate,\n setRoutstr21ModelsLastUpdate: (timestamp) =>\n store.getState().setRoutstr21ModelsLastUpdate(timestamp),\n});\n\nexport const createStorageAdapterFromStore = (\n store: SdkStore\n): StorageAdapter => ({\n getApiKeyDistribution: () => {\n const apiKeys = store.getState().apiKeys;\n const distributionMap: Record<string, number> = {};\n\n for (const entry of apiKeys) {\n const sum = entry.balance || 0;\n distributionMap[entry.baseUrl] =\n (distributionMap[entry.baseUrl] || 0) + sum;\n }\n\n return Object.entries(distributionMap)\n .map(([baseUrl, amt]) => ({ baseUrl, amount: amt }))\n .sort((a, b) => b.amount - a.amount);\n },\n saveProviderInfo: (baseUrl, info) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const next = { ...store.getState().infoFromAllProviders };\n next[normalized] = info;\n store.getState().setInfoFromAllProviders(next);\n },\n getProviderInfo: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n return store.getState().infoFromAllProviders[normalized] || null;\n },\n\n // ========== API Keys (for apikeys mode) ==========\n\n getApiKey: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const entry = store\n .getState()\n .apiKeys.find((key) => key.baseUrl === normalized);\n if (!entry) return null;\n return entry;\n },\n\n setApiKey: (baseUrl, key) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const keys = store.getState().apiKeys;\n const existingIndex = keys.findIndex(\n (entry) => entry.baseUrl === normalized\n );\n if (existingIndex !== -1) {\n throw new Error(`ApiKey already exists for baseUrl: ${normalized}`);\n }\n const next = [...keys];\n next.push({\n baseUrl: normalized,\n key,\n balance: 0,\n lastUsed: Date.now(),\n });\n store.getState().setApiKeys(next);\n },\n\n updateApiKeyBalance: (baseUrl, balance) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const keys = store.getState().apiKeys;\n const next = keys.map((entry) =>\n entry.baseUrl === normalized\n ? { ...entry, balance, lastUsed: Date.now() }\n : entry\n );\n store.getState().setApiKeys(next);\n },\n\n removeApiKey: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const next = store\n .getState()\n .apiKeys.filter((entry) => entry.baseUrl !== normalized);\n store.getState().setApiKeys(next);\n },\n\n getAllApiKeys: () => {\n return store.getState().apiKeys.map((entry) => ({\n baseUrl: entry.baseUrl,\n key: entry.key,\n balance: entry.balance,\n lastUsed: entry.lastUsed,\n }));\n },\n\n // ========== Child Keys ==========\n\n getChildKey: (parentBaseUrl) => {\n const normalized = normalizeBaseUrl(parentBaseUrl);\n const entry = store\n .getState()\n .childKeys.find((key) => key.parentBaseUrl === normalized);\n if (!entry) return null;\n return {\n parentBaseUrl: entry.parentBaseUrl,\n childKey: entry.childKey,\n balance: entry.balance,\n balanceLimit: entry.balanceLimit,\n validityDate: entry.validityDate,\n createdAt: entry.createdAt,\n };\n },\n\n setChildKey: (\n parentBaseUrl,\n childKey,\n balance,\n validityDate,\n balanceLimit\n ) => {\n const normalized = normalizeBaseUrl(parentBaseUrl);\n const keys = store.getState().childKeys;\n const existingIndex = keys.findIndex(\n (entry) => entry.parentBaseUrl === normalized\n );\n if (existingIndex !== -1) {\n // Update existing child key\n const next = keys.map((entry) =>\n entry.parentBaseUrl === normalized\n ? {\n ...entry,\n childKey,\n balance: balance ?? 0,\n validityDate,\n balanceLimit,\n createdAt: Date.now(),\n }\n : entry\n );\n store.getState().setChildKeys(next);\n } else {\n // Add new child key\n const next = [...keys];\n next.push({\n parentBaseUrl: normalized,\n childKey,\n balance: balance ?? 0,\n validityDate,\n balanceLimit,\n createdAt: Date.now(),\n });\n store.getState().setChildKeys(next);\n }\n },\n\n updateChildKeyBalance: (parentBaseUrl, balance) => {\n const normalized = normalizeBaseUrl(parentBaseUrl);\n const keys = store.getState().childKeys;\n const next = keys.map((entry) =>\n entry.parentBaseUrl === normalized ? { ...entry, balance } : entry\n );\n store.getState().setChildKeys(next);\n },\n\n removeChildKey: (parentBaseUrl) => {\n const normalized = normalizeBaseUrl(parentBaseUrl);\n const next = store\n .getState()\n .childKeys.filter((entry) => entry.parentBaseUrl !== normalized);\n store.getState().setChildKeys(next);\n },\n\n getAllChildKeys: () => {\n return store.getState().childKeys.map((entry) => ({\n parentBaseUrl: entry.parentBaseUrl,\n childKey: entry.childKey,\n balance: entry.balance,\n balanceLimit: entry.balanceLimit,\n validityDate: entry.validityDate,\n createdAt: entry.createdAt,\n }));\n },\n\n getCachedReceiveTokens: () => {\n return store.getState().cachedReceiveTokens;\n },\n\n setCachedReceiveTokens: (tokens) => {\n store.getState().setCachedReceiveTokens(tokens);\n },\n\n // ========== XCashu Tokens (multiple tokens per baseUrl) ==========\n\n getXcashuTokens: () => {\n return store.getState().xcashuTokens;\n },\n\n getXcashuTokensForBaseUrl: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n return store.getState().xcashuTokens[normalized] || [];\n },\n\n addXcashuToken: (baseUrl, token) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const tokens = store.getState().xcashuTokens;\n const existing = tokens[normalized] || [];\n const next = { ...tokens };\n next[normalized] = [\n ...existing,\n { baseUrl: normalized, token, createdAt: Date.now(), tryCount: 0 },\n ];\n store.getState().setXcashuTokens(next);\n },\n\n removeXcashuToken: (baseUrl, token) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const tokens = store.getState().xcashuTokens;\n const existing = tokens[normalized] || [];\n const next = { ...tokens };\n next[normalized] = existing.filter((entry) => entry.token !== token);\n if (next[normalized].length === 0) {\n delete next[normalized];\n }\n store.getState().setXcashuTokens(next);\n },\n\n clearXcashuTokensForBaseUrl: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const tokens = store.getState().xcashuTokens;\n const next = { ...tokens };\n delete next[normalized];\n store.getState().setXcashuTokens(next);\n },\n\n updateXcashuTokenTryCount: (token, tryCount) => {\n store.getState().updateXcashuTokenTryCount(token, tryCount);\n },\n});\n\nexport const createProviderRegistryFromStore = (\n store: SdkStore,\n logger?: SdkLogger\n): ProviderRegistry => {\n const log = (logger ?? consoleLogger).child(\"ProviderRegistry\");\n return {\n getModelsForProvider: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n return store.getState().modelsFromAllProviders[normalized] || [];\n },\n getDisabledProviders: () => store.getState().disabledProviders,\n getProviderMints: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n return store.getState().mintsFromAllProviders[normalized] || [];\n },\n getProviderInfo: async (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const cached = store.getState().infoFromAllProviders[normalized];\n if (cached) return cached;\n try {\n const response = await fetch(`${normalized}v1/info`);\n if (!response.ok) {\n throw new Error(`Failed ${response.status}`);\n }\n const info = (await response.json()) as ProviderInfo;\n const next = { ...store.getState().infoFromAllProviders };\n next[normalized] = info;\n store.getState().setInfoFromAllProviders(next);\n return info;\n } catch (error) {\n log.warn(`Failed to fetch provider info from ${normalized}:`, error);\n return null;\n }\n },\n getAllProvidersModels: () => store.getState().modelsFromAllProviders,\n };\n};\n","import { localStorageDriver } from \"./drivers/localStorage\";\nimport { createMemoryDriver } from \"./drivers/memory\";\nimport { createIndexedDBDriver } from \"./drivers/indexedDB\";\nimport {\n createIndexedDBUsageTrackingDriver,\n createMemoryUsageTrackingDriver,\n type UsageTrackingDriver,\n} from \"./usageTracking\";\nimport type { StorageDriver } from \"./types\";\nimport {\n createSdkStore,\n createStorageAdapterFromStore,\n type SdkStore,\n} from \"./store\";\nimport type { DiscoveryAdapter } from \"../discovery/interfaces\";\n\nexport type { StorageDriver } from \"./types\";\nexport type { SdkStore } from \"./store\";\nexport type { DiscoveryAdapter } from \"../discovery/interfaces\";\nexport type { StorageAdapter, ProviderRegistry, XCashuTokenEntry } from \"../wallet/interfaces\";\nexport type {\n AggregateUsageOptions,\n ListUsageTrackingOptions,\n UsageAggregateRow,\n UsageGroupBy,\n UsageTrackingDriver,\n UsageTrackingEntry,\n} from \"./usageTracking\";\nexport { SDK_STORAGE_KEYS } from \"./keys\";\nexport {\n createSdkStore,\n createDiscoveryAdapterFromStore,\n createProviderRegistryFromStore,\n createStorageAdapterFromStore,\n} from \"./store\";\nexport {\n localStorageDriver,\n createMemoryDriver,\n createIndexedDBDriver,\n};\nexport {\n createIndexedDBUsageTrackingDriver,\n createMemoryUsageTrackingDriver,\n} from \"./usageTracking\";\nimport {\n createProviderRegistryFromDiscoveryAdapter,\n createShardedDiscoveryAdapter,\n} from \"./shardedDiscoveryAdapter\";\nexport {\n createProviderRegistryFromDiscoveryAdapter,\n createShardedDiscoveryAdapter,\n} from \"./shardedDiscoveryAdapter\";\nexport type {\n ShardedDiscoveryAdapterOptions,\n} from \"./shardedDiscoveryAdapter\";\n\nconst isBrowser = (): boolean => {\n try {\n return (\n typeof window !== \"undefined\" &&\n typeof window.localStorage !== \"undefined\"\n );\n } catch {\n return false;\n }\n};\n\nlet defaultDriver: StorageDriver | null = null;\n\nexport const getDefaultSdkDriver = (): StorageDriver => {\n if (defaultDriver) return defaultDriver;\n if (isBrowser()) {\n defaultDriver = localStorageDriver;\n return defaultDriver;\n }\n defaultDriver = createMemoryDriver();\n return defaultDriver;\n};\n\nlet defaultStore: ReturnType<typeof createSdkStore> | null = null;\nlet defaultUsageTrackingDriver: UsageTrackingDriver | null = null;\n\nexport const getDefaultSdkStore = (): Promise<SdkStore> => {\n if (!defaultStore) {\n defaultStore = createSdkStore({ driver: getDefaultSdkDriver() });\n }\n return defaultStore.hydrate.then(() => defaultStore!.store);\n};\n\nexport const getDefaultUsageTrackingDriver = (): UsageTrackingDriver => {\n if (defaultUsageTrackingDriver) return defaultUsageTrackingDriver;\n\n const storageDriver = getDefaultSdkDriver();\n\n if (isBrowser()) {\n defaultUsageTrackingDriver = createIndexedDBUsageTrackingDriver({\n legacyStorageDriver: storageDriver,\n });\n return defaultUsageTrackingDriver;\n }\n\n defaultUsageTrackingDriver = createMemoryUsageTrackingDriver();\n return defaultUsageTrackingDriver;\n};\n\n/**\n * Allow setting a custom usage tracking driver (useful for routstrd to use proper DB path)\n */\nexport const setDefaultUsageTrackingDriver = (driver: UsageTrackingDriver): void => {\n defaultUsageTrackingDriver = driver;\n};\n\nlet defaultDiscoveryAdapter: DiscoveryAdapter | null = null;\n\nexport const getDefaultDiscoveryAdapter = async (): Promise<DiscoveryAdapter> => {\n if (defaultDiscoveryAdapter) return defaultDiscoveryAdapter;\n\n const driver = getDefaultSdkDriver();\n defaultDiscoveryAdapter = await createShardedDiscoveryAdapter({ driver });\n return defaultDiscoveryAdapter;\n};\n\nexport const getDefaultStorageAdapter = async () =>\n createStorageAdapterFromStore(await getDefaultSdkStore());\n\nexport const getDefaultProviderRegistry = async () =>\n createProviderRegistryFromDiscoveryAdapter(await getDefaultDiscoveryAdapter());\n","import type { UsageStats } from \"../core/types\";\n\nexport interface UsageTrackingData {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n cost: number;\n satsCost: number;\n /** Upstream provider/route that handled the request (e.g. \"openrouter:openrouter:Anthropic\"). */\n provider?: string;\n /** Full cost breakdown emitted by the upstream `cost` object. */\n baseMsats?: number;\n inputMsats?: number;\n outputMsats?: number;\n totalMsats?: number;\n totalUsd?: number;\n cacheReadInputTokens?: number;\n cacheCreationInputTokens?: number;\n cacheReadMsats?: number;\n cacheCreationMsats?: number;\n remainingBalanceMsats?: number;\n}\n\nconst numOrUndef = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n\n/**\n * Extract the detailed cost breakdown from an upstream `cost` object.\n * Returns the camelCased fields we persist on a UsageTrackingData/entry.\n */\nfunction extractCostBreakdown(\n costObj: Record<string, unknown> | null | undefined\n): Partial<UsageTrackingData> {\n if (!costObj || typeof costObj !== \"object\") return {};\n return {\n baseMsats: numOrUndef(costObj.base_msats),\n inputMsats: numOrUndef(costObj.input_msats),\n outputMsats: numOrUndef(costObj.output_msats),\n totalMsats: numOrUndef(costObj.total_msats),\n totalUsd: numOrUndef(costObj.total_usd),\n cacheReadInputTokens: numOrUndef(costObj.cache_read_input_tokens),\n cacheCreationInputTokens: numOrUndef(costObj.cache_creation_input_tokens),\n cacheReadMsats: numOrUndef(costObj.cache_read_msats),\n cacheCreationMsats: numOrUndef(costObj.cache_creation_msats),\n remainingBalanceMsats: numOrUndef(costObj.remaining_balance_msats),\n };\n}\n\nexport function extractUsageFromResponseBody(\n body: unknown,\n fallbackSatsCost = 0\n): UsageTrackingData | null {\n if (!body || typeof body !== \"object\") return null;\n const usage = (body as { usage?: Record<string, unknown> }).usage;\n if (!usage || typeof usage !== \"object\") return null;\n\n const promptTokens = Number(usage.prompt_tokens ?? 0);\n const completionTokens = Number(usage.completion_tokens ?? 0);\n const totalTokens = Number(usage.total_tokens ?? 0);\n const costValue = usage.cost;\n\n let cost = 0;\n let satsCost = fallbackSatsCost;\n let breakdown: Partial<UsageTrackingData> = {};\n\n if (typeof costValue === \"number\") {\n cost = costValue;\n } else if (costValue && typeof costValue === \"object\") {\n const costObj = costValue as Record<string, unknown>;\n const totalUsd = costObj.total_usd;\n const totalMsats = costObj.total_msats;\n\n cost = typeof totalUsd === \"number\" ? totalUsd : 0;\n if (typeof totalMsats === \"number\") {\n satsCost = totalMsats / 1000;\n }\n breakdown = extractCostBreakdown(costObj);\n }\n\n const provider =\n typeof (body as { provider?: unknown }).provider === \"string\"\n ? ((body as { provider?: string }).provider as string)\n : undefined;\n\n if (\n promptTokens === 0 &&\n completionTokens === 0 &&\n totalTokens === 0 &&\n cost === 0 &&\n satsCost === 0\n ) {\n return null;\n }\n\n return {\n promptTokens,\n completionTokens,\n totalTokens,\n cost,\n satsCost,\n provider,\n ...breakdown,\n };\n}\n\nexport function extractResponseId(body: unknown): string | undefined {\n if (!body || typeof body !== \"object\") return undefined;\n const id = (body as { id?: unknown }).id;\n if (typeof id !== \"string\") return undefined;\n const trimmed = id.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport function extractUsageFromSSEJson(\n parsed: any,\n fallbackSatsCost = 0\n): UsageTrackingData | null {\n if (!parsed || typeof parsed !== \"object\") {\n return null;\n }\n\n const provider =\n typeof parsed.provider === \"string\" ? parsed.provider : undefined;\n\n // Handle standalone cost chunk: {\"cost\":{\"base_msats\":...,\"input_msats\":...,\"output_msats\":...,\"total_msats\":2,...}}\n if (!parsed.usage && parsed.cost && typeof parsed.cost === \"object\") {\n const costObj = parsed.cost;\n const msats = costObj.total_msats ?? 0;\n const cost = costObj.total_usd ?? 0;\n if (msats === 0 && cost === 0) return null;\n return {\n promptTokens: Number(costObj.input_tokens ?? 0),\n completionTokens: Number(costObj.output_tokens ?? 0),\n totalTokens: Number((costObj.input_tokens ?? 0) + (costObj.output_tokens ?? 0)),\n cost: Number(cost),\n satsCost: msats > 0 ? msats / 1000 : fallbackSatsCost,\n provider,\n ...extractCostBreakdown(costObj),\n };\n }\n\n if (!parsed.usage) {\n return null;\n }\n\n const usage = parsed.usage;\n const usageCost = usage.cost;\n \n let cost = 0;\n let msats = 0;\n let breakdown: Partial<UsageTrackingData> = {};\n\n if (typeof usageCost === \"number\") {\n cost = usageCost;\n } else if (usageCost && typeof usageCost === \"object\") {\n cost = usageCost.total_usd ?? 0;\n msats = usageCost.total_msats ?? 0;\n breakdown = extractCostBreakdown(usageCost as Record<string, unknown>);\n }\n\n // Some upstreams put the detailed breakdown under metadata.routstr.cost.\n const routstrCost = parsed.metadata?.routstr?.cost;\n if (routstrCost && typeof routstrCost === \"object\") {\n breakdown = { ...extractCostBreakdown(routstrCost), ...breakdown };\n }\n\n // Fallbacks if not in usage.cost\n if (cost === 0) {\n cost = parsed.metadata?.routstr?.cost?.total_usd ?? 0;\n }\n if (msats === 0) {\n msats =\n parsed.metadata?.routstr?.cost?.total_msats ??\n (typeof usage.cost_sats === \"number\" ? usage.cost_sats * 1000 : 0);\n }\n\n // Support both OpenAI-style (prompt_tokens/completion_tokens) and Anthropic-style (input_tokens/output_tokens)\n const promptTokens = Number(usage.prompt_tokens ?? usage.input_tokens ?? 0);\n const completionTokens = Number(usage.completion_tokens ?? usage.output_tokens ?? 0);\n const totalTokens = Number(usage.total_tokens ?? (promptTokens + completionTokens));\n\n const result: UsageTrackingData = {\n promptTokens,\n completionTokens,\n totalTokens,\n cost: Number(cost ?? 0),\n satsCost: msats > 0 ? msats / 1000 : fallbackSatsCost,\n provider,\n ...breakdown,\n };\n\n if (\n result.promptTokens === 0 &&\n result.completionTokens === 0 &&\n result.totalTokens === 0 &&\n result.cost === 0 &&\n result.satsCost === 0\n ) {\n return null;\n }\n\n return result;\n}\n\nexport function toUsageStats(\n usage: UsageTrackingData | null | undefined\n): UsageStats | undefined {\n if (!usage) return undefined;\n return {\n total_tokens: usage.totalTokens,\n prompt_tokens: usage.promptTokens,\n completion_tokens: usage.completionTokens,\n cost: usage.cost,\n sats_cost: usage.satsCost,\n };\n}\n","import { Transform } from \"stream\";\nimport { StringDecoder } from \"string_decoder\";\nimport { extractUsageFromSSEJson, type UsageTrackingData } from \"./usage\";\n\n/**\n * Merge previously captured usage with a newly seen usage payload, preferring\n * non-zero fields from the new payload.\n */\nfunction mergeUsage(\n previous: UsageTrackingData | null,\n next: UsageTrackingData\n): UsageTrackingData {\n if (!previous) return next;\n const pickNum = (\n n: number | undefined,\n p: number | undefined\n ): number | undefined => (typeof n === \"number\" && n > 0 ? n : p ?? n);\n return {\n promptTokens:\n next.promptTokens > 0 ? next.promptTokens : previous.promptTokens,\n completionTokens:\n next.completionTokens > 0\n ? next.completionTokens\n : previous.completionTokens,\n totalTokens:\n next.totalTokens > 0 ? next.totalTokens : previous.totalTokens,\n cost: next.cost > 0 ? next.cost : previous.cost,\n satsCost: next.satsCost > 0 ? next.satsCost : previous.satsCost,\n provider: next.provider ?? previous.provider,\n baseMsats: pickNum(next.baseMsats, previous.baseMsats),\n inputMsats: pickNum(next.inputMsats, previous.inputMsats),\n outputMsats: pickNum(next.outputMsats, previous.outputMsats),\n totalMsats: pickNum(next.totalMsats, previous.totalMsats),\n totalUsd: pickNum(next.totalUsd, previous.totalUsd),\n cacheReadInputTokens: pickNum(\n next.cacheReadInputTokens,\n previous.cacheReadInputTokens\n ),\n cacheCreationInputTokens: pickNum(\n next.cacheCreationInputTokens,\n previous.cacheCreationInputTokens\n ),\n cacheReadMsats: pickNum(next.cacheReadMsats, previous.cacheReadMsats),\n cacheCreationMsats: pickNum(\n next.cacheCreationMsats,\n previous.cacheCreationMsats\n ),\n remainingBalanceMsats: pickNum(\n next.remainingBalanceMsats,\n previous.remainingBalanceMsats\n ),\n };\n}\n\nfunction hasUsageChanged(\n previous: UsageTrackingData | null,\n next: UsageTrackingData\n): boolean {\n if (!previous) return true;\n return (\n previous.promptTokens !== next.promptTokens ||\n previous.completionTokens !== next.completionTokens ||\n previous.totalTokens !== next.totalTokens ||\n previous.cost !== next.cost ||\n previous.satsCost !== next.satsCost ||\n previous.provider !== next.provider ||\n previous.totalMsats !== next.totalMsats ||\n previous.remainingBalanceMsats !== next.remainingBalanceMsats\n );\n}\n\n/**\n * The inspector can stop early once we've seen the response id, a provider,\n * usage with token counts, and the detailed cost breakdown (total_msats).\n */\nfunction isInspectionComplete(\n responseIdCaptured: boolean,\n usage: UsageTrackingData | null\n): boolean {\n return (\n responseIdCaptured &&\n !!usage &&\n usage.totalTokens > 0 &&\n typeof usage.totalMsats === \"number\" &&\n !!usage.provider\n );\n}\n\n/**\n * Inspect a Web `ReadableStream<Uint8Array>` of SSE bytes for `usage` and\n * response `id` fields without touching the bytes that are delivered to the\n * real client. This is meant to be called on one branch of a `body.tee()`.\n *\n * The inspector reads the stream to completion (or errors out), decoding\n * UTF-8 across chunk boundaries, splitting on SSE event terminators\n * (`\\r?\\n\\r?\\n`), parsing each `data:` payload as JSON, and invoking the\n * provided callbacks when usage / response id become known.\n *\n * The returned Promise resolves with the final captured values once the\n * stream ends (or is cancelled / errors out).\n */\nexport async function inspectSSEWebStream(\n stream: ReadableStream<Uint8Array>,\n onUsage: (usage: UsageTrackingData) => void,\n onResponseId?: (responseId: string) => void,\n options?: {\n /** Called with each raw chunk read from the tee'd inspection branch. */\n onRawChunk?: (chunk: Uint8Array, sequence: number, text: string) => void | Promise<void>;\n }\n): Promise<{\n capturedUsage?: UsageTrackingData;\n capturedResponseId?: string;\n}> {\n const reader = stream.getReader();\n const decoder = new TextDecoder(\"utf-8\");\n let buffer = \"\";\n let capturedUsage: UsageTrackingData | null = null;\n let capturedResponseId: string | undefined;\n let responseIdCaptured = false;\n let rawChunkSequence = 0;\n\n const inspectDataPayload = (jsonText: string): void => {\n const trimmed = jsonText.trim();\n if (!trimmed || trimmed === \"[DONE]\") {\n if (trimmed === \"[DONE]\") console.log(\"[routstr:sse] [DONE]\");\n return;\n }\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n console.log(\"[routstr:sse] non-JSON payload:\", trimmed.slice(0, 200));\n return;\n }\n\n try {\n const data = JSON.parse(trimmed) as any;\n console.log(\"[routstr:sse] chunk:\", JSON.stringify(data));\n\n if (isInspectionComplete(responseIdCaptured, capturedUsage)) {\n console.log(\"[routstr:sse] (inspection already complete, skipping)\");\n return;\n }\n\n if (!responseIdCaptured) {\n const responseId = data?.id;\n if (typeof responseId === \"string\" && responseId.trim().length > 0) {\n capturedResponseId = responseId.trim();\n onResponseId?.(capturedResponseId);\n responseIdCaptured = true;\n }\n }\n\n const usage = extractUsageFromSSEJson(data);\n if (usage) {\n console.log(\"[routstr:sse] → usage detected:\", usage);\n const merged = mergeUsage(capturedUsage, usage);\n if (hasUsageChanged(capturedUsage, merged)) {\n capturedUsage = merged;\n console.log(\"[routstr:sse] → merged (changed):\", merged);\n onUsage(merged);\n } else {\n console.log(\"[routstr:sse] → merged (no change)\");\n }\n }\n } catch {\n console.log(\"[routstr:sse] failed to parse payload:\", trimmed.slice(0, 200));\n }\n };\n\n const inspectEventBlock = (eventBlock: string): void => {\n const lines = eventBlock.split(/\\r?\\n/);\n const dataParts: string[] = [];\n for (const line of lines) {\n if (!line || line.startsWith(\":\")) continue;\n if (line.startsWith(\"data:\")) {\n const value = line.startsWith(\"data: \") ? line.slice(6) : line.slice(5);\n dataParts.push(value);\n }\n }\n\n if (dataParts.length === 0) return;\n inspectDataPayload(dataParts.join(\"\\n\"));\n };\n\n const drainBufferedEvents = (): void => {\n const terminator = /\\r?\\n\\r?\\n/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = terminator.exec(buffer)) !== null) {\n const block = buffer.slice(lastIndex, match.index);\n lastIndex = match.index + match[0].length;\n if (block.length > 0) inspectEventBlock(block);\n }\n if (lastIndex > 0) buffer = buffer.slice(lastIndex);\n };\n\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n if (value && value.byteLength > 0) {\n const text = decoder.decode(value, { stream: true });\n void options?.onRawChunk?.(value, rawChunkSequence++, text);\n buffer += text;\n drainBufferedEvents();\n }\n }\n buffer += decoder.decode();\n drainBufferedEvents();\n if (buffer.length > 0) {\n const tail = buffer.replace(/\\r?\\n+$/, \"\");\n if (tail.length > 0) inspectEventBlock(tail);\n buffer = \"\";\n }\n } catch {\n // Swallow — inspection is best-effort. The client branch is independent.\n } finally {\n try {\n reader.releaseLock();\n } catch {\n // ignore\n }\n }\n\n return {\n capturedUsage: capturedUsage ?? undefined,\n capturedResponseId,\n };\n}\n\n/**\n * SSE parser transform that preserves the original byte stream.\n *\n * Incoming chunks are forwarded downstream unchanged so chunk boundaries and\n * timing remain identical to the upstream source. In parallel, a streaming text\n * decoder buffers just enough data to detect complete SSE event blocks for\n * usage/responseId inspection.\n *\n * This means:\n * - The client sees the original stream bytes without parser-induced\n * re-chunking.\n * - Multi-line events (multiple `data:` lines, plus `event:`/`id:`/`retry:`\n * fields) are still parsed correctly for inspection.\n * - Chunks that contain multiple events, or events split across chunks, are\n * handled correctly without merging or losing packets.\n * - UTF-8 split across chunk boundaries is decoded safely.\n */\nexport function createSSEParserTransform(\n onUsage: (usage: UsageTrackingData) => void,\n onResponseId?: (responseId: string) => void\n): Transform {\n let buffer = \"\";\n const decoder = new StringDecoder(\"utf8\");\n let capturedUsage: UsageTrackingData | null = null;\n let responseIdCaptured = false;\n\n const inspectDataPayload = (jsonText: string): void => {\n const trimmed = jsonText.trim();\n if (!trimmed || trimmed === \"[DONE]\") {\n if (trimmed === \"[DONE]\") console.log(\"[routstr:sse] [DONE]\");\n return;\n }\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n console.log(\"[routstr:sse] non-JSON payload:\", trimmed.slice(0, 200));\n return;\n }\n\n try {\n const data = JSON.parse(trimmed) as any;\n console.log(\"[routstr:sse] chunk:\", JSON.stringify(data));\n\n if (isInspectionComplete(responseIdCaptured, capturedUsage)) {\n console.log(\"[routstr:sse] (inspection already complete, skipping)\");\n return;\n }\n\n if (!responseIdCaptured) {\n const responseId = data?.id;\n if (typeof responseId === \"string\" && responseId.trim().length > 0) {\n onResponseId?.(responseId.trim());\n responseIdCaptured = true;\n }\n }\n\n const usage = extractUsageFromSSEJson(data);\n if (usage) {\n console.log(\"[routstr:sse] → usage detected:\", usage);\n const mergedUsage = mergeUsage(capturedUsage, usage);\n if (hasUsageChanged(capturedUsage, mergedUsage)) {\n capturedUsage = mergedUsage;\n console.log(\"[routstr:sse] → merged (changed):\", mergedUsage);\n onUsage(mergedUsage);\n } else {\n console.log(\"[routstr:sse] → merged (no change)\");\n }\n }\n } catch {\n console.log(\"[routstr:sse] failed to parse payload:\", trimmed.slice(0, 200));\n }\n };\n\n /**\n * Parse a single SSE event block and invoke usage/id inspection on any\n * `data:` fields. Per the SSE spec, multiple `data:` lines within one\n * event are concatenated with `\\n` to form the payload.\n */\n const inspectEventBlock = (eventBlock: string): void => {\n const lines = eventBlock.split(/\\r?\\n/);\n const dataParts: string[] = [];\n\n for (const line of lines) {\n if (!line || line.startsWith(\":\")) continue;\n // SSE fields are of the form `field: value` or `field:value`.\n // We only care about `data:` for inspection purposes.\n if (line.startsWith(\"data:\")) {\n const value = line.startsWith(\"data: \") ? line.slice(6) : line.slice(5);\n dataParts.push(value);\n }\n }\n\n if (dataParts.length === 0) return;\n const payload = dataParts.join(\"\\n\");\n inspectDataPayload(payload);\n };\n\n const processBufferedEvents = (): void => {\n // Events are terminated by a blank line: either \\n\\n or \\r\\n\\r\\n.\n // Scan the decoded text buffer for complete events and inspect them.\n const terminator = /\\r?\\n\\r?\\n/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = terminator.exec(buffer)) !== null) {\n const block = buffer.slice(lastIndex, match.index);\n lastIndex = match.index + match[0].length;\n if (block.length > 0) {\n inspectEventBlock(block);\n }\n }\n\n if (lastIndex > 0) {\n buffer = buffer.slice(lastIndex);\n }\n };\n\n return new Transform({\n transform(chunk, _encoding, callback) {\n this.push(chunk);\n buffer += decoder.write(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n processBufferedEvents();\n callback();\n },\n flush(callback) {\n buffer += decoder.end();\n processBufferedEvents();\n\n // Inspect any remaining buffered content as a final event block. Upstreams\n // that close without a trailing blank line can still contain a final event.\n if (buffer.length > 0) {\n const tail = buffer.replace(/\\r?\\n+$/, \"\");\n if (tail.length > 0) {\n inspectEventBlock(tail);\n }\n buffer = \"\";\n }\n callback();\n },\n });\n}\n","/**\n * RoutstrClient - Main API client for Routstr\n *\n * Orchestrates:\n * - Token spending via CashuSpender\n * - API requests with authentication\n * - Streaming response processing\n * - Provider failover via ProviderManager\n * - Error handling and refunds\n *\n * Extracted from utils/apiUtils.ts\n */\n\nimport type { SdkLogger } from \"../core/types\";\nimport type { Model } from \"../core/types\";\nimport { consoleLogger } from \"../core/types\";\nimport type {\n WalletAdapter,\n StorageAdapter,\n ProviderRegistry,\n} from \"../wallet/interfaces\";\nimport type { UsageTrackingDriver } from \"../storage/usageTracking\";\nimport type { SdkStore } from \"../storage/store\";\nimport { CashuSpender } from \"../wallet/CashuSpender\";\nimport { BalanceManager } from \"../wallet/BalanceManager\";\nimport { ProviderManager } from \"./ProviderManager\";\nimport {\n ProviderError,\n FailoverError,\n InsufficientBalanceError,\n} from \"../core/errors\";\nimport { isNetworkErrorMessage } from \"../wallet/tokenUtils\";\nimport { getDefaultSdkStore, getDefaultUsageTrackingDriver } from \"../storage\";\nimport {\n extractResponseId,\n extractUsageFromResponseBody,\n type UsageTrackingData,\n} from \"./usage\";\nimport { inspectSSEWebStream } from \"./sse\";\n\n/**\n * RoutstrClient is the main SDK entry point\n */\nexport type AlertLevel = \"max\" | \"min\";\nexport type RoutstrClientMode = \"xcashu\" | \"apikeys\";\nexport type DebugLevel = \"DEBUG\" | \"WARN\" | \"ERROR\";\n\nconst TOPUP_MARGIN = 1.2;\n\nexport interface RouteRequestParams {\n path: string;\n method: string;\n body?: unknown;\n headers?: Record<string, string>;\n baseUrl: string;\n mintUrl: string;\n modelId?: string;\n clientApiKey?: string;\n}\n\nexport interface RequestResponseLogRequestInput {\n method: string;\n url: string;\n path: string;\n baseUrl: string;\n headers: Record<string, string>;\n body?: unknown;\n rawBody?: string;\n}\n\nexport interface RequestResponseLogSink {\n logRequest?(input: RequestResponseLogRequestInput): string | undefined | Promise<string | undefined>;\n logResponseStart?(id: string | undefined, response: Response): void | Promise<void>;\n logResponseChunk?(id: string | undefined, sequence: number, text: string): void | Promise<void>;\n logResponseEnd?(id: string | undefined): void | Promise<void>;\n logResponseError?(id: string | undefined, error: unknown): void | Promise<void>;\n logResponseBody?(id: string | undefined, response: Response): void | Promise<void>;\n}\n\nexport interface RoutstrClientConfig {\n usageTrackingDriver?: UsageTrackingDriver;\n sdkStore?: SdkStore;\n /** Optional: shared ProviderManager instance for consistent failure tracking across requests */\n providerManager?: ProviderManager;\n /** Optional: injectable logger (defaults to consoleLogger) */\n logger?: SdkLogger;\n /** Optional: raw request/response logging callbacks supplied by the runtime/app. */\n requestResponseLogSink?: RequestResponseLogSink;\n}\n\nexport class RoutstrClient {\n private cashuSpender: CashuSpender;\n private balanceManager: BalanceManager;\n private providerManager: ProviderManager;\n private alertLevel: AlertLevel;\n private mode: RoutstrClientMode;\n private debugLevel: DebugLevel = \"WARN\";\n private usageTrackingDriver?: UsageTrackingDriver;\n private sdkStore?: SdkStore;\n private logger: SdkLogger;\n private requestResponseLogSink?: RequestResponseLogSink;\n\n constructor(\n private walletAdapter: WalletAdapter,\n private storageAdapter: StorageAdapter,\n private providerRegistry: ProviderRegistry,\n alertLevel: AlertLevel,\n mode: RoutstrClientMode = \"xcashu\",\n options: RoutstrClientConfig = {}\n ) {\n this.logger = (options.logger ?? consoleLogger).child(\"RoutstrClient\");\n this.balanceManager = new BalanceManager(\n walletAdapter,\n storageAdapter,\n providerRegistry,\n undefined,\n this.logger\n );\n this.cashuSpender = new CashuSpender(\n walletAdapter,\n storageAdapter,\n providerRegistry,\n this.balanceManager,\n this.logger\n );\n this.alertLevel = alertLevel;\n this.mode = mode;\n this.usageTrackingDriver = options.usageTrackingDriver;\n this.sdkStore = options.sdkStore;\n this.requestResponseLogSink = options.requestResponseLogSink;\n // Use provided ProviderManager or create a new one\n this.providerManager =\n options.providerManager ??\n new ProviderManager(providerRegistry, this.sdkStore, this.logger);\n }\n\n /**\n * Get the current client mode\n */\n getMode(): RoutstrClientMode {\n return this.mode;\n }\n\n getDebugLevel(): DebugLevel {\n return this.debugLevel;\n }\n\n setDebugLevel(level: DebugLevel): void {\n this.debugLevel = level;\n }\n\n private _log(level: \"DEBUG\" | \"WARN\" | \"ERROR\", ...args: unknown[]): void {\n const levelPriority: Record<DebugLevel, number> = {\n DEBUG: 0,\n WARN: 1,\n ERROR: 2,\n };\n\n if (levelPriority[level] >= levelPriority[this.debugLevel]) {\n switch (level) {\n case \"DEBUG\":\n this.logger.log(...args);\n break;\n case \"WARN\":\n this.logger.warn(...args);\n break;\n case \"ERROR\":\n this.logger.error(...args);\n break;\n }\n }\n }\n\n /**\n * Get the CashuSpender instance\n */\n getCashuSpender(): CashuSpender {\n return this.cashuSpender;\n }\n\n /**\n * Get the BalanceManager instance\n */\n getBalanceManager(): BalanceManager {\n return this.balanceManager;\n }\n\n /**\n * Get the ProviderManager instance\n */\n getProviderManager(): ProviderManager {\n return this.providerManager;\n }\n\n /**\n * Check if the client is currently busy (in critical section)\n */\n get isBusy(): boolean {\n return this.cashuSpender.isBusy;\n }\n\n /**\n * Route an API request to the upstream provider\n *\n * This is a simpler alternative to fetchAIResponse that just proxies\n * the request upstream without the streaming callback machinery.\n * Useful for daemon-style routing where you just need to forward\n * requests and get responses back.\n */\n async routeRequest(params: RouteRequestParams): Promise<Response> {\n const prepared = await this._prepareRoutedRequest(params);\n const contentType =\n prepared.response.headers.get(\"content-type\") || \"\";\n const isSSE = contentType.includes(\"text/event-stream\");\n\n // For SSE, defer accounting until the inspector (tee'd branch) has seen\n // usage — which only happens as the client consumes the stream. We expose\n // the finalization as `(response).finalize` so callers that want to block\n // on accounting (e.g. a proxy after it finished piping) can `await` it.\n // Non-SSE responses can be finalized inline since the body is fully\n // available (the clone-and-read path inside `_trackResponseUsage` handles\n // JSON bodies without consuming the client-facing copy).\n const runFinalize = async (): Promise<number> => {\n const { capturedUsage, capturedResponseId } = await prepared.usagePromise;\n const usage = capturedUsage ?? prepared.capturedUsage;\n const requestId = capturedResponseId ?? prepared.capturedResponseId;\n const satsSpent = await this._handlePostResponseBalanceUpdate({\n token: prepared.tokenUsed,\n baseUrl: prepared.baseUrlUsed,\n mintUrl: params.mintUrl,\n initialTokenBalance: prepared.tokenBalanceInSats,\n initialTokenBalanceUnknown: prepared.tokenBalanceUnknown,\n fallbackSatsSpent: usage?.satsCost,\n response: prepared.response,\n modelId: prepared.modelId,\n usage,\n requestId,\n clientApiKey: prepared.clientApiKey,\n });\n (prepared.response as any).satsSpent = satsSpent;\n (prepared.response as any).usage = usage;\n (prepared.response as any).requestId = requestId;\n return satsSpent;\n };\n\n if (isSSE) {\n // Expose a finalize() that the caller can await after it's done piping\n // the stream to its client. Also fire-and-forget so accounting still\n // happens even if the caller ignores it.\n const finalizePromise = runFinalize().catch((error) => {\n this._log(\"ERROR\", \"[RoutstrClient] SSE finalize failed:\", error);\n return 0;\n });\n (prepared.response as any).finalize = () => finalizePromise;\n return prepared.response;\n }\n\n await runFinalize();\n return prepared.response;\n }\n\n private async _prepareRoutedRequest(params: RouteRequestParams): Promise<{\n response: Response;\n tokenUsed: string;\n baseUrlUsed: string;\n tokenBalanceInSats: number;\n tokenBalanceUnknown: boolean;\n modelId?: string;\n capturedUsage?: UsageTrackingData;\n capturedResponseId?: string;\n clientApiKey?: string;\n usagePromise: Promise<{\n capturedUsage?: UsageTrackingData;\n capturedResponseId?: string;\n }>;\n }> {\n const {\n path: requestPath,\n method,\n body,\n headers = {},\n baseUrl,\n mintUrl,\n modelId,\n clientApiKey: providedClientApiKey,\n } = params;\n\n // Extract clientApiKey from incoming headers then discard them — they must\n // not be forwarded upstream (the client's Authorization Bearer key would\n // overwrite the Cashu/API-key auth we attach ourselves).\n const clientApiKey =\n providedClientApiKey ?? this._extractClientApiKey(headers);\n\n await this._checkBalance();\n\n let requiredSats = 1;\n let selectedModel: Model | undefined;\n if (modelId) {\n const providerModel = await this.providerManager.getModelForProvider(\n baseUrl,\n modelId\n );\n selectedModel = providerModel ?? undefined;\n if (selectedModel) {\n const requestMessages = Array.isArray(\n (body as { messages?: unknown })?.messages\n )\n ? ((body as { messages?: unknown }).messages as any[])\n : [];\n const requestMaxTokens =\n typeof (body as { max_tokens?: unknown })?.max_tokens === \"number\"\n ? ((body as { max_tokens?: unknown }).max_tokens as number)\n : undefined;\n\n this._log(\n \"DEBUG\",\n \"[RoutstrClient] generic request pricing input\",\n {\n modelId: selectedModel.id,\n messageCount: requestMessages.length,\n maxTokens: requestMaxTokens,\n }\n );\n\n requiredSats = this.providerManager.getRequiredSatsForModel(\n selectedModel,\n requestMessages,\n requestMaxTokens\n );\n }\n }\n\n const { token, tokenBalance, tokenBalanceUnit, tokenBalanceUnknown } = await this._spendToken({\n mintUrl,\n amount: requiredSats,\n baseUrl,\n });\n\n let requestBody = body;\n if (body && typeof body === \"object\") {\n const bodyObj = body as Record<string, unknown>;\n if (!bodyObj.stream) {\n requestBody = { ...bodyObj, stream: false };\n }\n }\n\n // Build clean outgoing headers — do NOT pass the incoming client headers here\n const baseHeaders = this._buildBaseHeaders();\n const requestHeaders = this._withAuthHeader(baseHeaders, token);\n\n const response = await this._makeRequest({\n path: requestPath,\n method,\n body: method === \"GET\" ? undefined : requestBody,\n baseUrl,\n mintUrl,\n token,\n requiredSats,\n headers: requestHeaders,\n baseHeaders,\n selectedModel,\n });\n\n let tokenBalanceInSats =\n tokenBalanceUnit === \"msat\" ? tokenBalance / 1000 : tokenBalance;\n let initialTokenBalanceUnknown = tokenBalanceUnknown;\n const baseUrlUsed = (response as any).baseUrl || baseUrl;\n const tokenUsed = (response as any).token || token;\n\n // If failover occurred, use the initial balance captured when the\n // failover token was created. Do not query here: by the time fetch returns,\n // the provider may already have charged the request.\n if (baseUrlUsed !== baseUrl || tokenUsed !== token) {\n if (typeof (response as any).initialTokenBalanceInSats === \"number\") {\n tokenBalanceInSats = (response as any).initialTokenBalanceInSats;\n initialTokenBalanceUnknown = Boolean(\n (response as any).initialTokenBalanceUnknown\n );\n } else {\n initialTokenBalanceUnknown = true;\n }\n }\n\n const contentType = response.headers.get(\"content-type\") || \"\";\n let processedResponse = response;\n let capturedUsage: UsageTrackingData | undefined;\n let capturedResponseId: string | undefined;\n let usagePromise: Promise<{\n capturedUsage?: UsageTrackingData;\n capturedResponseId?: string;\n }> = Promise.resolve({});\n\n if (contentType.includes(\"text/event-stream\") && response.body) {\n // Tee the upstream Web stream: one branch goes untouched to the client,\n // the other is consumed by an inspector that extracts usage / responseId.\n const [clientStream, inspectStream] = response.body.tee();\n const requestResponseLogId = (response as any).requestResponseLogId as\n | string\n | undefined;\n\n processedResponse = new Response(clientStream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n\n (processedResponse as any).baseUrl = (response as any).baseUrl;\n (processedResponse as any).token = (response as any).token;\n (processedResponse as any).requestResponseLogId = requestResponseLogId;\n\n usagePromise = inspectSSEWebStream(\n inspectStream,\n (usage) => {\n capturedUsage = usage;\n (processedResponse as any).usage = usage;\n },\n (responseId) => {\n capturedResponseId = responseId;\n (processedResponse as any).requestId = responseId;\n },\n {\n onRawChunk: (_chunk, sequence, text) => {\n void this.requestResponseLogSink?.logResponseChunk?.(\n requestResponseLogId,\n sequence,\n text\n );\n },\n }\n ).then(async (result) => {\n await this.requestResponseLogSink?.logResponseEnd?.(requestResponseLogId);\n return result;\n }).catch(async (error) => {\n await this.requestResponseLogSink?.logResponseError?.(requestResponseLogId, error);\n throw error;\n });\n\n (processedResponse as any).usagePromise = usagePromise;\n }\n\n return {\n response: processedResponse,\n tokenUsed,\n baseUrlUsed,\n tokenBalanceInSats,\n tokenBalanceUnknown: initialTokenBalanceUnknown,\n modelId,\n capturedUsage,\n capturedResponseId,\n clientApiKey,\n usagePromise,\n };\n }\n\n /**\n * Extract clientApiKey from Authorization Bearer token if present\n */\n private _extractClientApiKey(\n headers: Record<string, string>\n ): string | undefined {\n const authHeader = headers[\"Authorization\"] || headers[\"authorization\"];\n if (authHeader?.startsWith(\"Bearer \")) {\n const extractedKey = authHeader.slice(7);\n return extractedKey;\n }\n return undefined;\n }\n\n /**\n * Make the API request with failover support\n */\n private async _makeRequest(params: {\n path: string;\n method: string;\n body?: unknown;\n selectedModel?: Model;\n baseUrl: string;\n mintUrl: string;\n token: string;\n requiredSats: number;\n maxTokens?: number;\n headers: Record<string, string>;\n baseHeaders: Record<string, string>;\n retryCount?: number;\n }): Promise<Response> {\n const { path, method, body, baseUrl, token, headers } = params;\n\n try {\n const url = `${baseUrl.replace(/\\/$/, \"\")}${path}`;\n const requestBodyText =\n body === undefined || method === \"GET\" ? undefined : JSON.stringify(body);\n const requestLogId = await this.requestResponseLogSink?.logRequest?.({\n method,\n url,\n path,\n baseUrl,\n headers,\n body,\n rawBody: requestBodyText,\n });\n\n if (this.mode === \"xcashu\") this._log(\"DEBUG\", \"HEADERS,\", headers);\n const response = await fetch(url, {\n method,\n headers,\n body: requestBodyText,\n });\n if (this.mode === \"xcashu\") this._log(\"DEBUG\", \"response,\", response);\n\n (response as any).baseUrl = baseUrl;\n (response as any).token = token;\n (response as any).requestResponseLogId = requestLogId;\n await this.requestResponseLogSink?.logResponseStart?.(requestLogId, response);\n\n const contentType = response.headers.get(\"content-type\") || \"\";\n\n if (!response.ok) {\n void this.requestResponseLogSink?.logResponseBody?.(requestLogId, response.clone());\n const requestId =\n response.headers.get(\"x-routstr-request-id\") || undefined;\n let bodyText: string | undefined;\n try {\n bodyText = await response.text();\n } catch (e) {\n bodyText = undefined;\n }\n return await this._handleErrorResponse(\n params,\n token,\n response.status,\n requestId,\n this.mode === \"xcashu\"\n ? (response.headers.get(\"x-cashu\") ?? undefined)\n : undefined,\n bodyText,\n params.retryCount ?? 0\n );\n }\n\n if (!contentType.includes(\"text/event-stream\")) {\n void this.requestResponseLogSink?.logResponseBody?.(requestLogId, response.clone());\n }\n\n return response;\n } catch (error: any) {\n // Handle network errors with failover\n if (isNetworkErrorMessage(error?.message || \"\")) {\n return await this._handleErrorResponse(\n params,\n token,\n -1, // just for Network Error to skip all statuses\n undefined,\n undefined,\n undefined,\n params.retryCount ?? 0\n );\n // return await this._handleNetworkError(error, params);\n }\n throw error;\n }\n }\n\n /**\n * Handle error responses with failover\n */\n private async _handleErrorResponse(\n params: {\n path: string;\n method: string;\n body?: unknown;\n selectedModel?: Model;\n baseUrl: string;\n mintUrl: string;\n token: string;\n requiredSats: number;\n maxTokens?: number;\n headers: Record<string, string>;\n baseHeaders: Record<string, string>;\n },\n token: string,\n status: number,\n requestId?: string,\n xCashuRefundToken?: string,\n responseBody?: string,\n retryCount: number = 0\n ): Promise<Response> {\n const MAX_RETRIES_PER_PROVIDER = 2;\n const { path, method, body, selectedModel, baseUrl, mintUrl } = params;\n let tryNextProvider: boolean = false;\n\n const errorMessage = responseBody;\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: status=${status}, baseUrl=${baseUrl}, mode=${this.mode}, token preview=${token}, requestId=${requestId}, errorMessage=${errorMessage}`\n );\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Attempting to receive/restore token for ${baseUrl}`\n );\n if (params.token.startsWith(\"cashu\")) {\n const receiveResult = await this.cashuSpender.receiveToken(\n params.token\n );\n if (receiveResult.success) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Token restored successfully, amount=${receiveResult.amount}`\n );\n tryNextProvider = true;\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Failed to receive token: ${receiveResult.message}`\n );\n }\n }\n\n if (this.mode === \"xcashu\") {\n if (xCashuRefundToken) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Attempting to receive xcashu refund token, preview=${xCashuRefundToken.substring(0, 20)}...`\n );\n const receiveResult =\n await this.cashuSpender.receiveToken(xCashuRefundToken);\n if (receiveResult.success) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: xcashu refund received, amount=${receiveResult.amount}`\n );\n tryNextProvider = true;\n } else {\n this._log(\n \"ERROR\",\n `[xcashu] Failed to receive refund token: ${receiveResult.message}`\n );\n throw new ProviderError(\n baseUrl,\n status,\n \"[xcashu] Failed to receive refund token\",\n requestId\n );\n }\n } else {\n if (!tryNextProvider)\n throw new ProviderError(\n baseUrl,\n status,\n \"[xcashu] Failed to receive refund token\",\n requestId\n );\n }\n }\n\n if (status === 402 && !tryNextProvider && this.mode === \"apikeys\") {\n this.storageAdapter.getApiKey(baseUrl);\n\n let topupAmount = params.requiredSats;\n\n try {\n const currentBalanceInfo = await this.balanceManager.getTokenBalance(\n params.token,\n baseUrl\n );\n if (currentBalanceInfo.balanceUnknown) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Current balance unknown for ${baseUrl}; using default topup amount=${topupAmount}`\n );\n } else {\n const currentBalance =\n currentBalanceInfo.unit === \"msat\"\n ? currentBalanceInfo.amount / 1000\n : currentBalanceInfo.amount;\n const reservedBalance =\n currentBalanceInfo.unit === \"msat\"\n ? (currentBalanceInfo.reserved ?? 0) / 1000\n : (currentBalanceInfo.reserved ?? 0);\n\n const shortfall = Math.max(\n 0,\n params.requiredSats - currentBalance + reservedBalance\n );\n topupAmount =\n shortfall > 0.21 * params.requiredSats\n ? shortfall\n : 0.21 * params.requiredSats;\n\n this._log(\n \"DEBUG\",\n `The shortfall is: ${shortfall}. requiredSats: ${params.requiredSats}. Current Balance: ${currentBalance}. Reserved Balance: ${reservedBalance}. Available Balance: ${currentBalance - reservedBalance}`\n );\n }\n } catch (e) {\n this._log(\n \"WARN\",\n \"Could not get current token balance for topup calculation:\",\n e\n );\n }\n\n const topupResult = await this.balanceManager.topUp({\n mintUrl,\n baseUrl,\n amount: topupAmount * TOPUP_MARGIN,\n token: params.token,\n });\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Topup result for ${baseUrl}: success=${topupResult.success}, message=${topupResult.message}`\n );\n\n if (!topupResult.success) {\n const message = topupResult.message || \"\";\n if (message.includes(\"Insufficient balance\")) {\n const needMatch = message.match(/need (\\d+)/);\n const haveMatch = message.match(/have (\\d+)/);\n const required = needMatch\n ? parseInt(needMatch[1], 10)\n : params.requiredSats;\n const available = haveMatch ? parseInt(haveMatch[1], 10) : 0;\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Insufficient balance, need=${required}, have=${available}`\n );\n throw new InsufficientBalanceError(\n required,\n available,\n 0,\n \"\",\n message\n );\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Topup failed with non-insufficient-balance error, will try next provider`\n );\n tryNextProvider = true;\n }\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Topup successful, will retry with new token`\n );\n }\n if (!tryNextProvider) {\n if (retryCount < MAX_RETRIES_PER_PROVIDER) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Retrying 402 (attempt ${retryCount + 1}/${MAX_RETRIES_PER_PROVIDER})`\n );\n return this._makeRequest({\n ...params,\n token: params.token,\n headers: this._withAuthHeader(params.baseHeaders, params.token),\n retryCount: retryCount + 1,\n });\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: 402 retry limit reached (${retryCount}/${MAX_RETRIES_PER_PROVIDER}), failing over to next provider`\n );\n tryNextProvider = true;\n }\n }\n }\n\n const isInsufficientBalance413 =\n status === 413 && responseBody?.includes(\"Insufficient balance\");\n\n if (\n isInsufficientBalance413 &&\n !tryNextProvider &&\n this.mode === \"apikeys\"\n ) {\n let retryToken = params.token;\n\n try {\n const latestBalanceInfo = await this.balanceManager.getTokenBalance(\n params.token,\n baseUrl\n );\n\n // Handle invalid/expired API key - delete and fail over\n if (latestBalanceInfo.isInvalidApiKey) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Invalid API key (proofs already spent), removing for ${baseUrl}`\n );\n this.storageAdapter.removeApiKey(baseUrl);\n tryNextProvider = true;\n } else {\n const latestTokenBalance = latestBalanceInfo.balanceUnknown\n ? undefined\n : latestBalanceInfo.unit === \"msat\"\n ? latestBalanceInfo.amount / 1000\n : latestBalanceInfo.amount;\n\n if (latestBalanceInfo.apiKey) {\n const storedApiKeyEntry = this.storageAdapter.getApiKey(baseUrl);\n if (storedApiKeyEntry?.key !== latestBalanceInfo.apiKey) {\n if (storedApiKeyEntry) {\n this.storageAdapter.removeApiKey(baseUrl);\n }\n this.storageAdapter.setApiKey(baseUrl, latestBalanceInfo.apiKey);\n }\n retryToken = latestBalanceInfo.apiKey;\n }\n\n if (latestTokenBalance !== undefined && latestTokenBalance >= 0) {\n this.storageAdapter.updateApiKeyBalance(\n baseUrl,\n latestTokenBalance\n );\n }\n }\n } catch (error) {\n this._log(\n \"WARN\",\n `[RoutstrClient] _handleErrorResponse: Failed to refresh API key after 413 insufficient balance for ${baseUrl}`,\n error\n );\n }\n\n if (retryCount < MAX_RETRIES_PER_PROVIDER) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Retrying 413 (attempt ${retryCount + 1}/${MAX_RETRIES_PER_PROVIDER})`\n );\n return this._makeRequest({\n ...params,\n token: retryToken,\n headers: this._withAuthHeader(params.baseHeaders, retryToken),\n retryCount: retryCount + 1,\n });\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: 413 retry limit reached (${retryCount}/${MAX_RETRIES_PER_PROVIDER}), failing over to next provider`\n );\n tryNextProvider = true;\n }\n }\n\n if (status === 401 && this.mode === \"apikeys\") {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Checking balance for ${baseUrl}, key preview=${token}`\n );\n const latestBalanceInfo = await this.balanceManager.getTokenBalance(\n token,\n baseUrl\n );\n if (latestBalanceInfo.isInvalidApiKey) {\n this.storageAdapter.removeApiKey(baseUrl);\n tryNextProvider = true;\n }\n }\n\n if (\n (status === 401 ||\n status === 403 ||\n status === 404 ||\n status === 413 ||\n status === 400 ||\n status === 429 ||\n status === 500 ||\n status === 502 ||\n status === 503 ||\n status === 504 ||\n status === 521) &&\n !tryNextProvider\n ) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Status ${status} (${status === 429 ? \"rate limited\" : \"auth/server error\"}), attempting refund for ${baseUrl}, mode=${this.mode}`\n );\n if (this.mode === \"apikeys\") {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Attempting API key refund for ${baseUrl}, key preview=${token}`\n );\n const latestBalanceInfo = await this.balanceManager.getTokenBalance(\n token,\n baseUrl\n );\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Initial API key balance: ${latestBalanceInfo.amount}`\n );\n const refundResult = await this.balanceManager.refundApiKey({\n mintUrl,\n baseUrl,\n apiKey: token,\n forceRefund: true,\n });\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: API key refund result: success=${refundResult.success}, message=${refundResult.message}`\n );\n if (\n !refundResult.success &&\n latestBalanceInfo.amount > 0 &&\n !latestBalanceInfo.balanceUnknown\n ) {\n throw new ProviderError(\n baseUrl,\n status,\n refundResult.message ?? \"Unknown error\"\n );\n }\n }\n }\n\n this.providerManager.markFailed(baseUrl);\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Marked provider ${baseUrl} as failed`\n );\n\n if (!selectedModel) {\n throw new ProviderError(\n baseUrl,\n status,\n \"Funny, no selected model. HMM. \"\n );\n }\n\n const nextProvider = this.providerManager.findNextBestProvider(\n selectedModel.id,\n baseUrl\n );\n\n if (nextProvider) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Failing over to next provider: ${nextProvider}, model: ${selectedModel.id}`\n );\n // Get new model for this provider\n const newModel =\n (await this.providerManager.getModelForProvider(\n nextProvider,\n selectedModel.id\n )) ?? selectedModel;\n\n const messagesForPricing = Array.isArray(\n (body as { messages?: unknown })?.messages\n )\n ? ((body as { messages?: unknown }).messages as any[])\n : [];\n\n const newRequiredSats = this.providerManager.getRequiredSatsForModel(\n newModel,\n messagesForPricing,\n params.maxTokens\n );\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Creating new token for failover provider ${nextProvider}, required sats: ${newRequiredSats}`\n );\n const spendResult = await this._spendToken({\n mintUrl,\n amount: newRequiredSats,\n baseUrl: nextProvider,\n });\n\n // Retry with new provider (reset retry count). Attach the balance that\n // was observed before the retry request so callers do not have to query\n // after the provider may already have charged the request.\n const retryResponse = await this._makeRequest({\n ...params,\n path,\n method,\n body,\n baseUrl: nextProvider,\n selectedModel: newModel,\n token: spendResult.token!,\n requiredSats: newRequiredSats,\n headers: this._withAuthHeader(params.baseHeaders, spendResult.token!),\n retryCount: 0,\n });\n (retryResponse as any).initialTokenBalanceInSats =\n spendResult.tokenBalanceUnit === \"msat\"\n ? spendResult.tokenBalance / 1000\n : spendResult.tokenBalance;\n (retryResponse as any).initialTokenBalanceUnknown =\n spendResult.tokenBalanceUnknown;\n return retryResponse;\n }\n\n // No more providers to try\n throw new FailoverError(\n baseUrl,\n Array.from(this.providerManager.getFailedProviders())\n );\n }\n\n /**\n * Handle post-response balance update for all modes\n */\n private async _handlePostResponseBalanceUpdate(params: {\n token: string;\n baseUrl: string;\n mintUrl: string;\n initialTokenBalance: number;\n initialTokenBalanceUnknown?: boolean;\n fallbackSatsSpent?: number;\n response?: Response;\n modelId?: string;\n usage?: UsageTrackingData;\n requestId?: string;\n clientApiKey?: string;\n }): Promise<number> {\n const {\n token,\n baseUrl,\n mintUrl,\n initialTokenBalance,\n initialTokenBalanceUnknown,\n fallbackSatsSpent,\n response,\n modelId,\n usage,\n requestId,\n clientApiKey,\n } = params;\n\n let satsSpent: number = initialTokenBalance;\n\n if (this.mode === \"xcashu\" && response) {\n const refundToken = response.headers.get(\"x-cashu\") ?? undefined;\n if (refundToken) {\n const receiveResult =\n await this.cashuSpender.receiveToken(refundToken);\n if (receiveResult.success) {\n // Remove the spent token from storage\n this.storageAdapter.removeXcashuToken(baseUrl, token);\n satsSpent =\n initialTokenBalance -\n receiveResult.amount * (receiveResult.unit == \"sat\" ? 1 : 1000);\n } else {\n this._log(\n \"ERROR\",\n `[xcashu] Failed to receive refund token: ${receiveResult.message}`\n );\n }\n }\n } else if (this.mode === \"apikeys\") {\n try {\n const latestBalanceInfo = await this.balanceManager.getTokenBalance(\n token,\n baseUrl\n );\n this._log(\n \"DEBUG\",\n \"LATEST Balance\",\n latestBalanceInfo.amount,\n latestBalanceInfo.reserved,\n latestBalanceInfo.apiKey,\n baseUrl\n );\n const latestTokenBalance = latestBalanceInfo.balanceUnknown\n ? undefined\n : latestBalanceInfo.unit === \"msat\"\n ? latestBalanceInfo.amount / 1000\n : latestBalanceInfo.amount;\n\n const storedApiKeyEntry = this.storageAdapter.getApiKey(baseUrl);\n if (\n storedApiKeyEntry?.key.startsWith(\"cashu\") &&\n latestBalanceInfo.apiKey\n ) {\n this.storageAdapter.removeApiKey(baseUrl);\n this.storageAdapter.setApiKey(baseUrl, latestBalanceInfo.apiKey);\n }\n if (latestTokenBalance !== undefined) {\n this.storageAdapter.updateApiKeyBalance(baseUrl, latestTokenBalance);\n }\n\n satsSpent =\n latestTokenBalance !== undefined && !initialTokenBalanceUnknown\n ? Math.max(0, initialTokenBalance - latestTokenBalance)\n : (fallbackSatsSpent ?? usage?.satsCost ?? 0);\n } catch (e) {\n this._log(\"WARN\", \"Could not get updated API key balance:\", e);\n satsSpent = fallbackSatsSpent ?? usage?.satsCost ?? 0;\n }\n }\n\n await this._trackResponseUsage({\n token,\n baseUrl,\n response,\n modelId,\n satsSpent,\n usage,\n requestId,\n clientApiKey,\n });\n\n // Fire-and-forget async spinoff - does not block\n (async () => {\n try {\n // Refund all xcashu tokens\n // const xcashuResults =\n // await this.cashuSpender.refundXcashuTokens(mintUrl);\n // this._log(\"DEBUG\", \"Refund xcashu tokens results:\", xcashuResults);\n\n // Also refund API keys (apikeys mode) DISABLED FOR NOW\n // const results = await this.cashuSpaender.refundProviders(mintUrl);\n } catch (error) {\n this._log(\"ERROR\", \"Failed to refund providers:\", error);\n }\n })();\n\n return satsSpent;\n }\n\n private async _trackResponseUsage(params: {\n token: string;\n baseUrl: string;\n response?: Response;\n modelId?: string;\n satsSpent: number;\n usage?: UsageTrackingData;\n requestId?: string;\n clientApiKey?: string;\n }): Promise<void> {\n const {\n token,\n baseUrl,\n response,\n modelId,\n satsSpent,\n usage: providedUsage,\n requestId: providedRequestId,\n clientApiKey,\n } = params;\n\n if (!response || !modelId) {\n return;\n }\n\n try {\n let usage = providedUsage;\n let requestId = providedRequestId;\n\n if (!usage || !requestId) {\n const contentType = response.headers.get(\"content-type\") || \"\";\n\n if (contentType.includes(\"text/event-stream\")) {\n usage = usage ?? (response as any).usage;\n requestId =\n requestId ??\n (response as any).requestId ??\n response.headers.get(\"x-routstr-request-id\") ??\n undefined;\n\n if (!usage) {\n return;\n }\n } else {\n const cloned = response.clone();\n const responseBody = await cloned.json();\n usage =\n usage ??\n extractUsageFromResponseBody(responseBody, satsSpent) ??\n undefined;\n requestId =\n requestId ??\n extractResponseId(responseBody) ??\n response.headers.get(\"x-routstr-request-id\") ??\n undefined;\n }\n }\n\n if (!usage) {\n return;\n }\n\n const finalRequestId = requestId || \"unknown\";\n\n const store = this.sdkStore ?? (await getDefaultSdkStore());\n const state = store.getState();\n\n // Use clientApiKey for matching if provided, otherwise fall back to token\n const matchKey = clientApiKey ?? token;\n const matchingClient = state.clientIds.find(\n (client) => client.apiKey === matchKey\n );\n\n const entryId =\n finalRequestId === \"unknown\"\n ? `req-${Date.now()}-${modelId}`\n : finalRequestId;\n\n const usageTracking =\n this.usageTrackingDriver ?? getDefaultUsageTrackingDriver();\n\n const entry = {\n id: entryId,\n timestamp: Date.now(),\n modelId,\n baseUrl,\n requestId: finalRequestId,\n client: matchingClient?.clientId,\n ...usage,\n };\n\n // For xcashu mode, use satsSpent directly for satsCost instead of calculating from usage\n if (this.mode === \"xcashu\") {\n entry.satsCost = satsSpent;\n }\n\n await usageTracking.append(entry);\n } catch (error) {\n // Silently ignore tracking failures\n }\n }\n\n /**\n * Check wallet balance and throw if insufficient\n */\n private async _checkBalance(): Promise<void> {\n const balances = await this.walletAdapter.getBalances();\n const totalBalance = Object.values(balances).reduce((sum, v) => sum + v, 0);\n\n if (totalBalance <= 0) {\n throw new InsufficientBalanceError(1, 0);\n }\n }\n\n /**\n * Spend a token using CashuSpender with standardized error handling\n */\n private async _spendToken(params: {\n mintUrl: string;\n amount: number;\n baseUrl: string;\n }): Promise<{\n token: string;\n tokenBalance: number;\n tokenBalanceUnit: \"sat\" | \"msat\";\n tokenBalanceUnknown: boolean;\n }> {\n const { mintUrl, amount, baseUrl } = params;\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: mode=${this.mode}, amount=${amount}, baseUrl=${baseUrl}, mintUrl=${mintUrl}`\n );\n\n if (this.mode === \"apikeys\") {\n let parentApiKey = this.storageAdapter.getApiKey(baseUrl);\n if (!parentApiKey) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: No existing API key for ${baseUrl}, creating new one via Cashu`\n );\n const spendResult = await this.cashuSpender.spend({\n mintUrl: mintUrl,\n amount: amount * TOPUP_MARGIN,\n baseUrl: \"\",\n reuseToken: false,\n });\n\n if (!spendResult.token) {\n this._log(\n \"ERROR\",\n `[RoutstrClient] _spendToken: Failed to create Cashu token for API key creation, error:`,\n spendResult.error\n );\n throw new Error(\n `[RoutstrClient] _spendToken: Failed to create Cashu token for API key creation, error: ${spendResult.error}`\n );\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Cashu token created, token preview: ${spendResult.token}`\n );\n }\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Created API key for ${baseUrl}, key preview: ${spendResult.token}, balance: ${spendResult.balance}`\n );\n\n try {\n this.storageAdapter.setApiKey(baseUrl, spendResult.token);\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"ApiKey already exists\")\n ) {\n const receiveResult = await this.cashuSpender.receiveToken(\n spendResult.token\n );\n if (receiveResult.success) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Token restored successfully, amount=${receiveResult.amount}`\n );\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Token restore failed: ${receiveResult.message}`\n );\n }\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: API key already exists for ${baseUrl}, using existing key`\n );\n } else {\n throw error;\n }\n }\n parentApiKey = this.storageAdapter.getApiKey(baseUrl);\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Using existing API key for ${baseUrl}, key preview: ${parentApiKey.key}`\n );\n }\n\n let tokenBalance = 0;\n let tokenBalanceUnit: \"sat\" | \"msat\" = \"sat\";\n let tokenBalanceUnknown = false;\n\n const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();\n const distributionForBaseUrl = apiKeyDistribution.find(\n (d) => d.baseUrl === baseUrl\n );\n if (distributionForBaseUrl) {\n tokenBalance = distributionForBaseUrl.amount;\n }\n\n if (tokenBalance === 0 && parentApiKey) {\n try {\n const balanceInfo = await this.balanceManager.getTokenBalance(\n parentApiKey.key,\n baseUrl\n );\n tokenBalance = balanceInfo.amount;\n tokenBalanceUnit = balanceInfo.unit;\n tokenBalanceUnknown = Boolean(balanceInfo.balanceUnknown);\n } catch (e) {\n this._log(\"WARN\", \"Could not get initial API key balance:\", e);\n }\n }\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Returning token with balance=${tokenBalance} ${tokenBalanceUnit}`\n );\n\n return {\n token: parentApiKey?.key ?? \"\",\n tokenBalance,\n tokenBalanceUnit,\n tokenBalanceUnknown,\n };\n }\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Calling CashuSpender.spend for amount=${amount}, mintUrl=${mintUrl}, mode=${this.mode}`\n );\n const spendResult = await this.cashuSpender.spend({\n mintUrl,\n amount,\n baseUrl: \"\",\n reuseToken: false,\n });\n\n if (!spendResult.token) {\n this._log(\n \"ERROR\",\n `[RoutstrClient] _spendToken: CashuSpender.spend failed, error:`,\n spendResult.error\n );\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Cashu token created, token preview: ${spendResult.token}, balance: ${spendResult.balance} ${spendResult.unit ?? \"sat\"}`\n );\n // Store xcashu token using the storage adapter\n this.storageAdapter.addXcashuToken(baseUrl, spendResult.token);\n }\n\n return {\n token: spendResult.token!,\n tokenBalance: spendResult.balance,\n tokenBalanceUnit: spendResult.unit ?? \"sat\",\n tokenBalanceUnknown: false,\n };\n }\n\n /**\n * Build request headers with common defaults and dev mock controls\n */\n private _buildBaseHeaders(\n additionalHeaders: Record<string, string> = {},\n token?: string\n ): Record<string, string> {\n const headers: Record<string, string> = {\n ...additionalHeaders,\n \"Content-Type\": \"application/json\",\n };\n\n return headers;\n }\n\n /**\n * Attach auth headers using the active client mode\n */\n private _withAuthHeader(\n headers: Record<string, string>,\n token: string\n ): Record<string, string> {\n const nextHeaders = { ...headers };\n\n if (this.mode === \"xcashu\") {\n nextHeaders[\"X-Cashu\"] = token;\n } else {\n nextHeaders[\"Authorization\"] = `Bearer ${token}`;\n }\n\n return nextHeaders;\n }\n}\n","/**\n * StreamProcessor - Handles SSE streaming response parsing\n *\n * Handles:\n * - Line buffering for large payloads\n * - Content extraction from delta chunks\n * - Thinking/reasoning block extraction\n * - Image data merging and deduplication\n * - Usage statistics extraction\n * - Citations and annotations\n *\n * Extracted from utils/apiUtils.ts processStreamingResponse\n */\n\nimport type { StreamingResult, ImageData, AnnotationData } from \"../core/types\";\nimport { extractUsageFromSSEJson, toUsageStats } from \"./usage\";\n\n/**\n * Callbacks for streaming updates\n */\nexport interface StreamCallbacks {\n /** Called when new content arrives */\n onContent: (content: string) => void;\n /** Called when thinking content arrives */\n onThinking: (thinking: string) => void;\n}\n\n/**\n * StreamProcessor parses SSE streaming responses\n */\nexport class StreamProcessor {\n private accumulatedContent = \"\";\n private accumulatedThinking = \"\";\n private accumulatedImages: ImageData[] = [];\n private isInThinking = false;\n private isInContent = false;\n\n /**\n * Process a streaming response\n */\n async process(\n response: Response,\n callbacks: StreamCallbacks,\n modelId?: string\n ): Promise<StreamingResult> {\n if (!response.body) {\n throw new Error(\"Response body is not available\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder(\"utf-8\");\n let buffer = \"\";\n\n // Reset state\n this.accumulatedContent = \"\";\n this.accumulatedThinking = \"\";\n this.accumulatedImages = [];\n this.isInThinking = false;\n this.isInContent = false;\n\n // Result accumulators\n let usage: StreamingResult[\"usage\"];\n let model: string | undefined;\n let finish_reason: string | undefined;\n let citations: string[] | undefined;\n let annotations: AnnotationData[] | undefined;\n let responseId: string | undefined;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n buffer += chunk;\n\n // Process complete lines\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\"; // Keep incomplete line in buffer\n\n for (const line of lines) {\n const parsed = this._parseLine(line);\n if (!parsed) continue;\n\n // Handle content delta\n if (parsed.content) {\n this._handleContent(parsed.content, callbacks, modelId);\n }\n\n // Handle reasoning/thinking\n if (parsed.reasoning) {\n this._handleThinking(parsed.reasoning, callbacks);\n }\n\n // Extract metadata\n if (parsed.usage) {\n usage = parsed.usage;\n }\n if (parsed.model) {\n model = parsed.model;\n }\n if (parsed.finish_reason) {\n finish_reason = parsed.finish_reason;\n }\n if (parsed.responseId) {\n responseId = parsed.responseId;\n }\n if (parsed.citations) {\n citations = parsed.citations;\n }\n if (parsed.annotations) {\n annotations = parsed.annotations;\n }\n\n // Handle images\n if (parsed.images) {\n this._mergeImages(parsed.images);\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n return {\n content: this.accumulatedContent,\n thinking: this.accumulatedThinking || undefined,\n images: this.accumulatedImages.length > 0 ? this.accumulatedImages : undefined,\n usage,\n model,\n responseId,\n finish_reason,\n citations,\n annotations,\n };\n }\n\n /**\n * Parse a single SSE line\n */\n private _parseLine(line: string): {\n content?: string;\n reasoning?: string;\n usage?: StreamingResult[\"usage\"];\n model?: string;\n finish_reason?: string;\n citations?: string[];\n annotations?: AnnotationData[];\n images?: ImageData[];\n responseId?: string;\n } | null {\n if (!line.trim()) return null;\n\n // SSE data lines start with \"data: \"\n if (!line.startsWith(\"data: \")) {\n // Show \"Generating...\" for non-data lines if no content yet\n return null;\n }\n\n const jsonData = line.slice(6);\n\n if (jsonData === \"[DONE]\") {\n return null;\n }\n\n try {\n const parsed = JSON.parse(jsonData);\n const result: ReturnType<typeof this._parseLine> = {};\n\n // Extract content delta\n if (parsed.choices?.[0]?.delta?.content) {\n result.content = parsed.choices[0].delta.content;\n }\n\n // Extract reasoning (OpenRouter style)\n if (parsed.choices?.[0]?.delta?.reasoning) {\n result.reasoning = parsed.choices[0].delta.reasoning;\n }\n\n // Extract usage (usually in final chunk)\n // extractUsageFromSSEJson handles both usage chunks and standalone cost chunks\n const extractedUsage = extractUsageFromSSEJson(parsed);\n if (extractedUsage) {\n result.usage = toUsageStats(extractedUsage);\n } else if (parsed.usage) {\n // Fallback: raw usage without cost\n result.usage = {\n total_tokens: parsed.usage.total_tokens ?? parsed.usage.input_tokens + parsed.usage.output_tokens,\n prompt_tokens: parsed.usage.prompt_tokens ?? parsed.usage.input_tokens,\n completion_tokens: parsed.usage.completion_tokens ?? parsed.usage.output_tokens,\n };\n }\n\n if (parsed.id) {\n result.responseId = parsed.id;\n }\n\n // Extract model info\n if (parsed.model) {\n result.model = parsed.model;\n }\n\n // Extract citations\n if (parsed.citations) {\n result.citations = parsed.citations;\n }\n\n // Extract annotations\n if (parsed.annotations) {\n result.annotations = parsed.annotations;\n }\n\n // Extract finish reason\n if (parsed.choices?.[0]?.finish_reason) {\n result.finish_reason = parsed.choices[0].finish_reason;\n }\n\n // Extract images (from message or delta)\n const images =\n parsed.choices?.[0]?.message?.images ||\n parsed.choices?.[0]?.delta?.images;\n if (images && Array.isArray(images)) {\n result.images = images;\n }\n\n return result;\n } catch {\n // Swallow parse errors for streaming chunks\n return null;\n }\n }\n\n /**\n * Handle content delta with thinking support\n */\n private _handleContent(\n content: string,\n callbacks: StreamCallbacks,\n modelId?: string\n ): void {\n // If we were in thinking mode and now got content, close thinking tag\n if (this.isInThinking && !this.isInContent) {\n this.accumulatedThinking += \"</thinking>\";\n callbacks.onThinking(this.accumulatedThinking);\n this.isInThinking = false;\n this.isInContent = true;\n }\n\n // For models that use <thinking> tags inline\n if (modelId) {\n this._extractThinkingFromContent(content, callbacks);\n } else {\n this.accumulatedContent += content;\n }\n\n callbacks.onContent(this.accumulatedContent);\n }\n\n /**\n * Handle thinking/reasoning content\n */\n private _handleThinking(reasoning: string, callbacks: StreamCallbacks): void {\n if (!this.isInThinking) {\n this.accumulatedThinking += \"<thinking> \";\n this.isInThinking = true;\n }\n this.accumulatedThinking += reasoning;\n callbacks.onThinking(this.accumulatedThinking);\n }\n\n /**\n * Extract thinking blocks from content (for models with inline thinking)\n */\n private _extractThinkingFromContent(\n content: string,\n callbacks: StreamCallbacks\n ): void {\n // Simple extraction - models that wrap thinking in <thinking> tags\n const parts = content.split(/(<thinking>|<\\/thinking>)/);\n\n for (const part of parts) {\n if (part === \"<thinking>\") {\n this.isInThinking = true;\n if (!this.accumulatedThinking.includes(\"<thinking>\")) {\n this.accumulatedThinking += \"<thinking> \";\n }\n } else if (part === \"</thinking>\") {\n this.isInThinking = false;\n this.accumulatedThinking += \"</thinking>\";\n } else if (this.isInThinking) {\n this.accumulatedThinking += part;\n } else {\n this.accumulatedContent += part;\n }\n }\n }\n\n /**\n * Merge images into accumulated array, avoiding duplicates\n */\n private _mergeImages(newImages: ImageData[]): void {\n for (const img of newImages) {\n const newUrl = img.image_url?.url;\n const existingIndex = this.accumulatedImages.findIndex((existing) => {\n const existingUrl = existing.image_url?.url;\n if (newUrl && existingUrl) {\n return existingUrl === newUrl;\n }\n if (img.index !== undefined && existing.index !== undefined) {\n return existing.index === img.index;\n }\n return false;\n });\n\n if (existingIndex === -1) {\n this.accumulatedImages.push(img);\n } else {\n this.accumulatedImages[existingIndex] = img;\n }\n }\n }\n}\n","import type { Message, Model, TransactionHistory, StreamingResult, SdkLogger } from \"../core/types\";\nimport type { StreamingCallbacks } from \"../wallet/interfaces\";\nimport { StreamProcessor } from \"./StreamProcessor\";\nimport type { AlertLevel, RoutstrClientMode } from \"./RoutstrClient\";\n\n/**\n * Options for fetching AI response\n */\nexport interface FetchOptions {\n messageHistory: Message[];\n selectedModel: Model;\n baseUrl: string;\n mintUrl: string;\n balance: number;\n transactionHistory: TransactionHistory[];\n maxTokens?: number;\n headers?: Record<string, string>;\n}\n\ninterface FetchAIResponseClient {\n routeRequest(params: {\n path: string;\n method: string;\n body?: unknown;\n headers?: Record<string, string>;\n baseUrl: string;\n mintUrl: string;\n modelId?: string;\n }): Promise<Response>;\n getMode(): RoutstrClientMode;\n}\n\nexport interface FetchAIResponseDeps {\n client: FetchAIResponseClient;\n alertLevel: AlertLevel;\n logger: SdkLogger;\n getPendingCashuTokenAmount?: () => number;\n}\n\n/**\n * Fetch an AI chat/completions response using RoutstrClient.routeRequest for\n * payment/auth/failover/accounting, then consume the returned SSE stream and\n * drive the legacy streaming callbacks.\n */\nexport async function fetchAIResponse(\n options: FetchOptions,\n callbacks: StreamingCallbacks,\n deps: FetchAIResponseDeps\n): Promise<void> {\n const {\n messageHistory,\n selectedModel,\n baseUrl,\n mintUrl,\n maxTokens,\n headers,\n } = options;\n\n try {\n const apiMessages = await convertMessages(messageHistory);\n\n callbacks.onPaymentProcessing?.(true);\n\n callbacks.onTokenCreated?.(deps.getPendingCashuTokenAmount?.() ?? 0);\n\n const body: any = {\n model: selectedModel.id,\n messages: apiMessages,\n stream: true,\n };\n\n if (maxTokens !== undefined) {\n body.max_tokens = maxTokens;\n }\n\n if (selectedModel?.name?.startsWith(\"OpenAI:\")) {\n body.tools = [{ type: \"web_search\" }];\n }\n\n const response = await deps.client.routeRequest({\n path: \"/v1/chat/completions\",\n method: \"POST\",\n body,\n headers,\n baseUrl,\n mintUrl,\n modelId: selectedModel.id,\n });\n\n if (!response.body) {\n throw new Error(\"Response body is not available\");\n }\n\n if (response.status !== 200) {\n throw new Error(`${response.status} ${response.statusText}`);\n }\n\n const streamProcessor = new StreamProcessor();\n const streamingResult = await streamProcessor.process(\n response,\n {\n onContent: callbacks.onStreamingUpdate,\n onThinking: callbacks.onThinkingUpdate,\n },\n selectedModel.id\n );\n\n if (streamingResult.finish_reason === \"content_filter\") {\n callbacks.onMessageAppend({\n role: \"assistant\",\n content: \"Your request was denied due to content filtering.\",\n });\n } else if (\n streamingResult.content ||\n (streamingResult.images && streamingResult.images.length > 0)\n ) {\n const message = await createAssistantMessage(streamingResult);\n callbacks.onMessageAppend(message);\n } else {\n callbacks.onMessageAppend({\n role: \"system\",\n content: \"The provider did not respond to this request.\",\n });\n }\n\n callbacks.onStreamingUpdate(\"\");\n callbacks.onThinkingUpdate(\"\");\n\n // routeRequest owns usage extraction + balance finalization. For streaming\n // responses it runs finalization in the background while this function\n // consumes the client-facing stream. Consumers that need exact cost can read\n // the persisted usage entry later.\n } catch (error) {\n handleError(error, callbacks, deps.alertLevel, deps.logger);\n } finally {\n callbacks.onPaymentProcessing?.(false);\n }\n}\n\nasync function convertMessages(messages: Message[]): Promise<any[]> {\n return Promise.all(\n messages\n .filter((m) => m.role !== \"system\")\n .map(async (m) => ({\n role: m.role,\n content: typeof m.content === \"string\" ? m.content : m.content,\n }))\n );\n}\n\nasync function createAssistantMessage(result: StreamingResult): Promise<Message> {\n if (result.images && result.images.length > 0) {\n const content: any[] = [];\n\n if (result.content) {\n content.push({\n type: \"text\",\n text: result.content,\n thinking: result.thinking,\n citations: result.citations,\n annotations: result.annotations,\n });\n }\n\n for (const img of result.images) {\n content.push({\n type: \"image_url\",\n image_url: {\n url: img.image_url.url,\n },\n });\n }\n\n return {\n role: \"assistant\",\n content,\n };\n }\n\n return {\n role: \"assistant\",\n content: result.content || \"\",\n };\n}\n\nfunction handleError(\n error: unknown,\n callbacks: StreamingCallbacks,\n alertLevel: AlertLevel,\n logger: SdkLogger\n): void {\n logger.error(\"[fetchAIResponse] Error occurred\", error);\n\n if (error instanceof Error) {\n const isStreamError =\n error.message.includes(\"Error in input stream\") ||\n error.message.includes(\"Load failed\");\n const modifiedErrorMsg = isStreamError\n ? \"AI stream was cut off, turn on Keep Active or please try again\"\n : error.message;\n\n logger.error(\n `[fetchAIResponse] Error type=${error.constructor.name}, message=${modifiedErrorMsg}, isStreamError=${isStreamError}`\n );\n\n callbacks.onMessageAppend({\n role: \"system\",\n content:\n \"Uncaught Error: \" +\n modifiedErrorMsg +\n (alertLevel === \"max\" ? \" | \" + error.stack : \"\"),\n });\n } else {\n callbacks.onMessageAppend({\n role: \"system\",\n content: \"Unknown Error: Please tag Routstr on Nostr and/or retry.\",\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../core/types.ts","../../core/errors.ts","../../wallet/AuditLogger.ts","../../wallet/tokenUtils.ts","../../wallet/CashuSpender.ts","../../wallet/BalanceManager.ts","../../utils/torUtils.ts","../../client/ProviderManager.ts","../../storage/drivers/localStorage.ts","../../storage/drivers/memory.ts","../../storage/keys.ts","../../storage/usageTracking/aggregate.ts","../../storage/usageTracking/indexedDB.ts","../../storage/usageTracking/memory.ts","../../storage/store.ts","../../storage/index.ts","../../client/usage.ts","../../client/sse.ts","../../client/TinfoilSecure.ts","../../client/RoutstrClient.ts","../../client/StreamProcessor.ts","../../client/fetchAIResponse.ts"],"names":["amount","unit","getDecodedToken","mintUrl","options","normalizeBaseUrl","matchesFilters","createStore","isBrowser","msats","cost","StringDecoder","Transform","spendResult"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Core types for the Routstr SDK\n * These types are shared across wallet and client modules\n */\n\nexport interface SdkLogger {\n log(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n debug(...args: unknown[]): void;\n child(prefix: string): SdkLogger;\n}\n\nfunction makeConsoleLogger(prefix?: string): SdkLogger {\n const fmt = (args: unknown[]) => (prefix ? [prefix, ...args] : args);\n return {\n log: (...args) => console.log(...fmt(args)),\n warn: (...args) => console.warn(...fmt(args)),\n error: (...args) => console.error(...fmt(args)),\n debug: (...args) => console.log(...fmt(args)),\n child: (p) => makeConsoleLogger(prefix ? `${prefix}:${p}` : p),\n };\n}\n\nexport const consoleLogger: SdkLogger = makeConsoleLogger();\n\nexport const noopLogger: SdkLogger = {\n log: () => {},\n warn: () => {},\n error: () => {},\n debug: () => {},\n child: () => noopLogger,\n};\n\nexport interface MessageContentType {\n type: \"text\" | \"image_url\" | \"file\";\n text?: string;\n image_url?: {\n url: string;\n storageId?: string;\n };\n file?: {\n url: string;\n name?: string;\n mimeType?: string;\n size?: number;\n };\n hidden?: boolean;\n thinking?: string;\n citations?: string[];\n}\n\nexport interface Message {\n role: string;\n content: string | MessageContentType[];\n _eventId?: string;\n _prevId?: string;\n _createdAt?: number;\n _modelId?: string;\n satsSpent?: number;\n}\n\nexport interface TransactionHistory {\n type: \"spent\" | \"mint\" | \"send\" | \"import\" | \"refund\";\n amount: number;\n timestamp: number;\n status: \"success\" | \"failed\";\n model?: string;\n message?: string;\n balance?: number;\n}\n\nexport interface ModelPricing {\n prompt: number;\n completion: number;\n request: number;\n image: number;\n web_search: number;\n internal_reasoning: number;\n}\n\nexport interface ModelSatsPricing extends ModelPricing {\n max_completion_cost: number;\n max_prompt_cost: number;\n max_cost: number;\n}\n\nexport interface ModelArchitecture {\n modality: string;\n input_modalities: readonly string[];\n output_modalities: readonly string[];\n tokenizer: string;\n instruct_type: string | null;\n}\n\nexport interface PerRequestLimits {\n readonly prompt_tokens?: number;\n readonly completion_tokens?: number;\n readonly requests_per_minute?: number;\n readonly images_per_minute?: number;\n readonly web_searches_per_minute?: number;\n readonly [key: string]: number | undefined;\n}\n\nexport interface Model {\n id: string;\n name: string;\n created?: number;\n description?: string;\n context_length?: number;\n architecture?: ModelArchitecture;\n pricing?: ModelPricing;\n sats_pricing: ModelSatsPricing;\n per_request_limits?: PerRequestLimits;\n}\n\n/**\n * Result from spending cashu tokens\n */\nexport interface SpendResult {\n token: string | null;\n status: \"success\" | \"failed\";\n balance: number;\n unit?: \"sat\" | \"msat\";\n error?: string;\n errorDetails?: {\n required: number;\n available: number;\n maxMintBalance: number;\n maxMintUrl: string;\n };\n}\n\n/**\n * Result from refund operations\n */\nexport interface RefundResult {\n success: boolean;\n refundedAmount?: number;\n message?: string;\n requestId?: string;\n}\n\n/**\n * Result from top up operations\n */\nexport interface TopUpResult {\n success: boolean;\n toppedUpAmount?: number;\n message?: string;\n requestId?: string;\n recoveredToken?: boolean;\n}\n\n/**\n * API error verdict for retry logic\n */\nexport interface APIErrorVerdict {\n retry: boolean;\n reason: string;\n newBaseUrl?: string; // New provider to retry with (for 50X errors)\n}\n\n/**\n * Image data from API response\n */\nexport interface ImageData {\n type: \"image_url\";\n image_url: {\n url: string;\n };\n index?: number;\n}\n\n/**\n * Annotation data from API response\n */\nexport interface AnnotationData {\n type: \"url_citation\";\n start_index: number;\n end_index: number;\n url: string;\n title: string;\n}\n\n/**\n * Usage statistics from API response\n */\nexport interface UsageStats {\n total_tokens?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n cost?: number;\n sats_cost?: number;\n}\n\n/**\n * Result from streaming response processing\n */\nexport interface StreamingResult {\n content: string;\n thinking?: string;\n images?: ImageData[];\n usage?: UsageStats;\n model?: string;\n responseId?: string;\n finish_reason?: string;\n citations?: string[];\n annotations?: AnnotationData[];\n}\n\n/**\n * Parameters for fetching AI response\n */\nexport interface FetchAIResponseParams {\n messageHistory: Message[];\n selectedModel: Model;\n baseUrl: string;\n mintUrl: string;\n balance: number;\n transactionHistory: TransactionHistory[];\n}\n\n/**\n * Candidate provider for failover\n */\nexport interface CandidateProvider {\n baseUrl: string;\n model: Model;\n cost: number;\n}\n\n/**\n * Mint selection result\n */\nexport interface MintSelection {\n selectedMintUrl: string | null;\n selectedMintBalance: number;\n}\n\n/**\n * Pending token entry\n */\nexport interface PendingTokenEntry {\n baseUrl: string;\n amount: number;\n}\n\n/**\n * Provider information from /v1/info endpoint\n */\nexport interface ProviderInfo {\n mints?: string[];\n [key: string]: any;\n}\n\n/**\n * Model discovery result\n */\nexport interface ModelDiscoveryResult {\n models: Model[];\n bestById: Map<string, { model: Model; base: string }>;\n totalProcessed: number;\n}\n\n/**\n * Mint discovery result\n */\nexport interface MintDiscoveryResult {\n mintsFromProviders: Record<string, string[]>;\n infoFromProviders: Record<string, ProviderInfo>;\n}\n","/**\n * Custom error classes for the Routstr SDK\n * Provides specific error types for different failure modes\n */\n\n/**\n * Error thrown when balance is insufficient for an operation\n */\nexport class InsufficientBalanceError extends Error {\n constructor(\n public required: number,\n public available: number,\n public maxMintBalance: number = 0,\n public maxMintUrl: string = \"\",\n customMessage?: string\n ) {\n super(\n customMessage ??\n (`Insufficient balance: need ${required} sats, have ${available} sats available. ` +\n (maxMintBalance > 0\n ? `Largest mint balance: ${maxMintBalance} sats from ${maxMintUrl}`\n : \"\"))\n );\n this.name = \"InsufficientBalanceError\";\n }\n}\n\n/**\n * Error thrown when a provider returns an error response\n */\nexport class ProviderError extends Error {\n constructor(\n public baseUrl: string,\n public statusCode: number,\n message: string,\n public requestId?: string\n ) {\n super(\n `Provider ${baseUrl} returned ${statusCode}: ${message}` +\n (requestId ? ` (Request ID: ${requestId})` : \"\")\n );\n this.name = \"ProviderError\";\n }\n}\n\n/**\n * Error thrown when a mint is unreachable\n */\nexport class MintUnreachableError extends Error {\n constructor(public mintUrl: string) {\n super(\n `Your mint ${mintUrl} is unreachable or is blocking your IP. Please try again later or switch mints.`\n );\n this.name = \"MintUnreachableError\";\n }\n}\n\n/**\n * Error thrown when a token operation fails\n */\nexport class TokenOperationError extends Error {\n constructor(\n message: string,\n public operation: \"send\" | \"receive\" | \"refund\",\n public mintUrl?: string\n ) {\n super(message);\n this.name = \"TokenOperationError\";\n }\n}\n\n/**\n * Error thrown when provider failover fails\n */\nexport class FailoverError extends Error {\n constructor(\n public originalProvider: string,\n public failedProviders: string[],\n message?: string\n ) {\n super(\n message ||\n `All providers failed. Original: ${originalProvider}, Failed: ${failedProviders.join(\", \")}`\n );\n this.name = \"FailoverError\";\n }\n}\n\n/**\n * Error thrown when streaming response processing fails\n */\nexport class StreamingError extends Error {\n constructor(\n message: string,\n public finishReason?: string,\n public accumulatedContent?: string\n ) {\n super(message);\n this.name = \"StreamingError\";\n }\n}\n\n/**\n * Error thrown when model is not found on a provider\n */\nexport class ModelNotFoundError extends Error {\n constructor(public modelId: string, public baseUrl: string) {\n super(`Model '${modelId}' not found on provider ${baseUrl}`);\n this.name = \"ModelNotFoundError\";\n }\n}\n\n/**\n * Error thrown when provider bootstrap fails\n */\nexport class ProviderBootstrapError extends Error {\n constructor(\n public failedProviders: string[],\n message?: string\n ) {\n super(\n message || `Failed to bootstrap providers. Tried: ${failedProviders.join(\", \")}`\n );\n this.name = \"ProviderBootstrapError\";\n }\n}\n\n/**\n * Error thrown when no providers are available\n */\nexport class NoProvidersAvailableError extends Error {\n constructor() {\n super(\"No providers are available for model discovery\");\n this.name = \"NoProvidersAvailableError\";\n }\n}\n\n/**\n * Error thrown when mint discovery fails\n */\nexport class MintDiscoveryError extends Error {\n constructor(\n public baseUrl: string,\n message?: string\n ) {\n super(message || `Failed to discover mints from provider ${baseUrl}`);\n this.name = \"MintDiscoveryError\";\n }\n}\n","/**\n * AuditLogger - Transaction audit logging utility\n * Writes JSON-formatted transaction logs to audit.log\n */\n\nexport interface AuditLogEntry {\n timestamp: string;\n action: \"spend\" | \"topup\" | \"refund\" | \"receive\" | \"balance_check\";\n totalBalance: number;\n providerBalances: Record<string, number>;\n mintBalances: Record<string, number>;\n amount?: number;\n mintUrl?: string;\n baseUrl?: string;\n status: \"success\" | \"failed\";\n details?: string;\n}\n\nexport class AuditLogger {\n private static instance: AuditLogger | null = null;\n\n static getInstance(): AuditLogger {\n if (!AuditLogger.instance) {\n AuditLogger.instance = new AuditLogger();\n }\n return AuditLogger.instance;\n }\n\n async log(entry: Omit<AuditLogEntry, \"timestamp\">): Promise<void> {\n const fullEntry: AuditLogEntry = {\n ...entry,\n timestamp: new Date().toISOString(),\n };\n\n const logLine = JSON.stringify(fullEntry) + \"\\n\";\n\n if (typeof window === \"undefined\") {\n try {\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n const logPath = path.join(process.cwd(), \"audit.log\");\n fs.appendFileSync(logPath, logLine);\n } catch (error) {\n console.error(\"[AuditLogger] Failed to write to file:\", error);\n }\n } else {\n console.log(\"[AUDIT]\", logLine.trim());\n }\n }\n\n async logBalanceSnapshot(\n action: AuditLogEntry[\"action\"],\n amounts: {\n totalBalance: number;\n providerBalances: Record<string, number>;\n mintBalances: Record<string, number>;\n },\n options?: {\n amount?: number;\n mintUrl?: string;\n baseUrl?: string;\n status?: \"success\" | \"failed\";\n details?: string;\n }\n ): Promise<void> {\n await this.log({\n action,\n totalBalance: amounts.totalBalance,\n providerBalances: amounts.providerBalances,\n mintBalances: amounts.mintBalances,\n amount: options?.amount,\n mintUrl: options?.mintUrl,\n baseUrl: options?.baseUrl,\n status: options?.status ?? \"success\",\n details: options?.details,\n });\n }\n}\n\nexport const auditLogger = AuditLogger.getInstance();\n","import type { MintSelection } from \"../core/types\";\n\nexport function isNetworkErrorMessage(message: string): boolean {\n return (\n message.includes(\"NetworkError when attempting to fetch resource\") ||\n message.includes(\"Failed to fetch\") ||\n message.includes(\"Load failed\") ||\n message.includes(\"ERR_TLS_CERT_ALTNAME_INVALID\") ||\n message.includes(\"ERR_TLS_CERT_NOT_YET_VALID\") ||\n message.includes(\"ERR_TLS_CERT_EXPIRED\") ||\n message.includes(\"UNABLE_TO_VERIFY_LEAF_SIGNATURE\") ||\n message.includes(\"SELF_SIGNED_CERT_IN_CHAIN\")\n );\n}\n\nexport function getBalanceInSats(\n balance: number,\n unit: \"sat\" | \"msat\" | string | undefined\n): number {\n return unit === \"msat\" ? balance / 1000 : balance;\n}\n\nexport function getTotalMintBalanceInSats(\n balances: Record<string, number>,\n units: Record<string, \"sat\" | \"msat\">\n): number {\n let total = 0;\n for (const mintUrl in balances) {\n total += getBalanceInSats(balances[mintUrl], units[mintUrl]);\n }\n return total;\n}\n\nexport function selectMintWithBalance(\n balances: Record<string, number>,\n units: Record<string, string>,\n amount: number,\n excludeMints: string[] = []\n): MintSelection {\n for (const mintUrl in balances) {\n if (excludeMints.includes(mintUrl)) {\n continue;\n }\n\n const balanceInSats = getBalanceInSats(balances[mintUrl], units[mintUrl]);\n if (balanceInSats >= amount) {\n return { selectedMintUrl: mintUrl, selectedMintBalance: balanceInSats };\n }\n }\n\n return { selectedMintUrl: null, selectedMintBalance: 0 };\n}\n","/**\n * CashuSpender - Core spending logic for Cashu tokens\n *\n * Handles:\n * - Mint selection with sufficient balance\n * - Provider mint compatibility checks\n * - Retry logic with alternate mints\n * - Critical section management (busy state)\n *\n * Extracted from hooks/useCashuWithXYZ.ts\n */\n\nimport type { WalletAdapter, StorageAdapter } from \"./interfaces\";\nimport type { SpendResult, SdkLogger } from \"../core/types\";\nimport { consoleLogger } from \"../core/types\";\nimport { InsufficientBalanceError } from \"../core/errors\";\nimport { BalanceManager } from \"./BalanceManager\";\nimport { auditLogger } from \"./AuditLogger\";\nimport { getBalanceInSats, isNetworkErrorMessage } from \"./tokenUtils\";\nimport { getDecodedToken } from \"@cashu/cashu-ts\";\n\n/**\n * Options for spending cashu tokens\n */\nexport interface SpendOptions {\n /** The mint URL to send from (can be overridden if insufficient balance) */\n mintUrl: string;\n\n /** The amount to spend in sats */\n amount: number;\n\n /** The provider base URL (for token storage and provider mint checks) */\n baseUrl: string;\n\n /** Whether to reuse an existing token if available */\n reuseToken?: boolean;\n\n /** Optional P2PK public key */\n p2pkPubkey?: string;\n\n /** Array of mint URLs to exclude (for retry logic) */\n excludeMints?: string[];\n\n /** Current retry count (for internal recursion) */\n retryCount?: number;\n\n /** Specific provider baseUrls to refund (if not provided, refunds all except current) */\n refundBaseUrls?: string[];\n}\n\ntype DebugLevel = \"DEBUG\" | \"WARN\" | \"ERROR\";\n\n/**\n * CashuSpender manages the spending of Cashu tokens\n */\nexport class CashuSpender {\n private _isBusy = false;\n private debugLevel: DebugLevel = \"WARN\";\n private readonly logger: SdkLogger;\n\n constructor(\n private walletAdapter: WalletAdapter,\n private storageAdapter: StorageAdapter,\n private _providerRegistry?: unknown,\n private balanceManager?: BalanceManager,\n logger?: SdkLogger\n ) {\n this.logger = (logger ?? consoleLogger).child(\"CashuSpender\");\n }\n\n async receiveToken(token: string): Promise<{\n success: boolean;\n amount: number;\n unit: \"sat\" | \"msat\";\n message?: string;\n }> {\n try {\n const result = await this.walletAdapter.receiveToken(token);\n return result;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n\n if (errorMessage.includes(\"Failed to fetch mint\")) {\n const cachedTokens = this.storageAdapter.getCachedReceiveTokens();\n const existingIndex = cachedTokens.findIndex((t) => t.token === token);\n if (existingIndex === -1) {\n const { amount, unit } = this._decodeTokenAmount(token);\n this.storageAdapter.setCachedReceiveTokens([\n ...cachedTokens,\n {\n token,\n amount,\n unit,\n createdAt: Date.now(),\n },\n ]);\n }\n }\n\n const { amount, unit } = this._decodeTokenAmount(token);\n return { success: false, amount, unit, message: errorMessage };\n }\n }\n\n private _decodeTokenAmount(token: string): {\n amount: number;\n unit: \"sat\" | \"msat\";\n } {\n try {\n const decoded = getDecodedToken(token);\n const amount = decoded.proofs.reduce(\n (acc, proof) => acc + proof.amount,\n 0\n );\n const unit = (decoded.unit as \"sat\" | \"msat\") || \"sat\";\n return { amount, unit };\n } catch {\n return { amount: 0, unit: \"sat\" };\n }\n }\n\n private async _getBalanceState(): Promise<{\n totalBalance: number;\n providerBalances: Record<string, number>;\n mintBalances: Record<string, number>;\n }> {\n if (this.balanceManager) {\n return this.balanceManager.getBalanceState();\n }\n\n const mintBalances = await this.walletAdapter.getBalances();\n const units = this.walletAdapter.getMintUnits();\n\n let totalMintBalance = 0;\n const normalizedMintBalances: Record<string, number> = {};\n for (const url in mintBalances) {\n const balance = mintBalances[url];\n const unit = units[url];\n const balanceInSats = getBalanceInSats(balance, unit);\n normalizedMintBalances[url] = balanceInSats;\n totalMintBalance += balanceInSats;\n }\n\n const providerBalances: Record<string, number> = {};\n let totalProviderBalance = 0;\n\n const apiKeys = this.storageAdapter.getAllApiKeys();\n for (const apiKey of apiKeys) {\n if (!providerBalances[apiKey.baseUrl]) {\n providerBalances[apiKey.baseUrl] = 0;\n }\n providerBalances[apiKey.baseUrl] += apiKey.balance;\n totalProviderBalance += apiKey.balance;\n }\n\n return {\n totalBalance: totalMintBalance + totalProviderBalance,\n providerBalances,\n mintBalances: normalizedMintBalances,\n };\n }\n\n private async _logTransaction(\n action: \"spend\" | \"topup\" | \"refund\" | \"receive\" | \"balance_check\",\n options?: {\n amount?: number;\n mintUrl?: string;\n baseUrl?: string;\n status?: \"success\" | \"failed\";\n details?: string;\n }\n ): Promise<void> {\n const balanceState = await this._getBalanceState();\n await auditLogger.logBalanceSnapshot(action, balanceState, options);\n }\n\n /**\n * Check if the spender is currently in a critical operation\n */\n get isBusy(): boolean {\n return this._isBusy;\n }\n\n getDebugLevel(): DebugLevel {\n return this.debugLevel;\n }\n\n setDebugLevel(level: DebugLevel): void {\n this.debugLevel = level;\n }\n\n private _log(level: \"DEBUG\" | \"WARN\" | \"ERROR\", ...args: unknown[]): void {\n const levelPriority: Record<DebugLevel, number> = {\n DEBUG: 0,\n WARN: 1,\n ERROR: 2,\n };\n\n if (levelPriority[level] >= levelPriority[this.debugLevel]) {\n switch (level) {\n case \"DEBUG\":\n this.logger.log(...args);\n break;\n case \"WARN\":\n this.logger.warn(...args);\n break;\n case \"ERROR\":\n this.logger.error(...args);\n break;\n }\n }\n }\n\n /**\n * Spend Cashu tokens with automatic mint selection and retry logic\n * Throws errors on failure instead of returning failed SpendResult\n */\n async spend(options: SpendOptions): Promise<SpendResult> {\n const {\n mintUrl,\n amount,\n baseUrl,\n reuseToken = false,\n p2pkPubkey,\n excludeMints = [],\n retryCount = 0,\n } = options;\n\n this._isBusy = true;\n\n try {\n const result = await this._spendInternal({\n mintUrl,\n amount,\n baseUrl,\n reuseToken,\n p2pkPubkey,\n excludeMints,\n retryCount,\n });\n\n if (result.status === \"failed\" || !result.token) {\n const errorMsg =\n result.error || `Insufficient balance. Need ${amount} sats.`;\n\n if (this._isNetworkError(errorMsg)) {\n throw new Error(\n `Your mint ${mintUrl} is unreachable or is blocking your IP. Please try again later or switch mints.`\n );\n }\n\n if (result.errorDetails) {\n throw new InsufficientBalanceError(\n result.errorDetails.required,\n result.errorDetails.available,\n result.errorDetails.maxMintBalance,\n result.errorDetails.maxMintUrl\n );\n }\n\n throw new Error(errorMsg);\n }\n\n return result;\n } finally {\n this._isBusy = false;\n }\n }\n\n /**\n * Check if error message indicates a network error\n */\n private _isNetworkError(message: string): boolean {\n return (\n isNetworkErrorMessage(message) ||\n (message.includes(\"Your mint\") && message.includes(\"unreachable\"))\n );\n }\n\n /**\n * Internal spending logic\n */\n private async _spendInternal(options: SpendOptions): Promise<SpendResult> {\n let {\n mintUrl,\n amount,\n baseUrl,\n reuseToken,\n p2pkPubkey,\n excludeMints,\n retryCount,\n } = options;\n\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: amount=${amount}, mintUrl=${mintUrl}, baseUrl=${baseUrl}, reuseToken=${reuseToken}`\n );\n\n // Validate amount\n let adjustedAmount = Math.ceil(amount);\n if (!adjustedAmount || isNaN(adjustedAmount)) {\n this._log(\n \"ERROR\",\n `[CashuSpender] _spendInternal: Invalid amount: ${amount}`\n );\n return {\n token: null,\n status: \"failed\",\n balance: 0,\n error: \"Please enter a valid amount\",\n };\n }\n\n // Try to get existing token for reuse\n if (reuseToken && baseUrl) {\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: Attempting to reuse token for ${baseUrl}`\n );\n const existingResult = await this._tryReuseToken(\n baseUrl,\n adjustedAmount,\n mintUrl\n );\n if (existingResult) {\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: Successfully reused token, balance: ${existingResult.balance}`\n );\n return existingResult;\n }\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: Could not reuse token, will create new token`\n );\n }\n\n // Get current balance state\n const balanceState = await this._getBalanceState();\n const totalAvailableBalance = balanceState.totalBalance;\n\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: totalAvailableBalance=${totalAvailableBalance}, adjustedAmount=${adjustedAmount}`\n );\n\n // Check total balance\n if (totalAvailableBalance < adjustedAmount) {\n this._log(\n \"ERROR\",\n `[CashuSpender] _spendInternal: Insufficient balance, have=${totalAvailableBalance}, need=${adjustedAmount}`\n );\n return this._createInsufficientBalanceError(\n adjustedAmount,\n balanceState.mintBalances,\n totalAvailableBalance\n );\n }\n\n let token: string | null = null;\n let selectedMintUrl: string | undefined;\n let spentAmount = adjustedAmount;\n\n if (this.balanceManager) {\n const tokenResult = await this.balanceManager.createProviderToken({\n mintUrl,\n baseUrl,\n amount: adjustedAmount,\n p2pkPubkey,\n excludeMints,\n retryCount,\n });\n\n if (!tokenResult.success || !tokenResult.token) {\n if ((tokenResult.error || \"\").includes(\"Insufficient balance\")) {\n return this._createInsufficientBalanceError(\n adjustedAmount,\n balanceState.mintBalances,\n totalAvailableBalance\n );\n }\n\n return {\n token: null,\n status: \"failed\",\n balance: 0,\n error: tokenResult.error || \"Failed to create token\",\n };\n }\n\n token = tokenResult.token;\n selectedMintUrl = tokenResult.selectedMintUrl;\n spentAmount = tokenResult.amountSpent || adjustedAmount;\n } else {\n try {\n token = await this.walletAdapter.sendToken(\n mintUrl,\n adjustedAmount,\n p2pkPubkey\n );\n selectedMintUrl = mintUrl;\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n return {\n token: null,\n status: \"failed\",\n balance: 0,\n error: `Error generating token: ${errorMsg}`,\n };\n }\n }\n\n // Store token and return\n if (token) {\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`\n );\n }\n\n this._logTransaction(\"spend\", {\n amount: spentAmount,\n mintUrl: selectedMintUrl || mintUrl,\n baseUrl,\n status: \"success\",\n });\n\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`\n );\n\n const units = this.walletAdapter.getMintUnits();\n\n return {\n token,\n status: \"success\",\n balance: spentAmount,\n unit:\n (selectedMintUrl ? units[selectedMintUrl] : units[mintUrl]) || \"sat\",\n };\n }\n\n /**\n * Try to reuse an existing API key\n */\n private async _tryReuseToken(\n baseUrl: string,\n amount: number,\n mintUrl: string\n ): Promise<SpendResult | null> {\n const apiKeyEntry = this.storageAdapter.getApiKey(baseUrl);\n if (!apiKeyEntry) return null;\n\n // Get pending distribution to check balance\n const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();\n const balanceForBaseUrl =\n apiKeyDistribution.find((b) => b.baseUrl === baseUrl)?.amount || 0;\n\n this._log(\"DEBUG\", \"Reusing API key\", balanceForBaseUrl, amount);\n\n if (balanceForBaseUrl > amount) {\n const units = this.walletAdapter.getMintUnits();\n const unit = units[mintUrl] || \"sat\";\n return {\n token: apiKeyEntry.key,\n status: \"success\",\n balance: balanceForBaseUrl,\n unit,\n };\n }\n\n // API key exists but insufficient balance - attempt topup\n if (this.balanceManager) {\n const topUpAmount = Math.ceil(amount * 1.2 - balanceForBaseUrl);\n const topUpResult = await this.balanceManager.topUp({\n mintUrl,\n baseUrl,\n amount: topUpAmount,\n token: apiKeyEntry.key,\n });\n this._log(\"DEBUG\", \"TOPUP \", topUpResult);\n\n if (topUpResult.success && topUpResult.toppedUpAmount) {\n const newBalance = balanceForBaseUrl + topUpResult.toppedUpAmount;\n const units = this.walletAdapter.getMintUnits();\n const unit = units[mintUrl] || \"sat\";\n\n this._logTransaction(\"topup\", {\n amount: topUpResult.toppedUpAmount,\n mintUrl,\n baseUrl,\n status: \"success\",\n });\n\n return {\n token: apiKeyEntry.key,\n status: \"success\",\n balance: newBalance,\n unit,\n };\n }\n\n const providerBalance = await this._getProviderTokenBalance(\n baseUrl,\n apiKeyEntry.key\n );\n this._log(\"DEBUG\", providerBalance);\n if (providerBalance <= 0) {\n this.storageAdapter.removeApiKey(baseUrl);\n }\n }\n\n return null;\n }\n\n /**\n * Refund all xcashu tokens from storage by calling the provider's refund endpoint.\n * The xcashu token acts as an API key to claim the refund, and the response contains\n * the actual refunded Cashu token which is then received into the wallet.\n * @param mintUrl - The mint URL for receiving tokens\n * @param excludeBaseUrls - Base URLs to exclude from refund (optional)\n * @returns Results for each xcashu token refund attempt\n */\n async refundXcashuTokens(\n mintUrl: string,\n excludeBaseUrls?: string[]\n ): Promise<\n { baseUrl: string; token: string; success: boolean; error?: string }[]\n > {\n const results: {\n baseUrl: string;\n token: string;\n success: boolean;\n error?: string;\n }[] = [];\n const xcashuTokens = this.storageAdapter.getXcashuTokens();\n const excludedUrls = new Set(excludeBaseUrls || []);\n\n for (const [baseUrl, tokens] of Object.entries(xcashuTokens)) {\n if (excludedUrls.has(baseUrl)) continue;\n\n for (const xcashuToken of tokens) {\n try {\n // XCashu tokens need to be sent to the provider's refund endpoint\n // The xcashu token acts as an API key, and the response contains the actual refunded token\n if (!this.balanceManager) {\n throw new Error(\"BalanceManager not available for xcashu refund\");\n }\n\n // Call the refund endpoint using the xcashu token as the API key\n const fetchResult = await this.balanceManager.fetchRefundToken(\n baseUrl,\n xcashuToken.token,\n true\n );\n\n if (!fetchResult.success || !fetchResult.token) {\n throw new Error(\n fetchResult.error || \"Failed to fetch refund token from provider\"\n );\n }\n\n // Receive the refunded Cashu token into the wallet\n const receiveResult = await this.receiveToken(fetchResult.token);\n\n if (receiveResult.success) {\n // Remove successfully refunded token from storage\n this.storageAdapter.removeXcashuToken(baseUrl, xcashuToken.token);\n results.push({\n baseUrl,\n token: xcashuToken.token,\n success: true,\n });\n this._log(\n \"DEBUG\",\n `[CashuSpender] refundXcashuTokens: Successfully refunded xcashu token for ${baseUrl}, amount=${receiveResult.amount}`\n );\n } else {\n // Refund failed - increment tryCount\n const currentTryCount = xcashuToken.tryCount ?? 0;\n const newTryCount = currentTryCount + 1;\n this.storageAdapter.updateXcashuTokenTryCount(\n xcashuToken.token,\n newTryCount\n );\n results.push({\n baseUrl,\n token: xcashuToken.token,\n success: false,\n error: receiveResult.message ?? \"Refund failed\",\n });\n this._log(\n \"DEBUG\",\n `[CashuSpender] refundXcashuTokens: Failed to receive refund token for ${baseUrl}, incremented tryCount to ${newTryCount}: ${receiveResult.message}`\n );\n }\n } catch (error) {\n // Exception occurred - increment tryCount\n const currentTryCount = xcashuToken.tryCount ?? 0;\n const newTryCount = currentTryCount + 1;\n this.storageAdapter.updateXcashuTokenTryCount(\n xcashuToken.token,\n newTryCount\n );\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n results.push({\n baseUrl,\n token: xcashuToken.token,\n success: false,\n error: errorMessage,\n });\n this._log(\n \"ERROR\",\n `[CashuSpender] refundXcashuTokens: Exception during refund for ${baseUrl}: ${errorMessage}, incremented tryCount to ${newTryCount}`\n );\n }\n }\n }\n\n return results;\n }\n\n /**\n * Refund specific providers without retrying spend\n */\n async refundProviders(\n mintUrl: string,\n forceRefund?: boolean\n ): Promise<{ baseUrl: string; success: boolean }[]> {\n const results: { baseUrl: string; success: boolean }[] = [];\n\n const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();\n\n // Refresh balances from providers before refunding\n for (const apiKeyEntry of apiKeyDistribution) {\n const apiKeyEntryFull = this.storageAdapter.getApiKey(\n apiKeyEntry.baseUrl\n );\n\n if (apiKeyEntryFull && this.balanceManager) {\n try {\n const balanceResult = await this.balanceManager.getTokenBalance(\n apiKeyEntryFull.key,\n apiKeyEntry.baseUrl\n );\n\n if (balanceResult.isInvalidApiKey) {\n // Key is invalid/expired on the provider side — clean it up\n this.logger.warn(\n `refundProviders: ${apiKeyEntry.baseUrl} returned invalid API key; removing local key and treating as success`\n );\n this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);\n results.push({\n baseUrl: apiKeyEntry.baseUrl,\n success: true,\n });\n continue;\n }\n\n if (balanceResult.amount >= 0 && !balanceResult.balanceUnknown) {\n const balanceSat = balanceResult.unit === \"msat\"\n ? Math.floor(balanceResult.amount / 1000)\n : balanceResult.amount;\n this.storageAdapter.updateApiKeyBalance(\n apiKeyEntry.baseUrl,\n balanceSat\n );\n } else {\n this.logger.warn(\n `refundProviders: balance refresh for ${apiKeyEntry.baseUrl} returned negative amount; keeping stale local balance=${apiKeyEntryFull.balance}`\n );\n }\n } catch (error) {\n // Balance check failed — proceed with stale local balance\n this.logger.warn(\n `refundProviders: balance refresh threw for ${apiKeyEntry.baseUrl}; proceeding with stale local balance`,\n error\n );\n }\n\n // Re-read the entry after balance refresh (may have been removed above)\n const refreshedEntry = this.storageAdapter.getApiKey(\n apiKeyEntry.baseUrl\n );\n if (!refreshedEntry) {\n continue;\n }\n\n const refundResult = await this.balanceManager.refundApiKey({\n mintUrl,\n baseUrl: apiKeyEntry.baseUrl,\n apiKey: refreshedEntry.key,\n forceRefund,\n });\n\n if (refundResult.success) {\n this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);\n } else {\n const currentEntry = this.storageAdapter.getApiKey(\n apiKeyEntry.baseUrl\n );\n this.logger.warn(\n `refundProviders: refund failed for ${apiKeyEntry.baseUrl}; currentEntry=${Boolean(currentEntry)} balance=${currentEntry?.balance ?? \"none\"}. Touching lastUsed to rate-limit retries.`\n );\n if (currentEntry) {\n this.storageAdapter.updateApiKeyBalance(\n apiKeyEntry.baseUrl,\n currentEntry.balance\n ); // update lastUsed so we only try to refund every 5 mins.\n }\n }\n\n results.push({\n baseUrl: apiKeyEntry.baseUrl,\n success: refundResult.success,\n });\n } else {\n this.logger.warn(\n `refundProviders: cannot refund ${apiKeyEntry.baseUrl}; apiKeyEntryFull=${Boolean(apiKeyEntryFull)} balanceManager=${Boolean(this.balanceManager)}`\n );\n results.push({\n baseUrl: apiKeyEntry.baseUrl,\n success: false,\n });\n }\n }\n\n return results;\n }\n\n /**\n * Create an insufficient balance error result\n */\n private _createInsufficientBalanceError(\n required: number,\n normalizedBalances: Record<string, number>,\n availableBalance?: number\n ): SpendResult {\n let maxBalance = 0;\n let maxMintUrl = \"\";\n\n for (const mintUrl in normalizedBalances) {\n const balanceInSats = normalizedBalances[mintUrl];\n\n if (balanceInSats > maxBalance) {\n maxBalance = balanceInSats;\n maxMintUrl = mintUrl;\n }\n }\n\n const error = new InsufficientBalanceError(\n required,\n availableBalance ?? maxBalance,\n maxBalance,\n maxMintUrl\n );\n\n return {\n token: null,\n status: \"failed\",\n balance: 0,\n error: error.message,\n errorDetails: {\n required,\n available: availableBalance ?? maxBalance,\n maxMintBalance: maxBalance,\n maxMintUrl,\n },\n };\n }\n\n private async _getProviderTokenBalance(\n baseUrl: string,\n token: string\n ): Promise<number> {\n try {\n const response = await fetch(`${baseUrl}v1/wallet/info`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (response.ok) {\n const data = await response.json();\n return data.balance / 1000;\n }\n } catch {\n return 0;\n }\n return 0;\n }\n}\n","/**\n * BalanceManager - Handles refunding and topping up tokens from providers\n *\n * Handles:\n * - Fetching refund tokens from provider API\n * - Receiving/storing refunded tokens\n * - Topping up API key balances with cashu tokens\n * - Error handling for various refund/topup failure modes\n *\n * Extracted from utils/cashuUtils.ts\n */\n\nimport type {\n WalletAdapter,\n StorageAdapter,\n ProviderRegistry,\n} from \"./interfaces\";\nimport type { RefundResult, TopUpResult, SdkLogger } from \"../core/types\";\nimport { consoleLogger } from \"../core/types\";\nimport { InsufficientBalanceError } from \"../core/errors\";\nimport { CashuSpender } from \"./CashuSpender\";\nimport {\n getBalanceInSats,\n isNetworkErrorMessage,\n selectMintWithBalance,\n} from \"./tokenUtils\";\n\n/**\n * Options for refunding API key balance\n */\nexport interface RefundApiKeyOptions {\n /** The mint URL (for NIP-60 wallet operations) */\n mintUrl: string;\n\n /** The provider base URL */\n baseUrl: string;\n\n /** The API key to use for authentication */\n apiKey: string;\n\n /** If true, forces refund even if the API key was used recently */\n forceRefund?: boolean;\n}\n\n/**\n * Options for topping up API key balance\n */\nexport interface TopUpOptions {\n /** The mint URL to spend from */\n mintUrl: string;\n\n /** The provider base URL */\n baseUrl: string;\n\n /** Amount to top up in sats */\n amount: number;\n\n /** Optional specific API key to top up (if not provided, uses stored token) */\n token?: string;\n}\n\nexport interface CreateProviderTokenOptions {\n mintUrl: string;\n baseUrl: string;\n amount: number;\n p2pkPubkey?: string;\n excludeMints?: string[];\n retryCount?: number;\n}\n\nexport interface ProviderTokenResult {\n success: boolean;\n token?: string;\n error?: string;\n selectedMintUrl?: string;\n amountSpent?: number;\n}\n\nexport interface BalanceState {\n totalBalance: number;\n providerBalances: Record<string, number>;\n mintBalances: Record<string, number>;\n}\n\n/**\n * BalanceManager handles token refunds and topups from providers\n */\nexport class BalanceManager {\n private cashuSpender: CashuSpender;\n /** In-memory guard for per-provider wallet mutations (topup / refund) */\n private providerWalletOps: Map<\n string,\n { type: \"topup\" | \"refund\"; startTime: number; endTime?: number }\n > = new Map();\n /** Cooldown (ms) between opposite operations on the same provider */\n private static readonly PROVIDER_WALLET_COOLDOWN_MS = 10_000;\n private readonly logger: SdkLogger;\n\n constructor(\n private walletAdapter: WalletAdapter,\n private storageAdapter: StorageAdapter,\n private providerRegistry?: ProviderRegistry,\n cashuSpender?: CashuSpender,\n logger?: SdkLogger\n ) {\n this.logger = (logger ?? consoleLogger).child(\"BalanceManager\");\n if (cashuSpender) {\n this.cashuSpender = cashuSpender;\n } else {\n this.cashuSpender = new CashuSpender(\n walletAdapter,\n storageAdapter,\n providerRegistry,\n this,\n this.logger\n );\n }\n }\n\n /**\n * Check whether a wallet operation (topup/refund) may run for a provider.\n * Returns the reason when blocked.\n */\n private _canRunProviderWalletOperation(\n baseUrl: string,\n type: \"topup\" | \"refund\"\n ): { allowed: boolean; reason?: string } {\n const existing = this.providerWalletOps.get(baseUrl);\n if (!existing) {\n return { allowed: true };\n }\n if (existing.type === type) {\n return { allowed: true };\n }\n // Opposite type in progress or recently completed\n if (!existing.endTime) {\n return {\n allowed: false,\n reason: `Provider wallet operation locked; ${existing.type} in progress`,\n };\n }\n const elapsed = Date.now() - existing.endTime;\n if (elapsed < BalanceManager.PROVIDER_WALLET_COOLDOWN_MS) {\n return {\n allowed: false,\n reason: `Provider wallet operation locked; recent ${existing.type} completed ${Math.round(elapsed / 1000)}s ago`,\n };\n }\n // Cooldown expired — clean up stale entry\n this.providerWalletOps.delete(baseUrl);\n return { allowed: true };\n }\n\n private _beginProviderWalletOperation(\n baseUrl: string,\n type: \"topup\" | \"refund\"\n ): void {\n this.providerWalletOps.set(baseUrl, { type, startTime: Date.now() });\n }\n\n private _endProviderWalletOperation(\n baseUrl: string,\n type: \"topup\" | \"refund\"\n ): void {\n const existing = this.providerWalletOps.get(baseUrl);\n if (existing && existing.type === type) {\n existing.endTime = Date.now();\n }\n }\n\n async getBalanceState(): Promise<BalanceState> {\n const mintBalances = await this.walletAdapter.getBalances();\n const units = this.walletAdapter.getMintUnits();\n\n let totalMintBalance = 0;\n const normalizedMintBalances: Record<string, number> = {};\n for (const url in mintBalances) {\n const balance = mintBalances[url];\n const unit = units[url];\n const balanceInSats = getBalanceInSats(balance, unit);\n normalizedMintBalances[url] = balanceInSats;\n totalMintBalance += balanceInSats;\n }\n\n const providerBalances: Record<string, number> = {};\n let totalProviderBalance = 0;\n\n const apiKeys = this.storageAdapter.getAllApiKeys();\n for (const apiKey of apiKeys) {\n if (!providerBalances[apiKey.baseUrl]) {\n providerBalances[apiKey.baseUrl] = 0;\n }\n providerBalances[apiKey.baseUrl] += apiKey.balance;\n totalProviderBalance += apiKey.balance;\n }\n\n return {\n totalBalance: totalMintBalance + totalProviderBalance,\n providerBalances,\n mintBalances: normalizedMintBalances,\n };\n }\n\n /**\n * Refund API key balance - convert remaining API key balance to cashu token\n * @param options - Refund options including forceRefund flag\n * @returns Refund result\n */\n async refundApiKey(options: RefundApiKeyOptions): Promise<RefundResult> {\n const { mintUrl, baseUrl, apiKey, forceRefund } = options;\n\n const guard = this._canRunProviderWalletOperation(baseUrl, \"refund\");\n if (!guard.allowed) {\n this.logger.log(`Skipping refund for ${baseUrl} - ${guard.reason}`);\n return { success: false, message: guard.reason };\n }\n\n this._beginProviderWalletOperation(baseUrl, \"refund\");\n\n try {\n return await this._refundApiKeyImpl({ mintUrl, baseUrl, apiKey, forceRefund });\n } finally {\n this._endProviderWalletOperation(baseUrl, \"refund\");\n }\n }\n\n private async _refundApiKeyImpl(options: RefundApiKeyOptions): Promise<RefundResult> {\n const { mintUrl, baseUrl, apiKey, forceRefund } = options;\n\n if (!apiKey) {\n this.logger.warn(`refundApiKey: aborting for ${baseUrl} - no API key`);\n return { success: false, message: \"No API key to refund\" };\n }\n\n // If forceRefund is not true, skip refund if the API key was used in the last 5 minutes\n if (!forceRefund) {\n const apiKeyEntry = this.storageAdapter.getApiKey(baseUrl);\n if (apiKeyEntry?.lastUsed) {\n const fiveMinutesAgo = Date.now() - 5 * 60 * 1000;\n if (apiKeyEntry.lastUsed > fiveMinutesAgo) {\n this.logger.log(\n `refundApiKey: skipping ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1000)}s ago`\n );\n return {\n success: false,\n message: \"API key was used recently, skipping refund\",\n };\n }\n }\n }\n\n let fetchResult:\n | { success: boolean; token?: string; requestId?: string; error?: string }\n | undefined;\n\n try {\n fetchResult = await this.fetchRefundToken(baseUrl, apiKey);\n\n if (fetchResult.error === \"No balance to refund\") {\n this.logger.log(`refundApiKey: provider says no balance for ${baseUrl}; removing API key`);\n this.storageAdapter.removeApiKey(baseUrl);\n return { success: true, message: \"No balance to refund, key cleaned up\" };\n }\n\n if (!fetchResult.success) {\n this.logger.warn(\n `refundApiKey: fetch failed for ${baseUrl}: ${fetchResult.error || \"API key refund failed\"}`\n );\n return {\n success: false,\n message: fetchResult.error || \"API key refund failed\",\n requestId: fetchResult.requestId,\n };\n }\n\n if (!fetchResult.token) {\n this.logger.warn(`refundApiKey: no token received for ${baseUrl}`);\n return {\n success: false,\n message: \"No token received from API key refund\",\n requestId: fetchResult.requestId,\n };\n }\n\n const receiveResult = await this.cashuSpender.receiveToken(\n fetchResult.token\n );\n const totalAmountMsat =\n receiveResult.unit === \"msat\"\n ? receiveResult.amount\n : receiveResult.amount * 1000;\n\n if (receiveResult.success) {\n this.storageAdapter.removeApiKey(baseUrl);\n } else {\n this.logger.warn(\n `refundApiKey: receive failed for ${baseUrl}; keeping API key. message=${receiveResult.message ?? \"none\"}`\n );\n }\n\n return {\n success: receiveResult.success,\n refundedAmount: totalAmountMsat,\n message: receiveResult.message,\n requestId: fetchResult.requestId,\n };\n } catch (error) {\n this.logger.error(\"API key refund error\", error);\n return this._handleRefundError(error, mintUrl, fetchResult?.requestId);\n }\n }\n\n /**\n * Fetch refund token from provider API using API key (or xcashu token) authentication\n */\n async fetchRefundToken(\n baseUrl: string,\n apiKeyOrToken: string,\n xCashu: boolean = false\n ): Promise<{\n success: boolean;\n token?: string;\n requestId?: string;\n error?: string;\n }> {\n if (!baseUrl) {\n return {\n success: false,\n error: \"No base URL configured\",\n };\n }\n\n const normalizedBaseUrl = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const url = `${normalizedBaseUrl}v1/wallet/refund`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, 60000);\n\n try {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (xCashu) {\n headers[\"X-Cashu\"] = apiKeyOrToken;\n } else {\n headers[\"Authorization\"] = `Bearer ${apiKeyOrToken}`;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const requestId =\n response.headers.get(\"x-routstr-request-id\") || undefined;\n\n if (!response.ok) {\n const responseBody = await response.text().catch(() => undefined);\n let errorData: any = {};\n if (responseBody) {\n try {\n errorData = JSON.parse(responseBody);\n } catch {\n errorData = {};\n }\n }\n this.logger.error(\"Upstream wallet refund error response\", {\n baseUrl,\n url,\n status: response.status,\n statusText: response.statusText,\n requestId,\n body: responseBody ?? \"<unable to read response body>\",\n });\n return {\n success: false,\n requestId,\n error: `API key refund failed: ${\n errorData?.detail || responseBody || response.statusText\n }`,\n };\n }\n\n const data = await response.json();\n return {\n success: true,\n token: data.token,\n requestId,\n };\n } catch (error) {\n clearTimeout(timeoutId);\n this.logger.error(\"fetchRefundToken fetch error\", error);\n\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n return {\n success: false,\n error: \"Request timed out after 1 minute\",\n };\n }\n return {\n success: false,\n error: error.message,\n };\n }\n\n return {\n success: false,\n error: \"Unknown error occurred during API key refund request\",\n };\n }\n }\n\n /**\n * Top up API key balance with a cashu token\n */\n async topUp(options: TopUpOptions): Promise<TopUpResult> {\n const { mintUrl, baseUrl, amount, token: providedToken } = options;\n\n const guard = this._canRunProviderWalletOperation(baseUrl, \"topup\");\n if (!guard.allowed) {\n this.logger.log(`Skipping topup for ${baseUrl} - ${guard.reason}`);\n return { success: false, message: guard.reason };\n }\n\n this._beginProviderWalletOperation(baseUrl, \"topup\");\n\n try {\n return await this._topUpImpl({ mintUrl, baseUrl, amount, token: providedToken });\n } finally {\n this._endProviderWalletOperation(baseUrl, \"topup\");\n }\n }\n\n private async _topUpImpl(options: TopUpOptions): Promise<TopUpResult> {\n const { mintUrl, baseUrl, amount, token: providedToken } = options;\n\n if (!amount || amount <= 0) {\n return { success: false, message: \"Invalid top up amount\" };\n }\n\n const apiKeyEntry = providedToken\n ? null // providedToken is now the apiKey for apikeys mode\n : this.storageAdapter.getApiKey(baseUrl);\n const apiKey = providedToken || apiKeyEntry?.key;\n\n if (!apiKey) {\n return { success: false, message: \"No API key available for top up\" };\n }\n\n let cashuToken: string | null = null;\n let requestId: string | undefined;\n\n try {\n const tokenResult = await this.createProviderToken({\n mintUrl,\n baseUrl,\n amount,\n });\n\n if (!tokenResult.success || !tokenResult.token) {\n return {\n success: false,\n message: tokenResult.error || \"Unable to create top up token\",\n };\n }\n\n cashuToken = tokenResult.token;\n\n const topUpResult = await this._postTopUp(baseUrl, apiKey, cashuToken);\n requestId = topUpResult.requestId;\n this.logger.log(\"topUpResult:\", topUpResult);\n\n if (!topUpResult.success) {\n await this._recoverFailedTopUp(cashuToken);\n return {\n success: false,\n message: topUpResult.error || \"Top up failed\",\n requestId,\n recoveredToken: true,\n };\n }\n\n return {\n success: true,\n toppedUpAmount: amount,\n requestId,\n };\n } catch (error) {\n this.logger.log(`topup error for ${baseUrl}: ${error}`);\n if (cashuToken) {\n await this._recoverFailedTopUp(cashuToken);\n }\n\n return this._handleTopUpError(error, mintUrl, requestId);\n }\n }\n\n async createProviderToken(\n options: CreateProviderTokenOptions\n ): Promise<ProviderTokenResult> {\n const {\n mintUrl,\n baseUrl,\n amount,\n retryCount = 0,\n excludeMints = [],\n p2pkPubkey,\n } = options;\n\n const adjustedAmount = Math.ceil(amount);\n this.logger.log(`createProviderToken: baseUrl=${baseUrl} mintUrl=${mintUrl} amount=${amount} adjustedAmount=${adjustedAmount} retryCount=${retryCount}`);\n if (!adjustedAmount || isNaN(adjustedAmount)) {\n this.logger.error(`createProviderToken: invalid amount=${amount}`);\n return { success: false, error: \"Invalid top up amount\" };\n }\n\n const balanceState = await this.getBalanceState();\n const balances = await this.walletAdapter.getBalances();\n const units = this.walletAdapter.getMintUnits();\n\n const totalMintBalance = Object.values(balanceState.mintBalances).reduce(\n (sum, value) => sum + value,\n 0\n );\n const targetProviderBalance = balanceState.providerBalances[baseUrl] || 0;\n const refundableProviderBalance = Object.entries(\n balanceState.providerBalances\n )\n .filter(([providerBaseUrl]) => providerBaseUrl !== baseUrl)\n .reduce((sum, [, value]) => sum + value, 0);\n\n if (\n totalMintBalance + targetProviderBalance < adjustedAmount &&\n totalMintBalance + targetProviderBalance + refundableProviderBalance >=\n adjustedAmount &&\n retryCount < 3\n ) {\n await this._refundOtherProvidersForTopUp(baseUrl, mintUrl, retryCount, adjustedAmount);\n return this.createProviderToken({\n ...options,\n retryCount: retryCount + 1,\n });\n }\n\n if (totalMintBalance + targetProviderBalance < adjustedAmount) {\n const error = new InsufficientBalanceError(\n adjustedAmount,\n totalMintBalance + targetProviderBalance,\n totalMintBalance,\n Object.entries(balanceState.mintBalances).reduce(\n (max, [url, balance]) =>\n balance > max.balance ? { url, balance } : max,\n { url: \"\", balance: 0 }\n ).url\n );\n this.logger.error(`createProviderToken: insufficient balance required=${adjustedAmount} available=${totalMintBalance + targetProviderBalance} totalMint=${totalMintBalance} targetProvider=${targetProviderBalance}`);\n return { success: false, error: error.message };\n }\n\n const providerMints =\n baseUrl && this.providerRegistry\n ? this.providerRegistry.getProviderMints(baseUrl)\n : [];\n\n let requiredAmount = adjustedAmount;\n const supportedMintsOnly = providerMints.length > 0;\n\n let candidates = this._selectCandidateMints({\n balances,\n units,\n amount: requiredAmount,\n preferredMintUrl: mintUrl,\n excludeMints,\n allowedMints: supportedMintsOnly ? providerMints : undefined,\n });\n\n if (candidates.length === 0 && supportedMintsOnly) {\n requiredAmount += 2;\n candidates = this._selectCandidateMints({\n balances,\n units,\n amount: requiredAmount,\n preferredMintUrl: mintUrl,\n excludeMints,\n });\n }\n\n if (candidates.length === 0) {\n let maxBalance = 0;\n let maxMintUrl = \"\";\n for (const mintUrl in balances) {\n const balance = balances[mintUrl];\n const unit = units[mintUrl];\n const balanceInSats = getBalanceInSats(balance, unit);\n if (balanceInSats > maxBalance) {\n maxBalance = balanceInSats;\n maxMintUrl = mintUrl;\n }\n }\n\n this.logger.error(`createProviderToken: no candidate mints required=${requiredAmount} totalMint=${totalMintBalance} maxBalance=${maxBalance} maxMint=${maxMintUrl}`);\n const error = new InsufficientBalanceError(\n adjustedAmount,\n totalMintBalance,\n maxBalance,\n maxMintUrl\n );\n\n return { success: false, error: error.message };\n }\n\n let lastError: string | undefined;\n for (const candidateMint of candidates) {\n try {\n this.logger.log(`createProviderToken: attempting mint=${candidateMint} amount=${requiredAmount}`);\n const token = await this.walletAdapter.sendToken(\n candidateMint,\n requiredAmount,\n p2pkPubkey\n );\n this.logger.log(`createProviderToken: success from mint=${candidateMint}`);\n return {\n success: true,\n token,\n selectedMintUrl: candidateMint,\n amountSpent: requiredAmount,\n };\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n this.logger.error(`createProviderToken: mint=${candidateMint} failed: ${errorMsg}`);\n if (error instanceof Error) {\n lastError = errorMsg;\n\n if (isNetworkErrorMessage(error.message)) {\n this.logger.warn(`createProviderToken: network error from ${candidateMint}, trying next mint...`);\n continue;\n }\n }\n\n return {\n success: false,\n error: lastError || \"Failed to create top up token\",\n };\n }\n }\n\n this.logger.error(`createProviderToken: all candidate mints exhausted lastError=${lastError}`);\n return {\n success: false,\n error:\n lastError || \"All candidate mints failed while creating top up token\",\n };\n }\n\n private _selectCandidateMints(options: {\n balances: Record<string, number>;\n units: Record<string, \"sat\" | \"msat\">;\n amount: number;\n preferredMintUrl: string;\n excludeMints: string[];\n allowedMints?: string[];\n }): string[] {\n const {\n balances,\n units,\n amount,\n preferredMintUrl,\n excludeMints,\n allowedMints,\n } = options;\n\n const candidates: string[] = [];\n\n const { selectedMintUrl: firstMint } = selectMintWithBalance(\n balances,\n units,\n amount,\n excludeMints\n );\n\n if (\n firstMint &&\n (!allowedMints ||\n allowedMints.length === 0 ||\n allowedMints.includes(firstMint))\n ) {\n candidates.push(firstMint);\n }\n\n const canUseMint = (mint: string): boolean => {\n if (excludeMints.includes(mint)) return false;\n if (\n allowedMints &&\n allowedMints.length > 0 &&\n !allowedMints.includes(mint)\n ) {\n return false;\n }\n const rawBalance = balances[mint] || 0;\n const unit = units[mint];\n const balanceInSats = getBalanceInSats(rawBalance, unit);\n return balanceInSats >= amount;\n };\n\n if (\n preferredMintUrl &&\n canUseMint(preferredMintUrl) &&\n !candidates.includes(preferredMintUrl)\n ) {\n candidates.push(preferredMintUrl);\n }\n\n for (const mint in balances) {\n if (mint === preferredMintUrl || candidates.includes(mint)) continue;\n if (canUseMint(mint)) {\n candidates.push(mint);\n }\n }\n\n return candidates;\n }\n\n private async _refundOtherProvidersForTopUp(\n baseUrl: string,\n mintUrl: string,\n retryCount: number,\n requiredAmount: number\n ): Promise<void> {\n const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();\n\n // If retryCount >= 2, force refund even if API keys were used recently\n const forceRefund = retryCount >= 2;\n\n // Build full candidate list sorted by lastUsed, oldest first.\n // This way providers outside the 5-min window are tried first (natural\n // refund succeeds), and if we must force-refund, we target the oldest\n // (closest to expiring) locked providers first.\n const candidates = apiKeyDistribution\n .filter((apiKey) => apiKey.baseUrl !== baseUrl && apiKey.amount > 0)\n .map((apiKey) => {\n const full = this.storageAdapter.getApiKey(apiKey.baseUrl);\n return {\n baseUrl: apiKey.baseUrl,\n amount: apiKey.amount,\n lastUsed: full?.lastUsed ?? 0,\n key: full?.key,\n } as const;\n })\n .filter((c) => c.key != null)\n .sort((a, b) => a.lastUsed - b.lastUsed); // oldest first\n\n if (candidates.length === 0) return;\n\n if (forceRefund) {\n // Sequential: refund one at a time until we have enough liquid balance\n // for the target provider, so we only force-refund as few providers as\n // necessary.\n //\n // NOTE: refundApiKey() already calls removeApiKey() on success, so we\n // don't need to update the balance here — the key is gone.\n for (const candidate of candidates) {\n await this.refundApiKey({\n mintUrl,\n baseUrl: candidate.baseUrl,\n apiKey: candidate.key!,\n forceRefund: true,\n });\n\n // Check if we've freed enough balance for the target provider\n const newState = await this.getBalanceState();\n const newAvailable =\n (newState.mintBalances[mintUrl] || 0) +\n (newState.providerBalances[baseUrl] || 0);\n\n if (newAvailable >= requiredAmount) {\n this.logger.log(\n `_refundOtherProvidersForTopUp: freed enough balance (${newAvailable} >= ${requiredAmount}), stopping early`\n );\n return;\n }\n }\n } else {\n // Non-force: try all in parallel (existing behavior, now sorted by\n // lastUsed for determinism). Providers outside the 5-min window will\n // succeed and be cleaned up by refundApiKey; recently-used ones are\n // skipped without side effects.\n await Promise.allSettled(\n candidates.map((candidate) =>\n this.refundApiKey({\n mintUrl,\n baseUrl: candidate.baseUrl,\n apiKey: candidate.key!,\n forceRefund: false,\n })\n )\n );\n }\n }\n\n /**\n * Post topup request to provider API\n */\n private async _postTopUp(\n baseUrl: string,\n storedToken: string,\n cashuToken: string\n ): Promise<{\n success: boolean;\n requestId?: string;\n error?: string;\n }> {\n if (!baseUrl) {\n return {\n success: false,\n error: \"No base URL configured\",\n };\n }\n\n const normalizedBaseUrl = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const url = `${normalizedBaseUrl}v1/wallet/topup?cashu_token=${encodeURIComponent(\n cashuToken\n )}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, 60000);\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${storedToken}`,\n \"Content-Type\": \"application/json\",\n },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const requestId =\n response.headers.get(\"x-routstr-request-id\") || undefined;\n\n if (!response.ok) {\n const responseBody = await response.text().catch(() => undefined);\n let errorData: any = {};\n if (responseBody) {\n try {\n errorData = JSON.parse(responseBody);\n } catch {\n errorData = {};\n }\n }\n this.logger.error(\"Upstream wallet topup error response\", {\n baseUrl,\n url,\n status: response.status,\n statusText: response.statusText,\n requestId,\n body: responseBody ?? \"<unable to read response body>\",\n });\n return {\n success: false,\n requestId,\n error:\n errorData?.detail || responseBody || `Top up failed with status ${response.status}`,\n };\n }\n\n return { success: true, requestId };\n } catch (error) {\n clearTimeout(timeoutId);\n this.logger.error(\"_postTopUp fetch error\", error);\n\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n return {\n success: false,\n error: \"Request timed out after 1 minute\",\n };\n }\n return {\n success: false,\n error: error.message,\n };\n }\n\n return {\n success: false,\n error: \"Unknown error occurred during top up request\",\n };\n }\n }\n\n /**\n * Attempt to receive token back after failed top up\n */\n private async _recoverFailedTopUp(cashuToken: string): Promise<void> {\n try {\n await this.cashuSpender.receiveToken(cashuToken);\n } catch (error) {\n this.logger.error(\"_recoverFailedTopUp: failed to recover token\", error);\n }\n }\n\n /**\n * Handle refund errors with specific error types\n */\n private _handleRefundError(\n error: unknown,\n mintUrl: string,\n requestId?: string\n ): RefundResult {\n if (error instanceof Error) {\n // Network errors\n if (isNetworkErrorMessage(error.message)) {\n return {\n success: false,\n message: `Failed to connect to the mint: ${mintUrl}`,\n requestId,\n };\n }\n\n // Wallet not found error\n if (error.message.includes(\"Wallet not found\")) {\n return {\n success: false,\n message: `Wallet couldn't be loaded. Please save this refunded cashu token manually.`,\n requestId,\n };\n }\n\n return {\n success: false,\n message: error.message,\n requestId,\n };\n }\n\n return {\n success: false,\n message: \"Refund failed\",\n requestId,\n };\n }\n\n /**\n * Get token balance from provider\n */\n async getTokenBalance(\n token: string,\n baseUrl: string\n ): Promise<{\n amount: number;\n reserved: number;\n unit: \"sat\" | \"msat\";\n apiKey: string;\n isInvalidApiKey?: boolean;\n /** True when the balance could not be determined (network error, non-OK\n * response, etc.). Callers MUST NOT use `amount` in arithmetic when\n * this flag is set — it is 0, not a real balance. */\n balanceUnknown?: boolean;\n }> {\n try {\n const response = await fetch(`${baseUrl}v1/wallet/info`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (response.ok) {\n const data = await response.json();\n return {\n amount: data.balance,\n reserved: data.reserved ?? 0,\n unit: \"msat\",\n apiKey: data.api_key,\n };\n } else {\n this.logger.warn(`getTokenBalance: status=${response.status}`);\n const data = await response.json();\n this.logger.warn(\"getTokenBalance: FAILED\", data);\n\n // Check for invalid/expired API key error (proofs already spent)\n const isInvalidApiKey =\n response.status === 401 &&\n data?.detail?.error?.code === \"invalid_api_key\" &&\n data?.detail?.error?.message?.includes(\"proofs already spent\");\n\n return {\n amount: 0,\n reserved: data.reserved ?? 0,\n unit: \"msat\",\n apiKey: data.api_key,\n isInvalidApiKey,\n balanceUnknown: true,\n };\n }\n } catch (error) {\n this.logger.error(\"getTokenBalance error\", error);\n }\n\n return {\n amount: 0,\n reserved: 0,\n unit: \"sat\",\n apiKey: \"\",\n balanceUnknown: true,\n };\n }\n\n /**\n * Handle topup errors with specific error types\n */\n private _handleTopUpError(\n error: unknown,\n mintUrl: string,\n requestId?: string\n ): TopUpResult {\n if (error instanceof Error) {\n if (isNetworkErrorMessage(error.message)) {\n return {\n success: false,\n message: `Failed to connect to the mint: ${mintUrl}`,\n requestId,\n };\n }\n\n if (error.message.includes(\"Wallet not found\")) {\n return {\n success: false,\n message:\n \"Wallet couldn't be loaded. The cashu token was recovered locally.\",\n requestId,\n };\n }\n\n return {\n success: false,\n message: error.message,\n requestId,\n };\n }\n\n return {\n success: false,\n message: \"Top up failed\",\n requestId,\n };\n }\n}\n","export type ProviderDirectoryEntry = {\n endpoint_url?: string | null;\n endpoint_urls?: string[] | null;\n onion_url?: string | null;\n onion_urls?: string[] | null;\n name?: string | null;\n};\n\nconst TOR_ONION_SUFFIX = \".onion\";\n\nexport const isTorContext = (): boolean => {\n if (typeof window === \"undefined\") return false;\n const hostname = window.location.hostname.toLowerCase();\n return hostname.endsWith(TOR_ONION_SUFFIX);\n};\n\nexport const isOnionUrl = (url: string): boolean => {\n if (!url) return false;\n const trimmed = url.trim().toLowerCase();\n if (!trimmed) return false;\n try {\n const candidate = trimmed.startsWith(\"http\")\n ? trimmed\n : `http://${trimmed}`;\n return new URL(candidate).hostname.endsWith(TOR_ONION_SUFFIX);\n } catch {\n return trimmed.includes(TOR_ONION_SUFFIX);\n }\n};\n\nconst shouldAllowHttp = (url: string, torMode: boolean): boolean => {\n if (!url.startsWith(\"http://\")) return true;\n if (url.includes(\"localhost\") || url.includes(\"127.0.0.1\")) return true;\n return torMode && isOnionUrl(url);\n};\n\nexport const normalizeProviderUrl = (\n url?: string | null,\n torMode: boolean = false\n): string | null => {\n if (!url || typeof url !== \"string\") return null;\n const trimmed = url.trim();\n if (!trimmed) return null;\n if (/^https?:\\/\\//i.test(trimmed)) {\n return trimmed.endsWith(\"/\") ? trimmed : `${trimmed}/`;\n }\n const useHttpForOnion = torMode && isOnionUrl(trimmed);\n const withProto = `${useHttpForOnion ? \"http\" : \"https\"}://${trimmed}`;\n return withProto.endsWith(\"/\") ? withProto : `${withProto}/`;\n};\n\nconst dedupePreserveOrder = (urls: string[]): string[] => {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const url of urls) {\n if (!seen.has(url)) {\n seen.add(url);\n out.push(url);\n }\n }\n return out;\n};\n\nexport const getProviderEndpoints = (\n provider: ProviderDirectoryEntry,\n torMode: boolean\n): string[] => {\n const rawUrls: (string | null | undefined)[] = [\n provider.endpoint_url,\n ...(Array.isArray(provider.endpoint_urls) ? provider.endpoint_urls : []),\n provider.onion_url,\n ...(Array.isArray(provider.onion_urls) ? provider.onion_urls : []),\n ];\n\n const normalized = rawUrls\n .map((value) => normalizeProviderUrl(value, torMode))\n .filter((value): value is string => Boolean(value));\n\n const unique = dedupePreserveOrder(normalized).filter((value) =>\n shouldAllowHttp(value, torMode)\n );\n\n if (unique.length === 0) return [];\n\n const onion = unique.filter((value) => isOnionUrl(value));\n const clearnet = unique.filter((value) => !isOnionUrl(value));\n\n if (torMode) {\n return onion.length > 0 ? onion : clearnet;\n }\n\n return clearnet;\n};\n\nexport const filterBaseUrlsForTor = (\n baseUrls: string[],\n torMode: boolean\n): string[] => {\n if (!Array.isArray(baseUrls)) return [];\n\n const normalized = baseUrls\n .map((value) => normalizeProviderUrl(value, torMode))\n .filter((value): value is string => Boolean(value));\n\n const filtered = normalized.filter((value) =>\n torMode ? true : !isOnionUrl(value)\n );\n\n return dedupePreserveOrder(\n filtered.filter((value) => shouldAllowHttp(value, torMode))\n );\n};\n","/**\n * ProviderManager - Handles provider selection and failover logic\n *\n * Handles:\n * - Finding the best provider for a model based on price\n * - Provider failover when errors occur\n * - Tracking failed providers to avoid retry loops\n * - Provider version compatibility\n *\n * Extracted from utils/apiUtils.ts findNextBestProvider and related logic\n */\n\nimport type { ProviderRegistry } from \"../wallet/interfaces\";\nimport type { Model, SdkLogger } from \"../core/types\";\nimport { consoleLogger } from \"../core/types\";\nimport type { SdkStore } from \"../storage/store\";\nimport { isOnionUrl, isTorContext } from \"../utils/torUtils\";\n\nexport interface ModelProviderPrice {\n baseUrl: string;\n model: Model;\n promptPerMillion: number;\n completionPerMillion: number;\n totalPerMillion: number;\n}\n\n/**\n * Extract image resolution (width, height) from a base64 data URL without DOM.\n * Supports PNG and JPEG. Returns null if format unsupported or parsing fails.\n */\nfunction getImageResolutionFromDataUrl(\n dataUrl: string\n): { width: number; height: number } | null {\n try {\n if (typeof dataUrl !== \"string\" || !dataUrl.startsWith(\"data:\"))\n return null;\n\n const commaIdx = dataUrl.indexOf(\",\");\n if (commaIdx === -1) return null;\n\n const meta = dataUrl.slice(5, commaIdx); // e.g. \"image/png;base64\"\n const base64 = dataUrl.slice(commaIdx + 1);\n\n // Decode base64 to binary\n const binary =\n typeof atob === \"function\"\n ? atob(base64)\n : Buffer.from(base64, \"base64\").toString(\"binary\");\n\n const len = binary.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) bytes[i] = binary.charCodeAt(i);\n\n const isPNG = meta.includes(\"image/png\");\n const isJPEG = meta.includes(\"image/jpeg\") || meta.includes(\"image/jpg\");\n\n // PNG: width/height are 4-byte big-endian at offsets 16 and 20\n if (isPNG) {\n // Validate PNG signature\n const sig = [137, 80, 78, 71, 13, 10, 26, 10];\n for (let i = 0; i < sig.length; i++) {\n if (bytes[i] !== sig[i]) return null;\n }\n const view = new DataView(\n bytes.buffer,\n bytes.byteOffset,\n bytes.byteLength\n );\n const width = view.getUint32(16, false);\n const height = view.getUint32(20, false);\n if (width > 0 && height > 0) return { width, height };\n return null;\n }\n\n // JPEG: parse markers to SOF0/SOF2 for dimensions\n if (isJPEG) {\n let offset = 0;\n // JPEG SOI 0xFFD8\n if (bytes[offset++] !== 0xff || bytes[offset++] !== 0xd8) return null;\n\n while (offset < bytes.length) {\n // Find marker\n while (offset < bytes.length && bytes[offset] !== 0xff) offset++;\n if (offset + 1 >= bytes.length) break;\n\n // Skip fill bytes 0xFF\n while (bytes[offset] === 0xff) offset++;\n const marker = bytes[offset++];\n\n // Standalone markers without length\n if (marker === 0xd8 || marker === 0xd9) continue; // SOI/EOI\n\n if (offset + 1 >= bytes.length) break;\n const length = (bytes[offset] << 8) | bytes[offset + 1];\n offset += 2;\n\n // SOF0 (0xC0) or SOF2 (0xC2) contain dimensions\n if (marker === 0xc0 || marker === 0xc2) {\n if (length < 7 || offset + length - 2 > bytes.length) return null;\n const precision = bytes[offset];\n const height = (bytes[offset + 1] << 8) | bytes[offset + 2];\n const width = (bytes[offset + 3] << 8) | bytes[offset + 4];\n if (precision > 0 && width > 0 && height > 0)\n return { width, height };\n return null;\n } else {\n // Skip this segment\n offset += length - 2;\n }\n }\n return null;\n }\n\n // Unsupported formats (e.g., webp/gif) - skip for now\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Calculate image tokens based on OpenAI's vision pricing.\n *\n * For low detail: 85 tokens\n * For high detail/auto: 85 base tokens + 170 tokens per 512px tile\n */\nfunction calculateImageTokens(\n width: number,\n height: number,\n detail: \"low\" | \"high\" | \"auto\" = \"auto\"\n): number {\n if (detail === \"low\") return 85;\n\n let w = width;\n let h = height;\n\n // Clamp longest side to 2048 while preserving aspect ratio\n if (w > 2048 || h > 2048) {\n const aspectRatio = w / h;\n if (w > h) {\n w = 2048;\n h = Math.floor(w / aspectRatio);\n } else {\n h = 2048;\n w = Math.floor(h * aspectRatio);\n }\n }\n\n // Then clamp longest side to 768 while preserving aspect ratio\n if (w > 768 || h > 768) {\n const aspectRatio = w / h;\n if (w > h) {\n w = 768;\n h = Math.floor(w / aspectRatio);\n } else {\n h = 768;\n w = Math.floor(h * aspectRatio);\n }\n }\n\n // Number of 512px tiles, ceil division using (x + 511) // 512\n const tilesWidth = Math.floor((w + 511) / 512);\n const tilesHeight = Math.floor((h + 511) / 512);\n const numTiles = tilesWidth * tilesHeight;\n\n return 85 + 170 * numTiles;\n}\n\n/**\n * Candidate provider for failover\n */\ninterface CandidateProvider {\n baseUrl: string;\n model: Model;\n cost: number;\n}\n\n/**\n * ProviderManager handles provider selection and failover\n */\nexport class ProviderManager {\n private failedProviders = new Set<string>();\n /** Track when each provider last failed (provider URL -> timestamp) */\n private lastFailed = new Map<string, number>();\n /** Providers on cooldown: [provider_url, cooldown_started_timestamp][] */\n private providersOnCoolDown: [string, number][] = [];\n /** Cooldown duration in milliseconds (42 seconds) */\n private static readonly COOLDOWN_DURATION_MS = 42 * 1000;\n /** Optional persistent store for failure tracking */\n private store: SdkStore | null = null;\n /** Instance ID for debugging */\n private readonly instanceId: string;\n private readonly logger: SdkLogger;\n\n constructor(\n private providerRegistry: ProviderRegistry,\n store?: SdkStore,\n logger?: SdkLogger\n ) {\n this.instanceId = `pm_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n this.logger = (logger ?? consoleLogger).child(`ProviderManager:${this.instanceId}`);\n if (store) {\n this.store = store;\n this.hydrateFromStore();\n }\n }\n\n /**\n * Hydrate in-memory state from persistent store\n */\n private hydrateFromStore(): void {\n if (!this.store) return;\n const state = this.store.getState();\n\n // Hydrate failedProviders\n this.failedProviders = new Set(state.failedProviders);\n\n // Hydrate lastFailed\n this.lastFailed = new Map(Object.entries(state.lastFailed));\n\n // Hydrate providersOnCooldown (filter out expired)\n const now = Date.now();\n this.providersOnCoolDown = state.providersOnCooldown\n .filter(\n (entry) => now - entry.timestamp < ProviderManager.COOLDOWN_DURATION_MS\n )\n .map((entry) => [entry.baseUrl, entry.timestamp] as [string, number]);\n\n this.logger.log(`Hydrated from store: failedProviders=${this.failedProviders.size} lastFailed=${this.lastFailed.size} providersOnCooldown=${this.providersOnCoolDown.length}`);\n }\n\n /**\n * Get instance ID for debugging\n */\n getInstanceId(): string {\n return this.instanceId;\n }\n\n /**\n * Clean up expired cooldown entries\n * Also removes the provider from failedProviders so it can be retried\n */\n private cleanupExpiredCooldowns(): void {\n const now = Date.now();\n const before = this.providersOnCoolDown.length;\n this.providersOnCoolDown = this.providersOnCoolDown.filter(\n ([url, timestamp]) => {\n const age = now - timestamp;\n const isExpired = age >= ProviderManager.COOLDOWN_DURATION_MS;\n if (isExpired) {\n this.logger.log(`Removing expired cooldown for ${url} (age: ${age}ms)`);\n // Also remove from failedProviders so the provider can be retried\n this.failedProviders.delete(url);\n // Persist to store\n if (this.store) {\n this.store.getState().removeFailedProvider(url);\n }\n }\n return !isExpired;\n }\n );\n const after = this.providersOnCoolDown.length;\n if (before !== after) {\n this.logger.log(`Cleaned up ${before - after} expired cooldown(s), ${after} remaining`);\n }\n }\n\n /**\n * Get the cooldown duration in milliseconds\n */\n getCooldownDurationMs(): number {\n return ProviderManager.COOLDOWN_DURATION_MS;\n }\n\n /**\n * Check if a provider is currently on cooldown\n */\n isOnCooldown(baseUrl: string): boolean {\n this.cleanupExpiredCooldowns();\n\n const result = this.providersOnCoolDown.some(([url]) => url === baseUrl);\n return result;\n }\n\n /**\n * Get all providers currently on cooldown\n */\n getProvidersOnCooldown(): [string, number][] {\n this.cleanupExpiredCooldowns();\n return [...this.providersOnCoolDown];\n }\n\n /**\n * Reset the failed providers list\n */\n resetFailedProviders(): void {\n this.failedProviders.clear();\n // Persist to store\n if (this.store) {\n this.store.getState().setFailedProviders([]);\n }\n }\n\n /**\n * Get the last failed timestamp for a provider\n */\n getLastFailed(baseUrl: string): number | undefined {\n return this.lastFailed.get(baseUrl);\n }\n\n /**\n * Get all providers with their last failed timestamps\n */\n getAllLastFailed(): Map<string, number> {\n return new Map(this.lastFailed);\n }\n\n /**\n * Mark a provider as failed\n * If a provider fails twice within 5 minutes, it's added to cooldown\n */\n markFailed(baseUrl: string): void {\n const now = Date.now();\n const lastFailure = this.lastFailed.get(baseUrl);\n\n this.logger.log(`markFailed: ${baseUrl} lastFailure=${lastFailure} now=${now}`);\n\n if (lastFailure !== undefined) {\n const timeSinceLastFailure = now - lastFailure;\n this.logger.log(`markFailed: timeSinceLastFailure=${timeSinceLastFailure}ms withinCooldown=${timeSinceLastFailure < ProviderManager.COOLDOWN_DURATION_MS}`);\n }\n\n // Track this failure in memory\n this.lastFailed.set(baseUrl, now);\n this.failedProviders.add(baseUrl);\n\n // Persist to store\n if (this.store) {\n this.store.getState().setLastFailedTimestamp(baseUrl, now);\n this.store.getState().addFailedProvider(baseUrl);\n }\n\n this.logger.log(`markFailed: updated ${baseUrl} to ${now}, failedProviders=${this.failedProviders.size}`);\n\n // Check if this is a second failure within the cooldown window\n if (\n lastFailure !== undefined &&\n now - lastFailure < ProviderManager.COOLDOWN_DURATION_MS\n ) {\n // Second failure within 5 minutes - add to cooldown\n this.logger.log(`markFailed: second failure within cooldown window for ${baseUrl}`);\n if (!this.isOnCooldown(baseUrl)) {\n this.providersOnCoolDown.push([baseUrl, now]);\n // Persist to store\n if (this.store) {\n this.store.getState().addProviderOnCooldown(baseUrl, now);\n }\n this.logger.log(`markFailed: ${baseUrl} added to cooldown`);\n } else {\n this.logger.log(`markFailed: ${baseUrl} already on cooldown`);\n }\n } else {\n if (lastFailure === undefined) {\n this.logger.log(`markFailed: first failure for ${baseUrl}`);\n } else {\n this.logger.log(`markFailed: failure outside cooldown window for ${baseUrl} (${now - lastFailure}ms ago)`);\n }\n }\n }\n\n /**\n * Remove a provider from cooldown (e.g., after successful request)\n */\n removeFromCooldown(baseUrl: string): void {\n this.providersOnCoolDown = this.providersOnCoolDown.filter(\n ([url]) => url !== baseUrl\n );\n // Persist to store\n if (this.store) {\n this.store.getState().removeProviderFromCooldown(baseUrl);\n }\n }\n\n /**\n * Clear all cooldown tracking\n */\n clearCooldowns(): void {\n this.providersOnCoolDown = [];\n // Persist to store\n if (this.store) {\n this.store.getState().clearProvidersOnCooldown();\n }\n }\n\n /**\n * Clear all failure tracking (lastFailed timestamps)\n */\n clearFailureHistory(): void {\n this.lastFailed.clear();\n // Persist to store\n if (this.store) {\n this.store.getState().setLastFailed({});\n }\n }\n\n /**\n * Check if a provider has failed\n */\n hasFailed(baseUrl: string): boolean {\n return this.failedProviders.has(baseUrl);\n }\n\n /**\n * Get a copy of the failed providers set\n */\n getFailedProviders(): Set<string> {\n return new Set(this.failedProviders);\n }\n\n /**\n * Find the next best provider for a model\n * @param modelId The model ID to find a provider for\n * @param currentBaseUrl The current provider to exclude\n * @returns The best provider URL or null if none available\n */\n findNextBestProvider(modelId: string, currentBaseUrl: string): string | null {\n try {\n const torMode = isTorContext();\n const disabledProviders = new Set(\n this.providerRegistry.getDisabledProviders()\n );\n\n this.logger.log(`findNextBestProvider: model=${modelId} disabled=${[...disabledProviders].length} onCooldown=${this.providersOnCoolDown.length}`);\n\n // Get all providers with their models\n const allProviders = this.providerRegistry.getAllProvidersModels();\n this.logger.log(`findNextBestProvider: total providers=${Object.keys(allProviders).length}`);\n\n // Find all candidate providers\n const candidates: CandidateProvider[] = [];\n\n for (const [baseUrl, models] of Object.entries(allProviders)) {\n // Skip current, failed, disabled, and cooldown providers\n if (baseUrl === currentBaseUrl) {\n continue;\n }\n // if (this.failedProviders.has(baseUrl)) {\n // console.log(`[findNextBestProvider:${this.instanceId}] SKIP (failed): ${baseUrl}`);\n // skippedFailed++;\n // continue;\n // }\n if (disabledProviders.has(baseUrl)) {\n continue;\n }\n if (this.isOnCooldown(baseUrl)) {\n continue;\n }\n\n // Skip onion URLs if not in Tor mode\n if (!torMode && isOnionUrl(baseUrl)) {\n continue;\n }\n\n // Find the model in this provider's list\n const model = models.find((m: Model) => m.id === modelId);\n if (!model) {\n continue;\n }\n\n // Calculate cost (using completion price as the metric)\n const cost = model.sats_pricing?.completion ?? 0;\n candidates.push({ baseUrl, model, cost });\n }\n\n // Sort by price (lowest first)\n candidates.sort((a, b) => a.cost - b.cost);\n\n if (candidates.length > 0) {\n return candidates[0].baseUrl;\n } else {\n return null;\n }\n } catch (error) {\n this.logger.error(\"findNextBestProvider error:\", error);\n return null;\n }\n }\n\n /**\n * Find the best model for a provider\n * Useful when switching providers and need to find equivalent model\n */\n async getModelForProvider(\n baseUrl: string,\n modelId: string\n ): Promise<Model | null> {\n // Get models for this provider\n const models = this.providerRegistry.getModelsForProvider(baseUrl);\n\n // First try exact match\n const exactMatch = models.find((m) => m.id === modelId);\n if (exactMatch) return exactMatch;\n\n // Try matching by ID suffix (for backward compatibility with v0.1.x providers)\n const providerInfo = await this.providerRegistry.getProviderInfo(baseUrl);\n if (providerInfo?.version && /^0\\.1\\./.test(providerInfo.version)) {\n const suffix = modelId.split(\"/\").pop();\n const suffixMatch = models.find((m) => m.id === suffix);\n if (suffixMatch) return suffixMatch;\n }\n\n return null;\n }\n\n /**\n * Get all available providers for a model\n * Returns sorted list by price\n */\n getAllProvidersForModel(modelId: string): Array<{\n baseUrl: string;\n model: Model;\n cost: number;\n }> {\n const candidates: CandidateProvider[] = [];\n const allProviders = this.providerRegistry.getAllProvidersModels();\n const disabledProviders = new Set(\n this.providerRegistry.getDisabledProviders()\n );\n const torMode = isTorContext();\n\n for (const [baseUrl, models] of Object.entries(allProviders)) {\n if (disabledProviders.has(baseUrl)) continue;\n if (this.isOnCooldown(baseUrl)) continue;\n if (!torMode && isOnionUrl(baseUrl))\n continue;\n\n const model = models.find((m: Model) => m.id === modelId);\n if (!model) continue;\n\n const cost = model.sats_pricing?.completion ?? 0;\n candidates.push({ baseUrl, model, cost });\n }\n\n return candidates.sort((a, b) => a.cost - b.cost);\n }\n\n /**\n * Get providers for a model sorted by prompt+completion pricing\n */\n getProviderPriceRankingForModel(\n modelId: string,\n options: { torMode?: boolean; includeDisabled?: boolean } = {}\n ): ModelProviderPrice[] {\n const includeDisabled = options.includeDisabled ?? false;\n const torMode = options.torMode ?? false;\n const disabledProviderList = this.providerRegistry.getDisabledProviders();\n const disabledProviders = new Set(disabledProviderList);\n if (disabledProviderList.length > 0) {\n this.logger.log(`getProviderPriceRankingForModel: disabled providers (${disabledProviderList.length}): ${disabledProviderList.join(\", \")}`);\n }\n const allModels = this.providerRegistry.getAllProvidersModels();\n const results: ModelProviderPrice[] = [];\n\n for (const [baseUrl, models] of Object.entries(allModels)) {\n if (!includeDisabled && disabledProviders.has(baseUrl)) continue;\n if (this.isOnCooldown(baseUrl)) continue;\n if (torMode && !baseUrl.includes(\".onion\")) continue;\n if (\n !torMode &&\n baseUrl.includes(\".onion\")\n )\n continue;\n\n const match = models.find((model) => model.id === modelId);\n if (!match?.sats_pricing) continue;\n\n const prompt = match.sats_pricing.prompt;\n const completion = match.sats_pricing.completion;\n if (typeof prompt !== \"number\" || typeof completion !== \"number\") {\n continue;\n }\n\n const promptPerMillion = prompt * 1_000_000;\n const completionPerMillion = completion * 1_000_000;\n const totalPerMillion = promptPerMillion + completionPerMillion;\n\n results.push({\n baseUrl,\n model: match,\n promptPerMillion,\n completionPerMillion,\n totalPerMillion,\n });\n }\n\n results.sort((a, b) => {\n if (a.totalPerMillion !== b.totalPerMillion) {\n return a.totalPerMillion - b.totalPerMillion;\n }\n return a.baseUrl.localeCompare(b.baseUrl);\n });\n\n if (results.length > 0) {\n const ranking = results\n .map((r, i) => ` ${i + 1}. ${r.baseUrl} total=${r.totalPerMillion.toFixed(2)} sats/M (prompt=${r.promptPerMillion.toFixed(2)} completion=${r.completionPerMillion.toFixed(2)})`)\n .join(\"\\n\");\n this.logger.log(`getProviderPriceRankingForModel: ${modelId} ranking (${results.length} providers):\\n${ranking}`);\n } else {\n this.logger.log(`getProviderPriceRankingForModel: ${modelId} no providers found`);\n }\n\n return results;\n }\n\n /**\n * Get best-priced provider for a specific model\n */\n getBestProviderForModel(\n modelId: string,\n options: { torMode?: boolean; includeDisabled?: boolean } = {}\n ): string | null {\n const ranking = this.getProviderPriceRankingForModel(modelId, options);\n return ranking[0]?.baseUrl ?? null;\n }\n\n private normalizeModelId(modelId: string): string {\n return modelId.includes(\"/\")\n ? modelId.split(\"/\").pop() || modelId\n : modelId;\n }\n\n /**\n * Check if a provider accepts a specific mint\n */\n providerAcceptsMint(baseUrl: string, mintUrl: string): boolean {\n const providerMints = this.providerRegistry.getProviderMints(baseUrl);\n if (providerMints.length === 0) {\n // If no mints specified, provider accepts all\n return true;\n }\n return providerMints.includes(mintUrl);\n }\n\n /**\n * Get required sats for a model based on message history\n * Simple estimation based on typical usage\n */\n getRequiredSatsForModel(\n model: Model,\n apiMessages: any[],\n maxTokens?: number\n ): number {\n try {\n let imageTokens = 0;\n if (apiMessages) {\n for (const msg of apiMessages as any[]) {\n const content = (msg as any)?.content;\n if (Array.isArray(content)) {\n for (const part of content) {\n const isImage =\n part && typeof part === \"object\" && part.type === \"image_url\";\n const url: string | undefined = isImage\n ? typeof part.image_url === \"string\"\n ? part.image_url\n : part.image_url?.url\n : undefined;\n\n // Expecting a base64 data URL for local image inputs\n if (url && typeof url === \"string\" && url.startsWith(\"data:\")) {\n const res = getImageResolutionFromDataUrl(url);\n if (res) {\n const tokensFromImage = calculateImageTokens(\n res.width,\n res.height\n );\n // const patchSize = 32;\n // const patchesW = Math.floor((res.width + patchSize - 1) / patchSize);\n // const patchesH = Math.floor((res.height + patchSize - 1) / patchSize);\n // const tokensFromImage = patchesW * patchesH;\n imageTokens += tokensFromImage;\n this.logger.log(`IMAGE INPUT RESOLUTION width=${res.width} height=${res.height} tokens=${tokensFromImage}`);\n } else {\n this.logger.log(\"IMAGE INPUT RESOLUTION: unknown format\");\n }\n }\n }\n }\n }\n }\n // Remove image_url parts from apiMessages when estimating text token count\n const apiMessagesNoImages = apiMessages // SWITCH AFTER NODE UPDAATES\n ? (apiMessages as any[]).map((m: any) => {\n if (Array.isArray(m?.content)) {\n const filtered = m.content.filter(\n (p: any) =>\n !(p && typeof p === \"object\" && p.type === \"image_url\")\n );\n return { ...m, content: filtered };\n }\n return m;\n })\n : undefined;\n\n const approximateTokens = apiMessagesNoImages // SWITCH AFTER NODE UPDAATES\n ? Math.ceil(JSON.stringify(apiMessagesNoImages, null, 2).length / 2.84)\n : 10000; // Assumed tokens for minimum balance calculation\n\n const totalInputTokens = approximateTokens + imageTokens;\n\n const sp: any = model?.sats_pricing as any;\n\n if (!sp) {\n return 0;\n }\n\n // If we don't have max_completion_cost, fall back to max_cost\n if (!sp.max_completion_cost) {\n return sp.max_cost ?? 50;\n }\n\n // Calculate based on token usage (similar to getTokenAmountForModel in apiUtils.ts)\n const promptCosts = (sp.prompt || 0) * totalInputTokens;\n let completionCost = sp.max_completion_cost;\n if (maxTokens !== undefined && sp.completion) {\n completionCost = sp.completion * maxTokens;\n }\n const totalEstimatedCosts = (promptCosts + completionCost) * 1.05;\n // return totalEstimatedCosts > sp.max_cost ? sp.max_cost : totalEstimatedCosts; // in some image input calculations, this cost balloons up. Now includes image tokens via 32px patches.\n return totalEstimatedCosts; // Backend has a bug here.it's calculating image tokens wrong. gotta switch to different logic once its fixed\n } catch (e) {\n this.logger.error(\"getRequiredSatsForModel error:\", e);\n return 0;\n }\n }\n}\n","import type { StorageDriver } from \"../types\";\n\nconst canUseLocalStorage = (): boolean => {\n return (\n typeof window !== \"undefined\" && typeof window.localStorage !== \"undefined\"\n );\n};\n\nconst isQuotaExceeded = (error: unknown): boolean => {\n const e = error as { name?: string; code?: number } | null;\n return (\n !!e &&\n (e?.name === \"QuotaExceededError\" || e?.code === 22 || e?.code === 1014)\n );\n};\n\nconst NON_CRITICAL_KEYS = new Set<string>([\"modelsFromAllProviders\"]);\n\nexport const localStorageDriver: StorageDriver = {\n async getItem<T>(key: string, defaultValue: T): Promise<T> {\n if (!canUseLocalStorage()) return defaultValue;\n try {\n const item = window.localStorage.getItem(key);\n if (item === null) return defaultValue;\n try {\n return JSON.parse(item) as T;\n } catch (parseError) {\n if (typeof defaultValue === \"string\") {\n return item as T;\n }\n throw parseError;\n }\n } catch (error) {\n console.error(`Error retrieving item with key \"${key}\":`, error);\n if (canUseLocalStorage()) {\n try {\n window.localStorage.removeItem(key);\n } catch (removeError) {\n console.error(\n `Error removing corrupted item with key \"${key}\":`,\n removeError\n );\n }\n }\n return defaultValue;\n }\n },\n async setItem<T>(key: string, value: T): Promise<void> {\n if (!canUseLocalStorage()) return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch (error) {\n if (isQuotaExceeded(error)) {\n if (NON_CRITICAL_KEYS.has(key)) {\n console.warn(\n `Storage quota exceeded; skipping non-critical key \"${key}\".`\n );\n return;\n }\n try {\n window.localStorage.removeItem(\"modelsFromAllProviders\");\n } catch {}\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n return;\n } catch (retryError) {\n console.warn(\n `Storage quota exceeded; unable to persist key \"${key}\" after cleanup attempt.`,\n retryError\n );\n return;\n }\n }\n console.error(`Error storing item with key \"${key}\":`, error);\n }\n },\n async removeItem(key: string): Promise<void> {\n if (!canUseLocalStorage()) return;\n try {\n window.localStorage.removeItem(key);\n } catch (error) {\n console.error(`Error removing item with key \"${key}\":`, error);\n }\n },\n};\n","import type { StorageDriver } from \"../types\";\n\nexport const createMemoryDriver = (\n seed?: Record<string, string>\n): StorageDriver => {\n const store = new Map<string, string>();\n\n if (seed) {\n for (const [key, value] of Object.entries(seed)) {\n store.set(key, value);\n }\n }\n\n return {\n async getItem<T>(key: string, defaultValue: T): Promise<T> {\n const item = store.get(key);\n if (item === undefined) return defaultValue;\n try {\n return JSON.parse(item) as T;\n } catch (parseError) {\n if (typeof defaultValue === \"string\") {\n return item as T;\n }\n throw parseError;\n }\n },\n async setItem<T>(key: string, value: T): Promise<void> {\n store.set(key, JSON.stringify(value));\n },\n async removeItem(key: string): Promise<void> {\n store.delete(key);\n },\n };\n};\n","export const SDK_STORAGE_KEYS = {\n MODELS_FROM_ALL_PROVIDERS: \"modelsFromAllProviders\",\n LAST_USED_MODEL: \"lastUsedModel\",\n BASE_URLS_LIST: \"base_urls_list\",\n DISABLED_PROVIDERS: \"disabled_providers\",\n MINTS_FROM_ALL_PROVIDERS: \"mints_from_all_providers\",\n INFO_FROM_ALL_PROVIDERS: \"info_from_all_providers\",\n LAST_MODELS_UPDATE: \"lastModelsUpdate\",\n LAST_BASE_URLS_UPDATE: \"lastBaseUrlsUpdate\",\n API_KEYS: \"api_keys\",\n CHILD_KEYS: \"child_keys\",\n XCASHU_TOKENS: \"xcashu_tokens\",\n ROUTSTR21_MODELS: \"routstr21Models\",\n LAST_ROUTSTR21_MODELS_UPDATE: \"lastRoutstr21ModelsUpdate\",\n CACHED_RECEIVE_TOKENS: \"cached_receive_tokens\",\n USAGE_TRACKING: \"usage_tracking\",\n CLIENT_IDS: \"client_ids\",\n FAILED_PROVIDERS: \"failed_providers\",\n LAST_FAILED: \"last_failed\",\n PROVIDERS_ON_COOLDOWN: \"providers_on_cooldown\",\n} as const;\n\nexport type SdkStorageKey =\n (typeof SDK_STORAGE_KEYS)[keyof typeof SDK_STORAGE_KEYS];\n","import type {\n AggregateUsageOptions,\n UsageAggregateRow,\n UsageGroupBy,\n} from \"./interfaces\";\nimport type { UsageTrackingEntry } from \"./types\";\n\n// Shared, platform-agnostic aggregation helpers used by every usage tracking\n// driver. SQL drivers (bunSqlite/sqlite) push the work down to SQLite via\n// buildAggregateSql/mapAggregateRow; in-memory drivers (memory/indexedDB)\n// reduce in JS via reduceAggregate. Both paths must produce identical group\n// keys and ordering so callers get the same result regardless of backend.\n\nconst pad2 = (n: number): string => String(n).padStart(2, \"0\");\n\nconst aggregateColumns =\n \"COUNT(*) AS requests, \" +\n \"COALESCE(SUM(prompt_tokens), 0) AS promptTokens, \" +\n \"COALESCE(SUM(completion_tokens), 0) AS completionTokens, \" +\n \"COALESCE(SUM(total_tokens), 0) AS totalTokens, \" +\n \"COALESCE(SUM(cost), 0) AS cost, \" +\n \"COALESCE(SUM(sats_cost), 0) AS satsCost, \" +\n \"COALESCE(SUM(base_msats), 0) AS baseMsats, \" +\n \"COALESCE(SUM(input_msats), 0) AS inputMsats, \" +\n \"COALESCE(SUM(output_msats), 0) AS outputMsats, \" +\n \"COALESCE(SUM(total_msats), 0) AS totalMsats, \" +\n \"COALESCE(SUM(total_usd), 0) AS totalUsd, \" +\n \"COALESCE(SUM(cache_read_input_tokens), 0) AS cacheReadInputTokens, \" +\n \"COALESCE(SUM(cache_creation_input_tokens), 0) AS cacheCreationInputTokens, \" +\n \"COALESCE(SUM(cache_read_msats), 0) AS cacheReadMsats, \" +\n \"COALESCE(SUM(cache_creation_msats), 0) AS cacheCreationMsats\";\n\n/**\n * SQL expression producing the group key. `day`/`hour` shift the (millisecond)\n * timestamp by the timezone offset before bucketing so buckets land on the\n * caller's local-day/hour boundaries rather than UTC.\n */\nconst sqlGroupExpr = (\n groupBy: UsageGroupBy,\n): { expr: string; usesTz: boolean } => {\n switch (groupBy) {\n case \"modelId\":\n return { expr: \"model_id\", usesTz: false };\n case \"baseUrl\":\n return { expr: \"base_url\", usesTz: false };\n case \"client\":\n return { expr: \"client\", usesTz: false };\n case \"sessionId\":\n return { expr: \"session_id\", usesTz: false };\n case \"provider\":\n return { expr: \"provider\", usesTz: false };\n case \"day\":\n return {\n expr: \"strftime('%Y-%m-%d', (timestamp - ? * 60000) / 1000, 'unixepoch')\",\n usesTz: true,\n };\n case \"hour\":\n return {\n expr: \"strftime('%H', (timestamp - ? * 60000) / 1000, 'unixepoch')\",\n usesTz: true,\n };\n }\n};\n\n/**\n * Build an aggregation query from a driver-supplied WHERE clause. When\n * `groupBy` is omitted a single grand-total row is returned. Timezone params\n * (day/hour grouping) bind before the WHERE params because the group\n * expression appears earlier in the statement (the SELECT list).\n */\nexport const buildAggregateSql = (\n tableName: string,\n where: { sql: string; params: unknown[] },\n options: AggregateUsageOptions = {},\n): { sql: string; params: unknown[] } => {\n if (!options.groupBy) {\n return {\n sql: `SELECT NULL AS grp, ${aggregateColumns} FROM ${tableName} ${where.sql}`,\n params: where.params,\n };\n }\n\n const { expr, usesTz } = sqlGroupExpr(options.groupBy);\n const tzParams = usesTz ? [options.tzOffsetMinutes ?? 0] : [];\n const orderBy =\n options.groupBy === \"day\" || options.groupBy === \"hour\"\n ? \"ORDER BY grp ASC\"\n : \"ORDER BY satsCost DESC\";\n\n return {\n sql: `SELECT ${expr} AS grp, ${aggregateColumns} FROM ${tableName} ${where.sql} GROUP BY grp ${orderBy}`,\n params: [...tzParams, ...where.params],\n };\n};\n\n/** Map a raw SQL aggregate row into a `UsageAggregateRow`. */\nexport const mapAggregateRow = (row: Record<string, unknown>): UsageAggregateRow => ({\n group: row.grp == null ? null : String(row.grp),\n requests: Number(row.requests ?? 0),\n promptTokens: Number(row.promptTokens ?? 0),\n completionTokens: Number(row.completionTokens ?? 0),\n totalTokens: Number(row.totalTokens ?? 0),\n cost: Number(row.cost ?? 0),\n satsCost: Number(row.satsCost ?? 0),\n baseMsats: Number(row.baseMsats ?? 0),\n inputMsats: Number(row.inputMsats ?? 0),\n outputMsats: Number(row.outputMsats ?? 0),\n totalMsats: Number(row.totalMsats ?? 0),\n totalUsd: Number(row.totalUsd ?? 0),\n cacheReadInputTokens: Number(row.cacheReadInputTokens ?? 0),\n cacheCreationInputTokens: Number(row.cacheCreationInputTokens ?? 0),\n cacheReadMsats: Number(row.cacheReadMsats ?? 0),\n cacheCreationMsats: Number(row.cacheCreationMsats ?? 0),\n});\n\nconst jsGroupKey = (\n entry: UsageTrackingEntry,\n groupBy: UsageGroupBy,\n tzOffsetMinutes: number,\n): string | null => {\n switch (groupBy) {\n case \"modelId\":\n return entry.modelId ?? null;\n case \"baseUrl\":\n return entry.baseUrl ?? null;\n case \"client\":\n return entry.client ?? null;\n case \"sessionId\":\n return entry.sessionId ?? null;\n case \"provider\":\n return entry.provider ?? null;\n case \"day\": {\n const d = new Date(entry.timestamp - tzOffsetMinutes * 60000);\n return `${d.getUTCFullYear()}-${pad2(d.getUTCMonth() + 1)}-${pad2(d.getUTCDate())}`;\n }\n case \"hour\": {\n const d = new Date(entry.timestamp - tzOffsetMinutes * 60000);\n return pad2(d.getUTCHours());\n }\n }\n};\n\n/**\n * Reduce already-filtered entries into aggregate rows, mirroring the SQL\n * drivers' grouping and ordering. With no `groupBy`, returns a single\n * grand-total row (even for an empty input).\n */\nexport const reduceAggregate = (\n entries: UsageTrackingEntry[],\n options: AggregateUsageOptions = {},\n): UsageAggregateRow[] => {\n const emptyRow = (group: string | null): UsageAggregateRow => ({\n group,\n requests: 0,\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n cost: 0,\n satsCost: 0,\n baseMsats: 0,\n inputMsats: 0,\n outputMsats: 0,\n totalMsats: 0,\n totalUsd: 0,\n cacheReadInputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadMsats: 0,\n cacheCreationMsats: 0,\n });\n\n const accumulate = (row: UsageAggregateRow, entry: UsageTrackingEntry): void => {\n row.requests += 1;\n row.promptTokens += entry.promptTokens;\n row.completionTokens += entry.completionTokens;\n row.totalTokens += entry.totalTokens;\n row.cost += entry.cost;\n row.satsCost += entry.satsCost;\n row.baseMsats += entry.baseMsats ?? 0;\n row.inputMsats += entry.inputMsats ?? 0;\n row.outputMsats += entry.outputMsats ?? 0;\n row.totalMsats += entry.totalMsats ?? 0;\n row.totalUsd += entry.totalUsd ?? 0;\n row.cacheReadInputTokens += entry.cacheReadInputTokens ?? 0;\n row.cacheCreationInputTokens += entry.cacheCreationInputTokens ?? 0;\n row.cacheReadMsats += entry.cacheReadMsats ?? 0;\n row.cacheCreationMsats += entry.cacheCreationMsats ?? 0;\n };\n\n if (!options.groupBy) {\n const total = emptyRow(null);\n for (const entry of entries) accumulate(total, entry);\n return [total];\n }\n\n const tz = options.tzOffsetMinutes ?? 0;\n const groups = new Map<string | null, UsageAggregateRow>();\n for (const entry of entries) {\n const key = jsGroupKey(entry, options.groupBy, tz);\n let row = groups.get(key);\n if (!row) {\n row = emptyRow(key);\n groups.set(key, row);\n }\n accumulate(row, entry);\n }\n\n const rows = [...groups.values()];\n if (options.groupBy === \"day\" || options.groupBy === \"hour\") {\n rows.sort((a, b) => (a.group ?? \"\").localeCompare(b.group ?? \"\"));\n } else {\n rows.sort((a, b) => b.satsCost - a.satsCost);\n }\n return rows;\n};\n","import { SDK_STORAGE_KEYS } from \"../keys\";\nimport type { StorageDriver } from \"../types\";\nimport type {\n AggregateUsageOptions,\n ListUsageTrackingOptions,\n UsageAggregateRow,\n UsageTrackingDriver,\n} from \"./interfaces\";\nimport type { UsageTrackingEntry } from \"./types\";\nimport { reduceAggregate } from \"./aggregate\";\n\nexport interface IndexedDBUsageTrackingDriverOptions {\n dbName?: string;\n storeName?: string;\n legacyStorageDriver?: StorageDriver;\n}\n\nconst DEFAULT_DB_NAME = \"routstr-sdk\";\nconst DEFAULT_STORE_NAME = \"usage_tracking\";\nconst MIGRATION_MARKER_KEY = \"usage_tracking_migration_v1\";\n\nconst isBrowser = typeof indexedDB !== \"undefined\";\n\nconst normalizeBaseUrl = (baseUrl: string): string =>\n baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n\nconst openDatabase = (\n dbName: string,\n storeName: string\n): Promise<IDBDatabase> => {\n if (!isBrowser) {\n return Promise.reject(new Error(\"IndexedDB is not available\"));\n }\n\n return new Promise((resolve, reject) => {\n // Version 3 — adds a `provider` index on the usage_tracking store.\n const request = indexedDB.open(dbName, 3);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n const tx = request.transaction;\n // Create our own store\n if (!db.objectStoreNames.contains(storeName)) {\n const store = db.createObjectStore(storeName, { keyPath: \"id\" });\n store.createIndex(\"timestamp\", \"timestamp\", { unique: false });\n store.createIndex(\"modelId\", \"modelId\", { unique: false });\n store.createIndex(\"baseUrl\", \"baseUrl\", { unique: false });\n store.createIndex(\"sessionId\", \"sessionId\", { unique: false });\n store.createIndex(\"client\", \"client\", { unique: false });\n store.createIndex(\"provider\", \"provider\", { unique: false });\n } else if (tx) {\n // Existing store from an older version — add the new index in place.\n const store = tx.objectStore(storeName);\n if (!store.indexNames.contains(\"provider\")) {\n store.createIndex(\"provider\", \"provider\", { unique: false });\n }\n }\n // Also create sdk_storage if it doesn't exist (cross-driver init)\n if (storeName !== \"sdk_storage\" && !db.objectStoreNames.contains(\"sdk_storage\")) {\n db.createObjectStore(\"sdk_storage\");\n }\n };\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n request.onblocked = () => {\n console.warn(\n `[usageTracking IndexedDB] open blocked for \"${dbName}\" — close other tabs using this DB`\n );\n reject(new Error(`IndexedDB \"${dbName}\" blocked by another connection`));\n };\n });\n};\n\nconst matchesFilters = (\n entry: UsageTrackingEntry,\n options: Omit<ListUsageTrackingOptions, \"limit\"> = {}\n): boolean => {\n if (typeof options.before === \"number\" && entry.timestamp >= options.before) {\n return false;\n }\n if (typeof options.after === \"number\" && entry.timestamp <= options.after) {\n return false;\n }\n if (options.modelId && entry.modelId !== options.modelId) {\n return false;\n }\n if (options.baseUrl && normalizeBaseUrl(entry.baseUrl) !== normalizeBaseUrl(options.baseUrl)) {\n return false;\n }\n if (options.sessionId && entry.sessionId !== options.sessionId) {\n return false;\n }\n if (options.client && entry.client !== options.client) {\n return false;\n }\n if (\n options.clients &&\n options.clients.length > 0 &&\n (entry.client == null || !options.clients.includes(entry.client))\n ) {\n return false;\n }\n if (options.provider && entry.provider !== options.provider) {\n return false;\n }\n return true;\n};\n\nexport const createIndexedDBUsageTrackingDriver = (\n options: IndexedDBUsageTrackingDriverOptions = {}\n): UsageTrackingDriver => {\n const dbName = options.dbName || DEFAULT_DB_NAME;\n const storeName = options.storeName || DEFAULT_STORE_NAME;\n const legacyStorageDriver = options.legacyStorageDriver;\n\n let dbPromise: Promise<IDBDatabase> | null = null;\n let migrationPromise: Promise<void> | null = null;\n\n const getDb = (): Promise<IDBDatabase> => {\n if (!dbPromise) {\n dbPromise = openDatabase(dbName, storeName);\n }\n return dbPromise;\n };\n\n const putMany = async (entries: UsageTrackingEntry[]): Promise<void> => {\n if (entries.length === 0) return;\n const db = await getDb();\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(storeName, \"readwrite\");\n const store = tx.objectStore(storeName);\n for (const entry of entries) {\n store.put({ ...entry, baseUrl: normalizeBaseUrl(entry.baseUrl) });\n }\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n };\n\n const ensureMigrated = async (): Promise<void> => {\n if (!legacyStorageDriver) return;\n if (!migrationPromise) {\n migrationPromise = (async () => {\n const migrated = await legacyStorageDriver.getItem<boolean>(\n MIGRATION_MARKER_KEY,\n false\n );\n if (migrated) return;\n\n const legacyEntries = await legacyStorageDriver.getItem<UsageTrackingEntry[]>(\n SDK_STORAGE_KEYS.USAGE_TRACKING,\n []\n );\n\n if (legacyEntries.length > 0) {\n await putMany(legacyEntries);\n await legacyStorageDriver.removeItem(SDK_STORAGE_KEYS.USAGE_TRACKING);\n }\n\n await legacyStorageDriver.setItem(MIGRATION_MARKER_KEY, true);\n })();\n }\n await migrationPromise;\n };\n\n return {\n async migrate(): Promise<void> {\n await ensureMigrated();\n },\n\n async append(entry: UsageTrackingEntry): Promise<void> {\n await ensureMigrated();\n await putMany([entry]);\n },\n\n async appendMany(entries: UsageTrackingEntry[]): Promise<void> {\n await ensureMigrated();\n await putMany(entries);\n },\n\n async list(options: ListUsageTrackingOptions = {}): Promise<UsageTrackingEntry[]> {\n await ensureMigrated();\n const db = await getDb();\n return new Promise<UsageTrackingEntry[]>((resolve, reject) => {\n const tx = db.transaction(storeName, \"readonly\");\n const store = tx.objectStore(storeName);\n const index = store.index(\"timestamp\");\n const direction: IDBCursorDirection = \"prev\";\n const request = index.openCursor(null, direction);\n const results: UsageTrackingEntry[] = [];\n const limit = options.limit;\n\n request.onsuccess = () => {\n const cursor = request.result;\n if (!cursor) {\n resolve(results);\n return;\n }\n\n const value = cursor.value as UsageTrackingEntry;\n if (matchesFilters(value, options)) {\n results.push(value);\n if (typeof limit === \"number\" && results.length >= limit) {\n resolve(results);\n return;\n }\n }\n cursor.continue();\n };\n\n request.onerror = () => reject(request.error);\n });\n },\n\n async count(options: Omit<ListUsageTrackingOptions, \"limit\"> = {}): Promise<number> {\n const results = await this.list(options);\n return results.length;\n },\n\n async aggregate(options: AggregateUsageOptions = {}): Promise<UsageAggregateRow[]> {\n const entries = await this.list(options);\n return reduceAggregate(entries, options);\n },\n\n async deleteOlderThan(timestamp: number): Promise<number> {\n await ensureMigrated();\n const db = await getDb();\n return new Promise<number>((resolve, reject) => {\n const tx = db.transaction(storeName, \"readwrite\");\n const store = tx.objectStore(storeName);\n const index = store.index(\"timestamp\");\n const range = IDBKeyRange.upperBound(timestamp, true);\n const request = index.openCursor(range);\n let deleted = 0;\n\n request.onsuccess = () => {\n const cursor = request.result;\n if (!cursor) {\n resolve(deleted);\n return;\n }\n deleted += 1;\n cursor.delete();\n cursor.continue();\n };\n\n request.onerror = () => reject(request.error);\n });\n },\n\n async clear(): Promise<void> {\n await ensureMigrated();\n const db = await getDb();\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(storeName, \"readwrite\");\n tx.objectStore(storeName).clear();\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n },\n };\n};\n","import type {\n AggregateUsageOptions,\n ListUsageTrackingOptions,\n UsageAggregateRow,\n UsageTrackingDriver,\n} from \"./interfaces\";\nimport type { UsageTrackingEntry } from \"./types\";\nimport { reduceAggregate } from \"./aggregate\";\n\nconst normalizeBaseUrl = (baseUrl: string): string =>\n baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n\nconst matchesFilters = (\n entry: UsageTrackingEntry,\n options: Omit<ListUsageTrackingOptions, \"limit\"> = {}\n): boolean => {\n if (typeof options.before === \"number\" && entry.timestamp >= options.before) {\n return false;\n }\n if (typeof options.after === \"number\" && entry.timestamp <= options.after) {\n return false;\n }\n if (options.modelId && entry.modelId !== options.modelId) {\n return false;\n }\n if (options.baseUrl && normalizeBaseUrl(entry.baseUrl) !== normalizeBaseUrl(options.baseUrl)) {\n return false;\n }\n if (options.sessionId && entry.sessionId !== options.sessionId) {\n return false;\n }\n if (options.client && entry.client !== options.client) {\n return false;\n }\n if (\n options.clients &&\n options.clients.length > 0 &&\n (entry.client == null || !options.clients.includes(entry.client))\n ) {\n return false;\n }\n if (options.provider && entry.provider !== options.provider) {\n return false;\n }\n return true;\n};\n\nexport const createMemoryUsageTrackingDriver = (\n seed: UsageTrackingEntry[] = []\n): UsageTrackingDriver => {\n const store = new Map<string, UsageTrackingEntry>();\n\n for (const entry of seed) {\n store.set(entry.id, { ...entry, baseUrl: normalizeBaseUrl(entry.baseUrl) });\n }\n\n return {\n async migrate(): Promise<void> {\n return;\n },\n\n async append(entry: UsageTrackingEntry): Promise<void> {\n store.set(entry.id, { ...entry, baseUrl: normalizeBaseUrl(entry.baseUrl) });\n },\n\n async appendMany(entries: UsageTrackingEntry[]): Promise<void> {\n for (const entry of entries) {\n store.set(entry.id, { ...entry, baseUrl: normalizeBaseUrl(entry.baseUrl) });\n }\n },\n\n async list(options: ListUsageTrackingOptions = {}): Promise<UsageTrackingEntry[]> {\n const entries = [...store.values()]\n .filter((entry) => matchesFilters(entry, options))\n .sort((a, b) => b.timestamp - a.timestamp);\n if (typeof options.limit === \"number\") {\n return entries.slice(0, options.limit);\n }\n return entries;\n },\n\n async count(options: Omit<ListUsageTrackingOptions, \"limit\"> = {}): Promise<number> {\n return (await this.list(options)).length;\n },\n\n async aggregate(options: AggregateUsageOptions = {}): Promise<UsageAggregateRow[]> {\n const entries = [...store.values()].filter((entry) => matchesFilters(entry, options));\n return reduceAggregate(entries, options);\n },\n\n async deleteOlderThan(timestamp: number): Promise<number> {\n let deleted = 0;\n for (const [id, entry] of store.entries()) {\n if (entry.timestamp < timestamp) {\n store.delete(id);\n deleted += 1;\n }\n }\n return deleted;\n },\n\n async clear(): Promise<void> {\n store.clear();\n },\n };\n};\n","import { createStore, type StoreApi } from \"zustand/vanilla\";\nimport type { DiscoveryAdapter } from \"../discovery/interfaces\";\nimport type { StorageAdapter, ProviderRegistry } from \"../wallet/interfaces\";\nimport type { ProviderInfo, Model, SdkLogger } from \"../core\";\nimport { consoleLogger } from \"../core/types\";\nimport { SDK_STORAGE_KEYS } from \"./keys\";\nimport type { StorageDriver, SdkStorageState } from \"./types\";\n\nconst normalizeBaseUrl = (baseUrl: string): string =>\n baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n\nexport interface SdkStoreOptions {\n driver: StorageDriver;\n}\n\nexport interface SdkStorageStore extends SdkStorageState {\n setModelsFromAllProviders: (value: Record<string, Model[]>) => void;\n setLastUsedModel: (value: string | null) => void;\n setBaseUrlsList: (value: string[]) => void;\n setBaseUrlsLastUpdate: (value: number | null) => void;\n setDisabledProviders: (value: string[]) => void;\n setMintsFromAllProviders: (value: Record<string, string[]>) => void;\n setInfoFromAllProviders: (value: Record<string, ProviderInfo>) => void;\n setLastModelsUpdate: (value: Record<string, number>) => void;\n setApiKeys: (\n value:\n | Array<{\n baseUrl: string;\n key: string;\n balance?: number;\n lastUsed?: number | null;\n }>\n | ((current: SdkStorageStore[\"apiKeys\"]) => SdkStorageStore[\"apiKeys\"])\n ) => void;\n setChildKeys: (\n value: Array<{\n parentBaseUrl: string;\n childKey: string;\n balance?: number;\n balanceLimit?: number;\n validityDate?: number;\n createdAt?: number;\n }>\n ) => void;\n setXcashuTokens: (\n value: Record<\n string,\n Array<{\n baseUrl: string;\n token: string;\n createdAt?: number;\n tryCount?: number;\n }>\n >\n ) => void;\n updateXcashuTokenTryCount: (token: string, tryCount: number) => void;\n setRoutstr21Models: (value: string[]) => void;\n setRoutstr21ModelsLastUpdate: (value: number | null) => void;\n setCachedReceiveTokens: (\n value: Array<{\n token: string;\n amount: number;\n unit: \"sat\" | \"msat\";\n createdAt?: number;\n }>\n ) => void;\n setClientIds: (\n value:\n | Array<{\n clientId: string;\n name: string;\n apiKey: string;\n createdAt?: number;\n lastUsed?: number | null;\n }>\n | ((\n current: SdkStorageStore[\"clientIds\"]\n ) => SdkStorageStore[\"clientIds\"])\n ) => void;\n // ========== Failure Tracking ==========\n setFailedProviders: (value: string[]) => void;\n addFailedProvider: (baseUrl: string) => void;\n removeFailedProvider: (baseUrl: string) => void;\n setLastFailed: (value: Record<string, number>) => void;\n setLastFailedTimestamp: (baseUrl: string, timestamp: number) => void;\n setProvidersOnCooldown: (\n value: Array<{ baseUrl: string; timestamp: number }>\n ) => void;\n addProviderOnCooldown: (baseUrl: string, timestamp: number) => void;\n removeProviderFromCooldown: (baseUrl: string) => void;\n clearProvidersOnCooldown: () => void;\n}\n\n/** Store type returned after async initialization */\nexport type SdkStore = StoreApi<SdkStorageStore>;\n\nconst createEmptyStore = (driver: StorageDriver): SdkStore =>\n createStore<SdkStorageStore>((set, get) => ({\n modelsFromAllProviders: {},\n lastUsedModel: null,\n baseUrlsList: [],\n lastBaseUrlsUpdate: null,\n disabledProviders: [],\n mintsFromAllProviders: {},\n infoFromAllProviders: {},\n lastModelsUpdate: {},\n apiKeys: [],\n childKeys: [],\n xcashuTokens: {},\n routstr21Models: [],\n lastRoutstr21ModelsUpdate: null,\n cachedReceiveTokens: [],\n clientIds: [],\n failedProviders: [],\n lastFailed: {},\n providersOnCooldown: [],\n setModelsFromAllProviders: (value) => {\n const normalized: Record<string, Model[]> = {};\n for (const [baseUrl, models] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = models;\n }\n void driver.setItem(\n SDK_STORAGE_KEYS.MODELS_FROM_ALL_PROVIDERS,\n normalized\n );\n set({ modelsFromAllProviders: normalized });\n },\n setLastUsedModel: (value) => {\n void driver.setItem(SDK_STORAGE_KEYS.LAST_USED_MODEL, value);\n set({ lastUsedModel: value });\n },\n setBaseUrlsList: (value) => {\n const normalized = value.map((url) => normalizeBaseUrl(url));\n void driver.setItem(SDK_STORAGE_KEYS.BASE_URLS_LIST, normalized);\n set({ baseUrlsList: normalized });\n },\n setBaseUrlsLastUpdate: (value) => {\n void driver.setItem(SDK_STORAGE_KEYS.LAST_BASE_URLS_UPDATE, value);\n set({ lastBaseUrlsUpdate: value });\n },\n setDisabledProviders: (value) => {\n const normalized = value.map((url) => normalizeBaseUrl(url));\n void driver.setItem(SDK_STORAGE_KEYS.DISABLED_PROVIDERS, normalized);\n set({ disabledProviders: normalized });\n },\n setMintsFromAllProviders: (value) => {\n const normalized: Record<string, string[]> = {};\n for (const [baseUrl, mints] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = mints.map((mint) =>\n mint.endsWith(\"/\") ? mint.slice(0, -1) : mint\n );\n }\n void driver.setItem(\n SDK_STORAGE_KEYS.MINTS_FROM_ALL_PROVIDERS,\n normalized\n );\n set({ mintsFromAllProviders: normalized });\n },\n setInfoFromAllProviders: (value) => {\n const normalized: Record<string, ProviderInfo> = {};\n for (const [baseUrl, info] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = info;\n }\n void driver.setItem(SDK_STORAGE_KEYS.INFO_FROM_ALL_PROVIDERS, normalized);\n set({ infoFromAllProviders: normalized });\n },\n setLastModelsUpdate: (value) => {\n const normalized: Record<string, number> = {};\n for (const [baseUrl, timestamp] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = timestamp;\n }\n void driver.setItem(SDK_STORAGE_KEYS.LAST_MODELS_UPDATE, normalized);\n set({ lastModelsUpdate: normalized });\n },\n setApiKeys: (value) => {\n set((state) => {\n const updates =\n typeof value === \"function\" ? value(state.apiKeys) : value;\n const normalized = updates.map((entry) => ({\n ...entry,\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n balance: entry.balance ?? 0,\n lastUsed: entry.lastUsed ?? null,\n }));\n void driver.setItem(SDK_STORAGE_KEYS.API_KEYS, normalized);\n return { apiKeys: normalized };\n });\n },\n setChildKeys: (\n value:\n | Array<{\n parentBaseUrl: string;\n childKey: string;\n balance?: number;\n balanceLimit?: number;\n validityDate?: number;\n createdAt?: number;\n }>\n | ((\n current: SdkStorageStore[\"childKeys\"]\n ) => SdkStorageStore[\"childKeys\"])\n ) => {\n set((state) => {\n const updates =\n typeof value === \"function\" ? value(state.childKeys) : value;\n const normalized = updates.map((entry) => ({\n parentBaseUrl: normalizeBaseUrl(entry.parentBaseUrl),\n childKey: entry.childKey,\n balance: entry.balance ?? 0,\n balanceLimit: entry.balanceLimit,\n validityDate: entry.validityDate,\n createdAt: entry.createdAt ?? Date.now(),\n }));\n void driver.setItem(SDK_STORAGE_KEYS.CHILD_KEYS, normalized);\n return { childKeys: normalized };\n });\n },\n setXcashuTokens: (value) => {\n const normalized: Record<\n string,\n Array<{\n baseUrl: string;\n token: string;\n createdAt: number;\n tryCount: number;\n }>\n > = {};\n for (const [baseUrl, tokens] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = tokens.map((entry) => ({\n ...entry,\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n createdAt: entry.createdAt ?? Date.now(),\n tryCount: entry.tryCount ?? 0,\n }));\n }\n void driver.setItem(SDK_STORAGE_KEYS.XCASHU_TOKENS, normalized);\n set({ xcashuTokens: normalized });\n },\n updateXcashuTokenTryCount: (token, tryCount) => {\n const currentTokens = get().xcashuTokens;\n const updatedTokens: Record<\n string,\n Array<{\n baseUrl: string;\n token: string;\n createdAt: number;\n tryCount: number;\n }>\n > = {};\n\n for (const [baseUrl, tokens] of Object.entries(currentTokens)) {\n updatedTokens[baseUrl] = tokens.map((entry) =>\n entry.token === token ? { ...entry, tryCount } : entry\n );\n }\n\n void driver.setItem(SDK_STORAGE_KEYS.XCASHU_TOKENS, updatedTokens);\n set({ xcashuTokens: updatedTokens });\n },\n setRoutstr21Models: (value) => {\n void driver.setItem(SDK_STORAGE_KEYS.ROUTSTR21_MODELS, value);\n set({ routstr21Models: value });\n },\n setRoutstr21ModelsLastUpdate: (value) => {\n void driver.setItem(SDK_STORAGE_KEYS.LAST_ROUTSTR21_MODELS_UPDATE, value);\n set({ lastRoutstr21ModelsUpdate: value });\n },\n setCachedReceiveTokens: (value) => {\n const normalized = value.map((entry) => ({\n token: entry.token,\n amount: entry.amount,\n unit: entry.unit || \"sat\",\n createdAt: entry.createdAt ?? Date.now(),\n }));\n void driver.setItem(SDK_STORAGE_KEYS.CACHED_RECEIVE_TOKENS, normalized);\n set({ cachedReceiveTokens: normalized });\n },\n setClientIds: (value) => {\n set((state) => {\n const updates =\n typeof value === \"function\" ? value(state.clientIds) : value;\n const normalized = updates.map((entry) => ({\n ...entry,\n createdAt: entry.createdAt ?? Date.now(),\n lastUsed: entry.lastUsed ?? null,\n }));\n void driver.setItem(SDK_STORAGE_KEYS.CLIENT_IDS, normalized);\n return { clientIds: normalized };\n });\n },\n // ========== Failure Tracking ==========\n setFailedProviders: (value) => {\n const normalized = value.map((url) => normalizeBaseUrl(url));\n void driver.setItem(SDK_STORAGE_KEYS.FAILED_PROVIDERS, normalized);\n set({ failedProviders: normalized });\n },\n addFailedProvider: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const current = get().failedProviders;\n if (!current.includes(normalized)) {\n const updated = [...current, normalized];\n void driver.setItem(SDK_STORAGE_KEYS.FAILED_PROVIDERS, updated);\n set({ failedProviders: updated });\n }\n },\n removeFailedProvider: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const current = get().failedProviders;\n const updated = current.filter((url) => url !== normalized);\n void driver.setItem(SDK_STORAGE_KEYS.FAILED_PROVIDERS, updated);\n set({ failedProviders: updated });\n },\n setLastFailed: (value) => {\n const normalized: Record<string, number> = {};\n for (const [baseUrl, timestamp] of Object.entries(value)) {\n normalized[normalizeBaseUrl(baseUrl)] = timestamp;\n }\n void driver.setItem(SDK_STORAGE_KEYS.LAST_FAILED, normalized);\n set({ lastFailed: normalized });\n },\n setLastFailedTimestamp: (baseUrl, timestamp) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const current = get().lastFailed;\n const updated = { ...current, [normalized]: timestamp };\n void driver.setItem(SDK_STORAGE_KEYS.LAST_FAILED, updated);\n set({ lastFailed: updated });\n },\n setProvidersOnCooldown: (value) => {\n const normalized = value.map((entry) => ({\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n timestamp: entry.timestamp,\n }));\n void driver.setItem(SDK_STORAGE_KEYS.PROVIDERS_ON_COOLDOWN, normalized);\n set({ providersOnCooldown: normalized });\n },\n addProviderOnCooldown: (baseUrl, timestamp) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const current = get().providersOnCooldown;\n if (!current.some((entry) => entry.baseUrl === normalized)) {\n const updated = [...current, { baseUrl: normalized, timestamp }];\n void driver.setItem(SDK_STORAGE_KEYS.PROVIDERS_ON_COOLDOWN, updated);\n set({ providersOnCooldown: updated });\n }\n },\n removeProviderFromCooldown: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const current = get().providersOnCooldown;\n const updated = current.filter((entry) => entry.baseUrl !== normalized);\n void driver.setItem(SDK_STORAGE_KEYS.PROVIDERS_ON_COOLDOWN, updated);\n set({ providersOnCooldown: updated });\n },\n clearProvidersOnCooldown: () => {\n void driver.setItem(SDK_STORAGE_KEYS.PROVIDERS_ON_COOLDOWN, []);\n set({ providersOnCooldown: [] });\n },\n }));\n\nconst hydrateStoreFromDriver = async (\n store: SdkStore,\n driver: StorageDriver\n): Promise<void> => {\n const [\n rawModels,\n lastUsedModel,\n rawBaseUrls,\n lastBaseUrlsUpdate,\n rawDisabledProviders,\n rawMints,\n rawInfo,\n rawLastModelsUpdate,\n rawApiKeys,\n rawChildKeys,\n rawXcashuTokens,\n rawRoutstr21Models,\n rawLastRoutstr21ModelsUpdate,\n rawCachedReceiveTokens,\n rawClientIds,\n rawFailedProviders,\n rawLastFailed,\n rawProvidersOnCooldown,\n ] = await Promise.all([\n driver.getItem<Record<string, Model[]>>(\n SDK_STORAGE_KEYS.MODELS_FROM_ALL_PROVIDERS,\n {}\n ),\n driver.getItem<string | null>(SDK_STORAGE_KEYS.LAST_USED_MODEL, null),\n driver.getItem<string[]>(SDK_STORAGE_KEYS.BASE_URLS_LIST, []),\n driver.getItem<number | null>(SDK_STORAGE_KEYS.LAST_BASE_URLS_UPDATE, null),\n driver.getItem<string[]>(SDK_STORAGE_KEYS.DISABLED_PROVIDERS, []),\n driver.getItem<Record<string, string[]>>(\n SDK_STORAGE_KEYS.MINTS_FROM_ALL_PROVIDERS,\n {}\n ),\n driver.getItem<Record<string, ProviderInfo>>(\n SDK_STORAGE_KEYS.INFO_FROM_ALL_PROVIDERS,\n {}\n ),\n driver.getItem<Record<string, number>>(\n SDK_STORAGE_KEYS.LAST_MODELS_UPDATE,\n {}\n ),\n driver.getItem<\n Array<{\n baseUrl: string;\n key: string;\n balance?: number;\n lastUsed?: number | null;\n }>\n >(SDK_STORAGE_KEYS.API_KEYS, []),\n driver.getItem<\n Array<{\n parentBaseUrl: string;\n childKey: string;\n balance?: number;\n balanceLimit?: number;\n validityDate?: number;\n createdAt?: number;\n }>\n >(SDK_STORAGE_KEYS.CHILD_KEYS, []),\n driver.getItem<\n Record<\n string,\n Array<{\n baseUrl: string;\n token: string;\n createdAt?: number;\n tryCount?: number;\n }>\n >\n >(SDK_STORAGE_KEYS.XCASHU_TOKENS, {}),\n driver.getItem<string[]>(SDK_STORAGE_KEYS.ROUTSTR21_MODELS, []),\n driver.getItem<number | null>(\n SDK_STORAGE_KEYS.LAST_ROUTSTR21_MODELS_UPDATE,\n null\n ),\n driver.getItem<\n Array<{\n token: string;\n amount: number;\n unit: \"sat\" | \"msat\";\n createdAt?: number;\n }>\n >(SDK_STORAGE_KEYS.CACHED_RECEIVE_TOKENS, []),\n driver.getItem<\n Array<{\n clientId: string;\n name: string;\n apiKey: string;\n createdAt?: number;\n lastUsed?: number | null;\n }>\n >(SDK_STORAGE_KEYS.CLIENT_IDS, []),\n driver.getItem<string[]>(SDK_STORAGE_KEYS.FAILED_PROVIDERS, []),\n driver.getItem<Record<string, number>>(SDK_STORAGE_KEYS.LAST_FAILED, {}),\n driver.getItem<Array<{ baseUrl: string; timestamp: number }>>(\n SDK_STORAGE_KEYS.PROVIDERS_ON_COOLDOWN,\n []\n ),\n ]);\n\n const modelsFromAllProviders = Object.fromEntries(\n Object.entries(rawModels).map(([baseUrl, models]) => [\n normalizeBaseUrl(baseUrl),\n models,\n ])\n );\n\n const baseUrlsList = rawBaseUrls.map((url) => normalizeBaseUrl(url));\n\n const disabledProviders = rawDisabledProviders.map((url) =>\n normalizeBaseUrl(url)\n );\n\n const mintsFromAllProviders = Object.fromEntries(\n Object.entries(rawMints).map(([baseUrl, mints]) => [\n normalizeBaseUrl(baseUrl),\n mints.map((mint) => (mint.endsWith(\"/\") ? mint.slice(0, -1) : mint)),\n ])\n );\n\n const infoFromAllProviders = Object.fromEntries(\n Object.entries(rawInfo).map(([baseUrl, info]) => [\n normalizeBaseUrl(baseUrl),\n info,\n ])\n );\n\n const lastModelsUpdate = Object.fromEntries(\n Object.entries(rawLastModelsUpdate).map(([baseUrl, timestamp]) => [\n normalizeBaseUrl(baseUrl),\n timestamp,\n ])\n );\n\n const apiKeys = rawApiKeys.map((entry) => ({\n ...entry,\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n balance: entry.balance ?? 0,\n lastUsed: entry.lastUsed ?? null,\n }));\n\n const childKeys = rawChildKeys.map((entry) => ({\n parentBaseUrl: normalizeBaseUrl(entry.parentBaseUrl),\n childKey: entry.childKey,\n balance: entry.balance ?? 0,\n balanceLimit: entry.balanceLimit,\n validityDate: entry.validityDate,\n createdAt: entry.createdAt ?? Date.now(),\n }));\n\n const xcashuTokens = Object.fromEntries(\n Object.entries(rawXcashuTokens).map(([baseUrl, tokens]) => [\n normalizeBaseUrl(baseUrl),\n tokens.map((entry) => ({\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n token: entry.token,\n createdAt: entry.createdAt ?? Date.now(),\n tryCount: entry.tryCount ?? 0,\n })),\n ])\n );\n\n const routstr21Models = rawRoutstr21Models;\n const lastRoutstr21ModelsUpdate = rawLastRoutstr21ModelsUpdate;\n\n const cachedReceiveTokens = rawCachedReceiveTokens?.map((entry) => ({\n token: entry.token,\n amount: entry.amount,\n unit: entry.unit || \"sat\",\n createdAt: entry.createdAt ?? Date.now(),\n }));\n\n const clientIds = rawClientIds.map((entry) => ({\n ...entry,\n createdAt: entry.createdAt ?? Date.now(),\n lastUsed: entry.lastUsed ?? null,\n }));\n\n const failedProviders = rawFailedProviders.map((url) =>\n normalizeBaseUrl(url)\n );\n const lastFailed = Object.fromEntries(\n Object.entries(rawLastFailed).map(([baseUrl, timestamp]) => [\n normalizeBaseUrl(baseUrl),\n timestamp,\n ])\n );\n const providersOnCooldown = rawProvidersOnCooldown.map((entry) => ({\n baseUrl: normalizeBaseUrl(entry.baseUrl),\n timestamp: entry.timestamp,\n }));\n\n store.setState({\n modelsFromAllProviders,\n lastUsedModel,\n baseUrlsList,\n lastBaseUrlsUpdate,\n disabledProviders,\n mintsFromAllProviders,\n infoFromAllProviders,\n lastModelsUpdate,\n apiKeys,\n childKeys,\n xcashuTokens,\n routstr21Models,\n lastRoutstr21ModelsUpdate,\n cachedReceiveTokens,\n clientIds,\n failedProviders,\n lastFailed,\n providersOnCooldown,\n });\n};\n\nexport const createSdkStore = ({\n driver,\n}: SdkStoreOptions): { store: SdkStore; hydrate: Promise<void> } => {\n const store = createEmptyStore(driver);\n return {\n store,\n hydrate: hydrateStoreFromDriver(store, driver),\n };\n};\n\nexport const createDiscoveryAdapterFromStore = (\n store: SdkStore\n): DiscoveryAdapter => ({\n getCachedModels: () => store.getState().modelsFromAllProviders,\n setCachedModels: (models) =>\n store.getState().setModelsFromAllProviders(models),\n getCachedMints: () => store.getState().mintsFromAllProviders,\n setCachedMints: (mints) => store.getState().setMintsFromAllProviders(mints),\n getCachedProviderInfo: () => store.getState().infoFromAllProviders,\n setCachedProviderInfo: (info) =>\n store.getState().setInfoFromAllProviders(info),\n getProviderLastUpdate: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const timestamps = store.getState().lastModelsUpdate;\n return timestamps[normalized] || null;\n },\n setProviderLastUpdate: (baseUrl, timestamp) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const timestamps = { ...store.getState().lastModelsUpdate };\n timestamps[normalized] = timestamp;\n store.getState().setLastModelsUpdate(timestamps);\n },\n getLastUsedModel: () => store.getState().lastUsedModel,\n setLastUsedModel: (modelId) => store.getState().setLastUsedModel(modelId),\n getDisabledProviders: () => store.getState().disabledProviders,\n setDisabledProviders: (urls) => store.getState().setDisabledProviders(urls),\n getBaseUrlsList: () => store.getState().baseUrlsList,\n setBaseUrlsList: (urls) => store.getState().setBaseUrlsList(urls),\n getBaseUrlsLastUpdate: () => store.getState().lastBaseUrlsUpdate,\n setBaseUrlsLastUpdate: (timestamp) =>\n store.getState().setBaseUrlsLastUpdate(timestamp),\n getRoutstr21Models: () => store.getState().routstr21Models,\n setRoutstr21Models: (models) => store.getState().setRoutstr21Models(models),\n getRoutstr21ModelsLastUpdate: () =>\n store.getState().lastRoutstr21ModelsUpdate,\n setRoutstr21ModelsLastUpdate: (timestamp) =>\n store.getState().setRoutstr21ModelsLastUpdate(timestamp),\n});\n\nexport const createStorageAdapterFromStore = (\n store: SdkStore\n): StorageAdapter => ({\n getApiKeyDistribution: () => {\n const apiKeys = store.getState().apiKeys;\n const distributionMap: Record<string, number> = {};\n\n for (const entry of apiKeys) {\n const sum = entry.balance || 0;\n distributionMap[entry.baseUrl] =\n (distributionMap[entry.baseUrl] || 0) + sum;\n }\n\n return Object.entries(distributionMap)\n .map(([baseUrl, amt]) => ({ baseUrl, amount: amt }))\n .sort((a, b) => b.amount - a.amount);\n },\n saveProviderInfo: (baseUrl, info) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const next = { ...store.getState().infoFromAllProviders };\n next[normalized] = info;\n store.getState().setInfoFromAllProviders(next);\n },\n getProviderInfo: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n return store.getState().infoFromAllProviders[normalized] || null;\n },\n\n // ========== API Keys (for apikeys mode) ==========\n\n getApiKey: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const entry = store\n .getState()\n .apiKeys.find((key) => key.baseUrl === normalized);\n if (!entry) return null;\n return entry;\n },\n\n setApiKey: (baseUrl, key) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const keys = store.getState().apiKeys;\n const existingIndex = keys.findIndex(\n (entry) => entry.baseUrl === normalized\n );\n if (existingIndex !== -1) {\n throw new Error(`ApiKey already exists for baseUrl: ${normalized}`);\n }\n const next = [...keys];\n next.push({\n baseUrl: normalized,\n key,\n balance: 0,\n lastUsed: Date.now(),\n });\n store.getState().setApiKeys(next);\n },\n\n updateApiKeyBalance: (baseUrl, balance) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const keys = store.getState().apiKeys;\n const next = keys.map((entry) =>\n entry.baseUrl === normalized\n ? { ...entry, balance, lastUsed: Date.now() }\n : entry\n );\n store.getState().setApiKeys(next);\n },\n\n removeApiKey: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const next = store\n .getState()\n .apiKeys.filter((entry) => entry.baseUrl !== normalized);\n store.getState().setApiKeys(next);\n },\n\n getAllApiKeys: () => {\n return store.getState().apiKeys.map((entry) => ({\n baseUrl: entry.baseUrl,\n key: entry.key,\n balance: entry.balance,\n lastUsed: entry.lastUsed,\n }));\n },\n\n // ========== Child Keys ==========\n\n getChildKey: (parentBaseUrl) => {\n const normalized = normalizeBaseUrl(parentBaseUrl);\n const entry = store\n .getState()\n .childKeys.find((key) => key.parentBaseUrl === normalized);\n if (!entry) return null;\n return {\n parentBaseUrl: entry.parentBaseUrl,\n childKey: entry.childKey,\n balance: entry.balance,\n balanceLimit: entry.balanceLimit,\n validityDate: entry.validityDate,\n createdAt: entry.createdAt,\n };\n },\n\n setChildKey: (\n parentBaseUrl,\n childKey,\n balance,\n validityDate,\n balanceLimit\n ) => {\n const normalized = normalizeBaseUrl(parentBaseUrl);\n const keys = store.getState().childKeys;\n const existingIndex = keys.findIndex(\n (entry) => entry.parentBaseUrl === normalized\n );\n if (existingIndex !== -1) {\n // Update existing child key\n const next = keys.map((entry) =>\n entry.parentBaseUrl === normalized\n ? {\n ...entry,\n childKey,\n balance: balance ?? 0,\n validityDate,\n balanceLimit,\n createdAt: Date.now(),\n }\n : entry\n );\n store.getState().setChildKeys(next);\n } else {\n // Add new child key\n const next = [...keys];\n next.push({\n parentBaseUrl: normalized,\n childKey,\n balance: balance ?? 0,\n validityDate,\n balanceLimit,\n createdAt: Date.now(),\n });\n store.getState().setChildKeys(next);\n }\n },\n\n updateChildKeyBalance: (parentBaseUrl, balance) => {\n const normalized = normalizeBaseUrl(parentBaseUrl);\n const keys = store.getState().childKeys;\n const next = keys.map((entry) =>\n entry.parentBaseUrl === normalized ? { ...entry, balance } : entry\n );\n store.getState().setChildKeys(next);\n },\n\n removeChildKey: (parentBaseUrl) => {\n const normalized = normalizeBaseUrl(parentBaseUrl);\n const next = store\n .getState()\n .childKeys.filter((entry) => entry.parentBaseUrl !== normalized);\n store.getState().setChildKeys(next);\n },\n\n getAllChildKeys: () => {\n return store.getState().childKeys.map((entry) => ({\n parentBaseUrl: entry.parentBaseUrl,\n childKey: entry.childKey,\n balance: entry.balance,\n balanceLimit: entry.balanceLimit,\n validityDate: entry.validityDate,\n createdAt: entry.createdAt,\n }));\n },\n\n getCachedReceiveTokens: () => {\n return store.getState().cachedReceiveTokens;\n },\n\n setCachedReceiveTokens: (tokens) => {\n store.getState().setCachedReceiveTokens(tokens);\n },\n\n // ========== XCashu Tokens (multiple tokens per baseUrl) ==========\n\n getXcashuTokens: () => {\n return store.getState().xcashuTokens;\n },\n\n getXcashuTokensForBaseUrl: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n return store.getState().xcashuTokens[normalized] || [];\n },\n\n addXcashuToken: (baseUrl, token) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const tokens = store.getState().xcashuTokens;\n const existing = tokens[normalized] || [];\n const next = { ...tokens };\n next[normalized] = [\n ...existing,\n { baseUrl: normalized, token, createdAt: Date.now(), tryCount: 0 },\n ];\n store.getState().setXcashuTokens(next);\n },\n\n removeXcashuToken: (baseUrl, token) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const tokens = store.getState().xcashuTokens;\n const existing = tokens[normalized] || [];\n const next = { ...tokens };\n next[normalized] = existing.filter((entry) => entry.token !== token);\n if (next[normalized].length === 0) {\n delete next[normalized];\n }\n store.getState().setXcashuTokens(next);\n },\n\n clearXcashuTokensForBaseUrl: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const tokens = store.getState().xcashuTokens;\n const next = { ...tokens };\n delete next[normalized];\n store.getState().setXcashuTokens(next);\n },\n\n updateXcashuTokenTryCount: (token, tryCount) => {\n store.getState().updateXcashuTokenTryCount(token, tryCount);\n },\n});\n\nexport const createProviderRegistryFromStore = (\n store: SdkStore,\n logger?: SdkLogger\n): ProviderRegistry => {\n const log = (logger ?? consoleLogger).child(\"ProviderRegistry\");\n return {\n getModelsForProvider: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n return store.getState().modelsFromAllProviders[normalized] || [];\n },\n getDisabledProviders: () => store.getState().disabledProviders,\n getProviderMints: (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n return store.getState().mintsFromAllProviders[normalized] || [];\n },\n getProviderInfo: async (baseUrl) => {\n const normalized = normalizeBaseUrl(baseUrl);\n const cached = store.getState().infoFromAllProviders[normalized];\n if (cached) return cached;\n try {\n const response = await fetch(`${normalized}v1/info`);\n if (!response.ok) {\n throw new Error(`Failed ${response.status}`);\n }\n const info = (await response.json()) as ProviderInfo;\n const next = { ...store.getState().infoFromAllProviders };\n next[normalized] = info;\n store.getState().setInfoFromAllProviders(next);\n return info;\n } catch (error) {\n log.warn(`Failed to fetch provider info from ${normalized}:`, error);\n return null;\n }\n },\n getAllProvidersModels: () => store.getState().modelsFromAllProviders,\n };\n};\n","import { localStorageDriver } from \"./drivers/localStorage\";\nimport { createMemoryDriver } from \"./drivers/memory\";\nimport { createIndexedDBDriver } from \"./drivers/indexedDB\";\nimport {\n createIndexedDBUsageTrackingDriver,\n createMemoryUsageTrackingDriver,\n type UsageTrackingDriver,\n} from \"./usageTracking\";\nimport type { StorageDriver } from \"./types\";\nimport {\n createSdkStore,\n createStorageAdapterFromStore,\n type SdkStore,\n} from \"./store\";\nimport type { DiscoveryAdapter } from \"../discovery/interfaces\";\n\nexport type { StorageDriver } from \"./types\";\nexport type { SdkStore } from \"./store\";\nexport type { DiscoveryAdapter } from \"../discovery/interfaces\";\nexport type { StorageAdapter, ProviderRegistry, XCashuTokenEntry } from \"../wallet/interfaces\";\nexport type {\n AggregateUsageOptions,\n ListUsageTrackingOptions,\n UsageAggregateRow,\n UsageGroupBy,\n UsageTrackingDriver,\n UsageTrackingEntry,\n} from \"./usageTracking\";\nexport { SDK_STORAGE_KEYS } from \"./keys\";\nexport {\n createSdkStore,\n createDiscoveryAdapterFromStore,\n createProviderRegistryFromStore,\n createStorageAdapterFromStore,\n} from \"./store\";\nexport {\n localStorageDriver,\n createMemoryDriver,\n createIndexedDBDriver,\n};\nexport {\n createIndexedDBUsageTrackingDriver,\n createMemoryUsageTrackingDriver,\n} from \"./usageTracking\";\nimport {\n createProviderRegistryFromDiscoveryAdapter,\n createShardedDiscoveryAdapter,\n} from \"./shardedDiscoveryAdapter\";\nexport {\n createProviderRegistryFromDiscoveryAdapter,\n createShardedDiscoveryAdapter,\n} from \"./shardedDiscoveryAdapter\";\nexport type {\n ShardedDiscoveryAdapterOptions,\n} from \"./shardedDiscoveryAdapter\";\n\nconst isBrowser = (): boolean => {\n try {\n return (\n typeof window !== \"undefined\" &&\n typeof window.localStorage !== \"undefined\"\n );\n } catch {\n return false;\n }\n};\n\nlet defaultDriver: StorageDriver | null = null;\n\nexport const getDefaultSdkDriver = (): StorageDriver => {\n if (defaultDriver) return defaultDriver;\n if (isBrowser()) {\n defaultDriver = localStorageDriver;\n return defaultDriver;\n }\n defaultDriver = createMemoryDriver();\n return defaultDriver;\n};\n\nlet defaultStore: ReturnType<typeof createSdkStore> | null = null;\nlet defaultUsageTrackingDriver: UsageTrackingDriver | null = null;\n\nexport const getDefaultSdkStore = (): Promise<SdkStore> => {\n if (!defaultStore) {\n defaultStore = createSdkStore({ driver: getDefaultSdkDriver() });\n }\n return defaultStore.hydrate.then(() => defaultStore!.store);\n};\n\nexport const getDefaultUsageTrackingDriver = (): UsageTrackingDriver => {\n if (defaultUsageTrackingDriver) return defaultUsageTrackingDriver;\n\n const storageDriver = getDefaultSdkDriver();\n\n if (isBrowser()) {\n defaultUsageTrackingDriver = createIndexedDBUsageTrackingDriver({\n legacyStorageDriver: storageDriver,\n });\n return defaultUsageTrackingDriver;\n }\n\n defaultUsageTrackingDriver = createMemoryUsageTrackingDriver();\n return defaultUsageTrackingDriver;\n};\n\n/**\n * Allow setting a custom usage tracking driver (useful for routstrd to use proper DB path)\n */\nexport const setDefaultUsageTrackingDriver = (driver: UsageTrackingDriver): void => {\n defaultUsageTrackingDriver = driver;\n};\n\nlet defaultDiscoveryAdapter: DiscoveryAdapter | null = null;\n\nexport const getDefaultDiscoveryAdapter = async (): Promise<DiscoveryAdapter> => {\n if (defaultDiscoveryAdapter) return defaultDiscoveryAdapter;\n\n const driver = getDefaultSdkDriver();\n defaultDiscoveryAdapter = await createShardedDiscoveryAdapter({ driver });\n return defaultDiscoveryAdapter;\n};\n\nexport const getDefaultStorageAdapter = async () =>\n createStorageAdapterFromStore(await getDefaultSdkStore());\n\nexport const getDefaultProviderRegistry = async () =>\n createProviderRegistryFromDiscoveryAdapter(await getDefaultDiscoveryAdapter());\n","import type { UsageStats } from \"../core/types\";\n\nexport interface UsageTrackingData {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n cost: number;\n satsCost: number;\n /** Upstream provider/route that handled the request (e.g. \"openrouter:openrouter:Anthropic\"). */\n provider?: string;\n /** Full cost breakdown emitted by the upstream `cost` object. */\n baseMsats?: number;\n inputMsats?: number;\n outputMsats?: number;\n totalMsats?: number;\n totalUsd?: number;\n cacheReadInputTokens?: number;\n cacheCreationInputTokens?: number;\n cacheReadMsats?: number;\n cacheCreationMsats?: number;\n remainingBalanceMsats?: number;\n}\n\nconst numOrUndef = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n\n/**\n * Extract the detailed cost breakdown from an upstream `cost` object.\n * Returns the camelCased fields we persist on a UsageTrackingData/entry.\n */\nfunction extractCostBreakdown(\n costObj: Record<string, unknown> | null | undefined\n): Partial<UsageTrackingData> {\n if (!costObj || typeof costObj !== \"object\") return {};\n return {\n baseMsats: numOrUndef(costObj.base_msats),\n inputMsats: numOrUndef(costObj.input_msats),\n outputMsats: numOrUndef(costObj.output_msats),\n totalMsats: numOrUndef(costObj.total_msats),\n totalUsd: numOrUndef(costObj.total_usd),\n cacheReadInputTokens: numOrUndef(costObj.cache_read_input_tokens),\n cacheCreationInputTokens: numOrUndef(costObj.cache_creation_input_tokens),\n cacheReadMsats: numOrUndef(costObj.cache_read_msats),\n cacheCreationMsats: numOrUndef(costObj.cache_creation_msats),\n remainingBalanceMsats: numOrUndef(costObj.remaining_balance_msats),\n };\n}\n\nexport function extractUsageFromResponseBody(\n body: unknown,\n fallbackSatsCost = 0\n): UsageTrackingData | null {\n if (!body || typeof body !== \"object\") return null;\n const usage = (body as { usage?: Record<string, unknown> }).usage;\n if (!usage || typeof usage !== \"object\") return null;\n\n const promptTokens = Number(usage.prompt_tokens ?? 0);\n const completionTokens = Number(usage.completion_tokens ?? 0);\n const totalTokens = Number(usage.total_tokens ?? 0);\n const costValue = usage.cost;\n\n let cost = 0;\n let satsCost = fallbackSatsCost;\n let breakdown: Partial<UsageTrackingData> = {};\n\n if (typeof costValue === \"number\") {\n cost = costValue;\n } else if (costValue && typeof costValue === \"object\") {\n const costObj = costValue as Record<string, unknown>;\n const totalUsd = costObj.total_usd;\n const totalMsats = costObj.total_msats;\n\n cost = typeof totalUsd === \"number\" ? totalUsd : 0;\n if (typeof totalMsats === \"number\") {\n satsCost = totalMsats / 1000;\n }\n breakdown = extractCostBreakdown(costObj);\n }\n\n const provider =\n typeof (body as { provider?: unknown }).provider === \"string\"\n ? ((body as { provider?: string }).provider as string)\n : undefined;\n\n if (\n promptTokens === 0 &&\n completionTokens === 0 &&\n totalTokens === 0 &&\n cost === 0 &&\n satsCost === 0\n ) {\n return null;\n }\n\n return {\n promptTokens,\n completionTokens,\n totalTokens,\n cost,\n satsCost,\n provider,\n ...breakdown,\n };\n}\n\nexport function extractResponseId(body: unknown): string | undefined {\n if (!body || typeof body !== \"object\") return undefined;\n const id = (body as { id?: unknown }).id;\n if (typeof id !== \"string\") return undefined;\n const trimmed = id.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport function extractUsageFromSSEJson(\n parsed: any,\n fallbackSatsCost = 0\n): UsageTrackingData | null {\n if (!parsed || typeof parsed !== \"object\") {\n return null;\n }\n\n const provider =\n typeof parsed.provider === \"string\" ? parsed.provider : undefined;\n\n // Handle standalone cost chunk: {\"cost\":{\"base_msats\":...,\"input_msats\":...,\"output_msats\":...,\"total_msats\":2,...}}\n if (!parsed.usage && parsed.cost && typeof parsed.cost === \"object\") {\n const costObj = parsed.cost;\n const msats = costObj.total_msats ?? 0;\n const cost = costObj.total_usd ?? 0;\n if (msats === 0 && cost === 0) return null;\n return {\n promptTokens: Number(costObj.input_tokens ?? 0),\n completionTokens: Number(costObj.output_tokens ?? 0),\n totalTokens: Number((costObj.input_tokens ?? 0) + (costObj.output_tokens ?? 0)),\n cost: Number(cost),\n satsCost: msats > 0 ? msats / 1000 : fallbackSatsCost,\n provider,\n ...extractCostBreakdown(costObj),\n };\n }\n\n if (!parsed.usage) {\n return null;\n }\n\n const usage = parsed.usage;\n const usageCost = usage.cost;\n \n let cost = 0;\n let msats = 0;\n let breakdown: Partial<UsageTrackingData> = {};\n\n if (typeof usageCost === \"number\") {\n cost = usageCost;\n } else if (usageCost && typeof usageCost === \"object\") {\n cost = usageCost.total_usd ?? 0;\n msats = usageCost.total_msats ?? 0;\n breakdown = extractCostBreakdown(usageCost as Record<string, unknown>);\n }\n\n // Some upstreams put the detailed breakdown under metadata.routstr.cost.\n const routstrCost = parsed.metadata?.routstr?.cost;\n if (routstrCost && typeof routstrCost === \"object\") {\n breakdown = { ...extractCostBreakdown(routstrCost), ...breakdown };\n }\n\n // Fallbacks if not in usage.cost\n if (cost === 0) {\n cost = parsed.metadata?.routstr?.cost?.total_usd ?? 0;\n }\n if (msats === 0) {\n msats =\n parsed.metadata?.routstr?.cost?.total_msats ??\n (typeof usage.cost_sats === \"number\" ? usage.cost_sats * 1000 : 0);\n }\n\n // Support both OpenAI-style (prompt_tokens/completion_tokens) and Anthropic-style (input_tokens/output_tokens)\n const promptTokens = Number(usage.prompt_tokens ?? usage.input_tokens ?? 0);\n const completionTokens = Number(usage.completion_tokens ?? usage.output_tokens ?? 0);\n const totalTokens = Number(usage.total_tokens ?? (promptTokens + completionTokens));\n\n const result: UsageTrackingData = {\n promptTokens,\n completionTokens,\n totalTokens,\n cost: Number(cost ?? 0),\n satsCost: msats > 0 ? msats / 1000 : fallbackSatsCost,\n provider,\n ...breakdown,\n };\n\n if (\n result.promptTokens === 0 &&\n result.completionTokens === 0 &&\n result.totalTokens === 0 &&\n result.cost === 0 &&\n result.satsCost === 0\n ) {\n return null;\n }\n\n return result;\n}\n\n/**\n * Extract cost/usage from EHBP/Tinfoil response headers.\n *\n * For EHBP requests the proxy cannot inject cost into the JSON/SSE body\n * (the body is opaque encrypted). Instead it returns cost as response\n * headers. This parses those headers into the same UsageTrackingData\n * shape used for SSE/body extraction, so callers can merge or fall back.\n */\nexport function extractUsageFromResponseHeaders(\n headers: Headers | Record<string, string>\n): UsageTrackingData | null {\n const get = (name: string): string | null => {\n if (headers instanceof Headers) return headers.get(name);\n // Case-insensitive lookup for plain objects\n const lower = name.toLowerCase();\n for (const [k, v] of Object.entries(headers)) {\n if (k.toLowerCase() === lower) return v;\n }\n return null;\n };\n\n const totalMsats = Number(get(\"X-Routstr-Cost-Msats\"));\n if (!totalMsats || !Number.isFinite(totalMsats)) return null;\n\n return {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n cost: Number(get(\"X-Routstr-Cost-Usd\")) || 0,\n satsCost: totalMsats / 1000,\n totalMsats,\n inputMsats: Number(get(\"X-Routstr-Input-Cost-Msats\")) || 0,\n outputMsats: Number(get(\"X-Routstr-Output-Cost-Msats\")) || 0,\n totalUsd: Number(get(\"X-Routstr-Cost-Usd\")) || undefined,\n };\n}\n\nexport function toUsageStats(\n usage: UsageTrackingData | null | undefined\n): UsageStats | undefined {\n if (!usage) return undefined;\n return {\n total_tokens: usage.totalTokens,\n prompt_tokens: usage.promptTokens,\n completion_tokens: usage.completionTokens,\n cost: usage.cost,\n sats_cost: usage.satsCost,\n };\n}\n","import { Transform } from \"stream\";\nimport { StringDecoder } from \"string_decoder\";\nimport { extractUsageFromSSEJson, type UsageTrackingData } from \"./usage\";\n\n/**\n * Merge previously captured usage with a newly seen usage payload, preferring\n * non-zero fields from the new payload.\n */\nfunction mergeUsage(\n previous: UsageTrackingData | null,\n next: UsageTrackingData\n): UsageTrackingData {\n if (!previous) return next;\n const pickNum = (\n n: number | undefined,\n p: number | undefined\n ): number | undefined => (typeof n === \"number\" && n > 0 ? n : p ?? n);\n return {\n promptTokens:\n next.promptTokens > 0 ? next.promptTokens : previous.promptTokens,\n completionTokens:\n next.completionTokens > 0\n ? next.completionTokens\n : previous.completionTokens,\n totalTokens:\n next.totalTokens > 0 ? next.totalTokens : previous.totalTokens,\n cost: next.cost > 0 ? next.cost : previous.cost,\n satsCost: next.satsCost > 0 ? next.satsCost : previous.satsCost,\n provider: next.provider ?? previous.provider,\n baseMsats: pickNum(next.baseMsats, previous.baseMsats),\n inputMsats: pickNum(next.inputMsats, previous.inputMsats),\n outputMsats: pickNum(next.outputMsats, previous.outputMsats),\n totalMsats: pickNum(next.totalMsats, previous.totalMsats),\n totalUsd: pickNum(next.totalUsd, previous.totalUsd),\n cacheReadInputTokens: pickNum(\n next.cacheReadInputTokens,\n previous.cacheReadInputTokens\n ),\n cacheCreationInputTokens: pickNum(\n next.cacheCreationInputTokens,\n previous.cacheCreationInputTokens\n ),\n cacheReadMsats: pickNum(next.cacheReadMsats, previous.cacheReadMsats),\n cacheCreationMsats: pickNum(\n next.cacheCreationMsats,\n previous.cacheCreationMsats\n ),\n remainingBalanceMsats: pickNum(\n next.remainingBalanceMsats,\n previous.remainingBalanceMsats\n ),\n };\n}\n\nfunction hasUsageChanged(\n previous: UsageTrackingData | null,\n next: UsageTrackingData\n): boolean {\n if (!previous) return true;\n return (\n previous.promptTokens !== next.promptTokens ||\n previous.completionTokens !== next.completionTokens ||\n previous.totalTokens !== next.totalTokens ||\n previous.cost !== next.cost ||\n previous.satsCost !== next.satsCost ||\n previous.provider !== next.provider ||\n previous.totalMsats !== next.totalMsats ||\n previous.remainingBalanceMsats !== next.remainingBalanceMsats\n );\n}\n\n/**\n * The inspector can stop early once we've seen the response id, a provider,\n * usage with token counts, and the detailed cost breakdown (total_msats).\n */\nfunction isInspectionComplete(\n responseIdCaptured: boolean,\n usage: UsageTrackingData | null\n): boolean {\n return (\n responseIdCaptured &&\n !!usage &&\n usage.totalTokens > 0 &&\n typeof usage.totalMsats === \"number\" &&\n !!usage.provider\n );\n}\n\n/**\n * Inspect a Web `ReadableStream<Uint8Array>` of SSE bytes for `usage` and\n * response `id` fields without touching the bytes that are delivered to the\n * real client. This is meant to be called on one branch of a `body.tee()`.\n *\n * The inspector reads the stream to completion (or errors out), decoding\n * UTF-8 across chunk boundaries, splitting on SSE event terminators\n * (`\\r?\\n\\r?\\n`), parsing each `data:` payload as JSON, and invoking the\n * provided callbacks when usage / response id become known.\n *\n * The returned Promise resolves with the final captured values once the\n * stream ends (or is cancelled / errors out).\n */\nexport async function inspectSSEWebStream(\n stream: ReadableStream<Uint8Array>,\n onUsage: (usage: UsageTrackingData) => void,\n onResponseId?: (responseId: string) => void,\n options?: {\n /** Called with each raw chunk read from the tee'd inspection branch. */\n onRawChunk?: (chunk: Uint8Array, sequence: number, text: string) => void | Promise<void>;\n }\n): Promise<{\n capturedUsage?: UsageTrackingData;\n capturedResponseId?: string;\n}> {\n const reader = stream.getReader();\n const decoder = new TextDecoder(\"utf-8\");\n let buffer = \"\";\n let capturedUsage: UsageTrackingData | null = null;\n let capturedResponseId: string | undefined;\n let responseIdCaptured = false;\n let rawChunkSequence = 0;\n\n const inspectDataPayload = (jsonText: string): void => {\n const trimmed = jsonText.trim();\n if (!trimmed || trimmed === \"[DONE]\") {\n if (trimmed === \"[DONE]\") console.log(\"[routstr:sse] [DONE]\");\n return;\n }\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n console.log(\"[routstr:sse] non-JSON payload:\", trimmed.slice(0, 200));\n return;\n }\n\n try {\n const data = JSON.parse(trimmed) as any;\n console.log(\"[routstr:sse] chunk:\", JSON.stringify(data));\n\n if (isInspectionComplete(responseIdCaptured, capturedUsage)) {\n console.log(\"[routstr:sse] (inspection already complete, skipping)\");\n return;\n }\n\n if (!responseIdCaptured) {\n const responseId = data?.id;\n if (typeof responseId === \"string\" && responseId.trim().length > 0) {\n capturedResponseId = responseId.trim();\n onResponseId?.(capturedResponseId);\n responseIdCaptured = true;\n }\n }\n\n const usage = extractUsageFromSSEJson(data);\n if (usage) {\n // console.log(\"[routstr:sse] → usage detected:\", usage);\n const merged = mergeUsage(capturedUsage, usage);\n if (hasUsageChanged(capturedUsage, merged)) {\n capturedUsage = merged;\n // console.log(\"[routstr:sse] → merged (changed):\", merged);\n onUsage(merged);\n } else {\n // console.log(\"[routstr:sse] → merged (no change)\");\n }\n }\n } catch {\n console.log(\"[routstr:sse] failed to parse payload:\", trimmed.slice(0, 200));\n }\n };\n\n const inspectEventBlock = (eventBlock: string): void => {\n const lines = eventBlock.split(/\\r?\\n/);\n const dataParts: string[] = [];\n for (const line of lines) {\n if (!line || line.startsWith(\":\")) continue;\n if (line.startsWith(\"data:\")) {\n const value = line.startsWith(\"data: \") ? line.slice(6) : line.slice(5);\n dataParts.push(value);\n }\n }\n\n if (dataParts.length === 0) return;\n inspectDataPayload(dataParts.join(\"\\n\"));\n };\n\n const drainBufferedEvents = (): void => {\n const terminator = /\\r?\\n\\r?\\n/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = terminator.exec(buffer)) !== null) {\n const block = buffer.slice(lastIndex, match.index);\n lastIndex = match.index + match[0].length;\n if (block.length > 0) inspectEventBlock(block);\n }\n if (lastIndex > 0) buffer = buffer.slice(lastIndex);\n };\n\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n if (value && value.byteLength > 0) {\n const text = decoder.decode(value, { stream: true });\n void options?.onRawChunk?.(value, rawChunkSequence++, text);\n buffer += text;\n drainBufferedEvents();\n }\n }\n buffer += decoder.decode();\n drainBufferedEvents();\n if (buffer.length > 0) {\n const tail = buffer.replace(/\\r?\\n+$/, \"\");\n if (tail.length > 0) inspectEventBlock(tail);\n buffer = \"\";\n }\n } catch {\n // Swallow — inspection is best-effort. The client branch is independent.\n } finally {\n try {\n reader.releaseLock();\n } catch {\n // ignore\n }\n }\n\n return {\n capturedUsage: capturedUsage ?? undefined,\n capturedResponseId,\n };\n}\n\n/**\n * SSE parser transform that preserves the original byte stream.\n *\n * Incoming chunks are forwarded downstream unchanged so chunk boundaries and\n * timing remain identical to the upstream source. In parallel, a streaming text\n * decoder buffers just enough data to detect complete SSE event blocks for\n * usage/responseId inspection.\n *\n * This means:\n * - The client sees the original stream bytes without parser-induced\n * re-chunking.\n * - Multi-line events (multiple `data:` lines, plus `event:`/`id:`/`retry:`\n * fields) are still parsed correctly for inspection.\n * - Chunks that contain multiple events, or events split across chunks, are\n * handled correctly without merging or losing packets.\n * - UTF-8 split across chunk boundaries is decoded safely.\n */\nexport function createSSEParserTransform(\n onUsage: (usage: UsageTrackingData) => void,\n onResponseId?: (responseId: string) => void\n): Transform {\n let buffer = \"\";\n const decoder = new StringDecoder(\"utf8\");\n let capturedUsage: UsageTrackingData | null = null;\n let responseIdCaptured = false;\n\n const inspectDataPayload = (jsonText: string): void => {\n const trimmed = jsonText.trim();\n if (!trimmed || trimmed === \"[DONE]\") {\n if (trimmed === \"[DONE]\") console.log(\"[routstr:sse] [DONE]\");\n return;\n }\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n console.log(\"[routstr:sse] non-JSON payload:\", trimmed.slice(0, 200));\n return;\n }\n\n try {\n const data = JSON.parse(trimmed) as any;\n console.log(\"[routstr:sse] chunk:\", JSON.stringify(data));\n\n if (isInspectionComplete(responseIdCaptured, capturedUsage)) {\n console.log(\"[routstr:sse] (inspection already complete, skipping)\");\n return;\n }\n\n if (!responseIdCaptured) {\n const responseId = data?.id;\n if (typeof responseId === \"string\" && responseId.trim().length > 0) {\n onResponseId?.(responseId.trim());\n responseIdCaptured = true;\n }\n }\n\n const usage = extractUsageFromSSEJson(data);\n if (usage) {\n console.log(\"[routstr:sse] → usage detected:\", usage);\n const mergedUsage = mergeUsage(capturedUsage, usage);\n if (hasUsageChanged(capturedUsage, mergedUsage)) {\n capturedUsage = mergedUsage;\n console.log(\"[routstr:sse] → merged (changed):\", mergedUsage);\n onUsage(mergedUsage);\n } else {\n console.log(\"[routstr:sse] → merged (no change)\");\n }\n }\n } catch {\n console.log(\"[routstr:sse] failed to parse payload:\", trimmed.slice(0, 200));\n }\n };\n\n /**\n * Parse a single SSE event block and invoke usage/id inspection on any\n * `data:` fields. Per the SSE spec, multiple `data:` lines within one\n * event are concatenated with `\\n` to form the payload.\n */\n const inspectEventBlock = (eventBlock: string): void => {\n const lines = eventBlock.split(/\\r?\\n/);\n const dataParts: string[] = [];\n\n for (const line of lines) {\n if (!line || line.startsWith(\":\")) continue;\n // SSE fields are of the form `field: value` or `field:value`.\n // We only care about `data:` for inspection purposes.\n if (line.startsWith(\"data:\")) {\n const value = line.startsWith(\"data: \") ? line.slice(6) : line.slice(5);\n dataParts.push(value);\n }\n }\n\n if (dataParts.length === 0) return;\n const payload = dataParts.join(\"\\n\");\n inspectDataPayload(payload);\n };\n\n const processBufferedEvents = (): void => {\n // Events are terminated by a blank line: either \\n\\n or \\r\\n\\r\\n.\n // Scan the decoded text buffer for complete events and inspect them.\n const terminator = /\\r?\\n\\r?\\n/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = terminator.exec(buffer)) !== null) {\n const block = buffer.slice(lastIndex, match.index);\n lastIndex = match.index + match[0].length;\n if (block.length > 0) {\n inspectEventBlock(block);\n }\n }\n\n if (lastIndex > 0) {\n buffer = buffer.slice(lastIndex);\n }\n };\n\n return new Transform({\n transform(chunk, _encoding, callback) {\n this.push(chunk);\n buffer += decoder.write(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n processBufferedEvents();\n callback();\n },\n flush(callback) {\n buffer += decoder.end();\n processBufferedEvents();\n\n // Inspect any remaining buffered content as a final event block. Upstreams\n // that close without a trailing blank line can still contain a final event.\n if (buffer.length > 0) {\n const tail = buffer.replace(/\\r?\\n+$/, \"\");\n if (tail.length > 0) {\n inspectEventBlock(tail);\n }\n buffer = \"\";\n }\n callback();\n },\n });\n}\n","/**\n * TinfoilSecure - EHBP transport encryption + enclave attestation for Tinfoil models.\n *\n * Any model whose id starts with `tinfoil-` is routed through Tinfoil EHBP.\n * SecureClient performs attestation (`ready()`) and verifies the enclave code\n * fingerprint. The SDK then uses EHBP request encryption so only the attested\n * enclave can decrypt request bodies.\n *\n * Unlike Venice E2EE, there is no per-field message encryption and no custom SSE\n * decrypt transform. Successful enclave responses are decrypted before normal\n * SDK response handling sees them. Plaintext proxy-side errors (for example\n * auth/balance failures before the request reaches the enclave) are preserved\n * with their real status/body.\n */\n\nimport type { SecureClient as SecureClientType, VerificationDocument } from \"tinfoil\";\n\nexport interface TinfoilClientContext {\n client: SecureClientType;\n verification: VerificationDocument;\n}\n\nexport interface TinfoilClientOptions {\n /** Routstr/provider base URL that will receive the EHBP-wrapped request. */\n baseUrl: string;\n /** Optional explicit attestation bundle origin. Defaults to Tinfoil's ATC. */\n attestationBundleURL?: string;\n /** Optional explicit enclave URL for custom Tinfoil deployments. */\n enclaveURL?: string;\n /** Optional source repo for code verification when enclaveURL is explicit. */\n configRepo?: string;\n}\n\nconst TINFOIL_MODEL_PREFIX = \"tinfoil-\";\n\n// Cache SecureClient initialization per option set. SecureClient internally\n// handles key rotation recovery and re-attestation on KeyConfigMismatchError.\nconst clientCache = new Map<string, Promise<TinfoilClientContext>>();\n\n/** Check if a model ID should use Tinfoil EHBP transport. */\nexport function isTinfoilModel(modelId: string): boolean {\n return modelId.startsWith(TINFOIL_MODEL_PREFIX);\n}\n\n/**\n * Return the model id sent inside the EHBP-encrypted request body.\n *\n * Strips the `tinfoil-` prefix so the attested enclave receives the bare\n * model id it expects (e.g. \"kimi-k2-6\"), not the caller-facing routstr id.\n */\nexport function getTinfoilUpstreamModelId(modelId: string): string {\n return modelId.slice(TINFOIL_MODEL_PREFIX.length);\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, \"\");\n}\n\nfunction cacheKey(options: TinfoilClientOptions): string {\n return JSON.stringify({\n baseUrl: options.baseUrl,\n attestationBundleURL: options.attestationBundleURL,\n enclaveURL: options.enclaveURL,\n configRepo: options.configRepo,\n });\n}\n\nfunction envOrUndefined(name: string): string | undefined {\n // `process` may not exist in browser builds. Keep this safe and dynamic.\n const maybeProcess = globalThis as typeof globalThis & {\n process?: { env?: Record<string, string | undefined> };\n };\n const value = maybeProcess.process?.env?.[name];\n return value && value.trim() ? value.trim() : undefined;\n}\n\n/**\n * Build SecureClient options.\n *\n * By default we use Tinfoil's public ATC for attestation and bind the encrypted\n * request transport to the Routstr/provider `baseUrl`. This is the standard\n * proxy-through-EHBP setup: the provider sees only EHBP ciphertext in the body\n * and forwards it to the attested Tinfoil enclave.\n *\n * Advanced/custom deployments can override the attestation/enclave parameters\n * with environment variables:\n * - ROUTSTR_TINFOIL_ATTESTATION_BUNDLE_URL\n * - ROUTSTR_TINFOIL_ENCLAVE_URL\n * - ROUTSTR_TINFOIL_CONFIG_REPO\n */\nfunction resolveOptions(options: TinfoilClientOptions): TinfoilClientOptions {\n return {\n ...options,\n baseUrl: normalizeBaseUrl(options.baseUrl),\n attestationBundleURL:\n options.attestationBundleURL ??\n envOrUndefined(\"ROUTSTR_TINFOIL_ATTESTATION_BUNDLE_URL\"),\n enclaveURL:\n options.enclaveURL ?? envOrUndefined(\"ROUTSTR_TINFOIL_ENCLAVE_URL\"),\n configRepo:\n options.configRepo ?? envOrUndefined(\"ROUTSTR_TINFOIL_CONFIG_REPO\"),\n };\n}\n\n/**\n * Attest and return a cached Tinfoil SecureClient for a provider base URL.\n */\nexport async function prepareTinfoilClient(\n options: TinfoilClientOptions\n): Promise<TinfoilClientContext> {\n const resolved = resolveOptions(options);\n const key = cacheKey(resolved);\n let pending = clientCache.get(key);\n\n if (!pending) {\n pending = (async () => {\n // Dynamic import keeps the SDK importable in contexts that never use\n // Tinfoil models and avoids loading the heavy OpenAI/tinfoil stack early.\n const { SecureClient } = await import(\"tinfoil\");\n\n const client = new SecureClient({\n // baseURL is the proxy/provider URL that receives the EHBP request.\n baseURL: resolved.baseUrl,\n // Leave undefined by default so tinfoil uses its public ATC. If set,\n // SecureClient will fetch `${attestationBundleURL}/attestation`.\n attestationBundleURL: resolved.attestationBundleURL,\n enclaveURL: resolved.enclaveURL,\n configRepo: resolved.configRepo,\n transport: \"ehbp\",\n });\n\n await client.ready();\n const verification = client.getVerificationDocument();\n\n return { client, verification };\n })();\n\n clientCache.set(key, pending);\n }\n\n try {\n return await pending;\n } catch (error) {\n // Do not cache failed attestation attempts forever.\n clientCache.delete(key);\n throw error;\n }\n}\n\nfunction normalizeFetchArgs(\n input: RequestInfo | URL,\n init?: RequestInit\n): { url: string; init?: RequestInit } {\n if (typeof input === \"string\") {\n return { url: input, init };\n }\n if (input instanceof URL) {\n return { url: input.toString(), init };\n }\n\n const cloned = input.clone();\n return {\n url: cloned.url,\n init: {\n method: cloned.method,\n headers: new Headers(cloned.headers),\n body: cloned.body ?? undefined,\n signal: cloned.signal,\n ...init,\n },\n };\n}\n\ntype EhbpModule = typeof import(\"ehbp\");\ntype NormalizedFetchArgs = ReturnType<typeof normalizeFetchArgs>;\n\nfunction isProblemJsonContentType(contentType: string | null): boolean {\n const mediaType = contentType?.split(\";\", 1)[0]?.trim().toLowerCase();\n return mediaType === \"application/problem+json\";\n}\n\nasync function isEhbpKeyConfigMismatchResponse(\n response: Response,\n protocol: EhbpModule[\"PROTOCOL\"]\n): Promise<boolean> {\n if (response.status !== 422) {\n return false;\n }\n\n if (!isProblemJsonContentType(response.headers.get(\"content-type\"))) {\n return false;\n }\n\n try {\n const problem = await response.clone().json();\n return problem?.type === protocol.KEY_CONFIG_PROBLEM_TYPE;\n } catch {\n return false;\n }\n}\n\nasync function fetchTinfoilEhbpOnce(\n context: TinfoilClientContext,\n options: TinfoilClientOptions,\n normalized: NormalizedFetchArgs,\n ehbp: EhbpModule\n): Promise<Response> {\n const { Identity, PROTOCOL, decryptResponseWithToken, extractSessionRecoveryToken } =\n ehbp;\n\n const resolved = resolveOptions(options);\n const baseURL = context.client.getBaseURL() ?? resolved.baseUrl;\n const enclaveURL = context.client.getEnclaveURL();\n const baseOrigin = new URL(baseURL).origin;\n const allowedOrigins = new Set([baseOrigin]);\n\n if (enclaveURL) {\n allowedOrigins.add(new URL(enclaveURL).origin);\n }\n\n const targetUrl = new URL(normalized.url, baseURL);\n\n if (!allowedOrigins.has(targetUrl.origin)) {\n throw new Error(\n `refusing to send Tinfoil request to ${targetUrl.origin}: client is bound to the verified enclave/proxy`\n );\n }\n\n const headers = new Headers(normalized.init?.headers);\n if (enclaveURL && new URL(enclaveURL).origin !== baseOrigin) {\n headers.set(\"X-Tinfoil-Enclave-Url\", enclaveURL);\n }\n\n const method = normalized.init?.method ?? \"GET\";\n const body = normalized.init?.body ?? null;\n const serverIdentity = await Identity.fromPublicKeyHex(\n context.verification.hpkePublicKey\n );\n\n const request = new Request(targetUrl.toString(), {\n method,\n headers,\n body,\n duplex: \"half\",\n } as RequestInit & { duplex: \"half\" });\n\n const { request: encryptedRequest, context: requestContext } =\n await serverIdentity.encryptRequestWithContext(request);\n\n const response = await fetch(encryptedRequest);\n if (!requestContext) {\n return response;\n }\n\n if (await isEhbpKeyConfigMismatchResponse(response, PROTOCOL)) {\n throw new ehbp.KeyConfigMismatchError(\"EHBP key configuration mismatch\");\n }\n\n if (!response.headers.get(PROTOCOL.RESPONSE_NONCE_HEADER)) {\n return response;\n }\n\n const token = await extractSessionRecoveryToken(requestContext);\n return await decryptResponseWithToken(response, token);\n}\n\n/**\n * Fetch through Tinfoil EHBP while preserving plaintext proxy error responses.\n *\n * Tinfoil's stock SecureClient.fetch throws ProtocolError when a response to an\n * encrypted request lacks Ehbp-Response-Nonce. That is correct for successful\n * enclave responses, but Routstr proxy-side auth/balance errors are plaintext\n * and need to flow through the SDK's normal error handling with their real\n * status/body. This wrapper performs the same request-body encryption and\n * response decryption, but returns non-EHBP responses unchanged.\n *\n * It also keeps SecureClient's key-rotation behavior: an EHBP key-config\n * mismatch response triggers one fresh attestation and one retry.\n */\nexport async function fetchTinfoilPreservingPlaintextErrors(\n options: TinfoilClientOptions,\n input: RequestInfo | URL,\n init?: RequestInit\n): Promise<Response> {\n const context = await prepareTinfoilClient(options);\n const ehbp = await import(\"ehbp\");\n const normalized = normalizeFetchArgs(input, init);\n\n try {\n return await fetchTinfoilEhbpOnce(context, options, normalized, ehbp);\n } catch (error) {\n // Channel recovery: server rotated EHBP keys, request was never processed.\n // Mirror tinfoil SecureClient.fetch by re-attesting and retrying once.\n if (error instanceof ehbp.KeyConfigMismatchError) {\n context.client.reset();\n try {\n await context.client.ready();\n context.verification = context.client.getVerificationDocument();\n } catch (reattestError) {\n // Do not keep a failed post-rotation attestation in the shared cache.\n clientCache.delete(cacheKey(resolveOptions(options)));\n throw reattestError;\n }\n\n return await fetchTinfoilEhbpOnce(context, options, normalized, ehbp);\n }\n\n throw error;\n }\n}\n\n/** Clear cached Tinfoil clients, mainly useful for tests or forced re-attest. */\nexport function clearTinfoilClientCache(): void {\n clientCache.clear();\n}\n","/**\n * RoutstrClient - Main API client for Routstr\n *\n * Orchestrates:\n * - Token spending via CashuSpender\n * - API requests with authentication\n * - Streaming response processing\n * - Provider failover via ProviderManager\n * - Error handling and refunds\n *\n * Extracted from utils/apiUtils.ts\n */\n\nimport type { SdkLogger } from \"../core/types\";\nimport type { Model } from \"../core/types\";\nimport { consoleLogger } from \"../core/types\";\nimport type {\n WalletAdapter,\n StorageAdapter,\n ProviderRegistry,\n} from \"../wallet/interfaces\";\nimport type { UsageTrackingDriver } from \"../storage/usageTracking\";\nimport type { SdkStore } from \"../storage/store\";\nimport { CashuSpender } from \"../wallet/CashuSpender\";\nimport { BalanceManager } from \"../wallet/BalanceManager\";\nimport { ProviderManager } from \"./ProviderManager\";\nimport {\n ProviderError,\n FailoverError,\n InsufficientBalanceError,\n} from \"../core/errors\";\nimport { isNetworkErrorMessage } from \"../wallet/tokenUtils\";\nimport { getDefaultSdkStore, getDefaultUsageTrackingDriver } from \"../storage\";\nimport {\n extractResponseId,\n extractUsageFromResponseBody,\n extractUsageFromResponseHeaders,\n type UsageTrackingData,\n} from \"./usage\";\nimport { inspectSSEWebStream } from \"./sse\";\nimport {\n isTinfoilModel,\n getTinfoilUpstreamModelId,\n prepareTinfoilClient,\n fetchTinfoilPreservingPlaintextErrors,\n} from \"./TinfoilSecure\";\n\n/**\n * RoutstrClient is the main SDK entry point\n */\nexport type AlertLevel = \"max\" | \"min\";\nexport type RoutstrClientMode = \"xcashu\" | \"apikeys\";\nexport type DebugLevel = \"DEBUG\" | \"WARN\" | \"ERROR\";\n\nconst TOPUP_MARGIN = 1.2;\n\nexport interface RouteRequestParams {\n path: string;\n method: string;\n body?: unknown;\n headers?: Record<string, string>;\n baseUrl: string;\n mintUrl: string;\n modelId?: string;\n clientApiKey?: string;\n}\n\nexport interface RequestResponseLogRequestInput {\n method: string;\n url: string;\n path: string;\n baseUrl: string;\n headers: Record<string, string>;\n body?: unknown;\n rawBody?: string;\n}\n\nexport interface RequestResponseLogSink {\n logRequest?(input: RequestResponseLogRequestInput): string | undefined | Promise<string | undefined>;\n logResponseStart?(id: string | undefined, response: Response): void | Promise<void>;\n logResponseChunk?(id: string | undefined, sequence: number, text: string): void | Promise<void>;\n logResponseEnd?(id: string | undefined): void | Promise<void>;\n logResponseError?(id: string | undefined, error: unknown): void | Promise<void>;\n logResponseBody?(id: string | undefined, response: Response): void | Promise<void>;\n}\n\nexport interface RoutstrClientConfig {\n usageTrackingDriver?: UsageTrackingDriver;\n sdkStore?: SdkStore;\n /** Optional: shared ProviderManager instance for consistent failure tracking across requests */\n providerManager?: ProviderManager;\n /** Optional: injectable logger (defaults to consoleLogger) */\n logger?: SdkLogger;\n /** Optional: raw request/response logging callbacks supplied by the runtime/app. */\n requestResponseLogSink?: RequestResponseLogSink;\n}\n\nexport class RoutstrClient {\n private cashuSpender: CashuSpender;\n private balanceManager: BalanceManager;\n private providerManager: ProviderManager;\n private alertLevel: AlertLevel;\n private mode: RoutstrClientMode;\n private debugLevel: DebugLevel = \"WARN\";\n private usageTrackingDriver?: UsageTrackingDriver;\n private sdkStore?: SdkStore;\n private logger: SdkLogger;\n private requestResponseLogSink?: RequestResponseLogSink;\n\n constructor(\n private walletAdapter: WalletAdapter,\n private storageAdapter: StorageAdapter,\n private providerRegistry: ProviderRegistry,\n alertLevel: AlertLevel,\n mode: RoutstrClientMode = \"xcashu\",\n options: RoutstrClientConfig = {}\n ) {\n this.logger = (options.logger ?? consoleLogger).child(\"RoutstrClient\");\n this.balanceManager = new BalanceManager(\n walletAdapter,\n storageAdapter,\n providerRegistry,\n undefined,\n this.logger\n );\n this.cashuSpender = new CashuSpender(\n walletAdapter,\n storageAdapter,\n providerRegistry,\n this.balanceManager,\n this.logger\n );\n this.alertLevel = alertLevel;\n this.mode = mode;\n this.usageTrackingDriver = options.usageTrackingDriver;\n this.sdkStore = options.sdkStore;\n this.requestResponseLogSink = options.requestResponseLogSink;\n // Use provided ProviderManager or create a new one\n this.providerManager =\n options.providerManager ??\n new ProviderManager(providerRegistry, this.sdkStore, this.logger);\n }\n\n /**\n * Get the current client mode\n */\n getMode(): RoutstrClientMode {\n return this.mode;\n }\n\n getDebugLevel(): DebugLevel {\n return this.debugLevel;\n }\n\n setDebugLevel(level: DebugLevel): void {\n this.debugLevel = level;\n }\n\n private _log(level: \"DEBUG\" | \"WARN\" | \"ERROR\", ...args: unknown[]): void {\n const levelPriority: Record<DebugLevel, number> = {\n DEBUG: 0,\n WARN: 1,\n ERROR: 2,\n };\n\n if (levelPriority[level] >= levelPriority[this.debugLevel]) {\n switch (level) {\n case \"DEBUG\":\n this.logger.log(...args);\n break;\n case \"WARN\":\n this.logger.warn(...args);\n break;\n case \"ERROR\":\n this.logger.error(...args);\n break;\n }\n }\n }\n\n /**\n * Get the CashuSpender instance\n */\n getCashuSpender(): CashuSpender {\n return this.cashuSpender;\n }\n\n /**\n * Get the BalanceManager instance\n */\n getBalanceManager(): BalanceManager {\n return this.balanceManager;\n }\n\n /**\n * Get the ProviderManager instance\n */\n getProviderManager(): ProviderManager {\n return this.providerManager;\n }\n\n /**\n * Check if the client is currently busy (in critical section)\n */\n get isBusy(): boolean {\n return this.cashuSpender.isBusy;\n }\n\n /**\n * Route an API request to the upstream provider\n *\n * This is a simpler alternative to fetchAIResponse that just proxies\n * the request upstream without the streaming callback machinery.\n * Useful for daemon-style routing where you just need to forward\n * requests and get responses back.\n */\n async routeRequest(params: RouteRequestParams): Promise<Response> {\n const prepared = await this._prepareRoutedRequest(params);\n const contentType =\n prepared.response.headers.get(\"content-type\") || \"\";\n const isSSE = contentType.includes(\"text/event-stream\");\n\n // For SSE, defer accounting until the inspector (tee'd branch) has seen\n // usage — which only happens as the client consumes the stream. We expose\n // the finalization as `(response).finalize` so callers that want to block\n // on accounting (e.g. a proxy after it finished piping) can `await` it.\n // Non-SSE responses can be finalized inline since the body is fully\n // available (the clone-and-read path inside `_trackResponseUsage` handles\n // JSON bodies without consuming the client-facing copy).\n const runFinalize = async (): Promise<number> => {\n const { capturedUsage, capturedResponseId } = await prepared.usagePromise;\n const usage = capturedUsage ?? prepared.capturedUsage;\n const requestId = capturedResponseId ?? prepared.capturedResponseId;\n const satsSpent = await this._handlePostResponseBalanceUpdate({\n token: prepared.tokenUsed,\n baseUrl: prepared.baseUrlUsed,\n mintUrl: params.mintUrl,\n initialTokenBalance: prepared.tokenBalanceInSats,\n initialTokenBalanceUnknown: prepared.tokenBalanceUnknown,\n fallbackSatsSpent: usage?.satsCost,\n response: prepared.response,\n modelId: prepared.modelId,\n usage,\n requestId,\n clientApiKey: prepared.clientApiKey,\n });\n (prepared.response as any).satsSpent = satsSpent;\n (prepared.response as any).usage = usage;\n (prepared.response as any).requestId = requestId;\n return satsSpent;\n };\n\n if (isSSE) {\n // Expose a finalize() that the caller can await after it's done piping\n // the stream to its client. Also fire-and-forget so accounting still\n // happens even if the caller ignores it.\n const finalizePromise = runFinalize().catch((error) => {\n this._log(\"ERROR\", \"[RoutstrClient] SSE finalize failed:\", error);\n return 0;\n });\n (prepared.response as any).finalize = () => finalizePromise;\n return prepared.response;\n }\n\n await runFinalize();\n return prepared.response;\n }\n\n private async _prepareRoutedRequest(params: RouteRequestParams): Promise<{\n response: Response;\n tokenUsed: string;\n baseUrlUsed: string;\n tokenBalanceInSats: number;\n tokenBalanceUnknown: boolean;\n modelId?: string;\n capturedUsage?: UsageTrackingData;\n capturedResponseId?: string;\n clientApiKey?: string;\n usagePromise: Promise<{\n capturedUsage?: UsageTrackingData;\n capturedResponseId?: string;\n }>;\n }> {\n const {\n path: requestPath,\n method,\n body,\n headers = {},\n baseUrl,\n mintUrl,\n modelId,\n clientApiKey: providedClientApiKey,\n } = params;\n\n // Extract clientApiKey from incoming headers then discard them — they must\n // not be forwarded upstream (the client's Authorization Bearer key would\n // overwrite the Cashu/API-key auth we attach ourselves).\n const clientApiKey =\n providedClientApiKey ?? this._extractClientApiKey(headers);\n\n await this._checkBalance();\n\n let requiredSats = 1;\n let selectedModel: Model | undefined;\n if (modelId) {\n const providerModel = await this.providerManager.getModelForProvider(\n baseUrl,\n modelId\n );\n selectedModel = providerModel ?? undefined;\n if (selectedModel) {\n const requestMessages = Array.isArray(\n (body as { messages?: unknown })?.messages\n )\n ? ((body as { messages?: unknown }).messages as any[])\n : [];\n const requestMaxTokens =\n typeof (body as { max_tokens?: unknown })?.max_tokens === \"number\"\n ? ((body as { max_tokens?: unknown }).max_tokens as number)\n : undefined;\n\n this._log(\n \"DEBUG\",\n \"[RoutstrClient] generic request pricing input\",\n {\n modelId: selectedModel.id,\n messageCount: requestMessages.length,\n maxTokens: requestMaxTokens,\n }\n );\n\n requiredSats = this.providerManager.getRequiredSatsForModel(\n selectedModel,\n requestMessages,\n requestMaxTokens\n );\n }\n }\n\n let requestBody = body;\n if (body && typeof body === \"object\") {\n const bodyObj = body as Record<string, unknown>;\n if (!bodyObj.stream) {\n requestBody = { ...bodyObj, stream: false };\n }\n }\n\n // Build clean outgoing headers — do NOT pass the incoming client headers here\n const baseHeaders = this._buildBaseHeaders();\n\n // ─── Tinfoil EHBP: attest BEFORE spending tokens ──────\n const tinfoilEnabled = Boolean(modelId && isTinfoilModel(modelId));\n\n if (tinfoilEnabled) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] Attesting Tinfoil model ${modelId} before spend`\n );\n\n const { verification } = await prepareTinfoilClient({ baseUrl });\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] Tinfoil attestation passed, enclave=${verification.enclaveHost}, codeFingerprint=${verification.codeFingerprint.slice(0, 16)}...`\n );\n\n // Strip the tinfoil- prefix for the model id inside the encrypted body.\n // The attested enclave expects the bare model id (e.g. \"kimi-k2-6\"),\n // not the caller-facing routstr id (e.g. \"tinfoil-kimi-k2-6\").\n // The full id is sent in the X-Routstr-Model header for proxy-side lookup.\n if (requestBody && typeof requestBody === \"object\" && modelId) {\n requestBody = {\n ...(requestBody as Record<string, unknown>),\n model: getTinfoilUpstreamModelId(modelId),\n };\n }\n }\n\n // Spend tokens for the actual request\n const spendResult = await this._spendToken({\n mintUrl,\n amount: requiredSats,\n baseUrl,\n });\n\n const { token, tokenBalance, tokenBalanceUnit, tokenBalanceUnknown } = spendResult;\n\n // Build final request headers (auth + Tinfoil model hint)\n const finalHeaders = this._withAuthAndTinfoilHeaders(\n baseHeaders,\n token,\n tinfoilEnabled,\n modelId\n );\n\n const response = await this._makeRequest({\n path: requestPath,\n method,\n body: method === \"GET\" ? undefined : requestBody,\n baseUrl,\n mintUrl,\n token,\n requiredSats,\n headers: finalHeaders,\n baseHeaders,\n selectedModel,\n tinfoilEnabled,\n });\n\n let tokenBalanceInSats =\n tokenBalanceUnit === \"msat\" ? tokenBalance / 1000 : tokenBalance;\n let initialTokenBalanceUnknown = tokenBalanceUnknown;\n const baseUrlUsed = (response as any).baseUrl || baseUrl;\n const tokenUsed = (response as any).token || token;\n\n // If failover occurred, use the initial balance captured when the\n // failover token was created. Do not query here: by the time fetch returns,\n // the provider may already have charged the request.\n if (baseUrlUsed !== baseUrl || tokenUsed !== token) {\n if (typeof (response as any).initialTokenBalanceInSats === \"number\") {\n tokenBalanceInSats = (response as any).initialTokenBalanceInSats;\n initialTokenBalanceUnknown = Boolean(\n (response as any).initialTokenBalanceUnknown\n );\n } else {\n initialTokenBalanceUnknown = true;\n }\n }\n\n const contentType = response.headers.get(\"content-type\") || \"\";\n let processedResponse = response;\n let capturedUsage: UsageTrackingData | undefined;\n let capturedResponseId: string | undefined;\n let usagePromise: Promise<{\n capturedUsage?: UsageTrackingData;\n capturedResponseId?: string;\n }> = Promise.resolve({});\n\n if (contentType.includes(\"text/event-stream\") && response.body) {\n // Tee the upstream Web stream: one branch goes untouched to the client,\n // the other is consumed by an inspector that extracts usage / responseId.\n const [clientStream, inspectStream] = response.body.tee();\n const requestResponseLogId = (response as any).requestResponseLogId as\n | string\n | undefined;\n\n processedResponse = new Response(clientStream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n\n (processedResponse as any).baseUrl = (response as any).baseUrl;\n (processedResponse as any).token = (response as any).token;\n (processedResponse as any).requestResponseLogId = requestResponseLogId;\n\n usagePromise = inspectSSEWebStream(\n inspectStream,\n (usage) => {\n capturedUsage = usage;\n (processedResponse as any).usage = usage;\n },\n (responseId) => {\n capturedResponseId = responseId;\n (processedResponse as any).requestId = responseId;\n },\n {\n onRawChunk: (_chunk, sequence, text) => {\n void this.requestResponseLogSink?.logResponseChunk?.(\n requestResponseLogId,\n sequence,\n text\n );\n },\n }\n ).then(async (result) => {\n await this.requestResponseLogSink?.logResponseEnd?.(requestResponseLogId);\n return result;\n }).catch(async (error) => {\n await this.requestResponseLogSink?.logResponseError?.(requestResponseLogId, error);\n throw error;\n });\n\n (processedResponse as any).usagePromise = usagePromise;\n }\n\n return {\n response: processedResponse,\n tokenUsed,\n baseUrlUsed,\n tokenBalanceInSats,\n tokenBalanceUnknown: initialTokenBalanceUnknown,\n modelId,\n capturedUsage,\n capturedResponseId,\n clientApiKey,\n usagePromise,\n };\n }\n\n /**\n * Extract clientApiKey from Authorization Bearer token if present\n */\n private _extractClientApiKey(\n headers: Record<string, string>\n ): string | undefined {\n const authHeader = headers[\"Authorization\"] || headers[\"authorization\"];\n if (authHeader?.startsWith(\"Bearer \")) {\n const extractedKey = authHeader.slice(7);\n return extractedKey;\n }\n return undefined;\n }\n\n /**\n * Make the API request with failover support\n */\n private async _makeRequest(params: {\n path: string;\n method: string;\n body?: unknown;\n selectedModel?: Model;\n baseUrl: string;\n mintUrl: string;\n token: string;\n requiredSats: number;\n maxTokens?: number;\n headers: Record<string, string>;\n baseHeaders: Record<string, string>;\n retryCount?: number;\n /** Route the request body through Tinfoil SecureClient.fetch (EHBP). */\n tinfoilEnabled?: boolean;\n }): Promise<Response> {\n const { path, method, body, baseUrl, token, headers, tinfoilEnabled } = params;\n\n try {\n const url = `${baseUrl.replace(/\\/$/, \"\")}${path}`;\n const requestBodyText =\n body === undefined || method === \"GET\" ? undefined : JSON.stringify(body);\n const requestLogId = await this.requestResponseLogSink?.logRequest?.({\n method,\n url,\n path,\n baseUrl,\n headers,\n body,\n rawBody: requestBodyText,\n });\n\n if (this.mode === \"xcashu\") this._log(\"DEBUG\", \"HEADERS,\", headers);\n\n const response = tinfoilEnabled\n ? await fetchTinfoilPreservingPlaintextErrors(\n { baseUrl },\n url,\n {\n method,\n headers,\n body: requestBodyText,\n }\n )\n : await fetch(url, {\n method,\n headers,\n body: requestBodyText,\n });\n if (this.mode === \"xcashu\") this._log(\"DEBUG\", \"response,\", response);\n\n (response as any).baseUrl = baseUrl;\n (response as any).token = token;\n (response as any).requestResponseLogId = requestLogId;\n await this.requestResponseLogSink?.logResponseStart?.(requestLogId, response);\n\n const contentType = response.headers.get(\"content-type\") || \"\";\n\n if (!response.ok) {\n void this.requestResponseLogSink?.logResponseBody?.(requestLogId, response.clone());\n const requestId =\n response.headers.get(\"x-routstr-request-id\") || undefined;\n let bodyText: string | undefined;\n try {\n bodyText = await response.text();\n } catch (e) {\n bodyText = undefined;\n }\n\n this._log(\"ERROR\", \"[RoutstrClient] Upstream error response\", {\n baseUrl,\n url,\n path,\n status: response.status,\n statusText: response.statusText,\n requestId,\n body: bodyText ?? \"<unable to read response body>\",\n });\n\n return await this._handleErrorResponse(\n params,\n token,\n response.status,\n requestId,\n this.mode === \"xcashu\"\n ? (response.headers.get(\"x-cashu\") ?? undefined)\n : undefined,\n bodyText,\n params.retryCount ?? 0\n );\n }\n\n if (!contentType.includes(\"text/event-stream\")) {\n void this.requestResponseLogSink?.logResponseBody?.(requestLogId, response.clone());\n }\n\n return response;\n } catch (error: any) {\n // Handle network errors with failover\n if (isNetworkErrorMessage(error?.message || \"\")) {\n return await this._handleErrorResponse(\n params,\n token,\n -1, // just for Network Error to skip all statuses\n undefined,\n undefined,\n undefined,\n params.retryCount ?? 0\n );\n // return await this._handleNetworkError(error, params);\n }\n throw error;\n }\n }\n\n /**\n * Store request details to a file in the reqs/ folder before fetch.\n */\n /**\n * Handle error responses with failover\n */\n private async _handleErrorResponse(\n params: {\n path: string;\n method: string;\n body?: unknown;\n selectedModel?: Model;\n baseUrl: string;\n mintUrl: string;\n token: string;\n requiredSats: number;\n maxTokens?: number;\n headers: Record<string, string>;\n baseHeaders: Record<string, string>;\n tinfoilEnabled?: boolean;\n },\n token: string,\n status: number,\n requestId?: string,\n xCashuRefundToken?: string,\n responseBody?: string,\n retryCount: number = 0\n ): Promise<Response> {\n const MAX_RETRIES_PER_PROVIDER = 2;\n const { path, method, body, selectedModel, baseUrl, mintUrl } = params;\n let tryNextProvider: boolean = false;\n\n const errorMessage = responseBody;\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: status=${status}, baseUrl=${baseUrl}, mode=${this.mode}, token preview=${token}, requestId=${requestId}, errorMessage=${errorMessage}`\n );\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Attempting to receive/restore token for ${baseUrl}`\n );\n if (params.token.startsWith(\"cashu\")) {\n const receiveResult = await this.cashuSpender.receiveToken(\n params.token\n );\n if (receiveResult.success) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Token restored successfully, amount=${receiveResult.amount}`\n );\n tryNextProvider = true;\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Failed to receive token: ${receiveResult.message}`\n );\n }\n }\n\n if (this.mode === \"xcashu\") {\n if (xCashuRefundToken) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Attempting to receive xcashu refund token, preview=${xCashuRefundToken.substring(0, 20)}...`\n );\n const receiveResult =\n await this.cashuSpender.receiveToken(xCashuRefundToken);\n if (receiveResult.success) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: xcashu refund received, amount=${receiveResult.amount}`\n );\n tryNextProvider = true;\n } else {\n this._log(\n \"ERROR\",\n `[xcashu] Failed to receive refund token: ${receiveResult.message}`\n );\n throw new ProviderError(\n baseUrl,\n status,\n \"[xcashu] Failed to receive refund token\",\n requestId\n );\n }\n } else {\n if (!tryNextProvider)\n throw new ProviderError(\n baseUrl,\n status,\n \"[xcashu] Failed to receive refund token\",\n requestId\n );\n }\n }\n\n if (status === 402 && !tryNextProvider && this.mode === \"apikeys\") {\n this.storageAdapter.getApiKey(baseUrl);\n\n let topupAmount = params.requiredSats;\n\n try {\n const currentBalanceInfo = await this.balanceManager.getTokenBalance(\n params.token,\n baseUrl\n );\n if (currentBalanceInfo.balanceUnknown) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Current balance unknown for ${baseUrl}; using default topup amount=${topupAmount}`\n );\n } else {\n const currentBalance =\n currentBalanceInfo.unit === \"msat\"\n ? currentBalanceInfo.amount / 1000\n : currentBalanceInfo.amount;\n const reservedBalance =\n currentBalanceInfo.unit === \"msat\"\n ? (currentBalanceInfo.reserved ?? 0) / 1000\n : (currentBalanceInfo.reserved ?? 0);\n\n const shortfall = Math.max(\n 0,\n params.requiredSats - currentBalance + reservedBalance\n );\n topupAmount =\n shortfall > 0.21 * params.requiredSats\n ? shortfall\n : 0.21 * params.requiredSats;\n\n this._log(\n \"DEBUG\",\n `The shortfall is: ${shortfall}. requiredSats: ${params.requiredSats}. Current Balance: ${currentBalance}. Reserved Balance: ${reservedBalance}. Available Balance: ${currentBalance - reservedBalance}`\n );\n }\n } catch (e) {\n this._log(\n \"WARN\",\n \"Could not get current token balance for topup calculation:\",\n e\n );\n }\n\n const topupResult = await this.balanceManager.topUp({\n mintUrl,\n baseUrl,\n amount: topupAmount * TOPUP_MARGIN,\n token: params.token,\n });\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Topup result for ${baseUrl}: success=${topupResult.success}, message=${topupResult.message}`\n );\n\n if (!topupResult.success) {\n const message = topupResult.message || \"\";\n if (message.includes(\"Insufficient balance\")) {\n const needMatch = message.match(/need (\\d+)/);\n const haveMatch = message.match(/have (\\d+)/);\n const required = needMatch\n ? parseInt(needMatch[1], 10)\n : params.requiredSats;\n const available = haveMatch ? parseInt(haveMatch[1], 10) : 0;\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Insufficient balance, need=${required}, have=${available}`\n );\n throw new InsufficientBalanceError(\n required,\n available,\n 0,\n \"\",\n message\n );\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Topup failed with non-insufficient-balance error, will try next provider`\n );\n tryNextProvider = true;\n }\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Topup successful, will retry with new token`\n );\n }\n if (!tryNextProvider) {\n if (retryCount < MAX_RETRIES_PER_PROVIDER) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Retrying 402 (attempt ${retryCount + 1}/${MAX_RETRIES_PER_PROVIDER})`\n );\n return this._makeRequest({\n ...params,\n token: params.token,\n headers: this._withAuthAndTinfoilHeaders(\n params.baseHeaders,\n params.token,\n params.tinfoilEnabled,\n params.selectedModel?.id\n ),\n retryCount: retryCount + 1,\n });\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: 402 retry limit reached (${retryCount}/${MAX_RETRIES_PER_PROVIDER}), failing over to next provider`\n );\n tryNextProvider = true;\n }\n }\n }\n\n const isInsufficientBalance413 =\n status === 413 && responseBody?.includes(\"Insufficient balance\");\n\n if (\n isInsufficientBalance413 &&\n !tryNextProvider &&\n this.mode === \"apikeys\"\n ) {\n let retryToken = params.token;\n\n try {\n const latestBalanceInfo = await this.balanceManager.getTokenBalance(\n params.token,\n baseUrl\n );\n\n // Handle invalid/expired API key - delete and fail over\n if (latestBalanceInfo.isInvalidApiKey) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Invalid API key (proofs already spent), removing for ${baseUrl}`\n );\n this.storageAdapter.removeApiKey(baseUrl);\n tryNextProvider = true;\n } else {\n const latestTokenBalance = latestBalanceInfo.balanceUnknown\n ? undefined\n : latestBalanceInfo.unit === \"msat\"\n ? latestBalanceInfo.amount / 1000\n : latestBalanceInfo.amount;\n\n if (latestBalanceInfo.apiKey) {\n const storedApiKeyEntry = this.storageAdapter.getApiKey(baseUrl);\n if (storedApiKeyEntry?.key !== latestBalanceInfo.apiKey) {\n if (storedApiKeyEntry) {\n this.storageAdapter.removeApiKey(baseUrl);\n }\n this.storageAdapter.setApiKey(baseUrl, latestBalanceInfo.apiKey);\n }\n retryToken = latestBalanceInfo.apiKey;\n }\n\n if (latestTokenBalance !== undefined && latestTokenBalance >= 0) {\n this.storageAdapter.updateApiKeyBalance(\n baseUrl,\n latestTokenBalance\n );\n }\n }\n } catch (error) {\n this._log(\n \"WARN\",\n `[RoutstrClient] _handleErrorResponse: Failed to refresh API key after 413 insufficient balance for ${baseUrl}`,\n error\n );\n }\n\n if (retryCount < MAX_RETRIES_PER_PROVIDER) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Retrying 413 (attempt ${retryCount + 1}/${MAX_RETRIES_PER_PROVIDER})`\n );\n return this._makeRequest({\n ...params,\n token: retryToken,\n headers: this._withAuthAndTinfoilHeaders(\n params.baseHeaders,\n retryToken,\n params.tinfoilEnabled,\n params.selectedModel?.id\n ),\n retryCount: retryCount + 1,\n });\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: 413 retry limit reached (${retryCount}/${MAX_RETRIES_PER_PROVIDER}), failing over to next provider`\n );\n tryNextProvider = true;\n }\n }\n\n if (status === 401 && this.mode === \"apikeys\") {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Checking balance for ${baseUrl}, key preview=${token}`\n );\n const latestBalanceInfo = await this.balanceManager.getTokenBalance(\n token,\n baseUrl\n );\n if (latestBalanceInfo.isInvalidApiKey) {\n this.storageAdapter.removeApiKey(baseUrl);\n tryNextProvider = true;\n }\n }\n\n if (\n (status === 401 ||\n status === 403 ||\n status === 404 ||\n status === 413 ||\n status === 400 ||\n status === 429 ||\n status === 500 ||\n status === 502 ||\n status === 503 ||\n status === 504 ||\n status === 521) &&\n !tryNextProvider\n ) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Status ${status} (${status === 429 ? \"rate limited\" : \"auth/server error\"}), attempting refund for ${baseUrl}, mode=${this.mode}`\n );\n if (this.mode === \"apikeys\") {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Attempting API key refund for ${baseUrl}, key preview=${token}`\n );\n const latestBalanceInfo = await this.balanceManager.getTokenBalance(\n token,\n baseUrl\n );\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Initial API key balance: ${latestBalanceInfo.amount}`\n );\n const refundResult = await this.balanceManager.refundApiKey({\n mintUrl,\n baseUrl,\n apiKey: token,\n forceRefund: true,\n });\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: API key refund result: success=${refundResult.success}, message=${refundResult.message}`\n );\n if (\n !refundResult.success &&\n latestBalanceInfo.amount > 0 &&\n !latestBalanceInfo.balanceUnknown\n ) {\n throw new ProviderError(\n baseUrl,\n status,\n refundResult.message ?? \"Unknown error\"\n );\n }\n }\n }\n\n this.providerManager.markFailed(baseUrl);\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Marked provider ${baseUrl} as failed`\n );\n\n if (!selectedModel) {\n throw new ProviderError(\n baseUrl,\n status,\n \"Funny, no selected model. HMM. \"\n );\n }\n\n const nextProvider = this.providerManager.findNextBestProvider(\n selectedModel.id,\n baseUrl\n );\n\n if (nextProvider) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Failing over to next provider: ${nextProvider}, model: ${selectedModel.id}`\n );\n // Get new model for this provider\n const newModel =\n (await this.providerManager.getModelForProvider(\n nextProvider,\n selectedModel.id\n )) ?? selectedModel;\n\n const messagesForPricing = Array.isArray(\n (body as { messages?: unknown })?.messages\n )\n ? ((body as { messages?: unknown }).messages as any[])\n : [];\n\n const newRequiredSats = this.providerManager.getRequiredSatsForModel(\n newModel,\n messagesForPricing,\n params.maxTokens\n );\n\n if (params.tinfoilEnabled) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Attesting Tinfoil failover provider ${nextProvider} before spend`\n );\n await prepareTinfoilClient({ baseUrl: nextProvider });\n }\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Creating new token for failover provider ${nextProvider}, required sats: ${newRequiredSats}`\n );\n const spendResult = await this._spendToken({\n mintUrl,\n amount: newRequiredSats,\n baseUrl: nextProvider,\n });\n\n // Retry with new provider (reset retry count). Attach the balance that\n // was observed before the retry request so callers do not have to query\n // after the provider may already have charged the request.\n const retryResponse = await this._makeRequest({\n ...params,\n path,\n method,\n body,\n baseUrl: nextProvider,\n selectedModel: newModel,\n token: spendResult.token!,\n requiredSats: newRequiredSats,\n headers: this._withAuthAndTinfoilHeaders(\n params.baseHeaders,\n spendResult.token!,\n params.tinfoilEnabled,\n newModel.id\n ),\n retryCount: 0,\n });\n (retryResponse as any).initialTokenBalanceInSats =\n spendResult.tokenBalanceUnit === \"msat\"\n ? spendResult.tokenBalance / 1000\n : spendResult.tokenBalance;\n (retryResponse as any).initialTokenBalanceUnknown =\n spendResult.tokenBalanceUnknown;\n return retryResponse;\n }\n\n // No more providers to try\n throw new FailoverError(\n baseUrl,\n Array.from(this.providerManager.getFailedProviders())\n );\n }\n\n /**\n * Handle post-response balance update for all modes\n */\n private async _handlePostResponseBalanceUpdate(params: {\n token: string;\n baseUrl: string;\n mintUrl: string;\n initialTokenBalance: number;\n initialTokenBalanceUnknown?: boolean;\n fallbackSatsSpent?: number;\n response?: Response;\n modelId?: string;\n usage?: UsageTrackingData;\n requestId?: string;\n clientApiKey?: string;\n }): Promise<number> {\n const {\n token,\n baseUrl,\n mintUrl,\n initialTokenBalance,\n initialTokenBalanceUnknown,\n fallbackSatsSpent,\n response,\n modelId,\n usage,\n requestId,\n clientApiKey,\n } = params;\n\n let satsSpent: number = initialTokenBalance;\n\n if (this.mode === \"xcashu\" && response) {\n const refundToken = response.headers.get(\"x-cashu\") ?? undefined;\n if (refundToken) {\n const receiveResult =\n await this.cashuSpender.receiveToken(refundToken);\n if (receiveResult.success) {\n // Remove the spent token from storage\n this.storageAdapter.removeXcashuToken(baseUrl, token);\n satsSpent =\n initialTokenBalance -\n receiveResult.amount * (receiveResult.unit == \"sat\" ? 1 : 1000);\n } else {\n this._log(\n \"ERROR\",\n `[xcashu] Failed to receive refund token: ${receiveResult.message}`\n );\n }\n }\n } else if (this.mode === \"apikeys\") {\n try {\n const latestBalanceInfo = await this.balanceManager.getTokenBalance(\n token,\n baseUrl\n );\n this._log(\n \"DEBUG\",\n \"LATEST Balance\",\n latestBalanceInfo.amount,\n latestBalanceInfo.reserved,\n latestBalanceInfo.apiKey,\n baseUrl\n );\n const latestTokenBalance = latestBalanceInfo.balanceUnknown\n ? undefined\n : latestBalanceInfo.unit === \"msat\"\n ? latestBalanceInfo.amount / 1000\n : latestBalanceInfo.amount;\n\n const storedApiKeyEntry = this.storageAdapter.getApiKey(baseUrl);\n if (\n storedApiKeyEntry?.key.startsWith(\"cashu\") &&\n latestBalanceInfo.apiKey\n ) {\n this.storageAdapter.removeApiKey(baseUrl);\n this.storageAdapter.setApiKey(baseUrl, latestBalanceInfo.apiKey);\n }\n if (latestTokenBalance !== undefined) {\n this.storageAdapter.updateApiKeyBalance(baseUrl, latestTokenBalance);\n }\n\n satsSpent =\n latestTokenBalance !== undefined && !initialTokenBalanceUnknown\n ? Math.max(0, initialTokenBalance - latestTokenBalance)\n : (fallbackSatsSpent ?? usage?.satsCost ?? this._headerSatsCost(response) ?? 0);\n } catch (e) {\n this._log(\"WARN\", \"Could not get updated API key balance:\", e);\n satsSpent = fallbackSatsSpent ?? usage?.satsCost ?? this._headerSatsCost(response) ?? 0;\n }\n }\n\n await this._trackResponseUsage({\n token,\n baseUrl,\n response,\n modelId,\n satsSpent,\n usage,\n requestId,\n clientApiKey,\n });\n\n // Fire-and-forget async spinoff - does not block\n (async () => {\n try {\n // Refund all xcashu tokens\n // const xcashuResults =\n // await this.cashuSpender.refundXcashuTokens(mintUrl);\n // this._log(\"DEBUG\", \"Refund xcashu tokens results:\", xcashuResults);\n\n // Also refund API keys (apikeys mode) DISABLED FOR NOW\n // const results = await this.cashuSpaender.refundProviders(mintUrl);\n } catch (error) {\n this._log(\"ERROR\", \"Failed to refund providers:\", error);\n }\n })();\n\n return satsSpent;\n }\n\n /**\n * Extract sats cost from EHBP/Tinfoil response headers as a last-resort\n * fallback when neither balance delta nor SSE/body usage provides a cost.\n */\n private _headerSatsCost(response?: Response): number | undefined {\n if (!response) return undefined;\n const headerUsage = extractUsageFromResponseHeaders(response.headers);\n return headerUsage?.satsCost;\n }\n\n private async _trackResponseUsage(params: {\n token: string;\n baseUrl: string;\n response?: Response;\n modelId?: string;\n satsSpent: number;\n usage?: UsageTrackingData;\n requestId?: string;\n clientApiKey?: string;\n }): Promise<void> {\n const {\n token,\n baseUrl,\n response,\n modelId,\n satsSpent,\n usage: providedUsage,\n requestId: providedRequestId,\n clientApiKey,\n } = params;\n\n if (!response || !modelId) {\n return;\n }\n\n try {\n let usage = providedUsage;\n let requestId = providedRequestId;\n\n if (!usage || !requestId) {\n const contentType = response.headers.get(\"content-type\") || \"\";\n\n if (contentType.includes(\"text/event-stream\")) {\n usage = usage ?? (response as any).usage;\n requestId =\n requestId ??\n (response as any).requestId ??\n response.headers.get(\"x-routstr-request-id\") ??\n undefined;\n\n if (!usage) {\n return;\n }\n } else {\n const cloned = response.clone();\n const responseBody = await cloned.json();\n usage =\n usage ??\n extractUsageFromResponseBody(responseBody, satsSpent) ??\n undefined;\n requestId =\n requestId ??\n extractResponseId(responseBody) ??\n response.headers.get(\"x-routstr-request-id\") ??\n undefined;\n }\n }\n\n if (!usage) {\n // No usage from SSE/body — try response headers (EHBP/Tinfoil path\n // where cost is only in headers because the body is encrypted).\n const headerUsage = extractUsageFromResponseHeaders(response.headers);\n if (headerUsage) {\n usage = headerUsage;\n } else {\n return;\n }\n } else {\n // Merge header-based costs into SSE/body-extracted usage. For EHBP\n // requests, the SSE body may have token counts but no cost breakdown;\n // the headers carry the authoritative cost. Header values take\n // priority when non-zero.\n const headerUsage = extractUsageFromResponseHeaders(response.headers);\n if (headerUsage) {\n // Only override cost fields that headers actually have\n if (headerUsage.totalMsats) {\n usage.totalMsats = headerUsage.totalMsats;\n usage.satsCost = headerUsage.satsCost;\n }\n if (headerUsage.cost) usage.cost = headerUsage.cost;\n if (headerUsage.inputMsats) usage.inputMsats = headerUsage.inputMsats;\n if (headerUsage.outputMsats) usage.outputMsats = headerUsage.outputMsats;\n if (headerUsage.totalUsd) usage.totalUsd = headerUsage.totalUsd;\n }\n }\n\n const finalRequestId = requestId || \"unknown\";\n\n const store = this.sdkStore ?? (await getDefaultSdkStore());\n const state = store.getState();\n\n // Use clientApiKey for matching if provided, otherwise fall back to token\n const matchKey = clientApiKey ?? token;\n const matchingClient = state.clientIds.find(\n (client) => client.apiKey === matchKey\n );\n\n const entryId =\n finalRequestId === \"unknown\"\n ? `req-${Date.now()}-${modelId}`\n : finalRequestId;\n\n const usageTracking =\n this.usageTrackingDriver ?? getDefaultUsageTrackingDriver();\n\n const entry = {\n id: entryId,\n timestamp: Date.now(),\n modelId,\n baseUrl,\n requestId: finalRequestId,\n client: matchingClient?.clientId,\n ...usage,\n };\n\n // For xcashu mode, use satsSpent directly for satsCost instead of calculating from usage\n if (this.mode === \"xcashu\") {\n entry.satsCost = satsSpent;\n }\n\n await usageTracking.append(entry);\n } catch (error) {\n // Silently ignore tracking failures\n }\n }\n\n /**\n * Check wallet balance and throw if insufficient\n */\n private async _checkBalance(): Promise<void> {\n const balances = await this.walletAdapter.getBalances();\n const totalBalance = Object.values(balances).reduce((sum, v) => sum + v, 0);\n\n if (totalBalance <= 0) {\n throw new InsufficientBalanceError(1, 0);\n }\n }\n\n /**\n * Spend a token using CashuSpender with standardized error handling\n */\n private async _spendToken(params: {\n mintUrl: string;\n amount: number;\n baseUrl: string;\n }): Promise<{\n token: string;\n tokenBalance: number;\n tokenBalanceUnit: \"sat\" | \"msat\";\n tokenBalanceUnknown: boolean;\n }> {\n const { mintUrl, amount, baseUrl } = params;\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: mode=${this.mode}, amount=${amount}, baseUrl=${baseUrl}, mintUrl=${mintUrl}`\n );\n\n if (this.mode === \"apikeys\") {\n let parentApiKey = this.storageAdapter.getApiKey(baseUrl);\n if (!parentApiKey) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: No existing API key for ${baseUrl}, creating new one via Cashu`\n );\n const spendResult = await this.cashuSpender.spend({\n mintUrl: mintUrl,\n amount: amount * TOPUP_MARGIN,\n baseUrl: \"\",\n reuseToken: false,\n });\n\n if (!spendResult.token) {\n this._log(\n \"ERROR\",\n `[RoutstrClient] _spendToken: Failed to create Cashu token for API key creation, error:`,\n spendResult.error\n );\n throw new Error(\n `[RoutstrClient] _spendToken: Failed to create Cashu token for API key creation, error: ${spendResult.error}`\n );\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Cashu token created, token preview: ${spendResult.token}`\n );\n }\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Created API key for ${baseUrl}, key preview: ${spendResult.token}, balance: ${spendResult.balance}`\n );\n\n try {\n this.storageAdapter.setApiKey(baseUrl, spendResult.token);\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"ApiKey already exists\")\n ) {\n const receiveResult = await this.cashuSpender.receiveToken(\n spendResult.token\n );\n if (receiveResult.success) {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Token restored successfully, amount=${receiveResult.amount}`\n );\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _handleErrorResponse: Token restore failed: ${receiveResult.message}`\n );\n }\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: API key already exists for ${baseUrl}, using existing key`\n );\n } else {\n throw error;\n }\n }\n parentApiKey = this.storageAdapter.getApiKey(baseUrl);\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Using existing API key for ${baseUrl}, key preview: ${parentApiKey.key}`\n );\n }\n\n let tokenBalance = 0;\n let tokenBalanceUnit: \"sat\" | \"msat\" = \"sat\";\n let tokenBalanceUnknown = false;\n\n const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();\n const distributionForBaseUrl = apiKeyDistribution.find(\n (d) => d.baseUrl === baseUrl\n );\n if (distributionForBaseUrl) {\n tokenBalance = distributionForBaseUrl.amount;\n }\n\n if (tokenBalance === 0 && parentApiKey) {\n try {\n const balanceInfo = await this.balanceManager.getTokenBalance(\n parentApiKey.key,\n baseUrl\n );\n tokenBalance = balanceInfo.amount;\n tokenBalanceUnit = balanceInfo.unit;\n tokenBalanceUnknown = Boolean(balanceInfo.balanceUnknown);\n } catch (e) {\n this._log(\"WARN\", \"Could not get initial API key balance:\", e);\n }\n }\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Returning token with balance=${tokenBalance} ${tokenBalanceUnit}`\n );\n\n return {\n token: parentApiKey?.key ?? \"\",\n tokenBalance,\n tokenBalanceUnit,\n tokenBalanceUnknown,\n };\n }\n\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Calling CashuSpender.spend for amount=${amount}, mintUrl=${mintUrl}, mode=${this.mode}`\n );\n const spendResult = await this.cashuSpender.spend({\n mintUrl,\n amount,\n baseUrl: \"\",\n reuseToken: false,\n });\n\n if (!spendResult.token) {\n this._log(\n \"ERROR\",\n `[RoutstrClient] _spendToken: CashuSpender.spend failed, error:`,\n spendResult.error\n );\n } else {\n this._log(\n \"DEBUG\",\n `[RoutstrClient] _spendToken: Cashu token created, token preview: ${spendResult.token}, balance: ${spendResult.balance} ${spendResult.unit ?? \"sat\"}`\n );\n // Store xcashu token using the storage adapter\n this.storageAdapter.addXcashuToken(baseUrl, spendResult.token);\n }\n\n return {\n token: spendResult.token!,\n tokenBalance: spendResult.balance,\n tokenBalanceUnit: spendResult.unit ?? \"sat\",\n tokenBalanceUnknown: false,\n };\n }\n\n /**\n * Build request headers with common defaults and dev mock controls\n */\n private _buildBaseHeaders(\n additionalHeaders: Record<string, string> = {},\n token?: string\n ): Record<string, string> {\n const headers: Record<string, string> = {\n ...additionalHeaders,\n \"Content-Type\": \"application/json\",\n };\n\n return headers;\n }\n\n /**\n * Attach auth headers using the active client mode\n */\n private _withAuthHeader(\n headers: Record<string, string>,\n token: string\n ): Record<string, string> {\n const nextHeaders = { ...headers };\n\n if (this.mode === \"xcashu\") {\n nextHeaders[\"X-Cashu\"] = token;\n } else {\n nextHeaders[\"Authorization\"] = `Bearer ${token}`;\n }\n\n return nextHeaders;\n }\n\n /**\n * Attach auth headers and preserve the plaintext model hint required by the\n * Routstr proxy for Tinfoil/EHBP requests. EHBP encrypts the JSON body, so\n * retries/failover must not rebuild headers from baseHeaders alone or the\n * proxy cannot route/price the encrypted request.\n */\n private _withAuthAndTinfoilHeaders(\n headers: Record<string, string>,\n token: string,\n tinfoilEnabled?: boolean,\n modelId?: string\n ): Record<string, string> {\n const nextHeaders = this._withAuthHeader(headers, token);\n\n if (tinfoilEnabled && modelId) {\n nextHeaders[\"X-Routstr-Model\"] = modelId;\n }\n\n return nextHeaders;\n }\n\n}\n\n","/**\n * StreamProcessor - Handles SSE streaming response parsing\n *\n * Handles:\n * - Line buffering for large payloads\n * - Content extraction from delta chunks\n * - Thinking/reasoning block extraction\n * - Image data merging and deduplication\n * - Usage statistics extraction\n * - Citations and annotations\n *\n * Extracted from utils/apiUtils.ts processStreamingResponse\n */\n\nimport type { StreamingResult, ImageData, AnnotationData } from \"../core/types\";\nimport { extractUsageFromSSEJson, toUsageStats } from \"./usage\";\n\n/**\n * Callbacks for streaming updates\n */\nexport interface StreamCallbacks {\n /** Called when new content arrives */\n onContent: (content: string) => void;\n /** Called when thinking content arrives */\n onThinking: (thinking: string) => void;\n}\n\n/**\n * StreamProcessor parses SSE streaming responses\n */\nexport class StreamProcessor {\n private accumulatedContent = \"\";\n private accumulatedThinking = \"\";\n private accumulatedImages: ImageData[] = [];\n private isInThinking = false;\n private isInContent = false;\n\n /**\n * Process a streaming response\n */\n async process(\n response: Response,\n callbacks: StreamCallbacks,\n modelId?: string\n ): Promise<StreamingResult> {\n if (!response.body) {\n throw new Error(\"Response body is not available\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder(\"utf-8\");\n let buffer = \"\";\n\n // Reset state\n this.accumulatedContent = \"\";\n this.accumulatedThinking = \"\";\n this.accumulatedImages = [];\n this.isInThinking = false;\n this.isInContent = false;\n\n // Result accumulators\n let usage: StreamingResult[\"usage\"];\n let model: string | undefined;\n let finish_reason: string | undefined;\n let citations: string[] | undefined;\n let annotations: AnnotationData[] | undefined;\n let responseId: string | undefined;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n buffer += chunk;\n\n // Process complete lines\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\"; // Keep incomplete line in buffer\n\n for (const line of lines) {\n const parsed = this._parseLine(line);\n if (!parsed) continue;\n\n // Handle content delta\n if (parsed.content) {\n this._handleContent(parsed.content, callbacks, modelId);\n }\n\n // Handle reasoning/thinking\n if (parsed.reasoning) {\n this._handleThinking(parsed.reasoning, callbacks);\n }\n\n // Extract metadata\n if (parsed.usage) {\n usage = parsed.usage;\n }\n if (parsed.model) {\n model = parsed.model;\n }\n if (parsed.finish_reason) {\n finish_reason = parsed.finish_reason;\n }\n if (parsed.responseId) {\n responseId = parsed.responseId;\n }\n if (parsed.citations) {\n citations = parsed.citations;\n }\n if (parsed.annotations) {\n annotations = parsed.annotations;\n }\n\n // Handle images\n if (parsed.images) {\n this._mergeImages(parsed.images);\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n return {\n content: this.accumulatedContent,\n thinking: this.accumulatedThinking || undefined,\n images: this.accumulatedImages.length > 0 ? this.accumulatedImages : undefined,\n usage,\n model,\n responseId,\n finish_reason,\n citations,\n annotations,\n };\n }\n\n /**\n * Parse a single SSE line\n */\n private _parseLine(line: string): {\n content?: string;\n reasoning?: string;\n usage?: StreamingResult[\"usage\"];\n model?: string;\n finish_reason?: string;\n citations?: string[];\n annotations?: AnnotationData[];\n images?: ImageData[];\n responseId?: string;\n } | null {\n if (!line.trim()) return null;\n\n // SSE data lines start with \"data: \"\n if (!line.startsWith(\"data: \")) {\n // Show \"Generating...\" for non-data lines if no content yet\n return null;\n }\n\n const jsonData = line.slice(6);\n\n if (jsonData === \"[DONE]\") {\n return null;\n }\n\n try {\n const parsed = JSON.parse(jsonData);\n const result: ReturnType<typeof this._parseLine> = {};\n\n // Extract content delta\n if (parsed.choices?.[0]?.delta?.content) {\n result.content = parsed.choices[0].delta.content;\n }\n\n // Extract reasoning (OpenRouter style)\n if (parsed.choices?.[0]?.delta?.reasoning) {\n result.reasoning = parsed.choices[0].delta.reasoning;\n }\n\n // Extract usage (usually in final chunk)\n // extractUsageFromSSEJson handles both usage chunks and standalone cost chunks\n const extractedUsage = extractUsageFromSSEJson(parsed);\n if (extractedUsage) {\n result.usage = toUsageStats(extractedUsage);\n } else if (parsed.usage) {\n // Fallback: raw usage without cost\n result.usage = {\n total_tokens: parsed.usage.total_tokens ?? parsed.usage.input_tokens + parsed.usage.output_tokens,\n prompt_tokens: parsed.usage.prompt_tokens ?? parsed.usage.input_tokens,\n completion_tokens: parsed.usage.completion_tokens ?? parsed.usage.output_tokens,\n };\n }\n\n if (parsed.id) {\n result.responseId = parsed.id;\n }\n\n // Extract model info\n if (parsed.model) {\n result.model = parsed.model;\n }\n\n // Extract citations\n if (parsed.citations) {\n result.citations = parsed.citations;\n }\n\n // Extract annotations\n if (parsed.annotations) {\n result.annotations = parsed.annotations;\n }\n\n // Extract finish reason\n if (parsed.choices?.[0]?.finish_reason) {\n result.finish_reason = parsed.choices[0].finish_reason;\n }\n\n // Extract images (from message or delta)\n const images =\n parsed.choices?.[0]?.message?.images ||\n parsed.choices?.[0]?.delta?.images;\n if (images && Array.isArray(images)) {\n result.images = images;\n }\n\n return result;\n } catch {\n // Swallow parse errors for streaming chunks\n return null;\n }\n }\n\n /**\n * Handle content delta with thinking support\n */\n private _handleContent(\n content: string,\n callbacks: StreamCallbacks,\n modelId?: string\n ): void {\n // If we were in thinking mode and now got content, close thinking tag\n if (this.isInThinking && !this.isInContent) {\n this.accumulatedThinking += \"</thinking>\";\n callbacks.onThinking(this.accumulatedThinking);\n this.isInThinking = false;\n this.isInContent = true;\n }\n\n // For models that use <thinking> tags inline\n if (modelId) {\n this._extractThinkingFromContent(content, callbacks);\n } else {\n this.accumulatedContent += content;\n }\n\n callbacks.onContent(this.accumulatedContent);\n }\n\n /**\n * Handle thinking/reasoning content\n */\n private _handleThinking(reasoning: string, callbacks: StreamCallbacks): void {\n if (!this.isInThinking) {\n this.accumulatedThinking += \"<thinking> \";\n this.isInThinking = true;\n }\n this.accumulatedThinking += reasoning;\n callbacks.onThinking(this.accumulatedThinking);\n }\n\n /**\n * Extract thinking blocks from content (for models with inline thinking)\n */\n private _extractThinkingFromContent(\n content: string,\n callbacks: StreamCallbacks\n ): void {\n // Simple extraction - models that wrap thinking in <thinking> tags\n const parts = content.split(/(<thinking>|<\\/thinking>)/);\n\n for (const part of parts) {\n if (part === \"<thinking>\") {\n this.isInThinking = true;\n if (!this.accumulatedThinking.includes(\"<thinking>\")) {\n this.accumulatedThinking += \"<thinking> \";\n }\n } else if (part === \"</thinking>\") {\n this.isInThinking = false;\n this.accumulatedThinking += \"</thinking>\";\n } else if (this.isInThinking) {\n this.accumulatedThinking += part;\n } else {\n this.accumulatedContent += part;\n }\n }\n }\n\n /**\n * Merge images into accumulated array, avoiding duplicates\n */\n private _mergeImages(newImages: ImageData[]): void {\n for (const img of newImages) {\n const newUrl = img.image_url?.url;\n const existingIndex = this.accumulatedImages.findIndex((existing) => {\n const existingUrl = existing.image_url?.url;\n if (newUrl && existingUrl) {\n return existingUrl === newUrl;\n }\n if (img.index !== undefined && existing.index !== undefined) {\n return existing.index === img.index;\n }\n return false;\n });\n\n if (existingIndex === -1) {\n this.accumulatedImages.push(img);\n } else {\n this.accumulatedImages[existingIndex] = img;\n }\n }\n }\n}\n","import type { Message, Model, TransactionHistory, StreamingResult, SdkLogger } from \"../core/types\";\nimport type { StreamingCallbacks } from \"../wallet/interfaces\";\nimport { StreamProcessor } from \"./StreamProcessor\";\nimport type { AlertLevel, RoutstrClientMode } from \"./RoutstrClient\";\n\n/**\n * Options for fetching AI response\n */\nexport interface FetchOptions {\n messageHistory: Message[];\n selectedModel: Model;\n baseUrl: string;\n mintUrl: string;\n balance: number;\n transactionHistory: TransactionHistory[];\n maxTokens?: number;\n headers?: Record<string, string>;\n}\n\ninterface FetchAIResponseClient {\n routeRequest(params: {\n path: string;\n method: string;\n body?: unknown;\n headers?: Record<string, string>;\n baseUrl: string;\n mintUrl: string;\n modelId?: string;\n }): Promise<Response>;\n getMode(): RoutstrClientMode;\n}\n\nexport interface FetchAIResponseDeps {\n client: FetchAIResponseClient;\n alertLevel: AlertLevel;\n logger: SdkLogger;\n getPendingCashuTokenAmount?: () => number;\n}\n\n/**\n * Fetch an AI chat/completions response using RoutstrClient.routeRequest for\n * payment/auth/failover/accounting, then consume the returned SSE stream and\n * drive the legacy streaming callbacks.\n */\nexport async function fetchAIResponse(\n options: FetchOptions,\n callbacks: StreamingCallbacks,\n deps: FetchAIResponseDeps\n): Promise<void> {\n const {\n messageHistory,\n selectedModel,\n baseUrl,\n mintUrl,\n maxTokens,\n headers,\n } = options;\n\n try {\n const apiMessages = await convertMessages(messageHistory);\n\n callbacks.onPaymentProcessing?.(true);\n\n callbacks.onTokenCreated?.(deps.getPendingCashuTokenAmount?.() ?? 0);\n\n const body: any = {\n model: selectedModel.id,\n messages: apiMessages,\n stream: true,\n };\n\n if (maxTokens !== undefined) {\n body.max_tokens = maxTokens;\n }\n\n if (selectedModel?.name?.startsWith(\"OpenAI:\")) {\n body.tools = [{ type: \"web_search\" }];\n }\n\n const response = await deps.client.routeRequest({\n path: \"/v1/chat/completions\",\n method: \"POST\",\n body,\n headers,\n baseUrl,\n mintUrl,\n modelId: selectedModel.id,\n });\n\n if (!response.body) {\n throw new Error(\"Response body is not available\");\n }\n\n if (response.status !== 200) {\n throw new Error(`${response.status} ${response.statusText}`);\n }\n\n const streamProcessor = new StreamProcessor();\n const streamingResult = await streamProcessor.process(\n response,\n {\n onContent: callbacks.onStreamingUpdate,\n onThinking: callbacks.onThinkingUpdate,\n },\n selectedModel.id\n );\n\n if (streamingResult.finish_reason === \"content_filter\") {\n callbacks.onMessageAppend({\n role: \"assistant\",\n content: \"Your request was denied due to content filtering.\",\n });\n } else if (\n streamingResult.content ||\n (streamingResult.images && streamingResult.images.length > 0)\n ) {\n const message = await createAssistantMessage(streamingResult);\n callbacks.onMessageAppend(message);\n } else {\n callbacks.onMessageAppend({\n role: \"system\",\n content: \"The provider did not respond to this request.\",\n });\n }\n\n callbacks.onStreamingUpdate(\"\");\n callbacks.onThinkingUpdate(\"\");\n\n // routeRequest owns usage extraction + balance finalization. For streaming\n // responses it runs finalization in the background while this function\n // consumes the client-facing stream. Consumers that need exact cost can read\n // the persisted usage entry later.\n } catch (error) {\n handleError(error, callbacks, deps.alertLevel, deps.logger);\n } finally {\n callbacks.onPaymentProcessing?.(false);\n }\n}\n\nasync function convertMessages(messages: Message[]): Promise<any[]> {\n return Promise.all(\n messages\n .filter((m) => m.role !== \"system\")\n .map(async (m) => ({\n role: m.role,\n content: typeof m.content === \"string\" ? m.content : m.content,\n }))\n );\n}\n\nasync function createAssistantMessage(result: StreamingResult): Promise<Message> {\n if (result.images && result.images.length > 0) {\n const content: any[] = [];\n\n if (result.content) {\n content.push({\n type: \"text\",\n text: result.content,\n thinking: result.thinking,\n citations: result.citations,\n annotations: result.annotations,\n });\n }\n\n for (const img of result.images) {\n content.push({\n type: \"image_url\",\n image_url: {\n url: img.image_url.url,\n },\n });\n }\n\n return {\n role: \"assistant\",\n content,\n };\n }\n\n return {\n role: \"assistant\",\n content: result.content || \"\",\n };\n}\n\nfunction handleError(\n error: unknown,\n callbacks: StreamingCallbacks,\n alertLevel: AlertLevel,\n logger: SdkLogger\n): void {\n logger.error(\"[fetchAIResponse] Error occurred\", error);\n\n if (error instanceof Error) {\n const isStreamError =\n error.message.includes(\"Error in input stream\") ||\n error.message.includes(\"Load failed\");\n const modifiedErrorMsg = isStreamError\n ? \"AI stream was cut off, turn on Keep Active or please try again\"\n : error.message;\n\n logger.error(\n `[fetchAIResponse] Error type=${error.constructor.name}, message=${modifiedErrorMsg}, isStreamError=${isStreamError}`\n );\n\n callbacks.onMessageAppend({\n role: \"system\",\n content:\n \"Uncaught Error: \" +\n modifiedErrorMsg +\n (alertLevel === \"max\" ? \" | \" + error.stack : \"\"),\n });\n } else {\n callbacks.onMessageAppend({\n role: \"system\",\n content: \"Unknown Error: Please tag Routstr on Nostr and/or retry.\",\n });\n }\n}\n"]}
|