@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
@@ -1279,6 +1279,97 @@ var TransactionPendingError = class extends VanaError {
1279
1279
  };
1280
1280
  }
1281
1281
  };
1282
+ var PersonalServerWriteError = class extends VanaError {
1283
+ constructor(message, code, status, errorCode = null, details) {
1284
+ super(message, code);
1285
+ this.status = status;
1286
+ this.errorCode = errorCode;
1287
+ this.details = details;
1288
+ }
1289
+ status;
1290
+ errorCode;
1291
+ details;
1292
+ };
1293
+ var WriteRequestError = class extends PersonalServerWriteError {
1294
+ constructor(message, details) {
1295
+ super(message, "WRITE_INVALID_REQUEST", void 0, null, details);
1296
+ }
1297
+ };
1298
+ var WriteTransportError = class extends PersonalServerWriteError {
1299
+ constructor(message, attempts, cause) {
1300
+ super(message, "WRITE_TRANSPORT_ERROR", void 0, null, { attempts });
1301
+ this.attempts = attempts;
1302
+ this.cause = cause;
1303
+ }
1304
+ attempts;
1305
+ };
1306
+ var WriteSessionError = class extends PersonalServerWriteError {
1307
+ constructor(message, status, errorCode = null, details) {
1308
+ super(message, "WRITE_SESSION_REJECTED", status, errorCode, details);
1309
+ }
1310
+ };
1311
+ var WriteSessionExpiredError = class extends PersonalServerWriteError {
1312
+ constructor(message, details) {
1313
+ super(message, "WRITE_SESSION_EXPIRED", void 0, null, details);
1314
+ }
1315
+ };
1316
+ var WriteUnauthorizedError = class extends PersonalServerWriteError {
1317
+ constructor(message, errorCode = null, details) {
1318
+ super(message, "WRITE_UNAUTHORIZED", 401, errorCode, details);
1319
+ }
1320
+ };
1321
+ var WriteForbiddenError = class extends PersonalServerWriteError {
1322
+ constructor(message, errorCode = null, details) {
1323
+ super(message, "WRITE_FORBIDDEN", 403, errorCode, details);
1324
+ }
1325
+ };
1326
+ var WriteConflictError = class extends PersonalServerWriteError {
1327
+ constructor(message, errorCode = null, details) {
1328
+ super(message, "WRITE_CONFLICT", 409, errorCode, details);
1329
+ }
1330
+ };
1331
+ var WriteLineageError = class extends PersonalServerWriteError {
1332
+ constructor(message, status = 422, errorCode = null, details) {
1333
+ super(message, "WRITE_LINEAGE_REJECTED", status, errorCode, details);
1334
+ }
1335
+ };
1336
+ var WriteRejectedError = class extends PersonalServerWriteError {
1337
+ constructor(message, status, errorCode = null, details) {
1338
+ super(message, "WRITE_REJECTED", status, errorCode, details);
1339
+ }
1340
+ };
1341
+ var LineageReadError = class extends VanaError {
1342
+ constructor(message, status, errorCode = null, details) {
1343
+ super(message, "LINEAGE_READ_ERROR");
1344
+ this.status = status;
1345
+ this.errorCode = errorCode;
1346
+ this.details = details;
1347
+ }
1348
+ status;
1349
+ errorCode;
1350
+ details;
1351
+ };
1352
+ var DataPointDeletedError = class extends VanaError {
1353
+ constructor(message, details = {}) {
1354
+ super(message, "DATA_POINT_DELETED");
1355
+ this.details = details;
1356
+ }
1357
+ details;
1358
+ };
1359
+ var DataPointNotFoundError = class extends VanaError {
1360
+ constructor(message, details = {}) {
1361
+ super(message, "DATA_POINT_NOT_FOUND");
1362
+ this.details = details;
1363
+ }
1364
+ details;
1365
+ };
1366
+ var DataPointVersionConflictError = class extends VanaError {
1367
+ constructor(message, details = {}) {
1368
+ super(message, "DATA_POINT_VERSION_CONFLICT");
1369
+ this.details = details;
1370
+ }
1371
+ details;
1372
+ };
1282
1373
 
1283
1374
  // src/contracts/contractController.ts
1284
1375
  import {
@@ -29041,6 +29132,22 @@ function getProtocolNetworkChainId(network) {
29041
29132
  return PROTOCOL_NETWORK_CHAIN_IDS[network];
29042
29133
  }
29043
29134
 
29135
+ // src/utils/response-body.ts
29136
+ function isPlainObject(value) {
29137
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29138
+ }
29139
+ async function readJsonValue(res) {
29140
+ try {
29141
+ return await res.json();
29142
+ } catch {
29143
+ return null;
29144
+ }
29145
+ }
29146
+ async function readJsonObject(res) {
29147
+ const value = await readJsonValue(res);
29148
+ return isPlainObject(value) ? value : {};
29149
+ }
29150
+
29044
29151
  // src/storage/providers/vana-storage.ts
29045
29152
  var DEFAULT_ENDPOINT = "https://storage.vana.org";
29046
29153
  var LEGACY_BLOB_PATH_PREFIX = "/v1/blobs";
@@ -29212,6 +29319,65 @@ var VanaStorage = class {
29212
29319
  }
29213
29320
  return true;
29214
29321
  }
