@blockrun/llm 2.11.1 → 2.12.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
@@ -119,7 +119,7 @@ console.log(result.response); // '4'
119
119
  | `nvidia/gpt-oss-120b` | 128K | OpenAI open-weight 120B — 123 tok/s. Hidden from `/v1/models` for privacy but direct calls still work |
120
120
  | `nvidia/gpt-oss-20b` | 128K | OpenAI open-weight 20B — 155 tok/s. Hidden from `/v1/models` but direct calls still work |
121
121
 
122
- > Need V4-Pro-class reasoning? Use the paid `deepseek/deepseek-v4-pro` ($0.50/$1.00 with the 75% promo through 2026-05-31) — `nvidia/deepseek-v4-pro` is currently hidden because NVIDIA's NIM deployment is hung; backend MODEL_REDIRECTS forwards calls to V4 Flash.
122
+ > Need V4-Pro-class reasoning? Use the paid `deepseek/deepseek-v4-pro` ($0.435/$0.87 — the 75% launch promo became the permanent list price after 2026-05-31) — `nvidia/deepseek-v4-pro` is currently hidden because NVIDIA's NIM deployment is hung; backend MODEL_REDIRECTS forwards calls to V4 Flash.
123
123
 
124
124
  > Privacy note: `nvidia/gpt-oss-120b` and `nvidia/gpt-oss-20b` are hidden from `/v1/models` because NVIDIA's free build.nvidia.com tier reserves the right to use prompts/outputs for service improvement. Direct calls by full model ID still work — opt in only when your data isn't sensitive.
125
125
 
@@ -328,22 +328,23 @@ thinking modes. V4 Pro is the new flagship paid SKU — 1.6T MoE / 49B active,
328
328
 
329
329
  | Model | Input Price | Output Price | Context | Notes |
330
330
  |-------|-------------|--------------|---------|-------|
331
- | `deepseek/deepseek-v4-pro` | $0.50/M | $1.00/M | 1M | V4 flagship — strongest open-weight reasoner. **75% off until 2026-05-31** (list $2.00/$4.00) |
331
+ | `deepseek/deepseek-v4-pro` | $0.435/M | $0.87/M | 1M | V4 flagship — strongest open-weight reasoner. The 75% launch promo became the permanent list price after 2026-05-31 |
332
332
  | `deepseek/deepseek-chat` | $0.20/M | $0.40/M | 1M | V4 Flash non-thinking (paid endpoint with 5MB request bodies; same upstream as `nvidia/deepseek-v4-flash`) |
333
333
  | `deepseek/deepseek-reasoner` | $0.20/M | $0.40/M | 1M | V4 Flash thinking (same upstream as `deepseek-chat`, thinking enabled by default) |
334
334
 
335
335
  ### xAI Grok
336
+
337
+ Grok 4.3 and Grok Build are resold through BlockRun's OpenRouter credit pool
338
+ (same pattern as `deepseek/deepseek-v4-pro` and `minimax/minimax-m3`). The
339
+ older Grok chat SKUs (grok-3/3-mini, grok-4-fast / 4-1-fast families,
340
+ grok-code-fast-1, grok-4-0709, grok-2-vision) are now **hidden from
341
+ `/v1/models`** — direct calls by full ID still work, but SmartChat won't
342
+ auto-pick them.
343
+
336
344
  | Model | Input Price | Output Price | Context | Notes |
337
345
  |-------|-------------|--------------|---------|-------|
338
- | `xai/grok-3` | $3.00/M | $15.00/M | 131K | Flagship |
339
- | `xai/grok-3-mini` | $0.30/M | $0.50/M | 131K | Fast & affordable |
340
- | `xai/grok-4-1-fast-reasoning` | $0.20/M | $0.50/M | **2M** | Latest, chain-of-thought |
341
- | `xai/grok-4-1-fast-non-reasoning` | $0.20/M | $0.50/M | **2M** | Latest, direct response |
342
- | `xai/grok-4-fast-reasoning` | $0.20/M | $0.50/M | **2M** | Step-by-step reasoning |
343
- | `xai/grok-4-fast-non-reasoning` | $0.20/M | $0.50/M | **2M** | Quick responses |
344
- | `xai/grok-code-fast-1` | $0.20/M | $1.50/M | 256K | Code generation |
345
- | `xai/grok-4-0709` | $0.20/M | $1.50/M | 256K | Premium quality |
346
- | `xai/grok-2-vision` | $2.00/M | $10.00/M | 32K | Vision capabilities |
346
+ | `xai/grok-4.3` | $1.50/M | $4.00/M | 1M | Reasoning model, vision-capable, tuned for agentic workflows |
347
+ | `xai/grok-build-0.1` | $1.50/M | $3.00/M | 256K | Fast agentic coding model — interactive software-engineering workflows |
347
348
 
348
349
  ### Moonshot Kimi
349
350
  | Model | Input Price | Output Price |
