Smart Contract

BBxBarbieCard

A.e5bf4d436ca23932.BBxBarbieCard

Deployed

1w ago
Feb 15, 2026, 02:21:54 PM UTC

Dependents

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