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

appstore_actions.gno

4.87 Kb · 136 lines
  1package memba_weighted_host
  2
  3import (
  4	"chain"
  5	"gno.land/p/samcrew/memba_weighted_policy"
  6	"strconv"
  7	"strings"
  8)
  9
 10const AppstorePath = "gno.land/r/samcrew/memba_appstore_v3"
 11const AppstoreMaxFee = int64(100000000)
 12
 13type AppstoreKind string
 14
 15const (
 16	AppstoreAccept        AppstoreKind = "accept-owner"
 17	AppstoreReturn        AppstoreKind = "return-owner"
 18	AppstoreAbortReturn   AppstoreKind = "abort-return"
 19	AppstoreAddCurator    AppstoreKind = "add-curator"
 20	AppstoreRemoveCurator AppstoreKind = "remove-curator"
 21	AppstoreFee           AppstoreKind = "set-fee"
 22	AppstoreTreasury      AppstoreKind = "set-treasury"
 23	AppstoreUnpause       AppstoreKind = "unpause"
 24	AppstoreSeal          AppstoreKind = "seal-import"
 25	AppstoreApprove       AppstoreKind = "approve"
 26	AppstoreReject        AppstoreKind = "reject"
 27	AppstoreDelist        AppstoreKind = "delist"
 28	AppstoreRestore       AppstoreKind = "restore"
 29	AppstoreClearFlags    AppstoreKind = "clear-flags"
 30)
 31
 32type AppstorePolicy struct{ dao, successor, treasury address }
 33
 34func NewAppstorePolicy(dao, successor, treasury address) AppstorePolicy {
 35	if dao != chain.PackageAddress("gno.land/r/samcrew/memba_dao") {
 36		panic("appstore policy requires the founding DAO address")
 37	}
 38	for _, a := range []address{successor, treasury} {
 39		if !a.IsValid() || a == dao || a == chain.PackageAddress(AppstorePath) {
 40			panic("appstore destination must be valid and distinct from DAO and target")
 41		}
 42	}
 43	return AppstorePolicy{dao, successor, treasury}
 44}
 45func (p AppstorePolicy) DAO() address       { return p.dao }
 46func (p AppstorePolicy) Successor() address { return p.successor }
 47func (p AppstorePolicy) Treasury() address  { return p.treasury }
 48
 49type AppstoreAction struct {
 50	kind         AppstoreKind
 51	recipient    address
 52	fee          int64
 53	path, reason string
 54}
 55
 56func (p AppstorePolicy) Accept() AppstoreAction { return AppstoreAction{kind: AppstoreAccept} }
 57func (p AppstorePolicy) Return() AppstoreAction {
 58	return AppstoreAction{kind: AppstoreReturn, recipient: p.successor}
 59}
 60func (p AppstorePolicy) AbortReturn() AppstoreAction {
 61	return AppstoreAction{kind: AppstoreAbortReturn, recipient: p.successor}
 62}
 63func (p AppstorePolicy) SetTreasury() AppstoreAction {
 64	return AppstoreAction{kind: AppstoreTreasury, recipient: p.treasury}
 65}
 66func AppstoreCurator(who address, grant bool) AppstoreAction {
 67	k := AppstoreRemoveCurator
 68	if grant {
 69		k = AppstoreAddCurator
 70	}
 71	a := AppstoreAction{kind: k, recipient: who}
 72	a.Bytes()
 73	return a
 74}
 75func AppstoreRegistrationFee(fee int64) AppstoreAction {
 76	a := AppstoreAction{kind: AppstoreFee, fee: fee}
 77	a.Bytes()
 78	return a
 79}
 80func AppstoreResume() AppstoreAction     { return AppstoreAction{kind: AppstoreUnpause} }
 81func AppstoreSealImport() AppstoreAction { return AppstoreAction{kind: AppstoreSeal} }
 82func AppstoreModeration(kind AppstoreKind, path, reason string) AppstoreAction {
 83	a := AppstoreAction{kind: kind, path: path, reason: reason}
 84	if !a.IsListing() {
 85		panic("unsupported appstore moderation")
 86	}
 87	a.Bytes()
 88	return a
 89}
 90func (a AppstoreAction) Kind() AppstoreKind { return a.kind }
 91func (a AppstoreAction) Recipient() address { return a.recipient }
 92func (a AppstoreAction) Fee() int64         { return a.fee }
 93func (a AppstoreAction) Path() string       { return a.path }
 94func (a AppstoreAction) Reason() string     { return a.reason }
 95func (a AppstoreAction) IsListing() bool {
 96	return a.kind == AppstoreApprove || a.kind == AppstoreReject || a.kind == AppstoreDelist || a.kind == AppstoreRestore || a.kind == AppstoreClearFlags
 97}
 98func (a AppstoreAction) Bytes() string {
 99	if a.IsListing() {
100		if a.recipient != "" || a.fee != 0 || len(a.path) > 200 || !(strings.HasPrefix(a.path, "gno.land/r/") || strings.HasPrefix(a.path, "gno.land/p/")) || len(a.reason) > 500 || (a.kind != AppstoreReject && a.reason != "") {
101			panic("invalid appstore moderation")
102		}
103	} else {
104		if a.path != "" || a.reason != "" {
105			panic("malformed appstore action")
106		}
107		switch a.kind {
108		case AppstoreAccept, AppstoreUnpause, AppstoreSeal:
109			if a.recipient != "" || a.fee != 0 {
110				panic("malformed appstore action")
111			}
112		case AppstoreReturn, AppstoreAbortReturn, AppstoreTreasury, AppstoreAddCurator, AppstoreRemoveCurator:
113			if !a.recipient.IsValid() || a.fee != 0 {
114				panic("invalid appstore recipient")
115			}
116		case AppstoreFee:
117			if a.recipient != "" || a.fee < 0 || a.fee > AppstoreMaxFee {
118				panic("invalid appstore fee")
119			}
120		default:
121			panic("unsupported appstore action")
122		}
123	}
124	return "appstore/v1|" + AppstorePath + "|" + quoteJSON(string(a.kind)) + "|" + quoteJSON(string(a.recipient)) + "|" + strconv.FormatInt(a.fee, 10) + "|" + quoteJSON(a.path) + "|" + quoteJSON(a.reason)
125}
126func (a AppstoreAction) Category() memba_weighted_policy.Category {
127	a.Bytes()
128	if a.IsListing() {
129		return memba_weighted_policy.Routine
130	}
131	switch a.kind {
132	case AppstoreFee, AppstoreTreasury, AppstoreUnpause:
133		return memba_weighted_policy.Financial
134	}
135	return memba_weighted_policy.Critical
136}