Smart Contract

BBxBarbieToken

A.e5bf4d436ca23932.BBxBarbieToken

Deployed

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