@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.js CHANGED
@@ -387,6 +387,7 @@ var IframeModal = class {
387
387
  root;
388
388
  shadow;
389
389
  iframe;
390
+ card;
390
391
  onClose;
391
392
  onMessage;
392
393
  messageHandler;
@@ -398,6 +399,10 @@ var IframeModal = class {
398
399
  // only uncorrelated resizes from this iframe are accepted (TC-647).
399
400
  expectedRequestId = null;
400
401
  expectedProtocolVersion = null;
402
+ phaseV2 = false;
403
+ currentLayoutId = 0;
404
+ displayedHeight = 0;
405
+ hasDisplayedLayout = false;
401
406
  constructor(opts) {
402
407
  this.host = opts.host;
403
408
  this.onClose = opts.onClose;
@@ -428,24 +433,29 @@ var IframeModal = class {
428
433
  backdrop.addEventListener("click", (e) => {
429
434
  if (e.target === backdrop) this.close();
430
435
  });
431
- const card = document.createElement("div");
432
- card.className = "ok-card";
436
+ this.card = document.createElement("div");
437
+ this.card.className = "ok-card";
438
+ if (opts.hideUntilLayout) {
439
+ this.card.style.visibility = "hidden";
440
+ this.card.style.animation = "none";
441
+ }
433
442
  if (isMobile) {
434
443
  const handle = document.createElement("div");
435
444
  handle.className = "ok-handle";
436
- card.appendChild(handle);
445
+ this.card.appendChild(handle);
437
446
  }
438
447
  const closeBtn = document.createElement("button");
439
448
  closeBtn.className = "ok-close";
440
449
  closeBtn.textContent = "\xD7";
441
450
  closeBtn.addEventListener("click", () => this.close());
442
- card.appendChild(closeBtn);
451
+ this.card.appendChild(closeBtn);
443
452
  this.iframe = document.createElement("iframe");
444
453
  this.iframe.src = opts.url;
445
454
  this.iframe.setAttribute("allow", "clipboard-write *; publickey-credentials-get *; publickey-credentials-create *");
446
455
  this.iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox");
447
- card.appendChild(this.iframe);
448
- backdrop.appendChild(card);
456
+ if (opts.hideUntilLayout) this.iframe.style.visibility = "hidden";
457
+ this.card.appendChild(this.iframe);
458
+ backdrop.appendChild(this.card);
449
459
  this.shadow.appendChild(style);
450
460
  this.shadow.appendChild(backdrop);
451
461
  this.messageHandler = (event) => {
@@ -459,16 +469,54 @@ var IframeModal = class {
459
469
  viewportHeight: window.innerHeight
460
470
  });
461
471
  if (h === null) return;
462
- this.iframe.style.height = `${h}px`;
472
+ if (this.phaseV2) {
473
+ if (typeof data.layoutId !== "number" || !Number.isSafeInteger(data.layoutId) || data.layoutId <= this.currentLayoutId) return;
474
+ this.currentLayoutId = data.layoutId;
475
+ this.iframe.style.transition = "none";
476
+ }
477
+ if (!this.phaseV2 || !this.hasDisplayedLayout) {
478
+ this.iframe.style.height = `${h}px`;
479
+ if (this.phaseV2) this.displayedHeight = h;
480
+ }
481
+ if (this.phaseV2) {
482
+ this.iframe.style.visibility = "visible";
483
+ this.card.style.visibility = "visible";
484
+ this.postMessage({
485
+ type: "openkey:layout-applied",
486
+ requestId: this.expectedRequestId,
487
+ protocolVersion: 2,
488
+ layoutId: data.layoutId,
489
+ height: this.hasDisplayedLayout ? this.displayedHeight : h
490
+ });
491
+ }
463
492
  return;
464
493
  }
465
- if (data.type === "openkey:close") {
494
+ if (data.type === "openkey:layout-ready" || data.type === "openkey:layout-invalidated") {
495
+ if (!this.phaseV2 || data.requestId !== this.expectedRequestId || data.protocolVersion !== this.expectedProtocolVersion || data.layoutId !== this.currentLayoutId) return;
496
+ if (data.type === "openkey:layout-ready") {
497
+ this.hasDisplayedLayout = true;
498
+ }
499
+ return;
466
500
  }
467
501
  this.onMessage(data);
468
502
  };
469
503
  window.addEventListener("message", this.messageHandler);
470
504
  document.body.appendChild(this.root);
471
505
  }
506
+ activatePhase(requestId, protocolVersion) {
507
+ this.setExpectedCorrelation(requestId, protocolVersion);
508
+ this.phaseV2 = true;
509
+ }
510
+ isVersionedPhase() {
511
+ return this.phaseV2;
512
+ }
513
+ revealLegacy() {
514
+ this.iframe.style.visibility = "visible";
515
+ this.card.style.visibility = "visible";
516
+ }
517
+ hasDisplayedCurrentPhase() {
518
+ return this.hasDisplayedLayout;
519
+ }
472
520
  postMessage(message) {
473
521
  this.iframe.contentWindow?.postMessage(message, this.host);
474
522
  }
@@ -1074,7 +1122,7 @@ var OpenKey = class {
1074
1122
  return this.openFlow("sign", {
1075
1123
  type: "openkey:sign:request",
1076
1124
  message: request.message,
1077
- keyId: request.keyId
1125
+ keyId: request.keyId ?? this.lastAuth?.keyId
1078
1126
  }, mode);
1079
1127
  }
1080
1128
  signTypedDataWithOpenKey(request, mode) {
@@ -1301,10 +1349,13 @@ var OpenKey = class {
1301
1349
  return new Promise(() => {
1302
1350
  });
1303
1351
  }
1304
- const url = `${this.host}/widget/embed/${action}?origin=${origin}${eoaFlag}${passkeysFlag}`;
1305
- return this.openIframeModal(url, action, message, origin);
1352
+ const selectedKeyId = action === "sign" && "keyId" in message ? message.keyId : null;
1353
+ const phase = action === "connect" || action === "sign" && typeof selectedKeyId === "string" ? { requestId: crypto.randomUUID(), protocolVersion: 2 } : null;
1354
+ const keyId = action === "sign" && "keyId" in message && typeof message.keyId === "string" ? `&keyId=${encodeURIComponent(message.keyId)}` : "";
1355
+ const url = `${this.host}/widget/embed/${action}?origin=${origin}${eoaFlag}${passkeysFlag}${phase ? `&requestId=${encodeURIComponent(phase.requestId)}&protocolVersion=2${keyId}` : ""}`;
1356
+ return this.openIframeModal(url, action, message, origin, phase);
1306
1357
  }
1307
- openIframeModal(url, action, message, origin) {
1358
+ openIframeModal(url, action, message, origin, phase = null) {
1308
1359
  const outgoingRequestId = message.requestId;
1309
1360
  const outgoingProtocolVersion = message.protocolVersion;
1310
1361
  const isVersionedRequest = typeof outgoingRequestId === "string" && typeof outgoingProtocolVersion === "number" && outgoingProtocolVersion >= 1;
@@ -1328,6 +1379,7 @@ var OpenKey = class {
1328
1379
  modal = new IframeModal({
1329
1380
  url,
1330
1381
  host: this.host,
1382
+ hideUntilLayout: action === "sign" && !!phase,
1331
1383
  onClose: () => {
1332
1384
  settle(() => {
1333
1385
  cleanup();
@@ -1335,16 +1387,35 @@ var OpenKey = class {
1335
1387
  });
1336
1388
  },
1337
1389
  onMessage: (data) => {
1390
+ if (settled) return;
1338
1391
  if (data.type === "openkey:ready") {
1392
+ if (readyReceived) return;
1393
+ if (phase && data.protocolVersion === 2) {
1394
+ if (data.requestId !== phase.requestId) return;
1395
+ modal?.activatePhase(phase.requestId, phase.protocolVersion);
1396
+ modal?.postMessage({
1397
+ ...message,
1398
+ ...phase,
1399
+ ...action === "sign" && isVersionedRequest && outgoingProtocolVersion === 1 ? { authorizationProtocolVersion: 1 } : {}
1400
+ });
1401
+ } else if (phase && data.protocolVersion !== void 0 && data.protocolVersion !== 1) {
1402
+ return;
1403
+ } else {
1404
+ modal?.setExpectedCorrelation(
1405
+ isVersionedRequest ? outgoingRequestId : null,
1406
+ isVersionedRequest ? outgoingProtocolVersion : null
1407
+ );
1408
+ modal?.revealLegacy();
1409
+ modal?.postMessage(message);
1410
+ }
1339
1411
  readyReceived = true;
1340
- modal?.postMessage(message);
1341
1412
  return;
1342
1413
  }
1343
- if (isVersionedRequest) {
1344
- const respRequestId = data.requestId;
1345
- const respVersion = data.protocolVersion;
1346
- if (respRequestId !== outgoingRequestId) return;
1347
- if (respVersion !== outgoingProtocolVersion) return;
1414
+ if (!readyReceived) return;
1415
+ const activeRequestId = phase && modal?.isVersionedPhase() ? phase.requestId : isVersionedRequest ? outgoingRequestId : null;
1416
+ const activeVersion = phase && modal?.isVersionedPhase() ? phase.protocolVersion : isVersionedRequest ? outgoingProtocolVersion : null;
1417
+ if (activeRequestId !== null) {
1418
+ if (!("requestId" in data) || data.requestId !== activeRequestId || !("protocolVersion" in data) || data.protocolVersion !== activeVersion) return;
1348
1419
  }
1349
1420
  if (data.type === "openkey:close") {
1350
1421
  settle(() => {
@@ -1354,7 +1425,7 @@ var OpenKey = class {
1354
1425
  return;
1355
1426
  }
1356
1427
  if (data.type === "openkey:link-wallet:delegate") {
1357
- this.handleWalletLinkDelegation(modal);
1428
+ this.handleWalletLinkDelegation(modal, modal?.isVersionedPhase() ? phase : null);
1358
1429
  return;
1359
1430
  }
1360
1431
  if (data.type === "openkey:auth:use-external-wallet") {
@@ -1362,6 +1433,7 @@ var OpenKey = class {
1362
1433
  this.handleExternalWalletConnect(resolve, reject);
1363
1434
  return;
1364
1435
  }
1436
+ if (action === "sign" && modal?.isVersionedPhase() && !modal.hasDisplayedCurrentPhase() && this.isResponseForAction(action, data)) return;
1365
1437
  if (this.isResponseForAction(action, data)) {
1366
1438
  settle(() => {
1367
1439
  cleanup();
@@ -1439,8 +1511,8 @@ var OpenKey = class {
1439
1511
  if (action === "sign-out") return type === "openkey:sign-out:response";
1440
1512
  return false;
1441
1513
  }
1442
- handleWalletLinkDelegation(modal) {
1443
- const sendResult = (result) => modal.postMessage(result);
1514
+ handleWalletLinkDelegation(modal, phase = null) {
1515
+ const sendResult = (result) => modal.postMessage({ ...result, ...phase });
1444
1516
  new WalletPicker({
1445
1517
  providers: this.discoveredProviders,
1446
1518
  onCancel: () => {