Browse Source

content-directory: Channel create and update extrinsics

Mokhtar Naamani 4 years ago
parent
commit
a0979c04dd

+ 35 - 31
runtime-modules/content/src/lib.rs

@@ -29,7 +29,8 @@ use sp_std::vec::Vec;
 use system::ensure_signed;
 
 pub use common::storage::{
-    ContentParameters as ContentParametersRecord, StorageObjectOwner, StorageSystem,
+    ContentParameters as ContentParametersRecord, StorageObjectOwner as StorageObjectOwnerRecord,
+    StorageSystem,
 };
 
 pub use common::{
@@ -44,6 +45,12 @@ pub(crate) type DataObjectTypeId<T> = <T as StorageOwnership>::DataObjectTypeId;
 
 pub(crate) type ContentParameters<T> = ContentParametersRecord<ContentId<T>, DataObjectTypeId<T>>;
 
+pub(crate) type StorageObjectOwner<T> = StorageObjectOwnerRecord<
+    <T as MembershipTypes>::MemberId,
+    <T as StorageOwnership>::ChannelId,
+    <T as StorageOwnership>::DAOId,
+>;
+
 /// Type, used in diffrent numeric constraints representations
 pub type MaxNumber = u32;
 
@@ -229,21 +236,25 @@ pub type ChannelOwnershipTransferRequest<T> = ChannelOwnershipTransferRequestRec
 /// Information about channel being created.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
-pub struct ChannelCreationParameters<ContentParameters> {
+pub struct ChannelCreationParameters<ContentParameters, AccountId> {
     /// Assets referenced by metadata
     assets: Vec<NewAsset<ContentParameters>>,
     /// Metadata about the channel.
     meta: Vec<u8>,
+    /// optional reward account
+    reward_account: Option<AccountId>,
 }
 
 /// Information about channel being updated.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
-pub struct ChannelUpdateParameters<ContentParameters> {
+pub struct ChannelUpdateParameters<ContentParameters, AccountId> {
     /// Assets referenced by metadata
     assets: Option<Vec<NewAsset<ContentParameters>>>,
     /// If set, metadata update for the channel.
     new_meta: Option<Vec<u8>>,
+    /// If set, updates the reward account of the channel
+    reward_account: Option<Option<AccountId>>,
 }
 
 /// A category that videos can belong to.
@@ -648,7 +659,7 @@ decl_module! {
             origin,
             actor: ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
             owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
-            params: ChannelCreationParameters<ContentParameters<T>>,
+            params: ChannelCreationParameters<ContentParameters<T>, T::AccountId>,
         ) -> DispatchResult {
             ensure_actor_authorized_to_create_or_update_channel::<T>(
                 origin,
@@ -657,11 +668,11 @@ decl_module! {
             )?;
 
             // Pick out the assets to be uploaded to storage system
-            let content_parameters: Vec<ContentParameters<T>> = Self::pick_upload_parameters_from_assets(&params.assets);
+            let content_parameters: Vec<ContentParameters<T>> = Self::pick_content_parameters_from_assets(&params.assets);
 
             let expected_channel_id = NextChannelId::<T>::get();
 
-            let object_owner = Self::channel_owner_to_object_owner(&owner, &expected_channel_id)?;
+            let object_owner = StorageObjectOwner::<T>::Channel(expected_channel_id);
 
             // check assets can be uploaded to storage.
             // update can_add_content() to only take &refrences
@@ -697,7 +708,7 @@ decl_module! {
                 playlists: vec![],
                 series: vec![],
                 is_censored: false,
-                reward_account: None,
+                reward_account: params.reward_account.clone(),
             };
             ChannelById::<T>::insert(channel_id, channel.clone());
 
@@ -715,7 +726,7 @@ decl_module! {
             origin,
             actor: ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
             channel_id: T::ChannelId,
-            params: ChannelUpdateParameters<ContentParameters<T>>,
+            params: ChannelUpdateParameters<ContentParameters<T>, T::AccountId>,
         ) -> DispatchResult {
             // check that channel exists
             let channel = Self::ensure_channel_exists(&channel_id)?;
@@ -728,9 +739,9 @@ decl_module! {
 
             // Pick out the assets to be uploaded to storage system
             let new_assets = if let Some(assets) = &params.assets {
-                let upload_parameters: Vec<ContentParameters<T>> = Self::pick_upload_parameters_from_assets(assets);
+                let upload_parameters: Vec<ContentParameters<T>> = Self::pick_content_parameters_from_assets(assets);
 
-                let object_owner = Self::channel_owner_to_object_owner(&channel.owner, &channel_id)?;
+                let object_owner = StorageObjectOwner::<T>::Channel(channel_id);
 
                 // check assets can be uploaded to storage.
                 // update can_add_content() to only take &refrences
@@ -748,8 +759,14 @@ decl_module! {
             // == MUTATION SAFE ==
             //
 
+            let mut channel = channel;
+
+            if let Some(reward_account) = &params.reward_account {
+                channel.reward_account = reward_account.clone();
+            }
+
             // update the channel
-            // ChannelById::<T>::insert(channel_id, channel.clone());
+            ChannelById::<T>::insert(channel_id, channel.clone());
 
             // add assets to storage
             // This should not fail because of prior can_add_content() check!
@@ -1134,31 +1151,17 @@ impl<T: Trait> Module<T> {
         Ok(ChannelCategoryById::<T>::get(channel_category_id))
     }
 
-    fn pick_upload_parameters_from_assets(
-        assets: &Vec<NewAsset<ContentParameters<T>>>,
+    fn pick_content_parameters_from_assets(
+        assets: &[NewAsset<ContentParameters<T>>],
     ) -> Vec<ContentParameters<T>> {
         assets
-            .clone()
-            .into_iter()
+            .iter()
             .filter_map(|asset| match asset {
-                NewAsset::Upload(upload_parameters) => Some(upload_parameters),
+                NewAsset::Upload(content_parameters) => Some(content_parameters.clone()),
                 _ => None,
             })
             .collect()
     }
-
-    fn channel_owner_to_object_owner(
-        channel_owner: &ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
-        channel_id: &T::ChannelId,
-    ) -> Result<StorageObjectOwner<T::MemberId, T::ChannelId, T::DAOId>, Error<T>> {
-        match channel_owner {
-            ChannelOwner::Member(_member_id) => Ok(StorageObjectOwner::Channel(*channel_id)),
-            ChannelOwner::CuratorGroup(_id) => {
-                Ok(StorageObjectOwner::WorkingGroup(WorkingGroup::Content))
-            }
-            _ => Err(Error::<T>::CannotConverChannelOwnerToObjectOwner),
-        }
-    }
 }
 
 // Some initial config for the module on runtime upgrade
@@ -1193,6 +1196,7 @@ decl_event!(
         Series = Series<<T as StorageOwnership>::ChannelId, <T as Trait>::VideoId>,
         Channel = Channel<T>,
         ContentParameters = ContentParameters<T>,
+        AccountId = <T as system::Trait>::AccountId,
     {
         // Curators
         CuratorGroupCreated(CuratorGroupId),
@@ -1205,12 +1209,12 @@ decl_event!(
         ChannelCreated(
             ChannelId,
             Channel,
-            ChannelCreationParameters<ContentParameters>,
+            ChannelCreationParameters<ContentParameters, AccountId>,
         ),
         ChannelUpdated(
             ChannelId,
             Channel,
-            ChannelUpdateParameters<ContentParameters>,
+            ChannelUpdateParameters<ContentParameters, AccountId>,
         ),
         ChannelDeleted(ChannelId),
 

+ 3 - 3
types/augment-codec/augment-api-tx.ts

@@ -4,7 +4,7 @@
 import { AnyNumber } from '@polkadot/types/types';
 import { Compact, Option, Vec } from '@polkadot/types/codec';
 import { Bytes, bool, u16, u32, u64 } from '@polkadot/types/primitive';
-import { ActivateOpeningAt, AddOpeningParameters, ApplicationId, ApplicationIdSet, BalanceOfMint, CategoryId, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwner, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, ContentId, ContentParameters, CuratorGroupId, CuratorId, DataObjectStorageRelationshipId, DataObjectType, DataObjectTypeId, DataObjectsMap, ElectionParameters, FillOpeningParameters, MemberId, MemoText, OpeningId, OpeningPolicyCommitment, OpeningType, PaidTermId, PersonActor, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, RewardPolicy, SeriesId, SeriesParameters, StorageObjectOwner, StorageProviderId, TerminateRoleParameters, ThreadId, Url, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, WorkerId, WorkingGroup } from './all';
+import { ActivateOpeningAt, AddOpeningParameters, ApplicationId, ApplicationIdSet, BalanceOfMint, CategoryId, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwner, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, ContentActor, ContentId, ContentParameters, CuratorGroupId, CuratorId, DataObjectStorageRelationshipId, DataObjectType, DataObjectTypeId, DataObjectsMap, ElectionParameters, FillOpeningParameters, MemberId, MemoText, OpeningId, OpeningPolicyCommitment, OpeningType, PaidTermId, PersonActor, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, RewardPolicy, SeriesId, SeriesParameters, StorageObjectOwner, StorageProviderId, TerminateRoleParameters, ThreadId, Url, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, WorkerId, WorkingGroup } from './all';
 import { Extrinsic, Signature } from '@polkadot/types/interfaces/extrinsics';
 import { GrandpaEquivocationProof, KeyOwnerProof } from '@polkadot/types/interfaces/grandpa';
 import { Heartbeat } from '@polkadot/types/interfaces/imOnline';
@@ -108,7 +108,7 @@ declare module '@polkadot/api/types/submittable' {
       cancelChannelTransferRequest: AugmentedSubmittable<(requestId: ChannelOwnershipTransferRequestId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       censorChannel: AugmentedSubmittable<(curatorId: CuratorId | AnyNumber | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       censorVideo: AugmentedSubmittable<(curatorId: CuratorId | AnyNumber | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
-      createChannel: AugmentedSubmittable<(owner: ChannelOwner | { Member: any } | { Curators: any } | { Dao: any } | string | Uint8Array, params: ChannelCreationParameters | { assets?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
+      createChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, owner: ChannelOwner | { Member: any } | { Curators: any } | { Dao: any } | string | Uint8Array, params: ChannelCreationParameters | { assets?: any; meta?: any; reward_account?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       createChannelCategory: AugmentedSubmittable<(curator: CuratorId | AnyNumber | Uint8Array, params: ChannelCategoryCreationParameters | { meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       /**
        * Add new curator group to runtime storage
@@ -143,7 +143,7 @@ declare module '@polkadot/api/types/submittable' {
       setFeaturedVideos: AugmentedSubmittable<(list: Vec<VideoId> | (VideoId | AnyNumber | Uint8Array)[]) => SubmittableExtrinsic<ApiType>>;
       uncensorChannel: AugmentedSubmittable<(curatorId: CuratorId | AnyNumber | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       uncensorVideo: AugmentedSubmittable<(curatorId: CuratorId | AnyNumber | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
-      updateChannel: AugmentedSubmittable<(owner: ChannelOwner | { Member: any } | { Curators: any } | { Dao: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: ChannelUpdateParameters | { assets?: any; new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
+      updateChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: ChannelUpdateParameters | { assets?: any; new_meta?: any; reward_account?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       updateChannelCategory: AugmentedSubmittable<(curator: CuratorId | AnyNumber | Uint8Array, category: ChannelCategoryId | AnyNumber | Uint8Array, params: ChannelCategoryUpdateParameters | { new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       updatePerson: AugmentedSubmittable<(actor: PersonActor | { Member: any } | { Curator: any } | string | Uint8Array, person: PersonId | AnyNumber | Uint8Array, params: PersonUpdateParameters | { assets?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       updatePlaylist: AugmentedSubmittable<(owner: ChannelOwner | { Member: any } | { Curators: any } | { Dao: any } | string | Uint8Array, playlist: PlaylistId | AnyNumber | Uint8Array, params: PlaylistUpdateParameters | { new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;

+ 4 - 2
types/augment/all/defs.json

@@ -727,11 +727,13 @@
     },
     "ChannelCreationParameters": {
         "assets": "Vec<NewAsset>",
-        "meta": "Bytes"
+        "meta": "Bytes",
+        "reward_account": "Option<GenericAccountId>"
     },
     "ChannelUpdateParameters": {
         "assets": "Option<Vec<NewAsset>>",
-        "new_meta": "Bytes"
+        "new_meta": "Option<Bytes>",
+        "reward_account": "Option<Option<GenericAccountId>>"
     },
     "ChannelOwnershipTransferRequestId": "u64",
     "ChannelOwnershipTransferRequest": {

+ 3 - 1
types/augment/all/types.ts

@@ -210,6 +210,7 @@ export interface ChannelContentType extends Null {}
 export interface ChannelCreationParameters extends Struct {
   readonly assets: Vec<NewAsset>;
   readonly meta: Bytes;
+  readonly reward_account: Option<GenericAccountId>;
 }
 
 /** @name ChannelCurationStatus */
@@ -245,7 +246,8 @@ export interface ChannelPublicationStatus extends Null {}
 /** @name ChannelUpdateParameters */
 export interface ChannelUpdateParameters extends Struct {
   readonly assets: Option<Vec<NewAsset>>;
-  readonly new_meta: Bytes;
+  readonly new_meta: Option<Bytes>;
+  readonly reward_account: Option<Option<GenericAccountId>>;
 }
 
 /** @name ChildPositionInParentCategory */

+ 3 - 3
types/augment/augment-api-tx.ts

@@ -4,7 +4,7 @@
 import { AnyNumber } from '@polkadot/types/types';
 import { Compact, Option, Vec } from '@polkadot/types/codec';
 import { Bytes, bool, u16, u32, u64 } from '@polkadot/types/primitive';
-import { ActivateOpeningAt, AddOpeningParameters, ApplicationId, ApplicationIdSet, BalanceOfMint, CategoryId, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwner, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, ContentId, ContentParameters, CuratorGroupId, CuratorId, DataObjectStorageRelationshipId, DataObjectType, DataObjectTypeId, DataObjectsMap, ElectionParameters, FillOpeningParameters, MemberId, MemoText, OpeningId, OpeningPolicyCommitment, OpeningType, PaidTermId, PersonActor, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, RewardPolicy, SeriesId, SeriesParameters, StorageObjectOwner, StorageProviderId, TerminateRoleParameters, ThreadId, Url, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, WorkerId, WorkingGroup } from './all';
+import { ActivateOpeningAt, AddOpeningParameters, ApplicationId, ApplicationIdSet, BalanceOfMint, CategoryId, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwner, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, ContentActor, ContentId, ContentParameters, CuratorGroupId, CuratorId, DataObjectStorageRelationshipId, DataObjectType, DataObjectTypeId, DataObjectsMap, ElectionParameters, FillOpeningParameters, MemberId, MemoText, OpeningId, OpeningPolicyCommitment, OpeningType, PaidTermId, PersonActor, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, RewardPolicy, SeriesId, SeriesParameters, StorageObjectOwner, StorageProviderId, TerminateRoleParameters, ThreadId, Url, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, WorkerId, WorkingGroup } from './all';
 import { Extrinsic, Signature } from '@polkadot/types/interfaces/extrinsics';
 import { GrandpaEquivocationProof, KeyOwnerProof } from '@polkadot/types/interfaces/grandpa';
 import { Heartbeat } from '@polkadot/types/interfaces/imOnline';
@@ -108,7 +108,7 @@ declare module '@polkadot/api/types/submittable' {
       cancelChannelTransferRequest: AugmentedSubmittable<(requestId: ChannelOwnershipTransferRequestId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       censorChannel: AugmentedSubmittable<(curatorId: CuratorId | AnyNumber | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       censorVideo: AugmentedSubmittable<(curatorId: CuratorId | AnyNumber | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
-      createChannel: AugmentedSubmittable<(owner: ChannelOwner | { Member: any } | { Curators: any } | { Dao: any } | string | Uint8Array, params: ChannelCreationParameters | { assets?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
+      createChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, owner: ChannelOwner | { Member: any } | { Curators: any } | { Dao: any } | string | Uint8Array, params: ChannelCreationParameters | { assets?: any; meta?: any; reward_account?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       createChannelCategory: AugmentedSubmittable<(curator: CuratorId | AnyNumber | Uint8Array, params: ChannelCategoryCreationParameters | { meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       /**
        * Add new curator group to runtime storage
@@ -143,7 +143,7 @@ declare module '@polkadot/api/types/submittable' {
       setFeaturedVideos: AugmentedSubmittable<(list: Vec<VideoId> | (VideoId | AnyNumber | Uint8Array)[]) => SubmittableExtrinsic<ApiType>>;
       uncensorChannel: AugmentedSubmittable<(curatorId: CuratorId | AnyNumber | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       uncensorVideo: AugmentedSubmittable<(curatorId: CuratorId | AnyNumber | Uint8Array, videoId: VideoId | AnyNumber | Uint8Array, rationale: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
-      updateChannel: AugmentedSubmittable<(owner: ChannelOwner | { Member: any } | { Curators: any } | { Dao: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: ChannelUpdateParameters | { assets?: any; new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
+      updateChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: ChannelUpdateParameters | { assets?: any; new_meta?: any; reward_account?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       updateChannelCategory: AugmentedSubmittable<(curator: CuratorId | AnyNumber | Uint8Array, category: ChannelCategoryId | AnyNumber | Uint8Array, params: ChannelCategoryUpdateParameters | { new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       updatePerson: AugmentedSubmittable<(actor: PersonActor | { Member: any } | { Curator: any } | string | Uint8Array, person: PersonId | AnyNumber | Uint8Array, params: PersonUpdateParameters | { assets?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       updatePlaylist: AugmentedSubmittable<(owner: ChannelOwner | { Member: any } | { Curators: any } | { Dao: any } | string | Uint8Array, playlist: PlaylistId | AnyNumber | Uint8Array, params: PlaylistUpdateParameters | { new_meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;

+ 3 - 1
types/src/content/index.ts

@@ -51,11 +51,13 @@ export class Channel extends JoyStructDecorated({
 export class ChannelCreationParameters extends JoyStructDecorated({
   assets: Vec.with(NewAsset),
   meta: Bytes,
+  reward_account: Option.with(AccountId),
 }) {}
 
 export class ChannelUpdateParameters extends JoyStructDecorated({
   assets: Option.with(Vec.with(NewAsset)),
-  new_meta: Bytes,
+  new_meta: Option.with(Bytes),
+  reward_account: Option.with(Option.with(AccountId)),
 }) {}
 
 export class ChannelOwnershipTransferRequest extends JoyStructDecorated({

+ 2 - 0
types/src/storage.ts

@@ -102,6 +102,8 @@ export class Quota extends JoyStructDecorated({
 export class QuotaLimit extends u64 {}
 export class UploadingStatus extends bool {}
 
+// Add 'Voucher' ? used as extrinsic parameter..
+
 export const mediaTypes: RegistryTypes = {
   ContentId,
   LiaisonJudgement,