@openkey/sdk 0.10.0 → 0.10.2
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 -18
- package/dist/index.d.ts +32 -18
- package/dist/index.js +48 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +48 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -211,12 +211,23 @@ interface CapabilityPresentationEnvelopeV1 {
|
|
|
211
211
|
/**
|
|
212
212
|
* Sol final continuation contract requirement 5: pure validation of an
|
|
213
213
|
* incoming iframe resize message envelope. Exported so unit tests can
|
|
214
|
-
* exercise every rejection branch — wrong requestId, wrong version,
|
|
215
|
-
*
|
|
216
|
-
*
|
|
214
|
+
* exercise every rejection branch — wrong requestId, wrong version,
|
|
215
|
+
* malformed height — without booting the browser runtime that
|
|
216
|
+
* `IframeModal` requires.
|
|
217
217
|
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
218
|
+
* Two modes, chosen by the modal's bound correlation:
|
|
219
|
+
* - Versioned request bound (`requestId` AND `protocolVersion` set): the
|
|
220
|
+
* resize MUST carry that exact pair.
|
|
221
|
+
* - No versioned request (both null — `connect`, `signMessage`, and the
|
|
222
|
+
* other unversioned flows): the widget sends a plain
|
|
223
|
+
* `{ type, height }`. It is accepted only when it carries no
|
|
224
|
+
* `requestId`. The caller has already checked that the message came
|
|
225
|
+
* from this modal's iframe (`event.source`) on the OpenKey origin
|
|
226
|
+
* (TC-647).
|
|
227
|
+
* A half-bound correlation (only one of the two set) drops everything.
|
|
228
|
+
*
|
|
229
|
+
* Returns the height clamped to 85% of the viewport when acceptable, or
|
|
230
|
+
* `null` when the message must be dropped.
|
|
220
231
|
*/
|
|
221
232
|
declare function validateIframeResize(incoming: unknown, expected: {
|
|
222
233
|
requestId: string | null;
|
|
@@ -318,14 +329,13 @@ declare class OpenKey {
|
|
|
318
329
|
private popup;
|
|
319
330
|
private lastAuth;
|
|
320
331
|
private discoveredProviders;
|
|
321
|
-
private sessionToken;
|
|
322
332
|
/** Cancels widget flows that could outlive a sign-out on this instance. */
|
|
323
333
|
private activeFlowCancellations;
|
|
324
334
|
/**
|
|
325
335
|
* Nostr identity custody + signing (secp256k1 Schnorr / BIP-340). Kept
|
|
326
336
|
* fully separate from the Ethereum flows above: it never reuses
|
|
327
|
-
* `lastAuth
|
|
328
|
-
*
|
|
337
|
+
* `lastAuth`, and its widget messages never carry a session token -
|
|
338
|
+
* the OpenKey session and any signing grants stay inside
|
|
329
339
|
* the OpenKey-origin iframe for the whole lifetime of this client.
|
|
330
340
|
*/
|
|
331
341
|
readonly nostr: OpenKeyNostr;
|
|
@@ -360,24 +370,28 @@ declare class OpenKey {
|
|
|
360
370
|
/**
|
|
361
371
|
* Signs the active OpenKey account out through the OpenKey-owned widget.
|
|
362
372
|
*
|
|
363
|
-
* The
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
373
|
+
* The OpenKey-owned widget revokes the OpenKey session it holds itself;
|
|
374
|
+
* the SDK never holds an OpenKey session token. Local SDK state is cleared
|
|
375
|
+
* before opening the widget, including when remote revocation is
|
|
376
|
+
* unavailable.
|
|
367
377
|
*/
|
|
368
378
|
signOut(opts?: {
|
|
369
379
|
mode?: OpenKeyMode;
|
|
370
380
|
}): Promise<SignOutAcknowledgement>;
|
|
371
381
|
/**
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
382
|
+
* Always null. OpenKey no longer gives its session token to the embedding
|
|
383
|
+
* page (TC-688): the token unlocked OpenKey's key and account APIs, not
|
|
384
|
+
* just the requesting app's flows.
|
|
385
|
+
*
|
|
386
|
+
* @deprecated Kept so existing callers compile. Third-party server-side
|
|
387
|
+
* signing uses an OAuth access token from the OpenKey OAuth flow.
|
|
375
388
|
*/
|
|
376
389
|
getSessionToken(): string | null;
|
|
377
390
|
/**
|
|
378
|
-
* Endpoint
|
|
379
|
-
*
|
|
380
|
-
*
|
|
391
|
+
* Endpoint for a TinyCloud auto-sign signing strategy. `token` is always
|
|
392
|
+
* null; see {@link OpenKey.getSessionToken}.
|
|
393
|
+
*
|
|
394
|
+
* @deprecated The endpoint accepts an OAuth access token as its bearer.
|
|
381
395
|
*/
|
|
382
396
|
tinycloudSigningOptions(): {
|
|
383
397
|
endpoint: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -211,12 +211,23 @@ interface CapabilityPresentationEnvelopeV1 {
|
|
|
211
211
|
/**
|
|
212
212
|
* Sol final continuation contract requirement 5: pure validation of an
|
|
213
213
|
* incoming iframe resize message envelope. Exported so unit tests can
|
|
214
|
-
* exercise every rejection branch — wrong requestId, wrong version,
|
|
215
|
-
*
|
|
216
|
-
*
|
|
214
|
+
* exercise every rejection branch — wrong requestId, wrong version,
|
|
215
|
+
* malformed height — without booting the browser runtime that
|
|
216
|
+
* `IframeModal` requires.
|
|
217
217
|
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
218
|
+
* Two modes, chosen by the modal's bound correlation:
|
|
219
|
+
* - Versioned request bound (`requestId` AND `protocolVersion` set): the
|
|
220
|
+
* resize MUST carry that exact pair.
|
|
221
|
+
* - No versioned request (both null — `connect`, `signMessage`, and the
|
|
222
|
+
* other unversioned flows): the widget sends a plain
|
|
223
|
+
* `{ type, height }`. It is accepted only when it carries no
|
|
224
|
+
* `requestId`. The caller has already checked that the message came
|
|
225
|
+
* from this modal's iframe (`event.source`) on the OpenKey origin
|
|
226
|
+
* (TC-647).
|
|
227
|
+
* A half-bound correlation (only one of the two set) drops everything.
|
|
228
|
+
*
|
|
229
|
+
* Returns the height clamped to 85% of the viewport when acceptable, or
|
|
230
|
+
* `null` when the message must be dropped.
|
|
220
231
|
*/
|
|
221
232
|
declare function validateIframeResize(incoming: unknown, expected: {
|
|
222
233
|
requestId: string | null;
|
|
@@ -318,14 +329,13 @@ declare class OpenKey {
|
|
|
318
329
|
private popup;
|
|
319
330
|
private lastAuth;
|
|
320
331
|
private discoveredProviders;
|
|
321
|
-
private sessionToken;
|
|
322
332
|
/** Cancels widget flows that could outlive a sign-out on this instance. */
|
|
323
333
|
private activeFlowCancellations;
|
|
324
334
|
/**
|
|
325
335
|
* Nostr identity custody + signing (secp256k1 Schnorr / BIP-340). Kept
|
|
326
336
|
* fully separate from the Ethereum flows above: it never reuses
|
|
327
|
-
* `lastAuth
|
|
328
|
-
*
|
|
337
|
+
* `lastAuth`, and its widget messages never carry a session token -
|
|
338
|
+
* the OpenKey session and any signing grants stay inside
|
|
329
339
|
* the OpenKey-origin iframe for the whole lifetime of this client.
|
|
330
340
|
*/
|
|
331
341
|
readonly nostr: OpenKeyNostr;
|
|
@@ -360,24 +370,28 @@ declare class OpenKey {
|
|
|
360
370
|
/**
|
|
361
371
|
* Signs the active OpenKey account out through the OpenKey-owned widget.
|
|
362
372
|
*
|
|
363
|
-
* The
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
373
|
+
* The OpenKey-owned widget revokes the OpenKey session it holds itself;
|
|
374
|
+
* the SDK never holds an OpenKey session token. Local SDK state is cleared
|
|
375
|
+
* before opening the widget, including when remote revocation is
|
|
376
|
+
* unavailable.
|
|
367
377
|
*/
|
|
368
378
|
signOut(opts?: {
|
|
369
379
|
mode?: OpenKeyMode;
|
|
370
380
|
}): Promise<SignOutAcknowledgement>;
|
|
371
381
|
/**
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
382
|
+
* Always null. OpenKey no longer gives its session token to the embedding
|
|
383
|
+
* page (TC-688): the token unlocked OpenKey's key and account APIs, not
|
|
384
|
+
* just the requesting app's flows.
|
|
385
|
+
*
|
|
386
|
+
* @deprecated Kept so existing callers compile. Third-party server-side
|
|
387
|
+
* signing uses an OAuth access token from the OpenKey OAuth flow.
|
|
375
388
|
*/
|
|
376
389
|
getSessionToken(): string | null;
|
|
377
390
|
/**
|
|
378
|
-
* Endpoint
|
|
379
|
-
*
|
|
380
|
-
*
|
|
391
|
+
* Endpoint for a TinyCloud auto-sign signing strategy. `token` is always
|
|
392
|
+
* null; see {@link OpenKey.getSessionToken}.
|
|
393
|
+
*
|
|
394
|
+
* @deprecated The endpoint accepts an OAuth access token as its bearer.
|
|
381
395
|
*/
|
|
382
396
|
tinycloudSigningOptions(): {
|
|
383
397
|
endpoint: string;
|
package/dist/index.js
CHANGED
|
@@ -273,12 +273,16 @@ function validateIframeResize(incoming, expected) {
|
|
|
273
273
|
if (!incoming || typeof incoming !== "object") return null;
|
|
274
274
|
const data = incoming;
|
|
275
275
|
if (data.type !== "openkey:resize") return null;
|
|
276
|
-
if (expected.requestId === null
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
276
|
+
if (expected.requestId === null && expected.protocolVersion === null) {
|
|
277
|
+
if (data.requestId !== void 0) return null;
|
|
278
|
+
} else {
|
|
279
|
+
if (expected.requestId === null || expected.protocolVersion === null) return null;
|
|
280
|
+
if (typeof data.protocolVersion !== "number" || data.protocolVersion !== expected.protocolVersion) {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
if (typeof data.requestId !== "string" || data.requestId !== expected.requestId) {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
282
286
|
}
|
|
283
287
|
if (typeof data.height !== "number" || !Number.isFinite(data.height) || data.height <= 0) {
|
|
284
288
|
return null;
|
|
@@ -354,11 +358,11 @@ var IframeModal = class {
|
|
|
354
358
|
onMessage;
|
|
355
359
|
messageHandler;
|
|
356
360
|
host;
|
|
357
|
-
// Sol final continuation contract requirement 5:
|
|
358
|
-
//
|
|
359
|
-
// Set by `setExpectedCorrelation`
|
|
360
|
-
//
|
|
361
|
-
//
|
|
361
|
+
// Sol final continuation contract requirement 5: when the modal carries a
|
|
362
|
+
// versioned request, iframe resize traffic MUST correlate to its
|
|
363
|
+
// requestId AND protocolVersion. Set by `setExpectedCorrelation` as soon
|
|
364
|
+
// as the modal is created. When both are null the flow is unversioned and
|
|
365
|
+
// only uncorrelated resizes from this iframe are accepted (TC-647).
|
|
362
366
|
expectedRequestId = null;
|
|
363
367
|
expectedProtocolVersion = null;
|
|
364
368
|
constructor(opts) {
|
|
@@ -440,10 +444,11 @@ var IframeModal = class {
|
|
|
440
444
|
* request correlation so subsequent resize (and future correlated)
|
|
441
445
|
* messages can be verified against `requestId` + `protocolVersion`.
|
|
442
446
|
*
|
|
443
|
-
* The outer flow calls this
|
|
444
|
-
* request
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
+
* The outer flow calls this right after creating the modal for a
|
|
448
|
+
* versioned request, before the iframe can send anything, so no
|
|
449
|
+
* uncorrelated resize is ever accepted for that request. Passing `null`
|
|
450
|
+
* for both arguments means the flow is unversioned; passing `null` for
|
|
451
|
+
* only one drops every resize.
|
|
447
452
|
*/
|
|
448
453
|
setExpectedCorrelation(requestId, protocolVersion) {
|
|
449
454
|
this.expectedRequestId = requestId;
|
|
@@ -581,14 +586,13 @@ var OpenKey = class {
|
|
|
581
586
|
popup = null;
|
|
582
587
|
lastAuth = null;
|
|
583
588
|
discoveredProviders = [];
|
|
584
|
-
sessionToken = null;
|
|
585
589
|
/** Cancels widget flows that could outlive a sign-out on this instance. */
|
|
586
590
|
activeFlowCancellations = /* @__PURE__ */ new Set();
|
|
587
591
|
/**
|
|
588
592
|
* Nostr identity custody + signing (secp256k1 Schnorr / BIP-340). Kept
|
|
589
593
|
* fully separate from the Ethereum flows above: it never reuses
|
|
590
|
-
* `lastAuth
|
|
591
|
-
*
|
|
594
|
+
* `lastAuth`, and its widget messages never carry a session token -
|
|
595
|
+
* the OpenKey session and any signing grants stay inside
|
|
592
596
|
* the OpenKey-origin iframe for the whole lifetime of this client.
|
|
593
597
|
*/
|
|
594
598
|
nostr;
|
|
@@ -670,25 +674,22 @@ var OpenKey = class {
|
|
|
670
674
|
/**
|
|
671
675
|
* Signs the active OpenKey account out through the OpenKey-owned widget.
|
|
672
676
|
*
|
|
673
|
-
* The
|
|
674
|
-
*
|
|
675
|
-
*
|
|
676
|
-
*
|
|
677
|
+
* The OpenKey-owned widget revokes the OpenKey session it holds itself;
|
|
678
|
+
* the SDK never holds an OpenKey session token. Local SDK state is cleared
|
|
679
|
+
* before opening the widget, including when remote revocation is
|
|
680
|
+
* unavailable.
|
|
677
681
|
*/
|
|
678
682
|
async signOut(opts) {
|
|
679
683
|
const requestId = `ok-signout-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
680
|
-
const sessionToken = this.sessionToken || void 0;
|
|
681
684
|
const mode = this.resolveMode(opts?.mode) === "redirect" ? "popup" : opts?.mode;
|
|
682
685
|
this.cancelActiveFlows();
|
|
683
686
|
this.lastAuth = null;
|
|
684
|
-
this.sessionToken = null;
|
|
685
687
|
const acknowledgement = await this.openFlow(
|
|
686
688
|
"sign-out",
|
|
687
689
|
{
|
|
688
690
|
type: "openkey:sign-out:request",
|
|
689
691
|
requestId,
|
|
690
|
-
protocolVersion: 1
|
|
691
|
-
sessionToken
|
|
692
|
+
protocolVersion: 1
|
|
692
693
|
},
|
|
693
694
|
mode
|
|
694
695
|
);
|
|
@@ -698,22 +699,26 @@ var OpenKey = class {
|
|
|
698
699
|
return acknowledgement;
|
|
699
700
|
}
|
|
700
701
|
/**
|
|
701
|
-
*
|
|
702
|
-
*
|
|
703
|
-
*
|
|
702
|
+
* Always null. OpenKey no longer gives its session token to the embedding
|
|
703
|
+
* page (TC-688): the token unlocked OpenKey's key and account APIs, not
|
|
704
|
+
* just the requesting app's flows.
|
|
705
|
+
*
|
|
706
|
+
* @deprecated Kept so existing callers compile. Third-party server-side
|
|
707
|
+
* signing uses an OAuth access token from the OpenKey OAuth flow.
|
|
704
708
|
*/
|
|
705
709
|
getSessionToken() {
|
|
706
|
-
return
|
|
710
|
+
return null;
|
|
707
711
|
}
|
|
708
712
|
/**
|
|
709
|
-
* Endpoint
|
|
710
|
-
*
|
|
711
|
-
*
|
|
713
|
+
* Endpoint for a TinyCloud auto-sign signing strategy. `token` is always
|
|
714
|
+
* null; see {@link OpenKey.getSessionToken}.
|
|
715
|
+
*
|
|
716
|
+
* @deprecated The endpoint accepts an OAuth access token as its bearer.
|
|
712
717
|
*/
|
|
713
718
|
tinycloudSigningOptions() {
|
|
714
719
|
return {
|
|
715
720
|
endpoint: `${this.oauthHost}/api/delegate/sign`,
|
|
716
|
-
token:
|
|
721
|
+
token: null
|
|
717
722
|
};
|
|
718
723
|
}
|
|
719
724
|
/**
|
|
@@ -798,8 +803,7 @@ var OpenKey = class {
|
|
|
798
803
|
// context. The envelope is display-only; the widget transport
|
|
799
804
|
// validates and size-bounds it before use and NEVER treats it as
|
|
800
805
|
// verified unless the server actually origin-binds a manifest.
|
|
801
|
-
presentation: request.presentation
|
|
802
|
-
sessionToken: this.sessionToken || void 0
|
|
806
|
+
presentation: request.presentation
|
|
803
807
|
},
|
|
804
808
|
opts?.mode
|
|
805
809
|
);
|
|
@@ -876,7 +880,6 @@ var OpenKey = class {
|
|
|
876
880
|
// bounded at the transport, never treated as verified without
|
|
877
881
|
// server-side origin-binding.
|
|
878
882
|
presentation: request.presentation,
|
|
879
|
-
sessionToken: this.sessionToken || void 0,
|
|
880
883
|
// Sol MAJOR-3 (continuation): tell the widget to hand us back
|
|
881
884
|
// the previewApproval instead of asking OpenKey to sign
|
|
882
885
|
// server-side with a managed key. The widget will still render
|
|
@@ -1030,15 +1033,13 @@ var OpenKey = class {
|
|
|
1030
1033
|
return this.openFlow("sign", {
|
|
1031
1034
|
type: "openkey:sign:request",
|
|
1032
1035
|
message: request.message,
|
|
1033
|
-
keyId: request.keyId
|
|
1034
|
-
sessionToken: this.sessionToken || void 0
|
|
1036
|
+
keyId: request.keyId
|
|
1035
1037
|
}, mode);
|
|
1036
1038
|
}
|
|
1037
1039
|
signTypedDataWithOpenKey(request, mode) {
|
|
1038
1040
|
return this.openFlow("sign-typed-data", {
|
|
1039
1041
|
type: "openkey:signTypedData:request",
|
|
1040
|
-
data: request
|
|
1041
|
-
sessionToken: this.sessionToken || void 0
|
|
1042
|
+
data: request
|
|
1042
1043
|
}, mode);
|
|
1043
1044
|
}
|
|
1044
1045
|
toHex(str) {
|
|
@@ -1294,12 +1295,6 @@ var OpenKey = class {
|
|
|
1294
1295
|
onMessage: (data) => {
|
|
1295
1296
|
if (data.type === "openkey:ready") {
|
|
1296
1297
|
readyReceived = true;
|
|
1297
|
-
if (isVersionedRequest && modal) {
|
|
1298
|
-
modal.setExpectedCorrelation(
|
|
1299
|
-
outgoingRequestId,
|
|
1300
|
-
outgoingProtocolVersion
|
|
1301
|
-
);
|
|
1302
|
-
}
|
|
1303
1298
|
modal?.postMessage(message);
|
|
1304
1299
|
return;
|
|
1305
1300
|
}
|
|
@@ -1330,7 +1325,6 @@ var OpenKey = class {
|
|
|
1330
1325
|
cleanup();
|
|
1331
1326
|
if (data.success) {
|
|
1332
1327
|
if (data.type === "openkey:auth:response") {
|
|
1333
|
-
if (data.sessionToken) this.sessionToken = data.sessionToken;
|
|
1334
1328
|
resolve({ address: data.address, keyId: data.keyId, keyType: data.keyType || "MANAGED" });
|
|
1335
1329
|
} else if (data.type === "openkey:link-wallet:response") {
|
|
1336
1330
|
resolve({ address: data.address, keyId: data.keyId });
|
|
@@ -1360,6 +1354,12 @@ var OpenKey = class {
|
|
|
1360
1354
|
}
|
|
1361
1355
|
}
|
|
1362
1356
|
});
|
|
1357
|
+
if (isVersionedRequest) {
|
|
1358
|
+
modal.setExpectedCorrelation(
|
|
1359
|
+
outgoingRequestId,
|
|
1360
|
+
outgoingProtocolVersion
|
|
1361
|
+
);
|
|
1362
|
+
}
|
|
1363
1363
|
const readyTimeout = setTimeout(() => {
|
|
1364
1364
|
if (readyReceived || settled) return;
|
|
1365
1365
|
cleanup();
|
|
@@ -1547,7 +1547,6 @@ var OpenKey = class {
|
|
|
1547
1547
|
popup.close();
|
|
1548
1548
|
if (data.success) {
|
|
1549
1549
|
if (data.type === "openkey:auth:response") {
|
|
1550
|
-
if (data.sessionToken) this.sessionToken = data.sessionToken;
|
|
1551
1550
|
resolve({ address: data.address, keyId: data.keyId, keyType: data.keyType || "MANAGED" });
|
|
1552
1551
|
} else if (data.type === "openkey:link-wallet:response") {
|
|
1553
1552
|
resolve({ address: data.address, keyId: data.keyId });
|