@vocdoni/davinci-sdk 0.0.5 → 0.0.7

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/index.js CHANGED
@@ -194,18 +194,20 @@ class VocdoniCensusService extends BaseService {
194
194
  }
195
195
 
196
196
  var CensusOrigin = /* @__PURE__ */ ((CensusOrigin2) => {
197
- CensusOrigin2[CensusOrigin2["CensusOriginMerkleTree"] = 1] = "CensusOriginMerkleTree";
198
- CensusOrigin2[CensusOrigin2["CensusOriginCSP"] = 2] = "CensusOriginCSP";
197
+ CensusOrigin2[CensusOrigin2["OffchainStatic"] = 1] = "OffchainStatic";
198
+ CensusOrigin2[CensusOrigin2["OffchainDynamic"] = 2] = "OffchainDynamic";
199
+ CensusOrigin2[CensusOrigin2["Onchain"] = 3] = "Onchain";
200
+ CensusOrigin2[CensusOrigin2["CSP"] = 4] = "CSP";
199
201
  return CensusOrigin2;
200
202
  })(CensusOrigin || {});
201
203
  function isBaseCensusProof(proof) {
202
204
  return !!proof && typeof proof.root === "string" && typeof proof.address === "string" && typeof proof.censusOrigin === "number" && Object.values(CensusOrigin).includes(proof.censusOrigin);
203
205
  }
204
206
  function isMerkleCensusProof(proof) {
205
- return isBaseCensusProof(proof) && proof.censusOrigin === 1 /* CensusOriginMerkleTree */ && typeof proof.weight === "string" && typeof proof.value === "string" && typeof proof.siblings === "string";
207
+ return isBaseCensusProof(proof) && (proof.censusOrigin === 1 /* OffchainStatic */ || proof.censusOrigin === 2 /* OffchainDynamic */ || proof.censusOrigin === 3 /* Onchain */) && typeof proof.weight === "string" && typeof proof.value === "string" && typeof proof.siblings === "string";
206
208
  }
207
209
  function isCSPCensusProof(proof) {
208
- return isBaseCensusProof(proof) && proof.censusOrigin === 2 /* CensusOriginCSP */ && typeof proof.weight === "string" && typeof proof.processId === "string" && typeof proof.publicKey === "string" && typeof proof.signature === "string";
210
+ return isBaseCensusProof(proof) && proof.censusOrigin === 4 /* CSP */ && typeof proof.weight === "string" && typeof proof.processId === "string" && typeof proof.publicKey === "string" && typeof proof.signature === "string";
209
211
  }
210
212
  function assertMerkleCensusProof(proof) {
211
213
  if (!isMerkleCensusProof(proof)) {
@@ -225,12 +227,27 @@ var CensusType = /* @__PURE__ */ ((CensusType2) => {
225
227
  return CensusType2;
226
228
  })(CensusType || {});
227
229
  class Census {
228
- constructor(type) {
230
+ constructor(type, censusOrigin) {
229
231
  this._censusId = null;
230
232
  this._censusRoot = null;
231
233
  this._censusURI = null;
232
234
  this._size = null;
233
235
  this._type = type;
236
+ if (censusOrigin !== void 0) {
237
+ this._censusOrigin = censusOrigin;
238
+ } else {
239
+ switch (type) {
240
+ case "plain" /* PLAIN */:
241
+ case "weighted" /* WEIGHTED */:
242
+ this._censusOrigin = CensusOrigin.OffchainStatic;
243
+ break;
244
+ case "csp" /* CSP */:
245
+ this._censusOrigin = CensusOrigin.CSP;
246
+ break;
247
+ default:
248
+ throw new Error(`Unknown census type: ${type}`);
249
+ }
250
+ }
234
251
  }
235
252
  get censusId() {
236
253
  return this._censusId;
@@ -251,24 +268,20 @@ class Census {
251
268
  return this._censusRoot !== null && this._censusURI !== null;
252
269
  }
253
270
  /**
254
- * Convert CensusType to CensusOrigin enum for API compatibility
271
+ * Get the census origin (OffchainStatic, OffchainDynamic, Onchain, or CSP)
255
272
  */
256
273
  get censusOrigin() {
257
- switch (this._type) {
258
- case "plain" /* PLAIN */:
259
- case "weighted" /* WEIGHTED */:
260
- return CensusOrigin.CensusOriginMerkleTree;
261
- case "csp" /* CSP */:
262
- return CensusOrigin.CensusOriginCSP;
263
- default:
264
- throw new Error(`Unknown census type: ${this._type}`);
265
- }
274
+ return this._censusOrigin;
266
275
  }
267
276
  }
268
277
 
269
278
  class PlainCensus extends Census {
270
- constructor() {
271
- super(CensusType.PLAIN);
279
+ /**
280
+ * Creates a new PlainCensus
281
+ * @param censusOrigin - The census origin (defaults to OffchainStatic for backward compatibility)
282
+ */
283
+ constructor(censusOrigin) {
284
+ super(CensusType.PLAIN, censusOrigin);
272
285
  this._participants = /* @__PURE__ */ new Set();
273
286
  }
274
287
  /**
@@ -326,8 +339,12 @@ class PlainCensus extends Census {
326
339
  }
327
340
 
328
341
  class WeightedCensus extends Census {
329
- constructor() {
330
- super(CensusType.WEIGHTED);
342
+ /**
343
+ * Creates a new WeightedCensus
344
+ * @param censusOrigin - The census origin (defaults to OffchainStatic for backward compatibility)
345
+ */
346
+ constructor(censusOrigin) {
347
+ super(CensusType.WEIGHTED, censusOrigin);
331
348
  this._participants = /* @__PURE__ */ new Map();
332
349
  }
333
350
  /**
@@ -419,7 +436,7 @@ class WeightedCensus extends Census {
419
436
 
420
437
  class CspCensus extends Census {
421
438
  constructor(publicKey, cspURI, size) {
422
- super(CensusType.CSP);
439
+ super(CensusType.CSP, CensusOrigin.CSP);
423
440
  if (!/^(0x)?[0-9a-fA-F]+$/.test(publicKey)) {
424
441
  throw new Error("Public key is missing or invalid");
425
442
  }
@@ -443,8 +460,16 @@ class CspCensus extends Census {
443
460
  }
444
461
 
445
462
  class PublishedCensus extends Census {
446
- constructor(type, root, uri, size) {
447
- super(type);
463
+ /**
464
+ * Creates a PublishedCensus from existing census data
465
+ * @param type - The census type (PLAIN, WEIGHTED, or CSP)
466
+ * @param root - The census root
467
+ * @param uri - The census URI
468
+ * @param size - The census size (number of participants)
469
+ * @param censusOrigin - The census origin (optional - defaults based on type if not provided)
470
+ */
471
+ constructor(type, root, uri, size, censusOrigin) {
472
+ super(type, censusOrigin);
448
473
  this._censusRoot = root;
449
474
  this._censusURI = uri;
450
475
  this._size = size;
@@ -943,6 +968,8 @@ class ProcessStatusError extends ContractServiceError {
943
968
  }
944
969
  class ProcessCensusError extends ContractServiceError {
945
970
  }
971
+ class CensusNotUpdatable extends ContractServiceError {
972
+ }
946
973
  class ProcessDurationError extends ContractServiceError {
947
974
  }
948
975
  class ProcessStateTransitionError extends ContractServiceError {
@@ -1006,7 +1033,7 @@ class ProcessRegistryService extends SmartContractService {
1006
1033
  return this.contract.stVerifier();
1007
1034
  }
1008
1035
  // ─── WRITES ────────────────────────────────────────────────────────
1009
- newProcess(status, startTime, duration, ballotMode, census, metadata, encryptionKey, initStateRoot) {
1036
+ newProcess(status, startTime, duration, maxVoters, ballotMode, census, metadata, encryptionKey, initStateRoot) {
1010
1037
  const contractCensus = {
1011
1038
  censusOrigin: BigInt(census.censusOrigin),
1012
1039
  censusRoot: census.censusRoot,
@@ -1017,6 +1044,7 @@ class ProcessRegistryService extends SmartContractService {
1017
1044
  status,
1018
1045
  startTime,
1019
1046
  duration,
1047
+ maxVoters,
1020
1048
  ballotMode,
1021
1049
  contractCensus,
1022
1050
  metadata,
@@ -1057,6 +1085,14 @@ class ProcessRegistryService extends SmartContractService {
1057
1085
  async () => ({ success: true })
1058
1086
  );
1059
1087
  }
1088
+ setProcessMaxVoters(processID, maxVoters) {
1089
+ return this.sendTx(
1090
+ this.contract.setProcessMaxVoters(processID, maxVoters).catch((e) => {
1091
+ throw new ProcessDurationError(e.message, "setMaxVoters");
1092
+ }),
1093
+ async () => ({ success: true })
1094
+ );
1095
+ }
1060
1096
  /**
1061
1097
  * Matches the on-chain `submitStateTransition(processId, proof, input)`
1062
1098
  */
@@ -1113,12 +1149,12 @@ class ProcessRegistryService extends SmartContractService {
1113
1149
  cb
1114
1150
  ).catch((err) => console.error("Error setting up ProcessDurationChanged listener:", err));
1115
1151
  }
1116
- onStateRootUpdated(cb) {
1152
+ onStateTransitioned(cb) {
1117
1153
  this.setupEventListener(
1118
1154
  this.contract,
1119
- this.contract.filters.ProcessStateRootUpdated(),
1155
+ this.contract.filters.ProcessStateTransitioned(),
1120
1156
  cb
1121
- ).catch((err) => console.error("Error setting up StateRootUpdated listener:", err));
1157
+ ).catch((err) => console.error("Error setting up ProcessStateTransitioned listener:", err));
1122
1158
  }
1123
1159
  onProcessResultsSet(cb) {
1124
1160
  this.setupEventListener(
@@ -1127,6 +1163,13 @@ class ProcessRegistryService extends SmartContractService {
1127
1163
  cb
1128
1164
  ).catch((err) => console.error("Error setting up ProcessResultsSet listener:", err));
1129
1165
  }
1166
+ onProcessMaxVotersChanged(cb) {
1167
+ this.setupEventListener(
1168
+ this.contract,
1169
+ this.contract.filters.ProcessMaxVotersChanged(),
1170
+ cb
1171
+ ).catch((err) => console.error("Error setting up ProcessMaxVotersChanged listener:", err));
1172
+ }
1130
1173
  removeAllListeners() {
1131
1174
  this.contract.removeAllListeners();
1132
1175
  this.clearPollingIntervals();
@@ -1232,6 +1275,7 @@ class ProcessOrchestrationService {
1232
1275
  endDate: new Date(endTime * 1e3),
1233
1276
  duration,
1234
1277
  timeRemaining,
1278
+ maxVoters: Number(rawProcess.maxVoters),
1235
1279
  result: rawProcess.result,
1236
1280
  votersCount: Number(rawProcess.votersCount),
1237
1281
  overwrittenVotesCount: Number(rawProcess.overwrittenVotesCount),
@@ -1286,6 +1330,7 @@ class ProcessOrchestrationService {
1286
1330
  ProcessStatus.READY,
1287
1331
  data.startTime,
1288
1332
  data.duration,
1333
+ data.maxVoters,
1289
1334
  data.ballotMode,
1290
1335
  data.census,
1291
1336
  data.metadataUri,
@@ -1373,6 +1418,7 @@ class ProcessOrchestrationService {
1373
1418
  ballotMode,
1374
1419
  signature
1375
1420
  });
1421
+ const maxVoters = config.maxVoters ?? censusConfig.size;
1376
1422
  const census = {
1377
1423
  censusOrigin: censusConfig.type,
1378
1424
  censusRoot,
@@ -1382,6 +1428,7 @@ class ProcessOrchestrationService {
1382
1428
  processId,
1383
1429
  startTime,
1384
1430
  duration,
1431
+ maxVoters,
1385
1432
  censusRoot,
1386
1433
  ballotMode,
1387
1434
  metadataUri,
@@ -1768,6 +1815,84 @@ class ProcessOrchestrationService {
1768
1815
  }
1769
1816
  throw new Error("Resume process stream ended unexpectedly");
1770
1817
  }
1818
+ /**
1819
+ * Sets the maximum number of voters for a process.
1820
+ * Returns an async generator that yields transaction status events.
1821
+ *
1822
+ * @param processId - The process ID
1823
+ * @param maxVoters - The new maximum number of voters
1824
+ * @returns AsyncGenerator yielding transaction status events
1825
+ *
1826
+ * @example
1827
+ * ```typescript
1828
+ * const stream = sdk.setProcessMaxVotersStream("0x1234567890abcdef...", 500);
1829
+ *
1830
+ * for await (const event of stream) {
1831
+ * switch (event.status) {
1832
+ * case "pending":
1833
+ * console.log("Transaction pending:", event.hash);
1834
+ * break;
1835
+ * case "completed":
1836
+ * console.log("MaxVoters updated successfully");
1837
+ * break;
1838
+ * case "failed":
1839
+ * console.error("Transaction failed:", event.error);
1840
+ * break;
1841
+ * case "reverted":
1842
+ * console.error("Transaction reverted:", event.reason);
1843
+ * break;
1844
+ * }
1845
+ * }
1846
+ * ```
1847
+ */
1848
+ async *setProcessMaxVotersStream(processId, maxVoters) {
1849
+ const txStream = this.processRegistry.setProcessMaxVoters(processId, maxVoters);
1850
+ for await (const event of txStream) {
1851
+ if (event.status === TxStatus.Pending) {
1852
+ yield { status: TxStatus.Pending, hash: event.hash };
1853
+ } else if (event.status === TxStatus.Completed) {
1854
+ yield {
1855
+ status: TxStatus.Completed,
1856
+ response: { success: true }
1857
+ };
1858
+ break;
1859
+ } else if (event.status === TxStatus.Failed) {
1860
+ yield { status: TxStatus.Failed, error: event.error };
1861
+ break;
1862
+ } else if (event.status === TxStatus.Reverted) {
1863
+ yield { status: TxStatus.Reverted, reason: event.reason };
1864
+ break;
1865
+ }
1866
+ }
1867
+ }
1868
+ /**
1869
+ * Sets the maximum number of voters for a process.
1870
+ * This is a simplified method that waits for transaction completion.
1871
+ *
1872
+ * For real-time transaction status updates, use setProcessMaxVotersStream() instead.
1873
+ *
1874
+ * @param processId - The process ID
1875
+ * @param maxVoters - The new maximum number of voters
1876
+ * @returns Promise resolving when the maxVoters is updated
1877
+ *
1878
+ * @example
1879
+ * ```typescript
1880
+ * await sdk.setProcessMaxVoters("0x1234567890abcdef...", 500);
1881
+ * console.log("MaxVoters updated successfully");
1882
+ * ```
1883
+ */
1884
+ async setProcessMaxVoters(processId, maxVoters) {
1885
+ for await (const event of this.setProcessMaxVotersStream(processId, maxVoters)) {
1886
+ if (event.status === "completed") {
1887
+ return;
1888
+ } else if (event.status === "failed") {
1889
+ throw event.error;
1890
+ } else if (event.status === "reverted") {
1891
+ throw new Error(`Transaction reverted: ${event.reason || "unknown reason"}`);
1892
+ }
1893
+ }
1894
+ throw new Error("Set process maxVoters stream ended unexpectedly");
1895
+ }
1771
1896
  }
1772
1897
 
1773
1898
  class CircomProof {
@@ -1923,7 +2048,7 @@ class VoteOrchestrationService {
1923
2048
  signature,
1924
2049
  voteId
1925
2050
  };
1926
- if (process.census.censusOrigin === CensusOrigin.CensusOriginCSP) {
2051
+ if (process.census.censusOrigin === CensusOrigin.CSP) {
1927
2052
  voteRequest.censusProof = censusProof;
1928
2053
  }
1929
2054
  await this.submitVoteRequest(voteRequest);
@@ -2039,7 +2164,7 @@ class VoteOrchestrationService {
2039
2164
  * Get census proof based on census origin type
2040
2165
  */
2041
2166
  async getCensusProof(censusOrigin, censusRoot, voterAddress, processId) {
2042
- if (censusOrigin === CensusOrigin.CensusOriginMerkleTree) {
2167
+ if (censusOrigin === CensusOrigin.OffchainStatic || censusOrigin === CensusOrigin.OffchainDynamic || censusOrigin === CensusOrigin.Onchain) {
2043
2168
  if (this.censusProviders.merkle) {
2044
2169
  const proof = await this.censusProviders.merkle({
2045
2170
  censusRoot,
@@ -2053,13 +2178,13 @@ class VoteOrchestrationService {
2053
2178
  root: censusRoot,
2054
2179
  address: voterAddress,
2055
2180
  weight,
2056
- censusOrigin: CensusOrigin.CensusOriginMerkleTree,
2181
+ censusOrigin,
2057
2182
  value: "",
2058
2183
  siblings: ""
2059
2184
  };
2060
2185
  }
2061
2186
  }
2062
- if (censusOrigin === CensusOrigin.CensusOriginCSP) {
2187
+ if (censusOrigin === CensusOrigin.CSP) {
2063
2188
  if (!this.censusProviders.csp) {
2064
2189
  throw new Error(
2065
2190
  "CSP voting requires a CSP census proof provider. Pass one via VoteOrchestrationService(..., { csp: yourFn })."
@@ -2633,7 +2758,7 @@ class DavinciSDK {
2633
2758
  * title: "My Election",
2634
2759
  * description: "A simple election",
2635
2760
  * census: {
2636
- * type: CensusOrigin.CensusOriginMerkleTree,
2761
+ * type: CensusOrigin.OffchainStatic,
2637
2762
  * root: "0x1234...",
2638
2763
  * size: 100,
2639
2764
  * uri: "ipfs://..."
@@ -2720,7 +2845,7 @@ class DavinciSDK {
2720
2845
  * title: "My Election",
2721
2846
  * description: "A simple election",
2722
2847
  * census: {
2723
- * type: CensusOrigin.CensusOriginMerkleTree,
2848
+ * type: CensusOrigin.OffchainStatic,
2724
2849
  * root: "0x1234...",
2725
2850
  * size: 100,
2726
2851
  * uri: "ipfs://your-census-uri"
@@ -3272,6 +3397,77 @@ class DavinciSDK {
3272
3397
  this.ensureProvider();
3273
3398
  return this.processOrchestrator.resumeProcess(processId);
3274
3399
  }
3400
+ /**
3401
+ * Sets the maximum number of voters for a process and returns an async generator
3402
+ * that yields transaction status events. This allows you to change the voter limit
3403
+ * after process creation.
3404
+ *
3405
+ * Requires a signer with a provider for blockchain interactions.
3406
+ *
3407
+ * @param processId - The process ID
3408
+ * @param maxVoters - The new maximum number of voters
3409
+ * @returns AsyncGenerator yielding transaction status events
3410
+ * @throws Error if signer does not have a provider
3411
+ *
3412
+ * @example
3413
+ * ```typescript
3414
+ * const stream = sdk.setProcessMaxVotersStream("0x1234567890abcdef...", 500);
3415
+ *
3416
+ * for await (const event of stream) {
3417
+ * switch (event.status) {
3418
+ * case TxStatus.Pending:
3419
+ * console.log("Transaction pending:", event.hash);
3420
+ * break;
3421
+ * case TxStatus.Completed:
3422
+ * console.log("MaxVoters updated successfully");
3423
+ * break;
3424
+ * case TxStatus.Failed:
3425
+ * console.error("Transaction failed:", event.error);
3426
+ * break;
3427
+ * case TxStatus.Reverted:
3428
+ * console.error("Transaction reverted:", event.reason);
3429
+ * break;
3430
+ * }
3431
+ * }
3432
+ * ```
3433
+ */
3434
+ setProcessMaxVotersStream(processId, maxVoters) {
3435
+ if (!this.initialized) {
3436
+ throw new Error(
3437
+ "SDK must be initialized before setting process maxVoters. Call sdk.init() first."
3438
+ );
3439
+ }
3440
+ this.ensureProvider();
3441
+ return this.processOrchestrator.setProcessMaxVotersStream(processId, maxVoters);
3442
+ }
3443
+ /**
3444
+ * Sets the maximum number of voters for a process.
3445
+ * This is the simplified method that waits for transaction completion.
3446
+ *
3447
+ * For real-time transaction status updates, use setProcessMaxVotersStream() instead.
3448
+ *
3449
+ * Requires a signer with a provider for blockchain interactions.
3450
+ *
3451
+ * @param processId - The process ID
3452
+ * @param maxVoters - The new maximum number of voters
3453
+ * @returns Promise resolving when the maxVoters is updated
3454
+ * @throws Error if signer does not have a provider
3455
+ *
3456
+ * @example
3457
+ * ```typescript
3458
+ * await sdk.setProcessMaxVoters("0x1234567890abcdef...", 500);
3459
+ * console.log("MaxVoters updated successfully");
3460
+ * ```
3461
+ */
3462
+ async setProcessMaxVoters(processId, maxVoters) {
3463
+ if (!this.initialized) {
3464
+ throw new Error(
3465
+ "SDK must be initialized before setting process maxVoters. Call sdk.init() first."
3466
+ );
3467
+ }
3468
+ this.ensureProvider();
3469
+ return this.processOrchestrator.setProcessMaxVoters(processId, maxVoters);
3470
+ }
3275
3471
  /**
3276
3472
  * Resolve contract address based on configuration priority:
3277
3473
  * 1. Custom addresses from user config (if provided)
@@ -3348,6 +3544,7 @@ class DavinciSDK {
3348
3544
 
3349
3545
  exports.BaseService = BaseService;
3350
3546
  exports.Census = Census;
3547
+ exports.CensusNotUpdatable = CensusNotUpdatable;
3351
3548
  exports.CensusOrchestrator = CensusOrchestrator;
3352
3549
  exports.CensusOrigin = CensusOrigin;
3353
3550
  exports.CensusType = CensusType;