@blockrun/llm 3.3.0 → 3.5.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/README.md CHANGED
@@ -165,15 +165,59 @@ const tweet = await client.chat('xai/grok-3-mini', 'What is trending on X?', { s
165
165
  **Supported endpoint:** `https://sol.blockrun.ai/api`
166
166
  **Payment:** Solana USDC (SPL, mainnet)
167
167
 
168
- ## How It Works
168
+ ## How Payment Works
169
169
 
170
- 1. You send a request to BlockRun's API
171
- 2. The API returns a 402 Payment Required with the price
172
- 3. The SDK automatically signs a USDC payment on Base
173
- 4. The request is retried with the payment proof
174
- 5. You receive the AI response
170
+ No API keys, no subscription. You hold USDC in your own wallet, and **every request pays for itself** with an on-chain micropayment. Two phases:
175
171
 
176
- **Your private key never leaves your machine** - it's only used for local signing.
172
+ ### Phase 1 — Fund your wallet once
173
+
174
+ You only do this when your balance runs low. Three ways to get USDC into your wallet:
175
+
176
+ - **(a) Buy with a card (Base USDC).** Call the new `onramp()` method to mint a one-time Coinbase Onramp link, then open the returned `pay.coinbase.com` URL — pay by card/bank in 60+ fiat currencies and the USDC lands in your wallet. The call itself is **free**. Onramp is **Base-only** (buying USDC with a card always lands Base USDC), and the funding address must equal your signing wallet:
177
+
178
+ ```typescript
179
+ const { url } = await client.onramp(client.getWalletAddress());
180
+ console.log(`Fund your wallet: ${url}`); // single-use, expires ~5 min — mint at click time
181
+ ```
182
+
183
+ - **(b) Transfer existing USDC.** Send USDC you already hold to your wallet address (`client.getWalletAddress()`). On Base, send Base USDC; on Solana (`SolanaLLMClient`), send Solana SPL USDC.
184
+
185
+ - **(c) Skip funding entirely.** Use the free NVIDIA models (e.g. `nvidia/deepseek-v4-flash`) — every call is **$0**, no balance required.
186
+
187
+ $5 of USDC covers thousands of paid requests. Check your balance any time:
188
+
189
+ ```typescript
190
+ const balance = await client.getBalance(); // USDC on Base
191
+ console.log(`Balance: $${balance.toFixed(2)} USDC`);
192
+ ```
193
+
194
+ ### Phase 2 — Every request pays itself (automatic x402)
195
+
196
+ You just call e.g. `client.chat(...)` — the payment is invisible:
197
+
198
+ 1. You send a request to BlockRun's API.
199
+ 2. The gateway returns **402 Payment Required** with the price.
200
+ 3. The SDK signs a USDC payment **locally** (EIP-712) — on **Base** for `LLMClient`, on **Solana** for `SolanaLLMClient` — using your wallet key.
201
+ 4. The request is retried automatically with the payment proof.
202
+ 5. The gateway settles on-chain and returns the AI response.
203
+
204
+ One call, no separate pay step. Free NVIDIA models settle at **$0** (no payment signed).
205
+
206
+ ### Track spend and verify settlements
207
+
208
+ ```typescript
209
+ import { getCostSummary } from '@blockrun/llm';
210
+
211
+ const spent = client.getSpending(); // this session
212
+ console.log(`Spent $${spent.totalUsd.toFixed(4)} across ${spent.calls} calls`);
213
+
214
+ const summary = getCostSummary(); // across sessions (~/.blockrun/data/costs.jsonl)
215
+ console.log(`Lifetime: $${summary.totalUsd.toFixed(2)} over ${summary.calls} calls`);
216
+ ```
217
+
218
+ Every paid request is a real on-chain USDC transfer — look up your wallet address on [Basescan](https://basescan.org) (or a Solana explorer) to verify each settlement independently.
219
+
220
+ **Non-custodial by design: your private key never leaves your machine** — it is only used for local signing, and no funds are ever held by BlockRun.
177
221
 
178
222
  ## Smart Routing (ClawRouter)
179
223
 
@@ -298,6 +342,7 @@ Released 2026-04-23 — first fully retrained base since GPT-4.5. 1M context, 12
298
342
  ### Anthropic Claude
299
343
  | Model | Input Price | Output Price | Context | Notes |
300
344
  |-------|-------------|--------------|---------|-------|
345
+ | `anthropic/claude-fable-5` | $10.00/M | $50.00/M | **1M** | Mythos-class flagship above Opus — always-on thinking, 128K output, fallback `claude-opus-4.8`. Alias: `claude-fable-5` |
301
346
  | `anthropic/claude-opus-4.8` | $5.00/M | $25.00/M | **1M** | Flagship — agentic coding + adaptive thinking, 128K output |
302
347
  | `anthropic/claude-opus-4.7` | $5.00/M | $25.00/M | **1M** | Agentic coding + adaptive thinking, 128K output |
303
348
  | `anthropic/claude-opus-4.6` | $5.00/M | $25.00/M | 200K | Hidden but still callable — kept as in-family hot-swap fallback |
@@ -1320,7 +1365,7 @@ const gptResponse = await client.messages.create({
1320
1365
  });
1321
1366
  ```
1322
1367
 
1323
- The `AnthropicClient` wraps the official `@anthropic-ai/sdk` with a custom fetch that handles x402 payment automatically. Your private key never leaves your machine.
1368
+ The `AnthropicClient` wraps the official `@anthropic-ai/sdk` with a custom fetch that handles x402 payment automatically. Your private key never leaves your machine. The Mythos-class `claude-fable-5` alias is available here too (1M context, always-on thinking).
1324
1369
 
1325
1370
  ## Links
1326
1371
 
package/dist/index.cjs CHANGED
@@ -544,7 +544,17 @@ function mapRawToImageModel(m) {
544
544
  }
545
545
  var DEFAULT_API_URL = "https://blockrun.ai/api";
546
546
  var DEFAULT_MAX_TOKENS = 1024;
547
- var DEFAULT_TIMEOUT = 6e4;
547
+ function resolveDefaultTimeout() {
548
+ const envVal = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_CHAT_TIMEOUT : void 0;
549
+ if (envVal !== void 0) {
550
+ const seconds = Number(envVal);
551
+ if (Number.isFinite(seconds) && seconds > 0) {
552
+ return seconds * 1e3;
553
+ }
554
+ }
555
+ return 6e5;
556
+ }
557
+ var DEFAULT_TIMEOUT = resolveDefaultTimeout();
548
558
  var SDK_VERSION = "1.5.0";
549
559
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
550
560
  var LLMClient = class _LLMClient {
@@ -1581,6 +1591,40 @@ var LLMClient = class _LLMClient {
1581
1591
  const data = await this.requestWithPaymentRaw("/v1/exa/find-similar", body);
1582
1592
  return data.data;
1583
1593
  }
1594
+ /**
1595
+ * Mint a one-time Coinbase Onramp link to fund this wallet with USDC on Base.
1596
+ *
1597
+ * FREE — the x402 signature only authenticates the wallet (no payment is
1598
+ * charged). Because the funding address must equal the signing wallet, this
1599
+ * mints a `pay.coinbase.com` link prefilled for `address` so a card/bank can
1600
+ * top it up (60+ fiat currencies → Base USDC). Base / USDC only.
1601
+ *
1602
+ * The returned URL is single-use and expires in ~5 minutes — mint it at click
1603
+ * time and never cache it. The funding `address` must match the signing wallet.
1604
+ *
1605
+ * @param address - Destination Base wallet address (0x + 40 hex chars). Must
1606
+ * equal the signing wallet that funds it.
1607
+ * @returns `{ url }` — a one-time https://pay.coinbase.com/... link.
1608
+ *
1609
+ * @example
1610
+ * const { url } = await client.onramp(client.getWalletAddress());
1611
+ * console.log(`Fund your wallet: ${url}`);
1612
+ */
1613
+ async onramp(address) {
1614
+ if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {
1615
+ throw new Error("address must be a 0x-prefixed 40-hex-character Base address");
1616
+ }
1617
+ const data = await this.requestWithPaymentRaw("/v1/onramp/token", {
1618
+ address,
1619
+ network: "base",
1620
+ asset: "USDC"
1621
+ });
1622
+ const url = typeof data.url === "string" ? data.url : "";
1623
+ if (!url.startsWith("https://pay.coinbase.com/")) {
1624
+ throw new APIError("gateway returned no onramp url", 502, { message: "gateway returned no onramp url" });
1625
+ }
1626
+ return { url };
1627
+ }
1584
1628
  /**
1585
1629
  * Get USDC balance on Base mainnet.
1586
1630
  *
@@ -5770,7 +5814,7 @@ var OpenAI = class {
5770
5814
  constructor(options = {}) {
5771
5815
  const privateKey = options.walletKey || options.privateKey;
5772
5816
  const apiUrl = options.baseURL || "https://blockrun.ai/api";
5773
- const timeout = options.timeout || 6e4;
5817
+ const timeout = options.timeout ?? DEFAULT_TIMEOUT;
5774
5818
  this.client = new LLMClient({
5775
5819
  privateKey,
5776
5820
  apiUrl,
@@ -5804,7 +5848,7 @@ var AnthropicClient = class {
5804
5848
  const apiUrl = options.apiUrl ?? "https://blockrun.ai/api";
5805
5849
  validateApiUrl(apiUrl);
5806
5850
  this._apiUrl = apiUrl.replace(/\/$/, "");
5807
- this._timeout = options.timeout ?? 6e4;
5851
+ this._timeout = options.timeout ?? DEFAULT_TIMEOUT;
5808
5852
  }
5809
5853
  async _getClient() {
5810
5854
  if (this._client) return this._client;
package/dist/index.d.cts CHANGED
@@ -245,7 +245,7 @@ interface LLMClientOptions {
245
245
  privateKey?: `0x${string}` | string;
246
246
  /** API endpoint URL (default: https://blockrun.ai/api) */
247
247
  apiUrl?: string;
248
- /** Request timeout in milliseconds (default: 60000) */
248
+ /** Request timeout in milliseconds (default: 600000 / 600s; override via BLOCKRUN_CHAT_TIMEOUT env, in seconds) */
249
249
  timeout?: number;
250
250
  }
251
251
  /**
@@ -727,6 +727,10 @@ interface ExaFindSimilarOptions {
727
727
  /** Exclude pages from the same domain as the reference URL */
728
728
  excludeSourceDomain?: boolean;
729
729
  }
730
+ interface OnrampResult {
731
+ /** One-time https://pay.coinbase.com/... URL prefilled for this wallet. */
732
+ url: string;
733
+ }
730
734
  type PriceCategory = "crypto" | "fx" | "commodity" | "usstock" | "stocks";
731
735
  type StockMarket = "us" | "hk" | "jp" | "kr" | "gb" | "de" | "fr" | "nl" | "ie" | "lu" | "cn" | "ca";
732
736
  type BarResolution = "1" | "5" | "15" | "60" | "240" | "D" | "W" | "M";
@@ -806,7 +810,7 @@ interface PhoneClientOptions {
806
810
  privateKey?: `0x${string}` | string;
807
811
  /** API endpoint URL (default: https://blockrun.ai/api) */
808
812
  apiUrl?: string;
809
- /** Request timeout in milliseconds (default: 60000) */
813
+ /** Request timeout in milliseconds (default: 600000 / 600s; override via BLOCKRUN_CHAT_TIMEOUT env, in seconds) */
810
814
  timeout?: number;
811
815
  }
812
816
  /**
@@ -875,7 +879,7 @@ interface PortraitClientOptions {
875
879
  privateKey?: `0x${string}` | string;
876
880
  /** API endpoint URL (default: https://blockrun.ai/api) */
877
881
  apiUrl?: string;
878
- /** Request timeout in milliseconds (default: 60000) */
882
+ /** Request timeout in milliseconds (default: 600000 / 600s; override via BLOCKRUN_CHAT_TIMEOUT env, in seconds) */
879
883
  timeout?: number;
880
884
  }
881
885
  interface PortraitEnrollOptions {
@@ -1220,6 +1224,26 @@ declare class LLMClient {
1220
1224
  * @param options - Optional filters (numResults, excludeSourceDomain)
1221
1225
  */
1222
1226
  exaFindSimilar(url: string, options?: ExaFindSimilarOptions): Promise<ExaSearchResponse>;
1227
+ /**
1228
+ * Mint a one-time Coinbase Onramp link to fund this wallet with USDC on Base.
1229
+ *
1230
+ * FREE — the x402 signature only authenticates the wallet (no payment is
1231
+ * charged). Because the funding address must equal the signing wallet, this
1232
+ * mints a `pay.coinbase.com` link prefilled for `address` so a card/bank can
1233
+ * top it up (60+ fiat currencies → Base USDC). Base / USDC only.
1234
+ *
1235
+ * The returned URL is single-use and expires in ~5 minutes — mint it at click
1236
+ * time and never cache it. The funding `address` must match the signing wallet.
1237
+ *
1238
+ * @param address - Destination Base wallet address (0x + 40 hex chars). Must
1239
+ * equal the signing wallet that funds it.
1240
+ * @returns `{ url }` — a one-time https://pay.coinbase.com/... link.
1241
+ *
1242
+ * @example
1243
+ * const { url } = await client.onramp(client.getWalletAddress());
1244
+ * console.log(`Fund your wallet: ${url}`);
1245
+ */
1246
+ onramp(address: string): Promise<OnrampResult>;
1223
1247
  /**
1224
1248
  * Get USDC balance on Base mainnet.
1225
1249
  *
package/dist/index.d.ts CHANGED
@@ -245,7 +245,7 @@ interface LLMClientOptions {
245
245
  privateKey?: `0x${string}` | string;
246
246
  /** API endpoint URL (default: https://blockrun.ai/api) */
247
247
  apiUrl?: string;
248
- /** Request timeout in milliseconds (default: 60000) */
248
+ /** Request timeout in milliseconds (default: 600000 / 600s; override via BLOCKRUN_CHAT_TIMEOUT env, in seconds) */
249
249
  timeout?: number;
250
250
  }
251
251
  /**
@@ -727,6 +727,10 @@ interface ExaFindSimilarOptions {
727
727
  /** Exclude pages from the same domain as the reference URL */
728
728
  excludeSourceDomain?: boolean;
729
729
  }
730
+ interface OnrampResult {
731
+ /** One-time https://pay.coinbase.com/... URL prefilled for this wallet. */
732
+ url: string;
733
+ }
730
734
  type PriceCategory = "crypto" | "fx" | "commodity" | "usstock" | "stocks";
731
735
  type StockMarket = "us" | "hk" | "jp" | "kr" | "gb" | "de" | "fr" | "nl" | "ie" | "lu" | "cn" | "ca";
732
736
  type BarResolution = "1" | "5" | "15" | "60" | "240" | "D" | "W" | "M";
@@ -806,7 +810,7 @@ interface PhoneClientOptions {
806
810
  privateKey?: `0x${string}` | string;
807
811
  /** API endpoint URL (default: https://blockrun.ai/api) */
808
812
  apiUrl?: string;
809
- /** Request timeout in milliseconds (default: 60000) */
813
+ /** Request timeout in milliseconds (default: 600000 / 600s; override via BLOCKRUN_CHAT_TIMEOUT env, in seconds) */
810
814
  timeout?: number;
811
815
  }
812
816
  /**
@@ -875,7 +879,7 @@ interface PortraitClientOptions {
875
879
  privateKey?: `0x${string}` | string;
876
880
  /** API endpoint URL (default: https://blockrun.ai/api) */
877
881
  apiUrl?: string;
878
- /** Request timeout in milliseconds (default: 60000) */
882
+ /** Request timeout in milliseconds (default: 600000 / 600s; override via BLOCKRUN_CHAT_TIMEOUT env, in seconds) */
879
883
  timeout?: number;
880
884
  }
881
885
  interface PortraitEnrollOptions {
@@ -1220,6 +1224,26 @@ declare class LLMClient {
1220
1224
  * @param options - Optional filters (numResults, excludeSourceDomain)
1221
1225
  */
1222
1226
  exaFindSimilar(url: string, options?: ExaFindSimilarOptions): Promise<ExaSearchResponse>;
1227
+ /**
1228
+ * Mint a one-time Coinbase Onramp link to fund this wallet with USDC on Base.
1229
+ *
1230
+ * FREE — the x402 signature only authenticates the wallet (no payment is
1231
+ * charged). Because the funding address must equal the signing wallet, this
1232
+ * mints a `pay.coinbase.com` link prefilled for `address` so a card/bank can
1233
+ * top it up (60+ fiat currencies → Base USDC). Base / USDC only.
1234
+ *
1235
+ * The returned URL is single-use and expires in ~5 minutes — mint it at click
1236
+ * time and never cache it. The funding `address` must match the signing wallet.
1237
+ *
1238
+ * @param address - Destination Base wallet address (0x + 40 hex chars). Must
1239
+ * equal the signing wallet that funds it.
1240
+ * @returns `{ url }` — a one-time https://pay.coinbase.com/... link.
1241
+ *
1242
+ * @example
1243
+ * const { url } = await client.onramp(client.getWalletAddress());
1244
+ * console.log(`Fund your wallet: ${url}`);
1245
+ */
1246
+ onramp(address: string): Promise<OnrampResult>;
1223
1247
  /**
1224
1248
  * Get USDC balance on Base mainnet.
1225
1249
  *
package/dist/index.js CHANGED
@@ -437,7 +437,17 @@ function mapRawToImageModel(m) {
437
437
  }
438
438
  var DEFAULT_API_URL = "https://blockrun.ai/api";
439
439
  var DEFAULT_MAX_TOKENS = 1024;
440
- var DEFAULT_TIMEOUT = 6e4;
440
+ function resolveDefaultTimeout() {
441
+ const envVal = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_CHAT_TIMEOUT : void 0;
442
+ if (envVal !== void 0) {
443
+ const seconds = Number(envVal);
444
+ if (Number.isFinite(seconds) && seconds > 0) {
445
+ return seconds * 1e3;
446
+ }
447
+ }
448
+ return 6e5;
449
+ }
450
+ var DEFAULT_TIMEOUT = resolveDefaultTimeout();
441
451
  var SDK_VERSION = "1.5.0";
442
452
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
443
453
  var LLMClient = class _LLMClient {
@@ -1474,6 +1484,40 @@ var LLMClient = class _LLMClient {
1474
1484
  const data = await this.requestWithPaymentRaw("/v1/exa/find-similar", body);
1475
1485
  return data.data;
1476
1486
  }
1487
+ /**
1488
+ * Mint a one-time Coinbase Onramp link to fund this wallet with USDC on Base.
1489
+ *
1490
+ * FREE — the x402 signature only authenticates the wallet (no payment is
1491
+ * charged). Because the funding address must equal the signing wallet, this
1492
+ * mints a `pay.coinbase.com` link prefilled for `address` so a card/bank can
1493
+ * top it up (60+ fiat currencies → Base USDC). Base / USDC only.
1494
+ *
1495
+ * The returned URL is single-use and expires in ~5 minutes — mint it at click
1496
+ * time and never cache it. The funding `address` must match the signing wallet.
1497
+ *
1498
+ * @param address - Destination Base wallet address (0x + 40 hex chars). Must
1499
+ * equal the signing wallet that funds it.
1500
+ * @returns `{ url }` — a one-time https://pay.coinbase.com/... link.
1501
+ *
1502
+ * @example
1503
+ * const { url } = await client.onramp(client.getWalletAddress());
1504
+ * console.log(`Fund your wallet: ${url}`);
1505
+ */
1506
+ async onramp(address) {
1507
+ if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {
1508
+ throw new Error("address must be a 0x-prefixed 40-hex-character Base address");
1509
+ }
1510
+ const data = await this.requestWithPaymentRaw("/v1/onramp/token", {
1511
+ address,
1512
+ network: "base",
1513
+ asset: "USDC"
1514
+ });
1515
+ const url = typeof data.url === "string" ? data.url : "";
1516
+ if (!url.startsWith("https://pay.coinbase.com/")) {
1517
+ throw new APIError("gateway returned no onramp url", 502, { message: "gateway returned no onramp url" });
1518
+ }
1519
+ return { url };
1520
+ }
1477
1521
  /**
1478
1522
  * Get USDC balance on Base mainnet.
1479
1523
  *
@@ -5663,7 +5707,7 @@ var OpenAI = class {
5663
5707
  constructor(options = {}) {
5664
5708
  const privateKey = options.walletKey || options.privateKey;
5665
5709
  const apiUrl = options.baseURL || "https://blockrun.ai/api";
5666
- const timeout = options.timeout || 6e4;
5710
+ const timeout = options.timeout ?? DEFAULT_TIMEOUT;
5667
5711
  this.client = new LLMClient({
5668
5712
  privateKey,
5669
5713
  apiUrl,
@@ -5697,7 +5741,7 @@ var AnthropicClient = class {
5697
5741
  const apiUrl = options.apiUrl ?? "https://blockrun.ai/api";
5698
5742
  validateApiUrl(apiUrl);
5699
5743
  this._apiUrl = apiUrl.replace(/\/$/, "");
5700
- this._timeout = options.timeout ?? 6e4;
5744
+ this._timeout = options.timeout ?? DEFAULT_TIMEOUT;
5701
5745
  }
5702
5746
  async _getClient() {
5703
5747
  if (this._client) return this._client;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "type": "module",
5
5
  "description": "BlockRun SDK - Pay-per-request AI (LLM, Image, Video, Music, Voice) via x402 on Base and Solana",
6
6
  "main": "dist/index.cjs",