diff --git a/examples/gno.land/p/demo/teritori/dao_core/dao_core.gno b/examples/gno.land/p/demo/teritori/dao_core/dao_core.gno index 2466b773f11..10618e199c4 100644 --- a/examples/gno.land/p/demo/teritori/dao_core/dao_core.gno +++ b/examples/gno.land/p/demo/teritori/dao_core/dao_core.gno @@ -2,6 +2,7 @@ package core import ( "std" + "strconv" dao_interfaces "gno.land/p/demo/teritori/dao_interfaces" "gno.land/p/demo/teritori/markdown_utils" @@ -124,15 +125,20 @@ func (d *daoCore) ActiveProposalModuleCount() int { func (d *daoCore) Render(path string) string { s := "# DAO Core\n" - s += "This is an attempt at porting [DA0-DA0 contracts](https://github.com/DA0-DA0/dao-contracts)\n" - s += markdown_utils.Indent(d.votingModule.Render(path)) + "\n" - for _, propMod := range d.proposalModules { + s += "Inspired by [DA0-DA0 contracts](https://github.com/DA0-DA0/dao-contracts)\n" + votingInfo := d.votingModule.Info() + s += "## Voting Module: " + votingInfo.String() + "\n" + s += d.votingModule.Render("") + s += "## Proposal Modules:\n" + for i, propMod := range d.proposalModules { if !propMod.Enabled { continue } - s += markdown_utils.Indent(propMod.Module.Render(path)) + "\n" + info := propMod.Module.Info() + s += "### #" + strconv.Itoa(i) + ": " + info.String() + "\n" + s += propMod.Module.Render("") } - return s + return s + "\n" } func (d *daoCore) Registry() *dao_interfaces.MessagesRegistry { diff --git a/examples/gno.land/p/demo/teritori/dao_interfaces/modules.gno b/examples/gno.land/p/demo/teritori/dao_interfaces/modules.gno index 1055968f578..5c33beff252 100644 --- a/examples/gno.land/p/demo/teritori/dao_interfaces/modules.gno +++ b/examples/gno.land/p/demo/teritori/dao_interfaces/modules.gno @@ -9,6 +9,10 @@ type ModuleInfo struct { Version string } +func (mi ModuleInfo) String() string { + return mi.Kind + "@v" + mi.Version +} + // NOTE: Some queries take a height param in DA0-DA0 contracts, but since gno seem to aim to support queries at any height, we shouldn't need it type IVotingModule interface { diff --git a/examples/gno.land/p/demo/teritori/dao_proposal_single/dao_proposal_single.gno b/examples/gno.land/p/demo/teritori/dao_proposal_single/dao_proposal_single.gno index 9820c7172a3..27b846c56c7 100644 --- a/examples/gno.land/p/demo/teritori/dao_proposal_single/dao_proposal_single.gno +++ b/examples/gno.land/p/demo/teritori/dao_proposal_single/dao_proposal_single.gno @@ -149,38 +149,37 @@ func (d *DAOProposalSingle) Render(path string) string { panic("unsupported Threshold type") } - proposalsStr := "## Proposals\n" + proposalsStr := "Proposals:\n\n" for _, p := range d.proposals { messagesStr := "" for _, m := range p.Messages { - messagesStr += "- " + m.(dao_interfaces.ExecutableMessage).String() + "\n" + messagesStr += m.(dao_interfaces.ExecutableMessage).Type() + "\n\n" + messagesStr += m.(dao_interfaces.ExecutableMessage).String() + "\n\n" } - proposalsStr += "### #" + strconv.Itoa(p.ID) + " " + p.Title + "\n" + - "Status: " + p.Status.String() + "\n\n" + - "Proposed by " + p.Proposer.String() + "\n\n" + - p.Description + "\n\n" + - "Votes summary:" + "\n\n" + - "- Yes: " + strconv.FormatUint(p.Votes.Yes, 10) + "\n" + - "- No: " + strconv.FormatUint(p.Votes.No, 10) + "\n" + - "- Abstain: " + strconv.FormatUint(p.Votes.Abstain, 10) + "\n\n" + - "Total: " + strconv.FormatUint(p.Votes.Total(), 10) + "\n" + - "#### Messages\n" + + proposalsStr += "\\#" + strconv.Itoa(p.ID) + ": " + p.Title + ":\n\n" + + " Status: " + p.Status.String() + "\n\n" + + " Proposed by " + p.Proposer.String() + "\n\n" + + " " + p.Description + "\n\n" + + " Votes summary:" + "\n\n" + + " - Yes: " + strconv.FormatUint(p.Votes.Yes, 10) + "\n" + + " - No: " + strconv.FormatUint(p.Votes.No, 10) + "\n" + + " - Abstain: " + strconv.FormatUint(p.Votes.Abstain, 10) + "\n\n" + + " Total: " + strconv.FormatUint(p.Votes.Total(), 10) + "\n\n" + + " Messages:\n\n" + messagesStr + - "#### Votes\n" + " Votes:\n\n" p.Ballots.Iterate("", "", func(k string, v interface{}) bool { ballot := v.(Ballot) - proposalsStr += "- " + k + " voted " + ballot.Vote.String() + "\n" + proposalsStr += k + " voted " + ballot.String() + "\n\n" return false }) proposalsStr += "\n" } - return "# Single choice proposals module" + "\n" + - "## Summary" + "\n" + - "Max voting period: " + d.opts.MaxVotingPeriod.String() + "\n\n" + + return "Max voting period: " + d.opts.MaxVotingPeriod.String() + "\n\n" + minVotingPeriodStr + "\n\n" + executeStr + "\n\n" + revotingStr + "\n\n" + @@ -195,7 +194,7 @@ func (d *DAOProposalSingle) Core() dao_interfaces.IDAOCore { func (d *DAOProposalSingle) Info() dao_interfaces.ModuleInfo { return dao_interfaces.ModuleInfo{ - Kind: "SingleChoiceProposal", + Kind: "gno.land/p/demo/teritori/dao_proposal_single", Version: "0.1.0", } } diff --git a/examples/gno.land/p/demo/teritori/dao_proposal_single/types.gno b/examples/gno.land/p/demo/teritori/dao_proposal_single/types.gno index f292118572a..98477f5f628 100644 --- a/examples/gno.land/p/demo/teritori/dao_proposal_single/types.gno +++ b/examples/gno.land/p/demo/teritori/dao_proposal_single/types.gno @@ -25,6 +25,10 @@ func (b Ballot) ToJSON() *json.Node { }) } +func (b Ballot) String() string { + return b.Vote.String() + " with power " + strconv.FormatUint(b.Power, 10) + "" + ": " + b.Rationale +} + type Votes struct { Yes uint64 No uint64 diff --git a/examples/gno.land/p/demo/teritori/dao_voting_group/voting_group.gno b/examples/gno.land/p/demo/teritori/dao_voting_group/voting_group.gno index 2567da5ea34..20ac61af227 100644 --- a/examples/gno.land/p/demo/teritori/dao_voting_group/voting_group.gno +++ b/examples/gno.land/p/demo/teritori/dao_voting_group/voting_group.gno @@ -47,7 +47,7 @@ func NewVotingGroup() *VotingGroup { func (v *VotingGroup) Info() dao_interfaces.ModuleInfo { return dao_interfaces.ModuleInfo{ - Kind: "Group", + Kind: "gno.land/p/demo/teritori/dao_voting_group", Version: "0.1.0", } } @@ -141,11 +141,12 @@ func (g *VotingGroup) GetMembers(start, end string, limit uint64, height int64) } func (v *VotingGroup) Render(path string) string { - s := "Members: " + strconv.FormatUint(uint64(v.MemberCount(havl.Latest)), 10) + "\n" - s += "Total power: " + strconv.FormatUint(v.TotalPowerAtHeight(havl.Latest), 10) + "\n" + s := "Member count: " + strconv.FormatUint(uint64(v.MemberCount(havl.Latest)), 10) + "\n\n" + s += "Total power: " + strconv.FormatUint(v.TotalPowerAtHeight(havl.Latest), 10) + "\n\n" + s += "Members:\n" v.powerByAddr.Iterate("", "", havl.Latest, func(k string, v interface{}) bool { s += "- " + k + ": " + strconv.FormatUint(v.(uint64), 10) + "\n" return false }) - return s + return s + "\n" } diff --git a/examples/gno.land/r/demo/teritori/dao_realm/dao_realm.gno b/examples/gno.land/r/demo/teritori/dao_realm/dao_realm.gno index 1f2e64ddb6a..1d094826d03 100644 --- a/examples/gno.land/r/demo/teritori/dao_realm/dao_realm.gno +++ b/examples/gno.land/r/demo/teritori/dao_realm/dao_realm.gno @@ -68,6 +68,10 @@ func init() { daoCore = dao_core.NewDAOCore(votingModuleFactory, proposalModulesFactories, messageHandlersFactories) + id := ProposeJSON(0, `{"title": "Test prop", "description": "A description", "messages": [{"type": "gno.land/p/demo/teritori/dao_voting_group.UpdateMembers", "payload": [{"power": "2", "address": "g18syxa0vh0vmne90mwhtynjet0zgeqf6prh3ryy"}]}]}`) + VoteJSON(0, id, `{"vote": "Yes", "rationale": "testing"}`) + Execute(0, id) + // dao_registry.Register(func() dao_interfaces.IDAOCore { return daoCore }, "DAO Realm", "Default testing DAO", "https://images.unsplash.com/photo-1477959858617-67f85cf4f1df?w=1080&fit=max") }