Merge pull request #171 from nkohen/rpc

Rpc
This commit is contained in:
Chris Stewart 2018-07-01 10:29:28 -04:00 committed by GitHub
commit b0229543c9
13 changed files with 1117 additions and 5 deletions

View file

@ -6,7 +6,8 @@ lazy val root = project
core,
coreGen,
coreTest,
zmq
zmq,
rpc
)
lazy val secp256k1jni = project
@ -42,4 +43,12 @@ lazy val zmq = project
core
)
lazy val rpc = project
.in(file("rpc"))
.enablePlugins()
.dependsOn(
core,
coreGen % "test->test"
)
publishArtifact in root := false

View file

@ -1,9 +1,10 @@
name := "bitcoin-s-core"
libraryDependencies ++= Deps.core
testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "2")
testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck,
"-verbosity",
"2")
//test in assembly := {}
@ -17,4 +18,5 @@ coverageMinimum := 90
coverageFailOnMinimum := true
assemblyOption in assembly := (assemblyOption in assembly).value.copy(includeScala = false)
assemblyOption in assembly := (assemblyOption in assembly).value
.copy(includeScala = false)

View file

@ -9,12 +9,18 @@ object Deps {
val slf4j = "1.7.5"
val spray = "1.3.2"
val zeromq = "0.4.3"
val akkav = "10.1.1"
val akkaStreamv = "2.5.12"
val playv = "2.6.9"
}
object Compile {
val bouncycastle = "org.bouncycastle" % "bcprov-jdk15on" % V.bouncyCastle
val slf4j = "org.slf4j" % "slf4j-api" % V.slf4j % "provided"
val zeromq = "org.zeromq" % "jeromq" % V.zeromq
val akkaHttp = "com.typesafe.akka" %% "akka-http" % V.akkav
val akkaStream = "com.typesafe.akka" %% "akka-stream" % V.akkaStreamv
val playJson = "com.typesafe.play" %% "play-json" % V.playv
}
object Test {
@ -24,6 +30,8 @@ object Deps {
val scalacheck = "org.scalacheck" %% "scalacheck" % V.scalacheck % "test" withSources() withJavadoc()
val scalaTest = "org.scalatest" %% "scalatest" % V.scalaTest % "test"
val spray = "io.spray" %% "spray-json" % V.spray % "test"
val akkaHttp = "com.typesafe.akka" %% "akka-http-testkit" % V.akkav % "test"
val akkaStream = "com.typesafe.akka" %% "akka-stream-testkit" % V.akkaStreamv % "test"
}
val core = List(
@ -51,4 +59,16 @@ object Deps {
Test.scalacheck,
Test.scalaTest
)
val rpc = List(
Compile.akkaHttp,
Compile.akkaStream,
Compile.playJson,
Compile.slf4j,
Test.akkaHttp,
Test.akkaStream,
Test.logback,
Test.scalaTest,
Test.scalacheck
)
}

View file

@ -8,4 +8,5 @@ addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.3.5")
addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.1.0")
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.2")
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.2")

View file

@ -0,0 +1,38 @@
package org.bitcoins.rpc.config
import java.io.File
/**
* Created by chris on 5/2/17.
*/
sealed trait AuthCredentials {
/** The directory where our bitcoin.conf file is located */
def datadir: File
/** rpcusername field in our bitcoin.conf file */
def username: String
/** rpcpassword field in our bitcoin.conf file */
def password: String
}
object AuthCredentials {
private case class AuthCredentialsImpl(
username: String,
password: String,
datadir: File)
extends AuthCredentials
def apply(username: String, password: String): AuthCredentials = {
val defaultDataDir = new File(System.getProperty("user.home") + "/.bitcoin")
AuthCredentials(username, password, defaultDataDir)
}
def apply(
username: String,
password: String,
datadir: File): AuthCredentials = {
AuthCredentialsImpl(username, password, datadir)
}
}

View file

@ -0,0 +1,33 @@
package org.bitcoins.rpc.config
import java.net.URI
import org.bitcoins.core.config.NetworkParameters
/**
* Created by chris on 4/29/17.
*/
sealed trait DaemonInstance {
def network: NetworkParameters
def uri: URI
def rpcUri: URI
def authCredentials: AuthCredentials
}
object DaemonInstance {
private case class DaemonInstanceImpl(
network: NetworkParameters,
uri: URI,
rpcUri: URI,
authCredentials: AuthCredentials)
extends DaemonInstance
def apply(
network: NetworkParameters,
uri: URI,
rpcUri: URI,
authCredentials: AuthCredentials): DaemonInstance = {
DaemonInstanceImpl(network, uri, rpcUri, authCredentials)
}
}

View file

@ -0,0 +1,182 @@
package org.bitcoins.rpc.jsonmodels
import org.bitcoins.core.crypto.DoubleSha256Digest
import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.core.number.{Int32, UInt32}
import org.bitcoins.core.wallet.fee.BitcoinFeeUnit
sealed abstract class BlockchainResult
case class GetBlockResult(
hash: DoubleSha256Digest,
confirmations: Int,
strippedsize: Int,
size: Int,
weight: Int,
height: Int,
version: Int,
versionHex: Int32,
merkleroot: DoubleSha256Digest,
tx: Vector[DoubleSha256Digest],
time: UInt32,
mediantime: UInt32,
nonce: UInt32,
bits: UInt32,
difficulty: BigDecimal,
chainwork: String,
previousblockhash: Option[DoubleSha256Digest],
nextblockhash: Option[DoubleSha256Digest])
extends BlockchainResult
case class GetBlockWithTransactionsResult(
hash: DoubleSha256Digest,
confirmations: Int,
strippedsize: Int,
size: Int,
weight: Int,
height: Int,
version: Int,
versionHex: Int32,
merkleroot: DoubleSha256Digest,
tx: Vector[RpcTransaction],
time: UInt32,
mediantime: UInt32,
nonce: UInt32,
bits: UInt32,
difficulty: BigDecimal,
chainwork: String,
previousblockhash: Option[DoubleSha256Digest],
nextblockhash: Option[DoubleSha256Digest])
extends BlockchainResult
case class GetBlockChainInfoResult(
chain: String,
blocks: Int,
headers: Int,
bestblockhash: DoubleSha256Digest,
difficulty: BigDecimal,
mediantime: Int,
verificationprogress: BigDecimal,
initialblockdownload: Boolean,
chainwork: String, // How should this be handled?
size_on_disk: Int,
pruned: Boolean,
pruneheight: Option[Int],
softforks: Vector[Softfork],
bip9_softforks: Map[String, Bip9Softfork],
warnings: String)
extends BlockchainResult
case class Softfork(
id: String,
version: Int,
enforce: Option[Map[String, SoftforkProgress]],
reject: SoftforkProgress)
extends BlockchainResult
case class SoftforkProgress(
status: Option[Boolean],
found: Option[Int],
required: Option[Int],
window: Option[Int])
extends BlockchainResult
case class Bip9Softfork(
status: String,
bit: Option[Int],
startTime: Int,
timeout: BigInt,
since: Int)
extends BlockchainResult
case class GetBlockHeaderResult(
hash: DoubleSha256Digest,
confirmations: Int,
height: Int,
version: Int,
versionHex: Int32,
merkleroot: DoubleSha256Digest,
time: UInt32,
mediantime: UInt32,
nonce: UInt32,
bits: UInt32,
difficulty: BigDecimal,
chainwork: String,
previousblockhash: Option[DoubleSha256Digest],
nextblockhash: Option[DoubleSha256Digest])
extends BlockchainResult
case class ChainTip(
height: Int,
hash: DoubleSha256Digest,
branchlen: Int,
status: String)
extends BlockchainResult
case class GetChainTxStatsResult(
time: UInt32,
txcount: Int,
window_block_count: Int,
window_tx_count: Option[Int],
window_interval: Option[UInt32],
txrate: Option[BigDecimal])
extends BlockchainResult
case class GetMemPoolResult(
size: Int,
fee: Option[Bitcoins],
modifiedfee: Option[Bitcoins],
time: UInt32,
height: Int,
descendantcount: Int,
descendantsize: Int,
descendantfees: Option[Bitcoins],
ancestorcount: Int,
ancestorsize: Int,
ancestorfees: Option[Bitcoins],
wtxid: DoubleSha256Digest,
depends: Vector[DoubleSha256Digest])
extends BlockchainResult
case class GetMemPoolEntryResult(
size: Int,
fee: Bitcoins,
modifiedfee: Bitcoins,
time: UInt32,
height: Int,
descendantcount: Int,
descendantsize: Int,
descendantfees: Bitcoins, // Should be BitcoinFeeUnit
ancestorcount: Int,
ancestorsize: Int,
ancestorfees: Bitcoins, // Should be BitcoinFeeUnit
depends: Option[Vector[DoubleSha256Digest]])
extends BlockchainResult
case class GetMemPoolInfoResult(
size: Int,
bytes: Int,
usage: Int,
maxmempool: Int,
mempoolminfee: BitcoinFeeUnit,
minrelaytxfee: Bitcoins)
extends BlockchainResult
case class GetTxOutResult(
bestblock: DoubleSha256Digest,
confirmations: Int,
value: Bitcoins,
scriptPubKey: RpcScriptPubKey,
coinbase: Boolean)
extends BlockchainResult
case class GetTxOutSetInfoResult(
height: Int,
bestblock: DoubleSha256Digest,
transactions: Int,
txouts: Int,
bogosize: Int,
hash_serialized_2: DoubleSha256Digest,
disk_size: Int,
total_amount: Bitcoins)
extends BlockchainResult

View file

@ -0,0 +1,100 @@
package org.bitcoins.rpc.jsonmodels
import java.net.URI
import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.core.number.{UInt32, UInt64}
sealed abstract class NetworkResult
case class Node(
addednode: URI,
connected: Option[Boolean],
addresses: Option[Vector[NodeAddress]])
extends NetworkResult
case class NodeAddress(address: URI, connected: String) extends NetworkResult
case class GetNetTotalsResult(
totalbytesrecv: Int,
totalbytessent: Int,
timemillis: UInt64,
uploadtarget: NetTarget)
extends NetworkResult
case class NetTarget(
timeframe: UInt32,
target: Int,
target_reached: Boolean,
serve_historical_blocks: Boolean,
bytes_left_in_cycle: Int,
time_left_in_cycle: UInt32)
extends NetworkResult
case class GetNetworkInfoResult(
version: Int,
subversion: String,
protocolversion: Int,
localservices: String,
localrelay: Boolean,
timeoffset: Int,
networkactive: Boolean,
connections: Int,
networks: Vector[Network],
relayfee: Bitcoins,
incrementalfee: Bitcoins,
localadresses: Option[Vector[NetworkAddress]],
warnings: String)
extends NetworkResult
case class Network(
name: String,
limited: Boolean,
reachable: Boolean,
proxy: String,
proxy_randomize_credentials: Boolean)
extends NetworkResult
case class NetworkAddress(address: String, port: Int, score: Int)
extends NetworkResult
case class Peer(
id: Int,
networkInfo: PeerNetworkInfo,
version: Int,
subver: String,
inbound: Boolean,
addnode: Boolean,
startingheight: Int,
banscore: Int,
synced_headers: Int,
synced_blocks: Int,
inflight: Vector[Int],
whitelisted: Boolean,
bytessent_per_msg: Map[String, Int],
bytesrecv_per_msg: Map[String, Int])
extends NetworkResult
case class PeerNetworkInfo(
addr: URI,
addrbind: URI,
addrlocal: Option[URI],
services: String,
relaytxes: Boolean,
lastsend: UInt32,
lastrecv: UInt32,
bytessent: Int,
bytesrecv: Int,
conntime: UInt32,
timeoffset: Int,
pingtime: Option[BigDecimal],
minping: Option[BigDecimal],
pingwait: Option[BigDecimal])
extends NetworkResult
case class NodeBan(
address: URI,
banned_until: UInt32,
ban_created: UInt32,
ban_reason: String)
extends NetworkResult

View file

@ -0,0 +1,97 @@
package org.bitcoins.rpc.jsonmodels
import org.bitcoins.core.crypto.{
DoubleSha256Digest,
ECPublicKey,
Sha256Hash160Digest
}
import org.bitcoins.core.currency.Satoshis
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.core.protocol.script.ScriptPubKey
import org.bitcoins.core.protocol.transaction.Transaction
import org.bitcoins.core.wallet.fee.BitcoinFeeUnit
import play.api.libs.json.JsObject
sealed abstract class OtherResult
case class GetBlockTemplateResult(
capabilities: Vector[String],
version: Int,
rules: Vector[String],
vbavailable: Map[String, Int], // Is this Int or BigDecimal?
vbrequired: Int,
previousblockhash: DoubleSha256Digest,
transactions: Vector[BlockTransaction],
coinbaseaux: Map[String, String],
coinbasevalue: Satoshis,
longpollid: String, // What is this?
coinbasetxn: Option[JsObject],
target: String, // What should this be?
mintime: UInt32,
mutable: Vector[String],
noncerange: String,
sigoplimit: Int,
sizelimit: Int,
weightlimit: Int,
curtime: UInt32,
bits: String, // What should this be?
height: Int)
extends OtherResult
case class BlockTransaction(
data: Transaction,
txid: DoubleSha256Digest,
hash: DoubleSha256Digest,
depends: Vector[Int],
fee: Satoshis,
sigops: Int,
weight: Int,
required: Option[Boolean])
extends OtherResult
case class GetMiningInfoResult(
blocks: Int,
currentblockweight: Int,
currentblocktx: Int,
difficulty: BigDecimal,
networkhashps: BigDecimal,
pooledtx: Int,
chain: String,
warnings: String)
extends OtherResult
case class GetMemoryInfoResult(locked: MemoryManager) extends OtherResult
case class MemoryManager(
used: Int,
free: Int,
total: Int,
locked: Int,
chunks_used: Int,
chunks_free: Int)
extends OtherResult
case class ValidateAddressResult(
isvalid: Boolean,
address: Option[BitcoinAddress],
scriptPubKey: Option[ScriptPubKey],
ismine: Option[Boolean],
iswatchonly: Option[Boolean],
isscript: Option[Boolean],
script: Option[ScriptPubKey],
hex: Option[String],
addresses: Option[Vector[BitcoinAddress]],
sigrequired: Option[Int],
pubkey: Option[ECPublicKey],
iscompressed: Option[Boolean],
account: Option[String],
hdkeypath: Option[String],
hdmasterkeyid: Option[Sha256Hash160Digest])
extends OtherResult
case class EstimateSmartFeeResult(
feerate: Option[BitcoinFeeUnit],
errors: Option[Vector[String]],
blocks: Int)
extends OtherResult

View file

@ -0,0 +1,92 @@
package org.bitcoins.rpc.jsonmodels
import org.bitcoins.core.crypto.DoubleSha256Digest
import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.{BitcoinAddress, P2PKHAddress, P2SHAddress}
import org.bitcoins.core.protocol.script.{ScriptPubKey, ScriptSignature}
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionInput}
sealed abstract class RawTransactionResult
case class RpcTransaction(
txid: DoubleSha256Digest,
hash: DoubleSha256Digest,
version: Int,
size: Int,
vsize: Int,
locktime: UInt32,
vin: Vector[TransactionInput],
vout: Vector[RpcTransactionOutput],
hex: Option[Transaction])
extends RawTransactionResult
case class RpcTransactionOutput(
value: Bitcoins,
n: Int,
scriptPubKey: RpcScriptPubKey)
extends RawTransactionResult
case class RpcScriptPubKey(
asm: String,
hex: String,
reqSigs: Option[Int],
scriptType: String,
addresses: Option[Vector[BitcoinAddress]])
extends RawTransactionResult
case class DecodeScriptResult(
asm: String,
typeOfScript: Option[String],
reqSigs: Option[Int],
addresses: Option[Vector[P2PKHAddress]],
p2sh: P2SHAddress)
extends RawTransactionResult
case class FundRawTransactionResult(
hex: Transaction,
fee: Bitcoins,
changepos: Int)
extends RawTransactionResult
case class GetRawTransactionResult(
in_active_blockchain: Option[Boolean],
hex: Transaction,
txid: DoubleSha256Digest,
hash: DoubleSha256Digest,
size: Int,
vsize: Int,
version: Int,
locktime: UInt32,
vin: Vector[GetRawTransactionVin],
vout: Vector[RpcTransactionOutput],
blockhash: DoubleSha256Digest,
confirmations: Int,
time: UInt32,
blocktime: UInt32)
extends RawTransactionResult
case class GetRawTransactionVin(
txid: Option[DoubleSha256Digest],
vout: Option[Int],
scriptSig: Option[GetRawTransactionScriptSig],
sequence: Option[BigDecimal],
txinwitness: Option[Vector[String]] // Should be TransactionWitness?
) extends RawTransactionResult
case class GetRawTransactionScriptSig(asm: String, hex: ScriptSignature)
extends RawTransactionResult
case class SignRawTransactionResult(
hex: Transaction,
complete: Boolean,
errors: Option[Vector[SignRawTransactionError]])
extends RawTransactionResult
case class SignRawTransactionError(
txid: DoubleSha256Digest,
vout: Int,
scriptSig: ScriptPubKey,
sequence: UInt32,
error: String)
extends RawTransactionResult

