@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.
- package/dist/client/index.d.mts +9 -5
- package/dist/client/index.d.ts +9 -5
- package/dist/client/index.js +107 -136
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +107 -136
- package/dist/client/index.mjs.map +1 -1
- package/dist/discovery/index.d.mts +8 -2
- package/dist/discovery/index.d.ts +8 -2
- package/dist/discovery/index.js +27 -16
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/index.mjs +27 -16
- package/dist/discovery/index.mjs.map +1 -1
- package/dist/index.d.mts +10 -8
- package/dist/index.d.ts +10 -8
- package/dist/index.js +179 -193
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +178 -194
- package/dist/index.mjs.map +1 -1
- package/dist/{interfaces-C5fLD3jB.d.mts → interfaces-Bp0Ngmqv.d.mts} +1 -1
- package/dist/{interfaces-BxDEka72.d.ts → interfaces-CIfd_phZ.d.ts} +1 -1
- package/dist/{interfaces-BWJJTCXO.d.mts → interfaces-Cxi8R4TT.d.mts} +1 -1
- package/dist/{interfaces-B62Rw-dd.d.ts → interfaces-D2FDCLyP.d.ts} +1 -1
- package/dist/storage/index.d.mts +9 -7
- package/dist/storage/index.d.ts +9 -7
- package/dist/storage/index.js +52 -37
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/index.mjs +52 -37
- package/dist/storage/index.mjs.map +1 -1
- package/dist/{store-h7m23ffq.d.ts → store-BD5zF9Hp.d.ts} +4 -4
- package/dist/{store-DGeLPv9E.d.mts → store-CBSyK2qg.d.mts} +4 -4
- package/dist/{types-BYj_8c5c.d.mts → types-DPQM6tIG.d.mts} +10 -1
- package/dist/{types-BYj_8c5c.d.ts → types-DPQM6tIG.d.ts} +10 -1
- package/dist/wallet/index.d.mts +8 -6
- package/dist/wallet/index.d.ts +8 -6
- package/dist/wallet/index.js +80 -57
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +80 -57
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/client/index.d.mts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { M as Model, a as Message, T as TransactionHistory,
|
|
2
|
-
import { P as ProviderRegistry, W as WalletAdapter, S as StorageAdapter, a as StreamingCallbacks } from '../interfaces-
|
|
3
|
-
import { S as SdkStore, U as UsageTrackingDriver } from '../store-
|
|
1
|
+
import { M as Model, S as SdkLogger, a as Message, T as TransactionHistory, m as StreamingResult } from '../types-DPQM6tIG.mjs';
|
|
2
|
+
import { P as ProviderRegistry, W as WalletAdapter, S as StorageAdapter, a as StreamingCallbacks } from '../interfaces-Bp0Ngmqv.mjs';
|
|
3
|
+
import { S as SdkStore, U as UsageTrackingDriver } from '../store-CBSyK2qg.mjs';
|
|
4
4
|
import { CashuSpender, BalanceManager } from '../wallet/index.mjs';
|
|
5
5
|
import { Transform } from 'stream';
|
|
6
6
|
import 'zustand/vanilla';
|
|
7
|
-
import '../interfaces-
|
|
7
|
+
import '../interfaces-Cxi8R4TT.mjs';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* ProviderManager - Handles provider selection and failover logic
|
|
@@ -38,7 +38,8 @@ declare class ProviderManager {
|
|
|
38
38
|
private store;
|
|
39
39
|
/** Instance ID for debugging */
|
|
40
40
|
private readonly instanceId;
|
|
41
|
-
|
|
41
|
+
private readonly logger;
|
|
42
|
+
constructor(providerRegistry: ProviderRegistry, store?: SdkStore, logger?: SdkLogger);
|
|
42
43
|
/**
|
|
43
44
|
* Hydrate in-memory state from persistent store
|
|
44
45
|
*/
|
|
@@ -195,6 +196,8 @@ interface RoutstrClientConfig {
|
|
|
195
196
|
sdkStore?: SdkStore;
|
|
196
197
|
/** Optional: shared ProviderManager instance for consistent failure tracking across requests */
|
|
197
198
|
providerManager?: ProviderManager;
|
|
199
|
+
/** Optional: injectable logger (defaults to consoleLogger) */
|
|
200
|
+
logger?: SdkLogger;
|
|
198
201
|
}
|
|
199
202
|
declare class RoutstrClient {
|
|
200
203
|
private walletAdapter;
|
|
@@ -209,6 +212,7 @@ declare class RoutstrClient {
|
|
|
209
212
|
private debugLevel;
|
|
210
213
|
private usageTrackingDriver?;
|
|
211
214
|
private sdkStore?;
|
|
215
|
+
private logger;
|
|
212
216
|
constructor(walletAdapter: WalletAdapter, storageAdapter: StorageAdapter, providerRegistry: ProviderRegistry, alertLevel: AlertLevel, mode?: RoutstrClientMode, options?: RoutstrClientConfig);
|
|
213
217
|
/**
|
|
214
218
|
* Get the current client mode
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { M as Model, a as Message, T as TransactionHistory,
|
|
2
|
-
import { P as ProviderRegistry, W as WalletAdapter, S as StorageAdapter, a as StreamingCallbacks } from '../interfaces-
|
|
3
|
-
import { S as SdkStore, U as UsageTrackingDriver } from '../store-
|
|
1
|
+
import { M as Model, S as SdkLogger, a as Message, T as TransactionHistory, m as StreamingResult } from '../types-DPQM6tIG.js';
|
|
2
|
+
import { P as ProviderRegistry, W as WalletAdapter, S as StorageAdapter, a as StreamingCallbacks } from '../interfaces-D2FDCLyP.js';
|
|
3
|
+
import { S as SdkStore, U as UsageTrackingDriver } from '../store-BD5zF9Hp.js';
|
|
4
4
|
import { CashuSpender, BalanceManager } from '../wallet/index.js';
|
|
5
5
|
import { Transform } from 'stream';
|
|
6
6
|
import 'zustand/vanilla';
|
|
7
|
-
import '../interfaces-
|
|
7
|
+
import '../interfaces-CIfd_phZ.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* ProviderManager - Handles provider selection and failover logic
|
|
@@ -38,7 +38,8 @@ declare class ProviderManager {
|
|
|
38
38
|
private store;
|
|
39
39
|
/** Instance ID for debugging */
|
|
40
40
|
private readonly instanceId;
|
|
41
|
-
|
|
41
|
+
private readonly logger;
|
|
42
|
+
constructor(providerRegistry: ProviderRegistry, store?: SdkStore, logger?: SdkLogger);
|
|
42
43
|
/**
|
|
43
44
|
* Hydrate in-memory state from persistent store
|
|
44
45
|
*/
|
|
@@ -195,6 +196,8 @@ interface RoutstrClientConfig {
|
|
|
195
196
|
sdkStore?: SdkStore;
|
|
196
197
|
/** Optional: shared ProviderManager instance for consistent failure tracking across requests */
|
|
197
198
|
providerManager?: ProviderManager;
|
|
199
|
+
/** Optional: injectable logger (defaults to consoleLogger) */
|
|
200
|
+
logger?: SdkLogger;
|
|
198
201
|
}
|
|
199
202
|
declare class RoutstrClient {
|
|
200
203
|
private walletAdapter;
|
|
@@ -209,6 +212,7 @@ declare class RoutstrClient {
|
|
|
209
212
|
private debugLevel;
|
|
210
213
|
private usageTrackingDriver?;
|
|
211
214
|
private sdkStore?;
|
|
215
|
+
private logger;
|
|
212
216
|
constructor(walletAdapter: WalletAdapter, storageAdapter: StorageAdapter, providerRegistry: ProviderRegistry, alertLevel: AlertLevel, mode?: RoutstrClientMode, options?: RoutstrClientConfig);
|
|
213
217
|
/**
|
|
214
218
|
* Get the current client mode
|
package/dist/client/index.js
CHANGED
|
@@ -5,6 +5,19 @@ var vanilla = require('zustand/vanilla');
|
|
|
5
5
|
var stream = require('stream');
|
|
6
6
|
var string_decoder = require('string_decoder');
|
|
7
7
|
|
|
8
|
+
// core/types.ts
|
|
9
|
+
function makeConsoleLogger(prefix) {
|
|
10
|
+
const fmt = (args) => prefix ? [prefix, ...args] : args;
|
|
11
|
+
return {
|
|
12
|
+
log: (...args) => console.log(...fmt(args)),
|
|
13
|
+
warn: (...args) => console.warn(...fmt(args)),
|
|
14
|
+
error: (...args) => console.error(...fmt(args)),
|
|
15
|
+
debug: (...args) => console.log(...fmt(args)),
|
|
16
|
+
child: (p) => makeConsoleLogger(prefix ? `${prefix}:${p}` : p)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
var consoleLogger = makeConsoleLogger();
|
|
20
|
+
|
|
8
21
|
// core/errors.ts
|
|
9
22
|
var InsufficientBalanceError = class extends Error {
|
|
10
23
|
constructor(required, available, maxMintBalance = 0, maxMintUrl = "", customMessage) {
|
|
@@ -104,14 +117,16 @@ function selectMintWithBalance(balances, units, amount, excludeMints = []) {
|
|
|
104
117
|
return { selectedMintUrl: null, selectedMintBalance: 0 };
|
|
105
118
|
}
|
|
106
119
|
var CashuSpender = class {
|
|
107
|
-
constructor(walletAdapter, storageAdapter, _providerRegistry, balanceManager) {
|
|
120
|
+
constructor(walletAdapter, storageAdapter, _providerRegistry, balanceManager, logger) {
|
|
108
121
|
this.walletAdapter = walletAdapter;
|
|
109
122
|
this.storageAdapter = storageAdapter;
|
|
110
123
|
this._providerRegistry = _providerRegistry;
|
|
111
124
|
this.balanceManager = balanceManager;
|
|
125
|
+
this.logger = (logger ?? consoleLogger).child("CashuSpender");
|
|
112
126
|
}
|
|
113
127
|
_isBusy = false;
|
|
114
128
|
debugLevel = "WARN";
|
|
129
|
+
logger;
|
|
115
130
|
async receiveToken(token) {
|
|
116
131
|
try {
|
|
117
132
|
const result = await this.walletAdapter.receiveToken(token);
|
|
@@ -207,13 +222,13 @@ var CashuSpender = class {
|
|
|
207
222
|
if (levelPriority[level] >= levelPriority[this.debugLevel]) {
|
|
208
223
|
switch (level) {
|
|
209
224
|
case "DEBUG":
|
|
210
|
-
|
|
225
|
+
this.logger.log(...args);
|
|
211
226
|
break;
|
|
212
227
|
case "WARN":
|
|
213
|
-
|
|
228
|
+
this.logger.warn(...args);
|
|
214
229
|
break;
|
|
215
230
|
case "ERROR":
|
|
216
|
-
|
|
231
|
+
this.logger.error(...args);
|
|
217
232
|
break;
|
|
218
233
|
}
|
|
219
234
|
}
|
|
@@ -561,19 +576,50 @@ var CashuSpender = class {
|
|
|
561
576
|
apiKeyEntry.baseUrl
|
|
562
577
|
);
|
|
563
578
|
if (apiKeyEntryFull && this.balanceManager) {
|
|
579
|
+
try {
|
|
580
|
+
const balanceResult = await this.balanceManager.getTokenBalance(
|
|
581
|
+
apiKeyEntryFull.key,
|
|
582
|
+
apiKeyEntry.baseUrl
|
|
583
|
+
);
|
|
584
|
+
if (balanceResult.isInvalidApiKey) {
|
|
585
|
+
this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);
|
|
586
|
+
results.push({
|
|
587
|
+
baseUrl: apiKeyEntry.baseUrl,
|
|
588
|
+
success: true
|
|
589
|
+
});
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
if (balanceResult.amount >= 0) {
|
|
593
|
+
const balanceSat = balanceResult.unit === "msat" ? Math.floor(balanceResult.amount / 1e3) : balanceResult.amount;
|
|
594
|
+
this.storageAdapter.updateApiKeyBalance(
|
|
595
|
+
apiKeyEntry.baseUrl,
|
|
596
|
+
balanceSat
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
} catch {
|
|
600
|
+
}
|
|
601
|
+
const refreshedEntry = this.storageAdapter.getApiKey(
|
|
602
|
+
apiKeyEntry.baseUrl
|
|
603
|
+
);
|
|
604
|
+
if (!refreshedEntry) continue;
|
|
564
605
|
const refundResult = await this.balanceManager.refundApiKey({
|
|
565
606
|
mintUrl,
|
|
566
607
|
baseUrl: apiKeyEntry.baseUrl,
|
|
567
|
-
apiKey:
|
|
608
|
+
apiKey: refreshedEntry.key,
|
|
568
609
|
forceRefund
|
|
569
610
|
});
|
|
570
611
|
if (refundResult.success) {
|
|
571
612
|
this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);
|
|
572
613
|
} else {
|
|
573
|
-
this.storageAdapter.
|
|
574
|
-
apiKeyEntry.baseUrl
|
|
575
|
-
apiKeyEntry.amount
|
|
614
|
+
const currentEntry = this.storageAdapter.getApiKey(
|
|
615
|
+
apiKeyEntry.baseUrl
|
|
576
616
|
);
|
|
617
|
+
if (currentEntry) {
|
|
618
|
+
this.storageAdapter.updateApiKeyBalance(
|
|
619
|
+
apiKeyEntry.baseUrl,
|
|
620
|
+
currentEntry.balance
|
|
621
|
+
);
|
|
622
|
+
}
|
|
577
623
|
}
|
|
578
624
|
results.push({
|
|
579
625
|
baseUrl: apiKeyEntry.baseUrl,
|
|
@@ -640,10 +686,11 @@ var CashuSpender = class {
|
|
|
640
686
|
|
|
641
687
|
// wallet/BalanceManager.ts
|
|
642
688
|
var BalanceManager = class _BalanceManager {
|
|
643
|
-
constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender) {
|
|
689
|
+
constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender, logger) {
|
|
644
690
|
this.walletAdapter = walletAdapter;
|
|
645
691
|
this.storageAdapter = storageAdapter;
|
|
646
692
|
this.providerRegistry = providerRegistry;
|
|
693
|
+
this.logger = (logger ?? consoleLogger).child("BalanceManager");
|
|
647
694
|
if (cashuSpender) {
|
|
648
695
|
this.cashuSpender = cashuSpender;
|
|
649
696
|
} else {
|
|
@@ -660,6 +707,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
660
707
|
providerWalletOps = /* @__PURE__ */ new Map();
|
|
661
708
|
/** Cooldown (ms) between opposite operations on the same provider */
|
|
662
709
|
static PROVIDER_WALLET_COOLDOWN_MS = 1e4;
|
|
710
|
+
logger;
|
|
663
711
|
/**
|
|
664
712
|
* Check whether a wallet operation (topup/refund) may run for a provider.
|
|
665
713
|
* Returns the reason when blocked.
|
|
@@ -734,7 +782,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
734
782
|
const { mintUrl, baseUrl, apiKey, forceRefund } = options;
|
|
735
783
|
const guard = this._canRunProviderWalletOperation(baseUrl, "refund");
|
|
736
784
|
if (!guard.allowed) {
|
|
737
|
-
|
|
785
|
+
this.logger.log(`Skipping refund for ${baseUrl} - ${guard.reason}`);
|
|
738
786
|
return { success: false, message: guard.reason };
|
|
739
787
|
}
|
|
740
788
|
this._beginProviderWalletOperation(baseUrl, "refund");
|
|
@@ -754,9 +802,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
754
802
|
if (apiKeyEntry?.lastUsed) {
|
|
755
803
|
const fiveMinutesAgo = Date.now() - 5 * 60 * 1e3;
|
|
756
804
|
if (apiKeyEntry.lastUsed > fiveMinutesAgo) {
|
|
757
|
-
|
|
758
|
-
`[BalanceManager] Skipping refund for ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1e3)}s ago`
|
|
759
|
-
);
|
|
805
|
+
this.logger.log(`Skipping refund for ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1e3)}s ago`);
|
|
760
806
|
return {
|
|
761
807
|
success: false,
|
|
762
808
|
message: "API key was used recently, skipping refund"
|
|
@@ -782,7 +828,8 @@ var BalanceManager = class _BalanceManager {
|
|
|
782
828
|
};
|
|
783
829
|
}
|
|
784
830
|
if (fetchResult.error === "No balance to refund") {
|
|
785
|
-
|
|
831
|
+
this.storageAdapter.removeApiKey(baseUrl);
|
|
832
|
+
return { success: true, message: "No balance to refund, key cleaned up" };
|
|
786
833
|
}
|
|
787
834
|
const receiveResult = await this.cashuSpender.receiveToken(
|
|
788
835
|
fetchResult.token
|
|
@@ -798,7 +845,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
798
845
|
requestId: fetchResult.requestId
|
|
799
846
|
};
|
|
800
847
|
} catch (error) {
|
|
801
|
-
|
|
848
|
+
this.logger.error("API key refund error", error);
|
|
802
849
|
return this._handleRefundError(error, mintUrl, fetchResult?.requestId);
|
|
803
850
|
}
|
|
804
851
|
}
|
|
@@ -850,7 +897,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
850
897
|
};
|
|
851
898
|
} catch (error) {
|
|
852
899
|
clearTimeout(timeoutId);
|
|
853
|
-
|
|
900
|
+
this.logger.error("fetchRefundToken fetch error", error);
|
|
854
901
|
if (error instanceof Error) {
|
|
855
902
|
if (error.name === "AbortError") {
|
|
856
903
|
return {
|
|
@@ -876,7 +923,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
876
923
|
const { mintUrl, baseUrl, amount, token: providedToken } = options;
|
|
877
924
|
const guard = this._canRunProviderWalletOperation(baseUrl, "topup");
|
|
878
925
|
if (!guard.allowed) {
|
|
879
|
-
|
|
926
|
+
this.logger.log(`Skipping topup for ${baseUrl} - ${guard.reason}`);
|
|
880
927
|
return { success: false, message: guard.reason };
|
|
881
928
|
}
|
|
882
929
|
this._beginProviderWalletOperation(baseUrl, "topup");
|
|
@@ -913,7 +960,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
913
960
|
cashuToken = tokenResult.token;
|
|
914
961
|
const topUpResult = await this._postTopUp(baseUrl, apiKey, cashuToken);
|
|
915
962
|
requestId = topUpResult.requestId;
|
|
916
|
-
|
|
963
|
+
this.logger.log("topUpResult:", topUpResult);
|
|
917
964
|
if (!topUpResult.success) {
|
|
918
965
|
await this._recoverFailedTopUp(cashuToken);
|
|
919
966
|
return {
|
|
@@ -929,10 +976,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
929
976
|
requestId
|
|
930
977
|
};
|
|
931
978
|
} catch (error) {
|
|
932
|
-
|
|
933
|
-
"DEBUG",
|
|
934
|
-
`[TopuPU] topup: Topup result for ${baseUrl}: error=${error}`
|
|
935
|
-
);
|
|
979
|
+
this.logger.log(`topup error for ${baseUrl}: ${error}`);
|
|
936
980
|
if (cashuToken) {
|
|
937
981
|
await this._recoverFailedTopUp(cashuToken);
|
|
938
982
|
}
|
|
@@ -949,13 +993,9 @@ var BalanceManager = class _BalanceManager {
|
|
|
949
993
|
p2pkPubkey
|
|
950
994
|
} = options;
|
|
951
995
|
const adjustedAmount = Math.ceil(amount);
|
|
952
|
-
|
|
953
|
-
`[BalanceManager.createProviderToken] Starting: baseUrl=${baseUrl}, mintUrl=${mintUrl}, amount=${amount}, adjustedAmount=${adjustedAmount}, retryCount=${retryCount}`
|
|
954
|
-
);
|
|
996
|
+
this.logger.log(`createProviderToken: baseUrl=${baseUrl} mintUrl=${mintUrl} amount=${amount} adjustedAmount=${adjustedAmount} retryCount=${retryCount}`);
|
|
955
997
|
if (!adjustedAmount || isNaN(adjustedAmount)) {
|
|
956
|
-
|
|
957
|
-
`[BalanceManager.createProviderToken] FAILURE: Invalid amount - amount=${amount}, adjustedAmount=${adjustedAmount}`
|
|
958
|
-
);
|
|
998
|
+
this.logger.error(`createProviderToken: invalid amount=${amount}`);
|
|
959
999
|
return { success: false, error: "Invalid top up amount" };
|
|
960
1000
|
}
|
|
961
1001
|
const balanceState = await this.getBalanceState();
|
|
@@ -986,9 +1026,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
986
1026
|
{ url: "", balance: 0 }
|
|
987
1027
|
).url
|
|
988
1028
|
);
|
|
989
|
-
|
|
990
|
-
`[BalanceManager.createProviderToken] FAILURE: Insufficient balance - required=${adjustedAmount}, available=${totalMintBalance + targetProviderBalance}, totalMintBalance=${totalMintBalance}, targetProviderBalance=${targetProviderBalance}, refundableProviderBalance=${refundableProviderBalance}`
|
|
991
|
-
);
|
|
1029
|
+
this.logger.error(`createProviderToken: insufficient balance required=${adjustedAmount} available=${totalMintBalance + targetProviderBalance} totalMint=${totalMintBalance} targetProvider=${targetProviderBalance}`);
|
|
992
1030
|
return { success: false, error: error.message };
|
|
993
1031
|
}
|
|
994
1032
|
const providerMints = baseUrl && this.providerRegistry ? this.providerRegistry.getProviderMints(baseUrl) : [];
|
|
@@ -1024,9 +1062,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
1024
1062
|
maxMintUrl = mintUrl2;
|
|
1025
1063
|
}
|
|
1026
1064
|
}
|
|
1027
|
-
|
|
1028
|
-
`[BalanceManager.createProviderToken] FAILURE: No candidate mints found - requiredAmount=${requiredAmount}, totalMintBalance=${totalMintBalance}, maxBalance=${maxBalance}, maxMintUrl=${maxMintUrl}, providerMints=${JSON.stringify(providerMints)}`
|
|
1029
|
-
);
|
|
1065
|
+
this.logger.error(`createProviderToken: no candidate mints required=${requiredAmount} totalMint=${totalMintBalance} maxBalance=${maxBalance} maxMint=${maxMintUrl}`);
|
|
1030
1066
|
const error = new InsufficientBalanceError(
|
|
1031
1067
|
adjustedAmount,
|
|
1032
1068
|
totalMintBalance,
|
|
@@ -1038,17 +1074,13 @@ var BalanceManager = class _BalanceManager {
|
|
|
1038
1074
|
let lastError;
|
|
1039
1075
|
for (const candidateMint of candidates) {
|
|
1040
1076
|
try {
|
|
1041
|
-
|
|
1042
|
-
`[BalanceManager.createProviderToken] Attempting mint: ${candidateMint}, amount: ${requiredAmount}`
|
|
1043
|
-
);
|
|
1077
|
+
this.logger.log(`createProviderToken: attempting mint=${candidateMint} amount=${requiredAmount}`);
|
|
1044
1078
|
const token = await this.walletAdapter.sendToken(
|
|
1045
1079
|
candidateMint,
|
|
1046
1080
|
requiredAmount,
|
|
1047
1081
|
p2pkPubkey
|
|
1048
1082
|
);
|
|
1049
|
-
|
|
1050
|
-
`[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])])))}`
|
|
1051
|
-
);
|
|
1083
|
+
this.logger.log(`createProviderToken: success from mint=${candidateMint}`);
|
|
1052
1084
|
return {
|
|
1053
1085
|
success: true,
|
|
1054
1086
|
token,
|
|
@@ -1057,15 +1089,11 @@ var BalanceManager = class _BalanceManager {
|
|
|
1057
1089
|
};
|
|
1058
1090
|
} catch (error) {
|
|
1059
1091
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
1060
|
-
|
|
1061
|
-
`[BalanceManager.createProviderToken] FAILURE: Mint ${candidateMint} failed with error: ${errorMsg}`
|
|
1062
|
-
);
|
|
1092
|
+
this.logger.error(`createProviderToken: mint=${candidateMint} failed: ${errorMsg}`);
|
|
1063
1093
|
if (error instanceof Error) {
|
|
1064
1094
|
lastError = errorMsg;
|
|
1065
1095
|
if (isNetworkErrorMessage(error.message)) {
|
|
1066
|
-
|
|
1067
|
-
`[BalanceManager.createProviderToken] Network error from ${candidateMint}, trying next mint...`
|
|
1068
|
-
);
|
|
1096
|
+
this.logger.warn(`createProviderToken: network error from ${candidateMint}, trying next mint...`);
|
|
1069
1097
|
continue;
|
|
1070
1098
|
}
|
|
1071
1099
|
}
|
|
@@ -1075,9 +1103,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
1075
1103
|
};
|
|
1076
1104
|
}
|
|
1077
1105
|
}
|
|
1078
|
-
|
|
1079
|
-
`[BalanceManager.createProviderToken] FAILURE: All candidate mints exhausted - lastError=${lastError}, candidates=${JSON.stringify(candidates)}`
|
|
1080
|
-
);
|
|
1106
|
+
this.logger.error(`createProviderToken: all candidate mints exhausted lastError=${lastError}`);
|
|
1081
1107
|
return {
|
|
1082
1108
|
success: false,
|
|
1083
1109
|
error: lastError || "All candidate mints failed while creating top up token"
|
|
@@ -1192,7 +1218,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
1192
1218
|
return { success: true, requestId };
|
|
1193
1219
|
} catch (error) {
|
|
1194
1220
|
clearTimeout(timeoutId);
|
|
1195
|
-
|
|
1221
|
+
this.logger.error("_postTopUp fetch error", error);
|
|
1196
1222
|
if (error instanceof Error) {
|
|
1197
1223
|
if (error.name === "AbortError") {
|
|
1198
1224
|
return {
|
|
@@ -1218,10 +1244,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
1218
1244
|
try {
|
|
1219
1245
|
await this.cashuSpender.receiveToken(cashuToken);
|
|
1220
1246
|
} catch (error) {
|
|
1221
|
-
|
|
1222
|
-
"[BalanceManager._recoverFailedTopUp] Failed to recover token",
|
|
1223
|
-
error
|
|
1224
|
-
);
|
|
1247
|
+
this.logger.error("_recoverFailedTopUp: failed to recover token", error);
|
|
1225
1248
|
}
|
|
1226
1249
|
}
|
|
1227
1250
|
/**
|
|
@@ -1274,9 +1297,9 @@ var BalanceManager = class _BalanceManager {
|
|
|
1274
1297
|
apiKey: data.api_key
|
|
1275
1298
|
};
|
|
1276
1299
|
} else {
|
|
1277
|
-
|
|
1300
|
+
this.logger.warn(`getTokenBalance: status=${response.status}`);
|
|
1278
1301
|
const data = await response.json();
|
|
1279
|
-
|
|
1302
|
+
this.logger.warn("getTokenBalance: FAILED", data);
|
|
1280
1303
|
const isInvalidApiKey = response.status === 401 && data?.detail?.error?.code === "invalid_api_key" && data?.detail?.error?.message?.includes("proofs already spent");
|
|
1281
1304
|
return {
|
|
1282
1305
|
amount: -1,
|
|
@@ -1287,7 +1310,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
1287
1310
|
};
|
|
1288
1311
|
}
|
|
1289
1312
|
} catch (error) {
|
|
1290
|
-
|
|
1313
|
+
this.logger.error("getTokenBalance error", error);
|
|
1291
1314
|
}
|
|
1292
1315
|
return { amount: -1, reserved: 0, unit: "sat", apiKey: "" };
|
|
1293
1316
|
}
|
|
@@ -1753,9 +1776,10 @@ function isInsecureHttpUrl(url) {
|
|
|
1753
1776
|
return url.startsWith("http://");
|
|
1754
1777
|
}
|
|
1755
1778
|
var ProviderManager = class _ProviderManager {
|
|
1756
|
-
constructor(providerRegistry, store) {
|
|
1779
|
+
constructor(providerRegistry, store, logger) {
|
|
1757
1780
|
this.providerRegistry = providerRegistry;
|
|
1758
1781
|
this.instanceId = `pm_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1782
|
+
this.logger = (logger ?? consoleLogger).child(`ProviderManager:${this.instanceId}`);
|
|
1759
1783
|
if (store) {
|
|
1760
1784
|
this.store = store;
|
|
1761
1785
|
this.hydrateFromStore();
|
|
@@ -1772,6 +1796,7 @@ var ProviderManager = class _ProviderManager {
|
|
|
1772
1796
|
store = null;
|
|
1773
1797
|
/** Instance ID for debugging */
|
|
1774
1798
|
instanceId;
|
|
1799
|
+
logger;
|
|
1775
1800
|
/**
|
|
1776
1801
|
* Hydrate in-memory state from persistent store
|
|
1777
1802
|
*/
|
|
@@ -1784,10 +1809,7 @@ var ProviderManager = class _ProviderManager {
|
|
|
1784
1809
|
this.providersOnCoolDown = state.providersOnCooldown.filter(
|
|
1785
1810
|
(entry) => now - entry.timestamp < _ProviderManager.COOLDOWN_DURATION_MS
|
|
1786
1811
|
).map((entry) => [entry.baseUrl, entry.timestamp]);
|
|
1787
|
-
|
|
1788
|
-
console.log(` failedProviders: ${this.failedProviders.size}`);
|
|
1789
|
-
console.log(` lastFailed: ${this.lastFailed.size}`);
|
|
1790
|
-
console.log(` providersOnCooldown: ${this.providersOnCoolDown.length}`);
|
|
1812
|
+
this.logger.log(`Hydrated from store: failedProviders=${this.failedProviders.size} lastFailed=${this.lastFailed.size} providersOnCooldown=${this.providersOnCoolDown.length}`);
|
|
1791
1813
|
}
|
|
1792
1814
|
/**
|
|
1793
1815
|
* Get instance ID for debugging
|
|
@@ -1807,9 +1829,7 @@ var ProviderManager = class _ProviderManager {
|
|
|
1807
1829
|
const age = now - timestamp;
|
|
1808
1830
|
const isExpired = age >= _ProviderManager.COOLDOWN_DURATION_MS;
|
|
1809
1831
|
if (isExpired) {
|
|
1810
|
-
|
|
1811
|
-
`[cleanupExpiredCooldowns:${this.instanceId}] Removing expired cooldown for ${url} (age: ${age}ms, cooldown: ${_ProviderManager.COOLDOWN_DURATION_MS}ms)`
|
|
1812
|
-
);
|
|
1832
|
+
this.logger.log(`Removing expired cooldown for ${url} (age: ${age}ms)`);
|
|
1813
1833
|
this.failedProviders.delete(url);
|
|
1814
1834
|
if (this.store) {
|
|
1815
1835
|
this.store.getState().removeFailedProvider(url);
|
|
@@ -1820,9 +1840,7 @@ var ProviderManager = class _ProviderManager {
|
|
|
1820
1840
|
);
|
|
1821
1841
|
const after = this.providersOnCoolDown.length;
|
|
1822
1842
|
if (before !== after) {
|
|
1823
|
-
|
|
1824
|
-
`[cleanupExpiredCooldowns:${this.instanceId}] Cleaned up ${before - after} expired cooldown(s), ${after} remaining`
|
|
1825
|
-
);
|
|
1843
|
+
this.logger.log(`Cleaned up ${before - after} expired cooldown(s), ${after} remaining`);
|
|
1826
1844
|
}
|
|
1827
1845
|
}
|
|
1828
1846
|
/**
|
|
@@ -1874,24 +1892,10 @@ var ProviderManager = class _ProviderManager {
|
|
|
1874
1892
|
markFailed(baseUrl) {
|
|
1875
1893
|
const now = Date.now();
|
|
1876
1894
|
const lastFailure = this.lastFailed.get(baseUrl);
|
|
1877
|
-
|
|
1878
|
-
console.log(
|
|
1879
|
-
`[markFailed:${this.instanceId}] lastFailure from map: ${lastFailure}`
|
|
1880
|
-
);
|
|
1881
|
-
console.log(
|
|
1882
|
-
`[markFailed:${this.instanceId}] current timestamp (now): ${now}`
|
|
1883
|
-
);
|
|
1884
|
-
console.log(
|
|
1885
|
-
`[markFailed:${this.instanceId}] COOLDOWN_DURATION_MS: ${_ProviderManager.COOLDOWN_DURATION_MS}`
|
|
1886
|
-
);
|
|
1895
|
+
this.logger.log(`markFailed: ${baseUrl} lastFailure=${lastFailure} now=${now}`);
|
|
1887
1896
|
if (lastFailure !== void 0) {
|
|
1888
1897
|
const timeSinceLastFailure = now - lastFailure;
|
|
1889
|
-
|
|
1890
|
-
`[markFailed:${this.instanceId}] timeSinceLastFailure: ${timeSinceLastFailure}ms`
|
|
1891
|
-
);
|
|
1892
|
-
console.log(
|
|
1893
|
-
`[markFailed:${this.instanceId}] isWithinCooldownWindow: ${timeSinceLastFailure < _ProviderManager.COOLDOWN_DURATION_MS}`
|
|
1894
|
-
);
|
|
1898
|
+
this.logger.log(`markFailed: timeSinceLastFailure=${timeSinceLastFailure}ms withinCooldown=${timeSinceLastFailure < _ProviderManager.COOLDOWN_DURATION_MS}`);
|
|
1895
1899
|
}
|
|
1896
1900
|
this.lastFailed.set(baseUrl, now);
|
|
1897
1901
|
this.failedProviders.add(baseUrl);
|
|
@@ -1899,38 +1903,23 @@ var ProviderManager = class _ProviderManager {
|
|
|
1899
1903
|
this.store.getState().setLastFailedTimestamp(baseUrl, now);
|
|
1900
1904
|
this.store.getState().addFailedProvider(baseUrl);
|
|
1901
1905
|
}
|
|
1902
|
-
|
|
1903
|
-
`[markFailed:${this.instanceId}] Updated lastFailed map for ${baseUrl} to ${now}`
|
|
1904
|
-
);
|
|
1905
|
-
console.log(
|
|
1906
|
-
`[markFailed:${this.instanceId}] failedProviders set size: ${this.failedProviders.size}`
|
|
1907
|
-
);
|
|
1906
|
+
this.logger.log(`markFailed: updated ${baseUrl} to ${now}, failedProviders=${this.failedProviders.size}`);
|
|
1908
1907
|
if (lastFailure !== void 0 && now - lastFailure < _ProviderManager.COOLDOWN_DURATION_MS) {
|
|
1909
|
-
|
|
1910
|
-
`[markFailed:${this.instanceId}] Second failure detected within cooldown window for ${baseUrl}`
|
|
1911
|
-
);
|
|
1908
|
+
this.logger.log(`markFailed: second failure within cooldown window for ${baseUrl}`);
|
|
1912
1909
|
if (!this.isOnCooldown(baseUrl)) {
|
|
1913
1910
|
this.providersOnCoolDown.push([baseUrl, now]);
|
|
1914
1911
|
if (this.store) {
|
|
1915
1912
|
this.store.getState().addProviderOnCooldown(baseUrl, now);
|
|
1916
1913
|
}
|
|
1917
|
-
|
|
1918
|
-
`[markFailed:${this.instanceId}] Provider ${baseUrl} added to cooldown after second failure within 5 minutes`
|
|
1919
|
-
);
|
|
1914
|
+
this.logger.log(`markFailed: ${baseUrl} added to cooldown`);
|
|
1920
1915
|
} else {
|
|
1921
|
-
|
|
1922
|
-
`[markFailed:${this.instanceId}] Provider ${baseUrl} is already on cooldown`
|
|
1923
|
-
);
|
|
1916
|
+
this.logger.log(`markFailed: ${baseUrl} already on cooldown`);
|
|
1924
1917
|
}
|
|
1925
1918
|
} else {
|
|
1926
1919
|
if (lastFailure === void 0) {
|
|
1927
|
-
|
|
1928
|
-
`[markFailed:${this.instanceId}] First failure for ${baseUrl} - not adding to cooldown yet`
|
|
1929
|
-
);
|
|
1920
|
+
this.logger.log(`markFailed: first failure for ${baseUrl}`);
|
|
1930
1921
|
} else {
|
|
1931
|
-
|
|
1932
|
-
`[markFailed:${this.instanceId}] Failure outside cooldown window for ${baseUrl} (timeSinceLastFailure: ${now - lastFailure}ms)`
|
|
1933
|
-
);
|
|
1922
|
+
this.logger.log(`markFailed: failure outside cooldown window for ${baseUrl} (${now - lastFailure}ms ago)`);
|
|
1934
1923
|
}
|
|
1935
1924
|
}
|
|
1936
1925
|
}
|
|
@@ -1987,25 +1976,12 @@ var ProviderManager = class _ProviderManager {
|
|
|
1987
1976
|
const disabledProviders = new Set(
|
|
1988
1977
|
this.providerRegistry.getDisabledProviders()
|
|
1989
1978
|
);
|
|
1990
|
-
|
|
1991
|
-
`[findNextBestProvider:${this.instanceId}] Starting search for model: ${modelId}`
|
|
1992
|
-
);
|
|
1993
|
-
console.log(
|
|
1994
|
-
`[findNextBestProvider:${this.instanceId}] disabledProviders: ${[...disabledProviders]}`
|
|
1995
|
-
);
|
|
1996
|
-
console.log(
|
|
1997
|
-
`[findNextBestProvider:${this.instanceId}] providersOnCooldown: ${this.providersOnCoolDown.map(([url]) => url)}`
|
|
1998
|
-
);
|
|
1979
|
+
this.logger.log(`findNextBestProvider: model=${modelId} disabled=${[...disabledProviders].length} onCooldown=${this.providersOnCoolDown.length}`);
|
|
1999
1980
|
const allProviders = this.providerRegistry.getAllProvidersModels();
|
|
2000
|
-
|
|
2001
|
-
`[findNextBestProvider:${this.instanceId}] Total providers in registry: ${Object.keys(allProviders).length}`
|
|
2002
|
-
);
|
|
1981
|
+
this.logger.log(`findNextBestProvider: total providers=${Object.keys(allProviders).length}`);
|
|
2003
1982
|
const candidates = [];
|
|
2004
1983
|
for (const [baseUrl, models] of Object.entries(allProviders)) {
|
|
2005
1984
|
if (baseUrl === currentBaseUrl) {
|
|
2006
|
-
console.log(
|
|
2007
|
-
`[findNextBestProvider:${this.instanceId}] SKIP (current): ${baseUrl}`
|
|
2008
|
-
);
|
|
2009
1985
|
continue;
|
|
2010
1986
|
}
|
|
2011
1987
|
if (disabledProviders.has(baseUrl)) {
|
|
@@ -2031,7 +2007,7 @@ var ProviderManager = class _ProviderManager {
|
|
|
2031
2007
|
return null;
|
|
2032
2008
|
}
|
|
2033
2009
|
} catch (error) {
|
|
2034
|
-
|
|
2010
|
+
this.logger.error("findNextBestProvider error:", error);
|
|
2035
2011
|
return null;
|
|
2036
2012
|
}
|
|
2037
2013
|
}
|
|
@@ -2158,16 +2134,9 @@ var ProviderManager = class _ProviderManager {
|
|
|
2158
2134
|
res.height
|
|
2159
2135
|
);
|
|
2160
2136
|
imageTokens += tokensFromImage;
|
|
2161
|
-
|
|
2162
|
-
width: res.width,
|
|
2163
|
-
height: res.height,
|
|
2164
|
-
tokensFromImage
|
|
2165
|
-
});
|
|
2137
|
+
this.logger.log(`IMAGE INPUT RESOLUTION width=${res.width} height=${res.height} tokens=${tokensFromImage}`);
|
|
2166
2138
|
} else {
|
|
2167
|
-
|
|
2168
|
-
"IMAGE INPUT RESOLUTION",
|
|
2169
|
-
"unknown (unsupported format or parse failure)"
|
|
2170
|
-
);
|
|
2139
|
+
this.logger.log("IMAGE INPUT RESOLUTION: unknown format");
|
|
2171
2140
|
}
|
|
2172
2141
|
}
|
|
2173
2142
|
}
|
|
@@ -2200,7 +2169,7 @@ var ProviderManager = class _ProviderManager {
|
|
|
2200
2169
|
const totalEstimatedCosts = (promptCosts + completionCost) * 1.05;
|
|
2201
2170
|
return totalEstimatedCosts;
|
|
2202
2171
|
} catch (e) {
|
|
2203
|
-
|
|
2172
|
+
this.logger.error("getRequiredSatsForModel error:", e);
|
|
2204
2173
|
return 0;
|
|
2205
2174
|
}
|
|
2206
2175
|
}
|
|
@@ -3697,6 +3666,7 @@ var RoutstrClient = class {
|
|
|
3697
3666
|
this.walletAdapter = walletAdapter;
|
|
3698
3667
|
this.storageAdapter = storageAdapter;
|
|
3699
3668
|
this.providerRegistry = providerRegistry;
|
|
3669
|
+
this.logger = (options.logger ?? consoleLogger).child("RoutstrClient");
|
|
3700
3670
|
this.balanceManager = new BalanceManager(
|
|
3701
3671
|
walletAdapter,
|
|
3702
3672
|
storageAdapter,
|
|
@@ -3713,7 +3683,7 @@ var RoutstrClient = class {
|
|
|
3713
3683
|
this.mode = mode;
|
|
3714
3684
|
this.usageTrackingDriver = options.usageTrackingDriver;
|
|
3715
3685
|
this.sdkStore = options.sdkStore;
|
|
3716
|
-
this.providerManager = options.providerManager ?? new ProviderManager(providerRegistry, this.sdkStore);
|
|
3686
|
+
this.providerManager = options.providerManager ?? new ProviderManager(providerRegistry, this.sdkStore, this.logger);
|
|
3717
3687
|
}
|
|
3718
3688
|
cashuSpender;
|
|
3719
3689
|
balanceManager;
|
|
@@ -3724,6 +3694,7 @@ var RoutstrClient = class {
|
|
|
3724
3694
|
debugLevel = "WARN";
|
|
3725
3695
|
usageTrackingDriver;
|
|
3726
3696
|
sdkStore;
|
|
3697
|
+
logger;
|
|
3727
3698
|
/**
|
|
3728
3699
|
* Get the current client mode
|
|
3729
3700
|
*/
|
|
@@ -3745,13 +3716,13 @@ var RoutstrClient = class {
|
|
|
3745
3716
|
if (levelPriority[level] >= levelPriority[this.debugLevel]) {
|
|
3746
3717
|
switch (level) {
|
|
3747
3718
|
case "DEBUG":
|
|
3748
|
-
|
|
3719
|
+
this.logger.log(...args);
|
|
3749
3720
|
break;
|
|
3750
3721
|
case "WARN":
|
|
3751
|
-
|
|
3722
|
+
this.logger.warn(...args);
|
|
3752
3723
|
break;
|
|
3753
3724
|
case "ERROR":
|
|
3754
|
-
|
|
3725
|
+
this.logger.error(...args);
|
|
3755
3726
|
break;
|
|
3756
3727
|
}
|
|
3757
3728
|
}
|
|
@@ -4355,7 +4326,7 @@ var RoutstrClient = class {
|
|
|
4355
4326
|
tryNextProvider = true;
|
|
4356
4327
|
}
|
|
4357
4328
|
}
|
|
4358
|
-
if ((status === 401 || status === 403 || status === 413 || status === 400 || status === 429 || status === 500 || status === 502 || status === 503 || status === 504 || status === 521) && !tryNextProvider) {
|
|
4329
|
+
if ((status === 401 || status === 403 || status === 404 || status === 413 || status === 400 || status === 429 || status === 500 || status === 502 || status === 503 || status === 504 || status === 521) && !tryNextProvider) {
|
|
4359
4330
|
this._log(
|
|
4360
4331
|
"DEBUG",
|
|
4361
4332
|
`[RoutstrClient] _handleErrorResponse: Status ${status} (${status === 429 ? "rate limited" : "auth/server error"}), attempting refund for ${baseUrl}, mode=${this.mode}`
|