@opendatalabs/vana-sdk 3.22.0 → 3.23.0-pr.211.341f55d

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 (58) hide show
  1. package/dist/crypto/envelope/job.cjs +355 -0
  2. package/dist/crypto/envelope/job.cjs.map +1 -0
  3. package/dist/crypto/envelope/job.d.ts +123 -0
  4. package/dist/crypto/envelope/job.js +333 -0
  5. package/dist/crypto/envelope/job.js.map +1 -0
  6. package/dist/direct/access-request-client.cjs +4 -0
  7. package/dist/direct/access-request-client.cjs.map +1 -1
  8. package/dist/direct/access-request-client.js +4 -0
  9. package/dist/direct/access-request-client.js.map +1 -1
  10. package/dist/direct/connect-flow.cjs +43 -1
  11. package/dist/direct/connect-flow.cjs.map +1 -1
  12. package/dist/direct/connect-flow.d.ts +12 -0
  13. package/dist/direct/connect-flow.js +43 -1
  14. package/dist/direct/connect-flow.js.map +1 -1
  15. package/dist/direct/types.cjs.map +1 -1
  16. package/dist/direct/types.d.ts +7 -0
  17. package/dist/direct/types.js.map +1 -1
  18. package/dist/direct/use-direct-vana-connect.cjs +2 -1
  19. package/dist/direct/use-direct-vana-connect.cjs.map +1 -1
  20. package/dist/direct/use-direct-vana-connect.d.ts +3 -1
  21. package/dist/direct/use-direct-vana-connect.js +2 -1
  22. package/dist/direct/use-direct-vana-connect.js.map +1 -1
  23. package/dist/errors.cjs +84 -0
  24. package/dist/errors.cjs.map +1 -1
  25. package/dist/errors.d.ts +133 -0
  26. package/dist/errors.js +73 -0
  27. package/dist/errors.js.map +1 -1
  28. package/dist/index.browser.d.ts +3 -0
  29. package/dist/index.browser.js +631 -24
  30. package/dist/index.browser.js.map +4 -4
  31. package/dist/index.node.cjs +1259 -111
  32. package/dist/index.node.cjs.map +4 -4
  33. package/dist/index.node.d.ts +4 -0
  34. package/dist/index.node.js +1223 -101
  35. package/dist/index.node.js.map +4 -4
  36. package/dist/protocol/identity.cjs +219 -0
  37. package/dist/protocol/identity.cjs.map +1 -0
  38. package/dist/protocol/identity.d.ts +193 -0
  39. package/dist/protocol/identity.js +183 -0
  40. package/dist/protocol/identity.js.map +1 -0
  41. package/dist/protocol/identity.test.d.ts +1 -0
  42. package/dist/protocol/identity.vector.test.d.ts +1 -0
  43. package/dist/protocol/jobs-client.cjs +540 -0
  44. package/dist/protocol/jobs-client.cjs.map +1 -0
  45. package/dist/protocol/jobs-client.d.ts +169 -0
  46. package/dist/protocol/jobs-client.js +547 -0
  47. package/dist/protocol/jobs-client.js.map +1 -0
  48. package/dist/protocol/jobs-client.test.d.ts +1 -0
  49. package/dist/protocol/jobs.cjs +64 -0
  50. package/dist/protocol/jobs.cjs.map +1 -0
  51. package/dist/protocol/jobs.d.ts +193 -0
  52. package/dist/protocol/jobs.js +31 -0
  53. package/dist/protocol/jobs.js.map +1 -0
  54. package/dist/protocol/jobs.test.d.ts +1 -0
  55. package/dist/react.cjs.map +1 -1
  56. package/dist/react.d.ts +1 -1
  57. package/dist/react.js.map +1 -1
  58. package/package.json +7 -1
@@ -1347,6 +1347,68 @@ var WriteRejectedError = class extends PersonalServerWriteError {
1347
1347
  super(message, "WRITE_REJECTED", status, errorCode, details);
1348
1348
  }
1349
1349
  };
