@enbox/browser 0.1.2 → 0.1.4
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/esm/browser-connect-handler.js +66 -0
- package/dist/esm/browser-connect-handler.js.map +1 -0
- package/dist/esm/dweb-connect-client.js +171 -0
- package/dist/esm/dweb-connect-client.js.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/ui/wallet-selector.js +313 -0
- package/dist/esm/ui/wallet-selector.js.map +1 -0
- package/dist/types/browser-connect-handler.d.ts +62 -0
- package/dist/types/browser-connect-handler.d.ts.map +1 -0
- package/dist/types/dweb-connect-client.d.ts +63 -0
- package/dist/types/dweb-connect-client.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/ui/wallet-selector.d.ts +12 -0
- package/dist/types/ui/wallet-selector.d.ts.map +1 -0
- package/package.json +7 -6
- package/src/browser-connect-handler.ts +103 -0
- package/src/dweb-connect-client.ts +214 -0
- package/src/index.ts +5 -1
- package/src/ui/wallet-selector.ts +349 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser connect handler for `@enbox/auth`.
|
|
3
|
+
*
|
|
4
|
+
* Implements the {@link ConnectHandler} interface using browser-native
|
|
5
|
+
* DWeb Connect (popup + postMessage) with a wallet selector modal.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
10
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
11
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
12
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
13
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
14
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
15
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
import { DWebConnect } from './dweb-connect-client.js';
|
|
19
|
+
import { showWalletSelector } from './ui/wallet-selector.js';
|
|
20
|
+
/** Default wallets shown in the selector when no overrides are provided. */
|
|
21
|
+
export const DEFAULT_WALLETS = [
|
|
22
|
+
{ name: 'Enbox Wallet', url: 'https://wallet.enbox.org' },
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Create a browser-native connect handler using DWeb Connect
|
|
26
|
+
* (popup + postMessage).
|
|
27
|
+
*
|
|
28
|
+
* This handler:
|
|
29
|
+
* 1. Shows a wallet selector modal (or uses a provided walletUrl).
|
|
30
|
+
* 2. Opens the selected wallet as a popup window.
|
|
31
|
+
* 3. Runs the DWeb Connect postMessage protocol.
|
|
32
|
+
* 4. Returns the delegate credentials on success.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { AuthManager } from '@enbox/auth';
|
|
37
|
+
* import { BrowserConnectHandler } from '@enbox/browser';
|
|
38
|
+
*
|
|
39
|
+
* const auth = await AuthManager.create({
|
|
40
|
+
* connectHandler: BrowserConnectHandler(),
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* const session = await auth.connect({ protocols: [NotesProtocol] });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export function BrowserConnectHandler(options = {}) {
|
|
47
|
+
const { wallets = DEFAULT_WALLETS, walletUrl: fixedWalletUrl, timeout, } = options;
|
|
48
|
+
return {
|
|
49
|
+
requestAccess(params) {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
// 1. Determine wallet URL.
|
|
52
|
+
let walletUrl = fixedWalletUrl;
|
|
53
|
+
if (!walletUrl) {
|
|
54
|
+
walletUrl = yield showWalletSelector(wallets);
|
|
55
|
+
}
|
|
56
|
+
// 2. Run the DWeb Connect popup flow.
|
|
57
|
+
return DWebConnect.initClient({
|
|
58
|
+
walletUrl,
|
|
59
|
+
permissionRequests: params.permissionRequests,
|
|
60
|
+
timeout,
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=browser-connect-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-connect-handler.js","sourceRoot":"","sources":["../../src/browser-connect-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;;;;;;;;;;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAc7D,4EAA4E;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAmB;IAC7C,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,0BAA0B,EAAE;CAC1D,CAAC;AAuBF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,qBAAqB,CACnC,UAAwC,EAAE;IAE1C,MAAM,EACJ,OAAO,GAAG,eAAe,EACzB,SAAS,EAAE,cAAc,EACzB,OAAO,GACR,GAAG,OAAO,CAAC;IAEZ,OAAO;QACC,aAAa,CAAC,MAEnB;;gBACC,2BAA2B;gBAC3B,IAAI,SAAS,GAAG,cAAc,CAAC;gBAC/B,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,SAAS,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;gBAChD,CAAC;gBAED,sCAAsC;gBACtC,OAAO,WAAW,CAAC,UAAU,CAAC;oBAC5B,SAAS;oBACT,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;oBAC7C,OAAO;iBACR,CAAC,CAAC;YACL,CAAC;SAAA;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DWeb Connect client — initiates the popup/postMessage connect flow.
|
|
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.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
11
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
12
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
13
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
14
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
15
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
16
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Open a wallet popup and run the DWeb Connect postMessage flow.
|
|
21
|
+
*
|
|
22
|
+
* Protocol:
|
|
23
|
+
* 1. Dapp opens `${walletUrl}/dweb-connect` as a popup.
|
|
24
|
+
* 2. Wallet sends `{ type: 'dweb-connect-loaded' }` when ready.
|
|
25
|
+
* 3. Dapp sends `{ type: 'dweb-connect-authorization-request', did, permissions }`.
|
|
26
|
+
* 4. Wallet shows consent UI, then sends back
|
|
27
|
+
* `{ type: 'dweb-connect-authorization-response', delegateDid, grants }`.
|
|
28
|
+
* 5. Popup closes.
|
|
29
|
+
*
|
|
30
|
+
* @returns The delegate credentials, or `undefined` if the user denied.
|
|
31
|
+
* @throws If the popup is blocked, times out, or the wallet returns an error.
|
|
32
|
+
*/
|
|
33
|
+
function initClient(options) {
|
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
const { walletUrl, did, permissionRequests, timeout = 300000, } = options;
|
|
36
|
+
if (typeof window === 'undefined') {
|
|
37
|
+
throw new Error('[@enbox/auth] DWeb Connect is only available in browser environments.');
|
|
38
|
+
}
|
|
39
|
+
// Open the wallet's DWeb Connect page as a popup.
|
|
40
|
+
const popupUrl = new URL('/dweb-connect', walletUrl).toString();
|
|
41
|
+
const popup = window.open(popupUrl, 'enbox-dweb-connect', 'width=500,height=700,menubar=no,toolbar=no,location=no,status=no');
|
|
42
|
+
if (!popup) {
|
|
43
|
+
throw new Error('[@enbox/auth] Popup blocked. Allow popups for this site to connect to a wallet.');
|
|
44
|
+
}
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
let settled = false;
|
|
47
|
+
const cleanup = () => {
|
|
48
|
+
settled = true;
|
|
49
|
+
clearTimeout(timeoutId);
|
|
50
|
+
window.removeEventListener('message', onMessage);
|
|
51
|
+
};
|
|
52
|
+
// Set up timeout.
|
|
53
|
+
const timeoutId = setTimeout(() => {
|
|
54
|
+
if (!settled) {
|
|
55
|
+
cleanup();
|
|
56
|
+
try {
|
|
57
|
+
popup.close();
|
|
58
|
+
}
|
|
59
|
+
catch ( /* best effort */_a) { /* best effort */ }
|
|
60
|
+
reject(new Error('[@enbox/auth] DWeb Connect timed out waiting for wallet response.'));
|
|
61
|
+
}
|
|
62
|
+
}, timeout);
|
|
63
|
+
// Monitor popup closed without response (user closed the window).
|
|
64
|
+
const pollClosed = setInterval(() => {
|
|
65
|
+
if (popup.closed && !settled) {
|
|
66
|
+
clearInterval(pollClosed);
|
|
67
|
+
cleanup();
|
|
68
|
+
resolve(undefined);
|
|
69
|
+
}
|
|
70
|
+
}, 500);
|
|
71
|
+
const onMessage = (event) => {
|
|
72
|
+
var _a;
|
|
73
|
+
// Validate origin matches the wallet URL.
|
|
74
|
+
const walletOrigin = new URL(walletUrl).origin;
|
|
75
|
+
if (event.origin !== walletOrigin) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const { type } = (_a = event.data) !== null && _a !== void 0 ? _a : {};
|
|
79
|
+
if (type === 'dweb-connect-loaded') {
|
|
80
|
+
// Wallet is ready — send the authorization request.
|
|
81
|
+
popup.postMessage({
|
|
82
|
+
type: 'dweb-connect-authorization-request',
|
|
83
|
+
did,
|
|
84
|
+
permissions: permissionRequests,
|
|
85
|
+
}, walletOrigin);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (type === 'dweb-connect-authorization-response') {
|
|
89
|
+
clearInterval(pollClosed);
|
|
90
|
+
cleanup();
|
|
91
|
+
const { delegateDid, grants } = event.data;
|
|
92
|
+
if (!delegateDid || !grants) {
|
|
93
|
+
// User denied the request.
|
|
94
|
+
resolve(undefined);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
resolve({
|
|
98
|
+
delegatePortableDid: delegateDid,
|
|
99
|
+
delegateGrants: grants,
|
|
100
|
+
connectedDid: did !== null && did !== void 0 ? did : delegateDid.uri,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
window.addEventListener('message', onMessage);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Probe whether a wallet supports a specific DID via a hidden iframe.
|
|
110
|
+
*
|
|
111
|
+
* Sends a `dweb-connect-support-request` message to the wallet and
|
|
112
|
+
* waits for a `dweb-connect-support-response`. Useful for checking
|
|
113
|
+
* multiple wallet URLs to find the one that manages a given DID.
|
|
114
|
+
*
|
|
115
|
+
* @param walletUrl - Base URL of the wallet to probe.
|
|
116
|
+
* @param did - The DID to check.
|
|
117
|
+
* @param timeout - Probe timeout in ms. Default: 5_000 (5 seconds).
|
|
118
|
+
* @returns `true` if the wallet manages the DID, `false` otherwise.
|
|
119
|
+
*/
|
|
120
|
+
function probeWalletSupport(walletUrl_1, did_1) {
|
|
121
|
+
return __awaiter(this, arguments, void 0, function* (walletUrl, did, timeout = 5000) {
|
|
122
|
+
if (typeof window === 'undefined') {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
return new Promise((resolve) => {
|
|
126
|
+
const iframe = document.createElement('iframe');
|
|
127
|
+
iframe.style.display = 'none';
|
|
128
|
+
iframe.src = walletUrl;
|
|
129
|
+
let settled = false;
|
|
130
|
+
const cleanup = () => {
|
|
131
|
+
settled = true;
|
|
132
|
+
window.removeEventListener('message', onMessage);
|
|
133
|
+
try {
|
|
134
|
+
document.body.removeChild(iframe);
|
|
135
|
+
}
|
|
136
|
+
catch ( /* best effort */_a) { /* best effort */ }
|
|
137
|
+
};
|
|
138
|
+
const timeoutId = setTimeout(() => {
|
|
139
|
+
if (!settled) {
|
|
140
|
+
cleanup();
|
|
141
|
+
resolve(false);
|
|
142
|
+
}
|
|
143
|
+
}, timeout);
|
|
144
|
+
const onMessage = (event) => {
|
|
145
|
+
var _a;
|
|
146
|
+
const walletOrigin = new URL(walletUrl).origin;
|
|
147
|
+
if (event.origin !== walletOrigin) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const { type, supported } = (_a = event.data) !== null && _a !== void 0 ? _a : {};
|
|
151
|
+
if (type === 'dweb-connect-support-response') {
|
|
152
|
+
clearTimeout(timeoutId);
|
|
153
|
+
cleanup();
|
|
154
|
+
resolve(!!supported);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
window.addEventListener('message', onMessage);
|
|
158
|
+
iframe.addEventListener('load', () => {
|
|
159
|
+
var _a;
|
|
160
|
+
const walletOrigin = new URL(walletUrl).origin;
|
|
161
|
+
(_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.postMessage({
|
|
162
|
+
type: 'dweb-connect-support-request',
|
|
163
|
+
did,
|
|
164
|
+
}, walletOrigin);
|
|
165
|
+
});
|
|
166
|
+
document.body.appendChild(iframe);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
export const DWebConnect = { initClient, probeWalletSupport };
|
|
171
|
+
//# sourceMappingURL=dweb-connect-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dweb-connect-client.js","sourceRoot":"","sources":["../../src/dweb-connect-client.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/index.js
CHANGED
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEtF,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wallet selector modal — a self-contained, framework-agnostic UI component.
|
|
3
|
+
*
|
|
4
|
+
* Injected into the DOM as a Shadow DOM element to prevent style conflicts.
|
|
5
|
+
* Inspired by WalletConnect's Web3Modal pattern.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
/** Shows the wallet selector modal and resolves with the chosen wallet URL. */
|
|
10
|
+
export function showWalletSelector(wallets) {
|
|
11
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
12
|
+
throw new Error('[@enbox/auth] Wallet selector is only available in browser environments.');
|
|
13
|
+
}
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
var _a, _b;
|
|
16
|
+
// Create the host element with Shadow DOM isolation.
|
|
17
|
+
const host = document.createElement('div');
|
|
18
|
+
host.id = 'enbox-wallet-selector';
|
|
19
|
+
const shadow = host.attachShadow({ mode: 'open' });
|
|
20
|
+
const cleanup = () => {
|
|
21
|
+
try {
|
|
22
|
+
document.body.removeChild(host);
|
|
23
|
+
}
|
|
24
|
+
catch ( /* best effort */_a) { /* best effort */ }
|
|
25
|
+
};
|
|
26
|
+
// Detect dark mode.
|
|
27
|
+
const isDark = (_a = window.matchMedia) === null || _a === void 0 ? void 0 : _a.call(window, '(prefers-color-scheme: dark)').matches;
|
|
28
|
+
// Build styles.
|
|
29
|
+
const style = document.createElement('style');
|
|
30
|
+
style.textContent = buildStyles(isDark);
|
|
31
|
+
shadow.appendChild(style);
|
|
32
|
+
// Build modal DOM.
|
|
33
|
+
const overlay = document.createElement('div');
|
|
34
|
+
overlay.className = 'overlay';
|
|
35
|
+
const modal = document.createElement('div');
|
|
36
|
+
modal.className = 'modal';
|
|
37
|
+
// Header
|
|
38
|
+
const header = document.createElement('div');
|
|
39
|
+
header.className = 'header';
|
|
40
|
+
const title = document.createElement('h2');
|
|
41
|
+
title.textContent = 'Connect Wallet';
|
|
42
|
+
const closeBtn = document.createElement('button');
|
|
43
|
+
closeBtn.className = 'close-btn';
|
|
44
|
+
closeBtn.innerHTML = '×';
|
|
45
|
+
closeBtn.addEventListener('click', () => {
|
|
46
|
+
cleanup();
|
|
47
|
+
reject(new Error('[@enbox/auth] Wallet selection cancelled.'));
|
|
48
|
+
});
|
|
49
|
+
header.appendChild(title);
|
|
50
|
+
header.appendChild(closeBtn);
|
|
51
|
+
modal.appendChild(header);
|
|
52
|
+
// Wallet list
|
|
53
|
+
const list = document.createElement('div');
|
|
54
|
+
list.className = 'wallet-list';
|
|
55
|
+
for (const wallet of wallets) {
|
|
56
|
+
const item = document.createElement('button');
|
|
57
|
+
item.className = 'wallet-item';
|
|
58
|
+
const icon = document.createElement('img');
|
|
59
|
+
icon.src = (_b = wallet.icon) !== null && _b !== void 0 ? _b : faviconUrl(wallet.url);
|
|
60
|
+
icon.alt = wallet.name;
|
|
61
|
+
icon.width = 32;
|
|
62
|
+
icon.height = 32;
|
|
63
|
+
icon.onerror = () => { icon.style.display = 'none'; };
|
|
64
|
+
const name = document.createElement('span');
|
|
65
|
+
name.className = 'wallet-name';
|
|
66
|
+
name.textContent = wallet.name;
|
|
67
|
+
const arrow = document.createElement('span');
|
|
68
|
+
arrow.className = 'arrow';
|
|
69
|
+
arrow.textContent = '\u203A'; // ›
|
|
70
|
+
item.appendChild(icon);
|
|
71
|
+
item.appendChild(name);
|
|
72
|
+
item.appendChild(arrow);
|
|
73
|
+
item.addEventListener('click', () => {
|
|
74
|
+
cleanup();
|
|
75
|
+
resolve(wallet.url);
|
|
76
|
+
});
|
|
77
|
+
list.appendChild(item);
|
|
78
|
+
}
|
|
79
|
+
modal.appendChild(list);
|
|
80
|
+
// Separator
|
|
81
|
+
const sep = document.createElement('div');
|
|
82
|
+
sep.className = 'separator';
|
|
83
|
+
const sepLine1 = document.createElement('div');
|
|
84
|
+
sepLine1.className = 'sep-line';
|
|
85
|
+
const sepText = document.createElement('span');
|
|
86
|
+
sepText.textContent = 'or';
|
|
87
|
+
const sepLine2 = document.createElement('div');
|
|
88
|
+
sepLine2.className = 'sep-line';
|
|
89
|
+
sep.appendChild(sepLine1);
|
|
90
|
+
sep.appendChild(sepText);
|
|
91
|
+
sep.appendChild(sepLine2);
|
|
92
|
+
modal.appendChild(sep);
|
|
93
|
+
// Custom URL input
|
|
94
|
+
const inputGroup = document.createElement('div');
|
|
95
|
+
inputGroup.className = 'input-group';
|
|
96
|
+
const input = document.createElement('input');
|
|
97
|
+
input.type = 'url';
|
|
98
|
+
input.placeholder = 'Enter wallet URL...';
|
|
99
|
+
input.className = 'url-input';
|
|
100
|
+
const goBtn = document.createElement('button');
|
|
101
|
+
goBtn.className = 'go-btn';
|
|
102
|
+
goBtn.textContent = 'Connect';
|
|
103
|
+
goBtn.disabled = true;
|
|
104
|
+
input.addEventListener('input', () => {
|
|
105
|
+
goBtn.disabled = !isValidUrl(input.value);
|
|
106
|
+
});
|
|
107
|
+
input.addEventListener('keydown', (e) => {
|
|
108
|
+
if (e.key === 'Enter' && isValidUrl(input.value)) {
|
|
109
|
+
cleanup();
|
|
110
|
+
resolve(normalizeUrl(input.value));
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
goBtn.addEventListener('click', () => {
|
|
114
|
+
if (isValidUrl(input.value)) {
|
|
115
|
+
cleanup();
|
|
116
|
+
resolve(normalizeUrl(input.value));
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
inputGroup.appendChild(input);
|
|
120
|
+
inputGroup.appendChild(goBtn);
|
|
121
|
+
modal.appendChild(inputGroup);
|
|
122
|
+
// Close on overlay click.
|
|
123
|
+
overlay.addEventListener('click', (e) => {
|
|
124
|
+
if (e.target === overlay) {
|
|
125
|
+
cleanup();
|
|
126
|
+
reject(new Error('[@enbox/auth] Wallet selection cancelled.'));
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
// Close on Escape.
|
|
130
|
+
const onKeydown = (e) => {
|
|
131
|
+
if (e.key === 'Escape') {
|
|
132
|
+
document.removeEventListener('keydown', onKeydown);
|
|
133
|
+
cleanup();
|
|
134
|
+
reject(new Error('[@enbox/auth] Wallet selection cancelled.'));
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
document.addEventListener('keydown', onKeydown);
|
|
138
|
+
overlay.appendChild(modal);
|
|
139
|
+
shadow.appendChild(overlay);
|
|
140
|
+
document.body.appendChild(host);
|
|
141
|
+
// Focus the input for keyboard-first users.
|
|
142
|
+
input.focus();
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
// ─── Helpers ─────────────────────────────────────────────────────
|
|
146
|
+
function faviconUrl(walletUrl) {
|
|
147
|
+
return `https://t3.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=${walletUrl}&size=128`;
|
|
148
|
+
}
|
|
149
|
+
function isValidUrl(value) {
|
|
150
|
+
try {
|
|
151
|
+
const url = new URL(value.includes('://') ? value : `https://${value}`);
|
|
152
|
+
return url.protocol === 'https:' || url.protocol === 'http:';
|
|
153
|
+
}
|
|
154
|
+
catch (_a) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function normalizeUrl(value) {
|
|
159
|
+
if (!value.includes('://')) {
|
|
160
|
+
value = `https://${value}`;
|
|
161
|
+
}
|
|
162
|
+
const url = new URL(value);
|
|
163
|
+
// Return origin only (strip path/trailing slash).
|
|
164
|
+
return url.origin;
|
|
165
|
+
}
|
|
166
|
+
function buildStyles(isDark) {
|
|
167
|
+
const bg = isDark ? '#1a1a2e' : '#ffffff';
|
|
168
|
+
const text = isDark ? '#e0e0e0' : '#1a1a2e';
|
|
169
|
+
const muted = isDark ? '#888' : '#666';
|
|
170
|
+
const border = isDark ? '#333' : '#e0e0e0';
|
|
171
|
+
const itemBg = isDark ? '#16213e' : '#f8f9fa';
|
|
172
|
+
const itemHover = isDark ? '#0f3460' : '#e9ecef';
|
|
173
|
+
const accent = isDark ? '#4a9eff' : '#0066cc';
|
|
174
|
+
const overlayBg = 'rgba(0, 0, 0, 0.5)';
|
|
175
|
+
return `
|
|
176
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
177
|
+
|
|
178
|
+
.overlay {
|
|
179
|
+
position: fixed;
|
|
180
|
+
inset: 0;
|
|
181
|
+
z-index: 2147483647;
|
|
182
|
+
display: flex;
|
|
183
|
+
align-items: center;
|
|
184
|
+
justify-content: center;
|
|
185
|
+
background: ${overlayBg};
|
|
186
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
187
|
+
animation: fadeIn 0.15s ease-out;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@keyframes fadeIn {
|
|
191
|
+
from { opacity: 0; }
|
|
192
|
+
to { opacity: 1; }
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@keyframes slideUp {
|
|
196
|
+
from { transform: translateY(20px); opacity: 0; }
|
|
197
|
+
to { transform: translateY(0); opacity: 1; }
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.modal {
|
|
201
|
+
background: ${bg};
|
|
202
|
+
color: ${text};
|
|
203
|
+
border-radius: 16px;
|
|
204
|
+
width: 380px;
|
|
205
|
+
max-width: 90vw;
|
|
206
|
+
max-height: 80vh;
|
|
207
|
+
overflow-y: auto;
|
|
208
|
+
padding: 24px;
|
|
209
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
210
|
+
animation: slideUp 0.2s ease-out;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.header {
|
|
214
|
+
display: flex;
|
|
215
|
+
justify-content: space-between;
|
|
216
|
+
align-items: center;
|
|
217
|
+
margin-bottom: 20px;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
h2 {
|
|
221
|
+
font-size: 18px;
|
|
222
|
+
font-weight: 600;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.close-btn {
|
|
226
|
+
background: none;
|
|
227
|
+
border: none;
|
|
228
|
+
font-size: 24px;
|
|
229
|
+
cursor: pointer;
|
|
230
|
+
color: ${muted};
|
|
231
|
+
padding: 4px 8px;
|
|
232
|
+
border-radius: 8px;
|
|
233
|
+
line-height: 1;
|
|
234
|
+
}
|
|
235
|
+
.close-btn:hover { color: ${text}; background: ${itemBg}; }
|
|
236
|
+
|
|
237
|
+
.wallet-list {
|
|
238
|
+
display: flex;
|
|
239
|
+
flex-direction: column;
|
|
240
|
+
gap: 8px;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.wallet-item {
|
|
244
|
+
display: flex;
|
|
245
|
+
align-items: center;
|
|
246
|
+
gap: 12px;
|
|
247
|
+
padding: 12px 16px;
|
|
248
|
+
background: ${itemBg};
|
|
249
|
+
border: 1px solid ${border};
|
|
250
|
+
border-radius: 12px;
|
|
251
|
+
cursor: pointer;
|
|
252
|
+
font-size: 15px;
|
|
253
|
+
color: ${text};
|
|
254
|
+
transition: background 0.15s;
|
|
255
|
+
width: 100%;
|
|
256
|
+
text-align: left;
|
|
257
|
+
}
|
|
258
|
+
.wallet-item:hover { background: ${itemHover}; }
|
|
259
|
+
|
|
260
|
+
.wallet-name { flex: 1; font-weight: 500; }
|
|
261
|
+
|
|
262
|
+
.arrow {
|
|
263
|
+
font-size: 20px;
|
|
264
|
+
color: ${muted};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.separator {
|
|
268
|
+
display: flex;
|
|
269
|
+
align-items: center;
|
|
270
|
+
gap: 12px;
|
|
271
|
+
margin: 20px 0;
|
|
272
|
+
color: ${muted};
|
|
273
|
+
font-size: 13px;
|
|
274
|
+
}
|
|
275
|
+
.sep-line { flex: 1; height: 1px; background: ${border}; }
|
|
276
|
+
|
|
277
|
+
.input-group {
|
|
278
|
+
display: flex;
|
|
279
|
+
gap: 8px;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.url-input {
|
|
283
|
+
flex: 1;
|
|
284
|
+
padding: 10px 14px;
|
|
285
|
+
border: 1px solid ${border};
|
|
286
|
+
border-radius: 10px;
|
|
287
|
+
font-size: 14px;
|
|
288
|
+
background: ${itemBg};
|
|
289
|
+
color: ${text};
|
|
290
|
+
outline: none;
|
|
291
|
+
}
|
|
292
|
+
.url-input:focus { border-color: ${accent}; }
|
|
293
|
+
.url-input::placeholder { color: ${muted}; }
|
|
294
|
+
|
|
295
|
+
.go-btn {
|
|
296
|
+
padding: 10px 18px;
|
|
297
|
+
border: none;
|
|
298
|
+
border-radius: 10px;
|
|
299
|
+
background: ${accent};
|
|
300
|
+
color: #fff;
|
|
301
|
+
font-size: 14px;
|
|
302
|
+
font-weight: 500;
|
|
303
|
+
cursor: pointer;
|
|
304
|
+
white-space: nowrap;
|
|
305
|
+
}
|
|
306
|
+
.go-btn:disabled {
|
|
307
|
+
opacity: 0.4;
|
|
308
|
+
cursor: not-allowed;
|
|
309
|
+
}
|
|
310
|
+
.go-btn:not(:disabled):hover { filter: brightness(1.1); }
|
|
311
|
+
`;
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=wallet-selector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-selector.js","sourceRoot":"","sources":["../../../src/ui/wallet-selector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser connect handler for `@enbox/auth`.
|
|
3
|
+
*
|
|
4
|
+
* Implements the {@link ConnectHandler} interface using browser-native
|
|
5
|
+
* DWeb Connect (popup + postMessage) with a wallet selector modal.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import type { ConnectHandler } from '@enbox/auth';
|
|
10
|
+
/** A wallet entry shown in the wallet selector modal. */
|
|
11
|
+
export interface WalletOption {
|
|
12
|
+
/** Display name (e.g. "Enbox Wallet"). */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Base URL of the wallet app (e.g. "https://wallet.enbox.org"). */
|
|
15
|
+
url: string;
|
|
16
|
+
/** Optional icon URL. If omitted, the wallet's favicon is used. */
|
|
17
|
+
icon?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Default wallets shown in the selector when no overrides are provided. */
|
|
20
|
+
export declare const DEFAULT_WALLETS: WalletOption[];
|
|
21
|
+
/** Options for creating a BrowserConnectHandler. */
|
|
22
|
+
export interface BrowserConnectHandlerOptions {
|
|
23
|
+
/**
|
|
24
|
+
* Known wallets shown in the wallet selector modal.
|
|
25
|
+
* If omitted, {@link DEFAULT_WALLETS} is used.
|
|
26
|
+
*/
|
|
27
|
+
wallets?: WalletOption[];
|
|
28
|
+
/**
|
|
29
|
+
* Explicit wallet URL. If provided, the wallet selector is skipped
|
|
30
|
+
* and this URL is used directly.
|
|
31
|
+
*/
|
|
32
|
+
walletUrl?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Timeout in milliseconds for the wallet popup flow.
|
|
35
|
+
* @default 300_000 (5 minutes)
|
|
36
|
+
*/
|
|
37
|
+
timeout?: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Create a browser-native connect handler using DWeb Connect
|
|
41
|
+
* (popup + postMessage).
|
|
42
|
+
*
|
|
43
|
+
* This handler:
|
|
44
|
+
* 1. Shows a wallet selector modal (or uses a provided walletUrl).
|
|
45
|
+
* 2. Opens the selected wallet as a popup window.
|
|
46
|
+
* 3. Runs the DWeb Connect postMessage protocol.
|
|
47
|
+
* 4. Returns the delegate credentials on success.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { AuthManager } from '@enbox/auth';
|
|
52
|
+
* import { BrowserConnectHandler } from '@enbox/browser';
|
|
53
|
+
*
|
|
54
|
+
* const auth = await AuthManager.create({
|
|
55
|
+
* connectHandler: BrowserConnectHandler(),
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* const session = await auth.connect({ protocols: [NotesProtocol] });
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function BrowserConnectHandler(options?: BrowserConnectHandlerOptions): ConnectHandler;
|
|
62
|
+
//# sourceMappingURL=browser-connect-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-connect-handler.d.ts","sourceRoot":"","sources":["../../src/browser-connect-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAKjE,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IAEb,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC;IAEZ,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,4EAA4E;AAC5E,eAAO,MAAM,eAAe,EAAE,YAAY,EAEzC,CAAC;AAEF,oDAAoD;AACpD,MAAM,WAAW,4BAA4B;IAC3C;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IAEzB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,4BAAiC,GACzC,cAAc,CAyBhB"}
|