Search Apps Documentation Source Content File Folder Download Copy Actions Download

utils.gno

4.50 Kb · 119 lines
  1package custom_condition
  2
  3import (
  4	"strings"
  5	"unicode"
  6
  7	"gno.land/p/mason/md"
  8	"gno.land/p/moul/txlink"
  9	"gno.land/p/nt/ufmt/v0"
 10	"gno.land/p/samcrew/basedao"
 11	"gno.land/p/samcrew/daokit"
 12)
 13
 14// initDemoProposals creates initial proposals to demonstrate custom condition functionality
 15func initDemoProposals() {
 16	demoProposals := []struct {
 17		address  string
 18		roles    []string
 19		proposer string
 20		title    string
 21		desc     string
 22	}{
 23		{
 24			"g1demomember001234567890abcdefghijklmnopqr1",
 25			[]string{},
 26			"g1demo1234567890abcdefghijklmnopqrstuvwxy2",
 27			"Add Alice as member with no role",
 28			"This proposal will add Alice to our DAO without roles.",
 29		},
 30		{
 31			"g1demomember001234567890abcdefghijklmnopqr2",
 32			[]string{"Role"},
 33			"g1demo1234567890abcdefghijklmnopqrstuvwxy3",
 34			"Add Bob as member with Role",
 35			"This proposal will add Bob to our DAO with the 'Role' role.",
 36		},
 37		{
 38			"g1demomember001234567890abcdefghijklmnopqr3",
 39			[]string{},
 40			"g1demo1234567890abcdefghijklmnopqrstuvwxy2",
 41			"Add Charlie as member with no role",
 42			"This proposal will add Charlie to our DAO without roles.",
 43		},
 44	}
 45
 46	for _, prop := range demoProposals {
 47		action := basedao.NewAddMemberAction(&basedao.ActionAddMember{
 48			Address: address(prop.address),
 49			Roles:   prop.roles,
 50		})
 51
 52		req := daokit.ProposalRequest{
 53			Title:       prop.title,
 54			Description: prop.desc,
 55			Action:      action,
 56		}
 57		daoPrivate.Core.Propose(prop.proposer, req)
 58	}
 59}
 60
 61// Bypass limitation by adding yourself to the DAO.
 62// It is necessary to be part of the DAO to create a Proposal.
 63func AddMember(cur realm) {
 64	id := daoPrivate.CallerID()
 65	daoPrivate.Members.AddMember(id, make([]string, 0))
 66}
 67
 68// Creates a Proposal to add a new member to the DAO with specified roles.
 69// This function exist to let users try the userflow of daokit with a simple MsgCall (maketx call) instead of a MsgRun.
 70// See why a run is necessary for creating a proposal -> https://docs.gno.land/users/interact-with-gnokey#run.
 71// Parameters:
 72//   - address: The std.Address of the member to be added
 73//   - roles: Comma-separated string of roles to assign to the member (e.g., "admin,moderator" or "voter")
 74func ProposeAddMember(cur realm, address address, roles string) {
 75	rs := strings.Split(roles, ",")
 76	for i, s := range rs {
 77		rs[i] = strings.TrimFunc(s, unicode.IsSpace)
 78	}
 79
 80	payload := basedao.ActionAddMember{
 81		Address: address,
 82		Roles:   rs,
 83	}
 84	action := basedao.NewAddMemberAction(&payload)
 85
 86	proposal := daokit.ProposalRequest{
 87		Title:       ufmt.Sprintf("Add member %s with roles %s", address, strings.Join(rs, ", ")),
 88		Description: ufmt.Sprintf("This proposal will add %s as a member with roles: %s", address, strings.Join(rs, ", ")),
 89		Action:      action,
 90	}
 91
 92	Propose(cur, proposal)
 93}
 94
 95func renderDemo() string {
 96	s := ""
 97	s += "# ⚙️ Custom Condition Demo\n\n"
 98	s += "This showcases how to create custom governance rules.\n\n"
 99	s += "## ℹ️ How it Works\n\n"
100	s += "1. **Join the DAO** using the " + md.Link("AddMember", txlink.Call("AddMember")) + " function.\n\n"
101	s += "2. **Create a Proposal** using " + md.Link("ProposeAddMember", txlink.Call("ProposeAddMember")) + " function with these parameters:\n\n"
102	s += "- `address`: The address of the member to add\n"
103	s += "- `roles`: Comma-separated roles (e.g., \"Role\")\n\n"
104	s += "3. " + md.Link("Vote", txlink.Call("Vote")) + " on proposals using their ID.\n\n"
105	s += "4. " + md.Link("Execute", txlink.Call("Execute")) + " proposals that have passed (met the required voting conditions).\n\n"
106	s += "   📝 **Note**: Only proposals that have met the governance conditions can be executed. You need at least 1 vote from members with no roles to execute a proposal.\n\n"
107	s += "## 🎯 Custom Condition: NoRole\n\n"
108	s += "This DAO uses a initial custom condition called **NoRole** that requires:\n"
109	s += "- At least **1 vote** from members who have **no assigned roles**\n"
110	s += "## 📋 Available Actions\n\n"
111	s += "### Member Management\n"
112	s += "- " + md.Link("🔗 Add Yourself as Member", txlink.Call("AddMember")) + " - Join the DAO to participate in governance\n"
113	s += "- " + md.Link("🔗 Propose Add Member", txlink.Call("ProposeAddMember")) + " - Create a proposal to add a new member with specific roles\n\n"
114	s += "### Other Demos\n"
115	s += "- " + md.Link("🔗 Simple DAO Demo", "/r/samcrew/daodemo/simple_dao") + " - Basic DAO functionality\n"
116	s += "- " + md.Link("🔗 Custom Resource Demo", "/r/samcrew/daodemo/custom_resource") + " - Custom DAO actions\n\n"
117	s += "*This is a demonstration DAO built with gno.land and daokit*"
118	return s
119}