@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/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 by its root
92
- * @param censusRoot - The census root (hex-prefixed)
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(censusRoot) {
96
- return `${this.axios.defaults.baseURL}/censuses/${censusRoot}`;
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((response) => ({
166
- ...response,
167
- uri: this.getCensusUri(response.root)
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.weight === "string" && typeof proof.censusOrigin === "number" && Object.values(CensusOrigin).includes(proof.censusOrigin);
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
- const metadata = this.createMetadata(config);
1336
- const metadataHash = await this.apiService.sequencer.pushMetadata(metadata);
1337
- const metadataUri = this.apiService.sequencer.getMetadataUrl(metadataHash);
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
- censusRoot,
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 simplified configuration
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
- await this.submitVoteRequest({
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
@@ -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
- censusRoot: string;
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 Merkle‐proof that you're in the census. */
239
- censusProof: 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",
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.21",
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"