@opendatalabs/vana-sdk 3.23.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +57 -0
  2. package/dist/auth/errors.cjs +1 -1
  3. package/dist/auth/web3-signed.cjs +1 -1
  4. package/dist/crypto/envelope/job-stream.test.d.ts +1 -0
  5. package/dist/crypto/envelope/job.cjs +593 -38
  6. package/dist/crypto/envelope/job.cjs.map +1 -1
  7. package/dist/crypto/envelope/job.d.ts +44 -27
  8. package/dist/crypto/envelope/job.js +589 -37
  9. package/dist/crypto/envelope/job.js.map +1 -1
  10. package/dist/direct/access-request-client.cjs +1 -1
  11. package/dist/direct/connect-flow.cjs +43 -1
  12. package/dist/direct/connect-flow.cjs.map +1 -1
  13. package/dist/direct/connect-flow.d.ts +12 -0
  14. package/dist/direct/connect-flow.js +43 -1
  15. package/dist/direct/connect-flow.js.map +1 -1
  16. package/dist/direct/controller.cjs +1 -1
  17. package/dist/direct/errors.cjs +1 -1
  18. package/dist/direct/escrow-payment.cjs.map +1 -1
  19. package/dist/direct/escrow-payment.d.ts +2 -2
  20. package/dist/direct/escrow-payment.js.map +1 -1
  21. package/dist/direct/personal-server-read.cjs +2 -2
  22. package/dist/direct/use-direct-vana-connect.cjs +2 -1
  23. package/dist/direct/use-direct-vana-connect.cjs.map +1 -1
  24. package/dist/direct/use-direct-vana-connect.d.ts +3 -1
  25. package/dist/direct/use-direct-vana-connect.js +2 -1
  26. package/dist/direct/use-direct-vana-connect.js.map +1 -1
  27. package/dist/error-entry-points.test.d.ts +1 -0
  28. package/dist/errors.cjs +7 -0
  29. package/dist/errors.cjs.map +1 -1
  30. package/dist/errors.d.ts +10 -0
  31. package/dist/errors.js +6 -0
  32. package/dist/errors.js.map +1 -1
  33. package/dist/index.browser.d.ts +4 -4
  34. package/dist/index.browser.js +889 -526
  35. package/dist/index.browser.js.map +4 -4
  36. package/dist/index.node.cjs +1042 -713
  37. package/dist/index.node.cjs.map +4 -4
  38. package/dist/index.node.d.ts +4 -4
  39. package/dist/index.node.js +996 -575
  40. package/dist/index.node.js.map +4 -4
  41. package/dist/protocol/data-point-deletion.cjs +1 -1
  42. package/dist/protocol/derivative-questions.cjs +1 -1
  43. package/dist/protocol/derivative-status.cjs +1 -1
  44. package/dist/protocol/eip712.cjs +28 -2
  45. package/dist/protocol/eip712.cjs.map +1 -1
  46. package/dist/protocol/eip712.d.ts +70 -0
  47. package/dist/protocol/eip712.js +24 -1
  48. package/dist/protocol/eip712.js.map +1 -1
  49. package/dist/protocol/escrow.cjs +154 -2
  50. package/dist/protocol/escrow.cjs.map +1 -1
  51. package/dist/protocol/escrow.d.ts +145 -2
  52. package/dist/protocol/escrow.js +152 -1
  53. package/dist/protocol/escrow.js.map +1 -1
  54. package/dist/protocol/fixtures/moksha-identity.json +20 -0
  55. package/dist/protocol/gateway.cjs +1 -1
  56. package/dist/protocol/gateway.cjs.map +1 -1
  57. package/dist/protocol/gateway.d.ts +8 -38
  58. package/dist/protocol/gateway.js.map +1 -1
  59. package/dist/protocol/identity.cjs +14 -10
  60. package/dist/protocol/identity.cjs.map +1 -1
  61. package/dist/protocol/identity.js +14 -10
  62. package/dist/protocol/identity.js.map +1 -1
  63. package/dist/protocol/jobs-client.cjs +73 -21
  64. package/dist/protocol/jobs-client.cjs.map +1 -1
  65. package/dist/protocol/jobs-client.d.ts +7 -5
  66. package/dist/protocol/jobs-client.js +74 -21
  67. package/dist/protocol/jobs-client.js.map +1 -1
  68. package/dist/protocol/jobs.cjs +0 -3
  69. package/dist/protocol/jobs.cjs.map +1 -1
  70. package/dist/protocol/jobs.d.ts +21 -13
  71. package/dist/protocol/jobs.js +0 -2
  72. package/dist/protocol/jobs.js.map +1 -1
  73. package/dist/protocol/lineage.cjs +1 -1
  74. package/dist/protocol/personal-server-data.cjs +1 -1
  75. package/dist/protocol/personal-server-write.cjs +1 -1
  76. package/dist/protocol/write-request.cjs +1 -1
  77. package/dist/protocol/write-signer.cjs +1 -1
  78. package/dist/react.cjs.map +1 -1
  79. package/dist/react.d.ts +1 -1
  80. package/dist/react.js.map +1 -1
  81. package/dist/session-relay/client.cjs +1 -1
  82. package/dist/session-relay/errors.cjs +1 -1
  83. package/dist/session-relay/index.cjs +1 -1
  84. package/package.json +1 -1
@@ -20,6 +20,7 @@ var __copyProps = (to, from, except, desc) => {
20
20
  }
21
21
  return to;
22
22
  };
23
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
23
24
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
25
  // If the importer is in node compatibility mode or this is not an ESM
25
26
  // file that has been converted to a CommonJS file using a Babel-
