git.delta.rocks / unique-network / refs/commits / 509c8280fa0c

difftreelog

Merge pull request #426 from UniqueNetwork/feature/token_owners

Yaroslav Bolyukin2022-07-22parents: #c2a34ed #10fad85.patch.diff
in: master

31 files changed

modifiedCargo.lockdiffbeforeafterboth
59535953
5954[[package]]5954[[package]]
5955name = "pallet-fungible"5955name = "pallet-fungible"
5956version = "0.1.0"5956version = "0.1.1"
5957dependencies = [5957dependencies = [
5958 "ethereum",5958 "ethereum",
5959 "evm-coder",5959 "evm-coder",
61986198
6199[[package]]6199[[package]]
6200name = "pallet-nonfungible"6200name = "pallet-nonfungible"
6201version = "0.1.0"6201version = "0.1.1"
6202dependencies = [6202dependencies = [
6203 "ethereum",6203 "ethereum",
6204 "evm-coder",6204 "evm-coder",
1237712377
12378[[package]]12378[[package]]
12379name = "uc-rpc"12379name = "uc-rpc"
12380version = "0.1.0"12380version = "0.1.1"
12381dependencies = [12381dependencies = [
12382 "anyhow",12382 "anyhow",
12383 "jsonrpsee",12383 "jsonrpsee",
1268212682
12683[[package]]12683[[package]]
12684name = "unique-runtime-common"12684name = "unique-runtime-common"
12685version = "0.9.24"12685version = "0.9.25"
12686dependencies = [12686dependencies = [
12687 "evm-coder",12687 "evm-coder",
12688 "fp-rpc",12688 "fp-rpc",
1275412754
12755[[package]]12755[[package]]
12756name = "up-rpc"12756name = "up-rpc"
12757version = "0.1.0"12757version = "0.1.1"
12758dependencies = [12758dependencies = [
12759 "pallet-common",12759 "pallet-common",
12760 "pallet-evm",12760 "pallet-evm",
addedclient/rpc/CHANGELOG.mddiffbeforeafterboth

no changes

modifiedclient/rpc/Cargo.tomldiffbeforeafterboth
1[package]1[package]
2name = "uc-rpc"2name = "uc-rpc"
3version = "0.1.0"3version = "0.1.1"
4license = "GPLv3"4license = "GPLv3"
5edition = "2021"5edition = "2021"
66
modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
71 at: Option<BlockHash>,71 at: Option<BlockHash>,
72 ) -> Result<Option<CrossAccountId>>;72 ) -> Result<Option<CrossAccountId>>;
73
74 /// Returns 10 tokens owners in no particular order.
75 #[method(name = "unique_tokenOwners")]
76 fn token_owners(
77 &self,
78 collection: CollectionId,
79 token: TokenId,
80 at: Option<BlockHash>,
81 ) -> Result<Vec<CrossAccountId>>;
82
73 #[method(name = "unique_topmostTokenOwner")]83 #[method(name = "unique_topmostTokenOwner")]
74 fn topmost_token_owner(84 fn topmost_token_owner(
473 pass_method!(next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Option<u64>, unique_api);483 pass_method!(next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Option<u64>, unique_api);
474 pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>, unique_api);484 pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>, unique_api);
475 pass_method!(total_pieces(collection_id: CollectionId, token_id: TokenId) -> Option<u128>, unique_api);485 pass_method!(total_pieces(collection_id: CollectionId, token_id: TokenId) -> Option<u128>, unique_api);
486 pass_method!(token_owners(collection: CollectionId, token: TokenId) -> Vec<CrossAccountId>, unique_api);
476}487}
477488
478#[allow(deprecated)]489#[allow(deprecated)]
addedpallets/common/CHANGELOG.mddiffbeforeafterboth

no changes

modifiedpallets/common/src/lib.rsdiffbeforeafterboth
1748 /// * `token` - The token for which you need to find out the owner.1748 /// * `token` - The token for which you need to find out the owner.
1749 fn token_owner(&self, token: TokenId) -> Option<T::CrossAccountId>;1749 fn token_owner(&self, token: TokenId) -> Option<T::CrossAccountId>;
1750
1751 /// Returns 10 tokens owners in no particular order.
1752 ///
1753 /// * `token` - The token for which you need to find out the owners.
1754 fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId>;
17501755
1751 /// Get the value of the token property by key.1756 /// Get the value of the token property by key.
1752 ///1757 ///
addedpallets/fungible/CHANGELOG.mddiffbeforeafterboth

no changes

modifiedpallets/fungible/Cargo.tomldiffbeforeafterboth
1[package]1[package]
2name = "pallet-fungible"2name = "pallet-fungible"
3version = "0.1.0"3version = "0.1.1"
4license = "GPLv3"4license = "GPLv3"
5edition = "2021"5edition = "2021"
66
modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
362 None362 None
363 }363 }
364
365 /// Returns 10 tokens owners in no particular order.
366 fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId> {
367 <Pallet<T>>::token_owners(self.id, token).unwrap_or_default()
368 }
364369
365 fn token_property(&self, _token_id: TokenId, _key: &PropertyKey) -> Option<PropertyValue> {370 fn token_property(&self, _token_id: TokenId, _key: &PropertyKey) -> Option<PropertyValue> {
366 None371 None
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
95use pallet_evm_coder_substrate::WithRecorder;95use pallet_evm_coder_substrate::WithRecorder;
96use sp_core::H160;96use sp_core::H160;
97use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};97use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};
98use sp_std::{collections::btree_map::BTreeMap};98use sp_std::{collections::btree_map::BTreeMap, vec::Vec};
9999
100pub use pallet::*;100pub use pallet::*;
101101
614 )614 )
615 }615 }
616
617 /// Returns 10 tokens owners in no particular order
618 ///
619 /// There is no direct way to get token holders in ascending order,
620 /// since `iter_prefix` returns values in no particular order.
621 /// Therefore, getting the 10 largest holders with a large value of holders
622 /// can lead to impact memory allocation + sorting with `n * log (n)`.
623 pub fn token_owners(
624 collection: CollectionId,
625 _token: TokenId,
626 ) -> Option<Vec<T::CrossAccountId>> {
627 let res: Vec<T::CrossAccountId> = <Balance<T>>::iter_prefix((collection,))
628 .map(|(owner, _amount)| owner)
629 .take(10)
630 .collect();
631
632 if res.is_empty() {
633 None
634 } else {
635 Some(res)
636 }
637 }
616}638}
617639
addedpallets/nonfungible/CHANGELOG.mddiffbeforeafterboth

