Skip to content

Instantly share code, notes, and snippets.

@bryanchriswhite
Created June 3, 2025 18:36
Show Gist options
  • Select an option

  • Save bryanchriswhite/d72a41f24a7196263de7a3754b691e86 to your computer and use it in GitHub Desktop.

Select an option

Save bryanchriswhite/d72a41f24a7196263de7a3754b691e86 to your computer and use it in GitHub Desktop.

🧠 Cosmos SDK x/group Module Notes

πŸ“¦ What is x/group?

The group module enables on-chain governance by groups of addresses. It supports:

  • Dynamic membership (add/remove members)
  • Flexible voting policies (threshold, percentage)
  • Proposal lifecycle (submit β†’ vote β†’ execute)

Unlike multisig keys, group accounts are real on-chain entities that manage their own authorization via proposals and voting.


🧱 Setting Up a Group (Decentralized Governance)

Step 1: πŸ‘₯ Create a group with members

pocketd tx group create-group \
  --admin alice \
  --members '[{"address": "bob", "weight": "1"}, {"address": "carol", "weight": "1"}]' \
  --metadata "Core team" \
  --from alice
  • admin: the address that can update group membership.
  • weight: voting weight per member.
  • metadata: optional label (free-form string).
  • Output: group ID (e.g. 1).

Step 2: 🧾 Create a group policy (group account)

pocketd tx group create-group-policy \
  --admin alice \
  --group-id 1 \
  --metadata "2-of-3 threshold policy" \
  --decision-policy '{"@type":"/cosmos.group.v1.ThresholdDecisionPolicy","threshold":"2","windows":{"voting_period":"3600s","min_execution_period":"0s"}}' \
  --from alice
  • This creates the on-chain group account.
  • Group policy address = new account you’ll fund and use in txs.
  • decision-policy can also be "PercentageDecisionPolicy".

Step 3: πŸ’° Fund the group account

pocketd tx bank send \
  alice <group-policy-address> 1000000upokt \
  --from alice
  • Group account can now hold funds and submit txs.

πŸ“€ Submitting and Executing Proposals

Step 4: πŸ—³οΈ Submit a proposal

pocketd tx group submit-proposal \
  --group-policy-address <group-policy-address> \
  --proposers alice \
  --messages '[{"@type":"/cosmos.bank.v1beta1.MsgSend", "from_address": "<group-policy-address>", "to_address": "<recipient>", "amount":[{"denom":"upokt", "amount":"500000"}]}]' \
  --metadata "Fund dev team" \
  --from alice
  • Anyone with proposer rights can submit.
  • messages is a JSON array of embedded Cosmos messages.
  • Returns proposal_id.

Step 5: βœ… Members vote on the proposal

pocketd tx group vote \
  --proposal-id 1 \
  --voter bob \
  --option YES \
  --metadata "Looks good" \
  --from bob

Each member votes independently.

Options:

  • YES
  • NO
  • ABSTAIN
  • VETO

Step 6: πŸš€ Execute the proposal (once approved)

pocketd tx group exec \
  --proposal-id 1 \
  --executor bob \
  --from bob
  • Executes messages in the proposal.
  • Anyone can execute once voting passes and execution window opens.

πŸ”„ Updating Group Membership or Policy

Update members

pocketd tx group update-group-members \
  --group-id 1 \
  --admin alice \
  --members '[{"address": "dave", "weight": "1"}]' \
  --from alice

Update decision policy

pocketd tx group update-group-policy \
  --admin alice \
  --group-policy-address <group-policy-address> \
  --decision-policy '{"@type":"/cosmos.group.v1.ThresholdDecisionPolicy", "threshold": "3", "windows": {"voting_period": "3600s", "min_execution_period": "0s"}}' \
  --from alice

βœ… Summary Table

Step Action Who
1 Create a group with members Admin
2 Create a group policy (account + voting rules) Admin
3 Fund the group policy address Any member
4 Submit a proposal Any proposer
5 Vote on proposal Group members
6 Execute proposal Any account (after approval)
7 (Optional) Update group or policy Admin

πŸ“š Decision Policy Types

Threshold Policy

{
  "@type": "/cosmos.group.v1.ThresholdDecisionPolicy",
  "threshold": "2",
  "windows": {
    "voting_period": "3600s",
    "min_execution_period": "0s"
  }
}

Percentage Policy (e.g., 66%)

{
  "@type": "/cosmos.group.v1.PercentageDecisionPolicy",
  "percentage": "0.66",
  "windows": {
    "voting_period": "3600s",
    "min_execution_period": "0s"
  }
}

🧠 Cosmos SDK (Legacy) Multisig Account Notes

