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