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}