@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.
- package/dist/crypto/envelope/job.cjs +313 -0
- package/dist/crypto/envelope/job.cjs.map +1 -0
- package/dist/crypto/envelope/job.d.ts +122 -0
- package/dist/crypto/envelope/job.js +291 -0
- package/dist/crypto/envelope/job.js.map +1 -0
- package/dist/direct/access-request-client.cjs +4 -0
- package/dist/direct/access-request-client.cjs.map +1 -1
- package/dist/direct/access-request-client.js +4 -0
- package/dist/direct/access-request-client.js.map +1 -1
- package/dist/direct/connect-flow.cjs +43 -1
- package/dist/direct/connect-flow.cjs.map +1 -1
- package/dist/direct/connect-flow.d.ts +12 -0
- package/dist/direct/connect-flow.js +43 -1
- package/dist/direct/connect-flow.js.map +1 -1
- package/dist/direct/types.cjs.map +1 -1
- package/dist/direct/types.d.ts +7 -0
- package/dist/direct/types.js.map +1 -1
- package/dist/direct/use-direct-vana-connect.cjs +2 -1
- package/dist/direct/use-direct-vana-connect.cjs.map +1 -1
- package/dist/direct/use-direct-vana-connect.d.ts +3 -1
- package/dist/direct/use-direct-vana-connect.js +2 -1
- package/dist/direct/use-direct-vana-connect.js.map +1 -1
- package/dist/errors.cjs +84 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +133 -0
- package/dist/errors.js +73 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.browser.d.ts +3 -0
- package/dist/index.browser.js +589 -24
- package/dist/index.browser.js.map +4 -4
- package/dist/index.node.cjs +1217 -111
- package/dist/index.node.cjs.map +4 -4
- package/dist/index.node.d.ts +4 -0
- package/dist/index.node.js +1181 -101
- package/dist/index.node.js.map +4 -4
- package/dist/protocol/identity.cjs +219 -0
- package/dist/protocol/identity.cjs.map +1 -0
- package/dist/protocol/identity.d.ts +193 -0
- package/dist/protocol/identity.js +183 -0
- package/dist/protocol/identity.js.map +1 -0
- package/dist/protocol/identity.test.d.ts +1 -0
- package/dist/protocol/identity.vector.test.d.ts +1 -0
- package/dist/protocol/jobs-client.cjs +540 -0
- package/dist/protocol/jobs-client.cjs.map +1 -0
- package/dist/protocol/jobs-client.d.ts +169 -0
- package/dist/protocol/jobs-client.js +547 -0
- package/dist/protocol/jobs-client.js.map +1 -0
- package/dist/protocol/jobs-client.test.d.ts +1 -0
- package/dist/protocol/jobs.cjs +64 -0
- package/dist/protocol/jobs.cjs.map +1 -0
- package/dist/protocol/jobs.d.ts +192 -0
- package/dist/protocol/jobs.js +31 -0
- package/dist/protocol/jobs.js.map +1 -0
- package/dist/protocol/jobs.test.d.ts +1 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js.map +1 -1
- package/package.json +7 -1
package/dist/index.node.js
CHANGED
|
@@ -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
|
|
31412
|
+
const secp256k15 = secp256k1Import2;
|
|
31351
31413
|
let privateKey;
|
|
31352
31414
|
do {
|
|
31353
31415
|
privateKey = randomBytes2(32);
|
|
31354
|
-
} while (!
|
|
31416
|
+
} while (!secp256k15.privateKeyVerify(privateKey));
|
|
31355
31417
|
const publicKey = Buffer.from(
|
|
31356
|
-
|
|
31418
|
+
secp256k15.publicKeyCreate(privateKey, true)
|
|
31357
31419
|
);
|
|
31358
31420
|
return {
|
|
31359
31421
|
privateKey: privateKey.toString("hex"),
|
|
@@ -32363,9 +32425,1026 @@ 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 JobEnvelopeError = class extends Error {
|
|
32635
|
+
constructor(message) {
|
|
32636
|
+
super(message);
|
|
32637
|
+
this.name = "JobEnvelopeError";
|
|
32638
|
+
}
|
|
32639
|
+
};
|
|
32640
|
+
function sortJsonKeys(value) {
|
|
32641
|
+
if (Array.isArray(value)) {
|
|
32642
|
+
return value.map(sortJsonKeys);
|
|
32643
|
+
}
|
|
32644
|
+
if (value !== null && typeof value === "object") {
|
|
32645
|
+
return Object.fromEntries(
|
|
32646
|
+
Object.keys(value).sort().map((key) => [
|
|
32647
|
+
key,
|
|
32648
|
+
sortJsonKeys(value[key])
|
|
32649
|
+
])
|
|
32650
|
+
);
|
|
32651
|
+
}
|
|
32652
|
+
return value;
|
|
32653
|
+
}
|
|
32654
|
+
function canonicalJsonBytes(value) {
|
|
32655
|
+
return textEncoder.encode(JSON.stringify(sortJsonKeys(value)));
|
|
32656
|
+
}
|
|
32657
|
+
function canonicalJobRequestBytes(request) {
|
|
32658
|
+
validateJobRequest(request);
|
|
32659
|
+
return canonicalJsonBytes(request);
|
|
32660
|
+
}
|
|
32661
|
+
function requestPlaintext(envelope) {
|
|
32662
|
+
validateRequestEnvelope(envelope);
|
|
32663
|
+
return canonicalJsonBytes(envelope);
|
|
32664
|
+
}
|
|
32665
|
+
function resultPlaintext(result) {
|
|
32666
|
+
return textEncoder.encode(
|
|
32667
|
+
JSON.stringify({
|
|
32668
|
+
v: result.v,
|
|
32669
|
+
jobId: result.jobId,
|
|
32670
|
+
scope: result.scope,
|
|
32671
|
+
version: result.version,
|
|
32672
|
+
contentType: result.contentType,
|
|
32673
|
+
body: result.body
|
|
32674
|
+
})
|
|
32675
|
+
);
|
|
32676
|
+
}
|
|
32677
|
+
function encryptedBytesToBase64(encrypted) {
|
|
32678
|
+
return toBase64(fromHex6(`0x${serializeECIES(encrypted)}`, "bytes"));
|
|
32679
|
+
}
|
|
32680
|
+
function encryptedToBytes(encrypted) {
|
|
32681
|
+
const bytes = new Uint8Array(
|
|
32682
|
+
encrypted.iv.length + encrypted.ephemPublicKey.length + encrypted.ciphertext.length + encrypted.mac.length
|
|
32683
|
+
);
|
|
32684
|
+
let offset = 0;
|
|
32685
|
+
bytes.set(encrypted.iv, offset);
|
|
32686
|
+
offset += encrypted.iv.length;
|
|
32687
|
+
bytes.set(encrypted.ephemPublicKey, offset);
|
|
32688
|
+
offset += encrypted.ephemPublicKey.length;
|
|
32689
|
+
bytes.set(encrypted.ciphertext, offset);
|
|
32690
|
+
offset += encrypted.ciphertext.length;
|
|
32691
|
+
bytes.set(encrypted.mac, offset);
|
|
32692
|
+
return bytes;
|
|
32693
|
+
}
|
|
32694
|
+
function bytesToEncrypted(bytes) {
|
|
32695
|
+
const absoluteMinLength = FORMAT.IV_LENGTH + 1 + MAC.LENGTH + 1;
|
|
32696
|
+
if (bytes.length < absoluteMinLength) {
|
|
32697
|
+
throw new ECIESError(
|
|
32698
|
+
`Invalid ECIES data: too short (${bytes.length} bytes, minimum ${absoluteMinLength} bytes required)`,
|
|
32699
|
+
"DECRYPTION_FAILED"
|
|
32700
|
+
);
|
|
32701
|
+
}
|
|
32702
|
+
const prefix = bytes[FORMAT.EPHEMERAL_KEY_OFFSET];
|
|
32703
|
+
if (prefix !== CURVE.PREFIX.UNCOMPRESSED) {
|
|
32704
|
+
throw new ECIESError(
|
|
32705
|
+
`Invalid ephemeral public key: must be uncompressed format (0x04 prefix), got 0x${prefix.toString(16).padStart(2, "0")}`,
|
|
32706
|
+
"DECRYPTION_FAILED"
|
|
32707
|
+
);
|
|
32708
|
+
}
|
|
32709
|
+
const ephemKeySize = CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH;
|
|
32710
|
+
const minLength = FORMAT.IV_LENGTH + ephemKeySize + MAC.LENGTH + 1;
|
|
32711
|
+
if (bytes.length < minLength) {
|
|
32712
|
+
throw new ECIESError(
|
|
32713
|
+
`Invalid ECIES data: too short (${bytes.length} bytes, minimum ${minLength} bytes required)`,
|
|
32714
|
+
"DECRYPTION_FAILED"
|
|
32715
|
+
);
|
|
32716
|
+
}
|
|
32717
|
+
return {
|
|
32718
|
+
iv: bytes.subarray(FORMAT.IV_OFFSET, FORMAT.IV_OFFSET + FORMAT.IV_LENGTH),
|
|
32719
|
+
ephemPublicKey: bytes.subarray(
|
|
32720
|
+
FORMAT.EPHEMERAL_KEY_OFFSET,
|
|
32721
|
+
FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize
|
|
32722
|
+
),
|
|
32723
|
+
ciphertext: bytes.subarray(
|
|
32724
|
+
FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize,
|
|
32725
|
+
bytes.length - MAC.LENGTH
|
|
32726
|
+
),
|
|
32727
|
+
mac: bytes.subarray(bytes.length - MAC.LENGTH)
|
|
32728
|
+
};
|
|
32729
|
+
}
|
|
32730
|
+
function base64ToEncrypted(ciphertext) {
|
|
32731
|
+
return deserializeECIES(toHex8(fromBase64(ciphertext)));
|
|
32732
|
+
}
|
|
32733
|
+
function parseObject(plaintext, kind) {
|
|
32734
|
+
try {
|
|
32735
|
+
const value = JSON.parse(textDecoder.decode(plaintext));
|
|
32736
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
32737
|
+
throw new JobEnvelopeError(`Invalid ${kind}: expected an object`);
|
|
32738
|
+
}
|
|
32739
|
+
return value;
|
|
32740
|
+
} catch (error) {
|
|
32741
|
+
if (error instanceof JobEnvelopeError) throw error;
|
|
32742
|
+
throw new JobEnvelopeError(`Invalid ${kind}: malformed JSON`);
|
|
32743
|
+
}
|
|
32744
|
+
}
|
|
32745
|
+
function isPlainObject2(value) {
|
|
32746
|
+
if (value === null || typeof value !== "object") return false;
|
|
32747
|
+
const prototype = Object.getPrototypeOf(value);
|
|
32748
|
+
return prototype === Object.prototype || prototype === null;
|
|
32749
|
+
}
|
|
32750
|
+
function requirePlainObject(value, field, kind) {
|
|
32751
|
+
if (!isPlainObject2(value)) {
|
|
32752
|
+
throw new JobEnvelopeError(`Invalid ${kind}: invalid ${field}`);
|
|
32753
|
+
}
|
|
32754
|
+
}
|
|
32755
|
+
function requireExactKeys(value, expectedKeys, kind) {
|
|
32756
|
+
for (const key of expectedKeys) {
|
|
32757
|
+
if (!Object.hasOwn(value, key) || value[key] === void 0) {
|
|
32758
|
+
throw new JobEnvelopeError(`Invalid ${kind}: missing ${key}`);
|
|
32759
|
+
}
|
|
32760
|
+
}
|
|
32761
|
+
const expected = new Set(expectedKeys);
|
|
32762
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
32763
|
+
if (!expected.has(key)) {
|
|
32764
|
+
throw new JobEnvelopeError(
|
|
32765
|
+
`Invalid ${kind}: unknown field ${String(key)}`
|
|
32766
|
+
);
|
|
32767
|
+
}
|
|
32768
|
+
}
|
|
32769
|
+
}
|
|
32770
|
+
function requireString(value, field, kind) {
|
|
32771
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
32772
|
+
throw new JobEnvelopeError(`Invalid ${kind}: missing ${field}`);
|
|
32773
|
+
}
|
|
32774
|
+
}
|
|
32775
|
+
function validateJobRequest(value) {
|
|
32776
|
+
requirePlainObject(value, "request", "job request");
|
|
32777
|
+
requireExactKeys(
|
|
32778
|
+
value,
|
|
32779
|
+
[
|
|
32780
|
+
"v",
|
|
32781
|
+
"jobId",
|
|
32782
|
+
"owner",
|
|
32783
|
+
"builder",
|
|
32784
|
+
"builderPublicKey",
|
|
32785
|
+
"grantId",
|
|
32786
|
+
"scope",
|
|
32787
|
+
"operation",
|
|
32788
|
+
"pinnedVersion",
|
|
32789
|
+
"deadline"
|
|
32790
|
+
],
|
|
32791
|
+
"job request"
|
|
32792
|
+
);
|
|
32793
|
+
if (value.v !== JOB_PROTOCOL_VERSION) {
|
|
32794
|
+
throw new JobEnvelopeError(
|
|
32795
|
+
`Unsupported job request version: ${String(value.v)}`
|
|
32796
|
+
);
|
|
32797
|
+
}
|
|
32798
|
+
requireString(value.jobId, "jobId", "job request");
|
|
32799
|
+
if (typeof value.owner !== "string" || !isAddress(value.owner)) {
|
|
32800
|
+
throw new JobEnvelopeError("Invalid job request: invalid owner");
|
|
32801
|
+
}
|
|
32802
|
+
if (typeof value.builder !== "string" || !isAddress(value.builder)) {
|
|
32803
|
+
throw new JobEnvelopeError("Invalid job request: invalid builder");
|
|
32804
|
+
}
|
|
32805
|
+
if (typeof value.builderPublicKey !== "string" || !isHex(value.builderPublicKey)) {
|
|
32806
|
+
throw new JobEnvelopeError("Invalid job request: invalid builderPublicKey");
|
|
32807
|
+
}
|
|
32808
|
+
if (typeof value.grantId !== "string" || !isHex(value.grantId)) {
|
|
32809
|
+
throw new JobEnvelopeError("Invalid job request: invalid grantId");
|
|
32810
|
+
}
|
|
32811
|
+
requireString(value.scope, "scope", "job request");
|
|
32812
|
+
if (!JOB_OPERATIONS.includes(value.operation)) {
|
|
32813
|
+
throw new JobEnvelopeError("Invalid job request: invalid operation");
|
|
32814
|
+
}
|
|
32815
|
+
if (value.pinnedVersion !== null && typeof value.pinnedVersion !== "string") {
|
|
32816
|
+
throw new JobEnvelopeError("Invalid job request: missing pinnedVersion");
|
|
32817
|
+
}
|
|
32818
|
+
if (typeof value.deadline !== "string" || !Number.isFinite(Date.parse(value.deadline))) {
|
|
32819
|
+
throw new JobEnvelopeError("Invalid job request: invalid deadline");
|
|
32820
|
+
}
|
|
32821
|
+
return value;
|
|
32822
|
+
}
|
|
32823
|
+
function validateRequestEnvelope(value) {
|
|
32824
|
+
requirePlainObject(value, "envelope", "job request envelope");
|
|
32825
|
+
requireExactKeys(value, ["request", "auth"], "job request envelope");
|
|
32826
|
+
validateJobRequest(value.request);
|
|
32827
|
+
requireString(value.auth, "auth", "job request envelope");
|
|
32828
|
+
return value;
|
|
32829
|
+
}
|
|
32830
|
+
function validateResult(value) {
|
|
32831
|
+
requirePlainObject(value, "result", "job result");
|
|
32832
|
+
requireExactKeys(
|
|
32833
|
+
value,
|
|
32834
|
+
["v", "jobId", "scope", "version", "contentType", "body"],
|
|
32835
|
+
"job result"
|
|
32836
|
+
);
|
|
32837
|
+
if (value.v !== JOB_PROTOCOL_VERSION) {
|
|
32838
|
+
throw new JobEnvelopeError(
|
|
32839
|
+
`Unsupported job result version: ${String(value.v)}`
|
|
32840
|
+
);
|
|
32841
|
+
}
|
|
32842
|
+
for (const field of ["jobId", "scope", "contentType"]) {
|
|
32843
|
+
requireString(value[field], field, "job result");
|
|
32844
|
+
}
|
|
32845
|
+
if (typeof value.body !== "string") {
|
|
32846
|
+
throw new JobEnvelopeError("Invalid job result: missing body");
|
|
32847
|
+
}
|
|
32848
|
+
if (value.version !== null && typeof value.version !== "string") {
|
|
32849
|
+
throw new JobEnvelopeError("Invalid job result: missing version");
|
|
32850
|
+
}
|
|
32851
|
+
return value;
|
|
32852
|
+
}
|
|
32853
|
+
async function sealJobRequest(envelope, enclavePublicKey, ecies) {
|
|
32854
|
+
const encrypted = await ecies.encrypt(
|
|
32855
|
+
fromHex6(enclavePublicKey, "bytes"),
|
|
32856
|
+
requestPlaintext(envelope)
|
|
32857
|
+
);
|
|
32858
|
+
return encryptedBytesToBase64(encrypted);
|
|
32859
|
+
}
|
|
32860
|
+
async function openJobRequest(ciphertext, privateKey, ecies) {
|
|
32861
|
+
const plaintext = await ecies.decrypt(
|
|
32862
|
+
privateKey,
|
|
32863
|
+
base64ToEncrypted(ciphertext)
|
|
32864
|
+
);
|
|
32865
|
+
return validateRequestEnvelope(
|
|
32866
|
+
parseObject(plaintext, "job request envelope")
|
|
32867
|
+
);
|
|
32868
|
+
}
|
|
32869
|
+
async function sealJobResult(result, builderPublicKey, ecies) {
|
|
32870
|
+
validateResult(result);
|
|
32871
|
+
const encrypted = await ecies.encrypt(
|
|
32872
|
+
fromHex6(builderPublicKey, "bytes"),
|
|
32873
|
+
resultPlaintext(result)
|
|
32874
|
+
);
|
|
32875
|
+
const bytes = encryptedToBytes(encrypted);
|
|
32876
|
+
return { bytes, hash: bytesToHex2(sha2565(bytes)), size: bytes.length };
|
|
32877
|
+
}
|
|
32878
|
+
async function openJobResult(sealedBytes, builderPrivateKey, ecies, expect) {
|
|
32879
|
+
const plaintext = await ecies.decrypt(
|
|
32880
|
+
fromHex6(builderPrivateKey, "bytes"),
|
|
32881
|
+
bytesToEncrypted(sealedBytes)
|
|
32882
|
+
);
|
|
32883
|
+
const result = validateResult(parseObject(plaintext, "job result"));
|
|
32884
|
+
if (result.jobId !== expect.jobId) {
|
|
32885
|
+
throw new JobEnvelopeError(
|
|
32886
|
+
`Job result ID ${result.jobId} does not match expected job ID ${expect.jobId}`
|
|
32887
|
+
);
|
|
32888
|
+
}
|
|
32889
|
+
if (expect.scope !== void 0 && result.scope !== expect.scope) {
|
|
32890
|
+
throw new JobEnvelopeError(
|
|
32891
|
+
`Job result scope ${result.scope} does not match expected scope ${expect.scope}`
|
|
32892
|
+
);
|
|
32893
|
+
}
|
|
32894
|
+
if (expect.version !== void 0 && result.version !== expect.version) {
|
|
32895
|
+
throw new JobEnvelopeError(
|
|
32896
|
+
`Job result version ${String(result.version)} does not match expected version ${String(expect.version)}`
|
|
32897
|
+
);
|
|
32898
|
+
}
|
|
32899
|
+
return result;
|
|
32900
|
+
}
|
|
32901
|
+
|
|
32902
|
+
// src/protocol/write-signer.ts
|
|
32903
|
+
function isRecord(value) {
|
|
32904
|
+
return value !== null && typeof value === "object";
|
|
32905
|
+
}
|
|
32906
|
+
function isViemWriteAccount(source) {
|
|
32907
|
+
return isRecord(source) && source.type === "local" && typeof source.address === "string" && typeof source.signMessage === "function";
|
|
32908
|
+
}
|
|
32909
|
+
function isViemWriteWalletClient(source) {
|
|
32910
|
+
return isRecord(source) && typeof source.signMessage === "function" && source.type !== "local" && (source.type === "walletClient" || "transport" in source);
|
|
32911
|
+
}
|
|
32912
|
+
function accountAddress(account) {
|
|
32913
|
+
return typeof account === "string" ? account : account.address;
|
|
32914
|
+
}
|
|
32915
|
+
function resolveWriteSigner(source, options = {}) {
|
|
32916
|
+
if (isViemWriteWalletClient(source)) {
|
|
32917
|
+
const account = options.account ?? source.account;
|
|
32918
|
+
if (account === void 0) {
|
|
32919
|
+
throw new WriteRequestError(
|
|
32920
|
+
"Viem wallet client requires an account option or account property"
|
|
32921
|
+
);
|
|
32922
|
+
}
|
|
32923
|
+
return {
|
|
32924
|
+
address: accountAddress(account),
|
|
32925
|
+
signMessage: (message) => source.signMessage({ account, message })
|
|
32926
|
+
};
|
|
32927
|
+
}
|
|
32928
|
+
if (isViemWriteAccount(source)) {
|
|
32929
|
+
return {
|
|
32930
|
+
address: source.address,
|
|
32931
|
+
signMessage: (message) => source.signMessage({ message })
|
|
32932
|
+
};
|
|
32933
|
+
}
|
|
32934
|
+
if (!isRecord(source) || typeof source.signMessage !== "function") {
|
|
32935
|
+
throw new WriteRequestError(
|
|
32936
|
+
"signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
|
|
32937
|
+
);
|
|
32938
|
+
}
|
|
32939
|
+
return source;
|
|
32940
|
+
}
|
|
32941
|
+
|
|
32942
|
+
// src/protocol/jobs-client.ts
|
|
32943
|
+
var IDENTITY_PATH = "/v1/identity";
|
|
32944
|
+
var JOBS_PATH = "/v1/jobs";
|
|
32945
|
+
var JOB_EXECUTE_PATH = "/v1/jobs/execute";
|
|
32946
|
+
var AUTHORIZATION_HEADER = "Authorization";
|
|
32947
|
+
var CONTENT_TYPE_HEADER = "Content-Type";
|
|
32948
|
+
var JSON_CONTENT_TYPE = "application/json";
|
|
32949
|
+
var GET_METHOD = "GET";
|
|
32950
|
+
var POST_METHOD = "POST";
|
|
32951
|
+
var RAW_READ_OPERATION = "raw_read";
|
|
32952
|
+
var SEALED_IDENTITY_STATE = "sealed";
|
|
32953
|
+
var HTTP_OK = 200;
|
|
32954
|
+
var HTTP_ACCEPTED = 202;
|
|
32955
|
+
var HTTP_UNAUTHORIZED = 401;
|
|
32956
|
+
var HTTP_FORBIDDEN = 403;
|
|
32957
|
+
var HTTP_NOT_FOUND = 404;
|
|
32958
|
+
var HTTP_CONFLICT = 409;
|
|
32959
|
+
var HTTP_PAYLOAD_TOO_LARGE = 413;
|
|
32960
|
+
var MILLISECONDS_PER_SECOND = 1e3;
|
|
32961
|
+
var DEFAULT_JOB_TIMEOUT_MS = 12e4;
|
|
32962
|
+
var DEFAULT_JOB_POLL_MS = CLAIM_POLL_FLOOR_MS;
|
|
32963
|
+
var TERMINAL_JOB_STATES = /* @__PURE__ */ new Set([
|
|
32964
|
+
"completed",
|
|
32965
|
+
"failed",
|
|
32966
|
+
"expired",
|
|
32967
|
+
"cancelled"
|
|
32968
|
+
]);
|
|
32969
|
+
function isRecord2(value) {
|
|
32970
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
32971
|
+
}
|
|
32972
|
+
function normalizeGateway(gatewayUrl) {
|
|
32973
|
+
try {
|
|
32974
|
+
const url = new URL(gatewayUrl);
|
|
32975
|
+
if (url.pathname !== "/" || url.search !== "" || url.hash !== "") {
|
|
32976
|
+
throw new JobRejectedError(
|
|
32977
|
+
"gatewayUrl must be an origin without a path, query, or fragment"
|
|
32978
|
+
);
|
|
32979
|
+
}
|
|
32980
|
+
return {
|
|
32981
|
+
baseUrl: url.origin,
|
|
32982
|
+
audience: url.origin
|
|
32983
|
+
};
|
|
32984
|
+
} catch (error) {
|
|
32985
|
+
if (error instanceof JobRejectedError) throw error;
|
|
32986
|
+
throw new JobRejectedError(
|
|
32987
|
+
"gatewayUrl must be an absolute URL",
|
|
32988
|
+
void 0,
|
|
32989
|
+
null,
|
|
32990
|
+
{
|
|
32991
|
+
cause: error instanceof Error ? error.message : String(error)
|
|
32992
|
+
}
|
|
32993
|
+
);
|
|
32994
|
+
}
|
|
32995
|
+
}
|
|
32996
|
+
function resolveFetch(fetchFn) {
|
|
32997
|
+
const resolved = fetchFn ?? globalThis.fetch;
|
|
32998
|
+
if (resolved === void 0) {
|
|
32999
|
+
throw new JobRejectedError("No fetch implementation available");
|
|
33000
|
+
}
|
|
33001
|
+
return resolved;
|
|
33002
|
+
}
|
|
33003
|
+
function sourcePublicKey(source) {
|
|
33004
|
+
if (isRecord2(source) && typeof source["publicKey"] === "string") {
|
|
33005
|
+
return source["publicKey"];
|
|
33006
|
+
}
|
|
33007
|
+
return void 0;
|
|
33008
|
+
}
|
|
33009
|
+
function resolveBuilder(options) {
|
|
33010
|
+
if (options.builderPrivateKey && options.builderAccount) {
|
|
33011
|
+
throw new JobRejectedError(
|
|
33012
|
+
"Provide builderPrivateKey or builderAccount, not both"
|
|
33013
|
+
);
|
|
33014
|
+
}
|
|
33015
|
+
let source;
|
|
33016
|
+
try {
|
|
33017
|
+
source = options.builderPrivateKey ? privateKeyToAccount(options.builderPrivateKey) : options.builderAccount;
|
|
33018
|
+
} catch (error) {
|
|
33019
|
+
throw new JobRejectedError("Invalid builder private key", void 0, null, {
|
|
33020
|
+
cause: error instanceof Error ? error.message : String(error)
|
|
33021
|
+
});
|
|
33022
|
+
}
|
|
33023
|
+
if (!source) {
|
|
33024
|
+
throw new JobRejectedError(
|
|
33025
|
+
"builderPrivateKey or builderAccount is required"
|
|
33026
|
+
);
|
|
33027
|
+
}
|
|
33028
|
+
let signer;
|
|
33029
|
+
try {
|
|
33030
|
+
signer = resolveWriteSigner(source);
|
|
33031
|
+
} catch (error) {
|
|
33032
|
+
throw new JobRejectedError("Invalid builder signer", void 0, null, {
|
|
33033
|
+
cause: error instanceof Error ? error.message : String(error)
|
|
33034
|
+
});
|
|
33035
|
+
}
|
|
33036
|
+
const publicKey = sourcePublicKey(source);
|
|
33037
|
+
if (!signer.address || !publicKey) {
|
|
33038
|
+
throw new JobRejectedError(
|
|
33039
|
+
"Builder signer must expose both address and publicKey"
|
|
33040
|
+
);
|
|
33041
|
+
}
|
|
33042
|
+
return {
|
|
33043
|
+
builder: {
|
|
33044
|
+
address: signer.address,
|
|
33045
|
+
publicKey,
|
|
33046
|
+
signMessage: signer.signMessage
|
|
33047
|
+
},
|
|
33048
|
+
...options.builderPrivateKey ? { privateKey: options.builderPrivateKey } : {}
|
|
33049
|
+
};
|
|
33050
|
+
}
|
|
33051
|
+
function clampInteger(value, fallback, minimum, maximum, field) {
|
|
33052
|
+
const resolved = value ?? fallback;
|
|
33053
|
+
if (!Number.isFinite(resolved)) {
|
|
33054
|
+
throw new JobRejectedError(`${field} must be a finite number`);
|
|
33055
|
+
}
|
|
33056
|
+
return Math.min(maximum, Math.max(minimum, Math.trunc(resolved)));
|
|
33057
|
+
}
|
|
33058
|
+
async function responseBody(response) {
|
|
33059
|
+
try {
|
|
33060
|
+
return await response.json();
|
|
33061
|
+
} catch {
|
|
33062
|
+
return null;
|
|
33063
|
+
}
|
|
33064
|
+
}
|
|
33065
|
+
function gatewayErrorBody(body, fallback) {
|
|
33066
|
+
if (!isRecord2(body)) return { code: null, message: fallback };
|
|
33067
|
+
const code = typeof body["code"] === "string" ? body["code"] : null;
|
|
33068
|
+
const message = typeof body["error"] === "string" ? body["error"] : typeof body["message"] === "string" ? body["message"] : fallback;
|
|
33069
|
+
const reason = typeof body["reason"] === "string" ? body["reason"] : void 0;
|
|
33070
|
+
const details = isRecord2(body["details"]) ? body["details"] : void 0;
|
|
33071
|
+
return {
|
|
33072
|
+
code,
|
|
33073
|
+
message,
|
|
33074
|
+
...reason ? { reason } : {},
|
|
33075
|
+
...details ? { details } : {}
|
|
33076
|
+
};
|
|
33077
|
+
}
|
|
33078
|
+
async function rejectedResponse(response, fallback) {
|
|
33079
|
+
const parsed = gatewayErrorBody(await responseBody(response), fallback);
|
|
33080
|
+
const details = response.status === HTTP_UNAUTHORIZED && parsed.reason ? { ...parsed.details, reason: parsed.reason } : parsed.details;
|
|
33081
|
+
const message = response.status === HTTP_UNAUTHORIZED && parsed.reason ? `${parsed.message}: ${parsed.reason}` : parsed.message;
|
|
33082
|
+
if (response.status === HTTP_FORBIDDEN) {
|
|
33083
|
+
if (parsed.code === "BUILDER_UNKNOWN") {
|
|
33084
|
+
return new BuilderUnknownError(parsed.message, details);
|
|
33085
|
+
}
|
|
33086
|
+
if (parsed.code === "GRANT_INVALID") {
|
|
33087
|
+
return new GrantInvalidError(parsed.message, details);
|
|
33088
|
+
}
|
|
33089
|
+
if (parsed.code === "OWNER_NOT_READY") {
|
|
33090
|
+
return new OwnerNotReadyError(parsed.message, details);
|
|
33091
|
+
}
|
|
33092
|
+
}
|
|
33093
|
+
if (response.status === HTTP_NOT_FOUND) {
|
|
33094
|
+
return new JobNotFoundError(parsed.message, details);
|
|
33095
|
+
}
|
|
33096
|
+
if (response.status === HTTP_CONFLICT && parsed.code === "JOB_ID_TAKEN") {
|
|
33097
|
+
return new JobIdTakenError(parsed.message, details);
|
|
33098
|
+
}
|
|
33099
|
+
if (response.status === HTTP_PAYLOAD_TOO_LARGE) {
|
|
33100
|
+
return new JobRequestTooLargeError(parsed.message, parsed.code, details);
|
|
33101
|
+
}
|
|
33102
|
+
return new JobRejectedError(message, response.status, parsed.code, details);
|
|
33103
|
+
}
|
|
33104
|
+
function requireStatus(value, status) {
|
|
33105
|
+
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"])) {
|
|
33106
|
+
throw new JobRejectedError(
|
|
33107
|
+
"Gateway response did not contain a job status",
|
|
33108
|
+
status
|
|
33109
|
+
);
|
|
33110
|
+
}
|
|
33111
|
+
return value;
|
|
33112
|
+
}
|
|
33113
|
+
function isNonEmptyString(value) {
|
|
33114
|
+
return typeof value === "string" && value.length > 0;
|
|
33115
|
+
}
|
|
33116
|
+
function hasMatchingIdentityKey(value) {
|
|
33117
|
+
const address = value["address"];
|
|
33118
|
+
const publicKey = value["publicKey"];
|
|
33119
|
+
if (typeof address !== "string" || !isAddress2(address) || typeof publicKey !== "string" || !isHex2(publicKey)) {
|
|
33120
|
+
return false;
|
|
33121
|
+
}
|
|
33122
|
+
try {
|
|
33123
|
+
return publicKeyToAddress2(publicKey).toLowerCase() === address.toLowerCase();
|
|
33124
|
+
} catch {
|
|
33125
|
+
return false;
|
|
33126
|
+
}
|
|
33127
|
+
}
|
|
33128
|
+
function hasExpectedIdentity(value, owner, chainId) {
|
|
33129
|
+
const identityOwner = value["ownerAddress"];
|
|
33130
|
+
const identityChainId = value["chainId"];
|
|
33131
|
+
const identityUserPsId = value["userPsId"];
|
|
33132
|
+
if (!hasMatchingIdentityKey(value) || typeof identityOwner !== "string" || !isAddress2(identityOwner) || typeof identityChainId !== "number" || typeof identityUserPsId !== "string" || !isHex2(identityUserPsId)) {
|
|
33133
|
+
return false;
|
|
33134
|
+
}
|
|
33135
|
+
return isAddressEqual2(identityOwner, owner) && identityChainId === chainId && identityUserPsId.toLowerCase() === userPsId(chainId, owner).toLowerCase();
|
|
33136
|
+
}
|
|
33137
|
+
function sleep2(ms) {
|
|
33138
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
33139
|
+
}
|
|
33140
|
+
function requireFiniteDuration(value, field) {
|
|
33141
|
+
if (!Number.isFinite(value)) {
|
|
33142
|
+
throw new JobRejectedError(`${field} must be a finite number`);
|
|
33143
|
+
}
|
|
33144
|
+
return Math.max(0, value);
|
|
33145
|
+
}
|
|
33146
|
+
function createJobsClient(options) {
|
|
33147
|
+
const { baseUrl, audience } = normalizeGateway(options.gatewayUrl);
|
|
33148
|
+
const fetchFn = resolveFetch(options.fetch);
|
|
33149
|
+
const { builder, privateKey } = resolveBuilder(options);
|
|
33150
|
+
const ecies = options.ecies ?? new NodeECIESUint8Provider();
|
|
33151
|
+
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
33152
|
+
async function request(url, init, description) {
|
|
33153
|
+
try {
|
|
33154
|
+
return await fetchFn(url, init);
|
|
33155
|
+
} catch (error) {
|
|
33156
|
+
throw new JobTransportError(
|
|
33157
|
+
`${description} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
33158
|
+
error
|
|
33159
|
+
);
|
|
33160
|
+
}
|
|
33161
|
+
}
|
|
33162
|
+
async function getIdentity(owner) {
|
|
33163
|
+
const query = new URLSearchParams({
|
|
33164
|
+
owner,
|
|
33165
|
+
chainId: String(options.chainId)
|
|
33166
|
+
});
|
|
33167
|
+
const response = await request(
|
|
33168
|
+
`${baseUrl}${IDENTITY_PATH}?${query.toString()}`,
|
|
33169
|
+
{ method: GET_METHOD },
|
|
33170
|
+
"Owner identity lookup"
|
|
33171
|
+
);
|
|
33172
|
+
if (response.status === HTTP_NOT_FOUND) {
|
|
33173
|
+
const parsed = gatewayErrorBody(
|
|
33174
|
+
await responseBody(response),
|
|
33175
|
+
"Owner identity not found"
|
|
33176
|
+
);
|
|
33177
|
+
throw new OwnerNotReadyError(parsed.message, parsed.details);
|
|
33178
|
+
}
|
|
33179
|
+
if (!response.ok) {
|
|
33180
|
+
throw await rejectedResponse(response, "Owner identity lookup rejected");
|
|
33181
|
+
}
|
|
33182
|
+
const body = await responseBody(response);
|
|
33183
|
+
if (!isRecord2(body) || body["state"] !== SEALED_IDENTITY_STATE || !isRecord2(body["identity"])) {
|
|
33184
|
+
throw new OwnerNotReadyError("Owner identity is not sealed", {
|
|
33185
|
+
state: isRecord2(body) ? body["state"] : void 0
|
|
33186
|
+
});
|
|
33187
|
+
}
|
|
33188
|
+
if (!hasExpectedIdentity(body["identity"], owner, options.chainId)) {
|
|
33189
|
+
throw new JobRejectedError(
|
|
33190
|
+
"Gateway returned a malformed or mismatched owner identity",
|
|
33191
|
+
response.status
|
|
33192
|
+
);
|
|
33193
|
+
}
|
|
33194
|
+
return body["identity"];
|
|
33195
|
+
}
|
|
33196
|
+
const client = {
|
|
33197
|
+
async submitRawRead(params) {
|
|
33198
|
+
const identity = await getIdentity(params.owner);
|
|
33199
|
+
const deadlineSeconds = clampInteger(
|
|
33200
|
+
params.deadlineSeconds,
|
|
33201
|
+
DEFAULT_JOB_DEADLINE_SECONDS,
|
|
33202
|
+
1,
|
|
33203
|
+
MAX_JOB_DEADLINE_SECONDS,
|
|
33204
|
+
"deadlineSeconds"
|
|
33205
|
+
);
|
|
33206
|
+
const wait = clampInteger(params.wait, 0, 0, MAX_WAIT_SECONDS, "wait");
|
|
33207
|
+
const jobId = randomUUID();
|
|
33208
|
+
const nowMs = now().getTime();
|
|
33209
|
+
if (!Number.isFinite(nowMs)) {
|
|
33210
|
+
throw new JobRejectedError("now must return a valid Date");
|
|
33211
|
+
}
|
|
33212
|
+
const deadline = new Date(
|
|
33213
|
+
nowMs + deadlineSeconds * MILLISECONDS_PER_SECOND
|
|
33214
|
+
).toISOString();
|
|
33215
|
+
const requestBody = {
|
|
33216
|
+
v: JOB_PROTOCOL_VERSION,
|
|
33217
|
+
jobId,
|
|
33218
|
+
owner: params.owner,
|
|
33219
|
+
builder: builder.address,
|
|
33220
|
+
builderPublicKey: builder.publicKey,
|
|
33221
|
+
grantId: params.grantId,
|
|
33222
|
+
scope: params.scope,
|
|
33223
|
+
operation: RAW_READ_OPERATION,
|
|
33224
|
+
pinnedVersion: params.pinnedVersion ?? null,
|
|
33225
|
+
deadline
|
|
33226
|
+
};
|
|
33227
|
+
const auth = await buildWeb3SignedHeader({
|
|
33228
|
+
signMessage: builder.signMessage,
|
|
33229
|
+
aud: audience,
|
|
33230
|
+
method: POST_METHOD,
|
|
33231
|
+
uri: JOB_EXECUTE_PATH,
|
|
33232
|
+
bodyHash: computeBodyHash(canonicalJobRequestBytes(requestBody)),
|
|
33233
|
+
nonce: randomUUID()
|
|
33234
|
+
});
|
|
33235
|
+
const requestCiphertext = await sealJobRequest(
|
|
33236
|
+
{ request: requestBody, auth },
|
|
33237
|
+
identity.publicKey,
|
|
33238
|
+
ecies
|
|
33239
|
+
);
|
|
33240
|
+
const submission = {
|
|
33241
|
+
owner: requestBody.owner,
|
|
33242
|
+
grantId: requestBody.grantId,
|
|
33243
|
+
scope: requestBody.scope,
|
|
33244
|
+
operation: requestBody.operation,
|
|
33245
|
+
idempotencyKey: randomUUID(),
|
|
33246
|
+
jobId,
|
|
33247
|
+
deadline,
|
|
33248
|
+
requestCiphertext
|
|
33249
|
+
};
|
|
33250
|
+
const bodyBytes = new TextEncoder().encode(JSON.stringify(submission));
|
|
33251
|
+
const authorization = await buildWeb3SignedHeader({
|
|
33252
|
+
signMessage: builder.signMessage,
|
|
33253
|
+
aud: audience,
|
|
33254
|
+
method: POST_METHOD,
|
|
33255
|
+
uri: JOBS_PATH,
|
|
33256
|
+
body: bodyBytes,
|
|
33257
|
+
nonce: randomUUID()
|
|
33258
|
+
});
|
|
33259
|
+
const response = await request(
|
|
33260
|
+
`${baseUrl}${JOBS_PATH}?wait=${wait}`,
|
|
33261
|
+
{
|
|
33262
|
+
method: POST_METHOD,
|
|
33263
|
+
headers: {
|
|
33264
|
+
[AUTHORIZATION_HEADER]: authorization,
|
|
33265
|
+
[CONTENT_TYPE_HEADER]: JSON_CONTENT_TYPE
|
|
33266
|
+
},
|
|
33267
|
+
body: bodyBytes
|
|
33268
|
+
},
|
|
33269
|
+
"Job submission"
|
|
33270
|
+
);
|
|
33271
|
+
if (!response.ok) {
|
|
33272
|
+
throw await rejectedResponse(response, "Job submission rejected");
|
|
33273
|
+
}
|
|
33274
|
+
const body = await responseBody(response);
|
|
33275
|
+
if (response.status === HTTP_OK && isRecord2(body)) {
|
|
33276
|
+
const job = requireStatus(body["job"], response.status);
|
|
33277
|
+
if (job.jobId !== jobId) {
|
|
33278
|
+
throw new JobRejectedError(
|
|
33279
|
+
"Gateway returned a job id that does not match the submission",
|
|
33280
|
+
response.status
|
|
33281
|
+
);
|
|
33282
|
+
}
|
|
33283
|
+
return { jobId, state: job.state, job };
|
|
33284
|
+
}
|
|
33285
|
+
if (response.status === HTTP_ACCEPTED && isRecord2(body) && body["jobId"] === jobId && typeof body["state"] === "string" && JOB_STATES.includes(body["state"])) {
|
|
33286
|
+
return { jobId, state: body["state"] };
|
|
33287
|
+
}
|
|
33288
|
+
throw new JobRejectedError(
|
|
33289
|
+
"Gateway returned an undocumented job submission response",
|
|
33290
|
+
response.status
|
|
33291
|
+
);
|
|
33292
|
+
},
|
|
33293
|
+
async getJob(jobId) {
|
|
33294
|
+
const path = `${JOBS_PATH}/${encodeURIComponent(jobId)}`;
|
|
33295
|
+
const authorization = await buildWeb3SignedHeader({
|
|
33296
|
+
signMessage: builder.signMessage,
|
|
33297
|
+
aud: audience,
|
|
33298
|
+
method: GET_METHOD,
|
|
33299
|
+
uri: path,
|
|
33300
|
+
nonce: randomUUID()
|
|
33301
|
+
});
|
|
33302
|
+
const response = await request(
|
|
33303
|
+
`${baseUrl}${path}`,
|
|
33304
|
+
{
|
|
33305
|
+
method: GET_METHOD,
|
|
33306
|
+
headers: { [AUTHORIZATION_HEADER]: authorization }
|
|
33307
|
+
},
|
|
33308
|
+
"Job status read"
|
|
33309
|
+
);
|
|
33310
|
+
if (!response.ok) {
|
|
33311
|
+
throw await rejectedResponse(response, "Job status read rejected");
|
|
33312
|
+
}
|
|
33313
|
+
const body = await responseBody(response);
|
|
33314
|
+
return requireStatus(
|
|
33315
|
+
isRecord2(body) ? body["job"] : void 0,
|
|
33316
|
+
response.status
|
|
33317
|
+
);
|
|
33318
|
+
},
|
|
33319
|
+
async waitForJob(jobId, waitOptions = {}) {
|
|
33320
|
+
const timeoutMs = requireFiniteDuration(
|
|
33321
|
+
waitOptions.timeoutMs ?? DEFAULT_JOB_TIMEOUT_MS,
|
|
33322
|
+
"timeoutMs"
|
|
33323
|
+
);
|
|
33324
|
+
const pollMs = Math.max(
|
|
33325
|
+
CLAIM_POLL_FLOOR_MS,
|
|
33326
|
+
requireFiniteDuration(
|
|
33327
|
+
waitOptions.pollMs ?? DEFAULT_JOB_POLL_MS,
|
|
33328
|
+
"pollMs"
|
|
33329
|
+
)
|
|
33330
|
+
);
|
|
33331
|
+
const startedAt = Date.now();
|
|
33332
|
+
const callerDeadline = startedAt + timeoutMs;
|
|
33333
|
+
let latest;
|
|
33334
|
+
for (; ; ) {
|
|
33335
|
+
if (Date.now() >= callerDeadline) {
|
|
33336
|
+
throw new JobTimeoutError(
|
|
33337
|
+
`Timed out waiting for terminal job ${jobId}`,
|
|
33338
|
+
{
|
|
33339
|
+
jobId,
|
|
33340
|
+
timeoutMs,
|
|
33341
|
+
state: latest?.state
|
|
33342
|
+
}
|
|
33343
|
+
);
|
|
33344
|
+
}
|
|
33345
|
+
latest = await client.getJob(jobId);
|
|
33346
|
+
if (TERMINAL_JOB_STATES.has(latest.state)) return latest;
|
|
33347
|
+
const remaining = callerDeadline - Date.now();
|
|
33348
|
+
if (remaining <= 0) {
|
|
33349
|
+
throw new JobTimeoutError(
|
|
33350
|
+
`Timed out waiting for terminal job ${jobId}`,
|
|
33351
|
+
{
|
|
33352
|
+
jobId,
|
|
33353
|
+
timeoutMs,
|
|
33354
|
+
state: latest.state
|
|
33355
|
+
}
|
|
33356
|
+
);
|
|
33357
|
+
}
|
|
33358
|
+
await sleep2(Math.min(pollMs, remaining));
|
|
33359
|
+
}
|
|
33360
|
+
},
|
|
33361
|
+
async openResult(handle, openOptions) {
|
|
33362
|
+
if (!privateKey) {
|
|
33363
|
+
throw new JobRejectedError(
|
|
33364
|
+
"openResult requires createJobsClient({ builderPrivateKey })"
|
|
33365
|
+
);
|
|
33366
|
+
}
|
|
33367
|
+
const response = await request(
|
|
33368
|
+
handle.url,
|
|
33369
|
+
{ method: GET_METHOD },
|
|
33370
|
+
"Job result fetch"
|
|
33371
|
+
);
|
|
33372
|
+
if (!response.ok) {
|
|
33373
|
+
throw await rejectedResponse(response, "Job result fetch rejected");
|
|
33374
|
+
}
|
|
33375
|
+
let bytes;
|
|
33376
|
+
try {
|
|
33377
|
+
bytes = new Uint8Array(await response.arrayBuffer());
|
|
33378
|
+
} catch (error) {
|
|
33379
|
+
throw new JobTransportError(
|
|
33380
|
+
`Job result fetch failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
33381
|
+
error
|
|
33382
|
+
);
|
|
33383
|
+
}
|
|
33384
|
+
const actualHash = bytesToHex3(sha2566(bytes));
|
|
33385
|
+
if (actualHash.toLowerCase() !== handle.hash.toLowerCase()) {
|
|
33386
|
+
throw new JobResultIntegrityError(
|
|
33387
|
+
"Fetched job result hash does not match its handle",
|
|
33388
|
+
{
|
|
33389
|
+
objectKey: handle.objectKey,
|
|
33390
|
+
expectedHash: handle.hash,
|
|
33391
|
+
actualHash
|
|
33392
|
+
}
|
|
33393
|
+
);
|
|
33394
|
+
}
|
|
33395
|
+
if (bytes.length !== handle.size) {
|
|
33396
|
+
throw new JobResultIntegrityError(
|
|
33397
|
+
"Fetched job result size does not match its handle",
|
|
33398
|
+
{
|
|
33399
|
+
objectKey: handle.objectKey,
|
|
33400
|
+
expectedSize: handle.size,
|
|
33401
|
+
actualSize: bytes.length
|
|
33402
|
+
}
|
|
33403
|
+
);
|
|
33404
|
+
}
|
|
33405
|
+
return openJobResult(bytes, privateKey, ecies, openOptions.expect);
|
|
33406
|
+
},
|
|
33407
|
+
async readRaw(params) {
|
|
33408
|
+
const submitted = await client.submitRawRead(params);
|
|
33409
|
+
const job = submitted.job && TERMINAL_JOB_STATES.has(submitted.job.state) ? submitted.job : await client.waitForJob(submitted.jobId, {
|
|
33410
|
+
timeoutMs: params.timeoutMs,
|
|
33411
|
+
pollMs: params.pollMs
|
|
33412
|
+
});
|
|
33413
|
+
if (job.state !== "completed") {
|
|
33414
|
+
throw new JobRejectedError(
|
|
33415
|
+
`Job ${job.jobId} ended in state ${job.state}${job.failureReason ? `: ${job.failureReason}` : ""}`,
|
|
33416
|
+
void 0,
|
|
33417
|
+
null,
|
|
33418
|
+
{
|
|
33419
|
+
jobId: job.jobId,
|
|
33420
|
+
state: job.state,
|
|
33421
|
+
...job.failureReason ? { failureReason: job.failureReason } : {}
|
|
33422
|
+
}
|
|
33423
|
+
);
|
|
33424
|
+
}
|
|
33425
|
+
if (!job.result) {
|
|
33426
|
+
throw new JobRejectedError(
|
|
33427
|
+
"Completed job status does not include a result handle",
|
|
33428
|
+
void 0,
|
|
33429
|
+
null,
|
|
33430
|
+
{ jobId: job.jobId, state: job.state }
|
|
33431
|
+
);
|
|
33432
|
+
}
|
|
33433
|
+
return client.openResult(job.result, {
|
|
33434
|
+
expect: {
|
|
33435
|
+
jobId: submitted.jobId,
|
|
33436
|
+
scope: params.scope,
|
|
33437
|
+
...params.pinnedVersion !== void 0 && params.pinnedVersion !== null ? { version: params.pinnedVersion } : {}
|
|
33438
|
+
}
|
|
33439
|
+
});
|
|
33440
|
+
}
|
|
33441
|
+
};
|
|
33442
|
+
return client;
|
|
33443
|
+
}
|
|
33444
|
+
|
|
32366
33445
|
// src/protocol/personal-server-registration.ts
|
|
32367
33446
|
import {
|
|
32368
|
-
isAddress
|
|
33447
|
+
isAddress as isAddress3
|
|
32369
33448
|
} from "viem";
|
|
32370
33449
|
var PERSONAL_SERVER_REGISTRATION_DEFAULT_CHAIN_ID = vanaMainnet2.id;
|
|
32371
33450
|
var PERSONAL_SERVER_REGISTRATION_DEFAULT_VERIFYING_CONTRACT = getContractAddress(
|
|
@@ -32373,7 +33452,7 @@ var PERSONAL_SERVER_REGISTRATION_DEFAULT_VERIFYING_CONTRACT = getContractAddress
|
|
|
32373
33452
|
"DataPortabilityServers"
|
|
32374
33453
|
);
|
|
32375
33454
|
function assertAddress(value, name) {
|
|
32376
|
-
if (!
|
|
33455
|
+
if (!isAddress3(value)) {
|
|
32377
33456
|
throw new Error(`${name} must be a valid EVM address`);
|
|
32378
33457
|
}
|
|
32379
33458
|
}
|
|
@@ -32460,13 +33539,13 @@ var registerPersonalServerSignature = buildPersonalServerRegistrationSignature;
|
|
|
32460
33539
|
|
|
32461
33540
|
// src/personal-server-lite/owner-binding.ts
|
|
32462
33541
|
import {
|
|
32463
|
-
isAddress as
|
|
33542
|
+
isAddress as isAddress4
|
|
32464
33543
|
} from "viem";
|
|
32465
33544
|
var PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION = "vana.ps-lite.owner-binding.v1";
|
|
32466
33545
|
var PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE = "ps-lite-owner";
|
|
32467
33546
|
var PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX = `${PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION}:${PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE}:`;
|
|
32468
33547
|
function assertAddress2(value, name) {
|
|
32469
|
-
if (!
|
|
33548
|
+
if (!isAddress4(value)) {
|
|
32470
33549
|
throw new Error(`${name} must be a valid EVM address`);
|
|
32471
33550
|
}
|
|
32472
33551
|
}
|
|
@@ -32516,7 +33595,7 @@ async function buildPersonalServerLiteOwnerBindingSignature(input) {
|
|
|
32516
33595
|
var signPersonalServerLiteOwnerBinding = buildPersonalServerLiteOwnerBindingSignature;
|
|
32517
33596
|
|
|
32518
33597
|
// src/account/personal-server-registration.ts
|
|
32519
|
-
import { isAddress as
|
|
33598
|
+
import { isAddress as isAddress5 } from "viem";
|
|
32520
33599
|
var ACCOUNT_PERSONAL_SERVER_REGISTRATION_INTENT = "personal_server.server_registration.v1";
|
|
32521
33600
|
var AccountPersonalServerRegistrationError = class extends Error {
|
|
32522
33601
|
status;
|
|
@@ -32535,7 +33614,7 @@ function trimTrailingSlash(value) {
|
|
|
32535
33614
|
return value.replace(/\/+$/, "");
|
|
32536
33615
|
}
|
|
32537
33616
|
function assertAddress3(value, name) {
|
|
32538
|
-
if (!
|
|
33617
|
+
if (!isAddress5(value)) {
|
|
32539
33618
|
throw new Error(`${name} must be a valid EVM address`);
|
|
32540
33619
|
}
|
|
32541
33620
|
}
|
|
@@ -32556,7 +33635,7 @@ function accountErrorMessage(status, body) {
|
|
|
32556
33635
|
if (nestedMessage) {
|
|
32557
33636
|
return nestedMessage;
|
|
32558
33637
|
}
|
|
32559
|
-
if (
|
|
33638
|
+
if (isRecord3(body) && typeof body.message === "string") {
|
|
32560
33639
|
return body.message;
|
|
32561
33640
|
}
|
|
32562
33641
|
const code = accountErrorCode(body);
|
|
@@ -32570,7 +33649,7 @@ function accountErrorCode(body) {
|
|
|
32570
33649
|
if (nestedCode) {
|
|
32571
33650
|
return nestedCode;
|
|
32572
33651
|
}
|
|
32573
|
-
if (
|
|
33652
|
+
if (isRecord3(body)) {
|
|
32574
33653
|
if (typeof body.code === "string") {
|
|
32575
33654
|
return body.code;
|
|
32576
33655
|
}
|
|
@@ -32581,13 +33660,13 @@ function accountErrorCode(body) {
|
|
|
32581
33660
|
return void 0;
|
|
32582
33661
|
}
|
|
32583
33662
|
function nestedAccountErrorField(body, field) {
|
|
32584
|
-
if (!
|
|
33663
|
+
if (!isRecord3(body) || !isRecord3(body.error)) {
|
|
32585
33664
|
return void 0;
|
|
32586
33665
|
}
|
|
32587
33666
|
const value = body.error[field];
|
|
32588
33667
|
return typeof value === "string" ? value : void 0;
|
|
32589
33668
|
}
|
|
32590
|
-
function
|
|
33669
|
+
function isRecord3(value) {
|
|
32591
33670
|
return typeof value === "object" && value !== null;
|
|
32592
33671
|
}
|
|
32593
33672
|
function normalizeAccountResponse(response) {
|
|
@@ -33061,8 +34140,8 @@ function buildMarkDataPointUnavailableRequest(config, input) {
|
|
|
33061
34140
|
|
|
33062
34141
|
// src/protocol/data-point-deletion.ts
|
|
33063
34142
|
import {
|
|
33064
|
-
isAddress as
|
|
33065
|
-
keccak256 as
|
|
34143
|
+
isAddress as isAddress7,
|
|
34144
|
+
keccak256 as keccak2563,
|
|
33066
34145
|
maxUint256,
|
|
33067
34146
|
stringToBytes as stringToBytes3
|
|
33068
34147
|
} from "viem";
|
|
@@ -33070,13 +34149,13 @@ import {
|
|
|
33070
34149
|
// src/protocol/lineage.ts
|
|
33071
34150
|
import {
|
|
33072
34151
|
encodeAbiParameters,
|
|
33073
|
-
isAddress as
|
|
33074
|
-
keccak256
|
|
34152
|
+
isAddress as isAddress6,
|
|
34153
|
+
keccak256 as keccak2562
|
|
33075
34154
|
} from "viem";
|
|
33076
34155
|
import { z } from "zod";
|
|
33077
34156
|
|
|
33078
34157
|
// src/protocol/personal-server-error-body.ts
|
|
33079
|
-
function
|
|
34158
|
+
function isRecord4(value) {
|
|
33080
34159
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
33081
34160
|
}
|
|
33082
34161
|
async function readPersonalServerErrorBody(response) {
|
|
@@ -33086,8 +34165,8 @@ async function readPersonalServerErrorBody(response) {
|
|
|
33086
34165
|
} catch {
|
|
33087
34166
|
return { errorCode: null, message: null };
|
|
33088
34167
|
}
|
|
33089
|
-
if (!
|
|
33090
|
-
const nested =
|
|
34168
|
+
if (!isRecord4(body)) return { errorCode: null, message: null };
|
|
34169
|
+
const nested = isRecord4(body.error) ? body.error : null;
|
|
33091
34170
|
const gatewayShape = typeof body.error === "string" && typeof body.code === "string";
|
|
33092
34171
|
const code = nested?.errorCode ?? nested?.code ?? body.errorCode ?? (gatewayShape ? body.code : void 0) ?? (typeof body.error === "string" ? body.error : void 0) ?? body.code;
|
|
33093
34172
|
const message = nested?.message ?? body.message ?? (gatewayShape ? body.error : void 0);
|
|
@@ -33100,62 +34179,22 @@ async function readPersonalServerErrorBody(response) {
|
|
|
33100
34179
|
return {
|
|
33101
34180
|
errorCode: typeof code === "string" ? code : null,
|
|
33102
34181
|
message: typeof message === "string" ? message : null,
|
|
33103
|
-
...
|
|
34182
|
+
...isRecord4(details) ? { details } : {}
|
|
33104
34183
|
};
|
|
33105
34184
|
}
|
|
33106
34185
|
|
|
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
34186
|
// src/protocol/lineage.ts
|
|
33148
34187
|
var DATA_POINT_ID_PATTERN = /^0x[0-9a-fA-F]{64}$/;
|
|
33149
34188
|
function isDataPointId(value) {
|
|
33150
34189
|
return typeof value === "string" && DATA_POINT_ID_PATTERN.test(value);
|
|
33151
34190
|
}
|
|
33152
34191
|
function deriveDataPointId(ownerAddress, scope) {
|
|
33153
|
-
if (!
|
|
34192
|
+
if (!isAddress6(ownerAddress, { strict: false })) {
|
|
33154
34193
|
throw new Error(
|
|
33155
34194
|
`ownerAddress is not an EVM address: ${String(ownerAddress)}`
|
|
33156
34195
|
);
|
|
33157
34196
|
}
|
|
33158
|
-
return
|
|
34197
|
+
return keccak2562(
|
|
33159
34198
|
encodeAbiParameters(
|
|
33160
34199
|
[
|
|
33161
34200
|
{ name: "ownerAddress", type: "address" },
|
|
@@ -33245,7 +34284,7 @@ function gatewayLineagePath(dataPointId, version) {
|
|
|
33245
34284
|
function normalizeBaseUrl(url) {
|
|
33246
34285
|
return url.replace(/\/+$/, "");
|
|
33247
34286
|
}
|
|
33248
|
-
function
|
|
34287
|
+
function resolveFetch2(fetchFn) {
|
|
33249
34288
|
const resolved = fetchFn ?? globalThis.fetch;
|
|
33250
34289
|
if (resolved === void 0) {
|
|
33251
34290
|
throw new LineageReadError("No fetch implementation available");
|
|
@@ -33286,7 +34325,7 @@ async function parseLineageGraph(source, response) {
|
|
|
33286
34325
|
{ cause: err instanceof Error ? err.message : String(err) }
|
|
33287
34326
|
);
|
|
33288
34327
|
}
|
|
33289
|
-
const envelope =
|
|
34328
|
+
const envelope = isRecord4(body) && isRecord4(body.data) ? body : void 0;
|
|
33290
34329
|
const parsed = LineageGraphSchema.safeParse(envelope?.data ?? body);
|
|
33291
34330
|
if (!parsed.success) {
|
|
33292
34331
|
throw new LineageReadError(
|
|
@@ -33296,7 +34335,7 @@ async function parseLineageGraph(source, response) {
|
|
|
33296
34335
|
{ issues: parsed.error.issues }
|
|
33297
34336
|
);
|
|
33298
34337
|
}
|
|
33299
|
-
const proof =
|
|
34338
|
+
const proof = isRecord4(envelope?.proof) ? envelope.proof : void 0;
|
|
33300
34339
|
return proof === void 0 ? parsed.data : { ...parsed.data, proof };
|
|
33301
34340
|
}
|
|
33302
34341
|
async function sendLineageRead(source, fetchFn, url, headers) {
|
|
@@ -33317,7 +34356,7 @@ async function sendLineageRead(source, fetchFn, url, headers) {
|
|
|
33317
34356
|
return parseLineageGraph(source, response);
|
|
33318
34357
|
}
|
|
33319
34358
|
async function getPersonalServerLineage(params) {
|
|
33320
|
-
const fetchFn =
|
|
34359
|
+
const fetchFn = resolveFetch2(params.fetch);
|
|
33321
34360
|
const baseUrl = normalizeBaseUrl(params.personalServerUrl);
|
|
33322
34361
|
const audience = params.audience ?? baseUrl;
|
|
33323
34362
|
const signer = resolveWriteSigner(params.signer, { account: params.account });
|
|
@@ -33352,7 +34391,7 @@ async function getGatewayLineage(params) {
|
|
|
33352
34391
|
{ dataPointId: params.dataPointId }
|
|
33353
34392
|
);
|
|
33354
34393
|
}
|
|
33355
|
-
const fetchFn =
|
|
34394
|
+
const fetchFn = resolveFetch2(params.fetch);
|
|
33356
34395
|
const baseUrl = normalizeBaseUrl(params.gatewayUrl);
|
|
33357
34396
|
const signer = resolveWriteSigner(params.signer, { account: params.account });
|
|
33358
34397
|
const uri = gatewayLineagePath(
|
|
@@ -33382,7 +34421,7 @@ var TOMBSTONE_METADATA_HASH_PREIMAGE = "vana.data-point.tombstone.metadata.v1";
|
|
|
33382
34421
|
var TOMBSTONE_DATA_HASH = "0x30c45ee72fe56d1927701316925ab7ceacd3b6f9267061735d59396f075c6222";
|
|
33383
34422
|
var TOMBSTONE_METADATA_HASH = "0xc5255a141acd6a2ae55971b62c0a85977c2511989dc114ad2abc2b7644f57d90";
|
|
33384
34423
|
function computeTombstoneHash(preimage) {
|
|
33385
|
-
return
|
|
34424
|
+
return keccak2563(stringToBytes3(preimage));
|
|
33386
34425
|
}
|
|
33387
34426
|
function isTombstoneHashes(dataHash, metadataHash) {
|
|
33388
34427
|
return typeof dataHash === "string" && typeof metadataHash === "string" && dataHash.toLowerCase() === TOMBSTONE_DATA_HASH && metadataHash.toLowerCase() === TOMBSTONE_METADATA_HASH;
|
|
@@ -33401,7 +34440,7 @@ function tombstoneDeletedAt(value) {
|
|
|
33401
34440
|
return typeof deletedAt === "string" ? deletedAt : null;
|
|
33402
34441
|
}
|
|
33403
34442
|
function assertAddress4(value, name) {
|
|
33404
|
-
if (!
|
|
34443
|
+
if (!isAddress7(value)) {
|
|
33405
34444
|
throw new Error(`${name} must be a valid EVM address`);
|
|
33406
34445
|
}
|
|
33407
34446
|
}
|
|
@@ -33816,17 +34855,17 @@ function tryGrantPermissions(scopes) {
|
|
|
33816
34855
|
}
|
|
33817
34856
|
|
|
33818
34857
|
// src/protocol/personal-server-write.ts
|
|
33819
|
-
import { sha256 as
|
|
33820
|
-
import { bytesToHex as
|
|
34858
|
+
import { sha256 as sha2568 } from "@noble/hashes/sha2";
|
|
34859
|
+
import { bytesToHex as bytesToHex5, isAddress as isAddress8 } from "viem";
|
|
33821
34860
|
import { z as z4 } from "zod";
|
|
33822
34861
|
|
|
33823
34862
|
// src/protocol/write-request.ts
|
|
33824
|
-
import { sha256 as
|
|
33825
|
-
import { bytesToHex as
|
|
34863
|
+
import { sha256 as sha2567 } from "@noble/hashes/sha2";
|
|
34864
|
+
import { bytesToHex as bytesToHex4 } from "viem";
|
|
33826
34865
|
function normalizeBaseUrl2(url) {
|
|
33827
34866
|
return url.replace(/\/+$/, "");
|
|
33828
34867
|
}
|
|
33829
|
-
function
|
|
34868
|
+
function resolveFetch3(fetchFn) {
|
|
33830
34869
|
const resolved = fetchFn ?? globalThis.fetch;
|
|
33831
34870
|
if (resolved === void 0) {
|
|
33832
34871
|
throw new WriteRequestError("No fetch implementation available");
|
|
@@ -33839,7 +34878,7 @@ function errorMessage(err) {
|
|
|
33839
34878
|
function finiteOr(value, fallback) {
|
|
33840
34879
|
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
33841
34880
|
}
|
|
33842
|
-
function
|
|
34881
|
+
function sleep3(ms) {
|
|
33843
34882
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
33844
34883
|
}
|
|
33845
34884
|
var issuedProofIats = /* @__PURE__ */ new Map();
|
|
@@ -33881,7 +34920,7 @@ function nextProofIat(proofKey) {
|
|
|
33881
34920
|
setIssuedProofIat(proofKey, iat, last);
|
|
33882
34921
|
const waitSec = iat - nowSec - PROOF_IAT_MAX_AHEAD_SECONDS;
|
|
33883
34922
|
if (waitSec <= 0) return Promise.resolve(iat);
|
|
33884
|
-
return
|
|
34923
|
+
return sleep3(waitSec * 1e3).then(() => iat);
|
|
33885
34924
|
}
|
|
33886
34925
|
function freshProofNonce() {
|
|
33887
34926
|
const webCrypto = globalThis.crypto;
|
|
@@ -33889,22 +34928,22 @@ function freshProofNonce() {
|
|
|
33889
34928
|
return webCrypto.randomUUID();
|
|
33890
34929
|
}
|
|
33891
34930
|
if (typeof webCrypto?.getRandomValues === "function") {
|
|
33892
|
-
return
|
|
34931
|
+
return bytesToHex4(webCrypto.getRandomValues(new Uint8Array(16)));
|
|
33893
34932
|
}
|
|
33894
34933
|
throw new WriteRequestError(
|
|
33895
34934
|
"No secure random source available to build a proof nonce; provide a crypto global"
|
|
33896
34935
|
);
|
|
33897
34936
|
}
|
|
33898
34937
|
function proofKeyFor(parts) {
|
|
33899
|
-
return
|
|
33900
|
-
|
|
34938
|
+
return bytesToHex4(
|
|
34939
|
+
sha2567(
|
|
33901
34940
|
new TextEncoder().encode(
|
|
33902
34941
|
JSON.stringify([
|
|
33903
34942
|
parts.aud,
|
|
33904
34943
|
parts.method,
|
|
33905
34944
|
parts.uri,
|
|
33906
34945
|
parts.grantId,
|
|
33907
|
-
parts.signedBytes ?
|
|
34946
|
+
parts.signedBytes ? bytesToHex4(sha2567(parts.signedBytes)) : ""
|
|
33908
34947
|
])
|
|
33909
34948
|
)
|
|
33910
34949
|
)
|
|
@@ -33922,7 +34961,7 @@ async function sendWithFreshProof(label, fetchFn, options, proofKey, build) {
|
|
|
33922
34961
|
lastError = err;
|
|
33923
34962
|
}
|
|
33924
34963
|
if (attempt < attempts - 1) {
|
|
33925
|
-
await
|
|
34964
|
+
await sleep3(delayMs);
|
|
33926
34965
|
delayMs *= 2;
|
|
33927
34966
|
}
|
|
33928
34967
|
}
|
|
@@ -33961,7 +35000,7 @@ function dataPath(scope) {
|
|
|
33961
35000
|
return `/v1/data/${encodeURIComponent(scope)}`;
|
|
33962
35001
|
}
|
|
33963
35002
|
async function openWriteSession(params) {
|
|
33964
|
-
const fetchFn =
|
|
35003
|
+
const fetchFn = resolveFetch3(params.fetch);
|
|
33965
35004
|
const personalServerUrl = normalizeBaseUrl2(params.personalServerUrl);
|
|
33966
35005
|
const audience = params.audience ?? personalServerUrl;
|
|
33967
35006
|
const signer = resolveWriteSigner(params.signer, { account: params.account });
|
|
@@ -34041,12 +35080,12 @@ async function openWriteSession(params) {
|
|
|
34041
35080
|
};
|
|
34042
35081
|
}
|
|
34043
35082
|
function isWriteSession(value) {
|
|
34044
|
-
if (!
|
|
35083
|
+
if (!isRecord4(value)) return false;
|
|
34045
35084
|
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") &&
|
|
35085
|
+
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
35086
|
}
|
|
34048
35087
|
function sessionCoversScope(session, scope) {
|
|
34049
|
-
if (!
|
|
35088
|
+
if (!isRecord4(session) || !Array.isArray(session.writeScopes) || !session.writeScopes.every((pattern) => typeof pattern === "string")) {
|
|
34050
35089
|
throw new WriteRequestError("session must come from openWriteSession");
|
|
34051
35090
|
}
|
|
34052
35091
|
return session.writeScopes.some(
|
|
@@ -34091,7 +35130,7 @@ function binaryWriteSignedBytes(input) {
|
|
|
34091
35130
|
mimeType: normalizeBinaryMimeType(input.contentType),
|
|
34092
35131
|
...input.filename ? { filename: input.filename } : {},
|
|
34093
35132
|
sizeBytes: input.bytes.length,
|
|
34094
|
-
contentHash:
|
|
35133
|
+
contentHash: bytesToHex5(sha2568(input.bytes)),
|
|
34095
35134
|
encoding: "base64",
|
|
34096
35135
|
content: toBase64(input.bytes),
|
|
34097
35136
|
...metadata !== void 0 ? { metadata } : {}
|
|
@@ -34120,7 +35159,7 @@ function assertNoReservedKeys(value, where) {
|
|
|
34120
35159
|
}
|
|
34121
35160
|
}
|
|
34122
35161
|
function isLineagePair(value) {
|
|
34123
|
-
return
|
|
35162
|
+
return isRecord4(value) && typeof value.ownerAddress === "string" && typeof value.scope === "string";
|
|
34124
35163
|
}
|
|
34125
35164
|
function normalizeLineage(lineage, derivedScope) {
|
|
34126
35165
|
if (!Array.isArray(lineage)) {
|
|
@@ -34139,7 +35178,7 @@ function normalizeLineage(lineage, derivedScope) {
|
|
|
34139
35178
|
for (const entry of lineage) {
|
|
34140
35179
|
let id;
|
|
34141
35180
|
if (isLineagePair(entry)) {
|
|
34142
|
-
if (!
|
|
35181
|
+
if (!isAddress8(entry.ownerAddress, { strict: false })) {
|
|
34143
35182
|
throw new WriteRequestError(
|
|
34144
35183
|
"lineage source ownerAddress must be an EVM address",
|
|
34145
35184
|
{ ownerAddress: entry.ownerAddress }
|
|
@@ -34188,7 +35227,7 @@ function assertNoLineageField(value, where) {
|
|
|
34188
35227
|
}
|
|
34189
35228
|
function buildMetadataHeader(metadata, sources) {
|
|
34190
35229
|
if (metadata !== void 0) {
|
|
34191
|
-
if (!
|
|
35230
|
+
if (!isRecord4(metadata)) {
|
|
34192
35231
|
throw new WriteRequestError("metadata must be a plain object");
|
|
34193
35232
|
}
|
|
34194
35233
|
assertNoReservedKeys(metadata, "metadata");
|
|
@@ -34241,7 +35280,7 @@ function prepareWrite(params) {
|
|
|
34241
35280
|
if (params.data === void 0) {
|
|
34242
35281
|
throw new WriteRequestError("Pass data (a JSON object) or binary");
|
|
34243
35282
|
}
|
|
34244
|
-
if (!
|
|
35283
|
+
if (!isRecord4(params.data)) {
|
|
34245
35284
|
throw new WriteRequestError("data must be a plain JSON object");
|
|
34246
35285
|
}
|
|
34247
35286
|
if (params.metadata !== void 0) {
|
|
@@ -34292,7 +35331,7 @@ async function writeData(params) {
|
|
|
34292
35331
|
if (!isWriteSession(session)) {
|
|
34293
35332
|
throw new WriteRequestError("session must come from openWriteSession");
|
|
34294
35333
|
}
|
|
34295
|
-
const fetchFn =
|
|
35334
|
+
const fetchFn = resolveFetch3(params.fetch);
|
|
34296
35335
|
if (typeof params.scope !== "string" || params.scope.length === 0) {
|
|
34297
35336
|
throw new WriteRequestError("scope is required");
|
|
34298
35337
|
}
|
|
@@ -34484,7 +35523,7 @@ function resolveRequest(params) {
|
|
|
34484
35523
|
"signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
|
|
34485
35524
|
);
|
|
34486
35525
|
}
|
|
34487
|
-
const fetchFn =
|
|
35526
|
+
const fetchFn = resolveFetch3(params.fetch);
|
|
34488
35527
|
const baseUrl = normalizeBaseUrl2(params.personalServerUrl);
|
|
34489
35528
|
const audience = params.audience ?? baseUrl;
|
|
34490
35529
|
return {
|
|
@@ -34817,7 +35856,7 @@ async function waitForQuestion(params) {
|
|
|
34817
35856
|
}
|
|
34818
35857
|
);
|
|
34819
35858
|
}
|
|
34820
|
-
await
|
|
35859
|
+
await sleep3(Math.min(pollIntervalMs, remaining));
|
|
34821
35860
|
}
|
|
34822
35861
|
}
|
|
34823
35862
|
async function askPersonalServer(params) {
|
|
@@ -34881,7 +35920,7 @@ function derivativeStatusTarget(derivedScope) {
|
|
|
34881
35920
|
function normalizeBaseUrl3(url) {
|
|
34882
35921
|
return url.replace(/\/+$/, "");
|
|
34883
35922
|
}
|
|
34884
|
-
function
|
|
35923
|
+
function resolveFetch4(fetchFn) {
|
|
34885
35924
|
const resolved = fetchFn ?? globalThis.fetch;
|
|
34886
35925
|
if (resolved === void 0) {
|
|
34887
35926
|
throw new WriteRequestError("No fetch implementation available");
|
|
@@ -34894,7 +35933,7 @@ function requireDerivedScope(derivedScope) {
|
|
|
34894
35933
|
}
|
|
34895
35934
|
return derivedScope;
|
|
34896
35935
|
}
|
|
34897
|
-
function
|
|
35936
|
+
function sleep4(ms, signal) {
|
|
34898
35937
|
if (ms <= 0) return Promise.resolve();
|
|
34899
35938
|
return new Promise((resolve, reject) => {
|
|
34900
35939
|
const timer = setTimeout(() => {
|
|
@@ -34930,7 +35969,7 @@ function isDerivativeStatusSettled(status) {
|
|
|
34930
35969
|
}
|
|
34931
35970
|
async function getDerivativeStatus(params) {
|
|
34932
35971
|
const derivedScope = requireDerivedScope(params.derivedScope);
|
|
34933
|
-
const fetchFn =
|
|
35972
|
+
const fetchFn = resolveFetch4(params.fetch);
|
|
34934
35973
|
const baseUrl = normalizeBaseUrl3(params.personalServerUrl);
|
|
34935
35974
|
const signer = resolveWriteSigner(params.signer, { account: params.account });
|
|
34936
35975
|
const headers = new Headers(params.headers);
|
|
@@ -35008,7 +36047,7 @@ async function waitForDerivativeStatus(params) {
|
|
|
35008
36047
|
if (waitMs > remaining) {
|
|
35009
36048
|
throw timeoutError(latest, timeoutMs);
|
|
35010
36049
|
}
|
|
35011
|
-
await
|
|
36050
|
+
await sleep4(waitMs, params.signal);
|
|
35012
36051
|
}
|
|
35013
36052
|
}
|
|
35014
36053
|
|
|
@@ -36041,7 +37080,7 @@ var KNOWN_CODES = /* @__PURE__ */ new Set([
|
|
|
36041
37080
|
"server_not_configured",
|
|
36042
37081
|
"content_too_large"
|
|
36043
37082
|
]);
|
|
36044
|
-
function
|
|
37083
|
+
function isRecord5(value) {
|
|
36045
37084
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
36046
37085
|
}
|
|
36047
37086
|
function normalizeCode(value) {
|
|
@@ -36052,10 +37091,10 @@ function normalizeCode(value) {
|
|
|
36052
37091
|
return KNOWN_CODES.has(code) ? code : null;
|
|
36053
37092
|
}
|
|
36054
37093
|
function extractPSErrorBody(body) {
|
|
36055
|
-
if (!
|
|
37094
|
+
if (!isRecord5(body)) {
|
|
36056
37095
|
return null;
|
|
36057
37096
|
}
|
|
36058
|
-
const nested =
|
|
37097
|
+
const nested = isRecord5(body.error) ? body.error : null;
|
|
36059
37098
|
const code = normalizeCode(
|
|
36060
37099
|
nested?.errorCode ?? nested?.code ?? body.errorCode ?? body.code
|
|
36061
37100
|
);
|
|
@@ -36086,6 +37125,8 @@ export {
|
|
|
36086
37125
|
BUILDER_REGISTRATION_TYPES,
|
|
36087
37126
|
BlockchainError,
|
|
36088
37127
|
BrowserPlatformAdapter,
|
|
37128
|
+
BuilderUnknownError,
|
|
37129
|
+
CLAIM_POLL_FLOOR_MS,
|
|
36089
37130
|
CONTRACTS,
|
|
36090
37131
|
CallbackStorage,
|
|
36091
37132
|
ContractFactory,
|
|
@@ -36094,6 +37135,8 @@ export {
|
|
|
36094
37135
|
DATA_REGISTRY_STATUS_ABI,
|
|
36095
37136
|
DEFAULT_DERIVATIVE_STATUS_POLL_INTERVAL_MS,
|
|
36096
37137
|
DEFAULT_DERIVATIVE_STATUS_TIMEOUT_MS,
|
|
37138
|
+
DEFAULT_JOB_DEADLINE_SECONDS,
|
|
37139
|
+
DEFAULT_LEASE_SECONDS,
|
|
36097
37140
|
DEFAULT_QUESTION_POLL_INTERVAL_MS,
|
|
36098
37141
|
DEFAULT_QUESTION_TIMEOUT_MS,
|
|
36099
37142
|
DERIVATIVE_ERROR_CODES,
|
|
@@ -36118,6 +37161,9 @@ export {
|
|
|
36118
37161
|
DerivativeStatusSchema,
|
|
36119
37162
|
DropboxStorage,
|
|
36120
37163
|
ECIESError,
|
|
37164
|
+
ENCLAVE_IDENTITY_EVIDENCE_VERSION,
|
|
37165
|
+
ENCLAVE_TRUST_ANCHORS,
|
|
37166
|
+
ENCLAVE_WALLET_PURPOSE,
|
|
36121
37167
|
ESCROW_DEPOSIT_ABI2 as ESCROW_DEPOSIT_ABI,
|
|
36122
37168
|
ExpiredTokenError,
|
|
36123
37169
|
FEE_REGISTRY_ABI,
|
|
@@ -36126,12 +37172,25 @@ export {
|
|
|
36126
37172
|
GRANT_REGISTRATION_TYPES,
|
|
36127
37173
|
GRANT_REVOCATION_TYPES,
|
|
36128
37174
|
GoogleDriveStorage,
|
|
37175
|
+
GrantInvalidError,
|
|
36129
37176
|
InMemoryTokenStore,
|
|
36130
37177
|
IngestResponseSchema,
|
|
36131
37178
|
InvalidConfigurationError,
|
|
36132
37179
|
InvalidScopeEntryError,
|
|
36133
37180
|
InvalidSignatureError,
|
|
36134
37181
|
IpfsStorage,
|
|
37182
|
+
JOB_OPERATIONS,
|
|
37183
|
+
JOB_PROTOCOL_VERSION,
|
|
37184
|
+
JOB_STATES,
|
|
37185
|
+
JobEnvelopeError,
|
|
37186
|
+
JobIdTakenError,
|
|
37187
|
+
JobNotFoundError,
|
|
37188
|
+
JobRejectedError,
|
|
37189
|
+
JobRequestTooLargeError,
|
|
37190
|
+
JobResultIntegrityError,
|
|
37191
|
+
JobTimeoutError,
|
|
37192
|
+
JobTransportError,
|
|
37193
|
+
JobsClientError,
|
|
36135
37194
|
LINEAGE_FIELD,
|
|
36136
37195
|
LINEAGE_KEY,
|
|
36137
37196
|
LineageEntrySchema,
|
|
@@ -36139,10 +37198,16 @@ export {
|
|
|
36139
37198
|
LineageNodeSchema,
|
|
36140
37199
|
LineageReadError,
|
|
36141
37200
|
MASTER_KEY_MESSAGE,
|
|
37201
|
+
MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS,
|
|
37202
|
+
MASTER_SIGNATURE_DELIVERY_VERSION,
|
|
37203
|
+
MAX_ATTEMPTS,
|
|
37204
|
+
MAX_JOB_DEADLINE_SECONDS,
|
|
37205
|
+
MAX_LEASE_SECONDS,
|
|
36142
37206
|
MAX_LINEAGE_SOURCES,
|
|
36143
37207
|
MAX_QUESTION_CHARS,
|
|
36144
37208
|
MAX_QUESTION_MODEL_CHARS,
|
|
36145
37209
|
MAX_QUESTION_SOURCE_SCOPES,
|
|
37210
|
+
MAX_WAIT_SECONDS,
|
|
36146
37211
|
MissingAuthError,
|
|
36147
37212
|
NATIVE_ASSET_ADDRESS,
|
|
36148
37213
|
NATIVE_VANA_ASSET,
|
|
@@ -36151,6 +37216,7 @@ export {
|
|
|
36151
37216
|
NodePlatformAdapter,
|
|
36152
37217
|
NonceError,
|
|
36153
37218
|
OAuthClient,
|
|
37219
|
+
OwnerNotReadyError,
|
|
36154
37220
|
PERSONAL_SERVER_LITE_OWNER_BINDING_PREFIX,
|
|
36155
37221
|
PERSONAL_SERVER_LITE_OWNER_BINDING_PURPOSE,
|
|
36156
37222
|
PERSONAL_SERVER_LITE_OWNER_BINDING_VERSION,
|
|
@@ -36176,6 +37242,7 @@ export {
|
|
|
36176
37242
|
RedactedLineageNodeSchema,
|
|
36177
37243
|
RelayerError,
|
|
36178
37244
|
SCOPE_ACTIONS,
|
|
37245
|
+
SEALED_ENVELOPE_VERSION,
|
|
36179
37246
|
SERVER_REGISTRATION_TYPES,
|
|
36180
37247
|
ScopeSchema,
|
|
36181
37248
|
SerializationError,
|
|
@@ -36188,6 +37255,7 @@ export {
|
|
|
36188
37255
|
TOMBSTONE_METADATA_HASH,
|
|
36189
37256
|
TOMBSTONE_METADATA_HASH_PREIMAGE,
|
|
36190
37257
|
TransactionPendingError,
|
|
37258
|
+
USER_PS_ID_DOMAIN,
|
|
36191
37259
|
UserRejectedRequestError,
|
|
36192
37260
|
VanaError,
|
|
36193
37261
|
VanaStorage,
|
|
@@ -36206,6 +37274,7 @@ export {
|
|
|
36206
37274
|
WriteSessionExpiredError,
|
|
36207
37275
|
WriteTransportError,
|
|
36208
37276
|
WriteUnauthorizedError,
|
|
37277
|
+
appRootPreimage,
|
|
36209
37278
|
askPersonalServer,
|
|
36210
37279
|
assertDerivedScopeNaming,
|
|
36211
37280
|
assertValidPkceVerifier,
|
|
@@ -36219,6 +37288,7 @@ export {
|
|
|
36219
37288
|
buildEscrowPaymentHeader,
|
|
36220
37289
|
buildGrantPaymentHeader,
|
|
36221
37290
|
buildMarkDataPointUnavailableRequest,
|
|
37291
|
+
buildMasterSignatureDelivery,
|
|
36222
37292
|
buildPersonalServerDataReadRequest,
|
|
36223
37293
|
buildPersonalServerLiteOwnerBindingMessage,
|
|
36224
37294
|
buildPersonalServerLiteOwnerBindingSignature,
|
|
@@ -36227,6 +37297,7 @@ export {
|
|
|
36227
37297
|
buildSetDataPointStatusRequest,
|
|
36228
37298
|
buildWeb3SignedHeader,
|
|
36229
37299
|
builderRegistrationDomain,
|
|
37300
|
+
canonicalJobRequestBytes,
|
|
36230
37301
|
chains,
|
|
36231
37302
|
clearContractCache,
|
|
36232
37303
|
computeBodyHash,
|
|
@@ -36238,6 +37309,7 @@ export {
|
|
|
36238
37309
|
createDefaultNonceSource,
|
|
36239
37310
|
createEscrowGatewayClient,
|
|
36240
37311
|
createGatewayClient,
|
|
37312
|
+
createJobsClient,
|
|
36241
37313
|
createNodePlatformAdapter,
|
|
36242
37314
|
createPlatformAdapter,
|
|
36243
37315
|
createPlatformAdapterFor,
|
|
@@ -36262,6 +37334,7 @@ export {
|
|
|
36262
37334
|
encodeDepositTokenData,
|
|
36263
37335
|
encodeSetDataPointStatusData,
|
|
36264
37336
|
encodeWriteMetadataHeader,
|
|
37337
|
+
encryptMasterSignatureDelivery,
|
|
36265
37338
|
encryptWithPassword,
|
|
36266
37339
|
escrowContractAddress,
|
|
36267
37340
|
escrowPaymentDomain,
|
|
@@ -36296,12 +37369,15 @@ export {
|
|
|
36296
37369
|
isPlatformSupported,
|
|
36297
37370
|
isRedactedLineageNode,
|
|
36298
37371
|
isTombstoneHashes,
|
|
37372
|
+
kmsIssuedPreimage,
|
|
36299
37373
|
listQuestions,
|
|
36300
37374
|
mainnetServices,
|
|
36301
37375
|
moksha,
|
|
36302
37376
|
mokshaServices,
|
|
36303
37377
|
mokshaTestnet2 as mokshaTestnet,
|
|
36304
37378
|
normalizeBinaryMimeType,
|
|
37379
|
+
openJobRequest,
|
|
37380
|
+
openJobResult,
|
|
36305
37381
|
openWriteSession,
|
|
36306
37382
|
parsePSError,
|
|
36307
37383
|
parsePersonalServerPaymentRequired,
|
|
@@ -36325,6 +37401,8 @@ export {
|
|
|
36325
37401
|
scopeMatchesPattern,
|
|
36326
37402
|
scopeNamespace,
|
|
36327
37403
|
scopeToPathSegments,
|
|
37404
|
+
sealJobRequest,
|
|
37405
|
+
sealJobResult,
|
|
36328
37406
|
serializeECIES,
|
|
36329
37407
|
serverRegistrationDomain,
|
|
36330
37408
|
sessionCoversScope,
|
|
@@ -36335,7 +37413,9 @@ export {
|
|
|
36335
37413
|
toDirectPaymentReceipt,
|
|
36336
37414
|
tombstoneDeletedAt,
|
|
36337
37415
|
tryGrantPermissions,
|
|
37416
|
+
userPsId,
|
|
36338
37417
|
vanaMainnet2 as vanaMainnet,
|
|
37418
|
+
verifyEnclaveIdentityEvidence,
|
|
36339
37419
|
verifyGrantRegistration,
|
|
36340
37420
|
verifyPkceChallenge,
|
|
36341
37421
|
verifyWeb3Signed,
|