Exosphere

Hex.pmHexDocs

Logo

Exosphere is a collection of protocol clients and utilities.

Documentation

What’s inside

Getting started

Installation

Add exosphere to your dependencies:

def deps do
  [
    {:exosphere, "~> 0.1.0"}
  ]
end

Quickstart: 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
end

Notes

CI / Releases

This project uses GitHub Actions:

To enable publishing, add a repository secret named HEX_API_KEY (generate one via mix hex.user key generate).