@routstr/sdk 0.3.2 → 0.3.4

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 +70 -131
  4. package/dist/client/index.js.map +1 -1
  5. package/dist/client/index.mjs +70 -131
  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 +141 -185
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.mjs +140 -186
  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 +51 -34
  26. package/dist/storage/index.js.map +1 -1
  27. package/dist/storage/index.mjs +51 -34
  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 +43 -52
  36. package/dist/wallet/index.js.map +1 -1
  37. package/dist/wallet/index.mjs +43 -52
  38. package/dist/wallet/index.mjs.map +1 -1
  39. package/package.json +3 -2
@@ -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
  }
@@ -640,10 +655,11 @@ var CashuSpender = class {
640
655
 
641
656
  // wallet/BalanceManager.ts
642
657
  var BalanceManager = class _BalanceManager {
643
- constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender) {
658
+ constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender, logger) {
644
659
  this.walletAdapter = walletAdapter;
645
660
  this.storageAdapter = storageAdapter;
646
661
  this.providerRegistry = providerRegistry;
662
+ this.logger = (logger ?? consoleLogger).child("BalanceManager");
647
663
  if (cashuSpender) {
648
664
  this.cashuSpender = cashuSpender;
649
665
  } else {
@@ -660,6 +676,7 @@ var BalanceManager = class _BalanceManager {
660
676
  providerWalletOps = /* @__PURE__ */ new Map();
661
677
  /** Cooldown (ms) between opposite operations on the same provider */
662
678
  static PROVIDER_WALLET_COOLDOWN_MS = 1e4;
679
+ logger;
663
680
  /**
664
681
  * Check whether a wallet operation (topup/refund) may run for a provider.
665
682
  * Returns the reason when blocked.
@@ -734,7 +751,7 @@ var BalanceManager = class _BalanceManager {
734
751
  const { mintUrl, baseUrl, apiKey, forceRefund } = options;
735
752
  const guard = this._canRunProviderWalletOperation(baseUrl, "refund");
736
753
  if (!guard.allowed) {
737
- console.log(`[BalanceManager] Skipping refund for ${baseUrl} - ${guard.reason}`);
754
+ this.logger.log(`Skipping refund for ${baseUrl} - ${guard.reason}`);
738
755
  return { success: false, message: guard.reason };
739
756
  }
740
757
  this._beginProviderWalletOperation(baseUrl, "refund");
@@ -754,9 +771,7 @@ var BalanceManager = class _BalanceManager {
754
771
  if (apiKeyEntry?.lastUsed) {
755
772
  const fiveMinutesAgo = Date.now() - 5 * 60 * 1e3;
756
773
  if (apiKeyEntry.lastUsed > fiveMinutesAgo) {
757
- console.log(
758
- `[BalanceManager] Skipping refund for ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1e3)}s ago`
759
- );
774
+ this.logger.log(`Skipping refund for ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1e3)}s ago`);
760
775
  return {
761
776
  success: false,
762
777
  message: "API key was used recently, skipping refund"
@@ -798,7 +813,7 @@ var BalanceManager = class _BalanceManager {
798
813
  requestId: fetchResult.requestId
799
814
  };
800
815
  } catch (error) {
801
- console.error("[BalanceManager] API key refund error", error);
816
+ this.logger.error("API key refund error", error);
802
817
  return this._handleRefundError(error, mintUrl, fetchResult?.requestId);
803
818
  }
804
819
  }
@@ -850,7 +865,7 @@ var BalanceManager = class _BalanceManager {
850
865
  };
851
866
  } catch (error) {
852
867
  clearTimeout(timeoutId);
853
- console.error("[BalanceManager.fetchRefundToken] Fetch error", error);
868
+ this.logger.error("fetchRefundToken fetch error", error);
854
869
  if (error instanceof Error) {
855
870
  if (error.name === "AbortError") {
856
871
  return {
@@ -876,7 +891,7 @@ var BalanceManager = class _BalanceManager {
876
891
  const { mintUrl, baseUrl, amount, token: providedToken } = options;
877
892
  const guard = this._canRunProviderWalletOperation(baseUrl, "topup");
878
893
  if (!guard.allowed) {
879
- console.log(`[BalanceManager] Skipping topup for ${baseUrl} - ${guard.reason}`);
894
+ this.logger.log(`Skipping topup for ${baseUrl} - ${guard.reason}`);
880
895
  return { success: false, message: guard.reason };
881
896
  }
882
897
  this._beginProviderWalletOperation(baseUrl, "topup");
@@ -913,7 +928,7 @@ var BalanceManager = class _BalanceManager {
913
928
  cashuToken = tokenResult.token;
914
929
  const topUpResult = await this._postTopUp(baseUrl, apiKey, cashuToken);
915
930
  requestId = topUpResult.requestId;
916
- console.log(topUpResult);
931
+ this.logger.log("topUpResult:", topUpResult);
917
932
  if (!topUpResult.success) {
918
933
  await this._recoverFailedTopUp(cashuToken);
919
934
  return {
@@ -929,10 +944,7 @@ var BalanceManager = class _BalanceManager {
929
944
  requestId
930
945
  };
931
946
  } catch (error) {
932
- console.log(
933
- "DEBUG",
934
- `[TopuPU] topup: Topup result for ${baseUrl}: error=${error}`
935
- );
947
+ this.logger.log(`topup error for ${baseUrl}: ${error}`);
936
948
  if (cashuToken) {
937
949
  await this._recoverFailedTopUp(cashuToken);
938
950
  }
@@ -949,13 +961,9 @@ var BalanceManager = class _BalanceManager {
949
961
  p2pkPubkey
950
962
  } = options;
951
963
  const adjustedAmount = Math.ceil(amount);
952
- console.log(
953
- `[BalanceManager.createProviderToken] Starting: baseUrl=${baseUrl}, mintUrl=${mintUrl}, amount=${amount}, adjustedAmount=${adjustedAmount}, retryCount=${retryCount}`
954
- );
964
+ this.logger.log(`createProviderToken: baseUrl=${baseUrl} mintUrl=${mintUrl} amount=${amount} adjustedAmount=${adjustedAmount} retryCount=${retryCount}`);
955
965
  if (!adjustedAmount || isNaN(adjustedAmount)) {
956
- console.error(
957
- `[BalanceManager.createProviderToken] FAILURE: Invalid amount - amount=${amount}, adjustedAmount=${adjustedAmount}`
958
- );
966
+ this.logger.error(`createProviderToken: invalid amount=${amount}`);
959
967
  return { success: false, error: "Invalid top up amount" };
960
968
  }
961
969
  const balanceState = await this.getBalanceState();
@@ -986,9 +994,7 @@ var BalanceManager = class _BalanceManager {
986
994
  { url: "", balance: 0 }
987
995
  ).url
988
996
  );
989
- console.error(
990
- `[BalanceManager.createProviderToken] FAILURE: Insufficient balance - required=${adjustedAmount}, available=${totalMintBalance + targetProviderBalance}, totalMintBalance=${totalMintBalance}, targetProviderBalance=${targetProviderBalance}, refundableProviderBalance=${refundableProviderBalance}`
991
- );
997
+ this.logger.error(`createProviderToken: insufficient balance required=${adjustedAmount} available=${totalMintBalance + targetProviderBalance} totalMint=${totalMintBalance} targetProvider=${targetProviderBalance}`);
992
998
  return { success: false, error: error.message };
993
999
  }
994
1000
  const providerMints = baseUrl && this.providerRegistry ? this.providerRegistry.getProviderMints(baseUrl) : [];
@@ -1024,9 +1030,7 @@ var BalanceManager = class _BalanceManager {
1024
1030
  maxMintUrl = mintUrl2;
1025
1031
  }
1026
1032
  }
1027
- console.error(
1028
- `[BalanceManager.createProviderToken] FAILURE: No candidate mints found - requiredAmount=${requiredAmount}, totalMintBalance=${totalMintBalance}, maxBalance=${maxBalance}, maxMintUrl=${maxMintUrl}, providerMints=${JSON.stringify(providerMints)}`
1029
- );
1033
+ this.logger.error(`createProviderToken: no candidate mints required=${requiredAmount} totalMint=${totalMintBalance} maxBalance=${maxBalance} maxMint=${maxMintUrl}`);
1030
1034
  const error = new InsufficientBalanceError(
1031
1035
  adjustedAmount,
1032
1036
  totalMintBalance,
@@ -1038,17 +1042,13 @@ var BalanceManager = class _BalanceManager {
1038
1042
  let lastError;
1039
1043
  for (const candidateMint of candidates) {
1040
1044
  try {
1041
- console.log(
1042
- `[BalanceManager.createProviderToken] Attempting mint: ${candidateMint}, amount: ${requiredAmount}`
1043
- );
1045
+ this.logger.log(`createProviderToken: attempting mint=${candidateMint} amount=${requiredAmount}`);
1044
1046
  const token = await this.walletAdapter.sendToken(
1045
1047
  candidateMint,
1046
1048
  requiredAmount,
1047
1049
  p2pkPubkey
1048
1050
  );
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
- );
1051
+ this.logger.log(`createProviderToken: success from mint=${candidateMint}`);
1052
1052
  return {
1053
1053
  success: true,
1054
1054
  token,
@@ -1057,15 +1057,11 @@ var BalanceManager = class _BalanceManager {
1057
1057
  };
1058
1058
  } catch (error) {
1059
1059
  const errorMsg = error instanceof Error ? error.message : String(error);
1060
- console.error(
1061
- `[BalanceManager.createProviderToken] FAILURE: Mint ${candidateMint} failed with error: ${errorMsg}`
1062
- );
1060
+ this.logger.error(`createProviderToken: mint=${candidateMint} failed: ${errorMsg}`);
1063
1061
  if (error instanceof Error) {
1064
1062
  lastError = errorMsg;
1065
1063
  if (isNetworkErrorMessage(error.message)) {
1066
- console.warn(
1067
- `[BalanceManager.createProviderToken] Network error from ${candidateMint}, trying next mint...`
1068
- );
1064
+ this.logger.warn(`createProviderToken: network error from ${candidateMint}, trying next mint...`);
1069
1065
  continue;
1070
1066
  }
1071
1067
  }
@@ -1075,9 +1071,7 @@ var BalanceManager = class _BalanceManager {
1075
1071
  };
1076
1072
  }
1077
1073
  }
1078
- console.error(
1079
- `[BalanceManager.createProviderToken] FAILURE: All candidate mints exhausted - lastError=${lastError}, candidates=${JSON.stringify(candidates)}`
1080
- );
1074
+ this.logger.error(`createProviderToken: all candidate mints exhausted lastError=${lastError}`);
1081
1075
  return {
1082
1076
  success: false,
1083
1077
  error: lastError || "All candidate mints failed while creating top up token"
@@ -1192,7 +1186,7 @@ var BalanceManager = class _BalanceManager {
1192
1186
  return { success: true, requestId };
1193
1187
  } catch (error) {
1194
1188
  clearTimeout(timeoutId);
1195
- console.error("[BalanceManager._postTopUp] Fetch error", error);
1189
+ this.logger.error("_postTopUp fetch error", error);
1196
1190
  if (error instanceof Error) {
1197
1191
  if (error.name === "AbortError") {
1198
1192
  return {
@@ -1218,10 +1212,7 @@ var BalanceManager = class _BalanceManager {
1218
1212
  try {
1219
1213
  await this.cashuSpender.receiveToken(cashuToken);
1220
1214
  } catch (error) {
1221
- console.error(
1222
- "[BalanceManager._recoverFailedTopUp] Failed to recover token",
1223
- error
1224
- );
1215
+ this.logger.error("_recoverFailedTopUp: failed to recover token", error);
1225
1216
  }
1226
1217
  }
1227
1218
  /**
@@ -1274,9 +1265,9 @@ var BalanceManager = class _BalanceManager {
1274
1265
  apiKey: data.api_key
1275
1266
  };
1276
1267
  } else {
1277
- console.log(response.status);
1268
+ this.logger.warn(`getTokenBalance: status=${response.status}`);
1278
1269
  const data = await response.json();
1279
- console.log("FAILED ", data);
1270
+ this.logger.warn("getTokenBalance: FAILED", data);
1280
1271
  const isInvalidApiKey = response.status === 401 && data?.detail?.error?.code === "invalid_api_key" && data?.detail?.error?.message?.includes("proofs already spent");
1281
1272
  return {
1282
1273
  amount: -1,
@@ -1287,7 +1278,7 @@ var BalanceManager = class _BalanceManager {
1287
1278
  };
1288
1279
  }
1289
1280
  } catch (error) {
1290
- console.error("ERRORR IN RESTPONSE", error);
1281
+ this.logger.error("getTokenBalance error", error);
1291
1282
  }
1292
1283
  return { amount: -1, reserved: 0, unit: "sat", apiKey: "" };
1293
1284
  }
@@ -1753,9 +1744,10 @@ function isInsecureHttpUrl(url) {
1753
1744
  return url.startsWith("http://");
1754
1745
  }
1755
1746
  var ProviderManager = class _ProviderManager {
1756
- constructor(providerRegistry, store) {
1747
+ constructor(providerRegistry, store, logger) {
1757
1748
  this.providerRegistry = providerRegistry;
1758
1749
  this.instanceId = `pm_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
1750
+ this.logger = (logger ?? consoleLogger).child(`ProviderManager:${this.instanceId}`);
1759
1751
  if (store) {
1760
1752
  this.store = store;
1761
1753
  this.hydrateFromStore();
@@ -1772,6 +1764,7 @@ var ProviderManager = class _ProviderManager {
1772
1764
  store = null;
1773
1765
  /** Instance ID for debugging */
1774
1766
  instanceId;
1767
+ logger;
1775
1768
  /**
1776
1769
  * Hydrate in-memory state from persistent store
1777
1770
  */
@@ -1784,10 +1777,7 @@ var ProviderManager = class _ProviderManager {
1784
1777
  this.providersOnCoolDown = state.providersOnCooldown.filter(
1785
1778
  (entry) => now - entry.timestamp < _ProviderManager.COOLDOWN_DURATION_MS
1786
1779
  ).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}`);
1780
+ this.logger.log(`Hydrated from store: failedProviders=${this.failedProviders.size} lastFailed=${this.lastFailed.size} providersOnCooldown=${this.providersOnCoolDown.length}`);
1791
1781
  }
1792
1782
  /**
1793
1783
  * Get instance ID for debugging
@@ -1807,9 +1797,7 @@ var ProviderManager = class _ProviderManager {
1807
1797
  const age = now - timestamp;
1808
1798
  const isExpired = age >= _ProviderManager.COOLDOWN_DURATION_MS;
1809
1799
  if (isExpired) {
1810
- console.log(
1811
- `[cleanupExpiredCooldowns:${this.instanceId}] Removing expired cooldown for ${url} (age: ${age}ms, cooldown: ${_ProviderManager.COOLDOWN_DURATION_MS}ms)`
1812
- );
1800
+ this.logger.log(`Removing expired cooldown for ${url} (age: ${age}ms)`);
1813
1801
  this.failedProviders.delete(url);
1814
1802
  if (this.store) {
1815
1803
  this.store.getState().removeFailedProvider(url);
@@ -1820,9 +1808,7 @@ var ProviderManager = class _ProviderManager {
1820
1808
  );
1821
1809
  const after = this.providersOnCoolDown.length;
1822
1810
  if (before !== after) {
1823
- console.log(
1824
- `[cleanupExpiredCooldowns:${this.instanceId}] Cleaned up ${before - after} expired cooldown(s), ${after} remaining`
1825
- );
1811
+ this.logger.log(`Cleaned up ${before - after} expired cooldown(s), ${after} remaining`);
1826
1812
  }
1827
1813
  }
1828
1814
  /**
@@ -1874,24 +1860,10 @@ var ProviderManager = class _ProviderManager {
1874
1860
  markFailed(baseUrl) {
1875
1861
  const now = Date.now();
1876
1862
  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
- );
1863
+ this.logger.log(`markFailed: ${baseUrl} lastFailure=${lastFailure} now=${now}`);
1887
1864
  if (lastFailure !== void 0) {
1888
1865
  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
- );
1866
+ this.logger.log(`markFailed: timeSinceLastFailure=${timeSinceLastFailure}ms withinCooldown=${timeSinceLastFailure < _ProviderManager.COOLDOWN_DURATION_MS}`);
1895
1867
  }
1896
1868
  this.lastFailed.set(baseUrl, now);
1897
1869
  this.failedProviders.add(baseUrl);
@@ -1899,38 +1871,23 @@ var ProviderManager = class _ProviderManager {
1899
1871
  this.store.getState().setLastFailedTimestamp(baseUrl, now);
1900
1872
  this.store.getState().addFailedProvider(baseUrl);
1901
1873
  }
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
- );
1874
+ this.logger.log(`markFailed: updated ${baseUrl} to ${now}, failedProviders=${this.failedProviders.size}`);
1908
1875
  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
- );
1876
+ this.logger.log(`markFailed: second failure within cooldown window for ${baseUrl}`);
1912
1877
  if (!this.isOnCooldown(baseUrl)) {
1913
1878
  this.providersOnCoolDown.push([baseUrl, now]);
1914
1879
  if (this.store) {
1915
1880
  this.store.getState().addProviderOnCooldown(baseUrl, now);
1916
1881
  }
1917
- console.log(
1918
- `[markFailed:${this.instanceId}] Provider ${baseUrl} added to cooldown after second failure within 5 minutes`
1919
- );
1882
+ this.logger.log(`markFailed: ${baseUrl} added to cooldown`);
1920
1883
  } else {
1921
- console.log(
1922
- `[markFailed:${this.instanceId}] Provider ${baseUrl} is already on cooldown`
1923
- );
1884
+ this.logger.log(`markFailed: ${baseUrl} already on cooldown`);
1924
1885
  }
1925
1886
  } else {
1926
1887
  if (lastFailure === void 0) {
1927
- console.log(
1928
- `[markFailed:${this.instanceId}] First failure for ${baseUrl} - not adding to cooldown yet`
1929
- );
1888
+ this.logger.log(`markFailed: first failure for ${baseUrl}`);
1930
1889
  } else {
1931
- console.log(
1932
- `[markFailed:${this.instanceId}] Failure outside cooldown window for ${baseUrl} (timeSinceLastFailure: ${now - lastFailure}ms)`
1933
- );
1890
+ this.logger.log(`markFailed: failure outside cooldown window for ${baseUrl} (${now - lastFailure}ms ago)`);
1934
1891
  }
1935
1892
  }
1936
1893
  }
@@ -1987,25 +1944,12 @@ var ProviderManager = class _ProviderManager {
1987
1944
  const disabledProviders = new Set(
1988
1945
  this.providerRegistry.getDisabledProviders()
1989
1946
  );
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
- );
1947
+ this.logger.log(`findNextBestProvider: model=${modelId} disabled=${[...disabledProviders].length} onCooldown=${this.providersOnCoolDown.length}`);
1999
1948
  const allProviders = this.providerRegistry.getAllProvidersModels();
2000
- console.log(
2001
- `[findNextBestProvider:${this.instanceId}] Total providers in registry: ${Object.keys(allProviders).length}`
2002
- );
1949
+ this.logger.log(`findNextBestProvider: total providers=${Object.keys(allProviders).length}`);
2003
1950
  const candidates = [];
2004
1951
  for (const [baseUrl, models] of Object.entries(allProviders)) {
2005
1952
  if (baseUrl === currentBaseUrl) {
2006
- console.log(
2007
- `[findNextBestProvider:${this.instanceId}] SKIP (current): ${baseUrl}`
2008
- );
2009
1953
  continue;
2010
1954
  }
2011
1955
  if (disabledProviders.has(baseUrl)) {
@@ -2031,7 +1975,7 @@ var ProviderManager = class _ProviderManager {
2031
1975
  return null;
2032
1976
  }
2033
1977
  } catch (error) {
2034
- console.error("Error finding next best provider:", error);
1978
+ this.logger.error("findNextBestProvider error:", error);
2035
1979
  return null;
2036
1980
  }
2037
1981
  }
@@ -2158,16 +2102,9 @@ var ProviderManager = class _ProviderManager {
2158
2102
  res.height
2159
2103
  );
2160
2104
  imageTokens += tokensFromImage;
2161
- console.log("IMAGE INPUT RESOLUTION", {
2162
- width: res.width,
2163
- height: res.height,
2164
- tokensFromImage
2165
- });
2105
+ this.logger.log(`IMAGE INPUT RESOLUTION width=${res.width} height=${res.height} tokens=${tokensFromImage}`);
2166
2106
  } else {
2167
- console.log(
2168
- "IMAGE INPUT RESOLUTION",
2169
- "unknown (unsupported format or parse failure)"
2170
- );
2107
+ this.logger.log("IMAGE INPUT RESOLUTION: unknown format");
2171
2108
  }
2172
2109
  }
2173
2110
  }
@@ -2200,7 +2137,7 @@ var ProviderManager = class _ProviderManager {
2200
2137
  const totalEstimatedCosts = (promptCosts + completionCost) * 1.05;
2201
2138
  return totalEstimatedCosts;
2202
2139
  } catch (e) {
2203
- console.error(e);
2140
+ this.logger.error("getRequiredSatsForModel error:", e);
2204
2141
  return 0;
2205
2142
  }
2206
2143
  }
@@ -3697,6 +3634,7 @@ var RoutstrClient = class {
3697
3634
  this.walletAdapter = walletAdapter;
3698
3635
  this.storageAdapter = storageAdapter;
3699
3636
  this.providerRegistry = providerRegistry;
3637
+ this.logger = (options.logger ?? consoleLogger).child("RoutstrClient");
3700
3638
  this.balanceManager = new BalanceManager(
3701
3639
  walletAdapter,
3702
3640
  storageAdapter,
@@ -3713,7 +3651,7 @@ var RoutstrClient = class {
3713
3651
  this.mode = mode;
3714
3652
  this.usageTrackingDriver = options.usageTrackingDriver;
3715
3653
  this.sdkStore = options.sdkStore;
3716
- this.providerManager = options.providerManager ?? new ProviderManager(providerRegistry, this.sdkStore);
3654
+ this.providerManager = options.providerManager ?? new ProviderManager(providerRegistry, this.sdkStore, this.logger);
3717
3655
  }
3718
3656
  cashuSpender;
3719
3657
  balanceManager;
@@ -3724,6 +3662,7 @@ var RoutstrClient = class {
3724
3662
  debugLevel = "WARN";
3725
3663
  usageTrackingDriver;
3726
3664
  sdkStore;
3665
+ logger;
3727
3666
  /**
3728
3667
  * Get the current client mode
3729
3668
  */
@@ -3745,13 +3684,13 @@ var RoutstrClient = class {
3745
3684
  if (levelPriority[level] >= levelPriority[this.debugLevel]) {
3746
3685
  switch (level) {
3747
3686
  case "DEBUG":
3748
- console.log(...args);
3687
+ this.logger.log(...args);
3749
3688
  break;
3750
3689
  case "WARN":
3751
- console.warn(...args);
3690
+ this.logger.warn(...args);
3752
3691
  break;
3753
3692
  case "ERROR":
3754
- console.error(...args);
3693
+ this.logger.error(...args);
3755
3694
  break;
3756
3695
  }
3757
3696
  }
@@ -4355,7 +4294,7 @@ var RoutstrClient = class {
4355
4294
  tryNextProvider = true;
4356
4295
  }
4357
4296
  }
4358
- if ((status === 401 || status === 403 || status === 413 || status === 400 || status === 429 || status === 500 || status === 502 || status === 503 || status === 504 || status === 521) && !tryNextProvider) {
4297
+ 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
4298
  this._log(
4360
4299
  "DEBUG",
4361
4300
  `[RoutstrClient] _handleErrorResponse: Status ${status} (${status === 429 ? "rate limited" : "auth/server error"}), attempting refund for ${baseUrl}, mode=${this.mode}`