Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
# Conflicts:
#	README.md
  • Loading branch information
CesarPantoja committed Dec 17, 2019
2 parents 615326d + e89b3c1 commit 7b2ac7a
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 76 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 2.5.1

* changed Ethereum syntax got rid of getNextBlockHash (not implemented yet)

# 2.5.0

* added Ethereum
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# blockchain-rpc
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/202ed1ef51524b749560c0ffd78400f7)](https://www.codacy.com/manual/tokenanalyst/bitcoin-rpc?utm_source=github.com&utm_medium=referral&utm_content=tokenanalyst/bitcoin-rpc&utm_campaign=Badge_Grade)
[![License](http://img.shields.io/:license-Apache%202-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0.txt) [![GitHub stars](https://img.shields.io/github/stars/tokenanalyst/blockchain-rpc.svg?style=flat)](https://github.com/tokenanalyst/bitcoin-rpc/stargazers)
[![Maven Central](https://img.shields.io/maven-central/v/io.tokenanalyst/blockchain-rpc_2.13.svg)](https://search.maven.org/search?q=io.tokenanalyst%20bitcoin-rpc) <img src="https://typelevel.org/cats/img/cats-badge.svg" height="40px" align="right" alt="Cats friendly" /></a>
[![Maven Central](https://img.shields.io/maven-central/v/io.tokenanalyst/blockchain-rpc_2.13.svg)](https://search.maven.org/search?q=io.tokenanalyst%blockchain-rpc) <img src="https://typelevel.org/cats/img/cats-badge.svg" height="40px" align="right" alt="Cats friendly" /></a>
[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/blockchain-rpc)

blockchain-rpc is a typesafe RPC client for **Bitcoin**, **Ethereum** and **Omni** written in and to be used with 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](https://github.com/tokenanalyst/bitcoin-rpc/tree/master/src/main/scala/examples).
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](https://github.com/tokenanalyst/blockchain-rpc/tree/master/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.

## Add Dependency

Simply add the following dependency to your project.

```
libraryDependencies += "io.tokenanalyst" %% "blockchain-rpc" % "2.5.0",
libraryDependencies += "io.tokenanalyst" %% "blockchain-rpc" % "2.5.1"
```

## Example: Fetch Bitcoin Block
Expand Down
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
lazy val commonSettings = Seq(
organization := "io.tokenanalyst",
version := "2.5.0-SNAPSHOT",
version := "2.5.1",
scalaVersion := "2.12.10",
crossScalaVersions := Seq("2.13.1", "2.12.10"),
organizationHomepage := Some(
Expand Down Expand Up @@ -84,8 +84,8 @@ lazy val json = Seq(
)
lazy val scalaTest = Seq(
"org.scalatest" %% "scalatest" % scalaTestVersion % "test",
"com.softwaremill.diffx" %% "diffx-scalatest" % "0.3.14" % "test"
)

lazy val zmq = Seq(
"org.zeromq" % "jeromq" % "0.5.1"
)
Expand Down
8 changes: 1 addition & 7 deletions src/main/scala/ethereum/Instances.scala
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,6 @@ object Instances {
)
}

implicit val getNextBlockHashInstance =
new GetNextBlockHash[Ethereum] {
override def getNextBlockHash(a: Ethereum): IO[String] =
a.client.nextBlockHash()
}

implicit val getBestBlockHeightInstance =
new GetBestBlockHeight[Ethereum] {
override def getBestBlockHeight(a: Ethereum): IO[Long] =
Expand All @@ -114,7 +108,7 @@ object Instances {
.requestJson[BestBlockHeightRequest](new BestBlockHeightRequest)
} yield HexTools
.parseQuantity(json.asObject.get("result").get.asString.get)
.longValue()
.toLong
}

implicit val getTransactionsInstance =
Expand Down
5 changes: 1 addition & 4 deletions src/main/scala/ethereum/Syntax.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ import io.tokenanalyst.blockchainrpc.ethereum.Protocol.{BlockResponse, _}

object Syntax {
implicit class EthereumOps(b: Ethereum) {

def getNextBlockHash() =
implicitly[GetNextBlockHash[Ethereum]].getNextBlockHash(b)


def getReceiptByHash(hash: String) =
implicitly[GetReceipt[Ethereum, ReceiptResponse]].getReceipt(b, hash)

Expand Down
2 changes: 0 additions & 2 deletions src/main/scala/ethereum/UInt256.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package io.tokenanalyst.blockchainrpc.ethereum

import akka.util.ByteString

import scala.language.implicitConversions

// scalastyle:off number.of.methods
object UInt256 {

Expand Down
105 changes: 62 additions & 43 deletions src/test/scala/bitcoin/ProtocolSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ package io.tokenanalyst.blockchainrpc.test.bitcoin

import org.scalatest.matchers.should.Matchers
import org.scalatest.flatspec.AnyFlatSpec
import com.softwaremill.diffx.scalatest.DiffMatcher
import io.tokenanalyst.blockchainrpc.bitcoin.Protocol._
import io.tokenanalyst.blockchainrpc.Codecs._
import io.circe.generic.auto._
import io.circe.parser.decode

class ProtocolSpec extends AnyFlatSpec with Matchers with DiffMatcher {
class ProtocolSpec extends AnyFlatSpec with Matchers {

behavior of "Bitcoin protocol"

Expand All @@ -34,55 +33,75 @@ class ProtocolSpec extends AnyFlatSpec with Matchers with DiffMatcher {
{"result":{"hash":"00000000000000000009db93b0bd627158b665cd954cc274c056ad8b257c3f35","confirmations":1,"strippedsize":779713,"size":1654295,"weight":3993434,"height":607523,"version":536928256,"versionHex":"2000e000","merkleroot":"e1c20883d44eead043c4d8bf118520e61c72183145067d212af8fba319d67ba5","tx":["26de2820d5e15884a18c24426c6fafa6f527cca0f67a0266aa9737690b0bf3bc"],"time":1575992821,"mediantime":1575988911,"nonce":3271658646,"bits":"1715dbd2","difficulty":12876842089682.48,"chainwork":"00000000000000000000000000000000000000000ac014e49df992a6caa4cd1c","nTx":2273,"previousblockhash":"0000000000000000000280301806aa6a1e74ff64139f2dd03c3ac30802739c7a"},"error":null,"id":"curltest"}
"""
val decoded = decode[BlockResponse](response)
decoded.isRight shouldEqual true
decoded.right.get should matchTo(BlockResponse(
607523,
"00000000000000000009db93b0bd627158b665cd954cc274c056ad8b257c3f35",
Some("0000000000000000000280301806aa6a1e74ff64139f2dd03c3ac30802739c7a"),
3271658646L,
779713,
"e1c20883d44eead043c4d8bf118520e61c72183145067d212af8fba319d67ba5",
536928256,
3993434,
12876842089682.48,
"00000000000000000000000000000000000000000ac014e49df992a6caa4cd1c",
"1715dbd2",
1654295,
1575988911,
1575992821,
2273,
List("26de2820d5e15884a18c24426c6fafa6f527cca0f67a0266aa9737690b0bf3bc")
decoded shouldEqual (Right(
BlockResponse(
607523,
"00000000000000000009db93b0bd627158b665cd954cc274c056ad8b257c3f35",
Some(
"0000000000000000000280301806aa6a1e74ff64139f2dd03c3ac30802739c7a"
),
3271658646L,
779713,
"e1c20883d44eead043c4d8bf118520e61c72183145067d212af8fba319d67ba5",
536928256,
3993434,
12876842089682.48,
"00000000000000000000000000000000000000000ac014e49df992a6caa4cd1c",
"1715dbd2",
1654295,
1575988911,
1575992821,
2273,
List("26de2820d5e15884a18c24426c6fafa6f527cca0f67a0266aa9737690b0bf3bc")
)
))
}

it should "decode TransactionResponse" in {
val response =
"""
"""
{"result":{"txid":"3246fa6d081b32223a4097052b15594acc00372a9ce293b29f92086e19655888","hash":"20ed27407730078e01478e375910cd92ec4c99c0e1763a893df877e36a63f24f","version":1,"size":193,"vsize":111,"weight":442,"locktime":0,"vin":[{"txid":"eee52abb8ef949f0eaba5b331b4aa6de13601b00a93d99ed0cc75189be3d2a24","vout":1,"scriptSig":{"asm":"","hex":""},"txinwitness":["3045022100dc5b8d3643750a3b96defa6e452b268d25bdcaba9d75e3614aaa8f59c285bd3902206b44833a75111ce4bd487be86972def80db4ef8c2865e8b1c19cda5f9f7ee09101","035d6e3719f26bcc5381eca4e5c33ff3f9fd5b4e84450f863abbd83a584ccdc204"],"sequence":4294967295}],"vout":[{"value":0.00803580,"n":0,"scriptPubKey":{"asm":"OP_HASH160 ab974139080e159ac8af9fc0d9e2ef4885a1339d OP_EQUAL","hex":"a914ab974139080e159ac8af9fc0d9e2ef4885a1339d87","reqSigs":1,"type":"scripthash","addresses":["3HLJfiJLa5CnKQoAF3YeteidRjDMvY5upH"]}}],"hex":"01000000000101242a3dbe8951c70ced993da9001b6013dea64a1b335bbaeaf049f98ebb2ae5ee0100000000ffffffff01fc420c000000000017a914ab974139080e159ac8af9fc0d9e2ef4885a1339d8702483045022100dc5b8d3643750a3b96defa6e452b268d25bdcaba9d75e3614aaa8f59c285bd3902206b44833a75111ce4bd487be86972def80db4ef8c2865e8b1c19cda5f9f7ee0910121035d6e3719f26bcc5381eca4e5c33ff3f9fd5b4e84450f863abbd83a584ccdc20400000000","blockhash":"0000000000000000000e924f2fc7105362ce640d0865d10d314086c795d2cfde","confirmations":1,"time":1575996190,"blocktime":1575996190},"error":null,"id":"curltest"}
"""
val decoded = decode[TransactionResponse](response)
decoded.isRight shouldEqual true
decoded.right.get should matchTo(TransactionResponse(
Some(1),
"0000000000000000000e924f2fc7105362ce640d0865d10d314086c795d2cfde",
1575996190L,
"20ed27407730078e01478e375910cd92ec4c99c0e1763a893df877e36a63f24f",
"01000000000101242a3dbe8951c70ced993da9001b6013dea64a1b335bbaeaf049f98ebb2ae5ee0100000000ffffffff01fc420c000000000017a914ab974139080e159ac8af9fc0d9e2ef4885a1339d8702483045022100dc5b8d3643750a3b96defa6e452b268d25bdcaba9d75e3614aaa8f59c285bd3902206b44833a75111ce4bd487be86972def80db4ef8c2865e8b1c19cda5f9f7ee0910121035d6e3719f26bcc5381eca4e5c33ff3f9fd5b4e84450f863abbd83a584ccdc20400000000",
"3246fa6d081b32223a4097052b15594acc00372a9ce293b29f92086e19655888",
1575996190L,
111,
193,
442,
1,
List(TransactionResponseVin(
Some("eee52abb8ef949f0eaba5b331b4aa6de13601b00a93d99ed0cc75189be3d2a24"),
decoded shouldEqual Right(
TransactionResponse(
Some(1),
Some(TransactionResponseScriptSig("", "")),
None,
4294967295L)),
List(TransactionResponseVout(0.00803580, 0, TransactionResponseScript("OP_HASH160 ab974139080e159ac8af9fc0d9e2ef4885a1339d OP_EQUAL",
"a914ab974139080e159ac8af9fc0d9e2ef4885a1339d87", Some(1), "scripthash", Some(List("3HLJfiJLa5CnKQoAF3YeteidRjDMvY5upH"))))),
0
))
"0000000000000000000e924f2fc7105362ce640d0865d10d314086c795d2cfde",
1575996190L,
"20ed27407730078e01478e375910cd92ec4c99c0e1763a893df877e36a63f24f",
"01000000000101242a3dbe8951c70ced993da9001b6013dea64a1b335bbaeaf049f98ebb2ae5ee0100000000ffffffff01fc420c000000000017a914ab974139080e159ac8af9fc0d9e2ef4885a1339d8702483045022100dc5b8d3643750a3b96defa6e452b268d25bdcaba9d75e3614aaa8f59c285bd3902206b44833a75111ce4bd487be86972def80db4ef8c2865e8b1c19cda5f9f7ee0910121035d6e3719f26bcc5381eca4e5c33ff3f9fd5b4e84450f863abbd83a584ccdc20400000000",
"3246fa6d081b32223a4097052b15594acc00372a9ce293b29f92086e19655888",
1575996190L,
111,
193,
442,
1,
List(
TransactionResponseVin(
Some(
"eee52abb8ef949f0eaba5b331b4aa6de13601b00a93d99ed0cc75189be3d2a24"
),
Some(1),
Some(TransactionResponseScriptSig("", "")),
None,
4294967295L
)
),
List(
TransactionResponseVout(
0.00803580,
0,
TransactionResponseScript(
"OP_HASH160 ab974139080e159ac8af9fc0d9e2ef4885a1339d OP_EQUAL",
"a914ab974139080e159ac8af9fc0d9e2ef4885a1339d87",
Some(1),
"scripthash",
Some(List("3HLJfiJLa5CnKQoAF3YeteidRjDMvY5upH"))
)
)
),
0
)
)
}
}
22 changes: 7 additions & 15 deletions src/test/scala/ethereum/ProtocolSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ package io.tokenanalyst.blockchainrpc.test.ethereum

import org.scalatest.matchers.should.Matchers
import org.scalatest.flatspec.AnyFlatSpec
import com.softwaremill.diffx.scalatest.DiffMatcher
import io.tokenanalyst.blockchainrpc.ethereum.Protocol.{BlockResponse, _}
import io.tokenanalyst.blockchainrpc.Codecs._
import io.circe.generic.auto._
import io.circe.parser.decode

class ProtocolSpec extends AnyFlatSpec with Matchers with DiffMatcher {
class ProtocolSpec extends AnyFlatSpec with Matchers {

behavior of "Ethereum protocol"

Expand Down Expand Up @@ -67,10 +66,8 @@ class ProtocolSpec extends AnyFlatSpec with Matchers with DiffMatcher {
"id": 1
}
"""

val decoded = decode[ReceiptResponse](response)
decoded.isRight shouldEqual true
decoded.right.get should matchTo(
decoded shouldEqual Right(
ReceiptResponse(
"0x3a1fba5abd9d41457944e91ed097e039b7b12d3d7ba324a3f422db2277a48e28",
"0xcb3d",
Expand Down Expand Up @@ -129,8 +126,7 @@ class ProtocolSpec extends AnyFlatSpec with Matchers with DiffMatcher {
"""

val decoded = decode[ReceiptResponse](response)
decoded.isRight shouldEqual true
decoded.right.get should matchTo(
decoded shouldEqual Right(
ReceiptResponse(
"0x67c0303244ae4beeec329e0c66198e8db8938a94d15a366c7514626528abfc8c",
"0x6914b0",
Expand Down Expand Up @@ -173,8 +169,7 @@ class ProtocolSpec extends AnyFlatSpec with Matchers with DiffMatcher {
"""

val decoded = decode[ReceiptResponse](response)
decoded.isRight shouldEqual true
decoded.right.get should matchTo(
decoded shouldEqual Right(
ReceiptResponse(
"0x67c0303244ae4beeec329e0c66198e8db8938a94d15a366c7514626528abfc8c",
"0x6914b0",
Expand Down Expand Up @@ -217,8 +212,7 @@ class ProtocolSpec extends AnyFlatSpec with Matchers with DiffMatcher {
"""

val decoded = decode[ReceiptResponse](response)
decoded.isRight shouldEqual true
decoded.right.get should matchTo(
decoded shouldEqual Right(
ReceiptResponse(
"0x67c0303244ae4beeec329e0c66198e8db8938a94d15a366c7514626528abfc8c",
"0x6914b0",
Expand All @@ -243,8 +237,7 @@ class ProtocolSpec extends AnyFlatSpec with Matchers with DiffMatcher {
"""

val decoded = decode[TransactionResponse](response)
decoded.isRight shouldEqual true
decoded.right.get should matchTo(
decoded shouldEqual Right(
TransactionResponse(
"0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2",
"0x5daf3b",
Expand Down Expand Up @@ -276,8 +269,7 @@ class ProtocolSpec extends AnyFlatSpec with Matchers with DiffMatcher {
{"jsonrpc":"2.0","result":{"author":"0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c","difficulty":"0x89e4c5695f464","extraData":"0x5050594520737061726b706f6f6c2d6574682d636e2d687a32","gasLimit":"0x9879a1","gasUsed":"0x0","hash":"0xd5e3eff1778c4735fb2a51c5c4e92bec32f9363ba23285d6d94e62c26b7c0884","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c","mixHash":"0x1c0540069d772ce8fe02415a5988ad5b90b389a13d1a0643087ea75487007aef","nonce":"0xdf2bd7300001a5e8","number":"0x865801","parentHash":"0x65144a20fd4d1b2faa86d90d35b9cfcc87b67f48b21ad439167d80429b719258","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sealFields":["0xa01c0540069d772ce8fe02415a5988ad5b90b389a13d1a0643087ea75487007aef","0x88df2bd7300001a5e8"],"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x21f","stateRoot":"0x4b909ee750967307134206db327f361b1877bffbdbd2c1100449dd4759c350c9","timestamp":"0x5db1e4c3","totalDifficulty":"0x2a7666ad70f09d1728f","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]},"id":1}
"""
val decoded = decode[BlockResponse](response)
decoded.isRight shouldEqual true
decoded.right.get should matchTo(
decoded shouldEqual Right(
new BlockResponse(
"0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c",
"0x89e4c5695f464",
Expand Down

0 comments on commit 7b2ac7a

Please sign in to comment.