git.delta.rocks / unique-network / refs/commits / 46330dd65bb1

difftreelog

CORE-386 Fix after rebase

Trubnikov Sergey2022-06-09parent: #ebbe668.patch.diff
in: master

9 files changed

modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -201,7 +201,7 @@
 		Ok(())
 	}
 
-	fn remove_admin(&self, caller: caller, admin: address) -> Result<void> {
+	fn remove_collection_admin(&self, caller: caller, admin: address) -> Result<void> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let admin = T::CrossAccountId::from_eth(admin);
 		<Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;
@@ -220,12 +220,21 @@
 	}
 
 	#[solidity(rename_selector = "setNesting")]
-	fn set_nesting(&mut self, caller: caller, enable: bool, collections: Vec<address>) -> Result<void> {
+	fn set_nesting(
+		&mut self,
+		caller: caller,
+		enable: bool,
+		collections: Vec<address>,
+	) -> Result<void> {
 		if collections.is_empty() {
 			return Err("No addresses provided".into());
 		}
 		if collections.len() >= OwnerRestrictedSet::bound() {
-			return Err(Error::Revert(format!("Out of bound: {} >= {}", collections.len(), OwnerRestrictedSet::bound())));
+			return Err(Error::Revert(format!(
+				"Out of bound: {} >= {}",
+				collections.len(),
+				OwnerRestrictedSet::bound()
+			)));
 		}
 		check_is_owner_or_admin(caller, self)?;
 		self.collection.permissions.nesting = Some(match enable {
@@ -238,7 +247,7 @@
 					})?)
 					.map_err(|e| Error::Revert(format!("{:?}", e)))?;
 				}
-				NestingRule::OwnerRestricted (bv)
+				NestingRule::OwnerRestricted(bv)
 			}
 		});
 		save(self)?;
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -148,7 +148,6 @@
 					.saturating_mul(writes),
 			))
 	}
-
 	pub fn save(self) -> DispatchResult {
 		<CollectionById<T>>::insert(self.id, self.collection);
 		Ok(())
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -51,147 +51,6 @@
 	event MintingFinished();
 }
 
