@openkey/sdk 0.10.1 → 0.11.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
@@ -141,8 +141,9 @@ var NostrFrame = class {
141
141
  }
142
142
  };
143
143
  var OpenKeyNostr = class {
144
- constructor(host) {
144
+ constructor(host, passkeysSupported = true) {
145
145
  this.host = host;
146
+ this.passkeysSupported = passkeysSupported;
146
147
  }
147
148
  /**
148
149
  * Get-or-create the user's OpenKey-custodied Nostr identity. Always shows
@@ -185,7 +186,8 @@ var OpenKeyNostr = class {
185
186
  }
186
187
  widgetUrl() {
187
188
  const origin = encodeURIComponent(window.location.origin);
188
- return `${this.host}/widget/embed/nostr/approve?origin=${origin}`;
189
+ const passkeysFlag = this.passkeysSupported ? "" : "&passkeys=false";
190
+ return `${this.host}/widget/embed/nostr/approve?origin=${origin}${passkeysFlag}`;
189
191
  }
190
192
  run(url, request, onData) {
191
193
  return new Promise((resolve, reject) => {
@@ -229,6 +231,9 @@ var OpenKeyNostr = class {
229
231
  };
230
232
 
231
233
  // src/index.ts
234
+ function passkeysQueryFlag(passkeysSupported) {
235
+ return passkeysSupported ? "" : "&passkeys=false";
236
+ }
232
237
  var DEFAULT_HOST = "https://openkey.so";
233
238
  var POPUP_WIDTH = 400;
234
239
  var POPUP_HEIGHT = 600;
@@ -548,18 +553,18 @@ var OpenKey = class {
548
553
  oauthHost;
549
554
  appName;
550
555
  mode;
556
+ passkeysSupported;
551
557
  config;
552
558
  popup = null;
553
559
  lastAuth = null;
554
560
  discoveredProviders = [];
555
- sessionToken = null;
556
561
  /** Cancels widget flows that could outlive a sign-out on this instance. */
557
562
  activeFlowCancellations = /* @__PURE__ */ new Set();
558
563
  /**
559
564
  * Nostr identity custody + signing (secp256k1 Schnorr / BIP-340). Kept
560
565
  * fully separate from the Ethereum flows above: it never reuses
561
- * `lastAuth`/`sessionToken`, and its widget messages never carry a
562
- * sessionToken - the OpenKey session and any signing grants stay inside
566
+ * `lastAuth`, and its widget messages never carry a session token -
567
+ * the OpenKey session and any signing grants stay inside
563
568
  * the OpenKey-origin iframe for the whole lifetime of this client.
564
569
  */
565
570
  nostr;
@@ -569,7 +574,8 @@ var OpenKey = class {
569
574
  this.oauthHost = config.oauthHost || this.deriveOAuthHost(this.host);
570
575
  this.appName = config.appName || window.location.hostname;
571
576
  this.mode = config.mode ?? "iframe";
572
- this.nostr = new OpenKeyNostr(this.host);
577
+ this.passkeysSupported = config.passkeysSupported ?? true;
578
+ this.nostr = new OpenKeyNostr(this.host, this.passkeysSupported);
573
579
  if (typeof window !== "undefined") {
574
580
  this.discoveredProviders = [];
575
581
  window.addEventListener("eip6963:announceProvider", (event) => {
@@ -641,25 +647,22 @@ var OpenKey = class {
641
647
  /**
642
648
  * Signs the active OpenKey account out through the OpenKey-owned widget.
643
649
  *
644
- * The SDK passes its Better Auth bearer through the OpenKey-owned widget
645
- * protocol so applications do not have to implement revocation themselves.
646
- * Local SDK session state is cleared before opening the widget, including
647
- * when remote revocation is unavailable.
650
+ * The OpenKey-owned widget revokes the OpenKey session it holds itself;
651
+ * the SDK never holds an OpenKey session token. Local SDK state is cleared
652
+ * before opening the widget, including when remote revocation is
653
+ * unavailable.
648
654
  */
649
655
  async signOut(opts) {
650
656
  const requestId = `ok-signout-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
651
- const sessionToken = this.sessionToken || void 0;
652
657
  const mode = this.resolveMode(opts?.mode) === "redirect" ? "popup" : opts?.mode;
653
658
  this.cancelActiveFlows();
654
659
  this.lastAuth = null;
655
- this.sessionToken = null;
656
660
  const acknowledgement = await this.openFlow(
657
661
  "sign-out",
658
662
  {
659
663
  type: "openkey:sign-out:request",
660
664
  requestId,
661
- protocolVersion: 1,
662
- sessionToken
665
+ protocolVersion: 1
663
666
  },
664
667
  mode
665
668
  );
@@ -669,22 +672,26 @@ var OpenKey = class {
669
672
  return acknowledgement;
670
673
  }
671
674
  /**
672
- * Better-auth session token relayed during connect(), or null if the
673
- * flow did not provide one. Use as a bearer token for API calls made
674
- * on the user's behalf (e.g. TinyCloud auto-sign bootstrap signing).
675
+ * Always null. OpenKey no longer gives its session token to the embedding
676
+ * page (TC-688): the token unlocked OpenKey's key and account APIs, not
677
+ * just the requesting app's flows.
678
+ *
679
+ * @deprecated Kept so existing callers compile. Third-party server-side
680
+ * signing uses an OAuth access token from the OpenKey OAuth flow.
675
681
  */
676
682
  getSessionToken() {
677
- return this.sessionToken;
683
+ return null;
678
684
  }
679
685
  /**
680
- * Endpoint + bearer token for a TinyCloud auto-sign signing strategy.
681
- * The endpoint is on the OpenKey API host and only signs requests the
682
- * server-side bootstrap allowlist permits.
686
+ * Endpoint for a TinyCloud auto-sign signing strategy. `token` is always
687
+ * null; see {@link OpenKey.getSessionToken}.
688
+ *
689
+ * @deprecated The endpoint accepts an OAuth access token as its bearer.
683
690
  */
684
691
  tinycloudSigningOptions() {
685
692
  return {
686
693
  endpoint: `${this.oauthHost}/api/delegate/sign`,
687
- token: this.sessionToken
694
+ token: null
688
695
  };
689
696
  }
690
697
  /**
@@ -769,8 +776,7 @@ var OpenKey = class {
769
776
  // context. The envelope is display-only; the widget transport
770
777
  // validates and size-bounds it before use and NEVER treats it as
771
778
  // verified unless the server actually origin-binds a manifest.
772
- presentation: request.presentation,
773
- sessionToken: this.sessionToken || void 0
779
+ presentation: request.presentation
774
780
  },
775
781
  opts?.mode
776
782
  );
@@ -847,7 +853,6 @@ var OpenKey = class {
847
853
  // bounded at the transport, never treated as verified without
848
854
  // server-side origin-binding.
849
855
  presentation: request.presentation,
850
- sessionToken: this.sessionToken || void 0,
851
856
  // Sol MAJOR-3 (continuation): tell the widget to hand us back
852
857
  // the previewApproval instead of asking OpenKey to sign
853
858
  // server-side with a managed key. The widget will still render
@@ -1001,15 +1006,13 @@ var OpenKey = class {
1001
1006
  return this.openFlow("sign", {
1002
1007
  type: "openkey:sign:request",
1003
1008
  message: request.message,
1004
- keyId: request.keyId,
1005
- sessionToken: this.sessionToken || void 0
1009
+ keyId: request.keyId
1006
1010
  }, mode);
1007
1011
  }
1008
1012
  signTypedDataWithOpenKey(request, mode) {
1009
1013
  return this.openFlow("sign-typed-data", {
1010
1014
  type: "openkey:signTypedData:request",
1011
- data: request,
1012
- sessionToken: this.sessionToken || void 0
1015
+ data: request
1013
1016
  }, mode);
1014
1017
  }
1015
1018
  toHex(str) {
@@ -1219,17 +1222,18 @@ var OpenKey = class {
1219
1222
  const mode = this.resolveMode(modeOverride);
1220
1223
  const origin = encodeURIComponent(window.location.origin);
1221
1224
  const eoaFlag = action === "connect" && this.hasDetectedEoa() ? "&hasEoa=true" : "";
1225
+ const passkeysFlag = passkeysQueryFlag(this.passkeysSupported);
1222
1226
  if (mode === "popup") {
1223
- const url2 = `${this.host}/widget/${action}?origin=${origin}${eoaFlag}`;
1227
+ const url2 = `${this.host}/widget/${action}?origin=${origin}${eoaFlag}${passkeysFlag}`;
1224
1228
  return new Promise((resolve, reject) => this.openPopup(action, url2, message, resolve, reject));
1225
1229
  }
1226
1230
  if (mode === "redirect") {
1227
- const url2 = `${this.host}/widget/${action}?origin=${origin}${eoaFlag}`;
1231
+ const url2 = `${this.host}/widget/${action}?origin=${origin}${eoaFlag}${passkeysFlag}`;
1228
1232
  window.location.href = url2;
1229
1233
  return new Promise(() => {
1230
1234
  });
1231
1235
  }
1232
- const url = `${this.host}/widget/embed/${action}?origin=${origin}${eoaFlag}`;
1236
+ const url = `${this.host}/widget/embed/${action}?origin=${origin}${eoaFlag}${passkeysFlag}`;
1233
1237
  return this.openIframeModal(url, action, message, origin);
1234
1238
  }
1235
1239
  openIframeModal(url, action, message, origin) {
@@ -1295,7 +1299,6 @@ var OpenKey = class {
1295
1299
  cleanup();
1296
1300
  if (data.success) {
1297
1301
  if (data.type === "openkey:auth:response") {
1298
- if (data.sessionToken) this.sessionToken = data.sessionToken;
1299
1302
  resolve({ address: data.address, keyId: data.keyId, keyType: data.keyType || "MANAGED" });
1300
1303
  } else if (data.type === "openkey:link-wallet:response") {
1301
1304
  resolve({ address: data.address, keyId: data.keyId });
@@ -1336,7 +1339,7 @@ var OpenKey = class {
1336
1339
  cleanup();
1337
1340
  console.warn("OpenKey: iframe blocked by CSP, falling back to popup. Add frame-src https://openkey.so to your CSP.");
1338
1341
  showToast();
1339
- const popupUrl = `${this.host}/widget/${action}?origin=${origin}`;
1342
+ const popupUrl = `${this.host}/widget/${action}?origin=${origin}${passkeysQueryFlag(this.passkeysSupported)}`;
1340
1343
  this.openPopup(action, popupUrl, message, (val) => settle(() => resolve(val)), (err) => settle(() => reject(err)));
1341
1344
  }, IFRAME_READY_TIMEOUT);
1342
1345
  const overallTimeout = setTimeout(() => {
@@ -1518,7 +1521,6 @@ var OpenKey = class {
1518
1521
  popup.close();
1519
1522
  if (data.success) {
1520
1523
  if (data.type === "openkey:auth:response") {
1521
- if (data.sessionToken) this.sessionToken = data.sessionToken;
1522
1524
  resolve({ address: data.address, keyId: data.keyId, keyType: data.keyType || "MANAGED" });
1523
1525
  } else if (data.type === "openkey:link-wallet:response") {
1524
1526
  resolve({ address: data.address, keyId: data.keyId });
@@ -1641,6 +1643,7 @@ export {
1641
1643
  OpenKeyProvider,
1642
1644
  index_default as default,
1643
1645
  getOpenKey,
1646
+ passkeysQueryFlag,
1644
1647
  resolveAuthorizeTinyCloudRouting,
1645
1648
  shouldRouteAuthorizeTinyCloudExternal,
1646
1649
  validateIframeResize