 (defn ca-user?
   [user]
   (not (nil? (:ca-location user))))
-
-(defn new-user!
-  [{:keys [msp-id name]
-    :as args}]
-  ;; roles - client, auditor
-  ;; %roles - peer, validator
-  (swap! core/users assoc [msp-id name] (core/make-user args)))
-
-;;; new_chain
-;;;
-;; "Initializes a chain instance with the given name. This is really representing the \"Channel\"
-;;   (as explained above), and this call returns an empty object. To initialize the channel, a list of
-;;   participating endorsers and orderer peers must be configured first on the returned object.
-;;   Params:
-;;         name (str): The name of the chain, recommend using namespaces to avoid collision
-;;   Returns:
-;;         (Chain instance): The uninitialized chain instance."
-;;
-;;
-(defn new-channel!
-  ([channel-opts]
-   (new-channel! core/*user* channel-opts))
-  ([{msp-id :msp-id user-name :name} channel-opts]
-   (let [user-key [msp-id user-name]]
-     (swap! core/users assoc-in [user-key :channels (:name channel-opts)]
-            (core/make-channel (assoc channel-opts :user-key user-key))))))
-
-;;; get_chain
-(defn get-channel
-  "Get a chain instance from the state storage. This allows existing chain instances to be saved
-  for retrieval later and to be shared among instances of the application. Note that it's the 
-  application/SDK’s responsibility to record the chain information. If an application is not able to
-  look up the chain information from storage, it may call another API that queries one or more Peers
-  for that information.
-  Params:
-        name (str): The name of the chain
-  Returns:
-        (Chain instance or None): the chain instance for the name.
-  Error:  The state store has not been set
-        A chain does not exist under that name"
-  ;; Implementation Note:
-  ;;    Not a storage operation 
-  ([channel-name]
-   (get-channel core/*user* channel-name))
-  ([{:keys [channels]} channel-name]
-   (if-let [found (get channels channel-name)]
-     found
-     ;; Implementation Note
-     ;;       The spec says that Returns is chain Instance or None
-     ;;       How it can be None and also throw an exception?
-     (throw (Exception. "A channel does not exist under that name")))))
 
 (defmacro with-validating-peers
   [[user-or-channel target-peers] & body]

(defn new-crypto-suite!
  ([crypto-opts]
   (new-crypto-suite! core/*user* crypto-opts))
  ([{:keys [msp-id name]} user crypto-opts]
   (swap! core/users assoc-in [[msp-id name] crypto-opts]
          (core/make-crypto-suite crypto-opts))))

;; Params:
;;   Suite (object): an instance of a crypto suite implementation"
;;   
;; Immutable

;;; get_crypto_suite 
(defn get-crypto-suite
  "A convenience method for obtaining the CryptoSuite object in use for this client.
  Params:
        None
  Returns:
        (CryptoSuite instance): The CryptoSuite implementation object set within this Client, 
        or null if it does not exist"
  ([]
   (get-crypto-suite core/*user*))
  ([user]
   (:crypto-suite user)))

;;; set_user_context
;; "Sets an instance of the User class as the security context of this client instance.

                                         target-peers
                                         user
                                         {:args [deployment-spec]})))))

;;; new_chain
;;;
;; "Initializes a chain instance with the given name. This is really representing the \"Channel\"
;;   (as explained above), and this call returns an empty object. To initialize the channel, a list of
;;   participating endorsers and orderer peers must be configured first on the returned object.
;;   Params:
;;         name (str): The name of the chain, recommend using namespaces to avoid collision
;;   Returns:
;;         (Chain instance): The uninitialized chain instance."
;;
;;
(defn new-channel!
  ([channel-opts]
   (new-channel! core/*user* channel-opts))
  ([{msp-id :msp-id user-name :name} channel-opts]
   (let [user-key [msp-id user-name]]
     (swap! core/users assoc-in [user-key :channels (:name channel-opts)]
            (core/make-channel (assoc channel-opts :user-key user-key))))))

(defn new-event-hub!
  [user peer]
  (if-let [existing-eh (deref (:event-hub peer))]
    (throw (Exception. "An event-hub already exists!"))
    (let [event-hub (event-hub/make-event-hub user peer)]
      (reset! (:event-hub peer) event-hub)
      event-hub)))


;;; query_chain-info
(defn query-channels
    "This is a network call to the designated Peer(s) to discover the chain information.
  The target Peer(s) must be part of the chain in question to be able to return the requested
  information.
  Params:
        name (str): The name of the chain
        peers (array of Peer instances): target Peers to query
  Returns: 
        (Chain instance or None): the chain instance for the name.
  Error: 
        The target Peer(s) does not know anything about the chain"
  ([channel-name peers]
   (query-channels core/*user* channel-name peers))
  ([user channel-name target-peers]
   (let [{:keys [crypto-suite user-context] :as channel} (get-channel user channel-name)]
     (with-validating-peers [channel target-peers]
                             (chaincode/send-chaincode-request :query-channels
                                                               system-channel-name
                                                               target-peers
                                                               user
                                                               {})))))


(defn query-installed-chaincodes
  ([peer]
   (query-installed-chaincodes core/*user* peer))
  ([user peer]
   (if (known-user-node? user peer :peers)
     (first (chaincode/send-chaincode-request :query-installed-chaincodes
                                              system-channel-name
                                              peer
                                              user
                                              {}))
     (throw (Exception. "The target Peer does not know anything about the channel")))))


;; (def e1 (Common$Envelope/parseFrom buf))
