@did-btcr2/method 0.35.0 → 0.36.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/dist/.tsbuildinfo +1 -1
- package/dist/browser.js +146 -56
- package/dist/browser.mjs +146 -56
- package/dist/cjs/index.js +146 -55
- package/dist/esm/core/aggregation/cohort.js +3 -1
- package/dist/esm/core/aggregation/cohort.js.map +1 -1
- package/dist/esm/core/aggregation/conditions.js +75 -0
- package/dist/esm/core/aggregation/conditions.js.map +1 -0
- package/dist/esm/core/aggregation/messages/base.js.map +1 -1
- package/dist/esm/core/aggregation/messages/bodies.js +16 -2
- package/dist/esm/core/aggregation/messages/bodies.js.map +1 -1
- package/dist/esm/core/aggregation/messages/factories.js.map +1 -1
- package/dist/esm/core/aggregation/participant.js +9 -7
- package/dist/esm/core/aggregation/participant.js.map +1 -1
- package/dist/esm/core/aggregation/runner/service-runner.js +8 -0
- package/dist/esm/core/aggregation/runner/service-runner.js.map +1 -1
- package/dist/esm/core/aggregation/service.js +23 -3
- package/dist/esm/core/aggregation/service.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/types/core/aggregation/cohort.d.ts.map +1 -1
- package/dist/types/core/aggregation/conditions.d.ts +58 -0
- package/dist/types/core/aggregation/conditions.d.ts.map +1 -0
- package/dist/types/core/aggregation/messages/base.d.ts +2 -3
- package/dist/types/core/aggregation/messages/base.d.ts.map +1 -1
- package/dist/types/core/aggregation/messages/bodies.d.ts +2 -3
- package/dist/types/core/aggregation/messages/bodies.d.ts.map +1 -1
- package/dist/types/core/aggregation/messages/factories.d.ts +2 -3
- package/dist/types/core/aggregation/messages/factories.d.ts.map +1 -1
- package/dist/types/core/aggregation/participant.d.ts +7 -4
- package/dist/types/core/aggregation/participant.d.ts.map +1 -1
- package/dist/types/core/aggregation/runner/service-runner.d.ts.map +1 -1
- package/dist/types/core/aggregation/service.d.ts +8 -4
- package/dist/types/core/aggregation/service.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/core/aggregation/cohort.ts +3 -1
- package/src/core/aggregation/conditions.ts +116 -0
- package/src/core/aggregation/messages/base.ts +6 -3
- package/src/core/aggregation/messages/bodies.ts +18 -6
- package/src/core/aggregation/messages/factories.ts +2 -3
- package/src/core/aggregation/participant.ts +16 -11
- package/src/core/aggregation/runner/service-runner.ts +9 -0
- package/src/core/aggregation/service.ts +39 -7
- package/src/index.ts +1 -0
package/dist/browser.js
CHANGED
|
@@ -93203,6 +93203,7 @@ a=end-of-candidates
|
|
|
93203
93203
|
InMemoryRateLimitStore: () => InMemoryRateLimitStore,
|
|
93204
93204
|
InMemoryTransport: () => InMemoryTransport,
|
|
93205
93205
|
InboxBuffer: () => InboxBuffer,
|
|
93206
|
+
KNOWN_BEACON_TYPES: () => KNOWN_BEACON_TYPES,
|
|
93206
93207
|
KeyPairAggregationSigner: () => KeyPairAggregationSigner,
|
|
93207
93208
|
NONCE_CONTRIBUTION: () => NONCE_CONTRIBUTION,
|
|
93208
93209
|
NonceCache: () => NonceCache,
|
|
@@ -93275,6 +93276,7 @@ a=end-of-candidates
|
|
|
93275
93276
|
registerBeaconStrategy: () => registerBeaconStrategy,
|
|
93276
93277
|
reviveFromWire: () => reviveFromWire,
|
|
93277
93278
|
signEnvelope: () => signEnvelope,
|
|
93279
|
+
validateCohortConditions: () => validateCohortConditions,
|
|
93278
93280
|
verifyEnvelope: () => verifyEnvelope,
|
|
93279
93281
|
verifyRequestAuth: () => verifyRequestAuth
|
|
93280
93282
|
});
|
|
@@ -103381,7 +103383,7 @@ a=end-of-candidates
|
|
|
103381
103383
|
validationRejections = /* @__PURE__ */ new Set();
|
|
103382
103384
|
constructor({ id, minParticipants, serviceDid, network, beaconType }) {
|
|
103383
103385
|
this.id = id || crypto.randomUUID();
|
|
103384
|
-
this.minParticipants = minParticipants
|
|
103386
|
+
this.minParticipants = minParticipants ?? 2;
|
|
103385
103387
|
this.serviceDid = serviceDid || "";
|
|
103386
103388
|
this.network = network;
|
|
103387
103389
|
this.beaconType = beaconType || "CASBeacon";
|
|
@@ -103547,6 +103549,57 @@ a=end-of-candidates
|
|
|
103547
103549
|
}
|
|
103548
103550
|
};
|
|
103549
103551
|
|
|
103552
|
+
// src/core/aggregation/conditions.ts
|
|
103553
|
+
init_shim();
|
|
103554
|
+
var KNOWN_BEACON_TYPES = ["CASBeacon", "SMTBeacon"];
|
|
103555
|
+
function checkPair(problems, label, min, max) {
|
|
103556
|
+
if (min !== void 0 && (!Number.isInteger(min) || min < 0)) {
|
|
103557
|
+
problems.push(`min${label} must be an integer >= 0`);
|
|
103558
|
+
}
|
|
103559
|
+
if (max !== void 0 && (!Number.isInteger(max) || max < 0)) {
|
|
103560
|
+
problems.push(`max${label} must be an integer >= 0`);
|
|
103561
|
+
}
|
|
103562
|
+
if (min !== void 0 && max !== void 0 && Number.isInteger(min) && Number.isInteger(max) && max < min) {
|
|
103563
|
+
problems.push(`max${label} must be >= min${label}`);
|
|
103564
|
+
}
|
|
103565
|
+
}
|
|
103566
|
+
function checkCost(problems, label, cost) {
|
|
103567
|
+
if (cost === void 0) return;
|
|
103568
|
+
if (typeof cost.amount !== "number" || !Number.isFinite(cost.amount) || cost.amount < 0) {
|
|
103569
|
+
problems.push(`${label}.amount must be a finite number >= 0`);
|
|
103570
|
+
}
|
|
103571
|
+
if (typeof cost.unit !== "string" || cost.unit.length === 0) {
|
|
103572
|
+
problems.push(`${label}.unit must be a non-empty string`);
|
|
103573
|
+
}
|
|
103574
|
+
if (cost.basis !== void 0 && cost.basis !== "per-did" && cost.basis !== "per-participant") {
|
|
103575
|
+
problems.push(`${label}.basis must be 'per-did' or 'per-participant'`);
|
|
103576
|
+
}
|
|
103577
|
+
}
|
|
103578
|
+
function validateCohortConditions(c2) {
|
|
103579
|
+
const problems = [];
|
|
103580
|
+
if (!KNOWN_BEACON_TYPES.includes(c2.beaconType)) {
|
|
103581
|
+
problems.push(`beaconType must be one of ${KNOWN_BEACON_TYPES.join(", ")}`);
|
|
103582
|
+
}
|
|
103583
|
+
if (!Number.isInteger(c2.minParticipants) || c2.minParticipants < 1) {
|
|
103584
|
+
problems.push("minParticipants must be an integer >= 1");
|
|
103585
|
+
}
|
|
103586
|
+
if (c2.maxParticipants !== void 0) {
|
|
103587
|
+
if (!Number.isInteger(c2.maxParticipants) || c2.maxParticipants < 1) {
|
|
103588
|
+
problems.push("maxParticipants must be an integer >= 1");
|
|
103589
|
+
} else if (Number.isInteger(c2.minParticipants) && c2.maxParticipants < c2.minParticipants) {
|
|
103590
|
+
problems.push("maxParticipants must be >= minParticipants");
|
|
103591
|
+
}
|
|
103592
|
+
}
|
|
103593
|
+
checkPair(problems, "DidsPerParticipant", c2.minDidsPerParticipant, c2.maxDidsPerParticipant);
|
|
103594
|
+
checkPair(problems, "SecondsBetweenAnnouncements", c2.minSecondsBetweenAnnouncements, c2.maxSecondsBetweenAnnouncements);
|
|
103595
|
+
if (c2.pendingUpdateTrigger !== void 0 && (!Number.isInteger(c2.pendingUpdateTrigger) || c2.pendingUpdateTrigger < 1)) {
|
|
103596
|
+
problems.push("pendingUpdateTrigger must be an integer >= 1");
|
|
103597
|
+
}
|
|
103598
|
+
checkCost(problems, "costOfEnrollment", c2.costOfEnrollment);
|
|
103599
|
+
checkCost(problems, "costPerAnnouncement", c2.costPerAnnouncement);
|
|
103600
|
+
return problems;
|
|
103601
|
+
}
|
|
103602
|
+
|
|
103550
103603
|
// src/core/aggregation/messages/base.ts
|
|
103551
103604
|
init_shim();
|
|
103552
103605
|
var AGGREGATION_WIRE_VERSION = 1;
|
|
@@ -103981,6 +104034,14 @@ a=end-of-candidates
|
|
|
103981
104034
|
* Cohort starts in `Created` phase — call `advertise()` to broadcast.
|
|
103982
104035
|
*/
|
|
103983
104036
|
createCohort(config) {
|
|
104037
|
+
const problems = validateCohortConditions(config);
|
|
104038
|
+
if (problems.length > 0) {
|
|
104039
|
+
throw new AggregationServiceError(
|
|
104040
|
+
`Invalid cohort conditions: ${problems.join("; ")}`,
|
|
104041
|
+
"INVALID_COHORT_CONDITIONS",
|
|
104042
|
+
{ problems }
|
|
104043
|
+
);
|
|
104044
|
+
}
|
|
103984
104045
|
const cohort = new AggregationCohort({
|
|
103985
104046
|
serviceDid: this.did,
|
|
103986
104047
|
minParticipants: config.minParticipants,
|
|
@@ -104013,13 +104074,13 @@ a=end-of-candidates
|
|
|
104013
104074
|
{ cohortId, phase: state.phase }
|
|
104014
104075
|
);
|
|
104015
104076
|
}
|
|
104077
|
+
const { network, ...conditions } = state.config;
|
|
104016
104078
|
const message2 = createCohortAdvertMessage({
|
|
104017
104079
|
from: this.did,
|
|
104018
104080
|
cohortId,
|
|
104019
|
-
|
|
104020
|
-
|
|
104021
|
-
|
|
104022
|
-
communicationPk: this.publicKey.compressed
|
|
104081
|
+
network,
|
|
104082
|
+
communicationPk: this.publicKey.compressed,
|
|
104083
|
+
...conditions
|
|
104023
104084
|
});
|
|
104024
104085
|
state.phase = "Advertised" /* Advertised */;
|
|
104025
104086
|
return [message2];
|
|
@@ -104078,6 +104139,14 @@ a=end-of-candidates
|
|
|
104078
104139
|
{ cohortId, participantDid }
|
|
104079
104140
|
);
|
|
104080
104141
|
}
|
|
104142
|
+
const maxParticipants = state.config.maxParticipants;
|
|
104143
|
+
if (maxParticipants !== void 0 && state.acceptedParticipants.size >= maxParticipants) {
|
|
104144
|
+
throw new AggregationServiceError(
|
|
104145
|
+
`Cohort ${cohortId} is full: ${maxParticipants} participants already accepted.`,
|
|
104146
|
+
"COHORT_FULL",
|
|
104147
|
+
{ cohortId, maxParticipants }
|
|
104148
|
+
);
|
|
104149
|
+
}
|
|
104081
104150
|
state.acceptedParticipants.add(participantDid);
|
|
104082
104151
|
state.cohort.participants.push(participantDid);
|
|
104083
104152
|
state.cohort.participantKeys.set(participantDid, optIn.participantPk);
|
|
@@ -104111,6 +104180,14 @@ a=end-of-candidates
|
|
|
104111
104180
|
{ cohortId }
|
|
104112
104181
|
);
|
|
104113
104182
|
}
|
|
104183
|
+
const maxParticipants = state.config.maxParticipants;
|
|
104184
|
+
if (maxParticipants !== void 0 && state.acceptedParticipants.size > maxParticipants) {
|
|
104185
|
+
throw new AggregationServiceError(
|
|
104186
|
+
`Cohort ${cohortId} has ${state.acceptedParticipants.size} accepted participants, exceeds max ${maxParticipants}.`,
|
|
104187
|
+
"TOO_MANY_PARTICIPANTS",
|
|
104188
|
+
{ cohortId, maxParticipants }
|
|
104189
|
+
);
|
|
104190
|
+
}
|
|
104114
104191
|
const beaconAddress = state.cohort.computeBeaconAddress();
|
|
104115
104192
|
state.phase = "CohortSet" /* CohortSet */;
|
|
104116
104193
|
const messages2 = [];
|
|
@@ -104428,6 +104505,59 @@ a=end-of-candidates
|
|
|
104428
104505
|
// src/core/aggregation/participant.ts
|
|
104429
104506
|
init_shim();
|
|
104430
104507
|
init_utils();
|
|
104508
|
+
|
|
104509
|
+
// src/core/aggregation/messages/bodies.ts
|
|
104510
|
+
init_shim();
|
|
104511
|
+
var hasStr = (b, k) => !!b && typeof b[k] === "string";
|
|
104512
|
+
var hasIntMin = (b, k, min) => {
|
|
104513
|
+
const v = b ? b[k] : void 0;
|
|
104514
|
+
return typeof v === "number" && Number.isInteger(v) && v >= min;
|
|
104515
|
+
};
|
|
104516
|
+
var optIntMin = (b, k, min) => {
|
|
104517
|
+
const v = b ? b[k] : void 0;
|
|
104518
|
+
return v === void 0 || typeof v === "number" && Number.isInteger(v) && v >= min;
|
|
104519
|
+
};
|
|
104520
|
+
var hasBool = (b, k) => !!b && typeof b[k] === "boolean";
|
|
104521
|
+
var hasBytes = (b, k) => !!b && b[k] instanceof Uint8Array;
|
|
104522
|
+
var hasBytesArray = (b, k) => {
|
|
104523
|
+
const v = b ? b[k] : void 0;
|
|
104524
|
+
return Array.isArray(v) && v.every((x) => x instanceof Uint8Array);
|
|
104525
|
+
};
|
|
104526
|
+
function isCohortAdvertMessage(m2) {
|
|
104527
|
+
return m2.type === COHORT_ADVERT && hasStr(m2.body, "cohortId") && hasIntMin(m2.body, "minParticipants", 1) && optIntMin(m2.body, "maxParticipants", 1) && hasStr(m2.body, "beaconType") && hasStr(m2.body, "network") && hasBytes(m2.body, "communicationPk");
|
|
104528
|
+
}
|
|
104529
|
+
function isCohortOptInMessage(m2) {
|
|
104530
|
+
return m2.type === COHORT_OPT_IN && hasStr(m2.body, "cohortId") && hasBytes(m2.body, "participantPk") && hasBytes(m2.body, "communicationPk");
|
|
104531
|
+
}
|
|
104532
|
+
function isCohortOptInAcceptMessage(m2) {
|
|
104533
|
+
return m2.type === COHORT_OPT_IN_ACCEPT && hasStr(m2.body, "cohortId");
|
|
104534
|
+
}
|
|
104535
|
+
function isCohortReadyMessage(m2) {
|
|
104536
|
+
return m2.type === COHORT_READY && hasStr(m2.body, "cohortId") && hasStr(m2.body, "beaconAddress") && hasBytesArray(m2.body, "cohortKeys");
|
|
104537
|
+
}
|
|
104538
|
+
function isSubmitUpdateMessage(m2) {
|
|
104539
|
+
return m2.type === SUBMIT_UPDATE && hasStr(m2.body, "cohortId") && !!m2.body && typeof m2.body.signedUpdate === "object";
|
|
104540
|
+
}
|
|
104541
|
+
function isDistributeAggregatedDataMessage(m2) {
|
|
104542
|
+
return m2.type === DISTRIBUTE_AGGREGATED_DATA && hasStr(m2.body, "cohortId") && hasStr(m2.body, "beaconType") && hasStr(m2.body, "signalBytesHex");
|
|
104543
|
+
}
|
|
104544
|
+
function isValidationAckMessage(m2) {
|
|
104545
|
+
return m2.type === VALIDATION_ACK && hasStr(m2.body, "cohortId") && hasBool(m2.body, "approved");
|
|
104546
|
+
}
|
|
104547
|
+
function isAuthorizationRequestMessage(m2) {
|
|
104548
|
+
return m2.type === AUTHORIZATION_REQUEST && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasStr(m2.body, "pendingTx") && hasStr(m2.body, "prevOutScriptHex") && hasStr(m2.body, "prevOutValue");
|
|
104549
|
+
}
|
|
104550
|
+
function isNonceContributionMessage(m2) {
|
|
104551
|
+
return m2.type === NONCE_CONTRIBUTION && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "nonceContribution");
|
|
104552
|
+
}
|
|
104553
|
+
function isAggregatedNonceMessage(m2) {
|
|
104554
|
+
return m2.type === AGGREGATED_NONCE && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "aggregatedNonce");
|
|
104555
|
+
}
|
|
104556
|
+
function isSignatureAuthorizationMessage(m2) {
|
|
104557
|
+
return m2.type === SIGNATURE_AUTHORIZATION && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "partialSignature");
|
|
104558
|
+
}
|
|
104559
|
+
|
|
104560
|
+
// src/core/aggregation/participant.ts
|
|
104431
104561
|
var AggregationParticipant = class {
|
|
104432
104562
|
did;
|
|
104433
104563
|
/** MuSig2 signing capability. The raw secret never lives as a field here. */
|
|
@@ -104485,16 +104615,15 @@ a=end-of-candidates
|
|
|
104485
104615
|
return map3;
|
|
104486
104616
|
}
|
|
104487
104617
|
#handleCohortAdvert(message2) {
|
|
104488
|
-
|
|
104489
|
-
|
|
104618
|
+
if (!isCohortAdvertMessage(message2)) return;
|
|
104619
|
+
const { cohortId, network, communicationPk, ...conditions } = message2.body;
|
|
104490
104620
|
if (this.#cohortStates.has(cohortId)) return;
|
|
104491
104621
|
const advert = {
|
|
104492
104622
|
cohortId,
|
|
104493
104623
|
serviceDid: message2.from,
|
|
104494
|
-
|
|
104495
|
-
|
|
104496
|
-
|
|
104497
|
-
serviceCommunicationPk: message2.body?.communicationPk ?? new Uint8Array()
|
|
104624
|
+
network,
|
|
104625
|
+
serviceCommunicationPk: communicationPk,
|
|
104626
|
+
...conditions
|
|
104498
104627
|
};
|
|
104499
104628
|
this.#cohortStates.set(cohortId, {
|
|
104500
104629
|
phase: "Discovered" /* Discovered */,
|
|
@@ -104519,7 +104648,7 @@ a=end-of-candidates
|
|
|
104519
104648
|
const cohort = new AggregationCohort({
|
|
104520
104649
|
id: cohortId,
|
|
104521
104650
|
serviceDid: state.serviceDid,
|
|
104522
|
-
minParticipants: state.advert.
|
|
104651
|
+
minParticipants: state.advert.minParticipants,
|
|
104523
104652
|
network: state.advert.network,
|
|
104524
104653
|
beaconType: state.advert.beaconType
|
|
104525
104654
|
});
|
|
@@ -104842,50 +104971,6 @@ a=end-of-candidates
|
|
|
104842
104971
|
// src/core/aggregation/messages/index.ts
|
|
104843
104972
|
init_shim();
|
|
104844
104973
|
|
|
104845
|
-
// src/core/aggregation/messages/bodies.ts
|
|
104846
|
-
init_shim();
|
|
104847
|
-
var hasStr = (b, k) => !!b && typeof b[k] === "string";
|
|
104848
|
-
var hasNum = (b, k) => !!b && typeof b[k] === "number";
|
|
104849
|
-
var hasBool = (b, k) => !!b && typeof b[k] === "boolean";
|
|
104850
|
-
var hasBytes = (b, k) => !!b && b[k] instanceof Uint8Array;
|
|
104851
|
-
var hasBytesArray = (b, k) => {
|
|
104852
|
-
const v = b ? b[k] : void 0;
|
|
104853
|
-
return Array.isArray(v) && v.every((x) => x instanceof Uint8Array);
|
|
104854
|
-
};
|
|
104855
|
-
function isCohortAdvertMessage(m2) {
|
|
104856
|
-
return m2.type === COHORT_ADVERT && hasStr(m2.body, "cohortId") && hasNum(m2.body, "cohortSize") && hasStr(m2.body, "beaconType") && hasStr(m2.body, "network") && hasBytes(m2.body, "communicationPk");
|
|
104857
|
-
}
|
|
104858
|
-
function isCohortOptInMessage(m2) {
|
|
104859
|
-
return m2.type === COHORT_OPT_IN && hasStr(m2.body, "cohortId") && hasBytes(m2.body, "participantPk") && hasBytes(m2.body, "communicationPk");
|
|
104860
|
-
}
|
|
104861
|
-
function isCohortOptInAcceptMessage(m2) {
|
|
104862
|
-
return m2.type === COHORT_OPT_IN_ACCEPT && hasStr(m2.body, "cohortId");
|
|
104863
|
-
}
|
|
104864
|
-
function isCohortReadyMessage(m2) {
|
|
104865
|
-
return m2.type === COHORT_READY && hasStr(m2.body, "cohortId") && hasStr(m2.body, "beaconAddress") && hasBytesArray(m2.body, "cohortKeys");
|
|
104866
|
-
}
|
|
104867
|
-
function isSubmitUpdateMessage(m2) {
|
|
104868
|
-
return m2.type === SUBMIT_UPDATE && hasStr(m2.body, "cohortId") && !!m2.body && typeof m2.body.signedUpdate === "object";
|
|
104869
|
-
}
|
|
104870
|
-
function isDistributeAggregatedDataMessage(m2) {
|
|
104871
|
-
return m2.type === DISTRIBUTE_AGGREGATED_DATA && hasStr(m2.body, "cohortId") && hasStr(m2.body, "beaconType") && hasStr(m2.body, "signalBytesHex");
|
|
104872
|
-
}
|
|
104873
|
-
function isValidationAckMessage(m2) {
|
|
104874
|
-
return m2.type === VALIDATION_ACK && hasStr(m2.body, "cohortId") && hasBool(m2.body, "approved");
|
|
104875
|
-
}
|
|
104876
|
-
function isAuthorizationRequestMessage(m2) {
|
|
104877
|
-
return m2.type === AUTHORIZATION_REQUEST && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasStr(m2.body, "pendingTx") && hasStr(m2.body, "prevOutScriptHex") && hasStr(m2.body, "prevOutValue");
|
|
104878
|
-
}
|
|
104879
|
-
function isNonceContributionMessage(m2) {
|
|
104880
|
-
return m2.type === NONCE_CONTRIBUTION && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "nonceContribution");
|
|
104881
|
-
}
|
|
104882
|
-
function isAggregatedNonceMessage(m2) {
|
|
104883
|
-
return m2.type === AGGREGATED_NONCE && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "aggregatedNonce");
|
|
104884
|
-
}
|
|
104885
|
-
function isSignatureAuthorizationMessage(m2) {
|
|
104886
|
-
return m2.type === SIGNATURE_AUTHORIZATION && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "partialSignature");
|
|
104887
|
-
}
|
|
104888
|
-
|
|
104889
104974
|
// src/core/aggregation/messages/guards.ts
|
|
104890
104975
|
init_shim();
|
|
104891
104976
|
var KEYGEN_VALUES = /* @__PURE__ */ new Set([
|
|
@@ -111731,6 +111816,11 @@ ${value2}`;
|
|
|
111731
111816
|
}
|
|
111732
111817
|
const decision = await this.#onOptInReceived(optIn);
|
|
111733
111818
|
if (!decision.accepted) return;
|
|
111819
|
+
const maxParticipants = this.#config.maxParticipants;
|
|
111820
|
+
const cohortNow = this.session.getCohort(this.#cohortId);
|
|
111821
|
+
if (maxParticipants !== void 0 && cohortNow && cohortNow.participants.length >= maxParticipants) {
|
|
111822
|
+
return;
|
|
111823
|
+
}
|
|
111734
111824
|
await this.#sendAll(this.session.acceptParticipant(this.#cohortId, msg.from));
|
|
111735
111825
|
this.emit("participant-accepted", { participantDid: msg.from });
|
|
111736
111826
|
const cohort = this.session.getCohort(this.#cohortId);
|
package/dist/browser.mjs
CHANGED
|
@@ -103245,7 +103245,7 @@ var AggregationCohort = class {
|
|
|
103245
103245
|
validationRejections = /* @__PURE__ */ new Set();
|
|
103246
103246
|
constructor({ id, minParticipants, serviceDid, network, beaconType }) {
|
|
103247
103247
|
this.id = id || crypto.randomUUID();
|
|
103248
|
-
this.minParticipants = minParticipants
|
|
103248
|
+
this.minParticipants = minParticipants ?? 2;
|
|
103249
103249
|
this.serviceDid = serviceDid || "";
|
|
103250
103250
|
this.network = network;
|
|
103251
103251
|
this.beaconType = beaconType || "CASBeacon";
|
|
@@ -103411,6 +103411,57 @@ var AggregationCohort = class {
|
|
|
103411
103411
|
}
|
|
103412
103412
|
};
|
|
103413
103413
|
|
|
103414
|
+
// src/core/aggregation/conditions.ts
|
|
103415
|
+
init_shim();
|
|
103416
|
+
var KNOWN_BEACON_TYPES = ["CASBeacon", "SMTBeacon"];
|
|
103417
|
+
function checkPair(problems, label, min, max) {
|
|
103418
|
+
if (min !== void 0 && (!Number.isInteger(min) || min < 0)) {
|
|
103419
|
+
problems.push(`min${label} must be an integer >= 0`);
|
|
103420
|
+
}
|
|
103421
|
+
if (max !== void 0 && (!Number.isInteger(max) || max < 0)) {
|
|
103422
|
+
problems.push(`max${label} must be an integer >= 0`);
|
|
103423
|
+
}
|
|
103424
|
+
if (min !== void 0 && max !== void 0 && Number.isInteger(min) && Number.isInteger(max) && max < min) {
|
|
103425
|
+
problems.push(`max${label} must be >= min${label}`);
|
|
103426
|
+
}
|
|
103427
|
+
}
|
|
103428
|
+
function checkCost(problems, label, cost) {
|
|
103429
|
+
if (cost === void 0) return;
|
|
103430
|
+
if (typeof cost.amount !== "number" || !Number.isFinite(cost.amount) || cost.amount < 0) {
|
|
103431
|
+
problems.push(`${label}.amount must be a finite number >= 0`);
|
|
103432
|
+
}
|
|
103433
|
+
if (typeof cost.unit !== "string" || cost.unit.length === 0) {
|
|
103434
|
+
problems.push(`${label}.unit must be a non-empty string`);
|
|
103435
|
+
}
|
|
103436
|
+
if (cost.basis !== void 0 && cost.basis !== "per-did" && cost.basis !== "per-participant") {
|
|
103437
|
+
problems.push(`${label}.basis must be 'per-did' or 'per-participant'`);
|
|
103438
|
+
}
|
|
103439
|
+
}
|
|
103440
|
+
function validateCohortConditions(c2) {
|
|
103441
|
+
const problems = [];
|
|
103442
|
+
if (!KNOWN_BEACON_TYPES.includes(c2.beaconType)) {
|
|
103443
|
+
problems.push(`beaconType must be one of ${KNOWN_BEACON_TYPES.join(", ")}`);
|
|
103444
|
+
}
|
|
103445
|
+
if (!Number.isInteger(c2.minParticipants) || c2.minParticipants < 1) {
|
|
103446
|
+
problems.push("minParticipants must be an integer >= 1");
|
|
103447
|
+
}
|
|
103448
|
+
if (c2.maxParticipants !== void 0) {
|
|
103449
|
+
if (!Number.isInteger(c2.maxParticipants) || c2.maxParticipants < 1) {
|
|
103450
|
+
problems.push("maxParticipants must be an integer >= 1");
|
|
103451
|
+
} else if (Number.isInteger(c2.minParticipants) && c2.maxParticipants < c2.minParticipants) {
|
|
103452
|
+
problems.push("maxParticipants must be >= minParticipants");
|
|
103453
|
+
}
|
|
103454
|
+
}
|
|
103455
|
+
checkPair(problems, "DidsPerParticipant", c2.minDidsPerParticipant, c2.maxDidsPerParticipant);
|
|
103456
|
+
checkPair(problems, "SecondsBetweenAnnouncements", c2.minSecondsBetweenAnnouncements, c2.maxSecondsBetweenAnnouncements);
|
|
103457
|
+
if (c2.pendingUpdateTrigger !== void 0 && (!Number.isInteger(c2.pendingUpdateTrigger) || c2.pendingUpdateTrigger < 1)) {
|
|
103458
|
+
problems.push("pendingUpdateTrigger must be an integer >= 1");
|
|
103459
|
+
}
|
|
103460
|
+
checkCost(problems, "costOfEnrollment", c2.costOfEnrollment);
|
|
103461
|
+
checkCost(problems, "costPerAnnouncement", c2.costPerAnnouncement);
|
|
103462
|
+
return problems;
|
|
103463
|
+
}
|
|
103464
|
+
|
|
103414
103465
|
// src/core/aggregation/messages/base.ts
|
|
103415
103466
|
init_shim();
|
|
103416
103467
|
var AGGREGATION_WIRE_VERSION = 1;
|
|
@@ -103845,6 +103896,14 @@ var AggregationService = class {
|
|
|
103845
103896
|
* Cohort starts in `Created` phase — call `advertise()` to broadcast.
|
|
103846
103897
|
*/
|
|
103847
103898
|
createCohort(config) {
|
|
103899
|
+
const problems = validateCohortConditions(config);
|
|
103900
|
+
if (problems.length > 0) {
|
|
103901
|
+
throw new AggregationServiceError(
|
|
103902
|
+
`Invalid cohort conditions: ${problems.join("; ")}`,
|
|
103903
|
+
"INVALID_COHORT_CONDITIONS",
|
|
103904
|
+
{ problems }
|
|
103905
|
+
);
|
|
103906
|
+
}
|
|
103848
103907
|
const cohort = new AggregationCohort({
|
|
103849
103908
|
serviceDid: this.did,
|
|
103850
103909
|
minParticipants: config.minParticipants,
|
|
@@ -103877,13 +103936,13 @@ var AggregationService = class {
|
|
|
103877
103936
|
{ cohortId, phase: state.phase }
|
|
103878
103937
|
);
|
|
103879
103938
|
}
|
|
103939
|
+
const { network, ...conditions } = state.config;
|
|
103880
103940
|
const message2 = createCohortAdvertMessage({
|
|
103881
103941
|
from: this.did,
|
|
103882
103942
|
cohortId,
|
|
103883
|
-
|
|
103884
|
-
|
|
103885
|
-
|
|
103886
|
-
communicationPk: this.publicKey.compressed
|
|
103943
|
+
network,
|
|
103944
|
+
communicationPk: this.publicKey.compressed,
|
|
103945
|
+
...conditions
|
|
103887
103946
|
});
|
|
103888
103947
|
state.phase = "Advertised" /* Advertised */;
|
|
103889
103948
|
return [message2];
|
|
@@ -103942,6 +104001,14 @@ var AggregationService = class {
|
|
|
103942
104001
|
{ cohortId, participantDid }
|
|
103943
104002
|
);
|
|
103944
104003
|
}
|
|
104004
|
+
const maxParticipants = state.config.maxParticipants;
|
|
104005
|
+
if (maxParticipants !== void 0 && state.acceptedParticipants.size >= maxParticipants) {
|
|
104006
|
+
throw new AggregationServiceError(
|
|
104007
|
+
`Cohort ${cohortId} is full: ${maxParticipants} participants already accepted.`,
|
|
104008
|
+
"COHORT_FULL",
|
|
104009
|
+
{ cohortId, maxParticipants }
|
|
104010
|
+
);
|
|
104011
|
+
}
|
|
103945
104012
|
state.acceptedParticipants.add(participantDid);
|
|
103946
104013
|
state.cohort.participants.push(participantDid);
|
|
103947
104014
|
state.cohort.participantKeys.set(participantDid, optIn.participantPk);
|
|
@@ -103975,6 +104042,14 @@ var AggregationService = class {
|
|
|
103975
104042
|
{ cohortId }
|
|
103976
104043
|
);
|
|
103977
104044
|
}
|
|
104045
|
+
const maxParticipants = state.config.maxParticipants;
|
|
104046
|
+
if (maxParticipants !== void 0 && state.acceptedParticipants.size > maxParticipants) {
|
|
104047
|
+
throw new AggregationServiceError(
|
|
104048
|
+
`Cohort ${cohortId} has ${state.acceptedParticipants.size} accepted participants, exceeds max ${maxParticipants}.`,
|
|
104049
|
+
"TOO_MANY_PARTICIPANTS",
|
|
104050
|
+
{ cohortId, maxParticipants }
|
|
104051
|
+
);
|
|
104052
|
+
}
|
|
103978
104053
|
const beaconAddress = state.cohort.computeBeaconAddress();
|
|
103979
104054
|
state.phase = "CohortSet" /* CohortSet */;
|
|
103980
104055
|
const messages2 = [];
|
|
@@ -104292,6 +104367,59 @@ var AggregationService = class {
|
|
|
104292
104367
|
// src/core/aggregation/participant.ts
|
|
104293
104368
|
init_shim();
|
|
104294
104369
|
init_utils();
|
|
104370
|
+
|
|
104371
|
+
// src/core/aggregation/messages/bodies.ts
|
|
104372
|
+
init_shim();
|
|
104373
|
+
var hasStr = (b, k) => !!b && typeof b[k] === "string";
|
|
104374
|
+
var hasIntMin = (b, k, min) => {
|
|
104375
|
+
const v = b ? b[k] : void 0;
|
|
104376
|
+
return typeof v === "number" && Number.isInteger(v) && v >= min;
|
|
104377
|
+
};
|
|
104378
|
+
var optIntMin = (b, k, min) => {
|
|
104379
|
+
const v = b ? b[k] : void 0;
|
|
104380
|
+
return v === void 0 || typeof v === "number" && Number.isInteger(v) && v >= min;
|
|
104381
|
+
};
|
|
104382
|
+
var hasBool = (b, k) => !!b && typeof b[k] === "boolean";
|
|
104383
|
+
var hasBytes = (b, k) => !!b && b[k] instanceof Uint8Array;
|
|
104384
|
+
var hasBytesArray = (b, k) => {
|
|
104385
|
+
const v = b ? b[k] : void 0;
|
|
104386
|
+
return Array.isArray(v) && v.every((x) => x instanceof Uint8Array);
|
|
104387
|
+
};
|
|
104388
|
+
function isCohortAdvertMessage(m2) {
|
|
104389
|
+
return m2.type === COHORT_ADVERT && hasStr(m2.body, "cohortId") && hasIntMin(m2.body, "minParticipants", 1) && optIntMin(m2.body, "maxParticipants", 1) && hasStr(m2.body, "beaconType") && hasStr(m2.body, "network") && hasBytes(m2.body, "communicationPk");
|
|
104390
|
+
}
|
|
104391
|
+
function isCohortOptInMessage(m2) {
|
|
104392
|
+
return m2.type === COHORT_OPT_IN && hasStr(m2.body, "cohortId") && hasBytes(m2.body, "participantPk") && hasBytes(m2.body, "communicationPk");
|
|
104393
|
+
}
|
|
104394
|
+
function isCohortOptInAcceptMessage(m2) {
|
|
104395
|
+
return m2.type === COHORT_OPT_IN_ACCEPT && hasStr(m2.body, "cohortId");
|
|
104396
|
+
}
|
|
104397
|
+
function isCohortReadyMessage(m2) {
|
|
104398
|
+
return m2.type === COHORT_READY && hasStr(m2.body, "cohortId") && hasStr(m2.body, "beaconAddress") && hasBytesArray(m2.body, "cohortKeys");
|
|
104399
|
+
}
|
|
104400
|
+
function isSubmitUpdateMessage(m2) {
|
|
104401
|
+
return m2.type === SUBMIT_UPDATE && hasStr(m2.body, "cohortId") && !!m2.body && typeof m2.body.signedUpdate === "object";
|
|
104402
|
+
}
|
|
104403
|
+
function isDistributeAggregatedDataMessage(m2) {
|
|
104404
|
+
return m2.type === DISTRIBUTE_AGGREGATED_DATA && hasStr(m2.body, "cohortId") && hasStr(m2.body, "beaconType") && hasStr(m2.body, "signalBytesHex");
|
|
104405
|
+
}
|
|
104406
|
+
function isValidationAckMessage(m2) {
|
|
104407
|
+
return m2.type === VALIDATION_ACK && hasStr(m2.body, "cohortId") && hasBool(m2.body, "approved");
|
|
104408
|
+
}
|
|
104409
|
+
function isAuthorizationRequestMessage(m2) {
|
|
104410
|
+
return m2.type === AUTHORIZATION_REQUEST && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasStr(m2.body, "pendingTx") && hasStr(m2.body, "prevOutScriptHex") && hasStr(m2.body, "prevOutValue");
|
|
104411
|
+
}
|
|
104412
|
+
function isNonceContributionMessage(m2) {
|
|
104413
|
+
return m2.type === NONCE_CONTRIBUTION && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "nonceContribution");
|
|
104414
|
+
}
|
|
104415
|
+
function isAggregatedNonceMessage(m2) {
|
|
104416
|
+
return m2.type === AGGREGATED_NONCE && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "aggregatedNonce");
|
|
104417
|
+
}
|
|
104418
|
+
function isSignatureAuthorizationMessage(m2) {
|
|
104419
|
+
return m2.type === SIGNATURE_AUTHORIZATION && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "partialSignature");
|
|
104420
|
+
}
|
|
104421
|
+
|
|
104422
|
+
// src/core/aggregation/participant.ts
|
|
104295
104423
|
var AggregationParticipant = class {
|
|
104296
104424
|
did;
|
|
104297
104425
|
/** MuSig2 signing capability. The raw secret never lives as a field here. */
|
|
@@ -104349,16 +104477,15 @@ var AggregationParticipant = class {
|
|
|
104349
104477
|
return map3;
|
|
104350
104478
|
}
|
|
104351
104479
|
#handleCohortAdvert(message2) {
|
|
104352
|
-
|
|
104353
|
-
|
|
104480
|
+
if (!isCohortAdvertMessage(message2)) return;
|
|
104481
|
+
const { cohortId, network, communicationPk, ...conditions } = message2.body;
|
|
104354
104482
|
if (this.#cohortStates.has(cohortId)) return;
|
|
104355
104483
|
const advert = {
|
|
104356
104484
|
cohortId,
|
|
104357
104485
|
serviceDid: message2.from,
|
|
104358
|
-
|
|
104359
|
-
|
|
104360
|
-
|
|
104361
|
-
serviceCommunicationPk: message2.body?.communicationPk ?? new Uint8Array()
|
|
104486
|
+
network,
|
|
104487
|
+
serviceCommunicationPk: communicationPk,
|
|
104488
|
+
...conditions
|
|
104362
104489
|
};
|
|
104363
104490
|
this.#cohortStates.set(cohortId, {
|
|
104364
104491
|
phase: "Discovered" /* Discovered */,
|
|
@@ -104383,7 +104510,7 @@ var AggregationParticipant = class {
|
|
|
104383
104510
|
const cohort = new AggregationCohort({
|
|
104384
104511
|
id: cohortId,
|
|
104385
104512
|
serviceDid: state.serviceDid,
|
|
104386
|
-
minParticipants: state.advert.
|
|
104513
|
+
minParticipants: state.advert.minParticipants,
|
|
104387
104514
|
network: state.advert.network,
|
|
104388
104515
|
beaconType: state.advert.beaconType
|
|
104389
104516
|
});
|
|
@@ -104706,50 +104833,6 @@ var SILENT_LOGGER = {
|
|
|
104706
104833
|
// src/core/aggregation/messages/index.ts
|
|
104707
104834
|
init_shim();
|
|
104708
104835
|
|
|
104709
|
-
// src/core/aggregation/messages/bodies.ts
|
|
104710
|
-
init_shim();
|
|
104711
|
-
var hasStr = (b, k) => !!b && typeof b[k] === "string";
|
|
104712
|
-
var hasNum = (b, k) => !!b && typeof b[k] === "number";
|
|
104713
|
-
var hasBool = (b, k) => !!b && typeof b[k] === "boolean";
|
|
104714
|
-
var hasBytes = (b, k) => !!b && b[k] instanceof Uint8Array;
|
|
104715
|
-
var hasBytesArray = (b, k) => {
|
|
104716
|
-
const v = b ? b[k] : void 0;
|
|
104717
|
-
return Array.isArray(v) && v.every((x) => x instanceof Uint8Array);
|
|
104718
|
-
};
|
|
104719
|
-
function isCohortAdvertMessage(m2) {
|
|
104720
|
-
return m2.type === COHORT_ADVERT && hasStr(m2.body, "cohortId") && hasNum(m2.body, "cohortSize") && hasStr(m2.body, "beaconType") && hasStr(m2.body, "network") && hasBytes(m2.body, "communicationPk");
|
|
104721
|
-
}
|
|
104722
|
-
function isCohortOptInMessage(m2) {
|
|
104723
|
-
return m2.type === COHORT_OPT_IN && hasStr(m2.body, "cohortId") && hasBytes(m2.body, "participantPk") && hasBytes(m2.body, "communicationPk");
|
|
104724
|
-
}
|
|
104725
|
-
function isCohortOptInAcceptMessage(m2) {
|
|
104726
|
-
return m2.type === COHORT_OPT_IN_ACCEPT && hasStr(m2.body, "cohortId");
|
|
104727
|
-
}
|
|
104728
|
-
function isCohortReadyMessage(m2) {
|
|
104729
|
-
return m2.type === COHORT_READY && hasStr(m2.body, "cohortId") && hasStr(m2.body, "beaconAddress") && hasBytesArray(m2.body, "cohortKeys");
|
|
104730
|
-
}
|
|
104731
|
-
function isSubmitUpdateMessage(m2) {
|
|
104732
|
-
return m2.type === SUBMIT_UPDATE && hasStr(m2.body, "cohortId") && !!m2.body && typeof m2.body.signedUpdate === "object";
|
|
104733
|
-
}
|
|
104734
|
-
function isDistributeAggregatedDataMessage(m2) {
|
|
104735
|
-
return m2.type === DISTRIBUTE_AGGREGATED_DATA && hasStr(m2.body, "cohortId") && hasStr(m2.body, "beaconType") && hasStr(m2.body, "signalBytesHex");
|
|
104736
|
-
}
|
|
104737
|
-
function isValidationAckMessage(m2) {
|
|
104738
|
-
return m2.type === VALIDATION_ACK && hasStr(m2.body, "cohortId") && hasBool(m2.body, "approved");
|
|
104739
|
-
}
|
|
104740
|
-
function isAuthorizationRequestMessage(m2) {
|
|
104741
|
-
return m2.type === AUTHORIZATION_REQUEST && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasStr(m2.body, "pendingTx") && hasStr(m2.body, "prevOutScriptHex") && hasStr(m2.body, "prevOutValue");
|
|
104742
|
-
}
|
|
104743
|
-
function isNonceContributionMessage(m2) {
|
|
104744
|
-
return m2.type === NONCE_CONTRIBUTION && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "nonceContribution");
|
|
104745
|
-
}
|
|
104746
|
-
function isAggregatedNonceMessage(m2) {
|
|
104747
|
-
return m2.type === AGGREGATED_NONCE && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "aggregatedNonce");
|
|
104748
|
-
}
|
|
104749
|
-
function isSignatureAuthorizationMessage(m2) {
|
|
104750
|
-
return m2.type === SIGNATURE_AUTHORIZATION && hasStr(m2.body, "cohortId") && hasStr(m2.body, "sessionId") && hasBytes(m2.body, "partialSignature");
|
|
104751
|
-
}
|
|
104752
|
-
|
|
104753
104836
|
// src/core/aggregation/messages/guards.ts
|
|
104754
104837
|
init_shim();
|
|
104755
104838
|
var KEYGEN_VALUES = /* @__PURE__ */ new Set([
|
|
@@ -111595,6 +111678,11 @@ var AggregationServiceRunner = class _AggregationServiceRunner extends TypedEven
|
|
|
111595
111678
|
}
|
|
111596
111679
|
const decision = await this.#onOptInReceived(optIn);
|
|
111597
111680
|
if (!decision.accepted) return;
|
|
111681
|
+
const maxParticipants = this.#config.maxParticipants;
|
|
111682
|
+
const cohortNow = this.session.getCohort(this.#cohortId);
|
|
111683
|
+
if (maxParticipants !== void 0 && cohortNow && cohortNow.participants.length >= maxParticipants) {
|
|
111684
|
+
return;
|
|
111685
|
+
}
|
|
111598
111686
|
await this.#sendAll(this.session.acceptParticipant(this.#cohortId, msg.from));
|
|
111599
111687
|
this.emit("participant-accepted", { participantDid: msg.from });
|
|
111600
111688
|
const cohort = this.session.getCohort(this.#cohortId);
|
|
@@ -129101,6 +129189,7 @@ export {
|
|
|
129101
129189
|
InMemoryRateLimitStore,
|
|
129102
129190
|
InMemoryTransport,
|
|
129103
129191
|
InboxBuffer,
|
|
129192
|
+
KNOWN_BEACON_TYPES,
|
|
129104
129193
|
KeyPairAggregationSigner,
|
|
129105
129194
|
NONCE_CONTRIBUTION,
|
|
129106
129195
|
NonceCache,
|
|
@@ -129173,6 +129262,7 @@ export {
|
|
|
129173
129262
|
registerBeaconStrategy,
|
|
129174
129263
|
reviveFromWire,
|
|
129175
129264
|
signEnvelope,
|
|
129265
|
+
validateCohortConditions,
|
|
129176
129266
|
verifyEnvelope,
|
|
129177
129267
|
verifyRequestAuth
|
|
129178
129268
|
};
|