Skip to content
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: token hub #3479

Open
wants to merge 78 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
6b9ceb7
initial commit
matijamarjanovic Jan 10, 2025
7ec4dc7
-add getter to basic nft and igrc721 interface
matijamarjanovic Jan 10, 2025
7970e42
fix fmt
matijamarjanovic Jan 10, 2025
9c397a5
- add iterate function to grc20reg to be able to get all registered t…
matijamarjanovic Jan 11, 2025
a02b955
remove unused var
matijamarjanovic Jan 11, 2025
0931341
add getter to grc1155
matijamarjanovic Jan 11, 2025
04ee40e
-add support for grc1155 (not perfect)
matijamarjanovic Jan 11, 2025
af1631f
display different token types on different pages
matijamarjanovic Jan 12, 2025
42152f4
add pagination for grc20 (this includes adding 1 more iteration funct…
matijamarjanovic Jan 12, 2025
c07116f
add pagination to grc721 page as well
matijamarjanovic Jan 12, 2025
c6ea858
add pagination for grc1155
matijamarjanovic Jan 12, 2025
b5967e4
add a getter function for tokens with non zero balances
matijamarjanovic Jan 12, 2025
8727cc6
-update saving grc1155 so it makes most sense
matijamarjanovic Jan 12, 2025
0186c2d
add get and must get for all token types
matijamarjanovic Jan 12, 2025
3181a38
fix fmt
matijamarjanovic Jan 12, 2025
1d7a4bf
Merge branch 'master' into feat/token-hub
matijamarjanovic Jan 13, 2025
3978697
add namespace support
matijamarjanovic Jan 13, 2025
fadc509
fix fmt
matijamarjanovic Jan 13, 2025
d3af61c
add testing
matijamarjanovic Jan 14, 2025
ad2b368
fix up test
matijamarjanovic Jan 14, 2025
2770485
fix fmt
matijamarjanovic Jan 14, 2025
99a5ca7
add getAll tokens + get tokens by type
matijamarjanovic Jan 14, 2025
2ab9221
add tests and remove (fake) test file
matijamarjanovic Jan 14, 2025
f084ceb
remove test realm
matijamarjanovic Jan 14, 2025
c484774
fix fmt
matijamarjanovic Jan 14, 2025
48c6cd1
more fix fmt
matijamarjanovic Jan 14, 2025
c0ca4a5
Merge branch 'master' into feat/token-hub
matijamarjanovic Jan 17, 2025
87aac01
update so nft doesn't allow optional slug, but has to include tokenid
matijamarjanovic Jan 17, 2025
8ab9a26
fix nft registration, now each minted can be registered
matijamarjanovic Jan 17, 2025
b107e7d
fix: show only nfts and grc1155 owner has, because there could be who…
matijamarjanovic Jan 17, 2025
936f181
write only key for nfts, no need for balance
matijamarjanovic Jan 17, 2025
dabf342
- add get all tokens without nfts
matijamarjanovic Jan 17, 2025
c333c42
add different funcs for prevrealm and orig caller
matijamarjanovic Jan 18, 2025
038cb50
- add seing anyones balances
matijamarjanovic Jan 20, 2025
d538723
Merge branch 'master' into feat/token-hub
matijamarjanovic Jan 20, 2025
5ed07c2
Merge branch 'master' into feat/token-hub
matijamarjanovic Jan 20, 2025
be510bc
Merge branch 'master' into feat/token-hub
matijamarjanovic Jan 21, 2025
8c09725
fix page size, remove test
matijamarjanovic Jan 21, 2025
88b0a7e
make errors start with lowercase
matijamarjanovic Jan 21, 2025
1c4b72a
remove not needed new lines
matijamarjanovic Jan 21, 2025
005e64b
- change slugs to slug
matijamarjanovic Jan 21, 2025
7ac568f
- remove getorigcaller use function
matijamarjanovic Jan 21, 2025
35fa7e2
remove get my balacnces - does the same as getuserbalances for the ca…
matijamarjanovic Jan 21, 2025
3b94b2e
fix naming
matijamarjanovic Jan 21, 2025
0a63572
return the tokens themselves instead of getters
matijamarjanovic Jan 21, 2025
99b44ac
implement return tokens themselves instead of getters in grc1155 too …
matijamarjanovic Jan 21, 2025
3f8bb51
update naming to be consistent
matijamarjanovic Jan 21, 2025
b5a8206
remove fqname and just use concat
matijamarjanovic Jan 21, 2025
3c5d8dc
divide realm into multiple files for better readability
matijamarjanovic Jan 21, 2025
43b4b52
render refactor; new functions for each case, use string concat inst…
matijamarjanovic Jan 21, 2025
59586e5
- change the pagination implement pager from p/demo/avl
matijamarjanovic Jan 21, 2025
f48d034
-refactor private getter
matijamarjanovic Jan 21, 2025
9b9767f
optimization so each token types should be gettable separately to red…
matijamarjanovic Jan 21, 2025
385fdf9
add get non zero balances
matijamarjanovic Jan 21, 2025
c9edff9
add formatting, fix ufmt print
matijamarjanovic Jan 21, 2025
1c598a3
move errors in separate file for better readability
matijamarjanovic Jan 21, 2025
a946cc4
add documentation
matijamarjanovic Jan 21, 2025
92305e9
Merge branch 'master' into feat/token-hub
matijamarjanovic Jan 21, 2025
93075f3
add working tests
matijamarjanovic Jan 21, 2025
387ebd9
\n placement
matijamarjanovic Jan 21, 2025
7be170b
fix fmt
matijamarjanovic Jan 21, 2025
1e0f60c
fix fmt again
matijamarjanovic Jan 21, 2025
0adea0e
set page size to 10
matijamarjanovic Jan 22, 2025
8d85cf1
Merge branch 'master' into feat/token-hub
matijamarjanovic Jan 23, 2025
dabdf61
Merge branch 'master' into feat/token-hub
matijamarjanovic Jan 23, 2025
13e4992
-move token hub to r/demo
matijamarjanovic Jan 23, 2025
7c5c2a7
Merge branch 'feat/token-hub' of https://github.com/matijamarjanovic/…
matijamarjanovic Jan 23, 2025
baeadcb
remove files
matijamarjanovic Jan 23, 2025
cbfe597
Merge branch 'master' into feat/token-hub
leohhhn Jan 28, 2025
1c3b939
Merge branch 'master' into feat/token-hub
matijamarjanovic Jan 31, 2025
403efc5
fix tests
matijamarjanovic Jan 31, 2025
d09eebc
Merge branch 'master' into feat/token-hub
matijamarjanovic Feb 4, 2025
50305aa
add hof registration
matijamarjanovic Feb 4, 2025
e70b81a
Merge branch 'master' into feat/token-hub
matijamarjanovic Feb 5, 2025
0bf5388
Merge branch 'master' into feat/token-hub
matijamarjanovic Feb 6, 2025
7bcf274
add tests for getters
matijamarjanovic Feb 6, 2025
ecd1b52
fix fmt
matijamarjanovic Feb 6, 2025
0db4ec8
try and fix tsts
matijamarjanovic Feb 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions examples/gno.land/p/demo/grc/grc1155/basic_grc1155_token.gno
Original file line number Diff line number Diff line change
Expand Up @@ -345,3 +345,9 @@ func (s *basicGRC1155Token) RenderHome() (str string) {

return
}

func (mt *basicGRC1155Token) Getter() MultiTokenGetter {
return func() IGRC1155 {
return mt
}
}
2 changes: 2 additions & 0 deletions examples/gno.land/p/demo/grc/grc1155/igrc1155.gno
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ type ApprovalForAllEvent struct {
type UpdateURIEvent struct {
URI string
}

type MultiTokenGetter func() IGRC1155
7 changes: 7 additions & 0 deletions examples/gno.land/p/demo/grc/grc721/basic_nft.gno
Original file line number Diff line number Diff line change
Expand Up @@ -395,3 +395,10 @@ func (s *basicNFT) RenderHome() (str string) {

return
}

// Then add the Getter method to your NFT types
func (n *basicNFT) Getter() NFTGetter {
return func() IGRC721 {
return n
}
}
2 changes: 2 additions & 0 deletions examples/gno.land/p/demo/grc/grc721/igrc721.gno
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ const (
ApprovalEvent = "Approval"
ApprovalForAllEvent = "ApprovalForAll"
)

type NFTGetter func() IGRC721
21 changes: 21 additions & 0 deletions examples/gno.land/r/demo/grc20reg/grc20reg.gno
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"std"

"gno.land/p/demo/avl"
"gno.land/p/demo/avl/rotree"
"gno.land/p/demo/fqname"
"gno.land/p/demo/grc/grc20"
"gno.land/p/demo/ufmt"
Expand All @@ -22,6 +23,22 @@ func Register(tokenGetter grc20.TokenGetter, slug string) {
)
}

func RegisterWithTokenhub(tokenGetter grc20.TokenGetter, key string) {
prevRealmPath := std.PrevRealm().PkgPath()
if prevRealmPath != "gno.land/r/demo/tokenhub" {
return
}

registry.Set(key, tokenGetter)

rlmPath, slug := fqname.Parse(key)
std.Emit(
registerEvent,
"pkgpath", rlmPath,
"slug", slug,
)
}

func Get(key string) grc20.TokenGetter {
tokenGetter, ok := registry.Get(key)
if !ok {
Expand Down Expand Up @@ -74,3 +91,7 @@ func Render(path string) string {
}

const registerEvent = "register"

func GetRegistry() *rotree.ReadOnlyTree {
return rotree.Wrap(registry, nil)
}
15 changes: 15 additions & 0 deletions examples/gno.land/r/demo/tokenhub/errors.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package tokenhub

import (
"errors"
)

var (
ErrNFTAlreadyRegistered = errors.New("NFT already registered")
ErrNFTNotFound = errors.New("NFT not found")
ErrMTAlreadyRegistered = errors.New("multi-token already registered")
ErrMTNotFound = errors.New("multi-token not found")
ErrMTInfoNotFound = errors.New("multi-token info not found")
ErrNFTtokIDNotExists = errors.New("NFT token ID does not exists")
ErrNFTNotMetadata = errors.New("NFT must implement IGRC721CollectionMetadata")
)
208 changes: 208 additions & 0 deletions examples/gno.land/r/demo/tokenhub/getters.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package tokenhub

import (
"std"
"strings"

"gno.land/p/demo/grc/grc1155"
"gno.land/p/demo/grc/grc20"
"gno.land/p/demo/grc/grc721"
"gno.land/p/demo/ufmt"
"gno.land/r/demo/grc20reg"
"gno.land/r/demo/users"
)

// GetUserTokenBalances returns a string of all the grc20 tokens the user owns
func GetUserTokenBalances(userNameOrAddress string) string {
return getTokenBalances(userNameOrAddress, false)
}

// GetUserTokenBalancesNonZero returns a string of all the grc20 tokens the user owns, but only the ones that have a balance greater than 0
func GetUserTokenBalancesNonZero(userNameOrAddress string) string {
return getTokenBalances(userNameOrAddress, true)
}

// GetUserNFTBalances returns a string of all the NFTs the user owns
func GetUserNFTBalances(userNameOrAddress string) string {
return getNFTBalances(userNameOrAddress)
}

// GetUserMultiTokenBalances returns a string of all the multi-tokens the user owns
func GetUserMultiTokenBalances(userNameOrAddress string) string {
return getMultiTokenBalances(userNameOrAddress, false)
}

// GetUserMultiTokenBalancesNonZero returns a string of all the multi-tokens the user owns, but only the ones that have a balance greater than 0
func GetUserMultiTokenBalancesNonZero(userNameOrAddress string) string {
return getMultiTokenBalances(userNameOrAddress, true)
}

// GetToken returns a token instance for a given key
func GetToken(key string) *grc20.Token {
getter := grc20reg.Get(key)
return getter()
}

// MustGetToken returns a token instance for a given key, panics if the token is not found
func MustGetToken(key string) *grc20.Token {
getter := grc20reg.MustGet(key)
if getter == nil {
panic("unknown token: " + key)
}
return getter()
}

// GetNFT returns an NFT instance for a given key
func GetNFT(key string) grc721.IGRC721 {
nftGetter, ok := registeredNFTs.Get(key)
if !ok {
return nil
}
return (nftGetter.(grc721.NFTGetter))()
}

// MustGetNFT returns an NFT instance for a given key, panics if the NFT is not found
func MustGetNFT(key string) grc721.IGRC721 {
nftGetter := GetNFT(key)
if nftGetter == nil {
panic("unknown NFT: " + key)
}
return nftGetter
}

// GetMultiToken returns a multi-token instance for a given key
func GetMultiToken(key string) grc1155.IGRC1155 {
info, ok := registeredMTs.Get(key)
if !ok {
return nil
}
mt := info.(GRC1155TokenInfo).Collection
return mt()
}

// MustGetMultiToken returns a multi-token instance for a given key, panics if the multi-token is not found
func MustGetMultiToken(key string) grc1155.IGRC1155 {
info := GetMultiToken(key)
if info == nil {
panic("unknown multi-token: " + key)
}
return info
}

// GetAllNFTs returns a string of all the NFTs registered
func GetAllNFTs() string {
var out string
registeredNFTs.Iterate("", "", func(key string, value interface{}) bool {
out += ufmt.Sprintf("NFT:%s,", key)
return false
})
return out
}

// GetAllTokens returns a string of all the tokens registered
func GetAllTokens() string {
var out string
grc20reg.GetRegistry().Iterate("", "", func(key string, value interface{}) bool {
out += "Token:" + key + ","
return false
})
return out
}

// GetAllMultiTokens returns a string of all the multi-tokens registered
func GetAllMultiTokens() string {
var out string
registeredMTs.Iterate("", "", func(key string, value interface{}) bool {
out += "MultiToken:" + key + ","
return false
})
return out
}

// GetAllRegistered returns a string of all the registered tokens, NFTs and multi-tokens
func GetAllRegistered() string {
return GetAllNFTs() + GetAllTokens() + GetAllMultiTokens()
}

// getNFTBalances returns a string of all the NFTs the user owns
func getNFTBalances(input string) string {
addr := getAddressForUsername(input)
if !addr.IsValid() {
panic("invalid address or username: " + input)
}
var out string

registeredNFTs.Iterate("", "", func(key string, value interface{}) bool {
nftGetter := value.(grc721.NFTGetter)
nft := nftGetter()
key_parts := strings.Split(key, ".")
owner, err := nft.OwnerOf(grc721.TokenID(key_parts[len(key_parts)-1]))
if err == nil && addr == owner { // show only the nfts owner owns
out += "NFT:" + key + ","
}
return false
})

return out
}

// getTokenBalances returns a string of all the tokens the user owns
func getTokenBalances(input string, nonZero bool) string {
addr := getAddressForUsername(input)
if !addr.IsValid() {
panic("invalid address or username: " + input)
}
var out string
grc20reg.GetRegistry().Iterate("", "", func(key string, value interface{}) bool {
tokenGetter := value.(grc20.TokenGetter)
token := tokenGetter()
balance := token.BalanceOf(addr)
if nonZero && balance > 0 {
out += ufmt.Sprintf("Token:%s:%d,", key, balance)
} else if !nonZero {
out += ufmt.Sprintf("Token:%s:%d,", key, balance)
}
return false
})

return out
}

// getMultiTokenBalances returns a string of all the multi-tokens the user owns
func getMultiTokenBalances(input string, nonZero bool) string {
addr := getAddressForUsername(input)
if !addr.IsValid() {
panic("invalid address or username: " + input)
}
var out string

registeredMTs.Iterate("", "", func(key string, value interface{}) bool {
info := value.(GRC1155TokenInfo)
mt := info.Collection()
balance, err := mt.BalanceOf(addr, grc1155.TokenID(info.TokenID))
if err == nil {
if nonZero && balance > 0 {
out += ufmt.Sprintf("MultiToken:%s:%d,", key, balance)
} else if !nonZero {
out += ufmt.Sprintf("MultiToken:%s:%d,", key, balance)
}
}
return false
})

return out
}

// getAddressForUsername returns an address for a given username or address
func getAddressForUsername(addrOrName string) std.Address {
addr := std.Address(addrOrName)
if addr.IsValid() {
return addr
}

if user := users.GetUserByName(addrOrName); user != nil {
return user.Address
}

return ""
}
1 change: 1 addition & 0 deletions examples/gno.land/r/demo/tokenhub/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module gno.land/r/demo/tokenhub
Loading
Loading