@@ -14,6 +14,49 @@ import {
1414} from "../utils/prophecySigil" ;
1515import type { ProphecySigilPayloadV1 } from "../types/prophecySigilTypes" ;
1616
17+ /* ──────────────────────────────────────────────────────────────────────────────
18+ ChakraDay coercion
19+ NOTE: KaiMoment (from marketTypes) does NOT include chakraDay — it's a minimal moment.
20+ So we define ChakraDay here (or import it from your canonical kai_pulse types).
21+ ────────────────────────────────────────────────────────────────────────────── */
22+ type ChakraDay =
23+ | "Root"
24+ | "Sacral"
25+ | "Solar Plexus"
26+ | "Heart"
27+ | "Throat"
28+ | "Third Eye"
29+ | "Crown" ;
30+
31+ function asChakraDay ( v : unknown ) : ChakraDay {
32+ const raw = String ( v ?? "" ) . trim ( ) ;
33+ const s = raw . toLowerCase ( ) . replace ( / [ - _ ] / g, " " ) . replace ( / \s + / g, " " ) ;
34+
35+ switch ( s ) {
36+ case "root" :
37+ return "Root" ;
38+ case "sacral" :
39+ return "Sacral" ;
40+ case "solar plexus" :
41+ case "solar" :
42+ case "plexus" :
43+ return "Solar Plexus" ;
44+ case "heart" :
45+ return "Heart" ;
46+ case "throat" :
47+ return "Throat" ;
48+ case "third eye" :
49+ case "third" :
50+ case "eye" :
51+ return "Third Eye" ;
52+ case "crown" :
53+ case "krown" :
54+ return "Crown" ;
55+ default :
56+ return "Root" ;
57+ }
58+ }
59+
1760const loadVkey = async ( ) : Promise < unknown | null > => {
1861 try {
1962 const res = await fetch ( "/zk/verification_key.json" , { cache : "no-store" } ) ;
@@ -34,7 +77,10 @@ export type ProphecySigilVerification = Readonly<{
3477 windowStatus : "open" | "closed" | "unknown" ;
3578} > ;
3679
37- export const useProphecySigilVerification = ( svg : string | undefined , now : KaiMoment ) : ProphecySigilVerification => {
80+ export const useProphecySigilVerification = (
81+ svg : string | undefined ,
82+ now : KaiMoment ,
83+ ) : ProphecySigilVerification => {
3884 const [ state , setState ] = useState < ProphecySigilVerification > ( {
3985 signatureOk : null ,
4086 zkOk : null ,
@@ -48,25 +94,30 @@ export const useProphecySigilVerification = (svg: string | undefined, now: KaiMo
4894 useEffect ( ( ) => {
4995 let cancelled = false ;
5096
97+ const reset = ( ) : void => {
98+ setState ( {
99+ signatureOk : null ,
100+ zkOk : null ,
101+ canonicalHashOk : null ,
102+ text : "" ,
103+ windowStatus : "unknown" ,
104+ } ) ;
105+ } ;
106+
51107 const run = async ( ) : Promise < void > => {
52108 if ( ! svgText ) {
53- if ( ! cancelled ) {
54- setState ( {
55- signatureOk : null ,
56- zkOk : null ,
57- canonicalHashOk : null ,
58- text : "" ,
59- windowStatus : "unknown" ,
60- } ) ;
61- }
109+ if ( ! cancelled ) reset ( ) ;
62110 return ;
63111 }
64112
65113 const parsed = parseProphecySigilSvg ( svgText ) ;
66114 const payload = parsed . payload ;
67- const text = typeof payload . text === "string" ? payload . text : parsed . textDecoded ?? "" ;
68115
69- const windowStatus =
116+ const textFromPayload = typeof payload . text === "string" ? payload . text : "" ;
117+ const textDecoded = parsed . textDecoded ?? "" ;
118+ const text = textFromPayload || textDecoded ;
119+
120+ const windowStatus : ProphecySigilVerification [ "windowStatus" ] =
70121 typeof payload . expirationPulse === "number"
71122 ? now . pulse >= payload . expirationPulse
72123 ? "closed"
@@ -79,7 +130,8 @@ export const useProphecySigilVerification = (svg: string | undefined, now: KaiMo
79130 : null ;
80131
81132 let canonicalHashOk : boolean | null = null ;
82- let canonicalHash : string | undefined = typeof payload . canonicalHash === "string" ? payload . canonicalHash : undefined ;
133+ let canonicalHash : string | undefined =
134+ typeof payload . canonicalHash === "string" ? payload . canonicalHash : undefined ;
83135
84136 const hasCoreFields =
85137 typeof payload . prophecyId === "string" &&
@@ -94,6 +146,16 @@ export const useProphecySigilVerification = (svg: string | undefined, now: KaiMo
94146 typeof payload . chakraDay === "string" ;
95147
96148 if ( hasCoreFields ) {
149+ // Build moment as a variable (assignable even if buildProphecyPayloadBase uses a narrower moment type)
150+ const moment = {
151+ pulse : payload . pulse ,
152+ beat : payload . beat ,
153+ stepIndex : payload . stepIndex ,
154+ stepPctAcrossBeat : payload . stepPct ,
155+ chakraDay : asChakraDay ( payload . chakraDay ) ,
156+ weekday : "Solhara" as const ,
157+ } ;
158+
97159 const base = buildProphecyPayloadBase ( {
98160 prophecyId : payload . prophecyId ,
99161 text : payload . text ,
@@ -104,18 +166,11 @@ export const useProphecySigilVerification = (svg: string | undefined, now: KaiMo
104166 evidence : payload . evidence ,
105167 userPhiKey : payload . userPhiKey ,
106168 kaiSignature : payload . kaiSignature ,
107- moment : {
108- pulse : payload . pulse ,
109- beat : payload . beat ,
110- stepIndex : payload . stepIndex ,
111- stepPctAcrossBeat : payload . stepPct ,
112- chakraDay : payload . chakraDay ,
113- weekday : "Solhara" ,
114- } ,
169+ moment,
115170 } ) ;
116171
117172 const computed = await computeProphecyCanonicalHash ( base ) ;
118- canonicalHashOk = canonicalHash ? canonicalHash . toLowerCase ( ) === computed : false ;
173+ canonicalHashOk = canonicalHash ? canonicalHash . toLowerCase ( ) === computed . toLowerCase ( ) : false ;
119174 canonicalHash = canonicalHash ?? computed ;
120175 }
121176
@@ -125,8 +180,10 @@ export const useProphecySigilVerification = (svg: string | undefined, now: KaiMo
125180 const zk = parsed . zk ?? ( payload . zk as ProphecySigilPayloadV1 [ "zk" ] | undefined ) ;
126181 if ( zk && zk . proof && zk . publicInputs && canonicalHash ) {
127182 zkScheme = zk . scheme ;
183+
128184 const poseidon = await computeZkPoseidonHash ( canonicalHash ) ;
129185 const publicInput0 = Array . isArray ( zk . publicInputs ) ? zk . publicInputs [ 0 ] : undefined ;
186+
130187 const binds =
131188 ( zk . poseidonHash ? zk . poseidonHash === poseidon . hash : true ) &&
132189 ( publicInput0 ? publicInput0 === poseidon . hash : true ) ;
@@ -152,7 +209,7 @@ export const useProphecySigilVerification = (svg: string | undefined, now: KaiMo
152209 zkScheme,
153210 canonicalHash,
154211 canonicalHashOk,
155- text : text || decodeProphecyText ( parsed . textDecoded ?? "" , payload . textEnc ) ,
212+ text : text || decodeProphecyText ( textDecoded , payload . textEnc ) ,
156213 windowStatus,
157214 } ) ;
158215 }
0 commit comments