no changes

modifiedpallets/nonfungible/Cargo.tomldiffbeforeafterboth
1[package]1[package]
2name = "pallet-nonfungible"2name = "pallet-nonfungible"
3version = "0.1.0"3version = "0.1.1"
4license = "GPLv3"4license = "GPLv3"
5edition = "2021"5edition = "2021"
66
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
26 weights::WeightInfo as _,26 weights::WeightInfo as _,
27};27};
28use sp_runtime::DispatchError;28use sp_runtime::DispatchError;
29use sp_std::vec::Vec;29use sp_std::{vec::Vec, vec};
3030
31use crate::{31use crate::{
32 AccountBalance, Allowance, Config, CreateItemData, Error, NonfungibleHandle, Owned, Pallet,32 AccountBalance, Allowance, Config, CreateItemData, Error, NonfungibleHandle, Owned, Pallet,
422 <TokenData<T>>::get((self.id, token)).map(|t| t.owner)422 <TokenData<T>>::get((self.id, token)).map(|t| t.owner)
423 }423 }
424
425 /// Returns token owners.
426 fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId> {
427 self.token_owner(token).map_or_else(|| vec![], |t| vec![t])
428 }
424429
425 fn token_property(&self, token_id: TokenId, key: &PropertyKey) -> Option<PropertyValue> {430 fn token_property(&self, token_id: TokenId, key: &PropertyKey) -> Option<PropertyValue> {
426 <Pallet<T>>::token_properties((self.id, token_id))431 <Pallet<T>>::token_properties((self.id, token_id))
modifiedpallets/refungible/CHANGELOG.mddiffbeforeafterboth
1## v0.1.2 - 2022-071# Change Log
22
3### Refungible Pallet3All notable changes to this project will be documented in this file.
44
5## [v0.1.2] - 2022-07-14
6
7### Other changes
8
5feat(refungible-pallet): add ERC-20 EVM API for RFT token pieces ([#413](https://github.com/UniqueNetwork/unique-chain/pull/413))9feat(refungible-pallet): add ERC-20 EVM API for RFT token pieces ([#413](https://github.com/UniqueNetwork/unique-chain/pull/413))
6test(refungible-pallet): add tests for ERC-20 EVM API for RFT token pieces ([#413](https://github.com/UniqueNetwork/unique-chain/pull/413))10test(refungible-pallet): add tests for ERC-20 EVM API for RFT token pieces ([#413](https://github.com/UniqueNetwork/unique-chain/pull/413))
11
12## [v0.1.1] - 2022-07-14
13
14### Other changes
15
16- feat: RPC method `token_owners` returning 10 owners in no particular order.
17
18This was an internal request to improve the web interface and support fractionalization event.
19
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
438 <Pallet<T>>::token_owner(self.id, token)438 <Pallet<T>>::token_owner(self.id, token)
439 }439 }
440
441 /// Returns 10 token in no particular order.
442 fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId> {
443 <Pallet<T>>::token_owners(self.id, token).unwrap_or_default()
444 }
440445
441 fn token_property(&self, _token_id: TokenId, _key: &PropertyKey) -> Option<PropertyValue> {446 fn token_property(&self, _token_id: TokenId, _key: &PropertyKey) -> Option<PropertyValue> {
442 None447 None
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
1236 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)1236 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)
1237 }1237 }
1238
1239 /// Returns 10 token in no particular order.
1240 ///
1241 /// There is no direct way to get token holders in ascending order,
1242 /// since `iter_prefix` returns values in no particular order.
1243 /// Therefore, getting the 10 largest holders with a large value of holders
1244 /// can lead to impact memory allocation + sorting with `n * log (n)`.
1245 pub fn token_owners(
1246 collection_id: CollectionId,
1247 token: TokenId,
1248 ) -> Option<Vec<T::CrossAccountId>> {
1249 let res: Vec<T::CrossAccountId> = <Balance<T>>::iter_prefix((collection_id, token))
1250 .map(|(owner, _amount)| owner)
1251 .take(10)
1252 .collect();
1253
1254 if res.is_empty() {
1255 None
1256 } else {
1257 Some(res)
1258 }
1259 }
1238}1260}
12391261
addedprimitives/rpc/CHANGELOG.mddiffbeforeafterboth

