@@ -11,6 +11,7 @@ import { hash } from "../utils/hash";
1111import {
1212 isGenesisOptions ,
1313 isRotationOptions ,
14+ type Signer ,
1415 type CreateLogEventOptions ,
1516 type GenesisLogOptions ,
1617 type LogEvent ,
@@ -28,15 +29,25 @@ import type { StorageSpec } from "./storage/storage-spec";
2829
2930export class IDLogManager {
3031 repository : StorageSpec < LogEvent , LogEvent > ;
32+ signer : Signer ;
3133
32- constructor ( repository : StorageSpec < LogEvent , LogEvent > ) {
34+ constructor ( repository : StorageSpec < LogEvent , LogEvent > , signer : Signer ) {
3335 this . repository = repository ;
36+ this . signer = signer ;
3437 }
3538
39+ /**
40+ * Validate a chain of W3ID logs
41+ *
42+ * @param {LogEvent[] } log
43+ * @param {VerifierCallback } verifyCallback
44+ * @returns {Promise<true> }
45+ */
46+
3647 static async validateLogChain (
3748 log : LogEvent [ ] ,
3849 verifyCallback : VerifierCallback ,
39- ) {
50+ ) : Promise < true > {
4051 let currIndex = 0 ;
4152 let currentNextKeyHashesSeen : string [ ] = [ ] ;
4253 let lastUpdateKeysSeen : string [ ] = [ ] ;
@@ -71,11 +82,19 @@ export class IDLogManager {
7182 return true ;
7283 }
7384
85+ /**
86+ * Validate cryptographic signature on a single LogEvent
87+ *
88+ * @param {LogEvent } e
89+ * @param {string[] } currentUpdateKeys
90+ * @param {VerifierCallback } verifyCallback
91+ * @returns {Promise<void> }
92+ */
7493 private static async verifyLogEventProof (
7594 e : LogEvent ,
7695 currentUpdateKeys : string [ ] ,
7796 verifyCallback : VerifierCallback ,
78- ) {
97+ ) : Promise < void > {
7998 const proof = e . proof ;
8099 const copy = JSON . parse ( JSON . stringify ( e ) ) ;
81100 // biome-ignore lint/performance/noDelete: we need to delete proof completely
@@ -94,8 +113,15 @@ export class IDLogManager {
94113 if ( ! verified ) throw new BadSignatureError ( ) ;
95114 }
96115
116+ /**
117+ * Append a new log entry for a W3ID
118+ *
119+ * @param {LogEvent[] } entries
120+ * @param {RotationLogOptions } options
121+ * @returns Promise<LogEvent>
122+ */
97123 private async appendEntry ( entries : LogEvent [ ] , options : RotationLogOptions ) {
98- const { signer , nextKeyHashes, nextKeySigner } = options ;
124+ const { nextKeyHashes, nextKeySigner } = options ;
99125 const latestEntry = entries [ entries . length - 1 ] ;
100126 const logHash = await hash ( latestEntry ) ;
101127 const index = Number ( latestEntry . versionId . split ( "-" ) [ 0 ] ) + 1 ;
@@ -113,30 +139,44 @@ export class IDLogManager {
113139 method : "w3id:v0.0.0" ,
114140 } ;
115141
116- const proof = await signer . sign ( canonicalize ( logEvent ) as string ) ;
142+ const proof = await this . signer . sign ( canonicalize ( logEvent ) as string ) ;
117143 logEvent . proof = proof ;
118144
119145 await this . repository . create ( logEvent ) ;
146+ this . signer = nextKeySigner ;
120147 return logEvent ;
121148 }
122149
150+ /**
151+ * Create genesis entry for a W3ID log
152+ *
153+ * @param {GenesisLogOptions } options
154+ * @returns Promise<LogEvent>
155+ */
123156 private async createGenesisEntry ( options : GenesisLogOptions ) {
124- const { id, nextKeyHashes, signer } = options ;
157+ const { id, nextKeyHashes } = options ;
158+ const idTag = id . includes ( "@" ) ? id . split ( "@" ) [ 1 ] : id ;
125159 const logEvent : LogEvent = {
126160 id,
127- versionId : `0-${ id . split ( "@" ) [ 1 ] } ` ,
161+ versionId : `0-${ idTag } ` ,
128162 versionTime : new Date ( Date . now ( ) ) ,
129- updateKeys : [ signer . pubKey ] ,
163+ updateKeys : [ this . signer . pubKey ] ,
130164 nextKeyHashes : nextKeyHashes ,
131165 method : "w3id:v0.0.0" ,
132166 } ;
133- const proof = await signer . sign ( canonicalize ( logEvent ) as string ) ;
167+ const proof = await this . signer . sign ( canonicalize ( logEvent ) as string ) ;
134168 logEvent . proof = proof ;
135169 await this . repository . create ( logEvent ) ;
136170 return logEvent ;
137171 }
138172
139- async createLogEvent ( options : CreateLogEventOptions ) {
173+ /**
174+ * Create a log event and save it to the repository
175+ *
176+ * @param {CreateLogEventOptions } options
177+ * @returns Promise<LogEvent>
178+ */
179+ async createLogEvent ( options : CreateLogEventOptions ) : Promise < LogEvent > {
140180 const entries = await this . repository . findMany ( { } ) ;
141181 if ( entries . length > 0 ) {
142182 if ( ! isRotationOptions ( options ) ) throw new BadOptionsSpecifiedError ( ) ;
0 commit comments