@opendatalabs/vana-sdk 3.16.0 → 3.18.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 (72) hide show
  1. package/README.md +107 -0
  2. package/dist/direct/personal-server-read.cjs +20 -1
  3. package/dist/direct/personal-server-read.cjs.map +1 -1
  4. package/dist/direct/personal-server-read.js +23 -1
  5. package/dist/direct/personal-server-read.js.map +1 -1
  6. package/dist/errors.cjs +121 -2
  7. package/dist/errors.cjs.map +1 -1
  8. package/dist/errors.d.ts +190 -0
  9. package/dist/errors.js +106 -1
  10. package/dist/errors.js.map +1 -1
  11. package/dist/index.browser.d.ts +5 -1
  12. package/dist/index.browser.js +1449 -58
  13. package/dist/index.browser.js.map +4 -4
  14. package/dist/index.node.cjs +1501 -59
  15. package/dist/index.node.cjs.map +4 -4
  16. package/dist/index.node.d.ts +5 -1
  17. package/dist/index.node.js +1449 -58
  18. package/dist/index.node.js.map +4 -4
  19. package/dist/protocol/data-point-deletion.cjs +220 -0
  20. package/dist/protocol/data-point-deletion.cjs.map +1 -0
  21. package/dist/protocol/data-point-deletion.d.ts +180 -0
  22. package/dist/protocol/data-point-deletion.js +193 -0
  23. package/dist/protocol/data-point-deletion.js.map +1 -0
  24. package/dist/protocol/data-point-deletion.test.d.ts +1 -0
  25. package/dist/protocol/gateway.cjs +145 -32
  26. package/dist/protocol/gateway.cjs.map +1 -1
  27. package/dist/protocol/gateway.d.ts +42 -3
  28. package/dist/protocol/gateway.js +156 -32
  29. package/dist/protocol/gateway.js.map +1 -1
  30. package/dist/protocol/lineage.cjs +287 -0
  31. package/dist/protocol/lineage.cjs.map +1 -0
  32. package/dist/protocol/lineage.d.ts +228 -0
  33. package/dist/protocol/lineage.js +258 -0
  34. package/dist/protocol/lineage.js.map +1 -0
  35. package/dist/protocol/lineage.test.d.ts +1 -0
  36. package/dist/protocol/personal-server-data.cjs +20 -1
  37. package/dist/protocol/personal-server-data.cjs.map +1 -1
  38. package/dist/protocol/personal-server-data.js +23 -1
  39. package/dist/protocol/personal-server-data.js.map +1 -1
  40. package/dist/protocol/personal-server-error-body.cjs +57 -0
  41. package/dist/protocol/personal-server-error-body.cjs.map +1 -0
  42. package/dist/protocol/personal-server-error-body.d.ts +18 -0
  43. package/dist/protocol/personal-server-error-body.js +32 -0
  44. package/dist/protocol/personal-server-error-body.js.map +1 -0
  45. package/dist/protocol/personal-server-write.cjs +623 -0
  46. package/dist/protocol/personal-server-write.cjs.map +1 -0
  47. package/dist/protocol/personal-server-write.d.ts +284 -0
  48. package/dist/protocol/personal-server-write.js +601 -0
  49. package/dist/protocol/personal-server-write.js.map +1 -0
  50. package/dist/protocol/personal-server-write.test.d.ts +1 -0
  51. package/dist/protocol/write-signer.cjs +67 -0
  52. package/dist/protocol/write-signer.cjs.map +1 -0
  53. package/dist/protocol/write-signer.d.ts +59 -0
  54. package/dist/protocol/write-signer.js +43 -0
  55. package/dist/protocol/write-signer.js.map +1 -0
  56. package/dist/protocol/write-signer.test.d.ts +1 -0
  57. package/dist/storage/index.cjs.map +1 -1
  58. package/dist/storage/index.d.ts +1 -1
  59. package/dist/storage/index.js.map +1 -1
  60. package/dist/storage/providers/vana-storage.cjs +66 -0
  61. package/dist/storage/providers/vana-storage.cjs.map +1 -1
  62. package/dist/storage/providers/vana-storage.d.ts +26 -0
  63. package/dist/storage/providers/vana-storage.js +66 -0
  64. package/dist/storage/providers/vana-storage.js.map +1 -1
  65. package/dist/tests/mock-personal-server.d.ts +127 -0
  66. package/dist/utils/response-body.cjs +46 -0
  67. package/dist/utils/response-body.cjs.map +1 -0
  68. package/dist/utils/response-body.d.ts +26 -0
  69. package/dist/utils/response-body.js +20 -0
  70. package/dist/utils/response-body.js.map +1 -0
  71. package/dist/utils/response-body.test.d.ts +1 -0
  72. package/package.json +1 -1
@@ -1288,6 +1288,97 @@ var TransactionPendingError = class extends VanaError {
1288
1288
  };
1289
1289
  }
1290
1290
  };
1291
+ var PersonalServerWriteError = class extends VanaError {
1292
+ constructor(message, code, status, errorCode = null, details) {
1293
+ super(message, code);
1294
+ this.status = status;
1295
+ this.errorCode = errorCode;
1296
+ this.details = details;
1297
+ }
1298
+ status;
1299
+ errorCode;
1300
+ details;
1301
+ };
1302
+ var WriteRequestError = class extends PersonalServerWriteError {
1303
+ constructor(message, details) {
1304
+ super(message, "WRITE_INVALID_REQUEST", void 0, null, details);
1305
+ }
1306
+ };
1307
+ var WriteTransportError = class extends PersonalServerWriteError {
1308
+ constructor(message, attempts, cause) {
1309
+ super(message, "WRITE_TRANSPORT_ERROR", void 0, null, { attempts });
1310
+ this.attempts = attempts;
1311
+ this.cause = cause;
1312
+ }
1313
+ attempts;
1314
+ };
1315
+ var WriteSessionError = class extends PersonalServerWriteError {
1316
+ constructor(message, status, errorCode = null, details) {
1317
+ super(message, "WRITE_SESSION_REJECTED", status, errorCode, details);
1318
+ }
1319
+ };
1320
+ var WriteSessionExpiredError = class extends PersonalServerWriteError {
1321
+ constructor(message, details) {
1322
+ super(message, "WRITE_SESSION_EXPIRED", void 0, null, details);
1323
+ }
1324
+ };
1325
+ var WriteUnauthorizedError = class extends PersonalServerWriteError {
1326
+ constructor(message, errorCode = null, details) {
1327
+ super(message, "WRITE_UNAUTHORIZED", 401, errorCode, details);
1328
+ }
1329
+ };
1330
+ var WriteForbiddenError = class extends PersonalServerWriteError {
1331
+ constructor(message, errorCode = null, details) {
1332
+ super(message, "WRITE_FORBIDDEN", 403, errorCode, details);
1333
+ }
1334
+ };
1335
+ var WriteConflictError = class extends PersonalServerWriteError {
1336
+ constructor(message, errorCode = null, details) {
1337
+ super(message, "WRITE_CONFLICT", 409, errorCode, details);
1338
+ }
1339
+ };
1340
+ var WriteLineageError = class extends PersonalServerWriteError {
1341
+ constructor(message, status = 422, errorCode = null, details) {
1342
+ super(message, "WRITE_LINEAGE_REJECTED", status, errorCode, details);
1343
+ }
1344
+ };
1345
+ var WriteRejectedError = class extends PersonalServerWriteError {
1346
+ constructor(message, status, errorCode = null, details) {
1347
+ super(message, "WRITE_REJECTED", status, errorCode, details);
1348
+ }
1349
+ };
1350
+ var LineageReadError = class extends VanaError {
1351
+ constructor(message, status, errorCode = null, details) {
1352
+ super(message, "LINEAGE_READ_ERROR");
1353
+ this.status = status;
1354
+ this.errorCode = errorCode;
1355
+ this.details = details;
1356
+ }
1357
+ status;
1358
+ errorCode;
1359
+ details;
1360
+ };
1361
+ var DataPointDeletedError = class extends VanaError {
1362
+ constructor(message, details = {}) {
1363
+ super(message, "DATA_POINT_DELETED");
1364
+ this.details = details;
1365
+ }
1366
+ details;
1367
+ };
1368
+ var DataPointNotFoundError = class extends VanaError {
1369
+ constructor(message, details = {}) {
1370
+ super(message, "DATA_POINT_NOT_FOUND");
1371
+ this.details = details;
1372
+ }
1373
+ details;
1374
+ };
1375
+ var DataPointVersionConflictError = class extends VanaError {
1376
+ constructor(message, details = {}) {
1377
+ super(message, "DATA_POINT_VERSION_CONFLICT");
1378
+ this.details = details;
1379
+ }
1380
+ details;
1381
+ };
1291
1382
 
1292
1383
  // src/contracts/contractController.ts
1293
1384
  import {
@@ -29050,6 +29141,22 @@ function getProtocolNetworkChainId(network) {
29050
29141
  return PROTOCOL_NETWORK_CHAIN_IDS[network];
29051
29142
  }
29052
29143
 
29144
+ // src/utils/response-body.ts
29145
+ function isPlainObject(value) {
29146
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29147
+ }
29148
+ async function readJsonValue(res) {
29149
+ try {
29150
+ return await res.json();
29151
+ } catch {
29152
+ return null;
29153
+ }
29154
+ }
29155
+ async function readJsonObject(res) {
29156
+ const value = await readJsonValue(res);
29157
+ return isPlainObject(value) ? value : {};
29158
+ }
29159
+
29053
29160
  // src/storage/providers/vana-storage.ts
29054
29161
  var DEFAULT_ENDPOINT = "https://storage.vana.org";
29055
29162
  var LEGACY_BLOB_PATH_PREFIX = "/v1/blobs";
@@ -29221,6 +29328,65 @@ var VanaStorage = class {
29221
29328
  }
29222
29329
  return true;
29223
29330
  }