@@ -356,7 +357,6 @@ thinking modes. V4 Pro is the new flagship paid SKU — 1.6T MoE / 49B active,
356
357
  |-------|-------------|--------------|
357
358
  | `minimax/minimax-m3` | $0.30/M | $1.20/M |
358
359
  | `minimax/minimax-m2.7` | $0.30/M | $1.20/M |
359
- | `minimax/minimax-m2.5` | $0.30/M | $1.20/M |
360
360
 
361
361
  ### NVIDIA (Free) + Moonshot
362
362
 
@@ -454,6 +454,46 @@ const r3 = await client.generate('aerial drone shot over a snowy mountain', {
454
454
  });
455
455
  ```
456
456
 
457
+ ### Text-to-Speech & Sound Effects
458
+
459
+ `SpeechClient` wraps BlockRun Voice (ElevenLabs): `POST /v1/audio/speech`
460
+ (OpenAI-compatible TTS), `POST /v1/audio/sound-effects`, and the free
461
+ `GET /v1/audio/voices`. TTS price scales with character count:
462
+ `(chars / 1000) × model rate`, minimum $0.001/request. Synthesis is
463
+ synchronous (<1s for Flash).
464
+
465
+ | Model | Price | Max Input | Notes |
466
+ |-------|-------|-----------|-------|
467
+ | `elevenlabs/flash-v2.5` | $0.05/1k chars | 40k chars | ~75ms latency, 32 languages (default) |
468
+ | `elevenlabs/turbo-v2.5` | $0.05/1k chars | 40k chars | ~250ms latency, balanced quality |
469
+ | `elevenlabs/multilingual-v2` | $0.10/1k chars | 10k chars | Long-form narration, audiobooks |
470
+ | `elevenlabs/v3` | $0.10/1k chars | 5k chars | Max expressiveness, 70+ languages |
471
+ | `elevenlabs/sound-effects` | $0.05/generation | 1k chars | Sound effects up to 22s |
472
+
473
+ ```ts
474
+ import { SpeechClient } from '@blockrun/llm';
475
+
476
+ const client = new SpeechClient();
477
+
478
+ // Text-to-speech (voice aliases: sarah, george, laura, charlie,
479
+ // river, roger, callum, harry — or any raw ElevenLabs voice_id)
480
+ const result = await client.generate('Welcome to BlockRun.', { voice: 'george' });
481
+ console.log(result.data[0].url); // audio URL (mp3 by default)
482
+
483
+ // Other formats / speed
484
+ const wav = await client.generate('Breaking news from the world of micropayments.', {
485
+ model: 'elevenlabs/v3',
486
+ responseFormat: 'wav',
487
+ speed: 1.1,
488
+ });
489
+
490
+ // Sound effects (flat $0.05/generation)
491
+ const fx = await client.soundEffect('rain on a tin roof, distant thunder');
492
+
493
+ // List voices (free, rate-limited)
494
+ const voices = await client.listVoices();
495
+ ```
496
+
457
497
  ### Virtual Portraits
458
498
 
459
499
  `PortraitClient` wraps `POST /v1/portrait/enroll` (paid, flat **$0.01** promo,
package/dist/index.cjs CHANGED
@@ -50,6 +50,7 @@ __export(index_exports, {
50
50
  SOLANA_WALLET_FILE_PATH: () => SOLANA_WALLET_FILE,
51
51
  SearchClient: () => SearchClient,
52
52
  SolanaLLMClient: () => SolanaLLMClient,
53
+ SpeechClient: () => SpeechClient,
53
54
  SurfClient: () => SurfClient,
54
55
  USDC_BASE: () => USDC_BASE,
55
56
  USDC_BASE_CONTRACT: () => USDC_BASE_CONTRACT,
@@ -2398,11 +2399,210 @@ var MusicClient = class {
2398
2399
  }
2399
2400
  };
2400
2401
 
2401
- // src/video.ts
2402
+ // src/speech.ts
2402
2403
  var import_accounts5 = require("viem/accounts");
2403
2404
  var DEFAULT_API_URL4 = "https://blockrun.ai/api";
2404
- var DEFAULT_MODEL3 = "xai/grok-imagine-video";
2405
+ var DEFAULT_MODEL3 = "elevenlabs/flash-v2.5";
2406
+ var DEFAULT_SOUNDFX_MODEL = "elevenlabs/sound-effects";
2405
2407
  var DEFAULT_TIMEOUT4 = 12e4;
2408
+ var SpeechClient = class {
2409
+ account;
2410
+ privateKey;
2411
+ apiUrl;
2412
+ timeout;
2413
+ sessionTotalUsd = 0;
2414
+ sessionCalls = 0;
2415
+ constructor(options = {}) {
2416
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
2417
+ const privateKey = options.privateKey || envKey;
2418
+ if (!privateKey) {
2419
+ throw new Error(
2420
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
2421
+ );
2422
+ }
2423
+ validatePrivateKey(privateKey);
2424
+ this.privateKey = privateKey;
2425
+ this.account = (0, import_accounts5.privateKeyToAccount)(privateKey);
2426
+ const apiUrl = options.apiUrl || DEFAULT_API_URL4;
2427
+ validateApiUrl(apiUrl);
2428
+ this.apiUrl = apiUrl.replace(/\/$/, "");
2429
+ this.timeout = options.timeout || DEFAULT_TIMEOUT4;
2430
+ }
2431
+ /**
2432
+ * Synthesize speech from text (OpenAI-compatible TTS).
2433
+ *
2434
+ * Price scales with character count: (chars / 1000) x model rate,
2435
+ * minimum $0.001/request. Synthesis is synchronous.
2436
+ *
2437
+ * @param input - Text to synthesize. Per-model character caps apply
2438
+ * (flash/turbo 40k, multilingual-v2 10k, v3 5k).
2439
+ * @param options - Optional model / voice / format / speed
2440
+ * @returns SpeechResponse with audio URL, format, and character count
2441
+ *
2442
+ * @example
2443
+ * const result = await client.generate('Welcome to BlockRun.', { voice: 'george' });
2444
+ * console.log(result.data[0].url); // audio URL (mp3 by default)
2445
+ */
2446
+ async generate(input, options) {
2447
+ const body = {
2448
+ model: options?.model || DEFAULT_MODEL3,
2449
+ input
2450
+ };
2451
+ if (options?.voice) body.voice = options.voice;
2452
+ if (options?.responseFormat) body.response_format = options.responseFormat;
2453
+ if (options?.speed !== void 0) body.speed = options.speed;
2454
+ return this.requestWithPayment("/v1/audio/speech", body);
2455
+ }
2456
+ /** OpenAI-style alias for {@link generate}. */
2457
+ speak(input, options) {
2458
+ return this.generate(input, options);
2459
+ }
2460
+ /**
2461
+ * Generate a cinematic sound effect from a text prompt.
2462
+ *
2463
+ * Flat $0.05/generation, up to 22 seconds of audio.
2464
+ *
2465
+ * @param text - Sound effect description (max 1000 chars).
2466
+ * E.g. 'rain on a tin roof', 'sci-fi door whoosh'
2467
+ * @param options - Optional duration / prompt influence / format
2468
+ * @returns SpeechResponse with audio URL and format
2469
+ *
2470
+ * @example
2471
+ * const fx = await client.soundEffect('crackling campfire at night');
2472
+ * console.log(fx.data[0].url);
2473
+ */
2474
+ async soundEffect(text, options) {
2475
+ const body = {
2476
+ model: options?.model || DEFAULT_SOUNDFX_MODEL,
2477
+ text
2478
+ };
2479
+ if (options?.durationSeconds !== void 0) body.duration_seconds = options.durationSeconds;
2480
+ if (options?.promptInfluence !== void 0) body.prompt_influence = options.promptInfluence;
2481
+ if (options?.responseFormat) body.response_format = options.responseFormat;
2482
+ return this.requestWithPayment("/v1/audio/sound-effects", body);
2483
+ }
2484
+ /**
2485
+ * List available voices for TTS (free, rate-limited 60 req/min/IP).
2486
+ *
2487
+ * Pass a voice's `alias` (if present) or `voice_id` as the `voice`
2488
+ * option to {@link generate}.
2489
+ */
2490
+ async listVoices() {
2491
+ const response = await this.fetchWithTimeout(`${this.apiUrl}/v1/audio/voices`, {
2492
+ method: "GET"
2493
+ });
2494
+ if (!response.ok) {
2495
+ let errorBody;
2496
+ try {
2497
+ errorBody = await response.json();
2498
+ } catch {
2499
+ errorBody = { error: "Request failed" };
2500
+ }
2501
+ throw new APIError(`API error: ${response.status}`, response.status, sanitizeErrorResponse(errorBody));
2502
+ }
2503
+ const payload = await response.json();
2504
+ return payload.data || [];
2505
+ }
2506
+ async requestWithPayment(endpoint, body) {
2507
+ const url = `${this.apiUrl}${endpoint}`;
2508
+ const response = await this.fetchWithTimeout(url, {
2509
+ method: "POST",
2510
+ headers: { "Content-Type": "application/json" },
2511
+ body: JSON.stringify(body)
2512
+ });
2513
+ if (response.status === 402) {
2514
+ return this.handlePaymentAndRetry(url, endpoint, body, response);
2515
+ }
2516
+ if (!response.ok) {
2517
+ let errorBody;
2518
+ try {
2519
+ errorBody = await response.json();
2520
+ } catch {
2521
+ errorBody = { error: "Request failed" };
2522
+ }
2523
+ throw new APIError(`API error: ${response.status}`, response.status, sanitizeErrorResponse(errorBody));
2524
+ }
2525
+ return response.json();
2526
+ }
2527
+ async handlePaymentAndRetry(url, endpoint, body, response) {
2528
+ let paymentHeader = response.headers.get("payment-required");
2529
+ if (!paymentHeader) {
2530
+ try {
2531
+ const respBody = await response.json();
2532
+ if (respBody.x402 || respBody.accepts) {
2533
+ paymentHeader = btoa(JSON.stringify(respBody));
2534
+ }
2535
+ } catch {
2536
+ }
2537
+ }
2538
+ if (!paymentHeader) {
2539
+ throw new PaymentError("402 response but no payment requirements found");
2540
+ }
2541
+ const paymentRequired = parsePaymentRequired(paymentHeader);
2542
+ const details = extractPaymentDetails(paymentRequired);
2543
+ const paymentPayload = await createPaymentPayload(
2544
+ this.privateKey,
2545
+ this.account.address,
2546
+ details.recipient,
2547
+ details.amount,
2548
+ details.network || "eip155:8453",
2549
+ {
2550
+ resourceUrl: details.resource?.url || `${this.apiUrl}${endpoint}`,
2551
+ resourceDescription: details.resource?.description || "BlockRun Voice",
2552
+ maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
2553
+ extra: details.extra
2554
+ }
2555
+ );
2556
+ const retryResponse = await this.fetchWithTimeout(url, {
2557
+ method: "POST",
2558
+ headers: {
2559
+ "Content-Type": "application/json",
2560
+ "PAYMENT-SIGNATURE": paymentPayload
2561
+ },
2562
+ body: JSON.stringify(body)
2563
+ });
2564
+ if (retryResponse.status === 402) {
2565
+ throw new PaymentError("Payment was rejected. Check your wallet balance.");
2566
+ }
2567
+ if (!retryResponse.ok) {
2568
+ let errorBody;
2569
+ try {
2570
+ errorBody = await retryResponse.json();
2571
+ } catch {
2572
+ errorBody = { error: "Request failed" };
2573
+ }
2574
+ throw new APIError(`API error after payment: ${retryResponse.status}`, retryResponse.status, sanitizeErrorResponse(errorBody));
2575
+ }
2576
+ const data = await retryResponse.json();
2577
+ this.sessionCalls++;
2578
+ const paidUsd = Number(details.amount) / 1e6;
2579
+ if (Number.isFinite(paidUsd)) this.sessionTotalUsd += paidUsd;
2580
+ const txHash = retryResponse.headers.get("x-payment-receipt") || retryResponse.headers.get("X-Payment-Receipt");
2581
+ if (txHash) data.txHash = txHash;
2582
+ return data;
2583
+ }
2584
+ async fetchWithTimeout(url, options) {
2585
+ const controller = new AbortController();
2586
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
2587
+ try {
2588
+ return await fetch(url, { ...options, signal: controller.signal });
2589
+ } finally {
2590
+ clearTimeout(timeoutId);
2591
+ }
2592
+ }
2593
+ getWalletAddress() {
2594
+ return this.account.address;
2595
+ }
2596
+ getSpending() {
2597
+ return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
2598
+ }
2599
+ };
2600
+
2601
+ // src/video.ts
2602
+ var import_accounts6 = require("viem/accounts");
2603
+ var DEFAULT_API_URL5 = "https://blockrun.ai/api";
2604
+ var DEFAULT_MODEL4 = "xai/grok-imagine-video";
2605
+ var DEFAULT_TIMEOUT5 = 12e4;
2406
2606
  var POLL_INTERVAL_MS2 = 5e3;
2407
2607
  var DEFAULT_GENERATE_BUDGET_MS = 3e5;
2408
2608
  var MAX_TIMEOUT_SECONDS = 600;
@@ -2423,11 +2623,11 @@ var VideoClient = class {
2423
2623
  }
2424
2624
  validatePrivateKey(privateKey);
2425
2625
  this.privateKey = privateKey;
2426
- this.account = (0, import_accounts5.privateKeyToAccount)(privateKey);
2427
- const apiUrl = options.apiUrl || DEFAULT_API_URL4;
2626
+ this.account = (0, import_accounts6.privateKeyToAccount)(privateKey);
2627
+ const apiUrl = options.apiUrl || DEFAULT_API_URL5;
2428
2628
  validateApiUrl(apiUrl);
2429
2629
  this.apiUrl = apiUrl.replace(/\/$/, "");
2430
- this.timeout = options.timeout || DEFAULT_TIMEOUT4;
2630
+ this.timeout = options.timeout || DEFAULT_TIMEOUT5;
2431
2631
  }
2432
2632
  /**
2433
2633
  * Generate a short video clip from a text prompt (or text + image).
@@ -2451,7 +2651,7 @@ var VideoClient = class {
2451
2651
  );
2452
2652
  }
2453
2653
  const body = {
2454
- model: options?.model || DEFAULT_MODEL3,
2654
+ model: options?.model || DEFAULT_MODEL4,
2455
2655
  prompt
2456
2656
  };
2457
2657
  if (options?.imageUrl) body.image_url = options.imageUrl;
@@ -2609,9 +2809,9 @@ var VideoClient = class {
2609
2809
  };
2610
2810
 
2611
2811
  // src/voice.ts
2612
- var import_accounts6 = require("viem/accounts");
2613
- var DEFAULT_API_URL5 = "https://blockrun.ai/api";
2614
- var DEFAULT_TIMEOUT5 = 6e4;
2812
+ var import_accounts7 = require("viem/accounts");
2813
+ var DEFAULT_API_URL6 = "https://blockrun.ai/api";
2814
+ var DEFAULT_TIMEOUT6 = 6e4;
2615
2815
  var CALL_PRICE_USD = 0.54;
2616
2816
  var VALID_MODELS = /* @__PURE__ */ new Set(["base", "enhanced", "turbo"]);
2617
2817
  var VoiceClient = class {
@@ -2631,11 +2831,11 @@ var VoiceClient = class {
2631
2831
  }
2632
2832
  validatePrivateKey(privateKey);
2633
2833
  this.privateKey = privateKey;
2634
- this.account = (0, import_accounts6.privateKeyToAccount)(privateKey);
2635
- const apiUrl = options.apiUrl || DEFAULT_API_URL5;
2834
+ this.account = (0, import_accounts7.privateKeyToAccount)(privateKey);
2835
+ const apiUrl = options.apiUrl || DEFAULT_API_URL6;
2636
2836
  validateApiUrl(apiUrl);
2637
2837
  this.apiUrl = apiUrl.replace(/\/$/, "");
2638
- this.timeout = options.timeout || DEFAULT_TIMEOUT5;
2838
+ this.timeout = options.timeout || DEFAULT_TIMEOUT6;
2639
2839
  }
2640
2840
  /**
2641
2841
  * Initiate an AI-powered outbound phone call.
@@ -2810,9 +3010,9 @@ var VoiceClient = class {
2810
3010
  };
2811
3011
 
2812
3012
  // src/phone.ts
2813
- var import_accounts7 = require("viem/accounts");
2814
- var DEFAULT_API_URL6 = "https://blockrun.ai/api";
2815
- var DEFAULT_TIMEOUT6 = 6e4;
3013
+ var import_accounts8 = require("viem/accounts");
3014
+ var DEFAULT_API_URL7 = "https://blockrun.ai/api";
3015
+ var DEFAULT_TIMEOUT7 = 6e4;
2816
3016
  var PHONE_PRICES = Object.freeze({
2817
3017
  lookup: 0.01,
2818
3018
  "lookup/fraud": 0.05,
@@ -2850,11 +3050,11 @@ var PhoneClient = class {
2850
3050
  }
2851
3051
  validatePrivateKey(privateKey);
2852
3052
  this.privateKey = privateKey;
2853
- this.account = (0, import_accounts7.privateKeyToAccount)(privateKey);
2854
- const apiUrl = options.apiUrl || DEFAULT_API_URL6;
3053
+ this.account = (0, import_accounts8.privateKeyToAccount)(privateKey);
3054
+ const apiUrl = options.apiUrl || DEFAULT_API_URL7;
2855
3055
  validateApiUrl(apiUrl);
2856
3056
  this.apiUrl = apiUrl.replace(/\/$/, "");
2857
- this.timeout = options.timeout || DEFAULT_TIMEOUT6;
3057
+ this.timeout = options.timeout || DEFAULT_TIMEOUT7;
2858
3058
  }
2859
3059
  /** EVM wallet address used for payments. */
2860
3060
  getWalletAddress() {
@@ -3029,9 +3229,9 @@ var PhoneClient = class {
3029
3229
  };
3030
3230
 
3031
3231
  // src/portrait.ts
3032
- var import_accounts8 = require("viem/accounts");
3033
- var DEFAULT_API_URL7 = "https://blockrun.ai/api";
3034
- var DEFAULT_TIMEOUT7 = 6e4;
3232
+ var import_accounts9 = require("viem/accounts");
3233
+ var DEFAULT_API_URL8 = "https://blockrun.ai/api";
3234
+ var DEFAULT_TIMEOUT8 = 6e4;
3035
3235
  var PORTRAIT_ENROLLMENT_PRICE_USD = 0.01;
3036
3236
  var PortraitClient = class {
3037
3237
  account;
@@ -3050,11 +3250,11 @@ var PortraitClient = class {
3050
3250
  }
3051
3251
  validatePrivateKey(privateKey);
3052
3252
  this.privateKey = privateKey;
3053
- this.account = (0, import_accounts8.privateKeyToAccount)(privateKey);
3054
- const apiUrl = options.apiUrl || DEFAULT_API_URL7;
3253
+ this.account = (0, import_accounts9.privateKeyToAccount)(privateKey);
3254
+ const apiUrl = options.apiUrl || DEFAULT_API_URL8;
3055
3255
  validateApiUrl(apiUrl);
3056
3256
  this.apiUrl = apiUrl.replace(/\/$/, "");
3057
- this.timeout = options.timeout || DEFAULT_TIMEOUT7;
3257
+ this.timeout = options.timeout || DEFAULT_TIMEOUT8;
3058
3258
  }
3059
3259
  /** EVM wallet address used for payments. */
3060
3260
  getWalletAddress() {
@@ -3183,9 +3383,9 @@ var PortraitClient = class {
3183
3383
  };
3184
3384
 
3185
3385
  // src/search.ts
3186
- var import_accounts9 = require("viem/accounts");
3187
- var DEFAULT_API_URL8 = "https://blockrun.ai/api";
3188
- var DEFAULT_TIMEOUT8 = 6e4;
3386
+ var import_accounts10 = require("viem/accounts");
3387
+ var DEFAULT_API_URL9 = "https://blockrun.ai/api";
3388
+ var DEFAULT_TIMEOUT9 = 6e4;
3189
3389
  var SearchClient = class {
3190
3390
  account;
3191
3391
  privateKey;
@@ -3201,11 +3401,11 @@ var SearchClient = class {
3201
3401
  }
3202
3402
  validatePrivateKey(privateKey);
3203
3403
  this.privateKey = privateKey;
3204
- this.account = (0, import_accounts9.privateKeyToAccount)(privateKey);
3205
- const apiUrl = options.apiUrl || DEFAULT_API_URL8;
3404
+ this.account = (0, import_accounts10.privateKeyToAccount)(privateKey);
3405
+ const apiUrl = options.apiUrl || DEFAULT_API_URL9;
3206
3406
  validateApiUrl(apiUrl);
3207
3407
  this.apiUrl = apiUrl.replace(/\/$/, "");
3208
- this.timeout = options.timeout || DEFAULT_TIMEOUT8;
3408
+ this.timeout = options.timeout || DEFAULT_TIMEOUT9;
3209
3409
  }
3210
3410
  async search(query, options) {
3211
3411
  if (!query || query.length > 1e3) {
@@ -3319,9 +3519,9 @@ var SearchClient = class {
3319
3519
  };
3320
3520
 
3321
3521
  // src/x-client.ts
3322
- var import_accounts10 = require("viem/accounts");
3323
- var DEFAULT_API_URL9 = "https://blockrun.ai/api";
3324
- var DEFAULT_TIMEOUT9 = 6e4;
3522
+ var import_accounts11 = require("viem/accounts");
3523
+ var DEFAULT_API_URL10 = "https://blockrun.ai/api";
3524
+ var DEFAULT_TIMEOUT10 = 6e4;
3325
3525
  var XClient = class _XClient {
3326
3526
  account;
3327
3527
  privateKey;
@@ -3344,11 +3544,11 @@ var XClient = class _XClient {
3344
3544
  }
3345
3545
  validatePrivateKey(privateKey);
3346
3546
  this.privateKey = privateKey;
3347
- this.account = (0, import_accounts10.privateKeyToAccount)(privateKey);
3348
- const apiUrl = options.apiUrl || DEFAULT_API_URL9;
3547
+ this.account = (0, import_accounts11.privateKeyToAccount)(privateKey);
3548
+ const apiUrl = options.apiUrl || DEFAULT_API_URL10;
3349
3549
  validateApiUrl(apiUrl);
3350
3550
  this.apiUrl = apiUrl.replace(/\/$/, "");
3351
- this.timeout = options.timeout || DEFAULT_TIMEOUT9;
3551
+ this.timeout = options.timeout || DEFAULT_TIMEOUT10;
3352
3552
  }
3353
3553
  // ───────── User endpoints ─────────
3354
3554
  userLookup(usernames) {
@@ -3526,9 +3726,9 @@ var XClient = class _XClient {
3526
3726
  };
3527
3727
 
3528
3728
  // src/price.ts
3529
- var import_accounts11 = require("viem/accounts");
3530
- var DEFAULT_API_URL10 = "https://blockrun.ai/api";
3531
- var DEFAULT_TIMEOUT10 = 3e4;
3729
+ var import_accounts12 = require("viem/accounts");
3730
+ var DEFAULT_API_URL11 = "https://blockrun.ai/api";
3731
+ var DEFAULT_TIMEOUT11 = 3e4;
3532
3732
  var PriceClient = class {
3533
3733
  account = null;
3534
3734
  privateKey = null;
@@ -3546,12 +3746,12 @@ var PriceClient = class {
3546
3746
  if (privateKey) {
3547
3747
  validatePrivateKey(privateKey);
3548
3748
  this.privateKey = privateKey;
3549
- this.account = (0, import_accounts11.privateKeyToAccount)(privateKey);
3749
+ this.account = (0, import_accounts12.privateKeyToAccount)(privateKey);
3550
3750
  }
3551
- const apiUrl = options.apiUrl || DEFAULT_API_URL10;
3751
+ const apiUrl = options.apiUrl || DEFAULT_API_URL11;
3552
3752
  validateApiUrl(apiUrl);
3553
3753
  this.apiUrl = apiUrl.replace(/\/$/, "");
3554
- this.timeout = options.timeout || DEFAULT_TIMEOUT10;
3754
+ this.timeout = options.timeout || DEFAULT_TIMEOUT11;
3555
3755
  }
3556
3756
  async price(category, symbol, options) {
3557
3757
  if (!symbol) throw new Error("symbol is required");
@@ -3730,9 +3930,9 @@ function buildUrl(base, query) {
3730
3930
  }
3731
3931
 
3732
3932
  // src/surf.ts
3733
- var import_accounts12 = require("viem/accounts");
3734
- var DEFAULT_API_URL11 = "https://blockrun.ai/api";
3735
- var DEFAULT_TIMEOUT11 = 6e4;
3933
+ var import_accounts13 = require("viem/accounts");
3934
+ var DEFAULT_API_URL12 = "https://blockrun.ai/api";
3935
+ var DEFAULT_TIMEOUT12 = 6e4;
3736
3936
  var SURF_PREFIX = "/v1/surf";
3737
3937
  var SurfClient = class {
3738
3938
  account;
@@ -3749,11 +3949,11 @@ var SurfClient = class {
3749
3949
  }
3750
3950
  validatePrivateKey(privateKey);
3751
3951
  this.privateKey = privateKey;
3752
- this.account = (0, import_accounts12.privateKeyToAccount)(privateKey);
3753
- const apiUrl = options.apiUrl || DEFAULT_API_URL11;
3952
+ this.account = (0, import_accounts13.privateKeyToAccount)(privateKey);
3953
+ const apiUrl = options.apiUrl || DEFAULT_API_URL12;
3754
3954
  validateApiUrl(apiUrl);
3755
3955
  this.apiUrl = apiUrl.replace(/\/$/, "");
3756
- this.timeout = options.timeout || DEFAULT_TIMEOUT11;
3956
+ this.timeout = options.timeout || DEFAULT_TIMEOUT12;
3757
3957
  }
3758
3958
  /**
3759
3959
  * GET a Surf endpoint. `path` is everything after `/v1/surf` (a leading
@@ -3885,9 +4085,9 @@ var SurfClient = class {
3885
4085
  };
3886
4086
 
3887
4087
  // src/blockrun.ts
3888
- var import_accounts13 = require("viem/accounts");
3889
- var DEFAULT_API_URL12 = "https://blockrun.ai/api";
3890
- var DEFAULT_TIMEOUT12 = 6e4;
4088
+ var import_accounts14 = require("viem/accounts");
4089
+ var DEFAULT_API_URL13 = "https://blockrun.ai/api";
4090
+ var DEFAULT_TIMEOUT13 = 6e4;
3891
4091
  var DEFAULT_POLL_INTERVAL_MS = 5e3;
3892
4092
  var DEFAULT_POLL_BUDGET_MS = 3e5;
3893
4093
  var MAX_SIGNED_AUTH_SECONDS = 600;
@@ -3908,11 +4108,11 @@ var BlockrunClient = class {
3908
4108
  }
3909
4109
  validatePrivateKey(privateKey);
3910
4110
  this.privateKey = privateKey;
3911
- this.account = (0, import_accounts13.privateKeyToAccount)(privateKey);
3912
- const apiUrl = options.apiUrl || DEFAULT_API_URL12;
4111
+ this.account = (0, import_accounts14.privateKeyToAccount)(privateKey);
4112
+ const apiUrl = options.apiUrl || DEFAULT_API_URL13;
3913
4113
  validateApiUrl(apiUrl);
3914
4114
  this.apiUrl = apiUrl.replace(/\/$/, "");
3915
- this.timeout = options.timeout || DEFAULT_TIMEOUT12;
4115
+ this.timeout = options.timeout || DEFAULT_TIMEOUT13;
3916
4116
  }
3917
4117
  /**
3918
4118
  * GET a BlockRun endpoint. `path` is everything after `/api` (a leading
@@ -4263,7 +4463,7 @@ function sleep(ms) {
4263
4463
  }
4264
4464
 
4265
4465
  // src/wallet.ts
4266
- var import_accounts14 = require("viem/accounts");
4466
+ var import_accounts15 = require("viem/accounts");
4267
4467
  var fs2 = __toESM(require("fs"), 1);
4268
4468
  var path2 = __toESM(require("path"), 1);
4269
4469
  var os2 = __toESM(require("os"), 1);
@@ -4272,8 +4472,8 @@ var BASE_CHAIN_ID2 = "8453";
4272
4472
  var WALLET_DIR = path2.join(os2.homedir(), ".blockrun");
4273
4473
  var WALLET_FILE = path2.join(WALLET_DIR, ".session");
4274
4474
  function createWallet() {
4275
- const privateKey = (0, import_accounts14.generatePrivateKey)();
4276
- const account = (0, import_accounts14.privateKeyToAccount)(privateKey);
4475
+ const privateKey = (0, import_accounts15.generatePrivateKey)();
4476
+ const account = (0, import_accounts15.privateKeyToAccount)(privateKey);
4277
4477
  return {
4278
4478
  address: account.address,
4279
4479
  privateKey
@@ -4329,12 +4529,12 @@ function loadWallet() {
4329
4529
  function getOrCreateWallet() {
4330
4530
  const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
4331
4531
  if (envKey) {
4332
- const account = (0, import_accounts14.privateKeyToAccount)(envKey);
4532
+ const account = (0, import_accounts15.privateKeyToAccount)(envKey);
4333
4533
  return { address: account.address, privateKey: envKey, isNew: false };
4334
4534
  }
4335
4535
  const fileKey = loadWallet();
4336
4536
  if (fileKey) {
4337
- const account = (0, import_accounts14.privateKeyToAccount)(fileKey);
4537
+ const account = (0, import_accounts15.privateKeyToAccount)(fileKey);
4338
4538
  return { address: account.address, privateKey: fileKey, isNew: false };
4339
4539
  }
4340
4540
  const { address, privateKey } = createWallet();
@@ -4344,11 +4544,11 @@ function getOrCreateWallet() {
4344
4544
  function getWalletAddress() {
4345
4545
  const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
4346
4546
  if (envKey) {
4347
- return (0, import_accounts14.privateKeyToAccount)(envKey).address;
4547
+ return (0, import_accounts15.privateKeyToAccount)(envKey).address;
4348
4548
  }
4349
4549
  const fileKey = loadWallet();
4350
4550
  if (fileKey) {
4351
- return (0, import_accounts14.privateKeyToAccount)(fileKey).address;
4551
+ return (0, import_accounts15.privateKeyToAccount)(fileKey).address;
4352
4552
  }
4353
4553
  return null;
4354
4554
  }
@@ -4528,7 +4728,7 @@ async function getOrCreateSolanaWallet() {
4528
4728
  // src/solana-client.ts
4529
4729
  var SOLANA_API_URL = "https://sol.blockrun.ai/api";
4530
4730
  var DEFAULT_MAX_TOKENS2 = 1024;
4531
- var DEFAULT_TIMEOUT13 = 6e4;
4731
+ var DEFAULT_TIMEOUT14 = 6e4;
4532
4732
  var SDK_VERSION2 = "0.3.0";
4533
4733
  var USER_AGENT2 = `blockrun-ts/${SDK_VERSION2}`;
4534
4734
  var DEFAULT_SOLANA_RPC_URL = "https://sol.blockrun.ai/api/v1/solana/rpc";
@@ -4578,7 +4778,7 @@ var SolanaLLMClient = class {
4578
4778
  const rpc = resolveRpcConfig(options.rpcUrl, options.rpcHeaders);
4579
4779
  this.rpcUrl = rpc.url;
4580
4780
  this.rpcHeaders = rpc.headers;
4581
- this.timeout = options.timeout || DEFAULT_TIMEOUT13;
4781
+ this.timeout = options.timeout || DEFAULT_TIMEOUT14;
4582
4782
  }
4583
4783
  /** Get Solana wallet address (public key in base58). */
4584
4784
  async getWalletAddress() {
@@ -5492,7 +5692,7 @@ var OpenAI = class {
5492
5692
  };
5493
5693
 
5494
5694
  // src/anthropic-compat.ts
5495
- var import_accounts15 = require("viem/accounts");
5695
+ var import_accounts16 = require("viem/accounts");
5496
5696
  var AnthropicClient = class {
5497
5697
  _client = null;
5498
5698
  _clientPromise = null;
@@ -5505,7 +5705,7 @@ var AnthropicClient = class {
5505
5705
  const key = options.privateKey ?? wallet.privateKey;
5506
5706
  validatePrivateKey(key);
5507
5707
  this._privateKey = key;
5508
- this._account = (0, import_accounts15.privateKeyToAccount)(this._privateKey);
5708
+ this._account = (0, import_accounts16.privateKeyToAccount)(this._privateKey);
5509
5709
  const apiUrl = options.apiUrl ?? "https://blockrun.ai/api";
5510
5710
  validateApiUrl(apiUrl);
5511
5711
  this._apiUrl = apiUrl.replace(/\/$/, "");
@@ -5621,6 +5821,7 @@ var AnthropicClient = class {
5621
5821
  SOLANA_WALLET_FILE_PATH,
5622
5822
  SearchClient,
5623
5823
  SolanaLLMClient,
5824
+ SpeechClient,
5624
5825
  SurfClient,
5625
5826
  USDC_BASE,
5626
5827
  USDC_BASE_CONTRACT,