Skip to content

Overview

HappyView provides JavaScript packages for building third-party apps that authenticate with a HappyView instance and make XRPC requests on behalf of users.

PackagePurpose
@happyview/lex-agentRecommended: type-safe XRPC via @atproto/lex Client with HappyView DPoP auth
@happyview/oauth-clientPlatform-agnostic core: DPoP key provisioning, session management, authenticated fetch
@happyview/oauth-client-browserBrowser OAuth wrapper for apps already using @atproto/oauth-client-browser
@happyview/oauth-client-nodeNode.js OAuth client for server-side apps, matching @atproto/oauth-client-node

Starting a new app? Use @happyview/lex-agent with @atproto/lex. It gives you type-safe XRPC calls through a Client that routes requests to your HappyView instance with DPoP authentication. This is the recommended way to interact with HappyView from JavaScript.

Already using @atproto/api? HappyViewSession works directly as a session manager for @atproto/api’s Agent: pass it to new Agent(session). See Using with @atproto/api.

Already using @atproto/oauth-client-browser? Add @happyview/oauth-client-browser to get a HappyViewBrowserClient that handles the HappyView-specific DPoP key provisioning and session registration on top of the standard atproto OAuth flow.

Building a server-side (Node.js) app? Use @happyview/oauth-client-node. It handles handle resolution, DID resolution, PDS discovery, and the full OAuth flow server-side. Matches the API surface of @atproto/oauth-client-node.

Building something more custom? Use @happyview/oauth-client directly and provide your own StorageAdapter.

Third-party apps authenticate using HappyView’s DPoP key provisioning flow:

  1. The SDK requests a DPoP keypair from the HappyView instance.
  2. Your app runs a standard atproto OAuth flow with the user’s PDS using that keypair.
  3. The SDK registers the resulting tokens with HappyView.
  4. All subsequent XRPC requests are authenticated with DPoP proofs. HappyView handles its own lexicons locally and proxies standard atproto writes to the user’s PDS.

If your app is a confidential atproto OAuth client, step 2 also needs a signed private_key_jwt assertion for its PAR and token-exchange requests. @happyview/oauth-client’s getClientAssertion() mints one. See Client assertions.

Terminal window
npm install @happyview/lex-agent @happyview/oauth-client-browser @atproto/lex
import { Client } from "@atproto/lex";
import { HappyViewBrowserClient } from "@happyview/oauth-client-browser";
import { createAgent } from "@happyview/lex-agent";
// Set up the OAuth client
const oauthClient = new HappyViewBrowserClient({
instanceUrl: "https://happyview.example.com",
clientId: "https://example.com/oauth-client-metadata.json",
clientKey: "hvc_your_client_key",
});
// Sign in: redirects to the user's PDS
await oauthClient.signIn("alice.bsky.social");
// On page load: restore session or process callback
const result = await oauthClient.init();
const session = result?.session;
// Create a type-safe Lex client
const agent = createAgent(session);
const lex = new Client(agent);
// Make type-safe XRPC calls
const game = await lex.xrpc(myLexicons.com.example.getGame, {
params: { slug: "celeste" },
});