@blockrun/llm 3.8.4 → 3.10.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
@@ -1,6 +1,6 @@
1
1
  # @blockrun/llm (TypeScript SDK)
2
2
 
3
- > **@blockrun/llm** is a TypeScript/Node.js SDK for accessing <!-- br:models.chatVisible -->66<!-- /br:models.chatVisible --> large language models (GPT-5, Claude, Gemini, Grok, DeepSeek, Kimi, and more) with automatic pay-per-request USDC micropayments via the x402 protocol. No API keys required — your wallet signature is your authentication. Supports **streaming**, smart routing, Base and Solana chains.
3
+ > **@blockrun/llm** is a TypeScript/Node.js SDK for accessing <!-- br:models.chatVisible -->71<!-- /br:models.chatVisible --> large language models (GPT-5, Claude, Gemini, Grok, DeepSeek, Kimi, and more) with automatic pay-per-request USDC micropayments via the x402 protocol. No API keys required — your wallet signature is your authentication. Supports **streaming**, smart routing, Base and Solana chains.
4
4
  >
5
5
  > 🆓 **Includes 7 fully-free NVIDIA-hosted models** (5 visible in `/v1/models`, 2 hidden but directly callable) — DeepSeek V4 Flash (1M context), Nemotron Nano Omni (vision), Qwen3 Coder, Llama 4, Mistral, plus the gpt-oss pair. Zero USDC, no rate-limit gimmicks. Use `routingProfile: 'free'` or call any `nvidia/*` model directly.
6
6
 
@@ -21,7 +21,7 @@
21
21
  ## Installation
22
22
 
23
23
  ```bash
24
- # Base and Solana support (optional Solana deps auto-installed)
24
+ # Base / EVM payments — nothing else needed
25
25
  npm install @blockrun/llm
26
26
  # or
27
27
  pnpm add @blockrun/llm
@@ -29,6 +29,21 @@ pnpm add @blockrun/llm
29
29
  yarn add @blockrun/llm
30
30
  ```
31
31
 
