← Back to Realms

Realm

gno.land/r/g1wx60nkcp5lfsxmedeg7sfs47tzxkath05u63t4/trialmint2/campaign

Overview

Realm Path
gno.land/r/g1wx60nkcp5lfsxmedeg7sfs47tzxkath05u63t4/trialmint2/campaign
Exported Functions
9
State Entries
4
Source Files
2
Total Package Entries
19

Exported Functions

9 exported functions

State

4 state entries

Source Code

FILES
campaign.gno
go
1package campaign
2
3import (
4	unsaferealm "chain/runtime/unsafe"
5	"strings"
6
7	"gno.land/p/nt/avl/v0"
8)
9
10var (
11	collectionOwner  address = "g1wx60nkcp5lfsxmedeg7sfs47tzxkath05u63t4"
12	approvedConsumer string
13	entries          avl.Tree // wallet.String() -> *entry
14)
15
16type entry struct {
17	Bps           int64
18	RemainingUses int64
19}
20
21func callerAddress() address {
22	return unsaferealm.PreviousRealm().Address()
23}
24
25func assertOwner() {
26	if callerAddress() != collectionOwner {
27		panic("unauthorized: caller is not the collection owner")
28	}
29}
30
31func SetApprovedConsumer(cur realm, pkgpath string) {
32	assertOwner()
33	approvedConsumer = pkgpath
34}
35
36func validateBps(bps int64) {
37	if bps < 0 || bps > 10000 {
38		panic("bps must be between 0 and 10000")
39	}
40}
41
42func validateMaxUses(maxUses int64) {
43	if maxUses <= 0 {
44		panic("maxUses must be positive")
45	}
46}
47
48func grantOne(wallet string, bps int64, maxUses int64) {
49	if raw := entries.Get(wallet); raw != nil {
50		if e, ok := raw.(*entry); ok {
51			e.RemainingUses += maxUses
52			if bps < e.Bps {
53				e.Bps = bps
54			}
55			entries.Set(wallet, e)
56			return
57		}
58	}
59	entries.Set(wallet, &entry{Bps: bps, RemainingUses: maxUses})
60}
61
62func AddWallet(cur realm, wallet address, bps int64, maxUses int64) {
63	assertOwner()
64	validateBps(bps)
65	validateMaxUses(maxUses)
66	grantOne(wallet.String(), bps, maxUses)
67}
68
69func AddWalletsBatch(cur realm, walletsCSV string, bps int64, maxUses int64) {
70	assertOwner()
71	validateBps(bps)
72	validateMaxUses(maxUses)
73	for _, w := range strings.Split(walletsCSV, ",") {
74		w = strings.TrimSpace(w)
75		if w == "" {
76			continue
77		}
78		grantOne(w, bps, maxUses)
79	}
80}
81
82func RemoveWallet(cur realm, wallet address) {
83	assertOwner()
84	entries.Remove(wallet.String())
85}
86
87func RemoveWalletsBatch(cur realm, walletsCSV string) {
88	assertOwner()
89	for _, w := range strings.Split(walletsCSV, ",") {
90		w = strings.TrimSpace(w)
91		if w == "" {
92			continue
93		}
94		entries.Remove(w)
95	}
96}
97
98func assertCallerIsApprovedConsumer(cur realm) {
99	caller := cur.Previous().PkgPath()
100	if approvedConsumer == "" || caller != approvedConsumer {
101		panic("unauthorized: caller is not the approved consumer realm")
102	}
103}
104
105func Peek(wallet address) (bps int64, remainingUses int64, ok bool) {
106	raw := entries.Get(wallet.String())
107	e, isEntry := raw.(*entry)
108	if !isEntry {
109		return 0, 0, false
110	}
111	return e.Bps, e.RemainingUses, true
112}
113
114func ConsumeDiscount(cur realm, wallet address) (bps int64, ok bool) {
115	assertCallerIsApprovedConsumer(cur)
116	raw := entries.Get(wallet.String())
117	e, isEntry := raw.(*entry)
118	if !isEntry {
119		return 0, false
120	}
121	e.RemainingUses--
122	if e.RemainingUses <= 0 {
123		entries.Remove(wallet.String())
124	} else {
125		entries.Set(wallet.String(), e)
126	}
127	return e.Bps, true
128}
129
130func Count() int64 { return int64(entries.Size()) }
131
132func EntryAt(index int) (wallet string, bps int64, remainingUses int64) {
133	w, v := entries.GetByIndex(index)
134	e := v.(*entry)
135	return w, e.Bps, e.RemainingUses
136}
137

Raw Package Data

Raw JSON data