@synonymdev/pubky 0.10.0-alpha.0 → 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/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@synonymdev/pubky",
3
3
  "type": "module",
4
- "description": "Pubky client",
5
- "version": "0.10.0-alpha.0",
4
+ "description": "Decentralized identity, auth flows, and user-owned storage",
5
+ "version": "0.11.0",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/pubky/pubky-core.git"
9
+ "url": "git+https://github.com/pubky/pubky-homeserver.git"
10
10
  },
11
11
  "scripts": {
12
12
  "testnet": "cargo run -p pubky-testnet",
@@ -16,6 +16,7 @@
16
16
  "test-browser": "npm run build:test && browserify dist/tests/setup.js dist/tests/*.js -p esmify | npx tape-run",
17
17
  "test-browser:ci": "npm run build:test && browserify dist/tests/setup.js dist/tests/*.js -p esmify | tape-run --browser electron --electron-arg=--no-sandbox --electron-arg=--disable-gpu",
18
18
  "build": "cargo run --bin bundle_npm",
19
+ "docs": "typedoc",
19
20
  "prepublishOnly": "npm run build"
20
21
  },
21
22
  "files": [
@@ -42,9 +43,13 @@
42
43
  "esmify": "^2.1.1",
43
44
  "tape": "^5.8.1",
44
45
  "tape-run": "^11.0.0",
46
+ "typedoc": "^0.28.20",
45
47
  "typescript": "^5.4.5"
46
48
  },
47
49
  "dependencies": {
48
50
  "fetch-cookie": "^3.0.1"
51
+ },
52
+ "overrides": {
53
+ "electron": "41.0.2"
49
54
  }
50
55
  }
package/pubky.d.ts CHANGED
@@ -21,6 +21,31 @@ type ReadableStreamType = "bytes";
21
21
  */
22
22
  export type PubkyErrorName = "RequestError" | "InvalidInput" | "AuthenticationError" | "PkarrError" | "ClientStateError" | "InternalError";
23
23
 
24
+ /**
25
+ * Optional x-callback-url metadata carried by a Pubky deep link.
26
+ *
27
+ * Callback destinations are untrusted navigation hints. Authentication still
28
+ * completes through the encrypted relay.
29
+ */
30
+ export interface XCallbackParams {
31
+ /**
32
+ * Human-readable name of the requesting application.
33
+ */
34
+ xSource?: string | null;
35
+ /**
36
+ * Destination to open after successful completion.
37
+ */
38
+ xSuccess?: string | null;
39
+ /**
40
+ * Destination to open after an error.
41
+ */
42
+ xError?: string | null;
43
+ /**
44
+ * Destination to open after user cancellation or timeout.
45
+ */
46
+ xCancel?: string | null;
47
+ }
48
+
24
49
  /**
25
50
  * Options for starting a grant-backed pubkyauth flow.
26
51
  */
@@ -34,6 +59,10 @@ export interface GrantAuthFlowOptions {
34
59
  * Defaults to the default Synonym-hosted relay when omitted.
35
60
  */
36
61
  relay?: string | null;
62
+ /**
63
+ * Optional return destinations for success, error, and cancellation.
64
+ */
65
+ xCallback?: XCallbackParams | null;
37
66
  }
38
67
 
39
68
  /**
@@ -251,6 +280,9 @@ export class AuthFlow {
251
280
  * Optional HTTP relay base, e.g. `"https://demo.httprelay.io/inbox/"`.
252
281
  * Defaults to the default Synonym-hosted relay when omitted.
253
282
  *
283
+ * @param {XCallbackParams} [xCallback]
284
+ * Optional return destinations for success, error, and cancellation.
285
+ *
254
286
  * @returns {AuthFlow}
255
287
  * A running auth flow. Call `authorizationUrl()` to show the deep link,
256
288
  * then `awaitApproval()` to receive a `Session`.
@@ -264,7 +296,7 @@ export class AuthFlow {
264
296
  *
265
297
  * @deprecated Use `GrantAuthFlow.start(...)` instead.
266
298
  */