-// Selector: 2da6e59e
-contract Collection is Dummy, ERC165 {
-	// Selector: setCollectionProperty(string,bytes) 2f073f66
-	function setCollectionProperty(string memory key, bytes memory value)
-		public
-	{
-		require(false, stub_error);
-		key;
-		value;
-		dummy = 0;
-	}
-
-	// Selector: deleteCollectionProperty(string) 7b7debce
-	function deleteCollectionProperty(string memory key) public {
-		require(false, stub_error);
-		key;
-		dummy = 0;
-	}
-
-	// Throws error if key not found
-	//
-	// Selector: collectionProperty(string) cf24fd6d
-	function collectionProperty(string memory key)
-		public
-		view
-		returns (bytes memory)
-	{
-		require(false, stub_error);
-		key;
-		dummy;
-		return hex"";
-	}
-
-	// Selector: setCollectionSponsor(address) 7623402e
-	function setCollectionSponsor(address sponsor) public {
-		require(false, stub_error);
-		sponsor;
-		dummy = 0;
-	}
-
-	// Selector: confirmCollectionSponsorship() 3c50e97a
-	function confirmCollectionSponsorship() public {
-		require(false, stub_error);
-		dummy = 0;
-	}
-
-	// Selector: setCollectionLimit(string,uint32) 6a3841db
-	function setCollectionLimit(string memory limit, uint32 value) public {
-		require(false, stub_error);
-		limit;
-		value;
-		dummy = 0;
-	}
-
-	// Selector: setCollectionLimit(string,bool) 993b7fba
-	function setCollectionLimit(string memory limit, bool value) public {
-		require(false, stub_error);
-		limit;
-		value;
-		dummy = 0;
-	}
-
-	// Selector: contractAddress() f6b4dfb4
-	function contractAddress() public view returns (address) {
-		require(false, stub_error);
-		dummy;
-		return 0x0000000000000000000000000000000000000000;
-	}
-
-	// Selector: addCollectionAdminSubstrate(uint256) 5730062b
-	function addCollectionAdminSubstrate(uint256 newAdmin) public view {
-		require(false, stub_error);
-		newAdmin;
-		dummy;
-	}
-
-	// Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
-	function removeCollectionAdminSubstrate(uint256 newAdmin) public view {
-		require(false, stub_error);
-		newAdmin;
-		dummy;
-	}
-
-	// Selector: addCollectionAdmin(address) 92e462c7
-	function addCollectionAdmin(address newAdmin) public view {
-		require(false, stub_error);
-		newAdmin;
-		dummy;
-	}
-
-	// Selector: removeAdmin(address) 1785f53c
-	function removeAdmin(address admin) public view {
-		require(false, stub_error);
-		admin;
-		dummy;
-	}
-
-	// Selector: setNesting(bool) e8fc50dd
-	function setNesting(bool enable) public {
-		require(false, stub_error);
-		enable;
-		dummy = 0;
-	}
-
-	// Selector: setNesting(bool,address[]) 7df12a9a
-	function setNesting(bool enable, address[] memory collections) public {
-		require(false, stub_error);
-		enable;
-		collections;
-		dummy = 0;
-	}
-
-	// Selector: setCollectionAccess(uint8) 41835d4c
-	function setCollectionAccess(uint8 mode) public {
-		require(false, stub_error);
-		mode;
-		dummy = 0;
-	}
-
-	// Selector: addToCollectionAllowList(address) 67844fe6
-	function addToCollectionAllowList(address user) public view {
-		require(false, stub_error);
-		user;
-		dummy;
-	}
-
-	// Selector: removeFromCollectionAllowList(address) 85c51acb
-	function removeFromCollectionAllowList(address user) public view {
-		require(false, stub_error);
-		user;
-		dummy;
-	}
-
-	// Selector: setMintMode(bool) 5dea9bd5
-	function setMintMode(bool mode) public {
-		require(false, stub_error);
-		mode;
-		dummy = 0;
-	}
-}
-
 // Selector: 41369377
 contract TokenProperties is Dummy, ERC165 {
 	// Selector: setTokenPropertyPermission(string,bool,bool,bool) 222d97fa
@@ -471,6 +330,147 @@
 	}
 }
 
