Generic and typesafe Blockchain-RPC

At TokenAnalyst we decided to build a thin layer library called blockchain-rpc to only connect, download and parse raw data into abstract data types in a typesafe Scala way. In the principle of: do one thing and do it well. Its open source and wed like to invite you to collaborate on it. The library is very generic since were using blockchain-dependent type class instances, s.t. we can snap any blockchain with its own methods into our syntax. Supported blockchains are Bitcoin, Ethereum and Omni.

Over at TokenAnalyst we're parsing multiple block-transaction-based blockchains. Instead of relying on RPC libraries for the different chains (mostly in untyped Javascript), we decided to build a thin layer library called blockchain-rpc to only connect, download and parse raw data into abstract data types (without interpretation) in a typesafe Scala way. In the principle of: do one thing and do it well. It's open source and we'd like to invite you to collaborate on it.

https://github.com/tokenanalyst/blockchain-rpc

How generic?

The library is very generic since we're using blockchain-dependent type class instances, such as JSON RPC encoders/decoders, we can snap any blockchain with its own methods into our syntax. Supported blockchains are Bitcoin, Ethereum and Omni. The following is a code snippet to retrieve a Bitcoin block by hash. We're using cats-effect IO monad to compose computations with side-effects. For an introduction into that have a look here. Also notice the Bitcoin syntax import statement to import the concrete Bitcoin type class instances.

import cats.effect.{ExitCode, IO, IOApp}
import scala.concurrent.ExecutionContext.global

import io.tokenanalyst.blockchainrpc.RPCClient
import io.tokenanalyst.blockchainrpc.bitcoin.Syntax._

object GetBlockHash extends IOApp {
  def run(args: List[String]): IO[ExitCode] = {
    implicit val ec = global
    RPCClient
      .bitcoin(
        Seq(127.0.0.1),
        username = "tokenanalyst",
        password = "!@#$%^&*(2009"
      )
      .use { bitcoin =>
        for {
          block <- bitcoin.getBlockByHash(
            "0000000000000000000759de6ab39c2d8fb01e4481ba581761ddc1d50a57358d"
          )
          _ <- IO { println(block) }
        } yield ExitCode(0)
      }
  }
}

Under the hood

Underlying we're using Blaze, a fast NIO microframework, to communicate over HTTP. Since we're big fans of functional programming and its benefits we adopted cats-effect for effect seperation. However, for the ease of usability we will also offer a non-IO interface shortly. Give it a star

We would be happy to answer any upcoming questions, please star the project on Github if you like! https://github.com/tokenanalyst/blockchain-rpc