From fb129ad11e2885700d9ac902f28373c1139f2f6b Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Tue, 11 Jan 2022 19:02:15 +0000 Subject: [PATCH] test: createCollectionEx --- --- a/tests/package.json +++ b/tests/package.json @@ -67,9 +67,10 @@ "testPalletPresence": "mocha --timeout 9999999 -r ts-node/register ./**/pallet-presence.test.ts", "testBlockProduction": "mocha --timeout 9999999 -r ts-node/register ./**/block-production.test.ts", "testEnableDisableTransfers": "mocha --timeout 9999999 -r ts-node/register ./**/enableDisableTransfer.test.ts", + "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", "polkadot-types-from-defs": "ts-node ./node_modules/.bin/polkadot-types-from-defs --input src/interfaces/ --package .", - "polkadot-types-from-chain": "ts-node ./node_modules/.bin/polkadot-types-from-chain --endpoint ws://localhost:9944 --output src/interfaces/ --package .", - "polkadot-types": "yarn polkadot-types-from-defs && yarn polkadot-types-from-chain" + "polkadot-types-from-chain": "ts-node ./node_modules/.bin/polkadot-types-from-chain --endpoint src/interfaces/metadata.json --output src/interfaces/ --package .", + "polkadot-types": "yarn polkadot-types-fetch-metadata && yarn polkadot-types-from-defs && yarn polkadot-types-from-chain" }, "author": "", "license": "SEE LICENSE IN ../LICENSE", --- a/tests/src/check-event/createCollectionEvent.test.ts +++ b/tests/src/check-event/createCollectionEvent.test.ts @@ -27,7 +27,7 @@ }); it('Check event from createCollection(): ', async () => { await usingApi(async (api: ApiPromise) => { - const tx = api.tx.unique.createCollection([0x31], [0x32], '0x33', 'NFT'); + const tx = api.tx.unique.createCollectionEx({name: [0x31], description: [0x32], tokenPrefix: '0x33', mode: 'NFT'}); const events = await submitTransactionAsync(alice, tx); const msg = JSON.stringify(uniqueEventMessage(events)); expect(msg).to.be.contain(checkSection); --- a/tests/src/createCollection.test.ts +++ b/tests/src/createCollection.test.ts @@ -3,12 +3,11 @@ // file 'LICENSE', which is part of this source code package. // -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import {createCollectionExpectFailure, createCollectionExpectSuccess} from './util/helpers'; +import {expect} from 'chai'; +import privateKey from './substrate/privateKey'; +import usingApi, {executeTransaction, submitTransactionAsync} from './substrate/substrate-api'; +import {createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo} from './util/helpers'; -chai.use(chaiAsPromised); - describe('integration test: ext. createCollection():', () => { it('Create new NFT collection', async () => { await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}}); @@ -28,6 +27,45 @@ it('Create new ReFungible collection', async () => { await createCollectionExpectSuccess({mode: {type: 'ReFungible'}}); }); + it('Create new collection with extra fields', async () => { + await usingApi(async api => { + const alice = privateKey('//Alice'); + const bob = privateKey('//Bob'); + const tx = api.tx.unique.createCollectionEx({ + mode: {Fungible: 8}, + access: 'AllowList', + name: [1], + description: [2], + tokenPrefix: '0x000000', + offchainSchema: '0x111111', + schemaVersion: 'Unique', + pendingSponsor: bob.address, + limits: { + accountTokenOwnershipLimit: 3, + }, + variableOnChainSchema: '0x222222', + constOnChainSchema: '0x333333', + metaUpdatePermission: 'Admin', + }); + const events = await submitTransactionAsync(alice, tx); + const result = getCreateCollectionResult(events); + + const collection = (await getDetailedCollectionInfo(api, result.collectionId))!; + expect(collection.owner.toString()).to.equal(alice.address); + expect(collection.mode.asFungible.toNumber()).to.equal(8); + expect(collection.access.isAllowList).to.be.true; + expect(collection.name.map(v => v.toNumber())).to.deep.equal([1]); + expect(collection.description.map(v => v.toNumber())).to.deep.equal([2]); + expect(collection.tokenPrefix.toString()).to.equal('0x000000'); + expect(collection.offchainSchema.toString()).to.equal('0x111111'); + expect(collection.schemaVersion.isUnique).to.be.true; + expect(collection.sponsorship.asUnconfirmed.toString()).to.equal(bob.address); + expect(collection.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.equal(3); + expect(collection.variableOnChainSchema.toString()).to.equal('0x222222'); + expect(collection.constOnChainSchema.toString()).to.equal('0x333333'); + expect(collection.metaUpdatePermission.isAdmin).to.be.true; + }); + }); }); describe('(!negative test!) integration test: ext. createCollection():', () => { @@ -40,4 +78,11 @@ it('(!negative test!) create new NFT collection whith incorrect data (token_prefix)', async () => { await createCollectionExpectFailure({tokenPrefix: 'A'.repeat(17), mode: {type: 'NFT'}}); }); + it('fails when bad limits are set', async () => { + await usingApi(async api => { + const alice = privateKey('//Alice'); + const tx = api.tx.unique.createCollectionEx({mode: 'NFT', limits: {tokenLimit: 0}}); + await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/^common.CollectionTokenLimitExceeded$/); + }); + }); }); --- /dev/null +++ b/tests/src/interfaces/.gitignore @@ -0,0 +1 @@ +metadata.json --- a/tests/src/interfaces/augment-api-consts.ts +++ b/tests/src/interfaces/augment-api-consts.ts @@ -36,6 +36,9 @@ [key: string]: Codec; }; inflation: { + /** + * Number of blocks that pass between treasury balance updates due to inflation + **/ inflationBlockInterval: u32 & AugmentedConst; /** * Generic const --- a/tests/src/interfaces/augment-api-errors.ts +++ b/tests/src/interfaces/augment-api-errors.ts @@ -61,14 +61,18 @@ **/ CantApproveMoreThanOwned: AugmentedError; /** - * Exceeded max admin amount + * Exceeded max admin count **/ - CollectionAdminAmountExceeded: AugmentedError; + CollectionAdminCountExceeded: AugmentedError; /** * Collection description can not be longer than 255 char. **/ CollectionDescriptionLimitExceeded: AugmentedError; /** + * Collection limit bounds per collection exceeded + **/ + CollectionLimitBoundsExceeded: AugmentedError; + /** * Collection name can not be longer than 63 char. **/ CollectionNameLimitExceeded: AugmentedError; @@ -97,6 +101,10 @@ **/ NoPermission: AugmentedError; /** + * Tried to enable permissions which are only permitted to be disabled + **/ + OwnerPermissionsCantBeReverted: AugmentedError; + /** * Collection is not in mint mode. **/ PublicMintingNotAllowed: AugmentedError; @@ -227,7 +235,7 @@ /** * Tried to set data for fungible item **/ - FungibleItemsHaveData: AugmentedError; + FungibleItemsDontHaveData: AugmentedError; /** * Not default id passed as TokenId argument **/ @@ -381,6 +389,10 @@ }; system: { /** + * The origin filter prevent the call to be dispatched. + **/ + CallFiltered: AugmentedError; + /** * Failed to extract the runtime version from the new runtime. * * Either calling `Core_version` or decoding `RuntimeVersion` failed. @@ -433,10 +445,6 @@ **/ CollectionDecimalPointLimitExceeded: AugmentedError; /** - * Collection limit bounds per collection exceeded - **/ - CollectionLimitBoundsExceeded: AugmentedError; - /** * This address is not set as sponsor, use setCollectionSponsor first. **/ ConfirmUnsetSponsorFail: AugmentedError; @@ -444,10 +452,6 @@ * Length of items properties must be greater than 0. **/ EmptyArgument: AugmentedError; - /** - * Tried to enable permissions which are only permitted to be disabled - **/ - OwnerPermissionsCantBeReverted: AugmentedError; /** * Generic error **/ --- a/tests/src/interfaces/augment-api-events.ts +++ b/tests/src/interfaces/augment-api-events.ts @@ -2,7 +2,7 @@ /* eslint-disable */ import type { EthereumLog, EvmCoreErrorExitReason } from './ethereum'; -import type { PalletCommonAccountBasicCrossAccountIdRepr } from './unique'; +import type { PalletCommonAccountBasicCrossAccountIdRepr, UpDataStructsAccessMode } from './unique'; import type { ApiTypes } from '@polkadot/api/types'; import type { Null, Option, Result, U256, U8aFixed, u128, u32, u64, u8 } from '@polkadot/types'; import type { AccountId32, H160, H256 } from '@polkadot/types/interfaces/runtime'; @@ -12,48 +12,45 @@ export interface AugmentedEvents { balances: { /** - * A balance was set by root. \[who, free, reserved\] + * A balance was set by root. **/ BalanceSet: AugmentedEvent; /** - * Some amount was deposited into the account (e.g. for transaction fees). \[who, - * deposit\] + * Some amount was deposited (e.g. for transaction fees). **/ Deposit: AugmentedEvent; /** * An account was removed whose balance was non-zero but below ExistentialDeposit, - * resulting in an outright loss. \[account, balance\] + * resulting in an outright loss. **/ DustLost: AugmentedEvent; /** - * An account was created with some free balance. \[account, free_balance\] + * An account was created with some free balance. **/ Endowed: AugmentedEvent; /** - * Some balance was reserved (moved from free to reserved). \[who, value\] + * Some balance was reserved (moved from free to reserved). **/ Reserved: AugmentedEvent; /** * Some balance was moved from the reserve of the first account to the second account. * Final argument indicates the destination balance type. - * \[from, to, balance, destination_status\] **/ ReserveRepatriated: AugmentedEvent; /** - * Some amount was removed from the account (e.g. for misbehavior). \[who, - * amount_slashed\] + * Some amount was removed from the account (e.g. for misbehavior). **/ Slashed: AugmentedEvent; /** - * Transfer succeeded. \[from, to, value\] + * Transfer succeeded. **/ Transfer: AugmentedEvent; /** - * Some balance was unreserved (moved from reserved to free). \[who, value\] + * Some balance was unreserved (moved from reserved to free). **/ Unreserved: AugmentedEvent; /** - * Some amount was withdrawn from the account (e.g. for transaction fees). \[who, value\] + * Some amount was withdrawn from the account (e.g. for transaction fees). **/ Withdraw: AugmentedEvent; /** @@ -87,6 +84,14 @@ **/ CollectionCreated: AugmentedEvent; /** + * New collection was destroyed + * + * # Arguments + * + * * collection_id: Globally unique identifier of collection. + **/ + CollectionDestroyed: AugmentedEvent; + /** * New item was created. * * # Arguments @@ -289,7 +294,7 @@ InvalidResponder: AugmentedEvent]>; /** * Expected query response has been received but the expected origin location placed in - * storate by this runtime previously cannot be decoded. The query remains registered. + * storage by this runtime previously cannot be decoded. The query remains registered. * * This is unexpected (since a location placed in storage in a previously executing * runtime should be readable prior to query timeout) and dangerous since the possibly @@ -471,6 +476,148 @@ **/ [key: string]: AugmentedEvent; }; + unique: { + /** + * Address was add to allow list + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + * + * * user: Address. + **/ + AllowListAddressAdded: AugmentedEvent; + /** + * Address was remove from allow list + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + * + * * user: Address. + **/ + AllowListAddressRemoved: AugmentedEvent; + /** + * Collection admin was added + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + * + * * admin: Admin address. + **/ + CollectionAdminAdded: AugmentedEvent; + /** + * Collection admin was removed + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + * + * * admin: Admin address. + **/ + CollectionAdminRemoved: AugmentedEvent; + /** + * Collection limits was set + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + **/ + CollectionLimitSet: AugmentedEvent; + /** + * Collection owned was change + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + * + * * owner: New owner address. + **/ + CollectionOwnedChanged: AugmentedEvent; + /** + * Collection sponsor was removed + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + **/ + CollectionSponsorRemoved: AugmentedEvent; + /** + * Collection sponsor was set + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + * + * * owner: New sponsor address. + **/ + CollectionSponsorSet: AugmentedEvent; + /** + * const on chain schema was set + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + **/ + ConstOnChainSchemaSet: AugmentedEvent; + /** + * Mint permission was set + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + **/ + MintPermissionSet: AugmentedEvent; + /** + * Offchain schema was set + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + **/ + OffchainSchemaSet: AugmentedEvent; + /** + * Public access mode was set + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + * + * * mode: New access state. + **/ + PublicAccessModeSet: AugmentedEvent; + /** + * Schema version was set + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + **/ + SchemaVersionSet: AugmentedEvent; + /** + * New sponsor was confirm + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + * + * * sponsor: New sponsor address. + **/ + SponsorshipConfirmed: AugmentedEvent; + /** + * Variable on chain schema was set + * + * # Arguments + * + * * collection_id: Globally unique collection identifier. + **/ + VariableOnChainSchemaSet: AugmentedEvent; + /** + * Generic event + **/ + [key: string]: AugmentedEvent; + }; vesting: { /** * Claimed vesting. \[who, locked_amount\] --- a/tests/src/interfaces/augment-api-query.ts +++ b/tests/src/interfaces/augment-api-query.ts @@ -163,10 +163,22 @@ }; inflation: { /** - * Current block inflation + * Current inflation for `InflationBlockInterval` number of blocks **/ blockInflation: AugmentedQuery Observable, []> & QueryableStorageEntry; /** + * Next target (relay) block when inflation will be applied + **/ + nextInflationBlock: AugmentedQuery Observable, []> & QueryableStorageEntry; + /** + * Next target (relay) block when inflation is recalculated + **/ + nextRecalculationBlock: AugmentedQuery Observable, []> & QueryableStorageEntry; + /** + * Relay block when inflation has started + **/ + startBlock: AugmentedQuery Observable, []> & QueryableStorageEntry; + /** * starting year total issuance **/ startingYearTotalIssuance: AugmentedQuery Observable, []> & QueryableStorageEntry; --- a/tests/src/interfaces/augment-api-tx.ts +++ b/tests/src/interfaces/augment-api-tx.ts @@ -3,12 +3,12 @@ import type { EthereumTransactionLegacyTransaction } from './ethereum'; import type { CumulusPrimitivesParachainInherentParachainInherentData } from './polkadot'; -import type { PalletCommonAccountBasicCrossAccountIdRepr, UpDataStructsAccessMode, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCreateItemData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion } from './unique'; +import type { PalletCommonAccountBasicCrossAccountIdRepr, UpDataStructsAccessMode, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCreateCollectionData, UpDataStructsCreateItemData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion } from './unique'; import type { ApiTypes, SubmittableExtrinsic } from '@polkadot/api/types'; import type { Bytes, Compact, Option, U256, Vec, bool, u128, u16, u32, u64 } from '@polkadot/types'; import type { Extrinsic } from '@polkadot/types/interfaces/extrinsics'; import type { AccountId32, Call, H160, H256, MultiAddress, Perbill } from '@polkadot/types/interfaces/runtime'; -import type { SpCoreChangesTrieChangesTrieConfiguration, XcmV1MultiLocation, XcmV2WeightLimit, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup'; +import type { XcmV1MultiLocation, XcmV2WeightLimit, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup'; import type { AnyNumber, ITuple } from '@polkadot/types/types'; declare module '@polkadot/api/types/submittable' { @@ -38,16 +38,6 @@ * it will reset the account nonce (`frame_system::AccountNonce`). * * The dispatch origin for this call is `root`. - * - * # - * - Independent of the arguments. - * - Contains a limited number of reads and writes. - * --------------------- - * - Base Weight: - * - Creating: 27.56 µs - * - Killing: 35.11 µs - * - DB Weight: 1 Read, 1 Write to `who` - * # **/ setBalance: AugmentedSubmittable<(who: MultiAddress | { Id: any } | { Index: any } | { Raw: any } | { Address32: any } | { Address20: any } | string | Uint8Array, newFree: Compact | AnyNumber | Uint8Array, newReserved: Compact | AnyNumber | Uint8Array) => SubmittableExtrinsic, [MultiAddress, Compact, Compact]>; /** @@ -75,8 +65,6 @@ * - `transfer_keep_alive` works the same way as `transfer`, but has an additional check * that the transfer will not kill the origin account. * --------------------------------- - * - Base Weight: 73.64 µs, worst case scenario (account created, account removed) - * - DB Weight: 1 Read and 1 Write to destination account * - Origin account is already in memory, so no DB operations for them. * # **/ @@ -108,11 +96,6 @@ * 99% of the time you want [`transfer`] instead. * * [`transfer`]: struct.Pallet.html#method.transfer - * # - * - Cheaper than transfer because account cannot be killed. - * - Base Weight: 51.4 µs - * - DB Weight: 1 Read and 1 Write to dest (sender is in overlay already) - * # **/ transferKeepAlive: AugmentedSubmittable<(dest: MultiAddress | { Id: any } | { Index: any } | { Raw: any } | { Address32: any } | { Address20: any } | string | Uint8Array, value: Compact | AnyNumber | Uint8Array) => SubmittableExtrinsic, [MultiAddress, Compact]>; /** @@ -197,6 +180,20 @@ }; inflation: { /** + * This method sets the inflation start date. Can be only called once. + * Inflation start block can be backdated and will catch up. The method will create Treasury + * account if it does not exist and perform the first inflation deposit. + * + * # Permissions + * + * * Root + * + * # Arguments + * + * * inflation_start_relay_block: The relay chain block at which inflation should start + **/ + startInflation: AugmentedSubmittable<(inflationStartRelayBlock: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u32]>; + /** * Generic tx **/ [key: string]: SubmittableExtrinsicFunction; @@ -374,7 +371,7 @@ * - Weight of derivative `call` execution + 10,000. * # **/ - sudo: AugmentedSubmittable<(call: Call) => SubmittableExtrinsic, [Call]>; + sudo: AugmentedSubmittable<(call: Call | string | Uint8Array) => SubmittableExtrinsic, [Call]>; /** * Authenticates the sudo key and dispatches a function call with `Signed` origin from * a given account. @@ -388,7 +385,7 @@ * - Weight of derivative `call` execution + 10,000. * # **/ - sudoAs: AugmentedSubmittable<(who: MultiAddress | { Id: any } | { Index: any } | { Raw: any } | { Address32: any } | { Address20: any } | string | Uint8Array, ) => SubmittableExtrinsic, [MultiAddress, Call]>; + sudoAs: AugmentedSubmittable<(who: MultiAddress | { Id: any } | { Index: any } | { Raw: any } | { Address32: any } | { Address20: any } | string | Uint8Array, call: Call | string | Uint8Array) => SubmittableExtrinsic, [MultiAddress, Call]>; /** * Authenticates the sudo key and dispatches a function call with `Root` origin. * This function does not check the weight of the call, and instead allows the @@ -401,7 +398,7 @@ * - The weight of this call is defined by the caller. * # **/ - sudoUncheckedWeight: AugmentedSubmittable<(call: Call, weight: u64 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [Call, u64]>; + sudoUncheckedWeight: AugmentedSubmittable<(call: Call | string | Uint8Array, weight: u64 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [Call, u64]>; /** * Generic tx **/ @@ -417,24 +414,10 @@ * * **NOTE:** We rely on the Root origin to provide us the number of subkeys under * the prefix we are removing to accurately calculate the weight of this function. - * - * # - * - `O(P)` where `P` amount of keys with prefix `prefix` - * - `P` storage deletions. - * - Base Weight: 0.834 * P µs - * - Writes: Number of subkeys + 1 - * # **/ killPrefix: AugmentedSubmittable<(prefix: Bytes | string | Uint8Array, subkeys: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [Bytes, u32]>; /** * Kill some items from storage. - * - * # - * - `O(IK)` where `I` length of `keys` and `K` length of one key - * - `I` storage deletions. - * - Base Weight: .378 * i µs - * - Writes: Number of items - * # **/ killStorage: AugmentedSubmittable<(keys: Vec | (Bytes | string | Uint8Array)[]) => SubmittableExtrinsic, [Vec]>; /** @@ -454,19 +437,6 @@ * # **/ remarkWithEvent: AugmentedSubmittable<(remark: Bytes | string | Uint8Array) => SubmittableExtrinsic, [Bytes]>; - /** - * Set the new changes trie configuration. - * - * # - * - `O(1)` - * - 1 storage write or delete (codec `O(1)`). - * - 1 call to `deposit_log`: Uses `append` API, so O(1) - * - Base Weight: 7.218 µs - * - DB Weight: - * - Writes: Changes Trie, System Digest - * # - **/ - setChangesTrieConfig: AugmentedSubmittable<(changesTrieConfig: Option | null | object | string | Uint8Array) => SubmittableExtrinsic, [Option]>; /** * Set the new runtime code. * @@ -496,25 +466,10 @@ setCodeWithoutChecks: AugmentedSubmittable<(code: Bytes | string | Uint8Array) => SubmittableExtrinsic, [Bytes]>; /** * Set the number of pages in the WebAssembly environment's heap. - * - * # - * - `O(1)` - * - 1 storage write. - * - Base Weight: 1.405 µs - * - 1 write to HEAP_PAGES - * - 1 digest item - * # **/ setHeapPages: AugmentedSubmittable<(pages: u64 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u64]>; /** * Set some items of storage. - * - * # - * - `O(I)` where `I` length of `items` - * - `I` storage writes (`O(1)`). - * - Base Weight: 0.568 * i µs - * - Writes: Number of items - * # **/ setStorage: AugmentedSubmittable<(items: Vec> | ([Bytes | string | Uint8Array, Bytes | string | Uint8Array])[]) => SubmittableExtrinsic, [Vec>]>; /** @@ -718,6 +673,12 @@ **/ createCollection: AugmentedSubmittable<(collectionName: Vec | (u16 | AnyNumber | Uint8Array)[], collectionDescription: Vec | (u16 | AnyNumber | Uint8Array)[], tokenPrefix: Bytes | string | Uint8Array, mode: UpDataStructsCollectionMode | { NFT: any } | { Fungible: any } | { ReFungible: any } | string | Uint8Array) => SubmittableExtrinsic, [Vec, Vec, Bytes, UpDataStructsCollectionMode]>; /** + * This method creates a collection + * + * Prefer it to deprecated [`created_collection`] method + **/ + 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, [UpDataStructsCreateCollectionData]>; + /** * This method creates a concrete instance of NFT Collection created with CreateCollection method. * * # Permissions --- a/tests/src/interfaces/augment-types.ts +++ b/tests/src/interfaces/augment-types.ts @@ -3,7 +3,7 @@ import type { EthereumBlock, EthereumLog, EthereumReceipt, EthereumTransactionLegacyTransaction, EvmCoreErrorExitReason, FpRpcTransactionStatus } from './ethereum'; import type { CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmpQueueInboundStatus, CumulusPalletXcmpQueueOutboundStatus, CumulusPalletXcmpQueueQueueConfigData, CumulusPrimitivesParachainInherentParachainInherentData, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV1AbridgedHostConfiguration, PolkadotPrimitivesV1PersistedValidationData } from './polkadot'; -import type { PalletCommonAccountBasicCrossAccountIdRepr, PalletNonfungibleItemData, PalletRefungibleItemData, PalletUnqSchedulerCallSpec, PalletUnqSchedulerReleases, PalletUnqSchedulerScheduledV2, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionId, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionStats, UpDataStructsCreateItemData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion, UpDataStructsSponsorshipState, UpDataStructsTokenId } from './unique'; +import type { PalletCommonAccountBasicCrossAccountIdRepr, PalletNonfungibleItemData, PalletRefungibleItemData, PalletUnqSchedulerCallSpec, PalletUnqSchedulerReleases, PalletUnqSchedulerScheduledV2, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionId, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateItemData, UpDataStructsMetaUpdatePermission, UpDataStructsSchemaVersion, UpDataStructsSponsorshipState, UpDataStructsTokenId } from './unique'; import 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'; import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets'; import type { BlockAttestations, IncludedBlocks, MoreAttestations } from '@polkadot/types/interfaces/attestations'; @@ -1021,6 +1021,7 @@ UpDataStructsCollectionLimits: UpDataStructsCollectionLimits; UpDataStructsCollectionMode: UpDataStructsCollectionMode; UpDataStructsCollectionStats: UpDataStructsCollectionStats; + UpDataStructsCreateCollectionData: UpDataStructsCreateCollectionData; UpDataStructsCreateItemData: UpDataStructsCreateItemData; UpDataStructsMetaUpdatePermission: UpDataStructsMetaUpdatePermission; UpDataStructsSchemaVersion: UpDataStructsSchemaVersion; --- a/tests/src/interfaces/unique/definitions.ts +++ b/tests/src/interfaces/unique/definitions.ts @@ -67,6 +67,20 @@ constOnChainSchema: 'Vec', metaUpdatePermission: 'UpDataStructsMetaUpdatePermission', }, + UpDataStructsCreateCollectionData: { + mode: 'UpDataStructsCollectionMode', + access: 'Option', + name: 'Vec', + description: 'Vec', + tokenPrefix: 'Vec', + offchainSchema: 'Vec', + schemaVersion: 'Option', + pendingSponsor: 'Option', + limits: 'Option', + variableOnChainSchema: 'Vec', + constOnChainSchema: 'Vec', + metaUpdatePermission: 'Option', + }, UpDataStructsCollectionStats: { created: 'u32', destroyed: 'u32', @@ -76,7 +90,13 @@ UpDataStructsTokenId: 'u32', PalletNonfungibleItemData: mkDummy('NftItemData'), PalletRefungibleItemData: mkDummy('RftItemData'), - UpDataStructsCollectionMode: mkDummy('CollectionMode'), + UpDataStructsCollectionMode: { + _enum: { + NFT: null, + Fungible: 'u32', + ReFungible: null, + }, + }, UpDataStructsCreateItemData: mkDummy('CreateItemData'), UpDataStructsCollectionLimits: { accountTokenOwnershipLimit: 'Option', @@ -101,7 +121,9 @@ UpDataStructsAccessMode: { _enum: ['Normal', 'AllowList'], }, - UpDataStructsSchemaVersion: mkDummy('SchemaVersion'), + UpDataStructsSchemaVersion: { + _enum: ['ImageURL', 'Unique'], + }, PalletUnqSchedulerScheduledV2: mkDummy('ScheduledV2'), PalletUnqSchedulerCallSpec: mkDummy('CallSpec'), --- a/tests/src/interfaces/unique/types.ts +++ b/tests/src/interfaces/unique/types.ts @@ -77,8 +77,11 @@ } /** @name UpDataStructsCollectionMode */ -export interface UpDataStructsCollectionMode extends Struct { - readonly dummyCollectionMode: u32; +export interface UpDataStructsCollectionMode extends Enum { + readonly isNft: boolean; + readonly isFungible: boolean; + readonly asFungible: u32; + readonly isReFungible: boolean; } /** @name UpDataStructsCollectionStats */ @@ -88,6 +91,22 @@ readonly alive: u32; } +/** @name UpDataStructsCreateCollectionData */ +export interface UpDataStructsCreateCollectionData extends Struct { + readonly mode: UpDataStructsCollectionMode; + readonly access: Option; + readonly name: Vec; + readonly description: Vec; + readonly tokenPrefix: Bytes; + readonly offchainSchema: Bytes; + readonly schemaVersion: Option; + readonly pendingSponsor: Option; + readonly limits: Option; + readonly variableOnChainSchema: Bytes; + readonly constOnChainSchema: Bytes; + readonly metaUpdatePermission: Option; +} + /** @name UpDataStructsCreateItemData */ export interface UpDataStructsCreateItemData extends Struct { readonly dummyCreateItemData: u32; @@ -101,8 +120,9 @@ } /** @name UpDataStructsSchemaVersion */ -export interface UpDataStructsSchemaVersion extends Struct { - readonly dummySchemaVersion: u32; +export interface UpDataStructsSchemaVersion extends Enum { + readonly isImageUrl: boolean; + readonly isUnique: boolean; } /** @name UpDataStructsSponsorshipState */ --- a/tests/src/substrate/substrate-api.ts +++ b/tests/src/substrate/substrate-api.ts @@ -95,6 +95,32 @@ return TransactionStatus.Fail; } +export function executeTransaction(api: ApiPromise, sender: IKeyringPair, transaction: SubmittableExtrinsic<'promise'>): Promise { + return new Promise(async (res, rej) => { + try { + await transaction.signAndSend(sender, ({events, status}) => { + if (!status.isInBlock && !status.isFinalized) return; + for (const {event} of events) { + if (api.events.system.ExtrinsicSuccess.is(event)) { + res(events); + } else if (api.events.system.ExtrinsicFailed.is(event)) { + const {data: [error]} = event; + if (error.isModule) { + const decoded = api.registry.findMetaError(error.asModule); + const {method, section} = decoded; + rej(new Error(`${section}.${method}`)); + } else { + rej(new Error(error.toString())); + } + } + } + }); + } catch (e) { + rej(e); + } + }); +} + export function submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic): Promise { /* eslint no-async-promise-executor: "off" */ --- a/tests/src/util/helpers.ts +++ b/tests/src/util/helpers.ts @@ -49,7 +49,7 @@ }; } else if ('Substrate' in input) { return input; - }else if ('substrate' in input) { + } else if ('substrate' in input) { return { Substrate: (input as any).substrate, }; @@ -116,15 +116,15 @@ export interface IChainLimits { collectionNumbersLimit: number; - accountTokenOwnershipLimit: number; - collectionsAdminsLimit: number; - customDataLimit: number; - nftSponsorTransferTimeout: number; - fungibleSponsorTransferTimeout: number; - refungibleSponsorTransferTimeout: number; - offchainSchemaLimit: number; - variableOnChainSchemaLimit: number; - constOnChainSchemaLimit: number; + accountTokenOwnershipLimit: number; + collectionsAdminsLimit: number; + customDataLimit: number; + nftSponsorTransferTimeout: number; + fungibleSponsorTransferTimeout: number; + refungibleSponsorTransferTimeout: number; + offchainSchemaLimit: number; + variableOnChainSchemaLimit: number; + constOnChainSchemaLimit: number; } export interface IReFungibleTokenDataType { @@ -283,7 +283,7 @@ modeprm = {refungible: null}; } - const tx = api.tx.unique.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm as any); + const tx = api.tx.unique.createCollectionEx({name: strToUTF16(name), description: strToUTF16(description), tokenPrefix: strToUTF16(tokenPrefix), mode: modeprm as any}); const events = await submitTransactionAsync(alicePrivateKey, tx); const result = getCreateCollectionResult(events); @@ -329,7 +329,7 @@ // Run the CreateCollection transaction const alicePrivateKey = privateKey('//Alice'); - const tx = api.tx.unique.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm as any); + const tx = api.tx.unique.createCollectionEx({name: strToUTF16(name), description: strToUTF16(description), tokenPrefix: strToUTF16(tokenPrefix), mode: modeprm as any}); const events = await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected; const result = getCreateCollectionResult(events); @@ -557,7 +557,7 @@ await usingApi(async (api) => { - const tx = api.tx.unique.setTransfersEnabledFlag (collectionId, enabled); + const tx = api.tx.unique.setTransfersEnabledFlag(collectionId, enabled); const events = await submitTransactionAsync(sender, tx); const result = getGenericResult(events); @@ -569,7 +569,7 @@ await usingApi(async (api) => { - const tx = api.tx.unique.setTransfersEnabledFlag (collectionId, enabled); + const tx = api.tx.unique.setTransfersEnabledFlag(collectionId, enabled); const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected; const result = getGenericResult(events); @@ -811,8 +811,7 @@ } export async function -getFreeBalance(account: IKeyringPair) : Promise -{ +getFreeBalance(account: IKeyringPair): Promise { let balance = 0n; await usingApi(async (api) => { balance = BigInt((await api.query.system.account(account.address)).data.free.toString()); -- gitstuff