Smart Contract

Monsoon

A.8234007b36f8113c.Monsoon

Deployed

1d ago
Feb 26, 2026, 10:39:03 PM UTC

Dependents

0 imports
1/**
2* SPDX-License-Identifier: UNLICENSED
3*/
4
5import NonFungibleToken from 0x1d7e57aa55817448
6
7// Monsoon
8// NFT items for cards!
9//
10pub contract Monsoon: NonFungibleToken {
11
12    // Events
13    //
14    pub event ContractInitialized()
15    pub event Withdraw(id: UInt64, from: Address?)
16    pub event Destroy(id: UInt64, from: Address?)
17    pub event Deposit(id: UInt64, to: Address?)
18    pub event Minted(id: UInt64, templateID: UInt64, typeOfCard: UInt32, universeID: UInt32, numSeries: UInt32, numSerial: UInt32, CID: String)
19    pub event monsoonCutPercentageChange(newPercent: UFix64)
20    pub event monsoonCutPercentageReceiverChange(newReceiver: Address)
21
22
23
24    // Named Paths
25    //
26    pub let CollectionStoragePath: StoragePath
27    pub let CollectionPublicPath: PublicPath
28    pub let MinterStoragePath: StoragePath
29
30    // totalSupply
31    // The total number of Monsoon that have been minted
32    //
33    pub var totalSupply: UInt64
34    
35    // totalSupplyUniverseType
36    // Dictionary with the total number minted desglosed by Universe_Type
37    //
38    access(contract) var totalSupplyUniverseType: {String: UInt64}
39
40    // totalBurned
41    // Total Number of cards burned in order to get fusion cards
42    //
43    pub var totalBurned: UInt64
44
45    // monsoonCutSalesPercentage
46    // Commission in the market of the sales 
47    //
48    pub var monsoonCutPercentage: UFix64
49    pub var addressReceivermonsoonCutPercentage: Address
50
51    // function to inform about all totals
52    pub fun getTotals(): {String: UInt64} {
53        var totals: {String: UInt64} = {}
54        var old = totals.insert(key: "totalSupply", self.totalSupply)
55        old = totals.insert(key: "totalBurned", self.totalBurned)
56        
57        for key in self.totalSupplyUniverseType.keys {
58            
59            old = totals.insert(key: key, self.totalSupplyUniverseType[key] ?? (0 as UInt64))
60        }
61        return totals
62    }
63
64    pub struct CardData {
65        // This is the key of the templateCard
66        pub let templateID: UInt64
67        // 0 Comun 1 Rare 2 Combination 3 Legendarie
68        pub let typeOfCard: UInt32 
69        // universe of the card (0 Zombicide 1 .....)
70        pub let universeID: UInt32
71        // printing number (as an book editon)
72        pub let numSeries: UInt32
73        // Number of the serie in the card
74        pub let numSerial: UInt32
75        //File static card in ipfs
76        pub let CID: String
77
78
79        init(templateID: UInt64, typeOfCard: UInt32, universeID: UInt32, numSeries: UInt32, numSerial: UInt32, CID: String) {
80            self.templateID = templateID
81            self.typeOfCard = typeOfCard
82            self.universeID = universeID
83            self.numSeries = numSeries
84            self.numSerial = numSerial
85            self.CID = CID
86        }
87    }
88
89    // NFT
90    // A Monsoon Card as an NFT
91    //
92    pub resource NFT: NonFungibleToken.INFT {
93        // The token's ID
94        pub let id: UInt64
95
96        pub let data: CardData
97
98        
99        // initializer
100        //
101        init(initID: UInt64, initTemplateID: UInt64, initTypeOfCard: UInt32, initUniverseID: UInt32, initnumSeries: UInt32, initnumSerial: UInt32, initCID: String) {
102            self.id = initID
103
104            self.data = CardData(templateID: initTemplateID, typeOfCard: initTypeOfCard, universeID: initUniverseID, numSeries: initnumSeries, numSerial: initnumSerial, CID: initCID)
105            emit Minted(id: self.id, templateID: self.data.templateID, typeOfCard: self.data.typeOfCard, universeID: self.data.universeID, numSeries: self.data.numSeries, numSerial: self.data.numSerial, CID: self.data.CID)
106            
107        }
108    }
109
110    // This is the interface that users can cast their Monsoon Collection as
111    // to allow others to deposit Monsoon into their Collection. It also allows for reading
112    // the details of Monsoon in the Collection.
113    pub resource interface MonsoonCollectionPublic {
114        pub fun deposit(token: @NonFungibleToken.NFT)
115        pub fun getIDs(): [UInt64]
116
117        //list of the propertied of the cards collections
118        pub fun listCards(): {UInt64: CardData}
119
120        pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
121        pub fun borrowMonsoonCard(id: UInt64): &Monsoon.NFT? {
122            // If the result isn't nil, the id of the returned reference
123            // should be the same as the argument to the function
124            post {
125                (result == nil) || (result?.id == id):
126                    "Cannot borrow MonsoonCard reference: The ID of the returned reference is incorrect"
127            }
128        }
129    }
130
131    // Collection
132    // A collection of MonsoonCard NFTs owned by an account
133    //
134    pub resource Collection: MonsoonCollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic {
135        // dictionary of NFT conforming tokens
136        // NFT is a resource type with an `UInt64` ID field
137        //
138        pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}
139
140        // withdraw
141        // Removes an NFT from the collection and moves it to the caller
142        //
143        pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
144            let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
145
146            emit Withdraw(id: token.id, from: self.owner?.address)
147
148            return <-token
149        }
150
151        // deposit
152        // Takes a NFT and adds it to the collections dictionary
153        // and adds the ID to the id array
154        //
155        pub fun deposit(token: @NonFungibleToken.NFT) {
156            let token <- token as! @Monsoon.NFT
157
158            let id: UInt64 = token.id
159
160            // add the new token to the dictionary which removes the old one
161            let oldToken <- self.ownedNFTs[id] <- token
162
163            emit Deposit(id: id, to: self.owner?.address)
164
165            destroy oldToken
166        }
167
168        // getIDs
169        // Returns an array of the IDs that are in the collection
170        //
171        pub fun getIDs(): [UInt64] {
172            return self.ownedNFTs.keys
173        }
174
175        // listCards
176        // functions for list the properties of the user's cards
177        //
178        pub fun listCards(): {UInt64: CardData} {
179            var cardsList: {UInt64:CardData} = {}
180            for key in self.ownedNFTs.keys {
181                //let el = &self.ownedNFTs[key] as &Monsoon.NFT
182                let ref = &self.ownedNFTs[key] as auth &NonFungibleToken.NFT? //update secure cadence
183                let el = ref as! &Monsoon.NFT
184                cardsList.insert(key: el.id, el.data)
185            }
186            return cardsList
187        }
188
189        // borrowNFT
190        // Gets a reference to an NFT in the collection
191        // so that the caller can read its metadata and call its methods
192        //
193        pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
194            return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)! //update secure cadence
195        }
196
197        // borrowMonsoonCard
198        // Gets a reference to an NFT in the collection as a MonsoonCard,
199        // exposing all of its fields.
200        // This is safe as there are no functions that can be called on the MonsoonCard.
201        //
202        pub fun borrowMonsoonCard(id: UInt64): &Monsoon.NFT? {
203            if self.ownedNFTs[id] != nil {
204                let ref = &self.ownedNFTs[id] as auth &NonFungibleToken.NFT? // update secure cadence
205                return ref as! &Monsoon.NFT
206            } else {
207                return nil
208            }
209        }
210
211        // function for burned the cards in order of allow mint a fusion card
212        pub fun batchDestroy(keys: [UInt64]): Int {            
213            var nBurned: Int = 0
214            
215            // in a first moment check if all the keys exits in the collection before starting to destroy
216            for key in keys {
217                if self.ownedNFTs[key] == nil {
218                    panic("The reference ".concat(key.toString()).concat(" doesn't exits in the account collection")) 
219                }
220            }
221
222            for key in keys {
223                let token <- self.ownedNFTs.remove(key: key) ?? panic("missing NFT")
224                emit Destroy(id: token.id, from: self.owner?.address)
225                destroy token                 
226                Monsoon.totalBurned = Monsoon.totalBurned + (1 as UInt64)
227                nBurned = nBurned +1
228            }
229
230            return nBurned
231        }
232
233
234        // destructor
235        destroy() {
236            destroy self.ownedNFTs
237        }
238
239        // initializer
240        //
241        init () {
242            self.ownedNFTs <- {}
243        }
244    }
245
246    // createEmptyCollection
247    // public function that anyone can call to create a new empty collection
248    //
249    pub fun createEmptyCollection(): @NonFungibleToken.Collection {
250        return <- create Collection()
251    }
252
253    // NFTMinter
254    // Resource that an admin or something similar would own to be
255    // able to mint new NFTs
256    //
257	pub resource NFTMinter {
258
259		// mintNFT
260        // Mints a new NFT with a new ID
261		// and deposit it in the recipients collection using their collection reference
262        //
263		pub fun mintNFT(recipient: &{NonFungibleToken.CollectionPublic}, templateID: UInt64, typeOfCard: UInt32, universeID: UInt32, numSeries: UInt32, numSerial: UInt32, CID: String) {
264            emit Minted(id: Monsoon.totalSupply, templateID: templateID, typeOfCard: typeOfCard, universeID: universeID, numSeries: numSeries, numSerial: numSerial, CID: CID)
265
266			// deposit it in the recipient's account using their reference
267			recipient.deposit(token: <-create Monsoon.NFT(initID: Monsoon.totalSupply, initTemplateID: templateID, initTypeOfCard: typeOfCard, initUniverseID: universeID, initnumSeries: numSeries, initnumSerial: numSerial, initCID: CID))
268
269            Monsoon.totalSupply = Monsoon.totalSupply + (1 as UInt64)
270            
271
272            // store the total supply by universe and type of cards
273            let keyUnvTyp: String = universeID.toString().concat("_").concat(typeOfCard.toString()) 
274            if (!Monsoon.totalSupplyUniverseType.containsKey(keyUnvTyp)) {
275                Monsoon.totalSupplyUniverseType.insert(key: keyUnvTyp, 1)            
276            } else {  
277                var auxCont = Monsoon.totalSupplyUniverseType[keyUnvTyp] ?? (0 as UInt64)   
278                auxCont = auxCont + (1 as UInt64) 
279                Monsoon.totalSupplyUniverseType.insert(key: keyUnvTyp, auxCont)            
280            }
281            //-------------------------------------------------------
282
283		}
284
285        pub fun changeMonsoonCutPercentage (newCutPercentage: UFix64) {
286            Monsoon.monsoonCutPercentage = newCutPercentage
287            emit monsoonCutPercentageChange(newPercent: Monsoon.monsoonCutPercentage)            
288        }
289
290        pub fun changeaddressReceivermonsoonCutPercentage (newReceiver: Address) {
291            Monsoon.addressReceivermonsoonCutPercentage = newReceiver
292            emit monsoonCutPercentageReceiverChange(newReceiver: Monsoon.addressReceivermonsoonCutPercentage)            
293        }
294
295
296	}
297
298    // fetch
299    // Get a reference to a MonsoonCard from an account's Collection, if available.
300    // If an account does not have a Monsoon.Collection, panic.
301    // If it has a collection but does not contain the itemID, return nil.
302    // If it has a collection and that collection contains the itemID, return a reference to that.
303    //
304    pub fun fetch(_ from: Address, itemID: UInt64): &Monsoon.NFT? {
305        let collection = getAccount(from)
306            .getCapability(Monsoon.CollectionPublicPath)!
307            .borrow<&Monsoon.Collection{Monsoon.MonsoonCollectionPublic}>()
308            ?? panic("Couldn't get collection")
309        // We trust Monsoon.Collection.borowMonsoonCard to get the correct itemID
310        // (it checks it before returning it).
311        return collection.borrowMonsoonCard(id: itemID)
312    }
313
314    // initializer
315    //
316	init() {
317        // Set our named paths
318        self.CollectionStoragePath = /storage/monsoonDigitalCollection
319        self.CollectionPublicPath = /public/monsoonDigitalCollection
320        self.MinterStoragePath = /storage/monsoonDigitalMinter
321
322        // Initialize the total supply
323        self.totalSupply = 0
324        self.totalSupplyUniverseType = {}
325        self.totalBurned = 0
326
327        self.monsoonCutPercentage = 0.05
328        self.addressReceivermonsoonCutPercentage = self.account.address
329        
330
331
332
333        // Create a Minter resource and save it to storage
334        let minter <- create NFTMinter()
335        self.account.save(<-minter, to: self.MinterStoragePath)
336
337        emit ContractInitialized()
338	}
339}
340