export interface IAVClient { initialize(latestConfig: LatestConfig): Promise; initialize(): Promise; requestAccessCode(opaqueVoterId: string, email: string): Promise; validateAccessCode(code: string): Promise; registerVoter(): Promise; constructBallot(ballotSelection: BallotSelection): Promise; waitForVerifierRegistration(): Promise; spoilBallot(): Promise; castBallot(affidavit: Affidavit): Promise; purgeData(): void; challengeBallot(): Promise; checkBallotStatus(trackingCode: string): Promise; } /** * This is an index, with contest ids for keys, and arbitrary values that belong to matching contests. * * Example, with selected contest options: * ```javascript * { '1': 'option1', '2': 'optiona' } * ``` * * Here `'1'` and `'2'` are contest ids, and `'option1'` and `'optiona'` are selected contest options. * * @template T Defines the data type of the value */ export interface ContestMap { [contestId: string]: T; } export interface EncryptedPile { multiplier: number; cryptograms: string[]; randomizers: string[]; } export interface SealedPile { multiplier: number; cryptograms: string[]; } export type KeyPair = { privateKey: string; publicKey: string; }; /** * A Base64-encoded string containing the affidavit */ export type Affidavit = string; export interface LocalString { [locale: string]: string; } export interface Election { enabled: boolean; id: number; title: LocalString; subtitle: LocalString; description: LocalString; } /** * Example of a receipt: * ```javascript * { * previousBoardHash: 'd8d9742271592d1b212bbd4cbbbe357aef8e00cdbdf312df95e9cf9a1a921465', * boardHash: '5a9175c2b3617298d78be7d0244a68f34bc8b2a37061bb4d3fdf97edc1424098', * registeredAt: '2020-03-01T10:00:00.000+01:00', * serverSignature: 'dbcce518142b8740a5c911f727f3c02829211a8ddfccabeb89297877e4198bc1,46826ddfccaac9ca105e39c8a2d015098479624c411b4783ca1a3600daf4e8fa', * voteSubmissionId: 6 * } * ``` */ export type BallotBoxReceipt = { trackingCode: string; receipt: string; }; export type BoardItem = VoterSessionItem | VoterCommitmentItem | BoardCommitmentItem | BallotCryptogramItem | CastRequestItem; interface IdentityConfirmationTokenIdentification { identitiyConfirmationToken: string; } interface PublicKeyIdentification { publicKey: string; } export type VoterAuthorizationIdentification = IdentityConfirmationTokenIdentification | PublicKeyIdentification; export type BoardItemType = "BallotCryptogramsItem" | "BoardEncryptionCommitmentItem" | "CastRequestItem" | "SpoilRequestItem" | "VerificationStartItem" | "VerifierItem" | "VoterEncryptionCommitmentItem" | "VoterSessionItem" | "VoterEncryptionCommitmentOpeningItem"; export interface BaseBoardItem { address: string; author: string; parentAddress: string; previousAddress: string; registeredAt: string; signature: string; } export interface BaseVerificationItem extends BaseBoardItem { shortAddress: string; } export interface VoterSessionItem extends BaseBoardItem { content: { authToken: string; identifier: string; voterGroup: string; publicKey: string; votingRoundReference: string; weight: number; segments?: Segments; }; type: "VoterSessionItem"; } interface Segments { [key: string]: string; } export interface BoardCommitmentItem extends BaseBoardItem { content: { commitment: string; }; type: "BoardEncryptionCommitmentItem"; } export interface VoterCommitmentOpeningItem extends BaseVerificationItem { content: { package: EncryptedCommitmentOpening; }; type: "VoterEncryptionCommitmentOpeningItem"; } export interface BoardCommitmentOpeningItem extends BaseVerificationItem { content: { package: EncryptedCommitmentOpening; }; type: "BoardEncryptionCommitmentOpeningItem"; } export interface VoterCommitmentItem extends BaseBoardItem { content: { commitment: string; }; type: "VoterEncryptionCommitmentItem"; } export interface BallotCryptogramItem extends BaseBoardItem { content: { contests: ContestMap; }; type: "BallotCryptogramsItem"; } export interface VerificationStartItem extends BaseVerificationItem { type: "VerificationStartItem"; } export interface VerifierItem extends BaseVerificationItem { content: { publicKey: string; }; type: "VerifierItem"; } export interface SpoilRequestItem extends BaseBoardItem { type: "SpoilRequestItem"; } export interface CastRequestItem extends BaseBoardItem { content: Record; type: "CastRequestItem"; } export interface CommitmentOpening { randomizers: ContestMap; commitmentRandomness: string; } export type EncryptedCommitmentOpening = string; export interface ItemExpectation { content?: { [k: string]: unknown; }; type: BoardItemType; parentAddress: string; } export type Signature = string; export type HashValue = string; export interface MarkingType { minMarks: number; maxMarks: number; maxPiles?: number; voteVariation?: string; blankSubmission: "disabled" | "active_choice" | "implicit"; votesAllowedPerOption?: number; encoding: { codeSize: number; maxSize: number; cryptogramCount: number; }; } export type BallotStatus = { status: string; activities: { type: string; registered_at: string; }; }; export type BallotSelection = { reference: string; contestSelections: ContestSelection[]; }; export type ContestSelection = { reference: string; piles: SelectionPile[]; }; export type SelectionPile = { multiplier: number; optionSelections: OptionSelection[]; explicitBlank?: boolean; }; export type OptionSelection = { reference: string; text?: string; }; export type ContestEnvelope = { reference: string; piles: EncryptedPile[]; }; export type ReadableContestSelection = { reference: string; title: string; piles: ReadableSelectionPile[]; }; export type ReadableSelectionPile = { multiplier: number; optionSelections: ReadableOptionSelection[]; }; export type ReadableOptionSelection = { reference: string; title: string; text?: string; }; export interface LatestConfig { items: LatestConfigItems; receipt?: string; } export interface LatestConfigItems { thresholdConfig: ThresholdConfig; voterAuthorizerConfig: VoterAuthorizer; ballotConfigs: BallotConfigMap; contestConfigs: ContestConfigMap; votingRoundConfigs: VotingRoundConfigMap; electionConfig: ElectionConfig; genesisConfig: GenesisConfig; latestConfigItem: LatestConfigurationConfig; segmentsConfig: SegmentsConfigMap | null; extractionIntents?: ExtractionIntents; extractionData?: ExtractionData; extractionConfirmations?: ExtractionConfirmations; } export interface LatestConfigurationConfig extends BaseBoardItem { type: 'ThresholdConfigItem' | 'VoterAuthorizationConfigItem' | 'BallotConfigItem' | 'ContestConfigItem' | 'VotingRoundConfigItem' | 'ElectionConfigItem' | 'GenesisItem' | 'SegmentsConfigItem'; content: VoterAuthorizerContent | ThresholdConfigContent | BallotContent | ContestContent | VotingRoundContent | ElectionConfigContent | GenesisConfigContent | SegmentsConfigContent; } export interface ThresholdConfig extends BaseBoardItem { content: ThresholdConfigContent; type: 'ThresholdConfigItem'; } export interface ThresholdConfigContent { encryptionKey: string; threshold: number; trustees: Trustee[]; } export interface Trustee { publicKey: string; id: number; polynomialCoefficients: PolynomialCoefficient[]; } export interface PolynomialCoefficient { degree: number; coefficient: string; } export interface VoterAuthorizer extends BaseBoardItem { content: VoterAuthorizerContent; type: 'VoterAuthorizationConfigItem'; } export interface VoterAuthorizerContent { identityProvider: VoterAuthorizerContentItem; voterAuthorizer: VoterAuthorizerContentItem; } export interface VoterAuthorizerContentItem { contextUuid: string; publicKey: string; url: string; authorizationMode?: 'proof-of-identity' | 'proof-of-election-codes'; } export interface BallotConfigMap { [voterGroupId: string]: BallotConfig; } export interface BallotConfig extends BaseBoardItem { content: BallotContent; type: 'BallotConfigItem'; } export interface BallotContent { reference: string; voterGroup: string; contestReferences: string[]; attachment?: string; } export interface ContestConfigMap { [contestReference: string]: ContestConfig; } export interface ContestConfig extends BaseBoardItem { content: ContestContent; type: 'ContestConfigItem'; } export type availableCustomRulesets = 'belgian_ballot_rules'; export interface ContestContent { reference: string; title: LocalString; id?: number; subtitle?: LocalString; question?: LocalString; description?: LocalString; collapsable?: boolean; collapseDefault?: boolean; searchForm?: boolean; disregardVoterWeight?: boolean; randomizeOptions?: boolean; markingType: MarkingType; resultType: ResultType; options: OptionContent[]; identifiable?: boolean; contestPositions?: ContestPositionMap; blankOptionColor?: string; customRulesets?: availableCustomRulesets[]; attachments?: Attachment[]; displayScrollToBottomBtn?: boolean; displayDescriptionOnSummary?: boolean; mode?: "list" | "gallery"; } export interface Error { message: string; keys?: any; } export interface ResultType { name: string; } export interface OptionContent { reference: string; code: number; id?: number; title: LocalString; subtitle?: LocalString; description?: LocalString; image?: string; selectable?: boolean; exclusive?: boolean; excluded?: boolean; children?: OptionContent[]; parentContent?: OptionContent; parent?: ParentOption | null; ancestry?: string; position?: number; randomizeChildren?: boolean; accentColor?: string; url?: LocalString; videoUrl?: LocalString; voteLimit?: number; writeIn?: { maxSize: number; encoding: 'utf8'; }; maxChooseableSuboptions?: number; minChooseableSuboptions?: number; candidateId?: number; isParty?: boolean; } export interface ParentOption { reference: string; code: number; id: number; contest_id?: number; position?: number; ancestry?: string; data?: { title: LocalString; image?: string | null; randomize_children?: boolean; accent_color?: string; description?: LocalString; }; created_at?: string; updated_at?: string; enabled?: boolean; exclusive?: boolean; selectable?: boolean; } export interface VotingRoundConfigMap { [votingRoundReference: string]: VotingRoundConfig; } export interface VotingRoundConfig extends BaseBoardItem { content: VotingRoundContent; type: 'VotingRoundConfigItem'; } export interface VotingRoundContent { reference: string; status: "open" | "scheduled" | "closed"; title?: LocalString; name?: string; contestReferences: string[]; identifiable?: boolean; demo?: boolean; handRaise?: boolean; contestPositions?: ContestPositionMap; schedule?: { from: string; to: string; }; resultPublicationDelay?: number; recasting?: boolean; attachments?: Attachment[]; prefilledContestSelections?: ContestSelection[]; } export interface ElectionConfig extends BaseBoardItem { content: ElectionConfigContent; type: 'ElectionConfigItem'; } export interface ElectionConfigContent { address?: string; title: LocalString; subtitle?: LocalString; description?: LocalString; uuid: string; status: string; locales: string[]; sessionTimeout?: number; numDaysToCureAffidavits?: number; castRequestItemAttachmentEncryptionKey?: string; requireCastRequestAttachment?: boolean; uocavaOpeningDate?: string; nonUocavaOpeningDate?: string; extractionThreshold?: number; rejectionReasons?: string[]; bcTimeout?: number; schedule?: { from: string; to: string; }; sendTrackingCodeByEmail?: boolean; dbasUrl?: string; utilizeScreenspace?: boolean; } export interface GenesisConfig extends BaseBoardItem { parentAddress: '0000000000000000000000000000000000000000000000000000000000000000'; previousAddress: '0000000000000000000000000000000000000000000000000000000000000000'; content: GenesisConfigContent; type: 'GenesisItem'; } export interface GenesisConfigContent { ballotAcceptance: 'inferred' | 'manual'; eaCurveName: 'secp256r1' | 'secp384r1' | 'secp521r1' | 'secp256k1'; eaPublicKey: string; electionSlug: string; publicKey: string; resultExtraction: 'post-election' | 'throughout-election'; } export interface SegmentsConfigMap { [segments: string]: SegmentsConfig; } export interface ContestPositionMap { [contestReference: string]: number; } export interface SegmentsConfig extends BaseBoardItem { content: SegmentsConfigContent; type: 'SegmentsConfigItem'; } export interface SegmentsConfigContent { segments: string[]; } export interface ExtractionData { votingRoundReference?: string; } export interface ExtractionIntentsMap { [extractionIntent: string]: ExtractionIntents; } export interface ExtractionIntents { extractionIntent?: any; receipt?: string; meta?: { pollingUrl: string | undefined; }; } export interface ExtractionConfirmations { parentAddress?: string; signature?: string; content?: string; attachment?: string; } export interface Attachment { name: string; sha: string; } export interface ClientState { latestConfig: LatestConfig; votingRoundReference: string; voterSession: VoterSessionItem; } export interface CheckedEventArgs { reference: string; amount: number; } export interface PartialResult { showPercentage?: boolean; reference: string; results: PartialCount; } export interface PartialCount { count: number; percentage: number; } export {};