@opendatalabs/vana-sdk 3.18.1 → 3.19.1

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.
Files changed (37) hide show
  1. package/README.md +141 -0
  2. package/dist/auth/web3-signed-builder.cjs +3 -0
  3. package/dist/auth/web3-signed-builder.cjs.map +1 -1
  4. package/dist/auth/web3-signed-builder.d.ts +14 -0
  5. package/dist/auth/web3-signed-builder.js +3 -0
  6. package/dist/auth/web3-signed-builder.js.map +1 -1
  7. package/dist/errors.cjs +69 -0
  8. package/dist/errors.cjs.map +1 -1
  9. package/dist/errors.d.ts +117 -2
  10. package/dist/errors.js +60 -0
  11. package/dist/errors.js.map +1 -1
  12. package/dist/index.browser.d.ts +1 -0
  13. package/dist/index.browser.js +577 -29
  14. package/dist/index.browser.js.map +4 -4
  15. package/dist/index.node.cjs +605 -29
  16. package/dist/index.node.cjs.map +4 -4
  17. package/dist/index.node.d.ts +1 -0
  18. package/dist/index.node.js +577 -29
  19. package/dist/index.node.js.map +4 -4
  20. package/dist/protocol/derivative-questions.cjs +518 -0
  21. package/dist/protocol/derivative-questions.cjs.map +1 -0
  22. package/dist/protocol/derivative-questions.d.ts +396 -0
  23. package/dist/protocol/derivative-questions.js +507 -0
  24. package/dist/protocol/derivative-questions.js.map +1 -0
  25. package/dist/protocol/derivative-questions.test.d.ts +1 -0
  26. package/dist/protocol/personal-server-write.cjs +12 -108
  27. package/dist/protocol/personal-server-write.cjs.map +1 -1
  28. package/dist/protocol/personal-server-write.d.ts +2 -17
  29. package/dist/protocol/personal-server-write.js +7 -98
  30. package/dist/protocol/personal-server-write.js.map +1 -1
  31. package/dist/protocol/write-request.cjs +156 -0
  32. package/dist/protocol/write-request.cjs.map +1 -0
  33. package/dist/protocol/write-request.d.ts +75 -0
  34. package/dist/protocol/write-request.js +124 -0
  35. package/dist/protocol/write-request.js.map +1 -0
  36. package/dist/tests/mock-personal-server.d.ts +54 -0
  37. package/package.json +1 -1
