@opendatalabs/vana-sdk 3.18.0 → 3.19.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/README.md +129 -3
- package/dist/errors.cjs +56 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +98 -2
- package/dist/errors.js +48 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.browser.d.ts +1 -0
- package/dist/index.browser.js +542 -33
- package/dist/index.browser.js.map +4 -4
- package/dist/index.node.cjs +569 -33
- package/dist/index.node.cjs.map +4 -4
- package/dist/index.node.d.ts +1 -0
- package/dist/index.node.js +542 -33
- package/dist/index.node.js.map +4 -4
- package/dist/protocol/derivative-questions.cjs +501 -0
- package/dist/protocol/derivative-questions.cjs.map +1 -0
- package/dist/protocol/derivative-questions.d.ts +355 -0
- package/dist/protocol/derivative-questions.js +486 -0
- package/dist/protocol/derivative-questions.js.map +1 -0
- package/dist/protocol/derivative-questions.test.d.ts +1 -0
- package/dist/protocol/lineage.cjs +9 -4
- package/dist/protocol/lineage.cjs.map +1 -1
- package/dist/protocol/lineage.d.ts +21 -12
- package/dist/protocol/lineage.js +9 -4
- package/dist/protocol/lineage.js.map +1 -1
- package/dist/protocol/personal-server-write.cjs +12 -108
- package/dist/protocol/personal-server-write.cjs.map +1 -1
- package/dist/protocol/personal-server-write.d.ts +2 -17
- package/dist/protocol/personal-server-write.js +7 -98
- package/dist/protocol/personal-server-write.js.map +1 -1
- package/dist/protocol/write-request.cjs +142 -0
- package/dist/protocol/write-request.cjs.map +1 -0
- package/dist/protocol/write-request.d.ts +63 -0
- package/dist/protocol/write-request.js +111 -0
- package/dist/protocol/write-request.js.map +1 -0
- package/dist/tests/mock-personal-server.d.ts +51 -0
- package/package.json +1 -1
package/dist/index.browser.js
CHANGED
|
@@ -1349,6 +1349,46 @@ var LineageReadError = class extends VanaError {
|
|
|
1349
1349
|
errorCode;
|
|
1350
1350
|
details;
|
|
1351
1351
|
};
|
|
1352
|
+
var DerivativeQuestionRejectedError = class extends PersonalServerWriteError {
|
|
1353
|
+
constructor(message, status, errorCode = null, details) {
|
|
1354
|
+
super(message, "DERIVATIVE_QUESTION_REJECTED", status, errorCode, details);
|
|
1355
|
+
}
|
|
1356
|
+
};
|
|
1357
|
+
var DerivativeQuestionInvalidError = class extends PersonalServerWriteError {
|
|
1358
|
+
constructor(message, status = 400, errorCode = null, details) {
|
|
1359
|
+
super(message, "DERIVATIVE_QUESTION_INVALID", status, errorCode, details);
|
|
1360
|
+
}
|
|
1361
|
+
};
|
|
1362
|
+
var DerivativeQuestionNotFoundError = class extends PersonalServerWriteError {
|
|
1363
|
+
constructor(message, errorCode = null, details) {
|
|
1364
|
+
super(message, "DERIVATIVE_QUESTION_NOT_FOUND", 404, errorCode, details);
|
|
1365
|
+
}
|
|
1366
|
+
};
|
|
1367
|
+
var DerivativeSourceNotGrantedError = class extends PersonalServerWriteError {
|
|
1368
|
+
constructor(message, errorCode = null, details) {
|
|
1369
|
+
super(message, "DERIVATIVE_SOURCE_NOT_GRANTED", 403, errorCode, details);
|
|
1370
|
+
}
|
|
1371
|
+
};
|
|
1372
|
+
var DerivativeCycleError = class extends PersonalServerWriteError {
|
|
1373
|
+
constructor(message, errorCode = null, details) {
|
|
1374
|
+
super(message, "DERIVATIVE_CYCLE", 409, errorCode, details);
|
|
1375
|
+
}
|
|
1376
|
+
};
|
|
1377
|
+
var DerivativeComputeUnavailableError = class extends PersonalServerWriteError {
|
|
1378
|
+
constructor(message, errorCode = null, details) {
|
|
1379
|
+
super(message, "DERIVATIVE_COMPUTE_UNAVAILABLE", 503, errorCode, details);
|
|
1380
|
+
}
|
|
1381
|
+
};
|
|
1382
|
+
var DerivativeQuestionTimeoutError = class extends PersonalServerWriteError {
|
|
1383
|
+
constructor(message, details) {
|
|
1384
|
+
super(message, "DERIVATIVE_QUESTION_TIMEOUT", void 0, null, details);
|
|
1385
|
+
}
|
|
1386
|
+
};
|
|
1387
|
+
var DerivativeQuestionFailedError = class extends PersonalServerWriteError {
|
|
1388
|
+
constructor(message, details) {
|
|
1389
|
+
super(message, "DERIVATIVE_QUESTION_FAILED", void 0, null, details);
|
|
1390
|
+
}
|
|
1391
|
+
};
|
|
1352
1392
|
var DataPointDeletedError = class extends VanaError {
|
|
1353
1393
|
constructor(message, details = {}) {
|
|
1354
1394
|
super(message, "DATA_POINT_DELETED");
|
|
@@ -33149,10 +33189,15 @@ var LineageNodeSchema = z.object({
|
|
|
33149
33189
|
*/
|
|
33150
33190
|
version: VersionSchema,
|
|
33151
33191
|
/** The node's tombstone time, or `null` when live. */
|
|
33152
|
-
deletedAt: z.string().nullable()
|
|
33192
|
+
deletedAt: z.string().nullable(),
|
|
33193
|
+
/**
|
|
33194
|
+
* Never present on a visible node. Declared so a node that carries
|
|
33195
|
+
* `redacted: true` next to an id, scope and version cannot slip through
|
|
33196
|
+
* this branch of {@link LineageEntrySchema} with the key stripped.
|
|
33197
|
+
*/
|
|
33198
|
+
redacted: z.never().optional()
|
|
33153
33199
|
});
|
|
33154
|
-
var RedactedLineageNodeSchema = z.
|
|
33155
|
-
dataPointId: DataPointIdSchema,
|
|
33200
|
+
var RedactedLineageNodeSchema = z.strictObject({
|
|
33156
33201
|
redacted: z.literal(true)
|
|
33157
33202
|
});
|
|
33158
33203
|
var LineageEntrySchema = z.union([
|
|
@@ -33177,7 +33222,7 @@ var LineageGraphSchema = z.object({
|
|
|
33177
33222
|
derivativesTruncated: z.boolean().optional()
|
|
33178
33223
|
});
|
|
33179
33224
|
function isRedactedLineageNode(entry) {
|
|
33180
|
-
return "redacted" in entry && entry.redacted === true;
|
|
33225
|
+
return "redacted" in entry && entry.redacted === true && Object.keys(entry).length === 1;
|
|
33181
33226
|
}
|
|
33182
33227
|
function personalServerLineagePath(scope, version) {
|
|
33183
33228
|
return `/v1/data/${encodeURIComponent(scope)}/lineage${version === void 0 ? "" : `/${String(version)}`}`;
|
|
@@ -33759,32 +33804,13 @@ function tryGrantPermissions(scopes) {
|
|
|
33759
33804
|
}
|
|
33760
33805
|
|
|
33761
33806
|
// src/protocol/personal-server-write.ts
|
|
33762
|
-
import { sha256 as
|
|
33763
|
-
import { bytesToHex as
|
|
33807
|
+
import { sha256 as sha2566 } from "@noble/hashes/sha2";
|
|
33808
|
+
import { bytesToHex as bytesToHex3, isAddress as isAddress6 } from "viem";
|
|
33764
33809
|
import { z as z4 } from "zod";
|
|
33765
|
-
|
|
33766
|
-
|
|
33767
|
-
|
|
33768
|
-
|
|
33769
|
-
var MAX_LINEAGE_SOURCES = 256;
|
|
33770
|
-
var WRITE_FILENAME_HEADER = "X-Filename";
|
|
33771
|
-
var WRITE_CONTENT_DISPOSITION_HEADER = "Content-Disposition";
|
|
33772
|
-
var WRITER_ATTRIBUTION_KEY = "$writtenBy";
|
|
33773
|
-
var LINEAGE_KEY = "$lineage";
|
|
33774
|
-
var RESERVED_WRITE_KEYS = [
|
|
33775
|
-
WRITER_ATTRIBUTION_KEY,
|
|
33776
|
-
LINEAGE_KEY
|
|
33777
|
-
];
|
|
33778
|
-
var WriteDataResultSchema = IngestResponseSchema.extend({
|
|
33779
|
-
// Present when the write carried lineage: the validated, lowercased ids.
|
|
33780
|
-
lineage: z4.object({ sources: z4.array(z4.string()) }).optional()
|
|
33781
|
-
});
|
|
33782
|
-
var WriteSessionResponseSchema = z4.object({
|
|
33783
|
-
access_token: z4.string().min(1),
|
|
33784
|
-
token_type: z4.string(),
|
|
33785
|
-
expires_in: z4.number().nonnegative(),
|
|
33786
|
-
scope: z4.string()
|
|
33787
|
-
});
|
|
33810
|
+
|
|
33811
|
+
// src/protocol/write-request.ts
|
|
33812
|
+
import { sha256 as sha2565 } from "@noble/hashes/sha2";
|
|
33813
|
+
import { bytesToHex as bytesToHex2 } from "viem";
|
|
33788
33814
|
function normalizeBaseUrl2(url) {
|
|
33789
33815
|
return url.replace(/\/+$/, "");
|
|
33790
33816
|
}
|
|
@@ -33795,9 +33821,6 @@ function resolveFetch2(fetchFn) {
|
|
|
33795
33821
|
}
|
|
33796
33822
|
return resolved;
|
|
33797
33823
|
}
|
|
33798
|
-
function dataPath(scope) {
|
|
33799
|
-
return `/v1/data/${encodeURIComponent(scope)}`;
|
|
33800
|
-
}
|
|
33801
33824
|
function errorMessage(err) {
|
|
33802
33825
|
return err instanceof Error ? err.message : String(err);
|
|
33803
33826
|
}
|
|
@@ -33885,6 +33908,34 @@ async function sendWithFreshProof(label, fetchFn, options, proofKey, build) {
|
|
|
33885
33908
|
lastError
|
|
33886
33909
|
);
|
|
33887
33910
|
}
|
|
33911
|
+
|
|
33912
|
+
// src/protocol/personal-server-write.ts
|
|
33913
|
+
var WRITE_SESSION_PATH = "/v1/write/session";
|
|
33914
|
+
var WRITE_SIGNATURE_HEADER = "X-Vana-Write-Signature";
|
|
33915
|
+
var WRITE_METADATA_HEADER = "X-Vana-Metadata";
|
|
33916
|
+
var LINEAGE_FIELD = "lineage";
|
|
33917
|
+
var MAX_LINEAGE_SOURCES = 256;
|
|
33918
|
+
var WRITE_FILENAME_HEADER = "X-Filename";
|
|
33919
|
+
var WRITE_CONTENT_DISPOSITION_HEADER = "Content-Disposition";
|
|
33920
|
+
var WRITER_ATTRIBUTION_KEY = "$writtenBy";
|
|
33921
|
+
var LINEAGE_KEY = "$lineage";
|
|
33922
|
+
var RESERVED_WRITE_KEYS = [
|
|
33923
|
+
WRITER_ATTRIBUTION_KEY,
|
|
33924
|
+
LINEAGE_KEY
|
|
33925
|
+
];
|
|
33926
|
+
var WriteDataResultSchema = IngestResponseSchema.extend({
|
|
33927
|
+
// Present when the write carried lineage: the validated, lowercased ids.
|
|
33928
|
+
lineage: z4.object({ sources: z4.array(z4.string()) }).optional()
|
|
33929
|
+
});
|
|
33930
|
+
var WriteSessionResponseSchema = z4.object({
|
|
33931
|
+
access_token: z4.string().min(1),
|
|
33932
|
+
token_type: z4.string(),
|
|
33933
|
+
expires_in: z4.number().nonnegative(),
|
|
33934
|
+
scope: z4.string()
|
|
33935
|
+
});
|
|
33936
|
+
function dataPath(scope) {
|
|
33937
|
+
return `/v1/data/${encodeURIComponent(scope)}`;
|
|
33938
|
+
}
|
|
33888
33939
|
async function openWriteSession(params) {
|
|
33889
33940
|
const fetchFn = resolveFetch2(params.fetch);
|
|
33890
33941
|
const personalServerUrl = normalizeBaseUrl2(params.personalServerUrl);
|
|
@@ -34016,7 +34067,7 @@ function binaryWriteSignedBytes(input) {
|
|
|
34016
34067
|
mimeType: normalizeBinaryMimeType(input.contentType),
|
|
34017
34068
|
...input.filename ? { filename: input.filename } : {},
|
|
34018
34069
|
sizeBytes: input.bytes.length,
|
|
34019
|
-
contentHash:
|
|
34070
|
+
contentHash: bytesToHex3(sha2566(input.bytes)),
|
|
34020
34071
|
encoding: "base64",
|
|
34021
34072
|
content: toBase64(input.bytes),
|
|
34022
34073
|
...metadata !== void 0 ? { metadata } : {}
|
|
@@ -34313,6 +34364,437 @@ async function writePersonalServerData(params) {
|
|
|
34313
34364
|
return { ...result, session };
|
|
34314
34365
|
}
|
|
34315
34366
|
|
|
34367
|
+
// src/protocol/derivative-questions.ts
|
|
34368
|
+
import { z as z5 } from "zod";
|
|
34369
|
+
var DERIVATIVE_QUESTIONS_PATH = "/v1/derivatives/questions";
|
|
34370
|
+
var MAX_QUESTION_SOURCE_SCOPES = 16;
|
|
34371
|
+
var MAX_QUESTION_CHARS = 8e3;
|
|
34372
|
+
var MAX_QUESTION_MODEL_CHARS = 128;
|
|
34373
|
+
var MODEL_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:/-]*$/;
|
|
34374
|
+
var DEFAULT_QUESTION_TIMEOUT_MS = 12e4;
|
|
34375
|
+
var DEFAULT_QUESTION_POLL_INTERVAL_MS = 2e3;
|
|
34376
|
+
var SESSION_REFRESH_SKEW_MS = 3e4;
|
|
34377
|
+
var QUESTION_STATUSES = [
|
|
34378
|
+
"pending",
|
|
34379
|
+
"ready",
|
|
34380
|
+
"failed",
|
|
34381
|
+
"stale"
|
|
34382
|
+
];
|
|
34383
|
+
var QuestionStatusSchema = z5.enum(QUESTION_STATUSES);
|
|
34384
|
+
var QuestionRegisteredBySchema = z5.union([
|
|
34385
|
+
z5.object({ kind: z5.literal("owner") }),
|
|
34386
|
+
z5.object({
|
|
34387
|
+
kind: z5.literal("builder"),
|
|
34388
|
+
builder: z5.string(),
|
|
34389
|
+
grantId: z5.string()
|
|
34390
|
+
})
|
|
34391
|
+
]);
|
|
34392
|
+
var nullableString = z5.string().nullish().transform((value) => value ?? null);
|
|
34393
|
+
var DerivativeQuestionSchema = z5.object({
|
|
34394
|
+
questionId: z5.string().min(1),
|
|
34395
|
+
derivedScope: z5.string().min(1),
|
|
34396
|
+
sourceScopes: z5.array(z5.string()),
|
|
34397
|
+
question: z5.string(),
|
|
34398
|
+
/** The model override, or `null` for the server's default. */
|
|
34399
|
+
model: nullableString,
|
|
34400
|
+
registeredBy: QuestionRegisteredBySchema,
|
|
34401
|
+
status: QuestionStatusSchema,
|
|
34402
|
+
/** A short reason, set only while `status` is `failed`. */
|
|
34403
|
+
error: nullableString,
|
|
34404
|
+
createdAt: z5.string(),
|
|
34405
|
+
updatedAt: nullableString,
|
|
34406
|
+
/** When the last compute finished, or `null` while `pending`. */
|
|
34407
|
+
lastComputedAt: nullableString,
|
|
34408
|
+
/** Local version of the derived record the last compute wrote. */
|
|
34409
|
+
derivedVersion: z5.number().nullish().transform((value) => value ?? null),
|
|
34410
|
+
derivedCollectedAt: nullableString
|
|
34411
|
+
});
|
|
34412
|
+
var QuestionListSchema = z5.object({
|
|
34413
|
+
questions: z5.array(DerivativeQuestionSchema)
|
|
34414
|
+
});
|
|
34415
|
+
var QuestionRecomputeResultSchema = z5.object({
|
|
34416
|
+
questionId: z5.string().min(1),
|
|
34417
|
+
derivedScope: z5.string().min(1),
|
|
34418
|
+
/** `pending` when the question was never computed, else `stale`. */
|
|
34419
|
+
status: QuestionStatusSchema
|
|
34420
|
+
});
|
|
34421
|
+
var QuestionDeleteResultSchema = z5.object({
|
|
34422
|
+
questionId: z5.string().min(1),
|
|
34423
|
+
deleted: z5.literal(true)
|
|
34424
|
+
});
|
|
34425
|
+
var sessionsBySigner = /* @__PURE__ */ new WeakMap();
|
|
34426
|
+
function sessionCacheKey(personalServerUrl, audience, grantId, fetchFn) {
|
|
34427
|
+
return JSON.stringify([personalServerUrl, audience, grantId]) + fetchIdOf(fetchFn);
|
|
34428
|
+
}
|
|
34429
|
+
var fetchIds = /* @__PURE__ */ new WeakMap();
|
|
34430
|
+
var nextFetchId = 0;
|
|
34431
|
+
function fetchIdOf(fetchFn) {
|
|
34432
|
+
let id = fetchIds.get(fetchFn);
|
|
34433
|
+
if (id === void 0) {
|
|
34434
|
+
id = ++nextFetchId;
|
|
34435
|
+
fetchIds.set(fetchFn, id);
|
|
34436
|
+
}
|
|
34437
|
+
return `#${id}`;
|
|
34438
|
+
}
|
|
34439
|
+
function resolveRequest(params) {
|
|
34440
|
+
if (typeof params.personalServerUrl !== "string" || params.personalServerUrl.length === 0) {
|
|
34441
|
+
throw new WriteRequestError("personalServerUrl is required");
|
|
34442
|
+
}
|
|
34443
|
+
if (typeof params.grantId !== "string" || params.grantId.length === 0) {
|
|
34444
|
+
throw new WriteRequestError(
|
|
34445
|
+
"grantId is required; a question call runs under the grant carrying write:<derivedScope>"
|
|
34446
|
+
);
|
|
34447
|
+
}
|
|
34448
|
+
if (params.signer === null || typeof params.signer !== "object") {
|
|
34449
|
+
throw new WriteRequestError(
|
|
34450
|
+
"signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
|
|
34451
|
+
);
|
|
34452
|
+
}
|
|
34453
|
+
const fetchFn = resolveFetch2(params.fetch);
|
|
34454
|
+
const baseUrl = normalizeBaseUrl2(params.personalServerUrl);
|
|
34455
|
+
const audience = params.audience ?? baseUrl;
|
|
34456
|
+
return {
|
|
34457
|
+
baseUrl,
|
|
34458
|
+
audience,
|
|
34459
|
+
fetchFn,
|
|
34460
|
+
cacheKey: sessionCacheKey(baseUrl, audience, params.grantId, fetchFn),
|
|
34461
|
+
signerKey: params.signer
|
|
34462
|
+
};
|
|
34463
|
+
}
|
|
34464
|
+
async function resolveSession(params, resolved, force) {
|
|
34465
|
+
let cache = sessionsBySigner.get(resolved.signerKey);
|
|
34466
|
+
if (cache === void 0) {
|
|
34467
|
+
cache = /* @__PURE__ */ new Map();
|
|
34468
|
+
sessionsBySigner.set(resolved.signerKey, cache);
|
|
34469
|
+
}
|
|
34470
|
+
const cached = cache.get(resolved.cacheKey);
|
|
34471
|
+
if (!force && cached !== void 0 && cached.expiresAt > Date.now() + SESSION_REFRESH_SKEW_MS) {
|
|
34472
|
+
return cached;
|
|
34473
|
+
}
|
|
34474
|
+
if (force) cache.delete(resolved.cacheKey);
|
|
34475
|
+
const session = await openWriteSession({
|
|
34476
|
+
personalServerUrl: resolved.baseUrl,
|
|
34477
|
+
signer: params.signer,
|
|
34478
|
+
grantId: params.grantId,
|
|
34479
|
+
account: params.account,
|
|
34480
|
+
audience: resolved.audience,
|
|
34481
|
+
fetch: resolved.fetchFn,
|
|
34482
|
+
headers: params.headers,
|
|
34483
|
+
retry: params.retry
|
|
34484
|
+
});
|
|
34485
|
+
cache.set(resolved.cacheKey, session);
|
|
34486
|
+
return session;
|
|
34487
|
+
}
|
|
34488
|
+
async function questionErrorFromResponse(response) {
|
|
34489
|
+
const { errorCode, message, details } = await readPersonalServerErrorBody(response);
|
|
34490
|
+
const text = message ?? `Derivative question request failed: ${response.status} ${response.statusText}`;
|
|
34491
|
+
switch (errorCode) {
|
|
34492
|
+
case "DERIVATIVE_SOURCE_NOT_GRANTED":
|
|
34493
|
+
return new DerivativeSourceNotGrantedError(text, errorCode, details);
|
|
34494
|
+
case "DERIVATIVE_CYCLE":
|
|
34495
|
+
return new DerivativeCycleError(text, errorCode, details);
|
|
34496
|
+
case "DERIVATIVE_COMPUTE_UNAVAILABLE":
|
|
34497
|
+
return new DerivativeComputeUnavailableError(text, errorCode, details);
|
|
34498
|
+
case "DERIVATIVE_QUESTION_INVALID":
|
|
34499
|
+
case "LINEAGE_SCOPE_UNDER_SOURCE_PREFIX":
|
|
34500
|
+
return new DerivativeQuestionInvalidError(
|
|
34501
|
+
text,
|
|
34502
|
+
response.status,
|
|
34503
|
+
errorCode,
|
|
34504
|
+
details
|
|
34505
|
+
);
|
|
34506
|
+
case "DERIVATIVE_QUESTION_NOT_FOUND":
|
|
34507
|
+
return new DerivativeQuestionNotFoundError(text, errorCode, details);
|
|
34508
|
+
default:
|
|
34509
|
+
break;
|
|
34510
|
+
}
|
|
34511
|
+
switch (response.status) {
|
|
34512
|
+
case 401:
|
|
34513
|
+
return new WriteUnauthorizedError(text, errorCode, details);
|
|
34514
|
+
case 403:
|
|
34515
|
+
return new WriteForbiddenError(text, errorCode, details);
|
|
34516
|
+
case 404:
|
|
34517
|
+
return new DerivativeQuestionNotFoundError(text, errorCode, details);
|
|
34518
|
+
case 409:
|
|
34519
|
+
return new WriteConflictError(text, errorCode, details);
|
|
34520
|
+
default:
|
|
34521
|
+
return new DerivativeQuestionRejectedError(
|
|
34522
|
+
text,
|
|
34523
|
+
response.status,
|
|
34524
|
+
errorCode,
|
|
34525
|
+
details
|
|
34526
|
+
);
|
|
34527
|
+
}
|
|
34528
|
+
}
|
|
34529
|
+
async function sendOnce(params, resolved, session, spec, bodyBytes) {
|
|
34530
|
+
return sendWithFreshProof(
|
|
34531
|
+
spec.label,
|
|
34532
|
+
resolved.fetchFn,
|
|
34533
|
+
params.retry,
|
|
34534
|
+
proofKeyFor({
|
|
34535
|
+
aud: session.audience,
|
|
34536
|
+
method: spec.method,
|
|
34537
|
+
uri: spec.path,
|
|
34538
|
+
grantId: session.grantId,
|
|
34539
|
+
signedBytes: bodyBytes
|
|
34540
|
+
}),
|
|
34541
|
+
async (iat) => {
|
|
34542
|
+
const headers = new Headers(params.headers);
|
|
34543
|
+
headers.set("Accept", "application/json");
|
|
34544
|
+
headers.set("Authorization", `Bearer ${session.accessToken}`);
|
|
34545
|
+
if (bodyBytes !== void 0) {
|
|
34546
|
+
headers.set("Content-Type", "application/json");
|
|
34547
|
+
}
|
|
34548
|
+
headers.set(
|
|
34549
|
+
WRITE_SIGNATURE_HEADER,
|
|
34550
|
+
await buildWeb3SignedHeader({
|
|
34551
|
+
signMessage: session.signer.signMessage,
|
|
34552
|
+
aud: session.audience,
|
|
34553
|
+
// The Personal Server verifies the proof against the request's
|
|
34554
|
+
// path only, so the signed `uri` must not carry the query string.
|
|
34555
|
+
uri: spec.path,
|
|
34556
|
+
method: spec.method,
|
|
34557
|
+
body: bodyBytes,
|
|
34558
|
+
grantId: session.grantId,
|
|
34559
|
+
iat
|
|
34560
|
+
})
|
|
34561
|
+
);
|
|
34562
|
+
return {
|
|
34563
|
+
url: `${resolved.baseUrl}${spec.path}${spec.query ?? ""}`,
|
|
34564
|
+
init: {
|
|
34565
|
+
method: spec.method,
|
|
34566
|
+
headers,
|
|
34567
|
+
...bodyBytes === void 0 ? {} : { body: bodyBytes },
|
|
34568
|
+
...params.signal ? { signal: params.signal } : {}
|
|
34569
|
+
}
|
|
34570
|
+
};
|
|
34571
|
+
}
|
|
34572
|
+
);
|
|
34573
|
+
}
|
|
34574
|
+
async function sendQuestionRequest(params, spec, schema) {
|
|
34575
|
+
const resolved = resolveRequest(params);
|
|
34576
|
+
const bodyBytes = spec.body === void 0 ? void 0 : new TextEncoder().encode(JSON.stringify(spec.body));
|
|
34577
|
+
let session = await resolveSession(params, resolved, false);
|
|
34578
|
+
let response = await sendOnce(params, resolved, session, spec, bodyBytes);
|
|
34579
|
+
if (response.status === 401) {
|
|
34580
|
+
session = await resolveSession(params, resolved, true);
|
|
34581
|
+
response = await sendOnce(params, resolved, session, spec, bodyBytes);
|
|
34582
|
+
}
|
|
34583
|
+
if (!response.ok) {
|
|
34584
|
+
throw await questionErrorFromResponse(response);
|
|
34585
|
+
}
|
|
34586
|
+
let body;
|
|
34587
|
+
try {
|
|
34588
|
+
body = await response.json();
|
|
34589
|
+
} catch (err) {
|
|
34590
|
+
throw new DerivativeQuestionRejectedError(
|
|
34591
|
+
`${spec.label} response is not JSON`,
|
|
34592
|
+
response.status,
|
|
34593
|
+
null,
|
|
34594
|
+
{ cause: errorMessage(err) }
|
|
34595
|
+
);
|
|
34596
|
+
}
|
|
34597
|
+
const parsed = schema.safeParse(body);
|
|
34598
|
+
if (!parsed.success) {
|
|
34599
|
+
throw new DerivativeQuestionRejectedError(
|
|
34600
|
+
`${spec.label} response is not a derivative question answer`,
|
|
34601
|
+
response.status,
|
|
34602
|
+
null,
|
|
34603
|
+
{ issues: parsed.error.issues }
|
|
34604
|
+
);
|
|
34605
|
+
}
|
|
34606
|
+
return parsed.data;
|
|
34607
|
+
}
|
|
34608
|
+
function assertQuestionId(questionId) {
|
|
34609
|
+
if (typeof questionId !== "string" || questionId.length === 0) {
|
|
34610
|
+
throw new WriteRequestError("questionId is required");
|
|
34611
|
+
}
|
|
34612
|
+
return `${DERIVATIVE_QUESTIONS_PATH}/${encodeURIComponent(questionId)}`;
|
|
34613
|
+
}
|
|
34614
|
+
function registrationBody(params) {
|
|
34615
|
+
const { derivedScope, question } = params;
|
|
34616
|
+
if (typeof derivedScope !== "string" || derivedScope.length === 0) {
|
|
34617
|
+
throw new WriteRequestError("derivedScope is required");
|
|
34618
|
+
}
|
|
34619
|
+
if (!Array.isArray(params.sourceScopes) || params.sourceScopes.length === 0) {
|
|
34620
|
+
throw new WriteRequestError(
|
|
34621
|
+
"sourceScopes must be a non-empty array of scopes"
|
|
34622
|
+
);
|
|
34623
|
+
}
|
|
34624
|
+
if (params.sourceScopes.length > MAX_QUESTION_SOURCE_SCOPES) {
|
|
34625
|
+
throw new WriteRequestError(
|
|
34626
|
+
`sourceScopes lists ${params.sourceScopes.length} scopes; the maximum is ${MAX_QUESTION_SOURCE_SCOPES}`,
|
|
34627
|
+
{ max: MAX_QUESTION_SOURCE_SCOPES, count: params.sourceScopes.length }
|
|
34628
|
+
);
|
|
34629
|
+
}
|
|
34630
|
+
const sourceScopes = [];
|
|
34631
|
+
for (const scope of params.sourceScopes) {
|
|
34632
|
+
if (typeof scope !== "string" || scope.length === 0) {
|
|
34633
|
+
throw new WriteRequestError("sourceScopes entries must be scope strings");
|
|
34634
|
+
}
|
|
34635
|
+
if (sourceScopes.includes(scope)) {
|
|
34636
|
+
throw new WriteRequestError("sourceScopes must not repeat a scope", {
|
|
34637
|
+
duplicate: scope
|
|
34638
|
+
});
|
|
34639
|
+
}
|
|
34640
|
+
if (scope === derivedScope) {
|
|
34641
|
+
throw new WriteRequestError(
|
|
34642
|
+
"derivedScope cannot be one of its own sources",
|
|
34643
|
+
{ scope }
|
|
34644
|
+
);
|
|
34645
|
+
}
|
|
34646
|
+
sourceScopes.push(scope);
|
|
34647
|
+
}
|
|
34648
|
+
if (typeof question !== "string" || question.trim() === "") {
|
|
34649
|
+
throw new WriteRequestError("question must be a non-empty string");
|
|
34650
|
+
}
|
|
34651
|
+
if (question.length > MAX_QUESTION_CHARS) {
|
|
34652
|
+
throw new WriteRequestError(
|
|
34653
|
+
`question is ${question.length} characters; the maximum is ${MAX_QUESTION_CHARS}`,
|
|
34654
|
+
{ max: MAX_QUESTION_CHARS, length: question.length }
|
|
34655
|
+
);
|
|
34656
|
+
}
|
|
34657
|
+
if (params.model !== void 0) {
|
|
34658
|
+
if (typeof params.model !== "string" || params.model.length > MAX_QUESTION_MODEL_CHARS || !MODEL_ID_PATTERN.test(params.model)) {
|
|
34659
|
+
throw new WriteRequestError("model must be a provider model id", {
|
|
34660
|
+
model: params.model
|
|
34661
|
+
});
|
|
34662
|
+
}
|
|
34663
|
+
}
|
|
34664
|
+
assertDerivedScopeNaming(derivedScope, sourceScopes);
|
|
34665
|
+
return {
|
|
34666
|
+
derivedScope,
|
|
34667
|
+
sourceScopes,
|
|
34668
|
+
question,
|
|
34669
|
+
...params.model === void 0 ? {} : { model: params.model }
|
|
34670
|
+
};
|
|
34671
|
+
}
|
|
34672
|
+
async function registerQuestion(params) {
|
|
34673
|
+
const body = registrationBody(params);
|
|
34674
|
+
return sendQuestionRequest(
|
|
34675
|
+
params,
|
|
34676
|
+
{
|
|
34677
|
+
method: "POST",
|
|
34678
|
+
path: DERIVATIVE_QUESTIONS_PATH,
|
|
34679
|
+
body,
|
|
34680
|
+
label: "Register derivative question"
|
|
34681
|
+
},
|
|
34682
|
+
DerivativeQuestionSchema
|
|
34683
|
+
);
|
|
34684
|
+
}
|
|
34685
|
+
async function getQuestion(params) {
|
|
34686
|
+
const path = assertQuestionId(params.questionId);
|
|
34687
|
+
return sendQuestionRequest(
|
|
34688
|
+
params,
|
|
34689
|
+
{ method: "GET", path, label: "Read derivative question" },
|
|
34690
|
+
DerivativeQuestionSchema
|
|
34691
|
+
);
|
|
34692
|
+
}
|
|
34693
|
+
async function listQuestions(params) {
|
|
34694
|
+
if (typeof params.derivedScope !== "string" || params.derivedScope.length === 0) {
|
|
34695
|
+
throw new WriteRequestError(
|
|
34696
|
+
"derivedScope is required; a builder may only list its own questions on a scope it may write"
|
|
34697
|
+
);
|
|
34698
|
+
}
|
|
34699
|
+
const { questions } = await sendQuestionRequest(
|
|
34700
|
+
params,
|
|
34701
|
+
{
|
|
34702
|
+
method: "GET",
|
|
34703
|
+
path: DERIVATIVE_QUESTIONS_PATH,
|
|
34704
|
+
query: `?derivedScope=${encodeURIComponent(params.derivedScope)}`,
|
|
34705
|
+
label: "List derivative questions"
|
|
34706
|
+
},
|
|
34707
|
+
QuestionListSchema
|
|
34708
|
+
);
|
|
34709
|
+
return questions;
|
|
34710
|
+
}
|
|
34711
|
+
async function recomputeQuestion(params) {
|
|
34712
|
+
const path = `${assertQuestionId(params.questionId)}/recompute`;
|
|
34713
|
+
return sendQuestionRequest(
|
|
34714
|
+
params,
|
|
34715
|
+
{ method: "POST", path, label: "Recompute derivative question" },
|
|
34716
|
+
QuestionRecomputeResultSchema
|
|
34717
|
+
);
|
|
34718
|
+
}
|
|
34719
|
+
async function deleteQuestion(params) {
|
|
34720
|
+
const path = assertQuestionId(params.questionId);
|
|
34721
|
+
return sendQuestionRequest(
|
|
34722
|
+
params,
|
|
34723
|
+
{ method: "DELETE", path, label: "Delete derivative question" },
|
|
34724
|
+
QuestionDeleteResultSchema
|
|
34725
|
+
);
|
|
34726
|
+
}
|
|
34727
|
+
function isSettled(status) {
|
|
34728
|
+
return status === "ready" || status === "failed";
|
|
34729
|
+
}
|
|
34730
|
+
function abortError(signal) {
|
|
34731
|
+
const reason = signal.reason;
|
|
34732
|
+
if (reason instanceof Error) return reason;
|
|
34733
|
+
const error = new Error("The operation was aborted");
|
|
34734
|
+
error.name = "AbortError";
|
|
34735
|
+
return error;
|
|
34736
|
+
}
|
|
34737
|
+
async function waitForQuestion(params) {
|
|
34738
|
+
const timeoutMs = Math.max(
|
|
34739
|
+
0,
|
|
34740
|
+
params.timeoutMs ?? DEFAULT_QUESTION_TIMEOUT_MS
|
|
34741
|
+
);
|
|
34742
|
+
const pollIntervalMs = Math.max(
|
|
34743
|
+
0,
|
|
34744
|
+
params.pollIntervalMs ?? DEFAULT_QUESTION_POLL_INTERVAL_MS
|
|
34745
|
+
);
|
|
34746
|
+
const deadline = Date.now() + timeoutMs;
|
|
34747
|
+
for (; ; ) {
|
|
34748
|
+
if (params.signal?.aborted) throw abortError(params.signal);
|
|
34749
|
+
const latest = await getQuestion(params);
|
|
34750
|
+
if (isSettled(latest.status)) return latest;
|
|
34751
|
+
const remaining = deadline - Date.now();
|
|
34752
|
+
if (remaining <= 0) {
|
|
34753
|
+
throw new DerivativeQuestionTimeoutError(
|
|
34754
|
+
`Derivative question ${latest.questionId} was still ${latest.status} after ${timeoutMs}ms`,
|
|
34755
|
+
{
|
|
34756
|
+
questionId: latest.questionId,
|
|
34757
|
+
derivedScope: latest.derivedScope,
|
|
34758
|
+
status: latest.status,
|
|
34759
|
+
timeoutMs
|
|
34760
|
+
}
|
|
34761
|
+
);
|
|
34762
|
+
}
|
|
34763
|
+
await sleep2(Math.min(pollIntervalMs, remaining));
|
|
34764
|
+
}
|
|
34765
|
+
}
|
|
34766
|
+
async function askPersonalServer(params) {
|
|
34767
|
+
const registered = await registerQuestion(params);
|
|
34768
|
+
const registration = await waitForQuestion({
|
|
34769
|
+
...params,
|
|
34770
|
+
questionId: registered.questionId
|
|
34771
|
+
});
|
|
34772
|
+
if (registration.status !== "ready") {
|
|
34773
|
+
throw new DerivativeQuestionFailedError(
|
|
34774
|
+
`Derivative question ${registration.questionId} failed: ${registration.error ?? "no reason given"}`,
|
|
34775
|
+
{
|
|
34776
|
+
questionId: registration.questionId,
|
|
34777
|
+
derivedScope: registration.derivedScope,
|
|
34778
|
+
error: registration.error
|
|
34779
|
+
}
|
|
34780
|
+
);
|
|
34781
|
+
}
|
|
34782
|
+
const signer = resolveWriteSigner(params.signer, {
|
|
34783
|
+
account: params.account
|
|
34784
|
+
});
|
|
34785
|
+
const readParams = {
|
|
34786
|
+
personalServerUrl: normalizeBaseUrl2(params.personalServerUrl),
|
|
34787
|
+
scope: params.derivedScope,
|
|
34788
|
+
grantId: params.grantId,
|
|
34789
|
+
signMessage: signer.signMessage,
|
|
34790
|
+
...params.audience === void 0 ? {} : { audience: params.audience },
|
|
34791
|
+
...params.headers === void 0 ? {} : { headers: params.headers },
|
|
34792
|
+
...params.fetch === void 0 ? {} : { fetch: params.fetch }
|
|
34793
|
+
};
|
|
34794
|
+
const record = await readPersonalServerData(readParams);
|
|
34795
|
+
return { registration, record };
|
|
34796
|
+
}
|
|
34797
|
+
|
|
34316
34798
|
// src/protocol/gateway.ts
|
|
34317
34799
|
function withGrantPermissions(grant) {
|
|
34318
34800
|
const stripped = { ...grant };
|
|
@@ -34925,11 +35407,23 @@ export {
|
|
|
34925
35407
|
ContractFactory,
|
|
34926
35408
|
ContractNotFoundError,
|
|
34927
35409
|
DATA_REGISTRY_STATUS_ABI,
|
|
35410
|
+
DEFAULT_QUESTION_POLL_INTERVAL_MS,
|
|
35411
|
+
DEFAULT_QUESTION_TIMEOUT_MS,
|
|
35412
|
+
DERIVATIVE_QUESTIONS_PATH,
|
|
34928
35413
|
DataFileEnvelopeSchema,
|
|
34929
35414
|
DataPointDeletedError,
|
|
34930
35415
|
DataPointNotFoundError,
|
|
34931
35416
|
DataPointStatus,
|
|
34932
35417
|
DataPointVersionConflictError,
|
|
35418
|
+
DerivativeComputeUnavailableError,
|
|
35419
|
+
DerivativeCycleError,
|
|
35420
|
+
DerivativeQuestionFailedError,
|
|
35421
|
+
DerivativeQuestionInvalidError,
|
|
35422
|
+
DerivativeQuestionNotFoundError,
|
|
35423
|
+
DerivativeQuestionRejectedError,
|
|
35424
|
+
DerivativeQuestionSchema,
|
|
35425
|
+
DerivativeQuestionTimeoutError,
|
|
35426
|
+
DerivativeSourceNotGrantedError,
|
|
34933
35427
|
DropboxStorage,
|
|
34934
35428
|
ECIESError,
|
|
34935
35429
|
ESCROW_DEPOSIT_ABI2 as ESCROW_DEPOSIT_ABI,
|
|
@@ -34953,6 +35447,9 @@ export {
|
|
|
34953
35447
|
LineageReadError,
|
|
34954
35448
|
MASTER_KEY_MESSAGE,
|
|
34955
35449
|
MAX_LINEAGE_SOURCES,
|
|
35450
|
+
MAX_QUESTION_CHARS,
|
|
35451
|
+
MAX_QUESTION_MODEL_CHARS,
|
|
35452
|
+
MAX_QUESTION_SOURCE_SCOPES,
|
|
34956
35453
|
MissingAuthError,
|
|
34957
35454
|
NATIVE_ASSET_ADDRESS,
|
|
34958
35455
|
NATIVE_VANA_ASSET,
|
|
@@ -34971,6 +35468,11 @@ export {
|
|
|
34971
35468
|
PersonalServerError,
|
|
34972
35469
|
PersonalServerWriteError,
|
|
34973
35470
|
PinataStorage,
|
|
35471
|
+
QUESTION_STATUSES,
|
|
35472
|
+
QuestionDeleteResultSchema,
|
|
35473
|
+
QuestionRecomputeResultSchema,
|
|
35474
|
+
QuestionRegisteredBySchema,
|
|
35475
|
+
QuestionStatusSchema,
|
|
34974
35476
|
R2Storage,
|
|
34975
35477
|
RECORD_DATA_ACCESS_TYPES,
|
|
34976
35478
|
REGISTRATION_KIND_FOR_OP,
|
|
@@ -35009,6 +35511,7 @@ export {
|
|
|
35009
35511
|
WriteSessionExpiredError,
|
|
35010
35512
|
WriteTransportError,
|
|
35011
35513
|
WriteUnauthorizedError,
|
|
35514
|
+
askPersonalServer,
|
|
35012
35515
|
assertDerivedScopeNaming,
|
|
35013
35516
|
assertValidPkceVerifier,
|
|
35014
35517
|
binaryWriteSignedBytes,
|
|
@@ -35044,6 +35547,7 @@ export {
|
|
|
35044
35547
|
dataRegistryDomain,
|
|
35045
35548
|
decryptWithPassword,
|
|
35046
35549
|
deleteDataPoint,
|
|
35550
|
+
deleteQuestion,
|
|
35047
35551
|
deriveDataPointId,
|
|
35048
35552
|
deriveMasterKey,
|
|
35049
35553
|
deriveScopeKey,
|
|
@@ -35073,6 +35577,7 @@ export {
|
|
|
35073
35577
|
getOpFee,
|
|
35074
35578
|
getPersonalServerLineage,
|
|
35075
35579
|
getPlatformCapabilities,
|
|
35580
|
+
getQuestion,
|
|
35076
35581
|
getServiceEndpoints,
|
|
35077
35582
|
grantPermissions,
|
|
35078
35583
|
grantRegistrationDomain,
|
|
@@ -35085,6 +35590,7 @@ export {
|
|
|
35085
35590
|
isPlatformSupported,
|
|
35086
35591
|
isRedactedLineageNode,
|
|
35087
35592
|
isTombstoneHashes,
|
|
35593
|
+
listQuestions,
|
|
35088
35594
|
mainnetServices,
|
|
35089
35595
|
moksha,
|
|
35090
35596
|
mokshaServices,
|
|
@@ -35101,8 +35607,10 @@ export {
|
|
|
35101
35607
|
personalServerLineagePath,
|
|
35102
35608
|
personalServerRegistrationDomain,
|
|
35103
35609
|
readPersonalServerData,
|
|
35610
|
+
recomputeQuestion,
|
|
35104
35611
|
recoverServerOwner,
|
|
35105
35612
|
registerPersonalServerSignature,
|
|
35613
|
+
registerQuestion,
|
|
35106
35614
|
resolveWriteSigner,
|
|
35107
35615
|
scopeCoveredByGrant,
|
|
35108
35616
|
scopeMatchesPattern,
|
|
@@ -35120,6 +35628,7 @@ export {
|
|
|
35120
35628
|
verifyGrantRegistration,
|
|
35121
35629
|
verifyPkceChallenge,
|
|
35122
35630
|
verifyWeb3Signed,
|
|
35631
|
+
waitForQuestion,
|
|
35123
35632
|
writeData,
|
|
35124
35633
|
writePersonalServerData
|
|
35125
35634
|
};
|