From c5d4e83d44818525596205adec5dd024579bf8a1 Mon Sep 17 00:00:00 2001 From: didier amyot Date: Thu, 10 Sep 2020 12:17:42 -0400 Subject: [PATCH] started to implement transactions. --- src/clj/skirmish/ledger/accounts.clj | 13 +++++++- src/clj/skirmish/ledger/core.clj | 30 ++++++++++++++----- .../wui/components/security_page.cljs | 9 +++--- .../skirmish/wui/components/todo_page.cljs | 4 +-- test/clj/skirmish/ledger/test_core.clj | 19 ++++++------ 5 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/clj/skirmish/ledger/accounts.clj b/src/clj/skirmish/ledger/accounts.clj index cbea7cd..e648fa5 100644 --- a/src/clj/skirmish/ledger/accounts.clj +++ b/src/clj/skirmish/ledger/accounts.clj @@ -35,6 +35,16 @@ [:db/add entity :skirmish.ledger/owner-public-key account-public-key] [:db/add entity :skirmish.ledger/sec (:db/id security)]])})}]) +(def create-transactions + [{:db/ident :skirmish.ledger/create-transactions + :db/doc "Move money from one account to the other." + :db/fn (d/function {:lang "clojure" + :requires ['[slingshot.slingshot]] + :params '[db transactions] + :code '(let [from-account-id (map :from-account-id transactions) + from-accounts (d/pull-many db '[*] (for [] [:skirmish.ledger/owner-public-key "2-sec-2"]))] + [])})}]) + ;; there are different types of securities... ;; 1. currencies, which pays interest rates in their one sec-id. ;; 2. equities, which do not pay interest rates. @@ -114,7 +124,8 @@ (concat schema-securities) (concat ledger-schema) (concat create-securities) - (concat print-securities))) + (concat print-securities) + (concat create-transactions))) (defn add-default-currencies [conn] diff --git a/src/clj/skirmish/ledger/core.clj b/src/clj/skirmish/ledger/core.clj index a51641f..e7b20a3 100644 --- a/src/clj/skirmish/ledger/core.clj +++ b/src/clj/skirmish/ledger/core.clj @@ -117,15 +117,16 @@ account-info (get-amount-in-account db account-id)] (get-account-body request account-info)))) -(s/def ::transaction (s/cat :type #{:create} - :sec-id keyword? - :amount int? - :account-id string?)) +(s/def ::transaction (s/cat :type #{:transfer-immediately} + :from-account-id string? + :to-account-id string? + :amount int?)) +(s/def ::transactions (s/coll-of ::transaction)) -(defn get-transaction [raw-transact] - (if (s/valid? ::transaction raw-transact) - (s/conform ::transaction raw-transact) +(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."}}))) @@ -267,6 +268,19 @@ {: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 @@ -274,6 +288,8 @@ (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 diff --git a/src/cljs/skirmish/wui/components/security_page.cljs b/src/cljs/skirmish/wui/components/security_page.cljs index 3318344..59c28e3 100644 --- a/src/cljs/skirmish/wui/components/security_page.cljs +++ b/src/cljs/skirmish/wui/components/security_page.cljs @@ -22,12 +22,13 @@ [:td "Security ID"] [:td (:sec-id sec-info)]] [:tr [:td "Type"] [:td (:type sec-info)]] + (when-let [symbol (:symbol sec-info)] + [:tr + [:td "Symbol"] [:td symbol]]) [:tr - [:td "Symbol"] [:td (:symbol sec-info)]] + [:td "Interest Rate"] [:td (-> sec-info :interest-rate (pp-int 2) (str " %"))]] [:tr - [:td "Interest Rate"] [:td (:interest-rate sec-info)]] - [:tr - [:td "Total Volume"] [:td (-> sec-info :volume (pp-int (:number-of-decimal sec-info)))]]]]]) + [:td "Total Volume"] [:td (-> sec-info :volume (pp-int (:number-of-decimal sec-info)) (str " " (:symbol sec-info)))]]]]]) (defn ledger-table [sec-id] diff --git a/src/cljs/skirmish/wui/components/todo_page.cljs b/src/cljs/skirmish/wui/components/todo_page.cljs index c8f01fa..8300ef4 100644 --- a/src/cljs/skirmish/wui/components/todo_page.cljs +++ b/src/cljs/skirmish/wui/components/todo_page.cljs @@ -47,8 +47,8 @@ [:li "move 'routes' in 'rest'"] [:li "add a little bit of professionalism on top of the broker api"] [:li "make the api support transit and edn"] - [:li on-it "implements interest rate in ledger."] - [:li "Make sure the ledger can have accounts"] + [:li done "implements interest rate in ledger."] + [:li done "Make sure the ledger can have accounts"] [:li done "when a new user signs in, he should receive some sort of money"] [:li "implement send securities to friends"] [:li "implement buy/sell securities."] diff --git a/test/clj/skirmish/ledger/test_core.clj b/test/clj/skirmish/ledger/test_core.clj index 780166f..c2c69b0 100644 --- a/test/clj/skirmish/ledger/test_core.clj +++ b/test/clj/skirmish/ledger/test_core.clj @@ -98,16 +98,17 @@ create-request {:body (edn->stream security) :headers {"accept" "application/edn"}} _ ((create-security conn) create-request) request {:route-params {:sec-id :new-currency} :headers {"accept" "application/edn"}} - resp ((get-security conn) request)] + resp ((get-security conn) request) + expt {:sec-id :new-currency + :interest-rate 100 + :name nil + :description nil + :number-of-decimal nil + :symbol nil + :type nil + :volume 0}] resp => (spec-check ::ok) - (body resp) => {:sec-id :new-currency - :interest-rate 100 - :name nil - :description nil - :number-of-decimal nil - :symbol nil - :type nil - :volume 0})) + (body resp) => (contains expt))) (fact "we should not be able to get-security if it does not exists" (let [conn (create-conn)