@routstr/sdk 0.3.3 → 0.3.5

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.
Files changed (39) hide show
  1. package/dist/client/index.d.mts +9 -5
  2. package/dist/client/index.d.ts +9 -5
  3. package/dist/client/index.js +107 -136
  4. package/dist/client/index.js.map +1 -1
  5. package/dist/client/index.mjs +107 -136
  6. package/dist/client/index.mjs.map +1 -1
  7. package/dist/discovery/index.d.mts +8 -2
  8. package/dist/discovery/index.d.ts +8 -2
  9. package/dist/discovery/index.js +27 -16
  10. package/dist/discovery/index.js.map +1 -1
  11. package/dist/discovery/index.mjs +27 -16
  12. package/dist/discovery/index.mjs.map +1 -1
  13. package/dist/index.d.mts +10 -8
  14. package/dist/index.d.ts +10 -8
  15. package/dist/index.js +179 -193
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.mjs +178 -194
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/{interfaces-C5fLD3jB.d.mts → interfaces-Bp0Ngmqv.d.mts} +1 -1
  20. package/dist/{interfaces-BxDEka72.d.ts → interfaces-CIfd_phZ.d.ts} +1 -1
  21. package/dist/{interfaces-BWJJTCXO.d.mts → interfaces-Cxi8R4TT.d.mts} +1 -1
  22. package/dist/{interfaces-B62Rw-dd.d.ts → interfaces-D2FDCLyP.d.ts} +1 -1
  23. package/dist/storage/index.d.mts +9 -7
  24. package/dist/storage/index.d.ts +9 -7
  25. package/dist/storage/index.js +52 -37
  26. package/dist/storage/index.js.map +1 -1
  27. package/dist/storage/index.mjs +52 -37
  28. package/dist/storage/index.mjs.map +1 -1
  29. package/dist/{store-h7m23ffq.d.ts → store-BD5zF9Hp.d.ts} +4 -4
  30. package/dist/{store-DGeLPv9E.d.mts → store-CBSyK2qg.d.mts} +4 -4
  31. package/dist/{types-BYj_8c5c.d.mts → types-DPQM6tIG.d.mts} +10 -1
  32. package/dist/{types-BYj_8c5c.d.ts → types-DPQM6tIG.d.ts} +10 -1
  33. package/dist/wallet/index.d.mts +8 -6
  34. package/dist/wallet/index.d.ts +8 -6
  35. package/dist/wallet/index.js +80 -57
  36. package/dist/wallet/index.js.map +1 -1
  37. package/dist/wallet/index.mjs +80 -57
  38. package/dist/wallet/index.mjs.map +1 -1
  39. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
- import { M as Model, a as Message, T as TransactionHistory, l as StreamingResult } from '../types-BYj_8c5c.mjs';
2
- import { P as ProviderRegistry, W as WalletAdapter, S as StorageAdapter, a as StreamingCallbacks } from '../interfaces-C5fLD3jB.mjs';
3
- import { S as SdkStore, U as UsageTrackingDriver } from '../store-DGeLPv9E.mjs';
1
+ import { M as Model, S as SdkLogger, a as Message, T as TransactionHistory, m as StreamingResult } from '../types-DPQM6tIG.mjs';
2
+ import { P as ProviderRegistry, W as WalletAdapter, S as StorageAdapter, a as StreamingCallbacks } from '../interfaces-Bp0Ngmqv.mjs';
3
+ import { S as SdkStore, U as UsageTrackingDriver } from '../store-CBSyK2qg.mjs';
4
4
  import { CashuSpender, BalanceManager } from '../wallet/index.mjs';
5
5
  import { Transform } from 'stream';
6
6
  import 'zustand/vanilla';
7
- import '../interfaces-BWJJTCXO.mjs';
7
+ import '../interfaces-Cxi8R4TT.mjs';
8
8
 
9
9
  /**
10
10
  * ProviderManager - Handles provider selection and failover logic
@@ -38,7 +38,8 @@ declare class ProviderManager {
38
38
  private store;
39
39
  /** Instance ID for debugging */
40
40
  private readonly instanceId;
41
- constructor(providerRegistry: ProviderRegistry, store?: SdkStore);
41
+ private readonly logger;
42
+ constructor(providerRegistry: ProviderRegistry, store?: SdkStore, logger?: SdkLogger);
42
43
  /**
43
44
  * Hydrate in-memory state from persistent store
44
45
  */
@@ -195,6 +196,8 @@ interface RoutstrClientConfig {
195
196
  sdkStore?: SdkStore;
196
197
  /** Optional: shared ProviderManager instance for consistent failure tracking across requests */
197
198
  providerManager?: ProviderManager;
199
+ /** Optional: injectable logger (defaults to consoleLogger) */
200
+ logger?: SdkLogger;
198
201
  }
