blockchain-rpc is a typesafe RPC client for Bitcoin, Ethereum and Omni written for Scala 2.12 or 2.13. Under the hood, it's using http4s, circe and cats-effect. We appreciate external contributions, please check issues for inspiration. For all examples, check: src/main/scala/examples. We're planning a non IO-monad interface soon which makes it easier to use with Java and without Cats-effect knowledge.
Simply add the following dependency to your project.
libraryDependencies += "com.madewithtea" %% "blockchain-rpc" % "2.5.2"
This is a simple example of how the RPCClient is generally used. We're using Cats Resources here which automatically deallocate any opened resources after use.
import cats.effect.{ExitCode, IO, IOApp}
import scala.concurrent.ExecutionContext.global
import com.madewithtea.blockchainrpc.RPCClient
import com.madewithtea.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 = "user",
password = "!@#(2009"
)
.use { bitcoin =>
for {
block <- bitcoin.getBlockByHash(
"0000000000000000000759de6ab39c2d8fb01e4481ba581761ddc1d50a57358d"
)
_ <- IO { println(block) }
} yield ExitCode(0)
}
}
}
This example makes use of the EnvConfig import, which automatically configures RPC via ENV flags exported in the shell. The environment flags for it are BLOCKCHAIN_RPC_HOSTS
, BLOCKCHAIN_RPC_USERNAME
, BLOCKCHAIN_RPC_PASSWORD
.
import com.madewithtea.blockchainrpc.Bitcoin
import com.madewithtea.blockchainrpc.{RPCClient, Config}
import com.madewithtea.blockchainrpc.bitcoin.Syntax._
object CatchupFromZero extends IOApp {
def loop(rpc: Bitcoin, current: Long = 0L, until: Long = 10L): IO[Unit] =
for {
block <- rpc.getBlockByHeight(current)
_ <- IO { println(block) }
l <- if (current + 1 < until) loop(rpc, current + 1, until) else IO.unit
} yield l
def run(args: List[String]): IO[ExitCode] = {
implicit val ec = global
implicit val config = Config.fromEnv
RPCClient
.bitcoin(config.hosts, config.port, config.username, config.password)
.use { rpc =>
for {
_ <- loop(rpc)
} yield ExitCode(0)
}
}
}
In this example, the Ethereum syntax is used to fetch a specific block. It uses HexTools
to parse the blocknumber and prints the contents of the block. RPC configuration is acquired from the env vars BLOCKCHAIN_RPC_HOSTS
, BLOCKCHAIN_RPC_USERNAME
, and BLOCKCHAIN_RPC_PASSWORD
.
package com.madewithtea.blockchainrpc.examples.ethereum
import cats.effect.{ExitCode, IO, IOApp}
import scala.concurrent.ExecutionContext.global
import com.madewithtea.blockchainrpc.{RPCClient, Config}
import com.madewithtea.blockchainrpc.ethereum.Syntax._
import com.madewithtea.blockchainrpc.ethereum.HexTools
object GetEthereumBlockByHash extends IOApp {
def run(args: List[String]): IO[ExitCode] = {
implicit val ec = global
implicit val config = Config.fromEnv
RPCClient
.ethereum(
config.hosts,
config.port,
config.username,
config.password
)
.use { ethereum =>
for {
block <- ethereum.getBlockByHash(
"0x3bad41c70c9efac92490e8a74ab816558bbdada0984f2bcfa4cb1522ddb3ca16"
)
_ <- IO { println(s"block ${HexTools.parseQuantity(block.number)}: $block") }
} yield ExitCode(0)
}
}
}
blockchain-rpc method | description | bitcoin rpc method |
---|---|---|
getBlockHash(height: Long) | Gets the block hash at a specific height | getblockhash |
getBestBlockHash() | Gets the block tip hash | getbestblockhash |
getBlockByHash(hash: String) | Gets the block with transaction ids | getblock |
getBlockByHeight(height: Long) | Gets the block with transaction ids | getblockhash , getblock |
getTransaction(hash: String) | Gets raw transaction data | getrawtransaction |
getTransactions(hashes: Seq[String]) | Gets raw transaction data | batch of getrawtransaction |
estimateSmartFee(height: Long) | Estimates fee for include in block n | estimatesmartfee |
getNextBlockHash() | Gets next block hash subscription | usage of ZeroMQ |
blockchain-rpc method | description | ethereum rpc method |
---|---|---|
getBlockByHeight(long: Height) | Get a block by height | eth_getBlockByNumber |
getBlockByHash(hash: String) | Get a block by hash | eth_getBlockByHash |
getBestBlockHeight | Get the best block height | eth_blockNumber |
getTransaction(hash: String) | Get a transaction by hash | eth_getTransactionByHash |
getTransactions(hashes: Seq[String]) | Get a batch of transaction by hash | eth_getTransactionByHash |
getReceiptByHash(hash: String) | Get a transaction receipt by hash | eth_getTransactionReceipt |
getReceiptsByHash(hashes: Seq[String]) | Get transaction receipts by hashes | Batch of eth_getTransactionReceipt |
variable | description | type |
---|---|---|
BLOCKCHAIN_RPC_HOSTS |
Comma-seperated IP list or hostname of full nodes | String |
BLOCKCHAIN_RPC_USERNAME |
RPC username | Optional String |
BLOCKCHAIN_RPC_PASSWORD |
RPC password | Optional String |
BLOCKCHAIN_RPC_PORT |
RPC port when not default | Optional Int |
BLOCKCHAIN_RPC_ZEROMQ_PORT |
ZeroMQ port when not default | Optional Int |