 
 public class BlockChainDB {
 
-    let dbBaseURL: String
-    let ethBaseURL: String?
-
-    // For `session.dataTask()`
-    let session = URLSession (configuration: .default)
-
-    // Temporary - adding asynchronicity to ETh requests.
+    /// Base URL (String) for the BRD BlockChain DB
+    let bdbBaseURL: String
+
+    /// Base URL (String) for BRD API Services
+    let apiBaseURL: String
+
+    // The seesion to use for DataTaskFunc as in `session.dataTask (with: request, ...)`
+    let session: URLSession
+
+    /// A DispatchQueue Used for certain queries that can't be accomplished in the session's data
+    /// task.  Such as when multiple request are needed in getTransactions().
     let queue = DispatchQueue.init(label: "BlockChainDB")
 
+    /// A function type that decorates a `request`, handle 'challenges', performs decrypting and/or
+    /// uncompression of response data and creates a `URLSessionDataTask` for the provided `session`.
+    public typealias DataTaskFunc = (URLSession, URLRequest, @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
+
+    /// A DataTaskFunc for submission to the BRD API
+    internal let apiDataTaskFunc: DataTaskFunc
+
+    /// A DataTaskFunc for submission to the BRD BlockChain DB
+    internal let bdbDataTaskFunc: DataTaskFunc
+
+    /// A default DataTaskFunc that simply invokes `session.dataTask (with: request, ...)`
+    static let defaultDataTaskFunc: DataTaskFunc = {
+        (_ session: URLSession,
+        _ request: URLRequest,
+        _ completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask in
+        session.dataTask (with: request, completionHandler: completionHandler)
+    }
+
+    ///
+    /// Initialize a BlockChainDB
+    ///
+    /// - Parameters:
+    ///   - session: the URLSession to use.  Defaults to `URLSession (configuration: .default)`
+    ///   - bdbBaseURL: the baseURL for the BRD BlockChain DB.  Defaults to "http://blockchain-db.us-east-1.elasticbeanstalk.com"
+    ///   - bdbDataTaskFunc: an optional DataTaskFunc for BRD BlockChain DB.  This defaults to
+    ///       `session.dataTask (with: request, ...)`
+    ///   - apiBaseURL: the baseRUL for the BRD API Server.  Defaults to "https://api.breadwallet.com".
+    ///       if this is a DEBUG build then "https://stage2.breadwallet.com" will be used instead.
+    ///   - apiDataTaskFunc: an optional DataTaskFunc for BRD API services.  For a non-DEBUG build,
+    ///       this function would need to properly authenticate with BRD.  This means 'decorating
+    ///       the request' header, perhaps responding to a 'challenge', perhaps decripting and/or
+    ///       uncompressing response data.  This defaults to `session.dataTask (with: request, ...)`
+    ///       which suffices for DEBUG builds.
+    ///
+    public init (session: URLSession = URLSession (configuration: .default),
+                 bdbBaseURL: String = "http://blockchain-db.us-east-1.elasticbeanstalk.com",
+                 bdbDataTaskFunc: DataTaskFunc? = nil,
+                 apiBaseURL: String = "https://api.breadwallet.com",
+                 apiDataTaskFunc: DataTaskFunc? = nil) {
+
+        self.session = session
+
+        self.bdbBaseURL = bdbBaseURL
+        self.bdbDataTaskFunc = bdbDataTaskFunc ?? BlockChainDB.defaultDataTaskFunc
+
+        #if DEBUG
+        self.apiBaseURL = "https://stage2.breadwallet.com"
+        #else
+        self.ethBaseURL = apiBaseURL
+        #endif
+        self.apiDataTaskFunc = apiDataTaskFunc ?? BlockChainDB.defaultDataTaskFunc
+    }
+
+    ///
+    /// A QueryError subtype of Error
+    ///
+    /// - url:
+    /// - submission:
+    /// - noData:
+    /// - jsonParse:
+    /// - model:
+    /// - noEntity:
+    ///
     public enum QueryError: Error {
         // HTTP URL build failed
         case url (String)


        static internal func asLog (json: JSON, rid: Int32) -> ETH.Log? {
            guard let hash = json.asString(name: "transactionHash"),
                let contract = json.asString(name: "address"),
                let topics   = dropLastIfEmpty (json.asStringArray (name: "topics")),
                let data     = json.asString(name: "data"),
                let gasPrice = json.asString(name: "gasPrice"),
                let gasUsed  = json.asString(name: "gasUsed"),
                let logIndex = json.asString(name: "logIndex"),
                let blockNumber = json.asString(name: "blockNumber"),
                let blockTransactionIndex = json.asString(name: "transactionIndex"),
                let blockTimestamp = json.asString(name: "timeStamp")
                else { return nil }

            return (hash: hash, contract: contract, topics: topics, data: data,

        ]
        if nil != contract { queryDict["address"] = contract! }

        apiMakeRequestQUERY (ewm: ewm, query: zip (Array(queryDict.keys), Array(queryDict.values)), data: json) {
            (res: Result<JSON, QueryError>) in

            let resLogs = res
