Skip to content

Commit

Permalink
use latest contracts and consolidate flow.json
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuahannan committed Apr 26, 2024
1 parent 51e56b2 commit 46062ad
Show file tree
Hide file tree
Showing 20 changed files with 372 additions and 385 deletions.
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,12 @@ update-mainnet:

.PHONY: update-testnet
update-testnet:
$(MAKE) flow accounts update-contract NFTStorefrontV2 ./contracts/NFTStorefrontV2.cdc --signer testnet-account --network testnet -f ./flow.testnet.json
$(MAKE) flow accounts update-contract NFTStorefrontV2 ./contracts/NFTStorefrontV2.cdc --signer testnet-account --network testnet -f ./flow.testnet.json

.PHONY: test
test:
flow-c1 test --cover --covercode="contracts" tests/*.cdc

.PHONY: ci
ci:
flow-c1 test --cover --covercode="contracts" tests/*.cdc
20 changes: 10 additions & 10 deletions contracts/NFTStorefrontV2.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import NonFungibleToken from "./utility/NonFungibleToken.cdc"
///
access(all) contract NFTStorefrontV2 {

access(all) entitlement Creatable
access(all) entitlement Removable
access(all) entitlement CreateListing
access(all) entitlement RemoveListing

/// StorefrontInitialized
/// A Storefront resource has been created.
Expand Down Expand Up @@ -240,12 +240,12 @@ access(all) contract NFTStorefrontV2 {
/// getAllowedCommissionReceivers
/// Fetches the allowed marketplaces capabilities or commission receivers.
/// If it returns `nil` then commission is up to grab by anyone.
access(all) fun getAllowedCommissionReceivers(): [Capability<&{FungibleToken.Receiver}>]?
access(all) view fun getAllowedCommissionReceivers(): [Capability<&{FungibleToken.Receiver}>]?

/// hasListingBecomeGhosted
/// Tells whether listed NFT is present in provided capability.
/// If it returns `false` then it means listing becomes ghost or sold out.
access(all) fun hasListingBecomeGhosted(): Bool
access(all) view fun hasListingBecomeGhosted(): Bool

}

Expand Down Expand Up @@ -291,14 +291,14 @@ access(all) contract NFTStorefrontV2 {
/// getAllowedCommissionReceivers
/// Fetches the allowed marketplaces capabilities or commission receivers.
/// If it returns `nil` then commission is up to grab by anyone.
access(all) fun getAllowedCommissionReceivers(): [Capability<&{FungibleToken.Receiver}>]? {
access(all) view fun getAllowedCommissionReceivers(): [Capability<&{FungibleToken.Receiver}>]? {
return self.marketplacesCapability
}

/// hasListingBecomeGhosted
/// Tells whether listed NFT is present in provided capability.
/// If it returns `false` then it means listing becomes ghost or sold out.
access(all) fun hasListingBecomeGhosted(): Bool {
access(all) view fun hasListingBecomeGhosted(): Bool {
if let providerRef = self.nftProviderCapability.borrow() {
let availableIDs = providerRef.getIDs()
return availableIDs.contains(self.details.nftID)
Expand Down Expand Up @@ -498,7 +498,7 @@ access(all) contract NFTStorefrontV2 {
/// createListing
/// Allows the Storefront owner to create and insert Listings.
///
access(Creatable) fun createListing(
access(CreateListing) fun createListing(
nftProviderCapability: Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Collection}>,
nftType: Type,
nftID: UInt64,
Expand All @@ -513,7 +513,7 @@ access(all) contract NFTStorefrontV2 {
/// removeListing
/// Allows the Storefront owner to remove any sale listing, accepted or not.
///
access(Removable) fun removeListing(listingResourceID: UInt64)
access(RemoveListing) fun removeListing(listingResourceID: UInt64)
}

/// StorefrontPublic
Expand Down Expand Up @@ -550,7 +550,7 @@ access(all) contract NFTStorefrontV2 {
/// insert
/// Create and publish a Listing for an NFT.
///
access(Creatable) fun createListing(
access(CreateListing) fun createListing(
nftProviderCapability: Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Collection}>,
nftType: Type,
nftID: UInt64,
Expand Down Expand Up @@ -651,7 +651,7 @@ access(all) contract NFTStorefrontV2 {
/// Remove a Listing that has not yet been purchased from the collection and destroy it.
/// It can only be executed by the StorefrontManager resource owner.
///
access(Removable) fun removeListing(listingResourceID: UInt64) {
access(RemoveListing) fun removeListing(listingResourceID: UInt64) {
let listing <- self.listings.remove(key: listingResourceID)
?? panic("missing Listing")
let listingDetails = listing.getDetails()
Expand Down
74 changes: 38 additions & 36 deletions contracts/utility/ExampleNFT.cdc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
*
* This is an example implementation of a Flow Non-Fungible Token
* using the V2 standard.
Expand All @@ -7,23 +7,26 @@
*
* This contract does not implement any sophisticated classification
* system for its NFTs. It defines a simple NFT with minimal metadata.
*
*
*/

