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