diff --git a/contracts/AllDay.cdc b/contracts/AllDay.cdc index 1c3ea15..8f444a1 100644 --- a/contracts/AllDay.cdc +++ b/contracts/AllDay.cdc @@ -72,6 +72,7 @@ pub contract AllDay: NonFungibleToken { playID: UInt64, maxMintSize: UInt64?, tier: String, + deserialized: Bool?, ) // Emitted when an edition is either closed by an admin, or the max amount of moments have been minted pub event EditionClosed(id: UInt64) @@ -398,6 +399,8 @@ pub contract AllDay: NonFungibleToken { pub var maxMintSize: UInt64? pub let tier: String pub var numMinted: UInt64 + pub let deserialized: Bool? + pub let presetSerial: UInt64? // member function to check if max edition size has been reached pub fun maxEditionMintSizeReached(): Bool { @@ -415,6 +418,8 @@ pub contract AllDay: NonFungibleToken { self.maxMintSize = edition.maxMintSize self.tier = edition.tier self.numMinted = edition.numMinted + self.deserialized = edition.deserialized + self.presetSerial = edition.presetSerial } else { panic("edition does not exist") } @@ -433,6 +438,8 @@ pub contract AllDay: NonFungibleToken { pub var maxMintSize: UInt64? // Updates each time we mint a new moment for the Edition to keep a running total pub var numMinted: UInt64 + pub let deserialized: Bool? + pub let presetSerial: UInt64? // Close this edition so that no more Moment NFTs can be minted in it // @@ -454,11 +461,16 @@ pub contract AllDay: NonFungibleToken { self.numMinted != self.maxMintSize: "max number of minted moments has been reached" } + var serial = self.numMinted + 1 + if self.deserialized != nil { + serial = self.presetSerial! + } + // Create the Moment NFT, filled out with our information let momentNFT <- create NFT( id: AllDay.totalSupply + 1, editionID: self.id, - serialNumber: self.numMinted + 1 + serialNumber: serial ) AllDay.totalSupply = AllDay.totalSupply + 1 // Keep a running total (you'll notice we used this as the serial number) @@ -475,6 +487,8 @@ pub contract AllDay: NonFungibleToken { playID: UInt64, maxMintSize: UInt64?, tier: String, + deserialized: Bool?, + presetSerial: UInt64? ) { pre { maxMintSize != 0: "max mint size is zero, must either be null or greater than 0" @@ -483,6 +497,7 @@ pub contract AllDay: NonFungibleToken { AllDay.playByID.containsKey(playID): "playID does not exist" SeriesData(id: seriesID).active == true: "cannot create an Edition with a closed Series" AllDay.getPlayTierExistsInEdition(setID, playID, tier) == false: "set play tier combination already exists in an edition" + deserialized != nil && presetSerial != nil || deserialized == nil && presetSerial == nil: "preset serial must be set if deserialized is true" } self.id = AllDay.nextEditionID @@ -499,6 +514,8 @@ pub contract AllDay: NonFungibleToken { self.tier = tier self.numMinted = 0 as UInt64 + self.deserialized = deserialized + self.presetSerial = presetSerial AllDay.nextEditionID = AllDay.nextEditionID + 1 as UInt64 AllDay.setByID[setID]?.insertNewPlay(playID: playID) @@ -511,6 +528,7 @@ pub contract AllDay: NonFungibleToken { playID: self.playID, maxMintSize: self.maxMintSize, tier: self.tier, + deserialized: deserialized, ) } } @@ -1060,13 +1078,17 @@ pub contract AllDay: NonFungibleToken { setID: UInt64, playID: UInt64, maxMintSize: UInt64?, - tier: String): UInt64 { + tier: String, + deserialized: Bool?, + presetSerial: UInt64?): UInt64 { let edition <- create Edition( seriesID: seriesID, setID: setID, playID: playID, maxMintSize: maxMintSize, tier: tier, + deserialized: deserialized, + presetSerial: presetSerial, ) let editionID = edition.id AllDay.editionByID[edition.id] <-! edition diff --git a/lib/go/test/allday_test.go b/lib/go/test/allday_test.go index 530d382..c98e2e7 100644 --- a/lib/go/test/allday_test.go +++ b/lib/go/test/allday_test.go @@ -1,9 +1,10 @@ package test import ( + "testing" + "github.com/onflow/cadence" "github.com/onflow/cadence/fixedpoint" - "testing" emulator "github.com/onflow/flow-emulator" "github.com/onflow/flow-go-sdk" @@ -274,6 +275,8 @@ func testCreateEdition( playID uint64, maxMintSize *uint64, tier string, + deserialized *bool, + presetSerial *uint64, shouldBeID uint64, shouldRevert bool, ) { @@ -286,6 +289,8 @@ func testCreateEdition( playID, maxMintSize, tier, + deserialized, + presetSerial, shouldRevert, ) @@ -299,6 +304,12 @@ func testCreateEdition( if maxMintSize != nil { assert.Equal(t, &maxMintSize, &edition.MaxMintSize) } + if deserialized != nil { + assert.Equal(t, &deserialized, &edition.Deserialized) + } + if presetSerial != nil { + assert.Equal(t, &presetSerial, &edition.PresetSerial) + } } } @@ -326,6 +337,8 @@ func testCloseEdition( func createTestEditions(t *testing.T, b *emulator.Blockchain, contracts Contracts) { var maxMintSize uint64 = 2 + var deserialized bool = true + var presetSerial uint64 = 2023 createTestSeries(t, b, contracts) createTestSets(t, b, contracts) createTestPlays(t, b, contracts) @@ -340,6 +353,8 @@ func createTestEditions(t *testing.T, b *emulator.Blockchain, contracts Contract 1, &maxMintSize, "COMMON", + nil, + nil, 1, false, ) @@ -355,6 +370,8 @@ func createTestEditions(t *testing.T, b *emulator.Blockchain, contracts Contract 1, nil, "COMMON", + nil, + nil, 2, false, ) @@ -370,6 +387,8 @@ func createTestEditions(t *testing.T, b *emulator.Blockchain, contracts Contract 2, nil, "COMMON", + nil, + nil, 3, false, ) @@ -385,6 +404,8 @@ func createTestEditions(t *testing.T, b *emulator.Blockchain, contracts Contract 1, nil, "COMMON", + nil, + nil, 4, true, ) @@ -393,13 +414,13 @@ func createTestEditions(t *testing.T, b *emulator.Blockchain, contracts Contract t.Run("Should be able to create an Edition with a Set/Play combination that already exists but with a different tier", func(t *testing.T) { //Mint LEGENDARY edition testCreateEdition(t, b, contracts, 1 /*seriesID*/, 1 /*setID*/, 2 /*playID*/, nil, - "LEGENDARY" /*tier*/, 4 /*shouldBEID*/, false /*shouldRevert*/) + "LEGENDARY" /*tier*/, nil /*deserialized*/, nil /*presetSerial*/, 4 /*shouldBEID*/, false /*shouldRevert*/) }) t.Run("Should NOT be able to mint new edition using the same set/play with new tier", func(t *testing.T) { //Mint COMMON edition again, tx should revert testCreateEdition(t, b, contracts, 1 /*seriesID*/, 1 /*setID*/, 2 /*playID*/, nil, - "COMMON" /*tier*/, 5 /*shouldBEID*/, true /*shouldRevert*/) + "COMMON" /*tier*/, nil /*deserialized*/, nil /*presetSerial*/, 5 /*shouldBEID*/, true /*shouldRevert*/) }) t.Run("Should be able to close and edition that has no max mint size", func(t *testing.T) { @@ -412,6 +433,23 @@ func createTestEditions(t *testing.T, b *emulator.Blockchain, contracts Contract false, ) }) + + t.Run("Should be able to create a deserialized edition and set the serial number", func(t *testing.T) { + testCreateEdition( + t, + b, + contracts, + 1, + 1, + 1, + nil, + "COMMON", + &deserialized, + &presetSerial, + 5, + true, + ) + }) } // ------------------------------------------------------------ diff --git a/lib/go/test/transactions.go b/lib/go/test/transactions.go index 082a7fe..a61a3f3 100644 --- a/lib/go/test/transactions.go +++ b/lib/go/test/transactions.go @@ -1,9 +1,10 @@ package test import ( - "github.com/stretchr/testify/require" "testing" + "github.com/stretchr/testify/require" + "github.com/onflow/cadence" emulator "github.com/onflow/flow-emulator" fttemplates "github.com/onflow/flow-ft/lib/go/templates" @@ -237,6 +238,8 @@ func createEdition( playID uint64, maxMintSize *uint64, tier string, + deserialized *bool, + presetSerial *uint64, shouldRevert bool, ) { tierString, _ := cadence.NewString(tier) @@ -256,6 +259,17 @@ func createEdition( tx.AddArgument(cadence.Optional{}) } + if deserialized != nil { + tx.AddArgument(cadence.NewBool(*deserialized)) + } else { + tx.AddArgument(cadence.Optional{}) + } + + if presetSerial != nil { + tx.AddArgument(cadence.NewUInt64(*presetSerial)) + } else { + tx.AddArgument(cadence.Optional{}) + } signer, err := b.ServiceKey().Signer() require.NoError(t, err) signAndSubmit( diff --git a/lib/go/test/types.go b/lib/go/test/types.go index c910e11..2585901 100644 --- a/lib/go/test/types.go +++ b/lib/go/test/types.go @@ -19,12 +19,14 @@ type PlayData struct { Metadata map[string]string } type EditionData struct { - ID uint64 - SeriesID uint64 - SetID uint64 - PlayID uint64 - MaxMintSize *uint64 - Tier string + ID uint64 + SeriesID uint64 + SetID uint64 + PlayID uint64 + MaxMintSize *uint64 + Tier string + Deserialized *bool + PresetSerial *uint64 } type OurNFTData struct { ID uint64 @@ -74,6 +76,16 @@ func parseEditionData(value cadence.Value) EditionData { if fields[4] != nil && fields[4].ToGoValue() != nil { maxMintSize = fields[4].ToGoValue().(uint64) } + + var deserialized bool + if fields[7] != nil && fields[7].ToGoValue() != nil { + deserialized = fields[7].ToGoValue().(bool) + } + + var presetSerial uint64 + if fields[8] != nil && fields[8].ToGoValue() != nil { + presetSerial = fields[8].ToGoValue().(uint64) + } return EditionData{ fields[0].ToGoValue().(uint64), fields[1].ToGoValue().(uint64), @@ -81,6 +93,8 @@ func parseEditionData(value cadence.Value) EditionData { fields[3].ToGoValue().(uint64), &maxMintSize, fields[5].ToGoValue().(string), + &deserialized, + &presetSerial, } } diff --git a/transactions/admin/editions/create_edition.cdc b/transactions/admin/editions/create_edition.cdc index e8e586b..8e621e6 100644 --- a/transactions/admin/editions/create_edition.cdc +++ b/transactions/admin/editions/create_edition.cdc @@ -6,6 +6,8 @@ transaction( playID: UInt64, tier: String, maxMintSize: UInt64?, + deserialized: Bool?, + presetSerial: UInt64?, ) { // local variable for the admin reference let admin: &AllDay.Admin @@ -23,6 +25,8 @@ transaction( playID: playID, maxMintSize: maxMintSize, tier: tier, + deserialized: deserialized, + presetSerial: presetSerial, ) log("====================================")