Smart Contract

SoulMadeComponent

A.9a57dfe5c8ce609c.SoulMadeComponent

Deployed

2h ago
Feb 28, 2026, 06:38:20 PM UTC

Dependents

0 imports
1import NonFungibleToken from 0x1d7e57aa55817448
2import MetadataViews from 0x1d7e57aa55817448
3import FlowToken from 0x1654653399040a61
4import FungibleToken from 0xf233dcee88fe0abe
5
6
7pub contract SoulMadeComponent: NonFungibleToken {
8
9    pub var totalSupply: UInt64
10    
11    pub event ContractInitialized()
12
13    pub event Withdraw(id: UInt64, from: Address?)
14    pub event Deposit(id: UInt64, to: Address?)
15
16    pub event SoulMadeComponentCollectionCreated()
17    pub event SoulMadeComponentCreated(componentDetail: ComponentDetail)
18
19    pub let CollectionStoragePath: StoragePath
20    pub let CollectionPublicPath: PublicPath
21    pub let CollectionPrivatePath: PrivatePath
22
23    pub struct ComponentDetail{
24        pub let id: UInt64
25        pub let series: String
26        pub let name: String
27        pub let description: String
28        pub let category: String
29        pub let layer: UInt64
30        pub let edition: UInt64
31        pub let maxEdition: UInt64
32        pub let ipfsHash: String
33
34        init(id: UInt64,
35            series: String,
36            name: String,
37            description: String,
38            category: String,
39            layer: UInt64,
40            edition: UInt64,
41            maxEdition: UInt64,
42            ipfsHash: String) {
43                self.id=id
44                self.series=series
45                self.name=name
46                self.description=description
47                self.category=category
48                self.layer=layer
49                self.edition=edition
50                self.maxEdition=maxEdition
51                self.ipfsHash=ipfsHash
52        }
53    }
54
55    pub resource interface ComponentPublic {
56        pub let id: UInt64
57        pub let componentDetail: ComponentDetail
58    }
59
60    pub resource NFT: NonFungibleToken.INFT, ComponentPublic, MetadataViews.Resolver{
61        pub let id: UInt64
62        pub let componentDetail: ComponentDetail
63
64        pub fun getViews(): [Type] {
65            return [
66                Type<MetadataViews.Display>(),
67                Type<MetadataViews.Royalties>(),
68                Type<MetadataViews.ExternalURL>(),
69                Type<MetadataViews.NFTCollectionData>(),
70                Type<MetadataViews.NFTCollectionDisplay>()
71            ]
72        }
73
74        pub fun resolveView(_ view: Type): AnyStruct? {
75            switch view {
76                case Type<MetadataViews.Display>():
77                    return MetadataViews.Display(
78                        name: self.componentDetail.name,
79                        description: self.componentDetail.description,
80                        thumbnail: MetadataViews.IPFSFile(
81                            cid: self.componentDetail.ipfsHash,
82                            path: nil
83                        )
84                    )
85                case Type<MetadataViews.Royalties>():
86                    return MetadataViews.Royalties([
87						MetadataViews.Royalty(
88							recepient: getAccount(0x9a57dfe5c8ce609c).getCapability<&FlowToken.Vault{FungibleToken.Receiver}>(/public/flowTokenReceiver),
89							cut: 0.00, 
90							description: "SoulMade Component Royalties"
91						)
92					])
93                case Type<MetadataViews.ExternalURL>():
94                    return MetadataViews.ExternalURL("https://soulmade.art")
95                case Type<MetadataViews.NFTCollectionData>():
96                    return MetadataViews.NFTCollectionData(
97                        storagePath: SoulMadeComponent.CollectionStoragePath,
98                        publicPath: SoulMadeComponent.CollectionPublicPath,
99                        providerPath: /private/SoulMadeComponentCollection,
100                        publicCollection: Type<&Collection{CollectionPublic}>(),
101                        publicLinkedType: Type<&Collection{CollectionPublic, NonFungibleToken.CollectionPublic, NonFungibleToken.Receiver, MetadataViews.ResolverCollection}>(),
102                        providerLinkedType: Type<&Collection{CollectionPublic, NonFungibleToken.CollectionPublic, NonFungibleToken.Provider, MetadataViews.ResolverCollection}>(),
103                        createEmptyCollectionFunction: (fun (): @NonFungibleToken.Collection {
104                            return <- SoulMadeComponent.createEmptyCollection()
105                        })
106                    )
107                case Type<MetadataViews.NFTCollectionDisplay>():
108                    let squareMedia = MetadataViews.Media(
109                        file: MetadataViews.HTTPFile(
110                           url: "https://i.imgur.com/XgqDY3s.jpg"
111                        ),
112                        mediaType: "image"
113                    )
114                    let bannerMedia = MetadataViews.Media(
115                        file: MetadataViews.HTTPFile(
116                            url: "https://i.imgur.com/yBw3ktk.png"
117                        ),
118                        mediaType: "image"
119                    )
120                    return MetadataViews.NFTCollectionDisplay(
121                        name: "SoulMadeComponent",
122                        description: "SoulMade Component Collection",
123                        externalURL: MetadataViews.ExternalURL("https://soulmade.art"),
124                        squareImage: squareMedia,
125                        bannerImage: bannerMedia,
126                        socials: {
127                            "twitter": MetadataViews.ExternalURL("https://twitter.com/soulmade_nft"),
128                            "discord": MetadataViews.ExternalURL("https://discord.com/invite/xtqqXCKW9B")
129                        }
130                    )
131            }
132
133            return nil
134        }
135
136        init(id: UInt64,
137            componentDetail: ComponentDetail) {
138                self.id=id
139                self.componentDetail=componentDetail
140        }
141    }
142
143    pub resource interface CollectionPublic {
144        pub fun deposit(token: @NonFungibleToken.NFT)
145        pub fun getIDs(): [UInt64]
146        pub fun borrowViewResolver(id: UInt64): &{MetadataViews.Resolver}
147        pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
148        pub fun borrowComponent(id: UInt64): &{SoulMadeComponent.ComponentPublic}
149    }
150
151
152    pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic, MetadataViews.ResolverCollection {
153        pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}
154
155        init () {
156            self.ownedNFTs <- {}
157        }
158
159        pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
160            let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing Component NFT")
161            emit Withdraw(id: token.id, from: self.owner?.address)
162            return <- token
163        }
164
165        pub fun deposit(token: @NonFungibleToken.NFT) {
166            let token <- token as! @SoulMadeComponent.NFT
167            let id: UInt64 = token.id
168            let oldToken <- self.ownedNFTs[id] <- token
169            emit Deposit(id: id, to: self.owner?.address)
170            destroy oldToken
171        }
172
173        pub fun getIDs(): [UInt64] {
174            return self.ownedNFTs.keys
175        }
176
177        pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
178            return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)!
179        }
180
181        pub fun borrowComponent(id: UInt64): &{SoulMadeComponent.ComponentPublic} {
182            pre {
183                self.ownedNFTs[id] != nil: "Component NFT doesn't exist"
184            }
185            let ref = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
186            return ref as! &SoulMadeComponent.NFT
187        }
188
189        pub fun borrowViewResolver(id: UInt64): &{MetadataViews.Resolver} {
190            let nft = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
191            let componentNFT = nft as! &SoulMadeComponent.NFT
192            return componentNFT as &{MetadataViews.Resolver}
193        }        
194
195
196
197        destroy() {
198            destroy self.ownedNFTs
199        }
200    }
201
202    pub fun createEmptyCollection(): @NonFungibleToken.Collection {
203        emit SoulMadeComponentCollectionCreated()
204        return <- create Collection()
205    }
206
207    access(account) fun makeEdition(series: String,
208                                    name: String,
209                                    description: String,
210                                    category: String,
211                                    layer: UInt64,
212                                    currentEdition: UInt64,
213                                    maxEdition: UInt64,
214                                    ipfsHash: String) : @NFT {
215        let componentDetail = ComponentDetail(
216            id: SoulMadeComponent.totalSupply,
217            series: series,
218            name: name,
219            description: description,
220            category: category,
221            layer: layer,
222            edition: currentEdition,
223            maxEdition: maxEdition,
224            ipfsHash: ipfsHash            
225        )
226
227        var newNFT <- create NFT(
228            id: SoulMadeComponent.totalSupply,
229            componentDetail: componentDetail
230        )
231
232        emit SoulMadeComponentCreated(componentDetail: componentDetail)
233        
234        SoulMadeComponent.totalSupply = SoulMadeComponent.totalSupply + UInt64(1)
235
236        return <- newNFT
237    }
238
239    init() {
240        self.totalSupply = 0
241        
242        self.CollectionPublicPath = /public/SoulMadeComponentCollection
243        self.CollectionStoragePath = /storage/SoulMadeComponentCollection
244        self.CollectionPrivatePath = /private/SoulMadeComponentCollection
245
246        emit ContractInitialized()
247    }
248}