-
Notifications
You must be signed in to change notification settings - Fork 53
/
FungibleTokenMetadataViews.cdc
186 lines (164 loc) · 6.77 KB
/
FungibleTokenMetadataViews.cdc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
import "FungibleToken"
import "MetadataViews"
import "ViewResolver"
/// This contract implements the metadata standard proposed
/// in FLIP-1087.
///
/// Ref: https://github.com/onflow/flips/blob/main/application/20220811-fungible-tokens-metadata.md
///
/// Structs and resources can implement one or more
/// metadata types, called views. Each view type represents
/// a different kind of metadata.
///
access(all) contract FungibleTokenMetadataViews {
/// FTView wraps FTDisplay and FTVaultData, and is used to give a complete
/// picture of a Fungible Token. Most Fungible Token contracts should
/// implement this view.
///
access(all) struct FTView {
access(all) let ftDisplay: FTDisplay?
access(all) let ftVaultData: FTVaultData?
view init(
ftDisplay: FTDisplay?,
ftVaultData: FTVaultData?
) {
self.ftDisplay = ftDisplay
self.ftVaultData = ftVaultData
}
}
/// Helper to get a FT view.
///
/// @param viewResolver: A reference to the resolver resource
/// @return A FTView struct
///
access(all) fun getFTView(viewResolver: &{ViewResolver.Resolver}): FTView {
let maybeFTView = viewResolver.resolveView(Type<FTView>())
if let ftView = maybeFTView {
return ftView as! FTView
}
return FTView(
ftDisplay: self.getFTDisplay(viewResolver),
ftVaultData: self.getFTVaultData(viewResolver)
)
}
/// View to expose the information needed to showcase this FT.
/// This can be used by applications to give an overview and
/// graphics of the FT.
///
access(all) struct FTDisplay {
/// The display name for this token.
///
/// Example: "Flow"
///
access(all) let name: String
/// The abbreviated symbol for this token.
///
/// Example: "FLOW"
access(all) let symbol: String
/// A description the provides an overview of this token.
///
/// Example: "The FLOW token is the native currency of the Flow network."
access(all) let description: String
/// External link to a URL to view more information about the fungible token.
access(all) let externalURL: MetadataViews.ExternalURL
/// One or more versions of the fungible token logo.
access(all) let logos: MetadataViews.Medias
/// Social links to reach the fungible token's social homepages.
/// Possible keys may be "instagram", "twitter", "discord", etc.
access(all) let socials: {String: MetadataViews.ExternalURL}
view init(
name: String,
symbol: String,
description: String,
externalURL: MetadataViews.ExternalURL,
logos: MetadataViews.Medias,
socials: {String: MetadataViews.ExternalURL}
) {
self.name = name
self.symbol = symbol
self.description = description
self.externalURL = externalURL
self.logos = logos
self.socials = socials
}
}
/// Helper to get FTDisplay in a way that will return a typed optional.
///
/// @param viewResolver: A reference to the resolver resource
/// @return An optional FTDisplay struct
///
access(all) fun getFTDisplay(_ viewResolver: &{ViewResolver.Resolver}): FTDisplay? {
if let maybeDisplayView = viewResolver.resolveView(Type<FTDisplay>()) {
if let displayView = maybeDisplayView as? FTDisplay {
return displayView
}
}
return nil
}
/// View to expose the information needed store and interact with a FT vault.
/// This can be used by applications to setup a FT vault with proper
/// storage and public capabilities.
///
access(all) struct FTVaultData {
/// Path in storage where this FT vault is recommended to be stored.
access(all) let storagePath: StoragePath
/// Public path which must be linked to expose the public receiver capability.
access(all) let receiverPath: PublicPath
/// Public path which must be linked to expose the balance and resolver public capabilities.
access(all) let metadataPath: PublicPath
/// Type that should be linked at the `receiverPath`. This is a restricted type requiring
/// the `FungibleToken.Receiver` interface.
access(all) let receiverLinkedType: Type
/// Type that should be linked at the `receiverPath`. This is a restricted type requiring
/// the `ViewResolver.Resolver` interfaces.
access(all) let metadataLinkedType: Type
/// Function that allows creation of an empty FT vault that is intended
/// to store the funds.
access(all) let createEmptyVault: fun(): @{FungibleToken.Vault}
view init(
storagePath: StoragePath,
receiverPath: PublicPath,
metadataPath: PublicPath,
receiverLinkedType: Type,
metadataLinkedType: Type,
createEmptyVaultFunction: fun(): @{FungibleToken.Vault}
) {
pre {
receiverLinkedType.isSubtype(of: Type<&{FungibleToken.Receiver}>()):
"Receiver public type <".concat(receiverLinkedType.identifier)
.concat("> must be a subtype of <").concat(Type<&{FungibleToken.Receiver}>().identifier)
.concat(">.")
metadataLinkedType.isSubtype(of: Type<&{FungibleToken.Vault}>()):
"Metadata linked type <".concat(metadataLinkedType.identifier)
.concat("> must be a subtype of <").concat(Type<&{FungibleToken.Vault}>().identifier)
.concat(">.")
}
self.storagePath = storagePath
self.receiverPath = receiverPath
self.metadataPath = metadataPath
self.receiverLinkedType = receiverLinkedType
self.metadataLinkedType = metadataLinkedType
self.createEmptyVault = createEmptyVaultFunction
}
}
/// Helper to get FTVaultData in a way that will return a typed Optional.
///
/// @param viewResolver: A reference to the resolver resource
/// @return A optional FTVaultData struct
///
access(all) fun getFTVaultData(_ viewResolver: &{ViewResolver.Resolver}): FTVaultData? {
if let view = viewResolver.resolveView(Type<FTVaultData>()) {
if let v = view as? FTVaultData {
return v
}
}
return nil
}
/// View to expose the total supply of the Vault's token
access(all) struct TotalSupply {
access(all) let supply: UFix64
view init(totalSupply: UFix64) {
self.supply = totalSupply
}
}
}