@blockrun/llm 1.2.0 → 1.3.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/dist/index.js CHANGED
@@ -670,6 +670,103 @@ var LLMClient = class {
670
670
  this.sessionTotalUsd += costUsd;
671
671
  return retryResponse.json();
672
672
  }
673
+ /**
674
+ * GET with automatic x402 payment handling, returning raw JSON.
675
+ * Used for Predexon prediction market endpoints that use GET + query params.
676
+ */
677
+ async getWithPaymentRaw(endpoint, params) {
678
+ const query = params ? "?" + new URLSearchParams(params).toString() : "";
679
+ const url = `${this.apiUrl}${endpoint}${query}`;
680
+ const response = await this.fetchWithTimeout(url, {
681
+ method: "GET",
682
+ headers: { "User-Agent": USER_AGENT }
683
+ });
684
+ if (response.status === 402) {
685
+ return this.handleGetPaymentAndRetryRaw(url, endpoint, params, response);
686
+ }
687
+ if (!response.ok) {
688
+ let errorBody;
689
+ try {
690
+ errorBody = await response.json();
691
+ } catch {
692
+ errorBody = { error: "Request failed" };
693
+ }
694
+ throw new APIError(
695
+ `API error: ${response.status}`,
696
+ response.status,
697
+ sanitizeErrorResponse(errorBody)
698
+ );
699
+ }
700
+ return response.json();
701
+ }
702
+ /**
703
+ * Handle 402 response for GET endpoints: parse requirements, sign payment, retry with GET.
704
+ */
705
+ async handleGetPaymentAndRetryRaw(url, endpoint, params, response) {
706
+ let paymentHeader = response.headers.get("payment-required");
707
+ if (!paymentHeader) {
708
+ try {
709
+ const respBody = await response.json();
710
+ if (respBody.x402 || respBody.accepts) {
711
+ paymentHeader = btoa(JSON.stringify(respBody));
712
+ }
713
+ } catch {
714
+ console.debug("Failed to parse payment header from response body");
715
+ }
716
+ }
717
+ if (!paymentHeader) {
718
+ throw new PaymentError("402 response but no payment requirements found");
719
+ }
720
+ const paymentRequired = parsePaymentRequired(paymentHeader);
721
+ const details = extractPaymentDetails(paymentRequired);
722
+ const extensions = paymentRequired.extensions;
723
+ const paymentPayload = await createPaymentPayload(
724
+ this.privateKey,
725
+ this.account.address,
726
+ details.recipient,
727
+ details.amount,
728
+ details.network || "eip155:8453",
729
+ {
730
+ resourceUrl: validateResourceUrl(
731
+ details.resource?.url || url,
732
+ this.apiUrl
733
+ ),
734
+ resourceDescription: details.resource?.description || "BlockRun AI API call",
735
+ maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
736
+ extra: details.extra,
737
+ extensions
738
+ }
739
+ );
740
+ const query = params ? "?" + new URLSearchParams(params).toString() : "";
741
+ const retryUrl = `${this.apiUrl}${endpoint}${query}`;
742
+ const retryResponse = await this.fetchWithTimeout(retryUrl, {
743
+ method: "GET",
744
+ headers: {
745
+ "User-Agent": USER_AGENT,
746
+ "PAYMENT-SIGNATURE": paymentPayload
747
+ }
748
+ });
749
+ if (retryResponse.status === 402) {
750
+ throw new PaymentError("Payment was rejected. Check your wallet balance.");
751
+ }
752
+ if (!retryResponse.ok) {
753
+ let errorBody;
754
+ try {
755
+ errorBody = await retryResponse.json();
756
+ } catch {
757
+ errorBody = { error: "Request failed" };
758
+ }
759
+ throw new APIError(
760
+ `API error after payment: ${retryResponse.status}`,
761
+ retryResponse.status,
762
+ sanitizeErrorResponse(errorBody)
763
+ );
764
+ }
765
+ const costUsd = parseFloat(details.amount) / 1e6;
766
+ this.sessionCalls += 1;
767
+ this.sessionTotalUsd += costUsd;
768
+ return retryResponse.json();
769
+ }
673
770
  /**
674
771
  * Fetch with timeout.
675
772
  */
@@ -1031,6 +1128,38 @@ var LLMClient = class {
1031
1128
  const data = await this.requestWithPaymentRaw("/v1/x/compare", { handle1, handle2 });
1032
1129
  return data;
1033
1130
  }
