Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add type definition for DropSummary #8

Merged
merged 4 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions contracts/DropFactory.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ pub contract DropFactory {
price: UFix64,
paymentTokenType: Type,
dropDisplay: MetadataViews.Display,
minterCap: Capability<&{FlowtyDrops.Minter}>
minterCap: Capability<&{FlowtyDrops.Minter}>,
nftTypeIdentifier: String
): @FlowtyDrops.Drop {
pre {
paymentTokenType.isSubtype(of: Type<@FungibleToken.Vault>()): "paymentTokenType must be a FungibleToken"
Expand All @@ -32,7 +33,9 @@ pub contract DropFactory {
let phaseDetails = FlowtyDrops.PhaseDetails(switcher: switcher, display: nil, pricer: pricer, addressVerifier: addressVerifier)
let phase <- FlowtyDrops.createPhase(details: phaseDetails)

let dropDetails = FlowtyDrops.DropDetails(display: dropDisplay, medias: nil, commissionRate: 0.05)

let nftType = CompositeType(nftTypeIdentifier) ?? panic("invalid nft type identifier")
let dropDetails = FlowtyDrops.DropDetails(display: dropDisplay, medias: nil, commissionRate: 0.05, nftType: nftType)
let drop <- FlowtyDrops.createDrop(details: dropDetails, minterCap: minterCap, phases: <- [<-phase])

return <- drop
Expand All @@ -44,7 +47,8 @@ pub contract DropFactory {
dropDisplay: MetadataViews.Display,
minterCap: Capability<&{FlowtyDrops.Minter}>,
startUnix: UInt64?,
endUnix: UInt64?
endUnix: UInt64?,
nftTypeIdentifier: String
): @FlowtyDrops.Drop {
pre {
paymentTokenType.isSubtype(of: Type<@FungibleToken.Vault>()): "paymentTokenType must be a FungibleToken"
Expand All @@ -62,7 +66,8 @@ pub contract DropFactory {
let phaseDetails = FlowtyDrops.PhaseDetails(switcher: switcher, display: nil, pricer: pricer, addressVerifier: addressVerifier)
let phase <- FlowtyDrops.createPhase(details: phaseDetails)

let dropDetails = FlowtyDrops.DropDetails(display: dropDisplay, medias: nil, commissionRate: 0.05)
let nftType = CompositeType(nftTypeIdentifier) ?? panic("invalid nft type identifier")
let dropDetails = FlowtyDrops.DropDetails(display: dropDisplay, medias: nil, commissionRate: 0.05, nftType: nftType)
let drop <- FlowtyDrops.createDrop(details: dropDetails, minterCap: minterCap, phases: <- [<-phase])

return <- drop
Expand Down
152 changes: 152 additions & 0 deletions contracts/DropTypes.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import "FlowtyDrops"
import "MetadataViews"
import "ViewResolver"

pub contract DropTypes {
pub struct DropSummary {
pub let id: UInt64
pub let display: MetadataViews.Display
pub let medias: MetadataViews.Medias?
pub let totalMinted: Int
pub let minterCount: Int
pub let commissionRate: UFix64
pub let nftType: String

pub let address: Address?
pub let mintedByAddress: Int?

pub let phases: [PhaseSummary]

pub let blockTimestamp: UInt64
pub let blockHeight: UInt64

init(
id: UInt64,
display: MetadataViews.Display,
medias: MetadataViews.Medias?,
totalMinted: Int,
minterCount: Int,
mintedByAddress: Int?,
commissionRate: UFix64,
nftType: Type,
address: Address?,
phases: [PhaseSummary]
) {
self.id = id
self.display = display
self.medias = medias
self.totalMinted = totalMinted
self.commissionRate = commissionRate
self.minterCount = minterCount
self.mintedByAddress = mintedByAddress
self.nftType = nftType.identifier
self.address = address
self.phases = phases

let b = getCurrentBlock()
self.blockHeight = b.height
self.blockTimestamp = UInt64(b.timestamp)
}
}

pub struct PhaseSummary {
pub let id: UInt64
pub let index: Int

pub let switcherType: String
pub let pricerType: String
pub let addressVerifierType: String

pub let hasStarted: Bool
pub let hasEnded: Bool
pub let start: UInt64?
pub let end: UInt64?

pub let paymentTypes: [String]

pub let address: Address?
pub let remainingForAddress: Int?

init(
index: Int,
phase: &{FlowtyDrops.PhasePublic},
address: Address?,
totalMinted: Int?
) {
self.index = index
self.id = phase.uuid

let d = phase.getDetails()
self.switcherType = d.switcher.getType().identifier
self.pricerType = d.pricer.getType().identifier
self.addressVerifierType = d.addressVerifier.getType().identifier

self.hasStarted = d.switcher.hasStarted()
self.hasEnded = d.switcher.hasEnded()
self.start = d.switcher.getStart()
self.end = d.switcher.getEnd()

self.paymentTypes = []
for pt in d.pricer.getPaymentTypes() {
self.paymentTypes.append(pt.identifier)
}

if let addr = address {
self.address = address
self.remainingForAddress = d.addressVerifier.remainingForAddress(addr: addr, totalMinted: totalMinted ?? 0)
} else {
self.address = nil
self.remainingForAddress = nil
}
}
}

pub fun getDropSummary(contractAddress: Address, contractName: String, dropID: UInt64, minter: Address?): DropSummary? {
let resolver = getAccount(contractAddress).contracts.borrow<&ViewResolver>(name: contractName)
if resolver == nil {
return nil
}

let dropResolver = resolver!.resolveView(Type<FlowtyDrops.DropResolver>()) as! FlowtyDrops.DropResolver?
if dropResolver == nil {
return nil
}

let container = dropResolver!.borrowContainer()
if container == nil {
return nil
}

let drop = container!.borrowDropPublic(id: dropID)
if drop == nil {
return nil
}

let dropDetails = drop!.getDetails()

let phaseSummaries: [PhaseSummary] = []
for index, phase in drop!.borrowAllPhases() {
let summary = PhaseSummary(
index: 0,
phase: phase,
address: minter,
totalMinted: minter != nil ? dropDetails.minters[minter!] : nil
)
}

let dropSummary = DropSummary(
id: drop!.uuid,
display: dropDetails.display,
medias: dropDetails.medias,
totalMinted: dropDetails.totalMinted,
minterCount: dropDetails.minters.keys.length,
mintedByAddress: minter != nil ? dropDetails.minters[minter!] : nil,
commissionRate: dropDetails.commissionRate,
nftType: dropDetails.nftType,
address: minter,
phases: phaseSummaries
)

return dropSummary
}
}
4 changes: 3 additions & 1 deletion contracts/FlowtyDrops.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ pub contract FlowtyDrops {
pub var totalMinted: Int
pub var minters: {Address: Int}
pub let commissionRate: UFix64
pub let nftType: Type

access(contract) fun addMinted(num: Int, addr: Address) {
self.totalMinted = self.totalMinted + num
Expand All @@ -194,12 +195,13 @@ pub contract FlowtyDrops {
self.minters[addr] = self.minters[addr]! + num
}

init(display: MetadataViews.Display, medias: MetadataViews.Medias?, commissionRate: UFix64) {
init(display: MetadataViews.Display, medias: MetadataViews.Medias?, commissionRate: UFix64, nftType: Type) {
self.display = display
self.medias = medias
self.totalMinted = 0
self.commissionRate = commissionRate
self.minters = {}
self.nftType = nftType
}
}

Expand Down
7 changes: 7 additions & 0 deletions flow.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@
"testing": "0x0000000000000006"
}
},
"DropTypes": {
"source": "./contracts/DropTypes.cdc",
"aliases": {
"testing": "0x0000000000000008"
}
},
"OpenEditionNFT": {
"source": "./contracts/nft/OpenEditionNFT.cdc",
"aliases": {
Expand Down Expand Up @@ -148,6 +154,7 @@
"FlowtyAddressVerifiers",
"FlowtyPricers",
"DropFactory",
"DropTypes",
"OpenEditionNFT",
"NonFungibleToken",
"ViewResolver",
Expand Down
5 changes: 5 additions & 0 deletions scripts/get_drop_summary.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import "DropTypes"

pub fun main(contractAddress: Address, contractName: String, dropID: UInt64, minter: Address?): DropTypes.DropSummary? {
return DropTypes.getDropSummary(contractAddress: contractAddress, contractName: contractName, dropID: dropID, minter: minter)
}
41 changes: 39 additions & 2 deletions tests/FlowtyDrops_tests.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "FlowToken"
import "FlowtyDrops"
import "OpenEditionNFT"
import "ExampleToken"
import "DropTypes"

pub let defaultEndlessOpenEditionName = "Default Endless Open Edition"

Expand Down Expand Up @@ -144,6 +145,40 @@ pub fun test_OpenEditionNFT_addPhase() {
Test.assert(!activePhaseIDs.contains(phaseEvent.id), message: "unexpected active phase length")
}

pub fun test_OpenEditionNFT_getDropSummary() {
let dropID = createDefaultTimeBasedOpenEditionDrop()

let minter = Test.createAccount()
setupExampleToken(minter)
mintExampleTokens(minter, 100.0)

let summary = scriptExecutor("get_drop_summary.cdc", [openEditionAccount.address, "OpenEditionNFT", dropID, minter.address])! as! DropTypes.DropSummary
Test.assertEqual(minter.address, summary.address!)

let numToMint = 5
let totalCost = 5.0

mintDrop(
minter: minter,
contractAddress: openEditionAccount.address,
contractName: "OpenEditionNFT",
numToMint: numToMint,
totalCost: totalCost,
paymentIdentifier: exampleTokenIdentifier(),
paymentStoragePath: exampleTokenStoragePath,
paymentReceiverPath: exampleTokenReceiverPath,
dropID: dropID,
dropPhaseIndex: 0,
nftIdentifier: Type<@OpenEditionNFT.NFT>().identifier,
commissionAddress: flowtyDropsAccount.address
)

let summaryAfter = scriptExecutor("get_drop_summary.cdc", [openEditionAccount.address, "OpenEditionNFT", dropID, minter.address])! as! DropTypes.DropSummary
Test.assertEqual(summaryAfter.totalMinted, numToMint)
Test.assertEqual(summaryAfter.mintedByAddress!, numToMint)

}

// ------------------------------------------------------------------------
// Helper functions section

Expand All @@ -156,7 +191,8 @@ pub fun createDefaultEndlessOpenEditionDrop(): UInt64 {
ipfsPath: nil,
price: 1.0,
paymentIdentifier: exampleTokenIdentifier(),
minterPrivatePath: FlowtyDrops.MinterPrivatePath
minterPrivatePath: FlowtyDrops.MinterPrivatePath,
nftTypeIdentifier: openEditionNftIdentifier()
)
}

Expand All @@ -173,7 +209,8 @@ pub fun createDefaultTimeBasedOpenEditionDrop(): UInt64 {
paymentIdentifier: exampleTokenIdentifier(),
startUnix: UInt64(getCurrentTime()),
endUnix: UInt64(currentTime + 5.0),
minterPrivatePath: FlowtyDrops.MinterPrivatePath
minterPrivatePath: FlowtyDrops.MinterPrivatePath,
nftTypeIdentifier: openEditionNftIdentifier()
)
}

Expand Down
20 changes: 16 additions & 4 deletions tests/test_helpers.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "NonFungibleToken"
import "FlowToken"
import "FlowtyDrops"
import "ExampleToken"
import "OpenEditionNFT"

// Helper functions. All of the following were taken from
// https://github.com/onflow/Offers/blob/fd380659f0836e5ce401aa99a2975166b2da5cb0/lib/cadence/test/Offers.cdc
Expand Down Expand Up @@ -164,12 +165,17 @@ pub let flowTokenReceiverPath = /public/flowTokenReceiver
pub fun deployAll() {
deploy("ExampleToken", "../contracts/standard/ExampleToken.cdc", [])

// 0x6
deploy("FlowtyDrops", "../contracts/FlowtyDrops.cdc", [])
deploy("FlowtySwitchers", "../contracts/FlowtySwitchers.cdc", [])
deploy("FlowtyPricers", "../contracts/FlowtyPricers.cdc", [])
deploy("FlowtyAddressVerifiers", "../contracts/FlowtyAddressVerifiers.cdc", [])
deploy("DropFactory", "../contracts/DropFactory.cdc", [])

// 0x8
deploy("DropTypes", "../contracts/DropTypes.cdc", [])

// 0x7
deploy("OpenEditionNFT", "../contracts/nft/OpenEditionNFT.cdc", [])


Expand Down Expand Up @@ -235,10 +241,11 @@ pub fun createEndlessOpenEditionDrop(
ipfsPath: String?,
price: UFix64,
paymentIdentifier: String,
minterPrivatePath: PrivatePath
minterPrivatePath: PrivatePath,
nftTypeIdentifier: String
): UInt64 {
txExecutor("drops/add_endless_open_edition.cdc", [acct], [
name, description, ipfsCid, ipfsPath, price, paymentIdentifier, minterPrivatePath
name, description, ipfsCid, ipfsPath, price, paymentIdentifier, minterPrivatePath, nftTypeIdentifier
], nil, nil)

let e = Test.eventsOfType(Type<FlowtyDrops.DropAdded>()).removeLast() as! FlowtyDrops.DropAdded
Expand All @@ -255,10 +262,11 @@ pub fun createTimebasedOpenEditionDrop(
paymentIdentifier: String,
startUnix: UInt64?,
endUnix: UInt64?,
minterPrivatePath: PrivatePath
minterPrivatePath: PrivatePath,
nftTypeIdentifier: String
): UInt64 {
txExecutor("drops/add_time_based_open_edition.cdc", [acct], [
name, description, ipfsCid, ipfsPath, price, paymentIdentifier, startUnix, endUnix, minterPrivatePath
name, description, ipfsCid, ipfsPath, price, paymentIdentifier, startUnix, endUnix, minterPrivatePath, nftTypeIdentifier
], nil, nil)

let e = Test.eventsOfType(Type<FlowtyDrops.DropAdded>()).removeLast() as! FlowtyDrops.DropAdded
Expand All @@ -281,6 +289,10 @@ pub fun exampleTokenIdentifier(): String {
return Type<@ExampleToken.Vault>().identifier
}

pub fun openEditionNftIdentifier(): String {
return Type<@OpenEditionNFT.NFT>().identifier
}

pub fun hasDropPhaseStarted(contractAddress: Address, contractName: String, dropID: UInt64, phaseIndex: Int): Bool {
return scriptExecutor("has_phase_started.cdc", [contractAddress, contractName, dropID, phaseIndex])! as! Bool
}
Expand Down
5 changes: 3 additions & 2 deletions transactions/drops/add_endless_open_edition.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ transaction(
ipfsPath: String?,
price: UFix64,
paymentIdentifier: String,
minterPrivatePath: PrivatePath
minterPrivatePath: PrivatePath,
nftTypeIdentifier: String
) {
prepare(acct: AuthAccount) {
if acct.borrow<&AnyResource>(from: FlowtyDrops.ContainerStoragePath) == nil {
Expand All @@ -33,7 +34,7 @@ transaction(
description: description,
thumbnail: MetadataViews.IPFSFile(cid: ipfsCid, path: ipfsPath)
)
let drop <- DropFactory.createEndlessOpenEditionDrop(price: 1.0, paymentTokenType: paymentType, dropDisplay: dropDisplay, minterCap: minter)
let drop <- DropFactory.createEndlessOpenEditionDrop(price: 1.0, paymentTokenType: paymentType, dropDisplay: dropDisplay, minterCap: minter, nftTypeIdentifier: nftTypeIdentifier)
container.addDrop(<- drop)
}
}
Loading
Loading