267
- static start(capabilities: Capabilities, kind: AuthFlowKind, relay?: string | null): AuthFlow;
299
+ static start(capabilities: Capabilities, kind: AuthFlowKind, relay?: string | null, x_callback?: XCallbackParams | null): AuthFlow;
268
300
  /**
269
301
  * Non-blocking single poll step (advanced UIs).
270
302
  *
@@ -406,6 +438,51 @@ export class AuthToken {
406
438
  readonly publicKey: PublicKey;
407
439
  }
408
440
 
441
+ /**
442
+ * Browser-backed durable store for completed grant sessions.
443
+ */
444
+ export class BrowserSessionStore {
445
+ private constructor();
446
+ free(): void;
447
+ [Symbol.dispose](): void;
448
+ /**
449
+ * Clear all local stored session records for this origin.
450
+ *
451
+ * Delegated keys referenced by those stored session records are removed.
452
+ * Delegated keys that only belong to pending grant flows are preserved.
453
+ */
454
+ clear(): Promise<void>;
455
+ /**
456
+ * Clear all browser auth persistence owned by this SDK origin.
457
+ *
458
+ * This removes all stored session records and all browser-held delegated
459
+ * grant keys, including keys for pending delegated grant flows. Saved
460
+ * delegated flow state becomes unrestorable. This does not revoke remote
461
+ * grants or immediately invalidate already-live in-memory sessions.
462
+ */
463
+ clearAll(): Promise<void>;
464
+ /**
465
+ * Whether IndexedDB is available for durable session persistence.
466
+ */
467
+ isAvailable(): Promise<boolean>;
468
+ /**
469
+ * List all locally stored sessions for this origin.
470
+ */
471
+ list(): Promise<StoredSessionInfo[]>;
472
+ /**
473
+ * Remove local stored session metadata and any SDK-owned delegated key for that record.
474
+ */
475
+ remove(id: string): Promise<void>;
476
+ /**
477
+ * Restore a specific stored session by id.
478
+ */
479
+ restore(id: string): Promise<Session>;
480
+ /**
481
+ * Persist a completed grant session in IndexedDB.
482
+ */
483
+ save(session: Session): Promise<StoredSessionInfo>;
484
+ }
485
+
409
486
  /**
410
487
  * Low-level HTTP bridge used by the Pubky facade and actors.
411
488
  *
@@ -499,6 +576,32 @@ export class CookieSession {
499
576
  exportSecret(): Promise<string>;
500
577
  }
501
578
 
579
+ /**
580
+ * Parsed direct signup deeplink.
581
+ */
582
+ export class DirectSignupDeepLink {
583
+ private constructor();
584
+ free(): void;
585
+ [Symbol.dispose](): void;
586
+ /**
587
+ * Parse a direct signup deeplink URL.
588
+ */
589
+ static parse(url: string): DirectSignupDeepLink;
590
+ toString(): string;
591
+ /**
592
+ * Homeserver public key requested for account creation.
593
+ */
594
+ readonly homeserver: PublicKey;
595
+ /**
596
+ * Optional signup token included in the request.
597
+ */
598
+ readonly signupToken: string | undefined;
599
+ /**
600
+ * Optional x-callback-url metadata carried by this deep link.
601
+ */
602
+ readonly xCallback: XCallbackParams;
603
+ }
604
+
502
605
  /**
503
606
  * A single event from the event stream.
504
607
  *
@@ -559,6 +662,15 @@ export class Event {
559
662
  * console.log(event.eventType, event.resource.path);
560
663
  * }
561
664
  * ```
665
+ *
666
+ * @example
667
+ * ```typescript
668
+ * // Private events: attach a session and request a `/priv/...` path.
669
+ * const stream = await pubky.eventStreamForUser(userPubkey, null)
670
+ * .session(session)
671
+ * .path("/priv/app/")
672
+ * .subscribe();
673
+ * ```
562
674
  */
