Skip to content

Commit 536a060

Browse files
committed
feat(api): expose vote memo and allow setting it from the client
- api: add `memo` to the Vote response and populate it in GET /votes/{voteId} from the authoritative state (the memo is not indexed). - apiclient: add Memo to VoteData and attach it to the VoteEnvelope before the tx is marshaled and signed, so it is covered by the vote signature.
1 parent f4a8c5f commit 536a060

3 files changed

Lines changed: 15 additions & 0 deletions

File tree

api/api_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ type Vote struct {
218218
BlockHeight uint32 `json:"blockHeight,omitempty" extensions:"x-omitempty"`
219219
TransactionIndex *int32 `json:"transactionIndex,omitempty" extensions:"x-omitempty"`
220220
OverwriteCount *uint32 `json:"overwriteCount,omitempty" extensions:"x-omitempty"`
221+
// Optional free-text note attached by the voter (max 256 bytes)
222+
Memo string `json:"memo,omitempty" extensions:"x-omitempty"`
221223
// Date when the vote was emitted
222224
Date *time.Time `json:"date,omitempty" extensions:"x-omitempty"`
223225
}

api/vote.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ func (a *API) getVoteHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) er
129129
Date: &voteData.Date,
130130
}
131131

132+
// The memo is not indexed; read it from the authoritative state if present.
133+
if sdbVote, err := a.vocapp.State.Vote(voteData.Meta.ProcessId, voteData.Meta.Nullifier, true); err == nil {
134+
vote.Memo = sdbVote.GetMemo()
135+
}
136+
132137
// If VotePackage is valid JSON, it's not encrypted, so we can include it direcectly.
133138
if json.Valid(voteData.VotePackage) {
134139
vote.VotePackage = voteData.VotePackage

apiclient/vote.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ type VoteData struct {
3939
Election *api.Election
4040
VoteWeight *big.Int
4141

42+
// Memo is an optional free-text note (max 256 bytes) attached to the vote,
43+
// e.g. an open "Other" answer. Only honored by the chain once the memo
44+
// soft-fork is active.
45+
Memo string
46+
4247
ProofMkTree *CensusProof
4348
ProofSIKTree *CensusProof
4449
ProofCSP types.HexBytes
@@ -71,6 +76,9 @@ func (cl *HTTPclient) Vote(v *VoteData) (types.HexBytes, error) {
7176
if err != nil {
7277
return nil, err
7378
}
79+
// Attach the optional memo before the envelope is wrapped, marshaled and
80+
// signed, so it is covered by the vote signature.
81+
vote.Memo = v.Memo
7482

7583
log.Debugw("generating a new vote", "electionId", v.Election.ElectionID, "voter", c.account.AddressString())
7684
voteAPI := &api.Vote{}

0 commit comments

Comments
 (0)