199
202
  declare class RoutstrClient {
200
203
  private walletAdapter;
@@ -209,6 +212,7 @@ declare class RoutstrClient {
209
212
  private debugLevel;
210
213
  private usageTrackingDriver?;
211
214
  private sdkStore?;
215
+ private logger;
212
216
  constructor(walletAdapter: WalletAdapter, storageAdapter: StorageAdapter, providerRegistry: ProviderRegistry, alertLevel: AlertLevel, mode?: RoutstrClientMode, options?: RoutstrClientConfig);
213
217
  /**
214
218
  * Get the current client mode
@@ -1,10 +1,10 @@
1
- import { M as Model, a as Message, T as TransactionHistory, l as StreamingResult } from '../types-BYj_8c5c.js';
2
- import { P as ProviderRegistry, W as WalletAdapter, S as StorageAdapter, a as StreamingCallbacks } from '../interfaces-B62Rw-dd.js';
3
- import { S as SdkStore, U as UsageTrackingDriver } from '../store-h7m23ffq.js';
1
+ import { M as Model, S as SdkLogger, a as Message, T as TransactionHistory, m as StreamingResult } from '../types-DPQM6tIG.js';
2
+ import { P as ProviderRegistry, W as WalletAdapter, S as StorageAdapter, a as StreamingCallbacks } from '../interfaces-D2FDCLyP.js';
3
+ import { S as SdkStore, U as UsageTrackingDriver } from '../store-BD5zF9Hp.js';
4
4
  import { CashuSpender, BalanceManager } from '../wallet/index.js';
5
5
  import { Transform } from 'stream';
6
6
  import 'zustand/vanilla';
7
- import '../interfaces-BxDEka72.js';
7
+ import '../interfaces-CIfd_phZ.js';
8
8
 
9
9
  /**
10
10
  * ProviderManager - Handles provider selection and failover logic
@@ -38,7 +38,8 @@ declare class ProviderManager {
38
38
  private store;
39
39
  /** Instance ID for debugging */
40
40
  private readonly instanceId;
41
- constructor(providerRegistry: ProviderRegistry, store?: SdkStore);
41
+ private readonly logger;
42
+ constructor(providerRegistry: ProviderRegistry, store?: SdkStore, logger?: SdkLogger);
42
43
  /**
43
44
  * Hydrate in-memory state from persistent store
44
45
  */
@@ -195,6 +196,8 @@ interface RoutstrClientConfig {
195
196
  sdkStore?: SdkStore;
196
197
  /** Optional: shared ProviderManager instance for consistent failure tracking across requests */
197
198
  providerManager?: ProviderManager;
199
+ /** Optional: injectable logger (defaults to consoleLogger) */
200
+ logger?: SdkLogger;
198
201
  }
199
202
  declare class RoutstrClient {
200
203
  private walletAdapter;
@@ -209,6 +212,7 @@ declare class RoutstrClient {
209
212
  private debugLevel;
210
213
  private usageTrackingDriver?;
211
214
  private sdkStore?;
215
+ private logger;
212
216
  constructor(walletAdapter: WalletAdapter, storageAdapter: StorageAdapter, providerRegistry: ProviderRegistry, alertLevel: AlertLevel, mode?: RoutstrClientMode, options?: RoutstrClientConfig);
213
217
  /**
214
218
  * Get the current client mode
@@ -5,6 +5,19 @@ var vanilla = require('zustand/vanilla');
5
5
  var stream = require('stream');
6
6
  var string_decoder = require('string_decoder');
7
7
 
8
+ // core/types.ts
9
+ function makeConsoleLogger(prefix) {
10
+ const fmt = (args) => prefix ? [prefix, ...args] : args;
11
+ return {
12
+ log: (...args) => console.log(...fmt(args)),
13
+ warn: (...args) => console.warn(...fmt(args)),
14
+ error: (...args) => console.error(...fmt(args)),
15
+ debug: (...args) => console.log(...fmt(args)),
16
+ child: (p) => makeConsoleLogger(prefix ? `${prefix}:${p}` : p)
17
+ };
18
+ }
19
+ var consoleLogger = makeConsoleLogger();
20
+
8
21
  // core/errors.ts
9
22
  var InsufficientBalanceError = class extends Error {
10
23
  constructor(required, available, maxMintBalance = 0, maxMintUrl = "", customMessage) {
@@ -104,14 +117,16 @@ function selectMintWithBalance(balances, units, amount, excludeMints = []) {
104
117
  return { selectedMintUrl: null, selectedMintBalance: 0 };
105
118
  }
106
119
  var CashuSpender = class {
107
- constructor(walletAdapter, storageAdapter, _providerRegistry, balanceManager) {
120
+ constructor(walletAdapter, storageAdapter, _providerRegistry, balanceManager, logger) {
108
121
  this.walletAdapter = walletAdapter;
109
122
  this.storageAdapter = storageAdapter;
110
123
  this._providerRegistry = _providerRegistry;
111
124
  this.balanceManager = balanceManager;
125
+ this.logger = (logger ?? consoleLogger).child("CashuSpender");
112
126
  }
113
127
  _isBusy = false;
114
128
  debugLevel = "WARN";
129
+ logger;
115
130
  async receiveToken(token) {
116
131
  try {
117
132
  const result = await this.walletAdapter.receiveToken(token);
@@ -207,13 +222,13 @@ var CashuSpender = class {
207
222
  if (levelPriority[level] >= levelPriority[this.debugLevel]) {
208
223
  switch (level) {
209
224
  case "DEBUG":
210
- console.log(...args);
225
+ this.logger.log(...args);
211
226
  break;
212
227
  case "WARN":
213
- console.warn(...args);
228
+ this.logger.warn(...args);
214
229
  break;
215
230
  case "ERROR":
216
- console.error(...args);
231
+ this.logger.error(...args);
217
232
  break;
218
233
  }
219
234
  }
@@ -561,19 +576,50 @@ var CashuSpender = class {
561
576
  apiKeyEntry.baseUrl
562
577
  );
563
578
  if (apiKeyEntryFull && this.balanceManager) {
579
+ try {
580
+ const balanceResult = await this.balanceManager.getTokenBalance(
581
+ apiKeyEntryFull.key,
582
+ apiKeyEntry.baseUrl
583
+ );
584
+ if (balanceResult.isInvalidApiKey) {
585
+ this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);
586
+ results.push({
587
+ baseUrl: apiKeyEntry.baseUrl,
588
+ success: true
589
+ });
590
+ continue;
591
+ }
592
+ if (balanceResult.amount >= 0) {
593
+ const balanceSat = balanceResult.unit === "msat" ? Math.floor(balanceResult.amount / 1e3) : balanceResult.amount;
594
+ this.storageAdapter.updateApiKeyBalance(
595
+ apiKeyEntry.baseUrl,
596
+ balanceSat
597
+ );
598
+ }
599
+ } catch {
600
+ }
601
+ const refreshedEntry = this.storageAdapter.getApiKey(
602
+ apiKeyEntry.baseUrl
603
+ );
604
+ if (!refreshedEntry) continue;
564
605
  const refundResult = await this.balanceManager.refundApiKey({
565
606
  mintUrl,
566
607
  baseUrl: apiKeyEntry.baseUrl,
567
- apiKey: apiKeyEntryFull.key,
608
+ apiKey: refreshedEntry.key,
568
609
  forceRefund
569
610
  });
570
611
  if (refundResult.success) {
571
612
  this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);
572
613
  } else {
573
- this.storageAdapter.updateApiKeyBalance(
574
- apiKeyEntry.baseUrl,
575
- apiKeyEntry.amount
614
+ const currentEntry = this.storageAdapter.getApiKey(
615
+ apiKeyEntry.baseUrl
576
616
  );
617
+ if (currentEntry) {
618
+ this.storageAdapter.updateApiKeyBalance(
619
+ apiKeyEntry.baseUrl,
620
+ currentEntry.balance
621
+ );
622
+ }
577
623
  }
578
624
  results.push({
579
625
  baseUrl: apiKeyEntry.baseUrl,
@@ -640,10 +686,11 @@ var CashuSpender = class {
640
686
 
641
687
  // wallet/BalanceManager.ts
642
688
  var BalanceManager = class _BalanceManager {
643
- constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender) {
689
+ constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender, logger) {
644
690
  this.walletAdapter = walletAdapter;
645
691
  this.storageAdapter = storageAdapter;
646
692
  this.providerRegistry = providerRegistry;
693
+ this.logger = (logger ?? consoleLogger).child("BalanceManager");
647
694
  if (cashuSpender) {
648
695
  this.cashuSpender = cashuSpender;
649
696
  } else {
@@ -660,6 +707,7 @@ var BalanceManager = class _BalanceManager {
660
707
  providerWalletOps = /* @__PURE__ */ new Map();
661
708
  /** Cooldown (ms) between opposite operations on the same provider */
662
709
  static PROVIDER_WALLET_COOLDOWN_MS = 1e4;
710
+ logger;
663
711
  /**
664
712
  * Check whether a wallet operation (topup/refund) may run for a provider.
665
713
  * Returns the reason when blocked.
@@ -734,7 +782,7 @@ var BalanceManager = class _BalanceManager {
734
782
  const { mintUrl, baseUrl, apiKey, forceRefund } = options;
735
783
  const guard = this._canRunProviderWalletOperation(baseUrl, "refund");
736
784
  if (!guard.allowed) {
737
- console.log(`[BalanceManager] Skipping refund for ${baseUrl} - ${guard.reason}`);
785
+ this.logger.log(`Skipping refund for ${baseUrl} - ${guard.reason}`);
738
786
  return { success: false, message: guard.reason };
739
787
  }
740
788
  this._beginProviderWalletOperation(baseUrl, "refund");
@@ -754,9 +802,7 @@ var BalanceManager = class _BalanceManager {
754
802
  if (apiKeyEntry?.lastUsed) {
755
803
  const fiveMinutesAgo = Date.now() - 5 * 60 * 1e3;
756
804
  if (apiKeyEntry.lastUsed > fiveMinutesAgo) {
757
- console.log(
758
- `[BalanceManager] Skipping refund for ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1e3)}s ago`
759
- );
805
+ this.logger.log(`Skipping refund for ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1e3)}s ago`);
760
806
  return {
761
807
  success: false,
762
808
  message: "API key was used recently, skipping refund"
@@ -782,7 +828,8 @@ var BalanceManager = class _BalanceManager {
782
828
  };
783
829
  }
784
830
  if (fetchResult.error === "No balance to refund") {
785
- return { success: false, message: "No balance to refund" };
831
+ this.storageAdapter.removeApiKey(baseUrl);
832
+ return { success: true, message: "No balance to refund, key cleaned up" };
786
833
  }
787
834
  const receiveResult = await this.cashuSpender.receiveToken(
788
835
  fetchResult.token
@@ -798,7 +845,7 @@ var BalanceManager = class _BalanceManager {
798
845
  requestId: fetchResult.requestId
799
846
  };
800
847
  } catch (error) {
801
- console.error("[BalanceManager] API key refund error", error);
848
+ this.logger.error("API key refund error", error);
802
849
  return this._handleRefundError(error, mintUrl, fetchResult?.requestId);
803
850
  }
804
851
  }
@@ -850,7 +897,7 @@ var BalanceManager = class _BalanceManager {
850
897
  };
851
898
  } catch (error) {
852
899
  clearTimeout(timeoutId);
853
- console.error("[BalanceManager.fetchRefundToken] Fetch error", error);
900
+ this.logger.error("fetchRefundToken fetch error", error);
854
901
  if (error instanceof Error) {
855
902
  if (error.name === "AbortError") {
856
903
  return {
@@ -876,7 +923,7 @@ var BalanceManager = class _BalanceManager {
876
923
  const { mintUrl, baseUrl, amount, token: providedToken } = options;
877
924
  const guard = this._canRunProviderWalletOperation(baseUrl, "topup");
878
925
  if (!guard.allowed) {
879
- console.log(`[BalanceManager] Skipping topup for ${baseUrl} - ${guard.reason}`);
926
+ this.logger.log(`Skipping topup for ${baseUrl} - ${guard.reason}`);
880
927
  return { success: false, message: guard.reason };
881
928
  }
882
929
  this._beginProviderWalletOperation(baseUrl, "topup");
@@ -913,7 +960,7 @@ var BalanceManager = class _BalanceManager {
913
960
  cashuToken = tokenResult.token;
914
961
  const topUpResult = await this._postTopUp(baseUrl, apiKey, cashuToken);
915
962
  requestId = topUpResult.requestId;
916
- console.log(topUpResult);
963
+ this.logger.log("topUpResult:", topUpResult);
917
964
  if (!topUpResult.success) {
918
965
  await this._recoverFailedTopUp(cashuToken);
919
966
  return {
@@ -929,10 +976,7 @@ var BalanceManager = class _BalanceManager {
929
976
  requestId
930
977
  };
931
978
  } catch (error) {
932
- console.log(
933
- "DEBUG",
934
- `[TopuPU] topup: Topup result for ${baseUrl}: error=${error}`
935
- );
979
+ this.logger.log(`topup error for ${baseUrl}: ${error}`);
936
980
  if (cashuToken) {
937
981
  await this._recoverFailedTopUp(cashuToken);
938
982
  }
@@ -949,13 +993,9 @@ var BalanceManager = class _BalanceManager {
949
993
  p2pkPubkey
950
994
  } = options;
951
995
  const adjustedAmount = Math.ceil(amount);
952
- console.log(
953
- `[BalanceManager.createProviderToken] Starting: baseUrl=${baseUrl}, mintUrl=${mintUrl}, amount=${amount}, adjustedAmount=${adjustedAmount}, retryCount=${retryCount}`
954
- );
996
+ this.logger.log(`createProviderToken: baseUrl=${baseUrl} mintUrl=${mintUrl} amount=${amount} adjustedAmount=${adjustedAmount} retryCount=${retryCount}`);
955
997
  if (!adjustedAmount || isNaN(adjustedAmount)) {
956
- console.error(
957
- `[BalanceManager.createProviderToken] FAILURE: Invalid amount - amount=${amount}, adjustedAmount=${adjustedAmount}`
958
- );
998
+ this.logger.error(`createProviderToken: invalid amount=${amount}`);
959
999
  return { success: false, error: "Invalid top up amount" };
960
1000
  }
961
1001
  const balanceState = await this.getBalanceState();
@@ -986,9 +1026,7 @@ var BalanceManager = class _BalanceManager {
986
1026
  { url: "", balance: 0 }
987
1027
  ).url
988
1028
  );
989
- console.error(
990
- `[BalanceManager.createProviderToken] FAILURE: Insufficient balance - required=${adjustedAmount}, available=${totalMintBalance + targetProviderBalance}, totalMintBalance=${totalMintBalance}, targetProviderBalance=${targetProviderBalance}, refundableProviderBalance=${refundableProviderBalance}`
991
- );
1029
+ this.logger.error(`createProviderToken: insufficient balance required=${adjustedAmount} available=${totalMintBalance + targetProviderBalance} totalMint=${totalMintBalance} targetProvider=${targetProviderBalance}`);
992
1030
  return { success: false, error: error.message };
993
1031
  }
994
1032
  const providerMints = baseUrl && this.providerRegistry ? this.providerRegistry.getProviderMints(baseUrl) : [];
@@ -1024,9 +1062,7 @@ var BalanceManager = class _BalanceManager {
1024
1062
  maxMintUrl = mintUrl2;
1025
1063
  }
1026
1064
  }
1027
- console.error(
1028
- `[BalanceManager.createProviderToken] FAILURE: No candidate mints found - requiredAmount=${requiredAmount}, totalMintBalance=${totalMintBalance}, maxBalance=${maxBalance}, maxMintUrl=${maxMintUrl}, providerMints=${JSON.stringify(providerMints)}`
1029
- );
1065
+ this.logger.error(`createProviderToken: no candidate mints required=${requiredAmount} totalMint=${totalMintBalance} maxBalance=${maxBalance} maxMint=${maxMintUrl}`);
1030
1066
  const error = new InsufficientBalanceError(
1031
1067
  adjustedAmount,
1032
1068
  totalMintBalance,
@@ -1038,17 +1074,13 @@ var BalanceManager = class _BalanceManager {
1038
1074
  let lastError;
1039
1075
  for (const candidateMint of candidates) {
1040
1076
  try {
1041
- console.log(
1042
- `[BalanceManager.createProviderToken] Attempting mint: ${candidateMint}, amount: ${requiredAmount}`
1043
- );
1077
+ this.logger.log(`createProviderToken: attempting mint=${candidateMint} amount=${requiredAmount}`);
1044
1078
  const token = await this.walletAdapter.sendToken(
1045
1079
  candidateMint,
1046
1080
  requiredAmount,
1047
1081
  p2pkPubkey
1048
1082
  );
1049
- console.log(
1050
- `[BalanceManager.createProviderToken] SUCCESS: Token created from mint ${candidateMint}, all mint balances: ${JSON.stringify(Object.fromEntries(Object.entries(balances).map(([mint, balance]) => [mint, getBalanceInSats(balance, units[mint])])))}`
1051
- );
1083
+ this.logger.log(`createProviderToken: success from mint=${candidateMint}`);
1052
1084
  return {
1053
1085
  success: true,
1054
1086
  token,
@@ -1057,15 +1089,11 @@ var BalanceManager = class _BalanceManager {
1057
1089
  };
1058
1090
  } catch (error) {
1059
1091
  const errorMsg = error instanceof Error ? error.message : String(error);
1060
- console.error(
1061
- `[BalanceManager.createProviderToken] FAILURE: Mint ${candidateMint} failed with error: ${errorMsg}`
1062
- );
1092
+ this.logger.error(`createProviderToken: mint=${candidateMint} failed: ${errorMsg}`);
1063
1093
  if (error instanceof Error) {
1064
1094
  lastError = errorMsg;
1065
1095
  if (isNetworkErrorMessage(error.message)) {
1066
- console.warn(
1067
- `[BalanceManager.createProviderToken] Network error from ${candidateMint}, trying next mint...`
1068
- );
1096
+ this.logger.warn(`createProviderToken: network error from ${candidateMint}, trying next mint...`);
1069
1097
  continue;
1070
1098
  }
1071
1099
  }
@@ -1075,9 +1103,7 @@ var BalanceManager = class _BalanceManager {
1075
1103
  };
1076
1104
  }
1077
1105
  }
1078
- console.error(
1079
- `[BalanceManager.createProviderToken] FAILURE: All candidate mints exhausted - lastError=${lastError}, candidates=${JSON.stringify(candidates)}`
1080
- );
1106
+ this.logger.error(`createProviderToken: all candidate mints exhausted lastError=${lastError}`);
1081
1107
  return {
1082
1108
  success: false,
1083
1109
  error: lastError || "All candidate mints failed while creating top up token"
@@ -1192,7 +1218,7 @@ var BalanceManager = class _BalanceManager {
1192
1218
  return { success: true, requestId };
1193
1219
  } catch (error) {
1194
1220
  clearTimeout(timeoutId);
1195
- console.error("[BalanceManager._postTopUp] Fetch error", error);
1221
+ this.logger.error("_postTopUp fetch error", error);
1196
1222
  if (error instanceof Error) {
1197
1223
  if (error.name === "AbortError") {
1198
1224
  return {
@@ -1218,10 +1244,7 @@ var BalanceManager = class _BalanceManager {
1218
1244
  try {
1219
1245
  await this.cashuSpender.receiveToken(cashuToken);
1220
1246
  } catch (error) {
1221
- console.error(
1222
- "[BalanceManager._recoverFailedTopUp] Failed to recover token",
1223
- error
1224
- );
1247
+ this.logger.error("_recoverFailedTopUp: failed to recover token", error);
1225
1248
  }
1226
1249
  }
1227
1250
  /**
@@ -1274,9 +1297,9 @@ var BalanceManager = class _BalanceManager {
1274
1297
  apiKey: data.api_key
1275
1298
  };
1276
1299
  } else {
1277
- console.log(response.status);
1300
+ this.logger.warn(`getTokenBalance: status=${response.status}`);
1278
1301
  const data = await response.json();
1279
- console.log("FAILED ", data);
1302
+ this.logger.warn("getTokenBalance: FAILED", data);
1280
1303
  const isInvalidApiKey = response.status === 401 && data?.detail?.error?.code === "invalid_api_key" && data?.detail?.error?.message?.includes("proofs already spent");
1281
1304
  return {
1282
1305
  amount: -1,
@@ -1287,7 +1310,7 @@ var BalanceManager = class _BalanceManager {
1287
1310
  };
1288
1311
  }
1289
1312
  } catch (error) {
1290
- console.error("ERRORR IN RESTPONSE", error);
1313
+ this.logger.error("getTokenBalance error", error);
1291
1314
  }
1292
1315
  return { amount: -1, reserved: 0, unit: "sat", apiKey: "" };
1293
1316
  }
@@ -1753,9 +1776,10 @@ function isInsecureHttpUrl(url) {
1753
1776
  return url.startsWith("http://");
1754
1777
  }
1755
1778
  var ProviderManager = class _ProviderManager {
1756
- constructor(providerRegistry, store) {
1779
+ constructor(providerRegistry, store, logger) {
1757
1780
  this.providerRegistry = providerRegistry;
1758
1781
  this.instanceId = `pm_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
1782
+ this.logger = (logger ?? consoleLogger).child(`ProviderManager:${this.instanceId}`);
1759
1783
  if (store) {
1760
1784
  this.store = store;
1761
1785
  this.hydrateFromStore();
@@ -1772,6 +1796,7 @@ var ProviderManager = class _ProviderManager {
1772
1796
  store = null;
1773
1797
  /** Instance ID for debugging */
1774
1798
  instanceId;
1799
+ logger;
1775
1800
  /**
1776
1801
  * Hydrate in-memory state from persistent store
1777
1802
  */
@@ -1784,10 +1809,7 @@ var ProviderManager = class _ProviderManager {
1784
1809
  this.providersOnCoolDown = state.providersOnCooldown.filter(
1785
1810
  (entry) => now - entry.timestamp < _ProviderManager.COOLDOWN_DURATION_MS
1786
1811
  ).map((entry) => [entry.baseUrl, entry.timestamp]);
1787
- console.log(`[ProviderManager:${this.instanceId}] Hydrated from store:`);
1788
- console.log(` failedProviders: ${this.failedProviders.size}`);
1789
- console.log(` lastFailed: ${this.lastFailed.size}`);
1790
- console.log(` providersOnCooldown: ${this.providersOnCoolDown.length}`);
1812
+ this.logger.log(`Hydrated from store: failedProviders=${this.failedProviders.size} lastFailed=${this.lastFailed.size} providersOnCooldown=${this.providersOnCoolDown.length}`);
1791
1813
  }
1792
1814
  /**
1793
1815
  * Get instance ID for debugging
@@ -1807,9 +1829,7 @@ var ProviderManager = class _ProviderManager {
1807
1829
  const age = now - timestamp;
1808
1830
  const isExpired = age >= _ProviderManager.COOLDOWN_DURATION_MS;
1809
1831
  if (isExpired) {
1810
- console.log(
1811
- `[cleanupExpiredCooldowns:${this.instanceId}] Removing expired cooldown for ${url} (age: ${age}ms, cooldown: ${_ProviderManager.COOLDOWN_DURATION_MS}ms)`
1812
- );
1832
+ this.logger.log(`Removing expired cooldown for ${url} (age: ${age}ms)`);
1813
1833
  this.failedProviders.delete(url);
1814
1834
  if (this.store) {
1815
1835
  this.store.getState().removeFailedProvider(url);
@@ -1820,9 +1840,7 @@ var ProviderManager = class _ProviderManager {
1820
1840
  );
1821
1841
  const after = this.providersOnCoolDown.length;
1822
1842
  if (before !== after) {
1823
- console.log(
1824
- `[cleanupExpiredCooldowns:${this.instanceId}] Cleaned up ${before - after} expired cooldown(s), ${after} remaining`
1825
- );
1843
+ this.logger.log(`Cleaned up ${before - after} expired cooldown(s), ${after} remaining`);
1826
1844
  }
1827
1845
  }
1828
1846
  /**
@@ -1874,24 +1892,10 @@ var ProviderManager = class _ProviderManager {
1874
1892
  markFailed(baseUrl) {
1875
1893
  const now = Date.now();
1876
1894
  const lastFailure = this.lastFailed.get(baseUrl);
1877
- console.log(`[markFailed:${this.instanceId}] baseUrl: ${baseUrl}`);
1878
- console.log(
1879
- `[markFailed:${this.instanceId}] lastFailure from map: ${lastFailure}`
1880
- );
1881
- console.log(
1882
- `[markFailed:${this.instanceId}] current timestamp (now): ${now}`
1883
- );
1884
- console.log(
1885
- `[markFailed:${this.instanceId}] COOLDOWN_DURATION_MS: ${_ProviderManager.COOLDOWN_DURATION_MS}`
1886
- );
1895
+ this.logger.log(`markFailed: ${baseUrl} lastFailure=${lastFailure} now=${now}`);
1887
1896
  if (lastFailure !== void 0) {
1888
1897
  const timeSinceLastFailure = now - lastFailure;
1889
- console.log(
1890
- `[markFailed:${this.instanceId}] timeSinceLastFailure: ${timeSinceLastFailure}ms`
1891
- );
1892
- console.log(
1893
- `[markFailed:${this.instanceId}] isWithinCooldownWindow: ${timeSinceLastFailure < _ProviderManager.COOLDOWN_DURATION_MS}`
1894
- );
1898
+ this.logger.log(`markFailed: timeSinceLastFailure=${timeSinceLastFailure}ms withinCooldown=${timeSinceLastFailure < _ProviderManager.COOLDOWN_DURATION_MS}`);
1895
1899
  }
1896
1900
  this.lastFailed.set(baseUrl, now);
1897
1901
  this.failedProviders.add(baseUrl);
@@ -1899,38 +1903,23 @@ var ProviderManager = class _ProviderManager {
1899
1903
  this.store.getState().setLastFailedTimestamp(baseUrl, now);
1900
1904
  this.store.getState().addFailedProvider(baseUrl);
1901
1905
  }
1902
- console.log(
1903
- `[markFailed:${this.instanceId}] Updated lastFailed map for ${baseUrl} to ${now}`
1904
- );
1905
- console.log(
1906
- `[markFailed:${this.instanceId}] failedProviders set size: ${this.failedProviders.size}`
1907
- );
1906
+ this.logger.log(`markFailed: updated ${baseUrl} to ${now}, failedProviders=${this.failedProviders.size}`);
1908
1907
  if (lastFailure !== void 0 && now - lastFailure < _ProviderManager.COOLDOWN_DURATION_MS) {
1909
- console.log(
1910
- `[markFailed:${this.instanceId}] Second failure detected within cooldown window for ${baseUrl}`
1911
- );
1908
+ this.logger.log(`markFailed: second failure within cooldown window for ${baseUrl}`);
1912
1909
  if (!this.isOnCooldown(baseUrl)) {
1913
1910
  this.providersOnCoolDown.push([baseUrl, now]);
1914
1911
  if (this.store) {
1915
1912
  this.store.getState().addProviderOnCooldown(baseUrl, now);
1916
1913
  }
1917
- console.log(
1918
- `[markFailed:${this.instanceId}] Provider ${baseUrl} added to cooldown after second failure within 5 minutes`
1919
- );
1914
+ this.logger.log(`markFailed: ${baseUrl} added to cooldown`);
1920
1915
  } else {
1921
- console.log(
1922
- `[markFailed:${this.instanceId}] Provider ${baseUrl} is already on cooldown`
1923
- );
1916
+ this.logger.log(`markFailed: ${baseUrl} already on cooldown`);
1924
1917
  }
1925
1918
  } else {
1926
1919
  if (lastFailure === void 0) {
1927
- console.log(
1928
- `[markFailed:${this.instanceId}] First failure for ${baseUrl} - not adding to cooldown yet`
1929
- );
1920
+ this.logger.log(`markFailed: first failure for ${baseUrl}`);
1930
1921
  } else {
1931
- console.log(
1932
- `[markFailed:${this.instanceId}] Failure outside cooldown window for ${baseUrl} (timeSinceLastFailure: ${now - lastFailure}ms)`
1933
- );
1922
+ this.logger.log(`markFailed: failure outside cooldown window for ${baseUrl} (${now - lastFailure}ms ago)`);
1934
1923
  }
1935
1924
  }
1936
1925
  }
@@ -1987,25 +1976,12 @@ var ProviderManager = class _ProviderManager {
1987
1976
  const disabledProviders = new Set(
1988
1977
  this.providerRegistry.getDisabledProviders()
1989
1978
  );
1990
- console.log(
1991
- `[findNextBestProvider:${this.instanceId}] Starting search for model: ${modelId}`
1992
- );
1993
- console.log(
1994
- `[findNextBestProvider:${this.instanceId}] disabledProviders: ${[...disabledProviders]}`
1995
- );
1996
- console.log(
1997
- `[findNextBestProvider:${this.instanceId}] providersOnCooldown: ${this.providersOnCoolDown.map(([url]) => url)}`
1998
- );
1979
+ this.logger.log(`findNextBestProvider: model=${modelId} disabled=${[...disabledProviders].length} onCooldown=${this.providersOnCoolDown.length}`);
1999
1980
  const allProviders = this.providerRegistry.getAllProvidersModels();
2000
- console.log(
2001
- `[findNextBestProvider:${this.instanceId}] Total providers in registry: ${Object.keys(allProviders).length}`
2002
- );
1981
+ this.logger.log(`findNextBestProvider: total providers=${Object.keys(allProviders).length}`);
2003
1982
  const candidates = [];
2004
1983
  for (const [baseUrl, models] of Object.entries(allProviders)) {
2005
1984
  if (baseUrl === currentBaseUrl) {
2006
- console.log(
2007
- `[findNextBestProvider:${this.instanceId}] SKIP (current): ${baseUrl}`
2008
- );
2009
1985
  continue;
2010
1986
  }
2011
1987
  if (disabledProviders.has(baseUrl)) {
@@ -2031,7 +2007,7 @@ var ProviderManager = class _ProviderManager {
2031
2007
  return null;
2032
2008
  }
2033
2009
  } catch (error) {
2034
- console.error("Error finding next best provider:", error);
2010
+ this.logger.error("findNextBestProvider error:", error);
2035
2011
  return null;
2036
2012
  }
2037
2013
  }
@@ -2158,16 +2134,9 @@ var ProviderManager = class _ProviderManager {
2158
2134
  res.height
2159
2135
  );
2160
2136
  imageTokens += tokensFromImage;
2161
- console.log("IMAGE INPUT RESOLUTION", {
2162
- width: res.width,
2163
- height: res.height,
2164
- tokensFromImage
2165
- });
2137
+ this.logger.log(`IMAGE INPUT RESOLUTION width=${res.width} height=${res.height} tokens=${tokensFromImage}`);
2166
2138
  } else {
2167
- console.log(
2168
- "IMAGE INPUT RESOLUTION",
2169
- "unknown (unsupported format or parse failure)"
2170
- );
2139
+ this.logger.log("IMAGE INPUT RESOLUTION: unknown format");
2171
2140
  }
2172
2141
  }
2173
2142
  }
@@ -2200,7 +2169,7 @@ var ProviderManager = class _ProviderManager {
2200
2169
  const totalEstimatedCosts = (promptCosts + completionCost) * 1.05;
2201
2170
  return totalEstimatedCosts;
2202
2171
  } catch (e) {
2203
- console.error(e);
2172
+ this.logger.error("getRequiredSatsForModel error:", e);
2204
2173
  return 0;
2205
2174
  }
2206
2175
  }
@@ -3697,6 +3666,7 @@ var RoutstrClient = class {
3697
3666
  this.walletAdapter = walletAdapter;
3698
3667
  this.storageAdapter = storageAdapter;
3699
3668
  this.providerRegistry = providerRegistry;
3669
+ this.logger = (options.logger ?? consoleLogger).child("RoutstrClient");
3700
3670
  this.balanceManager = new BalanceManager(
3701
3671
  walletAdapter,
3702
3672
  storageAdapter,
@@ -3713,7 +3683,7 @@ var RoutstrClient = class {
3713
3683
  this.mode = mode;
3714
3684
  this.usageTrackingDriver = options.usageTrackingDriver;
3715
3685
  this.sdkStore = options.sdkStore;
3716
- this.providerManager = options.providerManager ?? new ProviderManager(providerRegistry, this.sdkStore);
3686
+ this.providerManager = options.providerManager ?? new ProviderManager(providerRegistry, this.sdkStore, this.logger);
3717
3687
  }
3718
3688
  cashuSpender;
3719
3689
  balanceManager;
@@ -3724,6 +3694,7 @@ var RoutstrClient = class {
3724
3694
  debugLevel = "WARN";
3725
3695
  usageTrackingDriver;
3726
3696
  sdkStore;
3697
+ logger;
3727
3698
  /**
3728
3699
  * Get the current client mode
3729
3700
  */
@@ -3745,13 +3716,13 @@ var RoutstrClient = class {
3745
3716
  if (levelPriority[level] >= levelPriority[this.debugLevel]) {
3746
3717
  switch (level) {
3747
3718
  case "DEBUG":
3748
- console.log(...args);
3719
+ this.logger.log(...args);
3749
3720
  break;
3750
3721
  case "WARN":
3751
- console.warn(...args);
3722
+ this.logger.warn(...args);
3752
3723
  break;
3753
3724
  case "ERROR":
3754
- console.error(...args);
3725
+ this.logger.error(...args);
3755
3726
  break;
3756
3727
  }
3757
3728
  }
@@ -4355,7 +4326,7 @@ var RoutstrClient = class {
4355
4326
  tryNextProvider = true;
4356
4327
  }
4357
4328
  }
4358
- if ((status === 401 || status === 403 || status === 413 || status === 400 || status === 429 || status === 500 || status === 502 || status === 503 || status === 504 || status === 521) && !tryNextProvider) {
4329
+ if ((status === 401 || status === 403 || status === 404 || status === 413 || status === 400 || status === 429 || status === 500 || status === 502 || status === 503 || status === 504 || status === 521) && !tryNextProvider) {
4359
4330
  this._log(
4360
4331
  "DEBUG",
4361
4332
  `[RoutstrClient] _handleErrorResponse: Status ${status} (${status === 429 ? "rate limited" : "auth/server error"}), attempting refund for ${baseUrl}, mode=${this.mode}`