@synonymdev/pubky 0.9.3 → 0.10.0-alpha.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/README.md +51 -40
- package/index.cjs +1247 -222
- package/index.js +1248 -223
- package/package.json +1 -1
- package/pubky.d.ts +493 -26
- package/pubky_bg.wasm +0 -0
package/README.md
CHANGED
|
@@ -31,21 +31,29 @@ const homeserver = PublicKey.from(
|
|
|
31
31
|
"8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo"
|
|
32
32
|
);
|
|
33
33
|
const signupToken = "<your-invite-code-or-null>";
|
|
34
|
-
|
|
34
|
+
await signer.signup(homeserver, signupToken);
|
|
35
35
|
|
|
36
|
-
//
|
|
37
|
-
const
|
|
36
|
+
// 3a) Signin with the signer directly
|
|
37
|
+
const session = await signer.signin("example.com");
|
|
38
|
+
|
|
39
|
+
// 3b) Alternatively if you do not have the keypair available, authenticate on a 3rd-party app
|
|
40
|
+
// by delegating the authentication to a signer with a QR code.
|
|
41
|
+
const authFlow = pubky.startGrantAuthFlow(
|
|
42
|
+
"/pub/my-cool-app/:rw",
|
|
43
|
+
AuthFlowKind.signin(),
|
|
44
|
+
{ clientId: "my-cool-app.example" },
|
|
45
|
+
);
|
|
46
|
+
renderQr(authFlow.authorizationUrl); // Show to user the signin deeplink via a QR code
|
|
47
|
+
const session = await authFlow.awaitApproval();
|
|
48
|
+
|
|
49
|
+
// 4) Write a public JSON file
|
|
50
|
+
const path = "/pub/my-cool-app/hello.json";
|
|
38
51
|
await session.storage.putJson(path, { hello: "world" });
|
|
39
52
|
|
|
40
|
-
//
|
|
53
|
+
// 5) Read it publicly (no auth needed)
|
|
41
54
|
const userPk = session.info.publicKey.toString();
|
|
42
|
-
const addr = `${userPk}/pub/
|
|
55
|
+
const addr = `${userPk}/pub/my-cool-app/hello.json`;
|
|
43
56
|
const json = await pubky.publicStorage.getJson(addr); // -> { hello: "world" }
|
|
44
|
-
|
|
45
|
-
// 5) Authenticate on a 3rd-party app
|
|
46
|
-
const authFlow = pubky.startAuthFlow("/pub/my-cool-app/:rw", AuthFlowKind::signin()); // require permissions to read and write into `my.app`
|
|
47
|
-
renderQr(authFlow.authorizationUrl); // show to user
|
|
48
|
-
const session = await authFlow.awaitApproval();
|
|
49
57
|
```
|
|
50
58
|
|
|
51
59
|
Find here [**ready-to-run examples**](https://github.com/pubky/pubky-core/tree/main/examples).
|
|
@@ -84,8 +92,12 @@ const pubkyLocal = Pubky.testnet("localhost");
|
|
|
84
92
|
// Signer (bind your keypair to a new Signer actor)
|
|
85
93
|
const signer = pubky.signer(Keypair.random());
|
|
86
94
|
|
|
87
|
-
// Pubky Auth flow (with capabilities)
|
|
88
|
-
const authFlow = pubky.
|
|
95
|
+
// Grant Pubky Auth flow (with capabilities)
|
|
96
|
+
const authFlow = pubky.startGrantAuthFlow(
|
|
97
|
+
"/pub/my-cool-app/:rw",
|
|
98
|
+
AuthFlowKind.signin(),
|
|
99
|
+
{ clientId: "my-cool-app.example" },
|
|
100
|
+
);
|
|
89
101
|
|
|
90
102
|
// Public storage (read-only)
|
|
91
103
|
const publicStorage = pubky.publicStorage;
|
|
@@ -106,7 +118,7 @@ const client = new Client(); // or: pubky.client.fetch(); instead of constructin
|
|
|
106
118
|
|
|
107
119
|
// Convert the identifier into a transport URL before fetching.
|
|
108
120
|
const userId = PublicKey.from("pubky<z32>").toString();
|
|
109
|
-
const url = resolvePubky(`${userId}/pub/
|
|
121
|
+
const url = resolvePubky(`${userId}/pub/my-cool-app/file.txt`);
|
|
110
122
|
const res = await client.fetch(url);
|
|
111
123
|
```
|
|
112
124
|
|
|
@@ -155,12 +167,12 @@ const keypair = Keypair.random();
|
|
|
155
167
|
const signer = pubky.signer(keypair);
|
|
156
168
|
|
|
157
169
|
const homeserver = PublicKey.from("8pinxxgq…");
|
|
158
|
-
|
|
170
|
+
await signer.signup(homeserver); // Add optional signup code here if required
|
|
159
171
|
|
|
160
|
-
const
|
|
161
|
-
const
|
|
172
|
+
const session1 = await signer.signin("example.com"); // fast, prefer this; publishes PKDNS in background
|
|
173
|
+
const session2 = await signer.signinBlocking("example.com"); // slower but safer; waits for PKDNS publish
|
|
162
174
|
|
|
163
|
-
await
|
|
175
|
+
await session1.signout(); // invalidates server session
|
|
164
176
|
```
|
|
165
177
|
|
|
166
178
|
**Session details**
|
|
@@ -172,29 +184,29 @@ const caps = session.info.capabilities; // -> string[] permissions and paths
|
|
|
172
184
|
const storage = session.storage; // -> This User's storage API (absolute paths)
|
|
173
185
|
```
|
|
174
186
|
|
|
175
|
-
**Persist a session
|
|
187
|
+
**Persist a grant session**
|
|
176
188
|
|
|
177
189
|
```js
|
|
178
|
-
// Save the session
|
|
179
|
-
const
|
|
180
|
-
localStorage.setItem("pubky-session",
|
|
190
|
+
// Save the session secret. Treat this string like a bearer token.
|
|
191
|
+
const secret = await session.exportSecret();
|
|
192
|
+
localStorage.setItem("pubky-session", secret);
|
|
181
193
|
|
|
182
|
-
// Later
|
|
194
|
+
// Later, restore by minting a fresh short-lived bearer.
|
|
183
195
|
const restored = await pubky.restoreSession(localStorage.getItem("pubky-session")!);
|
|
184
196
|
```
|
|
185
197
|
|
|
186
|
-
>
|
|
187
|
-
>
|
|
198
|
+
> `session.export()` is still available for legacy cookie sessions, but new
|
|
199
|
+
> applications should use grant auth plus `exportSecret()`.
|
|
188
200
|
|
|
189
201
|
**Approve a pubkyauth request URL**
|
|
190
202
|
|
|
191
203
|
```js
|
|
192
|
-
await signer.approveAuthRequest("pubkyauth
|
|
204
|
+
await signer.approveAuthRequest("pubkyauth://signin?caps=...&secret=...&relay=...");
|
|
193
205
|
```
|
|
194
206
|
|
|
195
207
|
---
|
|
196
208
|
|
|
197
|
-
###
|
|
209
|
+
### GrantAuthFlow (pubkyauth)
|
|
198
210
|
|
|
199
211
|
End-to-end auth (3rd-party app asks a user to approve via QR/deeplink, E.g. Pubky Ring).
|
|
200
212
|
|
|
@@ -208,8 +220,12 @@ const caps = "/pub/my-cool-app/:rw,/pub/another-app/folder/:w";
|
|
|
208
220
|
// Optional relay; defaults to Synonym-hosted relay if omitted
|
|
209
221
|
const relay = "https://httprelay.pubky.app/inbox/"; // optional (defaults to this)
|
|
210
222
|
|
|
211
|
-
// Start
|
|
212
|
-
const flow = pubky.
|
|
223
|
+
// Start grant auth polling
|
|
224
|
+
const flow = pubky.startGrantAuthFlow(
|
|
225
|
+
caps,
|
|
226
|
+
AuthFlowKind.signin(),
|
|
227
|
+
{ clientId: "my-cool-app.example", relay },
|
|
228
|
+
);
|
|
213
229
|
|
|
214
230
|
renderQr(flow.authorizationUrl); // show to user
|
|
215
231
|
|
|
@@ -220,7 +236,7 @@ const session = await flow.awaitApproval();
|
|
|
220
236
|
#### Validate and normalize capabilities
|
|
221
237
|
|
|
222
238
|
If you accept capability strings from user input (forms, CLI arguments, etc.),
|
|
223
|
-
use `validateCapabilities` before calling `
|
|
239
|
+
use `validateCapabilities` before calling `startGrantAuthFlow`. The helper returns a
|
|
224
240
|
normalized string (ordering actions like `:rw`) and throws a structured error
|
|
225
241
|
when the input is malformed.
|
|
226
242
|
|
|
@@ -233,7 +249,9 @@ const rawCaps = formData.get("caps");
|
|
|
233
249
|
|
|
234
250
|
try {
|
|
235
251
|
const caps = validateCapabilities(rawCaps ?? "");
|
|
236
|
-
const flow = pubky.
|
|
252
|
+
const flow = pubky.startGrantAuthFlow(caps, AuthFlowKind.signin(), {
|
|
253
|
+
clientId: "my-cool-app.example",
|
|
254
|
+
});
|
|
237
255
|
renderQr(flow.authorizationUrl);
|
|
238
256
|
const session = await flow.awaitApproval();
|
|
239
257
|
// ...
|
|
@@ -252,9 +270,8 @@ surface precise feedback to the user.
|
|
|
252
270
|
|
|
253
271
|
#### Http Relay & reliability
|
|
254
272
|
|
|
255
|
-
- If you don’t specify a relay,
|
|
256
|
-
- For production and larger apps, run **your own http relay** (MIT, Docker): [https://
|
|
257
|
-
The channel is derived as `base64url(hash(secret))`; the token is end-to-end encrypted with the `secret` and cannot be decrypted by the relay.
|
|
273
|
+
- If you don’t specify a relay, the auth flow defaults to a Synonym-hosted relay. If that relay is down, logins won’t complete.
|
|
274
|
+
- For production and larger apps, run **your own http relay** (MIT, Docker): [https://github.com/pubky/http-relay](https://github.com/pubky/http-relay).
|
|
258
275
|
|
|
259
276
|
---
|
|
260
277
|
|
|
@@ -290,7 +307,7 @@ await pub.list(
|
|
|
290
307
|
|
|
291
308
|
Use `get()` when you need the raw `Response` for streaming or custom parsing.
|
|
292
309
|
|
|
293
|
-
#### SessionStorage (read/write
|
|
310
|
+
#### SessionStorage (read/write)
|
|
294
311
|
|
|
295
312
|
```js
|
|
296
313
|
const s = session.storage;
|
|
@@ -423,12 +440,6 @@ try {
|
|
|
423
440
|
}
|
|
424
441
|
```
|
|
425
442
|
|
|
426
|
-
## Browser environment notes
|
|
427
|
-
|
|
428
|
-
- Keep the Pubky client UI and the homeserver on the **same origin family** (both local or both remote). Browsers partition cookies by scheme/host, and cross-site requests (e.g., http://localhost calling https://staging…) can silently drop or cache `SameSite`/`Secure` session cookies.
|
|
429
|
-
- If you must mix environments, use a reverse proxy so the browser always talks to one consistent origin (or disable caching via devtools and clear cookies between switches).
|
|
430
|
-
- When troubleshooting auth/session caching: open a fresh incognito window, clear site data for the target origin, and verify the request includes credentials.
|
|
431
|
-
|
|
432
443
|
---
|
|
433
444
|
|
|
434
445
|
## Local Test & Development
|