Browse Source

Merge remote-tracking branch 'origin/giza-protobuf-and-query-node' into giza-protobuf-and-query-node

Leszek Wiesner 3 years ago
parent
commit
5be2fd86de

+ 18 - 37
query-node/mappings/content/channel.ts

@@ -2,19 +2,21 @@
 eslint-disable @typescript-eslint/naming-convention
 */
 import { EventContext, StoreContext } from '@joystream/hydra-common'
-import { AccountId } from '@polkadot/types/interfaces'
-import { Option } from '@polkadot/types/codec'
 import { Content } from '../generated/types'
 import { convertContentActorToChannelOwner, processChannelMetadata } from './utils'
-import { AssetNone, Channel, ChannelCategory } from 'query-node/dist/model'
+import { AssetNone, Channel, ChannelCategory, StorageDataObject } from 'query-node/dist/model'
 import { deserializeMetadata, inconsistentState, logger } from '../common'
 import { ChannelCategoryMetadata, ChannelMetadata } from '@joystream/metadata-protobuf'
 import { integrateMeta } from '@joystream/metadata-protobuf/utils'
+import { In } from 'typeorm'
+import { removeDataObject } from '../storage/utils'
 
 export async function content_ChannelCreated(ctx: EventContext & StoreContext): Promise<void> {
   const { store, event } = ctx
   // read event data
-  const [contentActor, channelId, , channelCreationParameters] = new Content.ChannelCreatedEvent(event).params
+  const [contentActor, channelId, runtimeChannel, channelCreationParameters] = new Content.ChannelCreatedEvent(
+    event
+  ).params
 
   // create entity
   const channel = new Channel({
@@ -23,6 +25,8 @@ export async function content_ChannelCreated(ctx: EventContext & StoreContext):
     isCensored: false,
     videos: [],
     createdInBlock: event.blockNumber,
+    rewardAccount: channelCreationParameters.reward_account.unwrapOr(undefined)?.toString(),
+    deletionPrizeDestAccount: runtimeChannel.deletion_prize_source_account_id.toString(),
     // assets
     coverPhoto: new AssetNone(),
     avatarPhoto: new AssetNone(),
@@ -63,7 +67,7 @@ export async function content_ChannelUpdated(ctx: EventContext & StoreContext):
   //  update metadata if it was changed
   if (newMetadataBytes) {
     const newMetadata = deserializeMetadata(ChannelMetadata, newMetadataBytes) || {}
-    await processChannelMetadata(ctx, channel, newMetadata, channelUpdateParameters.assets.unwrapOr([]))
+    await processChannelMetadata(ctx, channel, newMetadata, channelUpdateParameters.assets.unwrapOr(undefined))
   }
 
   // prepare changed reward account
@@ -72,7 +76,7 @@ export async function content_ChannelUpdated(ctx: EventContext & StoreContext):
   // reward account change happened?
   if (newRewardAccount) {
     // this will change the `channel`!
-    handleChannelRewardAccountChange(channel, newRewardAccount)
+    channel.rewardAccount = newRewardAccount.unwrapOr(undefined)?.toString()
   }
 
   // set last update time
@@ -86,18 +90,14 @@ export async function content_ChannelUpdated(ctx: EventContext & StoreContext):
 }
 
 export async function content_ChannelAssetsRemoved({ store, event }: EventContext & StoreContext): Promise<void> {
-  // TODO: Storage v2 integration
-  // // read event data
-  // const [, , contentIds] = new Content.ChannelAssetsRemovedEvent(event).params
-  // const assets = await store.getMany(StorageDataObject, {
-  //   where: {
-  //     id: In(contentIds.toArray().map((item) => item.toString())),
-  //   },
-  // })
-  // // delete assets
-  // await Promise.all(assets.map((a) => store.remove<StorageDataObject>(a)))
-  // // emit log event
-  // logger.info('Channel assets have been removed', { ids: contentIds })
+  const [, , dataObjectIds] = new Content.ChannelAssetsRemovedEvent(event).params
+  const assets = await store.getMany(StorageDataObject, {
+    where: {
+      id: In(Array.from(dataObjectIds).map((item) => item.toString())),
+    },
+  })
+  await Promise.all(assets.map((a) => removeDataObject(store, a)))
+  logger.info('Channel assets have been removed', { ids: dataObjectIds.toJSON() })
 }
 
 export async function content_ChannelCensorshipStatusUpdated({
@@ -209,22 +209,3 @@ export async function content_ChannelCategoryDeleted({ store, event }: EventCont
   // emit log event
   logger.info('Channel category has been deleted', { id: channelCategory.id })
 }
-
-/// //////////////// Helpers ////////////////////////////////////////////////////
-
-function handleChannelRewardAccountChange(
-  channel: Channel, // will be modified inside of the function!
-  reward_account: Option<AccountId>
-) {
-  const rewardAccount = reward_account.unwrapOr(null)
-
-  // new different reward account set?
-  if (rewardAccount) {
-    channel.rewardAccount = rewardAccount.toString()
-    return
-  }
-
-  // reward account removed
-
-  channel.rewardAccount = undefined // plan deletion (will have effect when saved to db)
-}

+ 153 - 98
query-node/mappings/content/utils.ts

@@ -1,5 +1,5 @@
 import { DatabaseManager, EventContext, StoreContext } from '@joystream/hydra-common'
-import { FindConditions } from 'typeorm'
+import { FindConditions, Raw } from 'typeorm'
 import {
   IVideoMetadata,
   IPublishedBeforeJoystream,
@@ -8,7 +8,7 @@ import {
   IChannelMetadata,
 } from '@joystream/metadata-protobuf'
 import { integrateMeta, isSet, isValidLanguageCode } from '@joystream/metadata-protobuf/utils'
-import { invalidMetadata, inconsistentState, logger } from '../common'
+import { invalidMetadata, inconsistentState, unexpectedData, logger } from '../common'
 import {
   // primary entities
   CuratorGroup,
@@ -25,23 +25,25 @@ import {
   VideoMediaEncoding,
   ChannelCategory,
   AssetNone,
+  AssetExternal,
+  AssetJoystreamStorage,
+  StorageDataObject,
 } from 'query-node/dist/model'
 // Joystream types
-import { NewAsset, ContentActor } from '@joystream/types/augment'
+import { NewAssets, ContentActor } from '@joystream/types/augment'
 import { DecodedMetadataObject } from '@joystream/metadata-protobuf/types'
 import BN from 'bn.js'
+import { getMostRecentlyCreatedDataObjects } from '../storage/utils'
+import { DataObjectCreationParameters as ObjectCreationParams } from '@joystream/types/storage'
+import { registry } from '@joystream/types'
 
 export async function processChannelMetadata(
   ctx: EventContext & StoreContext,
   channel: Channel,
   meta: DecodedMetadataObject<IChannelMetadata>,
-  assets: NewAsset[]
+  assets?: NewAssets
 ): Promise<Channel> {
-  // TODO: Assets processing (Storage v2)
-  // const assetsOwner = new DataObjectOwnerChannel()
-  // assetsOwner.channelId = channel.id
-
-  // const processedAssets = await Promise.all(assets.map((asset) => processNewAsset(ctx, asset, assetsOwner)))
+  const processedAssets = assets ? await processNewAssets(ctx, assets) : []
 
   integrateMeta(channel, meta, ['title', 'description', 'isPublic'])
 
@@ -52,21 +54,21 @@ export async function processChannelMetadata(
 
   channel.coverPhoto = new AssetNone()
   channel.avatarPhoto = new AssetNone()
-  // // prepare cover photo asset if needed
-  // if (isSet(meta.coverPhoto)) {
-  //   const asset = findAssetByIndex(processedAssets, meta.coverPhoto, 'channel cover photo')
-  //   if (asset) {
-  //     channel.coverPhoto = asset
-  //   }
-  // }
-
-  // // prepare avatar photo asset if needed
-  // if (isSet(meta.avatarPhoto)) {
-  //   const asset = findAssetByIndex(processedAssets, meta.avatarPhoto, 'channel avatar photo')
-  //   if (asset) {
-  //     channel.avatarPhoto = asset
-  //   }
-  // }
+  // prepare cover photo asset if needed
+  if (isSet(meta.coverPhoto)) {
+    const asset = findAssetByIndex(processedAssets, meta.coverPhoto, 'channel cover photo')
+    if (asset) {
+      channel.coverPhoto = asset
+    }
+  }
+
+  // prepare avatar photo asset if needed
+  if (isSet(meta.avatarPhoto)) {
+    const asset = findAssetByIndex(processedAssets, meta.avatarPhoto, 'channel avatar photo')
+    if (asset) {
+      channel.avatarPhoto = asset
+    }
+  }
 
   // prepare language if needed
   if (isSet(meta.language)) {
@@ -78,16 +80,11 @@ export async function processChannelMetadata(
 
 export async function processVideoMetadata(
   ctx: EventContext & StoreContext,
-  channel: Channel,
   video: Video,
   meta: DecodedMetadataObject<IVideoMetadata>,
-  assets: NewAsset[]
+  assets?: NewAssets
 ): Promise<Video> {
-  // TODO: Assets processing (Storage v2)
-  // const assetsOwner = new DataObjectOwnerChannel()
-  // assetsOwner.channelId = channel.id
-
-  // const processedAssets = await Promise.all(assets.map((asset) => processNewAsset(ctx, asset, assetsOwner)))
+  const processedAssets = assets ? await processNewAssets(ctx, assets) : []
 
   integrateMeta(video, meta, ['title', 'description', 'duration', 'hasMarketing', 'isExplicit', 'isPublic'])
 
@@ -99,7 +96,7 @@ export async function processVideoMetadata(
   // prepare media meta information if needed
   if (isSet(meta.mediaType) || isSet(meta.mediaPixelWidth) || isSet(meta.mediaPixelHeight)) {
     // prepare video file size if poosible
-    const videoSize = 0 // TODO: extractVideoSize(assets, meta.video)
+    const videoSize = extractVideoSize(assets, meta.video)
     video.mediaMetadata = await processVideoMediaMetadata(ctx, video.mediaMetadata, meta, videoSize)
   }
 
@@ -110,21 +107,21 @@ export async function processVideoMetadata(
 
   video.thumbnailPhoto = new AssetNone()
   video.media = new AssetNone()
-  // // prepare thumbnail photo asset if needed
-  // if (isSet(meta.thumbnailPhoto)) {
-  //   const asset = findAssetByIndex(processedAssets, meta.thumbnailPhoto, 'thumbnail photo')
-  //   if (asset) {
-  //     video.thumbnailPhoto = asset
-  //   }
-  // }
-
-  // // prepare video asset if needed
-  // if (isSet(meta.video)) {
-  //   const asset = findAssetByIndex(processedAssets, meta.video, 'video')
-  //   if (asset) {
-  //     video.media = asset
-  //   }
-  // }
+  // prepare thumbnail photo asset if needed
+  if (isSet(meta.thumbnailPhoto)) {
+    const asset = findAssetByIndex(processedAssets, meta.thumbnailPhoto, 'thumbnail photo')
+    if (asset) {
+      video.thumbnailPhoto = asset
+    }
+  }
+
+  // prepare video asset if needed
+  if (isSet(meta.video)) {
+    const asset = findAssetByIndex(processedAssets, meta.video, 'video')
+    if (asset) {
+      video.media = asset
+    }
+  }
 
   // prepare language if needed
   if (isSet(meta.language)) {
@@ -279,57 +276,64 @@ function processPublishedBeforeJoystream(
   return new Date(timestamp)
 }
 
-// TODO: Assets processing (Storage v2)
-// async function processNewAsset(
-//   ctx: EventContext & StoreContext,
-//   asset: NewAsset,
-//   owner: typeof DataObjectOwner
-// ): Promise<typeof Asset> {
-//   if (asset.isUrls) {
-//     const urls = asset.asUrls.toArray().map((url) => url.toString())
-//     const resultAsset = new AssetExternal()
-//     resultAsset.urls = JSON.stringify(urls)
-//     return resultAsset
-//   } else if (asset.isUpload) {
-//     const contentParameters: ContentParameters = asset.asUpload
-//     const dataObject = await createDataObject(ctx, contentParameters, owner)
-
-//     const resultAsset = new AssetJoystreamStorage()
-//     resultAsset.dataObjectId = dataObject.id
-//     return resultAsset
-//   } else {
-//     unexpectedData('Unrecognized asset type', asset.type)
-//   }
-// }
-
-// function extractVideoSize(assets: NewAsset[], assetIndex: number | null | undefined): number | undefined {
-//   // escape if no asset is required
-//   if (!isSet(assetIndex)) {
-//     return undefined
-//   }
-
-//   // ensure asset index is valid
-//   if (assetIndex > assets.length) {
-//     invalidMetadata(`Non-existing asset video size extraction requested`, { assetsProvided: assets.length, assetIndex })
-//     return undefined
-//   }
-
-//   const rawAsset = assets[assetIndex]
-
-//   // escape if asset is describing URLs (can't get size)
-//   if (rawAsset.isUrls) {
-//     return undefined
-//   }
-
-//   // !rawAsset.isUrls && rawAsset.isUpload // asset is in storage
-
-//   // convert generic content parameters coming from processor to custom Joystream data type
-//   const customContentParameters = new Custom_ContentParameters(registry, rawAsset.asUpload.toJSON() as any)
-//   // extract video size
-//   const videoSize = customContentParameters.size_in_bytes.toNumber()
-
-//   return videoSize
-// }
+async function processNewAssets(ctx: EventContext & StoreContext, assets: NewAssets): Promise<Array<typeof Asset>> {
+  if (assets.isUrls) {
+    return assets.asUrls.map((assetUrls) => {
+      const resultAsset = new AssetExternal()
+      resultAsset.urls = JSON.stringify(assetUrls.map((u) => u.toString()))
+      return resultAsset
+    })
+  } else if (assets.isUpload) {
+    const assetsUploaded = assets.asUpload.object_creation_list.length
+    // FIXME: Ideally the runtime would provide object ids in ChannelCreated/VideoCreated/ChannelUpdated(...) events
+    const objects = await getMostRecentlyCreatedDataObjects(ctx.store, assetsUploaded)
+    return objects.map((o) => {
+      const resultAsset = new AssetJoystreamStorage()
+      resultAsset.dataObjectId = o.id
+      return resultAsset
+    })
+  } else {
+    unexpectedData('Unrecognized assets type', assets.type)
+  }
+}
+
+function extractVideoSize(assets: NewAssets | undefined, assetIndex: number | null | undefined): number | undefined {
+  // escape if no assetIndex is set
+  if (!isSet(assetIndex)) {
+    return undefined
+  }
+
+  // index provided, but there are no assets
+  if (!assets) {
+    invalidMetadata(`Non-existing asset video size extraction requested - no assets were uploaded!`, {
+      assetIndex,
+    })
+    return undefined
+  }
+
+  // cannot extract size from other asset types than "Upload"
+  if (!assets.isUpload) {
+    return undefined
+  }
+
+  const dataObjectsParams = assets.asUpload.object_creation_list
+
+  // ensure asset index is valid
+  if (assetIndex >= dataObjectsParams.length) {
+    invalidMetadata(`Non-existing asset video size extraction requested`, {
+      assetsProvided: dataObjectsParams.length,
+      assetIndex,
+    })
+    return undefined
+  }
+
+  // extract video size from objectParams
+  const objectParams = assets.asUpload.object_creation_list[assetIndex]
+  const params = new ObjectCreationParams(registry, objectParams.toJSON() as any)
+  const videoSize = params.getField('size').toNumber()
+
+  return videoSize
+}
 
 async function processLanguage(
   ctx: EventContext & StoreContext,
@@ -464,3 +468,54 @@ async function processChannelCategory(
 
   return category
 }
+
+// Needs to be done every time before data object is removed!
+export async function unsetAssetRelations(store: DatabaseManager, dataObject: StorageDataObject): Promise<void> {
+  const channelAssets = ['avatarPhoto', 'coverPhoto'] as const
+  const videoAssets = ['thumbnailPhoto', 'media'] as const
+
+  // NOTE: we don't need to retrieve multiple channels/videos via `store.getMany()` because dataObject
+  // is allowed to be associated only with one channel/video in runtime
+  const channel = await store.get(Channel, {
+    where: channelAssets.map((assetName) => ({
+      [assetName]: Raw((alias) => `${alias}::json->'dataObjectId' = :id`, {
+        id: dataObject.id,
+      }),
+    })),
+  })
+  const video = await store.get(Video, {
+    where: videoAssets.map((assetName) => ({
+      [assetName]: Raw((alias) => `${alias}::json->'dataObjectId' = :id`, {
+        id: dataObject.id,
+      }),
+    })),
+  })
+
+  if (channel) {
+    channelAssets.forEach((assetName) => {
+      if (channel[assetName] && (channel[assetName] as AssetJoystreamStorage).dataObjectId === dataObject.id) {
+        channel[assetName] = new AssetNone()
+      }
+    })
+    await store.save<Channel>(channel)
+
+    // emit log event
+    logger.info('Content has been disconnected from Channel', {
+      channelId: channel.id.toString(),
+      dataObjectId: dataObject.id,
+    })
+  } else if (video) {
+    videoAssets.forEach((assetName) => {
+      if (video[assetName] && (video[assetName] as AssetJoystreamStorage).dataObjectId === dataObject.id) {
+        video[assetName] = new AssetNone()
+      }
+    })
+    await store.save<Video>(video)
+
+    // emit log event
+    logger.info('Content has been disconnected from Video', {
+      videoId: video.id.toString(),
+      dataObjectId: dataObject.id,
+    })
+  }
+}

+ 2 - 2
query-node/mappings/content/video.ts

@@ -114,7 +114,7 @@ export async function content_VideoCreated(ctx: EventContext & StoreContext): Pr
   })
   // deserialize & process metadata
   const metadata = deserializeMetadata(VideoMetadata, videoCreationParameters.meta) || {}
-  await processVideoMetadata(ctx, channel, video, metadata, videoCreationParameters.assets)
+  await processVideoMetadata(ctx, video, metadata, videoCreationParameters.assets)
 
   // save video
   await store.save<Video>(video)
@@ -145,7 +145,7 @@ export async function content_VideoUpdated(ctx: EventContext & StoreContext): Pr
   // update metadata if it was changed
   if (newMetadataBytes) {
     const newMetadata = deserializeMetadata(VideoMetadata, newMetadataBytes) || {}
-    await processVideoMetadata(ctx, video.channel, video, newMetadata, videoUpdateParameters.assets.unwrapOr([]))
+    await processVideoMetadata(ctx, video, newMetadata, videoUpdateParameters.assets.unwrapOr(undefined))
   }
 
   // set last update time

+ 2 - 1
query-node/mappings/genesis-data/storageSystem.json

@@ -6,5 +6,6 @@
   "uploadingBlocked": false,
   "dataObjectFeePerMb": 0,
   "storageBucketMaxObjectsCountLimit": 0,
-  "storageBucketMaxObjectsSizeLimit": 0
+  "storageBucketMaxObjectsSizeLimit": 0,
+  "nextDataObjectId": 0
 }

+ 4 - 24
query-node/mappings/storage/index.ts

@@ -27,10 +27,8 @@ import {
   StorageBagStorageAssignment,
 } from 'query-node/dist/model'
 import BN from 'bn.js'
-import { getById, bytesToString } from '../common'
+import { getById } from '../common'
 import { BTreeSet } from '@polkadot/types'
-import { DataObjectCreationParameters } from '@joystream/types/storage'
-import { registry } from '@joystream/types'
 import { In } from 'typeorm'
 import _ from 'lodash'
 import { DataObjectId, BagId, DynamicBagId, StaticBagId } from '@joystream/types/augment/all'
@@ -39,6 +37,7 @@ import {
   processDistributionOperatorMetadata,
   processStorageOperatorMetadata,
 } from './metadata'
+import { createDataObjects, getStorageSystem, removeDataObject } from './utils'
 
 async function getDataObjectsInBag(
   store: DatabaseManager,
@@ -180,15 +179,6 @@ async function getDistributionBucketFamilyWithMetadata(
   return family
 }
 
-async function getStorageSystem(store: DatabaseManager) {
-  const storageSystem = await store.get(StorageSystemParameters, {})
-  if (!storageSystem) {
-    throw new Error('Storage system entity is missing!')
-  }
-
-  return storageSystem
-}
-
 // STORAGE BUCKETS
 
 export async function storage_StorageBucketCreated({ event, store }: EventContext & StoreContext): Promise<void> {
@@ -366,17 +356,7 @@ export async function storage_DataObjectsUploaded({ event, store }: EventContext
   const [dataObjectIds, uploadParams] = new Storage.DataObjectsUploadedEvent(event).params
   const { bagId, objectCreationList } = uploadParams
   const storageBag = await getBag(store, bagId)
-  const dataObjects = dataObjectIds.map((objectId, i) => {
-    const objectParams = new DataObjectCreationParameters(registry, objectCreationList[i].toJSON() as any)
-    return new StorageDataObject({
-      id: objectId.toString(),
-      isAccepted: false,
-      ipfsHash: bytesToString(objectParams.ipfsContentId),
-      size: new BN(objectParams.getField('size').toString()),
-      storageBag,
-    })
-  })
-  await Promise.all(dataObjects.map((o) => store.save<StorageDataObject>(o)))
+  await createDataObjects(store, objectCreationList, storageBag, dataObjectIds)
 }
 
 export async function storage_PendingDataObjectsAccepted({ event, store }: EventContext & StoreContext): Promise<void> {
@@ -405,7 +385,7 @@ export async function storage_DataObjectsMoved({ event, store }: EventContext &
 export async function storage_DataObjectsDeleted({ event, store }: EventContext & StoreContext): Promise<void> {
   const [, bagId, dataObjectIds] = new Storage.DataObjectsDeletedEvent(event).params
   const dataObjects = await getDataObjectsInBag(store, bagId, dataObjectIds)
-  await Promise.all(dataObjects.map((o) => store.remove<StorageDataObject>(o)))
+  await Promise.all(dataObjects.map((o) => removeDataObject(store, o)))
 }
 
 // DISTRIBUTION FAMILY

+ 71 - 0
query-node/mappings/storage/utils.ts

@@ -0,0 +1,71 @@
+import { DatabaseManager } from '@joystream/hydra-common'
+import { DataObjectCreationParameters } from '@joystream/types/augment'
+import { registry } from '@joystream/types'
+import { DataObjectCreationParameters as ObjectCreationParams } from '@joystream/types/storage'
+import { StorageBag, StorageDataObject, StorageSystemParameters } from 'query-node/dist/model'
+import BN from 'bn.js'
+import { bytesToString, inconsistentState } from '../common'
+import { In } from 'typeorm'
+import { unsetAssetRelations } from '../content/utils'
+
+export async function getStorageSystem(store: DatabaseManager): Promise<StorageSystemParameters> {
+  const storageSystem = await store.get(StorageSystemParameters, {})
+  if (!storageSystem) {
+    throw new Error('Storage system entity is missing!')
+  }
+
+  return storageSystem
+}
+
+export async function createDataObjects(
+  store: DatabaseManager,
+  objectsParams: DataObjectCreationParameters[],
+  storageBag: StorageBag,
+  objectIds?: BN[]
+): Promise<StorageDataObject[]> {
+  const storageSystem = await getStorageSystem(store)
+
+  const dataObjects = objectsParams.map((objectParams, i) => {
+    const params = new ObjectCreationParams(registry, objectParams.toJSON() as any)
+    const objectId = objectIds ? objectIds[i] : storageSystem.nextDataObjectId
+    const object = new StorageDataObject({
+      id: objectId.toString(),
+      isAccepted: false,
+      ipfsHash: bytesToString(objectParams.ipfsContentId),
+      size: new BN(params.getField('size').toString()),
+      storageBag,
+    })
+    if (objectId.gte(storageSystem.nextDataObjectId)) {
+      storageSystem.nextDataObjectId = objectId.addn(1)
+    }
+    return object
+  })
+
+  await Promise.all(dataObjects.map((o) => store.save<StorageDataObject>(o)))
+  await store.save<StorageSystemParameters>(storageSystem)
+
+  return dataObjects
+}
+
+export async function getMostRecentlyCreatedDataObjects(
+  store: DatabaseManager,
+  numberOfObjects: number
+): Promise<StorageDataObject[]> {
+  const storageSystem = await getStorageSystem(store)
+  const objectIds = Array.from({ length: numberOfObjects }, (v, k) =>
+    storageSystem.nextDataObjectId.subn(k + 1).toString()
+  )
+  const objects = await store.getMany(StorageDataObject, { where: { id: In(objectIds) } })
+  if (objects.length < numberOfObjects) {
+    inconsistentState(`Could not get ${numberOfObjects} most recently created data objects`, {
+      expected: numberOfObjects,
+      got: objects.length,
+    })
+  }
+  return objects.sort((a, b) => new BN(a.id).cmp(new BN(b.id)))
+}
+
+export async function removeDataObject(store: DatabaseManager, object: StorageDataObject): Promise<void> {
+  await unsetAssetRelations(store, object)
+  await store.save<StorageDataObject>(object)
+}

+ 10 - 4
query-node/schemas/content.graphql

@@ -53,17 +53,21 @@ type Channel @entity {
   "Reward account where revenue is sent if set."
   rewardAccount: String
 
+  "Destination account for the prize associated with channel deletion"
+  deletionPrizeDestAccount: String!
+
   "The title of the Channel"
   title: String @fulltext(query: "search")
 
   "The description of a Channel"
   description: String
 
+  # FIXME: Due to https://github.com/Joystream/hydra/issues/434, Asset is currently non-optional (use AssetNone to unset it)
   "Channel's cover (background) photo asset. Recommended ratio: 16:9."
-  coverPhoto: Asset
+  coverPhoto: Asset!
 
   "Channel's avatar photo asset."
-  avatarPhoto: Asset
+  avatarPhoto: Asset!
 
   ##########################
 
@@ -125,8 +129,9 @@ type Video @entity {
   "Video duration in seconds"
   duration: Int
 
+# FIXME: Due to https://github.com/Joystream/hydra/issues/434, Asset is currently non-optional (use AssetNone to unset it)
   "Video thumbnail asset (recommended ratio: 16:9)"
-  thumbnailPhoto: Asset
+  thumbnailPhoto: Asset!
 
   ##########################
 
@@ -151,8 +156,9 @@ type Video @entity {
   "License under the video is published"
   license: License
 
+  # FIXME: Due to https://github.com/Joystream/hydra/issues/434, Asset is currently non-optional (use AssetNone to unset it)
   "Video media asset"
-  media: Asset
+  media: Asset!
 
   ##########################
 

+ 3 - 0
query-node/schemas/storage.graphql

@@ -20,6 +20,9 @@ type StorageSystemParameters @entity {
 
   "Global max. size of objects a storage bucket can store (can also be further limitted the provider)"
   storageBucketMaxObjectsSizeLimit: BigInt!
+
+  "ID of the next data object when created"
+  nextDataObjectId: BigInt!
 }
 
 type StorageBucketOperatorStatusMissing @variant {

File diff suppressed because it is too large
+ 1 - 1
types/augment-codec/all.ts


+ 16 - 0
types/augment-codec/augment-api-errors.ts

@@ -90,6 +90,14 @@ declare module '@polkadot/api/types/errors' {
        * A Channel or Video Category does not exist.
        **/
       CategoryDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Channel Contains Assets
+       **/
+      ChannelContainsAssets: AugmentedError<ApiType>;
+      /**
+       * Channel Contains Video
+       **/
+      ChannelContainsVideos: AugmentedError<ApiType>;
       /**
        * Channel does not exist
        **/
@@ -126,6 +134,10 @@ declare module '@polkadot/api/types/errors' {
        * Feature Not Implemented
        **/
       FeatureNotImplemented: AugmentedError<ApiType>;
+      /**
+       * Channel assets feasibility
+       **/
+      InvalidAssetsProvided: AugmentedError<ApiType>;
       /**
        * Lead authentication failed
        **/
@@ -134,6 +146,10 @@ declare module '@polkadot/api/types/errors' {
        * Member authentication failed
        **/
       MemberAuthFailed: AugmentedError<ApiType>;
+      /**
+       * No assets to be removed have been specified
+       **/
+      NoAssetsSpecified: AugmentedError<ApiType>;
       /**
        * Video does not exist
        **/

+ 7 - 6
types/augment-codec/augment-api-events.ts

@@ -2,7 +2,7 @@
 /* eslint-disable */
 
 import type { BTreeMap, BTreeSet, Bytes, Option, Vec, bool, u32, u64 } from '@polkadot/types';
-import type { ApplicationId, ApplicationIdToWorkerIdMap, BagId, CategoryId, Channel, ChannelCategory, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, ContentId, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrizeRecord, DynamicBagId, DynamicBagType, EntryMethod, IsCensored, MemberId, MintBalanceOf, MintId, NewAsset, OpeningId, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, ProposalStatus, RationaleText, Series, SeriesId, SeriesParameters, StorageBucketId, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, Voucher, WorkerId } from './all';
+import type { ApplicationId, ApplicationIdToWorkerIdMap, BagId, CategoryId, Channel, ChannelCategory, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrizeRecord, DynamicBagId, DynamicBagType, EntryMethod, IsCensored, MemberId, MintBalanceOf, MintId, NewAssets, OpeningId, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, ProposalStatus, RationaleText, Series, SeriesId, SeriesParameters, StorageBucketId, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, Voucher, WorkerId } from './all';
 import type { BalanceStatus } from '@polkadot/types/interfaces/balances';
 import type { AuthorityId } from '@polkadot/types/interfaces/consensus';
 import type { AuthorityList } from '@polkadot/types/interfaces/grandpa';
@@ -53,12 +53,13 @@ declare module '@polkadot/api/types/events' {
       Unreserved: AugmentedEvent<ApiType, [AccountId, Balance]>;
     };
     content: {
-      ChannelAssetsRemoved: AugmentedEvent<ApiType, [ContentActor, ChannelId, Vec<ContentId>]>;
+      ChannelAssetsRemoved: AugmentedEvent<ApiType, [ContentActor, ChannelId, BTreeSet<DataObjectId>, Channel]>;
       ChannelCategoryCreated: AugmentedEvent<ApiType, [ChannelCategoryId, ChannelCategory, ChannelCategoryCreationParameters]>;
       ChannelCategoryDeleted: AugmentedEvent<ApiType, [ContentActor, ChannelCategoryId]>;
       ChannelCategoryUpdated: AugmentedEvent<ApiType, [ContentActor, ChannelCategoryId, ChannelCategoryUpdateParameters]>;
       ChannelCensorshipStatusUpdated: AugmentedEvent<ApiType, [ContentActor, ChannelId, IsCensored, Bytes]>;
       ChannelCreated: AugmentedEvent<ApiType, [ContentActor, ChannelId, Channel, ChannelCreationParameters]>;
+      ChannelDeleted: AugmentedEvent<ApiType, [ContentActor, ChannelId]>;
       ChannelOwnershipTransferred: AugmentedEvent<ApiType, [ContentActor, ChannelOwnershipTransferRequestId]>;
       ChannelOwnershipTransferRequested: AugmentedEvent<ApiType, [ContentActor, ChannelOwnershipTransferRequestId, ChannelOwnershipTransferRequest]>;
       ChannelOwnershipTransferRequestWithdrawn: AugmentedEvent<ApiType, [ContentActor, ChannelOwnershipTransferRequestId]>;
@@ -68,15 +69,15 @@ declare module '@polkadot/api/types/events' {
       CuratorGroupStatusSet: AugmentedEvent<ApiType, [CuratorGroupId, bool]>;
       CuratorRemoved: AugmentedEvent<ApiType, [CuratorGroupId, CuratorId]>;
       FeaturedVideosSet: AugmentedEvent<ApiType, [ContentActor, Vec<VideoId>]>;
-      PersonCreated: AugmentedEvent<ApiType, [ContentActor, PersonId, Vec<NewAsset>, PersonCreationParameters]>;
+      PersonCreated: AugmentedEvent<ApiType, [ContentActor, PersonId, NewAssets, PersonCreationParameters]>;
       PersonDeleted: AugmentedEvent<ApiType, [ContentActor, PersonId]>;
-      PersonUpdated: AugmentedEvent<ApiType, [ContentActor, PersonId, Vec<NewAsset>, PersonUpdateParameters]>;
+      PersonUpdated: AugmentedEvent<ApiType, [ContentActor, PersonId, NewAssets, PersonUpdateParameters]>;
       PlaylistCreated: AugmentedEvent<ApiType, [ContentActor, PlaylistId, PlaylistCreationParameters]>;
       PlaylistDeleted: AugmentedEvent<ApiType, [ContentActor, PlaylistId]>;
       PlaylistUpdated: AugmentedEvent<ApiType, [ContentActor, PlaylistId, PlaylistUpdateParameters]>;
-      SeriesCreated: AugmentedEvent<ApiType, [ContentActor, SeriesId, Vec<NewAsset>, SeriesParameters, Series]>;
+      SeriesCreated: AugmentedEvent<ApiType, [ContentActor, SeriesId, NewAssets, SeriesParameters, Series]>;
       SeriesDeleted: AugmentedEvent<ApiType, [ContentActor, SeriesId]>;
-      SeriesUpdated: AugmentedEvent<ApiType, [ContentActor, SeriesId, Vec<NewAsset>, SeriesParameters, Series]>;
+      SeriesUpdated: AugmentedEvent<ApiType, [ContentActor, SeriesId, NewAssets, SeriesParameters, Series]>;
       VideoCategoryCreated: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId, VideoCategoryCreationParameters]>;
       VideoCategoryDeleted: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId]>;
       VideoCategoryUpdated: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId, VideoCategoryUpdateParameters]>;

+ 1 - 1
types/augment-codec/augment-api-query.ts

@@ -1137,7 +1137,7 @@ declare module '@polkadot/api/types/storage' {
        **/
       uploadingBlocked: AugmentedQuery<ApiType, () => Observable<bool>, []>;
       /**
-       * "Max objects number for a storage bucket voucher" number limit.
+       * "Max objects number for a storage  bucket voucher" number limit.
        **/
       voucherMaxObjectsNumberLimit: AugmentedQuery<ApiType, () => Observable<u64>, []>;
       /**

+ 8 - 7
types/augment-codec/augment-api-tx.ts

@@ -3,7 +3,7 @@
 
 import type { BTreeMap, BTreeSet, Bytes, Compact, Option, Vec, bool, u16, u32, u64 } from '@polkadot/types';
 import type { AnyNumber } from '@polkadot/types/types';
-import type { ActivateOpeningAt, AddOpeningParameters, ApplicationId, ApplicationIdSet, BagId, BalanceOfMint, CategoryId, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, ContentId, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrize, DynamicBagId, DynamicBagType, ElectionParameters, FillOpeningParameters, MemberId, MemoText, OpeningId, OpeningPolicyCommitment, OpeningType, PaidTermId, PersonActor, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, RewardPolicy, SeriesId, SeriesParameters, StorageBucketId, TerminateRoleParameters, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, WorkerId, WorkingGroup } from './all';
+import type { ActivateOpeningAt, AddOpeningParameters, ApplicationId, ApplicationIdSet, BagId, BalanceOfMint, CategoryId, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrize, DynamicBagId, DynamicBagType, ElectionParameters, FillOpeningParameters, MemberId, MemoText, OpeningId, OpeningPolicyCommitment, OpeningType, PaidTermId, PersonActor, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, RewardPolicy, SeriesId, SeriesParameters, StorageBucketId, TerminateRoleParameters, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, WorkerId, WorkingGroup } from './all';
 import type { BabeEquivocationProof } from '@polkadot/types/interfaces/babe';
 import type { Extrinsic, Signature } from '@polkadot/types/interfaces/extrinsics';
 import type { GrandpaEquivocationProof, KeyOwnerProof } from '@polkadot/types/interfaces/grandpa';
@@ -137,6 +137,7 @@ declare module '@polkadot/api/types/submittable' {
       createSeries: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: SeriesParameters | { assets?: any; seasons?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, SeriesParameters]>;
       createVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: VideoCreationParameters | { assets?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, VideoCreationParameters]>;
       createVideoCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, params: VideoCategoryCreationParameters | { meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoCategoryCreationParameters]>;
+      deleteChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId]>;
       deleteChannelCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, categoryId: ChannelCategoryId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelCategoryId]>;
       deletePerson: AugmentedSubmittable<(actor: PersonActor | { Member: any } | { Curator: any } | string | Uint8Array, person: PersonId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [PersonActor, PersonId]>;
       deletePlaylist: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, playlist: PlaylistId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, PlaylistId]>;
@@ -146,7 +147,7 @@ declare module '@polkadot/api/types/submittable' {
       /**
        * Remove assets of a channel from storage
        **/
-      removeChannelAssets: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, assets: Vec<ContentId> | (ContentId | AnyNumber | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, Vec<ContentId>]>;
+      removeChannelAssets: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, assets: BTreeSet<DataObjectId>) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, BTreeSet<DataObjectId>]>;
       /**
        * Remove curator from a given curator group
        **/
@@ -677,12 +678,12 @@ declare module '@polkadot/api/types/submittable' {
        * Create 'Begin review working group leader applications' proposal type.
        * This proposal uses `begin_applicant_review()` extrinsic from the Joystream `working group` module.
        **/
-      createBeginReviewWorkingGroupLeaderApplicationsProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, workingGroup: WorkingGroup | 'Storage' | 'Content' | 'Operations' | 'Gateway' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, OpeningId, WorkingGroup]>;
+      createBeginReviewWorkingGroupLeaderApplicationsProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, OpeningId, WorkingGroup]>;
       /**
        * Create 'decrease working group leader stake' proposal type.
        * This proposal uses `decrease_stake()` extrinsic from the `working-group`  module.
        **/
-      createDecreaseWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, decreasingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | 'Storage' | 'Content' | 'Operations' | 'Gateway' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
+      createDecreaseWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, decreasingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
       /**
        * Create 'Fill working group leader opening' proposal type.
        * This proposal uses `fill_opening()` extrinsic from the Joystream `working group` module.
@@ -707,17 +708,17 @@ declare module '@polkadot/api/types/submittable' {
        * Create 'set working group leader reward' proposal type.
        * This proposal uses `update_reward_amount()` extrinsic from the `working-group`  module.
        **/
-      createSetWorkingGroupLeaderRewardProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, rewardAmount: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | 'Storage' | 'Content' | 'Operations' | 'Gateway' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOfMint, WorkingGroup]>;
+      createSetWorkingGroupLeaderRewardProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, rewardAmount: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOfMint, WorkingGroup]>;
       /**
        * Create 'Set working group mint capacity' proposal type.
        * This proposal uses `set_mint_capacity()` extrinsic from the `working-group`  module.
        **/
-      createSetWorkingGroupMintCapacityProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, mintBalance: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | 'Storage' | 'Content' | 'Operations' | 'Gateway' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, BalanceOfMint, WorkingGroup]>;
+      createSetWorkingGroupMintCapacityProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, mintBalance: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, BalanceOfMint, WorkingGroup]>;
       /**
        * Create 'slash working group leader stake' proposal type.
        * This proposal uses `slash_stake()` extrinsic from the `working-group`  module.
        **/
-      createSlashWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, slashingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | 'Storage' | 'Content' | 'Operations' | 'Gateway' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
+      createSlashWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, slashingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
       /**
        * Create 'Spending' proposal type.
        * This proposal uses `spend_from_council_mint()` extrinsic from the `governance::council`  module.

File diff suppressed because it is too large
+ 0 - 0
types/augment-codec/augment-types.ts


+ 28 - 21
types/augment/all/defs.json

@@ -82,10 +82,13 @@
     },
     "WorkingGroup": {
         "_enum": [
+            "_Reserved0",
+            "_Reserved1",
             "Storage",
             "Content",
             "Operations",
-            "Gateway"
+            "Gateway",
+            "Distribution"
         ]
     },
     "SlashingTerms": {
@@ -761,25 +764,29 @@
             "Lead": "Null"
         }
     },
-    "NewAsset": {
+    "CreationUploadParameters": {
+        "object_creation_list": "Vec<DataObjectCreationParameters>",
+        "expected_data_size_fee": "u128"
+    },
+    "AssetUrls": "Vec<Url>",
+    "NewAssets": {
         "_enum": {
-            "Upload": "u64",
-            "Urls": "Vec<Url>"
+            "Upload": "CreationUploadParameters",
+            "Urls": "Vec<AssetUrls>"
         }
     },
     "Channel": {
         "owner": "ChannelOwner",
-        "videos": "Vec<VideoId>",
-        "playlists": "Vec<PlaylistId>",
-        "series": "Vec<SeriesId>",
+        "num_videos": "u64",
         "is_censored": "bool",
-        "reward_account": "Option<GenericAccountId>"
+        "reward_account": "Option<GenericAccountId>",
+        "deletion_prize_source_account_id": "GenericAccountId",
+        "num_assets": "u64"
     },
     "ChannelOwner": {
         "_enum": {
             "Member": "MemberId",
-            "Curators": "CuratorGroupId",
-            "Dao": "DAOId"
+            "Curators": "CuratorGroupId"
         }
     },
     "ChannelCategoryId": "u64",
@@ -791,12 +798,12 @@
         "new_meta": "Bytes"
     },
     "ChannelCreationParameters": {
-        "assets": "Vec<NewAsset>",
+        "assets": "NewAssets",
         "meta": "Bytes",
         "reward_account": "Option<GenericAccountId>"
     },
     "ChannelUpdateParameters": {
-        "assets": "Option<Vec<NewAsset>>",
+        "assets": "Option<NewAssets>",
         "new_meta": "Option<Bytes>",
         "reward_account": "Option<Option<GenericAccountId>>"
     },
@@ -810,7 +817,8 @@
     "Video": {
         "in_channel": "ChannelId",
         "in_series": "Option<SeriesId>",
-        "is_censored": "bool"
+        "is_censored": "bool",
+        "maybe_data_objects_id_set": "Option<Vec<DataObjectId>>"
     },
     "VideoId": "u64",
     "VideoCategoryId": "u64",
@@ -822,11 +830,11 @@
         "new_meta": "Bytes"
     },
     "VideoCreationParameters": {
-        "assets": "Vec<NewAsset>",
+        "assets": "NewAssets",
         "meta": "Bytes"
     },
     "VideoUpdateParameters": {
-        "assets": "Option<Vec<NewAsset>>",
+        "assets": "Option<NewAssets>",
         "new_meta": "Option<Bytes>"
     },
     "Person": {
@@ -846,11 +854,11 @@
         }
     },
     "PersonCreationParameters": {
-        "assets": "Vec<NewAsset>",
+        "assets": "NewAssets",
         "meta": "Bytes"
     },
     "PersonUpdateParameters": {
-        "assets": "Option<Vec<NewAsset>>",
+        "assets": "Option<NewAssets>",
         "meta": "Option<Bytes>"
     },
     "Playlist": {
@@ -872,12 +880,12 @@
         "episodes": "Vec<VideoId>"
     },
     "SeriesParameters": {
-        "assets": "Option<Vec<NewAsset>>",
+        "assets": "Option<NewAssets>",
         "seasons": "Option<Vec<Option<SeasonParameters>>>",
         "meta": "Option<Bytes>"
     },
     "SeasonParameters": {
-        "assets": "Option<Vec<NewAsset>>",
+        "assets": "Option<NewAssets>",
         "episodes": "Option<Vec<Option<EpisodeParemters>>>",
         "meta": "Option<Bytes>"
     },
@@ -888,6 +896,5 @@
         }
     },
     "MaxNumber": "u32",
-    "IsCensored": "bool",
-    "ContentId": "u64"
+    "IsCensored": "bool"
 }

+ 28 - 20
types/augment/all/types.ts

@@ -139,6 +139,9 @@ export interface Approved extends Enum {
   readonly asExecutionFailed: ExecutionFailed;
 }
 
+/** @name AssetUrls */
+export interface AssetUrls extends Vec<Url> {}
+
 /** @name Backer */
 export interface Backer extends Struct {
   readonly member: GenericAccountId;
@@ -202,11 +205,11 @@ export interface CategoryId extends u64 {}
 /** @name Channel */
 export interface Channel extends Struct {
   readonly owner: ChannelOwner;
-  readonly videos: Vec<VideoId>;
-  readonly playlists: Vec<PlaylistId>;
-  readonly series: Vec<SeriesId>;
+  readonly num_videos: u64;
   readonly is_censored: bool;
   readonly reward_account: Option<GenericAccountId>;
+  readonly deletion_prize_source_account_id: GenericAccountId;
+  readonly num_assets: u64;
 }
 
 /** @name ChannelCategory */
@@ -230,7 +233,7 @@ export interface ChannelContentType extends Null {}
 
 /** @name ChannelCreationParameters */
 export interface ChannelCreationParameters extends Struct {
-  readonly assets: Vec<NewAsset>;
+  readonly assets: NewAssets;
   readonly meta: Bytes;
   readonly reward_account: Option<GenericAccountId>;
 }
@@ -247,8 +250,6 @@ export interface ChannelOwner extends Enum {
   readonly asMember: MemberId;
   readonly isCurators: boolean;
   readonly asCurators: CuratorGroupId;
-  readonly isDao: boolean;
-  readonly asDao: DAOId;
 }
 
 /** @name ChannelOwnershipTransferRequest */
@@ -267,7 +268,7 @@ export interface ChannelPublicationStatus extends Null {}
 
 /** @name ChannelUpdateParameters */
 export interface ChannelUpdateParameters extends Struct {
-  readonly assets: Option<Vec<NewAsset>>;
+  readonly assets: Option<NewAssets>;
   readonly new_meta: Option<Bytes>;
   readonly reward_account: Option<Option<GenericAccountId>>;
 }
@@ -308,15 +309,18 @@ export interface ContentActor extends Enum {
   readonly isLead: boolean;
 }
 
-/** @name ContentId */
-export interface ContentId extends u64 {}
-
 /** @name ContentIdSet */
 export interface ContentIdSet extends BTreeSet<Cid> {}
 
 /** @name CreateEntityOperation */
 export interface CreateEntityOperation extends Null {}
 
+/** @name CreationUploadParameters */
+export interface CreationUploadParameters extends Struct {
+  readonly object_creation_list: Vec<DataObjectCreationParameters>;
+  readonly expected_data_size_fee: u128;
+}
+
 /** @name Credential */
 export interface Credential extends Null {}
 
@@ -654,12 +658,12 @@ export interface ModerationAction extends Struct {
   readonly rationale: Text;
 }
 
-/** @name NewAsset */
-export interface NewAsset extends Enum {
+/** @name NewAssets */
+export interface NewAssets extends Enum {
   readonly isUpload: boolean;
-  readonly asUpload: u64;
+  readonly asUpload: CreationUploadParameters;
   readonly isUrls: boolean;
-  readonly asUrls: Vec<Url>;
+  readonly asUrls: Vec<AssetUrls>;
 }
 
 /** @name NextAdjustment */
@@ -781,7 +785,7 @@ export interface PersonController extends Enum {
 
 /** @name PersonCreationParameters */
 export interface PersonCreationParameters extends Struct {
-  readonly assets: Vec<NewAsset>;
+  readonly assets: NewAssets;
   readonly meta: Bytes;
 }
 
@@ -790,7 +794,7 @@ export interface PersonId extends u64 {}
 
 /** @name PersonUpdateParameters */
 export interface PersonUpdateParameters extends Struct {
-  readonly assets: Option<Vec<NewAsset>>;
+  readonly assets: Option<NewAssets>;
   readonly meta: Option<Bytes>;
 }
 
@@ -1079,7 +1083,7 @@ export interface Season extends Struct {
 
 /** @name SeasonParameters */
 export interface SeasonParameters extends Struct {
-  readonly assets: Option<Vec<NewAsset>>;
+  readonly assets: Option<NewAssets>;
   readonly episodes: Option<Vec<Option<EpisodeParemters>>>;
   readonly meta: Option<Bytes>;
 }
@@ -1105,7 +1109,7 @@ export interface SeriesId extends u64 {}
 
 /** @name SeriesParameters */
 export interface SeriesParameters extends Struct {
-  readonly assets: Option<Vec<NewAsset>>;
+  readonly assets: Option<NewAssets>;
   readonly seasons: Option<Vec<Option<SeasonParameters>>>;
   readonly meta: Option<Bytes>;
 }
@@ -1329,6 +1333,7 @@ export interface Video extends Struct {
   readonly in_channel: ChannelId;
   readonly in_series: Option<SeriesId>;
   readonly is_censored: bool;
+  readonly maybe_data_objects_id_set: Option<Vec<DataObjectId>>;
 }
 
 /** @name VideoCategory */
@@ -1349,7 +1354,7 @@ export interface VideoCategoryUpdateParameters extends Struct {
 
 /** @name VideoCreationParameters */
 export interface VideoCreationParameters extends Struct {
-  readonly assets: Vec<NewAsset>;
+  readonly assets: NewAssets;
   readonly meta: Bytes;
 }
 
@@ -1358,7 +1363,7 @@ export interface VideoId extends u64 {}
 
 /** @name VideoUpdateParameters */
 export interface VideoUpdateParameters extends Struct {
-  readonly assets: Option<Vec<NewAsset>>;
+  readonly assets: Option<NewAssets>;
   readonly new_meta: Option<Bytes>;
 }
 
@@ -1404,10 +1409,13 @@ export interface WorkerOf extends Struct {
 
 /** @name WorkingGroup */
 export interface WorkingGroup extends Enum {
+  readonly isReserved0: boolean;
+  readonly isReserved1: boolean;
   readonly isStorage: boolean;
   readonly isContent: boolean;
   readonly isOperations: boolean;
   readonly isGateway: boolean;
+  readonly isDistribution: boolean;
 }
 
 /** @name WorkingGroupUnstaker */

+ 16 - 0
types/augment/augment-api-errors.ts

@@ -90,6 +90,14 @@ declare module '@polkadot/api/types/errors' {
        * A Channel or Video Category does not exist.
        **/
       CategoryDoesNotExist: AugmentedError<ApiType>;
+      /**
+       * Channel Contains Assets
+       **/
+      ChannelContainsAssets: AugmentedError<ApiType>;
+      /**
+       * Channel Contains Video
+       **/
+      ChannelContainsVideos: AugmentedError<ApiType>;
       /**
        * Channel does not exist
        **/
@@ -126,6 +134,10 @@ declare module '@polkadot/api/types/errors' {
        * Feature Not Implemented
        **/
       FeatureNotImplemented: AugmentedError<ApiType>;
+      /**
+       * Channel assets feasibility
+       **/
+      InvalidAssetsProvided: AugmentedError<ApiType>;
       /**
        * Lead authentication failed
        **/
@@ -134,6 +146,10 @@ declare module '@polkadot/api/types/errors' {
        * Member authentication failed
        **/
       MemberAuthFailed: AugmentedError<ApiType>;
+      /**
+       * No assets to be removed have been specified
+       **/
+      NoAssetsSpecified: AugmentedError<ApiType>;
       /**
        * Video does not exist
        **/

+ 7 - 6
types/augment/augment-api-events.ts

@@ -2,7 +2,7 @@
 /* eslint-disable */
 
 import type { BTreeMap, BTreeSet, Bytes, Option, Vec, bool, u32, u64 } from '@polkadot/types';
-import type { ApplicationId, ApplicationIdToWorkerIdMap, BagId, CategoryId, Channel, ChannelCategory, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, ContentId, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrizeRecord, DynamicBagId, DynamicBagType, EntryMethod, IsCensored, MemberId, MintBalanceOf, MintId, NewAsset, OpeningId, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, ProposalStatus, RationaleText, Series, SeriesId, SeriesParameters, StorageBucketId, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, Voucher, WorkerId } from './all';
+import type { ApplicationId, ApplicationIdToWorkerIdMap, BagId, CategoryId, Channel, ChannelCategory, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrizeRecord, DynamicBagId, DynamicBagType, EntryMethod, IsCensored, MemberId, MintBalanceOf, MintId, NewAssets, OpeningId, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, ProposalStatus, RationaleText, Series, SeriesId, SeriesParameters, StorageBucketId, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, Voucher, WorkerId } from './all';
 import type { BalanceStatus } from '@polkadot/types/interfaces/balances';
 import type { AuthorityId } from '@polkadot/types/interfaces/consensus';
 import type { AuthorityList } from '@polkadot/types/interfaces/grandpa';
@@ -53,12 +53,13 @@ declare module '@polkadot/api/types/events' {
       Unreserved: AugmentedEvent<ApiType, [AccountId, Balance]>;
     };
     content: {
-      ChannelAssetsRemoved: AugmentedEvent<ApiType, [ContentActor, ChannelId, Vec<ContentId>]>;
+      ChannelAssetsRemoved: AugmentedEvent<ApiType, [ContentActor, ChannelId, BTreeSet<DataObjectId>, Channel]>;
       ChannelCategoryCreated: AugmentedEvent<ApiType, [ChannelCategoryId, ChannelCategory, ChannelCategoryCreationParameters]>;
       ChannelCategoryDeleted: AugmentedEvent<ApiType, [ContentActor, ChannelCategoryId]>;
       ChannelCategoryUpdated: AugmentedEvent<ApiType, [ContentActor, ChannelCategoryId, ChannelCategoryUpdateParameters]>;
       ChannelCensorshipStatusUpdated: AugmentedEvent<ApiType, [ContentActor, ChannelId, IsCensored, Bytes]>;
       ChannelCreated: AugmentedEvent<ApiType, [ContentActor, ChannelId, Channel, ChannelCreationParameters]>;
+      ChannelDeleted: AugmentedEvent<ApiType, [ContentActor, ChannelId]>;
       ChannelOwnershipTransferred: AugmentedEvent<ApiType, [ContentActor, ChannelOwnershipTransferRequestId]>;
       ChannelOwnershipTransferRequested: AugmentedEvent<ApiType, [ContentActor, ChannelOwnershipTransferRequestId, ChannelOwnershipTransferRequest]>;
       ChannelOwnershipTransferRequestWithdrawn: AugmentedEvent<ApiType, [ContentActor, ChannelOwnershipTransferRequestId]>;
@@ -68,15 +69,15 @@ declare module '@polkadot/api/types/events' {
       CuratorGroupStatusSet: AugmentedEvent<ApiType, [CuratorGroupId, bool]>;
       CuratorRemoved: AugmentedEvent<ApiType, [CuratorGroupId, CuratorId]>;
       FeaturedVideosSet: AugmentedEvent<ApiType, [ContentActor, Vec<VideoId>]>;
-      PersonCreated: AugmentedEvent<ApiType, [ContentActor, PersonId, Vec<NewAsset>, PersonCreationParameters]>;
+      PersonCreated: AugmentedEvent<ApiType, [ContentActor, PersonId, NewAssets, PersonCreationParameters]>;
       PersonDeleted: AugmentedEvent<ApiType, [ContentActor, PersonId]>;
-      PersonUpdated: AugmentedEvent<ApiType, [ContentActor, PersonId, Vec<NewAsset>, PersonUpdateParameters]>;
+      PersonUpdated: AugmentedEvent<ApiType, [ContentActor, PersonId, NewAssets, PersonUpdateParameters]>;
       PlaylistCreated: AugmentedEvent<ApiType, [ContentActor, PlaylistId, PlaylistCreationParameters]>;
       PlaylistDeleted: AugmentedEvent<ApiType, [ContentActor, PlaylistId]>;
       PlaylistUpdated: AugmentedEvent<ApiType, [ContentActor, PlaylistId, PlaylistUpdateParameters]>;
-      SeriesCreated: AugmentedEvent<ApiType, [ContentActor, SeriesId, Vec<NewAsset>, SeriesParameters, Series]>;
+      SeriesCreated: AugmentedEvent<ApiType, [ContentActor, SeriesId, NewAssets, SeriesParameters, Series]>;
       SeriesDeleted: AugmentedEvent<ApiType, [ContentActor, SeriesId]>;
-      SeriesUpdated: AugmentedEvent<ApiType, [ContentActor, SeriesId, Vec<NewAsset>, SeriesParameters, Series]>;
+      SeriesUpdated: AugmentedEvent<ApiType, [ContentActor, SeriesId, NewAssets, SeriesParameters, Series]>;
       VideoCategoryCreated: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId, VideoCategoryCreationParameters]>;
       VideoCategoryDeleted: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId]>;
       VideoCategoryUpdated: AugmentedEvent<ApiType, [ContentActor, VideoCategoryId, VideoCategoryUpdateParameters]>;

+ 1 - 1
types/augment/augment-api-query.ts

@@ -1137,7 +1137,7 @@ declare module '@polkadot/api/types/storage' {
        **/
       uploadingBlocked: AugmentedQuery<ApiType, () => Observable<bool>, []>;
       /**
-       * "Max objects number for a storage bucket voucher" number limit.
+       * "Max objects number for a storage  bucket voucher" number limit.
        **/
       voucherMaxObjectsNumberLimit: AugmentedQuery<ApiType, () => Observable<u64>, []>;
       /**

+ 8 - 7
types/augment/augment-api-tx.ts

@@ -3,7 +3,7 @@
 
 import type { BTreeMap, BTreeSet, Bytes, Compact, Option, Vec, bool, u16, u32, u64 } from '@polkadot/types';
 import type { AnyNumber } from '@polkadot/types/types';
-import type { ActivateOpeningAt, AddOpeningParameters, ApplicationId, ApplicationIdSet, BagId, BalanceOfMint, CategoryId, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, ContentId, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrize, DynamicBagId, DynamicBagType, ElectionParameters, FillOpeningParameters, MemberId, MemoText, OpeningId, OpeningPolicyCommitment, OpeningType, PaidTermId, PersonActor, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, RewardPolicy, SeriesId, SeriesParameters, StorageBucketId, TerminateRoleParameters, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, WorkerId, WorkingGroup } from './all';
+import type { ActivateOpeningAt, AddOpeningParameters, ApplicationId, ApplicationIdSet, BagId, BalanceOfMint, CategoryId, ChannelCategoryCreationParameters, ChannelCategoryId, ChannelCategoryUpdateParameters, ChannelCreationParameters, ChannelId, ChannelOwnershipTransferRequest, ChannelOwnershipTransferRequestId, ChannelUpdateParameters, Cid, ContentActor, CuratorGroupId, CuratorId, DataObjectId, DistributionBucketFamilyId, DistributionBucketId, DynamicBagDeletionPrize, DynamicBagId, DynamicBagType, ElectionParameters, FillOpeningParameters, MemberId, MemoText, OpeningId, OpeningPolicyCommitment, OpeningType, PaidTermId, PersonActor, PersonCreationParameters, PersonId, PersonUpdateParameters, PlaylistCreationParameters, PlaylistId, PlaylistUpdateParameters, PostId, ProposalId, RewardPolicy, SeriesId, SeriesParameters, StorageBucketId, TerminateRoleParameters, ThreadId, UploadParameters, VideoCategoryCreationParameters, VideoCategoryId, VideoCategoryUpdateParameters, VideoCreationParameters, VideoId, VideoUpdateParameters, VoteKind, WorkerId, WorkingGroup } from './all';
 import type { BabeEquivocationProof } from '@polkadot/types/interfaces/babe';
 import type { Extrinsic, Signature } from '@polkadot/types/interfaces/extrinsics';
 import type { GrandpaEquivocationProof, KeyOwnerProof } from '@polkadot/types/interfaces/grandpa';
@@ -137,6 +137,7 @@ declare module '@polkadot/api/types/submittable' {
       createSeries: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: SeriesParameters | { assets?: any; seasons?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, SeriesParameters]>;
       createVideo: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, params: VideoCreationParameters | { assets?: any; meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, VideoCreationParameters]>;
       createVideoCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, params: VideoCategoryCreationParameters | { meta?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, VideoCategoryCreationParameters]>;
+      deleteChannel: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId]>;
       deleteChannelCategory: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, categoryId: ChannelCategoryId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelCategoryId]>;
       deletePerson: AugmentedSubmittable<(actor: PersonActor | { Member: any } | { Curator: any } | string | Uint8Array, person: PersonId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [PersonActor, PersonId]>;
       deletePlaylist: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, playlist: PlaylistId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, PlaylistId]>;
@@ -146,7 +147,7 @@ declare module '@polkadot/api/types/submittable' {
       /**
        * Remove assets of a channel from storage
        **/
-      removeChannelAssets: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, assets: Vec<ContentId> | (ContentId | AnyNumber | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, Vec<ContentId>]>;
+      removeChannelAssets: AugmentedSubmittable<(actor: ContentActor | { Curator: any } | { Member: any } | { Lead: any } | string | Uint8Array, channelId: ChannelId | AnyNumber | Uint8Array, assets: BTreeSet<DataObjectId>) => SubmittableExtrinsic<ApiType>, [ContentActor, ChannelId, BTreeSet<DataObjectId>]>;
       /**
        * Remove curator from a given curator group
        **/
@@ -677,12 +678,12 @@ declare module '@polkadot/api/types/submittable' {
        * Create 'Begin review working group leader applications' proposal type.
        * This proposal uses `begin_applicant_review()` extrinsic from the Joystream `working group` module.
        **/
-      createBeginReviewWorkingGroupLeaderApplicationsProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, workingGroup: WorkingGroup | 'Storage' | 'Content' | 'Operations' | 'Gateway' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, OpeningId, WorkingGroup]>;
+      createBeginReviewWorkingGroupLeaderApplicationsProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, openingId: OpeningId | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, OpeningId, WorkingGroup]>;
       /**
        * Create 'decrease working group leader stake' proposal type.
        * This proposal uses `decrease_stake()` extrinsic from the `working-group`  module.
        **/
-      createDecreaseWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, decreasingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | 'Storage' | 'Content' | 'Operations' | 'Gateway' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
+      createDecreaseWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, decreasingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
       /**
        * Create 'Fill working group leader opening' proposal type.
        * This proposal uses `fill_opening()` extrinsic from the Joystream `working group` module.
@@ -707,17 +708,17 @@ declare module '@polkadot/api/types/submittable' {
        * Create 'set working group leader reward' proposal type.
        * This proposal uses `update_reward_amount()` extrinsic from the `working-group`  module.
        **/
-      createSetWorkingGroupLeaderRewardProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, rewardAmount: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | 'Storage' | 'Content' | 'Operations' | 'Gateway' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOfMint, WorkingGroup]>;
+      createSetWorkingGroupLeaderRewardProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, rewardAmount: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOfMint, WorkingGroup]>;
       /**
        * Create 'Set working group mint capacity' proposal type.
        * This proposal uses `set_mint_capacity()` extrinsic from the `working-group`  module.
        **/
-      createSetWorkingGroupMintCapacityProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, mintBalance: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | 'Storage' | 'Content' | 'Operations' | 'Gateway' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, BalanceOfMint, WorkingGroup]>;
+      createSetWorkingGroupMintCapacityProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, mintBalance: BalanceOfMint | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, BalanceOfMint, WorkingGroup]>;
       /**
        * Create 'slash working group leader stake' proposal type.
        * This proposal uses `slash_stake()` extrinsic from the `working-group`  module.
        **/
-      createSlashWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, slashingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | 'Storage' | 'Content' | 'Operations' | 'Gateway' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
+      createSlashWorkingGroupLeaderStakeProposal: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, title: Bytes | string | Uint8Array, description: Bytes | string | Uint8Array, stakeBalance: Option<BalanceOf> | null | object | string | Uint8Array, workerId: WorkerId | AnyNumber | Uint8Array, slashingStake: BalanceOf | AnyNumber | Uint8Array, workingGroup: WorkingGroup | '_Reserved0' | '_Reserved1' | 'Storage' | 'Content' | 'Operations' | 'Gateway' | 'Distribution' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [MemberId, Bytes, Bytes, Option<BalanceOf>, WorkerId, BalanceOf, WorkingGroup]>;
       /**
        * Create 'Spending' proposal type.
        * This proposal uses `spend_from_council_mint()` extrinsic from the `governance::council`  module.

File diff suppressed because it is too large
+ 0 - 0
types/augment/augment-types.ts


+ 9 - 3
types/src/common.ts

@@ -106,16 +106,22 @@ export class InputValidationLengthConstraint
   }
 }
 
+// Reserved keys are not part of the exported definition const, since they are not intented to be used
 export const WorkingGroupDef = {
-  // TODO: Forum: Null,
+  // _Reserved0
+  // _Reserved1
   Storage: Null,
   Content: Null,
   Operations: Null,
   Gateway: Null,
-  // TODO: Distribution
+  Distribution: Null,
 } as const
 export type WorkingGroupKey = keyof typeof WorkingGroupDef
-export class WorkingGroup extends JoyEnum(WorkingGroupDef) {}
+export class WorkingGroup extends JoyEnum({
+  _Reserved0: Null,
+  _Reserved1: Null,
+  ...WorkingGroupDef,
+}) {}
 
 // Temporarly in "common", because used both by /working-group and /content-working-group:
 export type ISlashableTerms = {

+ 25 - 22
types/src/content/index.ts

@@ -1,8 +1,9 @@
 import { Vec, Option, Tuple } from '@polkadot/types'
 import { bool, u64, u32, u128, Null, Bytes } from '@polkadot/types/primitive'
 import { MemberId } from '../members'
-import { JoyStructDecorated, JoyEnum, ChannelId, JoyBTreeSet, DAOId, Url } from '../common'
+import { JoyStructDecorated, JoyEnum, ChannelId, JoyBTreeSet, Url } from '../common'
 import { GenericAccountId as AccountId } from '@polkadot/types/generic/AccountId'
+import { DataObjectId, DataObjectCreationParameters } from '../storage'
 
 export class CuratorId extends u64 {}
 export class CuratorGroupId extends u64 {}
@@ -16,15 +17,16 @@ export class ChannelOwnershipTransferRequestId extends u64 {}
 export class MaxNumber extends u32 {}
 export class IsCensored extends bool {}
 
-// TODO: Remove after the storage-content integration.
-export class ContentId extends u64 {}
+export class AssetUrls extends Vec.with(Url) {}
 
-// TODO: Remove after the storage-content integration.
-export class ContentParameters extends u64 {}
+export class CreationUploadParameters extends JoyStructDecorated({
+  object_creation_list: Vec.with(DataObjectCreationParameters),
+  expected_data_size_fee: u128,
+}) {}
 
-export class NewAsset extends JoyEnum({
-  Upload: ContentParameters,
-  Urls: Vec.with(Url),
+export class NewAssets extends JoyEnum({
+  Upload: CreationUploadParameters,
+  Urls: Vec.with(AssetUrls),
 }) {}
 
 export class CuratorGroup extends JoyStructDecorated({
@@ -41,26 +43,25 @@ export class ContentActor extends JoyEnum({
 export class ChannelOwner extends JoyEnum({
   Member: MemberId,
   Curators: CuratorGroupId,
-  Dao: DAOId,
 }) {}
 
 export class Channel extends JoyStructDecorated({
   owner: ChannelOwner,
-  videos: Vec.with(VideoId),
-  playlists: Vec.with(PlaylistId),
-  series: Vec.with(SeriesId),
+  num_videos: u64,
   is_censored: bool,
   reward_account: Option.with(AccountId),
+  deletion_prize_source_account_id: AccountId,
+  num_assets: u64,
 }) {}
 
 export class ChannelCreationParameters extends JoyStructDecorated({
-  assets: Vec.with(NewAsset),
+  assets: NewAssets,
   meta: Bytes,
   reward_account: Option.with(AccountId),
 }) {}
 
 export class ChannelUpdateParameters extends JoyStructDecorated({
-  assets: Option.with(Vec.with(NewAsset)),
+  assets: Option.with(NewAssets),
   new_meta: Option.with(Bytes),
   reward_account: Option.with(Option.with(AccountId)),
 }) {}
@@ -100,15 +101,16 @@ export class Video extends JoyStructDecorated({
   in_channel: ChannelId,
   in_series: Option.with(SeriesId),
   is_censored: bool,
+  maybe_data_objects_id_set: Option.with(JoyBTreeSet(DataObjectId)),
 }) {}
 
 export class VideoCreationParameters extends JoyStructDecorated({
-  assets: Vec.with(NewAsset),
+  assets: NewAssets,
   meta: Bytes,
 }) {}
 
 export class VideoUpdateParameters extends JoyStructDecorated({
-  assets: Option.with(Vec.with(NewAsset)),
+  assets: Option.with(NewAssets),
   new_meta: Option.with(Bytes),
 }) {}
 
@@ -134,7 +136,7 @@ export class Season extends JoyStructDecorated({
 }) {}
 
 export class SeasonParameters extends JoyStructDecorated({
-  assets: Option.with(Vec.with(NewAsset)),
+  assets: Option.with(NewAssets),
   episodes: Option.with(Vec.with(Option.with(EpisodeParemters))),
   meta: Option.with(Bytes),
 }) {}
@@ -145,7 +147,7 @@ export class Series extends JoyStructDecorated({
 }) {}
 
 export class SeriesParameters extends JoyStructDecorated({
-  assets: Option.with(Vec.with(NewAsset)),
+  assets: Option.with(NewAssets),
   seasons: Option.with(Vec.with(Option.with(SeasonParameters))),
   meta: Option.with(Bytes),
 }) {}
@@ -160,12 +162,12 @@ export class Person extends JoyStructDecorated({
 }) {}
 
 export class PersonCreationParameters extends JoyStructDecorated({
-  assets: Vec.with(NewAsset),
+  assets: NewAssets,
   meta: Bytes,
 }) {}
 
 export class PersonUpdateParameters extends JoyStructDecorated({
-  assets: Option.with(Vec.with(NewAsset)),
+  assets: Option.with(NewAssets),
   meta: Option.with(Bytes),
 }) {}
 
@@ -179,7 +181,9 @@ export const contentTypes = {
   CuratorGroupId,
   CuratorGroup,
   ContentActor,
-  NewAsset,
+  CreationUploadParameters,
+  AssetUrls,
+  NewAssets,
   Channel,
   ChannelOwner,
   ChannelCategoryId,
@@ -216,7 +220,6 @@ export const contentTypes = {
   EpisodeParemters,
   MaxNumber,
   IsCensored,
-  ContentId, // TODO: Remove after the content integration
 }
 
 export default contentTypes

+ 1 - 0
types/src/scripts/generateRegistryJson.ts

@@ -11,6 +11,7 @@ const OUTPUT_PATH = path.join(__dirname, '../../augment/all/defs.json')
 function normalizeDef(registry: Registry, defOrConstructor: any, typeName: string): RegistryTypes[string] {
   if (typeof defOrConstructor === 'string') {
     // Replace unhandled BTreeSet with Vec
+    // FIXME: Remove after updating @polkadot/api!
     defOrConstructor = defOrConstructor.replace('BTreeSet<', 'Vec<')
     // Workaround for "Unhandled type VecFixed"
     defOrConstructor = defOrConstructor.replace('[u8;32]', 'Hash')

Some files were not shown because too many files changed in this diff