Smart Contract

TitPalacePortraits

A.66b60643244a7738.TitPalacePortraits

Deployed

3d ago
Feb 25, 2026, 12:54:15 AM UTC

Dependents

24 imports
1
2// Mainnet
3import NonFungibleToken from 0x1d7e57aa55817448
4import MetadataViews from 0x1d7e57aa55817448 
5import FungibleToken from 0xf233dcee88fe0abe
6import FlowToken from 0x1654653399040a61
7import ViewResolver from 0x1d7e57aa55817448
8
9//Testnet
10// import NonFungibleToken from 0x631e88ae7f1d7c20
11// import MetadataViews from 0x631e88ae7f1d7c20
12
13access(all) contract TitPalacePortraits: NonFungibleToken {
14
15	//Define Events
16	access(all) event ContractInitialized()
17	access(all) event Withdraw(id: UInt64, from: Address?)
18	access(all) event Deposit(id: UInt64, to: Address?)
19	access(all) event ExclusiveMinted(id: UInt64, name: String, description: String, image: String, traits: {String:String})
20
21	//Define Paths
22	access(all) let CollectionStoragePath: StoragePath
23	access(all) let CollectionPublicPath: PublicPath
24	access(all) let CollectionPrivatePath: PrivatePath
25	access(all) let AdminStoragePath: StoragePath
26
27	//Difine Total Supply
28	access(all) var totalSupply: UInt64
29
30	access(all) struct titPalacePortraitsMetadata {
31		access(all) let id: UInt64
32		access(all) let name: String
33		access(all) let description: String 
34		access(all) let image: String
35		access(all) let traits: {String:String}
36
37		init(_id: UInt64, _name: String, _description: String, _image: String, _traits:{String:String}) {
38			self.id = _id
39			self.name = _name
40			self.description = _description
41			self.image = _image
42			self.traits = _traits
43		}
44	}
45
46	access(all) resource NFT: NonFungibleToken.NFT  {
47
48		access(all) let id: UInt64
49		access(all) let name: String
50		access(all) let description: String
51		access(all) var image: String
52		access(all) let traits: {String: String}
53
54		init( _id: UInt64, _name: String, _description: String, _image: String, _traits: {String:String}) {
55			
56			self.id = _id
57			self.name = _name
58			self.description = _description
59			self.image = _image
60			self.traits = _traits
61		}
62
63        access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection}  {
64   		    return <- TitPalacePortraits.createEmptyCollection(nftType: Type<@TitPalacePortraits.NFT>())
65   	    }
66
67		access(all) fun revealThumbnail() {
68            let urlBase = self.image.slice(from: 0, upTo: 47)
69            let newImage = urlBase.concat(self.id.toString()).concat(".png")
70            self.image = newImage
71        }
72
73		access(all) view fun getViews(): [Type] {
74			return [
75				Type<MetadataViews.Display>(),
76				Type<MetadataViews.ExternalURL>(),
77				Type<MetadataViews.NFTCollectionData>(),
78				Type<MetadataViews.NFTCollectionDisplay>(),
79				Type<TitPalacePortraits.titPalacePortraitsMetadata>(),
80                Type<MetadataViews.Royalties>(),
81				Type<MetadataViews.Traits>()				
82			]
83		}
84
85		access(all) fun resolveView(_ view: Type): AnyStruct? {
86			switch view {
87
88				case Type<MetadataViews.Display>():
89					return MetadataViews.Display(
90                        name: self.name,
91                        description: self.description,
92                        thumbnail: MetadataViews.IPFSFile(
93                            cid: self.image,
94                            path: nil
95                        )
96                    )
97
98                case Type<MetadataViews.ExternalURL>():
99         			return MetadataViews.ExternalURL("https://titpalace.xyz/")
100
101                case Type<MetadataViews.NFTCollectionData>():
102                    return TitPalacePortraits.resolveContractView(resourceType: nil, viewType: Type<MetadataViews.NFTCollectionData>())
103                case Type<MetadataViews.NFTCollectionDisplay>():
104                     return TitPalacePortraits.resolveContractView(resourceType: nil, viewType: Type<MetadataViews.NFTCollectionDisplay>())
105                
106
107				case Type<TitPalacePortraits.titPalacePortraitsMetadata>():
108					return TitPalacePortraits.titPalacePortraitsMetadata(
109						_id: self.id,
110						_name: self.name,
111						_description: self.description,
112						_image: self.image,
113						_traits: self.traits
114					)
115
116
117
118                case Type<MetadataViews.Royalties>():
119                    return MetadataViews.Royalties([])
120
121				case Type<MetadataViews.Traits>():
122					let traits: [MetadataViews.Trait] = []
123                    for trait in self.traits.keys {
124                        traits.append(MetadataViews.Trait(
125                            name: trait,
126                            value: self.traits[trait]!,
127                            displayType: nil,
128                            rarity: nil
129                        ))
130                    }
131                    return MetadataViews.Traits(traits)
132				
133			}
134			return nil
135		}
136
137		
138	}
139
140	access(all) resource interface CollectionPublic: NonFungibleToken.CollectionPublic {
141		access(all) fun deposit(token: @{NonFungibleToken.NFT})
142        access(all) fun borrowTitPalacePortraits(id: UInt64): &TitPalacePortraits.NFT? {
143            post {
144                (result == nil) || (result?.id == id):
145                    "Cannot borrow TitPalacePortraits reference: The ID of the returned reference is incorrect."
146            }
147        }
148	}
149
150	access(all) resource Collection: CollectionPublic, NonFungibleToken.Collection {
151		// dictionary of NFT conforming tokens
152		// NFT is a resource type with an 'UInt64' ID field
153		access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
154
155
156   	 access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
157   		 let supportedType: {Type: Bool}  = {}
158   		 supportedType[Type<@TitPalacePortraits.NFT>()] = true
159   		 return supportedType
160   	 }
161
162
163   	 access(all) view fun isSupportedNFTType(type: Type): Bool {
164   		 if type == Type<@TitPalacePortraits.NFT>() {
165   			return true
166   		 } 
167   	    return false
168   		 
169   	 }
170
171		// withdraw removes an NFT from the collection and moves it to the caller
172		access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
173			let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
174			return <-token
175		}
176
177		// deposit takes a NFT and adds it to the collections dictionary
178		// and adds the ID to the id array
179		access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
180			let token <- token as! @TitPalacePortraits.NFT
181
182			let id: UInt64 = token.id
183
184			let oldToken <- self.ownedNFTs[id] <- token
185
186
187            destroy oldToken
188			
189		}
190
191		// getIDs returns an array of the IDs that are in the collection
192		access(all) view fun getIDs(): [UInt64] {
193			return self.ownedNFTs.keys
194		}
195
196        access(all) view fun getLength(): Int {
197   		    return self.ownedNFTs.keys.length
198   	    }
199
200    	access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
201   		 if let nft  = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
202   			 return nft as &{ViewResolver.Resolver}
203   		 }
204   		 return nil
205   	 }
206
207
208		// borrowNFT gets a reference to an NFT in the collection
209		// so that the caller can read its metadata and call its methods
210   	 access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
211   		 return (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
212   	 }
213
214
215   	access(all) fun borrowTitPalacePortraits(id: UInt64): &TitPalacePortraits.NFT? {
216   		    if let nft  = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
217   			    return nft as! &NFT
218   		    }
219   		 return nil
220    	}
221
222
223        init () {
224            self.ownedNFTs <- {}
225        }
226
227        access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
228            return <- create Collection()
229        }
230
231
232	}
233
234    access(all) view fun getContractViews(resourceType: Type?): [Type] {
235        return [Type<MetadataViews.NFTCollectionData>(), Type<MetadataViews.NFTCollectionDisplay>(), Type<MetadataViews.Royalties>()]
236    }
237
238    /// Resolve this contract's metadata views
239    ///
240    access(all) view fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
241        post {
242            result == nil || result!.getType() == viewType: "The returned view must be of the given type or nil"
243        }
244        switch viewType {
245            case Type<MetadataViews.NFTCollectionData>():
246                return MetadataViews.NFTCollectionData(
247                    storagePath: /storage/TitPalacePortraitsCollection,
248                    publicPath: /public/TitPalacePortraitsCollection,
249                    publicCollection: Type<&TitPalacePortraits.Collection>(),
250                    publicLinkedType: Type<&TitPalacePortraits.Collection>(),
251                    createEmptyCollectionFunction: (fun (): @{NonFungibleToken.Collection} {
252                        return <-TitPalacePortraits.createEmptyCollection(nftType: Type<@TitPalacePortraits.NFT>())
253                    })
254                )
255            case Type<MetadataViews.NFTCollectionDisplay>():
256					let squareMedia = MetadataViews.Media(
257						file: MetadataViews.HTTPFile(
258							url: "https://pbs.twimg.com/profile_images/1775300465405636608/2Lyf_CaB_400x400.jpg"
259						),
260						mediaType: "image"
261					)
262					let bannerMedia = MetadataViews.Media(
263                        file: MetadataViews.HTTPFile(
264                            url: "https://pbs.twimg.com/profile_banners/1721863597683277824/1703012922/600x200"
265                        ),
266                        mediaType: "image"
267                    )
268                return MetadataViews.NFTCollectionDisplay(
269                    name: "Tit Palace Portraits",
270                    description: "An adult NFT collection with AI generated topless modals.",
271                    externalURL: MetadataViews.ExternalURL("https://titpalace.xyz"),
272                    squareImage: squareMedia,
273                    bannerImage: bannerMedia,
274                    socials: {
275                        "twitter": MetadataViews.ExternalURL("https://x.com/vertico_defi"),
276                        "instagram": MetadataViews.ExternalURL("https://www.instagram.com/titpalace/")
277                    }
278                )
279
280        }
281        return nil
282    }
283
284    access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
285   	    return <- create Collection()
286    }
287
288
289
290
291	access(all) resource Admin {
292		access(all) fun mintNFT(
293            recipient: &{NonFungibleToken.CollectionPublic}, 
294            name: String, 
295            description: String, 
296            image: String, 
297            traits: {String:String}
298            ) {
299			    emit ExclusiveMinted(id: TitPalacePortraits.totalSupply, name: name, description: description, image: image, traits: traits)
300			    TitPalacePortraits.totalSupply = TitPalacePortraits.totalSupply + (1 as UInt64)
301
302			recipient.deposit(token: <- create TitPalacePortraits.NFT(
303                _id: TitPalacePortraits.totalSupply,
304                _name: name,
305                _description: description,
306                _image: image,
307                _traits: traits
308                )
309			)
310		}	
311	}
312
313	init() {
314		
315		self.CollectionStoragePath = /storage/TitPalacePortraitsCollection
316		self.CollectionPublicPath = /public/TitPalacePortraitsCollection
317		self.CollectionPrivatePath = /private/TitPalacePortraitsCollection
318		self.AdminStoragePath = /storage/TitPalacePortraitsMinter
319
320		self.totalSupply = 0
321
322		let minter <- create Admin()
323		self.account.storage.save(<-minter, to: self.AdminStoragePath)
324
325		let collection <- create Collection()
326		self.account.storage.save(<- collection, to: self.CollectionStoragePath)
327
328        let collectionCap = self.account.capabilities.storage.issue<&TitPalacePortraits.Collection>(self.CollectionStoragePath)
329        self.account.capabilities.publish(collectionCap, at: self.CollectionPublicPath)
330        
331		
332		emit ContractInitialized()
333	}
334}