Polls struct provides methods for creating polls, casting votes, and decrypting poll results. Votes are end-to-end encrypted using AES-256-GCM with HKDF-SHA256 key derivation.
Access
Access poll operations through the client:Methods
create
Create a new poll in a chat.Recipient JID. Can be a direct message or group chat.
Poll question or title.
List of poll options. Must have between 2 and 12 entries, with no duplicates.
Maximum number of options a voter can select. Must be between 1 and the number of options. When set to 1, creates a single-select poll (uses
poll_creation_message_v3). When greater than 1, creates a multi-select poll (uses poll_creation_message).A tuple containing the message ID and a 32-byte random secret. The
message_secret is required to decrypt votes — store it securely.vote
Cast a vote on an existing poll.Chat JID where the poll was sent.
Message ID of the original poll creation message.
JID of the user who created the poll.
The 32-byte secret returned by
create. Required for vote encryption.Names of the selected options. Pass an empty slice to clear your vote.
Message ID of the vote update message.
decrypt_vote
Decrypt an encrypted poll vote. This is a static method — no client instance needed.Encrypted vote payload (from the
PollUpdateMessage).12-byte initialization vector from the encrypted vote.
The 32-byte secret from poll creation.
Message ID of the original poll.
JID of the poll creator (AD suffix is stripped automatically).
JID of the voter (AD suffix is stripped automatically).
List of 32-byte SHA-256 hashes of the selected option names.
aggregate_votes
Decrypt multiple votes and tally results per option. This is a static method. Later votes from the same voter replace earlier ones (last-vote-wins).The original poll option names (in order).
Slice of
(voter_jid, enc_payload, enc_iv) tuples, ordered oldest-first.The 32-byte secret from poll creation.
Message ID of the original poll.
JID of the poll creator.
One entry per poll option, each containing the option name and a list of voter JID strings.
Votes that fail to decrypt are logged as warnings and skipped. An empty selection from a voter clears their previous vote.
Types
PollOptionResult
Aggregated result for a single poll option.| Field | Type | Description |
|---|---|---|
name | String | The option name |
voters | Vec<String> | JID strings of voters who selected this option |
Low-level utilities
Thewacore::poll module exposes the cryptographic primitives used internally:
| Function | Description |
|---|---|
compute_option_hash(name: &str) -> [u8; 32] | SHA-256 hash of an option name |
derive_vote_encryption_key(secret, stanza_id, creator, voter) -> [u8; 32] | HKDF-SHA256 key derivation |
encrypt_poll_vote(hashes, key, stanza_id, voter) -> (Vec<u8>, [u8; 12]) | AES-256-GCM encryption |
decrypt_poll_vote(payload, iv, key, stanza_id, voter) -> Vec<Vec<u8>> | AES-256-GCM decryption |
Error handling
All methods returnResult<T, anyhow::Error>. Common errors:
- Fewer than 2 options or more than 12 options when creating a poll
- Duplicate option names — would produce identical SHA-256 hashes
selectable_countout of range — must be between 1 and the option count- Invalid
message_secretsize — must be exactly 32 bytes - GCM tag verification failed — wrong key, corrupted payload, or tampered data
- Invalid IV length — must be exactly 12 bytes
- Not logged in — voter’s JID cannot be determined when voting
See also
- Polls guide - Step-by-step usage guide
- Sending messages - Send other message types
- Send API - Low-level send operations