@routstr/sdk 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1183,6 +1183,14 @@ var BalanceManager = class {
1183
1183
  console.log(response.status);
1184
1184
  const data = await response.json();
1185
1185
  console.log("FAILED ", data);
1186
+ const isInvalidApiKey = response.status === 401 && data?.code === "invalid_api_key" && data?.message?.includes("proofs already spent");
1187
+ return {
1188
+ amount: -1,
1189
+ reserved: data.reserved ?? 0,
1190
+ unit: "msat",
1191
+ apiKey: data.api_key,
1192
+ isInvalidApiKey
1193
+ };
1186
1194
  }
1187
1195
  } catch (error) {
1188
1196
  console.error("ERRORR IN RESTPONSE", error);
@@ -2075,7 +2083,8 @@ var RoutstrClient = class {
2075
2083
  response.status,
2076
2084
  requestId,
2077
2085
  this.mode === "xcashu" ? response.headers.get("x-cashu") ?? void 0 : void 0,
2078
- bodyText
2086
+ bodyText,
2087
+ params.retryCount ?? 0
2079
2088
  );
2080
2089
  }
2081
2090
  return response;
@@ -2084,8 +2093,12 @@ var RoutstrClient = class {
2084
2093
  return await this._handleErrorResponse(
2085
2094
  params,
2086
2095
  token,
2087
- -1
2096
+ -1,
2088
2097
  // just for Network Error to skip all statuses
2098
+ void 0,
2099
+ void 0,
2100
+ void 0,
2101
+ params.retryCount ?? 0
2089
2102
  );
2090
2103
  }
2091
2104
  throw error;
