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

quest_actions.gno

2.73 Kb · 89 lines
 1package memba_weighted_host
 2
 3import (
 4	"chain"
 5	"encoding/hex"
 6	"gno.land/p/samcrew/memba_weighted_policy"
 7)
 8
 9const QuestPath = "gno.land/r/samcrew/memba_quest_attestation_v1"
10
11type QuestActionKind string
12
13const (
14	QuestAcceptOwner QuestActionKind = "accept-owner"
15	QuestSetSigner   QuestActionKind = "set-signer"
16	QuestReturnOwner QuestActionKind = "return-owner"
17	QuestAbortReturn QuestActionKind = "abort-return"
18)
19
20type QuestPolicy struct{ dao, successor address }
21
22func NewQuestPolicy(dao, successor address) QuestPolicy {
23	if !dao.IsValid() || dao != chain.PackageAddress("gno.land/r/samcrew/memba_dao") {
24		panic("quest policy requires the founding DAO address")
25	}
26	if !successor.IsValid() || successor == dao || successor == chain.PackageAddress(QuestPath) {
27		panic("quest policy requires a valid distinct successor")
28	}
29	return QuestPolicy{dao: dao, successor: successor}
30}
31func (p QuestPolicy) DAO() address       { return p.dao }
32func (p QuestPolicy) Successor() address { return p.successor }
33
34type QuestAction struct {
35	kind      QuestActionKind
36	key       string
37	recipient address
38}
39
40func (p QuestPolicy) Accept() QuestAction { return QuestAction{kind: QuestAcceptOwner} }
41func (p QuestPolicy) Return() QuestAction {
42	return QuestAction{kind: QuestReturnOwner, recipient: p.successor}
43}
44func (p QuestPolicy) AbortReturn() QuestAction {
45	return QuestAction{kind: QuestAbortReturn, recipient: p.successor}
46}
47func QuestSigner(key string) QuestAction {
48	a := QuestAction{kind: QuestSetSigner, key: key}
49	a.Bytes()
50	return a
51}
52func (a QuestAction) Kind() QuestActionKind { return a.kind }
53func (a QuestAction) Key() string           { return a.key }
54func (a QuestAction) Recipient() address    { return a.recipient }
55func canonicalQuestKey(key string) bool {
56	if len(key) != 64 {
57		return false
58	}
59	decoded, err := hex.DecodeString(key)
60	return err == nil && len(decoded) == 32 && hex.EncodeToString(decoded) == key
61}
62func (a QuestAction) Bytes() string {
63	base := "quest/v1|" + QuestPath + "|" + string(a.kind)
64	switch a.kind {
65	case QuestAcceptOwner:
66		if a.key != "" || a.recipient != "" {
67			panic("malformed quest accept action")
68		}
69		return base
70	case QuestSetSigner:
71		if !canonicalQuestKey(a.key) || a.recipient != "" {
72			panic("quest signer requires canonical 32-byte hex")
73		}
74		return base + "|" + a.key
75	case QuestReturnOwner, QuestAbortReturn:
76		if a.key != "" || !a.recipient.IsValid() {
77			panic("malformed quest return action")
78		}
79		return base + "|" + string(a.recipient)
80	default:
81		panic("unsupported quest action")
82	}
83}
84func (a QuestAction) Category() memba_weighted_policy.Category {
85	a.Bytes()
86	// Replacing the voucher-issuing key transfers attestation authority.
87	// It cannot be disguised as a routine content change.
88	return memba_weighted_policy.Critical
89}