sig
  exception Unspecified_connection
  exception Bitcoin_error of int * string
  exception Internal_error of int * string
  exception Httpclient_error of exn
  type address_t = string
  type account_t = [ `Default | `Named of string ]
  type amount_t = int64
  type txid_t = string
  type txoutput_t = Bitcoin.txid_t * int
  type blkhash_t = string
  type priv_t = string
  type pub_t = string
  type sig_t = string
  type sigcomp_t = [ `All | `None | `Single ]
  type hextx_t = string
  type hexspk_t = string
  type hexblk_t = string
  type hexwork_t = string
  type node_t = string
  type addnodeop_t = [ `Add | `Onetry | `Remove ]
  type lockop_t = [ `Lock | `Unlock ]
  type assoc_t = (string * Yojson.Safe.json) list
  type conn_t = {
    inet_addr : Unix.inet_addr;
    host : string;
    port : int;
    username : string;
    password : string;
  }
  module type HTTPCLIENT =
    sig
      module Monad :
        sig
          type 'a t
          val return : '-> 'Bitcoin.HTTPCLIENT.Monad.t
          val fail : exn -> 'Bitcoin.HTTPCLIENT.Monad.t
          val bind :
            'Bitcoin.HTTPCLIENT.Monad.t ->
            ('-> 'Bitcoin.HTTPCLIENT.Monad.t) ->
            'Bitcoin.HTTPCLIENT.Monad.t
          val catch :
            (unit -> 'Bitcoin.HTTPCLIENT.Monad.t) ->
            (exn -> 'Bitcoin.HTTPCLIENT.Monad.t) ->
            'Bitcoin.HTTPCLIENT.Monad.t
        end
      val post_string :
        headers:(string * string) list ->
        inet_addr:Unix.inet_addr ->
        host:string ->
        port:int -> uri:string -> string -> string Bitcoin.HTTPCLIENT.Monad.t
    end
  module type CONNECTION = sig val default : Bitcoin.conn_t option end
  module type ENGINE =
    sig
      type 'a monad_t
      val addnode :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.node_t -> Bitcoin.addnodeop_t -> unit Bitcoin.ENGINE.monad_t
      val backupwallet :
        ?conn:Bitcoin.conn_t -> string -> unit Bitcoin.ENGINE.monad_t
      val createmultisig :
        ?conn:Bitcoin.conn_t ->
        int ->
        Bitcoin.pub_t list ->
        (Bitcoin.address_t * Bitcoin.hexspk_t) Bitcoin.ENGINE.monad_t
      val createrawtransaction :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.txoutput_t list ->
        (Bitcoin.address_t * Bitcoin.amount_t) list ->
        Bitcoin.hextx_t Bitcoin.ENGINE.monad_t
      val decoderawtransaction :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.hextx_t -> Bitcoin.assoc_t Bitcoin.ENGINE.monad_t
      val dumpprivkey :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.address_t -> Bitcoin.priv_t Bitcoin.ENGINE.monad_t
      val encryptwallet :
        ?conn:Bitcoin.conn_t -> string -> unit Bitcoin.ENGINE.monad_t
      val getaccount :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.address_t -> Bitcoin.account_t Bitcoin.ENGINE.monad_t
      val getaccountaddress :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.account_t -> Bitcoin.address_t Bitcoin.ENGINE.monad_t
      val getaddednodeinfo :
        ?conn:Bitcoin.conn_t ->
        ?node:Bitcoin.node_t ->
        unit -> Bitcoin.assoc_t Bitcoin.ENGINE.monad_t
      val getaddednodeinfo_verbose :
        ?conn:Bitcoin.conn_t ->
        ?node:Bitcoin.node_t ->
        unit -> Bitcoin.assoc_t list Bitcoin.ENGINE.monad_t
      val getaddressesbyaccount :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.account_t -> Bitcoin.address_t list Bitcoin.ENGINE.monad_t
      val getbalance :
        ?conn:Bitcoin.conn_t ->
        ?account:Bitcoin.account_t ->
        ?minconf:int -> unit -> Bitcoin.amount_t Bitcoin.ENGINE.monad_t
      val getblock :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.blkhash_t -> Bitcoin.assoc_t Bitcoin.ENGINE.monad_t
      val getblockcount :
        ?conn:Bitcoin.conn_t -> unit -> int Bitcoin.ENGINE.monad_t
      val getblockhash :
        ?conn:Bitcoin.conn_t ->
        int -> Bitcoin.blkhash_t Bitcoin.ENGINE.monad_t
      val getblocktemplate :
        ?conn:Bitcoin.conn_t ->
        ?obj:Bitcoin.assoc_t ->
        unit -> Bitcoin.assoc_t Bitcoin.ENGINE.monad_t
      val getconnectioncount :
        ?conn:Bitcoin.conn_t -> unit -> int Bitcoin.ENGINE.monad_t
      val getdifficulty :
        ?conn:Bitcoin.conn_t -> unit -> float Bitcoin.ENGINE.monad_t
      val getgenerate :
        ?conn:Bitcoin.conn_t -> unit -> bool Bitcoin.ENGINE.monad_t
      val gethashespersec :
        ?conn:Bitcoin.conn_t -> unit -> int Bitcoin.ENGINE.monad_t
      val getinfo :
        ?conn:Bitcoin.conn_t ->
        unit -> Bitcoin.assoc_t Bitcoin.ENGINE.monad_t
      val getmininginfo :
        ?conn:Bitcoin.conn_t ->
        unit -> Bitcoin.assoc_t Bitcoin.ENGINE.monad_t
      val getnewaddress :
        ?conn:Bitcoin.conn_t ->
        ?account:Bitcoin.account_t ->
        unit -> Bitcoin.address_t Bitcoin.ENGINE.monad_t
      val getpeerinfo :
        ?conn:Bitcoin.conn_t ->
        unit -> Bitcoin.assoc_t list Bitcoin.ENGINE.monad_t
      val getrawmempool :
        ?conn:Bitcoin.conn_t ->
        unit -> Bitcoin.txid_t list Bitcoin.ENGINE.monad_t
      val getrawtransaction :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.txid_t -> Bitcoin.hextx_t Bitcoin.ENGINE.monad_t
      val getrawtransaction_verbose :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.txid_t -> Bitcoin.assoc_t Bitcoin.ENGINE.monad_t
      val getreceivedbyaccount :
        ?conn:Bitcoin.conn_t ->
        ?minconf:int ->
        Bitcoin.account_t -> Bitcoin.amount_t Bitcoin.ENGINE.monad_t
      val getreceivedbyaddress :
        ?conn:Bitcoin.conn_t ->
        ?minconf:int ->
        Bitcoin.address_t -> Bitcoin.amount_t Bitcoin.ENGINE.monad_t
      val gettransaction :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.txid_t -> Bitcoin.assoc_t Bitcoin.ENGINE.monad_t
      val gettxout :
        ?conn:Bitcoin.conn_t ->
        ?includemempool:bool ->
        Bitcoin.txoutput_t -> Bitcoin.assoc_t Bitcoin.ENGINE.monad_t
      val gettxoutsetinfo :
        ?conn:Bitcoin.conn_t ->
        unit -> Bitcoin.assoc_t Bitcoin.ENGINE.monad_t
      val getwork_with_data :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.hexwork_t -> bool Bitcoin.ENGINE.monad_t
      val getwork_without_data :
        ?conn:Bitcoin.conn_t ->
        unit -> Bitcoin.assoc_t Bitcoin.ENGINE.monad_t
      val importprivkey :
        ?conn:Bitcoin.conn_t ->
        ?account:Bitcoin.account_t ->
        ?rescan:bool -> Bitcoin.priv_t -> unit Bitcoin.ENGINE.monad_t
      val keypoolrefill :
        ?conn:Bitcoin.conn_t -> unit -> unit Bitcoin.ENGINE.monad_t
      val listaccounts :
        ?conn:Bitcoin.conn_t ->
        ?minconf:int ->
        unit ->
        (Bitcoin.account_t * Bitcoin.amount_t) list Bitcoin.ENGINE.monad_t
      val listaddressgroupings :
        ?conn:Bitcoin.conn_t ->
        unit ->
        (Bitcoin.address_t * Bitcoin.amount_t * Bitcoin.account_t) list list
        Bitcoin.ENGINE.monad_t
      val listlockunspent :
        ?conn:Bitcoin.conn_t ->
        unit -> Bitcoin.txoutput_t list Bitcoin.ENGINE.monad_t
      val listreceivedbyaccount :
        ?conn:Bitcoin.conn_t ->
        ?minconf:int ->
        ?includeempty:bool ->
        unit ->
        (Bitcoin.account_t * Bitcoin.amount_t * int) list
        Bitcoin.ENGINE.monad_t
      val listreceivedbyaddress :
        ?conn:Bitcoin.conn_t ->
        ?minconf:int ->
        ?includeempty:bool ->
        unit ->
        (Bitcoin.address_t * Bitcoin.account_t * Bitcoin.amount_t * int) list
        Bitcoin.ENGINE.monad_t
      val listsinceblock :
        ?conn:Bitcoin.conn_t ->
        ?blockhash:Bitcoin.blkhash_t ->
        ?minconf:int ->
        unit ->
        (Bitcoin.assoc_t list * Bitcoin.blkhash_t) Bitcoin.ENGINE.monad_t
      val listtransactions :
        ?conn:Bitcoin.conn_t ->
        ?account:Bitcoin.account_t ->
        ?count:int ->
        ?from:int -> unit -> Bitcoin.assoc_t list Bitcoin.ENGINE.monad_t
      val listunspent :
        ?conn:Bitcoin.conn_t ->
        ?minconf:int ->
        ?maxconf:int ->
        ?addresses:Bitcoin.address_t list ->
        unit -> Bitcoin.assoc_t list Bitcoin.ENGINE.monad_t
      val lockunspent :
        ?conn:Bitcoin.conn_t ->
        ?outputs:Bitcoin.txoutput_t list ->
        Bitcoin.lockop_t -> bool Bitcoin.ENGINE.monad_t
      val move :
        ?conn:Bitcoin.conn_t ->
        ?minconf:int ->
        ?comment:string ->
        Bitcoin.account_t ->
        Bitcoin.account_t -> Bitcoin.amount_t -> bool Bitcoin.ENGINE.monad_t
      val sendfrom :
        ?conn:Bitcoin.conn_t ->
        ?minconf:int ->
        ?comment:string ->
        ?recipient:string ->
        Bitcoin.account_t ->
        Bitcoin.address_t ->
        Bitcoin.amount_t -> Bitcoin.txid_t Bitcoin.ENGINE.monad_t
      val sendmany :
        ?conn:Bitcoin.conn_t ->
        ?minconf:int ->
        ?comment:string ->
        Bitcoin.account_t ->
        (Bitcoin.address_t * Bitcoin.amount_t) list ->
        Bitcoin.txid_t Bitcoin.ENGINE.monad_t
      val sendrawtransaction :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.hextx_t -> Bitcoin.txid_t Bitcoin.ENGINE.monad_t
      val sendtoaddress :
        ?conn:Bitcoin.conn_t ->
        ?comment:string ->
        ?recipient:string ->
        Bitcoin.address_t ->
        Bitcoin.amount_t -> Bitcoin.txid_t Bitcoin.ENGINE.monad_t
      val setaccount :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.address_t -> Bitcoin.account_t -> unit Bitcoin.ENGINE.monad_t
      val setgenerate :
        ?conn:Bitcoin.conn_t ->
        ?genproclimit:int -> bool -> unit Bitcoin.ENGINE.monad_t
      val settxfee :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.amount_t -> bool Bitcoin.ENGINE.monad_t
      val signmessage :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.address_t -> string -> Bitcoin.sig_t Bitcoin.ENGINE.monad_t
      val signrawtransaction :
        ?conn:Bitcoin.conn_t ->
        ?parents:(Bitcoin.txoutput_t * Bitcoin.hexspk_t) list ->
        ?keys:Bitcoin.priv_t list ->
        ?sighash:Bitcoin.sigcomp_t * bool ->
        Bitcoin.hextx_t -> (Bitcoin.hextx_t * bool) Bitcoin.ENGINE.monad_t
      val submitblock :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.hexblk_t -> unit Bitcoin.ENGINE.monad_t
      val validateaddress :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.address_t -> Bitcoin.assoc_t option Bitcoin.ENGINE.monad_t
      val verifymessage :
        ?conn:Bitcoin.conn_t ->
        Bitcoin.address_t ->
        Bitcoin.sig_t -> string -> bool Bitcoin.ENGINE.monad_t
      val walletlock :
        ?conn:Bitcoin.conn_t -> unit -> unit Bitcoin.ENGINE.monad_t
      val walletpassphrase :
        ?conn:Bitcoin.conn_t -> string -> int -> unit Bitcoin.ENGINE.monad_t
      val walletpassphrasechange :
        ?conn:Bitcoin.conn_t ->
        string -> string -> unit Bitcoin.ENGINE.monad_t
    end
  val amount_of_float : float -> Bitcoin.amount_t
  val float_of_amount : Bitcoin.amount_t -> float
  module Make :
    functor (Httpclient : HTTPCLIENT->
      functor (Connection : CONNECTION->
        sig
          type 'a monad_t = 'Httpclient.Monad.t
          val addnode : ?conn:conn_t -> node_t -> addnodeop_t -> unit monad_t
          val backupwallet : ?conn:conn_t -> string -> unit monad_t
          val createmultisig :
            ?conn:conn_t ->
            int -> pub_t list -> (address_t * hexspk_t) monad_t
          val createrawtransaction :
            ?conn:conn_t ->
            txoutput_t list -> (address_t * amount_t) list -> hextx_t monad_t
          val decoderawtransaction :
            ?conn:conn_t -> hextx_t -> assoc_t monad_t
          val dumpprivkey : ?conn:conn_t -> address_t -> priv_t monad_t
          val encryptwallet : ?conn:conn_t -> string -> unit monad_t
          val getaccount : ?conn:conn_t -> address_t -> account_t monad_t
          val getaccountaddress :
            ?conn:conn_t -> account_t -> address_t monad_t
          val getaddednodeinfo :
            ?conn:conn_t -> ?node:node_t -> unit -> assoc_t monad_t
          val getaddednodeinfo_verbose :
            ?conn:conn_t -> ?node:node_t -> unit -> assoc_t list monad_t
          val getaddressesbyaccount :
            ?conn:conn_t -> account_t -> address_t list monad_t
          val getbalance :
            ?conn:conn_t ->
            ?account:account_t -> ?minconf:int -> unit -> amount_t monad_t
          val getblock : ?conn:conn_t -> blkhash_t -> assoc_t monad_t
          val getblockcount : ?conn:conn_t -> unit -> int monad_t
          val getblockhash : ?conn:conn_t -> int -> blkhash_t monad_t
          val getblocktemplate :
            ?conn:conn_t -> ?obj:assoc_t -> unit -> assoc_t monad_t
          val getconnectioncount : ?conn:conn_t -> unit -> int monad_t
          val getdifficulty : ?conn:conn_t -> unit -> float monad_t
          val getgenerate : ?conn:conn_t -> unit -> bool monad_t
          val gethashespersec : ?conn:conn_t -> unit -> int monad_t
          val getinfo : ?conn:conn_t -> unit -> assoc_t monad_t
          val getmininginfo : ?conn:conn_t -> unit -> assoc_t monad_t
          val getnewaddress :
            ?conn:conn_t -> ?account:account_t -> unit -> address_t monad_t
          val getpeerinfo : ?conn:conn_t -> unit -> assoc_t list monad_t
          val getrawmempool : ?conn:conn_t -> unit -> txid_t list monad_t
          val getrawtransaction : ?conn:conn_t -> txid_t -> hextx_t monad_t
          val getrawtransaction_verbose :
            ?conn:conn_t -> txid_t -> assoc_t monad_t
          val getreceivedbyaccount :
            ?conn:conn_t -> ?minconf:int -> account_t -> amount_t monad_t
          val getreceivedbyaddress :
            ?conn:conn_t -> ?minconf:int -> address_t -> amount_t monad_t
          val gettransaction : ?conn:conn_t -> txid_t -> assoc_t monad_t
          val gettxout :
            ?conn:conn_t ->
            ?includemempool:bool -> txoutput_t -> assoc_t monad_t
          val gettxoutsetinfo : ?conn:conn_t -> unit -> assoc_t monad_t
          val getwork_with_data : ?conn:conn_t -> hexwork_t -> bool monad_t
          val getwork_without_data : ?conn:conn_t -> unit -> assoc_t monad_t
          val importprivkey :
            ?conn:conn_t ->
            ?account:account_t -> ?rescan:bool -> priv_t -> unit monad_t
          val keypoolrefill : ?conn:conn_t -> unit -> unit monad_t
          val listaccounts :
            ?conn:conn_t ->
            ?minconf:int -> unit -> (account_t * amount_t) list monad_t
          val listaddressgroupings :
            ?conn:conn_t ->
            unit -> (address_t * amount_t * account_t) list list monad_t
          val listlockunspent :
            ?conn:conn_t -> unit -> txoutput_t list monad_t
          val listreceivedbyaccount :
            ?conn:conn_t ->
            ?minconf:int ->
            ?includeempty:bool ->
            unit -> (account_t * amount_t * int) list monad_t
          val listreceivedbyaddress :
            ?conn:conn_t ->
            ?minconf:int ->
            ?includeempty:bool ->
            unit -> (address_t * account_t * amount_t * int) list monad_t
          val listsinceblock :
            ?conn:conn_t ->
            ?blockhash:blkhash_t ->
            ?minconf:int -> unit -> (assoc_t list * blkhash_t) monad_t
          val listtransactions :
            ?conn:conn_t ->
            ?account:account_t ->
            ?count:int -> ?from:int -> unit -> assoc_t list monad_t
          val listunspent :
            ?conn:conn_t ->
            ?minconf:int ->
            ?maxconf:int ->
            ?addresses:address_t list -> unit -> assoc_t list monad_t
          val lockunspent :
            ?conn:conn_t ->
            ?outputs:txoutput_t list -> lockop_t -> bool monad_t
          val move :
            ?conn:conn_t ->
            ?minconf:int ->
            ?comment:string ->
            account_t -> account_t -> amount_t -> bool monad_t
          val sendfrom :
            ?conn:conn_t ->
            ?minconf:int ->
            ?comment:string ->
            ?recipient:string ->
            account_t -> address_t -> amount_t -> txid_t monad_t
          val sendmany :
            ?conn:conn_t ->
            ?minconf:int ->
            ?comment:string ->
            account_t -> (address_t * amount_t) list -> txid_t monad_t
          val sendrawtransaction : ?conn:conn_t -> hextx_t -> txid_t monad_t
          val sendtoaddress :
            ?conn:conn_t ->
            ?comment:string ->
            ?recipient:string -> address_t -> amount_t -> txid_t monad_t
          val setaccount :
            ?conn:conn_t -> address_t -> account_t -> unit monad_t
          val setgenerate :
            ?conn:conn_t -> ?genproclimit:int -> bool -> unit monad_t
          val settxfee : ?conn:conn_t -> amount_t -> bool monad_t
          val signmessage :
            ?conn:conn_t -> address_t -> string -> sig_t monad_t
          val signrawtransaction :
            ?conn:conn_t ->
            ?parents:(txoutput_t * hexspk_t) list ->
            ?keys:priv_t list ->
            ?sighash:sigcomp_t * bool -> hextx_t -> (hextx_t * bool) monad_t
          val submitblock : ?conn:conn_t -> hexblk_t -> unit monad_t
          val validateaddress :
            ?conn:conn_t -> address_t -> assoc_t option monad_t
          val verifymessage :
            ?conn:conn_t -> address_t -> sig_t -> string -> bool monad_t
          val walletlock : ?conn:conn_t -> unit -> unit monad_t
          val walletpassphrase :
            ?conn:conn_t -> string -> int -> unit monad_t
          val walletpassphrasechange :
            ?conn:conn_t -> string -> string -> unit monad_t
        end
end