123456789101112131415161718192021#![cfg_attr(not(feature = "std"), no_std)]2223use core::{24 convert::{TryFrom, TryInto},25 fmt,26};27use frame_support::storage::{bounded_btree_map::BoundedBTreeMap, bounded_btree_set::BoundedBTreeSet};2829#[cfg(feature = "serde")]30use serde::{Serialize, Deserialize};3132use sp_core::U256;33use sp_runtime::{ArithmeticError, sp_std::prelude::Vec};34use codec::{Decode, Encode, EncodeLike, MaxEncodedLen};35use bondrewd::Bitfields;36use frame_support::{BoundedVec, traits::ConstU32};37use derivative::Derivative;38use scale_info::TypeInfo;3940mod bondrewd_codec;41mod bounded;42pub mod budget;43pub mod mapping;44mod migration;454647pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;484950pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;51pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;525354pub const MAX_TOKEN_OWNERSHIP: u32 = if cfg!(not(feature = "limit-testing")) {55 100_00056} else {57 1058};596061pub const COLLECTION_NUMBER_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {62 100_00063} else {64 1065};666768pub const CUSTOM_DATA_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {69 204870} else {71 1072};737475pub const COLLECTION_ADMINS_LIMIT: u32 = 5;767778pub const COLLECTION_TOKEN_LIMIT: u32 = u32::MAX;798081pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {82 1_000_00083} else {84 1085};868788pub const NFT_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;8990pub const FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;9192pub const REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;939495pub const SPONSOR_APPROVE_TIMEOUT: u32 = 5;969798pub const OFFCHAIN_SCHEMA_LIMIT: u32 = 8192;99pub const VARIABLE_ON_CHAIN_SCHEMA_LIMIT: u32 = 8192;100pub const CONST_ON_CHAIN_SCHEMA_LIMIT: u32 = 32768;101102103pub const COLLECTION_FIELD_LIMIT: u32 = CONST_ON_CHAIN_SCHEMA_LIMIT;104105106pub const MAX_COLLECTION_NAME_LENGTH: u32 = 64;107108109pub const MAX_COLLECTION_DESCRIPTION_LENGTH: u32 = 256;110111112pub const MAX_TOKEN_PREFIX_LENGTH: u32 = 16;113114115pub const MAX_PROPERTY_KEY_LENGTH: u32 = 256;116117118pub const MAX_PROPERTY_VALUE_LENGTH: u32 = 32768;119120121pub const MAX_PROPERTIES_PER_ITEM: u32 = 64;122123124pub const MAX_AUX_PROPERTY_VALUE_LENGTH: u32 = 2048;125126127pub const MAX_COLLECTION_PROPERTIES_SIZE: u32 = 40960;128129130pub const MAX_TOKEN_PROPERTIES_SIZE: u32 = 32768;131132133134pub const MAX_ITEMS_PER_BATCH: u32 = 200;135136137pub type CustomDataLimit = ConstU32<CUSTOM_DATA_LIMIT>;138139140#[derive(141 Encode,142 Decode,143 PartialEq,144 Eq,145 PartialOrd,146 Ord,147 Clone,148 Copy,149 Debug,150 Default,151 TypeInfo,152 MaxEncodedLen,153)]154#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]155pub struct CollectionId(pub u32);156impl EncodeLike<u32> for CollectionId {}157impl EncodeLike<CollectionId> for u32 {}158159impl From<u32> for CollectionId {160 fn from(value: u32) -> Self {161 Self(value)162 }163}164165166#[derive(167 Encode,168 Decode,169 PartialEq,170 Eq,171 PartialOrd,172 Ord,173 Clone,174 Copy,175 Debug,176 Default,177 TypeInfo,178 MaxEncodedLen,179)]180#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]181pub struct TokenId(pub u32);182impl EncodeLike<u32> for TokenId {}183impl EncodeLike<TokenId> for u32 {}184185impl TokenId {186 187 188 189 pub fn try_next(self) -> Result<TokenId, ArithmeticError> {190 self.0191 .checked_add(1)192 .ok_or(ArithmeticError::Overflow)193 .map(Self)194 }195}196197impl From<TokenId> for U256 {198 fn from(t: TokenId) -> Self {199 t.0.into()200 }201}202203impl TryFrom<U256> for TokenId {204 type Error = &'static str;205206 fn try_from(value: U256) -> Result<Self, Self::Error> {207 Ok(TokenId(value.try_into().map_err(|_| "too large token id")?))208 }209}210211212#[struct_versioning::versioned(version = 2, upper)]213#[derive(Encode, Decode, Clone, PartialEq, TypeInfo)]214#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]215pub struct TokenData<CrossAccountId> {216 217 pub properties: Vec<Property>,218219 220 pub owner: Option<CrossAccountId>,221222 223 #[version(2.., upper(0))]224 pub pieces: u128,225}226227228pub struct OverflowError;229impl From<OverflowError> for &'static str {230 fn from(_: OverflowError) -> Self {231 "overflow occured"232 }233}234235236pub type DecimalPoints = u8;237238239240241242243#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]244#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]245pub enum CollectionMode {246 247 NFT,248 249 Fungible(DecimalPoints),250 251 ReFungible,252}253254impl CollectionMode {255 256 pub fn id(&self) -> u8 {257 match self {258 CollectionMode::NFT => 1,259 CollectionMode::Fungible(_) => 2,260 CollectionMode::ReFungible => 3,261 }262 }263}264265266pub trait SponsoringResolve<AccountId, Call> {267 fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;268}269270271#[derive(Encode, Decode, Eq, Debug, Clone, Copy, PartialEq, TypeInfo, MaxEncodedLen)]272#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]273pub enum AccessMode {274 275 Normal,276 277 AllowList,278}279impl Default for AccessMode {280 fn default() -> Self {281 Self::Normal282 }283}284285286#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]287#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]288pub enum SchemaVersion {289 ImageURL,290 Unique,291}292impl Default for SchemaVersion {293 fn default() -> Self {294 Self::ImageURL295 }296}297298299#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, TypeInfo)]300#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]301pub struct Ownership<AccountId> {302 pub owner: AccountId,303 pub fraction: u128,304}305306307#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]308#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]309pub enum SponsorshipState<AccountId> {310 311 Disabled,312 313 314 Unconfirmed(AccountId),315 316 Confirmed(AccountId),317}318319impl<AccountId> SponsorshipState<AccountId> {320 321 pub fn sponsor(&self) -> Option<&AccountId> {322 match self {323 Self::Confirmed(sponsor) => Some(sponsor),324 _ => None,325 }326 }327328 329 pub fn pending_sponsor(&self) -> Option<&AccountId> {330 match self {331 Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),332 _ => None,333 }334 }335336 337 pub fn confirmed(&self) -> bool {338 matches!(self, Self::Confirmed(_))339 }340}341342impl<T> Default for SponsorshipState<T> {343 fn default() -> Self {344 Self::Disabled345 }346}347348pub type CollectionName = BoundedVec<u16, ConstU32<MAX_COLLECTION_NAME_LENGTH>>;349pub type CollectionDescription = BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>;350pub type CollectionTokenPrefix = BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>;351352#[derive(Bitfields, Clone, Copy, PartialEq, Eq, Debug, Default)]353#[bondrewd(enforce_bytes = 1)]354pub struct CollectionFlags {355 356 #[bondrewd(bits = "0..1")]357 pub foreign: bool,358 359 #[bondrewd(bits = "1..2")]360 pub erc721metadata: bool,361 362 #[bondrewd(bits = "7..8")]363 pub external: bool,364365 #[bondrewd(reserve, bits = "2..7")]366 pub reserved: u8,367}368bondrewd_codec!(CollectionFlags);369370371372373374375376#[struct_versioning::versioned(version = 2, upper)]377#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen)]378pub struct Collection<AccountId> {379 380 pub owner: AccountId,381382 383 pub mode: CollectionMode,384385 386 #[version(..2)]387 pub access: AccessMode,388389 390 pub name: CollectionName,391392 393 pub description: CollectionDescription,394395 396 pub token_prefix: CollectionTokenPrefix,397398 #[version(..2)]399 pub mint_mode: bool,400401 #[version(..2)]402 pub offchain_schema: BoundedVec<u8, ConstU32<OFFCHAIN_SCHEMA_LIMIT>>,403404 #[version(..2)]405 pub schema_version: SchemaVersion,406407 408 pub sponsorship: SponsorshipState<AccountId>,409410 411 pub limits: CollectionLimits,412413 414 #[version(2.., upper(Default::default()))]415 pub permissions: CollectionPermissions,416417 #[version(2.., upper(Default::default()))]418 pub flags: CollectionFlags,419420 #[version(..2)]421 pub variable_on_chain_schema: BoundedVec<u8, ConstU32<VARIABLE_ON_CHAIN_SCHEMA_LIMIT>>,422423 #[version(..2)]424 pub const_on_chain_schema: BoundedVec<u8, ConstU32<CONST_ON_CHAIN_SCHEMA_LIMIT>>,425426 #[version(..2)]427 pub meta_update_permission: MetaUpdatePermission,428}429430#[derive(Encode, Decode, Clone, PartialEq, TypeInfo)]431#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]432pub struct RpcCollectionFlags {433 434 pub foreign: bool,435 436 pub erc721metadata: bool,437}438439440#[struct_versioning::versioned(version = 2, upper)]441#[derive(Encode, Decode, Clone, PartialEq, TypeInfo)]442#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]443pub struct RpcCollection<AccountId> {444 445 pub owner: AccountId,446447 448 pub mode: CollectionMode,449450 451 pub name: Vec<u16>,452453 454 pub description: Vec<u16>,455456 457 pub token_prefix: Vec<u8>,458459 460 pub sponsorship: SponsorshipState<AccountId>,461462 463 pub limits: CollectionLimits,464465 466 pub permissions: CollectionPermissions,467468 469 pub token_property_permissions: Vec<PropertyKeyPermission>,470471 472 pub properties: Vec<Property>,473474 475 pub read_only: bool,476477 478 #[version(2.., upper(RpcCollectionFlags {foreign: false, erc721metadata: false}))]479 pub flags: RpcCollectionFlags,480}481482impl<AccountId> From<CollectionVersion1<AccountId>> for RpcCollection<AccountId> {483 fn from(value: CollectionVersion1<AccountId>) -> Self {484 let CollectionVersion1 {485 name,486 description,487 owner,488 mode,489 access,490 token_prefix,491 mint_mode,492 sponsorship,493 limits,494 ..495 } = value;496497 RpcCollection {498 name: name.into_inner(),499 description: description.into_inner(),500 owner,501 mode,502 token_prefix: token_prefix.into_inner(),503 sponsorship,504 limits,505 permissions: CollectionPermissions {506 access: Some(access),507 mint_mode: Some(mint_mode),508 nesting: None,509 },510 token_property_permissions: Vec::default(),511 properties: Vec::default(),512 read_only: true,513514 flags: RpcCollectionFlags {515 foreign: false,516 erc721metadata: false,517 },518 }519 }520}521522523524525#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, Derivative, MaxEncodedLen)]526#[derivative(Debug, Default(bound = ""))]527pub struct CreateCollectionData<AccountId> {528 529 #[derivative(Default(value = "CollectionMode::NFT"))]530 pub mode: CollectionMode,531532 533 pub access: Option<AccessMode>,534535 536 pub name: CollectionName,537538 539 pub description: CollectionDescription,540541 542 pub token_prefix: CollectionTokenPrefix,543544 545 pub pending_sponsor: Option<AccountId>,546547 548 pub limits: Option<CollectionLimits>,549550 551 pub permissions: Option<CollectionPermissions>,552553 554 pub token_property_permissions: CollectionPropertiesPermissionsVec,555556 557 pub properties: CollectionPropertiesVec,558}559560561562pub type CollectionPropertiesPermissionsVec =563 BoundedVec<PropertyKeyPermission, ConstU32<MAX_PROPERTIES_PER_ITEM>>;564565566pub type CollectionPropertiesVec = BoundedVec<Property, ConstU32<MAX_PROPERTIES_PER_ITEM>>;567568569570571572573574#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]575#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]576577578579pub struct CollectionLimits {580 581 582 583 pub account_token_ownership_limit: Option<u32>,584585 586 587 588 pub sponsored_data_size: Option<u32>,589590 591 592 593 594 595 596 597 598 599 pub sponsored_data_rate_limit: Option<SponsoringRateLimit>,600 601602 603 604 605 606 pub token_limit: Option<u32>,607608 609 610 611 612 613 614 615 pub sponsor_transfer_timeout: Option<u32>,616617 618 619 620 621 pub sponsor_approve_timeout: Option<u32>,622623 624 625 626 pub owner_can_transfer: Option<bool>,627628 629 630 631 pub owner_can_destroy: Option<bool>,632633 634 635 636 pub transfers_enabled: Option<bool>,637}638639impl CollectionLimits {640 pub fn with_default_limits(collection_type: CollectionMode) -> Self {641 CollectionLimits {642 account_token_ownership_limit: Some(ACCOUNT_TOKEN_OWNERSHIP_LIMIT),643 sponsored_data_size: Some(CUSTOM_DATA_LIMIT),644 sponsored_data_rate_limit: Some(SponsoringRateLimit::SponsoringDisabled),645 token_limit: Some(COLLECTION_TOKEN_LIMIT),646 sponsor_transfer_timeout: match collection_type {647 CollectionMode::NFT => Some(NFT_SPONSOR_TRANSFER_TIMEOUT),648 CollectionMode::ReFungible => Some(REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT),649 CollectionMode::Fungible(_) => Some(FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT),650 },651 sponsor_approve_timeout: Some(SPONSOR_APPROVE_TIMEOUT),652 owner_can_transfer: Some(false),653 owner_can_destroy: Some(true),654 transfers_enabled: Some(true),655 }656 }657658 659 pub fn account_token_ownership_limit(&self) -> u32 {660 self.account_token_ownership_limit661 .unwrap_or(ACCOUNT_TOKEN_OWNERSHIP_LIMIT)662 .min(MAX_TOKEN_OWNERSHIP)663 }664665 666 pub fn sponsored_data_size(&self) -> u32 {667 self.sponsored_data_size668 .unwrap_or(CUSTOM_DATA_LIMIT)669 .min(CUSTOM_DATA_LIMIT)670 }671672 673 pub fn token_limit(&self) -> u32 {674 self.token_limit675 .unwrap_or(COLLECTION_TOKEN_LIMIT)676 .min(COLLECTION_TOKEN_LIMIT)677 }678679 680 681 pub fn sponsor_transfer_timeout(&self, default: u32) -> u32 {682 self.sponsor_transfer_timeout683 .unwrap_or(default)684 .min(MAX_SPONSOR_TIMEOUT)685 }686687 688 pub fn sponsor_approve_timeout(&self) -> u32 {689 self.sponsor_approve_timeout690 .unwrap_or(SPONSOR_APPROVE_TIMEOUT)691 .min(MAX_SPONSOR_TIMEOUT)692 }693694 695 pub fn owner_can_transfer(&self) -> bool {696 self.owner_can_transfer.unwrap_or(false)697 }698699 700 pub fn owner_can_transfer_instaled(&self) -> bool {701 self.owner_can_transfer.is_some()702 }703704 705 pub fn owner_can_destroy(&self) -> bool {706 self.owner_can_destroy.unwrap_or(true)707 }708709 710 pub fn transfers_enabled(&self) -> bool {711 self.transfers_enabled.unwrap_or(true)712 }713714 715 pub fn sponsored_data_rate_limit(&self) -> Option<u32> {716 match self717 .sponsored_data_rate_limit718 .unwrap_or(SponsoringRateLimit::SponsoringDisabled)719 {720 SponsoringRateLimit::SponsoringDisabled => None,721 SponsoringRateLimit::Blocks(v) => Some(v.min(MAX_SPONSOR_TIMEOUT)),722 }723 }724}725726727728729730731#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]732#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]733734735pub struct CollectionPermissions {736 737 738 739 pub access: Option<AccessMode>,740741 742 743 744 pub mint_mode: Option<bool>,745746 747 748 749 750 751 752 pub nesting: Option<NestingPermissions>,753}754755impl CollectionPermissions {756 757 pub fn access(&self) -> AccessMode {758 self.access.unwrap_or(AccessMode::Normal)759 }760761 762 pub fn mint_mode(&self) -> bool {763 self.mint_mode.unwrap_or(false)764 }765766 767 pub fn nesting(&self) -> &NestingPermissions {768 static DEFAULT: NestingPermissions = NestingPermissions {769 token_owner: false,770 collection_admin: false,771 restricted: None,772 #[cfg(feature = "runtime-benchmarks")]773 permissive: false,774 };775 self.nesting.as_ref().unwrap_or(&DEFAULT)776 }777}778779780type OwnerRestrictedSetInner = BoundedBTreeSet<CollectionId, ConstU32<16>>;781782783#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen, Derivative)]784#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]785#[derivative(Debug)]786pub struct OwnerRestrictedSet(787 #[cfg_attr(feature = "serde1", serde(with = "bounded::set_serde"))]788 #[derivative(Debug(format_with = "bounded::set_debug"))]789 pub OwnerRestrictedSetInner,790);791792impl OwnerRestrictedSet {793 794 pub fn new() -> Self {795 Self(Default::default())796 }797}798impl core::ops::Deref for OwnerRestrictedSet {799 type Target = OwnerRestrictedSetInner;800 fn deref(&self) -> &Self::Target {801 &self.0802 }803}804impl core::ops::DerefMut for OwnerRestrictedSet {805 fn deref_mut(&mut self) -> &mut Self::Target {806 &mut self.0807 }808}809810811#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen, Derivative)]812#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]813#[derivative(Debug)]814pub struct NestingPermissions {815 816 pub token_owner: bool,817 818 pub collection_admin: bool,819 820 pub restricted: Option<OwnerRestrictedSet>,821822 #[cfg(feature = "runtime-benchmarks")]823 824 pub permissive: bool,825}826827828829830#[derive(Encode, Decode, Debug, Clone, Copy, PartialEq, TypeInfo, MaxEncodedLen)]831#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]832pub enum SponsoringRateLimit {833 834 SponsoringDisabled,835 836 Blocks(u32),837}838839840#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative, TypeInfo)]841#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]842#[derivative(Debug)]843pub struct CreateNftData {844 845 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]846 #[derivative(Debug(format_with = "bounded::vec_debug"))]847 848 pub properties: CollectionPropertiesVec,849}850851852#[derive(Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq, TypeInfo)]853#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]854pub struct CreateFungibleData {855 856 pub value: u128,857}858859860#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative, TypeInfo)]861#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]862#[derivative(Debug)]863pub struct CreateReFungibleData {864 865 pub pieces: u128,866867 868 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]869 #[derivative(Debug(format_with = "bounded::vec_debug"))]870 pub properties: CollectionPropertiesVec,871}872873874#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]875#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]876pub enum MetaUpdatePermission {877 ItemOwner,878 Admin,879 None,880}881882883884#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]885#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]886pub enum CreateItemData {887 888 NFT(CreateNftData),889 890 Fungible(CreateFungibleData),891 892 ReFungible(CreateReFungibleData),893}894895896#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]897#[derivative(Debug)]898pub struct CreateNftExData<CrossAccountId> {899 900 #[derivative(Debug(format_with = "bounded::vec_debug"))]901 pub properties: CollectionPropertiesVec,902903 904 pub owner: CrossAccountId,905}906907908#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]909#[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]910pub struct CreateRefungibleExMultipleOwners<CrossAccountId> {911 #[derivative(Debug(format_with = "bounded::map_debug"))]912 pub users: BoundedBTreeMap<CrossAccountId, u128, ConstU32<MAX_ITEMS_PER_BATCH>>,913 #[derivative(Debug(format_with = "bounded::vec_debug"))]914 pub properties: CollectionPropertiesVec,915}916917918#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]919#[derivative(Debug(bound = "CrossAccountId: fmt::Debug"))]920pub struct CreateRefungibleExSingleOwner<CrossAccountId> {921 pub user: CrossAccountId,922 pub pieces: u128,923 #[derivative(Debug(format_with = "bounded::vec_debug"))]924 pub properties: CollectionPropertiesVec,925}926927928#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]929#[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]930pub enum CreateItemExData<CrossAccountId> {931 932 NFT(933 #[derivative(Debug(format_with = "bounded::vec_debug"))]934 BoundedVec<CreateNftExData<CrossAccountId>, ConstU32<MAX_ITEMS_PER_BATCH>>,935 ),936937 938 Fungible(939 #[derivative(Debug(format_with = "bounded::map_debug"))]940 BoundedBTreeMap<CrossAccountId, u128, ConstU32<MAX_ITEMS_PER_BATCH>>,941 ),942943 944 945 RefungibleMultipleItems(946 #[derivative(Debug(format_with = "bounded::vec_debug"))]947 BoundedVec<CreateRefungibleExSingleOwner<CrossAccountId>, ConstU32<MAX_ITEMS_PER_BATCH>>,948 ),949950 951 952 RefungibleMultipleOwners(CreateRefungibleExMultipleOwners<CrossAccountId>),953}954955impl From<CreateNftData> for CreateItemData {956 fn from(item: CreateNftData) -> Self {957 CreateItemData::NFT(item)958 }959}960961impl From<CreateReFungibleData> for CreateItemData {962 fn from(item: CreateReFungibleData) -> Self {963 CreateItemData::ReFungible(item)964 }965}966967impl From<CreateFungibleData> for CreateItemData {968 fn from(item: CreateFungibleData) -> Self {969 CreateItemData::Fungible(item)970 }971}972973974#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]975#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]976977pub struct TokenChild {978 979 pub token: TokenId,980981 982 pub collection: CollectionId,983}984985986#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]987#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]988pub struct CollectionStats {989 990 pub created: u32,991992 993 pub destroyed: u32,994995 996 pub alive: u32,997}9989991000#[derive(Encode, Decode, Clone, Debug)]1001#[cfg_attr(feature = "std", derive(PartialEq))]1002pub struct PhantomType<T>(core::marker::PhantomData<T>);10031004impl<T: TypeInfo + 'static> TypeInfo for PhantomType<T> {1005 type Identity = PhantomType<T>;10061007 fn type_info() -> scale_info::Type {1008 use scale_info::{1009 Type, Path,1010 build::{FieldsBuilder, UnnamedFields},1011 form::MetaForm,1012 type_params,1013 };1014 Type::builder()1015 .path(Path::new("up_data_structs", "PhantomType"))1016 .type_params(type_params!(T))1017 .composite(1018 <FieldsBuilder<MetaForm, UnnamedFields>>::default().field(|b| b.ty::<[T; 0]>()),1019 )1020 }1021}1022impl<T> MaxEncodedLen for PhantomType<T> {1023 fn max_encoded_len() -> usize {1024 01025 }1026}102710281029pub type BoundedBytes<S> = BoundedVec<u8, S>;103010311032pub type AuxPropertyValue = BoundedBytes<ConstU32<MAX_AUX_PROPERTY_VALUE_LENGTH>>;103310341035pub type PropertyKey = BoundedBytes<ConstU32<MAX_PROPERTY_KEY_LENGTH>>;103610371038pub type PropertyValue = BoundedBytes<ConstU32<MAX_PROPERTY_VALUE_LENGTH>>;103910401041#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone, Default)]1042#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]1043pub struct PropertyPermission {1044 1045 1046 1047 pub mutable: bool,10481049 1050 pub collection_admin: bool,10511052 1053 pub token_owner: bool,1054}10551056impl PropertyPermission {1057 1058 pub fn none() -> Self {1059 Self {1060 mutable: true,1061 collection_admin: false,1062 token_owner: false,1063 }1064 }1065}106610671068#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, MaxEncodedLen)]1069#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]1070pub struct Property {1071 1072 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]1073 pub key: PropertyKey,10741075 1076 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]1077 pub value: PropertyValue,1078}10791080impl Into<(PropertyKey, PropertyValue)> for Property {1081 fn into(self) -> (PropertyKey, PropertyValue) {1082 (self.key, self.value)1083 }1084}108510861087#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]1088#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]1089pub struct PropertyKeyPermission {1090 1091 #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]1092 pub key: PropertyKey,10931094 1095 pub permission: PropertyPermission,1096}10971098impl Into<(PropertyKey, PropertyPermission)> for PropertyKeyPermission {1099 fn into(self) -> (PropertyKey, PropertyPermission) {1100 (self.key, self.permission)1101 }1102}110311041105#[derive(Debug)]1106pub enum PropertiesError {1107 1108 1109 1110 1111 NoSpaceForProperty,11121113 1114 1115 1116 PropertyLimitReached,11171118 1119 InvalidCharacterInPropertyKey,11201121 1122 1123 1124 PropertyKeyIsTooLong,11251126 1127 EmptyPropertyKey,1128}112911301131#[derive(Debug)]1132pub enum TokenOwnerError {1133 NotFound,1134 MultipleOwners,1135}11361137113811391140#[derive(Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Clone, Copy)]1141pub enum PropertyScope {1142 None,1143 Rmrk,1144}11451146impl PropertyScope {1147 pub fn prefix(&self) -> &'static [u8] {1148 match self {1149 Self::None => b"",1150 Self::Rmrk => b"rmrk:",1151 }1152 }1153 1154 pub fn apply(self, key: PropertyKey) -> Result<PropertyKey, PropertiesError> {1155 let prefix = self.prefix();1156 if prefix == b"" {1157 return Ok(key);1158 }1159 [prefix, key.as_slice()]1160 .concat()1161 .try_into()1162 .map_err(|_| PropertiesError::PropertyKeyIsTooLong)1163 }1164}116511661167pub trait TrySetProperty: Sized {1168 type Value;11691170 1171 fn try_scoped_set(1172 &mut self,1173 scope: PropertyScope,1174 key: PropertyKey,1175 value: Self::Value,1176 ) -> Result<Option<Self::Value>, PropertiesError>;11771178 1179 fn try_scoped_set_from_iter<I, KV>(1180 &mut self,1181 scope: PropertyScope,1182 iter: I,1183 ) -> Result<(), PropertiesError>1184 where1185 I: Iterator<Item = KV>,1186 KV: Into<(PropertyKey, Self::Value)>,1187 {1188 for kv in iter {1189 let (key, value) = kv.into();1190 self.try_scoped_set(scope, key, value)?;1191 }11921193 Ok(())1194 }11951196 1197 fn try_set(1198 &mut self,1199 key: PropertyKey,1200 value: Self::Value,1201 ) -> Result<Option<Self::Value>, PropertiesError> {1202 self.try_scoped_set(PropertyScope::None, key, value)1203 }12041205 1206 fn try_set_from_iter<I, KV>(&mut self, iter: I) -> Result<(), PropertiesError>1207 where1208 I: Iterator<Item = KV>,1209 KV: Into<(PropertyKey, Self::Value)>,1210 {1211 self.try_scoped_set_from_iter(PropertyScope::None, iter)1212 }1213}121412151216#[derive(Encode, Decode, TypeInfo, Derivative, Clone, PartialEq, MaxEncodedLen)]1217#[derivative(Default(bound = ""))]1218pub struct PropertiesMap<Value>(1219 BoundedBTreeMap<PropertyKey, Value, ConstU32<MAX_PROPERTIES_PER_ITEM>>,1220);12211222impl<Value> PropertiesMap<Value> {1223 1224 pub fn new() -> Self {1225 Self(BoundedBTreeMap::new())1226 }12271228 1229 pub fn remove(&mut self, key: &PropertyKey) -> Result<Option<Value>, PropertiesError> {1230 Self::check_property_key(key)?;12311232 Ok(self.0.remove(key))1233 }12341235 1236 pub fn get(&self, key: &PropertyKey) -> Option<&Value> {1237 self.0.get(key)1238 }12391240 1241 pub fn contains_key(&self, key: &PropertyKey) -> bool {1242 self.0.contains_key(key)1243 }12441245 1246 fn check_property_key(key: &PropertyKey) -> Result<(), PropertiesError> {1247 if key.is_empty() {1248 return Err(PropertiesError::EmptyPropertyKey);1249 }12501251 for byte in key.as_slice().iter() {1252 let byte = *byte;12531254 if !byte.is_ascii_alphanumeric() && byte != b'_' && byte != b'-' && byte != b'.' {1255 return Err(PropertiesError::InvalidCharacterInPropertyKey);1256 }1257 }12581259 Ok(())1260 }12611262 pub fn values(&self) -> impl Iterator<Item = &Value> {1263 self.0.values()1264 }12651266 pub fn iter(&self) -> impl Iterator<Item = (&PropertyKey, &Value)> {1267 self.0.iter()1268 }1269}12701271impl<Value> IntoIterator for PropertiesMap<Value> {1272 type Item = (PropertyKey, Value);1273 type IntoIter = <1274 BoundedBTreeMap<1275 PropertyKey,1276 Value,1277 ConstU32<MAX_PROPERTIES_PER_ITEM>1278 > as IntoIterator1279 >::IntoIter;12801281 fn into_iter(self) -> Self::IntoIter {1282 self.0.into_iter()1283 }1284}12851286impl<Value> TrySetProperty for PropertiesMap<Value> {1287 type Value = Value;12881289 fn try_scoped_set(1290 &mut self,1291 scope: PropertyScope,1292 key: PropertyKey,1293 value: Self::Value,1294 ) -> Result<Option<Self::Value>, PropertiesError> {1295 Self::check_property_key(&key)?;12961297 let key = scope.apply(key)?;1298 self.01299 .try_insert(key, value)1300 .map_err(|_| PropertiesError::PropertyLimitReached)1301 }1302}130313041305pub type PropertiesPermissionMap = PropertiesMap<PropertyPermission>;13061307fn slice_size(data: &[u8]) -> u32 {1308 scoped_slice_size(PropertyScope::None, data)1309}1310fn scoped_slice_size(scope: PropertyScope, data: &[u8]) -> u32 {1311 use codec::Compact;1312 let prefix = scope.prefix();1313 <Compact<u32>>::encoded_size(&Compact(data.len() as u32 + prefix.len() as u32)) as u321314 + data.len() as u321315 + prefix.len() as u321316}131713181319#[derive(Encode, Decode, TypeInfo, Clone, PartialEq)]1320pub struct Properties<const S: u32> {1321 map: PropertiesMap<PropertyValue>,1322 consumed_space: u32,1323 1324 _reserved: u32,1325}13261327impl<const S: u32> MaxEncodedLen for Properties<S> {1328 fn max_encoded_len() -> usize {1329 1330 u32::max_encoded_len() * 3 + S as usize1331 }1332}13331334impl<const S: u32> Default for Properties<S> {1335 fn default() -> Self {1336 Self::new()1337 }1338}13391340impl<const S: u32> Properties<S> {1341 1342 pub fn new() -> Self {1343 Self {1344 map: PropertiesMap::new(),1345 consumed_space: 0,1346 _reserved: 0,1347 }1348 }13491350 1351 pub fn remove(&mut self, key: &PropertyKey) -> Result<Option<PropertyValue>, PropertiesError> {1352 let value = self.map.remove(key)?;13531354 if let Some(ref value) = value {1355 let kv_len = slice_size(key) + slice_size(value);1356 self.consumed_space = self.consumed_space.saturating_sub(kv_len);1357 }13581359 Ok(value)1360 }13611362 1363 pub fn get(&self, key: &PropertyKey) -> Option<&PropertyValue> {1364 self.map.get(key)1365 }13661367 1368 1369 pub fn recompute_consumed_space(&mut self) {1370 self.consumed_space = self1371 .map1372 .iter()1373 .map(|(key, value)| slice_size(key) + slice_size(value))1374 .sum();1375 }1376}13771378impl<const S: u32> IntoIterator for Properties<S> {1379 type Item = (PropertyKey, PropertyValue);1380 type IntoIter = <PropertiesMap<PropertyValue> as IntoIterator>::IntoIter;13811382 fn into_iter(self) -> Self::IntoIter {1383 self.map.into_iter()1384 }1385}13861387impl<const S: u32> TrySetProperty for Properties<S> {1388 type Value = PropertyValue;13891390 fn try_scoped_set(1391 &mut self,1392 scope: PropertyScope,1393 key: PropertyKey,1394 value: Self::Value,1395 ) -> Result<Option<Self::Value>, PropertiesError> {1396 let key_size = scoped_slice_size(scope, &key);1397 let value_size = slice_size(&value) as u32;13981399 if self.consumed_space + value_size + key_size > S && !cfg!(feature = "runtime-benchmarks")1400 {1401 return Err(PropertiesError::NoSpaceForProperty);1402 }14031404 let old_value = self.map.try_scoped_set(scope, key, value)?;14051406 if let Some(old_value) = old_value.as_ref() {1407 let old_value_size = slice_size(&old_value);1408 self.consumed_space = self.consumed_space.saturating_sub(old_value_size) + value_size;1409 } else {1410 self.consumed_space += key_size + value_size;1411 }14121413 Ok(old_value)1414 }1415}14161417pub type CollectionProperties = Properties<MAX_COLLECTION_PROPERTIES_SIZE>;1418pub type TokenProperties = Properties<MAX_TOKEN_PROPERTIES_SIZE>;14191420#[cfg(test)]1421mod tests {1422 use super::*;1423 use codec::IoReader;14241425 #[test]1426 fn rpc_collection_supports_decoding_old_versions() {1427 let encoded_rpc_collection: [u8; 1013] = [1428 0, 1, 250, 241, 137, 120, 188, 29, 94, 210, 193, 237, 186, 22, 203, 241, 52, 248, 167,1429 235, 241, 211, 236, 28, 138, 156, 59, 160, 156, 105, 39, 247, 207, 101, 0, 0, 48, 65,1430 0, 73, 0, 32, 0, 67, 0, 114, 0, 101, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 115, 0,1431 252, 65, 0, 32, 0, 112, 0, 105, 0, 101, 0, 99, 0, 101, 0, 32, 0, 111, 0, 102, 0, 32, 0,1432 97, 0, 32, 0, 109, 0, 97, 0, 99, 0, 104, 0, 105, 0, 110, 0, 101, 0, 32, 0, 109, 0, 105,1433 0, 110, 0, 100, 0, 46, 0, 32, 0, 69, 0, 118, 0, 101, 0, 114, 0, 121, 0, 32, 0, 78, 0,1434 70, 0, 84, 0, 32, 0, 105, 0, 115, 0, 32, 0, 109, 0, 97, 0, 100, 0, 101, 0, 32, 0, 101,1435 0, 120, 0, 99, 0, 108, 0, 117, 0, 115, 0, 105, 0, 118, 0, 101, 0, 108, 0, 121, 0, 32,1436 0, 98, 0, 121, 0, 32, 0, 65, 0, 73, 0, 46, 0, 12, 65, 73, 67, 0, 0, 1, 0, 0, 0, 0, 0,1437 0, 0, 0, 0, 0, 17, 1, 123, 34, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 67, 111,1438 118, 101, 114, 34, 58, 34, 81, 109, 98, 52, 104, 122, 76, 101, 51, 49, 102, 98, 71, 74,1439 77, 89, 68, 82, 88, 84, 115, 107, 56, 49, 76, 103, 76, 97, 88, 76, 69, 112, 121, 97,1440 122, 102, 66, 85, 103, 111, 110, 118, 49, 118, 84, 85, 34, 125, 125, 11, 123, 34, 110,1441 101, 115, 116, 101, 100, 34, 58, 123, 34, 111, 110, 67, 104, 97, 105, 110, 77, 101,1442 116, 97, 68, 97, 116, 97, 34, 58, 123, 34, 110, 101, 115, 116, 101, 100, 34, 58, 123,1443 34, 78, 70, 84, 77, 101, 116, 97, 34, 58, 123, 34, 102, 105, 101, 108, 100, 115, 34,1444 58, 123, 34, 105, 112, 102, 115, 74, 115, 111, 110, 34, 58, 123, 34, 105, 100, 34, 58,1445 49, 44, 34, 114, 117, 108, 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34,1446 44, 34, 116, 121, 112, 101, 34, 58, 34, 115, 116, 114, 105, 110, 103, 34, 125, 44, 34,1447 67, 111, 108, 111, 114, 34, 58, 123, 34, 105, 100, 34, 58, 50, 44, 34, 114, 117, 108,1448 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34, 44, 34, 116, 121, 112,1449 101, 34, 58, 34, 67, 111, 108, 111, 114, 34, 125, 44, 34, 73, 110, 116, 101, 110, 115,1450 105, 111, 110, 115, 34, 58, 123, 34, 105, 100, 34, 58, 51, 44, 34, 114, 117, 108, 101,1451 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34, 44, 34, 116, 121, 112, 101, 34,1452 58, 34, 73, 110, 116, 101, 110, 115, 105, 111, 110, 115, 34, 125, 44, 34, 77, 111, 111,1453 100, 34, 58, 123, 34, 105, 100, 34, 58, 52, 44, 34, 114, 117, 108, 101, 34, 58, 34,1454 114, 101, 113, 117, 105, 114, 101, 100, 34, 44, 34, 116, 121, 112, 101, 34, 58, 34, 77,1455 111, 111, 100, 34, 125, 125, 125, 44, 34, 67, 111, 108, 111, 114, 34, 58, 123, 34, 111,1456 112, 116, 105, 111, 110, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34,1457 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 67, 111, 108, 111, 114, 101, 100, 92, 34,1458 125, 34, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92,1459 34, 58, 92, 34, 66, 108, 97, 99, 107, 38, 87, 104, 105, 116, 101, 92, 34, 125, 34, 125,1460 44, 34, 118, 97, 108, 117, 101, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34,1461 58, 48, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 49, 125, 125, 44, 34, 73, 110,1462 116, 101, 110, 115, 105, 111, 110, 115, 34, 58, 123, 34, 111, 112, 116, 105, 111, 110,1463 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34, 123, 92, 34, 101, 110,1464 92, 34, 58, 92, 34, 101, 118, 105, 108, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108,1465 100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 103, 111, 111, 100, 92,1466 34, 125, 34, 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 34, 123, 92, 34, 101, 110,1467 92, 34, 58, 92, 34, 110, 101, 117, 116, 114, 97, 108, 92, 34, 125, 34, 125, 44, 34,1468 118, 97, 108, 117, 101, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 48,1469 44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 49, 44, 34, 102, 105, 101, 108, 100, 51,1470 34, 58, 50, 125, 125, 44, 34, 77, 111, 111, 100, 34, 58, 123, 34, 111, 112, 116, 105,1471 111, 110, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34, 123, 92, 34,1472 101, 110, 92, 34, 58, 92, 34, 65, 98, 115, 116, 114, 97, 99, 116, 92, 34, 125, 34, 44,1473 34, 102, 105, 101, 108, 100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34,1474 85, 110, 99, 97, 110, 110, 101, 121, 32, 118, 97, 108, 108, 101, 121, 92, 34, 125, 34,1475 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92,1476 34, 83, 117, 114, 114, 101, 97, 108, 105, 115, 116, 92, 34, 125, 34, 125, 44, 34, 118,1477 97, 108, 117, 101, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 48, 44,1478 34, 102, 105, 101, 108, 100, 50, 34, 58, 49, 44, 34, 102, 105, 101, 108, 100, 51, 34,1479 58, 50, 125, 125, 125, 125, 125, 125, 0,1480 ];1481 let mut bytes = IoReader(encoded_rpc_collection.as_slice());1482 CollectionVersion1::<[u8; 34]>::decode(&mut bytes).unwrap();1483 }14841485 #[test]1486 fn rpc_collection_supports_decoding_new_versions() {1487 let encoded_rpc_collection: [u8; 1576] = [1488 0, 1, 238, 236, 179, 149, 150, 47, 71, 194, 69, 174, 250, 116, 251, 148, 90, 15, 56,1489 220, 91, 79, 49, 79, 45, 197, 171, 98, 14, 171, 80, 23, 58, 92, 0, 96, 77, 0, 105, 0,1490 110, 0, 116, 0, 70, 0, 101, 0, 115, 0, 116, 0, 32, 0, 83, 0, 121, 0, 109, 0, 109, 0,1491 101, 0, 116, 0, 114, 0, 121, 0, 32, 0, 66, 0, 114, 0, 101, 0, 97, 0, 99, 0, 104, 0,1492 113, 3, 83, 0, 121, 0, 109, 0, 109, 0, 101, 0, 116, 0, 114, 0, 121, 0, 32, 0, 104, 0,1493 97, 0, 115, 0, 32, 0, 115, 0, 111, 0, 109, 0, 101, 0, 116, 0, 104, 0, 105, 0, 110, 0,1494 103, 0, 32, 0, 105, 0, 110, 0, 116, 0, 111, 0, 120, 0, 105, 0, 99, 0, 97, 0, 116, 0,1495 105, 0, 110, 0, 103, 0, 32, 0, 116, 0, 104, 0, 97, 0, 116, 0, 32, 0, 100, 0, 114, 0,1496 97, 0, 119, 0, 115, 0, 32, 0, 121, 0, 111, 0, 117, 0, 32, 0, 105, 0, 110, 0, 46, 0, 10,1497 0, 73, 0, 110, 0, 115, 0, 112, 0, 105, 0, 114, 0, 101, 0, 100, 0, 32, 0, 98, 0, 121, 0,1498 32, 0, 116, 0, 104, 0, 101, 0, 32, 0, 112, 0, 101, 0, 114, 0, 102, 0, 101, 0, 99, 0,1499 116, 0, 105, 0, 111, 0, 110, 0, 32, 0, 111, 0, 102, 0, 32, 0, 116, 0, 104, 0, 101, 0,1500 32, 0, 115, 0, 121, 0, 109, 0, 109, 0, 101, 0, 116, 0, 114, 0, 121, 0, 44, 0, 32, 0,1501 73, 0, 32, 0, 104, 0, 97, 0, 118, 0, 101, 0, 32, 0, 99, 0, 114, 0, 101, 0, 97, 0, 116,1502 0, 101, 0, 100, 0, 32, 0, 115, 0, 121, 0, 109, 0, 109, 0, 101, 0, 116, 0, 114, 0, 105,1503 0, 99, 0, 97, 0, 108, 0, 32, 0, 105, 0, 109, 0, 97, 0, 103, 0, 101, 0, 115, 0, 32, 0,1504 111, 0, 102, 0, 32, 0, 115, 0, 101, 0, 118, 0, 101, 0, 114, 0, 97, 0, 108, 0, 32, 0,1505 118, 0, 101, 0, 114, 0, 116, 0, 105, 0, 99, 0, 101, 0, 115, 0, 44, 0, 32, 0, 98, 0,1506 117, 0, 116, 0, 32, 0, 115, 0, 111, 0, 109, 0, 101, 0, 32, 0, 115, 0, 121, 0, 109, 0,1507 109, 0, 101, 0, 116, 0, 114, 0, 121, 0, 32, 0, 98, 0, 114, 0, 101, 0, 97, 0, 99, 0,1508 104, 0, 101, 0, 115, 0, 32, 0, 97, 0, 110, 0, 100, 0, 32, 0, 99, 0, 111, 0, 108, 0,1509 111, 0, 114, 0, 115, 0, 32, 0, 116, 0, 104, 0, 97, 0, 116, 0, 32, 0, 109, 0, 97, 0,1510 107, 0, 101, 0, 32, 0, 101, 0, 97, 0, 99, 0, 104, 0, 32, 0, 105, 0, 109, 0, 97, 0, 103,1511 0, 101, 0, 32, 0, 85, 0, 78, 0, 73, 0, 81, 0, 85, 0, 69, 0, 46, 0, 12, 83, 121, 66, 0,1512 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 4, 56, 95, 111, 108, 100, 95, 99,1513 111, 110, 115, 116, 68, 97, 116, 97, 0, 1, 0, 12, 92, 95, 111, 108, 100, 95, 99, 111,1514 110, 115, 116, 79, 110, 67, 104, 97, 105, 110, 83, 99, 104, 101, 109, 97, 97, 13, 123,1515 34, 110, 101, 115, 116, 101, 100, 34, 58, 123, 34, 111, 110, 67, 104, 97, 105, 110, 77,1516 101, 116, 97, 68, 97, 116, 97, 34, 58, 123, 34, 110, 101, 115, 116, 101, 100, 34, 58,1517 123, 34, 78, 70, 84, 77, 101, 116, 97, 34, 58, 123, 34, 102, 105, 101, 108, 100, 115,1518 34, 58, 123, 34, 105, 112, 102, 115, 74, 115, 111, 110, 34, 58, 123, 34, 105, 100, 34,1519 58, 49, 44, 34, 114, 117, 108, 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100,1520 34, 44, 34, 116, 121, 112, 101, 34, 58, 34, 115, 116, 114, 105, 110, 103, 34, 125, 44,1521 34, 67, 111, 108, 111, 114, 34, 58, 123, 34, 105, 100, 34, 58, 50, 44, 34, 114, 117,1522 108, 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34, 44, 34, 116, 121,1523 112, 101, 34, 58, 34, 67, 111, 108, 111, 114, 34, 125, 44, 34, 83, 121, 109, 109, 101,1524 116, 114, 121, 32, 66, 114, 101, 97, 99, 104, 34, 58, 123, 34, 105, 100, 34, 58, 51,1525 44, 34, 114, 117, 108, 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34, 44,1526 34, 116, 121, 112, 101, 34, 58, 34, 83, 121, 109, 109, 101, 116, 114, 121, 32, 66, 114,1527 101, 97, 99, 104, 34, 125, 44, 34, 86, 101, 114, 116, 105, 99, 101, 34, 58, 123, 34,1528 105, 100, 34, 58, 52, 44, 34, 114, 117, 108, 101, 34, 58, 34, 114, 101, 113, 117, 105,1529 114, 101, 100, 34, 44, 34, 116, 121, 112, 101, 34, 58, 34, 86, 101, 114, 116, 105, 99,1530 101, 34, 125, 125, 125, 44, 34, 67, 111, 108, 111, 114, 34, 58, 123, 34, 111, 112, 116,1531 105, 111, 110, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34, 123, 92,1532 34, 101, 110, 92, 34, 58, 92, 34, 49, 32, 32, 32, 92, 34, 125, 34, 44, 34, 102, 105,1533 101, 108, 100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 50, 32, 92,1534 34, 125, 34, 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 34, 123, 92, 34, 101, 110,1535 92, 34, 58, 92, 34, 51, 92, 34, 125, 34, 125, 44, 34, 118, 97, 108, 117, 101, 115, 34,1536 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 48, 44, 34, 102, 105, 101, 108, 100,1537 50, 34, 58, 49, 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 50, 125, 125, 44, 34, 83,1538 121, 109, 109, 101, 116, 114, 121, 32, 66, 114, 101, 97, 99, 104, 34, 58, 123, 34, 111,1539 112, 116, 105, 111, 110, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34,1540 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 49, 92, 34, 125, 34, 44, 34, 102, 105, 101,1541 108, 100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 50, 92, 34, 125,1542 34, 125, 44, 34, 118, 97, 108, 117, 101, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100,1543 49, 34, 58, 48, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 49, 125, 125, 44, 34, 86,1544 101, 114, 116, 105, 99, 101, 34, 58, 123, 34, 111, 112, 116, 105, 111, 110, 115, 34,1545 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34,1546 58, 92, 34, 54, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 34, 123,1547 92, 34, 101, 110, 92, 34, 58, 92, 34, 55, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108,1548 100, 51, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 56, 92, 34, 125, 34,1549 44, 34, 102, 105, 101, 108, 100, 52, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92,1550 34, 57, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108, 100, 53, 34, 58, 34, 123, 92, 34,1551 101, 110, 92, 34, 58, 92, 34, 49, 48, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108, 100,1552 54, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 49, 49, 92, 34, 125, 34, 44,1553 34, 102, 105, 101, 108, 100, 55, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34,1554 49, 50, 92, 34, 125, 34, 125, 44, 34, 118, 97, 108, 117, 101, 115, 34, 58, 123, 34,1555 102, 105, 101, 108, 100, 49, 34, 58, 48, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58,1556 49, 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 50, 44, 34, 102, 105, 101, 108, 100,1557 52, 34, 58, 51, 44, 34, 102, 105, 101, 108, 100, 53, 34, 58, 52, 44, 34, 102, 105, 101,1558 108, 100, 54, 34, 58, 53, 44, 34, 102, 105, 101, 108, 100, 55, 34, 58, 54, 125, 125,1559 125, 125, 125, 125, 72, 95, 111, 108, 100, 95, 115, 99, 104, 101, 109, 97, 86, 101,1560 114, 115, 105, 111, 110, 24, 85, 110, 105, 113, 117, 101, 104, 95, 111, 108, 100, 95,1561 118, 97, 114, 105, 97, 98, 108, 101, 79, 110, 67, 104, 97, 105, 110, 83, 99, 104, 101,1562 109, 97, 17, 1, 123, 34, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 67, 111, 118,1563 101, 114, 34, 58, 34, 81, 109, 82, 67, 77, 84, 109, 57, 118, 81, 107, 76, 89, 86, 65,1564 54, 54, 87, 80, 49, 75, 72, 57, 55, 106, 84, 76, 76, 115, 56, 74, 78, 86, 65, 114, 80,1565 66, 52, 56, 98, 106, 87, 84, 75, 74, 110, 34, 125, 0, 0, 0,1566 ];1567 let mut bytes = IoReader(encoded_rpc_collection.as_slice());1568 RpcCollection::<[u8; 34]>::decode(&mut bytes).unwrap();1569 }1570}