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