1
+ import type {
2
+ AgentContext ,
3
+ DidRegistrar ,
4
+ DidCreateOptions ,
5
+ DidCreateResult ,
6
+ DidDeactivateResult ,
7
+ DidDocument ,
8
+ DidUpdateResult ,
9
+ DidUpdateOptions ,
10
+ DidDocumentRole ,
11
+ } from '@credo-ts/core'
12
+
13
+ import { MultibaseEncoder , Buffer , DidRepository , DidRecord , isValidPrivateKey , KeyType } from '@credo-ts/core'
14
+ import { createDID , updateDID } from 'didwebvh-ts'
15
+
16
+ import { WebvhModuleConfig } from '../WebvhModuleConfig'
17
+
18
+ import { generateDidDoc } from './didWebvhUtil'
19
+
20
+ export class WebvhDidRegistrar implements DidRegistrar {
21
+ public readonly supportedMethods = [ 'webvh' ]
22
+
23
+ public async create ( agentContext : AgentContext , options : WebvhDidCreateOptions ) : Promise < DidCreateResult > {
24
+ const didRepository = agentContext . dependencyManager . resolve ( DidRepository )
25
+ const webvhModuleConfig = agentContext . dependencyManager . resolve ( WebvhModuleConfig )
26
+
27
+ let didDocument : DidDocument
28
+
29
+ try {
30
+ if ( options . didDocument ) {
31
+ didDocument = options . didDocument
32
+ } else if ( options . secret ?. verificationMethod ) {
33
+ const verificationMethod = options . secret . verificationMethod
34
+ const privateKeyMultibase = verificationMethod . privateKeyMultibase
35
+ if ( ! privateKeyMultibase ) {
36
+ return {
37
+ didDocumentMetadata : { } ,
38
+ didRegistrationMetadata : { } ,
39
+ didState : {
40
+ state : 'failed' ,
41
+ reason : 'Invalid private key provided' ,
42
+ } ,
43
+ }
44
+ }
45
+ const privateKey = Buffer . from ( MultiBaseEncoder . decode ( privateKeyMultibase ) . data )
46
+ if ( privateKeyMultibase && ! isValidPrivateKey ( privateKey , KeyType . Ed25519 ) ) {
47
+ return {
48
+ didDocumentMetadata : { } ,
49
+ didRegistrationMetadata : { } ,
50
+ didState : {
51
+ state : 'failed' ,
52
+ reason : 'Invalid private key provided' ,
53
+ } ,
54
+ }
55
+ }
56
+
57
+ await agentContext . wallet . createKey ( {
58
+ keyType : KeyType . Ed25519 ,
59
+ privateKey,
60
+ } )
61
+
62
+ didDocument = await generateDidDoc ( {
63
+ verificationMethods : [ verificationMethod ] ,
64
+ updateKeys : [ verificationMethod . publicKeyMultibase ] ,
65
+ baseUrl : webvhModuleConfig . baseUrl ,
66
+ } , agentContext )
67
+ } else {
68
+ return {
69
+ didDocumentMetadata : { } ,
70
+ didRegistrationMetadata : { } ,
71
+ didState : {
72
+ state : 'failed' ,
73
+ reason : 'Provide a didDocument or at least one verificationMethod with seed in secret' ,
74
+ } ,
75
+ }
76
+ }
77
+
78
+ // Register the DID using didwebvh-ts
79
+ const response = await createDID ( )
80
+
81
+ // Save the did so we know we created it and can issue with it
82
+ const didRecord = new DidRecord ( {
83
+ did : didDocument . id ,
84
+ role : DidDocumentRole . Created ,
85
+ didDocument,
86
+ } )
87
+ await didRepository . save ( agentContext , didRecord )
88
+
89
+ return {
90
+ didDocumentMetadata : { } ,
91
+ didRegistrationMetadata : { } ,
92
+ didState : {
93
+ state : 'finished' ,
94
+ did : didDocument . id ,
95
+ didDocument,
96
+ secret : options . secret ,
97
+ } ,
98
+ }
99
+ } catch ( error ) {
100
+ agentContext . config . logger . error ( `Error registering DID` , error )
101
+ return {
102
+ didDocumentMetadata : { } ,
103
+ didRegistrationMetadata : { } ,
104
+ didState : {
105
+ state : 'failed' ,
106
+ reason : `unknownError: ${ error . message } ` ,
107
+ } ,
108
+ }
109
+ }
110
+ }
111
+
112
+ public async update ( agentContext : AgentContext , options : WebvhDidUpdateOptions ) : Promise < DidUpdateResult > {
113
+ const didRepository = agentContext . dependencyManager . resolve ( DidRepository )
114
+
115
+ try {
116
+ if ( ! options . didDocument ) {
117
+ return {
118
+ didDocumentMetadata : { } ,
119
+ didRegistrationMetadata : { } ,
120
+ didState : {
121
+ state : 'failed' ,
122
+ reason : 'Provide a valid didDocument' ,
123
+ } ,
124
+ }
125
+ }
126
+
127
+ // Update the DID using didwebvh-ts
128
+ const response = await updateDID ( { doc : options . didDocument . toJSON ( ) } )
129
+
130
+ // Update the did record
131
+ const didRecord = await didRepository . findCreatedDid ( agentContext , options . did )
132
+ if ( didRecord ) {
133
+ didRecord . didDocument = options . didDocument
134
+ await didRepository . update ( agentContext , didRecord )
135
+ }
136
+
137
+ return {
138
+ didDocumentMetadata : { } ,
139
+ didRegistrationMetadata : { } ,
140
+ didState : {
141
+ state : 'finished' ,
142
+ did : options . did ,
143
+ didDocument : options . didDocument ,
144
+ } ,
145
+ }
146
+ } catch ( error ) {
147
+ agentContext . config . logger . error ( `Error updating DID` , error )
148
+ return {
149
+ didDocumentMetadata : { } ,
150
+ didRegistrationMetadata : { } ,
151
+ didState : {
152
+ state : 'failed' ,
153
+ reason : `unknownError: ${ error . message } ` ,
154
+ } ,
155
+ }
156
+ }
157
+ }
158
+
159
+ public async deactivate ( agentContext : AgentContext , options : WebvhDidDeactivateOptions ) : Promise < DidDeactivateResult > {
160
+ // const didRepository = agentContext.dependencyManager.resolve(DidRepository)
161
+
162
+ // try {
163
+ // // Deactivate the DID using didwebvh-ts
164
+ // const response = await deactivateDID(options.did)
165
+
166
+ // // Update the did record
167
+ // const didRecord = await didRepository.findCreatedDid(agentContext, options.did)
168
+ // if (didRecord) {
169
+ // await didRepository.update(agentContext, didRecord)
170
+ // }
171
+
172
+ // return {
173
+ // didDocumentMetadata: {},
174
+ // didRegistrationMetadata: {},
175
+ // didState: {
176
+ // state: 'finished',
177
+ // did: options.did,
178
+ // didDocument:,
179
+ // },
180
+ // }
181
+ // } catch (error) {
182
+ // agentContext.config.logger.error(`Error deactivating DID`, error)
183
+ return {
184
+ didDocumentMetadata : { } ,
185
+ didRegistrationMetadata : { } ,
186
+ didState : {
187
+ state : 'failed' ,
188
+ reason : `unknownError` ,
189
+ } ,
190
+ }
191
+ // }
192
+ }
193
+ }
194
+
195
+ export interface WebvhDidCreateWithoutDidDocumentOptions extends DidCreateOptions {
196
+ method : 'webvh'
197
+ did ?: undefined
198
+ didDocument ?: undefined
199
+ options ?: {
200
+ versionId ?: string
201
+ }
202
+ secret : {
203
+ verificationMethod : IVerificationMethod
204
+ }
205
+ }
206
+
207
+ export interface WebvhDidCreateFromDidDocumentOptions extends DidCreateOptions {
208
+ method : 'webvh'
209
+ did ?: undefined
210
+ didDocument : DidDocument
211
+ options ?: {
212
+ versionId ?: string
213
+ }
214
+ }
215
+
216
+ export type WebvhDidCreateOptions = WebvhDidCreateFromDidDocumentOptions | WebvhDidCreateWithoutDidDocumentOptions
217
+
218
+ export interface WebvhDidUpdateOptions extends DidUpdateOptions {
219
+ did : string
220
+ didDocument : DidDocument
221
+ options ?: {
222
+ versionId ?: string
223
+ }
224
+ }
225
+
226
+ export interface WebvhDidDeactivateOptions extends DidCreateOptions {
227
+ method : 'webvh'
228
+ did : string
229
+ options ?: {
230
+ versionId ?: string
231
+ }
232
+ }
233
+
234
+ interface IVerificationMethod {
235
+ type : string
236
+ id : string
237
+ privateKeyMultibase ?: string
238
+ publicKeyMultibase : string
239
+ }
0 commit comments