@routstr/sdk 0.3.8 → 0.3.9

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.
@@ -603,7 +603,7 @@ var CashuSpender = class {
603
603
  });
604
604
  continue;
605
605
  }
606
- if (balanceResult.amount >= 0) {
606
+ if (balanceResult.amount >= 0 && !balanceResult.balanceUnknown) {
607
607
  const balanceSat = balanceResult.unit === "msat" ? Math.floor(balanceResult.amount / 1e3) : balanceResult.amount;
608
608
  this.storageAdapter.updateApiKeyBalance(
609
609
  apiKeyEntry.baseUrl,
@@ -1352,17 +1352,24 @@ var BalanceManager = class _BalanceManager {
1352
1352
  this.logger.warn("getTokenBalance: FAILED", data);
1353
1353
  const isInvalidApiKey = response.status === 401 && data?.detail?.error?.code === "invalid_api_key" && data?.detail?.error?.message?.includes("proofs already spent");
1354
1354
  return {
1355
- amount: -1,
1355
+ amount: 0,
1356
1356
  reserved: data.reserved ?? 0,
1357
1357
  unit: "msat",
1358
1358
  apiKey: data.api_key,
1359
- isInvalidApiKey
1359
+ isInvalidApiKey,
1360
+ balanceUnknown: true
1360
1361
  };
1361
1362
  }
1362
1363
  } catch (error) {
1363
1364
  this.logger.error("getTokenBalance error", error);
1364
1365
  }
1365
- return { amount: -1, reserved: 0, unit: "sat", apiKey: "" };
1366
+ return {
1367
+ amount: 0,
1368
+ reserved: 0,
1369
+ unit: "sat",
1370
+ apiKey: "",
1371
+ balanceUnknown: true
1372
+ };
1366
1373
  }
1367
1374
  /**
1368
1375
  * Handle topup errors with specific error types
@@ -3834,6 +3841,8 @@ var RoutstrClient = class {
3834
3841
  baseUrl: prepared.baseUrlUsed,
3835
3842
  mintUrl: params.mintUrl,
3836
3843
  initialTokenBalance: prepared.tokenBalanceInSats,
3844
+ initialTokenBalanceUnknown: prepared.tokenBalanceUnknown,
3845
+ fallbackSatsSpent: usage?.satsCost,
3837
3846
  response: prepared.response,
3838
3847
  modelId: prepared.modelId,
3839
3848
  usage,
@@ -3898,7 +3907,7 @@ var RoutstrClient = class {
3898
3907
  );
3899
3908
  }
3900
3909
  }
3901
- const { token, tokenBalance, tokenBalanceUnit } = await this._spendToken({
3910
+ const { token, tokenBalance, tokenBalanceUnit, tokenBalanceUnknown } = await this._spendToken({
3902
3911
  mintUrl,
3903
3912
  amount: requiredSats,
3904
3913
  baseUrl
@@ -3924,9 +3933,20 @@ var RoutstrClient = class {
3924
3933
  baseHeaders,
3925
3934
  selectedModel
3926
3935
  });
3927
- const tokenBalanceInSats = tokenBalanceUnit === "msat" ? tokenBalance / 1e3 : tokenBalance;
3936
+ let tokenBalanceInSats = tokenBalanceUnit === "msat" ? tokenBalance / 1e3 : tokenBalance;
3937
+ let initialTokenBalanceUnknown = tokenBalanceUnknown;
3928
3938
  const baseUrlUsed = response.baseUrl || baseUrl;
3929
3939
  const tokenUsed = response.token || token;
3940
+ if (baseUrlUsed !== baseUrl || tokenUsed !== token) {
3941
+ if (typeof response.initialTokenBalanceInSats === "number") {
3942
+ tokenBalanceInSats = response.initialTokenBalanceInSats;
3943
+ initialTokenBalanceUnknown = Boolean(
3944
+ response.initialTokenBalanceUnknown
3945
+ );
3946
+ } else {
3947
+ initialTokenBalanceUnknown = true;
3948
+ }
3949
+ }
3930
3950
  const contentType = response.headers.get("content-type") || "";
3931
3951
  let processedResponse = response;
3932
3952
  let capturedUsage;
@@ -3959,6 +3979,7 @@ var RoutstrClient = class {
3959
3979
  tokenUsed,
3960
3980
  baseUrlUsed,
3961
3981
  tokenBalanceInSats,
3982
+ tokenBalanceUnknown: initialTokenBalanceUnknown,
3962
3983
  modelId,
3963
3984
  capturedUsage,
3964
3985
  capturedResponseId,
@@ -4008,7 +4029,8 @@ var RoutstrClient = class {
4008
4029
  let token = spendResult.token;
4009
4030
  let tokenBalance = spendResult.tokenBalance;
4010
4031
  let tokenBalanceUnit = spendResult.tokenBalanceUnit;
4011
- const tokenBalanceInSats = tokenBalanceUnit === "msat" ? tokenBalance / 1e3 : tokenBalance;
4032
+ let tokenBalanceInSats = tokenBalanceUnit === "msat" ? tokenBalance / 1e3 : tokenBalance;
4033
+ let initialTokenBalanceUnknown = spendResult.tokenBalanceUnknown;
4012
4034
  callbacks.onTokenCreated?.(this._getPendingCashuTokenAmount());
4013
4035
  const baseHeaders = this._buildBaseHeaders(headers);
4014
4036
  const requestHeaders = this._withAuthHeader(baseHeaders, token);
@@ -4051,6 +4073,18 @@ var RoutstrClient = class {
4051
4073
  }
4052
4074
  if (response.status === 200) {
4053
4075
  const baseUrlUsed = response.baseUrl || baseUrl;
4076
+ const responseToken = response.token || token;
4077
+ if (baseUrlUsed !== baseUrl || responseToken !== token) {
4078
+ token = responseToken;
4079
+ if (typeof response.initialTokenBalanceInSats === "number") {
4080
+ tokenBalanceInSats = response.initialTokenBalanceInSats;
4081
+ initialTokenBalanceUnknown = Boolean(
4082
+ response.initialTokenBalanceUnknown
4083
+ );
4084
+ } else {
4085
+ initialTokenBalanceUnknown = true;
4086
+ }
4087
+ }
4054
4088
  const streamingResult = await this.streamProcessor.process(
4055
4089
  response,
4056
4090
  {
@@ -4081,6 +4115,7 @@ var RoutstrClient = class {
4081
4115
  baseUrl: baseUrlUsed,
4082
4116
  mintUrl,
4083
4117
  initialTokenBalance: tokenBalanceInSats,
4118
+ initialTokenBalanceUnknown,
4084
4119
  fallbackSatsSpent: isApikeysEstimate ? this._getEstimatedCosts(selectedModel, streamingResult) : void 0,
4085
4120
  response,
4086
4121
  modelId: selectedModel.id,
@@ -4237,14 +4272,24 @@ var RoutstrClient = class {
4237
4272
  params.token,
4238
4273
  baseUrl
4239
4274
  );
4240
- const currentBalance = currentBalanceInfo.unit === "msat" ? currentBalanceInfo.amount / 1e3 : currentBalanceInfo.amount;
4241
- const reservedBalance = currentBalanceInfo.unit === "msat" ? (currentBalanceInfo.reserved ?? 0) / 1e3 : currentBalanceInfo.reserved ?? 0;
4242
- const shortfall = Math.max(0, params.requiredSats - currentBalance + reservedBalance);
4243
- topupAmount = shortfall > 0.21 * params.requiredSats ? shortfall : 0.21 * params.requiredSats;
4244
- this._log(
4245
- "DEBUG",
4246
- `The shortfall is: ${shortfall}. requiredSats: ${params.requiredSats}. Current Balance: ${currentBalance}. Reserved Balance: ${reservedBalance}. Available Balance: ${currentBalance - reservedBalance}`
4247
- );
4275
+ if (currentBalanceInfo.balanceUnknown) {
4276
+ this._log(
4277
+ "DEBUG",
4278
+ `[RoutstrClient] _handleErrorResponse: Current balance unknown for ${baseUrl}; using default topup amount=${topupAmount}`
4279
+ );
4280
+ } else {
4281
+ const currentBalance = currentBalanceInfo.unit === "msat" ? currentBalanceInfo.amount / 1e3 : currentBalanceInfo.amount;
4282
+ const reservedBalance = currentBalanceInfo.unit === "msat" ? (currentBalanceInfo.reserved ?? 0) / 1e3 : currentBalanceInfo.reserved ?? 0;
4283
+ const shortfall = Math.max(
4284
+ 0,
4285
+ params.requiredSats - currentBalance + reservedBalance
4286
+ );
4287
+ topupAmount = shortfall > 0.21 * params.requiredSats ? shortfall : 0.21 * params.requiredSats;
4288
+ this._log(
4289
+ "DEBUG",
4290
+ `The shortfall is: ${shortfall}. requiredSats: ${params.requiredSats}. Current Balance: ${currentBalance}. Reserved Balance: ${reservedBalance}. Available Balance: ${currentBalance - reservedBalance}`
4291
+ );
4292
+ }
4248
4293
  } catch (e) {
4249
4294
  this._log(
4250
4295
  "WARN",
@@ -4330,7 +4375,7 @@ var RoutstrClient = class {
4330
4375
  this.storageAdapter.removeApiKey(baseUrl);
4331
4376
  tryNextProvider = true;
4332
4377
  } else {
4333
- const latestTokenBalance = latestBalanceInfo.unit === "msat" ? latestBalanceInfo.amount / 1e3 : latestBalanceInfo.amount;
4378
+ const latestTokenBalance = latestBalanceInfo.balanceUnknown ? void 0 : latestBalanceInfo.unit === "msat" ? latestBalanceInfo.amount / 1e3 : latestBalanceInfo.amount;
4334
4379
  if (latestBalanceInfo.apiKey) {
4335
4380
  const storedApiKeyEntry = this.storageAdapter.getApiKey(baseUrl);
4336
4381
  if (storedApiKeyEntry?.key !== latestBalanceInfo.apiKey) {
@@ -4341,7 +4386,7 @@ var RoutstrClient = class {
4341
4386
  }
4342
4387
  retryToken = latestBalanceInfo.apiKey;
4343
4388
  }
4344
- if (latestTokenBalance >= 0) {
4389
+ if (latestTokenBalance !== void 0 && latestTokenBalance >= 0) {
4345
4390
  this.storageAdapter.updateApiKeyBalance(
4346
4391
  baseUrl,
4347
4392
  latestTokenBalance
@@ -4416,7 +4461,7 @@ var RoutstrClient = class {
4416
4461
  "DEBUG",
4417
4462
  `[RoutstrClient] _handleErrorResponse: API key refund result: success=${refundResult.success}, message=${refundResult.message}`
4418
4463
  );
4419
- if (!refundResult.success && latestBalanceInfo.amount > 0) {
4464
+ if (!refundResult.success && latestBalanceInfo.amount > 0 && !latestBalanceInfo.balanceUnknown) {
4420
4465
  throw new ProviderError(
4421
4466
  baseUrl,
4422
4467
  status,
@@ -4467,7 +4512,7 @@ var RoutstrClient = class {
4467
4512
  amount: newRequiredSats,
4468
4513
  baseUrl: nextProvider
4469
4514
  });
4470
- return this._makeRequest({
4515
+ const retryResponse = await this._makeRequest({
4471
4516
  ...params,
4472
4517
  path,
4473
4518
  method,
@@ -4479,6 +4524,9 @@ var RoutstrClient = class {
4479
4524
  headers: this._withAuthHeader(params.baseHeaders, spendResult.token),
4480
4525
  retryCount: 0
4481
4526
  });
4527
+ retryResponse.initialTokenBalanceInSats = spendResult.tokenBalanceUnit === "msat" ? spendResult.tokenBalance / 1e3 : spendResult.tokenBalance;
4528
+ retryResponse.initialTokenBalanceUnknown = spendResult.tokenBalanceUnknown;
4529
+ return retryResponse;
4482
4530
  }
4483
4531
  throw new FailoverError(
4484
4532
  baseUrl,
@@ -4494,6 +4542,7 @@ var RoutstrClient = class {
4494
4542
  baseUrl,
4495
4543
  mintUrl,
4496
4544
  initialTokenBalance,
4545
+ initialTokenBalanceUnknown,
4497
4546
  fallbackSatsSpent,
4498
4547
  response,
4499
4548
  modelId,
@@ -4530,17 +4579,19 @@ var RoutstrClient = class {
4530
4579
  latestBalanceInfo.apiKey,
4531
4580
  baseUrl
4532
4581
  );
4533
- const latestTokenBalance = latestBalanceInfo.unit === "msat" ? latestBalanceInfo.amount / 1e3 : latestBalanceInfo.amount;
4582
+ const latestTokenBalance = latestBalanceInfo.balanceUnknown ? void 0 : latestBalanceInfo.unit === "msat" ? latestBalanceInfo.amount / 1e3 : latestBalanceInfo.amount;
4534
4583
  const storedApiKeyEntry = this.storageAdapter.getApiKey(baseUrl);
4535
4584
  if (storedApiKeyEntry?.key.startsWith("cashu") && latestBalanceInfo.apiKey) {
4536
4585
  this.storageAdapter.removeApiKey(baseUrl);
4537
4586
  this.storageAdapter.setApiKey(baseUrl, latestBalanceInfo.apiKey);
4538
4587
  }
4539
- this.storageAdapter.updateApiKeyBalance(baseUrl, latestTokenBalance);
4540
- satsSpent = initialTokenBalance - latestTokenBalance;
4588
+ if (latestTokenBalance !== void 0) {
4589
+ this.storageAdapter.updateApiKeyBalance(baseUrl, latestTokenBalance);
4590
+ }
4591
+ satsSpent = latestTokenBalance !== void 0 && !initialTokenBalanceUnknown ? Math.max(0, initialTokenBalance - latestTokenBalance) : fallbackSatsSpent ?? usage?.satsCost ?? 0;
4541
4592
  } catch (e) {
4542
4593
  this._log("WARN", "Could not get updated API key balance:", e);
4543
- satsSpent = fallbackSatsSpent ?? initialTokenBalance;
4594
+ satsSpent = fallbackSatsSpent ?? usage?.satsCost ?? 0;
4544
4595
  }
4545
4596
  }
4546
4597
  await this._trackResponseUsage({
@@ -4790,6 +4841,7 @@ var RoutstrClient = class {
4790
4841
  }
4791
4842
  let tokenBalance = 0;
4792
4843
  let tokenBalanceUnit = "sat";
4844
+ let tokenBalanceUnknown = false;
4793
4845
  const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();
4794
4846
  const distributionForBaseUrl = apiKeyDistribution.find(
4795
4847
  (d) => d.baseUrl === baseUrl
@@ -4805,6 +4857,7 @@ var RoutstrClient = class {
4805
4857
  );
4806
4858
  tokenBalance = balanceInfo.amount;
4807
4859
  tokenBalanceUnit = balanceInfo.unit;
4860
+ tokenBalanceUnknown = Boolean(balanceInfo.balanceUnknown);
4808
4861
  } catch (e) {
4809
4862
  this._log("WARN", "Could not get initial API key balance:", e);
4810
4863
  }
@@ -4816,7 +4869,8 @@ var RoutstrClient = class {
4816
4869
  return {
4817
4870
  token: parentApiKey?.key ?? "",
4818
4871
  tokenBalance,
4819
- tokenBalanceUnit
4872
+ tokenBalanceUnit,
4873
+ tokenBalanceUnknown
4820
4874
  };
4821
4875
  }
4822
4876
  this._log(
@@ -4845,7 +4899,8 @@ var RoutstrClient = class {
4845
4899
  return {
4846
4900
  token: spendResult.token,
4847
4901
  tokenBalance: spendResult.balance,
4848
- tokenBalanceUnit: spendResult.unit ?? "sat"
4902
+ tokenBalanceUnit: spendResult.unit ?? "sat",
4903
+ tokenBalanceUnknown: false
4849
4904
  };
4850
4905
  }
4851
4906
  /**