@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.umd.js
CHANGED
|
@@ -88,12 +88,12 @@
|
|
|
88
88
|
super(baseURL);
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
|
-
* Constructs the URI for accessing a census
|
|
92
|
-
* @param
|
|
91
|
+
* Constructs the URI for accessing a census
|
|
92
|
+
* @param relativePath - The relative path
|
|
93
93
|
* @returns The constructed URI for the census
|
|
94
94
|
*/
|
|
95
|
-
getCensusUri(
|
|
96
|
-
return `${this.axios.defaults.baseURL}
|
|
95
|
+
getCensusUri(relativePath) {
|
|
96
|
+
return `${this.axios.defaults.baseURL}${relativePath}`;
|
|
97
97
|
}
|
|
98
98
|
createCensus() {
|
|
99
99
|
return this.request({
|
|
@@ -162,10 +162,13 @@
|
|
|
162
162
|
return this.request({
|
|
163
163
|
method: "POST",
|
|
164
164
|
url: `/censuses/${censusId}/publish`
|
|
165
|
-
}).then((
|
|
166
|
-
...
|
|
167
|
-
|
|
168
|
-
|
|
165
|
+
}).then((apiResponse) => {
|
|
166
|
+
const { censusUri, ...responseWithoutCensusUri } = apiResponse;
|
|
167
|
+
return {
|
|
168
|
+
...responseWithoutCensusUri,
|
|
169
|
+
uri: this.getCensusUri(censusUri)
|
|
170
|
+
};
|
|
171
|
+
});
|
|
169
172
|
}
|
|
170
173
|
// BigQuery endpoints
|
|
171
174
|
getSnapshots(params) {
|
|
@@ -195,13 +198,13 @@
|
|
|
195
198
|
return CensusOrigin2;
|
|
196
199
|
})(CensusOrigin || {});
|
|
197
200
|
function isBaseCensusProof(proof) {
|
|
198
|
-
return !!proof && typeof proof.root === "string" && typeof proof.address === "string" && typeof proof.
|
|
201
|
+
return !!proof && typeof proof.root === "string" && typeof proof.address === "string" && typeof proof.censusOrigin === "number" && Object.values(CensusOrigin).includes(proof.censusOrigin);
|
|
199
202
|
}
|
|
200
203
|
function isMerkleCensusProof(proof) {
|
|
201
|
-
return isBaseCensusProof(proof) && proof.censusOrigin === 1 /* CensusOriginMerkleTree */ && typeof proof.value === "string" && typeof proof.siblings === "string";
|
|
204
|
+
return isBaseCensusProof(proof) && proof.censusOrigin === 1 /* CensusOriginMerkleTree */ && typeof proof.weight === "string" && typeof proof.value === "string" && typeof proof.siblings === "string";
|
|
202
205
|
}
|
|
203
206
|
function isCSPCensusProof(proof) {
|
|
204
|
-
return isBaseCensusProof(proof) && proof.censusOrigin === 2 /* CensusOriginCSP */ && typeof proof.processId === "string" && typeof proof.publicKey === "string" && typeof proof.signature === "string";
|
|
207
|
+
return isBaseCensusProof(proof) && proof.censusOrigin === 2 /* CensusOriginCSP */ && typeof proof.weight === "string" && typeof proof.processId === "string" && typeof proof.publicKey === "string" && typeof proof.signature === "string";
|
|
205
208
|
}
|
|
206
209
|
function assertMerkleCensusProof(proof) {
|
|
207
210
|
if (!isMerkleCensusProof(proof)) {
|
|
@@ -561,6 +564,12 @@
|
|
|
561
564
|
throw error;
|
|
562
565
|
}
|
|
563
566
|
}
|
|
567
|
+
isAddressAbleToVote(processId, address) {
|
|
568
|
+
return this.request({
|
|
569
|
+
method: "GET",
|
|
570
|
+
url: `/processes/${processId}/participants/${address}`
|
|
571
|
+
});
|
|
572
|
+
}
|
|
564
573
|
getInfo() {
|
|
565
574
|
return this.request({
|
|
566
575
|
method: "GET",
|
|
@@ -984,7 +993,6 @@
|
|
|
984
993
|
newProcess(status, startTime, duration, ballotMode, census, metadata, encryptionKey, initStateRoot) {
|
|
985
994
|
const contractCensus = {
|
|
986
995
|
censusOrigin: BigInt(census.censusOrigin),
|
|
987
|
-
maxVotes: BigInt(census.maxVotes),
|
|
988
996
|
censusRoot: census.censusRoot,
|
|
989
997
|
censusURI: census.censusURI
|
|
990
998
|
};
|
|
@@ -1015,7 +1023,6 @@
|
|
|
1015
1023
|
setProcessCensus(processID, census) {
|
|
1016
1024
|
const contractCensus = {
|
|
1017
1025
|
censusOrigin: BigInt(census.censusOrigin),
|
|
1018
|
-
maxVotes: BigInt(census.maxVotes),
|
|
1019
1026
|
censusRoot: census.censusRoot,
|
|
1020
1027
|
censusURI: census.censusURI
|
|
1021
1028
|
};
|
|
@@ -1184,7 +1191,6 @@
|
|
|
1184
1191
|
const census = {
|
|
1185
1192
|
type: Number(rawProcess.census.censusOrigin),
|
|
1186
1193
|
root: rawProcess.census.censusRoot,
|
|
1187
|
-
size: Number(rawProcess.census.maxVotes),
|
|
1188
1194
|
uri: rawProcess.census.censusURI || ""
|
|
1189
1195
|
};
|
|
1190
1196
|
const ballot = {
|
|
@@ -1199,11 +1205,11 @@
|
|
|
1199
1205
|
};
|
|
1200
1206
|
return {
|
|
1201
1207
|
processId,
|
|
1202
|
-
title,
|
|
1208
|
+
title: title || "",
|
|
1203
1209
|
description,
|
|
1204
1210
|
census,
|
|
1205
1211
|
ballot,
|
|
1206
|
-
questions,
|
|
1212
|
+
questions: questions || [],
|
|
1207
1213
|
status: Number(rawProcess.status),
|
|
1208
1214
|
creator: rawProcess.organizationId,
|
|
1209
1215
|
startDate: new Date(startTime * 1e3),
|
|
@@ -1332,20 +1338,27 @@
|
|
|
1332
1338
|
const censusConfig = await this.handleCensus(config.census);
|
|
1333
1339
|
const censusRoot = censusConfig.root;
|
|
1334
1340
|
const ballotMode = config.ballot;
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1341
|
+
let metadataUri;
|
|
1342
|
+
if ("metadataUri" in config) {
|
|
1343
|
+
metadataUri = config.metadataUri;
|
|
1344
|
+
} else {
|
|
1345
|
+
const metadata = this.createMetadata(config);
|
|
1346
|
+
const metadataHash = await this.apiService.sequencer.pushMetadata(metadata);
|
|
1347
|
+
metadataUri = this.apiService.sequencer.getMetadataUrl(metadataHash);
|
|
1348
|
+
}
|
|
1338
1349
|
const signature = await signProcessCreation(processId, this.signer);
|
|
1339
1350
|
const sequencerResult = await this.apiService.sequencer.createProcess({
|
|
1340
1351
|
processId,
|
|
1341
|
-
|
|
1352
|
+
census: {
|
|
1353
|
+
censusOrigin: censusConfig.type,
|
|
1354
|
+
censusRoot,
|
|
1355
|
+
censusURI: censusConfig.uri
|
|
1356
|
+
},
|
|
1342
1357
|
ballotMode,
|
|
1343
|
-
signature
|
|
1344
|
-
censusOrigin: censusConfig.type
|
|
1358
|
+
signature
|
|
1345
1359
|
});
|
|
1346
1360
|
const census = {
|
|
1347
1361
|
censusOrigin: censusConfig.type,
|
|
1348
|
-
maxVotes: censusConfig.size.toString(),
|
|
1349
1362
|
censusRoot,
|
|
1350
1363
|
censusURI: censusConfig.uri
|
|
1351
1364
|
};
|
|
@@ -1414,15 +1427,13 @@
|
|
|
1414
1427
|
throw new Error("Invalid date format. Use Date object, ISO string, or Unix timestamp.");
|
|
1415
1428
|
}
|
|
1416
1429
|
/**
|
|
1417
|
-
* Creates metadata from the
|
|
1430
|
+
* Creates metadata from the configuration with metadata fields
|
|
1431
|
+
* This method should only be called with ProcessConfigWithMetadata
|
|
1418
1432
|
*/
|
|
1419
1433
|
createMetadata(config) {
|
|
1420
1434
|
const metadata = getElectionMetadataTemplate();
|
|
1421
1435
|
metadata.title.default = config.title;
|
|
1422
1436
|
metadata.description.default = config.description || "";
|
|
1423
|
-
if (!config.questions || config.questions.length === 0) {
|
|
1424
|
-
throw new Error("Questions are required. Please provide at least one question with choices.");
|
|
1425
|
-
}
|
|
1426
1437
|
metadata.questions = config.questions.map((q) => ({
|
|
1427
1438
|
title: { default: q.title },
|
|
1428
1439
|
description: { default: q.description || "" },
|
|
@@ -1887,16 +1898,19 @@
|
|
|
1887
1898
|
);
|
|
1888
1899
|
const { proof } = await this.generateZkProof(circomInputs);
|
|
1889
1900
|
const signature = await this.signVote(voteId);
|
|
1890
|
-
|
|
1901
|
+
const voteRequest = {
|
|
1891
1902
|
processId: config.processId,
|
|
1892
|
-
censusProof,
|
|
1893
1903
|
ballot: cryptoOutput.ballot,
|
|
1894
1904
|
ballotProof: proof,
|
|
1895
1905
|
ballotInputsHash: cryptoOutput.ballotInputsHash,
|
|
1896
1906
|
address: voterAddress,
|
|
1897
1907
|
signature,
|
|
1898
1908
|
voteId
|
|
1899
|
-
}
|
|
1909
|
+
};
|
|
1910
|
+
if (process.census.censusOrigin === CensusOrigin.CensusOriginCSP) {
|
|
1911
|
+
voteRequest.censusProof = censusProof;
|
|
1912
|
+
}
|
|
1913
|
+
await this.submitVoteRequest(voteRequest);
|
|
1900
1914
|
const status = await this.apiService.sequencer.getVoteStatus(config.processId, voteId);
|
|
1901
1915
|
return {
|
|
1902
1916
|
voteId,
|
|
@@ -2340,14 +2354,15 @@
|
|
|
2340
2354
|
* @param privKey - The private key in hex format
|
|
2341
2355
|
* @param processId - The process ID in hex format
|
|
2342
2356
|
* @param address - The address in hex format
|
|
2357
|
+
* @param weight - The vote weight as a decimal string
|
|
2343
2358
|
* @returns The CSP proof as a parsed JSON object
|
|
2344
2359
|
* @throws if called before `await init()`, or if Go returns an error
|
|
2345
2360
|
*/
|
|
2346
|
-
async cspSign(censusOrigin, privKey, processId, address) {
|
|
2361
|
+
async cspSign(censusOrigin, privKey, processId, address, weight) {
|
|
2347
2362
|
if (!this.initialized) {
|
|
2348
2363
|
throw new Error("DavinciCrypto not initialized \u2014 call `await init()` first");
|
|
2349
2364
|
}
|
|
2350
|
-
const raw = globalThis.DavinciCrypto.cspSign(censusOrigin, privKey, processId, address);
|
|
2365
|
+
const raw = globalThis.DavinciCrypto.cspSign(censusOrigin, privKey, processId, address, weight);
|
|
2351
2366
|
if (raw.error) {
|
|
2352
2367
|
throw new Error(`Go/WASM cspSign error: ${raw.error}`);
|
|
2353
2368
|
}
|
|
@@ -2361,13 +2376,14 @@
|
|
|
2361
2376
|
* @param censusOrigin - The census origin type (e.g., CensusOrigin.CensusOriginCSP)
|
|
2362
2377
|
* @param root - The census root
|
|
2363
2378
|
* @param address - The address
|
|
2379
|
+
* @param weight - The vote weight as a decimal string
|
|
2364
2380
|
* @param processId - The process ID
|
|
2365
2381
|
* @param publicKey - The public key
|
|
2366
2382
|
* @param signature - The signature
|
|
2367
2383
|
* @returns The verification result
|
|
2368
2384
|
* @throws if called before `await init()`, or if Go returns an error
|
|
2369
2385
|
*/
|
|
2370
|
-
async cspVerify(censusOrigin, root, address, processId, publicKey, signature) {
|
|
2386
|
+
async cspVerify(censusOrigin, root, address, weight, processId, publicKey, signature) {
|
|
2371
2387
|
if (!this.initialized) {
|
|
2372
2388
|
throw new Error("DavinciCrypto not initialized \u2014 call `await init()` first");
|
|
2373
2389
|
}
|
|
@@ -2375,6 +2391,7 @@
|
|
|
2375
2391
|
censusOrigin,
|
|
2376
2392
|
root,
|
|
2377
2393
|
address,
|
|
2394
|
+
weight,
|
|
2378
2395
|
processId,
|
|
2379
2396
|
publicKey,
|
|
2380
2397
|
signature
|
|
@@ -2826,6 +2843,30 @@
|
|
|
2826
2843
|
}
|
|
2827
2844
|
return this.voteOrchestrator.hasAddressVoted(processId, address);
|
|
2828
2845
|
}
|
|
2846
|
+
/**
|
|
2847
|
+
* Check if an address is able to vote in a process and get participant information.
|
|
2848
|
+
*
|
|
2849
|
+
* Does NOT require a provider - uses API calls only.
|
|
2850
|
+
*
|
|
2851
|
+
* @param processId - The process ID
|
|
2852
|
+
* @param address - The voter's address
|
|
2853
|
+
* @returns Promise resolving to participant information (key and weight)
|
|
2854
|
+
*
|
|
2855
|
+
* @example
|
|
2856
|
+
* ```typescript
|
|
2857
|
+
* const participantInfo = await sdk.isAddressAbleToVote(processId, "0x1234567890abcdef...");
|
|
2858
|
+
* console.log("Address:", participantInfo.key);
|
|
2859
|
+
* console.log("Weight:", participantInfo.weight);
|
|
2860
|
+
* ```
|
|
2861
|
+
*/
|
|
2862
|
+
async isAddressAbleToVote(processId, address) {
|
|
2863
|
+
if (!this.initialized) {
|
|
2864
|
+
throw new Error(
|
|
2865
|
+
"SDK must be initialized before checking participant info. Call sdk.init() first."
|
|
2866
|
+
);
|
|
2867
|
+
}
|
|
2868
|
+
return this.apiService.sequencer.isAddressAbleToVote(processId, address);
|
|
2869
|
+
}
|
|
2829
2870
|
/**
|
|
2830
2871
|
* Watch vote status changes in real-time using an async generator.
|
|
2831
2872
|
* This method yields each status change as it happens, perfect for showing
|
package/dist/sequencer.d.ts
CHANGED
|
@@ -144,7 +144,6 @@ interface BallotMode {
|
|
|
144
144
|
}
|
|
145
145
|
interface CensusData {
|
|
146
146
|
censusOrigin: CensusOrigin;
|
|
147
|
-
maxVotes: string;
|
|
148
147
|
censusRoot: string;
|
|
149
148
|
censusURI: string;
|
|
150
149
|
}
|
|
@@ -155,14 +154,13 @@ interface EncryptionKey {
|
|
|
155
154
|
|
|
156
155
|
interface CreateProcessRequest {
|
|
157
156
|
processId: string;
|
|
158
|
-
|
|
157
|
+
census: {
|
|
158
|
+
censusOrigin: CensusOrigin;
|
|
159
|
+
censusRoot: string;
|
|
160
|
+
censusURI: string;
|
|
161
|
+
};
|
|
159
162
|
ballotMode: BallotMode;
|
|
160
163
|
signature: string;
|
|
161
|
-
/**
|
|
162
|
-
* The censusOrigin specifies the origin type of the census used in the request.
|
|
163
|
-
* This attribute allows the API to determine how the census data should be processed or verified.
|
|
164
|
-
*/
|
|
165
|
-
censusOrigin: CensusOrigin;
|
|
166
164
|
}
|
|
167
165
|
interface CreateProcessResponse {
|
|
168
166
|
processId: string;
|
|
@@ -235,8 +233,8 @@ interface VoteProof {
|
|
|
235
233
|
interface VoteRequest {
|
|
236
234
|
/** The `processId` you obtained when creating the process. */
|
|
237
235
|
processId: string;
|
|
238
|
-
/** Your
|
|
239
|
-
censusProof
|
|
236
|
+
/** Your census proof (only required for CSP, not for MerkleTree). */
|
|
237
|
+
censusProof?: CensusProof;
|
|
240
238
|
/** Your encrypted ballot. */
|
|
241
239
|
ballot: VoteBallot;
|
|
242
240
|
/** The zkSNARK proof that the ballot is well‐formed. */
|
|
@@ -302,6 +300,10 @@ interface WorkerStats {
|
|
|
302
300
|
interface WorkersResponse {
|
|
303
301
|
workers: WorkerStats[];
|
|
304
302
|
}
|
|
303
|
+
interface ParticipantInfoResponse {
|
|
304
|
+
key: string;
|
|
305
|
+
weight: string;
|
|
306
|
+
}
|
|
305
307
|
|
|
306
308
|
/**
|
|
307
309
|
* Creates the signature message for process creation.
|
|
@@ -421,6 +423,7 @@ interface CSPSignOutput {
|
|
|
421
423
|
censusOrigin: CensusOrigin;
|
|
422
424
|
root: string;
|
|
423
425
|
address: string;
|
|
426
|
+
weight: string;
|
|
424
427
|
processId: string;
|
|
425
428
|
publicKey: string;
|
|
426
429
|
signature: string;
|
|
@@ -431,7 +434,7 @@ interface RawResult<T = any> {
|
|
|
431
434
|
}
|
|
432
435
|
interface GoDavinciCryptoWasm {
|
|
433
436
|
proofInputs(inputJson: string): RawResult<DavinciCryptoOutput>;
|
|
434
|
-
cspSign(censusOrigin: number, privKey: string, processId: string, address: string): RawResult<CSPSignOutput>;
|
|
437
|
+
cspSign(censusOrigin: number, privKey: string, processId: string, address: string, weight: string): RawResult<CSPSignOutput>;
|
|
435
438
|
cspVerify(cspProof: string): RawResult<boolean>;
|
|
436
439
|
cspCensusRoot(censusOrigin: number, privKey: string): RawResult<{
|
|
437
440
|
root: string;
|
|
@@ -491,22 +494,24 @@ declare class DavinciCrypto {
|
|
|
491
494
|
* @param privKey - The private key in hex format
|
|
492
495
|
* @param processId - The process ID in hex format
|
|
493
496
|
* @param address - The address in hex format
|
|
497
|
+
* @param weight - The vote weight as a decimal string
|
|
494
498
|
* @returns The CSP proof as a parsed JSON object
|
|
495
499
|
* @throws if called before `await init()`, or if Go returns an error
|
|
496
500
|
*/
|
|
497
|
-
cspSign(censusOrigin: CensusOrigin, privKey: string, processId: string, address: string): Promise<CSPSignOutput>;
|
|
501
|
+
cspSign(censusOrigin: CensusOrigin, privKey: string, processId: string, address: string, weight: string): Promise<CSPSignOutput>;
|
|
498
502
|
/**
|
|
499
503
|
* Verify a CSP (Credential Service Provider) proof.
|
|
500
504
|
* @param censusOrigin - The census origin type (e.g., CensusOrigin.CensusOriginCSP)
|
|
501
505
|
* @param root - The census root
|
|
502
506
|
* @param address - The address
|
|
507
|
+
* @param weight - The vote weight as a decimal string
|
|
503
508
|
* @param processId - The process ID
|
|
504
509
|
* @param publicKey - The public key
|
|
505
510
|
* @param signature - The signature
|
|
506
511
|
* @returns The verification result
|
|
507
512
|
* @throws if called before `await init()`, or if Go returns an error
|
|
508
513
|
*/
|
|
509
|
-
cspVerify(censusOrigin: CensusOrigin, root: string, address: string, processId: string, publicKey: string, signature: string): Promise<boolean>;
|
|
514
|
+
cspVerify(censusOrigin: CensusOrigin, root: string, address: string, weight: string, processId: string, publicKey: string, signature: string): Promise<boolean>;
|
|
510
515
|
/**
|
|
511
516
|
* Generate a CSP (Credential Service Provider) census root.
|
|
512
517
|
* @param censusOrigin - The census origin type (e.g., CensusOrigin.CensusOriginCSP)
|
|
@@ -526,6 +531,7 @@ declare class VocdoniSequencerService extends BaseService {
|
|
|
526
531
|
submitVote(vote: VoteRequest): Promise<void>;
|
|
527
532
|
getVoteStatus(processId: string, voteId: string): Promise<VoteStatusResponse>;
|
|
528
533
|
hasAddressVoted(processId: string, address: string): Promise<boolean>;
|
|
534
|
+
isAddressAbleToVote(processId: string, address: string): Promise<ParticipantInfoResponse>;
|
|
529
535
|
getInfo(): Promise<InfoResponse>;
|
|
530
536
|
pushMetadata(metadata: ElectionMetadata): Promise<string>;
|
|
531
537
|
getMetadata(hashOrUrl: string): Promise<ElectionMetadata>;
|
|
@@ -535,4 +541,4 @@ declare class VocdoniSequencerService extends BaseService {
|
|
|
535
541
|
}
|
|
536
542
|
|
|
537
543
|
export { CircomProof, DavinciCrypto, VocdoniSequencerService, VoteStatus, createProcessSignatureMessage, signProcessCreation, validateProcessId };
|
|
538
|
-
export type { CSPSignOutput, CircomProofOptions, CreateProcessRequest, CreateProcessResponse, DavinciCryptoCiphertext, DavinciCryptoInputs, DavinciCryptoOptions, DavinciCryptoOutput, GetProcessResponse, Groth16Proof, InfoResponse, ListProcessesResponse, ProofInputs, SequencerStats, VoteBallot, VoteCiphertext, VoteProof, VoteRequest, VoteStatusResponse, WorkerStats, WorkersResponse };
|
|
544
|
+
export type { CSPSignOutput, CircomProofOptions, CreateProcessRequest, CreateProcessResponse, DavinciCryptoCiphertext, DavinciCryptoInputs, DavinciCryptoOptions, DavinciCryptoOutput, GetProcessResponse, Groth16Proof, InfoResponse, ListProcessesResponse, ParticipantInfoResponse, ProofInputs, SequencerStats, VoteBallot, VoteCiphertext, VoteProof, VoteRequest, VoteStatusResponse, WorkerStats, WorkersResponse };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vocdoni/davinci-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
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.
|
|
75
|
+
"@vocdoni/davinci-contracts": "0.0.26",
|
|
76
76
|
"axios": "^1.8.4",
|
|
77
77
|
"ethers": "^6.7.1",
|
|
78
78
|
"snarkjs": "^0.7.5"
|