Exosphere
Exosphere is a collection of protocol clients and utilities.
Documentation
- HexDocs: https://hexdocs.pm/exosphere
What’s inside
Exosphere.ATProto.*: lower-level, spec-aligned implementation building blocks (see atproto.com)Exosphere.*: public-facing API modules built on top ofExosphere.ATProto.*(XRPC client, firehose consumer, etc.)
Getting started
Installation
Add exosphere to your dependencies:
def deps do
[
{:exosphere, "~> 0.1.0"}
]
endQuickstart: XRPC client
Exosphere.XRPC.Client is a small wrapper around Exosphere.ATProto.XRPC.Client.
# Create an unauthenticated client for a PDS
client = Exosphere.XRPC.Client.new("https://bsky.social")
{:ok, %{"did" => did}} =
Exosphere.XRPC.Client.query(client, "com.atproto.identity.resolveHandle",
handle: "atproto.com"
)Firehose (subscribeRepos)
Use Exosphere.Firehose.Consumer to connect to a relay’s
com.atproto.sync.subscribeRepos WebSocket endpoint, decode frames into
structured messages, and dispatch them to your callback.
Running under a supervisor
The consumer requires an :on_event callback with arity 2: (message, state) -> state.
children = [
{Exosphere.Firehose.Consumer,
relay_url: "wss://bsky.network",
cursor: nil,
on_event: &MyApp.Firehose.on_event/2,
name: MyApp.FirehoseConsumer}
]
Supervisor.start_link(children, strategy: :one_for_one)Handling events
Messages are decoded into maps with a :type key (for example :commit, :identity, :handle).
For commit messages, you can extract record data from the embedded CAR blocks via
Exosphere.ATProto.Firehose.Message.extract_records/1.
defmodule MyApp.Firehose do
require Logger
alias Exosphere.ATProto.Firehose.Message
def on_event(%{type: :commit} = msg, state) do
# Persist msg.seq somewhere if you want resumable consumption (cursor).
case Message.extract_records(msg) do
{:ok, records} ->
Logger.info("commit seq=#{msg.seq} records=#{length(records)}")
state
{:error, reason} ->
Logger.warning("commit seq=#{msg.seq} extract_records failed: #{inspect(reason)}")
state
end
end
def on_event(msg, state) do
Logger.debug("firehose event: #{inspect(msg.type)}")
state
end
endNotes
- The consumer will attempt to reconnect on disconnects and errors.
-
For more control (or lower-level access), use the
Exosphere.ATProto.*modules directly.
CI / Releases
This project uses GitHub Actions:
- CI: runs
mix format --check-formatted,mix credo --strict,mix test, andmix dialyzeron pushes + PRs. - Auto-versioning on merge: when a PR is merged into
main, a workflow requires exactly one label:major,minor, orpatch. It bumpsmix.exs, commits, tagsvX.Y.Z, and pushes (which triggers the Hex release workflow). - Release: pushing a tag like
v0.1.0publishes the package + docs to Hex.
To enable publishing, add a repository secret named HEX_API_KEY (generate one via mix hex.user key generate).