Smart Contract
SimpleFlunksWithTraits
A.bfffec679fff3a94.SimpleFlunksWithTraits
1import NonFungibleToken from 0x1d7e57aa55817448
2import MetadataViews from 0x1d7e57aa55817448
3import ViewResolver from 0x1d7e57aa55817448
4
5access(all)
6contract SimpleFlunksWithTraits: NonFungibleToken {
7
8 access(all) event ContractInitialized()
9 access(all) event Withdraw(id: UInt64, from: Address?)
10 access(all) event Deposit(id: UInt64, to: Address?)
11 access(all) event Minted(id: UInt64, to: Address?)
12
13 access(all) var totalSupply: UInt64
14
15 access(all) let CollectionStoragePath: StoragePath
16 access(all) let CollectionPublicPath: PublicPath
17 access(all) let AdminStoragePath: StoragePath
18
19 // Trait structure for NFT attributes
20 access(all) struct Trait {
21 access(all) let name: String
22 access(all) let value: AnyStruct
23 access(all) let displayType: String?
24 access(all) let rarity: String?
25
26 init(name: String, value: AnyStruct, displayType: String?, rarity: String?) {
27 self.name = name
28 self.value = value
29 self.displayType = displayType
30 self.rarity = rarity
31 }
32 }
33
34 access(all) resource NFT: NonFungibleToken.NFT, ViewResolver.Resolver {
35
36 access(all) let id: UInt64
37 access(all) let name: String
38 access(all) let description: String
39 access(all) let image: String
40 access(all) let traits: [Trait]
41 access(all) let externalURL: String?
42 access(all) let animationURL: String?
43 access(all) let edition: UInt64?
44 access(all) let maxEdition: UInt64?
45
46 init(
47 id: UInt64,
48 name: String,
49 description: String,
50 image: String,
51 traits: [Trait],
52 externalURL: String?,
53 animationURL: String?,
54 edition: UInt64?,
55 maxEdition: UInt64?
56 ) {
57 self.id = id
58 self.name = name
59 self.description = description
60 self.image = image
61 self.traits = traits
62 self.externalURL = externalURL
63 self.animationURL = animationURL
64 self.edition = edition
65 self.maxEdition = maxEdition
66 }
67
68 access(all) view fun getViews(): [Type] {
69 return [
70 Type<MetadataViews.Display>(),
71 Type<MetadataViews.Traits>(),
72 Type<MetadataViews.Editions>(),
73 Type<MetadataViews.ExternalURL>(),
74 Type<MetadataViews.NFTCollectionData>(),
75 Type<MetadataViews.NFTCollectionDisplay>(),
76 Type<MetadataViews.Serial>(),
77 Type<MetadataViews.Royalties>()
78 ]
79 }
80
81 access(all) fun resolveView(_ view: Type): AnyStruct? {
82 switch view {
83 case Type<MetadataViews.Display>():
84 return MetadataViews.Display(
85 name: self.name,
86 description: self.description,
87 thumbnail: MetadataViews.HTTPFile(url: self.image)
88 )
89
90 case Type<MetadataViews.Traits>():
91 let traitsView: [MetadataViews.Trait] = []
92 for trait in self.traits {
93 traitsView.append(MetadataViews.Trait(
94 name: trait.name,
95 value: trait.value,
96 displayType: trait.displayType,
97 rarity: trait.rarity != nil ? MetadataViews.Rarity(
98 score: nil,
99 max: nil,
100 description: trait.rarity!
101 ) : nil
102 ))
103 }
104 return MetadataViews.Traits(traitsView)
105
106 case Type<MetadataViews.Editions>():
107 if self.edition != nil && self.maxEdition != nil {
108 return MetadataViews.Editions([
109 MetadataViews.Edition(
110 name: "SimpleFlunks Edition",
111 number: self.edition!,
112 max: self.maxEdition
113 )
114 ])
115 }
116 return nil
117
118 case Type<MetadataViews.ExternalURL>():
119 if self.externalURL != nil {
120 return MetadataViews.ExternalURL(self.externalURL!)
121 }
122 return nil
123
124 case Type<MetadataViews.Serial>():
125 return MetadataViews.Serial(self.id)
126
127 case Type<MetadataViews.Royalties>():
128 return MetadataViews.Royalties([])
129 }
130 return nil
131 }
132
133 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
134 return <-create Collection()
135 }
136 }
137
138 access(all) resource Collection: NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.Collection, NonFungibleToken.CollectionPublic, ViewResolver.ResolverCollection {
139
140 access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
141
142 init() {
143 self.ownedNFTs <- {}
144 }
145
146 access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
147 let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
148 emit Withdraw(id: token.id, from: self.owner?.address)
149 return <-token
150 }
151
152 access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
153 let token <- token as! @SimpleFlunksWithTraits.NFT
154 let id: UInt64 = token.id
155 let oldToken <- self.ownedNFTs[id] <- token
156 emit Deposit(id: id, to: self.owner?.address)
157 destroy oldToken
158 }
159
160 access(all) view fun getIDs(): [UInt64] {
161 return self.ownedNFTs.keys
162 }
163
164 access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
165 return &self.ownedNFTs[id]
166 }
167
168 access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
169 if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
170 return nft as &{ViewResolver.Resolver}
171 }
172 return nil
173 }
174
175 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
176 return <-create Collection()
177 }
178
179 access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
180 return {Type<@SimpleFlunksWithTraits.NFT>(): true}
181 }
182
183 access(all) view fun isSupportedNFTType(type: Type): Bool {
184 return type == Type<@SimpleFlunksWithTraits.NFT>()
185 }
186 }
187
188 access(all) resource Admin {
189
190 access(all) fun mintNFT(
191 recipient: &{NonFungibleToken.CollectionPublic},
192 name: String,
193 description: String,
194 image: String,
195 traits: [Trait],
196 externalURL: String?,
197 animationURL: String?,
198 edition: UInt64?,
199 maxEdition: UInt64?
200 ) {
201 let newNFT <- create NFT(
202 id: SimpleFlunksWithTraits.totalSupply,
203 name: name,
204 description: description,
205 image: image,
206 traits: traits,
207 externalURL: externalURL,
208 animationURL: animationURL,
209 edition: edition,
210 maxEdition: maxEdition
211 )
212
213 let recipientAddress = recipient.owner!.address
214
215 recipient.deposit(token: <-newNFT)
216
217 emit Minted(id: SimpleFlunksWithTraits.totalSupply, to: recipientAddress)
218
219 SimpleFlunksWithTraits.totalSupply = SimpleFlunksWithTraits.totalSupply + 1
220 }
221 }
222
223 access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
224 return <-create Collection()
225 }
226
227 access(all) view fun getContractViews(resourceType: Type?): [Type] {
228 return [Type<MetadataViews.NFTCollectionData>()]
229 }
230
231 access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
232 switch viewType {
233 case Type<MetadataViews.NFTCollectionData>():
234 return MetadataViews.NFTCollectionData(
235 storagePath: SimpleFlunksWithTraits.CollectionStoragePath,
236 publicPath: SimpleFlunksWithTraits.CollectionPublicPath,
237 publicCollection: Type<&SimpleFlunksWithTraits.Collection>(),
238 publicLinkedType: Type<&SimpleFlunksWithTraits.Collection>(),
239 createEmptyCollectionFunction: (fun (): @{NonFungibleToken.Collection} {
240 return <-SimpleFlunksWithTraits.createEmptyCollection(nftType: Type<@SimpleFlunksWithTraits.Collection>())
241 })
242 )
243 }
244 return nil
245 }
246
247 init() {
248 self.totalSupply = 0
249
250 self.CollectionStoragePath = /storage/SimpleFlunksWithTraitsCollection
251 self.CollectionPublicPath = /public/SimpleFlunksWithTraitsCollection
252 self.AdminStoragePath = /storage/SimpleFlunksWithTraitsAdmin
253
254 let admin <- create Admin()
255 self.account.storage.save(<-admin, to: self.AdminStoragePath)
256
257 emit ContractInitialized()
258 }
259}
260