import NonFungibleToken from "NonFungibleToken"
import ViewResolver from "ViewResolver"
import MetadataViews from "MetadataViews"
import "NonFungibleToken"
import "ViewResolver"
import "MetadataViews"

access(all) contract ExampleNFT: NonFungibleToken {
access(all) event Minted(id: UInt64, uuid: UInt64)

/// Standard Paths
access(all) let CollectionStoragePath: StoragePath
access(all) let CollectionPublicPath: PublicPath

/// Path where the minter should be stored
/// The standard paths for the collection are stored in the collection resource type
access(all) let MinterStoragePath: StoragePath

/// We choose the name NFT here, but this type can have any name now
/// because the interface does not require it to have a specific name any more
access(all) resource NFT: NonFungibleToken.NFT, ViewResolver.Resolver {
access(all) resource NFT: NonFungibleToken.NFT {

access(all) let id: UInt64

Expand All @@ -37,7 +40,7 @@ access(all) contract ExampleNFT: NonFungibleToken {

/// Generic dictionary of traits the NFT has
access(self) let metadata: {String: AnyStruct}

init(
name: String,
description: String,
Expand All @@ -59,7 +62,7 @@ access(all) contract ExampleNFT: NonFungibleToken {
access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
return <-ExampleNFT.createEmptyCollection(nftType: Type<@ExampleNFT.NFT>())
}

access(all) view fun getViews(): [Type] {
return [
Type<MetadataViews.Display>(),
Expand Down Expand Up @@ -118,26 +121,23 @@ access(all) contract ExampleNFT: NonFungibleToken {
let fooTraitRarity = MetadataViews.Rarity(score: 10.0, max: 100.0, description: "Common")
let fooTrait = MetadataViews.Trait(name: "foo", value: self.metadata["foo"], displayType: nil, rarity: fooTraitRarity)
traitsView.addTrait(fooTrait)

return traitsView
}
return nil
}
}

access(all) resource Collection: NonFungibleToken.Collection {
// Deprecated: Only here for backward compatibility.
access(all) resource interface ExampleNFTCollectionPublic {}

access(all) resource Collection: NonFungibleToken.Collection, ExampleNFTCollectionPublic {
/// dictionary of NFT conforming tokens
/// NFT is a resource type with an `UInt64` ID field
access(contract) var ownedNFTs: @{UInt64: ExampleNFT.NFT}

access(all) var storagePath: StoragePath
access(all) var publicPath: PublicPath
access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}

init () {
self.ownedNFTs <- {}
let identifier = "cadenceExampleNFTCollection"
self.storagePath = StoragePath(identifier: identifier)!
self.publicPath = PublicPath(identifier: identifier)!
}

/// getSupportedNFTTypes returns a list of NFT types that this receiver accepts
Expand All @@ -150,11 +150,7 @@ access(all) contract ExampleNFT: NonFungibleToken {
/// Returns whether or not the given type is accepted by the collection
/// A collection that can accept any type should just return true by default
access(all) view fun isSupportedNFTType(type: Type): Bool {
if type == Type<@ExampleNFT.NFT>() {
return true
} else {
return false
}
return type == Type<@ExampleNFT.NFT>()
}

/// withdraw removes an NFT from the collection and moves it to the caller
Expand All @@ -169,11 +165,20 @@ access(all) contract ExampleNFT: NonFungibleToken {
/// and adds the ID to the id array
access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
let token <- token as! @ExampleNFT.NFT
let id = token.id

// add the new token to the dictionary which removes the old one
let oldToken <- self.ownedNFTs[token.id] <- token

destroy oldToken

// This code is for testing purposes only
// Do not add to your contract unless you have a specific
// reason to want to emit the NFTUpdated event somewhere
// in your contract
let authTokenRef = (&self.ownedNFTs[id] as auth(NonFungibleToken.Owner) &{NonFungibleToken.NFT}?)!
//authTokenRef.updateTransferDate(date: getCurrentBlock().timestamp)
ExampleNFT.emitNFTUpdated(authTokenRef)
}

/// getIDs returns an array of the IDs that are in the collection
Expand All @@ -183,7 +188,7 @@ access(all) contract ExampleNFT: NonFungibleToken {

/// Gets the amount of NFTs stored in the collection
access(all) view fun getLength(): Int {
return self.ownedNFTs.keys.length
return self.ownedNFTs.length
}

access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
Expand All @@ -192,7 +197,7 @@ access(all) contract ExampleNFT: NonFungibleToken {

/// Borrow the view resolver for the specified NFT ID
access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
if let nft = &self.ownedNFTs[id] as &ExampleNFT.NFT? {
if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
return nft as &{ViewResolver.Resolver}
}
return nil
Expand Down Expand Up @@ -233,8 +238,8 @@ access(all) contract ExampleNFT: NonFungibleToken {
switch viewType {
case Type<MetadataViews.NFTCollectionData>():
let collectionData = MetadataViews.NFTCollectionData(
storagePath: /storage/cadenceExampleNFTCollection,
publicPath: /public/cadenceExampleNFTCollection,
storagePath: self.CollectionStoragePath,
publicPath: self.CollectionPublicPath,
publicCollection: Type<&ExampleNFT.Collection>(),
publicLinkedType: Type<&ExampleNFT.Collection>(),
createEmptyCollectionFunction: (fun(): @{NonFungibleToken.Collection} {
Expand Down Expand Up @@ -294,30 +299,27 @@ access(all) contract ExampleNFT: NonFungibleToken {
metadata: metadata,
)

emit Minted(id: newNFT.id, uuid: newNFT.uuid)

return <-newNFT
}
}

init() {

// Set the named paths
self.MinterStoragePath = /storage/cadenceExampleNFTMinter
self.CollectionStoragePath = /storage/exampleNFTCollection
self.CollectionPublicPath = /public/exampleNFTCollection
self.MinterStoragePath = /storage/exampleNFTMinter

// Create a Collection resource and save it to storage
let collection <- create Collection()
let defaultStoragePath = collection.storagePath
let defaultPublicPath = collection.publicPath
self.account.storage.save(<-collection, to: defaultStoragePath)
self.account.storage.save(<-collection, to: self.CollectionStoragePath)

// create a public capability for the collection
let collectionCap = self.account.capabilities.storage.issue<&ExampleNFT.Collection>(defaultStoragePath)
self.account.capabilities.publish(collectionCap, at: defaultPublicPath)
let collectionCap = self.account.capabilities.storage.issue<&ExampleNFT.Collection>(self.CollectionStoragePath)
self.account.capabilities.publish(collectionCap, at: self.CollectionPublicPath)

// Create a Minter resource and save it to storage
let minter <- create NFTMinter()
self.account.storage.save(<-minter, to: self.MinterStoragePath)
}
}

33 changes: 15 additions & 18 deletions contracts/utility/ExampleToken.cdc
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import FungibleToken from "FungibleToken"
import MetadataViews from "MetadataViews"
import FungibleTokenMetadataViews from "FungibleTokenMetadataViews"
import ViewResolver from "ViewResolver"
import "FungibleToken"
import "MetadataViews"
import "FungibleTokenMetadataViews"

access(all) contract ExampleToken: FungibleToken {

Expand All @@ -11,7 +10,10 @@ access(all) contract ExampleToken: FungibleToken {
/// Total supply of ExampleTokens in existence
access(all) var totalSupply: UFix64

/// Admin Path
/// Storage and Public Paths
access(all) let VaultStoragePath: StoragePath
access(all) let VaultPublicPath: PublicPath
access(all) let ReceiverPublicPath: PublicPath
access(all) let AdminStoragePath: StoragePath

access(all) view fun getContractViews(resourceType: Type?): [Type] {
Expand Down Expand Up @@ -84,17 +86,9 @@ access(all) contract ExampleToken: FungibleToken {
/// The total balance of this vault
access(all) var balance: UFix64

access(all) var storagePath: StoragePath
access(all) var publicPath: PublicPath
access(all) var receiverPath: PublicPath

// initialize the balance at resource creation time
init(balance: UFix64) {
self.balance = balance
let identifier = "exampleTokenVault"
self.storagePath = StoragePath(identifier: identifier)!
self.publicPath = PublicPath(identifier: identifier)!
self.receiverPath = PublicPath(identifier: "exampleTokenReceiver")!
}

/// Called when a fungible token is burned via the `Burner.burn()` method
Expand Down Expand Up @@ -203,6 +197,9 @@ access(all) contract ExampleToken: FungibleToken {
init() {
self.totalSupply = 1000.0

self.VaultStoragePath = /storage/exampleTokenVault
self.VaultPublicPath = /public/exampleTokenVault
self.ReceiverPublicPath = /public/exampleTokenReceiver
self.AdminStoragePath = /storage/exampleTokenAdmin

// Create the Vault with the total supply of tokens and save it in storage
Expand All @@ -213,14 +210,14 @@ access(all) contract ExampleToken: FungibleToken {
// the `deposit` method and getAcceptedTypes method through the `Receiver` interface
// and the `balance` method through the `Balance` interface
//
let exampleTokenCap = self.account.capabilities.storage.issue<&ExampleToken.Vault>(vault.storagePath)
self.account.capabilities.publish(exampleTokenCap, at: vault.publicPath)
let receiverCap = self.account.capabilities.storage.issue<&ExampleToken.Vault>(vault.storagePath)
self.account.capabilities.publish(receiverCap, at: vault.receiverPath)
let exampleTokenCap = self.account.capabilities.storage.issue<&ExampleToken.Vault>(self.VaultStoragePath)
self.account.capabilities.publish(exampleTokenCap, at: self.VaultPublicPath)
let receiverCap = self.account.capabilities.storage.issue<&ExampleToken.Vault>(self.VaultStoragePath)
self.account.capabilities.publish(receiverCap, at: self.ReceiverPublicPath)

self.account.storage.save(<-vault, to: /storage/exampleTokenVault)

let admin <- create Minter()
self.account.storage.save(<-admin, to: self.AdminStoragePath)
}
}
}
Loading

0 comments on commit 46062ad

Please sign in to comment.