@blockrun/llm 1.10.1 → 1.13.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,8 @@
1
1
  # @blockrun/llm (TypeScript SDK)
2
2
 
3
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.
4
+ >
5
+ > 🆓 **Includes 9 fully-free NVIDIA-hosted models** — DeepSeek V4 Pro/Flash (1M context), Nemotron Nano Omni (vision), Qwen3, Llama 4, GLM-4.7, Mistral. Zero USDC, no rate-limit gimmicks. Use `routingProfile: 'free'` or call any `nvidia/*` model directly.
4
6
 
5
7
  [![npm](https://img.shields.io/npm/v/@blockrun/llm.svg)](https://www.npmjs.com/package/@blockrun/llm)
6
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
@@ -39,6 +41,40 @@ const response = await client.chat('openai/gpt-4o', 'Hello!');
39
41
 
40
42
  That's it. The SDK handles x402 payment automatically.
41
43
 
44
+ ### Try It Free (No USDC Required)
45
+
46
+ Want to kick the tires before funding a wallet? Route to BlockRun's free NVIDIA tier:
47
+
48
+ ```typescript
49
+ import { LLMClient } from '@blockrun/llm';
50
+
51
+ const client = new LLMClient(); // Wallet still required for signing, but $0 charged
52
+
53
+ // Option 1: call a free model directly
54
+ const reply = await client.chat('nvidia/qwen3-next-80b-a3b-thinking', 'Explain x402 in 1 sentence');
55
+
56
+ // Option 2: let the smart router pick the best free model per request
57
+ const result = await client.smartChat('What is 2+2?', { routingProfile: 'free' });
58
+ console.log(result.model); // e.g. 'nvidia/deepseek-v4-flash' (cheapest capable for SIMPLE tier)
59
+ console.log(result.response); // '4'
60
+ ```
61
+
62
+ **Available free models** (input + output both $0, all NVIDIA-hosted, last refreshed 2026-04-28):
63
+
64
+ | Model ID | Context | Best For |
65
+ |----------|---------|----------|
66
+ | `nvidia/deepseek-v4-pro` | 1M | Flagship reasoning — MMLU-Pro 87.5, GPQA 90.1, SWE-bench 80.6, LiveCodeBench 93.5 |
67
+ | `nvidia/deepseek-v4-flash` | 1M | ~5× faster than V4 Pro — chat, summarization, light reasoning (weaker factual recall) |
68
+ | `nvidia/nemotron-3-nano-omni-30b-a3b-reasoning` | 256K | Only vision-capable free model — text + images + video (≤2 min) + audio (≤1 hr) |
69
+ | `nvidia/qwen3-next-80b-a3b-thinking` | 131K | 116 tok/s reasoning with thinking mode |
70
+ | `nvidia/mistral-small-4-119b` | 131K | 114 tok/s — fastest free chat |
71
+ | `nvidia/glm-4.7` | 131K | 237 tok/s — GLM-4.7 with thinking mode |
72
+ | `nvidia/llama-4-maverick` | 131K | Meta Llama 4 Maverick MoE |
73
+ | `nvidia/qwen3-coder-480b` | 131K | Coding-optimised 480B MoE |
74
+ | `nvidia/deepseek-v3.2` | 131K | Legacy V3.2 — auto-upgrades to V4 Pro via fallback |
75
+
76
+ > Note: `nvidia/gpt-oss-120b` and `nvidia/gpt-oss-20b` were retired 2026-04-28 — NVIDIA's free build.nvidia.com tier reserves the right to use prompts/outputs for service improvement, which conflicts with our data-privacy policy.
77
+
42
78
  ## Quick Start (Solana)
43
79
 
44
80
  ```typescript
@@ -115,7 +151,7 @@ console.log(complex.model); // 'xai/grok-4-1-fast-reasoning'
115
151
 
116
152
  | Profile | Description | Best For |
117
153
  |---------|-------------|----------|
118
- | `free` | nvidia/gpt-oss-120b only (FREE) | Testing, development |
154
+ | `free` | NVIDIA free tier — smart-routes across 9 models (DeepSeek V4 Pro/Flash, Nemotron Nano Omni, Qwen3, GLM-4.7, Llama 4, Mistral) | Zero-cost testing, dev, prod |
119
155
  | `eco` | Cheapest models per tier (DeepSeek, xAI) | Cost-sensitive production |
120
156
  | `auto` | Best balance of cost/quality (default) | General use |
121
157
  | `premium` | Top-tier models (OpenAI, Anthropic) | Quality-critical tasks |
@@ -151,6 +187,13 @@ The classifier runs in <1ms, 100% locally, and routes to one of four tiers:
151
187
 
152
188
  ## Available Models
153
189
 
190
+ ### OpenAI GPT-5.5 Family
191
+ Released 2026-04-23 — first fully retrained base since GPT-4.5. 1M context, 128K output, native agent + computer use.
192
+
193
+ | Model | Input Price | Output Price |
194
+ |-------|-------------|--------------|
195
+ | `openai/gpt-5.5` | $5.00/M | $30.00/M |
196
+
154
197
  ### OpenAI GPT-5.4 Family
155
198
  | Model | Input Price | Output Price |
156
199
  |-------|-------------|--------------|
@@ -238,20 +281,23 @@ The classifier runs in <1ms, 100% locally, and routes to one of four tiers:
238
281
 
239
282
  ### NVIDIA (Free) + Moonshot
240
283
 
241
- Free tier refreshed 2026-04-21: retired the Nemotron family, `mistral-large-3-675b`,
242
- `devstral-2-123b`, and paid `nvidia/kimi-k2.5`. The backend auto-redirects the
243
- old IDs; the recommended replacements are listed below.
284
+ Free tier refreshed 2026-04-28: added DeepSeek V4 Pro/Flash and Nemotron Nano
285
+ Omni (vision); retired `nvidia/gpt-oss-120b` / `nvidia/gpt-oss-20b` over data
286
+ privacy (NVIDIA's free build.nvidia.com tier reserves the right to use prompts
287
+ for service improvement, which conflicts with our policy). Backend
288
+ auto-redirects retired IDs to the replacements below.
244
289
 
245
290
  | Model | Input Price | Output Price | Notes |
246
291
  |-------|-------------|--------------|-------|
247
- | `nvidia/qwen3-next-80b-a3b-thinking` | **FREE** | **FREE** | Reasoning flagship116 tok/s, thinking mode |
248
- | `nvidia/mistral-small-4-119b` | **FREE** | **FREE** | Fastest free chat114 tok/s |
249
- | `nvidia/glm-4.7` | **FREE** | **FREE** | GLM-4.7 with thinking237 tok/s |
250
- | `nvidia/llama-4-maverick` | **FREE** | **FREE** | Llama 4 Maverick MoE |
292
+ | `nvidia/deepseek-v4-pro` | **FREE** | **FREE** | 1.6T MoE / 49B active, 1M context flagship reasoning (MMLU-Pro 87.5, GPQA 90.1) |
293
+ | `nvidia/deepseek-v4-flash` | **FREE** | **FREE** | 284B / 13B active MoE, 1M context ~5× faster than V4 Pro |
294
+ | `nvidia/nemotron-3-nano-omni-30b-a3b-reasoning` | **FREE** | **FREE** | 31B / 3.2B active MoE, 256K only vision-capable free model |
295
+ | `nvidia/qwen3-next-80b-a3b-thinking` | **FREE** | **FREE** | 116 tok/s reasoning flagship with thinking mode |
296
+ | `nvidia/mistral-small-4-119b` | **FREE** | **FREE** | 114 tok/s — fastest free chat |
297
+ | `nvidia/glm-4.7` | **FREE** | **FREE** | 237 tok/s — GLM-4.7 with thinking mode |
298
+ | `nvidia/llama-4-maverick` | **FREE** | **FREE** | Meta Llama 4 Maverick MoE |
251
299
  | `nvidia/qwen3-coder-480b` | **FREE** | **FREE** | Coding-optimised 480B MoE |
252
- | `nvidia/deepseek-v3.2` | **FREE** | **FREE** | DeepSeek V3.2 hosted |
253
- | `nvidia/gpt-oss-120b` | **FREE** | **FREE** | OpenAI open-weight 120B — 123 tok/s |
254
- | `nvidia/gpt-oss-20b` | **FREE** | **FREE** | OpenAI open-weight 20B — 155 tok/s |
300
+ | `nvidia/deepseek-v3.2` | **FREE** | **FREE** | Legacy V3.2 auto-upgrades to V4 Pro via fallback |
255
301
  | `moonshot/kimi-k2.5` | $0.60/M | $3.00/M | Direct from Moonshot — replaces `nvidia/kimi-k2.5` |
256
302
 
257
303
  ### E2E Verified Models
@@ -537,7 +583,7 @@ const premium = await client.smartChat('Write a legal brief', { routingProfile:
537
583
 
538
584
  | Profile | Description | Best For |
539
585
  |---------|-------------|----------|
540
- | `free` | NVIDIA free models only | Testing, simple queries |
586
+ | `free` | NVIDIA free tier (9 models, smart-routed) | Zero-cost testing, dev, prod |
541
587
  | `eco` | Budget-optimized | Cost-sensitive workloads |
542
588
  | `auto` | Intelligent routing (default) | General use |
543
589
  | `premium` | Best quality models | Critical tasks |
package/dist/index.cjs CHANGED
@@ -1686,6 +1686,8 @@ var DEFAULT_API_URL2 = "https://blockrun.ai/api";
1686
1686
  var DEFAULT_MODEL = "google/nano-banana";
1687
1687
  var DEFAULT_SIZE = "1024x1024";
1688
1688
  var DEFAULT_TIMEOUT2 = 2e5;
1689
+ var POLL_INTERVAL_MS = 3e3;
1690
+ var POLL_MAX_DURATION_MS = 3e5;
1689
1691
  var ImageClient = class {
1690
1692
  account;
1691
1693
  privateKey;
@@ -1870,7 +1872,70 @@ var ImageClient = class {
1870
1872
  sanitizeErrorResponse(errorBody)
1871
1873
  );
1872
1874
  }
1873
- return retryResponse.json();
1875
+ const responseBody = await retryResponse.json();
1876
+ if (retryResponse.status === 202 || responseBody.status === "queued" || responseBody.status === "in_progress") {
1877
+ if (!responseBody.poll_url) {
1878
+ throw new APIError(
1879
+ `Server returned ${retryResponse.status} but no poll_url to follow.`,
1880
+ retryResponse.status,
1881
+ sanitizeErrorResponse(responseBody)
1882
+ );
1883
+ }
1884
+ return this.pollImageJob(responseBody.poll_url, paymentPayload);
1885
+ }
1886
+ return responseBody;
1887
+ }
1888
+ /**
1889
+ * Poll the async image generation endpoint until the job reaches a terminal
1890
+ * state (completed/failed). Used when the POST returns 202 + poll_url for
1891
+ * slow models that exceeded the server's inline window.
1892
+ *
1893
+ * Sends the SAME payment header on every poll — the server binds the payer
1894
+ * to the job id and re-verifies on each call. Settlement happens server-side
1895
+ * on the first poll where status=completed.
1896
+ */
1897
+ async pollImageJob(pollPath, paymentHeader) {
1898
+ const pollUrl = pollPath.startsWith("/api/") ? `${this.apiUrl.replace(/\/api$/, "")}${pollPath}` : `${this.apiUrl}${pollPath.startsWith("/") ? "" : "/"}${pollPath}`;
1899
+ const startedAt = Date.now();
1900
+ while (Date.now() - startedAt < POLL_MAX_DURATION_MS) {
1901
+ await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
1902
+ const pollResp = await this.fetchWithTimeout(pollUrl, {
1903
+ method: "GET",
1904
+ headers: {
1905
+ "PAYMENT-SIGNATURE": paymentHeader,
1906
+ "X-PAYMENT": paymentHeader
1907
+ }
1908
+ });
1909
+ if (pollResp.status === 202) {
1910
+ continue;
1911
+ }
1912
+ const pollBody = await pollResp.json().catch(() => ({}));
1913
+ if (!pollResp.ok) {
1914
+ throw new APIError(
1915
+ `API error during poll: ${pollResp.status}`,
1916
+ pollResp.status,
1917
+ sanitizeErrorResponse(pollBody)
1918
+ );
1919
+ }
1920
+ if (pollBody.status === "failed") {
1921
+ throw new APIError(
1922
+ pollBody.error || "Upstream image generation failed",
1923
+ 200,
1924
+ sanitizeErrorResponse(pollBody)
1925
+ );
1926
+ }
1927
+ if (pollBody.data) {
1928
+ return pollBody;
1929
+ }
1930
+ if (pollBody.status === "queued" || pollBody.status === "in_progress") {
1931
+ continue;
1932
+ }
1933
+ }
1934
+ throw new APIError(
1935
+ `Image generation poll timed out after ${POLL_MAX_DURATION_MS / 1e3}s`,
1936
+ 504,
1937
+ { error: "poll_timeout", poll_url: pollPath }
1938
+ );
1874
1939
  }
1875
1940
  /**
1876
1941
  * Fetch with timeout.
@@ -2759,13 +2824,13 @@ var path2 = __toESM(require("path"), 1);
2759
2824
  var os2 = __toESM(require("os"), 1);
2760
2825
  var WALLET_DIR2 = path2.join(os2.homedir(), ".blockrun");
2761
2826
  var SOLANA_WALLET_FILE = path2.join(WALLET_DIR2, ".solana-session");
2762
- function createSolanaWallet() {
2763
- const { Keypair } = require("@solana/web3.js");
2764
- const bs58 = require("bs58");
2827
+ async function createSolanaWallet() {
2828
+ const { Keypair } = await import("@solana/web3.js");
2829
+ const bs58 = await import("bs58");
2765
2830
  const keypair = Keypair.generate();
2766
2831
  return {
2767
2832
  address: keypair.publicKey.toBase58(),
2768
- privateKey: bs58.default?.encode(keypair.secretKey) ?? bs58.encode(keypair.secretKey)
2833
+ privateKey: (bs58.default ?? bs58).encode(keypair.secretKey)
2769
2834
  };
2770
2835
  }
2771
2836
  async function solanaKeyToBytes(privateKey) {
@@ -2858,7 +2923,7 @@ async function getOrCreateSolanaWallet() {
2858
2923
  return { privateKey: fileKey, address: address2, isNew: false };
2859
2924
  }
2860
2925
  }
2861
- const { address, privateKey } = createSolanaWallet();
2926
+ const { address, privateKey } = await createSolanaWallet();
2862
2927
  saveSolanaWallet(privateKey);
2863
2928
  return { address, privateKey, isNew: true };
2864
2929
  }
package/dist/index.d.cts CHANGED
@@ -1195,6 +1195,16 @@ declare class ImageClient {
1195
1195
  * Handle 402 response: parse requirements, sign payment, retry.
1196
1196
  */
1197
1197
  private handlePaymentAndRetry;
1198
+ /**
1199
+ * Poll the async image generation endpoint until the job reaches a terminal
1200
+ * state (completed/failed). Used when the POST returns 202 + poll_url for
1201
+ * slow models that exceeded the server's inline window.
1202
+ *
1203
+ * Sends the SAME payment header on every poll — the server binds the payer
1204
+ * to the job id and re-verifies on each call. Settlement happens server-side
1205
+ * on the first poll where status=completed.
1206
+ */
1207
+ private pollImageJob;
1198
1208
  /**
1199
1209
  * Fetch with timeout.
1200
1210
  */
@@ -1736,12 +1746,14 @@ interface SolanaWalletInfo {
1736
1746
  }
1737
1747
  /**
1738
1748
  * Create a new Solana wallet.
1739
- * Requires @solana/web3.js (optional dep).
1749
+ * Requires @solana/web3.js (optional dep) — loaded lazily via dynamic
1750
+ * import so callers that never touch Solana don't pay the resolution cost
1751
+ * and ESM consumers don't trip over esbuild's __require shim.
1740
1752
  */
1741
- declare function createSolanaWallet(): {
1753
+ declare function createSolanaWallet(): Promise<{
1742
1754
  address: string;
1743
1755
  privateKey: string;
1744
- };
1756
+ }>;
1745
1757
  /**
1746
1758
  * Convert a bs58 private key string to Uint8Array (64 bytes).
1747
1759
  * Accepts: bs58-encoded 64-byte key (standard Solana format).
package/dist/index.d.ts CHANGED
@@ -1195,6 +1195,16 @@ declare class ImageClient {
1195
1195
  * Handle 402 response: parse requirements, sign payment, retry.
1196
1196
  */
1197
1197
  private handlePaymentAndRetry;
1198
+ /**
1199
+ * Poll the async image generation endpoint until the job reaches a terminal
1200
+ * state (completed/failed). Used when the POST returns 202 + poll_url for
1201
+ * slow models that exceeded the server's inline window.
1202
+ *
1203
+ * Sends the SAME payment header on every poll — the server binds the payer
1204
+ * to the job id and re-verifies on each call. Settlement happens server-side
1205
+ * on the first poll where status=completed.
1206
+ */
1207
+ private pollImageJob;
1198
1208
  /**
1199
1209
  * Fetch with timeout.
1200
1210
  */
@@ -1736,12 +1746,14 @@ interface SolanaWalletInfo {
1736
1746
  }
1737
1747
  /**
1738
1748
  * Create a new Solana wallet.
1739
- * Requires @solana/web3.js (optional dep).
1749
+ * Requires @solana/web3.js (optional dep) — loaded lazily via dynamic
1750
+ * import so callers that never touch Solana don't pay the resolution cost
1751
+ * and ESM consumers don't trip over esbuild's __require shim.
1740
1752
  */
1741
- declare function createSolanaWallet(): {
1753
+ declare function createSolanaWallet(): Promise<{
1742
1754
  address: string;
1743
1755
  privateKey: string;
1744
- };
1756
+ }>;
1745
1757
  /**
1746
1758
  * Convert a bs58 private key string to Uint8Array (64 bytes).
1747
1759
  * Accepts: bs58-encoded 64-byte key (standard Solana format).
package/dist/index.js CHANGED
@@ -1,10 +1,3 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
1
  // src/client.ts
9
2
  import { privateKeyToAccount } from "viem/accounts";
10
3
 
@@ -1597,6 +1590,8 @@ var DEFAULT_API_URL2 = "https://blockrun.ai/api";
1597
1590
  var DEFAULT_MODEL = "google/nano-banana";
1598
1591
  var DEFAULT_SIZE = "1024x1024";
1599
1592
  var DEFAULT_TIMEOUT2 = 2e5;
1593
+ var POLL_INTERVAL_MS = 3e3;
1594
+ var POLL_MAX_DURATION_MS = 3e5;
1600
1595
  var ImageClient = class {
1601
1596
  account;
1602
1597
  privateKey;
@@ -1781,7 +1776,70 @@ var ImageClient = class {
1781
1776
  sanitizeErrorResponse(errorBody)
1782
1777
  );
1783
1778
  }
1784
- return retryResponse.json();
1779
+ const responseBody = await retryResponse.json();
1780
+ if (retryResponse.status === 202 || responseBody.status === "queued" || responseBody.status === "in_progress") {
1781
+ if (!responseBody.poll_url) {
1782
+ throw new APIError(
1783
+ `Server returned ${retryResponse.status} but no poll_url to follow.`,
1784
+ retryResponse.status,
1785
+ sanitizeErrorResponse(responseBody)
1786
+ );
1787
+ }
1788
+ return this.pollImageJob(responseBody.poll_url, paymentPayload);
1789
+ }
1790
+ return responseBody;
1791
+ }
1792
+ /**
1793
+ * Poll the async image generation endpoint until the job reaches a terminal
1794
+ * state (completed/failed). Used when the POST returns 202 + poll_url for
1795
+ * slow models that exceeded the server's inline window.
1796
+ *
1797
+ * Sends the SAME payment header on every poll — the server binds the payer
1798
+ * to the job id and re-verifies on each call. Settlement happens server-side
1799
+ * on the first poll where status=completed.
1800
+ */
1801
+ async pollImageJob(pollPath, paymentHeader) {
1802
+ const pollUrl = pollPath.startsWith("/api/") ? `${this.apiUrl.replace(/\/api$/, "")}${pollPath}` : `${this.apiUrl}${pollPath.startsWith("/") ? "" : "/"}${pollPath}`;
1803
+ const startedAt = Date.now();
1804
+ while (Date.now() - startedAt < POLL_MAX_DURATION_MS) {
1805
+ await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
1806
+ const pollResp = await this.fetchWithTimeout(pollUrl, {
1807
+ method: "GET",
1808
+ headers: {
1809
+ "PAYMENT-SIGNATURE": paymentHeader,
1810
+ "X-PAYMENT": paymentHeader
1811
+ }
1812
+ });
1813
+ if (pollResp.status === 202) {
1814
+ continue;
1815
+ }
1816
+ const pollBody = await pollResp.json().catch(() => ({}));
1817
+ if (!pollResp.ok) {
1818
+ throw new APIError(
1819
+ `API error during poll: ${pollResp.status}`,
1820
+ pollResp.status,
1821
+ sanitizeErrorResponse(pollBody)
1822
+ );
1823
+ }
1824
+ if (pollBody.status === "failed") {
1825
+ throw new APIError(
1826
+ pollBody.error || "Upstream image generation failed",
1827
+ 200,
1828
+ sanitizeErrorResponse(pollBody)
1829
+ );
1830
+ }
1831
+ if (pollBody.data) {
1832
+ return pollBody;
1833
+ }
1834
+ if (pollBody.status === "queued" || pollBody.status === "in_progress") {
1835
+ continue;
1836
+ }
1837
+ }
1838
+ throw new APIError(
1839
+ `Image generation poll timed out after ${POLL_MAX_DURATION_MS / 1e3}s`,
1840
+ 504,
1841
+ { error: "poll_timeout", poll_url: pollPath }
1842
+ );
1785
1843
  }
1786
1844
  /**
1787
1845
  * Fetch with timeout.
@@ -2670,13 +2728,13 @@ import * as path2 from "path";
2670
2728
  import * as os2 from "os";
2671
2729
  var WALLET_DIR2 = path2.join(os2.homedir(), ".blockrun");
2672
2730
  var SOLANA_WALLET_FILE = path2.join(WALLET_DIR2, ".solana-session");
2673
- function createSolanaWallet() {
2674
- const { Keypair } = __require("@solana/web3.js");
2675
- const bs58 = __require("bs58");
2731
+ async function createSolanaWallet() {
2732
+ const { Keypair } = await import("@solana/web3.js");
2733
+ const bs58 = await import("bs58");
2676
2734
  const keypair = Keypair.generate();
2677
2735
  return {
2678
2736
  address: keypair.publicKey.toBase58(),
2679
- privateKey: bs58.default?.encode(keypair.secretKey) ?? bs58.encode(keypair.secretKey)
2737
+ privateKey: (bs58.default ?? bs58).encode(keypair.secretKey)
2680
2738
  };
2681
2739
  }
2682
2740
  async function solanaKeyToBytes(privateKey) {
@@ -2769,7 +2827,7 @@ async function getOrCreateSolanaWallet() {
2769
2827
  return { privateKey: fileKey, address: address2, isNew: false };
2770
2828
  }
2771
2829
  }
2772
- const { address, privateKey } = createSolanaWallet();
2830
+ const { address, privateKey } = await createSolanaWallet();
2773
2831
  saveSolanaWallet(privateKey);
2774
2832
  return { address, privateKey, isNew: true };
2775
2833
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "1.10.1",
3
+ "version": "1.13.0",
4
4
  "type": "module",
5
5
  "description": "BlockRun SDK - Pay-per-request AI (LLM, Image, Video, Music) via x402 on Base and Solana",
6
6
  "main": "dist/index.cjs",