Skip to content

Commit

Permalink
add creator to DropTypes.DropSummary struct (#41)
Browse files Browse the repository at this point in the history
* add creator to DropTypes.DropSummary struct
  • Loading branch information
austinkline authored Sep 20, 2024
1 parent 93d8816 commit 1e0964a
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 31 deletions.
42 changes: 39 additions & 3 deletions contracts/DropTypes.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import "FlowtyDrops"
import "MetadataViews"
import "ViewResolver"
import "AddressUtils"
import "ContractManager"

access(all) contract DropTypes {
access(all) struct Display {
Expand Down Expand Up @@ -34,6 +35,7 @@ access(all) contract DropTypes {
access(all) let minterCount: Int
access(all) let commissionRate: UFix64
access(all) let nftType: String
access(all) let creator: Address?

access(all) let address: Address?
access(all) let mintedByAddress: Int?
Expand All @@ -55,10 +57,12 @@ access(all) contract DropTypes {
nftType: Type,
address: Address?,
phases: [PhaseSummary],
royaltyRate: UFix64
royaltyRate: UFix64,
creator: Address?
) {
self.id = id
self.display = Display(display)
self.creator = creator

self.medias = []
for m in medias?.items ?? [] {
Expand Down Expand Up @@ -169,6 +173,8 @@ access(all) contract DropTypes {
let contractAddress = AddressUtils.parseAddress(nftType)!
let contractName = segments[2]

let creator = self.getCreatorAddress(contractAddress)

let resolver = getAccount(contractAddress).contracts.borrow<&{ViewResolver}>(name: contractName)
if resolver == nil {
return nil
Expand Down Expand Up @@ -224,7 +230,8 @@ access(all) contract DropTypes {
nftType: CompositeType(dropDetails.nftType)!,
address: minter,
phases: phaseSummaries,
royaltyRate: royaltyRate
royaltyRate: royaltyRate,
creator: creator
)

return dropSummary
Expand All @@ -235,6 +242,8 @@ access(all) contract DropTypes {
let segments = nftTypeIdentifier.split(separator: ".")
let contractAddress = AddressUtils.parseAddress(nftType)!
let contractName = segments[2]

let creator = self.getCreatorAddress(contractAddress)

let resolver = getAccount(contractAddress).contracts.borrow<&{ViewResolver}>(name: contractName)
if resolver == nil {
Expand Down Expand Up @@ -297,10 +306,37 @@ access(all) contract DropTypes {
nftType: CompositeType(dropDetails.nftType)!,
address: minter,
phases: phaseSummaries,
royaltyRate: royaltyRate
royaltyRate: royaltyRate,
creator: creator
))
}

return summaries
}

access(all) fun getCreatorAddress(_ contractAddress: Address): Address? {
// We look for a two-way relationship between creator and collection. A contract can expose an address at ContractManager.OwnerPublicPath
// specifying the owning account. If found, we will check that same account for a &ContractManager.Manager resource at ContractManager.PublicPath,
// which, when borrowed, can return its underlying account address using &Manager.getAccount().
//
// If the addresses match, we consider this account to be the creator of a drop
let tmp = getAccount(contractAddress).capabilities.borrow<&Address>(ContractManager.OwnerPublicPath)
if tmp == nil {
return nil
}

let creator = *(tmp!)
let manager = getAccount(creator).capabilities.borrow<&ContractManager.Manager>(ContractManager.PublicPath)
if manager == nil {
return nil
}

let contractManagerAccount = manager!.getAccount()

if contractManagerAccount.address != contractAddress {
return nil
}

return creator
}
}
19 changes: 5 additions & 14 deletions flow.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,18 @@
},
"emulator-account": {
"address": "f8d6e0586b0a20c7",
"key": {
"type": "file",
"location": "emulator-account.pkey"
}
"key": "f2e846bd4c1fbf17839ae59e111c6b1c98579eda7a841412f102d6621ec671cb"
},
"emulator-ft": {
"address": "ee82856bf20e2aa6",
"key": {
"type": "file",
"location": "emulator-account.pkey"
}
"key": "f2e846bd4c1fbf17839ae59e111c6b1c98579eda7a841412f102d6621ec671cb"
},
"emulator-flowtoken": {
"address": "0ae53cb6e3f42a79",
"key": {
"type": "file",
"location": "emulator-account.pkey"
}
"key": "f2e846bd4c1fbf17839ae59e111c6b1c98579eda7a841412f102d6621ec671cb"
},
"flowty-drops-testnet": {
"address": "0x772a10c786851a1b",
"address": "0x155bce6ac93f3e00",
"key": {
"type": "google-kms",
"index": 0,
Expand All @@ -42,7 +33,7 @@
}
},
"droptypes-testnet": {
"address": "0x22f23883bf122007",
"address": "0x53ff16309e318ae2",
"key": {
"type": "google-kms",
"index": 0,
Expand Down
17 changes: 17 additions & 0 deletions tests/ContractManager_tests.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Test
import "./test_helpers.cdc"
import "ContractManager"

access(all) fun setup() {
deployAll()
}

access(all) fun test_SetupContractManager() {
let acct = Test.createAccount()
mintFlowTokens(acct, 10.0)

txExecutor("contract-manager/setup.cdc", [acct], [1.0])

let savedEvent = Test.eventsOfType(Type<ContractManager.ManagerSaved>()).removeLast() as! ContractManager.ManagerSaved
Test.assertEqual(acct.address, savedEvent.ownerAddress)
}
14 changes: 7 additions & 7 deletions tests/FlowtyDrops_tests.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ access(all) fun setup() {
}

access(all) fun afterEach() {
txExecutor("drops/remove_all_drops.cdc", [openEditionAccount], [], nil, nil)
txExecutor("drops/remove_all_drops.cdc", [openEditionAccount], [])
}

access(all) fun testImports() {
Expand Down Expand Up @@ -91,7 +91,7 @@ access(all) fun test_OpenEditionNFT_EditPhaseDetails() {
let currentTime = getCurrentTime()
let newStart = UInt64(currentTime + 5.0)

txExecutor("drops/edit_timebased_phase_start_and_end.cdc", [openEditionAccount], [dropID, 0, newStart, newStart + 5], nil, nil)
txExecutor("drops/edit_timebased_phase_start_and_end.cdc", [openEditionAccount], [dropID, 0, newStart, newStart + 5])
Test.assertEqual(false, hasDropPhaseStarted(nftTypeIdentifier: openEditionNftIdentifier(), dropID: dropID, phaseIndex: 0))
Test.assertEqual(false, hasDropPhaseEnded(nftTypeIdentifier: openEditionNftIdentifier(), dropID: dropID, phaseIndex: 0))

Expand All @@ -109,14 +109,14 @@ access(all) fun test_OpenEditionNFT_EditPrice() {
let dropID = createDefaultTimeBasedOpenEditionDrop()
Test.assertEqual(1.0, getPriceAtPhase(nftTypeIdentifier: openEditionNftIdentifier(), dropID: dropID, phaseIndex: 0, minter: openEditionAccount.address, numToMint: 1, paymentIdentifier: flowTokenIdentifier()))

txExecutor("drops/edit_flat_price.cdc", [openEditionAccount], [dropID, 0, 2.0], nil, nil)
txExecutor("drops/edit_flat_price.cdc", [openEditionAccount], [dropID, 0, 2.0])
Test.assertEqual(2.0, getPriceAtPhase(nftTypeIdentifier: openEditionNftIdentifier(), dropID: dropID, phaseIndex: 0, minter: openEditionAccount.address, numToMint: 1, paymentIdentifier: flowTokenIdentifier()))
}

access(all) fun test_OpenEditionNFT_EditMaxPerMint() {
let dropID = createDefaultTimeBasedOpenEditionDrop()
Test.assertEqual(true, canMintAtPhase(nftTypeIdentifier: openEditionNftIdentifier(), dropID: dropID, phaseIndex: 0, minter: openEditionAccount.address, numToMint: 10, totalMinted: 0, paymentIdentifier: flowTokenIdentifier()))
txExecutor("drops/edit_address_verifier_max_per_mint.cdc", [openEditionAccount], [dropID, 0, 5], nil, nil)
txExecutor("drops/edit_address_verifier_max_per_mint.cdc", [openEditionAccount], [dropID, 0, 5])

Test.assertEqual(false, canMintAtPhase(nftTypeIdentifier: openEditionNftIdentifier(), dropID: dropID, phaseIndex: 0, minter: openEditionAccount.address, numToMint: 10, totalMinted: 0, paymentIdentifier: flowTokenIdentifier()))
Test.assertEqual(true, canMintAtPhase(nftTypeIdentifier: openEditionNftIdentifier(), dropID: dropID, phaseIndex: 0, minter: openEditionAccount.address, numToMint: 5, totalMinted: 0, paymentIdentifier: flowTokenIdentifier()))
Expand All @@ -131,13 +131,13 @@ access(all) fun test_OpenEditionNFT_GetActivePhases() {
access(all) fun test_OpenEditionNFT_addPhase() {
let dropID = createDefaultTimeBasedOpenEditionDrop()

txExecutor("drops/add_free_phase.cdc", [openEditionAccount], [dropID, nil, nil, "https://example.com/fake_image.jpg"], nil, nil)
txExecutor("drops/add_free_phase.cdc", [openEditionAccount], [dropID, nil, nil, "https://example.com/fake_image.jpg"])
let phaseEvent = Test.eventsOfType(Type<FlowtyDrops.PhaseAdded>()).removeLast() as! FlowtyDrops.PhaseAdded

var activePhaseIDs = scriptExecutor("get_active_phases.cdc", [openEditionNftIdentifier(), dropID])! as! [UInt64]
Test.assert(activePhaseIDs.contains(phaseEvent.id), message: "unexpected active phase length")

txExecutor("drops/remove_last_phase.cdc", [openEditionAccount], [dropID, nil, nil], nil, nil)
txExecutor("drops/remove_last_phase.cdc", [openEditionAccount], [dropID, nil, nil])
activePhaseIDs = scriptExecutor("get_active_phases.cdc", [openEditionNftIdentifier(), dropID])! as! [UInt64]
Test.assert(!activePhaseIDs.contains(phaseEvent.id), message: "unexpected active phase length")
}
Expand Down Expand Up @@ -251,7 +251,7 @@ access(all) fun mintDrop(
): [UInt64] {
txExecutor("drops/mint.cdc", [minter], [
nftTypeIdentifier, numToMint, totalCost, paymentIdentifier, paymentStoragePath, paymentReceiverPath, dropID, dropPhaseIndex, nftIdentifier, commissionAddress
], nil, nil)
])

let ids: [UInt64] = []
let events = Test.eventsOfType(Type<FlowtyDrops.Minted>())
Expand Down
14 changes: 7 additions & 7 deletions tests/test_helpers.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ access(all) fun expectScriptFailure(_ scriptName: String, _ arguments: [AnyStruc
return scriptResult.error!.message
}

access(all) fun txExecutor(_ txName: String, _ signers: [Test.TestAccount], _ arguments: [AnyStruct], _ expectedError: String?, _ expectedErrorType: ErrorType?): Test.TransactionResult {
access(all) fun txExecutor(_ txName: String, _ signers: [Test.TestAccount], _ arguments: [AnyStruct]): Test.TransactionResult {
let txCode = loadCode(txName, "transactions")

let authorizers: [Address] = []
Expand Down Expand Up @@ -173,7 +173,7 @@ access(all) fun deploy(_ name: String, _ path: String, _ arguments: [AnyStruct])
}

access(all) fun heartbeat() {
txExecutor("util/heartbeat.cdc", [serviceAccount], [], nil, nil)
txExecutor("util/heartbeat.cdc", [serviceAccount], [])
}

access(all) fun getCurrentTime(): UFix64 {
Expand Down Expand Up @@ -205,7 +205,7 @@ access(all) fun mintFromDrop(
nftIdentifier,
commissionReceiver
]
txExecutor("drops/mint.cdc", [minter], args, nil, nil)
txExecutor("drops/mint.cdc", [minter], args)
}

access(all) fun getDropIDs(
Expand All @@ -227,7 +227,7 @@ access(all) fun createEndlessOpenEditionDrop(
): UInt64 {
txExecutor("drops/add_endless_open_edition.cdc", [acct], [
name, description, ipfsCid, ipfsPath, price, paymentIdentifier, minterControllerID, nftTypeIdentifier
], nil, nil)
])

let e = Test.eventsOfType(Type<FlowtyDrops.DropAdded>()).removeLast() as! FlowtyDrops.DropAdded
return e.id
Expand All @@ -248,18 +248,18 @@ access(all) fun createTimebasedOpenEditionDrop(
): UInt64 {
txExecutor("drops/add_time_based_open_edition.cdc", [acct], [
name, description, ipfsCid, ipfsPath, price, paymentIdentifier, startUnix, endUnix, minterControllerID, nftTypeIdentifier
], nil, nil)
])

let e = Test.eventsOfType(Type<FlowtyDrops.DropAdded>()).removeLast() as! FlowtyDrops.DropAdded
return e.id
}

access(all) fun sendFlowTokens(fromAccount: Test.TestAccount, toAccount: Test.TestAccount, amount: UFix64) {
txExecutor("util/send_flow_tokens.cdc", [fromAccount], [toAccount.address, amount], nil, nil)
txExecutor("util/send_flow_tokens.cdc", [fromAccount], [toAccount.address, amount])
}

access(all) fun mintFlowTokens(_ acct: Test.TestAccount, _ amount: UFix64) {
txExecutor("flow-token/mint.cdc", [serviceAccount], [acct.address, amount], nil, nil)
txExecutor("flow-token/mint.cdc", [serviceAccount], [acct.address, amount])
}

access(all) fun flowTokenIdentifier(): String {
Expand Down

0 comments on commit 1e0964a

Please sign in to comment.