@opendatalabs/vana-sdk 3.22.0 → 3.23.0-pr.211.1da7c1b

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 +313 -0
  2. package/dist/crypto/envelope/job.cjs.map +1 -0
  3. package/dist/crypto/envelope/job.d.ts +122 -0
  4. package/dist/crypto/envelope/job.js +291 -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 +589 -24
  30. package/dist/index.browser.js.map +4 -4
  31. package/dist/index.node.cjs +1217 -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 +1181 -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 +192 -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
@@ -1338,6 +1338,68 @@ var WriteRejectedError = class extends PersonalServerWriteError {
1338
1338
  super(message, "WRITE_REJECTED", status, errorCode, details);
1339
1339
  }
1340
1340
  };
1341
+ var JobsClientError = class extends VanaError {
1342
+ constructor(message, code, status, errorCode = null, details) {
1343
+ super(message, code);
1344
+ this.status = status;
1345
+ this.errorCode = errorCode;
1346
+ this.details = details;
1347
+ }
1348
+ status;
1349
+ errorCode;
1350
+ details;
1351
+ };
1352
+ var BuilderUnknownError = class extends JobsClientError {
1353
+ constructor(message, details) {
1354
+ super(message, "JOB_BUILDER_UNKNOWN", 403, "BUILDER_UNKNOWN", details);
1355
+ }
1356
+ };
1357
+ var GrantInvalidError = class extends JobsClientError {
1358
+ constructor(message, details) {
1359
+ super(message, "JOB_GRANT_INVALID", 403, "GRANT_INVALID", details);
1360
+ }
1361
+ };
1362
+ var OwnerNotReadyError = class extends JobsClientError {
1363
+ constructor(message, details) {
1364
+ super(message, "JOB_OWNER_NOT_READY", 403, "OWNER_NOT_READY", details);
1365
+ }
1366
+ };
1367
+ var JobIdTakenError = class extends JobsClientError {
1368
+ constructor(message, details) {
1369
+ super(message, "JOB_ID_TAKEN", 409, "JOB_ID_TAKEN", details);
1370
+ }
1371
+ };
1372
+ var JobNotFoundError = class extends JobsClientError {
1373
+ constructor(message, details) {
1374
+ super(message, "JOB_NOT_FOUND", 404, "JOB_NOT_FOUND", details);
1375
+ }
1376
+ };
1377
+ var JobRequestTooLargeError = class extends JobsClientError {
1378
+ constructor(message, errorCode = "BODY_TOO_LARGE", details) {
1379
+ super(message, "JOB_REQUEST_TOO_LARGE", 413, errorCode, details);
1380
+ }
1381
+ };
1382
+ var JobTimeoutError = class extends JobsClientError {
1383
+ constructor(message, details) {
1384
+ super(message, "JOB_TIMEOUT", void 0, null, details);
1385
+ }
1386
+ };
1387
+ var JobResultIntegrityError = class extends JobsClientError {
1388
+ constructor(message, details) {
1389
+ super(message, "JOB_RESULT_INTEGRITY", void 0, null, details);
1390
+ }
1391
+ };
1392
+ var JobRejectedError = class extends JobsClientError {
1393
+ constructor(message, status, errorCode = null, details) {
1394
+ super(message, "JOB_REJECTED", status, errorCode, details);
1395
+ }
1396
+ };
1397
+ var JobTransportError = class extends JobsClientError {
1398
+ constructor(message, cause) {
1399
+ super(message, "JOB_TRANSPORT_ERROR");
1400
+ this.cause = cause;
1401
+ }
1402
+ };
1341
1403
  var LineageReadError = class extends VanaError {
1342
1404
  constructor(message, status, errorCode = null, details) {
1343
1405
  super(message, "LINEAGE_READ_ERROR");
@@ -31736,9 +31798,472 @@ var RECORD_DATA_ACCESS_TYPES = {
31736
31798
  ]
31737
31799
  };
31738
31800
 
31801
+ // src/protocol/identity.ts
31802
+ init_interface();
31803
+ import * as secp256k13 from "@noble/secp256k1";
31804
+ import {
31805
+ concat as concat4,
31806
+ encodePacked,
31807
+ fromHex as fromHex5,
31808
+ getAddress,
31809
+ isAddressEqual,
31810
+ keccak256,
31811
+ recoverPublicKey,
31812
+ toBytes,
31813
+ toHex as toHex6
31814
+ } from "viem";
31815
+ import { publicKeyToAddress } from "viem/accounts";
31816
+ var ENCLAVE_IDENTITY_EVIDENCE_VERSION = 1;
31817
+ var USER_PS_ID_DOMAIN = "vana.ps-enclave.v1";
31818
+ var ENCLAVE_WALLET_PURPOSE = "vana.ps-enclave.wallet.v1";
31819
+ var MASTER_SIGNATURE_DELIVERY_VERSION = "vana.ps-enclave.delivery.v1";
31820
+ var MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS = 600;
31821
+ var SEALED_ENVELOPE_VERSION = 1;
31822
+ var VANA_MAINNET_CHAIN_ID = 1480;
31823
+ var MOKSHA_CHAIN_ID = 14800;
31824
+ var KMS_ISSUED_PREFIX = "dstack-kms-issued";
31825
+ var PREIMAGE_SEPARATOR = ":";
31826
+ var UNCOMPRESSED_PUBLIC_KEY_BYTES = 65;
31827
+ var UNCOMPRESSED_PUBLIC_KEY_PREFIX = "04";
31828
+ var EMPTY_HEX = "0x";
31829
+ function emptyAnchor() {
31830
+ return Object.freeze({
31831
+ kmsRootPubkey: EMPTY_HEX,
31832
+ appIds: Object.freeze([])
31833
+ });
31834
+ }
31835
+ var ENCLAVE_TRUST_ANCHORS = Object.freeze({
31836
+ // filled at fleet provisioning; verify fails closed while empty
31837
+ [VANA_MAINNET_CHAIN_ID]: emptyAnchor(),
31838
+ // filled at fleet provisioning; verify fails closed while empty
31839
+ [MOKSHA_CHAIN_ID]: emptyAnchor()
31840
+ });
31841
+ function userPsId(chainId, ownerAddress) {
31842
+ const packed = encodePacked(
31843
+ ["string", "uint256", "address"],
31844
+ [USER_PS_ID_DOMAIN, BigInt(chainId), getAddress(ownerAddress)]
31845
+ );
31846
+ return keccak256(packed);
31847
+ }
31848
+ function compressPublicKey(publicKey) {
31849
+ return secp256k13.ProjectivePoint.fromHex(
31850
+ fromHex5(publicKey, "bytes")
31851
+ ).toRawBytes(true);
31852
+ }
31853
+ function sameKey(a, b) {
31854
+ return toHex6(compressPublicKey(a)) === toHex6(compressPublicKey(b));
31855
+ }
31856
+ function assertUncompressedKey(publicKey) {
31857
+ const hex = publicKey.slice(2);
31858
+ if (hex.length !== UNCOMPRESSED_PUBLIC_KEY_BYTES * 2 || !hex.startsWith(UNCOMPRESSED_PUBLIC_KEY_PREFIX) || !/^[0-9a-fA-F]+$/.test(hex)) {
31859
+ throw new Error("Public key must be a 65-byte uncompressed secp256k1 key");
31860
+ }
31861
+ }
31862
+ function appRootPreimage(purpose, publicKey) {
31863
+ const keyHex = toHex6(compressPublicKey(publicKey)).slice(2);
31864
+ return keccak256(toBytes(`${purpose}${PREIMAGE_SEPARATOR}${keyHex}`));
31865
+ }
31866
+ function kmsIssuedPreimage(appId, appRootPublicKey) {
31867
+ const prefix = concat4([
31868
+ toBytes(`${KMS_ISSUED_PREFIX}${PREIMAGE_SEPARATOR}`),
31869
+ fromHex5(appId, "bytes")
31870
+ ]);
31871
+ const compressed = compressPublicKey(appRootPublicKey);
31872
+ return keccak256(concat4([prefix, compressed]));
31873
+ }
31874
+ async function recoverChainKey(hash, signature, link) {
31875
+ try {
31876
+ return (await recoverPublicKey({ hash, signature })).toLowerCase();
31877
+ } catch {
31878
+ throw new Error(`Invalid enclave signature chain link ${link}`);
31879
+ }
31880
+ }
31881
+ async function verifyEnclaveIdentityEvidence(evidence, anchors, expected) {
31882
+ if (evidence.v !== ENCLAVE_IDENTITY_EVIDENCE_VERSION) {
31883
+ throw new Error("Unsupported enclave identity evidence version");
31884
+ }
31885
+ if (!Number.isInteger(evidence.epoch) || evidence.epoch < 1) {
31886
+ throw new Error("Invalid enclave identity epoch");
31887
+ }
31888
+ if (evidence.chainId !== expected.chainId) {
31889
+ throw new Error(
31890
+ "Enclave identity chain ID does not match expected chain ID"
31891
+ );
31892
+ }
31893
+ if (!isAddressEqual(evidence.ownerAddress, expected.ownerAddress)) {
31894
+ throw new Error("Enclave identity owner does not match expected owner");
31895
+ }
31896
+ if (evidence.epoch !== expected.epoch) {
31897
+ throw new Error("Enclave identity epoch does not match expected epoch");
31898
+ }
31899
+ const expectedUserPsId = userPsId(expected.chainId, expected.ownerAddress);
31900
+ if (evidence.userPsId.toLowerCase() !== expectedUserPsId.toLowerCase()) {
31901
+ throw new Error("Enclave userPsId does not match expected identity");
31902
+ }
31903
+ if (evidence.purpose !== ENCLAVE_WALLET_PURPOSE) {
31904
+ throw new Error("Unexpected enclave wallet purpose");
31905
+ }
31906
+ if (anchors.kmsRootPubkey === EMPTY_HEX) {
31907
+ throw new Error("KMS root trust anchor is not provisioned");
31908
+ }
31909
+ assertUncompressedKey(evidence.publicKey);
31910
+ const derivedAddress = publicKeyToAddress(evidence.publicKey);
31911
+ if (getAddress(derivedAddress) !== getAddress(evidence.address)) {
31912
+ throw new Error("Enclave public key does not match its address");
31913
+ }
31914
+ const appRootPublicKey = await recoverChainKey(
31915
+ appRootPreimage(evidence.purpose, evidence.publicKey),
31916
+ evidence.signatureChain[0],
31917
+ 0
31918
+ );
31919
+ const kmsRootPublicKey = await recoverChainKey(
31920
+ kmsIssuedPreimage(evidence.appId, appRootPublicKey),
31921
+ evidence.signatureChain[1],
31922
+ 1
31923
+ );
31924
+ let matchesAnchor;
31925
+ try {
31926
+ matchesAnchor = sameKey(kmsRootPublicKey, anchors.kmsRootPubkey);
31927
+ } catch {
31928
+ throw new Error("KMS root trust anchor is malformed");
31929
+ }
31930
+ if (!matchesAnchor) {
31931
+ throw new Error("KMS root public key does not match the trust anchor");
31932
+ }
31933
+ if (keccak256(kmsRootPublicKey) !== evidence.kmsRootFingerprint.toLowerCase()) {
31934
+ throw new Error("KMS root fingerprint does not match the evidence");
31935
+ }
31936
+ const appId = evidence.appId.toLowerCase();
31937
+ if (!anchors.appIds.some((allowedAppId) => allowedAppId.toLowerCase() === appId)) {
31938
+ throw new Error("Enclave app ID is not trusted");
31939
+ }
31940
+ }
31941
+ async function buildMasterSignatureDelivery(evidence, masterSignature, now = Math.floor(Date.now() / 1e3)) {
31942
+ deriveMasterKey(masterSignature);
31943
+ const signerAddress = await recoverServerOwner(masterSignature);
31944
+ if (!isAddressEqual(signerAddress, evidence.ownerAddress)) {
31945
+ throw new Error("Master signature signer does not match evidence owner");
31946
+ }
31947
+ return {
31948
+ v: MASTER_SIGNATURE_DELIVERY_VERSION,
31949
+ userPsId: evidence.userPsId,
31950
+ epoch: evidence.epoch,
31951
+ enclaveAddress: evidence.address,
31952
+ ownerAddress: evidence.ownerAddress,
31953
+ masterSignature,
31954
+ issuedAt: now
31955
+ };
31956
+ }
31957
+ async function encryptMasterSignatureDelivery(delivery, publicKey, ecies) {
31958
+ assertUncompressedKey(publicKey);
31959
+ if (!isAddressEqual(publicKeyToAddress(publicKey), delivery.enclaveAddress)) {
31960
+ throw new Error(
31961
+ "Public key does not belong to the delivery's enclave address"
31962
+ );
31963
+ }
31964
+ const plaintext = toBytes(JSON.stringify(delivery));
31965
+ const encrypted = await ecies.encrypt(fromHex5(publicKey, "bytes"), plaintext);
31966
+ return `0x${serializeECIES(encrypted)}`;
31967
+ }
31968
+
31969
+ // src/protocol/jobs.ts
31970
+ var JOB_PROTOCOL_VERSION = 1;
31971
+ var JOB_OPERATIONS = ["raw_read", "inference"];
31972
+ var JOB_STATES = [
31973
+ "queued",
31974
+ "claimed",
31975
+ "running",
31976
+ "completed",
31977
+ "failed",
31978
+ "expired",
31979
+ "cancelled"
31980
+ ];
31981
+ var DEFAULT_LEASE_SECONDS = 30;
31982
+ var MAX_LEASE_SECONDS = 300;
31983
+ var MAX_ATTEMPTS = 3;
31984
+ var MAX_WAIT_SECONDS = 25;
31985
+ var CLAIM_POLL_FLOOR_MS = 1e3;
31986
+ var DEFAULT_JOB_DEADLINE_SECONDS = 600;
31987
+ var MAX_JOB_DEADLINE_SECONDS = 3600;
31988
+
31989
+ // src/crypto/envelope/job.ts
31990
+ init_constants();
31991
+ init_interface();
31992
+ import { sha256 as sha2565 } from "@noble/hashes/sha2";
31993
+ import { bytesToHex as bytesToHex2, fromHex as fromHex6, isAddress, isHex, toHex as toHex7 } from "viem";
31994
+ var textDecoder = new TextDecoder();
31995
+ var textEncoder = new TextEncoder();
31996
+ var JobEnvelopeError = class extends Error {
31997
+ constructor(message) {
31998
+ super(message);
31999
+ this.name = "JobEnvelopeError";
32000
+ }
32001
+ };
32002
+ function sortJsonKeys(value) {
32003
+ if (Array.isArray(value)) {
32004
+ return value.map(sortJsonKeys);
32005
+ }
32006
+ if (value !== null && typeof value === "object") {
32007
+ return Object.fromEntries(
32008
+ Object.keys(value).sort().map((key) => [
32009
+ key,
32010
+ sortJsonKeys(value[key])
32011
+ ])
32012
+ );
32013
+ }
32014
+ return value;
32015
+ }
32016
+ function canonicalJsonBytes(value) {
32017
+ return textEncoder.encode(JSON.stringify(sortJsonKeys(value)));
32018
+ }
32019
+ function canonicalJobRequestBytes(request) {
32020
+ validateJobRequest(request);
32021
+ return canonicalJsonBytes(request);
32022
+ }
32023
+ function requestPlaintext(envelope) {
32024
+ validateRequestEnvelope(envelope);
32025
+ return canonicalJsonBytes(envelope);
32026
+ }
32027
+ function resultPlaintext(result) {
32028
+ return textEncoder.encode(
32029
+ JSON.stringify({
32030
+ v: result.v,
32031
+ jobId: result.jobId,
32032
+ scope: result.scope,
32033
+ version: result.version,
32034
+ contentType: result.contentType,
32035
+ body: result.body
32036
+ })
32037
+ );
32038
+ }
32039
+ function encryptedBytesToBase64(encrypted) {
32040
+ return toBase64(fromHex6(`0x${serializeECIES(encrypted)}`, "bytes"));
32041
+ }
32042
+ function encryptedToBytes(encrypted) {
32043
+ const bytes = new Uint8Array(
32044
+ encrypted.iv.length + encrypted.ephemPublicKey.length + encrypted.ciphertext.length + encrypted.mac.length
32045
+ );
32046
+ let offset = 0;
32047
+ bytes.set(encrypted.iv, offset);
32048
+ offset += encrypted.iv.length;
32049
+ bytes.set(encrypted.ephemPublicKey, offset);
32050
+ offset += encrypted.ephemPublicKey.length;
32051
+ bytes.set(encrypted.ciphertext, offset);
32052
+ offset += encrypted.ciphertext.length;
32053
+ bytes.set(encrypted.mac, offset);
32054
+ return bytes;
32055
+ }
32056
+ function bytesToEncrypted(bytes) {
32057
+ const absoluteMinLength = FORMAT.IV_LENGTH + 1 + MAC.LENGTH + 1;
32058
+ if (bytes.length < absoluteMinLength) {
32059
+ throw new ECIESError(
32060
+ `Invalid ECIES data: too short (${bytes.length} bytes, minimum ${absoluteMinLength} bytes required)`,
32061
+ "DECRYPTION_FAILED"
32062
+ );
32063
+ }
32064
+ const prefix = bytes[FORMAT.EPHEMERAL_KEY_OFFSET];
32065
+ if (prefix !== CURVE.PREFIX.UNCOMPRESSED) {
32066
+ throw new ECIESError(
32067
+ `Invalid ephemeral public key: must be uncompressed format (0x04 prefix), got 0x${prefix.toString(16).padStart(2, "0")}`,
32068
+ "DECRYPTION_FAILED"
32069
+ );
32070
+ }
32071
+ const ephemKeySize = CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH;
32072
+ const minLength = FORMAT.IV_LENGTH + ephemKeySize + MAC.LENGTH + 1;
32073
+ if (bytes.length < minLength) {
32074
+ throw new ECIESError(
32075
+ `Invalid ECIES data: too short (${bytes.length} bytes, minimum ${minLength} bytes required)`,
32076
+ "DECRYPTION_FAILED"
32077
+ );
32078
+ }
32079
+ return {
32080
+ iv: bytes.subarray(FORMAT.IV_OFFSET, FORMAT.IV_OFFSET + FORMAT.IV_LENGTH),
32081
+ ephemPublicKey: bytes.subarray(
32082
+ FORMAT.EPHEMERAL_KEY_OFFSET,
32083
+ FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize
32084
+ ),
32085
+ ciphertext: bytes.subarray(
32086
+ FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize,
32087
+ bytes.length - MAC.LENGTH
32088
+ ),
32089
+ mac: bytes.subarray(bytes.length - MAC.LENGTH)
32090
+ };
32091
+ }
32092
+ function base64ToEncrypted(ciphertext) {
32093
+ return deserializeECIES(toHex7(fromBase64(ciphertext)));
32094
+ }
32095
+ function parseObject(plaintext, kind) {
32096
+ try {
32097
+ const value = JSON.parse(textDecoder.decode(plaintext));
32098
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
32099
+ throw new JobEnvelopeError(`Invalid ${kind}: expected an object`);
32100
+ }
32101
+ return value;
32102
+ } catch (error) {
32103
+ if (error instanceof JobEnvelopeError) throw error;
32104
+ throw new JobEnvelopeError(`Invalid ${kind}: malformed JSON`);
32105
+ }
32106
+ }
32107
+ function isPlainObject2(value) {
32108
+ if (value === null || typeof value !== "object") return false;
32109
+ const prototype = Object.getPrototypeOf(value);
32110
+ return prototype === Object.prototype || prototype === null;
32111
+ }
32112
+ function requirePlainObject(value, field, kind) {
32113
+ if (!isPlainObject2(value)) {
32114
+ throw new JobEnvelopeError(`Invalid ${kind}: invalid ${field}`);
32115
+ }
32116
+ }
32117
+ function requireExactKeys(value, expectedKeys, kind) {
32118
+ for (const key of expectedKeys) {
32119
+ if (!Object.hasOwn(value, key) || value[key] === void 0) {
32120
+ throw new JobEnvelopeError(`Invalid ${kind}: missing ${key}`);
32121
+ }
32122
+ }
32123
+ const expected = new Set(expectedKeys);
32124
+ for (const key of Reflect.ownKeys(value)) {
32125
+ if (!expected.has(key)) {
32126
+ throw new JobEnvelopeError(
32127
+ `Invalid ${kind}: unknown field ${String(key)}`
32128
+ );
32129
+ }
32130
+ }
32131
+ }
32132
+ function requireString(value, field, kind) {
32133
+ if (typeof value !== "string" || value.length === 0) {
32134
+ throw new JobEnvelopeError(`Invalid ${kind}: missing ${field}`);
32135
+ }
32136
+ }
32137
+ function validateJobRequest(value) {
32138
+ requirePlainObject(value, "request", "job request");
32139
+ requireExactKeys(
32140
+ value,
32141
+ [
32142
+ "v",
32143
+ "jobId",
32144
+ "owner",
32145
+ "builder",
32146
+ "builderPublicKey",
32147
+ "grantId",
32148
+ "scope",
32149
+ "operation",
32150
+ "pinnedVersion",
32151
+ "deadline"
32152
+ ],
32153
+ "job request"
32154
+ );
32155
+ if (value.v !== JOB_PROTOCOL_VERSION) {
32156
+ throw new JobEnvelopeError(
32157
+ `Unsupported job request version: ${String(value.v)}`
32158
+ );
32159
+ }
32160
+ requireString(value.jobId, "jobId", "job request");
32161
+ if (typeof value.owner !== "string" || !isAddress(value.owner)) {
32162
+ throw new JobEnvelopeError("Invalid job request: invalid owner");
32163
+ }
32164
+ if (typeof value.builder !== "string" || !isAddress(value.builder)) {
32165
+ throw new JobEnvelopeError("Invalid job request: invalid builder");
32166
+ }
32167
+ if (typeof value.builderPublicKey !== "string" || !isHex(value.builderPublicKey)) {
32168
+ throw new JobEnvelopeError("Invalid job request: invalid builderPublicKey");
32169
+ }
32170
+ if (typeof value.grantId !== "string" || !isHex(value.grantId)) {
32171
+ throw new JobEnvelopeError("Invalid job request: invalid grantId");
32172
+ }
32173
+ requireString(value.scope, "scope", "job request");
32174
+ if (!JOB_OPERATIONS.includes(value.operation)) {
32175
+ throw new JobEnvelopeError("Invalid job request: invalid operation");
32176
+ }
32177
+ if (value.pinnedVersion !== null && typeof value.pinnedVersion !== "string") {
32178
+ throw new JobEnvelopeError("Invalid job request: missing pinnedVersion");
32179
+ }
32180
+ if (typeof value.deadline !== "string" || !Number.isFinite(Date.parse(value.deadline))) {
32181
+ throw new JobEnvelopeError("Invalid job request: invalid deadline");
32182
+ }
32183
+ return value;
32184
+ }
32185
+ function validateRequestEnvelope(value) {
32186
+ requirePlainObject(value, "envelope", "job request envelope");
32187
+ requireExactKeys(value, ["request", "auth"], "job request envelope");
32188
+ validateJobRequest(value.request);
32189
+ requireString(value.auth, "auth", "job request envelope");
32190
+ return value;
32191
+ }
32192
+ function validateResult(value) {
32193
+ requirePlainObject(value, "result", "job result");
32194
+ requireExactKeys(
32195
+ value,
32196
+ ["v", "jobId", "scope", "version", "contentType", "body"],
32197
+ "job result"
32198
+ );
32199
+ if (value.v !== JOB_PROTOCOL_VERSION) {
32200
+ throw new JobEnvelopeError(
32201
+ `Unsupported job result version: ${String(value.v)}`
32202
+ );
32203
+ }
32204
+ for (const field of ["jobId", "scope", "contentType"]) {
32205
+ requireString(value[field], field, "job result");
32206
+ }
32207
+ if (typeof value.body !== "string") {
32208
+ throw new JobEnvelopeError("Invalid job result: missing body");
32209
+ }
32210
+ if (value.version !== null && typeof value.version !== "string") {
32211
+ throw new JobEnvelopeError("Invalid job result: missing version");
32212
+ }
32213
+ return value;
32214
+ }
32215
+ async function sealJobRequest(envelope, enclavePublicKey, ecies) {
32216
+ const encrypted = await ecies.encrypt(
32217
+ fromHex6(enclavePublicKey, "bytes"),
32218
+ requestPlaintext(envelope)
32219
+ );
32220
+ return encryptedBytesToBase64(encrypted);
32221
+ }
32222
+ async function openJobRequest(ciphertext, privateKey, ecies) {
32223
+ const plaintext = await ecies.decrypt(
32224
+ privateKey,
32225
+ base64ToEncrypted(ciphertext)
32226
+ );
32227
+ return validateRequestEnvelope(
32228
+ parseObject(plaintext, "job request envelope")
32229
+ );
32230
+ }
32231
+ async function sealJobResult(result, builderPublicKey, ecies) {
32232
+ validateResult(result);
32233
+ const encrypted = await ecies.encrypt(
32234
+ fromHex6(builderPublicKey, "bytes"),
32235
+ resultPlaintext(result)
32236
+ );
32237
+ const bytes = encryptedToBytes(encrypted);
32238
+ return { bytes, hash: bytesToHex2(sha2565(bytes)), size: bytes.length };
32239
+ }
32240
+ async function openJobResult(sealedBytes, builderPrivateKey, ecies, expect) {
32241
+ const plaintext = await ecies.decrypt(
32242
+ fromHex6(builderPrivateKey, "bytes"),
32243
+ bytesToEncrypted(sealedBytes)
32244
+ );
32245
+ const result = validateResult(parseObject(plaintext, "job result"));
32246
+ if (result.jobId !== expect.jobId) {
32247
+ throw new JobEnvelopeError(
32248
+ `Job result ID ${result.jobId} does not match expected job ID ${expect.jobId}`
32249
+ );
32250
+ }
32251
+ if (expect.scope !== void 0 && result.scope !== expect.scope) {
32252
+ throw new JobEnvelopeError(
32253
+ `Job result scope ${result.scope} does not match expected scope ${expect.scope}`
32254
+ );
32255
+ }
32256
+ if (expect.version !== void 0 && result.version !== expect.version) {
32257
+ throw new JobEnvelopeError(
32258
+ `Job result version ${String(result.version)} does not match expected version ${String(expect.version)}`
32259
+ );
32260
+ }
32261
+ return result;
32262
+ }
32263
+
31739
32264
  // src/protocol/personal-server-registration.ts
