Txbox

Elixir Bitcoin Tx storage schema

Hex.pmLicenseBuild Status

Txbox is a Bitcoin transaction storage schema. It lets you store Bitcoin transactions in your application's database with searchable and filterable semantic metadata. Txbox is inspired by TXT but adapted to slot into an Elixir developers toolset.

Installation

The package can be installed by adding txbox to your list of dependencies in mix.exs.

def deps do
  [
    {:txbox, "~> 0.3"}
  ]
end

Once installed, update your application's configuration, making sure Txbox knows which Repo to use.

# config/config.exs
config :txbox, repo: MyApp.Repo

Next, Txbox to your application's supervision tree.

children = [
  {Txbox, [
    # Manic miner configuration (defaults to :taal)
    miner: {:taal, headers: [{"token", "MYTOKEN"}]},
    # Maximum number of times to attempt polling the miner (default is 20)
    max_status_attempts: 20,
    # Interval (in seconds) between each mAPI request (default is 300 - 5 minutes)
    retry_status_after: 300
  ]}
]

Supervisor.start_link(children, strategy: :one_for_one)

Finally, run the following tasks to generate and run the required database migrations.

mix txbox.gen.migrations
mix ecto.migrate

Upgrading

If upgrading from a previous version of txbox, make sure to run the migrations task to check if any new migrations are required.

mix txbox.gen.migrations
# If needed
mix ecto.migrate

Usage

For detailed examples, refer to the full documentation.

Once up an running, using Txbox is simple. The Txbox modules provides four CRUD-like functions for managing transactions: create/2, update/2, find/2 and all/2.

To add a transaction to Txbox, the minimum required is to give a txid.

Txbox.create(%{
  txid: "6dfccf46359e033053ab1975c1e008ddc98560f591e8ed1c8bd051050992c110"
})

Once a transaction is added, Txbox automatically syncs with the Miner API of your choice, updating the transaction's status until it is confirmed in a block.

When a channel name is ommitted, transactions are added to the default_channel/0 ("txbox"), but by specifiying a channel name as the first argument, the transaction will be added to that channel. You can provide additional metadata about the transaction, as well as attach the raw transaction binary.

Txbox.create("photos", %{
  txid: "6dfccf46359e033053ab1975c1e008ddc98560f591e8ed1c8bd051050992c110",
  rawtx: <<...>>,
  tags: ["hubble", "universe"],
  meta: %{
    title: "Hubble Ultra-Deep Field"
  },
  data: %{
    bitfs: "https://x.bitfs.network/6dfccf46359e033053ab1975c1e008ddc98560f591e8ed1c8bd051050992c110.out.0.3"
  }
})

The transaction can be retrieved by the txid.

Txbox.find("6dfccf46359e033053ab1975c1e008ddc98560f591e8ed1c8bd051050992c110")

As before, omitting the channel scopes the query to the default_channel/0 ("txbox"). Alterntively you can pass the channel name as the first argument, or use "_" which is the TXT syntax for global scope.

Txbox.find("_", "6dfccf46359e033053ab1975c1e008ddc98560f591e8ed1c8bd051050992c110")

A list of transactions can be returned using all/2. The second parameter must be a t:map/0 of query parameters to filter and search by.

Txbox.all("photos", %{
  from: 636400,
  tagged: "hubble",
  limit: 5
})

A full text search can be made by using the :search filter parameter.

Txbox.all("_", %{
  search: "hubble deep field"
})

Filtering and searching

Txbox adopts the same syntax and query modifiers used by TXT. Txbox automatically normalizes the query map, so keys can be specifiied either as atoms or strings. Here are a few examples:

Transaction state machine and miner API integration

Under the hood, Txbox is packed with a powerful state machine with automatic miner API integration.

Txbox state machine

When creating a new transaction, you can set its state to one of the following values.

The miner API queue and processing occurs automatically in a background process, run under your application's supervision tree. For details refer to Txbox.Mapi.Queue and Txbox.Mapi.Processor.

Each historic miner API response is saved associated to the transaction. The most recent response is always preloaded with the transaction. This allows you to inspect any messages or errors given by miners.

iex> {:ok, tx} = Txbox.find("6dfccf46359e033053ab1975c1e008ddc98560f591e8ed1c8bd051050992c110")
iex> tx.status
%Txbox.Transactions.MapiResponse{
  type: "push",
  payload: %{
    "return_result" => "failure",
    "return_description" => "Not enough fees",
    ...
  },
  public_key: "03e92d3e5c3f7bd945dfbf48e7a99393b1bfb3f11f380ae30d286e7ff2aec5a270",
  signature: "3045022100c8e7f9369545b89c978afc13cc19fc6dd6e1cd139d363a6b808141e2c9fccd2e02202e12f4bf91d10bf7a45191e6fe77f50d7b5351dae7e0613fecc42f61a5736af8",
  verified: true
}

For more examples, refer to the full documentation.

License

Txbox is open source and released under the Apache-2 License.

© Copyright 2020 libitx.