@blockrun/llm 3.22.0 → 3.23.0

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.d.ts CHANGED
@@ -230,6 +230,13 @@ interface Settlement {
230
230
  network?: string;
231
231
  /** Present and false only when the gateway reported a failed settlement. */
232
232
  success?: false;
233
+ /**
234
+ * `"free-fallback"` when the gateway served a paid request from a free
235
+ * fallback model and skipped settlement (`X-Settlement-Skipped`): nothing
236
+ * moved on chain, so `costUsd` is 0 and nothing was added to `getSpending()`.
237
+ * `quotedUsd` still states what was signed.
238
+ */
239
+ skipped?: "free-fallback";
233
240
  }
234
241
  interface FunctionCall {
235
242
  name: string;
@@ -1479,6 +1486,13 @@ declare class LLMClient {
1479
1486
  private signFrom402;
1480
1487
  /** Send the signed payment and read the answer. The payment may settle from here on. */
1481
1488
  private sendPaid;
1489
+ /**
1490
+ * Book a served, paid chat call and attach its cost. A response the gateway
1491
+ * served from a free fallback with settlement skipped
1492
+ * (`X-Settlement-Skipped: free-fallback`) moved nothing on chain, so it is
1493
+ * not added to `getSpending()` or the cost log, and reports `costUsd: 0`.
1494
+ */
1495
+ private bookPaid;
1482
1496
  /**
1483
1497
  * Sign a payment header and return the PAYMENT-SIGNATURE value.
1484
1498
  * Extracted to share logic between streaming and non-streaming flows.
@@ -1641,7 +1655,7 @@ declare class LLMClient {
1641
1655
  /**
1642
1656
  * Query Predexon prediction market data (GET endpoints).
1643
1657
  *
1644
- * Access real-time data from Polymarket, Kalshi, dFlow, and Binance Futures.
1658
+ * Access real-time data from Polymarket, Kalshi, Limitless, Opinion, Predict.Fun, Binance Futures, UMA and sports markets.
1645
1659
  * Powered by Predexon. Billed per request.
1646
1660
  *
1647
1661
  * @param path - Endpoint path, e.g. "polymarket/events", "kalshi/markets/12345"
@@ -1839,7 +1853,8 @@ declare class ImageClient {
1839
1853
  * combined with multiple source images.
1840
1854
  *
1841
1855
  * Edit-capable models: `openai/gpt-image-1`, `openai/gpt-image-2`,
1842
- * `google/nano-banana`, `google/nano-banana-pro`.
1856
+ * `openai/gpt-image-2.5-sunburst`, `google/nano-banana`, `google/nano-banana-2`,
1857
+ * `google/nano-banana-pro`. `mask` is OpenAI-only.
1843
1858
  *
1844
1859
  * @param prompt - Text description of the desired edit
1845
1860
  * @param image - A base64 `data:image/...` URI, or an array of 2–4 such URIs to fuse
@@ -3129,6 +3144,427 @@ declare class BatchCloseDeferredError extends BlockrunError {
3129
3144
  detail: string;
3130
3145
  });
3131
3146
  }
3147
+ /**
3148
+ * The outcome of one batch attempt.
3149
+ *
3150
+ * - `paid`: served, and paid with batch.
3151
+ * - `fallback`: pay `exact`. One after a 429 wait carries the fresh 402 it
3152
+ * fetched, which the `exact` payment must be signed against.
3153
+ * - `served`: the fresh, unpaid challenge sent after a wait was answered with
3154
+ * a 2xx. That response is the call's result; nothing was paid, and nothing
3155
+ * must be.
3156
+ * - `failed`: that fresh challenge got neither a 402 nor a 2xx (or no answer,
3157
+ * or a 402 that cannot be read). Raise `error`, which carries the `"unpaid"`
3158
+ * retry disposition: the 429 waited out proved nothing was charged, so
3159
+ * nothing was paid for the call. Never pay `exact` against the stale
3160
+ * challenge instead.
3161
+ */
3162
+ type BatchAttempt = {
3163
+ kind: "paid";
3164
+ response: Response;
3165
+ chargedUsd: number;
3166
+ } | {
3167
+ kind: "fallback";
3168
+ reason: string;
3169
+ paymentRequired?: PaymentRequired;
3170
+ } | {
3171
+ kind: "served";
3172
+ response: Response;
3173
+ } | {
3174
+ kind: "failed";
3175
+ error: unknown;
3176
+ };
3177
+ /**
3178
+ * The answer to a fresh, unpaid challenge request (see
3179
+ * {@link SolanaBatchPayer.pay}): a 402 to pay, or a 2xx that served the
3180
+ * request without a payment. Anything else is thrown.
3181
+ */
3182
+ type Rechallenge = {
3183
+ kind: "challenge";
3184
+ paymentRequired: PaymentRequired;
3185
+ } | {
3186
+ kind: "served";
3187
+ response: Response;
3188
+ };
3189
+ interface SolanaBatchPayerInit {
3190
+ options: SolanaBatchOptions;
3191
+ secretKey: () => Promise<Uint8Array>;
3192
+ address: () => Promise<string>;
3193
+ rpcUrl: string;
3194
+ /** Headers the exact path sends to `rpcUrl` (`rpcHeaders`, `SOLANA_RPC_HEADERS`, `SOLANA_RPC_API_KEY`). */
3195
+ rpcHeaders?: Record<string, string>;
3196
+ /**
3197
+ * Called once with the batch scheme's `x402Client`, after the scheme and its
3198
+ * policy are registered and before anything is signed. An embedder that
3199
+ * enforces its own spend rules registers its payment-creation hooks here, so
3200
+ * they see every batch payment this payer signs (each one's
3201
+ * `selectedRequirements.amount` is the per-call ceiling, not the channel
3202
+ * deposit) exactly as they see the embedder's own `exact` payments. A
3203
+ * before-hook that throws refuses the payment: nothing is signed or sent,
3204
+ * and `pay()` reports a fallback.
3205
+ */
3206
+ configureClient?: (client: X402ClientLike) => void;
3207
+ }
3208
+ /**
3209
+ * The slice of `@x402/core`'s x402Client handed to
3210
+ * {@link SolanaBatchPayerInit.configureClient}: its payment-creation hooks.
3211
+ * Structural, so this package's types never require the optional
3212
+ * `@x402/core` peer to be installed.
3213
+ */
3214
+ interface X402ClientLike {
3215
+ onBeforePaymentCreation(hook: (context: X402HookContext) => Promise<unknown> | unknown): unknown;
3216
+ onAfterPaymentCreation(hook: (context: X402HookContext) => Promise<unknown> | unknown): unknown;
3217
+ onPaymentCreationFailure(hook: (context: X402HookContext) => Promise<unknown> | unknown): unknown;
3218
+ }
3219
+ /** What a payment-creation hook receives: at least the requirement being paid. */
3220
+ interface X402HookContext {
3221
+ selectedRequirements: PaymentRequirement & {
3222
+ scheme: string;
3223
+ network: string;
3224
+ amount?: string;
3225
+ };
3226
+ [key: string]: unknown;
3227
+ }
3228
+ /**
3229
+ * One wallet's batch-settlement payer. Owned by a SolanaLLMClient.
3230
+ *
3231
+ * At most one batch request is in flight per wallet: the server-signed scheme
3232
+ * allows a single pending authorization per channel. Concurrent calls do not
3233
+ * queue behind it, they pay with `exact`, so batch never makes a parallel
3234
+ * workload slower than it is today. The exception is a 429 cooldown: then
3235
+ * every call for the wallet waits it out (within its own `rateLimit` budget)
3236
+ * rather than send the gateway another channel open it would refuse.
3237
+ */
3238
+ declare class SolanaBatchPayer {
3239
+ private readonly init;
3240
+ private state?;
3241
+ private readonly maxAttempts;
3242
+ private readonly maxWaitMs;
3243
+ private readonly inDoubtMaxWaitMs;
3244
+ private readonly counters;
3245
+ constructor(init: SolanaBatchPayerInit);
3246
+ /** A copy of this client's batch counters. */
3247
+ stats(): SolanaBatchStats;
3248
+ private storeFile;
3249
+ /**
3250
+ * This wallet's shared batch state, or why this client cannot use batch:
3251
+ * another client in this process holds the wallet with a different trust
3252
+ * configuration, or another live process owns its channel file.
3253
+ */
3254
+ private wallet;
3255
+ private build;
3256
+ /** Run a scheme call so its RPC requests carry this client's `rpcHeaders`. */
3257
+ private withRpcHeaders;
3258
+ /**
3259
+ * Drop everything this wallet knows about one channel, on disk and in
3260
+ * memory, leaving its other channels' records alone. The scheme is rebuilt
3261
+ * on the next call, without the closed channel in its memory.
3262
+ */
3263
+ private forget;
3264
+ /**
3265
+ * Stop trusting the record of the channel a payload paid into: the next
3266
+ * payment re-reads that channel from the chain first. The scheme has
3267
+ * already restored (or, for an open, dropped) its record; the book still
3268
+ * knows the channel and the cumulative it last confirmed.
3269
+ */
3270
+ private distrust;
3271
+ /**
3272
+ * The channel's total deposit if a deposit payload landed: the confirmed
3273
+ * deposit plus this one (for an open, nothing plus this one). Undefined for
3274
+ * a payment without a deposit, or a channel the SDK has no record of.
3275
+ */
3276
+ private depositExpectation;
3277
+ /**
3278
+ * Re-read every distrusted channel from the chain, at `finalized`
3279
+ * commitment, and rewrite its record: the on-chain deposit, and the highest
3280
+ * of the cumulative the SDK can vouch for, the cumulative the stored record
3281
+ * already confirmed, and the on-chain settled amount. A closing or closed
3282
+ * channel is dropped. The scheme is rebuilt to load the repaired record.
3283
+ *
3284
+ * The stored cumulative is never moved backwards. A deposit's intent can
3285
+ * outlive the receipt that reconciled it (the process died, or the journal
3286
+ * could not be cleared, after the scheme saved the new state), so its
3287
+ * cumulative may predate vouchers the scheme has since confirmed; and
3288
+ * vouchers are redeemed on-chain asynchronously, so `settled` can lag too.
3289
+ * Rewriting the record with either would leave every later voucher
3290
+ * unreconcilable.
3291
+ *
3292
+ * A deposit in doubt is settled by the chain alone:
3293
+ * - landed: the finalized channel holds at least the deposit it would
3294
+ * bring (and at least what the record already claimed);
3295
+ * - never landed: the finalized chain is {@link LANDING_MARGIN_BLOCKS}
3296
+ * past the target's anchor height, and a read at least that recent still
3297
+ * does not show it. An open's record is then dropped; a top-up's channel
3298
+ * is rewritten with the deposit it really has.
3299
+ * Until one of those holds, it is pending. This settles only the deposit:
3300
+ * whether the gateway charged the payment that carried it is never read
3301
+ * from the chain.
3302
+ *
3303
+ * @throws ResyncError when the chain cannot be read, or a deposit may still
3304
+ * land: the caller pays exact and the re-read is tried again next call.
3305
+ * Nothing opens or tops up a channel while any re-read is pending.
3306
+ */
3307
+ private resync;
3308
+ /**
3309
+ * A distrusted channel's account at `finalized` commitment, checked to be
3310
+ * this wallet's channel for the record's operator and mint.
3311
+ *
3312
+ * @throws ResyncError (`channel_unreadable`) for any other payment channel.
3313
+ */
3314
+ private readOwnChannel;
3315
+ /**
3316
+ * Make one event observable three ways: a stderr line (every time, never
3317
+ * deduplicated), this client's counters, and the caller's `onEvent`.
3318
+ */
3319
+ private report;
3320
+ /** Report a fallback and tell the caller to pay exact. */
3321
+ private fallback;
3322
+ /**
3323
+ * Pay one 402 with batch-settlement, or say why the caller should use exact.
3324
+ *
3325
+ * `send` replays the original request with the payment headers. Every send
3326
+ * goes through {@link sendOnce}, the one place an answer is classified as
3327
+ * charged, not charged, or in doubt:
3328
+ *
3329
+ * - charged: the 2xx is returned (`paid`);
3330
+ * - not charged (the gateway's explicit answer to a first send): a 429
3331
+ * whose receipt proves nothing was broadcast is backed off
3332
+ * (`Retry-After`, else 1s, 2s, 4s with jitter) and paid again with a new
3333
+ * payment built from a fresh 402 (`rechallenge`: the original's
3334
+ * `recentBlockhash` / `recentSlot` can be stale by then), within
3335
+ * `rateLimit.maxAttempts` / `maxWaitMs`, then with exact; any other is
3336
+ * paid with exact (`fallback`). A fresh challenge served with a 2xx is
3337
+ * the call's result (`served`, nothing paid); one that fails otherwise
3338
+ * is the call's error (`failed`, `"unpaid"`), never an exact payment
3339
+ * against the stale challenge;
3340
+ * - in doubt: ends only with a definitive success receipt from a replay
3341
+ * of the identical payment ({@link resolveInDoubt}: the one replay a
3342
+ * receipt-less 429 is allowed, or the replays of a payment carrying a
3343
+ * payment identifier while the gateway says one can succeed, within
3344
+ * `inDoubt.maxWaitMs`), or a thrown {@link BatchPaymentUnresolvedError}.
3345
+ * No new authorization, no new deposit, no exact payment and no fallback
3346
+ * model is ever paid for a call in doubt.
3347
+ *
3348
+ * The wallet stays in cooldown after a 429, so its other calls wait
3349
+ * instead of sending opens of their own. After a deposit the facilitator
3350
+ * refused before broadcasting it (a 402 with a failed `batch_*` admission
3351
+ * receipt), its calls do not wait: they pay exact at once
3352
+ * (`admission_refused`) until the refusal cooldown ends.
3353
+ *
3354
+ * @param closesAtStart - {@link closeFence}, taken before the call's first
3355
+ * (unpaid) request. If a close completed since, the call pays exact
3356
+ * (`closed_during_call`): it started before the close, so it must not
3357
+ * open a channel the caller believes is closed.
3358
+ */
3359
+ pay(paymentRequired: PaymentRequired, send: (headers: Record<string, string>) => Promise<Response>, rechallenge: () => Promise<Rechallenge>, closesAtStart?: number): Promise<BatchAttempt>;
3360
+ /**
3361
+ * The close fence for a call about to send its first request: how many
3362
+ * closes this wallet has completed so far, to hand to {@link pay}.
3363
+ * `close()` refuses while a call is inside `pay()`, but a call still
3364
+ * waiting for its 402 is not there yet; the fence covers that window.
3365
+ * Undefined when the wallet cannot be named (no fence then; `pay()`
3366
+ * reports why batch is unavailable).
3367
+ */
3368
+ closeFence(): Promise<number | undefined>;
3369
+ /** {@link pay}, for a wallet this client may use. */
3370
+ private payWith;
3371
+ /**
3372
+ * Put the wallet in a 429 cooldown for `delay` ms (`Retry-After`, or the
3373
+ * default backoff), and return how long this call would have to wait.
3374
+ *
3375
+ * The shared cooldown is capped at `rateLimit.maxWaitMs`, so one header,
3376
+ * however long, never keeps the wallet's calls off batch for longer than
3377
+ * the retry budget. This call still weighs the full delay: one it cannot
3378
+ * wait out within its budget is not waited at all, and the caller pays
3379
+ * exact (or raises a payment in doubt) at once.
3380
+ */
3381
+ private coolDown;
3382
+ /**
3383
+ * Try to end a payment in doubt with the gateway's own word.
3384
+ *
3385
+ * The one source of evidence this SDK accepts is a definitive success
3386
+ * receipt on a byte-identical replay of the payment. Any other answer to a
3387
+ * replay (a 402 or `duplicate_settlement`, which mean the original reached
3388
+ * the gateway; a 409; another 429; a 5xx; a timeout) leaves it in doubt.
3389
+ *
3390
+ * - A payment carrying a payment identifier is replayed for as long as
3391
+ * the gateway says a later replay can succeed ({@link replayInDoubt}).
3392
+ * - Any other payment gets a replay only after a 429 without a receipt:
3393
+ * one, after its backoff (the owner's bounded safety attempt), within
3394
+ * `rateLimit`. Every other in-doubt outcome is never replayed.
3395
+ *
3396
+ * Chain state is not evidence here: it can settle a deposit (see
3397
+ * `resync`), never whether the gateway charged.
3398
+ *
3399
+ * @returns the charged replay, or the doubt to raise.
3400
+ */
3401
+ private resolveInDoubt;
3402
+ /**
3403
+ * Replay a payment in doubt that carries a payment identifier until the
3404
+ * gateway's answer settles it.
3405
+ *
3406
+ * A gateway that declares `payment-identifier` stores each paid response
3407
+ * under its identifier and answers a byte-identical replay of a completed
3408
+ * request with it, the original receipt included; while the original is
3409
+ * still running, it answers 409 with a `Retry-After`. So the identical
3410
+ * payment (the same `PAYMENT-SIGNATURE` header and the same body) is
3411
+ * replayed for as long as the last answer says a later one can succeed
3412
+ * ({@link replayMayResolve}), after {@link inDoubtWait} each time, as long
3413
+ * as the wait fits in `inDoubt.maxWaitMs`, counted from the first doubt:
3414
+ * every wait (as long as it really took) and every replay's round trip. A
3415
+ * replay already sent is not cut short. These replays do not count
3416
+ * against `rateLimit`; a 429 among them still puts the wallet in cooldown.
3417
+ *
3418
+ * Every answer that does not settle it is held back from the scheme
3419
+ * ({@link InDoubt.held}) and handed over only once no replay follows, so
3420
+ * the scheme rolls the payment back once, or takes the receipt that answer
3421
+ * carries. That is the last answer, unless an earlier one carried a
3422
+ * success receipt and the later ones do not: a success receipt is the
3423
+ * gateway's word that it charged, and handing the scheme a receipt-less
3424
+ * refusal of a replay instead would roll a real charge back and desync the
3425
+ * channel's cumulative.
3426
+ *
3427
+ * @returns the charged replay, or the doubt to raise.
3428
+ */
3429
+ private replayInDoubt;
3430
+ /**
3431
+ * Raise a payment in doubt: release the scheme's hold on it (the channel
3432
+ * goes back to its confirmed state), put a deposit's channel in doubt so
3433
+ * it is re-read from the chain before anything pays into it again, report
3434
+ * the `unresolved` event, and throw {@link BatchPaymentUnresolvedError}.
3435
+ */
3436
+ private raiseUnresolved;
3437
+ /** Build a new batch payment for a 402: the payload, its headers and its kind. */
3438
+ private buildPayment;
3439
+ /**
3440
+ * Write a deposit's intent to the wallet's journal before it is sent
3441
+ * (with the file store: the file and its directory fsynced).
3442
+ *
3443
+ * @throws when it cannot be recorded; the deposit must then not be sent.
3444
+ */
3445
+ private journalDeposit;
3446
+ /**
3447
+ * Remove a deposit's intent once it is reconciled. A failure is logged,
3448
+ * not thrown: the intent then outlives its deposit, and after a restart
3449
+ * the chain re-read settles it again.
3450
+ */
3451
+ private forgetIntent;
3452
+ /**
3453
+ * THE choke point: send a batch payment once and classify the answer.
3454
+ *
3455
+ * The only caller of `send` for a batch payment, and the only place its
3456
+ * outcome is decided (see {@link SendOutcome}). Every exception once the
3457
+ * send has started is `in_doubt`, whatever its type or `cause.code`: the
3458
+ * request may have reached the gateway. "Not charged" is only ever minted
3459
+ * here, and only for a first send.
3460
+ *
3461
+ * @param retry - count this send in `retries` (it follows this call's own 429).
3462
+ * @param replay - this is a replay of a payment in doubt: only a 2xx with
3463
+ * a success receipt counts, everything else stays in doubt.
3464
+ */
3465
+ private sendOnce;
3466
+ /** {@link sendOnce}'s classifier, for an HTTP answer. */
3467
+ private classify;
3468
+ /**
3469
+ * {@link classify}, past a receipt-less 429. With `hold`, the answer is not
3470
+ * handed to the scheme: its receipt is only read.
3471
+ */
3472
+ private classifyAnswer;
3473
+ /**
3474
+ * Build the payment payload, re-reading any distrusted channel from the
3475
+ * chain first. A stored record the book refuses to hand over (a deposit a
3476
+ * dead process never heard back about), or one a top-up's read found
3477
+ * unusable ({@link prepareTopUp}), is re-read and the payload rebuilt
3478
+ * once.
3479
+ */
3480
+ private createPayload;
3481
+ /**
3482
+ * When this payment will top up the wallet's channel, read how much of its
3483
+ * deposit is already settled on-chain (at `finalized` commitment, so never
3484
+ * more than will stay settled), so `maxDeposit` caps the escrow still at
3485
+ * stake rather than every deposit the channel ever took.
3486
+ *
3487
+ * Only a top-up costs this read (a channel's balance decides it, from the
3488
+ * stored record). If the read fails, nothing settled is assumed, which is
3489
+ * the stricter, lifetime cap. If the chain shows a larger deposit than the
3490
+ * record, the record is behind (a deposit it never heard about landed):
3491
+ * sizing a top-up from it could exceed `maxDeposit`, so this call pays
3492
+ * exact and the channel is re-read before the next payment. If
3493
+ * `@x402/svm`'s channel layout is not the one this SDK decodes, or the
3494
+ * account at the channel's address cannot be read as a channel, the call
3495
+ * pays exact (`channel_unreadable`), record kept. If
3496
+ * the finalized channel is closing or closed, or is not this wallet's for
3497
+ * the record's operator and mint, no top-up is sized from the record: it
3498
+ * is re-read at once (`channel_unusable`), see {@link createPayload}.
3499
+ */
3500
+ private prepareTopUp;
3501
+ /**
3502
+ * Hand the gateway's answer to the scheme, which verifies the operator's
3503
+ * voucher and advances (or rolls back) the channel's local state.
3504
+ *
3505
+ * A malformed receipt must not lose a response the caller has been served,
3506
+ * so a scheme error is logged rather than thrown.
3507
+ */
3508
+ private settle;
3509
+ /**
3510
+ * Close the channel the gateway's current challenge names and return its
3511
+ * unused escrow to the wallet.
3512
+ *
3513
+ * The scheme keeps a closed channel in its records, and would go on paying
3514
+ * into it, so a successful close forgets that channel. The next batch call
3515
+ * finds no open channel on-chain and opens a new one. Any other channel
3516
+ * (say, one opened with an operator key that is being rotated out) keeps
3517
+ * its record, so it can still be closed without an on-chain scan. A
3518
+ * client-signed channel an earlier SDK version opened is closed too, once
3519
+ * the trusted server-signed one has no record (see {@link refundTarget}).
3520
+ *
3521
+ * @param url - any batch-enabled route on the gateway the channel was opened with.
3522
+ * @throws BatchCloseDeferredError while a batch call for the wallet is in
3523
+ * flight, or while any of its deposits is in doubt (until a finalized
3524
+ * chain read settles it). Nothing is refunded or forgotten then.
3525
+ */
3526
+ close(url: string): Promise<unknown>;
3527
+ /**
3528
+ * Re-read every distrusted channel before a close. A deposit still in
3529
+ * doubt defers the close: refunding (or forgetting) a channel a deposit
3530
+ * may yet land on could strand that deposit, and after a restart nothing
3531
+ * would remember it. A record re-read that only failed for another reason
3532
+ * (an RPC error on a channel with no deposit in doubt) does not.
3533
+ */
3534
+ private settleDoubtsForClose;
3535
+ /**
3536
+ * The channel a close targets: the one the gateway's refund challenge
3537
+ * names, by the scheme's storage key for its trusted server-signed accept
3538
+ * (network, asset, receiver, fee payer, withdraw delay, receiver
3539
+ * authorizer, operator). Probed with an unpaid GET, as `@x402/svm`'s own
3540
+ * refund probes; that accept is then handed to the refund, so upstream
3541
+ * does not probe again and pick another accept.
3542
+ *
3543
+ * A legacy client-signed channel (opened by an earlier SDK version, which
3544
+ * could pay a client-signed accept; this one never opens one) must stay
3545
+ * refundable. When the trusted server-signed accept has no stored record,
3546
+ * or there is none, a client-signed accept in the challenge whose storage
3547
+ * key names a stored client-signed record is the target instead, and the
3548
+ * refund runs through `@x402/svm`'s client-signed path (a refund voucher
3549
+ * signed by the payer at its confirmed cumulative). The signer modes match:
3550
+ * a server-signed record is never refunded under a client-signed accept.
3551
+ */
3552
+ private refundTarget;
3553
+ /**
3554
+ * Get the stored channel `key` ready to refund.
3555
+ *
3556
+ * `@x402/svm` refunds a server-signed channel only from the scheme's memory,
3557
+ * or after an on-chain scan that many RPCs refuse; it never reads the
3558
+ * stored record. So the target channel is loaded into a freshly built
3559
+ * scheme, and only that one: upstream's refund falls back to the first
3560
+ * channel in memory for the same receiver and asset, whatever its operator.
3561
+ * A record in doubt (a deposit this process never confirmed, or a pending
3562
+ * deposit left by a process that died) is re-read from the chain before it
3563
+ * is loaded. If a re-read cannot settle a record, the refund is still
3564
+ * attempted and may find the channel by its scan.
3565
+ */
3566
+ private prepareClose;
3567
+ }
3132
3568
 
3133
3569
  interface SolanaLLMClientOptions extends ApiKeyOptions {
3134
3570
  /** bs58-encoded Solana secret key (64 bytes). Optional if SOLANA_WALLET_KEY env var is set. */
@@ -3789,10 +4225,10 @@ declare class ChatCompletions {
3789
4225
  /**
3790
4226
  * Create a chat completion (OpenAI-compatible).
3791
4227
  */
3792
- create(params: OpenAIChatCompletionParams): Promise<OpenAIChatCompletionResponse>;
3793
4228
  create(params: OpenAIChatCompletionParams & {
3794
4229
  stream: true;
3795
4230
  }): Promise<AsyncIterable<OpenAIChatCompletionChunk>>;
4231
+ create(params: OpenAIChatCompletionParams): Promise<OpenAIChatCompletionResponse>;
3796
4232
  private createStream;
3797
4233
  private transformResponse;
3798
4234
  }
@@ -3971,4 +4407,4 @@ declare function readSettlement(response: Response, quotedUsd: number, scheme: S
3971
4407
  settlement: Settlement;
3972
4408
  };
3973
4409
 
3974
- export { APIError, API_KEY_URL, ARC_CHAIN_ID, AnthropicClient, type AnyTool, type ApiKeyOptions, type AudioModel, type AudioTrack, BASE_CHAIN_ID, BLOCKRUN_SOL_OPERATOR, type BarResolution, BatchCloseDeferredError, type BatchPayloadKind, BatchPaymentUnresolvedError, type BatchUnresolvedReason, type BlockRunAnthropicOptions, BlockrunClient, type BlockrunClientOptions, BlockrunError, type CallInitiatedResponse, type CallModel, type CallOptions, type CallStatusResponse, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatResponseWithCost, type ChatUsage, type CostEntry, type CostEstimate, type CreatePaymentOptions, DEFAULT_BATCH_IN_DOUBT, DEFAULT_BATCH_RATE_LIMIT, EVM_NETWORKS, type EvmNetwork, type FunctionCall, type FunctionDefinition, type HistoryOptions, ImageClient, type ImageClientOptions, type ImageData, type ImageEditOptions, type ImageGenerateOptions, type ImageModel, type ImageResponse, KNOWN_PROVIDERS, LLMClient, type LLMClientOptions, type ListOptions, type MarketSession, type Model, MusicClient, type MusicClientOptions, type MusicGenerateOptions, type MusicResponse, NETWORK_ALIASES, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PORTAL_URL, PORTRAIT_ENROLLMENT_PRICE_USD, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, PortraitClient, type PortraitClientOptions, type PortraitEnrollOptions, type PortraitEnrollResponse, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, RPC_PRICE_USD, type ResponseFormat, RetiredEndpointError, type RetryDisposition, type RoutingDecision, type RoutingProfile, type RoutingTaskType, type RoutingTier, type RoutingTierConfig, type RpcBatchRequest, RpcClient, type RpcClientOptions, type RpcError, type RpcNetwork, type RpcResponse, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SUPPORTED_NETWORKS, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type Settlement, type SmartChatCompletionOptions, type SmartChatCompletionResponse, type SmartChatOptions, type SmartChatResponse, type SolanaBatchEvent, type SolanaBatchOptions, type SolanaBatchStats, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type SoundEffectOptions, type SpeechAudio, SpeechClient, type SpeechClientOptions, type SpeechGenerateOptions, type SpeechModel, type SpeechResponse, type SpeechVoice, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_ARC, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, type UrlCitation, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoiceInfo, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type WebSearchTool, type XSearchSource, type XSearchTool, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, evmNetwork, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatSolanaWalletMigrationNotice, formatWalletCreatedMessage, formatWalletMigrationNotice, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, importSolanaWallet, importWallet, listDiscoveredSolanaWallets, listDiscoveredWallets, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, readSettlement, retryDisposition, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentClient, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, toWireSearchParameters, toWireTools, validateMaxTokens, validateModel, validateTemperature, validateTopP };
4410
+ export { APIError, API_KEY_URL, ARC_CHAIN_ID, AnthropicClient, type AnyTool, type ApiKeyOptions, type AudioModel, type AudioTrack, BASE_CHAIN_ID, BLOCKRUN_SOL_OPERATOR, type BarResolution, type BatchAttempt, BatchCloseDeferredError, type BatchPayloadKind, BatchPaymentUnresolvedError, type BatchUnresolvedReason, type BlockRunAnthropicOptions, BlockrunClient, type BlockrunClientOptions, BlockrunError, type CallInitiatedResponse, type CallModel, type CallOptions, type CallStatusResponse, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatResponseWithCost, type ChatUsage, type CostEntry, type CostEstimate, type CreatePaymentOptions, DEFAULT_BATCH_IN_DOUBT, DEFAULT_BATCH_RATE_LIMIT, EVM_NETWORKS, type EvmNetwork, type FunctionCall, type FunctionDefinition, type HistoryOptions, ImageClient, type ImageClientOptions, type ImageData, type ImageEditOptions, type ImageGenerateOptions, type ImageModel, type ImageResponse, KNOWN_PROVIDERS, LLMClient, type LLMClientOptions, type ListOptions, type MarketSession, type Model, MusicClient, type MusicClientOptions, type MusicGenerateOptions, type MusicResponse, NETWORK_ALIASES, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PORTAL_URL, PORTRAIT_ENROLLMENT_PRICE_USD, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, PortraitClient, type PortraitClientOptions, type PortraitEnrollOptions, type PortraitEnrollResponse, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, RPC_PRICE_USD, type Rechallenge, type ResponseFormat, RetiredEndpointError, type RetryDisposition, type RoutingDecision, type RoutingProfile, type RoutingTaskType, type RoutingTier, type RoutingTierConfig, type RpcBatchRequest, RpcClient, type RpcClientOptions, type RpcError, type RpcNetwork, type RpcResponse, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SUPPORTED_NETWORKS, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type Settlement, type SmartChatCompletionOptions, type SmartChatCompletionResponse, type SmartChatOptions, type SmartChatResponse, type SolanaBatchEvent, type SolanaBatchOptions, SolanaBatchPayer, type SolanaBatchPayerInit, type SolanaBatchStats, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type SoundEffectOptions, type SpeechAudio, SpeechClient, type SpeechClientOptions, type SpeechGenerateOptions, type SpeechModel, type SpeechResponse, type SpeechVoice, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_ARC, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, type UrlCitation, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoiceInfo, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type WebSearchTool, type X402ClientLike, type X402HookContext, type XSearchSource, type XSearchTool, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, evmNetwork, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatSolanaWalletMigrationNotice, formatWalletCreatedMessage, formatWalletMigrationNotice, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, importSolanaWallet, importWallet, listDiscoveredSolanaWallets, listDiscoveredWallets, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, readSettlement, retryDisposition, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentClient, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, toWireSearchParameters, toWireTools, validateMaxTokens, validateModel, validateTemperature, validateTopP };
package/dist/index.js CHANGED
@@ -423,7 +423,15 @@ function readSettlement(response, quotedUsd, scheme) {
423
423
  };
424
424
  return { costUsd, settlement };
425
425
  }
426
+ function settlementSkipped(response) {
427
+ return response.headers.get("X-Settlement-Skipped") === "free-fallback";
428
+ }
426
429
  function withCost(body, response, bookedUsd, scheme) {
430
+ if (settlementSkipped(response)) {
431
+ body.costUsd = 0;
432
+ body.settlement = { ...readSettlement(response, bookedUsd, scheme).settlement, skipped: "free-fallback" };
433
+ return body;
434
+ }
427
435
  body.costUsd = bookedUsd;
428
436
  body.settlement = readSettlement(response, bookedUsd, scheme).settlement;
429
437
  return body;
@@ -4694,7 +4702,7 @@ function getCostSummary() {
4694
4702
  }
4695
4703
 
4696
4704
  // src/version.ts
4697
- var SDK_VERSION = "3.22.0";
4705
+ var SDK_VERSION = "3.23.0";
4698
4706
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
4699
4707
 
4700
4708
  // src/client.ts
@@ -5260,11 +5268,7 @@ var LLMClient = class _LLMClient {
5260
5268
  }
5261
5269
  throw new APIError(`API error after payment: ${retryResp2.status}`, retryResp2.status, sanitizeErrorResponse(errorBody));
5262
5270
  }
5263
- const costUsd2 = parseFloat(details.amount) / 1e6;
5264
- this.sessionCalls += 1;
5265
- this.sessionTotalUsd += costUsd2;
5266
- this.recordCost(url, costUsd2, { body, network: details.network });
5267
- return withCost(await this.parseChatResponse(retryResp2), retryResp2, costUsd2, "exact");
5271
+ return this.bookPaid(url, body, details, retryResp2);
5268
5272
  }
5269
5273
  }
