@embarkai/ui-kit 0.4.25 → 0.4.27

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.
@@ -1,1515 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
-
3
-
4
-
5
- var _chunkDACL62OUcjs = require('./chunk-DACL62OU.cjs');
6
-
7
- // src/config/assets.tsx
8
- var _jsxruntime = require('react/jsx-runtime');
9
- var GoogleIcon, TelegramIcon, TwitterIcon, DiscordIcon;
10
- var init_assets = _chunkDACL62OUcjs.__esm.call(void 0, {
11
- "src/config/assets.tsx"() {
12
- GoogleIcon = exports.GoogleIcon = ({ className }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "svg", { viewBox: "0 0 24 24", className, children: [
13
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
14
- "path",
15
- {
16
- fill: "#4285F4",
17
- d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
18
- }
19
- ),
20
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
21
- "path",
22
- {
23
- fill: "#34A853",
24
- d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
25
- }
26
- ),
27
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
28
- "path",
29
- {
30
- fill: "#FBBC05",
31
- d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
32
- }
33
- ),
34
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
35
- "path",
36
- {
37
- fill: "#EA4335",
38
- d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
39
- }
40
- )
41
- ] });
42
- TelegramIcon = exports.TelegramIcon = ({ className }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { viewBox: "0 0 24 24", className, fill: "currentColor", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M9.78 18.65l.28-4.23 7.68-6.92c.34-.31-.07-.46-.52-.19L7.74 13.3 3.64 12c-.88-.25-.89-.86.2-1.3l15.97-6.16c.73-.33 1.43.18 1.15 1.3l-2.72 12.81c-.19.91-.74 1.13-1.5.71L12.6 16.3l-1.99 1.93c-.23.23-.42.42-.83.42z" }) });
43
- TwitterIcon = exports.TwitterIcon = ({ className }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { viewBox: "0 0 24 24", className, fill: "currentColor", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" }) });
44
- DiscordIcon = exports.DiscordIcon = ({ className }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { viewBox: "0 0 24 24", className, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
45
- "path",
46
- {
47
- fill: "currentColor",
48
- d: "M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0a12.64 12.64 0 0 0-.617-1.25a.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.078.078 0 0 0 .084-.028a14.09 14.09 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13.107 13.107 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10.2 10.2 0 0 0 .372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127a12.299 12.299 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028a19.839 19.839 0 0 0 6.002-3.03a.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418Z"
49
- }
50
- ) });
51
- }
52
- });
53
-
54
- // src/config/initial.tsx
55
- var initial_exports = {};
56
- _chunkDACL62OUcjs.__export.call(void 0, initial_exports, {
57
- DEFAULT_PROVIDER_CONFIG: () => DEFAULT_PROVIDER_CONFIG,
58
- getBlockscoutApiUrl: () => getBlockscoutApiUrl,
59
- getIframeUrl: () => getIframeUrl,
60
- getServiceUrls: () => getServiceUrls
61
- });
62
- var _read = require('@embarkai/core/read');
63
- function getServiceUrls() {
64
- const config = DEFAULT_PROVIDER_CONFIG;
65
- const globalOverride = typeof window !== "undefined" && window.__EMBARK_SERVICES__ || {};
66
- const searchParams = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : void 0;
67
- const paramTss = _optionalChain([searchParams, 'optionalAccess', _ => _.get, 'call', _2 => _2("tssUrl")]) || void 0;
68
- const paramVault = _optionalChain([searchParams, 'optionalAccess', _3 => _3.get, 'call', _4 => _4("shareVaultUrl")]) || void 0;
69
- const paramDashboard = _optionalChain([searchParams, 'optionalAccess', _5 => _5.get, 'call', _6 => _6("dashboardApiUrl")]) || void 0;
70
- const buildTss = "https://api.lumiapassport.com/tss";
71
- const buildVault = "https://api.lumiapassport.com/vault";
72
- const buildRequireWasm = false;
73
- const buildWasmDebug = false;
74
- const defaultTss = "/tss";
75
- const defaultVault = "/vault";
76
- const result = {
77
- tssUrl: paramTss || globalOverride.tssUrl || buildTss || config.services.tssUrl || defaultTss,
78
- shareVaultUrl: paramVault || globalOverride.shareVaultUrl || buildVault || config.services.shareVaultUrl || defaultVault,
79
- dashboardApiUrl: paramDashboard || globalOverride.dashboardApiUrl || config.services.dashboardApiUrl || "https://dashboard.lumiapassport.com/api",
80
- tssRequireWasm: _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(globalOverride.tssRequireWasm, () => ( buildRequireWasm)), () => ( config.services.tssRequireWasm)), () => ( false)),
81
- tssWasmDebug: _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(globalOverride.tssWasmDebug, () => ( buildWasmDebug)), () => ( config.services.tssWasmDebug)), () => ( false))
82
- };
83
- return result;
84
- }
85
- function getIframeUrl() {
86
- const config = DEFAULT_PROVIDER_CONFIG;
87
- const buildIframeUrl = "https://auth.lumiapassport.com";
88
- const iframeUrl = buildIframeUrl || config.services.iframeUrl || "https://auth.lumiapassport.com";
89
- return iframeUrl;
90
- }
91
- function getBlockscoutApiUrl(chainConfig) {
92
- return _optionalChain([chainConfig, 'optionalAccess', _7 => _7.blockscoutApiUrl]) || null;
93
- }
94
- var DEFAULT_PROVIDER_CONFIG;
95
- var init_initial = _chunkDACL62OUcjs.__esm.call(void 0, {
96
- "src/config/initial.tsx"() {
97
- init_assets();
98
- DEFAULT_PROVIDER_CONFIG = exports.DEFAULT_PROVIDER_CONFIG = {
99
- passkey: {
100
- enabled: true,
101
- showCreateButton: true,
102
- primaryButtonText: "Sign in with Passkey"
103
- },
104
- email: {
105
- enabled: true,
106
- placeholder: "Enter your email",
107
- buttonText: "Continue",
108
- verificationTitle: "Check your email"
109
- },
110
- social: {
111
- enabled: true,
112
- providers: [
113
- { id: "google", name: "Google", enabled: true, icon: GoogleIcon, comingSoon: true },
114
- {
115
- id: "telegram",
116
- name: "Telegram",
117
- enabled: true,
118
- icon: TelegramIcon,
119
- comingSoon: false,
120
- meta: {
121
- botUsername: "LumiaPassportDevBot",
122
- salt: "demo"
123
- }
124
- }
125
- ]
126
- },
127
- wallet: {
128
- enabled: false,
129
- supportedChains: [1, 137, 56],
130
- requireSignature: true,
131
- walletConnectProjectId: void 0,
132
- mode: "linked",
133
- allowedWallets: void 0
134
- },
135
- // preferedColorMode: 'light', // undefined means 'auto'
136
- ui: {
137
- title: "Sign in",
138
- subtitle: void 0,
139
- authOrder: ["email", "social", "wallet"]
140
- },
141
- network: {
142
- name: _read.BSC_TESTNET.name,
143
- symbol: _read.BSC_TESTNET.nativeCurrency.symbol,
144
- chainId: _read.BSC_TESTNET.id,
145
- rpcUrl: _read.BSC_TESTNET.rpcUrls[0],
146
- explorerUrl: _read.BSC_TESTNET.blockExplorerUrl,
147
- testnet: true,
148
- forceChain: false
149
- },
150
- services: {
151
- tssUrl: "",
152
- // Will fallback to build-time env vars
153
- shareVaultUrl: "",
154
- // Will fallback to build-time env vars
155
- iframeUrl: "https://auth.lumiapassport.com",
156
- // Secure iframe for MPC operations
157
- tssRequireWasm: false,
158
- tssWasmDebug: false
159
- },
160
- features: {
161
- mpcSecurity: true,
162
- strictMode: false,
163
- requestDeduplication: true,
164
- kycNeeded: false,
165
- displayNameNeeded: false,
166
- showActiveBalanceAsFiat: false
167
- },
168
- warnings: {
169
- backupWarning: true,
170
- emailNotConnectedWarning: true
171
- },
172
- kyc: {
173
- provider: void 0,
174
- options: void 0
175
- }
176
- };
177
- }
178
- });
179
-
180
- // src/lib/errors.ts
181
- var AccountAbstractionError = class _AccountAbstractionError extends Error {
182
- constructor(message, code) {
183
- super(message);
184
- this.code = code;
185
- this.name = "LumiaPassportError";
186
- if (Error.captureStackTrace) {
187
- Error.captureStackTrace(this, _AccountAbstractionError);
188
- }
189
- }
190
- };
191
- var UserRejectedError = class _UserRejectedError extends AccountAbstractionError {
192
- static {
193
- this.CODE = "USER_REJECTED";
194
- }
195
- constructor(message = "User rejected transaction") {
196
- super(message, _UserRejectedError.CODE);
197
- this.name = "UserRejectedError";
198
- }
199
- };
200
- var ErrorCodes = {
201
- MPC_SIGNING_ERROR: "MPC_SIGNING_ERROR",
202
- USER_REJECTED: UserRejectedError.CODE
203
- };
204
- function createAccountAbstractionError(params) {
205
- const { message, code } = params;
206
- if (!code) {
207
- return new Error(message);
208
- }
209
- switch (code) {
210
- case UserRejectedError.CODE:
211
- return new UserRejectedError(message);
212
- default:
213
- return new AccountAbstractionError(message, code);
214
- }
215
- }
216
-
217
- // src/internal/lib/iframe-manager.ts
218
- var IframeManager = class {
219
- constructor(config) {
220
- this.iframe = null;
221
- this.channelToken = null;
222
- this.isReady = false;
223
- this.initPromise = null;
224
- // Message handling
225
- this.pendingRequests = /* @__PURE__ */ new Map();
226
- this.usedNonces = /* @__PURE__ */ new Set();
227
- this.messageListener = null;
228
- // Track hidden dialog elements for restoration
229
- this.hiddenElements = [];
230
- this.pointerGuardCleanup = null;
231
- this.iframeHideTimeout = null;
232
- this.iframeActive = false;
233
- this.providerSessions = /* @__PURE__ */ new Map();
234
- this.providerConnections = /* @__PURE__ */ new Map();
235
- // Timeouts
236
- this.REQUEST_TIMEOUT = 3e5;
237
- // 5 minutes (for user interactions like consent)
238
- this.NONCE_EXPIRY = 3e5;
239
- // 5 minutes
240
- this.HEARTBEAT_INTERVAL = 5 * 60 * 1e3;
241
- this.isReconnecting = false;
242
- // SSE event listeners
243
- this.sseListeners = /* @__PURE__ */ new Set();
244
- this.iframeUrl = config.iframeUrl;
245
- this.projectId = config.projectId;
246
- this.debug = config.debug || false;
247
- this.onWalletReadyCallback = config.onWalletReady;
248
- this.readyPromise = new Promise((resolve) => {
249
- this.readyResolve = resolve;
250
- });
251
- this.log("[IframeManager] Initialized with:", {
252
- iframeUrl: this.iframeUrl,
253
- projectId: this.projectId
254
- });
255
- }
256
- setDebug(debug) {
257
- this.debug = debug;
258
- }
259
- /**
260
- * Initialize iframe and wait for it to be ready
261
- */
262
- async initialize() {
263
- if (this.initPromise) {
264
- return this.initPromise;
265
- }
266
- this.initPromise = this.doInitialize();
267
- return this.initPromise;
268
- }
269
- async doInitialize() {
270
- this.iframe = document.createElement("iframe");
271
- let iframeUrl = this.iframeUrl;
272
- this.iframe.src = iframeUrl;
273
- this.iframe.id = "lumia-passport-iframe";
274
- this.iframe.style.display = "none";
275
- this.iframe.style.position = "fixed";
276
- this.iframe.style.top = "0";
277
- this.iframe.style.left = "0";
278
- this.iframe.style.width = "100%";
279
- this.iframe.style.height = "100%";
280
- this.iframe.style.border = "none";
281
- this.iframe.style.zIndex = "999999";
282
- this.iframe.style.background = "rgba(0, 0, 0, 0.5)";
283
- this.iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox");
284
- this.iframe.setAttribute("allow", "publickey-credentials-get *; publickey-credentials-create *");
285
- this.messageListener = this.handleMessage.bind(this);
286
- window.addEventListener("message", this.messageListener);
287
- document.body.appendChild(this.iframe);
288
- await this.readyPromise;
289
- await this.authenticateSDK();
290
- await this.primeProviderSessions();
291
- this.startHeartbeat();
292
- this.setupVisibilityHandler();
293
- this.log("[IframeManager] \u2705 Iframe ready and authenticated");
294
- }
295
- /**
296
- * Set the onWalletReady callback
297
- */
298
- setOnWalletReady(callback) {
299
- this.onWalletReadyCallback = callback;
300
- }
301
- /**
302
- * Authenticate SDK with iframe to establish secure channel
303
- */
304
- async authenticateSDK() {
305
- const response = await this.sendMessage("SDK_AUTH", {
306
- projectId: this.projectId
307
- });
308
- if (response.type === "IFRAME_MSG_SDK_AUTH_SUCCESS") {
309
- this.channelToken = response.sessionToken;
310
- } else {
311
- throw new Error("SDK channel authentication failed");
312
- }
313
- }
314
- /**
315
- * Start periodic heartbeat to check SDK channel validity
316
- */
317
- startHeartbeat() {
318
- if (this.heartbeatInterval) {
319
- clearInterval(this.heartbeatInterval);
320
- }
321
- this.heartbeatInterval = setInterval(async () => {
322
- if (!this.channelToken) return;
323
- try {
324
- const response = await this.sendMessage("SDK_CHANNEL_HEARTBEAT", {});
325
- if (!response.valid) {
326
- this.log("[IframeManager] SDK channel invalid, reconnecting...");
327
- await this.reconnect();
328
- }
329
- } catch (error) {
330
- this.log("[IframeManager] Heartbeat failed:", error);
331
- await this.reconnect();
332
- }
333
- }, this.HEARTBEAT_INTERVAL);
334
- this.log("[IframeManager] Heartbeat started (interval: 5 min)");
335
- }
336
- /**
337
- * Stop heartbeat
338
- */
339
- stopHeartbeat() {
340
- if (this.heartbeatInterval) {
341
- clearInterval(this.heartbeatInterval);
342
- this.heartbeatInterval = void 0;
343
- this.log("[IframeManager] Heartbeat stopped");
344
- }
345
- }
346
- /**
347
- * Reconnect SDK channel after it becomes invalid
348
- */
349
- async reconnect() {
350
- if (this.isReconnecting) {
351
- this.log("[IframeManager] Already reconnecting, skipping...");
352
- return;
353
- }
354
- this.isReconnecting = true;
355
- this.log("[IframeManager] Reconnecting SDK channel...");
356
- try {
357
- this.channelToken = null;
358
- await this.authenticateSDK();
359
- this.log("[IframeManager] \u2705 SDK channel reconnected");
360
- } catch (error) {
361
- this.log("[IframeManager] \u274C Reconnect failed:", error);
362
- throw error;
363
- } finally {
364
- this.isReconnecting = false;
365
- }
366
- }
367
- /**
368
- * Setup visibility change handler to check channel when tab becomes visible
369
- */
370
- setupVisibilityHandler() {
371
- if (typeof document === "undefined") return;
372
- document.addEventListener("visibilitychange", async () => {
373
- if (document.visibilityState === "visible" && this.channelToken) {
374
- this.log("[IframeManager] Tab visible, checking SDK channel...");
375
- try {
376
- const response = await this.sendMessage("SDK_CHANNEL_HEARTBEAT", {});
377
- if (!response.valid) {
378
- this.log("[IframeManager] SDK channel expired while tab was hidden");
379
- await this.reconnect();
380
- }
381
- } catch (error) {
382
- this.log("[IframeManager] Channel check failed, reconnecting...");
383
- await this.reconnect();
384
- }
385
- }
386
- });
387
- this.log("[IframeManager] Visibility handler setup");
388
- }
389
- /**
390
- * Normalize legacy message types from cached iframe versions.
391
- * Old iframe sends LUMIA_PASSPORT_*, new iframe sends IFRAME_MSG_*.
392
- * This ensures both work until all browser caches expire.
393
- */
394
- normalizeMessageType(type) {
395
- if (type.startsWith("LUMIA_PASSPORT_")) {
396
- return type.replace("LUMIA_PASSPORT_", "IFRAME_MSG_");
397
- }
398
- return type;
399
- }
400
- /**
401
- * Handle incoming postMessage events
402
- */
403
- handleMessage(event) {
404
- const message = event.data;
405
- if (!message || typeof message !== "object" || !message.type) {
406
- return;
407
- }
408
- message.type = this.normalizeMessageType(message.type);
409
- const validIframeTypes = [
410
- "IFRAME_MSG_IFRAME_READY",
411
- "IFRAME_MSG_WALLET_READY",
412
- "IFRAME_MSG_SHOW_IFRAME",
413
- "IFRAME_MSG_HIDE_IFRAME",
414
- "IFRAME_MSG_SDK_AUTH_SUCCESS",
415
- "IFRAME_MSG_AUTH_SUCCESS",
416
- "IFRAME_MSG_DKG_SUCCESS",
417
- "IFRAME_MSG_SIGNATURE",
418
- "IFRAME_MSG_ADDRESS",
419
- "IFRAME_MSG_KEYSHARE_STATUS",
420
- "IFRAME_MSG_TRUSTED_APPS_LIST",
421
- "IFRAME_MSG_TRUSTED_APP_REMOVED",
422
- "IFRAME_MSG_REQUEST_NEW_TOKEN",
423
- "IFRAME_MSG_TOKEN_REFRESHED",
424
- "IFRAME_MSG_HEARTBEAT_RESPONSE",
425
- "IFRAME_MSG_RESPONSE",
426
- "IFRAME_MSG_ERROR",
427
- "IFRAME_SSE_EVENT"
428
- ];
429
- if (!validIframeTypes.includes(message.type) && !message.messageId) {
430
- return;
431
- }
432
- const iframeOrigin = new URL(this.iframeUrl).origin;
433
- if (event.origin !== iframeOrigin) {
434
- this.log("[IframeManager] \u26A0\uFE0F Ignored message from invalid origin:", {
435
- received: event.origin,
436
- expected: iframeOrigin
437
- });
438
- return;
439
- }
440
- if (message.type === "IFRAME_SSE_EVENT") {
441
- this.log("[IframeManager] \u{1F4E8} Received IFRAME_SSE_EVENT", message.data);
442
- for (const listener of this.sseListeners) {
443
- try {
444
- listener(message.data);
445
- } catch (err) {
446
- console.error("[IframeManager] SSE listener error:", err);
447
- }
448
- }
449
- return;
450
- }
451
- if (message.type === "IFRAME_MSG_IFRAME_READY") {
452
- this.log("[IframeManager] \u{1F4E8} Received IFRAME_MSG_IFRAME_READY");
453
- this.isReady = true;
454
- this.readyResolve();
455
- return;
456
- }
457
- if (message.type === "IFRAME_MSG_WALLET_READY") {
458
- this.log("[IframeManager] \u{1F4E8} Received IFRAME_MSG_WALLET_READY", message.data);
459
- if (this.onWalletReadyCallback) {
460
- this.onWalletReadyCallback(message.data);
461
- }
462
- return;
463
- }
464
- if (message.type === "IFRAME_MSG_SHOW_IFRAME") {
465
- this.log("[IframeManager] \u{1F4E8} Received IFRAME_MSG_SHOW_IFRAME");
466
- this.showIframe();
467
- return;
468
- }
469
- if (message.type === "IFRAME_MSG_HIDE_IFRAME") {
470
- this.log("[IframeManager] \u{1F4E8} Received IFRAME_MSG_HIDE_IFRAME");
471
- this.hideIframe();
472
- return;
473
- }
474
- if (message.type === "IFRAME_MSG_REQUEST_NEW_TOKEN") {
475
- this.log("[IframeManager] \u{1F4E8} Received IFRAME_MSG_REQUEST_NEW_TOKEN");
476
- this.handleTokenRefreshRequest(message).catch((error) => {
477
- this.log("[IframeManager] \u274C Token refresh error:", error);
478
- });
479
- return;
480
- }
481
- if (message.messageId) {
482
- const pending = this.pendingRequests.get(message.messageId);
483
- if (pending) {
484
- this.pendingRequests.delete(message.messageId);
485
- if (message.type === "IFRAME_MSG_ERROR") {
486
- const passportError = createAccountAbstractionError({
487
- message: message.error || "Unknown error",
488
- code: message.code
489
- });
490
- pending.reject(passportError);
491
- } else {
492
- pending.resolve(message.data || message);
493
- }
494
- }
495
- }
496
- }
497
- /**
498
- * Handle token refresh request from iframe
499
- */
500
- async handleTokenRefreshRequest(message) {
501
- try {
502
- const { jwtTokenManager } = await Promise.resolve().then(() => _interopRequireWildcard(require("./auth-LTJ6Z736.cjs")));
503
- const refreshSuccess = await jwtTokenManager.refreshAccessToken();
504
- if (refreshSuccess) {
505
- const newAccessToken = jwtTokenManager.getAccessToken();
506
- if (this.iframe && this.iframe.contentWindow) {
507
- const iframeOrigin = new URL(this.iframeUrl).origin;
508
- this.iframe.contentWindow.postMessage(
509
- {
510
- type: "IFRAME_MSG_TOKEN_REFRESHED",
511
- messageId: message.messageId,
512
- accessToken: newAccessToken,
513
- timestamp: Date.now()
514
- },
515
- iframeOrigin
516
- );
517
- }
518
- } else {
519
- if (this.iframe && this.iframe.contentWindow) {
520
- const iframeOrigin = new URL(this.iframeUrl).origin;
521
- this.iframe.contentWindow.postMessage(
522
- {
523
- type: "IFRAME_MSG_TOKEN_REFRESHED",
524
- messageId: message.messageId,
525
- error: "Token refresh failed",
526
- timestamp: Date.now()
527
- },
528
- iframeOrigin
529
- );
530
- }
531
- }
532
- } catch (error) {
533
- if (this.iframe && this.iframe.contentWindow) {
534
- const iframeOrigin = new URL(this.iframeUrl).origin;
535
- this.iframe.contentWindow.postMessage(
536
- {
537
- type: "IFRAME_MSG_TOKEN_REFRESHED",
538
- messageId: message.messageId,
539
- error: error instanceof Error ? error.message : "Unknown error",
540
- timestamp: Date.now()
541
- },
542
- iframeOrigin
543
- );
544
- }
545
- }
546
- }
547
- /**
548
- * Send secure message to iframe
549
- */
550
- async sendMessage(type, data) {
551
- if (this.initPromise && type !== "SDK_AUTH") {
552
- await this.initPromise;
553
- }
554
- if (!this.iframe || !this.iframe.contentWindow) {
555
- throw new Error("Iframe not initialized");
556
- }
557
- if (!this.channelToken && type !== "SDK_AUTH") {
558
- throw createAccountAbstractionError({ message: "SDK channel not established. Initialize iframe first." });
559
- }
560
- const messageId = this.generateMessageId();
561
- const nonce = this.generateNonce();
562
- const timestamp = Date.now();
563
- const message = {
564
- type,
565
- messageId,
566
- timestamp,
567
- nonce,
568
- projectId: this.projectId,
569
- data: {
570
- ...data,
571
- sessionToken: this.channelToken
572
- // named sessionToken for backward compatibility with iframe
573
- }
574
- };
575
- if (this.channelToken) {
576
- message.hmac = await this.computeHMAC(message);
577
- }
578
- const responsePromise = new Promise((resolve, reject) => {
579
- this.pendingRequests.set(messageId, {
580
- resolve,
581
- reject,
582
- timestamp
583
- });
584
- setTimeout(() => {
585
- if (this.pendingRequests.has(messageId)) {
586
- this.pendingRequests.delete(messageId);
587
- reject(new Error(`Request timeout: ${type}`));
588
- }
589
- }, this.REQUEST_TIMEOUT);
590
- });
591
- const iframeOrigin = new URL(this.iframeUrl).origin;
592
- this.iframe.contentWindow.postMessage(message, iframeOrigin);
593
- this.log(`[IframeManager] \u{1F4E4} Sent message: ${type}`, { messageId });
594
- return responsePromise;
595
- }
596
- onSseEvent(listener) {
597
- this.sseListeners.add(listener);
598
- return () => {
599
- this.sseListeners.delete(listener);
600
- };
601
- }
602
- /**
603
- * Compute HMAC for message authentication using SDK channel token
604
- */
605
- async computeHMAC(message) {
606
- const encoder = new TextEncoder();
607
- const payload = JSON.stringify({
608
- type: message.type,
609
- messageId: message.messageId,
610
- timestamp: message.timestamp,
611
- nonce: message.nonce,
612
- data: JSON.stringify(message.data)
613
- });
614
- const data = encoder.encode(payload);
615
- const key = encoder.encode(this.channelToken);
616
- const cryptoKey = await crypto.subtle.importKey("raw", key, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
617
- const signature = await crypto.subtle.sign("HMAC", cryptoKey, data);
618
- return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
619
- }
620
- /**
621
- * Generate unique message ID
622
- */
623
- generateMessageId() {
624
- return `msg_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
625
- }
626
- /**
627
- * Generate nonce for replay protection
628
- */
629
- generateNonce() {
630
- const randomBytes = new Uint8Array(16);
631
- crypto.getRandomValues(randomBytes);
632
- return Array.from(randomBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
633
- }
634
- // ========================================
635
- // UI Methods
636
- // ========================================
637
- /**
638
- * Show iframe (for consent/confirmation UI)
639
- */
640
- showIframe() {
641
- if (this.iframe) {
642
- if (this.iframeHideTimeout) {
643
- clearTimeout(this.iframeHideTimeout);
644
- this.iframeHideTimeout = null;
645
- }
646
- this.hideAllDialogs();
647
- this.iframeActive = true;
648
- this.enablePointerEventGuards();
649
- this.iframe.style.display = "block";
650
- this.iframe.style.zIndex = "2147483648";
651
- this.iframe.style.pointerEvents = "auto";
652
- this.iframe.style.visibility = "visible";
653
- this.iframe.style.background = "rgba(0, 0, 0, 0.5)";
654
- }
655
- }
656
- /**
657
- * Hide iframe
658
- */
659
- hideIframe() {
660
- if (this.iframe) {
661
- this.log("[IframeManager] hideIframe called - making iframe non-blocking");
662
- this.iframeActive = false;
663
- this.iframe.style.zIndex = "1";
664
- this.iframe.style.background = "transparent";
665
- this.iframe.style.pointerEvents = "none";
666
- this.iframe.style.visibility = "hidden";
667
- this.log("[IframeManager] iframe z-index set to 1, transparent, pointer-events: none");
668
- this.restoreAllDialogs();
669
- this.disablePointerEventGuards();
670
- this.iframeHideTimeout = setTimeout(() => {
671
- if (this.iframe) {
672
- this.log("[IframeManager] Fully hiding iframe with display: none");
673
- this.iframe.style.display = "none";
674
- this.iframe.style.zIndex = "999999";
675
- this.iframe.style.background = "rgba(0, 0, 0, 0.5)";
676
- this.iframe.style.pointerEvents = "auto";
677
- this.iframe.style.visibility = "visible";
678
- }
679
- this.iframeHideTimeout = null;
680
- }, 200);
681
- }
682
- }
683
- /**
684
- * Hide all Radix Dialog modals (SendModal, etc.)
685
- */
686
- hideAllDialogs() {
687
- this.hiddenElements = [];
688
- const allElements = document.body.querySelectorAll("*");
689
- allElements.forEach((element) => {
690
- const htmlElement = element;
691
- if (htmlElement.id === "lumia-passport-iframe" || htmlElement.closest("#lumia-passport-iframe")) {
692
- return;
693
- }
694
- if (htmlElement.hasAttribute("data-lumia-auth-modal") || htmlElement.closest("[data-lumia-auth-modal]")) {
695
- return;
696
- }
697
- const computedStyle = window.getComputedStyle(htmlElement);
698
- const zIndex = parseInt(computedStyle.zIndex, 10);
699
- const isRadixElement = htmlElement.hasAttribute("data-radix-focus-guard") || htmlElement.hasAttribute("data-radix-portal") || htmlElement.hasAttribute("data-radix-popper-content-wrapper");
700
- if (!isNaN(zIndex) && zIndex > 1e6 || isRadixElement) {
701
- this.hiddenElements.push({
702
- element: htmlElement,
703
- originalDisplay: htmlElement.style.display || "",
704
- originalVisibility: htmlElement.style.visibility || "",
705
- originalPointerEvents: htmlElement.style.pointerEvents || "",
706
- originalZIndex: htmlElement.style.zIndex || ""
707
- });
708
- htmlElement.style.display = "none";
709
- htmlElement.style.visibility = "hidden";
710
- htmlElement.style.pointerEvents = "none";
711
- htmlElement.style.zIndex = "-1";
712
- const elementType = isRadixElement ? "Radix element" : `z-index ${zIndex}`;
713
- this.log(
714
- `[IframeManager] Hiding ${elementType}: ${htmlElement.className || "(no class)"} (Tag: ${htmlElement.tagName})`
715
- );
716
- }
717
- });
718
- this.log(`[IframeManager] Hidden ${this.hiddenElements.length} elements total`);
719
- }
720
- /**
721
- * Restore all previously hidden Radix Dialog modals
722
- */
723
- restoreAllDialogs() {
724
- this.log(`[IframeManager] Restoring ${this.hiddenElements.length} elements`);
725
- this.hiddenElements.forEach(
726
- ({ element, originalDisplay, originalVisibility, originalPointerEvents, originalZIndex }) => {
727
- element.style.display = originalDisplay;
728
- element.style.visibility = originalVisibility;
729
- element.style.pointerEvents = originalPointerEvents || "auto";
730
- element.style.zIndex = originalZIndex;
731
- this.log(
732
- `[IframeManager] Restored element: ${element.className} (Tag: ${element.tagName}), pointerEvents set to: ${element.style.pointerEvents}`
733
- );
734
- }
735
- );
736
- this.hiddenElements = [];
737
- this.log(`[IframeManager] All elements restored`);
738
- }
739
- /**
740
- * Stop Radix dismissable layers from swallowing the first click on the iframe.
741
- * Radix attaches pointer event guards at the document level; we intercept at window
742
- * capture phase so user clicks flow straight into the consent iframe.
743
- */
744
- enablePointerEventGuards() {
745
- if (this.pointerGuardCleanup) {
746
- return;
747
- }
748
- const handler = (event) => {
749
- if (!this.iframeActive || !this.iframe) {
750
- return;
751
- }
752
- const target = event.target;
753
- const composedPath = typeof event.composedPath === "function" ? event.composedPath() : [];
754
- const hitsIframe = target === this.iframe || Array.isArray(composedPath) && composedPath.includes(this.iframe);
755
- if (!hitsIframe) {
756
- return;
757
- }
758
- if (typeof event.stopImmediatePropagation === "function") {
759
- ;
760
- event.stopImmediatePropagation();
761
- }
762
- event.stopPropagation();
763
- };
764
- const options = { capture: true };
765
- const eventNames = ["pointerdown", "mousedown", "mouseup", "click", "touchstart", "focusin"];
766
- eventNames.forEach((eventName) => {
767
- window.addEventListener(eventName, handler, options);
768
- });
769
- this.pointerGuardCleanup = () => {
770
- eventNames.forEach((eventName) => {
771
- window.removeEventListener(eventName, handler, options);
772
- });
773
- this.pointerGuardCleanup = null;
774
- };
775
- this.log("[IframeManager] Enabled pointer event guards for iframe consent");
776
- }
777
- /**
778
- * Remove pointer interception once iframe is hidden again.
779
- */
780
- disablePointerEventGuards() {
781
- if (this.pointerGuardCleanup) {
782
- this.pointerGuardCleanup();
783
- this.pointerGuardCleanup = null;
784
- this.log("[IframeManager] Disabled pointer event guards for iframe consent");
785
- }
786
- }
787
- // ========================================
788
- // Public API Methods
789
- // ========================================
790
- /**
791
- * Authenticate user with application
792
- */
793
- async authenticate(userId, avatar, displayName) {
794
- const response = await this.sendMessage("AUTHENTICATE", {
795
- userId,
796
- projectId: this.projectId,
797
- avatar,
798
- displayName
799
- });
800
- if (response.type === "IFRAME_MSG_AUTH_SUCCESS") {
801
- return {
802
- userId: response.userId,
803
- address: response.address
804
- };
805
- }
806
- throw new Error("Authentication failed");
807
- }
808
- /**
809
- * Start DKG (Distributed Key Generation)
810
- */
811
- async startDKG(userId, accessToken) {
812
- const response = await this.sendMessage("START_DKG", {
813
- userId,
814
- projectId: this.projectId,
815
- accessToken
816
- // Pass access token for TSS API authentication
817
- });
818
- if (response.type === "IFRAME_MSG_DKG_SUCCESS") {
819
- return response.ownerAddress;
820
- }
821
- throw new Error("DKG failed");
822
- }
823
- /**
824
- * Sign transaction
825
- */
826
- async signTransaction(userId, transaction, accessToken, avatar, displayName) {
827
- if (!avatar || !displayName) {
828
- const { jwtTokenManager } = await Promise.resolve().then(() => _interopRequireWildcard(require("@embarkai/core/auth")));
829
- avatar = avatar || jwtTokenManager.getAvatar();
830
- displayName = displayName || jwtTokenManager.getDisplayName();
831
- }
832
- const response = await this.sendMessage("SIGN_TRANSACTION", {
833
- userId,
834
- projectId: this.projectId,
835
- transaction,
836
- accessToken,
837
- // Pass access token for TSS API authentication
838
- avatar,
839
- displayName
840
- });
841
- if (response.type === "IFRAME_MSG_SIGNATURE") {
842
- return response.signature;
843
- }
844
- throw new Error("Transaction signing failed");
845
- }
846
- /**
847
- * Sign EIP712 typed data
848
- */
849
- async signTypedData(userId, typedData, digest32, accessToken, avatar, displayName) {
850
- console.log("[IframeManager] signTypedData: Sending SIGN_TYPED_DATA message", {
851
- userId,
852
- primaryType: typedData.primaryType,
853
- digest32
854
- });
855
- if (!avatar || !displayName) {
856
- const { jwtTokenManager } = await Promise.resolve().then(() => _interopRequireWildcard(require("@embarkai/core/auth")));
857
- avatar = avatar || jwtTokenManager.getAvatar();
858
- displayName = displayName || jwtTokenManager.getDisplayName();
859
- }
860
- const response = await this.sendMessage("SIGN_TYPED_DATA", {
861
- userId,
862
- projectId: this.projectId,
863
- typedData,
864
- digest32,
865
- accessToken,
866
- // Pass access token for TSS API authentication
867
- avatar,
868
- displayName
869
- });
870
- console.log("[IframeManager] signTypedData: Response received", {
871
- type: response.type,
872
- hasSignature: !!response.signature
873
- });
874
- if (response.type === "IFRAME_MSG_EIP712_SIGNATURE") {
875
- return response.signature;
876
- }
877
- throw new Error("EIP712 signing failed");
878
- }
879
- /**
880
- * Get user's wallet address
881
- */
882
- async getAddress(userId) {
883
- const response = await this.sendMessage("GET_ADDRESS", {
884
- userId
885
- });
886
- if (response.type === "IFRAME_MSG_ADDRESS") {
887
- return response.address;
888
- }
889
- return void 0;
890
- }
891
- /**
892
- * Check if user has a keyshare
893
- */
894
- async checkKeyshare(userId) {
895
- const response = await this.sendMessage("CHECK_KEYSHARE", {
896
- userId
897
- });
898
- if (response.type === "IFRAME_MSG_KEYSHARE_STATUS") {
899
- return {
900
- hasKeyshare: response.hasKeyshare,
901
- address: response.address
902
- };
903
- }
904
- return { hasKeyshare: false };
905
- }
906
- /**
907
- * Open social auth popup (Telegram, Discord, Twitter, etc.)
908
- */
909
- async openSocialAuthPopup(provider, config) {
910
- this.log(`[IframeManager] Opening social auth popup for provider: ${provider}`);
911
- return new Promise((resolve, reject) => {
912
- const normalizedProviderName = provider.toLowerCase();
913
- const providerKey = normalizedProviderName === "twitter" ? "x" : normalizedProviderName;
914
- const xMode = _optionalChain([config, 'optionalAccess', _8 => _8.mode]) === "link" ? "link" : "login";
915
- const sessionBeforeFlow = providerKey === "x" ? this.getKnownSessionId("x") : null;
916
- const connectionBeforeFlow = providerKey === "x" ? this.getKnownProviderConnection("x") : null;
917
- let popupUrl;
918
- if (providerKey === "telegram") {
919
- const iframeOrigin = new URL(this.iframeUrl).origin;
920
- const botUsername = _optionalChain([config, 'optionalAccess', _9 => _9.botUsername]);
921
- this.log("[IframeManager] Telegram config:", config);
922
- this.log("[IframeManager] Bot username:", botUsername);
923
- const url = new URL(`${iframeOrigin}/oauth/telegram.html`);
924
- if (botUsername) {
925
- url.searchParams.set("bot", botUsername);
926
- }
927
- popupUrl = url.toString();
928
- this.log("[IframeManager] Popup URL:", popupUrl);
929
- } else if (providerKey === "x") {
930
- const iframeOrigin = new URL(this.iframeUrl).origin;
931
- this.log("[IframeManager] X OAuth config:", config);
932
- const url = new URL(`${iframeOrigin}/oauth/x.html`);
933
- const { getServiceUrls: getServiceUrls2 } = (init_initial(), _chunkDACL62OUcjs.__toCommonJS.call(void 0, initial_exports));
934
- const { tssUrl } = getServiceUrls2();
935
- const projectId = typeof window !== "undefined" ? window.__EMBARK_PROJECT_ID__ : void 0;
936
- this.log("[IframeManager] TSS URL from config:", tssUrl);
937
- this.log("[IframeManager] Project ID:", projectId);
938
- url.searchParams.set("tssUrl", tssUrl);
939
- url.searchParams.set("mode", xMode);
940
- if (projectId) {
941
- url.searchParams.set("projectId", projectId);
942
- }
943
- if (xMode === "link" && _optionalChain([config, 'optionalAccess', _10 => _10.token])) {
944
- url.searchParams.set("token", config.token);
945
- }
946
- popupUrl = url.toString();
947
- this.log("[IframeManager] X OAuth Popup URL:", popupUrl);
948
- } else {
949
- reject(new Error(`Provider ${provider} not supported yet`));
950
- return;
951
- }
952
- const popup = window.open(
953
- popupUrl,
954
- `${provider}_auth`,
955
- "width=550,height=650,menubar=no,toolbar=no,location=no,status=no"
956
- );
957
- if (!popup) {
958
- reject(new Error("Failed to open popup. Please allow popups for this site."));
959
- return;
960
- }
961
- let checkClosed;
962
- let resolved = false;
963
- let messageHandler = null;
964
- let pendingCancellation = false;
965
- const cleanup = (closePopup = true) => {
966
- if (messageHandler) {
967
- window.removeEventListener("message", messageHandler);
968
- }
969
- if (checkClosed) {
970
- clearInterval(checkClosed);
971
- checkClosed = void 0;
972
- }
973
- if (closePopup && !popup.closed) {
974
- popup.close();
975
- }
976
- };
977
- const finalize = (result, closePopup = true) => {
978
- if (resolved) {
979
- return;
980
- }
981
- resolved = true;
982
- cleanup(closePopup);
983
- if (result.success && providerKey === "x") {
984
- this.updateProviderTrackingFromUser("x", result.user);
985
- }
986
- resolve({
987
- provider,
988
- ...result
989
- });
990
- };
991
- messageHandler = (event) => {
992
- const iframeOrigin = new URL(this.iframeUrl).origin;
993
- if (event.origin !== iframeOrigin) {
994
- return;
995
- }
996
- const eventProvider = _optionalChain([event, 'access', _11 => _11.data, 'access', _12 => _12.provider, 'optionalAccess', _13 => _13.toLowerCase, 'call', _14 => _14()]);
997
- if (event.data.type === "TELEGRAM_AUTH_SUCCESS" && eventProvider === "telegram" && providerKey === "telegram") {
998
- this.log("[IframeManager] Telegram auth successful from popup:", event.data);
999
- finalize({
1000
- success: true,
1001
- user: event.data.user
1002
- });
1003
- } else if (event.data.type === "X_AUTH_SUCCESS" && eventProvider === "x" && providerKey === "x") {
1004
- this.log("[IframeManager] X auth successful from popup:", event.data);
1005
- if (event.data.tokens) {
1006
- this.log("[IframeManager] Tokens received in postMessage, storing via jwtTokenManager");
1007
- Promise.resolve().then(() => _interopRequireWildcard(require("./auth-LTJ6Z736.cjs"))).then(({ jwtTokenManager }) => {
1008
- return jwtTokenManager.setTokens({
1009
- accessToken: event.data.tokens.accessToken,
1010
- refreshToken: event.data.tokens.refreshToken,
1011
- userId: event.data.user.userId,
1012
- expiresIn: event.data.user.expiresIn || 3600,
1013
- hasKeyshare: event.data.user.hasKeyshare || false,
1014
- displayName: event.data.user.displayName || null,
1015
- providers: event.data.user.providers || ["x"]
1016
- });
1017
- }).then(() => {
1018
- this.log("[IframeManager] Tokens stored successfully");
1019
- }).catch((tokenError) => {
1020
- this.log("[IframeManager] Warning: Failed to store tokens:", tokenError);
1021
- });
1022
- }
1023
- finalize({
1024
- success: true,
1025
- user: event.data.user,
1026
- mode: event.data.mode
1027
- });
1028
- } else if (event.data.type === "TELEGRAM_AUTH_CANCELLED" && eventProvider === "telegram" && providerKey === "telegram") {
1029
- this.log("[IframeManager] Telegram auth cancelled by user");
1030
- finalize(
1031
- {
1032
- success: false,
1033
- error: "User cancelled authentication"
1034
- },
1035
- false
1036
- );
1037
- } else if (event.data.type === "X_AUTH_CANCELLED" && eventProvider === "x" && providerKey === "x") {
1038
- this.log("[IframeManager] X auth cancelled by user");
1039
- pendingCancellation = true;
1040
- this.verifyAuthSession({ provider: "x" }).then((verification) => {
1041
- const sessionId = verification.sessionId || null;
1042
- const providers = verification.providers || [];
1043
- const isConnectedNow = providers.includes("x");
1044
- const sessionChanged = !!sessionId && sessionId !== sessionBeforeFlow;
1045
- const connectionGained = connectionBeforeFlow === false && isConnectedNow;
1046
- if (verification.success) {
1047
- if (sessionChanged || connectionGained) {
1048
- this.log(
1049
- "[IframeManager] X auth cancellation fallback found active session change, treating as success"
1050
- );
1051
- finalize(
1052
- {
1053
- success: true,
1054
- user: verification.user,
1055
- mode: xMode
1056
- },
1057
- true
1058
- );
1059
- } else {
1060
- this.log("[IframeManager] X auth fallback did not detect new session, treating as cancellation");
1061
- if (popup.closed) {
1062
- finalize(
1063
- {
1064
- success: false,
1065
- error: "User cancelled authentication"
1066
- },
1067
- false
1068
- );
1069
- }
1070
- }
1071
- } else {
1072
- this.log("[IframeManager] X auth fallback verification reported no session, treating as cancellation");
1073
- if (popup.closed) {
1074
- finalize(
1075
- {
1076
- success: false,
1077
- error: "User cancelled authentication"
1078
- },
1079
- false
1080
- );
1081
- }
1082
- }
1083
- }).catch((error) => {
1084
- this.log("[IframeManager] X auth fallback verification error:", error);
1085
- if (popup.closed) {
1086
- finalize(
1087
- {
1088
- success: false,
1089
- error: "User cancelled authentication"
1090
- },
1091
- false
1092
- );
1093
- }
1094
- });
1095
- } else if (event.data.type === "X_AUTH_ERROR" && eventProvider === "x" && providerKey === "x") {
1096
- this.log("[IframeManager] X auth error from popup:", event.data.error);
1097
- finalize({
1098
- success: false,
1099
- error: event.data.error || "Authentication failed"
1100
- });
1101
- }
1102
- };
1103
- window.addEventListener("message", messageHandler);
1104
- checkClosed = setInterval(() => {
1105
- if (popup.closed) {
1106
- if (checkClosed) {
1107
- clearInterval(checkClosed);
1108
- checkClosed = void 0;
1109
- }
1110
- if (!resolved) {
1111
- if (providerKey === "x" && pendingCancellation) {
1112
- finalize(
1113
- {
1114
- success: false,
1115
- error: "User cancelled authentication"
1116
- },
1117
- false
1118
- );
1119
- } else {
1120
- finalize(
1121
- {
1122
- success: false,
1123
- error: "Popup was closed"
1124
- },
1125
- false
1126
- );
1127
- }
1128
- }
1129
- }
1130
- }, 500);
1131
- });
1132
- }
1133
- /**
1134
- * Verify current auth session with the backend.
1135
- * Can optionally track session state for a specific provider.
1136
- * @param options.silent - If true, suppress logging
1137
- * @param options.provider - Optional provider key to track session state for (e.g., 'x', 'telegram')
1138
- */
1139
- async verifyAuthSession(options = {}) {
1140
- if (typeof window === "undefined" || typeof fetch === "undefined") {
1141
- return { success: false };
1142
- }
1143
- try {
1144
- const { getServiceUrls: getServiceUrls2 } = (init_initial(), _chunkDACL62OUcjs.__toCommonJS.call(void 0, initial_exports));
1145
- const { tssUrl } = getServiceUrls2();
1146
- const projectId = typeof window !== "undefined" ? window.__EMBARK_PROJECT_ID__ : void 0;
1147
- if (!tssUrl) {
1148
- this.log("[IframeManager] Session verify aborted: missing TSS URL");
1149
- return { success: false };
1150
- }
1151
- const verifyUrl = new URL(`${tssUrl}/api/auth/verify`);
1152
- if (projectId) {
1153
- verifyUrl.searchParams.set("projectId", projectId);
1154
- }
1155
- const { jwtTokenManager, ensureValidToken } = await Promise.resolve().then(() => _interopRequireWildcard(require("./auth-LTJ6Z736.cjs")));
1156
- const hasValidToken = await ensureValidToken();
1157
- const headers = {
1158
- "Content-Type": "application/json"
1159
- };
1160
- if (hasValidToken) {
1161
- const accessToken = jwtTokenManager.getAccessToken();
1162
- if (accessToken) {
1163
- headers["Authorization"] = `Bearer ${accessToken}`;
1164
- }
1165
- }
1166
- let response = await fetch(verifyUrl.toString(), {
1167
- method: "GET",
1168
- headers,
1169
- credentials: "include"
1170
- });
1171
- if (response.status === 401) {
1172
- this.log("[IframeManager] Session verify got 401, attempting token refresh...");
1173
- const refreshSuccess = await jwtTokenManager.refreshAccessToken();
1174
- if (refreshSuccess) {
1175
- const newAccessToken = jwtTokenManager.getAccessToken();
1176
- if (newAccessToken) {
1177
- headers["Authorization"] = `Bearer ${newAccessToken}`;
1178
- this.log("[IframeManager] Token refreshed, retrying verify...");
1179
- response = await fetch(verifyUrl.toString(), {
1180
- method: "GET",
1181
- headers,
1182
- credentials: "include"
1183
- });
1184
- }
1185
- }
1186
- }
1187
- if (!response.ok) {
1188
- this.log("[IframeManager] Session verify returned status:", response.status);
1189
- if (options.provider) {
1190
- this.recordProviderSession(options.provider, null);
1191
- this.recordProviderConnection(options.provider, false);
1192
- }
1193
- return { success: false };
1194
- }
1195
- let userData = void 0;
1196
- try {
1197
- userData = await response.json();
1198
- } catch (jsonError) {
1199
- this.log("[IframeManager] Session verify JSON parse failed:", jsonError);
1200
- }
1201
- const sessionId = this.extractSessionId(userData);
1202
- const providers = this.getProvidersList(userData);
1203
- if (options.provider) {
1204
- this.recordProviderSession(options.provider, sessionId);
1205
- this.recordProviderConnection(options.provider, providers.includes(options.provider));
1206
- }
1207
- if (!options.silent) {
1208
- this.log("[IframeManager] Session verify result:", {
1209
- sessionId,
1210
- providers
1211
- });
1212
- }
1213
- return {
1214
- success: true,
1215
- user: userData,
1216
- sessionId,
1217
- providers
1218
- };
1219
- } catch (error) {
1220
- this.log("[IframeManager] Session verify error:", error);
1221
- if (options.provider) {
1222
- this.recordProviderSession(options.provider, null);
1223
- this.recordProviderConnection(options.provider, false);
1224
- }
1225
- return { success: false };
1226
- }
1227
- }
1228
- /**
1229
- * Prime provider session/cache state to detect future changes.
1230
- */
1231
- async primeProviderSessions() {
1232
- try {
1233
- await this.verifyAuthSession({ silent: true });
1234
- } catch (error) {
1235
- this.log("[IframeManager] Prime provider sessions failed:", error);
1236
- }
1237
- }
1238
- getKnownSessionId(providerKey) {
1239
- return this.providerSessions.has(providerKey) ? _nullishCoalesce(this.providerSessions.get(providerKey), () => ( null)) : null;
1240
- }
1241
- getKnownProviderConnection(providerKey) {
1242
- if (!this.providerConnections.has(providerKey)) {
1243
- return null;
1244
- }
1245
- const value = this.providerConnections.get(providerKey);
1246
- return typeof value === "boolean" ? value : null;
1247
- }
1248
- recordProviderSession(providerKey, sessionId) {
1249
- this.providerSessions.set(providerKey, _nullishCoalesce(sessionId, () => ( null)));
1250
- }
1251
- recordProviderConnection(providerKey, connected) {
1252
- this.providerConnections.set(providerKey, connected);
1253
- }
1254
- updateProviderTrackingFromUser(providerKey, user) {
1255
- if (!user) {
1256
- return;
1257
- }
1258
- if (providerKey === "x") {
1259
- const sessionId = this.extractSessionId(user);
1260
- this.recordProviderSession("x", sessionId);
1261
- const providers = this.getProvidersList(user);
1262
- this.recordProviderConnection("x", providers.includes("x"));
1263
- }
1264
- }
1265
- extractSessionId(user) {
1266
- if (!user || typeof user !== "object") {
1267
- return null;
1268
- }
1269
- if (typeof user.sessionId === "string") {
1270
- return user.sessionId;
1271
- }
1272
- if (user.data && typeof user.data.sessionId === "string") {
1273
- return user.data.sessionId;
1274
- }
1275
- return null;
1276
- }
1277
- getProvidersList(user) {
1278
- if (!user || typeof user !== "object") {
1279
- return [];
1280
- }
1281
- const providersRaw = user.providers || _optionalChain([user, 'access', _15 => _15.data, 'optionalAccess', _16 => _16.providers]);
1282
- if (!Array.isArray(providersRaw)) {
1283
- return [];
1284
- }
1285
- return providersRaw.map((provider) => typeof provider === "string" ? provider.toLowerCase() : null).filter((provider) => provider !== null);
1286
- }
1287
- /**
1288
- * Get trusted apps for user
1289
- */
1290
- async getTrustedApps(userId) {
1291
- const response = await this.sendMessage("GET_TRUSTED_APPS", {
1292
- userId
1293
- });
1294
- if (response.type === "IFRAME_MSG_TRUSTED_APPS_LIST") {
1295
- return response.apps || [];
1296
- }
1297
- return [];
1298
- }
1299
- /**
1300
- * Remove app from trusted list
1301
- */
1302
- async removeTrustedApp(userId, projectId, origin) {
1303
- const response = await this.sendMessage("REMOVE_TRUSTED_APP", {
1304
- userId,
1305
- projectId,
1306
- appOrigin: origin
1307
- });
1308
- if (response.type === "IFRAME_MSG_TRUSTED_APP_REMOVED") {
1309
- return response.success;
1310
- }
1311
- return false;
1312
- }
1313
- /**
1314
- * Clear all authorizations for current project (for testing consent flow)
1315
- * This will force the consent modal to appear on next authentication
1316
- */
1317
- async clearAuthorizations() {
1318
- try {
1319
- const response = await this.sendMessage("CLEAR_AUTHORIZATIONS", {
1320
- projectId: this.projectId
1321
- });
1322
- this.log("[IframeManager] Cleared authorizations for project:", this.projectId);
1323
- return response.success || true;
1324
- } catch (error) {
1325
- this.log("[IframeManager] Failed to clear authorizations:", error);
1326
- return false;
1327
- }
1328
- }
1329
- /**
1330
- * Create backup of keyshare
1331
- */
1332
- async createBackup(userId, backupRequest, accessToken) {
1333
- const response = await this.sendMessage("CREATE_BACKUP", {
1334
- userId,
1335
- backupRequest,
1336
- accessToken
1337
- // Pass access token for TSS API authentication
1338
- });
1339
- if (response.type === "IFRAME_MSG_BACKUP_CREATED") {
1340
- return response.result;
1341
- }
1342
- throw new Error("Unexpected response type");
1343
- }
1344
- /**
1345
- * Restore keyshare from server backup
1346
- */
1347
- async restoreFromServer(userId, password, accessToken) {
1348
- const response = await this.sendMessage("RESTORE_BACKUP", {
1349
- userId,
1350
- password,
1351
- accessToken
1352
- // Pass access token for TSS API authentication
1353
- });
1354
- if (response.type === "IFRAME_MSG_BACKUP_RESTORED") {
1355
- return response.result;
1356
- }
1357
- throw new Error("Unexpected response type");
1358
- }
1359
- /**
1360
- * Encrypt backup data without uploading (for cloud/local backups)
1361
- * Returns encrypted data that parent can upload/download
1362
- */
1363
- async encryptBackupData(userId, password) {
1364
- const response = await this.sendMessage("ENCRYPT_BACKUP_DATA", {
1365
- userId,
1366
- password
1367
- });
1368
- if (response.type === "IFRAME_MSG_BACKUP_ENCRYPTED") {
1369
- return response.encryptedData;
1370
- }
1371
- throw new Error("Unexpected response type");
1372
- }
1373
- /**
1374
- * Encrypt current keyshare as EnvelopeEncryptedShare (for Guardian backup)
1375
- */
1376
- async encryptEnvelopeData(userId, password) {
1377
- const response = await this.sendMessage("ENCRYPT_ENVELOPE_DATA", { userId, password });
1378
- if (response.type === "IFRAME_MSG_ENVELOPE_ENCRYPTED") {
1379
- return response.envelopeJson;
1380
- }
1381
- throw new Error("Unexpected response type");
1382
- }
1383
- /**
1384
- * Decrypt EnvelopeEncryptedShare and restore keyshare (for Guardian restore)
1385
- */
1386
- async decryptAndRestoreEnvelope(userId, envelopeJson, password) {
1387
- const response = await this.sendMessage("DECRYPT_AND_RESTORE_ENVELOPE", {
1388
- userId,
1389
- envelopeJson,
1390
- password
1391
- });
1392
- if (response.type === "IFRAME_MSG_ENVELOPE_RESTORED") {
1393
- return response.result;
1394
- }
1395
- throw new Error("Unexpected response type");
1396
- }
1397
- /**
1398
- * Restore keyshare from local file backup
1399
- */
1400
- async restoreFromLocalFile(userId, fileContent, password) {
1401
- const response = await this.sendMessage("RESTORE_FROM_FILE", {
1402
- userId,
1403
- fileContent,
1404
- password
1405
- });
1406
- if (response.type === "IFRAME_MSG_FILE_RESTORED") {
1407
- return response.result;
1408
- }
1409
- throw new Error("Unexpected response type");
1410
- }
1411
- /**
1412
- * Get backup status for user
1413
- */
1414
- async getBackupStatus(userId) {
1415
- const response = await this.sendMessage("GET_BACKUP_STATUS", {
1416
- userId
1417
- });
1418
- if (response.type === "IFRAME_MSG_BACKUP_STATUS") {
1419
- return response.status;
1420
- }
1421
- throw new Error("Unexpected response type");
1422
- }
1423
- /**
1424
- * Get available cloud providers
1425
- */
1426
- async getCloudProviders() {
1427
- const response = await this.sendMessage("GET_CLOUD_PROVIDERS", {});
1428
- if (response.type === "IFRAME_MSG_CLOUD_PROVIDERS") {
1429
- return response.providers;
1430
- }
1431
- throw new Error("Unexpected response type");
1432
- }
1433
- /**
1434
- * Cleanup and destroy iframe
1435
- */
1436
- destroy() {
1437
- this.log("[IframeManager] Destroying iframe...");
1438
- this.stopHeartbeat();
1439
- this.pendingRequests.forEach((pending) => {
1440
- pending.reject(new Error("Iframe manager destroyed"));
1441
- });
1442
- this.pendingRequests.clear();
1443
- if (this.messageListener) {
1444
- window.removeEventListener("message", this.messageListener);
1445
- this.messageListener = null;
1446
- }
1447
- if (this.iframe && this.iframe.parentNode) {
1448
- this.iframe.parentNode.removeChild(this.iframe);
1449
- }
1450
- this.iframe = null;
1451
- this.isReady = false;
1452
- this.channelToken = null;
1453
- this.initPromise = null;
1454
- this.readyPromise = new Promise((resolve) => {
1455
- this.readyResolve = resolve;
1456
- });
1457
- this.log("[IframeManager] \u2705 Destroyed");
1458
- }
1459
- /**
1460
- * Debug logging
1461
- */
1462
- log(message, data) {
1463
- if (this.debug) {
1464
- if (data) {
1465
- console.log(message, data);
1466
- } else {
1467
- console.log(message);
1468
- }
1469
- }
1470
- }
1471
- };
1472
- var iframeManagerInstance = null;
1473
- function getIframeManager(config) {
1474
- if (!iframeManagerInstance && config) {
1475
- iframeManagerInstance = new IframeManager(config);
1476
- }
1477
- if (!iframeManagerInstance) {
1478
- throw new Error(
1479
- 'IframeManager not initialized. This usually means projectId is not configured.\n\nTo fix this:\n1. Get your projectId from https://dashboard.lumiapassport.com/\n2. Add it to Provider:\n <Provider projectId="your-project-id">\n\nFor more details, see the documentation.'
1480
- );
1481
- }
1482
- return iframeManagerInstance;
1483
- }
1484
- async function waitForIframe() {
1485
- const manager = getIframeManager();
1486
- await manager.initialize();
1487
- }
1488
- function destroyIframeManager() {
1489
- if (iframeManagerInstance) {
1490
- iframeManagerInstance.destroy();
1491
- iframeManagerInstance = null;
1492
- }
1493
- }
1494
-
1495
-
1496
-
1497
-
1498
-
1499
-
1500
-
1501
-
1502
-
1503
-
1504
-
1505
-
1506
-
1507
-
1508
-
1509
-
1510
-
1511
-
1512
-
1513
-
1514
- exports.GoogleIcon = GoogleIcon; exports.TelegramIcon = TelegramIcon; exports.TwitterIcon = TwitterIcon; exports.DiscordIcon = DiscordIcon; exports.init_assets = init_assets; exports.DEFAULT_PROVIDER_CONFIG = DEFAULT_PROVIDER_CONFIG; exports.getServiceUrls = getServiceUrls; exports.getIframeUrl = getIframeUrl; exports.getBlockscoutApiUrl = getBlockscoutApiUrl; exports.init_initial = init_initial; exports.AccountAbstractionError = AccountAbstractionError; exports.UserRejectedError = UserRejectedError; exports.ErrorCodes = ErrorCodes; exports.createAccountAbstractionError = createAccountAbstractionError; exports.IframeManager = IframeManager; exports.getIframeManager = getIframeManager; exports.waitForIframe = waitForIframe; exports.destroyIframeManager = destroyIframeManager;
1515
- //# sourceMappingURL=chunk-B254FLAW.cjs.map