Search Apps Documentation Source Content File Folder Download Copy

grc721_royalty.gno

2.36 Kb ยท 78 lines
 1package grc721
 2
 3import (
 4	"std"
 5
 6	"gno.land/p/demo/avl"
 7)
 8
 9// royaltyNFT represents a non-fungible token (NFT) with royalty functionality.
10type royaltyNFT struct {
11	*metadataNFT                   // Embedding metadataNFT for NFT functionality
12	tokenRoyaltyInfo     *avl.Tree // AVL tree to store royalty information for each token
13	maxRoyaltyPercentage uint64    // maxRoyaltyPercentage represents the maximum royalty percentage that can be charged every sale
14}
15
16// Ensure that royaltyNFT implements the IGRC2981 interface.
17var _ IGRC2981 = (*royaltyNFT)(nil)
18
19// NewNFTWithRoyalty creates a new royalty NFT with the specified name, symbol, and royalty calculator.
20func NewNFTWithRoyalty(name string, symbol string) *royaltyNFT {
21	// Create a new NFT with metadata
22	nft := NewNFTWithMetadata(name, symbol)
23
24	return &royaltyNFT{
25		metadataNFT:          nft,
26		tokenRoyaltyInfo:     avl.NewTree(),
27		maxRoyaltyPercentage: 100,
28	}
29}
30
31// SetTokenRoyalty sets the royalty information for a specific token ID.
32func (r *royaltyNFT) SetTokenRoyalty(tid TokenID, royaltyInfo RoyaltyInfo) error {
33	// Validate the payment address
34	if err := isValidAddress(royaltyInfo.PaymentAddress); err != nil {
35		return ErrInvalidRoyaltyPaymentAddress
36	}
37
38	// Check if royalty percentage exceeds maxRoyaltyPercentage
39	if royaltyInfo.Percentage > r.maxRoyaltyPercentage {
40		return ErrInvalidRoyaltyPercentage
41	}
42
43	// Check if the caller is the owner of the token
44	owner, err := r.metadataNFT.OwnerOf(tid)
45	if err != nil {
46		return err
47	}
48	caller := std.PrevRealm().Addr()
49	if caller != owner {
50		return ErrCallerIsNotOwner
51	}
52
53	// Set royalty information for the token
54	r.tokenRoyaltyInfo.Set(string(tid), royaltyInfo)
55
56	return nil
57}
58
59// RoyaltyInfo returns the royalty information for the given token ID and sale price.
60func (r *royaltyNFT) RoyaltyInfo(tid TokenID, salePrice uint64) (std.Address, uint64, error) {
61	// Retrieve royalty information for the token
62	val, found := r.tokenRoyaltyInfo.Get(string(tid))
63	if !found {
64		return "", 0, ErrInvalidTokenId
65	}
66
67	royaltyInfo := val.(RoyaltyInfo)
68
69	// Calculate royalty amount
70	royaltyAmount, _ := r.calculateRoyaltyAmount(salePrice, royaltyInfo.Percentage)
71
72	return royaltyInfo.PaymentAddress, royaltyAmount, nil
73}
74
75func (r *royaltyNFT) calculateRoyaltyAmount(salePrice, percentage uint64) (uint64, error) {
76	royaltyAmount := (salePrice * percentage) / 100
77	return royaltyAmount, nil
78}