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