From 8ab9a2651a1bd74a325fcad38bad5ffb14566787 Mon Sep 17 00:00:00 2001 From: matijamarjanovic Date: Fri, 17 Jan 2025 20:01:13 +0100 Subject: [PATCH] fix nft registration, now each minted can be registered --- .../r/matijamarjanovic/tokenhub/tokenhub.gno | 20 +++++++++---- .../tokenhub/tokenhub_test.gno | 28 +++++++++---------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/examples/gno.land/r/matijamarjanovic/tokenhub/tokenhub.gno b/examples/gno.land/r/matijamarjanovic/tokenhub/tokenhub.gno index 223c08666e1..6164b3466a3 100644 --- a/examples/gno.land/r/matijamarjanovic/tokenhub/tokenhub.gno +++ b/examples/gno.land/r/matijamarjanovic/tokenhub/tokenhub.gno @@ -23,7 +23,7 @@ type GRC1155TokenInfo struct { } var ( - registeredNFTs = avl.NewTree() // rlmPath[.slug] -> NFTGetter + registeredNFTs = avl.NewTree() // rlmPath[.slug] -> NFTInfo registeredMTs = avl.NewTree() // rlmPath[.slug] -> GRC1155TokenInfo ErrNFTAlreadyRegistered = errors.New("NFT already registered") @@ -31,6 +31,8 @@ var ( 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") pageSize = 2 test = "" @@ -44,16 +46,23 @@ func RegisterToken(tokenGetter grc20.TokenGetter, slugs ...string) { grc20reg.Register(tokenGetter, slug) } -// TokenId is mandatory for NFTs -func RegisterNFT(nftGetter grc721.NFTGetter, tokenId string) error { +// registering a collection of NFTs +func RegisterNFT(nftGetter grc721.NFTGetter, collection string, tokenId string) error { + nft := nftGetter() _, ok := nft.(grc721.IGRC721CollectionMetadata) if !ok { - return errors.New("NFT must implement IGRC721CollectionMetadata") + return ErrNFTNotMetadata + } + + nftOwner, err := nft.OwnerOf(grc721.TokenID(tokenId)) + if string(nftOwner) == "" || err != nil { + return ErrNFTtokIDNotExists } rlmPath := std.PrevRealm().PkgPath() - key := fqname.Construct(rlmPath, tokenId) + k := ufmt.Sprintf("%s.%s", collection, tokenId) + key := fqname.Construct(rlmPath, k) if registeredNFTs.Has(key) { return ErrNFTAlreadyRegistered @@ -419,7 +428,6 @@ func getBalances(addr std.Address) string { balance := value.(uint64) symbol := strings.TrimPrefix(key, "nft:") sb.WriteString(ufmt.Sprintf("NFT:%s:%d,", symbol, balance)) - sb.WriteString(ufmt.Sprintf("Token:%s:%d,", symbol, balance)) case strings.HasPrefix(key, "token:"): balance := value.(uint64) symbol := strings.TrimPrefix(key, "token:") diff --git a/examples/gno.land/r/matijamarjanovic/tokenhub/tokenhub_test.gno b/examples/gno.land/r/matijamarjanovic/tokenhub/tokenhub_test.gno index 9c81b6ca768..df65f27751b 100644 --- a/examples/gno.land/r/matijamarjanovic/tokenhub/tokenhub_test.gno +++ b/examples/gno.land/r/matijamarjanovic/tokenhub/tokenhub_test.gno @@ -30,11 +30,14 @@ func TestTokenRegistration(t *testing.T) { func TestNFTRegistration(t *testing.T) { std.TestSetRealm(std.NewCodeRealm("gno.land/r/matijamarjanovic/home")) + addr := std.Address("g1ej0qca5ptsw9kfr64ey8jvfy9eacga6mpj2z0y") + nft := grc721.NewBasicNFT("Test NFT", "TNFT") - err := RegisterNFT(nft.Getter(), "test_nft") + nft.Mint(addr, grc721.TokenID("1")) + err := RegisterNFT(nft.Getter(), "test_nft", "1") urequire.NoError(t, err, "Should register NFT without error") - getter := GetGRC721("gno.land/r/matijamarjanovic/home.test_nft") + getter := GetGRC721("gno.land/r/matijamarjanovic/home.test_nft.1") urequire.True(t, getter != nil, "Should retrieve registered NFT") retrievedNFT := getter() @@ -43,7 +46,7 @@ func TestNFTRegistration(t *testing.T) { uassert.Equal(t, "Test NFT", metadata.Name(), "NFT name should match") uassert.Equal(t, "TNFT", metadata.Symbol(), "NFT symbol should match") - err = RegisterNFT(nft.Getter(), "test_nft") + err = RegisterNFT(nft.Getter(), "test_nft", "1") uassert.True(t, err != nil, "Should not allow duplicate registration") } @@ -72,17 +75,13 @@ func TestBalanceRetrieval(t *testing.T) { RegisterToken(token.Getter(), "test_tokenn") ledger.Mint(addr, 1000) - nft := grc721.NewBasicNFT("Test NFT", "TNFT") - RegisterNFT(nft.Getter(), "test_nftt") - nft.Mint(addr, grc721.TokenID("str")) - mt := grc1155.NewBasicGRC1155Token("test-uri") RegisterGRC1155Token(mt.Getter(), "11") mt.SafeMint(addr, grc1155.TokenID("11"), 5) balances := GetBalancesAll(string(addr)) uassert.True(t, strings.Contains(balances, "Token:gno.land/r/matijamarjanovic/tokenhub.test_tokenn:1000"), "Should show correct GRC20 balance") - uassert.True(t, strings.Contains(balances, "NFT:gno.land/r/matijamarjanovic/home.test_nftt:1"), "Should show correct NFT balance") + uassert.True(t, strings.Contains(balances, "NFT:gno.land/r/matijamarjanovic/home.test_nft.1:1"), "Should show correct NFT balance") //already minted in test register uassert.True(t, strings.Contains(balances, "MultiToken:gno.land/r/matijamarjanovic/home.11:5"), "Should show multi-token balance") nonZeroBalances := GetBalances(string(addr)) @@ -93,10 +92,10 @@ func TestErrorCases(t *testing.T) { std.TestSetRealm(std.NewCodeRealm("gno.land/r/matijamarjanovic/home")) nft := grc721.NewBasicNFT("Test NFT", "TNFT") - err := RegisterNFT(nft.Getter(), "test_nft") + err := RegisterNFT(nft.Getter(), "test_nft", "1") uassert.True(t, err != nil, "Should not allow duplicate registration") - err = RegisterNFT(nft.Getter(), "test_nft") + err = RegisterNFT(nft.Getter(), "test_nft", "1") uassert.True(t, err != nil, "Should not allow duplicate registration") mt := grc1155.NewBasicGRC1155Token("test-uri") @@ -117,14 +116,15 @@ func TestTokenListingFunctions(t *testing.T) { grc20Token, _ := grc20.NewToken("Test Token", "TEST", 6) RegisterToken(grc20Token.Getter(), "listing_token") - nftToken := grc721.NewBasicNFT("Test NFT", "TNFT") - RegisterNFT(nftToken.Getter(), "listing_nft") + nftToken := grc721.NewBasicNFT("Listing NFT", "LNFT") + nftToken.Mint(std.Address("g1ej0qca5ptsw9kfr64ey8jvfy9eacga6mpj2z0y"), grc721.TokenID("1")) + RegisterNFT(nftToken.Getter(), "listing_nft", "1") multiToken := grc1155.NewBasicGRC1155Token("test-uri") RegisterGRC1155Token(multiToken.Getter(), "listing_mt") nftList := GetAllNFTs() - uassert.True(t, strings.Contains(nftList, "NFT:gno.land/r/matijamarjanovic/home.listing_nft"), + uassert.True(t, strings.Contains(nftList, "NFT:gno.land/r/matijamarjanovic/home.listing_nft.1"), "GetAllNFTs should list registered NFT") grc20List := GetAllGRC20Tokens() @@ -136,7 +136,7 @@ func TestTokenListingFunctions(t *testing.T) { "GetAllMultiTokens should list registered multi-token") completeList := GetAllTokens() - uassert.True(t, strings.Contains(completeList, "NFT:gno.land/r/matijamarjanovic/home.listing_nft"), + uassert.True(t, strings.Contains(completeList, "NFT:gno.land/r/matijamarjanovic/home.listing_nft.1"), "GetAllTokens should list NFTs") uassert.True(t, strings.Contains(completeList, "Token:gno.land/r/matijamarjanovic/tokenhub.listing_token"), "GetAllTokens should list GRC20 tokens")