@@ -2094,7 +2107,8 @@ var RoutstrClient = class {
2094
2107
  /**
2095
2108
  * Handle error responses with failover
2096
2109
  */
2097
- async _handleErrorResponse(params, token, status, requestId, xCashuRefundToken, responseBody) {
2110
+ async _handleErrorResponse(params, token, status, requestId, xCashuRefundToken, responseBody, retryCount = 0) {
2111
+ const MAX_RETRIES_PER_PROVIDER = 2;
2098
2112
  const { path, method, body, selectedModel, baseUrl, mintUrl } = params;
2099
2113
  let tryNextProvider = false;
2100
2114
  this._log(
@@ -2164,8 +2178,7 @@ var RoutstrClient = class {
2164
2178
  );
2165
2179
  }
2166
2180
  }
2167
- if ((status === 402 || status === 413 && responseBody?.includes("Insufficient balance")) && !tryNextProvider && (this.mode === "apikeys" || this.mode === "lazyrefund")) {
2168
- console.log("RESPONSFE ", responseBody);
2181
+ if (status === 402 && !tryNextProvider && (this.mode === "apikeys" || this.mode === "lazyrefund")) {
2169
2182
  const topupResult = await this.balanceManager.topUp({
2170
2183
  mintUrl,
2171
2184
  baseUrl,
@@ -2201,12 +2214,83 @@ var RoutstrClient = class {
2201
2214
  `[RoutstrClient] _handleErrorResponse: Topup successful, will retry with new token`
2202
2215
  );
2203
2216
  }
2204
- if (!tryNextProvider)
2217
+ if (!tryNextProvider) {
2218
+ if (retryCount < MAX_RETRIES_PER_PROVIDER) {
2219
+ this._log(
2220
+ "DEBUG",
2221
+ `[RoutstrClient] _handleErrorResponse: Retrying 402 (attempt ${retryCount + 1}/${MAX_RETRIES_PER_PROVIDER})`
2222
+ );
2223
+ return this._makeRequest({
2224
+ ...params,
2225
+ token: params.token,
2226
+ headers: this._withAuthHeader(params.baseHeaders, params.token),
2227
+ retryCount: retryCount + 1
2228
+ });
2229
+ } else {
2230
+ this._log(
2231
+ "DEBUG",
2232
+ `[RoutstrClient] _handleErrorResponse: 402 retry limit reached (${retryCount}/${MAX_RETRIES_PER_PROVIDER}), failing over to next provider`
2233
+ );
2234
+ tryNextProvider = true;
2235
+ }
2236
+ }
2237
+ }
2238
+ const isInsufficientBalance413 = status === 413 && responseBody?.includes("Insufficient balance");
2239
+ if (isInsufficientBalance413 && !tryNextProvider && this.mode === "apikeys") {
2240
+ let retryToken = params.token;
2241
+ try {
2242
+ const latestBalanceInfo = await this.balanceManager.getTokenBalance(
2243
+ params.token,
2244
+ baseUrl
2245
+ );
2246
+ if (latestBalanceInfo.isInvalidApiKey) {
2247
+ this._log(
2248
+ "DEBUG",
2249
+ `[RoutstrClient] _handleErrorResponse: Invalid API key (proofs already spent), removing for ${baseUrl}`
2250
+ );
2251
+ this.storageAdapter.removeApiKey(baseUrl);
2252
+ tryNextProvider = true;
2253
+ } else {
2254
+ const latestTokenBalance = latestBalanceInfo.unit === "msat" ? latestBalanceInfo.amount / 1e3 : latestBalanceInfo.amount;
2255
+ if (latestBalanceInfo.apiKey) {
2256
+ const storedApiKeyEntry = this.storageAdapter.getApiKey(baseUrl);
2257
+ if (storedApiKeyEntry?.key !== latestBalanceInfo.apiKey) {
2258
+ if (storedApiKeyEntry) {
2259
+ this.storageAdapter.removeApiKey(baseUrl);
2260
+ }
2261
+ this.storageAdapter.setApiKey(baseUrl, latestBalanceInfo.apiKey);
2262
+ }
2263
+ retryToken = latestBalanceInfo.apiKey;
2264
+ }
2265
+ if (latestTokenBalance >= 0) {
2266
+ this.storageAdapter.updateApiKeyBalance(baseUrl, latestTokenBalance);
2267
+ }
2268
+ }
2269
+ } catch (error) {
2270
+ this._log(
2271
+ "WARN",
2272
+ `[RoutstrClient] _handleErrorResponse: Failed to refresh API key after 413 insufficient balance for ${baseUrl}`,
2273
+ error
2274
+ );
2275
+ }
2276
+ if (retryCount < MAX_RETRIES_PER_PROVIDER) {
2277
+ this._log(
2278
+ "DEBUG",
2279
+ `[RoutstrClient] _handleErrorResponse: Retrying 413 (attempt ${retryCount + 1}/${MAX_RETRIES_PER_PROVIDER})`
2280
+ );
2205
2281
  return this._makeRequest({
2206
2282
  ...params,
2207
- token: params.token,
2208
- headers: this._withAuthHeader(params.baseHeaders, params.token)
2283
+ token: retryToken,
2284
+ headers: this._withAuthHeader(params.baseHeaders, retryToken),
2285
+ retryCount: retryCount + 1
2209
2286
  });
2287
+ } else {
2288
+ this._log(
2289
+ "DEBUG",
2290
+ `[RoutstrClient] _handleErrorResponse: 413 retry limit reached (${retryCount}/${MAX_RETRIES_PER_PROVIDER}), failing over to next provider`
2291
+ );
2292
+ tryNextProvider = true;
2293
+ }
2210
2294
  }
2211
2295
  if ((status === 401 || status === 403 || status === 413 || status === 400 || status === 500 || status === 502 || status === 503 || status === 504 || status === 521) && !tryNextProvider) {
2212
2296
  this._log(
@@ -2322,7 +2406,8 @@ var RoutstrClient = class {
2322
2406
  selectedModel: newModel,
2323
2407
  token: spendResult.token,
2324
2408
  requiredSats: newRequiredSats,
2325
- headers: this._withAuthHeader(params.baseHeaders, spendResult.token)
2409
+ headers: this._withAuthHeader(params.baseHeaders, spendResult.token),
2410
+ retryCount: 0
2326
2411
  });
2327
2412
  }
2328
2413
  throw new FailoverError(baseUrl, Array.from(this.providerManager));