Search Apps Documentation Source Content File Folder Download Copy Actions Download

royalty.gno

2.36 Kb · 65 lines
 1package memba_collections
 2
 3import (
 4	"chain"
 5	"math/overflow"
 6
 7	"gno.land/p/samcrew/grc721"
 8)
 9
10// SetRoyalty updates the collection-default royalty. Admin only; bps must be
11// in [MinCreatorRoyaltyBPS, maxCreatorRoyaltyBPS].
12func SetRoyalty(cur realm, id string, recip address, bps int64) {
13	c := mustGet(id)
14	assertCollectionAdmin(c)
15	if bps < MinCreatorRoyaltyBPS || bps > maxCreatorRoyaltyBPS {
16		panic("royalty out of range")
17	}
18	c.royaltyRecip, c.royaltyBPS = recip, bps
19	chain.Emit("RoyaltySet", "collectionID", id, "bps", itoa(bps), "recip", recip.String())
20}
21
22// SetTokenRoyalty sets a per-token royalty override. PRESENCE of the override
23// wins over the collection default — even bps==0 means "royalty OFF for this
24// token" (S-1). Admin only; bps <= maxCreatorRoyaltyBPS.
25func SetTokenRoyalty(cur realm, id string, tid grc721.TokenID, recip address, bps int64) {
26	c := mustGet(id)
27	assertCollectionAdmin(c)
28	if bps < MinCreatorRoyaltyBPS || bps > maxCreatorRoyaltyBPS {
29		panic("royalty out of range")
30	}
31	c.tokenRoyalty.Set(string(tid), royalty{recip: recip, bps: bps})
32	chain.Emit("TokenRoyaltySet", "collectionID", id, "tokenId", string(tid), "bps", itoa(bps), "recip", recip.String())
33}
34
35// ClearTokenRoyalty removes a per-token override; the token falls back to the
36// collection default. Admin only.
37func ClearTokenRoyalty(cur realm, id string, tid grc721.TokenID) {
38	c := mustGet(id)
39	assertCollectionAdmin(c)
40	c.tokenRoyalty.Remove(string(tid))
41	chain.Emit("TokenRoyaltyCleared", "collectionID", id, "tokenId", string(tid))
42}
43
44// resolveRoyalty returns the effective (recip, bps) for a token, applying the
45// frozen precedence: per-token override PRESENCE wins (even bps==0); else the
46// collection default.
47func resolveRoyalty(c *collection, tid grc721.TokenID) (address, int64) {
48	if v, ok := c.tokenRoyalty.Get(string(tid)); ok {
49		r := v.(royalty)
50		return r.recip, r.bps
51	}
52	return c.royaltyRecip, c.royaltyBPS
53}
54
55// RoyaltyInfo returns the royalty recipient and amount owed on a sale. Returns
56// ("", 0) when royalty is disabled for the token (bps==0 or recip==""). This
57// is a read; marketplace engines call it to settle royalties atomically.
58func RoyaltyInfo(id string, tid grc721.TokenID, salePrice int64) (address, int64) {
59	c := mustGet(id)
60	recip, bps := resolveRoyalty(c, tid)
61	if bps == 0 || recip == "" {
62		return "", 0
63	}
64	return recip, overflow.Mul64p(salePrice, bps) / 10000
65}