@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/README.md +48 -0
- package/dist/contracts.d.ts +16 -5
- package/dist/index.d.ts +163 -40
- package/dist/index.js +230 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +230 -14
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +230 -14
- package/dist/sequencer.d.ts +6 -27
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -565,11 +565,26 @@ class VocdoniSequencerService extends BaseService {
|
|
|
565
565
|
throw error;
|
|
566
566
|
}
|
|
567
567
|
}
|
|
568
|
-
|
|
569
|
-
|
|
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
|
-
|
|
1222
|
-
|
|
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
|
|
2037
|
-
|
|
2038
|
-
|
|
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
|
|
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
|
|
2973
|
+
* @returns Promise resolving to boolean indicating if the address can vote
|
|
2855
2974
|
*
|
|
2856
2975
|
* @example
|
|
2857
2976
|
* ```typescript
|
|
2858
|
-
* const
|
|
2859
|
-
*
|
|
2860
|
-
*
|
|
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
|
|
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)
|