From 0665e49b42443765a5ca35b6ab2a65c8d7d7dab9 Mon Sep 17 00:00:00 2001 From: etiti Date: Fri, 20 Feb 2026 09:27:03 +0300 Subject: [PATCH 1/5] feat: add governance voting messages and fields to the Cardano transaction proto definition. --- proto/utxorpc/v1alpha/cardano/cardano.proto | 36 +++++++++++++++++++++ proto/utxorpc/v1beta/cardano/cardano.proto | 36 +++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/proto/utxorpc/v1alpha/cardano/cardano.proto b/proto/utxorpc/v1alpha/cardano/cardano.proto index d4cc256..47fbb2f 100644 --- a/proto/utxorpc/v1alpha/cardano/cardano.proto +++ b/proto/utxorpc/v1alpha/cardano/cardano.proto @@ -110,6 +110,7 @@ message Tx { AuxData auxiliary = 12; // Auxiliary data not directly tied to the validation process bytes hash = 13; // Hash of the transaction that serves as main identifier repeated GovernanceActionProposal proposals = 14; // List of governance actions proposed + repeated VoterVotes votes = 15; // List of voters and their corresponding votes cast in this transaction } // Define a governance action proposal @@ -140,6 +141,41 @@ message GovernanceActionId { uint32 governance_action_index = 2; } +// Role of the voter in Cardano governance (CIP-1694) +enum VoterRole { + VOTER_ROLE_UNSPECIFIED = 0; + VOTER_ROLE_DREP = 1; // Delegated Representative + VOTER_ROLE_SPO = 2; // Stake Pool Operator + VOTER_ROLE_CONSTITUTIONAL_COMMITTEE = 3; // Constitutional Committee Member +} + +// Valid vote choices for a governance action +enum Vote { + VOTE_UNSPECIFIED = 0; + VOTE_YES = 1; // Vote in favor + VOTE_NO = 2; // Vote against + VOTE_ABSTAIN = 3; // Abstain from voting +} + +// Defines a voter by mapping their role to their specific credential +message Voter { + VoterRole role = 1; // The role assumed by the voter + StakeCredential credential = 2; // Credential (Key Hash or Script Hash) identifying the voter +} + +// A single cast vote, linking a specific governance action to the vote and an optional anchor +message VotingProcedure { + GovernanceActionId gov_action_id = 1; // ID (tx_hash + index) of the action being voted on + Vote vote = 2; // The choice selected (Yes, No, Abstain) + Anchor anchor = 3; // Optional anchor supplying context/justification +} + +// Wrapper aggregating all votes cast by a single voter in the transaction +message VoterVotes { + Voter voter = 1; // The entity casting the votes + repeated VotingProcedure votes = 2; // The list of voting procedures submitted by this voter +} + message ParameterChangeAction { GovernanceActionId gov_action_id = 1; PParams protocol_param_update = 2; // The updates proposed diff --git a/proto/utxorpc/v1beta/cardano/cardano.proto b/proto/utxorpc/v1beta/cardano/cardano.proto index 05c6a80..9b94adb 100644 --- a/proto/utxorpc/v1beta/cardano/cardano.proto +++ b/proto/utxorpc/v1beta/cardano/cardano.proto @@ -108,6 +108,7 @@ message Tx { AuxData auxiliary = 12; // Auxiliary data not directly tied to the validation process bytes hash = 13; // Hash of the transaction that serves as main identifier repeated GovernanceActionProposal proposals = 14; // List of governance actions proposed + repeated VoterVotes votes = 15; // List of voters and their corresponding votes cast in this transaction } // Define a governance action proposal @@ -136,6 +137,41 @@ message GovernanceActionId { uint32 governance_action_index = 2; } +// Role of the voter in Cardano governance (CIP-1694) +enum VoterRole { + VOTER_ROLE_UNSPECIFIED = 0; + VOTER_ROLE_DREP = 1; // Delegated Representative + VOTER_ROLE_SPO = 2; // Stake Pool Operator + VOTER_ROLE_CONSTITUTIONAL_COMMITTEE = 3; // Constitutional Committee Member +} + +// Valid vote choices for a governance action +enum Vote { + VOTE_UNSPECIFIED = 0; + VOTE_YES = 1; // Vote in favor + VOTE_NO = 2; // Vote against + VOTE_ABSTAIN = 3; // Abstain from voting +} + +// Defines a voter by mapping their role to their specific credential +message Voter { + VoterRole role = 1; // The role assumed by the voter + StakeCredential credential = 2; // Credential (Key Hash or Script Hash) identifying the voter +} + +// A single cast vote, linking a specific governance action to the vote and an optional anchor +message VotingProcedure { + GovernanceActionId gov_action_id = 1; // ID (tx_hash + index) of the action being voted on + Vote vote = 2; // The choice selected (Yes, No, Abstain) + Anchor anchor = 3; // Optional anchor supplying context/justification +} + +// Wrapper aggregating all votes cast by a single voter in the transaction +message VoterVotes { + Voter voter = 1; // The entity casting the votes + repeated VotingProcedure votes = 2; // The list of voting procedures submitted by this voter +} + message ParameterChangeAction { GovernanceActionId gov_action_id = 1; PParams protocol_param_update = 2; // The updates proposed From 0afe2583b380f0bb1a56b24c16335383c1be8d1c Mon Sep 17 00:00:00 2001 From: "Tyty.Emmanuel" <90614879+Emmanuel-Tyty@users.noreply.github.com> Date: Mon, 2 Mar 2026 18:19:46 +0300 Subject: [PATCH 2/5] Apply suggestion from @carbolymer Co-authored-by: Mateusz Galazyn <228866+carbolymer@users.noreply.github.com> --- proto/utxorpc/v1alpha/cardano/cardano.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/utxorpc/v1alpha/cardano/cardano.proto b/proto/utxorpc/v1alpha/cardano/cardano.proto index 47fbb2f..bedcd4e 100644 --- a/proto/utxorpc/v1alpha/cardano/cardano.proto +++ b/proto/utxorpc/v1alpha/cardano/cardano.proto @@ -167,7 +167,7 @@ message Voter { message VotingProcedure { GovernanceActionId gov_action_id = 1; // ID (tx_hash + index) of the action being voted on Vote vote = 2; // The choice selected (Yes, No, Abstain) - Anchor anchor = 3; // Optional anchor supplying context/justification + optional Anchor anchor = 3; // Optional anchor supplying context/justification } // Wrapper aggregating all votes cast by a single voter in the transaction From 56bd1d804d288c5ffb24a3b4d60394a28cff92bf Mon Sep 17 00:00:00 2001 From: "Tyty.Emmanuel" <90614879+Emmanuel-Tyty@users.noreply.github.com> Date: Mon, 2 Mar 2026 18:19:58 +0300 Subject: [PATCH 3/5] Apply suggestion from @carbolymer Co-authored-by: Mateusz Galazyn <228866+carbolymer@users.noreply.github.com> --- proto/utxorpc/v1beta/cardano/cardano.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/utxorpc/v1beta/cardano/cardano.proto b/proto/utxorpc/v1beta/cardano/cardano.proto index 9b94adb..1d0dcb9 100644 --- a/proto/utxorpc/v1beta/cardano/cardano.proto +++ b/proto/utxorpc/v1beta/cardano/cardano.proto @@ -163,7 +163,7 @@ message Voter { message VotingProcedure { GovernanceActionId gov_action_id = 1; // ID (tx_hash + index) of the action being voted on Vote vote = 2; // The choice selected (Yes, No, Abstain) - Anchor anchor = 3; // Optional anchor supplying context/justification + optional Anchor anchor = 3; // Optional anchor supplying context/justification } // Wrapper aggregating all votes cast by a single voter in the transaction From 974007bb594840c9e3c55d5bce349a5f44a92242 Mon Sep 17 00:00:00 2001 From: etiti Date: Mon, 2 Mar 2026 22:51:20 +0300 Subject: [PATCH 4/5] chore: cleanup v1alpha changes --- proto/utxorpc/v1alpha/cardano/cardano.proto | 36 --------------------- 1 file changed, 36 deletions(-) diff --git a/proto/utxorpc/v1alpha/cardano/cardano.proto b/proto/utxorpc/v1alpha/cardano/cardano.proto index bedcd4e..d4cc256 100644 --- a/proto/utxorpc/v1alpha/cardano/cardano.proto +++ b/proto/utxorpc/v1alpha/cardano/cardano.proto @@ -110,7 +110,6 @@ message Tx { AuxData auxiliary = 12; // Auxiliary data not directly tied to the validation process bytes hash = 13; // Hash of the transaction that serves as main identifier repeated GovernanceActionProposal proposals = 14; // List of governance actions proposed - repeated VoterVotes votes = 15; // List of voters and their corresponding votes cast in this transaction } // Define a governance action proposal @@ -141,41 +140,6 @@ message GovernanceActionId { uint32 governance_action_index = 2; } -// Role of the voter in Cardano governance (CIP-1694) -enum VoterRole { - VOTER_ROLE_UNSPECIFIED = 0; - VOTER_ROLE_DREP = 1; // Delegated Representative - VOTER_ROLE_SPO = 2; // Stake Pool Operator - VOTER_ROLE_CONSTITUTIONAL_COMMITTEE = 3; // Constitutional Committee Member -} - -// Valid vote choices for a governance action -enum Vote { - VOTE_UNSPECIFIED = 0; - VOTE_YES = 1; // Vote in favor - VOTE_NO = 2; // Vote against - VOTE_ABSTAIN = 3; // Abstain from voting -} - -// Defines a voter by mapping their role to their specific credential -message Voter { - VoterRole role = 1; // The role assumed by the voter - StakeCredential credential = 2; // Credential (Key Hash or Script Hash) identifying the voter -} - -// A single cast vote, linking a specific governance action to the vote and an optional anchor -message VotingProcedure { - GovernanceActionId gov_action_id = 1; // ID (tx_hash + index) of the action being voted on - Vote vote = 2; // The choice selected (Yes, No, Abstain) - optional Anchor anchor = 3; // Optional anchor supplying context/justification -} - -// Wrapper aggregating all votes cast by a single voter in the transaction -message VoterVotes { - Voter voter = 1; // The entity casting the votes - repeated VotingProcedure votes = 2; // The list of voting procedures submitted by this voter -} - message ParameterChangeAction { GovernanceActionId gov_action_id = 1; PParams protocol_param_update = 2; // The updates proposed From ab10689a97ab1f2f15c4ed4c70de7853e2618015 Mon Sep 17 00:00:00 2001 From: etiti Date: Mon, 2 Mar 2026 22:57:57 +0300 Subject: [PATCH 5/5] feat(cardano): restructure voting procedures for Conway governance (CIP-1694) --- proto/utxorpc/v1beta/cardano/cardano.proto | 42 +++++++++------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/proto/utxorpc/v1beta/cardano/cardano.proto b/proto/utxorpc/v1beta/cardano/cardano.proto index 1d0dcb9..24e54fa 100644 --- a/proto/utxorpc/v1beta/cardano/cardano.proto +++ b/proto/utxorpc/v1beta/cardano/cardano.proto @@ -137,39 +137,31 @@ message GovernanceActionId { uint32 governance_action_index = 2; } -// Role of the voter in Cardano governance (CIP-1694) -enum VoterRole { - VOTER_ROLE_UNSPECIFIED = 0; - VOTER_ROLE_DREP = 1; // Delegated Representative - VOTER_ROLE_SPO = 2; // Stake Pool Operator - VOTER_ROLE_CONSTITUTIONAL_COMMITTEE = 3; // Constitutional Committee Member -} - -// Valid vote choices for a governance action +// Valid vote choices for a governance action (CIP-1694). +// On-chain CBOR mapping: No=0, Yes=1, Abstain=2. enum Vote { VOTE_UNSPECIFIED = 0; - VOTE_YES = 1; // Vote in favor - VOTE_NO = 2; // Vote against - VOTE_ABSTAIN = 3; // Abstain from voting + VOTE_NO = 1; + VOTE_YES = 2; + VOTE_ABSTAIN = 3; } -// Defines a voter by mapping their role to their specific credential -message Voter { - VoterRole role = 1; // The role assumed by the voter - StakeCredential credential = 2; // Credential (Key Hash or Script Hash) identifying the voter -} - -// A single cast vote, linking a specific governance action to the vote and an optional anchor +// A single cast vote on a governance action. message VotingProcedure { - GovernanceActionId gov_action_id = 1; // ID (tx_hash + index) of the action being voted on - Vote vote = 2; // The choice selected (Yes, No, Abstain) - optional Anchor anchor = 3; // Optional anchor supplying context/justification + GovernanceActionId gov_action_id = 1; // ID of the governance action being voted on. + Vote vote = 2; // The vote cast. + optional Anchor anchor = 3; // Optional anchor for voter rationale. } -// Wrapper aggregating all votes cast by a single voter in the transaction +// Groups a voter with all votes they cast in the transaction. +// SPOs can only identify via pool key hash; DReps and CC members may use key or script hash. message VoterVotes { - Voter voter = 1; // The entity casting the votes - repeated VotingProcedure votes = 2; // The list of voting procedures submitted by this voter + oneof voter { + StakeCredential constitutional_committee = 1; // Constitutional Committee member. + StakeCredential drep = 2; // Delegated Representative. + bytes spo = 3; // Stake Pool Operator (pool key hash). + } + repeated VotingProcedure votes = 4; // Votes cast by this voter. } message ParameterChangeAction {