@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.
- package/README.md +107 -0
- package/dist/direct/personal-server-read.cjs +20 -1
- package/dist/direct/personal-server-read.cjs.map +1 -1
- package/dist/direct/personal-server-read.js +23 -1
- package/dist/direct/personal-server-read.js.map +1 -1
- package/dist/errors.cjs +121 -2
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +190 -0
- package/dist/errors.js +106 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.browser.d.ts +5 -1
- package/dist/index.browser.js +1449 -58
- package/dist/index.browser.js.map +4 -4
- package/dist/index.node.cjs +1501 -59
- package/dist/index.node.cjs.map +4 -4
- package/dist/index.node.d.ts +5 -1
- package/dist/index.node.js +1449 -58
- package/dist/index.node.js.map +4 -4
- package/dist/protocol/data-point-deletion.cjs +220 -0
- package/dist/protocol/data-point-deletion.cjs.map +1 -0
- package/dist/protocol/data-point-deletion.d.ts +180 -0
- package/dist/protocol/data-point-deletion.js +193 -0
- package/dist/protocol/data-point-deletion.js.map +1 -0
- package/dist/protocol/data-point-deletion.test.d.ts +1 -0
- package/dist/protocol/gateway.cjs +145 -32
- package/dist/protocol/gateway.cjs.map +1 -1
- package/dist/protocol/gateway.d.ts +42 -3
- package/dist/protocol/gateway.js +156 -32
- package/dist/protocol/gateway.js.map +1 -1
- package/dist/protocol/lineage.cjs +287 -0
- package/dist/protocol/lineage.cjs.map +1 -0
- package/dist/protocol/lineage.d.ts +228 -0
- package/dist/protocol/lineage.js +258 -0
- package/dist/protocol/lineage.js.map +1 -0
- package/dist/protocol/lineage.test.d.ts +1 -0
- package/dist/protocol/personal-server-data.cjs +20 -1
- package/dist/protocol/personal-server-data.cjs.map +1 -1
- package/dist/protocol/personal-server-data.js +23 -1
- package/dist/protocol/personal-server-data.js.map +1 -1
- package/dist/protocol/personal-server-error-body.cjs +57 -0
- package/dist/protocol/personal-server-error-body.cjs.map +1 -0
- package/dist/protocol/personal-server-error-body.d.ts +18 -0
- package/dist/protocol/personal-server-error-body.js +32 -0
- package/dist/protocol/personal-server-error-body.js.map +1 -0
- package/dist/protocol/personal-server-write.cjs +623 -0
- package/dist/protocol/personal-server-write.cjs.map +1 -0
- package/dist/protocol/personal-server-write.d.ts +284 -0
- package/dist/protocol/personal-server-write.js +601 -0
- package/dist/protocol/personal-server-write.js.map +1 -0
- package/dist/protocol/personal-server-write.test.d.ts +1 -0
- package/dist/protocol/write-signer.cjs +67 -0
- package/dist/protocol/write-signer.cjs.map +1 -0
- package/dist/protocol/write-signer.d.ts +59 -0
- package/dist/protocol/write-signer.js +43 -0
- package/dist/protocol/write-signer.js.map +1 -0
- package/dist/protocol/write-signer.test.d.ts +1 -0
- package/dist/storage/index.cjs.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/providers/vana-storage.cjs +66 -0
- package/dist/storage/providers/vana-storage.cjs.map +1 -1
- package/dist/storage/providers/vana-storage.d.ts +26 -0
- package/dist/storage/providers/vana-storage.js +66 -0
- package/dist/storage/providers/vana-storage.js.map +1 -1
- package/dist/tests/mock-personal-server.d.ts +127 -0
- package/dist/utils/response-body.cjs +46 -0
- package/dist/utils/response-body.cjs.map +1 -0
- package/dist/utils/response-body.d.ts +26 -0
- package/dist/utils/response-body.js +20 -0
- package/dist/utils/response-body.js.map +1 -0
- package/dist/utils/response-body.test.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.browser.js
CHANGED
|
@@ -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
|
|
32176
|
-
if (
|
|
32347
|
+
const accountAddress2 = getAccountAddress(options.account) ?? getAccountAddress(source.account);
|
|
32348
|
+
if (accountAddress2) {
|
|
32177
32349
|
return {
|
|
32178
|
-
address:
|
|
32350
|
+
address: accountAddress2,
|
|
32179
32351
|
signTypedData: (typedData) => source.signTypedData({
|
|
32180
32352
|
...typedData,
|
|
32181
|
-
account: options.account ?? source.account ??
|
|
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
|
|
32267
|
-
if (
|
|
32438
|
+
const accountAddress2 = getAccountAddress2(options.account) ?? getAccountAddress2(source.account);
|
|
32439
|
+
if (accountAddress2) {
|
|
32268
32440
|
return {
|
|
32269
|
-
address:
|
|
32441
|
+
address: accountAddress2,
|
|
32270
32442
|
signMessage: ({ message }) => source.signMessage({
|
|
32271
|
-
account: options.account ?? source.account ??
|
|
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-
|
|
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
|
-
|
|
32841
|
-
|
|
32842
|
-
|
|
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
|
-
|
|
32845
|
-
|
|
32846
|
-
|
|
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 =
|
|
32859
|
-
scope:
|
|
32860
|
-
collectedAt:
|
|
32861
|
-
status:
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
33195
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
33289
|
-
const detail = body2
|
|
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
|
|
34567
|
+
const body = await readJsonObject(res);
|
|
33293
34568
|
return {
|
|
33294
|
-
dataPointId: getMutationId(
|
|
33295
|
-
|
|
33296
|
-
|
|
33297
|
-
|
|
33298
|
-
|
|
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
|
|
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
|
|
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
|
|
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 (!
|
|
34888
|
+
if (!isRecord4(body)) {
|
|
33558
34889
|
return null;
|
|
33559
34890
|
}
|
|
33560
|
-
const nested =
|
|
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
|