@blockrun/llm 3.24.7 → 3.24.8

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/index.cjs CHANGED
@@ -5089,7 +5089,7 @@ function getCostSummary() {
5089
5089
  }
5090
5090
 
5091
5091
  // src/version.ts
5092
- var SDK_VERSION = "3.24.7";
5092
+ var SDK_VERSION = "3.24.8";
5093
5093
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
5094
5094
 
5095
5095
  // src/client.ts
@@ -10745,7 +10745,7 @@ var ChannelLayoutError = class extends Error {
10745
10745
  };
10746
10746
  async function readChannelAccount(rpcUrl, channelId, rpcHeaders, options = {}) {
10747
10747
  await checkChannelLayout();
10748
- const config = { encoding: "base64", commitment: "finalized" };
10748
+ const config = { encoding: "base64", commitment: options.commitment ?? "finalized" };
10749
10749
  if (options.minContextSlot !== void 0) config.minContextSlot = options.minContextSlot;
10750
10750
  const response = await fetch(rpcUrl, {
10751
10751
  method: "POST",
@@ -10809,7 +10809,10 @@ function checkChannelLayout() {
10809
10809
  return layoutChecked;
10810
10810
  }
10811
10811
  var LANDING_MARGIN_BLOCKS = 300;
10812
- var SECONDS_PER_SLOT = 0.4;
10812
+ function savedReclaimAnchor(record) {
10813
+ const saved = record.reclaimAnchorHeight;
10814
+ return typeof saved === "number" && Number.isSafeInteger(saved) && saved > 0 ? saved : void 0;
10815
+ }
10813
10816
  function maxOf(a, b) {
10814
10817
  if (a === void 0) return b;
10815
10818
  if (b === void 0) return a;
@@ -12338,7 +12341,11 @@ var SolanaBatchPayer = class {
12338
12341
  * pays exact (`channel_unreadable`), record kept. If
12339
12342
  * the finalized channel is closing or closed, or is not this wallet's for
12340
12343
  * the record's operator and mint, no top-up is sized from the record: it
12341
- * is re-read at once (`channel_unusable`), see {@link createPayload}.
12344
+ * is re-read at once (`channel_unusable`), see {@link createPayload}. So is
12345
+ * a channel with no account at finalized or at confirmed commitment (closed
12346
+ * and reclaimed); resync drops its record only once finality is past its
12347
+ * own anchor. One that shows only at confirmed is not finalized yet: the
12348
+ * lifetime cap applies.
12342
12349
  */
12343
12350
  async prepareTopUp(wallet, paymentRequired) {
12344
12351
  wallet.topUp = void 0;
@@ -12350,8 +12357,12 @@ var SolanaBatchPayer = class {
12350
12357
  const deposit = parseAtomic(record.deposit);
12351
12358
  if (parseAtomic(record.chargedCumulativeAmount) + parseAtomic(accept.amount) <= deposit) return;
12352
12359
  let channel;
12360
+ let unfinalized = false;
12353
12361
  try {
12354
12362
  channel = await readChannelAccount(this.init.rpcUrl, record.channelId, this.init.rpcHeaders);
12363
+ if (channel === void 0) {
12364
+ unfinalized = await readChannelAccount(this.init.rpcUrl, record.channelId, this.init.rpcHeaders, { commitment: "confirmed" }) !== void 0;
12365
+ }
12355
12366
  } catch (err) {
12356
12367
  if (err instanceof ChannelLayoutError) {
12357
12368
  throw new ResyncError("channel_unreadable", `channel ${record.channelId}: ${err.message}; no top-up is sized from it`);
@@ -12364,25 +12375,31 @@ var SolanaBatchPayer = class {
12364
12375
  `could not read channel ${record.channelId} before topping it up: ${err instanceof Error ? err.message : String(err)}`
12365
12376
  );
12366
12377
  }
12378
+ if (channel === void 0 && unfinalized) return;
12367
12379
  if (channel === void 0) {
12368
- const openSlot = Number(record.channelConfig.openSlot);
12369
- const delaySlots = Math.ceil((record.channelConfig.withdrawDelay ?? 86400) / SECONDS_PER_SLOT);
12370
- let finalizedSlot;
12371
- try {
12372
- const epoch = await rpcRequest(this.init.rpcUrl, "getEpochInfo", [{ commitment: "finalized" }], this.init.rpcHeaders);
12373
- finalizedSlot = rpcInteger(epoch.absoluteSlot, "getEpochInfo absoluteSlot");
12374
- } catch {
12375
- return;
12380
+ let anchorHeight = savedReclaimAnchor(record);
12381
+ if (anchorHeight === void 0) {
12382
+ try {
12383
+ anchorHeight = rpcInteger(
12384
+ await rpcRequest(this.init.rpcUrl, "getBlockHeight", [{ commitment: "confirmed" }], this.init.rpcHeaders),
12385
+ "getBlockHeight"
12386
+ );
12387
+ } catch {
12388
+ }
12389
+ if (anchorHeight !== void 0) {
12390
+ try {
12391
+ await wallet.book.set(key, { ...record, reclaimAnchorHeight: anchorHeight });
12392
+ } catch {
12393
+ }
12394
+ }
12376
12395
  }
12377
- if (!Number.isSafeInteger(openSlot) || openSlot <= 0 || finalizedSlot <= openSlot + delaySlots) return;
12378
12396
  addResyncTarget(wallet, {
12379
12397
  key,
12380
12398
  channelId: record.channelId,
12381
12399
  channelConfig: record.channelConfig,
12382
12400
  cumulative: parseAtomic(record.chargedCumulativeAmount),
12383
12401
  knownDeposit: deposit,
12384
- // No deposit is in doubt: nothing can still land in a reclaimed account.
12385
- anchorHeight: 0,
12402
+ ...anchorHeight !== void 0 ? { anchorHeight } : {},
12386
12403
  reason: "channel_unusable"
12387
12404
  });
12388
12405
  throw new ChannelResyncRequiredError(record.channelId);
package/dist/index.d.cts CHANGED
@@ -3509,7 +3509,11 @@ declare class SolanaBatchPayer {
3509
3509
  * pays exact (`channel_unreadable`), record kept. If
3510
3510
  * the finalized channel is closing or closed, or is not this wallet's for
3511
3511
  * the record's operator and mint, no top-up is sized from the record: it
3512
- * is re-read at once (`channel_unusable`), see {@link createPayload}.
3512
+ * is re-read at once (`channel_unusable`), see {@link createPayload}. So is
3513
+ * a channel with no account at finalized or at confirmed commitment (closed
3514
+ * and reclaimed); resync drops its record only once finality is past its
3515
+ * own anchor. One that shows only at confirmed is not finalized yet: the
3516
+ * lifetime cap applies.
3513
3517
  */
3514
3518
  private prepareTopUp;
3515
3519
  /**
package/dist/index.d.ts CHANGED
@@ -3509,7 +3509,11 @@ declare class SolanaBatchPayer {
3509
3509
  * pays exact (`channel_unreadable`), record kept. If
3510
3510
  * the finalized channel is closing or closed, or is not this wallet's for
3511
3511
  * the record's operator and mint, no top-up is sized from the record: it
3512
- * is re-read at once (`channel_unusable`), see {@link createPayload}.
3512
+ * is re-read at once (`channel_unusable`), see {@link createPayload}. So is
3513
+ * a channel with no account at finalized or at confirmed commitment (closed
3514
+ * and reclaimed); resync drops its record only once finality is past its
3515
+ * own anchor. One that shows only at confirmed is not finalized yet: the
3516
+ * lifetime cap applies.
3513
3517
  */
3514
3518
  private prepareTopUp;
3515
3519
  /**
package/dist/index.js CHANGED
@@ -4958,7 +4958,7 @@ function getCostSummary() {
4958
4958
  }
4959
4959
 
4960
4960
  // src/version.ts
4961
- var SDK_VERSION = "3.24.7";
4961
+ var SDK_VERSION = "3.24.8";
4962
4962
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
4963
4963
 
4964
4964
  // src/client.ts
@@ -10614,7 +10614,7 @@ var ChannelLayoutError = class extends Error {
10614
10614
  };
10615
10615
  async function readChannelAccount(rpcUrl, channelId, rpcHeaders, options = {}) {
10616
10616
  await checkChannelLayout();
10617
- const config = { encoding: "base64", commitment: "finalized" };
10617
+ const config = { encoding: "base64", commitment: options.commitment ?? "finalized" };
10618
10618
  if (options.minContextSlot !== void 0) config.minContextSlot = options.minContextSlot;
10619
10619
  const response = await fetch(rpcUrl, {
10620
10620
  method: "POST",
@@ -10678,7 +10678,10 @@ function checkChannelLayout() {
10678
10678
  return layoutChecked;
10679
10679
  }
10680
10680
  var LANDING_MARGIN_BLOCKS = 300;
10681
- var SECONDS_PER_SLOT = 0.4;
10681
+ function savedReclaimAnchor(record) {
10682
+ const saved = record.reclaimAnchorHeight;
10683
+ return typeof saved === "number" && Number.isSafeInteger(saved) && saved > 0 ? saved : void 0;
10684
+ }
10682
10685
  function maxOf(a, b) {
10683
10686
  if (a === void 0) return b;
10684
10687
  if (b === void 0) return a;
@@ -12207,7 +12210,11 @@ var SolanaBatchPayer = class {
12207
12210
  * pays exact (`channel_unreadable`), record kept. If
12208
12211
  * the finalized channel is closing or closed, or is not this wallet's for
12209
12212
  * the record's operator and mint, no top-up is sized from the record: it
12210
- * is re-read at once (`channel_unusable`), see {@link createPayload}.
12213
+ * is re-read at once (`channel_unusable`), see {@link createPayload}. So is
12214
+ * a channel with no account at finalized or at confirmed commitment (closed
12215
+ * and reclaimed); resync drops its record only once finality is past its
12216
+ * own anchor. One that shows only at confirmed is not finalized yet: the
12217
+ * lifetime cap applies.
12211
12218
  */
12212
12219
  async prepareTopUp(wallet, paymentRequired) {
12213
12220
  wallet.topUp = void 0;
@@ -12219,8 +12226,12 @@ var SolanaBatchPayer = class {
12219
12226
  const deposit = parseAtomic(record.deposit);
12220
12227
  if (parseAtomic(record.chargedCumulativeAmount) + parseAtomic(accept.amount) <= deposit) return;
12221
12228
  let channel;
12229
+ let unfinalized = false;
12222
12230
  try {
12223
12231
  channel = await readChannelAccount(this.init.rpcUrl, record.channelId, this.init.rpcHeaders);
12232
+ if (channel === void 0) {
12233
+ unfinalized = await readChannelAccount(this.init.rpcUrl, record.channelId, this.init.rpcHeaders, { commitment: "confirmed" }) !== void 0;
12234
+ }
12224
12235
  } catch (err) {
12225
12236
  if (err instanceof ChannelLayoutError) {
12226
12237
  throw new ResyncError("channel_unreadable", `channel ${record.channelId}: ${err.message}; no top-up is sized from it`);
@@ -12233,25 +12244,31 @@ var SolanaBatchPayer = class {
12233
12244
  `could not read channel ${record.channelId} before topping it up: ${err instanceof Error ? err.message : String(err)}`
12234
12245
  );
12235
12246
  }
12247
+ if (channel === void 0 && unfinalized) return;
12236
12248
  if (channel === void 0) {
12237
- const openSlot = Number(record.channelConfig.openSlot);
12238
- const delaySlots = Math.ceil((record.channelConfig.withdrawDelay ?? 86400) / SECONDS_PER_SLOT);
12239
- let finalizedSlot;
12240
- try {
12241
- const epoch = await rpcRequest(this.init.rpcUrl, "getEpochInfo", [{ commitment: "finalized" }], this.init.rpcHeaders);
12242
- finalizedSlot = rpcInteger(epoch.absoluteSlot, "getEpochInfo absoluteSlot");
12243
- } catch {
12244
- return;
12249
+ let anchorHeight = savedReclaimAnchor(record);
12250
+ if (anchorHeight === void 0) {
12251
+ try {
12252
+ anchorHeight = rpcInteger(
12253
+ await rpcRequest(this.init.rpcUrl, "getBlockHeight", [{ commitment: "confirmed" }], this.init.rpcHeaders),
12254
+ "getBlockHeight"
12255
+ );
12256
+ } catch {
12257
+ }
12258
+ if (anchorHeight !== void 0) {
12259
+ try {
12260
+ await wallet.book.set(key, { ...record, reclaimAnchorHeight: anchorHeight });
12261
+ } catch {
12262
+ }
12263
+ }
12245
12264
  }
12246
- if (!Number.isSafeInteger(openSlot) || openSlot <= 0 || finalizedSlot <= openSlot + delaySlots) return;
12247
12265
  addResyncTarget(wallet, {
12248
12266
  key,
12249
12267
  channelId: record.channelId,
12250
12268
  channelConfig: record.channelConfig,
12251
12269
  cumulative: parseAtomic(record.chargedCumulativeAmount),
12252
12270
  knownDeposit: deposit,
12253
- // No deposit is in doubt: nothing can still land in a reclaimed account.
12254
- anchorHeight: 0,
12271
+ ...anchorHeight !== void 0 ? { anchorHeight } : {},
12255
12272
  reason: "channel_unusable"
12256
12273
  });
12257
12274
  throw new ChannelResyncRequiredError(record.channelId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "3.24.7",
3
+ "version": "3.24.8",
4
4
  "type": "module",
5
5
  "description": "TypeScript SDK for BlockRun - every frontier model behind one OpenAI-compatible client. Pay with a BlockRun API key or per-call in USDC. Smart routing picks the cheapest capable model. No rate limits.",
6
6
  "main": "dist/index.cjs",