refactored code.

This commit is contained in:
didier amyot committed 2020-09-10 14:39:26 -04:00
1 parent ed7f4ef668
commit cfb63cb473
3 files changed
+39 -233

No files matched your search

@@ -1,4 +1,4 @@
(ns skirmish.ledger.routes
(ns skirmish.ledger.controllers
(:require [skirmish.rest.util :refer [build-response get-body cors-middleware]]
[skirmish.ledger.data-layer :as data-layer]
[skirmish.routes.core :as routes]
@@ -178,6 +178,6 @@
(routes/GET :ledger/securities [] (get-available-securities conn))
(routes/POST :ledger/securities [] (create-security conn))
(routes/GET :ledger/security [] (get-security conn))
(routes/PUT :ledger/security [] (update-security conn))) ;; not done
;(routes/POST :ledger/security [] (emit-securities conn))) ;; done
(routes/PUT :ledger/security [] (update-security conn)) ;; TODO
(routes/POST :ledger/security [] (emit-securities conn)))
(not-found "not found")))
+4 -199
View File
@@ -1,42 +1,11 @@
(ns skirmish.ledger.core
(:require [org.httpkit.server :refer [run-server]]
[skirmish.routes.core :as routes]
[skirmish.ledger.controllers :as controllers]
[compojure.handler :refer [api]]
[skirmish.util :refer [block-thread]]
[slingshot.slingshot :refer [try+ throw+]]
[compojure.route :refer [not-found]]
[skirmish.exchange-gateway.exchange-gateway :refer [create-routes-for-exchange]]
[skirmish.rest.util :refer [build-response get-body cors-middleware]]
[skirmish.ledger.data-layer :as data-layer]
[skirmish.rest.util :refer [cors-middleware]]
[skirmish.ledger.accounts]
[datomic.api :as d]
[taoensso.timbre :as timbre]
[compojure.core :as compojure]
[clojure.spec.alpha :as s]
[infix.macros :refer [infix]]
[ring.middleware.cors :refer [wrap-cors]]))
;; the ledger is the central
;; an :account-id is the public key of a
;; an :account-secret is an :account-id private key
(defn get-account-body [request {sec-id :sec-id amount :amount account-public-key :account-public-key}]
(if (nil? sec-id)
(build-response request {:status 404})
(let [sec-url (str "/api/1/ledger/securities/" (name sec-id))
beautify-account { :amount amount
:sec-id sec-id
:account-public-key account-public-key}
ret {:account beautify-account :sec-url sec-url}]
(build-response request ret))))
(defn get-account [conn]
"Returns the value of an account."
(fn [{{account-id :account-id} :route-params :as request}]
(let [db (d/db conn)
account-info (data-layer/get-amount-in-account db account-id)]
(get-account-body request account-info))))
[clojure.spec.alpha :as s]))
(s/def ::transaction (s/cat :type #{:transfer-immediately}
:from-account-id string?
@@ -45,12 +14,6 @@
(s/def ::transactions (s/coll-of ::transaction))
(defn extract-transactions [raw-transactions]
(if (s/valid? ::transactions raw-transactions)
(s/conform ::transactions raw-transactions)
(throw+ {:error-type :4XX :status 400 :body {:error "Invalid transaction format."}})))
(s/def ::security (s/cat :sec-id keyword?
:interest-rate nat-int?
:type #{:equity :currency}
@@ -58,172 +21,14 @@
:emitter string?
:symbol (s/? string?)))
(defn get-new-security [raw-securities]
(if (s/valid? ::security raw-securities)
raw-securities
(throw+ {:error-type :4XX :status 400 :body {:error "Invalid security format."}})))
(defn prettify-security [e db]
(let [{interest-rate :skirmish.security/interest-rate
description :skirmish.security/description
id :db/id
sec-id :skirmish.security/sec-id
symbol :skirmish.security/symbol
name :skirmish.security/name
number-of-decimal :skirmish.security/number-of-decimal
type_ :skirmish.security/type} e
interest-rate-history (data-layer/get-interest-rate-history db id)
volumes (d/q '[:find ?amount ?date
:in $ ?id
:where [?e :skirmish.ledger/sec ?id]
[?e :skirmish.ledger/amount ?amount ?tx]
[?tx :db/txInstant ?date]]
db id)
now (new java.util.Date)
volume (reduce + 0 (map #(data-layer/compute-face-value (first %) interest-rate-history (second %) now) volumes))]
{:sec-id sec-id
:interest-rate interest-rate
:volume (or volume 0)
:name name
:interest-rate-history interest-rate-history
:symbol symbol
:number-of-decimal number-of-decimal
:type type_
:description description}))
(defn get-security-from-db [conn sec-id]
(let [db (d/db conn)
e (d/pull db '[*] [:skirmish.security/sec-id sec-id])]
(if (-> e :db/id nil?)
(throw+ {:error-type :4XX :status 404 :body {:error "Security not found."}})
(prettify-security e db))))
(defn create-security [conn]
"Create a fresh new security."
(fn [{body :body :as request}]
(try+
(let [[sec-id interest-rate] (-> body get-body get-new-security)
new-sec @(data-layer/create-security conn sec-id interest-rate)]
(build-response request {:body {:success true}
:headers {"location" (str "/api/1" "/ledger/securities/" (name sec-id))}}))
(catch [:error-type :4XX] e (build-response request e))
(catch [:error-type :5XX] e (build-response request e)))))
(defn get-security [conn]
"Returns the security."
(fn [{{sec-id-str :sec-id} :route-params :as request}]
(try+
(let [sec-id (keyword sec-id-str)]
(build-response request (get-security-from-db conn sec-id)))
(catch [:error-type :4XX] e (build-response request e))
(catch [:error-type :5XX] e (build-response request e)))))
(defn update-security [conn]
"Update a security with new features."
(fn [request]
(try+
(catch [:error-type :4XX] e (build-response request e))
(catch [:error-type :5XX] e (build-response request e)))))
(defn get-available-securities-body [securities]
(let [sec-id->url #(routes/get-path-for :ledger/security {:sec-id (name %)})
to-security-description #(hash-map :sec-id % :url (sec-id->url %))
xf (comp cat (map to-security-description))
securities-info (sequence xf securities)];;
{:securities securities-info}))
(defn get-available-securities [conn]
(fn [request]
(let [db (d/db conn)
securities (data-layer/get-all-securities-id db)]
(build-response request (get-available-securities-body securities)))))
(s/def ::emit-securities (s/cat :sec-id keyword?
:amount nat-int?
:account string?))
(defn get-emit-securities-request [[amount account] sec-id]
(if (s/valid? ::emit-securities [sec-id amount account])
[:skirmish.ledger/emit-securities sec-id amount account]
(throw+ {:error-type :4XX :status 400 :body {:error "Invalid emit request."}})))
(defn emit-securities [conn]
"Emit securities in the specified wallet. This is the only way to
create securities.
payload
[:amount :account]"
(fn [{{sec-id-str :sec-id} :route-params body :body :as request}]
(try+
(let [emit-request (-> body get-body (get-emit-securities-request (keyword sec-id-str)))]
@(d/transact conn [emit-request])
(build-response request {}))
(catch [:error-type :4XX] e (build-response request e))
(catch [:error-type :5XX] e (build-response request e)))))
(defn get-available-accounts-body [accounts]
(let [sec-id->url #(routes/get-path-for :ledger/account {:account-id (name %)})
to-security-description #(hash-map :account-public-key % :url (sec-id->url %))
xf (comp cat (map to-security-description))
securities-info (sequence xf accounts)]
{:accounts securities-info}))
(defn get-available-accounts [conn]
(fn [request]
(let [db (d/db conn)]
(build-response request (get-available-accounts-body (data-layer/get-all-account-public-key db))))))
(defn get-api-description [request]
(let [body [{:url "ledger/accounts" :name "accounts"}
{:url "ledger/securities" :name "securities"}]]
(build-response request body)))
(defn get-transactions [conn]
(fn [request]
(let [all-pending-transactions []]
(build-response request all-pending-transactions))))
(defn create-transactions [conn]
(fn [{body :body :as request}]
(try+
(let [transactions (-> body get-body extract-transactions)
_ @(d/transact conn [[:skirmish.ledger/create-transactions transactions]])])
(catch [:error-type :4XX] e (build-response request e))
(catch [:error-type :5XX] e (build-response request e)))))
(defn create-routes-for-ledger [conn]
(compojure/routes
(routes/context :ledger []
(routes/GET :ledger/home [] get-api-description)
(routes/GET :ledger/accounts [] (get-available-accounts conn))
(routes/GET :ledger/account [] (get-account conn))
(routes/GET :ledger/transactions [] (get-transactions conn))
(routes/POST :ledger/transactions [] (create-transactions conn))
(routes/GET :ledger/securities [] (get-available-securities conn)) ;; done
(routes/POST :ledger/securities [] (create-security conn)) ;; done
(routes/GET :ledger/security [] (get-security conn)) ;; done
(routes/PUT :ledger/security [] (update-security conn)) ;; not done
(routes/POST :ledger/security [] (emit-securities conn))) ;; done
(not-found "not found")))
(defn -main [config securities-api exchange-apis]
(let [ledger-config (:ledger-server config)
conn (skirmish.ledger.accounts/create-connection (-> config :datomic :transactor-url))
api-routes (create-routes-for-ledger conn)]
api-routes (controllers/create-routes-for-ledger conn)]
(timbre/info "Running skirmish.ledger.core server with config: " ledger-config)
(run-server
(-> api-routes api cors-middleware)