@opendatalabs/vana-sdk 3.19.0 → 3.20.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.
Files changed (39) hide show
  1. package/README.md +82 -15
  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/direct/controller.cjs +3 -2
  8. package/dist/direct/controller.cjs.map +1 -1
  9. package/dist/direct/controller.d.ts +19 -2
  10. package/dist/direct/controller.js +3 -2
  11. package/dist/direct/controller.js.map +1 -1
  12. package/dist/errors.cjs +13 -0
  13. package/dist/errors.cjs.map +1 -1
  14. package/dist/errors.d.ts +21 -2
  15. package/dist/errors.js +12 -0
  16. package/dist/errors.js.map +1 -1
  17. package/dist/index.browser.js +69 -25
  18. package/dist/index.browser.js.map +2 -2
  19. package/dist/index.node.cjs +70 -25
  20. package/dist/index.node.cjs.map +2 -2
  21. package/dist/index.node.js +69 -25
  22. package/dist/index.node.js.map +2 -2
  23. package/dist/protocol/derivative-questions.cjs +42 -25
  24. package/dist/protocol/derivative-questions.cjs.map +1 -1
  25. package/dist/protocol/derivative-questions.d.ts +51 -10
  26. package/dist/protocol/derivative-questions.js +47 -26
  27. package/dist/protocol/derivative-questions.js.map +1 -1
  28. package/dist/protocol/write-request.cjs +14 -0
  29. package/dist/protocol/write-request.cjs.map +1 -1
  30. package/dist/protocol/write-request.d.ts +12 -0
  31. package/dist/protocol/write-request.js +13 -0
  32. package/dist/protocol/write-request.js.map +1 -1
  33. package/dist/server.cjs +28 -2
  34. package/dist/server.cjs.map +1 -1
  35. package/dist/server.d.ts +2 -0
  36. package/dist/server.js +29 -1
  37. package/dist/server.js.map +1 -1
  38. package/dist/tests/mock-personal-server.d.ts +9 -6
  39. package/package.json +1 -1
@@ -1364,6 +1364,17 @@ var DerivativeQuestionNotFoundError = class extends PersonalServerWriteError {
1364
1364
  super(message, "DERIVATIVE_QUESTION_NOT_FOUND", 404, errorCode, details);
1365
1365
  }
1366
1366
  };
