1package accesscontrol23import "chain/runtime/unsafe"45// AuthCheck must be owned by the calling realm/package.6// Do not pass callbacks received from untrusted callers.7type AuthCheck func(address) bool89func AssertCurrentRealm(_ int, rlm realm) {10 if !rlm.IsCurrent() {11 panic("spoofed realm")12 }13}1415func AssertIsAdmin(_ int, rlm realm, isAdmin AuthCheck) {16 MustGetAdminCaller(0, rlm, isAdmin)17}1819func MustGetAdminCaller(_ int, rlm realm, isAdmin AuthCheck) address {20 assertAuthCheck(isAdmin, "admin auth check is nil")21 AssertCurrentRealm(0, rlm)2223 caller := rlm.Previous().Address()24 if !isAdmin(caller) {25 panic("admin access required")26 }27 return caller28}2930func MustGetUserCaller(_ int, rlm realm) address {31 AssertCurrentRealm(0, rlm)3233 prev := rlm.Previous()34 if !prev.IsUserCall() {35 panic("contract calls not allowed: function must be called directly by user")36 }37 return prev.Address()38}3940// AssertIsAdminOrigin checks the transaction signer, not the direct caller realm.41// Use it only for explicit delegation APIs that intentionally allow code-realm relays.42func AssertIsAdminOrigin(isAdmin AuthCheck) {43 MustGetAdminOrigin(isAdmin)44}4546// MustGetAdminOrigin checks the transaction signer, not the direct caller realm.47// Use it only for explicit delegation APIs that intentionally allow code-realm relays.48func MustGetAdminOrigin(isAdmin AuthCheck) address {49 assertAuthCheck(isAdmin, "admin auth check is nil")5051 caller := unsafe.OriginCaller()52 if !isAdmin(caller) {53 panic("admin access required")54 }55 return caller56}5758func AssertIsAdminOrOperator(_ int, rlm realm, isAdmin AuthCheck, isOperator AuthCheck) {59 MustGetAdminOrOperatorCaller(0, rlm, isAdmin, isOperator)60}6162func MustGetAdminOrOperatorCaller(_ int, rlm realm, isAdmin AuthCheck, isOperator AuthCheck) address {63 assertAuthCheck(isAdmin, "admin auth check is nil")64 assertAuthCheck(isOperator, "operator auth check is nil")65 AssertCurrentRealm(0, rlm)6667 caller := rlm.Previous().Address()68 if !isAdmin(caller) && !isOperator(caller) {69 panic("admin or operator access required")70 }71 return caller72}7374func assertAuthCheck(check AuthCheck, msg string) {75 if check == nil {76 panic(msg)77 }78}79Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.