@flowtyio/flow-contracts 0.0.18 → 0.1.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,302 @@
1
+ import "FungibleToken"
2
+ import "FungibleTokenMetadataViews"
3
+ import "MetadataViews"
4
+
5
+
6
+ // THIS CONTRACT IS FOR TESTING PURPOSES ONLY!
7
+ access(all) contract ExampleToken {
8
+
9
+ /// Total supply of ExampleTokens in existence
10
+ access(all) var totalSupply: UFix64
11
+
12
+ /// TokensInitialized
13
+ ///
14
+ /// The event that is emitted when the contract is created
15
+ access(all) event TokensInitialized(initialSupply: UFix64)
16
+
17
+ /// TokensWithdrawn
18
+ ///
19
+ /// The event that is emitted when tokens are withdrawn from a Vault
20
+ access(all) event TokensWithdrawn(amount: UFix64, from: Address?)
21
+
22
+ /// TokensDeposited
23
+ ///
24
+ /// The event that is emitted when tokens are deposited to a Vault
25
+ access(all) event TokensDeposited(amount: UFix64, to: Address?)
26
+
27
+ /// TokensMinted
28
+ ///
29
+ /// The event that is emitted when new tokens are minted
30
+ access(all) event TokensMinted(amount: UFix64)
31
+
32
+ /// TokensBurned
33
+ ///
34
+ /// The event that is emitted when tokens are destroyed
35
+ access(all) event TokensBurned(amount: UFix64)
36
+
37
+ /// MinterCreated
38
+ ///
39
+ /// The event that is emitted when a new minter resource is created
40
+ access(all) event MinterCreated(allowedAmount: UFix64)
41
+
42
+ /// BurnerCreated
43
+ ///
44
+ /// The event that is emitted when a new burner resource is created
45
+ access(all) event BurnerCreated()
46
+
47
+ /// Vault
48
+ ///
49
+ /// Each user stores an instance of only the Vault in their storage
50
+ /// The functions in the Vault and governed by the pre and post conditions
51
+ /// in FungibleToken when they are called.
52
+ /// The checks happen at runtime whenever a function is called.
53
+ ///
54
+ /// Resources can only be created in the context of the contract that they
55
+ /// are defined in, so there is no way for a malicious user to create Vaults
56
+ /// out of thin air. A special Minter resource needs to be defined to mint
57
+ /// new tokens.
58
+ ///
59
+ access(all) resource Vault: FungibleToken.Vault {
60
+
61
+ /// The total balance of this vault
62
+ access(all) var balance: UFix64
63
+
64
+ // initialize the balance at resource creation time
65
+ init(balance: UFix64) {
66
+ self.balance = balance
67
+ }
68
+
69
+ access(all) view fun getBalance(): UFix64 {
70
+ return self.balance
71
+ }
72
+
73
+ access(all) view fun getDefaultStoragePath(): StoragePath? {
74
+ return /storage/exampleTokenVault
75
+ }
76
+
77
+ access(all) view fun getDefaultPublicPath(): PublicPath? {
78
+ return /public/exampleTokenPublic
79
+ }
80
+
81
+ access(all) view fun getDefaultReceiverPath(): PublicPath? {
82
+ return /public/exampleTokenPublic
83
+ }
84
+
85
+ access(all) view fun isAvailableToWithdraw(amount: UFix64): Bool {
86
+ return self.balance >= amount
87
+ }
88
+
89
+ /// Same as getViews above, but on a specific NFT instead of a contract
90
+ access(all) view fun getViews(): [Type] {
91
+ return ExampleToken.getContractViews(resourceType: nil)
92
+ }
93
+
94
+ /// Same as resolveView above, but on a specific NFT instead of a contract
95
+ access(all) fun resolveView(_ view: Type): AnyStruct? {
96
+ return ExampleToken.resolveContractView(resourceType: nil, viewType: view)
97
+ }
98
+
99
+ /// withdraw
100
+ ///
101
+ /// Function that takes an amount as an argument
102
+ /// and withdraws that amount from the Vault.
103
+ ///
104
+ /// It creates a new temporary Vault that is used to hold
105
+ /// the money that is being transferred. It returns the newly
106
+ /// created Vault to the context that called so it can be deposited
107
+ /// elsewhere.
108
+ ///
109
+ access(FungibleToken.Withdraw) fun withdraw(amount: UFix64): @{FungibleToken.Vault} {
110
+ self.balance = self.balance - amount
111
+ emit TokensWithdrawn(amount: amount, from: self.owner?.address)
112
+ return <-create Vault(balance: amount)
113
+ }
114
+
115
+ access(all) view fun getSupportedVaultTypes(): {Type: Bool} {
116
+ return {
117
+ Type<@ExampleToken.Vault>(): true
118
+ }
119
+ }
120
+
121
+ access(all) view fun isSupportedVaultType(type: Type): Bool {
122
+ return type == Type<@ExampleToken.Vault>()
123
+ }
124
+
125
+ /// deposit
126
+ ///
127
+ /// Function that takes a Vault object as an argument and adds
128
+ /// its balance to the balance of the owners Vault.
129
+ ///
130
+ /// It is allowed to destroy the sent Vault because the Vault
131
+ /// was a temporary holder of the tokens. The Vault's balance has
132
+ /// been consumed and therefore can be destroyed.
133
+ ///
134
+ access(all) fun deposit(from: @{FungibleToken.Vault}) {
135
+ let vault <- from as! @ExampleToken.Vault
136
+ self.balance = self.balance + vault.balance
137
+ emit TokensDeposited(amount: vault.balance, to: self.owner?.address)
138
+ vault.balance = 0.0
139
+ destroy vault
140
+ }
141
+
142
+ access(all) fun createEmptyVault(): @Vault {
143
+ return <- ExampleToken.createEmptyVault()
144
+ }
145
+ }
146
+
147
+ /// createEmptyVault
148
+ ///
149
+ /// Function that creates a new Vault with a balance of zero
150
+ /// and returns it to the calling context. A user must call this function
151
+ /// and store the returned Vault in their storage in order to allow their
152
+ /// account to be able to receive deposits of this token type.
153
+ ///
154
+ access(all) fun createEmptyVault(): @Vault {
155
+ return <-create Vault(balance: 0.0)
156
+ }
157
+
158
+ access(all) resource Administrator {
159
+
160
+ /// createNewMinter
161
+ ///
162
+ /// Function that creates and returns a new minter resource
163
+ ///
164
+ access(all) fun createNewMinter(allowedAmount: UFix64): @Minter {
165
+ emit MinterCreated(allowedAmount: allowedAmount)
166
+ return <-create Minter(allowedAmount: allowedAmount)
167
+ }
168
+
169
+ /// createNewBurner
170
+ ///
171
+ /// Function that creates and returns a new burner resource
172
+ ///
173
+ access(all) fun createNewBurner(): @Burner {
174
+ emit BurnerCreated()
175
+ return <-create Burner()
176
+ }
177
+ }
178
+
179
+ /// Minter
180
+ ///
181
+ /// Resource object that token admin accounts can hold to mint new tokens.
182
+ ///
183
+ access(all) resource Minter {
184
+
185
+ /// The amount of tokens that the minter is allowed to mint
186
+ access(all) var allowedAmount: UFix64
187
+
188
+ /// mintTokens
189
+ ///
190
+ /// Function that mints new tokens, adds them to the total supply,
191
+ /// and returns them to the calling context.
192
+ ///
193
+ access(all) fun mintTokens(amount: UFix64): @ExampleToken.Vault {
194
+ pre {
195
+ amount > 0.0: "Amount minted must be greater than zero"
196
+ amount <= self.allowedAmount: "Amount minted must be less than the allowed amount"
197
+ }
198
+ ExampleToken.totalSupply = ExampleToken.totalSupply + amount
199
+ self.allowedAmount = self.allowedAmount - amount
200
+ emit TokensMinted(amount: amount)
201
+ return <-create Vault(balance: amount)
202
+ }
203
+
204
+ init(allowedAmount: UFix64) {
205
+ self.allowedAmount = allowedAmount
206
+ }
207
+ }
208
+
209
+ /// Burner
210
+ ///
211
+ /// Resource object that token admin accounts can hold to burn tokens.
212
+ ///
213
+ access(all) resource Burner {
214
+
215
+ /// burnTokens
216
+ ///
217
+ /// Function that destroys a Vault instance, effectively burning the tokens.
218
+ ///
219
+ /// Note: the burned tokens are automatically subtracted from the
220
+ /// total supply in the Vault destructor.
221
+ ///
222
+ access(all) fun burnTokens(from: @{FungibleToken.Vault}) {
223
+ let vault <- from as! @ExampleToken.Vault
224
+ let amount = vault.balance
225
+ destroy vault
226
+ emit TokensBurned(amount: amount)
227
+ }
228
+ }
229
+
230
+ access(all) view fun getContractViews(resourceType: Type?): [Type] {
231
+ return [Type<FungibleTokenMetadataViews.FTView>(),
232
+ Type<FungibleTokenMetadataViews.FTDisplay>(),
233
+ Type<FungibleTokenMetadataViews.FTVaultData>(),
234
+ Type<FungibleTokenMetadataViews.TotalSupply>()]
235
+ }
236
+
237
+ access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
238
+ switch viewType {
239
+ case Type<FungibleTokenMetadataViews.FTView>():
240
+ return FungibleTokenMetadataViews.FTView(
241
+ ftDisplay: self.resolveContractView(resourceType: nil, viewType: Type<FungibleTokenMetadataViews.FTDisplay>()) as! FungibleTokenMetadataViews.FTDisplay?,
242
+ ftVaultData: self.resolveContractView(resourceType: nil, viewType: Type<FungibleTokenMetadataViews.FTVaultData>()) as! FungibleTokenMetadataViews.FTVaultData?
243
+ )
244
+ case Type<FungibleTokenMetadataViews.FTDisplay>():
245
+ let media = MetadataViews.Media(
246
+ file: MetadataViews.HTTPFile(
247
+ url: "https://example.com"
248
+ ),
249
+ mediaType: "image/svg+xml"
250
+ )
251
+ let medias = MetadataViews.Medias([media])
252
+ return FungibleTokenMetadataViews.FTDisplay(
253
+ name: "Example Token",
254
+ symbol: "EXAMPLE",
255
+ description: "",
256
+ externalURL: MetadataViews.ExternalURL("https://flow.com"),
257
+ logos: medias,
258
+ socials: {
259
+ "twitter": MetadataViews.ExternalURL("https://twitter.com/flow_blockchain")
260
+ }
261
+ )
262
+ case Type<FungibleTokenMetadataViews.FTVaultData>():
263
+ let vaultRef = ExampleToken.account.storage.borrow<auth(FungibleToken.Withdraw) &ExampleToken.Vault>(from: /storage/exampleTokenVault)
264
+ ?? panic("Could not borrow reference to the contract's Vault!")
265
+ return FungibleTokenMetadataViews.FTVaultData(
266
+ storagePath: /storage/exampleTokenVault,
267
+ receiverPath: /public/exampleTokenReceiver,
268
+ metadataPath: /public/exampleTokenBalance,
269
+ receiverLinkedType: Type<&{FungibleToken.Receiver, FungibleToken.Vault}>(),
270
+ metadataLinkedType: Type<&{FungibleToken.Balance, FungibleToken.Vault}>(),
271
+ createEmptyVaultFunction: (fun (): @{FungibleToken.Vault} {
272
+ return <-vaultRef.createEmptyVault()
273
+ })
274
+ )
275
+ case Type<FungibleTokenMetadataViews.TotalSupply>():
276
+ return FungibleTokenMetadataViews.TotalSupply(totalSupply: ExampleToken.totalSupply)
277
+ }
278
+ return nil
279
+ }
280
+
281
+ init() {
282
+ self.totalSupply = 1000.0
283
+
284
+ // Create the Vault with the total supply of tokens and save it in storage
285
+ //
286
+ let vault <- create Vault(balance: self.totalSupply)
287
+ self.account.storage.save(<-vault, to: /storage/exampleTokenVault)
288
+
289
+ // Create a public capability to the stored Vault that only exposes
290
+ // the `deposit` method through the `Receiver` interface
291
+ //
292
+ let publicCap = self.account.capabilities.storage.issue<&ExampleToken.Vault>(/storage/exampleTokenVault)
293
+ self.account.capabilities.publish(publicCap, at: /public/exampleTokenPublic)
294
+
295
+ let admin <- create Administrator()
296
+ self.account.storage.save(<-admin, to: /storage/exampleTokenAdmin)
297
+
298
+ // Emit an event that shows that the contract was initialized
299
+ //
300
+ emit TokensInitialized(initialSupply: self.totalSupply)
301
+ }
302
+ }
@@ -1,8 +1,5 @@
1
- import "StringUtils"
2
-
3
- pub contract AddressUtils {
4
-
5
- pub fun withoutPrefix(_ input: String): String {
1
+ access(all) contract AddressUtils {
2
+ access(all) fun withoutPrefix(_ input: String): String {
6
3
  var address = input
7
4
 
8
5
  // get rid of 0x
@@ -17,7 +14,7 @@ pub contract AddressUtils {
17
14
  return address
18
15
  }
19
16
 
20
- pub fun parseUInt64(_ input: AnyStruct): UInt64? {
17
+ access(all) fun parseUInt64(_ input: AnyStruct): UInt64? {
21
18
  var stringValue = ""
22
19
 
23
20
  if let string = input as? String {
@@ -25,7 +22,7 @@ pub contract AddressUtils {
25
22
  } else if let address = input as? Address {
26
23
  stringValue = address.toString()
27
24
  } else if let type = input as? Type {
28
- let parts = StringUtils.split(type.identifier, ".")
25
+ let parts = type.identifier.split(separator: ".")
29
26
  if parts.length == 1 {
30
27
  return nil
31
28
  }
@@ -45,14 +42,14 @@ pub contract AddressUtils {
45
42
  return r
46
43
  }
47
44
 
48
- pub fun parseAddress(_ input: AnyStruct): Address? {
45
+ access(all) fun parseAddress(_ input: AnyStruct): Address? {
49
46
  if let parsed = self.parseUInt64(input) {
50
47
  return Address(parsed)
51
48
  }
52
49
  return nil
53
50
  }
54
51
 
55
- pub fun isValidAddress(_ input: AnyStruct, forNetwork: String): Bool {
52
+ access(all) fun isValidAddress(_ input: AnyStruct, forNetwork: String): Bool {
56
53
  let address = self.parseUInt64(input)
57
54
  if address == nil {
58
55
  return false
@@ -61,18 +58,19 @@ pub contract AddressUtils {
61
58
  let codeWords: {String: UInt64} = {
62
59
  "MAINNET" : 0,
63
60
  "TESTNET" : 0x6834ba37b3980209,
61
+ "CRESCENDO" : 0x6834ba37b3980209,
64
62
  "EMULATOR": 0x1cb159857af02018
65
63
  }
66
64
 
67
65
  let parityCheckMatrixColumns: [UInt64] = [
68
- 0x00001, 0x00002, 0x00004, 0x00008, 0x00010, 0x00020, 0x00040, 0x00080,
69
- 0x00100, 0x00200, 0x00400, 0x00800, 0x01000, 0x02000, 0x04000, 0x08000,
70
- 0x10000, 0x20000, 0x40000, 0x7328d, 0x6689a, 0x6112f, 0x6084b, 0x433fd,
71
- 0x42aab, 0x41951, 0x233ce, 0x22a81, 0x21948, 0x1ef60, 0x1deca, 0x1c639,
72
- 0x1bdd8, 0x1a535, 0x194ac, 0x18c46, 0x1632b, 0x1529b, 0x14a43, 0x13184,
73
- 0x12942, 0x118c1, 0x0f812, 0x0e027, 0x0d00e, 0x0c83c, 0x0b01d, 0x0a831,
74
- 0x0982b, 0x07034, 0x0682a, 0x05819, 0x03807, 0x007d2, 0x00727, 0x0068e,
75
- 0x0067c, 0x0059d, 0x004eb, 0x003b4, 0x0036a, 0x002d9, 0x001c7, 0x0003f
66
+ 0x00001, 0x00002, 0x00004, 0x00008, 0x00010, 0x00020, 0x00040, 0x00080,
67
+ 0x00100, 0x00200, 0x00400, 0x00800, 0x01000, 0x02000, 0x04000, 0x08000,
68
+ 0x10000, 0x20000, 0x40000, 0x7328d, 0x6689a, 0x6112f, 0x6084b, 0x433fd,
69
+ 0x42aab, 0x41951, 0x233ce, 0x22a81, 0x21948, 0x1ef60, 0x1deca, 0x1c639,
70
+ 0x1bdd8, 0x1a535, 0x194ac, 0x18c46, 0x1632b, 0x1529b, 0x14a43, 0x13184,
71
+ 0x12942, 0x118c1, 0x0f812, 0x0e027, 0x0d00e, 0x0c83c, 0x0b01d, 0x0a831,
72
+ 0x0982b, 0x07034, 0x0682a, 0x05819, 0x03807, 0x007d2, 0x00727, 0x0068e,
73
+ 0x0067c, 0x0059d, 0x004eb, 0x003b4, 0x0036a, 0x002d9, 0x001c7, 0x0003f
76
74
  ]
77
75
 
78
76
  var parity: UInt64 = 0
@@ -93,8 +91,8 @@ pub contract AddressUtils {
93
91
  return parity == 0 && codeWord == 0
94
92
  }
95
93
 
96
- pub fun getNetworkFromAddress(_ input: AnyStruct): String? {
97
- for network in ["MAINNET", "TESTNET", "EMULATOR"]{
94
+ access(all) fun getNetworkFromAddress(_ input: AnyStruct): String? {
95
+ for network in ["MAINNET", "TESTNET", "EMULATOR"] {
98
96
  if self.isValidAddress(input, forNetwork: network){
99
97
  return network
100
98
  }
@@ -102,8 +100,7 @@ pub contract AddressUtils {
102
100
  return nil
103
101
  }
104
102
 
105
- pub fun currentNetwork(): String {
106
- return self.getNetworkFromAddress(self.account.address)!
103
+ access(all) fun currentNetwork(): String {
104
+ return self.getNetworkFromAddress(self.account.address) ?? panic("unknown network!")
107
105
  }
108
-
109
- }
106
+ }
@@ -1,8 +1,7 @@
1
1
  // Copied from https://github.com/bluesign/flow-utils/blob/dnz/cadence/contracts/ArrayUtils.cdc with minor adjustments
2
2
 
3
- pub contract ArrayUtils {
4
-
5
- pub fun rangeFunc(_ start: Int, _ end: Int, _ f: ((Int): Void)) {
3
+ access(all) contract ArrayUtils {
4
+ access(all) fun rangeFunc(_ start: Int, _ end: Int, _ f: fun (Int): Void) {
6
5
  var current = start
7
6
  while current < end {
8
7
  f(current)
@@ -10,7 +9,7 @@ pub contract ArrayUtils {
10
9
  }
11
10
  }
12
11
 
13
- pub fun range(_ start: Int, _ end: Int): [Int] {
12
+ access(all) fun range(_ start: Int, _ end: Int): [Int] {
14
13
  var res: [Int] = []
15
14
  self.rangeFunc(start, end, fun (i: Int) {
16
15
  res.append(i)
@@ -18,7 +17,7 @@ pub contract ArrayUtils {
18
17
  return res
19
18
  }
20
19
 
21
- pub fun reverse(_ array: [Int]): [Int] {
20
+ access(all) fun reverse(_ array: [Int]): [Int] {
22
21
  var res: [Int] = []
23
22
  var i: Int = array.length - 1
24
23
  while i >= 0 {
@@ -28,13 +27,13 @@ pub contract ArrayUtils {
28
27
  return res
29
28
  }
30
29
 
31
- pub fun transform(_ array: &[AnyStruct], _ f : ((AnyStruct): AnyStruct)){
30
+ access(all) fun transform(_ array: auth(Mutate) &[AnyStruct], _ f : fun (&AnyStruct, auth(Mutate) &[AnyStruct], Int)){
32
31
  for i in self.range(0, array.length){
33
- array[i] = f(array[i])
32
+ f(array[i], array, i)
34
33
  }
35
34
  }
36
35
 
37
- pub fun iterate(_ array: [AnyStruct], _ f : ((AnyStruct): Bool)){
36
+ access(all) fun iterate(_ array: [AnyStruct], _ f : fun (AnyStruct): Bool) {
38
37
  for item in array{
39
38
  if !f(item){
40
39
  break
@@ -42,7 +41,7 @@ pub contract ArrayUtils {
42
41
  }
43
42
  }
44
43
 
45
- pub fun map(_ array: [AnyStruct], _ f : ((AnyStruct): AnyStruct)) : [AnyStruct] {
44
+ access(all) fun map(_ array: [AnyStruct], _ f : fun (AnyStruct): AnyStruct) : [AnyStruct] {
46
45
  var res : [AnyStruct] = []
47
46
  for item in array{
48
47
  res.append(f(item))
@@ -50,7 +49,7 @@ pub contract ArrayUtils {
50
49
  return res
51
50
  }
52
51
 
53
- pub fun mapStrings(_ array: [String], _ f: ((String) : String) ) : [String] {
52
+ access(all) fun mapStrings(_ array: [String], _ f: fun (String) : String) : [String] {
54
53
  var res : [String] = []
55
54
  for item in array{
56
55
  res.append(f(item))
@@ -58,7 +57,7 @@ pub contract ArrayUtils {
58
57
  return res
59
58
  }
60
59
 
61
- pub fun reduce(_ array: [AnyStruct], _ initial: AnyStruct, _ f : ((AnyStruct, AnyStruct): AnyStruct)) : AnyStruct{
60
+ access(all) fun reduce(_ array: [AnyStruct], _ initial: AnyStruct, _ f : fun (AnyStruct, AnyStruct): AnyStruct) : AnyStruct{
62
61
  var res: AnyStruct = f(initial, array[0])
63
62
  for i in self.range(1, array.length){
64
63
  res = f(res, array[i])
@@ -8,14 +8,14 @@ import "StringUtils"
8
8
  //
9
9
  // ScopedProviders are meant to solve the issue of unbounded access FungibleToken vaults
10
10
  // when a provider is called for.
11
- pub contract ScopedFTProviders {
12
- pub struct interface FTFilter {
13
- pub fun canWithdrawAmount(_ amount: UFix64): Bool
14
- pub fun markAmountWithdrawn(_ amount: UFix64)
15
- pub fun getDetails(): {String: AnyStruct}
11
+ access(all) contract ScopedFTProviders {
12
+ access(all) struct interface FTFilter {
13
+ access(all) view fun canWithdrawAmount(_ amount: UFix64): Bool
14
+ access(FungibleToken.Withdraw) fun markAmountWithdrawn(_ amount: UFix64)
15
+ access(all) fun getDetails(): {String: AnyStruct}
16
16
  }
17
17
 
18
- pub struct AllowanceFilter: FTFilter {
18
+ access(all) struct AllowanceFilter: FTFilter {
19
19
  access(self) let allowance: UFix64
20
20
  access(self) var allowanceUsed: UFix64
21
21
 
@@ -24,15 +24,15 @@ pub contract ScopedFTProviders {
24
24
  self.allowanceUsed = 0.0
25
25
  }
26
26
 
27
- pub fun canWithdrawAmount(_ amount: UFix64): Bool {
27
+ access(all) view fun canWithdrawAmount(_ amount: UFix64): Bool {
28
28
  return amount + self.allowanceUsed <= self.allowance
29
29
  }
30
30
 
31
- pub fun markAmountWithdrawn(_ amount: UFix64) {
31
+ access(FungibleToken.Withdraw) fun markAmountWithdrawn(_ amount: UFix64) {
32
32
  self.allowanceUsed = self.allowanceUsed + amount
33
33
  }
34
34
 
35
- pub fun getDetails(): {String: AnyStruct} {
35
+ access(all) fun getDetails(): {String: AnyStruct} {
36
36
  return {
37
37
  "allowance": self.allowance,
38
38
  "allowanceUsed": self.allowanceUsed
@@ -44,31 +44,31 @@ pub contract ScopedFTProviders {
44
44
  //
45
45
  // A ScopedFTProvider is a wrapped FungibleTokenProvider with
46
46
  // filters that can be defined by anyone using the ScopedFTProvider.
47
- pub resource ScopedFTProvider: FungibleToken.Provider {
48
- access(self) let provider: Capability<&{FungibleToken.Provider}>
47
+ access(all) resource ScopedFTProvider: FungibleToken.Provider {
48
+ access(self) let provider: Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>
49
49
  access(self) var filters: [{FTFilter}]
50
50
 
51
51
  // block timestamp that this provider can no longer be used after
52
52
  access(self) let expiration: UFix64?
53
53
 
54
- pub init(provider: Capability<&{FungibleToken.Provider}>, filters: [{FTFilter}], expiration: UFix64?) {
54
+ access(all) init(provider: Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>, filters: [{FTFilter}], expiration: UFix64?) {
55
55
  self.provider = provider
56
56
  self.filters = filters
57
57
  self.expiration = expiration
58
58
  }
59
59
 
60
- pub fun check(): Bool {
60
+ access(all) fun check(): Bool {
61
61
  return self.provider.check()
62
62
  }
63
63
 
64
- pub fun isExpired(): Bool {
64
+ access(all) view fun isExpired(): Bool {
65
65
  if let expiration = self.expiration {
66
66
  return getCurrentBlock().timestamp >= expiration
67
67
  }
68
68
  return false
69
69
  }
70
70
 
71
- pub fun canWithdraw(_ amount: UFix64): Bool {
71
+ access(all) view fun canWithdraw(_ amount: UFix64): Bool {
72
72
  if self.isExpired() {
73
73
  return false
74
74
  }
@@ -82,7 +82,11 @@ pub contract ScopedFTProviders {
82
82
  return true
83
83
  }
84
84
 
85
- pub fun withdraw(amount: UFix64): @FungibleToken.Vault {
85
+ access(all) view fun isAvailableToWithdraw(amount: UFix64): Bool {
86
+ return self.canWithdraw(amount)
87
+ }
88
+
89
+ access(FungibleToken.Withdraw | FungibleToken.Withdraw) fun withdraw(amount: UFix64): @{FungibleToken.Vault} {
86
90
  pre {
87
91
  !self.isExpired(): "provider has expired"
88
92
  }
@@ -100,7 +104,7 @@ pub contract ScopedFTProviders {
100
104
  return <-self.provider.borrow()!.withdraw(amount: amount)
101
105
  }
102
106
 
103
- pub fun getDetails(): [{String: AnyStruct}] {
107
+ access(all) fun getDetails(): [{String: AnyStruct}] {
104
108
  let details: [{String: AnyStruct}] = []
105
109
  for filter in self.filters {
106
110
  details.append(filter.getDetails())
@@ -110,11 +114,12 @@ pub contract ScopedFTProviders {
110
114
  }
111
115
  }
112
116
 
113
- pub fun createScopedFTProvider(
114
- provider: Capability<&{FungibleToken.Provider}>,
117
+ access(all) fun createScopedFTProvider(
118
+ provider: Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>,
115
119
  filters: [{FTFilter}],
116
120
  expiration: UFix64?
117
121
  ): @ScopedFTProvider {
118
122
  return <- create ScopedFTProvider(provider: provider, filters: filters, expiration: expiration)
119
123
  }
120
124
  }
125
+