@synonymdev/pubky 0.5.4 → 0.6.0-rc.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.
Files changed (6) hide show
  1. package/README.md +193 -159
  2. package/index.cjs +1565 -385
  3. package/index.js +1672 -461
  4. package/package.json +3 -2
  5. package/pubky.d.ts +706 -82
  6. package/pubky_bg.wasm +0 -0
package/pubky.d.ts CHANGED
@@ -1,16 +1,77 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
3
  /**
4
- * Create a recovery file of the `keypair`, containing the secret key encrypted
5
- * using the `passphrase`.
4
+ * Set the global logging verbosity for the WASM Pubky SDK. Routes Rust `log` output to the browser console.
5
+ *
6
+ * Accepted values (case-insensitive): "error" | "warn" | "info" | "debug" | "trace".
7
+ * Effects:
8
+ * - Initializes the logger once; subsequent calls may throw if the logger is already set.
9
+ * - Emits a single info log: `Log level set to: <level>`.
10
+ * - Messages at or above `level` are forwarded to the appropriate `console.*` method.
11
+ *
12
+ * @param {string} level
13
+ * Minimum log level to enable. One of: "error" | "warn" | "info" | "debug" | "trace".
14
+ *
15
+ * @returns {void}
16
+ *
17
+ * @throws {Error}
18
+ * If `level` is invalid ("Invalid log level") or the logger cannot be initialized
19
+ * (e.g., already initialized).
20
+ *
21
+ * Usage:
22
+ * Call once at application startup, before invoking other SDK APIs.
6
23
  */
7
- export function createRecoveryFile(keypair: Keypair, passphrase: string): Uint8Array;
24
+ export function setLogLevel(level: string): void;
8
25
  /**
9
- * Create a recovery file of the `keypair`, containing the secret key encrypted
10
- * using the `passphrase`.
26
+ * Validate and normalize a capabilities string.
27
+ *
28
+ * - Normalizes action order (`wr` -> `rw`)
29
+ * - Throws `InvalidInput` listing malformed entries.
30
+ *
31
+ * @param {string} input
32
+ * @returns {string} Normalized string (same shape as input).
33
+ * @throws {PubkyJsError} `{ name: "InvalidInput" }` with a helpful message.
11
34
  */
12
- export function decryptRecoveryFile(recovery_file: Uint8Array, passphrase: string): Keypair;
13
- export function setLogLevel(level: string): void;
35
+ export function validateCapabilities(input: string): string;
36
+ /**
37
+ * A union type of all possible machine-readable codes for the `name` property
38
+ * of a {@link PubkyJsError}.
39
+ *
40
+ * Provides a simplified, actionable set of error categories for developers
41
+ * to handle in their code.
42
+ */
43
+ export type PubkyErrorName = "RequestError" | "InvalidInput" | "AuthenticationError" | "PkarrError" | "ClientStateError" | "InternalError";
44
+
45
+ /**
46
+ * Represents the standard error structure for all exceptions thrown by the Pubky
47
+ * WASM client.
48
+ *
49
+ * @property name - A machine-readable error code from {@link PubkyErrorName}. Use this for programmatic error handling.
50
+ * @property message - A human-readable, descriptive error message suitable for logging.
51
+ * @property data - An optional payload containing structured context for an error. For a `RequestError`, this may contain an object with the HTTP status code, e.g., `{ statusCode: 404 }`.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * try {
56
+ * await client.signup(...);
57
+ * } catch (e) {
58
+ * const error = e as PubkyJsError;
59
+ * if (error.name === \'RequestError\' && error.statusCode === 404) {
60
+ * // Handle not found...
61
+ * }
62
+ * }
63
+ * ```
64
+ */
65
+ export interface PubkyJsError {
66
+ name: PubkyErrorName;
67
+ message: string;
68
+ /**
69
+ * For `RequestError::Server`, this carries the numeric HTTP status code (e.g. 404).
70
+ * Otherwise `undefined` on the JS side.
71
+ */
72
+ statusCode?: number;
73
+ }
74
+
14
75
  /**
15
76
  * Pkarr Config
16
77
  */
@@ -23,7 +84,7 @@ export interface PkarrConfig {
23
84
  * The timeout for DHT requests in milliseconds.
24
85
  * Default is 2000ms.
25
86
  */
26
- requestTimeout?: NonZeroU64;
87
+ requestTimeout?: number;
27
88
  }
28
89
 
29
90
  /**
@@ -34,113 +95,273 @@ export interface PubkyClientConfig {
34
95
  * Configuration on how to access pkarr packets on the mainline DHT.
35
96
  */
36
97
  pkarr?: PkarrConfig;
