Smart Contract

BBxBarbiePack

A.e5bf4d436ca23932.BBxBarbiePack

Deployed

1w ago
Feb 16, 2026, 06:10:33 PM UTC

Dependents

14 imports
1/*
2*
3*   This is an implemetation of a Flow Non-Fungible Token
4*   It is not a part of the official standard but it is assumed to be
5*   similar to how NFTs would implement the core functionality
6*
7*
8*/
9
10import NonFungibleToken from 0x1d7e57aa55817448
11import FungibleToken from 0xf233dcee88fe0abe
12import MetadataViews from 0x1d7e57aa55817448
13import ViewResolver from 0x1d7e57aa55817448
14
15access(all) contract BBxBarbiePack: NonFungibleToken {
16
17    /* 
18    *   NonFungibleToken Standard Events
19    */
20    access(all) event ContractInitialized()
21    access(all) event Withdraw(id: UInt64, from: Address?)
22    access(all) event Deposit(id: UInt64, to: Address?)
23
24    /* 
25    *   Project Events
26    */
27    access(all) event Mint(id: UInt64)
28    access(all) event Burn(id: UInt64)
29    access(all) event DepositEvent(
30        uuid: UInt64
31        , id: UInt64
32        , seriesId: UInt64
33        , editionId: UInt64
34        , to: Address?
35    )
36
37        access(all) event TransferEvent(
38        uuid: UInt64
39        , id: UInt64
40        , seriesId: UInt64
41        , editionId: UInt64
42        , to: Address?
43        )
44
45    /* 
46    *   Named Paths
47    */
48    access(all) let CollectionStoragePath: StoragePath
49    access(all) let CollectionPublicPath: PublicPath
50
51    /* 
52    *   NonFungibleToken Standard Fields
53    */
54    access(all) var totalSupply: UInt64
55
56    /*
57    *   Pack State Variables
58    */
59    access(account) var name: String
60    access(account) var currentPackEditionIdByPackSeriesId: {UInt64: UInt64}
61
62
63    access(all) resource NFT: NonFungibleToken.NFT {
64        access(all) let id: UInt64
65        access(all) let packSeriesID: UInt64
66        access(all) let packEditionID: UInt64
67        access(all) let packHash: String
68        access(all) let metadata: {String: String}
69
70        access(all) view fun getViews(): [Type] {
71            return [
72                Type<MetadataViews.Display>(),
73                Type<MetadataViews.ExternalURL>(),
74                Type<MetadataViews.NFTCollectionData>(),
75                Type<MetadataViews.NFTCollectionDisplay>(),
76                Type<MetadataViews.Royalties>(),
77                Type<MetadataViews.Traits>()
78            ]
79        }
80
81
82        access(all) fun resolveView(_ view: Type): AnyStruct? {
83            switch view {
84                case Type<MetadataViews.Display>():
85                    var ipfsImage = MetadataViews.IPFSFile(
86                        cid: self.metadata["thumbnailCID"] ?? "No ThumnailCID set"
87                        , path: self.metadata["thumbnailPath"] ?? "No ThumbnailPath set"
88                        )
89                    return MetadataViews.Display(
90                        name: self.metadata["packName"]?.concat(" #")?.concat(self.packEditionID.toString()) ?? "Boss Beauties x Barbie Pack",
91                        description: self.metadata["description"] ?? "Digital Pack Collectable from the Boss Beauties x Barbie collaboration" ,
92                        thumbnail: ipfsImage
93                    )
94
95                case Type<MetadataViews.ExternalURL>():
96                    return MetadataViews.ExternalURL(
97                        self.metadata["url"] ?? ""
98                        )
99
100                case Type<MetadataViews.NFTCollectionData>():
101                    return BBxBarbiePack.resolveContractView(resourceType: Type<@BBxBarbiePack.NFT>(), viewType: Type<MetadataViews.NFTCollectionData>())
102                case Type<MetadataViews.NFTCollectionDisplay>():
103                    return BBxBarbiePack.resolveContractView(resourceType: Type<@BBxBarbiePack.NFT>(), viewType: Type<MetadataViews.NFTCollectionDisplay>())
104                case Type<MetadataViews.Traits>(): 
105                    let excludedTraits = [
106                                "thumbnailPath"
107                                , "thumbnailCID"
108                                , "collectionName"
109                                , "collectionDescription"
110                                , "description"
111                                , "url"
112                            ]
113                    let traitsView = MetadataViews.dictToTraits(
114                        dict: self.metadata
115                        , excludedNames: excludedTraits
116                        )
117                    return traitsView
118                case Type<MetadataViews.Royalties>(): 
119                    return BBxBarbiePack.resolveContractView(resourceType: Type<@BBxBarbiePack.NFT>(), viewType: Type<MetadataViews.Royalties>())
120            }
121
122            return nil
123        }
124
125
126        init(
127            id: UInt64
128            , packSeriesID: UInt64
129            , packEditionID: UInt64
130            , packHash: String
131            , metadata: {String: String}
132            ) {
133            self.id = id
134            self.packSeriesID = packSeriesID
135            self.packEditionID = packEditionID
136            self.packHash = packHash
137            self.metadata = metadata
138            emit Mint(id: self.packEditionID)
139        }
140
141
142        access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
143            return <-BBxBarbiePack.createEmptyCollection(nftType: Type<@BBxBarbiePack.NFT>())
144        }
145    }
146
147    access(all) resource interface PackCollectionPublic {}
148
149    access(all) resource Collection: PackCollectionPublic, NonFungibleToken.Collection {
150        access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
151
152        init() {
153            self.ownedNFTs <- {}
154        }
155
156
157        /// getSupportedNFTTypes returns a list of NFT types that this receiver accepts
158        access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
159            let supportedTypes: {Type: Bool} = {}
160            supportedTypes[Type<@BBxBarbiePack.NFT>()] = true
161            return supportedTypes
162        }
163
164        /// Returns whether or not the given type is accepted by the collection
165        /// A collection that can accept any type should just return true by default
166        access(all) view fun isSupportedNFTType(type: Type): Bool {
167            return type == Type<@BBxBarbiePack.NFT>()
168        }
169
170        access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
171            let BBxBarbiePack <- self.ownedNFTs.remove(
172                key: withdrawID
173                ) ?? panic("missing NFT")
174            emit Withdraw(
175                id: BBxBarbiePack.id,
176                from: self.owner?.address
177                )
178            return <-BBxBarbiePack
179        }
180
181        access(all) fun deposit(
182            token: @{NonFungibleToken.NFT}
183            ) {
184            let BBxBarbiePack <- token as! @BBxBarbiePack.NFT
185            let BBxBarbiePackUUID: UInt64 = BBxBarbiePack.uuid
186            let BBxBarbiePackSeriesId: UInt64 = BBxBarbiePack.packSeriesID
187            let BBxBarbiePackID: UInt64 = BBxBarbiePack.id
188            let BBxBarbiePackEditionID: UInt64 = BBxBarbiePack.packEditionID
189            self.ownedNFTs[BBxBarbiePackID] <-! BBxBarbiePack
190            emit Deposit(
191                id: BBxBarbiePackID,
192                to: self.owner?.address
193            )
194            emit DepositEvent(
195                uuid:BBxBarbiePackUUID
196                , id: BBxBarbiePackID
197                , seriesId: BBxBarbiePackSeriesId
198                , editionId: BBxBarbiePackEditionID
199                , to: self.owner?.address
200            )
201        }
202
203        access(all) view fun getIDs(): [UInt64] {
204            return self.ownedNFTs.keys
205        }
206
207
208        access(all) view fun getLength(): Int {
209            return self.ownedNFTs.keys.length
210        }
211
212
213        access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}?{
214            return (&self.ownedNFTs[id])
215        }
216
217        access(all) fun borrowPack(id: UInt64): &NFT? {
218            if let tokenRef: &{NonFungibleToken.NFT} = &self.ownedNFTs[id] {
219                return tokenRef as! &NFT
220            } else {
221                return nil
222            }
223        }
224
225        access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
226            if let nftRef: &{NonFungibleToken.NFT} = &self.ownedNFTs[id] {
227                return nftRef as &{ViewResolver.Resolver}
228            }
229        return nil
230        }
231
232
233        /// Allows a given function to iterate through the list
234        /// of owned NFT IDs in a collection without first
235        /// having to load the entire list into memory
236        access(all) fun forEachID(_ f: fun(UInt64): Bool) {
237            self.ownedNFTs.forEachKey(f)
238        }
239
240
241        access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
242            return <- BBxBarbiePack.createEmptyCollection(nftType: Type<@BBxBarbiePack.NFT>())
243        }
244    }
245
246    /* 
247    *   Public Functions
248    */
249
250    access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
251        return <- create Collection()
252    }
253
254    access(all) fun getTotalSupply(): UInt64 {
255        return self.totalSupply
256    }
257
258
259    access(all) fun getName(): String {
260        return self.name
261    }
262
263    access(all) fun transfer(uuid: UInt64, id: UInt64, packSeriesId: UInt64, packEditionId: UInt64, toAddress: Address){
264
265        let BBxBarbiePackV2UUID: UInt64 = uuid
266        let BBxBarbiePackV2SeriesId: UInt64 = packSeriesId
267        let BBxBarbiePackV2ID: UInt64 = id
268        let BBxBarbiePackV2packEditionID: UInt64 = packEditionId
269
270        emit TransferEvent(
271            uuid: BBxBarbiePackV2UUID
272            , id: BBxBarbiePackV2ID
273            , seriesId: BBxBarbiePackV2SeriesId
274            , editionId: BBxBarbiePackV2packEditionID
275            , to: toAddress)
276    }
277
278access(all) view fun getContractViews(resourceType: Type?): [Type] {
279    return [
280                Type<MetadataViews.NFTCollectionData>(),
281                Type<MetadataViews.NFTCollectionDisplay>(),
282                Type<MetadataViews.Royalties>()
283            ]
284}
285
286access(all) view fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct?{
287    switch viewType {
288                case Type<MetadataViews.NFTCollectionData>():
289                    return MetadataViews.NFTCollectionData(
290                        storagePath: BBxBarbiePack.CollectionStoragePath,
291                        publicPath: BBxBarbiePack.CollectionPublicPath,
292                        publicCollection: Type<&BBxBarbiePack.Collection>(),
293                        publicLinkedType: Type<&BBxBarbiePack.Collection>(),
294                        createEmptyCollectionFunction: fun(): @{NonFungibleToken.Collection} {return <- BBxBarbiePack.createEmptyCollection(nftType: Type<@BBxBarbiePack.NFT>())
295                        })
296                
297                case Type<MetadataViews.NFTCollectionDisplay>():
298                    let externalURL = MetadataViews.ExternalURL(
299                        "https://www.mattel.com/"
300                        )
301                    let squareImage = MetadataViews.Media(
302                        file: MetadataViews.HTTPFile(
303                            url: "https://www.mattel.com/"
304                            ),
305                        mediaType: "image/png")
306                    let bannerImage = MetadataViews.Media(
307                        file: MetadataViews.HTTPFile(
308                            url: "https://www.mattel.com/"
309                            ),
310                        mediaType: "image/png")
311                    let socialMap: {String: MetadataViews.ExternalURL} = {
312                        "facebook": MetadataViews.ExternalURL(
313                            "https://www.facebook.com/mattel"
314                            ),
315                        "instagram": MetadataViews.ExternalURL(
316                            "https://www.instagram.com/mattel"
317                            ),
318                        "twitter": MetadataViews.ExternalURL(
319                            "https://www.twitter.com/mattel"
320                            )
321                    }
322                    return MetadataViews.NFTCollectionDisplay(
323                        name: "Boss Beauties x Barbie Pack",
324                        description: "Digital Collectable from the Boss Beauties x Barbie collaboration",
325                        externalURL: externalURL,
326                        squareImage: squareImage,
327                        bannerImage: bannerImage,
328                        socials: socialMap
329                        )
330                case Type<MetadataViews.Royalties>(): 
331                    let flowReciever = getAccount(0xf86e2f015cd692be).capabilities.get<&{FungibleToken.Receiver}>(/public/flowTokenReceiver)
332                    return MetadataViews.Royalties([
333                    MetadataViews.Royalty(
334                        receiver:flowReciever
335                        , cut: 0.05
336                        , description: "Mattel 5% Royalty")
337                    ]
338                )
339                
340    }
341    return nil
342}
343
344    /* 
345    *   Admin Functions
346    */
347    access(account) fun addNewSeries(newPackSeriesID: UInt64){
348        self.currentPackEditionIdByPackSeriesId.insert(key: newPackSeriesID, 0)
349    }
350
351
352    access(account) fun updateCurrentEditionIdByPackSeriesId(packSeriesID: UInt64, packSeriesEdition: UInt64){
353        self.currentPackEditionIdByPackSeriesId[packSeriesID] = packSeriesEdition
354    }
355    
356
357    access(account) fun mint(
358        nftID: UInt64
359        , packEditionID: UInt64
360        , packSeriesID: UInt64
361        , packHash: String
362        , metadata: {String: String}
363        ): @{NonFungibleToken.NFT} {
364        self.totalSupply = self.totalSupply + 1
365        self.currentPackEditionIdByPackSeriesId[packSeriesID] = self.currentPackEditionIdByPackSeriesId[packSeriesID]! + 1
366        return <- create NFT(
367            id: nftID
368            , packSeriesID: packSeriesID
369            , packEditionID: self.currentPackEditionIdByPackSeriesId[packSeriesID]!
370            , packHash: packHash
371            , metadata: metadata
372            )
373    }
374    
375
376
377    // initialize contract state variables
378    init(){
379        self.name = "Boss Beauties x Barbie Pack"
380        self.totalSupply = 0
381        self.currentPackEditionIdByPackSeriesId = {1 : 0}
382
383        // set the named paths
384        self.CollectionStoragePath = /storage/BBxBarbiePackCollection
385        self.CollectionPublicPath = /public/BBxBarbiePackCollection
386
387        // create a collection resource and save it to storage
388        let collection: @BBxBarbiePack.Collection <- create Collection()
389        self.account.storage.save(<-collection, to: self.CollectionStoragePath)
390
391        let collectionCap = self.account.capabilities.storage.issue<&BBxBarbiePack.Collection>(self.CollectionStoragePath)
392        self.account.capabilities.publish(collectionCap, at: self.CollectionPublicPath)
393
394        emit ContractInitialized()
395    }
396
397}
398