Smart Contract
BaseCollection
A.befbaccb5032a457.BaseCollection
1import NonFungibleToken from 0x1d7e57aa55817448
2import ViewResolver from 0x1d7e57aa55817448
3import MetadataViews from 0x1d7e57aa55817448
4import NFTMetadata from 0xbefbaccb5032a457
5import FlowtyDrops from 0xbefbaccb5032a457
6import AddressUtils from 0xa340dc0a4ec828ab
7import StringUtils from 0xa340dc0a4ec828ab
8
9access(all) contract interface BaseCollection: ViewResolver {
10 access(all) var MetadataCap: Capability<&NFTMetadata.Container>
11 access(all) var totalSupply: UInt64
12
13 access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection}
14
15 // The base collection is an interface that attmepts to take more boilerplate
16 // off of NFT-standard compliant definitions.
17 access(all) resource interface Collection: NonFungibleToken.Collection {
18 access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
19 access(all) var nftType: Type
20
21 access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
22 pre {
23 token.getType() == self.nftType: "unexpected nft type being deposited"
24 }
25
26 destroy self.ownedNFTs.insert(key: token.id, <-token)
27 }
28
29 access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
30 return &self.ownedNFTs[id]
31 }
32
33 access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
34 return {
35 self.nftType: true
36 }
37 }
38
39 access(all) view fun isSupportedNFTType(type: Type): Bool {
40 return type == self.nftType
41 }
42
43 access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
44 return <- self.ownedNFTs.remove(key: withdrawID)!
45 }
46 }
47
48 access(all) view fun getContractViews(resourceType: Type?): [Type] {
49 return [
50 Type<MetadataViews.NFTCollectionData>(),
51 Type<MetadataViews.NFTCollectionDisplay>()
52 ]
53 }
54
55 access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
56 if resourceType == nil {
57 return nil
58 }
59
60 let rt = resourceType!
61 let segments = rt.identifier.split(separator: ".")
62 let pathIdentifier = StringUtils.join([segments[2], segments[1]], "_")
63
64 let addr = AddressUtils.parseAddress(rt)!
65 let acct = getAccount(addr)
66
67 switch viewType {
68 case Type<MetadataViews.NFTCollectionData>():
69 let segments = rt.identifier.split(separator: ".")
70 let pathIdentifier = StringUtils.join([segments[2], segments[1]], "_")
71
72 return MetadataViews.NFTCollectionData(
73 storagePath: StoragePath(identifier: pathIdentifier)!,
74 publicPath: PublicPath(identifier: pathIdentifier)!,
75 publicCollection: Type<&{NonFungibleToken.Collection}>(),
76 publicLinkedType: Type<&{NonFungibleToken.Collection}>(),
77 createEmptyCollectionFunction: fun(): @{NonFungibleToken.Collection} {
78 let addr = AddressUtils.parseAddress(rt)!
79 let c = getAccount(addr).contracts.borrow<&{BaseCollection}>(name: segments[2])!
80 return <- c.createEmptyCollection(nftType: rt)
81 }
82 )
83 case Type<FlowtyDrops.DropResolver>():
84 return FlowtyDrops.DropResolver(cap: acct.capabilities.get<&{FlowtyDrops.ContainerPublic}>(FlowtyDrops.ContainerPublicPath))
85 }
86
87 // These views require the {BaseCollection} interface
88 if let c = getAccount(addr).contracts.borrow<&{BaseCollection}>(name: segments[2]) {
89 let tmp = c.MetadataCap.borrow()
90 if tmp == nil {
91 return nil
92 }
93
94 switch viewType {
95 case Type<MetadataViews.NFTCollectionDisplay>():
96 return tmp!.collectionInfo.getDisplay()
97 case Type<MetadataViews.Royalties>():
98 let keys = tmp!.metadata.keys
99 if keys.length == 0 || keys.length > 1 {
100 return nil
101 }
102 return tmp!.borrowMetadata(id: keys[0])!.getRoyalties()
103 }
104 }
105
106 return nil
107 }
108}