Skip to content

Commit

Permalink
initial commit, add btree_dao structure
Browse files Browse the repository at this point in the history
  • Loading branch information
matijamarjanovic committed Dec 19, 2024
1 parent 1b1e03b commit c78d6c5
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 181 deletions.
150 changes: 150 additions & 0 deletions examples/gno.land/r/matijamarjanovic/btree_dao/btree_dao.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package btree_dao

import (
"std"
"strings"
"time"
"errors"
"gno.land/p/demo/btree"
"gno.land/p/demo/grc/grc721"
"gno.land/p/moul/md"
"gno.land/p/demo/ufmt"

)
// RegistrationDetails holds the details of a user's registration
type RegistrationDetails struct {
Address std.Address
RegTime time.Time
UserBTree *btree.BTree
NFTID int
}

// Less implements the Record interface for RegistrationDetails
// It compares based on the time of registration
func (rd *RegistrationDetails) Less(than btree.Record) bool {
other := than.(*RegistrationDetails)
return rd.RegTime.Before(other.RegTime)
}

var (
dao = grc721.NewBasicNFT("BTree DAO", "BTDAO")
tokenID = 0
members = btree.New()
)


// Register allows a user to register by sending their B-Tree instance
func Register(userBTree *btree.BTree) error {
// Check if this tree is already registered
var treeExists bool
members.Ascend(func(record btree.Record) bool {
regDetails := record.(*RegistrationDetails)
if regDetails.UserBTree == userBTree {
treeExists = true
return false // Stop iteration
}
return true
})
if treeExists {
return errors.New("tree is already registered")
}

// Get the caller's address - use GetOrigCaller() if called from init()
var userAddress std.Address
if std.PrevRealm().IsUser() {
userAddress = std.PrevRealm().Addr() // technically this will never happen as you can't register a btree from manually created tx
} else {
userAddress = std.GetOrigCaller()
}

// Check if the user has used a B-Tree or just made an empty one
// User can also cheat this system but I don't see the point
if userBTree == nil || userBTree.Len() == 0 {
return errors.New("Invalid B-Tree instance")
}

// Mint an NFT to the user
err := dao.Mint(userAddress, grc721.TokenID(tokenID))
if err != nil {
return err
}

regDetails := &RegistrationDetails{
Address: userAddress,
RegTime: time.Now(),
UserBTree: userBTree,
NFTID: tokenID,
}

members.Insert(regDetails)

tokenID++

return nil
}

// Render generates a Markdown representation of the DAO members,
// displaying the latest 10 members and the first 3 members as "OGs".
func Render(path string) string {
var latestMembers []string
var ogMembers []string

// Collect the latest 10 members
members.Descend(func(record btree.Record) bool {
if len(latestMembers) < 10 {
regDetails := record.(*RegistrationDetails)
addr := regDetails.Address
nftList := ""
balance, err := dao.BalanceOf(addr)
if err == nil && balance > 0 {
nftList = " (NFTs: "
for i := uint64(0); i < balance; i++ {
if i > 0 {
nftList += ", "
}
nftList += "#" + ufmt.Sprintf("%d", regDetails.NFTID)
}
nftList += ")"
}
latestMembers = append(latestMembers, string(addr)+nftList)
return true
}
return false
})

// Collect the first 3 members (OGs)
members.Ascend(func(record btree.Record) bool {
if len(ogMembers) < 3 {
regDetails := record.(*RegistrationDetails)
addr := regDetails.Address
nftList := ""
balance, err := dao.BalanceOf(addr)
if err == nil && balance > 0 {
nftList = " (NFTs: "
for i := uint64(0); i < balance; i++ {
if i > 0 {
nftList += ", "
}
nftList += "#" + ufmt.Sprintf("%d", regDetails.NFTID)
}
nftList += ")"
}
ogMembers = append(ogMembers, string(addr)+nftList)
return true
}
return false
})

// Use the md package to format the output
var sb strings.Builder

sb.WriteString(md.H1("B-Tree DAO Members"))
sb.WriteString(md.H2("Total NFTs Minted"))
sb.WriteString(ufmt.Sprintf("Total NFTs minted: %d\n\n", dao.TokenCount()))
sb.WriteString(md.H2("OG Members"))
sb.WriteString(md.BulletList(ogMembers))
sb.WriteString(md.H2("Latest Members"))
sb.WriteString(md.BulletList(latestMembers))

return sb.String()
}
2 changes: 2 additions & 0 deletions examples/gno.land/r/matijamarjanovic/btree_dao/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module gno.land/r/matijamarjanovic/btree_dao

33 changes: 33 additions & 0 deletions examples/gno.land/r/matijamarjanovic/home/home.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"gno.land/p/demo/ufmt"
"gno.land/p/moul/md"
"gno.land/r/leon/hof"
"gno.land/p/demo/btree"
"gno.land/r/matijamarjanovic/btree_dao"
)

var (
Expand Down Expand Up @@ -46,8 +48,11 @@ func init() {
classicLink = "https://www.google.com"
minimalLink = "https://www.google.com"
hof.Register()
CreateAndRegisterBTree()
}



func UpdatePFP(url, caption string) {
AssertAuthorized()
pfp = url
Expand Down Expand Up @@ -236,3 +241,31 @@ func UpdateMinimalLink(link string) {
AssertAuthorized()
minimalLink = link
}

// IntRecord wraps an int to implement btree.Record interface
type IntRecord struct {
value int
}

// Less implements btree.Record interface
func (i *IntRecord) Less(than btree.Record) bool {
return i.value < than.(*IntRecord).value
}

// CreateAndRegisterBTree creates a btree with 3 integers and registers it with the DAO
func CreateAndRegisterBTree() error {
// Create new btree
tree := btree.New()

// Add 3 integers
tree.Insert(&IntRecord{1})
tree.Insert(&IntRecord{2})
tree.Insert(&IntRecord{3})

// Register tree with each address
err := btree_dao.Register(tree)
if err != nil {
return err
}
return nil
}
10 changes: 0 additions & 10 deletions examples/gno.land/r/matijamarjanovic/todos/errors.gno

This file was deleted.

1 change: 0 additions & 1 deletion examples/gno.land/r/matijamarjanovic/todos/gno.mod

This file was deleted.

2 changes: 0 additions & 2 deletions examples/gno.land/r/matijamarjanovic/todos/platform.gno

This file was deleted.

168 changes: 0 additions & 168 deletions examples/gno.land/r/matijamarjanovic/todos/todo_nft.gno

This file was deleted.

0 comments on commit c78d6c5

Please sign in to comment.