32
+ **Solana payments** need two more packages. They are optional peer dependencies,
33
+ so npm will not install them for you:
34
+
35
+ ```bash
36
+ npm install @blockrun/llm @solana/web3.js @solana/spl-token
37
+ ```
38
+
39
+ Why they are not automatic: `@solana/spl-token` pulls in `bigint-buffer`, whose
40
+ native `toBigIntLE()` has an unpatched buffer overflow
41
+ ([GHSA-3gc7-fjrx-p6mg](https://github.com/advisories/GHSA-3gc7-fjrx-p6mg)) with no
42
+ fixed release anywhere. As an optional *dependency* it landed in the lockfile of
43
+ every consumer, including projects that only ever pay on Base. As an optional
44
+ *peer* it reaches only the projects that ask for Solana. Calling a Solana path
45
+ without them throws an error naming the exact install command.
46
+
32
47
  ## Quick Start (Base - Default)
33
48
 
34
49
  ```typescript
@@ -263,7 +278,7 @@ const reply = await client.chat('nvidia/deepseek-v4-flash', 'hello', {
263
278
 
264
279
  | Profile | Description | Best For |
265
280
  |---------|-------------|----------|
266
- | `free` | NVIDIA free tier — smart-routes across <!-- br:models.free -->8<!-- /br:models.free --> models (DeepSeek V4 Flash, Nemotron Nano Omni, Qwen3, Llama 4, Mistral, plus 2 hidden gpt-oss) | Zero-cost testing, dev, prod |
281
+ | `free` | NVIDIA free tier — smart-routes across <!-- br:models.free -->6<!-- /br:models.free --> models (DeepSeek V4 Flash, Nemotron Nano Omni, Qwen3, Llama 4, Mistral, plus 2 hidden gpt-oss) | Zero-cost testing, dev, prod |
267
282
  | `eco` | Cheapest models per tier (DeepSeek, xAI) | Cost-sensitive production |
268
283
  | `auto` | Best balance of cost/quality (default) | General use |
269
284
  | `premium` | Top-tier models (OpenAI, Anthropic) | Quality-critical tasks |
@@ -883,7 +898,7 @@ const premium = await client.smartChat('Write a legal brief', { routingProfile:
883
898
 
884
899
  | Profile | Description | Best For |
885
900
  |---------|-------------|----------|
886
- | `free` | NVIDIA free tier (<!-- br:models.free -->8<!-- /br:models.free --> models, smart-routed) | Zero-cost testing, dev, prod |
901
+ | `free` | NVIDIA free tier (<!-- br:models.free -->6<!-- /br:models.free --> models, smart-routed) | Zero-cost testing, dev, prod |
887
902
  | `eco` | Budget-optimized | Cost-sensitive workloads |
888
903
  | `auto` | Intelligent routing (default) | General use |
889
904
  | `premium` | Best quality models | Critical tasks |
package/dist/index.cjs CHANGED
@@ -48,6 +48,7 @@ __export(index_exports, {
48
48
  PortraitClient: () => PortraitClient,
49
49
  PriceClient: () => PriceClient,
50
50
  RPC_PRICE_USD: () => RPC_PRICE_USD,
51
+ RetiredEndpointError: () => RetiredEndpointError,
51
52
  RpcClient: () => RpcClient,
52
53
  SOLANA_NETWORK: () => SOLANA_NETWORK,
53
54
  SOLANA_WALLET_FILE_PATH: () => SOLANA_WALLET_FILE,
@@ -121,6 +122,12 @@ var BlockrunError = class extends Error {
121
122
  this.name = "BlockrunError";
122
123
  }
123
124
  };
125
+ var RetiredEndpointError = class extends BlockrunError {
126
+ constructor(message) {
127
+ super(message);
128
+ this.name = "RetiredEndpointError";
129
+ }
130
+ };
124
131
  var PaymentError = class extends BlockrunError {
125
132
  constructor(message) {
126
133
  super(message);
@@ -140,6 +147,35 @@ var APIError = class extends BlockrunError {
140
147
 
141
148
  // src/x402.ts
142
149
  var import_accounts = require("viem/accounts");
150
+
151
+ // src/solana-deps.ts
152
+ var INSTALL_HINT = "npm install @solana/web3.js @solana/spl-token (or pnpm add / yarn add)";
153
+ function missing(pkg, what, cause) {
154
+ return new Error(
155
+ `@blockrun/llm: ${what} requires the optional peer dependency "${pkg}", which is not installed.
156
+
157
+ ${INSTALL_HINT}
158
+
159
+ Solana packages are optional peers so that consumers who only use Base/EVM payments do not inherit them. If you only make Base payments, you should not be reaching this code path \u2014 check which chain you passed.
160
+ Original error: ${cause instanceof Error ? cause.message : String(cause)}`
161
+ );
162
+ }
163
+ async function loadSolanaWeb3(what) {
164
+ try {
165
+ return await import("@solana/web3.js");
166
+ } catch (err) {
167
+ throw missing("@solana/web3.js", what, err);
168
+ }
169
+ }
170
+ async function loadSplToken(what) {
171
+ try {
172
+ return await import("@solana/spl-token");
173
+ } catch (err) {
174
+ throw missing("@solana/spl-token", what, err);
175
+ }
176
+ }
177
+
178
+ // src/x402.ts
143
179
  var BASE_CHAIN_ID = 8453;
144
180
  var USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
145
181
  var SOLANA_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
@@ -268,9 +304,17 @@ async function createPaymentPayload(privateKey, fromAddress, recipient, amount,
268
304
  return btoa(JSON.stringify(paymentData));
269
305
  }
270
306
  async function createSolanaPaymentPayload(secretKey, fromAddress, recipient, amount, feePayer, options = {}) {
271
- const { Connection, PublicKey, TransactionMessage, VersionedTransaction, ComputeBudgetProgram } = await import("@solana/web3.js");
272
- const { getAssociatedTokenAddress, createTransferCheckedInstruction } = await import("@solana/spl-token");
273
- const { Keypair } = await import("@solana/web3.js");
307
+ const {
308
+ Connection,
309
+ PublicKey,
310
+ TransactionMessage,
311
+ VersionedTransaction,
312
+ ComputeBudgetProgram,
313
+ Keypair
314
+ } = await loadSolanaWeb3("createSolanaPaymentPayload()");
315
+ const { getAssociatedTokenAddress, createTransferCheckedInstruction } = await loadSplToken(
316
+ "createSolanaPaymentPayload()"
317
+ );
274
318
  const rpcUrl = options.rpcUrl || "https://sol.blockrun.ai/api/v1/solana/rpc";
275
319
  const connection = options.rpcHeaders ? new Connection(rpcUrl, { httpHeaders: options.rpcHeaders }) : new Connection(rpcUrl);
276
320
  const keypair = Keypair.fromSecretKey(secretKey);
@@ -564,7 +608,7 @@ function getCostSummary() {
564
608
  }
565
609
 
566
610
  // src/version.ts
567
- var SDK_VERSION = "3.8.4";
611
+ var SDK_VERSION = "3.10.0";
568
612
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
569
613
 
570
614
  // src/client.ts
@@ -1783,20 +1827,38 @@ var LLMClient = class _LLMClient {
1783
1827
  }
1784
1828
  // ── PM convenience helpers (Predexon v2) ─────────────────────────────────
1785
1829
  // Thin wrappers over pm() / pmQuery() for the most common v2 endpoints.
1786
- /** List canonical cross-venue markets (Predexon v2). Tier 1 ($0.001/call).
1787
- * Filter with venue, status, category, league, event_id, pagination_key. */
1788
- async pmMarkets(params) {
1789
- return this.pm("markets", params);
1830
+ /** RETIRED — `/v1/pm/markets` no longer exists.
1831
+ *
1832
+ * Predexon sunset market matching on 2026-07-20 and the whole canonical layer
1833
+ * went with it, so this path returns 410 upstream. Use
1834
+ * `pm("markets/search", { q })` for cross-venue lookups.
1835
+ *
1836
+ * Kept as a throwing stub rather than deleted so upgrading does not break
1837
+ * property access; it throws before any network I/O.
1838
+ *
1839
+ * @throws {RetiredEndpointError} always. */
1840
+ async pmMarkets(_params) {
1841
+ throw new RetiredEndpointError(
1842
+ '/v1/pm/markets was sunset by Predexon on 2026-07-20 (upstream 410). Use pm("markets/search", { q }) for cross-venue lookups.'
1843
+ );
1790
1844
  }
1791
- /** List venue-native executable listings flattened across canonical markets
1792
- * (Predexon v2). Tier 1 ($0.001/call). */
1793
- async pmListings(params) {
1794
- return this.pm("markets/listings", params);
1845
+ /** RETIRED — `/v1/pm/markets/listings` no longer exists (410, sunset
1846
+ * 2026-07-20 with market matching). Use `pm("markets/search", { q })`.
1847
+ *
1848
+ * @throws {RetiredEndpointError} always. */
1849
+ async pmListings(_params) {
1850
+ throw new RetiredEndpointError(
1851
+ '/v1/pm/markets/listings was sunset by Predexon on 2026-07-20 (upstream 410). Use pm("markets/search", { q }) for cross-venue lookups.'
1852
+ );
1795
1853
  }
1796
- /** Resolve a canonical Predexon outcome ID to its market context and venue
1797
- * listings. Tier 1 ($0.001/call). */
1798
- async pmOutcome(predexonId) {
1799
- return this.pm(`outcomes/${predexonId}`);
1854
+ /** RETIRED — `/v1/pm/outcomes/{predexonId}` no longer exists (410, sunset
1855
+ * 2026-07-20 with market matching). Use `pm("markets/search", { q })`.
1856
+ *
1857
+ * @throws {RetiredEndpointError} always. */
1858
+ async pmOutcome(_predexonId) {
1859
+ throw new RetiredEndpointError(
1860
+ '/v1/pm/outcomes/{predexon_id} was sunset by Predexon on 2026-07-20 (upstream 410). Use pm("markets/search", { q }) for cross-venue lookups.'
1861
+ );
1800
1862
  }
1801
1863
  /** Polymarket markets with cursor-based keyset pagination (use pagination_key).
1802
1864
  * Tier 1 ($0.001/call). */
@@ -1808,12 +1870,18 @@ var LLMClient = class _LLMClient {
1808
1870
  async pmPolymarketEventsKeyset(params) {
1809
1871
  return this.pm("polymarket/events/keyset", params);
1810
1872
  }
1811
- /** List available sports categories. Tier 1 ($0.001/call). */
1873
+ /** List available sports categories. Tier 1 ($0.001/call).
1874
+ *
1875
+ * NOTE: upstream returns 500 for every `sports/*` path as of 2026-08-04.
1876
+ * The route still resolves, so this works again the moment Predexon restores
1877
+ * it, but do not build on it yet. */
1812
1878
  async pmSportsCategories() {
1813
1879
  return this.pm("sports/categories");
1814
1880
  }
1815
1881
  /** List sports markets grouped by game. Filter with league, sport_type,
1816
- * status, venue. Tier 1 ($0.001/call). */
1882
+ * status, venue. Tier 1 ($0.001/call).
1883
+ *
1884
+ * NOTE: upstream returns 500 for every `sports/*` path as of 2026-08-04. */
1817
1885
  async pmSportsMarkets(params) {
1818
1886
  return this.pm("sports/markets", params);
1819
1887
  }
@@ -4894,7 +4962,7 @@ var os3 = __toESM(require("os"), 1);
4894
4962
  var WALLET_DIR2 = path3.join(os3.homedir(), ".blockrun");
4895
4963
  var SOLANA_WALLET_FILE = path3.join(WALLET_DIR2, ".solana-session");
4896
4964
  async function createSolanaWallet() {
4897
- const { Keypair } = await import("@solana/web3.js");
4965
+ const { Keypair } = await loadSolanaWeb3("Solana wallet operations");
4898
4966
  const bs58 = await import("bs58");
4899
4967
  const keypair = Keypair.generate();
4900
4968
  return {
@@ -4903,20 +4971,55 @@ async function createSolanaWallet() {
4903
4971
  };
4904
4972
  }
4905
4973
  async function solanaKeyToBytes(privateKey) {
4974
+ const key = privateKey.trim();
4975
+ if (key.startsWith("[")) {
4976
+ let parsed;
4977
+ try {
4978
+ parsed = JSON.parse(key);
4979
+ } catch {
4980
+ throw new Error(
4981
+ "Invalid Solana private key: looks like a JSON byte array but is not valid JSON"
4982
+ );
4983
+ }
4984
+ if (!Array.isArray(parsed) || !parsed.every((n) => Number.isInteger(n) && n >= 0 && n <= 255)) {
4985
+ throw new Error(
4986
+ "Invalid Solana private key: JSON array must contain only byte values (0-255)"
4987
+ );
4988
+ }
4989
+ if (parsed.length !== 64) {
4990
+ throw new Error(
4991
+ `Invalid Solana key length: expected 64 bytes, got ${parsed.length}`
4992
+ );
4993
+ }
4994
+ return Uint8Array.from(parsed);
4995
+ }
4996
+ const hex = key.startsWith("0x") || key.startsWith("0X") ? key.slice(2) : key;
4997
+ if (/^[0-9a-fA-F]+$/.test(hex) && (hex.length === 64 || hex.length === 128)) {
4998
+ if (hex.length === 64) {
4999
+ throw new Error(
5000
+ "Invalid Solana private key: this is a 32-byte hex key \u2014 the EVM (Base) wallet format, not a Solana key. Solana keys are 64 bytes, usually base58-encoded (86-88 characters)."
5001
+ );
5002
+ }
5003
+ const bytes = new Uint8Array(64);
5004
+ for (let i = 0; i < 64; i++) bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
5005
+ return bytes;
5006
+ }
4906
5007
  try {
4907
5008
  const bs58 = await import("bs58");
4908
- const bytes = (bs58.default ?? bs58).decode(privateKey);
5009
+ const bytes = (bs58.default ?? bs58).decode(key);
4909
5010
  if (bytes.length !== 64) {
4910
5011
  throw new Error(`Invalid Solana key length: expected 64 bytes, got ${bytes.length}`);
4911
5012
  }
4912
5013
  return bytes;
4913
5014
  } catch (err) {
4914
5015
  const msg = err instanceof Error ? err.message : String(err);
4915
- throw new Error(`Invalid Solana private key: ${msg}`);
5016
+ throw new Error(
5017
+ `Invalid Solana private key: ${msg}. Expected a base58-encoded 64-byte key (standard Solana format), a 64-byte hex string, or a Solana CLI JSON byte array.`
5018
+ );
4916
5019
  }
4917
5020
  }
4918
5021
  async function solanaPublicKey(privateKey) {
4919
- const { Keypair } = await import("@solana/web3.js");
5022
+ const { Keypair } = await loadSolanaWeb3("Solana wallet operations");
4920
5023
  const bytes = await solanaKeyToBytes(privateKey);
4921
5024
  return Keypair.fromSecretKey(bytes).publicKey.toBase58();
4922
5025
  }
@@ -5052,16 +5155,27 @@ Your current wallet is backed up first. You can also set
5052
5155
  SOLANA_WALLET_KEY=<private-key> for a single run without changing anything.
5053
5156
  `;
5054
5157
  }
5158
+ async function solanaPublicKeyFrom(privateKey, source) {
5159
+ try {
5160
+ return await solanaPublicKey(privateKey);
5161
+ } catch (err) {
5162
+ const msg = err instanceof Error ? err.message : String(err);
5163
+ throw new Error(`${msg} (key loaded from ${source})`);
5164
+ }
5165
+ }
5055
5166
  async function getOrCreateSolanaWallet() {
5056
5167
  const envKey = typeof process !== "undefined" && process.env ? process.env.SOLANA_WALLET_KEY : void 0;
5057
5168
  if (envKey) {
5058
- const address2 = await solanaPublicKey(envKey);
5169
+ const address2 = await solanaPublicKeyFrom(
5170
+ envKey,
5171
+ "the SOLANA_WALLET_KEY environment variable"
5172
+ );
5059
5173
  return { privateKey: envKey, address: address2, isNew: false };
5060
5174
  }
5061
5175
  if (fs3.existsSync(SOLANA_WALLET_FILE)) {
5062
5176
  const fileKey = fs3.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
5063
5177
  if (fileKey) {
5064
- const address2 = await solanaPublicKey(fileKey);
5178
+ const address2 = await solanaPublicKeyFrom(fileKey, SOLANA_WALLET_FILE);
5065
5179
  return { privateKey: fileKey, address: address2, isNew: false };
5066
5180
  }
5067
5181
  }
@@ -6199,6 +6313,7 @@ var AnthropicClient = class {
6199
6313
  PortraitClient,
6200
6314
  PriceClient,
6201
6315
  RPC_PRICE_USD,
6316
+ RetiredEndpointError,
6202
6317
  RpcClient,
6203
6318
  SOLANA_NETWORK,
6204
6319
  SOLANA_WALLET_FILE_PATH,
package/dist/index.d.cts CHANGED
@@ -947,6 +947,16 @@ interface PollOptions {
947
947
  declare class BlockrunError extends Error {
948
948
  constructor(message: string);
949
949
  }
950
+ /**
951
+ * Thrown by a helper whose upstream endpoint no longer exists.
952
+ *
953
+ * Kept as a throwing method rather than deleted so upgrading does not break
954
+ * imports or property access — the failure is explicit and immediate instead of
955
+ * a round trip that returns 410/404.
956
+ */
957
+ declare class RetiredEndpointError extends BlockrunError {
958
+ constructor(message: string);
959
+ }
950
960
  declare class PaymentError extends BlockrunError {
951
961
  constructor(message: string);
952
962
  }
@@ -1284,25 +1294,43 @@ declare class LLMClient {
1284
1294
  * });
1285
1295
  */
1286
1296
  pmQuery(path: string, query: Record<string, unknown>): Promise<Record<string, unknown>>;
1287
- /** List canonical cross-venue markets (Predexon v2). Tier 1 ($0.001/call).
1288
- * Filter with venue, status, category, league, event_id, pagination_key. */
1289
- pmMarkets(params?: Record<string, string>): Promise<Record<string, unknown>>;
1290
- /** List venue-native executable listings flattened across canonical markets
1291
- * (Predexon v2). Tier 1 ($0.001/call). */
1292
- pmListings(params?: Record<string, string>): Promise<Record<string, unknown>>;
1293
- /** Resolve a canonical Predexon outcome ID to its market context and venue
1294
- * listings. Tier 1 ($0.001/call). */
1295
- pmOutcome(predexonId: string): Promise<Record<string, unknown>>;
1297
+ /** RETIRED — `/v1/pm/markets` no longer exists.
1298
+ *
1299
+ * Predexon sunset market matching on 2026-07-20 and the whole canonical layer
1300
+ * went with it, so this path returns 410 upstream. Use
1301
+ * `pm("markets/search", { q })` for cross-venue lookups.
1302
+ *
1303
+ * Kept as a throwing stub rather than deleted so upgrading does not break
1304
+ * property access; it throws before any network I/O.
1305
+ *
1306
+ * @throws {RetiredEndpointError} always. */
1307
+ pmMarkets(_params?: Record<string, string>): Promise<Record<string, unknown>>;
1308
+ /** RETIRED — `/v1/pm/markets/listings` no longer exists (410, sunset
1309
+ * 2026-07-20 with market matching). Use `pm("markets/search", { q })`.
1310
+ *
1311
+ * @throws {RetiredEndpointError} always. */
1312
+ pmListings(_params?: Record<string, string>): Promise<Record<string, unknown>>;
1313
+ /** RETIRED — `/v1/pm/outcomes/{predexonId}` no longer exists (410, sunset
1314
+ * 2026-07-20 with market matching). Use `pm("markets/search", { q })`.
1315
+ *
1316
+ * @throws {RetiredEndpointError} always. */
1317
+ pmOutcome(_predexonId: string): Promise<Record<string, unknown>>;
1296
1318
  /** Polymarket markets with cursor-based keyset pagination (use pagination_key).
1297
1319
  * Tier 1 ($0.001/call). */
1298
1320
  pmPolymarketMarketsKeyset(params?: Record<string, string>): Promise<Record<string, unknown>>;
1299
1321
  /** Polymarket events with cursor-based keyset pagination (use pagination_key).
1300
1322
  * Tier 1 ($0.001/call). */
1301
1323
  pmPolymarketEventsKeyset(params?: Record<string, string>): Promise<Record<string, unknown>>;
1302
- /** List available sports categories. Tier 1 ($0.001/call). */
1324
+ /** List available sports categories. Tier 1 ($0.001/call).
1325
+ *
1326
+ * NOTE: upstream returns 500 for every `sports/*` path as of 2026-08-04.
1327
+ * The route still resolves, so this works again the moment Predexon restores
1328
+ * it, but do not build on it yet. */
1303
1329
  pmSportsCategories(): Promise<Record<string, unknown>>;
1304
1330
  /** List sports markets grouped by game. Filter with league, sport_type,
1305
- * status, venue. Tier 1 ($0.001/call). */
1331
+ * status, venue. Tier 1 ($0.001/call).
1332
+ *
1333
+ * NOTE: upstream returns 500 for every `sports/*` path as of 2026-08-04. */
1306
1334
  pmSportsMarkets(params?: Record<string, string>): Promise<Record<string, unknown>>;
1307
1335
  /** Fetch identity + profile metadata for one wallet (ENS, Twitter, portfolio,
1308
1336
  * etc.). Tier 2 ($0.005/call). */
@@ -2860,8 +2888,11 @@ declare function createSolanaWallet(): Promise<{
2860
2888
  privateKey: string;
2861
2889
  }>;
2862
2890
  /**
2863
- * Convert a bs58 private key string to Uint8Array (64 bytes).
2864
- * Accepts: bs58-encoded 64-byte key (standard Solana format).
2891
+ * Convert a Solana private key string to Uint8Array (64 bytes).
2892
+ * Accepts: bs58-encoded 64-byte key (standard Solana format), the Solana CLI
2893
+ * JSON byte-array format (~/.config/solana/id.json), or a 64-byte hex string
2894
+ * (with or without 0x). A 32-byte hex key is rejected with an explicit hint
2895
+ * that it is the EVM (Base) wallet format, not a Solana key.
2865
2896
  */
2866
2897
  declare function solanaKeyToBytes(privateKey: string): Promise<Uint8Array>;
2867
2898
  /**
@@ -3207,4 +3238,4 @@ declare function validateTemperature(temperature?: number): void;
3207
3238
  */
3208
3239
  declare function validateTopP(topP?: number): void;
3209
3240
 
3210
- export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, BlockrunClient, type BlockrunClientOptions, BlockrunError, type CallInitiatedResponse, type CallModel, type CallOptions, type CallStatusResponse, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatResponseWithCost, type ChatUsage, type CostEntry, type CostEstimate, type CreatePaymentOptions, type FunctionCall, type FunctionDefinition, type HistoryOptions, ImageClient, type ImageClientOptions, type ImageData, type ImageEditOptions, type ImageGenerateOptions, type ImageModel, type ImageResponse, KNOWN_PROVIDERS, LLMClient, type LLMClientOptions, type ListOptions, type MarketSession, type Model, MusicClient, type MusicClientOptions, type MusicGenerateOptions, type MusicResponse, NETWORK_ALIASES, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PORTRAIT_ENROLLMENT_PRICE_USD, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, PortraitClient, type PortraitClientOptions, type PortraitEnrollOptions, type PortraitEnrollResponse, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, RPC_PRICE_USD, type ResponseFormat, type RoutingDecision, type RoutingProfile, type RoutingTier, type RpcBatchRequest, RpcClient, type RpcClientOptions, type RpcError, type RpcNetwork, type RpcResponse, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SUPPORTED_NETWORKS, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type SoundEffectOptions, type SpeechAudio, SpeechClient, type SpeechClientOptions, type SpeechGenerateOptions, type SpeechModel, type SpeechResponse, type SpeechVoice, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoiceInfo, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatSolanaWalletMigrationNotice, formatWalletCreatedMessage, formatWalletMigrationNotice, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, importSolanaWallet, importWallet, listDiscoveredSolanaWallets, listDiscoveredWallets, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, validateMaxTokens, validateModel, validateTemperature, validateTopP };
3241
+ export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, BlockrunClient, type BlockrunClientOptions, BlockrunError, type CallInitiatedResponse, type CallModel, type CallOptions, type CallStatusResponse, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatResponseWithCost, type ChatUsage, type CostEntry, type CostEstimate, type CreatePaymentOptions, type FunctionCall, type FunctionDefinition, type HistoryOptions, ImageClient, type ImageClientOptions, type ImageData, type ImageEditOptions, type ImageGenerateOptions, type ImageModel, type ImageResponse, KNOWN_PROVIDERS, LLMClient, type LLMClientOptions, type ListOptions, type MarketSession, type Model, MusicClient, type MusicClientOptions, type MusicGenerateOptions, type MusicResponse, NETWORK_ALIASES, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PORTRAIT_ENROLLMENT_PRICE_USD, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, PortraitClient, type PortraitClientOptions, type PortraitEnrollOptions, type PortraitEnrollResponse, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, RPC_PRICE_USD, type ResponseFormat, RetiredEndpointError, type RoutingDecision, type RoutingProfile, type RoutingTier, type RpcBatchRequest, RpcClient, type RpcClientOptions, type RpcError, type RpcNetwork, type RpcResponse, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SUPPORTED_NETWORKS, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type SoundEffectOptions, type SpeechAudio, SpeechClient, type SpeechClientOptions, type SpeechGenerateOptions, type SpeechModel, type SpeechResponse, type SpeechVoice, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoiceInfo, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatSolanaWalletMigrationNotice, formatWalletCreatedMessage, formatWalletMigrationNotice, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, importSolanaWallet, importWallet, listDiscoveredSolanaWallets, listDiscoveredWallets, 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
@@ -947,6 +947,16 @@ interface PollOptions {
947
947
  declare class BlockrunError extends Error {
948
948
  constructor(message: string);
949
949
  }
950
+ /**
951
+ * Thrown by a helper whose upstream endpoint no longer exists.
952
+ *
953
+ * Kept as a throwing method rather than deleted so upgrading does not break
954
+ * imports or property access — the failure is explicit and immediate instead of
955
+ * a round trip that returns 410/404.
956
+ */
957
+ declare class RetiredEndpointError extends BlockrunError {
958
+ constructor(message: string);
959
+ }
950
960
  declare class PaymentError extends BlockrunError {
951
961
  constructor(message: string);
952
962
  }
@@ -1284,25 +1294,43 @@ declare class LLMClient {
1284
1294
  * });
1285
1295
  */
1286
1296
  pmQuery(path: string, query: Record<string, unknown>): Promise<Record<string, unknown>>;
1287
- /** List canonical cross-venue markets (Predexon v2). Tier 1 ($0.001/call).
1288
- * Filter with venue, status, category, league, event_id, pagination_key. */
1289
- pmMarkets(params?: Record<string, string>): Promise<Record<string, unknown>>;
1290
- /** List venue-native executable listings flattened across canonical markets
1291
- * (Predexon v2). Tier 1 ($0.001/call). */
1292
- pmListings(params?: Record<string, string>): Promise<Record<string, unknown>>;
1293
- /** Resolve a canonical Predexon outcome ID to its market context and venue
1294
- * listings. Tier 1 ($0.001/call). */
1295
- pmOutcome(predexonId: string): Promise<Record<string, unknown>>;
1297
+ /** RETIRED — `/v1/pm/markets` no longer exists.
1298
+ *
1299
+ * Predexon sunset market matching on 2026-07-20 and the whole canonical layer
1300
+ * went with it, so this path returns 410 upstream. Use
1301
+ * `pm("markets/search", { q })` for cross-venue lookups.
1302
+ *
1303
+ * Kept as a throwing stub rather than deleted so upgrading does not break
1304
+ * property access; it throws before any network I/O.
1305
+ *
1306
+ * @throws {RetiredEndpointError} always. */
1307
+ pmMarkets(_params?: Record<string, string>): Promise<Record<string, unknown>>;
1308
+ /** RETIRED — `/v1/pm/markets/listings` no longer exists (410, sunset
1309
+ * 2026-07-20 with market matching). Use `pm("markets/search", { q })`.
1310
+ *
1311
+ * @throws {RetiredEndpointError} always. */
1312
+ pmListings(_params?: Record<string, string>): Promise<Record<string, unknown>>;
1313
+ /** RETIRED — `/v1/pm/outcomes/{predexonId}` no longer exists (410, sunset
1314
+ * 2026-07-20 with market matching). Use `pm("markets/search", { q })`.
1315
+ *
1316
+ * @throws {RetiredEndpointError} always. */
1317
+ pmOutcome(_predexonId: string): Promise<Record<string, unknown>>;
1296
1318
  /** Polymarket markets with cursor-based keyset pagination (use pagination_key).
1297
1319
  * Tier 1 ($0.001/call). */
1298
1320
  pmPolymarketMarketsKeyset(params?: Record<string, string>): Promise<Record<string, unknown>>;
1299
1321
  /** Polymarket events with cursor-based keyset pagination (use pagination_key).
1300
1322
  * Tier 1 ($0.001/call). */
1301
1323
  pmPolymarketEventsKeyset(params?: Record<string, string>): Promise<Record<string, unknown>>;
1302
- /** List available sports categories. Tier 1 ($0.001/call). */
1324
+ /** List available sports categories. Tier 1 ($0.001/call).
1325
+ *
1326
+ * NOTE: upstream returns 500 for every `sports/*` path as of 2026-08-04.
1327
+ * The route still resolves, so this works again the moment Predexon restores
1328
+ * it, but do not build on it yet. */
1303
1329
  pmSportsCategories(): Promise<Record<string, unknown>>;
1304
1330
  /** List sports markets grouped by game. Filter with league, sport_type,
1305
- * status, venue. Tier 1 ($0.001/call). */
1331
+ * status, venue. Tier 1 ($0.001/call).
1332
+ *
1333
+ * NOTE: upstream returns 500 for every `sports/*` path as of 2026-08-04. */
1306
1334
  pmSportsMarkets(params?: Record<string, string>): Promise<Record<string, unknown>>;
1307
1335
  /** Fetch identity + profile metadata for one wallet (ENS, Twitter, portfolio,
1308
1336
  * etc.). Tier 2 ($0.005/call). */
@@ -2860,8 +2888,11 @@ declare function createSolanaWallet(): Promise<{
2860
2888
  privateKey: string;
2861
2889
  }>;
2862
2890
  /**
2863
- * Convert a bs58 private key string to Uint8Array (64 bytes).
2864
- * Accepts: bs58-encoded 64-byte key (standard Solana format).
2891
+ * Convert a Solana private key string to Uint8Array (64 bytes).
2892
+ * Accepts: bs58-encoded 64-byte key (standard Solana format), the Solana CLI
2893
+ * JSON byte-array format (~/.config/solana/id.json), or a 64-byte hex string
2894
+ * (with or without 0x). A 32-byte hex key is rejected with an explicit hint
2895
+ * that it is the EVM (Base) wallet format, not a Solana key.
2865
2896
  */
2866
2897
  declare function solanaKeyToBytes(privateKey: string): Promise<Uint8Array>;
2867
2898
  /**
@@ -3207,4 +3238,4 @@ declare function validateTemperature(temperature?: number): void;
3207
3238
  */
3208
3239
  declare function validateTopP(topP?: number): void;
3209
3240
 
3210
- export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, BlockrunClient, type BlockrunClientOptions, BlockrunError, type CallInitiatedResponse, type CallModel, type CallOptions, type CallStatusResponse, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatResponseWithCost, type ChatUsage, type CostEntry, type CostEstimate, type CreatePaymentOptions, type FunctionCall, type FunctionDefinition, type HistoryOptions, ImageClient, type ImageClientOptions, type ImageData, type ImageEditOptions, type ImageGenerateOptions, type ImageModel, type ImageResponse, KNOWN_PROVIDERS, LLMClient, type LLMClientOptions, type ListOptions, type MarketSession, type Model, MusicClient, type MusicClientOptions, type MusicGenerateOptions, type MusicResponse, NETWORK_ALIASES, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PORTRAIT_ENROLLMENT_PRICE_USD, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, PortraitClient, type PortraitClientOptions, type PortraitEnrollOptions, type PortraitEnrollResponse, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, RPC_PRICE_USD, type ResponseFormat, type RoutingDecision, type RoutingProfile, type RoutingTier, type RpcBatchRequest, RpcClient, type RpcClientOptions, type RpcError, type RpcNetwork, type RpcResponse, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SUPPORTED_NETWORKS, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type SoundEffectOptions, type SpeechAudio, SpeechClient, type SpeechClientOptions, type SpeechGenerateOptions, type SpeechModel, type SpeechResponse, type SpeechVoice, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoiceInfo, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatSolanaWalletMigrationNotice, formatWalletCreatedMessage, formatWalletMigrationNotice, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, importSolanaWallet, importWallet, listDiscoveredSolanaWallets, listDiscoveredWallets, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, validateMaxTokens, validateModel, validateTemperature, validateTopP };
3241
+ export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, BlockrunClient, type BlockrunClientOptions, BlockrunError, type CallInitiatedResponse, type CallModel, type CallOptions, type CallStatusResponse, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatResponseWithCost, type ChatUsage, type CostEntry, type CostEstimate, type CreatePaymentOptions, type FunctionCall, type FunctionDefinition, type HistoryOptions, ImageClient, type ImageClientOptions, type ImageData, type ImageEditOptions, type ImageGenerateOptions, type ImageModel, type ImageResponse, KNOWN_PROVIDERS, LLMClient, type LLMClientOptions, type ListOptions, type MarketSession, type Model, MusicClient, type MusicClientOptions, type MusicGenerateOptions, type MusicResponse, NETWORK_ALIASES, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PORTRAIT_ENROLLMENT_PRICE_USD, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, PortraitClient, type PortraitClientOptions, type PortraitEnrollOptions, type PortraitEnrollResponse, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, RPC_PRICE_USD, type ResponseFormat, RetiredEndpointError, type RoutingDecision, type RoutingProfile, type RoutingTier, type RpcBatchRequest, RpcClient, type RpcClientOptions, type RpcError, type RpcNetwork, type RpcResponse, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SUPPORTED_NETWORKS, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type SoundEffectOptions, type SpeechAudio, SpeechClient, type SpeechClientOptions, type SpeechGenerateOptions, type SpeechModel, type SpeechResponse, type SpeechVoice, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoiceInfo, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatSolanaWalletMigrationNotice, formatWalletCreatedMessage, formatWalletMigrationNotice, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, importSolanaWallet, importWallet, listDiscoveredSolanaWallets, listDiscoveredWallets, 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
@@ -8,6 +8,12 @@ var BlockrunError = class extends Error {
8
8
  this.name = "BlockrunError";
9
9
  }
10
10
  };
