Smart Contract
StarlyCard
A.5b82f21c0edf76e3.StarlyCard
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