difftreelog
add EVM event for `destoyCollection`, refactor `Unique` pallet code, add test for events
in: master
14 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5825,7 +5825,7 @@
[[package]]
name = "pallet-common"
-version = "0.1.8"
+version = "0.1.9"
dependencies = [
"ethereum",
"evm-coder",
pallets/common/CHANGELOG.mddiffbeforeafterboth--- a/pallets/common/CHANGELOG.md
+++ b/pallets/common/CHANGELOG.md
@@ -2,29 +2,37 @@
All notable changes to this project will be documented in this file.
+## [0.1.9] - 2022-10-13
+
+## Added
+
+- EVM event for `destroy_collection`.
+
## [0.1.8] - 2022-08-24
## Added
- - Eth methods for collection
- + set_collection_sponsor_substrate
- + has_collection_pending_sponsor
- + remove_collection_sponsor
- + get_collection_sponsor
+
+- Eth methods for collection
+ - set_collection_sponsor_substrate
+ - has_collection_pending_sponsor
+ - remove_collection_sponsor
+ - get_collection_sponsor
- Add convert function from `uint256` to `CrossAccountId`.
## [0.1.7] - 2022-08-19
### Added
- - Add convert funtion from `CrossAccountId` to eth `uint256`.
+- Add convert funtion from `CrossAccountId` to eth `uint256`.
-
## [0.1.6] - 2022-08-16
### Added
-- New Ethereum API methods: changeOwner, changeOwner(Substrate) and verifyOwnerOrAdmin(Substrate).
+- New Ethereum API methods: changeOwner, changeOwner(Substrate) and verifyOwnerOrAdmin(Substrate).
+
<!-- bureaucrate goes here -->
+
## [v0.1.5] 2022-08-16
### Other changes
@@ -45,19 +53,21 @@
- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b
## [0.1.3] - 2022-07-25
+
### Add
-- Some static property keys and values.
+- Some static property keys and values.
+
## [0.1.2] - 2022-07-20
### Fixed
-- Some methods in `#[solidity_interface]` for `CollectionHandle` had invalid
- mutability modifiers, causing invalid stub/abi generation.
+- Some methods in `#[solidity_interface]` for `CollectionHandle` had invalid
+ mutability modifiers, causing invalid stub/abi generation.
## [0.1.1] - 2022-07-14
### Added
- - Implementation of RPC method `token_owners` returning 10 owners in no particular order.
- This was an internal request to improve the web interface and support fractionalization event.
+- Implementation of RPC method `token_owners` returning 10 owners in no particular order.
+ This was an internal request to improve the web interface and support fractionalization event.
pallets/common/Cargo.tomldiffbeforeafterboth--- a/pallets/common/Cargo.toml
+++ b/pallets/common/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "pallet-common"
-version = "0.1.8"
+version = "0.1.9"
license = "GPLv3"
edition = "2021"
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -53,6 +53,12 @@
#[indexed]
collection_id: address,
},
+ /// The collection has been destroyed.
+ CollectionDestroyed {
+ /// Collection ID.
+ #[indexed]
+ collection_id: address,
+ },
}
/// Does not always represent a full collection, for RFT it is either
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -999,6 +999,13 @@
<CollectionProperties<T>>::remove(collection.id);
<Pallet<T>>::deposit_event(Event::CollectionDestroyed(collection.id));
+
+ <PalletEvm<T>>::deposit_log(
+ erc::CollectionHelpersEvents::CollectionDestroyed {
+ collection_id: eth::collection_id_to_address(collection.id),
+ }
+ .to_log(T::ContractAddress::get()),
+ );
Ok(())
}
pallets/unique/src/eth/mod.rsdiffbeforeafterboth--- a/pallets/unique/src/eth/mod.rs
+++ b/pallets/unique/src/eth/mod.rs
@@ -19,9 +19,10 @@
use core::marker::PhantomData;
use ethereum as _;
use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};
-use frame_support::{traits::Get, storage::StorageNMap};
+use frame_support::traits::Get;
+
+use crate::Pallet;
-use crate::sp_api_hidden_includes_decl_storage::hidden_include::StorageDoubleMap;
use pallet_common::{
CollectionById,
dispatch::CollectionDispatch,
@@ -39,10 +40,7 @@
CollectionMode, PropertyValue, CollectionFlags,
};
-use crate::{
- Config, SelfWeightOf, weights::WeightInfo, NftTransferBasket, FungibleTransferBasket,
- ReFungibleTransferBasket, NftApproveBasket, FungibleApproveBasket, RefungibleApproveBasket,
-};
+use crate::{Config, SelfWeightOf, weights::WeightInfo};
use sp_std::vec::Vec;
use alloc::format;
@@ -302,30 +300,13 @@
}
#[weight(<SelfWeightOf<T>>::destroy_collection())]
- #[solidity(rename_selector = "destroyCollection")]
fn destroy_collection(&mut self, caller: caller, collection_address: address) -> Result<void> {
let caller = T::CrossAccountId::from_eth(caller);
- let collection_id = pallet_common::eth::map_eth_to_id(&collection_address)
- .ok_or("Invalid collection address format".into())
- .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
- let collection = <pallet_common::CollectionHandle<T>>::try_get(collection_id)
- .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
- collection
- .check_is_internal()
- .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
- T::CollectionDispatch::destroy(caller, collection)
- .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
-
- let _ = <NftTransferBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
- let _ = <FungibleTransferBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
- let _ = <ReFungibleTransferBasket<T>>::clear_prefix((collection_id,), u32::MAX, None);
-
- let _ = <NftApproveBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
- let _ = <FungibleApproveBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
- let _ = <RefungibleApproveBasket<T>>::clear_prefix((collection_id,), u32::MAX, None);
-
- Ok(())
+ let collection_id = pallet_common::eth::map_eth_to_id(&collection_address)
+ .ok_or("Invalid collection address format")?;
+ <Pallet<T>>::destroy_collection_internal(caller, collection_id)
+ .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)
}
/// Check if a collection exists
pallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterboth--- a/pallets/unique/src/eth/stubs/CollectionHelpers.sol
+++ b/pallets/unique/src/eth/stubs/CollectionHelpers.sol
@@ -20,6 +20,7 @@
/// @dev inlined interface
contract CollectionHelpersEvents {
event CollectionCreated(address indexed owner, address indexed collectionId);
+ event CollectionDestroyed(address indexed collectionId);
}
/// @title Contract, which allows users to operate with collections
pallets/unique/src/lib.rsdiffbeforeafterboth--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -362,25 +362,8 @@
#[weight = <SelfWeightOf<T>>::destroy_collection()]
pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
- let collection = <CollectionHandle<T>>::try_get(collection_id)?;
- collection.check_is_internal()?;
-
- // =========
-
- T::CollectionDispatch::destroy(sender, collection)?;
- // TODO: basket cleanup should be moved elsewhere
- // Maybe runtime dispatch.rs should perform it?
-
- let _ = <NftTransferBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
- let _ = <FungibleTransferBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
- let _ = <ReFungibleTransferBasket<T>>::clear_prefix((collection_id,), u32::MAX, None);
-
- let _ = <NftApproveBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
- let _ = <FungibleApproveBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
- let _ = <RefungibleApproveBasket<T>>::clear_prefix((collection_id,), u32::MAX, None);
-
- Ok(())
+ Self::destroy_collection_internal(sender, collection_id)
}
/// Add an address to allow list.
@@ -1151,4 +1134,28 @@
target_collection.save()
}
+
+ #[inline(always)]
+ pub(crate) fn destroy_collection_internal(
+ sender: T::CrossAccountId,
+ collection_id: CollectionId,
+ ) -> DispatchResult {
+ let collection = <CollectionHandle<T>>::try_get(collection_id)?;
+ collection.check_is_internal()?;
+
+ T::CollectionDispatch::destroy(sender, collection)?;
+
+ // TODO: basket cleanup should be moved elsewhere
+ // Maybe runtime dispatch.rs should perform it?
+
+ let _ = <NftTransferBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
+ let _ = <FungibleTransferBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
+ let _ = <ReFungibleTransferBasket<T>>::clear_prefix((collection_id,), u32::MAX, None);
+
+ let _ = <NftApproveBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
+ let _ = <FungibleApproveBasket<T>>::clear_prefix(collection_id, u32::MAX, None);
+ let _ = <RefungibleApproveBasket<T>>::clear_prefix((collection_id,), u32::MAX, None);
+
+ Ok(())
+ }
}
tests/.vscode/settings.jsondiffbeforeafterboth--- a/tests/.vscode/settings.json
+++ b/tests/.vscode/settings.json
@@ -1,5 +1,12 @@
{
- "mocha.enabled": true,
- "mochaExplorer.files": "**/*.test.ts",
- "mochaExplorer.require": "ts-node/register"
+ "mocha.enabled": true,
+ "mochaExplorer.files": "**/*.test.ts",
+ "mochaExplorer.require": "ts-node/register",
+ "eslint.format.enable": true,
+ "[javascript]": {
+ "editor.defaultFormatter": "dbaeumer.vscode-eslint"
+ },
+ "[typescript]": {
+ "editor.defaultFormatter": "dbaeumer.vscode-eslint"
+ }
}
tests/src/eth/api/CollectionHelpers.soldiffbeforeafterboth--- a/tests/src/eth/api/CollectionHelpers.sol
+++ b/tests/src/eth/api/CollectionHelpers.sol
@@ -15,6 +15,7 @@
/// @dev inlined interface
interface CollectionHelpersEvents {
event CollectionCreated(address indexed owner, address indexed collectionId);
+ event CollectionDestroyed(address indexed collectionId);
}
/// @title Contract, which allows users to operate with collections
tests/src/eth/collectionHelpersAbi.jsondiffbeforeafterboth--- a/tests/src/eth/collectionHelpersAbi.json
+++ b/tests/src/eth/collectionHelpersAbi.json
@@ -19,6 +19,19 @@
"type": "event"
},
{
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "collectionId",
+ "type": "address"
+ }
+ ],
+ "name": "CollectionDestroyed",
+ "type": "event"
+ },
+ {
"inputs": [],
"name": "collectionCreationFee",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
tests/src/eth/createNFTCollection.test.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.8//9// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {evmToAddress} from '@polkadot/util-crypto';18import {IKeyringPair} from '@polkadot/types/types';19import {expect, itEth, usingEthPlaygrounds} from './util';202122describe('Create NFT collection from EVM', () => {23 let donor: IKeyringPair;2425 before(async function() {26 await usingEthPlaygrounds(async (_helper, privateKey) => {27 donor = await privateKey({filename: __filename});28 });29 });3031 itEth('Create collection', async ({helper}) => {32 const owner = await helper.eth.createAccountWithBalance(donor);3334 const name = 'CollectionEVM';35 const description = 'Some description';36 const prefix = 'token prefix';3738 const {collectionId} = await helper.eth.createNFTCollection(owner, name, description, prefix);39 const data = (await helper.rft.getData(collectionId))!;40 const collection = helper.nft.getCollectionObject(collectionId);41 42 expect(data.name).to.be.eq(name);43 expect(data.description).to.be.eq(description);44 expect(data.raw.tokenPrefix).to.be.eq(prefix);45 expect(data.raw.mode).to.be.eq('NFT');4647 const options = await collection.getOptions();4849 expect(options.tokenPropertyPermissions).to.be.empty;50 });5152 itEth('Create collection with properties', async ({helper}) => {53 const owner = await helper.eth.createAccountWithBalance(donor);5455 const name = 'CollectionEVM';56 const description = 'Some description';57 const prefix = 'token prefix';58 const baseUri = 'BaseURI';5960 const {collectionId} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, name, description, prefix, baseUri);6162 const collection = helper.nft.getCollectionObject(collectionId);63 const data = (await collection.getData())!;64 65 expect(data.name).to.be.eq(name);66 expect(data.description).to.be.eq(description);67 expect(data.raw.tokenPrefix).to.be.eq(prefix);68 expect(data.raw.mode).to.be.eq('NFT');6970 const options = await collection.getOptions();71 expect(options.tokenPropertyPermissions).to.be.deep.equal([72 {73 key: 'URI',74 permission: {mutable: true, collectionAdmin: true, tokenOwner: false},75 },76 {77 key: 'URISuffix',78 permission: {mutable: true, collectionAdmin: true, tokenOwner: false},79 },80 ]);81 });8283 // this test will occasionally fail when in async environment.84 itEth.skip('Check collection address exist', async ({helper}) => {85 const owner = await helper.eth.createAccountWithBalance(donor);8687 const expectedCollectionId = +(await helper.callRpc('api.rpc.unique.collectionStats')).created + 1;88 const expectedCollectionAddress = helper.ethAddress.fromCollectionId(expectedCollectionId);89 const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);9091 expect(await collectionHelpers.methods92 .isCollectionExist(expectedCollectionAddress)93 .call()).to.be.false;9495 await collectionHelpers.methods96 .createNFTCollection('A', 'A', 'A')97 .send({value: Number(2n * helper.balance.getOneTokenNominal())});98 99 expect(await collectionHelpers.methods100 .isCollectionExist(expectedCollectionAddress)101 .call()).to.be.true;102 });103 104 itEth('Set sponsorship', async ({helper}) => {105 const owner = await helper.eth.createAccountWithBalance(donor);106 const sponsor = await helper.eth.createAccountWithBalance(donor);107 const ss58Format = helper.chain.getChainProperties().ss58Format;108 const {collectionId, collectionAddress} = await helper.eth.createNFTCollection(owner, 'Sponsor', 'absolutely anything', 'ROC');109110 const collection = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);111 await collection.methods.setCollectionSponsor(sponsor).send();112113 let data = (await helper.nft.getData(collectionId))!;114 expect(data.raw.sponsorship.Unconfirmed).to.be.equal(evmToAddress(sponsor, Number(ss58Format)));115116 await expect(collection.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');117118 const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'nft', sponsor);119 await sponsorCollection.methods.confirmCollectionSponsorship().send();120121 data = (await helper.nft.getData(collectionId))!;122 expect(data.raw.sponsorship.Confirmed).to.be.equal(evmToAddress(sponsor, Number(ss58Format)));123 });124125 itEth('Set limits', async ({helper}) => {126 const owner = await helper.eth.createAccountWithBalance(donor);127 const {collectionId, collectionAddress} = await helper.eth.createNFTCollection(owner, 'Limits', 'absolutely anything', 'FLO');128 const limits = {129 accountTokenOwnershipLimit: 1000,130 sponsoredDataSize: 1024,131 sponsoredDataRateLimit: 30,132 tokenLimit: 1000000,133 sponsorTransferTimeout: 6,134 sponsorApproveTimeout: 6,135 ownerCanTransfer: false,136 ownerCanDestroy: false,137 transfersEnabled: false,138 };139140 const collection = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);141 await collection.methods['setCollectionLimit(string,uint32)']('accountTokenOwnershipLimit', limits.accountTokenOwnershipLimit).send();142 await collection.methods['setCollectionLimit(string,uint32)']('sponsoredDataSize', limits.sponsoredDataSize).send();143 await collection.methods['setCollectionLimit(string,uint32)']('sponsoredDataRateLimit', limits.sponsoredDataRateLimit).send();144 await collection.methods['setCollectionLimit(string,uint32)']('tokenLimit', limits.tokenLimit).send();145 await collection.methods['setCollectionLimit(string,uint32)']('sponsorTransferTimeout', limits.sponsorTransferTimeout).send();146 await collection.methods['setCollectionLimit(string,uint32)']('sponsorApproveTimeout', limits.sponsorApproveTimeout).send();147 await collection.methods['setCollectionLimit(string,bool)']('ownerCanTransfer', limits.ownerCanTransfer).send();148 await collection.methods['setCollectionLimit(string,bool)']('ownerCanDestroy', limits.ownerCanDestroy).send();149 await collection.methods['setCollectionLimit(string,bool)']('transfersEnabled', limits.transfersEnabled).send();150 151 const data = (await helper.nft.getData(collectionId))!;152 expect(data.raw.limits.accountTokenOwnershipLimit).to.be.eq(limits.accountTokenOwnershipLimit);153 expect(data.raw.limits.sponsoredDataSize).to.be.eq(limits.sponsoredDataSize);154 expect(data.raw.limits.sponsoredDataRateLimit.blocks).to.be.eq(limits.sponsoredDataRateLimit);155 expect(data.raw.limits.tokenLimit).to.be.eq(limits.tokenLimit);156 expect(data.raw.limits.sponsorTransferTimeout).to.be.eq(limits.sponsorTransferTimeout);157 expect(data.raw.limits.sponsorApproveTimeout).to.be.eq(limits.sponsorApproveTimeout);158 expect(data.raw.limits.ownerCanTransfer).to.be.eq(limits.ownerCanTransfer);159 expect(data.raw.limits.ownerCanDestroy).to.be.eq(limits.ownerCanDestroy);160 expect(data.raw.limits.transfersEnabled).to.be.eq(limits.transfersEnabled);161 });162163 itEth('Collection address exist', async ({helper}) => {164 const owner = await helper.eth.createAccountWithBalance(donor);165 const collectionAddressForNonexistentCollection = '0x17C4E6453CC49AAAAEACA894E6D9683E00112233';166 expect(await helper.ethNativeContract.collectionHelpers(collectionAddressForNonexistentCollection)167 .methods.isCollectionExist(collectionAddressForNonexistentCollection).call())168 .to.be.false;169 170 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'Exister', 'absolutely anything', 'EVC');171 expect(await helper.ethNativeContract.collectionHelpers(collectionAddress)172 .methods.isCollectionExist(collectionAddress).call())173 .to.be.true;174 });175});176177describe('(!negative tests!) Create NFT collection from EVM', () => {178 let donor: IKeyringPair;179 let nominal: bigint;180181 before(async function() {182 await usingEthPlaygrounds(async (helper, privateKey) => {183 donor = await privateKey({filename: __filename});184 nominal = helper.balance.getOneTokenNominal();185 });186 });187188 itEth('(!negative test!) Create collection (bad lengths)', async ({helper}) => {189 const owner = await helper.eth.createAccountWithBalance(donor);190 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);191 {192 const MAX_NAME_LENGTH = 64;193 const collectionName = 'A'.repeat(MAX_NAME_LENGTH + 1);194 const description = 'A';195 const tokenPrefix = 'A';196197 await expect(collectionHelper.methods198 .createNFTCollection(collectionName, description, tokenPrefix)199 .call({value: Number(2n * nominal)})).to.be.rejectedWith('name is too long. Max length is ' + MAX_NAME_LENGTH);200 201 }202 {203 const MAX_DESCRIPTION_LENGTH = 256;204 const collectionName = 'A';205 const description = 'A'.repeat(MAX_DESCRIPTION_LENGTH + 1);206 const tokenPrefix = 'A';207 await expect(collectionHelper.methods208 .createNFTCollection(collectionName, description, tokenPrefix)209 .call({value: Number(2n * nominal)})).to.be.rejectedWith('description is too long. Max length is ' + MAX_DESCRIPTION_LENGTH);210 }211 {212 const MAX_TOKEN_PREFIX_LENGTH = 16;213 const collectionName = 'A';214 const description = 'A';215 const tokenPrefix = 'A'.repeat(MAX_TOKEN_PREFIX_LENGTH + 1);216 await expect(collectionHelper.methods217 .createNFTCollection(collectionName, description, tokenPrefix)218 .call({value: Number(2n * nominal)})).to.be.rejectedWith('token_prefix is too long. Max length is ' + MAX_TOKEN_PREFIX_LENGTH);219 }220 });221 222 itEth('(!negative test!) Create collection (no funds)', async ({helper}) => {223 const owner = await helper.eth.createAccountWithBalance(donor);224 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);225 await expect(collectionHelper.methods226 .createNFTCollection('Peasantry', 'absolutely anything', 'CVE')227 .call({value: Number(1n * nominal)})).to.be.rejectedWith('Sent amount not equals to collection creation price (2000000000000000000)');228 });229230 itEth('(!negative test!) Check owner', async ({helper}) => {231 const owner = await helper.eth.createAccountWithBalance(donor);232 const malfeasant = helper.eth.createAccount();233 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'Transgressed', 'absolutely anything', 'COR');234 const malfeasantCollection = helper.ethNativeContract.collection(collectionAddress, 'nft', malfeasant);235 const EXPECTED_ERROR = 'NoPermission';236 {237 const sponsor = await helper.eth.createAccountWithBalance(donor);238 await expect(malfeasantCollection.methods239 .setCollectionSponsor(sponsor)240 .call()).to.be.rejectedWith(EXPECTED_ERROR);241 242 const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'nft', sponsor);243 await expect(sponsorCollection.methods244 .confirmCollectionSponsorship()245 .call()).to.be.rejectedWith('caller is not set as sponsor');246 }247 {248 await expect(malfeasantCollection.methods249 .setCollectionLimit('account_token_ownership_limit', '1000')250 .call()).to.be.rejectedWith(EXPECTED_ERROR);251 }252 });253254 itEth('(!negative test!) Set limits', async ({helper}) => {255 const owner = await helper.eth.createAccountWithBalance(donor);256 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'Limits', 'absolutely anything', 'OLF');257 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);258 await expect(collectionEvm.methods259 .setCollectionLimit('badLimit', 'true')260 .call()).to.be.rejectedWith('unknown boolean limit "badLimit"');261 });262});tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -173,49 +173,46 @@
async callEVM(signer: TEthereumAccount, contractAddress: string, abi: string) {
return await this.helper.callRpc('api.rpc.eth.call', [{from: signer, to: contractAddress, data: abi}]);
}
-
- async createNFTCollection(signer: string, name: string, description: string, tokenPrefix: string): Promise<{collectionId: number, collectionAddress: string}> {
+
+ async createCollecion(functionName: string, signer: string, name: string, description: string, tokenPrefix: string): Promise<{ collectionId: number, collectionAddress: string, events: NormalizedEvent[] }> {
const collectionCreationPrice = this.helper.balance.getCollectionCreationPrice();
const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
-
- const result = await collectionHelper.methods.createNFTCollection(name, description, tokenPrefix).send({value: Number(collectionCreationPrice)});
+
+ const result = await collectionHelper.methods[functionName](name, description, tokenPrefix).send({value: Number(collectionCreationPrice)});
const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
const collectionId = this.helper.ethAddress.extractCollectionId(collectionAddress);
-
- return {collectionId, collectionAddress};
+ const events = this.helper.eth.normalizeEvents(result.events);
+
+ return {collectionId, collectionAddress, events};
+ }
+
+ async createNFTCollection(signer: string, name: string, description: string, tokenPrefix: string): Promise<{ collectionId: number, collectionAddress: string, events: NormalizedEvent[] }> {
+ return this.createCollecion('createNFTCollection', signer, name, description, tokenPrefix);
}
- async createERC721MetadataCompatibleNFTCollection(signer: string, name: string, description: string, tokenPrefix: string, baseUri: string): Promise<{collectionId: number, collectionAddress: string}> {
+ async createERC721MetadataCompatibleNFTCollection(signer: string, name: string, description: string, tokenPrefix: string, baseUri: string): Promise<{collectionId: number, collectionAddress: string, events: NormalizedEvent[] }> {
const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
- const {collectionId, collectionAddress} = await this.createNFTCollection(signer, name, description, tokenPrefix);
+ const {collectionId, collectionAddress, events} = await this.createCollecion('createNFTCollection', signer, name, description, tokenPrefix);
await collectionHelper.methods.makeCollectionERC721MetadataCompatible(collectionAddress, baseUri).send();
- return {collectionId, collectionAddress};
+ return {collectionId, collectionAddress, events};
}
async createRFTCollection(signer: string, name: string, description: string, tokenPrefix: string): Promise<{collectionId: number, collectionAddress: string}> {
- const collectionCreationPrice = this.helper.balance.getCollectionCreationPrice();
- const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
-
- const result = await collectionHelper.methods.createRFTCollection(name, description, tokenPrefix).send({value: Number(collectionCreationPrice)});
-
- const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
- const collectionId = this.helper.ethAddress.extractCollectionId(collectionAddress);
-
- return {collectionId, collectionAddress};
+ return this.createCollecion('createRFTCollection', signer, name, description, tokenPrefix);
}
- async createERC721MetadataCompatibleRFTCollection(signer: string, name: string, description: string, tokenPrefix: string, baseUri: string): Promise<{collectionId: number, collectionAddress: string}> {
+ async createERC721MetadataCompatibleRFTCollection(signer: string, name: string, description: string, tokenPrefix: string, baseUri: string): Promise<{collectionId: number, collectionAddress: string, events: NormalizedEvent[] }> {
const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
- const {collectionId, collectionAddress} = await this.createRFTCollection(signer, name, description, tokenPrefix);
+ const {collectionId, collectionAddress, events} = await this.createCollecion('createRFTCollection', signer, name, description, tokenPrefix);
await collectionHelper.methods.makeCollectionERC721MetadataCompatible(collectionAddress, baseUri).send();
- return {collectionId, collectionAddress};
+ return {collectionId, collectionAddress, events};
}
async deployCollectorContract(signer: string): Promise<Contract> {