View file

@ -0,0 +1,174 @@
package org.bitcoins.rpc.jsonmodels
import java.io.File
import org.bitcoins.core.crypto.{DoubleSha256Digest, Sha256Hash160Digest}
import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.core.protocol.script.ScriptPubKey
import org.bitcoins.core.protocol.transaction.Transaction
import org.bitcoins.core.wallet.fee.BitcoinFeeUnit
sealed abstract class WalletResult
case class MultiSigResult(address: BitcoinAddress, redeemScript: ScriptPubKey)
extends WalletResult
case class BumpFeeResult(
txid: DoubleSha256Digest,
origfee: Bitcoins,
fee: Bitcoins, // TODO: Should be BitcoinFeeUnit
errors: Vector[String])
extends WalletResult
case class GetTransactionResult(
amount: Bitcoins,
fee: Option[Bitcoins],
confirmations: Int,
generated: Option[Boolean],
blockhash: Option[DoubleSha256Digest],
blockindex: Option[Int],
blocktime: Option[UInt32],
txid: DoubleSha256Digest,
walletconflicts: Vector[DoubleSha256Digest],
time: UInt32,
timereceived: UInt32,
bip125_replaceable: String,
comment: Option[String],
to: Option[String],
details: Vector[TransactionDetails],
hex: Transaction)
extends WalletResult
case class TransactionDetails(
involvesWatchonly: Option[Boolean],
account: Option[String],
address: Option[BitcoinAddress],
category: String,
amount: Bitcoins,
vout: Int,
fee: Option[Bitcoins],
abandoned: Option[Boolean])
extends WalletResult
case class GetWalletInfoResult(
walletname: String,
walletversion: Int,
balance: Bitcoins,
unconfirmed_balance: Bitcoins,
immature_balance: Bitcoins,
txcount: Int,
keypoololdest: UInt32,
keypoolsize: Int,
keypoolsize_hd_internal: Int,
paytxfee: BitcoinFeeUnit,
hdmasterkeyid: Sha256Hash160Digest,
unlocked_until: Option[Int])
extends WalletResult
case class ImportMultiResult(success: Boolean, error: Option[ImportMultiError])
extends WalletResult
case class ImportMultiError(code: Int, message: String) extends WalletResult
case class RpcAddress(
address: BitcoinAddress,
balance: Bitcoins,
account: Option[String])
extends WalletResult
case class RpcAccount(
involvesWatchonly: Boolean,
account: String,
amount: Bitcoins,
confirmations: Int)
extends WalletResult
case class DumpWalletResult(filename: File)
case class RescanBlockChainResult(start_height: Int, stop_height: Int)
extends WalletResult
case class ReceivedAddress(
involvesWatchonly: Option[Boolean],
address: BitcoinAddress,
account: String,
amount: Bitcoins,
confirmations: Int,
label: String,
txids: Vector[DoubleSha256Digest])
extends WalletResult
case class ReceivedAccount(
involvesWatchonly: Option[Boolean],
account: String,
amount: Bitcoins,
confirmations: Int,
lable: Option[String])
extends WalletResult
case class ListSinceBlockResult(
transactions: Vector[Payment],
lastblock: DoubleSha256Digest)
extends WalletResult
case class Payment(
involvesWatchonly: Option[Boolean],
account: Option[String],
address: Option[BitcoinAddress],
category: String,
amount: Bitcoins,
vout: Int,
fee: Option[Bitcoins],
confirmations: Int,
generated: Option[Boolean],
blockhash: Option[DoubleSha256Digest],
blockindex: Option[Int],
blocktime: Option[UInt32],
txid: DoubleSha256Digest,
walletconflicts: Vector[DoubleSha256Digest],
time: UInt32,
timereceived: UInt32,
bip125_replaceable: String,
comment: Option[String],
to: Option[String])
extends WalletResult
case class ListTransactionsResult(
account: Option[String],
address: Option[BitcoinAddress],
category: String,
amount: Bitcoins,
label: Option[String],
vout: Option[Int],
fee: Option[Bitcoins],
confirmations: Option[Int],
trusted: Option[Boolean],
generated: Option[Boolean],
blockhash: Option[DoubleSha256Digest],
blockindex: Option[Int],
blocktime: Option[UInt32],
txid: Option[DoubleSha256Digest],
walletconflicts: Option[Vector[DoubleSha256Digest]],
time: UInt32,
timereceived: Option[UInt32],
comment: Option[String],
to: Option[String],
otheraccount: Option[String],
bip125_replaceable: String,
abandoned: Option[Boolean])
extends WalletResult
case class UnspentOutput(
txid: DoubleSha256Digest,
vout: Int,
address: Option[BitcoinAddress],
account: Option[String],
scriptPubKey: Option[ScriptPubKey],
reedemScript: Option[ScriptPubKey],
amount: Bitcoins,
confirmations: Int,
spendable: Boolean,
solvable: Boolean)
extends WalletResult

