lightnode-sdk 0.7.18 → 0.7.20

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
@@ -464,17 +464,35 @@ PRIVATE_KEY=0x... npx lightnode worker deregister --yes # clear stuck + settl
464
464
 
465
465
  ### Scaffolders (write files into your project)
466
466
 
467
+ Server-paid (you host a backend; your funded wallet pays per call):
468
+
467
469
  ```bash
468
470
  npx lightnode add inference # encrypted inference route or script
469
471
  npx lightnode add chat # chat UI with conversation history
472
+ npx lightnode add judge # pass/fail evaluator route (criteria + evidence)
470
473
  npx lightnode add agent # scheduled inference (Vercel Cron / setInterval)
471
474
  npx lightnode add analytics-dashboard # read-only network + worker analytics page
472
475
  npx lightnode add nft-mint-with-inference # AI-generated NFT metadata with on-chain provenance
473
476
  ```
474
477
 
478
+ User-paid (no backend; each visitor signs + pays from their own wallet):
479
+
480
+ ```bash
481
+ npx lightnode add inference-web3 # one-shot inference UI, wallet-signed
482
+ npx lightnode add chat-web3 # chat UI, wallet-signed (mainnet + testnet aware)
483
+ npx lightnode add judge-web3 # evaluator UI, wallet-signed
484
+ npx lightnode add wagmi-setup # wallet wiring: lib/wagmi + providers + connect button
485
+ ```
486
+
487
+ The `*-web3` scaffolders and `wagmi-setup` write Next.js pages, so run them
488
+ inside a Next.js app (`npx create-next-app@latest .` first if you have none).
489
+
475
490
  All `add` commands accept `--template auto|nextjs-api|hono|node`,
476
491
  `--net testnet|mainnet`, and `--force`.
477
492
 
493
+ > If `add <name>` reports an unknown target, your `npx` cache is serving an
494
+ > older CLI. Force the current release: `npx lightnode-sdk@latest add <name>`.
495
+
478
496
  ## Networks
479
497
 
480
498
  | | Testnet | Mainnet |
package/dist/add.js CHANGED
@@ -321,6 +321,17 @@ function depsNeeded(template) {
321
321
  // installed too, otherwise `tsx ...` fails with "command not found".
322
322
  return ["lightnode-sdk", "viem", "ws", "tsx"];
323
323
  }