@@ -1178,14 +1179,11 @@ __export(index_node_exports, {
1178
1179
  AccountPersonalServerLiteOwnerBindingError: () => AccountPersonalServerLiteOwnerBindingError,
1179
1180
  AccountPersonalServerRegistrationError: () => AccountPersonalServerRegistrationError,
1180
1181
  BUILDER_REGISTRATION_TYPES: () => BUILDER_REGISTRATION_TYPES,
1181
- BlockchainError: () => BlockchainError,
1182
1182
  BrowserPlatformAdapter: () => BrowserPlatformAdapter,
1183
- BuilderUnknownError: () => BuilderUnknownError,
1184
1183
  CLAIM_POLL_FLOOR_MS: () => CLAIM_POLL_FLOOR_MS,
1185
1184
  CONTRACTS: () => CONTRACTS,
1186
1185
  CallbackStorage: () => CallbackStorage,
1187
1186
  ContractFactory: () => ContractFactory,
1188
- ContractNotFoundError: () => ContractNotFoundError,
1189
1187
  DATA_ACCESS_OP_TYPE: () => DATA_ACCESS_OP_TYPE,
1190
1188
  DATA_REGISTRY_STATUS_ABI: () => DATA_REGISTRY_STATUS_ABI,
1191
1189
  DEFAULT_DERIVATIVE_STATUS_POLL_INTERVAL_MS: () => DEFAULT_DERIVATIVE_STATUS_POLL_INTERVAL_MS,
@@ -1198,21 +1196,9 @@ __export(index_node_exports, {
1198
1196
  DERIVATIVE_QUESTIONS_PATH: () => DERIVATIVE_QUESTIONS_PATH,
1199
1197
  DERIVATIVE_STATUS_PATH: () => DERIVATIVE_STATUS_PATH,
1200
1198
  DataFileEnvelopeSchema: () => DataFileEnvelopeSchema,
1201
- DataPointDeletedError: () => DataPointDeletedError,
1202
- DataPointNotFoundError: () => DataPointNotFoundError,
1203
1199
  DataPointStatus: () => DataPointStatus,
1204
- DataPointVersionConflictError: () => DataPointVersionConflictError,
1205
- DerivativeComputeUnavailableError: () => DerivativeComputeUnavailableError,
1206
- DerivativeCycleError: () => DerivativeCycleError,
1207
- DerivativeDerivedScopeRequiredError: () => DerivativeDerivedScopeRequiredError,
1208
1200
  DerivativeErrorCodeSchema: () => DerivativeErrorCodeSchema,
1209
- DerivativeQuestionFailedError: () => DerivativeQuestionFailedError,
1210
- DerivativeQuestionInvalidError: () => DerivativeQuestionInvalidError,
1211
- DerivativeQuestionNotFoundError: () => DerivativeQuestionNotFoundError,
1212
- DerivativeQuestionRejectedError: () => DerivativeQuestionRejectedError,
1213
1201
  DerivativeQuestionSchema: () => DerivativeQuestionSchema,
1214
- DerivativeQuestionTimeoutError: () => DerivativeQuestionTimeoutError,
1215
- DerivativeSourceNotGrantedError: () => DerivativeSourceNotGrantedError,
1216
1202
  DerivativeStatusSchema: () => DerivativeStatusSchema,
1217
1203
  DropboxStorage: () => DropboxStorage,
1218
1204
  ECIESError: () => ECIESError,
@@ -1220,42 +1206,35 @@ __export(index_node_exports, {
1220
1206
  ENCLAVE_TRUST_ANCHORS: () => ENCLAVE_TRUST_ANCHORS,
1221
1207
  ENCLAVE_WALLET_PURPOSE: () => ENCLAVE_WALLET_PURPOSE,
1222
1208
  ESCROW_DEPOSIT_ABI: () => ESCROW_DEPOSIT_ABI2,
1223
- ExpiredTokenError: () => ExpiredTokenError,
1209
+ EscrowWithdrawalLifecycleError: () => EscrowWithdrawalLifecycleError,
1210
+ EscrowWithdrawalRejectionError: () => EscrowWithdrawalRejectionError,
1211
+ ExpiredTokenError: () => import_errors14.ExpiredTokenError,
1224
1212
  FEE_REGISTRY_ABI: () => FEE_REGISTRY_ABI,
1225
1213
  GENERIC_PAYMENT_TYPES: () => GENERIC_PAYMENT_TYPES,
1226
1214
  GRANT_OP_TYPE: () => GRANT_OP_TYPE,
1227
1215
  GRANT_REGISTRATION_TYPES: () => GRANT_REGISTRATION_TYPES,
1228
1216
  GRANT_REVOCATION_TYPES: () => GRANT_REVOCATION_TYPES,
1229
1217
  GoogleDriveStorage: () => GoogleDriveStorage,
1230
- GrantInvalidError: () => GrantInvalidError,
1231
1218
  InMemoryTokenStore: () => InMemoryTokenStore,
1232
1219
  IngestResponseSchema: () => IngestResponseSchema,
1233
- InvalidConfigurationError: () => InvalidConfigurationError,
1234
1220
  InvalidScopeEntryError: () => InvalidScopeEntryError,
1235
- InvalidSignatureError: () => InvalidSignatureError,
1221
+ InvalidSignatureError: () => import_errors14.InvalidSignatureError,
1236
1222
  IpfsStorage: () => IpfsStorage,
1237
1223
  JOB_OPERATIONS: () => JOB_OPERATIONS,
1238
1224
  JOB_PROTOCOL_VERSION: () => JOB_PROTOCOL_VERSION,
1225
+ JOB_RESULT_CHUNK_BYTES: () => JOB_RESULT_CHUNK_BYTES,
1226
+ JOB_RESULT_FORMAT_VERSION: () => JOB_RESULT_FORMAT_VERSION,
1239
1227
  JOB_STATES: () => JOB_STATES,
1240
1228
  JobEnvelopeError: () => JobEnvelopeError,
1241
- JobIdTakenError: () => JobIdTakenError,
1242
- JobNotFoundError: () => JobNotFoundError,
1243
- JobRejectedError: () => JobRejectedError,
1244
- JobRequestTooLargeError: () => JobRequestTooLargeError,
1245
- JobTimeoutError: () => JobTimeoutError,
1246
- JobTransportError: () => JobTransportError,
1247
- JobsClientError: () => JobsClientError,
1248
1229
  LINEAGE_FIELD: () => LINEAGE_FIELD,
1249
1230
  LINEAGE_KEY: () => LINEAGE_KEY,
1250
1231
  LineageEntrySchema: () => LineageEntrySchema,
1251
1232
  LineageGraphSchema: () => LineageGraphSchema,
1252
1233
  LineageNodeSchema: () => LineageNodeSchema,
1253
- LineageReadError: () => LineageReadError,
1254
1234
  MASTER_KEY_MESSAGE: () => MASTER_KEY_MESSAGE,
1255
1235
  MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS: () => MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS,
1256
1236
  MASTER_SIGNATURE_DELIVERY_VERSION: () => MASTER_SIGNATURE_DELIVERY_VERSION,
1257
1237
  MAX_ATTEMPTS: () => MAX_ATTEMPTS,
1258
- MAX_INLINE_RESULT_BYTES: () => MAX_INLINE_RESULT_BYTES,
1259
1238
  MAX_JOB_DEADLINE_SECONDS: () => MAX_JOB_DEADLINE_SECONDS,
1260
1239
  MAX_LEASE_SECONDS: () => MAX_LEASE_SECONDS,
1261
1240
  MAX_LINEAGE_SOURCES: () => MAX_LINEAGE_SOURCES,
@@ -1263,15 +1242,12 @@ __export(index_node_exports, {
1263
1242
  MAX_QUESTION_MODEL_CHARS: () => MAX_QUESTION_MODEL_CHARS,
1264
1243
  MAX_QUESTION_SOURCE_SCOPES: () => MAX_QUESTION_SOURCE_SCOPES,
1265
1244
  MAX_WAIT_SECONDS: () => MAX_WAIT_SECONDS,
1266
- MissingAuthError: () => MissingAuthError,
1245
+ MissingAuthError: () => import_errors14.MissingAuthError,
1267
1246
  NATIVE_ASSET_ADDRESS: () => NATIVE_ASSET_ADDRESS,
1268
1247
  NATIVE_VANA_ASSET: () => NATIVE_VANA_ASSET,
1269
- NetworkError: () => NetworkError,
1270
1248
  NodeECIESProvider: () => NodeECIESUint8Provider,
1271
1249
  NodePlatformAdapter: () => NodePlatformAdapter,
1272
- NonceError: () => NonceError,
1273
1250
  OAuthClient: () => OAuthClient,
1274
- OwnerNotReadyError: () => OwnerNotReadyError,
1275
1251
  PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX: () => PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX,
1276
1252
  PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE: () => PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE,
1277
1253
  PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION: () => PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION,
@@ -1280,9 +1256,6 @@ __export(index_node_exports, {
1280
1256
  PKCE_CHALLENGE_PATTERN: () => PKCE_CHALLENGE_PATTERN,
1281
1257
  PKCE_VERIFIER_PATTERN: () => PKCE_VERIFIER_PATTERN,
1282
1258
  PSError: () => PSError,
1283
- PermissionError: () => PermissionError,
1284
- PersonalServerError: () => PersonalServerError,
1285
- PersonalServerWriteError: () => PersonalServerWriteError,
1286
1259
  PinataStorage: () => PinataStorage,
1287
1260
  QUESTION_STATUSES: () => QUESTION_STATUSES,
1288
1261
  QuestionDeleteResultSchema: () => QuestionDeleteResultSchema,
@@ -1293,42 +1266,26 @@ __export(index_node_exports, {
1293
1266
  RECORD_DATA_ACCESS_TYPES: () => RECORD_DATA_ACCESS_TYPES,
1294
1267
  REGISTRATION_KIND_FOR_OP: () => REGISTRATION_KIND_FOR_OP,
1295
1268
  RESERVED_WRITE_KEYS: () => RESERVED_WRITE_KEYS,
1296
- ReadOnlyError: () => ReadOnlyError,
1297
1269
  RedactedLineageNodeSchema: () => RedactedLineageNodeSchema,
1298
- RelayerError: () => RelayerError,
1299
1270
  SCOPE_ACTIONS: () => SCOPE_ACTIONS,
1300
1271
  SEALED_ENVELOPE_VERSION: () => SEALED_ENVELOPE_VERSION,
1301
1272
  SERVER_REGISTRATION_TYPES: () => SERVER_REGISTRATION_TYPES,
1302
1273
  ScopeSchema: () => ScopeSchema,
1303
- SerializationError: () => SerializationError,
1304
- ServerUrlMismatchError: () => ServerUrlMismatchError,
1305
- SignatureError: () => SignatureError,
1306
1274
  StorageError: () => StorageError,
1307
1275
  StorageManager: () => StorageManager,
1308
1276
  TOMBSTONE_DATA_HASH: () => TOMBSTONE_DATA_HASH,
1309
1277
  TOMBSTONE_DATA_HASH_PREIMAGE: () => TOMBSTONE_DATA_HASH_PREIMAGE,
1310
1278
  TOMBSTONE_METADATA_HASH: () => TOMBSTONE_METADATA_HASH,
1311
1279
  TOMBSTONE_METADATA_HASH_PREIMAGE: () => TOMBSTONE_METADATA_HASH_PREIMAGE,
1312
- TransactionPendingError: () => TransactionPendingError,
1313
1280
  USER_PS_ID_DOMAIN: () => USER_PS_ID_DOMAIN,
1314
- UserRejectedRequestError: () => UserRejectedRequestError,
1315
- VanaError: () => VanaError,
1316
1281
  VanaStorage: () => VanaStorage,
1282
+ WITHDRAW_AUTHORIZATION_TYPES: () => WITHDRAW_AUTHORIZATION_TYPES,
1317
1283
  WRITER_ATTRIBUTION_KEY: () => WRITER_ATTRIBUTION_KEY,
1318
1284
  WRITE_CONTENT_DISPOSITION_HEADER: () => WRITE_CONTENT_DISPOSITION_HEADER,
1319
1285
  WRITE_FILENAME_HEADER: () => WRITE_FILENAME_HEADER,
1320
1286
  WRITE_METADATA_HEADER: () => WRITE_METADATA_HEADER,
1321
1287
  WRITE_SESSION_PATH: () => WRITE_SESSION_PATH,
1322
1288
  WRITE_SIGNATURE_HEADER: () => WRITE_SIGNATURE_HEADER,
1323
- WriteConflictError: () => WriteConflictError,
1324
- WriteForbiddenError: () => WriteForbiddenError,
1325
- WriteLineageError: () => WriteLineageError,
1326
- WriteRejectedError: () => WriteRejectedError,
1327
- WriteRequestError: () => WriteRequestError,
1328
- WriteSessionError: () => WriteSessionError,
1329
- WriteSessionExpiredError: () => WriteSessionExpiredError,
1330
- WriteTransportError: () => WriteTransportError,
1331
- WriteUnauthorizedError: () => WriteUnauthorizedError,
1332
1289
  appRootPreimage: () => appRootPreimage,
1333
1290
  askPersonalServer: () => askPersonalServer,
1334
1291
  assertDerivedScopeNaming: () => assertDerivedScopeNaming,
@@ -1351,6 +1308,7 @@ __export(index_node_exports, {
1351
1308
  buildPersonalServerRegistrationTypedData: () => buildPersonalServerRegistrationTypedData,
1352
1309
  buildSetDataPointStatusRequest: () => buildSetDataPointStatusRequest,
1353
1310
  buildWeb3SignedHeader: () => buildWeb3SignedHeader,
1311
+ buildWithdrawAuthorizationTypedData: () => buildWithdrawAuthorizationTypedData,
1354
1312
  builderRegistrationDomain: () => builderRegistrationDomain,
1355
1313
  canonicalJobRequestBytes: () => canonicalJobRequestBytes,
1356
1314
  chains: () => chains,
@@ -1433,6 +1391,7 @@ __export(index_node_exports, {
1433
1391
  normalizeBinaryMimeType: () => normalizeBinaryMimeType,
1434
1392
  openJobRequest: () => openJobRequest,
1435
1393
  openJobResult: () => openJobResult,
1394
+ openJobResultStream: () => openJobResultStream,
1436
1395
  openWriteSession: () => openWriteSession,
1437
1396
  parsePSError: () => parsePSError,
1438
1397
  parsePersonalServerPaymentRequired: () => parsePersonalServerPaymentRequired,
@@ -1458,6 +1417,7 @@ __export(index_node_exports, {
1458
1417
  scopeToPathSegments: () => scopeToPathSegments,
1459
1418
  sealJobRequest: () => sealJobRequest,
1460
1419
  sealJobResult: () => sealJobResult,
1420
+ sealJobResultStream: () => sealJobResultStream,
1461
1421
  serializeECIES: () => serializeECIES,
1462
1422
  serverRegistrationDomain: () => serverRegistrationDomain,
1463
1423
  sessionCoversScope: () => sessionCoversScope,
@@ -1476,351 +1436,12 @@ __export(index_node_exports, {
1476
1436
  verifyWeb3Signed: () => verifyWeb3Signed,
1477
1437
  waitForDerivativeStatus: () => waitForDerivativeStatus,
1478
1438
  waitForQuestion: () => waitForQuestion,
1439
+ withdrawAuthorizationDomain: () => withdrawAuthorizationDomain,
1479
1440
  writeData: () => writeData,
1480
1441
  writePersonalServerData: () => writePersonalServerData
1481
1442
  });
1482
1443
  module.exports = __toCommonJS(index_node_exports);
1483
-
1484
- // src/errors.ts
1485
- var VanaError = class extends Error {
1486
- constructor(message, code) {
1487
- super(message);
1488
- this.code = code;
1489
- this.name = this.constructor.name;
1490
- if (Error.captureStackTrace) {
1491
- Error.captureStackTrace(this, this.constructor);
1492
- }
1493
- }
1494
- code;
1495
- };
1496
- var RelayerError = class extends VanaError {
1497
- constructor(message, statusCode, response) {
1498
- super(message, "RELAYER_ERROR");
1499
- this.statusCode = statusCode;
1500
- this.response = response;
1501
- }
1502
- statusCode;
1503
- response;
1504
- };
1505
- var UserRejectedRequestError = class extends VanaError {
1506
- constructor(message = "User rejected the signature request") {
1507
- super(message, "USER_REJECTED_REQUEST");
1508
- }
1509
- };
1510
- var InvalidConfigurationError = class extends VanaError {
1511
- constructor(message) {
1512
- super(message, "INVALID_CONFIGURATION");
1513
- }
1514
- };
1515
- var ContractNotFoundError = class extends VanaError {
1516
- constructor(contractName, chainId) {
1517
- super(
1518
- `Contract ${contractName} not found on chain ${chainId}`,
1519
- "CONTRACT_NOT_FOUND"
1520
- );
1521
- }
1522
- };
1523
- var BlockchainError = class extends VanaError {
1524
- constructor(message, originalError) {
1525
- super(message, "BLOCKCHAIN_ERROR");
1526
- this.originalError = originalError;
1527
- }
1528
- originalError;
1529
- };
1530
- var SerializationError = class extends VanaError {
1531
- constructor(message) {
1532
- super(message, "SERIALIZATION_ERROR");
1533
- }
1534
- };
1535
- var SignatureError = class extends VanaError {
1536
- constructor(message, originalError) {
1537
- super(message, "SIGNATURE_ERROR");
1538
- this.originalError = originalError;
1539
- }
1540
- originalError;
1541
- };
1542
- var NetworkError = class extends VanaError {
1543
- constructor(message, originalError) {
1544
- super(message, "NETWORK_ERROR");
1545
- this.originalError = originalError;
1546
- }
1547
- originalError;
1548
- };
1549
- var NonceError = class extends VanaError {
1550
- constructor(message) {
1551
- super(message, "NONCE_ERROR");
1552
- }
1553
- };
1554
- var PersonalServerError = class extends VanaError {
1555
- constructor(message, originalError) {
1556
- super(message, "PERSONAL_SERVER_ERROR");
1557
- this.originalError = originalError;
1558
- }
1559
- originalError;
1560
- };
1561
- var ServerUrlMismatchError = class extends VanaError {
1562
- constructor(existingUrl, providedUrl, serverId) {
1563
- super(
1564
- `Server ${serverId} is already registered with URL "${existingUrl}". Cannot change to "${providedUrl}".`,
1565
- "SERVER_URL_MISMATCH"
1566
- );
1567
- this.existingUrl = existingUrl;
1568
- this.providedUrl = providedUrl;
1569
- this.serverId = serverId;
1570
- }
1571
- existingUrl;
1572
- providedUrl;
1573
- serverId;
1574
- };
1575
- var PermissionError = class extends VanaError {
1576
- constructor(message, originalError) {
1577
- super(message, "PERMISSION_ERROR");
1578
- this.originalError = originalError;
1579
- }
1580
- originalError;
1581
- };
1582
- var ReadOnlyError = class extends VanaError {
1583
- constructor(operation, suggestion = "Initialize the SDK with a walletClient to perform this operation") {
1584
- super(
1585
- `Operation '${operation}' requires a wallet client. ${suggestion}`,
1586
- "READ_ONLY_ERROR"
1587
- );
1588
- this.operation = operation;
1589
- this.suggestion = suggestion;
1590
- }
1591
- /** The operation that was attempted */
1592
- operation;
1593
- /** Suggested solution for fixing the error */
1594
- suggestion;
1595
- };
1596
- var TransactionPendingError = class extends VanaError {
1597
- constructor(operationId, message, lastKnownStatus) {
1598
- super(
1599
- `Transaction operation pending: ${message} (operationId: ${operationId})`,
1600
- "TRANSACTION_PENDING"
1601
- );
1602
- this.operationId = operationId;
1603
- this.lastKnownStatus = lastKnownStatus;
1604
- }
1605
- operationId;
1606
- lastKnownStatus;
1607
- /**
1608
- * Converts the error to a JSON-serializable format.
1609
- *
1610
- * @remarks
1611
- * Useful for logging, storage, or transmission of error details.
1612
- *
1613
- * @returns JSON representation of the error
1614
- */
1615
- toJSON() {
1616
- return {
1617
- name: this.name,
1618
- code: this.code,
1619
- message: this.message,
1620
- operationId: this.operationId,
1621
- lastKnownStatus: this.lastKnownStatus
1622
- };
1623
- }
1624
- };
1625
- var PersonalServerWriteError = class extends VanaError {
1626
- constructor(message, code, status, errorCode = null, details) {
1627
- super(message, code);
1628
- this.status = status;
1629
- this.errorCode = errorCode;
1630
- this.details = details;
1631
- }
1632
- status;
1633
- errorCode;
1634
- details;
1635
- };
1636
- var WriteRequestError = class extends PersonalServerWriteError {
1637
- constructor(message, details) {
1638
- super(message, "WRITE_INVALID_REQUEST", void 0, null, details);
1639
- }
1640
- };
1641
- var WriteTransportError = class extends PersonalServerWriteError {
1642
- constructor(message, attempts, cause) {
1643
- super(message, "WRITE_TRANSPORT_ERROR", void 0, null, { attempts });
1644
- this.attempts = attempts;
1645
- this.cause = cause;
1646
- }
1647
- attempts;
1648
- };
1649
- var WriteSessionError = class extends PersonalServerWriteError {
1650
- constructor(message, status, errorCode = null, details) {
1651
- super(message, "WRITE_SESSION_REJECTED", status, errorCode, details);
1652
- }
1653
- };
1654
- var WriteSessionExpiredError = class extends PersonalServerWriteError {
1655
- constructor(message, details) {
1656
- super(message, "WRITE_SESSION_EXPIRED", void 0, null, details);
1657
- }
1658
- };
1659
- var WriteUnauthorizedError = class extends PersonalServerWriteError {
1660
- constructor(message, errorCode = null, details) {
1661
- super(message, "WRITE_UNAUTHORIZED", 401, errorCode, details);
1662
- }
1663
- };
1664
- var WriteForbiddenError = class extends PersonalServerWriteError {
1665
- constructor(message, errorCode = null, details) {
1666
- super(message, "WRITE_FORBIDDEN", 403, errorCode, details);
1667
- }
1668
- };
1669
- var WriteConflictError = class extends PersonalServerWriteError {
1670
- constructor(message, errorCode = null, details) {
1671
- super(message, "WRITE_CONFLICT", 409, errorCode, details);
1672
- }
1673
- };
1674
- var WriteLineageError = class extends PersonalServerWriteError {
1675
- constructor(message, status = 422, errorCode = null, details) {
1676
- super(message, "WRITE_LINEAGE_REJECTED", status, errorCode, details);
1677
- }
1678
- };
1679
- var WriteRejectedError = class extends PersonalServerWriteError {
1680
- constructor(message, status, errorCode = null, details) {
1681
- super(message, "WRITE_REJECTED", status, errorCode, details);
1682
- }
1683
- };
1684
- var JobsClientError = class extends VanaError {
1685
- constructor(message, code, status, errorCode = null, details) {
1686
- super(message, code);
1687
- this.status = status;
1688
- this.errorCode = errorCode;
1689
- this.details = details;
1690
- }
1691
- status;
1692
- errorCode;
1693
- details;
1694
- };
1695
- var BuilderUnknownError = class extends JobsClientError {
1696
- constructor(message, details) {
1697
- super(message, "JOB_BUILDER_UNKNOWN", 403, "BUILDER_UNKNOWN", details);
1698
- }
1699
- };
1700
- var GrantInvalidError = class extends JobsClientError {
1701
- constructor(message, details) {
1702
- super(message, "JOB_GRANT_INVALID", 403, "GRANT_INVALID", details);
1703
- }
1704
- };
1705
- var OwnerNotReadyError = class extends JobsClientError {
1706
- constructor(message, details) {
1707
- super(message, "JOB_OWNER_NOT_READY", 403, "OWNER_NOT_READY", details);
1708
- }
1709
- };
1710
- var JobIdTakenError = class extends JobsClientError {
1711
- constructor(message, details) {
1712
- super(message, "JOB_ID_TAKEN", 409, "JOB_ID_TAKEN", details);
1713
- }
1714
- };
1715
- var JobNotFoundError = class extends JobsClientError {
1716
- constructor(message, details) {
1717
- super(message, "JOB_NOT_FOUND", 404, "JOB_NOT_FOUND", details);
1718
- }
1719
- };
1720
- var JobRequestTooLargeError = class extends JobsClientError {
1721
- constructor(message, errorCode = "BODY_TOO_LARGE", details) {
1722
- super(message, "JOB_REQUEST_TOO_LARGE", 413, errorCode, details);
1723
- }
1724
- };
1725
- var JobTimeoutError = class extends JobsClientError {
1726
- constructor(message, details) {
1727
- super(message, "JOB_TIMEOUT", void 0, null, details);
1728
- }
1729
- };
1730
- var JobRejectedError = class extends JobsClientError {
1731
- constructor(message, status, errorCode = null, details) {
1732
- super(message, "JOB_REJECTED", status, errorCode, details);
1733
- }
1734
- };
1735
- var JobTransportError = class extends JobsClientError {
1736
- constructor(message, cause) {
1737
- super(message, "JOB_TRANSPORT_ERROR");
1738
- this.cause = cause;
1739
- }
1740
- };
1741
- var LineageReadError = class extends VanaError {
1742
- constructor(message, status, errorCode = null, details) {
1743
- super(message, "LINEAGE_READ_ERROR");
1744
- this.status = status;
1745
- this.errorCode = errorCode;
1746
- this.details = details;
1747
- }
1748
- status;
1749
- errorCode;
1750
- details;
1751
- };
1752
- var DerivativeQuestionRejectedError = class extends PersonalServerWriteError {
1753
- constructor(message, status, errorCode = null, details) {
1754
- super(message, "DERIVATIVE_QUESTION_REJECTED", status, errorCode, details);
1755
- }
1756
- };
1757
- var DerivativeQuestionInvalidError = class extends PersonalServerWriteError {
1758
- constructor(message, status = 400, errorCode = null, details) {
1759
- super(message, "DERIVATIVE_QUESTION_INVALID", status, errorCode, details);
1760
- }
1761
- };
1762
- var DerivativeQuestionNotFoundError = class extends PersonalServerWriteError {
1763
- constructor(message, errorCode = null, details) {
1764
- super(message, "DERIVATIVE_QUESTION_NOT_FOUND", 404, errorCode, details);
1765
- }
1766
- };
1767
- var DerivativeDerivedScopeRequiredError = class extends PersonalServerWriteError {
1768
- constructor(message, errorCode = null, details) {
1769
- super(
1770
- message,
1771
- "DERIVATIVE_DERIVED_SCOPE_REQUIRED",
1772
- 400,
1773
- errorCode,
1774
- details
1775
- );
1776
- }
1777
- };
1778
- var DerivativeSourceNotGrantedError = class extends PersonalServerWriteError {
1779
- constructor(message, errorCode = null, details) {
1780
- super(message, "DERIVATIVE_SOURCE_NOT_GRANTED", 403, errorCode, details);
1781
- }
1782
- };
1783
- var DerivativeCycleError = class extends PersonalServerWriteError {
1784
- constructor(message, errorCode = null, details) {
1785
- super(message, "DERIVATIVE_CYCLE", 409, errorCode, details);
1786
- }
1787
- };
1788
- var DerivativeComputeUnavailableError = class extends PersonalServerWriteError {
1789
- constructor(message, errorCode = null, details) {
1790
- super(message, "DERIVATIVE_COMPUTE_UNAVAILABLE", 503, errorCode, details);
1791
- }
1792
- };
1793
- var DerivativeQuestionTimeoutError = class extends PersonalServerWriteError {
1794
- constructor(message, details) {
1795
- super(message, "DERIVATIVE_QUESTION_TIMEOUT", void 0, null, details);
1796
- }
1797
- };
1798
- var DerivativeQuestionFailedError = class extends PersonalServerWriteError {
1799
- constructor(message, details) {
1800
- super(message, "DERIVATIVE_QUESTION_FAILED", void 0, null, details);
1801
- }
1802
- };
1803
- var DataPointDeletedError = class extends VanaError {
1804
- constructor(message, details = {}) {
1805
- super(message, "DATA_POINT_DELETED");
1806
- this.details = details;
1807
- }
1808
- details;
1809
- };
1810
- var DataPointNotFoundError = class extends VanaError {
1811
- constructor(message, details = {}) {
1812
- super(message, "DATA_POINT_NOT_FOUND");
1813
- this.details = details;
1814
- }
1815
- details;
1816
- };
1817
- var DataPointVersionConflictError = class extends VanaError {
1818
- constructor(message, details = {}) {
1819
- super(message, "DATA_POINT_VERSION_CONFLICT");
1820
- this.details = details;
1821
- }
1822
- details;
1823
- };
1444
+ __reExport(index_node_exports, require("./errors.cjs"), module.exports);
1824
1445
 
1825
1446
  // src/contracts/contractController.ts
1826
1447
  var import_viem3 = require("viem");
@@ -32182,31 +31803,7 @@ async function decryptWithPassword(encrypted, password) {
32182
31803
 
32183
31804
  // src/auth/web3-signed.ts
32184
31805
  var import_viem13 = require("viem");
32185
-
32186
- // src/auth/errors.ts
32187
- var MissingAuthError = class extends VanaError {
32188
- constructor(message = "Missing authentication", details) {
32189
- super(message, "MISSING_AUTH");
32190
- this.details = details;
32191
- }
32192
- details;
32193
- };
32194
- var InvalidSignatureError = class extends VanaError {
32195
- constructor(details, message = "Invalid signature") {
32196
- super(message, "INVALID_SIGNATURE");
32197
- this.details = details;
32198
- }
32199
- details;
32200
- };
32201
- var ExpiredTokenError = class extends VanaError {
32202
- constructor(details, message = "Token has expired") {
32203
- super(message, "EXPIRED_TOKEN");
32204
- this.details = details;
32205
- }
32206
- details;
32207
- };
32208
-
32209
- // src/auth/web3-signed.ts
31806
+ var import_errors = require("./auth/errors.cjs");
32210
31807
  var WEB3_SIGNED_PREFIX = "Web3Signed ";
32211
31808
  var CLOCK_SKEW_SECONDS = 60;
32212
31809
  function base64urlDecode(input) {
@@ -32220,14 +31817,14 @@ function isFiniteNumber(value) {
32220
31817
  }
32221
31818
  function parsePayload(value) {
32222
31819
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
32223
- throw new InvalidSignatureError({ reason: "Invalid payload shape" });
31820
+ throw new import_errors.InvalidSignatureError({ reason: "Invalid payload shape" });
32224
31821
  }
32225
31822
  const payload = value;
32226
31823
  if (typeof payload["aud"] !== "string" || typeof payload["method"] !== "string" || typeof payload["uri"] !== "string" || typeof payload["bodyHash"] !== "string" || !isFiniteNumber(payload["iat"]) || !isFiniteNumber(payload["exp"])) {
32227
- throw new InvalidSignatureError({ reason: "Invalid payload claims" });
31824
+ throw new import_errors.InvalidSignatureError({ reason: "Invalid payload claims" });
32228
31825
  }
32229
31826
  if (payload["grantId"] !== void 0 && typeof payload["grantId"] !== "string") {
32230
- throw new InvalidSignatureError({ reason: "Invalid grantId claim" });
31827
+ throw new import_errors.InvalidSignatureError({ reason: "Invalid grantId claim" });
32231
31828
  }
32232
31829
  return {
32233
31830
  aud: payload["aud"],
@@ -32241,28 +31838,28 @@ function parsePayload(value) {
32241
31838
  }
32242
31839
  function parseWeb3SignedHeader(headerValue) {
32243
31840
  if (!headerValue) {
32244
- throw new MissingAuthError();
31841
+ throw new import_errors.MissingAuthError();
32245
31842
  }
32246
31843
  if (!headerValue.startsWith(WEB3_SIGNED_PREFIX)) {
32247
- throw new InvalidSignatureError({ reason: "Missing Web3Signed prefix" });
31844
+ throw new import_errors.InvalidSignatureError({ reason: "Missing Web3Signed prefix" });
32248
31845
  }
32249
31846
  const value = headerValue.slice(WEB3_SIGNED_PREFIX.length);
32250
31847
  const dotIndex = value.indexOf(".");
32251
31848
  if (dotIndex === -1 || dotIndex === 0 || dotIndex === value.length - 1) {
32252
- throw new InvalidSignatureError({ reason: "Invalid header format" });
31849
+ throw new import_errors.InvalidSignatureError({ reason: "Invalid header format" });
32253
31850
  }
32254
31851
  const payloadBase64 = value.slice(0, dotIndex);
32255
31852
  const signatureStr = value.slice(dotIndex + 1);
32256
31853
  if (!signatureStr.startsWith("0x")) {
32257
- throw new InvalidSignatureError({ reason: "Invalid signature format" });
31854
+ throw new import_errors.InvalidSignatureError({ reason: "Invalid signature format" });
32258
31855
  }
32259
31856
  let payload;
32260
31857
  try {
32261
31858
  const decoded = base64urlDecode(payloadBase64);
32262
31859
  payload = parsePayload(JSON.parse(decoded));
32263
31860
  } catch (err) {
32264
- if (err instanceof InvalidSignatureError) throw err;
32265
- throw new InvalidSignatureError({ reason: "Invalid payload encoding" });
31861
+ if (err instanceof import_errors.InvalidSignatureError) throw err;
31862
+ throw new import_errors.InvalidSignatureError({ reason: "Invalid payload encoding" });
32266
31863
  }
32267
31864
  return {
32268
31865
  payloadBase64,
@@ -32281,24 +31878,24 @@ async function verifyWeb3Signed(params) {
32281
31878
  signature
32282
31879
  });
32283
31880
  } catch {
32284
- throw new InvalidSignatureError({ reason: "Signature recovery failed" });
31881
+ throw new import_errors.InvalidSignatureError({ reason: "Signature recovery failed" });
32285
31882
  }
32286
31883
  if (payload.aud !== params.expectedOrigin) {
32287
- throw new InvalidSignatureError({
31884
+ throw new import_errors.InvalidSignatureError({
32288
31885
  reason: "Audience mismatch",
32289
31886
  expected: params.expectedOrigin,
32290
31887
  actual: payload.aud
32291
31888
  });
32292
31889
  }
32293
31890
  if (payload.method !== params.expectedMethod) {
32294
- throw new InvalidSignatureError({
31891
+ throw new import_errors.InvalidSignatureError({
32295
31892
  reason: "Method mismatch",
32296
31893
  expected: params.expectedMethod,
32297
31894
  actual: payload.method
32298
31895
  });
32299
31896
  }
32300
31897
  if (payload.uri !== params.expectedPath) {
32301
- throw new InvalidSignatureError({
31898
+ throw new import_errors.InvalidSignatureError({
32302
31899
  reason: "URI mismatch",
32303
31900
  expected: params.expectedPath,
32304
31901
  actual: payload.uri
@@ -32307,7 +31904,7 @@ async function verifyWeb3Signed(params) {
32307
31904
  if (params.bodyBytes !== void 0) {
32308
31905
  const expectedBodyHash = computeBodyHash(params.bodyBytes);
32309
31906
  if (payload.bodyHash !== expectedBodyHash) {
32310
- throw new InvalidSignatureError({
31907
+ throw new import_errors.InvalidSignatureError({
32311
31908
  reason: "Body hash mismatch",
32312
31909
  expected: expectedBodyHash,
32313
31910
  actual: payload.bodyHash
@@ -32316,14 +31913,17 @@ async function verifyWeb3Signed(params) {
32316
31913
  }
32317
31914
  const now = params.now ?? Math.floor(Date.now() / 1e3);
32318
31915
  if (payload.exp < now - CLOCK_SKEW_SECONDS) {
32319
- throw new ExpiredTokenError({ reason: "Token expired" });
31916
+ throw new import_errors.ExpiredTokenError({ reason: "Token expired" });
32320
31917
  }
32321
31918
  if (payload.iat > now + CLOCK_SKEW_SECONDS) {
32322
- throw new ExpiredTokenError({ reason: "Token issued in the future" });
31919
+ throw new import_errors.ExpiredTokenError({ reason: "Token issued in the future" });
32323
31920
  }
32324
31921
  return { signer, payload };
32325
31922
  }
32326
31923
 
31924
+ // src/index.node.ts
31925
+ var import_errors14 = require("./auth/errors.cjs");
31926
+
32327
31927
  // src/auth/pkce.ts
32328
31928
  var PKCE_VERIFIER_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
32329
31929
  var PKCE_VERIFIER_MIN_LENGTH = 43;
@@ -32691,6 +32291,9 @@ function escrowPaymentDomain(config) {
32691
32291
  config.contracts.dataPortabilityEscrow
32692
32292
  );
32693
32293
  }
32294
+ function withdrawAuthorizationDomain(config) {
32295
+ return escrowPaymentDomain(config);
32296
+ }
32694
32297
  var GRANT_REGISTRATION_TYPES = {
32695
32298
  GrantRegistration: [
32696
32299
  { name: "grantorAddress", type: "address" },
@@ -32723,6 +32326,15 @@ var BUILDER_REGISTRATION_TYPES = {
32723
32326
  { name: "appUrl", type: "string" }
32724
32327
  ]
32725
32328
  };
32329
+ var WITHDRAW_AUTHORIZATION_TYPES = {
32330
+ WithdrawAuthorization: [
32331
+ { name: "account", type: "address" },
32332
+ { name: "asset", type: "address" },
32333
+ { name: "amount", type: "uint256" },
32334
+ { name: "withdrawNonce", type: "uint256" },
32335
+ { name: "deadline", type: "uint256" }
32336
+ ]
32337
+ };
32726
32338
  var ADD_DATA_TYPES = {
32727
32339
  AddData: [
32728
32340
  { name: "ownerAddress", type: "address" },
@@ -32741,6 +32353,14 @@ var RECORD_DATA_ACCESS_TYPES = {
32741
32353
  { name: "recordId", type: "bytes32" }
32742
32354
  ]
32743
32355
  };
32356
+ function buildWithdrawAuthorizationTypedData(config, message) {
32357
+ return {
32358
+ domain: withdrawAuthorizationDomain(config),
32359
+ types: WITHDRAW_AUTHORIZATION_TYPES,
32360
+ primaryType: "WithdrawAuthorization",
32361
+ message
32362
+ };
32363
+ }
32744
32364
 
32745
32365
  // src/protocol/identity.ts
32746
32366
  var secp256k14 = __toESM(require("@noble/secp256k1"), 1);
@@ -32760,17 +32380,21 @@ var PREIMAGE_SEPARATOR = ":";
32760
32380
  var UNCOMPRESSED_PUBLIC_KEY_BYTES = 65;
32761
32381
  var UNCOMPRESSED_PUBLIC_KEY_PREFIX = "04";
32762
32382
  var EMPTY_HEX = "0x";
32763
- function emptyAnchor() {
32764
- return Object.freeze({
32765
- kmsRootPubkey: EMPTY_HEX,
32766
- appIds: Object.freeze([])
32767
- });
32768
- }
32383
+ var MAINNET_ANCHOR = Object.freeze({
32384
+ kmsRootPubkey: "0x0434c76e0c3f52ec64cbf9bbf5c910c272330166fd656c0a86bb330963e46910e1a0e6fa51bec74be2f9129342707636060d85856d102cee8290185409ecf7422f",
32385
+ appIds: Object.freeze([
32386
+ "0x01bb1b6dcaf1ea170f1480c5e53b093f384d939a"
32387
+ ])
32388
+ });
32769
32389
  var ENCLAVE_TRUST_ANCHORS = Object.freeze({
32770
- // filled at fleet provisioning; verify fails closed while empty
32771
- [VANA_MAINNET_CHAIN_ID]: emptyAnchor(),
32772
- // filled at fleet provisioning; verify fails closed while empty
32773
- [MOKSHA_CHAIN_ID]: emptyAnchor()
32390
+ [VANA_MAINNET_CHAIN_ID]: MAINNET_ANCHOR,
32391
+ // Moksha workers share this dstack app and KMS root; the controller does not derive owner keys.
32392
+ [MOKSHA_CHAIN_ID]: Object.freeze({
32393
+ kmsRootPubkey: "0x0434c76e0c3f52ec64cbf9bbf5c910c272330166fd656c0a86bb330963e46910e1a0e6fa51bec74be2f9129342707636060d85856d102cee8290185409ecf7422f",
32394
+ appIds: Object.freeze([
32395
+ "0xec9a39de98c760e1ded9f1e97016dc5f0e357cf2"
32396
+ ])
32397
+ })
32774
32398
  });
32775
32399
  function userPsId(chainId, ownerAddress) {
32776
32400
  const packed = (0, import_viem14.encodePacked)(
@@ -32917,21 +32541,36 @@ var MAX_LEASE_SECONDS = 300;
32917
32541
  var MAX_ATTEMPTS = 3;
32918
32542
  var MAX_WAIT_SECONDS = 25;
32919
32543
  var CLAIM_POLL_FLOOR_MS = 1e3;
32920
- var MAX_INLINE_RESULT_BYTES = 1048576;
32921
32544
  var DEFAULT_JOB_DEADLINE_SECONDS = 600;
32922
32545
  var MAX_JOB_DEADLINE_SECONDS = 3600;
32923
32546
 
32924
32547
  // src/protocol/jobs-client.ts
32925
32548
  var import_node_crypto = require("node:crypto");
32549
+ var import_sha26 = require("@noble/hashes/sha2");
32926
32550
  var import_viem16 = require("viem");
32927
32551
  var import_accounts2 = require("viem/accounts");
32928
32552
 
32929
32553
  // src/crypto/envelope/job.ts
32930
32554
  var import_sha25 = require("@noble/hashes/sha2");
32931
32555
  var import_viem15 = require("viem");
32556
+ init_constants();
32932
32557
  init_interface();
32933
32558
  var textDecoder = new TextDecoder();
32934
32559
  var textEncoder = new TextEncoder();
32560
+ var MAX_JOB_RESULT_HEADER_BYTES = 4096;
32561
+ var WRAPPED_KEY_LENGTH_BYTES = 4;
32562
+ var FRAME_LENGTH_BYTES = 4;
32563
+ var FRAME_FLAGS_BYTES = 1;
32564
+ var AES_KEY_BYTES = 32;
32565
+ var AES_GCM_NONCE_BYTES = 12;
32566
+ var AES_GCM_TAG_BYTES = 16;
32567
+ var WRAPPED_METADATA_LENGTH_BYTES = 4;
32568
+ var WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES = AES_KEY_BYTES + AES_GCM_NONCE_BYTES + WRAPPED_METADATA_LENGTH_BYTES;
32569
+ var MAX_WRAPPED_KEY_BYTES = 8192;
32570
+ var FINAL_FRAME_FLAG = 1;
32571
+ var MAX_CHUNK_INDEX = 4294967295;
32572
+ var JOB_RESULT_FORMAT_VERSION = 2;
32573
+ var JOB_RESULT_CHUNK_BYTES = 1024 * 1024;
32935
32574
  var JobEnvelopeError = class extends Error {
32936
32575
  constructor(message) {
32937
32576
  super(message);
@@ -32963,21 +32602,68 @@ function requestPlaintext(envelope) {
32963
32602
  validateRequestEnvelope(envelope);
32964
32603
  return canonicalJsonBytes(envelope);
32965
32604
  }
32966
- function resultPlaintext(result) {
32967
- return textEncoder.encode(
32968
- JSON.stringify({
32969
- v: result.v,
32970
- jobId: result.jobId,
32971
- scope: result.scope,
32972
- version: result.version,
32973
- contentType: result.contentType,
32974
- body: result.body
32975
- })
32976
- );
32605
+ function resultMetadata(result) {
32606
+ return {
32607
+ v: result.v,
32608
+ jobId: result.jobId,
32609
+ scope: result.scope,
32610
+ version: result.version,
32611
+ contentType: result.contentType
32612
+ };
32977
32613
  }
32978
32614
  function encryptedBytesToBase64(encrypted) {
32979
32615
  return toBase64((0, import_viem15.fromHex)(`0x${serializeECIES(encrypted)}`, "bytes"));
32980
32616
  }
32617
+ function encryptedToBytes(encrypted) {
32618
+ const bytes = new Uint8Array(
32619
+ encrypted.iv.length + encrypted.ephemPublicKey.length + encrypted.ciphertext.length + encrypted.mac.length
32620
+ );
32621
+ let offset = 0;
32622
+ bytes.set(encrypted.iv, offset);
32623
+ offset += encrypted.iv.length;
32624
+ bytes.set(encrypted.ephemPublicKey, offset);
32625
+ offset += encrypted.ephemPublicKey.length;
32626
+ bytes.set(encrypted.ciphertext, offset);
32627
+ offset += encrypted.ciphertext.length;
32628
+ bytes.set(encrypted.mac, offset);
32629
+ return bytes;
32630
+ }
32631
+ function bytesToEncrypted(bytes) {
32632
+ const absoluteMinLength = FORMAT.IV_LENGTH + 1 + MAC.LENGTH + 1;
32633
+ if (bytes.length < absoluteMinLength) {
32634
+ throw new ECIESError(
32635
+ `Invalid ECIES data: too short (${bytes.length} bytes, minimum ${absoluteMinLength} bytes required)`,
32636
+ "DECRYPTION_FAILED"
32637
+ );
32638
+ }
32639
+ const prefix = bytes[FORMAT.EPHEMERAL_KEY_OFFSET];
32640
+ if (prefix !== CURVE.PREFIX.UNCOMPRESSED) {
32641
+ throw new ECIESError(
32642
+ `Invalid ephemeral public key: must be uncompressed format (0x04 prefix), got 0x${prefix.toString(16).padStart(2, "0")}`,
32643
+ "DECRYPTION_FAILED"
32644
+ );
32645
+ }
32646
+ const ephemKeySize = CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH;
32647
+ const minLength = FORMAT.IV_LENGTH + ephemKeySize + MAC.LENGTH + 1;
32648
+ if (bytes.length < minLength) {
32649
+ throw new ECIESError(
32650
+ `Invalid ECIES data: too short (${bytes.length} bytes, minimum ${minLength} bytes required)`,
32651
+ "DECRYPTION_FAILED"
32652
+ );
32653
+ }
32654
+ return {
32655
+ iv: bytes.subarray(FORMAT.IV_OFFSET, FORMAT.IV_OFFSET + FORMAT.IV_LENGTH),
32656
+ ephemPublicKey: bytes.subarray(
32657
+ FORMAT.EPHEMERAL_KEY_OFFSET,
32658
+ FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize
32659
+ ),
32660
+ ciphertext: bytes.subarray(
32661
+ FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize,
32662
+ bytes.length - MAC.LENGTH
32663
+ ),
32664
+ mac: bytes.subarray(bytes.length - MAC.LENGTH)
32665
+ };
32666
+ }
32981
32667
  function base64ToEncrypted(ciphertext) {
32982
32668
  return deserializeECIES((0, import_viem15.toHex)(fromBase64(ciphertext)));
32983
32669
  }
@@ -33078,11 +32764,11 @@ function validateRequestEnvelope(value) {
33078
32764
  requireString(value.auth, "auth", "job request envelope");
33079
32765
  return value;
33080
32766
  }
33081
- function validateResult(value) {
33082
- requirePlainObject(value, "result", "job result");
32767
+ function validateResultMetadata(value) {
32768
+ requirePlainObject(value, "metadata", "job result");
33083
32769
  requireExactKeys(
33084
32770
  value,
33085
- ["v", "jobId", "scope", "version", "contentType", "body"],
32771
+ ["v", "jobId", "scope", "version", "contentType"],
33086
32772
  "job result"
33087
32773
  );
33088
32774
  if (value.v !== JOB_PROTOCOL_VERSION) {
@@ -33093,14 +32779,222 @@ function validateResult(value) {
33093
32779
  for (const field of ["jobId", "scope", "contentType"]) {
33094
32780
  requireString(value[field], field, "job result");
33095
32781
  }
33096
- if (typeof value.body !== "string") {
33097
- throw new JobEnvelopeError("Invalid job result: missing body");
33098
- }
33099
32782
  if (value.version !== null && typeof value.version !== "string") {
33100
32783
  throw new JobEnvelopeError("Invalid job result: missing version");
33101
32784
  }
33102
32785
  return value;
33103
32786
  }
32787
+ function validateResult(value) {
32788
+ requirePlainObject(value, "result", "job result");
32789
+ requireExactKeys(
32790
+ value,
32791
+ ["v", "jobId", "scope", "version", "contentType", "body"],
32792
+ "job result"
32793
+ );
32794
+ validateResultMetadata(resultMetadata(value));
32795
+ if (!(value.body instanceof Uint8Array)) {
32796
+ throw new JobEnvelopeError("Invalid job result: missing body");
32797
+ }
32798
+ return value;
32799
+ }
32800
+ function webCrypto() {
32801
+ if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.getRandomValues !== "function" || !globalThis.crypto.subtle) {
32802
+ throw new JobEnvelopeError(
32803
+ "Job result streaming requires the Web Crypto API"
32804
+ );
32805
+ }
32806
+ return globalThis.crypto;
32807
+ }
32808
+ function uint32(value) {
32809
+ const bytes = new Uint8Array(4);
32810
+ new DataView(bytes.buffer).setUint32(0, value);
32811
+ return bytes;
32812
+ }
32813
+ function readUint32(bytes, offset = 0) {
32814
+ return new DataView(bytes.buffer, bytes.byteOffset + offset, 4).getUint32(0);
32815
+ }
32816
+ function wrappedKeyPlaintext(contentKey, noncePrefix, metadataBytes) {
32817
+ const plaintext = new Uint8Array(
32818
+ WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES + metadataBytes.length
32819
+ );
32820
+ plaintext.set(contentKey, 0);
32821
+ plaintext.set(noncePrefix, AES_KEY_BYTES);
32822
+ new DataView(plaintext.buffer).setUint32(
32823
+ AES_KEY_BYTES + AES_GCM_NONCE_BYTES,
32824
+ metadataBytes.length
32825
+ );
32826
+ plaintext.set(metadataBytes, WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES);
32827
+ return plaintext;
32828
+ }
32829
+ function parseWrappedKeyPlaintext(plaintext) {
32830
+ if (plaintext.length < WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES) {
32831
+ throw new JobEnvelopeError("Invalid job result: wrapped key is truncated");
32832
+ }
32833
+ const metadataLength = readUint32(
32834
+ plaintext,
32835
+ AES_KEY_BYTES + AES_GCM_NONCE_BYTES
32836
+ );
32837
+ if (metadataLength > MAX_JOB_RESULT_HEADER_BYTES) {
32838
+ throw new JobEnvelopeError(
32839
+ `Invalid job result: header exceeds ${MAX_JOB_RESULT_HEADER_BYTES} bytes`
32840
+ );
32841
+ }
32842
+ if (plaintext.length !== WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES + metadataLength) {
32843
+ throw new JobEnvelopeError(
32844
+ "Invalid job result: header length exceeds payload"
32845
+ );
32846
+ }
32847
+ const metadataBytes = plaintext.slice(WRAPPED_KEY_PLAINTEXT_PREFIX_BYTES);
32848
+ const metadata = validateResultMetadata(
32849
+ parseObject(metadataBytes, "job result header")
32850
+ );
32851
+ return {
32852
+ contentKey: plaintext.slice(0, AES_KEY_BYTES),
32853
+ noncePrefix: plaintext.slice(
32854
+ AES_KEY_BYTES,
32855
+ AES_KEY_BYTES + AES_GCM_NONCE_BYTES
32856
+ ),
32857
+ metadataBytes,
32858
+ metadata
32859
+ };
32860
+ }
32861
+ async function importAesKey(contentKey, usage) {
32862
+ return webCrypto().subtle.importKey(
32863
+ "raw",
32864
+ contentKey,
32865
+ { name: "AES-GCM" },
32866
+ false,
32867
+ [usage]
32868
+ );
32869
+ }
32870
+ function chunkNonce(noncePrefix, chunkIndex) {
32871
+ if (chunkIndex > MAX_CHUNK_INDEX) {
32872
+ throw new JobEnvelopeError("Invalid job result: too many chunks");
32873
+ }
32874
+ const nonce = noncePrefix.slice();
32875
+ const view = new DataView(nonce.buffer, nonce.byteOffset, nonce.byteLength);
32876
+ view.setUint32(8, view.getUint32(8) ^ chunkIndex);
32877
+ return nonce;
32878
+ }
32879
+ function chunkAad(metadataBytes, chunkIndex, final, plaintextLength) {
32880
+ const aad = new Uint8Array(14 + metadataBytes.length);
32881
+ aad[0] = JOB_RESULT_FORMAT_VERSION;
32882
+ aad.set(uint32(metadataBytes.length), 1);
32883
+ aad.set(metadataBytes, 5);
32884
+ aad.set(uint32(chunkIndex), 5 + metadataBytes.length);
32885
+ aad[9 + metadataBytes.length] = final ? FINAL_FRAME_FLAG : 0;
32886
+ aad.set(uint32(plaintextLength), 10 + metadataBytes.length);
32887
+ return aad;
32888
+ }
32889
+ async function encryptResultChunk(key, noncePrefix, metadataBytes, plaintext, chunkIndex, final) {
32890
+ const encrypted = new Uint8Array(
32891
+ await webCrypto().subtle.encrypt(
32892
+ {
32893
+ name: "AES-GCM",
32894
+ iv: chunkNonce(noncePrefix, chunkIndex),
32895
+ additionalData: chunkAad(
32896
+ metadataBytes,
32897
+ chunkIndex,
32898
+ final,
32899
+ plaintext.length
32900
+ ),
32901
+ tagLength: AES_GCM_TAG_BYTES * 8
32902
+ },
32903
+ key,
32904
+ plaintext
32905
+ )
32906
+ );
32907
+ const frame = new Uint8Array(
32908
+ FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES + encrypted.length
32909
+ );
32910
+ new DataView(frame.buffer).setUint32(0, encrypted.length);
32911
+ frame[FRAME_LENGTH_BYTES] = final ? FINAL_FRAME_FLAG : 0;
32912
+ frame.set(encrypted, FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES);
32913
+ return frame;
32914
+ }
32915
+ function verifyResultBindings(metadata, expect) {
32916
+ if (metadata.jobId !== expect.jobId) {
32917
+ throw new JobEnvelopeError(
32918
+ `Job result ID ${metadata.jobId} does not match expected job ID ${expect.jobId}`
32919
+ );
32920
+ }
32921
+ if (expect.scope !== void 0 && metadata.scope !== expect.scope) {
32922
+ throw new JobEnvelopeError(
32923
+ `Job result scope ${metadata.scope} does not match expected scope ${expect.scope}`
32924
+ );
32925
+ }
32926
+ if (expect.version !== void 0 && metadata.version !== expect.version) {
32927
+ throw new JobEnvelopeError(
32928
+ `Job result version ${String(metadata.version)} does not match expected version ${String(expect.version)}`
32929
+ );
32930
+ }
32931
+ }
32932
+ var ByteStreamReader = class {
32933
+ reader;
32934
+ current;
32935
+ offset = 0;
32936
+ ended = false;
32937
+ constructor(stream) {
32938
+ this.reader = stream.getReader();
32939
+ }
32940
+ async ensureBytes() {
32941
+ while (!this.current || this.offset === this.current.length) {
32942
+ if (this.ended) return false;
32943
+ const next = await this.reader.read();
32944
+ if (next.done) {
32945
+ this.ended = true;
32946
+ this.current = void 0;
32947
+ return false;
32948
+ }
32949
+ if (!(next.value instanceof Uint8Array)) {
32950
+ throw new JobEnvelopeError(
32951
+ "Invalid job result: stream yielded non-byte data"
32952
+ );
32953
+ }
32954
+ this.current = next.value;
32955
+ this.offset = 0;
32956
+ }
32957
+ return true;
32958
+ }
32959
+ async readExactOrNull(length) {
32960
+ if (!await this.ensureBytes()) return null;
32961
+ const bytes = new Uint8Array(length);
32962
+ let written = 0;
32963
+ while (written < length) {
32964
+ if (!await this.ensureBytes()) {
32965
+ throw new JobEnvelopeError("Invalid job result: truncated payload");
32966
+ }
32967
+ const available = this.current.length - this.offset;
32968
+ const count = Math.min(available, length - written);
32969
+ bytes.set(
32970
+ this.current.subarray(this.offset, this.offset + count),
32971
+ written
32972
+ );
32973
+ this.offset += count;
32974
+ written += count;
32975
+ }
32976
+ return bytes;
32977
+ }
32978
+ async readExact(length) {
32979
+ const bytes = await this.readExactOrNull(length);
32980
+ if (!bytes) {
32981
+ throw new JobEnvelopeError("Invalid job result: truncated payload");
32982
+ }
32983
+ return bytes;
32984
+ }
32985
+ async hasRemaining() {
32986
+ return this.ensureBytes();
32987
+ }
32988
+ async cancel(reason) {
32989
+ await this.reader.cancel(reason);
32990
+ }
32991
+ };
32992
+ function normalizeChunkError(error) {
32993
+ if (error instanceof JobEnvelopeError) return error;
32994
+ return new JobEnvelopeError(
32995
+ `Invalid job result: chunk authentication failed${error instanceof Error ? `: ${error.message}` : ""}`
32996
+ );
32997
+ }
33104
32998
  async function sealJobRequest(envelope, enclavePublicKey, ecies) {
33105
32999
  const encrypted = await ecies.encrypt(
33106
33000
  (0, import_viem15.fromHex)(enclavePublicKey, "bytes"),
@@ -33117,41 +33011,322 @@ async function openJobRequest(ciphertext, privateKey, ecies) {
33117
33011
  parseObject(plaintext, "job request envelope")
33118
33012
  );
33119
33013
  }
33120
- async function sealJobResult(result, builderPublicKey, ecies) {
33121
- validateResult(result);
33122
- const encrypted = await ecies.encrypt(
33014
+ async function sealJobResultStream(metadataValue, builderPublicKey, ecies) {
33015
+ const metadata = validateResultMetadata(metadataValue);
33016
+ const metadataBytes = canonicalJsonBytes(metadata);
33017
+ if (metadataBytes.length > MAX_JOB_RESULT_HEADER_BYTES) {
33018
+ throw new JobEnvelopeError(
33019
+ `Invalid job result: header exceeds ${MAX_JOB_RESULT_HEADER_BYTES} bytes`
33020
+ );
33021
+ }
33022
+ const crypto2 = webCrypto();
33023
+ const contentKey = crypto2.getRandomValues(new Uint8Array(AES_KEY_BYTES));
33024
+ const noncePrefix = crypto2.getRandomValues(
33025
+ new Uint8Array(AES_GCM_NONCE_BYTES)
33026
+ );
33027
+ const key = await importAesKey(contentKey, "encrypt");
33028
+ const keyPlaintext = wrappedKeyPlaintext(
33029
+ contentKey,
33030
+ noncePrefix,
33031
+ metadataBytes
33032
+ );
33033
+ const encryptedKey = await ecies.encrypt(
33123
33034
  (0, import_viem15.fromHex)(builderPublicKey, "bytes"),
33124
- resultPlaintext(result)
33035
+ keyPlaintext
33125
33036
  );
33126
- const ciphertext = encryptedBytesToBase64(encrypted);
33127
- const bytes = fromBase64(ciphertext);
33128
- return { ciphertext, hash: (0, import_viem15.bytesToHex)((0, import_sha25.sha256)(bytes)), size: bytes.length };
33037
+ contentKey.fill(0);
33038
+ keyPlaintext.fill(0);
33039
+ const wrappedKey = encryptedToBytes(encryptedKey);
33040
+ if (wrappedKey.length > MAX_WRAPPED_KEY_BYTES) {
33041
+ throw new JobEnvelopeError("Invalid job result: wrapped key is too large");
33042
+ }
33043
+ const header = new Uint8Array(
33044
+ 1 + WRAPPED_KEY_LENGTH_BYTES + wrappedKey.length
33045
+ );
33046
+ header[0] = JOB_RESULT_FORMAT_VERSION;
33047
+ new DataView(header.buffer).setUint32(1, wrappedKey.length);
33048
+ header.set(wrappedKey, 1 + WRAPPED_KEY_LENGTH_BYTES);
33049
+ let pending = new Uint8Array(JOB_RESULT_CHUNK_BYTES);
33050
+ let pendingLength = 0;
33051
+ let chunkIndex = 0;
33052
+ const transform = new TransformStream({
33053
+ async transform(chunk, controller) {
33054
+ if (!(chunk instanceof Uint8Array)) {
33055
+ throw new JobEnvelopeError(
33056
+ "Invalid job result: stream yielded non-byte data"
33057
+ );
33058
+ }
33059
+ let offset = 0;
33060
+ while (offset < chunk.length) {
33061
+ if (pendingLength === JOB_RESULT_CHUNK_BYTES) {
33062
+ controller.enqueue(
33063
+ await encryptResultChunk(
33064
+ key,
33065
+ noncePrefix,
33066
+ metadataBytes,
33067
+ pending,
33068
+ chunkIndex,
33069
+ false
33070
+ )
33071
+ );
33072
+ chunkIndex += 1;
33073
+ pending = new Uint8Array(JOB_RESULT_CHUNK_BYTES);
33074
+ pendingLength = 0;
33075
+ }
33076
+ const count = Math.min(
33077
+ chunk.length - offset,
33078
+ JOB_RESULT_CHUNK_BYTES - pendingLength
33079
+ );
33080
+ pending.set(chunk.subarray(offset, offset + count), pendingLength);
33081
+ pendingLength += count;
33082
+ offset += count;
33083
+ }
33084
+ },
33085
+ async flush(controller) {
33086
+ controller.enqueue(
33087
+ await encryptResultChunk(
33088
+ key,
33089
+ noncePrefix,
33090
+ metadataBytes,
33091
+ pending.subarray(0, pendingLength),
33092
+ chunkIndex,
33093
+ true
33094
+ )
33095
+ );
33096
+ }
33097
+ });
33098
+ return { header, transform };
33129
33099
  }
33130
- async function openJobResult(ciphertext, builderPrivateKey, ecies, expect) {
33131
- const plaintext = await ecies.decrypt(
33132
- (0, import_viem15.fromHex)(builderPrivateKey, "bytes"),
33133
- base64ToEncrypted(ciphertext)
33100
+ async function sealJobResult(result, builderPublicKey, ecies) {
33101
+ validateResult(result);
33102
+ const sealed = await sealJobResultStream(
33103
+ resultMetadata(result),
33104
+ builderPublicKey,
33105
+ ecies
33134
33106
  );
33135
- const result = validateResult(parseObject(plaintext, "job result"));
33136
- if (result.jobId !== expect.jobId) {
33107
+ const frameCount = Math.max(
33108
+ 1,
33109
+ Math.ceil(result.body.length / JOB_RESULT_CHUNK_BYTES)
33110
+ );
33111
+ const size = sealed.header.length + result.body.length + frameCount * (FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES + AES_GCM_TAG_BYTES);
33112
+ const bytes = new Uint8Array(size);
33113
+ bytes.set(sealed.header, 0);
33114
+ let outputOffset = sealed.header.length;
33115
+ const reader = sealed.transform.readable.getReader();
33116
+ const drain = (async () => {
33117
+ for (; ; ) {
33118
+ const next = await reader.read();
33119
+ if (next.done) break;
33120
+ bytes.set(next.value, outputOffset);
33121
+ outputOffset += next.value.length;
33122
+ }
33123
+ })();
33124
+ const writer = sealed.transform.writable.getWriter();
33125
+ const fill = (async () => {
33126
+ for (let offset = 0; offset < result.body.length; offset += JOB_RESULT_CHUNK_BYTES) {
33127
+ await writer.write(
33128
+ result.body.subarray(offset, offset + JOB_RESULT_CHUNK_BYTES)
33129
+ );
33130
+ }
33131
+ await writer.close();
33132
+ })();
33133
+ await Promise.all([drain, fill]);
33134
+ if (outputOffset !== bytes.length) {
33135
+ throw new JobEnvelopeError("Invalid job result: sealed size mismatch");
33136
+ }
33137
+ return { bytes, hash: (0, import_viem15.bytesToHex)((0, import_sha25.sha256)(bytes)), size };
33138
+ }
33139
+ async function openJobResultStream(bytesStream, builderPrivateKey, ecies, expect) {
33140
+ const reader = new ByteStreamReader(bytesStream);
33141
+ const headerPrefix = await reader.readExact(1 + WRAPPED_KEY_LENGTH_BYTES);
33142
+ const formatVersion = headerPrefix[0];
33143
+ if (formatVersion !== JOB_RESULT_FORMAT_VERSION) {
33137
33144
  throw new JobEnvelopeError(
33138
- `Job result ID ${result.jobId} does not match expected job ID ${expect.jobId}`
33145
+ `Unsupported job result format: ${String(formatVersion)}`
33139
33146
  );
33140
33147
  }
33141
- if (expect.scope !== void 0 && result.scope !== expect.scope) {
33148
+ const wrappedKeyLength = readUint32(headerPrefix, 1);
33149
+ if (wrappedKeyLength === 0 || wrappedKeyLength > MAX_WRAPPED_KEY_BYTES) {
33142
33150
  throw new JobEnvelopeError(
33143
- `Job result scope ${result.scope} does not match expected scope ${expect.scope}`
33151
+ "Invalid job result: invalid wrapped key length"
33144
33152
  );
33145
33153
  }
33146
- if (expect.version !== void 0 && result.version !== expect.version) {
33154
+ const wrappedKey = await reader.readExact(wrappedKeyLength);
33155
+ const keyPlaintext = await ecies.decrypt(
33156
+ (0, import_viem15.fromHex)(builderPrivateKey, "bytes"),
33157
+ bytesToEncrypted(wrappedKey)
33158
+ );
33159
+ const parsed = parseWrappedKeyPlaintext(keyPlaintext);
33160
+ verifyResultBindings(parsed.metadata, expect);
33161
+ const key = await importAesKey(parsed.contentKey, "decrypt");
33162
+ parsed.contentKey.fill(0);
33163
+ keyPlaintext.fill(0);
33164
+ let chunkIndex = 0;
33165
+ let finished = false;
33166
+ const body = new ReadableStream({
33167
+ async pull(controller) {
33168
+ if (finished) {
33169
+ controller.close();
33170
+ return;
33171
+ }
33172
+ try {
33173
+ const frameHeader = await reader.readExactOrNull(
33174
+ FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES
33175
+ );
33176
+ if (!frameHeader) {
33177
+ throw new JobEnvelopeError("Invalid job result: missing final chunk");
33178
+ }
33179
+ const encryptedLength = readUint32(frameHeader);
33180
+ if (encryptedLength < AES_GCM_TAG_BYTES || encryptedLength > JOB_RESULT_CHUNK_BYTES + AES_GCM_TAG_BYTES) {
33181
+ throw new JobEnvelopeError(
33182
+ "Invalid job result: invalid chunk length"
33183
+ );
33184
+ }
33185
+ const flags = frameHeader[FRAME_LENGTH_BYTES];
33186
+ if (flags !== 0 && flags !== FINAL_FRAME_FLAG) {
33187
+ throw new JobEnvelopeError("Invalid job result: invalid chunk flags");
33188
+ }
33189
+ const final = flags === FINAL_FRAME_FLAG;
33190
+ const plaintextLength = encryptedLength - AES_GCM_TAG_BYTES;
33191
+ if (!final && plaintextLength !== JOB_RESULT_CHUNK_BYTES) {
33192
+ throw new JobEnvelopeError(
33193
+ "Invalid job result: short non-final chunk"
33194
+ );
33195
+ }
33196
+ const encrypted = await reader.readExact(encryptedLength);
33197
+ const plaintext = new Uint8Array(
33198
+ await webCrypto().subtle.decrypt(
33199
+ {
33200
+ name: "AES-GCM",
33201
+ iv: chunkNonce(parsed.noncePrefix, chunkIndex),
33202
+ additionalData: chunkAad(
33203
+ parsed.metadataBytes,
33204
+ chunkIndex,
33205
+ final,
33206
+ plaintextLength
33207
+ ),
33208
+ tagLength: AES_GCM_TAG_BYTES * 8
33209
+ },
33210
+ key,
33211
+ encrypted
33212
+ )
33213
+ );
33214
+ if (plaintext.length !== plaintextLength) {
33215
+ throw new JobEnvelopeError(
33216
+ "Invalid job result: decrypted chunk length mismatch"
33217
+ );
33218
+ }
33219
+ chunkIndex += 1;
33220
+ if (final) {
33221
+ if (await reader.hasRemaining()) {
33222
+ throw new JobEnvelopeError(
33223
+ "Invalid job result: bytes follow final chunk"
33224
+ );
33225
+ }
33226
+ finished = true;
33227
+ }
33228
+ controller.enqueue(plaintext);
33229
+ if (finished) controller.close();
33230
+ } catch (error) {
33231
+ controller.error(normalizeChunkError(error));
33232
+ void reader.cancel(error).catch(() => void 0);
33233
+ }
33234
+ },
33235
+ cancel(reason) {
33236
+ return reader.cancel(reason);
33237
+ }
33238
+ });
33239
+ return { metadata: parsed.metadata, body };
33240
+ }
33241
+ function bufferedResultBodySize(sealedBytes) {
33242
+ if (sealedBytes.length < 1 + WRAPPED_KEY_LENGTH_BYTES) {
33243
+ throw new JobEnvelopeError("Invalid job result: truncated payload");
33244
+ }
33245
+ if (sealedBytes[0] !== JOB_RESULT_FORMAT_VERSION) {
33147
33246
  throw new JobEnvelopeError(
33148
- `Job result version ${String(result.version)} does not match expected version ${String(expect.version)}`
33247
+ `Unsupported job result format: ${String(sealedBytes[0])}`
33149
33248
  );
33150
33249
  }
33151
- return result;
33250
+ const wrappedKeyLength = readUint32(sealedBytes, 1);
33251
+ if (wrappedKeyLength === 0 || wrappedKeyLength > MAX_WRAPPED_KEY_BYTES) {
33252
+ throw new JobEnvelopeError(
33253
+ "Invalid job result: invalid wrapped key length"
33254
+ );
33255
+ }
33256
+ let offset = 1 + WRAPPED_KEY_LENGTH_BYTES + wrappedKeyLength;
33257
+ if (offset > sealedBytes.length) {
33258
+ throw new JobEnvelopeError("Invalid job result: truncated payload");
33259
+ }
33260
+ let bodySize = 0;
33261
+ let sawFinal = false;
33262
+ while (offset < sealedBytes.length) {
33263
+ if (sealedBytes.length - offset < FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES) {
33264
+ throw new JobEnvelopeError("Invalid job result: truncated payload");
33265
+ }
33266
+ const encryptedLength = readUint32(sealedBytes, offset);
33267
+ const flags = sealedBytes[offset + FRAME_LENGTH_BYTES];
33268
+ if (encryptedLength < AES_GCM_TAG_BYTES || encryptedLength > JOB_RESULT_CHUNK_BYTES + AES_GCM_TAG_BYTES || flags !== 0 && flags !== FINAL_FRAME_FLAG) {
33269
+ throw new JobEnvelopeError("Invalid job result: invalid chunk framing");
33270
+ }
33271
+ const plaintextLength = encryptedLength - AES_GCM_TAG_BYTES;
33272
+ if (flags === 0 && plaintextLength !== JOB_RESULT_CHUNK_BYTES) {
33273
+ throw new JobEnvelopeError("Invalid job result: short non-final chunk");
33274
+ }
33275
+ offset += FRAME_LENGTH_BYTES + FRAME_FLAGS_BYTES;
33276
+ if (encryptedLength > sealedBytes.length - offset) {
33277
+ throw new JobEnvelopeError("Invalid job result: truncated payload");
33278
+ }
33279
+ offset += encryptedLength;
33280
+ bodySize += plaintextLength;
33281
+ if (flags === FINAL_FRAME_FLAG) {
33282
+ sawFinal = true;
33283
+ if (offset !== sealedBytes.length) {
33284
+ throw new JobEnvelopeError(
33285
+ "Invalid job result: bytes follow final chunk"
33286
+ );
33287
+ }
33288
+ }
33289
+ }
33290
+ if (!sawFinal) {
33291
+ throw new JobEnvelopeError("Invalid job result: missing final chunk");
33292
+ }
33293
+ return bodySize;
33152
33294
  }
33295
+ async function openJobResult(sealedBytes, builderPrivateKey, ecies, expect) {
33296
+ const bodySize = bufferedResultBodySize(sealedBytes);
33297
+ const stream = new ReadableStream({
33298
+ start(controller) {
33299
+ controller.enqueue(sealedBytes);
33300
+ controller.close();
33301
+ }
33302
+ });
33303
+ const opened = await openJobResultStream(
33304
+ stream,
33305
+ builderPrivateKey,
33306
+ ecies,
33307
+ expect
33308
+ );
33309
+ const body = new Uint8Array(bodySize);
33310
+ let offset = 0;
33311
+ await opened.body.pipeTo(
33312
+ new WritableStream({
33313
+ write(chunk) {
33314
+ body.set(chunk, offset);
33315
+ offset += chunk.length;
33316
+ }
33317
+ })
33318
+ );
33319
+ if (offset !== body.length) {
33320
+ throw new JobEnvelopeError("Invalid job result: opened size mismatch");
33321
+ }
33322
+ return { ...opened.metadata, body };
33323
+ }
33324
+
33325
+ // src/protocol/jobs-client.ts
33326
+ var import_errors3 = require("./errors.cjs");
33153
33327
 
33154
33328
  // src/protocol/write-signer.ts
33329
+ var import_errors2 = require("./errors.cjs");
33155
33330
  function isRecord(value) {
33156
33331
  return value !== null && typeof value === "object";
33157
33332
  }
@@ -33168,7 +33343,7 @@ function resolveWriteSigner(source, options = {}) {
33168
33343
  if (isViemWriteWalletClient(source)) {
33169
33344
  const account = options.account ?? source.account;
33170
33345
  if (account === void 0) {
33171
- throw new WriteRequestError(
33346
+ throw new import_errors2.WriteRequestError(
33172
33347
  "Viem wallet client requires an account option or account property"
33173
33348
  );
33174
33349
  }
@@ -33184,7 +33359,7 @@ function resolveWriteSigner(source, options = {}) {
33184
33359
  };
33185
33360
  }
33186
33361
  if (!isRecord(source) || typeof source.signMessage !== "function") {
33187
- throw new WriteRequestError(
33362
+ throw new import_errors2.WriteRequestError(
33188
33363
  "signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
33189
33364
  );
33190
33365
  }
@@ -33225,7 +33400,7 @@ function normalizeGateway(gatewayUrl) {
33225
33400
  try {
33226
33401
  const url = new URL(gatewayUrl);
33227
33402
  if (url.pathname !== "/" || url.search !== "" || url.hash !== "") {
33228
- throw new JobRejectedError(
33403
+ throw new import_errors3.JobRejectedError(
33229
33404
  "gatewayUrl must be an origin without a path, query, or fragment"
33230
33405
  );
33231
33406
  }
@@ -33234,8 +33409,8 @@ function normalizeGateway(gatewayUrl) {
33234
33409
  audience: url.origin
33235
33410
  };
33236
33411
  } catch (error) {
33237
- if (error instanceof JobRejectedError) throw error;
33238
- throw new JobRejectedError(
33412
+ if (error instanceof import_errors3.JobRejectedError) throw error;
33413
+ throw new import_errors3.JobRejectedError(
33239
33414
  "gatewayUrl must be an absolute URL",
33240
33415
  void 0,
33241
33416
  null,
@@ -33248,7 +33423,7 @@ function normalizeGateway(gatewayUrl) {
33248
33423
  function resolveFetch(fetchFn) {
33249
33424
  const resolved = fetchFn ?? globalThis.fetch;
33250
33425
  if (resolved === void 0) {
33251
- throw new JobRejectedError("No fetch implementation available");
33426
+ throw new import_errors3.JobRejectedError("No fetch implementation available");
33252
33427
  }
33253
33428
  return resolved;
33254
33429
  }
@@ -33260,7 +33435,7 @@ function sourcePublicKey(source) {
33260
33435
  }
33261
33436
  function resolveBuilder(options) {
33262
33437
  if (options.builderPrivateKey && options.builderAccount) {
33263
- throw new JobRejectedError(
33438
+ throw new import_errors3.JobRejectedError(
33264
33439
  "Provide builderPrivateKey or builderAccount, not both"
33265
33440
  );
33266
33441
  }
@@ -33268,12 +33443,12 @@ function resolveBuilder(options) {
33268
33443
  try {
33269
33444
  source = options.builderPrivateKey ? (0, import_accounts2.privateKeyToAccount)(options.builderPrivateKey) : options.builderAccount;
33270
33445
  } catch (error) {
33271
- throw new JobRejectedError("Invalid builder private key", void 0, null, {
33446
+ throw new import_errors3.JobRejectedError("Invalid builder private key", void 0, null, {
33272
33447
  cause: error instanceof Error ? error.message : String(error)
33273
33448
  });
33274
33449
  }
33275
33450
  if (!source) {
33276
- throw new JobRejectedError(
33451
+ throw new import_errors3.JobRejectedError(
33277
33452
  "builderPrivateKey or builderAccount is required"
33278
33453
  );
33279
33454
  }
@@ -33281,13 +33456,13 @@ function resolveBuilder(options) {
33281
33456
  try {
33282
33457
  signer = resolveWriteSigner(source);
33283
33458
  } catch (error) {
33284
- throw new JobRejectedError("Invalid builder signer", void 0, null, {
33459
+ throw new import_errors3.JobRejectedError("Invalid builder signer", void 0, null, {
33285
33460
  cause: error instanceof Error ? error.message : String(error)
33286
33461
  });
33287
33462
  }
33288
33463
  const publicKey = sourcePublicKey(source);
33289
33464
  if (!signer.address || !publicKey) {
33290
- throw new JobRejectedError(
33465
+ throw new import_errors3.JobRejectedError(
33291
33466
  "Builder signer must expose both address and publicKey"
33292
33467
  );
33293
33468
  }
@@ -33303,7 +33478,7 @@ function resolveBuilder(options) {
33303
33478
  function clampInteger(value, fallback, minimum, maximum, field) {
33304
33479
  const resolved = value ?? fallback;
33305
33480
  if (!Number.isFinite(resolved)) {
33306
- throw new JobRejectedError(`${field} must be a finite number`);
33481
+ throw new import_errors3.JobRejectedError(`${field} must be a finite number`);
33307
33482
  }
33308
33483
  return Math.min(maximum, Math.max(minimum, Math.trunc(resolved)));
33309
33484
  }
@@ -33333,29 +33508,29 @@ async function rejectedResponse(response, fallback) {
33333
33508
  const message = response.status === HTTP_UNAUTHORIZED && parsed.reason ? `${parsed.message}: ${parsed.reason}` : parsed.message;
33334
33509
  if (response.status === HTTP_FORBIDDEN) {
33335
33510
  if (parsed.code === "BUILDER_UNKNOWN") {
33336
- return new BuilderUnknownError(parsed.message, details);
33511
+ return new import_errors3.BuilderUnknownError(parsed.message, details);
33337
33512
  }
33338
33513
  if (parsed.code === "GRANT_INVALID") {
33339
- return new GrantInvalidError(parsed.message, details);
33514
+ return new import_errors3.GrantInvalidError(parsed.message, details);
33340
33515
  }
33341
33516
  if (parsed.code === "OWNER_NOT_READY") {
33342
- return new OwnerNotReadyError(parsed.message, details);
33517
+ return new import_errors3.OwnerNotReadyError(parsed.message, details);
33343
33518
  }
33344
33519
  }
33345
33520
  if (response.status === HTTP_NOT_FOUND) {
33346
- return new JobNotFoundError(parsed.message, details);
33521
+ return new import_errors3.JobNotFoundError(parsed.message, details);
33347
33522
  }
33348
33523
  if (response.status === HTTP_CONFLICT && parsed.code === "JOB_ID_TAKEN") {
33349
- return new JobIdTakenError(parsed.message, details);
33524
+ return new import_errors3.JobIdTakenError(parsed.message, details);
33350
33525
  }
33351
33526
  if (response.status === HTTP_PAYLOAD_TOO_LARGE) {
33352
- return new JobRequestTooLargeError(parsed.message, parsed.code, details);
33527
+ return new import_errors3.JobRequestTooLargeError(parsed.message, parsed.code, details);
33353
33528
  }
33354
- return new JobRejectedError(message, response.status, parsed.code, details);
33529
+ return new import_errors3.JobRejectedError(message, response.status, parsed.code, details);
33355
33530
  }
33356
33531
  function requireStatus(value, status) {
33357
- if (!isRecord2(value) || !isNonEmptyString(value["jobId"]) || typeof value["state"] !== "string" || !JOB_STATES.includes(value["state"]) || !isNonEmptyString(value["owner"]) || !isNonEmptyString(value["grantId"]) || !isNonEmptyString(value["scope"]) || !isNonEmptyString(value["operation"]) || !JOB_OPERATIONS.includes(value["operation"])) {
33358
- throw new JobRejectedError(
33532
+ if (!isRecord2(value) || !isNonEmptyString(value["jobId"]) || typeof value["state"] !== "string" || !JOB_STATES.includes(value["state"]) || !isNonEmptyString(value["owner"]) || !isNonEmptyString(value["grantId"]) || !isNonEmptyString(value["scope"]) || !isNonEmptyString(value["operation"]) || !JOB_OPERATIONS.includes(value["operation"]) || value["state"] === "completed" && !isResultHandle(value["result"])) {
33533
+ throw new import_errors3.JobRejectedError(
33359
33534
  "Gateway response did not contain a job status",
33360
33535
  status
33361
33536
  );
@@ -33365,6 +33540,17 @@ function requireStatus(value, status) {
33365
33540
  function isNonEmptyString(value) {
33366
33541
  return typeof value === "string" && value.length > 0;
33367
33542
  }
33543
+ function isResultHandle(value) {
33544
+ if (!isRecord2(value) || !isNonEmptyString(value["objectKey"]) || !isNonEmptyString(value["url"]) || typeof value["size"] !== "number" || !Number.isInteger(value["size"]) || value["size"] < 0 || typeof value["hash"] !== "string" || !/^0x[0-9a-fA-F]{64}$/.test(value["hash"]) || typeof value["expiresAt"] !== "string" || Number.isNaN(Date.parse(value["expiresAt"]))) {
33545
+ return false;
33546
+ }
33547
+ try {
33548
+ const url = new URL(value["url"]);
33549
+ return url.protocol === "https:" || url.protocol === "http:";
33550
+ } catch {
33551
+ return false;
33552
+ }
33553
+ }
33368
33554
  function hasMatchingIdentityKey(value) {
33369
33555
  const address = value["address"];
33370
33556
  const publicKey = value["publicKey"];
@@ -33391,7 +33577,7 @@ function sleep2(ms) {
33391
33577
  }
33392
33578
  function requireFiniteDuration(value, field) {
33393
33579
  if (!Number.isFinite(value)) {
33394
- throw new JobRejectedError(`${field} must be a finite number`);
33580
+ throw new import_errors3.JobRejectedError(`${field} must be a finite number`);
33395
33581
  }
33396
33582
  return Math.max(0, value);
33397
33583
  }
@@ -33405,7 +33591,7 @@ function createJobsClient(options) {
33405
33591
  try {
33406
33592
  return await fetchFn(url, init);
33407
33593
  } catch (error) {
33408
- throw new JobTransportError(
33594
+ throw new import_errors3.JobTransportError(
33409
33595
  `${description} failed: ${error instanceof Error ? error.message : String(error)}`,
33410
33596
  error
33411
33597
  );
@@ -33426,19 +33612,19 @@ function createJobsClient(options) {
33426
33612
  await responseBody(response),
33427
33613
  "Owner identity not found"
33428
33614
  );
33429
- throw new OwnerNotReadyError(parsed.message, parsed.details);
33615
+ throw new import_errors3.OwnerNotReadyError(parsed.message, parsed.details);
33430
33616
  }
33431
33617
  if (!response.ok) {
33432
33618
  throw await rejectedResponse(response, "Owner identity lookup rejected");
33433
33619
  }
33434
33620
  const body = await responseBody(response);
33435
33621
  if (!isRecord2(body) || body["state"] !== SEALED_IDENTITY_STATE || !isRecord2(body["identity"])) {
33436
- throw new OwnerNotReadyError("Owner identity is not sealed", {
33622
+ throw new import_errors3.OwnerNotReadyError("Owner identity is not sealed", {
33437
33623
  state: isRecord2(body) ? body["state"] : void 0
33438
33624
  });
33439
33625
  }
33440
33626
  if (!hasExpectedIdentity(body["identity"], owner, options.chainId)) {
33441
- throw new JobRejectedError(
33627
+ throw new import_errors3.JobRejectedError(
33442
33628
  "Gateway returned a malformed or mismatched owner identity",
33443
33629
  response.status
33444
33630
  );
@@ -33459,7 +33645,7 @@ function createJobsClient(options) {
33459
33645
  const jobId = (0, import_node_crypto.randomUUID)();
33460
33646
  const nowMs = now().getTime();
33461
33647
  if (!Number.isFinite(nowMs)) {
33462
- throw new JobRejectedError("now must return a valid Date");
33648
+ throw new import_errors3.JobRejectedError("now must return a valid Date");
33463
33649
  }
33464
33650
  const deadline = new Date(
33465
33651
  nowMs + deadlineSeconds * MILLISECONDS_PER_SECOND
@@ -33527,7 +33713,7 @@ function createJobsClient(options) {
33527
33713
  if (response.status === HTTP_OK && isRecord2(body)) {
33528
33714
  const job = requireStatus(body["job"], response.status);
33529
33715
  if (job.jobId !== jobId) {
33530
- throw new JobRejectedError(
33716
+ throw new import_errors3.JobRejectedError(
33531
33717
  "Gateway returned a job id that does not match the submission",
33532
33718
  response.status
33533
33719
  );
@@ -33537,7 +33723,7 @@ function createJobsClient(options) {
33537
33723
  if (response.status === HTTP_ACCEPTED && isRecord2(body) && body["jobId"] === jobId && typeof body["state"] === "string" && JOB_STATES.includes(body["state"])) {
33538
33724
  return { jobId, state: body["state"] };
33539
33725
  }
33540
- throw new JobRejectedError(
33726
+ throw new import_errors3.JobRejectedError(
33541
33727
  "Gateway returned an undocumented job submission response",
33542
33728
  response.status
33543
33729
  );
@@ -33585,7 +33771,7 @@ function createJobsClient(options) {
33585
33771
  let latest;
33586
33772
  for (; ; ) {
33587
33773
  if (Date.now() >= callerDeadline) {
33588
- throw new JobTimeoutError(
33774
+ throw new import_errors3.JobTimeoutError(
33589
33775
  `Timed out waiting for terminal job ${jobId}`,
33590
33776
  {
33591
33777
  jobId,
@@ -33598,7 +33784,7 @@ function createJobsClient(options) {
33598
33784
  if (TERMINAL_JOB_STATES.has(latest.state)) return latest;
33599
33785
  const remaining = callerDeadline - Date.now();
33600
33786
  if (remaining <= 0) {
33601
- throw new JobTimeoutError(
33787
+ throw new import_errors3.JobTimeoutError(
33602
33788
  `Timed out waiting for terminal job ${jobId}`,
33603
33789
  {
33604
33790
  jobId,
@@ -33610,31 +33796,51 @@ function createJobsClient(options) {
33610
33796
  await sleep2(Math.min(pollMs, remaining));
33611
33797
  }
33612
33798
  },
33613
- async openResult(job, openOptions) {
33614
- if (!job.resultCiphertext) {
33615
- throw new JobRejectedError(
33616
- "Job status does not include inline resultCiphertext",
33617
- void 0,
33618
- null,
33799
+ async openResult(handle, openOptions) {
33800
+ if (!privateKey) {
33801
+ throw new import_errors3.JobRejectedError(
33802
+ "openResult requires createJobsClient({ builderPrivateKey })"
33803
+ );
33804
+ }
33805
+ const response = await request(
33806
+ handle.url,
33807
+ { method: GET_METHOD },
33808
+ "Job result fetch"
33809
+ );
33810
+ if (!response.ok) {
33811
+ throw await rejectedResponse(response, "Job result fetch rejected");
33812
+ }
33813
+ let bytes;
33814
+ try {
33815
+ bytes = new Uint8Array(await response.arrayBuffer());
33816
+ } catch (error) {
33817
+ throw new import_errors3.JobTransportError(
33818
+ `Job result fetch failed: ${error instanceof Error ? error.message : String(error)}`,
33819
+ error
33820
+ );
33821
+ }
33822
+ const actualHash = (0, import_viem16.bytesToHex)((0, import_sha26.sha256)(bytes));
33823
+ if (actualHash.toLowerCase() !== handle.hash.toLowerCase()) {
33824
+ throw new import_errors3.JobResultIntegrityError(
33825
+ "Fetched job result hash does not match its handle",
33619
33826
  {
33620
- jobId: job.jobId,
33621
- state: job.state,
33622
- resultHandle: job.resultHandle,
33623
- maxInlineResultBytes: MAX_INLINE_RESULT_BYTES
33827
+ objectKey: handle.objectKey,
33828
+ expectedHash: handle.hash,
33829
+ actualHash
33624
33830
  }
33625
33831
  );
33626
33832
  }
33627
- if (!privateKey) {
33628
- throw new JobRejectedError(
33629
- "openResult requires createJobsClient({ builderPrivateKey })"
33833
+ if (bytes.length !== handle.size) {
33834
+ throw new import_errors3.JobResultIntegrityError(
33835
+ "Fetched job result size does not match its handle",
33836
+ {
33837
+ objectKey: handle.objectKey,
33838
+ expectedSize: handle.size,
33839
+ actualSize: bytes.length
33840
+ }
33630
33841
  );
33631
33842
  }
33632
- return openJobResult(
33633
- job.resultCiphertext,
33634
- privateKey,
33635
- ecies,
33636
- openOptions.expect
33637
- );
33843
+ return openJobResult(bytes, privateKey, ecies, openOptions.expect);
33638
33844
  },
33639
33845
  async readRaw(params) {
33640
33846
  const submitted = await client.submitRawRead(params);
@@ -33642,7 +33848,27 @@ function createJobsClient(options) {
33642
33848
  timeoutMs: params.timeoutMs,
33643
33849
  pollMs: params.pollMs
33644
33850
  });
33645
- return client.openResult(job, {
33851
+ if (job.state !== "completed") {
33852
+ throw new import_errors3.JobRejectedError(
33853
+ `Job ${job.jobId} ended in state ${job.state}${job.failureReason ? `: ${job.failureReason}` : ""}`,
33854
+ void 0,
33855
+ null,
33856
+ {
33857
+ jobId: job.jobId,
33858
+ state: job.state,
33859
+ ...job.failureReason ? { failureReason: job.failureReason } : {}
33860
+ }
33861
+ );
33862
+ }
33863
+ if (!job.result) {
33864
+ throw new import_errors3.JobRejectedError(
33865
+ "Completed job status does not include a result handle",
33866
+ void 0,
33867
+ null,
33868
+ { jobId: job.jobId, state: job.state }
33869
+ );
33870
+ }
33871
+ return client.openResult(job.result, {
33646
33872
  expect: {
33647
33873
  jobId: submitted.jobId,
33648
33874
  scope: params.scope,
@@ -34348,10 +34574,12 @@ function buildMarkDataPointUnavailableRequest(config, input) {
34348
34574
 
34349
34575
  // src/protocol/data-point-deletion.ts
34350
34576
  var import_viem25 = require("viem");
34577
+ var import_errors5 = require("./errors.cjs");
34351
34578
 
34352
34579
  // src/protocol/lineage.ts
34353
34580
  var import_viem24 = require("viem");
34354
34581
  var import_zod = require("zod");
34582
+ var import_errors4 = require("./errors.cjs");
34355
34583
 
34356
34584
  // src/protocol/personal-server-error-body.ts
34357
34585
  function isRecord4(value) {
@@ -34423,7 +34651,7 @@ function derivedScopeViolatesNaming(derivedScope, sourceScope) {
34423
34651
  function assertDerivedScopeNaming(derivedScope, sourceScopes) {
34424
34652
  for (const sourceScope of sourceScopes) {
34425
34653
  if (derivedScopeViolatesNaming(derivedScope, sourceScope)) {
34426
- throw new WriteRequestError(
34654
+ throw new import_errors4.WriteRequestError(
34427
34655
  `Derived scope ${derivedScope} must not share its first segment with source scope ${sourceScope}; put derivatives in the app's own namespace`,
34428
34656
  { scope: derivedScope, sourceScope }
34429
34657
  );
@@ -34486,7 +34714,7 @@ function normalizeBaseUrl(url) {
34486
34714
  function resolveFetch2(fetchFn) {
34487
34715
  const resolved = fetchFn ?? globalThis.fetch;
34488
34716
  if (resolved === void 0) {
34489
- throw new LineageReadError("No fetch implementation available");
34717
+ throw new import_errors4.LineageReadError("No fetch implementation available");
34490
34718
  }
34491
34719
  return resolved;
34492
34720
  }
@@ -34494,7 +34722,7 @@ function normalizeVersion(version) {
34494
34722
  if (version === void 0) return void 0;
34495
34723
  const text = String(version);
34496
34724
  if (!VERSION_PATTERN.test(text)) {
34497
- throw new LineageReadError(
34725
+ throw new import_errors4.LineageReadError(
34498
34726
  "version must be a positive decimal integer",
34499
34727
  void 0,
34500
34728
  "INVALID_VERSION",
@@ -34505,7 +34733,7 @@ function normalizeVersion(version) {
34505
34733
  }
34506
34734
  async function lineageReadFailure(source, response) {
34507
34735
  const { errorCode, message, details } = await readPersonalServerErrorBody(response);
34508
- return new LineageReadError(
34736
+ return new import_errors4.LineageReadError(
34509
34737
  message ?? `${source} lineage read failed: ${response.status} ${response.statusText}`,
34510
34738
  response.status,
34511
34739
  errorCode,
@@ -34517,7 +34745,7 @@ async function parseLineageGraph(source, response) {
34517
34745
  try {
34518
34746
  body = await response.json();
34519
34747
  } catch (err) {
34520
- throw new LineageReadError(
34748
+ throw new import_errors4.LineageReadError(
34521
34749
  `${source} lineage response is not JSON`,
34522
34750
  response.status,
34523
34751
  null,
@@ -34527,7 +34755,7 @@ async function parseLineageGraph(source, response) {
34527
34755
  const envelope = isRecord4(body) && isRecord4(body.data) ? body : void 0;
34528
34756
  const parsed = LineageGraphSchema.safeParse(envelope?.data ?? body);
34529
34757
  if (!parsed.success) {
34530
- throw new LineageReadError(
34758
+ throw new import_errors4.LineageReadError(
34531
34759
  `${source} lineage response is not a lineage view`,
34532
34760
  response.status,
34533
34761
  null,
@@ -34542,7 +34770,7 @@ async function sendLineageRead(source, fetchFn, url, headers) {
34542
34770
  try {
34543
34771
  response = await fetchFn(url, { method: "GET", headers });
34544
34772
  } catch (err) {
34545
- throw new LineageReadError(
34773
+ throw new import_errors4.LineageReadError(
34546
34774
  `${source} lineage read failed: ${err instanceof Error ? err.message : String(err)}`,
34547
34775
  void 0,
34548
34776
  null,
@@ -34583,7 +34811,7 @@ async function getPersonalServerLineage(params) {
34583
34811
  }
34584
34812
  async function getGatewayLineage(params) {
34585
34813
  if (!isDataPointId(params.dataPointId)) {
34586
- throw new LineageReadError(
34814
+ throw new import_errors4.LineageReadError(
34587
34815
  "dataPointId must be a 32-byte hex string (see deriveDataPointId)",
34588
34816
  void 0,
34589
34817
  "INVALID_DATA_POINT_ID",
@@ -34729,13 +34957,13 @@ async function deleteDataPoint(input) {
34729
34957
  if (currentVersion === void 0) {
34730
34958
  const record = await input.gateway.getDataPoint(dataPointId);
34731
34959
  if (record === null) {
34732
- throw new DataPointNotFoundError(
34960
+ throw new import_errors5.DataPointNotFoundError(
34733
34961
  `No data point registered for scope '${input.scope}' owned by ${ownerAddress}`,
34734
34962
  { dataPointId, scope: input.scope, ownerAddress }
34735
34963
  );
34736
34964
  }
34737
34965
  if (isDataPointTombstone(record)) {
34738
- throw new DataPointDeletedError(
34966
+ throw new import_errors5.DataPointDeletedError(
34739
34967
  `Data point ${dataPointId} (scope '${input.scope}') is already deleted`,
34740
34968
  {
34741
34969
  dataPointId,
@@ -34781,6 +35009,9 @@ async function deleteDataPoint(input) {
34781
35009
  }
34782
35010
  }
34783
35011
 
35012
+ // src/protocol/personal-server-data.ts
35013
+ var import_errors6 = require("./errors.cjs");
35014
+
34784
35015
  // src/protocol/data-file.ts
34785
35016
  var import_zod2 = require("zod");
34786
35017
  var DataFileEnvelopeSchema = import_zod2.z.object({
@@ -34839,7 +35070,7 @@ async function readPersonalServerData(params) {
34839
35070
  const request = await buildPersonalServerDataReadRequest(params);
34840
35071
  const response = await fetchFn(request);
34841
35072
  if (response.status === 410) {
34842
- throw new DataPointDeletedError(
35073
+ throw new import_errors6.DataPointDeletedError(
34843
35074
  `Personal Server scope '${params.scope}' has been deleted`,
34844
35075
  {
34845
35076
  scope: params.scope,
@@ -34854,7 +35085,7 @@ async function readPersonalServerData(params) {
34854
35085
  }
34855
35086
  const body = await response.json();
34856
35087
  if (isDataPointTombstone(body)) {
34857
- throw new DataPointDeletedError(
35088
+ throw new import_errors6.DataPointDeletedError(
34858
35089
  `Personal Server scope '${params.scope}' has been deleted`,
34859
35090
  { scope: params.scope, deletedAt: tombstoneDeletedAt(body) }
34860
35091
  );
@@ -35054,20 +35285,22 @@ function tryGrantPermissions(scopes) {
35054
35285
  }
35055
35286
 
35056
35287
  // src/protocol/personal-server-write.ts
35057
- var import_sha27 = require("@noble/hashes/sha2");
35288
+ var import_sha28 = require("@noble/hashes/sha2");
35058
35289
  var import_viem27 = require("viem");
35059
35290
  var import_zod4 = require("zod");
35291
+ var import_errors8 = require("./errors.cjs");
35060
35292
 
35061
35293
  // src/protocol/write-request.ts
35062
- var import_sha26 = require("@noble/hashes/sha2");
35294
+ var import_sha27 = require("@noble/hashes/sha2");
35063
35295
  var import_viem26 = require("viem");
35296
+ var import_errors7 = require("./errors.cjs");
35064
35297
  function normalizeBaseUrl2(url) {
35065
35298
  return url.replace(/\/+$/, "");
35066
35299
  }
35067
35300
  function resolveFetch3(fetchFn) {
35068
35301
  const resolved = fetchFn ?? globalThis.fetch;
35069
35302
  if (resolved === void 0) {
35070
- throw new WriteRequestError("No fetch implementation available");
35303
+ throw new import_errors7.WriteRequestError("No fetch implementation available");
35071
35304
  }
35072
35305
  return resolved;
35073
35306
  }
@@ -35122,27 +35355,27 @@ function nextProofIat(proofKey) {
35122
35355
  return sleep3(waitSec * 1e3).then(() => iat);
35123
35356
  }
35124
35357
  function freshProofNonce() {
35125
- const webCrypto = globalThis.crypto;
35126
- if (typeof webCrypto?.randomUUID === "function") {
35127
- return webCrypto.randomUUID();
35358
+ const webCrypto2 = globalThis.crypto;
35359
+ if (typeof webCrypto2?.randomUUID === "function") {
35360
+ return webCrypto2.randomUUID();
35128
35361
  }
35129
- if (typeof webCrypto?.getRandomValues === "function") {
35130
- return (0, import_viem26.bytesToHex)(webCrypto.getRandomValues(new Uint8Array(16)));
35362
+ if (typeof webCrypto2?.getRandomValues === "function") {
35363
+ return (0, import_viem26.bytesToHex)(webCrypto2.getRandomValues(new Uint8Array(16)));
35131
35364
  }
35132
- throw new WriteRequestError(
35365
+ throw new import_errors7.WriteRequestError(
35133
35366
  "No secure random source available to build a proof nonce; provide a crypto global"
35134
35367
  );
35135
35368
  }
35136
35369
  function proofKeyFor(parts) {
35137
35370
  return (0, import_viem26.bytesToHex)(
35138
- (0, import_sha26.sha256)(
35371
+ (0, import_sha27.sha256)(
35139
35372
  new TextEncoder().encode(
35140
35373
  JSON.stringify([
35141
35374
  parts.aud,
35142
35375
  parts.method,
35143
35376
  parts.uri,
35144
35377
  parts.grantId,
35145
- parts.signedBytes ? (0, import_viem26.bytesToHex)((0, import_sha26.sha256)(parts.signedBytes)) : ""
35378
+ parts.signedBytes ? (0, import_viem26.bytesToHex)((0, import_sha27.sha256)(parts.signedBytes)) : ""
35146
35379
  ])
35147
35380
  )
35148
35381
  )
@@ -35164,7 +35397,7 @@ async function sendWithFreshProof(label, fetchFn, options, proofKey, build) {
35164
35397
  delayMs *= 2;
35165
35398
  }
35166
35399
  }
35167
- throw new WriteTransportError(
35400
+ throw new import_errors7.WriteTransportError(
35168
35401
  `${label} failed after ${attempts} attempt(s): ${errorMessage(lastError)}`,
35169
35402
  attempts,
35170
35403
  lastError
@@ -35235,7 +35468,7 @@ async function openWriteSession(params) {
35235
35468
  const mintedAt = Date.now();
35236
35469
  if (!response.ok) {
35237
35470
  const { errorCode, message, details } = await readPersonalServerErrorBody(response);
35238
- throw new WriteSessionError(
35471
+ throw new import_errors8.WriteSessionError(
35239
35472
  message ?? `Write session handshake failed: ${response.status} ${response.statusText}`,
35240
35473
  response.status,
35241
35474
  errorCode,
@@ -35246,7 +35479,7 @@ async function openWriteSession(params) {
35246
35479
  try {
35247
35480
  body = await response.json();
35248
35481
  } catch (err) {
35249
- throw new WriteSessionError(
35482
+ throw new import_errors8.WriteSessionError(
35250
35483
  "Write session response is not JSON",
35251
35484
  response.status,
35252
35485
  null,
@@ -35255,7 +35488,7 @@ async function openWriteSession(params) {
35255
35488
  }
35256
35489
  const parsed = WriteSessionResponseSchema.safeParse(body);
35257
35490
  if (!parsed.success) {
35258
- throw new WriteSessionError(
35491
+ throw new import_errors8.WriteSessionError(
35259
35492
  "Write session response is not a session",
35260
35493
  response.status,
35261
35494
  null,
@@ -35263,7 +35496,7 @@ async function openWriteSession(params) {
35263
35496
  );
35264
35497
  }
35265
35498
  if (parsed.data.token_type.toLowerCase() !== "bearer") {
35266
- throw new WriteSessionError(
35499
+ throw new import_errors8.WriteSessionError(
35267
35500
  `Write session token type is not Bearer: ${parsed.data.token_type}`,
35268
35501
  response.status
35269
35502
  );
@@ -35285,7 +35518,7 @@ function isWriteSession(value) {
35285
35518
  }
35286
35519
  function sessionCoversScope(session, scope) {
35287
35520
  if (!isRecord4(session) || !Array.isArray(session.writeScopes) || !session.writeScopes.every((pattern) => typeof pattern === "string")) {
35288
- throw new WriteRequestError("session must come from openWriteSession");
35521
+ throw new import_errors8.WriteRequestError("session must come from openWriteSession");
35289
35522
  }
35290
35523
  return session.writeScopes.some(
35291
35524
  (pattern) => scopeMatchesPattern(scope, pattern)
@@ -35310,12 +35543,12 @@ function encodeWriteMetadataHeader(metadata) {
35310
35543
  try {
35311
35544
  json = JSON.stringify(metadata);
35312
35545
  } catch (err) {
35313
- throw new WriteRequestError(
35546
+ throw new import_errors8.WriteRequestError(
35314
35547
  `metadata is not JSON-serialisable: ${errorMessage(err)}`
35315
35548
  );
35316
35549
  }
35317
35550
  if (typeof json !== "string") {
35318
- throw new WriteRequestError("metadata must serialise to JSON");
35551
+ throw new import_errors8.WriteRequestError("metadata must serialise to JSON");
35319
35552
  }
35320
35553
  return json.replace(
35321
35554
  /[\u007f-\uffff]/g,
@@ -35329,7 +35562,7 @@ function binaryWriteSignedBytes(input) {
35329
35562
  mimeType: normalizeBinaryMimeType(input.contentType),
35330
35563
  ...input.filename ? { filename: input.filename } : {},
35331
35564
  sizeBytes: input.bytes.length,
35332
- contentHash: (0, import_viem27.bytesToHex)((0, import_sha27.sha256)(input.bytes)),
35565
+ contentHash: (0, import_viem27.bytesToHex)((0, import_sha28.sha256)(input.bytes)),
35333
35566
  encoding: "base64",
35334
35567
  content: toBase64(input.bytes),
35335
35568
  ...metadata !== void 0 ? { metadata } : {}
@@ -35350,7 +35583,7 @@ function setFilenameHeader(headers, filename) {
35350
35583
  function assertNoReservedKeys(value, where) {
35351
35584
  for (const key of RESERVED_WRITE_KEYS) {
35352
35585
  if (Object.prototype.hasOwnProperty.call(value, key)) {
35353
- throw new WriteRequestError(
35586
+ throw new import_errors8.WriteRequestError(
35354
35587
  `${where} must not contain the reserved ${key} key; the Personal Server stamps it`,
35355
35588
  { key }
35356
35589
  );
@@ -35362,10 +35595,10 @@ function isLineagePair(value) {
35362
35595
  }
35363
35596
  function normalizeLineage(lineage, derivedScope) {
35364
35597
  if (!Array.isArray(lineage)) {
35365
- throw new WriteRequestError("lineage must be an array of data point ids");
35598
+ throw new import_errors8.WriteRequestError("lineage must be an array of data point ids");
35366
35599
  }
35367
35600
  if (lineage.length > MAX_LINEAGE_SOURCES) {
35368
- throw new WriteRequestError(
35601
+ throw new import_errors8.WriteRequestError(
35369
35602
  `lineage lists ${lineage.length} sources; the maximum is ${MAX_LINEAGE_SOURCES}`,
35370
35603
  { max: MAX_LINEAGE_SOURCES, count: lineage.length }
35371
35604
  );
@@ -35378,13 +35611,13 @@ function normalizeLineage(lineage, derivedScope) {
35378
35611
  let id;
35379
35612
  if (isLineagePair(entry)) {
35380
35613
  if (!(0, import_viem27.isAddress)(entry.ownerAddress, { strict: false })) {
35381
- throw new WriteRequestError(
35614
+ throw new import_errors8.WriteRequestError(
35382
35615
  "lineage source ownerAddress must be an EVM address",
35383
35616
  { ownerAddress: entry.ownerAddress }
35384
35617
  );
35385
35618
  }
35386
35619
  if (entry.scope.length === 0) {
35387
- throw new WriteRequestError("lineage source scope is required");
35620
+ throw new import_errors8.WriteRequestError("lineage source scope is required");
35388
35621
  }
35389
35622
  id = deriveDataPointId(entry.ownerAddress, entry.scope);
35390
35623
  sourceScopes.push(entry.scope);
@@ -35392,14 +35625,14 @@ function normalizeLineage(lineage, derivedScope) {
35392
35625
  } else if (isDataPointId(entry)) {
35393
35626
  id = entry;
35394
35627
  } else {
35395
- throw new WriteRequestError(
35628
+ throw new import_errors8.WriteRequestError(
35396
35629
  "lineage entries must be 32-byte hex data point ids or { ownerAddress, scope } pairs",
35397
35630
  { entry }
35398
35631
  );
35399
35632
  }
35400
35633
  const normalized = id.toLowerCase();
35401
35634
  if (seen.has(normalized)) {
35402
- throw new WriteRequestError("lineage must not repeat a data point id", {
35635
+ throw new import_errors8.WriteRequestError("lineage must not repeat a data point id", {
35403
35636
  dataPointId: normalized
35404
35637
  });
35405
35638
  }
@@ -35408,7 +35641,7 @@ function normalizeLineage(lineage, derivedScope) {
35408
35641
  }
35409
35642
  for (const own of ownIds) {
35410
35643
  if (seen.has(own)) {
35411
- throw new WriteRequestError(
35644
+ throw new import_errors8.WriteRequestError(
35412
35645
  "lineage must not cite the record's own data point",
35413
35646
  { dataPointId: own, scope: derivedScope }
35414
35647
  );
@@ -35419,7 +35652,7 @@ function normalizeLineage(lineage, derivedScope) {
35419
35652
  }
35420
35653
  function assertNoLineageField(value, where) {
35421
35654
  if (Object.prototype.hasOwnProperty.call(value, LINEAGE_FIELD)) {
35422
- throw new WriteRequestError(
35655
+ throw new import_errors8.WriteRequestError(
35423
35656
  `${where}.${LINEAGE_FIELD} is reserved; pass sources through the lineage option`
35424
35657
  );
35425
35658
  }
@@ -35427,7 +35660,7 @@ function assertNoLineageField(value, where) {
35427
35660
  function buildMetadataHeader(metadata, sources) {
35428
35661
  if (metadata !== void 0) {
35429
35662
  if (!isRecord4(metadata)) {
35430
- throw new WriteRequestError("metadata must be a plain object");
35663
+ throw new import_errors8.WriteRequestError("metadata must be a plain object");
35431
35664
  }
35432
35665
  assertNoReservedKeys(metadata, "metadata");
35433
35666
  assertNoLineageField(metadata, "metadata");
@@ -35440,24 +35673,24 @@ function buildMetadataHeader(metadata, sources) {
35440
35673
  }
35441
35674
  function prepareWrite(params) {
35442
35675
  if (params.binary !== void 0 && params.data !== void 0) {
35443
- throw new WriteRequestError("Pass either data or binary, not both");
35676
+ throw new import_errors8.WriteRequestError("Pass either data or binary, not both");
35444
35677
  }
35445
35678
  const rawLineage = params.lineage;
35446
35679
  const sources = rawLineage === void 0 || rawLineage === null ? void 0 : normalizeLineage(rawLineage, params.scope);
35447
35680
  if (params.binary !== void 0) {
35448
35681
  const { bytes, contentType, filename } = params.binary;
35449
35682
  if (!(bytes instanceof Uint8Array)) {
35450
- throw new WriteRequestError("binary.bytes must be a Uint8Array");
35683
+ throw new import_errors8.WriteRequestError("binary.bytes must be a Uint8Array");
35451
35684
  }
35452
35685
  if (typeof contentType !== "string" || contentType.trim() === "") {
35453
- throw new WriteRequestError("binary.contentType is required");
35686
+ throw new import_errors8.WriteRequestError("binary.contentType is required");
35454
35687
  }
35455
35688
  if (filename !== void 0) {
35456
35689
  if (typeof filename !== "string") {
35457
- throw new WriteRequestError("binary.filename must be a string");
35690
+ throw new import_errors8.WriteRequestError("binary.filename must be a string");
35458
35691
  }
35459
35692
  if (filename !== filename.trim()) {
35460
- throw new WriteRequestError(
35693
+ throw new import_errors8.WriteRequestError(
35461
35694
  "binary.filename must not have leading or trailing whitespace"
35462
35695
  );
35463
35696
  }
@@ -35477,13 +35710,13 @@ function prepareWrite(params) {
35477
35710
  };
35478
35711
  }
35479
35712
  if (params.data === void 0) {
35480
- throw new WriteRequestError("Pass data (a JSON object) or binary");
35713
+ throw new import_errors8.WriteRequestError("Pass data (a JSON object) or binary");
35481
35714
  }
35482
35715
  if (!isRecord4(params.data)) {
35483
- throw new WriteRequestError("data must be a plain JSON object");
35716
+ throw new import_errors8.WriteRequestError("data must be a plain JSON object");
35484
35717
  }
35485
35718
  if (params.metadata !== void 0) {
35486
- throw new WriteRequestError(
35719
+ throw new import_errors8.WriteRequestError(
35487
35720
  "metadata applies to binary writes; put fields to store inside data"
35488
35721
  );
35489
35722
  }
@@ -35494,12 +35727,12 @@ function prepareWrite(params) {
35494
35727
  try {
35495
35728
  text = JSON.stringify(record);
35496
35729
  } catch (err) {
35497
- throw new WriteRequestError(
35730
+ throw new import_errors8.WriteRequestError(
35498
35731
  `data is not JSON-serialisable: ${errorMessage(err)}`
35499
35732
  );
35500
35733
  }
35501
35734
  if (typeof text !== "string" || !text.startsWith("{")) {
35502
- throw new WriteRequestError("data must serialise to a JSON object");
35735
+ throw new import_errors8.WriteRequestError("data must serialise to a JSON object");
35503
35736
  }
35504
35737
  const body = new TextEncoder().encode(text);
35505
35738
  return {
@@ -35512,31 +35745,31 @@ async function writeErrorFromResponse(response) {
35512
35745
  const { errorCode, message, details } = await readPersonalServerErrorBody(response);
35513
35746
  const text = message ?? `Personal Server write failed: ${response.status} ${response.statusText}`;
35514
35747
  if (response.status === 422 || errorCode?.startsWith("LINEAGE_")) {
35515
- return new WriteLineageError(text, response.status, errorCode, details);
35748
+ return new import_errors8.WriteLineageError(text, response.status, errorCode, details);
35516
35749
  }
35517
35750
  switch (response.status) {
35518
35751
  case 401:
35519
- return new WriteUnauthorizedError(text, errorCode, details);
35752
+ return new import_errors8.WriteUnauthorizedError(text, errorCode, details);
35520
35753
  case 403:
35521
- return new WriteForbiddenError(text, errorCode, details);
35754
+ return new import_errors8.WriteForbiddenError(text, errorCode, details);
35522
35755
  case 409:
35523
- return new WriteConflictError(text, errorCode, details);
35756
+ return new import_errors8.WriteConflictError(text, errorCode, details);
35524
35757
  default:
35525
- return new WriteRejectedError(text, response.status, errorCode, details);
35758
+ return new import_errors8.WriteRejectedError(text, response.status, errorCode, details);
35526
35759
  }
35527
35760
  }
35528
35761
  async function writeData(params) {
35529
35762
  const { session } = params;
35530
35763
  if (!isWriteSession(session)) {
35531
- throw new WriteRequestError("session must come from openWriteSession");
35764
+ throw new import_errors8.WriteRequestError("session must come from openWriteSession");
35532
35765
  }
35533
35766
  const fetchFn = resolveFetch3(params.fetch);
35534
35767
  if (typeof params.scope !== "string" || params.scope.length === 0) {
35535
- throw new WriteRequestError("scope is required");
35768
+ throw new import_errors8.WriteRequestError("scope is required");
35536
35769
  }
35537
35770
  const prepared = prepareWrite(params);
35538
35771
  if (Date.now() >= session.expiresAt) {
35539
- throw new WriteSessionExpiredError(
35772
+ throw new import_errors8.WriteSessionExpiredError(
35540
35773
  "Write session has expired; open a new session",
35541
35774
  { grantId: session.grantId, expiresAt: session.expiresAt }
35542
35775
  );
@@ -35592,7 +35825,7 @@ async function writeData(params) {
35592
35825
  try {
35593
35826
  body = await response.json();
35594
35827
  } catch (err) {
35595
- throw new WriteRejectedError(
35828
+ throw new import_errors8.WriteRejectedError(
35596
35829
  "Personal Server write response is not JSON",
35597
35830
  response.status,
35598
35831
  null,
@@ -35601,7 +35834,7 @@ async function writeData(params) {
35601
35834
  }
35602
35835
  const parsed = WriteDataResultSchema.safeParse(body);
35603
35836
  if (!parsed.success) {
35604
- throw new WriteRejectedError(
35837
+ throw new import_errors8.WriteRejectedError(
35605
35838
  "Personal Server write response is not an ingest result",
35606
35839
  response.status,
35607
35840
  null,
@@ -35628,6 +35861,7 @@ async function writePersonalServerData(params) {
35628
35861
 
35629
35862
  // src/protocol/derivative-questions.ts
35630
35863
  var import_zod5 = require("zod");
35864
+ var import_errors9 = require("./errors.cjs");
35631
35865
  var DERIVATIVE_QUESTIONS_PATH = "/v1/derivatives/questions";
35632
35866
  var MAX_QUESTION_SOURCE_SCOPES = 16;
35633
35867
  var MAX_QUESTION_CHARS = 8e3;
@@ -35710,15 +35944,15 @@ function fetchIdOf(fetchFn) {
35710
35944
  }
35711
35945
  function resolveRequest(params) {
35712
35946
  if (typeof params.personalServerUrl !== "string" || params.personalServerUrl.length === 0) {
35713
- throw new WriteRequestError("personalServerUrl is required");
35947
+ throw new import_errors9.WriteRequestError("personalServerUrl is required");
35714
35948
  }
35715
35949
  if (typeof params.grantId !== "string" || params.grantId.length === 0) {
35716
- throw new WriteRequestError(
35950
+ throw new import_errors9.WriteRequestError(
35717
35951
  "grantId is required; a question call runs under the grant carrying write:<derivedScope>"
35718
35952
  );
35719
35953
  }
35720
35954
  if (params.signer === null || typeof params.signer !== "object") {
35721
- throw new WriteRequestError(
35955
+ throw new import_errors9.WriteRequestError(
35722
35956
  "signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
35723
35957
  );
35724
35958
  }
@@ -35772,37 +36006,37 @@ async function questionErrorFromResponse(response, body) {
35772
36006
  const text = message ?? `Derivative question request failed: ${response.status} ${response.statusText}`;
35773
36007
  switch (errorCode) {
35774
36008
  case "DERIVATIVE_SOURCE_NOT_GRANTED":
35775
- return new DerivativeSourceNotGrantedError(text, errorCode, details);
36009
+ return new import_errors9.DerivativeSourceNotGrantedError(text, errorCode, details);
35776
36010
  case "DERIVATIVE_CYCLE":
35777
- return new DerivativeCycleError(text, errorCode, details);
36011
+ return new import_errors9.DerivativeCycleError(text, errorCode, details);
35778
36012
  case "DERIVATIVE_COMPUTE_UNAVAILABLE":
35779
- return new DerivativeComputeUnavailableError(text, errorCode, details);
36013
+ return new import_errors9.DerivativeComputeUnavailableError(text, errorCode, details);
35780
36014
  case "DERIVATIVE_QUESTION_INVALID":
35781
36015
  case "LINEAGE_SCOPE_UNDER_SOURCE_PREFIX":
35782
- return new DerivativeQuestionInvalidError(
36016
+ return new import_errors9.DerivativeQuestionInvalidError(
35783
36017
  text,
35784
36018
  response.status,
35785
36019
  errorCode,
35786
36020
  details
35787
36021
  );
35788
36022
  case "DERIVATIVE_QUESTION_NOT_FOUND":
35789
- return new DerivativeQuestionNotFoundError(text, errorCode, details);
36023
+ return new import_errors9.DerivativeQuestionNotFoundError(text, errorCode, details);
35790
36024
  case "DERIVATIVE_DERIVED_SCOPE_REQUIRED":
35791
- return new DerivativeDerivedScopeRequiredError(text, errorCode, details);
36025
+ return new import_errors9.DerivativeDerivedScopeRequiredError(text, errorCode, details);
35792
36026
  default:
35793
36027
  break;
35794
36028
  }
35795
36029
  switch (response.status) {
35796
36030
  case 401:
35797
- return new WriteUnauthorizedError(text, errorCode, details);
36031
+ return new import_errors9.WriteUnauthorizedError(text, errorCode, details);
35798
36032
  case 403:
35799
- return new WriteForbiddenError(text, errorCode, details);
36033
+ return new import_errors9.WriteForbiddenError(text, errorCode, details);
35800
36034
  case 404:
35801
- return new DerivativeQuestionNotFoundError(text, errorCode, details);
36035
+ return new import_errors9.DerivativeQuestionNotFoundError(text, errorCode, details);
35802
36036
  case 409:
35803
- return new WriteConflictError(text, errorCode, details);
36037
+ return new import_errors9.WriteConflictError(text, errorCode, details);
35804
36038
  default:
35805
- return new DerivativeQuestionRejectedError(
36039
+ return new import_errors9.DerivativeQuestionRejectedError(
35806
36040
  text,
35807
36041
  response.status,
35808
36042
  errorCode,
@@ -35882,7 +36116,7 @@ async function sendQuestionRequest(params, spec, schema) {
35882
36116
  try {
35883
36117
  body = await response.json();
35884
36118
  } catch (err) {
35885
- throw new DerivativeQuestionRejectedError(
36119
+ throw new import_errors9.DerivativeQuestionRejectedError(
35886
36120
  `${spec.label} response is not JSON`,
35887
36121
  response.status,
35888
36122
  null,
@@ -35891,7 +36125,7 @@ async function sendQuestionRequest(params, spec, schema) {
35891
36125
  }
35892
36126
  const parsed = schema.safeParse(body);
35893
36127
  if (!parsed.success) {
35894
- throw new DerivativeQuestionRejectedError(
36128
+ throw new import_errors9.DerivativeQuestionRejectedError(
35895
36129
  `${spec.label} response is not a derivative question answer`,
35896
36130
  response.status,
35897
36131
  null,
@@ -35902,22 +36136,22 @@ async function sendQuestionRequest(params, spec, schema) {
35902
36136
  }
35903
36137
  function assertQuestionId(questionId) {
35904
36138
  if (typeof questionId !== "string" || questionId.length === 0) {
35905
- throw new WriteRequestError("questionId is required");
36139
+ throw new import_errors9.WriteRequestError("questionId is required");
35906
36140
  }
35907
36141
  return `${DERIVATIVE_QUESTIONS_PATH}/${encodeURIComponent(questionId)}`;
35908
36142
  }
35909
36143
  function registrationBody(params) {
35910
36144
  const { derivedScope, question } = params;
35911
36145
  if (typeof derivedScope !== "string" || derivedScope.length === 0) {
35912
- throw new WriteRequestError("derivedScope is required");
36146
+ throw new import_errors9.WriteRequestError("derivedScope is required");
35913
36147
  }
35914
36148
  if (!Array.isArray(params.sourceScopes) || params.sourceScopes.length === 0) {
35915
- throw new WriteRequestError(
36149
+ throw new import_errors9.WriteRequestError(
35916
36150
  "sourceScopes must be a non-empty array of scopes"
35917
36151
  );
35918
36152
  }
35919
36153
  if (params.sourceScopes.length > MAX_QUESTION_SOURCE_SCOPES) {
35920
- throw new WriteRequestError(
36154
+ throw new import_errors9.WriteRequestError(
35921
36155
  `sourceScopes lists ${params.sourceScopes.length} scopes; the maximum is ${MAX_QUESTION_SOURCE_SCOPES}`,
35922
36156
  { max: MAX_QUESTION_SOURCE_SCOPES, count: params.sourceScopes.length }
35923
36157
  );
@@ -35925,15 +36159,15 @@ function registrationBody(params) {
35925
36159
  const sourceScopes = [];
35926
36160
  for (const scope of params.sourceScopes) {
35927
36161
  if (typeof scope !== "string" || scope.length === 0) {
35928
- throw new WriteRequestError("sourceScopes entries must be scope strings");
36162
+ throw new import_errors9.WriteRequestError("sourceScopes entries must be scope strings");
35929
36163
  }
35930
36164
  if (sourceScopes.includes(scope)) {
35931
- throw new WriteRequestError("sourceScopes must not repeat a scope", {
36165
+ throw new import_errors9.WriteRequestError("sourceScopes must not repeat a scope", {
35932
36166
  duplicate: scope
35933
36167
  });
35934
36168
  }
35935
36169
  if (scope === derivedScope) {
35936
- throw new WriteRequestError(
36170
+ throw new import_errors9.WriteRequestError(
35937
36171
  "derivedScope cannot be one of its own sources",
35938
36172
  { scope }
35939
36173
  );
@@ -35941,17 +36175,17 @@ function registrationBody(params) {
35941
36175
  sourceScopes.push(scope);
35942
36176
  }
35943
36177
  if (typeof question !== "string" || question.trim() === "") {
35944
- throw new WriteRequestError("question must be a non-empty string");
36178
+ throw new import_errors9.WriteRequestError("question must be a non-empty string");
35945
36179
  }
35946
36180
  if (question.length > MAX_QUESTION_CHARS) {
35947
- throw new WriteRequestError(
36181
+ throw new import_errors9.WriteRequestError(
35948
36182
  `question is ${question.length} characters; the maximum is ${MAX_QUESTION_CHARS}`,
35949
36183
  { max: MAX_QUESTION_CHARS, length: question.length }
35950
36184
  );
35951
36185
  }
35952
36186
  if (params.model !== void 0) {
35953
36187
  if (typeof params.model !== "string" || params.model.length > MAX_QUESTION_MODEL_CHARS || !MODEL_ID_PATTERN.test(params.model)) {
35954
- throw new WriteRequestError("model must be a provider model id", {
36188
+ throw new import_errors9.WriteRequestError("model must be a provider model id", {
35955
36189
  model: params.model
35956
36190
  });
35957
36191
  }
@@ -35987,7 +36221,7 @@ async function getQuestion(params) {
35987
36221
  }
35988
36222
  async function listQuestions(params) {
35989
36223
  if (typeof params.derivedScope !== "string" || params.derivedScope.length === 0) {
35990
- throw new WriteRequestError(
36224
+ throw new import_errors9.WriteRequestError(
35991
36225
  "derivedScope is required; a builder may only list its own questions on a scope it may write"
35992
36226
  );
35993
36227
  }
@@ -36045,7 +36279,7 @@ async function waitForQuestion(params) {
36045
36279
  if (isSettled(latest.status)) return latest;
36046
36280
  const remaining = deadline - Date.now();
36047
36281
  if (remaining <= 0) {
36048
- throw new DerivativeQuestionTimeoutError(
36282
+ throw new import_errors9.DerivativeQuestionTimeoutError(
36049
36283
  `Derivative question ${latest.questionId} was still ${latest.status} after ${timeoutMs}ms`,
36050
36284
  {
36051
36285
  questionId: latest.questionId,
@@ -36065,7 +36299,7 @@ async function askPersonalServer(params) {
36065
36299
  questionId: registered.questionId
36066
36300
  });
36067
36301
  if (registration.status !== "ready") {
36068
- throw new DerivativeQuestionFailedError(
36302
+ throw new import_errors9.DerivativeQuestionFailedError(
36069
36303
  `Derivative question ${registration.questionId} failed: ${registration.error ?? "no reason given"}`,
36070
36304
  {
36071
36305
  questionId: registration.questionId,
@@ -36092,6 +36326,7 @@ async function askPersonalServer(params) {
36092
36326
 
36093
36327
  // src/protocol/derivative-status.ts
36094
36328
  var import_zod6 = require("zod");
36329
+ var import_errors10 = require("./errors.cjs");
36095
36330
  var DERIVATIVE_STATUS_PATH = "/v1/derivatives/status";
36096
36331
  var DEFAULT_DERIVATIVE_STATUS_TIMEOUT_MS = 12e4;
36097
36332
  var DEFAULT_DERIVATIVE_STATUS_POLL_INTERVAL_MS = 2e3;
@@ -36122,13 +36357,13 @@ function normalizeBaseUrl3(url) {
36122
36357
  function resolveFetch4(fetchFn) {
36123
36358
  const resolved = fetchFn ?? globalThis.fetch;
36124
36359
  if (resolved === void 0) {
36125
- throw new WriteRequestError("No fetch implementation available");
36360
+ throw new import_errors10.WriteRequestError("No fetch implementation available");
36126
36361
  }
36127
36362
  return resolved;
36128
36363
  }
36129
36364
  function requireDerivedScope(derivedScope) {
36130
36365
  if (typeof derivedScope !== "string" || derivedScope.length === 0) {
36131
- throw new WriteRequestError("derivedScope is required");
36366
+ throw new import_errors10.WriteRequestError("derivedScope is required");
36132
36367
  }
36133
36368
  return derivedScope;
36134
36369
  }
@@ -36147,7 +36382,7 @@ function sleep4(ms, signal) {
36147
36382
  });
36148
36383
  }
36149
36384
  function timeoutError(latest, timeoutMs) {
36150
- return new DerivativeQuestionTimeoutError(
36385
+ return new import_errors10.DerivativeQuestionTimeoutError(
36151
36386
  `Derived scope ${latest.derivedScope} was still ${latest.status} after ${timeoutMs}ms`,
36152
36387
  {
36153
36388
  derivedScope: latest.derivedScope,
@@ -36160,7 +36395,7 @@ function timeoutError(latest, timeoutMs) {
36160
36395
  }
36161
36396
  function abortError2(signal) {
36162
36397
  const reason = signal?.reason;
36163
- return reason instanceof Error ? reason : new WriteRequestError("Derivative status wait was aborted");
36398
+ return reason instanceof Error ? reason : new import_errors10.WriteRequestError("Derivative status wait was aborted");
36164
36399
  }
36165
36400
  function isDerivativeStatusSettled(status) {
36166
36401
  if (status.status === "ready") return true;
@@ -36193,7 +36428,7 @@ async function getDerivativeStatus(params) {
36193
36428
  }
36194
36429
  );
36195
36430
  } catch (err) {
36196
- throw new WriteTransportError(
36431
+ throw new import_errors10.WriteTransportError(
36197
36432
  `Derivative status read failed: ${err instanceof Error ? err.message : String(err)}`,
36198
36433
  1,
36199
36434
  err
@@ -36208,7 +36443,7 @@ async function getDerivativeStatus(params) {
36208
36443
  try {
36209
36444
  body = await response.json();
36210
36445
  } catch (err) {
36211
- throw new DerivativeQuestionRejectedError(
36446
+ throw new import_errors10.DerivativeQuestionRejectedError(
36212
36447
  "Derivative status response is not JSON",
36213
36448
  response.status,
36214
36449
  null,
@@ -36217,7 +36452,7 @@ async function getDerivativeStatus(params) {
36217
36452
  }
36218
36453
  const parsed = DerivativeStatusSchema.safeParse(body);
36219
36454
  if (!parsed.success) {
36220
- throw new DerivativeQuestionRejectedError(
36455
+ throw new import_errors10.DerivativeQuestionRejectedError(
36221
36456
  "Derivative status response is not a status view",
36222
36457
  response.status,
36223
36458
  null,
@@ -36251,6 +36486,7 @@ async function waitForDerivativeStatus(params) {
36251
36486
  }
36252
36487
 
36253
36488
  // src/protocol/gateway.ts
36489
+ var import_errors11 = require("./errors.cjs");
36254
36490
  function withGrantPermissions(grant) {
36255
36491
  const stripped = { ...grant };
36256
36492
  delete stripped.permissions;
@@ -36296,7 +36532,7 @@ function createGatewayClient(baseUrl) {
36296
36532
  }
36297
36533
  async function deletedError(res, details) {
36298
36534
  const body = await readBody(res);
36299
- return new DataPointDeletedError(
36535
+ return new import_errors11.DataPointDeletedError(
36300
36536
  `Data point ${details.dataPointId ?? details.scope ?? ""} has been deleted`,
36301
36537
  { ...details, deletedAt: tombstoneDeletedAt(body) }
36302
36538
  );
@@ -36369,7 +36605,7 @@ function createGatewayClient(baseUrl) {
36369
36605
  }
36370
36606
  const record = await unwrapEnvelope(res);
36371
36607
  if (!options?.includeDeleted && isDataPointTombstone(record)) {
36372
- throw new DataPointDeletedError(
36608
+ throw new import_errors11.DataPointDeletedError(
36373
36609
  `Data point ${dataPointId} has been deleted`,
36374
36610
  {
36375
36611
  dataPointId,
@@ -36531,7 +36767,7 @@ function createGatewayClient(baseUrl) {
36531
36767
  })
36532
36768
  });
36533
36769
  if (res.status === 404) {
36534
- throw new DataPointNotFoundError(
36770
+ throw new import_errors11.DataPointNotFoundError(
36535
36771
  `Data point ${dataPointId} (scope '${params.scope}') is not registered`,
36536
36772
  details
36537
36773
  );
@@ -36542,7 +36778,7 @@ function createGatewayClient(baseUrl) {
36542
36778
  body2["currentExpectedVersion"]
36543
36779
  );
36544
36780
  const detail = stringOrUndefined(body2["error"]) ?? res.statusText;
36545
- throw new DataPointVersionConflictError(
36781
+ throw new import_errors11.DataPointVersionConflictError(
36546
36782
  `Gateway error: 409 ${detail}`,
36547
36783
  {
36548
36784
  ...details,
@@ -36673,6 +36909,7 @@ function createGatewayClient(baseUrl) {
36673
36909
  }
36674
36910
 
36675
36911
  // src/protocol/escrow.ts
36912
+ var import_viem28 = require("viem");
36676
36913
  var GENERIC_PAYMENT_TYPES = {
36677
36914
  GenericPayment: [
36678
36915
  { name: "payerAddress", type: "address" },
@@ -36712,6 +36949,26 @@ var ESCROW_DEPOSIT_ABI2 = [
36712
36949
  }
36713
36950
  ];
36714
36951
  var NATIVE_ASSET_ADDRESS = "0x0000000000000000000000000000000000000000";
36952
+ var EscrowWithdrawalLifecycleError = class extends Error {
36953
+ constructor(httpStatus, result) {
36954
+ super(result.error);
36955
+ this.httpStatus = httpStatus;
36956
+ this.result = result;
36957
+ }
36958
+ httpStatus;
36959
+ result;
36960
+ name = "EscrowWithdrawalLifecycleError";
36961
+ };
36962
+ var EscrowWithdrawalRejectionError = class extends Error {
36963
+ constructor(httpStatus, result) {
36964
+ super(result.error);
36965
+ this.httpStatus = httpStatus;
36966
+ this.result = result;
36967
+ }
36968
+ httpStatus;
36969
+ result;
36970
+ name = "EscrowWithdrawalRejectionError";
36971
+ };
36715
36972
  function createEscrowGatewayClient(baseUrl) {
36716
36973
  const base = baseUrl.replace(/\/+$/, "");
36717
36974
  async function throwOnError(res, context) {
@@ -36727,6 +36984,27 @@ function createEscrowGatewayClient(baseUrl) {
36727
36984
  );
36728
36985
  }
36729
36986
  }
36987
+ async function throwOnWithdrawError(res) {
36988
+ if (res.ok) return;
36989
+ let body;
36990
+ try {
36991
+ body = await res.json();
36992
+ } catch {
36993
+ throw new Error(
36994
+ `Escrow gateway error (POST /v1/escrow/withdraw): ${res.status} ${res.statusText}`
36995
+ );
36996
+ }
36997
+ if (isEscrowWithdrawalFailureResult(body)) {
36998
+ throw new EscrowWithdrawalLifecycleError(res.status, body);
36999
+ }
37000
+ if (isEscrowWithdrawalRejectedResult(body)) {
37001
+ throw new EscrowWithdrawalRejectionError(res.status, body);
37002
+ }
37003
+ const error = getGatewayErrorMessage(body);
37004
+ throw new Error(
37005
+ `Escrow gateway error (POST /v1/escrow/withdraw): ${res.status} ${res.statusText}${error ? `: ${error}` : ""}`
37006
+ );
37007
+ }
36730
37008
  return {
36731
37009
  async submitDeposit({ txHash }) {
36732
37010
  const res = await fetch(`${base}/v1/escrow/deposit`, {
@@ -36782,9 +37060,108 @@ function createEscrowGatewayClient(baseUrl) {
36782
37060
  });
36783
37061
  await throwOnError(res, "POST /v1/escrow/pay");
36784
37062
  return res.json();
37063
+ },
37064
+ async withdraw({
37065
+ account,
37066
+ asset,
37067
+ amount,
37068
+ withdrawNonce,
37069
+ deadline,
37070
+ signature
37071
+ }) {
37072
+ const res = await fetch(`${base}/v1/escrow/withdraw`, {
37073
+ method: "POST",
37074
+ headers: {
37075
+ "Content-Type": "application/json",
37076
+ Authorization: `Web3Signed ${signature}`
37077
+ },
37078
+ body: JSON.stringify({
37079
+ account,
37080
+ asset,
37081
+ amount,
37082
+ withdrawNonce,
37083
+ deadline
37084
+ })
37085
+ });
37086
+ await throwOnWithdrawError(res);
37087
+ return res.json();
37088
+ },
37089
+ async getWithdrawNonce(account) {
37090
+ const res = await fetch(
37091
+ `${base}/v1/escrow/withdraw/nonce?account=${encodeURIComponent(account)}`,
37092
+ { cache: "no-store" }
37093
+ );
37094
+ await throwOnError(res, "GET /v1/escrow/withdraw/nonce");
37095
+ const body = await res.json();
37096
+ if (!isWithdrawNonceResponse(body, account)) {
37097
+ throw new Error(
37098
+ "GET /v1/escrow/withdraw/nonce: invalid response structure"
37099
+ );
37100
+ }
37101
+ return body;
36785
37102
  }
36786
37103
  };
36787
37104
  }
37105
+ function getGatewayErrorMessage(body) {
37106
+ if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
37107
+ return body.error;
37108
+ }
37109
+ return void 0;
37110
+ }
37111
+ function isEscrowWithdrawalFailureResult(body) {
37112
+ if (typeof body !== "object" || body === null) return false;
37113
+ const value = body;
37114
+ return value.success === false && (value.status === "retryable" || value.status === "reorged" || value.status === "failed") && typeof value.error === "string" && isAddressHex(value.account) && isAddressHex(value.asset) && isUint256Decimal(value.amount) && isUint256Decimal(value.withdrawNonce) && isUint256Decimal(value.deadline) && (isHash(value.txHash) || value.txHash === null) && (!("blockNumber" in value) || isBlockNumber(value.blockNumber));
37115
+ }
37116
+ function isEscrowWithdrawalRejectedResult(body) {
37117
+ if (typeof body !== "object" || body === null) return false;
37118
+ const value = body;
37119
+ return value.success === false && value.status === "rejected" && isWithdrawalRejectionCode(value.code) && typeof value.error === "string" && isAddressHex(value.account) && isAddressHex(value.asset) && isUint256Decimal(value.amount) && isUint256Decimal(value.withdrawNonce) && isUint256Decimal(value.deadline) && optionalUint256Decimal(value.balance) && optionalUint256Decimal(value.authorizedAmount) && optionalUint256Decimal(value.withdrawingAmount) && optionalUint256Decimal(value.availableAmount) && optionalUint256Decimal(value.requestedAmount) && optionalUint256Decimal(value.minimumAmount);
37120
+ }
37121
+ function isWithdrawalRejectionCode(value) {
37122
+ return value === "below_minimum" || value === "deadline_too_far" || value === "expired" || value === "insufficient_available" || value === "stale_nonce";
37123
+ }
37124
+ function optionalUint256Decimal(value) {
37125
+ return value === void 0 || isUint256Decimal(value);
37126
+ }
37127
+ function isAddressHex(value) {
37128
+ return typeof value === "string" && (0, import_viem28.isHex)(value, { strict: true }) && value.length === 42;
37129
+ }
37130
+ function isHash(value) {
37131
+ return typeof value === "string" && (0, import_viem28.isHex)(value, { strict: true }) && value.length === 66;
37132
+ }
37133
+ function isUint256Decimal(value) {
37134
+ if (typeof value !== "string" || value.length === 0 || value.length > 78) {
37135
+ return false;
37136
+ }
37137
+ if (!/^(0|[1-9]\d*)$/.test(value)) return false;
37138
+ return BigInt(value) <= 2n ** 256n - 1n;
37139
+ }
37140
+ function isBlockNumber(value) {
37141
+ return value === null || isUint256Decimal(value);
37142
+ }
37143
+ function isWithdrawNonceResponse(body, requestedAccount) {
37144
+ if (typeof body !== "object" || body === null) return false;
37145
+ const value = body;
37146
+ if (value.success !== true) return false;
37147
+ if (!isAddressHex(value.account)) return false;
37148
+ if (value.account.toLowerCase() !== requestedAccount.toLowerCase())
37149
+ return false;
37150
+ if (typeof value.chainId !== "string") return false;
37151
+ if (!/^(0|[1-9]\d*)$/.test(value.chainId)) return false;
37152
+ const isLastNull = value.lastWithdrawNonce === null;
37153
+ const lastNonceValid = isLastNull || isUint256Decimal(value.lastWithdrawNonce);
37154
+ if (!lastNonceValid) return false;
37155
+ if (!isUint256Decimal(value.nextWithdrawNonce)) return false;
37156
+ if (isLastNull) {
37157
+ return value.nextWithdrawNonce === "1";
37158
+ }
37159
+ const lastNonce = BigInt(value.lastWithdrawNonce);
37160
+ const nextNonce = BigInt(value.nextWithdrawNonce);
37161
+ const expectedNextNonce = lastNonce + 1n;
37162
+ if (expectedNextNonce > 2n ** 256n - 1n) return false;
37163
+ return nextNonce === expectedNextNonce;
37164
+ }
36788
37165
 
36789
37166
  // src/direct/escrow-payment.ts
36790
37167
  var GRANT_OP_TYPE = "grant";
@@ -36821,12 +37198,12 @@ var UINT256_MAX = (1n << 256n) - 1n;
36821
37198
  var ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
36822
37199
  var BYTES32_RE = /^0x[0-9a-fA-F]{64}$/;
36823
37200
  var SIGNATURE_RE = /^0x[0-9a-fA-F]{130}$/;
36824
- function isUint256Decimal(value, allowZero) {
37201
+ function isUint256Decimal2(value, allowZero) {
36825
37202
  const pattern = allowZero ? /^(0|[1-9]\d*)$/ : /^[1-9]\d*$/;
36826
37203
  return value.length <= UINT256_MAX.toString().length && pattern.test(value) && BigInt(value) <= UINT256_MAX;
36827
37204
  }
36828
37205
  function isValidAccessRecord(record) {
36829
- return BYTES32_RE.test(record.dataPointId) && isUint256Decimal(record.version, false) && ADDRESS_RE.test(record.accessor) && BYTES32_RE.test(record.recordId) && SIGNATURE_RE.test(record.signature);
37206
+ return BYTES32_RE.test(record.dataPointId) && isUint256Decimal2(record.version, false) && ADDRESS_RE.test(record.accessor) && BYTES32_RE.test(record.recordId) && SIGNATURE_RE.test(record.signature);
36830
37207
  }
36831
37208
  function validateSigningOperation(payerAddress, required) {
36832
37209
  if (!ADDRESS_RE.test(payerAddress)) {
@@ -36838,10 +37215,10 @@ function validateSigningOperation(payerAddress, required) {
36838
37215
  if (!ADDRESS_RE.test(required.asset || NATIVE_ASSET_ADDRESS)) {
36839
37216
  throw new Error("Payment asset must be a 20-byte EVM address");
36840
37217
  }
36841
- if (!isUint256Decimal(required.amount, true)) {
37218
+ if (!isUint256Decimal2(required.amount, true)) {
36842
37219
  throw new Error("Payment amount must be a canonical uint256 decimal");
36843
37220
  }
36844
- if (required.paymentNonce !== void 0 && !isUint256Decimal(required.paymentNonce, false)) {
37221
+ if (required.paymentNonce !== void 0 && !isUint256Decimal2(required.paymentNonce, false)) {
36845
37222
  throw new Error("Payment nonce must be a positive uint256 decimal");
36846
37223
  }
36847
37224
  const accessRecord = required.accessRecord;
@@ -36972,7 +37349,7 @@ function paymentResponseMetadataFromHeader(header) {
36972
37349
  const registrationFee = stringField(breakdown, "registrationFee");
36973
37350
  const dataAccessFee = stringField(breakdown, "dataAccessFee");
36974
37351
  const paidAt = stringField(result, "paidAt");
36975
- if (result?.success !== true || !opType || !opId || !BYTES32_RE.test(opId) || !payerAddress || !ADDRESS_RE.test(payerAddress) || !asset || !ADDRESS_RE.test(asset) || !amount || !isUint256Decimal(amount, true) || !paymentNonce || !isUint256Decimal(paymentNonce, false) || !registrationFee || !isUint256Decimal(registrationFee, true) || !dataAccessFee || !isUint256Decimal(dataAccessFee, true) || typeof breakdown?.registrationPaid !== "boolean" || !paidAt || !isCanonicalIsoTimestamp(paidAt)) {
37352
+ if (result?.success !== true || !opType || !opId || !BYTES32_RE.test(opId) || !payerAddress || !ADDRESS_RE.test(payerAddress) || !asset || !ADDRESS_RE.test(asset) || !amount || !isUint256Decimal2(amount, true) || !paymentNonce || !isUint256Decimal2(paymentNonce, false) || !registrationFee || !isUint256Decimal2(registrationFee, true) || !dataAccessFee || !isUint256Decimal2(dataAccessFee, true) || typeof breakdown?.registrationPaid !== "boolean" || !paidAt || !isCanonicalIsoTimestamp(paidAt)) {
36976
37353
  return void 0;
36977
37354
  }
36978
37355
  return {
@@ -37021,18 +37398,9 @@ async function authorizeEscrowPayment(params) {
37021
37398
  return toDirectPaymentReceipt(result);
37022
37399
  }
37023
37400
 
37024
- // src/direct/errors.ts
37025
- var PersonalServerReadError = class extends VanaError {
37026
- constructor(message, status, details) {
37027
- super(message, "DIRECT_PERSONAL_SERVER_READ_ERROR");
37028
- this.status = status;
37029
- this.details = details;
37030
- }
37031
- status;
37032
- details;
37033
- };
37034
-
37035
37401
  // src/direct/personal-server-read.ts
37402
+ var import_errors12 = require("./direct/errors.cjs");
37403
+ var import_errors13 = require("./errors.cjs");
37036
37404
  function asRecord2(value) {
37037
37405
  return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
37038
37406
  }
@@ -37062,21 +37430,21 @@ function isBytes32Hex(value) {
37062
37430
  return /^0x[0-9a-fA-F]{64}$/.test(value);
37063
37431
  }
37064
37432
  var UINT256_MAX2 = (1n << 256n) - 1n;
37065
- function isAddressHex(value) {
37433
+ function isAddressHex2(value) {
37066
37434
  return /^0x[0-9a-fA-F]{40}$/.test(value);
37067
37435
  }
37068
- function isUint256Decimal2(value, allowZero) {
37436
+ function isUint256Decimal3(value, allowZero) {
37069
37437
  const pattern = allowZero ? /^(0|[1-9]\d*)$/ : /^[1-9]\d*$/;
37070
37438
  return value.length <= UINT256_MAX2.toString().length && pattern.test(value) && BigInt(value) <= UINT256_MAX2;
37071
37439
  }
37072
37440
  function isValidDataAccessRecord(record) {
37073
- return isBytes32Hex(record.dataPointId) && isUint256Decimal2(record.version, false) && isAddressHex(record.accessor) && isBytes32Hex(record.recordId) && /^0x[0-9a-fA-F]{130}$/.test(record.signature);
37441
+ return isBytes32Hex(record.dataPointId) && isUint256Decimal3(record.version, false) && isAddressHex2(record.accessor) && isBytes32Hex(record.recordId) && /^0x[0-9a-fA-F]{130}$/.test(record.signature);
37074
37442
  }
37075
37443
  function parseLegacyGrantOperation(params) {
37076
37444
  const { challengeGrantId, challengeOpId, challengeOpType, grantId } = params;
37077
37445
  const opType = challengeOpType ?? GRANT_OP_TYPE;
37078
37446
  if (opType !== GRANT_OP_TYPE) {
37079
- throw new PersonalServerReadError(
37447
+ throw new import_errors12.PersonalServerReadError(
37080
37448
  "Personal Server payment challenge used an unsupported escrow op type",
37081
37449
  402,
37082
37450
  { opType: challengeOpType }
@@ -37084,14 +37452,14 @@ function parseLegacyGrantOperation(params) {
37084
37452
  }
37085
37453
  const opId = challengeOpId ?? challengeGrantId ?? grantId;
37086
37454
  if (!opId || !isBytes32Hex(opId)) {
37087
- throw new PersonalServerReadError(
37455
+ throw new import_errors12.PersonalServerReadError(
37088
37456
  "Personal Server payment challenge used an invalid escrow op id",
37089
37457
  402,
37090
37458
  { opId }
37091
37459
  );
37092
37460
  }
37093
37461
  if (opId.toLowerCase() !== grantId.toLowerCase()) {
37094
- throw new PersonalServerReadError(
37462
+ throw new import_errors12.PersonalServerReadError(
37095
37463
  "Personal Server payment challenge did not match the requested grant",
37096
37464
  402,
37097
37465
  { opId, grantId }
@@ -37121,7 +37489,7 @@ function parseCanonicalDataAccessAccept(value) {
37121
37489
  const accessRecord = parseAccessRecord(accept?.accessRecord);
37122
37490
  const acceptAsset = stringField2(accept, "asset");
37123
37491
  const acceptAmount = stringField2(accept, "amount");
37124
- if (!network || !payerAddress || !isAddressHex(payerAddress) || !opId || !isBytes32Hex(opId) || !asset || !isAddressHex(asset) || !amount || !isUint256Decimal2(amount, true) || !paymentNonce || !isUint256Decimal2(paymentNonce, false) || !accessRecord || !isValidDataAccessRecord(accessRecord) || payerAddress.toLowerCase() !== accessRecord.accessor.toLowerCase() || opId.toLowerCase() !== accessRecord.recordId.toLowerCase() || !acceptAsset || acceptAsset.toLowerCase() !== asset.toLowerCase() || acceptAmount !== amount) {
37492
+ if (!network || !payerAddress || !isAddressHex2(payerAddress) || !opId || !isBytes32Hex(opId) || !asset || !isAddressHex2(asset) || !amount || !isUint256Decimal3(amount, true) || !paymentNonce || !isUint256Decimal3(paymentNonce, false) || !accessRecord || !isValidDataAccessRecord(accessRecord) || payerAddress.toLowerCase() !== accessRecord.accessor.toLowerCase() || opId.toLowerCase() !== accessRecord.recordId.toLowerCase() || !acceptAsset || acceptAsset.toLowerCase() !== asset.toLowerCase() || acceptAmount !== amount) {
37125
37493
  return null;
37126
37494
  }
37127
37495
  return {
@@ -37137,7 +37505,7 @@ function parseCanonicalDataAccessAccept(value) {
37137
37505
  function parseCanonicalDataAccessPayment(params) {
37138
37506
  const { body, grantId, raw } = params;
37139
37507
  if (body.x402Version !== 1 || body.error !== "PAYMENT_REQUIRED") {
37140
- throw new PersonalServerReadError(
37508
+ throw new import_errors12.PersonalServerReadError(
37141
37509
  "Personal Server data-access payment response was not a canonical x402 challenge",
37142
37510
  402
37143
37511
  );
@@ -37176,20 +37544,20 @@ async function parsePersonalServerPaymentRequired(res, grantId) {
37176
37544
  "accepts"
37177
37545
  );
37178
37546
  if (hasAcceptsEnvelope && (body.x402Version !== 1 || body.error !== "PAYMENT_REQUIRED")) {
37179
- throw new PersonalServerReadError(
37547
+ throw new import_errors12.PersonalServerReadError(
37180
37548
  "Personal Server grant payment response was not a canonical x402 challenge",
37181
37549
  402
37182
37550
  );
37183
37551
  }
37184
37552
  const accept = preferredLegacyAccept(body);
37185
37553
  if (hasDataAccessMarker(body) && !accept) {
37186
- throw new PersonalServerReadError(
37554
+ throw new import_errors12.PersonalServerReadError(
37187
37555
  "Personal Server data-access payment challenge was untrusted or incomplete",
37188
37556
  402
37189
37557
  );
37190
37558
  }
37191
37559
  if (hasAcceptsEnvelope && !accept) {
37192
- throw new PersonalServerReadError(
37560
+ throw new import_errors12.PersonalServerReadError(
37193
37561
  "Personal Server grant payment challenge had no compatible escrow offer",
37194
37562
  402
37195
37563
  );
@@ -37206,8 +37574,8 @@ async function parsePersonalServerPaymentRequired(res, grantId) {
37206
37574
  const acceptAmount = stringField2(accept, "amount");
37207
37575
  const accessRecord2 = parseAccessRecord(accept.accessRecord);
37208
37576
  const hasAccessRecord = accept.accessRecord !== void 0;
37209
- if (!network || !payerAddress || !isAddressHex(payerAddress) || !opId || !isBytes32Hex(opId) || !asset || !isAddressHex(asset) || !amount || !isUint256Decimal2(amount, true) || !paymentNonce || !isUint256Decimal2(paymentNonce, false) || !acceptAsset || acceptAsset.toLowerCase() !== asset.toLowerCase() || acceptAmount !== amount || hasAccessRecord && (!accessRecord2 || !isValidDataAccessRecord(accessRecord2) || accessRecord2.accessor.toLowerCase() !== payerAddress.toLowerCase()) || amount === "0" && !accessRecord2) {
37210
- throw new PersonalServerReadError(
37577
+ if (!network || !payerAddress || !isAddressHex2(payerAddress) || !opId || !isBytes32Hex(opId) || !asset || !isAddressHex2(asset) || !amount || !isUint256Decimal3(amount, true) || !paymentNonce || !isUint256Decimal3(paymentNonce, false) || !acceptAsset || acceptAsset.toLowerCase() !== asset.toLowerCase() || acceptAmount !== amount || hasAccessRecord && (!accessRecord2 || !isValidDataAccessRecord(accessRecord2) || accessRecord2.accessor.toLowerCase() !== payerAddress.toLowerCase()) || amount === "0" && !accessRecord2) {
37578
+ throw new import_errors12.PersonalServerReadError(
37211
37579
  "Personal Server grant payment challenge was untrusted or incomplete",
37212
37580
  402
37213
37581
  );
@@ -37323,14 +37691,11 @@ async function parsePSError(response) {
37323
37691
  AccountPersonalServerLiteOwnerBindingError,
37324
37692
  AccountPersonalServerRegistrationError,
37325
37693
  BUILDER_REGISTRATION_TYPES,
37326
- BlockchainError,
37327
37694
  BrowserPlatformAdapter,
37328
- BuilderUnknownError,
37329
37695
  CLAIM_POLL_FLOOR_MS,
37330
37696
  CONTRACTS,
37331
37697
  CallbackStorage,
37332
37698
  ContractFactory,
37333
- ContractNotFoundError,
37334
37699
  DATA_ACCESS_OP_TYPE,
37335
37700
  DATA_REGISTRY_STATUS_ABI,
37336
37701
  DEFAULT_DERIVATIVE_STATUS_POLL_INTERVAL_MS,
@@ -37343,21 +37708,9 @@ async function parsePSError(response) {
37343
37708
  DERIVATIVE_QUESTIONS_PATH,
37344
37709
  DERIVATIVE_STATUS_PATH,
37345
37710
  DataFileEnvelopeSchema,
37346
- DataPointDeletedError,
37347
- DataPointNotFoundError,
37348
37711
  DataPointStatus,
37349
- DataPointVersionConflictError,
37350
- DerivativeComputeUnavailableError,
37351
- DerivativeCycleError,
37352
- DerivativeDerivedScopeRequiredError,
37353
37712
  DerivativeErrorCodeSchema,
37354
- DerivativeQuestionFailedError,
37355
- DerivativeQuestionInvalidError,
37356
- DerivativeQuestionNotFoundError,
37357
- DerivativeQuestionRejectedError,
37358
37713
  DerivativeQuestionSchema,
37359
- DerivativeQuestionTimeoutError,
37360
- DerivativeSourceNotGrantedError,
37361
37714
  DerivativeStatusSchema,
37362
37715
  DropboxStorage,
37363
37716
  ECIESError,
@@ -37365,6 +37718,8 @@ async function parsePSError(response) {
37365
37718
  ENCLAVE_TRUST_ANCHORS,
37366
37719
  ENCLAVE_WALLET_PURPOSE,
37367
37720
  ESCROW_DEPOSIT_ABI,
37721
+ EscrowWithdrawalLifecycleError,
37722
+ EscrowWithdrawalRejectionError,
37368
37723
  ExpiredTokenError,
37369
37724
  FEE_REGISTRY_ABI,
37370
37725
  GENERIC_PAYMENT_TYPES,
@@ -37372,35 +37727,26 @@ async function parsePSError(response) {
37372
37727
  GRANT_REGISTRATION_TYPES,
37373
37728
  GRANT_REVOCATION_TYPES,
37374
37729
  GoogleDriveStorage,
37375
- GrantInvalidError,
37376
37730
  InMemoryTokenStore,
37377
37731
  IngestResponseSchema,
37378
- InvalidConfigurationError,
37379
37732
  InvalidScopeEntryError,
37380
37733
  InvalidSignatureError,
37381
37734
  IpfsStorage,
37382
37735
  JOB_OPERATIONS,
37383
37736
  JOB_PROTOCOL_VERSION,
37737
+ JOB_RESULT_CHUNK_BYTES,
37738
+ JOB_RESULT_FORMAT_VERSION,
37384
37739
  JOB_STATES,
37385
37740
  JobEnvelopeError,
37386
- JobIdTakenError,
37387
- JobNotFoundError,
37388
- JobRejectedError,
37389
- JobRequestTooLargeError,
37390
- JobTimeoutError,
37391
- JobTransportError,
37392
- JobsClientError,
37393
37741
  LINEAGE_FIELD,
37394
37742
  LINEAGE_KEY,
37395
37743
  LineageEntrySchema,
37396
37744
  LineageGraphSchema,
37397
37745
  LineageNodeSchema,
37398
- LineageReadError,
37399
37746
  MASTER_KEY_MESSAGE,
37400
37747
  MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS,
37401
37748
  MASTER_SIGNATURE_DELIVERY_VERSION,
37402
37749
  MAX_ATTEMPTS,
37403
- MAX_INLINE_RESULT_BYTES,
37404
37750
  MAX_JOB_DEADLINE_SECONDS,
37405
37751
  MAX_LEASE_SECONDS,
37406
37752
  MAX_LINEAGE_SOURCES,
@@ -37411,12 +37757,9 @@ async function parsePSError(response) {
37411
37757
  MissingAuthError,
37412
37758
  NATIVE_ASSET_ADDRESS,
37413
37759
  NATIVE_VANA_ASSET,
37414
- NetworkError,
37415
37760
  NodeECIESProvider,
37416
37761
  NodePlatformAdapter,
37417
- NonceError,
37418
37762
  OAuthClient,
37419
- OwnerNotReadyError,
37420
37763
  PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX,
37421
37764
  PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE,
37422
37765
  PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION,
@@ -37425,9 +37768,6 @@ async function parsePSError(response) {
37425
37768
  PKCE_CHALLENGE_PATTERN,
37426
37769
  PKCE_VERIFIER_PATTERN,
37427
37770
  PSError,
37428
- PermissionError,
37429
- PersonalServerError,
37430
- PersonalServerWriteError,
37431
37771
  PinataStorage,
37432
37772
  QUESTION_STATUSES,
37433
37773
  QuestionDeleteResultSchema,
@@ -37438,42 +37778,26 @@ async function parsePSError(response) {
37438
37778
  RECORD_DATA_ACCESS_TYPES,
37439
37779
  REGISTRATION_KIND_FOR_OP,
37440
37780
  RESERVED_WRITE_KEYS,
37441
- ReadOnlyError,
37442
37781
  RedactedLineageNodeSchema,
37443
- RelayerError,
37444
37782
  SCOPE_ACTIONS,
37445
37783
  SEALED_ENVELOPE_VERSION,
37446
37784
  SERVER_REGISTRATION_TYPES,
37447
37785
  ScopeSchema,
37448
- SerializationError,
37449
- ServerUrlMismatchError,
37450
- SignatureError,
37451
37786
  StorageError,
37452
37787
  StorageManager,
37453
37788
  TOMBSTONE_DATA_HASH,
37454
37789
  TOMBSTONE_DATA_HASH_PREIMAGE,
37455
37790
  TOMBSTONE_METADATA_HASH,
37456
37791
  TOMBSTONE_METADATA_HASH_PREIMAGE,
37457
- TransactionPendingError,
37458
37792
  USER_PS_ID_DOMAIN,
37459
- UserRejectedRequestError,
37460
- VanaError,
37461
37793
  VanaStorage,
37794
+ WITHDRAW_AUTHORIZATION_TYPES,
37462
37795
  WRITER_ATTRIBUTION_KEY,
37463
37796
  WRITE_CONTENT_DISPOSITION_HEADER,
37464
37797
  WRITE_FILENAME_HEADER,
37465
37798
  WRITE_METADATA_HEADER,
37466
37799
  WRITE_SESSION_PATH,
37467
37800
  WRITE_SIGNATURE_HEADER,
37468
- WriteConflictError,
37469
- WriteForbiddenError,
37470
- WriteLineageError,
37471
- WriteRejectedError,
37472
- WriteRequestError,
37473
- WriteSessionError,
37474
- WriteSessionExpiredError,
37475
- WriteTransportError,
37476
- WriteUnauthorizedError,
37477
37801
  appRootPreimage,
37478
37802
  askPersonalServer,
37479
37803
  assertDerivedScopeNaming,
@@ -37496,6 +37820,7 @@ async function parsePSError(response) {
37496
37820
  buildPersonalServerRegistrationTypedData,
37497
37821
  buildSetDataPointStatusRequest,
37498
37822
  buildWeb3SignedHeader,
37823
+ buildWithdrawAuthorizationTypedData,
37499
37824
  builderRegistrationDomain,
37500
37825
  canonicalJobRequestBytes,
37501
37826
  chains,
@@ -37578,6 +37903,7 @@ async function parsePSError(response) {
37578
37903
  normalizeBinaryMimeType,
37579
37904
  openJobRequest,
37580
37905
  openJobResult,
37906
+ openJobResultStream,
37581
37907
  openWriteSession,
37582
37908
  parsePSError,
37583
37909
  parsePersonalServerPaymentRequired,
@@ -37603,6 +37929,7 @@ async function parsePSError(response) {
37603
37929
  scopeToPathSegments,
37604
37930
  sealJobRequest,
37605
37931
  sealJobResult,
37932
+ sealJobResultStream,
37606
37933
  serializeECIES,
37607
37934
  serverRegistrationDomain,
37608
37935
  sessionCoversScope,
@@ -37621,7 +37948,9 @@ async function parsePSError(response) {
37621
37948
  verifyWeb3Signed,
37622
37949
  waitForDerivativeStatus,
37623
37950
  waitForQuestion,
37951
+ withdrawAuthorizationDomain,
37624
37952
  writeData,
37625
- writePersonalServerData
37953
+ writePersonalServerData,
37954
+ ...require("./errors.cjs")
37626
37955
  });
37627
37956
  //# sourceMappingURL=index.node.cjs.map