1131
+ // ── Prediction Markets (Powered by Predexon) ────────────────────────────
1132
+ /**
1133
+ * Query Predexon prediction market data (GET endpoints).
1134
+ *
1135
+ * Access real-time data from Polymarket, Kalshi, dFlow, and Binance Futures.
1136
+ * Powered by Predexon. $0.001 per request.
1137
+ *
1138
+ * @param path - Endpoint path, e.g. "polymarket/events", "kalshi/markets/12345"
1139
+ * @param params - Query parameters passed to the endpoint
1140
+ *
1141
+ * @example
1142
+ * const events = await client.pm("polymarket/events");
1143
+ * const market = await client.pm("kalshi/markets/KXBTC-25MAR14");
1144
+ * const results = await client.pm("polymarket/search", { q: "bitcoin" });
1145
+ */
1146
+ async pm(path5, params) {
1147
+ return this.getWithPaymentRaw(`/v1/pm/${path5}`, params);
1148
+ }
1149
+ /**
1150
+ * Structured query for Predexon prediction market data (POST endpoints).
1151
+ *
1152
+ * For complex queries that require a JSON body. $0.005 per request.
1153
+ *
1154
+ * @param path - Endpoint path, e.g. "polymarket/query", "kalshi/query"
1155
+ * @param query - JSON body for the structured query
1156
+ *
1157
+ * @example
1158
+ * const data = await client.pmQuery("polymarket/query", { filter: "active", limit: 10 });
1159
+ */
1160
+ async pmQuery(path5, query) {
1161
+ return this.requestWithPaymentRaw(`/v1/pm/${path5}`, query);
1162
+ }
1034
1163
  /**
1035
1164
  * Get current session spending.
1036
1165
  *
@@ -1316,7 +1445,35 @@ function saveWallet(privateKey) {
1316
1445
  fs.writeFileSync(WALLET_FILE, privateKey, { mode: 384 });
1317
1446
  return WALLET_FILE;
1318
1447
  }
1448
+ function scanWallets() {
1449
+ const home = os.homedir();
1450
+ const results = [];
1451
+ try {
1452
+ const entries = fs.readdirSync(home, { withFileTypes: true });
1453
+ for (const entry of entries) {
1454
+ if (!entry.name.startsWith(".") || !entry.isDirectory()) continue;
1455
+ const walletFile = path.join(home, entry.name, "wallet.json");
1456
+ if (!fs.existsSync(walletFile)) continue;
1457
+ try {
1458
+ const data = JSON.parse(fs.readFileSync(walletFile, "utf-8"));
1459
+ const pk = data.privateKey || "";
1460
+ const addr = data.address || "";
1461
+ if (pk && addr) {
1462
+ const mtime = fs.statSync(walletFile).mtimeMs;
1463
+ results.push({ mtime, privateKey: pk, address: addr });
1464
+ }
1465
+ } catch {
1466
+ continue;
1467
+ }
1468
+ }
1469
+ } catch {
1470
+ }
1471
+ results.sort((a, b) => b.mtime - a.mtime);
1472
+ return results.map(({ privateKey, address }) => ({ privateKey, address }));
1473
+ }
1319
1474
  function loadWallet() {
1475
+ const wallets = scanWallets();
1476
+ if (wallets.length > 0) return wallets[0].privateKey;
1320
1477
  if (fs.existsSync(WALLET_FILE)) {
1321
1478
  const key = fs.readFileSync(WALLET_FILE, "utf-8").trim();
1322
1479
  if (key) return key;
@@ -1455,7 +1612,50 @@ function saveSolanaWallet(privateKey) {
1455
1612
  fs2.writeFileSync(SOLANA_WALLET_FILE, privateKey, { mode: 384 });
1456
1613
  return SOLANA_WALLET_FILE;
1457
1614
  }
1615
+ function scanSolanaWallets() {
1616
+ const home = os2.homedir();
1617
+ const results = [];
1618
+ try {
1619
+ const entries = fs2.readdirSync(home, { withFileTypes: true });
1620
+ for (const entry of entries) {
1621
+ if (!entry.name.startsWith(".") || !entry.isDirectory()) continue;
1622
+ const solanaWalletFile = path2.join(home, entry.name, "solana-wallet.json");
1623
+ if (fs2.existsSync(solanaWalletFile)) {
1624
+ try {
1625
+ const data = JSON.parse(fs2.readFileSync(solanaWalletFile, "utf-8"));
1626
+ const pk = data.privateKey || "";
1627
+ const addr = data.address || "";
1628
+ if (pk && addr) {
1629
+ const mtime = fs2.statSync(solanaWalletFile).mtimeMs;
1630
+ results.push({ mtime, secretKey: pk, publicKey: addr });
1631
+ }
1632
+ } catch {
1633
+ }
1634
+ }
1635
+ if (entry.name === ".brcc") {
1636
+ const brccWalletFile = path2.join(home, entry.name, "wallet.json");
1637
+ if (fs2.existsSync(brccWalletFile)) {
1638
+ try {
1639
+ const data = JSON.parse(fs2.readFileSync(brccWalletFile, "utf-8"));
1640
+ const pk = data.privateKey || "";
1641
+ const addr = data.address || "";
1642
+ if (pk && addr) {
1643
+ const mtime = fs2.statSync(brccWalletFile).mtimeMs;
1644
+ results.push({ mtime, secretKey: pk, publicKey: addr });
1645
+ }
1646
+ } catch {
1647
+ }
1648
+ }
1649
+ }
1650
+ }
1651
+ } catch {
1652
+ }
1653
+ results.sort((a, b) => b.mtime - a.mtime);
1654
+ return results.map(({ secretKey, publicKey }) => ({ secretKey, publicKey }));
1655
+ }
1458
1656
  function loadSolanaWallet() {
1657
+ const wallets = scanSolanaWallets();
1658
+ if (wallets.length > 0) return wallets[0].secretKey;
1459
1659
  if (fs2.existsSync(SOLANA_WALLET_FILE)) {
1460
1660
  const key = fs2.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
1461
1661
  if (key) return key;
@@ -1468,10 +1668,16 @@ async function getOrCreateSolanaWallet() {
1468
1668
  const address2 = await solanaPublicKey(envKey);
1469
1669
  return { privateKey: envKey, address: address2, isNew: false };
1470
1670
  }
1471
- const fileKey = loadSolanaWallet();
1472
- if (fileKey) {
1473
- const address2 = await solanaPublicKey(fileKey);
1474
- return { privateKey: fileKey, address: address2, isNew: false };
1671
+ const wallets = scanSolanaWallets();
1672
+ if (wallets.length > 0) {
1673
+ return { privateKey: wallets[0].secretKey, address: wallets[0].publicKey, isNew: false };
1674
+ }
1675
+ if (fs2.existsSync(SOLANA_WALLET_FILE)) {
1676
+ const fileKey = fs2.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
1677
+ if (fileKey) {
1678
+ const address2 = await solanaPublicKey(fileKey);
1679
+ return { privateKey: fileKey, address: address2, isNew: false };
1680
+ }
1475
1681
  }
1476
1682
  const { address, privateKey } = createSolanaWallet();
1477
1683
  saveSolanaWallet(privateKey);
@@ -1689,6 +1895,13 @@ var SolanaLLMClient = class {
1689
1895
  const data = await this.requestWithPaymentRaw("/v1/x/compare", { handle1, handle2 });
1690
1896
  return data;
1691
1897
  }
1898
+ // ── Prediction Markets (Powered by Predexon) ────────────────────────────
1899
+ async pm(path5, params) {
1900
+ return this.getWithPaymentRaw(`/v1/pm/${path5}`, params);
1901
+ }
1902
+ async pmQuery(path5, query) {
1903
+ return this.requestWithPaymentRaw(`/v1/pm/${path5}`, query);
1904
+ }
1692
1905
  /** Get session spending. */
