Smart Contract
DNAHandler
A.3cdbb3d569211ff3.DNAHandler
1import FlowtyListingCallback from 0x3cdbb3d569211ff3
2import FlowtyViews from 0x3cdbb3d569211ff3
3import NonFungibleToken from 0x1d7e57aa55817448
4
5/*
6DNAHandler
7
8A contract which contains a resource that handles listing callbacks. Depending on the stage of the listing,
9a the DNAHandler will either:
10 - Record the DNA of an NFT
11 - Compare the DNA of an NFT with its previously recorded value
12 - Remove recorded DNA (it is no longer needed)
13
14If the FlowtyViews.DNA metadata view is not on an NFT, the initial recording of DNA will not be done.
15If, on the other hand, DNA was recorded on an item and then it is found to be missing when a listing is being filled,
16that listing will not be valid, as an empty DNA metadata view is not a match to a previously recorded value. This is to
17handle cases of NFT collections making returning DNA optional.
18*/
19access(all) contract DNAHandler {
20 access(all) resource Handler: FlowtyListingCallback.Handler {
21 access(self) let recordedDNA: {UInt64: String}
22
23 access(FlowtyListingCallback.Handle) fun handle(stage: FlowtyListingCallback.Stage, listing: &{FlowtyListingCallback.Listing}, nft: &{NonFungibleToken.NFT}?): Bool {
24 switch stage {
25 case FlowtyListingCallback.Stage.Created:
26 return self.handleCreate(listing: listing, nft: nft)
27 case FlowtyListingCallback.Stage.Filled:
28 return self.handleFilled(listing: listing, nft: nft!)
29 case FlowtyListingCallback.Stage.Completed:
30 return self.handleCompleted(listing: listing, nft: nft)
31 case FlowtyListingCallback.Stage.Destroyed:
32 return self.handleDestroyed(listing: listing, nft: nft)
33 }
34
35 return true
36 }
37
38 access(all) fun validateListing(listing: &{FlowtyListingCallback.Listing}, nft: &{NonFungibleToken.NFT}?): Bool {
39 var res = false
40 if let n = nft {
41 res = true
42 if let prev = self.recordedDNA[listing.uuid] {
43 let dnaTmp = nft!.resolveView(Type<FlowtyViews.DNA>()) ?? FlowtyViews.DNA("")
44 let dna = dnaTmp as! FlowtyViews.DNA
45 res = dna.value == prev
46 }
47 }
48
49 return res
50 }
51
52 access(self) fun handleCreate(listing: &{FlowtyListingCallback.Listing}, nft: &{NonFungibleToken.NFT}?): Bool {
53 if nft == nil {
54 return true
55 }
56
57 let dnaTmp = nft!.resolveView(Type<FlowtyViews.DNA>())
58 if dnaTmp == nil {
59 return true
60 }
61 let dna = dnaTmp! as! FlowtyViews.DNA
62
63 self.recordedDNA[listing.uuid] = dna.value
64 return true
65 }
66
67 access(self) fun handleFilled(listing: &{FlowtyListingCallback.Listing}, nft: &{NonFungibleToken.NFT}): Bool {
68 assert(self.validateListing(listing: listing, nft: nft), message: "DNA of nft does not match recorded DNA when listing was created")
69 return true
70 }
71
72 access(self) fun handleCompleted(listing: &{FlowtyListingCallback.Listing}, nft: &{NonFungibleToken.NFT}?): Bool {
73 if let ref = nft {
74 if let prev = self.recordedDNA[listing.uuid] {
75 let dnaTmp = ref.resolveView(Type<FlowtyViews.DNA>()) ?? FlowtyViews.DNA("")
76
77 let dna = dnaTmp as! FlowtyViews.DNA
78 assert(dna.value == prev, message: "DNA of nft does not match recorded DNA when listing was created")
79 }
80 }
81
82 self.recordedDNA.remove(key: listing.uuid)
83 return true
84 }
85
86 access(self) fun handleDestroyed(listing: &{FlowtyListingCallback.Listing}, nft: &{NonFungibleToken.NFT}?): Bool {
87 self.recordedDNA.remove(key: listing.uuid)
88 return true
89 }
90
91 init() {
92 self.recordedDNA = {}
93 }
94 }
95
96 access(all) fun createHandler(): @Handler {
97 return <- create Handler()
98 }
99}