-
Notifications
You must be signed in to change notification settings - Fork 6
/
shop.con
74 lines (53 loc) · 2.12 KB
/
shop.con
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
(def shop
(deploy
'(do
(import convex.asset :as asset)
(def counter 0)
;; Listings indexed by ID.
(def listings {})
(defn ^{:callable? true} add-listing [listing]
(let [owner *caller*
;; Counter is a good-enough mechanism to manage IDs.
id counter]
;; Accept offer (caller must offer the Asset first).
;; This call will in turn call the `accept` function of the Asset Actor.
;; See the Asset library source for more details.
(asset/accept *caller* (:asset listing))
;; Update available Listings (indexed by ID).
(def listings (assoc listings id (merge listing {:id id :owner owner})))
(def counter (inc counter))
id))
(defn ^{:callable? true} remove-listing [id]
(let [owner *caller*]
;; The owner is the only one allowed to remove the Listing.
(when (not (= owner (get-in listings [id :owner])))
(fail "Not allowed."))
;; Offer Asset to owner.
(asset/transfer owner (get-in listings [id :asset]))
;; Update available Listings (indexed by ID).
(def listings (dissoc listings id))
nil))
;; Returns a list with all Listings.
(defn ^{:callable? true} shop []
(values listings))
(defn ^{:callable? true} buy-listing [id]
(let [listing (get listings id)
buyer *caller*
seller (:owner listing)
;; Price is in CVX if `price-with` is nil.
[price price-with] (:price listing)]
(cond
price-with
(do
(asset/accept buyer [price-with price])
(asset/transfer seller [price-with price]))
:else
(let [accepted (accept *offer*)]
(if (< accepted price)
(fail (str accepted " < " price))
(transfer seller accepted))))
;; Transfer Asset to buyer.
(asset/transfer buyer (:asset listing))
;; Remove listing.
(def listings (dissoc listings id))
true)))))