@@ -3,12 +3,19 @@ import swagger from "@fastify/swagger";
33import swaggerUi from "@fastify/swagger-ui" ;
44import { W3ID } from "../w3id/w3id" ;
55import { LogEvent } from "w3id" ;
6- import {
7- WatcherSignatureRequest ,
8- WatcherRequest ,
9- TypedRequest ,
10- TypedReply ,
11- } from "./types" ;
6+ import axios from "axios" ;
7+ import { WatcherRequest , TypedRequest , TypedReply } from "./types" ;
8+ import { verifierCallback } from "../utils/signer" ;
9+
10+ interface WatcherSignatureRequest {
11+ w3id : string ;
12+ logEntryId : string ;
13+ proof : {
14+ signature : string ;
15+ alg : string ;
16+ kid : string ;
17+ } ;
18+ }
1219
1320export async function registerHttpRoutes (
1421 server : FastifyInstance
@@ -98,11 +105,19 @@ export async function registerHttpRoutes(
98105 description : "Post a signature for a specific log entry" ,
99106 body : {
100107 type : "object" ,
101- required : [ "w3id" , "signature " , "logEntryId " ] ,
108+ required : [ "w3id" , "logEntryId " , "proof " ] ,
102109 properties : {
103110 w3id : { type : "string" } ,
104- signature : { type : "string" } ,
105111 logEntryId : { type : "string" } ,
112+ proof : {
113+ type : "object" ,
114+ required : [ "signature" , "alg" , "kid" ] ,
115+ properties : {
116+ signature : { type : "string" } ,
117+ alg : { type : "string" } ,
118+ kid : { type : "string" } ,
119+ } ,
120+ } ,
106121 } ,
107122 } ,
108123 response : {
@@ -120,12 +135,51 @@ export async function registerHttpRoutes(
120135 request : TypedRequest < WatcherSignatureRequest > ,
121136 reply : TypedReply
122137 ) => {
123- const { w3id, signature, logEntryId } = request . body ;
124- // TODO: Implement signature verification and storage
125- return {
126- success : true ,
127- message : "Signature stored successfully" ,
128- } ;
138+ const { w3id, logEntryId, proof } = request . body ;
139+
140+ try {
141+ const currentW3ID = await W3ID . get ( ) ;
142+ if ( ! currentW3ID . logs ) {
143+ throw new Error ( "W3ID must have logs enabled" ) ;
144+ }
145+
146+ const logEvent = await currentW3ID . logs . repository . findOne ( {
147+ versionId : logEntryId ,
148+ } ) ;
149+ if ( ! logEvent ) {
150+ throw new Error ( `Log event not found with id ${ logEntryId } ` ) ;
151+ }
152+
153+ const isValid = await verifierCallback (
154+ logEntryId ,
155+ [ proof ] ,
156+ proof . kid . split ( "#" ) [ 0 ]
157+ ) ;
158+ if ( ! isValid ) {
159+ throw new Error ( "Invalid signature" ) ;
160+ }
161+
162+ const updatedLogEvent : LogEvent = {
163+ ...logEvent ,
164+ proofs : [ ...( logEvent . proofs || [ ] ) , proof ] ,
165+ } ;
166+
167+ await currentW3ID . logs . repository . create ( updatedLogEvent ) ;
168+
169+ return {
170+ success : true ,
171+ message : "Signature stored successfully" ,
172+ } ;
173+ } catch ( error ) {
174+ console . error ( "Error storing signature:" , error ) ;
175+ return {
176+ success : false ,
177+ message :
178+ error instanceof Error
179+ ? error . message
180+ : "Failed to store signature" ,
181+ } ;
182+ }
129183 }
130184 ) ;
131185
@@ -158,12 +212,54 @@ export async function registerHttpRoutes(
158212 } ,
159213 async ( request : TypedRequest < WatcherRequest > , reply : TypedReply ) => {
160214 const { w3id, logEntryId } = request . body ;
161- // TODO: Implement signature request logic
162- return {
163- success : true ,
164- message : "Signature request created" ,
165- requestId : "req_" + Date . now ( ) ,
166- } ;
215+
216+ try {
217+ // Resolve the W3ID to get its request endpoint
218+ const registryResponse = await axios . get (
219+ `http://localhost:4321/resolve?w3id=${ w3id } `
220+ ) ;
221+ const { requestWatcherSignature } = registryResponse . data ;
222+
223+ // Get the current W3ID instance
224+ const currentW3ID = await W3ID . get ( ) ;
225+ if ( ! currentW3ID . logs ) {
226+ throw new Error ( "W3ID must have logs enabled" ) ;
227+ }
228+
229+ // Find the log event
230+ const logEvent = await currentW3ID . logs . repository . findOne ( {
231+ versionId : logEntryId ,
232+ } ) ;
233+ if ( ! logEvent ) {
234+ throw new Error ( `Log event not found with id ${ logEntryId } ` ) ;
235+ }
236+
237+ // Request signature from the watcher
238+ const response = await axios . post ( requestWatcherSignature , {
239+ w3id : currentW3ID . id ,
240+ logEntryId,
241+ signature : await currentW3ID . signJWT ( {
242+ sub : logEntryId ,
243+ exp : Date . now ( ) + 3600 * 1000 , // 1 hour expiry
244+ } ) ,
245+ } ) ;
246+
247+ return {
248+ success : true ,
249+ message : "Signature request created" ,
250+ requestId : response . data . requestId ,
251+ } ;
252+ } catch ( error ) {
253+ console . error ( "Error requesting signature:" , error ) ;
254+ return {
255+ success : false ,
256+ message :
257+ error instanceof Error
258+ ? error . message
259+ : "Failed to request signature" ,
260+ requestId : "" ,
261+ } ;
262+ }
167263 }
168264 ) ;
169265}
0 commit comments