difftreelog
added coderTest via Conract
in: master
4 files changed
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
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: OTHER
+// This code is automatically generated
+
+pragma solidity >=0.8.0 <0.9.0;
+
+/// @dev common stubs holder
+contract Dummy {
+ uint8 dummy;
+ string stub_error = "this contract is implemented in native";
+}
+
+contract ERC165 is Dummy {
+ function supportsInterface(bytes4 interfaceID) external view returns (bool) {
+ require(false, stub_error);
+ interfaceID;
+ return true;
+ }
+}
+
+/// @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
+/// @dev the ERC-165 identifier for this interface is 0x7dea03b1
+contract CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {
+ /// Create an NFT collection
+ /// @param name Name of the collection
+ /// @param description Informative description of the collection
+ /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
+ /// @return address Address of the newly created collection
+ /// @dev EVM selector for this function is: 0x844af658,
+ /// or in textual repr: createNFTCollection(string,string,string)
+ function createNFTCollection(
+ string memory name,
+ string memory description,
+ string memory tokenPrefix
+ ) public payable returns (address) {
+ require(false, stub_error);
+ name;
+ description;
+ tokenPrefix;
+ dummy = 0;
+ return 0x0000000000000000000000000000000000000000;
+ }
+
+ // /// Create an NFT collection
+ // /// @param name Name of the collection
+ // /// @param description Informative description of the collection
+ // /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
+ // /// @return address Address of the newly created collection
+ // /// @dev EVM selector for this function is: 0xe34a6844,
+ // /// or in textual repr: createNonfungibleCollection(string,string,string)
+ // function createNonfungibleCollection(string memory name, string memory description, string memory tokenPrefix) public payable returns (address) {
+ // require(false, stub_error);
+ // name;
+ // description;
+ // tokenPrefix;
+ // dummy = 0;
+ // return 0x0000000000000000000000000000000000000000;
+ // }
+
+ /// @dev EVM selector for this function is: 0xab173450,
+ /// or in textual repr: createRFTCollection(string,string,string)
+ function createRFTCollection(
+ string memory name,
+ string memory description,
+ string memory tokenPrefix
+ ) public payable returns (address) {
+ require(false, stub_error);
+ name;
+ description;
+ tokenPrefix;
+ dummy = 0;
+ return 0x0000000000000000000000000000000000000000;
+ }
+
+ /// @dev EVM selector for this function is: 0x7335b79f,
+ /// or in textual repr: createFTCollection(string,uint8,string,string)
+ function createFTCollection(
+ string memory name,
+ uint8 decimals,
+ string memory description,
+ string memory tokenPrefix
+ ) public payable returns (address) {
+ require(false, stub_error);
+ name;
+ decimals;
+ description;
+ tokenPrefix;
+ dummy = 0;
+ return 0x0000000000000000000000000000000000000000;
+ }
+
+ /// @dev EVM selector for this function is: 0x85624258,
+ /// or in textual repr: makeCollectionERC721MetadataCompatible(address,string)
+ function makeCollectionERC721MetadataCompatible(address collection, string memory baseUri) public {
+ require(false, stub_error);
+ collection;
+ baseUri;
+ dummy = 0;
+ }
+
+ /// @dev EVM selector for this function is: 0x564e321f,
+ /// or in textual repr: destroyCollection(address)
+ function destroyCollection(address collectionAddress) public {
+ require(false, stub_error);
+ collectionAddress;
+ dummy = 0;
+ }
+
+ /// Check if a collection exists
+ /// @param collectionAddress Address of the collection in question
+ /// @return bool Does the collection exist?
+ /// @dev EVM selector for this function is: 0xc3de1494,
+ /// or in textual repr: isCollectionExist(address)
+ function isCollectionExist(address collectionAddress) public view returns (bool) {
+ require(false, stub_error);
+ collectionAddress;
+ dummy;
+ return false;
+ }
+
+ /// @dev EVM selector for this function is: 0xd23a7ab1,
+ /// or in textual repr: collectionCreationFee()
+ function collectionCreationFee() public view returns (uint256) {
+ require(false, stub_error);
+ dummy;
+ return 0;
+ }
+}
tests/src/eth/evmToSubstrate/EvmToSubstrateHelper.soldiffbeforeafterboth1// SPDX-License-Identifier: Apache License2pragma solidity >=0.8.0;3import {CollectionHelpers} from "../api/CollectionHelpers.sol";4import {ContractHelpers} from "../api/ContractHelpers.sol";5import {UniqueRefungibleToken} from "../api/UniqueRefungibleToken.sol";6import {UniqueRefungible, Collection, EthCrossAccount as RftCrossAccountId, Tuple20 as RftProperties} from "../api/UniqueRefungible.sol";7import {UniqueNFT, EthCrossAccount as NftCrossAccountId, Tuple21 as NftProperty, TokenProperties} from "../api/UniqueNFT.sol";89struct Property {10 string key;11 bytes value;12}1314// interface Foo {15// struct Tuple19 {16// string field_0;17// bytes field_1;18// }1920// }2122contract EvmToSubstrate {23 bytes32 constant REFUNGIBLE_COLLECTION_TYPE = keccak256(bytes("ReFungible"));24 bytes32 constant NONFUNGIBLE_COLLECTION_TYPE = keccak256(bytes("NFT"));25 // bytes32 collectionType;2627 // Collection commonContract;28 // UniqueNFT nftCollection;29 // UniqueRefungible rftCollection;3031 // function(address, uint256) external returns (bool) mintInvoke;32 // function(address, address, uint256) external transferInvoke;3334 modifier checkRestrictions(address _collection) {35 Collection commonContract = Collection(_collection);36 require(commonContract.isOwnerOrAdmin(msg.sender), "Only collection admin/owner can call this method");3738 // bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));39 // uint256 tokenId;4041 // if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {42 // UniqueRefungible rftCollection = UniqueRefungible(_collection);43 // mintInvoke = rftCollection.mint;44 // transferInvoke = rftCollection.transferFrom;45 // tokenId = rftCollection.nextTokenId();46 // } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {47 // UniqueNFT nftCollection = UniqueNFT(_collection);48 // mintInvoke = nftCollection.mint;49 // transferInvoke = nftCollection.transferFrom;5051 // tokenId = nftCollection.nextTokenId();52 // } else {53 // revert("Wrong collection type. Works only with NFT or RFT");54 // }5556 _;57 }5859 /// @dev This emits when a mint to a substrate address has been made.60 event MintToSub(address _toEth, uint256 _toSub, address _collection, uint256 _tokenId);6162 function mintToSubstrate(address _collection, uint256 _substrateReceiver) external checkRestrictions(_collection) {63 // function(address, uint256) external returns (bool) mintInvoke;64 // function(Tuple8 memory, Tuple8 memory, uint256) external transferInvoke;65 Collection commonContract = Collection(_collection);66 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));67 uint256 tokenId;6869 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {70 UniqueRefungible rftCollection = UniqueRefungible(_collection);71 72 tokenId = rftCollection.mint(address(this));7374 rftCollection.transferFromCross(75 RftCrossAccountId(address(this), 0),76 RftCrossAccountId(address(0), _substrateReceiver),77 tokenId78 );79 } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {80 UniqueNFT nftCollection = UniqueNFT(_collection);81 // tokenId = nftCollection.nextTokenId();82 tokenId = nftCollection.mint(address(this));8384 nftCollection.transferFromCross(85 NftCrossAccountId(address(this), 0),86 NftCrossAccountId(address(0), _substrateReceiver),87 tokenId88 );89 } else {90 revert("Wrong collection type. Works only with NFT or RFT");91 }9293 // mintInvoke(address(this), tokenId);94 // Tuple8 memory sender = Tuple8(address(this), 0);95 // Tuple8 memory receiver = Tuple8(address(0), _substrateReceiver);9697 // transferInvoke(sender, receiver, tokenId);9899 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);100 }101102 function mintToSubstrateWithProperty(103 address _collection,104 uint256 _substrateReceiver,105 Property[] calldata properties106 ) external checkRestrictions(_collection) {107 // function(address, uint256, string memory) external returns (bool) mintInvoke;108 // function(address, address, uint256) external transferInvoke;109 uint256 propertiesLength = properties.length;110 require(propertiesLength > 0, "Properies is empty");111112 Collection commonContract = Collection(_collection);113 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));114 uint256 tokenId;115116 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {117 UniqueRefungible rftCollection = UniqueRefungible(_collection);118 tokenId = rftCollection.nextTokenId();119 rftCollection.mint(address(this));120 for (uint256 i = 0; i < propertiesLength; ++i) {121 rftCollection.setProperty(tokenId, properties[i].key, properties[i].value);122 }123 rftCollection.transferFromCross(124 RftCrossAccountId(address(this), 0),125 RftCrossAccountId(address(0), _substrateReceiver),126 tokenId127 );128 } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {129 UniqueNFT nftCollection = UniqueNFT(_collection);130 // tokenId = nftCollection.nextTokenId();131 tokenId = nftCollection.mint(address(this));132 for (uint256 i = 0; i < propertiesLength; ++i) {133 nftCollection.setProperty(tokenId, properties[i].key, properties[i].value);134 }135 nftCollection.transferFromCross(136 NftCrossAccountId(address(this), 0),137 NftCrossAccountId(address(0), _substrateReceiver),138 tokenId139 );140 } else {141 revert("Wrong collection type. Works only with NFT or RFT");142 }143144 // transferInvoke(address(this), _gap, tokenId);145146 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);147 }148149 function mintToSubstrateBulkProperty(150 address _collection,151 uint256 _substrateReceiver,152 NftProperty[] calldata _properties153 ) external checkRestrictions(_collection) {154 uint256 propertiesLength = _properties.length;155 require(propertiesLength > 0, "Properies is empty");156157 Collection commonContract = Collection(_collection);158 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));159 uint256 tokenId;160161 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {} else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {162 UniqueNFT nftCollection = UniqueNFT(_collection);163 // tokenId = nftCollection.nextTokenId();164 tokenId = nftCollection.mint(address(this));165166 nftCollection.setProperties(tokenId, _properties);167168 nftCollection.transferFromCross(169 NftCrossAccountId(address(this), 0),170 NftCrossAccountId(address(0), _substrateReceiver),171 tokenId172 );173 } else {174 revert("Wrong collection type. Works only with NFT or RFT");175 }176177 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);178 }179}1// SPDX-License-Identifier: Apache License2pragma solidity >=0.8.0;3import {CollectionHelpers} from "../api/CollectionHelpers.sol";4import {ContractHelpers} from "../api/ContractHelpers.sol";5import {UniqueRefungibleToken} from "../api/UniqueRefungibleToken.sol";6import {UniqueRefungible, Collection, EthCrossAccount as RftCrossAccountId, Tuple20 as RftProperties} from "../api/UniqueRefungible.sol";7import {UniqueNFT, EthCrossAccount as NftCrossAccountId, Tuple21 as NftProperty, TokenProperties} from "../api/UniqueNFT.sol";89struct Property {10 string key;11 bytes value;12}1314// interface Foo {15// struct Tuple19 {16// string field_0;17// bytes field_1;18// }1920// }2122contract EvmToSubstrate {23 bytes32 constant REFUNGIBLE_COLLECTION_TYPE = keccak256(bytes("ReFungible"));24 bytes32 constant NONFUNGIBLE_COLLECTION_TYPE = keccak256(bytes("NFT"));25 // bytes32 collectionType;2627 // Collection commonContract;28 // UniqueNFT nftCollection;29 // UniqueRefungible rftCollection;3031 // function(address, uint256) external returns (bool) mintInvoke;32 // function(address, address, uint256) external transferInvoke;3334 modifier checkRestrictions(address _collection) {35 Collection commonContract = Collection(_collection);36 require(commonContract.isOwnerOrAdmin(msg.sender), "Only collection admin/owner can call this method");3738 // bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));39 // uint256 tokenId;4041 // if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {42 // UniqueRefungible rftCollection = UniqueRefungible(_collection);43 // mintInvoke = rftCollection.mint;44 // transferInvoke = rftCollection.transferFrom;45 // tokenId = rftCollection.nextTokenId();46 // } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {47 // UniqueNFT nftCollection = UniqueNFT(_collection);48 // mintInvoke = nftCollection.mint;49 // transferInvoke = nftCollection.transferFrom;5051 // tokenId = nftCollection.nextTokenId();52 // } else {53 // revert("Wrong collection type. Works only with NFT or RFT");54 // }5556 _;57 }5859 /// @dev This emits when a mint to a substrate address has been made.60 event MintToSub(address _toEth, uint256 _toSub, address _collection, uint256 _tokenId);6162 function mintToSubstrate(address _collection, uint256 _substrateReceiver) external checkRestrictions(_collection) {63 // function(address, uint256) external returns (bool) mintInvoke;64 // function(Tuple8 memory, Tuple8 memory, uint256) external transferInvoke;65 Collection commonContract = Collection(_collection);66 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));67 uint256 tokenId;6869 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {70 UniqueRefungible rftCollection = UniqueRefungible(_collection);7172 tokenId = rftCollection.mint(address(this));7374 rftCollection.transferFromCross(75 RftCrossAccountId(address(this), 0),76 RftCrossAccountId(address(0), _substrateReceiver),77 tokenId78 );79 } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {80 UniqueNFT nftCollection = UniqueNFT(_collection);81 // tokenId = nftCollection.nextTokenId();82 tokenId = nftCollection.mint(address(this));8384 nftCollection.transferFromCross(85 NftCrossAccountId(address(this), 0),86 NftCrossAccountId(address(0), _substrateReceiver),87 tokenId88 );89 } else {90 revert("Wrong collection type. Works only with NFT or RFT");91 }9293 // mintInvoke(address(this), tokenId);94 // Tuple8 memory sender = Tuple8(address(this), 0);95 // Tuple8 memory receiver = Tuple8(address(0), _substrateReceiver);9697 // transferInvoke(sender, receiver, tokenId);9899 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);100 }101102 function mintToSubstrateWithProperty(103 address _collection,104 uint256 _substrateReceiver,105 Property[] calldata properties106 ) external checkRestrictions(_collection) {107 // function(address, uint256, string memory) external returns (bool) mintInvoke;108 // function(address, address, uint256) external transferInvoke;109 uint256 propertiesLength = properties.length;110 require(propertiesLength > 0, "Properies is empty");111112 Collection commonContract = Collection(_collection);113 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));114 uint256 tokenId;115116 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {117 UniqueRefungible rftCollection = UniqueRefungible(_collection);118 tokenId = rftCollection.nextTokenId();119 rftCollection.mint(address(this));120 for (uint256 i = 0; i < propertiesLength; ++i) {121 rftCollection.setProperty(tokenId, properties[i].key, properties[i].value);122 }123 rftCollection.transferFromCross(124 RftCrossAccountId(address(this), 0),125 RftCrossAccountId(address(0), _substrateReceiver),126 tokenId127 );128 } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {129 UniqueNFT nftCollection = UniqueNFT(_collection);130 // tokenId = nftCollection.nextTokenId();131 tokenId = nftCollection.mint(address(this));132 for (uint256 i = 0; i < propertiesLength; ++i) {133 nftCollection.setProperty(tokenId, properties[i].key, properties[i].value);134 }135 nftCollection.transferFromCross(136 NftCrossAccountId(address(this), 0),137 NftCrossAccountId(address(0), _substrateReceiver),138 tokenId139 );140 } else {141 revert("Wrong collection type. Works only with NFT or RFT");142 }143144 // transferInvoke(address(this), _gap, tokenId);145146 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);147 }148149 function mintToSubstrateBulkProperty(150 address _collection,151 uint256 _substrateReceiver,152 NftProperty[] calldata _properties153 ) external checkRestrictions(_collection) {154 uint256 propertiesLength = _properties.length;155 require(propertiesLength > 0, "Properies is empty");156157 Collection commonContract = Collection(_collection);158 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));159 uint256 tokenId;160161 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {} else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {162 UniqueNFT nftCollection = UniqueNFT(_collection);163 // tokenId = nftCollection.nextTokenId();164 tokenId = nftCollection.mint(address(this));165166 nftCollection.setProperties(tokenId, _properties);167168 nftCollection.transferFromCross(169 NftCrossAccountId(address(this), 0),170 NftCrossAccountId(address(0), _substrateReceiver),171 tokenId172 );173 } else {174 revert("Wrong collection type. Works only with NFT or RFT");175 }176177 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);178 }179180 function proxyProperties(181 address _collection,182 uint256 _tokenId,183 NftProperty[] calldata _properties184 ) external checkRestrictions(_collection) {185 uint256 propertiesLength = _properties.length;186 require(propertiesLength > 0, "Properies is empty");187188 Collection commonContract = Collection(_collection);189 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));190 191 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {192 revert("Wrong collection type. Works only with NFT or RFT");193 } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {194 UniqueNFT nftCollection = UniqueNFT(_collection);195 196197 nftCollection.setProperties(_tokenId, _properties);198 } else {199 revert("Wrong collection type. Works only with NFT or RFT");200 }201 }202}tests/src/eth/evmToSubstrate/coderTest.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/eth/evmToSubstrate/coderTest.ts
@@ -0,0 +1,215 @@
+import { EthUniqueHelper, usingEthPlaygrounds } from '../util';
+import { readFile } from 'fs/promises';
+import { ContractImports } from '../util/playgrounds/types';
+import { Contract } from '@polkadot/api-contract/base';
+import Web3 from 'web3';
+import {
+ IProperty,
+ ITokenPropertyPermission,
+} from '../../util/playgrounds/types';
+import { addressToEvm, decodeAddress } from '@polkadot/util-crypto';
+import nonFungibleAbi from '../nonFungibleAbi.json';
+import { IKeyringPair } from '@polkadot/types/types';
+
+enum SponsoringMode {
+ Disabled = 0,
+ Allowlisted = 1,
+ Generous = 2,
+}
+
+const WS_ENDPOINT = 'wss://ws-rc.unique.network';
+const CONTRACT_IMPORT: ContractImports[] = [
+ {
+ fsPath: `${__dirname}/../api/CollectionHelpers.sol`,
+ solPath: 'api/CollectionHelpers.sol',
+ },
+ {
+ fsPath: `${__dirname}/../api/ContractHelpers.sol`,
+ solPath: 'api/ContractHelpers.sol',
+ },
+ {
+ fsPath: `${__dirname}/../api/UniqueRefungibleToken.sol`,
+ solPath: 'api/UniqueRefungibleToken.sol',
+ },
+ {
+ fsPath: `${__dirname}/../api/UniqueRefungible.sol`,
+ solPath: 'api/UniqueRefungible.sol',
+ },
+ {
+ fsPath: `${__dirname}/../api/UniqueNFT.sol`,
+ solPath: 'api/UniqueNFT.sol',
+ },
+];
+
+const main = async () => {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ const contract_source = (
+ await readFile(`${__dirname}/EvmToSubstrateHelper.sol`)
+ ).toString();
+
+ const donor = await privateKey('//Alice'); // Seed from account with balance on this network
+ const myAccount = await privateKey('//Bob'); // replace with account from polkadot extension
+ const signer = await helper.eth.createAccountWithBalance(donor, 100n);
+ console.log(`signer data: ${Uint8Array.from(Buffer.from(signer.slice(2), 'hex'))}`)
+ const collection = await helper.nft.mintCollection(donor, {
+ name: 'test mintToSubstrate',
+ description: 'EVMHelpers',
+ tokenPrefix: 'ap',
+ tokenPropertyPermissions: [
+ {
+ key: 'url',
+ permission: {
+ tokenOwner: true,
+ collectionAdmin: true,
+ mutable: true,
+ },
+ },
+ ],
+ limits: { sponsorTransferTimeout: 0, sponsorApproveTimeout: 0 },
+ permissions: { mintMode: true },
+ });
+
+ await collection.addToAllowList(donor, {
+ Ethereum: helper.address.substrateToEth(donor.address),
+ });
+ await collection.addToAllowList(donor, { Substrate: donor.address });
+ await collection.addAdmin(donor, { Ethereum: signer });
+ await collection.addAdmin(donor, {
+ Ethereum: helper.address.substrateToEth(donor.address),
+ });
+
+ console.log('collection admin(s)): ', await collection.getAdmins());
+ console.log('collection owner(s)): ', await collection.getAllowList());
+
+ const collectionEthAddress = helper.ethAddress.fromCollectionId(
+ collection.collectionId,
+ );
+
+ const collectionEthContract = helper.ethNativeContract.collection(
+ collectionEthAddress,
+ 'nft',
+ );
+
+ const receiverEthAddress = helper.address.substrateToEth(myAccount.address);
+
+ const contract = await helper.ethContract.deployByCode(
+ signer,
+ 'EvmToSubstrate',
+ contract_source,
+ CONTRACT_IMPORT,
+ );
+ console.log(`contract has been deployed\naddres: ${contract.options.address} || ${Uint8Array.from(Buffer.from(contract.options.address.slice(2), 'hex'))}`);
+
+ await helper.eth.transferBalanceFromSubstrate(
+ donor,
+ contract.options.address,
+ 100n,
+ );
+
+ console.log(`transfer has been completed`);
+
+ await collection.addToAllowList(donor, {
+ Ethereum: contract.options.address,
+ });
+ await collection.addAdmin(donor, { Ethereum: contract.options.address });
+
+ console.log(`setup has been completed`);
+
+ console.log('\t\t\t *** Properties Fees ***\n');
+
+ const propertiesNumber = 20;
+
+ const properties = Array(40)
+ .fill(0)
+ .map((_, i) => {
+ return {
+ key: `key_${i}`,
+ value: Uint8Array.from(Buffer.from(`value_${i}`)),
+ };
+ });
+
+ const permissions: ITokenPropertyPermission[] = properties.map((p) => {
+ return {
+ key: p.key,
+ permission: {
+ tokenOwner: true,
+ collectionAdmin: true,
+ mutable: true,
+ },
+ };
+ });
+
+ // *** ProxyContract Bulk ***
+
+ const token = await collection.mintToken(donor, { Ethereum: signer });
+
+ const mintWithBulkPropProxyContractFee = await helper.arrange.calculcateFee(
+ { Ethereum: signer },
+ async () => {
+ await contract.methods
+ .proxyProperties(
+ collectionEthContract.options.address,
+ token.tokenId,
+ properties.slice(0, propertiesNumber).map((p) => {
+ return { field_0: p.key, field_1: p.value };
+ }),
+ )
+ .send({ from: signer });
+ },
+ );
+ console.log(
+ `token mint from contract(with bulk prop.) to the Substrate Id: ${mintWithBulkPropProxyContractFee}`,
+ );
+
+ console.log('All done');
+ });
+};
+
+main()
+ .then(() => process.exit(0))
+ .catch((e) => {
+ console.log(e);
+ process.exit(1);
+ });
+
+async function createCollectionForPropertiesBenchmarks(
+ helper: EthUniqueHelper,
+ privateKey: (seed: string) => Promise<IKeyringPair>,
+ ethSigner: string,
+ proxyContract: string,
+ permissions: ITokenPropertyPermission[],
+) {
+ const donor = await privateKey('//Alice'); // Seed from account with balance on this network
+
+ const collection = await helper.nft.mintCollection(donor, {
+ name: 'test mintToSubstrate',
+ description: 'EVMHelpers',
+ tokenPrefix: 'ap',
+ tokenPropertyPermissions: [
+ {
+ key: 'url',
+ permission: {
+ tokenOwner: true,
+ collectionAdmin: true,
+ mutable: true,
+ },
+ },
+ ],
+ limits: { sponsorTransferTimeout: 0, sponsorApproveTimeout: 0 },
+ permissions: { mintMode: true },
+ });
+
+ await collection.addToAllowList(donor, {
+ Ethereum: helper.address.substrateToEth(donor.address),
+ });
+ await collection.addToAllowList(donor, { Substrate: donor.address });
+ await collection.addAdmin(donor, { Ethereum: ethSigner });
+ await collection.addAdmin(donor, {
+ Ethereum: helper.address.substrateToEth(donor.address),
+ });
+ await collection.addToAllowList(donor, { Ethereum: proxyContract });
+ await collection.addAdmin(donor, { Ethereum: proxyContract });
+ await collection.setTokenPropertyPermissions(donor, permissions);
+
+ return collection;
+}