@enbox/browser 0.3.38 → 0.3.40

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.
Files changed (35) hide show
  1. package/dist/browser.mjs +16 -16
  2. package/dist/browser.mjs.map +4 -4
  3. package/dist/esm/browser-connect-handler.js +3 -3
  4. package/dist/esm/browser-connect-handler.js.map +1 -1
  5. package/dist/esm/dweb-connect-client.js +267 -190
  6. package/dist/esm/dweb-connect-client.js.map +1 -1
  7. package/dist/esm/dweb-connect-messages.js +54 -0
  8. package/dist/esm/dweb-connect-messages.js.map +1 -0
  9. package/dist/esm/dweb-connect-wallet.js +209 -0
  10. package/dist/esm/dweb-connect-wallet.js.map +1 -0
  11. package/dist/esm/index.js +9 -3
  12. package/dist/esm/index.js.map +1 -1
  13. package/dist/esm/ui/wallet-selector.js +6 -2
  14. package/dist/esm/ui/wallet-selector.js.map +1 -1
  15. package/dist/types/dweb-connect-client.d.ts +123 -59
  16. package/dist/types/dweb-connect-client.d.ts.map +1 -1
  17. package/dist/types/dweb-connect-messages.d.ts +64 -0
  18. package/dist/types/dweb-connect-messages.d.ts.map +1 -0
  19. package/dist/types/dweb-connect-wallet.d.ts +101 -0
  20. package/dist/types/dweb-connect-wallet.d.ts.map +1 -0
  21. package/dist/types/index.d.ts +8 -4
  22. package/dist/types/index.d.ts.map +1 -1
  23. package/dist/types/ui/wallet-selector.d.ts.map +1 -1
  24. package/package.json +9 -6
  25. package/src/browser-connect-handler.ts +4 -4
  26. package/src/dweb-connect-client.ts +327 -251
  27. package/src/dweb-connect-messages.ts +91 -0
  28. package/src/dweb-connect-wallet.ts +258 -0
  29. package/src/index.ts +24 -5
  30. package/src/ui/wallet-selector.ts +7 -2
  31. package/dist/esm/dweb-connect-crypto.js +0 -112
  32. package/dist/esm/dweb-connect-crypto.js.map +0 -1
  33. package/dist/types/dweb-connect-crypto.d.ts +0 -52
  34. package/dist/types/dweb-connect-crypto.d.ts.map +0 -1
  35. package/src/dweb-connect-crypto.ts +0 -156
@@ -1,9 +1,21 @@
1
1
  /**
2
- * DWeb Connect client — initiates the popup/postMessage connect flow.
2
+ * DWeb Connect client — the dapp side of the popup/postMessage connect flow.
3
3
  *
4
- * This is the dapp-side counterpart to the wallet's `/dweb-connect` page.
5
- * The wallet is opened as a popup window, and communication happens via
6
- * `window.postMessage`. No relay server, QR codes, or PINs are needed.
4
+ * {@link PopupClientTransport} implements the `@enbox/connect` kernel's
5
+ * `ConnectTransport` over a wallet popup:
6
+ *
7
+ * 1. The dapp opens `${walletUrl}/dweb-connect` as a popup window.
8
+ * 2. The wallet emits a `loaded` beacon carrying a fresh ephemeral X25519
9
+ * public key and its origin.
10
+ * 3. The kernel seals the signed connect request to that key (ECDH-ES,
11
+ * `apv` bound to the wallet origin) and the transport posts the
12
+ * ciphertext to the popup.
13
+ * 4. The wallet posts back the sealed response JWE (or the deny token),
14
+ * which the kernel opens and value-checks.
15
+ *
16
+ * Only ciphertext crosses the postMessage channel. Every message is checked
17
+ * against the wallet origin derived from the configured wallet URL (never
18
+ * `'*'`), and against the popup window as `event.source`.
7
19
  *
8
20
  * @module
9
21
  */
