@vocdoni/davinci-sdk 0.0.4 → 0.0.6

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.mjs CHANGED
@@ -563,11 +563,26 @@ class VocdoniSequencerService extends BaseService {
563
563
  throw error;
564
564
  }
565
565
  }
566
- isAddressAbleToVote(processId, address) {
567
- return this.request({
566
+ async getAddressWeight(processId, address) {
567
+ const participant = await this.request({
568
568
  method: "GET",
569
569
  url: `/processes/${processId}/participants/${address}`
570
570
  });
571
+ return participant.weight;
572
+ }
573
+ async isAddressAbleToVote(processId, address) {
574
+ try {
575
+ await this.request({
576
+ method: "GET",
577
+ url: `/processes/${processId}/participants/${address}`
578
+ });
579
+ return true;
580
+ } catch (error) {
581
+ if (error?.code === 40001) {
582
+ return false;
583
+ }
584
+ throw error;
585
+ }
571
586
  }
572
587
  getInfo() {
573
588
  return this.request({
@@ -989,7 +1004,7 @@ class ProcessRegistryService extends SmartContractService {
989
1004
  return this.contract.stVerifier();
990
1005
  }
991
1006
  // ─── WRITES ────────────────────────────────────────────────────────
992
- newProcess(status, startTime, duration, ballotMode, census, metadata, encryptionKey, initStateRoot) {
1007
+ newProcess(status, startTime, duration, maxVoters, ballotMode, census, metadata, encryptionKey, initStateRoot) {
993
1008
  const contractCensus = {
994
1009
  censusOrigin: BigInt(census.censusOrigin),
995
1010
  censusRoot: census.censusRoot,
@@ -1000,6 +1015,7 @@ class ProcessRegistryService extends SmartContractService {
1000
1015
  status,
1001
1016
  startTime,
1002
1017
  duration,
1018
+ maxVoters,
1003
1019
  ballotMode,
1004
1020
  contractCensus,
1005
1021
  metadata,
@@ -1040,6 +1056,14 @@ class ProcessRegistryService extends SmartContractService {
1040
1056
  async () => ({ success: true })
1041
1057
  );
1042
1058
  }
1059
+ setProcessMaxVoters(processID, maxVoters) {
1060
+ return this.sendTx(
1061
+ this.contract.setProcessMaxVoters(processID, maxVoters).catch((e) => {
1062
+ throw new ProcessDurationError(e.message, "setMaxVoters");
1063
+ }),
1064
+ async () => ({ success: true })
1065
+ );
1066
+ }
1043
1067
  /**
1044
1068
  * Matches the on-chain `submitStateTransition(processId, proof, input)`
1045
1069
  */
@@ -1110,6 +1134,13 @@ class ProcessRegistryService extends SmartContractService {
1110
1134
  cb
1111
1135
  ).catch((err) => console.error("Error setting up ProcessResultsSet listener:", err));
1112
1136
  }
1137
+ onProcessMaxVotersChanged(cb) {
1138
+ this.setupEventListener(
1139
+ this.contract,
1140
+ this.contract.filters.ProcessMaxVotersChanged(),
1141
+ cb
1142
+ ).catch((err) => console.error("Error setting up ProcessMaxVotersChanged listener:", err));
1143
+ }
1113
1144
  removeAllListeners() {
1114
1145
  this.contract.removeAllListeners();
1115
1146
  this.clearPollingIntervals();
@@ -1215,9 +1246,10 @@ class ProcessOrchestrationService {
1215
1246
  endDate: new Date(endTime * 1e3),
1216
1247
  duration,
1217
1248
  timeRemaining,
1249
+ maxVoters: Number(rawProcess.maxVoters),
1218
1250
  result: rawProcess.result,
1219
- voteCount: Number(rawProcess.voteCount),
1220
- voteOverwriteCount: Number(rawProcess.voteOverwriteCount),
1251
+ votersCount: Number(rawProcess.votersCount),
1252
+ overwrittenVotesCount: Number(rawProcess.overwrittenVotesCount),
1221
1253
  metadataURI: rawProcess.metadataURI,
1222
1254
  raw: rawProcess
1223
1255
  };
@@ -1269,6 +1301,7 @@ class ProcessOrchestrationService {
1269
1301
  ProcessStatus.READY,
1270
1302
  data.startTime,
1271
1303
  data.duration,
1304
+ data.maxVoters,
1272
1305
  data.ballotMode,
1273
1306
  data.census,
1274
1307
  data.metadataUri,
@@ -1356,6 +1389,7 @@ class ProcessOrchestrationService {
1356
1389
  ballotMode,
1357
1390
  signature
1358
1391
  });
1392
+ const maxVoters = config.maxVoters ?? censusConfig.size;
1359
1393
  const census = {
1360
1394
  censusOrigin: censusConfig.type,
1361
1395
  censusRoot,
@@ -1365,6 +1399,7 @@ class ProcessOrchestrationService {
1365
1399
  processId,
1366
1400
  startTime,
1367
1401
  duration,
1402
+ maxVoters,
1368
1403
  censusRoot,
1369
1404
  ballotMode,
1370
1405
  metadataUri,
@@ -1751,6 +1786,84 @@ class ProcessOrchestrationService {
1751
1786
  }
1752
1787
  throw new Error("Resume process stream ended unexpectedly");
1753
1788
  }
1789
+ /**
1790
+ * Sets the maximum number of voters for a process.
1791
+ * Returns an async generator that yields transaction status events.
1792
+ *
1793
+ * @param processId - The process ID
1794
+ * @param maxVoters - The new maximum number of voters
1795
+ * @returns AsyncGenerator yielding transaction status events
1796
+ *
1797
+ * @example
1798
+ * ```typescript
1799
+ * const stream = sdk.setProcessMaxVotersStream("0x1234567890abcdef...", 500);
1800
+ *
1801
+ * for await (const event of stream) {
1802
+ * switch (event.status) {
1803
+ * case "pending":
1804
+ * console.log("Transaction pending:", event.hash);
1805
+ * break;
1806
+ * case "completed":
1807
+ * console.log("MaxVoters updated successfully");
1808
+ * break;
1809
+ * case "failed":
1810
+ * console.error("Transaction failed:", event.error);
1811
+ * break;
1812
+ * case "reverted":
1813
+ * console.error("Transaction reverted:", event.reason);
1814
+ * break;
1815
+ * }
1816
+ * }
1817
+ * ```
1818
+ */
1819
+ async *setProcessMaxVotersStream(processId, maxVoters) {
1820
+ const txStream = this.processRegistry.setProcessMaxVoters(processId, maxVoters);
1821
+ for await (const event of txStream) {
1822
+ if (event.status === TxStatus.Pending) {
1823
+ yield { status: TxStatus.Pending, hash: event.hash };
1824
+ } else if (event.status === TxStatus.Completed) {
1825
+ yield {
1826
+ status: TxStatus.Completed,
1827
+ response: { success: true }
1828
+ };
1829
+ break;
1830
+ } else if (event.status === TxStatus.Failed) {
1831
+ yield { status: TxStatus.Failed, error: event.error };
1832
+ break;
1833
+ } else if (event.status === TxStatus.Reverted) {
1834
+ yield { status: TxStatus.Reverted, reason: event.reason };
1835
+ break;
1836
+ }
1837
+ }
1838
+ }
1839
+ /**
1840
+ * Sets the maximum number of voters for a process.
1841
+ * This is a simplified method that waits for transaction completion.
1842
+ *
1843
+ * For real-time transaction status updates, use setProcessMaxVotersStream() instead.
1844
+ *
1845
+ * @param processId - The process ID
1846
+ * @param maxVoters - The new maximum number of voters
1847
+ * @returns Promise resolving when the maxVoters is updated
1848
+ *
1849
+ * @example
1850
+ * ```typescript
1851
+ * await sdk.setProcessMaxVoters("0x1234567890abcdef...", 500);
1852
+ * console.log("MaxVoters updated successfully");
1853
+ * ```
1854
+ */
1855
+ async setProcessMaxVoters(processId, maxVoters) {
1856
+ for await (const event of this.setProcessMaxVotersStream(processId, maxVoters)) {
1857
+ if (event.status === "completed") {
1858
+ return;
1859
+ } else if (event.status === "failed") {
1860
+ throw event.error;
1861
+ } else if (event.status === "reverted") {
1862
+ throw new Error(`Transaction reverted: ${event.reason || "unknown reason"}`);
1863
+ }
1864
+ }
1865
+ throw new Error("Set process maxVoters stream ended unexpectedly");
1866
+ }
1754
1867
  }
1755
1868
 
1756
1869
  class CircomProof {
@@ -2031,9 +2144,15 @@ class VoteOrchestrationService {
2031
2144
  assertMerkleCensusProof(proof);
2032
2145
  return proof;
2033
2146
  } else {
2034
- const proof = await this.apiService.census.getCensusProof(censusRoot, voterAddress);
2035
- assertMerkleCensusProof(proof);
2036
- return proof;
2147
+ const weight = await this.apiService.sequencer.getAddressWeight(processId, voterAddress);
2148
+ return {
2149
+ root: censusRoot,
2150
+ address: voterAddress,
2151
+ weight,
2152
+ censusOrigin: CensusOrigin.CensusOriginMerkleTree,
2153
+ value: "",
2154
+ siblings: ""
2155
+ };
2037
2156
  }
2038
2157
  }
2039
2158
  if (censusOrigin === CensusOrigin.CensusOriginCSP) {
@@ -2843,29 +2962,55 @@ class DavinciSDK {
2843
2962
  return this.voteOrchestrator.hasAddressVoted(processId, address);
2844
2963
  }
2845
2964
  /**
2846
- * Check if an address is able to vote in a process and get participant information.
2965
+ * Check if an address is able to vote in a process (i.e., is in the census).
2847
2966
  *
2848
2967
  * Does NOT require a provider - uses API calls only.
2849
2968
  *
2850
2969
  * @param processId - The process ID
2851
2970
  * @param address - The voter's address
2852
- * @returns Promise resolving to participant information (key and weight)
2971
+ * @returns Promise resolving to boolean indicating if the address can vote
2853
2972
  *
2854
2973
  * @example
2855
2974
  * ```typescript
2856
- * const participantInfo = await sdk.isAddressAbleToVote(processId, "0x1234567890abcdef...");
2857
- * console.log("Address:", participantInfo.key);
2858
- * console.log("Weight:", participantInfo.weight);
2975
+ * const canVote = await sdk.isAddressAbleToVote(processId, "0x1234567890abcdef...");
2976
+ * if (canVote) {
2977
+ * console.log("This address can vote");
2978
+ * } else {
2979
+ * console.log("This address is not in the census");
2980
+ * }
2859
2981
  * ```
2860
2982
  */
2861
2983
  async isAddressAbleToVote(processId, address) {
2862
2984
  if (!this.initialized) {
2863
2985
  throw new Error(
2864
- "SDK must be initialized before checking participant info. Call sdk.init() first."
2986
+ "SDK must be initialized before checking if address can vote. Call sdk.init() first."
2865
2987
  );
2866
2988
  }
2867
2989
  return this.apiService.sequencer.isAddressAbleToVote(processId, address);
2868
2990
  }
2991
+ /**
2992
+ * Get the voting weight for an address in a process.
2993
+ *
2994
+ * Does NOT require a provider - uses API calls only.
2995
+ *
2996
+ * @param processId - The process ID
2997
+ * @param address - The voter's address
2998
+ * @returns Promise resolving to the address weight as a string
2999
+ *
3000
+ * @example
3001
+ * ```typescript
3002
+ * const weight = await sdk.getAddressWeight(processId, "0x1234567890abcdef...");
3003
+ * console.log("Address weight:", weight);
3004
+ * ```
3005
+ */
3006
+ async getAddressWeight(processId, address) {
3007
+ if (!this.initialized) {
3008
+ throw new Error(
3009
+ "SDK must be initialized before getting address weight. Call sdk.init() first."
3010
+ );
3011
+ }
3012
+ return this.apiService.sequencer.getAddressWeight(processId, address);
3013
+ }
2869
3014
  /**
2870
3015
  * Watch vote status changes in real-time using an async generator.
2871
3016
  * This method yields each status change as it happens, perfect for showing
@@ -3223,6 +3368,77 @@ class DavinciSDK {
3223
3368
  this.ensureProvider();
3224
3369
  return this.processOrchestrator.resumeProcess(processId);
3225
3370
  }
3371
+ /**
3372
+ * Sets the maximum number of voters for a process and returns an async generator
3373
+ * that yields transaction status events. This allows you to change the voter limit
3374
+ * after process creation.
3375
+ *
3376
+ * Requires a signer with a provider for blockchain interactions.
3377
+ *
3378
+ * @param processId - The process ID
3379
+ * @param maxVoters - The new maximum number of voters
3380
+ * @returns AsyncGenerator yielding transaction status events
3381
+ * @throws Error if signer does not have a provider
3382
+ *
3383
+ * @example
3384
+ * ```typescript
3385
+ * const stream = sdk.setProcessMaxVotersStream("0x1234567890abcdef...", 500);
3386
+ *
3387
+ * for await (const event of stream) {
3388
+ * switch (event.status) {
3389
+ * case TxStatus.Pending:
3390
+ * console.log("Transaction pending:", event.hash);
3391
+ * break;
3392
+ * case TxStatus.Completed:
3393
+ * console.log("MaxVoters updated successfully");
3394
+ * break;
3395
+ * case TxStatus.Failed:
3396
+ * console.error("Transaction failed:", event.error);
3397
+ * break;
3398
+ * case TxStatus.Reverted:
3399
+ * console.error("Transaction reverted:", event.reason);
3400
+ * break;
3401
+ * }
3402
+ * }
3403
+ * ```
3404
+ */
3405
+ setProcessMaxVotersStream(processId, maxVoters) {
3406
+ if (!this.initialized) {
3407
+ throw new Error(
3408
+ "SDK must be initialized before setting process maxVoters. Call sdk.init() first."
3409
+ );
3410
+ }
3411
+ this.ensureProvider();
3412
+ return this.processOrchestrator.setProcessMaxVotersStream(processId, maxVoters);
3413
+ }
3414
+ /**
3415
+ * Sets the maximum number of voters for a process.
3416
+ * This is the simplified method that waits for transaction completion.
3417
+ *
3418
+ * For real-time transaction status updates, use setProcessMaxVotersStream() instead.
3419
+ *
3420
+ * Requires a signer with a provider for blockchain interactions.
3421
+ *
3422
+ * @param processId - The process ID
3423
+ * @param maxVoters - The new maximum number of voters
3424
+ * @returns Promise resolving when the maxVoters is updated
3425
+ * @throws Error if signer does not have a provider
3426
+ *
3427
+ * @example
3428
+ * ```typescript
3429
+ * await sdk.setProcessMaxVoters("0x1234567890abcdef...", 500);
3430
+ * console.log("MaxVoters updated successfully");
3431
+ * ```
3432
+ */
3433
+ async setProcessMaxVoters(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.setProcessMaxVoters(processId, maxVoters);
3441
+ }
3226
3442
  /**
3227
3443
  * Resolve contract address based on configuration priority:
3228
3444
  * 1. Custom addresses from user config (if provided)