29322
+ /**
29323
+ * Delete every version's blob under `(owner, scope)` --
29324
+ * `DELETE {prefix}/{owner}/{scope}` on vana-storage, signed with the same
29325
+ * Web3Signed header as uploads (aud = endpoint origin, empty bodyHash).
29326
+ * The worker accepts the owner's own signature or a personal server the
29327
+ * owner registered with the gateway.
29328
+ *
29329
+ * @param ownerAddress - Must equal the provider's configured owner; a
29330
+ * mismatch throws before anything is signed so this wallet can never be
29331
+ * induced to sign a delete for another namespace.
29332
+ * @param scope - The scope segment, e.g. `"instagram.profile"`.
29333
+ */
29334
+ async deleteScope(ownerAddress, scope) {
29335
+ if (ownerAddress.toLowerCase() !== this.ownerAddress) {
29336
+ throw new StorageError(
29337
+ `deleteScope owner '${ownerAddress}' does not match the configured owner '${this.ownerAddress}'`,
29338
+ "INVALID_OWNER",
29339
+ "vana-storage"
29340
+ );
29341
+ }
29342
+ if (scope.length === 0 || scope.includes("/") || isTraversalSegment(scope)) {
29343
+ throw new StorageError(
29344
+ `scope must be a single non-empty path segment, got '${scope}'`,
29345
+ "INVALID_SCOPE",
29346
+ "vana-storage"
29347
+ );
29348
+ }
29349
+ const path = `${this.blobPathPrefix}/${this.ownerAddress}/${encodeURIComponent(scope)}`;
29350
+ const header = await this.signRequest("DELETE", path);
29351
+ let response;
29352
+ try {
29353
+ response = await this.fetchImpl(`${this.endpoint}${path}`, {
29354
+ method: "DELETE",
29355
+ headers: { authorization: header }
29356
+ });
29357
+ } catch (cause) {
29358
+ throw new StorageError(
29359
+ `vana-storage scope delete network error: ${describe(cause)}`,
29360
+ "DELETE_ERROR",
29361
+ "vana-storage",
29362
+ { cause: cause instanceof Error ? cause : void 0 }
29363
+ );
29364
+ }
29365
+ if (!response.ok) {
29366
+ const responseText = await safeText(response);
29367
+ throw new StorageError(
29368
+ `vana-storage scope delete failed: ${response.status} ${response.statusText} - ${responseText}`,
29369
+ "DELETE_FAILED",
29370
+ "vana-storage"
29371
+ );
29372
+ }
29373
+ const body = await readJsonObject(response);
29374
+ return {
29375
+ deleted: typeof body["deleted"] === "boolean" ? body["deleted"] : true,
29376
+ scope: typeof body["scope"] === "string" ? body["scope"] : scope,
29377
+ count: nonNegativeInteger(body["count"]) ?? 0,
29378
+ totalBytes: nonNegativeInteger(body["totalBytes"]) ?? 0
29379
+ };
29380
+ }
29215
29381
  getConfig() {
29216
29382
  return {
29217
29383
  name: "vana-storage",
@@ -29340,6 +29506,12 @@ function encodeRelativePath(filename) {
29340
29506
  }
29341
29507
  return parts.map((p) => encodeURIComponent(p)).join("/");
29342
29508
  }
29509
+ function isTraversalSegment(segment) {
29510
+ return segment === "." || segment === "..";
29511
+ }
29512
+ function nonNegativeInteger(value) {
29513
+ return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
29514
+ }
29343
29515
  function describe(value) {
29344
29516
  if (value instanceof Error) return value.message;
29345
29517
  return String(value);
@@ -32172,13 +32344,13 @@ function createViemPersonalServerRegistrationSigner(source, options = {}) {
32172
32344
  if (isPersonalServerRegistrationSigner(source)) {
32173
32345
  return source;
32174
32346
  }
32175
- const accountAddress = getAccountAddress(options.account) ?? getAccountAddress(source.account);
32176
- if (accountAddress) {
32347
+ const accountAddress2 = getAccountAddress(options.account) ?? getAccountAddress(source.account);
32348
+ if (accountAddress2) {
32177
32349
  return {
32178
- address: accountAddress,
32350
+ address: accountAddress2,
32179
32351
  signTypedData: (typedData) => source.signTypedData({
32180
32352
  ...typedData,
32181
- account: options.account ?? source.account ?? accountAddress
32353
+ account: options.account ?? source.account ?? accountAddress2
32182
32354
  })
32183
32355
  };
32184
32356
  }
@@ -32263,12 +32435,12 @@ function createViemPersonalServerLiteOwnerBindingSigner(source, options = {}) {
32263
32435
  if (isPersonalServerLiteOwnerBindingSigner(source)) {
32264
32436
  return source;
32265
32437
  }
32266
- const accountAddress = getAccountAddress2(options.account) ?? getAccountAddress2(source.account);
32267
- if (accountAddress) {
32438
+ const accountAddress2 = getAccountAddress2(options.account) ?? getAccountAddress2(source.account);
32439
+ if (accountAddress2) {
32268
32440
  return {
32269
- address: accountAddress,
32441
+ address: accountAddress2,
32270
32442
  signMessage: ({ message }) => source.signMessage({
32271
- account: options.account ?? source.account ?? accountAddress,
32443
+ account: options.account ?? source.account ?? accountAddress2,
32272
32444
  message
32273
32445
  })
32274
32446
  };
@@ -32835,15 +33007,494 @@ function buildMarkDataPointUnavailableRequest(config, input) {
32835
33007
  });
32836
33008
  }
32837
33009
 
32838
- // src/protocol/data-file.ts
33010
+ // src/protocol/data-point-deletion.ts
33011
+ import {
33012
+ isAddress as isAddress5,
33013
+ keccak256 as keccak2562,
33014
+ maxUint256,
33015
+ stringToBytes as stringToBytes3
33016
+ } from "viem";
33017
+
33018
+ // src/protocol/lineage.ts
33019
+ import {
33020
+ encodeAbiParameters,
33021
+ isAddress as isAddress4,
33022
+ keccak256
33023
+ } from "viem";
32839
33024
  import { z } from "zod";
32840
- var DataFileEnvelopeSchema = z.object({
32841
- $schema: z.string().url().optional(),
32842
- version: z.literal("1.0"),
33025
+
33026
+ // src/protocol/personal-server-error-body.ts
33027
+ function isRecord2(value) {
33028
+ return value !== null && typeof value === "object" && !Array.isArray(value);
33029
+ }
33030
+ async function readPersonalServerErrorBody(response) {
33031
+ let body;
33032
+ try {
33033
+ body = await response.json();
33034
+ } catch {
33035
+ return { errorCode: null, message: null };
33036
+ }
33037
+ if (!isRecord2(body)) return { errorCode: null, message: null };
33038
+ const nested = isRecord2(body.error) ? body.error : null;
33039
+ const gatewayShape = typeof body.error === "string" && typeof body.code === "string";
33040
+ const code = nested?.errorCode ?? nested?.code ?? body.errorCode ?? (gatewayShape ? body.code : void 0) ?? (typeof body.error === "string" ? body.error : void 0) ?? body.code;
33041
+ const message = nested?.message ?? body.message ?? (gatewayShape ? body.error : void 0);
33042
+ const gatewayDetails = {};
33043
+ for (const key of ["unknown", "scope", "sourceScope"]) {
33044
+ if (gatewayShape && body[key] !== void 0)
33045
+ gatewayDetails[key] = body[key];
33046
+ }
33047
+ const details = nested?.details ?? body.details ?? (Object.keys(gatewayDetails).length > 0 ? gatewayDetails : void 0);
33048
+ return {
33049
+ errorCode: typeof code === "string" ? code : null,
33050
+ message: typeof message === "string" ? message : null,
33051
+ ...isRecord2(details) ? { details } : {}
33052
+ };
33053
+ }
33054
+
33055
+ // src/protocol/write-signer.ts
33056
+ function isRecord3(value) {
33057
+ return value !== null && typeof value === "object";
33058
+ }
33059
+ function isViemWriteAccount(source) {
33060
+ return isRecord3(source) && source.type === "local" && typeof source.address === "string" && typeof source.signMessage === "function";
33061
+ }
33062
+ function isViemWriteWalletClient(source) {
33063
+ return isRecord3(source) && typeof source.signMessage === "function" && source.type !== "local" && (source.type === "walletClient" || "transport" in source);
33064
+ }
33065
+ function accountAddress(account) {
33066
+ return typeof account === "string" ? account : account.address;
33067
+ }
33068
+ function resolveWriteSigner(source, options = {}) {
33069
+ if (isViemWriteWalletClient(source)) {
33070
+ const account = options.account ?? source.account;
33071
+ if (account === void 0) {
33072
+ throw new WriteRequestError(
33073
+ "Viem wallet client requires an account option or account property"
33074
+ );
33075
+ }
33076
+ return {
33077
+ address: accountAddress(account),
33078
+ signMessage: (message) => source.signMessage({ account, message })
33079
+ };
33080
+ }
33081
+ if (isViemWriteAccount(source)) {
33082
+ return {
33083
+ address: source.address,
33084
+ signMessage: (message) => source.signMessage({ message })
33085
+ };
33086
+ }
33087
+ if (!isRecord3(source) || typeof source.signMessage !== "function") {
33088
+ throw new WriteRequestError(
33089
+ "signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
33090
+ );
33091
+ }
33092
+ return source;
33093
+ }
33094
+
33095
+ // src/protocol/lineage.ts
33096
+ var DATA_POINT_ID_PATTERN = /^0x[0-9a-fA-F]{64}$/;
33097
+ function isDataPointId(value) {
33098
+ return typeof value === "string" && DATA_POINT_ID_PATTERN.test(value);
33099
+ }
33100
+ function deriveDataPointId(ownerAddress, scope) {
33101
+ if (!isAddress4(ownerAddress, { strict: false })) {
33102
+ throw new Error(
33103
+ `ownerAddress is not an EVM address: ${String(ownerAddress)}`
33104
+ );
33105
+ }
33106
+ return keccak256(
33107
+ encodeAbiParameters(
33108
+ [
33109
+ { name: "ownerAddress", type: "address" },
33110
+ { name: "scope", type: "string" }
33111
+ ],
33112
+ [ownerAddress, scope]
33113
+ )
33114
+ );
33115
+ }
33116
+ var DataPointIdSchema = z.string().regex(DATA_POINT_ID_PATTERN).transform((value) => value.toLowerCase());
33117
+ var VERSION_PATTERN = /^[1-9]\d*$/;
33118
+ var NODE_VERSION_PATTERN = /^(0|[1-9]\d*)$/;
33119
+ var VersionSchema = z.union([z.string(), z.number()]).transform(String).refine((value) => NODE_VERSION_PATTERN.test(value), {
33120
+ message: "version must be a decimal integer"
33121
+ });
33122
+ var ViewVersionSchema = VersionSchema.refine(
33123
+ (value) => VERSION_PATTERN.test(value),
33124
+ { message: "version must be a positive decimal integer" }
33125
+ );
33126
+ function scopeNamespace(scope) {
33127
+ const dot = scope.indexOf(".");
33128
+ return dot === -1 ? scope : scope.slice(0, dot);
33129
+ }
33130
+ function derivedScopeViolatesNaming(derivedScope, sourceScope) {
33131
+ return scopeNamespace(derivedScope) === scopeNamespace(sourceScope);
33132
+ }
33133
+ function assertDerivedScopeNaming(derivedScope, sourceScopes) {
33134
+ for (const sourceScope of sourceScopes) {
33135
+ if (derivedScopeViolatesNaming(derivedScope, sourceScope)) {
33136
+ throw new WriteRequestError(
33137
+ `Derived scope ${derivedScope} must not share its first segment with source scope ${sourceScope}; put derivatives in the app's own namespace`,
33138
+ { scope: derivedScope, sourceScope }
33139
+ );
33140
+ }
33141
+ }
33142
+ }
33143
+ var LineageNodeSchema = z.object({
33144
+ dataPointId: DataPointIdSchema,
32843
33145
  scope: z.string(),
32844
- schemaId: z.string().optional(),
32845
- collectedAt: z.string().datetime(),
32846
- data: z.record(z.string(), z.unknown())
33146
+ /**
33147
+ * The node's current version, decimal string; `"0"` for a source that no
33148
+ * longer resolves to a registered data point.
33149
+ */
33150
+ version: VersionSchema,
33151
+ /** The node's tombstone time, or `null` when live. */
33152
+ deletedAt: z.string().nullable()
33153
+ });
33154
+ var RedactedLineageNodeSchema = z.object({
33155
+ dataPointId: DataPointIdSchema,
33156
+ redacted: z.literal(true)
33157
+ });
33158
+ var LineageEntrySchema = z.union([
33159
+ RedactedLineageNodeSchema,
33160
+ LineageNodeSchema
33161
+ ]);
33162
+ var LineageGraphSchema = z.object({
33163
+ dataPointId: DataPointIdSchema,
33164
+ /** The data point owner; every node in the view belongs to it. */
33165
+ ownerAddress: z.string().optional(),
33166
+ scope: z.string(),
33167
+ /**
33168
+ * The derived record's version whose lineage is shown: the requested one,
33169
+ * else the current one, else (current is a tombstone) the last version
33170
+ * that carried lineage.
33171
+ */
33172
+ version: ViewVersionSchema,
33173
+ deletedAt: z.string().nullable(),
33174
+ sources: z.array(LineageEntrySchema),
33175
+ derivatives: z.array(LineageEntrySchema),
33176
+ /** `true` when `derivatives` was cut at the server's cap (1000). */
33177
+ derivativesTruncated: z.boolean().optional()
33178
+ });
33179
+ function isRedactedLineageNode(entry) {
33180
+ return "redacted" in entry && entry.redacted === true;
33181
+ }
33182
+ function personalServerLineagePath(scope, version) {
33183
+ return `/v1/data/${encodeURIComponent(scope)}/lineage${version === void 0 ? "" : `/${String(version)}`}`;
33184
+ }
33185
+ function gatewayLineagePath(dataPointId, version) {
33186
+ return `/v1/data/${dataPointId.toLowerCase()}/lineage${version === void 0 ? "" : `/${String(version)}`}`;
33187
+ }
33188
+ function normalizeBaseUrl(url) {
33189
+ return url.replace(/\/+$/, "");
33190
+ }
33191
+ function resolveFetch(fetchFn) {
33192
+ const resolved = fetchFn ?? globalThis.fetch;
33193
+ if (resolved === void 0) {
33194
+ throw new LineageReadError("No fetch implementation available");
33195
+ }
33196
+ return resolved;
33197
+ }
33198
+ function normalizeVersion(version) {
33199
+ if (version === void 0) return void 0;
33200
+ const text = String(version);
33201
+ if (!VERSION_PATTERN.test(text)) {
33202
+ throw new LineageReadError(
33203
+ "version must be a positive decimal integer",
33204
+ void 0,
33205
+ "INVALID_VERSION",
33206
+ { version }
33207
+ );
33208
+ }
33209
+ return text;
33210
+ }
33211
+ async function lineageReadFailure(source, response) {
33212
+ const { errorCode, message, details } = await readPersonalServerErrorBody(response);
33213
+ return new LineageReadError(
33214
+ message ?? `${source} lineage read failed: ${response.status} ${response.statusText}`,
33215
+ response.status,
33216
+ errorCode,
33217
+ details
33218
+ );
33219
+ }
33220
+ async function parseLineageGraph(source, response) {
33221
+ let body;
33222
+ try {
33223
+ body = await response.json();
33224
+ } catch (err) {
33225
+ throw new LineageReadError(
33226
+ `${source} lineage response is not JSON`,
33227
+ response.status,
33228
+ null,
33229
+ { cause: err instanceof Error ? err.message : String(err) }
33230
+ );
33231
+ }
33232
+ const envelope = isRecord2(body) && isRecord2(body.data) ? body : void 0;
33233
+ const parsed = LineageGraphSchema.safeParse(envelope?.data ?? body);
33234
+ if (!parsed.success) {
33235
+ throw new LineageReadError(
33236
+ `${source} lineage response is not a lineage view`,
33237
+ response.status,
33238
+ null,
33239
+ { issues: parsed.error.issues }
33240
+ );
33241
+ }
33242
+ const proof = isRecord2(envelope?.proof) ? envelope.proof : void 0;
33243
+ return proof === void 0 ? parsed.data : { ...parsed.data, proof };
33244
+ }
33245
+ async function sendLineageRead(source, fetchFn, url, headers) {
33246
+ let response;
33247
+ try {
33248
+ response = await fetchFn(url, { method: "GET", headers });
33249
+ } catch (err) {
33250
+ throw new LineageReadError(
33251
+ `${source} lineage read failed: ${err instanceof Error ? err.message : String(err)}`,
33252
+ void 0,
33253
+ null,
33254
+ { cause: err instanceof Error ? err.message : String(err) }
33255
+ );
33256
+ }
33257
+ if (!response.ok) {
33258
+ throw await lineageReadFailure(source, response);
33259
+ }
33260
+ return parseLineageGraph(source, response);
33261
+ }
33262
+ async function getPersonalServerLineage(params) {
33263
+ const fetchFn = resolveFetch(params.fetch);
33264
+ const baseUrl = normalizeBaseUrl(params.personalServerUrl);
33265
+ const audience = params.audience ?? baseUrl;
33266
+ const signer = resolveWriteSigner(params.signer, { account: params.account });
33267
+ const path = personalServerLineagePath(
33268
+ params.scope,
33269
+ normalizeVersion(params.version)
33270
+ );
33271
+ const headers = new Headers(params.headers);
33272
+ headers.set(
33273
+ "Authorization",
33274
+ await buildWeb3SignedHeader({
33275
+ signMessage: signer.signMessage,
33276
+ aud: audience,
33277
+ method: "GET",
33278
+ uri: path,
33279
+ grantId: params.grantId
33280
+ })
33281
+ );
33282
+ return sendLineageRead(
33283
+ "Personal Server",
33284
+ fetchFn,
33285
+ `${baseUrl}${path}`,
33286
+ headers
33287
+ );
33288
+ }
33289
+ async function getGatewayLineage(params) {
33290
+ if (!isDataPointId(params.dataPointId)) {
33291
+ throw new LineageReadError(
33292
+ "dataPointId must be a 32-byte hex string (see deriveDataPointId)",
33293
+ void 0,
33294
+ "INVALID_DATA_POINT_ID",
33295
+ { dataPointId: params.dataPointId }
33296
+ );
33297
+ }
33298
+ const fetchFn = resolveFetch(params.fetch);
33299
+ const baseUrl = normalizeBaseUrl(params.gatewayUrl);
33300
+ const signer = resolveWriteSigner(params.signer, { account: params.account });
33301
+ const uri = gatewayLineagePath(
33302
+ params.dataPointId,
33303
+ normalizeVersion(params.version)
33304
+ );
33305
+ const headers = new Headers(params.headers);
33306
+ headers.set(
33307
+ "Authorization",
33308
+ await buildWeb3SignedHeader({
33309
+ signMessage: signer.signMessage,
33310
+ aud: baseUrl,
33311
+ method: "GET",
33312
+ uri,
33313
+ grantId: params.grantId?.toLowerCase()
33314
+ })
33315
+ );
33316
+ return sendLineageRead("Gateway", fetchFn, `${baseUrl}${uri}`, headers);
33317
+ }
33318
+ function getLineage(params) {
33319
+ return "personalServerUrl" in params ? getPersonalServerLineage(params) : getGatewayLineage(params);
33320
+ }
33321
+
33322
+ // src/protocol/data-point-deletion.ts
33323
+ var TOMBSTONE_DATA_HASH_PREIMAGE = "vana.data-point.tombstone.v1";
33324
+ var TOMBSTONE_METADATA_HASH_PREIMAGE = "vana.data-point.tombstone.metadata.v1";
33325
+ var TOMBSTONE_DATA_HASH = "0x30c45ee72fe56d1927701316925ab7ceacd3b6f9267061735d59396f075c6222";
33326
+ var TOMBSTONE_METADATA_HASH = "0xc5255a141acd6a2ae55971b62c0a85977c2511989dc114ad2abc2b7644f57d90";
33327
+ function computeTombstoneHash(preimage) {
33328
+ return keccak2562(stringToBytes3(preimage));
33329
+ }
33330
+ function isTombstoneHashes(dataHash, metadataHash) {
33331
+ return typeof dataHash === "string" && typeof metadataHash === "string" && dataHash.toLowerCase() === TOMBSTONE_DATA_HASH && metadataHash.toLowerCase() === TOMBSTONE_METADATA_HASH;
33332
+ }
33333
+ function isDataPointTombstone(value) {
33334
+ if (!isPlainObject(value)) return false;
33335
+ if (typeof value["deletedAt"] === "string") return true;
33336
+ return isTombstoneHashes(
33337
+ typeof value["dataHash"] === "string" ? value["dataHash"] : void 0,
33338
+ typeof value["metadataHash"] === "string" ? value["metadataHash"] : void 0
33339
+ );
33340
+ }
33341
+ function tombstoneDeletedAt(value) {
33342
+ if (!isPlainObject(value)) return null;
33343
+ const deletedAt = value["deletedAt"];
33344
+ return typeof deletedAt === "string" ? deletedAt : null;
33345
+ }
33346
+ function assertAddress4(value, name) {
33347
+ if (!isAddress5(value)) {
33348
+ throw new Error(`${name} must be a valid EVM address`);
33349
+ }
33350
+ }
33351
+ function assertUint256(value, name) {
33352
+ if (value < 0n || value > maxUint256) {
33353
+ throw new Error(`${name} must fit in uint256, got ${value}`);
33354
+ }
33355
+ }
33356
+ function getAccountAddress3(account) {
33357
+ if (!account) return void 0;
33358
+ return typeof account === "string" ? account : account.address;
33359
+ }
33360
+ function isDataPointDeletionSigner(source) {
33361
+ return "address" in source && typeof source.signTypedData === "function";
33362
+ }
33363
+ function createViemDataPointDeletionSigner(source, options = {}) {
33364
+ if (isDataPointDeletionSigner(source)) {
33365
+ return source;
33366
+ }
33367
+ const accountAddress2 = getAccountAddress3(options.account) ?? getAccountAddress3(source.account);
33368
+ if (accountAddress2) {
33369
+ return {
33370
+ address: accountAddress2,
33371
+ signTypedData: (typedData) => source.signTypedData({
33372
+ ...typedData,
33373
+ account: options.account ?? source.account ?? accountAddress2
33374
+ })
33375
+ };
33376
+ }
33377
+ throw new Error(
33378
+ "Viem wallet client requires an account option or account property"
33379
+ );
33380
+ }
33381
+ function buildDataPointDeletionTypedData(input) {
33382
+ assertAddress4(input.ownerAddress, "ownerAddress");
33383
+ if (input.scope.length === 0) {
33384
+ throw new Error("scope must be a non-empty string");
33385
+ }
33386
+ if (input.expectedVersion <= 0n) {
33387
+ throw new Error("expectedVersion must be a positive version number");
33388
+ }
33389
+ assertUint256(input.expectedVersion, "expectedVersion");
33390
+ return {
33391
+ domain: dataRegistryDomain(input.config),
33392
+ types: ADD_DATA_TYPES,
33393
+ primaryType: "AddData",
33394
+ message: {
33395
+ ownerAddress: input.ownerAddress,
33396
+ scope: input.scope,
33397
+ dataHash: TOMBSTONE_DATA_HASH,
33398
+ metadataHash: TOMBSTONE_METADATA_HASH,
33399
+ expectedVersion: input.expectedVersion
33400
+ }
33401
+ };
33402
+ }
33403
+ async function buildDataPointDeletionSignature(input) {
33404
+ const typedData = buildDataPointDeletionTypedData({
33405
+ ownerAddress: input.signer.address,
33406
+ scope: input.scope,
33407
+ expectedVersion: input.expectedVersion,
33408
+ config: input.config
33409
+ });
33410
+ const signature = await input.signer.signTypedData(typedData);
33411
+ return {
33412
+ signature,
33413
+ signerAddress: input.signer.address,
33414
+ typedData
33415
+ };
33416
+ }
33417
+ function toError(value) {
33418
+ return value instanceof Error ? value : new Error(String(value));
33419
+ }
33420
+ function parseExpectedVersion(value) {
33421
+ if (typeof value !== "string" || !/^\d+$/.test(value)) {
33422
+ throw new Error(
33423
+ `Gateway returned a malformed expectedVersion: ${JSON.stringify(value)}`
33424
+ );
33425
+ }
33426
+ const parsed = BigInt(value);
33427
+ assertUint256(parsed, "Gateway expectedVersion");
33428
+ return parsed;
33429
+ }
33430
+ async function deleteDataPoint(input) {
33431
+ const ownerAddress = input.signer.address;
33432
+ const dataPointId = deriveDataPointId(ownerAddress, input.scope);
33433
+ let currentVersion = input.currentVersion;
33434
+ if (currentVersion === void 0) {
33435
+ const record = await input.gateway.getDataPoint(dataPointId);
33436
+ if (record === null) {
33437
+ throw new DataPointNotFoundError(
33438
+ `No data point registered for scope '${input.scope}' owned by ${ownerAddress}`,
33439
+ { dataPointId, scope: input.scope, ownerAddress }
33440
+ );
33441
+ }
33442
+ if (isDataPointTombstone(record)) {
33443
+ throw new DataPointDeletedError(
33444
+ `Data point ${dataPointId} (scope '${input.scope}') is already deleted`,
33445
+ {
33446
+ dataPointId,
33447
+ scope: input.scope,
33448
+ ownerAddress,
33449
+ deletedAt: tombstoneDeletedAt(record)
33450
+ }
33451
+ );
33452
+ }
33453
+ currentVersion = parseExpectedVersion(record.expectedVersion);
33454
+ }
33455
+ if (currentVersion < 0n || currentVersion >= maxUint256) {
33456
+ throw new Error(
33457
+ `currentVersion ${currentVersion} cannot be incremented to a uint256 tombstone version`
33458
+ );
33459
+ }
33460
+ const tombstoneVersion = currentVersion + 1n;
33461
+ const signed = await buildDataPointDeletionSignature({
33462
+ signer: input.signer,
33463
+ scope: input.scope,
33464
+ expectedVersion: tombstoneVersion,
33465
+ config: input.config
33466
+ });
33467
+ const tombstone = await input.gateway.deleteDataPoint({
33468
+ ownerAddress,
33469
+ scope: input.scope,
33470
+ expectedVersion: tombstoneVersion.toString(),
33471
+ signature: signed.signature
33472
+ });
33473
+ const base = {
33474
+ dataPointId,
33475
+ ownerAddress,
33476
+ scope: input.scope,
33477
+ version: tombstoneVersion.toString(),
33478
+ signature: signed.signature,
33479
+ tombstone
33480
+ };
33481
+ try {
33482
+ const storage = await input.storage.deleteScope(ownerAddress, input.scope);
33483
+ return { ...base, status: "deleted", storage };
33484
+ } catch (cause) {
33485
+ return { ...base, status: "partial", storageError: toError(cause) };
33486
+ }
33487
+ }
33488
+
33489
+ // src/protocol/data-file.ts
33490
+ import { z as z2 } from "zod";
33491
+ var DataFileEnvelopeSchema = z2.object({
33492
+ $schema: z2.string().url().optional(),
33493
+ version: z2.literal("1.0"),
33494
+ scope: z2.string(),
33495
+ schemaId: z2.string().optional(),
33496
+ collectedAt: z2.string().datetime(),
33497
+ data: z2.record(z2.string(), z2.unknown())
32847
33498
  });
32848
33499
  function createDataFileEnvelope(scope, collectedAt, data, schemaUrl, schemaId) {
32849
33500
  return {
@@ -32855,10 +33506,10 @@ function createDataFileEnvelope(scope, collectedAt, data, schemaUrl, schemaId) {
32855
33506
  data
32856
33507
  };
32857
33508
  }
32858
- var IngestResponseSchema = z.object({
32859
- scope: z.string(),
32860
- collectedAt: z.string().datetime(),
32861
- status: z.enum(["stored", "syncing"])
33509
+ var IngestResponseSchema = z2.object({
33510
+ scope: z2.string(),
33511
+ collectedAt: z2.string().datetime(),
33512
+ status: z2.enum(["stored", "syncing"])
32862
33513
  });
32863
33514
 
32864
33515
  // src/protocol/personal-server-data.ts
@@ -32892,19 +33543,35 @@ async function readPersonalServerData(params) {
32892
33543
  }
32893
33544
  const request = await buildPersonalServerDataReadRequest(params);
32894
33545
  const response = await fetchFn(request);
33546
+ if (response.status === 410) {
33547
+ throw new DataPointDeletedError(
33548
+ `Personal Server scope '${params.scope}' has been deleted`,
33549
+ {
33550
+ scope: params.scope,
33551
+ deletedAt: tombstoneDeletedAt(await readJsonValue(response))
33552
+ }
33553
+ );
33554
+ }
32895
33555
  if (!response.ok) {
32896
33556
  throw new Error(
32897
33557
  `Personal Server data read failed: ${response.status} ${response.statusText}`
32898
33558
  );
32899
33559
  }
32900
- return DataFileEnvelopeSchema.parse(await response.json());
33560
+ const body = await response.json();
33561
+ if (isDataPointTombstone(body)) {
33562
+ throw new DataPointDeletedError(
33563
+ `Personal Server scope '${params.scope}' has been deleted`,
33564
+ { scope: params.scope, deletedAt: tombstoneDeletedAt(body) }
33565
+ );
33566
+ }
33567
+ return DataFileEnvelopeSchema.parse(body);
32901
33568
  }
32902
33569
 
32903
33570
  // src/protocol/scopes.ts
32904
- import { z as z2 } from "zod";
33571
+ import { z as z3 } from "zod";
32905
33572
  var SOURCE_RE = /^[a-z0-9][a-z0-9_]*$/;
32906
33573
  var TAIL_SEGMENT_RE = /^[a-zA-Z0-9][a-zA-Z0-9_]*$/;
32907
- var ScopeSchema = z2.string().refine(
33574
+ var ScopeSchema = z3.string().refine(
32908
33575
  (scope) => {
32909
33576
  const parts = scope.split(".");
32910
33577
  if (parts.length < 2 || parts.length > 3) return false;
@@ -33091,6 +33758,561 @@ function tryGrantPermissions(scopes) {
33091
33758
  }
33092
33759
  }
33093
33760
 
33761
+ // src/protocol/personal-server-write.ts
33762
+ import { sha256 as sha2565 } from "@noble/hashes/sha2";
33763
+ import { bytesToHex as bytesToHex2, isAddress as isAddress6 } from "viem";
33764
+ import { z as z4 } from "zod";
33765
+ var WRITE_SESSION_PATH = "/v1/write/session";
33766
+ var WRITE_SIGNATURE_HEADER = "X-Vana-Write-Signature";
33767
+ var WRITE_METADATA_HEADER = "X-Vana-Metadata";
33768
+ var LINEAGE_FIELD = "lineage";
33769
+ var MAX_LINEAGE_SOURCES = 256;
33770
+ var WRITE_FILENAME_HEADER = "X-Filename";
33771
+ var WRITE_CONTENT_DISPOSITION_HEADER = "Content-Disposition";
33772
+ var WRITER_ATTRIBUTION_KEY = "$writtenBy";
33773
+ var LINEAGE_KEY = "$lineage";
33774
+ var RESERVED_WRITE_KEYS = [
33775
+ WRITER_ATTRIBUTION_KEY,
33776
+ LINEAGE_KEY
33777
+ ];
33778
+ var WriteDataResultSchema = IngestResponseSchema.extend({
33779
+ // Present when the write carried lineage: the validated, lowercased ids.
33780
+ lineage: z4.object({ sources: z4.array(z4.string()) }).optional()
33781
+ });
33782
+ var WriteSessionResponseSchema = z4.object({
33783
+ access_token: z4.string().min(1),
33784
+ token_type: z4.string(),
33785
+ expires_in: z4.number().nonnegative(),
33786
+ scope: z4.string()
33787
+ });
33788
+ function normalizeBaseUrl2(url) {
33789
+ return url.replace(/\/+$/, "");
33790
+ }
33791
+ function resolveFetch2(fetchFn) {
33792
+ const resolved = fetchFn ?? globalThis.fetch;
33793
+ if (resolved === void 0) {
33794
+ throw new WriteRequestError("No fetch implementation available");
33795
+ }
33796
+ return resolved;
33797
+ }
33798
+ function dataPath(scope) {
33799
+ return `/v1/data/${encodeURIComponent(scope)}`;
33800
+ }
33801
+ function errorMessage(err) {
33802
+ return err instanceof Error ? err.message : String(err);
33803
+ }
33804
+ function finiteOr(value, fallback) {
33805
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
33806
+ }
33807
+ function sleep2(ms) {
33808
+ return new Promise((resolve) => setTimeout(resolve, ms));
33809
+ }
33810
+ var issuedProofIats = /* @__PURE__ */ new Map();
33811
+ var issuedProofBuckets = /* @__PURE__ */ new Map();
33812
+ var issuedProofIatsPrunedAtSec = 0;
33813
+ var WEB3_SIGNED_PROOF_LIFETIME_SECONDS = 300;
33814
+ var WEB3_SIGNED_CLOCK_SKEW_SECONDS = 60;
33815
+ var PROOF_IAT_RETENTION_SECONDS = WEB3_SIGNED_PROOF_LIFETIME_SECONDS + WEB3_SIGNED_CLOCK_SKEW_SECONDS;
33816
+ var PROOF_IAT_MAX_AHEAD_SECONDS = 30;
33817
+ function pruneIssuedProofIats(nowSec) {
33818
+ if (issuedProofIatsPrunedAtSec === nowSec) return;
33819
+ issuedProofIatsPrunedAtSec = nowSec;
33820
+ const cutoff = nowSec - PROOF_IAT_RETENTION_SECONDS;
33821
+ for (const [sec, keys] of issuedProofBuckets) {
33822
+ if (sec >= cutoff) continue;
33823
+ for (const key of keys) issuedProofIats.delete(key);
33824
+ issuedProofBuckets.delete(sec);
33825
+ }
33826
+ }
33827
+ function setIssuedProofIat(key, iat, previous) {
33828
+ if (previous !== void 0) {
33829
+ const bucket2 = issuedProofBuckets.get(previous);
33830
+ bucket2?.delete(key);
33831
+ if (bucket2?.size === 0) issuedProofBuckets.delete(previous);
33832
+ }
33833
+ issuedProofIats.set(key, iat);
33834
+ let bucket = issuedProofBuckets.get(iat);
33835
+ if (bucket === void 0) {
33836
+ bucket = /* @__PURE__ */ new Set();
33837
+ issuedProofBuckets.set(iat, bucket);
33838
+ }
33839
+ bucket.add(key);
33840
+ }
33841
+ function nextProofIat(proofKey) {
33842
+ const nowSec = Math.floor(Date.now() / 1e3);
33843
+ pruneIssuedProofIats(nowSec);
33844
+ const last = issuedProofIats.get(proofKey);
33845
+ const iat = last === void 0 ? nowSec : Math.max(nowSec, last + 1);
33846
+ setIssuedProofIat(proofKey, iat, last);
33847
+ const waitSec = iat - nowSec - PROOF_IAT_MAX_AHEAD_SECONDS;
33848
+ if (waitSec <= 0) return Promise.resolve(iat);
33849
+ return sleep2(waitSec * 1e3).then(() => iat);
33850
+ }
33851
+ function proofKeyFor(parts) {
33852
+ return bytesToHex2(
33853
+ sha2565(
33854
+ new TextEncoder().encode(
33855
+ JSON.stringify([
33856
+ parts.aud,
33857
+ parts.method,
33858
+ parts.uri,
33859
+ parts.grantId,
33860
+ parts.signedBytes ? bytesToHex2(sha2565(parts.signedBytes)) : ""
33861
+ ])
33862
+ )
33863
+ )
33864
+ );
33865
+ }
33866
+ async function sendWithFreshProof(label, fetchFn, options, proofKey, build) {
33867
+ const attempts = Math.max(1, Math.floor(finiteOr(options?.attempts, 3)));
33868
+ let delayMs = Math.max(0, finiteOr(options?.initialDelayMs, 1e3));
33869
+ let lastError;
33870
+ for (let attempt = 0; attempt < attempts; attempt++) {
33871
+ const { url, init } = await build(await nextProofIat(proofKey));
33872
+ try {
33873
+ return await fetchFn(url, init);
33874
+ } catch (err) {
33875
+ lastError = err;
33876
+ }
33877
+ if (attempt < attempts - 1) {
33878
+ await sleep2(delayMs);
33879
+ delayMs *= 2;
33880
+ }
33881
+ }
33882
+ throw new WriteTransportError(
33883
+ `${label} failed after ${attempts} attempt(s): ${errorMessage(lastError)}`,
33884
+ attempts,
33885
+ lastError
33886
+ );
33887
+ }
33888
+ async function openWriteSession(params) {
33889
+ const fetchFn = resolveFetch2(params.fetch);
33890
+ const personalServerUrl = normalizeBaseUrl2(params.personalServerUrl);
33891
+ const audience = params.audience ?? personalServerUrl;
33892
+ const signer = resolveWriteSigner(params.signer, { account: params.account });
33893
+ const response = await sendWithFreshProof(
33894
+ "Write session handshake",
33895
+ fetchFn,
33896
+ params.retry,
33897
+ proofKeyFor({
33898
+ aud: audience,
33899
+ method: "POST",
33900
+ uri: WRITE_SESSION_PATH,
33901
+ grantId: params.grantId
33902
+ }),
33903
+ async (iat) => {
33904
+ const headers = new Headers(params.headers);
33905
+ headers.set(
33906
+ "Authorization",
33907
+ await buildWeb3SignedHeader({
33908
+ signMessage: signer.signMessage,
33909
+ aud: audience,
33910
+ method: "POST",
33911
+ uri: WRITE_SESSION_PATH,
33912
+ grantId: params.grantId,
33913
+ iat
33914
+ })
33915
+ );
33916
+ return {
33917
+ url: `${personalServerUrl}${WRITE_SESSION_PATH}`,
33918
+ init: { method: "POST", headers }
33919
+ };
33920
+ }
33921
+ );
33922
+ const mintedAt = Date.now();
33923
+ if (!response.ok) {
33924
+ const { errorCode, message, details } = await readPersonalServerErrorBody(response);
33925
+ throw new WriteSessionError(
33926
+ message ?? `Write session handshake failed: ${response.status} ${response.statusText}`,
33927
+ response.status,
33928
+ errorCode,
33929
+ details
33930
+ );
33931
+ }
33932
+ let body;
33933
+ try {
33934
+ body = await response.json();
33935
+ } catch (err) {
33936
+ throw new WriteSessionError(
33937
+ "Write session response is not JSON",
33938
+ response.status,
33939
+ null,
33940
+ { cause: errorMessage(err) }
33941
+ );
33942
+ }
33943
+ const parsed = WriteSessionResponseSchema.safeParse(body);
33944
+ if (!parsed.success) {
33945
+ throw new WriteSessionError(
33946
+ "Write session response is not a session",
33947
+ response.status,
33948
+ null,
33949
+ { issues: parsed.error.issues }
33950
+ );
33951
+ }
33952
+ if (parsed.data.token_type.toLowerCase() !== "bearer") {
33953
+ throw new WriteSessionError(
33954
+ `Write session token type is not Bearer: ${parsed.data.token_type}`,
33955
+ response.status
33956
+ );
33957
+ }
33958
+ return {
33959
+ personalServerUrl,
33960
+ audience,
33961
+ grantId: params.grantId,
33962
+ accessToken: parsed.data.access_token,
33963
+ expiresAt: mintedAt + parsed.data.expires_in * 1e3,
33964
+ writeScopes: parsed.data.scope.split(" ").filter((s) => s.length > 0),
33965
+ signer
33966
+ };
33967
+ }
33968
+ function isWriteSession(value) {
33969
+ if (!isRecord2(value)) return false;
33970
+ const signer = value.signer;
33971
+ 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";
33972
+ }
33973
+ function sessionCoversScope(session, scope) {
33974
+ if (!isRecord2(session) || !Array.isArray(session.writeScopes) || !session.writeScopes.every((pattern) => typeof pattern === "string")) {
33975
+ throw new WriteRequestError("session must come from openWriteSession");
33976
+ }
33977
+ return session.writeScopes.some(
33978
+ (pattern) => scopeMatchesPattern(scope, pattern)
33979
+ );
33980
+ }
33981
+ function normalizeBinaryMimeType(contentType) {
33982
+ if (!contentType) return "application/octet-stream";
33983
+ return contentType.split(";")[0].trim() || "application/octet-stream";
33984
+ }
33985
+ function parseWriteMetadataHeader(value) {
33986
+ if (value === null) return void 0;
33987
+ const trimmed = value.trim();
33988
+ if (trimmed === "") return void 0;
33989
+ try {
33990
+ return JSON.parse(trimmed);
33991
+ } catch {
33992
+ return value;
33993
+ }
33994
+ }
33995
+ function encodeWriteMetadataHeader(metadata) {
33996
+ let json;
33997
+ try {
33998
+ json = JSON.stringify(metadata);
33999
+ } catch (err) {
34000
+ throw new WriteRequestError(
34001
+ `metadata is not JSON-serialisable: ${errorMessage(err)}`
34002
+ );
34003
+ }
34004
+ if (typeof json !== "string") {
34005
+ throw new WriteRequestError("metadata must serialise to JSON");
34006
+ }
34007
+ return json.replace(
34008
+ /[\u007f-\uffff]/g,
34009
+ (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`
34010
+ );
34011
+ }
34012
+ function binaryWriteSignedBytes(input) {
34013
+ const metadata = parseWriteMetadataHeader(input.metadataHeader ?? null);
34014
+ const record = {
34015
+ $binary: true,
34016
+ mimeType: normalizeBinaryMimeType(input.contentType),
34017
+ ...input.filename ? { filename: input.filename } : {},
34018
+ sizeBytes: input.bytes.length,
34019
+ contentHash: bytesToHex2(sha2565(input.bytes)),
34020
+ encoding: "base64",
34021
+ content: toBase64(input.bytes),
34022
+ ...metadata !== void 0 ? { metadata } : {}
34023
+ };
34024
+ return new TextEncoder().encode(JSON.stringify(record));
34025
+ }
34026
+ var PRINTABLE_ASCII = /^[\x20-\x7e]*$/;
34027
+ function setFilenameHeader(headers, filename) {
34028
+ if (PRINTABLE_ASCII.test(filename)) {
34029
+ headers.set(WRITE_FILENAME_HEADER, filename);
34030
+ return;
34031
+ }
34032
+ headers.set(
34033
+ WRITE_CONTENT_DISPOSITION_HEADER,
34034
+ `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`
34035
+ );
34036
+ }
34037
+ function assertNoReservedKeys(value, where) {
34038
+ for (const key of RESERVED_WRITE_KEYS) {
34039
+ if (Object.prototype.hasOwnProperty.call(value, key)) {
34040
+ throw new WriteRequestError(
34041
+ `${where} must not contain the reserved ${key} key; the Personal Server stamps it`,
34042
+ { key }
34043
+ );
34044
+ }
34045
+ }
34046
+ }
34047
+ function isLineagePair(value) {
34048
+ return isRecord2(value) && typeof value.ownerAddress === "string" && typeof value.scope === "string";
34049
+ }
34050
+ function normalizeLineage(lineage, derivedScope) {
34051
+ if (!Array.isArray(lineage)) {
34052
+ throw new WriteRequestError("lineage must be an array of data point ids");
34053
+ }
34054
+ if (lineage.length > MAX_LINEAGE_SOURCES) {
34055
+ throw new WriteRequestError(
34056
+ `lineage lists ${lineage.length} sources; the maximum is ${MAX_LINEAGE_SOURCES}`,
34057
+ { max: MAX_LINEAGE_SOURCES, count: lineage.length }
34058
+ );
34059
+ }
34060
+ const seen = /* @__PURE__ */ new Set();
34061
+ const sources = [];
34062
+ const sourceScopes = [];
34063
+ const ownIds = /* @__PURE__ */ new Set();
34064
+ for (const entry of lineage) {
34065
+ let id;
34066
+ if (isLineagePair(entry)) {
34067
+ if (!isAddress6(entry.ownerAddress, { strict: false })) {
34068
+ throw new WriteRequestError(
34069
+ "lineage source ownerAddress must be an EVM address",
34070
+ { ownerAddress: entry.ownerAddress }
34071
+ );
34072
+ }
34073
+ if (entry.scope.length === 0) {
34074
+ throw new WriteRequestError("lineage source scope is required");
34075
+ }
34076
+ id = deriveDataPointId(entry.ownerAddress, entry.scope);
34077
+ sourceScopes.push(entry.scope);
34078
+ ownIds.add(deriveDataPointId(entry.ownerAddress, derivedScope));
34079
+ } else if (isDataPointId(entry)) {
34080
+ id = entry;
34081
+ } else {
34082
+ throw new WriteRequestError(
34083
+ "lineage entries must be 32-byte hex data point ids or { ownerAddress, scope } pairs",
34084
+ { entry }
34085
+ );
34086
+ }
34087
+ const normalized = id.toLowerCase();
34088
+ if (seen.has(normalized)) {
34089
+ throw new WriteRequestError("lineage must not repeat a data point id", {
34090
+ dataPointId: normalized
34091
+ });
34092
+ }
34093
+ seen.add(normalized);
34094
+ sources.push(normalized);
34095
+ }
34096
+ for (const own of ownIds) {
34097
+ if (seen.has(own)) {
34098
+ throw new WriteRequestError(
34099
+ "lineage must not cite the record's own data point",
34100
+ { dataPointId: own, scope: derivedScope }
34101
+ );
34102
+ }
34103
+ }
34104
+ assertDerivedScopeNaming(derivedScope, sourceScopes);
34105
+ return sources;
34106
+ }
34107
+ function assertNoLineageField(value, where) {
34108
+ if (Object.prototype.hasOwnProperty.call(value, LINEAGE_FIELD)) {
34109
+ throw new WriteRequestError(
34110
+ `${where}.${LINEAGE_FIELD} is reserved; pass sources through the lineage option`
34111
+ );
34112
+ }
34113
+ }
34114
+ function buildMetadataHeader(metadata, sources) {
34115
+ if (metadata !== void 0) {
34116
+ if (!isRecord2(metadata)) {
34117
+ throw new WriteRequestError("metadata must be a plain object");
34118
+ }
34119
+ assertNoReservedKeys(metadata, "metadata");
34120
+ assertNoLineageField(metadata, "metadata");
34121
+ }
34122
+ if (metadata === void 0 && sources === void 0) return void 0;
34123
+ return encodeWriteMetadataHeader({
34124
+ ...metadata ?? {},
34125
+ ...sources !== void 0 ? { [LINEAGE_FIELD]: sources } : {}
34126
+ });
34127
+ }
34128
+ function prepareWrite(params) {
34129
+ if (params.binary !== void 0 && params.data !== void 0) {
34130
+ throw new WriteRequestError("Pass either data or binary, not both");
34131
+ }
34132
+ const rawLineage = params.lineage;
34133
+ const sources = rawLineage === void 0 || rawLineage === null ? void 0 : normalizeLineage(rawLineage, params.scope);
34134
+ if (params.binary !== void 0) {
34135
+ const { bytes, contentType, filename } = params.binary;
34136
+ if (!(bytes instanceof Uint8Array)) {
34137
+ throw new WriteRequestError("binary.bytes must be a Uint8Array");
34138
+ }
34139
+ if (typeof contentType !== "string" || contentType.trim() === "") {
34140
+ throw new WriteRequestError("binary.contentType is required");
34141
+ }
34142
+ if (filename !== void 0) {
34143
+ if (typeof filename !== "string") {
34144
+ throw new WriteRequestError("binary.filename must be a string");
34145
+ }
34146
+ if (filename !== filename.trim()) {
34147
+ throw new WriteRequestError(
34148
+ "binary.filename must not have leading or trailing whitespace"
34149
+ );
34150
+ }
34151
+ }
34152
+ const metadataHeader = buildMetadataHeader(params.metadata, sources);
34153
+ return {
34154
+ body: bytes,
34155
+ signedBytes: binaryWriteSignedBytes({
34156
+ bytes,
34157
+ contentType,
34158
+ filename,
34159
+ metadataHeader
34160
+ }),
34161
+ contentType,
34162
+ filename,
34163
+ metadataHeader
34164
+ };
34165
+ }
34166
+ if (params.data === void 0) {
34167
+ throw new WriteRequestError("Pass data (a JSON object) or binary");
34168
+ }
34169
+ if (!isRecord2(params.data)) {
34170
+ throw new WriteRequestError("data must be a plain JSON object");
34171
+ }
34172
+ if (params.metadata !== void 0) {
34173
+ throw new WriteRequestError(
34174
+ "metadata applies to binary writes; put fields to store inside data"
34175
+ );
34176
+ }
34177
+ assertNoReservedKeys(params.data, "data");
34178
+ assertNoLineageField(params.data, "data");
34179
+ const record = sources === void 0 ? params.data : { ...params.data, [LINEAGE_FIELD]: sources };
34180
+ let text;
34181
+ try {
34182
+ text = JSON.stringify(record);
34183
+ } catch (err) {
34184
+ throw new WriteRequestError(
34185
+ `data is not JSON-serialisable: ${errorMessage(err)}`
34186
+ );
34187
+ }
34188
+ if (typeof text !== "string" || !text.startsWith("{")) {
34189
+ throw new WriteRequestError("data must serialise to a JSON object");
34190
+ }
34191
+ const body = new TextEncoder().encode(text);
34192
+ return {
34193
+ body,
34194
+ signedBytes: body,
34195
+ contentType: "application/json"
34196
+ };
34197
+ }
34198
+ async function writeErrorFromResponse(response) {
34199
+ const { errorCode, message, details } = await readPersonalServerErrorBody(response);
34200
+ const text = message ?? `Personal Server write failed: ${response.status} ${response.statusText}`;
34201
+ if (response.status === 422 || errorCode?.startsWith("LINEAGE_")) {
34202
+ return new WriteLineageError(text, response.status, errorCode, details);
34203
+ }
34204
+ switch (response.status) {
34205
+ case 401:
34206
+ return new WriteUnauthorizedError(text, errorCode, details);
34207
+ case 403:
34208
+ return new WriteForbiddenError(text, errorCode, details);
34209
+ case 409:
34210
+ return new WriteConflictError(text, errorCode, details);
34211
+ default:
34212
+ return new WriteRejectedError(text, response.status, errorCode, details);
34213
+ }
34214
+ }
34215
+ async function writeData(params) {
34216
+ const { session } = params;
34217
+ if (!isWriteSession(session)) {
34218
+ throw new WriteRequestError("session must come from openWriteSession");
34219
+ }
34220
+ const fetchFn = resolveFetch2(params.fetch);
34221
+ if (typeof params.scope !== "string" || params.scope.length === 0) {
34222
+ throw new WriteRequestError("scope is required");
34223
+ }
34224
+ const prepared = prepareWrite(params);
34225
+ if (Date.now() >= session.expiresAt) {
34226
+ throw new WriteSessionExpiredError(
34227
+ "Write session has expired; open a new session",
34228
+ { grantId: session.grantId, expiresAt: session.expiresAt }
34229
+ );
34230
+ }
34231
+ const path = dataPath(params.scope);
34232
+ const response = await sendWithFreshProof(
34233
+ `Write to ${params.scope}`,
34234
+ fetchFn,
34235
+ params.retry,
34236
+ proofKeyFor({
34237
+ aud: session.audience,
34238
+ method: "POST",
34239
+ uri: path,
34240
+ grantId: session.grantId,
34241
+ signedBytes: prepared.signedBytes
34242
+ }),
34243
+ async (iat) => {
34244
+ const headers = new Headers(params.headers);
34245
+ headers.set("Content-Type", prepared.contentType);
34246
+ headers.set("Authorization", `Bearer ${session.accessToken}`);
34247
+ if (prepared.filename) {
34248
+ setFilenameHeader(headers, prepared.filename);
34249
+ }
34250
+ if (prepared.metadataHeader !== void 0) {
34251
+ headers.set(WRITE_METADATA_HEADER, prepared.metadataHeader);
34252
+ }
34253
+ headers.set(
34254
+ WRITE_SIGNATURE_HEADER,
34255
+ await buildWeb3SignedHeader({
34256
+ signMessage: session.signer.signMessage,
34257
+ aud: session.audience,
34258
+ method: "POST",
34259
+ uri: path,
34260
+ body: prepared.signedBytes,
34261
+ grantId: session.grantId,
34262
+ iat
34263
+ })
34264
+ );
34265
+ return {
34266
+ url: `${session.personalServerUrl}${path}`,
34267
+ init: {
34268
+ method: "POST",
34269
+ headers,
34270
+ body: prepared.body
34271
+ }
34272
+ };
34273
+ }
34274
+ );
34275
+ if (!response.ok) {
34276
+ throw await writeErrorFromResponse(response);
34277
+ }
34278
+ let body;
34279
+ try {
34280
+ body = await response.json();
34281
+ } catch (err) {
34282
+ throw new WriteRejectedError(
34283
+ "Personal Server write response is not JSON",
34284
+ response.status,
34285
+ null,
34286
+ { cause: errorMessage(err) }
34287
+ );
34288
+ }
34289
+ const parsed = WriteDataResultSchema.safeParse(body);
34290
+ if (!parsed.success) {
34291
+ throw new WriteRejectedError(
34292
+ "Personal Server write response is not an ingest result",
34293
+ response.status,
34294
+ null,
34295
+ { issues: parsed.error.issues }
34296
+ );
34297
+ }
34298
+ return parsed.data;
34299
+ }
34300
+ async function writePersonalServerData(params) {
34301
+ const session = await openWriteSession({
34302
+ personalServerUrl: params.personalServerUrl,
34303
+ signer: params.signer,
34304
+ grantId: params.grantId,
34305
+ account: params.account,
34306
+ audience: params.audience,
34307
+ fetch: params.fetch,
34308
+ headers: params.headers,
34309
+ retry: params.retry
34310
+ });
34311
+ const writeParams = { ...params, session };
34312
+ const result = await writeData(writeParams);
34313
+ return { ...result, session };
34314
+ }
34315
+
33094
34316
  // src/protocol/gateway.ts
33095
34317
  function withGrantPermissions(grant) {
33096
34318
  const stripped = { ...grant };
@@ -33104,14 +34326,44 @@ function withGrantPermissions(grant) {
33104
34326
  }
33105
34327
  function createGatewayClient(baseUrl) {
33106
34328
  const base = baseUrl.replace(/\/+$/, "");
34329
+ function malformedBody(res) {
34330
+ return new Error(
34331
+ `Gateway error: ${res.status} malformed response body (expected a JSON envelope)`
34332
+ );
34333
+ }
34334
+ async function readEnvelope(res) {
34335
+ const envelope = await readJsonValue(res);
34336
+ if (!isPlainObject(envelope) || !("data" in envelope)) {
34337
+ throw malformedBody(res);
34338
+ }
34339
+ return envelope;
34340
+ }
33107
34341
  async function unwrapEnvelope(res) {
33108
- const envelope = await res.json();
33109
- return envelope.data;
34342
+ return (await readEnvelope(res)).data;
33110
34343
  }
33111
34344
  function getMutationId(body, key) {
34345
+ if (!isPlainObject(body)) return void 0;
33112
34346
  const value = body[key] ?? body["id"];
33113
34347
  return typeof value === "string" ? value : void 0;
33114
34348
  }
34349
+ async function readBody(res) {
34350
+ const raw = await readJsonObject(res);
34351
+ const data = raw["data"];
34352
+ if (isPlainObject(data) && "proof" in raw) {
34353
+ return data;
34354
+ }
34355
+ return raw;
34356
+ }
34357
+ function stringOrUndefined(value) {
34358
+ return typeof value === "string" ? value : void 0;
34359
+ }
34360
+ async function deletedError(res, details) {
34361
+ const body = await readBody(res);
34362
+ return new DataPointDeletedError(
34363
+ `Data point ${details.dataPointId ?? details.scope ?? ""} has been deleted`,
34364
+ { ...details, deletedAt: tombstoneDeletedAt(body) }
34365
+ );
34366
+ }
33115
34367
  return {
33116
34368
  async isRegisteredBuilder(address) {
33117
34369
  const builder = await this.getBuilder(address);
@@ -33168,13 +34420,29 @@ function createGatewayClient(baseUrl) {
33168
34420
  }
33169
34421
  return await res.json();
33170
34422
  },
33171
- async getDataPoint(dataPointId) {
33172
- const res = await fetch(`${base}/v1/data/${dataPointId}`);
34423
+ async getDataPoint(dataPointId, options) {
34424
+ const query = options?.includeDeleted ? "?includeDeleted=true" : "";
34425
+ const res = await fetch(`${base}/v1/data/${dataPointId}${query}`);
33173
34426
  if (res.status === 404) return null;
34427
+ if (res.status === 410) {
34428
+ throw await deletedError(res, { dataPointId });
34429
+ }
33174
34430
  if (!res.ok) {
33175
34431
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
33176
34432
  }
33177
- return unwrapEnvelope(res);
34433
+ const record = await unwrapEnvelope(res);
34434
+ if (!options?.includeDeleted && isDataPointTombstone(record)) {
34435
+ throw new DataPointDeletedError(
34436
+ `Data point ${dataPointId} has been deleted`,
34437
+ {
34438
+ dataPointId,
34439
+ scope: record.scope,
34440
+ ownerAddress: record.ownerAddress,
34441
+ deletedAt: tombstoneDeletedAt(record)
34442
+ }
34443
+ );
34444
+ }
34445
+ return record;
33178
34446
  },
33179
34447
  async listDataPointsByOwner(owner, cursor, options) {
33180
34448
  const params = new URLSearchParams({ user: owner });
@@ -33187,14 +34455,24 @@ function createGatewayClient(baseUrl) {
33187
34455
  if (options?.limit !== void 0) {
33188
34456
  params.set("limit", String(options.limit));
33189
34457
  }
34458
+ if (options?.includeDeleted) {
34459
+ params.set("includeDeleted", "true");
34460
+ }
33190
34461
  const res = await fetch(`${base}/v1/data?${params.toString()}`);
33191
34462
  if (!res.ok) {
33192
34463
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
33193
34464
  }
33194
- const envelope = await res.json();
33195
- const nextCursor = envelope.pagination?.hasMore === false ? null : envelope.pagination?.nextCursor ?? null;
34465
+ const envelope = await readEnvelope(res);
34466
+ if (!isPlainObject(envelope.data) || !Array.isArray(envelope.data["dataPoints"])) {
34467
+ throw malformedBody(res);
34468
+ }
34469
+ const rows = envelope.data["dataPoints"];
34470
+ const pagination = isPlainObject(envelope["pagination"]) ? envelope["pagination"] : void 0;
34471
+ const rawCursor = pagination?.["nextCursor"];
34472
+ const nextCursor = pagination?.["hasMore"] === false || typeof rawCursor !== "string" ? null : rawCursor;
34473
+ const dataPoints = options?.includeDeleted ? rows : rows.filter((row) => !isDataPointTombstone(row));
33196
34474
  return {
33197
- dataPoints: envelope.data.dataPoints,
34475
+ dataPoints,
33198
34476
  cursor: nextCursor
33199
34477
  };
33200
34478
  },
@@ -33221,7 +34499,7 @@ function createGatewayClient(baseUrl) {
33221
34499
  })
33222
34500
  });
33223
34501
  if (res.status === 409) {
33224
- const body2 = await res.json().catch(() => ({}));
34502
+ const body2 = await readJsonObject(res);
33225
34503
  return {
33226
34504
  serverId: getMutationId(body2, "serverId"),
33227
34505
  alreadyRegistered: true
@@ -33230,7 +34508,7 @@ function createGatewayClient(baseUrl) {
33230
34508
  if (!res.ok) {
33231
34509
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
33232
34510
  }
33233
- const body = await res.json().catch(() => ({}));
34511
+ const body = await readJsonObject(res);
33234
34512
  return {
33235
34513
  serverId: getMutationId(body, "serverId"),
33236
34514
  alreadyRegistered: false
@@ -33251,19 +34529,16 @@ function createGatewayClient(baseUrl) {
33251
34529
  })
33252
34530
  });
33253
34531
  if (res.status === 409) {
33254
- const body2 = await res.json().catch(() => ({}));
34532
+ const body2 = await readJsonObject(res);
33255
34533
  return {
33256
- builderId: getMutationId(
33257
- body2,
33258
- "builderId"
33259
- ),
34534
+ builderId: getMutationId(body2, "builderId"),
33260
34535
  alreadyRegistered: true
33261
34536
  };
33262
34537
  }
33263
34538
  if (!res.ok) {
33264
34539
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
33265
34540
  }
33266
- const body = await res.json().catch(() => ({}));
34541
+ const body = await readJsonObject(res);
33267
34542
  return {
33268
34543
  builderId: getMutationId(body, "builderId"),
33269
34544
  alreadyRegistered: false
@@ -33285,17 +34560,77 @@ function createGatewayClient(baseUrl) {
33285
34560
  })
33286
34561
  });
33287
34562
  if (!res.ok) {
33288
- const body2 = await res.json().catch(() => ({}));
33289
- const detail = body2.error ?? res.statusText;
34563
+ const body2 = await readJsonObject(res);
34564
+ const detail = stringOrUndefined(body2["error"]) ?? res.statusText;
33290
34565
  throw new Error(`Gateway error: ${res.status} ${detail}`);
33291
34566
  }
33292
- const body = await res.json().catch(() => ({}));
34567
+ const body = await readJsonObject(res);
33293
34568
  return {
33294
- dataPointId: getMutationId(
33295
- body,
33296
- "dataPointId"
33297
- ),
33298
- expectedVersion: body.expectedVersion
34569
+ dataPointId: getMutationId(body, "dataPointId"),
34570
+ expectedVersion: stringOrUndefined(body["expectedVersion"])
34571
+ };
34572
+ },
34573
+ async deleteDataPoint(params) {
34574
+ const dataPointId = deriveDataPointId(
34575
+ params.ownerAddress,
34576
+ params.scope
34577
+ );
34578
+ const details = {
34579
+ dataPointId,
34580
+ scope: params.scope,
34581
+ ownerAddress: params.ownerAddress
34582
+ };
34583
+ const res = await fetch(`${base}/v1/data/${dataPointId}`, {
34584
+ method: "DELETE",
34585
+ headers: {
34586
+ "Content-Type": "application/json",
34587
+ Authorization: `Web3Signed ${params.signature}`
34588
+ },
34589
+ body: JSON.stringify({
34590
+ ownerAddress: params.ownerAddress,
34591
+ scope: params.scope,
34592
+ expectedVersion: params.expectedVersion,
34593
+ signature: params.signature
34594
+ })
34595
+ });
34596
+ if (res.status === 404) {
34597
+ throw new DataPointNotFoundError(
34598
+ `Data point ${dataPointId} (scope '${params.scope}') is not registered`,
34599
+ details
34600
+ );
34601
+ }
34602
+ if (res.status === 409) {
34603
+ const body2 = await readBody(res);
34604
+ const currentExpectedVersion = stringOrUndefined(
34605
+ body2["currentExpectedVersion"]
34606
+ );
34607
+ const detail = stringOrUndefined(body2["error"]) ?? res.statusText;
34608
+ throw new DataPointVersionConflictError(
34609
+ `Gateway error: 409 ${detail}`,
34610
+ {
34611
+ ...details,
34612
+ expectedVersion: params.expectedVersion,
34613
+ currentExpectedVersion
34614
+ }
34615
+ );
34616
+ }
34617
+ if (res.status === 410) {
34618
+ throw await deletedError(res, details);
34619
+ }
34620
+ if (!res.ok) {
34621
+ const body2 = await readBody(res);
34622
+ const detail = stringOrUndefined(body2["error"]) ?? res.statusText;
34623
+ throw new Error(`Gateway error: ${res.status} ${detail}`);
34624
+ }
34625
+ const body = await readBody(res);
34626
+ return {
34627
+ dataPointId: getMutationId(body, "dataPointId") ?? dataPointId,
34628
+ ownerAddress: stringOrUndefined(body["ownerAddress"]),
34629
+ scope: stringOrUndefined(body["scope"]),
34630
+ dataHash: stringOrUndefined(body["dataHash"]),
34631
+ metadataHash: stringOrUndefined(body["metadataHash"]),
34632
+ expectedVersion: stringOrUndefined(body["expectedVersion"]),
34633
+ deletedAt: tombstoneDeletedAt(body)
33299
34634
  };
33300
34635
  },
33301
34636
  async createGrant(params) {
@@ -33314,18 +34649,14 @@ function createGatewayClient(baseUrl) {
33314
34649
  })
33315
34650
  });
33316
34651
  if (res.status === 409) {
33317
- const body2 = await res.json().catch(() => ({}));
33318
- return {
33319
- grantId: getMutationId(body2, "grantId")
33320
- };
34652
+ const body2 = await readJsonObject(res);
34653
+ return { grantId: getMutationId(body2, "grantId") };
33321
34654
  }
33322
34655
  if (!res.ok) {
33323
34656
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
33324
34657
  }
33325
- const body = await res.json();
33326
- return {
33327
- grantId: getMutationId(body, "grantId")
33328
- };
34658
+ const body = await readJsonObject(res);
34659
+ return { grantId: getMutationId(body, "grantId") };
33329
34660
  },
33330
34661
  async revokeGrant(params) {
33331
34662
  const res = await fetch(`${base}/v1/grants/${params.grantId}`, {
@@ -33543,7 +34874,7 @@ var KNOWN_CODES = /* @__PURE__ */ new Set([
33543
34874
  "server_not_configured",
33544
34875
  "content_too_large"
33545
34876
  ]);
33546
- function isRecord2(value) {
34877
+ function isRecord4(value) {
33547
34878
  return value !== null && typeof value === "object" && !Array.isArray(value);
33548
34879
  }
33549
34880
  function normalizeCode(value) {
@@ -33554,10 +34885,10 @@ function normalizeCode(value) {
33554
34885
  return KNOWN_CODES.has(code) ? code : null;
33555
34886
  }
33556
34887
  function extractPSErrorBody(body) {
33557
- if (!isRecord2(body)) {
34888
+ if (!isRecord4(body)) {
33558
34889
  return null;
33559
34890
  }
33560
- const nested = isRecord2(body.error) ? body.error : null;
34891
+ const nested = isRecord4(body.error) ? body.error : null;
33561
34892
  const code = normalizeCode(
33562
34893
  nested?.errorCode ?? nested?.code ?? body.errorCode ?? body.code
33563
34894
  );
@@ -33595,7 +34926,10 @@ export {
33595
34926
  ContractNotFoundError,
33596
34927
  DATA_REGISTRY_STATUS_ABI,
33597
34928
  DataFileEnvelopeSchema,
34929
+ DataPointDeletedError,
34930
+ DataPointNotFoundError,
33598
34931
  DataPointStatus,
34932
+ DataPointVersionConflictError,
33599
34933
  DropboxStorage,
33600
34934
  ECIESError,
33601
34935
  ESCROW_DEPOSIT_ABI2 as ESCROW_DEPOSIT_ABI,
@@ -33611,7 +34945,14 @@ export {
33611
34945
  InvalidScopeEntryError,
33612
34946
  InvalidSignatureError,
33613
34947
  IpfsStorage,
34948
+ LINEAGE_FIELD,
34949
+ LINEAGE_KEY,
34950
+ LineageEntrySchema,
34951
+ LineageGraphSchema,
34952
+ LineageNodeSchema,
34953
+ LineageReadError,
33614
34954
  MASTER_KEY_MESSAGE,
34955
+ MAX_LINEAGE_SOURCES,
33615
34956
  MissingAuthError,
33616
34957
  NATIVE_ASSET_ADDRESS,
33617
34958
  NATIVE_VANA_ASSET,
@@ -33628,11 +34969,14 @@ export {
33628
34969
  PSError,
33629
34970
  PermissionError,
33630
34971
  PersonalServerError,
34972
+ PersonalServerWriteError,
33631
34973
  PinataStorage,
33632
34974
  R2Storage,
33633
34975
  RECORD_DATA_ACCESS_TYPES,
33634
34976
  REGISTRATION_KIND_FOR_OP,
34977
+ RESERVED_WRITE_KEYS,
33635
34978
  ReadOnlyError,
34979
+ RedactedLineageNodeSchema,
33636
34980
  RelayerError,
33637
34981
  SCOPE_ACTIONS,
33638
34982
  SERVER_REGISTRATION_TYPES,
@@ -33642,11 +34986,34 @@ export {
33642
34986
  SignatureError,
33643
34987
  StorageError,
33644
34988
  StorageManager,
34989
+ TOMBSTONE_DATA_HASH,
34990
+ TOMBSTONE_DATA_HASH_PREIMAGE,
34991
+ TOMBSTONE_METADATA_HASH,
34992
+ TOMBSTONE_METADATA_HASH_PREIMAGE,
33645
34993
  TransactionPendingError,
33646
34994
  UserRejectedRequestError,
33647
34995
  VanaError,
33648
34996
  VanaStorage,
34997
+ WRITER_ATTRIBUTION_KEY,
34998
+ WRITE_CONTENT_DISPOSITION_HEADER,
34999
+ WRITE_FILENAME_HEADER,
35000
+ WRITE_METADATA_HEADER,
35001
+ WRITE_SESSION_PATH,
35002
+ WRITE_SIGNATURE_HEADER,
35003
+ WriteConflictError,
35004
+ WriteForbiddenError,
35005
+ WriteLineageError,
35006
+ WriteRejectedError,
35007
+ WriteRequestError,
35008
+ WriteSessionError,
35009
+ WriteSessionExpiredError,
35010
+ WriteTransportError,
35011
+ WriteUnauthorizedError,
35012
+ assertDerivedScopeNaming,
33649
35013
  assertValidPkceVerifier,
35014
+ binaryWriteSignedBytes,
35015
+ buildDataPointDeletionSignature,
35016
+ buildDataPointDeletionTypedData,
33650
35017
  buildDepositNativeRequest,
33651
35018
  buildDepositTokenRequest,
33652
35019
  buildMarkDataPointUnavailableRequest,
@@ -33662,6 +35029,7 @@ export {
33662
35029
  clearContractCache,
33663
35030
  computeBodyHash,
33664
35031
  computePkceChallenge,
35032
+ computeTombstoneHash,
33665
35033
  contractCacheForTesting,
33666
35034
  createBrowserPlatformAdapter,
33667
35035
  createDataFileEnvelope,
@@ -33669,22 +35037,28 @@ export {
33669
35037
  createGatewayClient,
33670
35038
  createPlatformAdapterSafe,
33671
35039
  createVanaStorageProvider,
35040
+ createViemDataPointDeletionSigner,
33672
35041
  createViemPersonalServerLiteOwnerBindingSigner,
33673
35042
  createViemPersonalServerRegistrationSigner,
33674
35043
  dataRegistryContractAddress,
33675
35044
  dataRegistryDomain,
33676
35045
  decryptWithPassword,
35046
+ deleteDataPoint,
35047
+ deriveDataPointId,
33677
35048
  deriveMasterKey,
33678
35049
  deriveScopeKey,
35050
+ derivedScopeViolatesNaming,
33679
35051
  deserializeECIES,
33680
35052
  detectPlatform,
33681
35053
  encodeDepositNativeData,
33682
35054
  encodeDepositTokenData,
33683
35055
  encodeSetDataPointStatusData,
35056
+ encodeWriteMetadataHeader,
33684
35057
  encryptWithPassword,
33685
35058
  escrowContractAddress,
33686
35059
  escrowPaymentDomain,
33687
35060
  formatScopeEntry,
35061
+ gatewayLineagePath,
33688
35062
  generatePkceVerifier,
33689
35063
  genericPaymentDomain,
33690
35064
  getAbi,
@@ -33694,42 +35068,59 @@ export {
33694
35068
  getContractController,
33695
35069
  getContractInfo,
33696
35070
  getFee,
35071
+ getGatewayLineage,
35072
+ getLineage,
33697
35073
  getOpFee,
35074
+ getPersonalServerLineage,
33698
35075
  getPlatformCapabilities,
33699
35076
  getServiceEndpoints,
33700
35077
  grantPermissions,
33701
35078
  grantRegistrationDomain,
33702
35079
  grantRevocationDomain,
33703
35080
  hasAction,
35081
+ isDataPointId,
35082
+ isDataPointTombstone,
33704
35083
  isDataPortabilityGatewayConfig,
33705
35084
  isECIESEncrypted,
33706
35085
  isPlatformSupported,
35086
+ isRedactedLineageNode,
35087
+ isTombstoneHashes,
33707
35088
  mainnetServices,
33708
35089
  moksha,
33709
35090
  mokshaServices,
33710
35091
  mokshaTestnet2 as mokshaTestnet,
35092
+ normalizeBinaryMimeType,
35093
+ openWriteSession,
33711
35094
  parsePSError,
33712
35095
  parseScope,
33713
35096
  parseScopeEntry,
33714
35097
  parseWeb3SignedHeader,
35098
+ parseWriteMetadataHeader,
33715
35099
  permissionsToScopes,
33716
35100
  personalServerDataReadPath,
35101
+ personalServerLineagePath,
33717
35102
  personalServerRegistrationDomain,
33718
35103
  readPersonalServerData,
33719
35104
  recoverServerOwner,
33720
35105
  registerPersonalServerSignature,
35106
+ resolveWriteSigner,
33721
35107
  scopeCoveredByGrant,
33722
35108
  scopeMatchesPattern,
35109
+ scopeNamespace,
33723
35110
  scopeToPathSegments,
33724
35111
  serializeECIES,
33725
35112
  serverRegistrationDomain,
35113
+ sessionCoversScope,
33726
35114
  signPersonalServerLiteOwnerBinding,
33727
35115
  signPersonalServerLiteOwnerBindingWithAccountClient,
33728
35116
  signPersonalServerRegistrationWithAccount,
35117
+ tombstoneDeletedAt,
33729
35118
  tryGrantPermissions,
33730
35119
  vanaMainnet2 as vanaMainnet,
33731
35120
  verifyGrantRegistration,
33732
35121
  verifyPkceChallenge,
33733
- verifyWeb3Signed
35122
+ verifyWeb3Signed,
35123
+ writeData,
35124
+ writePersonalServerData
33734
35125
  };
33735
35126
  //# sourceMappingURL=index.browser.js.map