@routstr/sdk 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -106,6 +106,9 @@ var CashuSpender = class {
106
106
  return result;
107
107
  }
108
108
  async _getBalanceState() {
109
+ if (this.balanceManager) {
110
+ return this.balanceManager.getBalanceState();
111
+ }
109
112
  const mintBalances = await this.walletAdapter.getBalances();
110
113
  const units = this.walletAdapter.getMintUnits();
111
114
  let totalMintBalance = 0;
@@ -121,15 +124,16 @@ var CashuSpender = class {
121
124
  const providerBalances = {};
122
125
  let totalProviderBalance = 0;
123
126
  for (const pending of pendingDistribution) {
124
- providerBalances[pending.baseUrl] = pending.amount;
127
+ providerBalances[pending.baseUrl] = (providerBalances[pending.baseUrl] || 0) + pending.amount;
125
128
  totalProviderBalance += pending.amount;
126
129
  }
127
130
  const apiKeys = this.storageAdapter.getAllApiKeys();
128
131
  for (const apiKey of apiKeys) {
129
132
  if (!providerBalances[apiKey.baseUrl]) {
130
- providerBalances[apiKey.baseUrl] = apiKey.balance;
131
- totalProviderBalance += apiKey.balance;
133
+ providerBalances[apiKey.baseUrl] = 0;
132
134
  }
135
+ providerBalances[apiKey.baseUrl] += apiKey.balance;
136
+ totalProviderBalance += apiKey.balance;
133
137
  }
134
138
  return {
135
139
  totalBalance: totalMintBalance + totalProviderBalance,
@@ -278,25 +282,12 @@ var CashuSpender = class {
278
282
  `[CashuSpender] _spendInternal: Could not reuse token, will create new token`
279
283
  );
280
284
  }
281
- const balances = await this.walletAdapter.getBalances();
282
- const units = this.walletAdapter.getMintUnits();
283
- let totalBalance = 0;
284
- for (const url in balances) {
285
- const balance = balances[url];
286
- const unit = units[url];
287
- const balanceInSats = getBalanceInSats(balance, unit);
288
- totalBalance += balanceInSats;
289
- }
290
- const pendingDistribution = this.storageAdapter.getCachedTokenDistribution();
291
- const totalPending = pendingDistribution.reduce(
292
- (sum, item) => sum + item.amount,
293
- 0
294
- );
285
+ const balanceState = await this._getBalanceState();
286
+ const totalAvailableBalance = balanceState.totalBalance;
295
287
  this._log(
296
288
  "DEBUG",
297
- `[CashuSpender] _spendInternal: totalBalance=${totalBalance}, totalPending=${totalPending}, adjustedAmount=${adjustedAmount}`
289
+ `[CashuSpender] _spendInternal: totalAvailableBalance=${totalAvailableBalance}, adjustedAmount=${adjustedAmount}`
298
290
  );
299
- const totalAvailableBalance = totalBalance + totalPending;
300
291
  if (totalAvailableBalance < adjustedAmount) {
301
292
  this._log(
302
293
  "ERROR",
@@ -304,8 +295,7 @@ var CashuSpender = class {
304
295
  );
305
296
  return this._createInsufficientBalanceError(
306
297
  adjustedAmount,
307
- balances,
308
- units,
298
+ balanceState.mintBalances,
309
299
  totalAvailableBalance
310
300
  );
311
301
  }
@@ -325,8 +315,7 @@ var CashuSpender = class {
325
315
  if ((tokenResult.error || "").includes("Insufficient balance")) {
326
316
  return this._createInsufficientBalanceError(
327
317
  adjustedAmount,
328
- balances,
329
- units,
318
+ balanceState.mintBalances,
330
319
  totalAvailableBalance
331
320
  );
332
321
  }
@@ -371,6 +360,7 @@ var CashuSpender = class {
371
360
  "DEBUG",
372
361
  `[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`
373
362
  );
363
+ const units = this.walletAdapter.getMintUnits();
374
364
  return {
375
365
  token,
376
366
  status: "success",
@@ -508,13 +498,11 @@ var CashuSpender = class {
508
498
  /**
509
499
  * Create an insufficient balance error result
510
500
  */
511
- _createInsufficientBalanceError(required, balances, units, availableBalance) {
501
+ _createInsufficientBalanceError(required, normalizedBalances, availableBalance) {
512
502
  let maxBalance = 0;
513
503
  let maxMintUrl = "";
514
- for (const mintUrl in balances) {
515
- const balance = balances[mintUrl];
516
- const unit = units[mintUrl];
517
- const balanceInSats = getBalanceInSats(balance, unit);
504
+ for (const mintUrl in normalizedBalances) {
505
+ const balanceInSats = normalizedBalances[mintUrl];
518
506
  if (balanceInSats > maxBalance) {
519
507
  maxBalance = balanceInSats;
520
508
  maxMintUrl = mintUrl;
@@ -575,6 +563,39 @@ var BalanceManager = class {
575
563
  }
576
564
  }
577
565
  cashuSpender;
566
+ async getBalanceState() {
567
+ const mintBalances = await this.walletAdapter.getBalances();
568
+ const units = this.walletAdapter.getMintUnits();
569
+ let totalMintBalance = 0;
570
+ const normalizedMintBalances = {};
571
+ for (const url in mintBalances) {
572
+ const balance = mintBalances[url];
573
+ const unit = units[url];
574
+ const balanceInSats = getBalanceInSats(balance, unit);
575
+ normalizedMintBalances[url] = balanceInSats;
576
+ totalMintBalance += balanceInSats;
577
+ }
578
+ const pendingDistribution = this.storageAdapter.getCachedTokenDistribution();
579
+ const providerBalances = {};
580
+ let totalProviderBalance = 0;
581
+ for (const pending of pendingDistribution) {
582
+ providerBalances[pending.baseUrl] = (providerBalances[pending.baseUrl] || 0) + pending.amount;
583
+ totalProviderBalance += pending.amount;
584
+ }
585
+ const apiKeys = this.storageAdapter.getAllApiKeys();
586
+ for (const apiKey of apiKeys) {
587
+ if (!providerBalances[apiKey.baseUrl]) {
588
+ providerBalances[apiKey.baseUrl] = 0;
589
+ }
590
+ providerBalances[apiKey.baseUrl] += apiKey.balance;
591
+ totalProviderBalance += apiKey.balance;
592
+ }
593
+ return {
594
+ totalBalance: totalMintBalance + totalProviderBalance,
595
+ providerBalances,
596
+ mintBalances: normalizedMintBalances
597
+ };
598
+ }
578
599
  /**
579
600
  * Unified refund - handles both NIP-60 and legacy wallet refunds
580
601
  */
@@ -804,17 +825,17 @@ var BalanceManager = class {
804
825
  if (!adjustedAmount || isNaN(adjustedAmount)) {
805
826
  return { success: false, error: "Invalid top up amount" };
806
827
  }
828
+ const balanceState = await this.getBalanceState();
807
829
  const balances = await this.walletAdapter.getBalances();
808
830
  const units = this.walletAdapter.getMintUnits();
809
- let totalMintBalance = 0;
810
- for (const url in balances) {
811
- const unit = units[url];
812
- const balanceInSats = getBalanceInSats(balances[url], unit);
813
- totalMintBalance += balanceInSats;
814
- }
815
- const pendingDistribution = this.storageAdapter.getCachedTokenDistribution();
816
- const refundablePending = pendingDistribution.filter((entry) => entry.baseUrl !== baseUrl).reduce((sum, entry) => sum + entry.amount, 0);
817
- if (totalMintBalance < adjustedAmount && totalMintBalance + refundablePending >= adjustedAmount && retryCount < 1) {
831
+ const totalMintBalance = Object.values(balanceState.mintBalances).reduce(
832
+ (sum, value) => sum + value,
833
+ 0
834
+ );
835
+ const refundableProviderBalance = Object.entries(
836
+ balanceState.providerBalances
837
+ ).filter(([providerBaseUrl]) => providerBaseUrl !== baseUrl).reduce((sum, [, value]) => sum + value, 0);
838
+ if (totalMintBalance < adjustedAmount && totalMintBalance + refundableProviderBalance >= adjustedAmount && retryCount < 1) {
818
839
  await this._refundOtherProvidersForTopUp(baseUrl, mintUrl);
819
840
  return this.createProviderToken({
820
841
  ...options,
@@ -936,10 +957,14 @@ var BalanceManager = class {
936
957
  }
937
958
  async _refundOtherProvidersForTopUp(baseUrl, mintUrl) {
938
959
  const pendingDistribution = this.storageAdapter.getCachedTokenDistribution();
960
+ const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();
939
961
  const toRefund = pendingDistribution.filter(
940
962
  (pending) => pending.baseUrl !== baseUrl
941
963
  );
942
- const refundResults = await Promise.allSettled(
964
+ const apiKeysToRefund = apiKeyDistribution.filter(
965
+ (apiKey) => apiKey.baseUrl !== baseUrl && apiKey.amount > 0
966
+ );
967
+ const tokenRefundResults = await Promise.allSettled(
943
968
  toRefund.map(async (pending) => {
944
969
  const token = this.storageAdapter.getToken(pending.baseUrl);
945
970
  if (!token) {
@@ -957,11 +982,32 @@ var BalanceManager = class {
957
982
  return { baseUrl: pending.baseUrl, success: result.success };
958
983
  })
959
984
  );
960
- for (const result of refundResults) {
985
+ for (const result of tokenRefundResults) {
961
986
  if (result.status === "fulfilled" && result.value.success) {
962
987
  this.storageAdapter.removeToken(result.value.baseUrl);
963
988
  }
964
989
  }
990
+ const apiKeyRefundResults = await Promise.allSettled(
991
+ apiKeysToRefund.map(async (apiKeyEntry) => {
992
+ const fullApiKeyEntry = this.storageAdapter.getApiKey(
993
+ apiKeyEntry.baseUrl
994
+ );
995
+ if (!fullApiKeyEntry) {
996
+ return { baseUrl: apiKeyEntry.baseUrl, success: false };
997
+ }
998
+ const result = await this.refundApiKey({
999
+ mintUrl,
1000
+ baseUrl: apiKeyEntry.baseUrl,
1001
+ apiKey: fullApiKeyEntry.key
1002
+ });
1003
+ return { baseUrl: apiKeyEntry.baseUrl, success: result.success };
1004
+ })
1005
+ );
1006
+ for (const result of apiKeyRefundResults) {
1007
+ if (result.status === "fulfilled" && result.value.success) {
1008
+ this.storageAdapter.updateApiKeyBalance(result.value.baseUrl, 0);
1009
+ }
1010
+ }
965
1011
  }
966
1012
  /**
967
1013
  * Fetch refund token from provider API