A lexicon-driven AppView for ATProto. happyview.dev
backfill firehose jetstream atproto appview oauth lexicon
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: add readmes and licenses for sdks

Trezy 5366177b b0de4b82

+309
+21
packages/lex-agent/LICENSE.md
··· 1 + MIT License 2 + 3 + Copyright (c) 2024 Lexicon Community 4 + 5 + Permission is hereby granted, free of charge, to any person obtaining a copy 6 + of this software and associated documentation files (the "Software"), to deal 7 + in the Software without restriction, including without limitation the rights 8 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 + copies of the Software, and to permit persons to whom the Software is 10 + furnished to do so, subject to the following conditions: 11 + 12 + The above copyright notice and this permission notice shall be included in all 13 + copies or substantial portions of the Software. 14 + 15 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 + SOFTWARE.
+46
packages/lex-agent/README.md
··· 1 + # @happyview/lex-agent 2 + 3 + Adapter that creates an [`@atproto/lex`](https://www.npmjs.com/package/@atproto/lex) `Agent` from a `HappyViewSession`. This lets you use `@atproto/lex`'s type-safe `Client` and `xrpc()` calls with HappyView's DPoP authentication. 4 + 5 + All XRPC requests made through the agent are routed to your HappyView instance. HappyView handles requests for its own lexicons locally and proxies standard AT Protocol methods (e.g., `com.atproto.repo.createRecord`) to the user's PDS. 6 + 7 + ## Installation 8 + 9 + ```bash 10 + npm install @happyview/lex-agent @atproto/lex 11 + ``` 12 + 13 + `@atproto/lex` is a peer dependency (`>=0.0.20`). 14 + 15 + ## Usage 16 + 17 + ```typescript 18 + import { Client } from "@atproto/lex"; 19 + import { HappyViewBrowserClient } from "@happyview/oauth-client-browser"; 20 + import { createAgent } from "@happyview/lex-agent"; 21 + 22 + // Authenticate with HappyView 23 + const client = new HappyViewBrowserClient({ 24 + instanceUrl: "https://happyview.example.com", 25 + clientKey: "hvc_your_client_key", 26 + }); 27 + const session = await client.restore(); 28 + 29 + // Create a Lex agent from the session 30 + const agent = createAgent(session); 31 + const lex = new Client(agent); 32 + 33 + // Make type-safe XRPC calls 34 + const game = await lex.xrpc(myLexicons.com.example.getGame, { 35 + params: { slug: "celeste" }, 36 + }); 37 + ``` 38 + 39 + ## API 40 + 41 + ### `createAgent(session: HappyViewSession): Agent` 42 + 43 + Creates an `@atproto/lex` `Agent` from a `HappyViewSession`. The returned agent: 44 + 45 + - Exposes the session's DID via `agent.did` 46 + - Delegates all fetch requests to `session.fetchHandler`, which attaches DPoP authentication headers and prepends the HappyView instance URL
+21
packages/oauth-client-browser/LICENSE.md
··· 1 + MIT License 2 + 3 + Copyright (c) 2024 Lexicon Community 4 + 5 + Permission is hereby granted, free of charge, to any person obtaining a copy 6 + of this software and associated documentation files (the "Software"), to deal 7 + in the Software without restriction, including without limitation the rights 8 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 + copies of the Software, and to permit persons to whom the Software is 10 + furnished to do so, subject to the following conditions: 11 + 12 + The above copyright notice and this permission notice shall be included in all 13 + copies or substantial portions of the Software. 14 + 15 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 + SOFTWARE.
+89
packages/oauth-client-browser/README.md
··· 1 + # @happyview/oauth-client-browser 2 + 3 + Browser OAuth client for authenticating with a [HappyView](https://github.com/gamesgamesgamesgamesgames/happyview) instance using AT Protocol. 4 + 5 + Built on top of [`@happyview/oauth-client`](https://www.npmjs.com/package/@happyview/oauth-client) with Web Crypto and localStorage adapters included. 6 + 7 + ## Installation 8 + 9 + ```bash 10 + npm install @happyview/oauth-client-browser 11 + ``` 12 + 13 + ## Usage 14 + 15 + ### Setup 16 + 17 + ```typescript 18 + import { HappyViewBrowserClient } from "@happyview/oauth-client-browser"; 19 + 20 + const client = new HappyViewBrowserClient({ 21 + instanceUrl: "https://happyview.example.com", 22 + clientKey: "hvc_your_client_key", 23 + }); 24 + ``` 25 + 26 + ### Login 27 + 28 + Redirects the user to their PDS authorization server: 29 + 30 + ```typescript 31 + await client.login("alice.bsky.social"); 32 + // User is redirected to their PDS for authorization 33 + ``` 34 + 35 + If you need the authorization URL without an immediate redirect (e.g., to open in a popup), use `prepareLogin`: 36 + 37 + ```typescript 38 + const { authorizationUrl, did, state } = 39 + await client.prepareLogin("alice.bsky.social"); 40 + ``` 41 + 42 + ### OAuth Callback 43 + 44 + On the `/oauth/callback` route, call `callback()` to complete the token exchange: 45 + 46 + ```typescript 47 + const session = await client.callback(); 48 + // Session is now stored in localStorage 49 + ``` 50 + 51 + ### Restore Session 52 + 53 + On subsequent page loads, restore the session from localStorage: 54 + 55 + ```typescript 56 + const session = await client.restore(); 57 + if (session) { 58 + // User is still logged in 59 + } 60 + ``` 61 + 62 + ### Authenticated Requests 63 + 64 + The session's `fetchHandler` attaches DPoP proof headers automatically. Pass it a path (relative to the HappyView instance) or a full URL: 65 + 66 + ```typescript 67 + const response = await session.fetchHandler( 68 + "/xrpc/com.example.getStuff?limit=10", 69 + { method: "GET" }, 70 + ); 71 + ``` 72 + 73 + ### Logout 74 + 75 + ```typescript 76 + await client.logout("did:plc:abc123"); 77 + ``` 78 + 79 + ## Exports 80 + 81 + This package re-exports everything from `@happyview/oauth-client`, plus: 82 + 83 + - `HappyViewBrowserClient` -- the main browser client 84 + - `LocalStorageAdapter` -- `StorageAdapter` backed by `window.localStorage` 85 + - `WebCryptoAdapter` -- `CryptoAdapter` backed by the Web Crypto API 86 + - `resolveHandleToDid` -- resolve an AT Protocol handle to a DID 87 + - `resolveDidDocument` -- fetch a DID document 88 + - `resolvePdsUrl` -- extract the PDS URL from a DID document 89 + - `resolveAuthServerMetadata` -- fetch OAuth authorization server metadata from a PDS
+21
packages/oauth-client/LICENSE.md
··· 1 + MIT License 2 + 3 + Copyright (c) 2024 Lexicon Community 4 + 5 + Permission is hereby granted, free of charge, to any person obtaining a copy 6 + of this software and associated documentation files (the "Software"), to deal 7 + in the Software without restriction, including without limitation the rights 8 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 + copies of the Software, and to permit persons to whom the Software is 10 + furnished to do so, subject to the following conditions: 11 + 12 + The above copyright notice and this permission notice shall be included in all 13 + copies or substantial portions of the Software. 14 + 15 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 + SOFTWARE.
+111
packages/oauth-client/README.md
··· 1 + # @happyview/oauth-client 2 + 3 + Core OAuth client for authenticating with a [HappyView](https://github.com/gamesgamesgamesgamesgames/happyview) instance. 4 + 5 + This is a platform-agnostic package. If you're building a browser app, use [`@happyview/oauth-client-browser`](https://www.npmjs.com/package/@happyview/oauth-client-browser) instead. It wraps this package with Web Crypto, localStorage, and a complete OAuth redirect flow. 6 + 7 + ## Installation 8 + 9 + ```bash 10 + npm install @happyview/oauth-client 11 + ``` 12 + 13 + ## Usage 14 + 15 + `HappyViewOAuthClient` manages DPoP key provisioning, session registration, and session restoration lifecycle. You provide a `CryptoAdapter` and optional `StorageAdapter` for your platform. 16 + 17 + ```typescript 18 + import { HappyViewOAuthClient } from "@happyview/oauth-client"; 19 + 20 + const client = new HappyViewOAuthClient({ 21 + instanceUrl: "https://happyview.example.com", 22 + clientKey: "hvc_your_client_key", 23 + clientSecret: "hvs_your_secret", // optional, for confidential clients (server-to-server) 24 + crypto: myCryptoAdapter, 25 + storage: myStorageAdapter, // optional, defaults to in-memory 26 + }); 27 + ``` 28 + 29 + ### DPoP Key Provisioning 30 + 31 + Request a DPoP keypair from the HappyView instance: 32 + 33 + ```typescript 34 + const { provisionId, dpopKey, pkceVerifier } = await client.provisionDpopKey(); 35 + ``` 36 + 37 + ### Session Registration 38 + 39 + After completing OAuth authorization with the user's PDS, register the session with HappyView: 40 + 41 + ```typescript 42 + const session = await client.registerSession({ 43 + provisionId, 44 + pkceVerifier, 45 + did: "did:plc:abc123", 46 + accessToken: tokens.access_token, 47 + refreshToken: tokens.refresh_token, 48 + scopes: "atproto", 49 + pdsUrl: "https://pds.example.com", 50 + issuer: tokens.iss, 51 + dpopKey, 52 + }); 53 + ``` 54 + 55 + ### Making Authenticated Requests 56 + 57 + The returned `HappyViewSession` provides a `fetchHandler` that automatically attaches DPoP proof headers: 58 + 59 + ```typescript 60 + const response = await session.fetchHandler("/xrpc/com.example.getStuff", { 61 + method: "GET", 62 + }); 63 + ``` 64 + 65 + ### Session Restoration 66 + 67 + Restore a previously stored session: 68 + 69 + ```typescript 70 + // Restore the last active session 71 + const session = await client.restore(); 72 + 73 + // Or restore a specific user's session 74 + const session = await client.restoreSession("did:plc:abc123"); 75 + ``` 76 + 77 + ### Logout 78 + 79 + ```typescript 80 + await client.deleteSession("did:plc:abc123"); 81 + ``` 82 + 83 + ## Adapters 84 + 85 + ### CryptoAdapter 86 + 87 + Implement this interface for your platform's cryptographic primitives: 88 + 89 + ```typescript 90 + interface CryptoAdapter { 91 + generatePkceVerifier(): Promise<string>; 92 + computePkceChallenge(verifier: string): Promise<string>; 93 + signEs256(privateKey: JsonWebKey, payload: Uint8Array): Promise<Uint8Array>; 94 + sha256(data: Uint8Array): Promise<Uint8Array>; 95 + getRandomValues(length: number): Uint8Array; 96 + } 97 + ``` 98 + 99 + ### StorageAdapter 100 + 101 + Implement this interface to persist sessions across restarts: 102 + 103 + ```typescript 104 + interface StorageAdapter { 105 + get(key: string): Promise<string | null>; 106 + set(key: string, value: string): Promise<void>; 107 + delete(key: string): Promise<void>; 108 + } 109 + ``` 110 + 111 + If no `StorageAdapter` is provided, sessions are stored in memory and will not survive page reloads or process restarts.