@opendatalabs/personal-server-ts-server 1.16.1 → 1.17.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/app.d.ts +5 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +38 -1
- package/dist/app.js.map +1 -1
- package/dist/bootstrap.d.ts +6 -0
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +63 -21
- package/dist/bootstrap.js.map +1 -1
- package/dist/enclave-main.d.ts +11 -0
- package/dist/enclave-main.d.ts.map +1 -0
- package/dist/enclave-main.js +188 -0
- package/dist/enclave-main.js.map +1 -0
- package/dist/index.js +6 -22
- package/dist/index.js.map +1 -1
- package/dist/jobs/access-reporter.d.ts +36 -0
- package/dist/jobs/access-reporter.d.ts.map +1 -0
- package/dist/jobs/access-reporter.js +272 -0
- package/dist/jobs/access-reporter.js.map +1 -0
- package/dist/jobs/raw-envelope-stream.d.ts +3 -0
- package/dist/jobs/raw-envelope-stream.d.ts.map +1 -0
- package/dist/jobs/raw-envelope-stream.js +371 -0
- package/dist/jobs/raw-envelope-stream.js.map +1 -0
- package/dist/jobs/types.d.ts +17 -0
- package/dist/jobs/types.d.ts.map +1 -0
- package/dist/jobs/types.js +3 -0
- package/dist/jobs/types.js.map +1 -0
- package/dist/jobs/worker.d.ts +43 -0
- package/dist/jobs/worker.d.ts.map +1 -0
- package/dist/jobs/worker.js +491 -0
- package/dist/jobs/worker.js.map +1 -0
- package/dist/listen.d.ts +11 -0
- package/dist/listen.d.ts.map +1 -0
- package/dist/listen.js +23 -0
- package/dist/listen.js.map +1 -0
- package/dist/mcp/durable-state.d.ts +75 -0
- package/dist/mcp/durable-state.d.ts.map +1 -0
- package/dist/mcp/durable-state.js +418 -0
- package/dist/mcp/durable-state.js.map +1 -0
- package/dist/mcp/grants.d.ts +12 -0
- package/dist/mcp/grants.d.ts.map +1 -0
- package/dist/mcp/grants.js +33 -0
- package/dist/mcp/grants.js.map +1 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +4 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/tee-ingress.d.ts +29 -0
- package/dist/mcp/tee-ingress.d.ts.map +1 -0
- package/dist/mcp/tee-ingress.js +203 -0
- package/dist/mcp/tee-ingress.js.map +1 -0
- package/dist/package.json +67 -0
- package/dist/routes/enclave-fleet.d.ts +14 -0
- package/dist/routes/enclave-fleet.d.ts.map +1 -0
- package/dist/routes/enclave-fleet.js +43 -0
- package/dist/routes/enclave-fleet.js.map +1 -0
- package/dist/routes/enclave-jobs.d.ts +9 -0
- package/dist/routes/enclave-jobs.d.ts.map +1 -0
- package/dist/routes/enclave-jobs.js +106 -0
- package/dist/routes/enclave-jobs.js.map +1 -0
- package/dist/routes/enclave-mcp.d.ts +9 -0
- package/dist/routes/enclave-mcp.d.ts.map +1 -0
- package/dist/routes/enclave-mcp.js +46 -0
- package/dist/routes/enclave-mcp.js.map +1 -0
- package/dist/routes/mcp.d.ts +5 -2
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +49 -17
- package/dist/routes/mcp.js.map +1 -1
- package/dist/scripts/bundle-verification.d.ts +2 -0
- package/dist/scripts/bundle-verification.d.ts.map +1 -0
- package/dist/scripts/bundle-verification.js +32 -0
- package/dist/scripts/bundle-verification.js.map +1 -0
- package/dist/scripts/verify-bundle.d.ts +2 -0
- package/dist/scripts/verify-bundle.d.ts.map +1 -0
- package/dist/scripts/verify-bundle.js +44 -0
- package/dist/scripts/verify-bundle.js.map +1 -0
- package/dist/storage/hierarchy.d.ts +4 -0
- package/dist/storage/hierarchy.d.ts.map +1 -1
- package/dist/storage/hierarchy.js +10 -0
- package/dist/storage/hierarchy.js.map +1 -1
- package/dist/storage/node-data-storage.d.ts.map +1 -1
- package/dist/storage/node-data-storage.js +7 -1
- package/dist/storage/node-data-storage.js.map +1 -1
- package/dist/ui/ps-lite-debug.js +3205 -5575
- package/package.json +15 -7
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { createReadStream, createWriteStream } from "node:fs";
|
|
3
|
+
import { mkdir, mkdtemp, rm } from "node:fs/promises";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { Readable, Transform } from "node:stream";
|
|
7
|
+
import { pipeline } from "node:stream/promises";
|
|
8
|
+
import { assertScopeNotDeleted, redactEnvelopeForGrantee, redactJsonEnvelopeBytesForGrantee, } from "@opendatalabs/personal-server-ts-core/api";
|
|
9
|
+
import { readDataContract } from "@opendatalabs/personal-server-ts-core/contracts";
|
|
10
|
+
import { DataDeletedError, GrantRevokedError, InvalidSignatureError, ProtocolError, SignedArtifactInvalidError, SignedArtifactMissingError, UnregisteredBuilderError, } from "@opendatalabs/personal-server-ts-core/errors";
|
|
11
|
+
import { verifyDataReadPolicy, verifySignedArtifacts, } from "@opendatalabs/personal-server-ts-core/policy";
|
|
12
|
+
import { parseWeb3SignedHeader, verifyWeb3Signed, } from "@opendatalabs/vana-sdk/node";
|
|
13
|
+
import { canonicalJobRequestBytes, sealJobResultStream, } from "@opendatalabs/vana-sdk/crypto/envelope/job";
|
|
14
|
+
import { JOB_PROTOCOL_VERSION, } from "@opendatalabs/vana-sdk/protocol/jobs";
|
|
15
|
+
import { isAddressEqual } from "viem";
|
|
16
|
+
import { publicKeyToAddress } from "viem/accounts";
|
|
17
|
+
import { openRedactedEnvelopeStream } from "./raw-envelope-stream.js";
|
|
18
|
+
const RAW_READ = "raw_read";
|
|
19
|
+
const EXECUTE_PATH = "/v1/jobs/execute";
|
|
20
|
+
const POST = "POST";
|
|
21
|
+
const JSON_CONTENT_TYPE = "application/json";
|
|
22
|
+
const UNKNOWN_METADATA = "unknown";
|
|
23
|
+
const MILLISECONDS_PER_SECOND = 1_000;
|
|
24
|
+
// Mirrors the SDK's own Web3Signed clock skew allowance.
|
|
25
|
+
const AUTH_CLOCK_SKEW_SECONDS = 60;
|
|
26
|
+
const JOB_EXECUTION_FAILED_LOG = "Enclave job execution failed";
|
|
27
|
+
const JOB_EXECUTION_PROGRESS_LOG = "Enclave job execution progress";
|
|
28
|
+
const JOB_SCOPE_HYDRATION_FAILED_LOG = "Job scope hydration failed";
|
|
29
|
+
const RESULT_SIGNING_PATH = "/agent/v1/job-results/sign";
|
|
30
|
+
const RESULT_SIGNING_TIMEOUT_MS = 15_000;
|
|
31
|
+
const RESULT_UPLOAD_TIMEOUT_MS = 120_000;
|
|
32
|
+
const RESULT_OBJECT_PREFIX = "jobresults";
|
|
33
|
+
const BYTES_PER_MIB = 1024 * 1024;
|
|
34
|
+
export const DEFAULT_JOB_RESULT_MAX_BYTES = 64 * BYTES_PER_MIB;
|
|
35
|
+
const PUT = "PUT";
|
|
36
|
+
const JOB_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
37
|
+
export class JobFailure extends Error {
|
|
38
|
+
code;
|
|
39
|
+
retryable;
|
|
40
|
+
constructor(code, message, retryable) {
|
|
41
|
+
super(message);
|
|
42
|
+
this.code = code;
|
|
43
|
+
this.retryable = retryable;
|
|
44
|
+
this.name = "JobFailure";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export async function executeJob(envelope, deps) {
|
|
48
|
+
try {
|
|
49
|
+
return await executeJobUnsafe(envelope, deps);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (error instanceof JobFailure) {
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
deps.logger.warn({ jobId: envelope.request.jobId, error: errorSummary(error) }, JOB_EXECUTION_FAILED_LOG);
|
|
56
|
+
throw new JobFailure("INTERNAL", "job execution failed", true);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function executeJobUnsafe(envelope, deps) {
|
|
60
|
+
const { request } = envelope;
|
|
61
|
+
const executionStartedAt = performance.now();
|
|
62
|
+
if (request.v !== JOB_PROTOCOL_VERSION) {
|
|
63
|
+
throw new JobFailure("INTERNAL", "protocol version not supported", false);
|
|
64
|
+
}
|
|
65
|
+
if (request.operation !== RAW_READ) {
|
|
66
|
+
throw new JobFailure("INTERNAL", "operation not supported", false);
|
|
67
|
+
}
|
|
68
|
+
const jobId = normalizeJobId(request.jobId);
|
|
69
|
+
const now = deps.now?.() ?? new Date();
|
|
70
|
+
if (!validDeadline(request.deadline, now)) {
|
|
71
|
+
throw new JobFailure("DEADLINE_PASSED", "job deadline passed", false);
|
|
72
|
+
}
|
|
73
|
+
const auth = await verifyJobAuth(envelope, deps.authAudience, now);
|
|
74
|
+
if (!sameAddress(auth.signer, request.builder)) {
|
|
75
|
+
throw new JobFailure("BUILDER_MISMATCH", "builder identity mismatch", false);
|
|
76
|
+
}
|
|
77
|
+
if (!sameAddress(request.owner, deps.serverOwner)) {
|
|
78
|
+
throw new JobFailure("OWNER_MISMATCH", "job owner mismatch", false);
|
|
79
|
+
}
|
|
80
|
+
let grant;
|
|
81
|
+
try {
|
|
82
|
+
grant = await verifyDataReadPolicy({
|
|
83
|
+
signer: request.builder,
|
|
84
|
+
grantId: request.grantId,
|
|
85
|
+
requestedScope: request.scope,
|
|
86
|
+
serverOwner: deps.serverOwner,
|
|
87
|
+
}, { authSessionVerifier: deps.gateway, grantVerifier: deps.gateway });
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
throw mapPolicyFailure(error);
|
|
91
|
+
}
|
|
92
|
+
const builder = await deps.gateway.getBuilder(request.builder);
|
|
93
|
+
if (!builder) {
|
|
94
|
+
throw new JobFailure("BUILDER_MISMATCH", "builder is not registered", false);
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
await verifySignedArtifacts({
|
|
98
|
+
grant,
|
|
99
|
+
builder,
|
|
100
|
+
gatewayConfig: deps.gatewayConfig,
|
|
101
|
+
ownerAddress: deps.serverOwner,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
throw mapArtifactFailure(error);
|
|
106
|
+
}
|
|
107
|
+
let builderKeyAddress;
|
|
108
|
+
try {
|
|
109
|
+
builderKeyAddress = publicKeyToAddress(builder.publicKey);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
throw new JobFailure("SIGNED_ARTIFACT_INVALID", "builder public key is invalid", false);
|
|
113
|
+
}
|
|
114
|
+
if (!sameAddress(builderKeyAddress, request.builder) ||
|
|
115
|
+
builder.publicKey.toLowerCase() !== request.builderPublicKey.toLowerCase()) {
|
|
116
|
+
throw new JobFailure("BUILDER_MISMATCH", "builder key mismatch", false);
|
|
117
|
+
}
|
|
118
|
+
const registration = await deps.gateway.getServer(deps.serverAddress);
|
|
119
|
+
if (!registration ||
|
|
120
|
+
registration.revokedAt !== null ||
|
|
121
|
+
!sameAddress(registration.ownerAddress, deps.serverOwner) ||
|
|
122
|
+
registration.publicKey.toLowerCase() !== deps.serverPublicKey.toLowerCase()) {
|
|
123
|
+
throw new JobFailure("SERVER_NOT_REGISTERED", "server registration is invalid", false);
|
|
124
|
+
}
|
|
125
|
+
let hydrationAttempted = false;
|
|
126
|
+
let entry = deps.storage.findEntry({ scope: request.scope });
|
|
127
|
+
if (!entry && deps.hydrateScope) {
|
|
128
|
+
hydrationAttempted = true;
|
|
129
|
+
try {
|
|
130
|
+
await deps.hydrateScope(request.scope);
|
|
131
|
+
entry = deps.storage.findEntry({ scope: request.scope });
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
deps.logger.warn({ jobId, scope: request.scope, error: errorSummary(error) }, JOB_SCOPE_HYDRATION_FAILED_LOG);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const resultMaxBytes = deps.resultMaxBytes ??
|
|
138
|
+
readJobResultMaxBytes(process.env.JOB_RESULT_MAX_BYTES);
|
|
139
|
+
let selected = await selectJobScope(deps, request.scope, entry, resultMaxBytes);
|
|
140
|
+
if (request.pinnedVersion !== null &&
|
|
141
|
+
String(selected.localVersion) !== request.pinnedVersion &&
|
|
142
|
+
deps.hydrateScope &&
|
|
143
|
+
!hydrationAttempted) {
|
|
144
|
+
hydrationAttempted = true;
|
|
145
|
+
try {
|
|
146
|
+
await deps.hydrateScope(request.scope);
|
|
147
|
+
entry = deps.storage.findEntry({ scope: request.scope });
|
|
148
|
+
selected = await selectJobScope(deps, request.scope, entry, resultMaxBytes);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
deps.logger.warn({ jobId, scope: request.scope, error: errorSummary(error) }, JOB_SCOPE_HYDRATION_FAILED_LOG);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (request.pinnedVersion !== null &&
|
|
155
|
+
String(selected.localVersion) !== request.pinnedVersion) {
|
|
156
|
+
throw new JobFailure("VERSION_MISMATCH", "scope version mismatch", true);
|
|
157
|
+
}
|
|
158
|
+
const result = {
|
|
159
|
+
v: JOB_PROTOCOL_VERSION,
|
|
160
|
+
jobId,
|
|
161
|
+
scope: request.scope,
|
|
162
|
+
version: selected.localVersion === 0 ? null : String(selected.localVersion),
|
|
163
|
+
contentType: JSON_CONTENT_TYPE,
|
|
164
|
+
};
|
|
165
|
+
const body = await openRawReadBodyStream(deps.storage, request.scope, selected.entry);
|
|
166
|
+
const sealed = await sealJobResultStream(result, request.builderPublicKey, deps.ecies);
|
|
167
|
+
const tempRoot = deps.resultTempDir ?? process.env.PERSONAL_SERVER_ROOT_PATH ?? tmpdir();
|
|
168
|
+
await mkdir(tempRoot, { recursive: true });
|
|
169
|
+
const tempDirectory = await mkdtemp(join(tempRoot, ".job-result-"));
|
|
170
|
+
const sealedPath = join(tempDirectory, "sealed.bin");
|
|
171
|
+
try {
|
|
172
|
+
let payloadBytes = 0;
|
|
173
|
+
const countedBody = body.pipeThrough(new TransformStream({
|
|
174
|
+
transform(chunk, controller) {
|
|
175
|
+
payloadBytes += chunk.byteLength;
|
|
176
|
+
controller.enqueue(chunk);
|
|
177
|
+
},
|
|
178
|
+
}));
|
|
179
|
+
const { digest, byteLength: resultSize } = await writeSealedResult(sealedPath, sealed.header, countedBody.pipeThrough(sealed.transform));
|
|
180
|
+
logExecutionStep(deps, jobId, "read", executionStartedAt, {
|
|
181
|
+
payloadBytes,
|
|
182
|
+
});
|
|
183
|
+
logExecutionStep(deps, jobId, "seal", executionStartedAt, {
|
|
184
|
+
sealedBytes: resultSize,
|
|
185
|
+
});
|
|
186
|
+
const resultHash = `0x${digest}`;
|
|
187
|
+
const encodedJobId = encodeURIComponent(jobId);
|
|
188
|
+
const owner = deps.serverOwner.toLowerCase();
|
|
189
|
+
const resultObjectKey = `${RESULT_OBJECT_PREFIX}/${deps.resultUpload.chainId}/${encodedJobId}`;
|
|
190
|
+
const uploadPath = `/v1/job-results/${deps.resultUpload.chainId}/${owner}/${encodedJobId}`;
|
|
191
|
+
const requestFetch = deps.resultUpload.fetch ?? fetch;
|
|
192
|
+
logExecutionStep(deps, jobId, "sign", executionStartedAt);
|
|
193
|
+
const authorization = await requestUploadSignature(requestFetch, {
|
|
194
|
+
agentEndpoint: deps.resultUpload.agentEndpoint,
|
|
195
|
+
accessToken: deps.resultUpload.accessToken,
|
|
196
|
+
jobId,
|
|
197
|
+
chainId: deps.resultUpload.chainId,
|
|
198
|
+
owner: deps.serverOwner,
|
|
199
|
+
byteLength: resultSize,
|
|
200
|
+
bodyHash: `sha256:${digest}`,
|
|
201
|
+
});
|
|
202
|
+
logExecutionStep(deps, jobId, "upload", executionStartedAt);
|
|
203
|
+
await uploadResult(requestFetch, {
|
|
204
|
+
storageEndpoint: deps.resultUpload.storageEndpoint,
|
|
205
|
+
path: uploadPath,
|
|
206
|
+
authorization,
|
|
207
|
+
filePath: sealedPath,
|
|
208
|
+
byteLength: resultSize,
|
|
209
|
+
});
|
|
210
|
+
await deps.accessLogWriter.write({
|
|
211
|
+
logId: randomUUID(),
|
|
212
|
+
grantId: request.grantId,
|
|
213
|
+
builder: request.builder,
|
|
214
|
+
action: "read",
|
|
215
|
+
scope: request.scope,
|
|
216
|
+
timestamp: now.toISOString(),
|
|
217
|
+
ipAddress: UNKNOWN_METADATA,
|
|
218
|
+
userAgent: UNKNOWN_METADATA,
|
|
219
|
+
});
|
|
220
|
+
deps.logger.info({
|
|
221
|
+
jobId: request.jobId,
|
|
222
|
+
scope: request.scope,
|
|
223
|
+
version: selected.localVersion,
|
|
224
|
+
}, "Enclave job read served");
|
|
225
|
+
logExecutionStep(deps, jobId, "done", executionStartedAt);
|
|
226
|
+
return { resultObjectKey, resultHash, resultSize };
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
await rm(tempDirectory, { recursive: true, force: true });
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async function selectJobScope(deps, scope, entry, resultMaxBytes) {
|
|
233
|
+
try {
|
|
234
|
+
await assertScopeNotDeleted({ scopeDeletions: deps.scopeDeletions, serverOwner: deps.serverOwner }, scope, entry);
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
if (error instanceof DataDeletedError) {
|
|
238
|
+
throw new JobFailure("SCOPE_NOT_FOUND", "scope not found", false);
|
|
239
|
+
}
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
if (!entry) {
|
|
243
|
+
throw new JobFailure("SCOPE_NOT_FOUND", "scope not found", false);
|
|
244
|
+
}
|
|
245
|
+
if (entry.sizeBytes > resultMaxBytes) {
|
|
246
|
+
throw new JobFailure("RESULT_TOO_LARGE", `job result is ${entry.sizeBytes} bytes; limit is ${resultMaxBytes} bytes`, false);
|
|
247
|
+
}
|
|
248
|
+
const localVersion = await deps.storage.findLatestVersionByScope(scope);
|
|
249
|
+
return { entry, localVersion };
|
|
250
|
+
}
|
|
251
|
+
export function readJobResultMaxBytes(value) {
|
|
252
|
+
if (value === undefined)
|
|
253
|
+
return DEFAULT_JOB_RESULT_MAX_BYTES;
|
|
254
|
+
const parsed = Number(value);
|
|
255
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0) {
|
|
256
|
+
throw new Error("JOB_RESULT_MAX_BYTES must be a positive safe integer");
|
|
257
|
+
}
|
|
258
|
+
return parsed;
|
|
259
|
+
}
|
|
260
|
+
async function openRawReadBodyStream(storage, scope, entry) {
|
|
261
|
+
if (storage.readEnvelopeStream) {
|
|
262
|
+
return openRedactedEnvelopeStream(() => storage.readEnvelopeStream(scope, entry.collectedAt));
|
|
263
|
+
}
|
|
264
|
+
if (storage.readEnvelopeBytes) {
|
|
265
|
+
const bytes = redactJsonEnvelopeBytesForGrantee(await storage.readEnvelopeBytes(scope, entry.collectedAt));
|
|
266
|
+
return oneChunkStream(bytes);
|
|
267
|
+
}
|
|
268
|
+
const read = await readDataContract({ storage, scopeParam: scope });
|
|
269
|
+
if (!read.ok) {
|
|
270
|
+
throw new JobFailure("SCOPE_NOT_FOUND", "scope not found", false);
|
|
271
|
+
}
|
|
272
|
+
return oneChunkStream(new TextEncoder().encode(JSON.stringify(redactEnvelopeForGrantee(read.envelope))));
|
|
273
|
+
}
|
|
274
|
+
function oneChunkStream(bytes) {
|
|
275
|
+
return new ReadableStream({
|
|
276
|
+
start(controller) {
|
|
277
|
+
controller.enqueue(bytes);
|
|
278
|
+
controller.close();
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
async function writeSealedResult(path, header, ciphertext) {
|
|
283
|
+
const hash = createHash("sha256");
|
|
284
|
+
let byteLength = 0;
|
|
285
|
+
const meter = new Transform({
|
|
286
|
+
transform(chunk, _encoding, callback) {
|
|
287
|
+
hash.update(chunk);
|
|
288
|
+
byteLength += chunk.byteLength;
|
|
289
|
+
callback(null, chunk);
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
const source = Readable.from((async function* () {
|
|
293
|
+
yield header;
|
|
294
|
+
for await (const chunk of Readable.fromWeb(ciphertext)) {
|
|
295
|
+
yield chunk;
|
|
296
|
+
}
|
|
297
|
+
})());
|
|
298
|
+
await pipeline(source, meter, createWriteStream(path));
|
|
299
|
+
return { digest: hash.digest("hex"), byteLength };
|
|
300
|
+
}
|
|
301
|
+
function logExecutionStep(deps, jobId, event, startedAt, details = {}) {
|
|
302
|
+
const memory = process.memoryUsage();
|
|
303
|
+
deps.logger.info({
|
|
304
|
+
jobId,
|
|
305
|
+
stage: "execute",
|
|
306
|
+
event,
|
|
307
|
+
elapsedMs: Math.max(0, Math.round(performance.now() - startedAt)),
|
|
308
|
+
rssMiB: Math.round(memory.rss / BYTES_PER_MIB),
|
|
309
|
+
heapUsedMiB: Math.round(memory.heapUsed / BYTES_PER_MIB),
|
|
310
|
+
arrayBuffersMiB: Math.round(memory.arrayBuffers / BYTES_PER_MIB),
|
|
311
|
+
...details,
|
|
312
|
+
}, JOB_EXECUTION_PROGRESS_LOG);
|
|
313
|
+
}
|
|
314
|
+
async function requestUploadSignature(requestFetch, request) {
|
|
315
|
+
let response;
|
|
316
|
+
const timeoutSignal = AbortSignal.timeout(RESULT_SIGNING_TIMEOUT_MS);
|
|
317
|
+
try {
|
|
318
|
+
response = await requestFetch(`${request.agentEndpoint.replace(/\/$/, "")}${RESULT_SIGNING_PATH}`, {
|
|
319
|
+
method: POST,
|
|
320
|
+
headers: {
|
|
321
|
+
Authorization: `Bearer ${request.accessToken}`,
|
|
322
|
+
"Content-Type": JSON_CONTENT_TYPE,
|
|
323
|
+
},
|
|
324
|
+
body: JSON.stringify({
|
|
325
|
+
jobId: request.jobId,
|
|
326
|
+
chainId: request.chainId,
|
|
327
|
+
owner: request.owner,
|
|
328
|
+
byteLength: request.byteLength,
|
|
329
|
+
bodyHash: request.bodyHash,
|
|
330
|
+
}),
|
|
331
|
+
signal: timeoutSignal,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
if (timeoutSignal.aborted) {
|
|
336
|
+
throw new JobFailure("RESULT_UPLOAD_FAILED", `result signing request timed out after ${RESULT_SIGNING_TIMEOUT_MS}ms`, true);
|
|
337
|
+
}
|
|
338
|
+
throw new JobFailure("RESULT_UPLOAD_FAILED", "result signing service is unavailable", true);
|
|
339
|
+
}
|
|
340
|
+
if (!response.ok) {
|
|
341
|
+
if (response.status >= 500) {
|
|
342
|
+
throw new JobFailure("RESULT_UPLOAD_FAILED", "result signing service is unavailable", true);
|
|
343
|
+
}
|
|
344
|
+
throw new JobFailure("RESULT_SIGNING_REFUSED", "result upload signing was refused", false);
|
|
345
|
+
}
|
|
346
|
+
let body;
|
|
347
|
+
try {
|
|
348
|
+
body = await response.json();
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
if (timeoutSignal.aborted) {
|
|
352
|
+
throw new JobFailure("RESULT_UPLOAD_FAILED", `result signing request timed out after ${RESULT_SIGNING_TIMEOUT_MS}ms`, true);
|
|
353
|
+
}
|
|
354
|
+
body = undefined;
|
|
355
|
+
}
|
|
356
|
+
if (!body ||
|
|
357
|
+
typeof body !== "object" ||
|
|
358
|
+
!("authorization" in body) ||
|
|
359
|
+
typeof body.authorization !== "string" ||
|
|
360
|
+
!body.authorization.startsWith("Web3Signed ")) {
|
|
361
|
+
throw new JobFailure("RESULT_SIGNING_REFUSED", "result upload signing response is invalid", false);
|
|
362
|
+
}
|
|
363
|
+
return body.authorization;
|
|
364
|
+
}
|
|
365
|
+
async function uploadResult(requestFetch, request) {
|
|
366
|
+
let response;
|
|
367
|
+
const timeoutSignal = AbortSignal.timeout(RESULT_UPLOAD_TIMEOUT_MS);
|
|
368
|
+
const body = createReadStream(request.filePath);
|
|
369
|
+
try {
|
|
370
|
+
const storageOrigin = new URL(request.storageEndpoint).origin;
|
|
371
|
+
response = await requestFetch(`${storageOrigin}${request.path}`, {
|
|
372
|
+
method: PUT,
|
|
373
|
+
headers: {
|
|
374
|
+
Authorization: request.authorization,
|
|
375
|
+
"Content-Type": "application/octet-stream",
|
|
376
|
+
"Content-Length": String(request.byteLength),
|
|
377
|
+
},
|
|
378
|
+
body,
|
|
379
|
+
duplex: "half",
|
|
380
|
+
signal: timeoutSignal,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
if (timeoutSignal.aborted) {
|
|
385
|
+
throw new JobFailure("RESULT_UPLOAD_FAILED", `result upload timed out after ${RESULT_UPLOAD_TIMEOUT_MS}ms`, true);
|
|
386
|
+
}
|
|
387
|
+
throw new JobFailure("RESULT_UPLOAD_FAILED", "result upload failed", true);
|
|
388
|
+
}
|
|
389
|
+
finally {
|
|
390
|
+
body.destroy();
|
|
391
|
+
}
|
|
392
|
+
if (response.status === 413) {
|
|
393
|
+
throw new JobFailure("RESULT_TOO_LARGE", "sealed result exceeds the 100 MB storage limit", false);
|
|
394
|
+
}
|
|
395
|
+
if (!response.ok) {
|
|
396
|
+
throw new JobFailure("RESULT_UPLOAD_FAILED", "result upload failed", response.status >= 500);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Verify the builder's inner Web3Signed proof over the decrypted job request.
|
|
401
|
+
*
|
|
402
|
+
* The proof carries the SDK's 300 s request TTL, which is sized for a live HTTP
|
|
403
|
+
* call. A job is signed at submit and verified here at claim, and the Gateway
|
|
404
|
+
* queues a job whenever the fleet is full: a 6-owner burst on a 4-slot fleet
|
|
405
|
+
* held two jobs for 391 s while a worker booted, past 300 s + 60 s skew, so an
|
|
406
|
+
* authorization the Gateway had accepted expired in the queue.
|
|
407
|
+
*
|
|
408
|
+
* submit ──── queued (scale-up) ──── claim ──── execute
|
|
409
|
+
* │ iat │ 391 s later
|
|
410
|
+
* └── freshness proven HERE, once ──┘ binding proven here
|
|
411
|
+
*
|
|
412
|
+
* So freshness is anchored to the builder-signed `iat`, not to the claim clock —
|
|
413
|
+
* queue time never counts. Everything the proof binds (signer, audience, method,
|
|
414
|
+
* path, body hash over the canonical request) is still verified against this
|
|
415
|
+
* claim, and a proof dated in the future is still refused. The execution bound
|
|
416
|
+
* stays `request.deadline`: builder-signed, capped by the Gateway at submit, and
|
|
417
|
+
* checked against the real clock by {@link validDeadline}.
|
|
418
|
+
*/
|
|
419
|
+
async function verifyJobAuth(envelope, authAudience, now) {
|
|
420
|
+
const nowSeconds = Math.floor(now.getTime() / MILLISECONDS_PER_SECOND);
|
|
421
|
+
try {
|
|
422
|
+
const { payload } = parseWeb3SignedHeader(envelope.auth);
|
|
423
|
+
if (payload.iat > nowSeconds + AUTH_CLOCK_SKEW_SECONDS) {
|
|
424
|
+
throw new Error("job authorization is issued in the future");
|
|
425
|
+
}
|
|
426
|
+
// aud = Gateway origin; contract section 1 step 1 amendment.
|
|
427
|
+
return await verifyWeb3Signed({
|
|
428
|
+
headerValue: envelope.auth,
|
|
429
|
+
expectedOrigin: authAudience,
|
|
430
|
+
expectedMethod: POST,
|
|
431
|
+
expectedPath: EXECUTE_PATH,
|
|
432
|
+
bodyBytes: canonicalJobRequestBytes(envelope.request),
|
|
433
|
+
now: payload.iat,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
throw new JobFailure("AUTH_INVALID", "job authorization is invalid", false);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
function normalizeJobId(jobId) {
|
|
441
|
+
if (!JOB_ID_PATTERN.test(jobId)) {
|
|
442
|
+
throw new JobFailure("INTERNAL", "job id is invalid", false);
|
|
443
|
+
}
|
|
444
|
+
return jobId.toLowerCase();
|
|
445
|
+
}
|
|
446
|
+
function mapPolicyFailure(error) {
|
|
447
|
+
if (error instanceof GrantRevokedError) {
|
|
448
|
+
return new JobFailure("GRANT_REVOKED", "grant is revoked", false);
|
|
449
|
+
}
|
|
450
|
+
if (error instanceof InvalidSignatureError ||
|
|
451
|
+
error instanceof UnregisteredBuilderError) {
|
|
452
|
+
return new JobFailure("BUILDER_MISMATCH", "builder is not authorized", false);
|
|
453
|
+
}
|
|
454
|
+
if (error instanceof ProtocolError) {
|
|
455
|
+
return new JobFailure("GRANT_INVALID", "grant is invalid", false);
|
|
456
|
+
}
|
|
457
|
+
return new JobFailure("INTERNAL", "policy verification failed", true);
|
|
458
|
+
}
|
|
459
|
+
function mapArtifactFailure(error) {
|
|
460
|
+
if (error instanceof SignedArtifactMissingError) {
|
|
461
|
+
return new JobFailure("SIGNED_ARTIFACT_MISSING", "signed artifact is missing", false);
|
|
462
|
+
}
|
|
463
|
+
if (error instanceof GrantRevokedError) {
|
|
464
|
+
return new JobFailure("GRANT_REVOKED", "grant is revoked", false);
|
|
465
|
+
}
|
|
466
|
+
if (error instanceof SignedArtifactInvalidError) {
|
|
467
|
+
return new JobFailure("SIGNED_ARTIFACT_INVALID", "signed artifact is invalid", false);
|
|
468
|
+
}
|
|
469
|
+
if (error instanceof ProtocolError) {
|
|
470
|
+
return new JobFailure("SIGNED_ARTIFACT_INVALID", "signed artifact is invalid", false);
|
|
471
|
+
}
|
|
472
|
+
return new JobFailure("INTERNAL", "artifact verification failed", true);
|
|
473
|
+
}
|
|
474
|
+
function errorSummary(error) {
|
|
475
|
+
return error instanceof Error
|
|
476
|
+
? `${error.name}: ${error.message}`
|
|
477
|
+
: String(error);
|
|
478
|
+
}
|
|
479
|
+
function validDeadline(deadline, now) {
|
|
480
|
+
const timestamp = Date.parse(deadline);
|
|
481
|
+
return Number.isFinite(timestamp) && timestamp > now.getTime();
|
|
482
|
+
}
|
|
483
|
+
function sameAddress(left, right) {
|
|
484
|
+
try {
|
|
485
|
+
return isAddressEqual(left, right);
|
|
486
|
+
}
|
|
487
|
+
catch {
|
|
488
|
+
return false;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/jobs/worker.ts"],"names":[],"mappings":"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"}
|
package/dist/listen.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createAdaptorServer } from "@hono/node-server";
|
|
2
|
+
import type { AddressInfo } from "node:net";
|
|
3
|
+
export type NodeFetchHandler = Parameters<typeof createAdaptorServer>[0]["fetch"];
|
|
4
|
+
export type NodeServer = ReturnType<typeof createAdaptorServer>;
|
|
5
|
+
export declare function listenHttpServer(params: {
|
|
6
|
+
fetch: NodeFetchHandler;
|
|
7
|
+
port: number;
|
|
8
|
+
hostname?: string;
|
|
9
|
+
onListening?: (info: AddressInfo) => void;
|
|
10
|
+
}): Promise<NodeServer>;
|
|
11
|
+
//# sourceMappingURL=listen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listen.d.ts","sourceRoot":"","sources":["../src/listen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,MAAM,gBAAgB,GAAG,UAAU,CACvC,OAAO,mBAAmB,CAC3B,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AACd,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,KAAK,EAAE,gBAAgB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;CAC3C,GAAG,OAAO,CAAC,UAAU,CAAC,CAwBtB"}
|
package/dist/listen.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createAdaptorServer } from "@hono/node-server";
|
|
2
|
+
export async function listenHttpServer(params) {
|
|
3
|
+
const server = createAdaptorServer({ fetch: params.fetch });
|
|
4
|
+
await new Promise((resolve, reject) => {
|
|
5
|
+
const onError = (error) => {
|
|
6
|
+
server.off("error", onError);
|
|
7
|
+
reject(error);
|
|
8
|
+
};
|
|
9
|
+
server.once("error", onError);
|
|
10
|
+
server.listen(params.port, params.hostname, () => {
|
|
11
|
+
server.off("error", onError);
|
|
12
|
+
const address = server.address();
|
|
13
|
+
if (!address || typeof address === "string") {
|
|
14
|
+
reject(new Error("Could not resolve bound server address"));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
params.onListening?.(address);
|
|
18
|
+
resolve();
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
return server;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=listen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listen.js","sourceRoot":"","sources":["../src/listen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAQxD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAKtC;IACC,MAAM,MAAM,GAAG,mBAAmB,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAE5D,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,OAAO,GAAG,CAAC,KAAY,EAAE,EAAE;YAC/B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE;YAC/C,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC5C,MAAM,CAAC,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;gBAC5D,OAAO;YACT,CAAC;YAED,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,CAAC;YAC9B,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type McpConnectionStore, type McpOAuthAuthorizationStore } from "@opendatalabs/personal-server-ts-core/mcp";
|
|
2
|
+
import type { Address } from "viem";
|
|
3
|
+
import type { ClaimResponse } from "@opendatalabs/vana-sdk/protocol/jobs";
|
|
4
|
+
export type McpWakeupIdentity = ClaimResponse["identity"];
|
|
5
|
+
/** Whether a missing or unreadable sealed state file is a genuine first boot
|
|
6
|
+
* (`Optional`, today's default) or a lost durable volume (`Required`, set
|
|
7
|
+
* from the signed `MCP_STATE_REQUIRED=1`). */
|
|
8
|
+
export declare enum McpStateRequirement {
|
|
9
|
+
Optional = "optional",
|
|
10
|
+
Required = "required"
|
|
11
|
+
}
|
|
12
|
+
/** Stable code for a required sealed MCP state file that was missing or
|
|
13
|
+
* could not be decrypted at boot. Distinguishes a lost durable volume from
|
|
14
|
+
* an ordinary first boot; callers must never fall back to fresh state. */
|
|
15
|
+
export declare const MCP_STATE_REQUIRED_MISSING_CODE = "MCP_STATE_REQUIRED_MISSING";
|
|
16
|
+
export declare class McpStateRequiredError extends Error {
|
|
17
|
+
constructor(cause: unknown);
|
|
18
|
+
}
|
|
19
|
+
export interface McpOwnerBinding {
|
|
20
|
+
owner: Address;
|
|
21
|
+
chainId: number;
|
|
22
|
+
}
|
|
23
|
+
export interface McpRollbackIdentity {
|
|
24
|
+
identity: McpWakeupIdentity;
|
|
25
|
+
generation: number;
|
|
26
|
+
}
|
|
27
|
+
export interface McpRollbackReceipt {
|
|
28
|
+
migrationId: string;
|
|
29
|
+
digest: string;
|
|
30
|
+
owners: number;
|
|
31
|
+
connections: number;
|
|
32
|
+
}
|
|
33
|
+
export interface McpDurableState {
|
|
34
|
+
/** These methods are exposed only through an attested encrypted migration peer. */
|
|
35
|
+
fenceAndExport(migrationId: string, target: string): Promise<Uint8Array>;
|
|
36
|
+
importSnapshot(snapshot: Uint8Array, migrationId: string): Promise<{
|
|
37
|
+
connections: number;
|
|
38
|
+
digest: string;
|
|
39
|
+
}>;
|
|
40
|
+
migrationStatus(): Promise<{
|
|
41
|
+
fenced: boolean;
|
|
42
|
+
importedId?: string;
|
|
43
|
+
rollbackActivated?: boolean;
|
|
44
|
+
}>;
|
|
45
|
+
activateRollback(receipt: McpRollbackReceipt): Promise<void>;
|
|
46
|
+
prepareRollback(migrationId: string, resolve: (binding: McpOwnerBinding) => Promise<McpRollbackIdentity>): Promise<McpRollbackReceipt>;
|
|
47
|
+
getRollbackPreparation(): Promise<{
|
|
48
|
+
receipt: McpRollbackReceipt;
|
|
49
|
+
owners: {
|
|
50
|
+
binding: McpOwnerBinding;
|
|
51
|
+
identity: McpWakeupIdentity;
|
|
52
|
+
generation: number;
|
|
53
|
+
}[];
|
|
54
|
+
}>;
|
|
55
|
+
approvedOwnerBindings(): Promise<McpOwnerBinding[]>;
|
|
56
|
+
connections: McpConnectionStore;
|
|
57
|
+
authorizations: McpOAuthAuthorizationStore;
|
|
58
|
+
bindOwner(connectionId: string, binding: McpOwnerBinding): Promise<void>;
|
|
59
|
+
getOwner(connectionId: string): Promise<McpOwnerBinding | null>;
|
|
60
|
+
rememberIdentity(identity: McpWakeupIdentity): Promise<void>;
|
|
61
|
+
getIdentity(userPsId: string): Promise<McpWakeupIdentity | null>;
|
|
62
|
+
/** Serializes multi-step OAuth mutations in the single ingress process. */
|
|
63
|
+
exclusive<T>(operation: () => Promise<T>): Promise<T>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Single-CVM, single-writer store. Only ciphertext is written to its durable
|
|
67
|
+
* volume; the caller obtains its 32-byte key from the TEE key agent. This is
|
|
68
|
+
* deliberately not a multi-process or fleet database.
|
|
69
|
+
*/
|
|
70
|
+
export declare function openMcpDurableState(options: {
|
|
71
|
+
path: string;
|
|
72
|
+
key: Uint8Array;
|
|
73
|
+
requirement?: McpStateRequirement;
|
|
74
|
+
}): Promise<McpDurableState>;
|
|
75
|
+
//# sourceMappingURL=durable-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durable-state.d.ts","sourceRoot":"","sources":["../../src/mcp/durable-state.ts"],"names":[],"mappings":"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"}
|