@routstr/sdk 0.2.9 → 0.2.12

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.
@@ -50,6 +50,7 @@ declare class ProviderManager {
50
50
  getInstanceId(): string;
51
51
  /**
52
52
  * Clean up expired cooldown entries
53
+ * Also removes the provider from failedProviders so it can be retried
53
54
  */
54
55
  private cleanupExpiredCooldowns;
55
56
  /**
@@ -372,6 +373,21 @@ interface UsageTrackingData {
372
373
  satsCost: number;
373
374
  }
374
375
 
376
+ /**
377
+ * SSE parser transform that preserves event boundaries verbatim.
378
+ *
379
+ * Unlike a naive line-splitter, this buffers until a full SSE event is
380
+ * received (terminated by a blank line, per the SSE spec), then forwards the
381
+ * entire event unchanged downstream. This means:
382
+ * - Multi-line events (multiple `data:` lines, plus `event:`/`id:`/`retry:`
383
+ * fields) are preserved.
384
+ * - Comments / keepalives (lines beginning with `:`) are preserved.
385
+ * - Chunks that contain multiple events, or events split across chunks, are
386
+ * handled correctly without merging or losing packets.
387
+ *
388
+ * As a side-effect, it inspects `data:` payloads for usage/responseId and
389
+ * invokes the provided callbacks the first time each is seen.
390
+ */
375
391
  declare function createSSEParserTransform(onUsage: (usage: UsageTrackingData) => void, onResponseId?: (responseId: string) => void): Transform;
376
392
 
377
393
  export { type AlertLevel, type DebugLevel, type FetchOptions, type ModelProviderPrice, ProviderManager, type RouteRequestParams, type RouteRequestToNodeResponseParams, RoutstrClient, type RoutstrClientConfig, type RoutstrClientMode, type StreamCallbacks, StreamProcessor, createSSEParserTransform };
@@ -50,6 +50,7 @@ declare class ProviderManager {
50
50
  getInstanceId(): string;
51
51
  /**
52
52
  * Clean up expired cooldown entries
53
+ * Also removes the provider from failedProviders so it can be retried
53
54
  */
54
55
  private cleanupExpiredCooldowns;
55
56
  /**
@@ -372,6 +373,21 @@ interface UsageTrackingData {
372
373
  satsCost: number;
373
374
  }
374
375
 
376
+ /**
377
+ * SSE parser transform that preserves event boundaries verbatim.
378
+ *
379
+ * Unlike a naive line-splitter, this buffers until a full SSE event is
380
+ * received (terminated by a blank line, per the SSE spec), then forwards the
381
+ * entire event unchanged downstream. This means:
382
+ * - Multi-line events (multiple `data:` lines, plus `event:`/`id:`/`retry:`
383
+ * fields) are preserved.
384
+ * - Comments / keepalives (lines beginning with `:`) are preserved.
385
+ * - Chunks that contain multiple events, or events split across chunks, are
386
+ * handled correctly without merging or losing packets.
387
+ *
388
+ * As a side-effect, it inspects `data:` payloads for usage/responseId and
389
+ * invokes the provided callbacks the first time each is seen.
390
+ */
375
391
  declare function createSSEParserTransform(onUsage: (usage: UsageTrackingData) => void, onResponseId?: (responseId: string) => void): Transform;
376
392
 
377
393
  export { type AlertLevel, type DebugLevel, type FetchOptions, type ModelProviderPrice, ProviderManager, type RouteRequestParams, type RouteRequestToNodeResponseParams, RoutstrClient, type RoutstrClientConfig, type RoutstrClientMode, type StreamCallbacks, StreamProcessor, createSSEParserTransform };
@@ -3,6 +3,31 @@
3
3
  var cashuTs = require('@cashu/cashu-ts');
4
4
  var vanilla = require('zustand/vanilla');
5
5
  var stream = require('stream');
6
+ var fs = require('fs');
7
+ var path = require('path');
8
+ var os = require('os');
9
+
10
+ function _interopNamespace(e) {
11
+ if (e && e.__esModule) return e;
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () { return e[k]; }
20
+ });
21
+ }
22
+ });
23
+ }
24
+ n.default = e;
25
+ return Object.freeze(n);
26
+ }
27
+
28
+ var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
29
+ var path__namespace = /*#__PURE__*/_interopNamespace(path);
30
+ var os__namespace = /*#__PURE__*/_interopNamespace(os);
6
31
 
