Getting started
The only integration step is using Habitat as your identity resolver. Habitat resolves the identity through the public network (or its own directory) and then rewrites the #atproto_pds service entry in the returned DID document to point at Habitat. Every downstream piece of the atproto stack — OAuth discovery, XRPC routing — follows that pointer, so your app talks to Habitat without knowing anything special.
TypeScript
npm install @habitat-network/habitat
import { BrowserOAuthClient } from "@atproto/oauth-client-browser";
import { HabitatIdentityResolver } from "@habitat-network/habitat";
const client = new BrowserOAuthClient({
clientMetadata,
identityResolver: new HabitatIdentityResolver(), // defaults to https://pear.habitat.network
});
const session = await client.signIn("alice.bsky.social");
The resolver satisfies @atproto-labs/identity-resolver's IdentityResolver interface, so it drops into the standard browser OAuth client. Pass a service URL to target a self-hosted instance: new HabitatIdentityResolver("https://pear.example.com").
Note that the resolver performs no client-side bidirectional handle/DID verification — it trusts the Habitat instance you point it at.
Go
Use indigo's API directory with Habitat as the host:
import "github.com/bluesky-social/indigo/atproto/identity/apidir"
dir := apidir.NewAPIDirectory("https://pear.habitat.network")
ident, err := dir.LookupHandle(ctx, syntax.Handle("alice.bsky.social"))
// ident.PDSEndpoint() == "https://pear.habitat.network"
Direct XRPC
curl "https://pear.habitat.network/xrpc/com.atproto.identity.resolveIdentity?identifier=alice.bsky.social"
Authentication
Because the resolved DID document names Habitat as the PDS, a standard atproto OAuth client discovers Habitat's /.well-known/oauth-protected-resource and authorizes against Habitat. Habitat brokers that flow: it runs its own OAuth server for your app while acting as an OAuth client against the user's real PDS, so the user still authenticates with their own provider.
Next: Endpoints.