@@ -1186,11 +1186,24 @@ __export(index_node_exports, {
1186
1186
  ContractNotFoundError: () => ContractNotFoundError,
1187
1187
  DATA_ACCESS_OP_TYPE: () => DATA_ACCESS_OP_TYPE,
1188
1188
  DATA_REGISTRY_STATUS_ABI: () => DATA_REGISTRY_STATUS_ABI,
1189
+ DEFAULT_QUESTION_POLL_INTERVAL_MS: () => DEFAULT_QUESTION_POLL_INTERVAL_MS,
1190
+ DEFAULT_QUESTION_TIMEOUT_MS: () => DEFAULT_QUESTION_TIMEOUT_MS,
1191
+ DERIVATIVE_QUESTIONS_PATH: () => DERIVATIVE_QUESTIONS_PATH,
1189
1192
  DataFileEnvelopeSchema: () => DataFileEnvelopeSchema,
1190
1193
  DataPointDeletedError: () => DataPointDeletedError,
1191
1194
  DataPointNotFoundError: () => DataPointNotFoundError,
1192
1195
  DataPointStatus: () => DataPointStatus,
1193
1196
  DataPointVersionConflictError: () => DataPointVersionConflictError,
1197
+ DerivativeComputeUnavailableError: () => DerivativeComputeUnavailableError,
1198
+ DerivativeCycleError: () => DerivativeCycleError,
1199
+ DerivativeDerivedScopeRequiredError: () => DerivativeDerivedScopeRequiredError,
1200
+ DerivativeQuestionFailedError: () => DerivativeQuestionFailedError,
1201
+ DerivativeQuestionInvalidError: () => DerivativeQuestionInvalidError,
1202
+ DerivativeQuestionNotFoundError: () => DerivativeQuestionNotFoundError,
1203
+ DerivativeQuestionRejectedError: () => DerivativeQuestionRejectedError,
1204
+ DerivativeQuestionSchema: () => DerivativeQuestionSchema,
1205
+ DerivativeQuestionTimeoutError: () => DerivativeQuestionTimeoutError,
1206
+ DerivativeSourceNotGrantedError: () => DerivativeSourceNotGrantedError,
1194
1207
  DropboxStorage: () => DropboxStorage,
1195
1208
  ECIESError: () => ECIESError,
1196
1209
  ESCROW_DEPOSIT_ABI: () => ESCROW_DEPOSIT_ABI2,
@@ -1215,6 +1228,9 @@ __export(index_node_exports, {
1215
1228
  LineageReadError: () => LineageReadError,
1216
1229
  MASTER_KEY_MESSAGE: () => MASTER_KEY_MESSAGE,
1217
1230
  MAX_LINEAGE_SOURCES: () => MAX_LINEAGE_SOURCES,
1231
+ MAX_QUESTION_CHARS: () => MAX_QUESTION_CHARS,
1232
+ MAX_QUESTION_MODEL_CHARS: () => MAX_QUESTION_MODEL_CHARS,
1233
+ MAX_QUESTION_SOURCE_SCOPES: () => MAX_QUESTION_SOURCE_SCOPES,
1218
1234
  MissingAuthError: () => MissingAuthError,
1219
1235
  NATIVE_ASSET_ADDRESS: () => NATIVE_ASSET_ADDRESS,
1220
1236
  NATIVE_VANA_ASSET: () => NATIVE_VANA_ASSET,
@@ -1235,6 +1251,11 @@ __export(index_node_exports, {
1235
1251
  PersonalServerError: () => PersonalServerError,
1236
1252
  PersonalServerWriteError: () => PersonalServerWriteError,
1237
1253
  PinataStorage: () => PinataStorage,
1254
+ QUESTION_STATUSES: () => QUESTION_STATUSES,
1255
+ QuestionDeleteResultSchema: () => QuestionDeleteResultSchema,
1256
+ QuestionRecomputeResultSchema: () => QuestionRecomputeResultSchema,
1257
+ QuestionRegisteredBySchema: () => QuestionRegisteredBySchema,
1258
+ QuestionStatusSchema: () => QuestionStatusSchema,
1238
1259
  R2Storage: () => R2Storage,
1239
1260
  RECORD_DATA_ACCESS_TYPES: () => RECORD_DATA_ACCESS_TYPES,
1240
1261
  REGISTRATION_KIND_FOR_OP: () => REGISTRATION_KIND_FOR_OP,
@@ -1273,6 +1294,7 @@ __export(index_node_exports, {
1273
1294
  WriteSessionExpiredError: () => WriteSessionExpiredError,
1274
1295
  WriteTransportError: () => WriteTransportError,
1275
1296
  WriteUnauthorizedError: () => WriteUnauthorizedError,
1297
+ askPersonalServer: () => askPersonalServer,
1276
1298
  assertDerivedScopeNaming: () => assertDerivedScopeNaming,
1277
1299
  assertValidPkceVerifier: () => assertValidPkceVerifier,
1278
1300
  authorizeEscrowPayment: () => authorizeEscrowPayment,
@@ -1316,6 +1338,7 @@ __export(index_node_exports, {
1316
1338
  dataRegistryDomain: () => dataRegistryDomain,
1317
1339
  decryptWithPassword: () => decryptWithPassword,
1318
1340
  deleteDataPoint: () => deleteDataPoint,
1341
+ deleteQuestion: () => deleteQuestion,
1319
1342
  deriveDataPointId: () => deriveDataPointId,
1320
1343
  deriveMasterKey: () => deriveMasterKey,
1321
1344
  deriveScopeKey: () => deriveScopeKey,
@@ -1345,6 +1368,7 @@ __export(index_node_exports, {
1345
1368
  getOpFee: () => getOpFee,
1346
1369
  getPersonalServerLineage: () => getPersonalServerLineage,
1347
1370
  getPlatformCapabilities: () => getPlatformCapabilities,
1371
+ getQuestion: () => getQuestion,
1348
1372
  getServiceEndpoints: () => getServiceEndpoints,
1349
1373
  grantPermissions: () => grantPermissions,
1350
1374
  grantRegistrationDomain: () => grantRegistrationDomain,
@@ -1357,6 +1381,7 @@ __export(index_node_exports, {
1357
1381
  isPlatformSupported: () => isPlatformSupported,
1358
1382
  isRedactedLineageNode: () => isRedactedLineageNode,
1359
1383
  isTombstoneHashes: () => isTombstoneHashes,
1384
+ listQuestions: () => listQuestions,
1360
1385
  mainnetServices: () => mainnetServices,
1361
1386
  moksha: () => moksha,
1362
1387
  mokshaServices: () => mokshaServices,
@@ -1376,8 +1401,10 @@ __export(index_node_exports, {
1376
1401
  personalServerLineagePath: () => personalServerLineagePath,
1377
1402
  personalServerRegistrationDomain: () => personalServerRegistrationDomain,
1378
1403
  readPersonalServerData: () => readPersonalServerData,
1404
+ recomputeQuestion: () => recomputeQuestion,
1379
1405
  recoverServerOwner: () => recoverServerOwner,
1380
1406
  registerPersonalServerSignature: () => registerPersonalServerSignature,
1407
+ registerQuestion: () => registerQuestion,
1381
1408
  resolveWriteSigner: () => resolveWriteSigner,
1382
1409
  scopeCoveredByGrant: () => scopeCoveredByGrant,
1383
1410
  scopeMatchesPattern: () => scopeMatchesPattern,
@@ -1397,6 +1424,7 @@ __export(index_node_exports, {
1397
1424
  verifyGrantRegistration: () => verifyGrantRegistration,
1398
1425
  verifyPkceChallenge: () => verifyPkceChallenge,
1399
1426
  verifyWeb3Signed: () => verifyWeb3Signed,
1427
+ waitForQuestion: () => waitForQuestion,
1400
1428
  writeData: () => writeData,
1401
1429
  writePersonalServerData: () => writePersonalServerData
1402
1430
  });
@@ -1613,6 +1641,57 @@ var LineageReadError = class extends VanaError {
1613
1641
  errorCode;
1614
1642
  details;
1615
1643
  };
1644
+ var DerivativeQuestionRejectedError = class extends PersonalServerWriteError {
1645
+ constructor(message, status, errorCode = null, details) {
1646
+ super(message, "DERIVATIVE_QUESTION_REJECTED", status, errorCode, details);
1647
+ }
1648
+ };
1649
+ var DerivativeQuestionInvalidError = class extends PersonalServerWriteError {
1650
+ constructor(message, status = 400, errorCode = null, details) {
1651
+ super(message, "DERIVATIVE_QUESTION_INVALID", status, errorCode, details);
1652
+ }
1653
+ };
1654
+ var DerivativeQuestionNotFoundError = class extends PersonalServerWriteError {
1655
+ constructor(message, errorCode = null, details) {
1656
+ super(message, "DERIVATIVE_QUESTION_NOT_FOUND", 404, errorCode, details);
1657
+ }
1658
+ };
1659
+ var DerivativeDerivedScopeRequiredError = class extends PersonalServerWriteError {
1660
+ constructor(message, errorCode = null, details) {
1661
+ super(
1662
+ message,
1663
+ "DERIVATIVE_DERIVED_SCOPE_REQUIRED",
1664
+ 400,
1665
+ errorCode,
1666
+ details
1667
+ );
1668
+ }
1669
+ };
1670
+ var DerivativeSourceNotGrantedError = class extends PersonalServerWriteError {
1671
+ constructor(message, errorCode = null, details) {
1672
+ super(message, "DERIVATIVE_SOURCE_NOT_GRANTED", 403, errorCode, details);
1673
+ }
1674
+ };
1675
+ var DerivativeCycleError = class extends PersonalServerWriteError {
1676
+ constructor(message, errorCode = null, details) {
1677
+ super(message, "DERIVATIVE_CYCLE", 409, errorCode, details);
1678
+ }
1679
+ };
1680
+ var DerivativeComputeUnavailableError = class extends PersonalServerWriteError {
1681
+ constructor(message, errorCode = null, details) {
1682
+ super(message, "DERIVATIVE_COMPUTE_UNAVAILABLE", 503, errorCode, details);
1683
+ }
1684
+ };
1685
+ var DerivativeQuestionTimeoutError = class extends PersonalServerWriteError {
1686
+ constructor(message, details) {
1687
+ super(message, "DERIVATIVE_QUESTION_TIMEOUT", void 0, null, details);
1688
+ }
1689
+ };
1690
+ var DerivativeQuestionFailedError = class extends PersonalServerWriteError {
1691
+ constructor(message, details) {
1692
+ super(message, "DERIVATIVE_QUESTION_FAILED", void 0, null, details);
1693
+ }
1694
+ };
1616
1695
  var DataPointDeletedError = class extends VanaError {
1617
1696
  constructor(message, details = {}) {
1618
1697
  super(message, "DATA_POINT_DELETED");
@@ -29364,6 +29443,9 @@ async function buildWeb3SignedHeader(params) {
29364
29443
  if (params.grantId !== void 0) {
29365
29444
  payload["grantId"] = params.grantId;
29366
29445
  }
29446
+ if (params.nonce !== void 0) {
29447
+ payload["nonce"] = params.nonce;
29448
+ }
29367
29449
  const sortedPayload = Object.keys(payload).sort().reduce((acc, key) => {
29368
29450
  acc[key] = payload[key];
29369
29451
  return acc;
@@ -34621,32 +34703,13 @@ function tryGrantPermissions(scopes) {
34621
34703
  }
34622
34704
 
34623
34705
  // src/protocol/personal-server-write.ts
34706
+ var import_sha26 = require("@noble/hashes/sha2");
34707
+ var import_viem24 = require("viem");
34708
+ var import_zod4 = require("zod");
34709
+
34710
+ // src/protocol/write-request.ts
34624
34711
  var import_sha25 = require("@noble/hashes/sha2");
34625
34712
  var import_viem23 = require("viem");
34626
- var import_zod4 = require("zod");
34627
- var WRITE_SESSION_PATH = "/v1/write/session";
34628
- var WRITE_SIGNATURE_HEADER = "X-Vana-Write-Signature";
34629
- var WRITE_METADATA_HEADER = "X-Vana-Metadata";
34630
- var LINEAGE_FIELD = "lineage";
34631
- var MAX_LINEAGE_SOURCES = 256;
34632
- var WRITE_FILENAME_HEADER = "X-Filename";
34633
- var WRITE_CONTENT_DISPOSITION_HEADER = "Content-Disposition";
34634
- var WRITER_ATTRIBUTION_KEY = "$writtenBy";
34635
- var LINEAGE_KEY = "$lineage";
34636
- var RESERVED_WRITE_KEYS = [
34637
- WRITER_ATTRIBUTION_KEY,
34638
- LINEAGE_KEY
34639
- ];
34640
- var WriteDataResultSchema = IngestResponseSchema.extend({
34641
- // Present when the write carried lineage: the validated, lowercased ids.
34642
- lineage: import_zod4.z.object({ sources: import_zod4.z.array(import_zod4.z.string()) }).optional()
34643
- });
34644
- var WriteSessionResponseSchema = import_zod4.z.object({
34645
- access_token: import_zod4.z.string().min(1),
34646
- token_type: import_zod4.z.string(),
34647
- expires_in: import_zod4.z.number().nonnegative(),
34648
- scope: import_zod4.z.string()
34649
- });
34650
34713
  function normalizeBaseUrl2(url) {
34651
34714
  return url.replace(/\/+$/, "");
34652
34715
  }
@@ -34657,9 +34720,6 @@ function resolveFetch2(fetchFn) {
34657
34720
  }
34658
34721
  return resolved;
34659
34722
  }
34660
- function dataPath(scope) {
34661
- return `/v1/data/${encodeURIComponent(scope)}`;
34662
- }
34663
34723
  function errorMessage(err) {
34664
34724
  return err instanceof Error ? err.message : String(err);
34665
34725
  }
@@ -34710,6 +34770,18 @@ function nextProofIat(proofKey) {
34710
34770
  if (waitSec <= 0) return Promise.resolve(iat);
34711
34771
  return sleep2(waitSec * 1e3).then(() => iat);
34712
34772
  }
34773
+ function freshProofNonce() {
34774
+ const webCrypto = globalThis.crypto;
34775
+ if (typeof webCrypto?.randomUUID === "function") {
34776
+ return webCrypto.randomUUID();
34777
+ }
34778
+ if (typeof webCrypto?.getRandomValues === "function") {
34779
+ return (0, import_viem23.bytesToHex)(webCrypto.getRandomValues(new Uint8Array(16)));
34780
+ }
34781
+ throw new WriteRequestError(
34782
+ "No secure random source available to build a proof nonce; provide a crypto global"
34783
+ );
34784
+ }
34713
34785
  function proofKeyFor(parts) {
34714
34786
  return (0, import_viem23.bytesToHex)(
34715
34787
  (0, import_sha25.sha256)(
@@ -34747,6 +34819,34 @@ async function sendWithFreshProof(label, fetchFn, options, proofKey, build) {
34747
34819
  lastError
34748
34820
  );
34749
34821
  }
34822
+
34823
+ // src/protocol/personal-server-write.ts
34824
+ var WRITE_SESSION_PATH = "/v1/write/session";
34825
+ var WRITE_SIGNATURE_HEADER = "X-Vana-Write-Signature";
34826
+ var WRITE_METADATA_HEADER = "X-Vana-Metadata";
34827
+ var LINEAGE_FIELD = "lineage";
34828
+ var MAX_LINEAGE_SOURCES = 256;
34829
+ var WRITE_FILENAME_HEADER = "X-Filename";
34830
+ var WRITE_CONTENT_DISPOSITION_HEADER = "Content-Disposition";
34831
+ var WRITER_ATTRIBUTION_KEY = "$writtenBy";
34832
+ var LINEAGE_KEY = "$lineage";
34833
+ var RESERVED_WRITE_KEYS = [
34834
+ WRITER_ATTRIBUTION_KEY,
34835
+ LINEAGE_KEY
34836
+ ];
34837
+ var WriteDataResultSchema = IngestResponseSchema.extend({
34838
+ // Present when the write carried lineage: the validated, lowercased ids.
34839
+ lineage: import_zod4.z.object({ sources: import_zod4.z.array(import_zod4.z.string()) }).optional()
34840
+ });
34841
+ var WriteSessionResponseSchema = import_zod4.z.object({
34842
+ access_token: import_zod4.z.string().min(1),
34843
+ token_type: import_zod4.z.string(),
34844
+ expires_in: import_zod4.z.number().nonnegative(),
34845
+ scope: import_zod4.z.string()
34846
+ });
34847
+ function dataPath(scope) {
34848
+ return `/v1/data/${encodeURIComponent(scope)}`;
34849
+ }
34750
34850
  async function openWriteSession(params) {
34751
34851
  const fetchFn = resolveFetch2(params.fetch);
34752
34852
  const personalServerUrl = normalizeBaseUrl2(params.personalServerUrl);
@@ -34878,7 +34978,7 @@ function binaryWriteSignedBytes(input) {
34878
34978
  mimeType: normalizeBinaryMimeType(input.contentType),
34879
34979
  ...input.filename ? { filename: input.filename } : {},
34880
34980
  sizeBytes: input.bytes.length,
34881
- contentHash: (0, import_viem23.bytesToHex)((0, import_sha25.sha256)(input.bytes)),
34981
+ contentHash: (0, import_viem24.bytesToHex)((0, import_sha26.sha256)(input.bytes)),
34882
34982
  encoding: "base64",
34883
34983
  content: toBase64(input.bytes),
34884
34984
  ...metadata !== void 0 ? { metadata } : {}
@@ -34926,7 +35026,7 @@ function normalizeLineage(lineage, derivedScope) {
34926
35026
  for (const entry of lineage) {
34927
35027
  let id;
34928
35028
  if (isLineagePair(entry)) {
34929
- if (!(0, import_viem23.isAddress)(entry.ownerAddress, { strict: false })) {
35029
+ if (!(0, import_viem24.isAddress)(entry.ownerAddress, { strict: false })) {
34930
35030
  throw new WriteRequestError(
34931
35031
  "lineage source ownerAddress must be an EVM address",
34932
35032
  { ownerAddress: entry.ownerAddress }
@@ -35175,6 +35275,454 @@ async function writePersonalServerData(params) {
35175
35275
  return { ...result, session };
35176
35276
  }
35177
35277
 
35278
+ // src/protocol/derivative-questions.ts
35279
+ var import_zod5 = require("zod");
35280
+ var DERIVATIVE_QUESTIONS_PATH = "/v1/derivatives/questions";
35281
+ var MAX_QUESTION_SOURCE_SCOPES = 16;
35282
+ var MAX_QUESTION_CHARS = 8e3;
35283
+ var MAX_QUESTION_MODEL_CHARS = 128;
35284
+ var MODEL_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:/-]*$/;
35285
+ var DEFAULT_QUESTION_TIMEOUT_MS = 12e4;
35286
+ var DEFAULT_QUESTION_POLL_INTERVAL_MS = 2e3;
35287
+ var SESSION_REFRESH_SKEW_MS = 3e4;
35288
+ var QUESTION_STATUSES = [
35289
+ "pending",
35290
+ "ready",
35291
+ "failed",
35292
+ "stale"
35293
+ ];
35294
+ var QuestionStatusSchema = import_zod5.z.enum(QUESTION_STATUSES);
35295
+ var QuestionRegisteredBySchema = import_zod5.z.union([
35296
+ import_zod5.z.object({ kind: import_zod5.z.literal("owner") }),
35297
+ import_zod5.z.object({
35298
+ kind: import_zod5.z.literal("builder"),
35299
+ builder: import_zod5.z.string(),
35300
+ grantId: import_zod5.z.string()
35301
+ })
35302
+ ]);
35303
+ var nullableString = import_zod5.z.string().nullish().transform((value) => value ?? null);
35304
+ var DerivativeQuestionSchema = import_zod5.z.object({
35305
+ questionId: import_zod5.z.string().min(1),
35306
+ derivedScope: import_zod5.z.string().min(1),
35307
+ sourceScopes: import_zod5.z.array(import_zod5.z.string()),
35308
+ question: import_zod5.z.string(),
35309
+ /** The model override, or `null` for the server's default. */
35310
+ model: nullableString,
35311
+ registeredBy: QuestionRegisteredBySchema,
35312
+ status: QuestionStatusSchema,
35313
+ /** A short reason, set only while `status` is `failed`. */
35314
+ error: nullableString,
35315
+ createdAt: import_zod5.z.string(),
35316
+ updatedAt: nullableString,
35317
+ /** When the last compute finished, or `null` while `pending`. */
35318
+ lastComputedAt: nullableString,
35319
+ /** Local version of the derived record the last compute wrote. */
35320
+ derivedVersion: import_zod5.z.number().nullish().transform((value) => value ?? null),
35321
+ derivedCollectedAt: nullableString
35322
+ });
35323
+ var QuestionListSchema = import_zod5.z.object({
35324
+ questions: import_zod5.z.array(DerivativeQuestionSchema)
35325
+ });
35326
+ var QuestionRecomputeResultSchema = DerivativeQuestionSchema;
35327
+ var QuestionDeleteResultSchema = import_zod5.z.object({
35328
+ questionId: import_zod5.z.string().min(1),
35329
+ deleted: import_zod5.z.literal(true)
35330
+ });
35331
+ var sessionsBySigner = /* @__PURE__ */ new WeakMap();
35332
+ function sessionCacheKey(personalServerUrl, audience, grantId, fetchFn) {
35333
+ return JSON.stringify([personalServerUrl, audience, grantId]) + fetchIdOf(fetchFn);
35334
+ }
35335
+ var fetchIds = /* @__PURE__ */ new WeakMap();
35336
+ var nextFetchId = 0;
35337
+ function fetchIdOf(fetchFn) {
35338
+ let id = fetchIds.get(fetchFn);
35339
+ if (id === void 0) {
35340
+ id = ++nextFetchId;
35341
+ fetchIds.set(fetchFn, id);
35342
+ }
35343
+ return `#${id}`;
35344
+ }
35345
+ function resolveRequest(params) {
35346
+ if (typeof params.personalServerUrl !== "string" || params.personalServerUrl.length === 0) {
35347
+ throw new WriteRequestError("personalServerUrl is required");
35348
+ }
35349
+ if (typeof params.grantId !== "string" || params.grantId.length === 0) {
35350
+ throw new WriteRequestError(
35351
+ "grantId is required; a question call runs under the grant carrying write:<derivedScope>"
35352
+ );
35353
+ }
35354
+ if (params.signer === null || typeof params.signer !== "object") {
35355
+ throw new WriteRequestError(
35356
+ "signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
35357
+ );
35358
+ }
35359
+ const fetchFn = resolveFetch2(params.fetch);
35360
+ const baseUrl = normalizeBaseUrl2(params.personalServerUrl);
35361
+ const audience = params.audience ?? baseUrl;
35362
+ return {
35363
+ baseUrl,
35364
+ audience,
35365
+ fetchFn,
35366
+ cacheKey: sessionCacheKey(baseUrl, audience, params.grantId, fetchFn),
35367
+ signerKey: params.signer
35368
+ };
35369
+ }
35370
+ async function resolveSession(params, resolved, force) {
35371
+ let cache = sessionsBySigner.get(resolved.signerKey);
35372
+ if (cache === void 0) {
35373
+ cache = /* @__PURE__ */ new Map();
35374
+ sessionsBySigner.set(resolved.signerKey, cache);
35375
+ }
35376
+ const cached = cache.get(resolved.cacheKey);
35377
+ if (!force && cached !== void 0 && cached.expiresAt > Date.now() + SESSION_REFRESH_SKEW_MS) {
35378
+ return cached;
35379
+ }
35380
+ if (force) cache.delete(resolved.cacheKey);
35381
+ const session = await openWriteSession({
35382
+ personalServerUrl: resolved.baseUrl,
35383
+ signer: params.signer,
35384
+ grantId: params.grantId,
35385
+ account: params.account,
35386
+ audience: resolved.audience,
35387
+ fetch: resolved.fetchFn,
35388
+ headers: params.headers,
35389
+ retry: params.retry
35390
+ });
35391
+ cache.set(resolved.cacheKey, session);
35392
+ return session;
35393
+ }
35394
+ var PROOF_FAILURE_CODES = /* @__PURE__ */ new Set([
35395
+ "WRITE_ATTRIBUTION_REQUIRED",
35396
+ "WRITE_ATTRIBUTION_INVALID",
35397
+ "WRITE_ATTRIBUTION_SIGNER_MISMATCH",
35398
+ "WRITE_ATTRIBUTION_GRANT_MISMATCH",
35399
+ "WRITE_ATTRIBUTION_REPLAY"
35400
+ ]);
35401
+ function isStaleSession(errorCode) {
35402
+ return errorCode === null || !PROOF_FAILURE_CODES.has(errorCode);
35403
+ }
35404
+ async function questionErrorFromResponse(response, body) {
35405
+ const { errorCode, message, details } = body ?? await readPersonalServerErrorBody(response);
35406
+ const text = message ?? `Derivative question request failed: ${response.status} ${response.statusText}`;
35407
+ switch (errorCode) {
35408
+ case "DERIVATIVE_SOURCE_NOT_GRANTED":
35409
+ return new DerivativeSourceNotGrantedError(text, errorCode, details);
35410
+ case "DERIVATIVE_CYCLE":
35411
+ return new DerivativeCycleError(text, errorCode, details);
35412
+ case "DERIVATIVE_COMPUTE_UNAVAILABLE":
35413
+ return new DerivativeComputeUnavailableError(text, errorCode, details);
35414
+ case "DERIVATIVE_QUESTION_INVALID":
35415
+ case "LINEAGE_SCOPE_UNDER_SOURCE_PREFIX":
35416
+ return new DerivativeQuestionInvalidError(
35417
+ text,
35418
+ response.status,
35419
+ errorCode,
35420
+ details
35421
+ );
35422
+ case "DERIVATIVE_QUESTION_NOT_FOUND":
35423
+ return new DerivativeQuestionNotFoundError(text, errorCode, details);
35424
+ case "DERIVATIVE_DERIVED_SCOPE_REQUIRED":
35425
+ return new DerivativeDerivedScopeRequiredError(text, errorCode, details);
35426
+ default:
35427
+ break;
35428
+ }
35429
+ switch (response.status) {
35430
+ case 401:
35431
+ return new WriteUnauthorizedError(text, errorCode, details);
35432
+ case 403:
35433
+ return new WriteForbiddenError(text, errorCode, details);
35434
+ case 404:
35435
+ return new DerivativeQuestionNotFoundError(text, errorCode, details);
35436
+ case 409:
35437
+ return new WriteConflictError(text, errorCode, details);
35438
+ default:
35439
+ return new DerivativeQuestionRejectedError(
35440
+ text,
35441
+ response.status,
35442
+ errorCode,
35443
+ details
35444
+ );
35445
+ }
35446
+ }
35447
+ async function sendOnce(params, resolved, session, spec, bodyBytes) {
35448
+ return sendWithFreshProof(
35449
+ spec.label,
35450
+ resolved.fetchFn,
35451
+ params.retry,
35452
+ proofKeyFor({
35453
+ aud: session.audience,
35454
+ method: spec.method,
35455
+ uri: spec.target,
35456
+ grantId: session.grantId,
35457
+ signedBytes: bodyBytes
35458
+ }),
35459
+ async (iat) => {
35460
+ const headers = new Headers(params.headers);
35461
+ headers.set("Accept", "application/json");
35462
+ headers.set("Authorization", `Bearer ${session.accessToken}`);
35463
+ if (bodyBytes !== void 0) {
35464
+ headers.set("Content-Type", "application/json");
35465
+ }
35466
+ headers.set(
35467
+ WRITE_SIGNATURE_HEADER,
35468
+ await buildWeb3SignedHeader({
35469
+ signMessage: session.signer.signMessage,
35470
+ aud: session.audience,
35471
+ // The proof commits to the whole request target, query included:
35472
+ // `?derivedScope=` is what the list route authorizes against, and a
35473
+ // proof that did not cover it would authorize any other scope.
35474
+ uri: spec.target,
35475
+ method: spec.method,
35476
+ body: bodyBytes,
35477
+ grantId: session.grantId,
35478
+ // Fresh per attempt, so a retry after a thrown `fetch` is never the
35479
+ // proof the server may already have consumed, and so two identical
35480
+ // polls inside one second stay distinct.
35481
+ nonce: freshProofNonce(),
35482
+ iat
35483
+ })
35484
+ );
35485
+ return {
35486
+ url: `${resolved.baseUrl}${spec.target}`,
35487
+ init: {
35488
+ method: spec.method,
35489
+ headers,
35490
+ ...bodyBytes === void 0 ? {} : { body: bodyBytes },
35491
+ ...params.signal ? { signal: params.signal } : {}
35492
+ }
35493
+ };
35494
+ }
35495
+ );
35496
+ }
35497
+ async function sendQuestionRequest(params, spec, schema) {
35498
+ const resolved = resolveRequest(params);
35499
+ const bodyBytes = spec.body === void 0 ? void 0 : new TextEncoder().encode(JSON.stringify(spec.body));
35500
+ let session = await resolveSession(params, resolved, false);
35501
+ let response = await sendOnce(params, resolved, session, spec, bodyBytes);
35502
+ let errorBody;
35503
+ if (response.status === 401) {
35504
+ errorBody = await readPersonalServerErrorBody(response);
35505
+ if (isStaleSession(errorBody.errorCode)) {
35506
+ session = await resolveSession(params, resolved, true);
35507
+ response = await sendOnce(params, resolved, session, spec, bodyBytes);
35508
+ errorBody = void 0;
35509
+ }
35510
+ }
35511
+ if (!response.ok) {
35512
+ throw await questionErrorFromResponse(response, errorBody);
35513
+ }
35514
+ let body;
35515
+ try {
35516
+ body = await response.json();
35517
+ } catch (err) {
35518
+ throw new DerivativeQuestionRejectedError(
35519
+ `${spec.label} response is not JSON`,
35520
+ response.status,
35521
+ null,
35522
+ { cause: errorMessage(err) }
35523
+ );
35524
+ }
35525
+ const parsed = schema.safeParse(body);
35526
+ if (!parsed.success) {
35527
+ throw new DerivativeQuestionRejectedError(
35528
+ `${spec.label} response is not a derivative question answer`,
35529
+ response.status,
35530
+ null,
35531
+ { issues: parsed.error.issues }
35532
+ );
35533
+ }
35534
+ return parsed.data;
35535
+ }
35536
+ function assertQuestionId(questionId) {
35537
+ if (typeof questionId !== "string" || questionId.length === 0) {
35538
+ throw new WriteRequestError("questionId is required");
35539
+ }
35540
+ return `${DERIVATIVE_QUESTIONS_PATH}/${encodeURIComponent(questionId)}`;
35541
+ }
35542
+ function registrationBody(params) {
35543
+ const { derivedScope, question } = params;
35544
+ if (typeof derivedScope !== "string" || derivedScope.length === 0) {
35545
+ throw new WriteRequestError("derivedScope is required");
35546
+ }
35547
+ if (!Array.isArray(params.sourceScopes) || params.sourceScopes.length === 0) {
35548
+ throw new WriteRequestError(
35549
+ "sourceScopes must be a non-empty array of scopes"
35550
+ );
35551
+ }
35552
+ if (params.sourceScopes.length > MAX_QUESTION_SOURCE_SCOPES) {
35553
+ throw new WriteRequestError(
35554
+ `sourceScopes lists ${params.sourceScopes.length} scopes; the maximum is ${MAX_QUESTION_SOURCE_SCOPES}`,
35555
+ { max: MAX_QUESTION_SOURCE_SCOPES, count: params.sourceScopes.length }
35556
+ );
35557
+ }
35558
+ const sourceScopes = [];
35559
+ for (const scope of params.sourceScopes) {
35560
+ if (typeof scope !== "string" || scope.length === 0) {
35561
+ throw new WriteRequestError("sourceScopes entries must be scope strings");
35562
+ }
35563
+ if (sourceScopes.includes(scope)) {
35564
+ throw new WriteRequestError("sourceScopes must not repeat a scope", {
35565
+ duplicate: scope
35566
+ });
35567
+ }
35568
+ if (scope === derivedScope) {
35569
+ throw new WriteRequestError(
35570
+ "derivedScope cannot be one of its own sources",
35571
+ { scope }
35572
+ );
35573
+ }
35574
+ sourceScopes.push(scope);
35575
+ }
35576
+ if (typeof question !== "string" || question.trim() === "") {
35577
+ throw new WriteRequestError("question must be a non-empty string");
35578
+ }
35579
+ if (question.length > MAX_QUESTION_CHARS) {
35580
+ throw new WriteRequestError(
35581
+ `question is ${question.length} characters; the maximum is ${MAX_QUESTION_CHARS}`,
35582
+ { max: MAX_QUESTION_CHARS, length: question.length }
35583
+ );
35584
+ }
35585
+ if (params.model !== void 0) {
35586
+ if (typeof params.model !== "string" || params.model.length > MAX_QUESTION_MODEL_CHARS || !MODEL_ID_PATTERN.test(params.model)) {
35587
+ throw new WriteRequestError("model must be a provider model id", {
35588
+ model: params.model
35589
+ });
35590
+ }
35591
+ }
35592
+ assertDerivedScopeNaming(derivedScope, sourceScopes);
35593
+ return {
35594
+ derivedScope,
35595
+ sourceScopes,
35596
+ question,
35597
+ ...params.model === void 0 ? {} : { model: params.model }
35598
+ };
35599
+ }
35600
+ async function registerQuestion(params) {
35601
+ const body = registrationBody(params);
35602
+ return sendQuestionRequest(
35603
+ params,
35604
+ {
35605
+ method: "POST",
35606
+ target: DERIVATIVE_QUESTIONS_PATH,
35607
+ body,
35608
+ label: "Register derivative question"
35609
+ },
35610
+ DerivativeQuestionSchema
35611
+ );
35612
+ }
35613
+ async function getQuestion(params) {
35614
+ const target = assertQuestionId(params.questionId);
35615
+ return sendQuestionRequest(
35616
+ params,
35617
+ { method: "GET", target, label: "Read derivative question" },
35618
+ DerivativeQuestionSchema
35619
+ );
35620
+ }
35621
+ async function listQuestions(params) {
35622
+ if (typeof params.derivedScope !== "string" || params.derivedScope.length === 0) {
35623
+ throw new WriteRequestError(
35624
+ "derivedScope is required; a builder may only list its own questions on a scope it may write"
35625
+ );
35626
+ }
35627
+ const target = `${DERIVATIVE_QUESTIONS_PATH}?derivedScope=${encodeURIComponent(params.derivedScope)}`;
35628
+ const { questions } = await sendQuestionRequest(
35629
+ params,
35630
+ {
35631
+ method: "GET",
35632
+ target,
35633
+ label: "List derivative questions"
35634
+ },
35635
+ QuestionListSchema
35636
+ );
35637
+ return questions;
35638
+ }
35639
+ async function recomputeQuestion(params) {
35640
+ const target = `${assertQuestionId(params.questionId)}/recompute`;
35641
+ return sendQuestionRequest(
35642
+ params,
35643
+ { method: "POST", target, label: "Recompute derivative question" },
35644
+ QuestionRecomputeResultSchema
35645
+ );
35646
+ }
35647
+ async function deleteQuestion(params) {
35648
+ const target = assertQuestionId(params.questionId);
35649
+ return sendQuestionRequest(
35650
+ params,
35651
+ { method: "DELETE", target, label: "Delete derivative question" },
35652
+ QuestionDeleteResultSchema
35653
+ );
35654
+ }
35655
+ function isSettled(status) {
35656
+ return status === "ready" || status === "failed";
35657
+ }
35658
+ function abortError(signal) {
35659
+ const reason = signal.reason;
35660
+ if (reason instanceof Error) return reason;
35661
+ const error = new Error("The operation was aborted");
35662
+ error.name = "AbortError";
35663
+ return error;
35664
+ }
35665
+ async function waitForQuestion(params) {
35666
+ const timeoutMs = Math.max(
35667
+ 0,
35668
+ params.timeoutMs ?? DEFAULT_QUESTION_TIMEOUT_MS
35669
+ );
35670
+ const pollIntervalMs = Math.max(
35671
+ 0,
35672
+ params.pollIntervalMs ?? DEFAULT_QUESTION_POLL_INTERVAL_MS
35673
+ );
35674
+ const deadline = Date.now() + timeoutMs;
35675
+ for (; ; ) {
35676
+ if (params.signal?.aborted) throw abortError(params.signal);
35677
+ const latest = await getQuestion(params);
35678
+ if (isSettled(latest.status)) return latest;
35679
+ const remaining = deadline - Date.now();
35680
+ if (remaining <= 0) {
35681
+ throw new DerivativeQuestionTimeoutError(
35682
+ `Derivative question ${latest.questionId} was still ${latest.status} after ${timeoutMs}ms`,
35683
+ {
35684
+ questionId: latest.questionId,
35685
+ derivedScope: latest.derivedScope,
35686
+ status: latest.status,
35687
+ timeoutMs
35688
+ }
35689
+ );
35690
+ }
35691
+ await sleep2(Math.min(pollIntervalMs, remaining));
35692
+ }
35693
+ }
35694
+ async function askPersonalServer(params) {
35695
+ const registered = await registerQuestion(params);
35696
+ const registration = await waitForQuestion({
35697
+ ...params,
35698
+ questionId: registered.questionId
35699
+ });
35700
+ if (registration.status !== "ready") {
35701
+ throw new DerivativeQuestionFailedError(
35702
+ `Derivative question ${registration.questionId} failed: ${registration.error ?? "no reason given"}`,
35703
+ {
35704
+ questionId: registration.questionId,
35705
+ derivedScope: registration.derivedScope,
35706
+ error: registration.error
35707
+ }
35708
+ );
35709
+ }
35710
+ const signer = resolveWriteSigner(params.signer, {
35711
+ account: params.account
35712
+ });
35713
+ const readParams = {
35714
+ personalServerUrl: normalizeBaseUrl2(params.personalServerUrl),
35715
+ scope: params.derivedScope,
35716
+ grantId: params.grantId,
35717
+ signMessage: signer.signMessage,
35718
+ ...params.audience === void 0 ? {} : { audience: params.audience },
35719
+ ...params.headers === void 0 ? {} : { headers: params.headers },
35720
+ ...params.fetch === void 0 ? {} : { fetch: params.fetch }
35721
+ };
35722
+ const record = await readPersonalServerData(readParams);
35723
+ return { registration, record };
35724
+ }
35725
+
35178
35726
  // src/protocol/gateway.ts
35179
35727
  function withGrantPermissions(grant) {
35180
35728
  const stripped = { ...grant };
@@ -36256,11 +36804,24 @@ async function parsePSError(response) {
36256
36804
  ContractNotFoundError,
36257
36805
  DATA_ACCESS_OP_TYPE,
36258
36806
  DATA_REGISTRY_STATUS_ABI,
36807
+ DEFAULT_QUESTION_POLL_INTERVAL_MS,
36808
+ DEFAULT_QUESTION_TIMEOUT_MS,
36809
+ DERIVATIVE_QUESTIONS_PATH,
36259
36810
  DataFileEnvelopeSchema,
36260
36811
  DataPointDeletedError,
36261
36812
  DataPointNotFoundError,
36262
36813
  DataPointStatus,
36263
36814
  DataPointVersionConflictError,
36815
+ DerivativeComputeUnavailableError,
36816
+ DerivativeCycleError,
36817
+ DerivativeDerivedScopeRequiredError,
36818
+ DerivativeQuestionFailedError,
36819
+ DerivativeQuestionInvalidError,
36820
+ DerivativeQuestionNotFoundError,
36821
+ DerivativeQuestionRejectedError,
36822
+ DerivativeQuestionSchema,
36823
+ DerivativeQuestionTimeoutError,
36824
+ DerivativeSourceNotGrantedError,
36264
36825
  DropboxStorage,
36265
36826
  ECIESError,
36266
36827
  ESCROW_DEPOSIT_ABI,
@@ -36285,6 +36846,9 @@ async function parsePSError(response) {
36285
36846
  LineageReadError,
36286
36847
  MASTER_KEY_MESSAGE,
36287
36848
  MAX_LINEAGE_SOURCES,
36849
+ MAX_QUESTION_CHARS,
36850
+ MAX_QUESTION_MODEL_CHARS,
36851
+ MAX_QUESTION_SOURCE_SCOPES,
36288
36852
  MissingAuthError,
36289
36853
  NATIVE_ASSET_ADDRESS,
36290
36854
  NATIVE_VANA_ASSET,
@@ -36305,6 +36869,11 @@ async function parsePSError(response) {
36305
36869
  PersonalServerError,
36306
36870
  PersonalServerWriteError,
36307
36871
  PinataStorage,
36872
+ QUESTION_STATUSES,
36873
+ QuestionDeleteResultSchema,
36874
+ QuestionRecomputeResultSchema,
36875
+ QuestionRegisteredBySchema,
36876
+ QuestionStatusSchema,
36308
36877
  R2Storage,
36309
36878
  RECORD_DATA_ACCESS_TYPES,
36310
36879
  REGISTRATION_KIND_FOR_OP,
@@ -36343,6 +36912,7 @@ async function parsePSError(response) {
36343
36912
  WriteSessionExpiredError,
36344
36913
  WriteTransportError,
36345
36914
  WriteUnauthorizedError,
36915
+ askPersonalServer,
36346
36916
  assertDerivedScopeNaming,
36347
36917
  assertValidPkceVerifier,
36348
36918
  authorizeEscrowPayment,
@@ -36386,6 +36956,7 @@ async function parsePSError(response) {
36386
36956
  dataRegistryDomain,
36387
36957
  decryptWithPassword,
36388
36958
  deleteDataPoint,
36959
+ deleteQuestion,
36389
36960
  deriveDataPointId,
36390
36961
  deriveMasterKey,
36391
36962
  deriveScopeKey,
@@ -36415,6 +36986,7 @@ async function parsePSError(response) {
36415
36986
  getOpFee,
36416
36987
  getPersonalServerLineage,
36417
36988
  getPlatformCapabilities,
36989
+ getQuestion,
36418
36990
  getServiceEndpoints,
36419
36991
  grantPermissions,
36420
36992
  grantRegistrationDomain,
@@ -36427,6 +36999,7 @@ async function parsePSError(response) {
36427
36999
  isPlatformSupported,
36428
37000
  isRedactedLineageNode,
36429
37001
  isTombstoneHashes,
37002
+ listQuestions,
36430
37003
  mainnetServices,
36431
37004
  moksha,
36432
37005
  mokshaServices,
@@ -36446,8 +37019,10 @@ async function parsePSError(response) {
36446
37019
  personalServerLineagePath,
36447
37020
  personalServerRegistrationDomain,
36448
37021
  readPersonalServerData,
37022
+ recomputeQuestion,
36449
37023
  recoverServerOwner,
36450
37024
  registerPersonalServerSignature,
37025
+ registerQuestion,
36451
37026
  resolveWriteSigner,
36452
37027
  scopeCoveredByGrant,
36453
37028
  scopeMatchesPattern,
@@ -36467,6 +37042,7 @@ async function parsePSError(response) {
36467
37042
  verifyGrantRegistration,
36468
37043
  verifyPkceChallenge,
36469
37044
  verifyWeb3Signed,
37045
+ waitForQuestion,
36470
37046
  writeData,
36471
37047
  writePersonalServerData
36472
37048
  });