@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
@@ -3,6 +3,19 @@ import { createStore } from 'zustand/vanilla';
3
3
  import { Transform } from 'stream';
4
4
  import { StringDecoder } from 'string_decoder';
5
5
 
6
+ // core/types.ts
7
+ function makeConsoleLogger(prefix) {
8
+ const fmt = (args) => prefix ? [prefix, ...args] : args;
9
+ return {
10
+ log: (...args) => console.log(...fmt(args)),
11
+ warn: (...args) => console.warn(...fmt(args)),
12
+ error: (...args) => console.error(...fmt(args)),
13
+ debug: (...args) => console.log(...fmt(args)),
14
+ child: (p) => makeConsoleLogger(prefix ? `${prefix}:${p}` : p)
15
+ };
16
+ }
17
+ var consoleLogger = makeConsoleLogger();
18
+
6
19
  // core/errors.ts
7
20
  var InsufficientBalanceError = class extends Error {
8
21
  constructor(required, available, maxMintBalance = 0, maxMintUrl = "", customMessage) {
@@ -102,14 +115,16 @@ function selectMintWithBalance(balances, units, amount, excludeMints = []) {
102
115
  return { selectedMintUrl: null, selectedMintBalance: 0 };
103
116
  }
104
117
  var CashuSpender = class {
105
- constructor(walletAdapter, storageAdapter, _providerRegistry, balanceManager) {
118
+ constructor(walletAdapter, storageAdapter, _providerRegistry, balanceManager, logger) {
106
119
  this.walletAdapter = walletAdapter;
107
120
  this.storageAdapter = storageAdapter;
108
121
  this._providerRegistry = _providerRegistry;
109
122
  this.balanceManager = balanceManager;
123
+ this.logger = (logger ?? consoleLogger).child("CashuSpender");
110
124
  }
111
125
  _isBusy = false;
112
126
  debugLevel = "WARN";
127
+ logger;
113
128
  async receiveToken(token) {
114
129
  try {
115
130
  const result = await this.walletAdapter.receiveToken(token);
@@ -205,13 +220,13 @@ var CashuSpender = class {
205
220
  if (levelPriority[level] >= levelPriority[this.debugLevel]) {
206
221
  switch (level) {
207
222
  case "DEBUG":
208
- console.log(...args);
223
+ this.logger.log(...args);
209
224
  break;
210
225
  case "WARN":
211
- console.warn(...args);
226
+ this.logger.warn(...args);
212
227
  break;
213
228
  case "ERROR":
214
- console.error(...args);
229
+ this.logger.error(...args);
215
230
  break;
216
231
  }
217
232
  }
@@ -559,19 +574,50 @@ var CashuSpender = class {
559
574
  apiKeyEntry.baseUrl
560
575
  );
561
576
  if (apiKeyEntryFull && this.balanceManager) {
577
+ try {
578
+ const balanceResult = await this.balanceManager.getTokenBalance(
579
+ apiKeyEntryFull.key,
580
+ apiKeyEntry.baseUrl
581
+ );
582
+ if (balanceResult.isInvalidApiKey) {
583
+ this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);
584
+ results.push({
585
+ baseUrl: apiKeyEntry.baseUrl,
586
+ success: true
587
+ });
588
+ continue;
589
+ }
590
+ if (balanceResult.amount >= 0) {
591
+ const balanceSat = balanceResult.unit === "msat" ? Math.floor(balanceResult.amount / 1e3) : balanceResult.amount;
592
+ this.storageAdapter.updateApiKeyBalance(
593
+ apiKeyEntry.baseUrl,
594
+ balanceSat
595
+ );
596
+ }
597
+ } catch {
598
+ }
599
+ const refreshedEntry = this.storageAdapter.getApiKey(
600
+ apiKeyEntry.baseUrl
601
+ );
602
+ if (!refreshedEntry) continue;
562
603
  const refundResult = await this.balanceManager.refundApiKey({
563
604
  mintUrl,
564
605
  baseUrl: apiKeyEntry.baseUrl,
565
- apiKey: apiKeyEntryFull.key,
606
+ apiKey: refreshedEntry.key,
566
607
  forceRefund
567
608
  });
568
609
  if (refundResult.success) {
569
610
  this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);
570
611
  } else {
571
- this.storageAdapter.updateApiKeyBalance(
572
- apiKeyEntry.baseUrl,
573
- apiKeyEntry.amount
612
+ const currentEntry = this.storageAdapter.getApiKey(
613
+ apiKeyEntry.baseUrl
574
614
  );
615
+ if (currentEntry) {
616
+ this.storageAdapter.updateApiKeyBalance(
617
+ apiKeyEntry.baseUrl,
618
+ currentEntry.balance
619
+ );
620
+ }
575
621
  }
576
622
  results.push({
577
623
  baseUrl: apiKeyEntry.baseUrl,
@@ -638,10 +684,11 @@ var CashuSpender = class {
638
684
 
639
685
  // wallet/BalanceManager.ts
640
686
  var BalanceManager = class _BalanceManager {
641
- constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender) {
687
+ constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender, logger) {
642
688
  this.walletAdapter = walletAdapter;
643
689
  this.storageAdapter = storageAdapter;
644
690
  this.providerRegistry = providerRegistry;
691
+ this.logger = (logger ?? consoleLogger).child("BalanceManager");
645
692
  if (cashuSpender) {
646
693
  this.cashuSpender = cashuSpender;
647
694
  } else {
@@ -658,6 +705,7 @@ var BalanceManager = class _BalanceManager {
658
705
  providerWalletOps = /* @__PURE__ */ new Map();
659
706
  /** Cooldown (ms) between opposite operations on the same provider */
660
707
  static PROVIDER_WALLET_COOLDOWN_MS = 1e4;
708
+ logger;
661
709
  /**
662
710
  * Check whether a wallet operation (topup/refund) may run for a provider.
663
711
  * Returns the reason when blocked.
@@ -732,7 +780,7 @@ var BalanceManager = class _BalanceManager {
732
780
  const { mintUrl, baseUrl, apiKey, forceRefund } = options;
733
781
  const guard = this._canRunProviderWalletOperation(baseUrl, "refund");
734
782
  if (!guard.allowed) {
735
- console.log(`[BalanceManager] Skipping refund for ${baseUrl} - ${guard.reason}`);
783
+ this.logger.log(`Skipping refund for ${baseUrl} - ${guard.reason}`);
736
784
  return { success: false, message: guard.reason };
737
785
  }
738
786
  this._beginProviderWalletOperation(baseUrl, "refund");
@@ -752,9 +800,7 @@ var BalanceManager = class _BalanceManager {
752
800
  if (apiKeyEntry?.lastUsed) {
753
801
  const fiveMinutesAgo = Date.now() - 5 * 60 * 1e3;
754
802
  if (apiKeyEntry.lastUsed > fiveMinutesAgo) {
755
- console.log(
756
- `[BalanceManager] Skipping refund for ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1e3)}s ago`
757
- );
803
+ this.logger.log(`Skipping refund for ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1e3)}s ago`);
758
804
  return {
759
805
  success: false,
760
806
  message: "API key was used recently, skipping refund"
@@ -780,7 +826,8 @@ var BalanceManager = class _BalanceManager {
780
826
  };
781
827
  }
782
828
  if (fetchResult.error === "No balance to refund") {
783
- return { success: false, message: "No balance to refund" };
829
+ this.storageAdapter.removeApiKey(baseUrl);
830
+ return { success: true, message: "No balance to refund, key cleaned up" };
784
831
  }
785
832
  const receiveResult = await this.cashuSpender.receiveToken(
786
833
  fetchResult.token
@@ -796,7 +843,7 @@ var BalanceManager = class _BalanceManager {
796
843
  requestId: fetchResult.requestId
797
844
  };
798
845
  } catch (error) {
799
- console.error("[BalanceManager] API key refund error", error);
846
+ this.logger.error("API key refund error", error);
800
847
  return this._handleRefundError(error, mintUrl, fetchResult?.requestId);
801
848
  }
802
849
  }
@@ -848,7 +895,7 @@ var BalanceManager = class _BalanceManager {
848
895
  };
849
896
  } catch (error) {
850
897
  clearTimeout(timeoutId);
851
- console.error("[BalanceManager.fetchRefundToken] Fetch error", error);
898
+ this.logger.error("fetchRefundToken fetch error", error);
852
899
  if (error instanceof Error) {
853
900
  if (error.name === "AbortError") {
854
901
  return {
@@ -874,7 +921,7 @@ var BalanceManager = class _BalanceManager {
874
921
  const { mintUrl, baseUrl, amount, token: providedToken } = options;
875
922
  const guard = this._canRunProviderWalletOperation(baseUrl, "topup");
876
923
  if (!guard.allowed) {
877
- console.log(`[BalanceManager] Skipping topup for ${baseUrl} - ${guard.reason}`);
924
+ this.logger.log(`Skipping topup for ${baseUrl} - ${guard.reason}`);
878
925
  return { success: false, message: guard.reason };
879
926
  }
880
927
  this._beginProviderWalletOperation(baseUrl, "topup");
@@ -911,7 +958,7 @@ var BalanceManager = class _BalanceManager {
911
958
  cashuToken = tokenResult.token;
912
959
  const topUpResult = await this._postTopUp(baseUrl, apiKey, cashuToken);
913
960
  requestId = topUpResult.requestId;
914
- console.log(topUpResult);
961
+ this.logger.log("topUpResult:", topUpResult);
915
962
  if (!topUpResult.success) {
916
963
  await this._recoverFailedTopUp(cashuToken);
917
964
  return {
@@ -927,10 +974,7 @@ var BalanceManager = class _BalanceManager {
927
974
  requestId
928
975
  };
929
976
  } catch (error) {
930
- console.log(
931
- "DEBUG",
932
- `[TopuPU] topup: Topup result for ${baseUrl}: error=${error}`
933
- );
977
+ this.logger.log(`topup error for ${baseUrl}: ${error}`);
934
978
  if (cashuToken) {
935
979
  await this._recoverFailedTopUp(cashuToken);
936
980
  }
@@ -947,13 +991,9 @@ var BalanceManager = class _BalanceManager {
947
991
  p2pkPubkey
948
992
  } = options;
949
993
  const adjustedAmount = Math.ceil(amount);
950
- console.log(
951
- `[BalanceManager.createProviderToken] Starting: baseUrl=${baseUrl}, mintUrl=${mintUrl}, amount=${amount}, adjustedAmount=${adjustedAmount}, retryCount=${retryCount}`
952
- );
994
+ this.logger.log(`createProviderToken: baseUrl=${baseUrl} mintUrl=${mintUrl} amount=${amount} adjustedAmount=${adjustedAmount} retryCount=${retryCount}`);
953
995
  if (!adjustedAmount || isNaN(adjustedAmount)) {
954
- console.error(
955
- `[BalanceManager.createProviderToken] FAILURE: Invalid amount - amount=${amount}, adjustedAmount=${adjustedAmount}`
956
- );
996
+ this.logger.error(`createProviderToken: invalid amount=${amount}`);
957
997
  return { success: false, error: "Invalid top up amount" };
958
998
  }
959
999
  const balanceState = await this.getBalanceState();
@@ -984,9 +1024,7 @@ var BalanceManager = class _BalanceManager {
984
1024
  { url: "", balance: 0 }
985
1025
  ).url
986
1026
  );
987
- console.error(
988
- `[BalanceManager.createProviderToken] FAILURE: Insufficient balance - required=${adjustedAmount}, available=${totalMintBalance + targetProviderBalance}, totalMintBalance=${totalMintBalance}, targetProviderBalance=${targetProviderBalance}, refundableProviderBalance=${refundableProviderBalance}`
989
- );
1027
+ this.logger.error(`createProviderToken: insufficient balance required=${adjustedAmount} available=${totalMintBalance + targetProviderBalance} totalMint=${totalMintBalance} targetProvider=${targetProviderBalance}`);
990
1028
  return { success: false, error: error.message };
991
1029
  }
992
1030
  const providerMints = baseUrl && this.providerRegistry ? this.providerRegistry.getProviderMints(baseUrl) : [];
@@ -1022,9 +1060,7 @@ var BalanceManager = class _BalanceManager {
1022
1060
  maxMintUrl = mintUrl2;
1023
1061
  }
1024
1062
  }
1025
- console.error(
1026
- `[BalanceManager.createProviderToken] FAILURE: No candidate mints found - requiredAmount=${requiredAmount}, totalMintBalance=${totalMintBalance}, maxBalance=${maxBalance}, maxMintUrl=${maxMintUrl}, providerMints=${JSON.stringify(providerMints)}`
1027
- );
1063
+ this.logger.error(`createProviderToken: no candidate mints required=${requiredAmount} totalMint=${totalMintBalance} maxBalance=${maxBalance} maxMint=${maxMintUrl}`);
1028
1064
  const error = new InsufficientBalanceError(
1029
1065
  adjustedAmount,
1030
1066
  totalMintBalance,
@@ -1036,17 +1072,13 @@ var BalanceManager = class _BalanceManager {
1036
1072
  let lastError;
1037
1073
  for (const candidateMint of candidates) {
1038
1074
  try {
1039
- console.log(
1040
- `[BalanceManager.createProviderToken] Attempting mint: ${candidateMint}, amount: ${requiredAmount}`
1041
- );
1075
+ this.logger.log(`createProviderToken: attempting mint=${candidateMint} amount=${requiredAmount}`);
1042
1076
  const token = await this.walletAdapter.sendToken(
1043
1077
  candidateMint,
1044
1078
  requiredAmount,
1045
1079
  p2pkPubkey
1046
1080
  );
1047
- console.log(
1048
- `[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])])))}`
1049
- );
1081
+ this.logger.log(`createProviderToken: success from mint=${candidateMint}`);
1050
1082
  return {
1051
1083
  success: true,
1052
1084
  token,
@@ -1055,15 +1087,11 @@ var BalanceManager = class _BalanceManager {
1055
1087
  };
1056
1088
  } catch (error) {
1057
1089
  const errorMsg = error instanceof Error ? error.message : String(error);
1058
- console.error(
1059
- `[BalanceManager.createProviderToken] FAILURE: Mint ${candidateMint} failed with error: ${errorMsg}`
1060
- );
1090
+ this.logger.error(`createProviderToken: mint=${candidateMint} failed: ${errorMsg}`);
1061
1091
  if (error instanceof Error) {
1062
1092
  lastError = errorMsg;
1063
1093
  if (isNetworkErrorMessage(error.message)) {
1064
- console.warn(
1065
- `[BalanceManager.createProviderToken] Network error from ${candidateMint}, trying next mint...`
1066
- );
1094
+ this.logger.warn(`createProviderToken: network error from ${candidateMint}, trying next mint...`);
1067
1095
  continue;
1068
1096
  }
1069
1097
  }
@@ -1073,9 +1101,7 @@ var BalanceManager = class _BalanceManager {
1073
1101
  };
1074
1102
  }
1075
1103
  }
1076
- console.error(
1077
- `[BalanceManager.createProviderToken] FAILURE: All candidate mints exhausted - lastError=${lastError}, candidates=${JSON.stringify(candidates)}`
1078
- );
1104
+ this.logger.error(`createProviderToken: all candidate mints exhausted lastError=${lastError}`);
1079
1105
  return {
1080
1106
  success: false,
1081
1107
  error: lastError || "All candidate mints failed while creating top up token"
@@ -1190,7 +1216,7 @@ var BalanceManager = class _BalanceManager {
1190
1216
  return { success: true, requestId };
1191
1217
  } catch (error) {
1192
1218
  clearTimeout(timeoutId);
1193
- console.error("[BalanceManager._postTopUp] Fetch error", error);
1219
+ this.logger.error("_postTopUp fetch error", error);
1194
1220
  if (error instanceof Error) {
1195
1221
  if (error.name === "AbortError") {
1196
1222
  return {
@@ -1216,10 +1242,7 @@ var BalanceManager = class _BalanceManager {
1216
1242
  try {
1217
1243
  await this.cashuSpender.receiveToken(cashuToken);
1218
1244
  } catch (error) {
1219
- console.error(
1220
- "[BalanceManager._recoverFailedTopUp] Failed to recover token",
1221
- error
1222
- );
1245
+ this.logger.error("_recoverFailedTopUp: failed to recover token", error);
1223
1246
  }
1224
1247
  }
1225
1248
  /**
@@ -1272,9 +1295,9 @@ var BalanceManager = class _BalanceManager {
1272
1295
  apiKey: data.api_key
1273
1296
  };
1274
1297
  } else {
1275
- console.log(response.status);
1298
+ this.logger.warn(`getTokenBalance: status=${response.status}`);
1276
1299
  const data = await response.json();
1277
- console.log("FAILED ", data);
1300
+ this.logger.warn("getTokenBalance: FAILED", data);
1278
1301
  const isInvalidApiKey = response.status === 401 && data?.detail?.error?.code === "invalid_api_key" && data?.detail?.error?.message?.includes("proofs already spent");
1279
1302
  return {
1280
1303
  amount: -1,
@@ -1285,7 +1308,7 @@ var BalanceManager = class _BalanceManager {
1285
1308
  };
1286
1309
  }
1287
1310
  } catch (error) {
1288
- console.error("ERRORR IN RESTPONSE", error);
1311
+ this.logger.error("getTokenBalance error", error);
1289
1312
  }
1290
1313
  return { amount: -1, reserved: 0, unit: "sat", apiKey: "" };
1291
1314
  }
@@ -1751,9 +1774,10 @@ function isInsecureHttpUrl(url) {
1751
1774
  return url.startsWith("http://");
1752
1775
  }
1753
1776
  var ProviderManager = class _ProviderManager {
1754
- constructor(providerRegistry, store) {
1777
+ constructor(providerRegistry, store, logger) {
1755
1778
  this.providerRegistry = providerRegistry;
1756
1779
  this.instanceId = `pm_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
1780
+ this.logger = (logger ?? consoleLogger).child(`ProviderManager:${this.instanceId}`);
1757
1781
  if (store) {
1758
1782
  this.store = store;
1759
1783
  this.hydrateFromStore();
@@ -1770,6 +1794,7 @@ var ProviderManager = class _ProviderManager {
1770
1794
  store = null;
1771
1795
  /** Instance ID for debugging */
1772
1796
  instanceId;
1797
+ logger;
1773
1798
  /**
1774
1799
  * Hydrate in-memory state from persistent store
1775
1800
  */
@@ -1782,10 +1807,7 @@ var ProviderManager = class _ProviderManager {
1782
1807
  this.providersOnCoolDown = state.providersOnCooldown.filter(
1783
1808
  (entry) => now - entry.timestamp < _ProviderManager.COOLDOWN_DURATION_MS
1784
1809
  ).map((entry) => [entry.baseUrl, entry.timestamp]);
1785
- console.log(`[ProviderManager:${this.instanceId}] Hydrated from store:`);
1786
- console.log(` failedProviders: ${this.failedProviders.size}`);
1787
- console.log(` lastFailed: ${this.lastFailed.size}`);
1788
- console.log(` providersOnCooldown: ${this.providersOnCoolDown.length}`);
1810
+ this.logger.log(`Hydrated from store: failedProviders=${this.failedProviders.size} lastFailed=${this.lastFailed.size} providersOnCooldown=${this.providersOnCoolDown.length}`);
1789
1811
  }
1790
1812
  /**
1791
1813
  * Get instance ID for debugging
@@ -1805,9 +1827,7 @@ var ProviderManager = class _ProviderManager {
1805
1827
  const age = now - timestamp;
1806
1828
  const isExpired = age >= _ProviderManager.COOLDOWN_DURATION_MS;
1807
1829
  if (isExpired) {
1808
- console.log(
1809
- `[cleanupExpiredCooldowns:${this.instanceId}] Removing expired cooldown for ${url} (age: ${age}ms, cooldown: ${_ProviderManager.COOLDOWN_DURATION_MS}ms)`
1810
- );
1830
+ this.logger.log(`Removing expired cooldown for ${url} (age: ${age}ms)`);
1811
1831
  this.failedProviders.delete(url);
1812
1832
  if (this.store) {
1813
1833
  this.store.getState().removeFailedProvider(url);
@@ -1818,9 +1838,7 @@ var ProviderManager = class _ProviderManager {
1818
1838
  );
1819
1839
  const after = this.providersOnCoolDown.length;
1820
1840
  if (before !== after) {
1821
- console.log(
1822
- `[cleanupExpiredCooldowns:${this.instanceId}] Cleaned up ${before - after} expired cooldown(s), ${after} remaining`
1823
- );
1841
+ this.logger.log(`Cleaned up ${before - after} expired cooldown(s), ${after} remaining`);
1824
1842
  }
1825
1843
  }
1826
1844
  /**
@@ -1872,24 +1890,10 @@ var ProviderManager = class _ProviderManager {
1872
1890
  markFailed(baseUrl) {
1873
1891
  const now = Date.now();
1874
1892
  const lastFailure = this.lastFailed.get(baseUrl);
1875
- console.log(`[markFailed:${this.instanceId}] baseUrl: ${baseUrl}`);
1876
- console.log(
1877
- `[markFailed:${this.instanceId}] lastFailure from map: ${lastFailure}`
1878
- );
1879
- console.log(
1880
- `[markFailed:${this.instanceId}] current timestamp (now): ${now}`
1881
- );
1882
- console.log(
1883
- `[markFailed:${this.instanceId}] COOLDOWN_DURATION_MS: ${_ProviderManager.COOLDOWN_DURATION_MS}`
1884
- );
1893
+ this.logger.log(`markFailed: ${baseUrl} lastFailure=${lastFailure} now=${now}`);
1885
1894
  if (lastFailure !== void 0) {
1886
1895
  const timeSinceLastFailure = now - lastFailure;
1887
- console.log(
1888
- `[markFailed:${this.instanceId}] timeSinceLastFailure: ${timeSinceLastFailure}ms`
1889
- );
1890
- console.log(
1891
- `[markFailed:${this.instanceId}] isWithinCooldownWindow: ${timeSinceLastFailure < _ProviderManager.COOLDOWN_DURATION_MS}`
1892
- );
1896
+ this.logger.log(`markFailed: timeSinceLastFailure=${timeSinceLastFailure}ms withinCooldown=${timeSinceLastFailure < _ProviderManager.COOLDOWN_DURATION_MS}`);
1893
1897
  }
1894
1898
  this.lastFailed.set(baseUrl, now);
1895
1899
  this.failedProviders.add(baseUrl);
@@ -1897,38 +1901,23 @@ var ProviderManager = class _ProviderManager {
1897
1901
  this.store.getState().setLastFailedTimestamp(baseUrl, now);
1898
1902
  this.store.getState().addFailedProvider(baseUrl);
1899
1903
  }
1900
- console.log(
1901
- `[markFailed:${this.instanceId}] Updated lastFailed map for ${baseUrl} to ${now}`
1902
- );
1903
- console.log(
1904
- `[markFailed:${this.instanceId}] failedProviders set size: ${this.failedProviders.size}`
1905
- );
1904
+ this.logger.log(`markFailed: updated ${baseUrl} to ${now}, failedProviders=${this.failedProviders.size}`);
1906
1905
  if (lastFailure !== void 0 && now - lastFailure < _ProviderManager.COOLDOWN_DURATION_MS) {
1907
- console.log(
1908
- `[markFailed:${this.instanceId}] Second failure detected within cooldown window for ${baseUrl}`
1909
- );
1906
+ this.logger.log(`markFailed: second failure within cooldown window for ${baseUrl}`);
1910
1907
  if (!this.isOnCooldown(baseUrl)) {
1911
1908
  this.providersOnCoolDown.push([baseUrl, now]);
1912
1909
  if (this.store) {
1913
1910
  this.store.getState().addProviderOnCooldown(baseUrl, now);
1914
1911
  }
1915
- console.log(
1916
- `[markFailed:${this.instanceId}] Provider ${baseUrl} added to cooldown after second failure within 5 minutes`
1917
- );
1912
+ this.logger.log(`markFailed: ${baseUrl} added to cooldown`);
1918
1913
  } else {
1919
- console.log(
1920
- `[markFailed:${this.instanceId}] Provider ${baseUrl} is already on cooldown`
1921
- );
1914
+ this.logger.log(`markFailed: ${baseUrl} already on cooldown`);
1922
1915
  }
1923
1916
  } else {
1924
1917
  if (lastFailure === void 0) {
1925
- console.log(
1926
- `[markFailed:${this.instanceId}] First failure for ${baseUrl} - not adding to cooldown yet`
1927
- );
1918
+ this.logger.log(`markFailed: first failure for ${baseUrl}`);
1928
1919
  } else {
1929
- console.log(
1930
- `[markFailed:${this.instanceId}] Failure outside cooldown window for ${baseUrl} (timeSinceLastFailure: ${now - lastFailure}ms)`
1931
- );
1920
+ this.logger.log(`markFailed: failure outside cooldown window for ${baseUrl} (${now - lastFailure}ms ago)`);
1932
1921
  }
1933
1922
  }
1934
1923
  }
@@ -1985,25 +1974,12 @@ var ProviderManager = class _ProviderManager {
1985
1974
  const disabledProviders = new Set(
1986
1975
  this.providerRegistry.getDisabledProviders()
1987
1976
  );
1988
- console.log(
1989
- `[findNextBestProvider:${this.instanceId}] Starting search for model: ${modelId}`
1990
- );
1991
- console.log(
1992
- `[findNextBestProvider:${this.instanceId}] disabledProviders: ${[...disabledProviders]}`
1993
- );
1994
- console.log(
1995
- `[findNextBestProvider:${this.instanceId}] providersOnCooldown: ${this.providersOnCoolDown.map(([url]) => url)}`
1996
- );
1977
+ this.logger.log(`findNextBestProvider: model=${modelId} disabled=${[...disabledProviders].length} onCooldown=${this.providersOnCoolDown.length}`);
1997
1978
  const allProviders = this.providerRegistry.getAllProvidersModels();
1998
- console.log(
1999
- `[findNextBestProvider:${this.instanceId}] Total providers in registry: ${Object.keys(allProviders).length}`
2000
- );
1979
+ this.logger.log(`findNextBestProvider: total providers=${Object.keys(allProviders).length}`);
2001
1980
  const candidates = [];
2002
1981
  for (const [baseUrl, models] of Object.entries(allProviders)) {
2003
1982
  if (baseUrl === currentBaseUrl) {
2004
- console.log(
2005
- `[findNextBestProvider:${this.instanceId}] SKIP (current): ${baseUrl}`
2006
- );
2007
1983
  continue;
2008
1984
  }
2009
1985
  if (disabledProviders.has(baseUrl)) {
@@ -2029,7 +2005,7 @@ var ProviderManager = class _ProviderManager {
2029
2005
  return null;
2030
2006
  }
2031
2007
  } catch (error) {
2032
- console.error("Error finding next best provider:", error);
2008
+ this.logger.error("findNextBestProvider error:", error);
2033
2009
  return null;
2034
2010
  }
2035
2011
  }
@@ -2156,16 +2132,9 @@ var ProviderManager = class _ProviderManager {
2156
2132
  res.height
2157
2133
  );
2158
2134
  imageTokens += tokensFromImage;
2159
- console.log("IMAGE INPUT RESOLUTION", {
2160
- width: res.width,
2161
- height: res.height,
2162
- tokensFromImage
2163
- });
2135
+ this.logger.log(`IMAGE INPUT RESOLUTION width=${res.width} height=${res.height} tokens=${tokensFromImage}`);
2164
2136
  } else {
2165
- console.log(
2166
- "IMAGE INPUT RESOLUTION",
2167
- "unknown (unsupported format or parse failure)"
2168
- );
2137
+ this.logger.log("IMAGE INPUT RESOLUTION: unknown format");
2169
2138
  }
2170
2139
  }
2171
2140
  }
@@ -2198,7 +2167,7 @@ var ProviderManager = class _ProviderManager {
2198
2167
  const totalEstimatedCosts = (promptCosts + completionCost) * 1.05;
2199
2168
  return totalEstimatedCosts;
2200
2169
  } catch (e) {
2201
- console.error(e);
2170
+ this.logger.error("getRequiredSatsForModel error:", e);
2202
2171
  return 0;
2203
2172
  }
2204
2173
  }
@@ -3695,6 +3664,7 @@ var RoutstrClient = class {
3695
3664
  this.walletAdapter = walletAdapter;
3696
3665
  this.storageAdapter = storageAdapter;
3697
3666
  this.providerRegistry = providerRegistry;
3667
+ this.logger = (options.logger ?? consoleLogger).child("RoutstrClient");
3698
3668
  this.balanceManager = new BalanceManager(
3699
3669
  walletAdapter,
3700
3670
  storageAdapter,
@@ -3711,7 +3681,7 @@ var RoutstrClient = class {
3711
3681
  this.mode = mode;
3712
3682
  this.usageTrackingDriver = options.usageTrackingDriver;
3713
3683
  this.sdkStore = options.sdkStore;
3714
- this.providerManager = options.providerManager ?? new ProviderManager(providerRegistry, this.sdkStore);
3684
+ this.providerManager = options.providerManager ?? new ProviderManager(providerRegistry, this.sdkStore, this.logger);
3715
3685
  }
3716
3686
  cashuSpender;
3717
3687
  balanceManager;
@@ -3722,6 +3692,7 @@ var RoutstrClient = class {
3722
3692
  debugLevel = "WARN";
3723
3693
  usageTrackingDriver;
3724
3694
  sdkStore;
3695
+ logger;
3725
3696
  /**
3726
3697
  * Get the current client mode
3727
3698
  */
@@ -3743,13 +3714,13 @@ var RoutstrClient = class {
3743
3714
  if (levelPriority[level] >= levelPriority[this.debugLevel]) {
3744
3715
  switch (level) {
3745
3716
  case "DEBUG":
3746
- console.log(...args);
3717
+ this.logger.log(...args);
3747
3718
  break;
3748
3719
  case "WARN":
3749
- console.warn(...args);
3720
+ this.logger.warn(...args);
3750
3721
  break;
3751
3722
  case "ERROR":
3752
- console.error(...args);
3723
+ this.logger.error(...args);
3753
3724
  break;
3754
3725
  }
3755
3726
  }
@@ -4353,7 +4324,7 @@ var RoutstrClient = class {
4353
4324
  tryNextProvider = true;
4354
4325
  }
4355
4326
  }
4356
- if ((status === 401 || status === 403 || status === 413 || status === 400 || status === 429 || status === 500 || status === 502 || status === 503 || status === 504 || status === 521) && !tryNextProvider) {
4327
+ if ((status === 401 || status === 403 || status === 404 || status === 413 || status === 400 || status === 429 || status === 500 || status === 502 || status === 503 || status === 504 || status === 521) && !tryNextProvider) {
4357
4328
  this._log(
4358
4329
  "DEBUG",
4359
4330
  `[RoutstrClient] _handleErrorResponse: Status ${status} (${status === 429 ? "rate limited" : "auth/server error"}), attempting refund for ${baseUrl}, mode=${this.mode}`