-
Notifications
You must be signed in to change notification settings - Fork 387
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: social feed and moderation dao by @hthieu1110
- Loading branch information
Showing
59 changed files
with
6,462 additions
and
2 deletions.
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 |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package binutils | ||
|
||
import ( | ||
"encoding/binary" | ||
"errors" | ||
) | ||
|
||
var ErrInvalidLengthPrefixedString = errors.New("invalid length-prefixed string") | ||
|
||
func EncodeLengthPrefixedStringUint16BE(s string) []byte { | ||
b := make([]byte, 2+len(s)) | ||
binary.BigEndian.PutUint16(b, uint16(len(s))) | ||
copy(b[2:], s) | ||
return b | ||
} | ||
|
||
func DecodeLengthPrefixedStringUint16BE(b []byte) (string, []byte, error) { | ||
if len(b) < 2 { | ||
return "", nil, ErrInvalidLengthPrefixedString | ||
} | ||
l := binary.BigEndian.Uint16(b) | ||
if len(b) < 2+int(l) { | ||
return "", nil, ErrInvalidLengthPrefixedString | ||
} | ||
return string(b[2 : 2+l]), b[l+2:], nil | ||
} | ||
|
||
func MustDecodeLengthPrefixedStringUint16BE(b []byte) (string, []byte) { | ||
s, r, err := DecodeLengthPrefixedStringUint16BE(b) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return s, r | ||
} |
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 @@ | ||
module gno.land/p/demo/binutils |
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,70 @@ | ||
package core | ||
|
||
import ( | ||
"std" | ||
"strings" | ||
|
||
dao_interfaces "gno.land/p/demo/daodao/interfaces_v6" | ||
"gno.land/p/demo/markdown_utils" | ||
) | ||
|
||
// TODO: add wrapper message handler to handle multiple proposal modules messages | ||
|
||
type IDAOCore interface { | ||
AddProposalModule(proposalMod dao_interfaces.IProposalModule) | ||
|
||
VotingModule() dao_interfaces.IVotingModule | ||
ProposalModules() []dao_interfaces.IProposalModule | ||
|
||
Render(path string) string | ||
} | ||
|
||
type daoCore struct { | ||
IDAOCore | ||
|
||
votingModule dao_interfaces.IVotingModule | ||
proposalModules []dao_interfaces.IProposalModule | ||
} | ||
|
||
func NewDAOCore( | ||
votingModule dao_interfaces.IVotingModule, | ||
proposalModules []dao_interfaces.IProposalModule, | ||
) IDAOCore { | ||
return &daoCore{ | ||
votingModule: votingModule, | ||
proposalModules: proposalModules, | ||
} | ||
} | ||
|
||
func (d *daoCore) VotingModule() dao_interfaces.IVotingModule { | ||
return d.votingModule | ||
} | ||
|
||
func (d *daoCore) ProposalModules() []dao_interfaces.IProposalModule { | ||
return d.proposalModules | ||
} | ||
|
||
func (d *daoCore) AddProposalModule(proposalMod dao_interfaces.IProposalModule) { | ||
d.proposalModules = append(d.proposalModules, proposalMod) | ||
} | ||
|
||
func (d *daoCore) Render(path string) string { | ||
s := "# DAO Core\n" | ||
s += "This is a port of [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 += markdown_utils.Indent(propMod.Render(path)) + "\n" | ||
} | ||
return s | ||
} | ||
|
||
func GetProposalModule(core IDAOCore, moduleIndex int) dao_interfaces.IProposalModule { | ||
if moduleIndex < 0 { | ||
panic("Module index must be >= 0") | ||
} | ||
mods := core.ProposalModules() | ||
if moduleIndex >= len(mods) { | ||
panic("invalid module index") | ||
} | ||
return mods[moduleIndex] | ||
} |
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,6 @@ | ||
module gno.land/p/demo/daodao/core_v6 | ||
|
||
require ( | ||
"gno.land/p/demo/daodao/interfaces_v6" v0.0.0-latest | ||
"gno.land/p/demo/markdown_utils" v0.0.0-latest | ||
) |
172 changes: 172 additions & 0 deletions
172
examples/gno.land/p/demo/daodao/interfaces_v6/dao_interfaces.gno
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,172 @@ | ||
package dao_interfaces | ||
|
||
import ( | ||
"std" | ||
"strconv" | ||
|
||
"gno.land/p/demo/avl" | ||
"gno.land/p/demo/jsonutil_v4" | ||
) | ||
|
||
type IVotingModule interface { | ||
VotingPower(addr std.Address) uint64 | ||
TotalPower() uint64 | ||
Render(path string) string | ||
} | ||
|
||
type Ballot struct { | ||
Power uint64 | ||
Vote Vote | ||
Rationale string | ||
} | ||
|
||
func (b Ballot) ToJSON() string { | ||
return jsonutil.FormatObject([]jsonutil.KeyValue{ | ||
{Key: "power", Value: b.Power}, | ||
{Key: "vote", Value: b.Vote}, | ||
{Key: "rationale", Value: b.Rationale}, | ||
}) | ||
} | ||
|
||
type Votes struct { | ||
Yes uint64 | ||
No uint64 | ||
Abstain uint64 | ||
} | ||
|
||
func (v *Votes) Add(vote Vote, power uint64) { | ||
switch vote { | ||
case VoteYes: | ||
v.Yes += power | ||
case VoteNo: | ||
v.No += power | ||
case VoteAbstain: | ||
v.Abstain += power | ||
default: | ||
panic("unknown vote kind") | ||
} | ||
} | ||
|
||
func (v *Votes) Remove(vote Vote, power uint64) { | ||
switch vote { | ||
case VoteYes: | ||
v.Yes -= power | ||
case VoteNo: | ||
v.No -= power | ||
case VoteAbstain: | ||
v.Abstain -= power | ||
default: | ||
panic("unknown vote kind") | ||
} | ||
} | ||
|
||
func (v *Votes) Total() uint64 { | ||
return v.Yes + v.No + v.Abstain | ||
} | ||
|
||
func (v Votes) ToJSON() string { | ||
return jsonutil.FormatObject([]jsonutil.KeyValue{ | ||
{Key: "yes", Value: v.Yes}, | ||
{Key: "no", Value: v.No}, | ||
{Key: "abstain", Value: v.Abstain}, | ||
}) | ||
} | ||
|
||
type Proposal struct { | ||
ID int | ||
Title string | ||
Description string | ||
Proposer std.Address | ||
Messages []ExecutableMessage | ||
Ballots *avl.Tree // dev | ||
// Ballots *avl.MutTree // test3 | ||
Votes Votes | ||
Status ProposalStatus | ||
} | ||
|
||
var _ jsonutil.JSONAble = (*Proposal)(nil) | ||
|
||
func (p Proposal) ToJSON() string { | ||
return jsonutil.FormatObject([]jsonutil.KeyValue{ | ||
{Key: "id", Value: p.ID}, | ||
{Key: "title", Value: p.Title}, | ||
{Key: "description", Value: p.Description}, | ||
{Key: "proposer", Value: p.Proposer}, | ||
{Key: "messages", Value: jsonutil.FormatSlice(p.Messages), Raw: true}, | ||
{Key: "ballots", Value: p.Ballots}, | ||
{Key: "votes", Value: p.Votes}, | ||
{Key: "status", Value: p.Status}, | ||
}) | ||
} | ||
|
||
type ProposalStatus int | ||
|
||
const ( | ||
ProposalStatusOpen ProposalStatus = iota | ||
ProposalStatusPassed | ||
ProposalStatusExecuted | ||
) | ||
|
||
func (p ProposalStatus) ToJSON() string { | ||
return jsonutil.FormatString(p.String()) | ||
} | ||
|
||
func (p ProposalStatus) String() string { | ||
switch p { | ||
case ProposalStatusOpen: | ||
return "Open" | ||
case ProposalStatusPassed: | ||
return "Passed" | ||
case ProposalStatusExecuted: | ||
return "Executed" | ||
default: | ||
return "Unknown(" + strconv.Itoa(int(p)) + ")" | ||
} | ||
} | ||
|
||
type Vote int | ||
|
||
const ( | ||
VoteYes Vote = iota | ||
VoteNo | ||
VoteAbstain | ||
) | ||
|
||
func (v Vote) ToJSON() string { | ||
return jsonutil.FormatString(v.String()) | ||
} | ||
|
||
func (v Vote) String() string { | ||
switch v { | ||
case VoteYes: | ||
return "Yes" | ||
case VoteNo: | ||
return "No" | ||
case VoteAbstain: | ||
return "Abstain" | ||
default: | ||
return "Unknown(" + strconv.Itoa(int(v)) + ")" | ||
} | ||
} | ||
|
||
type IProposalModule interface { | ||
Propose( | ||
title string, | ||
description string, | ||
actions []ExecutableMessage, | ||
) | ||
Vote(proposalId int, vote Vote, rationale string) | ||
Execute(proposalId int) | ||
Threshold() Threshold | ||
|
||
Proposals() []Proposal | ||
GetBallot(proposalId int, addr std.Address) Ballot | ||
|
||
Render(path string) string | ||
} | ||
|
||
type ExecutableMessage interface { | ||
String() string | ||
Binary() []byte | ||
Type() string | ||
} |
Oops, something went wrong.