@routstr/sdk 0.1.4 → 0.1.6
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/client/index.js +45 -6
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +45 -6
- package/dist/client/index.mjs.map +1 -1
- package/dist/discovery/index.d.mts +3 -1
- package/dist/discovery/index.d.ts +3 -1
- package/dist/discovery/index.js +17 -13
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/index.mjs +17 -13
- package/dist/discovery/index.mjs.map +1 -1
- package/dist/index.js +62 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +62 -19
- package/dist/index.mjs.map +1 -1
- package/dist/wallet/index.js +3 -0
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +3 -0
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../core/errors.ts","../../wallet/AuditLogger.ts","../../wallet/tokenUtils.ts","../../wallet/CashuSpender.ts","../../wallet/BalanceManager.ts"],"names":["mintUrl"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\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 ) {\n super(\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 );\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 } from \"../core/types\";\nimport { InsufficientBalanceError } from \"../core/errors\";\nimport { BalanceManager } from \"./BalanceManager\";\nimport { auditLogger } from \"./AuditLogger\";\nimport { getBalanceInSats, isNetworkErrorMessage } from \"./tokenUtils\";\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\n constructor(\n private walletAdapter: WalletAdapter,\n private storageAdapter: StorageAdapter,\n private _providerRegistry?: unknown,\n private balanceManager?: BalanceManager\n ) {}\n\n async receiveToken(token: string): Promise<{\n success: boolean;\n amount: number;\n unit: \"sat\" | \"msat\";\n message?: string;\n }> {\n const result = await this.walletAdapter.receiveToken(token);\n\n if (!result.success && result.message?.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 this.storageAdapter.setCachedReceiveTokens([\n ...cachedTokens,\n {\n token,\n amount: result.amount,\n unit: result.unit,\n createdAt: Date.now(),\n },\n ]);\n }\n }\n\n return result;\n }\n\n private async _getBalanceState(): Promise<{\n totalBalance: number;\n providerBalances: Record<string, number>;\n mintBalances: Record<string, number>;\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 pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n const providerBalances: Record<string, number> = {};\n let totalProviderBalance = 0;\n for (const pending of pendingDistribution) {\n providerBalances[pending.baseUrl] = pending.amount;\n totalProviderBalance += pending.amount;\n }\n\n const apiKeys = this.storageAdapter.getAllApiKeys();\n for (const apiKey of apiKeys) {\n if (!providerBalances[apiKey.baseUrl]) {\n providerBalances[apiKey.baseUrl] = apiKey.balance;\n totalProviderBalance += apiKey.balance;\n }\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 console.log(...args);\n break;\n case \"WARN\":\n console.warn(...args);\n break;\n case \"ERROR\":\n console.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 balances\n const balances = await this.walletAdapter.getBalances();\n const units = this.walletAdapter.getMintUnits();\n\n // Calculate total available balance\n let totalBalance = 0;\n for (const url in balances) {\n const balance = balances[url];\n const unit = units[url];\n const balanceInSats = getBalanceInSats(balance, unit);\n totalBalance += balanceInSats;\n }\n\n // Check pending tokens\n const pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n const totalPending = pendingDistribution.reduce(\n (sum, item) => sum + item.amount,\n 0\n );\n\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: totalBalance=${totalBalance}, totalPending=${totalPending}, adjustedAmount=${adjustedAmount}`\n );\n\n const totalAvailableBalance = totalBalance + totalPending;\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 balances,\n units,\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 balances,\n units,\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 && baseUrl) {\n this.storageAdapter.setToken(baseUrl, token);\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 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 token\n */\n private async _tryReuseToken(\n baseUrl: string,\n amount: number,\n mintUrl: string\n ): Promise<SpendResult | null> {\n const storedToken = this.storageAdapter.getToken(baseUrl);\n if (!storedToken) return null;\n\n // Get pending distribution to check balance\n const pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n const balanceForBaseUrl =\n pendingDistribution.find((b) => b.baseUrl === baseUrl)?.amount || 0;\n\n this._log(\"DEBUG\", \"RESUINGDSR GSODGNSD\", balanceForBaseUrl, amount);\n\n if (balanceForBaseUrl > amount) {\n const units = this.walletAdapter.getMintUnits();\n const unit = units[mintUrl] || \"sat\";\n return {\n token: storedToken,\n status: \"success\",\n balance: balanceForBaseUrl,\n unit,\n };\n }\n\n // Token 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 });\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: storedToken,\n status: \"success\",\n balance: newBalance,\n unit,\n };\n }\n\n const providerBalance = await this._getProviderTokenBalance(\n baseUrl,\n storedToken\n );\n this._log(\"DEBUG\", providerBalance);\n if (providerBalance <= 0) {\n this.storageAdapter.removeToken(baseUrl);\n }\n }\n\n return null;\n }\n\n /**\n * Refund specific providers without retrying spend\n */\n async refundProviders(\n baseUrls: string[],\n mintUrl: string,\n refundApiKeys: boolean = false\n ): Promise<{ baseUrl: string; success: boolean }[]> {\n const results: { baseUrl: string; success: boolean }[] = [];\n\n const pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n\n const toRefund = pendingDistribution.filter((p) =>\n baseUrls.includes(p.baseUrl)\n );\n\n const refundResults = await Promise.allSettled(\n toRefund.map(async (pending) => {\n const token = this.storageAdapter.getToken(pending.baseUrl);\n this._log(\"DEBUG\", token, this.balanceManager);\n if (!token || !this.balanceManager) {\n return { baseUrl: pending.baseUrl, success: false };\n }\n\n const tokenBalance = await this.balanceManager.getTokenBalance(\n token,\n pending.baseUrl\n );\n\n if (tokenBalance.reserved > 0) {\n return { baseUrl: pending.baseUrl, success: false };\n }\n\n const result = await this.balanceManager.refund({\n mintUrl,\n baseUrl: pending.baseUrl,\n token,\n });\n this._log(\"DEBUG\", result);\n\n if (result.success) {\n this.storageAdapter.removeToken(pending.baseUrl);\n }\n\n return { baseUrl: pending.baseUrl, success: result.success };\n })\n );\n\n results.push(\n ...refundResults.map((r) =>\n r.status === \"fulfilled\" ? r.value : { baseUrl: \"\", success: false }\n )\n );\n\n if (refundApiKeys) {\n const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();\n const apiKeysToRefund = apiKeyDistribution.filter((p) =>\n baseUrls.includes(p.baseUrl)\n );\n\n for (const apiKeyEntry of apiKeysToRefund) {\n const apiKeyEntryFull = this.storageAdapter.getApiKey(\n apiKeyEntry.baseUrl\n );\n if (apiKeyEntryFull && this.balanceManager) {\n const refundResult = await this.balanceManager.refundApiKey({\n mintUrl,\n baseUrl: apiKeyEntry.baseUrl,\n apiKey: apiKeyEntryFull.key,\n });\n\n if (refundResult.success) {\n this.storageAdapter.updateApiKeyBalance(apiKeyEntry.baseUrl, 0);\n }\n\n results.push({\n baseUrl: apiKeyEntry.baseUrl,\n success: refundResult.success,\n });\n } else {\n results.push({\n baseUrl: apiKeyEntry.baseUrl,\n success: false,\n });\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 balances: Record<string, number>,\n units: Record<string, string>,\n availableBalance?: number\n ): SpendResult {\n let maxBalance = 0;\n let maxMintUrl = \"\";\n\n for (const mintUrl in balances) {\n const balance = balances[mintUrl];\n const unit = units[mintUrl];\n const balanceInSats = getBalanceInSats(balance, unit);\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 } 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 tokens\n */\nexport interface RefundOptions {\n /** The mint URL (for NIP-60 wallet operations) */\n mintUrl: string;\n\n /** The provider base URL */\n baseUrl: string;\n\n /** Optional specific token to refund (if not provided, uses stored token) */\n token?: string;\n}\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\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\n/**\n * BalanceManager handles token refunds and topups from providers\n */\nexport class BalanceManager {\n private cashuSpender: CashuSpender;\n\n constructor(\n private walletAdapter: WalletAdapter,\n private storageAdapter: StorageAdapter,\n private providerRegistry?: ProviderRegistry,\n cashuSpender?: CashuSpender\n ) {\n if (cashuSpender) {\n this.cashuSpender = cashuSpender;\n } else {\n this.cashuSpender = new CashuSpender(\n walletAdapter,\n storageAdapter,\n providerRegistry,\n this\n );\n }\n }\n\n /**\n * Unified refund - handles both NIP-60 and legacy wallet refunds\n */\n async refund(options: RefundOptions): Promise<RefundResult> {\n const { mintUrl, baseUrl, token: providedToken } = options;\n\n const storedToken = providedToken || this.storageAdapter.getToken(baseUrl);\n\n if (!storedToken) {\n console.log(\"[BalanceManager] No token to refund, returning early\");\n return { success: true, message: \"No API key to refund\" };\n }\n\n let fetchResult:\n | { success: boolean; token?: string; requestId?: string; error?: string }\n | undefined;\n\n try {\n // Fetch refund token from provider\n fetchResult = await this._fetchRefundToken(baseUrl, storedToken);\n\n if (!fetchResult.success) {\n return {\n success: false,\n message: fetchResult.error || \"Refund failed\",\n requestId: fetchResult.requestId,\n };\n }\n\n if (!fetchResult.token) {\n return {\n success: false,\n message: \"No token received from refund\",\n requestId: fetchResult.requestId,\n };\n }\n\n // Check if this is a \"no balance to refund\" case\n if (fetchResult.error === \"No balance to refund\") {\n console.log(\n \"[BalanceManager] No balance to refund, removing stored token\"\n );\n this.storageAdapter.removeToken(baseUrl);\n return { success: true, message: \"No balance to refund\" };\n }\n\n // Receive the refunded token\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 // Remove the stored token if we used it from storage\n if (!providedToken) {\n this.storageAdapter.removeToken(baseUrl);\n }\n\n return {\n success: receiveResult.success,\n refundedAmount: totalAmountMsat,\n requestId: fetchResult.requestId,\n };\n } catch (error) {\n console.error(\"[BalanceManager] Refund error\", error);\n return this._handleRefundError(error, mintUrl, fetchResult?.requestId);\n }\n }\n\n /**\n * Refund API key balance - convert remaining API key balance to cashu token\n */\n async refundApiKey(options: RefundApiKeyOptions): Promise<RefundResult> {\n const { mintUrl, baseUrl, apiKey } = options;\n\n if (!apiKey) {\n return { success: false, message: \"No API key to refund\" };\n }\n\n let fetchResult:\n | { success: boolean; token?: string; requestId?: string; error?: string }\n | undefined;\n\n try {\n fetchResult = await this._fetchRefundTokenWithApiKey(baseUrl, apiKey);\n\n if (!fetchResult.success) {\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 return {\n success: false,\n message: \"No token received from API key refund\",\n requestId: fetchResult.requestId,\n };\n }\n\n if (fetchResult.error === \"No balance to refund\") {\n return { success: false, message: \"No balance to refund\" };\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 return {\n success: receiveResult.success,\n refundedAmount: totalAmountMsat,\n requestId: fetchResult.requestId,\n };\n } catch (error) {\n console.error(\"[BalanceManager] 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 authentication\n */\n private async _fetchRefundTokenWithApiKey(\n baseUrl: string,\n apiKey: string\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 response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\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: `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 console.error(\n \"[BalanceManager._fetchRefundTokenWithApiKey] Fetch error\",\n error\n );\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 if (!amount || amount <= 0) {\n return { success: false, message: \"Invalid top up amount\" };\n }\n\n const storedToken = providedToken || this.storageAdapter.getToken(baseUrl);\n if (!storedToken) {\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(\n baseUrl,\n storedToken,\n cashuToken\n );\n requestId = topUpResult.requestId;\n console.log(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 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 if (!adjustedAmount || isNaN(adjustedAmount)) {\n return { success: false, error: \"Invalid top up amount\" };\n }\n\n const balances = await this.walletAdapter.getBalances();\n const units = this.walletAdapter.getMintUnits();\n\n let totalMintBalance = 0;\n for (const url in balances) {\n const unit = units[url];\n const balanceInSats = getBalanceInSats(balances[url], unit);\n totalMintBalance += balanceInSats;\n }\n\n const pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n const refundablePending = pendingDistribution\n .filter((entry) => entry.baseUrl !== baseUrl)\n .reduce((sum, entry) => sum + entry.amount, 0);\n\n if (\n totalMintBalance < adjustedAmount &&\n totalMintBalance + refundablePending >= adjustedAmount &&\n retryCount < 1\n ) {\n await this._refundOtherProvidersForTopUp(baseUrl, mintUrl);\n return this.createProviderToken({\n ...options,\n retryCount: retryCount + 1,\n });\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 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 const token = await this.walletAdapter.sendToken(\n candidateMint,\n requiredAmount,\n p2pkPubkey\n );\n return {\n success: true,\n token,\n selectedMintUrl: candidateMint,\n amountSpent: requiredAmount,\n };\n } catch (error) {\n if (error instanceof Error) {\n lastError = error.message;\n\n if (isNetworkErrorMessage(error.message)) {\n continue;\n }\n }\n\n return {\n success: false,\n error: lastError || \"Failed to create top up token\",\n };\n }\n }\n\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 ): Promise<void> {\n const pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n\n const toRefund = pendingDistribution.filter(\n (pending) => pending.baseUrl !== baseUrl\n );\n\n const refundResults = await Promise.allSettled(\n toRefund.map(async (pending) => {\n const token = this.storageAdapter.getToken(pending.baseUrl);\n if (!token) {\n return { baseUrl: pending.baseUrl, success: false };\n }\n\n const tokenBalance = await this.getTokenBalance(token, pending.baseUrl);\n if (tokenBalance.reserved > 0) {\n return { baseUrl: pending.baseUrl, success: false };\n }\n\n const result = await this.refund({\n mintUrl,\n baseUrl: pending.baseUrl,\n token,\n });\n\n return { baseUrl: pending.baseUrl, success: result.success };\n })\n );\n\n for (const result of refundResults) {\n if (result.status === \"fulfilled\" && result.value.success) {\n this.storageAdapter.removeToken(result.value.baseUrl);\n }\n }\n }\n\n /**\n * Fetch refund token from provider API\n */\n private async _fetchRefundToken(\n baseUrl: string,\n storedToken: string\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\n const url = `${normalizedBaseUrl}v1/wallet/refund`;\n\n // Create an AbortController for timeout handling\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, 60000); // 1 minute timeout\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\n if (\n response.status === 400 &&\n errorData?.detail === \"No balance to refund\"\n ) {\n this.storageAdapter.removeToken(baseUrl);\n return {\n success: false,\n requestId,\n error: \"No balance to refund\",\n };\n }\n\n return {\n success: false,\n requestId,\n error: `Refund request failed with status ${response.status}: ${\n errorData?.detail || response.statusText\n }`,\n };\n }\n\n const data = await response.json();\n console.log(\"refund rsule\", data);\n return {\n success: true,\n token: data.token,\n requestId,\n };\n } catch (error) {\n clearTimeout(timeoutId);\n console.error(\"[BalanceManager._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 refund request\",\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 console.error(\"[BalanceManager._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 console.error(\n \"[BalanceManager._recoverFailedTopUp] Failed to recover token\",\n error\n );\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 }> {\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 console.log(\"TOKENA FASJDFAS\", data);\n return {\n amount: data.balance,\n reserved: data.reserved ?? 0,\n unit: \"msat\",\n apiKey: data.api_key,\n };\n } else {\n console.log(response.status);\n const data = await response.json();\n console.log(\"FAILED \", data);\n }\n } catch (error) {\n console.error(\"ERRORR IN RESTPONSE\", error);\n // Fall through to default\n }\n\n return { amount: -1, reserved: 0, unit: \"sat\", apiKey: \"\" };\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"]}
|
|
1
|
+
{"version":3,"sources":["../../core/errors.ts","../../wallet/AuditLogger.ts","../../wallet/tokenUtils.ts","../../wallet/CashuSpender.ts","../../wallet/BalanceManager.ts"],"names":["mintUrl"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\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 ) {\n super(\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 );\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 } from \"../core/types\";\nimport { InsufficientBalanceError } from \"../core/errors\";\nimport { BalanceManager } from \"./BalanceManager\";\nimport { auditLogger } from \"./AuditLogger\";\nimport { getBalanceInSats, isNetworkErrorMessage } from \"./tokenUtils\";\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\n constructor(\n private walletAdapter: WalletAdapter,\n private storageAdapter: StorageAdapter,\n private _providerRegistry?: unknown,\n private balanceManager?: BalanceManager\n ) {}\n\n async receiveToken(token: string): Promise<{\n success: boolean;\n amount: number;\n unit: \"sat\" | \"msat\";\n message?: string;\n }> {\n const result = await this.walletAdapter.receiveToken(token);\n\n if (!result.success && result.message?.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 this.storageAdapter.setCachedReceiveTokens([\n ...cachedTokens,\n {\n token,\n amount: result.amount,\n unit: result.unit,\n createdAt: Date.now(),\n },\n ]);\n }\n }\n\n return result;\n }\n\n private async _getBalanceState(): Promise<{\n totalBalance: number;\n providerBalances: Record<string, number>;\n mintBalances: Record<string, number>;\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 pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n const providerBalances: Record<string, number> = {};\n let totalProviderBalance = 0;\n for (const pending of pendingDistribution) {\n providerBalances[pending.baseUrl] = pending.amount;\n totalProviderBalance += pending.amount;\n }\n\n const apiKeys = this.storageAdapter.getAllApiKeys();\n for (const apiKey of apiKeys) {\n if (!providerBalances[apiKey.baseUrl]) {\n providerBalances[apiKey.baseUrl] = apiKey.balance;\n totalProviderBalance += apiKey.balance;\n }\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 console.log(...args);\n break;\n case \"WARN\":\n console.warn(...args);\n break;\n case \"ERROR\":\n console.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 balances\n const balances = await this.walletAdapter.getBalances();\n const units = this.walletAdapter.getMintUnits();\n\n // Calculate total available balance\n let totalBalance = 0;\n for (const url in balances) {\n const balance = balances[url];\n const unit = units[url];\n const balanceInSats = getBalanceInSats(balance, unit);\n totalBalance += balanceInSats;\n }\n\n // Check pending tokens\n const pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n const totalPending = pendingDistribution.reduce(\n (sum, item) => sum + item.amount,\n 0\n );\n\n this._log(\n \"DEBUG\",\n `[CashuSpender] _spendInternal: totalBalance=${totalBalance}, totalPending=${totalPending}, adjustedAmount=${adjustedAmount}`\n );\n\n const totalAvailableBalance = totalBalance + totalPending;\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 balances,\n units,\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 balances,\n units,\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 && baseUrl) {\n this.storageAdapter.setToken(baseUrl, token);\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 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 token\n */\n private async _tryReuseToken(\n baseUrl: string,\n amount: number,\n mintUrl: string\n ): Promise<SpendResult | null> {\n const storedToken = this.storageAdapter.getToken(baseUrl);\n if (!storedToken) return null;\n\n // Get pending distribution to check balance\n const pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n const balanceForBaseUrl =\n pendingDistribution.find((b) => b.baseUrl === baseUrl)?.amount || 0;\n\n this._log(\"DEBUG\", \"RESUINGDSR GSODGNSD\", balanceForBaseUrl, amount);\n\n if (balanceForBaseUrl > amount) {\n const units = this.walletAdapter.getMintUnits();\n const unit = units[mintUrl] || \"sat\";\n return {\n token: storedToken,\n status: \"success\",\n balance: balanceForBaseUrl,\n unit,\n };\n }\n\n // Token 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 });\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: storedToken,\n status: \"success\",\n balance: newBalance,\n unit,\n };\n }\n\n const providerBalance = await this._getProviderTokenBalance(\n baseUrl,\n storedToken\n );\n this._log(\"DEBUG\", providerBalance);\n if (providerBalance <= 0) {\n this.storageAdapter.removeToken(baseUrl);\n }\n }\n\n return null;\n }\n\n /**\n * Refund specific providers without retrying spend\n */\n async refundProviders(\n baseUrls: string[],\n mintUrl: string,\n refundApiKeys: boolean = false\n ): Promise<{ baseUrl: string; success: boolean }[]> {\n const results: { baseUrl: string; success: boolean }[] = [];\n\n const pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n\n const toRefund = pendingDistribution.filter((p) =>\n baseUrls.includes(p.baseUrl)\n );\n\n const refundResults = await Promise.allSettled(\n toRefund.map(async (pending) => {\n const token = this.storageAdapter.getToken(pending.baseUrl);\n this._log(\"DEBUG\", token, this.balanceManager);\n if (!token || !this.balanceManager) {\n return { baseUrl: pending.baseUrl, success: false };\n }\n\n const tokenBalance = await this.balanceManager.getTokenBalance(\n token,\n pending.baseUrl\n );\n\n if (tokenBalance.reserved > 0) {\n return { baseUrl: pending.baseUrl, success: false };\n }\n\n const result = await this.balanceManager.refund({\n mintUrl,\n baseUrl: pending.baseUrl,\n token,\n });\n this._log(\"DEBUG\", result);\n\n if (result.success) {\n this.storageAdapter.removeToken(pending.baseUrl);\n }\n\n return { baseUrl: pending.baseUrl, success: result.success };\n })\n );\n\n results.push(\n ...refundResults.map((r) =>\n r.status === \"fulfilled\" ? r.value : { baseUrl: \"\", success: false }\n )\n );\n\n if (refundApiKeys) {\n const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();\n const apiKeysToRefund = apiKeyDistribution.filter((p) =>\n baseUrls.includes(p.baseUrl)\n );\n\n for (const apiKeyEntry of apiKeysToRefund) {\n const apiKeyEntryFull = this.storageAdapter.getApiKey(\n apiKeyEntry.baseUrl\n );\n if (apiKeyEntryFull && this.balanceManager) {\n const refundResult = await this.balanceManager.refundApiKey({\n mintUrl,\n baseUrl: apiKeyEntry.baseUrl,\n apiKey: apiKeyEntryFull.key,\n });\n\n if (refundResult.success) {\n this.storageAdapter.updateApiKeyBalance(apiKeyEntry.baseUrl, 0);\n }\n\n results.push({\n baseUrl: apiKeyEntry.baseUrl,\n success: refundResult.success,\n });\n } else {\n results.push({\n baseUrl: apiKeyEntry.baseUrl,\n success: false,\n });\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 balances: Record<string, number>,\n units: Record<string, string>,\n availableBalance?: number\n ): SpendResult {\n let maxBalance = 0;\n let maxMintUrl = \"\";\n\n for (const mintUrl in balances) {\n const balance = balances[mintUrl];\n const unit = units[mintUrl];\n const balanceInSats = getBalanceInSats(balance, unit);\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 } 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 tokens\n */\nexport interface RefundOptions {\n /** The mint URL (for NIP-60 wallet operations) */\n mintUrl: string;\n\n /** The provider base URL */\n baseUrl: string;\n\n /** Optional specific token to refund (if not provided, uses stored token) */\n token?: string;\n}\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\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\n/**\n * BalanceManager handles token refunds and topups from providers\n */\nexport class BalanceManager {\n private cashuSpender: CashuSpender;\n\n constructor(\n private walletAdapter: WalletAdapter,\n private storageAdapter: StorageAdapter,\n private providerRegistry?: ProviderRegistry,\n cashuSpender?: CashuSpender\n ) {\n if (cashuSpender) {\n this.cashuSpender = cashuSpender;\n } else {\n this.cashuSpender = new CashuSpender(\n walletAdapter,\n storageAdapter,\n providerRegistry,\n this\n );\n }\n }\n\n /**\n * Unified refund - handles both NIP-60 and legacy wallet refunds\n */\n async refund(options: RefundOptions): Promise<RefundResult> {\n const { mintUrl, baseUrl, token: providedToken } = options;\n\n const storedToken = providedToken || this.storageAdapter.getToken(baseUrl);\n\n if (!storedToken) {\n console.log(\"[BalanceManager] No token to refund, returning early\");\n return { success: true, message: \"No API key to refund\" };\n }\n\n let fetchResult:\n | { success: boolean; token?: string; requestId?: string; error?: string }\n | undefined;\n\n try {\n // Fetch refund token from provider\n fetchResult = await this._fetchRefundToken(baseUrl, storedToken);\n\n if (!fetchResult.success) {\n return {\n success: false,\n message: fetchResult.error || \"Refund failed\",\n requestId: fetchResult.requestId,\n };\n }\n\n if (!fetchResult.token) {\n return {\n success: false,\n message: \"No token received from refund\",\n requestId: fetchResult.requestId,\n };\n }\n\n // Check if this is a \"no balance to refund\" case\n if (fetchResult.error === \"No balance to refund\") {\n console.log(\n \"[BalanceManager] No balance to refund, removing stored token\"\n );\n this.storageAdapter.removeToken(baseUrl);\n return { success: true, message: \"No balance to refund\" };\n }\n\n // Receive the refunded token\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 // Remove the stored token if we used it from storage\n if (!providedToken) {\n this.storageAdapter.removeToken(baseUrl);\n }\n\n return {\n success: receiveResult.success,\n refundedAmount: totalAmountMsat,\n requestId: fetchResult.requestId,\n };\n } catch (error) {\n console.error(\"[BalanceManager] Refund error\", error);\n return this._handleRefundError(error, mintUrl, fetchResult?.requestId);\n }\n }\n\n /**\n * Refund API key balance - convert remaining API key balance to cashu token\n */\n async refundApiKey(options: RefundApiKeyOptions): Promise<RefundResult> {\n const { mintUrl, baseUrl, apiKey } = options;\n\n if (!apiKey) {\n return { success: false, message: \"No API key to refund\" };\n }\n\n let fetchResult:\n | { success: boolean; token?: string; requestId?: string; error?: string }\n | undefined;\n\n try {\n fetchResult = await this._fetchRefundTokenWithApiKey(baseUrl, apiKey);\n\n if (!fetchResult.success) {\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 return {\n success: false,\n message: \"No token received from API key refund\",\n requestId: fetchResult.requestId,\n };\n }\n\n if (fetchResult.error === \"No balance to refund\") {\n return { success: false, message: \"No balance to refund\" };\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); // TODO: remove this after all nodes upgrade to 0.4.0\n }\n\n return {\n success: receiveResult.success,\n refundedAmount: totalAmountMsat,\n requestId: fetchResult.requestId,\n };\n } catch (error) {\n console.error(\"[BalanceManager] 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 authentication\n */\n private async _fetchRefundTokenWithApiKey(\n baseUrl: string,\n apiKey: string\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 response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\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: `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 console.error(\n \"[BalanceManager._fetchRefundTokenWithApiKey] Fetch error\",\n error\n );\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 if (!amount || amount <= 0) {\n return { success: false, message: \"Invalid top up amount\" };\n }\n\n const storedToken = providedToken || this.storageAdapter.getToken(baseUrl);\n if (!storedToken) {\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(\n baseUrl,\n storedToken,\n cashuToken\n );\n requestId = topUpResult.requestId;\n console.log(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 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 if (!adjustedAmount || isNaN(adjustedAmount)) {\n return { success: false, error: \"Invalid top up amount\" };\n }\n\n const balances = await this.walletAdapter.getBalances();\n const units = this.walletAdapter.getMintUnits();\n\n let totalMintBalance = 0;\n for (const url in balances) {\n const unit = units[url];\n const balanceInSats = getBalanceInSats(balances[url], unit);\n totalMintBalance += balanceInSats;\n }\n\n const pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n const refundablePending = pendingDistribution\n .filter((entry) => entry.baseUrl !== baseUrl)\n .reduce((sum, entry) => sum + entry.amount, 0);\n\n if (\n totalMintBalance < adjustedAmount &&\n totalMintBalance + refundablePending >= adjustedAmount &&\n retryCount < 1\n ) {\n await this._refundOtherProvidersForTopUp(baseUrl, mintUrl);\n return this.createProviderToken({\n ...options,\n retryCount: retryCount + 1,\n });\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 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 const token = await this.walletAdapter.sendToken(\n candidateMint,\n requiredAmount,\n p2pkPubkey\n );\n return {\n success: true,\n token,\n selectedMintUrl: candidateMint,\n amountSpent: requiredAmount,\n };\n } catch (error) {\n if (error instanceof Error) {\n lastError = error.message;\n\n if (isNetworkErrorMessage(error.message)) {\n continue;\n }\n }\n\n return {\n success: false,\n error: lastError || \"Failed to create top up token\",\n };\n }\n }\n\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 ): Promise<void> {\n const pendingDistribution =\n this.storageAdapter.getCachedTokenDistribution();\n\n const toRefund = pendingDistribution.filter(\n (pending) => pending.baseUrl !== baseUrl\n );\n\n const refundResults = await Promise.allSettled(\n toRefund.map(async (pending) => {\n const token = this.storageAdapter.getToken(pending.baseUrl);\n if (!token) {\n return { baseUrl: pending.baseUrl, success: false };\n }\n\n const tokenBalance = await this.getTokenBalance(token, pending.baseUrl);\n if (tokenBalance.reserved > 0) {\n return { baseUrl: pending.baseUrl, success: false };\n }\n\n const result = await this.refund({\n mintUrl,\n baseUrl: pending.baseUrl,\n token,\n });\n\n return { baseUrl: pending.baseUrl, success: result.success };\n })\n );\n\n for (const result of refundResults) {\n if (result.status === \"fulfilled\" && result.value.success) {\n this.storageAdapter.removeToken(result.value.baseUrl);\n }\n }\n }\n\n /**\n * Fetch refund token from provider API\n */\n private async _fetchRefundToken(\n baseUrl: string,\n storedToken: string\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\n const url = `${normalizedBaseUrl}v1/wallet/refund`;\n\n // Create an AbortController for timeout handling\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, 60000); // 1 minute timeout\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\n if (\n response.status === 400 &&\n errorData?.detail === \"No balance to refund\"\n ) {\n this.storageAdapter.removeToken(baseUrl);\n return {\n success: false,\n requestId,\n error: \"No balance to refund\",\n };\n }\n\n return {\n success: false,\n requestId,\n error: `Refund request failed with status ${response.status}: ${\n errorData?.detail || response.statusText\n }`,\n };\n }\n\n const data = await response.json();\n console.log(\"refund rsule\", data);\n return {\n success: true,\n token: data.token,\n requestId,\n };\n } catch (error) {\n clearTimeout(timeoutId);\n console.error(\"[BalanceManager._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 refund request\",\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 console.error(\"[BalanceManager._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 console.error(\n \"[BalanceManager._recoverFailedTopUp] Failed to recover token\",\n error\n );\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 }> {\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 console.log(\"TOKENA FASJDFAS\", data);\n return {\n amount: data.balance,\n reserved: data.reserved ?? 0,\n unit: \"msat\",\n apiKey: data.api_key,\n };\n } else {\n console.log(response.status);\n const data = await response.json();\n console.log(\"FAILED \", data);\n }\n } catch (error) {\n console.error(\"ERRORR IN RESTPONSE\", error);\n // Fall through to default\n }\n\n return { amount: -1, reserved: 0, unit: \"sat\", apiKey: \"\" };\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"]}
|