@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,5 +1,18 @@
1
1
  import { getDecodedToken } from '@cashu/cashu-ts';
2
2
 
3
+ // core/types.ts
4
+ function makeConsoleLogger(prefix) {
5
+ const fmt = (args) => prefix ? [prefix, ...args] : args;
6
+ return {
7
+ log: (...args) => console.log(...fmt(args)),
8
+ warn: (...args) => console.warn(...fmt(args)),
9
+ error: (...args) => console.error(...fmt(args)),
10
+ debug: (...args) => console.log(...fmt(args)),
11
+ child: (p) => makeConsoleLogger(prefix ? `${prefix}:${p}` : p)
12
+ };
13
+ }
14
+ var consoleLogger = makeConsoleLogger();
15
+
3
16
  // core/errors.ts
4
17
  var InsufficientBalanceError = class extends Error {
5
18
  constructor(required, available, maxMintBalance = 0, maxMintUrl = "", customMessage) {
@@ -78,14 +91,16 @@ function selectMintWithBalance(balances, units, amount, excludeMints = []) {
78
91
  return { selectedMintUrl: null, selectedMintBalance: 0 };
79
92
  }
80
93
  var CashuSpender = class {
81
- constructor(walletAdapter, storageAdapter, _providerRegistry, balanceManager) {
94
+ constructor(walletAdapter, storageAdapter, _providerRegistry, balanceManager, logger) {
82
95
  this.walletAdapter = walletAdapter;
83
96
  this.storageAdapter = storageAdapter;
84
97
  this._providerRegistry = _providerRegistry;
85
98
  this.balanceManager = balanceManager;
99
+ this.logger = (logger ?? consoleLogger).child("CashuSpender");
86
100
  }
87
101
  _isBusy = false;
88
102
  debugLevel = "WARN";
103
+ logger;
89
104
  async receiveToken(token) {
90
105
  try {
91
106
  const result = await this.walletAdapter.receiveToken(token);
@@ -181,13 +196,13 @@ var CashuSpender = class {
181
196
  if (levelPriority[level] >= levelPriority[this.debugLevel]) {
182
197
  switch (level) {
183
198
  case "DEBUG":
184
- console.log(...args);
199
+ this.logger.log(...args);
185
200
  break;
186
201
  case "WARN":
187
- console.warn(...args);
202
+ this.logger.warn(...args);
188
203
  break;
189
204
  case "ERROR":
190
- console.error(...args);
205
+ this.logger.error(...args);
191
206
  break;
192
207
  }
193
208
  }
@@ -535,19 +550,50 @@ var CashuSpender = class {
535
550
  apiKeyEntry.baseUrl
536
551
  );
537
552
  if (apiKeyEntryFull && this.balanceManager) {
553
+ try {
554
+ const balanceResult = await this.balanceManager.getTokenBalance(
555
+ apiKeyEntryFull.key,
556
+ apiKeyEntry.baseUrl
557
+ );
558
+ if (balanceResult.isInvalidApiKey) {
559
+ this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);
560
+ results.push({
561
+ baseUrl: apiKeyEntry.baseUrl,
562
+ success: true
563
+ });
564
+ continue;
565
+ }
566
+ if (balanceResult.amount >= 0) {
567
+ const balanceSat = balanceResult.unit === "msat" ? Math.floor(balanceResult.amount / 1e3) : balanceResult.amount;
568
+ this.storageAdapter.updateApiKeyBalance(
569
+ apiKeyEntry.baseUrl,
570
+ balanceSat
571
+ );
572
+ }
573
+ } catch {
574
+ }
575
+ const refreshedEntry = this.storageAdapter.getApiKey(
576
+ apiKeyEntry.baseUrl
577
+ );
578
+ if (!refreshedEntry) continue;
538
579
  const refundResult = await this.balanceManager.refundApiKey({
539
580
  mintUrl,
540
581
  baseUrl: apiKeyEntry.baseUrl,
541
- apiKey: apiKeyEntryFull.key,
582
+ apiKey: refreshedEntry.key,
542
583
  forceRefund
543
584
  });
544
585
  if (refundResult.success) {
545
586
  this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);
546
587
  } else {
547
- this.storageAdapter.updateApiKeyBalance(
548
- apiKeyEntry.baseUrl,
549
- apiKeyEntry.amount
588
+ const currentEntry = this.storageAdapter.getApiKey(
589
+ apiKeyEntry.baseUrl
550
590
  );
591
+ if (currentEntry) {
592
+ this.storageAdapter.updateApiKeyBalance(
593
+ apiKeyEntry.baseUrl,
594
+ currentEntry.balance
595
+ );
596
+ }
551
597
  }
552
598
  results.push({
553
599
  baseUrl: apiKeyEntry.baseUrl,
@@ -614,10 +660,11 @@ var CashuSpender = class {
614
660
 
615
661
  // wallet/BalanceManager.ts
616
662
  var BalanceManager = class _BalanceManager {
617
- constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender) {
663
+ constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender, logger) {
618
664
  this.walletAdapter = walletAdapter;
619
665
  this.storageAdapter = storageAdapter;
620
666
  this.providerRegistry = providerRegistry;
667
+ this.logger = (logger ?? consoleLogger).child("BalanceManager");
621
668
  if (cashuSpender) {
622
669
  this.cashuSpender = cashuSpender;
623
670
  } else {
@@ -634,6 +681,7 @@ var BalanceManager = class _BalanceManager {
634
681
  providerWalletOps = /* @__PURE__ */ new Map();
635
682
  /** Cooldown (ms) between opposite operations on the same provider */
636
683
  static PROVIDER_WALLET_COOLDOWN_MS = 1e4;
684
+ logger;
637
685
  /**
638
686
  * Check whether a wallet operation (topup/refund) may run for a provider.
639
687
  * Returns the reason when blocked.
@@ -708,7 +756,7 @@ var BalanceManager = class _BalanceManager {
708
756
  const { mintUrl, baseUrl, apiKey, forceRefund } = options;
709
757
  const guard = this._canRunProviderWalletOperation(baseUrl, "refund");
710
758
  if (!guard.allowed) {
711
- console.log(`[BalanceManager] Skipping refund for ${baseUrl} - ${guard.reason}`);
759
+ this.logger.log(`Skipping refund for ${baseUrl} - ${guard.reason}`);
712
760
  return { success: false, message: guard.reason };
713
761
  }
714
762
  this._beginProviderWalletOperation(baseUrl, "refund");
@@ -728,9 +776,7 @@ var BalanceManager = class _BalanceManager {
728
776
  if (apiKeyEntry?.lastUsed) {
729
777
  const fiveMinutesAgo = Date.now() - 5 * 60 * 1e3;
730
778
  if (apiKeyEntry.lastUsed > fiveMinutesAgo) {
731
- console.log(
732
- `[BalanceManager] Skipping refund for ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1e3)}s ago`
733
- );
779
+ this.logger.log(`Skipping refund for ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1e3)}s ago`);
734
780
  return {
735
781
  success: false,
736
782
  message: "API key was used recently, skipping refund"
@@ -756,7 +802,8 @@ var BalanceManager = class _BalanceManager {
756
802
  };
757
803
  }
758
804
  if (fetchResult.error === "No balance to refund") {
759
- return { success: false, message: "No balance to refund" };
805
+ this.storageAdapter.removeApiKey(baseUrl);
806
+ return { success: true, message: "No balance to refund, key cleaned up" };
760
807
  }
761
808
  const receiveResult = await this.cashuSpender.receiveToken(
762
809
  fetchResult.token
@@ -772,7 +819,7 @@ var BalanceManager = class _BalanceManager {
772
819
  requestId: fetchResult.requestId
773
820
  };
774
821
  } catch (error) {
775
- console.error("[BalanceManager] API key refund error", error);
822
+ this.logger.error("API key refund error", error);
776
823
  return this._handleRefundError(error, mintUrl, fetchResult?.requestId);
777
824
  }
778
825
  }
@@ -824,7 +871,7 @@ var BalanceManager = class _BalanceManager {
824
871
  };
825
872
  } catch (error) {
826
873
  clearTimeout(timeoutId);
827
- console.error("[BalanceManager.fetchRefundToken] Fetch error", error);
874
+ this.logger.error("fetchRefundToken fetch error", error);
828
875
  if (error instanceof Error) {
829
876
  if (error.name === "AbortError") {
830
877
  return {
@@ -850,7 +897,7 @@ var BalanceManager = class _BalanceManager {
850
897
  const { mintUrl, baseUrl, amount, token: providedToken } = options;
851
898
  const guard = this._canRunProviderWalletOperation(baseUrl, "topup");
852
899
  if (!guard.allowed) {
853
- console.log(`[BalanceManager] Skipping topup for ${baseUrl} - ${guard.reason}`);
900
+ this.logger.log(`Skipping topup for ${baseUrl} - ${guard.reason}`);
854
901
  return { success: false, message: guard.reason };
855
902
  }
856
903
  this._beginProviderWalletOperation(baseUrl, "topup");
@@ -887,7 +934,7 @@ var BalanceManager = class _BalanceManager {
887
934
  cashuToken = tokenResult.token;
888
935
  const topUpResult = await this._postTopUp(baseUrl, apiKey, cashuToken);
889
936
  requestId = topUpResult.requestId;
890
- console.log(topUpResult);
937
+ this.logger.log("topUpResult:", topUpResult);
891
938
  if (!topUpResult.success) {
892
939
  await this._recoverFailedTopUp(cashuToken);
893
940
  return {
@@ -903,10 +950,7 @@ var BalanceManager = class _BalanceManager {
903
950
  requestId
904
951
  };
905
952
  } catch (error) {
906
- console.log(
907
- "DEBUG",
908
- `[TopuPU] topup: Topup result for ${baseUrl}: error=${error}`
909
- );
953
+ this.logger.log(`topup error for ${baseUrl}: ${error}`);
910
954
  if (cashuToken) {
911
955
  await this._recoverFailedTopUp(cashuToken);
912
956
  }
@@ -923,13 +967,9 @@ var BalanceManager = class _BalanceManager {
923
967
  p2pkPubkey
924
968
  } = options;
925
969
  const adjustedAmount = Math.ceil(amount);
926
- console.log(
927
- `[BalanceManager.createProviderToken] Starting: baseUrl=${baseUrl}, mintUrl=${mintUrl}, amount=${amount}, adjustedAmount=${adjustedAmount}, retryCount=${retryCount}`
928
- );
970
+ this.logger.log(`createProviderToken: baseUrl=${baseUrl} mintUrl=${mintUrl} amount=${amount} adjustedAmount=${adjustedAmount} retryCount=${retryCount}`);
929
971
  if (!adjustedAmount || isNaN(adjustedAmount)) {
930
- console.error(
931
- `[BalanceManager.createProviderToken] FAILURE: Invalid amount - amount=${amount}, adjustedAmount=${adjustedAmount}`
932
- );
972
+ this.logger.error(`createProviderToken: invalid amount=${amount}`);
933
973
  return { success: false, error: "Invalid top up amount" };
934
974
  }
935
975
  const balanceState = await this.getBalanceState();
@@ -960,9 +1000,7 @@ var BalanceManager = class _BalanceManager {
960
1000
  { url: "", balance: 0 }
961
1001
  ).url
962
1002
  );
963
- console.error(
964
- `[BalanceManager.createProviderToken] FAILURE: Insufficient balance - required=${adjustedAmount}, available=${totalMintBalance + targetProviderBalance}, totalMintBalance=${totalMintBalance}, targetProviderBalance=${targetProviderBalance}, refundableProviderBalance=${refundableProviderBalance}`
965
- );
1003
+ this.logger.error(`createProviderToken: insufficient balance required=${adjustedAmount} available=${totalMintBalance + targetProviderBalance} totalMint=${totalMintBalance} targetProvider=${targetProviderBalance}`);
966
1004
  return { success: false, error: error.message };
967
1005
  }
968
1006
  const providerMints = baseUrl && this.providerRegistry ? this.providerRegistry.getProviderMints(baseUrl) : [];
@@ -998,9 +1036,7 @@ var BalanceManager = class _BalanceManager {
998
1036
  maxMintUrl = mintUrl2;
999
1037
  }
1000
1038
  }
1001
- console.error(
1002
- `[BalanceManager.createProviderToken] FAILURE: No candidate mints found - requiredAmount=${requiredAmount}, totalMintBalance=${totalMintBalance}, maxBalance=${maxBalance}, maxMintUrl=${maxMintUrl}, providerMints=${JSON.stringify(providerMints)}`
1003
- );
1039
+ this.logger.error(`createProviderToken: no candidate mints required=${requiredAmount} totalMint=${totalMintBalance} maxBalance=${maxBalance} maxMint=${maxMintUrl}`);
1004
1040
  const error = new InsufficientBalanceError(
1005
1041
  adjustedAmount,
1006
1042
  totalMintBalance,
@@ -1012,17 +1048,13 @@ var BalanceManager = class _BalanceManager {
1012
1048
  let lastError;
1013
1049
  for (const candidateMint of candidates) {
1014
1050
  try {
1015
- console.log(
1016
- `[BalanceManager.createProviderToken] Attempting mint: ${candidateMint}, amount: ${requiredAmount}`
1017
- );
1051
+ this.logger.log(`createProviderToken: attempting mint=${candidateMint} amount=${requiredAmount}`);
1018
1052
  const token = await this.walletAdapter.sendToken(
1019
1053
  candidateMint,
1020
1054
  requiredAmount,
1021
1055
  p2pkPubkey
1022
1056
  );
1023
- console.log(
1024
- `[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])])))}`
1025
- );
1057
+ this.logger.log(`createProviderToken: success from mint=${candidateMint}`);
1026
1058
  return {
1027
1059
  success: true,
1028
1060
  token,
@@ -1031,15 +1063,11 @@ var BalanceManager = class _BalanceManager {
1031
1063
  };
1032
1064
  } catch (error) {
1033
1065
  const errorMsg = error instanceof Error ? error.message : String(error);
1034
- console.error(
1035
- `[BalanceManager.createProviderToken] FAILURE: Mint ${candidateMint} failed with error: ${errorMsg}`
1036
- );
1066
+ this.logger.error(`createProviderToken: mint=${candidateMint} failed: ${errorMsg}`);
1037
1067
  if (error instanceof Error) {
1038
1068
  lastError = errorMsg;
1039
1069
  if (isNetworkErrorMessage(error.message)) {
1040
- console.warn(
1041
- `[BalanceManager.createProviderToken] Network error from ${candidateMint}, trying next mint...`
1042
- );
1070
+ this.logger.warn(`createProviderToken: network error from ${candidateMint}, trying next mint...`);
1043
1071
  continue;
1044
1072
  }
1045
1073
  }
@@ -1049,9 +1077,7 @@ var BalanceManager = class _BalanceManager {
1049
1077
  };
1050
1078
  }
1051
1079
  }
1052
- console.error(
1053
- `[BalanceManager.createProviderToken] FAILURE: All candidate mints exhausted - lastError=${lastError}, candidates=${JSON.stringify(candidates)}`
1054
- );
1080
+ this.logger.error(`createProviderToken: all candidate mints exhausted lastError=${lastError}`);
1055
1081
  return {
1056
1082
  success: false,
1057
1083
  error: lastError || "All candidate mints failed while creating top up token"
@@ -1166,7 +1192,7 @@ var BalanceManager = class _BalanceManager {
1166
1192
  return { success: true, requestId };
1167
1193
  } catch (error) {
1168
1194
  clearTimeout(timeoutId);
1169
- console.error("[BalanceManager._postTopUp] Fetch error", error);
1195
+ this.logger.error("_postTopUp fetch error", error);
1170
1196
  if (error instanceof Error) {
1171
1197
  if (error.name === "AbortError") {
1172
1198
  return {
@@ -1192,10 +1218,7 @@ var BalanceManager = class _BalanceManager {
1192
1218
  try {
1193
1219
  await this.cashuSpender.receiveToken(cashuToken);
1194
1220
  } catch (error) {
1195
- console.error(
1196
- "[BalanceManager._recoverFailedTopUp] Failed to recover token",
1197
- error
1198
- );
1221
+ this.logger.error("_recoverFailedTopUp: failed to recover token", error);
1199
1222
  }
1200
1223
  }
1201
1224
  /**
@@ -1248,9 +1271,9 @@ var BalanceManager = class _BalanceManager {
1248
1271
  apiKey: data.api_key
1249
1272
  };
1250
1273
  } else {
1251
- console.log(response.status);
1274
+ this.logger.warn(`getTokenBalance: status=${response.status}`);
1252
1275
  const data = await response.json();
1253
- console.log("FAILED ", data);
1276
+ this.logger.warn("getTokenBalance: FAILED", data);
1254
1277
  const isInvalidApiKey = response.status === 401 && data?.detail?.error?.code === "invalid_api_key" && data?.detail?.error?.message?.includes("proofs already spent");
1255
1278
  return {
1256
1279
  amount: -1,
@@ -1261,7 +1284,7 @@ var BalanceManager = class _BalanceManager {
1261
1284
  };
1262
1285
  }
1263
1286
  } catch (error) {
1264
- console.error("ERRORR IN RESTPONSE", error);
1287
+ this.logger.error("getTokenBalance error", error);
1265
1288
  }
1266
1289
  return { amount: -1, reserved: 0, unit: "sat", apiKey: "" };
1267
1290
  }