bitcoin-client

bitcoin client library for price ticker and wallet

git clone https://9o.is/git/bitcoin-client.git

JsonRPC.scala

(5950B)


      1 package inc.pyc.bitcoin
      2 
      3 import net.liftweb._
      4 import net.liftweb.json.JsonAST._
      5 import scala.math.BigDecimal.int2bigDecimal
      6 import scala.math.BigInt.int2bigInt
      7 
      8 sealed trait JsonMessage
      9 
     10 /**
     11  * For more information, visit 
     12  * http://json-rpc.org/wiki/specification
     13  */
     14 object JsonRPC {
     15   implicit val formats = json.DefaultFormats
     16 
     17   // JSON-RPC MESSAGES
     18   case class JsonNotification(jsonrpc: String, method: String, params: JArray) extends JsonMessage
     19   case class JsonRequest(jsonrpc: String, id: String, method: String, params: JArray) extends JsonMessage  
     20   case class JsonResponse(jsonrpc: String, id: String, error: Option[JValue], result: Option[JValue]) extends JsonMessage {
     21     def either: Either[String, JValue] =
     22       (result, error) match {
     23         case (Some(result), _) => Right(result)
     24         case (_, Some(error)) => Left((error \ "message").extract[String])
     25         case _ => Left("Unknown response")
     26       }  
     27   }
     28   
     29   // JsonMessage to JValue implicit
     30   implicit def jsonRequestToJValue(r: JsonRequest): JValue = {
     31     JObject(List(
     32         JField("jsonrpc", JString(r.jsonrpc)), 
     33         JField("id", JString(r.id)), 
     34         JField("method", JString(r.method)), 
     35         JField("params", r.params)))
     36   }
     37 }
     38 
     39 trait WalletMessage
     40 trait NotificationMessage extends WalletMessage
     41 
     42 /**
     43  * For more information, visit 
     44  * https://en.bitcoin.it/wiki/API_reference_(JSON-RPC)
     45  */
     46 object BitcoinJsonRPC {
     47   import JsonRPC._
     48   
     49   // BITCOIN TRANSACTIONS
     50   case class RawTransaction(hex: String, txid: String, version: BigDecimal, locktime: BigDecimal, vin: Seq[VIn], vout: Seq[VOut])
     51   case class VIn(txid: String, vout: Int, scriptSig: ScriptSig, sequence: BigDecimal)
     52   case class VOut(value: BigDecimal, n: BigDecimal, scriptPubKey: ScriptPubKey)
     53   case class ScriptSig(asm: String, hex: String)
     54   case class ScriptPubKey(asm: String, hex: String, reqSigs: BigDecimal, `type`: String, addresses: Seq[String])
     55   case class UnspentTransaction(txid: String, account: String, address: String, amount: BigDecimal, confirmations: BigDecimal)
     56   case class SignedTransaction(hex: String, complete: Boolean)
     57   case class TransactionNotification(txid: String, account: String, address: String, 
     58       category: String, amount: BigDecimal, confirmations: BigDecimal, timereceived: BigDecimal)
     59 
     60   // OTHER BITCOIN MESSAGES
     61   case class AddressValidation(isvalid: Boolean, address: String,
     62     ismine: Option[Boolean], pubkey: Option[String], iscompressed: Option[Boolean])
     63 
     64   // ACTOR MESSAGES
     65   // notifications
     66   case class ReceivedPayment(txId: String, address: String, amount: BigDecimal, confirmations: BigDecimal) extends NotificationMessage  
     67   
     68   // requests
     69   sealed trait RequestMessage extends WalletMessage
     70   case class CreateRawTransaction(inputs: Seq[(String, BigDecimal)], receivers: Seq[(String, BigDecimal)]) extends RequestMessage
     71   case object GetBalance extends RequestMessage
     72   case object GetNewAddress extends RequestMessage
     73   case class GetRawTransaction(transactionHash: String) extends RequestMessage
     74   case class ListUnspentTransactions(minConfirmations: BigDecimal = 1, maxConfirmations: BigDecimal = 999999) extends RequestMessage
     75   case class SendRawTransaction(signedTransaction: String) extends RequestMessage
     76   case class SignRawTransaction(transaction: String) extends RequestMessage
     77   case class WalletPassPhrase(walletPass: String, timeout: BigDecimal) extends RequestMessage
     78   case class ValidateAddress(address: String) extends RequestMessage
     79   
     80 
     81   /**
     82    * Constructs JSON-RPC messages out of the existing actor messages related
     83    * to Bitcoin's standard rpc-json commands.
     84    */
     85   object JsonMessage {
     86     def createRawTransaction(inputs: Seq[(String, BigDecimal)], receivers: Seq[(String, BigDecimal)]) =
     87       JsonRequest("1.0", Utils.getUUID, "createrawtransaction", JArray(
     88         inputs.map(i => JObject(List("txid" -> i._1, "vout" -> i._2))).toList ::
     89           receivers.map(r => JObject(List(r._1 -> r._2))).toList))
     90 
     91     def getBalance =
     92       JsonRequest("1.0", Utils.getUUID, "getbalance", Seq())
     93       
     94     def getNewAddress =
     95       JsonRequest("1.0", Utils.getUUID, "getnewaddress", Seq())
     96 
     97     def getRawTransaction(transactionHash: String) =
     98       JsonRequest("1.0", Utils.getUUID, "getrawtransaction", JArray(List(transactionHash, 1)))
     99 
    100     def listUnspentTransactions(minConfirmations: BigDecimal, maxConfirmations: BigDecimal, addresses: Seq[String] = Seq.empty[String]) = {
    101       val params =
    102         if (addresses.isEmpty) JArray(List(minConfirmations, maxConfirmations))
    103         else JArray(List(minConfirmations, maxConfirmations, addresses))
    104       JsonRequest("1.0", Utils.getUUID, "listunspent", params)
    105     }
    106 
    107     def sendRawTransaction(signedTransaction: String) =
    108       JsonRequest("1.0", Utils.getUUID, "sendrawtransaction", Seq(signedTransaction))
    109 
    110     def signRawTransaction(transaction: String) =
    111       JsonRequest("1.0", Utils.getUUID, "signrawtransaction", Seq(transaction))
    112 
    113     def walletPassPhrase(walletPass: String, timeout: BigDecimal) =
    114       JsonRequest("1.0", Utils.getUUID, "walletpassphrase", JArray(List(walletPass, timeout)))
    115 
    116     def validateAddress(address: String) =
    117       JsonRequest("1.0", Utils.getUUID, "validateaddress", Seq(address))
    118   }
    119   
    120   private object Utils {
    121     def getUUID = java.util.UUID.randomUUID.toString
    122   }
    123 
    124   // JValue implicits
    125   implicit def intToJInt(i: Int): JInt = JInt(i)
    126   implicit def stringToJString(s: String): JString = JString(s)
    127   implicit def stringToJField(m: (String, String)): JField = JField(m._1, m._2)
    128 
    129   // BigDecimal to JValue implicits
    130   implicit def bigdecimalToJField(m: (String, BigDecimal)): JField = JField(m._1, m._2)
    131   implicit def bigdecimalToJDouble(d: BigDecimal): JDouble = JDouble(d.doubleValue)
    132 
    133   // Scala collections to JArray implicits
    134   implicit def listToJArray(l: List[JValue]): JArray = JArray(l)
    135   implicit def seqStringToJArray(l: Seq[String]): JArray = JArray(l.map(JString).toList)
    136 }