Search Apps Documentation Source Content File Folder Download Copy Actions Download

telescope.gno

4.76 Kb · 129 lines
  1package telescope
  2
  3import (
  4	"chain"
  5	"strconv"
  6
  7	ns "gno.land/p/nym-vikbez000/nightsky0"
  8	registry "gno.land/r/nym-vikbez000/nightsky0"
  9)
 10
 11var telescope *ns.TelescopeRealm
 12
 13func init(cur realm) {
 14	owner := "g13kytw9mpyutwmyg5eq7arqxqcszfl6uq4p89zg"
 15
 16	config := ns.NewTelescopeConfig(
 17		"vik telescope", // name
 18		"Seestar S30",   // model
 19
 20		// Do not use too precise coordinates to keep some privacy
 21		49.02, // latitude
 22		1.15,  // longitude
 23		owner,
 24		cur.PkgPath(),
 25	)
 26
 27	telescope = ns.NewTelescopeRealm(&config)
 28	telescope.Config.UpdateStatus("online")
 29	registry.Register(cross(cur), config)
 30}
 31
 32func Render(path string) string {
 33	return telescope.RenderNightsky(path)
 34}
 35
 36// Identity note: access control is keyed by the immediate caller via
 37// cur.Previous().Address() — the statically-scoped realm handle, not the
 38// stack-walking tx-origin. For a direct `gnokey maketx call` this resolves to
 39// the signing EOA (matching the address-keyed access list); a call routed
 40// through an intermediary realm is identified as that realm and denied unless
 41// explicitly granted. This is the phishing-resistant pattern recommended in
 42// gno-interrealm.md, and avoids the chain/runtime/unsafe primitives entirely.
 43
 44// SubmitCommand allows authorized users to submit telescope commands.
 45// commandType: "capture" or "stop"
 46// targetRA: Right Ascension in hours (0-24), leave empty for stop
 47// targetDec: Declination in degrees (-90 to 90), leave empty for stop
 48// exposure: Exposure time in seconds (1-300), leave empty for stop
 49func SubmitCommand(cur realm, commandType, targetRA, targetDec, exposure string) {
 50	caller := cur.Previous().Address().String()
 51
 52	var ra, dec float64
 53	var exp int
 54	if commandType == "capture" {
 55		// Reject malformed numbers instead of silently treating them as 0,
 56		// which would otherwise pass coordinate validation.
 57		var err error
 58		if ra, err = strconv.ParseFloat(targetRA, 64); err != nil {
 59			panic("invalid RA: must be a number")
 60		}
 61		if dec, err = strconv.ParseFloat(targetDec, 64); err != nil {
 62			panic("invalid Dec: must be a number")
 63		}
 64		if exp, err = strconv.Atoi(exposure); err != nil {
 65			panic("invalid exposure: must be an integer")
 66		}
 67	}
 68
 69	telescope.SubmitCommand(caller, commandType, ra, dec, exp)
 70	chain.Emit("CommandSubmitted", "type", commandType, "requester", caller)
 71}
 72
 73// GrantAccess allows the owner to grant access to another user.
 74// durationDays: 0 = never expires
 75func GrantAccess(cur realm, address string, durationDays int) {
 76	caller := cur.Previous().Address().String()
 77	telescope.GrantAccess(caller, address, durationDays)
 78	chain.Emit("AccessGranted", "address", address, "durationDays", strconv.Itoa(durationDays))
 79}
 80
 81// RevokeAccess allows the owner to revoke access from a user.
 82func RevokeAccess(cur realm, address string) {
 83	caller := cur.Previous().Address().String()
 84	telescope.RevokeAccess(caller, address)
 85	chain.Emit("AccessRevoked", "address", address)
 86}
 87
 88// GetNextCommand returns and removes the next command from the queue.
 89// Called by the telescope controller.
 90func GetNextCommand(cur realm) ns.TelescopeCommand {
 91	caller := cur.Previous().Address().String()
 92	return telescope.GetNextCommand(caller)
 93}
 94
 95// UpdateStatus updates the telescope status locally and in the NightSky registry.
 96// Valid values: "online", "offline", "busy", "error"
 97func UpdateStatus(cur realm, status string) {
 98	switch status {
 99	case "online", "offline", "busy", "error":
100	default:
101		panic("invalid status: must be online, offline, busy, or error")
102	}
103	caller := cur.Previous().Address().String()
104	telescope.UpdateStatus(caller, status)
105	registry.UpdateTelescopeStatus(cross(cur), status)
106}
107
108// RecordCapture records a capture result locally and submits it to the NightSky network feed.
109func RecordCapture(cur realm, imageURL string, targetRA, targetDec float64, exposure int, capturedBy string) {
110	caller := cur.Previous().Address().String()
111	telescope.RecordCapture(caller, imageURL, targetRA, targetDec, exposure, capturedBy)
112	registry.SubmitCapture(cross(cur), imageURL, targetRA, targetDec, exposure, capturedBy)
113	chain.Emit("CaptureRecorded", "imageURL", imageURL, "capturedBy", capturedBy)
114}
115
116// ClearCommandQueue clears all pending commands (emergency stop).
117func ClearCommandQueue(cur realm) {
118	caller := cur.Previous().Address().String()
119	telescope.ClearCommandQueue(caller)
120	chain.Emit("CommandQueueCleared", "by", caller)
121}
122
123func GetCommandCount() int      { return telescope.GetCommandCount() }
124func GetCaptureCount() int      { return telescope.GetCaptureCount() }
125func GetAccessRuleCount() int   { return telescope.GetAccessRuleCount() }
126func GetStatus() string         { return telescope.Config.Status }
127func GetTelescopeName() string  { return telescope.Config.Name }
128func GetTelescopeModel() string { return telescope.Config.Model }
129func GetOwner() string          { return telescope.OwnerAddress }