7
32
  // core/errors.ts
8
33
  var InsufficientBalanceError = class extends Error {
@@ -56,10 +81,10 @@ var AuditLogger = class _AuditLogger {
56
81
  const logLine = JSON.stringify(fullEntry) + "\n";
57
82
  if (typeof window === "undefined") {
58
83
  try {
59
- const fs = await import('fs');
60
- const path = await import('path');
61
- const logPath = path.join(process.cwd(), "audit.log");
62
- fs.appendFileSync(logPath, logLine);
84
+ const fs2 = await import('fs');
85
+ const path2 = await import('path');
86
+ const logPath = path2.join(process.cwd(), "audit.log");
87
+ fs2.appendFileSync(logPath, logLine);
63
88
  } catch (error) {
64
89
  console.error("[AuditLogger] Failed to write to file:", error);
65
90
  }
@@ -1295,17 +1320,48 @@ function extractResponseId(body) {
1295
1320
  return trimmed.length > 0 ? trimmed : void 0;
1296
1321
  }
1297
1322
  function extractUsageFromSSEJson(parsed, fallbackSatsCost = 0) {
1298
- if (!parsed || typeof parsed !== "object" || !parsed.usage) {
1323
+ if (!parsed || typeof parsed !== "object") {
1324
+ return null;
1325
+ }
1326
+ if (!parsed.usage && parsed.cost && typeof parsed.cost === "object") {
1327
+ const costObj = parsed.cost;
1328
+ const msats2 = costObj.total_msats ?? 0;
1329
+ const cost2 = costObj.total_usd ?? 0;
1330
+ if (msats2 === 0 && cost2 === 0) return null;
1331
+ return {
1332
+ promptTokens: Number(costObj.input_tokens ?? 0),
1333
+ completionTokens: Number(costObj.output_tokens ?? 0),
1334
+ totalTokens: Number((costObj.input_tokens ?? 0) + (costObj.output_tokens ?? 0)),
1335
+ cost: Number(cost2),
1336
+ satsCost: msats2 > 0 ? msats2 / 1e3 : fallbackSatsCost
1337
+ };
1338
+ }
1339
+ if (!parsed.usage) {
1299
1340
  return null;
1300
1341
  }
1301
1342
  const usage = parsed.usage;
1302
1343
  const usageCost = usage.cost;
1303
- const cost = typeof usageCost === "number" ? usageCost : usageCost?.total_usd ?? parsed.metadata?.routstr?.cost?.total_usd ?? 0;
1304
- const msats = parsed.metadata?.routstr?.cost?.total_msats ?? (typeof usage.cost_sats === "number" ? usage.cost_sats * 1e3 : 0);
1344
+ let cost = 0;
1345
+ let msats = 0;
1346
+ if (typeof usageCost === "number") {
1347
+ cost = usageCost;
1348
+ } else if (usageCost && typeof usageCost === "object") {
1349
+ cost = usageCost.total_usd ?? 0;
1350
+ msats = usageCost.total_msats ?? 0;
1351
+ }
1352
+ if (cost === 0) {
1353
+ cost = parsed.metadata?.routstr?.cost?.total_usd ?? 0;
1354
+ }
1355
+ if (msats === 0) {
1356
+ msats = parsed.metadata?.routstr?.cost?.total_msats ?? (typeof usage.cost_sats === "number" ? usage.cost_sats * 1e3 : 0);
1357
+ }
1358
+ const promptTokens = Number(usage.prompt_tokens ?? usage.input_tokens ?? 0);
1359
+ const completionTokens = Number(usage.completion_tokens ?? usage.output_tokens ?? 0);
1360
+ const totalTokens = Number(usage.total_tokens ?? promptTokens + completionTokens);
1305
1361
  const result = {
1306
- promptTokens: Number(usage.prompt_tokens ?? 0),
1307
- completionTokens: Number(usage.completion_tokens ?? 0),
1308
- totalTokens: Number(usage.total_tokens ?? 0),
1362
+ promptTokens,
1363
+ completionTokens,
1364
+ totalTokens,
1309
1365
  cost: Number(cost ?? 0),
1310
1366
  satsCost: msats > 0 ? msats / 1e3 : fallbackSatsCost
1311
1367
  };
@@ -1431,11 +1487,14 @@ var StreamProcessor = class {
1431
1487
  if (parsed.choices?.[0]?.delta?.reasoning) {
1432
1488
  result.reasoning = parsed.choices[0].delta.reasoning;
1433
1489
  }
1434
- if (parsed.usage) {
1435
- result.usage = toUsageStats(extractUsageFromSSEJson(parsed)) ?? {
1436
- total_tokens: parsed.usage.total_tokens,
1437
- prompt_tokens: parsed.usage.prompt_tokens,
1438
- completion_tokens: parsed.usage.completion_tokens
1490
+ const extractedUsage = extractUsageFromSSEJson(parsed);
1491
+ if (extractedUsage) {
1492
+ result.usage = toUsageStats(extractedUsage);
1493
+ } else if (parsed.usage) {
1494
+ result.usage = {
1495
+ total_tokens: parsed.usage.total_tokens ?? parsed.usage.input_tokens + parsed.usage.output_tokens,
1496
+ prompt_tokens: parsed.usage.prompt_tokens ?? parsed.usage.input_tokens,
1497
+ completion_tokens: parsed.usage.completion_tokens ?? parsed.usage.output_tokens
1439
1498
  };
1440
1499
  }
1441
1500
  if (parsed.id) {
@@ -1693,6 +1752,7 @@ var ProviderManager = class _ProviderManager {
1693
1752
  }
1694
1753
  /**
1695
1754
  * Clean up expired cooldown entries
1755
+ * Also removes the provider from failedProviders so it can be retried
1696
1756
  */
1697
1757
  cleanupExpiredCooldowns() {
1698
1758
  const now = Date.now();
@@ -1705,6 +1765,10 @@ var ProviderManager = class _ProviderManager {
1705
1765
  console.log(
1706
1766
  `[cleanupExpiredCooldowns:${this.instanceId}] Removing expired cooldown for ${url} (age: ${age}ms, cooldown: ${_ProviderManager.COOLDOWN_DURATION_MS}ms)`
1707
1767
  );
1768
+ this.failedProviders.delete(url);
1769
+ if (this.store) {
1770
+ this.store.getState().removeFailedProvider(url);
1771
+ }
1708
1772
  }
1709
1773
  return !isExpired;
1710
1774
  }
@@ -1878,22 +1942,49 @@ var ProviderManager = class _ProviderManager {
1878
1942
  const disabledProviders = new Set(
1879
1943
  this.providerRegistry.getDisabledProviders()
1880
1944
  );
1945
+ console.log(
1946
+ `[findNextBestProvider:${this.instanceId}] Starting search for model: ${modelId}`
1947
+ );
1948
+ console.log(
1949
+ `[findNextBestProvider:${this.instanceId}] disabledProviders: ${[...disabledProviders]}`
1950
+ );
1951
+ console.log(
1952
+ `[findNextBestProvider:${this.instanceId}] providersOnCooldown: ${this.providersOnCoolDown.map(([url]) => url)}`
1953
+ );
1881
1954
  const allProviders = this.providerRegistry.getAllProvidersModels();
1955
+ console.log(
1956
+ `[findNextBestProvider:${this.instanceId}] Total providers in registry: ${Object.keys(allProviders).length}`
1957
+ );
1882
1958
  const candidates = [];
1883
1959
  for (const [baseUrl, models] of Object.entries(allProviders)) {
1884
- if (baseUrl === currentBaseUrl || this.failedProviders.has(baseUrl) || disabledProviders.has(baseUrl) || this.isOnCooldown(baseUrl)) {
1960
+ if (baseUrl === currentBaseUrl) {
1961
+ console.log(
1962
+ `[findNextBestProvider:${this.instanceId}] SKIP (current): ${baseUrl}`
1963
+ );
1964
+ continue;
1965
+ }
1966
+ if (disabledProviders.has(baseUrl)) {
1967
+ continue;
1968
+ }
1969
+ if (this.isOnCooldown(baseUrl)) {
1885
1970
  continue;
1886
1971
  }
1887
1972
  if (!torMode && (isOnionUrl(baseUrl) || isInsecureHttpUrl(baseUrl))) {
1888
1973
  continue;
1889
1974
  }
1890
1975
  const model = models.find((m) => m.id === modelId);
1891
- if (!model) continue;
1976
+ if (!model) {
1977
+ continue;
1978
+ }
1892
1979
  const cost = model.sats_pricing?.completion ?? 0;
1893
1980
  candidates.push({ baseUrl, model, cost });
1894
1981
  }
1895
1982
  candidates.sort((a, b) => a.cost - b.cost);
1896
- return candidates.length > 0 ? candidates[0].baseUrl : null;
1983
+ if (candidates.length > 0) {
1984
+ return candidates[0].baseUrl;
1985
+ } else {
1986
+ return null;
1987
+ }
1897
1988
  } catch (error) {
1898
1989
  console.error("Error finding next best provider:", error);
1899
1990
  return null;
@@ -3364,69 +3455,95 @@ var getDefaultUsageTrackingDriver = () => {
3364
3455
  };
3365
3456
  function createSSEParserTransform(onUsage, onResponseId) {
3366
3457
  let buffer = "";
3367
- let usageCaptured = false;
3458
+ let capturedUsage = null;
3368
3459
  let responseIdCaptured = false;
3369
- const maybeCaptureUsageFromJson = (jsonText) => {
3460
+ const mergeUsage = (previous, next) => {
3461
+ if (!previous) return next;
3462
+ return {
3463
+ promptTokens: next.promptTokens > 0 ? next.promptTokens : previous.promptTokens,
3464
+ completionTokens: next.completionTokens > 0 ? next.completionTokens : previous.completionTokens,
3465
+ totalTokens: next.totalTokens > 0 ? next.totalTokens : previous.totalTokens,
3466
+ cost: next.cost > 0 ? next.cost : previous.cost,
3467
+ satsCost: next.satsCost > 0 ? next.satsCost : previous.satsCost
3468
+ };
3469
+ };
3470
+ const hasUsageChanged = (previous, next) => {
3471
+ if (!previous) return true;
3472
+ return previous.promptTokens !== next.promptTokens || previous.completionTokens !== next.completionTokens || previous.totalTokens !== next.totalTokens || previous.cost !== next.cost || previous.satsCost !== next.satsCost;
3473
+ };
3474
+ const inspectDataPayload = (jsonText) => {
3475
+ if (responseIdCaptured && capturedUsage?.satsCost && capturedUsage.totalTokens) {
3476
+ return;
3477
+ }
3478
+ const trimmed = jsonText.trim();
3479
+ if (!trimmed || trimmed === "[DONE]") return;
3480
+ if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return;
3370
3481
  try {
3371
- const data = JSON.parse(jsonText);
3372
- const responseId = data.id;
3373
- if (typeof responseId === "string" && responseId.trim().length > 0) {
3374
- onResponseId?.(responseId.trim());
3375
- responseIdCaptured = true;
3482
+ const data = JSON.parse(trimmed);
3483
+ if (!responseIdCaptured) {
3484
+ const responseId = data?.id;
3485
+ if (typeof responseId === "string" && responseId.trim().length > 0) {
3486
+ onResponseId?.(responseId.trim());
3487
+ responseIdCaptured = true;
3488
+ }
3376
3489
  }
3377
3490
  const usage = extractUsageFromSSEJson(data);
3378
3491
  if (usage) {
3379
- onUsage(usage);
3380
- usageCaptured = true;
3492
+ const mergedUsage = mergeUsage(capturedUsage, usage);
3493
+ if (hasUsageChanged(capturedUsage, mergedUsage)) {
3494
+ capturedUsage = mergedUsage;
3495
+ onUsage(mergedUsage);
3496
+ }
3381
3497
  }
3382
3498
  } catch {
3383
3499
  }
3384
3500
  };
3385
- const processLine = (self, line) => {
3386
- const trimmed = line.trim();
3387
- if (!trimmed) {
3501
+ const inspectEventBlock = (eventBlock) => {
3502
+ if (responseIdCaptured && capturedUsage?.satsCost && capturedUsage.totalTokens) {
3388
3503
  return;
3389
3504
  }
3390
- if (trimmed === "data: [DONE]" || trimmed === "[DONE]") {
3391
- self.push("data: [DONE]\n\n");
3392
- return;
3393
- }
3394
- if (trimmed.startsWith("data:")) {
3395
- const dataStr = trimmed.startsWith("data: ") ? trimmed.slice(6) : trimmed.slice(5).trimStart();
3396
- if (dataStr === "[DONE]") {
3397
- self.push("data: [DONE]\n\n");
3398
- return;
3505
+ const lines = eventBlock.split(/\r?\n/);
3506
+ const dataParts = [];
3507
+ for (const line of lines) {
3508
+ if (!line || line.startsWith(":")) continue;
3509
+ if (line.startsWith("data:")) {
3510
+ const value = line.startsWith("data: ") ? line.slice(6) : line.slice(5);
3511
+ dataParts.push(value);
3399
3512
  }
3400
- maybeCaptureUsageFromJson(dataStr);
3401
- self.push(`data: ${dataStr}
3402
-
3403
- `);
3404
- return;
3405
- }
3406
- if (trimmed.startsWith("{")) {
3407
- maybeCaptureUsageFromJson(trimmed);
3408
- self.push(`data: ${trimmed}
3409
-
3410
- `);
3411
- return;
3412
3513
  }
3413
- self.push(line + "\n");
3514
+ if (dataParts.length === 0) return;
3515
+ const payload = dataParts.join("\n");
3516
+ inspectDataPayload(payload);
3517
+ };
3518
+ const emitEventBlock = (self, eventBlock) => {
3519
+ if (eventBlock.length === 0) return;
3520
+ inspectEventBlock(eventBlock);
3521
+ self.push(eventBlock + "\n\n");
3414
3522
  };
3415
3523
  return new stream.Transform({
3416
- transform(chunk, encoding, callback) {
3524
+ transform(chunk, _encoding, callback) {
3417
3525
  buffer += chunk.toString();
3418
- const lines = buffer.split(/\r?\n/);
3419
- buffer = lines.pop() || "";
3420
- for (const line of lines) {
3421
- processLine(this, line);
3526
+ const terminator = /\r?\n\r?\n/g;
3527
+ let lastIndex = 0;
3528
+ let match;
3529
+ while ((match = terminator.exec(buffer)) !== null) {
3530
+ const block = buffer.slice(lastIndex, match.index);
3531
+ lastIndex = match.index + match[0].length;
3532
+ emitEventBlock(this, block);
3533
+ }
3534
+ if (lastIndex > 0) {
3535
+ buffer = buffer.slice(lastIndex);
3422
3536
  }
3423
3537
  callback();
3424
3538
  },
3425
3539
  flush(callback) {
3426
- if (buffer.trim()) {
3427
- processLine(this, buffer);
3540
+ if (buffer.length > 0) {
3541
+ const tail = buffer.replace(/\r?\n+$/, "");
3542
+ if (tail.length > 0) {
3543
+ emitEventBlock(this, tail);
3544
+ }
3545
+ buffer = "";
3428
3546
  }
3429
- buffer = "";
3430
3547
  callback();
3431
3548
  }
3432
3549
  });
@@ -3610,7 +3727,7 @@ var RoutstrClient = class {
3610
3727
  }
3611
3728
  async _prepareRoutedRequest(params) {
3612
3729
  const {
3613
- path,
3730
+ path: requestPath,
3614
3731
  method,
3615
3732
  body,
3616
3733
  headers = {},
@@ -3651,7 +3768,7 @@ var RoutstrClient = class {
3651
3768
  const baseHeaders = this._buildBaseHeaders();
3652
3769
  const requestHeaders = this._withAuthHeader(baseHeaders, token);
3653
3770
  const response = await this._makeRequest({
3654
- path,
3771
+ path: requestPath,
3655
3772
  method,
3656
3773
  body: method === "GET" ? void 0 : requestBody,
3657
3774
  baseUrl,
@@ -3670,7 +3787,20 @@ var RoutstrClient = class {
3670
3787
  let capturedUsage;
3671
3788
  let capturedResponseId;
3672
3789
  if (contentType.includes("text/event-stream") && response.body) {
3790
+ const logDir = path__namespace.join(os__namespace.homedir(), ".routstrd", "stream-response");
3791
+ if (!fs__namespace.existsSync(logDir)) {
3792
+ fs__namespace.mkdirSync(logDir, { recursive: true });
3793
+ }
3794
+ const logFile = path__namespace.join(logDir, `${Date.now()}.jsonl`);
3795
+ const logStream = fs__namespace.createWriteStream(logFile);
3673
3796
  const nodeReadable = stream.Readable.fromWeb(response.body);
3797
+ const loggingTransform = new stream.Transform({
3798
+ transform(chunk, encoding, callback) {
3799
+ const raw = chunk.toString();
3800
+ logStream.write(JSON.stringify({ raw, timestamp: Date.now() }) + "\n");
3801
+ callback(null, chunk);
3802
+ }
3803
+ });
3674
3804
  const sseParser = createSSEParserTransform(
3675
3805
  (usage) => {
3676
3806
  capturedUsage = usage;
@@ -3681,7 +3811,7 @@ var RoutstrClient = class {
3681
3811
  processedResponse.requestId = responseId;
3682
3812
  }
3683
3813
  );
3684
- const transformed = nodeReadable.pipe(sseParser, { end: true });
3814
+ const transformed = nodeReadable.pipe(loggingTransform).pipe(sseParser, { end: true });
3685
3815
  const webStream = stream.Readable.toWeb(
3686
3816
  transformed
3687
3817
  );
@@ -3750,7 +3880,6 @@ var RoutstrClient = class {
3750
3880
  callbacks.onTokenCreated?.(this._getPendingCashuTokenAmount());
3751
3881
  const baseHeaders = this._buildBaseHeaders(headers);
3752
3882
  const requestHeaders = this._withAuthHeader(baseHeaders, token);
3753
- this.providerManager.resetFailedProviders();
3754
3883
  const providerInfo = await this.providerRegistry.getProviderInfo(baseUrl);
3755
3884
  const providerVersion = providerInfo?.version ?? "";
3756
3885
  let modelIdForRequest = selectedModel.id;
@@ -3853,9 +3982,9 @@ var RoutstrClient = class {
3853
3982
  * Make the API request with failover support
3854
3983
  */
3855
3984
  async _makeRequest(params) {
3856
- const { path, method, body, baseUrl, token, headers } = params;
3985
+ const { path: path2, method, body, baseUrl, token, headers } = params;
3857
3986
  try {
3858
- const url = `${baseUrl.replace(/\/$/, "")}${path}`;
3987
+ const url = `${baseUrl.replace(/\/$/, "")}${path2}`;
3859
3988
  if (this.mode === "xcashu") this._log("DEBUG", "HEADERS,", headers);
3860
3989
  const response = await fetch(url, {
3861
3990
  method,
@@ -3905,11 +4034,12 @@ var RoutstrClient = class {
3905
4034
  */
3906
4035
  async _handleErrorResponse(params, token, status, requestId, xCashuRefundToken, responseBody, retryCount = 0) {
3907
4036
  const MAX_RETRIES_PER_PROVIDER = 2;
3908
- const { path, method, body, selectedModel, baseUrl, mintUrl } = params;
4037
+ const { path: path2, method, body, selectedModel, baseUrl, mintUrl } = params;
3909
4038
  let tryNextProvider = false;
4039
+ const errorMessage = responseBody;
3910
4040
  this._log(
3911
4041
  "DEBUG",
3912
- `[RoutstrClient] _handleErrorResponse: status=${status}, baseUrl=${baseUrl}, mode=${this.mode}, token preview=${token}, requestId=${requestId}`
4042
+ `[RoutstrClient] _handleErrorResponse: status=${status}, baseUrl=${baseUrl}, mode=${this.mode}, token preview=${token}, requestId=${requestId}, errorMessage=${errorMessage}`
3913
4043
  );
3914
4044
  this._log(
3915
4045
  "DEBUG",
@@ -4206,7 +4336,7 @@ var RoutstrClient = class {
4206
4336
  });
4207
4337
  return this._makeRequest({
4208
4338
  ...params,
4209
- path,
4339
+ path: path2,
4210
4340
  method,
4211
4341
  body,
4212
4342
  baseUrl: nextProvider,