+// Selector: c0de6be0
+contract Collection is Dummy, ERC165 {
+	// Selector: setCollectionProperty(string,bytes) 2f073f66
+	function setCollectionProperty(string memory key, bytes memory value)
+		public
+	{
+		require(false, stub_error);
+		key;
+		value;
+		dummy = 0;
+	}
+
+	// Selector: deleteCollectionProperty(string) 7b7debce
+	function deleteCollectionProperty(string memory key) public {
+		require(false, stub_error);
+		key;
+		dummy = 0;
+	}
+
+	// Throws error if key not found
+	//
+	// Selector: collectionProperty(string) cf24fd6d
+	function collectionProperty(string memory key)
+		public
+		view
+		returns (bytes memory)
+	{
+		require(false, stub_error);
+		key;
+		dummy;
+		return hex"";
+	}
+
+	// Selector: setCollectionSponsor(address) 7623402e
+	function setCollectionSponsor(address sponsor) public {
+		require(false, stub_error);
+		sponsor;
+		dummy = 0;
+	}
+
+	// Selector: confirmCollectionSponsorship() 3c50e97a
+	function confirmCollectionSponsorship() public {
+		require(false, stub_error);
+		dummy = 0;
+	}
+
+	// Selector: setCollectionLimit(string,uint32) 6a3841db
+	function setCollectionLimit(string memory limit, uint32 value) public {
+		require(false, stub_error);
+		limit;
+		value;
+		dummy = 0;
+	}
+
+	// Selector: setCollectionLimit(string,bool) 993b7fba
+	function setCollectionLimit(string memory limit, bool value) public {
+		require(false, stub_error);
+		limit;
+		value;
+		dummy = 0;
+	}
+
+	// Selector: contractAddress() f6b4dfb4
+	function contractAddress() public view returns (address) {
+		require(false, stub_error);
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
+
+	// Selector: addCollectionAdminSubstrate(uint256) 5730062b
+	function addCollectionAdminSubstrate(uint256 newAdmin) public view {
+		require(false, stub_error);
+		newAdmin;
+		dummy;
+	}
+
+	// Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
+	function removeCollectionAdminSubstrate(uint256 newAdmin) public view {
+		require(false, stub_error);
+		newAdmin;
+		dummy;
+	}
+
+	// Selector: addCollectionAdmin(address) 92e462c7
+	function addCollectionAdmin(address newAdmin) public view {
+		require(false, stub_error);
+		newAdmin;
+		dummy;
+	}
+
+	// Selector: removeCollectionAdmin(address) fafd7b42
+	function removeCollectionAdmin(address admin) public view {
+		require(false, stub_error);
+		admin;
+		dummy;
+	}
+
+	// Selector: setNesting(bool) e8fc50dd
+	function setNesting(bool enable) public {
+		require(false, stub_error);
+		enable;
+		dummy = 0;
+	}
+
+	// Selector: setNesting(bool,address[]) 7df12a9a
+	function setNesting(bool enable, address[] memory collections) public {
+		require(false, stub_error);
+		enable;
+		collections;
+		dummy = 0;
+	}
+
+	// Selector: setCollectionAccess(uint8) 41835d4c
+	function setCollectionAccess(uint8 mode) public {
+		require(false, stub_error);
+		mode;
+		dummy = 0;
+	}
+
+	// Selector: addToCollectionAllowList(address) 67844fe6
+	function addToCollectionAllowList(address user) public view {
+		require(false, stub_error);
+		user;
+		dummy;
+	}
+
+	// Selector: removeFromCollectionAllowList(address) 85c51acb
+	function removeFromCollectionAllowList(address user) public view {
+		require(false, stub_error);
+		user;
+		dummy;
+	}
+
+	// Selector: setMintMode(bool) 5dea9bd5
+	function setMintMode(bool mode) public {
+		require(false, stub_error);
+		mode;
+		dummy = 0;
+	}
+}
+
 // Selector: d74d154f
 contract ERC721UniqueExtensions is Dummy, ERC165 {
 	// Selector: transfer(address,uint256) a9059cbb
modifiedruntime/tests/src/tests.rsdiffbeforeafterboth
--- a/runtime/tests/src/tests.rs
+++ b/runtime/tests/src/tests.rs
@@ -1286,7 +1286,7 @@
 			account(3)
 		)));
 
