@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.d.mts +32 -15
- package/dist/index.d.ts +32 -15
- package/dist/index.js +39 -35
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +38 -35
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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
|
|
562
|
-
*
|
|
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.
|
|
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
|
|
645
|
-
*
|
|
646
|
-
*
|
|
647
|
-
*
|
|
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
|
-
*
|
|
673
|
-
*
|
|
674
|
-
*
|
|
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
|
|
683
|
+
return null;
|
|
678
684
|
}
|
|
679
685
|
/**
|
|
680
|
-
* Endpoint
|
|
681
|
-
*
|
|
682
|
-
*
|
|
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:
|
|
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
|