29331
+ /**
29332
+ * Delete every version's blob under `(owner, scope)` --
29333
+ * `DELETE {prefix}/{owner}/{scope}` on vana-storage, signed with the same
29334
+ * Web3Signed header as uploads (aud = endpoint origin, empty bodyHash).
29335
+ * The worker accepts the owner's own signature or a personal server the
29336
+ * owner registered with the gateway.
29337
+ *
29338
+ * @param ownerAddress - Must equal the provider's configured owner; a
29339
+ * mismatch throws before anything is signed so this wallet can never be
29340
+ * induced to sign a delete for another namespace.
29341
+ * @param scope - The scope segment, e.g. `"instagram.profile"`.
29342
+ */
29343
+ async deleteScope(ownerAddress, scope) {
29344
+ if (ownerAddress.toLowerCase() !== this.ownerAddress) {
29345
+ throw new StorageError(
29346
+ `deleteScope owner '${ownerAddress}' does not match the configured owner '${this.ownerAddress}'`,
29347
+ "INVALID_OWNER",
29348
+ "vana-storage"
29349
+ );
29350
+ }
29351
+ if (scope.length === 0 || scope.includes("/") || isTraversalSegment(scope)) {
29352
+ throw new StorageError(
29353
+ `scope must be a single non-empty path segment, got '${scope}'`,
29354
+ "INVALID_SCOPE",
29355
+ "vana-storage"
29356
+ );
29357
+ }
29358
+ const path = `${this.blobPathPrefix}/${this.ownerAddress}/${encodeURIComponent(scope)}`;
29359
+ const header = await this.signRequest("DELETE", path);
29360
+ let response;
29361
+ try {
29362
+ response = await this.fetchImpl(`${this.endpoint}${path}`, {
29363
+ method: "DELETE",
29364
+ headers: { authorization: header }
29365
+ });
29366
+ } catch (cause) {
29367
+ throw new StorageError(
29368
+ `vana-storage scope delete network error: ${describe(cause)}`,
29369
+ "DELETE_ERROR",
29370
+ "vana-storage",
29371
+ { cause: cause instanceof Error ? cause : void 0 }
29372
+ );
29373
+ }
29374
+ if (!response.ok) {
29375
+ const responseText = await safeText(response);
29376
+ throw new StorageError(
29377
+ `vana-storage scope delete failed: ${response.status} ${response.statusText} - ${responseText}`,
29378
+ "DELETE_FAILED",
29379
+ "vana-storage"
29380
+ );
29381
+ }
29382
+ const body = await readJsonObject(response);
29383
+ return {
29384
+ deleted: typeof body["deleted"] === "boolean" ? body["deleted"] : true,
29385
+ scope: typeof body["scope"] === "string" ? body["scope"] : scope,
29386
+ count: nonNegativeInteger(body["count"]) ?? 0,
29387
+ totalBytes: nonNegativeInteger(body["totalBytes"]) ?? 0
29388
+ };
29389
+ }
29224
29390
  getConfig() {
29225
29391
  return {
29226
29392
  name: "vana-storage",
@@ -29349,6 +29515,12 @@ function encodeRelativePath(filename) {
29349
29515
  }
29350
29516
  return parts.map((p) => encodeURIComponent(p)).join("/");
29351
29517
  }
29518
+ function isTraversalSegment(segment) {
29519
+ return segment === "." || segment === "..";
29520
+ }
29521
+ function nonNegativeInteger(value) {
29522
+ return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
29523
+ }
29352
29524
  function describe(value) {
29353
29525
  if (value instanceof Error) return value.message;
29354
29526
  return String(value);
@@ -32799,13 +32971,13 @@ function createViemPersonalServerRegistrationSigner(source, options = {}) {
32799
32971
  if (isPersonalServerRegistrationSigner(source)) {
32800
32972
  return source;
32801
32973
  }
32802
- const accountAddress = getAccountAddress(options.account) ?? getAccountAddress(source.account);
32803
- if (accountAddress) {
32974
+ const accountAddress2 = getAccountAddress(options.account) ?? getAccountAddress(source.account);
32975
+ if (accountAddress2) {
32804
32976
  return {
32805
- address: accountAddress,
32977
+ address: accountAddress2,
32806
32978
  signTypedData: (typedData) => source.signTypedData({
32807
32979
  ...typedData,
32808
- account: options.account ?? source.account ?? accountAddress
32980
+ account: options.account ?? source.account ?? accountAddress2
32809
32981
  })
32810
32982
  };
32811
32983
  }
@@ -32890,12 +33062,12 @@ function createViemPersonalServerLiteOwnerBindingSigner(source, options = {}) {
32890
33062
  if (isPersonalServerLiteOwnerBindingSigner(source)) {
32891
33063
  return source;
32892
33064
  }
32893
- const accountAddress = getAccountAddress2(options.account) ?? getAccountAddress2(source.account);
32894
- if (accountAddress) {
33065
+ const accountAddress2 = getAccountAddress2(options.account) ?? getAccountAddress2(source.account);
33066
+ if (accountAddress2) {
32895
33067
  return {
32896
- address: accountAddress,
33068
+ address: accountAddress2,
32897
33069
  signMessage: ({ message }) => source.signMessage({
32898
- account: options.account ?? source.account ?? accountAddress,
33070
+ account: options.account ?? source.account ?? accountAddress2,
32899
33071
  message
32900
33072
  })
32901
33073
  };
@@ -33462,15 +33634,494 @@ function buildMarkDataPointUnavailableRequest(config, input) {
33462
33634
  });
33463
33635
  }
33464
33636
 
33465
- // src/protocol/data-file.ts
33637
+ // src/protocol/data-point-deletion.ts
33638
+ import {
33639
+ isAddress as isAddress5,
33640
+ keccak256 as keccak2562,
33641
+ maxUint256,
33642
+ stringToBytes as stringToBytes3
33643
+ } from "viem";
33644
+
33645
+ // src/protocol/lineage.ts
33646
+ import {
33647
+ encodeAbiParameters,
33648
+ isAddress as isAddress4,
33649
+ keccak256
33650
+ } from "viem";
33466
33651
  import { z } from "zod";
33467
- var DataFileEnvelopeSchema = z.object({
33468
- $schema: z.string().url().optional(),
33469
- version: z.literal("1.0"),
33652
+
33653
+ // src/protocol/personal-server-error-body.ts
33654
+ function isRecord2(value) {
33655
+ return value !== null && typeof value === "object" && !Array.isArray(value);
33656
+ }
33657
+ async function readPersonalServerErrorBody(response) {
33658
+ let body;
33659
+ try {
33660
+ body = await response.json();
33661
+ } catch {
33662
+ return { errorCode: null, message: null };
33663
+ }
33664
+ if (!isRecord2(body)) return { errorCode: null, message: null };
33665
+ const nested = isRecord2(body.error) ? body.error : null;
33666
+ const gatewayShape = typeof body.error === "string" && typeof body.code === "string";
33667
+ const code = nested?.errorCode ?? nested?.code ?? body.errorCode ?? (gatewayShape ? body.code : void 0) ?? (typeof body.error === "string" ? body.error : void 0) ?? body.code;
33668
+ const message = nested?.message ?? body.message ?? (gatewayShape ? body.error : void 0);
33669
+ const gatewayDetails = {};
33670
+ for (const key of ["unknown", "scope", "sourceScope"]) {
33671
+ if (gatewayShape && body[key] !== void 0)
33672
+ gatewayDetails[key] = body[key];
33673
+ }
33674
+ const details = nested?.details ?? body.details ?? (Object.keys(gatewayDetails).length > 0 ? gatewayDetails : void 0);
33675
+ return {
33676
+ errorCode: typeof code === "string" ? code : null,
33677
+ message: typeof message === "string" ? message : null,
33678
+ ...isRecord2(details) ? { details } : {}
33679
+ };
33680
+ }
33681
+
33682
+ // src/protocol/write-signer.ts
33683
+ function isRecord3(value) {
33684
+ return value !== null && typeof value === "object";
33685
+ }
33686
+ function isViemWriteAccount(source) {
33687
+ return isRecord3(source) && source.type === "local" && typeof source.address === "string" && typeof source.signMessage === "function";
33688
+ }
33689
+ function isViemWriteWalletClient(source) {
33690
+ return isRecord3(source) && typeof source.signMessage === "function" && source.type !== "local" && (source.type === "walletClient" || "transport" in source);
33691
+ }
33692
+ function accountAddress(account) {
33693
+ return typeof account === "string" ? account : account.address;
33694
+ }
33695
+ function resolveWriteSigner(source, options = {}) {
33696
+ if (isViemWriteWalletClient(source)) {
33697
+ const account = options.account ?? source.account;
33698
+ if (account === void 0) {
33699
+ throw new WriteRequestError(
33700
+ "Viem wallet client requires an account option or account property"
33701
+ );
33702
+ }
33703
+ return {
33704
+ address: accountAddress(account),
33705
+ signMessage: (message) => source.signMessage({ account, message })
33706
+ };
33707
+ }
33708
+ if (isViemWriteAccount(source)) {
33709
+ return {
33710
+ address: source.address,
33711
+ signMessage: (message) => source.signMessage({ message })
33712
+ };
33713
+ }
33714
+ if (!isRecord3(source) || typeof source.signMessage !== "function") {
33715
+ throw new WriteRequestError(
33716
+ "signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
33717
+ );
33718
+ }
33719
+ return source;
33720
+ }
33721
+
33722
+ // src/protocol/lineage.ts
33723
+ var DATA_POINT_ID_PATTERN = /^0x[0-9a-fA-F]{64}$/;
33724
+ function isDataPointId(value) {
33725
+ return typeof value === "string" && DATA_POINT_ID_PATTERN.test(value);
33726
+ }
33727
+ function deriveDataPointId(ownerAddress, scope) {
33728
+ if (!isAddress4(ownerAddress, { strict: false })) {
33729
+ throw new Error(
33730
+ `ownerAddress is not an EVM address: ${String(ownerAddress)}`
33731
+ );
33732
+ }
33733
+ return keccak256(
33734
+ encodeAbiParameters(
33735
+ [
33736
+ { name: "ownerAddress", type: "address" },
33737
+ { name: "scope", type: "string" }
33738
+ ],
33739
+ [ownerAddress, scope]
33740
+ )
33741
+ );
33742
+ }
33743
+ var DataPointIdSchema = z.string().regex(DATA_POINT_ID_PATTERN).transform((value) => value.toLowerCase());
33744
+ var VERSION_PATTERN = /^[1-9]\d*$/;
33745
+ var NODE_VERSION_PATTERN = /^(0|[1-9]\d*)$/;
33746
+ var VersionSchema = z.union([z.string(), z.number()]).transform(String).refine((value) => NODE_VERSION_PATTERN.test(value), {
33747
+ message: "version must be a decimal integer"
33748
+ });
33749
+ var ViewVersionSchema = VersionSchema.refine(
33750
+ (value) => VERSION_PATTERN.test(value),
33751
+ { message: "version must be a positive decimal integer" }
33752
+ );
33753
+ function scopeNamespace(scope) {
33754
+ const dot = scope.indexOf(".");
33755
+ return dot === -1 ? scope : scope.slice(0, dot);
33756
+ }
33757
+ function derivedScopeViolatesNaming(derivedScope, sourceScope) {
33758
+ return scopeNamespace(derivedScope) === scopeNamespace(sourceScope);
33759
+ }
33760
+ function assertDerivedScopeNaming(derivedScope, sourceScopes) {
33761
+ for (const sourceScope of sourceScopes) {
33762
+ if (derivedScopeViolatesNaming(derivedScope, sourceScope)) {
33763
+ throw new WriteRequestError(
33764
+ `Derived scope ${derivedScope} must not share its first segment with source scope ${sourceScope}; put derivatives in the app's own namespace`,
33765
+ { scope: derivedScope, sourceScope }
33766
+ );
33767
+ }
33768
+ }
33769
+ }
33770
+ var LineageNodeSchema = z.object({
33771
+ dataPointId: DataPointIdSchema,
33470
33772
  scope: z.string(),
33471
- schemaId: z.string().optional(),
33472
- collectedAt: z.string().datetime(),
33473
- data: z.record(z.string(), z.unknown())
33773
+ /**
33774
+ * The node's current version, decimal string; `"0"` for a source that no
33775
+ * longer resolves to a registered data point.
33776
+ */
33777
+ version: VersionSchema,
33778
+ /** The node's tombstone time, or `null` when live. */
33779
+ deletedAt: z.string().nullable()
33780
+ });
33781
+ var RedactedLineageNodeSchema = z.object({
33782
+ dataPointId: DataPointIdSchema,
33783
+ redacted: z.literal(true)
33784
+ });
33785
+ var LineageEntrySchema = z.union([
33786
+ RedactedLineageNodeSchema,
33787
+ LineageNodeSchema
33788
+ ]);
33789
+ var LineageGraphSchema = z.object({
33790
+ dataPointId: DataPointIdSchema,
33791
+ /** The data point owner; every node in the view belongs to it. */
33792
+ ownerAddress: z.string().optional(),
33793
+ scope: z.string(),
33794
+ /**
33795
+ * The derived record's version whose lineage is shown: the requested one,
33796
+ * else the current one, else (current is a tombstone) the last version
33797
+ * that carried lineage.
33798
+ */
33799
+ version: ViewVersionSchema,
33800
+ deletedAt: z.string().nullable(),
33801
+ sources: z.array(LineageEntrySchema),
33802
+ derivatives: z.array(LineageEntrySchema),
33803
+ /** `true` when `derivatives` was cut at the server's cap (1000). */
33804
+ derivativesTruncated: z.boolean().optional()
33805
+ });
33806
+ function isRedactedLineageNode(entry) {
33807
+ return "redacted" in entry && entry.redacted === true;
33808
+ }
33809
+ function personalServerLineagePath(scope, version) {
33810
+ return `/v1/data/${encodeURIComponent(scope)}/lineage${version === void 0 ? "" : `/${String(version)}`}`;
33811
+ }
33812
+ function gatewayLineagePath(dataPointId, version) {
33813
+ return `/v1/data/${dataPointId.toLowerCase()}/lineage${version === void 0 ? "" : `/${String(version)}`}`;
33814
+ }
33815
+ function normalizeBaseUrl(url) {
33816
+ return url.replace(/\/+$/, "");
33817
+ }
33818
+ function resolveFetch(fetchFn) {
33819
+ const resolved = fetchFn ?? globalThis.fetch;
33820
+ if (resolved === void 0) {
33821
+ throw new LineageReadError("No fetch implementation available");
33822
+ }
33823
+ return resolved;
33824
+ }
33825
+ function normalizeVersion(version) {
33826
+ if (version === void 0) return void 0;
33827
+ const text = String(version);
33828
+ if (!VERSION_PATTERN.test(text)) {
33829
+ throw new LineageReadError(
33830
+ "version must be a positive decimal integer",
33831
+ void 0,
33832
+ "INVALID_VERSION",
33833
+ { version }
33834
+ );
33835
+ }
33836
+ return text;
33837
+ }
33838
+ async function lineageReadFailure(source, response) {
33839
+ const { errorCode, message, details } = await readPersonalServerErrorBody(response);
33840
+ return new LineageReadError(
33841
+ message ?? `${source} lineage read failed: ${response.status} ${response.statusText}`,
33842
+ response.status,
33843
+ errorCode,
33844
+ details
33845
+ );
33846
+ }
33847
+ async function parseLineageGraph(source, response) {
33848
+ let body;
33849
+ try {
33850
+ body = await response.json();
33851
+ } catch (err) {
33852
+ throw new LineageReadError(
33853
+ `${source} lineage response is not JSON`,
33854
+ response.status,
33855
+ null,
33856
+ { cause: err instanceof Error ? err.message : String(err) }
33857
+ );
33858
+ }
33859
+ const envelope = isRecord2(body) && isRecord2(body.data) ? body : void 0;
33860
+ const parsed = LineageGraphSchema.safeParse(envelope?.data ?? body);
33861
+ if (!parsed.success) {
33862
+ throw new LineageReadError(
33863
+ `${source} lineage response is not a lineage view`,
33864
+ response.status,
33865
+ null,
33866
+ { issues: parsed.error.issues }
33867
+ );
33868
+ }
33869
+ const proof = isRecord2(envelope?.proof) ? envelope.proof : void 0;
33870
+ return proof === void 0 ? parsed.data : { ...parsed.data, proof };
33871
+ }
33872
+ async function sendLineageRead(source, fetchFn, url, headers) {
33873
+ let response;
33874
+ try {
33875
+ response = await fetchFn(url, { method: "GET", headers });
33876
+ } catch (err) {
33877
+ throw new LineageReadError(
33878
+ `${source} lineage read failed: ${err instanceof Error ? err.message : String(err)}`,
33879
+ void 0,
33880
+ null,
33881
+ { cause: err instanceof Error ? err.message : String(err) }
33882
+ );
33883
+ }
33884
+ if (!response.ok) {
33885
+ throw await lineageReadFailure(source, response);
33886
+ }
33887
+ return parseLineageGraph(source, response);
33888
+ }
33889
+ async function getPersonalServerLineage(params) {
33890
+ const fetchFn = resolveFetch(params.fetch);
33891
+ const baseUrl = normalizeBaseUrl(params.personalServerUrl);
33892
+ const audience = params.audience ?? baseUrl;
33893
+ const signer = resolveWriteSigner(params.signer, { account: params.account });
33894
+ const path = personalServerLineagePath(
33895
+ params.scope,
33896
+ normalizeVersion(params.version)
33897
+ );
33898
+ const headers = new Headers(params.headers);
33899
+ headers.set(
33900
+ "Authorization",
33901
+ await buildWeb3SignedHeader({
33902
+ signMessage: signer.signMessage,
33903
+ aud: audience,
33904
+ method: "GET",
33905
+ uri: path,
33906
+ grantId: params.grantId
33907
+ })
33908
+ );
33909
+ return sendLineageRead(
33910
+ "Personal Server",
33911
+ fetchFn,
33912
+ `${baseUrl}${path}`,
33913
+ headers
33914
+ );
33915
+ }
33916
+ async function getGatewayLineage(params) {
33917
+ if (!isDataPointId(params.dataPointId)) {
33918
+ throw new LineageReadError(
33919
+ "dataPointId must be a 32-byte hex string (see deriveDataPointId)",
33920
+ void 0,
33921
+ "INVALID_DATA_POINT_ID",
33922
+ { dataPointId: params.dataPointId }
33923
+ );
33924
+ }
33925
+ const fetchFn = resolveFetch(params.fetch);
33926
+ const baseUrl = normalizeBaseUrl(params.gatewayUrl);
33927
+ const signer = resolveWriteSigner(params.signer, { account: params.account });
33928
+ const uri = gatewayLineagePath(
33929
+ params.dataPointId,
33930
+ normalizeVersion(params.version)
33931
+ );
33932
+ const headers = new Headers(params.headers);
33933
+ headers.set(
33934
+ "Authorization",
33935
+ await buildWeb3SignedHeader({
33936
+ signMessage: signer.signMessage,
33937
+ aud: baseUrl,
33938
+ method: "GET",
33939
+ uri,
33940
+ grantId: params.grantId?.toLowerCase()
33941
+ })
33942
+ );
33943
+ return sendLineageRead("Gateway", fetchFn, `${baseUrl}${uri}`, headers);
33944
+ }
33945
+ function getLineage(params) {
33946
+ return "personalServerUrl" in params ? getPersonalServerLineage(params) : getGatewayLineage(params);
33947
+ }
33948
+
33949
+ // src/protocol/data-point-deletion.ts
33950
+ var TOMBSTONE_DATA_HASH_PREIMAGE = "vana.data-point.tombstone.v1";
33951
+ var TOMBSTONE_METADATA_HASH_PREIMAGE = "vana.data-point.tombstone.metadata.v1";
33952
+ var TOMBSTONE_DATA_HASH = "0x30c45ee72fe56d1927701316925ab7ceacd3b6f9267061735d59396f075c6222";
33953
+ var TOMBSTONE_METADATA_HASH = "0xc5255a141acd6a2ae55971b62c0a85977c2511989dc114ad2abc2b7644f57d90";
33954
+ function computeTombstoneHash(preimage) {
33955
+ return keccak2562(stringToBytes3(preimage));
33956
+ }
33957
+ function isTombstoneHashes(dataHash, metadataHash) {
33958
+ return typeof dataHash === "string" && typeof metadataHash === "string" && dataHash.toLowerCase() === TOMBSTONE_DATA_HASH && metadataHash.toLowerCase() === TOMBSTONE_METADATA_HASH;
33959
+ }
33960
+ function isDataPointTombstone(value) {
33961
+ if (!isPlainObject(value)) return false;
33962
+ if (typeof value["deletedAt"] === "string") return true;
33963
+ return isTombstoneHashes(
33964
+ typeof value["dataHash"] === "string" ? value["dataHash"] : void 0,
33965
+ typeof value["metadataHash"] === "string" ? value["metadataHash"] : void 0
33966
+ );
33967
+ }
33968
+ function tombstoneDeletedAt(value) {
33969
+ if (!isPlainObject(value)) return null;
33970
+ const deletedAt = value["deletedAt"];
33971
+ return typeof deletedAt === "string" ? deletedAt : null;
33972
+ }
33973
+ function assertAddress4(value, name) {
33974
+ if (!isAddress5(value)) {
33975
+ throw new Error(`${name} must be a valid EVM address`);
33976
+ }
33977
+ }
33978
+ function assertUint256(value, name) {
33979
+ if (value < 0n || value > maxUint256) {
33980
+ throw new Error(`${name} must fit in uint256, got ${value}`);
33981
+ }
33982
+ }
33983
+ function getAccountAddress3(account) {
33984
+ if (!account) return void 0;
33985
+ return typeof account === "string" ? account : account.address;
33986
+ }
33987
+ function isDataPointDeletionSigner(source) {
33988
+ return "address" in source && typeof source.signTypedData === "function";
33989
+ }
33990
+ function createViemDataPointDeletionSigner(source, options = {}) {
33991
+ if (isDataPointDeletionSigner(source)) {
33992
+ return source;
33993
+ }
33994
+ const accountAddress2 = getAccountAddress3(options.account) ?? getAccountAddress3(source.account);
33995
+ if (accountAddress2) {
33996
+ return {
33997
+ address: accountAddress2,
33998
+ signTypedData: (typedData) => source.signTypedData({
33999
+ ...typedData,
34000
+ account: options.account ?? source.account ?? accountAddress2
34001
+ })
34002
+ };
34003
+ }
34004
+ throw new Error(
34005
+ "Viem wallet client requires an account option or account property"
34006
+ );
34007
+ }
34008
+ function buildDataPointDeletionTypedData(input) {
34009
+ assertAddress4(input.ownerAddress, "ownerAddress");
34010
+ if (input.scope.length === 0) {
34011
+ throw new Error("scope must be a non-empty string");
34012
+ }
34013
+ if (input.expectedVersion <= 0n) {
34014
+ throw new Error("expectedVersion must be a positive version number");
34015
+ }
34016
+ assertUint256(input.expectedVersion, "expectedVersion");
34017
+ return {
34018
+ domain: dataRegistryDomain(input.config),
34019
+ types: ADD_DATA_TYPES,
34020
+ primaryType: "AddData",
34021
+ message: {
34022
+ ownerAddress: input.ownerAddress,
34023
+ scope: input.scope,
34024
+ dataHash: TOMBSTONE_DATA_HASH,
34025
+ metadataHash: TOMBSTONE_METADATA_HASH,
34026
+ expectedVersion: input.expectedVersion
34027
+ }
34028
+ };
34029
+ }
34030
+ async function buildDataPointDeletionSignature(input) {
34031
+ const typedData = buildDataPointDeletionTypedData({
34032
+ ownerAddress: input.signer.address,
34033
+ scope: input.scope,
34034
+ expectedVersion: input.expectedVersion,
34035
+ config: input.config
34036
+ });
34037
+ const signature = await input.signer.signTypedData(typedData);
34038
+ return {
34039
+ signature,
34040
+ signerAddress: input.signer.address,
34041
+ typedData
34042
+ };
34043
+ }
34044
+ function toError(value) {
34045
+ return value instanceof Error ? value : new Error(String(value));
34046
+ }
34047
+ function parseExpectedVersion(value) {
34048
+ if (typeof value !== "string" || !/^\d+$/.test(value)) {
34049
+ throw new Error(
34050
+ `Gateway returned a malformed expectedVersion: ${JSON.stringify(value)}`
34051
+ );
34052
+ }
34053
+ const parsed = BigInt(value);
34054
+ assertUint256(parsed, "Gateway expectedVersion");
34055
+ return parsed;
34056
+ }
34057
+ async function deleteDataPoint(input) {
34058
+ const ownerAddress = input.signer.address;
34059
+ const dataPointId = deriveDataPointId(ownerAddress, input.scope);
34060
+ let currentVersion = input.currentVersion;
34061
+ if (currentVersion === void 0) {
34062
+ const record = await input.gateway.getDataPoint(dataPointId);
34063
+ if (record === null) {
34064
+ throw new DataPointNotFoundError(
34065
+ `No data point registered for scope '${input.scope}' owned by ${ownerAddress}`,
34066
+ { dataPointId, scope: input.scope, ownerAddress }
34067
+ );
34068
+ }
34069
+ if (isDataPointTombstone(record)) {
34070
+ throw new DataPointDeletedError(
34071
+ `Data point ${dataPointId} (scope '${input.scope}') is already deleted`,
34072
+ {
34073
+ dataPointId,
34074
+ scope: input.scope,
34075
+ ownerAddress,
34076
+ deletedAt: tombstoneDeletedAt(record)
34077
+ }
34078
+ );
34079
+ }
34080
+ currentVersion = parseExpectedVersion(record.expectedVersion);
34081
+ }
34082
+ if (currentVersion < 0n || currentVersion >= maxUint256) {
34083
+ throw new Error(
34084
+ `currentVersion ${currentVersion} cannot be incremented to a uint256 tombstone version`
34085
+ );
34086
+ }
34087
+ const tombstoneVersion = currentVersion + 1n;
34088
+ const signed = await buildDataPointDeletionSignature({
34089
+ signer: input.signer,
34090
+ scope: input.scope,
34091
+ expectedVersion: tombstoneVersion,
34092
+ config: input.config
34093
+ });
34094
+ const tombstone = await input.gateway.deleteDataPoint({
34095
+ ownerAddress,
34096
+ scope: input.scope,
34097
+ expectedVersion: tombstoneVersion.toString(),
34098
+ signature: signed.signature
34099
+ });
34100
+ const base = {
34101
+ dataPointId,
34102
+ ownerAddress,
34103
+ scope: input.scope,
34104
+ version: tombstoneVersion.toString(),
34105
+ signature: signed.signature,
34106
+ tombstone
34107
+ };
34108
+ try {
34109
+ const storage = await input.storage.deleteScope(ownerAddress, input.scope);
34110
+ return { ...base, status: "deleted", storage };
34111
+ } catch (cause) {
34112
+ return { ...base, status: "partial", storageError: toError(cause) };
34113
+ }
34114
+ }
34115
+
34116
+ // src/protocol/data-file.ts
34117
+ import { z as z2 } from "zod";
34118
+ var DataFileEnvelopeSchema = z2.object({
34119
+ $schema: z2.string().url().optional(),
34120
+ version: z2.literal("1.0"),
34121
+ scope: z2.string(),
34122
+ schemaId: z2.string().optional(),
34123
+ collectedAt: z2.string().datetime(),
34124
+ data: z2.record(z2.string(), z2.unknown())
33474
34125
  });
33475
34126
  function createDataFileEnvelope(scope, collectedAt, data, schemaUrl, schemaId) {
33476
34127
  return {
@@ -33482,10 +34133,10 @@ function createDataFileEnvelope(scope, collectedAt, data, schemaUrl, schemaId) {
33482
34133
  data
33483
34134
  };
33484
34135
  }
33485
- var IngestResponseSchema = z.object({
33486
- scope: z.string(),
33487
- collectedAt: z.string().datetime(),
33488
- status: z.enum(["stored", "syncing"])
34136
+ var IngestResponseSchema = z2.object({
34137
+ scope: z2.string(),
34138
+ collectedAt: z2.string().datetime(),
34139
+ status: z2.enum(["stored", "syncing"])
33489
34140
  });
33490
34141
 
33491
34142
  // src/protocol/personal-server-data.ts
@@ -33519,19 +34170,35 @@ async function readPersonalServerData(params) {
33519
34170
  }
33520
34171
  const request = await buildPersonalServerDataReadRequest(params);
33521
34172
  const response = await fetchFn(request);
34173
+ if (response.status === 410) {
34174
+ throw new DataPointDeletedError(
34175
+ `Personal Server scope '${params.scope}' has been deleted`,
34176
+ {
34177
+ scope: params.scope,
34178
+ deletedAt: tombstoneDeletedAt(await readJsonValue(response))
34179
+ }
34180
+ );
34181
+ }
33522
34182
  if (!response.ok) {
33523
34183
  throw new Error(
33524
34184
  `Personal Server data read failed: ${response.status} ${response.statusText}`
33525
34185
  );
33526
34186
  }
33527
- return DataFileEnvelopeSchema.parse(await response.json());
34187
+ const body = await response.json();
34188
+ if (isDataPointTombstone(body)) {
34189
+ throw new DataPointDeletedError(
34190
+ `Personal Server scope '${params.scope}' has been deleted`,
34191
+ { scope: params.scope, deletedAt: tombstoneDeletedAt(body) }
34192
+ );
34193
+ }
34194
+ return DataFileEnvelopeSchema.parse(body);
33528
34195
  }
33529
34196
 
33530
34197
  // src/protocol/scopes.ts
33531
- import { z as z2 } from "zod";
34198
+ import { z as z3 } from "zod";
33532
34199
  var SOURCE_RE = /^[a-z0-9][a-z0-9_]*$/;
33533
34200
  var TAIL_SEGMENT_RE = /^[a-zA-Z0-9][a-zA-Z0-9_]*$/;
33534
- var ScopeSchema = z2.string().refine(
34201
+ var ScopeSchema = z3.string().refine(
33535
34202
  (scope) => {
33536
34203
  const parts = scope.split(".");
33537
34204
  if (parts.length < 2 || parts.length > 3) return false;
@@ -33718,6 +34385,561 @@ function tryGrantPermissions(scopes) {
33718
34385
  }
33719
34386
  }
33720
34387
 
34388
+ // src/protocol/personal-server-write.ts
34389
+ import { sha256 as sha2565 } from "@noble/hashes/sha2";
34390
+ import { bytesToHex as bytesToHex2, isAddress as isAddress6 } from "viem";
34391
+ import { z as z4 } from "zod";
34392
+ var WRITE_SESSION_PATH = "/v1/write/session";
34393
+ var WRITE_SIGNATURE_HEADER = "X-Vana-Write-Signature";
34394
+ var WRITE_METADATA_HEADER = "X-Vana-Metadata";
34395
+ var LINEAGE_FIELD = "lineage";
34396
+ var MAX_LINEAGE_SOURCES = 256;
34397
+ var WRITE_FILENAME_HEADER = "X-Filename";
34398
+ var WRITE_CONTENT_DISPOSITION_HEADER = "Content-Disposition";
34399
+ var WRITER_ATTRIBUTION_KEY = "$writtenBy";
34400
+ var LINEAGE_KEY = "$lineage";
34401
+ var RESERVED_WRITE_KEYS = [
34402
+ WRITER_ATTRIBUTION_KEY,
34403
+ LINEAGE_KEY
34404
+ ];
34405
+ var WriteDataResultSchema = IngestResponseSchema.extend({
34406
+ // Present when the write carried lineage: the validated, lowercased ids.
34407
+ lineage: z4.object({ sources: z4.array(z4.string()) }).optional()
34408
+ });
34409
+ var WriteSessionResponseSchema = z4.object({
34410
+ access_token: z4.string().min(1),
34411
+ token_type: z4.string(),
34412
+ expires_in: z4.number().nonnegative(),
34413
+ scope: z4.string()
34414
+ });
34415
+ function normalizeBaseUrl2(url) {
34416
+ return url.replace(/\/+$/, "");
34417
+ }
34418
+ function resolveFetch2(fetchFn) {
34419
+ const resolved = fetchFn ?? globalThis.fetch;
34420
+ if (resolved === void 0) {
34421
+ throw new WriteRequestError("No fetch implementation available");
34422
+ }
34423
+ return resolved;
34424
+ }
34425
+ function dataPath(scope) {
34426
+ return `/v1/data/${encodeURIComponent(scope)}`;
34427
+ }
34428
+ function errorMessage(err) {
34429
+ return err instanceof Error ? err.message : String(err);
34430
+ }
34431
+ function finiteOr(value, fallback) {
34432
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
34433
+ }
34434
+ function sleep2(ms) {
34435
+ return new Promise((resolve) => setTimeout(resolve, ms));
34436
+ }
34437
+ var issuedProofIats = /* @__PURE__ */ new Map();
34438
+ var issuedProofBuckets = /* @__PURE__ */ new Map();
34439
+ var issuedProofIatsPrunedAtSec = 0;
34440
+ var WEB3_SIGNED_PROOF_LIFETIME_SECONDS = 300;
34441
+ var WEB3_SIGNED_CLOCK_SKEW_SECONDS = 60;
34442
+ var PROOF_IAT_RETENTION_SECONDS = WEB3_SIGNED_PROOF_LIFETIME_SECONDS + WEB3_SIGNED_CLOCK_SKEW_SECONDS;
34443
+ var PROOF_IAT_MAX_AHEAD_SECONDS = 30;
34444
+ function pruneIssuedProofIats(nowSec) {
34445
+ if (issuedProofIatsPrunedAtSec === nowSec) return;
34446
+ issuedProofIatsPrunedAtSec = nowSec;
34447
+ const cutoff = nowSec - PROOF_IAT_RETENTION_SECONDS;
34448
+ for (const [sec, keys] of issuedProofBuckets) {
34449
+ if (sec >= cutoff) continue;
34450
+ for (const key of keys) issuedProofIats.delete(key);
34451
+ issuedProofBuckets.delete(sec);
34452
+ }
34453
+ }
34454
+ function setIssuedProofIat(key, iat, previous) {
34455
+ if (previous !== void 0) {
34456
+ const bucket2 = issuedProofBuckets.get(previous);
34457
+ bucket2?.delete(key);
34458
+ if (bucket2?.size === 0) issuedProofBuckets.delete(previous);
34459
+ }
34460
+ issuedProofIats.set(key, iat);
34461
+ let bucket = issuedProofBuckets.get(iat);
34462
+ if (bucket === void 0) {
34463
+ bucket = /* @__PURE__ */ new Set();
34464
+ issuedProofBuckets.set(iat, bucket);
34465
+ }
34466
+ bucket.add(key);
34467
+ }
34468
+ function nextProofIat(proofKey) {
34469
+ const nowSec = Math.floor(Date.now() / 1e3);
34470
+ pruneIssuedProofIats(nowSec);
34471
+ const last = issuedProofIats.get(proofKey);
34472
+ const iat = last === void 0 ? nowSec : Math.max(nowSec, last + 1);
34473
+ setIssuedProofIat(proofKey, iat, last);
34474
+ const waitSec = iat - nowSec - PROOF_IAT_MAX_AHEAD_SECONDS;
34475
+ if (waitSec <= 0) return Promise.resolve(iat);
34476
+ return sleep2(waitSec * 1e3).then(() => iat);
34477
+ }
34478
+ function proofKeyFor(parts) {
34479
+ return bytesToHex2(
34480
+ sha2565(
34481
+ new TextEncoder().encode(
34482
+ JSON.stringify([
34483
+ parts.aud,
34484
+ parts.method,
34485
+ parts.uri,
34486
+ parts.grantId,
34487
+ parts.signedBytes ? bytesToHex2(sha2565(parts.signedBytes)) : ""
34488
+ ])
34489
+ )
34490
+ )
34491
+ );
34492
+ }
34493
+ async function sendWithFreshProof(label, fetchFn, options, proofKey, build) {
34494
+ const attempts = Math.max(1, Math.floor(finiteOr(options?.attempts, 3)));
34495
+ let delayMs = Math.max(0, finiteOr(options?.initialDelayMs, 1e3));
34496
+ let lastError;
34497
+ for (let attempt = 0; attempt < attempts; attempt++) {
34498
+ const { url, init } = await build(await nextProofIat(proofKey));
34499
+ try {
34500
+ return await fetchFn(url, init);
34501
+ } catch (err) {
34502
+ lastError = err;
34503
+ }
34504
+ if (attempt < attempts - 1) {
34505
+ await sleep2(delayMs);
34506
+ delayMs *= 2;
34507
+ }
34508
+ }
34509
+ throw new WriteTransportError(
34510
+ `${label} failed after ${attempts} attempt(s): ${errorMessage(lastError)}`,
34511
+ attempts,
34512
+ lastError
34513
+ );
34514
+ }
34515
+ async function openWriteSession(params) {
34516
+ const fetchFn = resolveFetch2(params.fetch);
34517
+ const personalServerUrl = normalizeBaseUrl2(params.personalServerUrl);
34518
+ const audience = params.audience ?? personalServerUrl;
34519
+ const signer = resolveWriteSigner(params.signer, { account: params.account });
34520
+ const response = await sendWithFreshProof(
34521
+ "Write session handshake",
34522
+ fetchFn,
34523
+ params.retry,
34524
+ proofKeyFor({
34525
+ aud: audience,
34526
+ method: "POST",
34527
+ uri: WRITE_SESSION_PATH,
34528
+ grantId: params.grantId
34529
+ }),
34530
+ async (iat) => {
34531
+ const headers = new Headers(params.headers);
34532
+ headers.set(
34533
+ "Authorization",
34534
+ await buildWeb3SignedHeader({
34535
+ signMessage: signer.signMessage,
34536
+ aud: audience,
34537
+ method: "POST",
34538
+ uri: WRITE_SESSION_PATH,
34539
+ grantId: params.grantId,
34540
+ iat
34541
+ })
34542
+ );
34543
+ return {
34544
+ url: `${personalServerUrl}${WRITE_SESSION_PATH}`,
34545
+ init: { method: "POST", headers }
34546
+ };
34547
+ }
34548
+ );
34549
+ const mintedAt = Date.now();
34550
+ if (!response.ok) {
34551
+ const { errorCode, message, details } = await readPersonalServerErrorBody(response);
34552
+ throw new WriteSessionError(
34553
+ message ?? `Write session handshake failed: ${response.status} ${response.statusText}`,
34554
+ response.status,
34555
+ errorCode,
34556
+ details
34557
+ );
34558
+ }
34559
+ let body;
34560
+ try {
34561
+ body = await response.json();
34562
+ } catch (err) {
34563
+ throw new WriteSessionError(
34564
+ "Write session response is not JSON",
34565
+ response.status,
34566
+ null,
34567
+ { cause: errorMessage(err) }
34568
+ );
34569
+ }
34570
+ const parsed = WriteSessionResponseSchema.safeParse(body);
34571
+ if (!parsed.success) {
34572
+ throw new WriteSessionError(
34573
+ "Write session response is not a session",
34574
+ response.status,
34575
+ null,
34576
+ { issues: parsed.error.issues }
34577
+ );
34578
+ }
34579
+ if (parsed.data.token_type.toLowerCase() !== "bearer") {
34580
+ throw new WriteSessionError(
34581
+ `Write session token type is not Bearer: ${parsed.data.token_type}`,
34582
+ response.status
34583
+ );
34584
+ }
34585
+ return {
34586
+ personalServerUrl,
34587
+ audience,
34588
+ grantId: params.grantId,
34589
+ accessToken: parsed.data.access_token,
34590
+ expiresAt: mintedAt + parsed.data.expires_in * 1e3,
34591
+ writeScopes: parsed.data.scope.split(" ").filter((s) => s.length > 0),
34592
+ signer
34593
+ };
34594
+ }
34595
+ function isWriteSession(value) {
34596
+ if (!isRecord2(value)) return false;
34597
+ const signer = value.signer;
34598
+ return typeof value.personalServerUrl === "string" && typeof value.audience === "string" && typeof value.grantId === "string" && typeof value.accessToken === "string" && value.accessToken.length > 0 && typeof value.expiresAt === "number" && Number.isFinite(value.expiresAt) && Array.isArray(value.writeScopes) && value.writeScopes.every((scope) => typeof scope === "string") && isRecord2(signer) && typeof signer.signMessage === "function";
34599
+ }
34600
+ function sessionCoversScope(session, scope) {
34601
+ if (!isRecord2(session) || !Array.isArray(session.writeScopes) || !session.writeScopes.every((pattern) => typeof pattern === "string")) {
34602
+ throw new WriteRequestError("session must come from openWriteSession");
34603
+ }
34604
+ return session.writeScopes.some(
34605
+ (pattern) => scopeMatchesPattern(scope, pattern)
34606
+ );
34607
+ }
34608
+ function normalizeBinaryMimeType(contentType) {
34609
+ if (!contentType) return "application/octet-stream";
34610
+ return contentType.split(";")[0].trim() || "application/octet-stream";
34611
+ }
34612
+ function parseWriteMetadataHeader(value) {
34613
+ if (value === null) return void 0;
34614
+ const trimmed = value.trim();
34615
+ if (trimmed === "") return void 0;
34616
+ try {
34617
+ return JSON.parse(trimmed);
34618
+ } catch {
34619
+ return value;
34620
+ }
34621
+ }
34622
+ function encodeWriteMetadataHeader(metadata) {
34623
+ let json;
34624
+ try {
34625
+ json = JSON.stringify(metadata);
34626
+ } catch (err) {
34627
+ throw new WriteRequestError(
34628
+ `metadata is not JSON-serialisable: ${errorMessage(err)}`
34629
+ );
34630
+ }
34631
+ if (typeof json !== "string") {
34632
+ throw new WriteRequestError("metadata must serialise to JSON");
34633
+ }
34634
+ return json.replace(
34635
+ /[\u007f-\uffff]/g,
34636
+ (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`
34637
+ );
34638
+ }
34639
+ function binaryWriteSignedBytes(input) {
34640
+ const metadata = parseWriteMetadataHeader(input.metadataHeader ?? null);
34641
+ const record = {
34642
+ $binary: true,
34643
+ mimeType: normalizeBinaryMimeType(input.contentType),
34644
+ ...input.filename ? { filename: input.filename } : {},
34645
+ sizeBytes: input.bytes.length,
34646
+ contentHash: bytesToHex2(sha2565(input.bytes)),
34647
+ encoding: "base64",
34648
+ content: toBase64(input.bytes),
34649
+ ...metadata !== void 0 ? { metadata } : {}
34650
+ };
34651
+ return new TextEncoder().encode(JSON.stringify(record));
34652
+ }
34653
+ var PRINTABLE_ASCII = /^[\x20-\x7e]*$/;
34654
+ function setFilenameHeader(headers, filename) {
34655
+ if (PRINTABLE_ASCII.test(filename)) {
34656
+ headers.set(WRITE_FILENAME_HEADER, filename);
34657
+ return;
34658
+ }
34659
+ headers.set(
34660
+ WRITE_CONTENT_DISPOSITION_HEADER,
34661
+ `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`
34662
+ );
34663
+ }
34664
+ function assertNoReservedKeys(value, where) {
34665
+ for (const key of RESERVED_WRITE_KEYS) {
34666
+ if (Object.prototype.hasOwnProperty.call(value, key)) {
34667
+ throw new WriteRequestError(
34668
+ `${where} must not contain the reserved ${key} key; the Personal Server stamps it`,
34669
+ { key }
34670
+ );
34671
+ }
34672
+ }
34673
+ }
34674
+ function isLineagePair(value) {
34675
+ return isRecord2(value) && typeof value.ownerAddress === "string" && typeof value.scope === "string";
34676
+ }
34677
+ function normalizeLineage(lineage, derivedScope) {
34678
+ if (!Array.isArray(lineage)) {
34679
+ throw new WriteRequestError("lineage must be an array of data point ids");
34680
+ }
34681
+ if (lineage.length > MAX_LINEAGE_SOURCES) {
34682
+ throw new WriteRequestError(
34683
+ `lineage lists ${lineage.length} sources; the maximum is ${MAX_LINEAGE_SOURCES}`,
34684
+ { max: MAX_LINEAGE_SOURCES, count: lineage.length }
34685
+ );
34686
+ }
34687
+ const seen = /* @__PURE__ */ new Set();
34688
+ const sources = [];
34689
+ const sourceScopes = [];
34690
+ const ownIds = /* @__PURE__ */ new Set();
34691
+ for (const entry of lineage) {
34692
+ let id;
34693
+ if (isLineagePair(entry)) {
34694
+ if (!isAddress6(entry.ownerAddress, { strict: false })) {
34695
+ throw new WriteRequestError(
34696
+ "lineage source ownerAddress must be an EVM address",
34697
+ { ownerAddress: entry.ownerAddress }
34698
+ );
34699
+ }
34700
+ if (entry.scope.length === 0) {
34701
+ throw new WriteRequestError("lineage source scope is required");
34702
+ }
34703
+ id = deriveDataPointId(entry.ownerAddress, entry.scope);
34704
+ sourceScopes.push(entry.scope);
34705
+ ownIds.add(deriveDataPointId(entry.ownerAddress, derivedScope));
34706
+ } else if (isDataPointId(entry)) {
34707
+ id = entry;
34708
+ } else {
34709
+ throw new WriteRequestError(
34710
+ "lineage entries must be 32-byte hex data point ids or { ownerAddress, scope } pairs",
34711
+ { entry }
34712
+ );
34713
+ }
34714
+ const normalized = id.toLowerCase();
34715
+ if (seen.has(normalized)) {
34716
+ throw new WriteRequestError("lineage must not repeat a data point id", {
34717
+ dataPointId: normalized
34718
+ });
34719
+ }
34720
+ seen.add(normalized);
34721
+ sources.push(normalized);
34722
+ }
34723
+ for (const own of ownIds) {
34724
+ if (seen.has(own)) {
34725
+ throw new WriteRequestError(
34726
+ "lineage must not cite the record's own data point",
34727
+ { dataPointId: own, scope: derivedScope }
34728
+ );
34729
+ }
34730
+ }
34731
+ assertDerivedScopeNaming(derivedScope, sourceScopes);
34732
+ return sources;
34733
+ }
34734
+ function assertNoLineageField(value, where) {
34735
+ if (Object.prototype.hasOwnProperty.call(value, LINEAGE_FIELD)) {
34736
+ throw new WriteRequestError(
34737
+ `${where}.${LINEAGE_FIELD} is reserved; pass sources through the lineage option`
34738
+ );
34739
+ }
34740
+ }
34741
+ function buildMetadataHeader(metadata, sources) {
34742
+ if (metadata !== void 0) {
34743
+ if (!isRecord2(metadata)) {
34744
+ throw new WriteRequestError("metadata must be a plain object");
34745
+ }
34746
+ assertNoReservedKeys(metadata, "metadata");
34747
+ assertNoLineageField(metadata, "metadata");
34748
+ }
34749
+ if (metadata === void 0 && sources === void 0) return void 0;
34750
+ return encodeWriteMetadataHeader({
34751
+ ...metadata ?? {},
34752
+ ...sources !== void 0 ? { [LINEAGE_FIELD]: sources } : {}
34753
+ });
34754
+ }
34755
+ function prepareWrite(params) {
34756
+ if (params.binary !== void 0 && params.data !== void 0) {
34757
+ throw new WriteRequestError("Pass either data or binary, not both");
34758
+ }
34759
+ const rawLineage = params.lineage;
34760
+ const sources = rawLineage === void 0 || rawLineage === null ? void 0 : normalizeLineage(rawLineage, params.scope);
34761
+ if (params.binary !== void 0) {
34762
+ const { bytes, contentType, filename } = params.binary;
34763
+ if (!(bytes instanceof Uint8Array)) {
34764
+ throw new WriteRequestError("binary.bytes must be a Uint8Array");
34765
+ }
34766
+ if (typeof contentType !== "string" || contentType.trim() === "") {
34767
+ throw new WriteRequestError("binary.contentType is required");
34768
+ }
34769
+ if (filename !== void 0) {
34770
+ if (typeof filename !== "string") {
34771
+ throw new WriteRequestError("binary.filename must be a string");
34772
+ }
34773
+ if (filename !== filename.trim()) {
34774
+ throw new WriteRequestError(
34775
+ "binary.filename must not have leading or trailing whitespace"
34776
+ );
34777
+ }
34778
+ }
34779
+ const metadataHeader = buildMetadataHeader(params.metadata, sources);
34780
+ return {
34781
+ body: bytes,
34782
+ signedBytes: binaryWriteSignedBytes({
34783
+ bytes,
34784
+ contentType,
34785
+ filename,
34786
+ metadataHeader
34787
+ }),
34788
+ contentType,
34789
+ filename,
34790
+ metadataHeader
34791
+ };
34792
+ }
34793
+ if (params.data === void 0) {
34794
+ throw new WriteRequestError("Pass data (a JSON object) or binary");
34795
+ }
34796
+ if (!isRecord2(params.data)) {
34797
+ throw new WriteRequestError("data must be a plain JSON object");
34798
+ }
34799
+ if (params.metadata !== void 0) {
34800
+ throw new WriteRequestError(
34801
+ "metadata applies to binary writes; put fields to store inside data"
34802
+ );
34803
+ }
34804
+ assertNoReservedKeys(params.data, "data");
34805
+ assertNoLineageField(params.data, "data");
34806
+ const record = sources === void 0 ? params.data : { ...params.data, [LINEAGE_FIELD]: sources };
34807
+ let text;
34808
+ try {
34809
+ text = JSON.stringify(record);
34810
+ } catch (err) {
34811
+ throw new WriteRequestError(
34812
+ `data is not JSON-serialisable: ${errorMessage(err)}`
34813
+ );
34814
+ }
34815
+ if (typeof text !== "string" || !text.startsWith("{")) {
34816
+ throw new WriteRequestError("data must serialise to a JSON object");
34817
+ }
34818
+ const body = new TextEncoder().encode(text);
34819
+ return {
34820
+ body,
34821
+ signedBytes: body,
34822
+ contentType: "application/json"
34823
+ };
34824
+ }
34825
+ async function writeErrorFromResponse(response) {
34826
+ const { errorCode, message, details } = await readPersonalServerErrorBody(response);
34827
+ const text = message ?? `Personal Server write failed: ${response.status} ${response.statusText}`;
34828
+ if (response.status === 422 || errorCode?.startsWith("LINEAGE_")) {
34829
+ return new WriteLineageError(text, response.status, errorCode, details);
34830
+ }
34831
+ switch (response.status) {
34832
+ case 401:
34833
+ return new WriteUnauthorizedError(text, errorCode, details);
34834
+ case 403:
34835
+ return new WriteForbiddenError(text, errorCode, details);
34836
+ case 409:
34837
+ return new WriteConflictError(text, errorCode, details);
34838
+ default:
34839
+ return new WriteRejectedError(text, response.status, errorCode, details);
34840
+ }
34841
+ }
34842
+ async function writeData(params) {
34843
+ const { session } = params;
34844
+ if (!isWriteSession(session)) {
34845
+ throw new WriteRequestError("session must come from openWriteSession");
34846
+ }
34847
+ const fetchFn = resolveFetch2(params.fetch);
34848
+ if (typeof params.scope !== "string" || params.scope.length === 0) {
34849
+ throw new WriteRequestError("scope is required");
34850
+ }
34851
+ const prepared = prepareWrite(params);
34852
+ if (Date.now() >= session.expiresAt) {
34853
+ throw new WriteSessionExpiredError(
34854
+ "Write session has expired; open a new session",
34855
+ { grantId: session.grantId, expiresAt: session.expiresAt }
34856
+ );
34857
+ }
34858
+ const path = dataPath(params.scope);
34859
+ const response = await sendWithFreshProof(
34860
+ `Write to ${params.scope}`,
34861
+ fetchFn,
34862
+ params.retry,
34863
+ proofKeyFor({
34864
+ aud: session.audience,
34865
+ method: "POST",
34866
+ uri: path,
34867
+ grantId: session.grantId,
34868
+ signedBytes: prepared.signedBytes
34869
+ }),
34870
+ async (iat) => {
34871
+ const headers = new Headers(params.headers);
34872
+ headers.set("Content-Type", prepared.contentType);
34873
+ headers.set("Authorization", `Bearer ${session.accessToken}`);
34874
+ if (prepared.filename) {
34875
+ setFilenameHeader(headers, prepared.filename);
34876
+ }
34877
+ if (prepared.metadataHeader !== void 0) {
34878
+ headers.set(WRITE_METADATA_HEADER, prepared.metadataHeader);
34879
+ }
34880
+ headers.set(
34881
+ WRITE_SIGNATURE_HEADER,
34882
+ await buildWeb3SignedHeader({
34883
+ signMessage: session.signer.signMessage,
34884
+ aud: session.audience,
34885
+ method: "POST",
34886
+ uri: path,
34887
+ body: prepared.signedBytes,
34888
+ grantId: session.grantId,
34889
+ iat
34890
+ })
34891
+ );
34892
+ return {
34893
+ url: `${session.personalServerUrl}${path}`,
34894
+ init: {
34895
+ method: "POST",
34896
+ headers,
34897
+ body: prepared.body
34898
+ }
34899
+ };
34900
+ }
34901
+ );
34902
+ if (!response.ok) {
34903
+ throw await writeErrorFromResponse(response);
34904
+ }
34905
+ let body;
34906
+ try {
34907
+ body = await response.json();
34908
+ } catch (err) {
34909
+ throw new WriteRejectedError(
34910
+ "Personal Server write response is not JSON",
34911
+ response.status,
34912
+ null,
34913
+ { cause: errorMessage(err) }
34914
+ );
34915
+ }
34916
+ const parsed = WriteDataResultSchema.safeParse(body);
34917
+ if (!parsed.success) {
34918
+ throw new WriteRejectedError(
34919
+ "Personal Server write response is not an ingest result",
34920
+ response.status,
34921
+ null,
34922
+ { issues: parsed.error.issues }
34923
+ );
34924
+ }
34925
+ return parsed.data;
34926
+ }
34927
+ async function writePersonalServerData(params) {
34928
+ const session = await openWriteSession({
34929
+ personalServerUrl: params.personalServerUrl,
34930
+ signer: params.signer,
34931
+ grantId: params.grantId,
34932
+ account: params.account,
34933
+ audience: params.audience,
34934
+ fetch: params.fetch,
34935
+ headers: params.headers,
34936
+ retry: params.retry
34937
+ });
34938
+ const writeParams = { ...params, session };
34939
+ const result = await writeData(writeParams);
34940
+ return { ...result, session };
34941
+ }
34942
+
33721
34943
  // src/protocol/gateway.ts
33722
34944
  function withGrantPermissions(grant) {
33723
34945
  const stripped = { ...grant };
@@ -33731,14 +34953,44 @@ function withGrantPermissions(grant) {
33731
34953
  }
33732
34954
  function createGatewayClient(baseUrl) {
33733
34955
  const base = baseUrl.replace(/\/+$/, "");
34956
+ function malformedBody(res) {
34957
+ return new Error(
34958
+ `Gateway error: ${res.status} malformed response body (expected a JSON envelope)`
34959
+ );
34960
+ }
34961
+ async function readEnvelope(res) {
34962
+ const envelope = await readJsonValue(res);
34963
+ if (!isPlainObject(envelope) || !("data" in envelope)) {
34964
+ throw malformedBody(res);
34965
+ }
34966
+ return envelope;
34967
+ }
33734
34968
  async function unwrapEnvelope(res) {
33735
- const envelope = await res.json();
33736
- return envelope.data;
34969
+ return (await readEnvelope(res)).data;
33737
34970
  }
33738
34971
  function getMutationId(body, key) {
34972
+ if (!isPlainObject(body)) return void 0;
33739
34973
  const value = body[key] ?? body["id"];
33740
34974
  return typeof value === "string" ? value : void 0;
33741
34975
  }
34976
+ async function readBody(res) {
34977
+ const raw = await readJsonObject(res);
34978
+ const data = raw["data"];
34979
+ if (isPlainObject(data) && "proof" in raw) {
34980
+ return data;
34981
+ }
34982
+ return raw;
34983
+ }
34984
+ function stringOrUndefined(value) {
34985
+ return typeof value === "string" ? value : void 0;
34986
+ }
34987
+ async function deletedError(res, details) {
34988
+ const body = await readBody(res);
34989
+ return new DataPointDeletedError(
34990
+ `Data point ${details.dataPointId ?? details.scope ?? ""} has been deleted`,
34991
+ { ...details, deletedAt: tombstoneDeletedAt(body) }
34992
+ );
34993
+ }
33742
34994
  return {
33743
34995
  async isRegisteredBuilder(address) {
33744
34996
  const builder = await this.getBuilder(address);
@@ -33795,13 +35047,29 @@ function createGatewayClient(baseUrl) {
33795
35047
  }
33796
35048
  return await res.json();
33797
35049
  },
33798
- async getDataPoint(dataPointId) {
33799
- const res = await fetch(`${base}/v1/data/${dataPointId}`);
35050
+ async getDataPoint(dataPointId, options) {
35051
+ const query = options?.includeDeleted ? "?includeDeleted=true" : "";
35052
+ const res = await fetch(`${base}/v1/data/${dataPointId}${query}`);
33800
35053
  if (res.status === 404) return null;
35054
+ if (res.status === 410) {
35055
+ throw await deletedError(res, { dataPointId });
35056
+ }
33801
35057
  if (!res.ok) {
33802
35058
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
33803
35059
  }
33804
- return unwrapEnvelope(res);
35060
+ const record = await unwrapEnvelope(res);
35061
+ if (!options?.includeDeleted && isDataPointTombstone(record)) {
35062
+ throw new DataPointDeletedError(
35063
+ `Data point ${dataPointId} has been deleted`,
35064
+ {
35065
+ dataPointId,
35066
+ scope: record.scope,
35067
+ ownerAddress: record.ownerAddress,
35068
+ deletedAt: tombstoneDeletedAt(record)
35069
+ }
35070
+ );
35071
+ }
35072
+ return record;
33805
35073
  },
33806
35074
  async listDataPointsByOwner(owner, cursor, options) {
33807
35075
  const params = new URLSearchParams({ user: owner });
@@ -33814,14 +35082,24 @@ function createGatewayClient(baseUrl) {
33814
35082
  if (options?.limit !== void 0) {
33815
35083
  params.set("limit", String(options.limit));
33816
35084
  }
35085
+ if (options?.includeDeleted) {
35086
+ params.set("includeDeleted", "true");
35087
+ }
33817
35088
  const res = await fetch(`${base}/v1/data?${params.toString()}`);
33818
35089
  if (!res.ok) {
33819
35090
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
33820
35091
  }
33821
- const envelope = await res.json();
33822
- const nextCursor = envelope.pagination?.hasMore === false ? null : envelope.pagination?.nextCursor ?? null;
35092
+ const envelope = await readEnvelope(res);
35093
+ if (!isPlainObject(envelope.data) || !Array.isArray(envelope.data["dataPoints"])) {
35094
+ throw malformedBody(res);
35095
+ }
35096
+ const rows = envelope.data["dataPoints"];
35097
+ const pagination = isPlainObject(envelope["pagination"]) ? envelope["pagination"] : void 0;
35098
+ const rawCursor = pagination?.["nextCursor"];
35099
+ const nextCursor = pagination?.["hasMore"] === false || typeof rawCursor !== "string" ? null : rawCursor;
35100
+ const dataPoints = options?.includeDeleted ? rows : rows.filter((row) => !isDataPointTombstone(row));
33823
35101
  return {
33824
- dataPoints: envelope.data.dataPoints,
35102
+ dataPoints,
33825
35103
  cursor: nextCursor
33826
35104
  };
33827
35105
  },
@@ -33848,7 +35126,7 @@ function createGatewayClient(baseUrl) {
33848
35126
  })
33849
35127
  });
33850
35128
  if (res.status === 409) {
33851
- const body2 = await res.json().catch(() => ({}));
35129
+ const body2 = await readJsonObject(res);
33852
35130
  return {
33853
35131
  serverId: getMutationId(body2, "serverId"),
33854
35132
  alreadyRegistered: true
@@ -33857,7 +35135,7 @@ function createGatewayClient(baseUrl) {
33857
35135
  if (!res.ok) {
33858
35136
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
33859
35137
  }
33860
- const body = await res.json().catch(() => ({}));
35138
+ const body = await readJsonObject(res);
33861
35139
  return {
33862
35140
  serverId: getMutationId(body, "serverId"),
33863
35141
  alreadyRegistered: false
@@ -33878,19 +35156,16 @@ function createGatewayClient(baseUrl) {
33878
35156
  })
33879
35157
  });
33880
35158
  if (res.status === 409) {
33881
- const body2 = await res.json().catch(() => ({}));
35159
+ const body2 = await readJsonObject(res);
33882
35160
  return {
33883
- builderId: getMutationId(
33884
- body2,
33885
- "builderId"
33886
- ),
35161
+ builderId: getMutationId(body2, "builderId"),
33887
35162
  alreadyRegistered: true
33888
35163
  };
33889
35164
  }
33890
35165
  if (!res.ok) {
33891
35166
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
33892
35167
  }
33893
- const body = await res.json().catch(() => ({}));
35168
+ const body = await readJsonObject(res);
33894
35169
  return {
33895
35170
  builderId: getMutationId(body, "builderId"),
33896
35171
  alreadyRegistered: false
@@ -33912,17 +35187,77 @@ function createGatewayClient(baseUrl) {
33912
35187
  })
33913
35188
  });
33914
35189
  if (!res.ok) {
33915
- const body2 = await res.json().catch(() => ({}));
33916
- const detail = body2.error ?? res.statusText;
35190
+ const body2 = await readJsonObject(res);
35191
+ const detail = stringOrUndefined(body2["error"]) ?? res.statusText;
35192
+ throw new Error(`Gateway error: ${res.status} ${detail}`);
35193
+ }
35194
+ const body = await readJsonObject(res);
35195
+ return {
35196
+ dataPointId: getMutationId(body, "dataPointId"),
35197
+ expectedVersion: stringOrUndefined(body["expectedVersion"])
35198
+ };
35199
+ },
35200
+ async deleteDataPoint(params) {
35201
+ const dataPointId = deriveDataPointId(
35202
+ params.ownerAddress,
35203
+ params.scope
35204
+ );
35205
+ const details = {
35206
+ dataPointId,
35207
+ scope: params.scope,
35208
+ ownerAddress: params.ownerAddress
35209
+ };
35210
+ const res = await fetch(`${base}/v1/data/${dataPointId}`, {
35211
+ method: "DELETE",
35212
+ headers: {
35213
+ "Content-Type": "application/json",
35214
+ Authorization: `Web3Signed ${params.signature}`
35215
+ },
35216
+ body: JSON.stringify({
35217
+ ownerAddress: params.ownerAddress,
35218
+ scope: params.scope,
35219
+ expectedVersion: params.expectedVersion,
35220
+ signature: params.signature
35221
+ })
35222
+ });
35223
+ if (res.status === 404) {
35224
+ throw new DataPointNotFoundError(
35225
+ `Data point ${dataPointId} (scope '${params.scope}') is not registered`,
35226
+ details
35227
+ );
35228
+ }
35229
+ if (res.status === 409) {
35230
+ const body2 = await readBody(res);
35231
+ const currentExpectedVersion = stringOrUndefined(
35232
+ body2["currentExpectedVersion"]
35233
+ );
35234
+ const detail = stringOrUndefined(body2["error"]) ?? res.statusText;
35235
+ throw new DataPointVersionConflictError(
35236
+ `Gateway error: 409 ${detail}`,
35237
+ {
35238
+ ...details,
35239
+ expectedVersion: params.expectedVersion,
35240
+ currentExpectedVersion
35241
+ }
35242
+ );
35243
+ }
35244
+ if (res.status === 410) {
35245
+ throw await deletedError(res, details);
35246
+ }
35247
+ if (!res.ok) {
35248
+ const body2 = await readBody(res);
35249
+ const detail = stringOrUndefined(body2["error"]) ?? res.statusText;
33917
35250
  throw new Error(`Gateway error: ${res.status} ${detail}`);
33918
35251
  }
33919
- const body = await res.json().catch(() => ({}));
35252
+ const body = await readBody(res);
33920
35253
  return {
33921
- dataPointId: getMutationId(
33922
- body,
33923
- "dataPointId"
33924
- ),
33925
- expectedVersion: body.expectedVersion
35254
+ dataPointId: getMutationId(body, "dataPointId") ?? dataPointId,
35255
+ ownerAddress: stringOrUndefined(body["ownerAddress"]),
35256
+ scope: stringOrUndefined(body["scope"]),
35257
+ dataHash: stringOrUndefined(body["dataHash"]),
35258
+ metadataHash: stringOrUndefined(body["metadataHash"]),
35259
+ expectedVersion: stringOrUndefined(body["expectedVersion"]),
35260
+ deletedAt: tombstoneDeletedAt(body)
33926
35261
  };
33927
35262
  },
33928
35263
  async createGrant(params) {
@@ -33941,18 +35276,14 @@ function createGatewayClient(baseUrl) {
33941
35276
  })
33942
35277
  });
33943
35278
  if (res.status === 409) {
33944
- const body2 = await res.json().catch(() => ({}));
33945
- return {
33946
- grantId: getMutationId(body2, "grantId")
33947
- };
35279
+ const body2 = await readJsonObject(res);
35280
+ return { grantId: getMutationId(body2, "grantId") };
33948
35281
  }
33949
35282
  if (!res.ok) {
33950
35283
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
33951
35284
  }
33952
- const body = await res.json();
33953
- return {
33954
- grantId: getMutationId(body, "grantId")
33955
- };
35285
+ const body = await readJsonObject(res);
35286
+ return { grantId: getMutationId(body, "grantId") };
33956
35287
  },
33957
35288
  async revokeGrant(params) {
33958
35289
  const res = await fetch(`${base}/v1/grants/${params.grantId}`, {
@@ -34638,7 +35969,7 @@ var KNOWN_CODES = /* @__PURE__ */ new Set([
34638
35969
  "server_not_configured",
34639
35970
  "content_too_large"
34640
35971
  ]);
34641
- function isRecord2(value) {
35972
+ function isRecord4(value) {
34642
35973
  return value !== null && typeof value === "object" && !Array.isArray(value);
34643
35974
  }
34644
35975
  function normalizeCode(value) {
@@ -34649,10 +35980,10 @@ function normalizeCode(value) {
34649
35980
  return KNOWN_CODES.has(code) ? code : null;
34650
35981
  }
34651
35982
  function extractPSErrorBody(body) {
34652
- if (!isRecord2(body)) {
35983
+ if (!isRecord4(body)) {
34653
35984
  return null;
34654
35985
  }
34655
- const nested = isRecord2(body.error) ? body.error : null;
35986
+ const nested = isRecord4(body.error) ? body.error : null;
34656
35987
  const code = normalizeCode(
34657
35988
  nested?.errorCode ?? nested?.code ?? body.errorCode ?? body.code
34658
35989
  );
@@ -34690,7 +36021,10 @@ export {
34690
36021
  DATA_ACCESS_OP_TYPE,
34691
36022
  DATA_REGISTRY_STATUS_ABI,
34692
36023
  DataFileEnvelopeSchema,
36024
+ DataPointDeletedError,
36025
+ DataPointNotFoundError,
34693
36026
  DataPointStatus,
36027
+ DataPointVersionConflictError,
34694
36028
  DropboxStorage,
34695
36029
  ECIESError,
34696
36030
  ESCROW_DEPOSIT_ABI2 as ESCROW_DEPOSIT_ABI,
@@ -34707,7 +36041,14 @@ export {
34707
36041
  InvalidScopeEntryError,
34708
36042
  InvalidSignatureError,
34709
36043
  IpfsStorage,
36044
+ LINEAGE_FIELD,
36045
+ LINEAGE_KEY,
36046
+ LineageEntrySchema,
36047
+ LineageGraphSchema,
36048
+ LineageNodeSchema,
36049
+ LineageReadError,
34710
36050
  MASTER_KEY_MESSAGE,
36051
+ MAX_LINEAGE_SOURCES,
34711
36052
  MissingAuthError,
34712
36053
  NATIVE_ASSET_ADDRESS,
34713
36054
  NATIVE_VANA_ASSET,
@@ -34726,11 +36067,14 @@ export {
34726
36067
  PSError,
34727
36068
  PermissionError,
34728
36069
  PersonalServerError,
36070
+ PersonalServerWriteError,
34729
36071
  PinataStorage,
34730
36072
  R2Storage,
34731
36073
  RECORD_DATA_ACCESS_TYPES,
34732
36074
  REGISTRATION_KIND_FOR_OP,
36075
+ RESERVED_WRITE_KEYS,
34733
36076
  ReadOnlyError,
36077
+ RedactedLineageNodeSchema,
34734
36078
  RelayerError,
34735
36079
  SCOPE_ACTIONS,
34736
36080
  SERVER_REGISTRATION_TYPES,
@@ -34740,13 +36084,36 @@ export {
34740
36084
  SignatureError,
34741
36085
  StorageError,
34742
36086
  StorageManager,
36087
+ TOMBSTONE_DATA_HASH,
36088
+ TOMBSTONE_DATA_HASH_PREIMAGE,
36089
+ TOMBSTONE_METADATA_HASH,
36090
+ TOMBSTONE_METADATA_HASH_PREIMAGE,
34743
36091
  TransactionPendingError,
34744
36092
  UserRejectedRequestError,
34745
36093
  VanaError,
34746
36094
  VanaStorage,
36095
+ WRITER_ATTRIBUTION_KEY,
36096
+ WRITE_CONTENT_DISPOSITION_HEADER,
36097
+ WRITE_FILENAME_HEADER,
36098
+ WRITE_METADATA_HEADER,
36099
+ WRITE_SESSION_PATH,
36100
+ WRITE_SIGNATURE_HEADER,
36101
+ WriteConflictError,
36102
+ WriteForbiddenError,
36103
+ WriteLineageError,
36104
+ WriteRejectedError,
36105
+ WriteRequestError,
36106
+ WriteSessionError,
36107
+ WriteSessionExpiredError,
36108
+ WriteTransportError,
36109
+ WriteUnauthorizedError,
36110
+ assertDerivedScopeNaming,
34747
36111
  assertValidPkceVerifier,
34748
36112
  authorizeEscrowPayment,
34749
36113
  authorizeGrantPayment,
36114
+ binaryWriteSignedBytes,
36115
+ buildDataPointDeletionSignature,
36116
+ buildDataPointDeletionTypedData,
34750
36117
  buildDepositNativeRequest,
34751
36118
  buildDepositTokenRequest,
34752
36119
  buildEscrowPaymentHeader,
@@ -34764,6 +36131,7 @@ export {
34764
36131
  clearContractCache,
34765
36132
  computeBodyHash,
34766
36133
  computePkceChallenge,
36134
+ computeTombstoneHash,
34767
36135
  contractCacheForTesting,
34768
36136
  createBrowserPlatformAdapter,
34769
36137
  createDataFileEnvelope,
@@ -34775,22 +36143,28 @@ export {
34775
36143
  createPlatformAdapterFor,
34776
36144
  createPlatformAdapterSafe,
34777
36145
  createVanaStorageProvider,
36146
+ createViemDataPointDeletionSigner,
34778
36147
  createViemPersonalServerLiteOwnerBindingSigner,
34779
36148
  createViemPersonalServerRegistrationSigner,
34780
36149
  dataRegistryContractAddress,
34781
36150
  dataRegistryDomain,
34782
36151
  decryptWithPassword,
36152
+ deleteDataPoint,
36153
+ deriveDataPointId,
34783
36154
  deriveMasterKey,
34784
36155
  deriveScopeKey,
36156
+ derivedScopeViolatesNaming,
34785
36157
  deserializeECIES,
34786
36158
  detectPlatform,
34787
36159
  encodeDepositNativeData,
34788
36160
  encodeDepositTokenData,
34789
36161
  encodeSetDataPointStatusData,
36162
+ encodeWriteMetadataHeader,
34790
36163
  encryptWithPassword,
34791
36164
  escrowContractAddress,
34792
36165
  escrowPaymentDomain,
34793
36166
  formatScopeEntry,
36167
+ gatewayLineagePath,
34794
36168
  generatePkceVerifier,
34795
36169
  genericPaymentDomain,
34796
36170
  getAbi,
@@ -34800,47 +36174,64 @@ export {
34800
36174
  getContractController,
34801
36175
  getContractInfo,
34802
36176
  getFee,
36177
+ getGatewayLineage,
36178
+ getLineage,
34803
36179
  getOpFee,
36180
+ getPersonalServerLineage,
34804
36181
  getPlatformCapabilities,
34805
36182
  getServiceEndpoints,
34806
36183
  grantPermissions,
34807
36184
  grantRegistrationDomain,
34808
36185
  grantRevocationDomain,
34809
36186
  hasAction,
36187
+ isDataPointId,
36188
+ isDataPointTombstone,
34810
36189
  isDataPortabilityGatewayConfig,
34811
36190
  isECIESEncrypted,
34812
36191
  isPlatformSupported,
36192
+ isRedactedLineageNode,
36193
+ isTombstoneHashes,
34813
36194
  mainnetServices,
34814
36195
  moksha,
34815
36196
  mokshaServices,
34816
36197
  mokshaTestnet2 as mokshaTestnet,
36198
+ normalizeBinaryMimeType,
36199
+ openWriteSession,
34817
36200
  parsePSError,
34818
36201
  parsePersonalServerPaymentRequired,
34819
36202
  parseScope,
34820
36203
  parseScopeEntry,
34821
36204
  parseWeb3SignedHeader,
36205
+ parseWriteMetadataHeader,
34822
36206
  paymentReceiptFromHeader,
34823
36207
  paymentResponseMetadataFromHeader,
34824
36208
  permissionsToScopes,
34825
36209
  personalServerDataReadPath,
36210
+ personalServerLineagePath,
34826
36211
  personalServerRegistrationDomain,
34827
36212
  readPersonalServerData,
34828
36213
  recoverServerOwner,
34829
36214
  registerPersonalServerSignature,
36215
+ resolveWriteSigner,
34830
36216
  scopeCoveredByGrant,
34831
36217
  scopeMatchesPattern,
36218
+ scopeNamespace,
34832
36219
  scopeToPathSegments,
34833
36220
  serializeECIES,
34834
36221
  serverRegistrationDomain,
36222
+ sessionCoversScope,
34835
36223
  signPersonalServerLiteOwnerBinding,
34836
36224
  signPersonalServerLiteOwnerBindingWithAccountClient,
34837
36225
  signPersonalServerRegistrationWithAccount,
34838
36226
  toDirectFeeBreakdown,
34839
36227
  toDirectPaymentReceipt,
36228
+ tombstoneDeletedAt,
34840
36229
  tryGrantPermissions,
34841
36230
  vanaMainnet2 as vanaMainnet,
34842
36231
  verifyGrantRegistration,
34843
36232
  verifyPkceChallenge,
34844
- verifyWeb3Signed
36233
+ verifyWeb3Signed,
36234
+ writeData,
36235
+ writePersonalServerData
34845
36236
  };
34846
36237
  //# sourceMappingURL=index.node.js.map