PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/nt/grc721/royalty/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
nt / grc721 / royalty
Files
4 (gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/nt/grc721/royalty/v0
gno
0.9

Files (4)

  • gnomod.tomltoml
  • token.gnogno
  • types.gnogno
  • token_test.gnogno
token.gnogno
1package royalty23import (4	"chain"5	"math"6	"strconv"78	"gno.land/p/nt/grc721/v0"9)1011const Kind = "royalty"1213// NewRoyalty attaches a royalty extension; maxBps caps every rate and must be 0..10000.14func NewRoyalty(coreLedger *grc721.PrivateLedger, maxBps int64) (*Royalty, *Ledger) {15	if coreLedger == nil {16		panic("royalty: nil core ledger")17	}1819	if maxBps < 0 || maxBps > FeeDenominator {20		panic(ErrMaxBpsRange)21	}2223	st := &storage{maxBps: maxBps}24	core := coreLedger.ReadToken()25	led := &Ledger{core: core, st: st}2627	coreLedger.RegisterExtension(led)2829	return &Royalty{core: core, st: st}, led30}3132func (r *Royalty) ExtensionKind() string { return Kind }3334func (r *Royalty) TokenID() string { return r.core.ID() }3536func (r *Royalty) MaxBps() int64 { return r.st.maxBps }3738// RoyaltyInfo implements EIP-2981; per-token override takes precedence over the39// default, and no royalty returns (zeroAddress, 0) — the "no royalty" signal.40func (r *Royalty) RoyaltyInfo(tid grc721.TokenID, salePrice int64) (address, int64, error) {41	if salePrice < 0 {42		return zeroAddress, 0, ErrInvalidSalePrice43	}4445	info, ok := r.resolve(tid)46	if !ok {47		return zeroAddress, 0, nil48	}4950	if info.Bps != 0 && salePrice > math.MaxInt64/info.Bps {51		return zeroAddress, 0, ErrInvalidSalePrice52	}5354	amount := salePrice * info.Bps / FeeDenominator5556	return info.Receiver, amount, nil57}5859func (r *Royalty) DefaultRoyalty() (RoyaltyInfo, bool) {60	if !r.st.hasDefault {61		return RoyaltyInfo{}, false62	}6364	return r.st.def, true65}6667func (r *Royalty) TokenRoyalty(tid grc721.TokenID) (RoyaltyInfo, bool) {68	v := r.st.perToken.Get(tid.String())69	if v == nil {70		return RoyaltyInfo{}, false71	}7273	return v.(RoyaltyInfo), true74}7576// resolve returns the effective royalty: per-token override first, then default.77func (r *Royalty) resolve(tid grc721.TokenID) (RoyaltyInfo, bool) {78	if v := r.st.perToken.Get(tid.String()); v != nil {79		return v.(RoyaltyInfo), true80	}8182	if r.st.hasDefault {83		return r.st.def, true84	}8586	return RoyaltyInfo{}, false87}8889// SetDefaultRoyalty sets the collection default for tokens without an override; issuer-only.90func (led *Ledger) SetDefaultRoyalty(receiver address, bps int64) error {91	if err := led.validate(receiver, bps); err != nil {92		return err93	}9495	led.st.def = RoyaltyInfo{Receiver: receiver, Bps: bps}96	led.st.hasDefault = true9798	led.emitRoyaltyUpdate("default", "", receiver, bps)99	return nil100}101102func (led *Ledger) DeleteDefaultRoyalty() {103	led.st.hasDefault = false104	led.st.def = RoyaltyInfo{}105106	led.emitRoyaltyUpdate("default", "", zeroAddress, 0)107}108109// SetTokenRoyalty sets a per-token override for tid; issuer-only.110func (led *Ledger) SetTokenRoyalty(tid grc721.TokenID, receiver address, bps int64) error {111	if _, err := led.core.OwnerOf(tid); err != nil {112		return ErrTokenNotMinted113	}114115	if err := led.validate(receiver, bps); err != nil {116		return err117	}118119	led.st.perToken.Set(tid.String(), RoyaltyInfo{Receiver: receiver, Bps: bps})120121	led.emitRoyaltyUpdate("token", tid.String(), receiver, bps)122	return nil123}124125// DeleteTokenRoyalty clears the per-token override, falling back to the default.126func (led *Ledger) DeleteTokenRoyalty(tid grc721.TokenID) {127	led.st.perToken.Remove(tid.String())128129	led.emitRoyaltyUpdate("token", tid.String(), zeroAddress, 0)130}131132// emitRoyaltyUpdate signals a royalty change (EIP-2981 defines no events); a133// cleared royalty is reported as an empty receiver and bps 0.134func (led *Ledger) emitRoyaltyUpdate(scope, tokenID string, receiver address, bps int64) {135	chain.Emit(136		RoyaltyUpdateEvent,137		"token", led.core.ID(),138		"scope", scope,139		"tokenId", tokenID,140		"receiver", receiver.String(),141		"bps", strconv.FormatInt(bps, 10),142	)143}144145func (led *Ledger) validate(receiver address, bps int64) error {146	if !receiver.IsValid() {147		return ErrInvalidReceiver148	}149150	if bps < 0 || bps > led.st.maxBps {151		return ErrInvalidBps152	}153154	return nil155}156157func (led *Ledger) ExtensionKind() string { return Kind }158159func (led *Ledger) OnMint(to address, tid grc721.TokenID)           {}160func (led *Ledger) OnTransfer(from, to address, tid grc721.TokenID) {}161162// OnBurn clears the per-token override (cannot resurface on re-mint) but keeps163// the default, which is collection-level policy, not per-token state.164func (led *Ledger) OnBurn(tid grc721.TokenID) {165	led.st.perToken.Remove(tid.String())166}167

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.