@routstr/sdk 0.1.1 → 0.1.2
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 +7 -2
- package/dist/client/index.d.ts +7 -2
- package/dist/client/index.js +194 -65
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +194 -65
- package/dist/client/index.mjs.map +1 -1
- package/dist/discovery/index.d.mts +6 -1
- package/dist/discovery/index.d.ts +6 -1
- package/dist/discovery/index.js +53 -0
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/index.mjs +53 -0
- package/dist/discovery/index.mjs.map +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +288 -69
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +288 -69
- package/dist/index.mjs.map +1 -1
- package/dist/{interfaces-BOfiz3Tt.d.mts → interfaces-B85Wx7ni.d.mts} +15 -0
- package/dist/{interfaces-BbAtkq7z.d.ts → interfaces-BVNyAmKu.d.ts} +15 -0
- package/dist/{interfaces-CW773NQv.d.ts → interfaces-Dnrvxr6N.d.ts} +10 -0
- package/dist/{interfaces-CEOwpdG0.d.mts → interfaces-nanJOqdW.d.mts} +10 -0
- package/dist/storage/index.d.mts +20 -4
- package/dist/storage/index.d.ts +20 -4
- package/dist/storage/index.js +41 -4
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/index.mjs +41 -4
- package/dist/storage/index.mjs.map +1 -1
- package/dist/wallet/index.d.mts +15 -3
- package/dist/wallet/index.d.ts +15 -3
- package/dist/wallet/index.js +84 -17
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +84 -17
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/client/index.mjs
CHANGED
|
@@ -106,6 +106,26 @@ var CashuSpender = class {
|
|
|
106
106
|
this.balanceManager = balanceManager;
|
|
107
107
|
}
|
|
108
108
|
_isBusy = false;
|
|
109
|
+
debugLevel = "WARN";
|
|
110
|
+
async receiveToken(token) {
|
|
111
|
+
const result = await this.walletAdapter.receiveToken(token);
|
|
112
|
+
if (!result.success && result.message?.includes("Failed to fetch mint")) {
|
|
113
|
+
const cachedTokens = this.storageAdapter.getCachedReceiveTokens();
|
|
114
|
+
const existingIndex = cachedTokens.findIndex((t) => t.token === token);
|
|
115
|
+
if (existingIndex === -1) {
|
|
116
|
+
this.storageAdapter.setCachedReceiveTokens([
|
|
117
|
+
...cachedTokens,
|
|
118
|
+
{
|
|
119
|
+
token,
|
|
120
|
+
amount: result.amount,
|
|
121
|
+
unit: result.unit,
|
|
122
|
+
createdAt: Date.now()
|
|
123
|
+
}
|
|
124
|
+
]);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
109
129
|
async _getBalanceState() {
|
|
110
130
|
const mintBalances = await this.walletAdapter.getBalances();
|
|
111
131
|
const units = this.walletAdapter.getMintUnits();
|
|
@@ -148,6 +168,32 @@ var CashuSpender = class {
|
|
|
148
168
|
get isBusy() {
|
|
149
169
|
return this._isBusy;
|
|
150
170
|
}
|
|
171
|
+
getDebugLevel() {
|
|
172
|
+
return this.debugLevel;
|
|
173
|
+
}
|
|
174
|
+
setDebugLevel(level) {
|
|
175
|
+
this.debugLevel = level;
|
|
176
|
+
}
|
|
177
|
+
_log(level, ...args) {
|
|
178
|
+
const levelPriority = {
|
|
179
|
+
DEBUG: 0,
|
|
180
|
+
WARN: 1,
|
|
181
|
+
ERROR: 2
|
|
182
|
+
};
|
|
183
|
+
if (levelPriority[level] >= levelPriority[this.debugLevel]) {
|
|
184
|
+
switch (level) {
|
|
185
|
+
case "DEBUG":
|
|
186
|
+
console.log(...args);
|
|
187
|
+
break;
|
|
188
|
+
case "WARN":
|
|
189
|
+
console.warn(...args);
|
|
190
|
+
break;
|
|
191
|
+
case "ERROR":
|
|
192
|
+
console.error(...args);
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
151
197
|
/**
|
|
152
198
|
* Spend Cashu tokens with automatic mint selection and retry logic
|
|
153
199
|
* Throws errors on failure instead of returning failed SpendResult
|
|
@@ -214,12 +260,16 @@ var CashuSpender = class {
|
|
|
214
260
|
excludeMints,
|
|
215
261
|
retryCount
|
|
216
262
|
} = options;
|
|
217
|
-
|
|
263
|
+
this._log(
|
|
264
|
+
"DEBUG",
|
|
218
265
|
`[CashuSpender] _spendInternal: amount=${amount}, mintUrl=${mintUrl}, baseUrl=${baseUrl}, reuseToken=${reuseToken}`
|
|
219
266
|
);
|
|
220
267
|
let adjustedAmount = Math.ceil(amount);
|
|
221
268
|
if (!adjustedAmount || isNaN(adjustedAmount)) {
|
|
222
|
-
|
|
269
|
+
this._log(
|
|
270
|
+
"ERROR",
|
|
271
|
+
`[CashuSpender] _spendInternal: Invalid amount: ${amount}`
|
|
272
|
+
);
|
|
223
273
|
return {
|
|
224
274
|
token: null,
|
|
225
275
|
status: "failed",
|
|
@@ -228,7 +278,8 @@ var CashuSpender = class {
|
|
|
228
278
|
};
|
|
229
279
|
}
|
|
230
280
|
if (reuseToken && baseUrl) {
|
|
231
|
-
|
|
281
|
+
this._log(
|
|
282
|
+
"DEBUG",
|
|
232
283
|
`[CashuSpender] _spendInternal: Attempting to reuse token for ${baseUrl}`
|
|
233
284
|
);
|
|
234
285
|
const existingResult = await this._tryReuseToken(
|
|
@@ -237,12 +288,14 @@ var CashuSpender = class {
|
|
|
237
288
|
mintUrl
|
|
238
289
|
);
|
|
239
290
|
if (existingResult) {
|
|
240
|
-
|
|
291
|
+
this._log(
|
|
292
|
+
"DEBUG",
|
|
241
293
|
`[CashuSpender] _spendInternal: Successfully reused token, balance: ${existingResult.balance}`
|
|
242
294
|
);
|
|
243
295
|
return existingResult;
|
|
244
296
|
}
|
|
245
|
-
|
|
297
|
+
this._log(
|
|
298
|
+
"DEBUG",
|
|
246
299
|
`[CashuSpender] _spendInternal: Could not reuse token, will create new token`
|
|
247
300
|
);
|
|
248
301
|
}
|
|
@@ -260,12 +313,14 @@ var CashuSpender = class {
|
|
|
260
313
|
(sum, item) => sum + item.amount,
|
|
261
314
|
0
|
|
262
315
|
);
|
|
263
|
-
|
|
316
|
+
this._log(
|
|
317
|
+
"DEBUG",
|
|
264
318
|
`[CashuSpender] _spendInternal: totalBalance=${totalBalance}, totalPending=${totalPending}, adjustedAmount=${adjustedAmount}`
|
|
265
319
|
);
|
|
266
320
|
const totalAvailableBalance = totalBalance + totalPending;
|
|
267
321
|
if (totalAvailableBalance < adjustedAmount) {
|
|
268
|
-
|
|
322
|
+
this._log(
|
|
323
|
+
"ERROR",
|
|
269
324
|
`[CashuSpender] _spendInternal: Insufficient balance, have=${totalAvailableBalance}, need=${adjustedAmount}`
|
|
270
325
|
);
|
|
271
326
|
return this._createInsufficientBalanceError(
|
|
@@ -333,7 +388,8 @@ var CashuSpender = class {
|
|
|
333
388
|
baseUrl,
|
|
334
389
|
status: "success"
|
|
335
390
|
});
|
|
336
|
-
|
|
391
|
+
this._log(
|
|
392
|
+
"DEBUG",
|
|
337
393
|
`[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`
|
|
338
394
|
);
|
|
339
395
|
return {
|
|
@@ -351,7 +407,7 @@ var CashuSpender = class {
|
|
|
351
407
|
if (!storedToken) return null;
|
|
352
408
|
const pendingDistribution = this.storageAdapter.getCachedTokenDistribution();
|
|
353
409
|
const balanceForBaseUrl = pendingDistribution.find((b) => b.baseUrl === baseUrl)?.amount || 0;
|
|
354
|
-
|
|
410
|
+
this._log("DEBUG", "RESUINGDSR GSODGNSD", balanceForBaseUrl, amount);
|
|
355
411
|
if (balanceForBaseUrl > amount) {
|
|
356
412
|
const units = this.walletAdapter.getMintUnits();
|
|
357
413
|
const unit = units[mintUrl] || "sat";
|
|
@@ -369,7 +425,7 @@ var CashuSpender = class {
|
|
|
369
425
|
baseUrl,
|
|
370
426
|
amount: topUpAmount
|
|
371
427
|
});
|
|
372
|
-
|
|
428
|
+
this._log("DEBUG", "TOPUP ", topUpResult);
|
|
373
429
|
if (topUpResult.success && topUpResult.toppedUpAmount) {
|
|
374
430
|
const newBalance = balanceForBaseUrl + topUpResult.toppedUpAmount;
|
|
375
431
|
const units = this.walletAdapter.getMintUnits();
|
|
@@ -391,7 +447,7 @@ var CashuSpender = class {
|
|
|
391
447
|
baseUrl,
|
|
392
448
|
storedToken
|
|
393
449
|
);
|
|
394
|
-
|
|
450
|
+
this._log("DEBUG", providerBalance);
|
|
395
451
|
if (providerBalance <= 0) {
|
|
396
452
|
this.storageAdapter.removeToken(baseUrl);
|
|
397
453
|
}
|
|
@@ -410,7 +466,7 @@ var CashuSpender = class {
|
|
|
410
466
|
const refundResults = await Promise.allSettled(
|
|
411
467
|
toRefund.map(async (pending) => {
|
|
412
468
|
const token = this.storageAdapter.getToken(pending.baseUrl);
|
|
413
|
-
|
|
469
|
+
this._log("DEBUG", token, this.balanceManager);
|
|
414
470
|
if (!token || !this.balanceManager) {
|
|
415
471
|
return { baseUrl: pending.baseUrl, success: false };
|
|
416
472
|
}
|
|
@@ -426,7 +482,7 @@ var CashuSpender = class {
|
|
|
426
482
|
baseUrl: pending.baseUrl,
|
|
427
483
|
token
|
|
428
484
|
});
|
|
429
|
-
|
|
485
|
+
this._log("DEBUG", result);
|
|
430
486
|
if (result.success) {
|
|
431
487
|
this.storageAdapter.removeToken(pending.baseUrl);
|
|
432
488
|
}
|
|
@@ -524,11 +580,22 @@ var CashuSpender = class {
|
|
|
524
580
|
|
|
525
581
|
// wallet/BalanceManager.ts
|
|
526
582
|
var BalanceManager = class {
|
|
527
|
-
constructor(walletAdapter, storageAdapter, providerRegistry) {
|
|
583
|
+
constructor(walletAdapter, storageAdapter, providerRegistry, cashuSpender) {
|
|
528
584
|
this.walletAdapter = walletAdapter;
|
|
529
585
|
this.storageAdapter = storageAdapter;
|
|
530
586
|
this.providerRegistry = providerRegistry;
|
|
587
|
+
if (cashuSpender) {
|
|
588
|
+
this.cashuSpender = cashuSpender;
|
|
589
|
+
} else {
|
|
590
|
+
this.cashuSpender = new CashuSpender(
|
|
591
|
+
walletAdapter,
|
|
592
|
+
storageAdapter,
|
|
593
|
+
providerRegistry,
|
|
594
|
+
this
|
|
595
|
+
);
|
|
596
|
+
}
|
|
531
597
|
}
|
|
598
|
+
cashuSpender;
|
|
532
599
|
/**
|
|
533
600
|
* Unified refund - handles both NIP-60 and legacy wallet refunds
|
|
534
601
|
*/
|
|
@@ -563,7 +630,7 @@ var BalanceManager = class {
|
|
|
563
630
|
this.storageAdapter.removeToken(baseUrl);
|
|
564
631
|
return { success: true, message: "No balance to refund" };
|
|
565
632
|
}
|
|
566
|
-
const receiveResult = await this.
|
|
633
|
+
const receiveResult = await this.cashuSpender.receiveToken(
|
|
567
634
|
fetchResult.token
|
|
568
635
|
);
|
|
569
636
|
const totalAmountMsat = receiveResult.unit === "msat" ? receiveResult.amount : receiveResult.amount * 1e3;
|
|
@@ -608,7 +675,7 @@ var BalanceManager = class {
|
|
|
608
675
|
if (fetchResult.error === "No balance to refund") {
|
|
609
676
|
return { success: false, message: "No balance to refund" };
|
|
610
677
|
}
|
|
611
|
-
const receiveResult = await this.
|
|
678
|
+
const receiveResult = await this.cashuSpender.receiveToken(
|
|
612
679
|
fetchResult.token
|
|
613
680
|
);
|
|
614
681
|
const totalAmountMsat = receiveResult.unit === "msat" ? receiveResult.amount : receiveResult.amount * 1e3;
|
|
@@ -1049,7 +1116,7 @@ var BalanceManager = class {
|
|
|
1049
1116
|
*/
|
|
1050
1117
|
async _recoverFailedTopUp(cashuToken) {
|
|
1051
1118
|
try {
|
|
1052
|
-
await this.
|
|
1119
|
+
await this.cashuSpender.receiveToken(cashuToken);
|
|
1053
1120
|
} catch (error) {
|
|
1054
1121
|
console.error(
|
|
1055
1122
|
"[BalanceManager._recoverFailedTopUp] Failed to recover token",
|
|
@@ -1720,12 +1787,39 @@ var RoutstrClient = class {
|
|
|
1720
1787
|
providerManager;
|
|
1721
1788
|
alertLevel;
|
|
1722
1789
|
mode;
|
|
1790
|
+
debugLevel = "WARN";
|
|
1723
1791
|
/**
|
|
1724
1792
|
* Get the current client mode
|
|
1725
1793
|
*/
|
|
1726
1794
|
getMode() {
|
|
1727
1795
|
return this.mode;
|
|
1728
1796
|
}
|
|
1797
|
+
getDebugLevel() {
|
|
1798
|
+
return this.debugLevel;
|
|
1799
|
+
}
|
|
1800
|
+
setDebugLevel(level) {
|
|
1801
|
+
this.debugLevel = level;
|
|
1802
|
+
}
|
|
1803
|
+
_log(level, ...args) {
|
|
1804
|
+
const levelPriority = {
|
|
1805
|
+
DEBUG: 0,
|
|
1806
|
+
WARN: 1,
|
|
1807
|
+
ERROR: 2
|
|
1808
|
+
};
|
|
1809
|
+
if (levelPriority[level] >= levelPriority[this.debugLevel]) {
|
|
1810
|
+
switch (level) {
|
|
1811
|
+
case "DEBUG":
|
|
1812
|
+
console.log(...args);
|
|
1813
|
+
break;
|
|
1814
|
+
case "WARN":
|
|
1815
|
+
console.warn(...args);
|
|
1816
|
+
break;
|
|
1817
|
+
case "ERROR":
|
|
1818
|
+
console.error(...args);
|
|
1819
|
+
break;
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1729
1823
|
/**
|
|
1730
1824
|
* Get the CashuSpender instance
|
|
1731
1825
|
*/
|
|
@@ -1789,7 +1883,7 @@ var RoutstrClient = class {
|
|
|
1789
1883
|
amount: requiredSats,
|
|
1790
1884
|
baseUrl
|
|
1791
1885
|
});
|
|
1792
|
-
|
|
1886
|
+
this._log("DEBUG", token, baseUrl);
|
|
1793
1887
|
let requestBody = body;
|
|
1794
1888
|
if (body && typeof body === "object") {
|
|
1795
1889
|
const bodyObj = body;
|
|
@@ -1813,8 +1907,9 @@ var RoutstrClient = class {
|
|
|
1813
1907
|
});
|
|
1814
1908
|
const tokenBalanceInSats = tokenBalanceUnit === "msat" ? tokenBalance / 1e3 : tokenBalance;
|
|
1815
1909
|
const baseUrlUsed = response.baseUrl || baseUrl;
|
|
1910
|
+
const tokenUsed = response.token || token;
|
|
1816
1911
|
await this._handlePostResponseBalanceUpdate({
|
|
1817
|
-
token,
|
|
1912
|
+
token: tokenUsed,
|
|
1818
1913
|
baseUrl: baseUrlUsed,
|
|
1819
1914
|
initialTokenBalance: tokenBalanceInSats,
|
|
1820
1915
|
response
|
|
@@ -1950,14 +2045,15 @@ var RoutstrClient = class {
|
|
|
1950
2045
|
const { path, method, body, baseUrl, token, headers } = params;
|
|
1951
2046
|
try {
|
|
1952
2047
|
const url = `${baseUrl.replace(/\/$/, "")}${path}`;
|
|
1953
|
-
if (this.mode === "xcashu")
|
|
2048
|
+
if (this.mode === "xcashu") this._log("DEBUG", "HEADERS,", headers);
|
|
1954
2049
|
const response = await fetch(url, {
|
|
1955
2050
|
method,
|
|
1956
2051
|
headers,
|
|
1957
2052
|
body: body === void 0 || method === "GET" ? void 0 : JSON.stringify(body)
|
|
1958
2053
|
});
|
|
1959
|
-
if (this.mode === "xcashu")
|
|
2054
|
+
if (this.mode === "xcashu") this._log("DEBUG", "response,", response);
|
|
1960
2055
|
response.baseUrl = baseUrl;
|
|
2056
|
+
response.token = token;
|
|
1961
2057
|
if (!response.ok) {
|
|
1962
2058
|
const requestId = response.headers.get("x-routstr-request-id") || void 0;
|
|
1963
2059
|
return await this._handleErrorResponse(
|
|
@@ -1987,38 +2083,44 @@ var RoutstrClient = class {
|
|
|
1987
2083
|
async _handleErrorResponse(params, token, status, requestId, xCashuRefundToken) {
|
|
1988
2084
|
const { path, method, body, selectedModel, baseUrl, mintUrl } = params;
|
|
1989
2085
|
let tryNextProvider = false;
|
|
1990
|
-
|
|
2086
|
+
this._log(
|
|
2087
|
+
"DEBUG",
|
|
1991
2088
|
`[RoutstrClient] _handleErrorResponse: status=${status}, baseUrl=${baseUrl}, mode=${this.mode}, token preview=${token}, requestId=${requestId}`
|
|
1992
2089
|
);
|
|
1993
|
-
|
|
2090
|
+
this._log(
|
|
2091
|
+
"DEBUG",
|
|
1994
2092
|
`[RoutstrClient] _handleErrorResponse: Attempting to receive/restore token for ${baseUrl}`
|
|
1995
2093
|
);
|
|
1996
2094
|
if (params.token.startsWith("cashu")) {
|
|
1997
|
-
const tryReceiveTokenResult = await this.
|
|
2095
|
+
const tryReceiveTokenResult = await this.cashuSpender.receiveToken(
|
|
1998
2096
|
params.token
|
|
1999
2097
|
);
|
|
2000
2098
|
if (tryReceiveTokenResult.success) {
|
|
2001
|
-
|
|
2099
|
+
this._log(
|
|
2100
|
+
"DEBUG",
|
|
2002
2101
|
`[RoutstrClient] _handleErrorResponse: Token restored successfully, amount=${tryReceiveTokenResult.amount}`
|
|
2003
2102
|
);
|
|
2004
2103
|
tryNextProvider = true;
|
|
2005
2104
|
if (this.mode === "lazyrefund")
|
|
2006
2105
|
this.storageAdapter.removeToken(baseUrl);
|
|
2007
2106
|
} else {
|
|
2008
|
-
|
|
2009
|
-
|
|
2107
|
+
this._log(
|
|
2108
|
+
"DEBUG",
|
|
2109
|
+
`[RoutstrClient] _handleErrorResponse: Failed to receive token. `
|
|
2010
2110
|
);
|
|
2011
2111
|
}
|
|
2012
2112
|
}
|
|
2013
2113
|
if (this.mode === "xcashu") {
|
|
2014
2114
|
if (xCashuRefundToken) {
|
|
2015
|
-
|
|
2115
|
+
this._log(
|
|
2116
|
+
"DEBUG",
|
|
2016
2117
|
`[RoutstrClient] _handleErrorResponse: Attempting to receive xcashu refund token, preview=${xCashuRefundToken.substring(0, 20)}...`
|
|
2017
2118
|
);
|
|
2018
2119
|
try {
|
|
2019
|
-
const receiveResult = await this.
|
|
2120
|
+
const receiveResult = await this.cashuSpender.receiveToken(xCashuRefundToken);
|
|
2020
2121
|
if (receiveResult.success) {
|
|
2021
|
-
|
|
2122
|
+
this._log(
|
|
2123
|
+
"DEBUG",
|
|
2022
2124
|
`[RoutstrClient] _handleErrorResponse: xcashu refund received, amount=${receiveResult.amount}`
|
|
2023
2125
|
);
|
|
2024
2126
|
tryNextProvider = true;
|
|
@@ -2030,7 +2132,7 @@ var RoutstrClient = class {
|
|
|
2030
2132
|
requestId
|
|
2031
2133
|
);
|
|
2032
2134
|
} catch (error) {
|
|
2033
|
-
|
|
2135
|
+
this._log("ERROR", "[xcashu] Failed to receive refund token:", error);
|
|
2034
2136
|
throw new ProviderError(
|
|
2035
2137
|
baseUrl,
|
|
2036
2138
|
status,
|
|
@@ -2055,7 +2157,8 @@ var RoutstrClient = class {
|
|
|
2055
2157
|
amount: params.requiredSats * TOPUP_MARGIN,
|
|
2056
2158
|
token: params.token
|
|
2057
2159
|
});
|
|
2058
|
-
|
|
2160
|
+
this._log(
|
|
2161
|
+
"DEBUG",
|
|
2059
2162
|
`[RoutstrClient] _handleErrorResponse: Topup result for ${baseUrl}: success=${topupResult.success}, message=${topupResult.message}`
|
|
2060
2163
|
);
|
|
2061
2164
|
if (!topupResult.success) {
|
|
@@ -2065,18 +2168,21 @@ var RoutstrClient = class {
|
|
|
2065
2168
|
const haveMatch = message.match(/have (\d+)/);
|
|
2066
2169
|
const required = needMatch ? parseInt(needMatch[1], 10) : params.requiredSats;
|
|
2067
2170
|
const available = haveMatch ? parseInt(haveMatch[1], 10) : 0;
|
|
2068
|
-
|
|
2171
|
+
this._log(
|
|
2172
|
+
"DEBUG",
|
|
2069
2173
|
`[RoutstrClient] _handleErrorResponse: Insufficient balance, need=${required}, have=${available}`
|
|
2070
2174
|
);
|
|
2071
2175
|
throw new InsufficientBalanceError(required, available);
|
|
2072
2176
|
} else {
|
|
2073
|
-
|
|
2177
|
+
this._log(
|
|
2178
|
+
"DEBUG",
|
|
2074
2179
|
`[RoutstrClient] _handleErrorResponse: Topup failed with non-insufficient-balance error, will try next provider`
|
|
2075
2180
|
);
|
|
2076
2181
|
tryNextProvider = true;
|
|
2077
2182
|
}
|
|
2078
2183
|
} else {
|
|
2079
|
-
|
|
2184
|
+
this._log(
|
|
2185
|
+
"DEBUG",
|
|
2080
2186
|
`[RoutstrClient] _handleErrorResponse: Topup successful, will retry with new token`
|
|
2081
2187
|
);
|
|
2082
2188
|
}
|
|
@@ -2087,8 +2193,9 @@ var RoutstrClient = class {
|
|
|
2087
2193
|
headers: this._withAuthHeader(params.baseHeaders, params.token)
|
|
2088
2194
|
});
|
|
2089
2195
|
}
|
|
2090
|
-
if ((status === 401 || status === 403 || status === 413 || status === 400 || status === 500 || status === 502 || status === 503 || status === 521) && !tryNextProvider) {
|
|
2091
|
-
|
|
2196
|
+
if ((status === 401 || status === 403 || status === 413 || status === 400 || status === 500 || status === 502 || status === 503 || status === 504 || status === 521) && !tryNextProvider) {
|
|
2197
|
+
this._log(
|
|
2198
|
+
"DEBUG",
|
|
2092
2199
|
`[RoutstrClient] _handleErrorResponse: Status ${status} (auth/server error), attempting refund for ${baseUrl}, mode=${this.mode}`
|
|
2093
2200
|
);
|
|
2094
2201
|
if (this.mode === "lazyrefund") {
|
|
@@ -2098,7 +2205,8 @@ var RoutstrClient = class {
|
|
|
2098
2205
|
baseUrl,
|
|
2099
2206
|
token: params.token
|
|
2100
2207
|
});
|
|
2101
|
-
|
|
2208
|
+
this._log(
|
|
2209
|
+
"DEBUG",
|
|
2102
2210
|
`[RoutstrClient] _handleErrorResponse: Lazyrefund result: success=${refundResult.success}`
|
|
2103
2211
|
);
|
|
2104
2212
|
if (refundResult.success) this.storageAdapter.removeToken(baseUrl);
|
|
@@ -2118,14 +2226,16 @@ var RoutstrClient = class {
|
|
|
2118
2226
|
);
|
|
2119
2227
|
}
|
|
2120
2228
|
} else if (this.mode === "apikeys") {
|
|
2121
|
-
|
|
2229
|
+
this._log(
|
|
2230
|
+
"DEBUG",
|
|
2122
2231
|
`[RoutstrClient] _handleErrorResponse: Attempting API key refund for ${baseUrl}, key preview=${token}`
|
|
2123
2232
|
);
|
|
2124
2233
|
const initialBalance = await this.balanceManager.getTokenBalance(
|
|
2125
2234
|
token,
|
|
2126
2235
|
baseUrl
|
|
2127
2236
|
);
|
|
2128
|
-
|
|
2237
|
+
this._log(
|
|
2238
|
+
"DEBUG",
|
|
2129
2239
|
`[RoutstrClient] _handleErrorResponse: Initial API key balance: ${initialBalance.amount}`
|
|
2130
2240
|
);
|
|
2131
2241
|
const refundResult = await this.balanceManager.refundApiKey({
|
|
@@ -2133,7 +2243,8 @@ var RoutstrClient = class {
|
|
|
2133
2243
|
baseUrl,
|
|
2134
2244
|
apiKey: token
|
|
2135
2245
|
});
|
|
2136
|
-
|
|
2246
|
+
this._log(
|
|
2247
|
+
"DEBUG",
|
|
2137
2248
|
`[RoutstrClient] _handleErrorResponse: API key refund result: success=${refundResult.success}, message=${refundResult.message}`
|
|
2138
2249
|
);
|
|
2139
2250
|
if (!refundResult.success && initialBalance.amount > 0) {
|
|
@@ -2148,7 +2259,8 @@ var RoutstrClient = class {
|
|
|
2148
2259
|
}
|
|
2149
2260
|
}
|
|
2150
2261
|
this.providerManager.markFailed(baseUrl);
|
|
2151
|
-
|
|
2262
|
+
this._log(
|
|
2263
|
+
"DEBUG",
|
|
2152
2264
|
`[RoutstrClient] _handleErrorResponse: Marked provider ${baseUrl} as failed`
|
|
2153
2265
|
);
|
|
2154
2266
|
if (!selectedModel) {
|
|
@@ -2163,7 +2275,8 @@ var RoutstrClient = class {
|
|
|
2163
2275
|
baseUrl
|
|
2164
2276
|
);
|
|
2165
2277
|
if (nextProvider) {
|
|
2166
|
-
|
|
2278
|
+
this._log(
|
|
2279
|
+
"DEBUG",
|
|
2167
2280
|
`[RoutstrClient] _handleErrorResponse: Failing over to next provider: ${nextProvider}, model: ${selectedModel.id}`
|
|
2168
2281
|
);
|
|
2169
2282
|
const newModel = await this.providerManager.getModelForProvider(
|
|
@@ -2178,7 +2291,8 @@ var RoutstrClient = class {
|
|
|
2178
2291
|
messagesForPricing,
|
|
2179
2292
|
params.maxTokens
|
|
2180
2293
|
);
|
|
2181
|
-
|
|
2294
|
+
this._log(
|
|
2295
|
+
"DEBUG",
|
|
2182
2296
|
`[RoutstrClient] _handleErrorResponse: Creating new token for failover provider ${nextProvider}, required sats: ${newRequiredSats}`
|
|
2183
2297
|
);
|
|
2184
2298
|
const spendResult = await this._spendToken({
|
|
@@ -2210,10 +2324,10 @@ var RoutstrClient = class {
|
|
|
2210
2324
|
const refundToken = response.headers.get("x-cashu") ?? void 0;
|
|
2211
2325
|
if (refundToken) {
|
|
2212
2326
|
try {
|
|
2213
|
-
const receiveResult = await this.
|
|
2327
|
+
const receiveResult = await this.cashuSpender.receiveToken(refundToken);
|
|
2214
2328
|
satsSpent = initialTokenBalance - receiveResult.amount * (receiveResult.unit == "sat" ? 1 : 1e3);
|
|
2215
2329
|
} catch (error) {
|
|
2216
|
-
|
|
2330
|
+
this._log("ERROR", "[xcashu] Failed to receive refund token:", error);
|
|
2217
2331
|
}
|
|
2218
2332
|
}
|
|
2219
2333
|
} else if (this.mode === "lazyrefund") {
|
|
@@ -2230,7 +2344,8 @@ var RoutstrClient = class {
|
|
|
2230
2344
|
token,
|
|
2231
2345
|
baseUrl
|
|
2232
2346
|
);
|
|
2233
|
-
|
|
2347
|
+
this._log(
|
|
2348
|
+
"DEBUG",
|
|
2234
2349
|
"LATEST Balance",
|
|
2235
2350
|
latestBalanceInfo.amount,
|
|
2236
2351
|
latestBalanceInfo.reserved,
|
|
@@ -2242,7 +2357,7 @@ var RoutstrClient = class {
|
|
|
2242
2357
|
this.storageAdapter.updateApiKeyBalance(baseUrl, latestTokenBalance);
|
|
2243
2358
|
satsSpent = initialTokenBalance - latestTokenBalance;
|
|
2244
2359
|
} catch (e) {
|
|
2245
|
-
|
|
2360
|
+
this._log("WARN", "Could not get updated API key balance:", e);
|
|
2246
2361
|
satsSpent = fallbackSatsSpent ?? initialTokenBalance;
|
|
2247
2362
|
}
|
|
2248
2363
|
}
|
|
@@ -2353,11 +2468,12 @@ var RoutstrClient = class {
|
|
|
2353
2468
|
* Handle errors and notify callbacks
|
|
2354
2469
|
*/
|
|
2355
2470
|
_handleError(error, callbacks) {
|
|
2356
|
-
|
|
2471
|
+
this._log("ERROR", "[RoutstrClient] _handleError: Error occurred", error);
|
|
2357
2472
|
if (error instanceof Error) {
|
|
2358
2473
|
const isStreamError = error.message.includes("Error in input stream") || error.message.includes("Load failed");
|
|
2359
2474
|
const modifiedErrorMsg = isStreamError ? "AI stream was cut off, turn on Keep Active or please try again" : error.message;
|
|
2360
|
-
|
|
2475
|
+
this._log(
|
|
2476
|
+
"ERROR",
|
|
2361
2477
|
`[RoutstrClient] _handleError: Error type=${error.constructor.name}, message=${modifiedErrorMsg}, isStreamError=${isStreamError}`
|
|
2362
2478
|
);
|
|
2363
2479
|
callbacks.onMessageAppend({
|
|
@@ -2386,13 +2502,15 @@ var RoutstrClient = class {
|
|
|
2386
2502
|
*/
|
|
2387
2503
|
async _spendToken(params) {
|
|
2388
2504
|
const { mintUrl, amount, baseUrl } = params;
|
|
2389
|
-
|
|
2505
|
+
this._log(
|
|
2506
|
+
"DEBUG",
|
|
2390
2507
|
`[RoutstrClient] _spendToken: mode=${this.mode}, amount=${amount}, baseUrl=${baseUrl}, mintUrl=${mintUrl}`
|
|
2391
2508
|
);
|
|
2392
2509
|
if (this.mode === "apikeys") {
|
|
2393
2510
|
let parentApiKey = this.storageAdapter.getApiKey(baseUrl);
|
|
2394
2511
|
if (!parentApiKey) {
|
|
2395
|
-
|
|
2512
|
+
this._log(
|
|
2513
|
+
"DEBUG",
|
|
2396
2514
|
`[RoutstrClient] _spendToken: No existing API key for ${baseUrl}, creating new one via Cashu`
|
|
2397
2515
|
);
|
|
2398
2516
|
const spendResult2 = await this.cashuSpender.spend({
|
|
@@ -2402,7 +2520,8 @@ var RoutstrClient = class {
|
|
|
2402
2520
|
reuseToken: false
|
|
2403
2521
|
});
|
|
2404
2522
|
if (!spendResult2.token) {
|
|
2405
|
-
|
|
2523
|
+
this._log(
|
|
2524
|
+
"ERROR",
|
|
2406
2525
|
`[RoutstrClient] _spendToken: Failed to create Cashu token for API key creation, error:`,
|
|
2407
2526
|
spendResult2.error
|
|
2408
2527
|
);
|
|
@@ -2410,30 +2529,35 @@ var RoutstrClient = class {
|
|
|
2410
2529
|
`[RoutstrClient] _spendToken: Failed to create Cashu token for API key creation, error: ${spendResult2.error}`
|
|
2411
2530
|
);
|
|
2412
2531
|
} else {
|
|
2413
|
-
|
|
2532
|
+
this._log(
|
|
2533
|
+
"DEBUG",
|
|
2414
2534
|
`[RoutstrClient] _spendToken: Cashu token created, token preview: ${spendResult2.token}`
|
|
2415
2535
|
);
|
|
2416
2536
|
}
|
|
2417
|
-
|
|
2537
|
+
this._log(
|
|
2538
|
+
"DEBUG",
|
|
2418
2539
|
`[RoutstrClient] _spendToken: Created API key for ${baseUrl}, key preview: ${spendResult2.token}, balance: ${spendResult2.balance}`
|
|
2419
2540
|
);
|
|
2420
2541
|
try {
|
|
2421
2542
|
this.storageAdapter.setApiKey(baseUrl, spendResult2.token);
|
|
2422
2543
|
} catch (error) {
|
|
2423
2544
|
if (error instanceof Error && error.message.includes("ApiKey already exists")) {
|
|
2424
|
-
const tryReceiveTokenResult = await this.
|
|
2545
|
+
const tryReceiveTokenResult = await this.cashuSpender.receiveToken(
|
|
2425
2546
|
spendResult2.token
|
|
2426
2547
|
);
|
|
2427
2548
|
if (tryReceiveTokenResult.success) {
|
|
2428
|
-
|
|
2549
|
+
this._log(
|
|
2550
|
+
"DEBUG",
|
|
2429
2551
|
`[RoutstrClient] _handleErrorResponse: Token restored successfully, amount=${tryReceiveTokenResult.amount}`
|
|
2430
2552
|
);
|
|
2431
2553
|
} else {
|
|
2432
|
-
|
|
2554
|
+
this._log(
|
|
2555
|
+
"DEBUG",
|
|
2433
2556
|
`[RoutstrClient] _handleErrorResponse: Token restore failed or not needed`
|
|
2434
2557
|
);
|
|
2435
2558
|
}
|
|
2436
|
-
|
|
2559
|
+
this._log(
|
|
2560
|
+
"DEBUG",
|
|
2437
2561
|
`[RoutstrClient] _spendToken: API key already exists for ${baseUrl}, using existing key`
|
|
2438
2562
|
);
|
|
2439
2563
|
} else {
|
|
@@ -2442,7 +2566,8 @@ var RoutstrClient = class {
|
|
|
2442
2566
|
}
|
|
2443
2567
|
parentApiKey = this.storageAdapter.getApiKey(baseUrl);
|
|
2444
2568
|
} else {
|
|
2445
|
-
|
|
2569
|
+
this._log(
|
|
2570
|
+
"DEBUG",
|
|
2446
2571
|
`[RoutstrClient] _spendToken: Using existing API key for ${baseUrl}, key preview: ${parentApiKey.key}`
|
|
2447
2572
|
);
|
|
2448
2573
|
}
|
|
@@ -2464,10 +2589,11 @@ var RoutstrClient = class {
|
|
|
2464
2589
|
tokenBalance = balanceInfo.amount;
|
|
2465
2590
|
tokenBalanceUnit = balanceInfo.unit;
|
|
2466
2591
|
} catch (e) {
|
|
2467
|
-
|
|
2592
|
+
this._log("WARN", "Could not get initial API key balance:", e);
|
|
2468
2593
|
}
|
|
2469
2594
|
}
|
|
2470
|
-
|
|
2595
|
+
this._log(
|
|
2596
|
+
"DEBUG",
|
|
2471
2597
|
`[RoutstrClient] _spendToken: Returning token with balance=${tokenBalance} ${tokenBalanceUnit}`
|
|
2472
2598
|
);
|
|
2473
2599
|
return {
|
|
@@ -2476,7 +2602,8 @@ var RoutstrClient = class {
|
|
|
2476
2602
|
tokenBalanceUnit
|
|
2477
2603
|
};
|
|
2478
2604
|
}
|
|
2479
|
-
|
|
2605
|
+
this._log(
|
|
2606
|
+
"DEBUG",
|
|
2480
2607
|
`[RoutstrClient] _spendToken: Calling CashuSpender.spend for amount=${amount}, mintUrl=${mintUrl}, mode=${this.mode}`
|
|
2481
2608
|
);
|
|
2482
2609
|
const spendResult = await this.cashuSpender.spend({
|
|
@@ -2486,12 +2613,14 @@ var RoutstrClient = class {
|
|
|
2486
2613
|
reuseToken: this.mode === "lazyrefund"
|
|
2487
2614
|
});
|
|
2488
2615
|
if (!spendResult.token) {
|
|
2489
|
-
|
|
2616
|
+
this._log(
|
|
2617
|
+
"ERROR",
|
|
2490
2618
|
`[RoutstrClient] _spendToken: CashuSpender.spend failed, error:`,
|
|
2491
2619
|
spendResult.error
|
|
2492
2620
|
);
|
|
2493
2621
|
} else {
|
|
2494
|
-
|
|
2622
|
+
this._log(
|
|
2623
|
+
"DEBUG",
|
|
2495
2624
|
`[RoutstrClient] _spendToken: Cashu token created, token preview: ${spendResult.token}, balance: ${spendResult.balance} ${spendResult.unit ?? "sat"}`
|
|
2496
2625
|
);
|
|
2497
2626
|
}
|