98
+ }
99
+
100
+ /**
101
+ * Resource metadata returned by `SessionStorage.stats()` and `PublicStorage.stats()`.
102
+ *
103
+ * @typedef {Object} ResourceStats
104
+ * @property {number=} contentLength Size in bytes.
105
+ * @property {string=} contentType Media type (e.g. \"application/json; charset=utf-8\").
106
+ * @property {number=} lastModifiedMs Unix epoch milliseconds.
107
+ * @property {string=} etag Opaque server ETag for the current version.
108
+ *
109
+ * @example
110
+ * const stats = await pubky.publicStorage().stats(`${user}/pub/app/file.json`);
111
+ * if (stats) {
112
+ * console.log(stats.contentLength, stats.contentType, stats.lastModifiedMs);
113
+ * }
114
+ *
115
+ * Notes:
116
+ * - `contentLength` equals `getBytes(...).length`.
117
+ * - `etag` may be absent and is opaque; compare values to detect updates.
118
+ * - `lastModifiedMs` increases when the resource is updated.
119
+ */
120
+ export interface ResourceStats {
37
121
  /**
38
- * The maximum age of a record in seconds.
39
- * If the user pkarr record is older than this, it will be automatically refreshed.
122
+ * Size in bytes of the stored object.
40
123
  */
41
- userMaxRecordAge?: NonZeroU64;
124
+ contentLength?: number;
125
+ /**
126
+ * Media type of the stored object (e.g., `\"application/json\"`).
127
+ */
128
+ contentType?: string;
129
+ /**
130
+ * Unix epoch **milliseconds** for the last modification time.
131
+ */
132
+ lastModifiedMs?: number;
133
+ /**
134
+ * Opaque entity tag identifying the current stored version.
135
+ */
136
+ etag?: string;
42
137
  }
43
138
 