@@ -16,207 +28,272 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
16
28
  step((generator = generator.apply(thisArg, _arguments || [])).next());
17
29
  });
18
30
  };
19
- import { decryptPostMessagePayload, generateEphemeralKeyPair } from './dweb-connect-crypto.js';
20
- function collectBrowserClientMetadata() {
21
- const resolvedOptions = Intl.DateTimeFormat().resolvedOptions();
22
- const languages = Array.isArray(globalThis.navigator.languages)
23
- ? globalThis.navigator.languages.filter((language) => typeof language === 'string' && language.length > 0)
24
- : undefined;
25
- return Object.assign(Object.assign({ origin: globalThis.location.origin, userAgent: globalThis.navigator.userAgent, platform: globalThis.navigator.platform, language: globalThis.navigator.language }, (languages && languages.length > 0 ? { languages } : {})), (resolvedOptions.timeZone ? { timezone: resolvedOptions.timeZone } : {}));
31
+ import { assertX25519PublicJwk, CONNECT_DENIED_TOKEN, ConnectClient } from '@enbox/connect';
32
+ import { DWEB_CONNECT_LOADED_MESSAGE_TYPE, DWEB_CONNECT_PATH, DWEB_CONNECT_REQUEST_MESSAGE_TYPE, DWEB_CONNECT_RESPONSE_MESSAGE_TYPE, getTrustedMessage, } from './dweb-connect-messages.js';
33
+ /** Default budget for the whole popup handshake (beacon + user consent + response). */
34
+ const DEFAULT_TIMEOUT_MS = 300000;
35
+ /** Interval at which the transport checks whether the user closed the popup. */
36
+ const CLOSED_POLL_INTERVAL_MS = 500;
37
+ /** Window name given to the wallet popup. */
38
+ const POPUP_WINDOW_NAME = 'enbox-dweb-connect';
39
+ /** Window features given to the wallet popup. */
40
+ const POPUP_WINDOW_FEATURES = 'width=500,height=700,menubar=no,toolbar=no,location=no,status=no';
41
+ /** Guards against calling browser-only entry points outside a browser. */
42
+ function assertBrowserEnvironment() {
43
+ if (typeof window === 'undefined') {
44
+ throw new Error('[@enbox/browser] DWeb Connect is only available in browser environments.');
45
+ }
46
+ }
47
+ /**
48
+ * Thrown when the user closes the wallet popup before the wallet finished
49
+ * loading (i.e. before its `loaded` beacon arrived). Callers typically treat
50
+ * this the same as a user denial.
51
+ */
52
+ export class PopupWindowClosedError extends Error {
53
+ constructor() {
54
+ super('[@enbox/browser] Wallet popup was closed before the wallet finished loading.');
55
+ this.name = 'PopupWindowClosedError';
56
+ }
26
57
  }
27
58
  /**
28
- * Open a wallet popup and run the DWeb Connect postMessage flow.
59
+ * Popup/postMessage {@link ConnectTransport} for browser dapps.
29
60
  *
30
- * Protocol:
31
- * 1. Dapp opens `${walletUrl}/dweb-connect` as a popup.
32
- * 2. Wallet sends `{ type: 'dweb-connect-loaded' }` when ready.
33
- * 3. Dapp sends `{ type: 'dweb-connect-authorization-request', did, permissions,
34
- * appName?, appIcon?, portableIdentity? }`.
35
- * 4. Wallet shows consent UI, then sends back
36
- * `{ type: 'dweb-connect-authorization-response', delegateDid, grants }`.
37
- * 5. Popup closes.
61
+ * Single-use: construct a new transport per handshake. The **constructor**
62
+ * opens the wallet popup synchronously — so `window.open` runs inside the user
63
+ * gesture, ahead of the kernel's awaited key generation, and survives strict
64
+ * popup blockers; `requestProfile()` then awaits the wallet's `loaded` beacon;
65
+ * `deliverRequest()` posts the sealed request ciphertext; `awaitResponse()`
66
+ * resolves with the sealed response JWE, or the deny token when the user denies
67
+ * or closes the popup after the handshake was established.
38
68
  *
39
- * @returns The delegate credentials, or `undefined` if the user denied.
40
- * @throws If the popup is blocked, times out, or the wallet returns an error.
69
+ * Security properties:
70
+ * - `targetOrigin` of every outbound `postMessage` is pinned to the origin
71
+ * derived from `walletUrl` — never `'*'`.
72
+ * - Inbound messages are dropped unless `event.origin` equals the pinned
73
+ * wallet origin AND `event.source` is the popup window this transport opened.
74
+ * - The beacon's `walletOrigin` field must equal the pinned origin, and its
75
+ * `walletEpk` must be a public-only X25519 JWK; a malformed beacon from the
76
+ * genuine popup fails the handshake closed.
41
77
  */
42
- function initClient(options) {
43
- return __awaiter(this, void 0, void 0, function* () {
44
- const { walletUrl, did, permissionRequests, timeout = 300000, appName, appIcon, portableIdentity, } = options;
45
- if (typeof window === 'undefined') {
46
- throw new Error('[@enbox/browser] DWeb Connect is only available in browser environments.');
47
- }
48
- // Open the wallet's DWeb Connect page as a popup.
49
- const popupUrl = new URL('/dweb-connect', walletUrl).toString();
50
- const popup = window.open(popupUrl, 'enbox-dweb-connect', 'width=500,height=700,menubar=no,toolbar=no,location=no,status=no');
78
+ export class PopupClientTransport {
79
+ constructor(options) {
80
+ var _a;
81
+ /** {@inheritDoc ConnectTransport.requiresPin} */
82
+ this.requiresPin = false;
83
+ this._settled = false;
84
+ this._walletEpkReceived = false;
85
+ assertBrowserEnvironment();
86
+ this._walletOrigin = new URL(options.walletUrl).origin;
87
+ this._timeoutMs = (_a = options.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;
88
+ // Open the wallet popup SYNCHRONOUSLY, in the user-gesture call stack,
89
+ // before the kernel's awaited `DidJwk.create()` / `X25519.generateKey()`
90
+ // run. Strict popup blockers (Safari) reject a `window.open` issued once
91
+ // the stack has yielded to a prior `await`, so opening it here — instead of
92
+ // inside the awaited `requestProfile()` — is what keeps the flow usable.
93
+ const popupUrl = new URL(DWEB_CONNECT_PATH, options.walletUrl).toString();
94
+ const popup = window.open(popupUrl, POPUP_WINDOW_NAME, POPUP_WINDOW_FEATURES);
51
95
  if (!popup) {
52
96
  throw new Error('[@enbox/browser] Popup blocked. Allow popups for this site to connect to a wallet.');
53
97
  }
54
- // Generate an ephemeral ECDH keypair for this connect session.
55
- // The public key is sent to the wallet so it can encrypt the response
56
- // containing delegate private keys and decryption material.
57
- // Encryption is mandatory — if key generation fails (e.g. non-secure
58
- // context where crypto.subtle is unavailable), the connect flow aborts.
59
- let dappKeyPair;
60
- let dappPublicKeyBase64url;
61
- try {
62
- const ephemeral = yield generateEphemeralKeyPair();
63
- dappKeyPair = ephemeral.keyPair;
64
- dappPublicKeyBase64url = ephemeral.publicKeyBase64url;
65
- }
66
- catch (_a) {
67
- popup.close();
68
- throw new Error('[@enbox/browser] DWeb Connect requires a secure context (HTTPS) for encrypted key exchange. '
69
- + 'crypto.subtle is not available in this environment.');
70
- }
71
- return new Promise((resolve, reject) => {
72
- let settled = false;
73
- const cleanup = () => {
74
- settled = true;
75
- clearTimeout(timeoutId);
76
- window.removeEventListener('message', onMessage);
77
- };
78
- // Set up timeout.
79
- const timeoutId = setTimeout(() => {
80
- if (!settled) {
81
- cleanup();
82
- try {
83
- popup.close();
84
- }
85
- catch ( /* best effort */_a) { /* best effort */ }
86
- reject(new Error('[@enbox/browser] DWeb Connect timed out waiting for wallet response.'));
87
- }
88
- }, timeout);
89
- // Monitor popup closed without response (user closed the window).
90
- const pollClosed = setInterval(() => {
91
- if (popup.closed && !settled) {
92
- clearInterval(pollClosed);
93
- cleanup();
94
- resolve(undefined);
95
- }
96
- }, 500);
97
- const onMessage = (event) => {
98
- var _a;
99
- // Validate origin matches the wallet URL.
100
- const walletOrigin = new URL(walletUrl).origin;
101
- if (event.origin !== walletOrigin) {
102
- return;
103
- }
104
- const { type } = (_a = event.data) !== null && _a !== void 0 ? _a : {};
105
- if (type === 'dweb-connect-loaded') {
106
- // Wallet is ready — send the authorization request with
107
- // ephemeral public key and optional app metadata.
108
- popup.postMessage({
109
- type: 'dweb-connect-authorization-request',
110
- did,
111
- permissions: permissionRequests,
112
- ephemeralPublicKey: dappPublicKeyBase64url,
113
- appName,
114
- appIcon,
115
- clientMetadata: collectBrowserClientMetadata(),
116
- portableIdentity,
117
- }, walletOrigin);
118
- return;
119
- }
120
- if (type === 'dweb-connect-authorization-response') {
121
- clearInterval(pollClosed);
122
- cleanup();
123
- // If the wallet sent an explicit error, treat as denied.
124
- if (event.data.error) {
125
- resolve(undefined);
126
- return;
127
- }
128
- // Require an encrypted response. The dapp always sends an
129
- // ephemeralPublicKey, so a plaintext response means either the
130
- // wallet is outdated or something intercepted the flow.
131
- const encrypted = event.data.encryptedPayload;
132
- if (!encrypted) {
133
- resolve(undefined);
134
- return;
135
- }
136
- decryptPostMessagePayload(encrypted, dappKeyPair).then((payload) => {
137
- var _a, _b, _c;
138
- const p = payload;
139
- if (!p.delegateDid || !p.grants) {
140
- resolve(undefined);
141
- return;
142
- }
143
- resolve({
144
- delegatePortableDid: p.delegateDid,
145
- delegateGrants: p.grants,
146
- connectedDid: (_b = (_a = p.connectedDid) !== null && _a !== void 0 ? _a : did) !== null && _b !== void 0 ? _b : p.delegateDid.uri,
147
- sessionRevocations: (_c = p.sessionRevocations) !== null && _c !== void 0 ? _c : undefined,
148
- });
149
- }).catch(() => {
150
- // Decryption failed — treat as denied.
151
- resolve(undefined);
152
- });
153
- }
98
+ this._popup = popup;
99
+ this._walletEpkPromise = new Promise((resolve, reject) => {
100
+ this._resolveWalletEpk = resolve;
101
+ this._rejectWalletEpk = reject;
102
+ });
103
+ // Created up-front so a response (or deny) arriving before
104
+ // `awaitResponse()` is called is never dropped. The no-op catch marks
105
+ // early rejections (timeout, popup closed during load) as handled until
106
+ // the kernel attaches its own handlers via `awaitResponse()`.
107
+ this._responsePromise = new Promise((resolve, reject) => {
108
+ this._resolveResponse = resolve;
109
+ this._rejectResponse = reject;
110
+ });
111
+ this._responsePromise.catch(() => undefined);
112
+ // Listen synchronously, before the wallet page can emit its `loaded`
113
+ // beacon, so the beacon is never missed while the kernel awaits key
114
+ // generation ahead of `requestProfile()`.
115
+ this._messageListener = (event) => { this.onMessage(event); };
116
+ window.addEventListener('message', this._messageListener);
117
+ this._timeoutId = setTimeout(() => {
118
+ this.fail(new Error('[@enbox/browser] DWeb Connect timed out waiting for wallet response.'));
119
+ }, this._timeoutMs);
120
+ this._closedPollId = setInterval(() => { this.onClosedPoll(); }, CLOSED_POLL_INTERVAL_MS);
121
+ }
122
+ /**
123
+ * Awaits the already-open popup's `loaded` beacon, then returns the popup
124
+ * channel profile: ECDH-ES encryption to the beacon's ephemeral key with the
125
+ * pinned wallet origin as the `apv` binding, a `post_message` reply
126
+ * descriptor, and the client-supplied `state` correlator.
127
+ *
128
+ * The popup was opened synchronously at construction, so this method only
129
+ * awaits the beacon — it never issues the blocker-sensitive `window.open`.
130
+ *
131
+ * @param state - The handshake correlator minted by the {@link ConnectClient}.
132
+ * @throws If the user closes the popup before the beacon arrives
133
+ * ({@link PopupWindowClosedError}), the beacon is malformed, or on
134
+ * timeout.
135
+ */
136
+ requestProfile(state) {
137
+ return __awaiter(this, void 0, void 0, function* () {
138
+ const walletEpk = yield this._walletEpkPromise;
139
+ return {
140
+ encryption: { mode: 'ecdh-es', walletEpk, walletOrigin: this._walletOrigin },
141
+ reply: { mode: 'post_message' },
142
+ state,
154
143
  };
155
- window.addEventListener('message', onMessage);
156
144
  });
157
- });
145
+ }
146
+ /**
147
+ * Posts the sealed request ciphertext to the wallet popup with the
148
+ * `targetOrigin` pinned to the wallet origin.
149
+ */
150
+ deliverRequest(jwe) {
151
+ return __awaiter(this, void 0, void 0, function* () {
152
+ this._popup.postMessage({ type: DWEB_CONNECT_REQUEST_MESSAGE_TYPE, jwe }, this._walletOrigin);
153
+ });
154
+ }
155
+ /**
156
+ * Awaits the wallet's response ciphertext: the sealed response JWE, or the
157
+ * deny token when the user denies in the wallet or closes the popup.
158
+ * Rejects on timeout.
159
+ */
160
+ awaitResponse() {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ return yield this._responsePromise;
163
+ });
164
+ }
165
+ onMessage(event) {
166
+ const message = getTrustedMessage(event, this._walletOrigin, this._popup);
167
+ if (message === undefined) {
168
+ return;
169
+ }
170
+ if (message.type === DWEB_CONNECT_LOADED_MESSAGE_TYPE) {
171
+ this.onLoadedBeacon(message);
172
+ return;
173
+ }
174
+ if (message.type === DWEB_CONNECT_RESPONSE_MESSAGE_TYPE) {
175
+ this.onResponseMessage(message);
176
+ }
177
+ }
178
+ onLoadedBeacon(message) {
179
+ var _a;
180
+ if (this._settled || this._walletEpkReceived) {
181
+ return;
182
+ }
183
+ // The beacon passed the origin and source checks, so a malformed payload
184
+ // is a protocol violation by the genuine popup — fail closed. The X25519
185
+ // public-JWK shape check is delegated to the connect kernel.
186
+ let walletEpk;
187
+ try {
188
+ assertX25519PublicJwk(message.walletEpk);
189
+ walletEpk = message.walletEpk;
190
+ }
191
+ catch (_b) {
192
+ this.fail(new Error('[@enbox/browser] Wallet loaded beacon did not carry a valid X25519 public key.'));
193
+ return;
194
+ }
195
+ if (message.walletOrigin !== this._walletOrigin) {
196
+ this.fail(new Error('[@enbox/browser] Wallet loaded beacon origin does not match the configured wallet origin.'));
197
+ return;
198
+ }
199
+ this._walletEpkReceived = true;
200
+ (_a = this._resolveWalletEpk) === null || _a === void 0 ? void 0 : _a.call(this, walletEpk);
201
+ }
202
+ onResponseMessage(message) {
203
+ var _a, _b;
204
+ if (this._settled) {
205
+ return;
206
+ }
207
+ if (typeof message.payload !== 'string') {
208
+ this.fail(new Error('[@enbox/browser] Wallet response message did not carry a ciphertext payload.'));
209
+ return;
210
+ }
211
+ this._settled = true;
212
+ this.cleanup();
213
+ // No-op on the normal path; unblocks `requestProfile()` if a response
214
+ // somehow arrives before the beacon.
215
+ (_a = this._rejectWalletEpk) === null || _a === void 0 ? void 0 : _a.call(this, new Error('[@enbox/browser] Wallet responded before the handshake was established.'));
216
+ (_b = this._resolveResponse) === null || _b === void 0 ? void 0 : _b.call(this, message.payload);
217
+ }
218
+ onClosedPoll() {
219
+ var _a;
220
+ if (this._settled || this._popup.closed !== true) {
221
+ return;
222
+ }
223
+ if (!this._walletEpkReceived) {
224
+ // Closed before the wallet ever loaded — the handshake cannot proceed.
225
+ this.fail(new PopupWindowClosedError());
226
+ return;
227
+ }
228
+ // Closed after the handshake was established — treat as a user denial.
229
+ this._settled = true;
230
+ this.cleanup();
231
+ (_a = this._resolveResponse) === null || _a === void 0 ? void 0 : _a.call(this, CONNECT_DENIED_TOKEN);
232
+ }
233
+ fail(error) {
234
+ var _a, _b;
235
+ if (this._settled) {
236
+ return;
237
+ }
238
+ this._settled = true;
239
+ this.cleanup();
240
+ try {
241
+ this._popup.close();
242
+ }
243
+ catch ( /* best effort */_c) { /* best effort */ }
244
+ (_a = this._rejectWalletEpk) === null || _a === void 0 ? void 0 : _a.call(this, error);
245
+ (_b = this._rejectResponse) === null || _b === void 0 ? void 0 : _b.call(this, error);
246
+ }
247
+ cleanup() {
248
+ clearTimeout(this._timeoutId);
249
+ clearInterval(this._closedPollId);
250
+ if (this._messageListener !== undefined) {
251
+ window.removeEventListener('message', this._messageListener);
252
+ this._messageListener = undefined;
253
+ }
254
+ }
255
+ }
256
+ /** Collects self-reported environment hints for the wallet's session display. */
257
+ function collectBrowserClientMetadata() {
258
+ const resolvedOptions = Intl.DateTimeFormat().resolvedOptions();
259
+ const languages = Array.isArray(globalThis.navigator.languages)
260
+ ? globalThis.navigator.languages.filter((language) => typeof language === 'string' && language.length > 0)
261
+ : undefined;
262
+ return Object.assign(Object.assign({ origin: globalThis.location.origin, userAgent: globalThis.navigator.userAgent, platform: globalThis.navigator.platform, language: globalThis.navigator.language }, (languages && languages.length > 0 ? { languages } : {})), (resolvedOptions.timeZone ? { timezone: resolvedOptions.timeZone } : {}));
158
263
  }
159
264
  /**
160
- * Probe whether a wallet supports a specific DID via a hidden iframe.
265
+ * Runs one DWeb Connect popup handshake end-to-end: opens the wallet popup,
266
+ * drives the `@enbox/connect` kernel client over a {@link PopupClientTransport},
267
+ * and returns the delegated credentials.
161
268
  *
162
- * Sends a `dweb-connect-support-request` message to the wallet and
163
- * waits for a `dweb-connect-support-response`. Useful for checking
164
- * multiple wallet URLs to find the one that manages a given DID.
165
- *
166
- * @param walletUrl - Base URL of the wallet to probe.
167
- * @param did - The DID to check.
168
- * @param timeout - Probe timeout in ms. Default: 5_000 (5 seconds).
169
- * @returns `true` if the wallet manages the DID, `false` otherwise.
269
+ * @returns The delegate credentials, or `undefined` when the user denied the
270
+ * request or closed the popup.
271
+ * @throws If the popup is blocked, the handshake times out, or the wallet
272
+ * returns an invalid response.
170
273
  */
171
- function probeWalletSupport(walletUrl_1, did_1) {
172
- return __awaiter(this, arguments, void 0, function* (walletUrl, did, timeout = 5000) {
173
- if (typeof window === 'undefined') {
174
- return false;
175
- }
176
- return new Promise((resolve) => {
177
- const iframe = document.createElement('iframe');
178
- iframe.style.display = 'none';
179
- iframe.src = walletUrl;
180
- let settled = false;
181
- const cleanup = () => {
182
- settled = true;
183
- window.removeEventListener('message', onMessage);
184
- try {
185
- document.body.removeChild(iframe);
186
- }
187
- catch ( /* best effort */_a) { /* best effort */ }
188
- };
189
- const timeoutId = setTimeout(() => {
190
- if (!settled) {
191
- cleanup();
192
- resolve(false);
193
- }
194
- }, timeout);
195
- const onMessage = (event) => {
196
- var _a;
197
- const walletOrigin = new URL(walletUrl).origin;
198
- if (event.origin !== walletOrigin) {
199
- return;
200
- }
201
- const { type, supported } = (_a = event.data) !== null && _a !== void 0 ? _a : {};
202
- if (type === 'dweb-connect-support-response') {
203
- clearTimeout(timeoutId);
204
- cleanup();
205
- resolve(!!supported);
206
- }
207
- };
208
- window.addEventListener('message', onMessage);
209
- iframe.addEventListener('load', () => {
210
- var _a;
211
- const walletOrigin = new URL(walletUrl).origin;
212
- (_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.postMessage({
213
- type: 'dweb-connect-support-request',
214
- did,
215
- }, walletOrigin);
216
- });
217
- document.body.appendChild(iframe);
274
+ export function connectViaPopup(options) {
275
+ return __awaiter(this, void 0, void 0, function* () {
276
+ var _a;
277
+ const transport = new PopupClientTransport({
278
+ walletUrl: options.walletUrl,
279
+ timeoutMs: options.timeout,
218
280
  });
281
+ const client = new ConnectClient({ transport });
282
+ try {
283
+ return yield client.connect({
284
+ appName: (_a = options.appName) !== null && _a !== void 0 ? _a : globalThis.location.host,
285
+ appIcon: options.appIcon,
286
+ clientMetadata: collectBrowserClientMetadata(),
287
+ permissionRequests: options.permissionRequests,
288
+ });
289
+ }
290
+ catch (error) {
291
+ if (error instanceof PopupWindowClosedError) {
292
+ // The user closed the wallet before it loaded — same as a denial.
293
+ return undefined;
294
+ }
295
+ throw error;
296
+ }
219
297
  });
220
298
  }
221
- export const DWebConnect = { initClient, probeWalletSupport };
222
299
  //# sourceMappingURL=dweb-connect-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dweb-connect-client.js","sourceRoot":"","sources":["../../src/dweb-connect-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dweb-connect-client.js","sourceRoot":"","sources":["../../src/dweb-connect-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Wire shapes for the DWeb Connect popup/postMessage channel.
3
+ *
4
+ * The dapp and the wallet exchange exactly three message kinds over
5
+ * `window.postMessage`:
6
+ *
7
+ * 1. `loaded` beacon (wallet → dapp): announces the wallet page is ready and
8
+ * carries a fresh ephemeral X25519 public key plus the wallet's origin.
9
+ * 2. `request` (dapp → wallet): the sealed connect request JWE — ciphertext
10
+ * only, encrypted to the beacon key with ECDH-ES and the wallet origin
11
+ * bound into the JWE `apv` header.
12
+ * 3. `response` (wallet → dapp): the sealed connect response JWE, or the
13
+ * literal deny token — again ciphertext only.
14
+ *
15
+ * Plaintext never crosses the channel, and both sides pin `targetOrigin`
16
+ * and verify `event.origin` / `event.source` on every message.
17
+ *
18
+ * @module
19
+ */
20
+ /** Path of the wallet's DWeb Connect page, opened as a popup by the dapp. */
21
+ export const DWEB_CONNECT_PATH = '/dweb-connect';
22
+ /** Message type of the wallet's `loaded` beacon (wallet → dapp). */
23
+ export const DWEB_CONNECT_LOADED_MESSAGE_TYPE = 'enbox-connect-loaded';
24
+ /** Message type carrying the sealed connect request JWE (dapp → wallet). */
25
+ export const DWEB_CONNECT_REQUEST_MESSAGE_TYPE = 'enbox-connect-request';
26
+ /** Message type carrying the sealed connect response JWE or deny token (wallet → dapp). */
27
+ export const DWEB_CONNECT_RESPONSE_MESSAGE_TYPE = 'enbox-connect-response';
28
+ /**
29
+ * Applies the shared inbound-message trust filter for the popup channel:
30
+ * pins the message to the expected `event.origin`, pins its `event.source` to
31
+ * the expected window, and requires a non-null object payload.
32
+ *
33
+ * Returns the payload cast to a plain record when every check passes, or
34
+ * `undefined` when the message must be dropped. Both the dapp-side and
35
+ * wallet-side transports early-return on `undefined` before inspecting any
36
+ * message field — this is the security-critical filter that keeps hostile
37
+ * origins and stray windows off the channel.
38
+ */
39
+ export function getTrustedMessage(event, expectedOrigin, expectedSource) {
40
+ // Origin pinning: only messages from the expected origin count.
41
+ if (event.origin !== expectedOrigin) {
42
+ return undefined;
43
+ }
44
+ // Source pinning: the message must come from the expected window.
45
+ if (event.source !== expectedSource) {
46
+ return undefined;
47
+ }
48
+ const data = event.data;
49
+ if (typeof data !== 'object' || data === null) {
50
+ return undefined;
51
+ }
52
+ return data;
53
+ }
54
+ //# sourceMappingURL=dweb-connect-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dweb-connect-messages.js","sourceRoot":"","sources":["../../src/dweb-connect-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,6EAA6E;AAC7E,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAEjD,oEAAoE;AACpE,MAAM,CAAC,MAAM,gCAAgC,GAAG,sBAAsB,CAAC;AAEvE,4EAA4E;AAC5E,MAAM,CAAC,MAAM,iCAAiC,GAAG,uBAAuB,CAAC;AAEzE,2FAA2F;AAC3F,MAAM,CAAC,MAAM,kCAAkC,GAAG,wBAAwB,CAAC;AAgC3E;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAmB,EACnB,cAAsB,EACtB,cAAkC;IAElC,gEAAgE;IAChE,IAAI,KAAK,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;QAAC,OAAO,SAAS,CAAC;IAAC,CAAC;IAE1D,kEAAkE;IAClE,IAAI,KAAK,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;QAAC,OAAO,SAAS,CAAC;IAAC,CAAC;IAE1D,MAAM,IAAI,GAAY,KAAK,CAAC,IAAI,CAAC;IACjC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAAC,OAAO,SAAS,CAAC;IAAC,CAAC;IAEpE,OAAO,IAA+B,CAAC;AACzC,CAAC"}