@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 CHANGED
@@ -549,6 +549,27 @@ if (hasVoted) {
549
549
  }
550
550
  ```
551
551
 
552
+ #### Checking if Address is Able to Vote
553
+
554
+ Get participant information including voting weight for an address:
555
+
556
+ ```typescript
557
+ const participantInfo = await sdk.isAddressAbleToVote(processId, voterAddress);
558
+
559
+ console.log('Address:', participantInfo.key);
560
+ console.log('Voting weight:', participantInfo.weight);
561
+
562
+ // Use this to verify voter eligibility before submitting a vote
563
+ if (participantInfo) {
564
+ console.log(`Address ${participantInfo.key} is eligible with weight ${participantInfo.weight}`);
565
+ }
566
+ ```
567
+
568
+ This method is useful for:
569
+ - Verifying voter eligibility before vote submission
570
+ - Displaying voting power/weight to users
571
+ - Building voter dashboards and analytics
572
+
552
573
  ## 💡 Examples
553
574
 
554
575
  ### Complete Voting Flow
@@ -293,9 +293,8 @@ type ProcessStatusChangedCallback = EntityCallback<[string, bigint, bigint]>;
293
293
  * @param processID - The process ID
294
294
  * @param root - The new census root
295
295
  * @param uri - The new census URI
296
- * @param maxVotes - The maximum number of votes
297
296
  */
298
- type ProcessCensusUpdatedCallback = EntityCallback<[string, string, string, bigint]>;
297
+ type ProcessCensusUpdatedCallback = EntityCallback<[string, string, string]>;
299
298
  /**
300
299
  * Callback for when a process duration changes.
301
300
  * @param processID - The process ID
@@ -372,7 +371,6 @@ interface BallotMode {
372
371
  }
373
372
  interface CensusData {
374
373
  censusOrigin: CensusOrigin;
375
- maxVotes: string;
376
374
  censusRoot: string;
377
375
  censusURI: string;
378
376
  }
@@ -420,6 +418,7 @@ interface CSPSignOutput {
420
418
  censusOrigin: CensusOrigin;
421
419
  root: string;
422
420
  address: string;
421
+ weight: string;
423
422
  processId: string;
424
423
  publicKey: string;
425
424
  signature: string;
@@ -430,7 +429,7 @@ interface RawResult<T = any> {
430
429
  }
431
430
  interface GoDavinciCryptoWasm {
432
431
  proofInputs(inputJson: string): RawResult<DavinciCryptoOutput>;
433
- cspSign(censusOrigin: number, privKey: string, processId: string, address: string): RawResult<CSPSignOutput>;
432
+ cspSign(censusOrigin: number, privKey: string, processId: string, address: string, weight: string): RawResult<CSPSignOutput>;
434
433
  cspVerify(cspProof: string): RawResult<boolean>;
435
434
  cspCensusRoot(censusOrigin: number, privKey: string): RawResult<{
436
435
  root: string;
package/dist/index.d.ts CHANGED
@@ -194,6 +194,8 @@ interface PublishCensusResponse {
194
194
  publishedAt: string;
195
195
  /** The constructed URI for accessing the census */
196
196
  uri: string;
197
+ /** The size of the census. */
198
+ size: number;
197
199
  }
198
200
  interface Snapshot {
199
201
  /** ISO timestamp of the snapshot date. */
@@ -263,11 +265,11 @@ interface HealthResponse {
263
265
  declare class VocdoniCensusService extends BaseService {
264
266
  constructor(baseURL: string);
265
267
  /**
266
- * Constructs the URI for accessing a census by its root
267
- * @param censusRoot - The census root (hex-prefixed)
268
+ * Constructs the URI for accessing a census
269
+ * @param relativePath - The relative path
268
270
  * @returns The constructed URI for the census
269
271
  */
270
- getCensusUri(censusRoot: string): string;
272
+ getCensusUri(relativePath: string): string;
271
273
  createCensus(): Promise<string>;
272
274
  addParticipants(censusId: string, participants: CensusParticipant$1[]): Promise<void>;
273
275
  getParticipants(censusId: string): Promise<CensusParticipant$1[]>;
@@ -457,7 +459,6 @@ interface BallotMode {
457
459
  }
458
460
  interface CensusData {
459
461
  censusOrigin: CensusOrigin;
460
- maxVotes: string;
461
462
  censusRoot: string;
462
463
  censusURI: string;
463
464
  }
@@ -468,14 +469,13 @@ interface EncryptionKey {
468
469
 
469
470
  interface CreateProcessRequest {
470
471
  processId: string;
471
- censusRoot: string;
472
+ census: {
473
+ censusOrigin: CensusOrigin;
474
+ censusRoot: string;
475
+ censusURI: string;
476
+ };
472
477
  ballotMode: BallotMode;
473
478
  signature: string;
474
- /**
475
- * The censusOrigin specifies the origin type of the census used in the request.
476
- * This attribute allows the API to determine how the census data should be processed or verified.
477
- */
478
- censusOrigin: CensusOrigin;
479
479
  }
480
480
  interface CreateProcessResponse {
481
481
  processId: string;
@@ -548,8 +548,8 @@ interface VoteProof {
548
548
  interface VoteRequest {
549
549
  /** The `processId` you obtained when creating the process. */
550
550
  processId: string;
551
- /** Your Merkle‐proof that you're in the census. */
552
- censusProof: CensusProof;
551
+ /** Your census proof (only required for CSP, not for MerkleTree). */
552
+ censusProof?: CensusProof;
553
553
  /** Your encrypted ballot. */
554
554
  ballot: VoteBallot;
555
555
  /** The zkSNARK proof that the ballot is well‐formed. */
@@ -615,6 +615,10 @@ interface WorkerStats {
615
615
  interface WorkersResponse {
616
616
  workers: WorkerStats[];
617
617
  }
618
+ interface ParticipantInfoResponse {
619
+ key: string;
620
+ weight: string;
621
+ }
618
622
 
619
623
  declare class VocdoniSequencerService extends BaseService {
620
624
  constructor(baseURL: string);
@@ -625,6 +629,7 @@ declare class VocdoniSequencerService extends BaseService {
625
629
  submitVote(vote: VoteRequest): Promise<void>;
626
630
  getVoteStatus(processId: string, voteId: string): Promise<VoteStatusResponse>;
627
631
  hasAddressVoted(processId: string, address: string): Promise<boolean>;
632
+ isAddressAbleToVote(processId: string, address: string): Promise<ParticipantInfoResponse>;
628
633
  getInfo(): Promise<InfoResponse>;
629
634
  pushMetadata(metadata: ElectionMetadata): Promise<string>;
630
635
  getMetadata(hashOrUrl: string): Promise<ElectionMetadata>;
@@ -864,9 +869,8 @@ type ProcessStatusChangedCallback = EntityCallback<[string, bigint, bigint]>;
864
869
  * @param processID - The process ID
865
870
  * @param root - The new census root
866
871
  * @param uri - The new census URI
867
- * @param maxVotes - The maximum number of votes
868
872
  */
869
- type ProcessCensusUpdatedCallback = EntityCallback<[string, string, string, bigint]>;
873
+ type ProcessCensusUpdatedCallback = EntityCallback<[string, string, string]>;
870
874
  /**
871
875
  * Callback for when a process duration changes.
872
876
  * @param processID - The process ID
@@ -1094,6 +1098,7 @@ interface CSPSignOutput {
1094
1098
  censusOrigin: CensusOrigin;
1095
1099
  root: string;
1096
1100
  address: string;
1101
+ weight: string;
1097
1102
  processId: string;
1098
1103
  publicKey: string;
1099
1104
  signature: string;
@@ -1104,7 +1109,7 @@ interface RawResult<T = any> {
1104
1109
  }
1105
1110
  interface GoDavinciCryptoWasm {
1106
1111
  proofInputs(inputJson: string): RawResult<DavinciCryptoOutput>;
1107
- cspSign(censusOrigin: number, privKey: string, processId: string, address: string): RawResult<CSPSignOutput>;
1112
+ cspSign(censusOrigin: number, privKey: string, processId: string, address: string, weight: string): RawResult<CSPSignOutput>;
1108
1113
  cspVerify(cspProof: string): RawResult<boolean>;
1109
1114
  cspCensusRoot(censusOrigin: number, privKey: string): RawResult<{
1110
1115
  root: string;
@@ -1164,22 +1169,24 @@ declare class DavinciCrypto {
1164
1169
  * @param privKey - The private key in hex format
1165
1170
  * @param processId - The process ID in hex format
1166
1171
  * @param address - The address in hex format
1172
+ * @param weight - The vote weight as a decimal string
1167
1173
  * @returns The CSP proof as a parsed JSON object
1168
1174
  * @throws if called before `await init()`, or if Go returns an error
1169
1175
  */
1170
- cspSign(censusOrigin: CensusOrigin, privKey: string, processId: string, address: string): Promise<CSPSignOutput>;
1176
+ cspSign(censusOrigin: CensusOrigin, privKey: string, processId: string, address: string, weight: string): Promise<CSPSignOutput>;
1171
1177
  /**
1172
1178
  * Verify a CSP (Credential Service Provider) proof.
1173
1179
  * @param censusOrigin - The census origin type (e.g., CensusOrigin.CensusOriginCSP)
1174
1180
  * @param root - The census root
1175
1181
  * @param address - The address
1182
+ * @param weight - The vote weight as a decimal string
1176
1183
  * @param processId - The process ID
1177
1184
  * @param publicKey - The public key
1178
1185
  * @param signature - The signature
1179
1186
  * @returns The verification result
1180
1187
  * @throws if called before `await init()`, or if Go returns an error
1181
1188
  */
1182
- cspVerify(censusOrigin: CensusOrigin, root: string, address: string, processId: string, publicKey: string, signature: string): Promise<boolean>;
1189
+ cspVerify(censusOrigin: CensusOrigin, root: string, address: string, weight: string, processId: string, publicKey: string, signature: string): Promise<boolean>;
1183
1190
  /**
1184
1191
  * Generate a CSP (Credential Service Provider) census root.
1185
1192
  * @param censusOrigin - The census origin type (e.g., CensusOrigin.CensusOriginCSP)
@@ -1204,27 +1211,29 @@ interface BaseProcess {
1204
1211
  type: CensusOrigin;
1205
1212
  /** Census root */
1206
1213
  root: string;
1207
- /** Census size */
1208
- size: number;
1209
1214
  /** Census URI */
1210
1215
  uri: string;
1211
1216
  };
1212
1217
  /** Ballot configuration */
1213
1218
  ballot: BallotMode;
1214
1219
  /** Election questions and choices (required) */
1215
- questions: Array<{
1220
+ questions: Array<ProcessQuestion>;
1221
+ }
1222
+ /**
1223
+ * Question structure used in process configuration and metadata
1224
+ */
1225
+ type ProcessQuestion = {
1226
+ title: string;
1227
+ description?: string;
1228
+ choices: Array<{
1216
1229
  title: string;
1217
- description?: string;
1218
- choices: Array<{
1219
- title: string;
1220
- value: number;
1221
- }>;
1230
+ value: number;
1222
1231
  }>;
1223
- }
1232
+ };
1224
1233
  /**
1225
- * Configuration for creating a process
1234
+ * Base configuration shared by both process creation variants
1226
1235
  */
1227
- interface ProcessConfig extends Omit<BaseProcess, 'census'> {
1236
+ interface BaseProcessConfig {
1228
1237
  /**
1229
1238
  * Census - either a Census object (PlainCensus, WeightedCensus, CspCensus, PublishedCensus)
1230
1239
  * or manual configuration. If a Census object is provided and not published, it will be
@@ -1240,6 +1249,8 @@ interface ProcessConfig extends Omit<BaseProcess, 'census'> {
1240
1249
  /** Census URI */
1241
1250
  uri: string;
1242
1251
  };
1252
+ /** Ballot configuration */
1253
+ ballot: BallotMode;
1243
1254
  /** Process timing - use either duration-based or date-based configuration */
1244
1255
  timing: {
1245
1256
  /** Start date/time (Date object, ISO string, or Unix timestamp, default: now + 60 seconds) */
@@ -1250,6 +1261,31 @@ interface ProcessConfig extends Omit<BaseProcess, 'census'> {
1250
1261
  endDate?: Date | string | number;
1251
1262
  };
1252
1263
  }
1264
+ /**
1265
+ * Process configuration with metadata fields (title, description, questions)
1266
+ * The metadata will be created and uploaded automatically
1267
+ */
1268
+ interface ProcessConfigWithMetadata extends BaseProcessConfig {
1269
+ /** Process title */
1270
+ title: string;
1271
+ /** Process description (optional) */
1272
+ description?: string;
1273
+ /** Election questions and choices (at least one required) */
1274
+ questions: [ProcessQuestion, ...ProcessQuestion[]];
1275
+ }
1276
+ /**
1277
+ * Process configuration with a pre-existing metadata URI
1278
+ * No metadata upload will occur - the provided URI will be used directly
1279
+ */
1280
+ interface ProcessConfigWithMetadataUri extends BaseProcessConfig {
1281
+ /** Pre-existing metadata URI to use instead of uploading new metadata */
1282
+ metadataUri: string;
1283
+ }
1284
+ /**
1285
+ * Configuration for creating a process
1286
+ * Use either metadata fields (title, questions) or a pre-existing metadataUri
1287
+ */
1288
+ type ProcessConfig = ProcessConfigWithMetadata | ProcessConfigWithMetadataUri;
1253
1289
  /**
1254
1290
  * Result of process creation
1255
1291
  */
@@ -1379,7 +1415,8 @@ declare class ProcessOrchestrationService {
1379
1415
  */
1380
1416
  private dateToUnixTimestamp;
1381
1417
  /**
1382
- * Creates metadata from the simplified configuration
1418
+ * Creates metadata from the configuration with metadata fields
1419
+ * This method should only be called with ProcessConfigWithMetadata
1383
1420
  */
1384
1421
  private createMetadata;
1385
1422
  /**
@@ -2178,6 +2215,23 @@ declare class DavinciSDK {
2178
2215
  * ```
