-
Notifications
You must be signed in to change notification settings - Fork 398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: DAO SDK #1925
Closed
Closed
feat: DAO SDK #1925
Changes from all commits
Commits
Show all changes
121 commits
Select commit
Hold shift + click to select a range
f677f1c
feat: DA0-DA0 port
135287a
feat: social feed and moderation dao by @hthieu1110
6cc1280
chore: remove duplicates and unversion packages
ce2465a
chore: reset gnovm changes
d375b61
fix: make social feed and moderation work with latest dao packages
d8800be
chore: move daodao contracts under teritori dir
0fa396f
chore: move ujson under teritori dir
86d4fcc
chore: move binutils under teritori dir
fd7a5b3
chore: move flags_index under teritori dir
9c89420
chore: move havl under teritori dir
06d722f
chore: move markdown_utils under teritori dir
f9f376d
chore: move utf16 under teritori dir
3532d57
chore: update modboards golden test
380f7e7
chore: move dao_realm under teritori dir
3d12ce1
chore: move dao_registry under teritori dir
6a8e185
chore: fork groups into teritori dir
6ba2ba2
chore: move modboards under teritori dir
3ab1751
chore: move social_feeds under teritori dir
13b1337
chore: move social_feeds_dao under teritori dir
b416f44
chore: move tori under teritori dir
f320770
chore: update modboards golden test
85302e4
chore: reset gnovm changes
69dd461
chore: reset .gitignore changes
507039d
feat: escrow contract by @go7066
5a77310
chore: move escrow under teritori dir
0c01047
feat: cosmos-style voting DAO by @go7066
9e826d7
chore: move gnodaos under teritori dir
911d788
chore: add disclaimer in gnodaos
ea09b63
feat: justicedao and vrf by @go7066
225aa19
chore: move justicedao and vrf under teritori dir
93ac190
chore: disable test targeting test3 avl
34d62bb
chore: move daodao contracts at teritori root
f5f82eb
chore: add teritori contracts overview
94e02fd
feat: abstract modules config query
28fd066
fix: add missing imports in gno.mods
66ad360
feat: add tutorial to create a DAO
a73db3d
chore: clean dao core
10345cd
chore: add moderation DAO documentation
54f55a2
feat(ujson): add union support
12692b4
chore: use ujson union
97ac41f
feat: add voting durations
f0a1b10
chore: clearer error messages
0281ad3
fix: pass examples CI tests
2d7a15d
feat: check expiration in vote procedure
5c227f7
chore: typo in doc
29bdb6d
chore: fmt
c2a5707
feat: add social follow system (#15)
omarsy 9cce73e
chore: tidy utf16
n0izn0iz f1fdc46
chore: clean ujson
n0izn0iz 91c8303
chore: clean flags_index
n0izn0iz eef83fe
chore: clean dao_interfaces
n0izn0iz af10b75
chore: clean social_feeds
n0izn0iz 1a729f2
chore: clean havl
n0izn0iz 98631b5
chore: clean havl groups
n0izn0iz f3ed282
chore: clean markdown_utils
n0izn0iz 397d156
chore: clean dao_core
n0izn0iz d92a828
chore: clean dao_utils
n0izn0iz 76d7200
chore: clean dao_proposal_single
n0izn0iz 6f67bef
chore: clean dao_voting_group
n0izn0iz f22248d
chore: clean dao_registry
n0izn0iz 3b9983e
fix: disable broken registry in dao
n0izn0iz 9e37291
chore: clean modboard
n0izn0iz 215068d
chore: clean tori
n0izn0iz 3915cb3
chore: clean dao_realm
n0izn0iz 19e50eb
chore: clean escrow package
n0izn0iz dc1474c
chore: rename escrow -> projects_manager
n0izn0iz 852a499
chore: remove vrf and justicedao
n0izn0iz eaf6792
chore: remove unused package
n0izn0iz 2157ff3
chore: remove unrelated packages
n0izn0iz 5a1307e
chore: update golden tests
n0izn0iz 865c6d3
chore: fmt imports
n0izn0iz 4dc53b5
chore: remove duplicate utf16
n0izn0iz b35749e
chore: replace ujson with official json
n0izn0iz 6195695
chore: remove moderation stuff
n0izn0iz af3a8ef
feat: improve render
n0izn0iz c471f46
chore: remove markdown_utils
n0izn0iz 70b461e
feat: render supported messages
n0izn0iz 2629c68
fix: pass gno2go check
n0izn0iz 27e4829
fix: update test
n0izn0iz 9235af4
chore: remove obsolete comment
n0izn0iz 1f0f2b6
chore: move docs
n0izn0iz d88b16d
Merge remote-tracking branch 'teritori/master' into daosdk
n0izn0iz 67126bf
chore: improve docs
n0izn0iz 346ca7a
chore: remove default proposal in exemple
n0izn0iz 73f84dc
chore: precise todo
n0izn0iz b5a5150
chore: remove leftovers
n0izn0iz ef96580
feat: allow to change tori admin
n0izn0iz 893907c
chore: remove obsolete comment
n0izn0iz 1555f35
feat: improve dao doc
n0izn0iz 7d4e448
Merge branch 'master' into daosdk
n0izn0iz a6689df
chore: fix test
n0izn0iz 165c1a6
chore: use strings.Builder instead of concatenation
n0izn0iz 05433bd
chore: update doc
n0izn0iz 2fd99f5
Merge branch 'master' into daosdk
n0izn0iz 3501f28
Merge branch 'master' into daosdk
n0izn0iz d7cdd9c
Merge branch 'master' into daosdk
n0izn0iz c1c4d97
Merge branch 'master' into daosdk
n0izn0iz f863190
Merge remote-tracking branch 'origin/master' into daosdk
n0izn0iz a3251f1
chore: add space after blocks
n0izn0iz e701f83
chore: improve doc
n0izn0iz 66a4854
chore: improve docs
n0izn0iz 5eaf156
chore: improve docs
n0izn0iz f51719c
chore: better comment
n0izn0iz 7956e63
chore: rename teritori -> dao-maker
n0izn0iz 9c4463d
Merge remote-tracking branch 'origin/master' into daosdk
n0izn0iz 00b499f
chore: mod tidy
n0izn0iz 58a8385
chore: rename dao-maker -> dao_maker because - is not supported in re…
n0izn0iz 1b78823
Merge branch 'master' into daosdk
n0izn0iz f4f54a2
Merge branch 'master' into daosdk
n0izn0iz db663c7
chore: update docs
n0izn0iz 63e3de2
chore: update docs
n0izn0iz 6834121
feat: add update to dao_interfaces
MikaelVallenet af91c7f
Merge branch 'master' into daosdk
n0izn0iz 2ca5706
chore: move everything under teritori namespace
n0izn0iz b690ec0
fix: remove require and tidy
n0izn0iz 508e831
chore: gno fmt
n0izn0iz 58c1011
chore: update tori with new grc20 apis
n0izn0iz 98afc2f
chore: update usage after interface change
n0izn0iz 1e87380
Merge branch 'master' into daosdk
n0izn0iz 648a09d
fix: gnoweb UI styles (#3349)
alexiscolin 252b21a
Merge remote-tracking branch 'origin/master' into daosdk
n0izn0iz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,58 @@ | ||
package users | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestAddressOrNameValidation(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
address string | ||
expected bool | ||
}{ | ||
{ | ||
name: "Valid address", | ||
address: "g18syxa0vh0vmne90mwhtynjet0zgeqf6prh3ryy", | ||
expected: true, | ||
}, | ||
{ | ||
name: "Invalid address", | ||
address: "0x123456789012345678901234567890123456789", | ||
expected: false, | ||
}, | ||
{ | ||
name: "Valid name", | ||
address: "@test", | ||
expected: true, | ||
}, | ||
{ | ||
name: "Invalid name", | ||
address: "test@", | ||
expected: false, | ||
}, | ||
{ | ||
name: "Empty", | ||
address: "", | ||
expected: false, | ||
}, | ||
{ | ||
name: "Only @", | ||
address: "@", | ||
expected: false, | ||
}, | ||
{ | ||
name: "One letter", | ||
address: "@a", | ||
expected: true, | ||
}, | ||
} | ||
|
||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
result := AddressOrName(test.address).IsValid() | ||
if result != test.expected { | ||
t.Errorf("Expected %v, got %v", test.expected, result) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
package core | ||
|
||
import ( | ||
"std" | ||
"strconv" | ||
"strings" | ||
|
||
dao_interfaces "gno.land/p/teritori/dao_interfaces" | ||
) | ||
|
||
// TODO: add wrapper message handler to handle multiple proposal modules messages | ||
|
||
type daoCore struct { | ||
dao_interfaces.IDAOCore | ||
|
||
votingModule dao_interfaces.IVotingModule | ||
proposalModules []dao_interfaces.ActivableProposalModule | ||
activeProposalModuleCount int | ||
realm std.Realm | ||
registry *dao_interfaces.MessagesRegistry | ||
} | ||
|
||
func NewDAOCore( | ||
votingModuleFactory dao_interfaces.VotingModuleFactory, | ||
proposalModulesFactories []dao_interfaces.ProposalModuleFactory, | ||
messageHandlersFactories []dao_interfaces.MessageHandlerFactory, | ||
) dao_interfaces.IDAOCore { | ||
if votingModuleFactory == nil { | ||
panic("Missing voting module factory") | ||
} | ||
|
||
if len(proposalModulesFactories) == 0 { | ||
panic("No proposal modules factories") | ||
} | ||
|
||
core := &daoCore{ | ||
realm: std.CurrentRealm(), | ||
activeProposalModuleCount: len(proposalModulesFactories), | ||
registry: dao_interfaces.NewMessagesRegistry(), | ||
proposalModules: make([]dao_interfaces.ActivableProposalModule, len(proposalModulesFactories)), | ||
} | ||
|
||
core.votingModule = votingModuleFactory(core) | ||
if core.votingModule == nil { | ||
panic("voting module factory returned nil") | ||
} | ||
|
||
for i, modFactory := range proposalModulesFactories { | ||
mod := modFactory(core) | ||
if mod == nil { | ||
panic("proposal module factory returned nil") | ||
} | ||
|
||
core.proposalModules[i] = dao_interfaces.ActivableProposalModule{ | ||
Enabled: true, | ||
Module: mod, | ||
} | ||
} | ||
|
||
// this registry is specific to gno since we can't do dynamic calls | ||
core.registry.Register(NewUpdateVotingModuleMessageHandler(core)) | ||
core.registry.Register(NewUpdateProposalModulesMessageHandler(core)) | ||
for _, handlerFactory := range messageHandlersFactories { | ||
handler := handlerFactory(core) | ||
if handler == nil { | ||
panic("message handler factory returned nil") | ||
} | ||
|
||
core.registry.Register(handler) | ||
} | ||
|
||
return core | ||
} | ||
|
||
// mutations | ||
|
||
func (d *daoCore) UpdateVotingModule(newVotingModule dao_interfaces.IVotingModule) { | ||
if std.CurrentRealm().Addr() != d.realm.Addr() { // not sure this check necessary since the ownership system should protect against mutation from other realms | ||
panic(ErrUnauthorized) | ||
} | ||
|
||
d.votingModule = newVotingModule | ||
} | ||
|
||
func (d *daoCore) UpdateProposalModules(toAdd []dao_interfaces.IProposalModule, toDisable []int) { | ||
if std.CurrentRealm().Addr() != d.realm.Addr() { // not sure this check necessary since the ownership system should protect against mutation from other realms | ||
panic(ErrUnauthorized) | ||
} | ||
|
||
for _, module := range toAdd { | ||
d.addProposalModule(module) | ||
} | ||
|
||
for _, moduleIndex := range toDisable { | ||
module := GetProposalModule(d, moduleIndex) | ||
|
||
if !module.Enabled { | ||
panic(ErrModuleAlreadyDisabled) | ||
} | ||
|
||
module.Enabled = false | ||
|
||
d.activeProposalModuleCount-- | ||
if d.activeProposalModuleCount == 0 { | ||
panic("no active proposal modules") // this -> `panic(ErrNoActiveProposalModules)` triggers `panic: reflect: reflect.Value.SetString using value obtained using unexported field` | ||
} | ||
} | ||
} | ||
|
||
// queries | ||
|
||
func (d *daoCore) ProposalModules() []dao_interfaces.ActivableProposalModule { | ||
return d.proposalModules | ||
} | ||
|
||
func (d *daoCore) VotingModule() dao_interfaces.IVotingModule { | ||
return d.votingModule | ||
} | ||
|
||
func (d *daoCore) VotingPowerAtHeight(address std.Address, height int64) uint64 { | ||
return d.VotingModule().VotingPowerAtHeight(address, height, []string{}) | ||
} | ||
|
||
func (d *daoCore) ActiveProposalModuleCount() int { | ||
return d.activeProposalModuleCount | ||
} | ||
|
||
func (d *daoCore) Render(path string) string { | ||
sb := strings.Builder{} | ||
sb.WriteString("# DAO Core\n") | ||
votingInfo := d.votingModule.Info() | ||
sb.WriteString("## Voting Module: ") | ||
sb.WriteString(votingInfo.String()) | ||
sb.WriteRune('\n') | ||
sb.WriteString(d.votingModule.Render("")) | ||
sb.WriteString("## Supported Messages:\n") | ||
sb.WriteString(d.registry.Render()) | ||
|
||
sb.WriteString("## Proposal Modules:\n") | ||
for i, propMod := range d.proposalModules { | ||
if !propMod.Enabled { | ||
continue | ||
} | ||
|
||
info := propMod.Module.Info() | ||
sb.WriteString("### #") | ||
sb.WriteString(strconv.Itoa(i)) | ||
sb.WriteString(": ") | ||
sb.WriteString(info.String()) | ||
sb.WriteRune('\n') | ||
sb.WriteString(propMod.Module.Render("")) | ||
} | ||
|
||
sb.WriteRune('\n') | ||
return sb.String() | ||
} | ||
|
||
func (d *daoCore) Registry() *dao_interfaces.MessagesRegistry { | ||
return d.registry | ||
} | ||
|
||
// TODO: move this helper in dao interfaces | ||
|
||
func GetProposalModule(core dao_interfaces.IDAOCore, moduleIndex int) *dao_interfaces.ActivableProposalModule { | ||
if moduleIndex < 0 { | ||
panic("module index must be >= 0") | ||
} | ||
|
||
mods := core.ProposalModules() | ||
if moduleIndex >= len(mods) { | ||
panic("invalid module index") | ||
} | ||
|
||
return &mods[moduleIndex] | ||
} | ||
|
||
// internal | ||
|
||
func (d *daoCore) executeMsgs(msgs []dao_interfaces.ExecutableMessage) { | ||
for _, msg := range msgs { | ||
d.registry.Execute(msg) | ||
} | ||
} | ||
|
||
func (d *daoCore) addProposalModule(proposalMod dao_interfaces.IProposalModule) { | ||
for _, mod := range d.proposalModules { | ||
if mod.Module != proposalMod { | ||
continue | ||
} | ||
|
||
if mod.Enabled { | ||
panic(ErrModuleAlreadyAdded) | ||
} | ||
|
||
mod.Enabled = true | ||
d.activeProposalModuleCount++ | ||
return | ||
} | ||
|
||
d.proposalModules = append(d.proposalModules, dao_interfaces.ActivableProposalModule{ | ||
Enabled: true, | ||
Module: proposalMod, | ||
}) | ||
|
||
d.activeProposalModuleCount++ | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about using
users.Resolve(aon).IsValid()
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't call the realm method
users.Resolve
from ap
package