1
- import type { BearerIdentity , HdIdentityVault , Web5Agent } from '@web5/agent' ;
2
-
1
+ import {
2
+ WalletConnect ,
3
+ type BearerIdentity ,
4
+ type HdIdentityVault ,
5
+ type WalletConnectOptions ,
6
+ type Web5Agent ,
7
+ } from '@web5/agent' ;
8
+ import { Web5UserAgent } from '@web5/user-agent' ;
3
9
import { DidApi } from './did-api.js' ;
4
10
import { DwnApi } from './dwn-api.js' ;
5
- import { DwnRecordsPermissionScope , DwnProtocolDefinition , DwnRegistrar } from '@web5/agent' ;
11
+ import { DwnRegistrar } from '@web5/agent' ;
6
12
import { VcApi } from './vc-api.js' ;
7
- import { Web5UserAgent } from '@web5/user-agent ' ;
13
+ import { PortableDid } from '@web5/dids ' ;
8
14
9
15
/** Override defaults configured during the technical preview phase. */
10
16
export type TechPreviewOptions = {
11
17
/** Override default dwnEndpoints provided for technical preview. */
12
18
dwnEndpoints ?: string [ ] ;
13
- }
19
+ } ;
14
20
15
21
/** Override defaults for DID creation. */
16
22
export type DidCreateOptions = {
17
23
/** Override default dwnEndpoints provided during DID creation. */
18
24
dwnEndpoints ?: string [ ] ;
19
25
}
20
26
21
- /**
22
- * Options to provide when the initiating app wants to import a delegated identity/DID from an external wallet.
23
- */
24
- export type WalletConnectOptions = {
25
- /**
26
- * The URL of the wallet connect server to use for relaying messages between the app and the wallet.
27
- */
28
- connectServerUrl : string ;
29
-
30
- /**
31
- * The protocols of permissions requested, along with the definition and permission copes for each protocol.
32
- * The key is the protocol URL and the value is an object with the protocol definition and the permission scopes.
33
- */
34
- requestedProtocolsAndScopes : Map <
35
- string ,
36
- {
37
- /**
38
- * The definition of the protocol the permissions are being requested for.
39
- * In the event that the protocol is not already installed, the wallet will install this given protocol definition.
40
- */
41
- protocolDefinition : DwnProtocolDefinition ;
42
-
43
- /**
44
- * The scope of the permissions being requested for the given protocol.
45
- */
46
- permissionScopes : DwnRecordsPermissionScope [ ] ;
47
- }
48
- > ;
49
-
50
- /**
51
- * A handler to be called when the request URL is ready to be used to fetch the permission request by the wallet.
52
- * This method should be used by the calling app to pass the request URL to the wallet via a QR code or a deep link.
53
- *
54
- * @param requestUrl - The request URL for the wallet to fetch the permission request.
55
- */
56
- onRequestReady : ( requestUrl : string ) => void ;
57
-
58
- /**
59
- * An async method to get the PIN from the user to decrypt the response from the wallet.
60
- *
61
- * @returns A promise that resolves to the PIN as a string.
62
- */
63
- pinCapture : ( ) => Promise < string > ;
64
- }
65
-
66
27
/** Optional overrides that can be provided when calling {@link Web5.connect}. */
67
28
export type Web5ConnectOptions = {
68
-
69
29
/**
70
- * When specified, wallet connect flow interacting with an external wallet would be triggered.
30
+ * When specified, external wallet connect flow is triggered.
31
+ * This param currently will not work in apps that are currently connected.
32
+ * It must only be invoked at registration with a reset and empty DWN and agent.
71
33
*/
72
34
walletConnectOptions ?: WalletConnectOptions ;
73
35
@@ -180,6 +142,12 @@ export type Web5ConnectResult = {
180
142
* and should be stored securely by the user.
181
143
*/
182
144
recoveryPhrase ?: string ;
145
+
146
+ /**
147
+ * The resulting did of a successful wallet connect. Only returned on success if
148
+ * {@link WalletConnectOptions} was provided.
149
+ */
150
+ delegateDid ?: PortableDid
183
151
} ;
184
152
185
153
/**
@@ -237,7 +205,16 @@ export class Web5 {
237
205
* @returns A promise that resolves to a {@link Web5} instance and the connected DID.
238
206
*/
239
207
static async connect ( {
240
- agent, agentVault, connectedDid, password, recoveryPhrase, sync, techPreview, didCreateOptions, registration
208
+ agent,
209
+ agentVault,
210
+ connectedDid,
211
+ password,
212
+ recoveryPhrase,
213
+ sync,
214
+ techPreview,
215
+ didCreateOptions,
216
+ registration,
217
+ walletConnectOptions,
241
218
} : Web5ConnectOptions = { } ) : Promise < Web5ConnectResult > {
242
219
if ( agent === undefined ) {
243
220
// A custom Web5Agent implementation was not specified, so use default managed user agent.
@@ -263,69 +240,74 @@ export class Web5 {
263
240
}
264
241
await userAgent . start ( { password } ) ;
265
242
266
- // TODO: Replace stubbed connection attempt once Connect Protocol has been implemented.
267
- // Attempt to Connect to localhost agent or via Connect Server.
268
- // userAgent.connect();
269
-
270
- const notConnected = true ;
271
- if ( /* !userAgent.isConnected() */ notConnected ) {
272
- // Connect attempt failed or was rejected so fallback to local user agent.
273
- let identity : BearerIdentity ;
274
-
275
- // Query the Agent's DWN tenant for identity records.
276
- const identities = await userAgent . identity . list ( ) ;
277
-
278
- // If an existing identity is not found found, create a new one.
279
- const existingIdentityCount = identities . length ;
280
- if ( existingIdentityCount === 0 ) {
281
- // Use the specified DWN endpoints or the latest TBD hosted DWN
282
- const serviceEndpointNodes = techPreview ?. dwnEndpoints ?? didCreateOptions ?. dwnEndpoints ?? [ 'https://dwn.tbddev.org/beta' ] ;
283
-
284
- // Generate a new Identity for the end-user.
285
- identity = await userAgent . identity . create ( {
286
- didMethod : 'dht' ,
287
- metadata : { name : 'Default' } ,
288
- didOptions : {
289
- services : [
290
- {
291
- id : 'dwn' ,
292
- type : 'DecentralizedWebNode' ,
293
- serviceEndpoint : serviceEndpointNodes ,
294
- enc : '#enc' ,
295
- sig : '#sig' ,
296
- }
297
- ] ,
298
- verificationMethods : [
299
- {
300
- algorithm : 'Ed25519' ,
301
- id : 'sig' ,
302
- purposes : [ 'assertionMethod' , 'authentication' ]
303
- } ,
304
- {
305
- algorithm : 'secp256k1' ,
306
- id : 'enc' ,
307
- purposes : [ 'keyAgreement' ]
308
- }
309
- ]
310
- }
311
- } ) ;
312
-
313
- // The User Agent will manage the Identity, which ensures it will be available on future
314
- // sessions.
315
- await userAgent . identity . manage ( { portableIdentity : await identity . export ( ) } ) ;
316
-
317
- } else if ( existingIdentityCount === 1 ) {
318
- // An existing identity was found in the User Agent's tenant.
319
- identity = identities [ 0 ] ;
320
-
321
- } else {
322
- throw new Error ( `connect() failed due to unexpected state: Expected 1 but found ${ existingIdentityCount } stored identities.` ) ;
243
+ let identity : BearerIdentity ;
244
+
245
+ // Query the Agent's DWN tenant for identity records.
246
+ const identities = await userAgent . identity . list ( ) ;
247
+
248
+ // If an existing identity is not found found, create a new one.
249
+ const existingIdentityCount = identities . length ;
250
+
251
+ // on init/registration
252
+ if ( existingIdentityCount === 0 ) {
253
+ if ( walletConnectOptions ) {
254
+ // WIP: ingest this
255
+ const { delegateDid } = await WalletConnect . initClient ( walletConnectOptions ) ;
256
+ // WIP
257
+ // identity = await userAgent.identity.import({
258
+ // portableIdentity: {
259
+ // portableDid : did,
260
+ // metadata : { name: 'Connection', uri: did.uri, tenant: did.uri }
261
+ // }
262
+ // });
263
+
264
+ // WIP. just going to early return for now.
265
+ return { web5 : null , did : null , delegateDid } ;
323
266
}
324
267
325
- // Set the stored identity as the connected DID.
326
- connectedDid = identity . did . uri ;
268
+ // Use the specified DWN endpoints or get default tech preview hosted nodes.
269
+ const serviceEndpointNodes = techPreview ?. dwnEndpoints ?? didCreateOptions ?. dwnEndpoints ?? [ 'https://dwn.tbddev.org/beta' ] ;
270
+
271
+ // Generate a new Identity for the end-user.
272
+ identity = await userAgent . identity . create ( {
273
+ didMethod : 'dht' ,
274
+ metadata : { name : 'Default' } ,
275
+ didOptions : {
276
+ services : [
277
+ {
278
+ id : 'dwn' ,
279
+ type : 'DecentralizedWebNode' ,
280
+ serviceEndpoint : serviceEndpointNodes ,
281
+ enc : '#enc' ,
282
+ sig : '#sig' ,
283
+ }
284
+ ] ,
285
+ verificationMethods : [
286
+ {
287
+ algorithm : 'Ed25519' ,
288
+ id : 'sig' ,
289
+ purposes : [ 'assertionMethod' , 'authentication' ]
290
+ } ,
291
+ {
292
+ algorithm : 'secp256k1' ,
293
+ id : 'enc' ,
294
+ purposes : [ 'keyAgreement' ]
295
+ }
296
+ ]
297
+ }
298
+ } ) ;
299
+
300
+ // Persists the Identity to be available in future sessions
301
+ await userAgent . identity . manage ( { portableIdentity : await identity . export ( ) } ) ;
302
+ } else if ( existingIdentityCount === 1 ) {
303
+ // An existing identity was found in the User Agent's tenant.
304
+ identity = identities [ 0 ] ;
305
+ } else {
306
+ throw new Error ( `connect() failed due to unexpected state: Expected 1 but found ${ existingIdentityCount } stored identities.` ) ;
327
307
}
328
308
309
+ connectedDid = identity . did . uri ;
310
+
329
311
if ( registration !== undefined ) {
330
312
// If a registration object is passed, we attempt to register the AgentDID and the ConnectedDID with the DWN endpoints provided
331
313
const serviceEndpointNodes = techPreview ?. dwnEndpoints ?? didCreateOptions ?. dwnEndpoints ;
@@ -369,7 +351,6 @@ export class Web5 {
369
351
}
370
352
371
353
const web5 = new Web5 ( { agent, connectedDid } ) ;
372
-
373
354
return { web5, did : connectedDid , recoveryPhrase } ;
374
355
}
375
- }
356
+ }
0 commit comments