324
+ /** Full `npm install` line for a template's next-steps, including the dev type
325
+ * packages an editor needs. The node/script template uses Node builtins
326
+ * (`node:process`, `node:readline`) and imports `ws`, so without @types/node
327
+ * and @types/ws a freshly-scaffolded file is a wall of red squiggles in any
328
+ * TypeScript-aware editor even though `tsx` runs it fine. */
329
+ function installLine(template) {
330
+ const runtime = `npm install ${depsNeeded(template).join(" ")}`;
331
+ if (template === "node")
332
+ return `${runtime} && npm install -D @types/node @types/ws`;
333
+ return runtime;
334
+ }
324
335
  /**
325
336
  * Implementation called by `lightnode add inference [...]`.
326
337
  * Returns the list of files written + the install command the user should run.
@@ -347,7 +358,7 @@ export function addInference(opts = {}) {
347
358
  written.push(writeFile(path.join(cwd, ".env.example"), ENV_EXAMPLE(network), force));
348
359
  return {
349
360
  written,
350
- install: `npm install ${depsNeeded(template).join(" ")}`,
361
+ install: installLine(template),
351
362
  template,
352
363
  network,
353
364
  };
@@ -1708,7 +1719,7 @@ export function addAgent(opts = {}) {
1708
1719
  written.push(writeFile(path.join(cwd, "agent.ts"), NODE_AGENT_SCRIPT, force));
1709
1720
  }
1710
1721
  written.push(writeFile(path.join(cwd, ".env.example"), ENV_EXAMPLE(network), force));
1711
- return { written, install: `npm install ${depsNeeded(template).join(" ")}`, template, network };
1722
+ return { written, install: installLine(template), template, network };
1712
1723
  }
1713
1724
  export function addChat(opts = {}) {
1714
1725
  const cwd = opts.cwd ?? process.cwd();
@@ -1732,7 +1743,7 @@ export function addChat(opts = {}) {
1732
1743
  written.push(writeFile(path.join(cwd, "chat-repl.ts"), NODE_CHAT_REPL, force));
1733
1744
  }
1734
1745
  written.push(writeFile(path.join(cwd, ".env.example"), ENV_EXAMPLE(network), force));
1735
- return { written, install: `npm install ${depsNeeded(template).join(" ")}`, template, network };
1746
+ return { written, install: installLine(template), template, network };
1736
1747
  }
1737
1748
  /**
1738
1749
  * `lightnode add chat-web3` - the user-pays counterpart to addChat.
@@ -2114,7 +2125,7 @@ export function addJudge(opts = {}) {
2114
2125
  written.push(writeFile(path.join(cwd, "judge.ts"), NODE_JUDGE_SCRIPT, force));
2115
2126
  }
2116
2127
  written.push(writeFile(path.join(cwd, ".env.example"), ENV_EXAMPLE(network), force));
2117
- return { written, install: `npm install ${depsNeeded(template).join(" ")}`, template, network };
2128
+ return { written, install: installLine(template), template, network };
2118
2129
  }
2119
2130
  export function addNftMint(opts = {}) {
2120
2131
  const cwd = opts.cwd ?? process.cwd();
@@ -2132,7 +2143,7 @@ export function addNftMint(opts = {}) {
2132
2143
  written.push(writeFile(path.join(cwd, ".env.example"), ENV_EXAMPLE(network), force));
2133
2144
  return {
2134
2145
  written,
2135
- install: `npm install ${depsNeeded(template).join(" ")}`,
2146
+ install: installLine(template),
2136
2147
  template,
2137
2148
  network,
2138
2149
  };
package/dist/cli.js CHANGED
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { LightNode, modelStatsCsv, workerStatsCsv, workerJobsCsv, runInferenceWithKey, runInferenceBatch, Agent, isStalledWorker, workerPreflight, workerWatch, WorkerOperator, isWorkerOpError, BRIDGE_ROUTE, DAO, DAO_ADDRESSES } from "./index.js";
2
+ import { LightNode, modelStatsCsv, workerStatsCsv, workerJobsCsv, runInferenceWithKey, runInferenceBatch, Agent, isStalledWorker, workerPreflight, workerWatch, WorkerOperator, isWorkerOpError, BRIDGE_ROUTE, DAO, DAO_ADDRESSES, SDK_VERSION } from "./index.js";
3
3
  import { addInference, addInferenceWeb3, addJudgeWeb3, addAnalyticsDashboard, addNftMint, addChat, addChatWeb3, addAgent, addJudge, addWagmiSetup } from "./add.js";
4
4
  import { createPublicClient, createWalletClient, http, parseEther } from "viem";
5
5
  import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
6
+ import { existsSync } from "node:fs";
7
+ import { join } from "node:path";
6
8
  function flag(name) {
7
9
  const i = process.argv.indexOf(name);
8
10
  return i >= 0 ? process.argv[i + 1] : undefined;
@@ -62,15 +64,27 @@ Ecosystem (read-only):
62
64
  dao addresses print LCAI Governor + Timelock + Treasury addresses
63
65
  dao config print voting delay / period / threshold (live read)
64
66
 
65
- Scaffold templates into the current project:
66
- add inference end-to-end encrypted inference route/script
67
- add chat chat-style UI with conversation history
68
- add agent scheduled/loop inference (cron-style)
69
- add analytics-dashboard read-only network + worker analytics page
70
- add nft-mint-with-inference AI-generated NFT metadata (provenance on-chain)
71
- (all add commands: [--template auto|nextjs-api|hono|node] [--force])
67
+ Scaffold templates into the current project (run inside a Next.js app):
68
+ Server-paid (you host a backend; your funded wallet pays per call):
69
+ add inference end-to-end encrypted inference route/script
70
+ add chat chat-style UI with conversation history
71
+ add judge pass/fail evaluator route (criteria + evidence)
72
+ add agent scheduled/loop inference (cron-style)
73
+ add analytics-dashboard read-only network + worker analytics page
74
+ add nft-mint-with-inference AI-generated NFT metadata (provenance on-chain)
75
+ User-paid (no backend; each visitor signs + pays from their own wallet):
76
+ add inference-web3 one-shot inference UI, wallet-signed
77
+ add chat-web3 chat UI, wallet-signed (mainnet + testnet aware)
78
+ add judge-web3 evaluator UI, wallet-signed
79
+ add wagmi-setup wallet wiring: lib/wagmi + providers + connect button
80
+ (all add commands: [--template auto|nextjs-api|hono|node] [--net testnet|mainnet] [--force])
72
81
 
73
- To scaffold a new project instead, run: npm create lightnode-app my-app`;
82
+ To scaffold a new project instead, run: npm create lightnode-app my-app
83
+
84
+ Diagnostics:
85
+ version print this CLI's version (also: --version, -v)
86
+ (a missing 'add' target usually means an old install -
87
+ update with: npm install -g lightnode-sdk@latest)`;
74
88
  function pickKey() {
75
89
  const k = flag("--key") ?? process.env.PRIVATE_KEY;
76
90
  if (!k || !k.startsWith("0x") || k.length !== 66) {
@@ -113,6 +127,14 @@ async function workerJobIds(n, address) {
113
127
  return jobs.map((j) => Number(j.id)).filter((x) => Number.isFinite(x));
114
128
  }
115
129
  async function main() {
130
+ // Answer `version` / `--version` / `-v` before anything else so a user who
131
+ // suspects they're on a stale binary can confirm it without a network call
132
+ // or a funded key. This is the first thing to check when an `add` target
133
+ // "doesn't exist" - an old global install is the common cause.
134
+ if (cmd === "version" || process.argv.includes("--version") || process.argv.includes("-v")) {
135
+ console.log(SDK_VERSION);
136
+ return;
137
+ }
116
138
  const ln = new LightNode(net);
117
139
  switch (cmd) {
118
140
  case "chat": {
@@ -464,7 +486,24 @@ async function main() {
464
486
  const network = (net === "mainnet" ? "mainnet" : "testnet");
465
487
  const known = ["inference", "inference-web3", "chat", "chat-web3", "judge", "judge-web3", "wagmi-setup", "agent", "analytics-dashboard", "nft-mint-with-inference"];
466
488
  if (!known.includes(sub ?? "")) {
467
- die(`usage: lightnode add <${known.join("|")}> [--template auto|nextjs-api|hono|node] [--net testnet|mainnet] [--force]`);
489
+ const lines = [
490
+ `usage: lightnode add <${known.join("|")}> [--template auto|nextjs-api|hono|node] [--net testnet|mainnet] [--force]`,
491
+ ];
492
+ // A target that's missing here but valid in a newer release means the
493
+ // user is running an OLD lightnode-sdk. The usual cause is an outdated
494
+ // GLOBAL install (`npm i -g lightnode-sdk`) on PATH, which npx prefers
495
+ // over the registry - so `npx lightnode-sdk add ...` keeps hitting the
496
+ // stale binary. We can't know the latest version offline, but we can
497
+ // show what THIS binary is and the two commands that fix it. Listing
498
+ // the global update first because that's the one most people miss.
499
+ if (sub) {
500
+ lines.push("");
501
+ lines.push(`unknown add target "${sub}" - this CLI is lightnode-sdk v${SDK_VERSION}, which`);
502
+ lines.push(`does not have it. You're likely on an older install. Update, then retry:`);
503
+ lines.push(` npm install -g lightnode-sdk@latest # if 'lightnode' is on your PATH`);
504
+ lines.push(` npx lightnode-sdk@latest add ${sub} # or force the latest for one run`);
505
+ }
506
+ die(lines.join("\n"));
468
507
  }
469
508
  const result = sub === "analytics-dashboard" ? addAnalyticsDashboard({ template, network, force })
470
509
  : sub === "nft-mint-with-inference" ? addNftMint({ template, network, force })
@@ -488,6 +527,26 @@ async function main() {
488
527
  console.log("\nNothing to do - all target files already exist. Pass --force to overwrite.");
489
528
  }
490
529
  else {
530
+ // The *-web3 pages and wagmi-setup are Next.js React files. If no
531
+ // Next.js app was detected (e.g. an empty folder), nothing can render
532
+ // what we just wrote - surface that before the numbered steps so the
533
+ // user scaffolds an app first instead of chasing a non-running page.
534
+ const isNextOnly = sub === "chat-web3" || sub === "inference-web3" || sub === "judge-web3" || sub === "wagmi-setup";
535
+ const hasPackageJson = existsSync(join(process.cwd(), "package.json"));
536
+ if (isNextOnly && result.template !== "nextjs-api") {
537
+ console.log(`\nNo Next.js app detected in this folder. ${sub} is a Next.js page, so`);
538
+ console.log(`create one here first, then re-run this command:`);
539
+ console.log(` npx create-next-app@latest .`);
540
+ }
541
+ else if (!hasPackageJson) {
542
+ // A scaffolded script dropped into a bare folder (no package.json)
543
+ // gives the editor nothing to resolve Node/ws types against - the
544
+ // user sees "Cannot find name 'process'" everywhere. Initialize a
545
+ // project first so the install below lands in a real node_modules.
546
+ console.log(`\nNo package.json in this folder yet, so your editor can't resolve types`);
547
+ console.log(`(you'd see "Cannot find name 'process'" etc.). Initialize a project first:`);
548
+ console.log(` npm init -y`);
549
+ }
491
550
  console.log(`\nNext steps (these files were added to your CURRENT folder, not a new project):`);
492
551
  console.log(` 1. ${result.install}`);
493
552
  if (sub === "wagmi-setup") {
package/dist/index.d.ts CHANGED
@@ -134,7 +134,7 @@ export declare class LightNode {
134
134
  * (especially in registry-proxy environments like StackBlitz where lockfiles
135
135
  * may pin an older minor than the local install command suggests).
136
136
  */
