@routstr/sdk 0.2.5 → 0.2.7
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/README.md +1 -2
- package/dist/client/index.d.mts +34 -6
- package/dist/client/index.d.ts +34 -6
- package/dist/client/index.js +773 -479
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +773 -479
- package/dist/client/index.mjs.map +1 -1
- package/dist/discovery/index.js +1 -1
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/index.mjs +1 -1
- package/dist/discovery/index.mjs.map +1 -1
- package/dist/index.d.mts +21 -9
- package/dist/index.d.ts +21 -9
- package/dist/index.js +897 -558
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +895 -559
- package/dist/index.mjs.map +1 -1
- package/dist/{interfaces-CluftN4z.d.ts → interfaces-B62Rw-dd.d.ts} +19 -14
- package/dist/{interfaces-C6Dr6hKy.d.mts → interfaces-C5fLD3jB.d.mts} +19 -14
- package/dist/storage/index.d.mts +39 -162
- package/dist/storage/index.d.ts +39 -162
- package/dist/storage/index.js +529 -193
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/index.mjs +527 -194
- package/dist/storage/index.mjs.map +1 -1
- package/dist/store-DGeLPv9E.d.mts +172 -0
- package/dist/store-h7m23ffq.d.ts +172 -0
- package/dist/wallet/index.d.mts +26 -26
- package/dist/wallet/index.d.ts +26 -26
- package/dist/wallet/index.js +143 -271
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +143 -271
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/wallet/index.mjs
CHANGED
|
@@ -120,13 +120,8 @@ var CashuSpender = class {
|
|
|
120
120
|
normalizedMintBalances[url] = balanceInSats;
|
|
121
121
|
totalMintBalance += balanceInSats;
|
|
122
122
|
}
|
|
123
|
-
const pendingDistribution = this.storageAdapter.getCachedTokenDistribution();
|
|
124
123
|
const providerBalances = {};
|
|
125
124
|
let totalProviderBalance = 0;
|
|
126
|
-
for (const pending of pendingDistribution) {
|
|
127
|
-
providerBalances[pending.baseUrl] = (providerBalances[pending.baseUrl] || 0) + pending.amount;
|
|
128
|
-
totalProviderBalance += pending.amount;
|
|
129
|
-
}
|
|
130
125
|
const apiKeys = this.storageAdapter.getAllApiKeys();
|
|
131
126
|
for (const apiKey of apiKeys) {
|
|
132
127
|
if (!providerBalances[apiKey.baseUrl]) {
|
|
@@ -347,27 +342,11 @@ var CashuSpender = class {
|
|
|
347
342
|
};
|
|
348
343
|
}
|
|
349
344
|
}
|
|
350
|
-
if (token
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
this._log(
|
|
356
|
-
"DEBUG",
|
|
357
|
-
`[CashuSpender] _spendInternal: Token already exists for ${baseUrl}, receiving newly created token and using existing`
|
|
358
|
-
);
|
|
359
|
-
const receiveResult = await this.receiveToken(token);
|
|
360
|
-
if (receiveResult.success) {
|
|
361
|
-
this._log(
|
|
362
|
-
"DEBUG",
|
|
363
|
-
`[CashuSpender] _spendInternal: Token restored successfully, amount=${receiveResult.amount}`
|
|
364
|
-
);
|
|
365
|
-
}
|
|
366
|
-
token = this.storageAdapter.getToken(baseUrl);
|
|
367
|
-
} else {
|
|
368
|
-
throw error;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
345
|
+
if (token) {
|
|
346
|
+
this._log(
|
|
347
|
+
"DEBUG",
|
|
348
|
+
`[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`
|
|
349
|
+
);
|
|
371
350
|
}
|
|
372
351
|
this._logTransaction("spend", {
|
|
373
352
|
amount: spentAmount,
|
|
@@ -388,19 +367,19 @@ var CashuSpender = class {
|
|
|
388
367
|
};
|
|
389
368
|
}
|
|
390
369
|
/**
|
|
391
|
-
* Try to reuse an existing
|
|
370
|
+
* Try to reuse an existing API key
|
|
392
371
|
*/
|
|
393
372
|
async _tryReuseToken(baseUrl, amount, mintUrl) {
|
|
394
|
-
const
|
|
395
|
-
if (!
|
|
396
|
-
const
|
|
397
|
-
const balanceForBaseUrl =
|
|
398
|
-
this._log("DEBUG", "
|
|
373
|
+
const apiKeyEntry = this.storageAdapter.getApiKey(baseUrl);
|
|
374
|
+
if (!apiKeyEntry) return null;
|
|
375
|
+
const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();
|
|
376
|
+
const balanceForBaseUrl = apiKeyDistribution.find((b) => b.baseUrl === baseUrl)?.amount || 0;
|
|
377
|
+
this._log("DEBUG", "Reusing API key", balanceForBaseUrl, amount);
|
|
399
378
|
if (balanceForBaseUrl > amount) {
|
|
400
379
|
const units = this.walletAdapter.getMintUnits();
|
|
401
380
|
const unit = units[mintUrl] || "sat";
|
|
402
381
|
return {
|
|
403
|
-
token:
|
|
382
|
+
token: apiKeyEntry.key,
|
|
404
383
|
status: "success",
|
|
405
384
|
balance: balanceForBaseUrl,
|
|
406
385
|
unit
|
|
@@ -411,7 +390,8 @@ var CashuSpender = class {
|
|
|
411
390
|
const topUpResult = await this.balanceManager.topUp({
|
|
412
391
|
mintUrl,
|
|
413
392
|
baseUrl,
|
|
414
|
-
amount: topUpAmount
|
|
393
|
+
amount: topUpAmount,
|
|
394
|
+
token: apiKeyEntry.key
|
|
415
395
|
});
|
|
416
396
|
this._log("DEBUG", "TOPUP ", topUpResult);
|
|
417
397
|
if (topUpResult.success && topUpResult.toppedUpAmount) {
|
|
@@ -425,7 +405,7 @@ var CashuSpender = class {
|
|
|
425
405
|
status: "success"
|
|
426
406
|
});
|
|
427
407
|
return {
|
|
428
|
-
token:
|
|
408
|
+
token: apiKeyEntry.key,
|
|
429
409
|
status: "success",
|
|
430
410
|
balance: newBalance,
|
|
431
411
|
unit
|
|
@@ -433,84 +413,131 @@ var CashuSpender = class {
|
|
|
433
413
|
}
|
|
434
414
|
const providerBalance = await this._getProviderTokenBalance(
|
|
435
415
|
baseUrl,
|
|
436
|
-
|
|
416
|
+
apiKeyEntry.key
|
|
437
417
|
);
|
|
438
418
|
this._log("DEBUG", providerBalance);
|
|
439
419
|
if (providerBalance <= 0) {
|
|
440
|
-
this.storageAdapter.
|
|
420
|
+
this.storageAdapter.removeApiKey(baseUrl);
|
|
441
421
|
}
|
|
442
422
|
}
|
|
443
423
|
return null;
|
|
444
424
|
}
|
|
445
425
|
/**
|
|
446
|
-
* Refund
|
|
426
|
+
* Refund all xcashu tokens from storage by calling the provider's refund endpoint.
|
|
427
|
+
* The xcashu token acts as an API key to claim the refund, and the response contains
|
|
428
|
+
* the actual refunded Cashu token which is then received into the wallet.
|
|
429
|
+
* @param mintUrl - The mint URL for receiving tokens
|
|
430
|
+
* @param excludeBaseUrls - Base URLs to exclude from refund (optional)
|
|
431
|
+
* @returns Results for each xcashu token refund attempt
|
|
447
432
|
*/
|
|
448
|
-
async
|
|
433
|
+
async refundXcashuTokens(mintUrl, excludeBaseUrls) {
|
|
449
434
|
const results = [];
|
|
450
|
-
const
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
apiKey: apiKeyEntryFull.key,
|
|
499
|
-
forceRefund
|
|
500
|
-
});
|
|
501
|
-
if (refundResult.success) {
|
|
502
|
-
this.storageAdapter.updateApiKeyBalance(apiKeyEntry.baseUrl, 0);
|
|
435
|
+
const xcashuTokens = this.storageAdapter.getXcashuTokens();
|
|
436
|
+
const excludedUrls = new Set(excludeBaseUrls || []);
|
|
437
|
+
for (const [baseUrl, tokens] of Object.entries(xcashuTokens)) {
|
|
438
|
+
if (excludedUrls.has(baseUrl)) continue;
|
|
439
|
+
for (const xcashuToken of tokens) {
|
|
440
|
+
try {
|
|
441
|
+
if (!this.balanceManager) {
|
|
442
|
+
throw new Error("BalanceManager not available for xcashu refund");
|
|
443
|
+
}
|
|
444
|
+
const fetchResult = await this.balanceManager.fetchRefundToken(
|
|
445
|
+
baseUrl,
|
|
446
|
+
xcashuToken.token,
|
|
447
|
+
true
|
|
448
|
+
);
|
|
449
|
+
if (!fetchResult.success || !fetchResult.token) {
|
|
450
|
+
throw new Error(
|
|
451
|
+
fetchResult.error || "Failed to fetch refund token from provider"
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
const receiveResult = await this.receiveToken(fetchResult.token);
|
|
455
|
+
if (receiveResult.success) {
|
|
456
|
+
this.storageAdapter.removeXcashuToken(baseUrl, xcashuToken.token);
|
|
457
|
+
results.push({
|
|
458
|
+
baseUrl,
|
|
459
|
+
token: xcashuToken.token,
|
|
460
|
+
success: true
|
|
461
|
+
});
|
|
462
|
+
this._log(
|
|
463
|
+
"DEBUG",
|
|
464
|
+
`[CashuSpender] refundXcashuTokens: Successfully refunded xcashu token for ${baseUrl}, amount=${receiveResult.amount}`
|
|
465
|
+
);
|
|
466
|
+
} else {
|
|
467
|
+
const currentTryCount = xcashuToken.tryCount ?? 0;
|
|
468
|
+
const newTryCount = currentTryCount + 1;
|
|
469
|
+
this.storageAdapter.updateXcashuTokenTryCount(
|
|
470
|
+
xcashuToken.token,
|
|
471
|
+
newTryCount
|
|
472
|
+
);
|
|
473
|
+
results.push({
|
|
474
|
+
baseUrl,
|
|
475
|
+
token: xcashuToken.token,
|
|
476
|
+
success: false,
|
|
477
|
+
error: receiveResult.message ?? "Refund failed"
|
|
478
|
+
});
|
|
479
|
+
this._log(
|
|
480
|
+
"DEBUG",
|
|
481
|
+
`[CashuSpender] refundXcashuTokens: Failed to receive refund token for ${baseUrl}, incremented tryCount to ${newTryCount}`
|
|
482
|
+
);
|
|
503
483
|
}
|
|
484
|
+
} catch (error) {
|
|
485
|
+
const currentTryCount = xcashuToken.tryCount ?? 0;
|
|
486
|
+
const newTryCount = currentTryCount + 1;
|
|
487
|
+
this.storageAdapter.updateXcashuTokenTryCount(
|
|
488
|
+
xcashuToken.token,
|
|
489
|
+
newTryCount
|
|
490
|
+
);
|
|
491
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
504
492
|
results.push({
|
|
505
|
-
baseUrl
|
|
506
|
-
|
|
493
|
+
baseUrl,
|
|
494
|
+
token: xcashuToken.token,
|
|
495
|
+
success: false,
|
|
496
|
+
error: errorMessage
|
|
507
497
|
});
|
|
498
|
+
this._log(
|
|
499
|
+
"ERROR",
|
|
500
|
+
`[CashuSpender] refundXcashuTokens: Exception during refund for ${baseUrl}: ${errorMessage}, incremented tryCount to ${newTryCount}`
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return results;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Refund specific providers without retrying spend
|
|
509
|
+
*/
|
|
510
|
+
async refundProviders(mintUrl, forceRefund) {
|
|
511
|
+
const results = [];
|
|
512
|
+
const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();
|
|
513
|
+
for (const apiKeyEntry of apiKeyDistribution) {
|
|
514
|
+
const apiKeyEntryFull = this.storageAdapter.getApiKey(
|
|
515
|
+
apiKeyEntry.baseUrl
|
|
516
|
+
);
|
|
517
|
+
if (apiKeyEntryFull && this.balanceManager) {
|
|
518
|
+
const refundResult = await this.balanceManager.refundApiKey({
|
|
519
|
+
mintUrl,
|
|
520
|
+
baseUrl: apiKeyEntry.baseUrl,
|
|
521
|
+
apiKey: apiKeyEntryFull.key,
|
|
522
|
+
forceRefund
|
|
523
|
+
});
|
|
524
|
+
if (refundResult.success) {
|
|
525
|
+
this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);
|
|
508
526
|
} else {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
527
|
+
this.storageAdapter.updateApiKeyBalance(
|
|
528
|
+
apiKeyEntry.baseUrl,
|
|
529
|
+
apiKeyEntry.amount
|
|
530
|
+
);
|
|
513
531
|
}
|
|
532
|
+
results.push({
|
|
533
|
+
baseUrl: apiKeyEntry.baseUrl,
|
|
534
|
+
success: refundResult.success
|
|
535
|
+
});
|
|
536
|
+
} else {
|
|
537
|
+
results.push({
|
|
538
|
+
baseUrl: apiKeyEntry.baseUrl,
|
|
539
|
+
success: false
|
|
540
|
+
});
|
|
514
541
|
}
|
|
515
542
|
}
|
|
516
543
|
return results;
|
|
@@ -595,13 +622,8 @@ var BalanceManager = class {
|
|
|
595
622
|
normalizedMintBalances[url] = balanceInSats;
|
|
596
623
|
totalMintBalance += balanceInSats;
|
|
597
624
|
}
|
|
598
|
-
const pendingDistribution = this.storageAdapter.getCachedTokenDistribution();
|
|
599
625
|
const providerBalances = {};
|
|
600
626
|
let totalProviderBalance = 0;
|
|
601
|
-
for (const pending of pendingDistribution) {
|
|
602
|
-
providerBalances[pending.baseUrl] = (providerBalances[pending.baseUrl] || 0) + pending.amount;
|
|
603
|
-
totalProviderBalance += pending.amount;
|
|
604
|
-
}
|
|
605
627
|
const apiKeys = this.storageAdapter.getAllApiKeys();
|
|
606
628
|
for (const apiKey of apiKeys) {
|
|
607
629
|
if (!providerBalances[apiKey.baseUrl]) {
|
|
@@ -616,57 +638,6 @@ var BalanceManager = class {
|
|
|
616
638
|
mintBalances: normalizedMintBalances
|
|
617
639
|
};
|
|
618
640
|
}
|
|
619
|
-
/**
|
|
620
|
-
* Unified refund - handles both NIP-60 and legacy wallet refunds
|
|
621
|
-
*/
|
|
622
|
-
async refund(options) {
|
|
623
|
-
const { mintUrl, baseUrl, token: providedToken } = options;
|
|
624
|
-
const storedToken = providedToken || this.storageAdapter.getToken(baseUrl);
|
|
625
|
-
if (!storedToken) {
|
|
626
|
-
console.log("[BalanceManager] No token to refund, returning early");
|
|
627
|
-
return { success: true, message: "No API key to refund" };
|
|
628
|
-
}
|
|
629
|
-
let fetchResult;
|
|
630
|
-
try {
|
|
631
|
-
fetchResult = await this._fetchRefundToken(baseUrl, storedToken);
|
|
632
|
-
if (!fetchResult.success) {
|
|
633
|
-
return {
|
|
634
|
-
success: false,
|
|
635
|
-
message: fetchResult.error || "Refund failed",
|
|
636
|
-
requestId: fetchResult.requestId
|
|
637
|
-
};
|
|
638
|
-
}
|
|
639
|
-
if (!fetchResult.token) {
|
|
640
|
-
return {
|
|
641
|
-
success: false,
|
|
642
|
-
message: "No token received from refund",
|
|
643
|
-
requestId: fetchResult.requestId
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
if (fetchResult.error === "No balance to refund") {
|
|
647
|
-
console.log(
|
|
648
|
-
"[BalanceManager] No balance to refund, removing stored token"
|
|
649
|
-
);
|
|
650
|
-
this.storageAdapter.removeToken(baseUrl);
|
|
651
|
-
return { success: true, message: "No balance to refund" };
|
|
652
|
-
}
|
|
653
|
-
const receiveResult = await this.cashuSpender.receiveToken(
|
|
654
|
-
fetchResult.token
|
|
655
|
-
);
|
|
656
|
-
const totalAmountMsat = receiveResult.unit === "msat" ? receiveResult.amount : receiveResult.amount * 1e3;
|
|
657
|
-
if (!providedToken) {
|
|
658
|
-
this.storageAdapter.removeToken(baseUrl);
|
|
659
|
-
}
|
|
660
|
-
return {
|
|
661
|
-
success: receiveResult.success,
|
|
662
|
-
refundedAmount: totalAmountMsat,
|
|
663
|
-
requestId: fetchResult.requestId
|
|
664
|
-
};
|
|
665
|
-
} catch (error) {
|
|
666
|
-
console.error("[BalanceManager] Refund error", error);
|
|
667
|
-
return this._handleRefundError(error, mintUrl, fetchResult?.requestId);
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
641
|
/**
|
|
671
642
|
* Refund API key balance - convert remaining API key balance to cashu token
|
|
672
643
|
* @param options - Refund options including forceRefund flag
|
|
@@ -694,7 +665,7 @@ var BalanceManager = class {
|
|
|
694
665
|
}
|
|
695
666
|
let fetchResult;
|
|
696
667
|
try {
|
|
697
|
-
fetchResult = await this.
|
|
668
|
+
fetchResult = await this.fetchRefundToken(baseUrl, apiKey);
|
|
698
669
|
if (!fetchResult.success) {
|
|
699
670
|
return {
|
|
700
671
|
success: false,
|
|
@@ -730,9 +701,9 @@ var BalanceManager = class {
|
|
|
730
701
|
}
|
|
731
702
|
}
|
|
732
703
|
/**
|
|
733
|
-
* Fetch refund token from provider API using API key authentication
|
|
704
|
+
* Fetch refund token from provider API using API key (or xcashu token) authentication
|
|
734
705
|
*/
|
|
735
|
-
async
|
|
706
|
+
async fetchRefundToken(baseUrl, apiKeyOrToken, xCashu = false) {
|
|
736
707
|
if (!baseUrl) {
|
|
737
708
|
return {
|
|
738
709
|
success: false,
|
|
@@ -746,12 +717,17 @@ var BalanceManager = class {
|
|
|
746
717
|
controller.abort();
|
|
747
718
|
}, 6e4);
|
|
748
719
|
try {
|
|
720
|
+
const headers = {
|
|
721
|
+
"Content-Type": "application/json"
|
|
722
|
+
};
|
|
723
|
+
if (xCashu) {
|
|
724
|
+
headers["X-Cashu"] = apiKeyOrToken;
|
|
725
|
+
} else {
|
|
726
|
+
headers["Authorization"] = `Bearer ${apiKeyOrToken}`;
|
|
727
|
+
}
|
|
749
728
|
const response = await fetch(url, {
|
|
750
729
|
method: "POST",
|
|
751
|
-
headers
|
|
752
|
-
Authorization: `Bearer ${apiKey}`,
|
|
753
|
-
"Content-Type": "application/json"
|
|
754
|
-
},
|
|
730
|
+
headers,
|
|
755
731
|
signal: controller.signal
|
|
756
732
|
});
|
|
757
733
|
clearTimeout(timeoutId);
|
|
@@ -772,10 +748,7 @@ var BalanceManager = class {
|
|
|
772
748
|
};
|
|
773
749
|
} catch (error) {
|
|
774
750
|
clearTimeout(timeoutId);
|
|
775
|
-
console.error(
|
|
776
|
-
"[BalanceManager._fetchRefundTokenWithApiKey] Fetch error",
|
|
777
|
-
error
|
|
778
|
-
);
|
|
751
|
+
console.error("[BalanceManager.fetchRefundToken] Fetch error", error);
|
|
779
752
|
if (error instanceof Error) {
|
|
780
753
|
if (error.name === "AbortError") {
|
|
781
754
|
return {
|
|
@@ -802,8 +775,9 @@ var BalanceManager = class {
|
|
|
802
775
|
if (!amount || amount <= 0) {
|
|
803
776
|
return { success: false, message: "Invalid top up amount" };
|
|
804
777
|
}
|
|
805
|
-
const
|
|
806
|
-
|
|
778
|
+
const apiKeyEntry = providedToken ? null : this.storageAdapter.getApiKey(baseUrl);
|
|
779
|
+
const apiKey = providedToken || apiKeyEntry?.key;
|
|
780
|
+
if (!apiKey) {
|
|
807
781
|
return { success: false, message: "No API key available for top up" };
|
|
808
782
|
}
|
|
809
783
|
let cashuToken = null;
|
|
@@ -821,11 +795,7 @@ var BalanceManager = class {
|
|
|
821
795
|
};
|
|
822
796
|
}
|
|
823
797
|
cashuToken = tokenResult.token;
|
|
824
|
-
const topUpResult = await this._postTopUp(
|
|
825
|
-
baseUrl,
|
|
826
|
-
storedToken,
|
|
827
|
-
cashuToken
|
|
828
|
-
);
|
|
798
|
+
const topUpResult = await this._postTopUp(baseUrl, apiKey, cashuToken);
|
|
829
799
|
requestId = topUpResult.requestId;
|
|
830
800
|
console.log(topUpResult);
|
|
831
801
|
if (!topUpResult.success) {
|
|
@@ -1038,38 +1008,11 @@ var BalanceManager = class {
|
|
|
1038
1008
|
return candidates;
|
|
1039
1009
|
}
|
|
1040
1010
|
async _refundOtherProvidersForTopUp(baseUrl, mintUrl, retryCount) {
|
|
1041
|
-
const pendingDistribution = this.storageAdapter.getCachedTokenDistribution();
|
|
1042
1011
|
const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();
|
|
1043
1012
|
const forceRefund = retryCount >= 2;
|
|
1044
|
-
const toRefund = pendingDistribution.filter(
|
|
1045
|
-
(pending) => pending.baseUrl !== baseUrl
|
|
1046
|
-
);
|
|
1047
1013
|
const apiKeysToRefund = apiKeyDistribution.filter(
|
|
1048
1014
|
(apiKey) => apiKey.baseUrl !== baseUrl && apiKey.amount > 0
|
|
1049
1015
|
);
|
|
1050
|
-
const tokenRefundResults = await Promise.allSettled(
|
|
1051
|
-
toRefund.map(async (pending) => {
|
|
1052
|
-
const token = this.storageAdapter.getToken(pending.baseUrl);
|
|
1053
|
-
if (!token) {
|
|
1054
|
-
return { baseUrl: pending.baseUrl, success: false };
|
|
1055
|
-
}
|
|
1056
|
-
const tokenBalance = await this.getTokenBalance(token, pending.baseUrl);
|
|
1057
|
-
if (tokenBalance.reserved > 0) {
|
|
1058
|
-
return { baseUrl: pending.baseUrl, success: false };
|
|
1059
|
-
}
|
|
1060
|
-
const result = await this.refund({
|
|
1061
|
-
mintUrl,
|
|
1062
|
-
baseUrl: pending.baseUrl,
|
|
1063
|
-
token
|
|
1064
|
-
});
|
|
1065
|
-
return { baseUrl: pending.baseUrl, success: result.success };
|
|
1066
|
-
})
|
|
1067
|
-
);
|
|
1068
|
-
for (const result of tokenRefundResults) {
|
|
1069
|
-
if (result.status === "fulfilled" && result.value.success) {
|
|
1070
|
-
this.storageAdapter.removeToken(result.value.baseUrl);
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
1016
|
const apiKeyRefundResults = await Promise.allSettled(
|
|
1074
1017
|
apiKeysToRefund.map(async (apiKeyEntry) => {
|
|
1075
1018
|
const fullApiKeyEntry = this.storageAdapter.getApiKey(
|
|
@@ -1093,77 +1036,6 @@ var BalanceManager = class {
|
|
|
1093
1036
|
}
|
|
1094
1037
|
}
|
|
1095
1038
|
}
|
|
1096
|
-
/**
|
|
1097
|
-
* Fetch refund token from provider API
|
|
1098
|
-
*/
|
|
1099
|
-
async _fetchRefundToken(baseUrl, storedToken) {
|
|
1100
|
-
if (!baseUrl) {
|
|
1101
|
-
return {
|
|
1102
|
-
success: false,
|
|
1103
|
-
error: "No base URL configured"
|
|
1104
|
-
};
|
|
1105
|
-
}
|
|
1106
|
-
const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
|
1107
|
-
const url = `${normalizedBaseUrl}v1/wallet/refund`;
|
|
1108
|
-
const controller = new AbortController();
|
|
1109
|
-
const timeoutId = setTimeout(() => {
|
|
1110
|
-
controller.abort();
|
|
1111
|
-
}, 6e4);
|
|
1112
|
-
try {
|
|
1113
|
-
const response = await fetch(url, {
|
|
1114
|
-
method: "POST",
|
|
1115
|
-
headers: {
|
|
1116
|
-
Authorization: `Bearer ${storedToken}`,
|
|
1117
|
-
"Content-Type": "application/json"
|
|
1118
|
-
},
|
|
1119
|
-
signal: controller.signal
|
|
1120
|
-
});
|
|
1121
|
-
clearTimeout(timeoutId);
|
|
1122
|
-
const requestId = response.headers.get("x-routstr-request-id") || void 0;
|
|
1123
|
-
if (!response.ok) {
|
|
1124
|
-
const errorData = await response.json().catch(() => ({}));
|
|
1125
|
-
if (response.status === 400 && errorData?.detail === "No balance to refund") {
|
|
1126
|
-
this.storageAdapter.removeToken(baseUrl);
|
|
1127
|
-
return {
|
|
1128
|
-
success: false,
|
|
1129
|
-
requestId,
|
|
1130
|
-
error: "No balance to refund"
|
|
1131
|
-
};
|
|
1132
|
-
}
|
|
1133
|
-
return {
|
|
1134
|
-
success: false,
|
|
1135
|
-
requestId,
|
|
1136
|
-
error: `Refund request failed with status ${response.status}: ${errorData?.detail || response.statusText}`
|
|
1137
|
-
};
|
|
1138
|
-
}
|
|
1139
|
-
const data = await response.json();
|
|
1140
|
-
console.log("refund rsule", data);
|
|
1141
|
-
return {
|
|
1142
|
-
success: true,
|
|
1143
|
-
token: data.token,
|
|
1144
|
-
requestId
|
|
1145
|
-
};
|
|
1146
|
-
} catch (error) {
|
|
1147
|
-
clearTimeout(timeoutId);
|
|
1148
|
-
console.error("[BalanceManager._fetchRefundToken] Fetch error", error);
|
|
1149
|
-
if (error instanceof Error) {
|
|
1150
|
-
if (error.name === "AbortError") {
|
|
1151
|
-
return {
|
|
1152
|
-
success: false,
|
|
1153
|
-
error: "Request timed out after 1 minute"
|
|
1154
|
-
};
|
|
1155
|
-
}
|
|
1156
|
-
return {
|
|
1157
|
-
success: false,
|
|
1158
|
-
error: error.message
|
|
1159
|
-
};
|
|
1160
|
-
}
|
|
1161
|
-
return {
|
|
1162
|
-
success: false,
|
|
1163
|
-
error: "Unknown error occurred during refund request"
|
|
1164
|
-
};
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
1039
|
/**
|
|
1168
1040
|
* Post topup request to provider API
|
|
1169
1041
|
*/
|
|
@@ -1289,7 +1161,7 @@ var BalanceManager = class {
|
|
|
1289
1161
|
console.log(response.status);
|
|
1290
1162
|
const data = await response.json();
|
|
1291
1163
|
console.log("FAILED ", data);
|
|
1292
|
-
const isInvalidApiKey = response.status === 401 && data?.code === "invalid_api_key" && data?.message?.includes("proofs already spent");
|
|
1164
|
+
const isInvalidApiKey = response.status === 401 && data?.detail?.error?.code === "invalid_api_key" && data?.detail?.error?.message?.includes("proofs already spent");
|
|
1293
1165
|
return {
|
|
1294
1166
|
amount: -1,
|
|
1295
1167
|
reserved: data.reserved ?? 0,
|