@enbox/browser 0.3.70 → 0.3.72
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/README.md +30 -7
- package/dist/browser.mjs +14 -14
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/blob-url-pool.js +36 -0
- package/dist/esm/blob-url-pool.js.map +1 -0
- package/dist/esm/browser-connect-handler.js +3 -1
- package/dist/esm/browser-connect-handler.js.map +1 -1
- package/dist/esm/file-envelope-url-store.js +203 -0
- package/dist/esm/file-envelope-url-store.js.map +1 -0
- package/dist/esm/index.js +12 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/object-url-reference.js +68 -0
- package/dist/esm/object-url-reference.js.map +1 -0
- package/dist/esm/relay-connect-runner.js +9 -1
- package/dist/esm/relay-connect-runner.js.map +1 -1
- package/dist/esm/ui/connect-modal.js +134 -16
- package/dist/esm/ui/connect-modal.js.map +1 -1
- package/dist/types/blob-url-pool.d.ts +16 -0
- package/dist/types/blob-url-pool.d.ts.map +1 -0
- package/dist/types/browser-connect-handler.d.ts +8 -2
- package/dist/types/browser-connect-handler.d.ts.map +1 -1
- package/dist/types/file-envelope-url-store.d.ts +30 -0
- package/dist/types/file-envelope-url-store.d.ts.map +1 -0
- package/dist/types/index.d.ts +16 -14
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/object-url-reference.d.ts +20 -0
- package/dist/types/object-url-reference.d.ts.map +1 -0
- package/dist/types/relay-connect-runner.d.ts +4 -0
- package/dist/types/relay-connect-runner.d.ts.map +1 -1
- package/dist/types/ui/connect-modal.d.ts +24 -11
- package/dist/types/ui/connect-modal.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/blob-url-pool.ts +55 -0
- package/src/browser-connect-handler.ts +13 -2
- package/src/file-envelope-url-store.ts +260 -0
- package/src/index.ts +23 -159
- package/src/object-url-reference.ts +82 -0
- package/src/relay-connect-runner.ts +17 -2
- package/src/ui/connect-modal.ts +187 -28
package/src/index.ts
CHANGED
|
@@ -8,14 +8,17 @@
|
|
|
8
8
|
* @example Single-import dapp setup
|
|
9
9
|
* ```ts
|
|
10
10
|
* import {
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* BrowserConnectHandler, createConnectionStore,
|
|
12
|
+
* defineApplicationManifest,
|
|
13
13
|
* } from '@enbox/browser';
|
|
14
|
+
* import { MyProtocol } from './my-protocol.js';
|
|
14
15
|
*
|
|
15
|
-
* const
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* const store = createConnectionStore({
|
|
17
|
+
* application : defineApplicationManifest({ protocols: [MyProtocol] }),
|
|
18
|
+
* connectHandler : BrowserConnectHandler({ appName: 'My App' }),
|
|
18
19
|
* });
|
|
20
|
+
* const snapshot = await store.connect();
|
|
21
|
+
* if (snapshot.phase !== 'connected') throw snapshot.error ?? new Error('Connection failed.');
|
|
19
22
|
* ```
|
|
20
23
|
*
|
|
21
24
|
* For non-browser environments (Node.js, CLI, desktop), import from
|
|
@@ -28,150 +31,13 @@
|
|
|
28
31
|
//
|
|
29
32
|
// The high-level Enbox API: DWN records and protocols.
|
|
30
33
|
|
|
31
|
-
export
|
|
32
|
-
AudienceDecryptError,
|
|
33
|
-
createConnectionStore,
|
|
34
|
-
ContextNotReadyError,
|
|
35
|
-
ContextRetiredError,
|
|
36
|
-
defineApplicationManifest,
|
|
37
|
-
DwnResponseError,
|
|
38
|
-
Enbox,
|
|
39
|
-
defineProtocol,
|
|
40
|
-
getApplicationProtocolRequests,
|
|
41
|
-
ProtocolReadinessError,
|
|
42
|
-
RecordConflictError,
|
|
43
|
-
RecordParentNotFoundError,
|
|
44
|
-
RecordSquashBackstopError,
|
|
45
|
-
RecordValidationError,
|
|
46
|
-
protocolContextKey,
|
|
47
|
-
recordCodecs,
|
|
48
|
-
ServiceConfigProtocol,
|
|
49
|
-
} from '@enbox/api';
|
|
50
|
-
|
|
51
|
-
export type {
|
|
52
|
-
ApplicationConnectionStore,
|
|
53
|
-
ApplicationConnectionStoreConnectOptions,
|
|
54
|
-
ApplicationConnectionStoreOptions,
|
|
55
|
-
ApplicationConnectionStoreRefreshOptions,
|
|
56
|
-
ApplicationManifest,
|
|
57
|
-
ApplicationManifestProtocol,
|
|
58
|
-
ApplicationManifestProtocolInput,
|
|
59
|
-
AudienceDecryptFailureCause,
|
|
60
|
-
ConnectionPhase,
|
|
61
|
-
ConnectionSnapshot,
|
|
62
|
-
ConnectionSnapshotListener,
|
|
63
|
-
ConnectionStore,
|
|
64
|
-
ConnectionStoreOptions,
|
|
65
|
-
ContextView,
|
|
66
|
-
ContextViewListener,
|
|
67
|
-
ContextViewState,
|
|
68
|
-
ContextMember,
|
|
69
|
-
ContextMembersApi,
|
|
70
|
-
ContextInvitation,
|
|
71
|
-
ContextInvitationPreview,
|
|
72
|
-
ContextInvitationsApi,
|
|
73
|
-
ContextMaterializedRecord,
|
|
74
|
-
ContextRecord,
|
|
75
|
-
ContextRecordDeleteParams,
|
|
76
|
-
ContextRecordsApi,
|
|
77
|
-
ContextRecordUpdateParams,
|
|
78
|
-
ContextRoleGroup,
|
|
79
|
-
ContextRoleGroups,
|
|
80
|
-
ContextRolePath,
|
|
81
|
-
ContextsApi,
|
|
82
|
-
DataForPath,
|
|
83
|
-
DefineApplicationManifestOptions,
|
|
84
|
-
DwnEndpointResolution,
|
|
85
|
-
EnboxAnonymousOptions,
|
|
86
|
-
EnboxConnectOptions,
|
|
87
|
-
EnboxConnectResult,
|
|
88
|
-
EnboxParams,
|
|
89
|
-
EnboxSessionParams,
|
|
90
|
-
EncodedRecordData,
|
|
91
|
-
EnsureProtocolsReadyOptions,
|
|
92
|
-
ExpandableRecordView,
|
|
93
|
-
FileEnvelopeCodec,
|
|
94
|
-
FileEnvelopeCodecOptions,
|
|
95
|
-
FileEnvelopeData,
|
|
96
|
-
FollowContextOptions,
|
|
97
|
-
JsonRecordCodecOptions,
|
|
98
|
-
MaterializedMemberContext,
|
|
99
|
-
MaterializedRecord,
|
|
100
|
-
MemberContext,
|
|
101
|
-
OwnedContext,
|
|
102
|
-
ProtocolContext,
|
|
103
|
-
ProtocolRolePaths,
|
|
104
|
-
SquashProtocolPaths,
|
|
105
|
-
RecordCodec,
|
|
106
|
-
RecordCodecContext,
|
|
107
|
-
RecordCodecValue,
|
|
108
|
-
RecordFilter,
|
|
109
|
-
RecordPage,
|
|
110
|
-
RecordPatch,
|
|
111
|
-
RecordPatchInput,
|
|
112
|
-
RecordQuery,
|
|
113
|
-
RecordSubscription,
|
|
114
|
-
RecordSubscriptionEvent,
|
|
115
|
-
RecordSubscriptionListener,
|
|
116
|
-
RecordView,
|
|
117
|
-
RecordViewListener,
|
|
118
|
-
RecordViewState,
|
|
119
|
-
RecordValidationFailure,
|
|
120
|
-
RecordValidator,
|
|
121
|
-
ReplicationCurrentness,
|
|
122
|
-
RoleDeliveryState,
|
|
123
|
-
SyncStatusSnapshot,
|
|
124
|
-
TypedMaterializedRecord,
|
|
125
|
-
TypedRecord,
|
|
126
|
-
} from '@enbox/api';
|
|
34
|
+
export * from '@enbox/api';
|
|
127
35
|
|
|
128
36
|
// ─── Re-exports from @enbox/auth ────────────────────────────────
|
|
129
37
|
//
|
|
130
38
|
// Authentication lifecycle, session management, connect handlers.
|
|
131
39
|
|
|
132
|
-
export
|
|
133
|
-
AuthManager,
|
|
134
|
-
AuthSession,
|
|
135
|
-
ConnectDeniedError,
|
|
136
|
-
SESSION_EXPIRED_ERROR_CODE,
|
|
137
|
-
SESSION_REVOKED_ERROR_CODE,
|
|
138
|
-
computeConnectionStatus,
|
|
139
|
-
isConnectDeniedError,
|
|
140
|
-
isSessionExpiredError,
|
|
141
|
-
isSessionInvalidError,
|
|
142
|
-
normalizeProtocolRequests,
|
|
143
|
-
WalletConnect,
|
|
144
|
-
} from '@enbox/auth/browser';
|
|
145
|
-
|
|
146
|
-
export type {
|
|
147
|
-
AuthEvent,
|
|
148
|
-
AuthEventHandler,
|
|
149
|
-
AuthManagerOptions,
|
|
150
|
-
AuthState,
|
|
151
|
-
ComputeConnectionStatusOptions,
|
|
152
|
-
ConnectionMonitorOptions,
|
|
153
|
-
ConnectionState,
|
|
154
|
-
ConnectionStatus,
|
|
155
|
-
ConnectionStatusGrant,
|
|
156
|
-
ConnectHandler,
|
|
157
|
-
ConnectOptions,
|
|
158
|
-
ConnectResult,
|
|
159
|
-
DisconnectOptions,
|
|
160
|
-
GetConnectionStatusOptions,
|
|
161
|
-
HandlerConnectOptions,
|
|
162
|
-
ImportFromPortableOptions,
|
|
163
|
-
VaultConnectOptions,
|
|
164
|
-
Permission,
|
|
165
|
-
PortableIdentity,
|
|
166
|
-
ProtocolDefinitionCarrier,
|
|
167
|
-
ProtocolPermissionRequest,
|
|
168
|
-
ProtocolRequest,
|
|
169
|
-
RefreshOptions,
|
|
170
|
-
RegistrationOptions,
|
|
171
|
-
StorageAdapter,
|
|
172
|
-
SyncOption,
|
|
173
|
-
WalletConnectOptions,
|
|
174
|
-
} from '@enbox/auth/browser';
|
|
40
|
+
export * from '@enbox/auth/browser';
|
|
175
41
|
|
|
176
42
|
// ─── Re-exports from @enbox/connect ─────────────────────────────
|
|
177
43
|
//
|
|
@@ -179,7 +45,7 @@ export type {
|
|
|
179
45
|
// transports: opening/sealing envelopes and the deny token.
|
|
180
46
|
|
|
181
47
|
export { CONNECT_DENIED_TOKEN, ConnectProvider } from '@enbox/connect';
|
|
182
|
-
export type { ConnectApproval,
|
|
48
|
+
export type { ConnectApproval, ConnectRequest } from '@enbox/connect';
|
|
183
49
|
|
|
184
50
|
// ─── Browser-specific exports ───────────────────────────────────
|
|
185
51
|
//
|
|
@@ -213,6 +79,14 @@ export { MAX_PIN_ATTEMPTS, RelayConnectCancelledError, runRelayConnect } from '.
|
|
|
213
79
|
export type { RelayConnectOptions } from './relay-connect-runner.js';
|
|
214
80
|
export { encodeQr, qrToSvg } from './ui/qr.js';
|
|
215
81
|
export type { QrCode, QrSvgOptions } from './ui/qr.js';
|
|
82
|
+
export { createBlobUrlPool } from './blob-url-pool.js';
|
|
83
|
+
export type { BlobUrlLease, BlobUrlPool } from './blob-url-pool.js';
|
|
84
|
+
export { createFileEnvelopeUrlStore } from './file-envelope-url-store.js';
|
|
85
|
+
export type {
|
|
86
|
+
FileEnvelopeUrlLease,
|
|
87
|
+
FileEnvelopeUrlStore,
|
|
88
|
+
FileEnvelopeUrlStoreOptions,
|
|
89
|
+
} from './file-envelope-url-store.js';
|
|
216
90
|
|
|
217
91
|
// ─── Convenience re-exports for dapps ───────────────────────────
|
|
218
92
|
//
|
|
@@ -222,14 +96,6 @@ export type { QrCode, QrSvgOptions } from './ui/qr.js';
|
|
|
222
96
|
// more specialized is still available by importing the underlying package
|
|
223
97
|
// directly.
|
|
224
98
|
|
|
225
|
-
// Canonical typed record (from @enbox/api).
|
|
226
|
-
export { Record } from '@enbox/api';
|
|
227
|
-
|
|
228
|
-
// Custom storage adapter + DWN registration provider-auth callback shapes
|
|
229
|
-
// (from @enbox/auth).
|
|
230
|
-
export { BrowserStorage } from '@enbox/auth/browser';
|
|
231
|
-
export type { ProviderAuthParams, ProviderAuthResult } from '@enbox/auth/browser';
|
|
232
|
-
|
|
233
99
|
// Public-profile read/cache layer (from @enbox/protocols): fetch other
|
|
234
100
|
// users' published profiles (displayName + avatar/hero) from their DWNs
|
|
235
101
|
// with caching, retries, negative caching, and refcounted subscriptions.
|
|
@@ -255,12 +121,9 @@ export type {
|
|
|
255
121
|
// DWN interface enum for typing agent requests (from @enbox/agent).
|
|
256
122
|
export { DwnInterface } from '@enbox/agent';
|
|
257
123
|
|
|
258
|
-
//
|
|
259
|
-
//
|
|
260
|
-
//
|
|
261
|
-
// quota-blocked remote will next be re-probed, via
|
|
262
|
-
// `agent.sync.getRemoteSyncStatus()`; resume immediately with
|
|
263
|
-
// `agent.sync.retryRemoteNow(tenantDid, remoteEndpoint)`.
|
|
124
|
+
// Low-level sync-status types for advanced agent consumers. Dapps using a
|
|
125
|
+
// ConnectionStore receive current advertised rows through `snapshot.sync.remotes`
|
|
126
|
+
// and can call `store.retryRemote(remoteEndpoint)` without wiring agent events.
|
|
264
127
|
export type {
|
|
265
128
|
DeadLetterEntry,
|
|
266
129
|
RemoteSyncState,
|
|
@@ -270,6 +133,7 @@ export type {
|
|
|
270
133
|
SyncEvent,
|
|
271
134
|
SyncEventListener,
|
|
272
135
|
SyncHealthSummary,
|
|
136
|
+
SyncIdentityStatus,
|
|
273
137
|
} from '@enbox/agent';
|
|
274
138
|
|
|
275
139
|
// Common DWN primitives for record queries, permission scopes, and protocol
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export type ObjectUrlLease = Readonly<{
|
|
2
|
+
url: string;
|
|
3
|
+
/** Release immediately, cancelling any deferred release. Idempotent. */
|
|
4
|
+
release(): void;
|
|
5
|
+
/** Release after a grace period. The first deferred release wins. */
|
|
6
|
+
releaseAfter(delayMs: number): void;
|
|
7
|
+
}>;
|
|
8
|
+
|
|
9
|
+
const MAX_TIMER_DELAY_MS = 2_147_483_647;
|
|
10
|
+
|
|
11
|
+
function assertReleaseDelay(delayMs: number): void {
|
|
12
|
+
if (!Number.isSafeInteger(delayMs) || delayMs < 0 || delayMs > MAX_TIMER_DELAY_MS) {
|
|
13
|
+
throw new TypeError(`delayMs must be an integer between 0 and ${MAX_TIMER_DELAY_MS}.`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Private reference-counted ownership for one object URL. */
|
|
18
|
+
export class ObjectUrlReference {
|
|
19
|
+
public readonly url: string;
|
|
20
|
+
private _isRevoked = false;
|
|
21
|
+
private _references = 0;
|
|
22
|
+
private readonly _releaseTimers = new Set<ReturnType<typeof setTimeout>>();
|
|
23
|
+
|
|
24
|
+
public constructor(blob: Blob, private readonly _onEmpty: (reference: ObjectUrlReference) => void) {
|
|
25
|
+
this.url = globalThis.URL.createObjectURL(blob);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public get references(): number {
|
|
29
|
+
return this._references;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public acquire(): ObjectUrlLease {
|
|
33
|
+
if (this._isRevoked) {
|
|
34
|
+
throw new Error('Object URL has been revoked.');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this._references += 1;
|
|
38
|
+
let released = false;
|
|
39
|
+
let releaseTimer: ReturnType<typeof setTimeout> | undefined;
|
|
40
|
+
const release = (): void => {
|
|
41
|
+
if (released) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
released = true;
|
|
45
|
+
if (releaseTimer !== undefined) {
|
|
46
|
+
clearTimeout(releaseTimer);
|
|
47
|
+
this._releaseTimers.delete(releaseTimer);
|
|
48
|
+
}
|
|
49
|
+
if (this._isRevoked) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this._references -= 1;
|
|
53
|
+
if (this._references === 0) {
|
|
54
|
+
this._onEmpty(this);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
return Object.freeze({
|
|
58
|
+
url : this.url,
|
|
59
|
+
release,
|
|
60
|
+
releaseAfter : (delayMs: number): void => {
|
|
61
|
+
assertReleaseDelay(delayMs);
|
|
62
|
+
if (released || this._isRevoked || releaseTimer !== undefined) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
releaseTimer = setTimeout(release, delayMs);
|
|
66
|
+
this._releaseTimers.add(releaseTimer);
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public revoke(): void {
|
|
72
|
+
if (!this._isRevoked) {
|
|
73
|
+
this._isRevoked = true;
|
|
74
|
+
for (const timer of this._releaseTimers) {
|
|
75
|
+
clearTimeout(timer);
|
|
76
|
+
}
|
|
77
|
+
this._releaseTimers.clear();
|
|
78
|
+
this._references = 0;
|
|
79
|
+
globalThis.URL.revokeObjectURL(this.url);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -66,6 +66,9 @@ export interface RelayConnectOptions {
|
|
|
66
66
|
/** Optional icon URL for the app, shown in the wallet consent UI. */
|
|
67
67
|
appIcon?: string;
|
|
68
68
|
|
|
69
|
+
/** Stable application identifier hint available to the wallet during approval. */
|
|
70
|
+
applicationId?: string;
|
|
71
|
+
|
|
69
72
|
/** Optional client/environment metadata for wallet session display. */
|
|
70
73
|
clientMetadata?: ConnectClientMetadata;
|
|
71
74
|
|
|
@@ -78,6 +81,9 @@ export interface RelayConnectOptions {
|
|
|
78
81
|
/** User-facing request purpose. Absent means a normal connect. */
|
|
79
82
|
requestType?: ConnectRequestType;
|
|
80
83
|
|
|
84
|
+
/** Wallet profile DID that a refresh must renew. */
|
|
85
|
+
expectedProviderDid?: string;
|
|
86
|
+
|
|
81
87
|
/** Total milliseconds to poll the relay for a wallet response. */
|
|
82
88
|
timeoutMs?: number;
|
|
83
89
|
|
|
@@ -193,10 +199,12 @@ export async function runRelayConnect(options: RelayConnectOptions): Promise<Con
|
|
|
193
199
|
clientDid : clientDid.uri,
|
|
194
200
|
appName : options.appName,
|
|
195
201
|
appIcon : options.appIcon,
|
|
202
|
+
applicationId : options.applicationId,
|
|
196
203
|
clientMetadata : options.clientMetadata,
|
|
197
204
|
permissionRequests : options.permissionRequests,
|
|
198
205
|
delegateDid : options.delegatePortableDid?.uri,
|
|
199
206
|
requestType : options.requestType,
|
|
207
|
+
expectedProviderDid : options.expectedProviderDid,
|
|
200
208
|
supportedDidMethods : ['did:dht', 'did:jwk'],
|
|
201
209
|
nonce,
|
|
202
210
|
state,
|
|
@@ -243,6 +251,7 @@ export async function runRelayConnect(options: RelayConnectOptions): Promise<Con
|
|
|
243
251
|
nonce,
|
|
244
252
|
state,
|
|
245
253
|
pin,
|
|
254
|
+
expectedProviderDid : options.expectedProviderDid,
|
|
246
255
|
delegatePortableDid : options.delegatePortableDid,
|
|
247
256
|
confirmComplete : transport.confirmComplete?.bind(transport),
|
|
248
257
|
});
|
|
@@ -274,6 +283,7 @@ async function attemptPinOpen(params: {
|
|
|
274
283
|
nonce: string;
|
|
275
284
|
state: string;
|
|
276
285
|
pin: string;
|
|
286
|
+
expectedProviderDid: string | undefined;
|
|
277
287
|
delegatePortableDid: PortableDid | undefined;
|
|
278
288
|
confirmComplete: (() => Promise<void>) | undefined;
|
|
279
289
|
}): Promise<PinAttemptOutcome> {
|
|
@@ -281,8 +291,13 @@ async function attemptPinOpen(params: {
|
|
|
281
291
|
const response = await openResponse({
|
|
282
292
|
jwe : params.responseCiphertext,
|
|
283
293
|
recipientPrivateKey : params.responsePrivateKey,
|
|
284
|
-
expected : {
|
|
285
|
-
|
|
294
|
+
expected : {
|
|
295
|
+
clientDid : params.clientDid,
|
|
296
|
+
nonce : params.nonce,
|
|
297
|
+
state : params.state,
|
|
298
|
+
providerDid : params.expectedProviderDid,
|
|
299
|
+
},
|
|
300
|
+
pin: params.pin,
|
|
286
301
|
});
|
|
287
302
|
|
|
288
303
|
const delegatePortableDid = resolveDelegatePortableDid({
|