Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

admins.gno

1.93 Kb · 64 lines
 1// Package admins lets a fixed set of addresses change a realm's gnotif
 2// triggers. The realm passes the handle gnotif.Open returned straight to New,
 3// keeps the *Admins unexported, and on each call gives its gnotif identity,
 4// minted in the crossing function the admin called.
 5package admins
 6
 7import (
 8	"chain/runtime"
 9
10	"gno.land/p/g13rqvks880v0hmlfepcj0kkudq0js38d3pc5k6a/gnotif/trigger/v0"
11)
12
13// Handle is the method set of the registry's *Handle.
14type Handle interface {
15	Set(cur realm, name string, t trigger.Trigger) string
16	Remove(cur realm, name string)
17}
18
19// Admins holds a realm's handle and the addresses allowed to use it.
20type Admins struct {
21	h      Handle
22	admins map[address]bool
23}
24
25// New returns an Admins over the handle h. It panics with no admin.
26func New(h Handle, addrs ...address) *Admins {
27	if len(addrs) == 0 {
28		panic("at least one admin")
29	}
30	a := &Admins{h: h, admins: make(map[address]bool, len(addrs))}
31	for _, addr := range addrs {
32		if !addr.IsValid() {
33			panic("invalid admin address " + addr.String())
34		}
35		a.admins[addr] = true
36	}
37	return a
38}
39
40// Set stores t under name and returns its id, when the realm's caller is an
41// admin. me is the realm's gnotif identity, cur.Sub(gnotif.Subpath), and its
42// Previous is the caller.
43func (a *Admins) Set(_ int, me realm, name string, t trigger.Trigger) string {
44	a.mustAdmin(0, me)
45	return a.h.Set(cross(me), name, t)
46}
47
48// Remove removes the trigger under name, when the realm's caller is an admin.
49func (a *Admins) Remove(_ int, me realm, name string) {
50	a.mustAdmin(0, me)
51	a.h.Remove(cross(me), name)
52}
53
54func (a *Admins) mustAdmin(_ int, me realm) {
55	if !me.IsCurrent() {
56		panic("me is not current: mint it in the crossing function the admin called")
57	}
58	if _, _, _, isSession := runtime.GetSessionInfo(); isSession {
59		panic("sign with your own key, not a session key")
60	}
61	if caller := me.Previous().Address(); !a.admins[caller] {
62		panic(caller.String() + " is not an admin")
63	}
64}