lightnode-sdk 0.4.2 → 0.4.3
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.d.ts +3 -3
- package/dist/index.js +4 -2
- package/dist/inference.d.ts +58 -0
- package/dist/inference.js +97 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS } from "./networks.js";
|
|
2
2
|
import { fromWei } from "./subgraph.js";
|
|
3
3
|
import { aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv } from "./analytics.js";
|
|
4
|
-
import { modelId as computeModelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, runInference } from "./inference.js";
|
|
4
|
+
import { modelId as computeModelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, runInference, runInferenceWithKey } from "./inference.js";
|
|
5
5
|
import { StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker } from "./errors.js";
|
|
6
6
|
import { GatewayClient, GatewayHttpError } from "./gateway.js";
|
|
7
7
|
import * as crypto from "./crypto.js";
|
|
@@ -60,7 +60,7 @@ export declare class LightNode {
|
|
|
60
60
|
baseUrl?: string;
|
|
61
61
|
}): GatewayClient;
|
|
62
62
|
}
|
|
63
|
-
export { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS, aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, fromWei, computeModelId as modelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, GatewayClient, GatewayHttpError, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, crypto, runInference, StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, };
|
|
63
|
+
export { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS, aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, fromWei, computeModelId as modelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, GatewayClient, GatewayHttpError, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, crypto, runInference, runInferenceWithKey, StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, };
|
|
64
64
|
export type { BearerSource, GatewayClientOptions, SelectSessionResult, PrepareSessionResult, UploadBlobResult, SessionTokenResult } from "./gateway.js";
|
|
65
|
-
export type { SessionPreparation, RunInferenceArgs, RunInferenceResult } from "./inference.js";
|
|
65
|
+
export type { SessionPreparation, RunInferenceArgs, RunInferenceResult, RunInferenceWithKeyArgs } from "./inference.js";
|
|
66
66
|
export type { NetworkId, NetworkConfig, Worker, Job, ModelInfo, NetworkStats, ModelStat, WorkerStat, NetworkAnalytics };
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS } from "./networks.js";
|
|
|
2
2
|
import { fetchWorker, fetchWorkerJobs, fetchRecentJobs, fetchModels, fetchWorkers, summarize, fromWei, } from "./subgraph.js";
|
|
3
3
|
import { isRegistered } from "./onchain.js";
|
|
4
4
|
import { aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, } from "./analytics.js";
|
|
5
|
-
import { modelId as computeModelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, runInference, } from "./inference.js";
|
|
5
|
+
import { modelId as computeModelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, runInference, runInferenceWithKey, } from "./inference.js";
|
|
6
6
|
import { StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, } from "./errors.js";
|
|
7
7
|
import { GatewayClient, GatewayHttpError } from "./gateway.js";
|
|
8
8
|
import * as crypto from "./crypto.js";
|
|
@@ -94,4 +94,6 @@ export { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS, aggregateModelStats, aggreg
|
|
|
94
94
|
// v0.3 inference-submit surface (BETA - see README "Submitting inference").
|
|
95
95
|
GatewayClient, GatewayHttpError, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, crypto,
|
|
96
96
|
// v0.4 high-level orchestrator: one call, full flow.
|
|
97
|
-
runInference,
|
|
97
|
+
runInference,
|
|
98
|
+
// v0.4.3 key-in-answer-out shortcut: same flow, no viem/SIWE wiring.
|
|
99
|
+
runInferenceWithKey, StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, };
|
package/dist/inference.d.ts
CHANGED
|
@@ -229,3 +229,61 @@ export interface RunInferenceResult {
|
|
|
229
229
|
export declare function runInference(args: RunInferenceArgs): Promise<RunInferenceResult>;
|
|
230
230
|
/** Re-export the typed errors at this layer so a single import covers everything. */
|
|
231
231
|
export { StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker } from "./errors.js";
|
|
232
|
+
import type { NetworkId } from "./types.js";
|
|
233
|
+
export interface RunInferenceWithKeyArgs {
|
|
234
|
+
/** Network ID (`"testnet"` / `"mainnet"`) or a custom NetworkConfig. */
|
|
235
|
+
network: NetworkId | NetworkConfig;
|
|
236
|
+
/**
|
|
237
|
+
* A funded EVM private key, hex with `0x` prefix. Pays the job fee + gas and
|
|
238
|
+
* signs createSession + submitJob. NEVER hardcode this - load from env.
|
|
239
|
+
*/
|
|
240
|
+
privateKey: string;
|
|
241
|
+
/** The plaintext prompt to send. UTF-8 encoded before encryption. */
|
|
242
|
+
prompt: string;
|
|
243
|
+
/** Inference model tag. Default: `"llama3-8b"`. */
|
|
244
|
+
model?: string;
|
|
245
|
+
/**
|
|
246
|
+
* Streaming callback invoked once per decrypted relay chunk. Use for live
|
|
247
|
+
* stdout / UI updates. Optional - the final `answer` is returned either way.
|
|
248
|
+
*/
|
|
249
|
+
onChunk?: (chunk: string, totalSoFar: string) => void;
|
|
250
|
+
/** Retry count if a worker stalls. Default 2 (so up to 3 paid attempts). */
|
|
251
|
+
maxRetries?: number;
|
|
252
|
+
/** How long to wait for JobCompleted before declaring the worker stalled. Default 120s. */
|
|
253
|
+
jobCompletedTimeoutMs?: number;
|
|
254
|
+
/**
|
|
255
|
+
* WebSocket constructor. In a browser this is auto-detected from
|
|
256
|
+
* `globalThis.WebSocket`. In Node, pass `WS` from the `ws` package
|
|
257
|
+
* (`import WS from "ws"`) - `ws` is not a hard dep of this SDK.
|
|
258
|
+
*/
|
|
259
|
+
WebSocket?: WebSocketCtor;
|
|
260
|
+
/** Override the relay URL (defaults to `wss://relay.<network>.lightchain.ai/ws`). */
|
|
261
|
+
relayUrl?: string;
|
|
262
|
+
/**
|
|
263
|
+
* Override the consumer-api gateway URL. Defaults to a network-derived URL.
|
|
264
|
+
* Useful for tests / mirrors / proxying through your own backend.
|
|
265
|
+
*/
|
|
266
|
+
gatewayUrl?: string;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* One call, key-in / answer-out encrypted inference. Builds viem clients,
|
|
270
|
+
* runs the SIWE handshake, opens the encrypted session, submits + decrypts,
|
|
271
|
+
* and returns. Same proof chain (`createSession`, `submitJob`, `jobCompleted`)
|
|
272
|
+
* as the lower-level `runInference`.
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```ts
|
|
276
|
+
* import { runInferenceWithKey } from "lightnode-sdk";
|
|
277
|
+
* import WS from "ws";
|
|
278
|
+
*
|
|
279
|
+
* const { answer, txs } = await runInferenceWithKey({
|
|
280
|
+
* network: "testnet",
|
|
281
|
+
* privateKey: process.env.PRIVATE_KEY!,
|
|
282
|
+
* prompt: "Reply with a one-sentence fun fact about the ocean.",
|
|
283
|
+
* WebSocket: WS, // omit in the browser
|
|
284
|
+
* });
|
|
285
|
+
*
|
|
286
|
+
* console.log(answer);
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
289
|
+
export declare function runInferenceWithKey(args: RunInferenceWithKeyArgs): Promise<RunInferenceResult>;
|
package/dist/inference.js
CHANGED
|
@@ -434,3 +434,100 @@ export async function runInference(args) {
|
|
|
434
434
|
}
|
|
435
435
|
/** Re-export the typed errors at this layer so a single import covers everything. */
|
|
436
436
|
export { StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker } from "./errors.js";
|
|
437
|
+
import { NETWORKS } from "./networks.js";
|
|
438
|
+
import { GatewayClient as GatewayClientCtor, consumerGatewayUrl as consumerGatewayUrlFn } from "./gateway.js";
|
|
439
|
+
import { GatewayAuthError } from "./errors.js";
|
|
440
|
+
import { createPublicClient as viemCreatePublicClient, createWalletClient as viemCreateWalletClient, http as viemHttp } from "viem";
|
|
441
|
+
import { privateKeyToAccount as viemPrivateKeyToAccount } from "viem/accounts";
|
|
442
|
+
/**
|
|
443
|
+
* One call, key-in / answer-out encrypted inference. Builds viem clients,
|
|
444
|
+
* runs the SIWE handshake, opens the encrypted session, submits + decrypts,
|
|
445
|
+
* and returns. Same proof chain (`createSession`, `submitJob`, `jobCompleted`)
|
|
446
|
+
* as the lower-level `runInference`.
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* ```ts
|
|
450
|
+
* import { runInferenceWithKey } from "lightnode-sdk";
|
|
451
|
+
* import WS from "ws";
|
|
452
|
+
*
|
|
453
|
+
* const { answer, txs } = await runInferenceWithKey({
|
|
454
|
+
* network: "testnet",
|
|
455
|
+
* privateKey: process.env.PRIVATE_KEY!,
|
|
456
|
+
* prompt: "Reply with a one-sentence fun fact about the ocean.",
|
|
457
|
+
* WebSocket: WS, // omit in the browser
|
|
458
|
+
* });
|
|
459
|
+
*
|
|
460
|
+
* console.log(answer);
|
|
461
|
+
* ```
|
|
462
|
+
*/
|
|
463
|
+
export async function runInferenceWithKey(args) {
|
|
464
|
+
// Resolve the network config and validate the key shape up front so a
|
|
465
|
+
// mistyped key fails BEFORE we touch the RPC or the gateway.
|
|
466
|
+
const network = typeof args.network === "string" ? NETWORKS[args.network] : args.network;
|
|
467
|
+
if (!network)
|
|
468
|
+
throw new Error(`unknown network: ${String(args.network)}`);
|
|
469
|
+
const networkId = (typeof args.network === "string" ? args.network : "mainnet");
|
|
470
|
+
const key = args.privateKey?.trim();
|
|
471
|
+
if (!key || !key.startsWith("0x") || key.length !== 66) {
|
|
472
|
+
throw new Error("runInferenceWithKey: privateKey must be a 0x-prefixed 32-byte hex string");
|
|
473
|
+
}
|
|
474
|
+
const account = viemPrivateKeyToAccount(key);
|
|
475
|
+
const chain = {
|
|
476
|
+
id: network.chainId,
|
|
477
|
+
name: network.label,
|
|
478
|
+
nativeCurrency: { name: "LCAI", symbol: "LCAI", decimals: 18 },
|
|
479
|
+
rpcUrls: { default: { http: [network.rpc] } },
|
|
480
|
+
};
|
|
481
|
+
// Keep viem's real types here so signMessage / etc. are typed. The MinimalX
|
|
482
|
+
// casts only happen at the runInference() call site below.
|
|
483
|
+
const publicClient = viemCreatePublicClient({ transport: viemHttp(network.rpc), chain });
|
|
484
|
+
const wallet = viemCreateWalletClient({ account, transport: viemHttp(network.rpc), chain });
|
|
485
|
+
// One-shot SIWE handshake. We do this inline (rather than re-export it) so
|
|
486
|
+
// the caller doesn't need a second import; in browsers + Node it works the
|
|
487
|
+
// same against the consumer-api gateway.
|
|
488
|
+
const gwBase = args.gatewayUrl ?? consumerGatewayUrlFn(networkId);
|
|
489
|
+
const chRes = await fetch(`${gwBase}/api/auth/challenge?address=${account.address}`, {
|
|
490
|
+
headers: { Accept: "application/json" },
|
|
491
|
+
});
|
|
492
|
+
if (!chRes.ok)
|
|
493
|
+
throw new GatewayAuthError(chRes.status, await chRes.text());
|
|
494
|
+
const ch = (await chRes.json());
|
|
495
|
+
if (!ch.message)
|
|
496
|
+
throw new GatewayAuthError(chRes.status, "auth challenge returned no message");
|
|
497
|
+
const signature = await wallet.signMessage({ account, message: ch.message });
|
|
498
|
+
const verifyRes = await fetch(`${gwBase}/api/auth/verify`, {
|
|
499
|
+
method: "POST",
|
|
500
|
+
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
501
|
+
body: JSON.stringify({ message: ch.message, signature }),
|
|
502
|
+
});
|
|
503
|
+
if (!verifyRes.ok)
|
|
504
|
+
throw new GatewayAuthError(verifyRes.status, await verifyRes.text());
|
|
505
|
+
const verify = (await verifyRes.json());
|
|
506
|
+
if (!verify.token)
|
|
507
|
+
throw new GatewayAuthError(verifyRes.status, "auth verify returned no token");
|
|
508
|
+
const gateway = new GatewayClientCtor({ network: networkId, bearer: verify.token, baseUrl: args.gatewayUrl });
|
|
509
|
+
// Pick a WebSocket: the browser global if present, otherwise the caller-
|
|
510
|
+
// supplied ctor. We deliberately do NOT try to dynamic-import "ws" - it
|
|
511
|
+
// isn't a hard dep, and a bundler trying to resolve it would fail noisily.
|
|
512
|
+
const wsCtor = args.WebSocket ??
|
|
513
|
+
(typeof globalThis !== "undefined" && globalThis.WebSocket
|
|
514
|
+
? globalThis.WebSocket
|
|
515
|
+
: undefined);
|
|
516
|
+
if (!wsCtor) {
|
|
517
|
+
throw new Error("runInferenceWithKey: no WebSocket constructor available. In Node, install `ws` and pass it: " +
|
|
518
|
+
"`import WS from 'ws'; runInferenceWithKey({ WebSocket: WS, ... })`");
|
|
519
|
+
}
|
|
520
|
+
return runInference({
|
|
521
|
+
prompt: args.prompt,
|
|
522
|
+
gateway,
|
|
523
|
+
wallet: wallet,
|
|
524
|
+
publicClient: publicClient,
|
|
525
|
+
network,
|
|
526
|
+
model: args.model,
|
|
527
|
+
onChunk: args.onChunk,
|
|
528
|
+
maxRetries: args.maxRetries,
|
|
529
|
+
jobCompletedTimeoutMs: args.jobCompletedTimeoutMs,
|
|
530
|
+
WebSocket: wsCtor,
|
|
531
|
+
relayUrl: args.relayUrl,
|
|
532
|
+
});
|
|
533
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lightnode-sdk",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
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",
|