1350
+ var JobsClientError = class extends VanaError {
1351
+ constructor(message, code, status, errorCode = null, details) {
1352
+ super(message, code);
1353
+ this.status = status;
1354
+ this.errorCode = errorCode;
1355
+ this.details = details;
1356
+ }
1357
+ status;
1358
+ errorCode;
1359
+ details;
1360
+ };
1361
+ var BuilderUnknownError = class extends JobsClientError {
1362
+ constructor(message, details) {
1363
+ super(message, "JOB_BUILDER_UNKNOWN", 403, "BUILDER_UNKNOWN", details);
1364
+ }
1365
+ };
1366
+ var GrantInvalidError = class extends JobsClientError {
1367
+ constructor(message, details) {
1368
+ super(message, "JOB_GRANT_INVALID", 403, "GRANT_INVALID", details);
1369
+ }
1370
+ };
1371
+ var OwnerNotReadyError = class extends JobsClientError {
1372
+ constructor(message, details) {
1373
+ super(message, "JOB_OWNER_NOT_READY", 403, "OWNER_NOT_READY", details);
1374
+ }
1375
+ };
1376
+ var JobIdTakenError = class extends JobsClientError {
1377
+ constructor(message, details) {
1378
+ super(message, "JOB_ID_TAKEN", 409, "JOB_ID_TAKEN", details);
1379
+ }
1380
+ };
1381
+ var JobNotFoundError = class extends JobsClientError {
1382
+ constructor(message, details) {
1383
+ super(message, "JOB_NOT_FOUND", 404, "JOB_NOT_FOUND", details);
1384
+ }
1385
+ };
1386
+ var JobRequestTooLargeError = class extends JobsClientError {
1387
+ constructor(message, errorCode = "BODY_TOO_LARGE", details) {
1388
+ super(message, "JOB_REQUEST_TOO_LARGE", 413, errorCode, details);
1389
+ }
1390
+ };
1391
+ var JobTimeoutError = class extends JobsClientError {
1392
+ constructor(message, details) {
1393
+ super(message, "JOB_TIMEOUT", void 0, null, details);
1394
+ }
1395
+ };
1396
+ var JobResultIntegrityError = class extends JobsClientError {
1397
+ constructor(message, details) {
1398
+ super(message, "JOB_RESULT_INTEGRITY", void 0, null, details);
1399
+ }
1400
+ };
1401
+ var JobRejectedError = class extends JobsClientError {
1402
+ constructor(message, status, errorCode = null, details) {
1403
+ super(message, "JOB_REJECTED", status, errorCode, details);
1404
+ }
1405
+ };
1406
+ var JobTransportError = class extends JobsClientError {
1407
+ constructor(message, cause) {
1408
+ super(message, "JOB_TRANSPORT_ERROR");
1409
+ this.cause = cause;
1410
+ }
1411
+ };
1350
1412
  var LineageReadError = class extends VanaError {
1351
1413
  constructor(message, status, errorCode = null, details) {
1352
1414
  super(message, "LINEAGE_READ_ERROR");
@@ -31347,13 +31409,13 @@ var NodeCryptoAdapter = class {
31347
31409
  */
31348
31410
  async generateKeyPair() {
31349
31411
  try {
31350
- const secp256k14 = secp256k1Import2;
31412
+ const secp256k15 = secp256k1Import2;
31351
31413
  let privateKey;
31352
31414
  do {
31353
31415
  privateKey = randomBytes2(32);
31354
- } while (!secp256k14.privateKeyVerify(privateKey));
31416
+ } while (!secp256k15.privateKeyVerify(privateKey));
31355
31417
  const publicKey = Buffer.from(
31356
- secp256k14.publicKeyCreate(privateKey, true)
31418
+ secp256k15.publicKeyCreate(privateKey, true)
31357
31419
  );
31358
31420
  return {
31359
31421
  privateKey: privateKey.toString("hex"),
@@ -32363,9 +32425,1068 @@ var RECORD_DATA_ACCESS_TYPES = {
32363
32425
  ]
32364
32426
  };
32365
32427
 
32428
+ // src/protocol/identity.ts
32429
+ init_interface();
32430
+ import * as secp256k14 from "@noble/secp256k1";
32431
+ import {
32432
+ concat as concat4,
32433
+ encodePacked,
32434
+ fromHex as fromHex5,
32435
+ getAddress,
32436
+ isAddressEqual,
32437
+ keccak256,
32438
+ recoverPublicKey,
32439
+ toBytes,
32440
+ toHex as toHex7
32441
+ } from "viem";
32442
+ import { publicKeyToAddress } from "viem/accounts";
32443
+ var ENCLAVE_IDENTITY_EVIDENCE_VERSION = 1;
32444
+ var USER_PS_ID_DOMAIN = "vana.ps-enclave.v1";
32445
+ var ENCLAVE_WALLET_PURPOSE = "vana.ps-enclave.wallet.v1";
32446
+ var MASTER_SIGNATURE_DELIVERY_VERSION = "vana.ps-enclave.delivery.v1";
32447
+ var MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS = 600;
32448
+ var SEALED_ENVELOPE_VERSION = 1;
32449
+ var VANA_MAINNET_CHAIN_ID = 1480;
32450
+ var MOKSHA_CHAIN_ID = 14800;
32451
+ var KMS_ISSUED_PREFIX = "dstack-kms-issued";
32452
+ var PREIMAGE_SEPARATOR = ":";
32453
+ var UNCOMPRESSED_PUBLIC_KEY_BYTES = 65;
32454
+ var UNCOMPRESSED_PUBLIC_KEY_PREFIX = "04";
32455
+ var EMPTY_HEX = "0x";
32456
+ function emptyAnchor() {
32457
+ return Object.freeze({
32458
+ kmsRootPubkey: EMPTY_HEX,
32459
+ appIds: Object.freeze([])
32460
+ });
32461
+ }
32462
+ var ENCLAVE_TRUST_ANCHORS = Object.freeze({
32463
+ // filled at fleet provisioning; verify fails closed while empty
32464
+ [VANA_MAINNET_CHAIN_ID]: emptyAnchor(),
32465
+ // filled at fleet provisioning; verify fails closed while empty
32466
+ [MOKSHA_CHAIN_ID]: emptyAnchor()
32467
+ });
32468
+ function userPsId(chainId, ownerAddress) {
32469
+ const packed = encodePacked(
32470
+ ["string", "uint256", "address"],
32471
+ [USER_PS_ID_DOMAIN, BigInt(chainId), getAddress(ownerAddress)]
32472
+ );
32473
+ return keccak256(packed);
32474
+ }
32475
+ function compressPublicKey(publicKey) {
32476
+ return secp256k14.ProjectivePoint.fromHex(
32477
+ fromHex5(publicKey, "bytes")
32478
+ ).toRawBytes(true);
32479
+ }
32480
+ function sameKey(a, b) {
32481
+ return toHex7(compressPublicKey(a)) === toHex7(compressPublicKey(b));
32482
+ }
32483
+ function assertUncompressedKey(publicKey) {
32484
+ const hex = publicKey.slice(2);
32485
+ if (hex.length !== UNCOMPRESSED_PUBLIC_KEY_BYTES * 2 || !hex.startsWith(UNCOMPRESSED_PUBLIC_KEY_PREFIX) || !/^[0-9a-fA-F]+$/.test(hex)) {
32486
+ throw new Error("Public key must be a 65-byte uncompressed secp256k1 key");
32487
+ }
32488
+ }
32489
+ function appRootPreimage(purpose, publicKey) {
32490
+ const keyHex = toHex7(compressPublicKey(publicKey)).slice(2);
32491
+ return keccak256(toBytes(`${purpose}${PREIMAGE_SEPARATOR}${keyHex}`));
32492
+ }
32493
+ function kmsIssuedPreimage(appId, appRootPublicKey) {
32494
+ const prefix = concat4([
32495
+ toBytes(`${KMS_ISSUED_PREFIX}${PREIMAGE_SEPARATOR}`),
32496
+ fromHex5(appId, "bytes")
32497
+ ]);
32498
+ const compressed = compressPublicKey(appRootPublicKey);
32499
+ return keccak256(concat4([prefix, compressed]));
32500
+ }
32501
+ async function recoverChainKey(hash, signature, link) {
32502
+ try {
32503
+ return (await recoverPublicKey({ hash, signature })).toLowerCase();
32504
+ } catch {
32505
+ throw new Error(`Invalid enclave signature chain link ${link}`);
32506
+ }
32507
+ }
32508
+ async function verifyEnclaveIdentityEvidence(evidence, anchors, expected) {
32509
+ if (evidence.v !== ENCLAVE_IDENTITY_EVIDENCE_VERSION) {
32510
+ throw new Error("Unsupported enclave identity evidence version");
32511
+ }
32512
+ if (!Number.isInteger(evidence.epoch) || evidence.epoch < 1) {
32513
+ throw new Error("Invalid enclave identity epoch");
32514
+ }
32515
+ if (evidence.chainId !== expected.chainId) {
32516
+ throw new Error(
32517
+ "Enclave identity chain ID does not match expected chain ID"
32518
+ );
32519
+ }
32520
+ if (!isAddressEqual(evidence.ownerAddress, expected.ownerAddress)) {
32521
+ throw new Error("Enclave identity owner does not match expected owner");
32522
+ }
32523
+ if (evidence.epoch !== expected.epoch) {
32524
+ throw new Error("Enclave identity epoch does not match expected epoch");
32525
+ }
32526
+ const expectedUserPsId = userPsId(expected.chainId, expected.ownerAddress);
32527
+ if (evidence.userPsId.toLowerCase() !== expectedUserPsId.toLowerCase()) {
32528
+ throw new Error("Enclave userPsId does not match expected identity");
32529
+ }
32530
+ if (evidence.purpose !== ENCLAVE_WALLET_PURPOSE) {
32531
+ throw new Error("Unexpected enclave wallet purpose");
32532
+ }
32533
+ if (anchors.kmsRootPubkey === EMPTY_HEX) {
32534
+ throw new Error("KMS root trust anchor is not provisioned");
32535
+ }
32536
+ assertUncompressedKey(evidence.publicKey);
32537
+ const derivedAddress = publicKeyToAddress(evidence.publicKey);
32538
+ if (getAddress(derivedAddress) !== getAddress(evidence.address)) {
32539
+ throw new Error("Enclave public key does not match its address");
32540
+ }
32541
+ const appRootPublicKey = await recoverChainKey(
32542
+ appRootPreimage(evidence.purpose, evidence.publicKey),
32543
+ evidence.signatureChain[0],
32544
+ 0
32545
+ );
32546
+ const kmsRootPublicKey = await recoverChainKey(
32547
+ kmsIssuedPreimage(evidence.appId, appRootPublicKey),
32548
+ evidence.signatureChain[1],
32549
+ 1
32550
+ );
32551
+ let matchesAnchor;
32552
+ try {
32553
+ matchesAnchor = sameKey(kmsRootPublicKey, anchors.kmsRootPubkey);
32554
+ } catch {
32555
+ throw new Error("KMS root trust anchor is malformed");
32556
+ }
32557
+ if (!matchesAnchor) {
32558
+ throw new Error("KMS root public key does not match the trust anchor");
32559
+ }
32560
+ if (keccak256(kmsRootPublicKey) !== evidence.kmsRootFingerprint.toLowerCase()) {
32561
+ throw new Error("KMS root fingerprint does not match the evidence");
32562
+ }
32563
+ const appId = evidence.appId.toLowerCase();
32564
+ if (!anchors.appIds.some((allowedAppId) => allowedAppId.toLowerCase() === appId)) {
32565
+ throw new Error("Enclave app ID is not trusted");
32566
+ }
32567
+ }
32568
+ async function buildMasterSignatureDelivery(evidence, masterSignature, now = Math.floor(Date.now() / 1e3)) {
32569
+ deriveMasterKey(masterSignature);
32570
+ const signerAddress = await recoverServerOwner(masterSignature);
32571
+ if (!isAddressEqual(signerAddress, evidence.ownerAddress)) {
32572
+ throw new Error("Master signature signer does not match evidence owner");
32573
+ }
32574
+ return {
32575
+ v: MASTER_SIGNATURE_DELIVERY_VERSION,
32576
+ userPsId: evidence.userPsId,
32577
+ epoch: evidence.epoch,
32578
+ enclaveAddress: evidence.address,
32579
+ ownerAddress: evidence.ownerAddress,
32580
+ masterSignature,
32581
+ issuedAt: now
32582
+ };
32583
+ }
32584
+ async function encryptMasterSignatureDelivery(delivery, publicKey, ecies) {
32585
+ assertUncompressedKey(publicKey);
32586
+ if (!isAddressEqual(publicKeyToAddress(publicKey), delivery.enclaveAddress)) {
32587
+ throw new Error(
32588
+ "Public key does not belong to the delivery's enclave address"
32589
+ );
32590
+ }
32591
+ const plaintext = toBytes(JSON.stringify(delivery));
32592
+ const encrypted = await ecies.encrypt(fromHex5(publicKey, "bytes"), plaintext);
32593
+ return `0x${serializeECIES(encrypted)}`;
32594
+ }
32595
+
32596
+ // src/protocol/jobs.ts
32597
+ var JOB_PROTOCOL_VERSION = 1;
32598
+ var JOB_OPERATIONS = ["raw_read", "inference"];
32599
+ var JOB_STATES = [
32600
+ "queued",
32601
+ "claimed",
32602
+ "running",
32603
+ "completed",
32604
+ "failed",
32605
+ "expired",
32606
+ "cancelled"
32607
+ ];
32608
+ var DEFAULT_LEASE_SECONDS = 30;
32609
+ var MAX_LEASE_SECONDS = 300;
32610
+ var MAX_ATTEMPTS = 3;
32611
+ var MAX_WAIT_SECONDS = 25;
32612
+ var CLAIM_POLL_FLOOR_MS = 1e3;
32613
+ var DEFAULT_JOB_DEADLINE_SECONDS = 600;
32614
+ var MAX_JOB_DEADLINE_SECONDS = 3600;
32615
+
32616
+ // src/protocol/jobs-client.ts
32617
+ import { randomUUID } from "node:crypto";
32618
+ import { sha256 as sha2566 } from "@noble/hashes/sha2";
32619
+ import {
32620
+ bytesToHex as bytesToHex3,
32621
+ isAddress as isAddress2,
32622
+ isAddressEqual as isAddressEqual2,
32623
+ isHex as isHex2
32624
+ } from "viem";
32625
+ import { privateKeyToAccount, publicKeyToAddress as publicKeyToAddress2 } from "viem/accounts";
32626
+
32627
+ // src/crypto/envelope/job.ts
32628
+ init_constants();
32629
+ init_interface();
32630
+ import { sha256 as sha2565 } from "@noble/hashes/sha2";
32631
+ import { bytesToHex as bytesToHex2, fromHex as fromHex6, isAddress, isHex, toHex as toHex8 } from "viem";
32632
+ var textDecoder = new TextDecoder();
32633
+ var textEncoder = new TextEncoder();
32634
+ var MAX_JOB_RESULT_HEADER_BYTES = 4096;
32635
+ var JOB_RESULT_LENGTH_PREFIX_BYTES = 4;
32636
+ var JobEnvelopeError = class extends Error {
32637
+ constructor(message) {
32638
+ super(message);
32639
+ this.name = "JobEnvelopeError";
32640
+ }
32641
+ };
32642
+ function sortJsonKeys(value) {
32643
+ if (Array.isArray(value)) {
32644
+ return value.map(sortJsonKeys);
32645
+ }
32646
+ if (value !== null && typeof value === "object") {
32647
+ return Object.fromEntries(
32648
+ Object.keys(value).sort().map((key) => [
32649
+ key,
32650
+ sortJsonKeys(value[key])
32651
+ ])
32652
+ );
32653
+ }
32654
+ return value;
32655
+ }
32656
+ function canonicalJsonBytes(value) {
32657
+ return textEncoder.encode(JSON.stringify(sortJsonKeys(value)));
32658
+ }
32659
+ function canonicalJobRequestBytes(request) {
32660
+ validateJobRequest(request);
32661
+ return canonicalJsonBytes(request);
32662
+ }
32663
+ function requestPlaintext(envelope) {
32664
+ validateRequestEnvelope(envelope);
32665
+ return canonicalJsonBytes(envelope);
32666
+ }
32667
+ function resultPlaintext(result) {
32668
+ const header = textEncoder.encode(
32669
+ JSON.stringify({
32670
+ v: result.v,
32671
+ jobId: result.jobId,
32672
+ scope: result.scope,
32673
+ version: result.version,
32674
+ contentType: result.contentType
32675
+ })
32676
+ );
32677
+ if (header.length > MAX_JOB_RESULT_HEADER_BYTES) {
32678
+ throw new JobEnvelopeError(
32679
+ `Invalid job result: header exceeds ${MAX_JOB_RESULT_HEADER_BYTES} bytes`
32680
+ );
32681
+ }
32682
+ const plaintext = new Uint8Array(
32683
+ JOB_RESULT_LENGTH_PREFIX_BYTES + header.length + result.body.length
32684
+ );
32685
+ new DataView(plaintext.buffer).setUint32(0, header.length);
32686
+ plaintext.set(header, JOB_RESULT_LENGTH_PREFIX_BYTES);
32687
+ plaintext.set(result.body, JOB_RESULT_LENGTH_PREFIX_BYTES + header.length);
32688
+ return plaintext;
32689
+ }
32690
+ function parseResultPlaintext(plaintext) {
32691
+ if (plaintext.length < JOB_RESULT_LENGTH_PREFIX_BYTES) {
32692
+ throw new JobEnvelopeError(
32693
+ "Invalid job result: missing header length prefix"
32694
+ );
32695
+ }
32696
+ const headerLength = new DataView(
32697
+ plaintext.buffer,
32698
+ plaintext.byteOffset,
32699
+ JOB_RESULT_LENGTH_PREFIX_BYTES
32700
+ ).getUint32(0);
32701
+ if (headerLength > MAX_JOB_RESULT_HEADER_BYTES) {
32702
+ throw new JobEnvelopeError(
32703
+ `Invalid job result: header exceeds ${MAX_JOB_RESULT_HEADER_BYTES} bytes`
32704
+ );
32705
+ }
32706
+ const remainingLength = plaintext.length - JOB_RESULT_LENGTH_PREFIX_BYTES;
32707
+ if (headerLength > remainingLength) {
32708
+ throw new JobEnvelopeError(
32709
+ "Invalid job result: header length exceeds payload"
32710
+ );
32711
+ }
32712
+ const headerEnd = JOB_RESULT_LENGTH_PREFIX_BYTES + headerLength;
32713
+ const header = parseObject(
32714
+ plaintext.subarray(JOB_RESULT_LENGTH_PREFIX_BYTES, headerEnd),
32715
+ "job result header"
32716
+ );
32717
+ return validateResult({ ...header, body: plaintext.subarray(headerEnd) });
32718
+ }
32719
+ function encryptedBytesToBase64(encrypted) {
32720
+ return toBase64(fromHex6(`0x${serializeECIES(encrypted)}`, "bytes"));
32721
+ }
32722
+ function encryptedToBytes(encrypted) {
32723
+ const bytes = new Uint8Array(
32724
+ encrypted.iv.length + encrypted.ephemPublicKey.length + encrypted.ciphertext.length + encrypted.mac.length
32725
+ );
32726
+ let offset = 0;
32727
+ bytes.set(encrypted.iv, offset);
32728
+ offset += encrypted.iv.length;
32729
+ bytes.set(encrypted.ephemPublicKey, offset);
32730
+ offset += encrypted.ephemPublicKey.length;
32731
+ bytes.set(encrypted.ciphertext, offset);
32732
+ offset += encrypted.ciphertext.length;
32733
+ bytes.set(encrypted.mac, offset);
32734
+ return bytes;
32735
+ }
32736
+ function bytesToEncrypted(bytes) {
32737
+ const absoluteMinLength = FORMAT.IV_LENGTH + 1 + MAC.LENGTH + 1;
32738
+ if (bytes.length < absoluteMinLength) {
32739
+ throw new ECIESError(
32740
+ `Invalid ECIES data: too short (${bytes.length} bytes, minimum ${absoluteMinLength} bytes required)`,
32741
+ "DECRYPTION_FAILED"
32742
+ );
32743
+ }
32744
+ const prefix = bytes[FORMAT.EPHEMERAL_KEY_OFFSET];
32745
+ if (prefix !== CURVE.PREFIX.UNCOMPRESSED) {
32746
+ throw new ECIESError(
32747
+ `Invalid ephemeral public key: must be uncompressed format (0x04 prefix), got 0x${prefix.toString(16).padStart(2, "0")}`,
32748
+ "DECRYPTION_FAILED"
32749
+ );
32750
+ }
32751
+ const ephemKeySize = CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH;
32752
+ const minLength = FORMAT.IV_LENGTH + ephemKeySize + MAC.LENGTH + 1;
32753
+ if (bytes.length < minLength) {
32754
+ throw new ECIESError(
32755
+ `Invalid ECIES data: too short (${bytes.length} bytes, minimum ${minLength} bytes required)`,
32756
+ "DECRYPTION_FAILED"
32757
+ );
32758
+ }
32759
+ return {
32760
+ iv: bytes.subarray(FORMAT.IV_OFFSET, FORMAT.IV_OFFSET + FORMAT.IV_LENGTH),
32761
+ ephemPublicKey: bytes.subarray(
32762
+ FORMAT.EPHEMERAL_KEY_OFFSET,
32763
+ FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize
32764
+ ),
32765
+ ciphertext: bytes.subarray(
32766
+ FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize,
32767
+ bytes.length - MAC.LENGTH
32768
+ ),
32769
+ mac: bytes.subarray(bytes.length - MAC.LENGTH)
32770
+ };
32771
+ }
32772
+ function base64ToEncrypted(ciphertext) {
32773
+ return deserializeECIES(toHex8(fromBase64(ciphertext)));
32774
+ }
32775
+ function parseObject(plaintext, kind) {
32776
+ try {
32777
+ const value = JSON.parse(textDecoder.decode(plaintext));
32778
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
32779
+ throw new JobEnvelopeError(`Invalid ${kind}: expected an object`);
32780
+ }
32781
+ return value;
32782
+ } catch (error) {
32783
+ if (error instanceof JobEnvelopeError) throw error;
32784
+ throw new JobEnvelopeError(`Invalid ${kind}: malformed JSON`);
32785
+ }
32786
+ }
32787
+ function isPlainObject2(value) {
32788
+ if (value === null || typeof value !== "object") return false;
32789
+ const prototype = Object.getPrototypeOf(value);
32790
+ return prototype === Object.prototype || prototype === null;
32791
+ }
32792
+ function requirePlainObject(value, field, kind) {
32793
+ if (!isPlainObject2(value)) {
32794
+ throw new JobEnvelopeError(`Invalid ${kind}: invalid ${field}`);
32795
+ }
32796
+ }
32797
+ function requireExactKeys(value, expectedKeys, kind) {
32798
+ for (const key of expectedKeys) {
32799
+ if (!Object.hasOwn(value, key) || value[key] === void 0) {
32800
+ throw new JobEnvelopeError(`Invalid ${kind}: missing ${key}`);
32801
+ }
32802
+ }
32803
+ const expected = new Set(expectedKeys);
32804
+ for (const key of Reflect.ownKeys(value)) {
32805
+ if (!expected.has(key)) {
32806
+ throw new JobEnvelopeError(
32807
+ `Invalid ${kind}: unknown field ${String(key)}`
32808
+ );
32809
+ }
32810
+ }
32811
+ }
32812
+ function requireString(value, field, kind) {
32813
+ if (typeof value !== "string" || value.length === 0) {
32814
+ throw new JobEnvelopeError(`Invalid ${kind}: missing ${field}`);
32815
+ }
32816
+ }
32817
+ function validateJobRequest(value) {
32818
+ requirePlainObject(value, "request", "job request");
32819
+ requireExactKeys(
32820
+ value,
32821
+ [
32822
+ "v",
32823
+ "jobId",
32824
+ "owner",
32825
+ "builder",
32826
+ "builderPublicKey",
32827
+ "grantId",
32828
+ "scope",
32829
+ "operation",
32830
+ "pinnedVersion",
32831
+ "deadline"
32832
+ ],
32833
+ "job request"
32834
+ );
32835
+ if (value.v !== JOB_PROTOCOL_VERSION) {
32836
+ throw new JobEnvelopeError(
32837
+ `Unsupported job request version: ${String(value.v)}`
32838
+ );
32839
+ }
32840
+ requireString(value.jobId, "jobId", "job request");
32841
+ if (typeof value.owner !== "string" || !isAddress(value.owner)) {
32842
+ throw new JobEnvelopeError("Invalid job request: invalid owner");
32843
+ }
32844
+ if (typeof value.builder !== "string" || !isAddress(value.builder)) {
32845
+ throw new JobEnvelopeError("Invalid job request: invalid builder");
32846
+ }
32847
+ if (typeof value.builderPublicKey !== "string" || !isHex(value.builderPublicKey)) {
32848
+ throw new JobEnvelopeError("Invalid job request: invalid builderPublicKey");
32849
+ }
32850
+ if (typeof value.grantId !== "string" || !isHex(value.grantId)) {
32851
+ throw new JobEnvelopeError("Invalid job request: invalid grantId");
32852
+ }
32853
+ requireString(value.scope, "scope", "job request");
32854
+ if (!JOB_OPERATIONS.includes(value.operation)) {
32855
+ throw new JobEnvelopeError("Invalid job request: invalid operation");
32856
+ }
32857
+ if (value.pinnedVersion !== null && typeof value.pinnedVersion !== "string") {
32858
+ throw new JobEnvelopeError("Invalid job request: missing pinnedVersion");
32859
+ }
32860
+ if (typeof value.deadline !== "string" || !Number.isFinite(Date.parse(value.deadline))) {
32861
+ throw new JobEnvelopeError("Invalid job request: invalid deadline");
32862
+ }
32863
+ return value;
32864
+ }
32865
+ function validateRequestEnvelope(value) {
32866
+ requirePlainObject(value, "envelope", "job request envelope");
32867
+ requireExactKeys(value, ["request", "auth"], "job request envelope");
32868
+ validateJobRequest(value.request);
32869
+ requireString(value.auth, "auth", "job request envelope");
32870
+ return value;
32871
+ }
32872
+ function validateResult(value) {
32873
+ requirePlainObject(value, "result", "job result");
32874
+ requireExactKeys(
32875
+ value,
32876
+ ["v", "jobId", "scope", "version", "contentType", "body"],
32877
+ "job result"
32878
+ );
32879
+ if (value.v !== JOB_PROTOCOL_VERSION) {
32880
+ throw new JobEnvelopeError(
32881
+ `Unsupported job result version: ${String(value.v)}`
32882
+ );
32883
+ }
32884
+ for (const field of ["jobId", "scope", "contentType"]) {
32885
+ requireString(value[field], field, "job result");
32886
+ }
32887
+ if (!(value.body instanceof Uint8Array)) {
32888
+ throw new JobEnvelopeError("Invalid job result: missing body");
32889
+ }
32890
+ if (value.version !== null && typeof value.version !== "string") {
32891
+ throw new JobEnvelopeError("Invalid job result: missing version");
32892
+ }
32893
+ return value;
32894
+ }
32895
+ async function sealJobRequest(envelope, enclavePublicKey, ecies) {
32896
+ const encrypted = await ecies.encrypt(
32897
+ fromHex6(enclavePublicKey, "bytes"),
32898
+ requestPlaintext(envelope)
32899
+ );
32900
+ return encryptedBytesToBase64(encrypted);
32901
+ }
32902
+ async function openJobRequest(ciphertext, privateKey, ecies) {
32903
+ const plaintext = await ecies.decrypt(
32904
+ privateKey,
32905
+ base64ToEncrypted(ciphertext)
32906
+ );
32907
+ return validateRequestEnvelope(
32908
+ parseObject(plaintext, "job request envelope")
32909
+ );
32910
+ }
32911
+ async function sealJobResult(result, builderPublicKey, ecies) {
32912
+ validateResult(result);
32913
+ const encrypted = await ecies.encrypt(
32914
+ fromHex6(builderPublicKey, "bytes"),
32915
+ resultPlaintext(result)
32916
+ );
32917
+ const bytes = encryptedToBytes(encrypted);
32918
+ return { bytes, hash: bytesToHex2(sha2565(bytes)), size: bytes.length };
32919
+ }
32920
+ async function openJobResult(sealedBytes, builderPrivateKey, ecies, expect) {
32921
+ const plaintext = await ecies.decrypt(
32922
+ fromHex6(builderPrivateKey, "bytes"),
32923
+ bytesToEncrypted(sealedBytes)
32924
+ );
32925
+ const result = parseResultPlaintext(plaintext);
32926
+ if (result.jobId !== expect.jobId) {
32927
+ throw new JobEnvelopeError(
32928
+ `Job result ID ${result.jobId} does not match expected job ID ${expect.jobId}`
32929
+ );
32930
+ }
32931
+ if (expect.scope !== void 0 && result.scope !== expect.scope) {
32932
+ throw new JobEnvelopeError(
32933
+ `Job result scope ${result.scope} does not match expected scope ${expect.scope}`
32934
+ );
32935
+ }
32936
+ if (expect.version !== void 0 && result.version !== expect.version) {
32937
+ throw new JobEnvelopeError(
32938
+ `Job result version ${String(result.version)} does not match expected version ${String(expect.version)}`
32939
+ );
32940
+ }
32941
+ return result;
32942
+ }
32943
+
32944
+ // src/protocol/write-signer.ts
32945
+ function isRecord(value) {
32946
+ return value !== null && typeof value === "object";
32947
+ }
32948
+ function isViemWriteAccount(source) {
32949
+ return isRecord(source) && source.type === "local" && typeof source.address === "string" && typeof source.signMessage === "function";
32950
+ }
32951
+ function isViemWriteWalletClient(source) {
32952
+ return isRecord(source) && typeof source.signMessage === "function" && source.type !== "local" && (source.type === "walletClient" || "transport" in source);
32953
+ }
32954
+ function accountAddress(account) {
32955
+ return typeof account === "string" ? account : account.address;
32956
+ }
32957
+ function resolveWriteSigner(source, options = {}) {
32958
+ if (isViemWriteWalletClient(source)) {
32959
+ const account = options.account ?? source.account;
32960
+ if (account === void 0) {
32961
+ throw new WriteRequestError(
32962
+ "Viem wallet client requires an account option or account property"
32963
+ );
32964
+ }
32965
+ return {
32966
+ address: accountAddress(account),
32967
+ signMessage: (message) => source.signMessage({ account, message })
32968
+ };
32969
+ }
32970
+ if (isViemWriteAccount(source)) {
32971
+ return {
32972
+ address: source.address,
32973
+ signMessage: (message) => source.signMessage({ message })
32974
+ };
32975
+ }
32976
+ if (!isRecord(source) || typeof source.signMessage !== "function") {
32977
+ throw new WriteRequestError(
32978
+ "signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
32979
+ );
32980
+ }
32981
+ return source;
32982
+ }
32983
+
32984
+ // src/protocol/jobs-client.ts
32985
+ var IDENTITY_PATH = "/v1/identity";
32986
+ var JOBS_PATH = "/v1/jobs";
32987
+ var JOB_EXECUTE_PATH = "/v1/jobs/execute";
32988
+ var AUTHORIZATION_HEADER = "Authorization";
32989
+ var CONTENT_TYPE_HEADER = "Content-Type";
32990
+ var JSON_CONTENT_TYPE = "application/json";
32991
+ var GET_METHOD = "GET";
32992
+ var POST_METHOD = "POST";
32993
+ var RAW_READ_OPERATION = "raw_read";
32994
+ var SEALED_IDENTITY_STATE = "sealed";
32995
+ var HTTP_OK = 200;
32996
+ var HTTP_ACCEPTED = 202;
32997
+ var HTTP_UNAUTHORIZED = 401;
32998
+ var HTTP_FORBIDDEN = 403;
32999
+ var HTTP_NOT_FOUND = 404;
33000
+ var HTTP_CONFLICT = 409;
33001
+ var HTTP_PAYLOAD_TOO_LARGE = 413;
33002
+ var MILLISECONDS_PER_SECOND = 1e3;
33003
+ var DEFAULT_JOB_TIMEOUT_MS = 12e4;
33004
+ var DEFAULT_JOB_POLL_MS = CLAIM_POLL_FLOOR_MS;
33005
+ var TERMINAL_JOB_STATES = /* @__PURE__ */ new Set([
33006
+ "completed",
33007
+ "failed",
33008
+ "expired",
33009
+ "cancelled"
33010
+ ]);
33011
+ function isRecord2(value) {
33012
+ return value !== null && typeof value === "object" && !Array.isArray(value);
33013
+ }
33014
+ function normalizeGateway(gatewayUrl) {
33015
+ try {
33016
+ const url = new URL(gatewayUrl);
33017
+ if (url.pathname !== "/" || url.search !== "" || url.hash !== "") {
33018
+ throw new JobRejectedError(
33019
+ "gatewayUrl must be an origin without a path, query, or fragment"
33020
+ );
33021
+ }
33022
+ return {
33023
+ baseUrl: url.origin,
33024
+ audience: url.origin
33025
+ };
33026
+ } catch (error) {
33027
+ if (error instanceof JobRejectedError) throw error;
33028
+ throw new JobRejectedError(
33029
+ "gatewayUrl must be an absolute URL",
33030
+ void 0,
33031
+ null,
33032
+ {
33033
+ cause: error instanceof Error ? error.message : String(error)
33034
+ }
33035
+ );
33036
+ }
33037
+ }
33038
+ function resolveFetch(fetchFn) {
33039
+ const resolved = fetchFn ?? globalThis.fetch;
33040
+ if (resolved === void 0) {
33041
+ throw new JobRejectedError("No fetch implementation available");
33042
+ }
33043
+ return resolved;
33044
+ }
33045
+ function sourcePublicKey(source) {
33046
+ if (isRecord2(source) && typeof source["publicKey"] === "string") {
33047
+ return source["publicKey"];
33048
+ }
33049
+ return void 0;
33050
+ }
33051
+ function resolveBuilder(options) {
33052
+ if (options.builderPrivateKey && options.builderAccount) {
33053
+ throw new JobRejectedError(
33054
+ "Provide builderPrivateKey or builderAccount, not both"
33055
+ );
33056
+ }
33057
+ let source;
33058
+ try {
33059
+ source = options.builderPrivateKey ? privateKeyToAccount(options.builderPrivateKey) : options.builderAccount;
33060
+ } catch (error) {
33061
+ throw new JobRejectedError("Invalid builder private key", void 0, null, {
33062
+ cause: error instanceof Error ? error.message : String(error)
33063
+ });
33064
+ }
33065
+ if (!source) {
33066
+ throw new JobRejectedError(
33067
+ "builderPrivateKey or builderAccount is required"
33068
+ );
33069
+ }
33070
+ let signer;
33071
+ try {
33072
+ signer = resolveWriteSigner(source);
33073
+ } catch (error) {
33074
+ throw new JobRejectedError("Invalid builder signer", void 0, null, {
33075
+ cause: error instanceof Error ? error.message : String(error)
33076
+ });
33077
+ }
33078
+ const publicKey = sourcePublicKey(source);
33079
+ if (!signer.address || !publicKey) {
33080
+ throw new JobRejectedError(
33081
+ "Builder signer must expose both address and publicKey"
33082
+ );
33083
+ }
33084
+ return {
33085
+ builder: {
33086
+ address: signer.address,
33087
+ publicKey,
33088
+ signMessage: signer.signMessage
33089
+ },
33090
+ ...options.builderPrivateKey ? { privateKey: options.builderPrivateKey } : {}
33091
+ };
33092
+ }
33093
+ function clampInteger(value, fallback, minimum, maximum, field) {
33094
+ const resolved = value ?? fallback;
33095
+ if (!Number.isFinite(resolved)) {
33096
+ throw new JobRejectedError(`${field} must be a finite number`);
33097
+ }
33098
+ return Math.min(maximum, Math.max(minimum, Math.trunc(resolved)));
33099
+ }
33100
+ async function responseBody(response) {
33101
+ try {
33102
+ return await response.json();
33103
+ } catch {
33104
+ return null;
33105
+ }
33106
+ }
33107
+ function gatewayErrorBody(body, fallback) {
33108
+ if (!isRecord2(body)) return { code: null, message: fallback };
33109
+ const code = typeof body["code"] === "string" ? body["code"] : null;
33110
+ const message = typeof body["error"] === "string" ? body["error"] : typeof body["message"] === "string" ? body["message"] : fallback;
33111
+ const reason = typeof body["reason"] === "string" ? body["reason"] : void 0;
33112
+ const details = isRecord2(body["details"]) ? body["details"] : void 0;
33113
+ return {
33114
+ code,
33115
+ message,
33116
+ ...reason ? { reason } : {},
33117
+ ...details ? { details } : {}
33118
+ };
33119
+ }
33120
+ async function rejectedResponse(response, fallback) {
33121
+ const parsed = gatewayErrorBody(await responseBody(response), fallback);
33122
+ const details = response.status === HTTP_UNAUTHORIZED && parsed.reason ? { ...parsed.details, reason: parsed.reason } : parsed.details;
33123
+ const message = response.status === HTTP_UNAUTHORIZED && parsed.reason ? `${parsed.message}: ${parsed.reason}` : parsed.message;
33124
+ if (response.status === HTTP_FORBIDDEN) {
33125
+ if (parsed.code === "BUILDER_UNKNOWN") {
33126
+ return new BuilderUnknownError(parsed.message, details);
33127
+ }
33128
+ if (parsed.code === "GRANT_INVALID") {
33129
+ return new GrantInvalidError(parsed.message, details);
33130
+ }
33131
+ if (parsed.code === "OWNER_NOT_READY") {
33132
+ return new OwnerNotReadyError(parsed.message, details);
33133
+ }
33134
+ }
33135
+ if (response.status === HTTP_NOT_FOUND) {
33136
+ return new JobNotFoundError(parsed.message, details);
33137
+ }
33138
+ if (response.status === HTTP_CONFLICT && parsed.code === "JOB_ID_TAKEN") {
33139
+ return new JobIdTakenError(parsed.message, details);
33140
+ }
33141
+ if (response.status === HTTP_PAYLOAD_TOO_LARGE) {
33142
+ return new JobRequestTooLargeError(parsed.message, parsed.code, details);
33143
+ }
33144
+ return new JobRejectedError(message, response.status, parsed.code, details);
33145
+ }
33146
+ function requireStatus(value, status) {
33147
+ 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"])) {
33148
+ throw new JobRejectedError(
33149
+ "Gateway response did not contain a job status",
33150
+ status
33151
+ );
33152
+ }
33153
+ return value;
33154
+ }
33155
+ function isNonEmptyString(value) {
33156
+ return typeof value === "string" && value.length > 0;
33157
+ }
33158
+ function hasMatchingIdentityKey(value) {
33159
+ const address = value["address"];
33160
+ const publicKey = value["publicKey"];
33161
+ if (typeof address !== "string" || !isAddress2(address) || typeof publicKey !== "string" || !isHex2(publicKey)) {
33162
+ return false;
33163
+ }
33164
+ try {
33165
+ return publicKeyToAddress2(publicKey).toLowerCase() === address.toLowerCase();
33166
+ } catch {
33167
+ return false;
33168
+ }
33169
+ }
33170
+ function hasExpectedIdentity(value, owner, chainId) {
33171
+ const identityOwner = value["ownerAddress"];
33172
+ const identityChainId = value["chainId"];
33173
+ const identityUserPsId = value["userPsId"];
33174
+ if (!hasMatchingIdentityKey(value) || typeof identityOwner !== "string" || !isAddress2(identityOwner) || typeof identityChainId !== "number" || typeof identityUserPsId !== "string" || !isHex2(identityUserPsId)) {
33175
+ return false;
33176
+ }
33177
+ return isAddressEqual2(identityOwner, owner) && identityChainId === chainId && identityUserPsId.toLowerCase() === userPsId(chainId, owner).toLowerCase();
33178
+ }
33179
+ function sleep2(ms) {
33180
+ return new Promise((resolve) => setTimeout(resolve, ms));
33181
+ }
33182
+ function requireFiniteDuration(value, field) {
33183
+ if (!Number.isFinite(value)) {
33184
+ throw new JobRejectedError(`${field} must be a finite number`);
33185
+ }
33186
+ return Math.max(0, value);
33187
+ }
33188
+ function createJobsClient(options) {
33189
+ const { baseUrl, audience } = normalizeGateway(options.gatewayUrl);
33190
+ const fetchFn = resolveFetch(options.fetch);
33191
+ const { builder, privateKey } = resolveBuilder(options);
33192
+ const ecies = options.ecies ?? new NodeECIESUint8Provider();
33193
+ const now = options.now ?? (() => /* @__PURE__ */ new Date());
33194
+ async function request(url, init, description) {
33195
+ try {
33196
+ return await fetchFn(url, init);
33197
+ } catch (error) {
33198
+ throw new JobTransportError(
33199
+ `${description} failed: ${error instanceof Error ? error.message : String(error)}`,
33200
+ error
33201
+ );
33202
+ }
33203
+ }
33204
+ async function getIdentity(owner) {
33205
+ const query = new URLSearchParams({
33206
+ owner,
33207
+ chainId: String(options.chainId)
33208
+ });
33209
+ const response = await request(
33210
+ `${baseUrl}${IDENTITY_PATH}?${query.toString()}`,
33211
+ { method: GET_METHOD },
33212
+ "Owner identity lookup"
33213
+ );
33214
+ if (response.status === HTTP_NOT_FOUND) {
33215
+ const parsed = gatewayErrorBody(
33216
+ await responseBody(response),
33217
+ "Owner identity not found"
33218
+ );
33219
+ throw new OwnerNotReadyError(parsed.message, parsed.details);
33220
+ }
33221
+ if (!response.ok) {
33222
+ throw await rejectedResponse(response, "Owner identity lookup rejected");
33223
+ }
33224
+ const body = await responseBody(response);
33225
+ if (!isRecord2(body) || body["state"] !== SEALED_IDENTITY_STATE || !isRecord2(body["identity"])) {
33226
+ throw new OwnerNotReadyError("Owner identity is not sealed", {
33227
+ state: isRecord2(body) ? body["state"] : void 0
33228
+ });
33229
+ }
33230
+ if (!hasExpectedIdentity(body["identity"], owner, options.chainId)) {
33231
+ throw new JobRejectedError(
33232
+ "Gateway returned a malformed or mismatched owner identity",
33233
+ response.status
33234
+ );
33235
+ }
33236
+ return body["identity"];
33237
+ }
33238
+ const client = {
33239
+ async submitRawRead(params) {
33240
+ const identity = await getIdentity(params.owner);
33241
+ const deadlineSeconds = clampInteger(
33242
+ params.deadlineSeconds,
33243
+ DEFAULT_JOB_DEADLINE_SECONDS,
33244
+ 1,
33245
+ MAX_JOB_DEADLINE_SECONDS,
33246
+ "deadlineSeconds"
33247
+ );
33248
+ const wait = clampInteger(params.wait, 0, 0, MAX_WAIT_SECONDS, "wait");
33249
+ const jobId = randomUUID();
33250
+ const nowMs = now().getTime();
33251
+ if (!Number.isFinite(nowMs)) {
33252
+ throw new JobRejectedError("now must return a valid Date");
33253
+ }
33254
+ const deadline = new Date(
33255
+ nowMs + deadlineSeconds * MILLISECONDS_PER_SECOND
33256
+ ).toISOString();
33257
+ const requestBody = {
33258
+ v: JOB_PROTOCOL_VERSION,
33259
+ jobId,
33260
+ owner: params.owner,
33261
+ builder: builder.address,
33262
+ builderPublicKey: builder.publicKey,
33263
+ grantId: params.grantId,
33264
+ scope: params.scope,
33265
+ operation: RAW_READ_OPERATION,
33266
+ pinnedVersion: params.pinnedVersion ?? null,
33267
+ deadline
33268
+ };
33269
+ const auth = await buildWeb3SignedHeader({
33270
+ signMessage: builder.signMessage,
33271
+ aud: audience,
33272
+ method: POST_METHOD,
33273
+ uri: JOB_EXECUTE_PATH,
33274
+ bodyHash: computeBodyHash(canonicalJobRequestBytes(requestBody)),
33275
+ nonce: randomUUID()
33276
+ });
33277
+ const requestCiphertext = await sealJobRequest(
33278
+ { request: requestBody, auth },
33279
+ identity.publicKey,
33280
+ ecies
33281
+ );
33282
+ const submission = {
33283
+ owner: requestBody.owner,
33284
+ grantId: requestBody.grantId,
33285
+ scope: requestBody.scope,
33286
+ operation: requestBody.operation,
33287
+ idempotencyKey: randomUUID(),
33288
+ jobId,
33289
+ deadline,
33290
+ requestCiphertext
33291
+ };
33292
+ const bodyBytes = new TextEncoder().encode(JSON.stringify(submission));
33293
+ const authorization = await buildWeb3SignedHeader({
33294
+ signMessage: builder.signMessage,
33295
+ aud: audience,
33296
+ method: POST_METHOD,
33297
+ uri: JOBS_PATH,
33298
+ body: bodyBytes,
33299
+ nonce: randomUUID()
33300
+ });
33301
+ const response = await request(
33302
+ `${baseUrl}${JOBS_PATH}?wait=${wait}`,
33303
+ {
33304
+ method: POST_METHOD,
33305
+ headers: {
33306
+ [AUTHORIZATION_HEADER]: authorization,
33307
+ [CONTENT_TYPE_HEADER]: JSON_CONTENT_TYPE
33308
+ },
33309
+ body: bodyBytes
33310
+ },
33311
+ "Job submission"
33312
+ );
33313
+ if (!response.ok) {
33314
+ throw await rejectedResponse(response, "Job submission rejected");
33315
+ }
33316
+ const body = await responseBody(response);
33317
+ if (response.status === HTTP_OK && isRecord2(body)) {
33318
+ const job = requireStatus(body["job"], response.status);
33319
+ if (job.jobId !== jobId) {
33320
+ throw new JobRejectedError(
33321
+ "Gateway returned a job id that does not match the submission",
33322
+ response.status
33323
+ );
33324
+ }
33325
+ return { jobId, state: job.state, job };
33326
+ }
33327
+ if (response.status === HTTP_ACCEPTED && isRecord2(body) && body["jobId"] === jobId && typeof body["state"] === "string" && JOB_STATES.includes(body["state"])) {
33328
+ return { jobId, state: body["state"] };
33329
+ }
33330
+ throw new JobRejectedError(
33331
+ "Gateway returned an undocumented job submission response",
33332
+ response.status
33333
+ );
33334
+ },
33335
+ async getJob(jobId) {
33336
+ const path = `${JOBS_PATH}/${encodeURIComponent(jobId)}`;
33337
+ const authorization = await buildWeb3SignedHeader({
33338
+ signMessage: builder.signMessage,
33339
+ aud: audience,
33340
+ method: GET_METHOD,
33341
+ uri: path,
33342
+ nonce: randomUUID()
33343
+ });
33344
+ const response = await request(
33345
+ `${baseUrl}${path}`,
33346
+ {
33347
+ method: GET_METHOD,
33348
+ headers: { [AUTHORIZATION_HEADER]: authorization }
33349
+ },
33350
+ "Job status read"
33351
+ );
33352
+ if (!response.ok) {
33353
+ throw await rejectedResponse(response, "Job status read rejected");
33354
+ }
33355
+ const body = await responseBody(response);
33356
+ return requireStatus(
33357
+ isRecord2(body) ? body["job"] : void 0,
33358
+ response.status
33359
+ );
33360
+ },
33361
+ async waitForJob(jobId, waitOptions = {}) {
33362
+ const timeoutMs = requireFiniteDuration(
33363
+ waitOptions.timeoutMs ?? DEFAULT_JOB_TIMEOUT_MS,
33364
+ "timeoutMs"
33365
+ );
33366
+ const pollMs = Math.max(
33367
+ CLAIM_POLL_FLOOR_MS,
33368
+ requireFiniteDuration(
33369
+ waitOptions.pollMs ?? DEFAULT_JOB_POLL_MS,
33370
+ "pollMs"
33371
+ )
33372
+ );
33373
+ const startedAt = Date.now();
33374
+ const callerDeadline = startedAt + timeoutMs;
33375
+ let latest;
33376
+ for (; ; ) {
33377
+ if (Date.now() >= callerDeadline) {
33378
+ throw new JobTimeoutError(
33379
+ `Timed out waiting for terminal job ${jobId}`,
33380
+ {
33381
+ jobId,
33382
+ timeoutMs,
33383
+ state: latest?.state
33384
+ }
33385
+ );
33386
+ }
33387
+ latest = await client.getJob(jobId);
33388
+ if (TERMINAL_JOB_STATES.has(latest.state)) return latest;
33389
+ const remaining = callerDeadline - Date.now();
33390
+ if (remaining <= 0) {
33391
+ throw new JobTimeoutError(
33392
+ `Timed out waiting for terminal job ${jobId}`,
33393
+ {
33394
+ jobId,
33395
+ timeoutMs,
33396
+ state: latest.state
33397
+ }
33398
+ );
33399
+ }
33400
+ await sleep2(Math.min(pollMs, remaining));
33401
+ }
33402
+ },
33403
+ async openResult(handle, openOptions) {
33404
+ if (!privateKey) {
33405
+ throw new JobRejectedError(
33406
+ "openResult requires createJobsClient({ builderPrivateKey })"
33407
+ );
33408
+ }
33409
+ const response = await request(
33410
+ handle.url,
33411
+ { method: GET_METHOD },
33412
+ "Job result fetch"
33413
+ );
33414
+ if (!response.ok) {
33415
+ throw await rejectedResponse(response, "Job result fetch rejected");
33416
+ }
33417
+ let bytes;
33418
+ try {
33419
+ bytes = new Uint8Array(await response.arrayBuffer());
33420
+ } catch (error) {
33421
+ throw new JobTransportError(
33422
+ `Job result fetch failed: ${error instanceof Error ? error.message : String(error)}`,
33423
+ error
33424
+ );
33425
+ }
33426
+ const actualHash = bytesToHex3(sha2566(bytes));
33427
+ if (actualHash.toLowerCase() !== handle.hash.toLowerCase()) {
33428
+ throw new JobResultIntegrityError(
33429
+ "Fetched job result hash does not match its handle",
33430
+ {
33431
+ objectKey: handle.objectKey,
33432
+ expectedHash: handle.hash,
33433
+ actualHash
33434
+ }
33435
+ );
33436
+ }
33437
+ if (bytes.length !== handle.size) {
33438
+ throw new JobResultIntegrityError(
33439
+ "Fetched job result size does not match its handle",
33440
+ {
33441
+ objectKey: handle.objectKey,
33442
+ expectedSize: handle.size,
33443
+ actualSize: bytes.length
33444
+ }
33445
+ );
33446
+ }
33447
+ return openJobResult(bytes, privateKey, ecies, openOptions.expect);
33448
+ },
33449
+ async readRaw(params) {
33450
+ const submitted = await client.submitRawRead(params);
33451
+ const job = submitted.job && TERMINAL_JOB_STATES.has(submitted.job.state) ? submitted.job : await client.waitForJob(submitted.jobId, {
33452
+ timeoutMs: params.timeoutMs,
33453
+ pollMs: params.pollMs
33454
+ });
33455
+ if (job.state !== "completed") {
33456
+ throw new JobRejectedError(
33457
+ `Job ${job.jobId} ended in state ${job.state}${job.failureReason ? `: ${job.failureReason}` : ""}`,
33458
+ void 0,
33459
+ null,
33460
+ {
33461
+ jobId: job.jobId,
33462
+ state: job.state,
33463
+ ...job.failureReason ? { failureReason: job.failureReason } : {}
33464
+ }
33465
+ );
33466
+ }
33467
+ if (!job.result) {
33468
+ throw new JobRejectedError(
33469
+ "Completed job status does not include a result handle",
33470
+ void 0,
33471
+ null,
33472
+ { jobId: job.jobId, state: job.state }
33473
+ );
33474
+ }
33475
+ return client.openResult(job.result, {
33476
+ expect: {
33477
+ jobId: submitted.jobId,
33478
+ scope: params.scope,
33479
+ ...params.pinnedVersion !== void 0 && params.pinnedVersion !== null ? { version: params.pinnedVersion } : {}
33480
+ }
33481
+ });
33482
+ }
33483
+ };
33484
+ return client;
33485
+ }
33486
+
32366
33487
  // src/protocol/personal-server-registration.ts
32367
33488
  import {
32368
- isAddress
33489
+ isAddress as isAddress3
32369
33490
  } from "viem";
32370
33491
  var PERSONAL_SERVER_REGISTRATION_DEFAULT_CHAIN_ID = vanaMainnet2.id;
32371
33492
  var PERSONAL_SERVER_REGISTRATION_DEFAULT_VERIFYING_CONTRACT = getContractAddress(
@@ -32373,7 +33494,7 @@ var PERSONAL_SERVER_REGISTRATION_DEFAULT_VERIFYING_CONTRACT = getContractAddress
32373
33494
  "DataPortabilityServers"
32374
33495
  );
32375
33496
  function assertAddress(value, name) {
32376
- if (!isAddress(value)) {
33497
+ if (!isAddress3(value)) {
32377
33498
  throw new Error(`${name} must be a valid EVM address`);
32378
33499
  }
32379
33500
  }
@@ -32460,13 +33581,13 @@ var registerPersonalServerSignature = buildPersonalServerRegistrationSignature;
32460
33581
 
32461
33582
  // src/personal-server-lite/owner-binding.ts
32462
33583
  import {
32463
- isAddress as isAddress2
33584
+ isAddress as isAddress4
32464
33585
  } from "viem";
32465
33586
  var PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION = "vana.ps-lite.owner-binding.v1";
32466
33587
  var PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE = "ps-lite-owner";
32467
33588
  var PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX = `${PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION}:${PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE}:`;
32468
33589
  function assertAddress2(value, name) {
32469
- if (!isAddress2(value)) {
33590
+ if (!isAddress4(value)) {
32470
33591
  throw new Error(`${name} must be a valid EVM address`);
32471
33592
  }
32472
33593
  }
@@ -32516,7 +33637,7 @@ async function buildPersonalServerLiteOwnerBindingSignature(input) {
32516
33637
  var signPersonalServerLiteOwnerBinding = buildPersonalServerLiteOwnerBindingSignature;
32517
33638
 
32518
33639
  // src/account/personal-server-registration.ts
32519
- import { isAddress as isAddress3 } from "viem";
33640
+ import { isAddress as isAddress5 } from "viem";
32520
33641
  var ACCOUNT_PERSONAL_SERVER_REGISTRATION_INTENT = "personal_server.server_registration.v1";
32521
33642
  var AccountPersonalServerRegistrationError = class extends Error {
32522
33643
  status;
@@ -32535,7 +33656,7 @@ function trimTrailingSlash(value) {
32535
33656
  return value.replace(/\/+$/, "");
32536
33657
  }
32537
33658
  function assertAddress3(value, name) {
32538
- if (!isAddress3(value)) {
33659
+ if (!isAddress5(value)) {
32539
33660
  throw new Error(`${name} must be a valid EVM address`);
32540
33661
  }
32541
33662
  }
@@ -32556,7 +33677,7 @@ function accountErrorMessage(status, body) {
32556
33677
  if (nestedMessage) {
32557
33678
  return nestedMessage;
32558
33679
  }
32559
- if (isRecord(body) && typeof body.message === "string") {
33680
+ if (isRecord3(body) && typeof body.message === "string") {
32560
33681
  return body.message;
32561
33682
  }
32562
33683
  const code = accountErrorCode(body);
@@ -32570,7 +33691,7 @@ function accountErrorCode(body) {
32570
33691
  if (nestedCode) {
32571
33692
  return nestedCode;
32572
33693
  }
32573
- if (isRecord(body)) {
33694
+ if (isRecord3(body)) {
32574
33695
  if (typeof body.code === "string") {
32575
33696
  return body.code;
32576
33697
  }
@@ -32581,13 +33702,13 @@ function accountErrorCode(body) {
32581
33702
  return void 0;
32582
33703
  }
32583
33704
  function nestedAccountErrorField(body, field) {
32584
- if (!isRecord(body) || !isRecord(body.error)) {
33705
+ if (!isRecord3(body) || !isRecord3(body.error)) {
32585
33706
  return void 0;
32586
33707
  }
32587
33708
  const value = body.error[field];
32588
33709
  return typeof value === "string" ? value : void 0;
32589
33710
  }
32590
- function isRecord(value) {
33711
+ function isRecord3(value) {
32591
33712
  return typeof value === "object" && value !== null;
32592
33713
  }
32593
33714
  function normalizeAccountResponse(response) {
@@ -33061,8 +34182,8 @@ function buildMarkDataPointUnavailableRequest(config, input) {
33061
34182
 
33062
34183
  // src/protocol/data-point-deletion.ts
33063
34184
  import {
33064
- isAddress as isAddress5,
33065
- keccak256 as keccak2562,
34185
+ isAddress as isAddress7,
34186
+ keccak256 as keccak2563,
33066
34187
  maxUint256,
33067
34188
  stringToBytes as stringToBytes3
33068
34189
  } from "viem";
@@ -33070,13 +34191,13 @@ import {
33070
34191
  // src/protocol/lineage.ts
33071
34192
  import {
33072
34193
  encodeAbiParameters,
33073
- isAddress as isAddress4,
33074
- keccak256
34194
+ isAddress as isAddress6,
34195
+ keccak256 as keccak2562
33075
34196
  } from "viem";
33076
34197
  import { z } from "zod";
33077
34198
 
33078
34199
  // src/protocol/personal-server-error-body.ts
33079
- function isRecord2(value) {
34200
+ function isRecord4(value) {
33080
34201
  return value !== null && typeof value === "object" && !Array.isArray(value);
33081
34202
  }
33082
34203
  async function readPersonalServerErrorBody(response) {
@@ -33086,8 +34207,8 @@ async function readPersonalServerErrorBody(response) {
33086
34207
  } catch {
33087
34208
  return { errorCode: null, message: null };
33088
34209
  }
33089
- if (!isRecord2(body)) return { errorCode: null, message: null };
33090
- const nested = isRecord2(body.error) ? body.error : null;
34210
+ if (!isRecord4(body)) return { errorCode: null, message: null };
34211
+ const nested = isRecord4(body.error) ? body.error : null;
33091
34212
  const gatewayShape = typeof body.error === "string" && typeof body.code === "string";
33092
34213
  const code = nested?.errorCode ?? nested?.code ?? body.errorCode ?? (gatewayShape ? body.code : void 0) ?? (typeof body.error === "string" ? body.error : void 0) ?? body.code;
33093
34214
  const message = nested?.message ?? body.message ?? (gatewayShape ? body.error : void 0);
@@ -33100,62 +34221,22 @@ async function readPersonalServerErrorBody(response) {
33100
34221
  return {
33101
34222
  errorCode: typeof code === "string" ? code : null,
33102
34223
  message: typeof message === "string" ? message : null,
33103
- ...isRecord2(details) ? { details } : {}
34224
+ ...isRecord4(details) ? { details } : {}
33104
34225
  };
33105
34226
  }
33106
34227
 
33107
- // src/protocol/write-signer.ts
33108
- function isRecord3(value) {
33109
- return value !== null && typeof value === "object";
33110
- }
33111
- function isViemWriteAccount(source) {
33112
- return isRecord3(source) && source.type === "local" && typeof source.address === "string" && typeof source.signMessage === "function";
33113
- }
33114
- function isViemWriteWalletClient(source) {
33115
- return isRecord3(source) && typeof source.signMessage === "function" && source.type !== "local" && (source.type === "walletClient" || "transport" in source);
33116
- }
33117
- function accountAddress(account) {
33118
- return typeof account === "string" ? account : account.address;
33119
- }
33120
- function resolveWriteSigner(source, options = {}) {
33121
- if (isViemWriteWalletClient(source)) {
33122
- const account = options.account ?? source.account;
33123
- if (account === void 0) {
33124
- throw new WriteRequestError(
33125
- "Viem wallet client requires an account option or account property"
33126
- );
33127
- }
33128
- return {
33129
- address: accountAddress(account),
33130
- signMessage: (message) => source.signMessage({ account, message })
33131
- };
33132
- }
33133
- if (isViemWriteAccount(source)) {
33134
- return {
33135
- address: source.address,
33136
- signMessage: (message) => source.signMessage({ message })
33137
- };
33138
- }
33139
- if (!isRecord3(source) || typeof source.signMessage !== "function") {
33140
- throw new WriteRequestError(
33141
- "signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
33142
- );
33143
- }
33144
- return source;
33145
- }
33146
-
33147
34228
  // src/protocol/lineage.ts
33148
34229
  var DATA_POINT_ID_PATTERN = /^0x[0-9a-fA-F]{64}$/;
33149
34230
  function isDataPointId(value) {
33150
34231
  return typeof value === "string" && DATA_POINT_ID_PATTERN.test(value);
33151
34232
  }
33152
34233
  function deriveDataPointId(ownerAddress, scope) {
33153
- if (!isAddress4(ownerAddress, { strict: false })) {
34234
+ if (!isAddress6(ownerAddress, { strict: false })) {
33154
34235
  throw new Error(
33155
34236
  `ownerAddress is not an EVM address: ${String(ownerAddress)}`
33156
34237
  );
33157
34238
  }
33158
- return keccak256(
34239
+ return keccak2562(
33159
34240
  encodeAbiParameters(
33160
34241
  [
33161
34242
  { name: "ownerAddress", type: "address" },
@@ -33245,7 +34326,7 @@ function gatewayLineagePath(dataPointId, version) {
33245
34326
  function normalizeBaseUrl(url) {
33246
34327
  return url.replace(/\/+$/, "");
33247
34328
  }
33248
- function resolveFetch(fetchFn) {
34329
+ function resolveFetch2(fetchFn) {
33249
34330
  const resolved = fetchFn ?? globalThis.fetch;
33250
34331
  if (resolved === void 0) {
33251
34332
  throw new LineageReadError("No fetch implementation available");
@@ -33286,7 +34367,7 @@ async function parseLineageGraph(source, response) {
33286
34367
  { cause: err instanceof Error ? err.message : String(err) }
33287
34368
  );
33288
34369
  }
33289
- const envelope = isRecord2(body) && isRecord2(body.data) ? body : void 0;
34370
+ const envelope = isRecord4(body) && isRecord4(body.data) ? body : void 0;
33290
34371
  const parsed = LineageGraphSchema.safeParse(envelope?.data ?? body);
33291
34372
  if (!parsed.success) {
33292
34373
  throw new LineageReadError(
@@ -33296,7 +34377,7 @@ async function parseLineageGraph(source, response) {
33296
34377
  { issues: parsed.error.issues }
33297
34378
  );
33298
34379
  }
33299
- const proof = isRecord2(envelope?.proof) ? envelope.proof : void 0;
34380
+ const proof = isRecord4(envelope?.proof) ? envelope.proof : void 0;
33300
34381
  return proof === void 0 ? parsed.data : { ...parsed.data, proof };
33301
34382
  }
33302
34383
  async function sendLineageRead(source, fetchFn, url, headers) {
@@ -33317,7 +34398,7 @@ async function sendLineageRead(source, fetchFn, url, headers) {
33317
34398
  return parseLineageGraph(source, response);
33318
34399
  }
33319
34400
  async function getPersonalServerLineage(params) {
33320
- const fetchFn = resolveFetch(params.fetch);
34401
+ const fetchFn = resolveFetch2(params.fetch);
33321
34402
  const baseUrl = normalizeBaseUrl(params.personalServerUrl);
33322
34403
  const audience = params.audience ?? baseUrl;
33323
34404
  const signer = resolveWriteSigner(params.signer, { account: params.account });
@@ -33352,7 +34433,7 @@ async function getGatewayLineage(params) {
33352
34433
  { dataPointId: params.dataPointId }
33353
34434
  );
33354
34435
  }
33355
- const fetchFn = resolveFetch(params.fetch);
34436
+ const fetchFn = resolveFetch2(params.fetch);
33356
34437
  const baseUrl = normalizeBaseUrl(params.gatewayUrl);
33357
34438
  const signer = resolveWriteSigner(params.signer, { account: params.account });
33358
34439
  const uri = gatewayLineagePath(
@@ -33382,7 +34463,7 @@ var TOMBSTONE_METADATA_HASH_PREIMAGE = "vana.data-point.tombstone.metadata.v1";
33382
34463
  var TOMBSTONE_DATA_HASH = "0x30c45ee72fe56d1927701316925ab7ceacd3b6f9267061735d59396f075c6222";
33383
34464
  var TOMBSTONE_METADATA_HASH = "0xc5255a141acd6a2ae55971b62c0a85977c2511989dc114ad2abc2b7644f57d90";
33384
34465
  function computeTombstoneHash(preimage) {
33385
- return keccak2562(stringToBytes3(preimage));
34466
+ return keccak2563(stringToBytes3(preimage));
33386
34467
  }
33387
34468
  function isTombstoneHashes(dataHash, metadataHash) {
33388
34469
  return typeof dataHash === "string" && typeof metadataHash === "string" && dataHash.toLowerCase() === TOMBSTONE_DATA_HASH && metadataHash.toLowerCase() === TOMBSTONE_METADATA_HASH;
@@ -33401,7 +34482,7 @@ function tombstoneDeletedAt(value) {
33401
34482
  return typeof deletedAt === "string" ? deletedAt : null;
33402
34483
  }
33403
34484
  function assertAddress4(value, name) {
33404
- if (!isAddress5(value)) {
34485
+ if (!isAddress7(value)) {
33405
34486
  throw new Error(`${name} must be a valid EVM address`);
33406
34487
  }
33407
34488
  }
@@ -33816,17 +34897,17 @@ function tryGrantPermissions(scopes) {
33816
34897
  }
33817
34898
 
33818
34899
  // src/protocol/personal-server-write.ts
33819
- import { sha256 as sha2566 } from "@noble/hashes/sha2";
33820
- import { bytesToHex as bytesToHex3, isAddress as isAddress6 } from "viem";
34900
+ import { sha256 as sha2568 } from "@noble/hashes/sha2";
34901
+ import { bytesToHex as bytesToHex5, isAddress as isAddress8 } from "viem";
33821
34902
  import { z as z4 } from "zod";
33822
34903
 
33823
34904
  // src/protocol/write-request.ts
33824
- import { sha256 as sha2565 } from "@noble/hashes/sha2";
33825
- import { bytesToHex as bytesToHex2 } from "viem";
34905
+ import { sha256 as sha2567 } from "@noble/hashes/sha2";
34906
+ import { bytesToHex as bytesToHex4 } from "viem";
33826
34907
  function normalizeBaseUrl2(url) {
33827
34908
  return url.replace(/\/+$/, "");
33828
34909
  }
33829
- function resolveFetch2(fetchFn) {
34910
+ function resolveFetch3(fetchFn) {
33830
34911
  const resolved = fetchFn ?? globalThis.fetch;
33831
34912
  if (resolved === void 0) {
33832
34913
  throw new WriteRequestError("No fetch implementation available");
@@ -33839,7 +34920,7 @@ function errorMessage(err) {
33839
34920
  function finiteOr(value, fallback) {
33840
34921
  return typeof value === "number" && Number.isFinite(value) ? value : fallback;
33841
34922
  }
33842
- function sleep2(ms) {
34923
+ function sleep3(ms) {
33843
34924
  return new Promise((resolve) => setTimeout(resolve, ms));
33844
34925
  }
33845
34926
  var issuedProofIats = /* @__PURE__ */ new Map();
@@ -33881,7 +34962,7 @@ function nextProofIat(proofKey) {
33881
34962
  setIssuedProofIat(proofKey, iat, last);
33882
34963
  const waitSec = iat - nowSec - PROOF_IAT_MAX_AHEAD_SECONDS;
33883
34964
  if (waitSec <= 0) return Promise.resolve(iat);
33884
- return sleep2(waitSec * 1e3).then(() => iat);
34965
+ return sleep3(waitSec * 1e3).then(() => iat);
33885
34966
  }
33886
34967
  function freshProofNonce() {
33887
34968
  const webCrypto = globalThis.crypto;
@@ -33889,22 +34970,22 @@ function freshProofNonce() {
33889
34970
  return webCrypto.randomUUID();
33890
34971
  }
33891
34972
  if (typeof webCrypto?.getRandomValues === "function") {
33892
- return bytesToHex2(webCrypto.getRandomValues(new Uint8Array(16)));
34973
+ return bytesToHex4(webCrypto.getRandomValues(new Uint8Array(16)));
33893
34974
  }
33894
34975
  throw new WriteRequestError(
33895
34976
  "No secure random source available to build a proof nonce; provide a crypto global"
33896
34977
  );
33897
34978
  }
33898
34979
  function proofKeyFor(parts) {
33899
- return bytesToHex2(
33900
- sha2565(
34980
+ return bytesToHex4(
34981
+ sha2567(
33901
34982
  new TextEncoder().encode(
33902
34983
  JSON.stringify([
33903
34984
  parts.aud,
33904
34985
  parts.method,
33905
34986
  parts.uri,
33906
34987
  parts.grantId,
33907
- parts.signedBytes ? bytesToHex2(sha2565(parts.signedBytes)) : ""
34988
+ parts.signedBytes ? bytesToHex4(sha2567(parts.signedBytes)) : ""
33908
34989
  ])
33909
34990
  )
33910
34991
  )
@@ -33922,7 +35003,7 @@ async function sendWithFreshProof(label, fetchFn, options, proofKey, build) {
33922
35003
  lastError = err;
33923
35004
  }
33924
35005
  if (attempt < attempts - 1) {
33925
- await sleep2(delayMs);
35006
+ await sleep3(delayMs);
33926
35007
  delayMs *= 2;
33927
35008
  }
33928
35009
  }
@@ -33961,7 +35042,7 @@ function dataPath(scope) {
33961
35042
  return `/v1/data/${encodeURIComponent(scope)}`;
33962
35043
  }
33963
35044
  async function openWriteSession(params) {
33964
- const fetchFn = resolveFetch2(params.fetch);
35045
+ const fetchFn = resolveFetch3(params.fetch);
33965
35046
  const personalServerUrl = normalizeBaseUrl2(params.personalServerUrl);
33966
35047
  const audience = params.audience ?? personalServerUrl;
33967
35048
  const signer = resolveWriteSigner(params.signer, { account: params.account });
@@ -34041,12 +35122,12 @@ async function openWriteSession(params) {
34041
35122
  };
34042
35123
  }
34043
35124
  function isWriteSession(value) {
34044
- if (!isRecord2(value)) return false;
35125
+ if (!isRecord4(value)) return false;
34045
35126
  const signer = value.signer;
34046
- return typeof value.personalServerUrl === "string" && typeof value.audience === "string" && typeof value.grantId === "string" && typeof value.accessToken === "string" && value.accessToken.length > 0 && typeof value.expiresAt === "number" && Number.isFinite(value.expiresAt) && Array.isArray(value.writeScopes) && value.writeScopes.every((scope) => typeof scope === "string") && isRecord2(signer) && typeof signer.signMessage === "function";
35127
+ return typeof value.personalServerUrl === "string" && typeof value.audience === "string" && typeof value.grantId === "string" && typeof value.accessToken === "string" && value.accessToken.length > 0 && typeof value.expiresAt === "number" && Number.isFinite(value.expiresAt) && Array.isArray(value.writeScopes) && value.writeScopes.every((scope) => typeof scope === "string") && isRecord4(signer) && typeof signer.signMessage === "function";
34047
35128
  }
34048
35129
  function sessionCoversScope(session, scope) {
34049
- if (!isRecord2(session) || !Array.isArray(session.writeScopes) || !session.writeScopes.every((pattern) => typeof pattern === "string")) {
35130
+ if (!isRecord4(session) || !Array.isArray(session.writeScopes) || !session.writeScopes.every((pattern) => typeof pattern === "string")) {
34050
35131
  throw new WriteRequestError("session must come from openWriteSession");
34051
35132
  }
34052
35133
  return session.writeScopes.some(
@@ -34091,7 +35172,7 @@ function binaryWriteSignedBytes(input) {
34091
35172
  mimeType: normalizeBinaryMimeType(input.contentType),
34092
35173
  ...input.filename ? { filename: input.filename } : {},
34093
35174
  sizeBytes: input.bytes.length,
34094
- contentHash: bytesToHex3(sha2566(input.bytes)),
35175
+ contentHash: bytesToHex5(sha2568(input.bytes)),
34095
35176
  encoding: "base64",
34096
35177
  content: toBase64(input.bytes),
34097
35178
  ...metadata !== void 0 ? { metadata } : {}
@@ -34120,7 +35201,7 @@ function assertNoReservedKeys(value, where) {
34120
35201
  }
34121
35202
  }
34122
35203
  function isLineagePair(value) {
34123
- return isRecord2(value) && typeof value.ownerAddress === "string" && typeof value.scope === "string";
35204
+ return isRecord4(value) && typeof value.ownerAddress === "string" && typeof value.scope === "string";
34124
35205
  }
34125
35206
  function normalizeLineage(lineage, derivedScope) {
34126
35207
  if (!Array.isArray(lineage)) {
@@ -34139,7 +35220,7 @@ function normalizeLineage(lineage, derivedScope) {
34139
35220
  for (const entry of lineage) {
34140
35221
  let id;
34141
35222
  if (isLineagePair(entry)) {
34142
- if (!isAddress6(entry.ownerAddress, { strict: false })) {
35223
+ if (!isAddress8(entry.ownerAddress, { strict: false })) {
34143
35224
  throw new WriteRequestError(
34144
35225
  "lineage source ownerAddress must be an EVM address",
34145
35226
  { ownerAddress: entry.ownerAddress }
@@ -34188,7 +35269,7 @@ function assertNoLineageField(value, where) {
34188
35269
  }
34189
35270
  function buildMetadataHeader(metadata, sources) {
34190
35271
  if (metadata !== void 0) {
34191
- if (!isRecord2(metadata)) {
35272
+ if (!isRecord4(metadata)) {
34192
35273
  throw new WriteRequestError("metadata must be a plain object");
34193
35274
  }
34194
35275
  assertNoReservedKeys(metadata, "metadata");
@@ -34241,7 +35322,7 @@ function prepareWrite(params) {
34241
35322
  if (params.data === void 0) {
34242
35323
  throw new WriteRequestError("Pass data (a JSON object) or binary");
34243
35324
  }
34244
- if (!isRecord2(params.data)) {
35325
+ if (!isRecord4(params.data)) {
34245
35326
  throw new WriteRequestError("data must be a plain JSON object");
34246
35327
  }
34247
35328
  if (params.metadata !== void 0) {
@@ -34292,7 +35373,7 @@ async function writeData(params) {
34292
35373
  if (!isWriteSession(session)) {
34293
35374
  throw new WriteRequestError("session must come from openWriteSession");
34294
35375
  }
34295
- const fetchFn = resolveFetch2(params.fetch);
35376
+ const fetchFn = resolveFetch3(params.fetch);
34296
35377
  if (typeof params.scope !== "string" || params.scope.length === 0) {
34297
35378
  throw new WriteRequestError("scope is required");
34298
35379
  }
@@ -34484,7 +35565,7 @@ function resolveRequest(params) {
34484
35565
  "signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
34485
35566
  );
34486
35567
  }
34487
- const fetchFn = resolveFetch2(params.fetch);
35568
+ const fetchFn = resolveFetch3(params.fetch);
34488
35569
  const baseUrl = normalizeBaseUrl2(params.personalServerUrl);
34489
35570
  const audience = params.audience ?? baseUrl;
34490
35571
  return {
@@ -34817,7 +35898,7 @@ async function waitForQuestion(params) {
34817
35898
  }
34818
35899
  );
34819
35900
  }
34820
- await sleep2(Math.min(pollIntervalMs, remaining));
35901
+ await sleep3(Math.min(pollIntervalMs, remaining));
34821
35902
  }
34822
35903
  }
34823
35904
  async function askPersonalServer(params) {
@@ -34881,7 +35962,7 @@ function derivativeStatusTarget(derivedScope) {
34881
35962
  function normalizeBaseUrl3(url) {
34882
35963
  return url.replace(/\/+$/, "");
34883
35964
  }
34884
- function resolveFetch3(fetchFn) {
35965
+ function resolveFetch4(fetchFn) {
34885
35966
  const resolved = fetchFn ?? globalThis.fetch;
34886
35967
  if (resolved === void 0) {
34887
35968
  throw new WriteRequestError("No fetch implementation available");
@@ -34894,7 +35975,7 @@ function requireDerivedScope(derivedScope) {
34894
35975
  }
34895
35976
  return derivedScope;
34896
35977
  }
34897
- function sleep3(ms, signal) {
35978
+ function sleep4(ms, signal) {
34898
35979
  if (ms <= 0) return Promise.resolve();
34899
35980
  return new Promise((resolve, reject) => {
34900
35981
  const timer = setTimeout(() => {
@@ -34930,7 +36011,7 @@ function isDerivativeStatusSettled(status) {
34930
36011
  }
34931
36012
  async function getDerivativeStatus(params) {
34932
36013
  const derivedScope = requireDerivedScope(params.derivedScope);
34933
- const fetchFn = resolveFetch3(params.fetch);
36014
+ const fetchFn = resolveFetch4(params.fetch);
34934
36015
  const baseUrl = normalizeBaseUrl3(params.personalServerUrl);
34935
36016
  const signer = resolveWriteSigner(params.signer, { account: params.account });
34936
36017
  const headers = new Headers(params.headers);
@@ -35008,7 +36089,7 @@ async function waitForDerivativeStatus(params) {
35008
36089
  if (waitMs > remaining) {
35009
36090
  throw timeoutError(latest, timeoutMs);
35010
36091
  }
35011
- await sleep3(waitMs, params.signal);
36092
+ await sleep4(waitMs, params.signal);
35012
36093
  }
35013
36094
  }
35014
36095
 
@@ -36041,7 +37122,7 @@ var KNOWN_CODES = /* @__PURE__ */ new Set([
36041
37122
  "server_not_configured",
36042
37123
  "content_too_large"
36043
37124
  ]);
36044
- function isRecord4(value) {
37125
+ function isRecord5(value) {
36045
37126
  return value !== null && typeof value === "object" && !Array.isArray(value);
36046
37127
  }
36047
37128
  function normalizeCode(value) {
@@ -36052,10 +37133,10 @@ function normalizeCode(value) {
36052
37133
  return KNOWN_CODES.has(code) ? code : null;
36053
37134
  }
36054
37135
  function extractPSErrorBody(body) {
36055
- if (!isRecord4(body)) {
37136
+ if (!isRecord5(body)) {
36056
37137
  return null;
36057
37138
  }
36058
- const nested = isRecord4(body.error) ? body.error : null;
37139
+ const nested = isRecord5(body.error) ? body.error : null;
36059
37140
  const code = normalizeCode(
36060
37141
  nested?.errorCode ?? nested?.code ?? body.errorCode ?? body.code
36061
37142
  );
@@ -36086,6 +37167,8 @@ export {
36086
37167
  BUILDER_REGISTRATION_TYPES,
36087
37168
  BlockchainError,
36088
37169
  BrowserPlatformAdapter,
37170
+ BuilderUnknownError,
37171
+ CLAIM_POLL_FLOOR_MS,
36089
37172
  CONTRACTS,
36090
37173
  CallbackStorage,
36091
37174
  ContractFactory,
@@ -36094,6 +37177,8 @@ export {
36094
37177
  DATA_REGISTRY_STATUS_ABI,
36095
37178
  DEFAULT_DERIVATIVE_STATUS_POLL_INTERVAL_MS,
36096
37179
  DEFAULT_DERIVATIVE_STATUS_TIMEOUT_MS,
37180
+ DEFAULT_JOB_DEADLINE_SECONDS,
37181
+ DEFAULT_LEASE_SECONDS,
36097
37182
  DEFAULT_QUESTION_POLL_INTERVAL_MS,
36098
37183
  DEFAULT_QUESTION_TIMEOUT_MS,
36099
37184
  DERIVATIVE_ERROR_CODES,
@@ -36118,6 +37203,9 @@ export {
36118
37203
  DerivativeStatusSchema,
36119
37204
  DropboxStorage,
36120
37205
  ECIESError,
37206
+ ENCLAVE_IDENTITY_EVIDENCE_VERSION,
37207
+ ENCLAVE_TRUST_ANCHORS,
37208
+ ENCLAVE_WALLET_PURPOSE,
36121
37209
  ESCROW_DEPOSIT_ABI2 as ESCROW_DEPOSIT_ABI,
36122
37210
  ExpiredTokenError,
36123
37211
  FEE_REGISTRY_ABI,
@@ -36126,12 +37214,25 @@ export {
36126
37214
  GRANT_REGISTRATION_TYPES,
36127
37215
  GRANT_REVOCATION_TYPES,
36128
37216
  GoogleDriveStorage,
37217
+ GrantInvalidError,
36129
37218
  InMemoryTokenStore,
36130
37219
  IngestResponseSchema,
36131
37220
  InvalidConfigurationError,
36132
37221
  InvalidScopeEntryError,
36133
37222
  InvalidSignatureError,
36134
37223
  IpfsStorage,
37224
+ JOB_OPERATIONS,
37225
+ JOB_PROTOCOL_VERSION,
37226
+ JOB_STATES,
37227
+ JobEnvelopeError,
37228
+ JobIdTakenError,
37229
+ JobNotFoundError,
37230
+ JobRejectedError,
37231
+ JobRequestTooLargeError,
37232
+ JobResultIntegrityError,
37233
+ JobTimeoutError,
37234
+ JobTransportError,
37235
+ JobsClientError,
36135
37236
  LINEAGE_FIELD,
36136
37237
  LINEAGE_KEY,
36137
37238
  LineageEntrySchema,
@@ -36139,10 +37240,16 @@ export {
36139
37240
  LineageNodeSchema,
36140
37241
  LineageReadError,
36141
37242
  MASTER_KEY_MESSAGE,
37243
+ MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS,
37244
+ MASTER_SIGNATURE_DELIVERY_VERSION,
37245
+ MAX_ATTEMPTS,
37246
+ MAX_JOB_DEADLINE_SECONDS,
37247
+ MAX_LEASE_SECONDS,
36142
37248
  MAX_LINEAGE_SOURCES,
36143
37249
  MAX_QUESTION_CHARS,
36144
37250
  MAX_QUESTION_MODEL_CHARS,
36145
37251
  MAX_QUESTION_SOURCE_SCOPES,
37252
+ MAX_WAIT_SECONDS,
36146
37253
  MissingAuthError,
36147
37254
  NATIVE_ASSET_ADDRESS,
36148
37255
  NATIVE_VANA_ASSET,
@@ -36151,6 +37258,7 @@ export {
36151
37258
  NodePlatformAdapter,
36152
37259
  NonceError,
36153
37260
  OAuthClient,
37261
+ OwnerNotReadyError,
36154
37262
  PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX,
36155
37263
  PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE,
36156
37264
  PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION,
@@ -36176,6 +37284,7 @@ export {
36176
37284
  RedactedLineageNodeSchema,
36177
37285
  RelayerError,
36178
37286
  SCOPE_ACTIONS,
37287
+ SEALED_ENVELOPE_VERSION,
36179
37288
  SERVER_REGISTRATION_TYPES,
36180
37289
  ScopeSchema,
36181
37290
  SerializationError,
@@ -36188,6 +37297,7 @@ export {
36188
37297
  TOMBSTONE_METADATA_HASH,
36189
37298
  TOMBSTONE_METADATA_HASH_PREIMAGE,
36190
37299
  TransactionPendingError,
37300
+ USER_PS_ID_DOMAIN,
36191
37301
  UserRejectedRequestError,
36192
37302
  VanaError,
36193
37303
  VanaStorage,
@@ -36206,6 +37316,7 @@ export {
36206
37316
  WriteSessionExpiredError,
36207
37317
  WriteTransportError,
36208
37318
  WriteUnauthorizedError,
37319
+ appRootPreimage,
36209
37320
  askPersonalServer,
36210
37321
  assertDerivedScopeNaming,
36211
37322
  assertValidPkceVerifier,
@@ -36219,6 +37330,7 @@ export {
36219
37330
  buildEscrowPaymentHeader,
36220
37331
  buildGrantPaymentHeader,
36221
37332
  buildMarkDataPointUnavailableRequest,
37333
+ buildMasterSignatureDelivery,
36222
37334
  buildPersonalServerDataReadRequest,
36223
37335
  buildPersonalServerLiteOwnerBindingMessage,
36224
37336
  buildPersonalServerLiteOwnerBindingSignature,
@@ -36227,6 +37339,7 @@ export {
36227
37339
  buildSetDataPointStatusRequest,
36228
37340
  buildWeb3SignedHeader,
36229
37341
  builderRegistrationDomain,
37342
+ canonicalJobRequestBytes,
36230
37343
  chains,
36231
37344
  clearContractCache,
36232
37345
  computeBodyHash,
@@ -36238,6 +37351,7 @@ export {
36238
37351
  createDefaultNonceSource,
36239
37352
  createEscrowGatewayClient,
36240
37353
  createGatewayClient,
37354
+ createJobsClient,
36241
37355
  createNodePlatformAdapter,
36242
37356
  createPlatformAdapter,
36243
37357
  createPlatformAdapterFor,
@@ -36262,6 +37376,7 @@ export {
36262
37376
  encodeDepositTokenData,
36263
37377
  encodeSetDataPointStatusData,
36264
37378
  encodeWriteMetadataHeader,
37379
+ encryptMasterSignatureDelivery,
36265
37380
  encryptWithPassword,
36266
37381
  escrowContractAddress,
36267
37382
  escrowPaymentDomain,
@@ -36296,12 +37411,15 @@ export {
36296
37411
  isPlatformSupported,
36297
37412
  isRedactedLineageNode,
36298
37413
  isTombstoneHashes,
37414
+ kmsIssuedPreimage,
36299
37415
  listQuestions,
36300
37416
  mainnetServices,
36301
37417
  moksha,
36302
37418
  mokshaServices,
36303
37419
  mokshaTestnet2 as mokshaTestnet,
36304
37420
  normalizeBinaryMimeType,
37421
+ openJobRequest,
37422
+ openJobResult,
36305
37423
  openWriteSession,
36306
37424
  parsePSError,
36307
37425
  parsePersonalServerPaymentRequired,
@@ -36325,6 +37443,8 @@ export {
36325
37443
  scopeMatchesPattern,
36326
37444
  scopeNamespace,
36327
37445
  scopeToPathSegments,
37446
+ sealJobRequest,
37447
+ sealJobResult,
36328
37448
  serializeECIES,
36329
37449
  serverRegistrationDomain,
36330
37450
  sessionCoversScope,
@@ -36335,7 +37455,9 @@ export {
36335
37455
  toDirectPaymentReceipt,
36336
37456
  tombstoneDeletedAt,
36337
37457
  tryGrantPermissions,
37458
+ userPsId,
36338
37459
  vanaMainnet2 as vanaMainnet,
37460
+ verifyEnclaveIdentityEvidence,
36339
37461
  verifyGrantRegistration,
36340
37462
  verifyPkceChallenge,
36341
37463
  verifyWeb3Signed,