11
+ var RetiredEndpointError = class extends BlockrunError {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = "RetiredEndpointError";
15
+ }
16
+ };
11
17
  var PaymentError = class extends BlockrunError {
12
18
  constructor(message) {
13
19
  super(message);
@@ -27,6 +33,35 @@ var APIError = class extends BlockrunError {
27
33
 
28
34
  // src/x402.ts
29
35
  import { signTypedData } from "viem/accounts";
36
+
37
+ // src/solana-deps.ts
38
+ var INSTALL_HINT = "npm install @solana/web3.js @solana/spl-token (or pnpm add / yarn add)";
39
+ function missing(pkg, what, cause) {
40
+ return new Error(
41
+ `@blockrun/llm: ${what} requires the optional peer dependency "${pkg}", which is not installed.
42
+
43
+ ${INSTALL_HINT}
44
+
45
+ Solana packages are optional peers so that consumers who only use Base/EVM payments do not inherit them. If you only make Base payments, you should not be reaching this code path \u2014 check which chain you passed.
46
+ Original error: ${cause instanceof Error ? cause.message : String(cause)}`
47
+ );
48
+ }
49
+ async function loadSolanaWeb3(what) {
50
+ try {
51
+ return await import("@solana/web3.js");
52
+ } catch (err) {
53
+ throw missing("@solana/web3.js", what, err);
54
+ }
55
+ }
56
+ async function loadSplToken(what) {
57
+ try {
58
+ return await import("@solana/spl-token");
59
+ } catch (err) {
60
+ throw missing("@solana/spl-token", what, err);
61
+ }
62
+ }
63
+
64
+ // src/x402.ts
30
65
  var BASE_CHAIN_ID = 8453;
31
66
  var USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
32
67
  var SOLANA_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
@@ -155,9 +190,17 @@ async function createPaymentPayload(privateKey, fromAddress, recipient, amount,
155
190
  return btoa(JSON.stringify(paymentData));
156
191
  }
157
192
  async function createSolanaPaymentPayload(secretKey, fromAddress, recipient, amount, feePayer, options = {}) {
158
- const { Connection, PublicKey, TransactionMessage, VersionedTransaction, ComputeBudgetProgram } = await import("@solana/web3.js");
159
- const { getAssociatedTokenAddress, createTransferCheckedInstruction } = await import("@solana/spl-token");
160
- const { Keypair } = await import("@solana/web3.js");
193
+ const {
194
+ Connection,
195
+ PublicKey,
196
+ TransactionMessage,
197
+ VersionedTransaction,
198
+ ComputeBudgetProgram,
199
+ Keypair
200
+ } = await loadSolanaWeb3("createSolanaPaymentPayload()");
201
+ const { getAssociatedTokenAddress, createTransferCheckedInstruction } = await loadSplToken(
202
+ "createSolanaPaymentPayload()"
203
+ );
161
204
  const rpcUrl = options.rpcUrl || "https://sol.blockrun.ai/api/v1/solana/rpc";
162
205
  const connection = options.rpcHeaders ? new Connection(rpcUrl, { httpHeaders: options.rpcHeaders }) : new Connection(rpcUrl);
163
206
  const keypair = Keypair.fromSecretKey(secretKey);
@@ -451,7 +494,7 @@ function getCostSummary() {
451
494
  }
452
495
 
453
496
  // src/version.ts
454
- var SDK_VERSION = "3.8.4";
497
+ var SDK_VERSION = "3.10.0";
455
498
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
456
499
 
457
500
  // src/client.ts
@@ -1670,20 +1713,38 @@ var LLMClient = class _LLMClient {
1670
1713
  }
1671
1714
  // ── PM convenience helpers (Predexon v2) ─────────────────────────────────
1672
1715
  // Thin wrappers over pm() / pmQuery() for the most common v2 endpoints.
1673
- /** List canonical cross-venue markets (Predexon v2). Tier 1 ($0.001/call).
1674
- * Filter with venue, status, category, league, event_id, pagination_key. */
1675
- async pmMarkets(params) {
1676
- return this.pm("markets", params);
1716
+ /** RETIRED — `/v1/pm/markets` no longer exists.
1717
+ *
1718
+ * Predexon sunset market matching on 2026-07-20 and the whole canonical layer
1719
+ * went with it, so this path returns 410 upstream. Use
1720
+ * `pm("markets/search", { q })` for cross-venue lookups.
1721
+ *
1722
+ * Kept as a throwing stub rather than deleted so upgrading does not break
1723
+ * property access; it throws before any network I/O.
1724
+ *
1725
+ * @throws {RetiredEndpointError} always. */
1726
+ async pmMarkets(_params) {
1727
+ throw new RetiredEndpointError(
1728
+ '/v1/pm/markets was sunset by Predexon on 2026-07-20 (upstream 410). Use pm("markets/search", { q }) for cross-venue lookups.'
1729
+ );
1677
1730
  }
1678
- /** List venue-native executable listings flattened across canonical markets
1679
- * (Predexon v2). Tier 1 ($0.001/call). */
1680
- async pmListings(params) {
1681
- return this.pm("markets/listings", params);
1731
+ /** RETIRED — `/v1/pm/markets/listings` no longer exists (410, sunset
1732
+ * 2026-07-20 with market matching). Use `pm("markets/search", { q })`.
1733
+ *
1734
+ * @throws {RetiredEndpointError} always. */
1735
+ async pmListings(_params) {
1736
+ throw new RetiredEndpointError(
1737
+ '/v1/pm/markets/listings was sunset by Predexon on 2026-07-20 (upstream 410). Use pm("markets/search", { q }) for cross-venue lookups.'
1738
+ );
1682
1739
  }
1683
- /** Resolve a canonical Predexon outcome ID to its market context and venue
1684
- * listings. Tier 1 ($0.001/call). */
1685
- async pmOutcome(predexonId) {
1686
- return this.pm(`outcomes/${predexonId}`);
1740
+ /** RETIRED — `/v1/pm/outcomes/{predexonId}` no longer exists (410, sunset
1741
+ * 2026-07-20 with market matching). Use `pm("markets/search", { q })`.
1742
+ *
1743
+ * @throws {RetiredEndpointError} always. */
1744
+ async pmOutcome(_predexonId) {
1745
+ throw new RetiredEndpointError(
1746
+ '/v1/pm/outcomes/{predexon_id} was sunset by Predexon on 2026-07-20 (upstream 410). Use pm("markets/search", { q }) for cross-venue lookups.'
1747
+ );
1687
1748
  }
1688
1749
  /** Polymarket markets with cursor-based keyset pagination (use pagination_key).
1689
1750
  * Tier 1 ($0.001/call). */
@@ -1695,12 +1756,18 @@ var LLMClient = class _LLMClient {
1695
1756
  async pmPolymarketEventsKeyset(params) {
1696
1757
  return this.pm("polymarket/events/keyset", params);
1697
1758
  }
1698
- /** List available sports categories. Tier 1 ($0.001/call). */
1759
+ /** List available sports categories. Tier 1 ($0.001/call).
1760
+ *
1761
+ * NOTE: upstream returns 500 for every `sports/*` path as of 2026-08-04.
1762
+ * The route still resolves, so this works again the moment Predexon restores
1763
+ * it, but do not build on it yet. */
1699
1764
  async pmSportsCategories() {
1700
1765
  return this.pm("sports/categories");
1701
1766
  }
1702
1767
  /** List sports markets grouped by game. Filter with league, sport_type,
1703
- * status, venue. Tier 1 ($0.001/call). */
1768
+ * status, venue. Tier 1 ($0.001/call).
1769
+ *
1770
+ * NOTE: upstream returns 500 for every `sports/*` path as of 2026-08-04. */
1704
1771
  async pmSportsMarkets(params) {
1705
1772
  return this.pm("sports/markets", params);
1706
1773
  }
@@ -4781,7 +4848,7 @@ import * as os3 from "os";
4781
4848
  var WALLET_DIR2 = path3.join(os3.homedir(), ".blockrun");
4782
4849
  var SOLANA_WALLET_FILE = path3.join(WALLET_DIR2, ".solana-session");
4783
4850
  async function createSolanaWallet() {
4784
- const { Keypair } = await import("@solana/web3.js");
4851
+ const { Keypair } = await loadSolanaWeb3("Solana wallet operations");
4785
4852
  const bs58 = await import("bs58");
4786
4853
  const keypair = Keypair.generate();
4787
4854
  return {
@@ -4790,20 +4857,55 @@ async function createSolanaWallet() {
4790
4857
  };
4791
4858
  }
4792
4859
  async function solanaKeyToBytes(privateKey) {
4860
+ const key = privateKey.trim();
4861
+ if (key.startsWith("[")) {
4862
+ let parsed;
4863
+ try {
4864
+ parsed = JSON.parse(key);
4865
+ } catch {
4866
+ throw new Error(
4867
+ "Invalid Solana private key: looks like a JSON byte array but is not valid JSON"
4868
+ );
4869
+ }
4870
+ if (!Array.isArray(parsed) || !parsed.every((n) => Number.isInteger(n) && n >= 0 && n <= 255)) {
4871
+ throw new Error(
4872
+ "Invalid Solana private key: JSON array must contain only byte values (0-255)"
4873
+ );
4874
+ }
4875
+ if (parsed.length !== 64) {
4876
+ throw new Error(
4877
+ `Invalid Solana key length: expected 64 bytes, got ${parsed.length}`
4878
+ );
4879
+ }
4880
+ return Uint8Array.from(parsed);
4881
+ }
4882
+ const hex = key.startsWith("0x") || key.startsWith("0X") ? key.slice(2) : key;
4883
+ if (/^[0-9a-fA-F]+$/.test(hex) && (hex.length === 64 || hex.length === 128)) {
4884
+ if (hex.length === 64) {
4885
+ throw new Error(
4886
+ "Invalid Solana private key: this is a 32-byte hex key \u2014 the EVM (Base) wallet format, not a Solana key. Solana keys are 64 bytes, usually base58-encoded (86-88 characters)."
4887
+ );
4888
+ }
4889
+ const bytes = new Uint8Array(64);
4890
+ for (let i = 0; i < 64; i++) bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
4891
+ return bytes;
4892
+ }
4793
4893
  try {
4794
4894
  const bs58 = await import("bs58");
4795
- const bytes = (bs58.default ?? bs58).decode(privateKey);
4895
+ const bytes = (bs58.default ?? bs58).decode(key);
4796
4896
  if (bytes.length !== 64) {
4797
4897
  throw new Error(`Invalid Solana key length: expected 64 bytes, got ${bytes.length}`);
4798
4898
  }
4799
4899
  return bytes;
4800
4900
  } catch (err) {
4801
4901
  const msg = err instanceof Error ? err.message : String(err);
4802
- throw new Error(`Invalid Solana private key: ${msg}`);
4902
+ throw new Error(
4903
+ `Invalid Solana private key: ${msg}. Expected a base58-encoded 64-byte key (standard Solana format), a 64-byte hex string, or a Solana CLI JSON byte array.`
4904
+ );
4803
4905
  }
4804
4906
  }
4805
4907
  async function solanaPublicKey(privateKey) {
4806
- const { Keypair } = await import("@solana/web3.js");
4908
+ const { Keypair } = await loadSolanaWeb3("Solana wallet operations");
4807
4909
  const bytes = await solanaKeyToBytes(privateKey);
4808
4910
  return Keypair.fromSecretKey(bytes).publicKey.toBase58();
4809
4911
  }
@@ -4939,16 +5041,27 @@ Your current wallet is backed up first. You can also set
4939
5041
  SOLANA_WALLET_KEY=<private-key> for a single run without changing anything.
4940
5042
  `;
4941
5043
  }
5044
+ async function solanaPublicKeyFrom(privateKey, source) {
5045
+ try {
5046
+ return await solanaPublicKey(privateKey);
5047
+ } catch (err) {
5048
+ const msg = err instanceof Error ? err.message : String(err);
5049
+ throw new Error(`${msg} (key loaded from ${source})`);
5050
+ }
5051
+ }
4942
5052
  async function getOrCreateSolanaWallet() {
4943
5053
  const envKey = typeof process !== "undefined" && process.env ? process.env.SOLANA_WALLET_KEY : void 0;
4944
5054
  if (envKey) {
4945
- const address2 = await solanaPublicKey(envKey);
5055
+ const address2 = await solanaPublicKeyFrom(
5056
+ envKey,
5057
+ "the SOLANA_WALLET_KEY environment variable"
5058
+ );
4946
5059
  return { privateKey: envKey, address: address2, isNew: false };
4947
5060
  }
4948
5061
  if (fs3.existsSync(SOLANA_WALLET_FILE)) {
4949
5062
  const fileKey = fs3.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
4950
5063
  if (fileKey) {
4951
- const address2 = await solanaPublicKey(fileKey);
5064
+ const address2 = await solanaPublicKeyFrom(fileKey, SOLANA_WALLET_FILE);
4952
5065
  return { privateKey: fileKey, address: address2, isNew: false };
4953
5066
  }
4954
5067
  }
@@ -6085,6 +6198,7 @@ export {
6085
6198
  PortraitClient,
6086
6199
  PriceClient,
6087
6200
  RPC_PRICE_USD,
6201
+ RetiredEndpointError,
6088
6202
  RpcClient,
6089
6203
  SOLANA_NETWORK,
6090
6204
  SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "3.8.4",
3
+ "version": "3.10.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",
@@ -52,9 +52,7 @@
52
52
  "viem": "^2.49.0"
53
53
  },
54
54
  "optionalDependencies": {
55
- "@anthropic-ai/sdk": "^0.39.0",
56
- "@solana/spl-token": "^0.4.14",
57
- "@solana/web3.js": "^1.98.4"
55
+ "@anthropic-ai/sdk": "^0.39.0"
58
56
  },
59
57
  "devDependencies": {
60
58
  "@eslint/js": "^9.39.4",
@@ -77,11 +75,19 @@
77
75
  },
78
76
  "packageManager": "pnpm@9.15.4",
79
77
  "peerDependencies": {
80
- "@blockrun/clawrouter": "^0.12.222"
78
+ "@blockrun/clawrouter": "^0.12.222",
79
+ "@solana/spl-token": "^0.4.14",
80
+ "@solana/web3.js": "^1.98.4"
81
81
  },
82
82
  "peerDependenciesMeta": {
83
83
  "@blockrun/clawrouter": {
84
84
  "optional": true
85
+ },
86
+ "@solana/spl-token": {
87
+ "optional": true
88
+ },
89
+ "@solana/web3.js": {
90
+ "optional": true
85
91
  }
86
92
  }
87
93
  }