Smart Contract

StarlyCard

A.5b82f21c0edf76e3.StarlyCard

Deployed

2d ago
Feb 25, 2026, 02:55:55 AM UTC

Dependents

83 imports
1import NonFungibleToken from 0x1d7e57aa55817448
2import ViewResolver from 0x1d7e57aa55817448
3import MetadataViews from 0x1d7e57aa55817448
4import StarlyMetadata from 0x5b82f21c0edf76e3
5import StarlyMetadataViews from 0x5b82f21c0edf76e3
6
7access(all) contract StarlyCard: NonFungibleToken {
8
9    access(all) event Minted(id: UInt64, starlyID: String)
10    access(all) event MinterCreated()
11
12    access(all) let CollectionStoragePath: StoragePath
13    access(all) let CollectionPublicPath: PublicPath
14    access(all) let AdminStoragePath: StoragePath
15    access(all) let MinterStoragePath: StoragePath
16    access(all) let MinterProxyStoragePath: StoragePath
17    access(all) let MinterProxyPublicPath: PublicPath
18
19    access(all) var totalSupply: UInt64
20
21    access(all) resource NFT: NonFungibleToken.NFT {
22        access(all) let id: UInt64
23        access(all) let starlyID: String
24
25        init(initID: UInt64, initStarlyID: String) {
26            self.id = initID
27            self.starlyID = initStarlyID
28        }
29
30        access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
31            return <-StarlyCard.createEmptyCollection(nftType: Type<@StarlyCard.NFT>())
32        }
33
34        access(all) fun getMetadata(): StarlyMetadataViews.CardEdition? {
35            return StarlyMetadata.getCardEdition(starlyID: self.starlyID);
36        }
37
38        access(all) view fun getViews(): [Type] {
39            return StarlyMetadata.getViews()
40        }
41
42        access(all) fun resolveView(_ view: Type): AnyStruct? {
43            switch view {
44                case Type<MetadataViews.NFTCollectionData>():
45                    return StarlyCard.resolveContractView(resourceType: Type<@StarlyCard.NFT>(), viewType: Type<MetadataViews.NFTCollectionData>())
46                default:
47                    return StarlyMetadata.resolveView(starlyID: self.starlyID, view: view)
48            }
49        }
50    }
51
52    access(all) resource interface StarlyCardCollectionPublic {
53        access(all) view fun borrowStarlyCard(id: UInt64): &StarlyCard.NFT? {
54            post {
55                (result == nil) || (result?.id == id):
56                    "Cannot borrow StarlyCard reference: The ID of the returned reference is incorrect"
57            }
58        }
59    }
60
61    access(all) resource Collection: NonFungibleToken.Collection, StarlyCardCollectionPublic {
62
63        access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
64
65        access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
66            let supportedTypes: {Type: Bool} = {}
67            supportedTypes[Type<@StarlyCard.NFT>()] = true
68            return supportedTypes
69        }
70
71        access(all) view fun isSupportedNFTType(type: Type): Bool {
72           if type == Type<@StarlyCard.NFT>() {
73            return true
74           } else {
75            return false
76           }
77        }
78
79        access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
80            let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
81            return <-token
82        }
83
84        access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
85            let token <- token as! @StarlyCard.NFT
86            let oldToken <- self.ownedNFTs[token.id] <- token
87            destroy oldToken
88        }
89
90        access(all) view fun getIDs(): [UInt64] {
91            return self.ownedNFTs.keys
92        }
93
94        access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
95            return (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)
96        }
97
98        access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
99            if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
100                return nft as &{ViewResolver.Resolver}
101            }
102            return nil
103        }
104
105        access(all) view fun borrowStarlyCard(id: UInt64): &StarlyCard.NFT? {
106            if self.ownedNFTs[id] != nil {
107                let ref = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
108                return ref as! &StarlyCard.NFT
109            } else {
110                return nil
111            }
112        }
113
114        access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
115            return <-StarlyCard.createEmptyCollection(nftType: Type<@StarlyCard.NFT>())
116        }
117
118        init () {
119            self.ownedNFTs <- {}
120        }
121    }
122
123    access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
124        return <- create Collection()
125    }
126
127    access(all) view fun fetch(_ from: Address, itemID: UInt64): &StarlyCard.NFT? {
128        let collection = getAccount(from).capabilities.borrow<&StarlyCard.Collection>(self.CollectionPublicPath)!
129        return collection.borrowStarlyCard(id: itemID)
130    }
131
132    access(all) view fun getContractViews(resourceType: Type?): [Type] {
133        return [
134            Type<MetadataViews.NFTCollectionData>(),
135            Type<MetadataViews.NFTCollectionDisplay>()
136        ]
137    }
138
139    access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
140        switch viewType {
141            case Type<MetadataViews.NFTCollectionData>():
142                return MetadataViews.NFTCollectionData(
143                    storagePath: StarlyCard.CollectionStoragePath,
144                    publicPath: StarlyCard.CollectionPublicPath,
145                    publicCollection: Type<&StarlyCard.Collection>(),
146                    publicLinkedType: Type<&StarlyCard.Collection>(),
147                    createEmptyCollectionFunction: (fun (): @{NonFungibleToken.Collection} {
148                        return <-StarlyCard.createEmptyCollection(nftType: Type<@StarlyCard.NFT>())
149                    }))
150            case Type<MetadataViews.NFTCollectionDisplay>():
151                return StarlyMetadata.getNFTCollectionDisplay();
152        }
153        return nil
154    }
155
156    access(all) resource NFTMinter {
157
158        access(all) fun mintNFT(recipient: &{NonFungibleToken.CollectionPublic}, starlyID: String) {
159            emit Minted(id: StarlyCard.totalSupply, starlyID: starlyID)
160            recipient.deposit(token: <-create StarlyCard.NFT(initID: StarlyCard.totalSupply, initStarlyID: starlyID))
161            StarlyCard.totalSupply = StarlyCard.totalSupply + (1 as UInt64)
162        }
163
164        access(all) fun cloneNFT(id: UInt64, starlyID: String): @StarlyCard.NFT {
165            return <-create StarlyCard.NFT(initID: id, initStarlyID: starlyID)
166        }
167    }
168
169    access(all) resource interface MinterProxyPublic {
170        access(all) fun setMinterCapability(capability: Capability<&NFTMinter>)
171    }
172
173    access(all) resource MinterProxy: MinterProxyPublic {
174
175        access(self) var minterCapability: Capability<&NFTMinter>?
176
177        access(all) fun setMinterCapability(capability: Capability<&NFTMinter>) {
178            self.minterCapability = capability
179        }
180
181        access(all) fun mintNFT(recipient: &{NonFungibleToken.CollectionPublic}, starlyID: String) {
182            self.minterCapability!
183            .borrow()!
184            .mintNFT(recipient: recipient, starlyID: starlyID)
185        }
186
187        access(all) fun cloneNFT(id: UInt64, starlyID: String): @StarlyCard.NFT {
188            return <-self.minterCapability!
189            .borrow()!
190            .cloneNFT(id: id, starlyID: starlyID)
191        }
192
193        init() {
194            self.minterCapability = nil
195        }
196    }
197
198    access(all) fun createMinterProxy(): @MinterProxy {
199        return <- create MinterProxy()
200    }
201
202    access(all) resource Administrator {
203
204        access(all) fun createNewMinter(): @NFTMinter {
205            emit MinterCreated()
206            return <- create NFTMinter()
207        }
208    }
209
210    init() {
211        self.CollectionStoragePath = /storage/starlyCardCollection
212        self.CollectionPublicPath = /public/starlyCardCollection
213        self.AdminStoragePath = /storage/starlyCardAdmin
214        self.MinterStoragePath = /storage/starlyCardMinter
215        self.MinterProxyPublicPath = /public/starlyCardMinterProxy
216        self.MinterProxyStoragePath = /storage/starlyCardMinterProxy
217
218        self.totalSupply = 0
219
220        let admin <- create Administrator()
221        let minter <- admin.createNewMinter()
222        self.account.storage.save(<-admin, to: self.AdminStoragePath)
223        self.account.storage.save(<-minter, to: self.MinterStoragePath)
224    }
225}
226