@interfold/sdk 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -30
- package/dist/contracts/index.cjs +16 -2
- package/dist/contracts/index.cjs.map +1 -1
- package/dist/contracts/index.d.ts +2 -2
- package/dist/contracts/index.js +17 -2
- package/dist/contracts/index.js.map +1 -1
- package/dist/events/index.cjs +3 -0
- package/dist/events/index.cjs.map +1 -1
- package/dist/events/index.d.ts +24 -2
- package/dist/events/index.js +3 -0
- package/dist/events/index.js.map +1 -1
- package/dist/index.cjs +171 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +37 -9
- package/dist/index.js +169 -7
- package/dist/index.js.map +1 -1
- package/dist/{types-Cwx_flfX.d.ts → types-BJe3EYvv.d.ts} +8 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
CommitteePublicKeyAssembler: () => CommitteePublicKeyAssembler,
|
|
33
34
|
CommitteeSize: () => CommitteeSize,
|
|
34
35
|
ContractClient: () => ContractClient,
|
|
35
36
|
DEFAULT_COMPUTE_PROVIDER_PARAMS: () => DEFAULT_COMPUTE_PROVIDER_PARAMS,
|
|
@@ -40,6 +41,8 @@ __export(index_exports, {
|
|
|
40
41
|
FailureReason: () => FailureReason,
|
|
41
42
|
InterfoldEventType: () => InterfoldEventType,
|
|
42
43
|
InterfoldSDK: () => InterfoldSDK,
|
|
44
|
+
MAX_COMMITTEE_PUBLIC_KEY_BYTES: () => MAX_COMMITTEE_PUBLIC_KEY_BYTES,
|
|
45
|
+
MAX_COMMITTEE_PUBLIC_KEY_CHUNK_BYTES: () => MAX_COMMITTEE_PUBLIC_KEY_CHUNK_BYTES,
|
|
43
46
|
RandomnessProviderEventType: () => RandomnessProviderEventType,
|
|
44
47
|
RegistryEventType: () => RegistryEventType,
|
|
45
48
|
SDKError: () => SDKError,
|
|
@@ -398,7 +401,7 @@ var ContractClient = class _ContractClient {
|
|
|
398
401
|
throw new SDKError(`Failed to cancel E3: ${error}`, "CANCEL_E3_FAILED");
|
|
399
402
|
}
|
|
400
403
|
}
|
|
401
|
-
async publishCiphertextOutput(e3Id,
|
|
404
|
+
async publishCiphertextOutput(e3Id, outputReference, gasLimit) {
|
|
402
405
|
if (!this.walletClient) {
|
|
403
406
|
throw new SDKError("Wallet client required for write operations", "NO_WALLET");
|
|
404
407
|
}
|
|
@@ -407,11 +410,25 @@ var ContractClient = class _ContractClient {
|
|
|
407
410
|
if (!account) {
|
|
408
411
|
throw new SDKError("No account connected", "NO_ACCOUNT");
|
|
409
412
|
}
|
|
413
|
+
const encodedOutputReference = (0, import_viem2.encodeAbiParameters)(
|
|
414
|
+
[
|
|
415
|
+
{
|
|
416
|
+
type: "tuple",
|
|
417
|
+
components: [
|
|
418
|
+
{ name: "contentHash", type: "bytes32" },
|
|
419
|
+
{ name: "ciphertextCommitment", type: "bytes32" },
|
|
420
|
+
{ name: "computeProof", type: "bytes" },
|
|
421
|
+
{ name: "availabilityProof", type: "bytes" }
|
|
422
|
+
]
|
|
423
|
+
}
|
|
424
|
+
],
|
|
425
|
+
[outputReference]
|
|
426
|
+
);
|
|
410
427
|
const { request } = await this.publicClient.simulateContract({
|
|
411
428
|
address: this.contracts.interfold,
|
|
412
429
|
abi: import_types.Interfold__factory.abi,
|
|
413
430
|
functionName: "publishCiphertextOutput",
|
|
414
|
-
args: [e3Id,
|
|
431
|
+
args: [e3Id, encodedOutputReference],
|
|
415
432
|
account,
|
|
416
433
|
gas: gasLimit
|
|
417
434
|
});
|
|
@@ -537,6 +554,7 @@ var import_types3 = require("@interfold/contracts/types");
|
|
|
537
554
|
var InterfoldEventType = /* @__PURE__ */ ((InterfoldEventType2) => {
|
|
538
555
|
InterfoldEventType2["E3_REQUESTED"] = "E3Requested";
|
|
539
556
|
InterfoldEventType2["CIPHERTEXT_OUTPUT_PUBLISHED"] = "CiphertextOutputPublished";
|
|
557
|
+
InterfoldEventType2["CIPHERTEXT_OUTPUT_REFERENCE_PUBLISHED"] = "CiphertextOutputReferencePublished";
|
|
540
558
|
InterfoldEventType2["PLAINTEXT_OUTPUT_PUBLISHED"] = "PlaintextOutputPublished";
|
|
541
559
|
InterfoldEventType2["E3_PROGRAM_REGISTERED"] = "E3ProgramRegistered";
|
|
542
560
|
InterfoldEventType2["ENCRYPTION_SCHEME_ENABLED"] = "EncryptionSchemeEnabled";
|
|
@@ -552,6 +570,7 @@ var RegistryEventType = /* @__PURE__ */ ((RegistryEventType2) => {
|
|
|
552
570
|
RegistryEventType2["COMMITTEE_RANDOMNESS_REQUESTED"] = "CommitteeRandomnessRequested";
|
|
553
571
|
RegistryEventType2["RANDOMNESS_CIRCUIT_BREAKER_TRIPPED"] = "RandomnessCircuitBreakerTripped";
|
|
554
572
|
RegistryEventType2["COMMITTEE_PUBLISHED"] = "CommitteePublished";
|
|
573
|
+
RegistryEventType2["COMMITTEE_PUBLIC_KEY_CHUNK_PUBLISHED"] = "CommitteePublicKeyChunkPublished";
|
|
555
574
|
RegistryEventType2["COMMITTEE_FINALIZED"] = "SortitionCommitteeFinalized";
|
|
556
575
|
RegistryEventType2["INTERFOLD_SET"] = "InterfoldSet";
|
|
557
576
|
RegistryEventType2["OWNERSHIP_TRANSFERRED"] = "OwnershipTransferred";
|
|
@@ -591,6 +610,7 @@ var EventListener = class _EventListener {
|
|
|
591
610
|
"CommitteeRandomnessRequested" /* COMMITTEE_RANDOMNESS_REQUESTED */,
|
|
592
611
|
"RandomnessCircuitBreakerTripped" /* RANDOMNESS_CIRCUIT_BREAKER_TRIPPED */,
|
|
593
612
|
"CommitteePublished" /* COMMITTEE_PUBLISHED */,
|
|
613
|
+
"CommitteePublicKeyChunkPublished" /* COMMITTEE_PUBLIC_KEY_CHUNK_PUBLISHED */,
|
|
594
614
|
"SortitionCommitteeFinalized" /* COMMITTEE_FINALIZED */,
|
|
595
615
|
"InterfoldSet" /* INTERFOLD_SET */
|
|
596
616
|
]);
|
|
@@ -1190,9 +1210,9 @@ var InterfoldSDK = class _InterfoldSDK {
|
|
|
1190
1210
|
/**
|
|
1191
1211
|
* Validate serialized BFV public-key bytes before using them for encryption.
|
|
1192
1212
|
*
|
|
1193
|
-
*
|
|
1194
|
-
*
|
|
1195
|
-
*
|
|
1213
|
+
* A reassembled public key is an untrusted transport value. Consumers must
|
|
1214
|
+
* compare its semantic BFV commitment with the on-chain `pkCommitment`
|
|
1215
|
+
* before accepting it.
|
|
1196
1216
|
*/
|
|
1197
1217
|
async validatePublicKeyCommitment(publicKey, expectedCommitment) {
|
|
1198
1218
|
if (expectedCommitment.length !== 32) {
|
|
@@ -1232,8 +1252,8 @@ var InterfoldSDK = class _InterfoldSDK {
|
|
|
1232
1252
|
async getE3PublicKey(e3Id) {
|
|
1233
1253
|
return this.contractClient.getE3PublicKey(e3Id);
|
|
1234
1254
|
}
|
|
1235
|
-
async publishCiphertextOutput(e3Id,
|
|
1236
|
-
return this.contractClient.publishCiphertextOutput(e3Id,
|
|
1255
|
+
async publishCiphertextOutput(e3Id, outputReference, gasLimit) {
|
|
1256
|
+
return this.contractClient.publishCiphertextOutput(e3Id, outputReference, gasLimit);
|
|
1237
1257
|
}
|
|
1238
1258
|
async getE3(e3Id) {
|
|
1239
1259
|
return this.contractClient.getE3(e3Id);
|
|
@@ -1313,8 +1333,150 @@ var InterfoldSDK = class _InterfoldSDK {
|
|
|
1313
1333
|
});
|
|
1314
1334
|
}
|
|
1315
1335
|
};
|
|
1336
|
+
|
|
1337
|
+
// src/committee-public-key.ts
|
|
1338
|
+
var import_viem4 = require("viem");
|
|
1339
|
+
var MAX_COMMITTEE_PUBLIC_KEY_BYTES = 512 * 1024;
|
|
1340
|
+
var MAX_COMMITTEE_PUBLIC_KEY_CHUNK_BYTES = 90 * 1024;
|
|
1341
|
+
var DEFAULT_MAX_TRACKED_COMMITTEE_KEYS = 128;
|
|
1342
|
+
var CommitteePublicKeyAssembler = class {
|
|
1343
|
+
constructor(maxTrackedE3s = DEFAULT_MAX_TRACKED_COMMITTEE_KEYS) {
|
|
1344
|
+
this.maxTrackedE3s = maxTrackedE3s;
|
|
1345
|
+
if (!Number.isInteger(maxTrackedE3s) || maxTrackedE3s < 1) {
|
|
1346
|
+
throw new Error("Maximum tracked committee-key count must be a positive integer");
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
selectedCandidates = /* @__PURE__ */ new Map();
|
|
1350
|
+
assemblies = /* @__PURE__ */ new Map();
|
|
1351
|
+
invalidAssemblies = /* @__PURE__ */ new Set();
|
|
1352
|
+
completedAssemblies = /* @__PURE__ */ new Set();
|
|
1353
|
+
trackedE3s = /* @__PURE__ */ new Map();
|
|
1354
|
+
add(event) {
|
|
1355
|
+
const e3Key = event.e3Id.toString();
|
|
1356
|
+
this.track(e3Key);
|
|
1357
|
+
const metadata = validateEvent(event);
|
|
1358
|
+
const publisherKey = `${e3Key}:${event.publisher.toLowerCase()}`;
|
|
1359
|
+
const selectedCandidate = this.selectedCandidates.get(publisherKey);
|
|
1360
|
+
if (selectedCandidate && selectedCandidate.toLowerCase() !== metadata.candidateHash.toLowerCase()) {
|
|
1361
|
+
return void 0;
|
|
1362
|
+
}
|
|
1363
|
+
this.selectedCandidates.set(publisherKey, metadata.candidateHash);
|
|
1364
|
+
const assemblyKey = `${publisherKey}:${metadata.candidateHash.toLowerCase()}`;
|
|
1365
|
+
if (this.completedAssemblies.has(assemblyKey)) return void 0;
|
|
1366
|
+
if (this.invalidAssemblies.has(assemblyKey)) return void 0;
|
|
1367
|
+
const assembly = this.assemblies.get(assemblyKey) ?? {
|
|
1368
|
+
nodes: [...event.nodes],
|
|
1369
|
+
pkCommitment: metadata.pkCommitment,
|
|
1370
|
+
candidateHash: metadata.candidateHash,
|
|
1371
|
+
totalLength: event.totalLength,
|
|
1372
|
+
chunks: Array.from({ length: event.chunkCount }).fill(void 0)
|
|
1373
|
+
};
|
|
1374
|
+
if (!metadataMatches(assembly, event, metadata.pkCommitment)) {
|
|
1375
|
+
this.assemblies.delete(assemblyKey);
|
|
1376
|
+
this.invalidAssemblies.add(assemblyKey);
|
|
1377
|
+
return void 0;
|
|
1378
|
+
}
|
|
1379
|
+
const existing = assembly.chunks[event.chunkIndex];
|
|
1380
|
+
if (existing && !bytesEqual(existing, metadata.chunk)) {
|
|
1381
|
+
this.assemblies.delete(assemblyKey);
|
|
1382
|
+
this.invalidAssemblies.add(assemblyKey);
|
|
1383
|
+
return void 0;
|
|
1384
|
+
}
|
|
1385
|
+
assembly.chunks[event.chunkIndex] = metadata.chunk;
|
|
1386
|
+
this.assemblies.set(assemblyKey, assembly);
|
|
1387
|
+
if (assembly.chunks.some((chunk) => chunk === void 0)) return void 0;
|
|
1388
|
+
const publicKey = new Uint8Array(assembly.totalLength);
|
|
1389
|
+
let offset = 0;
|
|
1390
|
+
for (const chunk of assembly.chunks) {
|
|
1391
|
+
publicKey.set(chunk, offset);
|
|
1392
|
+
offset += chunk.length;
|
|
1393
|
+
}
|
|
1394
|
+
if (offset !== assembly.totalLength || (0, import_viem4.keccak256)(publicKey).toLowerCase() !== assembly.candidateHash.toLowerCase()) {
|
|
1395
|
+
this.assemblies.delete(assemblyKey);
|
|
1396
|
+
this.invalidAssemblies.add(assemblyKey);
|
|
1397
|
+
return void 0;
|
|
1398
|
+
}
|
|
1399
|
+
this.completedAssemblies.add(assemblyKey);
|
|
1400
|
+
this.assemblies.delete(assemblyKey);
|
|
1401
|
+
return {
|
|
1402
|
+
e3Id: event.e3Id,
|
|
1403
|
+
nodes: assembly.nodes,
|
|
1404
|
+
pkCommitment: assembly.pkCommitment,
|
|
1405
|
+
publicKey
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1408
|
+
clear(e3Id) {
|
|
1409
|
+
const e3Key = e3Id.toString();
|
|
1410
|
+
this.trackedE3s.delete(e3Key);
|
|
1411
|
+
this.dropE3(e3Key);
|
|
1412
|
+
}
|
|
1413
|
+
track(e3Key) {
|
|
1414
|
+
this.trackedE3s.delete(e3Key);
|
|
1415
|
+
this.trackedE3s.set(e3Key, true);
|
|
1416
|
+
while (this.trackedE3s.size > this.maxTrackedE3s) {
|
|
1417
|
+
const oldest = this.trackedE3s.keys().next().value;
|
|
1418
|
+
if (oldest === void 0) return;
|
|
1419
|
+
this.trackedE3s.delete(oldest);
|
|
1420
|
+
this.dropE3(oldest);
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
dropE3(e3Key) {
|
|
1424
|
+
const prefix = `${e3Key}:`;
|
|
1425
|
+
for (const key of this.selectedCandidates.keys()) {
|
|
1426
|
+
if (key.startsWith(prefix)) this.selectedCandidates.delete(key);
|
|
1427
|
+
}
|
|
1428
|
+
for (const key of this.assemblies.keys()) {
|
|
1429
|
+
if (key.startsWith(prefix)) this.assemblies.delete(key);
|
|
1430
|
+
}
|
|
1431
|
+
for (const key of this.invalidAssemblies) {
|
|
1432
|
+
if (key.startsWith(prefix)) this.invalidAssemblies.delete(key);
|
|
1433
|
+
}
|
|
1434
|
+
for (const key of this.completedAssemblies) {
|
|
1435
|
+
if (key.startsWith(prefix)) this.completedAssemblies.delete(key);
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
};
|
|
1439
|
+
function validateEvent(event) {
|
|
1440
|
+
if (!isBytes32(event.candidateHash) || !isBytes32(event.pkCommitment)) {
|
|
1441
|
+
throw new Error("Committee public-key chunk contains an invalid bytes32 value");
|
|
1442
|
+
}
|
|
1443
|
+
if (!Number.isInteger(event.totalLength) || event.totalLength <= 0 || event.totalLength > MAX_COMMITTEE_PUBLIC_KEY_BYTES) {
|
|
1444
|
+
throw new Error("Committee public-key total length is outside the supported range");
|
|
1445
|
+
}
|
|
1446
|
+
const expectedChunkCount = Math.ceil(event.totalLength / MAX_COMMITTEE_PUBLIC_KEY_CHUNK_BYTES);
|
|
1447
|
+
if (!Number.isInteger(event.chunkCount) || event.chunkCount !== expectedChunkCount) {
|
|
1448
|
+
throw new Error("Committee public-key chunk count does not match the total length");
|
|
1449
|
+
}
|
|
1450
|
+
if (!Number.isInteger(event.chunkIndex) || event.chunkIndex < 0 || event.chunkIndex >= event.chunkCount) {
|
|
1451
|
+
throw new Error("Committee public-key chunk index is outside the candidate range");
|
|
1452
|
+
}
|
|
1453
|
+
if (!(0, import_viem4.isHex)(event.chunk)) {
|
|
1454
|
+
throw new Error("Committee public-key chunk is not valid hex");
|
|
1455
|
+
}
|
|
1456
|
+
const chunk = (0, import_viem4.hexToBytes)(event.chunk);
|
|
1457
|
+
const remaining = event.totalLength - event.chunkIndex * MAX_COMMITTEE_PUBLIC_KEY_CHUNK_BYTES;
|
|
1458
|
+
const expectedLength = Math.min(remaining, MAX_COMMITTEE_PUBLIC_KEY_CHUNK_BYTES);
|
|
1459
|
+
if (chunk.length !== expectedLength) {
|
|
1460
|
+
throw new Error("Committee public-key chunk length does not match its index");
|
|
1461
|
+
}
|
|
1462
|
+
return {
|
|
1463
|
+
candidateHash: event.candidateHash,
|
|
1464
|
+
pkCommitment: event.pkCommitment,
|
|
1465
|
+
chunk
|
|
1466
|
+
};
|
|
1467
|
+
}
|
|
1468
|
+
function metadataMatches(assembly, event, pkCommitment) {
|
|
1469
|
+
return assembly.totalLength === event.totalLength && assembly.chunks.length === event.chunkCount && assembly.pkCommitment.toLowerCase() === pkCommitment.toLowerCase() && assembly.nodes.length === event.nodes.length && assembly.nodes.every((node, index) => node.toLowerCase() === event.nodes[index]?.toLowerCase());
|
|
1470
|
+
}
|
|
1471
|
+
function isBytes32(value) {
|
|
1472
|
+
return /^0x[0-9a-fA-F]{64}$/.test(value);
|
|
1473
|
+
}
|
|
1474
|
+
function bytesEqual(left, right) {
|
|
1475
|
+
return left.length === right.length && left.every((byte, index) => byte === right[index]);
|
|
1476
|
+
}
|
|
1316
1477
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1317
1478
|
0 && (module.exports = {
|
|
1479
|
+
CommitteePublicKeyAssembler,
|
|
1318
1480
|
CommitteeSize,
|
|
1319
1481
|
ContractClient,
|
|
1320
1482
|
DEFAULT_COMPUTE_PROVIDER_PARAMS,
|
|
@@ -1325,6 +1487,8 @@ var InterfoldSDK = class _InterfoldSDK {
|
|
|
1325
1487
|
FailureReason,
|
|
1326
1488
|
InterfoldEventType,
|
|
1327
1489
|
InterfoldSDK,
|
|
1490
|
+
MAX_COMMITTEE_PUBLIC_KEY_BYTES,
|
|
1491
|
+
MAX_COMMITTEE_PUBLIC_KEY_CHUNK_BYTES,
|
|
1328
1492
|
RandomnessProviderEventType,
|
|
1329
1493
|
RegistryEventType,
|
|
1330
1494
|
SDKError,
|