@vocdoni/davinci-sdk 0.0.3 → 0.0.4
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 +21 -0
- package/dist/contracts.d.ts +3 -4
- package/dist/index.d.ts +84 -30
- package/dist/index.js +74 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +74 -33
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +74 -33
- package/dist/sequencer.d.ts +19 -13
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -87,12 +87,12 @@ class VocdoniCensusService extends BaseService {
|
|
|
87
87
|
super(baseURL);
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
|
-
* Constructs the URI for accessing a census
|
|
91
|
-
* @param
|
|
90
|
+
* Constructs the URI for accessing a census
|
|
91
|
+
* @param relativePath - The relative path
|
|
92
92
|
* @returns The constructed URI for the census
|
|
93
93
|
*/
|
|
94
|
-
getCensusUri(
|
|
95
|
-
return `${this.axios.defaults.baseURL}
|
|
94
|
+
getCensusUri(relativePath) {
|
|
95
|
+
return `${this.axios.defaults.baseURL}${relativePath}`;
|
|
96
96
|
}
|
|
97
97
|
createCensus() {
|
|
98
98
|
return this.request({
|
|
@@ -161,10 +161,13 @@ class VocdoniCensusService extends BaseService {
|
|
|
161
161
|
return this.request({
|
|
162
162
|
method: "POST",
|
|
163
163
|
url: `/censuses/${censusId}/publish`
|
|
164
|
-
}).then((
|
|
165
|
-
...
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
}).then((apiResponse) => {
|
|
165
|
+
const { censusUri, ...responseWithoutCensusUri } = apiResponse;
|
|
166
|
+
return {
|
|
167
|
+
...responseWithoutCensusUri,
|
|
168
|
+
uri: this.getCensusUri(censusUri)
|
|
169
|
+
};
|
|
170
|
+
});
|
|
168
171
|
}
|
|
169
172
|
// BigQuery endpoints
|
|
170
173
|
getSnapshots(params) {
|
|
@@ -194,13 +197,13 @@ var CensusOrigin = /* @__PURE__ */ ((CensusOrigin2) => {
|
|
|
194
197
|
return CensusOrigin2;
|
|
195
198
|
})(CensusOrigin || {});
|
|
196
199
|
function isBaseCensusProof(proof) {
|
|
197
|
-
return !!proof && typeof proof.root === "string" && typeof proof.address === "string" && typeof proof.
|
|
200
|
+
return !!proof && typeof proof.root === "string" && typeof proof.address === "string" && typeof proof.censusOrigin === "number" && Object.values(CensusOrigin).includes(proof.censusOrigin);
|
|
198
201
|
}
|
|
199
202
|
function isMerkleCensusProof(proof) {
|
|
200
|
-
return isBaseCensusProof(proof) && proof.censusOrigin === 1 /* CensusOriginMerkleTree */ && typeof proof.value === "string" && typeof proof.siblings === "string";
|
|
203
|
+
return isBaseCensusProof(proof) && proof.censusOrigin === 1 /* CensusOriginMerkleTree */ && typeof proof.weight === "string" && typeof proof.value === "string" && typeof proof.siblings === "string";
|
|
201
204
|
}
|
|
202
205
|
function isCSPCensusProof(proof) {
|
|
203
|
-
return isBaseCensusProof(proof) && proof.censusOrigin === 2 /* CensusOriginCSP */ && typeof proof.processId === "string" && typeof proof.publicKey === "string" && typeof proof.signature === "string";
|
|
206
|
+
return isBaseCensusProof(proof) && proof.censusOrigin === 2 /* CensusOriginCSP */ && typeof proof.weight === "string" && typeof proof.processId === "string" && typeof proof.publicKey === "string" && typeof proof.signature === "string";
|
|
204
207
|
}
|
|
205
208
|
function assertMerkleCensusProof(proof) {
|
|
206
209
|
if (!isMerkleCensusProof(proof)) {
|
|
@@ -560,6 +563,12 @@ class VocdoniSequencerService extends BaseService {
|
|
|
560
563
|
throw error;
|
|
561
564
|
}
|
|
562
565
|
}
|
|
566
|
+
isAddressAbleToVote(processId, address) {
|
|
567
|
+
return this.request({
|
|
568
|
+
method: "GET",
|
|
569
|
+
url: `/processes/${processId}/participants/${address}`
|
|
570
|
+
});
|
|
571
|
+
}
|
|
563
572
|
getInfo() {
|
|
564
573
|
return this.request({
|
|
565
574
|
method: "GET",
|
|
@@ -983,7 +992,6 @@ class ProcessRegistryService extends SmartContractService {
|
|
|
983
992
|
newProcess(status, startTime, duration, ballotMode, census, metadata, encryptionKey, initStateRoot) {
|
|
984
993
|
const contractCensus = {
|
|
985
994
|
censusOrigin: BigInt(census.censusOrigin),
|
|
986
|
-
maxVotes: BigInt(census.maxVotes),
|
|
987
995
|
censusRoot: census.censusRoot,
|
|
988
996
|
censusURI: census.censusURI
|
|
989
997
|
};
|
|
@@ -1014,7 +1022,6 @@ class ProcessRegistryService extends SmartContractService {
|
|
|
1014
1022
|
setProcessCensus(processID, census) {
|
|
1015
1023
|
const contractCensus = {
|
|
1016
1024
|
censusOrigin: BigInt(census.censusOrigin),
|
|
1017
|
-
maxVotes: BigInt(census.maxVotes),
|
|
1018
1025
|
censusRoot: census.censusRoot,
|
|
1019
1026
|
censusURI: census.censusURI
|
|
1020
1027
|
};
|
|
@@ -1183,7 +1190,6 @@ class ProcessOrchestrationService {
|
|
|
1183
1190
|
const census = {
|
|
1184
1191
|
type: Number(rawProcess.census.censusOrigin),
|
|
1185
1192
|
root: rawProcess.census.censusRoot,
|
|
1186
|
-
size: Number(rawProcess.census.maxVotes),
|
|
1187
1193
|
uri: rawProcess.census.censusURI || ""
|
|
1188
1194
|
};
|
|
1189
1195
|
const ballot = {
|
|
@@ -1198,11 +1204,11 @@ class ProcessOrchestrationService {
|
|
|
1198
1204
|
};
|
|
1199
1205
|
return {
|
|
1200
1206
|
processId,
|
|
1201
|
-
title,
|
|
1207
|
+
title: title || "",
|
|
1202
1208
|
description,
|
|
1203
1209
|
census,
|
|
1204
1210
|
ballot,
|
|
1205
|
-
questions,
|
|
1211
|
+
questions: questions || [],
|
|
1206
1212
|
status: Number(rawProcess.status),
|
|
1207
1213
|
creator: rawProcess.organizationId,
|
|
1208
1214
|
startDate: new Date(startTime * 1e3),
|
|
@@ -1331,20 +1337,27 @@ class ProcessOrchestrationService {
|
|
|
1331
1337
|
const censusConfig = await this.handleCensus(config.census);
|
|
1332
1338
|
const censusRoot = censusConfig.root;
|
|
1333
1339
|
const ballotMode = config.ballot;
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1340
|
+
let metadataUri;
|
|
1341
|
+
if ("metadataUri" in config) {
|
|
1342
|
+
metadataUri = config.metadataUri;
|
|
1343
|
+
} else {
|
|
1344
|
+
const metadata = this.createMetadata(config);
|
|
1345
|
+
const metadataHash = await this.apiService.sequencer.pushMetadata(metadata);
|
|
1346
|
+
metadataUri = this.apiService.sequencer.getMetadataUrl(metadataHash);
|
|
1347
|
+
}
|
|
1337
1348
|
const signature = await signProcessCreation(processId, this.signer);
|
|
1338
1349
|
const sequencerResult = await this.apiService.sequencer.createProcess({
|
|
1339
1350
|
processId,
|
|
1340
|
-
|
|
1351
|
+
census: {
|
|
1352
|
+
censusOrigin: censusConfig.type,
|
|
1353
|
+
censusRoot,
|
|
1354
|
+
censusURI: censusConfig.uri
|
|
1355
|
+
},
|
|
1341
1356
|
ballotMode,
|
|
1342
|
-
signature
|
|
1343
|
-
censusOrigin: censusConfig.type
|
|
1357
|
+
signature
|
|
1344
1358
|
});
|
|
1345
1359
|
const census = {
|
|
1346
1360
|
censusOrigin: censusConfig.type,
|
|
1347
|
-
maxVotes: censusConfig.size.toString(),
|
|
1348
1361
|
censusRoot,
|
|
1349
1362
|
censusURI: censusConfig.uri
|
|
1350
1363
|
};
|
|
@@ -1413,15 +1426,13 @@ class ProcessOrchestrationService {
|
|
|
1413
1426
|
throw new Error("Invalid date format. Use Date object, ISO string, or Unix timestamp.");
|
|
1414
1427
|
}
|
|
1415
1428
|
/**
|
|
1416
|
-
* Creates metadata from the
|
|
1429
|
+
* Creates metadata from the configuration with metadata fields
|
|
1430
|
+
* This method should only be called with ProcessConfigWithMetadata
|
|
1417
1431
|
*/
|
|
1418
1432
|
createMetadata(config) {
|
|
1419
1433
|
const metadata = getElectionMetadataTemplate();
|
|
1420
1434
|
metadata.title.default = config.title;
|
|
1421
1435
|
metadata.description.default = config.description || "";
|
|
1422
|
-
if (!config.questions || config.questions.length === 0) {
|
|
1423
|
-
throw new Error("Questions are required. Please provide at least one question with choices.");
|
|
1424
|
-
}
|
|
1425
1436
|
metadata.questions = config.questions.map((q) => ({
|
|
1426
1437
|
title: { default: q.title },
|
|
1427
1438
|
description: { default: q.description || "" },
|
|
@@ -1886,16 +1897,19 @@ class VoteOrchestrationService {
|
|
|
1886
1897
|
);
|
|
1887
1898
|
const { proof } = await this.generateZkProof(circomInputs);
|
|
1888
1899
|
const signature = await this.signVote(voteId);
|
|
1889
|
-
|
|
1900
|
+
const voteRequest = {
|
|
1890
1901
|
processId: config.processId,
|
|
1891
|
-
censusProof,
|
|
1892
1902
|
ballot: cryptoOutput.ballot,
|
|
1893
1903
|
ballotProof: proof,
|
|
1894
1904
|
ballotInputsHash: cryptoOutput.ballotInputsHash,
|
|
1895
1905
|
address: voterAddress,
|
|
1896
1906
|
signature,
|
|
1897
1907
|
voteId
|
|
1898
|
-
}
|
|
1908
|
+
};
|
|
1909
|
+
if (process.census.censusOrigin === CensusOrigin.CensusOriginCSP) {
|
|
1910
|
+
voteRequest.censusProof = censusProof;
|
|
1911
|
+
}
|
|
1912
|
+
await this.submitVoteRequest(voteRequest);
|
|
1899
1913
|
const status = await this.apiService.sequencer.getVoteStatus(config.processId, voteId);
|
|
1900
1914
|
return {
|
|
1901
1915
|
voteId,
|
|
@@ -2339,14 +2353,15 @@ class DavinciCrypto {
|
|
|
2339
2353
|
* @param privKey - The private key in hex format
|
|
2340
2354
|
* @param processId - The process ID in hex format
|
|
2341
2355
|
* @param address - The address in hex format
|
|
2356
|
+
* @param weight - The vote weight as a decimal string
|
|
2342
2357
|
* @returns The CSP proof as a parsed JSON object
|
|
2343
2358
|
* @throws if called before `await init()`, or if Go returns an error
|
|
2344
2359
|
*/
|
|
2345
|
-
async cspSign(censusOrigin, privKey, processId, address) {
|
|
2360
|
+
async cspSign(censusOrigin, privKey, processId, address, weight) {
|
|
2346
2361
|
if (!this.initialized) {
|
|
2347
2362
|
throw new Error("DavinciCrypto not initialized \u2014 call `await init()` first");
|
|
2348
2363
|
}
|
|
2349
|
-
const raw = globalThis.DavinciCrypto.cspSign(censusOrigin, privKey, processId, address);
|
|
2364
|
+
const raw = globalThis.DavinciCrypto.cspSign(censusOrigin, privKey, processId, address, weight);
|
|
2350
2365
|
if (raw.error) {
|
|
2351
2366
|
throw new Error(`Go/WASM cspSign error: ${raw.error}`);
|
|
2352
2367
|
}
|
|
@@ -2360,13 +2375,14 @@ class DavinciCrypto {
|
|
|
2360
2375
|
* @param censusOrigin - The census origin type (e.g., CensusOrigin.CensusOriginCSP)
|
|
2361
2376
|
* @param root - The census root
|
|
2362
2377
|
* @param address - The address
|
|
2378
|
+
* @param weight - The vote weight as a decimal string
|
|
2363
2379
|
* @param processId - The process ID
|
|
2364
2380
|
* @param publicKey - The public key
|
|
2365
2381
|
* @param signature - The signature
|
|
2366
2382
|
* @returns The verification result
|
|
2367
2383
|
* @throws if called before `await init()`, or if Go returns an error
|
|
2368
2384
|
*/
|
|
2369
|
-
async cspVerify(censusOrigin, root, address, processId, publicKey, signature) {
|
|
2385
|
+
async cspVerify(censusOrigin, root, address, weight, processId, publicKey, signature) {
|
|
2370
2386
|
if (!this.initialized) {
|
|
2371
2387
|
throw new Error("DavinciCrypto not initialized \u2014 call `await init()` first");
|
|
2372
2388
|
}
|
|
@@ -2374,6 +2390,7 @@ class DavinciCrypto {
|
|
|
2374
2390
|
censusOrigin,
|
|
2375
2391
|
root,
|
|
2376
2392
|
address,
|
|
2393
|
+
weight,
|
|
2377
2394
|
processId,
|
|
2378
2395
|
publicKey,
|
|
2379
2396
|
signature
|
|
@@ -2825,6 +2842,30 @@ class DavinciSDK {
|
|
|
2825
2842
|
}
|
|
2826
2843
|
return this.voteOrchestrator.hasAddressVoted(processId, address);
|
|
2827
2844
|
}
|
|
2845
|
+
/**
|
|
2846
|
+
* Check if an address is able to vote in a process and get participant information.
|
|
2847
|
+
*
|
|
2848
|
+
* Does NOT require a provider - uses API calls only.
|
|
2849
|
+
*
|
|
2850
|
+
* @param processId - The process ID
|
|
2851
|
+
* @param address - The voter's address
|
|
2852
|
+
* @returns Promise resolving to participant information (key and weight)
|
|
2853
|
+
*
|
|
2854
|
+
* @example
|
|
2855
|
+
* ```typescript
|
|
2856
|
+
* const participantInfo = await sdk.isAddressAbleToVote(processId, "0x1234567890abcdef...");
|
|
2857
|
+
* console.log("Address:", participantInfo.key);
|
|
2858
|
+
* console.log("Weight:", participantInfo.weight);
|
|
2859
|
+
* ```
|
|
2860
|
+
*/
|
|
2861
|
+
async isAddressAbleToVote(processId, address) {
|
|
2862
|
+
if (!this.initialized) {
|
|
2863
|
+
throw new Error(
|
|
2864
|
+
"SDK must be initialized before checking participant info. Call sdk.init() first."
|
|
2865
|
+
);
|
|
2866
|
+
}
|
|
2867
|
+
return this.apiService.sequencer.isAddressAbleToVote(processId, address);
|
|
2868
|
+
}
|
|
2828
2869
|
/**
|
|
2829
2870
|
* Watch vote status changes in real-time using an async generator.
|
|
2830
2871
|
* This method yields each status change as it happens, perfect for showing
|