44
- export class AuthRequest {
139
+ /**
140
+ * Start and control a pubkyauth authorization flow.
141
+ *
142
+ * Typical flow:
143
+ * 1) `AuthFlow.start(...)` or `pubky.startAuthFlow(...)`
144
+ * 2) Show `authorizationUrl()` as QR/deeplink to the user’s signing device
145
+ * 3) `awaitApproval()` to receive a ready `Session`
146
+ */
147
+ export class AuthFlow {
45
148
  private constructor();
46
149
  free(): void;
47
150
  /**
48
- * Returns the Pubky Auth url, which you should show to the user
49
- * to request an authentication or authorization token.
151
+ * Start a flow (standalone).
152
+ * Prefer `pubky.startAuthFlow()` to reuse a façade client.
50
153
  *
51
- * Wait for this token using `this.response()`.
52
- */
53
- url(): string;
54
- /**
55
- * Wait for the user to send an authentication or authorization proof.
154
+ * @param {string} capabilities
155
+ * Comma-separated capabilities, e.g. `"/pub/app/:rw,/priv/foo.txt:r"`.
156
+ * Each entry must be `"<scope>:<actions>"`, where:
157
+ * - `scope` starts with `/` (e.g. `/pub/example.app/`)
158
+ * - `actions` is any combo of `r` and/or `w` (order is normalized; `wr` -> `rw`)
159
+ * Empty string is allowed (no scopes).
56
160
  *
57
- * If successful, you should expect an instance of [PublicKey]
161
+ * @param {string} [relay]
162
+ * Optional HTTP relay base, e.g. `"https://demo.httprelay.io/link/"`.
163
+ * Defaults to the default Synonym-hosted relay when omitted.
58
164
  *
59
- * Otherwise it will throw an error.
165
+ * @returns {AuthFlow}
166
+ * A running auth flow. Call `authorizationUrl()` to show the deep link,
167
+ * then `awaitApproval()` to receive a `Session`.
168
+ * @throws {PubkyJsError}
169
+ * - `{ name: "InvalidInput", message: string }` if any capability entry is invalid
170
+ * or for an invalid relay URL.
171
+ * @example
172
+ * const flow = AuthFlow.start("/pub/my.app/:rw,/pub/pubky.app/:w");
173
+ * renderQRCode(flow.authorizationUrl());
174
+ * const session = await flow.awaitApproval();
60
175
  */
61
- response(): Promise<PublicKey>;
62
- }
63
- export class Client {
64
- free(): void;
176
+ static start(capabilities: string, relay?: string | null): AuthFlow;
65
177
  /**
66
- * Signup to a homeserver and update Pkarr accordingly.
178
+ * Return the authorization deep link (URL) to show as QR or open on the signer device.
67
179
  *
68
- * The homeserver is a Pkarr domain name, where the TLD is a Pkarr public key
69
- * for example "pubky.o4dksfbqk85ogzdb5osziw6befigbuxmuxkuxq8434q89uj56uyy"
180
+ * @returns {string} A `pubkyauth://…` or `https://…` URL with channel info.
181
+ *
182
+ * @example
183
+ * renderQr(flow.authorizationUrl());
70
184
  */
71
- signup(keypair: Keypair, homeserver: PublicKey, signup_token?: string | null): Promise<Session>;
185
+ authorizationUrl(): string;
72
186
  /**
73
- * Check the current session for a given Pubky in its homeserver.
187
+ * Block until the user approves on their signer device; returns a `Session`.
188
+ *
189
+ * @returns {Promise<Session>}
190
+ * Resolves when approved; rejects on timeout/cancel/network errors.
74
191
  *
75
- * Returns [Session] or `None` (if received `404 NOT_FOUND`),
76
- * or throws the received error if the response has any other `>=400` status code.
192
+ * @throws {PubkyJsError}
193
+ * - `RequestError` if relay/network fails
194
+ * - `AuthenticationError` if approval is denied/invalid
77
195
  */
78
- session(pubky: PublicKey): Promise<Session | undefined>;
196
+ awaitApproval(): Promise<Session>;
79
197
  /**
80
- * Signout from a homeserver.
198
+ * Block until the user approves on their signer device; returns an `AuthToken`.
199
+ *
200
+ * @returns {Promise<AuthToken>}
201
+ * Resolves when approved; rejects on timeout/cancel/network errors.
202
+ *
203
+ * @throws {PubkyJsError}
204
+ * - `RequestError` if relay/network fails
81
205
  */
82
- signout(pubky: PublicKey): Promise<void>;
206
+ awaitToken(): Promise<AuthToken>;
83
207
  /**
84
- * Signin to a homeserver using the root Keypair.
208
+ * Non-blocking single poll step (advanced UIs).
209
+ *
210
+ * @returns {Promise<Session|null>} A session if the approval arrived, otherwise `null`.
85
211
  */
86
- signin(keypair: Keypair): Promise<void>;
212
+ tryPollOnce(): Promise<Session | undefined>;
213
+ }
214
+ /**
215
+ * AuthToken: signed, time-bound proof of key ownership.
216
+ *
217
+ * Returned by [`AuthFlow.awaitToken()`] on the 3rd-party app side when doing **authentication-only**
218
+ * flows (no homeserver session). You can inspect who authenticated and which capabilities were
219
+ * requested, or serialize the token and send it to a backend to verify.
220
+ *
221
+ * ### Typical usage
222
+ * ```js
223
+ * // Start an auth-only flow (no capabilities)
224
+ * const flow = pubky.startAuthFlow("", relay);
225
+ *
226
+ * // Wait for the signer to approve; returns an AuthToken
227
+ * const token = await flow.awaitToken();
228
+ *
229
+ * // Identify the user
230
+ * console.log(token.publicKey().z32());
231
+ *
232
+ * // Optionally forward to a server for verification:
233
+ * await fetch("/api/verify", { method: "POST", body: token.toBytes() });
234
+ * ```
235
+ *
236
+ * ### Binary format
237
+ * `AuthToken` serializes to a canonical binary (postcard) form; use [`AuthToken.toBytes()`] to get a
238
+ * `Uint8Array`, and [`AuthToken.verify()`] to parse + verify on the server.
239
+ */
240
+ export class AuthToken {
241
+ private constructor();
242
+ free(): void;
87
243
  /**
88
- * Return `pubkyauth://` url and wait for the incoming [AuthToken]
89
- * verifying that AuthToken, and if capabilities were requested, signing in to
90
- * the Pubky's homeserver and returning the [Session] information.
244
+ * Parse and verify an `AuthToken` from its canonical bytes.
245
+ *
246
+ * - Verifies version, timestamp freshness window, and signature.
247
+ * - Throws on invalid/expired/unknown version.
91
248
  *
92
- * Returns a [AuthRequest]
249
+ * Use this on your server after receiving `Uint8Array` from the client.
250
+ *
251
+ * ```js
252
+ * import { AuthToken } from "@synonymdev/pubky";
253
+ *
254
+ * export async function POST(req) {
255
+ * const bytes = new Uint8Array(await req.arrayBuffer());
256
+ * const token = AuthToken.verify(bytes); // throws on failure
257
+ * return new Response(token.publicKey().z32(), { status: 200 });
258
+ * }
259
+ * ```
93
260
  */
94
- authRequest(relay: string, capabilities: string): AuthRequest;
261
+ static verify(bytes: Uint8Array): AuthToken;
95
262
  /**
96
- * Sign an [pubky_common::auth::AuthToken], encrypt it and send it to the
97
- * source of the pubkyauth request url.
263
+ * Deserialize an `AuthToken` **without** verification.
264
+ *
265
+ * Most apps should call [`AuthToken.verify()`]. This is provided for tooling or diagnostics
266
+ * where you want to inspect the structure first.
267
+ *
268
+ * Throws if the bytes cannot be parsed as a valid serialized token.
98
269
  */
99
- sendAuthToken(keypair: Keypair, pubkyauth_url: string): Promise<void>;
270
+ static fromBytes(bytes: Uint8Array): AuthToken;
100
271
  /**
101
- * Get the homeserver id for a given Pubky public key.
102
- * Looks up the pkarr packet for the given public key and returns the content of the first `_pubky` SVCB record.
103
- * Throws an error if no homeserver is found.
272
+ * Returns the **public key** that authenticated with this token.
273
+ *
274
+ * Use `.z32()` on the returned `PublicKey` to get the string form.
275
+ *
276
+ * ```js
277
+ * const who = token.publicKey().z32();
278
+ * ```
104
279
  */
105
- getHomeserver(public_key: PublicKey): Promise<PublicKey>;
280
+ publicKey(): PublicKey;
106
281
  /**
107
- * Republish the user's PKarr record pointing to their homeserver.
282
+ * Returns the **capabilities** requested by the flow at the time this token was signed.
283
+ *
284
+ * Most auth-only flows pass an empty string to `startAuthFlow("", relay)`, so this will
285
+ * commonly be an empty array.
108
286
  *
109
- * This method will republish the record if no record exists or if the existing record
110
- * is older than 6 hours.
287
+ * Returns: `string[]`, where each item is the canonical entry `"<scope>:<actions>"`.
111
288
  *
112
- * The method is intended for clients and key managers (e.g., pubky-ring) to
113
- * keep the records of active users fresh and available in the DHT and relays.
114
- * It is intended to be used only after failed signin due to homeserver resolution
115
- * failure. This method is lighter than performing a re-signup into the last known
116
- * homeserver, but does not return a session token, so a signin must be done after
117
- * republishing. On a failed signin due to homeserver resolution failure, a key
118
- * manager should always attempt to republish the last known homeserver.
289
+ * Example entry: `"/pub/my.app/:rw"`
119
290
  */
120
- republishHomeserver(keypair: Keypair, host: PublicKey): Promise<void>;
291
+ capabilities(): Array<any>;
121
292
  /**
122
- * Returns a list of Pubky urls (as strings).
293
+ * Serialize the token to a `Uint8Array` in its **canonical** (postcard) binary format.
123
294
  *
124
- * - `url`: The Pubky url (string) to the directory you want to list its content.
125
- * - `cursor`: Either a full `pubky://` Url (from previous list response),
126
- * or a path (to a file or directory) relative to the `url`
127
- * - `reverse`: List in reverse order
128
- * - `limit` Limit the number of urls in the response
129
- * - `shallow`: List directories and files, instead of flat list of files.
295
+ * Use this to send the token to a backend for verification.
296
+ *
297
+ * ```js
298
+ * const bytes = token.toBytes();
299
+ * await fetch("/api/verify", { method: "POST", body: bytes });
300
+ * ```
130
301
  */
131
- list(url: string, cursor?: string | null, reverse?: boolean | null, limit?: number | null, shallow?: boolean | null): Promise<Array<any>>;
132
- fetch(url: string, init?: any | null): Promise<Promise<any>>;
302
+ toBytes(): Uint8Array;
303
+ }
304
+ /**
305
+ * Low-level HTTP bridge used by the Pubky façade and actors.
306
+ *
307
+ * - Supports `pubky://<user-z32>/<abs-path>` and `http(s)://` URLs.
308
+ * - In browsers/undici, passes `credentials: "include"` to send cookies.
309
+ */
310
+ export class Client {
311
+ free(): void;
133
312
  /**
134
- * Create a new Pubky Client with an optional configuration.
313
+ * Create a Pubky HTTP client.
314
+ *
315
+ * @param {PubkyClientConfig} [config]
316
+ * Optional transport overrides:
317
+ * `{ pkarr?: { relays?: string[], request_timeout?: number } }`.
318
+ *
319
+ * @returns {Client}
320
+ * A configured low-level client. Prefer `new Pubky().client()` unless you
321
+ * need custom relays/timeouts.
322
+ *
323
+ * @throws {InvalidInput}
324
+ * If any PKARR relay URL is invalid.
325
+ *
326
+ * @example
327
+ * const client = new Client({
328
+ * pkarr: { relays: ["https://relay1/","https://relay2/"], request_timeout: 8000 }
329
+ * });
330
+ * const pubky = Pubky.withClient(client);
135
331
  */
136
332
  constructor(config_opt?: PubkyClientConfig | null);
137
333
  /**
138
- * Create a client with with configurations appropriate for local testing:
139
- * - set Pkarr relays to `http://<host>:15411` (defaults to `localhost`).
140
- * - transform `pubky://<pkarr public key>` to `http://<host>` instead of `https:`
141
- * and read the homeserver HTTP port from the PKarr record.
334
+ * Create a client wired for **local testnet**.
335
+ *
336
+ * Sets PKARR relays to `http://<host>:15411/` and enables WASM `pubky://`
337
+ * mapping for that host.
338
+ *
339
+ * @param {string} [host="localhost"]
340
+ * Testnet hostname or IP.
341
+ *
342
+ * @returns {Client}
343
+ * A client ready to talk to your local testnet.
344
+ *
345
+ * @example
346
+ * const client = Client.testnet(); // localhost
347
+ * const pubky = Pubky.withClient(client);
348
+ *
349
+ * @example
350
+ * const client = Client.testnet("docker0"); // custom host
142
351
  */
143
352
  static testnet(host?: string | null): Client;
353
+ /**
354
+ * Perform a raw fetch. Works with `pubky://` or `http(s)://` URLs.
355
+ *
356
+ * @param {string} url
357
+ * @param {RequestInit=} init Standard fetch options; `credentials: "include"` recommended for session I/O.
358
+ * @returns {Promise<Response>}
359
+ *
360
+ * @example
361
+ * const client = pubky.client();
362
+ * const res = await client.fetch(`pubky://${user}/pub/app/file.txt`, { method: "PUT", body: "hi", credentials: "include" });
363
+ */
364
+ fetch(url: string, init?: any | null): Promise<Promise<any>>;
144
365
  }
145
366
  export class Keypair {
146
367
  private constructor();
@@ -161,15 +382,175 @@ export class Keypair {
161
382
  * Returns the [PublicKey] of this keypair.
162
383
  */
163
384
  publicKey(): PublicKey;
385
+ /**
386
+ * Create a recovery file for this keypair (encrypted with the given passphrase).
387
+ */
388
+ createRecoveryFile(passphrase: string): Uint8Array;
389
+ /**
390
+ * Decrypt a recovery file and return a Keypair (decrypted with the given passphrase).
391
+ */
392
+ static fromRecoveryFile(recovery_file: Uint8Array, passphrase: string): Keypair;
164
393
  }
165
- export class PublicKey {
166
- private constructor();
394
+ /**
395
+ * Resolve/publish `_pubky` PKDNS records (homeserver pointers).
396
+ */
397
+ export class Pkdns {
167
398
  free(): void;
168
399
  /**
169
- * Convert the PublicKey to Uint8Array
170
- * @deprecated Use `toUint8Array` instead
400
+ * Read-only PKDNS actor (no keypair; resolve only).
401
+ */
402
+ constructor();
403
+ /**
404
+ * PKDNS actor with publishing enabled (requires a keypair).
405
+ */
406
+ static fromKeypair(keypair: Keypair): Pkdns;
407
+ /**
408
+ * Resolve the homeserver for a given public key (read-only).
409
+ *
410
+ * @param {PublicKey} user
411
+ * @returns {Promise<string|undefined>} Homeserver public key (z32) or `undefined` if not found.
412
+ */
413
+ getHomeserverOf(pubky: PublicKey): Promise<string | undefined>;
414
+ /**
415
+ * Resolve the homeserver for **this** user (requires keypair).
416
+ *
417
+ * @returns {Promise<string|undefined>} Homeserver public key (z32) or `undefined` if not found.
418
+ */
419
+ getHomeserver(): Promise<string | undefined>;
420
+ /**
421
+ * Republish homeserver if record is missing/stale.
422
+ *
423
+ * Requires keypair or to be signer bound.
424
+ *
425
+ * @param {PublicKey=} overrideHost Optional new homeserver to publish (migration).
426
+ * @returns {Promise<void>}
427
+ */
428
+ publishHomeserverForce(host_override?: PublicKey | null): Promise<void>;
429
+ /**
430
+ * Force publish homeserver immediately (even if fresh).
431
+ *
432
+ * Requires keypair or to be signer bound.
433
+ *
434
+ * @param {PublicKey=} overrideHost Optional new homeserver to publish (migration).
435
+ * @returns {Promise<void>}
436
+ */
437
+ publishHomeserverIfStale(host_override?: PublicKey | null): Promise<void>;
438
+ }
439
+ /**
440
+ * High-level entrypoint to the Pubky SDK.
441
+ */
442
+ export class Pubky {
443
+ free(): void;
444
+ /**
445
+ * Create a Pubky façade wired for **mainnet** defaults (public relays).
446
+ *
447
+ * @returns {Pubky}
448
+ * A new façade instance. Use this to create signers, start auth flows, etc.
449
+ *
450
+ * @example
451
+ * const pubky = new Pubky();
452
+ * const signer = pubky.signer(Keypair.random());
453
+ */
454
+ constructor();
455
+ /**
456
+ * Create a Pubky façade preconfigured for a **local testnet**.
457
+ *
458
+ * If `host` is provided, PKARR and HTTP endpoints are derived as `http://<host>:ports/...`.
459
+ * If omitted, `"localhost"` is assumed (handy for `cargo install pubky-testnet`).
460
+ *
461
+ * @param {string=} host Optional host (e.g. `"localhost"`, `"docker-host"`, `"127.0.0.1"`).
462
+ * @returns {Pubky}
463
+ *
464
+ * @example
465
+ * const pubky = Pubky.testnet(); // localhost default
466
+ * const pubky = Pubky.testnet("docker-host"); // custom hostname/IP
467
+ */
468
+ static testnet(host?: string | null): Pubky;
469
+ /**
470
+ * Wrap an existing configured HTTP client into a Pubky façade.
471
+ *
472
+ * @param {Client} client A previously constructed client.
473
+ * @returns {Pubky}
474
+ *
475
+ * @example
476
+ * const client = Client.testnet();
477
+ * const pubky = Pubky.withClient(client);
478
+ */
479
+ static withClient(client: Client): Pubky;
480
+ /**
481
+ * Start a **pubkyauth** flow.
482
+ *
483
+ * Provide a **capabilities string** and (optionally) a relay base URL.
484
+ * The capabilities string is a comma-separated list of entries:
485
+ * `"<scope>:<actions>"`, where:
486
+ * - `scope` starts with `/` (e.g. `/pub/example.app/`).
487
+ * - `actions` is any combo of `r` and/or `w` (order normalized; `wr` -> `rw`).
488
+ * Pass `""` for no scopes (read-only public session).
489
+ *
490
+ * @param {string} capabilities Comma-separated caps, e.g. `"/pub/app/:rw,/pub/foo/file:r"`.
491
+ * @param {string=} relay Optional HTTP relay base (e.g. `"https://…/link/"`).
492
+ * @returns {AuthFlow}
493
+ * A running auth flow. Call `authorizationUrl()` to show a QR/deeplink,
494
+ * then `awaitApproval()` to obtain a `Session`.
495
+ *
496
+ * @throws {PubkyJsError}
497
+ * - `{ name: "InvalidInput" }` for malformed capabilities or bad relay URL
498
+ * - `{ name: "RequestError" }` if the flow cannot be started (network/relay)
499
+ *
500
+ * @example
501
+ * const flow = pubky.startAuthFlow("/pub/my.app/:rw");
502
+ * renderQr(flow.authorizationUrl());
503
+ * const session = await flow.awaitApproval();
504
+ */
505
+ startAuthFlow(capabilities: string, relay?: string | null): AuthFlow;
506
+ /**
507
+ * Create a `Signer` from an existing `Keypair`.
508
+ *
509
+ * @param {Keypair} keypair The user’s keys.
510
+ * @returns {Signer}
511
+ *
512
+ * @example
513
+ * const signer = pubky.signer(Keypair.random());
514
+ * const session = await signer.signup(homeserverPk, null);
515
+ */
516
+ signer(keypair: Keypair): Signer;
517
+ /**
518
+ * Public, unauthenticated storage API.
519
+ *
520
+ * Use for **read-only** public access via addressed paths:
521
+ * `"<user-z32>/pub/…"`.
522
+ *
523
+ * @returns {PublicStorage}
524
+ *
525
+ * @example
526
+ * const pub = pubky.publicStorage();
527
+ * const text = await pub.getText(`${userPk.z32()}/pub/example.com/hello.txt`);
528
+ */
529
+ publicStorage(): PublicStorage;
530
+ /**
531
+ * Read-only PKDNS (Pkarr) resolver.
532
+ *
533
+ * @returns {Pkdns}
534
+ *
535
+ * @example
536
+ * const dns = pubky.pkdns();
537
+ * const homeserver = await dns.getHomeserverOf(userPk);
538
+ */
539
+ pkdns(): Pkdns;
540
+ /**
541
+ * Access the underlying HTTP client (advanced).
542
+ *
543
+ * @returns {Client}
544
+ * Use this for low-level `fetch()` calls or testing with raw URLs.
545
+ *
546
+ * @example
547
+ * const r = await pubky.client().fetch(`pubky://${user}/pub/app/file.txt`, { credentials: "include" });
171
548
  */
172
- to_uint8array(): Uint8Array;
549
+ client(): Client;
550
+ }
551
+ export class PublicKey {
552
+ private constructor();
553
+ free(): void;
173
554
  /**
174
555
  * Convert the PublicKey to Uint8Array
175
556
  */
@@ -183,15 +564,258 @@ export class PublicKey {
183
564
  */
184
565
  static from(value: string): PublicKey;
185
566
  }
567
+ /**
568
+ * Read-only public storage using addressed paths (`"<user-z32>/pub/...")`.
569
+ */
570
+ export class PublicStorage {
571
+ free(): void;
572
+ /**
573
+ * Construct PublicStorage using global client (mainline relays).
574
+ */
575
+ constructor();
576
+ /**
577
+ * List a directory. Results are `pubky://…` absolute URLs.
578
+ *
579
+ * @param {string} address Addressed directory (must end with `/`).
580
+ * @param {string|null=} cursor Optional suffix or full URL to start **after**.
581
+ * @param {boolean=} reverse Default `false`. When `true`, newest/lexicographically-last first.
582
+ * @param {number=} limit Optional result limit.
583
+ * @param {boolean=} shallow Default `false`. When `true`, lists only first-level entries.
584
+ * @returns {Promise<string[]>}
585
+ */
586
+ list(address: string, cursor?: string | null, reverse?: boolean | null, limit?: number | null, shallow?: boolean | null): Promise<string[]>;
587
+ /**
588
+ * Fetch bytes from an addressed path.
589
+ *
590
+ * @param {string} address
591
+ * @returns {Promise<Uint8Array>}
592
+ */
593
+ getBytes(address: string): Promise<Uint8Array>;
594
+ /**
595
+ * Fetch text from an addressed path as UTF-8 text.
596
+ *
597
+ * @param {string} address
598
+ * @returns {Promise<string>}
599
+ */
600
+ getText(address: string): Promise<string>;
601
+ /**
602
+ * Fetch JSON from an addressed path.
603
+ *
604
+ * @param {string} address `"<user-z32>/pub/.../file.json"` or `pubky://<user>/pub/...`.
605
+ * @returns {Promise<any>}
606
+ */
607
+ getJson(address: string): Promise<any>;
608
+ /**
609
+ * Check if a path exists.
610
+ *
611
+ * @param {string} address
612
+ * @returns {Promise<boolean>}
613
+ */
614
+ exists(address: string): Promise<boolean>;
615
+ /**
616
+ * Get metadata for an address
617
+ *
618
+ * @param {string} address `"<user-z32>/pub/.../file.json"` or `pubky://<user>/pub/...`.
619
+ * @returns {Promise<ResourceStats|undefined>} `undefined` if the resource does not exist.
620
+ * @throws {PubkyJsError} On invalid input or transport/server errors.
621
+ */
622
+ stats(address: string): Promise<ResourceStats | undefined>;
623
+ }
624
+ /**
625
+ * An authenticated context “as the user”.
626
+ * - Use `storage()` for reads/writes (absolute paths like `/pub/app/file.txt`)
627
+ * - Cookie is managed automatically by the underlying fetch client
628
+ */
186
629
  export class Session {
187
630
  private constructor();
188
631
  free(): void;
189
632
  /**
190
- * Return the [PublicKey] of this session
633
+ * Retrieve immutable info about this session (user & capabilities).
634
+ *
635
+ * @returns {SessionInfo}
636
+ */
637
+ info(): SessionInfo;
638
+ /**
639
+ * Access the session-scoped storage API (read/write).
640
+ *
641
+ * @returns {SessionStorage}
191
642
  */
192
- pubky(): PublicKey;
643
+ storage(): SessionStorage;
193
644
  /**
194
- * Return the capabilities that this session has.
645
+ * Invalidate the session on the server (clears server cookie).
646
+ * It also consumes this JS/Wasm Session. Further calls will fail.
647
+ *
648
+ * @returns {Promise<void>}
649
+ */
650
+ signout(): Promise<void>;
651
+ }
652
+ /**
653
+ * Static snapshot of session metadata.
654
+ */
655
+ export class SessionInfo {
656
+ private constructor();
657
+ free(): void;
658
+ /**
659
+ * The user’s public key for this session.
660
+ *
661
+ * @returns {PublicKey}
662
+ */
663
+ publicKey(): PublicKey;
664
+ /**
665
+ * Effective capabilities granted to this session.
666
+ *
667
+ * @returns {string[]} Normalized capability entries (e.g. `"/pub/app/:rw"`).
195
668
  */
196
669
  capabilities(): string[];
197
670
  }
671
+ /**
672
+ * Read/write storage scoped to **your** session (absolute paths: `/pub/...`).
673
+ */
674
+ export class SessionStorage {
675
+ private constructor();
676
+ free(): void;
677
+ /**
678
+ * List a directory (absolute session path). Returns `pubky://…` URLs.
679
+ *
680
+ * @param {string} path Must end with `/`.
681
+ * @param {string|null=} cursor Optional suffix or full URL to start **after**.
682
+ * @param {boolean=} reverse Default `false`.
683
+ * @param {number=} limit Optional result limit.
684
+ * @param {boolean=} shallow Default `false`.
685
+ * @returns {Promise<string[]>}
686
+ */
687
+ list(path: string, cursor?: string | null, reverse?: boolean | null, limit?: number | null, shallow?: boolean | null): Promise<string[]>;
688
+ /**
689
+ * GET bytes from an absolute session path.
690
+ *
691
+ * @param {string} path
692
+ * @returns {Promise<Uint8Array>}
693
+ */
694
+ getBytes(path: string): Promise<Uint8Array>;
695
+ /**
696
+ * GET text from an absolute session path.
697
+ *
698
+ * @param {string} path
699
+ * @returns {Promise<string>}
700
+ */
701
+ getText(path: string): Promise<string>;
702
+ /**
703
+ * GET JSON from an absolute session path.
704
+ *
705
+ * @param {string} path
706
+ * @returns {Promise<any>}
707
+ */
708
+ getJson(addr: string): Promise<any>;
709
+ /**
710
+ * Check existence.
711
+ *
712
+ * @param {string} path
713
+ * @returns {Promise<boolean>}
714
+ */
715
+ exists(path: string): Promise<boolean>;
716
+ /**
717
+ * Get metadata for an absolute, session-scoped path (e.g. `"/pub/app/file.json"`).
718
+ *
719
+ * @param {string} path Absolute path under your user (starts with `/`).
720
+ * @returns {Promise<ResourceStats|undefined>} `undefined` if the resource does not exist.
721
+ * @throws {PubkyJsError} On invalid input or transport/server errors.
722
+ */
723
+ stats(path: string): Promise<ResourceStats | undefined>;
724
+ /**
725
+ * PUT binary at an absolute session path.
726
+ *
727
+ * @param {string} path
728
+ * @param {Uint8Array} bytes
729
+ * @returns {Promise<void>}
730
+ */
731
+ putBytes(path: string, body: Uint8Array): Promise<void>;
732
+ /**
733
+ * PUT text at an absolute session path.
734
+ *
735
+ * @param {string} path
736
+ * @param {string} text
737
+ * @returns {Promise<void>}
738
+ */
739
+ putText(path: string, body: string): Promise<void>;
740
+ /**
741
+ * PUT JSON at an absolute session path.
742
+ *
743
+ * @param {string} path Absolute path (e.g. `"/pub/app/data.json"`).
744
+ * @param {any} value JSON-serializable value.
745
+ * @returns {Promise<void>}
746
+ */
747
+ putJson(path: string, body: any): Promise<void>;
748
+ /**
749
+ * Delete a path (file or empty directory).
750
+ *
751
+ * @param {string} path
752
+ * @returns {Promise<void>}
753
+ */
754
+ delete(path: string): Promise<void>;
755
+ }
756
+ /**
757
+ * Holds a user’s `Keypair` and performs identity operations:
758
+ * - `signup` creates a new homeserver user.
759
+ * - `signin` creates a homeserver session for an existing user.
760
+ * - Approve pubkyauth requests
761
+ * - Publish PKDNS when signer-bound
762
+ */
763
+ export class Signer {
764
+ private constructor();
765
+ free(): void;
766
+ /**
767
+ * Create a signer from a `Keypair` (prefer `pubky.signer(kp)`).
768
+ *
769
+ * @param {Keypair} keypair
770
+ * @returns {Signer}
771
+ */
772
+ static fromKeypair(keypair: Keypair): Signer;
773
+ /**
774
+ * Get the public key of this signer.
775
+ *
776
+ * @returns {PublicKey}
777
+ */
778
+ publicKey(): PublicKey;
779
+ /**
780
+ * Sign up at a homeserver. Returns a ready `Session`.
781
+ *
782
+ * Creates a valid homeserver Session with root capabilities
783
+ *
784
+ * @param {PublicKey} homeserver The homeserver’s public key.
785
+ * @param {string|null} signupToken Invite/registration token or `null`.
786
+ * @returns {Promise<Session>}
787
+ *
788
+ * @throws {PubkyJsError}
789
+ * - `AuthenticationError` (bad/expired token)
790
+ * - `RequestError` (network/server)
791
+ */
792
+ signup(homeserver: PublicKey, signup_token?: string | null): Promise<Session>;
793
+ /**
794
+ * Fast sign-in for a returning user. Publishes PKDNS in the background.
795
+ *
796
+ * Creates a valid homeserver Session with root capabilities
797
+ *
798
+ * @returns {Promise<Session>}
799
+ *
800
+ * @throws {PubkyJsError}
801
+ */
802
+ signin(): Promise<Session>;
803
+ /**
804
+ * Blocking sign-in. Waits for PKDNS publish to complete (slower; safer).
805
+ *
806
+ * Creates a valid homeserver Session with root capabilities
807
+ *
808
+ * @returns {Promise<Session>}
809
+ */
810
+ signinBlocking(): Promise<Session>;
811
+ /**
812
+ * Approve a `pubkyauth://` request URL (encrypts & POSTs the signed AuthToken).
813
+ */
814
+ approveAuthRequest(pubkyauth_url: string): Promise<void>;
815
+ /**
816
+ * Get a PKDNS actor bound to this signer's client & keypair (publishing enabled).
817
+ *
818
+ * @returns {Pkdns}
819
+ */
820
+ pkdns(): Pkdns;
821
+ }