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