2179
2216
  */
2180
2217
  hasAddressVoted(processId: string, address: string): Promise<boolean>;
2218
+ /**
2219
+ * Check if an address is able to vote in a process and get participant information.
2220
+ *
2221
+ * Does NOT require a provider - uses API calls only.
2222
+ *
2223
+ * @param processId - The process ID
2224
+ * @param address - The voter's address
2225
+ * @returns Promise resolving to participant information (key and weight)
2226
+ *
2227
+ * @example
2228
+ * ```typescript
2229
+ * const participantInfo = await sdk.isAddressAbleToVote(processId, "0x1234567890abcdef...");
2230
+ * console.log("Address:", participantInfo.key);
2231
+ * console.log("Weight:", participantInfo.weight);
2232
+ * ```
2233
+ */
2234
+ isAddressAbleToVote(processId: string, address: string): Promise<ParticipantInfoResponse>;
2181
2235
  /**
2182
2236
  * Watch vote status changes in real-time using an async generator.
2183
2237
  * This method yields each status change as it happens, perfect for showing
@@ -2507,4 +2561,4 @@ declare class DavinciSDK {
2507
2561
  }
2508
2562
 
2509
2563
  export { BaseService, Census, CensusOrchestrator, CensusOrigin, CensusType, CircomProof, ContractServiceError, CspCensus, DavinciCrypto, DavinciSDK, ElectionMetadataTemplate, ElectionResultsTypeNames, OrganizationAdministratorError, OrganizationCreateError, OrganizationDeleteError, OrganizationRegistryService, OrganizationUpdateError, PlainCensus, ProcessCensusError, ProcessCreateError, ProcessDurationError, ProcessOrchestrationService, ProcessRegistryService, ProcessResultError, ProcessStateTransitionError, ProcessStatus, ProcessStatusError, PublishedCensus, SmartContractService, TxStatus, VocdoniApiService, VocdoniCensusService, VocdoniSequencerService, VoteOrchestrationService, VoteStatus, WeightedCensus, assertCSPCensusProof, assertMerkleCensusProof, createProcessSignatureMessage, getElectionMetadataTemplate, isCSPCensusProof, isMerkleCensusProof, signProcessCreation, validateProcessId };
2510
- export type { AbstainProperties, AnyJson, ApiError, ApprovalProperties, BallotMode, BaseCensusProof, BaseProcess, BudgetProperties, CSPCensusProof, CSPCensusProofProvider, CSPSignOutput, CensusData, CensusParticipant$1 as CensusParticipant, CensusProof, CensusProviders, CensusSizeResponse, Choice, ChoiceProperties, CircomProofOptions, CreateProcessRequest, CreateProcessResponse, CustomMeta, DavinciCryptoCiphertext, DavinciCryptoInputs, DavinciCryptoOptions, DavinciCryptoOutput, DavinciSDKConfig, ElectionMetadata, ElectionResultsType, EncryptionKey, EntityCallback, GetProcessResponse, Groth16Proof, HealthResponse, IChoice, IQuestion, InfoResponse, JsonArray, JsonMap, ListProcessesResponse, MerkleCensusProof, MerkleCensusProofProvider, MultiLanguage, OrganizationAdministratorAddedCallback, OrganizationAdministratorRemovedCallback, OrganizationCreatedCallback, OrganizationInfo, OrganizationUpdatedCallback, ProcessCensusUpdatedCallback, ProcessConfig, ProcessCreatedCallback, ProcessCreationResult, ProcessDurationChangedCallback, ProcessInfo, ProcessResultsSetCallback, ProcessStateRootUpdatedCallback, ProcessStatusChangedCallback, ProofInputs, ProtocolVersion, PublishCensusResponse, QuadraticProperties, Question, SequencerStats, Snapshot, SnapshotsQueryParams, SnapshotsResponse, TxStatusEvent, VocdoniApiServiceConfig, VoteBallot, VoteCiphertext, VoteConfig, VoteOrchestrationConfig, VoteProof, VoteRequest, VoteResult, VoteStatusInfo, VoteStatusResponse, WeightedParticipant, WorkerStats, WorkersResponse };
2564
+ export type { AbstainProperties, AnyJson, ApiError, ApprovalProperties, BallotMode, BaseCensusProof, BaseProcess, BudgetProperties, CSPCensusProof, CSPCensusProofProvider, CSPSignOutput, CensusData, CensusParticipant$1 as CensusParticipant, CensusProof, CensusProviders, CensusSizeResponse, Choice, ChoiceProperties, CircomProofOptions, CreateProcessRequest, CreateProcessResponse, CustomMeta, DavinciCryptoCiphertext, DavinciCryptoInputs, DavinciCryptoOptions, DavinciCryptoOutput, DavinciSDKConfig, ElectionMetadata, ElectionResultsType, EncryptionKey, EntityCallback, GetProcessResponse, Groth16Proof, HealthResponse, IChoice, IQuestion, InfoResponse, JsonArray, JsonMap, ListProcessesResponse, MerkleCensusProof, MerkleCensusProofProvider, MultiLanguage, OrganizationAdministratorAddedCallback, OrganizationAdministratorRemovedCallback, OrganizationCreatedCallback, OrganizationInfo, OrganizationUpdatedCallback, ParticipantInfoResponse, ProcessCensusUpdatedCallback, ProcessConfig, ProcessConfigWithMetadata, ProcessConfigWithMetadataUri, ProcessCreatedCallback, ProcessCreationResult, ProcessDurationChangedCallback, ProcessInfo, ProcessQuestion, ProcessResultsSetCallback, ProcessStateRootUpdatedCallback, ProcessStatusChangedCallback, ProofInputs, ProtocolVersion, PublishCensusResponse, QuadraticProperties, Question, SequencerStats, Snapshot, SnapshotsQueryParams, SnapshotsResponse, TxStatusEvent, VocdoniApiServiceConfig, VoteBallot, VoteCiphertext, VoteConfig, VoteOrchestrationConfig, VoteProof, VoteRequest, VoteResult, VoteStatusInfo, VoteStatusResponse, WeightedParticipant, WorkerStats, WorkersResponse };
package/dist/index.js CHANGED
@@ -89,12 +89,12 @@ class VocdoniCensusService extends BaseService {
89
89
  super(baseURL);
90
90
  }
91
91
  /**
92
- * Constructs the URI for accessing a census by its root
93
- * @param censusRoot - The census root (hex-prefixed)
92
+ * Constructs the URI for accessing a census
93
+ * @param relativePath - The relative path
94
94
  * @returns The constructed URI for the census
95
95
  */
