Terminus v0.1.1 Terminus.Bitsocket View Source

Module for interfacing with the Bitsocket API.

Bitsocket sends you realtime events from the Bitcoin blockchain. It uses Server Sent Events to stream new unconfirmed transactions as soon as they appear on the Bitcoin network.

Bitsocket is like Websocket, but for Bitcoin. With just a single Bitsocket connection, you get access to a live, filterable stream of all transaction events across the entire bitcoin peer network.

Schema

Realtime transactions have a similar schema to Bitbus documents. However, as these are unconfirmed transactions, they have no blk infomation and provide a timestamp attribute reflecting when Bitsocket first saw the transaction.

%{
  "_id" => "...",       # Bitbus document ID
  "in" => [...],        # List of inputs
  "lock" => int,        # Lock time
  "out" => [...],       # List of outputs
  "timestamp" => int,   # Timestamp of when tx seen
  "tx" => %{
    "h" => "..."        # Transaction hash
  }
}

Terminus supports both of the Bitsocket public enpoints. The endpoint can be selected by passing the :host option to any API method.

The available endpoints are:

iex> Terminus.Bitsocket.listen(query, host: :bob)

Usage

Subscribe to realtime Bitcoin transactions using listen/3 and stream the results into your own data processing pipeline.

iex> Terminus.Bitsocket.listen!(query)
...> |> Stream.map(&Terminus.BitFS.scan_tx/1)
...> |> Stream.each(&save_to_db/1)
...> |> Stream.run
:ok

Bitsocket also provides an API for querying and crawling the transaction event database which indexes all transactions in the previous 24 hours. Both crawl/3 and fetch/2 can be used to query these events.

iex> Terminus.Bitsocket.fetch(%{
...>   find: %{
...>     "out.s2" => "1LtyME6b5AnMopQrBPLk4FGN8UBuhxKqrn",
...>     "timestamp" => %{"$gt": :os.system_time(:millisecond) - 60000}
...>   },
...>   sort: %{ "timestamp": -1 }
...> }, token: token)
{:ok, [
  %{
    "tx" => %{"h" => "fca7bdd7658613418c54872212811cf4c5b4f8ee16864eaf70cb1393fb0df6ca"},
    ...
  },
  ...
]}

Link to this section Summary

Functions

Crawls the Bitsocket event database for transactions using the given query and returns a stream.

As crawl/3 but returns the result or raises an exception if it fails.

Crawls the Bitsocket event database for transactions using the given query and returns a stream.

As fetch/2 but returns the result or raises an exception if it fails.

Subscribes to Bitsocket and streams realtime transaction events using the given query.

As listen/3 but returns the result or raises an exception if it fails.

Link to this section Functions

Link to this function

crawl(query, options \\ [], ondata \\ nil)

View Source

Specs

crawl(Terminus.bitquery(), keyword(), Terminus.callback()) ::
  {:ok, Enumerable.t() | pid()} | :ok | {:error, Exception.t()}

Crawls the Bitsocket event database for transactions using the given query and returns a stream.

Returns the result in an :ok / :error tuple pair.

All requests must provide a valid Planaria token. By default a streaming Enumerable.t/0 is returned. Optionally a linked GenStage pid can be returned for using in combination with your own GenStage consumer.

If a callback is provided, the stream is automatically run and the callback is called on each transaction.

Options

The accepted options are:

  • token - Planaria authentication token. Required.
  • host - The Bitsocket host. Defaults to txo.bitsocket.network.
  • stage - Return a linked GenStage pid. Defaults to false.

Examples

Queries should be in the form of any valid Bitquery.

query = %{
  find: %{ "out.s2" => "1LtyME6b5AnMopQrBPLk4FGN8UBuhxKqrn" }
}

By default Terminus.Bitsocket.crawl/2 returns a streaming Enumerable.t/0.

iex> Terminus.Bitsocket.crawl(query, token: token)
{:ok, %Stream{}}

Optionally the pid of the GenStage producer can be returned.

iex> Terminus.Bitsocket.crawl(query, token: token, stage: true)
{:ok, #PID<>}

If a callback is provided, the function returns :ok and the callback is called on each transaction.

iex> Terminus.Bitsocket.crawl(query, [token: token], fn tx ->
...>   IO.inspect tx
...> end)
:ok
Link to this function

crawl!(query, options \\ [], ondata \\ nil)

View Source

Specs

As crawl/3 but returns the result or raises an exception if it fails.

Link to this function

fetch(query, options \\ [])

View Source

Specs

fetch(Terminus.bitquery(), keyword()) :: {:ok, list()} | {:error, Exception.t()}

Crawls the Bitsocket event database for transactions using the given query and returns a stream.

Returns the result in an :ok / :error tuple pair.

This function is suitable for smaller limited queries as the entire result set is loaded in to memory an returned. For large crawls, crawl/3 is preferred as the results can be streamed and processed more efficiently.

Options

The accepted options are:

  • token - Planaria authentication token. Required.
  • host - The Bitsocket host. Defaults to txo.bitsocket.network.

Examples

  iex> Terminus.Bitsocket.fetch(query, token: token)
  [
    %{
      "tx" => %{"h" => "bbae7aa467cb34010c52033691f6688e00d9781b2d24620cab51827cd517afb8"},
      ...
    },
    ...
  ]
Link to this function

fetch!(query, options \\ [])

View Source

Specs

fetch!(Terminus.bitquery(), keyword()) :: list()

As fetch/2 but returns the result or raises an exception if it fails.

Link to this function

listen(query, options \\ [], ondata \\ nil)

View Source

Specs

listen(Terminus.bitquery(), keyword(), Terminus.callback()) ::
  {:ok, Enumerable.t() | pid()} | :ok | {:error, Exception.t()}

Subscribes to Bitsocket and streams realtime transaction events using the given query.

Returns the result in an :ok / :error tuple pair.

By default a streaming Enumerable.t/0 is returned. Optionally a linked GenStage pid can be returned for using in combination with your own GenStage consumer.

If a callback is provided, the stream is automatically run and the callback is called on each transaction.

As Bitsocket streams transactions using Server Sent Events, the stream will stay open (and blocking) permanently. This is best managed inside a long-running Elixir process.

Options

The accepted options are:

  • host - The Bitsocket host. Defaults to txo.bitsocket.network.
  • stage - Return a linked GenStage pid instead of a stream.
  • recycle - Number of seconds after which to recycle to a quiet Bitsocket request. Defaults to 900.

Examples

Queries should be in the form of any valid Bitquery.

query = %{
  find: %{ "out.s2" => "1LtyME6b5AnMopQrBPLk4FGN8UBuhxKqrn" }
}

By default Terminus.Bitsocket.listen/2 returns a streaming Enumerable.t/0.

iex> Terminus.Bitsocket.listen(query, token: token)
{:ok, %Stream{}}

Optionally the pid of the GenStage producer can be returned.

iex> Terminus.Bitsocket.listen(query, token: token, stage: true)
{:ok, #PID<>}

If a callback is provided, the stream returns :ok and the callback is called on each transaction.

iex> Terminus.Bitsocket.listen(query, [token: token], fn tx ->
...>   IO.inspect tx
...> end)
:ok
Link to this function

listen!(query, options \\ [])

View Source

Specs

listen!(Terminus.bitquery(), keyword()) :: Enumerable.t() | pid() | :ok

As listen/3 but returns the result or raises an exception if it fails.