lightnode-sdk 0.7.10 → 0.7.12
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/auth.d.ts +3 -0
- package/dist/auth.js +34 -8
- package/dist/gateway.d.ts +20 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/inference.js +8 -0
- package/package.json +1 -1
package/dist/auth.d.ts
CHANGED
|
@@ -76,6 +76,7 @@ export interface SiweSession {
|
|
|
76
76
|
*/
|
|
77
77
|
export declare function siweChallenge(network: NetworkId | NetworkConfig, address: `0x${string}`, opts?: {
|
|
78
78
|
signal?: AbortSignal;
|
|
79
|
+
baseUrl?: string;
|
|
79
80
|
}): Promise<SiweChallenge>;
|
|
80
81
|
/**
|
|
81
82
|
* Verify a signed SIWE message and mint a JWT bearer.
|
|
@@ -85,6 +86,7 @@ export declare function siweVerify(network: NetworkId | NetworkConfig, args: {
|
|
|
85
86
|
signature: `0x${string}`;
|
|
86
87
|
}, opts?: {
|
|
87
88
|
signal?: AbortSignal;
|
|
89
|
+
baseUrl?: string;
|
|
88
90
|
}): Promise<SiweVerifyResult>;
|
|
89
91
|
/**
|
|
90
92
|
* End-to-end SIWE sign-in: challenge -> sign -> verify -> JWT.
|
|
@@ -103,4 +105,5 @@ export declare function siweVerify(network: NetworkId | NetworkConfig, args: {
|
|
|
103
105
|
export declare function siweSignIn(walletClient: SiweWalletClient, network: NetworkId | NetworkConfig, opts?: {
|
|
104
106
|
address?: `0x${string}`;
|
|
105
107
|
signal?: AbortSignal;
|
|
108
|
+
baseUrl?: string;
|
|
106
109
|
}): Promise<SiweSession>;
|
package/dist/auth.js
CHANGED
|
@@ -21,6 +21,26 @@
|
|
|
21
21
|
* can refresh proactively.
|
|
22
22
|
*/
|
|
23
23
|
import { NETWORKS } from "./networks.js";
|
|
24
|
+
// Same logic as gateway.ts: in a browser-like runtime the consumer-api's
|
|
25
|
+
// CORS allowlist excludes most origins, so we route the SIWE handshake
|
|
26
|
+
// through lightnode.app's public pass-through proxy. The proxy preserves
|
|
27
|
+
// the upstream `/api/auth/{challenge,verify}` shape, so callers do not
|
|
28
|
+
// have to special-case it.
|
|
29
|
+
const PROXY_HOSTS = {
|
|
30
|
+
mainnet: "https://lightnode.app/api/gw/mainnet",
|
|
31
|
+
testnet: "https://lightnode.app/api/gw/testnet",
|
|
32
|
+
};
|
|
33
|
+
function looksLikeBrowserFetch() {
|
|
34
|
+
if (typeof window !== "undefined" && typeof document !== "undefined")
|
|
35
|
+
return true;
|
|
36
|
+
const wc = globalThis.process?.versions?.webcontainer;
|
|
37
|
+
return Boolean(wc);
|
|
38
|
+
}
|
|
39
|
+
function defaultSiweBase(cfg) {
|
|
40
|
+
if (looksLikeBrowserFetch())
|
|
41
|
+
return PROXY_HOSTS[cfg.id];
|
|
42
|
+
return cfg.consumerApi ?? "";
|
|
43
|
+
}
|
|
24
44
|
const REQUEST_TIMEOUT_MS = 15000;
|
|
25
45
|
function resolveNetwork(network) {
|
|
26
46
|
if (typeof network === "string") {
|
|
@@ -68,10 +88,15 @@ async function httpJson(url, init) {
|
|
|
68
88
|
*/
|
|
69
89
|
export async function siweChallenge(network, address, opts = {}) {
|
|
70
90
|
const cfg = resolveNetwork(network);
|
|
71
|
-
|
|
72
|
-
|
|
91
|
+
// baseUrl override lets a browser caller route through a different
|
|
92
|
+
// proxy. By default the SDK auto-routes browser traffic through
|
|
93
|
+
// lightnode.app's pass-through proxy (the consumer-api's CORS allowlist
|
|
94
|
+
// excludes most origins). Server-side, we hit the consumer-api direct.
|
|
95
|
+
const base = (opts.baseUrl ?? defaultSiweBase(cfg)).replace(/\/+$/, "");
|
|
96
|
+
if (!base) {
|
|
97
|
+
throw new Error(`siweChallenge: network "${cfg.id}" has no consumerApi configured (and no baseUrl override)`);
|
|
73
98
|
}
|
|
74
|
-
const url = `${
|
|
99
|
+
const url = `${base}/api/auth/challenge?address=${address}`;
|
|
75
100
|
return httpJson(url, { method: "GET", signal: opts.signal });
|
|
76
101
|
}
|
|
77
102
|
/**
|
|
@@ -79,10 +104,11 @@ export async function siweChallenge(network, address, opts = {}) {
|
|
|
79
104
|
*/
|
|
80
105
|
export async function siweVerify(network, args, opts = {}) {
|
|
81
106
|
const cfg = resolveNetwork(network);
|
|
82
|
-
|
|
83
|
-
|
|
107
|
+
const base = (opts.baseUrl ?? defaultSiweBase(cfg)).replace(/\/+$/, "");
|
|
108
|
+
if (!base) {
|
|
109
|
+
throw new Error(`siweVerify: network "${cfg.id}" has no consumerApi configured (and no baseUrl override)`);
|
|
84
110
|
}
|
|
85
|
-
const url = `${
|
|
111
|
+
const url = `${base}/api/auth/verify`;
|
|
86
112
|
const out = await httpJson(url, {
|
|
87
113
|
method: "POST",
|
|
88
114
|
body: { message: args.message, signature: args.signature },
|
|
@@ -125,14 +151,14 @@ export async function siweSignIn(walletClient, network, opts = {}) {
|
|
|
125
151
|
if (!address) {
|
|
126
152
|
throw new Error("siweSignIn: walletClient has no account; pass `address` explicitly");
|
|
127
153
|
}
|
|
128
|
-
const { message } = await siweChallenge(cfg, address, { signal: opts.signal });
|
|
154
|
+
const { message } = await siweChallenge(cfg, address, { signal: opts.signal, baseUrl: opts.baseUrl });
|
|
129
155
|
// viem's signMessage requires `account` even when one is set on the
|
|
130
156
|
// client; passing it explicitly works with both wagmi and bare viem.
|
|
131
157
|
const signature = await walletClient.signMessage({
|
|
132
158
|
account: walletClient.account?.address ?? address,
|
|
133
159
|
message,
|
|
134
160
|
});
|
|
135
|
-
const verified = await siweVerify(cfg, { message, signature }, { signal: opts.signal });
|
|
161
|
+
const verified = await siweVerify(cfg, { message, signature }, { signal: opts.signal, baseUrl: opts.baseUrl });
|
|
136
162
|
const token = verified.token;
|
|
137
163
|
return {
|
|
138
164
|
token,
|
package/dist/gateway.d.ts
CHANGED
|
@@ -35,6 +35,19 @@ export interface SelectSessionResult {
|
|
|
35
35
|
disputerEncryptionKey?: string;
|
|
36
36
|
nonce: number;
|
|
37
37
|
expiry: number;
|
|
38
|
+
/**
|
|
39
|
+
* Opaque correlation token added by the dispatcher in May 2026
|
|
40
|
+
* (lcai-chat-v2 commit 33c70841, web-search epic / Story 16). The client
|
|
41
|
+
* MUST echo it back to `prepareSession` so a later capability-aware
|
|
42
|
+
* select cannot overwrite our pending slot. Optional for forward-compat
|
|
43
|
+
* with older dispatchers that predate the token.
|
|
44
|
+
*
|
|
45
|
+
* Without this, any concurrent activity for the same wallet produces a
|
|
46
|
+
* 409 selection_mismatch on prepare.
|
|
47
|
+
*/
|
|
48
|
+
selectionId?: string;
|
|
49
|
+
/** Worker capabilities reported by the dispatcher (web-search etc.). */
|
|
50
|
+
workerCapabilities?: string[];
|
|
38
51
|
}
|
|
39
52
|
export interface PrepareSessionResult {
|
|
40
53
|
worker: `0x${string}`;
|
|
@@ -95,6 +108,13 @@ export declare class GatewayClient {
|
|
|
95
108
|
modelId: `0x${string}`;
|
|
96
109
|
encWorkerKey: string;
|
|
97
110
|
encDisputerKey: string;
|
|
111
|
+
/**
|
|
112
|
+
* Correlation token from {@link SelectSessionResult.selectionId}. Required
|
|
113
|
+
* by the May 2026 dispatcher to avoid 409 selection_mismatch when a newer
|
|
114
|
+
* select for the same wallet has overwritten the pending slot.
|
|
115
|
+
*/
|
|
116
|
+
selectionId?: string;
|
|
117
|
+
requiredCapabilities?: string[];
|
|
98
118
|
}): Promise<PrepareSessionResult>;
|
|
99
119
|
/** Protected: upload an encrypted prompt blob; returns the EIP-4844 blob hash. */
|
|
100
120
|
uploadBlob(base64Data: string): Promise<UploadBlobResult>;
|
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.
|
|
137
|
+
export declare const SDK_VERSION = "0.7.12";
|
|
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.
|
|
216
|
+
export const SDK_VERSION = "0.7.12";
|
|
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/dist/inference.js
CHANGED
|
@@ -107,10 +107,18 @@ export async function prepareSession(gateway, modelTag) {
|
|
|
107
107
|
const encDisputer = selected.disputerEncryptionKey
|
|
108
108
|
? await encryptSessionKey(sessionKey, await importPublicKey(decodePublicKey(selected.disputerEncryptionKey)))
|
|
109
109
|
: new Uint8Array(0);
|
|
110
|
+
// ROOT-CAUSE FIX (lcai-chat-v2 commit 33c70841, May 2026): echo the
|
|
111
|
+
// dispatcher's selectionId from selectSession back into prepareSession.
|
|
112
|
+
// Without this, the dispatcher's pending-slot tracker matches against
|
|
113
|
+
// the LATEST select for our wallet, so any concurrent activity (other
|
|
114
|
+
// tab, other dApp signed into the same wallet) produces 409
|
|
115
|
+
// selection_mismatch. Threading it makes the prepare bind to the
|
|
116
|
+
// selection we actually got.
|
|
110
117
|
const prepared = await gateway.prepareSession({
|
|
111
118
|
modelId: id,
|
|
112
119
|
encWorkerKey: bytesToBase64(encWorker),
|
|
113
120
|
encDisputerKey: bytesToBase64(encDisputer),
|
|
121
|
+
...(selected.selectionId ? { selectionId: selected.selectionId } : {}),
|
|
114
122
|
});
|
|
115
123
|
return {
|
|
116
124
|
sessionKey,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lightnode-sdk",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.12",
|
|
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",
|