@routstr/sdk 0.1.1 → 0.1.3

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.
@@ -108,6 +108,26 @@ var CashuSpender = class {
108
108
  this.balanceManager = balanceManager;
109
109
  }
110
110
  _isBusy = false;
111
+ debugLevel = "WARN";
112
+ async receiveToken(token) {
113
+ const result = await this.walletAdapter.receiveToken(token);
114
+ if (!result.success && result.message?.includes("Failed to fetch mint")) {
115
+ const cachedTokens = this.storageAdapter.getCachedReceiveTokens();
116
+ const existingIndex = cachedTokens.findIndex((t) => t.token === token);
117
+ if (existingIndex === -1) {
118
+ this.storageAdapter.setCachedReceiveTokens([
119
+ ...cachedTokens,
120
+ {
121
+ token,
122
+ amount: result.amount,
123
+ unit: result.unit,
124
+ createdAt: Date.now()
125
+ }
126
+ ]);
127
+ }
128
+ }
129
+ return result;
130
+ }
111
131
  async _getBalanceState() {
112
132
  const mintBalances = await this.walletAdapter.getBalances();
113
133
  const units = this.walletAdapter.getMintUnits();
@@ -150,6 +170,32 @@ var CashuSpender = class {
150
170
  get isBusy() {
151
171
  return this._isBusy;
152
172
  }
173
+ getDebugLevel() {
174
+ return this.debugLevel;
175
+ }
176
+ setDebugLevel(level) {
177
+ this.debugLevel = level;
178
+ }
179
+ _log(level, ...args) {
180
+ const levelPriority = {
181
+ DEBUG: 0,
182
+ WARN: 1,
183
+ ERROR: 2
184
+ };
185
+ if (levelPriority[level] >= levelPriority[this.debugLevel]) {
186
+ switch (level) {
187
+ case "DEBUG":
188
+ console.log(...args);
189
+ break;
190
+ case "WARN":
191
+ console.warn(...args);
192
+ break;
193
+ case "ERROR":
194
+ console.error(...args);
195
+ break;
196
+ }
197
+ }
198
+ }
153
199
  /**
154
200
  * Spend Cashu tokens with automatic mint selection and retry logic
155
201
  * Throws errors on failure instead of returning failed SpendResult
@@ -216,12 +262,16 @@ var CashuSpender = class {
216
262
  excludeMints,
217
263
  retryCount
218
264
  } = options;
219
- console.log(
265
+ this._log(
266
+ "DEBUG",
220
267
  `[CashuSpender] _spendInternal: amount=${amount}, mintUrl=${mintUrl}, baseUrl=${baseUrl}, reuseToken=${reuseToken}`
221
268
  );
222
269
  let adjustedAmount = Math.ceil(amount);
223
270
  if (!adjustedAmount || isNaN(adjustedAmount)) {
224
- console.error(`[CashuSpender] _spendInternal: Invalid amount: ${amount}`);
271
+ this._log(
272
+ "ERROR",
273
+ `[CashuSpender] _spendInternal: Invalid amount: ${amount}`
274
+ );
225
275
  return {
226
276
  token: null,
227
277
  status: "failed",
@@ -230,7 +280,8 @@ var CashuSpender = class {
230
280
  };
231
281
  }
232
282
  if (reuseToken && baseUrl) {
233
- console.log(
283
+ this._log(
284
+ "DEBUG",
234
285
  `[CashuSpender] _spendInternal: Attempting to reuse token for ${baseUrl}`
235
286
  );
236
287
  const existingResult = await this._tryReuseToken(
@@ -239,12 +290,14 @@ var CashuSpender = class {
239
290
  mintUrl
240
291
  );
241
292
  if (existingResult) {
242
- console.log(
293
+ this._log(
294
+ "DEBUG",
243
295
  `[CashuSpender] _spendInternal: Successfully reused token, balance: ${existingResult.balance}`
244
296
  );
245
297
  return existingResult;
246
298
  }
247
- console.log(
299
+ this._log(
300
+ "DEBUG",
248
301
  `[CashuSpender] _spendInternal: Could not reuse token, will create new token`
249
302
  );
250
303
  }
@@ -262,12 +315,14 @@ var CashuSpender = class {
262
315
  (sum, item) => sum + item.amount,
263
316
  0
264
317
  );
265
- console.log(
318
+ this._log(
319
+ "DEBUG",
266
320
  `[CashuSpender] _spendInternal: totalBalance=${totalBalance}, totalPending=${totalPending}, adjustedAmount=${adjustedAmount}`
267
321
  );
268
322
  const totalAvailableBalance = totalBalance + totalPending;
269
323
  if (totalAvailableBalance < adjustedAmount) {
270
- console.error(
324
+ this._log(
325
+ "ERROR",
271
326
  `[CashuSpender] _spendInternal: Insufficient balance, have=${totalAvailableBalance}, need=${adjustedAmount}`
272
327
  );
273
328
  return this._createInsufficientBalanceError(
@@ -335,7 +390,8 @@ var CashuSpender = class {
335
390
  baseUrl,
336
391
  status: "success"
337
392
  });
338
- console.log(
393
+ this._log(
394
+ "DEBUG",
339
395
  `[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`
340
396
  );
341
397
  return {
@@ -353,7 +409,7 @@ var CashuSpender = class {
353
409
  if (!storedToken) return null;
354
410
  const pendingDistribution = this.storageAdapter.getCachedTokenDistribution();
355
411
  const balanceForBaseUrl = pendingDistribution.find((b) => b.baseUrl === baseUrl)?.amount || 0;
356
- console.log("RESUINGDSR GSODGNSD", balanceForBaseUrl, amount);
412
+ this._log("DEBUG", "RESUINGDSR GSODGNSD", balanceForBaseUrl, amount);
357
413
  if (balanceForBaseUrl > amount) {
358
414
  const units = this.walletAdapter.getMintUnits();
359
415
  const unit = units[mintUrl] || "sat";
@@ -371,7 +427,7 @@ var CashuSpender = class {
371
427
  baseUrl,
372
428
  amount: topUpAmount
373
429
  });
374
- console.log("TOPUP ", topUpResult);
430
+ this._log("DEBUG", "TOPUP ", topUpResult);
375
431
  if (topUpResult.success && topUpResult.toppedUpAmount) {
376
432
  const newBalance = balanceForBaseUrl + topUpResult.toppedUpAmount;
377
433
  const units = this.walletAdapter.getMintUnits();
@@ -393,7 +449,7 @@ var CashuSpender = class {
393
449
  baseUrl,
394
450
  storedToken
395
451
  );
396
- console.log(providerBalance);
452
+ this._log("DEBUG", providerBalance);
397
453
  if (providerBalance <= 0) {
398
454
  this.storageAdapter.removeToken(baseUrl);
399
455
  }
@@ -412,7 +468,7 @@ var CashuSpender = class {
412
468
  const refundResults = await Promise.allSettled(
413
469
  toRefund.map(async (pending) => {
414
470
  const token = this.storageAdapter.getToken(pending.baseUrl);
415
- console.log(token, this.balanceManager);
471
+ this._log("DEBUG", token, this.balanceManager);
416
472
  if (!token || !this.balanceManager) {
417
473
  return { baseUrl: pending.baseUrl, success: false };
418
474
  }
@@ -428,7 +484,7 @@ var CashuSpender = class {
428
484
  baseUrl: pending.baseUrl,
429
485
  token
430
486
  });
431
- console.log(result);
487
+ this._log("DEBUG", result);
432
488
  if (result.success) {
433
489
  this.storageAdapter.removeToken(pending.baseUrl);
434
490
  }
@@ -526,11 +582,22 @@ var CashuSpender = class {
526
582
 
527
583
  // wallet/BalanceManager.ts
528
584
  var BalanceManager = class {
529
- constructor(walletAdapter, storageAdapter, providerRegistry) {
585
+ constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender) {
530
586
  this.walletAdapter = walletAdapter;
531
587
  this.storageAdapter = storageAdapter;
532
588
  this.providerRegistry = providerRegistry;
589
+ if (cashuSpender) {
590
+ this.cashuSpender = cashuSpender;
591
+ } else {
592
+ this.cashuSpender = new CashuSpender(
593
+ walletAdapter,
594
+ storageAdapter,
595
+ providerRegistry,
596
+ this
597
+ );
598
+ }
533
599
  }
600
+ cashuSpender;
534
601
  /**
535
602
  * Unified refund - handles both NIP-60 and legacy wallet refunds
536
603
  */
@@ -565,7 +632,7 @@ var BalanceManager = class {
565
632
  this.storageAdapter.removeToken(baseUrl);
566
633
  return { success: true, message: "No balance to refund" };
567
634
  }
568
- const receiveResult = await this.walletAdapter.receiveToken(
635
+ const receiveResult = await this.cashuSpender.receiveToken(
569
636
  fetchResult.token
570
637
  );
571
638
  const totalAmountMsat = receiveResult.unit === "msat" ? receiveResult.amount : receiveResult.amount * 1e3;
@@ -610,7 +677,7 @@ var BalanceManager = class {
610
677
  if (fetchResult.error === "No balance to refund") {
611
678
  return { success: false, message: "No balance to refund" };
612
679
  }
613
- const receiveResult = await this.walletAdapter.receiveToken(
680
+ const receiveResult = await this.cashuSpender.receiveToken(
614
681
  fetchResult.token
615
682
  );
616
683
  const totalAmountMsat = receiveResult.unit === "msat" ? receiveResult.amount : receiveResult.amount * 1e3;
@@ -1051,7 +1118,7 @@ var BalanceManager = class {
1051
1118
  */
1052
1119
  async _recoverFailedTopUp(cashuToken) {
1053
1120
  try {
1054
- await this.walletAdapter.receiveToken(cashuToken);
1121
+ await this.cashuSpender.receiveToken(cashuToken);
1055
1122
  } catch (error) {
1056
1123
  console.error(
1057
1124
  "[BalanceManager._recoverFailedTopUp] Failed to recover token",
@@ -1722,12 +1789,39 @@ var RoutstrClient = class {
1722
1789
  providerManager;
1723
1790
  alertLevel;
1724
1791
  mode;
1792
+ debugLevel = "WARN";
1725
1793
  /**
1726
1794
  * Get the current client mode
1727
1795
  */
1728
1796
  getMode() {
1729
1797
  return this.mode;
1730
1798
  }
1799
+ getDebugLevel() {
1800
+ return this.debugLevel;
1801
+ }
1802
+ setDebugLevel(level) {
1803
+ this.debugLevel = level;
1804
+ }
1805
+ _log(level, ...args) {
1806
+ const levelPriority = {
1807
+ DEBUG: 0,
1808
+ WARN: 1,
1809
+ ERROR: 2
1810
+ };
1811
+ if (levelPriority[level] >= levelPriority[this.debugLevel]) {
1812
+ switch (level) {
1813
+ case "DEBUG":
1814
+ console.log(...args);
1815
+ break;
1816
+ case "WARN":
1817
+ console.warn(...args);
1818
+ break;
1819
+ case "ERROR":
1820
+ console.error(...args);
1821
+ break;
1822
+ }
1823
+ }
1824
+ }
1731
1825
  /**
1732
1826
  * Get the CashuSpender instance
1733
1827
  */
@@ -1791,7 +1885,7 @@ var RoutstrClient = class {
1791
1885
  amount: requiredSats,
1792
1886
  baseUrl
1793
1887
  });
1794
- console.log(token, baseUrl);
1888
+ this._log("DEBUG", token, baseUrl);
1795
1889
  let requestBody = body;
1796
1890
  if (body && typeof body === "object") {
1797
1891
  const bodyObj = body;
@@ -1815,8 +1909,9 @@ var RoutstrClient = class {
1815
1909
  });
1816
1910
  const tokenBalanceInSats = tokenBalanceUnit === "msat" ? tokenBalance / 1e3 : tokenBalance;
1817
1911
  const baseUrlUsed = response.baseUrl || baseUrl;
1912
+ const tokenUsed = response.token || token;
1818
1913
  await this._handlePostResponseBalanceUpdate({
1819
- token,
1914
+ token: tokenUsed,
1820
1915
  baseUrl: baseUrlUsed,
1821
1916
  initialTokenBalance: tokenBalanceInSats,
1822
1917
  response
@@ -1952,22 +2047,30 @@ var RoutstrClient = class {
1952
2047
  const { path, method, body, baseUrl, token, headers } = params;
1953
2048
  try {
1954
2049
  const url = `${baseUrl.replace(/\/$/, "")}${path}`;
1955
- if (this.mode === "xcashu") console.log("HEADERS,", headers);
2050
+ if (this.mode === "xcashu") this._log("DEBUG", "HEADERS,", headers);
1956
2051
  const response = await fetch(url, {
1957
2052
  method,
1958
2053
  headers,
1959
2054
  body: body === void 0 || method === "GET" ? void 0 : JSON.stringify(body)
1960
2055
  });
1961
- if (this.mode === "xcashu") console.log("response,", response);
2056
+ if (this.mode === "xcashu") this._log("DEBUG", "response,", response);
1962
2057
  response.baseUrl = baseUrl;
2058
+ response.token = token;
1963
2059
  if (!response.ok) {
1964
2060
  const requestId = response.headers.get("x-routstr-request-id") || void 0;
2061
+ let bodyText;
2062
+ try {
2063
+ bodyText = await response.text();
2064
+ } catch (e) {
2065
+ bodyText = void 0;
2066
+ }
1965
2067
  return await this._handleErrorResponse(
1966
2068
  params,
1967
2069
  token,
1968
2070
  response.status,
1969
2071
  requestId,
1970
- this.mode === "xcashu" ? response.headers.get("x-cashu") ?? void 0 : void 0
2072
+ this.mode === "xcashu" ? response.headers.get("x-cashu") ?? void 0 : void 0,
2073
+ bodyText
1971
2074
  );
1972
2075
  }
1973
2076
  return response;
@@ -1986,41 +2089,47 @@ var RoutstrClient = class {
1986
2089
  /**
1987
2090
  * Handle error responses with failover
1988
2091
  */
1989
- async _handleErrorResponse(params, token, status, requestId, xCashuRefundToken) {
2092
+ async _handleErrorResponse(params, token, status, requestId, xCashuRefundToken, responseBody) {
1990
2093
  const { path, method, body, selectedModel, baseUrl, mintUrl } = params;
1991
2094
  let tryNextProvider = false;
1992
- console.log(
2095
+ this._log(
2096
+ "DEBUG",
1993
2097
  `[RoutstrClient] _handleErrorResponse: status=${status}, baseUrl=${baseUrl}, mode=${this.mode}, token preview=${token}, requestId=${requestId}`
1994
2098
  );
1995
- console.log(
2099
+ this._log(
2100
+ "DEBUG",
1996
2101
  `[RoutstrClient] _handleErrorResponse: Attempting to receive/restore token for ${baseUrl}`
1997
2102
  );
1998
2103
  if (params.token.startsWith("cashu")) {
1999
- const tryReceiveTokenResult = await this.walletAdapter.receiveToken(
2104
+ const tryReceiveTokenResult = await this.cashuSpender.receiveToken(
2000
2105
  params.token
2001
2106
  );
2002
2107
  if (tryReceiveTokenResult.success) {
2003
- console.log(
2108
+ this._log(
2109
+ "DEBUG",
2004
2110
  `[RoutstrClient] _handleErrorResponse: Token restored successfully, amount=${tryReceiveTokenResult.amount}`
2005
2111
  );
2006
2112
  tryNextProvider = true;
2007
2113
  if (this.mode === "lazyrefund")
2008
2114
  this.storageAdapter.removeToken(baseUrl);
2009
2115
  } else {
2010
- console.log(
2011
- `[RoutstrClient] _handleErrorResponse: Token restore failed or not needed`
2116
+ this._log(
2117
+ "DEBUG",
2118
+ `[RoutstrClient] _handleErrorResponse: Failed to receive token. `
2012
2119
  );
2013
2120
  }
2014
2121
  }
2015
2122
  if (this.mode === "xcashu") {
2016
2123
  if (xCashuRefundToken) {
2017
- console.log(
2124
+ this._log(
2125
+ "DEBUG",
2018
2126
  `[RoutstrClient] _handleErrorResponse: Attempting to receive xcashu refund token, preview=${xCashuRefundToken.substring(0, 20)}...`
2019
2127
  );
2020
2128
  try {
2021
- const receiveResult = await this.walletAdapter.receiveToken(xCashuRefundToken);
2129
+ const receiveResult = await this.cashuSpender.receiveToken(xCashuRefundToken);
2022
2130
  if (receiveResult.success) {
2023
- console.log(
2131
+ this._log(
2132
+ "DEBUG",
2024
2133
  `[RoutstrClient] _handleErrorResponse: xcashu refund received, amount=${receiveResult.amount}`
2025
2134
  );
2026
2135
  tryNextProvider = true;
@@ -2032,7 +2141,7 @@ var RoutstrClient = class {
2032
2141
  requestId
2033
2142
  );
2034
2143
  } catch (error) {
2035
- console.error("[xcashu] Failed to receive refund token:", error);
2144
+ this._log("ERROR", "[xcashu] Failed to receive refund token:", error);
2036
2145
  throw new ProviderError(
2037
2146
  baseUrl,
2038
2147
  status,
@@ -2050,14 +2159,15 @@ var RoutstrClient = class {
2050
2159
  );
2051
2160
  }
2052
2161
  }
2053
- if (status === 402 && !tryNextProvider && (this.mode === "apikeys" || this.mode === "lazyrefund")) {
2162
+ if ((status === 402 || status === 413 && responseBody?.includes("Insufficient balance")) && !tryNextProvider && (this.mode === "apikeys" || this.mode === "lazyrefund")) {
2054
2163
  const topupResult = await this.balanceManager.topUp({
2055
2164
  mintUrl,
2056
2165
  baseUrl,
2057
2166
  amount: params.requiredSats * TOPUP_MARGIN,
2058
2167
  token: params.token
2059
2168
  });
2060
- console.log(
2169
+ this._log(
2170
+ "DEBUG",
2061
2171
  `[RoutstrClient] _handleErrorResponse: Topup result for ${baseUrl}: success=${topupResult.success}, message=${topupResult.message}`
2062
2172
  );
2063
2173
  if (!topupResult.success) {
@@ -2067,18 +2177,21 @@ var RoutstrClient = class {
2067
2177
  const haveMatch = message.match(/have (\d+)/);
2068
2178
  const required = needMatch ? parseInt(needMatch[1], 10) : params.requiredSats;
2069
2179
  const available = haveMatch ? parseInt(haveMatch[1], 10) : 0;
2070
- console.log(
2180
+ this._log(
2181
+ "DEBUG",
2071
2182
  `[RoutstrClient] _handleErrorResponse: Insufficient balance, need=${required}, have=${available}`
2072
2183
  );
2073
2184
  throw new InsufficientBalanceError(required, available);
2074
2185
  } else {
2075
- console.log(
2186
+ this._log(
2187
+ "DEBUG",
2076
2188
  `[RoutstrClient] _handleErrorResponse: Topup failed with non-insufficient-balance error, will try next provider`
2077
2189
  );
2078
2190
  tryNextProvider = true;
2079
2191
  }
2080
2192
  } else {
2081
- console.log(
2193
+ this._log(
2194
+ "DEBUG",
2082
2195
  `[RoutstrClient] _handleErrorResponse: Topup successful, will retry with new token`
2083
2196
  );
2084
2197
  }
@@ -2089,8 +2202,9 @@ var RoutstrClient = class {
2089
2202
  headers: this._withAuthHeader(params.baseHeaders, params.token)
2090
2203
  });
2091
2204
  }
2092
- if ((status === 401 || status === 403 || status === 413 || status === 400 || status === 500 || status === 502 || status === 503 || status === 521) && !tryNextProvider) {
2093
- console.log(
2205
+ if ((status === 401 || status === 403 || status === 413 || status === 400 || status === 500 || status === 502 || status === 503 || status === 504 || status === 521) && !tryNextProvider) {
2206
+ this._log(
2207
+ "DEBUG",
2094
2208
  `[RoutstrClient] _handleErrorResponse: Status ${status} (auth/server error), attempting refund for ${baseUrl}, mode=${this.mode}`
2095
2209
  );
2096
2210
  if (this.mode === "lazyrefund") {
@@ -2100,7 +2214,8 @@ var RoutstrClient = class {
2100
2214
  baseUrl,
2101
2215
  token: params.token
2102
2216
  });
2103
- console.log(
2217
+ this._log(
2218
+ "DEBUG",
2104
2219
  `[RoutstrClient] _handleErrorResponse: Lazyrefund result: success=${refundResult.success}`
2105
2220
  );
2106
2221
  if (refundResult.success) this.storageAdapter.removeToken(baseUrl);
@@ -2120,14 +2235,16 @@ var RoutstrClient = class {
2120
2235
  );
2121
2236
  }
2122
2237
  } else if (this.mode === "apikeys") {
2123
- console.log(
2238
+ this._log(
2239
+ "DEBUG",
2124
2240
  `[RoutstrClient] _handleErrorResponse: Attempting API key refund for ${baseUrl}, key preview=${token}`
2125
2241
  );
2126
2242
  const initialBalance = await this.balanceManager.getTokenBalance(
2127
2243
  token,
2128
2244
  baseUrl
2129
2245
  );
2130
- console.log(
2246
+ this._log(
2247
+ "DEBUG",
2131
2248
  `[RoutstrClient] _handleErrorResponse: Initial API key balance: ${initialBalance.amount}`
2132
2249
  );
2133
2250
  const refundResult = await this.balanceManager.refundApiKey({
@@ -2135,7 +2252,8 @@ var RoutstrClient = class {
2135
2252
  baseUrl,
2136
2253
  apiKey: token
2137
2254
  });
2138
- console.log(
2255
+ this._log(
2256
+ "DEBUG",
2139
2257
  `[RoutstrClient] _handleErrorResponse: API key refund result: success=${refundResult.success}, message=${refundResult.message}`
2140
2258
  );
2141
2259
  if (!refundResult.success && initialBalance.amount > 0) {
@@ -2150,7 +2268,8 @@ var RoutstrClient = class {
2150
2268
  }
2151
2269
  }
2152
2270
  this.providerManager.markFailed(baseUrl);
2153
- console.log(
2271
+ this._log(
2272
+ "DEBUG",
2154
2273
  `[RoutstrClient] _handleErrorResponse: Marked provider ${baseUrl} as failed`
2155
2274
  );
2156
2275
  if (!selectedModel) {
@@ -2165,7 +2284,8 @@ var RoutstrClient = class {
2165
2284
  baseUrl
2166
2285
  );
2167
2286
  if (nextProvider) {
2168
- console.log(
2287
+ this._log(
2288
+ "DEBUG",
2169
2289
  `[RoutstrClient] _handleErrorResponse: Failing over to next provider: ${nextProvider}, model: ${selectedModel.id}`
2170
2290
  );
2171
2291
  const newModel = await this.providerManager.getModelForProvider(
@@ -2180,7 +2300,8 @@ var RoutstrClient = class {
2180
2300
  messagesForPricing,
2181
2301
  params.maxTokens
2182
2302
  );
2183
- console.log(
2303
+ this._log(
2304
+ "DEBUG",
2184
2305
  `[RoutstrClient] _handleErrorResponse: Creating new token for failover provider ${nextProvider}, required sats: ${newRequiredSats}`
2185
2306
  );
2186
2307
  const spendResult = await this._spendToken({
@@ -2212,10 +2333,10 @@ var RoutstrClient = class {
2212
2333
  const refundToken = response.headers.get("x-cashu") ?? void 0;
2213
2334
  if (refundToken) {
2214
2335
  try {
2215
- const receiveResult = await this.walletAdapter.receiveToken(refundToken);
2336
+ const receiveResult = await this.cashuSpender.receiveToken(refundToken);
2216
2337
  satsSpent = initialTokenBalance - receiveResult.amount * (receiveResult.unit == "sat" ? 1 : 1e3);
2217
2338
  } catch (error) {
2218
- console.error("[xcashu] Failed to receive refund token:", error);
2339
+ this._log("ERROR", "[xcashu] Failed to receive refund token:", error);
2219
2340
  }
2220
2341
  }
2221
2342
  } else if (this.mode === "lazyrefund") {
@@ -2232,7 +2353,8 @@ var RoutstrClient = class {
2232
2353
  token,
2233
2354
  baseUrl
2234
2355
  );
2235
- console.log(
2356
+ this._log(
2357
+ "DEBUG",
2236
2358
  "LATEST Balance",
2237
2359
  latestBalanceInfo.amount,
2238
2360
  latestBalanceInfo.reserved,
@@ -2244,7 +2366,7 @@ var RoutstrClient = class {
2244
2366
  this.storageAdapter.updateApiKeyBalance(baseUrl, latestTokenBalance);
2245
2367
  satsSpent = initialTokenBalance - latestTokenBalance;
2246
2368
  } catch (e) {
2247
- console.warn("Could not get updated API key balance:", e);
2369
+ this._log("WARN", "Could not get updated API key balance:", e);
2248
2370
  satsSpent = fallbackSatsSpent ?? initialTokenBalance;
2249
2371
  }
2250
2372
  }
@@ -2355,11 +2477,12 @@ var RoutstrClient = class {
2355
2477
  * Handle errors and notify callbacks
2356
2478
  */
2357
2479
  _handleError(error, callbacks) {
2358
- console.error("[RoutstrClient] _handleError: Error occurred", error);
2480
+ this._log("ERROR", "[RoutstrClient] _handleError: Error occurred", error);
2359
2481
  if (error instanceof Error) {
2360
2482
  const isStreamError = error.message.includes("Error in input stream") || error.message.includes("Load failed");
2361
2483
  const modifiedErrorMsg = isStreamError ? "AI stream was cut off, turn on Keep Active or please try again" : error.message;
2362
- console.error(
2484
+ this._log(
2485
+ "ERROR",
2363
2486
  `[RoutstrClient] _handleError: Error type=${error.constructor.name}, message=${modifiedErrorMsg}, isStreamError=${isStreamError}`
2364
2487
  );
2365
2488
  callbacks.onMessageAppend({
@@ -2388,13 +2511,15 @@ var RoutstrClient = class {
2388
2511
  */
2389
2512
  async _spendToken(params) {
2390
2513
  const { mintUrl, amount, baseUrl } = params;
2391
- console.log(
2514
+ this._log(
2515
+ "DEBUG",
2392
2516
  `[RoutstrClient] _spendToken: mode=${this.mode}, amount=${amount}, baseUrl=${baseUrl}, mintUrl=${mintUrl}`
2393
2517
  );
2394
2518
  if (this.mode === "apikeys") {
2395
2519
  let parentApiKey = this.storageAdapter.getApiKey(baseUrl);
2396
2520
  if (!parentApiKey) {
2397
- console.log(
2521
+ this._log(
2522
+ "DEBUG",
2398
2523
  `[RoutstrClient] _spendToken: No existing API key for ${baseUrl}, creating new one via Cashu`
2399
2524
  );
2400
2525
  const spendResult2 = await this.cashuSpender.spend({
@@ -2404,7 +2529,8 @@ var RoutstrClient = class {
2404
2529
  reuseToken: false
2405
2530
  });
2406
2531
  if (!spendResult2.token) {
2407
- console.error(
2532
+ this._log(
2533
+ "ERROR",
2408
2534
  `[RoutstrClient] _spendToken: Failed to create Cashu token for API key creation, error:`,
2409
2535
  spendResult2.error
2410
2536
  );
@@ -2412,30 +2538,35 @@ var RoutstrClient = class {
2412
2538
  `[RoutstrClient] _spendToken: Failed to create Cashu token for API key creation, error: ${spendResult2.error}`
2413
2539
  );
2414
2540
  } else {
2415
- console.log(
2541
+ this._log(
2542
+ "DEBUG",
2416
2543
  `[RoutstrClient] _spendToken: Cashu token created, token preview: ${spendResult2.token}`
2417
2544
  );
2418
2545
  }
2419
- console.log(
2546
+ this._log(
2547
+ "DEBUG",
2420
2548
  `[RoutstrClient] _spendToken: Created API key for ${baseUrl}, key preview: ${spendResult2.token}, balance: ${spendResult2.balance}`
2421
2549
  );
2422
2550
  try {
2423
2551
  this.storageAdapter.setApiKey(baseUrl, spendResult2.token);
2424
2552
  } catch (error) {
2425
2553
  if (error instanceof Error && error.message.includes("ApiKey already exists")) {
2426
- const tryReceiveTokenResult = await this.walletAdapter.receiveToken(
2554
+ const tryReceiveTokenResult = await this.cashuSpender.receiveToken(
2427
2555
  spendResult2.token
2428
2556
  );
2429
2557
  if (tryReceiveTokenResult.success) {
2430
- console.log(
2558
+ this._log(
2559
+ "DEBUG",
2431
2560
  `[RoutstrClient] _handleErrorResponse: Token restored successfully, amount=${tryReceiveTokenResult.amount}`
2432
2561
  );
2433
2562
  } else {
2434
- console.log(
2563
+ this._log(
2564
+ "DEBUG",
2435
2565
  `[RoutstrClient] _handleErrorResponse: Token restore failed or not needed`
2436
2566
  );
2437
2567
  }
2438
- console.log(
2568
+ this._log(
2569
+ "DEBUG",
2439
2570
  `[RoutstrClient] _spendToken: API key already exists for ${baseUrl}, using existing key`
2440
2571
  );
2441
2572
  } else {
@@ -2444,7 +2575,8 @@ var RoutstrClient = class {
2444
2575
  }
2445
2576
  parentApiKey = this.storageAdapter.getApiKey(baseUrl);
2446
2577
  } else {
2447
- console.log(
2578
+ this._log(
2579
+ "DEBUG",
2448
2580
  `[RoutstrClient] _spendToken: Using existing API key for ${baseUrl}, key preview: ${parentApiKey.key}`
2449
2581
  );
2450
2582
  }
@@ -2466,10 +2598,11 @@ var RoutstrClient = class {
2466
2598
  tokenBalance = balanceInfo.amount;
2467
2599
  tokenBalanceUnit = balanceInfo.unit;
2468
2600
  } catch (e) {
2469
- console.warn("Could not get initial API key balance:", e);
2601
+ this._log("WARN", "Could not get initial API key balance:", e);
2470
2602
  }
2471
2603
  }
2472
- console.log(
2604
+ this._log(
2605
+ "DEBUG",
2473
2606
  `[RoutstrClient] _spendToken: Returning token with balance=${tokenBalance} ${tokenBalanceUnit}`
2474
2607
  );
2475
2608
  return {
@@ -2478,7 +2611,8 @@ var RoutstrClient = class {
2478
2611
  tokenBalanceUnit
2479
2612
  };
2480
2613
  }
2481
- console.log(
2614
+ this._log(
2615
+ "DEBUG",
2482
2616
  `[RoutstrClient] _spendToken: Calling CashuSpender.spend for amount=${amount}, mintUrl=${mintUrl}, mode=${this.mode}`
2483
2617
  );
2484
2618
  const spendResult = await this.cashuSpender.spend({
@@ -2488,12 +2622,14 @@ var RoutstrClient = class {
2488
2622
  reuseToken: this.mode === "lazyrefund"
2489
2623
  });
2490
2624
  if (!spendResult.token) {
2491
- console.error(
2625
+ this._log(
2626
+ "ERROR",
2492
2627
  `[RoutstrClient] _spendToken: CashuSpender.spend failed, error:`,
2493
2628
  spendResult.error
2494
2629
  );
2495
2630
  } else {
2496
- console.log(
2631
+ this._log(
2632
+ "DEBUG",
2497
2633
  `[RoutstrClient] _spendToken: Cashu token created, token preview: ${spendResult.token}, balance: ${spendResult.balance} ${spendResult.unit ?? "sat"}`
2498
2634
  );
2499
2635
  }