@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.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 by its root
91
- * @param censusRoot - The census root (hex-prefixed)
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(censusRoot) {
95
- return `${this.axios.defaults.baseURL}/censuses/${censusRoot}`;
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((response) => ({
165
- ...response,
166
- uri: this.getCensusUri(response.root)
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.weight === "string" && typeof proof.censusOrigin === "number" && Object.values(CensusOrigin).includes(proof.censusOrigin);
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
- const metadata = this.createMetadata(config);
1335
- const metadataHash = await this.apiService.sequencer.pushMetadata(metadata);
1336
- const metadataUri = this.apiService.sequencer.getMetadataUrl(metadataHash);
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
- censusRoot,
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 simplified configuration
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
- await this.submitVoteRequest({
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