From 604e8720783deabe113de5d1f9b619783bf5228e Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Fri, 1 Sep 2023 10:52:48 -0500 Subject: [PATCH] FungibleToken Factory Manager Setup Transaction (#152) Closes: #151 --- .../factories/FTReceiverBalanceFactory.cdc | 10 +++ flow.json | 11 +++ scripts/test/get_ft_all_factory.cdc | 13 +++ scripts/test/get_ft_balance_factory.cdc | 13 +++ scripts/test/get_ft_provider_factory.cdc | 13 +++ .../test/get_ft_receiver_balance_factory.cdc | 13 +++ scripts/test/get_ft_receiver_factory.cdc | 13 +++ .../get_nft_collection_public_factory.cdc | 13 +++ .../get_nft_provider_collection_factory.cdc | 13 +++ scripts/test/get_nft_provider_factory.cdc | 13 +++ test/CapabilityFactory_tests.cdc | 89 +++++++++++++++++-- test/HybridCustody_tests.cdc | 8 +- transactions/example-token/setup.cdc | 2 +- .../{setup.cdc => setup_ft_manager.cdc} | 15 ++-- transactions/factory/setup_nft_ft_manager.cdc | 8 +- transactions/factory/setup_nft_manager.cdc | 5 +- 16 files changed, 229 insertions(+), 23 deletions(-) create mode 100644 contracts/factories/FTReceiverBalanceFactory.cdc create mode 100644 scripts/test/get_ft_all_factory.cdc create mode 100644 scripts/test/get_ft_balance_factory.cdc create mode 100644 scripts/test/get_ft_provider_factory.cdc create mode 100644 scripts/test/get_ft_receiver_balance_factory.cdc create mode 100644 scripts/test/get_ft_receiver_factory.cdc create mode 100644 scripts/test/get_nft_collection_public_factory.cdc create mode 100644 scripts/test/get_nft_provider_collection_factory.cdc create mode 100644 scripts/test/get_nft_provider_factory.cdc rename transactions/factory/{setup.cdc => setup_ft_manager.cdc} (73%) diff --git a/contracts/factories/FTReceiverBalanceFactory.cdc b/contracts/factories/FTReceiverBalanceFactory.cdc new file mode 100644 index 0000000..49673d5 --- /dev/null +++ b/contracts/factories/FTReceiverBalanceFactory.cdc @@ -0,0 +1,10 @@ +import "CapabilityFactory" +import "FungibleToken" + +pub contract FTReceiverBalanceFactory { + pub struct Factory: CapabilityFactory.Factory { + pub fun getCapability(acct: &AuthAccount, path: CapabilityPath): Capability { + return acct.getCapability<&{FungibleToken.Receiver, FungibleToken.Balance}>(path) + } + } +} \ No newline at end of file diff --git a/flow.json b/flow.json index b6f8c2f..525b043 100644 --- a/flow.json +++ b/flow.json @@ -73,6 +73,14 @@ "mainnet": "d8a7e05a7ac670c0" } }, + "FTReceiverBalanceFactory": { + "source": "./contracts/factories/FTReceiverBalanceFactory.cdc", + "aliases": { + "emulator": "f8d6e0586b0a20c7", + "testnet": "294e44e1ec6993c6", + "mainnet": "d8a7e05a7ac670c0" + } + }, "FTReceiverFactory": { "source": "./contracts/factories/FTReceiverFactory.cdc", "aliases": { @@ -233,6 +241,7 @@ "FTProviderFactory", "FTAllFactory", "FTBalanceFactory", + "FTReceiverBalanceFactory", "FTReceiverFactory", "NFTProviderFactory", "NFTProviderAndCollectionFactory", @@ -257,6 +266,7 @@ "FTProviderFactory", "FTAllFactory", "FTBalanceFactory", + "FTReceiverBalanceFactory", "FTReceiverFactory" ] }, @@ -272,6 +282,7 @@ "FTProviderFactory", "FTAllFactory", "FTBalanceFactory", + "FTReceiverBalanceFactory", "FTReceiverFactory" ] } diff --git a/scripts/test/get_ft_all_factory.cdc b/scripts/test/get_ft_all_factory.cdc new file mode 100644 index 0000000..122b57a --- /dev/null +++ b/scripts/test/get_ft_all_factory.cdc @@ -0,0 +1,13 @@ +import "FungibleToken" + +import "CapabilityFactory" + +pub fun main(address: Address): Bool { + + let managerRef = getAuthAccount(address).borrow<&CapabilityFactory.Manager>(from: CapabilityFactory.StoragePath) + ?? panic("CapabilityFactory Manager not found") + + let ftAllFactory = managerRef.getFactory(Type<&{FungibleToken.Provider, FungibleToken.Receiver, FungibleToken.Balance}>()) + + return ftAllFactory != nil +} \ No newline at end of file diff --git a/scripts/test/get_ft_balance_factory.cdc b/scripts/test/get_ft_balance_factory.cdc new file mode 100644 index 0000000..219afd1 --- /dev/null +++ b/scripts/test/get_ft_balance_factory.cdc @@ -0,0 +1,13 @@ +import "FungibleToken" + +import "CapabilityFactory" + +pub fun main(address: Address): Bool { + + let managerRef = getAuthAccount(address).borrow<&CapabilityFactory.Manager>(from: CapabilityFactory.StoragePath) + ?? panic("CapabilityFactory Manager not found") + + let balanceFactory = managerRef.getFactory(Type<&{FungibleToken.Balance}>()) + + return balanceFactory != nil +} \ No newline at end of file diff --git a/scripts/test/get_ft_provider_factory.cdc b/scripts/test/get_ft_provider_factory.cdc new file mode 100644 index 0000000..257065b --- /dev/null +++ b/scripts/test/get_ft_provider_factory.cdc @@ -0,0 +1,13 @@ +import "FungibleToken" + +import "CapabilityFactory" + +pub fun main(address: Address): Bool { + + let managerRef = getAuthAccount(address).borrow<&CapabilityFactory.Manager>(from: CapabilityFactory.StoragePath) + ?? panic("CapabilityFactory Manager not found") + + let providerFactory = managerRef.getFactory(Type<&{FungibleToken.Provider}>()) + + return providerFactory != nil +} \ No newline at end of file diff --git a/scripts/test/get_ft_receiver_balance_factory.cdc b/scripts/test/get_ft_receiver_balance_factory.cdc new file mode 100644 index 0000000..c8c6fc7 --- /dev/null +++ b/scripts/test/get_ft_receiver_balance_factory.cdc @@ -0,0 +1,13 @@ +import "FungibleToken" + +import "CapabilityFactory" + +pub fun main(address: Address): Bool { + + let managerRef = getAuthAccount(address).borrow<&CapabilityFactory.Manager>(from: CapabilityFactory.StoragePath) + ?? panic("CapabilityFactory Manager not found") + + let receiverBalanceFactory = managerRef.getFactory(Type<&{FungibleToken.Receiver, FungibleToken.Balance}>()) + + return receiverBalanceFactory != nil +} \ No newline at end of file diff --git a/scripts/test/get_ft_receiver_factory.cdc b/scripts/test/get_ft_receiver_factory.cdc new file mode 100644 index 0000000..5b058be --- /dev/null +++ b/scripts/test/get_ft_receiver_factory.cdc @@ -0,0 +1,13 @@ +import "FungibleToken" + +import "CapabilityFactory" + +pub fun main(address: Address): Bool { + + let managerRef = getAuthAccount(address).borrow<&CapabilityFactory.Manager>(from: CapabilityFactory.StoragePath) + ?? panic("CapabilityFactory Manager not found") + + let receiverFactory = managerRef.getFactory(Type<&{FungibleToken.Receiver}>()) + + return receiverFactory != nil +} \ No newline at end of file diff --git a/scripts/test/get_nft_collection_public_factory.cdc b/scripts/test/get_nft_collection_public_factory.cdc new file mode 100644 index 0000000..a0095f1 --- /dev/null +++ b/scripts/test/get_nft_collection_public_factory.cdc @@ -0,0 +1,13 @@ +import "NonFungibleToken" + +import "CapabilityFactory" + +pub fun main(address: Address): Bool { + + let managerRef = getAuthAccount(address).borrow<&CapabilityFactory.Manager>(from: CapabilityFactory.StoragePath) + ?? panic("CapabilityFactory Manager not found") + + let collectionPublicFactory = managerRef.getFactory(Type<&{NonFungibleToken.CollectionPublic}>()) + + return collectionPublicFactory != nil +} \ No newline at end of file diff --git a/scripts/test/get_nft_provider_collection_factory.cdc b/scripts/test/get_nft_provider_collection_factory.cdc new file mode 100644 index 0000000..0ccb874 --- /dev/null +++ b/scripts/test/get_nft_provider_collection_factory.cdc @@ -0,0 +1,13 @@ +import "NonFungibleToken" + +import "CapabilityFactory" + +pub fun main(address: Address): Bool { + + let managerRef = getAuthAccount(address).borrow<&CapabilityFactory.Manager>(from: CapabilityFactory.StoragePath) + ?? panic("CapabilityFactory Manager not found") + + let providerCollectionFactory = managerRef.getFactory(Type<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>()) + + return providerCollectionFactory != nil +} \ No newline at end of file diff --git a/scripts/test/get_nft_provider_factory.cdc b/scripts/test/get_nft_provider_factory.cdc new file mode 100644 index 0000000..06ff04e --- /dev/null +++ b/scripts/test/get_nft_provider_factory.cdc @@ -0,0 +1,13 @@ +import "NonFungibleToken" + +import "CapabilityFactory" + +pub fun main(address: Address): Bool { + + let managerRef = getAuthAccount(address).borrow<&CapabilityFactory.Manager>(from: CapabilityFactory.StoragePath) + ?? panic("CapabilityFactory Manager not found") + + let providerFactory = managerRef.getFactory(Type<&{NonFungibleToken.Provider}>()) + + return providerFactory != nil +} \ No newline at end of file diff --git a/test/CapabilityFactory_tests.cdc b/test/CapabilityFactory_tests.cdc index 47d82c9..2fba2c6 100644 --- a/test/CapabilityFactory_tests.cdc +++ b/test/CapabilityFactory_tests.cdc @@ -8,12 +8,17 @@ pub let flowtyThumbnail = "https://storage.googleapis.com/flowty-images/flowty-l // BEGIN SECTION - Test Cases -pub fun testGetProviderCapability() { +pub fun testGetNFTProviderCapability() { setupNFTCollection(creator) scriptExecutor("factory/get_nft_provider_from_factory.cdc", [creator.address]) } +pub fun testGetFTReceiverBalanceCapability() { + txExecutor("example-token/setup.cdc", [creator], [], nil, nil) + scriptExecutor("factory/get_ft_receiver_from_factory.cdc", [creator.address]) +} + pub fun testGetSupportedTypesFromManager() { setupCapabilityFactoryManager(creator) @@ -21,7 +26,7 @@ pub fun testGetSupportedTypesFromManager() { "factory/get_supported_types_from_manager.cdc", [creator.address] )! as! [Type] - Test.assertEqual(6, supportedTypes.length) + Test.assertEqual(8, supportedTypes.length) } pub fun testAddFactoryFails() { @@ -36,7 +41,7 @@ pub fun testAddFactorySucceeds() { "factory/get_supported_types_from_manager.cdc", [creator.address] )! as! [Type] - Test.assertEqual(7, supportedTypes.length) + Test.assertEqual(9, supportedTypes.length) let scriptResult = scriptExecutor( "test/get_nft_receiver_factory.cdc", @@ -66,22 +71,92 @@ pub fun testRemoveNFTProviderFactory() { ) } +pub fun testSetupNFTManager() { + let tmp = blockchain.createAccount() + txExecutor("factory/setup_nft_manager.cdc", [tmp], [], nil, nil) + + let supportedTypes = scriptExecutor("factory/get_supported_types_from_manager.cdc", [tmp.address])! as! [Type] + Test.assertEqual(3, supportedTypes.length) + + let collectionPublicFactorySuccess = scriptExecutor("test/get_nft_collection_public_factory.cdc", [tmp.address])! as! Bool + let providerFactorySuccess = scriptExecutor("test/get_nft_provider_factory.cdc", [tmp.address])! as! Bool + let providerCollectionFactorySuccess = scriptExecutor("test/get_nft_provider_collection_factory.cdc", [tmp.address])! as! Bool + + Test.assertEqual(true, collectionPublicFactorySuccess) + Test.assertEqual(true, providerFactorySuccess) + Test.assertEqual(true, providerCollectionFactorySuccess) +} + +pub fun testSetupFTManager() { + let tmp = blockchain.createAccount() + txExecutor("factory/setup_ft_manager.cdc", [tmp], [], nil, nil) + + let supportedTypes = scriptExecutor("factory/get_supported_types_from_manager.cdc", [tmp.address])! as! [Type] + Test.assertEqual(5, supportedTypes.length) + + let balanceFactorySuccess = scriptExecutor("test/get_ft_balance_factory.cdc", [tmp.address])! as! Bool + let receiverFactorySuccess = scriptExecutor("test/get_ft_receiver_factory.cdc", [tmp.address])! as! Bool + let receiverBalanceFactorySuccess = scriptExecutor("test/get_ft_receiver_balance_factory.cdc", [tmp.address])! as! Bool + let providerFactorySuccess = scriptExecutor("test/get_ft_provider_factory.cdc", [tmp.address])! as! Bool + let allFactorySuccess = scriptExecutor("test/get_ft_all_factory.cdc", [tmp.address])! as! Bool + + + Test.assertEqual(true, balanceFactorySuccess) + Test.assertEqual(true, receiverFactorySuccess) + Test.assertEqual(true, receiverBalanceFactorySuccess) + Test.assertEqual(true, providerFactorySuccess) + Test.assertEqual(true, allFactorySuccess) +} + +pub fun testSetupNFTFTManager() { + let tmp = blockchain.createAccount() + txExecutor("factory/setup_nft_ft_manager.cdc", [tmp], [], nil, nil) + + let supportedTypes = scriptExecutor("factory/get_supported_types_from_manager.cdc", [tmp.address])! as! [Type] + Test.assertEqual(8, supportedTypes.length) + + let collectionPublicFactorySuccess = scriptExecutor("test/get_nft_collection_public_factory.cdc", [tmp.address])! as! Bool + let nftProviderFactorySuccess = scriptExecutor("test/get_nft_provider_factory.cdc", [tmp.address])! as! Bool + let providerCollectionFactorySuccess = scriptExecutor("test/get_nft_provider_collection_factory.cdc", [tmp.address])! as! Bool + + Test.assertEqual(true, collectionPublicFactorySuccess) + Test.assertEqual(true, nftProviderFactorySuccess) + Test.assertEqual(true, providerCollectionFactorySuccess) + + let balanceFactorySuccess = scriptExecutor("test/get_ft_balance_factory.cdc", [tmp.address])! as! Bool + let receiverFactorySuccess = scriptExecutor("test/get_ft_receiver_factory.cdc", [tmp.address])! as! Bool + let receiverBalanceFactorySuccess = scriptExecutor("test/get_ft_receiver_balance_factory.cdc", [tmp.address])! as! Bool + let ftProviderFactorySuccess = scriptExecutor("test/get_ft_provider_factory.cdc", [tmp.address])! as! Bool + let allFactorySuccess = scriptExecutor("test/get_ft_all_factory.cdc", [tmp.address])! as! Bool + + + Test.assertEqual(true, balanceFactorySuccess) + Test.assertEqual(true, receiverFactorySuccess) + Test.assertEqual(true, receiverBalanceFactorySuccess) + Test.assertEqual(true, ftProviderFactorySuccess) + Test.assertEqual(true, allFactorySuccess) +} + // END SECTION - Test Cases pub fun setup() { blockchain.useConfiguration(Test.Configuration({ "CapabilityFactory": adminAccount.address, "ExampleNFT": adminAccount.address, + "ExampleToken": adminAccount.address, "NFTProviderFactory": adminAccount.address, "NFTCollectionPublicFactory": adminAccount.address, "NFTProviderAndCollectionFactory": adminAccount.address, "FTProviderFactory": adminAccount.address, "FTBalanceFactory": adminAccount.address, - "FTReceiverFactory": adminAccount.address + "FTReceiverFactory": adminAccount.address, + "FTReceiverBalanceFactory": adminAccount.address, + "FTAllFactory": adminAccount.address })) - // helper nft contract so we can actually talk to nfts with tests + // helper nft & ft contract so we can actually talk to nfts & fts with tests deploy("ExampleNFT", adminAccount, "../modules/flow-nft/contracts/ExampleNFT.cdc") + deploy("ExampleToken", adminAccount, "../contracts/standard/ExampleToken.cdc") // our main contract is last deploy("CapabilityFactory", adminAccount, "../contracts/CapabilityFactory.cdc") @@ -91,6 +166,8 @@ pub fun setup() { deploy("FTProviderFactory", adminAccount, "../contracts/factories/FTProviderFactory.cdc") deploy("FTBalanceFactory", adminAccount, "../contracts/factories/FTBalanceFactory.cdc") deploy("FTReceiverFactory", adminAccount, "../contracts/factories/FTReceiverFactory.cdc") + deploy("FTReceiverBalanceFactory", adminAccount, "../contracts/factories/FTReceiverBalanceFactory.cdc") + deploy("FTAllFactory", adminAccount, "../contracts/factories/FTAllFactory.cdc") } // BEGIN SECTION - transactions used in tests @@ -112,7 +189,7 @@ pub fun mintNFTDefault(_ minter: Test.Account, receiver: Test.Account) { } pub fun setupCapabilityFactoryManager(_ acct: Test.Account) { - txExecutor("factory/setup.cdc", [acct], [], nil, nil) + txExecutor("factory/setup_nft_ft_manager.cdc", [acct], [], nil, nil) } // END SECTION - transactions use in tests diff --git a/test/HybridCustody_tests.cdc b/test/HybridCustody_tests.cdc index 1b3093e..a485a53 100644 --- a/test/HybridCustody_tests.cdc +++ b/test/HybridCustody_tests.cdc @@ -842,7 +842,7 @@ pub fun setupOwnedAccount(_ acct: Test.Account, _ filterKind: String) { } pub fun setupFactoryManager(_ acct: Test.Account) { - txExecutor("factory/setup.cdc", [acct], [], nil, nil) + txExecutor("factory/setup_nft_ft_manager.cdc", [acct], [], nil, nil) } pub fun setupNFTCollection(_ acct: Test.Account) { @@ -1022,7 +1022,9 @@ pub fun setup() { accounts["NFTProviderFactory"] = adminAccount accounts["FTProviderFactory"] = adminAccount accounts["FTBalanceFactory"] = adminAccount + accounts["FTReceiverBalanceFactory"] = adminAccount accounts["FTReceiverFactory"] = adminAccount + accounts["FTAllFactory"] = adminAccount accounts["ExampleNFT"] = adminAccount accounts["ExampleNFT2"] = adminAccount accounts["ExampleToken"] = adminAccount @@ -1041,7 +1043,9 @@ pub fun setup() { "NFTProviderFactory": adminAccount.address, "FTProviderFactory": adminAccount.address, "FTBalanceFactory": adminAccount.address, + "FTReceiverBalanceFactory": adminAccount.address, "FTReceiverFactory": adminAccount.address, + "FTAllFactory": adminAccount.address, "ExampleNFT": adminAccount.address, "ExampleNFT2": adminAccount.address, "ExampleToken": adminAccount.address @@ -1061,6 +1065,8 @@ pub fun setup() { deploy("NFTProviderFactory", adminAccount, "../contracts/factories/NFTProviderFactory.cdc") deploy("FTProviderFactory", adminAccount, "../contracts/factories/FTProviderFactory.cdc") deploy("FTBalanceFactory", adminAccount, "../contracts/factories/FTBalanceFactory.cdc") + deploy("FTReceiverBalanceFactory", adminAccount, "../contracts/factories/FTReceiverBalanceFactory.cdc") deploy("FTReceiverFactory", adminAccount, "../contracts/factories/FTReceiverFactory.cdc") + deploy("FTAllFactory", adminAccount, "../contracts/factories/FTAllFactory.cdc") deploy("HybridCustody", adminAccount, "../contracts/HybridCustody.cdc") } diff --git a/transactions/example-token/setup.cdc b/transactions/example-token/setup.cdc index 7f2cd27..3de7cc4 100644 --- a/transactions/example-token/setup.cdc +++ b/transactions/example-token/setup.cdc @@ -13,7 +13,7 @@ transaction { // Create a public capability to the Vault that only exposes // the deposit function through the Receiver interface - acct.link<&ExampleToken.Vault{FungibleToken.Receiver}>( + acct.link<&ExampleToken.Vault{FungibleToken.Receiver, FungibleToken.Balance}>( ExampleToken.ReceiverPublicPath, target: ExampleToken.VaultStoragePath ) diff --git a/transactions/factory/setup.cdc b/transactions/factory/setup_ft_manager.cdc similarity index 73% rename from transactions/factory/setup.cdc rename to transactions/factory/setup_ft_manager.cdc index a237c5d..fcd4631 100644 --- a/transactions/factory/setup.cdc +++ b/transactions/factory/setup_ft_manager.cdc @@ -1,13 +1,11 @@ +import "FungibleToken" + import "CapabilityFactory" -import "NFTCollectionPublicFactory" -import "NFTProviderAndCollectionFactory" -import "NFTProviderFactory" import "FTProviderFactory" import "FTBalanceFactory" +import "FTReceiverBalanceFactory" import "FTReceiverFactory" - -import "NonFungibleToken" -import "FungibleToken" +import "FTAllFactory" transaction { prepare(acct: AuthAccount) { @@ -29,11 +27,10 @@ transaction { let manager = acct.borrow<&CapabilityFactory.Manager>(from: CapabilityFactory.StoragePath) ?? panic("manager not found") - manager.updateFactory(Type<&{NonFungibleToken.CollectionPublic}>(), NFTCollectionPublicFactory.Factory()) - manager.updateFactory(Type<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>(), NFTProviderAndCollectionFactory.Factory()) - manager.updateFactory(Type<&{NonFungibleToken.Provider}>(), NFTProviderFactory.Factory()) manager.updateFactory(Type<&{FungibleToken.Provider}>(), FTProviderFactory.Factory()) manager.updateFactory(Type<&{FungibleToken.Balance}>(), FTBalanceFactory.Factory()) manager.updateFactory(Type<&{FungibleToken.Receiver}>(), FTReceiverFactory.Factory()) + manager.updateFactory(Type<&{FungibleToken.Receiver, FungibleToken.Balance}>(), FTReceiverBalanceFactory.Factory()) + manager.updateFactory(Type<&{FungibleToken.Provider, FungibleToken.Receiver, FungibleToken.Balance}>(), FTAllFactory.Factory()) } } diff --git a/transactions/factory/setup_nft_ft_manager.cdc b/transactions/factory/setup_nft_ft_manager.cdc index cc395e1..3c47e49 100644 --- a/transactions/factory/setup_nft_ft_manager.cdc +++ b/transactions/factory/setup_nft_ft_manager.cdc @@ -1,15 +1,16 @@ +import "NonFungibleToken" +import "FungibleToken" + import "CapabilityFactory" import "NFTCollectionPublicFactory" import "NFTProviderAndCollectionFactory" import "NFTProviderFactory" import "FTProviderFactory" import "FTBalanceFactory" +import "FTReceiverBalanceFactory" import "FTReceiverFactory" import "FTAllFactory" -import "NonFungibleToken" -import "FungibleToken" - transaction { prepare(acct: AuthAccount) { if acct.borrow<&AnyResource>(from: CapabilityFactory.StoragePath) == nil { @@ -36,6 +37,7 @@ transaction { manager.updateFactory(Type<&{FungibleToken.Provider}>(), FTProviderFactory.Factory()) manager.updateFactory(Type<&{FungibleToken.Balance}>(), FTBalanceFactory.Factory()) manager.updateFactory(Type<&{FungibleToken.Receiver}>(), FTReceiverFactory.Factory()) + manager.updateFactory(Type<&{FungibleToken.Receiver, FungibleToken.Balance}>(), FTReceiverBalanceFactory.Factory()) manager.updateFactory(Type<&{FungibleToken.Provider, FungibleToken.Receiver, FungibleToken.Balance}>(), FTAllFactory.Factory()) } } diff --git a/transactions/factory/setup_nft_manager.cdc b/transactions/factory/setup_nft_manager.cdc index 107e379..7ca5590 100644 --- a/transactions/factory/setup_nft_manager.cdc +++ b/transactions/factory/setup_nft_manager.cdc @@ -1,11 +1,10 @@ +import "NonFungibleToken" + import "CapabilityFactory" import "NFTCollectionPublicFactory" import "NFTProviderAndCollectionFactory" import "NFTProviderFactory" -import "NonFungibleToken" -import "FungibleToken" - transaction { prepare(acct: AuthAccount) { if acct.borrow<&AnyResource>(from: CapabilityFactory.StoragePath) == nil {