View file

@ -0,0 +1,311 @@
package org.bitcoins.rpc.serializers
import java.io.File
import java.net.{InetAddress, URI}
import org.bitcoins.core.crypto.{
DoubleSha256Digest,
ECPublicKey,
Sha256Hash160Digest
}
import org.bitcoins.core.currency.{Bitcoins, Satoshis}
import org.bitcoins.core.number.{Int32, UInt32, UInt64}
import org.bitcoins.core.protocol.{
Address,
BitcoinAddress,
P2PKHAddress,
P2SHAddress
}
import org.bitcoins.core.protocol.blockchain.{Block, BlockHeader, MerkleBlock}
import org.bitcoins.core.protocol.script.{ScriptPubKey, ScriptSignature}
import org.bitcoins.core.protocol.transaction.{
Transaction,
TransactionInput,
TransactionOutPoint
}
import org.bitcoins.core.wallet.fee.BitcoinFeeUnit
import org.bitcoins.rpc.jsonmodels._
import org.bitcoins.rpc.serializers.JsonReaders._
import org.bitcoins.rpc.serializers.JsonWriters._
import play.api.libs.json._
import play.api.libs.functional.syntax._
object JsonSerializers {
implicit val bigIntReads: Reads[BigInt] = BigIntReads
// Internal Types
implicit val doubleSha256DigestReads: Reads[DoubleSha256Digest] =
DoubleSha256DigestReads
implicit val bitcoinsReads: Reads[Bitcoins] = BitcoinsReads
implicit val satoshisReads: Reads[Satoshis] = SatoshisReads
implicit val blockHeaderReads: Reads[BlockHeader] = BlockHeaderReads
implicit val int32Reads: Reads[Int32] = Int32Reads
implicit val uInt32Reads: Reads[UInt32] = UInt32Reads
implicit val uInt64Reads: Reads[UInt64] = UInt64Reads
implicit val addressReads: Reads[Address] = AddressReads
implicit val unitReads: Reads[Unit] = UnitReads
implicit val inetAddressReads: Reads[InetAddress] = InetAddressReads
implicit val scriptPubKeyReads: Reads[ScriptPubKey] = ScriptPubKeyReads
implicit val blockReads: Reads[Block] = BlockReads
implicit val sha256Hash160DigestReads: Reads[Sha256Hash160Digest] =
Sha256Hash160DigestReads
implicit val eCPublicKeyReads: Reads[ECPublicKey] = ECPublicKeyReads
implicit val p2PKHAddressReads: Reads[P2PKHAddress] = P2PKHAddressReads
implicit val p2SHAddressReads: Reads[P2SHAddress] = P2SHAddressReads
implicit val transactionInputReads: Reads[TransactionInput] =
TransactionInputReads
implicit val bitcoinAddressReads: Reads[BitcoinAddress] = BitcoinAddressReads
implicit val merkleBlockReads: Reads[MerkleBlock] = MerkleBlockReads
implicit val transactionReads: Reads[Transaction] = TransactionReads
implicit val transactionOutPointReads: Reads[TransactionOutPoint] =
TransactionOutPointReads
implicit val bitcoinFeeUnitReads: Reads[BitcoinFeeUnit] = BitcoinFeeUnitReads
implicit val fileReads: Reads[File] = FileReads
implicit val uRIReads: Reads[URI] = URIReads
implicit val scriptSignatureReads: Reads[ScriptSignature] =
ScriptSignatureReads
implicit val bitcoinsWrites: Writes[Bitcoins] = BitcoinsWrites
implicit val bitcoinAddressWrites: Writes[BitcoinAddress] =
BitcoinAddressWrites
implicit val doubleSha256DigestWrites: Writes[DoubleSha256Digest] =
DoubleSha256DigestWrites
implicit val scriptPubKeyWrites: Writes[ScriptPubKey] = ScriptPubKeyWrites
implicit val transactionInputWrites: Writes[TransactionInput] =
TransactionInputWrites
implicit val uInt32Writes: Writes[UInt32] = UInt32Writes
implicit val transactionWrites: Writes[Transaction] = TransactionWrites
// Transaction Models
implicit val rpcScriptPubKeyReads: Reads[RpcScriptPubKey] =
((__ \ "asm").read[String] and
(__ \ "hex").read[String] and
(__ \ "reqSigs").readNullable[Int] and
(__ \ "type").read[String] and
(__ \ "addresses").readNullable[Vector[BitcoinAddress]])(RpcScriptPubKey)
implicit val rpcTransactionOutputReads: Reads[RpcTransactionOutput] =
Json.reads[RpcTransactionOutput]
implicit val rpcTransactionReads: Reads[RpcTransaction] =
Json.reads[RpcTransaction]
implicit val decodeScriptResultReads: Reads[DecodeScriptResult] =
((__ \ "asm").read[String] and
(__ \ "type").readNullable[String] and
(__ \ "reqSigs").readNullable[Int] and
(__ \ "addresses").readNullable[Vector[P2PKHAddress]] and
(__ \ "p2sh").read[P2SHAddress])(DecodeScriptResult)
implicit val fundRawTransactionResultReads: Reads[FundRawTransactionResult] =
Json.reads[FundRawTransactionResult]
implicit val getRawTransactionScriptSigReads: Reads[
GetRawTransactionScriptSig] = Json.reads[GetRawTransactionScriptSig]
implicit val getRawTransactionVinReads: Reads[GetRawTransactionVin] =
Json.reads[GetRawTransactionVin]
implicit val getRawTransactionResultReads: Reads[GetRawTransactionResult] =
Json.reads[GetRawTransactionResult]
implicit val signRawTransactionErrorReads: Reads[SignRawTransactionError] =
Json.reads[SignRawTransactionError]
implicit val signRawTransactionResultReads: Reads[SignRawTransactionResult] =
Json.reads[SignRawTransactionResult]
// Network Models
implicit val nodeAddressReads: Reads[NodeAddress] = Json.reads[NodeAddress]
implicit val nodeReads: Reads[Node] = Json.reads[Node]
implicit val netTargetReads: Reads[NetTarget] = Json.reads[NetTarget]
implicit val getNetTotalsResultReads: Reads[GetNetTotalsResult] =
Json.reads[GetNetTotalsResult]
implicit val networkReads: Reads[Network] = Json.reads[Network]
implicit val networkAddressReads: Reads[NetworkAddress] =
Json.reads[NetworkAddress]
implicit val networkInfoReads: Reads[GetNetworkInfoResult] =
Json.reads[GetNetworkInfoResult]
implicit val peerNetworkInfoReads: Reads[PeerNetworkInfo] =
Json.reads[PeerNetworkInfo]
implicit val peerReads: Reads[Peer] = ((__ \ "id").read[Int] and
__.read[PeerNetworkInfo] and
(__ \ "version").read[Int] and
(__ \ "subver").read[String] and
(__ \ "inbound").read[Boolean] and
(__ \ "addnode").read[Boolean] and
(__ \ "startingheight").read[Int] and
(__ \ "banscore").read[Int] and
(__ \ "synced_headers").read[Int] and
(__ \ "synced_blocks").read[Int] and
(__ \ "inflight").read[Vector[Int]] and
(__ \ "whitelisted").read[Boolean] and
(__ \ "bytessent_per_msg").read[Map[String, Int]] and
(__ \ "bytesrecv_per_msg").read[Map[String, Int]])(Peer)
implicit val nodeBanReads: Reads[NodeBan] = Json.reads[NodeBan]
// Blockchain Models
implicit val getBlockResultReads: Reads[GetBlockResult] =
Json.reads[GetBlockResult]
implicit val getBlockWithTransactionsResultReads: Reads[
GetBlockWithTransactionsResult] = Json.reads[GetBlockWithTransactionsResult]
implicit val softforkProgressReads: Reads[SoftforkProgress] =
Json.reads[SoftforkProgress]
implicit val softforkReads: Reads[Softfork] = Json.reads[Softfork]
implicit val bip9SoftforkReads: Reads[Bip9Softfork] = Json.reads[Bip9Softfork]
implicit val getBlockChainInfoResultReads: Reads[GetBlockChainInfoResult] =
Json.reads[GetBlockChainInfoResult]
implicit val blockHeaderFormattedReads: Reads[GetBlockHeaderResult] =
Json.reads[GetBlockHeaderResult]
implicit val chainTipReads: Reads[ChainTip] = Json.reads[ChainTip]
implicit val getChainTxStatsResultReads: Reads[GetChainTxStatsResult] =
Json.reads[GetChainTxStatsResult]
implicit val getMemPoolResultReads: Reads[GetMemPoolResult] =
Json.reads[GetMemPoolResult]
implicit val getMemPoolEntryResultReads: Reads[GetMemPoolEntryResult] =
Json.reads[GetMemPoolEntryResult]
implicit val getMemPoolInfoResultReads: Reads[GetMemPoolInfoResult] =
Json.reads[GetMemPoolInfoResult]
implicit val getTxOutResultReads: Reads[GetTxOutResult] =
Json.reads[GetTxOutResult]
implicit val getTxOutSetInfoResultReads: Reads[GetTxOutSetInfoResult] =
Json.reads[GetTxOutSetInfoResult]
// Wallet Models
implicit val multiSigReads: Reads[MultiSigResult] =
Json.reads[MultiSigResult]
implicit val bumpFeeReads: Reads[BumpFeeResult] = Json.reads[BumpFeeResult]
implicit val TransactionDetailsReads: Reads[TransactionDetails] =
Json.reads[TransactionDetails]
implicit val getTransactionResultReads: Reads[GetTransactionResult] =
((__ \ "amount").read[Bitcoins] and
(__ \ "fee").readNullable[Bitcoins] and
(__ \ "confirmations").read[Int] and
(__ \ "generated").readNullable[Boolean] and
(__ \ "blockhash").readNullable[DoubleSha256Digest] and
(__ \ "blockindex").readNullable[Int] and
(__ \ "blocktime").readNullable[UInt32] and
(__ \ "txid").read[DoubleSha256Digest] and
(__ \ "walletconflicts").read[Vector[DoubleSha256Digest]] and
(__ \ "time").read[UInt32] and
(__ \ "timereceived").read[UInt32] and
(__ \ "bip125-replaceable").read[String] and
(__ \ "comment").readNullable[String] and
(__ \ "to").readNullable[String] and
(__ \ "details").read[Vector[TransactionDetails]] and
(__ \ "hex").read[Transaction])(GetTransactionResult)
implicit val getWalletInfoResultReads: Reads[GetWalletInfoResult] =
Json.reads[GetWalletInfoResult]
implicit val importMultiErrorReads: Reads[ImportMultiError] =
Json.reads[ImportMultiError]
implicit val importMultiResultReads: Reads[ImportMultiResult] =
Json.reads[ImportMultiResult]
implicit val rpcAddressReads: Reads[RpcAddress] = RpcAddressReads
implicit val rpcAccoutReads: Reads[RpcAccount] = Json.reads[RpcAccount]
implicit val dumpWalletResultReads: Reads[DumpWalletResult] =
Json.reads[DumpWalletResult]
implicit val rescanBlockChainResultReads: Reads[RescanBlockChainResult] =
Json.reads[RescanBlockChainResult]
implicit val receivedAddressReads: Reads[ReceivedAddress] =
Json.reads[ReceivedAddress]
implicit val receivedAccountReads: Reads[ReceivedAccount] =
Json.reads[ReceivedAccount]
implicit val paymentReads: Reads[Payment] =
((__ \ "involvesWatchonly").readNullable[Boolean] and
(__ \ "account").readNullable[String] and
(__ \ "address").readNullable[BitcoinAddress] and
(__ \ "category").read[String] and
(__ \ "amount").read[Bitcoins] and
(__ \ "vout").read[Int] and
(__ \ "fee").readNullable[Bitcoins] and
(__ \ "confirmations").read[Int] and
(__ \ "generated").readNullable[Boolean] and
(__ \ "blockhash").readNullable[DoubleSha256Digest] and
(__ \ "blockindex").readNullable[Int] and
(__ \ "blocktime").readNullable[UInt32] and
(__ \ "txid").read[DoubleSha256Digest] and
(__ \ "walletconflicts").read[Vector[DoubleSha256Digest]] and
(__ \ "time").read[UInt32] and
(__ \ "timereceived").read[UInt32] and
(__ \ "bip125-replaceable").read[String] and
(__ \ "comment").readNullable[String] and
(__ \ "to").readNullable[String])(Payment)
implicit val listSinceBlockResultReads: Reads[ListSinceBlockResult] =
Json.reads[ListSinceBlockResult]
implicit val listTransactionsResultReads: Reads[ListTransactionsResult] =
((__ \ "account").readNullable[String] and
(__ \ "address").readNullable[BitcoinAddress] and
(__ \ "category").read[String] and
(__ \ "amount").read[Bitcoins] and
(__ \ "label").readNullable[String] and
(__ \ "vout").readNullable[Int] and
(__ \ "fee").readNullable[Bitcoins] and
(__ \ "confirmations").readNullable[Int] and
(__ \ "trusted").readNullable[Boolean] and
(__ \ "generated").readNullable[Boolean] and
(__ \ "blockhash").readNullable[DoubleSha256Digest] and
(__ \ "blockindex").readNullable[Int] and
(__ \ "blocktime").readNullable[UInt32] and
(__ \ "txid").readNullable[DoubleSha256Digest] and
(__ \ "walletconflicts").readNullable[Vector[DoubleSha256Digest]] and
(__ \ "time").read[UInt32] and
(__ \ "timereceived").readNullable[UInt32] and
(__ \ "comment").readNullable[String] and
(__ \ "to").readNullable[String] and
(__ \ "otheraccount").readNullable[String] and
(__ \ "bip125-replaceable").read[String] and
(__ \ "abandoned").readNullable[Boolean])(ListTransactionsResult)
implicit val unspentOutputReads: Reads[UnspentOutput] =
Json.reads[UnspentOutput]
// Other Models
implicit val blockTransactionReads: Reads[BlockTransaction] =
Json.reads[BlockTransaction]
implicit val getBlockTemplateResultReads: Reads[GetBlockTemplateResult] =
Json.reads[GetBlockTemplateResult]
implicit val miningInfoReads: Reads[GetMiningInfoResult] =
Json.reads[GetMiningInfoResult]
implicit val memoryManagerReads: Reads[MemoryManager] =
Json.reads[MemoryManager]
implicit val getMemoryInfoResultReads: Reads[GetMemoryInfoResult] =
Json.reads[GetMemoryInfoResult]
implicit val validateAddressResultReads: Reads[ValidateAddressResult] =
Json.reads[ValidateAddressResult]
implicit val estimateSmartFeeResultReads: Reads[EstimateSmartFeeResult] =
Json.reads[EstimateSmartFeeResult]
// Map stuff
implicit def mapDoubleSha256DigestReads: Reads[
Map[DoubleSha256Digest, GetMemPoolResult]] =
Reads.mapReads[DoubleSha256Digest, GetMemPoolResult](s =>
JsSuccess(DoubleSha256Digest.fromHex(s)))
implicit val outputMapWrites: Writes[Map[BitcoinAddress, Bitcoins]] =
mapWrites[BitcoinAddress, Bitcoins](_.value)
}

