Skip to content

feat: add vote and proposal part builders - #857

Merged
twwu123 merged 2 commits into
feat/tx-parts-certificatesfrom
feat/tx-parts-governance
Oct 30, 2026
Merged

twwu123 merged 2 commits into
feat/tx-parts-certificatesfrom
feat/tx-parts-governance

Conversation

@lisicky

@lisicky lisicky commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

What

Adds part builders for votes and governance proposals. With these, every part of a Conway transaction has a builder.

Stacked on #856. Merge it first; this PR can then be retargeted to main. Still in packages/mesh-transaction/src/tx-builder/, not exported from the package root.

Contents

packages/mesh-transaction/src/tx-builder/parts/governance.ts:

  • vote({ voter, votes, witness? }): all of one voter's votes in one part, since the ledger runs a voter's script, and takes its redeemer, once for all of them.
    • The voter is { drep } (CIP-105/129 id or credential), { committee } (hot credential, or a reward address carrying it) or { pool } (bech32 id or key hash).
    • Each vote is { action: { txHash, index }, vote: "yes" | "no" | "abstain", anchor? }. An action may be voted on once per part.
    • Witnesses: pools vote with their key, and a script witness for a pool is rejected. Script DReps and committee members need a witness, Plutus V3 only.
  • proposal.* for the seven governance actions:
    • parameterChange, hardForkInitiation, treasuryWithdrawals, noConfidence, updateCommittee, newConstitution, info.
    • Common arguments: rewardAccount (where the deposit is returned), anchor and deposit. When deposit is omitted it is left to the govActionDeposit protocol parameter and reported by unresolved.
    • previous links an action to the last enacted one of the same purpose.
    • Guardrail. parameterChange and treasuryWithdrawals take an optional guardrail script, native or Plutus V3. Its hash becomes the action's policy hash and it witnesses the proposal. A guardrail referenced by out ref alone needs policyHash, and a policy hash without its guardrail is rejected.
    • Parameter updates are given in the ledger's shape and checked field by field: non-negative integers, signed cost model entries, ratios with a non-zero denominator. An empty update is rejected.
    • updateCommittee checks term limits and that the quorum is at most 1.
    • Order. Proposals keep the order their parts are given in.
  • Shared credential helpers. The helpers for stake, DRep and committee credentials, pools, anchors, deposits and credential witnesses move from certificates.ts to credentials.ts, shared by certificates and governance parts. DepositParameter now also covers govActionDeposit.

Validation

npm run build:mesh
cd packages/mesh-transaction && npx jest test/tx-builder
  • 13 new tests:
    • each voter kind;
    • witness and Plutus V3 rules;
    • deposit gaps;
    • guardrails and policy hashes;
    • malformed votes, updates, quorums, versions and addresses.
  • Round trip: votes and every proposal kind are encoded with transactionPrototypeToHex and decoded with transactionPrototypeFromHex. The exception is the parameter change, which the decoder deliberately does not decode, so it is checked for encoding only.
  • Full mesh-transaction suite (NODE_OPTIONS=--experimental-vm-modules npx jest): 237 tests pass. script-tx-fetcher and script-tx-fail fail to load under that flag on main too.

@twwu123
twwu123 merged commit 82cc3da into main Oct 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants