@flowtyio/flow-contracts 0.1.0-beta.30 → 0.1.0-beta.32
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/contracts/flowty-drops/ContractManager.cdc +29 -3
- package/contracts/flowty-drops/DropFactory.cdc +6 -6
- package/contracts/flowty-drops/DropTypes.cdc +11 -7
- package/contracts/flowty-drops/{FlowtySwitchers.cdc → FlowtyActiveCheckers.cdc} +11 -11
- package/contracts/flowty-drops/FlowtyDrops.cdc +87 -57
- package/contracts/flowty-drops/initializers/OpenEditionInitializer.cdc +14 -15
- package/contracts/flowty-drops/nft/BaseCollection.cdc +3 -3
- package/contracts/flowty-drops/nft/NFTMetadata.cdc +24 -3
- package/contracts/flowty-drops/nft/OpenEditionNFT.cdc +1 -0
- package/contracts/flowty-drops/nft/OpenEditionTemplate.cdc +4 -2
- package/contracts/flowty-drops/nft/UniversalCollection.cdc +6 -0
- package/contracts/fungible-token-router/FungibleTokenRouter.cdc +1 -3
- package/flow.json +19 -19
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "FlowToken"
|
|
2
2
|
import "FungibleToken"
|
|
3
|
+
import "FungibleTokenRouter"
|
|
3
4
|
|
|
4
5
|
access(all) contract ContractManager {
|
|
5
6
|
access(all) let StoragePath: StoragePath
|
|
@@ -9,11 +10,24 @@ access(all) contract ContractManager {
|
|
|
9
10
|
|
|
10
11
|
access(all) resource Manager {
|
|
11
12
|
access(self) let acct: Capability<auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account>
|
|
13
|
+
access(self) let routerCap: Capability<auth(FungibleTokenRouter.Owner) &FungibleTokenRouter.Router>
|
|
14
|
+
|
|
15
|
+
access(all) let data: {String: AnyStruct}
|
|
16
|
+
access(all) let resources: @{String: AnyResource}
|
|
12
17
|
|
|
13
18
|
access(Manage) fun borrowContractAccount(): auth(Contracts) &Account {
|
|
14
19
|
return self.acct.borrow()!
|
|
15
20
|
}
|
|
16
21
|
|
|
22
|
+
access(Manage) fun addOverride(type: Type, addr: Address) {
|
|
23
|
+
let router = self.routerCap.borrow() ?? panic("fungible token router is not valid")
|
|
24
|
+
router.addOverride(type: type, addr: addr)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
access(Manage) fun getSwitchboard(): auth(FungibleTokenRouter.Owner) &FungibleTokenRouter.Router {
|
|
28
|
+
return self.routerCap.borrow()!
|
|
29
|
+
}
|
|
30
|
+
|
|
17
31
|
access(all) fun addFlowTokensToAccount(_ tokens: @FlowToken.Vault) {
|
|
18
32
|
self.acct.borrow()!.storage.borrow<&{FungibleToken.Receiver}>(from: /storage/flowTokenVault)!.deposit(from: <-tokens)
|
|
19
33
|
}
|
|
@@ -22,7 +36,7 @@ access(all) contract ContractManager {
|
|
|
22
36
|
return getAccount(self.acct.address)
|
|
23
37
|
}
|
|
24
38
|
|
|
25
|
-
init(tokens: @FlowToken.Vault) {
|
|
39
|
+
init(tokens: @FlowToken.Vault, defaultRouterAddress: Address) {
|
|
26
40
|
pre {
|
|
27
41
|
tokens.balance >= 0.001: "minimum balance of 0.001 required for initialization"
|
|
28
42
|
}
|
|
@@ -32,11 +46,23 @@ access(all) contract ContractManager {
|
|
|
32
46
|
assert(self.acct.check(), message: "failed to setup account capability")
|
|
33
47
|
|
|
34
48
|
acct.storage.borrow<&{FungibleToken.Receiver}>(from: /storage/flowTokenVault)!.deposit(from: <-tokens)
|
|
49
|
+
|
|
50
|
+
let router <- FungibleTokenRouter.createRouter(defaultAddress: defaultRouterAddress)
|
|
51
|
+
acct.storage.save(<-router, to: FungibleTokenRouter.StoragePath)
|
|
52
|
+
|
|
53
|
+
let receiver = acct.capabilities.storage.issue<&{FungibleToken.Receiver}>(FungibleTokenRouter.StoragePath)
|
|
54
|
+
assert(receiver.check(), message: "invalid switchboard receiver capability")
|
|
55
|
+
acct.capabilities.publish(receiver, at: FungibleTokenRouter.PublicPath)
|
|
56
|
+
|
|
57
|
+
self.routerCap = acct.capabilities.storage.issue<auth(FungibleTokenRouter.Owner) &FungibleTokenRouter.Router>(FungibleTokenRouter.StoragePath)
|
|
58
|
+
|
|
59
|
+
self.data = {}
|
|
60
|
+
self.resources <- {}
|
|
35
61
|
}
|
|
36
62
|
}
|
|
37
63
|
|
|
38
|
-
access(all) fun createManager(tokens: @FlowToken.Vault): @Manager {
|
|
39
|
-
return <- create Manager(tokens: <- tokens)
|
|
64
|
+
access(all) fun createManager(tokens: @FlowToken.Vault, defaultRouterAddress: Address): @Manager {
|
|
65
|
+
return <- create Manager(tokens: <- tokens, defaultRouterAddress: defaultRouterAddress)
|
|
40
66
|
}
|
|
41
67
|
|
|
42
68
|
init() {
|
|
@@ -2,7 +2,7 @@ import "FungibleToken"
|
|
|
2
2
|
import "MetadataViews"
|
|
3
3
|
|
|
4
4
|
import "FlowtyDrops"
|
|
5
|
-
import "
|
|
5
|
+
import "FlowtyActiveCheckers"
|
|
6
6
|
import "FlowtyAddressVerifiers"
|
|
7
7
|
import "FlowtyPricers"
|
|
8
8
|
|
|
@@ -22,7 +22,7 @@ access(all) contract DropFactory {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
// This drop is always on and never ends.
|
|
25
|
-
let
|
|
25
|
+
let activeChecker = FlowtyActiveCheckers.AlwaysOn()
|
|
26
26
|
|
|
27
27
|
// All addresses are allowed to participate
|
|
28
28
|
let addressVerifier = FlowtyAddressVerifiers.AllowAll(maxPerMint: 10)
|
|
@@ -30,7 +30,7 @@ access(all) contract DropFactory {
|
|
|
30
30
|
// The cost of each mint is the same, and only permits one token type as payment
|
|
31
31
|
let pricer = FlowtyPricers.FlatPrice(price: price, paymentTokenType: paymentTokenType)
|
|
32
32
|
|
|
33
|
-
let phaseDetails = FlowtyDrops.PhaseDetails(
|
|
33
|
+
let phaseDetails = FlowtyDrops.PhaseDetails(activeChecker: activeChecker, display: nil, pricer: pricer, addressVerifier: addressVerifier)
|
|
34
34
|
let phase <- FlowtyDrops.createPhase(details: phaseDetails)
|
|
35
35
|
|
|
36
36
|
|
|
@@ -54,8 +54,8 @@ access(all) contract DropFactory {
|
|
|
54
54
|
paymentTokenType.isSubtype(of: Type<@{FungibleToken.Vault}>()): "paymentTokenType must be a FungibleToken"
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
// This
|
|
58
|
-
let
|
|
57
|
+
// This ActiveChecker turns on at a set unix timestamp (or is on by default if nil), and ends at the specified end date if provided
|
|
58
|
+
let activeChecker = FlowtyActiveCheckers.TimestampChecker(start: startUnix, end: endUnix)
|
|
59
59
|
|
|
60
60
|
// All addresses are allowed to participate
|
|
61
61
|
let addressVerifier = FlowtyAddressVerifiers.AllowAll(maxPerMint: 10)
|
|
@@ -63,7 +63,7 @@ access(all) contract DropFactory {
|
|
|
63
63
|
// The cost of each mint is the same, and only permits one token type as payment
|
|
64
64
|
let pricer = FlowtyPricers.FlatPrice(price: price, paymentTokenType: paymentTokenType)
|
|
65
65
|
|
|
66
|
-
let phaseDetails = FlowtyDrops.PhaseDetails(
|
|
66
|
+
let phaseDetails = FlowtyDrops.PhaseDetails(activeChecker: activeChecker, display: nil, pricer: pricer, addressVerifier: addressVerifier)
|
|
67
67
|
let phase <- FlowtyDrops.createPhase(details: phaseDetails)
|
|
68
68
|
|
|
69
69
|
let nftType = CompositeType(nftTypeIdentifier) ?? panic("invalid nft type identifier")
|
|
@@ -96,7 +96,7 @@ access(all) contract DropTypes {
|
|
|
96
96
|
access(all) let id: UInt64
|
|
97
97
|
access(all) let index: Int
|
|
98
98
|
|
|
99
|
-
access(all) let
|
|
99
|
+
access(all) let activeCheckerType: String
|
|
100
100
|
access(all) let pricerType: String
|
|
101
101
|
access(all) let addressVerifierType: String
|
|
102
102
|
|
|
@@ -124,15 +124,15 @@ access(all) contract DropTypes {
|
|
|
124
124
|
self.index = index
|
|
125
125
|
self.id = phase.uuid
|
|
126
126
|
|
|
127
|
-
let d = phase.getDetails()
|
|
128
|
-
self.
|
|
127
|
+
let d: FlowtyDrops.PhaseDetails = phase.getDetails()
|
|
128
|
+
self.activeCheckerType = d.activeChecker.getType().identifier
|
|
129
129
|
self.pricerType = d.pricer.getType().identifier
|
|
130
130
|
self.addressVerifierType = d.addressVerifier.getType().identifier
|
|
131
131
|
|
|
132
|
-
self.hasStarted = d.
|
|
133
|
-
self.hasEnded = d.
|
|
134
|
-
self.start = d.
|
|
135
|
-
self.end = d.
|
|
132
|
+
self.hasStarted = d.activeChecker.hasStarted()
|
|
133
|
+
self.hasEnded = d.activeChecker.hasEnded()
|
|
134
|
+
self.start = d.activeChecker.getStart()
|
|
135
|
+
self.end = d.activeChecker.getEnd()
|
|
136
136
|
|
|
137
137
|
self.paymentTypes = []
|
|
138
138
|
for pt in d.pricer.getPaymentTypes() {
|
|
@@ -259,6 +259,10 @@ access(all) contract DropTypes {
|
|
|
259
259
|
phaseSummaries.append(summary)
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
if CompositeType(dropDetails.nftType) == nil {
|
|
263
|
+
continue
|
|
264
|
+
}
|
|
265
|
+
|
|
262
266
|
summaries.append(DropSummary(
|
|
263
267
|
id: drop!.uuid,
|
|
264
268
|
display: dropDetails.display,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import "FlowtyDrops"
|
|
2
2
|
|
|
3
3
|
/*
|
|
4
|
-
This contract contains implementations for the FlowtyDrops.
|
|
5
|
-
You can use these implementations, or your own,
|
|
4
|
+
This contract contains implementations for the FlowtyDrops.ActiveChecker struct interface.
|
|
5
|
+
You can use these implementations, or your own, to configure when a phase in a drop is active
|
|
6
6
|
*/
|
|
7
|
-
access(all) contract
|
|
7
|
+
access(all) contract FlowtyActiveCheckers {
|
|
8
8
|
/*
|
|
9
|
-
The AlwaysOn
|
|
9
|
+
The AlwaysOn ActiveChecker is always on and never ends.
|
|
10
10
|
*/
|
|
11
|
-
access(all) struct AlwaysOn: FlowtyDrops.
|
|
11
|
+
access(all) struct AlwaysOn: FlowtyDrops.ActiveChecker {
|
|
12
12
|
access(all) view fun hasStarted(): Bool {
|
|
13
13
|
return true
|
|
14
14
|
}
|
|
@@ -27,10 +27,10 @@ access(all) contract FlowtySwitchers {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/*
|
|
30
|
-
The manual
|
|
31
|
-
This version of
|
|
30
|
+
The manual checker is used to explicitly toggle a drop.
|
|
31
|
+
This version of checker allows a creator to turn on or off a drop at will
|
|
32
32
|
*/
|
|
33
|
-
access(all) struct
|
|
33
|
+
access(all) struct ManualChecker: FlowtyDrops.ActiveChecker {
|
|
34
34
|
access(self) var started: Bool
|
|
35
35
|
access(self) var ended: Bool
|
|
36
36
|
|
|
@@ -65,10 +65,10 @@ access(all) contract FlowtySwitchers {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/*
|
|
68
|
-
|
|
69
|
-
A timestamp
|
|
68
|
+
TimestampChecker uses block timestamps to determine if a phase or drop is live or not.
|
|
69
|
+
A timestamp checker has a start and an end time.
|
|
70
70
|
*/
|
|
71
|
-
access(all) struct
|
|
71
|
+
access(all) struct TimestampChecker: FlowtyDrops.ActiveChecker {
|
|
72
72
|
access(all) var start: UInt64?
|
|
73
73
|
access(all) var end: UInt64?
|
|
74
74
|
|
|
@@ -2,14 +2,16 @@ import "NonFungibleToken"
|
|
|
2
2
|
import "FungibleToken"
|
|
3
3
|
import "MetadataViews"
|
|
4
4
|
import "AddressUtils"
|
|
5
|
+
import "FungibleTokenMetadataViews"
|
|
6
|
+
import "FungibleTokenRouter"
|
|
5
7
|
|
|
6
8
|
access(all) contract FlowtyDrops {
|
|
7
9
|
access(all) let ContainerStoragePath: StoragePath
|
|
8
10
|
access(all) let ContainerPublicPath: PublicPath
|
|
9
11
|
|
|
10
|
-
access(all) event DropAdded(address: Address, id: UInt64, name: String, description: String, imageUrl: String, start: UInt64?, end: UInt64
|
|
12
|
+
access(all) event DropAdded(address: Address, id: UInt64, name: String, description: String, imageUrl: String, start: UInt64?, end: UInt64?, nftType: String)
|
|
11
13
|
access(all) event Minted(address: Address, dropID: UInt64, phaseID: UInt64, nftID: UInt64, nftType: String)
|
|
12
|
-
access(all) event PhaseAdded(dropID: UInt64, dropAddress: Address, id: UInt64, index: Int,
|
|
14
|
+
access(all) event PhaseAdded(dropID: UInt64, dropAddress: Address, id: UInt64, index: Int, activeCheckerType: String, pricerType: String, addressVerifierType: String)
|
|
13
15
|
access(all) event PhaseRemoved(dropID: UInt64, dropAddress: Address, id: UInt64)
|
|
14
16
|
|
|
15
17
|
access(all) entitlement Owner
|
|
@@ -27,12 +29,52 @@ access(all) contract FlowtyDrops {
|
|
|
27
29
|
phaseIndex: Int,
|
|
28
30
|
expectedType: Type,
|
|
29
31
|
receiverCap: Capability<&{NonFungibleToken.CollectionPublic}>,
|
|
30
|
-
commissionReceiver: Capability<&{FungibleToken.Receiver}
|
|
32
|
+
commissionReceiver: Capability<&{FungibleToken.Receiver}>?,
|
|
31
33
|
data: {String: AnyStruct}
|
|
32
34
|
): @{FungibleToken.Vault}
|
|
33
35
|
access(all) fun getDetails(): DropDetails
|
|
34
36
|
}
|
|
35
37
|
|
|
38
|
+
// A phase represents a stage of a drop. Some drops will only have one
|
|
39
|
+
// phase, while others could have many. For example, a drop with an allow list
|
|
40
|
+
// and a public mint would likely have two phases.
|
|
41
|
+
access(all) resource Phase: PhasePublic {
|
|
42
|
+
access(all) event ResourceDestroyed(uuid: UInt64 = self.uuid)
|
|
43
|
+
|
|
44
|
+
access(all) let details: PhaseDetails
|
|
45
|
+
|
|
46
|
+
access(all) let data: {String: AnyStruct}
|
|
47
|
+
access(all) let resources: @{String: AnyResource}
|
|
48
|
+
|
|
49
|
+
// returns whether this phase of a drop has started.
|
|
50
|
+
access(all) fun isActive(): Bool {
|
|
51
|
+
return self.details.activeChecker.hasStarted() && !self.details.activeChecker.hasEnded()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
access(all) fun getDetails(): PhaseDetails {
|
|
55
|
+
return self.details
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
access(EditPhase) fun borrowActiveCheckerAuth(): auth(Mutate) &{ActiveChecker} {
|
|
59
|
+
return &self.details.activeChecker
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
access(EditPhase) fun borrowPricerAuth(): auth(Mutate) &{Pricer} {
|
|
63
|
+
return &self.details.pricer
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
access(EditPhase) fun borrowAddressVerifierAuth(): auth(Mutate) &{AddressVerifier} {
|
|
67
|
+
return &self.details.addressVerifier
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
init(details: PhaseDetails) {
|
|
71
|
+
self.details = details
|
|
72
|
+
|
|
73
|
+
self.data = {}
|
|
74
|
+
self.resources <- {}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
36
78
|
access(all) resource Drop: DropPublic {
|
|
37
79
|
access(all) event ResourceDestroyed(
|
|
38
80
|
uuid: UInt64 = self.uuid,
|
|
@@ -47,13 +89,16 @@ access(all) contract FlowtyDrops {
|
|
|
47
89
|
access(self) let details: DropDetails
|
|
48
90
|
access(self) let minterCap: Capability<&{Minter}>
|
|
49
91
|
|
|
92
|
+
access(all) let data: {String: AnyStruct}
|
|
93
|
+
access(all) let resources: @{String: AnyResource}
|
|
94
|
+
|
|
50
95
|
access(all) fun mint(
|
|
51
96
|
payment: @{FungibleToken.Vault},
|
|
52
97
|
amount: Int,
|
|
53
98
|
phaseIndex: Int,
|
|
54
99
|
expectedType: Type,
|
|
55
100
|
receiverCap: Capability<&{NonFungibleToken.CollectionPublic}>,
|
|
56
|
-
commissionReceiver: Capability<&{FungibleToken.Receiver}
|
|
101
|
+
commissionReceiver: Capability<&{FungibleToken.Receiver}>?,
|
|
57
102
|
data: {String: AnyStruct}
|
|
58
103
|
): @{FungibleToken.Vault} {
|
|
59
104
|
pre {
|
|
@@ -74,16 +119,18 @@ access(all) contract FlowtyDrops {
|
|
|
74
119
|
let withdrawn <- payment.withdraw(amount: paymentAmount) // make sure that we have a fresh vault resource
|
|
75
120
|
|
|
76
121
|
// take commission
|
|
77
|
-
|
|
78
|
-
|
|
122
|
+
if commissionReceiver != nil && commissionReceiver!.check() {
|
|
123
|
+
let commission <- withdrawn.withdraw(amount: self.details.commissionRate * withdrawn.balance)
|
|
124
|
+
commissionReceiver!.borrow()!.deposit(from: <-commission)
|
|
125
|
+
}
|
|
79
126
|
|
|
80
127
|
assert(phase.details.pricer.getPrice(num: amount, paymentTokenType: withdrawn.getType(), minter: receiverCap.address) * (1.0 - self.details.commissionRate) == withdrawn.balance, message: "incorrect payment amount")
|
|
81
128
|
assert(phase.details.pricer.getPaymentTypes().contains(withdrawn.getType()), message: "unsupported payment type")
|
|
82
129
|
|
|
83
130
|
// mint the nfts
|
|
84
131
|
let minter = self.minterCap.borrow() ?? panic("minter capability could not be borrowed")
|
|
85
|
-
let mintedNFTs <- minter.mint(payment: <-withdrawn, amount: amount, phase: phase, data: data)
|
|
86
|
-
assert(phase.details.
|
|
132
|
+
let mintedNFTs: @[{NonFungibleToken.NFT}] <- minter.mint(payment: <-withdrawn, amount: amount, phase: phase, data: data)
|
|
133
|
+
assert(phase.details.activeChecker.hasStarted() && !phase.details.activeChecker.hasEnded(), message: "phase is not active")
|
|
87
134
|
assert(mintedNFTs.length == amount, message: "incorrect number of items returned")
|
|
88
135
|
|
|
89
136
|
// distribute to receiver
|
|
@@ -123,8 +170,8 @@ access(all) contract FlowtyDrops {
|
|
|
123
170
|
var count = 0
|
|
124
171
|
while count < self.phases.length {
|
|
125
172
|
let ref = self.borrowPhasePublic(index: count)
|
|
126
|
-
let
|
|
127
|
-
if
|
|
173
|
+
let activeChecker = ref.getDetails().activeChecker
|
|
174
|
+
if activeChecker.hasStarted() && !activeChecker.hasEnded() {
|
|
128
175
|
arr.append(ref)
|
|
129
176
|
}
|
|
130
177
|
|
|
@@ -152,7 +199,7 @@ access(all) contract FlowtyDrops {
|
|
|
152
199
|
dropAddress: self.owner!.address,
|
|
153
200
|
id: phase.uuid,
|
|
154
201
|
index: self.phases.length,
|
|
155
|
-
|
|
202
|
+
activeCheckerType: phase.details.activeChecker.getType().identifier,
|
|
156
203
|
pricerType: phase.details.pricer.getType().identifier,
|
|
157
204
|
addressVerifierType: phase.details.addressVerifier.getType().identifier
|
|
158
205
|
)
|
|
@@ -182,6 +229,9 @@ access(all) contract FlowtyDrops {
|
|
|
182
229
|
self.phases <- phases
|
|
183
230
|
self.details = details
|
|
184
231
|
self.minterCap = minterCap
|
|
232
|
+
|
|
233
|
+
self.data = {}
|
|
234
|
+
self.resources <- {}
|
|
185
235
|
}
|
|
186
236
|
}
|
|
187
237
|
|
|
@@ -193,6 +243,8 @@ access(all) contract FlowtyDrops {
|
|
|
193
243
|
access(all) let commissionRate: UFix64
|
|
194
244
|
access(all) let nftType: String
|
|
195
245
|
|
|
246
|
+
access(all) let data: {String: AnyStruct}
|
|
247
|
+
|
|
196
248
|
access(contract) fun addMinted(num: Int, addr: Address) {
|
|
197
249
|
self.totalMinted = self.totalMinted + num
|
|
198
250
|
if self.minters[addr] == nil {
|
|
@@ -203,22 +255,27 @@ access(all) contract FlowtyDrops {
|
|
|
203
255
|
}
|
|
204
256
|
|
|
205
257
|
init(display: MetadataViews.Display, medias: MetadataViews.Medias?, commissionRate: UFix64, nftType: String) {
|
|
258
|
+
pre {
|
|
259
|
+
nftType != "": "nftType should be a composite type identifier"
|
|
260
|
+
}
|
|
261
|
+
|
|
206
262
|
self.display = display
|
|
207
263
|
self.medias = medias
|
|
208
264
|
self.totalMinted = 0
|
|
209
265
|
self.commissionRate = commissionRate
|
|
210
266
|
self.minters = {}
|
|
211
267
|
self.nftType = nftType
|
|
268
|
+
self.data = {}
|
|
212
269
|
}
|
|
213
270
|
}
|
|
214
271
|
|
|
215
|
-
//
|
|
272
|
+
// An ActiveChecker represents a phase being on or off, and holds information
|
|
216
273
|
// about whether a phase has started or not.
|
|
217
|
-
access(all) struct interface
|
|
218
|
-
// Signal that a phase has started. If the phase has not ended, it means that this
|
|
274
|
+
access(all) struct interface ActiveChecker {
|
|
275
|
+
// Signal that a phase has started. If the phase has not ended, it means that this activeChecker's phase
|
|
219
276
|
// is active
|
|
220
277
|
access(all) view fun hasStarted(): Bool
|
|
221
|
-
// Signal that a phase has ended. If
|
|
278
|
+
// Signal that a phase has ended. If an ActiveChecker has ended, minting will not work. That could mean
|
|
222
279
|
// the drop is over, or it could mean another phase has begun.
|
|
223
280
|
access(all) view fun hasEnded(): Bool
|
|
224
281
|
|
|
@@ -226,40 +283,6 @@ access(all) contract FlowtyDrops {
|
|
|
226
283
|
access(all) view fun getEnd(): UInt64?
|
|
227
284
|
}
|
|
228
285
|
|
|
229
|
-
// A phase represents a stage of a drop. Some drops will only have one
|
|
230
|
-
// phase, while others could have many. For example, a drop with an allow list
|
|
231
|
-
// and a public mint would likely have two phases.
|
|
232
|
-
access(all) resource Phase: PhasePublic {
|
|
233
|
-
access(all) event ResourceDestroyed(uuid: UInt64 = self.uuid)
|
|
234
|
-
|
|
235
|
-
access(all) let details: PhaseDetails
|
|
236
|
-
|
|
237
|
-
// returns whether this phase of a drop has started.
|
|
238
|
-
access(all) fun isActive(): Bool {
|
|
239
|
-
return self.details.switcher.hasStarted() && !self.details.switcher.hasEnded()
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
access(all) fun getDetails(): PhaseDetails {
|
|
243
|
-
return self.details
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
access(EditPhase) fun borrowSwitchAuth(): auth(Mutate) &{Switcher} {
|
|
247
|
-
return &self.details.switcher
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
access(EditPhase) fun borrowPricerAuth(): auth(Mutate) &{Pricer} {
|
|
251
|
-
return &self.details.pricer
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
access(EditPhase) fun borrowAddressVerifierAuth(): auth(Mutate) &{AddressVerifier} {
|
|
255
|
-
return &self.details.addressVerifier
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
init(details: PhaseDetails) {
|
|
259
|
-
self.details = details
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
286
|
access(all) resource interface PhasePublic {
|
|
264
287
|
// What does a phase need to be able to answer/manage?
|
|
265
288
|
// - What are the details of the phase being interactive with?
|
|
@@ -272,7 +295,7 @@ access(all) contract FlowtyDrops {
|
|
|
272
295
|
|
|
273
296
|
access(all) struct PhaseDetails {
|
|
274
297
|
// handles whether a phase is on or not
|
|
275
|
-
access(all) let
|
|
298
|
+
access(all) let activeChecker: {ActiveChecker}
|
|
276
299
|
|
|
277
300
|
// display information about a phase
|
|
278
301
|
access(all) let display: MetadataViews.Display?
|
|
@@ -286,8 +309,8 @@ access(all) contract FlowtyDrops {
|
|
|
286
309
|
// placecholder data dictionary to allow new fields to be accessed
|
|
287
310
|
access(all) let data: {String: AnyStruct}
|
|
288
311
|
|
|
289
|
-
init(
|
|
290
|
-
self.
|
|
312
|
+
init(activeChecker: {ActiveChecker}, display: MetadataViews.Display?, pricer: {Pricer}, addressVerifier: {AddressVerifier}) {
|
|
313
|
+
self.activeChecker = activeChecker
|
|
291
314
|
self.display = display
|
|
292
315
|
self.pricer = pricer
|
|
293
316
|
self.addressVerifier = addressVerifier
|
|
@@ -314,8 +337,8 @@ access(all) contract FlowtyDrops {
|
|
|
314
337
|
access(all) resource interface Minter {
|
|
315
338
|
access(contract) fun mint(payment: @{FungibleToken.Vault}, amount: Int, phase: &FlowtyDrops.Phase, data: {String: AnyStruct}): @[{NonFungibleToken.NFT}] {
|
|
316
339
|
let resourceAddress = AddressUtils.parseAddress(self.getType())!
|
|
317
|
-
let receiver = getAccount(resourceAddress).capabilities.get<&{FungibleToken.Receiver}>(
|
|
318
|
-
?? panic("
|
|
340
|
+
let receiver = getAccount(resourceAddress).capabilities.get<&{FungibleToken.Receiver}>(FungibleTokenRouter.PublicPath).borrow()
|
|
341
|
+
?? panic("missing receiver at fungible token router path")
|
|
319
342
|
receiver.deposit(from: <-payment)
|
|
320
343
|
|
|
321
344
|
let nfts: @[{NonFungibleToken.NFT}] <- []
|
|
@@ -357,6 +380,9 @@ access(all) contract FlowtyDrops {
|
|
|
357
380
|
access(all) resource Container: ContainerPublic {
|
|
358
381
|
access(self) let drops: @{UInt64: Drop}
|
|
359
382
|
|
|
383
|
+
access(all) let data: {String: AnyStruct}
|
|
384
|
+
access(all) let resources: @{String: AnyResource}
|
|
385
|
+
|
|
360
386
|
access(Owner) fun addDrop(_ drop: @Drop) {
|
|
361
387
|
let details = drop.getDetails()
|
|
362
388
|
|
|
@@ -371,8 +397,9 @@ access(all) contract FlowtyDrops {
|
|
|
371
397
|
name: details.display.name,
|
|
372
398
|
description: details.display.description,
|
|
373
399
|
imageUrl: details.display.thumbnail.uri(),
|
|
374
|
-
start: firstPhaseDetails.
|
|
375
|
-
end: firstPhaseDetails.
|
|
400
|
+
start: firstPhaseDetails.activeChecker.getStart(),
|
|
401
|
+
end: firstPhaseDetails.activeChecker.getEnd(),
|
|
402
|
+
nftType: details.nftType
|
|
376
403
|
)
|
|
377
404
|
destroy self.drops.insert(key: drop.uuid, <-drop)
|
|
378
405
|
}
|
|
@@ -399,6 +426,9 @@ access(all) contract FlowtyDrops {
|
|
|
399
426
|
|
|
400
427
|
init() {
|
|
401
428
|
self.drops <- {}
|
|
429
|
+
|
|
430
|
+
self.data = {}
|
|
431
|
+
self.resources <- {}
|
|
402
432
|
}
|
|
403
433
|
}
|
|
404
434
|
|
|
@@ -416,7 +446,7 @@ access(all) contract FlowtyDrops {
|
|
|
416
446
|
|
|
417
447
|
access(all) fun getMinterStoragePath(type: Type): StoragePath {
|
|
418
448
|
let segments = type.identifier.split(separator: ".")
|
|
419
|
-
let identifier = "FlowtyDrops_Minter_".concat(segments[1]).concat(segments[2])
|
|
449
|
+
let identifier = "FlowtyDrops_Minter_".concat(segments[1]).concat("_").concat(segments[2])
|
|
420
450
|
return StoragePath(identifier: identifier)!
|
|
421
451
|
}
|
|
422
452
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import "ContractInitializer"
|
|
2
2
|
import "NFTMetadata"
|
|
3
3
|
import "FlowtyDrops"
|
|
4
|
+
import "NonFungibleToken"
|
|
5
|
+
import "UniversalCollection"
|
|
4
6
|
|
|
5
7
|
access(all) contract OpenEditionInitializer: ContractInitializer {
|
|
6
8
|
access(all) fun initialize(contractAcct: auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account, params: {String: AnyStruct}): NFTMetadata.InitializedCaps {
|
|
@@ -9,18 +11,15 @@ access(all) contract OpenEditionInitializer: ContractInitializer {
|
|
|
9
11
|
params["data"]!.getType() == Type<NFTMetadata.Metadata>(): "data param must be of type NFTMetadata.Metadata"
|
|
10
12
|
params["collectionInfo"] != nil: "missing param collectionInfo"
|
|
11
13
|
params["collectionInfo"]!.getType() == Type<NFTMetadata.CollectionInfo>(): "collectionInfo param must be of type NFTMetadata.CollectionInfo"
|
|
14
|
+
params["type"] != nil: "missing param type"
|
|
15
|
+
params["type"]!.getType() == Type<Type>(): "type param must be of type Type"
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
let data = params["data"]! as! NFTMetadata.Metadata
|
|
15
19
|
let collectionInfo = params["collectionInfo"]! as! NFTMetadata.CollectionInfo
|
|
16
20
|
|
|
17
|
-
let
|
|
18
|
-
let
|
|
19
|
-
|
|
20
|
-
let t = self.getType()
|
|
21
|
-
let contractName = t.identifier.split(separator: ".")[2]
|
|
22
|
-
|
|
23
|
-
self.account.storage.save(cap, to: StoragePath(identifier: "metadataAuthAccount_".concat(contractName))!)
|
|
21
|
+
let nftType = params["type"]! as! Type
|
|
22
|
+
let contractName = nftType.identifier.split(separator: ".")[2]
|
|
24
23
|
|
|
25
24
|
// do we have information to setup a drop as well?
|
|
26
25
|
if params.containsKey("dropDetails") && params.containsKey("phaseDetails") && params.containsKey("minterController") {
|
|
@@ -30,7 +29,7 @@ access(all) contract OpenEditionInitializer: ContractInitializer {
|
|
|
30
29
|
let phaseDetails = params["phaseDetails"]! as! [FlowtyDrops.PhaseDetails]
|
|
31
30
|
|
|
32
31
|
assert(minterCap.check(), message: "invalid minter capability")
|
|
33
|
-
|
|
32
|
+
assert(CompositeType(dropDetails.nftType) != nil, message: "dropDetails.nftType must be a valid CompositeType")
|
|
34
33
|
|
|
35
34
|
let phases: @[FlowtyDrops.Phase] <- []
|
|
36
35
|
for p in phaseDetails {
|
|
@@ -38,21 +37,21 @@ access(all) contract OpenEditionInitializer: ContractInitializer {
|
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
let drop <- FlowtyDrops.createDrop(details: dropDetails, minterCap: minterCap, phases: <- phases)
|
|
41
|
-
if
|
|
42
|
-
|
|
40
|
+
if contractAcct.storage.borrow<&AnyResource>(from: FlowtyDrops.ContainerStoragePath) == nil {
|
|
41
|
+
contractAcct.storage.save(<- FlowtyDrops.createContainer(), to: FlowtyDrops.ContainerStoragePath)
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
contractAcct.capabilities.unpublish(FlowtyDrops.ContainerPublicPath)
|
|
44
|
+
contractAcct.capabilities.publish(
|
|
45
|
+
contractAcct.capabilities.storage.issue<&{FlowtyDrops.ContainerPublic}>(FlowtyDrops.ContainerStoragePath),
|
|
47
46
|
at: FlowtyDrops.ContainerPublicPath
|
|
48
47
|
)
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
let container =
|
|
50
|
+
let container = contractAcct.storage.borrow<auth(FlowtyDrops.Owner) &FlowtyDrops.Container>(from: FlowtyDrops.ContainerStoragePath)
|
|
52
51
|
?? panic("drops container not found")
|
|
53
52
|
container.addDrop(<- drop)
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
return NFTMetadata.initialize(acct:
|
|
55
|
+
return NFTMetadata.initialize(acct: contractAcct, collectionInfo: collectionInfo, nftType: nftType)
|
|
57
56
|
}
|
|
58
57
|
}
|
|
@@ -82,12 +82,12 @@ access(all) contract interface BaseCollection: ViewResolver {
|
|
|
82
82
|
)
|
|
83
83
|
case Type<MetadataViews.NFTCollectionDisplay>():
|
|
84
84
|
let c = getAccount(addr).contracts.borrow<&{BaseCollection}>(name: segments[2])!
|
|
85
|
-
let
|
|
86
|
-
if
|
|
85
|
+
let tmp = c.MetadataCap.borrow()
|
|
86
|
+
if tmp == nil {
|
|
87
87
|
return nil
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
return
|
|
90
|
+
return tmp!.collectionInfo.getDisplay()
|
|
91
91
|
case Type<FlowtyDrops.DropResolver>():
|
|
92
92
|
return FlowtyDrops.DropResolver(cap: acct.capabilities.get<&{FlowtyDrops.ContainerPublic}>(FlowtyDrops.ContainerPublicPath))
|
|
93
93
|
}
|
|
@@ -9,8 +9,16 @@ access(all) contract NFTMetadata {
|
|
|
9
9
|
access(all) struct CollectionInfo {
|
|
10
10
|
access(all) var collectionDisplay: MetadataViews.NFTCollectionDisplay
|
|
11
11
|
|
|
12
|
+
access(all) let data: {String: AnyStruct}
|
|
13
|
+
|
|
14
|
+
access(all) fun getDisplay(): MetadataViews.NFTCollectionDisplay {
|
|
15
|
+
return self.collectionDisplay
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
init(collectionDisplay: MetadataViews.NFTCollectionDisplay) {
|
|
13
19
|
self.collectionDisplay = collectionDisplay
|
|
20
|
+
|
|
21
|
+
self.data = {}
|
|
14
22
|
}
|
|
15
23
|
}
|
|
16
24
|
|
|
@@ -24,8 +32,9 @@ access(all) contract NFTMetadata {
|
|
|
24
32
|
access(all) let traits: MetadataViews.Traits?
|
|
25
33
|
access(all) let editions: MetadataViews.Editions?
|
|
26
34
|
access(all) let externalURL: MetadataViews.ExternalURL?
|
|
35
|
+
access(all) let royalties: MetadataViews.Royalties?
|
|
27
36
|
|
|
28
|
-
access(all) let data: {String: AnyStruct}
|
|
37
|
+
access(all) let data: {String: AnyStruct}
|
|
29
38
|
|
|
30
39
|
init(
|
|
31
40
|
name: String,
|
|
@@ -34,6 +43,7 @@ access(all) contract NFTMetadata {
|
|
|
34
43
|
traits: MetadataViews.Traits?,
|
|
35
44
|
editions: MetadataViews.Editions?,
|
|
36
45
|
externalURL: MetadataViews.ExternalURL?,
|
|
46
|
+
royalties: MetadataViews.Royalties?,
|
|
37
47
|
data: {String: AnyStruct}
|
|
38
48
|
) {
|
|
39
49
|
self.name = name
|
|
@@ -43,6 +53,7 @@ access(all) contract NFTMetadata {
|
|
|
43
53
|
self.traits = traits
|
|
44
54
|
self.editions = editions
|
|
45
55
|
self.externalURL = externalURL
|
|
56
|
+
self.royalties = royalties
|
|
46
57
|
|
|
47
58
|
self.data = {}
|
|
48
59
|
}
|
|
@@ -53,6 +64,9 @@ access(all) contract NFTMetadata {
|
|
|
53
64
|
access(all) let metadata: {UInt64: Metadata}
|
|
54
65
|
access(all) var frozen: Bool
|
|
55
66
|
|
|
67
|
+
access(all) let data: {String: AnyStruct}
|
|
68
|
+
access(all) let resources: @{String: AnyResource}
|
|
69
|
+
|
|
56
70
|
access(all) fun borrowMetadata(id: UInt64): &Metadata? {
|
|
57
71
|
return &self.metadata[id]
|
|
58
72
|
}
|
|
@@ -74,6 +88,9 @@ access(all) contract NFTMetadata {
|
|
|
74
88
|
self.collectionInfo = collectionInfo
|
|
75
89
|
self.metadata = {}
|
|
76
90
|
self.frozen = false
|
|
91
|
+
|
|
92
|
+
self.data = {}
|
|
93
|
+
self.resources <- {}
|
|
77
94
|
}
|
|
78
95
|
}
|
|
79
96
|
|
|
@@ -81,9 +98,13 @@ access(all) contract NFTMetadata {
|
|
|
81
98
|
access(all) let pubCap: Capability<&Container>
|
|
82
99
|
access(all) let ownerCap: Capability<auth(Owner) &Container>
|
|
83
100
|
|
|
101
|
+
access(all) let data: {String: AnyStruct}
|
|
102
|
+
|
|
84
103
|
init(pubCap: Capability<&Container>, ownerCap: Capability<auth(Owner) &Container>) {
|
|
85
104
|
self.pubCap = pubCap
|
|
86
105
|
self.ownerCap = ownerCap
|
|
106
|
+
|
|
107
|
+
self.data = {}
|
|
87
108
|
}
|
|
88
109
|
}
|
|
89
110
|
|
|
@@ -91,8 +112,8 @@ access(all) contract NFTMetadata {
|
|
|
91
112
|
return <- create Container(collectionInfo: collectionInfo)
|
|
92
113
|
}
|
|
93
114
|
|
|
94
|
-
access(all) fun initialize(acct: auth(Storage, Capabilities) &Account, collectionInfo: CollectionInfo,
|
|
95
|
-
let storagePath = self.getCollectionStoragePath(type:
|
|
115
|
+
access(all) fun initialize(acct: auth(Storage, Capabilities) &Account, collectionInfo: CollectionInfo, nftType: Type): InitializedCaps {
|
|
116
|
+
let storagePath = self.getCollectionStoragePath(type: nftType)
|
|
96
117
|
let container <- self.createContainer(collectionInfo: collectionInfo)
|
|
97
118
|
acct.storage.save(<-container, to: storagePath)
|
|
98
119
|
let pubCap = acct.capabilities.storage.issue<&Container>(storagePath)
|
|
@@ -35,6 +35,7 @@ access(all) contract OpenEditionNFT: BaseCollection {
|
|
|
35
35
|
self.totalSupply = 0
|
|
36
36
|
self.account.storage.save(<- create NFTMinter(), to: FlowtyDrops.getMinterStoragePath(type: self.getType()))
|
|
37
37
|
params["minterController"] = self.account.capabilities.storage.issue<&{FlowtyDrops.Minter}>(FlowtyDrops.getMinterStoragePath(type: self.getType()))
|
|
38
|
+
params["type"] = Type<@NFT>()
|
|
38
39
|
|
|
39
40
|
self.MetadataCap = ContractBorrower.borrowInitializer(typeIdentifier: initializeIdentifier).initialize(contractAcct: self.account, params: params).pubCap
|
|
40
41
|
}
|
|
@@ -11,9 +11,10 @@ access(all) contract OpenEditionTemplate: ContractFactoryTemplate {
|
|
|
11
11
|
"NFTMetadata",
|
|
12
12
|
"UniversalCollection",
|
|
13
13
|
"ContractBorrower",
|
|
14
|
-
"BaseCollection"
|
|
14
|
+
"BaseCollection",
|
|
15
|
+
"ViewResolver"
|
|
15
16
|
]).concat("\n\n")
|
|
16
|
-
.concat("access(all) contract ").concat(name).concat(": BaseCollection {\n")
|
|
17
|
+
.concat("access(all) contract ").concat(name).concat(": BaseCollection, ViewResolver {\n")
|
|
17
18
|
.concat(" access(all) var MetadataCap: Capability<&NFTMetadata.Container>\n")
|
|
18
19
|
.concat(" access(all) var totalSupply: UInt64\n")
|
|
19
20
|
.concat("\n\n")
|
|
@@ -42,6 +43,7 @@ access(all) contract OpenEditionTemplate: ContractFactoryTemplate {
|
|
|
42
43
|
.concat(" let minter <- create NFTMinter()\n")
|
|
43
44
|
.concat(" self.account.storage.save(<-minter, to: FlowtyDrops.getMinterStoragePath(type: self.getType()))\n")
|
|
44
45
|
.concat(" params[\"minterController\"] = self.account.capabilities.storage.issue<&{FlowtyDrops.Minter}>(FlowtyDrops.getMinterStoragePath(type: self.getType()))\n")
|
|
46
|
+
.concat(" params[\"type\"] = Type<@NFT>()\n")
|
|
45
47
|
.concat("\n\n")
|
|
46
48
|
.concat(" self.MetadataCap = ContractBorrower.borrowInitializer(typeIdentifier: initializeIdentifier).initialize(contractAcct: self.account, params: params).pubCap\n")
|
|
47
49
|
.concat(" }\n")
|
|
@@ -7,6 +7,9 @@ access(all) contract UniversalCollection {
|
|
|
7
7
|
access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
|
|
8
8
|
access(all) var nftType: Type
|
|
9
9
|
|
|
10
|
+
access(all) let data: {String: AnyStruct}
|
|
11
|
+
access(all) let resources: @{String: AnyResource}
|
|
12
|
+
|
|
10
13
|
access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
|
|
11
14
|
return <- create Collection(nftType: self.nftType)
|
|
12
15
|
}
|
|
@@ -14,6 +17,9 @@ access(all) contract UniversalCollection {
|
|
|
14
17
|
init (nftType: Type) {
|
|
15
18
|
self.ownedNFTs <- {}
|
|
16
19
|
self.nftType = nftType
|
|
20
|
+
|
|
21
|
+
self.data = {}
|
|
22
|
+
self.resources <- {}
|
|
17
23
|
}
|
|
18
24
|
}
|
|
19
25
|
|
|
@@ -65,14 +65,12 @@ access(all) contract FungibleTokenRouter {
|
|
|
65
65
|
vaultDataOpt = md as! FungibleTokenMetadataViews.FTVaultData
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
let vaultData = vaultDataOpt ?? panic("vault data could not be retrieved")
|
|
68
|
+
let vaultData = vaultDataOpt ?? panic("vault data could not be retrieved for type ".concat(tokenType.identifier))
|
|
69
69
|
let receiver = getAccount(destination).capabilities.get<&{FungibleToken.Receiver}>(vaultData.receiverPath)
|
|
70
70
|
assert(receiver.check(), message: "no receiver found at path: ".concat(vaultData.receiverPath.toString()))
|
|
71
71
|
|
|
72
72
|
emit TokensRouted(tokenType: tokenType.identifier, amount: from.balance, to: destination)
|
|
73
73
|
receiver.borrow()!.deposit(from: <-from)
|
|
74
|
-
|
|
75
|
-
panic("Could not find FungibleTokenMetadataViews.FTVaultData on depositing tokens")
|
|
76
74
|
}
|
|
77
75
|
|
|
78
76
|
access(all) view fun getSupportedVaultTypes(): {Type: Bool} {
|
package/flow.json
CHANGED
|
@@ -359,7 +359,7 @@
|
|
|
359
359
|
"source": "./contracts/flowty-drops/ContractManager.cdc",
|
|
360
360
|
"aliases": {
|
|
361
361
|
"testing": "0x0000000000000006",
|
|
362
|
-
"testnet": "
|
|
362
|
+
"testnet": "0x772a10c786851a1b",
|
|
363
363
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
364
364
|
}
|
|
365
365
|
},
|
|
@@ -367,7 +367,7 @@
|
|
|
367
367
|
"source": "./contracts/flowty-drops/initializers/ContractInitializer.cdc",
|
|
368
368
|
"aliases": {
|
|
369
369
|
"testing": "0x0000000000000006",
|
|
370
|
-
"testnet": "
|
|
370
|
+
"testnet": "0x772a10c786851a1b",
|
|
371
371
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
372
372
|
}
|
|
373
373
|
},
|
|
@@ -375,7 +375,7 @@
|
|
|
375
375
|
"source": "./contracts/flowty-drops/initializers/ContractBorrower.cdc",
|
|
376
376
|
"aliases": {
|
|
377
377
|
"testing": "0x0000000000000006",
|
|
378
|
-
"testnet": "
|
|
378
|
+
"testnet": "0x772a10c786851a1b",
|
|
379
379
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
380
380
|
}
|
|
381
381
|
},
|
|
@@ -383,7 +383,7 @@
|
|
|
383
383
|
"source": "./contracts/flowty-drops/initializers/OpenEditionInitializer.cdc",
|
|
384
384
|
"aliases": {
|
|
385
385
|
"testing": "0x0000000000000006",
|
|
386
|
-
"testnet": "
|
|
386
|
+
"testnet": "0x772a10c786851a1b",
|
|
387
387
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
388
388
|
}
|
|
389
389
|
},
|
|
@@ -391,7 +391,7 @@
|
|
|
391
391
|
"source": "./contracts/flowty-drops/nft/BaseCollection.cdc",
|
|
392
392
|
"aliases": {
|
|
393
393
|
"testing": "0x0000000000000006",
|
|
394
|
-
"testnet": "
|
|
394
|
+
"testnet": "0x772a10c786851a1b",
|
|
395
395
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
396
396
|
}
|
|
397
397
|
},
|
|
@@ -399,7 +399,7 @@
|
|
|
399
399
|
"source": "./contracts/flowty-drops/nft/ContractFactoryTemplate.cdc",
|
|
400
400
|
"aliases": {
|
|
401
401
|
"testing": "0x0000000000000006",
|
|
402
|
-
"testnet": "
|
|
402
|
+
"testnet": "0x772a10c786851a1b",
|
|
403
403
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
404
404
|
}
|
|
405
405
|
},
|
|
@@ -407,7 +407,7 @@
|
|
|
407
407
|
"source": "./contracts/flowty-drops/nft/ContractFactory.cdc",
|
|
408
408
|
"aliases": {
|
|
409
409
|
"testing": "0x0000000000000006",
|
|
410
|
-
"testnet": "
|
|
410
|
+
"testnet": "0x772a10c786851a1b",
|
|
411
411
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
412
412
|
}
|
|
413
413
|
},
|
|
@@ -415,7 +415,7 @@
|
|
|
415
415
|
"source": "./contracts/flowty-drops/nft/OpenEditionTemplate.cdc",
|
|
416
416
|
"aliases": {
|
|
417
417
|
"testing": "0x0000000000000006",
|
|
418
|
-
"testnet": "
|
|
418
|
+
"testnet": "0x772a10c786851a1b",
|
|
419
419
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
420
420
|
}
|
|
421
421
|
},
|
|
@@ -423,7 +423,7 @@
|
|
|
423
423
|
"source": "./contracts/flowty-drops/nft/UniversalCollection.cdc",
|
|
424
424
|
"aliases": {
|
|
425
425
|
"testing": "0x0000000000000006",
|
|
426
|
-
"testnet": "
|
|
426
|
+
"testnet": "0x772a10c786851a1b",
|
|
427
427
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
428
428
|
}
|
|
429
429
|
},
|
|
@@ -431,7 +431,7 @@
|
|
|
431
431
|
"source": "./contracts/flowty-drops/nft/BaseNFT.cdc",
|
|
432
432
|
"aliases": {
|
|
433
433
|
"testing": "0x0000000000000006",
|
|
434
|
-
"testnet": "
|
|
434
|
+
"testnet": "0x772a10c786851a1b",
|
|
435
435
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
436
436
|
}
|
|
437
437
|
},
|
|
@@ -439,7 +439,7 @@
|
|
|
439
439
|
"source": "./contracts/flowty-drops/nft/NFTMetadata.cdc",
|
|
440
440
|
"aliases": {
|
|
441
441
|
"testing": "0x0000000000000006",
|
|
442
|
-
"testnet": "
|
|
442
|
+
"testnet": "0x772a10c786851a1b",
|
|
443
443
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
444
444
|
}
|
|
445
445
|
},
|
|
@@ -447,7 +447,7 @@
|
|
|
447
447
|
"source": "./contracts/flowty-drops/FlowtyDrops.cdc",
|
|
448
448
|
"aliases": {
|
|
449
449
|
"testing": "0x0000000000000006",
|
|
450
|
-
"testnet": "
|
|
450
|
+
"testnet": "0x772a10c786851a1b",
|
|
451
451
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
452
452
|
}
|
|
453
453
|
},
|
|
@@ -455,15 +455,15 @@
|
|
|
455
455
|
"source": "./contracts/flowty-drops/DropFactory.cdc",
|
|
456
456
|
"aliases": {
|
|
457
457
|
"testing": "0x0000000000000006",
|
|
458
|
-
"testnet": "
|
|
458
|
+
"testnet": "0x772a10c786851a1b",
|
|
459
459
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
460
460
|
}
|
|
461
461
|
},
|
|
462
|
-
"
|
|
463
|
-
"source": "./contracts/flowty-drops/
|
|
462
|
+
"FlowtyActiveCheckers": {
|
|
463
|
+
"source": "./contracts/flowty-drops/FlowtyActiveCheckers.cdc",
|
|
464
464
|
"aliases": {
|
|
465
465
|
"testing": "0x0000000000000006",
|
|
466
|
-
"testnet": "
|
|
466
|
+
"testnet": "0x772a10c786851a1b",
|
|
467
467
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
468
468
|
}
|
|
469
469
|
},
|
|
@@ -471,7 +471,7 @@
|
|
|
471
471
|
"source": "./contracts/flowty-drops/FlowtyPricers.cdc",
|
|
472
472
|
"aliases": {
|
|
473
473
|
"testing": "0x0000000000000006",
|
|
474
|
-
"testnet": "
|
|
474
|
+
"testnet": "0x772a10c786851a1b",
|
|
475
475
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
476
476
|
}
|
|
477
477
|
},
|
|
@@ -479,7 +479,7 @@
|
|
|
479
479
|
"source": "./contracts/flowty-drops/FlowtyAddressVerifiers.cdc",
|
|
480
480
|
"aliases": {
|
|
481
481
|
"testing": "0x0000000000000006",
|
|
482
|
-
"testnet": "
|
|
482
|
+
"testnet": "0x772a10c786851a1b",
|
|
483
483
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
484
484
|
}
|
|
485
485
|
},
|
|
@@ -487,7 +487,7 @@
|
|
|
487
487
|
"source": "./contracts/flowty-drops/DropTypes.cdc",
|
|
488
488
|
"aliases": {
|
|
489
489
|
"testing": "0x0000000000000006",
|
|
490
|
-
"testnet": "
|
|
490
|
+
"testnet": "0x934da91a977f1ac4",
|
|
491
491
|
"emulator": "0xf8d6e0586b0a20c7"
|
|
492
492
|
}
|
|
493
493
|
},
|