-		// remove admin 3 
+		// remove admin 3
 		assert_ok!(Unique::remove_collection_admin(
 			origin1,
 			CollectionId(1),
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -42,69 +42,6 @@
 	event MintingFinished();
 }
 
-// Selector: 2da6e59e
-interface Collection is Dummy, ERC165 {
-	// Selector: setCollectionProperty(string,bytes) 2f073f66
-	function setCollectionProperty(string memory key, bytes memory value)
-		external;
-
-	// Selector: deleteCollectionProperty(string) 7b7debce
-	function deleteCollectionProperty(string memory key) external;
-
-	// Throws error if key not found
-	//
-	// Selector: collectionProperty(string) cf24fd6d
-	function collectionProperty(string memory key)
-		external
-		view
-		returns (bytes memory);
-
-	// Selector: setCollectionSponsor(address) 7623402e
-	function setCollectionSponsor(address sponsor) external;
-
-	// Selector: confirmCollectionSponsorship() 3c50e97a
-	function confirmCollectionSponsorship() external;
-
-	// Selector: setCollectionLimit(string,uint32) 6a3841db
-	function setCollectionLimit(string memory limit, uint32 value) external;
-
-	// Selector: setCollectionLimit(string,bool) 993b7fba
-	function setCollectionLimit(string memory limit, bool value) external;
-
-	// Selector: contractAddress() f6b4dfb4
-	function contractAddress() external view returns (address);
-
-	// Selector: addCollectionAdminSubstrate(uint256) 5730062b
-	function addCollectionAdminSubstrate(uint256 newAdmin) external view;
-
-	// Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
-	function removeCollectionAdminSubstrate(uint256 newAdmin) external view;
-
-	// Selector: addCollectionAdmin(address) 92e462c7
-	function addCollectionAdmin(address newAdmin) external view;
-
-	// Selector: removeAdmin(address) 1785f53c
-	function removeAdmin(address admin) external view;
-
-	// Selector: setNesting(bool) e8fc50dd
-	function setNesting(bool enable) external;
-
-	// Selector: setNesting(bool,address[]) 7df12a9a
-	function setNesting(bool enable, address[] memory collections) external;
-
-	// Selector: setCollectionAccess(uint8) 41835d4c
-	function setCollectionAccess(uint8 mode) external;
-
-	// Selector: addToCollectionAllowList(address) 67844fe6
-	function addToCollectionAllowList(address user) external view;
-
-	// Selector: removeFromCollectionAllowList(address) 85c51acb
-	function removeFromCollectionAllowList(address user) external view;
-
-	// Selector: setMintMode(bool) 5dea9bd5
-	function setMintMode(bool mode) external;
-}
-
 // Selector: 41369377
 interface TokenProperties is Dummy, ERC165 {
 	// Selector: setTokenPropertyPermission(string,bool,bool,bool) 222d97fa
@@ -254,6 +191,69 @@
 	function totalSupply() external view returns (uint256);
 }
 
+// Selector: c0de6be0
+interface Collection is Dummy, ERC165 {
+	// Selector: setCollectionProperty(string,bytes) 2f073f66
+	function setCollectionProperty(string memory key, bytes memory value)
+		external;
+
+	// Selector: deleteCollectionProperty(string) 7b7debce
+	function deleteCollectionProperty(string memory key) external;
+
+	// Throws error if key not found
+	//
+	// Selector: collectionProperty(string) cf24fd6d
+	function collectionProperty(string memory key)
+		external
+		view
+		returns (bytes memory);
+
+	// Selector: setCollectionSponsor(address) 7623402e
+	function setCollectionSponsor(address sponsor) external;
+
+	// Selector: confirmCollectionSponsorship() 3c50e97a
+	function confirmCollectionSponsorship() external;
+
+	// Selector: setCollectionLimit(string,uint32) 6a3841db
+	function setCollectionLimit(string memory limit, uint32 value) external;
+
+	// Selector: setCollectionLimit(string,bool) 993b7fba
+	function setCollectionLimit(string memory limit, bool value) external;
+
+	// Selector: contractAddress() f6b4dfb4
+	function contractAddress() external view returns (address);
+
+	// Selector: addCollectionAdminSubstrate(uint256) 5730062b
+	function addCollectionAdminSubstrate(uint256 newAdmin) external view;
+
+	// Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9
+	function removeCollectionAdminSubstrate(uint256 newAdmin) external view;
+
+	// Selector: addCollectionAdmin(address) 92e462c7
+	function addCollectionAdmin(address newAdmin) external view;
+
+	// Selector: removeCollectionAdmin(address) fafd7b42
+	function removeCollectionAdmin(address admin) external view;
+
+	// Selector: setNesting(bool) e8fc50dd
+	function setNesting(bool enable) external;
+
+	// Selector: setNesting(bool,address[]) 7df12a9a
+	function setNesting(bool enable, address[] memory collections) external;
+
+	// Selector: setCollectionAccess(uint8) 41835d4c
+	function setCollectionAccess(uint8 mode) external;
+
+	// Selector: addToCollectionAllowList(address) 67844fe6
+	function addToCollectionAllowList(address user) external view;
+
+	// Selector: removeFromCollectionAllowList(address) 85c51acb
+	function removeFromCollectionAllowList(address user) external view;
+
+	// Selector: setMintMode(bool) 5dea9bd5
+	function setMintMode(bool mode) external;
+}
+
 // Selector: d74d154f
 interface ERC721UniqueExtensions is Dummy, ERC165 {
 	// Selector: transfer(address,uint256) a9059cbb
modifiedtests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth
--- a/tests/src/eth/contractSponsoring.test.ts
+++ b/tests/src/eth/contractSponsoring.test.ts
@@ -221,7 +221,6 @@
     expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');
   });
 
-  //TODO: CORE-302 add eth methods
   itWeb3('Sponsoring collection from evm address via access list', async ({api, web3}) => {
     const owner = await createEthAccountWithBalance(api, web3);
     const collectionHelpers = evmCollectionHelpers(web3, owner);
@@ -229,13 +228,13 @@
     const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
     const sponsor = await createEthAccountWithBalance(api, web3);
     const collectionEvm = evmCollection(web3, owner, collectionIdAddress);
-    result = await collectionEvm.methods.ethSetSponsor(sponsor).send({from: owner});
+    result = await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner});
     let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
     expect(collectionSub.sponsorship.isUnconfirmed).to.be.true;
     expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor));
     await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor');
 