πŸ” Keyring Behavior

  • The Cosmos SDK keyring can store public keys (without private keys) using:

    • --pubkey <json> (JSON format)
    • --pubkey-base64 <base64> (raw base64)
  • This allows multisig construction without having all private keys in one place.


🧱 Setting Up a Multisig (Decentralized)

Step 1: πŸ”‘ Each signer creates their individual key

pocketd keys add alice

Step 2: πŸ“€ Each signer exports their public key

pocketd keys show alice --pubkey > alice-pub.json

Repeat for bob, carol, etc.

Step 3: πŸ“₯ Coordinator imports public keys

pocketd keys add alice --pubkey "$(cat alice-pub.json)"
pocketd keys add bob --pubkey "$(cat bob-pub.json)"
pocketd keys add carol --pubkey "$(cat carol-pub.json)"

Step 4: 🧩 Coordinator creates the multisig key

pocketd keys add multisig-escrow \
  --multisig "alice,bob,carol" \
  --multisig-threshold 2
  • This creates a 2-of-3 multisig key using the imported public keys.
  • --nosort can be used to keep the order as given.

Step 5: πŸ“¬ Share the multisig public key/address

pocketd keys show multisig-escrow --pubkey > multisig-pub.json
pocketd keys show multisig-escrow -a > multisig-address.txt

Distribute multisig-pub.json and multisig-address.txt to all signers.

Step 6 (Optional): πŸ›  Other signers import the multisig key

pocketd keys add multisig-escrow --pubkey "$(cat multisig-pub.json)"

πŸ“€ Signing and Broadcasting a Multisig Transaction

Step A: Create an unsigned transaction

pocketd tx bank send \
  multisig-escrow <recipient> <amount> \
  --generate-only > tx.json

Step B: Each signer produces a partial signature

pocketd tx sign tx.json \
  --from alice \
  --multisig multisig-escrow \
  --output-document alice-sig.json

Repeat for others (e.g. bob, carol).

Step C: Combine signatures into one

pocketd tx multisign tx.json \
  multisig-escrow \
  alice-sig.json bob-sig.json > signed-tx.json
  • Combine any M-of-N valid signatures (based on threshold).

Step D: Broadcast the transaction

pocketd tx broadcast signed-tx.json

βœ… Summary Table

Step Action Who
1 Generate individual key Each signer
2 Export public key Each signer
3 Import public keys Coordinator
4 Create multisig key Coordinator
5 Share multisig pubkey/address Coordinator
6 Import multisig key (optional) All signers
A–D Sign, combine, and broadcast Participants

πŸ”€ Multisig (LegacyAminoMultisig) vs Group Module

Feature Multisig (tx multisign) Group Module (x/group)
Key type LegacyAminoMultisig pubkey Standard on-chain module
Setup location Local/off-chain (manual setup) On-chain via governance or CLI
Execution flow Each signer signs a tx β†’ combined β†’ broadcasted Proposals created β†’ voted β†’ executed by group
Threshold Static M-of-N threshold Flexible voting policies: percentage-based, thresholds, etc.
Signer coordination Out-of-band (e.g., sharing JSON sigs) On-chain proposal lifecycle handles coordination
Account Deterministically derived from pubkeys Group account created and managed on-chain
Governance None; just threshold sig check Full proposal, voting, and execution logic
Security Simpler, but no rotation/upgrades Key management + upgradeable group membership
Use cases Lightweight shared control (e.g., shared treasury) DAO governance, smart fund management, flexible voting
CLI Support Built-in in tx commands Requires group module integration in app and CLI

πŸ” Multisig (LegacyAminoMultisig)

βœ… Pros:

  • Fully offline/local setup.
  • Simple to reason about.
  • Works with any Cosmos SDK chain that supports tx signing.

❌ Cons:

  • Signers must coordinate off-chain (manual sig collection).
  • Threshold is fixed; can’t rotate members or keys.
  • No metadata (e.g. proposals, descriptions, votes).
  • More brittle UX at scale.

πŸ§‘β€πŸ€β€πŸ§‘ Group Module (x/group)

βœ… Pros:

  • On-chain coordination (less off-band syncing).
  • Can assign different weights to members.
  • Supports proposals, voting windows, and policy changes.
  • Group membership and policy can evolve over time.
  • Built-in support for DAOs and community governance.

❌ Cons:

  • More complex to set up and manage.
  • Requires the x/group module to be enabled and configured in the app.
  • More overhead for small/simple use cases.

βš–οΈ When to Use What?

Use Case Recommended
Simple shared wallet among 2–3 people Multisig
DAO governance Group module
Treasury with evolving membership Group module
Quick multisig payment with no coordination infra Multisig
On-chain proposal lifecycle with flexibility Group module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment