@flowtyio/flow-contracts 0.1.0-beta.3 → 0.1.0-beta.30
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.
- package/README.md +1 -1
- package/contracts/Burner.cdc +44 -0
- package/contracts/FlowStorageFees.cdc +15 -15
- package/contracts/FlowToken.cdc +29 -78
- package/contracts/FungibleToken.cdc +80 -53
- package/contracts/FungibleTokenMetadataViews.cdc +13 -25
- package/contracts/FungibleTokenSwitchboard.cdc +360 -0
- package/contracts/MetadataViews.cdc +107 -50
- package/contracts/NonFungibleToken.cdc +110 -60
- package/contracts/TokenForwarding.cdc +19 -11
- package/contracts/ViewResolver.cdc +20 -16
- package/contracts/capability-cache/CapabilityCache.cdc +97 -0
- package/contracts/dapper/DapperUtilityCoin.cdc +106 -39
- package/contracts/dapper/FlowUtilityToken.cdc +107 -40
- package/contracts/dapper/TopShot.cdc +323 -259
- package/contracts/dapper/TopShotLocking.cdc +41 -15
- package/contracts/dapper/offers/DapperOffersV2.cdc +46 -43
- package/contracts/dapper/offers/OffersV2.cdc +40 -56
- package/contracts/dapper/offers/Resolver.cdc +20 -13
- package/contracts/emerald-city/FLOAT.cdc +259 -254
- package/contracts/example/ExampleNFT.cdc +18 -21
- package/contracts/example/ExampleToken.cdc +68 -1
- package/contracts/find/FindViews.cdc +357 -353
- package/contracts/flow-utils/AddressUtils.cdc +20 -23
- package/contracts/flow-utils/ArrayUtils.cdc +10 -11
- package/contracts/flow-utils/ScopedFTProviders.cdc +27 -19
- package/contracts/flow-utils/ScopedNFTProviders.cdc +31 -26
- package/contracts/flow-utils/StringUtils.cdc +24 -37
- package/contracts/flowty-drops/ContractManager.cdc +47 -0
- package/contracts/flowty-drops/DropFactory.cdc +75 -0
- package/contracts/flowty-drops/DropTypes.cdc +278 -0
- package/contracts/flowty-drops/FlowtyAddressVerifiers.cdc +64 -0
- package/contracts/flowty-drops/FlowtyDrops.cdc +431 -0
- package/contracts/flowty-drops/FlowtyPricers.cdc +48 -0
- package/contracts/flowty-drops/FlowtySwitchers.cdc +113 -0
- package/contracts/flowty-drops/initializers/ContractBorrower.cdc +14 -0
- package/contracts/flowty-drops/initializers/ContractInitializer.cdc +7 -0
- package/contracts/flowty-drops/initializers/OpenEditionInitializer.cdc +58 -0
- package/contracts/flowty-drops/nft/BaseCollection.cdc +97 -0
- package/contracts/flowty-drops/nft/BaseNFT.cdc +107 -0
- package/contracts/flowty-drops/nft/ContractFactory.cdc +13 -0
- package/contracts/flowty-drops/nft/ContractFactoryTemplate.cdc +48 -0
- package/contracts/flowty-drops/nft/NFTMetadata.cdc +119 -0
- package/contracts/flowty-drops/nft/OpenEditionNFT.cdc +41 -0
- package/contracts/flowty-drops/nft/OpenEditionTemplate.cdc +52 -0
- package/contracts/flowty-drops/nft/UniversalCollection.cdc +23 -0
- package/contracts/fungible-token-router/FungibleTokenRouter.cdc +105 -0
- package/contracts/hybrid-custody/CapabilityDelegator.cdc +28 -26
- package/contracts/hybrid-custody/CapabilityFactory.cdc +20 -18
- package/contracts/hybrid-custody/CapabilityFilter.cdc +41 -24
- package/contracts/hybrid-custody/HybridCustody.cdc +303 -242
- package/contracts/hybrid-custody/factories/FTAllFactory.cdc +16 -4
- package/contracts/hybrid-custody/factories/FTBalanceFactory.cdc +16 -4
- package/contracts/hybrid-custody/factories/FTProviderFactory.cdc +17 -5
- package/contracts/hybrid-custody/factories/FTReceiverBalanceFactory.cdc +16 -4
- package/contracts/hybrid-custody/factories/FTReceiverFactory.cdc +16 -4
- package/contracts/hybrid-custody/factories/FTVaultFactory.cdc +46 -0
- package/contracts/hybrid-custody/factories/NFTCollectionFactory.cdc +45 -0
- package/contracts/hybrid-custody/factories/NFTCollectionPublicFactory.cdc +16 -4
- package/contracts/hybrid-custody/factories/NFTProviderAndCollectionFactory.cdc +22 -0
- package/contracts/hybrid-custody/factories/NFTProviderFactory.cdc +16 -4
- package/contracts/lost-and-found/LostAndFound.cdc +29 -25
- package/contracts/nft-catalog/NFTCatalog.cdc +60 -64
- package/contracts/nft-catalog/NFTCatalogAdmin.cdc +28 -27
- package/flow.json +189 -5
- package/package.json +1 -1
- package/contracts/hybrid-custody/factories/NFTProviderAndCollectionPublicFactory.cdc +0 -10
|
@@ -16,29 +16,37 @@ their tokens to.
|
|
|
16
16
|
|
|
17
17
|
import "FungibleToken"
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
access(all) contract TokenForwarding {
|
|
20
20
|
|
|
21
21
|
// Event that is emitted when tokens are deposited to the target receiver
|
|
22
|
-
|
|
22
|
+
access(all) event ForwardedDeposit(amount: UFix64, from: Address?)
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
access(all) resource interface ForwarderPublic {
|
|
25
|
+
access(all) fun check(): Bool
|
|
26
|
+
access(all) fun safeBorrow(): &{FungibleToken.Receiver}?
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
access(all) resource Forwarder: FungibleToken.Receiver, ForwarderPublic {
|
|
30
30
|
|
|
31
31
|
// This is where the deposited tokens will be sent.
|
|
32
32
|
// The type indicates that it is a reference to a receiver
|
|
33
33
|
//
|
|
34
34
|
access(self) var recipient: Capability
|
|
35
35
|
|
|
36
|
+
access(all) view fun getSupportedVaultTypes(): {Type: Bool} {
|
|
37
|
+
return {}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
access(all) view fun isSupportedVaultType(type: Type): Bool {
|
|
41
|
+
return true
|
|
42
|
+
}
|
|
43
|
+
|
|
36
44
|
// deposit
|
|
37
45
|
//
|
|
38
46
|
// Function that takes a Vault object as an argument and forwards
|
|
39
47
|
// it to the recipient's Vault using the stored reference
|
|
40
48
|
//
|
|
41
|
-
|
|
49
|
+
access(all) fun deposit(from: @{FungibleToken.Vault}) {
|
|
42
50
|
let receiverRef = self.recipient.borrow<&{FungibleToken.Receiver}>()!
|
|
43
51
|
|
|
44
52
|
let balance = from.balance
|
|
@@ -48,17 +56,17 @@ pub contract TokenForwarding {
|
|
|
48
56
|
emit ForwardedDeposit(amount: balance, from: self.owner?.address)
|
|
49
57
|
}
|
|
50
58
|
|
|
51
|
-
|
|
59
|
+
access(all) fun check(): Bool {
|
|
52
60
|
return self.recipient.check<&{FungibleToken.Receiver}>()
|
|
53
61
|
}
|
|
54
62
|
|
|
55
|
-
|
|
63
|
+
access(all) fun safeBorrow(): &{FungibleToken.Receiver}? {
|
|
56
64
|
return self.recipient.borrow<&{FungibleToken.Receiver}>()
|
|
57
65
|
}
|
|
58
66
|
|
|
59
67
|
// changeRecipient changes the recipient of the forwarder to the provided recipient
|
|
60
68
|
//
|
|
61
|
-
|
|
69
|
+
access(all) fun changeRecipient(_ newRecipient: Capability) {
|
|
62
70
|
pre {
|
|
63
71
|
newRecipient.borrow<&{FungibleToken.Receiver}>() != nil: "Could not borrow Receiver reference from the Capability"
|
|
64
72
|
}
|
|
@@ -75,7 +83,7 @@ pub contract TokenForwarding {
|
|
|
75
83
|
|
|
76
84
|
// createNewForwarder creates a new Forwarder reference with the provided recipient
|
|
77
85
|
//
|
|
78
|
-
|
|
86
|
+
access(all) fun createNewForwarder(recipient: Capability): @Forwarder {
|
|
79
87
|
return <-create Forwarder(recipient: recipient)
|
|
80
88
|
}
|
|
81
89
|
}
|
|
@@ -1,43 +1,47 @@
|
|
|
1
|
-
// Taken from the NFT Metadata standard, this contract exposes an interface to let
|
|
1
|
+
// Taken from the NFT Metadata standard, this contract exposes an interface to let
|
|
2
2
|
// anyone borrow a contract and resolve views on it.
|
|
3
3
|
//
|
|
4
4
|
// This will allow you to obtain information about a contract without necessarily knowing anything about it.
|
|
5
5
|
// All you need is its address and name and you're good to go!
|
|
6
6
|
access(all) contract interface ViewResolver {
|
|
7
7
|
|
|
8
|
-
/// Function that returns all the Metadata Views implemented by the resolving contract
|
|
8
|
+
/// Function that returns all the Metadata Views implemented by the resolving contract.
|
|
9
|
+
/// Some contracts may have multiple resource types that support metadata views
|
|
10
|
+
/// so there there is an optional parameter for specify which resource type the caller
|
|
11
|
+
/// is looking for views for.
|
|
12
|
+
/// Some contract-level views may be type-agnostic. In that case, the contract
|
|
13
|
+
/// should return the same views regardless of what type is passed in.
|
|
9
14
|
///
|
|
15
|
+
/// @param resourceType: An optional resource type to return views for
|
|
10
16
|
/// @return An array of Types defining the implemented views. This value will be used by
|
|
11
17
|
/// developers to know which parameter to pass to the resolveView() method.
|
|
12
18
|
///
|
|
13
|
-
access(all) view fun
|
|
14
|
-
return []
|
|
15
|
-
}
|
|
19
|
+
access(all) view fun getContractViews(resourceType: Type?): [Type]
|
|
16
20
|
|
|
17
21
|
/// Function that resolves a metadata view for this token.
|
|
22
|
+
/// Some contracts may have multiple resource types that support metadata views
|
|
23
|
+
/// so there there is an optional parameter for specify which resource type the caller
|
|
24
|
+
/// is looking for views for.
|
|
25
|
+
/// Some contract-level views may be type-agnostic. In that case, the contract
|
|
26
|
+
/// should return the same views regardless of what type is passed in.
|
|
18
27
|
///
|
|
28
|
+
/// @param resourceType: An optional resource type to return views for
|
|
19
29
|
/// @param view: The Type of the desired view.
|
|
20
30
|
/// @return A structure representing the requested view.
|
|
21
31
|
///
|
|
22
|
-
access(all) fun
|
|
23
|
-
return nil
|
|
24
|
-
}
|
|
32
|
+
access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct?
|
|
25
33
|
|
|
26
|
-
/// Provides access to a set of metadata views. A struct or
|
|
27
|
-
/// resource (e.g. an NFT) can implement this interface to provide access to
|
|
34
|
+
/// Provides access to a set of metadata views. A struct or
|
|
35
|
+
/// resource (e.g. an NFT) can implement this interface to provide access to
|
|
28
36
|
/// the views that it supports.
|
|
29
37
|
///
|
|
30
38
|
access(all) resource interface Resolver {
|
|
31
39
|
|
|
32
40
|
/// Same as getViews above, but on a specific NFT instead of a contract
|
|
33
|
-
access(all) view fun getViews(): [Type]
|
|
34
|
-
return []
|
|
35
|
-
}
|
|
41
|
+
access(all) view fun getViews(): [Type]
|
|
36
42
|
|
|
37
43
|
/// Same as resolveView above, but on a specific NFT instead of a contract
|
|
38
|
-
access(all) fun resolveView(_ view: Type): AnyStruct?
|
|
39
|
-
return nil
|
|
40
|
-
}
|
|
44
|
+
access(all) fun resolveView(_ view: Type): AnyStruct?
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
/// A group of view resolvers indexed by ID.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/*
|
|
2
|
+
https://github.com/Flowtyio/capability-cache
|
|
3
|
+
|
|
4
|
+
CapabilityCache helps manage capabilities which are issued but are not in public paths.
|
|
5
|
+
Rather than looping through all capabilities under a storage path and finding one that
|
|
6
|
+
matches the Capability type you want, the cache can be used to retrieve them
|
|
7
|
+
*/
|
|
8
|
+
access(all) contract CapabilityCache {
|
|
9
|
+
|
|
10
|
+
access(all) let basePathIdentifier: String
|
|
11
|
+
|
|
12
|
+
access(all) event CapabilityAdded(owner: Address?, cacheUuid: UInt64, namespace: String, resourceType: Type, capabilityType: Type, capabilityID: UInt64)
|
|
13
|
+
access(all) event CapabilityRemoved(owner: Address?, cacheUuid: UInt64, namespace: String, resourceType: Type, capabilityType: Type, capabilityID: UInt64)
|
|
14
|
+
|
|
15
|
+
// Add to a namespace
|
|
16
|
+
access(all) entitlement Add
|
|
17
|
+
|
|
18
|
+
// Remove from a namespace
|
|
19
|
+
access(all) entitlement Delete
|
|
20
|
+
|
|
21
|
+
// Retrieve a cap from the namespace
|
|
22
|
+
access(all) entitlement Get
|
|
23
|
+
|
|
24
|
+
// Resource that manages capabilities for a provided namespace. Only one capability is permitted per type.
|
|
25
|
+
access(all) resource Cache {
|
|
26
|
+
// A dictionary of resourceType -> CapabilityType -> Capability
|
|
27
|
+
// For example, one might store a Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Collection}> for the @TopShot.NFT resource.
|
|
28
|
+
// Note that the resource type is not necessarily the type that the borrowed capability is an instance of. This is because some resource definitions
|
|
29
|
+
// might be reused.
|
|
30
|
+
access(self) let caps: {Type: {Type: Capability}}
|
|
31
|
+
|
|
32
|
+
// who is this capability cache maintained by? e.g. flowty, dapper, find?
|
|
33
|
+
access(all) let namespace: String
|
|
34
|
+
|
|
35
|
+
// Remove a capability, if it exists,
|
|
36
|
+
access(Delete) fun removeCapabilityByType(resourceType: Type, capabilityType: Type): Capability? {
|
|
37
|
+
if let ref = &self.caps[resourceType] as auth(Mutate) &{Type: Capability}? {
|
|
38
|
+
let cap = ref.remove(key: capabilityType)
|
|
39
|
+
if cap != nil {
|
|
40
|
+
emit CapabilityRemoved(owner: self.owner?.address, cacheUuid: self.uuid, namespace: self.namespace, resourceType: resourceType, capabilityType: capabilityType, capabilityID: cap!.id)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return nil
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Adds a capability to the cache. If there is already an entry for the given type,
|
|
48
|
+
// it will be returned
|
|
49
|
+
access(Add) fun addCapability(resourceType: Type, cap: Capability): Capability? {
|
|
50
|
+
pre {
|
|
51
|
+
cap.id != 0: "cannot add a capability with id 0"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let capType = cap.getType()
|
|
55
|
+
emit CapabilityAdded(owner: self.owner?.address, cacheUuid: self.uuid, namespace: self.namespace, resourceType: resourceType, capabilityType: capType, capabilityID: cap.id)
|
|
56
|
+
if let ref = &self.caps[resourceType] as auth(Mutate) &{Type: Capability}? {
|
|
57
|
+
return ref.insert(key: capType, cap)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
self.caps[resourceType] = {
|
|
61
|
+
capType: cap
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return nil
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Retrieve a capability key'd by a given type.
|
|
68
|
+
access(Get) fun getCapabilityByType(resourceType: Type, capabilityType: Type): Capability? {
|
|
69
|
+
if let tmp = self.caps[resourceType] {
|
|
70
|
+
return tmp[capabilityType]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return nil
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
init(namespace: String) {
|
|
77
|
+
self.caps = {}
|
|
78
|
+
|
|
79
|
+
self.namespace = namespace
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// There is no uniform storage path for the Capability Cache. Instead, each platform which issues capabilities
|
|
84
|
+
// should manage their own cache, and can generate the storage path to store it in with this helper method
|
|
85
|
+
access(all) fun getPathForCache(_ namespace: String): StoragePath {
|
|
86
|
+
return StoragePath(identifier: self.basePathIdentifier.concat(namespace))
|
|
87
|
+
?? panic("invalid namespace value")
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
access(all) fun createCache(namespace: String): @Cache {
|
|
91
|
+
return <- create Cache(namespace: namespace)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
init() {
|
|
95
|
+
self.basePathIdentifier = "CapabilityCache_".concat(self.account.address.toString()).concat("_")
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
import "FungibleToken"
|
|
2
|
+
import "MetadataViews"
|
|
3
|
+
import "FungibleTokenMetadataViews"
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
access(all) contract DapperUtilityCoin: FungibleToken {
|
|
4
6
|
|
|
5
7
|
// Total supply of DapperUtilityCoins in existence
|
|
6
|
-
|
|
8
|
+
access(all) var totalSupply: UFix64
|
|
7
9
|
|
|
8
10
|
// Event that is emitted when the contract is created
|
|
9
|
-
|
|
11
|
+
access(all) event TokensInitialized(initialSupply: UFix64)
|
|
10
12
|
|
|
11
13
|
// Event that is emitted when tokens are withdrawn from a Vault
|
|
12
|
-
|
|
14
|
+
access(all) event TokensWithdrawn(amount: UFix64, from: Address?)
|
|
13
15
|
|
|
14
16
|
// Event that is emitted when tokens are deposited to a Vault
|
|
15
|
-
|
|
17
|
+
access(all) event TokensDeposited(amount: UFix64, to: Address?)
|
|
16
18
|
|
|
17
19
|
// Event that is emitted when new tokens are minted
|
|
18
|
-
|
|
20
|
+
access(all) event TokensMinted(amount: UFix64)
|
|
19
21
|
|
|
20
22
|
// Event that is emitted when tokens are destroyed
|
|
21
|
-
|
|
23
|
+
access(all) event TokensBurned(amount: UFix64)
|
|
22
24
|
|
|
23
25
|
// Event that is emitted when a new minter resource is created
|
|
24
|
-
|
|
26
|
+
access(all) event MinterCreated(allowedAmount: UFix64)
|
|
25
27
|
|
|
26
28
|
// Event that is emitted when a new burner resource is created
|
|
27
|
-
|
|
29
|
+
access(all) event BurnerCreated()
|
|
28
30
|
|
|
29
31
|
// Vault
|
|
30
32
|
//
|
|
@@ -38,10 +40,10 @@ pub contract DapperUtilityCoin: FungibleToken {
|
|
|
38
40
|
// out of thin air. A special Minter resource needs to be defined to mint
|
|
39
41
|
// new tokens.
|
|
40
42
|
//
|
|
41
|
-
|
|
43
|
+
access(all) resource Vault: FungibleToken.Vault {
|
|
42
44
|
|
|
43
45
|
// holds the balance of a users tokens
|
|
44
|
-
|
|
46
|
+
access(all) var balance: UFix64
|
|
45
47
|
|
|
46
48
|
// initialize the balance at resource creation time
|
|
47
49
|
init(balance: UFix64) {
|
|
@@ -57,7 +59,7 @@ pub contract DapperUtilityCoin: FungibleToken {
|
|
|
57
59
|
// created Vault to the context that called so it can be deposited
|
|
58
60
|
// elsewhere.
|
|
59
61
|
//
|
|
60
|
-
|
|
62
|
+
access(FungibleToken.Withdraw) fun withdraw(amount: UFix64): @{FungibleToken.Vault} {
|
|
61
63
|
self.balance = self.balance - amount
|
|
62
64
|
emit TokensWithdrawn(amount: amount, from: self.owner?.address)
|
|
63
65
|
return <-create Vault(balance: amount)
|
|
@@ -70,7 +72,7 @@ pub contract DapperUtilityCoin: FungibleToken {
|
|
|
70
72
|
// It is allowed to destroy the sent Vault because the Vault
|
|
71
73
|
// was a temporary holder of the tokens. The Vault's balance has
|
|
72
74
|
// been consumed and therefore can be destroyed.
|
|
73
|
-
|
|
75
|
+
access(all) fun deposit(from: @{FungibleToken.Vault}) {
|
|
74
76
|
let vault <- from as! @DapperUtilityCoin.Vault
|
|
75
77
|
self.balance = self.balance + vault.balance
|
|
76
78
|
emit TokensDeposited(amount: vault.balance, to: self.owner?.address)
|
|
@@ -78,9 +80,33 @@ pub contract DapperUtilityCoin: FungibleToken {
|
|
|
78
80
|
destroy vault
|
|
79
81
|
}
|
|
80
82
|
|
|
81
|
-
|
|
83
|
+
access(all) view fun isAvailableToWithdraw(amount: UFix64): Bool {
|
|
84
|
+
return self.balance >= amount
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
access(all) view fun getSupportedVaultTypes(): {Type: Bool} {
|
|
88
|
+
return {Type<@Vault>(): true}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
access(all) view fun isSupportedVaultType(type: Type): Bool {
|
|
92
|
+
return type == Type<@Vault>()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
access(contract) fun burnCallback() {
|
|
82
96
|
DapperUtilityCoin.totalSupply = DapperUtilityCoin.totalSupply - self.balance
|
|
83
97
|
}
|
|
98
|
+
|
|
99
|
+
access(all) fun createEmptyVault(): @{FungibleToken.Vault} {
|
|
100
|
+
return <- create Vault(balance: 0.0)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
access(all) view fun getViews(): [Type]{
|
|
104
|
+
return DapperUtilityCoin.getContractViews(resourceType: nil)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
access(all) fun resolveView(_ view: Type): AnyStruct? {
|
|
108
|
+
return DapperUtilityCoin.resolveContractView(resourceType: nil, viewType: view)
|
|
109
|
+
}
|
|
84
110
|
}
|
|
85
111
|
|
|
86
112
|
// createEmptyVault
|
|
@@ -90,16 +116,16 @@ pub contract DapperUtilityCoin: FungibleToken {
|
|
|
90
116
|
// and store the returned Vault in their storage in order to allow their
|
|
91
117
|
// account to be able to receive deposits of this token type.
|
|
92
118
|
//
|
|
93
|
-
|
|
119
|
+
access(all) fun createEmptyVault(vaultType: Type): @{FungibleToken.Vault} {
|
|
94
120
|
return <-create Vault(balance: 0.0)
|
|
95
121
|
}
|
|
96
122
|
|
|
97
|
-
|
|
123
|
+
access(all) resource Administrator {
|
|
98
124
|
// createNewMinter
|
|
99
125
|
//
|
|
100
126
|
// Function that creates and returns a new minter resource
|
|
101
127
|
//
|
|
102
|
-
|
|
128
|
+
access(all) fun createNewMinter(allowedAmount: UFix64): @Minter {
|
|
103
129
|
emit MinterCreated(allowedAmount: allowedAmount)
|
|
104
130
|
return <-create Minter(allowedAmount: allowedAmount)
|
|
105
131
|
}
|
|
@@ -108,7 +134,7 @@ pub contract DapperUtilityCoin: FungibleToken {
|
|
|
108
134
|
//
|
|
109
135
|
// Function that creates and returns a new burner resource
|
|
110
136
|
//
|
|
111
|
-
|
|
137
|
+
access(all) fun createNewBurner(): @Burner {
|
|
112
138
|
emit BurnerCreated()
|
|
113
139
|
return <-create Burner()
|
|
114
140
|
}
|
|
@@ -118,19 +144,19 @@ pub contract DapperUtilityCoin: FungibleToken {
|
|
|
118
144
|
//
|
|
119
145
|
// Resource object that token admin accounts can hold to mint new tokens.
|
|
120
146
|
//
|
|
121
|
-
|
|
147
|
+
access(all) resource Minter {
|
|
122
148
|
|
|
123
149
|
// the amount of tokens that the minter is allowed to mint
|
|
124
|
-
|
|
150
|
+
access(all) var allowedAmount: UFix64
|
|
125
151
|
|
|
126
152
|
// mintTokens
|
|
127
153
|
//
|
|
128
154
|
// Function that mints new tokens, adds them to the total supply,
|
|
129
155
|
// and returns them to the calling context.
|
|
130
156
|
//
|
|
131
|
-
|
|
157
|
+
access(all) fun mintTokens(amount: UFix64): @DapperUtilityCoin.Vault {
|
|
132
158
|
pre {
|
|
133
|
-
amount >
|
|
159
|
+
amount > 0.0: "Amount minted must be greater than zero"
|
|
134
160
|
amount <= self.allowedAmount: "Amount minted must be less than the allowed amount"
|
|
135
161
|
}
|
|
136
162
|
DapperUtilityCoin.totalSupply = DapperUtilityCoin.totalSupply + amount
|
|
@@ -148,7 +174,7 @@ pub contract DapperUtilityCoin: FungibleToken {
|
|
|
148
174
|
//
|
|
149
175
|
// Resource object that token admin accounts can hold to burn tokens.
|
|
150
176
|
//
|
|
151
|
-
|
|
177
|
+
access(all) resource Burner {
|
|
152
178
|
|
|
153
179
|
// burnTokens
|
|
154
180
|
//
|
|
@@ -157,7 +183,7 @@ pub contract DapperUtilityCoin: FungibleToken {
|
|
|
157
183
|
// Note: the burned tokens are automatically subtracted from the
|
|
158
184
|
// total supply in the Vault destructor.
|
|
159
185
|
//
|
|
160
|
-
|
|
186
|
+
access(all) fun burnTokens(from: @{FungibleToken.Vault}) {
|
|
161
187
|
let vault <- from as! @DapperUtilityCoin.Vault
|
|
162
188
|
let amount = vault.balance
|
|
163
189
|
destroy vault
|
|
@@ -165,6 +191,57 @@ pub contract DapperUtilityCoin: FungibleToken {
|
|
|
165
191
|
}
|
|
166
192
|
}
|
|
167
193
|
|
|
194
|
+
access(all) view fun getContractViews(resourceType: Type?): [Type] {
|
|
195
|
+
return [Type<FungibleTokenMetadataViews.FTView>(),
|
|
196
|
+
Type<FungibleTokenMetadataViews.FTDisplay>(),
|
|
197
|
+
Type<FungibleTokenMetadataViews.FTVaultData>(),
|
|
198
|
+
Type<FungibleTokenMetadataViews.TotalSupply>()]
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
|
|
202
|
+
switch viewType {
|
|
203
|
+
case Type<FungibleTokenMetadataViews.FTView>():
|
|
204
|
+
return FungibleTokenMetadataViews.FTView(
|
|
205
|
+
ftDisplay: self.resolveContractView(resourceType: nil, viewType: Type<FungibleTokenMetadataViews.FTDisplay>()) as! FungibleTokenMetadataViews.FTDisplay?,
|
|
206
|
+
ftVaultData: self.resolveContractView(resourceType: nil, viewType: Type<FungibleTokenMetadataViews.FTVaultData>()) as! FungibleTokenMetadataViews.FTVaultData?
|
|
207
|
+
)
|
|
208
|
+
case Type<FungibleTokenMetadataViews.FTDisplay>():
|
|
209
|
+
let media = MetadataViews.Media(
|
|
210
|
+
file: MetadataViews.HTTPFile(
|
|
211
|
+
url: "https://meetdapper.com/"
|
|
212
|
+
),
|
|
213
|
+
mediaType: "image/svg+xml"
|
|
214
|
+
)
|
|
215
|
+
let medias = MetadataViews.Medias([media])
|
|
216
|
+
return FungibleTokenMetadataViews.FTDisplay(
|
|
217
|
+
name: "Dapper Utility Coin",
|
|
218
|
+
symbol: "DUC",
|
|
219
|
+
description: "",
|
|
220
|
+
externalURL: MetadataViews.ExternalURL("https://meetdapper.com/"),
|
|
221
|
+
logos: medias,
|
|
222
|
+
socials: {
|
|
223
|
+
"twitter": MetadataViews.ExternalURL("https://twitter.com/hellodapper")
|
|
224
|
+
}
|
|
225
|
+
)
|
|
226
|
+
case Type<FungibleTokenMetadataViews.FTVaultData>():
|
|
227
|
+
let vaultRef = DapperUtilityCoin.account.storage.borrow<auth(FungibleToken.Withdraw) &DapperUtilityCoin.Vault>(from: /storage/dapperUtilityCoinVault)
|
|
228
|
+
?? panic("Could not borrow reference to the contract's Vault!")
|
|
229
|
+
return FungibleTokenMetadataViews.FTVaultData(
|
|
230
|
+
storagePath: /storage/dapperUtilityCoinVault,
|
|
231
|
+
receiverPath: /public/exampleTokenReceiver,
|
|
232
|
+
metadataPath: /public/dapperUtilityCoinBalance,
|
|
233
|
+
receiverLinkedType: Type<&{FungibleToken.Receiver, FungibleToken.Vault}>(),
|
|
234
|
+
metadataLinkedType: Type<&{FungibleToken.Balance, FungibleToken.Vault}>(),
|
|
235
|
+
createEmptyVaultFunction: (fun (): @{FungibleToken.Vault} {
|
|
236
|
+
return <-vaultRef.createEmptyVault()
|
|
237
|
+
})
|
|
238
|
+
)
|
|
239
|
+
case Type<FungibleTokenMetadataViews.TotalSupply>():
|
|
240
|
+
return FungibleTokenMetadataViews.TotalSupply(totalSupply: DapperUtilityCoin.totalSupply)
|
|
241
|
+
}
|
|
242
|
+
return nil
|
|
243
|
+
}
|
|
244
|
+
|
|
168
245
|
init() {
|
|
169
246
|
// we're using a high value as the balance here to make it look like we've got a ton of money,
|
|
170
247
|
// just in case some contract manually checks that our balance is sufficient to pay for stuff
|
|
@@ -172,26 +249,16 @@ pub contract DapperUtilityCoin: FungibleToken {
|
|
|
172
249
|
|
|
173
250
|
let admin <- create Administrator()
|
|
174
251
|
let minter <- admin.createNewMinter(allowedAmount: self.totalSupply)
|
|
175
|
-
self.account.save(<-admin, to: /storage/dapperUtilityCoinAdmin)
|
|
252
|
+
self.account.storage.save(<-admin, to: /storage/dapperUtilityCoinAdmin)
|
|
176
253
|
|
|
177
254
|
// mint tokens
|
|
178
255
|
let tokenVault <- minter.mintTokens(amount: self.totalSupply)
|
|
179
|
-
self.account.save(<-tokenVault, to: /storage/dapperUtilityCoinVault)
|
|
256
|
+
self.account.storage.save(<-tokenVault, to: /storage/dapperUtilityCoinVault)
|
|
180
257
|
destroy minter
|
|
181
258
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
self.account.
|
|
185
|
-
/public/dapperUtilityCoinBalance,
|
|
186
|
-
target: /storage/dapperUtilityCoinVault
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
// Create a public capability to the stored Vault that only exposes
|
|
190
|
-
// the deposit method through the Receiver interface
|
|
191
|
-
self.account.link<&{FungibleToken.Receiver}>(
|
|
192
|
-
/public/dapperUtilityCoinReceiver,
|
|
193
|
-
target: /storage/dapperUtilityCoinVault
|
|
194
|
-
)
|
|
259
|
+
let cap = self.account.capabilities.storage.issue<&DapperUtilityCoin.Vault>(/storage/dapperUtilityCoinVault)
|
|
260
|
+
self.account.capabilities.publish(cap, at: /public/dapperUtilityCoinBalance)
|
|
261
|
+
self.account.capabilities.publish(cap, at: /public/dapperUtilityCoinReceiver)
|
|
195
262
|
|
|
196
263
|
// Emit an event that shows that the contract was initialized
|
|
197
264
|
emit TokensInitialized(initialSupply: self.totalSupply)
|