Smart Contract

RCRDSHPNFT

A.6c3ff40b90b928ab.RCRDSHPNFT

Deployed

2h ago
Mar 01, 2026, 12:57:41 PM UTC

Dependents

0 imports
1import NonFungibleToken from 0x1d7e57aa55817448
2import MetadataViews from 0x1d7e57aa55817448
3
4pub contract RCRDSHPNFT: NonFungibleToken {
5    pub var totalSupply: UInt64
6    pub let minterStoragePath: StoragePath
7    pub let collectionStoragePath: StoragePath
8    pub let collectionPublicPath: PublicPath
9
10    pub event ContractInitialized()
11    pub event Withdraw(id: UInt64, from: Address?)
12    pub event Deposit(id: UInt64, to: Address?)
13    pub event Burn(id: UInt64, from: Address?)
14    pub event Sale(id: UInt64, price: UInt64)
15
16    pub resource NFT: NonFungibleToken.INFT, MetadataViews.Resolver {
17        pub let id: UInt64
18        pub var metadata: {String: String}
19
20        pub fun getViews(): [Type] {
21            return [
22                Type<MetadataViews.Serial>(),
23                Type<MetadataViews.Display>(),
24                Type<MetadataViews.ExternalURL>(),
25                Type<MetadataViews.NFTCollectionData>(),
26                Type<MetadataViews.NFTCollectionDisplay>(),
27                Type<MetadataViews.Royalties>(),
28                Type<MetadataViews.Traits>()
29            ]
30        }
31
32
33
34        pub fun resolveView(_ view: Type): AnyStruct? {
35
36            let metadata = self.metadata
37
38            fun getMetaValue(_ key: String, _ defaultVal: String) : String {
39                return metadata[key] ?? defaultVal
40            }
41
42            fun getThumbnail(): MetadataViews.HTTPFile {
43                let url = metadata["uri"] == nil ? "https://rcrdshp-happyfox-assets.s3.amazonaws.com/Purple.svg" : metadata["uri"]!.concat("/thumbnail")
44                return MetadataViews.HTTPFile(url: url)
45            }
46
47            fun createGenericDisplay(): MetadataViews.Display {
48                let name = getMetaValue("name", "?RCRDSHP NFT?")
49                let serial = getMetaValue("serial_number", "?")
50                return MetadataViews.Display(
51                    name: name,
52                    description: getMetaValue("description", "An unknown RCRDSHP Collection NFT"),
53                    thumbnail: getThumbnail()
54                )
55            }
56
57            fun createVoucherDisplay(): MetadataViews.Display {
58                let name = getMetaValue("name", "?RCRDSHP Voucher NFT?")
59                let serial = getMetaValue("voucher_serial_number", "?")
60                let isFlowFest = name.slice(from: 0, upTo: 9) == "Flow fest"
61                return MetadataViews.Display(
62                    name: name.concat(" #").concat(serial),
63                    description: getMetaValue("description", "An unknown RCRDSHP Collection Vouncher NFT"),
64                    thumbnail: isFlowFest ? MetadataViews.HTTPFile(url: "https://rcrdshp-happyfox-assets.s3.amazonaws.com/flowfest-pack.png") : getThumbnail()
65                )
66            }
67
68            fun createTraits(): MetadataViews.Traits {
69                let rarity = metadata["rarity"]
70                if rarity == nil{
71                    return MetadataViews.Traits(traits: [])
72                } else {
73                    let rarityTrait = MetadataViews.Trait(
74                        name: "Rarity",
75                        value: rarity!,
76                        rarity: nil,
77                        displayType: nil
78                    )
79                    return MetadataViews.Traits(traits: [rarityTrait])
80                }
81            }
82
83            fun createExternalURL(): MetadataViews.ExternalURL {
84                return MetadataViews.ExternalURL(url: metadata["uri"] ?? "https://app.rcrdshp.com")
85            }
86
87            fun createCollectionData(): MetadataViews.NFTCollectionData {
88                return MetadataViews.NFTCollectionData(
89                                                storagePath: RCRDSHPNFT.collectionStoragePath,
90                                                publicPath: RCRDSHPNFT.collectionPublicPath,
91                                                providerPath: /private/RCRDSHPNFTCollection,
92                                                publicCollection: Type<&RCRDSHPNFT.Collection{RCRDSHPNFT.RCRDSHPNFTCollectionPublic}>(),
93                                                publicLinkedType: Type<&RCRDSHPNFT.Collection{RCRDSHPNFT.RCRDSHPNFTCollectionPublic,NonFungibleToken.CollectionPublic,NonFungibleToken.Receiver,MetadataViews.ResolverCollection}>(),
94                                                providerLinkedType: Type<&RCRDSHPNFT.Collection{RCRDSHPNFT.RCRDSHPNFTCollectionPublic,NonFungibleToken.CollectionPublic,NonFungibleToken.Provider,MetadataViews.ResolverCollection}>(),
95                                                createEmptyCollectionFunction: (fun (): @NonFungibleToken.Collection {
96                                                    return <-RCRDSHPNFT.createEmptyCollection()
97                                                })
98                )
99            }
100
101            fun createCollectionDisplay(): MetadataViews.NFTCollectionDisplay {
102                    let squareMedia = MetadataViews.Media(
103                        file: MetadataViews.HTTPFile(
104                            url: "https://rcrdshp-happyfox-assets.s3.amazonaws.com/Purple.svg"
105                        ),
106                        mediaType: "image/svg+xml"
107                    )
108                    let bannerMedia = MetadataViews.Media(
109                        file: MetadataViews.HTTPFile(
110                            url: "https://rcrdshp-happyfox-assets.s3.amazonaws.com/banner.png"
111                        ),
112                        mediaType: "image/png"
113                    )
114
115                    return MetadataViews.NFTCollectionDisplay(
116                        name: "The RCRDSHP Collection",
117                        description: "Here comes the drop!",
118                        externalURL: MetadataViews.ExternalURL("https://app.rcrdshp.com"),
119                        squareImage: squareMedia,
120                        bannerImage: bannerMedia,
121                        socials: {
122                            "twitter": MetadataViews.ExternalURL("https://twitter.com/rcrdshp"),
123                            "instagram": MetadataViews.ExternalURL("https://www.instagram.com/rcrdshp"),
124                            "discord": MetadataViews.ExternalURL("https://discord.gg/rcrdshp"),
125                            "facebook": MetadataViews.ExternalURL("https://www.facebook.com/rcrdshp")
126                        }
127                    )
128            }
129
130            fun createRoyalties(): MetadataViews.Royalties {
131               let royalties : [MetadataViews.Royalty] = []
132               return MetadataViews.Royalties(royalties: royalties)
133            }
134
135            fun parseUInt64(_ string: String) : UInt64? {
136                let chars : {Character : UInt64} = {
137                    "0" : 0 ,
138                    "1" : 1 ,
139                    "2" : 2 ,
140                    "3" : 3 ,
141                    "4" : 4 ,
142                    "5" : 5 ,
143                    "6" : 6 ,
144                    "7" : 7 ,
145                    "8" : 8 ,
146                    "9" : 9
147                }
148                var number : UInt64 = 0
149                var i = 0
150                while i < string.length {
151                    if let n = chars[string[i]] {
152                            number = number * 10 + n
153                    } else {
154                        return nil
155                    }
156                    i = i + 1
157                }
158                return number
159            }
160
161
162            switch view {
163                case Type<MetadataViews.Serial>():
164                    return MetadataViews.Serial(parseUInt64(getMetaValue("serial_number", "0")) ?? 0)
165                case Type<MetadataViews.Display>():
166                    return metadata["type"] == "Voucher" ? createVoucherDisplay() : createGenericDisplay()
167                case Type<MetadataViews.ExternalURL>():
168                    return createExternalURL()
169                case Type<MetadataViews.NFTCollectionData>():
170                    return createCollectionData()
171                case Type<MetadataViews.NFTCollectionDisplay>():
172                    return createCollectionDisplay()
173                case Type<MetadataViews.Royalties>():
174                    return createRoyalties()
175                case Type<MetadataViews.Traits>():
176                    return createTraits()
177            }
178            return nil
179        }
180
181        init(initID: UInt64, metadata: {String : String}) {
182            self.id = initID
183            self.metadata = metadata
184        }
185    }
186
187    pub resource interface RCRDSHPNFTCollectionPublic {
188        pub fun deposit(token: @NonFungibleToken.NFT)
189        pub fun getIDs(): [UInt64]
190        pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
191        pub fun borrowRCRDSHPNFT(id: UInt64): &RCRDSHPNFT.NFT? {
192            post {
193                (result == nil) || (result?.id == id):
194                    "Cannot borrow RCRDSHPNFT reference: the ID of the returned reference is incorrect"
195            }
196        }
197    }
198
199    pub resource Collection: RCRDSHPNFTCollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic, MetadataViews.ResolverCollection {
200        pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}
201
202        init () {
203            self.ownedNFTs <- {}
204        }
205
206        pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
207            let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("withdraw - missing NFT")
208
209            emit Withdraw(id: token.id, from: self.owner?.address)
210            return <-token
211        }
212
213        pub fun deposit(token: @NonFungibleToken.NFT) {
214            let token <- token as! @RCRDSHPNFT.NFT
215            let id: UInt64 = token.id
216            let oldToken <- self.ownedNFTs[id] <- token
217
218            emit Deposit(id: id, to: self.owner?.address)
219            destroy oldToken
220        }
221
222        pub fun sale(id: UInt64, price: UInt64): @NonFungibleToken.NFT {
223            emit Sale(id: id, price: price)
224            return <-self.withdraw(withdrawID: id)
225        }
226
227        pub fun burn(burnID: UInt64){
228            let token <- self.ownedNFTs.remove(key: burnID) ?? panic("burn - missing NFT")
229
230            emit Burn(id: token.id, from: self.owner?.address)
231            destroy token
232        }
233
234        pub fun getIDs(): [UInt64] {
235            return self.ownedNFTs.keys
236        }
237
238        pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
239            return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)!
240        }
241
242        pub fun borrowRCRDSHPNFT(id: UInt64): &RCRDSHPNFT.NFT? {
243            if self.ownedNFTs[id] != nil {
244                let ref = &self.ownedNFTs[id] as auth &NonFungibleToken.NFT?
245                return ref as! &RCRDSHPNFT.NFT?
246            }
247
248            return nil
249        }
250
251        pub fun borrowViewResolver(id: UInt64): &AnyResource{MetadataViews.Resolver} {
252            let nft = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
253            let rcrdshpNFT = nft as! &RCRDSHPNFT.NFT
254            return rcrdshpNFT as &AnyResource{MetadataViews.Resolver}
255        }
256
257        destroy() {
258            destroy self.ownedNFTs
259        }
260    }
261
262    pub fun createEmptyCollection(): @NonFungibleToken.Collection {
263        return <- create Collection()
264    }
265
266    pub resource NFTMinter {
267        pub fun mintNFT(recipient: &{NonFungibleToken.CollectionPublic}, meta: {String : String}) {
268            var newNFT <- create NFT(initID: RCRDSHPNFT.totalSupply, metadata: meta)
269            recipient.deposit(token: <-newNFT)
270            RCRDSHPNFT.totalSupply = RCRDSHPNFT.totalSupply + UInt64(1)
271        }
272    }
273
274    init() {
275        self.totalSupply = 0
276
277        self.minterStoragePath = /storage/RCRDSHPNFTMinter
278        self.collectionStoragePath = /storage/RCRDSHPNFTCollection
279        self.collectionPublicPath  = /public/RCRDSHPNFTCollection
280
281        let collection <- create Collection()
282        self.account.save(<-collection, to: self.collectionStoragePath)
283
284        self.account.link<&RCRDSHPNFT.Collection{NonFungibleToken.CollectionPublic, RCRDSHPNFT.RCRDSHPNFTCollectionPublic}>(
285            self.collectionPublicPath,
286            target: self.collectionStoragePath
287        )
288
289        let minter <- create NFTMinter()
290        self.account.save(<-minter, to: self.minterStoragePath)
291
292        emit ContractInitialized()
293    }
294}
295