difftreelog
Merge pull request #277 from UniqueNetwork/feature/create-collection-ex
in: master
Add createCollectionEx call
18 files changed
pallets/common/src/lib.rsdiffbeforeafterboth14use 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 count287 CollectionAdminCountExceeded,290 CollectionAdminCountExceeded,291 /// Collection limit bounds per collection exceeded292 CollectionLimitBoundsExceeded,293 /// Tried to enable permissions which are only permitted to be disabled294 OwnerPermissionsCantBeReverted,288295289 /// Collection settings not allowing items transferring296 /// Collection settings not allowing items transferring290 TransferNotAllowed,297 TransferNotAllowed,395}402}396403397impl<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!(418428419 // =========429 // =========430431 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: data442 .pending_sponsor443 .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: data448 .limits449 .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 };420453421 // Take a (non-refundable) deposit of collection creation454 // Take a (non-refundable) deposit of collection creation422 {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 }449478528 Ok(())557 Ok(())529 }558 }559560 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 $check573 } else {574 $new.$field = $old.$field575 }576 )*577 }};578 }579580 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>>::CollectionTokenLimitExceeded600 ),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}531615532#[macro_export]616#[macro_export]pallets/fungible/src/lib.rsdiffbeforeafterboth223use 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}101101102impl<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>,pallets/nonfungible/src/lib.rsdiffbeforeafterboth3use 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,140142141// unchecked calls skips any permission checks143// unchecked calls skips any permission checks142impl<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>,pallets/refungible/src/lib.rsdiffbeforeafterboth3use 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,155156156// unchecked calls skips any permission checks157// unchecked calls skips any permission checks157impl<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>,pallets/unique/src/lib.rsdiffbeforeafterboth36use 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 exceeded88 CollectionLimitBoundsExceeded,89 /// Tried to enable permissions which are only permitted to be disabled90 OwnerPermissionsCantBeReverted,91 }85 }92}86}9387321 // returns collection ID315 // returns collection ID322 #[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 {329330 // Anyone can create a collection331 let who = ensure_signed(origin)?;324 let data: CreateCollectionData<T::AccountId> = CreateCollectionData {332333 // Create new collection334 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 }333334 /// This method creates a collection335 ///336 /// Prefer it to deprecated [`created_collection`] method347 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)?;350341351 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 params355 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 };362353363 Ok(())354 Ok(())364 }355 }365356366 /// **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;110110911102 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 $check1110 } else {1111 $new.$field = $old.$field1112 }1113 )*1114 }};1115 }11161117 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>>::CollectionTokenLimitExceeded1137 ),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 );11491150 target_collection.limits = new_limit;115110931152 <Pallet<T>>::deposit_event(Event::<T>::CollectionLimitSet(1094 <Pallet<T>>::deposit_event(Event::<T>::CollectionLimitSet(1153 collection_id1095 collection_idpallets/unique/src/tests.rsdiffbeforeafterboth5use 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;primitives/data-structs/src/lib.rsdiffbeforeafterboth263 pub meta_update_permission: MetaUpdatePermission,263 pub meta_update_permission: MetaUpdatePermission,264}264}265266#[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}265290266#[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))]tests/package.jsondiffbeforeafterboth68 "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",tests/src/check-event/createCollectionEvent.test.tsdiffbeforeafterboth27 });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);tests/src/createCollection.test.tsdiffbeforeafterboth3// file 'LICENSE', which is part of this source code package.3// file 'LICENSE', which is part of this source code package.4//4//556import 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';910chai.use(chaiAsPromised);111012describe('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);5253 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});327033describe('(!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});4489tests/src/interfaces/.gitignorediffbeforeafterbothno changes
tests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth68 * 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 exceeded73 **/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 action97 **/101 **/98 NoPermission: AugmentedError<ApiType>;102 NoPermission: AugmentedError<ApiType>;103 /**104 * Tried to enable permissions which are only permitted to be disabled105 **/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 exceeded441 **/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 disabled453 **/454 OwnerPermissionsCantBeReverted: AugmentedError<ApiType>;455 /**455 /**456 * Generic error456 * Generic error457 **/457 **/tests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth2/* eslint-disable */2/* eslint-disable */334import 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 collection675 * 676 * Prefer it to deprecated [`created_collection`] method677 **/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 * tests/src/interfaces/augment-types.tsdiffbeforeafterboth334import 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;tests/src/interfaces/unique/definitions.tsdiffbeforeafterboth67 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 },105127106 PalletUnqSchedulerScheduledV2: mkDummy('ScheduledV2'),128 PalletUnqSchedulerScheduledV2: mkDummy('ScheduledV2'),107 PalletUnqSchedulerCallSpec: mkDummy('CallSpec'),129 PalletUnqSchedulerCallSpec: mkDummy('CallSpec'),tests/src/interfaces/unique/types.tsdiffbeforeafterboth77}77}787879/** @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}838684/** @name UpDataStructsCollectionStats */87/** @name UpDataStructsCollectionStats */88 readonly alive: u32;91 readonly alive: u32;89}92}9394/** @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}9010991/** @name UpDataStructsCreateItemData */110/** @name UpDataStructsCreateItemData */92export interface UpDataStructsCreateItemData extends Struct {111export interface UpDataStructsCreateItemData extends Struct {101}120}102121103/** @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}107127108/** @name UpDataStructsSponsorshipState */128/** @name UpDataStructsSponsorshipState */tests/src/substrate/substrate-api.tsdiffbeforeafterboth95 return TransactionStatus.Fail;95 return TransactionStatus.Fail;96}96}9798export 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}9712398export function124export function99submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {125submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {tests/src/util/helpers.tsdiffbeforeafterboth283 modeprm = {refungible: null};283 modeprm = {refungible: null};284 }284 }285285286 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);289289329329330 // Run the CreateCollection transaction330 // Run the CreateCollection transaction331 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