5270
5274
  if (retryResponse.status === 402) {
@@ -5283,11 +5287,22 @@ var LLMClient = class _LLMClient {
5283
5287
  sanitizeErrorResponse(errorBody)
5284
5288
  );
5285
5289
  }
5290
+ return this.bookPaid(url, body, details, retryResponse);
5291
+ }
5292
+ /**
5293
+ * Book a served, paid chat call and attach its cost. A response the gateway
5294
+ * served from a free fallback with settlement skipped
5295
+ * (`X-Settlement-Skipped: free-fallback`) moved nothing on chain, so it is
5296
+ * not added to `getSpending()` or the cost log, and reports `costUsd: 0`.
5297
+ */
5298
+ async bookPaid(url, body, details, response) {
5286
5299
  const costUsd = parseFloat(details.amount) / 1e6;
5287
- this.sessionCalls += 1;
5288
- this.sessionTotalUsd += costUsd;
5289
- this.recordCost(url, costUsd, { body, network: details.network });
5290
- return withCost(await this.parseChatResponse(retryResponse), retryResponse, costUsd, "exact");
5300
+ if (!settlementSkipped(response)) {
5301
+ this.sessionCalls += 1;
5302
+ this.sessionTotalUsd += costUsd;
5303
+ this.recordCost(url, costUsd, { body, network: details.network });
5304
+ }
5305
+ return withCost(await this.parseChatResponse(response), response, costUsd, "exact");
5291
5306
  }
