@openkey/sdk 0.12.0 → 0.12.1-beta.0

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/index.mjs CHANGED
@@ -352,6 +352,7 @@ var IframeModal = class {
352
352
  root;
353
353
  shadow;
354
354
  iframe;
355
+ card;
355
356
  onClose;
356
357
  onMessage;
357
358
  messageHandler;
@@ -363,6 +364,10 @@ var IframeModal = class {
363
364
  // only uncorrelated resizes from this iframe are accepted (TC-647).
364
365
  expectedRequestId = null;
365
366
  expectedProtocolVersion = null;
367
+ phaseV2 = false;
368
+ currentLayoutId = 0;
369
+ displayedHeight = 0;
370
+ hasDisplayedLayout = false;
366
371
  constructor(opts) {
367
372
  this.host = opts.host;
368
373
  this.onClose = opts.onClose;
@@ -393,24 +398,29 @@ var IframeModal = class {
393
398
  backdrop.addEventListener("click", (e) => {
394
399
  if (e.target === backdrop) this.close();
395
400
  });
396
- const card = document.createElement("div");
397
- card.className = "ok-card";
401
+ this.card = document.createElement("div");
402
+ this.card.className = "ok-card";
403
+ if (opts.hideUntilLayout) {
404
+ this.card.style.visibility = "hidden";
405
+ this.card.style.animation = "none";
406
+ }
398
407
  if (isMobile) {
399
408
  const handle = document.createElement("div");
400
409
  handle.className = "ok-handle";
401
- card.appendChild(handle);
410
+ this.card.appendChild(handle);
402
411
  }
403
412
  const closeBtn = document.createElement("button");
404
413
  closeBtn.className = "ok-close";
405
414
  closeBtn.textContent = "\xD7";
406
415
  closeBtn.addEventListener("click", () => this.close());
407
- card.appendChild(closeBtn);
416
+ this.card.appendChild(closeBtn);
408
417
  this.iframe = document.createElement("iframe");
409
418
  this.iframe.src = opts.url;
410
419
  this.iframe.setAttribute("allow", "clipboard-write *; publickey-credentials-get *; publickey-credentials-create *");
411
420
  this.iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox");
412
- card.appendChild(this.iframe);
413
- backdrop.appendChild(card);
421
+ if (opts.hideUntilLayout) this.iframe.style.visibility = "hidden";
422
+ this.card.appendChild(this.iframe);
423
+ backdrop.appendChild(this.card);
414
424
  this.shadow.appendChild(style);
415
425
  this.shadow.appendChild(backdrop);
416
426
  this.messageHandler = (event) => {
@@ -424,16 +434,54 @@ var IframeModal = class {
424
434
  viewportHeight: window.innerHeight
425
435
  });
426
436
  if (h === null) return;
427
- this.iframe.style.height = `${h}px`;
437
+ if (this.phaseV2) {
438
+ if (typeof data.layoutId !== "number" || !Number.isSafeInteger(data.layoutId) || data.layoutId <= this.currentLayoutId) return;
439
+ this.currentLayoutId = data.layoutId;
440
+ this.iframe.style.transition = "none";
441
+ }
442
+ if (!this.phaseV2 || !this.hasDisplayedLayout) {
443
+ this.iframe.style.height = `${h}px`;
444
+ if (this.phaseV2) this.displayedHeight = h;
445
+ }
446
+ if (this.phaseV2) {
447
+ this.iframe.style.visibility = "visible";
448
+ this.card.style.visibility = "visible";
449
+ this.postMessage({
450
+ type: "openkey:layout-applied",
451
+ requestId: this.expectedRequestId,
452
+ protocolVersion: 2,
453
+ layoutId: data.layoutId,
454
+ height: this.hasDisplayedLayout ? this.displayedHeight : h
455
+ });
456
+ }
428
457
  return;
429
458
  }
430
- if (data.type === "openkey:close") {
459
+ if (data.type === "openkey:layout-ready" || data.type === "openkey:layout-invalidated") {
460
+ if (!this.phaseV2 || data.requestId !== this.expectedRequestId || data.protocolVersion !== this.expectedProtocolVersion || data.layoutId !== this.currentLayoutId) return;
461
+ if (data.type === "openkey:layout-ready") {
462
+ this.hasDisplayedLayout = true;
463
+ }
464
+ return;
431
465
  }
432
466
  this.onMessage(data);
433
467
  };
434
468
  window.addEventListener("message", this.messageHandler);
435
469
  document.body.appendChild(this.root);
436
470
  }
471
+ activatePhase(requestId, protocolVersion) {
472
+ this.setExpectedCorrelation(requestId, protocolVersion);
473
+ this.phaseV2 = true;
474
+ }
475
+ isVersionedPhase() {
476
+ return this.phaseV2;
477
+ }
478
+ revealLegacy() {
479
+ this.iframe.style.visibility = "visible";
480
+ this.card.style.visibility = "visible";
481
+ }
482
+ hasDisplayedCurrentPhase() {
483
+ return this.hasDisplayedLayout;
484
+ }
437
485
  postMessage(message) {
438
486
  this.iframe.contentWindow?.postMessage(message, this.host);
439
487
  }
@@ -1039,7 +1087,7 @@ var OpenKey = class {
1039
1087
  return this.openFlow("sign", {
1040
1088
  type: "openkey:sign:request",
1041
1089
  message: request.message,
1042
- keyId: request.keyId
1090
+ keyId: request.keyId ?? this.lastAuth?.keyId
1043
1091
  }, mode);
1044
1092
  }
1045
1093
  signTypedDataWithOpenKey(request, mode) {
@@ -1266,10 +1314,13 @@ var OpenKey = class {
1266
1314
  return new Promise(() => {
1267
1315
  });
1268
1316
  }
1269
- const url = `${this.host}/widget/embed/${action}?origin=${origin}${eoaFlag}${passkeysFlag}`;
1270
- return this.openIframeModal(url, action, message, origin);
1317
+ const selectedKeyId = action === "sign" && "keyId" in message ? message.keyId : null;
1318
+ const phase = action === "connect" || action === "sign" && typeof selectedKeyId === "string" ? { requestId: crypto.randomUUID(), protocolVersion: 2 } : null;
1319
+ const keyId = action === "sign" && "keyId" in message && typeof message.keyId === "string" ? `&keyId=${encodeURIComponent(message.keyId)}` : "";
1320
+ const url = `${this.host}/widget/embed/${action}?origin=${origin}${eoaFlag}${passkeysFlag}${phase ? `&requestId=${encodeURIComponent(phase.requestId)}&protocolVersion=2${keyId}` : ""}`;
1321
+ return this.openIframeModal(url, action, message, origin, phase);
1271
1322
  }
1272
- openIframeModal(url, action, message, origin) {
1323
+ openIframeModal(url, action, message, origin, phase = null) {
1273
1324
  const outgoingRequestId = message.requestId;
1274
1325
  const outgoingProtocolVersion = message.protocolVersion;
1275
1326
  const isVersionedRequest = typeof outgoingRequestId === "string" && typeof outgoingProtocolVersion === "number" && outgoingProtocolVersion >= 1;
@@ -1293,6 +1344,7 @@ var OpenKey = class {
1293
1344
  modal = new IframeModal({
1294
1345
  url,
1295
1346
  host: this.host,
1347
+ hideUntilLayout: action === "sign" && !!phase,
1296
1348
  onClose: () => {
1297
1349
  settle(() => {
1298
1350
  cleanup();
@@ -1300,16 +1352,35 @@ var OpenKey = class {
1300
1352
  });
1301
1353
  },
1302
1354
  onMessage: (data) => {
1355
+ if (settled) return;
1303
1356
  if (data.type === "openkey:ready") {
1357
+ if (readyReceived) return;
1358
+ if (phase && data.protocolVersion === 2) {
1359
+ if (data.requestId !== phase.requestId) return;
1360
+ modal?.activatePhase(phase.requestId, phase.protocolVersion);
1361
+ modal?.postMessage({
1362
+ ...message,
1363
+ ...phase,
1364
+ ...action === "sign" && isVersionedRequest && outgoingProtocolVersion === 1 ? { authorizationProtocolVersion: 1 } : {}
1365
+ });
1366
+ } else if (phase && data.protocolVersion !== void 0 && data.protocolVersion !== 1) {
1367
+ return;
1368
+ } else {
1369
+ modal?.setExpectedCorrelation(
1370
+ isVersionedRequest ? outgoingRequestId : null,
1371
+ isVersionedRequest ? outgoingProtocolVersion : null
1372
+ );
1373
+ modal?.revealLegacy();
1374
+ modal?.postMessage(message);
1375
+ }
1304
1376
  readyReceived = true;
1305
- modal?.postMessage(message);
1306
1377
  return;
1307
1378
  }
1308
- if (isVersionedRequest) {
1309
- const respRequestId = data.requestId;
1310
- const respVersion = data.protocolVersion;
1311
- if (respRequestId !== outgoingRequestId) return;
1312
- if (respVersion !== outgoingProtocolVersion) return;
1379
+ if (!readyReceived) return;
1380
+ const activeRequestId = phase && modal?.isVersionedPhase() ? phase.requestId : isVersionedRequest ? outgoingRequestId : null;
1381
+ const activeVersion = phase && modal?.isVersionedPhase() ? phase.protocolVersion : isVersionedRequest ? outgoingProtocolVersion : null;
1382
+ if (activeRequestId !== null) {
1383
+ if (!("requestId" in data) || data.requestId !== activeRequestId || !("protocolVersion" in data) || data.protocolVersion !== activeVersion) return;
1313
1384
  }
1314
1385
  if (data.type === "openkey:close") {
1315
1386
  settle(() => {
@@ -1319,7 +1390,7 @@ var OpenKey = class {
1319
1390
  return;
1320
1391
  }
1321
1392
  if (data.type === "openkey:link-wallet:delegate") {
1322
- this.handleWalletLinkDelegation(modal);
1393
+ this.handleWalletLinkDelegation(modal, modal?.isVersionedPhase() ? phase : null);
1323
1394
  return;
1324
1395
  }
1325
1396
  if (data.type === "openkey:auth:use-external-wallet") {
@@ -1327,6 +1398,7 @@ var OpenKey = class {
1327
1398
  this.handleExternalWalletConnect(resolve, reject);
1328
1399
  return;
1329
1400
  }
1401
+ if (action === "sign" && modal?.isVersionedPhase() && !modal.hasDisplayedCurrentPhase() && this.isResponseForAction(action, data)) return;
1330
1402
  if (this.isResponseForAction(action, data)) {
1331
1403
  settle(() => {
1332
1404
  cleanup();
@@ -1404,8 +1476,8 @@ var OpenKey = class {
1404
1476
  if (action === "sign-out") return type === "openkey:sign-out:response";
1405
1477
  return false;
1406
1478
  }
1407
- handleWalletLinkDelegation(modal) {
1408
- const sendResult = (result) => modal.postMessage(result);
1479
+ handleWalletLinkDelegation(modal, phase = null) {
1480
+ const sendResult = (result) => modal.postMessage({ ...result, ...phase });
1409
1481
  new WalletPicker({
1410
1482
  providers: this.discoveredProviders,
1411
1483
  onCancel: () => {