@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.
- package/dist/client/index.js +114 -41
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +114 -41
- package/dist/client/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +126 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +126 -44
- package/dist/index.mjs.map +1 -1
- package/dist/storage/index.d.mts +31 -0
- package/dist/storage/index.d.ts +31 -0
- package/dist/storage/index.js +12 -3
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/index.mjs +12 -3
- package/dist/storage/index.mjs.map +1 -1
- package/dist/wallet/index.d.mts +7 -1
- package/dist/wallet/index.d.ts +7 -1
- package/dist/wallet/index.js +85 -39
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +85 -39
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/wallet/index.mjs
CHANGED
|
@@ -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] =
|
|
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
|
|
282
|
-
const
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
501
|
+
_createInsufficientBalanceError(required, normalizedBalances, availableBalance) {
|
|
512
502
|
let maxBalance = 0;
|
|
513
503
|
let maxMintUrl = "";
|
|
514
|
-
for (const mintUrl in
|
|
515
|
-
const
|
|
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
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
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
|
|
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
|
|
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
|