@opendatalabs/vana-sdk 3.0.0 → 3.0.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.
@@ -1253,12 +1253,14 @@ __export(index_node_exports, {
1253
1253
  getServiceEndpoints: () => getServiceEndpoints,
1254
1254
  grantRegistrationDomain: () => grantRegistrationDomain,
1255
1255
  grantRevocationDomain: () => grantRevocationDomain,
1256
+ isDataPortabilityGatewayConfig: () => isDataPortabilityGatewayConfig,
1256
1257
  isECIESEncrypted: () => isECIESEncrypted,
1257
1258
  isPlatformSupported: () => isPlatformSupported,
1258
1259
  mainnetServices: () => mainnetServices,
1259
1260
  moksha: () => moksha,
1260
1261
  mokshaServices: () => mokshaServices,
1261
1262
  mokshaTestnet: () => mokshaTestnet2,
1263
+ parseGrantRegistrationPayload: () => parseGrantRegistrationPayload,
1262
1264
  parsePSError: () => parsePSError,
1263
1265
  parseScope: () => parseScope,
1264
1266
  parseWeb3SignedHeader: () => parseWeb3SignedHeader,
@@ -1269,6 +1271,7 @@ __export(index_node_exports, {
1269
1271
  serializeECIES: () => serializeECIES,
1270
1272
  serverRegistrationDomain: () => serverRegistrationDomain,
1271
1273
  vanaMainnet: () => vanaMainnet2,
1274
+ verifyGrantRegistration: () => verifyGrantRegistration,
1272
1275
  verifyPkceChallenge: () => verifyPkceChallenge,
1273
1276
  verifyWeb3Signed: () => verifyWeb3Signed
1274
1277
  });
@@ -32193,6 +32196,30 @@ function base64urlDecode(input) {
32193
32196
  base64 += "=".repeat(padLength);
32194
32197
  return new TextDecoder().decode(fromBase64(base64));
32195
32198
  }
32199
+ function isFiniteNumber(value) {
32200
+ return typeof value === "number" && Number.isFinite(value);
32201
+ }
32202
+ function parsePayload(value) {
32203
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
32204
+ throw new InvalidSignatureError({ reason: "Invalid payload shape" });
32205
+ }
32206
+ const payload = value;
32207
+ if (typeof payload["aud"] !== "string" || typeof payload["method"] !== "string" || typeof payload["uri"] !== "string" || typeof payload["bodyHash"] !== "string" || !isFiniteNumber(payload["iat"]) || !isFiniteNumber(payload["exp"])) {
32208
+ throw new InvalidSignatureError({ reason: "Invalid payload claims" });
32209
+ }
32210
+ if (payload["grantId"] !== void 0 && typeof payload["grantId"] !== "string") {
32211
+ throw new InvalidSignatureError({ reason: "Invalid grantId claim" });
32212
+ }
32213
+ return {
32214
+ aud: payload["aud"],
32215
+ method: payload["method"],
32216
+ uri: payload["uri"],
32217
+ bodyHash: payload["bodyHash"],
32218
+ iat: payload["iat"],
32219
+ exp: payload["exp"],
32220
+ grantId: payload["grantId"]
32221
+ };
32222
+ }
32196
32223
  function parseWeb3SignedHeader(headerValue) {
32197
32224
  if (!headerValue) {
32198
32225
  throw new MissingAuthError();
@@ -32213,8 +32240,9 @@ function parseWeb3SignedHeader(headerValue) {
32213
32240
  let payload;
32214
32241
  try {
32215
32242
  const decoded = base64urlDecode(payloadBase64);
32216
- payload = JSON.parse(decoded);
32217
- } catch {
32243
+ payload = parsePayload(JSON.parse(decoded));
32244
+ } catch (err) {
32245
+ if (err instanceof InvalidSignatureError) throw err;
32218
32246
  throw new InvalidSignatureError({ reason: "Invalid payload encoding" });
32219
32247
  }
32220
32248
  return {
@@ -32257,7 +32285,7 @@ async function verifyWeb3Signed(params) {
32257
32285
  actual: payload.uri
32258
32286
  });
32259
32287
  }
32260
- if (params.bodyBytes !== void 0 && params.bodyBytes.length > 0) {
32288
+ if (params.bodyBytes !== void 0) {
32261
32289
  const expectedBodyHash = computeBodyHash(params.bodyBytes);
32262
32290
  if (payload.bodyHash !== expectedBodyHash) {
32263
32291
  throw new InvalidSignatureError({
@@ -32453,6 +32481,121 @@ var BUILDER_REGISTRATION_TYPES = {
32453
32481
  ]
32454
32482
  };
32455
32483
 
32484
+ // src/protocol/grants.ts
32485
+ var import_viem14 = require("viem");
32486
+ function isHexString(value) {
32487
+ return typeof value === "string" && value.startsWith("0x");
32488
+ }
32489
+ function isDataPortabilityGatewayConfig(value) {
32490
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
32491
+ return false;
32492
+ }
32493
+ const config = value;
32494
+ const contracts = config["contracts"];
32495
+ if (typeof config["chainId"] !== "number" || !Number.isInteger(config["chainId"]) || config["chainId"] <= 0 || contracts === null || typeof contracts !== "object" || Array.isArray(contracts)) {
32496
+ return false;
32497
+ }
32498
+ const c = contracts;
32499
+ return isHexString(c["dataRegistry"]) && isHexString(c["dataPortabilityPermissions"]) && isHexString(c["dataPortabilityServer"]) && isHexString(c["dataPortabilityGrantees"]);
32500
+ }
32501
+ function parseGrantRegistrationPayload(grant) {
32502
+ let parsed;
32503
+ try {
32504
+ parsed = JSON.parse(grant);
32505
+ } catch {
32506
+ return null;
32507
+ }
32508
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
32509
+ return null;
32510
+ }
32511
+ const value = parsed;
32512
+ if (!Array.isArray(value["scopes"]) || value["scopes"].length === 0) {
32513
+ return null;
32514
+ }
32515
+ if (!value["scopes"].every((scope) => typeof scope === "string")) {
32516
+ return null;
32517
+ }
32518
+ if (typeof value["expiresAt"] !== "number" || !Number.isFinite(value["expiresAt"])) {
32519
+ return null;
32520
+ }
32521
+ if (value["user"] !== void 0 && !isHexString(value["user"])) {
32522
+ return null;
32523
+ }
32524
+ if (value["builder"] !== void 0 && !isHexString(value["builder"])) {
32525
+ return null;
32526
+ }
32527
+ if (value["nonce"] !== void 0 && (typeof value["nonce"] !== "number" || !Number.isFinite(value["nonce"]))) {
32528
+ return null;
32529
+ }
32530
+ return {
32531
+ user: value["user"],
32532
+ builder: value["builder"],
32533
+ scopes: value["scopes"],
32534
+ expiresAt: value["expiresAt"],
32535
+ nonce: value["nonce"]
32536
+ };
32537
+ }
32538
+ function parseFileIds(fileIds) {
32539
+ try {
32540
+ const values = (fileIds ?? []).map((fileId) => BigInt(fileId));
32541
+ return {
32542
+ values,
32543
+ display: values.map((fileId) => fileId.toString())
32544
+ };
32545
+ } catch {
32546
+ return null;
32547
+ }
32548
+ }
32549
+ async function verifyGrantRegistration(input) {
32550
+ const payload = parseGrantRegistrationPayload(input.grant);
32551
+ if (!payload) {
32552
+ return {
32553
+ valid: false,
32554
+ error: "Grant must be JSON with scopes and expiresAt"
32555
+ };
32556
+ }
32557
+ const fileIds = parseFileIds(input.fileIds);
32558
+ if (!fileIds) {
32559
+ return { valid: false, error: "fileIds must contain integer values" };
32560
+ }
32561
+ let valid;
32562
+ try {
32563
+ valid = await (0, import_viem14.verifyTypedData)({
32564
+ address: input.grantorAddress,
32565
+ domain: grantRegistrationDomain(input.gatewayConfig),
32566
+ types: GRANT_REGISTRATION_TYPES,
32567
+ primaryType: "GrantRegistration",
32568
+ message: {
32569
+ grantorAddress: input.grantorAddress,
32570
+ granteeId: input.granteeId,
32571
+ grant: input.grant,
32572
+ fileIds: fileIds.values
32573
+ },
32574
+ signature: input.signature
32575
+ });
32576
+ } catch {
32577
+ return { valid: false, error: "EIP-712 signature verification failed" };
32578
+ }
32579
+ if (!valid) {
32580
+ return { valid: false, error: "Grant signature does not match grantor" };
32581
+ }
32582
+ const nowSeconds = input.nowSeconds ?? Math.floor(Date.now() / 1e3);
32583
+ if (payload.expiresAt > 0 && payload.expiresAt < nowSeconds) {
32584
+ return { valid: false, error: "Grant has expired" };
32585
+ }
32586
+ if (payload.user !== void 0 && payload.user.toLowerCase() !== input.grantorAddress.toLowerCase()) {
32587
+ return { valid: false, error: "Grant user does not match grantorAddress" };
32588
+ }
32589
+ return {
32590
+ valid: true,
32591
+ grantorAddress: input.grantorAddress,
32592
+ granteeId: input.granteeId,
32593
+ grant: input.grant,
32594
+ payload,
32595
+ fileIds: fileIds.display
32596
+ };
32597
+ }
32598
+
32456
32599
  // src/protocol/scopes.ts
32457
32600
  var import_zod = require("zod");
32458
32601
  var SEGMENT_RE = /^[a-z0-9][a-z0-9_]*$/;
@@ -32733,32 +32876,57 @@ var PSError = class extends Error {
32733
32876
  code;
32734
32877
  };
32735
32878
  var KNOWN_CODES = /* @__PURE__ */ new Set([
32879
+ "missing_auth",
32880
+ "invalid_signature",
32881
+ "unregistered_builder",
32882
+ "not_owner",
32883
+ "expired_token",
32736
32884
  "grant_invalid",
32885
+ "grant_required",
32886
+ "grant_expired",
32737
32887
  "grant_revoked",
32888
+ "scope_mismatch",
32738
32889
  "fee_required",
32739
- "ps_unavailable"
32890
+ "ps_unavailable",
32891
+ "server_not_configured",
32892
+ "content_too_large"
32740
32893
  ]);
32741
- async function parsePSError(response) {
32742
- if (response.ok) {
32894
+ function isRecord(value) {
32895
+ return value !== null && typeof value === "object" && !Array.isArray(value);
32896
+ }
32897
+ function normalizeCode(value) {
32898
+ if (typeof value !== "string") {
32743
32899
  return null;
32744
32900
  }
32745
- let body;
32746
- try {
32747
- body = await response.json();
32748
- } catch {
32901
+ const code = value.toLowerCase();
32902
+ return KNOWN_CODES.has(code) ? code : null;
32903
+ }
32904
+ function extractPSErrorBody(body) {
32905
+ if (!isRecord(body)) {
32749
32906
  return null;
32750
32907
  }
32751
- if (typeof body !== "object" || body === null) {
32908
+ const nested = isRecord(body.error) ? body.error : null;
32909
+ const code = normalizeCode(
32910
+ nested?.errorCode ?? nested?.code ?? body.errorCode ?? body.code
32911
+ );
32912
+ const message = nested?.message ?? body.message;
32913
+ if (!code || typeof message !== "string") {
32752
32914
  return null;
32753
32915
  }
32754
- const { code, message } = body;
32755
- if (typeof code !== "string" || typeof message !== "string") {
32916
+ return { code, message };
32917
+ }
32918
+ async function parsePSError(response) {
32919
+ if (response.ok) {
32756
32920
  return null;
32757
32921
  }
32758
- if (!KNOWN_CODES.has(code)) {
32922
+ let body;
32923
+ try {
32924
+ body = await response.json();
32925
+ } catch {
32759
32926
  return null;
32760
32927
  }
32761
- return new PSError(code, message);
32928
+ const errorBody = extractPSErrorBody(body);
32929
+ return errorBody ? new PSError(errorBody.code, errorBody.message) : null;
32762
32930
  }
32763
32931
  // Annotate the CommonJS export names for ESM import in node:
32764
32932
  0 && (module.exports = {
@@ -32842,12 +33010,14 @@ async function parsePSError(response) {
32842
33010
  getServiceEndpoints,
32843
33011
  grantRegistrationDomain,
32844
33012
  grantRevocationDomain,
33013
+ isDataPortabilityGatewayConfig,
32845
33014
  isECIESEncrypted,
32846
33015
  isPlatformSupported,
32847
33016
  mainnetServices,
32848
33017
  moksha,
32849
33018
  mokshaServices,
32850
33019
  mokshaTestnet,
33020
+ parseGrantRegistrationPayload,
32851
33021
  parsePSError,
32852
33022
  parseScope,
32853
33023
  parseWeb3SignedHeader,
@@ -32858,6 +33028,7 @@ async function parsePSError(response) {
32858
33028
  serializeECIES,
32859
33029
  serverRegistrationDomain,
32860
33030
  vanaMainnet,
33031
+ verifyGrantRegistration,
32861
33032
  verifyPkceChallenge,
32862
33033
  verifyWeb3Signed
32863
33034
  });