@blockrun/llm 2.3.0 → 2.4.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
@@ -455,6 +455,50 @@ const results = await x.search('x402 micropayments', { queryType: 'Latest' });
455
455
  const tweets = await x.userTweets({ username: 'vitalikbuterin', includeReplies: false });
456
456
  ```
457
457
 
458
+ ### Surf Crypto Data
459
+
460
+ `SurfClient` exposes the full `/v1/surf/*` catalog — 84+ pay-per-call
461
+ endpoints across CEX/DEX market data, on-chain SQL, wallet intelligence,
462
+ prediction markets (Polymarket + Kalshi), social analytics, news, VC fund
463
+ data, and an OpenAI-compatible chat surface. Flat pricing per call:
464
+
465
+ | Tier | Price/call | Examples |
466
+ |------|-----------|----------|
467
+ | 1 | $0.001 | `/market/price`, `/market/ranking`, `/news/feed`, prediction-market reads, social tweets |
468
+ | 2 | $0.005 | `/exchange/depth`, `/exchange/klines`, `/wallet/detail`, `/search/*`, `/social/ranking` |
469
+ | 3 | $0.020 | `/onchain/sql`, `/onchain/query`, `/onchain/schema`, `/chat/completions` |
470
+
471
+ Because the catalog is broad and evolving, the client deliberately ships a
472
+ generic `get` / `post` pair instead of 84 typed wrappers. Pass the path
473
+ (with or without the `/v1/surf` prefix), query params, or a JSON body —
474
+ type the response via a generic if you want.
475
+
476
+ ```ts
477
+ import { SurfClient } from '@blockrun/llm';
478
+
479
+ const surf = new SurfClient();
480
+
481
+ // Tier 1 — token price ($0.001)
482
+ const btc = await surf.get('/market/price', { symbol: 'BTC' });
483
+
484
+ // Tier 2 — order book depth ($0.005)
485
+ const book = await surf.get('/exchange/depth', {
486
+ exchange: 'binance',
487
+ symbol: 'BTC-USDT',
488
+ });
489
+
490
+ // Tier 3 — raw on-chain SQL against 80+ ClickHouse tables ($0.020)
491
+ const rows = await surf.post('/onchain/sql', {
492
+ query: 'SELECT block_number FROM ethereum.blocks ORDER BY block_number DESC LIMIT 5',
493
+ });
494
+
495
+ // Typed response via generic
496
+ type Price = { symbol: string; price: number; timestamp: string };
497
+ const eth = await surf.get<Price>('/market/price', { symbol: 'ETH' });
498
+ ```
499
+
500
+ Full endpoint inventory: <https://blockrun.ai/marketplace/surf>.
501
+
458
502
  Methods: `userLookup`, `userInfo`, `followers`, `following`, `followings`,
459
503
  `verifiedFollowers`, `userTweets`, `mentions`, `tweetLookup`, `tweetReplies`,
460
504
  `tweetThread`, `search`, `trending`, `articlesRising`.
package/dist/index.cjs CHANGED
@@ -45,6 +45,7 @@ __export(index_exports, {
45
45
  SOLANA_WALLET_FILE_PATH: () => SOLANA_WALLET_FILE,
46
46
  SearchClient: () => SearchClient,
47
47
  SolanaLLMClient: () => SolanaLLMClient,
48
+ SurfClient: () => SurfClient,
48
49
  USDC_BASE: () => USDC_BASE,
49
50
  USDC_BASE_CONTRACT: () => USDC_BASE_CONTRACT,
50
51
  USDC_SOLANA: () => USDC_SOLANA,
@@ -3312,8 +3313,163 @@ function buildUrl(base, query) {
3312
3313
  return `${base}?${qs}`;
3313
3314
  }
3314
3315
 
3315
- // src/wallet.ts
3316
+ // src/surf.ts
3316
3317
  var import_accounts10 = require("viem/accounts");
3318
+ var DEFAULT_API_URL9 = "https://blockrun.ai/api";
3319
+ var DEFAULT_TIMEOUT9 = 6e4;
3320
+ var SURF_PREFIX = "/v1/surf";
3321
+ var SurfClient = class {
3322
+ account;
3323
+ privateKey;
3324
+ apiUrl;
3325
+ timeout;
3326
+ constructor(options = {}) {
3327
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
3328
+ const privateKey = options.privateKey || envKey;
3329
+ if (!privateKey) {
3330
+ throw new Error(
3331
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
3332
+ );
3333
+ }
3334
+ validatePrivateKey(privateKey);
3335
+ this.privateKey = privateKey;
3336
+ this.account = (0, import_accounts10.privateKeyToAccount)(privateKey);
3337
+ const apiUrl = options.apiUrl || DEFAULT_API_URL9;
3338
+ validateApiUrl(apiUrl);
3339
+ this.apiUrl = apiUrl.replace(/\/$/, "");
3340
+ this.timeout = options.timeout || DEFAULT_TIMEOUT9;
3341
+ }
3342
+ /**
3343
+ * GET a Surf endpoint. `path` is everything after `/v1/surf` (a leading
3344
+ * `/v1/surf` is tolerated and stripped). Query params are URL-encoded;
3345
+ * arrays become repeated keys (`?a=1&a=2`).
3346
+ */
3347
+ async get(path5, params) {
3348
+ const url = this.buildUrl(path5, params);
3349
+ return this.requestWithPayment(url, "GET");
3350
+ }
3351
+ /**
3352
+ * POST a Surf endpoint with a JSON body. Same path normalization as `get`.
3353
+ */
3354
+ async post(path5, body) {
3355
+ const url = this.buildUrl(path5);
3356
+ return this.requestWithPayment(url, "POST", body);
3357
+ }
3358
+ buildUrl(path5, params) {
3359
+ let normalized = path5.startsWith("/") ? path5 : `/${path5}`;
3360
+ if (!normalized.startsWith(SURF_PREFIX)) {
3361
+ normalized = `${SURF_PREFIX}${normalized}`;
3362
+ }
3363
+ const base = `${this.apiUrl}${normalized}`;
3364
+ if (!params) return base;
3365
+ const qs = new URLSearchParams();
3366
+ for (const [key, value] of Object.entries(params)) {
3367
+ if (value === void 0 || value === null) continue;
3368
+ if (Array.isArray(value)) {
3369
+ for (const v of value) {
3370
+ if (v === void 0 || v === null) continue;
3371
+ qs.append(key, String(v));
3372
+ }
3373
+ } else {
3374
+ qs.append(key, String(value));
3375
+ }
3376
+ }
3377
+ const query = qs.toString();
3378
+ return query ? `${base}?${query}` : base;
3379
+ }
3380
+ async requestWithPayment(url, method, body) {
3381
+ const init = { method };
3382
+ if (method === "POST") {
3383
+ init.headers = { "Content-Type": "application/json" };
3384
+ init.body = JSON.stringify(body ?? {});
3385
+ }
3386
+ const response = await this.fetchWithTimeout(url, init);
3387
+ if (response.status === 402) {
3388
+ return this.handlePaymentAndRetry(url, method, body, response);
3389
+ }
3390
+ if (!response.ok) {
3391
+ await this.throwApiError(response, `Surf request failed (${method} ${url})`);
3392
+ }
3393
+ return response.json();
3394
+ }
3395
+ async handlePaymentAndRetry(url, method, body, response) {
3396
+ let paymentHeader = response.headers.get("payment-required");
3397
+ if (!paymentHeader) {
3398
+ try {
3399
+ const respBody = await response.json();
3400
+ if (respBody.x402Version !== void 0 || respBody.accepts !== void 0) {
3401
+ paymentHeader = btoa(JSON.stringify(respBody));
3402
+ }
3403
+ } catch {
3404
+ }
3405
+ }
3406
+ if (!paymentHeader) {
3407
+ throw new PaymentError("402 response but no payment requirements found");
3408
+ }
3409
+ const paymentRequired = parsePaymentRequired(paymentHeader);
3410
+ const details = extractPaymentDetails(paymentRequired);
3411
+ const paymentPayload = await createPaymentPayload(
3412
+ this.privateKey,
3413
+ this.account.address,
3414
+ details.recipient,
3415
+ details.amount,
3416
+ details.network || "eip155:8453",
3417
+ {
3418
+ resourceUrl: details.resource?.url || url,
3419
+ resourceDescription: details.resource?.description || "BlockRun Surf",
3420
+ maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
3421
+ extra: details.extra
3422
+ }
3423
+ );
3424
+ const retryInit = {
3425
+ method,
3426
+ headers: { "PAYMENT-SIGNATURE": paymentPayload }
3427
+ };
3428
+ if (method === "POST") {
3429
+ retryInit.headers = {
3430
+ ...retryInit.headers,
3431
+ "Content-Type": "application/json"
3432
+ };
3433
+ retryInit.body = JSON.stringify(body ?? {});
3434
+ }
3435
+ const retry = await this.fetchWithTimeout(url, retryInit);
3436
+ if (retry.status === 402) {
3437
+ throw new PaymentError("Payment was rejected. Check your wallet balance.");
3438
+ }
3439
+ if (!retry.ok) {
3440
+ await this.throwApiError(retry, `Surf request failed after payment (${method} ${url})`);
3441
+ }
3442
+ return retry.json();
3443
+ }
3444
+ async throwApiError(resp, prefix) {
3445
+ let errorBody;
3446
+ try {
3447
+ errorBody = await resp.json();
3448
+ } catch {
3449
+ errorBody = { error: "Request failed" };
3450
+ }
3451
+ throw new APIError(
3452
+ `${prefix}: HTTP ${resp.status}`,
3453
+ resp.status,
3454
+ sanitizeErrorResponse(errorBody)
3455
+ );
3456
+ }
3457
+ async fetchWithTimeout(url, init) {
3458
+ const controller = new AbortController();
3459
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3460
+ try {
3461
+ return await fetch(url, { ...init, signal: controller.signal });
3462
+ } finally {
3463
+ clearTimeout(timeoutId);
3464
+ }
3465
+ }
3466
+ getWalletAddress() {
3467
+ return this.account.address;
3468
+ }
3469
+ };
3470
+
3471
+ // src/wallet.ts
3472
+ var import_accounts11 = require("viem/accounts");
3317
3473
  var fs2 = __toESM(require("fs"), 1);