no changes

modifiedprimitives/rpc/Cargo.tomldiffbeforeafterboth
1[package]1[package]
2name = "up-rpc"2name = "up-rpc"
3version = "0.1.0"3version = "0.1.1"
4license = "GPLv3"4license = "GPLv3"
5edition = "2021"5edition = "2021"
66
modifiedprimitives/rpc/src/lib.rsdiffbeforeafterboth
81 fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>>;81 fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>>;
82 fn effective_collection_limits(collection_id: CollectionId) -> Result<Option<CollectionLimits>>;82 fn effective_collection_limits(collection_id: CollectionId) -> Result<Option<CollectionLimits>>;
83 fn total_pieces(collection_id: CollectionId, token_id: TokenId) -> Result<Option<u128>>;83 fn total_pieces(collection_id: CollectionId, token_id: TokenId) -> Result<Option<u128>>;
84 fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec<CrossAccountId>>;
84 }85 }
85}86}
8687
addedruntime/common/CHANGELOG.mddiffbeforeafterboth

no changes

modifiedruntime/common/src/runtime_apis.rsdiffbeforeafterboth
41 dispatch_unique_runtime!(collection.token_owner(token))41 dispatch_unique_runtime!(collection.token_owner(token))
42 }42 }
43
44 fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec::<CrossAccountId>, DispatchError> {
45 dispatch_unique_runtime!(collection.token_owners(token))
46 }
47
43 fn topmost_token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {48 fn topmost_token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {
44 let budget = up_data_structs::budget::Value::new(10);49 let budget = up_data_structs::budget::Value::new(10);
addedtests/CHANGELOG.mddiffbeforeafterboth

no changes

modifiedtests/package.jsondiffbeforeafterboth
80 "testLimits": "mocha --timeout 9999999 -r ts-node/register ./**/limits.test.ts",80 "testLimits": "mocha --timeout 9999999 -r ts-node/register ./**/limits.test.ts",
81 "testEthCreateCollection": "mocha --timeout 9999999 -r ts-node/register ./**/eth/createCollection.test.ts",81 "testEthCreateCollection": "mocha --timeout 9999999 -r ts-node/register ./**/eth/createCollection.test.ts",
82 "testRFT": "mocha --timeout 9999999 -r ts-node/register ./**/refungible.test.ts",82 "testRFT": "mocha --timeout 9999999 -r ts-node/register ./**/refungible.test.ts",
83 "testFT": "mocha --timeout 9999999 -r ts-node/register ./**/fungible.test.ts",
84 "testRPC": "mocha --timeout 9999999 -r ts-node/register ./**/rpc.test.ts",
83 "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",85 "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",
84 "polkadot-types-from-defs": "ts-node ./node_modules/.bin/polkadot-types-from-defs --endpoint src/interfaces/metadata.json --input src/interfaces/ --package .",86 "polkadot-types-from-defs": "ts-node ./node_modules/.bin/polkadot-types-from-defs --endpoint src/interfaces/metadata.json --input src/interfaces/ --package .",
85 "polkadot-types-from-chain": "ts-node ./node_modules/.bin/polkadot-types-from-chain --endpoint src/interfaces/metadata.json --output src/interfaces/ --package .",87 "polkadot-types-from-chain": "ts-node ./node_modules/.bin/polkadot-types-from-chain --endpoint src/interfaces/metadata.json --output src/interfaces/ --package .",
addedtests/src/fungible.test.tsdiffbeforeafterboth

no changes

modifiedtests/src/interfaces/augment-api-consts.tsdiffbeforeafterboth
29 [key: string]: Codec;29 [key: string]: Codec;
30 };30 };
31 common: {31 common: {
32 /**
33 * Maximum admins per collection.
34 **/
32 collectionAdminsLimit: u32 & AugmentedConst<ApiType>;35 collectionAdminsLimit: u32 & AugmentedConst<ApiType>;
36 /**
37 * Set price to create a collection.
38 **/
33 collectionCreationPrice: u128 & AugmentedConst<ApiType>;39 collectionCreationPrice: u128 & AugmentedConst<ApiType>;
34 /**40 /**
35 * Generic const41 * Generic const
modifiedtests/src/interfaces/augment-api-events.tsdiffbeforeafterboth
58 [key: string]: AugmentedEvent<ApiType>;58 [key: string]: AugmentedEvent<ApiType>;
59 };59 };
60 common: {60 common: {
61 /**61 /**
62 * * collection_id62 * Amount pieces of token owned by `sender` was approved for `spender`.
63 * 63 **/
64 * * item_id
65 *
66 * * sender
67 *
68 * * spender
69 *
70 * * amount
71 **/
72 Approved: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;64 Approved: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
73 /**65 /**
74 * New collection was created66 * New collection was created
75 * 67 **/
76 * # Arguments
77 *
78 * * collection_id: Globally unique identifier of newly created collection.
79 *
80 * * mode: [CollectionMode] converted into u8.
81 *
82 * * account_id: Collection owner.
83 **/
84 CollectionCreated: AugmentedEvent<ApiType, [u32, u8, AccountId32]>;68 CollectionCreated: AugmentedEvent<ApiType, [u32, u8, AccountId32]>;
85 /**69 /**
86 * New collection was destroyed70 * New collection was destroyed
87 * 71 **/
88 * # Arguments
89 *
90 * * collection_id: Globally unique identifier of collection.
91 **/
92 CollectionDestroyed: AugmentedEvent<ApiType, [u32]>;72 CollectionDestroyed: AugmentedEvent<ApiType, [u32]>;
73 /**
74 * The property has been deleted.
75 **/
93 CollectionPropertyDeleted: AugmentedEvent<ApiType, [u32, Bytes]>;76 CollectionPropertyDeleted: AugmentedEvent<ApiType, [u32, Bytes]>;
77 /**
78 * The colletion property has been set.
79 **/
94 CollectionPropertySet: AugmentedEvent<ApiType, [u32, Bytes]>;80 CollectionPropertySet: AugmentedEvent<ApiType, [u32, Bytes]>;
95 /**81 /**
96 * New item was created.82 * New item was created.
97 * 83 **/
98 * # Arguments
99 *
100 * * collection_id: Id of the collection where item was created.
101 *
102 * * item_id: Id of an item. Unique within the collection.
103 *
104 * * recipient: Owner of newly created item
105 *
106 * * amount: Always 1 for NFT
107 **/
108 ItemCreated: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;84 ItemCreated: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
109 /**85 /**
110 * Collection item was burned.86 * Collection item was burned.
111 * 87 **/
112 * # Arguments
113 *
114 * * collection_id.
115 *
116 * * item_id: Identifier of burned NFT.
117 *
118 * * owner: which user has destroyed its tokens
119 *
120 * * amount: Always 1 for NFT
121 **/
122 ItemDestroyed: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;88 ItemDestroyed: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
89 /**
90 * The colletion property permission has been set.
91 **/
123 PropertyPermissionSet: AugmentedEvent<ApiType, [u32, Bytes]>;92 PropertyPermissionSet: AugmentedEvent<ApiType, [u32, Bytes]>;
93 /**
94 * The token property has been deleted.
95 **/
124 TokenPropertyDeleted: AugmentedEvent<ApiType, [u32, u32, Bytes]>;96 TokenPropertyDeleted: AugmentedEvent<ApiType, [u32, u32, Bytes]>;
97 /**
98 * The token property has been set.
99 **/
125 TokenPropertySet: AugmentedEvent<ApiType, [u32, u32, Bytes]>;100 TokenPropertySet: AugmentedEvent<ApiType, [u32, u32, Bytes]>;
126 /**101 /**
127 * Item was transferred102 * Item was transferred
128 * 103 **/
129 * * collection_id: Id of collection to which item is belong
130 *
131 * * item_id: Id of an item
132 *
133 * * sender: Original owner of item
134 *
135 * * recipient: New owner of item
136 *
137 * * amount: Always 1 for NFT
138 **/
139 Transfer: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;104 Transfer: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
140 /**105 /**
141 * Generic event106 * Generic event
modifiedtests/src/interfaces/augment-api-query.tsdiffbeforeafterboth
69 [key: string]: QueryableStorageEntry<ApiType>;69 [key: string]: QueryableStorageEntry<ApiType>;
70 };70 };
71 common: {71 common: {
72 /**
73 * Storage of collection admins count.
74 **/
72 adminAmount: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;75 adminAmount: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
73 /**76 /**
74 * Allowlisted collection users77 * Allowlisted collection users
75 **/78 **/
76 allowlist: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<bool>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;79 allowlist: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<bool>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
77 /**80 /**
78 * Collection info81 * Storage of collection info.
79 **/82 **/
80 collectionById: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<Option<UpDataStructsCollection>>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;83 collectionById: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<Option<UpDataStructsCollection>>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
81 /**84 /**
82 * Collection properties85 * Storage of collection properties.
83 **/86 **/
84 collectionProperties: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<UpDataStructsProperties>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;87 collectionProperties: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<UpDataStructsProperties>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
88 /**
89 * Storage of collection properties permissions.
90 **/
85 collectionPropertyPermissions: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<BTreeMap<Bytes, UpDataStructsPropertyPermission>>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;91 collectionPropertyPermissions: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<BTreeMap<Bytes, UpDataStructsPropertyPermission>>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
92 /**
93 * Storage of the count of created collections.
94 **/
86 createdCollectionCount: AugmentedQuery<ApiType, () => Observable<u32>, []> & QueryableStorageEntry<ApiType, []>;95 createdCollectionCount: AugmentedQuery<ApiType, () => Observable<u32>, []> & QueryableStorageEntry<ApiType, []>;
96 /**
97 * Storage of the count of deleted collections.
98 **/
87 destroyedCollectionCount: AugmentedQuery<ApiType, () => Observable<u32>, []> & QueryableStorageEntry<ApiType, []>;99 destroyedCollectionCount: AugmentedQuery<ApiType, () => Observable<u32>, []> & QueryableStorageEntry<ApiType, []>;
88 /**100 /**
89 * Not used by code, exists only to provide some types to metadata101 * Not used by code, exists only to provide some types to metadata.
90 **/102 **/
91 dummyStorageValue: AugmentedQuery<ApiType, () => Observable<Option<ITuple<[UpDataStructsCollectionStats, u32, u32, UpDataStructsTokenChild, PhantomTypeUpDataStructs]>>>, []> & QueryableStorageEntry<ApiType, []>;103 dummyStorageValue: AugmentedQuery<ApiType, () => Observable<Option<ITuple<[UpDataStructsCollectionStats, u32, u32, UpDataStructsTokenChild, PhantomTypeUpDataStructs]>>>, []> & QueryableStorageEntry<ApiType, []>;
92 /**104 /**
93 * List of collection admins105 * List of collection admins
231 [key: string]: QueryableStorageEntry<ApiType>;243 [key: string]: QueryableStorageEntry<ApiType>;
232 };244 };
233 nonfungible: {245 nonfungible: {
246 /**
247 * Amount of tokens owned by account.
248 **/
234 accountBalance: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<u32>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;249 accountBalance: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<u32>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
250 /**
251 * Allowance set by an owner for a spender for a token.
252 **/
235 allowance: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<Option<PalletEvmAccountBasicCrossAccountIdRepr>>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;253 allowance: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<Option<PalletEvmAccountBasicCrossAccountIdRepr>>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
236 /**254 /**
237 * Used to enumerate tokens owned by account255 * Used to enumerate tokens owned by account.
238 **/256 **/
239 owned: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, arg3: u32 | AnyNumber | Uint8Array) => Observable<bool>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, u32]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr, u32]>;257 owned: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, arg3: u32 | AnyNumber | Uint8Array) => Observable<bool>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, u32]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr, u32]>;
258 /**
259 * Custom data that is serialized to bytes and attached to a token property.
260 * Currently used to store RMRK data.
261 **/
240 tokenAuxProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: UpDataStructsPropertyScope | 'None' | 'Rmrk' | number | Uint8Array, arg4: Bytes | string | Uint8Array) => Observable<Option<Bytes>>, [u32, u32, UpDataStructsPropertyScope, Bytes]> & QueryableStorageEntry<ApiType, [u32, u32, UpDataStructsPropertyScope, Bytes]>;262 tokenAuxProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: UpDataStructsPropertyScope | 'None' | 'Rmrk' | number | Uint8Array, arg4: Bytes | string | Uint8Array) => Observable<Option<Bytes>>, [u32, u32, UpDataStructsPropertyScope, Bytes]> & QueryableStorageEntry<ApiType, [u32, u32, UpDataStructsPropertyScope, Bytes]>;
241 /**263 /**
242 * Used to enumerate token's children264 * Used to enumerate token's children.
243 **/265 **/
244 tokenChildren: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: ITuple<[u32, u32]> | [u32 | AnyNumber | Uint8Array, u32 | AnyNumber | Uint8Array]) => Observable<bool>, [u32, u32, ITuple<[u32, u32]>]> & QueryableStorageEntry<ApiType, [u32, u32, ITuple<[u32, u32]>]>;266 tokenChildren: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array, arg3: ITuple<[u32, u32]> | [u32 | AnyNumber | Uint8Array, u32 | AnyNumber | Uint8Array]) => Observable<bool>, [u32, u32, ITuple<[u32, u32]>]> & QueryableStorageEntry<ApiType, [u32, u32, ITuple<[u32, u32]>]>;
267 /**
268 * Custom data serialized to bytes for token.
269 **/
245 tokenData: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<Option<PalletNonfungibleItemData>>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;270 tokenData: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<Option<PalletNonfungibleItemData>>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
271 /**
272 * Key-Value map stored for token.
273 **/
246 tokenProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<UpDataStructsProperties>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;274 tokenProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<UpDataStructsProperties>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
275 /**
276 * Amount of burnt tokens for collection.
277 **/
247 tokensBurnt: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;278 tokensBurnt: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
279 /**
280 * Amount of tokens minted for collection.
281 **/
248 tokensMinted: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;282 tokensMinted: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
249 /**283 /**
250 * Generic query284 * Generic query
430 **/464 **/
431 tokenData: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<PalletRefungibleItemData>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;465 tokenData: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<PalletRefungibleItemData>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
432 tokenProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<UpDataStructsProperties>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;466 tokenProperties: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<UpDataStructsProperties>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
467 /**
468 * Amount of burnt tokens for collection
469 **/
433 tokensBurnt: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;470 tokensBurnt: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
434 /**471 /**
435 * Amount of tokens minted for collection472 * Amount of tokens minted for collection
modifiedtests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth
708 * Get token owner708 * Get token owner
709 **/709 **/
710 tokenOwner: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<PalletEvmAccountBasicCrossAccountIdRepr>>>;710 tokenOwner: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<PalletEvmAccountBasicCrossAccountIdRepr>>>;
711 /**
712 * Returns 10 tokens owners in no particular order
713 **/
714 tokenOwners: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<PalletEvmAccountBasicCrossAccountIdRepr>>>;
711 /**715 /**
712 * Get token properties716 * Get token properties
713 **/717 **/
modifiedtests/src/interfaces/unique/definitions.tsdiffbeforeafterboth
49 balance: fun('Get amount of specific account token', [collectionParam, crossAccountParam(), tokenParam], 'u128'),49 balance: fun('Get amount of specific account token', [collectionParam, crossAccountParam(), tokenParam], 'u128'),
50 allowance: fun('Get allowed amount', [collectionParam, crossAccountParam('sender'), crossAccountParam('spender'), tokenParam], 'u128'),50 allowance: fun('Get allowed amount', [collectionParam, crossAccountParam('sender'), crossAccountParam('spender'), tokenParam], 'u128'),
51 tokenOwner: fun('Get token owner', [collectionParam, tokenParam], `Option<${CROSS_ACCOUNT_ID_TYPE}>`),51 tokenOwner: fun('Get token owner', [collectionParam, tokenParam], `Option<${CROSS_ACCOUNT_ID_TYPE}>`),
52 tokenOwners: fun('Returns 10 tokens owners in no particular order', [collectionParam, tokenParam], `Vec<${CROSS_ACCOUNT_ID_TYPE}>`),
52 topmostTokenOwner: fun('Get token owner, in case of nested token - find parent recursive', [collectionParam, tokenParam], `Option<${CROSS_ACCOUNT_ID_TYPE}>`),53 topmostTokenOwner: fun('Get token owner, in case of nested token - find parent recursive', [collectionParam, tokenParam], `Option<${CROSS_ACCOUNT_ID_TYPE}>`),
53 tokenChildren: fun('Get tokens nested directly into the token', [collectionParam, tokenParam], 'Vec<UpDataStructsTokenChild>'),54 tokenChildren: fun('Get tokens nested directly into the token', [collectionParam, tokenParam], 'Vec<UpDataStructsTokenChild>'),
54 constMetadata: fun('Get token constant metadata', [collectionParam, tokenParam], 'Vec<u8>'),55 constMetadata: fun('Get token constant metadata', [collectionParam, tokenParam], 'Vec<u8>'),
modifiedtests/src/refungible.test.tsdiffbeforeafterboth
32 repartitionRFT,32 repartitionRFT,
33 createCollectionWithPropsExpectSuccess,33 createCollectionWithPropsExpectSuccess,
34 getDetailedCollectionInfo,34 getDetailedCollectionInfo,
35 normalizeAccountId,
36 CrossAccountId,
35 getCreateItemsResult,37 getCreateItemsResult,
36 getDestroyItemsResult,38 getDestroyItemsResult,
37} from './util/helpers';39} from './util/helpers';
72 });74 });
73 });75 });
7476
77 it('RPC method tokenOnewrs for refungible collection and token', async () => {
78 await usingApi(async (api, privateKeyWrapper) => {
79 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
80 const facelessCrowd = Array.from(Array(7).keys()).map(i => normalizeAccountId(privateKeyWrapper(i.toString())));
81
82 const createCollectionResult = await createCollection(api, alice, {mode: {type: 'ReFungible'}});
83 const collectionId = createCollectionResult.collectionId;
84
85 const result = await createRefungibleToken(api, alice, collectionId, 10_000n);
86 const aliceTokenId = result.itemId;
87
88
89 await transfer(api, collectionId, aliceTokenId, alice, bob, 1000n);
90 await transfer(api, collectionId, aliceTokenId, alice, ethAcc, 900n);
91
92 for (let i = 0; i < 7; i++) {
93 await transfer(api, collectionId, aliceTokenId, alice, facelessCrowd[i], 50*(i+1));
94 }
95
96 const owners = await api.rpc.unique.tokenOwners(collectionId, aliceTokenId);
97 const ids = (owners.toJSON() as CrossAccountId[]).map(s => normalizeAccountId(s));
98
99 const aliceID = normalizeAccountId(alice);
100 const bobId = normalizeAccountId(bob);
101
102 // What to expect
103 // tslint:disable-next-line:no-unused-expression
104 expect(ids).to.deep.include.members([aliceID, ethAcc, bobId, ...facelessCrowd]);
105 expect(owners.length).to.be.equal(10);
106
107 const eleven = privateKeyWrapper('11');
108 expect(await transfer(api, collectionId, aliceTokenId, alice, eleven, 10n)).to.be.true;
109 expect((await api.rpc.unique.tokenOwners(collectionId, aliceTokenId)).length).to.be.equal(10);
110 });
111 });
112
75 it('Transfer token pieces', async () => {113 it('Transfer token pieces', async () => {
76 await usingApi(async api => {114 await usingApi(async api => {
modifiedtests/src/rpc.test.tsdiffbeforeafterboth
1import {IKeyringPair} from '@polkadot/types/types';
1import {expect} from 'chai';2import {expect} from 'chai';
2import usingApi from './substrate/substrate-api';3import usingApi from './substrate/substrate-api';
3import {createCollectionExpectSuccess, getTokenOwner} from './util/helpers';4import {createCollection, createCollectionExpectSuccess, createFungibleItemExpectSuccess, CrossAccountId, getTokenOwner, normalizeAccountId, transfer, U128_MAX} from './util/helpers';
5
6let alice: IKeyringPair;
7let bob: IKeyringPair;
8
49
5describe('getTokenOwner', () => {10describe('integration test: RPC methods', () => {
11 before(async () => {
12 await usingApi(async (api, privateKeyWrapper) => {
13 alice = privateKeyWrapper('//Alice');
14 bob = privateKeyWrapper('//Bob');
15 });
16 });
17
18
6 it('returns None for fungible collection', async () => {19 it('returns None for fungible collection', async () => {
10 });23 });
11 });24 });
25
26 it('RPC method tokenOwners for fungible collection and token', async () => {
27 await usingApi(async (api, privateKeyWrapper) => {
28 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
29 const facelessCrowd = Array.from(Array(7).keys()).map(i => normalizeAccountId(privateKeyWrapper(i.toString())));
30
31 const createCollectionResult = await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}});
32 const collectionId = createCollectionResult.collectionId;
33 const aliceTokenId = await createFungibleItemExpectSuccess(alice, collectionId, {Value: U128_MAX}, alice.address);
34
35 await transfer(api, collectionId, aliceTokenId, alice, bob, 1000n);
36 await transfer(api, collectionId, aliceTokenId, alice, ethAcc, 900n);
37
38 for (let i = 0; i < 7; i++) {
39 await transfer(api, collectionId, aliceTokenId, alice, facelessCrowd[i], 1);
40 }
41
42 const owners = await api.rpc.unique.tokenOwners(collectionId, aliceTokenId);
43 const ids = (owners.toJSON() as CrossAccountId[]).map(s => normalizeAccountId(s));
44 const aliceID = normalizeAccountId(alice);
45 const bobId = normalizeAccountId(bob);
46
47 // What to expect
48 // tslint:disable-next-line:no-unused-expression
49 expect(ids).to.deep.include.members([aliceID, ethAcc, bobId, ...facelessCrowd]);
50 expect(owners.length == 10).to.be.true;
51
52 const eleven = privateKeyWrapper('11');
53 expect(await transfer(api, collectionId, aliceTokenId, alice, eleven, 10n)).to.be.true;
54 expect((await api.rpc.unique.tokenOwners(collectionId, aliceTokenId)).length).to.be.equal(10);
55 });
56 });
12});57});