convex.asset.nft.simple.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!
'asset.nft.simple
(call *registry*
(register {:description ["Enables the creation of minimal NFT tokens."
"A Simple NFT is merely an ownable Integer ID. Users can build an additional layer so that this ID points to anything."
"Follows the interface described in `convex.asset`."]
:name "Simple NFT creation and management"}))
(declare balance)
;;;;;;;;;; Values
(def counter
^{:doc {:description "Used for creating NFT ids."}}
0)
(def offers
^{:doc {:description "Map of `owner` -> map of `recipient address` -> `set of NFT ids`"}}
{})
;;;;;;;;;; Implementation of `convex.asset` interface
(defn -qc
^{:doc {:description "Checks a NFT quantity."}
:private true}
[q]
(cond (set? q) q ;; base case, quantity should always be a Set
(int? q) #{q}
(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 "Insufficient NFT balance"))
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
:private true}
[sender quantity]
(let [q (-qc quantity)
sender (address sender)
sender-offers (or (get offers
sender)
{})
offer (get-in offers [sender *caller*] #{})
_ (or (subset? q offer)
(fail :STATE "Insufficient 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* q)))
(defn balance
^{:callable true
:private 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 burn
^{:callable true
:doc {:description "Destroys a set of NFTs. NFTs must be owned by the caller."
:signature [{:params [nft-set]}]}}
[nft-set]
(let [owned-nfts (get-holding *caller*)
nft-set (-qc nft-set)]
(when-not (subset? nft-set
owned-nfts)
(fail :TRUST "Can only burn owned NFTs"))
(set-holding *caller*
(difference owned-nfts
nft-set))
nft-set))
(defn create
^{:callable true
:doc {:description "Creates a new NFT with a fresh ID."
:signature [{:params []}]}}
[]
(let [id counter
owner *caller*
owned-nfts (or (get-holding owner)
#{})]
(set-holding owner
(conj owned-nfts
id))
(def counter
(inc counter))
id))