137
- export declare const SDK_VERSION = "0.7.18";
137
+ export declare const SDK_VERSION = "0.7.20";
138
138
  export { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS, aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, fromWei, resolveJobTransactions, siweSignIn, siweChallenge, siweVerify, fetchWorkerModels, computeModelId as modelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost, GatewayClient, GatewayHttpError, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, crypto, runInference, runInferenceWithKey, runInferenceStream, Conversation, chat, runInferenceBatch, Agent, parseAgentOutput, workerPreflight, workerWatch, Bridge, BRIDGE_ROUTE, HYPERLANE_ROUTER_ABI, ERC20_ABI, addressToBytes32, quoteBridgeFee, bridgeableBalance, bridgeAllowance, approveBridge, bridgeTransfer, DAO, DAO_ADDRESSES, ProposalState, PROPOSAL_STATE_LABEL, VoteSupport, GOVERNOR_ABI, VOTES_ABI, OnchainModelRegistry, AIVM_MODEL_REGISTRY_ABI, BENCHMARK_REGISTRY_ABI, ModelStatus, MODEL_STATUS_LABEL, StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, WorkerOperator, WORKER_REGISTRY_ABI, JOB_REGISTRY_OPERATOR_ABI, AI_CONFIG_ABI, JOB_STATE, decodeWorkerError, WorkerOpError, isWorkerOpError, };
139
139
  export type { BearerSource, GatewayClientOptions, SelectSessionResult, PrepareSessionResult, UploadBlobResult, SessionTokenResult } from "./gateway.js";
140
140
  export type { SessionPreparation, RunInferenceArgs, RunInferenceResult, RunInferenceWithKeyArgs, RunInferenceStreamResult } from "./inference.js";
package/dist/index.js CHANGED
@@ -213,7 +213,7 @@ export class LightNode {
213
213
  * (especially in registry-proxy environments like StackBlitz where lockfiles
214
214
  * may pin an older minor than the local install command suggests).
215
215
  */
216
- export const SDK_VERSION = "0.7.18";
216
+ export const SDK_VERSION = "0.7.20";
217
217
  export { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS, aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, fromWei,
218
218
  // v0.7.3 per-job transaction-hash resolver (lifts the upstream
219
219
  // subgraph's "block-only" Job entity to a deep-linkable Job + tx pair).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lightnode-sdk",
3
- "version": "0.7.18",
3
+ "version": "0.7.20",
4
4
  "description": "Read-only TypeScript client for LightChain AI: workers, jobs, models, on-chain registration, and per-model network analytics. Independent, community-built (not an official LightChain package).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",