-    await collectionEvm.methods.ethConfirmSponsorship().send({from: sponsor});
+    await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
     collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
     expect(collectionSub.sponsorship.isConfirmed).to.be.true;
     expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor));
@@ -248,15 +247,16 @@
     expect(oldPermissions.mintMode).to.be.false;
     expect(oldPermissions.access).to.be.equal('Normal');
 
-    await collectionEvm.methods.setAccess('AllowList').send({from: owner});
-    await collectionEvm.methods.addToAllowList(user).send({from: owner});
+    await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});
+    await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});
     await collectionEvm.methods.setMintMode(true).send({from: owner});
 
     const newPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();
     expect(newPermissions.mintMode).to.be.true;
     expect(newPermissions.access).to.be.equal('AllowList');
 
-    // const [alicesBalanceBefore] = await getBalance(api, [alicesPublicKey]);
+    const ownerBalanceBefore = await ethBalanceViaSub(api, owner);
+    const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);
 
     {
       const nextTokenId = await collectionEvm.methods.nextTokenId().call();
@@ -265,13 +265,12 @@
         user,
         nextTokenId,
         'Test URI',
-      ).call({from: user});
-      console.log(result);
+      ).send({from: user});
       const events = normalizeEvents(result.events);
 
       expect(events).to.be.deep.equal([
         {
-          collectionIdAddress,
+          address: collectionIdAddress,
           event: 'Transfer',
           args: {
             from: '0x0000000000000000000000000000000000000000',
@@ -281,7 +280,12 @@
         },
       ]);
 
+      const ownerBalanceAfter = await ethBalanceViaSub(api, owner);
+      const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);
+
       expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
+      expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);
+      expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;
     }
   });
 
@@ -292,19 +296,19 @@
     const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
     const sponsor = await createEthAccountWithBalance(api, web3);
     const collectionEvm = evmCollection(web3, owner, collectionIdAddress);
-    result = await collectionEvm.methods.ethSetSponsor(sponsor).send();
+    result = await collectionEvm.methods.setCollectionSponsor(sponsor).send();
     let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
     expect(collectionSub.sponsorship.isUnconfirmed).to.be.true;
     expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor));
-    await expect(collectionEvm.methods.ethConfirmSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor');
+    await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor');
     const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress);
-    await sponsorCollection.methods.ethConfirmSponsorship().send();
+    await sponsorCollection.methods.confirmCollectionSponsorship().send();
     collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
     expect(collectionSub.sponsorship.isConfirmed).to.be.true;
     expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor));
 
     const user = createEthAccount(web3);
-    await collectionEvm.methods.addAdmin(user).send();
+    await collectionEvm.methods.addCollectionAdmin(user).send();
     
     const ownerBalanceBefore = await ethBalanceViaSub(api, owner);
     const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);
modifiedtests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth
--- a/tests/src/eth/nonFungibleAbi.json
+++ b/tests/src/eth/nonFungibleAbi.json
@@ -302,7 +302,7 @@
     "inputs": [
       { "internalType": "address", "name": "admin", "type": "address" }
     ],
-    "name": "removeAdmin",
+    "name": "removeCollectionAdmin",
     "outputs": [],
     "stateMutability": "view",
     "type": "function"