96
- getCensusUri(censusRoot) {
97
- return `${this.axios.defaults.baseURL}/censuses/${censusRoot}`;
96
+ getCensusUri(relativePath) {
97
+ return `${this.axios.defaults.baseURL}${relativePath}`;
98
98
  }
99
99
  createCensus() {
100
100
  return this.request({
@@ -163,10 +163,13 @@ class VocdoniCensusService extends BaseService {
163
163
  return this.request({
164
164
  method: "POST",
165
165
  url: `/censuses/${censusId}/publish`
166
- }).then((response) => ({
167
- ...response,
168
- uri: this.getCensusUri(response.root)
169
- }));
166
+ }).then((apiResponse) => {
167
+ const { censusUri, ...responseWithoutCensusUri } = apiResponse;
168
+ return {
169
+ ...responseWithoutCensusUri,
170
+ uri: this.getCensusUri(censusUri)
171
+ };
172
+ });
170
173
  }
171
174
  // BigQuery endpoints
172
175
  getSnapshots(params) {
@@ -196,13 +199,13 @@ var CensusOrigin = /* @__PURE__ */ ((CensusOrigin2) => {
196
199
  return CensusOrigin2;
197
200
  })(CensusOrigin || {});
198
201
  function isBaseCensusProof(proof) {
199
- return !!proof && typeof proof.root === "string" && typeof proof.address === "string" && typeof proof.weight === "string" && typeof proof.censusOrigin === "number" && Object.values(CensusOrigin).includes(proof.censusOrigin);
202
+ return !!proof && typeof proof.root === "string" && typeof proof.address === "string" && typeof proof.censusOrigin === "number" && Object.values(CensusOrigin).includes(proof.censusOrigin);
200
203
  }
201
204
  function isMerkleCensusProof(proof) {
202
- return isBaseCensusProof(proof) && proof.censusOrigin === 1 /* CensusOriginMerkleTree */ && typeof proof.value === "string" && typeof proof.siblings === "string";
205
+ return isBaseCensusProof(proof) && proof.censusOrigin === 1 /* CensusOriginMerkleTree */ && typeof proof.weight === "string" && typeof proof.value === "string" && typeof proof.siblings === "string";
203
206
  }
204
207
  function isCSPCensusProof(proof) {
205
- return isBaseCensusProof(proof) && proof.censusOrigin === 2 /* CensusOriginCSP */ && typeof proof.processId === "string" && typeof proof.publicKey === "string" && typeof proof.signature === "string";
208
+ return isBaseCensusProof(proof) && proof.censusOrigin === 2 /* CensusOriginCSP */ && typeof proof.weight === "string" && typeof proof.processId === "string" && typeof proof.publicKey === "string" && typeof proof.signature === "string";
206
209
  }
207
210
  function assertMerkleCensusProof(proof) {
208
211
  if (!isMerkleCensusProof(proof)) {
@@ -562,6 +565,12 @@ class VocdoniSequencerService extends BaseService {
562
565
  throw error;
563
566
  }
564
567
  }
568
+ isAddressAbleToVote(processId, address) {
569
+ return this.request({
570
+ method: "GET",
571
+ url: `/processes/${processId}/participants/${address}`
572
+ });
573
+ }
565
574
  getInfo() {
566
575
  return this.request({
567
576
  method: "GET",
@@ -985,7 +994,6 @@ class ProcessRegistryService extends SmartContractService {
985
994
  newProcess(status, startTime, duration, ballotMode, census, metadata, encryptionKey, initStateRoot) {
986
995
  const contractCensus = {
987
996
  censusOrigin: BigInt(census.censusOrigin),
988
- maxVotes: BigInt(census.maxVotes),
989
997
  censusRoot: census.censusRoot,
990
998
  censusURI: census.censusURI
991
999
  };
@@ -1016,7 +1024,6 @@ class ProcessRegistryService extends SmartContractService {
1016
1024
  setProcessCensus(processID, census) {
1017
1025
  const contractCensus = {
1018
1026
  censusOrigin: BigInt(census.censusOrigin),
1019
- maxVotes: BigInt(census.maxVotes),
1020
1027
  censusRoot: census.censusRoot,
1021
1028
  censusURI: census.censusURI
1022
1029
  };
@@ -1185,7 +1192,6 @@ class ProcessOrchestrationService {
1185
1192
  const census = {
1186
1193
  type: Number(rawProcess.census.censusOrigin),
1187
1194
  root: rawProcess.census.censusRoot,
1188
- size: Number(rawProcess.census.maxVotes),
1189
1195
  uri: rawProcess.census.censusURI || ""
1190
1196
  };
1191
1197
  const ballot = {
@@ -1200,11 +1206,11 @@ class ProcessOrchestrationService {
1200
1206
  };
1201
1207
  return {
1202
1208
  processId,
1203
- title,
1209
+ title: title || "",
1204
1210
  description,
1205
1211
  census,
1206
1212
  ballot,
1207
- questions,
1213
+ questions: questions || [],
1208
1214
  status: Number(rawProcess.status),
1209
1215
  creator: rawProcess.organizationId,
1210
1216
  startDate: new Date(startTime * 1e3),
@@ -1333,20 +1339,27 @@ class ProcessOrchestrationService {
1333
1339
  const censusConfig = await this.handleCensus(config.census);
1334
1340
  const censusRoot = censusConfig.root;
1335
1341
  const ballotMode = config.ballot;
1336
- const metadata = this.createMetadata(config);
1337
- const metadataHash = await this.apiService.sequencer.pushMetadata(metadata);
1338
- const metadataUri = this.apiService.sequencer.getMetadataUrl(metadataHash);
1342
+ let metadataUri;
1343
+ if ("metadataUri" in config) {
1344
+ metadataUri = config.metadataUri;
1345
+ } else {
1346
+ const metadata = this.createMetadata(config);
1347
+ const metadataHash = await this.apiService.sequencer.pushMetadata(metadata);
1348
+ metadataUri = this.apiService.sequencer.getMetadataUrl(metadataHash);
1349
+ }
1339
1350
  const signature = await signProcessCreation(processId, this.signer);
1340
1351
  const sequencerResult = await this.apiService.sequencer.createProcess({
1341
1352
  processId,
1342
- censusRoot,
1353
+ census: {
1354
+ censusOrigin: censusConfig.type,
1355
+ censusRoot,
1356
+ censusURI: censusConfig.uri
1357
+ },
1343
1358
  ballotMode,
1344
- signature,
1345
- censusOrigin: censusConfig.type
1359
+ signature
1346
1360
  });
1347
1361
  const census = {
1348
1362
  censusOrigin: censusConfig.type,
1349
- maxVotes: censusConfig.size.toString(),
1350
1363
  censusRoot,
1351
1364
  censusURI: censusConfig.uri
1352
1365
  };
@@ -1415,15 +1428,13 @@ class ProcessOrchestrationService {
1415
1428
  throw new Error("Invalid date format. Use Date object, ISO string, or Unix timestamp.");
1416
1429
  }
1417
1430
  /**
1418
- * Creates metadata from the simplified configuration
1431
+ * Creates metadata from the configuration with metadata fields
1432
+ * This method should only be called with ProcessConfigWithMetadata
1419
1433
  */
1420
1434
  createMetadata(config) {
1421
1435
  const metadata = getElectionMetadataTemplate();
1422
1436
  metadata.title.default = config.title;
1423
1437
  metadata.description.default = config.description || "";
1424
- if (!config.questions || config.questions.length === 0) {
1425
- throw new Error("Questions are required. Please provide at least one question with choices.");
1426
- }
1427
1438
  metadata.questions = config.questions.map((q) => ({
1428
1439
  title: { default: q.title },
1429
1440
  description: { default: q.description || "" },
@@ -1888,16 +1899,19 @@ class VoteOrchestrationService {
1888
1899
  );
1889
1900
  const { proof } = await this.generateZkProof(circomInputs);
1890
1901
  const signature = await this.signVote(voteId);
1891
- await this.submitVoteRequest({
1902
+ const voteRequest = {
1892
1903
  processId: config.processId,
1893
- censusProof,
1894
1904
  ballot: cryptoOutput.ballot,
1895
1905
  ballotProof: proof,
1896
1906
  ballotInputsHash: cryptoOutput.ballotInputsHash,
1897
1907
  address: voterAddress,
1898
1908
  signature,
1899
1909
  voteId
1900
- });
1910
+ };
1911
+ if (process.census.censusOrigin === CensusOrigin.CensusOriginCSP) {
1912
+ voteRequest.censusProof = censusProof;
1913
+ }
1914
+ await this.submitVoteRequest(voteRequest);
1901
1915
  const status = await this.apiService.sequencer.getVoteStatus(config.processId, voteId);
1902
1916
  return {
1903
1917
  voteId,
@@ -2341,14 +2355,15 @@ class DavinciCrypto {
2341
2355
  * @param privKey - The private key in hex format
2342
2356
  * @param processId - The process ID in hex format
2343
2357
  * @param address - The address in hex format
2358
+ * @param weight - The vote weight as a decimal string
2344
2359
  * @returns The CSP proof as a parsed JSON object
2345
2360
  * @throws if called before `await init()`, or if Go returns an error
2346
2361
  */
2347
- async cspSign(censusOrigin, privKey, processId, address) {
2362
+ async cspSign(censusOrigin, privKey, processId, address, weight) {
2348
2363
  if (!this.initialized) {
2349
2364
  throw new Error("DavinciCrypto not initialized \u2014 call `await init()` first");
2350
2365
  }
2351
- const raw = globalThis.DavinciCrypto.cspSign(censusOrigin, privKey, processId, address);
2366
+ const raw = globalThis.DavinciCrypto.cspSign(censusOrigin, privKey, processId, address, weight);
2352
2367
  if (raw.error) {
2353
2368
  throw new Error(`Go/WASM cspSign error: ${raw.error}`);
2354
2369
  }
@@ -2362,13 +2377,14 @@ class DavinciCrypto {
2362
2377
  * @param censusOrigin - The census origin type (e.g., CensusOrigin.CensusOriginCSP)
2363
2378
  * @param root - The census root
2364
2379
  * @param address - The address
2380
+ * @param weight - The vote weight as a decimal string
2365
2381
  * @param processId - The process ID
2366
2382
  * @param publicKey - The public key
2367
2383
  * @param signature - The signature
2368
2384
  * @returns The verification result
2369
2385
  * @throws if called before `await init()`, or if Go returns an error
2370
2386
  */
2371
- async cspVerify(censusOrigin, root, address, processId, publicKey, signature) {
2387
+ async cspVerify(censusOrigin, root, address, weight, processId, publicKey, signature) {
2372
2388
  if (!this.initialized) {
2373
2389
  throw new Error("DavinciCrypto not initialized \u2014 call `await init()` first");
2374
2390
  }
@@ -2376,6 +2392,7 @@ class DavinciCrypto {
2376
2392
  censusOrigin,
2377
2393
  root,
2378
2394
  address,
2395
+ weight,
2379
2396
  processId,
2380
2397
  publicKey,
2381
2398
  signature
@@ -2827,6 +2844,30 @@ class DavinciSDK {
2827
2844
  }
2828
2845
  return this.voteOrchestrator.hasAddressVoted(processId, address);
2829
2846
  }
2847
+ /**
2848
+ * Check if an address is able to vote in a process and get participant information.
2849
+ *
2850
+ * Does NOT require a provider - uses API calls only.
2851
+ *
2852
+ * @param processId - The process ID
2853
+ * @param address - The voter's address
2854
+ * @returns Promise resolving to participant information (key and weight)
2855
+ *
2856
+ * @example
2857
+ * ```typescript
2858
+ * const participantInfo = await sdk.isAddressAbleToVote(processId, "0x1234567890abcdef...");
2859
+ * console.log("Address:", participantInfo.key);
2860
+ * console.log("Weight:", participantInfo.weight);
2861
+ * ```
2862
+ */
2863
+ async isAddressAbleToVote(processId, address) {
2864
+ if (!this.initialized) {
2865
+ throw new Error(
2866
+ "SDK must be initialized before checking participant info. Call sdk.init() first."
2867
+ );
2868
+ }
2869
+ return this.apiService.sequencer.isAddressAbleToVote(processId, address);
2870
+ }
2830
2871
  /**
2831
2872
  * Watch vote status changes in real-time using an async generator.
2832
2873
  * This method yields each status change as it happens, perfect for showing