@enbox/agent 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.mjs +12 -30
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/dwn-api.js +149 -22
- package/dist/esm/dwn-api.js.map +1 -1
- package/dist/esm/dwn-discovery-file.js +1 -1
- package/dist/esm/dwn-discovery-payload.js +20 -21
- package/dist/esm/dwn-discovery-payload.js.map +1 -1
- package/dist/esm/dwn-key-delivery.js.map +1 -1
- package/dist/esm/{oidc.js → enbox-connect-protocol.js} +219 -251
- package/dist/esm/enbox-connect-protocol.js.map +1 -0
- package/dist/esm/enbox-user-agent.js +19 -12
- package/dist/esm/enbox-user-agent.js.map +1 -1
- package/dist/esm/hd-identity-vault.js +11 -0
- package/dist/esm/hd-identity-vault.js.map +1 -1
- package/dist/esm/index.js +4 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/local-dwn.js +21 -51
- package/dist/esm/local-dwn.js.map +1 -1
- package/dist/esm/permissions-api.js.map +1 -1
- package/dist/esm/store-data.js.map +1 -1
- package/dist/esm/sync-engine-level.js +1 -1
- package/dist/esm/sync-engine-level.js.map +1 -1
- package/dist/esm/sync-messages.js +1 -1
- package/dist/esm/sync-messages.js.map +1 -1
- package/dist/esm/test-harness.js +2 -3
- package/dist/esm/test-harness.js.map +1 -1
- package/dist/esm/types/dwn.js.map +1 -1
- package/dist/types/dwn-api.d.ts +46 -6
- package/dist/types/dwn-api.d.ts.map +1 -1
- package/dist/types/dwn-discovery-file.d.ts +1 -1
- package/dist/types/dwn-discovery-payload.d.ts +18 -19
- package/dist/types/dwn-discovery-payload.d.ts.map +1 -1
- package/dist/types/enbox-connect-protocol.d.ts +206 -0
- package/dist/types/enbox-connect-protocol.d.ts.map +1 -0
- package/dist/types/enbox-user-agent.d.ts +13 -8
- package/dist/types/enbox-user-agent.d.ts.map +1 -1
- package/dist/types/hd-identity-vault.d.ts +7 -0
- package/dist/types/hd-identity-vault.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/local-dwn.d.ts +16 -32
- package/dist/types/local-dwn.d.ts.map +1 -1
- package/dist/types/test-harness.d.ts.map +1 -1
- package/dist/types/types/agent.d.ts +2 -7
- package/dist/types/types/agent.d.ts.map +1 -1
- package/dist/types/types/dwn.d.ts +0 -10
- package/dist/types/types/dwn.d.ts.map +1 -1
- package/dist/types/types/sync.d.ts +6 -0
- package/dist/types/types/sync.d.ts.map +1 -1
- package/package.json +14 -16
- package/src/dwn-api.ts +175 -29
- package/src/dwn-discovery-file.ts +1 -1
- package/src/dwn-discovery-payload.ts +23 -24
- package/src/dwn-key-delivery.ts +1 -1
- package/src/enbox-connect-protocol.ts +753 -0
- package/src/enbox-user-agent.ts +31 -18
- package/src/hd-identity-vault.ts +21 -0
- package/src/index.ts +4 -4
- package/src/local-dwn.ts +22 -53
- package/src/permissions-api.ts +3 -3
- package/src/store-data.ts +1 -1
- package/src/sync-engine-level.ts +1 -1
- package/src/sync-messages.ts +1 -1
- package/src/test-harness.ts +2 -3
- package/src/types/agent.ts +3 -14
- package/src/types/dwn.ts +1 -13
- package/src/types/sync.ts +7 -0
- package/dist/esm/connect.js +0 -180
- package/dist/esm/connect.js.map +0 -1
- package/dist/esm/oidc.js.map +0 -1
- package/dist/esm/sync-api.js +0 -64
- package/dist/esm/sync-api.js.map +0 -1
- package/dist/types/connect.d.ts +0 -88
- package/dist/types/connect.d.ts.map +0 -1
- package/dist/types/oidc.d.ts +0 -250
- package/dist/types/oidc.d.ts.map +0 -1
- package/dist/types/sync-api.d.ts +0 -40
- package/dist/types/sync-api.d.ts.map +0 -1
- package/src/connect.ts +0 -285
- package/src/oidc.ts +0 -864
- package/src/sync-api.ts +0 -75
package/src/connect.ts
DELETED
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import type { PushedAuthResponse } from './oidc.js';
|
|
3
|
-
import type { DwnPermissionScope, DwnProtocolDefinition, EnboxConnectAuthResponse } from './index.js';
|
|
4
|
-
|
|
5
|
-
import { CryptoUtils } from '@enbox/crypto';
|
|
6
|
-
import { DidJwk } from '@enbox/dids';
|
|
7
|
-
import { Oidc } from './oidc.js';
|
|
8
|
-
import { pollWithTtl } from './utils.js';
|
|
9
|
-
import { Convert, logger } from '@enbox/common';
|
|
10
|
-
import { DwnInterfaceName, DwnMethodName } from '@enbox/dwn-sdk-js';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Initiates the wallet connect process. Used when a client wants to obtain
|
|
14
|
-
* a did from a provider.
|
|
15
|
-
*/
|
|
16
|
-
async function initClient({
|
|
17
|
-
displayName,
|
|
18
|
-
connectServerUrl,
|
|
19
|
-
walletUri,
|
|
20
|
-
permissionRequests,
|
|
21
|
-
onWalletUriReady,
|
|
22
|
-
validatePin,
|
|
23
|
-
}: WalletConnectOptions): Promise<{
|
|
24
|
-
delegateGrants: EnboxConnectAuthResponse['delegateGrants'];
|
|
25
|
-
delegatePortableDid: EnboxConnectAuthResponse['delegatePortableDid'];
|
|
26
|
-
connectedDid: string;
|
|
27
|
-
} | undefined> {
|
|
28
|
-
// ephemeral client did for ECDH, signing, verification
|
|
29
|
-
const clientDid = await DidJwk.create();
|
|
30
|
-
|
|
31
|
-
// TODO: properly implement PKCE. this implementation is lacking server side validations and more.
|
|
32
|
-
// https://github.com/enboxorg/enbox/issues/829
|
|
33
|
-
// Derive the code challenge based on the code verifier
|
|
34
|
-
// const { codeChallengeBytes, codeChallengeBase64Url } =
|
|
35
|
-
// await Oidc.generateCodeChallenge();
|
|
36
|
-
const encryptionKey = CryptoUtils.randomBytes(32);
|
|
37
|
-
|
|
38
|
-
// build callback URL to pass into the auth request
|
|
39
|
-
const callbackEndpoint = Oidc.buildOidcUrl({
|
|
40
|
-
baseURL : connectServerUrl,
|
|
41
|
-
endpoint : 'callback',
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// build the PAR request
|
|
45
|
-
const request = await Oidc.createAuthRequest({
|
|
46
|
-
client_id : clientDid.uri,
|
|
47
|
-
scope : 'openid did:jwk',
|
|
48
|
-
redirect_uri : callbackEndpoint,
|
|
49
|
-
// custom properties:
|
|
50
|
-
// code_challenge : codeChallengeBase64Url,
|
|
51
|
-
// code_challenge_method : 'S256',
|
|
52
|
-
permissionRequests : permissionRequests,
|
|
53
|
-
displayName,
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// Sign the Request Object using the Client DID's signing key.
|
|
57
|
-
const requestJwt = await Oidc.signJwt({
|
|
58
|
-
did : clientDid,
|
|
59
|
-
data : request,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
if (!requestJwt) {
|
|
63
|
-
throw new Error('Unable to sign requestObject');
|
|
64
|
-
}
|
|
65
|
-
// Encrypt the Request Object JWT using the code challenge.
|
|
66
|
-
const requestObjectJwe = await Oidc.encryptAuthRequest({
|
|
67
|
-
jwt: requestJwt,
|
|
68
|
-
encryptionKey,
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
const pushedAuthorizationRequestEndpoint = Oidc.buildOidcUrl({
|
|
72
|
-
baseURL : connectServerUrl,
|
|
73
|
-
endpoint : 'pushedAuthorizationRequest',
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
const parResponse = await fetch(pushedAuthorizationRequestEndpoint, {
|
|
77
|
-
body : JSON.stringify({ request: requestObjectJwe }),
|
|
78
|
-
method : 'POST',
|
|
79
|
-
headers : {
|
|
80
|
-
'Content-Type': 'application/json',
|
|
81
|
-
},
|
|
82
|
-
signal: AbortSignal.timeout(30_000),
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
if (!parResponse.ok) {
|
|
86
|
-
throw new Error(`${parResponse.status}: ${parResponse.statusText}`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const parData: PushedAuthResponse = await parResponse.json();
|
|
90
|
-
|
|
91
|
-
// a deeplink to a compatible wallet. if the wallet scans this link it should receive
|
|
92
|
-
// a route to its Connect provider flow and the params of where to fetch the auth request.
|
|
93
|
-
logger.log(`Wallet URI: ${walletUri}`);
|
|
94
|
-
const generatedWalletUri = new URL(walletUri);
|
|
95
|
-
generatedWalletUri.searchParams.set('request_uri', parData.request_uri);
|
|
96
|
-
generatedWalletUri.searchParams.set(
|
|
97
|
-
'encryption_key',
|
|
98
|
-
Convert.uint8Array(encryptionKey).toBase64Url()
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
// call user's callback so they can send the URI to the wallet as they see fit
|
|
102
|
-
onWalletUriReady(generatedWalletUri.toString());
|
|
103
|
-
|
|
104
|
-
const tokenUrl = Oidc.buildOidcUrl({
|
|
105
|
-
baseURL : connectServerUrl,
|
|
106
|
-
endpoint : 'token',
|
|
107
|
-
tokenParam : request.state,
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
// subscribe to receiving a response from the wallet with default TTL. receive ciphertext of {@link EnboxConnectAuthResponse}
|
|
111
|
-
const authResponse = await pollWithTtl(() => fetch(tokenUrl, { signal: AbortSignal.timeout(30_000) }));
|
|
112
|
-
|
|
113
|
-
if (authResponse) {
|
|
114
|
-
const jwe = await authResponse?.text();
|
|
115
|
-
|
|
116
|
-
// get the pin from the user and use it as AAD to decrypt
|
|
117
|
-
const pin = await validatePin();
|
|
118
|
-
const jwt = await Oidc.decryptAuthResponse(clientDid, jwe, pin);
|
|
119
|
-
const verifiedAuthResponse = (await Oidc.verifyJwt({
|
|
120
|
-
jwt,
|
|
121
|
-
})) as EnboxConnectAuthResponse;
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
delegateGrants : verifiedAuthResponse.delegateGrants,
|
|
125
|
-
delegatePortableDid : verifiedAuthResponse.delegatePortableDid,
|
|
126
|
-
connectedDid : verifiedAuthResponse.iss,
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Initiates the wallet connect process. Used when a client wants to obtain
|
|
133
|
-
* a did from a provider.
|
|
134
|
-
*/
|
|
135
|
-
export type WalletConnectOptions = {
|
|
136
|
-
/** The user friendly name of the client/app to be displayed when prompting end-user with permission requests. */
|
|
137
|
-
displayName: string;
|
|
138
|
-
|
|
139
|
-
/** The URL of the intermediary server which relays messages between the client and provider. */
|
|
140
|
-
connectServerUrl: string;
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* The URI of the Provider (wallet).The `onWalletUriReady` will take this wallet
|
|
144
|
-
* uri and add a payload to it which will be used to obtain and decrypt from the `request_uri`.
|
|
145
|
-
* @example `web5://` or `http://localhost:3000/`.
|
|
146
|
-
*/
|
|
147
|
-
walletUri: string;
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* The protocols of permissions requested, along with the definition and
|
|
151
|
-
* permission scopes for each protocol. The key is the protocol URL and
|
|
152
|
-
* the value is an object with the protocol definition and the permission scopes.
|
|
153
|
-
*/
|
|
154
|
-
permissionRequests: ConnectPermissionRequest[];
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* The Connect API provides a URI to the wallet based on the `walletUri` plus a query params payload valid for 5 minutes.
|
|
158
|
-
* The link can either be used as a deep link on the same device or a QR code for cross device or both.
|
|
159
|
-
* The query params are `{ request_uri: string; encryption_key: string; }`
|
|
160
|
-
* The wallet will use the `request_uri to contact the intermediary server's `authorize` endpoint
|
|
161
|
-
* and pull down the {@link EnboxConnectAuthRequest} and use the `encryption_key` to decrypt it.
|
|
162
|
-
*
|
|
163
|
-
* @param uri - The URI returned by the Connect API to be passed to a provider.
|
|
164
|
-
*/
|
|
165
|
-
onWalletUriReady: (uri: string) => void;
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Function that must be provided to submit the pin entered by the user on the client.
|
|
169
|
-
* The pin is used to decrypt the {@link EnboxConnectAuthResponse} that was retrieved from the
|
|
170
|
-
* token endpoint by the client inside of Connect.
|
|
171
|
-
*
|
|
172
|
-
* @returns A promise that resolves to the PIN as a string.
|
|
173
|
-
*/
|
|
174
|
-
validatePin: () => Promise<string>;
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* The protocols of permissions requested, along with the definition and permission scopes for each protocol.
|
|
179
|
-
*/
|
|
180
|
-
export type ConnectPermissionRequest = {
|
|
181
|
-
/**
|
|
182
|
-
* The definition of the protocol the permissions are being requested for.
|
|
183
|
-
* In the event that the protocol is not already installed, the wallet will install this given protocol definition.
|
|
184
|
-
*/
|
|
185
|
-
protocolDefinition: DwnProtocolDefinition;
|
|
186
|
-
|
|
187
|
-
/** The scope of the permissions being requested for the given protocol */
|
|
188
|
-
permissionScopes: DwnPermissionScope[];
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Shorthand for the types of permissions that can be requested.
|
|
193
|
-
*/
|
|
194
|
-
export type Permission = 'write' | 'read' | 'delete' | 'query' | 'subscribe' | 'configure';
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* The options for creating a permission request for a given protocol.
|
|
198
|
-
*/
|
|
199
|
-
export type ProtocolPermissionOptions = {
|
|
200
|
-
/** The protocol definition for the protocol being requested */
|
|
201
|
-
definition: DwnProtocolDefinition;
|
|
202
|
-
|
|
203
|
-
/** The permissions being requested for the protocol */
|
|
204
|
-
permissions: Permission[];
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Creates a set of Dwn Permission Scopes to request for a given protocol.
|
|
209
|
-
*
|
|
210
|
-
* If no permissions are provided, the default is to request all relevant record permissions (write, read, delete, query, subscribe).
|
|
211
|
-
* 'configure' is not included by default, as this gives the application a lot of control over the protocol.
|
|
212
|
-
*/
|
|
213
|
-
function createPermissionRequestForProtocol({ definition, permissions }: ProtocolPermissionOptions): ConnectPermissionRequest {
|
|
214
|
-
const requests: DwnPermissionScope[] = [];
|
|
215
|
-
|
|
216
|
-
// Add the ability to query for the specific protocol
|
|
217
|
-
requests.push({
|
|
218
|
-
protocol : definition.protocol,
|
|
219
|
-
interface : DwnInterfaceName.Protocols,
|
|
220
|
-
method : DwnMethodName.Query,
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
// A Messages.Read grant is a unified scope that covers MessagesRead, MessagesSync, and MessagesSubscribe.
|
|
224
|
-
// This single grant enables sync and real-time subscriptions for the protocol.
|
|
225
|
-
requests.push({
|
|
226
|
-
protocol : definition.protocol,
|
|
227
|
-
interface : DwnInterfaceName.Messages,
|
|
228
|
-
method : DwnMethodName.Read,
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
// We also request any additional permissions the user has requested for this protocol
|
|
232
|
-
for (const permission of permissions) {
|
|
233
|
-
switch (permission) {
|
|
234
|
-
case 'write':
|
|
235
|
-
requests.push({
|
|
236
|
-
protocol : definition.protocol,
|
|
237
|
-
interface : DwnInterfaceName.Records,
|
|
238
|
-
method : DwnMethodName.Write,
|
|
239
|
-
});
|
|
240
|
-
break;
|
|
241
|
-
case 'read':
|
|
242
|
-
requests.push({
|
|
243
|
-
protocol : definition.protocol,
|
|
244
|
-
interface : DwnInterfaceName.Records,
|
|
245
|
-
method : DwnMethodName.Read,
|
|
246
|
-
});
|
|
247
|
-
break;
|
|
248
|
-
case 'delete':
|
|
249
|
-
requests.push({
|
|
250
|
-
protocol : definition.protocol,
|
|
251
|
-
interface : DwnInterfaceName.Records,
|
|
252
|
-
method : DwnMethodName.Delete,
|
|
253
|
-
});
|
|
254
|
-
break;
|
|
255
|
-
case 'query':
|
|
256
|
-
requests.push({
|
|
257
|
-
protocol : definition.protocol,
|
|
258
|
-
interface : DwnInterfaceName.Records,
|
|
259
|
-
method : DwnMethodName.Query,
|
|
260
|
-
});
|
|
261
|
-
break;
|
|
262
|
-
case 'subscribe':
|
|
263
|
-
requests.push({
|
|
264
|
-
protocol : definition.protocol,
|
|
265
|
-
interface : DwnInterfaceName.Records,
|
|
266
|
-
method : DwnMethodName.Subscribe,
|
|
267
|
-
});
|
|
268
|
-
break;
|
|
269
|
-
case 'configure':
|
|
270
|
-
requests.push({
|
|
271
|
-
protocol : definition.protocol,
|
|
272
|
-
interface : DwnInterfaceName.Protocols,
|
|
273
|
-
method : DwnMethodName.Configure,
|
|
274
|
-
});
|
|
275
|
-
break;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return {
|
|
280
|
-
protocolDefinition : definition,
|
|
281
|
-
permissionScopes : requests,
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
export const WalletConnect = { initClient, createPermissionRequestForProtocol };
|