31740
32265
  import {
31741
- isAddress
32266
+ isAddress as isAddress2
31742
32267
  } from "viem";
31743
32268
  var PERSONAL_SERVER_REGISTRATION_DEFAULT_CHAIN_ID = vanaMainnet2.id;
31744
32269
  var PERSONAL_SERVER_REGISTRATION_DEFAULT_VERIFYING_CONTRACT = getContractAddress(
@@ -31746,7 +32271,7 @@ var PERSONAL_SERVER_REGISTRATION_DEFAULT_VERIFYING_CONTRACT = getContractAddress
31746
32271
  "DataPortabilityServers"
31747
32272
  );
31748
32273
  function assertAddress(value, name) {
31749
- if (!isAddress(value)) {
32274
+ if (!isAddress2(value)) {
31750
32275
  throw new Error(`${name} must be a valid EVM address`);
31751
32276
  }
31752
32277
  }
@@ -31833,13 +32358,13 @@ var registerPersonalServerSignature = buildPersonalServerRegistrationSignature;
31833
32358
 
31834
32359
  // src/personal-server-lite/owner-binding.ts
31835
32360
  import {
31836
- isAddress as isAddress2
32361
+ isAddress as isAddress3
31837
32362
  } from "viem";
31838
32363
  var PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION = "vana.ps-lite.owner-binding.v1";
31839
32364
  var PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE = "ps-lite-owner";
31840
32365
  var PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX = `${PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION}:${PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE}:`;
31841
32366
  function assertAddress2(value, name) {
31842
- if (!isAddress2(value)) {
32367
+ if (!isAddress3(value)) {
31843
32368
  throw new Error(`${name} must be a valid EVM address`);
31844
32369
  }
31845
32370
  }
@@ -31889,7 +32414,7 @@ async function buildPersonalServerLiteOwnerBindingSignature(input) {
31889
32414
  var signPersonalServerLiteOwnerBinding = buildPersonalServerLiteOwnerBindingSignature;
31890
32415
 
31891
32416
  // src/account/personal-server-registration.ts
31892
- import { isAddress as isAddress3 } from "viem";
32417
+ import { isAddress as isAddress4 } from "viem";
31893
32418
  var ACCOUNT_PERSONAL_SERVER_REGISTRATION_INTENT = "personal_server.server_registration.v1";
31894
32419
  var AccountPersonalServerRegistrationError = class extends Error {
31895
32420
  status;
@@ -31908,7 +32433,7 @@ function trimTrailingSlash(value) {
31908
32433
  return value.replace(/\/+$/, "");
31909
32434
  }
31910
32435
  function assertAddress3(value, name) {
31911
- if (!isAddress3(value)) {
32436
+ if (!isAddress4(value)) {
31912
32437
  throw new Error(`${name} must be a valid EVM address`);
31913
32438
  }
31914
32439
  }
@@ -32434,8 +32959,8 @@ function buildMarkDataPointUnavailableRequest(config, input) {
32434
32959
 
32435
32960
  // src/protocol/data-point-deletion.ts
32436
32961
  import {
32437
- isAddress as isAddress5,
32438
- keccak256 as keccak2562,
32962
+ isAddress as isAddress6,
32963
+ keccak256 as keccak2563,
32439
32964
  maxUint256,
32440
32965
  stringToBytes as stringToBytes3
32441
32966
  } from "viem";
@@ -32443,8 +32968,8 @@ import {
32443
32968
  // src/protocol/lineage.ts
32444
32969
  import {
32445
32970
  encodeAbiParameters,
32446
- isAddress as isAddress4,
32447
- keccak256
32971
+ isAddress as isAddress5,
32972
+ keccak256 as keccak2562
32448
32973
  } from "viem";
32449
32974
  import { z } from "zod";
32450
32975
 
@@ -32523,12 +33048,12 @@ function isDataPointId(value) {
32523
33048
  return typeof value === "string" && DATA_POINT_ID_PATTERN.test(value);
32524
33049
  }
32525
33050
  function deriveDataPointId(ownerAddress, scope) {
32526
- if (!isAddress4(ownerAddress, { strict: false })) {
33051
+ if (!isAddress5(ownerAddress, { strict: false })) {
32527
33052
  throw new Error(
32528
33053
  `ownerAddress is not an EVM address: ${String(ownerAddress)}`
32529
33054
  );
32530
33055
  }
32531
- return keccak256(
33056
+ return keccak2562(
32532
33057
  encodeAbiParameters(
32533
33058
  [
32534
33059
  { name: "ownerAddress", type: "address" },
@@ -32755,7 +33280,7 @@ var TOMBSTONE_METADATA_HASH_PREIMAGE = "vana.data-point.tombstone.metadata.v1";
32755
33280
  var TOMBSTONE_DATA_HASH = "0x30c45ee72fe56d1927701316925ab7ceacd3b6f9267061735d59396f075c6222";
32756
33281
  var TOMBSTONE_METADATA_HASH = "0xc5255a141acd6a2ae55971b62c0a85977c2511989dc114ad2abc2b7644f57d90";
32757
33282
  function computeTombstoneHash(preimage) {
32758
- return keccak2562(stringToBytes3(preimage));
33283
+ return keccak2563(stringToBytes3(preimage));
32759
33284
  }
32760
33285
  function isTombstoneHashes(dataHash, metadataHash) {
32761
33286
  return typeof dataHash === "string" && typeof metadataHash === "string" && dataHash.toLowerCase() === TOMBSTONE_DATA_HASH && metadataHash.toLowerCase() === TOMBSTONE_METADATA_HASH;
@@ -32774,7 +33299,7 @@ function tombstoneDeletedAt(value) {
32774
33299
  return typeof deletedAt === "string" ? deletedAt : null;
32775
33300
  }
32776
33301
  function assertAddress4(value, name) {
32777
- if (!isAddress5(value)) {
33302
+ if (!isAddress6(value)) {
32778
33303
  throw new Error(`${name} must be a valid EVM address`);
32779
33304
  }
32780
33305
  }
@@ -33189,13 +33714,13 @@ function tryGrantPermissions(scopes) {
33189
33714
  }
33190
33715
 
33191
33716
  // src/protocol/personal-server-write.ts
33192
- import { sha256 as sha2566 } from "@noble/hashes/sha2";
33193
- import { bytesToHex as bytesToHex3, isAddress as isAddress6 } from "viem";
33717
+ import { sha256 as sha2567 } from "@noble/hashes/sha2";
33718
+ import { bytesToHex as bytesToHex4, isAddress as isAddress7 } from "viem";
33194
33719
  import { z as z4 } from "zod";
33195
33720
 
33196
33721
  // src/protocol/write-request.ts
33197
- import { sha256 as sha2565 } from "@noble/hashes/sha2";
33198
- import { bytesToHex as bytesToHex2 } from "viem";
33722
+ import { sha256 as sha2566 } from "@noble/hashes/sha2";
33723
+ import { bytesToHex as bytesToHex3 } from "viem";
33199
33724
  function normalizeBaseUrl2(url) {
33200
33725
  return url.replace(/\/+$/, "");
33201
33726
  }
@@ -33262,22 +33787,22 @@ function freshProofNonce() {
33262
33787
  return webCrypto.randomUUID();
33263
33788
  }
33264
33789
  if (typeof webCrypto?.getRandomValues === "function") {
33265
- return bytesToHex2(webCrypto.getRandomValues(new Uint8Array(16)));
33790
+ return bytesToHex3(webCrypto.getRandomValues(new Uint8Array(16)));
33266
33791
  }
33267
33792
  throw new WriteRequestError(
33268
33793
  "No secure random source available to build a proof nonce; provide a crypto global"
33269
33794
  );
33270
33795
  }
33271
33796
  function proofKeyFor(parts) {
33272
- return bytesToHex2(
33273
- sha2565(
33797
+ return bytesToHex3(
33798
+ sha2566(
33274
33799
  new TextEncoder().encode(
33275
33800
  JSON.stringify([
33276
33801
  parts.aud,
33277
33802
  parts.method,
33278
33803
  parts.uri,
33279
33804
  parts.grantId,
33280
- parts.signedBytes ? bytesToHex2(sha2565(parts.signedBytes)) : ""
33805
+ parts.signedBytes ? bytesToHex3(sha2566(parts.signedBytes)) : ""
33281
33806
  ])
33282
33807
  )
33283
33808
  )
@@ -33464,7 +33989,7 @@ function binaryWriteSignedBytes(input) {
33464
33989
  mimeType: normalizeBinaryMimeType(input.contentType),
33465
33990
  ...input.filename ? { filename: input.filename } : {},
33466
33991
  sizeBytes: input.bytes.length,
33467
- contentHash: bytesToHex3(sha2566(input.bytes)),
33992
+ contentHash: bytesToHex4(sha2567(input.bytes)),
33468
33993
  encoding: "base64",
33469
33994
  content: toBase64(input.bytes),
33470
33995
  ...metadata !== void 0 ? { metadata } : {}
@@ -33512,7 +34037,7 @@ function normalizeLineage(lineage, derivedScope) {
33512
34037
  for (const entry of lineage) {
33513
34038
  let id;
33514
34039
  if (isLineagePair(entry)) {
33515
- if (!isAddress6(entry.ownerAddress, { strict: false })) {
34040
+ if (!isAddress7(entry.ownerAddress, { strict: false })) {
33516
34041
  throw new WriteRequestError(
33517
34042
  "lineage source ownerAddress must be an EVM address",
33518
34043
  { ownerAddress: entry.ownerAddress }
@@ -34992,6 +35517,8 @@ export {
34992
35517
  BlockchainError,
34993
35518
  BrowserECIESUint8Provider as BrowserECIESProvider,
34994
35519
  BrowserPlatformAdapter,
35520
+ BuilderUnknownError,
35521
+ CLAIM_POLL_FLOOR_MS,
34995
35522
  CONTRACTS,
34996
35523
  CallbackStorage,
34997
35524
  ContractFactory,
@@ -34999,6 +35526,8 @@ export {
34999
35526
  DATA_REGISTRY_STATUS_ABI,
35000
35527
  DEFAULT_DERIVATIVE_STATUS_POLL_INTERVAL_MS,
35001
35528
  DEFAULT_DERIVATIVE_STATUS_TIMEOUT_MS,
35529
+ DEFAULT_JOB_DEADLINE_SECONDS,
35530
+ DEFAULT_LEASE_SECONDS,
35002
35531
  DEFAULT_QUESTION_POLL_INTERVAL_MS,
35003
35532
  DEFAULT_QUESTION_TIMEOUT_MS,
35004
35533
  DERIVATIVE_ERROR_CODES,
@@ -35023,6 +35552,9 @@ export {
35023
35552
  DerivativeStatusSchema,
35024
35553
  DropboxStorage,
35025
35554
  ECIESError,
35555
+ ENCLAVE_IDENTITY_EVIDENCE_VERSION,
35556
+ ENCLAVE_TRUST_ANCHORS,
35557
+ ENCLAVE_WALLET_PURPOSE,
35026
35558
  ESCROW_DEPOSIT_ABI2 as ESCROW_DEPOSIT_ABI,
35027
35559
  ExpiredTokenError,
35028
35560
  FEE_REGISTRY_ABI,
@@ -35030,12 +35562,25 @@ export {
35030
35562
  GRANT_REGISTRATION_TYPES,
35031
35563
  GRANT_REVOCATION_TYPES,
35032
35564
  GoogleDriveStorage,
35565
+ GrantInvalidError,
35033
35566
  InMemoryTokenStore,
35034
35567
  IngestResponseSchema,
35035
35568
  InvalidConfigurationError,
35036
35569
  InvalidScopeEntryError,
35037
35570
  InvalidSignatureError,
35038
35571
  IpfsStorage,
35572
+ JOB_OPERATIONS,
35573
+ JOB_PROTOCOL_VERSION,
35574
+ JOB_STATES,
35575
+ JobEnvelopeError,
35576
+ JobIdTakenError,
35577
+ JobNotFoundError,
35578
+ JobRejectedError,
35579
+ JobRequestTooLargeError,
35580
+ JobResultIntegrityError,
35581
+ JobTimeoutError,
35582
+ JobTransportError,
35583
+ JobsClientError,
35039
35584
  LINEAGE_FIELD,
35040
35585
  LINEAGE_KEY,
35041
35586
  LineageEntrySchema,
@@ -35043,16 +35588,23 @@ export {
35043
35588
  LineageNodeSchema,
35044
35589
  LineageReadError,
35045
35590
  MASTER_KEY_MESSAGE,
35591
+ MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS,
35592
+ MASTER_SIGNATURE_DELIVERY_VERSION,
35593
+ MAX_ATTEMPTS,
35594
+ MAX_JOB_DEADLINE_SECONDS,
35595
+ MAX_LEASE_SECONDS,
35046
35596
  MAX_LINEAGE_SOURCES,
35047
35597
  MAX_QUESTION_CHARS,
35048
35598
  MAX_QUESTION_MODEL_CHARS,
35049
35599
  MAX_QUESTION_SOURCE_SCOPES,
35600
+ MAX_WAIT_SECONDS,
35050
35601
  MissingAuthError,
35051
35602
  NATIVE_ASSET_ADDRESS,
35052
35603
  NATIVE_VANA_ASSET,
35053
35604
  NetworkError,
35054
35605
  NonceError,
35055
35606
  OAuthClient,
35607
+ OwnerNotReadyError,
35056
35608
  PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX,
35057
35609
  PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE,
35058
35610
  PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION,
@@ -35078,6 +35630,7 @@ export {
35078
35630
  RedactedLineageNodeSchema,
35079
35631
  RelayerError,
35080
35632
  SCOPE_ACTIONS,
35633
+ SEALED_ENVELOPE_VERSION,
35081
35634
  SERVER_REGISTRATION_TYPES,
35082
35635
  ScopeSchema,
35083
35636
  SerializationError,
@@ -35090,6 +35643,7 @@ export {
35090
35643
  TOMBSTONE_METADATA_HASH,
35091
35644
  TOMBSTONE_METADATA_HASH_PREIMAGE,
35092
35645
  TransactionPendingError,
35646
+ USER_PS_ID_DOMAIN,
35093
35647
  UserRejectedRequestError,
35094
35648
  VanaError,
35095
35649
  VanaStorage,
@@ -35108,6 +35662,7 @@ export {
35108
35662
  WriteSessionExpiredError,
35109
35663
  WriteTransportError,
35110
35664
  WriteUnauthorizedError,
35665
+ appRootPreimage,
35111
35666
  askPersonalServer,
35112
35667
  assertDerivedScopeNaming,
35113
35668
  assertValidPkceVerifier,
@@ -35117,6 +35672,7 @@ export {
35117
35672
  buildDepositNativeRequest,
35118
35673
  buildDepositTokenRequest,
35119
35674
  buildMarkDataPointUnavailableRequest,
35675
+ buildMasterSignatureDelivery,
35120
35676
  buildPersonalServerDataReadRequest,
35121
35677
  buildPersonalServerLiteOwnerBindingMessage,
35122
35678
  buildPersonalServerLiteOwnerBindingSignature,
@@ -35125,6 +35681,7 @@ export {
35125
35681
  buildSetDataPointStatusRequest,
35126
35682
  buildWeb3SignedHeader,
35127
35683
  builderRegistrationDomain,
35684
+ canonicalJobRequestBytes,
35128
35685
  chains,
35129
35686
  clearContractCache,
35130
35687
  computeBodyHash,
@@ -35156,6 +35713,7 @@ export {
35156
35713
  encodeDepositTokenData,
35157
35714
  encodeSetDataPointStatusData,
35158
35715
  encodeWriteMetadataHeader,
35716
+ encryptMasterSignatureDelivery,
35159
35717
  encryptWithPassword,
35160
35718
  escrowContractAddress,
35161
35719
  escrowPaymentDomain,
@@ -35190,12 +35748,15 @@ export {
35190
35748
  isPlatformSupported,
35191
35749
  isRedactedLineageNode,
35192
35750
  isTombstoneHashes,
35751
+ kmsIssuedPreimage,
35193
35752
  listQuestions,
35194
35753
  mainnetServices,
35195
35754
  moksha,
35196
35755
  mokshaServices,
35197
35756
  mokshaTestnet2 as mokshaTestnet,
35198
35757
  normalizeBinaryMimeType,
35758
+ openJobRequest,
35759
+ openJobResult,
35199
35760
  openWriteSession,
35200
35761
  parsePSError,
35201
35762
  parseScope,
@@ -35216,6 +35777,8 @@ export {
35216
35777
  scopeMatchesPattern,
35217
35778
  scopeNamespace,
35218
35779
  scopeToPathSegments,
35780
+ sealJobRequest,
35781
+ sealJobResult,
35219
35782
  serializeECIES,
35220
35783
  serverRegistrationDomain,
35221
35784
  sessionCoversScope,
@@ -35224,7 +35787,9 @@ export {
35224
35787
  signPersonalServerRegistrationWithAccount,
35225
35788
  tombstoneDeletedAt,
35226
35789
  tryGrantPermissions,
35790
+ userPsId,
35227
35791
  vanaMainnet2 as vanaMainnet,
35792
+ verifyEnclaveIdentityEvidence,
35228
35793
  verifyGrantRegistration,
35229
35794
  verifyPkceChallenge,
35230
35795
  verifyWeb3Signed,