git.delta.rocks / unique-network / refs/commits / 75d8b9094b27

difftreelog

Merge pull request #277 from UniqueNetwork/feature/create-collection-ex

kozyrevdev2022-02-17parents: #c5b0654 #0660dd1.patch.diff
in: master
Add createCollectionEx call

18 files changed

modifiedpallets/common/src/lib.rsdiffbeforeafterboth
14use up_data_structs::{14use up_data_structs::{
15 COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, ExistenceRequirement,15 COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, ExistenceRequirement,
16 MAX_TOKEN_PREFIX_LENGTH, COLLECTION_ADMINS_LIMIT, MetaUpdatePermission, Pays, PostDispatchInfo,16 MAX_TOKEN_PREFIX_LENGTH, COLLECTION_ADMINS_LIMIT, MetaUpdatePermission, Pays, PostDispatchInfo,
17 TokenId, Weight, WithdrawReasons, CollectionStats, CustomDataLimit,17 TokenId, Weight, WithdrawReasons, CollectionStats, MAX_TOKEN_OWNERSHIP, CollectionMode,
18 NFT_SPONSOR_TRANSFER_TIMEOUT, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
19 REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MAX_SPONSOR_TIMEOUT, CUSTOM_DATA_LIMIT, CollectionLimits,
20 CustomDataLimit, CreateCollectionData, SponsorshipState,
18};21};
19pub use pallet::*;22pub use pallet::*;
20use sp_core::H160;23use sp_core::H160;
285 TokenVariableDataLimitExceeded,288 TokenVariableDataLimitExceeded,
286 /// Exceeded max admin count289 /// Exceeded max admin count
287 CollectionAdminCountExceeded,290 CollectionAdminCountExceeded,
291 /// Collection limit bounds per collection exceeded
292 CollectionLimitBoundsExceeded,
293 /// Tried to enable permissions which are only permitted to be disabled
294 OwnerPermissionsCantBeReverted,
288295
289 /// Collection settings not allowing items transferring296 /// Collection settings not allowing items transferring
290 TransferNotAllowed,297 TransferNotAllowed,
395}402}
396403
397impl<T: Config> Pallet<T> {404impl<T: Config> Pallet<T> {
398 pub fn init_collection(data: Collection<T::AccountId>) -> Result<CollectionId, DispatchError> {405 pub fn init_collection(
406 owner: T::AccountId,
407 data: CreateCollectionData<T::AccountId>,
408 ) -> Result<CollectionId, DispatchError> {
399 {409 {
400 ensure!(410 ensure!(
418428
419 // =========429 // =========
430
431 let collection = Collection {
432 owner: owner.clone(),
433 name: data.name,
434 mode: data.mode.clone(),
435 mint_mode: false,
436 access: data.access.unwrap_or_default(),
437 description: data.description,
438 token_prefix: data.token_prefix,
439 offchain_schema: data.offchain_schema,
440 schema_version: data.schema_version.unwrap_or_default(),
441 sponsorship: data
442 .pending_sponsor
443 .map(SponsorshipState::Unconfirmed)
444 .unwrap_or_default(),
445 variable_on_chain_schema: data.variable_on_chain_schema,
446 const_on_chain_schema: data.const_on_chain_schema,
447 limits: data
448 .limits
449 .map(|limits| Self::clamp_limits(data.mode.clone(), &Default::default(), limits))
450 .unwrap_or_else(|| Ok(CollectionLimits::default()))?,
451 meta_update_permission: data.meta_update_permission.unwrap_or_default(),
452 };
420453
421 // Take a (non-refundable) deposit of collection creation454 // Take a (non-refundable) deposit of collection creation
422 {455 {
429 ),462 ),
430 );463 );
431 <T as Config>::Currency::settle(464 <T as Config>::Currency::settle(
432 &data.owner,465 &owner,
433 imbalance,466 imbalance,
434 WithdrawReasons::TRANSFER,467 WithdrawReasons::TRANSFER,
435 ExistenceRequirement::KeepAlive,468 ExistenceRequirement::KeepAlive,
441 <Pallet<T>>::deposit_event(Event::CollectionCreated(474 <Pallet<T>>::deposit_event(Event::CollectionCreated(id, data.mode.id(), owner.clone()));
442 id,
443 data.mode.id(),
444 data.owner.clone(),
445 ));
446 <CollectionById<T>>::insert(id, data);475 <CollectionById<T>>::insert(id, collection);
447 Ok(id)476 Ok(id)
448 }477 }
449478
528 Ok(())557 Ok(())
529 }558 }
559
560 pub fn clamp_limits(
561 mode: CollectionMode,
562 old_limit: &CollectionLimits,
563 mut new_limit: CollectionLimits,
564 ) -> Result<CollectionLimits, DispatchError> {
565 macro_rules! limit_default {
566 ($old:ident, $new:ident, $($field:ident $(($arg:expr))? => $check:expr),* $(,)?) => {{
567 $(
568 if let Some($new) = $new.$field {
569 let $old = $old.$field($($arg)?);
570 let _ = $new;
571 let _ = $old;
572 $check
573 } else {
574 $new.$field = $old.$field
575 }
576 )*
577 }};
578 }
579
580 limit_default!(old_limit, new_limit,
581 account_token_ownership_limit => ensure!(
582 new_limit <= MAX_TOKEN_OWNERSHIP,
583 <Error<T>>::CollectionLimitBoundsExceeded,
584 ),
585 sponsor_transfer_timeout(match mode {
586 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
587 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
588 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
589 }) => ensure!(
590 new_limit <= MAX_SPONSOR_TIMEOUT,
591 <Error<T>>::CollectionLimitBoundsExceeded,
592 ),
593 sponsored_data_size => ensure!(
594 new_limit <= CUSTOM_DATA_LIMIT,
595 <Error<T>>::CollectionLimitBoundsExceeded,
596 ),
597 token_limit => ensure!(
598 old_limit >= new_limit && new_limit > 0,
599 <Error<T>>::CollectionTokenLimitExceeded
600 ),
601 owner_can_transfer => ensure!(
602 old_limit || !new_limit,
603 <Error<T>>::OwnerPermissionsCantBeReverted,
604 ),
605 owner_can_destroy => ensure!(
606 old_limit || !new_limit,
607 <Error<T>>::OwnerPermissionsCantBeReverted,
608 ),
609 sponsored_data_rate_limit => {},
610 transfers_enabled => {},
611 );
612 Ok(new_limit)
613 }
530}614}
531615
532#[macro_export]616#[macro_export]
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
22
3use core::ops::Deref;3use core::ops::Deref;
4use frame_support::{ensure};4use frame_support::{ensure};
5use up_data_structs::{AccessMode, Collection, CollectionId, TokenId};5use up_data_structs::{AccessMode, Collection, CollectionId, TokenId, CreateCollectionData};
6use pallet_common::{6use pallet_common::{
7 Error as CommonError, Event as CommonEvent, Pallet as PalletCommon, account::CrossAccountId,7 Error as CommonError, Event as CommonEvent, Pallet as PalletCommon, account::CrossAccountId,
8};8};
100}100}
101101
102impl<T: Config> Pallet<T> {102impl<T: Config> Pallet<T> {
103 pub fn init_collection(data: Collection<T::AccountId>) -> Result<CollectionId, DispatchError> {103 pub fn init_collection(
104 owner: T::AccountId,
105 data: CreateCollectionData<T::AccountId>,
106 ) -> Result<CollectionId, DispatchError> {
104 <PalletCommon<T>>::init_collection(data)107 <PalletCommon<T>>::init_collection(owner, data)
105 }108 }
106 pub fn destroy_collection(109 pub fn destroy_collection(
107 collection: FungibleHandle<T>,110 collection: FungibleHandle<T>,
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
3use erc::ERC721Events;3use erc::ERC721Events;
4use frame_support::{BoundedVec, ensure};4use frame_support::{BoundedVec, ensure};
5use up_data_structs::{AccessMode, Collection, CollectionId, CustomDataLimit, TokenId};5use up_data_structs::{
6 AccessMode, Collection, CollectionId, CustomDataLimit, TokenId, CreateCollectionData,
7};
6use pallet_common::{8use pallet_common::{
7 Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, account::CrossAccountId,9 Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, account::CrossAccountId,
140142
141// unchecked calls skips any permission checks143// unchecked calls skips any permission checks
142impl<T: Config> Pallet<T> {144impl<T: Config> Pallet<T> {
143 pub fn init_collection(data: Collection<T::AccountId>) -> Result<CollectionId, DispatchError> {145 pub fn init_collection(
146 owner: T::AccountId,
147 data: CreateCollectionData<T::AccountId>,
148 ) -> Result<CollectionId, DispatchError> {
144 <PalletCommon<T>>::init_collection(data)149 <PalletCommon<T>>::init_collection(owner, data)
145 }150 }
146 pub fn destroy_collection(151 pub fn destroy_collection(
147 collection: NonfungibleHandle<T>,152 collection: NonfungibleHandle<T>,
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
3use frame_support::{ensure, BoundedVec};3use frame_support::{ensure, BoundedVec};
4use up_data_structs::{4use up_data_structs::{
5 AccessMode, Collection, CollectionId, CustomDataLimit, MAX_REFUNGIBLE_PIECES, TokenId,5 AccessMode, Collection, CollectionId, CustomDataLimit, MAX_REFUNGIBLE_PIECES, TokenId,
6 CreateCollectionData,
6};7};
7use pallet_common::{8use pallet_common::{
8 Error as CommonError, Event as CommonEvent, Pallet as PalletCommon, account::CrossAccountId,9 Error as CommonError, Event as CommonEvent, Pallet as PalletCommon, account::CrossAccountId,
155156
156// unchecked calls skips any permission checks157// unchecked calls skips any permission checks
157impl<T: Config> Pallet<T> {158impl<T: Config> Pallet<T> {
158 pub fn init_collection(data: Collection<T::AccountId>) -> Result<CollectionId, DispatchError> {159 pub fn init_collection(
160 owner: T::AccountId,
161 data: CreateCollectionData<T::AccountId>,
162 ) -> Result<CollectionId, DispatchError> {
159 <PalletCommon<T>>::init_collection(data)163 <PalletCommon<T>>::init_collection(owner, data)
160 }164 }
161 pub fn destroy_collection(165 pub fn destroy_collection(
162 collection: RefungibleHandle<T>,166 collection: RefungibleHandle<T>,
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
36use frame_system::{self as system, ensure_signed};36use frame_system::{self as system, ensure_signed};
37use sp_runtime::{sp_std::prelude::Vec};37use sp_runtime::{sp_std::prelude::Vec};
38use up_data_structs::{38use up_data_structs::{
39 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, CUSTOM_DATA_LIMIT,39 MAX_DECIMAL_POINTS, VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT,
40 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, OFFCHAIN_SCHEMA_LIMIT,40 OFFCHAIN_SCHEMA_LIMIT, MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH,
41 FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
42 NFT_SPONSOR_TRANSFER_TIMEOUT, MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH,
43 MAX_TOKEN_PREFIX_LENGTH, AccessMode, Collection, CreateItemData, CollectionLimits,41 MAX_TOKEN_PREFIX_LENGTH, AccessMode, Collection, CreateItemData, CollectionLimits,
44 CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,42 CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,
45 CustomDataLimit,43 CreateCollectionData, CustomDataLimit,
46};44};
47use pallet_common::{45use pallet_common::{
48 account::CrossAccountId, CollectionHandle, Pallet as PalletCommon, Error as CommonError,46 account::CrossAccountId, CollectionHandle, Pallet as PalletCommon, Error as CommonError,
84 ConfirmUnsetSponsorFail,82 ConfirmUnsetSponsorFail,
85 /// Length of items properties must be greater than 0.83 /// Length of items properties must be greater than 0.
86 EmptyArgument,84 EmptyArgument,
87 /// Collection limit bounds per collection exceeded
88 CollectionLimitBoundsExceeded,
89 /// Tried to enable permissions which are only permitted to be disabled
90 OwnerPermissionsCantBeReverted,
91 }85 }
92}86}
9387
321 // returns collection ID315 // returns collection ID
322 #[weight = <SelfWeightOf<T>>::create_collection()]316 #[weight = <SelfWeightOf<T>>::create_collection()]
323 #[transactional]317 #[transactional]
318 #[deprecated]
324 pub fn create_collection(origin,319 pub fn create_collection(origin,
325 collection_name: BoundedVec<u16, ConstU32<MAX_COLLECTION_NAME_LENGTH>>,320 collection_name: BoundedVec<u16, ConstU32<MAX_COLLECTION_NAME_LENGTH>>,
326 collection_description: BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>,321 collection_description: BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>,
327 token_prefix: BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>,322 token_prefix: BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>,
328 mode: CollectionMode) -> DispatchResult {323 mode: CollectionMode) -> DispatchResult {
329
330 // Anyone can create a collection
331 let who = ensure_signed(origin)?;324 let data: CreateCollectionData<T::AccountId> = CreateCollectionData {
332
333 // Create new collection
334 let new_collection = Collection {
335 owner: who,
336 name: collection_name,325 name: collection_name,
337 mode: mode.clone(),
338 mint_mode: false,
339 access: AccessMode::Normal,
340 description: collection_description,326 description: collection_description,
341 token_prefix,327 token_prefix,
342 offchain_schema: BoundedVec::default(),328 mode,
343 schema_version: SchemaVersion::ImageURL,
344 sponsorship: SponsorshipState::Disabled,
345 variable_on_chain_schema: BoundedVec::default(),329 ..Default::default()
330 };
346 const_on_chain_schema: BoundedVec::default(),331 Self::create_collection_ex(origin, data)
332 }
333
334 /// This method creates a collection
335 ///
336 /// Prefer it to deprecated [`created_collection`] method
347 limits: Default::default(),337 #[weight = <SelfWeightOf<T>>::create_collection()]
338 #[transactional]
348 meta_update_permission: Default::default(),339 pub fn create_collection_ex(origin, data: CreateCollectionData<T::AccountId>) -> DispatchResult {
349 };340 let owner = ensure_signed(origin)?;
350341
351 let _id = match mode {342 let _id = match data.mode {
352 CollectionMode::NFT => {<PalletNonfungible<T>>::init_collection(new_collection)?},343 CollectionMode::NFT => {<PalletNonfungible<T>>::init_collection(owner, data)?},
353 CollectionMode::Fungible(decimal_points) => {344 CollectionMode::Fungible(decimal_points) => {
354 // check params345 // check params
355 ensure!(decimal_points <= MAX_DECIMAL_POINTS, Error::<T>::CollectionDecimalPointLimitExceeded);346 ensure!(decimal_points <= MAX_DECIMAL_POINTS, Error::<T>::CollectionDecimalPointLimitExceeded);
356 <PalletFungible<T>>::init_collection(new_collection)?347 <PalletFungible<T>>::init_collection(owner, data)?
357 }348 }
358 CollectionMode::ReFungible => {349 CollectionMode::ReFungible => {
359 <PalletRefungible<T>>::init_collection(new_collection)?350 <PalletRefungible<T>>::init_collection(owner, data)?
360 }351 }
361 };352 };
362353
363 Ok(())354 Ok(())
364 }355 }
365356
366 /// **DANGEROUS**: Destroys collection and all NFTs within this collection. Users irrecoverably lose their assets and may lose real money.357 /// **DANGEROUS**: Destroys collection and all NFTs within this collection. Users irrecoverably lose their assets and may lose real money.
367 ///358 ///
1093 collection_id: CollectionId,1084 collection_id: CollectionId,
1094 new_limit: CollectionLimits,1085 new_limit: CollectionLimits,
1095 ) -> DispatchResult {1086 ) -> DispatchResult {
1096 let mut new_limit = new_limit;
1097 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);1087 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
1098 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;1088 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
1099 target_collection.check_is_owner(&sender)?;1089 target_collection.check_is_owner(&sender)?;
1100 let old_limit = &target_collection.limits;1090 let old_limit = &target_collection.limits;
11011091
1102 macro_rules! limit_default {
1103 ($old:ident, $new:ident, $($field:ident $(($arg:expr))? => $check:expr),* $(,)?) => {{
1104 $(
1105 if let Some($new) = $new.$field {1092 target_collection.limits = <PalletCommon<T>>::clamp_limits(target_collection.mode.clone(), &old_limit, new_limit)?;
1106 let $old = $old.$field($($arg)?);
1107 let _ = $new;
1108 let _ = $old;
1109 $check
1110 } else {
1111 $new.$field = $old.$field
1112 }
1113 )*
1114 }};
1115 }
1116
1117 limit_default!(old_limit, new_limit,
1118 account_token_ownership_limit => ensure!(
1119 new_limit <= MAX_TOKEN_OWNERSHIP,
1120 <Error<T>>::CollectionLimitBoundsExceeded,
1121 ),
1122 sponsor_transfer_timeout(match target_collection.mode {
1123 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
1124 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
1125 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
1126 }) => ensure!(
1127 new_limit <= MAX_SPONSOR_TIMEOUT,
1128 <Error<T>>::CollectionLimitBoundsExceeded,
1129 ),
1130 sponsored_data_size => ensure!(
1131 new_limit <= CUSTOM_DATA_LIMIT,
1132 <Error<T>>::CollectionLimitBoundsExceeded,
1133 ),
1134 token_limit => ensure!(
1135 old_limit >= new_limit && new_limit > 0,
1136 <CommonError<T>>::CollectionTokenLimitExceeded
1137 ),
1138 owner_can_transfer => ensure!(
1139 old_limit || !new_limit,
1140 <Error<T>>::OwnerPermissionsCantBeReverted,
1141 ),
1142 owner_can_destroy => ensure!(
1143 old_limit || !new_limit,
1144 <Error<T>>::OwnerPermissionsCantBeReverted,
1145 ),
1146 sponsored_data_rate_limit => {},
1147 transfers_enabled => {},
1148 );
1149
1150 target_collection.limits = new_limit;
11511093
1152 <Pallet<T>>::deposit_event(Event::<T>::CollectionLimitSet(1094 <Pallet<T>>::deposit_event(Event::<T>::CollectionLimitSet(
1153 collection_id1095 collection_id
modifiedpallets/unique/src/tests.rsdiffbeforeafterboth
5use up_data_structs::{5use up_data_structs::{
6 COLLECTION_NUMBER_LIMIT, CollectionId, CreateItemData, CreateFungibleData, CreateNftData,6 COLLECTION_NUMBER_LIMIT, CollectionId, CreateItemData, CreateFungibleData, CreateNftData,
7 CreateReFungibleData, MAX_DECIMAL_POINTS, COLLECTION_ADMINS_LIMIT, MetaUpdatePermission,7 CreateReFungibleData, MAX_DECIMAL_POINTS, COLLECTION_ADMINS_LIMIT, MetaUpdatePermission,
8 TokenId,8 TokenId, MAX_TOKEN_OWNERSHIP,
9};9};
10use frame_support::{assert_noop, assert_ok};10use frame_support::{assert_noop, assert_ok};
11use sp_std::convert::TryInto;11use sp_std::convert::TryInto;
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
263 pub meta_update_permission: MetaUpdatePermission,263 pub meta_update_permission: MetaUpdatePermission,
264}264}
265
266#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, Debug, Derivative, MaxEncodedLen)]
267#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
268#[derivative(Default(bound = ""))]
269pub struct CreateCollectionData<AccountId> {
270 #[derivative(Default(value = "CollectionMode::NFT"))]
271 pub mode: CollectionMode,
272 pub access: Option<AccessMode>,
273 #[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
274 pub name: BoundedVec<u16, ConstU32<MAX_COLLECTION_NAME_LENGTH>>,
275 #[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
276 pub description: BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>,
277 #[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
278 pub token_prefix: BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>,
279 #[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
280 pub offchain_schema: BoundedVec<u8, ConstU32<OFFCHAIN_SCHEMA_LIMIT>>,
281 pub schema_version: Option<SchemaVersion>,
282 pub pending_sponsor: Option<AccountId>,
283 pub limits: Option<CollectionLimits>,
284 #[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
285 pub variable_on_chain_schema: BoundedVec<u8, ConstU32<VARIABLE_ON_CHAIN_SCHEMA_LIMIT>>,
286 #[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
287 pub const_on_chain_schema: BoundedVec<u8, ConstU32<CONST_ON_CHAIN_SCHEMA_LIMIT>>,
288 pub meta_update_permission: Option<MetaUpdatePermission>,
289}
265290
266#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]291#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]
267#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]292#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
modifiedtests/package.jsondiffbeforeafterboth
68 "testPalletPresence": "mocha --timeout 9999999 -r ts-node/register ./**/pallet-presence.test.ts",68 "testPalletPresence": "mocha --timeout 9999999 -r ts-node/register ./**/pallet-presence.test.ts",
69 "testBlockProduction": "mocha --timeout 9999999 -r ts-node/register ./**/block-production.test.ts",69 "testBlockProduction": "mocha --timeout 9999999 -r ts-node/register ./**/block-production.test.ts",
70 "testEnableDisableTransfers": "mocha --timeout 9999999 -r ts-node/register ./**/enableDisableTransfer.test.ts",70 "testEnableDisableTransfers": "mocha --timeout 9999999 -r ts-node/register ./**/enableDisableTransfer.test.ts",
71 "polkadot-types-fetch-metadata": "curl -H 'Content-Type: application/json' -d '{\"id\":\"1\", \"jsonrpc\":\"2.0\", \"method\": \"state_getMetadata\", \"params\":[]}' http://localhost:9933 > src/interfaces/metadata.json",
71 "polkadot-types-from-defs": "ts-node ./node_modules/.bin/polkadot-types-from-defs --input src/interfaces/ --package .",72 "polkadot-types-from-defs": "ts-node ./node_modules/.bin/polkadot-types-from-defs --input src/interfaces/ --package .",
72 "polkadot-types-from-chain": "ts-node ./node_modules/.bin/polkadot-types-from-chain --endpoint ws://localhost:9944 --output src/interfaces/ --package .",73 "polkadot-types-from-chain": "ts-node ./node_modules/.bin/polkadot-types-from-chain --endpoint src/interfaces/metadata.json --output src/interfaces/ --package .",
73 "polkadot-types": "yarn polkadot-types-from-defs && yarn polkadot-types-from-chain"74 "polkadot-types": "yarn polkadot-types-fetch-metadata && yarn polkadot-types-from-defs && yarn polkadot-types-from-chain"
74 },75 },
75 "author": "",76 "author": "",
76 "license": "SEE LICENSE IN ../LICENSE",77 "license": "SEE LICENSE IN ../LICENSE",
modifiedtests/src/check-event/createCollectionEvent.test.tsdiffbeforeafterboth
27 });27 });
28 it('Check event from createCollection(): ', async () => {28 it('Check event from createCollection(): ', async () => {
29 await usingApi(async (api: ApiPromise) => {29 await usingApi(async (api: ApiPromise) => {
30 const tx = api.tx.unique.createCollection([0x31], [0x32], '0x33', 'NFT');30 const tx = api.tx.unique.createCollectionEx({name: [0x31], description: [0x32], tokenPrefix: '0x33', mode: 'NFT'});
31 const events = await submitTransactionAsync(alice, tx);31 const events = await submitTransactionAsync(alice, tx);
32 const msg = JSON.stringify(uniqueEventMessage(events));32 const msg = JSON.stringify(uniqueEventMessage(events));
33 expect(msg).to.be.contain(checkSection);33 expect(msg).to.be.contain(checkSection);
modifiedtests/src/createCollection.test.tsdiffbeforeafterboth
3// file 'LICENSE', which is part of this source code package.3// file 'LICENSE', which is part of this source code package.
4//4//
55
6import chai from 'chai';6import {expect} from 'chai';
7import chaiAsPromised from 'chai-as-promised';7import privateKey from './substrate/privateKey';
8import usingApi, {executeTransaction, submitTransactionAsync} from './substrate/substrate-api';
8import {createCollectionExpectFailure, createCollectionExpectSuccess} from './util/helpers';9import {createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo} from './util/helpers';
9
10chai.use(chaiAsPromised);
1110
12describe('integration test: ext. createCollection():', () => {11describe('integration test: ext. createCollection():', () => {
13 it('Create new NFT collection', async () => {12 it('Create new NFT collection', async () => {
28 it('Create new ReFungible collection', async () => {27 it('Create new ReFungible collection', async () => {
29 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});28 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
30 });29 });
30 it('Create new collection with extra fields', async () => {
31 await usingApi(async api => {
32 const alice = privateKey('//Alice');
33 const bob = privateKey('//Bob');
34 const tx = api.tx.unique.createCollectionEx({
35 mode: {Fungible: 8},
36 access: 'AllowList',
37 name: [1],
38 description: [2],
39 tokenPrefix: '0x000000',
40 offchainSchema: '0x111111',
41 schemaVersion: 'Unique',
42 pendingSponsor: bob.address,
43 limits: {
44 accountTokenOwnershipLimit: 3,
45 },
46 variableOnChainSchema: '0x222222',
47 constOnChainSchema: '0x333333',
48 metaUpdatePermission: 'Admin',
49 });
50 const events = await submitTransactionAsync(alice, tx);
51 const result = getCreateCollectionResult(events);
52
53 const collection = (await getDetailedCollectionInfo(api, result.collectionId))!;
54 expect(collection.owner.toString()).to.equal(alice.address);
55 expect(collection.mode.asFungible.toNumber()).to.equal(8);
56 expect(collection.access.isAllowList).to.be.true;
57 expect(collection.name.map(v => v.toNumber())).to.deep.equal([1]);
58 expect(collection.description.map(v => v.toNumber())).to.deep.equal([2]);
59 expect(collection.tokenPrefix.toString()).to.equal('0x000000');
60 expect(collection.offchainSchema.toString()).to.equal('0x111111');
61 expect(collection.schemaVersion.isUnique).to.be.true;
62 expect(collection.sponsorship.asUnconfirmed.toString()).to.equal(bob.address);
63 expect(collection.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.equal(3);
64 expect(collection.variableOnChainSchema.toString()).to.equal('0x222222');
65 expect(collection.constOnChainSchema.toString()).to.equal('0x333333');
66 expect(collection.metaUpdatePermission.isAdmin).to.be.true;
67 });
68 });
31});69});
3270
33describe('(!negative test!) integration test: ext. createCollection():', () => {71describe('(!negative test!) integration test: ext. createCollection():', () => {
40 it('(!negative test!) create new NFT collection whith incorrect data (token_prefix)', async () => {78 it('(!negative test!) create new NFT collection whith incorrect data (token_prefix)', async () => {
41 await createCollectionExpectFailure({tokenPrefix: 'A'.repeat(17), mode: {type: 'NFT'}});79 await createCollectionExpectFailure({tokenPrefix: 'A'.repeat(17), mode: {type: 'NFT'}});
42 });80 });
81 it('fails when bad limits are set', async () => {
82 await usingApi(async api => {
83 const alice = privateKey('//Alice');
84 const tx = api.tx.unique.createCollectionEx({mode: 'NFT', limits: {tokenLimit: 0}});
85 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/^common.CollectionTokenLimitExceeded$/);
86 });
87 });
43});88});
4489
addedtests/src/interfaces/.gitignorediffbeforeafterboth

no changes

modifiedtests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth
68 * Collection description can not be longer than 255 char.68 * Collection description can not be longer than 255 char.
69 **/69 **/
70 CollectionDescriptionLimitExceeded: AugmentedError<ApiType>;70 CollectionDescriptionLimitExceeded: AugmentedError<ApiType>;
71 /**
72 * Collection limit bounds per collection exceeded
73 **/
74 CollectionLimitBoundsExceeded: AugmentedError<ApiType>;
71 /**75 /**
72 * Collection name can not be longer than 63 char.76 * Collection name can not be longer than 63 char.
73 **/77 **/
96 * No permission to perform action100 * No permission to perform action
97 **/101 **/
98 NoPermission: AugmentedError<ApiType>;102 NoPermission: AugmentedError<ApiType>;
103 /**
104 * Tried to enable permissions which are only permitted to be disabled
105 **/
106 OwnerPermissionsCantBeReverted: AugmentedError<ApiType>;
99 /**107 /**
100 * Collection is not in mint mode.108 * Collection is not in mint mode.
101 **/109 **/
436 * Decimal_points parameter must be lower than MAX_DECIMAL_POINTS constant, currently it is 30.444 * Decimal_points parameter must be lower than MAX_DECIMAL_POINTS constant, currently it is 30.
437 **/445 **/
438 CollectionDecimalPointLimitExceeded: AugmentedError<ApiType>;446 CollectionDecimalPointLimitExceeded: AugmentedError<ApiType>;
439 /**
440 * Collection limit bounds per collection exceeded
441 **/
442 CollectionLimitBoundsExceeded: AugmentedError<ApiType>;
443 /**447 /**
444 * This address is not set as sponsor, use setCollectionSponsor first.448 * This address is not set as sponsor, use setCollectionSponsor first.
445 **/449 **/
448 * Length of items properties must be greater than 0.452 * Length of items properties must be greater than 0.
449 **/453 **/
450 EmptyArgument: AugmentedError<ApiType>;454 EmptyArgument: AugmentedError<ApiType>;
451 /**
452 * Tried to enable permissions which are only permitted to be disabled
453 **/
454 OwnerPermissionsCantBeReverted: AugmentedError<ApiType>;
455 /**455 /**
456 * Generic error456 * Generic error
457 **/457 **/
modifiedtests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth
2/* eslint-disable */2/* eslint-disable */
33
4import type { CumulusPrimitivesParachainInherentParachainInherentData } from './polkadot';4import type { CumulusPrimitivesParachainInherentParachainInherentData } from './polkadot';
5import type { PalletCommonAccountBasicCrossAccountIdRepr, UpDataStructsAccessMode, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCreateItemData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion } from './unique';5import type { PalletCommonAccountBasicCrossAccountIdRepr, UpDataStructsAccessMode, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCreateCollectionData, UpDataStructsCreateItemData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion } from './unique';
6import type { ApiTypes, SubmittableExtrinsic } from '@polkadot/api/types';6import type { ApiTypes, SubmittableExtrinsic } from '@polkadot/api/types';
7import type { Bytes, Compact, Option, U256, Vec, bool, u128, u16, u32, u64 } from '@polkadot/types';7import type { Bytes, Compact, Option, U256, Vec, bool, u128, u16, u32, u64 } from '@polkadot/types';
8import type { Extrinsic } from '@polkadot/types/interfaces/extrinsics';8import type { Extrinsic } from '@polkadot/types/interfaces/extrinsics';
670 * * mode: [CollectionMode] collection type and type dependent data.670 * * mode: [CollectionMode] collection type and type dependent data.
671 **/671 **/
672 createCollection: AugmentedSubmittable<(collectionName: Vec<u16> | (u16 | AnyNumber | Uint8Array)[], collectionDescription: Vec<u16> | (u16 | AnyNumber | Uint8Array)[], tokenPrefix: Bytes | string | Uint8Array, mode: UpDataStructsCollectionMode | { NFT: any } | { Fungible: any } | { ReFungible: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [Vec<u16>, Vec<u16>, Bytes, UpDataStructsCollectionMode]>;672 createCollection: AugmentedSubmittable<(collectionName: Vec<u16> | (u16 | AnyNumber | Uint8Array)[], collectionDescription: Vec<u16> | (u16 | AnyNumber | Uint8Array)[], tokenPrefix: Bytes | string | Uint8Array, mode: UpDataStructsCollectionMode | { NFT: any } | { Fungible: any } | { ReFungible: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [Vec<u16>, Vec<u16>, Bytes, UpDataStructsCollectionMode]>;
673 /**
674 * This method creates a collection
675 *
676 * Prefer it to deprecated [`created_collection`] method
677 **/
678 createCollectionEx: AugmentedSubmittable<(data: UpDataStructsCreateCollectionData | { mode?: any; access?: any; name?: any; description?: any; tokenPrefix?: any; offchainSchema?: any; schemaVersion?: any; pendingSponsor?: any; limits?: any; variableOnChainSchema?: any; constOnChainSchema?: any; metaUpdatePermission?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [UpDataStructsCreateCollectionData]>;
673 /**679 /**
674 * This method creates a concrete instance of NFT Collection created with CreateCollection method.680 * This method creates a concrete instance of NFT Collection created with CreateCollection method.
675 * 681 *
modifiedtests/src/interfaces/augment-types.tsdiffbeforeafterboth
33
4import type { EthereumBlock, EthereumLog, EthereumReceipt, EthereumTransactionLegacyTransaction, EvmCoreErrorExitReason, FpRpcTransactionStatus } from './ethereum';4import type { EthereumBlock, EthereumLog, EthereumReceipt, EthereumTransactionLegacyTransaction, EvmCoreErrorExitReason, FpRpcTransactionStatus } from './ethereum';
5import type { CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmpQueueInboundStatus, CumulusPalletXcmpQueueOutboundStatus, CumulusPalletXcmpQueueQueueConfigData, CumulusPrimitivesParachainInherentParachainInherentData, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV1AbridgedHostConfiguration, PolkadotPrimitivesV1PersistedValidationData } from './polkadot';5import type { CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmpQueueInboundStatus, CumulusPalletXcmpQueueOutboundStatus, CumulusPalletXcmpQueueQueueConfigData, CumulusPrimitivesParachainInherentParachainInherentData, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV1AbridgedHostConfiguration, PolkadotPrimitivesV1PersistedValidationData } from './polkadot';
6import type { PalletCommonAccountBasicCrossAccountIdRepr, PalletNonfungibleItemData, PalletRefungibleItemData, PalletUnqSchedulerCallSpec, PalletUnqSchedulerReleases, PalletUnqSchedulerScheduledV2, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionId, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionStats, UpDataStructsCreateItemData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion, UpDataStructsSponsorshipState, UpDataStructsTokenId } from './unique';6import type { PalletCommonAccountBasicCrossAccountIdRepr, PalletNonfungibleItemData, PalletRefungibleItemData, PalletUnqSchedulerCallSpec, PalletUnqSchedulerReleases, PalletUnqSchedulerScheduledV2, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionId, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateItemData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion, UpDataStructsSponsorshipState, UpDataStructsTokenId } from './unique';
7import type { BitVec, Bool, Bytes, Data, I128, I16, I256, I32, I64, I8, Json, Null, Raw, StorageKey, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types';7import type { BitVec, Bool, Bytes, Data, I128, I16, I256, I32, I64, I8, Json, Null, Raw, StorageKey, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types';
8import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets';8import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets';
9import type { BlockAttestations, IncludedBlocks, MoreAttestations } from '@polkadot/types/interfaces/attestations';9import type { BlockAttestations, IncludedBlocks, MoreAttestations } from '@polkadot/types/interfaces/attestations';
1021 UpDataStructsCollectionLimits: UpDataStructsCollectionLimits;1021 UpDataStructsCollectionLimits: UpDataStructsCollectionLimits;
1022 UpDataStructsCollectionMode: UpDataStructsCollectionMode;1022 UpDataStructsCollectionMode: UpDataStructsCollectionMode;
1023 UpDataStructsCollectionStats: UpDataStructsCollectionStats;1023 UpDataStructsCollectionStats: UpDataStructsCollectionStats;
1024 UpDataStructsCreateCollectionData: UpDataStructsCreateCollectionData;
1024 UpDataStructsCreateItemData: UpDataStructsCreateItemData;1025 UpDataStructsCreateItemData: UpDataStructsCreateItemData;
1025 UpDataStructsMetaUpdatePermission: UpDataStructsMetaUpdatePermission;1026 UpDataStructsMetaUpdatePermission: UpDataStructsMetaUpdatePermission;
1026 UpDataStructsSchemaVersion: UpDataStructsSchemaVersion;1027 UpDataStructsSchemaVersion: UpDataStructsSchemaVersion;
modifiedtests/src/interfaces/unique/definitions.tsdiffbeforeafterboth
67 constOnChainSchema: 'Vec<u8>',67 constOnChainSchema: 'Vec<u8>',
68 metaUpdatePermission: 'UpDataStructsMetaUpdatePermission',68 metaUpdatePermission: 'UpDataStructsMetaUpdatePermission',
69 },69 },
70 UpDataStructsCreateCollectionData: {
71 mode: 'UpDataStructsCollectionMode',
72 access: 'Option<UpDataStructsAccessMode>',
73 name: 'Vec<u16>',
74 description: 'Vec<u16>',
75 tokenPrefix: 'Vec<u8>',
76 offchainSchema: 'Vec<u8>',
77 schemaVersion: 'Option<UpDataStructsSchemaVersion>',
78 pendingSponsor: 'Option<AccountId>',
79 limits: 'Option<UpDataStructsCollectionLimits>',
80 variableOnChainSchema: 'Vec<u8>',
81 constOnChainSchema: 'Vec<u8>',
82 metaUpdatePermission: 'Option<UpDataStructsMetaUpdatePermission>',
83 },
70 UpDataStructsCollectionStats: {84 UpDataStructsCollectionStats: {
71 created: 'u32',85 created: 'u32',
72 destroyed: 'u32',86 destroyed: 'u32',
76 UpDataStructsTokenId: 'u32',90 UpDataStructsTokenId: 'u32',
77 PalletNonfungibleItemData: mkDummy('NftItemData'),91 PalletNonfungibleItemData: mkDummy('NftItemData'),
78 PalletRefungibleItemData: mkDummy('RftItemData'),92 PalletRefungibleItemData: mkDummy('RftItemData'),
79 UpDataStructsCollectionMode: mkDummy('CollectionMode'),93 UpDataStructsCollectionMode: {
94 _enum: {
95 NFT: null,
96 Fungible: 'u32',
97 ReFungible: null,
98 },
99 },
80 UpDataStructsCreateItemData: mkDummy('CreateItemData'),100 UpDataStructsCreateItemData: mkDummy('CreateItemData'),
81 UpDataStructsCollectionLimits: {101 UpDataStructsCollectionLimits: {
82 accountTokenOwnershipLimit: 'Option<u32>',102 accountTokenOwnershipLimit: 'Option<u32>',
101 UpDataStructsAccessMode: {121 UpDataStructsAccessMode: {
102 _enum: ['Normal', 'AllowList'],122 _enum: ['Normal', 'AllowList'],
103 },123 },
104 UpDataStructsSchemaVersion: mkDummy('SchemaVersion'),124 UpDataStructsSchemaVersion: {
125 _enum: ['ImageURL', 'Unique'],
126 },
105127
106 PalletUnqSchedulerScheduledV2: mkDummy('ScheduledV2'),128 PalletUnqSchedulerScheduledV2: mkDummy('ScheduledV2'),
107 PalletUnqSchedulerCallSpec: mkDummy('CallSpec'),129 PalletUnqSchedulerCallSpec: mkDummy('CallSpec'),
modifiedtests/src/interfaces/unique/types.tsdiffbeforeafterboth
77}77}
7878
79/** @name UpDataStructsCollectionMode */79/** @name UpDataStructsCollectionMode */
80export interface UpDataStructsCollectionMode extends Struct {80export interface UpDataStructsCollectionMode extends Enum {
81 readonly isNft: boolean;
82 readonly isFungible: boolean;
81 readonly dummyCollectionMode: u32;83 readonly asFungible: u32;
84 readonly isReFungible: boolean;
82}85}
8386
84/** @name UpDataStructsCollectionStats */87/** @name UpDataStructsCollectionStats */
88 readonly alive: u32;91 readonly alive: u32;
89}92}
93
94/** @name UpDataStructsCreateCollectionData */
95export interface UpDataStructsCreateCollectionData extends Struct {
96 readonly mode: UpDataStructsCollectionMode;
97 readonly access: Option<UpDataStructsAccessMode>;
98 readonly name: Vec<u16>;
99 readonly description: Vec<u16>;
100 readonly tokenPrefix: Bytes;
101 readonly offchainSchema: Bytes;
102 readonly schemaVersion: Option<UpDataStructsSchemaVersion>;
103 readonly pendingSponsor: Option<AccountId>;
104 readonly limits: Option<UpDataStructsCollectionLimits>;
105 readonly variableOnChainSchema: Bytes;
106 readonly constOnChainSchema: Bytes;
107 readonly metaUpdatePermission: Option<UpDataStructsMetaUpdatePermission>;
108}
90109
91/** @name UpDataStructsCreateItemData */110/** @name UpDataStructsCreateItemData */
92export interface UpDataStructsCreateItemData extends Struct {111export interface UpDataStructsCreateItemData extends Struct {
101}120}
102121
103/** @name UpDataStructsSchemaVersion */122/** @name UpDataStructsSchemaVersion */
104export interface UpDataStructsSchemaVersion extends Struct {123export interface UpDataStructsSchemaVersion extends Enum {
105 readonly dummySchemaVersion: u32;124 readonly isImageUrl: boolean;
125 readonly isUnique: boolean;
106}126}
107127
108/** @name UpDataStructsSponsorshipState */128/** @name UpDataStructsSponsorshipState */
modifiedtests/src/substrate/substrate-api.tsdiffbeforeafterboth
95 return TransactionStatus.Fail;95 return TransactionStatus.Fail;
96}96}
97
98export function executeTransaction(api: ApiPromise, sender: IKeyringPair, transaction: SubmittableExtrinsic<'promise'>): Promise<EventRecord[]> {
99 return new Promise(async (res, rej) => {
100 try {
101 await transaction.signAndSend(sender, ({events, status}) => {
102 if (!status.isInBlock && !status.isFinalized) return;
103 for (const {event} of events) {
104 if (api.events.system.ExtrinsicSuccess.is(event)) {
105 res(events);
106 } else if (api.events.system.ExtrinsicFailed.is(event)) {
107 const {data: [error]} = event;
108 if (error.isModule) {
109 const decoded = api.registry.findMetaError(error.asModule);
110 const {method, section} = decoded;
111 rej(new Error(`${section}.${method}`));
112 } else {
113 rej(new Error(error.toString()));
114 }
115 }
116 }
117 });
118 } catch (e) {
119 rej(e);
120 }
121 });
122}
97123
98export function124export function
99submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {125submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
283 modeprm = {refungible: null};283 modeprm = {refungible: null};
284 }284 }
285285
286 const tx = api.tx.unique.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm as any);286 const tx = api.tx.unique.createCollectionEx({name: strToUTF16(name), description: strToUTF16(description), tokenPrefix: strToUTF16(tokenPrefix), mode: modeprm as any});
287 const events = await submitTransactionAsync(alicePrivateKey, tx);287 const events = await submitTransactionAsync(alicePrivateKey, tx);
288 const result = getCreateCollectionResult(events);288 const result = getCreateCollectionResult(events);
289289
329329
330 // Run the CreateCollection transaction330 // Run the CreateCollection transaction
331 const alicePrivateKey = privateKey('//Alice');331 const alicePrivateKey = privateKey('//Alice');
332 const tx = api.tx.unique.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm as any);332 const tx = api.tx.unique.createCollectionEx({name: strToUTF16(name), description: strToUTF16(description), tokenPrefix: strToUTF16(tokenPrefix), mode: modeprm as any});
333 const events = await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected;333 const events = await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected;
334 const result = getCreateCollectionResult(events);334 const result = getCreateCollectionResult(events);
335335