1693
1906
  getSpending() {
1694
1907
  return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
@@ -1879,6 +2092,97 @@ var SolanaLLMClient = class {
1879
2092
  this.sessionTotalUsd += costUsd;
1880
2093
  return retryResponse.json();
1881
2094
  }
2095
+ async getWithPaymentRaw(endpoint, params) {
2096
+ const query = params ? "?" + new URLSearchParams(params).toString() : "";
2097
+ const url = `${this.apiUrl}${endpoint}${query}`;
2098
+ const response = await this.fetchWithTimeout(url, {
2099
+ method: "GET",
2100
+ headers: { "User-Agent": USER_AGENT2 }
2101
+ });
2102
+ if (response.status === 402) {
2103
+ return this.handleGetPaymentAndRetryRaw(url, endpoint, params, response);
2104
+ }
2105
+ if (!response.ok) {
2106
+ let errorBody;
2107
+ try {
2108
+ errorBody = await response.json();
2109
+ } catch {
2110
+ errorBody = { error: "Request failed" };
2111
+ }
2112
+ throw new APIError(`API error: ${response.status}`, response.status, sanitizeErrorResponse(errorBody));
2113
+ }
2114
+ return response.json();
2115
+ }
2116
+ async handleGetPaymentAndRetryRaw(url, endpoint, params, response) {
2117
+ let paymentHeader = response.headers.get("payment-required");
2118
+ if (!paymentHeader) {
2119
+ try {
2120
+ const respBody = await response.json();
2121
+ if (respBody.accepts || respBody.x402Version) {
2122
+ paymentHeader = btoa(JSON.stringify(respBody));
2123
+ }
2124
+ } catch {
2125
+ }
2126
+ }
2127
+ if (!paymentHeader) {
2128
+ throw new PaymentError("402 response but no payment requirements found");
2129
+ }
2130
+ const paymentRequired = parsePaymentRequired(paymentHeader);
2131
+ const details = extractPaymentDetails(paymentRequired, SOLANA_NETWORK);
2132
+ if (!details.network?.startsWith("solana:")) {
2133
+ throw new PaymentError(
2134
+ `Expected Solana payment network, got: ${details.network}. Use LLMClient for Base payments.`
2135
+ );
2136
+ }
2137
+ const feePayer = details.extra?.feePayer;
2138
+ if (!feePayer) throw new PaymentError("Missing feePayer in 402 extra field");
2139
+ const fromAddress = await this.getWalletAddress();
2140
+ const secretKey = await solanaKeyToBytes(this.privateKey);
2141
+ const extensions = paymentRequired.extensions;
2142
+ const paymentPayload = await createSolanaPaymentPayload(
2143
+ secretKey,
2144
+ fromAddress,
2145
+ details.recipient,
2146
+ details.amount,
2147
+ feePayer,
2148
+ {
2149
+ resourceUrl: validateResourceUrl(
2150
+ details.resource?.url || url,
2151
+ this.apiUrl
2152
+ ),
2153
+ resourceDescription: details.resource?.description || "BlockRun Solana AI API call",
2154
+ maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
2155
+ extra: details.extra,
2156
+ extensions,
2157
+ rpcUrl: this.rpcUrl
2158
+ }
2159
+ );
2160
+ const query = params ? "?" + new URLSearchParams(params).toString() : "";
2161
+ const retryUrl = `${this.apiUrl}${endpoint}${query}`;
2162
+ const retryResponse = await this.fetchWithTimeout(retryUrl, {
2163
+ method: "GET",
2164
+ headers: {
2165
+ "User-Agent": USER_AGENT2,
2166
+ "PAYMENT-SIGNATURE": paymentPayload
2167
+ }
2168
+ });
2169
+ if (retryResponse.status === 402) {
2170
+ throw new PaymentError("Payment was rejected. Check your Solana USDC balance.");
2171
+ }
2172
+ if (!retryResponse.ok) {
2173
+ let errorBody;
2174
+ try {
2175
+ errorBody = await retryResponse.json();
2176
+ } catch {
2177
+ errorBody = { error: "Request failed" };
2178
+ }
2179
+ throw new APIError(`API error after payment: ${retryResponse.status}`, retryResponse.status, sanitizeErrorResponse(errorBody));
2180
+ }
2181
+ const costUsd = parseFloat(details.amount) / 1e6;
2182
+ this.sessionCalls += 1;
2183
+ this.sessionTotalUsd += costUsd;
2184
+ return retryResponse.json();
2185
+ }
1882
2186
  async fetchWithTimeout(url, options) {
1883
2187
  const controller = new AbortController();
1884
2188
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
@@ -1893,6 +2197,192 @@ function solanaClient(options = {}) {
1893
2197
  return new SolanaLLMClient({ ...options, apiUrl: SOLANA_API_URL });
1894
2198
  }
1895
2199
 
2200
+ // src/cache.ts
2201
+ import * as fs3 from "fs";
2202
+ import * as path3 from "path";
2203
+ import * as os3 from "os";
2204
+ import * as crypto2 from "crypto";
2205
+ var CACHE_DIR = path3.join(os3.homedir(), ".blockrun", "cache");
2206
+ var DEFAULT_TTL = {
2207
+ "/v1/x/": 3600 * 1e3,
2208
+ "/v1/partner/": 3600 * 1e3,
2209
+ "/v1/pm/": 1800 * 1e3,
2210
+ "/v1/chat/": 0,
2211
+ "/v1/search": 900 * 1e3,
2212
+ "/v1/image": 0,
2213
+ "/v1/models": 86400 * 1e3
2214
+ };
2215
+ function getTtl(endpoint) {
2216
+ for (const [pattern, ttl] of Object.entries(DEFAULT_TTL)) {
2217
+ if (endpoint.includes(pattern)) return ttl;
2218
+ }
2219
+ return 3600 * 1e3;
2220
+ }
2221
+ function cacheKey(endpoint, body) {
2222
+ const keyData = JSON.stringify({ endpoint, body }, Object.keys({ endpoint, body }).sort());
2223
+ return crypto2.createHash("sha256").update(keyData).digest("hex").slice(0, 16);
2224
+ }
2225
+ function cachePath(key) {
2226
+ return path3.join(CACHE_DIR, `${key}.json`);
2227
+ }
2228
+ function getCached(key) {
2229
+ const filePath = cachePath(key);
2230
+ if (!fs3.existsSync(filePath)) return null;
2231
+ try {
2232
+ const raw = fs3.readFileSync(filePath, "utf-8");
2233
+ const entry = JSON.parse(raw);
2234
+ const ttl = entry.ttlMs ?? getTtl(entry.endpoint ?? "");
2235
+ if (ttl <= 0) return null;
2236
+ if (Date.now() - entry.cachedAt > ttl) {
2237
+ try {
2238
+ fs3.unlinkSync(filePath);
2239
+ } catch {
2240
+ }
2241
+ return null;
2242
+ }
2243
+ return entry.response;
2244
+ } catch {
2245
+ return null;
2246
+ }
2247
+ }
2248
+ function getCachedByRequest(endpoint, body) {
2249
+ const ttl = getTtl(endpoint);
2250
+ if (ttl <= 0) return null;
2251
+ const key = cacheKey(endpoint, body);
2252
+ return getCached(key);
2253
+ }
2254
+ function setCache(key, data, ttlMs) {
2255
+ if (ttlMs <= 0) return;
2256
+ try {
2257
+ fs3.mkdirSync(CACHE_DIR, { recursive: true });
2258
+ } catch {
2259
+ }
2260
+ const entry = {
2261
+ cachedAt: Date.now(),
2262
+ response: data,
2263
+ ttlMs
2264
+ };
2265
+ try {
2266
+ fs3.writeFileSync(cachePath(key), JSON.stringify(entry));
2267
+ } catch {
2268
+ }
2269
+ }
2270
+ function saveToCache(endpoint, body, response, costUsd = 0) {
2271
+ const ttl = getTtl(endpoint);
2272
+ if (ttl <= 0) return;
2273
+ try {
2274
+ fs3.mkdirSync(CACHE_DIR, { recursive: true });
2275
+ } catch {
2276
+ }
2277
+ const key = cacheKey(endpoint, body);
2278
+ const entry = {
2279
+ cachedAt: Date.now(),
2280
+ endpoint,
2281
+ body,
2282
+ response,
2283
+ costUsd
2284
+ };
2285
+ try {
2286
+ fs3.writeFileSync(cachePath(key), JSON.stringify(entry));
2287
+ } catch {
2288
+ }
2289
+ }
2290
+ function clearCache() {
2291
+ if (!fs3.existsSync(CACHE_DIR)) return 0;
2292
+ let count = 0;
2293
+ try {
2294
+ const files = fs3.readdirSync(CACHE_DIR);
2295
+ for (const file of files) {
2296
+ if (file.endsWith(".json")) {
2297
+ try {
2298
+ fs3.unlinkSync(path3.join(CACHE_DIR, file));
2299
+ count++;
2300
+ } catch {
2301
+ }
2302
+ }
2303
+ }
2304
+ } catch {
2305
+ }
2306
+ return count;
2307
+ }
2308
+
2309
+ // src/setup.ts
2310
+ function setupAgentWallet(options) {
2311
+ const { address, privateKey, isNew } = getOrCreateWallet();
2312
+ if (isNew && !options?.silent) {
2313
+ console.error(
2314
+ `
2315
+ BlockRun Agent Wallet Created!
2316
+ Address: ${address}
2317
+ Send USDC on Base to get started.
2318
+ `
2319
+ );
2320
+ }
2321
+ return new LLMClient({ privateKey });
2322
+ }
2323
+ async function setupAgentSolanaWallet(options) {
2324
+ const result = await getOrCreateSolanaWallet();
2325
+ if (result.isNew && !options?.silent) {
2326
+ console.error(
2327
+ `
2328
+ BlockRun Solana Agent Wallet Created!
2329
+ Address: ${result.address}
2330
+ Send USDC on Solana to get started.
2331
+ `
2332
+ );
2333
+ }
2334
+ return new SolanaLLMClient({ privateKey: result.privateKey });
2335
+ }
2336
+ async function status() {
2337
+ const client = setupAgentWallet({ silent: true });
2338
+ const address = client.getWalletAddress();
2339
+ const balance = await client.getBalance();
2340
+ console.log(`Wallet: ${address}`);
2341
+ console.log(`Balance: $${balance.toFixed(2)} USDC`);
2342
+ return { address, balance };
2343
+ }
2344
+
2345
+ // src/cost-log.ts
2346
+ import * as fs4 from "fs";
2347
+ import * as path4 from "path";
2348
+ import * as os4 from "os";
2349
+ var DATA_DIR = path4.join(os4.homedir(), ".blockrun", "data");
2350
+ var COST_LOG_FILE = path4.join(DATA_DIR, "costs.jsonl");
2351
+ function logCost(entry) {
2352
+ try {
2353
+ fs4.mkdirSync(DATA_DIR, { recursive: true });
2354
+ } catch {
2355
+ }
2356
+ try {
2357
+ fs4.appendFileSync(COST_LOG_FILE, JSON.stringify(entry) + "\n");
2358
+ } catch {
2359
+ }
2360
+ }
2361
+ function getCostSummary() {
2362
+ if (!fs4.existsSync(COST_LOG_FILE)) {
2363
+ return { totalUsd: 0, calls: 0, byModel: {} };
2364
+ }
2365
+ let totalUsd = 0;
2366
+ let calls = 0;
2367
+ const byModel = {};
2368
+ try {
2369
+ const content = fs4.readFileSync(COST_LOG_FILE, "utf-8").trim();
2370
+ if (!content) return { totalUsd: 0, calls: 0, byModel: {} };
2371
+ for (const line of content.split("\n")) {
2372
+ if (!line) continue;
2373
+ try {
2374
+ const entry = JSON.parse(line);
2375
+ totalUsd += entry.costUsd;
2376
+ calls += 1;
2377
+ byModel[entry.model] = (byModel[entry.model] || 0) + entry.costUsd;
2378
+ } catch {
2379
+ }
2380
+ }
2381
+ } catch {
2382
+ }
2383
+ return { totalUsd, calls, byModel };
2384
+ }
2385
+
1896
2386
  // src/openai-compat.ts
1897
2387
  var StreamingResponse = class {
1898
2388
  reader;
@@ -2078,6 +2568,7 @@ export {
2078
2568
  USDC_SOLANA,
2079
2569
  WALLET_DIR_PATH,
2080
2570
  WALLET_FILE_PATH,
2571
+ clearCache,
2081
2572
  createSolanaPaymentPayload,
2082
2573
  createSolanaWallet,
2083
2574
  createWallet,
@@ -2085,6 +2576,9 @@ export {
2085
2576
  formatFundingMessageCompact,
2086
2577
  formatNeedsFundingMessage,
2087
2578
  formatWalletCreatedMessage,
2579
+ getCached,
2580
+ getCachedByRequest,
2581
+ getCostSummary,
2088
2582
  getEip681Uri,
2089
2583
  getOrCreateSolanaWallet,
2090
2584
  getOrCreateWallet,
@@ -2092,10 +2586,18 @@ export {
2092
2586
  getWalletAddress,
2093
2587
  loadSolanaWallet,
2094
2588
  loadWallet,
2589
+ logCost,
2095
2590
  saveSolanaWallet,
2591
+ saveToCache,
2096
2592
  saveWallet,
2593
+ scanSolanaWallets,
2594
+ scanWallets,
2595
+ setCache,
2596
+ setupAgentSolanaWallet,
2597
+ setupAgentWallet,
2097
2598
  solanaClient,
2098
2599
  solanaKeyToBytes,
2099
2600
  solanaPublicKey,
2601
+ status,
2100
2602
  testnetClient
2101
2603
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "description": "BlockRun LLM Gateway SDK - Pay-per-request AI via x402 on Base",
6
6
  "main": "dist/index.cjs",