@opendatalabs/vana-sdk 3.22.0 → 3.23.0-pr.211.3227174
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 +57 -0
- package/dist/auth/errors.cjs +1 -1
- package/dist/auth/web3-signed.cjs +1 -1
- package/dist/crypto/envelope/job-stream.test.d.ts +1 -0
- package/dist/crypto/envelope/job.cjs +818 -0
- package/dist/crypto/envelope/job.cjs.map +1 -0
- package/dist/crypto/envelope/job.d.ts +139 -0
- package/dist/crypto/envelope/job.js +792 -0
- package/dist/crypto/envelope/job.js.map +1 -0
- package/dist/direct/access-request-client.cjs +5 -1
- package/dist/direct/access-request-client.cjs.map +1 -1
- package/dist/direct/access-request-client.js +4 -0
- package/dist/direct/access-request-client.js.map +1 -1
- package/dist/direct/connect-flow.cjs +43 -1
- package/dist/direct/connect-flow.cjs.map +1 -1
- package/dist/direct/connect-flow.d.ts +12 -0
- package/dist/direct/connect-flow.js +43 -1
- package/dist/direct/connect-flow.js.map +1 -1
- package/dist/direct/controller.cjs +1 -1
- package/dist/direct/errors.cjs +1 -1
- package/dist/direct/personal-server-read.cjs +2 -2
- package/dist/direct/types.cjs.map +1 -1
- package/dist/direct/types.d.ts +7 -0
- package/dist/direct/types.js.map +1 -1
- package/dist/direct/use-direct-vana-connect.cjs +2 -1
- package/dist/direct/use-direct-vana-connect.cjs.map +1 -1
- package/dist/direct/use-direct-vana-connect.d.ts +3 -1
- package/dist/direct/use-direct-vana-connect.js +2 -1
- package/dist/direct/use-direct-vana-connect.js.map +1 -1
- package/dist/error-entry-points.test.d.ts +1 -0
- package/dist/errors.cjs +84 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +133 -0
- package/dist/errors.js +73 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.browser.d.ts +3 -0
- package/dist/index.browser.js +1143 -434
- package/dist/index.browser.js.map +4 -4
- package/dist/index.node.cjs +1801 -631
- package/dist/index.node.cjs.map +4 -4
- package/dist/index.node.d.ts +4 -0
- package/dist/index.node.js +1762 -522
- package/dist/index.node.js.map +4 -4
- package/dist/protocol/data-point-deletion.cjs +1 -1
- package/dist/protocol/derivative-questions.cjs +1 -1
- package/dist/protocol/derivative-status.cjs +1 -1
- package/dist/protocol/fixtures/moksha-identity.json +20 -0
- package/dist/protocol/gateway.cjs +1 -1
- package/dist/protocol/identity.cjs +224 -0
- package/dist/protocol/identity.cjs.map +1 -0
- package/dist/protocol/identity.d.ts +193 -0
- package/dist/protocol/identity.js +188 -0
- package/dist/protocol/identity.js.map +1 -0
- package/dist/protocol/identity.test.d.ts +1 -0
- package/dist/protocol/identity.vector.test.d.ts +1 -0
- package/dist/protocol/jobs-client.cjs +551 -0
- package/dist/protocol/jobs-client.cjs.map +1 -0
- package/dist/protocol/jobs-client.d.ts +169 -0
- package/dist/protocol/jobs-client.js +558 -0
- package/dist/protocol/jobs-client.js.map +1 -0
- package/dist/protocol/jobs-client.test.d.ts +1 -0
- package/dist/protocol/jobs.cjs +64 -0
- package/dist/protocol/jobs.cjs.map +1 -0
- package/dist/protocol/jobs.d.ts +193 -0
- package/dist/protocol/jobs.js +31 -0
- package/dist/protocol/jobs.js.map +1 -0
- package/dist/protocol/jobs.test.d.ts +1 -0
- package/dist/protocol/lineage.cjs +1 -1
- package/dist/protocol/personal-server-data.cjs +1 -1
- package/dist/protocol/personal-server-write.cjs +1 -1
- package/dist/protocol/write-request.cjs +1 -1
- package/dist/protocol/write-signer.cjs +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js.map +1 -1
- package/dist/session-relay/client.cjs +1 -1
- package/dist/session-relay/errors.cjs +1 -1
- package/dist/session-relay/index.cjs +1 -1
- package/package.json +7 -1
package/dist/index.browser.js
CHANGED
|
@@ -1138,289 +1138,8 @@ var init_browser2 = __esm({
|
|
|
1138
1138
|
}
|
|
1139
1139
|
});
|
|
1140
1140
|
|
|
1141
|
-
// src/
|
|
1142
|
-
|
|
1143
|
-
constructor(message, code) {
|
|
1144
|
-
super(message);
|
|
1145
|
-
this.code = code;
|
|
1146
|
-
this.name = this.constructor.name;
|
|
1147
|
-
if (Error.captureStackTrace) {
|
|
1148
|
-
Error.captureStackTrace(this, this.constructor);
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
code;
|
|
1152
|
-
};
|
|
1153
|
-
var RelayerError = class extends VanaError {
|
|
1154
|
-
constructor(message, statusCode, response) {
|
|
1155
|
-
super(message, "RELAYER_ERROR");
|
|
1156
|
-
this.statusCode = statusCode;
|
|
1157
|
-
this.response = response;
|
|
1158
|
-
}
|
|
1159
|
-
statusCode;
|
|
1160
|
-
response;
|
|
1161
|
-
};
|
|
1162
|
-
var UserRejectedRequestError = class extends VanaError {
|
|
1163
|
-
constructor(message = "User rejected the signature request") {
|
|
1164
|
-
super(message, "USER_REJECTED_REQUEST");
|
|
1165
|
-
}
|
|
1166
|
-
};
|
|
1167
|
-
var InvalidConfigurationError = class extends VanaError {
|
|
1168
|
-
constructor(message) {
|
|
1169
|
-
super(message, "INVALID_CONFIGURATION");
|
|
1170
|
-
}
|
|
1171
|
-
};
|
|
1172
|
-
var ContractNotFoundError = class extends VanaError {
|
|
1173
|
-
constructor(contractName, chainId) {
|
|
1174
|
-
super(
|
|
1175
|
-
`Contract ${contractName} not found on chain ${chainId}`,
|
|
1176
|
-
"CONTRACT_NOT_FOUND"
|
|
1177
|
-
);
|
|
1178
|
-
}
|
|
1179
|
-
};
|
|
1180
|
-
var BlockchainError = class extends VanaError {
|
|
1181
|
-
constructor(message, originalError) {
|
|
1182
|
-
super(message, "BLOCKCHAIN_ERROR");
|
|
1183
|
-
this.originalError = originalError;
|
|
1184
|
-
}
|
|
1185
|
-
originalError;
|
|
1186
|
-
};
|
|
1187
|
-
var SerializationError = class extends VanaError {
|
|
1188
|
-
constructor(message) {
|
|
1189
|
-
super(message, "SERIALIZATION_ERROR");
|
|
1190
|
-
}
|
|
1191
|
-
};
|
|
1192
|
-
var SignatureError = class extends VanaError {
|
|
1193
|
-
constructor(message, originalError) {
|
|
1194
|
-
super(message, "SIGNATURE_ERROR");
|
|
1195
|
-
this.originalError = originalError;
|
|
1196
|
-
}
|
|
1197
|
-
originalError;
|
|
1198
|
-
};
|
|
1199
|
-
var NetworkError = class extends VanaError {
|
|
1200
|
-
constructor(message, originalError) {
|
|
1201
|
-
super(message, "NETWORK_ERROR");
|
|
1202
|
-
this.originalError = originalError;
|
|
1203
|
-
}
|
|
1204
|
-
originalError;
|
|
1205
|
-
};
|
|
1206
|
-
var NonceError = class extends VanaError {
|
|
1207
|
-
constructor(message) {
|
|
1208
|
-
super(message, "NONCE_ERROR");
|
|
1209
|
-
}
|
|
1210
|
-
};
|
|
1211
|
-
var PersonalServerError = class extends VanaError {
|
|
1212
|
-
constructor(message, originalError) {
|
|
1213
|
-
super(message, "PERSONAL_SERVER_ERROR");
|
|
1214
|
-
this.originalError = originalError;
|
|
1215
|
-
}
|
|
1216
|
-
originalError;
|
|
1217
|
-
};
|
|
1218
|
-
var ServerUrlMismatchError = class extends VanaError {
|
|
1219
|
-
constructor(existingUrl, providedUrl, serverId) {
|
|
1220
|
-
super(
|
|
1221
|
-
`Server ${serverId} is already registered with URL "${existingUrl}". Cannot change to "${providedUrl}".`,
|
|
1222
|
-
"SERVER_URL_MISMATCH"
|
|
1223
|
-
);
|
|
1224
|
-
this.existingUrl = existingUrl;
|
|
1225
|
-
this.providedUrl = providedUrl;
|
|
1226
|
-
this.serverId = serverId;
|
|
1227
|
-
}
|
|
1228
|
-
existingUrl;
|
|
1229
|
-
providedUrl;
|
|
1230
|
-
serverId;
|
|
1231
|
-
};
|
|
1232
|
-
var PermissionError = class extends VanaError {
|
|
1233
|
-
constructor(message, originalError) {
|
|
1234
|
-
super(message, "PERMISSION_ERROR");
|
|
1235
|
-
this.originalError = originalError;
|
|
1236
|
-
}
|
|
1237
|
-
originalError;
|
|
1238
|
-
};
|
|
1239
|
-
var ReadOnlyError = class extends VanaError {
|
|
1240
|
-
constructor(operation, suggestion = "Initialize the SDK with a walletClient to perform this operation") {
|
|
1241
|
-
super(
|
|
1242
|
-
`Operation '${operation}' requires a wallet client. ${suggestion}`,
|
|
1243
|
-
"READ_ONLY_ERROR"
|
|
1244
|
-
);
|
|
1245
|
-
this.operation = operation;
|
|
1246
|
-
this.suggestion = suggestion;
|
|
1247
|
-
}
|
|
1248
|
-
/** The operation that was attempted */
|
|
1249
|
-
operation;
|
|
1250
|
-
/** Suggested solution for fixing the error */
|
|
1251
|
-
suggestion;
|
|
1252
|
-
};
|
|
1253
|
-
var TransactionPendingError = class extends VanaError {
|
|
1254
|
-
constructor(operationId, message, lastKnownStatus) {
|
|
1255
|
-
super(
|
|
1256
|
-
`Transaction operation pending: ${message} (operationId: ${operationId})`,
|
|
1257
|
-
"TRANSACTION_PENDING"
|
|
1258
|
-
);
|
|
1259
|
-
this.operationId = operationId;
|
|
1260
|
-
this.lastKnownStatus = lastKnownStatus;
|
|
1261
|
-
}
|
|
1262
|
-
operationId;
|
|
1263
|
-
lastKnownStatus;
|
|
1264
|
-
/**
|
|
1265
|
-
* Converts the error to a JSON-serializable format.
|
|
1266
|
-
*
|
|
1267
|
-
* @remarks
|
|
1268
|
-
* Useful for logging, storage, or transmission of error details.
|
|
1269
|
-
*
|
|
1270
|
-
* @returns JSON representation of the error
|
|
1271
|
-
*/
|
|
1272
|
-
toJSON() {
|
|
1273
|
-
return {
|
|
1274
|
-
name: this.name,
|
|
1275
|
-
code: this.code,
|
|
1276
|
-
message: this.message,
|
|
1277
|
-
operationId: this.operationId,
|
|
1278
|
-
lastKnownStatus: this.lastKnownStatus
|
|
1279
|
-
};
|
|
1280
|
-
}
|
|
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 DerivativeQuestionRejectedError = class extends PersonalServerWriteError {
|
|
1353
|
-
constructor(message, status, errorCode = null, details) {
|
|
1354
|
-
super(message, "DERIVATIVE_QUESTION_REJECTED", status, errorCode, details);
|
|
1355
|
-
}
|
|
1356
|
-
};
|
|
1357
|
-
var DerivativeQuestionInvalidError = class extends PersonalServerWriteError {
|
|
1358
|
-
constructor(message, status = 400, errorCode = null, details) {
|
|
1359
|
-
super(message, "DERIVATIVE_QUESTION_INVALID", status, errorCode, details);
|
|
1360
|
-
}
|
|
1361
|
-
};
|
|
1362
|
-
var DerivativeQuestionNotFoundError = class extends PersonalServerWriteError {
|
|
1363
|
-
constructor(message, errorCode = null, details) {
|
|
1364
|
-
super(message, "DERIVATIVE_QUESTION_NOT_FOUND", 404, errorCode, details);
|
|
1365
|
-
}
|
|
1366
|
-
};
|
|
1367
|
-
var DerivativeDerivedScopeRequiredError = class extends PersonalServerWriteError {
|
|
1368
|
-
constructor(message, errorCode = null, details) {
|
|
1369
|
-
super(
|
|
1370
|
-
message,
|
|
1371
|
-
"DERIVATIVE_DERIVED_SCOPE_REQUIRED",
|
|
1372
|
-
400,
|
|
1373
|
-
errorCode,
|
|
1374
|
-
details
|
|
1375
|
-
);
|
|
1376
|
-
}
|
|
1377
|
-
};
|
|
1378
|
-
var DerivativeSourceNotGrantedError = class extends PersonalServerWriteError {
|
|
1379
|
-
constructor(message, errorCode = null, details) {
|
|
1380
|
-
super(message, "DERIVATIVE_SOURCE_NOT_GRANTED", 403, errorCode, details);
|
|
1381
|
-
}
|
|
1382
|
-
};
|
|
1383
|
-
var DerivativeCycleError = class extends PersonalServerWriteError {
|
|
1384
|
-
constructor(message, errorCode = null, details) {
|
|
1385
|
-
super(message, "DERIVATIVE_CYCLE", 409, errorCode, details);
|
|
1386
|
-
}
|
|
1387
|
-
};
|
|
1388
|
-
var DerivativeComputeUnavailableError = class extends PersonalServerWriteError {
|
|
1389
|
-
constructor(message, errorCode = null, details) {
|
|
1390
|
-
super(message, "DERIVATIVE_COMPUTE_UNAVAILABLE", 503, errorCode, details);
|
|
1391
|
-
}
|
|
1392
|
-
};
|
|
1393
|
-
var DerivativeQuestionTimeoutError = class extends PersonalServerWriteError {
|
|
1394
|
-
constructor(message, details) {
|
|
1395
|
-
super(message, "DERIVATIVE_QUESTION_TIMEOUT", void 0, null, details);
|
|
1396
|
-
}
|
|
1397
|
-
};
|
|
1398
|
-
var DerivativeQuestionFailedError = class extends PersonalServerWriteError {
|
|
1399
|
-
constructor(message, details) {
|
|
1400
|
-
super(message, "DERIVATIVE_QUESTION_FAILED", void 0, null, details);
|
|
1401
|
-
}
|
|
1402
|
-
};
|
|
1403
|
-
var DataPointDeletedError = class extends VanaError {
|
|
1404
|
-
constructor(message, details = {}) {
|
|
1405
|
-
super(message, "DATA_POINT_DELETED");
|
|
1406
|
-
this.details = details;
|
|
1407
|
-
}
|
|
1408
|
-
details;
|
|
1409
|
-
};
|
|
1410
|
-
var DataPointNotFoundError = class extends VanaError {
|
|
1411
|
-
constructor(message, details = {}) {
|
|
1412
|
-
super(message, "DATA_POINT_NOT_FOUND");
|
|
1413
|
-
this.details = details;
|
|
1414
|
-
}
|
|
1415
|
-
details;
|
|
1416
|
-
};
|
|
1417
|
-
var DataPointVersionConflictError = class extends VanaError {
|
|
1418
|
-
constructor(message, details = {}) {
|
|
1419
|
-
super(message, "DATA_POINT_VERSION_CONFLICT");
|
|
1420
|
-
this.details = details;
|
|
1421
|
-
}
|
|
1422
|
-
details;
|
|
1423
|
-
};
|
|
1141
|
+
// src/index.browser.ts
|
|
1142
|
+
export * from "./errors.js";
|
|
1424
1143
|
|
|
1425
1144
|
// src/contracts/contractController.ts
|
|
1426
1145
|
import {
|
|
@@ -31495,31 +31214,11 @@ async function decryptWithPassword(encrypted, password) {
|
|
|
31495
31214
|
|
|
31496
31215
|
// src/auth/web3-signed.ts
|
|
31497
31216
|
import { recoverMessageAddress as recoverMessageAddress2 } from "viem";
|
|
31498
|
-
|
|
31499
|
-
|
|
31500
|
-
|
|
31501
|
-
|
|
31502
|
-
|
|
31503
|
-
this.details = details;
|
|
31504
|
-
}
|
|
31505
|
-
details;
|
|
31506
|
-
};
|
|
31507
|
-
var InvalidSignatureError = class extends VanaError {
|
|
31508
|
-
constructor(details, message = "Invalid signature") {
|
|
31509
|
-
super(message, "INVALID_SIGNATURE");
|
|
31510
|
-
this.details = details;
|
|
31511
|
-
}
|
|
31512
|
-
details;
|
|
31513
|
-
};
|
|
31514
|
-
var ExpiredTokenError = class extends VanaError {
|
|
31515
|
-
constructor(details, message = "Token has expired") {
|
|
31516
|
-
super(message, "EXPIRED_TOKEN");
|
|
31517
|
-
this.details = details;
|
|
31518
|
-
}
|
|
31519
|
-
details;
|
|
31520
|
-
};
|
|
31521
|
-
|
|
31522
|
-
// src/auth/web3-signed.ts
|
|
31217
|
+
import {
|
|
31218
|
+
MissingAuthError,
|
|
31219
|
+
InvalidSignatureError,
|
|
31220
|
+
ExpiredTokenError
|
|
31221
|
+
} from "./auth/errors.js";
|
|
31523
31222
|
var WEB3_SIGNED_PREFIX = "Web3Signed ";
|
|
31524
31223
|
var CLOCK_SKEW_SECONDS = 60;
|
|
31525
31224
|
function base64urlDecode(input) {
|
|
@@ -31637,6 +31336,13 @@ async function verifyWeb3Signed(params) {
|
|
|
31637
31336
|
return { signer, payload };
|
|
31638
31337
|
}
|
|
31639
31338
|
|
|
31339
|
+
// src/index.browser.ts
|
|
31340
|
+
import {
|
|
31341
|
+
MissingAuthError as MissingAuthError2,
|
|
31342
|
+
InvalidSignatureError as InvalidSignatureError2,
|
|
31343
|
+
ExpiredTokenError as ExpiredTokenError2
|
|
31344
|
+
} from "./auth/errors.js";
|
|
31345
|
+
|
|
31640
31346
|
// src/protocol/eip712.ts
|
|
31641
31347
|
var DOMAIN_NAME = "Vana Data Portability";
|
|
31642
31348
|
var DOMAIN_VERSION = "1";
|
|
@@ -31736,9 +31442,974 @@ var RECORD_DATA_ACCESS_TYPES = {
|
|
|
31736
31442
|
]
|
|
31737
31443
|
};
|
|
31738
31444
|
|
|
31445
|
+
// src/protocol/identity.ts
|
|
31446
|
+
init_interface();
|
|
31447
|
+
import * as secp256k13 from "@noble/secp256k1";
|
|
31448
|
+
import {
|
|
31449
|
+
concat as concat4,
|
|
31450
|
+
encodePacked,
|
|
31451
|
+
fromHex as fromHex5,
|
|
31452
|
+
getAddress,
|
|
31453
|
+
isAddressEqual,
|
|
31454
|
+
keccak256,
|
|
31455
|
+
recoverPublicKey,
|
|
31456
|
+
toBytes,
|
|
31457
|
+
toHex as toHex6
|
|
31458
|
+
} from "viem";
|
|
31459
|
+
import { publicKeyToAddress } from "viem/accounts";
|
|
31460
|
+
var ENCLAVE_IDENTITY_EVIDENCE_VERSION = 1;
|
|
31461
|
+
var USER_PS_ID_DOMAIN = "vana.ps-enclave.v1";
|
|
31462
|
+
var ENCLAVE_WALLET_PURPOSE = "vana.ps-enclave.wallet.v1";
|
|
31463
|
+
var MASTER_SIGNATURE_DELIVERY_VERSION = "vana.ps-enclave.delivery.v1";
|
|
31464
|
+
var MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS = 600;
|
|
31465
|
+
var SEALED_ENVELOPE_VERSION = 1;
|
|
31466
|
+
var VANA_MAINNET_CHAIN_ID = 1480;
|
|
31467
|
+
var MOKSHA_CHAIN_ID = 14800;
|
|
31468
|
+
var KMS_ISSUED_PREFIX = "dstack-kms-issued";
|
|
31469
|
+
var PREIMAGE_SEPARATOR = ":";
|
|
31470
|
+
var UNCOMPRESSED_PUBLIC_KEY_BYTES = 65;
|
|
31471
|
+
var UNCOMPRESSED_PUBLIC_KEY_PREFIX = "04";
|
|
31472
|
+
var EMPTY_HEX = "0x";
|
|
31473
|
+
function emptyAnchor() {
|
|
31474
|
+
return Object.freeze({
|
|
31475
|
+
kmsRootPubkey: EMPTY_HEX,
|
|
31476
|
+
appIds: Object.freeze([])
|
|
31477
|
+
});
|
|
31478
|
+
}
|
|
31479
|
+
var ENCLAVE_TRUST_ANCHORS = Object.freeze({
|
|
31480
|
+
// filled at fleet provisioning; verify fails closed while empty
|
|
31481
|
+
[VANA_MAINNET_CHAIN_ID]: emptyAnchor(),
|
|
31482
|
+
// Moksha workers share this dstack app and KMS root; the controller does not derive owner keys.
|
|
31483
|
+
[MOKSHA_CHAIN_ID]: Object.freeze({
|
|
31484
|
+
kmsRootPubkey: "0x0434c76e0c3f52ec64cbf9bbf5c910c272330166fd656c0a86bb330963e46910e1a0e6fa51bec74be2f9129342707636060d85856d102cee8290185409ecf7422f",
|
|
31485
|
+
appIds: Object.freeze([
|
|
31486
|
+
"0xec9a39de98c760e1ded9f1e97016dc5f0e357cf2"
|
|
31487
|
+
])
|
|
31488
|
+
})
|
|
31489
|
+
});
|
|
31490
|
+
function userPsId(chainId, ownerAddress) {
|
|
31491
|
+
const packed = encodePacked(
|
|
31492
|
+
["string", "uint256", "address"],
|
|
31493
|
+
[USER_PS_ID_DOMAIN, BigInt(chainId), getAddress(ownerAddress)]
|
|
31494
|
+
);
|
|
31495
|
+
return keccak256(packed);
|
|
31496
|
+
}
|
|
31497
|
+
function compressPublicKey(publicKey) {
|
|
31498
|
+
return secp256k13.ProjectivePoint.fromHex(
|
|
31499
|
+
fromHex5(publicKey, "bytes")
|
|
31500
|
+
).toRawBytes(true);
|
|
31501
|
+
}
|
|
31502
|
+
function sameKey(a, b) {
|
|
31503
|
+
return toHex6(compressPublicKey(a)) === toHex6(compressPublicKey(b));
|
|
31504
|
+
}
|
|
31505
|
+
function assertUncompressedKey(publicKey) {
|
|
31506
|
+
const hex = publicKey.slice(2);
|
|
31507
|
+
if (hex.length !== UNCOMPRESSED_PUBLIC_KEY_BYTES * 2 || !hex.startsWith(UNCOMPRESSED_PUBLIC_KEY_PREFIX) || !/^[0-9a-fA-F]+$/.test(hex)) {
|
|
31508
|
+
throw new Error("Public key must be a 65-byte uncompressed secp256k1 key");
|
|
31509
|
+
}
|
|
31510
|
+
}
|
|
31511
|
+
function appRootPreimage(purpose, publicKey) {
|
|
31512
|
+
const keyHex = toHex6(compressPublicKey(publicKey)).slice(2);
|
|
31513
|
+
return keccak256(toBytes(`${purpose}${PREIMAGE_SEPARATOR}${keyHex}`));
|
|
31514
|
+
}
|
|
31515
|
+
function kmsIssuedPreimage(appId, appRootPublicKey) {
|
|
31516
|
+
const prefix = concat4([
|
|
31517
|
+
toBytes(`${KMS_ISSUED_PREFIX}${PREIMAGE_SEPARATOR}`),
|
|
31518
|
+
fromHex5(appId, "bytes")
|
|
31519
|
+
]);
|
|
31520
|
+
const compressed = compressPublicKey(appRootPublicKey);
|
|
31521
|
+
return keccak256(concat4([prefix, compressed]));
|
|
31522
|
+
}
|
|
31523
|
+
async function recoverChainKey(hash, signature, link) {
|
|
31524
|
+
try {
|
|
31525
|
+
return (await recoverPublicKey({ hash, signature })).toLowerCase();
|
|
31526
|
+
} catch {
|
|
31527
|
+
throw new Error(`Invalid enclave signature chain link ${link}`);
|
|
31528
|
+
}
|
|
31529
|
+
}
|
|
31530
|
+
async function verifyEnclaveIdentityEvidence(evidence, anchors, expected) {
|
|
31531
|
+
if (evidence.v !== ENCLAVE_IDENTITY_EVIDENCE_VERSION) {
|
|
31532
|
+
throw new Error("Unsupported enclave identity evidence version");
|
|
31533
|
+
}
|
|
31534
|
+
if (!Number.isInteger(evidence.epoch) || evidence.epoch < 1) {
|
|
31535
|
+
throw new Error("Invalid enclave identity epoch");
|
|
31536
|
+
}
|
|
31537
|
+
if (evidence.chainId !== expected.chainId) {
|
|
31538
|
+
throw new Error(
|
|
31539
|
+
"Enclave identity chain ID does not match expected chain ID"
|
|
31540
|
+
);
|
|
31541
|
+
}
|
|
31542
|
+
if (!isAddressEqual(evidence.ownerAddress, expected.ownerAddress)) {
|
|
31543
|
+
throw new Error("Enclave identity owner does not match expected owner");
|
|
31544
|
+
}
|
|
31545
|
+
if (evidence.epoch !== expected.epoch) {
|
|
31546
|
+
throw new Error("Enclave identity epoch does not match expected epoch");
|
|
31547
|
+
}
|
|
31548
|
+
const expectedUserPsId = userPsId(expected.chainId, expected.ownerAddress);
|
|
31549
|
+
if (evidence.userPsId.toLowerCase() !== expectedUserPsId.toLowerCase()) {
|
|
31550
|
+
throw new Error("Enclave userPsId does not match expected identity");
|
|
31551
|
+
}
|
|
31552
|
+
if (evidence.purpose !== ENCLAVE_WALLET_PURPOSE) {
|
|
31553
|
+
throw new Error("Unexpected enclave wallet purpose");
|
|
31554
|
+
}
|
|
31555
|
+
if (anchors.kmsRootPubkey === EMPTY_HEX) {
|
|
31556
|
+
throw new Error("KMS root trust anchor is not provisioned");
|
|
31557
|
+
}
|
|
31558
|
+
assertUncompressedKey(evidence.publicKey);
|
|
31559
|
+
const derivedAddress = publicKeyToAddress(evidence.publicKey);
|
|
31560
|
+
if (getAddress(derivedAddress) !== getAddress(evidence.address)) {
|
|
31561
|
+
throw new Error("Enclave public key does not match its address");
|
|
31562
|
+
}
|
|
31563
|
+
const appRootPublicKey = await recoverChainKey(
|
|
31564
|
+
appRootPreimage(evidence.purpose, evidence.publicKey),
|
|
31565
|
+
evidence.signatureChain[0],
|
|
31566
|
+
0
|
|
31567
|
+
);
|
|
31568
|
+
const kmsRootPublicKey = await recoverChainKey(
|
|
31569
|
+
kmsIssuedPreimage(evidence.appId, appRootPublicKey),
|
|
31570
|
+
evidence.signatureChain[1],
|
|
31571
|
+
1
|
|
31572
|
+
);
|
|
31573
|
+
let matchesAnchor;
|
|
31574
|
+
try {
|
|
31575
|
+
matchesAnchor = sameKey(kmsRootPublicKey, anchors.kmsRootPubkey);
|
|
31576
|
+
} catch {
|
|
31577
|
+
throw new Error("KMS root trust anchor is malformed");
|
|
31578
|
+
}
|
|
31579
|
+
if (!matchesAnchor) {
|
|
31580
|
+
throw new Error("KMS root public key does not match the trust anchor");
|
|
31581
|
+
}
|
|
31582
|
+
if (keccak256(kmsRootPublicKey) !== evidence.kmsRootFingerprint.toLowerCase()) {
|
|
31583
|
+
throw new Error("KMS root fingerprint does not match the evidence");
|
|
31584
|
+
}
|
|
31585
|
+
const appId = evidence.appId.toLowerCase();
|
|
31586
|
+
if (!anchors.appIds.some((allowedAppId) => allowedAppId.toLowerCase() === appId)) {
|
|
31587
|
+
throw new Error("Enclave app ID is not trusted");
|
|
31588
|
+
}
|
|
31589
|
+
}
|
|
31590
|
+
async function buildMasterSignatureDelivery(evidence, masterSignature, now = Math.floor(Date.now() / 1e3)) {
|
|
31591
|
+
deriveMasterKey(masterSignature);
|
|
31592
|
+
const signerAddress = await recoverServerOwner(masterSignature);
|
|
31593
|
+
if (!isAddressEqual(signerAddress, evidence.ownerAddress)) {
|
|
31594
|
+
throw new Error("Master signature signer does not match evidence owner");
|
|
31595
|
+
}
|
|
31596
|
+
return {
|
|
31597
|
+
v: MASTER_SIGNATURE_DELIVERY_VERSION,
|
|
31598
|
+
userPsId: evidence.userPsId,
|
|
31599
|
+
epoch: evidence.epoch,
|
|
31600
|
+
enclaveAddress: evidence.address,
|
|
31601
|
+
ownerAddress: evidence.ownerAddress,
|
|
31602
|
+
masterSignature,
|
|
31603
|
+
issuedAt: now
|
|
31604
|
+
};
|
|
31605
|
+
}
|
|
31606
|
+
async function encryptMasterSignatureDelivery(delivery, publicKey, ecies) {
|
|
31607
|
+
assertUncompressedKey(publicKey);
|
|
31608
|
+
if (!isAddressEqual(publicKeyToAddress(publicKey), delivery.enclaveAddress)) {
|
|
31609
|
+
throw new Error(
|
|
31610
|
+
"Public key does not belong to the delivery's enclave address"
|
|
31611
|
+
);
|
|
31612
|
+
}
|
|
31613
|
+
const plaintext = toBytes(JSON.stringify(delivery));
|
|
31614
|
+
const encrypted = await ecies.encrypt(fromHex5(publicKey, "bytes"), plaintext);
|
|
31615
|
+
return `0x${serializeECIES(encrypted)}`;
|
|
31616
|
+
}
|
|
31617
|
+
|
|
31618
|
+
// src/protocol/jobs.ts
|
|
31619
|
+
var JOB_PROTOCOL_VERSION = 1;
|
|
31620
|
+
var JOB_OPERATIONS = ["raw_read", "inference"];
|
|
31621
|
+
var JOB_STATES = [
|
|
31622
|
+
"queued",
|
|
31623
|
+
"claimed",
|
|
31624
|
+
"running",
|
|
31625
|
+
"completed",
|
|
31626
|
+
"failed",
|
|
31627
|
+
"expired",
|
|
31628
|
+
"cancelled"
|
|
31629
|
+
];
|
|
31630
|
+
var DEFAULT_LEASE_SECONDS = 30;
|
|
31631
|
+
var MAX_LEASE_SECONDS = 300;
|
|
31632
|
+
var MAX_ATTEMPTS = 3;
|
|
31633
|
+
var MAX_WAIT_SECONDS = 25;
|
|
31634
|
+
var CLAIM_POLL_FLOOR_MS = 1e3;
|
|
31635
|
+
var DEFAULT_JOB_DEADLINE_SECONDS = 600;
|
|
31636
|
+
var MAX_JOB_DEADLINE_SECONDS = 3600;
|
|
31637
|
+
|
|
31638
|
+
// src/crypto/envelope/job.ts
|
|
31639
|
+
init_constants();
|
|
31640
|
+
init_interface();
|
|
31641
|
+
import { sha256 as sha2565 } from "@noble/hashes/sha2";
|
|
31642
|
+
import { bytesToHex as bytesToHex2, fromHex as fromHex6, isAddress, isHex, toHex as toHex7 } from "viem";
|
|
31643
|
+
var textDecoder = new TextDecoder();
|
|
31644
|
+
var textEncoder = new TextEncoder();
|
|
31645
|
+
var MAX_JOB_RESULT_HEADER_BYTES = 4096;
|
|
31646
|
+
var WRAPPED_KEY_LENGTH_BYTES = 4;
|
|
31647
|
+
var FRAME_LENGTH_BYTES = 4;
|
|
31648
|
+
var FRAME_FLAGS_BYTES = 1;
|
|
31649
|
+
var AES_KEY_BYTES = 32;
|
|
31650
|
+
var AES_GCM_NONCE_BYTES = 12;
|
|
31651
|
+
var AES_GCM_TAG_BYTES = 16;
|
|
31652
|
+
var WRAPPED_METADATA_LENGTH_BYTES = 4;
|
|
31653
|
+
var WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES = AES_KEY_BYTES + AES_GCM_NONCE_BYTES + WRAPPED_METADATA_LENGTH_BYTES;
|
|
31654
|
+
var MAX_WRAPPED_KEY_BYTES = 8192;
|
|
31655
|
+
var FINAL_FRAME_FLAG = 1;
|
|
31656
|
+
var MAX_CHUNK_INDEX = 4294967295;
|
|
31657
|
+
var JOB_RESULT_FORMAT_VERSION = 2;
|
|
31658
|
+
var JOB_RESULT_CHUNK_BYTES = 1024 * 1024;
|
|
31659
|
+
var JobEnvelopeError = class extends Error {
|
|
31660
|
+
constructor(message) {
|
|
31661
|
+
super(message);
|
|
31662
|
+
this.name = "JobEnvelopeError";
|
|
31663
|
+
}
|
|
31664
|
+
};
|
|
31665
|
+
function sortJsonKeys(value) {
|
|
31666
|
+
if (Array.isArray(value)) {
|
|
31667
|
+
return value.map(sortJsonKeys);
|
|
31668
|
+
}
|
|
31669
|
+
if (value !== null && typeof value === "object") {
|
|
31670
|
+
return Object.fromEntries(
|
|
31671
|
+
Object.keys(value).sort().map((key) => [
|
|
31672
|
+
key,
|
|
31673
|
+
sortJsonKeys(value[key])
|
|
31674
|
+
])
|
|
31675
|
+
);
|
|
31676
|
+
}
|
|
31677
|
+
return value;
|
|
31678
|
+
}
|
|
31679
|
+
function canonicalJsonBytes(value) {
|
|
31680
|
+
return textEncoder.encode(JSON.stringify(sortJsonKeys(value)));
|
|
31681
|
+
}
|
|
31682
|
+
function canonicalJobRequestBytes(request) {
|
|
31683
|
+
validateJobRequest(request);
|
|
31684
|
+
return canonicalJsonBytes(request);
|
|
31685
|
+
}
|
|
31686
|
+
function requestPlaintext(envelope) {
|
|
31687
|
+
validateRequestEnvelope(envelope);
|
|
31688
|
+
return canonicalJsonBytes(envelope);
|
|
31689
|
+
}
|
|
31690
|
+
function resultMetadata(result) {
|
|
31691
|
+
return {
|
|
31692
|
+
v: result.v,
|
|
31693
|
+
jobId: result.jobId,
|
|
31694
|
+
scope: result.scope,
|
|
31695
|
+
version: result.version,
|
|
31696
|
+
contentType: result.contentType
|
|
31697
|
+
};
|
|
31698
|
+
}
|
|
31699
|
+
function encryptedBytesToBase64(encrypted) {
|
|
31700
|
+
return toBase64(fromHex6(`0x${serializeECIES(encrypted)}`, "bytes"));
|
|
31701
|
+
}
|
|
31702
|
+
function encryptedToBytes(encrypted) {
|
|
31703
|
+
const bytes = new Uint8Array(
|
|
31704
|
+
encrypted.iv.length + encrypted.ephemPublicKey.length + encrypted.ciphertext.length + encrypted.mac.length
|
|
31705
|
+
);
|
|
31706
|
+
let offset = 0;
|
|
31707
|
+
bytes.set(encrypted.iv, offset);
|
|
31708
|
+
offset += encrypted.iv.length;
|
|
31709
|
+
bytes.set(encrypted.ephemPublicKey, offset);
|
|
31710
|
+
offset += encrypted.ephemPublicKey.length;
|
|
31711
|
+
bytes.set(encrypted.ciphertext, offset);
|
|
31712
|
+
offset += encrypted.ciphertext.length;
|
|
31713
|
+
bytes.set(encrypted.mac, offset);
|
|
31714
|
+
return bytes;
|
|
31715
|
+
}
|
|
31716
|
+
function bytesToEncrypted(bytes) {
|
|
31717
|
+
const absoluteMinLength = FORMAT.IV_LENGTH + 1 + MAC.LENGTH + 1;
|
|
31718
|
+
if (bytes.length < absoluteMinLength) {
|
|
31719
|
+
throw new ECIESError(
|
|
31720
|
+
`Invalid ECIES data: too short (${bytes.length} bytes, minimum ${absoluteMinLength} bytes required)`,
|
|
31721
|
+
"DECRYPTION_FAILED"
|
|
31722
|
+
);
|
|
31723
|
+
}
|
|
31724
|
+
const prefix = bytes[FORMAT.EPHEMERAL_KEY_OFFSET];
|
|
31725
|
+
if (prefix !== CURVE.PREFIX.UNCOMPRESSED) {
|
|
31726
|
+
throw new ECIESError(
|
|
31727
|
+
`Invalid ephemeral public key: must be uncompressed format (0x04 prefix), got 0x${prefix.toString(16).padStart(2, "0")}`,
|
|
31728
|
+
"DECRYPTION_FAILED"
|
|
31729
|
+
);
|
|
31730
|
+
}
|
|
31731
|
+
const ephemKeySize = CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH;
|
|
31732
|
+
const minLength = FORMAT.IV_LENGTH + ephemKeySize + MAC.LENGTH + 1;
|
|
31733
|
+
if (bytes.length < minLength) {
|
|
31734
|
+
throw new ECIESError(
|
|
31735
|
+
`Invalid ECIES data: too short (${bytes.length} bytes, minimum ${minLength} bytes required)`,
|
|
31736
|
+
"DECRYPTION_FAILED"
|
|
31737
|
+
);
|
|
31738
|
+
}
|
|
31739
|
+
return {
|
|
31740
|
+
iv: bytes.subarray(FORMAT.IV_OFFSET, FORMAT.IV_OFFSET + FORMAT.IV_LENGTH),
|
|
31741
|
+
ephemPublicKey: bytes.subarray(
|
|
31742
|
+
FORMAT.EPHEMERAL_KEY_OFFSET,
|
|
31743
|
+
FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize
|
|
31744
|
+
),
|
|
31745
|
+
ciphertext: bytes.subarray(
|
|
31746
|
+
FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize,
|
|
31747
|
+
bytes.length - MAC.LENGTH
|
|
31748
|
+
),
|
|
31749
|
+
mac: bytes.subarray(bytes.length - MAC.LENGTH)
|
|
31750
|
+
};
|
|
31751
|
+
}
|
|
31752
|
+
function base64ToEncrypted(ciphertext) {
|
|
31753
|
+
return deserializeECIES(toHex7(fromBase64(ciphertext)));
|
|
31754
|
+
}
|
|
31755
|
+
function parseObject(plaintext, kind) {
|
|
31756
|
+
try {
|
|
31757
|
+
const value = JSON.parse(textDecoder.decode(plaintext));
|
|
31758
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
31759
|
+
throw new JobEnvelopeError(`Invalid ${kind}: expected an object`);
|
|
31760
|
+
}
|
|
31761
|
+
return value;
|
|
31762
|
+
} catch (error) {
|
|
31763
|
+
if (error instanceof JobEnvelopeError) throw error;
|
|
31764
|
+
throw new JobEnvelopeError(`Invalid ${kind}: malformed JSON`);
|
|
31765
|
+
}
|
|
31766
|
+
}
|
|
31767
|
+
function isPlainObject2(value) {
|
|
31768
|
+
if (value === null || typeof value !== "object") return false;
|
|
31769
|
+
const prototype = Object.getPrototypeOf(value);
|
|
31770
|
+
return prototype === Object.prototype || prototype === null;
|
|
31771
|
+
}
|
|
31772
|
+
function requirePlainObject(value, field, kind) {
|
|
31773
|
+
if (!isPlainObject2(value)) {
|
|
31774
|
+
throw new JobEnvelopeError(`Invalid ${kind}: invalid ${field}`);
|
|
31775
|
+
}
|
|
31776
|
+
}
|
|
31777
|
+
function requireExactKeys(value, expectedKeys, kind) {
|
|
31778
|
+
for (const key of expectedKeys) {
|
|
31779
|
+
if (!Object.hasOwn(value, key) || value[key] === void 0) {
|
|
31780
|
+
throw new JobEnvelopeError(`Invalid ${kind}: missing ${key}`);
|
|
31781
|
+
}
|
|
31782
|
+
}
|
|
31783
|
+
const expected = new Set(expectedKeys);
|
|
31784
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
31785
|
+
if (!expected.has(key)) {
|
|
31786
|
+
throw new JobEnvelopeError(
|
|
31787
|
+
`Invalid ${kind}: unknown field ${String(key)}`
|
|
31788
|
+
);
|
|
31789
|
+
}
|
|
31790
|
+
}
|
|
31791
|
+
}
|
|
31792
|
+
function requireString(value, field, kind) {
|
|
31793
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
31794
|
+
throw new JobEnvelopeError(`Invalid ${kind}: missing ${field}`);
|
|
31795
|
+
}
|
|
31796
|
+
}
|
|
31797
|
+
function validateJobRequest(value) {
|
|
31798
|
+
requirePlainObject(value, "request", "job request");
|
|
31799
|
+
requireExactKeys(
|
|
31800
|
+
value,
|
|
31801
|
+
[
|
|
31802
|
+
"v",
|
|
31803
|
+
"jobId",
|
|
31804
|
+
"owner",
|
|
31805
|
+
"builder",
|
|
31806
|
+
"builderPublicKey",
|
|
31807
|
+
"grantId",
|
|
31808
|
+
"scope",
|
|
31809
|
+
"operation",
|
|
31810
|
+
"pinnedVersion",
|
|
31811
|
+
"deadline"
|
|
31812
|
+
],
|
|
31813
|
+
"job request"
|
|
31814
|
+
);
|
|
31815
|
+
if (value.v !== JOB_PROTOCOL_VERSION) {
|
|
31816
|
+
throw new JobEnvelopeError(
|
|
31817
|
+
`Unsupported job request version: ${String(value.v)}`
|
|
31818
|
+
);
|
|
31819
|
+
}
|
|
31820
|
+
requireString(value.jobId, "jobId", "job request");
|
|
31821
|
+
if (typeof value.owner !== "string" || !isAddress(value.owner)) {
|
|
31822
|
+
throw new JobEnvelopeError("Invalid job request: invalid owner");
|
|
31823
|
+
}
|
|
31824
|
+
if (typeof value.builder !== "string" || !isAddress(value.builder)) {
|
|
31825
|
+
throw new JobEnvelopeError("Invalid job request: invalid builder");
|
|
31826
|
+
}
|
|
31827
|
+
if (typeof value.builderPublicKey !== "string" || !isHex(value.builderPublicKey)) {
|
|
31828
|
+
throw new JobEnvelopeError("Invalid job request: invalid builderPublicKey");
|
|
31829
|
+
}
|
|
31830
|
+
if (typeof value.grantId !== "string" || !isHex(value.grantId)) {
|
|
31831
|
+
throw new JobEnvelopeError("Invalid job request: invalid grantId");
|
|
31832
|
+
}
|
|
31833
|
+
requireString(value.scope, "scope", "job request");
|
|
31834
|
+
if (!JOB_OPERATIONS.includes(value.operation)) {
|
|
31835
|
+
throw new JobEnvelopeError("Invalid job request: invalid operation");
|
|
31836
|
+
}
|
|
31837
|
+
if (value.pinnedVersion !== null && typeof value.pinnedVersion !== "string") {
|
|
31838
|
+
throw new JobEnvelopeError("Invalid job request: missing pinnedVersion");
|
|
31839
|
+
}
|
|
31840
|
+
if (typeof value.deadline !== "string" || !Number.isFinite(Date.parse(value.deadline))) {
|
|
31841
|
+
throw new JobEnvelopeError("Invalid job request: invalid deadline");
|
|
31842
|
+
}
|
|
31843
|
+
return value;
|
|
31844
|
+
}
|
|
31845
|
+
function validateRequestEnvelope(value) {
|
|
31846
|
+
requirePlainObject(value, "envelope", "job request envelope");
|
|
31847
|
+
requireExactKeys(value, ["request", "auth"], "job request envelope");
|
|
31848
|
+
validateJobRequest(value.request);
|
|
31849
|
+
requireString(value.auth, "auth", "job request envelope");
|
|
31850
|
+
return value;
|
|
31851
|
+
}
|
|
31852
|
+
function validateResultMetadata(value) {
|
|
31853
|
+
requirePlainObject(value, "metadata", "job result");
|
|
31854
|
+
requireExactKeys(
|
|
31855
|
+
value,
|
|
31856
|
+
["v", "jobId", "scope", "version", "contentType"],
|
|
31857
|
+
"job result"
|
|
31858
|
+
);
|
|
31859
|
+
if (value.v !== JOB_PROTOCOL_VERSION) {
|
|
31860
|
+
throw new JobEnvelopeError(
|
|
31861
|
+
`Unsupported job result version: ${String(value.v)}`
|
|
31862
|
+
);
|
|
31863
|
+
}
|
|
31864
|
+
for (const field of ["jobId", "scope", "contentType"]) {
|
|
31865
|
+
requireString(value[field], field, "job result");
|
|
31866
|
+
}
|
|
31867
|
+
if (value.version !== null && typeof value.version !== "string") {
|
|
31868
|
+
throw new JobEnvelopeError("Invalid job result: missing version");
|
|
31869
|
+
}
|
|
31870
|
+
return value;
|
|
31871
|
+
}
|
|
31872
|
+
function validateResult(value) {
|
|
31873
|
+
requirePlainObject(value, "result", "job result");
|
|
31874
|
+
requireExactKeys(
|
|
31875
|
+
value,
|
|
31876
|
+
["v", "jobId", "scope", "version", "contentType", "body"],
|
|
31877
|
+
"job result"
|
|
31878
|
+
);
|
|
31879
|
+
validateResultMetadata(resultMetadata(value));
|
|
31880
|
+
if (!(value.body instanceof Uint8Array)) {
|
|
31881
|
+
throw new JobEnvelopeError("Invalid job result: missing body");
|
|
31882
|
+
}
|
|
31883
|
+
return value;
|
|
31884
|
+
}
|
|
31885
|
+
function webCrypto() {
|
|
31886
|
+
if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.getRandomValues !== "function" || !globalThis.crypto.subtle) {
|
|
31887
|
+
throw new JobEnvelopeError(
|
|
31888
|
+
"Job result streaming requires the Web Crypto API"
|
|
31889
|
+
);
|
|
31890
|
+
}
|
|
31891
|
+
return globalThis.crypto;
|
|
31892
|
+
}
|
|
31893
|
+
function uint32(value) {
|
|
31894
|
+
const bytes = new Uint8Array(4);
|
|
31895
|
+
new DataView(bytes.buffer).setUint32(0, value);
|
|
31896
|
+
return bytes;
|
|
31897
|
+
}
|
|
31898
|
+
function readUint32(bytes, offset = 0) {
|
|
31899
|
+
return new DataView(bytes.buffer, bytes.byteOffset + offset, 4).getUint32(0);
|
|
31900
|
+
}
|
|
31901
|
+
function wrappedKeyPlaintext(contentKey, noncePrefix, metadataBytes) {
|
|
31902
|
+
const plaintext = new Uint8Array(
|
|
31903
|
+
WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES + metadataBytes.length
|
|
31904
|
+
);
|
|
31905
|
+
plaintext.set(contentKey, 0);
|
|
31906
|
+
plaintext.set(noncePrefix, AES_KEY_BYTES);
|
|
31907
|
+
new DataView(plaintext.buffer).setUint32(
|
|
31908
|
+
AES_KEY_BYTES + AES_GCM_NONCE_BYTES,
|
|
31909
|
+
metadataBytes.length
|
|
31910
|
+
);
|
|
31911
|
+
plaintext.set(metadataBytes, WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES);
|
|
31912
|
+
return plaintext;
|
|
31913
|
+
}
|
|
31914
|
+
function parseWrappedKeyPlaintext(plaintext) {
|
|
31915
|
+
if (plaintext.length < WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES) {
|
|
31916
|
+
throw new JobEnvelopeError("Invalid job result: wrapped key is truncated");
|
|
31917
|
+
}
|
|
31918
|
+
const metadataLength = readUint32(
|
|
31919
|
+
plaintext,
|
|
31920
|
+
AES_KEY_BYTES + AES_GCM_NONCE_BYTES
|
|
31921
|
+
);
|
|
31922
|
+
if (metadataLength > MAX_JOB_RESULT_HEADER_BYTES) {
|
|
31923
|
+
throw new JobEnvelopeError(
|
|
31924
|
+
`Invalid job result: header exceeds ${MAX_JOB_RESULT_HEADER_BYTES} bytes`
|
|
31925
|
+
);
|
|
31926
|
+
}
|
|
31927
|
+
if (plaintext.length !== WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES + metadataLength) {
|
|
31928
|
+
throw new JobEnvelopeError(
|
|
31929
|
+
"Invalid job result: header length exceeds payload"
|
|
31930
|
+
);
|
|
31931
|
+
}
|
|
31932
|
+
const metadataBytes = plaintext.slice(WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES);
|
|
31933
|
+
const metadata = validateResultMetadata(
|
|
31934
|
+
parseObject(metadataBytes, "job result header")
|
|
31935
|
+
);
|
|
31936
|
+
return {
|
|
31937
|
+
contentKey: plaintext.slice(0, AES_KEY_BYTES),
|
|
31938
|
+
noncePrefix: plaintext.slice(
|
|
31939
|
+
AES_KEY_BYTES,
|
|
31940
|
+
AES_KEY_BYTES + AES_GCM_NONCE_BYTES
|
|
31941
|
+
),
|
|
31942
|
+
metadataBytes,
|
|
31943
|
+
metadata
|
|
31944
|
+
};
|
|
31945
|
+
}
|
|
31946
|
+
async function importAesKey(contentKey, usage) {
|
|
31947
|
+
return webCrypto().subtle.importKey(
|
|
31948
|
+
"raw",
|
|
31949
|
+
contentKey,
|
|
31950
|
+
{ name: "AES-GCM" },
|
|
31951
|
+
false,
|
|
31952
|
+
[usage]
|
|
31953
|
+
);
|
|
31954
|
+
}
|
|
31955
|
+
function chunkNonce(noncePrefix, chunkIndex) {
|
|
31956
|
+
if (chunkIndex > MAX_CHUNK_INDEX) {
|
|
31957
|
+
throw new JobEnvelopeError("Invalid job result: too many chunks");
|
|
31958
|
+
}
|
|
31959
|
+
const nonce = noncePrefix.slice();
|
|
31960
|
+
const view = new DataView(nonce.buffer, nonce.byteOffset, nonce.byteLength);
|
|
31961
|
+
view.setUint32(8, view.getUint32(8) ^ chunkIndex);
|
|
31962
|
+
return nonce;
|
|
31963
|
+
}
|
|
31964
|
+
function chunkAad(metadataBytes, chunkIndex, final, plaintextLength) {
|
|
31965
|
+
const aad = new Uint8Array(14 + metadataBytes.length);
|
|
31966
|
+
aad[0] = JOB_RESULT_FORMAT_VERSION;
|
|
31967
|
+
aad.set(uint32(metadataBytes.length), 1);
|
|
31968
|
+
aad.set(metadataBytes, 5);
|
|
31969
|
+
aad.set(uint32(chunkIndex), 5 + metadataBytes.length);
|
|
31970
|
+
aad[9 + metadataBytes.length] = final ? FINAL_FRAME_FLAG : 0;
|
|
31971
|
+
aad.set(uint32(plaintextLength), 10 + metadataBytes.length);
|
|
31972
|
+
return aad;
|
|
31973
|
+
}
|
|
31974
|
+
async function encryptResultChunk(key, noncePrefix, metadataBytes, plaintext, chunkIndex, final) {
|
|
31975
|
+
const encrypted = new Uint8Array(
|
|
31976
|
+
await webCrypto().subtle.encrypt(
|
|
31977
|
+
{
|
|
31978
|
+
name: "AES-GCM",
|
|
31979
|
+
iv: chunkNonce(noncePrefix, chunkIndex),
|
|
31980
|
+
additionalData: chunkAad(
|
|
31981
|
+
metadataBytes,
|
|
31982
|
+
chunkIndex,
|
|
31983
|
+
final,
|
|
31984
|
+
plaintext.length
|
|
31985
|
+
),
|
|
31986
|
+
tagLength: AES_GCM_TAG_BYTES * 8
|
|
31987
|
+
},
|
|
31988
|
+
key,
|
|
31989
|
+
plaintext
|
|
31990
|
+
)
|
|
31991
|
+
);
|
|
31992
|
+
const frame = new Uint8Array(
|
|
31993
|
+
FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES + encrypted.length
|
|
31994
|
+
);
|
|
31995
|
+
new DataView(frame.buffer).setUint32(0, encrypted.length);
|
|
31996
|
+
frame[FRAME_LENGTH_BYTES] = final ? FINAL_FRAME_FLAG : 0;
|
|
31997
|
+
frame.set(encrypted, FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES);
|
|
31998
|
+
return frame;
|
|
31999
|
+
}
|
|
32000
|
+
function verifyResultBindings(metadata, expect) {
|
|
32001
|
+
if (metadata.jobId !== expect.jobId) {
|
|
32002
|
+
throw new JobEnvelopeError(
|
|
32003
|
+
`Job result ID ${metadata.jobId} does not match expected job ID ${expect.jobId}`
|
|
32004
|
+
);
|
|
32005
|
+
}
|
|
32006
|
+
if (expect.scope !== void 0 && metadata.scope !== expect.scope) {
|
|
32007
|
+
throw new JobEnvelopeError(
|
|
32008
|
+
`Job result scope ${metadata.scope} does not match expected scope ${expect.scope}`
|
|
32009
|
+
);
|
|
32010
|
+
}
|
|
32011
|
+
if (expect.version !== void 0 && metadata.version !== expect.version) {
|
|
32012
|
+
throw new JobEnvelopeError(
|
|
32013
|
+
`Job result version ${String(metadata.version)} does not match expected version ${String(expect.version)}`
|
|
32014
|
+
);
|
|
32015
|
+
}
|
|
32016
|
+
}
|
|
32017
|
+
var ByteStreamReader = class {
|
|
32018
|
+
reader;
|
|
32019
|
+
current;
|
|
32020
|
+
offset = 0;
|
|
32021
|
+
ended = false;
|
|
32022
|
+
constructor(stream) {
|
|
32023
|
+
this.reader = stream.getReader();
|
|
32024
|
+
}
|
|
32025
|
+
async ensureBytes() {
|
|
32026
|
+
while (!this.current || this.offset === this.current.length) {
|
|
32027
|
+
if (this.ended) return false;
|
|
32028
|
+
const next = await this.reader.read();
|
|
32029
|
+
if (next.done) {
|
|
32030
|
+
this.ended = true;
|
|
32031
|
+
this.current = void 0;
|
|
32032
|
+
return false;
|
|
32033
|
+
}
|
|
32034
|
+
if (!(next.value instanceof Uint8Array)) {
|
|
32035
|
+
throw new JobEnvelopeError(
|
|
32036
|
+
"Invalid job result: stream yielded non-byte data"
|
|
32037
|
+
);
|
|
32038
|
+
}
|
|
32039
|
+
this.current = next.value;
|
|
32040
|
+
this.offset = 0;
|
|
32041
|
+
}
|
|
32042
|
+
return true;
|
|
32043
|
+
}
|
|
32044
|
+
async readExactOrNull(length) {
|
|
32045
|
+
if (!await this.ensureBytes()) return null;
|
|
32046
|
+
const bytes = new Uint8Array(length);
|
|
32047
|
+
let written = 0;
|
|
32048
|
+
while (written < length) {
|
|
32049
|
+
if (!await this.ensureBytes()) {
|
|
32050
|
+
throw new JobEnvelopeError("Invalid job result: truncated payload");
|
|
32051
|
+
}
|
|
32052
|
+
const available = this.current.length - this.offset;
|
|
32053
|
+
const count = Math.min(available, length - written);
|
|
32054
|
+
bytes.set(
|
|
32055
|
+
this.current.subarray(this.offset, this.offset + count),
|
|
32056
|
+
written
|
|
32057
|
+
);
|
|
32058
|
+
this.offset += count;
|
|
32059
|
+
written += count;
|
|
32060
|
+
}
|
|
32061
|
+
return bytes;
|
|
32062
|
+
}
|
|
32063
|
+
async readExact(length) {
|
|
32064
|
+
const bytes = await this.readExactOrNull(length);
|
|
32065
|
+
if (!bytes) {
|
|
32066
|
+
throw new JobEnvelopeError("Invalid job result: truncated payload");
|
|
32067
|
+
}
|
|
32068
|
+
return bytes;
|
|
32069
|
+
}
|
|
32070
|
+
async hasRemaining() {
|
|
32071
|
+
return this.ensureBytes();
|
|
32072
|
+
}
|
|
32073
|
+
async cancel(reason) {
|
|
32074
|
+
await this.reader.cancel(reason);
|
|
32075
|
+
}
|
|
32076
|
+
};
|
|
32077
|
+
function normalizeChunkError(error) {
|
|
32078
|
+
if (error instanceof JobEnvelopeError) return error;
|
|
32079
|
+
return new JobEnvelopeError(
|
|
32080
|
+
`Invalid job result: chunk authentication failed${error instanceof Error ? `: ${error.message}` : ""}`
|
|
32081
|
+
);
|
|
32082
|
+
}
|
|
32083
|
+
async function sealJobRequest(envelope, enclavePublicKey, ecies) {
|
|
32084
|
+
const encrypted = await ecies.encrypt(
|
|
32085
|
+
fromHex6(enclavePublicKey, "bytes"),
|
|
32086
|
+
requestPlaintext(envelope)
|
|
32087
|
+
);
|
|
32088
|
+
return encryptedBytesToBase64(encrypted);
|
|
32089
|
+
}
|
|
32090
|
+
async function openJobRequest(ciphertext, privateKey, ecies) {
|
|
32091
|
+
const plaintext = await ecies.decrypt(
|
|
32092
|
+
privateKey,
|
|
32093
|
+
base64ToEncrypted(ciphertext)
|
|
32094
|
+
);
|
|
32095
|
+
return validateRequestEnvelope(
|
|
32096
|
+
parseObject(plaintext, "job request envelope")
|
|
32097
|
+
);
|
|
32098
|
+
}
|
|
32099
|
+
async function sealJobResultStream(metadataValue, builderPublicKey, ecies) {
|
|
32100
|
+
const metadata = validateResultMetadata(metadataValue);
|
|
32101
|
+
const metadataBytes = canonicalJsonBytes(metadata);
|
|
32102
|
+
if (metadataBytes.length > MAX_JOB_RESULT_HEADER_BYTES) {
|
|
32103
|
+
throw new JobEnvelopeError(
|
|
32104
|
+
`Invalid job result: header exceeds ${MAX_JOB_RESULT_HEADER_BYTES} bytes`
|
|
32105
|
+
);
|
|
32106
|
+
}
|
|
32107
|
+
const crypto2 = webCrypto();
|
|
32108
|
+
const contentKey = crypto2.getRandomValues(new Uint8Array(AES_KEY_BYTES));
|
|
32109
|
+
const noncePrefix = crypto2.getRandomValues(
|
|
32110
|
+
new Uint8Array(AES_GCM_NONCE_BYTES)
|
|
32111
|
+
);
|
|
32112
|
+
const key = await importAesKey(contentKey, "encrypt");
|
|
32113
|
+
const keyPlaintext = wrappedKeyPlaintext(
|
|
32114
|
+
contentKey,
|
|
32115
|
+
noncePrefix,
|
|
32116
|
+
metadataBytes
|
|
32117
|
+
);
|
|
32118
|
+
const encryptedKey = await ecies.encrypt(
|
|
32119
|
+
fromHex6(builderPublicKey, "bytes"),
|
|
32120
|
+
keyPlaintext
|
|
32121
|
+
);
|
|
32122
|
+
contentKey.fill(0);
|
|
32123
|
+
keyPlaintext.fill(0);
|
|
32124
|
+
const wrappedKey = encryptedToBytes(encryptedKey);
|
|
32125
|
+
if (wrappedKey.length > MAX_WRAPPED_KEY_BYTES) {
|
|
32126
|
+
throw new JobEnvelopeError("Invalid job result: wrapped key is too large");
|
|
32127
|
+
}
|
|
32128
|
+
const header = new Uint8Array(
|
|
32129
|
+
1 + WRAPPED_KEY_LENGTH_BYTES + wrappedKey.length
|
|
32130
|
+
);
|
|
32131
|
+
header[0] = JOB_RESULT_FORMAT_VERSION;
|
|
32132
|
+
new DataView(header.buffer).setUint32(1, wrappedKey.length);
|
|
32133
|
+
header.set(wrappedKey, 1 + WRAPPED_KEY_LENGTH_BYTES);
|
|
32134
|
+
let pending = new Uint8Array(JOB_RESULT_CHUNK_BYTES);
|
|
32135
|
+
let pendingLength = 0;
|
|
32136
|
+
let chunkIndex = 0;
|
|
32137
|
+
const transform = new TransformStream({
|
|
32138
|
+
async transform(chunk, controller) {
|
|
32139
|
+
if (!(chunk instanceof Uint8Array)) {
|
|
32140
|
+
throw new JobEnvelopeError(
|
|
32141
|
+
"Invalid job result: stream yielded non-byte data"
|
|
32142
|
+
);
|
|
32143
|
+
}
|
|
32144
|
+
let offset = 0;
|
|
32145
|
+
while (offset < chunk.length) {
|
|
32146
|
+
if (pendingLength === JOB_RESULT_CHUNK_BYTES) {
|
|
32147
|
+
controller.enqueue(
|
|
32148
|
+
await encryptResultChunk(
|
|
32149
|
+
key,
|
|
32150
|
+
noncePrefix,
|
|
32151
|
+
metadataBytes,
|
|
32152
|
+
pending,
|
|
32153
|
+
chunkIndex,
|
|
32154
|
+
false
|
|
32155
|
+
)
|
|
32156
|
+
);
|
|
32157
|
+
chunkIndex += 1;
|
|
32158
|
+
pending = new Uint8Array(JOB_RESULT_CHUNK_BYTES);
|
|
32159
|
+
pendingLength = 0;
|
|
32160
|
+
}
|
|
32161
|
+
const count = Math.min(
|
|
32162
|
+
chunk.length - offset,
|
|
32163
|
+
JOB_RESULT_CHUNK_BYTES - pendingLength
|
|
32164
|
+
);
|
|
32165
|
+
pending.set(chunk.subarray(offset, offset + count), pendingLength);
|
|
32166
|
+
pendingLength += count;
|
|
32167
|
+
offset += count;
|
|
32168
|
+
}
|
|
32169
|
+
},
|
|
32170
|
+
async flush(controller) {
|
|
32171
|
+
controller.enqueue(
|
|
32172
|
+
await encryptResultChunk(
|
|
32173
|
+
key,
|
|
32174
|
+
noncePrefix,
|
|
32175
|
+
metadataBytes,
|
|
32176
|
+
pending.subarray(0, pendingLength),
|
|
32177
|
+
chunkIndex,
|
|
32178
|
+
true
|
|
32179
|
+
)
|
|
32180
|
+
);
|
|
32181
|
+
}
|
|
32182
|
+
});
|
|
32183
|
+
return { header, transform };
|
|
32184
|
+
}
|
|
32185
|
+
async function sealJobResult(result, builderPublicKey, ecies) {
|
|
32186
|
+
validateResult(result);
|
|
32187
|
+
const sealed = await sealJobResultStream(
|
|
32188
|
+
resultMetadata(result),
|
|
32189
|
+
builderPublicKey,
|
|
32190
|
+
ecies
|
|
32191
|
+
);
|
|
32192
|
+
const frameCount = Math.max(
|
|
32193
|
+
1,
|
|
32194
|
+
Math.ceil(result.body.length / JOB_RESULT_CHUNK_BYTES)
|
|
32195
|
+
);
|
|
32196
|
+
const size = sealed.header.length + result.body.length + frameCount * (FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES + AES_GCM_TAG_BYTES);
|
|
32197
|
+
const bytes = new Uint8Array(size);
|
|
32198
|
+
bytes.set(sealed.header, 0);
|
|
32199
|
+
let outputOffset = sealed.header.length;
|
|
32200
|
+
const reader = sealed.transform.readable.getReader();
|
|
32201
|
+
const drain = (async () => {
|
|
32202
|
+
for (; ; ) {
|
|
32203
|
+
const next = await reader.read();
|
|
32204
|
+
if (next.done) break;
|
|
32205
|
+
bytes.set(next.value, outputOffset);
|
|
32206
|
+
outputOffset += next.value.length;
|
|
32207
|
+
}
|
|
32208
|
+
})();
|
|
32209
|
+
const writer = sealed.transform.writable.getWriter();
|
|
32210
|
+
const fill = (async () => {
|
|
32211
|
+
for (let offset = 0; offset < result.body.length; offset += JOB_RESULT_CHUNK_BYTES) {
|
|
32212
|
+
await writer.write(
|
|
32213
|
+
result.body.subarray(offset, offset + JOB_RESULT_CHUNK_BYTES)
|
|
32214
|
+
);
|
|
32215
|
+
}
|
|
32216
|
+
await writer.close();
|
|
32217
|
+
})();
|
|
32218
|
+
await Promise.all([drain, fill]);
|
|
32219
|
+
if (outputOffset !== bytes.length) {
|
|
32220
|
+
throw new JobEnvelopeError("Invalid job result: sealed size mismatch");
|
|
32221
|
+
}
|
|
32222
|
+
return { bytes, hash: bytesToHex2(sha2565(bytes)), size };
|
|
32223
|
+
}
|
|
32224
|
+
async function openJobResultStream(bytesStream, builderPrivateKey, ecies, expect) {
|
|
32225
|
+
const reader = new ByteStreamReader(bytesStream);
|
|
32226
|
+
const headerPrefix = await reader.readExact(1 + WRAPPED_KEY_LENGTH_BYTES);
|
|
32227
|
+
const formatVersion = headerPrefix[0];
|
|
32228
|
+
if (formatVersion !== JOB_RESULT_FORMAT_VERSION) {
|
|
32229
|
+
throw new JobEnvelopeError(
|
|
32230
|
+
`Unsupported job result format: ${String(formatVersion)}`
|
|
32231
|
+
);
|
|
32232
|
+
}
|
|
32233
|
+
const wrappedKeyLength = readUint32(headerPrefix, 1);
|
|
32234
|
+
if (wrappedKeyLength === 0 || wrappedKeyLength > MAX_WRAPPED_KEY_BYTES) {
|
|
32235
|
+
throw new JobEnvelopeError(
|
|
32236
|
+
"Invalid job result: invalid wrapped key length"
|
|
32237
|
+
);
|
|
32238
|
+
}
|
|
32239
|
+
const wrappedKey = await reader.readExact(wrappedKeyLength);
|
|
32240
|
+
const keyPlaintext = await ecies.decrypt(
|
|
32241
|
+
fromHex6(builderPrivateKey, "bytes"),
|
|
32242
|
+
bytesToEncrypted(wrappedKey)
|
|
32243
|
+
);
|
|
32244
|
+
const parsed = parseWrappedKeyPlaintext(keyPlaintext);
|
|
32245
|
+
verifyResultBindings(parsed.metadata, expect);
|
|
32246
|
+
const key = await importAesKey(parsed.contentKey, "decrypt");
|
|
32247
|
+
parsed.contentKey.fill(0);
|
|
32248
|
+
keyPlaintext.fill(0);
|
|
32249
|
+
let chunkIndex = 0;
|
|
32250
|
+
let finished = false;
|
|
32251
|
+
const body = new ReadableStream({
|
|
32252
|
+
async pull(controller) {
|
|
32253
|
+
if (finished) {
|
|
32254
|
+
controller.close();
|
|
32255
|
+
return;
|
|
32256
|
+
}
|
|
32257
|
+
try {
|
|
32258
|
+
const frameHeader = await reader.readExactOrNull(
|
|
32259
|
+
FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES
|
|
32260
|
+
);
|
|
32261
|
+
if (!frameHeader) {
|
|
32262
|
+
throw new JobEnvelopeError("Invalid job result: missing final chunk");
|
|
32263
|
+
}
|
|
32264
|
+
const encryptedLength = readUint32(frameHeader);
|
|
32265
|
+
if (encryptedLength < AES_GCM_TAG_BYTES || encryptedLength > JOB_RESULT_CHUNK_BYTES + AES_GCM_TAG_BYTES) {
|
|
32266
|
+
throw new JobEnvelopeError(
|
|
32267
|
+
"Invalid job result: invalid chunk length"
|
|
32268
|
+
);
|
|
32269
|
+
}
|
|
32270
|
+
const flags = frameHeader[FRAME_LENGTH_BYTES];
|
|
32271
|
+
if (flags !== 0 && flags !== FINAL_FRAME_FLAG) {
|
|
32272
|
+
throw new JobEnvelopeError("Invalid job result: invalid chunk flags");
|
|
32273
|
+
}
|
|
32274
|
+
const final = flags === FINAL_FRAME_FLAG;
|
|
32275
|
+
const plaintextLength = encryptedLength - AES_GCM_TAG_BYTES;
|
|
32276
|
+
if (!final && plaintextLength !== JOB_RESULT_CHUNK_BYTES) {
|
|
32277
|
+
throw new JobEnvelopeError(
|
|
32278
|
+
"Invalid job result: short non-final chunk"
|
|
32279
|
+
);
|
|
32280
|
+
}
|
|
32281
|
+
const encrypted = await reader.readExact(encryptedLength);
|
|
32282
|
+
const plaintext = new Uint8Array(
|
|
32283
|
+
await webCrypto().subtle.decrypt(
|
|
32284
|
+
{
|
|
32285
|
+
name: "AES-GCM",
|
|
32286
|
+
iv: chunkNonce(parsed.noncePrefix, chunkIndex),
|
|
32287
|
+
additionalData: chunkAad(
|
|
32288
|
+
parsed.metadataBytes,
|
|
32289
|
+
chunkIndex,
|
|
32290
|
+
final,
|
|
32291
|
+
plaintextLength
|
|
32292
|
+
),
|
|
32293
|
+
tagLength: AES_GCM_TAG_BYTES * 8
|
|
32294
|
+
},
|
|
32295
|
+
key,
|
|
32296
|
+
encrypted
|
|
32297
|
+
)
|
|
32298
|
+
);
|
|
32299
|
+
if (plaintext.length !== plaintextLength) {
|
|
32300
|
+
throw new JobEnvelopeError(
|
|
32301
|
+
"Invalid job result: decrypted chunk length mismatch"
|
|
32302
|
+
);
|
|
32303
|
+
}
|
|
32304
|
+
chunkIndex += 1;
|
|
32305
|
+
if (final) {
|
|
32306
|
+
if (await reader.hasRemaining()) {
|
|
32307
|
+
throw new JobEnvelopeError(
|
|
32308
|
+
"Invalid job result: bytes follow final chunk"
|
|
32309
|
+
);
|
|
32310
|
+
}
|
|
32311
|
+
finished = true;
|
|
32312
|
+
}
|
|
32313
|
+
controller.enqueue(plaintext);
|
|
32314
|
+
if (finished) controller.close();
|
|
32315
|
+
} catch (error) {
|
|
32316
|
+
controller.error(normalizeChunkError(error));
|
|
32317
|
+
void reader.cancel(error).catch(() => void 0);
|
|
32318
|
+
}
|
|
32319
|
+
},
|
|
32320
|
+
cancel(reason) {
|
|
32321
|
+
return reader.cancel(reason);
|
|
32322
|
+
}
|
|
32323
|
+
});
|
|
32324
|
+
return { metadata: parsed.metadata, body };
|
|
32325
|
+
}
|
|
32326
|
+
function bufferedResultBodySize(sealedBytes) {
|
|
32327
|
+
if (sealedBytes.length < 1 + WRAPPED_KEY_LENGTH_BYTES) {
|
|
32328
|
+
throw new JobEnvelopeError("Invalid job result: truncated payload");
|
|
32329
|
+
}
|
|
32330
|
+
if (sealedBytes[0] !== JOB_RESULT_FORMAT_VERSION) {
|
|
32331
|
+
throw new JobEnvelopeError(
|
|
32332
|
+
`Unsupported job result format: ${String(sealedBytes[0])}`
|
|
32333
|
+
);
|
|
32334
|
+
}
|
|
32335
|
+
const wrappedKeyLength = readUint32(sealedBytes, 1);
|
|
32336
|
+
if (wrappedKeyLength === 0 || wrappedKeyLength > MAX_WRAPPED_KEY_BYTES) {
|
|
32337
|
+
throw new JobEnvelopeError(
|
|
32338
|
+
"Invalid job result: invalid wrapped key length"
|
|
32339
|
+
);
|
|
32340
|
+
}
|
|
32341
|
+
let offset = 1 + WRAPPED_KEY_LENGTH_BYTES + wrappedKeyLength;
|
|
32342
|
+
if (offset > sealedBytes.length) {
|
|
32343
|
+
throw new JobEnvelopeError("Invalid job result: truncated payload");
|
|
32344
|
+
}
|
|
32345
|
+
let bodySize = 0;
|
|
32346
|
+
let sawFinal = false;
|
|
32347
|
+
while (offset < sealedBytes.length) {
|
|
32348
|
+
if (sealedBytes.length - offset < FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES) {
|
|
32349
|
+
throw new JobEnvelopeError("Invalid job result: truncated payload");
|
|
32350
|
+
}
|
|
32351
|
+
const encryptedLength = readUint32(sealedBytes, offset);
|
|
32352
|
+
const flags = sealedBytes[offset + FRAME_LENGTH_BYTES];
|
|
32353
|
+
if (encryptedLength < AES_GCM_TAG_BYTES || encryptedLength > JOB_RESULT_CHUNK_BYTES + AES_GCM_TAG_BYTES || flags !== 0 && flags !== FINAL_FRAME_FLAG) {
|
|
32354
|
+
throw new JobEnvelopeError("Invalid job result: invalid chunk framing");
|
|
32355
|
+
}
|
|
32356
|
+
const plaintextLength = encryptedLength - AES_GCM_TAG_BYTES;
|
|
32357
|
+
if (flags === 0 && plaintextLength !== JOB_RESULT_CHUNK_BYTES) {
|
|
32358
|
+
throw new JobEnvelopeError("Invalid job result: short non-final chunk");
|
|
32359
|
+
}
|
|
32360
|
+
offset += FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES;
|
|
32361
|
+
if (encryptedLength > sealedBytes.length - offset) {
|
|
32362
|
+
throw new JobEnvelopeError("Invalid job result: truncated payload");
|
|
32363
|
+
}
|
|
32364
|
+
offset += encryptedLength;
|
|
32365
|
+
bodySize += plaintextLength;
|
|
32366
|
+
if (flags === FINAL_FRAME_FLAG) {
|
|
32367
|
+
sawFinal = true;
|
|
32368
|
+
if (offset !== sealedBytes.length) {
|
|
32369
|
+
throw new JobEnvelopeError(
|
|
32370
|
+
"Invalid job result: bytes follow final chunk"
|
|
32371
|
+
);
|
|
32372
|
+
}
|
|
32373
|
+
}
|
|
32374
|
+
}
|
|
32375
|
+
if (!sawFinal) {
|
|
32376
|
+
throw new JobEnvelopeError("Invalid job result: missing final chunk");
|
|
32377
|
+
}
|
|
32378
|
+
return bodySize;
|
|
32379
|
+
}
|
|
32380
|
+
async function openJobResult(sealedBytes, builderPrivateKey, ecies, expect) {
|
|
32381
|
+
const bodySize = bufferedResultBodySize(sealedBytes);
|
|
32382
|
+
const stream = new ReadableStream({
|
|
32383
|
+
start(controller) {
|
|
32384
|
+
controller.enqueue(sealedBytes);
|
|
32385
|
+
controller.close();
|
|
32386
|
+
}
|
|
32387
|
+
});
|
|
32388
|
+
const opened = await openJobResultStream(
|
|
32389
|
+
stream,
|
|
32390
|
+
builderPrivateKey,
|
|
32391
|
+
ecies,
|
|
32392
|
+
expect
|
|
32393
|
+
);
|
|
32394
|
+
const body = new Uint8Array(bodySize);
|
|
32395
|
+
let offset = 0;
|
|
32396
|
+
await opened.body.pipeTo(
|
|
32397
|
+
new WritableStream({
|
|
32398
|
+
write(chunk) {
|
|
32399
|
+
body.set(chunk, offset);
|
|
32400
|
+
offset += chunk.length;
|
|
32401
|
+
}
|
|
32402
|
+
})
|
|
32403
|
+
);
|
|
32404
|
+
if (offset !== body.length) {
|
|
32405
|
+
throw new JobEnvelopeError("Invalid job result: opened size mismatch");
|
|
32406
|
+
}
|
|
32407
|
+
return { ...opened.metadata, body };
|
|
32408
|
+
}
|
|
32409
|
+
|
|
31739
32410
|
// src/protocol/personal-server-registration.ts
|
|
31740
32411
|
import {
|
|
31741
|
-
isAddress
|
|
32412
|
+
isAddress as isAddress2
|
|
31742
32413
|
} from "viem";
|
|
31743
32414
|
var PERSONAL_SERVER_REGISTRATION_DEFAULT_CHAIN_ID = vanaMainnet2.id;
|
|
31744
32415
|
var PERSONAL_SERVER_REGISTRATION_DEFAULT_VERIFYING_CONTRACT = getContractAddress(
|
|
@@ -31746,7 +32417,7 @@ var PERSONAL_SERVER_REGISTRATION_DEFAULT_VERIFYING_CONTRACT = getContractAddress
|
|
|
31746
32417
|
"DataPortabilityServers"
|
|
31747
32418
|
);
|
|
31748
32419
|
function assertAddress(value, name) {
|
|
31749
|
-
if (!
|
|
32420
|
+
if (!isAddress2(value)) {
|
|
31750
32421
|
throw new Error(`${name} must be a valid EVM address`);
|
|
31751
32422
|
}
|
|
31752
32423
|
}
|
|
@@ -31833,13 +32504,13 @@ var registerPersonalServerSignature = buildPersonalServerRegistrationSignature;
|
|
|
31833
32504
|
|
|
31834
32505
|
// src/personal-server-lite/owner-binding.ts
|
|
31835
32506
|
import {
|
|
31836
|
-
isAddress as
|
|
32507
|
+
isAddress as isAddress3
|
|
31837
32508
|
} from "viem";
|
|
31838
32509
|
var PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION = "vana.ps-lite.owner-binding.v1";
|
|
31839
32510
|
var PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE = "ps-lite-owner";
|
|
31840
32511
|
var PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX = `${PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION}:${PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE}:`;
|
|
31841
32512
|
function assertAddress2(value, name) {
|
|
31842
|
-
if (!
|
|
32513
|
+
if (!isAddress3(value)) {
|
|
31843
32514
|
throw new Error(`${name} must be a valid EVM address`);
|
|
31844
32515
|
}
|
|
31845
32516
|
}
|
|
@@ -31889,7 +32560,7 @@ async function buildPersonalServerLiteOwnerBindingSignature(input) {
|
|
|
31889
32560
|
var signPersonalServerLiteOwnerBinding = buildPersonalServerLiteOwnerBindingSignature;
|
|
31890
32561
|
|
|
31891
32562
|
// src/account/personal-server-registration.ts
|
|
31892
|
-
import { isAddress as
|
|
32563
|
+
import { isAddress as isAddress4 } from "viem";
|
|
31893
32564
|
var ACCOUNT_PERSONAL_SERVER_REGISTRATION_INTENT = "personal_server.server_registration.v1";
|
|
31894
32565
|
var AccountPersonalServerRegistrationError = class extends Error {
|
|
31895
32566
|
status;
|
|
@@ -31908,7 +32579,7 @@ function trimTrailingSlash(value) {
|
|
|
31908
32579
|
return value.replace(/\/+$/, "");
|
|
31909
32580
|
}
|
|
31910
32581
|
function assertAddress3(value, name) {
|
|
31911
|
-
if (!
|
|
32582
|
+
if (!isAddress4(value)) {
|
|
31912
32583
|
throw new Error(`${name} must be a valid EVM address`);
|
|
31913
32584
|
}
|
|
31914
32585
|
}
|
|
@@ -32434,19 +33105,21 @@ function buildMarkDataPointUnavailableRequest(config, input) {
|
|
|
32434
33105
|
|
|
32435
33106
|
// src/protocol/data-point-deletion.ts
|
|
32436
33107
|
import {
|
|
32437
|
-
isAddress as
|
|
32438
|
-
keccak256 as
|
|
33108
|
+
isAddress as isAddress6,
|
|
33109
|
+
keccak256 as keccak2563,
|
|
32439
33110
|
maxUint256,
|
|
32440
33111
|
stringToBytes as stringToBytes3
|
|
32441
33112
|
} from "viem";
|
|
33113
|
+
import { DataPointDeletedError, DataPointNotFoundError } from "./errors.js";
|
|
32442
33114
|
|
|
32443
33115
|
// src/protocol/lineage.ts
|
|
32444
33116
|
import {
|
|
32445
33117
|
encodeAbiParameters,
|
|
32446
|
-
isAddress as
|
|
32447
|
-
keccak256
|
|
33118
|
+
isAddress as isAddress5,
|
|
33119
|
+
keccak256 as keccak2562
|
|
32448
33120
|
} from "viem";
|
|
32449
33121
|
import { z } from "zod";
|
|
33122
|
+
import { LineageReadError, WriteRequestError as WriteRequestError2 } from "./errors.js";
|
|
32450
33123
|
|
|
32451
33124
|
// src/protocol/personal-server-error-body.ts
|
|
32452
33125
|
function isRecord2(value) {
|
|
@@ -32478,6 +33151,7 @@ async function readPersonalServerErrorBody(response) {
|
|
|
32478
33151
|
}
|
|
32479
33152
|
|
|
32480
33153
|
// src/protocol/write-signer.ts
|
|
33154
|
+
import { WriteRequestError } from "./errors.js";
|
|
32481
33155
|
function isRecord3(value) {
|
|
32482
33156
|
return value !== null && typeof value === "object";
|
|
32483
33157
|
}
|
|
@@ -32523,12 +33197,12 @@ function isDataPointId(value) {
|
|
|
32523
33197
|
return typeof value === "string" && DATA_POINT_ID_PATTERN.test(value);
|
|
32524
33198
|
}
|
|
32525
33199
|
function deriveDataPointId(ownerAddress, scope) {
|
|
32526
|
-
if (!
|
|
33200
|
+
if (!isAddress5(ownerAddress, { strict: false })) {
|
|
32527
33201
|
throw new Error(
|
|
32528
33202
|
`ownerAddress is not an EVM address: ${String(ownerAddress)}`
|
|
32529
33203
|
);
|
|
32530
33204
|
}
|
|
32531
|
-
return
|
|
33205
|
+
return keccak2562(
|
|
32532
33206
|
encodeAbiParameters(
|
|
32533
33207
|
[
|
|
32534
33208
|
{ name: "ownerAddress", type: "address" },
|
|
@@ -32558,7 +33232,7 @@ function derivedScopeViolatesNaming(derivedScope, sourceScope) {
|
|
|
32558
33232
|
function assertDerivedScopeNaming(derivedScope, sourceScopes) {
|
|
32559
33233
|
for (const sourceScope of sourceScopes) {
|
|
32560
33234
|
if (derivedScopeViolatesNaming(derivedScope, sourceScope)) {
|
|
32561
|
-
throw new
|
|
33235
|
+
throw new WriteRequestError2(
|
|
32562
33236
|
`Derived scope ${derivedScope} must not share its first segment with source scope ${sourceScope}; put derivatives in the app's own namespace`,
|
|
32563
33237
|
{ scope: derivedScope, sourceScope }
|
|
32564
33238
|
);
|
|
@@ -32755,7 +33429,7 @@ var TOMBSTONE_METADATA_HASH_PREIMAGE = "vana.data-point.tombstone.metadata.v1";
|
|
|
32755
33429
|
var TOMBSTONE_DATA_HASH = "0x30c45ee72fe56d1927701316925ab7ceacd3b6f9267061735d59396f075c6222";
|
|
32756
33430
|
var TOMBSTONE_METADATA_HASH = "0xc5255a141acd6a2ae55971b62c0a85977c2511989dc114ad2abc2b7644f57d90";
|
|
32757
33431
|
function computeTombstoneHash(preimage) {
|
|
32758
|
-
return
|
|
33432
|
+
return keccak2563(stringToBytes3(preimage));
|
|
32759
33433
|
}
|
|
32760
33434
|
function isTombstoneHashes(dataHash, metadataHash) {
|
|
32761
33435
|
return typeof dataHash === "string" && typeof metadataHash === "string" && dataHash.toLowerCase() === TOMBSTONE_DATA_HASH && metadataHash.toLowerCase() === TOMBSTONE_METADATA_HASH;
|
|
@@ -32774,7 +33448,7 @@ function tombstoneDeletedAt(value) {
|
|
|
32774
33448
|
return typeof deletedAt === "string" ? deletedAt : null;
|
|
32775
33449
|
}
|
|
32776
33450
|
function assertAddress4(value, name) {
|
|
32777
|
-
if (!
|
|
33451
|
+
if (!isAddress6(value)) {
|
|
32778
33452
|
throw new Error(`${name} must be a valid EVM address`);
|
|
32779
33453
|
}
|
|
32780
33454
|
}
|
|
@@ -32916,6 +33590,9 @@ async function deleteDataPoint(input) {
|
|
|
32916
33590
|
}
|
|
32917
33591
|
}
|
|
32918
33592
|
|
|
33593
|
+
// src/protocol/personal-server-data.ts
|
|
33594
|
+
import { DataPointDeletedError as DataPointDeletedError2 } from "./errors.js";
|
|
33595
|
+
|
|
32919
33596
|
// src/protocol/data-file.ts
|
|
32920
33597
|
import { z as z2 } from "zod";
|
|
32921
33598
|
var DataFileEnvelopeSchema = z2.object({
|
|
@@ -32974,7 +33651,7 @@ async function readPersonalServerData(params) {
|
|
|
32974
33651
|
const request = await buildPersonalServerDataReadRequest(params);
|
|
32975
33652
|
const response = await fetchFn(request);
|
|
32976
33653
|
if (response.status === 410) {
|
|
32977
|
-
throw new
|
|
33654
|
+
throw new DataPointDeletedError2(
|
|
32978
33655
|
`Personal Server scope '${params.scope}' has been deleted`,
|
|
32979
33656
|
{
|
|
32980
33657
|
scope: params.scope,
|
|
@@ -32989,7 +33666,7 @@ async function readPersonalServerData(params) {
|
|
|
32989
33666
|
}
|
|
32990
33667
|
const body = await response.json();
|
|
32991
33668
|
if (isDataPointTombstone(body)) {
|
|
32992
|
-
throw new
|
|
33669
|
+
throw new DataPointDeletedError2(
|
|
32993
33670
|
`Personal Server scope '${params.scope}' has been deleted`,
|
|
32994
33671
|
{ scope: params.scope, deletedAt: tombstoneDeletedAt(body) }
|
|
32995
33672
|
);
|
|
@@ -33189,20 +33866,31 @@ function tryGrantPermissions(scopes) {
|
|
|
33189
33866
|
}
|
|
33190
33867
|
|
|
33191
33868
|
// src/protocol/personal-server-write.ts
|
|
33192
|
-
import { sha256 as
|
|
33193
|
-
import { bytesToHex as
|
|
33869
|
+
import { sha256 as sha2567 } from "@noble/hashes/sha2";
|
|
33870
|
+
import { bytesToHex as bytesToHex4, isAddress as isAddress7 } from "viem";
|
|
33194
33871
|
import { z as z4 } from "zod";
|
|
33872
|
+
import {
|
|
33873
|
+
WriteConflictError,
|
|
33874
|
+
WriteForbiddenError,
|
|
33875
|
+
WriteLineageError,
|
|
33876
|
+
WriteRejectedError,
|
|
33877
|
+
WriteRequestError as WriteRequestError4,
|
|
33878
|
+
WriteSessionError,
|
|
33879
|
+
WriteSessionExpiredError,
|
|
33880
|
+
WriteUnauthorizedError
|
|
33881
|
+
} from "./errors.js";
|
|
33195
33882
|
|
|
33196
33883
|
// src/protocol/write-request.ts
|
|
33197
|
-
import { sha256 as
|
|
33198
|
-
import { bytesToHex as
|
|
33884
|
+
import { sha256 as sha2566 } from "@noble/hashes/sha2";
|
|
33885
|
+
import { bytesToHex as bytesToHex3 } from "viem";
|
|
33886
|
+
import { WriteRequestError as WriteRequestError3, WriteTransportError } from "./errors.js";
|
|
33199
33887
|
function normalizeBaseUrl2(url) {
|
|
33200
33888
|
return url.replace(/\/+$/, "");
|
|
33201
33889
|
}
|
|
33202
33890
|
function resolveFetch2(fetchFn) {
|
|
33203
33891
|
const resolved = fetchFn ?? globalThis.fetch;
|
|
33204
33892
|
if (resolved === void 0) {
|
|
33205
|
-
throw new
|
|
33893
|
+
throw new WriteRequestError3("No fetch implementation available");
|
|
33206
33894
|
}
|
|
33207
33895
|
return resolved;
|
|
33208
33896
|
}
|
|
@@ -33257,27 +33945,27 @@ function nextProofIat(proofKey) {
|
|
|
33257
33945
|
return sleep2(waitSec * 1e3).then(() => iat);
|
|
33258
33946
|
}
|
|
33259
33947
|
function freshProofNonce() {
|
|
33260
|
-
const
|
|
33261
|
-
if (typeof
|
|
33262
|
-
return
|
|
33948
|
+
const webCrypto2 = globalThis.crypto;
|
|
33949
|
+
if (typeof webCrypto2?.randomUUID === "function") {
|
|
33950
|
+
return webCrypto2.randomUUID();
|
|
33263
33951
|
}
|
|
33264
|
-
if (typeof
|
|
33265
|
-
return
|
|
33952
|
+
if (typeof webCrypto2?.getRandomValues === "function") {
|
|
33953
|
+
return bytesToHex3(webCrypto2.getRandomValues(new Uint8Array(16)));
|
|
33266
33954
|
}
|
|
33267
|
-
throw new
|
|
33955
|
+
throw new WriteRequestError3(
|
|
33268
33956
|
"No secure random source available to build a proof nonce; provide a crypto global"
|
|
33269
33957
|
);
|
|
33270
33958
|
}
|
|
33271
33959
|
function proofKeyFor(parts) {
|
|
33272
|
-
return
|
|
33273
|
-
|
|
33960
|
+
return bytesToHex3(
|
|
33961
|
+
sha2566(
|
|
33274
33962
|
new TextEncoder().encode(
|
|
33275
33963
|
JSON.stringify([
|
|
33276
33964
|
parts.aud,
|
|
33277
33965
|
parts.method,
|
|
33278
33966
|
parts.uri,
|
|
33279
33967
|
parts.grantId,
|
|
33280
|
-
parts.signedBytes ?
|
|
33968
|
+
parts.signedBytes ? bytesToHex3(sha2566(parts.signedBytes)) : ""
|
|
33281
33969
|
])
|
|
33282
33970
|
)
|
|
33283
33971
|
)
|
|
@@ -33420,7 +34108,7 @@ function isWriteSession(value) {
|
|
|
33420
34108
|
}
|
|
33421
34109
|
function sessionCoversScope(session, scope) {
|
|
33422
34110
|
if (!isRecord2(session) || !Array.isArray(session.writeScopes) || !session.writeScopes.every((pattern) => typeof pattern === "string")) {
|
|
33423
|
-
throw new
|
|
34111
|
+
throw new WriteRequestError4("session must come from openWriteSession");
|
|
33424
34112
|
}
|
|
33425
34113
|
return session.writeScopes.some(
|
|
33426
34114
|
(pattern) => scopeMatchesPattern(scope, pattern)
|
|
@@ -33445,12 +34133,12 @@ function encodeWriteMetadataHeader(metadata) {
|
|
|
33445
34133
|
try {
|
|
33446
34134
|
json = JSON.stringify(metadata);
|
|
33447
34135
|
} catch (err) {
|
|
33448
|
-
throw new
|
|
34136
|
+
throw new WriteRequestError4(
|
|
33449
34137
|
`metadata is not JSON-serialisable: ${errorMessage(err)}`
|
|
33450
34138
|
);
|
|
33451
34139
|
}
|
|
33452
34140
|
if (typeof json !== "string") {
|
|
33453
|
-
throw new
|
|
34141
|
+
throw new WriteRequestError4("metadata must serialise to JSON");
|
|
33454
34142
|
}
|
|
33455
34143
|
return json.replace(
|
|
33456
34144
|
/[\u007f-\uffff]/g,
|
|
@@ -33464,7 +34152,7 @@ function binaryWriteSignedBytes(input) {
|
|
|
33464
34152
|
mimeType: normalizeBinaryMimeType(input.contentType),
|
|
33465
34153
|
...input.filename ? { filename: input.filename } : {},
|
|
33466
34154
|
sizeBytes: input.bytes.length,
|
|
33467
|
-
contentHash:
|
|
34155
|
+
contentHash: bytesToHex4(sha2567(input.bytes)),
|
|
33468
34156
|
encoding: "base64",
|
|
33469
34157
|
content: toBase64(input.bytes),
|
|
33470
34158
|
...metadata !== void 0 ? { metadata } : {}
|
|
@@ -33485,7 +34173,7 @@ function setFilenameHeader(headers, filename) {
|
|
|
33485
34173
|
function assertNoReservedKeys(value, where) {
|
|
33486
34174
|
for (const key of RESERVED_WRITE_KEYS) {
|
|
33487
34175
|
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
33488
|
-
throw new
|
|
34176
|
+
throw new WriteRequestError4(
|
|
33489
34177
|
`${where} must not contain the reserved ${key} key; the Personal Server stamps it`,
|
|
33490
34178
|
{ key }
|
|
33491
34179
|
);
|
|
@@ -33497,10 +34185,10 @@ function isLineagePair(value) {
|
|
|
33497
34185
|
}
|
|
33498
34186
|
function normalizeLineage(lineage, derivedScope) {
|
|
33499
34187
|
if (!Array.isArray(lineage)) {
|
|
33500
|
-
throw new
|
|
34188
|
+
throw new WriteRequestError4("lineage must be an array of data point ids");
|
|
33501
34189
|
}
|
|
33502
34190
|
if (lineage.length > MAX_LINEAGE_SOURCES) {
|
|
33503
|
-
throw new
|
|
34191
|
+
throw new WriteRequestError4(
|
|
33504
34192
|
`lineage lists ${lineage.length} sources; the maximum is ${MAX_LINEAGE_SOURCES}`,
|
|
33505
34193
|
{ max: MAX_LINEAGE_SOURCES, count: lineage.length }
|
|
33506
34194
|
);
|
|
@@ -33512,14 +34200,14 @@ function normalizeLineage(lineage, derivedScope) {
|
|
|
33512
34200
|
for (const entry of lineage) {
|
|
33513
34201
|
let id;
|
|
33514
34202
|
if (isLineagePair(entry)) {
|
|
33515
|
-
if (!
|
|
33516
|
-
throw new
|
|
34203
|
+
if (!isAddress7(entry.ownerAddress, { strict: false })) {
|
|
34204
|
+
throw new WriteRequestError4(
|
|
33517
34205
|
"lineage source ownerAddress must be an EVM address",
|
|
33518
34206
|
{ ownerAddress: entry.ownerAddress }
|
|
33519
34207
|
);
|
|
33520
34208
|
}
|
|
33521
34209
|
if (entry.scope.length === 0) {
|
|
33522
|
-
throw new
|
|
34210
|
+
throw new WriteRequestError4("lineage source scope is required");
|
|
33523
34211
|
}
|
|
33524
34212
|
id = deriveDataPointId(entry.ownerAddress, entry.scope);
|
|
33525
34213
|
sourceScopes.push(entry.scope);
|
|
@@ -33527,14 +34215,14 @@ function normalizeLineage(lineage, derivedScope) {
|
|
|
33527
34215
|
} else if (isDataPointId(entry)) {
|
|
33528
34216
|
id = entry;
|
|
33529
34217
|
} else {
|
|
33530
|
-
throw new
|
|
34218
|
+
throw new WriteRequestError4(
|
|
33531
34219
|
"lineage entries must be 32-byte hex data point ids or { ownerAddress, scope } pairs",
|
|
33532
34220
|
{ entry }
|
|
33533
34221
|
);
|
|
33534
34222
|
}
|
|
33535
34223
|
const normalized = id.toLowerCase();
|
|
33536
34224
|
if (seen.has(normalized)) {
|
|
33537
|
-
throw new
|
|
34225
|
+
throw new WriteRequestError4("lineage must not repeat a data point id", {
|
|
33538
34226
|
dataPointId: normalized
|
|
33539
34227
|
});
|
|
33540
34228
|
}
|
|
@@ -33543,7 +34231,7 @@ function normalizeLineage(lineage, derivedScope) {
|
|
|
33543
34231
|
}
|
|
33544
34232
|
for (const own of ownIds) {
|
|
33545
34233
|
if (seen.has(own)) {
|
|
33546
|
-
throw new
|
|
34234
|
+
throw new WriteRequestError4(
|
|
33547
34235
|
"lineage must not cite the record's own data point",
|
|
33548
34236
|
{ dataPointId: own, scope: derivedScope }
|
|
33549
34237
|
);
|
|
@@ -33554,7 +34242,7 @@ function normalizeLineage(lineage, derivedScope) {
|
|
|
33554
34242
|
}
|
|
33555
34243
|
function assertNoLineageField(value, where) {
|
|
33556
34244
|
if (Object.prototype.hasOwnProperty.call(value, LINEAGE_FIELD)) {
|
|
33557
|
-
throw new
|
|
34245
|
+
throw new WriteRequestError4(
|
|
33558
34246
|
`${where}.${LINEAGE_FIELD} is reserved; pass sources through the lineage option`
|
|
33559
34247
|
);
|
|
33560
34248
|
}
|
|
@@ -33562,7 +34250,7 @@ function assertNoLineageField(value, where) {
|
|
|
33562
34250
|
function buildMetadataHeader(metadata, sources) {
|
|
33563
34251
|
if (metadata !== void 0) {
|
|
33564
34252
|
if (!isRecord2(metadata)) {
|
|
33565
|
-
throw new
|
|
34253
|
+
throw new WriteRequestError4("metadata must be a plain object");
|
|
33566
34254
|
}
|
|
33567
34255
|
assertNoReservedKeys(metadata, "metadata");
|
|
33568
34256
|
assertNoLineageField(metadata, "metadata");
|
|
@@ -33575,24 +34263,24 @@ function buildMetadataHeader(metadata, sources) {
|
|
|
33575
34263
|
}
|
|
33576
34264
|
function prepareWrite(params) {
|
|
33577
34265
|
if (params.binary !== void 0 && params.data !== void 0) {
|
|
33578
|
-
throw new
|
|
34266
|
+
throw new WriteRequestError4("Pass either data or binary, not both");
|
|
33579
34267
|
}
|
|
33580
34268
|
const rawLineage = params.lineage;
|
|
33581
34269
|
const sources = rawLineage === void 0 || rawLineage === null ? void 0 : normalizeLineage(rawLineage, params.scope);
|
|
33582
34270
|
if (params.binary !== void 0) {
|
|
33583
34271
|
const { bytes, contentType, filename } = params.binary;
|
|
33584
34272
|
if (!(bytes instanceof Uint8Array)) {
|
|
33585
|
-
throw new
|
|
34273
|
+
throw new WriteRequestError4("binary.bytes must be a Uint8Array");
|
|
33586
34274
|
}
|
|
33587
34275
|
if (typeof contentType !== "string" || contentType.trim() === "") {
|
|
33588
|
-
throw new
|
|
34276
|
+
throw new WriteRequestError4("binary.contentType is required");
|
|
33589
34277
|
}
|
|
33590
34278
|
if (filename !== void 0) {
|
|
33591
34279
|
if (typeof filename !== "string") {
|
|
33592
|
-
throw new
|
|
34280
|
+
throw new WriteRequestError4("binary.filename must be a string");
|
|
33593
34281
|
}
|
|
33594
34282
|
if (filename !== filename.trim()) {
|
|
33595
|
-
throw new
|
|
34283
|
+
throw new WriteRequestError4(
|
|
33596
34284
|
"binary.filename must not have leading or trailing whitespace"
|
|
33597
34285
|
);
|
|
33598
34286
|
}
|
|
@@ -33612,13 +34300,13 @@ function prepareWrite(params) {
|
|
|
33612
34300
|
};
|
|
33613
34301
|
}
|
|
33614
34302
|
if (params.data === void 0) {
|
|
33615
|
-
throw new
|
|
34303
|
+
throw new WriteRequestError4("Pass data (a JSON object) or binary");
|
|
33616
34304
|
}
|
|
33617
34305
|
if (!isRecord2(params.data)) {
|
|
33618
|
-
throw new
|
|
34306
|
+
throw new WriteRequestError4("data must be a plain JSON object");
|
|
33619
34307
|
}
|
|
33620
34308
|
if (params.metadata !== void 0) {
|
|
33621
|
-
throw new
|
|
34309
|
+
throw new WriteRequestError4(
|
|
33622
34310
|
"metadata applies to binary writes; put fields to store inside data"
|
|
33623
34311
|
);
|
|
33624
34312
|
}
|
|
@@ -33629,12 +34317,12 @@ function prepareWrite(params) {
|
|
|
33629
34317
|
try {
|
|
33630
34318
|
text = JSON.stringify(record);
|
|
33631
34319
|
} catch (err) {
|
|
33632
|
-
throw new
|
|
34320
|
+
throw new WriteRequestError4(
|
|
33633
34321
|
`data is not JSON-serialisable: ${errorMessage(err)}`
|
|
33634
34322
|
);
|
|
33635
34323
|
}
|
|
33636
34324
|
if (typeof text !== "string" || !text.startsWith("{")) {
|
|
33637
|
-
throw new
|
|
34325
|
+
throw new WriteRequestError4("data must serialise to a JSON object");
|
|
33638
34326
|
}
|
|
33639
34327
|
const body = new TextEncoder().encode(text);
|
|
33640
34328
|
return {
|
|
@@ -33663,11 +34351,11 @@ async function writeErrorFromResponse(response) {
|
|
|
33663
34351
|
async function writeData(params) {
|
|
33664
34352
|
const { session } = params;
|
|
33665
34353
|
if (!isWriteSession(session)) {
|
|
33666
|
-
throw new
|
|
34354
|
+
throw new WriteRequestError4("session must come from openWriteSession");
|
|
33667
34355
|
}
|
|
33668
34356
|
const fetchFn = resolveFetch2(params.fetch);
|
|
33669
34357
|
if (typeof params.scope !== "string" || params.scope.length === 0) {
|
|
33670
|
-
throw new
|
|
34358
|
+
throw new WriteRequestError4("scope is required");
|
|
33671
34359
|
}
|
|
33672
34360
|
const prepared = prepareWrite(params);
|
|
33673
34361
|
if (Date.now() >= session.expiresAt) {
|
|
@@ -33763,6 +34451,21 @@ async function writePersonalServerData(params) {
|
|
|
33763
34451
|
|
|
33764
34452
|
// src/protocol/derivative-questions.ts
|
|
33765
34453
|
import { z as z5 } from "zod";
|
|
34454
|
+
import {
|
|
34455
|
+
DerivativeComputeUnavailableError,
|
|
34456
|
+
DerivativeCycleError,
|
|
34457
|
+
DerivativeDerivedScopeRequiredError,
|
|
34458
|
+
DerivativeQuestionFailedError,
|
|
34459
|
+
DerivativeQuestionInvalidError,
|
|
34460
|
+
DerivativeQuestionNotFoundError,
|
|
34461
|
+
DerivativeQuestionRejectedError,
|
|
34462
|
+
DerivativeQuestionTimeoutError,
|
|
34463
|
+
DerivativeSourceNotGrantedError,
|
|
34464
|
+
WriteConflictError as WriteConflictError2,
|
|
34465
|
+
WriteForbiddenError as WriteForbiddenError2,
|
|
34466
|
+
WriteRequestError as WriteRequestError5,
|
|
34467
|
+
WriteUnauthorizedError as WriteUnauthorizedError2
|
|
34468
|
+
} from "./errors.js";
|
|
33766
34469
|
var DERIVATIVE_QUESTIONS_PATH = "/v1/derivatives/questions";
|
|
33767
34470
|
var MAX_QUESTION_SOURCE_SCOPES = 16;
|
|
33768
34471
|
var MAX_QUESTION_CHARS = 8e3;
|
|
@@ -33845,15 +34548,15 @@ function fetchIdOf(fetchFn) {
|
|
|
33845
34548
|
}
|
|
33846
34549
|
function resolveRequest(params) {
|
|
33847
34550
|
if (typeof params.personalServerUrl !== "string" || params.personalServerUrl.length === 0) {
|
|
33848
|
-
throw new
|
|
34551
|
+
throw new WriteRequestError5("personalServerUrl is required");
|
|
33849
34552
|
}
|
|
33850
34553
|
if (typeof params.grantId !== "string" || params.grantId.length === 0) {
|
|
33851
|
-
throw new
|
|
34554
|
+
throw new WriteRequestError5(
|
|
33852
34555
|
"grantId is required; a question call runs under the grant carrying write:<derivedScope>"
|
|
33853
34556
|
);
|
|
33854
34557
|
}
|
|
33855
34558
|
if (params.signer === null || typeof params.signer !== "object") {
|
|
33856
|
-
throw new
|
|
34559
|
+
throw new WriteRequestError5(
|
|
33857
34560
|
"signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
|
|
33858
34561
|
);
|
|
33859
34562
|
}
|
|
@@ -33929,13 +34632,13 @@ async function questionErrorFromResponse(response, body) {
|
|
|
33929
34632
|
}
|
|
33930
34633
|
switch (response.status) {
|
|
33931
34634
|
case 401:
|
|
33932
|
-
return new
|
|
34635
|
+
return new WriteUnauthorizedError2(text, errorCode, details);
|
|
33933
34636
|
case 403:
|
|
33934
|
-
return new
|
|
34637
|
+
return new WriteForbiddenError2(text, errorCode, details);
|
|
33935
34638
|
case 404:
|
|
33936
34639
|
return new DerivativeQuestionNotFoundError(text, errorCode, details);
|
|
33937
34640
|
case 409:
|
|
33938
|
-
return new
|
|
34641
|
+
return new WriteConflictError2(text, errorCode, details);
|
|
33939
34642
|
default:
|
|
33940
34643
|
return new DerivativeQuestionRejectedError(
|
|
33941
34644
|
text,
|
|
@@ -34037,22 +34740,22 @@ async function sendQuestionRequest(params, spec, schema) {
|
|
|
34037
34740
|
}
|
|
34038
34741
|
function assertQuestionId(questionId) {
|
|
34039
34742
|
if (typeof questionId !== "string" || questionId.length === 0) {
|
|
34040
|
-
throw new
|
|
34743
|
+
throw new WriteRequestError5("questionId is required");
|
|
34041
34744
|
}
|
|
34042
34745
|
return `${DERIVATIVE_QUESTIONS_PATH}/${encodeURIComponent(questionId)}`;
|
|
34043
34746
|
}
|
|
34044
34747
|
function registrationBody(params) {
|
|
34045
34748
|
const { derivedScope, question } = params;
|
|
34046
34749
|
if (typeof derivedScope !== "string" || derivedScope.length === 0) {
|
|
34047
|
-
throw new
|
|
34750
|
+
throw new WriteRequestError5("derivedScope is required");
|
|
34048
34751
|
}
|
|
34049
34752
|
if (!Array.isArray(params.sourceScopes) || params.sourceScopes.length === 0) {
|
|
34050
|
-
throw new
|
|
34753
|
+
throw new WriteRequestError5(
|
|
34051
34754
|
"sourceScopes must be a non-empty array of scopes"
|
|
34052
34755
|
);
|
|
34053
34756
|
}
|
|
34054
34757
|
if (params.sourceScopes.length > MAX_QUESTION_SOURCE_SCOPES) {
|
|
34055
|
-
throw new
|
|
34758
|
+
throw new WriteRequestError5(
|
|
34056
34759
|
`sourceScopes lists ${params.sourceScopes.length} scopes; the maximum is ${MAX_QUESTION_SOURCE_SCOPES}`,
|
|
34057
34760
|
{ max: MAX_QUESTION_SOURCE_SCOPES, count: params.sourceScopes.length }
|
|
34058
34761
|
);
|
|
@@ -34060,15 +34763,15 @@ function registrationBody(params) {
|
|
|
34060
34763
|
const sourceScopes = [];
|
|
34061
34764
|
for (const scope of params.sourceScopes) {
|
|
34062
34765
|
if (typeof scope !== "string" || scope.length === 0) {
|
|
34063
|
-
throw new
|
|
34766
|
+
throw new WriteRequestError5("sourceScopes entries must be scope strings");
|
|
34064
34767
|
}
|
|
34065
34768
|
if (sourceScopes.includes(scope)) {
|
|
34066
|
-
throw new
|
|
34769
|
+
throw new WriteRequestError5("sourceScopes must not repeat a scope", {
|
|
34067
34770
|
duplicate: scope
|
|
34068
34771
|
});
|
|
34069
34772
|
}
|
|
34070
34773
|
if (scope === derivedScope) {
|
|
34071
|
-
throw new
|
|
34774
|
+
throw new WriteRequestError5(
|
|
34072
34775
|
"derivedScope cannot be one of its own sources",
|
|
34073
34776
|
{ scope }
|
|
34074
34777
|
);
|
|
@@ -34076,17 +34779,17 @@ function registrationBody(params) {
|
|
|
34076
34779
|
sourceScopes.push(scope);
|
|
34077
34780
|
}
|
|
34078
34781
|
if (typeof question !== "string" || question.trim() === "") {
|
|
34079
|
-
throw new
|
|
34782
|
+
throw new WriteRequestError5("question must be a non-empty string");
|
|
34080
34783
|
}
|
|
34081
34784
|
if (question.length > MAX_QUESTION_CHARS) {
|
|
34082
|
-
throw new
|
|
34785
|
+
throw new WriteRequestError5(
|
|
34083
34786
|
`question is ${question.length} characters; the maximum is ${MAX_QUESTION_CHARS}`,
|
|
34084
34787
|
{ max: MAX_QUESTION_CHARS, length: question.length }
|
|
34085
34788
|
);
|
|
34086
34789
|
}
|
|
34087
34790
|
if (params.model !== void 0) {
|
|
34088
34791
|
if (typeof params.model !== "string" || params.model.length > MAX_QUESTION_MODEL_CHARS || !MODEL_ID_PATTERN.test(params.model)) {
|
|
34089
|
-
throw new
|
|
34792
|
+
throw new WriteRequestError5("model must be a provider model id", {
|
|
34090
34793
|
model: params.model
|
|
34091
34794
|
});
|
|
34092
34795
|
}
|
|
@@ -34122,7 +34825,7 @@ async function getQuestion(params) {
|
|
|
34122
34825
|
}
|
|
34123
34826
|
async function listQuestions(params) {
|
|
34124
34827
|
if (typeof params.derivedScope !== "string" || params.derivedScope.length === 0) {
|
|
34125
|
-
throw new
|
|
34828
|
+
throw new WriteRequestError5(
|
|
34126
34829
|
"derivedScope is required; a builder may only list its own questions on a scope it may write"
|
|
34127
34830
|
);
|
|
34128
34831
|
}
|
|
@@ -34227,6 +34930,12 @@ async function askPersonalServer(params) {
|
|
|
34227
34930
|
|
|
34228
34931
|
// src/protocol/derivative-status.ts
|
|
34229
34932
|
import { z as z6 } from "zod";
|
|
34933
|
+
import {
|
|
34934
|
+
DerivativeQuestionRejectedError as DerivativeQuestionRejectedError2,
|
|
34935
|
+
DerivativeQuestionTimeoutError as DerivativeQuestionTimeoutError2,
|
|
34936
|
+
WriteRequestError as WriteRequestError6,
|
|
34937
|
+
WriteTransportError as WriteTransportError2
|
|
34938
|
+
} from "./errors.js";
|
|
34230
34939
|
var DERIVATIVE_STATUS_PATH = "/v1/derivatives/status";
|
|
34231
34940
|
var DEFAULT_DERIVATIVE_STATUS_TIMEOUT_MS = 12e4;
|
|
34232
34941
|
var DEFAULT_DERIVATIVE_STATUS_POLL_INTERVAL_MS = 2e3;
|
|
@@ -34257,13 +34966,13 @@ function normalizeBaseUrl3(url) {
|
|
|
34257
34966
|
function resolveFetch3(fetchFn) {
|
|
34258
34967
|
const resolved = fetchFn ?? globalThis.fetch;
|
|
34259
34968
|
if (resolved === void 0) {
|
|
34260
|
-
throw new
|
|
34969
|
+
throw new WriteRequestError6("No fetch implementation available");
|
|
34261
34970
|
}
|
|
34262
34971
|
return resolved;
|
|
34263
34972
|
}
|
|
34264
34973
|
function requireDerivedScope(derivedScope) {
|
|
34265
34974
|
if (typeof derivedScope !== "string" || derivedScope.length === 0) {
|
|
34266
|
-
throw new
|
|
34975
|
+
throw new WriteRequestError6("derivedScope is required");
|
|
34267
34976
|
}
|
|
34268
34977
|
return derivedScope;
|
|
34269
34978
|
}
|
|
@@ -34282,7 +34991,7 @@ function sleep3(ms, signal) {
|
|
|
34282
34991
|
});
|
|
34283
34992
|
}
|
|
34284
34993
|
function timeoutError(latest, timeoutMs) {
|
|
34285
|
-
return new
|
|
34994
|
+
return new DerivativeQuestionTimeoutError2(
|
|
34286
34995
|
`Derived scope ${latest.derivedScope} was still ${latest.status} after ${timeoutMs}ms`,
|
|
34287
34996
|
{
|
|
34288
34997
|
derivedScope: latest.derivedScope,
|
|
@@ -34295,7 +35004,7 @@ function timeoutError(latest, timeoutMs) {
|
|
|
34295
35004
|
}
|
|
34296
35005
|
function abortError2(signal) {
|
|
34297
35006
|
const reason = signal?.reason;
|
|
34298
|
-
return reason instanceof Error ? reason : new
|
|
35007
|
+
return reason instanceof Error ? reason : new WriteRequestError6("Derivative status wait was aborted");
|
|
34299
35008
|
}
|
|
34300
35009
|
function isDerivativeStatusSettled(status) {
|
|
34301
35010
|
if (status.status === "ready") return true;
|
|
@@ -34328,7 +35037,7 @@ async function getDerivativeStatus(params) {
|
|
|
34328
35037
|
}
|
|
34329
35038
|
);
|
|
34330
35039
|
} catch (err) {
|
|
34331
|
-
throw new
|
|
35040
|
+
throw new WriteTransportError2(
|
|
34332
35041
|
`Derivative status read failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
34333
35042
|
1,
|
|
34334
35043
|
err
|
|
@@ -34343,7 +35052,7 @@ async function getDerivativeStatus(params) {
|
|
|
34343
35052
|
try {
|
|
34344
35053
|
body = await response.json();
|
|
34345
35054
|
} catch (err) {
|
|
34346
|
-
throw new
|
|
35055
|
+
throw new DerivativeQuestionRejectedError2(
|
|
34347
35056
|
"Derivative status response is not JSON",
|
|
34348
35057
|
response.status,
|
|
34349
35058
|
null,
|
|
@@ -34352,7 +35061,7 @@ async function getDerivativeStatus(params) {
|
|
|
34352
35061
|
}
|
|
34353
35062
|
const parsed = DerivativeStatusSchema.safeParse(body);
|
|
34354
35063
|
if (!parsed.success) {
|
|
34355
|
-
throw new
|
|
35064
|
+
throw new DerivativeQuestionRejectedError2(
|
|
34356
35065
|
"Derivative status response is not a status view",
|
|
34357
35066
|
response.status,
|
|
34358
35067
|
null,
|
|
@@ -34386,6 +35095,11 @@ async function waitForDerivativeStatus(params) {
|
|
|
34386
35095
|
}
|
|
34387
35096
|
|
|
34388
35097
|
// src/protocol/gateway.ts
|
|
35098
|
+
import {
|
|
35099
|
+
DataPointDeletedError as DataPointDeletedError3,
|
|
35100
|
+
DataPointNotFoundError as DataPointNotFoundError2,
|
|
35101
|
+
DataPointVersionConflictError
|
|
35102
|
+
} from "./errors.js";
|
|
34389
35103
|
function withGrantPermissions(grant) {
|
|
34390
35104
|
const stripped = { ...grant };
|
|
34391
35105
|
delete stripped.permissions;
|
|
@@ -34431,7 +35145,7 @@ function createGatewayClient(baseUrl) {
|
|
|
34431
35145
|
}
|
|
34432
35146
|
async function deletedError(res, details) {
|
|
34433
35147
|
const body = await readBody(res);
|
|
34434
|
-
return new
|
|
35148
|
+
return new DataPointDeletedError3(
|
|
34435
35149
|
`Data point ${details.dataPointId ?? details.scope ?? ""} has been deleted`,
|
|
34436
35150
|
{ ...details, deletedAt: tombstoneDeletedAt(body) }
|
|
34437
35151
|
);
|
|
@@ -34504,7 +35218,7 @@ function createGatewayClient(baseUrl) {
|
|
|
34504
35218
|
}
|
|
34505
35219
|
const record = await unwrapEnvelope(res);
|
|
34506
35220
|
if (!options?.includeDeleted && isDataPointTombstone(record)) {
|
|
34507
|
-
throw new
|
|
35221
|
+
throw new DataPointDeletedError3(
|
|
34508
35222
|
`Data point ${dataPointId} has been deleted`,
|
|
34509
35223
|
{
|
|
34510
35224
|
dataPointId,
|
|
@@ -34666,7 +35380,7 @@ function createGatewayClient(baseUrl) {
|
|
|
34666
35380
|
})
|
|
34667
35381
|
});
|
|
34668
35382
|
if (res.status === 404) {
|
|
34669
|
-
throw new
|
|
35383
|
+
throw new DataPointNotFoundError2(
|
|
34670
35384
|
`Data point ${dataPointId} (scope '${params.scope}') is not registered`,
|
|
34671
35385
|
details
|
|
34672
35386
|
);
|
|
@@ -34989,42 +35703,34 @@ export {
|
|
|
34989
35703
|
AccountPersonalServerLiteOwnerBindingError,
|
|
34990
35704
|
AccountPersonalServerRegistrationError,
|
|
34991
35705
|
BUILDER_REGISTRATION_TYPES,
|
|
34992
|
-
BlockchainError,
|
|
34993
35706
|
BrowserECIESUint8Provider as BrowserECIESProvider,
|
|
34994
35707
|
BrowserPlatformAdapter,
|
|
35708
|
+
CLAIM_POLL_FLOOR_MS,
|
|
34995
35709
|
CONTRACTS,
|
|
34996
35710
|
CallbackStorage,
|
|
34997
35711
|
ContractFactory,
|
|
34998
|
-
ContractNotFoundError,
|
|
34999
35712
|
DATA_REGISTRY_STATUS_ABI,
|
|
35000
35713
|
DEFAULT_DERIVATIVE_STATUS_POLL_INTERVAL_MS,
|
|
35001
35714
|
DEFAULT_DERIVATIVE_STATUS_TIMEOUT_MS,
|
|
35715
|
+
DEFAULT_JOB_DEADLINE_SECONDS,
|
|
35716
|
+
DEFAULT_LEASE_SECONDS,
|
|
35002
35717
|
DEFAULT_QUESTION_POLL_INTERVAL_MS,
|
|
35003
35718
|
DEFAULT_QUESTION_TIMEOUT_MS,
|
|
35004
35719
|
DERIVATIVE_ERROR_CODES,
|
|
35005
35720
|
DERIVATIVE_QUESTIONS_PATH,
|
|
35006
35721
|
DERIVATIVE_STATUS_PATH,
|
|
35007
35722
|
DataFileEnvelopeSchema,
|
|
35008
|
-
DataPointDeletedError,
|
|
35009
|
-
DataPointNotFoundError,
|
|
35010
35723
|
DataPointStatus,
|
|
35011
|
-
DataPointVersionConflictError,
|
|
35012
|
-
DerivativeComputeUnavailableError,
|
|
35013
|
-
DerivativeCycleError,
|
|
35014
|
-
DerivativeDerivedScopeRequiredError,
|
|
35015
35724
|
DerivativeErrorCodeSchema,
|
|
35016
|
-
DerivativeQuestionFailedError,
|
|
35017
|
-
DerivativeQuestionInvalidError,
|
|
35018
|
-
DerivativeQuestionNotFoundError,
|
|
35019
|
-
DerivativeQuestionRejectedError,
|
|
35020
35725
|
DerivativeQuestionSchema,
|
|
35021
|
-
DerivativeQuestionTimeoutError,
|
|
35022
|
-
DerivativeSourceNotGrantedError,
|
|
35023
35726
|
DerivativeStatusSchema,
|
|
35024
35727
|
DropboxStorage,
|
|
35025
35728
|
ECIESError,
|
|
35729
|
+
ENCLAVE_IDENTITY_EVIDENCE_VERSION,
|
|
35730
|
+
ENCLAVE_TRUST_ANCHORS,
|
|
35731
|
+
ENCLAVE_WALLET_PURPOSE,
|
|
35026
35732
|
ESCROW_DEPOSIT_ABI2 as ESCROW_DEPOSIT_ABI,
|
|
35027
|
-
ExpiredTokenError,
|
|
35733
|
+
ExpiredTokenError2 as ExpiredTokenError,
|
|
35028
35734
|
FEE_REGISTRY_ABI,
|
|
35029
35735
|
GENERIC_PAYMENT_TYPES,
|
|
35030
35736
|
GRANT_REGISTRATION_TYPES,
|
|
@@ -35032,26 +35738,34 @@ export {
|
|
|
35032
35738
|
GoogleDriveStorage,
|
|
35033
35739
|
InMemoryTokenStore,
|
|
35034
35740
|
IngestResponseSchema,
|
|
35035
|
-
InvalidConfigurationError,
|
|
35036
35741
|
InvalidScopeEntryError,
|
|
35037
|
-
InvalidSignatureError,
|
|
35742
|
+
InvalidSignatureError2 as InvalidSignatureError,
|
|
35038
35743
|
IpfsStorage,
|
|
35744
|
+
JOB_OPERATIONS,
|
|
35745
|
+
JOB_PROTOCOL_VERSION,
|
|
35746
|
+
JOB_RESULT_CHUNK_BYTES,
|
|
35747
|
+
JOB_RESULT_FORMAT_VERSION,
|
|
35748
|
+
JOB_STATES,
|
|
35749
|
+
JobEnvelopeError,
|
|
35039
35750
|
LINEAGE_FIELD,
|
|
35040
35751
|
LINEAGE_KEY,
|
|
35041
35752
|
LineageEntrySchema,
|
|
35042
35753
|
LineageGraphSchema,
|
|
35043
35754
|
LineageNodeSchema,
|
|
35044
|
-
LineageReadError,
|
|
35045
35755
|
MASTER_KEY_MESSAGE,
|
|
35756
|
+
MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS,
|
|
35757
|
+
MASTER_SIGNATURE_DELIVERY_VERSION,
|
|
35758
|
+
MAX_ATTEMPTS,
|
|
35759
|
+
MAX_JOB_DEADLINE_SECONDS,
|
|
35760
|
+
MAX_LEASE_SECONDS,
|
|
35046
35761
|
MAX_LINEAGE_SOURCES,
|
|
35047
35762
|
MAX_QUESTION_CHARS,
|
|
35048
35763
|
MAX_QUESTION_MODEL_CHARS,
|
|
35049
35764
|
MAX_QUESTION_SOURCE_SCOPES,
|
|
35050
|
-
|
|
35765
|
+
MAX_WAIT_SECONDS,
|
|
35766
|
+
MissingAuthError2 as MissingAuthError,
|
|
35051
35767
|
NATIVE_ASSET_ADDRESS,
|
|
35052
35768
|
NATIVE_VANA_ASSET,
|
|
35053
|
-
NetworkError,
|
|
35054
|
-
NonceError,
|
|
35055
35769
|
OAuthClient,
|
|
35056
35770
|
PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX,
|
|
35057
35771
|
PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE,
|
|
@@ -35061,9 +35775,6 @@ export {
|
|
|
35061
35775
|
PKCE_CHALLENGE_PATTERN,
|
|
35062
35776
|
PKCE_VERIFIER_PATTERN,
|
|
35063
35777
|
PSError,
|
|
35064
|
-
PermissionError,
|
|
35065
|
-
PersonalServerError,
|
|
35066
|
-
PersonalServerWriteError,
|
|
35067
35778
|
PinataStorage,
|
|
35068
35779
|
QUESTION_STATUSES,
|
|
35069
35780
|
QuestionDeleteResultSchema,
|
|
@@ -35074,24 +35785,18 @@ export {
|
|
|
35074
35785
|
RECORD_DATA_ACCESS_TYPES,
|
|
35075
35786
|
REGISTRATION_KIND_FOR_OP,
|
|
35076
35787
|
RESERVED_WRITE_KEYS,
|
|
35077
|
-
ReadOnlyError,
|
|
35078
35788
|
RedactedLineageNodeSchema,
|
|
35079
|
-
RelayerError,
|
|
35080
35789
|
SCOPE_ACTIONS,
|
|
35790
|
+
SEALED_ENVELOPE_VERSION,
|
|
35081
35791
|
SERVER_REGISTRATION_TYPES,
|
|
35082
35792
|
ScopeSchema,
|
|
35083
|
-
SerializationError,
|
|
35084
|
-
ServerUrlMismatchError,
|
|
35085
|
-
SignatureError,
|
|
35086
35793
|
StorageError,
|
|
35087
35794
|
StorageManager,
|
|
35088
35795
|
TOMBSTONE_DATA_HASH,
|
|
35089
35796
|
TOMBSTONE_DATA_HASH_PREIMAGE,
|
|
35090
35797
|
TOMBSTONE_METADATA_HASH,
|
|
35091
35798
|
TOMBSTONE_METADATA_HASH_PREIMAGE,
|
|
35092
|
-
|
|
35093
|
-
UserRejectedRequestError,
|
|
35094
|
-
VanaError,
|
|
35799
|
+
USER_PS_ID_DOMAIN,
|
|
35095
35800
|
VanaStorage,
|
|
35096
35801
|
WRITER_ATTRIBUTION_KEY,
|
|
35097
35802
|
WRITE_CONTENT_DISPOSITION_HEADER,
|
|
@@ -35099,15 +35804,7 @@ export {
|
|
|
35099
35804
|
WRITE_METADATA_HEADER,
|
|
35100
35805
|
WRITE_SESSION_PATH,
|
|
35101
35806
|
WRITE_SIGNATURE_HEADER,
|
|
35102
|
-
|
|
35103
|
-
WriteForbiddenError,
|
|
35104
|
-
WriteLineageError,
|
|
35105
|
-
WriteRejectedError,
|
|
35106
|
-
WriteRequestError,
|
|
35107
|
-
WriteSessionError,
|
|
35108
|
-
WriteSessionExpiredError,
|
|
35109
|
-
WriteTransportError,
|
|
35110
|
-
WriteUnauthorizedError,
|
|
35807
|
+
appRootPreimage,
|
|
35111
35808
|
askPersonalServer,
|
|
35112
35809
|
assertDerivedScopeNaming,
|
|
35113
35810
|
assertValidPkceVerifier,
|
|
@@ -35117,6 +35814,7 @@ export {
|
|
|
35117
35814
|
buildDepositNativeRequest,
|
|
35118
35815
|
buildDepositTokenRequest,
|
|
35119
35816
|
buildMarkDataPointUnavailableRequest,
|
|
35817
|
+
buildMasterSignatureDelivery,
|
|
35120
35818
|
buildPersonalServerDataReadRequest,
|
|
35121
35819
|
buildPersonalServerLiteOwnerBindingMessage,
|
|
35122
35820
|
buildPersonalServerLiteOwnerBindingSignature,
|
|
@@ -35125,6 +35823,7 @@ export {
|
|
|
35125
35823
|
buildSetDataPointStatusRequest,
|
|
35126
35824
|
buildWeb3SignedHeader,
|
|
35127
35825
|
builderRegistrationDomain,
|
|
35826
|
+
canonicalJobRequestBytes,
|
|
35128
35827
|
chains,
|
|
35129
35828
|
clearContractCache,
|
|
35130
35829
|
computeBodyHash,
|
|
@@ -35156,6 +35855,7 @@ export {
|
|
|
35156
35855
|
encodeDepositTokenData,
|
|
35157
35856
|
encodeSetDataPointStatusData,
|
|
35158
35857
|
encodeWriteMetadataHeader,
|
|
35858
|
+
encryptMasterSignatureDelivery,
|
|
35159
35859
|
encryptWithPassword,
|
|
35160
35860
|
escrowContractAddress,
|
|
35161
35861
|
escrowPaymentDomain,
|
|
@@ -35190,12 +35890,16 @@ export {
|
|
|
35190
35890
|
isPlatformSupported,
|
|
35191
35891
|
isRedactedLineageNode,
|
|
35192
35892
|
isTombstoneHashes,
|
|
35893
|
+
kmsIssuedPreimage,
|
|
35193
35894
|
listQuestions,
|
|
35194
35895
|
mainnetServices,
|
|
35195
35896
|
moksha,
|
|
35196
35897
|
mokshaServices,
|
|
35197
35898
|
mokshaTestnet2 as mokshaTestnet,
|
|
35198
35899
|
normalizeBinaryMimeType,
|
|
35900
|
+
openJobRequest,
|
|
35901
|
+
openJobResult,
|
|
35902
|
+
openJobResultStream,
|
|
35199
35903
|
openWriteSession,
|
|
35200
35904
|
parsePSError,
|
|
35201
35905
|
parseScope,
|
|
@@ -35216,6 +35920,9 @@ export {
|
|
|
35216
35920
|
scopeMatchesPattern,
|
|
35217
35921
|
scopeNamespace,
|
|
35218
35922
|
scopeToPathSegments,
|
|
35923
|
+
sealJobRequest,
|
|
35924
|
+
sealJobResult,
|
|
35925
|
+
sealJobResultStream,
|
|
35219
35926
|
serializeECIES,
|
|
35220
35927
|
serverRegistrationDomain,
|
|
35221
35928
|
sessionCoversScope,
|
|
@@ -35224,7 +35931,9 @@ export {
|
|
|
35224
35931
|
signPersonalServerRegistrationWithAccount,
|
|
35225
35932
|
tombstoneDeletedAt,
|
|
35226
35933
|
tryGrantPermissions,
|
|
35934
|
+
userPsId,
|
|
35227
35935
|
vanaMainnet2 as vanaMainnet,
|
|
35936
|
+
verifyEnclaveIdentityEvidence,
|
|
35228
35937
|
verifyGrantRegistration,
|
|
35229
35938
|
verifyPkceChallenge,
|
|
35230
35939
|
verifyWeb3Signed,
|