5292
5307
  /**
5293
5308
  * Sign a payment header and return the PAYMENT-SIGNATURE value.
@@ -6033,7 +6048,7 @@ var LLMClient = class _LLMClient {
6033
6048
  /**
6034
6049
  * Query Predexon prediction market data (GET endpoints).
6035
6050
  *
6036
- * Access real-time data from Polymarket, Kalshi, dFlow, and Binance Futures.
6051
+ * Access real-time data from Polymarket, Kalshi, Limitless, Opinion, Predict.Fun, Binance Futures, UMA and sports markets.
6037
6052
  * Powered by Predexon. Billed per request.
6038
6053
  *
6039
6054
  * @param path - Endpoint path, e.g. "polymarket/events", "kalshi/markets/12345"
@@ -6360,7 +6375,8 @@ var ImageClient = class {
6360
6375
  * combined with multiple source images.
6361
6376
  *
6362
6377
  * Edit-capable models: `openai/gpt-image-1`, `openai/gpt-image-2`,
6363
- * `google/nano-banana`, `google/nano-banana-pro`.
6378
+ * `openai/gpt-image-2.5-sunburst`, `google/nano-banana`, `google/nano-banana-2`,
6379
+ * `google/nano-banana-pro`. `mask` is OpenAI-only.
6364
6380
  *
6365
6381
  * @param prompt - Text description of the desired edit
6366
6382
  * @param image - A base64 `data:image/...` URI, or an array of 2–4 such URIs to fuse
@@ -10899,6 +10915,7 @@ var SolanaBatchPayer = class {
10899
10915
  capOutstandingEscrow(scheme, wallet);
10900
10916
  const client = new core.x402Client().register("solana:*", scheme).registerPolicy(scheme.paymentPolicy);
10901
10917
  client.setSpendControls({ maxAmountPerPayment: false });
10918
+ this.init.configureClient?.(client);
10902
10919
  const raw = new core.x402HTTPClient(client);
10903
10920
  const http = {
10904
10921
  getPaymentSettleResponse: (getHeader) => raw.getPaymentSettleResponse(getHeader),
@@ -13274,7 +13291,7 @@ var SolanaLLMClient = class {
13274
13291
  throw withDisposition(error, "paid-or-in-doubt");
13275
13292
  }
13276
13293
  await this.assertPaid(retryResponse);
13277
- this.recordSettlement(costUsd);
13294
+ if (!settlementSkipped(retryResponse)) this.recordSettlement(costUsd);
13278
13295
  const paid = await this.readPaidJson(retryResponse);
13279
13296
  return withCost(paid, retryResponse, costUsd, "exact");
13280
13297
  }
@@ -14014,6 +14031,7 @@ export {
14014
14031
  SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH,
14015
14032
  SUPPORTED_NETWORKS,
14016
14033
  SearchClient,
14034
+ SolanaBatchPayer,
14017
14035
  SolanaLLMClient,
14018
14036
  SpeechClient,
14019
14037
  SurfClient,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "3.22.0",
3
+ "version": "3.23.0",
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",