convex.lab.archon.cvx Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of convex-core Show documentation
Show all versions of convex-core Show documentation
Convex core libraries and common utilities
The newest version!
'archon
(call *registry*
(register {:description ["Archon NFT collection actor."]
:name "Archon Actor"}))
;;;;;;;;;; Governance
;; We set a controller with upgrade and access rights. This can be removed / modified later
;; Use the current controller, or the geneses peer account #12 if unspecified
(define guv (or *controller* #12))
(set-controller guv)
;;;;;;;;;; Values
(define offers
^{:doc {:description "Map of `owner` -> map of `recipient address` -> `set of NFT ids`"}}
{})
(define base-url "http://localhost:8080/dlfs/archon0x")
;;;;;;;;;; Archon specific functionality
;; Determine if an ID is valid
(defn valid-id? [id]
(cond
(and
(blob? id)
(= 2 (count id))
(<= 1 (int id) 1024))
true
false))
;; Archon NFT minting, performed once
(loop [nfts #{} i 1]
(cond
;; looping for each Archon NFT
(<= i 1024)
;; Run this branch for each NFT
(let [;; Generate a 2 byte blob. Small new numeric IDs need an extra byte
nft (blob i)
nft (if (< i 128) (blob (str "00" nft)) nft)]
(if (valid-id? nft)
(recur (conj nfts nft) (inc i))
(fail (str "Somehow created an invalid NFT:" nft))))
;; When done give all NFTs to governance account
(do (set-holding guv nfts)
(or (= (count nfts) 1024) (fail "Unexpected total number of Archons" (count nfts))))))
;;;;;;;;;; Implementation of `convex.asset` interface
;; These functions provide full CAD19 asset functionality
;;
;; Quanity check
(defn -qc
[q]
(cond
(set? q) q ;; base case, quantity should always be a Set
(valid-id? q) #{q} ;; we allow a blob ID to be used as a quanitity if valid
(nil? q) #{}
(fail :ARGUMENT "Invalid NFT quantity")))
(defn -direct-transfer
^{:private? true}
;; Used internally by [[accept]] and [[direct-transfer]].
[sender receiver quantity]
(let [q (-qc quantity)
receiver (address receiver)
sender-balance (or (get-holding sender)
#{})
_ (or (subset? q sender-balance)
(fail :FUNDS "Cannot transfer non-owned NFT(s)"))
receiver-balance (or (get-holding receiver)
#{})
new-sender-balance (difference sender-balance q)
new-receiver-balance (union receiver-balance q)]
(set-holding sender new-sender-balance)
(set-holding receiver new-receiver-balance)
quantity))
(defn accept
^{:callable true}
[sender quantity]
(let [q (-qc quantity)
sender (address sender)
sender-offers (or (get offers
sender)
{})
offer (or (get-in offers
[sender
*caller*])
#{})
_ (or (subset? q offer)
(fail :STATE "Insuffient NFT offer to accept"))
receiver-balance (or (get-holding *caller*)
#{})
new-offer (difference offer q)]
(set! offers
(assoc offers
sender
(assoc sender-offers
*caller*
new-offer)))
(-direct-transfer sender
*caller*
quantity)))
(defn balance
^{:callable true}
[owner]
(or (get-holding owner)
#{}))
(defn direct-transfer
^{:callable true}
[receiver quantity data]
(-direct-transfer *caller*
receiver
quantity))
(defn offer
^{:callable true}
[receiver quantity]
(let [q (-qc quantity)
caller-offers (get offers *caller* {})]
(set! offers
(assoc offers
*caller*
(assoc caller-offers
receiver
q)))))
(def quantity-add
^{:callable true}
union)
(def quantity-sub
^{:callable true}
difference)
(def quantity-subset?
^{:callable true}
subset?)
;;;;;;;;;; Callable functions
(defn get-metadata
^{:callable true
:doc {:description "Gets metadata for a given NFT ID."
:signature [{:params []}
{:params [id]}]}}
([] (recur *scope*))
([id]
(or (valid-id? id) (return nil))
(let [hex (str id)
img (str base-url hex ".png")]
{
"name" "Archon"
"image" img
})))