1367
+ var DerivativeDerivedScopeRequiredError = class extends PersonalServerWriteError {
1368
+ constructor(message, errorCode = null, details) {
1369
+ super(
1370
+ message,
1371
+ "DERIVATIVE_DERIVED_SCOPE_REQUIRED",
1372
+ 400,
1373
+ errorCode,
1374
+ details
1375
+ );
1376
+ }
1377
+ };
1367
1378
  var DerivativeSourceNotGrantedError = class extends PersonalServerWriteError {
1368
1379
  constructor(message, errorCode = null, details) {
1369
1380
  super(message, "DERIVATIVE_SOURCE_NOT_GRANTED", 403, errorCode, details);
@@ -29146,6 +29157,9 @@ async function buildWeb3SignedHeader(params) {
29146
29157
  if (params.grantId !== void 0) {
29147
29158
  payload["grantId"] = params.grantId;
29148
29159
  }
29160
+ if (params.nonce !== void 0) {
29161
+ payload["nonce"] = params.nonce;
29162
+ }
29149
29163
  const sortedPayload = Object.keys(payload).sort().reduce((acc, key) => {
29150
29164
  acc[key] = payload[key];
29151
29165
  return acc;
@@ -33871,6 +33885,18 @@ function nextProofIat(proofKey) {
33871
33885
  if (waitSec <= 0) return Promise.resolve(iat);
33872
33886
  return sleep2(waitSec * 1e3).then(() => iat);
33873
33887
  }
33888
+ function freshProofNonce() {
33889
+ const webCrypto = globalThis.crypto;
33890
+ if (typeof webCrypto?.randomUUID === "function") {
33891
+ return webCrypto.randomUUID();
33892
+ }
33893
+ if (typeof webCrypto?.getRandomValues === "function") {
33894
+ return bytesToHex2(webCrypto.getRandomValues(new Uint8Array(16)));
33895
+ }
33896
+ throw new WriteRequestError(
33897
+ "No secure random source available to build a proof nonce; provide a crypto global"
33898
+ );
33899
+ }
33874
33900
  function proofKeyFor(parts) {
33875
33901
  return bytesToHex2(
33876
33902
  sha2565(
@@ -34412,12 +34438,7 @@ var DerivativeQuestionSchema = z5.object({
34412
34438
  var QuestionListSchema = z5.object({
34413
34439
  questions: z5.array(DerivativeQuestionSchema)
34414
34440
  });
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
- });
34441
+ var QuestionRecomputeResultSchema = DerivativeQuestionSchema;
34421
34442
  var QuestionDeleteResultSchema = z5.object({
34422
34443
  questionId: z5.string().min(1),
34423
34444
  deleted: z5.literal(true)
@@ -34485,8 +34506,18 @@ async function resolveSession(params, resolved, force) {
34485
34506
  cache.set(resolved.cacheKey, session);
34486
34507
  return session;
34487
34508
  }
34488
- async function questionErrorFromResponse(response) {
34489
- const { errorCode, message, details } = await readPersonalServerErrorBody(response);
34509
+ var PROOF_FAILURE_CODES = /* @__PURE__ */ new Set([
34510
+ "WRITE_ATTRIBUTION_REQUIRED",
34511
+ "WRITE_ATTRIBUTION_INVALID",
34512
+ "WRITE_ATTRIBUTION_SIGNER_MISMATCH",
34513
+ "WRITE_ATTRIBUTION_GRANT_MISMATCH",
34514
+ "WRITE_ATTRIBUTION_REPLAY"
34515
+ ]);
34516
+ function isStaleSession(errorCode) {
34517
+ return errorCode === null || !PROOF_FAILURE_CODES.has(errorCode);
34518
+ }
34519
+ async function questionErrorFromResponse(response, body) {
34520
+ const { errorCode, message, details } = body ?? await readPersonalServerErrorBody(response);
34490
34521
  const text = message ?? `Derivative question request failed: ${response.status} ${response.statusText}`;
34491
34522
  switch (errorCode) {
34492
34523
  case "DERIVATIVE_SOURCE_NOT_GRANTED":
@@ -34505,6 +34536,8 @@ async function questionErrorFromResponse(response) {
34505
34536
  );
34506
34537
  case "DERIVATIVE_QUESTION_NOT_FOUND":
34507
34538
  return new DerivativeQuestionNotFoundError(text, errorCode, details);
34539
+ case "DERIVATIVE_DERIVED_SCOPE_REQUIRED":
34540
+ return new DerivativeDerivedScopeRequiredError(text, errorCode, details);
34508
34541
  default:
34509
34542
  break;
34510
34543
  }
@@ -34534,7 +34567,7 @@ async function sendOnce(params, resolved, session, spec, bodyBytes) {
34534
34567
  proofKeyFor({
34535
34568
  aud: session.audience,
34536
34569
  method: spec.method,
34537
- uri: spec.path,
34570
+ uri: spec.target,
34538
34571
  grantId: session.grantId,
34539
34572
  signedBytes: bodyBytes
34540
34573
  }),
@@ -34550,17 +34583,22 @@ async function sendOnce(params, resolved, session, spec, bodyBytes) {
34550
34583
  await buildWeb3SignedHeader({
34551
34584
  signMessage: session.signer.signMessage,
34552
34585
  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,
34586
+ // The proof commits to the whole request target, query included:
34587
+ // `?derivedScope=` is what the list route authorizes against, and a
34588
+ // proof that did not cover it would authorize any other scope.
34589
+ uri: spec.target,
34556
34590
  method: spec.method,
34557
34591
  body: bodyBytes,
34558
34592
  grantId: session.grantId,
34593
+ // Fresh per attempt, so a retry after a thrown `fetch` is never the
34594
+ // proof the server may already have consumed, and so two identical
34595
+ // polls inside one second stay distinct.
34596
+ nonce: freshProofNonce(),
34559
34597
  iat
34560
34598
  })
34561
34599
  );
34562
34600
  return {
34563
- url: `${resolved.baseUrl}${spec.path}${spec.query ?? ""}`,
34601
+ url: `${resolved.baseUrl}${spec.target}`,
34564
34602
  init: {
34565
34603
  method: spec.method,
34566
34604
  headers,
@@ -34576,12 +34614,17 @@ async function sendQuestionRequest(params, spec, schema) {
34576
34614
  const bodyBytes = spec.body === void 0 ? void 0 : new TextEncoder().encode(JSON.stringify(spec.body));
34577
34615
  let session = await resolveSession(params, resolved, false);
34578
34616
  let response = await sendOnce(params, resolved, session, spec, bodyBytes);
34617
+ let errorBody;
34579
34618
  if (response.status === 401) {
34580
- session = await resolveSession(params, resolved, true);
34581
- response = await sendOnce(params, resolved, session, spec, bodyBytes);
34619
+ errorBody = await readPersonalServerErrorBody(response);
34620
+ if (isStaleSession(errorBody.errorCode)) {
34621
+ session = await resolveSession(params, resolved, true);
34622
+ response = await sendOnce(params, resolved, session, spec, bodyBytes);
34623
+ errorBody = void 0;
34624
+ }
34582
34625
  }
34583
34626
  if (!response.ok) {
34584
- throw await questionErrorFromResponse(response);
34627
+ throw await questionErrorFromResponse(response, errorBody);
34585
34628
  }
34586
34629
  let body;
34587
34630
  try {
@@ -34675,7 +34718,7 @@ async function registerQuestion(params) {
34675
34718
  params,
34676
34719
  {
34677
34720
  method: "POST",
34678
- path: DERIVATIVE_QUESTIONS_PATH,
34721
+ target: DERIVATIVE_QUESTIONS_PATH,
34679
34722
  body,
34680
34723
  label: "Register derivative question"
34681
34724
  },
@@ -34683,10 +34726,10 @@ async function registerQuestion(params) {
34683
34726
  );
34684
34727
  }
34685
34728
  async function getQuestion(params) {
34686
- const path = assertQuestionId(params.questionId);
34729
+ const target = assertQuestionId(params.questionId);
34687
34730
  return sendQuestionRequest(
34688
34731
  params,
34689
- { method: "GET", path, label: "Read derivative question" },
34732
+ { method: "GET", target, label: "Read derivative question" },
34690
34733
  DerivativeQuestionSchema
34691
34734
  );
34692
34735
  }
@@ -34696,12 +34739,12 @@ async function listQuestions(params) {
34696
34739
  "derivedScope is required; a builder may only list its own questions on a scope it may write"
34697
34740
  );
34698
34741
  }
34742
+ const target = `${DERIVATIVE_QUESTIONS_PATH}?derivedScope=${encodeURIComponent(params.derivedScope)}`;
34699
34743
  const { questions } = await sendQuestionRequest(
34700
34744
  params,
34701
34745
  {
34702
34746
  method: "GET",
34703
- path: DERIVATIVE_QUESTIONS_PATH,
34704
- query: `?derivedScope=${encodeURIComponent(params.derivedScope)}`,
34747
+ target,
34705
34748
  label: "List derivative questions"
34706
34749
  },
34707
34750
  QuestionListSchema
@@ -34709,18 +34752,18 @@ async function listQuestions(params) {
34709
34752
  return questions;
34710
34753
  }
34711
34754
  async function recomputeQuestion(params) {
34712
- const path = `${assertQuestionId(params.questionId)}/recompute`;
34755
+ const target = `${assertQuestionId(params.questionId)}/recompute`;
34713
34756
  return sendQuestionRequest(
34714
34757
  params,
34715
- { method: "POST", path, label: "Recompute derivative question" },
34758
+ { method: "POST", target, label: "Recompute derivative question" },
34716
34759
  QuestionRecomputeResultSchema
34717
34760
  );
34718
34761
  }
34719
34762
  async function deleteQuestion(params) {
34720
- const path = assertQuestionId(params.questionId);
34763
+ const target = assertQuestionId(params.questionId);
34721
34764
  return sendQuestionRequest(
34722
34765
  params,
34723
- { method: "DELETE", path, label: "Delete derivative question" },
34766
+ { method: "DELETE", target, label: "Delete derivative question" },
34724
34767
  QuestionDeleteResultSchema
34725
34768
  );
34726
34769
  }
@@ -35417,6 +35460,7 @@ export {
35417
35460
  DataPointVersionConflictError,
35418
35461
  DerivativeComputeUnavailableError,
35419
35462
  DerivativeCycleError,
35463
+ DerivativeDerivedScopeRequiredError,
35420
35464
  DerivativeQuestionFailedError,
35421
35465
  DerivativeQuestionInvalidError,
35422
35466
  DerivativeQuestionNotFoundError,