3318
3474
  var path2 = __toESM(require("path"), 1);
3319
3475
  var os2 = __toESM(require("os"), 1);
@@ -3322,8 +3478,8 @@ var BASE_CHAIN_ID2 = "8453";
3322
3478
  var WALLET_DIR = path2.join(os2.homedir(), ".blockrun");
3323
3479
  var WALLET_FILE = path2.join(WALLET_DIR, ".session");
3324
3480
  function createWallet() {
3325
- const privateKey = (0, import_accounts10.generatePrivateKey)();
3326
- const account = (0, import_accounts10.privateKeyToAccount)(privateKey);
3481
+ const privateKey = (0, import_accounts11.generatePrivateKey)();
3482
+ const account = (0, import_accounts11.privateKeyToAccount)(privateKey);
3327
3483
  return {
3328
3484
  address: account.address,
3329
3485
  privateKey
@@ -3379,12 +3535,12 @@ function loadWallet() {
3379
3535
  function getOrCreateWallet() {
3380
3536
  const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
3381
3537
  if (envKey) {
3382
- const account = (0, import_accounts10.privateKeyToAccount)(envKey);
3538
+ const account = (0, import_accounts11.privateKeyToAccount)(envKey);
3383
3539
  return { address: account.address, privateKey: envKey, isNew: false };
3384
3540
  }
3385
3541
  const fileKey = loadWallet();
3386
3542
  if (fileKey) {
3387
- const account = (0, import_accounts10.privateKeyToAccount)(fileKey);
3543
+ const account = (0, import_accounts11.privateKeyToAccount)(fileKey);
3388
3544
  return { address: account.address, privateKey: fileKey, isNew: false };
3389
3545
  }
3390
3546
  const { address, privateKey } = createWallet();
@@ -3394,11 +3550,11 @@ function getOrCreateWallet() {
3394
3550
  function getWalletAddress() {
3395
3551
  const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
3396
3552
  if (envKey) {
3397
- return (0, import_accounts10.privateKeyToAccount)(envKey).address;
3553
+ return (0, import_accounts11.privateKeyToAccount)(envKey).address;
3398
3554
  }
3399
3555
  const fileKey = loadWallet();
3400
3556
  if (fileKey) {
3401
- return (0, import_accounts10.privateKeyToAccount)(fileKey).address;
3557
+ return (0, import_accounts11.privateKeyToAccount)(fileKey).address;
3402
3558
  }
3403
3559
  return null;
3404
3560
  }
@@ -3578,7 +3734,7 @@ async function getOrCreateSolanaWallet() {
3578
3734
  // src/solana-client.ts
3579
3735
  var SOLANA_API_URL = "https://sol.blockrun.ai/api";
3580
3736
  var DEFAULT_MAX_TOKENS2 = 1024;
3581
- var DEFAULT_TIMEOUT9 = 6e4;
3737
+ var DEFAULT_TIMEOUT10 = 6e4;
3582
3738
  var SDK_VERSION2 = "0.3.0";
3583
3739
  var USER_AGENT2 = `blockrun-ts/${SDK_VERSION2}`;
3584
3740
  var SolanaLLMClient = class {
@@ -3603,7 +3759,7 @@ var SolanaLLMClient = class {
3603
3759
  validateApiUrl(apiUrl);
3604
3760
  this.apiUrl = apiUrl.replace(/\/$/, "");
3605
3761
  this.rpcUrl = options.rpcUrl || "https://api.mainnet-beta.solana.com";
3606
- this.timeout = options.timeout || DEFAULT_TIMEOUT9;
3762
+ this.timeout = options.timeout || DEFAULT_TIMEOUT10;
3607
3763
  }
3608
3764
  /** Get Solana wallet address (public key in base58). */
3609
3765
  async getWalletAddress() {
@@ -4510,7 +4666,7 @@ var OpenAI = class {
4510
4666
  };
4511
4667
 
4512
4668
  // src/anthropic-compat.ts
4513
- var import_accounts11 = require("viem/accounts");
4669
+ var import_accounts12 = require("viem/accounts");
4514
4670
  var AnthropicClient = class {
4515
4671
  _client = null;
4516
4672
  _clientPromise = null;
@@ -4523,7 +4679,7 @@ var AnthropicClient = class {
4523
4679
  const key = options.privateKey ?? wallet.privateKey;
4524
4680
  validatePrivateKey(key);
4525
4681
  this._privateKey = key;
4526
- this._account = (0, import_accounts11.privateKeyToAccount)(this._privateKey);
4682
+ this._account = (0, import_accounts12.privateKeyToAccount)(this._privateKey);
4527
4683
  const apiUrl = options.apiUrl ?? "https://blockrun.ai/api";
4528
4684
  validateApiUrl(apiUrl);
4529
4685
  this._apiUrl = apiUrl.replace(/\/$/, "");
@@ -4634,6 +4790,7 @@ var AnthropicClient = class {
4634
4790
  SOLANA_WALLET_FILE_PATH,
4635
4791
  SearchClient,
4636
4792
  SolanaLLMClient,
4793
+ SurfClient,
4637
4794
  USDC_BASE,
4638
4795
  USDC_BASE_CONTRACT,
4639
4796
  USDC_SOLANA,
package/dist/index.d.cts CHANGED
@@ -785,6 +785,11 @@ interface PriceClientOptions {
785
785
  /** If false, construction succeeds without a wallet (free endpoints only). */
786
786
  requireWallet?: boolean;
787
787
  }
788
+ interface SurfClientOptions {
789
+ privateKey?: `0x${string}` | string;
790
+ apiUrl?: string;
791
+ timeout?: number;
792
+ }
788
793
  declare class BlockrunError extends Error {
789
794
  constructor(message: string);
790
795
  }
@@ -1713,6 +1718,74 @@ declare class PriceClient {
1713
1718
  private fetchWithTimeout;
1714
1719
  }
1715
1720
 
1721
+ /**
1722
+ * BlockRun Surf Client — pay-per-call crypto data via x402 micropayments.
1723
+ *
1724
+ * Surf aggregates 84+ endpoints across CEX/DEX market data, on-chain SQL,
1725
+ * wallet intelligence, prediction markets, social analytics, and news under
1726
+ * a single OpenAPI surface mounted at `/api/v1/surf/*`.
1727
+ *
1728
+ * Pricing tiers (flat per-call, USDC on Base):
1729
+ * Tier 1 — $0.001/call (prices, rankings, lists, news, simple reads)
1730
+ * Tier 2 — $0.005/call (order books, candles, search, wallet details)
1731
+ * Tier 3 — $0.020/call (on-chain SQL, schema introspection, chat)
1732
+ *
1733
+ * Because the catalog is large and evolving, this client deliberately
1734
+ * exposes a thin `get` / `post` pair instead of 84 typed wrappers. Pass the
1735
+ * path (with or without the `/v1/surf` prefix) and either query params or a
1736
+ * JSON body. The full endpoint inventory lives at
1737
+ * https://blockrun.ai/marketplace/surf.
1738
+ *
1739
+ * Usage:
1740
+ * import { SurfClient } from "@blockrun/llm";
1741
+ *
1742
+ * const surf = new SurfClient({ privateKey: "0x..." });
1743
+ *
1744
+ * // Tier 1 — token price ($0.001)
1745
+ * const btc = await surf.get("/market/price", { symbol: "BTC" });
1746
+ *
1747
+ * // Tier 2 — order book ($0.005)
1748
+ * const book = await surf.get("/exchange/depth", {
1749
+ * exchange: "binance",
1750
+ * symbol: "BTC-USDT",
1751
+ * });
1752
+ *
1753
+ * // Tier 3 — raw on-chain SQL ($0.020)
1754
+ * const rows = await surf.post("/onchain/sql", {
1755
+ * query: "SELECT block_number FROM ethereum.blocks ORDER BY block_number DESC LIMIT 5",
1756
+ * });
1757
+ *
1758
+ * // Typed responses via generic
1759
+ * type Price = { symbol: string; price: number; timestamp: string };
1760
+ * const typed = await surf.get<Price>("/market/price", { symbol: "ETH" });
1761
+ */
1762
+
1763
+ type QueryValue = string | number | boolean | null | undefined;
1764
+ type QueryParams = Record<string, QueryValue | QueryValue[]>;
1765
+ declare class SurfClient {
1766
+ private account;
1767
+ private privateKey;
1768
+ private apiUrl;
1769
+ private timeout;
1770
+ constructor(options?: SurfClientOptions);
1771
+ /**
1772
+ * GET a Surf endpoint. `path` is everything after `/v1/surf` (a leading
1773
+ * `/v1/surf` is tolerated and stripped). Query params are URL-encoded;
1774
+ * arrays become repeated keys (`?a=1&a=2`).
1775
+ */
1776
+ get<T = unknown>(path: string, params?: QueryParams): Promise<T>;
1777
+ /**
1778
+ * POST a Surf endpoint with a JSON body. Same path normalization as `get`.
1779
+ */
1780
+ post<T = unknown>(path: string, body?: Record<string, unknown>): Promise<T>;
1781
+ private buildUrl;
1782
+ private requestWithPayment;
1783
+ private handlePaymentAndRetry;
1784
+ private throwApiError;
1785
+ private fetchWithTimeout;
1786
+ getWalletAddress(): string;
1787
+ }
1788
+
1716
1789
  /**
1717
1790
  * x402 Payment Protocol v2 Implementation for BlockRun.
1718
1791
  *
@@ -2356,4 +2429,4 @@ declare function validateTemperature(temperature?: number): void;
2356
2429
  */
2357
2430
  declare function validateTopP(topP?: number): void;
2358
2431
 
2359
- export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, 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, 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, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PaymentError, type PaymentLinks, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type Spending, type SpendingReport, type StockMarket, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XArticlesRisingResponse, type XAuthorAnalyticsResponse, XClient, type XClientOptions, type XCompareAuthorsResponse, type XFollower, type XFollowersResponse, type XFollowingsResponse, type XMentionsOptions, type XMentionsResponse, type XSearchOptions, type XSearchResponse, type XSearchSource, type XTrendingResponse, type XTweet, type XTweetLookupResponse, type XTweetRepliesOptions, type XTweetRepliesResponse, type XTweetThreadResponse, type XTweetsResponse, type XUser, type XUserInfoResponse, type XUserLookupResponse, type XUserTweetsOptions, type XVerifiedFollowersResponse, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatWalletCreatedMessage, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, validateMaxTokens, validateModel, validateTemperature, validateTopP };
2432
+ export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, 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, 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, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PaymentError, type PaymentLinks, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XArticlesRisingResponse, type XAuthorAnalyticsResponse, XClient, type XClientOptions, type XCompareAuthorsResponse, type XFollower, type XFollowersResponse, type XFollowingsResponse, type XMentionsOptions, type XMentionsResponse, type XSearchOptions, type XSearchResponse, type XSearchSource, type XTrendingResponse, type XTweet, type XTweetLookupResponse, type XTweetRepliesOptions, type XTweetRepliesResponse, type XTweetThreadResponse, type XTweetsResponse, type XUser, type XUserInfoResponse, type XUserLookupResponse, type XUserTweetsOptions, type XVerifiedFollowersResponse, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatWalletCreatedMessage, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, validateMaxTokens, validateModel, validateTemperature, validateTopP };
package/dist/index.d.ts CHANGED
@@ -785,6 +785,11 @@ interface PriceClientOptions {
785
785
  /** If false, construction succeeds without a wallet (free endpoints only). */
786
786
  requireWallet?: boolean;
787
787
  }
788
+ interface SurfClientOptions {
789
+ privateKey?: `0x${string}` | string;
790
+ apiUrl?: string;
791
+ timeout?: number;
792
+ }
788
793
  declare class BlockrunError extends Error {
789
794
  constructor(message: string);
790
795
  }
@@ -1713,6 +1718,74 @@ declare class PriceClient {
1713
1718
  private fetchWithTimeout;
1714
1719
  }
1715
1720
 
1721
+ /**
1722
+ * BlockRun Surf Client — pay-per-call crypto data via x402 micropayments.
1723
+ *
1724
+ * Surf aggregates 84+ endpoints across CEX/DEX market data, on-chain SQL,
1725
+ * wallet intelligence, prediction markets, social analytics, and news under
1726
+ * a single OpenAPI surface mounted at `/api/v1/surf/*`.
1727
+ *
1728
+ * Pricing tiers (flat per-call, USDC on Base):
1729
+ * Tier 1 — $0.001/call (prices, rankings, lists, news, simple reads)
1730
+ * Tier 2 — $0.005/call (order books, candles, search, wallet details)
1731
+ * Tier 3 — $0.020/call (on-chain SQL, schema introspection, chat)
1732
+ *
1733
+ * Because the catalog is large and evolving, this client deliberately
1734
+ * exposes a thin `get` / `post` pair instead of 84 typed wrappers. Pass the
1735
+ * path (with or without the `/v1/surf` prefix) and either query params or a
1736
+ * JSON body. The full endpoint inventory lives at
1737
+ * https://blockrun.ai/marketplace/surf.
1738
+ *
1739
+ * Usage:
1740
+ * import { SurfClient } from "@blockrun/llm";
1741
+ *
1742
+ * const surf = new SurfClient({ privateKey: "0x..." });
1743
+ *
1744
+ * // Tier 1 — token price ($0.001)
1745
+ * const btc = await surf.get("/market/price", { symbol: "BTC" });
1746
+ *
1747
+ * // Tier 2 — order book ($0.005)
1748
+ * const book = await surf.get("/exchange/depth", {
1749
+ * exchange: "binance",
1750
+ * symbol: "BTC-USDT",
1751
+ * });
1752
+ *
1753
+ * // Tier 3 — raw on-chain SQL ($0.020)
1754
+ * const rows = await surf.post("/onchain/sql", {
1755
+ * query: "SELECT block_number FROM ethereum.blocks ORDER BY block_number DESC LIMIT 5",
1756
+ * });
1757
+ *
1758
+ * // Typed responses via generic
1759
+ * type Price = { symbol: string; price: number; timestamp: string };
1760
+ * const typed = await surf.get<Price>("/market/price", { symbol: "ETH" });
1761
+ */
1762
+
1763
+ type QueryValue = string | number | boolean | null | undefined;
1764
+ type QueryParams = Record<string, QueryValue | QueryValue[]>;
1765
+ declare class SurfClient {
1766
+ private account;
1767
+ private privateKey;
1768
+ private apiUrl;
1769
+ private timeout;
1770
+ constructor(options?: SurfClientOptions);
1771
+ /**
1772
+ * GET a Surf endpoint. `path` is everything after `/v1/surf` (a leading
1773
+ * `/v1/surf` is tolerated and stripped). Query params are URL-encoded;
1774
+ * arrays become repeated keys (`?a=1&a=2`).
1775
+ */
1776
+ get<T = unknown>(path: string, params?: QueryParams): Promise<T>;
1777
+ /**
1778
+ * POST a Surf endpoint with a JSON body. Same path normalization as `get`.
1779
+ */
1780
+ post<T = unknown>(path: string, body?: Record<string, unknown>): Promise<T>;
1781
+ private buildUrl;
1782
+ private requestWithPayment;
1783
+ private handlePaymentAndRetry;
1784
+ private throwApiError;
1785
+ private fetchWithTimeout;
1786
+ getWalletAddress(): string;
1787
+ }
1788
+
1716
1789
  /**
1717
1790
  * x402 Payment Protocol v2 Implementation for BlockRun.
1718
1791
  *
@@ -2356,4 +2429,4 @@ declare function validateTemperature(temperature?: number): void;
2356
2429
  */
2357
2430
  declare function validateTopP(topP?: number): void;
2358
2431
 
2359
- export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, 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, 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, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PaymentError, type PaymentLinks, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type Spending, type SpendingReport, type StockMarket, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XArticlesRisingResponse, type XAuthorAnalyticsResponse, XClient, type XClientOptions, type XCompareAuthorsResponse, type XFollower, type XFollowersResponse, type XFollowingsResponse, type XMentionsOptions, type XMentionsResponse, type XSearchOptions, type XSearchResponse, type XSearchSource, type XTrendingResponse, type XTweet, type XTweetLookupResponse, type XTweetRepliesOptions, type XTweetRepliesResponse, type XTweetThreadResponse, type XTweetsResponse, type XUser, type XUserInfoResponse, type XUserLookupResponse, type XUserTweetsOptions, type XVerifiedFollowersResponse, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatWalletCreatedMessage, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, validateMaxTokens, validateModel, validateTemperature, validateTopP };
2432
+ export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, 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, 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, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PaymentError, type PaymentLinks, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XArticlesRisingResponse, type XAuthorAnalyticsResponse, XClient, type XClientOptions, type XCompareAuthorsResponse, type XFollower, type XFollowersResponse, type XFollowingsResponse, type XMentionsOptions, type XMentionsResponse, type XSearchOptions, type XSearchResponse, type XSearchSource, type XTrendingResponse, type XTweet, type XTweetLookupResponse, type XTweetRepliesOptions, type XTweetRepliesResponse, type XTweetThreadResponse, type XTweetsResponse, type XUser, type XUserInfoResponse, type XUserLookupResponse, type XUserTweetsOptions, type XVerifiedFollowersResponse, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatWalletCreatedMessage, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, validateMaxTokens, validateModel, validateTemperature, validateTopP };
package/dist/index.js CHANGED
@@ -3215,8 +3215,163 @@ function buildUrl(base, query) {
3215
3215
  return `${base}?${qs}`;
3216
3216
  }
3217
3217
 
3218
+ // src/surf.ts
3219
+ import { privateKeyToAccount as privateKeyToAccount9 } from "viem/accounts";
3220
+ var DEFAULT_API_URL9 = "https://blockrun.ai/api";
3221
+ var DEFAULT_TIMEOUT9 = 6e4;
3222
+ var SURF_PREFIX = "/v1/surf";
3223
+ var SurfClient = class {
3224
+ account;
3225
+ privateKey;
3226
+ apiUrl;
3227
+ timeout;
3228
+ constructor(options = {}) {
3229
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
3230
+ const privateKey = options.privateKey || envKey;
3231
+ if (!privateKey) {
3232
+ throw new Error(
3233
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
3234
+ );
3235
+ }
3236
+ validatePrivateKey(privateKey);
3237
+ this.privateKey = privateKey;
3238
+ this.account = privateKeyToAccount9(privateKey);
3239
+ const apiUrl = options.apiUrl || DEFAULT_API_URL9;
3240
+ validateApiUrl(apiUrl);
3241
+ this.apiUrl = apiUrl.replace(/\/$/, "");
3242
+ this.timeout = options.timeout || DEFAULT_TIMEOUT9;
3243
+ }
3244
+ /**
3245
+ * GET a Surf endpoint. `path` is everything after `/v1/surf` (a leading
3246
+ * `/v1/surf` is tolerated and stripped). Query params are URL-encoded;
3247
+ * arrays become repeated keys (`?a=1&a=2`).
3248
+ */
3249
+ async get(path5, params) {
3250
+ const url = this.buildUrl(path5, params);
3251
+ return this.requestWithPayment(url, "GET");
3252
+ }
3253
+ /**
3254
+ * POST a Surf endpoint with a JSON body. Same path normalization as `get`.
3255
+ */
3256
+ async post(path5, body) {
3257
+ const url = this.buildUrl(path5);
3258
+ return this.requestWithPayment(url, "POST", body);
3259
+ }
3260
+ buildUrl(path5, params) {
3261
+ let normalized = path5.startsWith("/") ? path5 : `/${path5}`;
3262
+ if (!normalized.startsWith(SURF_PREFIX)) {
3263
+ normalized = `${SURF_PREFIX}${normalized}`;
3264
+ }
3265
+ const base = `${this.apiUrl}${normalized}`;
3266
+ if (!params) return base;
3267
+ const qs = new URLSearchParams();
3268
+ for (const [key, value] of Object.entries(params)) {
3269
+ if (value === void 0 || value === null) continue;
3270
+ if (Array.isArray(value)) {
3271
+ for (const v of value) {
3272
+ if (v === void 0 || v === null) continue;
3273
+ qs.append(key, String(v));
3274
+ }
3275
+ } else {
3276
+ qs.append(key, String(value));
3277
+ }
3278
+ }
3279
+ const query = qs.toString();
3280
+ return query ? `${base}?${query}` : base;
3281
+ }
3282
+ async requestWithPayment(url, method, body) {
3283
+ const init = { method };
3284
+ if (method === "POST") {
3285
+ init.headers = { "Content-Type": "application/json" };
3286
+ init.body = JSON.stringify(body ?? {});
3287
+ }
3288
+ const response = await this.fetchWithTimeout(url, init);
3289
+ if (response.status === 402) {
3290
+ return this.handlePaymentAndRetry(url, method, body, response);
3291
+ }
3292
+ if (!response.ok) {
3293
+ await this.throwApiError(response, `Surf request failed (${method} ${url})`);
3294
+ }
3295
+ return response.json();
3296
+ }
3297
+ async handlePaymentAndRetry(url, method, body, response) {
3298
+ let paymentHeader = response.headers.get("payment-required");
3299
+ if (!paymentHeader) {
3300
+ try {
3301
+ const respBody = await response.json();
3302
+ if (respBody.x402Version !== void 0 || respBody.accepts !== void 0) {
3303
+ paymentHeader = btoa(JSON.stringify(respBody));
3304
+ }
3305
+ } catch {
3306
+ }
3307
+ }
3308
+ if (!paymentHeader) {
3309
+ throw new PaymentError("402 response but no payment requirements found");
3310
+ }
3311
+ const paymentRequired = parsePaymentRequired(paymentHeader);
3312
+ const details = extractPaymentDetails(paymentRequired);
3313
+ const paymentPayload = await createPaymentPayload(
3314
+ this.privateKey,
3315
+ this.account.address,
3316
+ details.recipient,
3317
+ details.amount,
3318
+ details.network || "eip155:8453",
3319
+ {
3320
+ resourceUrl: details.resource?.url || url,
3321
+ resourceDescription: details.resource?.description || "BlockRun Surf",
3322
+ maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
3323
+ extra: details.extra
3324
+ }
3325
+ );
3326
+ const retryInit = {
3327
+ method,
3328
+ headers: { "PAYMENT-SIGNATURE": paymentPayload }
3329
+ };
3330
+ if (method === "POST") {
3331
+ retryInit.headers = {
3332
+ ...retryInit.headers,
3333
+ "Content-Type": "application/json"
3334
+ };
3335
+ retryInit.body = JSON.stringify(body ?? {});
3336
+ }
3337
+ const retry = await this.fetchWithTimeout(url, retryInit);
3338
+ if (retry.status === 402) {
3339
+ throw new PaymentError("Payment was rejected. Check your wallet balance.");
3340
+ }
3341
+ if (!retry.ok) {
3342
+ await this.throwApiError(retry, `Surf request failed after payment (${method} ${url})`);
3343
+ }
3344
+ return retry.json();
3345
+ }
3346
+ async throwApiError(resp, prefix) {
3347
+ let errorBody;
3348
+ try {
3349
+ errorBody = await resp.json();
3350
+ } catch {
3351
+ errorBody = { error: "Request failed" };
3352
+ }
3353
+ throw new APIError(
3354
+ `${prefix}: HTTP ${resp.status}`,
3355
+ resp.status,
3356
+ sanitizeErrorResponse(errorBody)
3357
+ );
3358
+ }
3359
+ async fetchWithTimeout(url, init) {
3360
+ const controller = new AbortController();
3361
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3362
+ try {
3363
+ return await fetch(url, { ...init, signal: controller.signal });
3364
+ } finally {
3365
+ clearTimeout(timeoutId);
3366
+ }
3367
+ }
3368
+ getWalletAddress() {
3369
+ return this.account.address;
3370
+ }
3371
+ };
3372
+
3218
3373
  // src/wallet.ts
3219
- import { privateKeyToAccount as privateKeyToAccount9, generatePrivateKey } from "viem/accounts";
3374
+ import { privateKeyToAccount as privateKeyToAccount10, generatePrivateKey } from "viem/accounts";
3220
3375
  import * as fs2 from "fs";
3221
3376
  import * as path2 from "path";
3222
3377
  import * as os2 from "os";
@@ -3226,7 +3381,7 @@ var WALLET_DIR = path2.join(os2.homedir(), ".blockrun");
3226
3381
  var WALLET_FILE = path2.join(WALLET_DIR, ".session");
3227
3382
  function createWallet() {
3228
3383
  const privateKey = generatePrivateKey();
3229
- const account = privateKeyToAccount9(privateKey);
3384
+ const account = privateKeyToAccount10(privateKey);
3230
3385
  return {
3231
3386
  address: account.address,
3232
3387
  privateKey
@@ -3282,12 +3437,12 @@ function loadWallet() {
3282
3437
  function getOrCreateWallet() {
3283
3438
  const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
3284
3439
  if (envKey) {
3285
- const account = privateKeyToAccount9(envKey);
3440
+ const account = privateKeyToAccount10(envKey);
3286
3441
  return { address: account.address, privateKey: envKey, isNew: false };
3287
3442
  }
3288
3443
  const fileKey = loadWallet();
3289
3444
  if (fileKey) {
3290
- const account = privateKeyToAccount9(fileKey);
3445
+ const account = privateKeyToAccount10(fileKey);
3291
3446
  return { address: account.address, privateKey: fileKey, isNew: false };
3292
3447
  }
3293
3448
  const { address, privateKey } = createWallet();
@@ -3297,11 +3452,11 @@ function getOrCreateWallet() {
3297
3452
  function getWalletAddress() {
3298
3453
  const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
3299
3454
  if (envKey) {
3300
- return privateKeyToAccount9(envKey).address;
3455
+ return privateKeyToAccount10(envKey).address;
3301
3456
  }
3302
3457
  const fileKey = loadWallet();
3303
3458
  if (fileKey) {
3304
- return privateKeyToAccount9(fileKey).address;
3459
+ return privateKeyToAccount10(fileKey).address;
3305
3460
  }
3306
3461
  return null;
3307
3462
  }
@@ -3481,7 +3636,7 @@ async function getOrCreateSolanaWallet() {
3481
3636
  // src/solana-client.ts
3482
3637
  var SOLANA_API_URL = "https://sol.blockrun.ai/api";
3483
3638
  var DEFAULT_MAX_TOKENS2 = 1024;
3484
- var DEFAULT_TIMEOUT9 = 6e4;
3639
+ var DEFAULT_TIMEOUT10 = 6e4;
3485
3640
  var SDK_VERSION2 = "0.3.0";
3486
3641
  var USER_AGENT2 = `blockrun-ts/${SDK_VERSION2}`;
3487
3642
  var SolanaLLMClient = class {
@@ -3506,7 +3661,7 @@ var SolanaLLMClient = class {
3506
3661
  validateApiUrl(apiUrl);
3507
3662
  this.apiUrl = apiUrl.replace(/\/$/, "");
3508
3663
  this.rpcUrl = options.rpcUrl || "https://api.mainnet-beta.solana.com";
3509
- this.timeout = options.timeout || DEFAULT_TIMEOUT9;
3664
+ this.timeout = options.timeout || DEFAULT_TIMEOUT10;
3510
3665
  }
3511
3666
  /** Get Solana wallet address (public key in base58). */
3512
3667
  async getWalletAddress() {
@@ -4413,7 +4568,7 @@ var OpenAI = class {
4413
4568
  };
4414
4569
 
4415
4570
  // src/anthropic-compat.ts
4416
- import { privateKeyToAccount as privateKeyToAccount10 } from "viem/accounts";
4571
+ import { privateKeyToAccount as privateKeyToAccount11 } from "viem/accounts";
4417
4572
  var AnthropicClient = class {
4418
4573
  _client = null;
4419
4574
  _clientPromise = null;
@@ -4426,7 +4581,7 @@ var AnthropicClient = class {
4426
4581
  const key = options.privateKey ?? wallet.privateKey;
4427
4582
  validatePrivateKey(key);
4428
4583
  this._privateKey = key;
4429
- this._account = privateKeyToAccount10(this._privateKey);
4584
+ this._account = privateKeyToAccount11(this._privateKey);
4430
4585
  const apiUrl = options.apiUrl ?? "https://blockrun.ai/api";
4431
4586
  validateApiUrl(apiUrl);
4432
4587
  this._apiUrl = apiUrl.replace(/\/$/, "");
@@ -4536,6 +4691,7 @@ export {
4536
4691
  SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH,
4537
4692
  SearchClient,
4538
4693
  SolanaLLMClient,
4694
+ SurfClient,
4539
4695
  USDC_BASE,
4540
4696
  USDC_BASE_CONTRACT,
4541
4697
  USDC_SOLANA,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "2.3.0",
3
+ "version": "2.4.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",