View file

@ -0,0 +1,53 @@
package org.bitcoins.rpc.serializers
import org.bitcoins.core.crypto.DoubleSha256Digest
import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.core.protocol.script.ScriptPubKey
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionInput}
import org.bitcoins.core.util.BitcoinSUtil
import play.api.libs.json._
object JsonWriters {
implicit object BitcoinsWrites extends Writes[Bitcoins] {
override def writes(o: Bitcoins): JsValue = JsNumber(o.toBigDecimal)
}
implicit object BitcoinAddressWrites extends Writes[BitcoinAddress] {
override def writes(o: BitcoinAddress): JsValue = JsString(o.value)
}
implicit object DoubleSha256DigestWrites extends Writes[DoubleSha256Digest] {
override def writes(o: DoubleSha256Digest): JsValue = JsString(o.hex)
}
implicit object ScriptPubKeyWrites extends Writes[ScriptPubKey] {
override def writes(o: ScriptPubKey): JsValue =
JsString(BitcoinSUtil.encodeHex(o.asmBytes))
}
implicit object TransactionInputWrites extends Writes[TransactionInput] {
override def writes(o: TransactionInput): JsValue =
JsObject(
Seq(("txid", JsString(o.previousOutput.txId.flip.hex)),
("vout", JsNumber(o.previousOutput.vout.toLong)),
("sequence", JsNumber(o.sequence.toLong))))
}
implicit object UInt32Writes extends Writes[UInt32] {
override def writes(o: UInt32): JsValue = JsNumber(o.toLong)
}
implicit object TransactionWrites extends Writes[Transaction] {
override def writes(o: Transaction): JsValue = JsString(o.hex)
}
implicit def mapWrites[K, V](keyString: K => String)(
implicit
vWrites: Writes[V]): Writes[Map[K, V]] = new Writes[Map[K, V]] {
override def writes(o: Map[K, V]): JsValue = {
Json.toJson(o.map { case (k, v) => (keyString(k), v) })
}
}
}