@lumiapassport/ui-kit 1.13.6 → 1.13.7

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.
@@ -1218,6 +1218,135 @@ var init_keccak256 = __esm({
1218
1218
  }
1219
1219
  });
1220
1220
 
1221
+ // src/iframe/templates/template-engine.ts
1222
+ var TemplateEngine = class {
1223
+ /**
1224
+ * Render template with data
1225
+ */
1226
+ static render(template, data) {
1227
+ let html = template;
1228
+ html = this.processConditionals(html, data);
1229
+ html = this.processVariables(html, data);
1230
+ return html;
1231
+ }
1232
+ /**
1233
+ * Process conditional blocks: {{#if condition}}...{{else}}...{{/if}}
1234
+ */
1235
+ static processConditionals(html, data) {
1236
+ const conditionalRegex = /\{\{#if\s+(\w+)\}\}([\s\S]*?)(?:\{\{else\}\}([\s\S]*?))?\{\{\/if\}\}/g;
1237
+ return html.replace(conditionalRegex, (match, variable, trueBlock, falseBlock) => {
1238
+ const value = data[variable];
1239
+ const condition = this.isTruthy(value);
1240
+ if (condition) {
1241
+ return trueBlock || "";
1242
+ } else {
1243
+ return falseBlock || "";
1244
+ }
1245
+ });
1246
+ }
1247
+ /**
1248
+ * Process variable interpolation: {{variable}}
1249
+ */
1250
+ static processVariables(html, data) {
1251
+ const variableRegex = /\{\{(?!#|\/|else)(\w+)\}\}/g;
1252
+ return html.replace(variableRegex, (match, variable) => {
1253
+ const value = data[variable];
1254
+ return value !== null && value !== void 0 ? String(value) : "";
1255
+ });
1256
+ }
1257
+ /**
1258
+ * Check if value is truthy (for conditionals)
1259
+ */
1260
+ static isTruthy(value) {
1261
+ if (value === null || value === void 0) return false;
1262
+ if (typeof value === "boolean") return value;
1263
+ if (typeof value === "number") return value !== 0;
1264
+ if (typeof value === "string") return value.length > 0;
1265
+ return true;
1266
+ }
1267
+ };
1268
+
1269
+ // src/iframe/templates/html/authorization.html
1270
+ var authorization_default = '<div class="modal-overlay">\n <div class="modal-content" style="display: flex; flex-direction: column; gap: var(--iframe-gap); align-items: center">\n <div style="display: flex; align-items: center; gap: var(--iframe-gap); justify-content: center">\n <img\n src="./lumia-logo.svg"\n alt="Lumia Passport"\n style="width: 40px; height: 40px; border-radius: 20px; object-fit: cover"\n />\n\n <span\n style="display: block; font-size: var(--iframe-h1-fz); font-weight: var(--iframe-heading-fw); line-height: 150%"\n >Authorize</span\n >\n </div>\n\n <div style="display: flex; align-items: center; gap: var(--iframe-gap); justify-content: center">\n {{#if displayLogo}}\n <img\n src="{{displayLogo}}"\n alt="{{displayName}}"\n style="width: 32px; height: 32px; border-radius: 16px; object-fit: cover"\n />\n {{else}}\n <span style="font-size: 14px; font-weight: 600">{{displayName}}</span>\n {{/if}}\n\n <span\n style="display: block; font-size: var(--iframe-h2-fz); font-weight: var(--iframe-heading-fw); line-height: 150%"\n >{{displayName}}</span\n >\n </div>\n\n <div class="domain-info {{domainStatusClass}}" style="font-size: 12px; text-align: center">\n <span style="font-family: monospace">{{domainStatusIcon}} {{domainStatusText}} {{origin}}</span>\n </div>\n\n <!-- Permissions box -->\n <details style="display: flex; flex-direction: column; width: 100%">\n <summary\n style="\n cursor: pointer;\n text-align: center;\n list-style: none;\n padding: 0 var(--iframe-pd);\n user-select: none;\n font-size: 12px;\n line-height: 20px;\n "\n >\n Show Permissions\n </summary>\n <div\n data-details-content="true"\n style="\n width: 100%;\n padding: var(--iframe-gap);\n border-radius: var(--iframe-el-bdrs);\n background: var(--iframe-info);\n font-size: 10px;\n "\n >\n <div style="margin-bottom: var(--iframe-gap)">\n <strong>{{displayName}}</strong> by <span class="project-owner">{{displayName}}</span> wants to access your\n <strong>Lumia Passport</strong> account\n </div>\n\n <div style="margin-bottom: var(--iframe-gap)">\n <strong style="margin-bottom: var(--iframe-gap)">Personal user data</strong>\n <ul style="list-style: none">\n <li style="padding-left: var(--iframe-pd)">Wallet address (read-only)</li>\n <li style="padding-left: var(--iframe-pd)">Public transaction history (read-only)</li>\n </ul>\n </div>\n\n <div style="width: 100%">\n <strong style="margin-bottom: var(--iframe-gap)">Permissions</strong>\n <ul style="list-style: none">\n <li style="padding-left: var(--iframe-pd)">Request transaction signatures</li>\n <li style="padding-left: var(--iframe-pd)">Initiate blockchain operations</li>\n </ul>\n </div>\n </div>\n </details>\n\n {{#if showSecurityWarning}}\n <div class="security-warning">\n <strong>\u26A0\uFE0F Warning:</strong> This domain is not verified for {{displayName}}\n <div>Expected: {{expectedDomains}}</div>\n <div>Actual: {{origin}}</div>\n </div>\n {{else}}\n <span style="font-size: 10px; color: var(--iframe-text-secondary)"\n >By continuing you allow the app to use these permissions.</span\n >\n {{/if}}\n\n <!-- Action buttons -->\n <div style="display: flex; gap: var(--iframe-gap); width: 100%; align-items: center">\n <button class="cancel-btn">Cancel</button>\n <button class="authorize-btn" {{authorizeButtonState}}>Continue</button>\n </div>\n\n <!-- Footer notice -->\n <div\n style="\n color: var(--iframe-text-secondary);\n font-size: 10px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n align-items: center;\n text-align: center;\n "\n >\n <span>Authorizing will redirect to <strong>{{origin}}</strong></span>\n <span>You can revoke access at any time in your Lumia Passport settings.</span>\n </div>\n </div>\n</div>\n';
1271
+
1272
+ // src/iframe/templates/html/ready-indicator.html
1273
+ var ready_indicator_default = '<div class="ready-indicator">\n <div class="status-icon">\u2713</div>\n <h2>Secure Wallet Ready</h2>\n <p>Lumia Passport is ready for secure operations</p>\n <div class="info">\n <div class="info-row">\n <strong>Origin:</strong>\n <span>{{origin}}</span>\n </div>\n <div class="info-row">\n <strong>Status:</strong>\n <span class="status-active">Active</span>\n </div>\n <div class="info-row">\n <strong>Version:</strong>\n <span>{{iframeVersion}}</span>\n </div>\n <div class="info-row">\n <strong>Documentation:</strong>\n <a\n href="https://docs.lumiapassport.com/"\n target="_blank"\n rel="noopener noreferrer"\n style="color: #667eea; text-decoration: none"\n >docs.lumiapassport.com</a\n >\n </div>\n </div>\n</div>\n';
1274
+
1275
+ // src/iframe/templates/template-loader.ts
1276
+ var TemplateLoader = class {
1277
+ /** Get template by name */
1278
+ static getTemplate(name) {
1279
+ if (this.templateCache.has(name)) {
1280
+ return this.templateCache.get(name);
1281
+ }
1282
+ const template = this.loadBundledTemplate(name);
1283
+ if (!template) {
1284
+ throw new Error(`Template not found: ${name}`);
1285
+ }
1286
+ this.templateCache.set(name, template);
1287
+ return template;
1288
+ }
1289
+ /** Load bundled template */
1290
+ static loadBundledTemplate(name) {
1291
+ switch (name) {
1292
+ case "authorization":
1293
+ return authorization_default;
1294
+ case "ready-indicator":
1295
+ return ready_indicator_default;
1296
+ default:
1297
+ return null;
1298
+ }
1299
+ }
1300
+ // /** Pre-load all templates (optional optimization) */
1301
+ // static preloadTemplates(): void {
1302
+ // this.getTemplate('authorization')
1303
+ // console.log('[TemplateLoader] Pre-loaded all templates')
1304
+ // }
1305
+ // /** Clear template cache (useful for hot-reloading in development) */
1306
+ // static clearCache(): void {
1307
+ // this.templateCache.clear()
1308
+ // console.log('[TemplateLoader] Cleared template cache')
1309
+ // }
1310
+ };
1311
+ TemplateLoader.templateCache = /* @__PURE__ */ new Map();
1312
+
1313
+ // src/iframe/templates/data/authorization-template-data.ts
1314
+ function buildAuthorizationTemplateData(project, origin, metadata, userProfile) {
1315
+ const isVerifiedOrigin = project.domains.includes(origin);
1316
+ const displayName = metadata?.name || project.name;
1317
+ const displayLogo = metadata?.logo || project.logoUrl || "";
1318
+ const displayDescription = metadata?.description || "";
1319
+ const userAvatar = userProfile?.avatar || "";
1320
+ const userName = userProfile?.displayName || "Lumia Passport";
1321
+ return {
1322
+ // Display
1323
+ displayName,
1324
+ displayLogo,
1325
+ displayDescription,
1326
+ // User
1327
+ userAvatar,
1328
+ userName,
1329
+ // Domain
1330
+ origin,
1331
+ domainStatusClass: isVerifiedOrigin ? "verified" : "unverified",
1332
+ domainStatusIcon: isVerifiedOrigin ? "\u2713" : "\u26A0\uFE0F",
1333
+ domainStatusText: isVerifiedOrigin ? "Verified domain:" : "Unverified domain:",
1334
+ // Security
1335
+ showSecurityWarning: !isVerifiedOrigin,
1336
+ expectedDomains: project.domains.join(", "),
1337
+ // Button
1338
+ authorizeButtonState: !isVerifiedOrigin ? "disabled" : ""
1339
+ };
1340
+ }
1341
+
1342
+ // src/iframe/templates/data/ready-indicator-data.ts
1343
+ function buildReadyIndicatorData(input) {
1344
+ return {
1345
+ origin: input.origin,
1346
+ iframeVersion: input.iframeVersion
1347
+ };
1348
+ }
1349
+
1221
1350
  // src/iframe/lib/authorization-manager.ts
1222
1351
  var AuthorizationManager = class {
1223
1352
  constructor() {
@@ -1376,93 +1505,10 @@ var AuthorizationManager = class {
1376
1505
  createAuthorizationModal(project, origin, metadata, userProfile) {
1377
1506
  const modal = document.createElement("div");
1378
1507
  modal.className = "authorization-modal";
1379
- const isVerifiedOrigin = project.domains.includes(origin);
1380
- const displayName = metadata?.name || project.name;
1381
- const displayLogo = metadata?.logo || project.logoUrl;
1382
- const displayDescription = metadata?.description;
1383
- const userAvatar = userProfile?.avatar;
1384
- const userName = userProfile?.displayName || "Lumia Passport";
1385
- modal.innerHTML = `
1386
- <div class="modal-overlay">
1387
- <div class="modal-content">
1388
- <!-- Header with logos -->
1389
- <div class="auth-header">
1390
- <div class="logo-container">
1391
- ${displayLogo ? `<img src="${displayLogo}" alt="${displayName}" class="app-logo" />` : '<div class="app-logo-placeholder"></div>'}
1392
- <div class="logo-connector">
1393
- <svg width="24" height="16" viewBox="0 0 24 16" fill="currentColor">
1394
- <path d="M23.7071 8.70711C24.0976 8.31658 24.0976 7.68342 23.7071 7.29289L17.3431 0.928932C16.9526 0.538408 16.3195 0.538408 15.9289 0.928932C15.5384 1.31946 15.5384 1.95262 15.9289 2.34315L21.5858 8L15.9289 13.6569C15.5384 14.0474 15.5384 14.6805 15.9289 15.0711C16.3195 15.4616 16.9526 15.4616 17.3431 15.0711L23.7071 8.70711ZM0 9H23V7H0V9Z"/>
1395
- </svg>
1396
- </div>
1397
- ${userAvatar ? `<img src="${userAvatar}" alt="${userName}" class="lumia-logo user-avatar" />` : '<img src="./lumia-logo.svg" alt="Lumia Passport" class="lumia-logo" />'}
1398
- </div>
1399
- </div>
1400
-
1401
- <!-- Authorization title -->
1402
- <h2 class="auth-title">Authorize ${displayName}</h2>
1403
-
1404
- <!-- Description section -->
1405
- <div class="auth-description">
1406
- ${displayDescription ? `<p class="project-description">${displayDescription}</p>` : ""}
1407
- <div class="domain-info ${isVerifiedOrigin ? "verified" : "unverified"}">
1408
- <span class="domain-label">
1409
- ${isVerifiedOrigin ? "\u2713 Verified domain:" : "\u26A0\uFE0F Unverified domain:"}
1410
- </span>
1411
- <span class="domain-value">${origin}</span>
1412
- </div>
1413
- </div>
1414
-
1415
- <!-- Permissions box -->
1416
- <div class="permissions-box">
1417
- <div class="permissions-header">
1418
- <strong>${displayName}</strong> by <span class="project-owner">${displayName}</span> wants to access your <strong>Lumia Passport</strong> account
1419
- </div>
1420
-
1421
- <div class="permissions-list">
1422
- <div class="permission-group">
1423
- <div class="permission-group-title">Personal user data</div>
1424
- <ul>
1425
- <li>Wallet address (read-only)</li>
1426
- <li>Public transaction history (read-only)</li>
1427
- </ul>
1428
- </div>
1429
-
1430
- <div class="permission-group">
1431
- <div class="permission-group-title">Permissions</div>
1432
- <ul>
1433
- <li>Request transaction signatures</li>
1434
- <li>Initiate blockchain operations</li>
1435
- </ul>
1436
- </div>
1437
- </div>
1438
- </div>
1439
-
1440
- ${!isVerifiedOrigin ? `
1441
- <div class="security-warning">
1442
- <strong>\u26A0\uFE0F Warning:</strong> This domain is not verified for ${displayName}
1443
- <div class="warning-details">
1444
- <div>Expected: ${project.domains.join(", ")}</div>
1445
- <div>Actual: ${origin}</div>
1446
- </div>
1447
- </div>
1448
- ` : ""}
1449
-
1450
- <!-- Action buttons -->
1451
- <div class="actions">
1452
- <button class="cancel-btn">Cancel</button>
1453
- <button class="authorize-btn" ${!isVerifiedOrigin ? "disabled" : ""}>
1454
- Authorize ${displayName}
1455
- </button>
1456
- </div>
1457
-
1458
- <!-- Footer notice -->
1459
- <div class="auth-footer">
1460
- <p>Authorizing will redirect to <strong>${origin}</strong></p>
1461
- <p class="footer-note">You can revoke access at any time in your Lumia Passport settings.</p>
1462
- </div>
1463
- </div>
1464
- </div>
1465
- `;
1508
+ const templateData = buildAuthorizationTemplateData(project, origin, metadata, userProfile);
1509
+ const template = TemplateLoader.getTemplate("authorization");
1510
+ const populatedHTML = TemplateEngine.render(template, templateData);
1511
+ modal.innerHTML = populatedHTML;
1466
1512
  return modal;
1467
1513
  }
1468
1514
  /**
@@ -3964,7 +4010,7 @@ var SigningManager = class extends TokenRefreshApiClient {
3964
4010
  };
3965
4011
 
3966
4012
  // src/iframe/main.ts
3967
- var IFRAME_VERSION = "1.13.6";
4013
+ var IFRAME_VERSION = "1.13.7";
3968
4014
  var IframeWallet = class {
3969
4015
  constructor() {
3970
4016
  console.log("=".repeat(60));
@@ -4588,31 +4634,13 @@ var IframeWallet = class {
4588
4634
  displayReadyIndicator() {
4589
4635
  const app = document.getElementById("app");
4590
4636
  if (!app) return;
4591
- app.innerHTML = `
4592
- <div class="ready-indicator">
4593
- <div class="status-icon">\u{1F512}</div>
4594
- <h2>Secure Wallet Ready</h2>
4595
- <p>Lumia Passport is ready for secure operations</p>
4596
- <div class="info">
4597
- <div class="info-row">
4598
- <strong>Origin:</strong>
4599
- <span>${window.location.origin}</span>
4600
- </div>
4601
- <div class="info-row">
4602
- <strong>Status:</strong>
4603
- <span class="status-active">Active</span>
4604
- </div>
4605
- <div class="info-row">
4606
- <strong>Version:</strong>
4607
- <span>${IFRAME_VERSION}</span>
4608
- </div>
4609
- <div class="info-row">
4610
- <strong>Documentation:</strong>
4611
- <a href="https://docs.lumiapassport.com/" target="_blank" rel="noopener noreferrer" style="color: #667eea; text-decoration: none;">docs.lumiapassport.com</a>
4612
- </div>
4613
- </div>
4614
- </div>
4615
- `;
4637
+ const templateData = buildReadyIndicatorData({
4638
+ origin: window.location.origin,
4639
+ iframeVersion: IFRAME_VERSION
4640
+ });
4641
+ const template = TemplateLoader.getTemplate("ready-indicator");
4642
+ const populatedReadyIndicatorHTML = TemplateEngine.render(template, templateData);
4643
+ app.innerHTML = populatedReadyIndicatorHTML;
4616
4644
  }
4617
4645
  /**
4618
4646
  * Send wallet ready status to parent