lightnode-sdk 0.4.9 → 0.5.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/bridge.d.ts +233 -0
- package/dist/bridge.js +201 -0
- package/dist/chat.d.ts +70 -0
- package/dist/chat.js +88 -0
- package/dist/cli.js +105 -2
- package/dist/dao.d.ts +439 -0
- package/dist/dao.js +234 -0
- package/dist/index.d.ts +29 -2
- package/dist/index.js +60 -3
- package/dist/onchain-models.d.ts +380 -0
- package/dist/onchain-models.js +187 -0
- package/dist/subgraph.d.ts +2 -0
- package/dist/subgraph.js +6 -0
- package/dist/worker.d.ts +104 -0
- package/dist/worker.js +186 -0
- package/package.json +1 -1
package/dist/dao.js
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DAO SDK: typed wrapper around the LCAI Governor (OpenZeppelin Governor v5)
|
|
3
|
+
* on Ethereum mainnet. Addresses extracted from
|
|
4
|
+
* `lightchain-protocol/LCAI-dao-frontend/config/index.ts`.
|
|
5
|
+
*
|
|
6
|
+
* Governance is currently Ethereum-side (chain 1). Voting on LCAI proposals
|
|
7
|
+
* happens via the LCAI ERC-20 wrapped as IVotes (LCAIBallots). Execution
|
|
8
|
+
* goes through LCAITimeLock with the timelock controller managing actual
|
|
9
|
+
* calldata dispatch.
|
|
10
|
+
*
|
|
11
|
+
* Voting parameters (hard-coded in LCAIGovernor.sol constructor):
|
|
12
|
+
* - votingDelay = 7,200 blocks (~1 day at 12s)
|
|
13
|
+
* - votingPeriod = 100,800 blocks (~14 days at 12s)
|
|
14
|
+
* - proposalThreshold = 140,000 LCAI (votes required to create a proposal)
|
|
15
|
+
* - quorum = 3% of total supply (3-15 by admin)
|
|
16
|
+
*
|
|
17
|
+
* This module covers the OZ Governor v5 surface: state machine, propose,
|
|
18
|
+
* castVote, queue, execute. Plus convenience reads of the constants.
|
|
19
|
+
*/
|
|
20
|
+
import { parseAbi } from "viem";
|
|
21
|
+
/** Confirmed Ethereum mainnet addresses (chain 1). */
|
|
22
|
+
export const DAO_ADDRESSES = {
|
|
23
|
+
ethereum: {
|
|
24
|
+
chainId: 1,
|
|
25
|
+
governor: "0x6dfa413B5900a1a7947BC75E68AbBA093cB2492d",
|
|
26
|
+
timelock: "0xbE1c37F8C4DA77dD06F4A8AC5098Ec70273093d7",
|
|
27
|
+
ballots: "0x75F3D01c4D960FE986A598B7954A3b786B29cE49",
|
|
28
|
+
token: "0x9cA8530CA349c966Fe9ef903Df17a75B8A778927",
|
|
29
|
+
treasury: "0x07A716a551E5f4CA7D6C71Da9dF1cb1429Dba826",
|
|
30
|
+
explorer: "https://etherscan.io",
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The 8-state OZ Governor v5 enum. The string label is what most builders
|
|
35
|
+
* will want to surface in a UI.
|
|
36
|
+
*/
|
|
37
|
+
export var ProposalState;
|
|
38
|
+
(function (ProposalState) {
|
|
39
|
+
ProposalState[ProposalState["Pending"] = 0] = "Pending";
|
|
40
|
+
ProposalState[ProposalState["Active"] = 1] = "Active";
|
|
41
|
+
ProposalState[ProposalState["Canceled"] = 2] = "Canceled";
|
|
42
|
+
ProposalState[ProposalState["Defeated"] = 3] = "Defeated";
|
|
43
|
+
ProposalState[ProposalState["Succeeded"] = 4] = "Succeeded";
|
|
44
|
+
ProposalState[ProposalState["Queued"] = 5] = "Queued";
|
|
45
|
+
ProposalState[ProposalState["Expired"] = 6] = "Expired";
|
|
46
|
+
ProposalState[ProposalState["Executed"] = 7] = "Executed";
|
|
47
|
+
})(ProposalState || (ProposalState = {}));
|
|
48
|
+
export const PROPOSAL_STATE_LABEL = {
|
|
49
|
+
[ProposalState.Pending]: "pending",
|
|
50
|
+
[ProposalState.Active]: "active",
|
|
51
|
+
[ProposalState.Canceled]: "canceled",
|
|
52
|
+
[ProposalState.Defeated]: "defeated",
|
|
53
|
+
[ProposalState.Succeeded]: "succeeded",
|
|
54
|
+
[ProposalState.Queued]: "queued",
|
|
55
|
+
[ProposalState.Expired]: "expired",
|
|
56
|
+
[ProposalState.Executed]: "executed",
|
|
57
|
+
};
|
|
58
|
+
/** Vote support values. Maps to OZ's GovernorCountingSimple. */
|
|
59
|
+
export var VoteSupport;
|
|
60
|
+
(function (VoteSupport) {
|
|
61
|
+
VoteSupport[VoteSupport["Against"] = 0] = "Against";
|
|
62
|
+
VoteSupport[VoteSupport["For"] = 1] = "For";
|
|
63
|
+
VoteSupport[VoteSupport["Abstain"] = 2] = "Abstain";
|
|
64
|
+
})(VoteSupport || (VoteSupport = {}));
|
|
65
|
+
/** OZ Governor v5 ABI (subset). */
|
|
66
|
+
export const GOVERNOR_ABI = parseAbi([
|
|
67
|
+
"function propose(address[] targets, uint256[] values, bytes[] calldatas, string description) external returns (uint256 proposalId)",
|
|
68
|
+
"function castVote(uint256 proposalId, uint8 support) external returns (uint256)",
|
|
69
|
+
"function castVoteWithReason(uint256 proposalId, uint8 support, string reason) external returns (uint256)",
|
|
70
|
+
"function queue(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash) external returns (uint256)",
|
|
71
|
+
"function execute(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash) external payable returns (uint256)",
|
|
72
|
+
"function state(uint256 proposalId) external view returns (uint8)",
|
|
73
|
+
"function hashProposal(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash) external pure returns (uint256)",
|
|
74
|
+
"function votingDelay() external view returns (uint256)",
|
|
75
|
+
"function votingPeriod() external view returns (uint256)",
|
|
76
|
+
"function proposalThreshold() external view returns (uint256)",
|
|
77
|
+
"function quorum(uint256 timepoint) external view returns (uint256)",
|
|
78
|
+
"function proposalVotes(uint256 proposalId) external view returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes)",
|
|
79
|
+
"function proposalSnapshot(uint256 proposalId) external view returns (uint256)",
|
|
80
|
+
"function proposalDeadline(uint256 proposalId) external view returns (uint256)",
|
|
81
|
+
"function proposalProposer(uint256 proposalId) external view returns (address)",
|
|
82
|
+
"function proposalEta(uint256 proposalId) external view returns (uint256)",
|
|
83
|
+
"function getVotes(address account, uint256 timepoint) external view returns (uint256)",
|
|
84
|
+
"function hasVoted(uint256 proposalId, address account) external view returns (bool)",
|
|
85
|
+
]);
|
|
86
|
+
/** Minimal IVotes ABI for delegate + balance reads (LCAIBallots). */
|
|
87
|
+
export const VOTES_ABI = parseAbi([
|
|
88
|
+
"function balanceOf(address) external view returns (uint256)",
|
|
89
|
+
"function getVotes(address) external view returns (uint256)",
|
|
90
|
+
"function delegates(address) external view returns (address)",
|
|
91
|
+
"function delegate(address delegatee) external returns (bool)",
|
|
92
|
+
]);
|
|
93
|
+
/**
|
|
94
|
+
* DAO client. Wraps reads (proposal state, config) + writes (propose, vote,
|
|
95
|
+
* queue, execute) on the Ethereum LCAIGovernor.
|
|
96
|
+
*/
|
|
97
|
+
export class DAO {
|
|
98
|
+
constructor(publicClient, chain = "ethereum", walletClient) {
|
|
99
|
+
this.publicClient = publicClient;
|
|
100
|
+
this.walletClient = walletClient;
|
|
101
|
+
this.addresses = DAO_ADDRESSES[chain];
|
|
102
|
+
}
|
|
103
|
+
// -------- Reads --------
|
|
104
|
+
/** Current proposal state by id. */
|
|
105
|
+
async state(proposalId) {
|
|
106
|
+
const raw = (await this.publicClient.readContract({
|
|
107
|
+
address: this.addresses.governor,
|
|
108
|
+
abi: GOVERNOR_ABI,
|
|
109
|
+
functionName: "state",
|
|
110
|
+
args: [proposalId],
|
|
111
|
+
}));
|
|
112
|
+
return raw;
|
|
113
|
+
}
|
|
114
|
+
/** Full proposal summary by id. Aggregates state + votes + key blocks. */
|
|
115
|
+
async proposal(proposalId) {
|
|
116
|
+
const [stateRaw, votesRaw, snapshot, deadline, eta, proposerRaw] = (await Promise.all([
|
|
117
|
+
this.publicClient.readContract({ address: this.addresses.governor, abi: GOVERNOR_ABI, functionName: "state", args: [proposalId] }),
|
|
118
|
+
this.publicClient.readContract({ address: this.addresses.governor, abi: GOVERNOR_ABI, functionName: "proposalVotes", args: [proposalId] }),
|
|
119
|
+
this.publicClient.readContract({ address: this.addresses.governor, abi: GOVERNOR_ABI, functionName: "proposalSnapshot", args: [proposalId] }),
|
|
120
|
+
this.publicClient.readContract({ address: this.addresses.governor, abi: GOVERNOR_ABI, functionName: "proposalDeadline", args: [proposalId] }),
|
|
121
|
+
this.publicClient.readContract({ address: this.addresses.governor, abi: GOVERNOR_ABI, functionName: "proposalEta", args: [proposalId] }).catch(() => 0n),
|
|
122
|
+
this.publicClient.readContract({ address: this.addresses.governor, abi: GOVERNOR_ABI, functionName: "proposalProposer", args: [proposalId] }).catch(() => null),
|
|
123
|
+
]));
|
|
124
|
+
const state = stateRaw;
|
|
125
|
+
return {
|
|
126
|
+
id: proposalId,
|
|
127
|
+
state,
|
|
128
|
+
stateLabel: PROPOSAL_STATE_LABEL[state] ?? "unknown",
|
|
129
|
+
proposer: proposerRaw,
|
|
130
|
+
snapshot,
|
|
131
|
+
deadline,
|
|
132
|
+
eta,
|
|
133
|
+
votes: { againstWei: votesRaw[0], forWei: votesRaw[1], abstainWei: votesRaw[2] },
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/** Whether `voter` has cast a vote on `proposalId`. */
|
|
137
|
+
hasVoted(proposalId, voter) {
|
|
138
|
+
return this.publicClient.readContract({
|
|
139
|
+
address: this.addresses.governor,
|
|
140
|
+
abi: GOVERNOR_ABI,
|
|
141
|
+
functionName: "hasVoted",
|
|
142
|
+
args: [proposalId, voter],
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/** Voting weight of `voter` at a specific block (use the proposal's `snapshot`). */
|
|
146
|
+
getVotes(voter, timepoint) {
|
|
147
|
+
return this.publicClient.readContract({
|
|
148
|
+
address: this.addresses.governor,
|
|
149
|
+
abi: GOVERNOR_ABI,
|
|
150
|
+
functionName: "getVotes",
|
|
151
|
+
args: [voter, timepoint],
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
/** Aggregated voting parameters of the LCAIGovernor. */
|
|
155
|
+
async config() {
|
|
156
|
+
const [delay, period, threshold] = (await Promise.all([
|
|
157
|
+
this.publicClient.readContract({ address: this.addresses.governor, abi: GOVERNOR_ABI, functionName: "votingDelay" }),
|
|
158
|
+
this.publicClient.readContract({ address: this.addresses.governor, abi: GOVERNOR_ABI, functionName: "votingPeriod" }),
|
|
159
|
+
this.publicClient.readContract({ address: this.addresses.governor, abi: GOVERNOR_ABI, functionName: "proposalThreshold" }),
|
|
160
|
+
]));
|
|
161
|
+
return {
|
|
162
|
+
votingDelayBlocks: delay,
|
|
163
|
+
votingPeriodBlocks: period,
|
|
164
|
+
proposalThresholdWei: threshold,
|
|
165
|
+
votingPeriodSecs: Number(period) * 12,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/** Quorum required at a given timepoint (in wei of voting weight). */
|
|
169
|
+
quorum(timepoint) {
|
|
170
|
+
return this.publicClient.readContract({
|
|
171
|
+
address: this.addresses.governor,
|
|
172
|
+
abi: GOVERNOR_ABI,
|
|
173
|
+
functionName: "quorum",
|
|
174
|
+
args: [timepoint],
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
// -------- Writes --------
|
|
178
|
+
/** Cast a For / Against / Abstain vote. Wallet must be the voter and have delegated their LCAI. */
|
|
179
|
+
castVote(proposalId, support, reason) {
|
|
180
|
+
if (!this.walletClient)
|
|
181
|
+
throw new Error("DAO: no wallet client; pass one to the DAO constructor for writes");
|
|
182
|
+
return reason
|
|
183
|
+
? this.walletClient.writeContract({
|
|
184
|
+
address: this.addresses.governor,
|
|
185
|
+
abi: GOVERNOR_ABI,
|
|
186
|
+
functionName: "castVoteWithReason",
|
|
187
|
+
args: [proposalId, support, reason],
|
|
188
|
+
})
|
|
189
|
+
: this.walletClient.writeContract({
|
|
190
|
+
address: this.addresses.governor,
|
|
191
|
+
abi: GOVERNOR_ABI,
|
|
192
|
+
functionName: "castVote",
|
|
193
|
+
args: [proposalId, support],
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/** Submit a new proposal. Wallet must hold at least `proposalThreshold` delegated votes. */
|
|
197
|
+
propose(args) {
|
|
198
|
+
if (!this.walletClient)
|
|
199
|
+
throw new Error("DAO: no wallet client; pass one to the DAO constructor for writes");
|
|
200
|
+
return this.walletClient.writeContract({
|
|
201
|
+
address: this.addresses.governor,
|
|
202
|
+
abi: GOVERNOR_ABI,
|
|
203
|
+
functionName: "propose",
|
|
204
|
+
args: [args.targets, args.values, args.calldatas, args.description],
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
/** Queue a Succeeded proposal into the timelock. */
|
|
208
|
+
queue(args) {
|
|
209
|
+
if (!this.walletClient)
|
|
210
|
+
throw new Error("DAO: no wallet client; pass one to the DAO constructor for writes");
|
|
211
|
+
return this.walletClient.writeContract({
|
|
212
|
+
address: this.addresses.governor,
|
|
213
|
+
abi: GOVERNOR_ABI,
|
|
214
|
+
functionName: "queue",
|
|
215
|
+
args: [args.targets, args.values, args.calldatas, args.descriptionHash],
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Execute a Queued proposal. The Governor enforces
|
|
220
|
+
* `msg.value == sum(values)`; pass the sum as `value`.
|
|
221
|
+
*/
|
|
222
|
+
execute(args) {
|
|
223
|
+
if (!this.walletClient)
|
|
224
|
+
throw new Error("DAO: no wallet client; pass one to the DAO constructor for writes");
|
|
225
|
+
const totalValue = args.values.reduce((acc, v) => acc + v, 0n);
|
|
226
|
+
return this.walletClient.writeContract({
|
|
227
|
+
address: this.addresses.governor,
|
|
228
|
+
abi: GOVERNOR_ABI,
|
|
229
|
+
functionName: "execute",
|
|
230
|
+
args: [args.targets, args.values, args.calldatas, args.descriptionHash],
|
|
231
|
+
value: totalValue,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,11 @@ 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
4
|
import { modelId as computeModelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, runInference, runInferenceWithKey, runInferenceStream } from "./inference.js";
|
|
5
|
+
import { Conversation, chat } from "./chat.js";
|
|
6
|
+
import { preflight as workerPreflight, watch as workerWatch } from "./worker.js";
|
|
7
|
+
import { Bridge, BRIDGE_ROUTE, HYPERLANE_ROUTER_ABI, ERC20_ABI, addressToBytes32, quoteBridgeFee, bridgeableBalance, bridgeAllowance, approveBridge, bridgeTransfer } from "./bridge.js";
|
|
8
|
+
import { DAO, DAO_ADDRESSES, ProposalState, PROPOSAL_STATE_LABEL, VoteSupport, GOVERNOR_ABI, VOTES_ABI } from "./dao.js";
|
|
9
|
+
import { OnchainModelRegistry, AIVM_MODEL_REGISTRY_ABI, BENCHMARK_REGISTRY_ABI, ModelStatus, MODEL_STATUS_LABEL } from "./onchain-models.js";
|
|
5
10
|
import { StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker } from "./errors.js";
|
|
6
11
|
import { GatewayClient, GatewayHttpError } from "./gateway.js";
|
|
7
12
|
import * as crypto from "./crypto.js";
|
|
@@ -45,6 +50,23 @@ export declare class LightNode {
|
|
|
45
50
|
isRegistered(address: string): Promise<boolean | null>;
|
|
46
51
|
/** Settled worker earnings in whole LCAI (from total_earned wei). */
|
|
47
52
|
getEarningsLcai(address: string): Promise<number>;
|
|
53
|
+
/**
|
|
54
|
+
* One job's current status, classified for builders deciding whether to
|
|
55
|
+
* retry / claim a refund / accept the answer. `category` is the
|
|
56
|
+
* builder-friendly label; `raw` is the indexer's literal state string.
|
|
57
|
+
* Null when the indexer has never seen the job (still pending propagation).
|
|
58
|
+
*/
|
|
59
|
+
getJobStatus(jobId: string | bigint): Promise<{
|
|
60
|
+
id: string;
|
|
61
|
+
raw: string;
|
|
62
|
+
category: "submitted" | "in-flight" | "completed" | "stalled" | "disputed" | "resolved" | "unknown";
|
|
63
|
+
worker: string | null;
|
|
64
|
+
model: string | null;
|
|
65
|
+
submittedAt: number | null;
|
|
66
|
+
completedAt: number | null;
|
|
67
|
+
workerShareLcai: number;
|
|
68
|
+
refundable: boolean;
|
|
69
|
+
} | null>;
|
|
48
70
|
/** keccak256 of a model tag (its on-chain + indexer id). */
|
|
49
71
|
modelId(tag: string): `0x${string}`;
|
|
50
72
|
/** On-chain inference fee for a model, in whole LCAI (what submitJob must be paid). */
|
|
@@ -66,8 +88,13 @@ export declare class LightNode {
|
|
|
66
88
|
* (especially in registry-proxy environments like StackBlitz where lockfiles
|
|
67
89
|
* may pin an older minor than the local install command suggests).
|
|
68
90
|
*/
|
|
69
|
-
export declare const SDK_VERSION = "0.
|
|
70
|
-
export { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS, aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, fromWei, computeModelId as modelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost, GatewayClient, GatewayHttpError, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, crypto, runInference, runInferenceWithKey, runInferenceStream, StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, };
|
|
91
|
+
export declare const SDK_VERSION = "0.5.0";
|
|
92
|
+
export { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS, aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, fromWei, computeModelId as modelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost, GatewayClient, GatewayHttpError, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, crypto, runInference, runInferenceWithKey, runInferenceStream, Conversation, chat, 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, };
|
|
71
93
|
export type { BearerSource, GatewayClientOptions, SelectSessionResult, PrepareSessionResult, UploadBlobResult, SessionTokenResult } from "./gateway.js";
|
|
72
94
|
export type { SessionPreparation, RunInferenceArgs, RunInferenceResult, RunInferenceWithKeyArgs, RunInferenceStreamResult } from "./inference.js";
|
|
95
|
+
export type { ChatRole, ChatMessage, ConversationOptions, ConversationSendResult } from "./chat.js";
|
|
96
|
+
export type { WorkerPreflightArgs, WorkerPreflightResult, WorkerWatchOptions, WorkerEventKind, WorkerEvent, WorkerWatchHandle } from "./worker.js";
|
|
97
|
+
export type { BridgeChain, BridgeEndpoints, BridgeTransferArgs } from "./bridge.js";
|
|
98
|
+
export type { DaoChain, DaoAddresses, ProposalSummary, DaoConfig } from "./dao.js";
|
|
99
|
+
export type { BaseModel, ModelVariant, AccessTier, AccessPolicy, Benchmark, OnchainModelRegistryOptions } from "./onchain-models.js";
|
|
73
100
|
export type { NetworkId, NetworkConfig, Worker, Job, ModelInfo, NetworkStats, ModelStat, WorkerStat, NetworkAnalytics };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS } from "./networks.js";
|
|
2
|
-
import { fetchWorker, fetchWorkerJobs, fetchRecentJobs, fetchModels, fetchWorkers, summarize, fromWei, } from "./subgraph.js";
|
|
2
|
+
import { fetchWorker, fetchWorkerJobs, fetchRecentJobs, fetchJob, 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
5
|
import { modelId as computeModelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, runInference, runInferenceWithKey, runInferenceStream, } from "./inference.js";
|
|
6
|
+
import { Conversation, chat } from "./chat.js";
|
|
7
|
+
import { preflight as workerPreflight, watch as workerWatch } from "./worker.js";
|
|
8
|
+
import { Bridge, BRIDGE_ROUTE, HYPERLANE_ROUTER_ABI, ERC20_ABI, addressToBytes32, quoteBridgeFee, bridgeableBalance, bridgeAllowance, approveBridge, bridgeTransfer, } from "./bridge.js";
|
|
9
|
+
import { DAO, DAO_ADDRESSES, ProposalState, PROPOSAL_STATE_LABEL, VoteSupport, GOVERNOR_ABI, VOTES_ABI, } from "./dao.js";
|
|
10
|
+
import { OnchainModelRegistry, AIVM_MODEL_REGISTRY_ABI, BENCHMARK_REGISTRY_ABI, ModelStatus, MODEL_STATUS_LABEL, } from "./onchain-models.js";
|
|
6
11
|
import { StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, } from "./errors.js";
|
|
7
12
|
import { GatewayClient, GatewayHttpError } from "./gateway.js";
|
|
8
13
|
import * as crypto from "./crypto.js";
|
|
@@ -72,6 +77,48 @@ export class LightNode {
|
|
|
72
77
|
const w = await fetchWorker(this.network, address);
|
|
73
78
|
return w ? fromWei(w.total_earned) : 0;
|
|
74
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* One job's current status, classified for builders deciding whether to
|
|
82
|
+
* retry / claim a refund / accept the answer. `category` is the
|
|
83
|
+
* builder-friendly label; `raw` is the indexer's literal state string.
|
|
84
|
+
* Null when the indexer has never seen the job (still pending propagation).
|
|
85
|
+
*/
|
|
86
|
+
async getJobStatus(jobId) {
|
|
87
|
+
const j = await fetchJob(this.network, jobId);
|
|
88
|
+
if (!j)
|
|
89
|
+
return null;
|
|
90
|
+
const state = (j.state ?? "").trim();
|
|
91
|
+
const stateLow = state.toLowerCase();
|
|
92
|
+
const category = /completed|released|paid/.test(stateLow)
|
|
93
|
+
? "completed"
|
|
94
|
+
: /timed.?out|stalled|expired/.test(stateLow)
|
|
95
|
+
? "stalled"
|
|
96
|
+
: /disputed/.test(stateLow)
|
|
97
|
+
? "disputed"
|
|
98
|
+
: /resolved/.test(stateLow)
|
|
99
|
+
? "resolved"
|
|
100
|
+
: /ack/.test(stateLow)
|
|
101
|
+
? "in-flight"
|
|
102
|
+
: /submitted/.test(stateLow)
|
|
103
|
+
? "submitted"
|
|
104
|
+
: "unknown";
|
|
105
|
+
// A refund is on the table when the worker accepted the job but never
|
|
106
|
+
// produced an answer within the protocol's dispute window. The protocol's
|
|
107
|
+
// own timeout/dispute pipeline reclaims the fee; this flag is the SDK's
|
|
108
|
+
// builder-facing hint that the on-chain refund call is the right path.
|
|
109
|
+
const refundable = category === "stalled" || category === "disputed";
|
|
110
|
+
return {
|
|
111
|
+
id: j.id,
|
|
112
|
+
raw: state,
|
|
113
|
+
category,
|
|
114
|
+
worker: j.worker ?? null,
|
|
115
|
+
model: j.model_id ?? null,
|
|
116
|
+
submittedAt: j.submitted_at ?? null,
|
|
117
|
+
completedAt: j.completed_at ?? null,
|
|
118
|
+
workerShareLcai: fromWei(j.worker_share),
|
|
119
|
+
refundable,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
75
122
|
/** keccak256 of a model tag (its on-chain + indexer id). */
|
|
76
123
|
modelId(tag) {
|
|
77
124
|
return computeModelId(tag);
|
|
@@ -96,7 +143,7 @@ export class LightNode {
|
|
|
96
143
|
* (especially in registry-proxy environments like StackBlitz where lockfiles
|
|
97
144
|
* may pin an older minor than the local install command suggests).
|
|
98
145
|
*/
|
|
99
|
-
export const SDK_VERSION = "0.
|
|
146
|
+
export const SDK_VERSION = "0.5.0";
|
|
100
147
|
export { NETWORKS, WORKER_REGISTRY, REGISTRY_TOPICS, aggregateModelStats, aggregateWorkerStats, networkAnalytics, modelStatsCsv, workerStatsCsv, workerJobsCsv, fromWei, computeModelId as modelId, estimateJobFee, JOB_REGISTRY_CONSUMER_ABI, consumerGatewayUrl, consumerGatewayHost,
|
|
101
148
|
// v0.3 inference-submit surface (BETA - see README "Submitting inference").
|
|
102
149
|
GatewayClient, GatewayHttpError, prepareSession, submitPrompt, decryptResponse, generateEcdhKeyPair, crypto,
|
|
@@ -105,4 +152,14 @@ runInference,
|
|
|
105
152
|
// v0.4.3 key-in-answer-out shortcut: same flow, no viem/SIWE wiring.
|
|
106
153
|
runInferenceWithKey,
|
|
107
154
|
// v0.4.9 AsyncIterable<string> wrapper around runInferenceWithKey.
|
|
108
|
-
runInferenceStream,
|
|
155
|
+
runInferenceStream,
|
|
156
|
+
// v0.5.0 multi-turn conversation helper (history client-side; one inference per turn).
|
|
157
|
+
Conversation, chat,
|
|
158
|
+
// v0.5.0 worker preflight + watch (one real test inference + status polling).
|
|
159
|
+
workerPreflight, workerWatch,
|
|
160
|
+
// v0.5.0 Bridge SDK (Hyperlane Warp Route wrapper for LCAI <-> Ethereum).
|
|
161
|
+
Bridge, BRIDGE_ROUTE, HYPERLANE_ROUTER_ABI, ERC20_ABI, addressToBytes32, quoteBridgeFee, bridgeableBalance, bridgeAllowance, approveBridge, bridgeTransfer,
|
|
162
|
+
// v0.5.0 DAO SDK (LCAIGovernor wrapper on Ethereum mainnet).
|
|
163
|
+
DAO, DAO_ADDRESSES, ProposalState, PROPOSAL_STATE_LABEL, VoteSupport, GOVERNOR_ABI, VOTES_ABI,
|
|
164
|
+
// v0.5.0 On-chain model registry reader (AIVMModelRegistry + BenchmarkRegistry).
|
|
165
|
+
OnchainModelRegistry, AIVM_MODEL_REGISTRY_ABI, BENCHMARK_REGISTRY_ABI, ModelStatus, MODEL_STATUS_LABEL, StalledWorkerError, OnChainRevertError, RelayTokenTimeoutError, GatewayAuthError, isStalledWorker, };
|