Smart Contract

NTest_Trm_Asset_NFT

A.2a20bcae76f735aa.NTest_Trm_Asset_NFT

Valid From

132,377,914

Deployed

1w ago
Feb 21, 2026, 05:14:51 PM UTC

Dependents

3 imports
1import NonFungibleToken from 0x1d7e57aa55817448
2import ViewResolver from 0x1d7e57aa55817448
3import MetadataViews from 0x1d7e57aa55817448
4
5
6access(all) contract NTest_Trm_Asset_NFT: NonFungibleToken {
7    
8    access(all) var totalSupply: UInt64
9    /// Standard Paths
10
11    access(all) let CollectionStoragePath: StoragePath
12    access(all) let CollectionPublicPath: PublicPath
13
14    /// Path where the minter should be stored
15    /// The standard paths for the collection are stored in the collection resource type
16    access(all) let MinterStoragePath: StoragePath
17    access(all) let adminStoragePath: StoragePath
18
19    access(all) event AssetMinted(id:  UInt64, title: String, description: String, thumbnail: String, metadata: {String: String}, serialNumber: UInt32, url: String, ownerInfo: String, assetType: String, kID: String, songID: String, masterTokenID: UInt64?, webhookID: String?)
20    access(all) event AssetOwnerTransfer(id: UInt64, ownerFrom: String, ownerTo: String, songID: String, price: UFix64?, priceUnit: String?, paymentRefInfo: String?, webhookID: String?)
21    access(all) event AssetBatchMinted(startID: UInt64, endID: UInt64, totalCount: UInt32, startSerialNumber: UInt32, endSerialNumber: UInt32, title: String, description: String, thumbnail: String, metadata: {String: String}, url: String, ownerInfo: String, assetType: String, kID: String, songID: String, masterTokenID: UInt64, webhookID: String?)
22    access(all) event AssetUpdated(id: UInt64 , title: String?, description: String?, thumbnail: String?, assetType: String?, ownerInfo: String, metadata: {String: String}?, webhookID: String? )
23    access(all) event AssetBatchUpdated(ids: [UInt64] , title: String?, description: String?, thumbnail: String?, assetType: String?, ownerInfo: String, metadata: {String: String}?, webhookID: String? )
24
25
26
27    access(all) resource NFT: NonFungibleToken.NFT {
28        access(all) let id: UInt64
29        access(all) let masterTokenID: UInt64
30        
31        access(all) var title: String
32        access(all) var description: String
33        access(all) var thumbnail: String
34
35        access(all) let url: String
36        access(all) var ownerInfo: String
37        access(all) let serialNumber: UInt32
38        access(all) var assetType: String
39        access(all) let kID: String
40        access(all) var songID: String
41
42        access(all) var metadata: {String: AnyStruct}
43
44        init(
45            id: UInt64,
46            title: String,
47            description: String,
48            thumbnail: String,
49            metadata: {String: AnyStruct},
50            serialNumber: UInt32,
51            url: String,
52            ownerInfo: String,
53            assetType: String,
54            kID: String,
55            songID: String,
56            masterTokenID: UInt64
57
58        ) {
59            self.id = id
60            self.title = title
61            self.description = description
62            self.thumbnail = thumbnail
63            self.serialNumber = serialNumber
64            self.url = url
65            self.ownerInfo = ownerInfo
66            self.assetType = assetType
67            self.kID = kID
68            self.songID = songID
69            self.masterTokenID = masterTokenID
70
71
72            self.metadata = metadata
73        }
74
75        access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
76            return <-NTest_Trm_Asset_NFT.createEmptyCollection(nftType: Type<@NTest_Trm_Asset_NFT.NFT>())
77        }
78
79        access(all) view fun getViews(): [Type] {
80            return [
81                Type<MetadataViews.Display>(),
82                Type<MetadataViews.ExternalURL>(),
83                Type<MetadataViews.Editions>(),
84                Type<MetadataViews.NFTCollectionData>(),
85                Type<MetadataViews.NFTCollectionDisplay>(),
86                Type<MetadataViews.Serial>()
87            ]
88        }
89
90        access(all) fun resolveView(_ view: Type): AnyStruct? {
91            switch view {
92                case Type<MetadataViews.Display>():
93                    return MetadataViews.Display(
94                        name: self.title,
95                        description: self.description,
96                        thumbnail: MetadataViews.HTTPFile(
97                            url: self.thumbnail
98                        )
99                    )
100                case Type<MetadataViews.Editions>():
101                    // There is no max number of NFTs that can be minted from this contract
102                    // so the max edition field value is set to nil
103                    let editionInfo = MetadataViews.Edition(name: "Intertrust NFT Creation", number: self.id, max: nil)
104                    let editionList: [MetadataViews.Edition] = [editionInfo]
105                    return MetadataViews.Editions(
106                        editionList
107                    )
108                case Type<MetadataViews.Serial>():
109                    return MetadataViews.Serial(
110                        self.id
111                    )
112                case Type<MetadataViews.ExternalURL>():
113                    return MetadataViews.ExternalURL("https://www.intertrust.com/marketmaker/")
114                case Type<MetadataViews.NFTCollectionData>():
115                    return NTest_Trm_Asset_NFT.resolveContractView(resourceType: Type<@NTest_Trm_Asset_NFT.NFT>(), viewType: Type<MetadataViews.NFTCollectionData>())
116                case Type<MetadataViews.NFTCollectionDisplay>():
117                    return NTest_Trm_Asset_NFT.resolveContractView(resourceType: Type<@NTest_Trm_Asset_NFT.NFT>(), viewType: Type<MetadataViews.NFTCollectionDisplay>())
118            }
119            return nil
120
121        }
122    
123        access(contract) fun transferOwner(id: UInt64, ownerFrom: String, ownerTo: String, songID: String, price: UFix64?, priceUnit: String?, paymentRefInfo: String?, webhookID: String?) {
124            if (ownerFrom == self.ownerInfo) {
125                self.ownerInfo = ownerTo
126
127                emit AssetOwnerTransfer(id: id, ownerFrom: ownerFrom, ownerTo: ownerTo, songID: songID, price: price, priceUnit: priceUnit, paymentRefInfo: paymentRefInfo, webhookID: webhookID)
128
129            }
130          
131        }
132
133        access(contract) fun updateMetadata(id: UInt64 , title: String?, description: String?, thumbnail: String?, assetType: String?, ownerInfo: String, metadata: {String: String}?, webhookID: String? ){
134            if (ownerInfo == self.ownerInfo) {
135                if let tempname = title {self.title = tempname}
136                
137                if let tempdesc = description {self.description = tempdesc}
138
139                if let tempthumbnail = thumbnail {self.thumbnail = tempthumbnail}
140
141                if let tempassetType = assetType {self.assetType = tempassetType}
142
143                if let tempmetadata = metadata {self.metadata = tempmetadata}
144            }
145           
146        }
147        
148
149
150    }
151
152    access(all) resource Collection: NonFungibleToken.Collection {
153        /// dictionary of NFT conforming tokens
154        /// NFT is a resource type with an `UInt64` ID field
155        access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
156
157        init () {
158            self.ownedNFTs <- {}
159        }
160
161        access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
162            let supportedTypes: {Type: Bool} = {}
163            supportedTypes[Type<@NTest_Trm_Asset_NFT.NFT>()] = true
164            return supportedTypes
165        }
166
167        /// Returns whether or not the given type is accepted by the collection
168        /// A collection that can accept any type should just return true by default
169        access(all) view fun isSupportedNFTType(type: Type): Bool {
170            return type == Type<@NTest_Trm_Asset_NFT.NFT>()
171        }
172
173        access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
174            let token <- self.ownedNFTs.remove(key: withdrawID)
175                ?? panic("Could not withdraw an NFT with the provided ID from the collection")
176
177            return <-token
178        }
179
180        /// deposit takes a NFT and adds it to the collections dictionary
181        /// and adds the ID to the id array
182        access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
183            pre {
184                false: "Depositing Asset directly to Asset contract is not allowed"
185            }
186            let token <- token as! @NTest_Trm_Asset_NFT.NFT
187            let id = token.id
188
189            // add the new token to the dictionary which removes the old one
190            let oldToken <- self.ownedNFTs[token.id] <- token
191
192            destroy oldToken
193        }
194
195        access(all) view fun getIDs(): [UInt64] {
196            return self.ownedNFTs.keys
197        }
198
199        /// Gets the amount of NFTs stored in the collection
200        access(all) view fun getLength(): Int {
201            return self.ownedNFTs.length
202        }
203
204        access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
205            return (&self.ownedNFTs[id])
206        }
207
208        /// Borrow the view resolver for the specified NFT ID
209        access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
210            if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
211                return nft as &{ViewResolver.Resolver}
212            }
213            return nil
214        }
215
216        access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
217            return <-NTest_Trm_Asset_NFT.createEmptyCollection(nftType: Type<@NTest_Trm_Asset_NFT.NFT>())
218        }
219
220        access(all) view fun getSerialNumber(id: UInt64): UInt32 {
221            pre {
222                self.ownedNFTs[id] != nil: "Asset Token ID does not exist"
223            }
224
225            let refNFT = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
226            let refAssetNFT: &NTest_Trm_Asset_NFT.NFT = refNFT as! &NFT
227
228            return refAssetNFT.serialNumber
229        }
230        access(all) view fun getownerInfo(id: UInt64): String {
231            pre {
232                self.ownedNFTs[id] != nil: "Asset Token ID does not exist"
233            }
234
235            let refNFT = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
236            let refAssetNFT = refNFT as! &NFT
237
238        
239            return refAssetNFT.ownerInfo 
240        }
241
242        access(all) view fun getkID(id: UInt64): String {
243            pre {
244                self.ownedNFTs[id] != nil: "Asset Token ID does not exist"
245            }
246
247            let refNFT = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
248            let refAssetNFT = refNFT as! &NFT
249
250        
251            return refAssetNFT.kID 
252        }
253
254        access(contract) fun depositAsset(token: @{NonFungibleToken.NFT}) {
255            let assetToken <- token as! @NFT
256
257            let oldToken <- self.ownedNFTs[assetToken.id] <- assetToken
258
259            destroy oldToken
260        }
261
262        access(contract) fun transferOwner(id: UInt64, ownerFrom: String, ownerTo: String, songID: String, price: UFix64?, priceUnit: String?, paymentRefInfo: String?, webhookID: String?) {
263            pre {
264                self.ownedNFTs[id] != nil: "Asset Token ID does not exist"
265            }
266
267            let refNFT = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
268            let refAssetNFT = refNFT as! &NFT
269            
270            refAssetNFT.transferOwner(id: id, ownerFrom: ownerFrom, ownerTo: ownerTo, songID: songID, price: price, priceUnit: priceUnit, paymentRefInfo: paymentRefInfo, webhookID: webhookID)
271
272        }
273
274        access(contract) fun updateMetadata(id: UInt64, title: String?, description: String?, thumbnail: String?, assetType: String?, ownerInfo: String, metadata: {String:String}?, webhookID: String?) {
275            pre {
276                self.ownedNFTs[id] != nil: "Asset Token ID does not exist"
277            }
278
279            let refNFT = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
280            let refAssetNFT = refNFT as! &NFT
281            
282            refAssetNFT.updateMetadata(id: id, title: title, description: description, thumbnail: thumbnail, assetType: assetType,  ownerInfo: ownerInfo, metadata: metadata, webhookID:webhookID)
283            emit AssetUpdated(id: id, title: title, description: description, thumbnail: thumbnail, assetType: assetType, ownerInfo: ownerInfo, metadata: metadata, webhookID: webhookID)
284            
285        }
286
287        access(contract) fun batchupdateMetadata(ids: [UInt64], title: String?, description: String?, thumbnail: String?, assetType: String?, ownerInfo: String, metadata: {String:String}?, webhookID: String?) {
288            pre {
289                assetType == "private" || assetType == "public" || assetType == nil:
290                    "Asset Type must be private or public or null"
291
292                ids.length > 0: "Total length of ids cannot be less than 1"
293            }
294
295            for id in ids {
296                if self.ownedNFTs[id] != nil {
297
298                    let refNFT = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
299                    let refAssetNFT = refNFT as! &NFT
300                    
301                    refAssetNFT.updateMetadata(id: id, title: title, description: description, thumbnail: thumbnail, assetType: assetType, ownerInfo: ownerInfo, metadata: metadata, webhookID:webhookID)
302                } else {
303                    panic("Asset Token ID ".concat(id.toString()).concat(" not owned"))
304                }
305            }
306            emit AssetBatchUpdated(ids: ids, title: title, description: description,  thumbnail: thumbnail, assetType: assetType, ownerInfo: ownerInfo, metadata: metadata, webhookID: webhookID)
307        }
308
309
310
311    }
312
313    access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
314        return <- create Collection()
315    }
316
317    access(all) view fun getContractViews(resourceType: Type?): [Type] {
318        return [
319            Type<MetadataViews.NFTCollectionData>(),
320            Type<MetadataViews.NFTCollectionDisplay>()
321        ]
322    }
323
324
325    access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
326        switch viewType {
327            case Type<MetadataViews.NFTCollectionData>():
328                let collectionData = MetadataViews.NFTCollectionData(
329                    storagePath: self.CollectionStoragePath,
330                    publicPath: self.CollectionPublicPath,
331                    publicCollection: Type<&NTest_Trm_Asset_NFT.Collection>(),
332                    publicLinkedType: Type<&NTest_Trm_Asset_NFT.Collection>(),
333                    createEmptyCollectionFunction: (fun(): @{NonFungibleToken.Collection} {
334                        return <-NTest_Trm_Asset_NFT.createEmptyCollection(nftType: Type<@NTest_Trm_Asset_NFT.NFT>())
335                    })
336                )
337                return collectionData
338            case Type<MetadataViews.NFTCollectionDisplay>():
339                let media = MetadataViews.Media(
340                    file: MetadataViews.HTTPFile(
341                        url: "https://www.intertrust.com/wp-content/themes/flat-theme/assets/images/svg/intertrust-header-logoV2.png"
342                    ),
343                    mediaType: "image/png+xml"
344                )
345                return MetadataViews.NFTCollectionDisplay(
346                    name: "The Example Collection",
347                    description: "This collection is used as an example to help you develop your next Flow NFT.",
348                    externalURL: MetadataViews.ExternalURL("https://www.intertrust.com/marketmaker/"),
349                    squareImage: media,
350                    bannerImage: media,
351                    socials: {
352                        "twitter": MetadataViews.ExternalURL("https://x.com/IntertrustTech")
353                    }
354                )
355        }
356        return nil
357    }
358
359    access(all) resource NFTMinter {
360
361        /// mintNFT mints a new NFT with a new ID
362        /// and returns it to the calling context
363        access(all) fun mintNFT(
364            collectionRef: &NTest_Trm_Asset_NFT.Collection,
365            title: String,
366            description: String,
367            thumbnail: String,
368            metadata: {String: String},
369            serialNumber: UInt32,
370            url: String,
371            ownerInfo: String,
372            assetType: String,
373            kID: String,
374            songID: String,
375            masterTokenID: UInt64?,
376            webhookID: String?
377        ): UInt64  {
378
379            let tokenID = NTest_Trm_Asset_NFT.totalSupply
380            var finalMasterTokenID = tokenID
381
382            if let tempMasterTokenID = masterTokenID {
383                var masterTokenSerialNumber = collectionRef.getSerialNumber(id: tempMasterTokenID)
384                if masterTokenSerialNumber != 0 { panic("Invalid Master Token ID") }
385                finalMasterTokenID = tempMasterTokenID
386            }
387
388            collectionRef.deposit(token: <- create NFT(id: tokenID,
389            title: title,
390            description: description,
391            thumbnail: thumbnail,
392            metadata: metadata,
393            serialNumber: serialNumber,
394            url: url,
395            ownerInfo: ownerInfo,
396            assetType: assetType,
397            kID: kID,
398            songID: songID,
399            masterTokenID: finalMasterTokenID))
400
401            NTest_Trm_Asset_NFT.totalSupply = tokenID + 1
402            
403            return NTest_Trm_Asset_NFT.totalSupply
404            // create a new NFT
405           
406        }
407
408
409    }
410
411    access(all) resource Admin {
412
413        access(all) fun transferOwner(collectionRef: &NTest_Trm_Asset_NFT.Collection, id: UInt64, ownerFrom: String, ownerTo: String, songID: String, price: UFix64?, priceUnit: String?, paymentRefInfo: String?, webhookID: String?) {
414            
415           collectionRef.transferOwner(id: id, ownerFrom: ownerFrom, ownerTo: ownerTo, songID: songID, price: price, priceUnit: priceUnit, paymentRefInfo: paymentRefInfo, webhookID: webhookID)
416        }
417
418        access(all) fun updateMetadata(collectionRef: &NTest_Trm_Asset_NFT.Collection, id: UInt64, title: String?, description: String?, thumbnail: String?,  metadata: {String:String}?, ownerInfo: String, assetType: String?, webhookID: String?) {
419            
420            collectionRef.updateMetadata(id: id, title: title, description: description, thumbnail: thumbnail, assetType: assetType, ownerInfo: ownerInfo, metadata: metadata, webhookID: webhookID)
421        }
422        access(all) fun batchupdateMetadata(collectionRef: &NTest_Trm_Asset_NFT.Collection, ids: [UInt64], title: String?, description: String?, thumbnail: String?, metadata: {String:String}?, ownerInfo: String, assetType: String?,  webhookID: String?) {
423            
424            collectionRef.batchupdateMetadata(ids: ids, title: title, description: description, thumbnail: thumbnail, assetType: assetType, ownerInfo: ownerInfo, metadata: metadata, webhookID: webhookID)
425        }
426
427        access(all) fun depositAsset(collectionRef: &NTest_Trm_Asset_NFT.Collection,title: String, description: String, thumbnail: String, metadata: {String: String}, serialNumber: UInt32, url: String,ownerInfo: String, assetType: String, kID: String,songID: String, masterTokenID: UInt64?,webhookID: String?): UInt64 {
428            
429            let tokenID = NTest_Trm_Asset_NFT.totalSupply
430                var finalMasterTokenID = tokenID
431
432                if let tempMasterTokenID = masterTokenID {
433                    var masterTokenSerialNumber = collectionRef.getSerialNumber(id: tempMasterTokenID)
434                    if masterTokenSerialNumber != 0 { panic("Invalid Master Token ID") }
435                    finalMasterTokenID = tempMasterTokenID
436                }
437
438                collectionRef.depositAsset(token: <- create NFT(id: tokenID, title: title, description: description, thumbnail: thumbnail, metadata: metadata, serialNumber: serialNumber, url: url, ownerInfo: ownerInfo, assetType: assetType,kID: kID, songID: songID, masterTokenID: finalMasterTokenID))
439
440                NTest_Trm_Asset_NFT.totalSupply = tokenID + 1
441
442                emit AssetMinted(id: tokenID, title: title, description: description, thumbnail: thumbnail, metadata: metadata, serialNumber: serialNumber, url: url, ownerInfo: ownerInfo, assetType: assetType, kID: kID, songID: songID,masterTokenID: finalMasterTokenID, webhookID: webhookID)
443                
444                return NTest_Trm_Asset_NFT.totalSupply
445                // create a new NFT
446           
447        }
448        access(all) fun batchdepositAsset(collectionRef: &NTest_Trm_Asset_NFT.Collection, totalCount: UInt32, title: String, description: String, thumbnail: String, metadata: {String: String},startSerialNumber: UInt32, url: String, ownerInfo: String, assetType: String, kID: String, songID: String, masterTokenID: UInt64?, webhookID: String?): UInt64 {
449            pre {
450                totalCount > 0: "Total Count cannot be less than 1"
451               }
452            
453            let startTokenID = NTest_Trm_Asset_NFT.totalSupply
454            var tempmasterTokenID = startTokenID
455
456            if masterTokenID != nil {
457                tempmasterTokenID = masterTokenID!
458            }
459
460            var tokenID = startTokenID
461            var counter: UInt32 = 0
462            var serialNumber = startSerialNumber
463
464            while counter < totalCount {
465
466                collectionRef.depositAsset(token: <- create NFT(id: tokenID, title: title, description: description, thumbnail: thumbnail, metadata: metadata, serialNumber: serialNumber, url: url, ownerInfo: ownerInfo, assetType: assetType, kID: kID, songID: songID, masterTokenID: tempmasterTokenID))
467
468                counter = counter + 1
469                tokenID = tokenID + 1
470                serialNumber = serialNumber + 1
471            }
472
473            let endTokenID = tokenID - 1
474            let endSerialNumber = serialNumber - 1
475
476            emit AssetBatchMinted(startID: startTokenID, endID: endTokenID, totalCount: totalCount, startSerialNumber: startSerialNumber, endSerialNumber: endSerialNumber, title: title, description: description, thumbnail: thumbnail, metadata: metadata, url: url, ownerInfo: ownerInfo, assetType: assetType, kID: kID, songID: songID, masterTokenID: tempmasterTokenID, webhookID: webhookID) 
477            
478            NTest_Trm_Asset_NFT.totalSupply = tokenID
479
480            return NTest_Trm_Asset_NFT.totalSupply
481
482        }
483
484
485    }
486
487    init() {
488        // Set the named paths
489        self.CollectionStoragePath =  /storage/NTest_Trm_Asset_NFTCollection
490        self.CollectionPublicPath = /public/NTest_Trm_Asset_NFTCollection
491        self.MinterStoragePath = /storage/NTest_Trm_Asset_NFTMinter
492        self.adminStoragePath = /storage/NTest_Trm_Asset_NFTAdmin
493
494        // First, check to see if a minter resource already exists
495        if self.account.storage.type(at: self.MinterStoragePath) == nil {
496            // Put the minter in storage with access only to admin
497            self.account.storage.save(<-create NFTMinter(), to: self.MinterStoragePath)
498        }
499
500        // First, check to see if a minter resource already exists
501        if self.account.storage.type(at: self.adminStoragePath) == nil {
502            // Put the minter in storage with access only to admin
503            self.account.storage.save(<-create Admin(), to: self.adminStoragePath)
504        }
505
506        self.totalSupply = 0
507
508    }
509}
510