modifiedtests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth
before · tests/src/eth/proxy/nonFungibleProxy.test.ts
1// 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.89// 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 {createCollectionExpectSuccess, createItemExpectSuccess} from '../../util/helpers';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents} from '../util/helpers';19import nonFungibleAbi from '../nonFungibleAbi.json';20import {expect} from 'chai';21import {submitTransactionAsync} from '../../substrate/substrate-api';22import Web3 from 'web3';23import {readFile} from 'fs/promises';24import {ApiPromise} from '@polkadot/api';2526async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {27  // Proxy owner has no special privilegies, we don't need to reuse them28  const owner = await createEthAccountWithBalance(api, web3);29  const proxyContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueNFTProxy.abi`)).toString()), undefined, {30    from: owner,31    ...GAS_ARGS,32  });33  const proxy = await proxyContract.deploy({data: (await readFile(`${__dirname}/UniqueNFTProxy.bin`)).toString(), arguments: [wrapped.options.address]}).send({from: owner});34  return proxy;35}3637describe('NFT (Via EVM proxy): Information getting', () => {38  itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {39    const collection = await createCollectionExpectSuccess({40      mode: {type: 'NFT'},41    });42    const alice = privateKeyWrapper('//Alice');43    const caller = await createEthAccountWithBalance(api, web3);4445    await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});4647    const address = collectionIdToAddress(collection);48    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));49    const totalSupply = await contract.methods.totalSupply().call();5051    expect(totalSupply).to.equal('1');52  });5354  itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {55    const collection = await createCollectionExpectSuccess({56      mode: {type: 'NFT'},57    });58    const alice = privateKeyWrapper('//Alice');5960    const caller = await createEthAccountWithBalance(api, web3);61    await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});62    await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});63    await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});6465    const address = collectionIdToAddress(collection);66    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));67    const balance = await contract.methods.balanceOf(caller).call();6869    expect(balance).to.equal('3');70  });7172  itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => {73    const collection = await createCollectionExpectSuccess({74      mode: {type: 'NFT'},75    });76    const alice = privateKeyWrapper('//Alice');7778    const caller = await createEthAccountWithBalance(api, web3);79    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});8081    const address = collectionIdToAddress(collection);82    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));83    const owner = await contract.methods.ownerOf(tokenId).call();8485    expect(owner).to.equal(caller);86  });87});8889describe('NFT (Via EVM proxy): Plain calls', () => {90  itWeb3('Can perform mint()', async ({web3, api}) => {91    const owner = await createEthAccountWithBalance(api, web3);92    const collectionHelper = evmCollectionHelpers(web3, owner);93    const result = await collectionHelper.methods94      .createNonfungibleCollection('A', 'A', 'A')95      .send();96    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);97    const caller = await createEthAccountWithBalance(api, web3);98    const receiver = createEthAccount(web3);99    const collectionEvmOwned = evmCollection(web3, owner, collectionIdAddress);100    const collectionEvm = evmCollection(web3, caller, collectionIdAddress);101    const contract = await proxyWrap(api, web3, collectionEvm);102    await collectionEvmOwned.methods.addAdmin(contract.options.address).send();103104    {105      const nextTokenId = await contract.methods.nextTokenId().call();106      expect(nextTokenId).to.be.equal('1');107      const result = await contract.methods.mintWithTokenURI(108        receiver,109        nextTokenId,110        'Test URI',111      ).send({from: caller});112      const events = normalizeEvents(result.events);113      events[0].address = events[0].address.toLocaleLowerCase();114115      expect(events).to.be.deep.equal([116        {117          address: collectionIdAddress.toLocaleLowerCase(),118          event: 'Transfer',119          args: {120            from: '0x0000000000000000000000000000000000000000',121            to: receiver,122            tokenId: nextTokenId,123          },124        },125      ]);126127      expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');128    }129  });130  131  //TODO: CORE-302 add eth methods132  itWeb3.skip('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {133    const collection = await createCollectionExpectSuccess({134      mode: {type: 'NFT'},135    });136    const alice = privateKeyWrapper('//Alice');137138    const caller = await createEthAccountWithBalance(api, web3);139    const receiver = createEthAccount(web3);140141    const address = collectionIdToAddress(collection);142    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));143    const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address});144    await submitTransactionAsync(alice, changeAdminTx);145146    {147      const nextTokenId = await contract.methods.nextTokenId().call();148      expect(nextTokenId).to.be.equal('1');149      const result = await contract.methods.mintBulkWithTokenURI(150        receiver,151        [152          [nextTokenId, 'Test URI 0'],153          [+nextTokenId + 1, 'Test URI 1'],154          [+nextTokenId + 2, 'Test URI 2'],155        ],156      ).send({from: caller});157      const events = normalizeEvents(result.events);158159      expect(events).to.be.deep.equal([160        {161          address,162          event: 'Transfer',163          args: {164            from: '0x0000000000000000000000000000000000000000',165            to: receiver,166            tokenId: nextTokenId,167          },168        },169        {170          address,171          event: 'Transfer',172          args: {173            from: '0x0000000000000000000000000000000000000000',174            to: receiver,175            tokenId: String(+nextTokenId + 1),176          },177        },178        {179          address,180          event: 'Transfer',181          args: {182            from: '0x0000000000000000000000000000000000000000',183            to: receiver,184            tokenId: String(+nextTokenId + 2),185          },186        },187      ]);188189      expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');190      expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');191      expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');192    }193  });194195  itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {196    const collection = await createCollectionExpectSuccess({197      mode: {type: 'NFT'},198    });199    const alice = privateKeyWrapper('//Alice');200    const caller = await createEthAccountWithBalance(api, web3);201202    const address = collectionIdToAddress(collection);203    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));204    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});205206    const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address});207    await submitTransactionAsync(alice, changeAdminTx);208209    {210      const result = await contract.methods.burn(tokenId).send({from: caller});211      const events = normalizeEvents(result.events);212213      expect(events).to.be.deep.equal([214        {215          address,216          event: 'Transfer',217          args: {218            from: contract.options.address,219            to: '0x0000000000000000000000000000000000000000',220            tokenId: tokenId.toString(),221          },222        },223      ]);224    }225  });226227  itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {228    const collection = await createCollectionExpectSuccess({229      mode: {type: 'NFT'},230    });231    const alice = privateKeyWrapper('//Alice');232    const caller = await createEthAccountWithBalance(api, web3);233    const spender = createEthAccount(web3);234235    const address = collectionIdToAddress(collection);236    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address));237    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});238239    {240      const result = await contract.methods.approve(spender, tokenId).send({from: caller, ...GAS_ARGS});241      const events = normalizeEvents(result.events);242243      expect(events).to.be.deep.equal([244        {245          address,246          event: 'Approval',247          args: {248            owner: contract.options.address,249            approved: spender,250            tokenId: tokenId.toString(),251          },252        },253      ]);254    }255  });256257  itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {258    const collection = await createCollectionExpectSuccess({259      mode: {type: 'NFT'},260    });261    const alice = privateKeyWrapper('//Alice');262    const caller = await createEthAccountWithBalance(api, web3);263    const owner = await createEthAccountWithBalance(api, web3);264265    const receiver = createEthAccount(web3);266267    const address = collectionIdToAddress(collection);268    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});269    const contract = await proxyWrap(api, web3, evmCollection);270    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});271272    await evmCollection.methods.approve(contract.options.address, tokenId).send({from: owner});273274    {275      const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({from: caller});276      const events = normalizeEvents(result.events);277      expect(events).to.be.deep.equal([278        {279          address,280          event: 'Transfer',281          args: {282            from: owner,283            to: receiver,284            tokenId: tokenId.toString(),285          },286        },287      ]);288    }289290    {291      const balance = await contract.methods.balanceOf(receiver).call();292      expect(+balance).to.equal(1);293    }294295    {296      const balance = await contract.methods.balanceOf(contract.options.address).call();297      expect(+balance).to.equal(0);298    }299  });300301  itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {302    const collection = await createCollectionExpectSuccess({303      mode: {type: 'NFT'},304    });305    const alice = privateKeyWrapper('//Alice');306    const caller = await createEthAccountWithBalance(api, web3);307    const receiver = createEthAccount(web3);308309    const address = collectionIdToAddress(collection);310    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));311    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});312313    {314      const result = await contract.methods.transfer(receiver, tokenId).send({from: caller});315      const events = normalizeEvents(result.events);316      expect(events).to.be.deep.equal([317        {318          address,319          event: 'Transfer',320          args: {321            from: contract.options.address,322            to: receiver,323            tokenId: tokenId.toString(),324          },325        },326      ]);327    }328329    {330      const balance = await contract.methods.balanceOf(contract.options.address).call();331      expect(+balance).to.equal(0);332    }333334    {335      const balance = await contract.methods.balanceOf(receiver).call();336      expect(+balance).to.equal(1);337    }338  });339});