main.mx raw

   1  package main
   2  
   3  // Verify Worker - BIP-340 Schnorr signature verification.
   4  //
   5  // Wire format:
   6  //   supervisor -> worker: ["V_CHECK", reqID, evJSON]
   7  //   worker -> supervisor: ["V_RESULT", reqID, 1|0]
   8  //
   9  // Pure compute: no IDB, no WebSocket, no signer access.
  10  // Four instances run in parallel; the Verify Supervisor distributes round-robin.
  11  
  12  import (
  13  	"git.smesh.lol/smesh/web/common/helpers"
  14  	"git.smesh.lol/smesh/web/common/jsbridge/verify"
  15  	"git.smesh.lol/smesh/web/common/nostr"
  16  	nosig "git.smesh.lol/smesh/web/common/nostr/sig"
  17  )
  18  
  19  func main() {
  20  	verify.WorkerOnMessage(handleMessage)
  21  }
  22  
  23  func handleMessage(msg string) {
  24  	w := newMW(msg)
  25  	if w.str() != "V_CHECK" {
  26  		return
  27  	}
  28  	reqID := w.num()
  29  	evJSON := w.raw()
  30  
  31  	ev := nostr.ParseEvent(evJSON)
  32  	var valid int64
  33  	if ev != nil && (*nosig.Event)(ev).CheckSig() {
  34  		valid = 1
  35  	}
  36  	verify.WorkerPost(`["V_RESULT",` | helpers.Itoa(reqID) | `,` | helpers.Itoa(valid) | `]`)
  37  }
  38  
  39  // mw: minimal JSON-array walker
  40  
  41  type mw struct {
  42  	s string
  43  	i int32
  44  }
  45  
  46  func newMW(s string) (v mw) {
  47  	w := mw{s: s}
  48  	for w.i < len(s) && s[w.i] != '[' {
  49  		w.i++
  50  	}
  51  	if w.i < len(s) {
  52  		w.i++
  53  	}
  54  	return w
  55  }
  56  
  57  func (w *mw) sep() {
  58  	for w.i < len(w.s) {
  59  		c := w.s[w.i]
  60  		if c != ' ' && c != '\n' && c != '\r' && c != '\t' && c != ',' {
  61  			break
  62  		}
  63  		w.i++
  64  	}
  65  }
  66  
  67  func (w *mw) str() (s string) {
  68  	w.sep()
  69  	if w.i >= len(w.s) || w.s[w.i] != '"' {
  70  		return ""
  71  	}
  72  	w.i++
  73  	start := w.i
  74  	for w.i < len(w.s) && w.s[w.i] != '"' {
  75  		if w.s[w.i] == '\\' {
  76  			w.i++
  77  		}
  78  		w.i++
  79  	}
  80  	if w.i >= len(w.s) {
  81  		return ""
  82  	}
  83  	result := w.s[start:w.i]
  84  	w.i++
  85  	return result
  86  }
  87  
  88  func (w *mw) num() (n int64) {
  89  	w.sep()
  90  	neg := false
  91  	if w.i < len(w.s) && w.s[w.i] == '-' {
  92  		neg = true
  93  		w.i++
  94  	}
  95  	var n int64
  96  	for w.i < len(w.s) && w.s[w.i] >= '0' && w.s[w.i] <= '9' {
  97  		n = n*10 + int64(w.s[w.i]-'0')
  98  		w.i++
  99  	}
 100  	if neg {
 101  		n = -n
 102  	}
 103  	return n
 104  }
 105  
 106  func (w *mw) raw() (s string) {
 107  	w.sep()
 108  	start := w.i
 109  	w.i = skipval(w.s, w.i)
 110  	if w.i < 0 {
 111  		w.i = len(w.s)
 112  		return ""
 113  	}
 114  	return w.s[start:w.i]
 115  }
 116  
 117  func skipval(s string, i int32) (n int32) {
 118  	if i >= len(s) {
 119  		return -1
 120  	}
 121  	c := s[i]
 122  	if c == '"' {
 123  		i++
 124  		for i < len(s) && s[i] != '"' {
 125  			if s[i] == '\\' {
 126  				i++
 127  			}
 128  			i++
 129  		}
 130  		if i >= len(s) {
 131  			return -1
 132  		}
 133  		return i + 1
 134  	}
 135  	if c == '{' || c == '[' {
 136  		open := c
 137  		close := byte('}')
 138  		if open == '[' {
 139  			close = ']'
 140  		}
 141  		depth := 1
 142  		i++
 143  		for i < len(s) && depth > 0 {
 144  			if s[i] == '"' {
 145  				i++
 146  				for i < len(s) && s[i] != '"' {
 147  					if s[i] == '\\' {
 148  						i++
 149  					}
 150  					i++
 151  				}
 152  				if i >= len(s) {
 153  					return -1
 154  				}
 155  				i++
 156  				continue
 157  			}
 158  			if s[i] == open {
 159  				depth++
 160  			} else if s[i] == close {
 161  				depth--
 162  				if depth == 0 {
 163  					return i + 1
 164  				}
 165  			}
 166  			i++
 167  		}
 168  		return -1
 169  	}
 170  	for i < len(s) {
 171  		c := s[i]
 172  		if c == ',' || c == ']' || c == '}' {
 173  			return i
 174  		}
 175  		i++
 176  	}
 177  	return i
 178  }
 179