563
675
  export class EventStreamBuilder {
564
676
  private constructor();
@@ -628,12 +740,17 @@ export class EventStreamBuilder {
628
740
  */
629
741
  live(): EventStreamBuilder;
630
742
  /**
631
- * Filter events by path prefix.
743
+ * Filter events by path. Call once per path to receive the
744
+ * union of several scopes (e.g. `/pub/` plus a private `/priv/app/`).
632
745
  *
633
- * Format: Path WITHOUT `pubky://` scheme or user pubkey (e.g., "/pub/files/" or "/pub/").
634
- * Only events whose path starts with this prefix are returned.
746
+ * Format: a path WITHOUT the `pubky://` scheme or user pubkey. A trailing
747
+ * slash matches a directory and all its descendants (`/pub/files/`); no
748
+ * trailing slash matches an exact file (`/pub/notes.txt`).
635
749
  *
636
- * @param {string} path - Path prefix to filter by
750
+ * Private (`/priv/...`) paths require a session attached via `session()`;
751
+ * without one the homeserver rejects the subscription with 401.
752
+ *
753
+ * @param {string} path - Path filter (repeatable)
637
754
  * @returns {EventStreamBuilder} - Builder for chaining
638
755
  */
639
756
  path(path: string): EventStreamBuilder;
@@ -649,6 +766,19 @@ export class EventStreamBuilder {
649
766
  * @returns {EventStreamBuilder} - Builder for chaining
650
767
  */
651
768
  reverse(): EventStreamBuilder;
769
+ /**
770
+ * Authenticate the subscription with a user `Session`.
771
+ *
772
+ * Required to receive private (`/priv/...`) events: the session credential
773
+ * (grant or cookie) is attached so the homeserver can authorize each private
774
+ * `path()` against the session's read capabilities. Public subscriptions
775
+ * don't need this.
776
+ *
777
+ *
778
+ * @param {Session} session - The authenticated session
779
+ * @returns {EventStreamBuilder} - Builder for chaining
780
+ */
781
+ session(session: Session): EventStreamBuilder;
652
782
  /**
653
783
  * Subscribe to the event stream.
654
784
  *
@@ -699,20 +829,37 @@ export class GrantAuthFlow {
699
829
  * **Security:** `savedState` contains the relay secret and PoP client private key.
700
830
  * Store it only temporarily and delete it once the flow completes or is abandoned.
701
831
  *
702
- * @param {string} savedState A string produced by `grantFlow.save()`.
832
+ * @param {string} savedState A string produced by `grantFlow.saveLocal()`.
703
833
  * @returns {GrantAuthFlow} A flow reconnected to the original relay channel.
704
834
  */
705
835
  static resume(saved_state: string): GrantAuthFlow;
706
836
  /**
707
- * Save sensitive state required to resume this pending grant flow.
837
+ * Resume a previously saved pending delegated grant auth flow.
838
+ *
839
+ * Runtime: delegated grant keys require a secure browser context with
840
+ * WebCrypto `crypto.subtle` and IndexedDB. The saved `keyId` must still
841
+ * exist in IndexedDB for the same origin. Unsupported runtimes reject with
842
+ * `ClientStateError`.
843
+ */
844
+ static resumeDelegated(saved_state: string): Promise<GrantAuthFlow>;
845
+ /**
846
+ * Save sensitive state required to resume this delegated pending grant flow.
847
+ *
848
+ * This does not export the delegated private key, but it includes the relay
849
+ * secret in the authorization URL. Store it only temporarily and delete it
850
+ * once the flow completes or is abandoned.
851
+ */
852
+ saveDelegated(): string;
853
+ /**
854
+ * Save sensitive state required to resume this pending local grant flow.
708
855
  *
709
856
  * @returns {string} Opaque state for `GrantAuthFlow.resume()` or
710
857
  * `pubky.resumeGrantAuthFlow()`.
711
858
  */
712
- save(): string;
859
+ saveLocal(): string;
713
860
  /**
714
- * Start a grant-backed flow (standalone).
715
- * Prefer `pubky.startGrantAuthFlow()` to reuse a facade client.
861
+ * Start a grant-backed flow with a new DHT client.
862
+ * Prefer `pubky.startGrantAuthFlow()` to reuse a facade DHT client.
716
863
  *
717
864
  * @param {string} capabilities
718
865
  * Comma-separated capabilities, e.g. `"/pub/app/:rw,/priv/foo.txt:r"`.
@@ -722,13 +869,24 @@ export class GrantAuthFlow {
722
869
  * The kind of authentication flow to perform.
723
870
  *
724
871
  * @param {GrantAuthFlowOptions} options
725
- * Options for the grant flow: `{ clientId, relay? }`.
872
+ * Options for the grant flow: `{ clientId, relay?, xCallback? }`.
726
873
  *
727
874
  * @returns {GrantAuthFlow}
728
875
  * A running grant auth flow. Call `authorizationUrl()` to show the deep link,
729
876
  * then `awaitApproval()` to receive a grant-backed `Session`.
730
877
  */
731
878
  static start(capabilities: Capabilities, kind: AuthFlowKind, options: GrantAuthFlowOptions): GrantAuthFlow;
879
+ /**
880
+ * Start a browser delegated grant-backed flow.
881
+ *
882
+ * The SDK creates a fresh non-extractable WebCrypto Ed25519 key in
883
+ * IndexedDB and uses that key for grant Proof-of-Possession signing.
884
+ *
885
+ * Runtime: delegated grant keys require a secure browser context with
886
+ * WebCrypto `crypto.subtle` and IndexedDB. Unsupported runtimes reject
887
+ * with `ClientStateError`.
888
+ */
889
+ static startDelegated(capabilities: Capabilities, kind: AuthFlowKind, options: GrantAuthFlowOptions): Promise<GrantAuthFlow>;
732
890
  /**
733
891
  * Non-blocking single poll step (advanced UIs).
734
892
  *
@@ -739,6 +897,14 @@ export class GrantAuthFlow {
739
897
  * Return the authorization deep link (URL) to show as QR or open on the signer device.
740
898
  */
741
899
  readonly authorizationUrl: string;
900
+ /**
901
+ * Whether delegated grant auth is available in the current JS runtime.
902
+ *
903
+ * This checks for a secure browser context with WebCrypto `crypto.subtle`
904
+ * and IndexedDB. It is a coarse synchronous feature-detection helper only;
905
+ * some runtimes expose those primitives without Ed25519 support.
906
+ */
907
+ static readonly isDelegationAvailable: boolean;
742
908
  }
743
909
 
744
910
  /**
@@ -815,14 +981,14 @@ export class GrantSession {
815
981
  free(): void;
816
982
  [Symbol.dispose](): void;
817
983
  /**
818
- * Export the durable refresh material needed to restore this grant session.
984
+ * Export the portable local secret material needed to restore this grant session.
819
985
  *
820
986
  * Treat the returned string as bearer-equivalent secret material until the
821
987
  * grant expires or is revoked.
822
988
  *
823
989
  * @returns {Promise<string>}
824
990
  */
825
- exportSecret(): Promise<string>;
991
+ exportLocalSecret(): Promise<string>;
826
992
  /**
827
993
  * Current grant id (`jti`) backing this session.
828
994
  *
@@ -957,13 +1123,17 @@ export class Pkdns {
957
1123
  * Resolve the homeserver for **this** user (requires keypair).
958
1124
  *
959
1125
  * @returns {Promise<PublicKey|undefined>} Homeserver public key or `undefined` if not found.
1126
+ * @throws When no keypair is attached, Pkarr resolution fails, or a resolved `_pubky` target
1127
+ * is malformed.
960
1128
  */
961
1129
  getHomeserver(): Promise<PublicKey | undefined>;
962
1130
  /**
963
1131
  * Resolve the homeserver for a given public key (read-only).
964
1132
  *
965
1133
  * @param {PublicKey} user
966
- * @returns {Promise<PublicKey|undefined>} Homeserver public key or `undefined` if not found.
1134
+ * @returns {Promise<PublicKey|undefined>} Homeserver public key, or `undefined` when the
1135
+ * user has no resolvable homeserver record.
1136
+ * @throws When Pkarr resolution fails or a resolved `_pubky` target is malformed.
967
1137
  */
968
1138
  getHomeserverOf(pubky: PublicKey): Promise<PublicKey | undefined>;
969
1139
  /**
@@ -1048,7 +1218,9 @@ export class Pubky {
1048
1218
  * Uses an internal read-only Pkdns actor.
1049
1219
  *
1050
1220
  * @param {PublicKey} user
1051
- * @returns {Promise<PublicKey|undefined>} Homeserver public key or `undefined` if not found.
1221
+ * @returns {Promise<PublicKey|undefined>} Homeserver public key, or `undefined` when the
1222
+ * user has no resolvable homeserver record.
1223
+ * @throws When Pkarr resolution fails or a resolved `_pubky` target is malformed.
1052
1224
  */
1053
1225
  getHomeserverOf(user_public_key: PublicKey): Promise<PublicKey | undefined>;
1054
1226
  /**
@@ -1069,11 +1241,11 @@ export class Pubky {
1069
1241
  /**
1070
1242
  * Restore a session from a previously exported token or snapshot, using this instance's client.
1071
1243
  *
1072
- * Accepts grant secret tokens from `session.exportSecret()` and legacy cookie
1244
+ * Accepts grant secret tokens from `session.exportLocalSecret()` and legacy cookie
1073
1245
  * secret tokens. Also accepts legacy cookie metadata snapshots from `session.export()`.
1074
1246
  * Grant restore mints a fresh short-lived bearer.
1075
1247
  *
1076
- * @param {string} exported A string produced by `session.exportSecret()` or legacy `session.export()`.
1248
+ * @param {string} exported A string produced by `session.exportLocalSecret()` or legacy `session.export()`.
1077
1249
  * @returns {Promise<Session>}
1078
1250
  * A rehydrated session bound to this SDK's HTTP client.
1079
1251
  *
@@ -1084,11 +1256,17 @@ export class Pubky {
1084
1256
  /**
1085
1257
  * Resume a previously started **pubkyauth** flow from its saved `authorizationUrl`.
1086
1258
  *
1259
+ * If the user refreshes or navigates away mid-flow, WASM memory is lost and
1260
+ * the original `AuthFlow` object is gone. You can reconnect to the same relay
1261
+ * channel by saving the `authorizationUrl` beforehand and calling this method
1262
+ * after reload.
1263
+ *
1087
1264
  * The relay inbox retains messages for **~5 minutes**. Resume is only
1088
1265
  * viable within that window; afterwards start a fresh flow.
1089
1266
  *
1090
1267
  * **Security:** The URL contains the `client_secret` in plaintext.
1091
- * Delete it from storage as soon as the resumed flow completes.
1268
+ * Store it in `sessionStorage` (scoped to the tab), **not** `localStorage`,
1269
+ * and delete it as soon as the resumed flow completes or is abandoned.
1092
1270
  * See `startCookieAuthFlow()` docs for full storage guidance.
1093
1271
  *
1094
1272
  * @param {string} authorizationUrl The `pubkyauth://…` URL from a previous flow.
@@ -1096,15 +1274,41 @@ export class Pubky {
1096
1274
  * @throws {PubkyError}
1097
1275
  * - `{ name: "AuthenticationError" }` if the URL is invalid or not a signin/signup link
1098
1276
  * - `{ name: "RequestError" }` on network/relay failure
1277
+ *
1278
+ * @example
1279
+ * // 1) Before a potential refresh, persist the URL.
1280
+ * const flow = pubky.startCookieAuthFlow("/pub/my-cool-app/:rw", AuthFlowKind.signin());
1281
+ * sessionStorage.setItem("pubky-auth-url", flow.authorizationUrl);
1282
+ * renderQr(flow.authorizationUrl);
1283
+ *
1284
+ * // 2) After reload, resume from the saved URL.
1285
+ * const savedUrl = sessionStorage.getItem("pubky-auth-url");
1286
+ * if (savedUrl) {
1287
+ * try {
1288
+ * const resumed = pubky.resumeCookieAuthFlow(savedUrl);
1289
+ * const session = await resumed.awaitApproval();
1290
+ * } finally {
1291
+ * sessionStorage.removeItem("pubky-auth-url");
1292
+ * }
1293
+ * }
1099
1294
  */
1100
1295
  resumeCookieAuthFlow(authorization_url: string): AuthFlow;
1296
+ /**
1297
+ * Resume a previously saved pending delegated grant auth flow.
1298
+ *
1299
+ * Runtime: delegated grant keys require a secure browser context with
1300
+ * WebCrypto `crypto.subtle` and IndexedDB. The saved `keyId` must still
1301
+ * exist in IndexedDB for the same origin. Unsupported runtimes reject with
1302
+ * `ClientStateError`.
1303
+ */
1304
+ resumeDelegatedGrantAuthFlow(saved_state: string): Promise<GrantAuthFlow>;
1101
1305
  /**
1102
1306
  * Resume a previously saved pending grant auth flow.
1103
1307
  *
1104
1308
  * **Security:** `savedState` contains the relay secret and PoP client private key.
1105
1309
  * Delete it from storage as soon as the resumed flow completes.
1106
1310
  *
1107
- * @param {string} savedState A string produced by `grantFlow.save()`.
1311
+ * @param {string} savedState A string produced by `grantFlow.saveLocal()`.
1108
1312
  * @returns {GrantAuthFlow} A flow reconnected to the original relay channel.
1109
1313
  */
1110
1314
  resumeGrantAuthFlow(saved_state: string): GrantAuthFlow;
@@ -1139,6 +1343,7 @@ export class Pubky {
1139
1343
  * - `AuthFlowKind.signin()` - Sign in to an existing account.
1140
1344
  * - `AuthFlowKind.signup(homeserverPublicKey, signupToken)` - Sign up for a new account.
1141
1345
  * @param {string=} relay Optional HTTP relay base (e.g. `"https://…/inbox/"`).
1346
+ * @param {XCallbackParams=} xCallback Optional app return destinations.
1142
1347
  * @returns {AuthFlow}
1143
1348
  * A running auth flow. Show `authorizationUrl` as QR/deeplink,
1144
1349
  * then `awaitApproval()` to obtain a `Session`.
@@ -1152,7 +1357,7 @@ export class Pubky {
1152
1357
  * renderQr(flow.authorizationUrl);
1153
1358
  * const session = await flow.awaitApproval();
1154
1359
  */
1155
- startCookieAuthFlow(capabilities: Capabilities, kind: AuthFlowKind, relay?: string | null): AuthFlow;
1360
+ startCookieAuthFlow(capabilities: Capabilities, kind: AuthFlowKind, relay?: string | null, x_callback?: XCallbackParams | null): AuthFlow;
1156
1361
  /**
1157
1362
  * Start a grant-backed **pubkyauth** flow.
1158
1363
  *
@@ -1161,19 +1366,20 @@ export class Pubky {
1161
1366
  *
1162
1367
  * @param {string} capabilities Comma-separated caps, e.g. `"/pub/app/:rw,/pub/foo/file:r"`.
1163
1368
  * @param {AuthFlowKind} kind The kind of authentication flow to perform.
1164
- * @param {GrantAuthFlowOptions} options Options for the grant flow: `{ clientId, relay? }`.
1165
- * @returns {GrantAuthFlow}
1369
+ * @param {GrantAuthFlowOptions} options Options for the grant flow:
1370
+ * `{ clientId, relay?, xCallback? }`.
1371
+ * @returns {Promise<GrantAuthFlow>}
1166
1372
  * A running grant auth flow. Show `authorizationUrl` as QR/deeplink,
1167
1373
  * then `awaitApproval()` to obtain a grant-backed `Session`.
1168
1374
  *
1169
1375
  * @example
1170
- * const flow = pubky.startGrantAuthFlow(
1376
+ * const flow = await pubky.startGrantAuthFlow(
1171
1377
  * "/pub/my-cool-app/:rw",
1172
1378
  * AuthFlowKind.signin(),
1173
1379
  * { clientId: "my-cool-app.example" },
1174
1380
  * );
1175
1381
  */
1176
- startGrantAuthFlow(capabilities: Capabilities, kind: AuthFlowKind, options: GrantAuthFlowOptions): GrantAuthFlow;
1382
+ startGrantAuthFlow(capabilities: Capabilities, kind: AuthFlowKind, options: GrantAuthFlowOptions): Promise<GrantAuthFlow>;
1177
1383
  /**
1178
1384
  * Create a Pubky facade preconfigured for a **local testnet**.
1179
1385
  *
@@ -1199,6 +1405,14 @@ export class Pubky {
1199
1405
  * const pubky = Pubky.withClient(client);
1200
1406
  */
1201
1407
  static withClient(client: Client): Pubky;
1408
+ /**
1409
+ * Browser-backed store for explicitly persisted completed grant sessions.
1410
+ *
1411
+ * Use `browserSessionStore.save(session)` after a successful grant auth flow to make
1412
+ * the session restorable after reload. The store supports multiple accounts
1413
+ * and multiple grants per account.
1414
+ */
1415
+ readonly browserSessionStore: BrowserSessionStore;
1202
1416
  /**
1203
1417
  * Access the underlying HTTP client (advanced).
1204
1418
  *
@@ -1367,6 +1581,10 @@ export class SeedExportDeepLink {
1367
1581
  static parse(url: string): SeedExportDeepLink;
1368
1582
  toString(): string;
1369
1583
  readonly secret: Uint8Array;
1584
+ /**
1585
+ * Optional x-callback-url metadata carried by this deep link.
1586
+ */
1587
+ readonly xCallback: XCallbackParams;
1370
1588
  }
1371
1589
 
1372
1590
  /**
@@ -1387,15 +1605,16 @@ export class Session {
1387
1605
  * @returns {string}
1388
1606
  * A base64 string to store (e.g. in `localStorage`).
1389
1607
  *
1390
- * @deprecated Prefer `exportSecret()` for grant sessions.
1608
+ * @deprecated Prefer `exportLocalSecret()` for grant sessions.
1391
1609
  */
1392
1610
  export(): string;
1393
1611
  /**
1394
- * Export the secret material needed to restore this session.
1612
+ * Export the local secret material needed to restore this session.
1395
1613
  *
1396
- * For grant sessions this exports the grant JWS and PoP client secret; restoring
1397
- * mints a fresh bearer. For legacy cookie sessions this exports the cookie secret
1398
- * when the SDK owns it.
1614
+ * For local grant sessions this exports the grant JWS and PoP client secret;
1615
+ * restoring mints a fresh bearer. For legacy cookie sessions this exports the
1616
+ * cookie secret when the SDK owns it. Delegated browser grant sessions cannot
1617
+ * export raw secret material; use `BrowserSessionStore`.
1399
1618
  *
1400
1619
  * Treat the returned string as a bearer-equivalent secret until the grant or
1401
1620
  * cookie session expires or is revoked.
@@ -1403,7 +1622,7 @@ export class Session {
1403
1622
  * @returns {Promise<string>}
1404
1623
  * A secret token that can be passed to `pubky.restoreSession()`.
1405
1624
  */
1406
- exportSecret(): Promise<string>;
1625
+ exportLocalSecret(): Promise<string>;
1407
1626
  /**
1408
1627
  * Restore a session from an `export()` string.
1409
1628
  *
@@ -1599,6 +1818,13 @@ export class Signer {
1599
1818
  * @returns {Signer}
1600
1819
  */
1601
1820
  static fromKeypair(keypair: Keypair): Signer;
1821
+ /**
1822
+ * Handle a `pubkyauth://` deep link.
1823
+ *
1824
+ * Auth requests are approved through their relay. A `direct_signup` link
1825
+ * creates an account on its target homeserver.
1826
+ */
1827
+ handleDeepLink(pubkyauth_url: string): Promise<void>;
1602
1828
  /**
1603
1829
  * Fast sign-in for a returning user. Publishes PKDNS in the background.
1604
1830
  *
@@ -1679,6 +1905,10 @@ export class SigninDeepLink {
1679
1905
  readonly baseRelayUrl: string;
1680
1906
  readonly capabilities: string;
1681
1907
  readonly secret: Uint8Array;
1908
+ /**
1909
+ * Optional x-callback-url metadata carried by this deep link.
1910
+ */
1911
+ readonly xCallback: XCallbackParams;
1682
1912
  }
1683
1913
 
1684
1914
  /**
@@ -1737,6 +1967,10 @@ export class SigninGrantDeepLink {
1737
1967
  * @returns {Uint8Array}
1738
1968
  */
1739
1969
  readonly secret: Uint8Array;
1970
+ /**
1971
+ * Optional x-callback-url metadata carried by this deep link.
1972
+ */
1973
+ readonly xCallback: XCallbackParams;
1740
1974
  }
1741
1975
 
1742
1976
  export class SignupDeepLink {
@@ -1750,6 +1984,10 @@ export class SignupDeepLink {
1750
1984
  readonly homeserver: PublicKey;
1751
1985
  readonly secret: Uint8Array;
1752
1986
  readonly signupToken: string | undefined;
1987
+ /**
1988
+ * Optional x-callback-url metadata carried by this deep link.
1989
+ */
1990
+ readonly xCallback: XCallbackParams;
1753
1991
  }
1754
1992
 
1755
1993
  /**
@@ -1820,6 +2058,55 @@ export class SignupGrantDeepLink {
1820
2058
  * @returns {string|undefined}
1821
2059
  */
1822
2060
  readonly signupToken: string | undefined;
2061
+ /**
2062
+ * Optional x-callback-url metadata carried by this deep link.
2063
+ */
2064
+ readonly xCallback: XCallbackParams;
2065
+ }
2066
+
2067
+ /**
2068
+ * Metadata for a session saved in the browser session store.
2069
+ */
2070
+ export class StoredSessionInfo {
2071
+ private constructor();
2072
+ free(): void;
2073
+ [Symbol.dispose](): void;
2074
+ /**
2075
+ * Authorized capabilities.
2076
+ */
2077
+ readonly capabilities: string[];
2078
+ /**
2079
+ * Application/client identifier.
2080
+ */
2081
+ readonly clientId: string;
2082
+ /**
2083
+ * Local save timestamp, in Unix milliseconds.
2084
+ */
2085
+ readonly createdAt: number;
2086
+ /**
2087
+ * Underlying grant expiry timestamp, in Unix seconds.
2088
+ */
2089
+ readonly grantExpiresAt: number;
2090
+ /**
2091
+ * Grant identifier backing this stored session.
2092
+ */
2093
+ readonly grantId: string;
2094
+ /**
2095
+ * Homeserver public key as z32.
2096
+ */
2097
+ readonly homeserver: string;
2098
+ /**
2099
+ * Stable local identifier for this stored session.
2100
+ */
2101
+ readonly id: string;
2102
+ /**
2103
+ * User public key as z32.
2104
+ */
2105
+ readonly publicKey: string;
2106
+ /**
2107
+ * `delegated` for origin-bound WebCrypto sessions, `localSecret` for raw local PoP secret storage.
2108
+ */
2109
+ readonly storageMode: string;
1823
2110
  }
1824
2111
 
1825
2112
  /**
@@ -1857,11 +2144,11 @@ export function setLogLevel(level: Level): void;
1857
2144
  * Validate and normalize a capabilities string.
1858
2145
  *
1859
2146
  * - Normalizes action order (`wr` -> `rw`)
1860
- * - Throws `InvalidInput` listing malformed entries.
2147
+ * - Throws `InvalidInput` identifying the first malformed entry.
1861
2148
  *
1862
2149
  * @param {string} input
1863
2150
  * @returns {string} Normalized string (same shape as input).
1864
2151
  * @throws {PubkyError} `{ name: "InvalidInput" }` with a helpful message.
1865
- * The error's `data` field is `{ invalidEntries: string[] }` listing malformed tokens.
2152
+ * The error's `data` field is `{ invalidEntries: string[] }` containing the malformed token.
1866
2153
  */
1867
2154
  export function validateCapabilities(input: string): string;
package/pubky_bg.wasm CHANGED
Binary file