@flowtyio/flow-contracts 0.1.0-beta.9 → 0.1.1
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/FungibleTokenSwitchboard.cdc +360 -0
- package/contracts/MetadataViews.cdc +79 -6
- package/contracts/NonFungibleToken.cdc +17 -10
- package/contracts/capability-cache/CapabilityCache.cdc +97 -0
- 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/evm/CrossVMNFT.cdc +50 -0
- package/contracts/evm/EVM.cdc +851 -0
- package/contracts/evm/FlowEVMBridgeConfig.cdc +454 -0
- package/contracts/evm/FlowEVMBridgeHandlerInterfaces.cdc +163 -0
- package/contracts/evm/FlowEVMBridgeHandlers.cdc +230 -0
- package/contracts/evm/FlowEVMBridgeUtils.cdc +1303 -0
- package/contracts/evm/IBridgePermissions.cdc +19 -0
- package/contracts/evm/ICrossVM.cdc +12 -0
- package/contracts/evm/ICrossVMAsset.cdc +19 -0
- package/contracts/evm/Serialize.cdc +141 -0
- package/contracts/evm/SerializeMetadata.cdc +221 -0
- package/contracts/example/ExampleNFT.cdc +2 -2
- package/contracts/find/FindViews.cdc +357 -353
- package/contracts/flow-utils/ScopedFTProviders.cdc +5 -2
- package/contracts/flow-utils/ScopedNFTProviders.cdc +6 -2
- package/contracts/flowty-drops/ContractManager.cdc +73 -0
- package/contracts/flowty-drops/DropFactory.cdc +75 -0
- package/contracts/flowty-drops/DropTypes.cdc +282 -0
- package/contracts/flowty-drops/FlowtyActiveCheckers.cdc +113 -0
- package/contracts/flowty-drops/FlowtyAddressVerifiers.cdc +64 -0
- package/contracts/flowty-drops/FlowtyDrops.cdc +461 -0
- package/contracts/flowty-drops/FlowtyPricers.cdc +48 -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 +57 -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 +140 -0
- package/contracts/flowty-drops/nft/OpenEditionNFT.cdc +42 -0
- package/contracts/flowty-drops/nft/OpenEditionTemplate.cdc +54 -0
- package/contracts/flowty-drops/nft/UniversalCollection.cdc +29 -0
- package/contracts/fungible-token-router/FungibleTokenRouter.cdc +103 -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 +21 -17
- package/contracts/tokens/USDCFlow.cdc +232 -0
- package/flow.json +278 -7
- package/package.json +1 -1
- package/contracts/hybrid-custody/factories/NFTProviderAndCollectionPublicFactory.cdc +0 -10
|
@@ -47,62 +47,63 @@ import "FungibleToken"
|
|
|
47
47
|
import "NonFungibleToken"
|
|
48
48
|
import "MetadataViews"
|
|
49
49
|
import "TopShotLocking"
|
|
50
|
+
import "ViewResolver"
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
access(all) contract TopShot: NonFungibleToken {
|
|
52
53
|
// -----------------------------------------------------------------------
|
|
53
54
|
// TopShot deployment variables
|
|
54
55
|
// -----------------------------------------------------------------------
|
|
55
56
|
|
|
56
57
|
// The network the contract is deployed on
|
|
57
|
-
|
|
58
|
+
access(all) view fun Network() : String { return "emulator" }
|
|
58
59
|
|
|
59
60
|
// The address to which royalties should be deposited
|
|
60
|
-
|
|
61
|
+
access(all) view fun RoyaltyAddress() : Address { return TopShot.account.address }
|
|
61
62
|
|
|
62
63
|
// The path to the Subedition Admin resource belonging to the Account
|
|
63
64
|
// which the contract is deployed on
|
|
64
|
-
|
|
65
|
+
access(all) view fun SubeditionAdminStoragePath() : StoragePath { return /storage/TopShotSubeditionAdmin}
|
|
65
66
|
|
|
66
67
|
// -----------------------------------------------------------------------
|
|
67
68
|
// TopShot contract Events
|
|
68
69
|
// -----------------------------------------------------------------------
|
|
69
70
|
|
|
70
71
|
// Emitted when the TopShot contract is created
|
|
71
|
-
|
|
72
|
+
access(all) event ContractInitialized()
|
|
72
73
|
|
|
73
74
|
// Emitted when a new Play struct is created
|
|
74
|
-
|
|
75
|
+
access(all) event PlayCreated(id: UInt32, metadata: {String:String})
|
|
75
76
|
// Emitted when a new series has been triggered by an admin
|
|
76
|
-
|
|
77
|
+
access(all) event NewSeriesStarted(newCurrentSeries: UInt32)
|
|
77
78
|
|
|
78
79
|
// Events for Set-Related actions
|
|
79
80
|
//
|
|
80
81
|
// Emitted when a new Set is created
|
|
81
|
-
|
|
82
|
+
access(all) event SetCreated(setID: UInt32, series: UInt32)
|
|
82
83
|
// Emitted when a new Play is added to a Set
|
|
83
|
-
|
|
84
|
+
access(all) event PlayAddedToSet(setID: UInt32, playID: UInt32)
|
|
84
85
|
// Emitted when a Play is retired from a Set and cannot be used to mint
|
|
85
|
-
|
|
86
|
+
access(all) event PlayRetiredFromSet(setID: UInt32, playID: UInt32, numMoments: UInt32)
|
|
86
87
|
// Emitted when a Set is locked, meaning Plays cannot be added
|
|
87
|
-
|
|
88
|
+
access(all) event SetLocked(setID: UInt32)
|
|
88
89
|
// Emitted when a Moment is minted from a Set
|
|
89
|
-
|
|
90
|
+
access(all) event MomentMinted(momentID: UInt64, playID: UInt32, setID: UInt32, serialNumber: UInt32, subeditionID: UInt32)
|
|
90
91
|
|
|
91
92
|
// Events for Collection-related actions
|
|
92
93
|
//
|
|
93
94
|
// Emitted when a moment is withdrawn from a Collection
|
|
94
|
-
|
|
95
|
+
access(all) event Withdraw(id: UInt64, from: Address?)
|
|
95
96
|
// Emitted when a moment is deposited into a Collection
|
|
96
|
-
|
|
97
|
+
access(all) event Deposit(id: UInt64, to: Address?)
|
|
97
98
|
|
|
98
99
|
// Emitted when a Moment is destroyed
|
|
99
|
-
|
|
100
|
+
access(all) event MomentDestroyed(id: UInt64)
|
|
100
101
|
|
|
101
102
|
// Emitted when a Subedition is created
|
|
102
|
-
|
|
103
|
+
access(all) event SubeditionCreated(subeditionID: UInt32, name: String, metadata: {String:String})
|
|
103
104
|
|
|
104
105
|
// Emitted when a Subedition is linked to the specific Moment
|
|
105
|
-
|
|
106
|
+
access(all) event SubeditionAddedToMoment(momentID: UInt64, subeditionID: UInt32, setID: UInt32, playID: UInt32)
|
|
106
107
|
|
|
107
108
|
// -----------------------------------------------------------------------
|
|
108
109
|
// TopShot contract-level fields.
|
|
@@ -112,7 +113,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
112
113
|
// Series that this Set belongs to.
|
|
113
114
|
// Series is a concept that indicates a group of Sets through time.
|
|
114
115
|
// Many Sets can exist at a time, but only one series.
|
|
115
|
-
|
|
116
|
+
access(all) var currentSeries: UInt32
|
|
116
117
|
|
|
117
118
|
// Variable size dictionary of Play structs
|
|
118
119
|
access(self) var playDatas: {UInt32: Play}
|
|
@@ -126,17 +127,17 @@ pub contract TopShot: NonFungibleToken {
|
|
|
126
127
|
// The ID that is used to create Plays.
|
|
127
128
|
// Every time a Play is created, playID is assigned
|
|
128
129
|
// to the new Play's ID and then is incremented by 1.
|
|
129
|
-
|
|
130
|
+
access(all) var nextPlayID: UInt32
|
|
130
131
|
|
|
131
132
|
// The ID that is used to create Sets. Every time a Set is created
|
|
132
133
|
// setID is assigned to the new set's ID and then is incremented by 1.
|
|
133
|
-
|
|
134
|
+
access(all) var nextSetID: UInt32
|
|
134
135
|
|
|
135
136
|
// The total number of Top shot Moment NFTs that have been created
|
|
136
137
|
// Because NFTs can be destroyed, it doesn't necessarily mean that this
|
|
137
138
|
// reflects the total number of NFTs in existence, just the number that
|
|
138
139
|
// have been minted to date. Also used as global moment IDs for minting.
|
|
139
|
-
|
|
140
|
+
access(all) var totalSupply: UInt64
|
|
140
141
|
|
|
141
142
|
// -----------------------------------------------------------------------
|
|
142
143
|
// TopShot contract-level Composite Type definitions
|
|
@@ -156,16 +157,16 @@ pub contract TopShot: NonFungibleToken {
|
|
|
156
157
|
// its metadata. The plays are publicly accessible, so anyone can
|
|
157
158
|
// read the metadata associated with a specific play ID
|
|
158
159
|
//
|
|
159
|
-
|
|
160
|
+
access(all) struct Play {
|
|
160
161
|
|
|
161
162
|
// The unique ID for the Play
|
|
162
|
-
|
|
163
|
+
access(all) let playID: UInt32
|
|
163
164
|
|
|
164
165
|
// Stores all the metadata about the play as a string mapping
|
|
165
166
|
// This is not the long term way NFT metadata will be stored. It's a temporary
|
|
166
167
|
// construct while we figure out a better way to do metadata.
|
|
167
168
|
//
|
|
168
|
-
|
|
169
|
+
access(all) let metadata: {String: String}
|
|
169
170
|
|
|
170
171
|
init(metadata: {String: String}) {
|
|
171
172
|
pre {
|
|
@@ -196,19 +197,19 @@ pub contract TopShot: NonFungibleToken {
|
|
|
196
197
|
// at the end of the contract. Only the admin has the ability
|
|
197
198
|
// to modify any data in the private Set resource.
|
|
198
199
|
//
|
|
199
|
-
|
|
200
|
+
access(all) struct SetData {
|
|
200
201
|
|
|
201
202
|
// Unique ID for the Set
|
|
202
|
-
|
|
203
|
+
access(all) let setID: UInt32
|
|
203
204
|
|
|
204
205
|
// Name of the Set
|
|
205
206
|
// ex. "Times when the Toronto Raptors choked in the playoffs"
|
|
206
|
-
|
|
207
|
+
access(all) let name: String
|
|
207
208
|
|
|
208
209
|
// Series that this Set belongs to.
|
|
209
210
|
// Series is a concept that indicates a group of Sets through time.
|
|
210
211
|
// Many Sets can exist at a time, but only one series.
|
|
211
|
-
|
|
212
|
+
access(all) let series: UInt32
|
|
212
213
|
|
|
213
214
|
init(name: String) {
|
|
214
215
|
pre {
|
|
@@ -239,10 +240,10 @@ pub contract TopShot: NonFungibleToken {
|
|
|
239
240
|
//
|
|
240
241
|
// If retireAll() and lock() are called back-to-back,
|
|
241
242
|
// the Set is closed off forever and nothing more can be done with it.
|
|
242
|
-
|
|
243
|
+
access(all) resource Set {
|
|
243
244
|
|
|
244
245
|
// Unique ID for the set
|
|
245
|
-
|
|
246
|
+
access(all) let setID: UInt32
|
|
246
247
|
|
|
247
248
|
// Array of plays that are a part of this set.
|
|
248
249
|
// When a play is added to the set, its ID gets appended here.
|
|
@@ -263,7 +264,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
263
264
|
// If a Set is locked, Plays cannot be added, but
|
|
264
265
|
// Moments can still be minted from Plays
|
|
265
266
|
// that exist in the Set.
|
|
266
|
-
|
|
267
|
+
access(all) var locked: Bool
|
|
267
268
|
|
|
268
269
|
// Mapping of Play IDs that indicates the number of Moments
|
|
269
270
|
// that have been minted for specific Plays in this Set.
|
|
@@ -291,7 +292,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
291
292
|
// The Set needs to be not locked
|
|
292
293
|
// The Play can't have already been added to the Set
|
|
293
294
|
//
|
|
294
|
-
|
|
295
|
+
access(all) fun addPlay(playID: UInt32) {
|
|
295
296
|
pre {
|
|
296
297
|
TopShot.playDatas[playID] != nil: "Cannot add the Play to Set: Play doesn't exist."
|
|
297
298
|
!self.locked: "Cannot add the play to the Set after the set has been locked."
|
|
@@ -315,7 +316,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
315
316
|
// Parameters: playIDs: The IDs of the Plays that are being added
|
|
316
317
|
// as an array
|
|
317
318
|
//
|
|
318
|
-
|
|
319
|
+
access(all) fun addPlays(playIDs: [UInt32]) {
|
|
319
320
|
for play in playIDs {
|
|
320
321
|
self.addPlay(playID: play)
|
|
321
322
|
}
|
|
@@ -328,7 +329,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
328
329
|
// Pre-Conditions:
|
|
329
330
|
// The Play is part of the Set and not retired (available for minting).
|
|
330
331
|
//
|
|
331
|
-
|
|
332
|
+
access(all) fun retirePlay(playID: UInt32) {
|
|
332
333
|
pre {
|
|
333
334
|
self.retired[playID] != nil: "Cannot retire the Play: Play doesn't exist in this set!"
|
|
334
335
|
}
|
|
@@ -343,7 +344,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
343
344
|
// retireAll retires all the plays in the Set
|
|
344
345
|
// Afterwards, none of the retired Plays will be able to mint new Moments
|
|
345
346
|
//
|
|
346
|
-
|
|
347
|
+
access(all) fun retireAll() {
|
|
347
348
|
for play in self.plays {
|
|
348
349
|
self.retirePlay(playID: play)
|
|
349
350
|
}
|
|
@@ -353,7 +354,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
353
354
|
//
|
|
354
355
|
// Pre-Conditions:
|
|
355
356
|
// The Set should not be locked
|
|
356
|
-
|
|
357
|
+
access(all) fun lock() {
|
|
357
358
|
if !self.locked {
|
|
358
359
|
self.locked = true
|
|
359
360
|
emit SetLocked(setID: self.setID)
|
|
@@ -369,7 +370,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
369
370
|
//
|
|
370
371
|
// Returns: The NFT that was minted
|
|
371
372
|
//
|
|
372
|
-
|
|
373
|
+
access(all) fun mintMoment(playID: UInt32): @NFT {
|
|
373
374
|
pre {
|
|
374
375
|
self.retired[playID] != nil: "Cannot mint the moment: This play doesn't exist."
|
|
375
376
|
!self.retired[playID]!: "Cannot mint the moment from this play: This play has been retired."
|
|
@@ -399,7 +400,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
399
400
|
//
|
|
400
401
|
// Returns: Collection object that contains all the Moments that were minted
|
|
401
402
|
//
|
|
402
|
-
|
|
403
|
+
access(all) fun batchMintMoment(playID: UInt32, quantity: UInt64): @Collection {
|
|
403
404
|
let newCollection <- create Collection()
|
|
404
405
|
|
|
405
406
|
var i: UInt64 = 0
|
|
@@ -421,7 +422,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
421
422
|
//
|
|
422
423
|
// Returns: The NFT that was minted
|
|
423
424
|
//
|
|
424
|
-
|
|
425
|
+
access(all) fun mintMomentWithSubedition(playID: UInt32, subeditionID: UInt32): @NFT {
|
|
425
426
|
pre {
|
|
426
427
|
self.retired[playID] != nil: "Cannot mint the moment: This play doesn't exist."
|
|
427
428
|
!self.retired[playID]!: "Cannot mint the moment from this play: This play has been retired."
|
|
@@ -429,7 +430,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
429
430
|
|
|
430
431
|
// Gets the number of Moments that have been minted for this subedition
|
|
431
432
|
// to use as this Moment's serial number
|
|
432
|
-
let subeditionRef = TopShot.account.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
433
|
+
let subeditionRef = TopShot.account.storage.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
433
434
|
?? panic("No subedition admin resource in storage")
|
|
434
435
|
|
|
435
436
|
let numInSubedition = subeditionRef.getNumberMintedPerSubedition(setID: self.setID,
|
|
@@ -463,7 +464,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
463
464
|
//
|
|
464
465
|
// Returns: Collection object that contains all the Moments that were minted
|
|
465
466
|
//
|
|
466
|
-
|
|
467
|
+
access(all) fun batchMintMomentWithSubedition(playID: UInt32, quantity: UInt64, subeditionID: UInt32): @Collection {
|
|
467
468
|
let newCollection <- create Collection()
|
|
468
469
|
|
|
469
470
|
var i: UInt64 = 0
|
|
@@ -476,15 +477,15 @@ pub contract TopShot: NonFungibleToken {
|
|
|
476
477
|
return <-newCollection
|
|
477
478
|
}
|
|
478
479
|
|
|
479
|
-
|
|
480
|
+
access(all) view fun getPlays(): [UInt32] {
|
|
480
481
|
return self.plays
|
|
481
482
|
}
|
|
482
483
|
|
|
483
|
-
|
|
484
|
+
access(all) view fun getRetired(): {UInt32: Bool} {
|
|
484
485
|
return self.retired
|
|
485
486
|
}
|
|
486
487
|
|
|
487
|
-
|
|
488
|
+
access(all) view fun getNumMintedPerPlay(): {UInt32: UInt32} {
|
|
488
489
|
return self.numberMintedPerPlay
|
|
489
490
|
}
|
|
490
491
|
}
|
|
@@ -494,13 +495,13 @@ pub contract TopShot: NonFungibleToken {
|
|
|
494
495
|
// with the desired set ID
|
|
495
496
|
// let setData = TopShot.QuerySetData(setID: 12)
|
|
496
497
|
//
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
498
|
+
access(all) struct QuerySetData {
|
|
499
|
+
access(all) let setID: UInt32
|
|
500
|
+
access(all) let name: String
|
|
501
|
+
access(all) let series: UInt32
|
|
501
502
|
access(self) var plays: [UInt32]
|
|
502
503
|
access(self) var retired: {UInt32: Bool}
|
|
503
|
-
|
|
504
|
+
access(all) var locked: Bool
|
|
504
505
|
access(self) var numberMintedPerPlay: {UInt32: UInt32}
|
|
505
506
|
|
|
506
507
|
init(setID: UInt32) {
|
|
@@ -514,36 +515,36 @@ pub contract TopShot: NonFungibleToken {
|
|
|
514
515
|
self.setID = setID
|
|
515
516
|
self.name = setData.name
|
|
516
517
|
self.series = setData.series
|
|
517
|
-
self.plays = set.
|
|
518
|
-
self.retired = set.
|
|
518
|
+
self.plays = set.getPlays()
|
|
519
|
+
self.retired = set.getRetired()
|
|
519
520
|
self.locked = set.locked
|
|
520
|
-
self.numberMintedPerPlay = set.
|
|
521
|
+
self.numberMintedPerPlay = set.getNumMintedPerPlay()
|
|
521
522
|
}
|
|
522
523
|
|
|
523
|
-
|
|
524
|
+
access(all) view fun getPlays(): [UInt32] {
|
|
524
525
|
return self.plays
|
|
525
526
|
}
|
|
526
527
|
|
|
527
|
-
|
|
528
|
+
access(all) view fun getRetired(): {UInt32: Bool} {
|
|
528
529
|
return self.retired
|
|
529
530
|
}
|
|
530
531
|
|
|
531
|
-
|
|
532
|
+
access(all) view fun getNumberMintedPerPlay(): {UInt32: UInt32} {
|
|
532
533
|
return self.numberMintedPerPlay
|
|
533
534
|
}
|
|
534
535
|
}
|
|
535
536
|
|
|
536
|
-
|
|
537
|
+
access(all) struct MomentData {
|
|
537
538
|
|
|
538
539
|
// The ID of the Set that the Moment comes from
|
|
539
|
-
|
|
540
|
+
access(all) let setID: UInt32
|
|
540
541
|
|
|
541
542
|
// The ID of the Play that the Moment references
|
|
542
|
-
|
|
543
|
+
access(all) let playID: UInt32
|
|
543
544
|
|
|
544
545
|
// The place in the edition that this Moment was minted
|
|
545
546
|
// Otherwise know as the serial number
|
|
546
|
-
|
|
547
|
+
access(all) let serialNumber: UInt32
|
|
547
548
|
|
|
548
549
|
init(setID: UInt32, playID: UInt32, serialNumber: UInt32) {
|
|
549
550
|
self.setID = setID
|
|
@@ -556,38 +557,38 @@ pub contract TopShot: NonFungibleToken {
|
|
|
556
557
|
// This is an implementation of a custom metadata view for Top Shot.
|
|
557
558
|
// This view contains the play metadata.
|
|
558
559
|
//
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
560
|
+
access(all) struct TopShotMomentMetadataView {
|
|
561
|
+
|
|
562
|
+
access(all) let fullName: String?
|
|
563
|
+
access(all) let firstName: String?
|
|
564
|
+
access(all) let lastName: String?
|
|
565
|
+
access(all) let birthdate: String?
|
|
566
|
+
access(all) let birthplace: String?
|
|
567
|
+
access(all) let jerseyNumber: String?
|
|
568
|
+
access(all) let draftTeam: String?
|
|
569
|
+
access(all) let draftYear: String?
|
|
570
|
+
access(all) let draftSelection: String?
|
|
571
|
+
access(all) let draftRound: String?
|
|
572
|
+
access(all) let teamAtMomentNBAID: String?
|
|
573
|
+
access(all) let teamAtMoment: String?
|
|
574
|
+
access(all) let primaryPosition: String?
|
|
575
|
+
access(all) let height: String?
|
|
576
|
+
access(all) let weight: String?
|
|
577
|
+
access(all) let totalYearsExperience: String?
|
|
578
|
+
access(all) let nbaSeason: String?
|
|
579
|
+
access(all) let dateOfMoment: String?
|
|
580
|
+
access(all) let playCategory: String?
|
|
581
|
+
access(all) let playType: String?
|
|
582
|
+
access(all) let homeTeamName: String?
|
|
583
|
+
access(all) let awayTeamName: String?
|
|
584
|
+
access(all) let homeTeamScore: String?
|
|
585
|
+
access(all) let awayTeamScore: String?
|
|
586
|
+
access(all) let seriesNumber: UInt32?
|
|
587
|
+
access(all) let setName: String?
|
|
588
|
+
access(all) let serialNumber: UInt32
|
|
589
|
+
access(all) let playID: UInt32
|
|
590
|
+
access(all) let setID: UInt32
|
|
591
|
+
access(all) let numMomentsInEdition: UInt32?
|
|
591
592
|
|
|
592
593
|
init(
|
|
593
594
|
fullName: String?,
|
|
@@ -656,13 +657,13 @@ pub contract TopShot: NonFungibleToken {
|
|
|
656
657
|
|
|
657
658
|
// The resource that represents the Moment NFTs
|
|
658
659
|
//
|
|
659
|
-
|
|
660
|
+
access(all) resource NFT: NonFungibleToken.NFT {
|
|
660
661
|
|
|
661
662
|
// Global unique moment ID
|
|
662
|
-
|
|
663
|
+
access(all) let id: UInt64
|
|
663
664
|
|
|
664
665
|
// Struct of Moment metadata
|
|
665
|
-
|
|
666
|
+
access(all) let data: MomentData
|
|
666
667
|
|
|
667
668
|
init(serialNumber: UInt32, playID: UInt32, setID: UInt32, subeditionID: UInt32) {
|
|
668
669
|
// Increment the global Moment IDs
|
|
@@ -681,12 +682,15 @@ pub contract TopShot: NonFungibleToken {
|
|
|
681
682
|
}
|
|
682
683
|
|
|
683
684
|
// If the Moment is destroyed, emit an event to indicate
|
|
684
|
-
// to outside
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
685
|
+
// to outside observers that it has been destroyed
|
|
686
|
+
access(all) event ResourceDestroyed(
|
|
687
|
+
id: UInt64 = self.id,
|
|
688
|
+
serialNumber: UInt32 = self.data.serialNumber,
|
|
689
|
+
playID: UInt32 = self.data.playID,
|
|
690
|
+
setID: UInt32 = self.data.setID
|
|
691
|
+
)
|
|
692
|
+
|
|
693
|
+
access(all) view fun name(): String {
|
|
690
694
|
let fullName: String = TopShot.getPlayMetaDataByField(playID: self.data.playID, field: "FullName") ?? ""
|
|
691
695
|
let playType: String = TopShot.getPlayMetaDataByField(playID: self.data.playID, field: "PlayType") ?? ""
|
|
692
696
|
return fullName
|
|
@@ -708,14 +712,14 @@ pub contract TopShot: NonFungibleToken {
|
|
|
708
712
|
|
|
709
713
|
/// The description of the Moment. If Tagline property of the play is empty, compose it using the buildDescString function
|
|
710
714
|
/// If the Tagline property is not empty, use that as the description
|
|
711
|
-
|
|
715
|
+
access(all) fun description(): String {
|
|
712
716
|
let playDesc: String = TopShot.getPlayMetaDataByField(playID: self.data.playID, field: "Tagline") ?? ""
|
|
713
717
|
|
|
714
718
|
return playDesc.length > 0 ? playDesc : self.buildDescString()
|
|
715
719
|
}
|
|
716
720
|
|
|
717
721
|
// All supported metadata views for the Moment including the Core NFT Views
|
|
718
|
-
|
|
722
|
+
access(all) view fun getViews(): [Type] {
|
|
719
723
|
return [
|
|
720
724
|
Type<MetadataViews.Display>(),
|
|
721
725
|
Type<TopShotMomentMetadataView>(),
|
|
@@ -732,7 +736,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
732
736
|
|
|
733
737
|
|
|
734
738
|
|
|
735
|
-
|
|
739
|
+
access(all) fun resolveView(_ view: Type): AnyStruct? {
|
|
736
740
|
switch view {
|
|
737
741
|
case Type<MetadataViews.Display>():
|
|
738
742
|
return MetadataViews.Display(
|
|
@@ -787,56 +791,13 @@ pub contract TopShot: NonFungibleToken {
|
|
|
787
791
|
UInt64(self.data.serialNumber)
|
|
788
792
|
)
|
|
789
793
|
case Type<MetadataViews.Royalties>():
|
|
790
|
-
|
|
791
|
-
getAccount(TopShot.RoyaltyAddress()).getCapability<&AnyResource{FungibleToken.Receiver}>(MetadataViews.getRoyaltyReceiverPublicPath())
|
|
792
|
-
return MetadataViews.Royalties(
|
|
793
|
-
royalties: [
|
|
794
|
-
MetadataViews.Royalty(
|
|
795
|
-
receiver: royaltyReceiver,
|
|
796
|
-
cut: 0.05,
|
|
797
|
-
description: "NBATopShot marketplace royalty"
|
|
798
|
-
)
|
|
799
|
-
]
|
|
800
|
-
)
|
|
794
|
+
return TopShot.resolveContractView(resourceType: nil, viewType: Type<MetadataViews.Royalties>())
|
|
801
795
|
case Type<MetadataViews.ExternalURL>():
|
|
802
796
|
return MetadataViews.ExternalURL(self.getMomentURL())
|
|
803
797
|
case Type<MetadataViews.NFTCollectionData>():
|
|
804
|
-
return MetadataViews.NFTCollectionData(
|
|
805
|
-
storagePath: /storage/MomentCollection,
|
|
806
|
-
publicPath: /public/MomentCollection,
|
|
807
|
-
providerPath: /private/MomentCollection,
|
|
808
|
-
publicCollection: Type<&TopShot.Collection{TopShot.MomentCollectionPublic}>(),
|
|
809
|
-
publicLinkedType: Type<&TopShot.Collection{TopShot.MomentCollectionPublic,NonFungibleToken.Receiver,NonFungibleToken.CollectionPublic,MetadataViews.ResolverCollection}>(),
|
|
810
|
-
providerLinkedType: Type<&TopShot.Collection{NonFungibleToken.Provider,TopShot.MomentCollectionPublic,NonFungibleToken.Receiver,NonFungibleToken.CollectionPublic,MetadataViews.ResolverCollection}>(),
|
|
811
|
-
createEmptyCollectionFunction: (fun (): @NonFungibleToken.Collection {
|
|
812
|
-
return <-TopShot.createEmptyCollection()
|
|
813
|
-
})
|
|
814
|
-
)
|
|
798
|
+
return TopShot.resolveContractView(resourceType: nil, viewType: Type<MetadataViews.NFTCollectionData>())
|
|
815
799
|
case Type<MetadataViews.NFTCollectionDisplay>():
|
|
816
|
-
|
|
817
|
-
file: MetadataViews.HTTPFile(
|
|
818
|
-
url: "https://nbatopshot.com/static/img/top-shot-logo-horizontal-white.svg"
|
|
819
|
-
),
|
|
820
|
-
mediaType: "image/svg+xml"
|
|
821
|
-
)
|
|
822
|
-
let squareImage = MetadataViews.Media(
|
|
823
|
-
file: MetadataViews.HTTPFile(
|
|
824
|
-
url: "https://nbatopshot.com/static/img/og/og.png"
|
|
825
|
-
),
|
|
826
|
-
mediaType: "image/png"
|
|
827
|
-
)
|
|
828
|
-
return MetadataViews.NFTCollectionDisplay(
|
|
829
|
-
name: "NBA-Top-Shot",
|
|
830
|
-
description: "NBA Top Shot is your chance to own, sell, and trade official digital collectibles of the NBA and WNBA's greatest plays and players",
|
|
831
|
-
externalURL: MetadataViews.ExternalURL("https://nbatopshot.com"),
|
|
832
|
-
squareImage: squareImage,
|
|
833
|
-
bannerImage: bannerImage,
|
|
834
|
-
socials: {
|
|
835
|
-
"twitter": MetadataViews.ExternalURL("https://twitter.com/nbatopshot"),
|
|
836
|
-
"discord": MetadataViews.ExternalURL("https://discord.com/invite/nbatopshot"),
|
|
837
|
-
"instagram": MetadataViews.ExternalURL("https://www.instagram.com/nbatopshot")
|
|
838
|
-
}
|
|
839
|
-
)
|
|
800
|
+
return TopShot.resolveContractView(resourceType: nil, viewType: Type<MetadataViews.NFTCollectionDisplay>())
|
|
840
801
|
case Type<MetadataViews.Traits>():
|
|
841
802
|
// sports radar team id
|
|
842
803
|
let excludedNames: [String] = ["TeamAtMomentNBAID"]
|
|
@@ -844,14 +805,15 @@ pub contract TopShot: NonFungibleToken {
|
|
|
844
805
|
let traitDictionary: {String: AnyStruct} = {
|
|
845
806
|
"SeriesNumber": TopShot.getSetSeries(setID: self.data.setID),
|
|
846
807
|
"SetName": TopShot.getSetName(setID: self.data.setID),
|
|
847
|
-
"SerialNumber": self.data.serialNumber
|
|
808
|
+
"SerialNumber": self.data.serialNumber,
|
|
809
|
+
"Locked": TopShotLocking.isLocked(nftRef: &self as &{NonFungibleToken.NFT})
|
|
848
810
|
}
|
|
849
811
|
// add play specific data
|
|
850
812
|
let fullDictionary = self.mapPlayData(dict: traitDictionary)
|
|
851
813
|
return MetadataViews.dictToTraits(dict: fullDictionary, excludedNames: excludedNames)
|
|
852
814
|
case Type<MetadataViews.Medias>():
|
|
853
815
|
return MetadataViews.Medias(
|
|
854
|
-
|
|
816
|
+
[
|
|
855
817
|
MetadataViews.Media(
|
|
856
818
|
file: MetadataViews.HTTPFile(
|
|
857
819
|
url: self.mediumimage()
|
|
@@ -875,7 +837,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
875
837
|
|
|
876
838
|
// mapPlayData helps build our trait map from play metadata
|
|
877
839
|
// Returns: The trait map with all non-empty fields from play data added
|
|
878
|
-
|
|
840
|
+
access(all) fun mapPlayData(dict: {String: AnyStruct}) : {String: AnyStruct} {
|
|
879
841
|
let playMetadata = TopShot.getPlayMetaData(playID: self.data.playID) ?? {}
|
|
880
842
|
for name in playMetadata.keys {
|
|
881
843
|
let value = playMetadata[name] ?? ""
|
|
@@ -888,53 +850,58 @@ pub contract TopShot: NonFungibleToken {
|
|
|
888
850
|
|
|
889
851
|
// getMomentURL
|
|
890
852
|
// Returns: The computed external url of the moment
|
|
891
|
-
|
|
853
|
+
access(all) view fun getMomentURL(): String {
|
|
892
854
|
return "https://nbatopshot.com/moment/".concat(self.id.toString())
|
|
893
855
|
}
|
|
894
856
|
// getEditionName Moment's edition name is a combination of the Moment's setName and playID
|
|
895
857
|
// `setName: #playID`
|
|
896
|
-
|
|
858
|
+
access(all) view fun getEditionName() : String {
|
|
897
859
|
let setName: String = TopShot.getSetName(setID: self.data.setID) ?? ""
|
|
898
860
|
let editionName = setName.concat(": #").concat(self.data.playID.toString())
|
|
899
861
|
return editionName
|
|
900
862
|
}
|
|
901
863
|
|
|
902
|
-
|
|
864
|
+
access(all) view fun assetPath(): String {
|
|
903
865
|
return "https://assets.nbatopshot.com/media/".concat(self.id.toString())
|
|
904
866
|
}
|
|
905
867
|
|
|
906
868
|
// returns a url to display an medium sized image
|
|
907
|
-
|
|
869
|
+
access(all) fun mediumimage(): String {
|
|
908
870
|
let url = self.assetPath().concat("?width=512")
|
|
909
871
|
return self.appendOptionalParams(url: url, firstDelim: "&")
|
|
910
872
|
}
|
|
911
873
|
|
|
912
874
|
// a url to display a thumbnail associated with the moment
|
|
913
|
-
|
|
875
|
+
access(all) fun thumbnail(): String {
|
|
914
876
|
let url = self.assetPath().concat("?width=256")
|
|
915
877
|
return self.appendOptionalParams(url: url, firstDelim: "&")
|
|
916
878
|
}
|
|
917
879
|
|
|
918
880
|
// a url to display a video associated with the moment
|
|
919
|
-
|
|
881
|
+
access(all) fun video(): String {
|
|
920
882
|
let url = self.assetPath().concat("/video")
|
|
921
883
|
return self.appendOptionalParams(url: url, firstDelim: "?")
|
|
922
884
|
}
|
|
923
885
|
|
|
924
886
|
// appends and optional network param needed to resolve the media
|
|
925
|
-
|
|
887
|
+
access(all) fun appendOptionalParams(url: String, firstDelim: String): String {
|
|
926
888
|
if (TopShot.Network() == "testnet") {
|
|
927
889
|
return url.concat(firstDelim).concat("testnet")
|
|
928
890
|
}
|
|
929
891
|
return url
|
|
930
892
|
}
|
|
893
|
+
|
|
894
|
+
// Create an empty Collection for Pinnacle NFTs and return it to the caller
|
|
895
|
+
access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
|
|
896
|
+
return <- TopShot.createEmptyCollection(nftType: Type<@TopShot.NFT>())
|
|
897
|
+
}
|
|
931
898
|
}
|
|
932
899
|
|
|
933
900
|
// Admin is a special authorization resource that
|
|
934
901
|
// allows the owner to perform important functions to modify the
|
|
935
902
|
// various aspects of the Plays, Sets, and Moments
|
|
936
903
|
//
|
|
937
|
-
|
|
904
|
+
access(all) resource Admin {
|
|
938
905
|
|
|
939
906
|
// createPlay creates a new Play struct
|
|
940
907
|
// and stores it in the Plays dictionary in the TopShot smart contract
|
|
@@ -945,7 +912,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
945
912
|
//
|
|
946
913
|
// Returns: the ID of the new Play object
|
|
947
914
|
//
|
|
948
|
-
|
|
915
|
+
access(all) fun createPlay(metadata: {String: String}): UInt32 {
|
|
949
916
|
// Create the new Play
|
|
950
917
|
var newPlay = Play(metadata: metadata)
|
|
951
918
|
let newID = newPlay.playID
|
|
@@ -965,7 +932,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
965
932
|
/// Parameters: playID: The ID of the play to update
|
|
966
933
|
/// tagline: A string to be used as the tagline for the play
|
|
967
934
|
/// Returns: The ID of the play
|
|
968
|
-
|
|
935
|
+
access(all) fun updatePlayTagline(playID: UInt32, tagline: String): UInt32 {
|
|
969
936
|
let tmpPlay = TopShot.playDatas[playID] ?? panic("playID does not exist")
|
|
970
937
|
tmpPlay.updateTagline(tagline: tagline)
|
|
971
938
|
return playID
|
|
@@ -977,7 +944,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
977
944
|
// Parameters: name: The name of the Set
|
|
978
945
|
//
|
|
979
946
|
// Returns: The ID of the created set
|
|
980
|
-
|
|
947
|
+
access(all) fun createSet(name: String): UInt32 {
|
|
981
948
|
|
|
982
949
|
// Create the new Set
|
|
983
950
|
var newSet <- create Set(name: name)
|
|
@@ -1004,7 +971,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1004
971
|
// Returns: A reference to the Set with all of the fields
|
|
1005
972
|
// and methods exposed
|
|
1006
973
|
//
|
|
1007
|
-
|
|
974
|
+
access(all) view fun borrowSet(setID: UInt32): &Set {
|
|
1008
975
|
pre {
|
|
1009
976
|
TopShot.sets[setID] != nil: "Cannot borrow Set: The Set doesn't exist"
|
|
1010
977
|
}
|
|
@@ -1020,7 +987,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1020
987
|
//
|
|
1021
988
|
// Returns: The new series number
|
|
1022
989
|
//
|
|
1023
|
-
|
|
990
|
+
access(all) fun startNewSeries(): UInt32 {
|
|
1024
991
|
// End the current series and start a new one
|
|
1025
992
|
// by incrementing the TopShot series number
|
|
1026
993
|
TopShot.currentSeries = TopShot.currentSeries + UInt32(1)
|
|
@@ -1032,8 +999,8 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1032
999
|
|
|
1033
1000
|
// createSubeditionResource creates new SubeditionMap resource that
|
|
1034
1001
|
// will be used to mint Moments with Subeditions
|
|
1035
|
-
|
|
1036
|
-
TopShot.account.save<@SubeditionAdmin>(<- create SubeditionAdmin(), to: TopShot.SubeditionAdminStoragePath())
|
|
1002
|
+
access(all) fun createSubeditionAdminResource() {
|
|
1003
|
+
TopShot.account.storage.save<@SubeditionAdmin>(<- create SubeditionAdmin(), to: TopShot.SubeditionAdminStoragePath())
|
|
1037
1004
|
}
|
|
1038
1005
|
|
|
1039
1006
|
// setMomentsSubedition saves which Subedition the Moment belongs to
|
|
@@ -1043,8 +1010,8 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1043
1010
|
// setID: The ID of the Set that the Moment references
|
|
1044
1011
|
// playID: The ID of the Play that the Moment references
|
|
1045
1012
|
//
|
|
1046
|
-
|
|
1047
|
-
let subeditionAdmin = TopShot.account.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1013
|
+
access(all) fun setMomentsSubedition(nftID: UInt64, subeditionID: UInt32, setID: UInt32, playID: UInt32) {
|
|
1014
|
+
let subeditionAdmin = TopShot.account.storage.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1048
1015
|
?? panic("No subedition admin resource in storage")
|
|
1049
1016
|
|
|
1050
1017
|
subeditionAdmin.setMomentsSubedition(nftID: nftID, subeditionID: subeditionID, setID: setID, playID: playID)
|
|
@@ -1058,8 +1025,8 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1058
1025
|
//
|
|
1059
1026
|
// Returns: the ID of the new Subedition object
|
|
1060
1027
|
//
|
|
1061
|
-
|
|
1062
|
-
let subeditionAdmin = TopShot.account.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1028
|
+
access(all) fun createSubedition(name:String, metadata:{String:String}): UInt32 {
|
|
1029
|
+
let subeditionAdmin = TopShot.account.storage.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1063
1030
|
?? panic("No subedition admin resource in storage")
|
|
1064
1031
|
|
|
1065
1032
|
return subeditionAdmin.createSubedition(name:name, metadata:metadata)
|
|
@@ -1067,7 +1034,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1067
1034
|
|
|
1068
1035
|
// createNewAdmin creates a new Admin resource
|
|
1069
1036
|
//
|
|
1070
|
-
|
|
1037
|
+
access(all) fun createNewAdmin(): @Admin {
|
|
1071
1038
|
return <-create Admin()
|
|
1072
1039
|
}
|
|
1073
1040
|
}
|
|
@@ -1075,12 +1042,9 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1075
1042
|
// This is the interface that users can cast their Moment Collection as
|
|
1076
1043
|
// to allow others to deposit Moments into their Collection. It also allows for reading
|
|
1077
1044
|
// the IDs of Moments in the Collection.
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
pub fun getIDs(): [UInt64]
|
|
1082
|
-
pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
|
|
1083
|
-
pub fun borrowMoment(id: UInt64): &TopShot.NFT? {
|
|
1045
|
+
access(all) resource interface MomentCollectionPublic : NonFungibleToken.CollectionPublic {
|
|
1046
|
+
access(all) fun batchDeposit(tokens: @{NonFungibleToken.Collection})
|
|
1047
|
+
access(all) fun borrowMoment(id: UInt64): &TopShot.NFT? {
|
|
1084
1048
|
// If the result isn't nil, the id of the returned reference
|
|
1085
1049
|
// should be the same as the argument to the function
|
|
1086
1050
|
post {
|
|
@@ -1093,35 +1057,62 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1093
1057
|
// Collection is a resource that every user who owns NFTs
|
|
1094
1058
|
// will store in their account to manage their NFTS
|
|
1095
1059
|
//
|
|
1096
|
-
|
|
1060
|
+
access(all) resource Collection: MomentCollectionPublic, NonFungibleToken.Collection {
|
|
1097
1061
|
// Dictionary of Moment conforming tokens
|
|
1098
1062
|
// NFT is a resource type with a UInt64 ID field
|
|
1099
|
-
|
|
1063
|
+
access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
|
|
1100
1064
|
|
|
1101
1065
|
init() {
|
|
1102
1066
|
self.ownedNFTs <- {}
|
|
1103
1067
|
}
|
|
1104
1068
|
|
|
1069
|
+
// Return a list of NFT types that this receiver accepts
|
|
1070
|
+
access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
|
|
1071
|
+
let supportedTypes: {Type: Bool} = {}
|
|
1072
|
+
supportedTypes[Type<@TopShot.NFT>()] = true
|
|
1073
|
+
return supportedTypes
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// Return whether or not the given type is accepted by the collection
|
|
1077
|
+
// A collection that can accept any type should just return true by default
|
|
1078
|
+
access(all) view fun isSupportedNFTType(type: Type): Bool {
|
|
1079
|
+
if type == Type<@TopShot.NFT>() {
|
|
1080
|
+
return true
|
|
1081
|
+
}
|
|
1082
|
+
return false
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
// Return the amount of NFTs stored in the collection
|
|
1086
|
+
access(all) view fun getLength(): Int {
|
|
1087
|
+
return self.ownedNFTs.keys.length
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
// Create an empty Collection for TopShot NFTs and return it to the caller
|
|
1091
|
+
access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
|
|
1092
|
+
return <- TopShot.createEmptyCollection(nftType: Type<@TopShot.NFT>())
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1105
1095
|
// withdraw removes an Moment from the Collection and moves it to the caller
|
|
1106
1096
|
//
|
|
1107
1097
|
// Parameters: withdrawID: The ID of the NFT
|
|
1108
1098
|
// that is to be removed from the Collection
|
|
1109
1099
|
//
|
|
1110
1100
|
// returns: @NonFungibleToken.NFT the token that was withdrawn
|
|
1111
|
-
|
|
1101
|
+
access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
|
|
1112
1102
|
|
|
1113
1103
|
// Borrow nft and check if locked
|
|
1114
|
-
let nft = self.borrowNFT(
|
|
1104
|
+
let nft = self.borrowNFT(withdrawID)
|
|
1105
|
+
?? panic("Cannot borrow: empty reference")
|
|
1115
1106
|
if TopShotLocking.isLocked(nftRef: nft) {
|
|
1116
1107
|
panic("Cannot withdraw: Moment is locked")
|
|
1117
1108
|
}
|
|
1118
1109
|
|
|
1119
1110
|
// Remove the nft from the Collection
|
|
1120
|
-
let token <- self.ownedNFTs.remove(key: withdrawID)
|
|
1111
|
+
let token <- self.ownedNFTs.remove(key: withdrawID)
|
|
1121
1112
|
?? panic("Cannot withdraw: Moment does not exist in the collection")
|
|
1122
1113
|
|
|
1123
1114
|
emit Withdraw(id: token.id, from: self.owner?.address)
|
|
1124
|
-
|
|
1115
|
+
|
|
1125
1116
|
// Return the withdrawn token
|
|
1126
1117
|
return <-token
|
|
1127
1118
|
}
|
|
@@ -1133,7 +1124,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1133
1124
|
// Returns: @NonFungibleToken.Collection: A collection that contains
|
|
1134
1125
|
// the withdrawn moments
|
|
1135
1126
|
//
|
|
1136
|
-
|
|
1127
|
+
access(NonFungibleToken.Withdraw) fun batchWithdraw(ids: [UInt64]): @{NonFungibleToken.Collection} {
|
|
1137
1128
|
// Create a new empty Collection
|
|
1138
1129
|
var batchCollection <- create Collection()
|
|
1139
1130
|
|
|
@@ -1150,7 +1141,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1150
1141
|
//
|
|
1151
1142
|
// Paramters: token: the NFT to be deposited in the collection
|
|
1152
1143
|
//
|
|
1153
|
-
|
|
1144
|
+
access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
|
|
1154
1145
|
|
|
1155
1146
|
// Cast the deposited token as a TopShot NFT to make sure
|
|
1156
1147
|
// it is the correct type
|
|
@@ -1174,7 +1165,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1174
1165
|
|
|
1175
1166
|
// batchDeposit takes a Collection object as an argument
|
|
1176
1167
|
// and deposits each contained NFT into this Collection
|
|
1177
|
-
|
|
1168
|
+
access(all) fun batchDeposit(tokens: @{NonFungibleToken.Collection}) {
|
|
1178
1169
|
|
|
1179
1170
|
// Get an array of the IDs to be deposited
|
|
1180
1171
|
let keys = tokens.getIDs()
|
|
@@ -1190,7 +1181,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1190
1181
|
|
|
1191
1182
|
// lock takes a token id and a duration in seconds and locks
|
|
1192
1183
|
// the moment for that duration
|
|
1193
|
-
|
|
1184
|
+
access(NonFungibleToken.Update) fun lock(id: UInt64, duration: UFix64) {
|
|
1194
1185
|
// Remove the nft from the Collection
|
|
1195
1186
|
let token <- self.ownedNFTs.remove(key: id)
|
|
1196
1187
|
?? panic("Cannot lock: Moment does not exist in the collection")
|
|
@@ -1204,7 +1195,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1204
1195
|
|
|
1205
1196
|
// batchLock takes an array of token ids and a duration in seconds
|
|
1206
1197
|
// it iterates through the ids and locks each for the specified duration
|
|
1207
|
-
|
|
1198
|
+
access(NonFungibleToken.Update) fun batchLock(ids: [UInt64], duration: UFix64) {
|
|
1208
1199
|
// Iterate through the ids and lock them
|
|
1209
1200
|
for id in ids {
|
|
1210
1201
|
self.lock(id: id, duration: duration)
|
|
@@ -1213,7 +1204,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1213
1204
|
|
|
1214
1205
|
// unlock takes a token id and attempts to unlock it
|
|
1215
1206
|
// TopShotLocking.unlockNFT contains business logic around unlock eligibility
|
|
1216
|
-
|
|
1207
|
+
access(NonFungibleToken.Update) fun unlock(id: UInt64) {
|
|
1217
1208
|
// Remove the nft from the Collection
|
|
1218
1209
|
let token <- self.ownedNFTs.remove(key: id)
|
|
1219
1210
|
?? panic("Cannot lock: Moment does not exist in the collection")
|
|
@@ -1227,15 +1218,40 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1227
1218
|
|
|
1228
1219
|
// batchUnlock takes an array of token ids
|
|
1229
1220
|
// it iterates through the ids and unlocks each if they are eligible
|
|
1230
|
-
|
|
1221
|
+
access(NonFungibleToken.Update) fun batchUnlock(ids: [UInt64]) {
|
|
1231
1222
|
// Iterate through the ids and unlocks them
|
|
1232
1223
|
for id in ids {
|
|
1233
1224
|
self.unlock(id: id)
|
|
1234
1225
|
}
|
|
1235
1226
|
}
|
|
1236
1227
|
|
|
1228
|
+
// destroyMoments destroys moments in this collection
|
|
1229
|
+
// unlocks the moments if they are locked
|
|
1230
|
+
//
|
|
1231
|
+
// Parameters: ids: An array of NFT IDs
|
|
1232
|
+
// to be destroyed from the Collection
|
|
1233
|
+
access(NonFungibleToken.Update) fun destroyMoments(ids: [UInt64]) {
|
|
1234
|
+
let topShotLockingAdmin = TopShot.account.storage.borrow<&TopShotLocking.Admin>(from: TopShotLocking.AdminStoragePath())
|
|
1235
|
+
?? panic("No TopShotLocking admin resource in storage")
|
|
1236
|
+
|
|
1237
|
+
for id in ids {
|
|
1238
|
+
// Remove the nft from the Collection
|
|
1239
|
+
let token <- self.ownedNFTs.remove(key: id)
|
|
1240
|
+
?? panic("Cannot destroy: Moment does not exist in collection: ".concat(id.toString()))
|
|
1241
|
+
|
|
1242
|
+
// Emit a withdraw event here so that platforms do not have to understand TopShot-specific events to see ownership change
|
|
1243
|
+
// A withdraw without a corresponding deposit means the NFT in question has no owner address
|
|
1244
|
+
emit Withdraw(id: id, from: self.owner?.address)
|
|
1245
|
+
|
|
1246
|
+
// does nothing if the moment is not locked
|
|
1247
|
+
topShotLockingAdmin.unlockByID(id: id)
|
|
1248
|
+
|
|
1249
|
+
destroy token
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1237
1253
|
// getIDs returns an array of the IDs that are in the Collection
|
|
1238
|
-
|
|
1254
|
+
access(all) view fun getIDs(): [UInt64] {
|
|
1239
1255
|
return self.ownedNFTs.keys
|
|
1240
1256
|
}
|
|
1241
1257
|
|
|
@@ -1250,21 +1266,8 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1250
1266
|
// not any topshot specific data. Please use borrowMoment to
|
|
1251
1267
|
// read Moment data.
|
|
1252
1268
|
//
|
|
1253
|
-
|
|
1254
|
-
return
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
|
-
// Safe way to borrow a reference to an NFT that does not panic
|
|
1258
|
-
// Also now part of the NonFungibleToken.PublicCollection interface
|
|
1259
|
-
//
|
|
1260
|
-
// Parameters: id: The ID of the NFT to get the reference for
|
|
1261
|
-
//
|
|
1262
|
-
// Returns: An optional reference to the desired NFT, will be nil if the passed ID does not exist
|
|
1263
|
-
pub fun borrowNFTSafe(id: UInt64): &NonFungibleToken.NFT? {
|
|
1264
|
-
if let nftRef = &self.ownedNFTs[id] as &NonFungibleToken.NFT? {
|
|
1265
|
-
return nftRef
|
|
1266
|
-
}
|
|
1267
|
-
return nil
|
|
1269
|
+
access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
|
|
1270
|
+
return &self.ownedNFTs[id]
|
|
1268
1271
|
}
|
|
1269
1272
|
|
|
1270
1273
|
// borrowMoment returns a borrowed reference to a Moment
|
|
@@ -1277,29 +1280,17 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1277
1280
|
// Parameters: id: The ID of the NFT to get the reference for
|
|
1278
1281
|
//
|
|
1279
1282
|
// Returns: A reference to the NFT
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
let ref = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
|
|
1283
|
-
return ref as! &TopShot.NFT
|
|
1284
|
-
} else {
|
|
1285
|
-
return nil
|
|
1286
|
-
}
|
|
1283
|
+
access(all) view fun borrowMoment(id: UInt64): &TopShot.NFT? {
|
|
1284
|
+
return self.borrowNFT(id) as! &TopShot.NFT?
|
|
1287
1285
|
}
|
|
1288
1286
|
|
|
1289
|
-
|
|
1290
|
-
let nft =
|
|
1291
|
-
|
|
1292
|
-
|
|
1287
|
+
access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
|
|
1288
|
+
if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
|
|
1289
|
+
return nft as &{ViewResolver.Resolver}
|
|
1290
|
+
}
|
|
1291
|
+
return nil
|
|
1293
1292
|
}
|
|
1294
1293
|
|
|
1295
|
-
// If a transaction destroys the Collection object,
|
|
1296
|
-
// All the NFTs contained within are also destroyed!
|
|
1297
|
-
// Much like when Damian Lillard destroys the hopes and
|
|
1298
|
-
// dreams of the entire city of Houston.
|
|
1299
|
-
//
|
|
1300
|
-
destroy() {
|
|
1301
|
-
destroy self.ownedNFTs
|
|
1302
|
-
}
|
|
1303
1294
|
}
|
|
1304
1295
|
|
|
1305
1296
|
// -----------------------------------------------------------------------
|
|
@@ -1311,14 +1302,17 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1311
1302
|
// Once they have a Collection in their storage, they are able to receive
|
|
1312
1303
|
// Moments in transactions.
|
|
1313
1304
|
//
|
|
1314
|
-
|
|
1305
|
+
access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
|
|
1306
|
+
if nftType != Type<@TopShot.NFT>() {
|
|
1307
|
+
panic("NFT type is not supported")
|
|
1308
|
+
}
|
|
1315
1309
|
return <-create TopShot.Collection()
|
|
1316
1310
|
}
|
|
1317
1311
|
|
|
1318
1312
|
// getAllPlays returns all the plays in topshot
|
|
1319
1313
|
//
|
|
1320
1314
|
// Returns: An array of all the plays that have been created
|
|
1321
|
-
|
|
1315
|
+
access(all) view fun getAllPlays(): [TopShot.Play] {
|
|
1322
1316
|
return TopShot.playDatas.values
|
|
1323
1317
|
}
|
|
1324
1318
|
|
|
@@ -1327,7 +1321,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1327
1321
|
// Parameters: playID: The id of the Play that is being searched
|
|
1328
1322
|
//
|
|
1329
1323
|
// Returns: The metadata as a String to String mapping optional
|
|
1330
|
-
|
|
1324
|
+
access(all) view fun getPlayMetaData(playID: UInt32): {String: String}? {
|
|
1331
1325
|
return self.playDatas[playID]?.metadata
|
|
1332
1326
|
}
|
|
1333
1327
|
|
|
@@ -1340,7 +1334,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1340
1334
|
// field: The field to search for
|
|
1341
1335
|
//
|
|
1342
1336
|
// Returns: The metadata field as a String Optional
|
|
1343
|
-
|
|
1337
|
+
access(all) view fun getPlayMetaDataByField(playID: UInt32, field: String): String? {
|
|
1344
1338
|
// Don't force a revert if the playID or field is invalid
|
|
1345
1339
|
if let play = TopShot.playDatas[playID] {
|
|
1346
1340
|
return play.metadata[field]
|
|
@@ -1355,7 +1349,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1355
1349
|
// Parameters: setID: The id of the Set that is being searched
|
|
1356
1350
|
//
|
|
1357
1351
|
// Returns: The QuerySetData struct that has all the important information about the set
|
|
1358
|
-
|
|
1352
|
+
access(all) fun getSetData(setID: UInt32): QuerySetData? {
|
|
1359
1353
|
if TopShot.sets[setID] == nil {
|
|
1360
1354
|
return nil
|
|
1361
1355
|
} else {
|
|
@@ -1369,7 +1363,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1369
1363
|
// Parameters: setID: The id of the Set that is being searched
|
|
1370
1364
|
//
|
|
1371
1365
|
// Returns: The name of the Set
|
|
1372
|
-
|
|
1366
|
+
access(all) view fun getSetName(setID: UInt32): String? {
|
|
1373
1367
|
// Don't force a revert if the setID is invalid
|
|
1374
1368
|
return TopShot.setDatas[setID]?.name
|
|
1375
1369
|
}
|
|
@@ -1380,7 +1374,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1380
1374
|
// Parameters: setID: The id of the Set that is being searched
|
|
1381
1375
|
//
|
|
1382
1376
|
// Returns: The series that the Set belongs to
|
|
1383
|
-
|
|
1377
|
+
access(all) view fun getSetSeries(setID: UInt32): UInt32? {
|
|
1384
1378
|
// Don't force a revert if the setID is invalid
|
|
1385
1379
|
return TopShot.setDatas[setID]?.series
|
|
1386
1380
|
}
|
|
@@ -1391,7 +1385,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1391
1385
|
// Parameters: setName: The name of the Set that is being searched
|
|
1392
1386
|
//
|
|
1393
1387
|
// Returns: An array of the IDs of the Set if it exists, or nil if doesn't
|
|
1394
|
-
|
|
1388
|
+
access(all) fun getSetIDsByName(setName: String): [UInt32]? {
|
|
1395
1389
|
var setIDs: [UInt32] = []
|
|
1396
1390
|
|
|
1397
1391
|
// Iterate through all the setDatas and search for the name
|
|
@@ -1416,7 +1410,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1416
1410
|
// Parameters: setID: The id of the Set that is being searched
|
|
1417
1411
|
//
|
|
1418
1412
|
// Returns: An array of Play IDs
|
|
1419
|
-
|
|
1413
|
+
access(all) view fun getPlaysInSet(setID: UInt32): [UInt32]? {
|
|
1420
1414
|
// Don't force a revert if the setID is invalid
|
|
1421
1415
|
return TopShot.sets[setID]?.plays
|
|
1422
1416
|
}
|
|
@@ -1430,7 +1424,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1430
1424
|
// playID: The id of the Play that is being searched
|
|
1431
1425
|
//
|
|
1432
1426
|
// Returns: Boolean indicating if the edition is retired or not
|
|
1433
|
-
|
|
1427
|
+
access(all) fun isEditionRetired(setID: UInt32, playID: UInt32): Bool? {
|
|
1434
1428
|
|
|
1435
1429
|
if let setdata = self.getSetData(setID: setID) {
|
|
1436
1430
|
|
|
@@ -1454,7 +1448,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1454
1448
|
// Parameters: setID: The id of the Set that is being searched
|
|
1455
1449
|
//
|
|
1456
1450
|
// Returns: Boolean indicating if the Set is locked or not
|
|
1457
|
-
|
|
1451
|
+
access(all) view fun isSetLocked(setID: UInt32): Bool? {
|
|
1458
1452
|
// Don't force a revert if the setID is invalid
|
|
1459
1453
|
return TopShot.sets[setID]?.locked
|
|
1460
1454
|
}
|
|
@@ -1467,7 +1461,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1467
1461
|
//
|
|
1468
1462
|
// Returns: The total number of Moments
|
|
1469
1463
|
// that have been minted from an edition
|
|
1470
|
-
|
|
1464
|
+
access(all) fun getNumMomentsInEdition(setID: UInt32, playID: UInt32): UInt32? {
|
|
1471
1465
|
if let setdata = self.getSetData(setID: setID) {
|
|
1472
1466
|
|
|
1473
1467
|
// Read the numMintedPerPlay
|
|
@@ -1486,8 +1480,8 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1486
1480
|
//
|
|
1487
1481
|
// returns: UInt32? Subedition's ID if exists
|
|
1488
1482
|
//
|
|
1489
|
-
|
|
1490
|
-
let subeditionAdmin = self.account.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1483
|
+
access(all) view fun getMomentsSubedition(nftID: UInt64):UInt32? {
|
|
1484
|
+
let subeditionAdmin = self.account.storage.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1491
1485
|
?? panic("No subedition admin resource in storage")
|
|
1492
1486
|
|
|
1493
1487
|
return subeditionAdmin.getMomentsSubedition(nftID: nftID)
|
|
@@ -1496,8 +1490,8 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1496
1490
|
// getAllSubeditions returns all the subeditions in topshot subeditionAdmin resource
|
|
1497
1491
|
//
|
|
1498
1492
|
// Returns: An array of all the subeditions that have been created
|
|
1499
|
-
|
|
1500
|
-
let subeditionAdmin = self.account.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1493
|
+
access(all) view fun getAllSubeditions(): &[TopShot.Subedition] {
|
|
1494
|
+
let subeditionAdmin = self.account.storage.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1501
1495
|
?? panic("No subedition admin resource in storage")
|
|
1502
1496
|
return subeditionAdmin.subeditionDatas.values
|
|
1503
1497
|
}
|
|
@@ -1507,8 +1501,8 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1507
1501
|
// Parameters: subeditionID: The id of the Subedition that is being searched
|
|
1508
1502
|
//
|
|
1509
1503
|
// Returns: The Subedition struct
|
|
1510
|
-
|
|
1511
|
-
let subeditionAdmin = self.account.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1504
|
+
access(all) view fun getSubeditionByID(subeditionID: UInt32): &TopShot.Subedition {
|
|
1505
|
+
let subeditionAdmin = self.account.storage.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1512
1506
|
?? panic("No subedition admin resource in storage")
|
|
1513
1507
|
return subeditionAdmin.subeditionDatas[subeditionID]!
|
|
1514
1508
|
}
|
|
@@ -1518,19 +1512,19 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1518
1512
|
//
|
|
1519
1513
|
// Returns: UInt32
|
|
1520
1514
|
// the next number in nextSubeditionID from the SubeditionAdmin resource
|
|
1521
|
-
|
|
1522
|
-
let subeditionAdmin = self.account.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1515
|
+
access(all) view fun getNextSubeditionID():UInt32 {
|
|
1516
|
+
let subeditionAdmin = self.account.storage.borrow<&SubeditionAdmin>(from: TopShot.SubeditionAdminStoragePath())
|
|
1523
1517
|
?? panic("No subedition admin resource in storage")
|
|
1524
1518
|
return subeditionAdmin.nextSubeditionID
|
|
1525
1519
|
}
|
|
1526
1520
|
// SubeditionAdmin is a resource that allows Set to mint Moments with Subeditions
|
|
1527
1521
|
//
|
|
1528
|
-
|
|
1529
|
-
|
|
1522
|
+
access(all) struct Subedition {
|
|
1523
|
+
access(all) let subeditionID: UInt32
|
|
1530
1524
|
|
|
1531
|
-
|
|
1525
|
+
access(all) let name: String
|
|
1532
1526
|
|
|
1533
|
-
|
|
1527
|
+
access(all) let metadata: {String: String}
|
|
1534
1528
|
|
|
1535
1529
|
init(subeditionID: UInt32, name: String, metadata: {String: String}) {
|
|
1536
1530
|
pre {
|
|
@@ -1542,7 +1536,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1542
1536
|
}
|
|
1543
1537
|
}
|
|
1544
1538
|
|
|
1545
|
-
|
|
1539
|
+
access(all) resource SubeditionAdmin {
|
|
1546
1540
|
|
|
1547
1541
|
// Map of number of already minted Moments using Subedition.
|
|
1548
1542
|
// When a new Moment with Subedition is minted, 1 is added to the
|
|
@@ -1570,7 +1564,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1570
1564
|
//
|
|
1571
1565
|
// Returns: the ID of the new Subedition object
|
|
1572
1566
|
//
|
|
1573
|
-
|
|
1567
|
+
access(all) fun createSubedition(name:String, metadata:{String:String}): UInt32 {
|
|
1574
1568
|
|
|
1575
1569
|
let newID = self.nextSubeditionID
|
|
1576
1570
|
|
|
@@ -1591,7 +1585,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1591
1585
|
//
|
|
1592
1586
|
// returns: UInt32? Subedition's ID if exists
|
|
1593
1587
|
//
|
|
1594
|
-
|
|
1588
|
+
access(all) view fun getMomentsSubedition(nftID: UInt64):UInt32? {
|
|
1595
1589
|
return self.momentsSubedition[nftID]
|
|
1596
1590
|
}
|
|
1597
1591
|
|
|
@@ -1605,7 +1599,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1605
1599
|
//
|
|
1606
1600
|
// returns: UInt32 Number of Moments, already minted for this Subedition
|
|
1607
1601
|
//
|
|
1608
|
-
|
|
1602
|
+
access(all) fun getNumberMintedPerSubedition(setID: UInt32, playID: UInt32, subeditionID: UInt32): UInt32 {
|
|
1609
1603
|
let setPlaySubedition = setID.toString().concat(playID.toString()).concat(subeditionID.toString())
|
|
1610
1604
|
if !self.numberMintedPerSubedition.containsKey(setPlaySubedition) {
|
|
1611
1605
|
self.numberMintedPerSubedition.insert(key: setPlaySubedition,UInt32(0))
|
|
@@ -1622,7 +1616,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1622
1616
|
// subeditionID: The ID of the Subedition using which moment will be minted
|
|
1623
1617
|
//
|
|
1624
1618
|
//
|
|
1625
|
-
|
|
1619
|
+
access(all) fun addToNumberMintedPerSubedition(setID: UInt32, playID: UInt32, subeditionID: UInt32) {
|
|
1626
1620
|
let setPlaySubedition = setID.toString().concat(playID.toString()).concat(subeditionID.toString())
|
|
1627
1621
|
|
|
1628
1622
|
if !self.numberMintedPerSubedition.containsKey(setPlaySubedition) {
|
|
@@ -1639,7 +1633,7 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1639
1633
|
// setID: The ID of the Set that the Moment references
|
|
1640
1634
|
// playID: The ID of the Play that the Moment references
|
|
1641
1635
|
//
|
|
1642
|
-
|
|
1636
|
+
access(all) fun setMomentsSubedition(nftID: UInt64, subeditionID: UInt32, setID: UInt32, playID: UInt32){
|
|
1643
1637
|
pre {
|
|
1644
1638
|
!self.momentsSubedition.containsKey(nftID) : "Subedition for this moment already exists!"
|
|
1645
1639
|
}
|
|
@@ -1657,6 +1651,74 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1657
1651
|
}
|
|
1658
1652
|
}
|
|
1659
1653
|
|
|
1654
|
+
//------------------------------------------------------------
|
|
1655
|
+
// Contract MetadataViews
|
|
1656
|
+
//------------------------------------------------------------
|
|
1657
|
+
|
|
1658
|
+
/// Return the metadata view types available for this contract
|
|
1659
|
+
///
|
|
1660
|
+
access(all) view fun getContractViews(resourceType: Type?): [Type] {
|
|
1661
|
+
return [Type<MetadataViews.NFTCollectionData>(), Type<MetadataViews.NFTCollectionDisplay>(), Type<MetadataViews.Royalties>()]
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
/// Resolve this contract's metadata views
|
|
1665
|
+
///
|
|
1666
|
+
access(all) view fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
|
|
1667
|
+
post {
|
|
1668
|
+
result == nil || result!.getType() == viewType: "The returned view must be of the given type or nil"
|
|
1669
|
+
}
|
|
1670
|
+
switch viewType {
|
|
1671
|
+
case Type<MetadataViews.NFTCollectionData>():
|
|
1672
|
+
return MetadataViews.NFTCollectionData(
|
|
1673
|
+
storagePath: /storage/MomentCollection,
|
|
1674
|
+
publicPath: /public/MomentCollection,
|
|
1675
|
+
publicCollection: Type<&TopShot.Collection>(),
|
|
1676
|
+
publicLinkedType: Type<&TopShot.Collection>(),
|
|
1677
|
+
createEmptyCollectionFunction: (fun (): @{NonFungibleToken.Collection} {
|
|
1678
|
+
return <-TopShot.createEmptyCollection(nftType: Type<@TopShot.NFT>())
|
|
1679
|
+
})
|
|
1680
|
+
)
|
|
1681
|
+
case Type<MetadataViews.NFTCollectionDisplay>():
|
|
1682
|
+
let bannerImage = MetadataViews.Media(
|
|
1683
|
+
file: MetadataViews.HTTPFile(
|
|
1684
|
+
url: "https://nbatopshot.com/static/img/top-shot-logo-horizontal-white.svg"
|
|
1685
|
+
),
|
|
1686
|
+
mediaType: "image/svg+xml"
|
|
1687
|
+
)
|
|
1688
|
+
let squareImage = MetadataViews.Media(
|
|
1689
|
+
file: MetadataViews.HTTPFile(
|
|
1690
|
+
url: "https://nbatopshot.com/static/img/og/og.png"
|
|
1691
|
+
),
|
|
1692
|
+
mediaType: "image/png"
|
|
1693
|
+
)
|
|
1694
|
+
return MetadataViews.NFTCollectionDisplay(
|
|
1695
|
+
name: "NBA-Top-Shot",
|
|
1696
|
+
description: "NBA Top Shot is your chance to own, sell, and trade official digital collectibles of the NBA and WNBA's greatest plays and players",
|
|
1697
|
+
externalURL: MetadataViews.ExternalURL("https://nbatopshot.com"),
|
|
1698
|
+
squareImage: squareImage,
|
|
1699
|
+
bannerImage: bannerImage,
|
|
1700
|
+
socials: {
|
|
1701
|
+
"twitter": MetadataViews.ExternalURL("https://twitter.com/nbatopshot"),
|
|
1702
|
+
"discord": MetadataViews.ExternalURL("https://discord.com/invite/nbatopshot"),
|
|
1703
|
+
"instagram": MetadataViews.ExternalURL("https://www.instagram.com/nbatopshot")
|
|
1704
|
+
}
|
|
1705
|
+
)
|
|
1706
|
+
case Type<MetadataViews.Royalties>():
|
|
1707
|
+
let royaltyReceiver: Capability<&{FungibleToken.Receiver}> =
|
|
1708
|
+
getAccount(TopShot.RoyaltyAddress()).capabilities.get<&{FungibleToken.Receiver}>(MetadataViews.getRoyaltyReceiverPublicPath())!
|
|
1709
|
+
return MetadataViews.Royalties(
|
|
1710
|
+
[
|
|
1711
|
+
MetadataViews.Royalty(
|
|
1712
|
+
receiver: royaltyReceiver,
|
|
1713
|
+
cut: 0.05,
|
|
1714
|
+
description: "NBATopShot marketplace royalty"
|
|
1715
|
+
)
|
|
1716
|
+
]
|
|
1717
|
+
)
|
|
1718
|
+
}
|
|
1719
|
+
return nil
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1660
1722
|
|
|
1661
1723
|
// -----------------------------------------------------------------------
|
|
1662
1724
|
// TopShot initialization function
|
|
@@ -1673,13 +1735,15 @@ pub contract TopShot: NonFungibleToken {
|
|
|
1673
1735
|
self.totalSupply = 0
|
|
1674
1736
|
|
|
1675
1737
|
// Put a new Collection in storage
|
|
1676
|
-
self.account.save<@Collection>(<- create Collection(), to: /storage/MomentCollection)
|
|
1738
|
+
self.account.storage.save<@Collection>(<- create Collection(), to: /storage/MomentCollection)
|
|
1677
1739
|
|
|
1678
1740
|
// Create a public capability for the Collection
|
|
1679
|
-
self.account.
|
|
1741
|
+
let cap = self.account.capabilities.storage.issue<&TopShot.Collection>(/storage/MomentCollection)
|
|
1742
|
+
self.account.capabilities.publish(cap, at: /public/MomentCollection)
|
|
1743
|
+
//self.account.link<&{MomentCollectionPublic}>(/public/MomentCollection, target: /storage/MomentCollection)
|
|
1680
1744
|
|
|
1681
1745
|
// Put the Minter in storage
|
|
1682
|
-
self.account.save<@Admin>(<- create Admin(), to: /storage/TopShotAdmin)
|
|
1746
|
+
self.account.storage.save<@Admin>(<- create Admin(), to: /storage/TopShotAdmin)
|
|
1683
1747
|
|
|
1684
1748
|
emit ContractInitialized()
|
|
1685
1749
|
}
|