@blockrun/llm 3.8.3 → 3.8.4

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 41+ 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 -->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.
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
 
@@ -232,7 +232,7 @@ const client = new LLMClient();
232
232
  const result = await client.smartChat('What is 2+2?');
233
233
  console.log(result.response); // '4'
234
234
  console.log(result.model); // 'moonshot/kimi-k2.5' (cheap, fast)
235
- console.log(`Saved ${(result.routing.savings * 100).toFixed(0)}%`); // 'Saved 78%'
235
+ console.log(`Saved ${(result.routing.savings * 100).toFixed(0)}%`); // 'Saved 87%'
236
236
 
237
237
  // Complex reasoning task -> routes to reasoning model
238
238
  const complex = await client.smartChat('Prove the Riemann hypothesis step by step');
@@ -263,7 +263,7 @@ const reply = await client.chat('nvidia/deepseek-v4-flash', 'hello', {
263
263
 
264
264
  | Profile | Description | Best For |
265
265
  |---------|-------------|----------|
266
- | `free` | NVIDIA free tier — smart-routes across 8 models (DeepSeek V4 Flash, Nemotron Nano Omni, Qwen3, Llama 4, Mistral, plus 2 hidden gpt-oss) | Zero-cost testing, dev, prod |
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 |
267
267
  | `eco` | Cheapest models per tier (DeepSeek, xAI) | Cost-sensitive production |
268
268
  | `auto` | Best balance of cost/quality (default) | General use |
269
269
  | `premium` | Top-tier models (OpenAI, Anthropic) | Quality-critical tasks |
@@ -748,7 +748,7 @@ Generic escape hatches: `client.defi(path, params)`, `client.dex(path, params, b
748
748
  ### Multi-chain RPC
749
749
 
750
750
  `RpcClient` wraps `POST /v1/rpc/{network}` — standard JSON-RPC 2.0 access to
751
- 40+ chains through one endpoint (Ethereum, Base, Solana, Polygon, BSC,
751
+ <!-- br:chains.rpc -->40<!-- /br:chains.rpc --> chains through one endpoint (Ethereum, Base, Solana, Polygon, BSC,
752
752
  Arbitrum, Optimism, Avalanche, Bitcoin, Sui, and more; powered by Tatum's RPC
753
753
  gateway). No API key, no per-chain endpoints: flat **$0.002 per call** in
754
754
  USDC; a JSON-RPC batch charges per element.
@@ -858,7 +858,7 @@ const response2 = await client.chat('anthropic/claude-sonnet-4', 'Write a haiku'
858
858
 
859
859
  ### Smart Routing (ClawRouter)
860
860
 
861
- Save up to 78% on inference costs with intelligent model routing. ClawRouter uses a 14-dimension rule-based scoring algorithm to select the cheapest model that can handle your request (<1ms, 100% local).
861
+ Save up to <!-- br:savings.autoVsBaselinePct -->87<!-- /br:savings.autoVsBaselinePct -->% on inference costs with intelligent model routing. ClawRouter uses a <!-- br:clawrouter.dimensions -->15<!-- /br:clawrouter.dimensions -->-dimension rule-based scoring algorithm to select the cheapest model that can handle your request (<1ms, 100% local).
862
862
 
863
863
  ```typescript
864
864
  import { LLMClient } from '@blockrun/llm';
@@ -870,7 +870,7 @@ const result = await client.smartChat('What is 2+2?');
870
870
  console.log(result.response); // '4'
871
871
  console.log(result.model); // 'google/gemini-2.5-flash'
872
872
  console.log(result.routing.tier); // 'SIMPLE'
873
- console.log(`Saved ${(result.routing.savings * 100).toFixed(0)}%`); // 'Saved 78%'
873
+ console.log(`Saved ${(result.routing.savings * 100).toFixed(0)}%`); // 'Saved 87%'
874
874
 
875
875
  // Routing profiles
876
876
  const free = await client.smartChat('Hello!', { routingProfile: 'free' }); // Zero cost
@@ -883,7 +883,7 @@ const premium = await client.smartChat('Write a legal brief', { routingProfile:
883
883
 
884
884
  | Profile | Description | Best For |
885
885
  |---------|-------------|----------|
886
- | `free` | NVIDIA free tier (9 models, smart-routed) | Zero-cost testing, dev, prod |
886
+ | `free` | NVIDIA free tier (<!-- br:models.free -->8<!-- /br:models.free --> models, smart-routed) | Zero-cost testing, dev, prod |
887
887
  | `eco` | Budget-optimized | Cost-sensitive workloads |
888
888
  | `auto` | Intelligent routing (default) | General use |
889
889
  | `premium` | Best quality models | Critical tasks |
@@ -1427,7 +1427,7 @@ The `AnthropicClient` wraps the official `@anthropic-ai/sdk` with a custom fetch
1427
1427
  When you make an API call, the SDK automatically handles x402 payment. It signs a USDC transaction locally using your wallet private key (which never leaves your machine), and includes the payment proof in the request header. Settlement is non-custodial and instant on Base or Solana.
1428
1428
 
1429
1429
  ### What is smart routing / ClawRouter?
1430
- ClawRouter is a built-in smart routing engine that analyzes your request across 14 dimensions and automatically picks the cheapest model capable of handling it. Routing happens locally in under 1ms. It can save up to 78% on LLM costs compared to using premium models for every request.
1430
+ ClawRouter is a built-in smart routing engine that analyzes your request across <!-- br:clawrouter.dimensions -->15<!-- /br:clawrouter.dimensions --> dimensions and automatically picks the cheapest model capable of handling it. Routing happens locally in under 1ms. It can save up to <!-- br:savings.autoVsBaselinePct -->87<!-- /br:savings.autoVsBaselinePct -->% on LLM costs compared to using premium models for every request.
1431
1431
 
1432
1432
  ### Does it support streaming?
1433
1433
  Yes — as of v1.6.1. Use `client.chatCompletionStream()` for native streaming or `stream: true` in the OpenAI-compatible client. Payment is handled automatically: the SDK signs USDC payment before streaming begins, and caches payment requirements per model so subsequent calls skip the 402 round-trip (~200ms faster).
package/dist/index.cjs CHANGED
@@ -144,8 +144,47 @@ var BASE_CHAIN_ID = 8453;
144
144
  var USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
145
145
  var SOLANA_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
146
146
  var USDC_SOLANA = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
147
+ var SOLANA_USDC_DECIMALS = 6;
147
148
  var DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;
148
149
  var DEFAULT_COMPUTE_UNIT_LIMIT = 8e3;
150
+ var BLOCKHASH_TTL_MS = 1e4;
151
+ var MAX_FEE_NONCE_STEPS = 64;
152
+ var MAX_TRACKED_BLOCKHASHES = 8;
153
+ var MAX_TRACKED_ENDPOINTS = 8;
154
+ var blockhashCache = /* @__PURE__ */ new Map();
155
+ function trimOldest(map, limit) {
156
+ while (map.size > limit) {
157
+ const oldest = map.keys().next().value;
158
+ map.delete(oldest);
159
+ }
160
+ }
161
+ var issuedByBlockhash = /* @__PURE__ */ new Map();
162
+ function issuedFor(blockhash) {
163
+ let issued = issuedByBlockhash.get(blockhash);
164
+ if (!issued) {
165
+ issued = /* @__PURE__ */ new Set();
166
+ issuedByBlockhash.set(blockhash, issued);
167
+ trimOldest(issuedByBlockhash, MAX_TRACKED_BLOCKHASHES);
168
+ }
169
+ return issued;
170
+ }
171
+ async function getBlockhashEntry(connection, rpcUrl, forceRefresh) {
172
+ const now = Date.now();
173
+ const cached = blockhashCache.get(rpcUrl);
174
+ if (!forceRefresh && cached && now - cached.fetchedAt < BLOCKHASH_TTL_MS) {
175
+ return cached;
176
+ }
177
+ const { blockhash } = await connection.getLatestBlockhash();
178
+ const current = blockhashCache.get(rpcUrl);
179
+ if (current?.blockhash === blockhash) {
180
+ current.fetchedAt = now;
181
+ return current;
182
+ }
183
+ const entry = { blockhash, fetchedAt: now };
184
+ blockhashCache.set(rpcUrl, entry);
185
+ trimOldest(blockhashCache, MAX_TRACKED_ENDPOINTS);
186
+ return entry;
187
+ }
149
188
  var USDC_DOMAIN = {
150
189
  name: "USD Coin",
151
190
  version: "2",
@@ -230,7 +269,7 @@ async function createPaymentPayload(privateKey, fromAddress, recipient, amount,
230
269
  }
231
270
  async function createSolanaPaymentPayload(secretKey, fromAddress, recipient, amount, feePayer, options = {}) {
232
271
  const { Connection, PublicKey, TransactionMessage, VersionedTransaction, ComputeBudgetProgram } = await import("@solana/web3.js");
233
- const { getAssociatedTokenAddress, createTransferCheckedInstruction, getMint } = await import("@solana/spl-token");
272
+ const { getAssociatedTokenAddress, createTransferCheckedInstruction } = await import("@solana/spl-token");
234
273
  const { Keypair } = await import("@solana/web3.js");
235
274
  const rpcUrl = options.rpcUrl || "https://sol.blockrun.ai/api/v1/solana/rpc";
236
275
  const connection = options.rpcHeaders ? new Connection(rpcUrl, { httpHeaders: options.rpcHeaders }) : new Connection(rpcUrl);
@@ -239,32 +278,53 @@ async function createSolanaPaymentPayload(secretKey, fromAddress, recipient, amo
239
278
  const ownerPubkey = keypair.publicKey;
240
279
  const tokenMint = new PublicKey(USDC_SOLANA);
241
280
  const payToPubkey = new PublicKey(recipient);
242
- const mintInfo = await getMint(connection, tokenMint);
243
281
  const sourceATA = await getAssociatedTokenAddress(tokenMint, ownerPubkey, false);
244
282
  const destinationATA = await getAssociatedTokenAddress(tokenMint, payToPubkey, false);
245
- const { blockhash } = await connection.getLatestBlockhash();
246
- const setComputeUnitPriceIx = ComputeBudgetProgram.setComputeUnitPrice({
247
- microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS
248
- });
249
- const setComputeUnitLimitIx = ComputeBudgetProgram.setComputeUnitLimit({
250
- units: DEFAULT_COMPUTE_UNIT_LIMIT
251
- });
252
283
  const transferIx = createTransferCheckedInstruction(
253
284
  sourceATA,
254
285
  tokenMint,
255
286
  destinationATA,
256
287
  ownerPubkey,
257
288
  BigInt(amount),
258
- mintInfo.decimals
289
+ SOLANA_USDC_DECIMALS
259
290
  );
260
- const messageV0 = new TransactionMessage({
261
- payerKey: feePayerPubkey,
262
- recentBlockhash: blockhash,
263
- instructions: [setComputeUnitLimitIx, setComputeUnitPriceIx, transferIx]
264
- }).compileToV0Message();
265
- const transaction = new VersionedTransaction(messageV0);
266
- transaction.sign([keypair]);
267
- const serializedTx = Buffer.from(transaction.serialize()).toString("base64");
291
+ const buildSignedTx = (blockhash, unitPriceMicroLamports) => {
292
+ const messageV0 = new TransactionMessage({
293
+ payerKey: feePayerPubkey,
294
+ recentBlockhash: blockhash,
295
+ instructions: [
296
+ ComputeBudgetProgram.setComputeUnitLimit({ units: DEFAULT_COMPUTE_UNIT_LIMIT }),
297
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: unitPriceMicroLamports }),
298
+ transferIx
299
+ ]
300
+ }).compileToV0Message();
301
+ const transaction = new VersionedTransaction(messageV0);
302
+ transaction.sign([keypair]);
303
+ return Buffer.from(transaction.serialize()).toString("base64");
304
+ };
305
+ const findDistinctTx = (candidate) => {
306
+ const issued = issuedFor(candidate.blockhash);
307
+ for (let step = 0; step <= MAX_FEE_NONCE_STEPS; step++) {
308
+ const tx = buildSignedTx(
309
+ candidate.blockhash,
310
+ DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS + step
311
+ );
312
+ if (!issued.has(tx)) return tx;
313
+ }
314
+ return null;
315
+ };
316
+ let entry = await getBlockhashEntry(connection, rpcUrl, false);
317
+ let serializedTx = findDistinctTx(entry);
318
+ if (serializedTx === null) {
319
+ entry = await getBlockhashEntry(connection, rpcUrl, true);
320
+ serializedTx = findDistinctTx(entry);
321
+ }
322
+ if (serializedTx === null) {
323
+ throw new Error(
324
+ `Solana payment: ${MAX_FEE_NONCE_STEPS + 1} identical payments already issued against blockhash ${entry.blockhash}. Retry once it rotates.`
325
+ );
326
+ }
327
+ issuedFor(entry.blockhash).add(serializedTx);
268
328
  const paymentData = {
269
329
  x402Version: 2,
270
330
  resource: {
@@ -504,7 +564,7 @@ function getCostSummary() {
504
564
  }
505
565
 
506
566
  // src/version.ts
507
- var SDK_VERSION = "3.8.3";
567
+ var SDK_VERSION = "3.8.4";
508
568
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
509
569
 
510
570
  // src/client.ts
package/dist/index.js CHANGED
@@ -31,8 +31,47 @@ var BASE_CHAIN_ID = 8453;
31
31
  var USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
32
32
  var SOLANA_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
33
33
  var USDC_SOLANA = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
34
+ var SOLANA_USDC_DECIMALS = 6;
34
35
  var DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;
35
36
  var DEFAULT_COMPUTE_UNIT_LIMIT = 8e3;
37
+ var BLOCKHASH_TTL_MS = 1e4;
38
+ var MAX_FEE_NONCE_STEPS = 64;
39
+ var MAX_TRACKED_BLOCKHASHES = 8;
40
+ var MAX_TRACKED_ENDPOINTS = 8;
41
+ var blockhashCache = /* @__PURE__ */ new Map();
42
+ function trimOldest(map, limit) {
43
+ while (map.size > limit) {
44
+ const oldest = map.keys().next().value;
45
+ map.delete(oldest);
46
+ }
47
+ }
48
+ var issuedByBlockhash = /* @__PURE__ */ new Map();
49
+ function issuedFor(blockhash) {
50
+ let issued = issuedByBlockhash.get(blockhash);
51
+ if (!issued) {
52
+ issued = /* @__PURE__ */ new Set();
53
+ issuedByBlockhash.set(blockhash, issued);
54
+ trimOldest(issuedByBlockhash, MAX_TRACKED_BLOCKHASHES);
55
+ }
56
+ return issued;
57
+ }
58
+ async function getBlockhashEntry(connection, rpcUrl, forceRefresh) {
59
+ const now = Date.now();
60
+ const cached = blockhashCache.get(rpcUrl);
61
+ if (!forceRefresh && cached && now - cached.fetchedAt < BLOCKHASH_TTL_MS) {
62
+ return cached;
63
+ }
64
+ const { blockhash } = await connection.getLatestBlockhash();
65
+ const current = blockhashCache.get(rpcUrl);
66
+ if (current?.blockhash === blockhash) {
67
+ current.fetchedAt = now;
68
+ return current;
69
+ }
70
+ const entry = { blockhash, fetchedAt: now };
71
+ blockhashCache.set(rpcUrl, entry);
72
+ trimOldest(blockhashCache, MAX_TRACKED_ENDPOINTS);
73
+ return entry;
74
+ }
36
75
  var USDC_DOMAIN = {
37
76
  name: "USD Coin",
38
77
  version: "2",
@@ -117,7 +156,7 @@ async function createPaymentPayload(privateKey, fromAddress, recipient, amount,
117
156
  }
118
157
  async function createSolanaPaymentPayload(secretKey, fromAddress, recipient, amount, feePayer, options = {}) {
119
158
  const { Connection, PublicKey, TransactionMessage, VersionedTransaction, ComputeBudgetProgram } = await import("@solana/web3.js");
120
- const { getAssociatedTokenAddress, createTransferCheckedInstruction, getMint } = await import("@solana/spl-token");
159
+ const { getAssociatedTokenAddress, createTransferCheckedInstruction } = await import("@solana/spl-token");
121
160
  const { Keypair } = await import("@solana/web3.js");
122
161
  const rpcUrl = options.rpcUrl || "https://sol.blockrun.ai/api/v1/solana/rpc";
123
162
  const connection = options.rpcHeaders ? new Connection(rpcUrl, { httpHeaders: options.rpcHeaders }) : new Connection(rpcUrl);
@@ -126,32 +165,53 @@ async function createSolanaPaymentPayload(secretKey, fromAddress, recipient, amo
126
165
  const ownerPubkey = keypair.publicKey;
127
166
  const tokenMint = new PublicKey(USDC_SOLANA);
128
167
  const payToPubkey = new PublicKey(recipient);
129
- const mintInfo = await getMint(connection, tokenMint);
130
168
  const sourceATA = await getAssociatedTokenAddress(tokenMint, ownerPubkey, false);
131
169
  const destinationATA = await getAssociatedTokenAddress(tokenMint, payToPubkey, false);
132
- const { blockhash } = await connection.getLatestBlockhash();
133
- const setComputeUnitPriceIx = ComputeBudgetProgram.setComputeUnitPrice({
134
- microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS
135
- });
136
- const setComputeUnitLimitIx = ComputeBudgetProgram.setComputeUnitLimit({
137
- units: DEFAULT_COMPUTE_UNIT_LIMIT
138
- });
139
170
  const transferIx = createTransferCheckedInstruction(
140
171
  sourceATA,
141
172
  tokenMint,
142
173
  destinationATA,
143
174
  ownerPubkey,
144
175
  BigInt(amount),
145
- mintInfo.decimals
176
+ SOLANA_USDC_DECIMALS
146
177
  );
147
- const messageV0 = new TransactionMessage({
148
- payerKey: feePayerPubkey,
149
- recentBlockhash: blockhash,
150
- instructions: [setComputeUnitLimitIx, setComputeUnitPriceIx, transferIx]
151
- }).compileToV0Message();
152
- const transaction = new VersionedTransaction(messageV0);
153
- transaction.sign([keypair]);
154
- const serializedTx = Buffer.from(transaction.serialize()).toString("base64");
178
+ const buildSignedTx = (blockhash, unitPriceMicroLamports) => {
179
+ const messageV0 = new TransactionMessage({
180
+ payerKey: feePayerPubkey,
181
+ recentBlockhash: blockhash,
182
+ instructions: [
183
+ ComputeBudgetProgram.setComputeUnitLimit({ units: DEFAULT_COMPUTE_UNIT_LIMIT }),
184
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: unitPriceMicroLamports }),
185
+ transferIx
186
+ ]
187
+ }).compileToV0Message();
188
+ const transaction = new VersionedTransaction(messageV0);
189
+ transaction.sign([keypair]);
190
+ return Buffer.from(transaction.serialize()).toString("base64");
191
+ };
192
+ const findDistinctTx = (candidate) => {
193
+ const issued = issuedFor(candidate.blockhash);
194
+ for (let step = 0; step <= MAX_FEE_NONCE_STEPS; step++) {
195
+ const tx = buildSignedTx(
196
+ candidate.blockhash,
197
+ DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS + step
198
+ );
199
+ if (!issued.has(tx)) return tx;
200
+ }
201
+ return null;
202
+ };
203
+ let entry = await getBlockhashEntry(connection, rpcUrl, false);
204
+ let serializedTx = findDistinctTx(entry);
205
+ if (serializedTx === null) {
206
+ entry = await getBlockhashEntry(connection, rpcUrl, true);
207
+ serializedTx = findDistinctTx(entry);
208
+ }
209
+ if (serializedTx === null) {
210
+ throw new Error(
211
+ `Solana payment: ${MAX_FEE_NONCE_STEPS + 1} identical payments already issued against blockhash ${entry.blockhash}. Retry once it rotates.`
212
+ );
213
+ }
214
+ issuedFor(entry.blockhash).add(serializedTx);
155
215
  const paymentData = {
156
216
  x402Version: 2,
157
217
  resource: {
@@ -391,7 +451,7 @@ function getCostSummary() {
391
451
  }
392
452
 
393
453
  // src/version.ts
394
- var SDK_VERSION = "3.8.3";
454
+ var SDK_VERSION = "3.8.4";
395
455
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
396
456
 
397
457
  // src/client.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "3.8.3",
3
+ "version": "3.8.4",
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",