Jelajahi Sumber

query node - mappings implementation I

ondratra 4 tahun lalu
induk
melakukan
cf5bc27fbe

+ 8 - 0
query-node/README.md

@@ -123,5 +123,13 @@ chmod +x tmp.sh
 yarn workspace query-node-root typegen
 yarn workspace query-node-mappings build
 
+```
+
+running the processor:
+```
+cp types/augment/all/defs.json query-node/mappings/lib/generated/types/typedefs.json
+docker-compose up -d db
+yarn workspace query-node-root db:create
+yarn workspace query-node-root db:migrate
 
 ```

+ 111 - 5
query-node/manifest.yml

@@ -1,6 +1,7 @@
 version: '0.1'
 description: Joystream query-node manifest file for sumer
 repository: https://github.com/Joystream/joystream
+hydraVersion: "2"
 dataSource:
   kind: substrate
   chain: joystream
@@ -11,13 +12,41 @@ typegen:
   metadata:
     source: wss://sumer.joystream.app
   events:
+    # members
     - members.MemberRegistered
     - members.MemberUpdatedAboutText
     - members.MemberUpdatedAvatar
     - members.MemberUpdatedHandle
     - members.MemberSetRootAccount
     - members.MemberSetControllerAccount
+
+    # content directory
+    - content.CuratorGroupCreated
+    - content.CuratorGroupStatusSet
+    - content.CuratorAdded
+    - content.CuratorRemoved
+    - content.ChannelCreated
+    - content.ChannelUpdated
+    - content.ChannelAssetsRemoved
+    - content.ChannelCensored
+    - content.ChannelUncensored
+    - content.ChannelOwnershipTransferRequested
+    - content.ChannelOwnershipTransferRequestWithdrawn
+    - content.ChannelOwnershipTransferred
+    - content.ChannelCategoryCreated
+    - content.ChannelCategoryUpdated
+    - content.ChannelCategoryDeleted
+    - content.VideoCategoryCreated
+    - content.VideoCategoryUpdated
+    - content.VideoCategoryDeleted
+    - content.VideoCreated
+    - content.VideoUpdated
+    - content.VideoDeleted
+    - content.VideoCensored
+    - content.VideoUncensored
+    - content.FeaturedVideosSet
   calls:
+    # members
     - members.buyMembership
     - members.addScreenedMember
     - members.changeMemberAboutText
@@ -25,20 +54,48 @@ typegen:
     - members.changeMemberHandle
     - members.setRootAccount
     - members.setControllerAccount
+
+    # content directory
+    - content.create_curator_group
+    - content.set_curator_group_status
+    - content.add_curator_to_group
+    - content.remove_curator_from_group
+    - content.create_channel
+    - content.update_channel
+    - content.remove_channel_assets
+    - content.censor_channel
+    - content.uncensor_channel
+    - content.create_channel_category
+    - content.update_channel_category
+    - content.delete_channel_category
+    - content.request_channel_transfer
+    - content.cancel_channel_transfer_request
+    - content.accept_channel_transfer
+    - content.create_video
+    - content.update_video
+    - content.delete_video
+    - content.create_playlist
+    - content.update_playlist
+    - content.delete_playlist
+    - content.set_featured_videos
+    - content.create_video_category
+    - content.update_video_category
+    - content.delete_video_category
+    - content.remove_person_from_video
+    - content.censor_video
+    - content.uncensor_video
+
   outDir: ./generated/types
   customTypes:
-    lib: '@joystream/types/augment/all/types'
+    lib: '@joystream/types/augment'
     typedefsLoc: '../types/augment/all/defs.json'
 mappings:
-  hydraCommonVersion: '0.0.3'
-    # process only blocks with height >= 1M
-  blockInterval: '[1000000,]'
   # js module that exports the handler functions
   mappingsModule: mappings/lib/mappings
   # additinal libraries the processor loads
   # typically it is a module with event and extrinsic types generated by hydra-typegen
   imports:
-    - mappings/lib/mappings/generated/types
+    - mappings/lib/generated/types
   eventHandlers:
     - event: members.MemberRegistered
       handler: members_MemberRegistered(DatabaseManager, SubstrateEvent)
@@ -52,6 +109,55 @@ mappings:
       handler: members_MemberSetRootAccount(DatabaseManager, SubstrateEvent)
     - event: members.MemberSetControllerAccount
       handler: members_MemberSetControllerAccount(DatabaseManager, SubstrateEvent)
+
+    - event: content.CuratorGroupCreated
+      handler: content_CuratorGroupCreated(DatabaseManager, SubstrateEvent)
+    - event: content.CuratorGroupStatusSet
+      handler: content_CuratorGroupStatusSet(DatabaseManager, SubstrateEvent)
+    - event: content.CuratorAdded
+      handler: content_CuratorAdded(DatabaseManager, SubstrateEvent)
+    - event: content.CuratorRemoved
+      handler: content_CuratorRemoved(DatabaseManager, SubstrateEvent)
+    - event: content.ChannelCreated
+      handler: content_ChannelCreated(DatabaseManager, SubstrateEvent)
+    - event: content.ChannelUpdated
+      handler: content_ChannelUpdated(DatabaseManager, SubstrateEvent)
+    - event: content.ChannelAssetsRemoved
+      handler: content_ChannelAssetsRemoved(DatabaseManager, SubstrateEvent)
+    - event: content.ChannelCensored
+      handler: content_ChannelCensored(DatabaseManager, SubstrateEvent)
+    - event: content.ChannelUncensored
+      handler: content_ChannelUncensored(DatabaseManager, SubstrateEvent)
+    - event: content.ChannelOwnershipTransferRequested
+      handler: content_ChannelOwnershipTransferRequested(DatabaseManager, SubstrateEvent)
+    - event: content.ChannelOwnershipTransferRequestWithdrawn
+      handler: content_ChannelOwnershipTransferRequestWithdrawn(DatabaseManager, SubstrateEvent)
+    - event: content.ChannelOwnershipTransferred
+      handler: content_ChannelOwnershipTransferred(DatabaseManager, SubstrateEvent)
+    - event: content.ChannelCategoryCreated
+      handler: content_ChannelCategoryCreated(DatabaseManager, SubstrateEvent)
+    - event: content.ChannelCategoryUpdated
+      handler: content_ChannelCategoryUpdated(DatabaseManager, SubstrateEvent)
+    - event: content.ChannelCategoryDeleted
+      handler: content_ChannelCategoryDeleted(DatabaseManager, SubstrateEvent)
+    - event: content.VideoCategoryCreated
+      handler: content_VideoCategoryCreated(DatabaseManager, SubstrateEvent)
+    - event: content.VideoCategoryUpdated
+      handler: content_VideoCategoryUpdated(DatabaseManager, SubstrateEvent)
+    - event: content.VideoCategoryDeleted
+      handler: content_VideoCategoryDeleted(DatabaseManager, SubstrateEvent)
+    - event: content.VideoCreated
+      handler: content_VideoCreated(DatabaseManager, SubstrateEvent)
+    - event: content.VideoUpdated
+      handler: content_VideoUpdated(DatabaseManager, SubstrateEvent)
+    - event: content.VideoDeleted
+      handler: content_VideoDeleted(DatabaseManager, SubstrateEvent)
+    - event: content.VideoCensored
+      handler: content_VideoCensored(DatabaseManager, SubstrateEvent)
+    - event: content.VideoUncensored
+      handler: content_VideoUncensored(DatabaseManager, SubstrateEvent)
+    - event: content.FeaturedVideosSet
+      handler: content_FeaturedVideosSet(DatabaseManager, SubstrateEvent)
   extrinsicHandlers:
     # infer defaults here
     #- extrinsic: Balances.Transfer

+ 4 - 4
query-node/mappings/common.ts

@@ -2,7 +2,7 @@ import BN from 'bn.js'
 import { SubstrateEvent } from '@dzlzv/hydra-common'
 import { DatabaseManager } from '@dzlzv/hydra-db-utils'
 
-import { Block } from 'query-node/dist/src/modules/block/block.model'
+import { Block } from 'query-node/src/modules/block/block.model'
 import { Network } from 'query-node/src/modules/enums/enums'
 
 // Asset
@@ -11,11 +11,11 @@ import {
   AssetUploadStatus,
   AssetStorage,
   AssetOwnerMember,
-} from 'query-node/dist/src/modules/variants/variants.model'
+} from 'query-node/src/modules/variants/variants.model'
 import {
   AssetDataObject,
   LiaisonJudgement,
-} from 'query-node/dist/src/modules/asset-data-object/asset-data-object.model'
+} from 'query-node/src/modules/asset-data-object/asset-data-object.model'
 import {
   ContentParameters
 } from '@joystream/types/augment'
@@ -43,7 +43,7 @@ export async function prepareBlock(db: DatabaseManager, event: SubstrateEvent):
 
 export async function prepareAssetDataObject(contentParameters: ContentParameters, block: Block): Promise<AssetStorage> {
   const assetOwner = new AssetOwnerMember() // TODO: proper owner
-  assetOwner.memberId = 0
+  assetOwner.memberId = new BN(0)
 
   const assetDataObject = new AssetDataObject({
     owner: assetOwner,

+ 107 - 174
query-node/mappings/mappingsContent.ts

@@ -1,5 +1,6 @@
 // TODO: add logging of mapping events (entity found/not found, entity updated/deleted, etc.)
 // TODO: split file into multiple files
+// TODO: make sure assets are updated when VideoUpdateParameters have only `assets` parameter set (no `new_meta` set) - if this situation can even happend
 
 import { SubstrateEvent } from '@dzlzv/hydra-common'
 import { DatabaseManager } from '@dzlzv/hydra-db-utils'
@@ -15,6 +16,10 @@ import {
   VideoCategoryMetadata,
 } from '@joystream/content-metadata-protobuf'
 
+import {
+  Content,
+} from '../generated/types'
+
 /* TODO: can it be imported nicely like this?
 import {
   // primary entites
@@ -51,17 +56,17 @@ import {
 } from './common'
 
 // primary entities
-import { Block } from 'query-node/dist/src/modules/block/block.model'
-import { Channel } from 'query-node/dist/src/modules/channel/channel.model'
-import { ChannelCategory } from 'query-node/dist/src/modules/channel-category/channel-category.model'
-import { Video } from 'query-node/dist/src/modules/video/video.model'
-import { VideoCategory } from 'query-node/dist/src/modules/video-category/video-category.model'
+import { Block } from 'query-node/src/modules/block/block.model'
+import { Channel } from 'query-node/src/modules/channel/channel.model'
+import { ChannelCategory } from 'query-node/src/modules/channel-category/channel-category.model'
+import { Video } from 'query-node/src/modules/video/video.model'
+import { VideoCategory } from 'query-node/src/modules/video-category/video-category.model'
 
 // secondary entities
-import { Language } from 'query-node/dist/src/modules/language/language.model'
-import { License } from 'query-node/dist/src/modules/license/license.model'
-import { VideoMediaEncoding } from 'query-node/dist/src/modules/video-media-encoding/video-media-encoding.model'
-import { VideoMediaMetadata } from 'query-node/dist/src/modules/video-media-metadata/video-media-metadata.model'
+import { Language } from 'query-node/src/modules/language/language.model'
+import { License } from 'query-node/src/modules/license/license.model'
+import { VideoMediaEncoding } from 'query-node/src/modules/video-media-encoding/video-media-encoding.model'
+import { VideoMediaMetadata } from 'query-node/src/modules/video-media-metadata/video-media-metadata.model'
 
 // Asset
 import {
@@ -71,30 +76,24 @@ import {
   AssetStorage,
   AssetOwner,
   AssetOwnerMember,
-} from 'query-node/dist/src/modules/variants/variants.model'
+} from 'query-node/src/modules/variants/variants.model'
 import {
   AssetDataObject,
   LiaisonJudgement
-} from 'query-node/dist/src/modules/asset-data-object/asset-data-object.model'
-
+} from 'query-node/src/modules/asset-data-object/asset-data-object.model'
 
-// TODO: decide which of the following imports is valid
+// Joystream types
 import {
-  ContentParameters
+  ContentParameters,
+  NewAsset,
 } from '@joystream/types/augment'
-import {
-  contentDirectory,
-  storage,
-} from '@joystream/types'
-type RawAsset = ReturnType<typeof contentDirectory.NewAsset.create>
-type RawAssetTypes = typeof contentDirectory.NewAsset.typeDefinitions
 
 /////////////////// Utils //////////////////////////////////////////////////////
 
 async function readProtobuf(
   type: Channel | ChannelCategory | Video | VideoCategory,
   metadata: Uint8Array,
-  assets: RawAsset[],
+  assets: NewAsset[],
   db: DatabaseManager,
   event: SubstrateEvent,
 ): Promise<Partial<typeof type>> {
@@ -135,8 +134,7 @@ async function readProtobuf(
 
     // prepare video category if needed
     if (metaAsObject.category !== undefined) {
-      // TODO: find why array instead of one value is required here (mb input schema problem?)
-      result.category = [await prepareVideoCategory(metaAsObject.category, db)]
+      result.category = await prepareVideoCategory(metaAsObject.category, db)
     }
 
     // prepare media meta information if needed
@@ -187,19 +185,17 @@ async function readProtobuf(
   throw `Not implemented type: ${type}`
 }
 
-
-async function convertAsset(rawAsset: RawAsset, db: DatabaseManager, event: SubstrateEvent): Promise<typeof Asset> {
-  if (rawAsset.type == 'Urls') {
+async function convertAsset(rawAsset: NewAsset, db: DatabaseManager, event: SubstrateEvent): Promise<typeof Asset> {
+  if (rawAsset.isUrls) {
     const assetUrl = new AssetUrl()
-    assetUrl.url = rawAsset.asType('Urls').toArray()[0].toString() // TODO: find out why asUrl() returns array
+    assetUrl.url = rawAsset.asUrls.toArray()[0].toString() // TODO: find out why asUrl() returns array
 
     return assetUrl
   }
 
-  // rawAsset == 'Upload'
+  // !rawAsset.isUrls && rawAsset.isUpload
 
-  //const contentParameters: typeof contentDirectory.ContentParameters = rawAsset.asStorage()
-  const contentParameters: ContentParameters = rawAsset.asType('Upload')
+  const contentParameters: ContentParameters = rawAsset.asUpload
 
   const block = await prepareBlock(db, event)
   const assetStorage = await prepareAssetDataObject(contentParameters, block)
@@ -209,7 +205,7 @@ async function convertAsset(rawAsset: RawAsset, db: DatabaseManager, event: Subs
 
 async function extractAsset(
   assetIndex: number | undefined,
-  assets: RawAsset[],
+  assets: NewAsset[],
   db: DatabaseManager,
   event: SubstrateEvent,
 ): Promise<typeof Asset | undefined> {
@@ -280,24 +276,18 @@ async function prepareVideoCategory(categoryId: number, db: DatabaseManager): Pr
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
 export async function content_ChannelCreated(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  /* event arguments
-  ChannelId,
-  ChannelOwner<MemberId, CuratorGroupId, DAOId>,
-  Vec<NewAsset>,
-  ChannelCreationParameters<ContentParameters>,
-  */
-
-  //const protobufContent = await readProtobuf(ProtobufEntity.Channel, (event.params[3].value as any).meta, event.params[2].value as any[], db) // TODO: get rid of `any` typecast
+  const {channelId, channelCreationParameters} = new Content.ChannelCreatedEvent(event).data
+
   const protobufContent = await readProtobuf(
     new Channel(),
-    (event.params[3].value as any).meta,
-    event.params[2].value as any[],
+    channelCreationParameters.meta,
+    channelCreationParameters.assets,
     db,
     event,
-  ) // TODO: get rid of `any` typecast
+  )
 
   const channel = new Channel({
-    id: event.params[0].value.toString(), // ChannelId
+    id: channelId,
     isCensored: false,
     videos: [],
     happenedIn: await prepareBlock(db, event),
@@ -312,31 +302,39 @@ export async function content_ChannelUpdated(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  ChannelId,
-  Channel,
-  ChannelUpdateParameters<ContentParameters, AccountId>,
-  */
+  const {channelId , channelUpdateParameters} = new Content.ChannelUpdatedEvent(event).data
 
-  const channelId = event.params[1].value.toString()
   const channel = await db.get(Channel, { where: { id: channelId } })
 
   if (!channel) {
     return inconsistentState()
   }
 
-  const protobufContent = await readProtobuf(
-    new Channel(),
-    (event.params[3].value as any).new_meta,
-    (event.params[3].value as any).assets,
-    db,
-    event,
-  ) // TODO: get rid of `any` typecast
+  // metadata change happened?
+  if (channelUpdateParameters.new_meta.isSome) {
+    const protobufContent = await readProtobuf(
+      new Channel(),
+      channelUpdateParameters.new_meta.unwrap(), // TODO: is there any better way to get value without unwrap?
+      channelUpdateParameters.assets.unwrapOr([]),
+      db,
+      event,
+    )
+
+    // update all fields read from protobuf
+    for (let [key, value] of Object(protobufContent).entries()) {
+      channel[key] = value
+    }
+  }
 
-  // update all fields read from protobuf
-  for (let [key, value] of Object(protobufContent).entries()) {
-    channel[key] = value
+  // reward account change happened?
+  if (channelUpdateParameters.reward_account.isSome) {
+    // TODO: separate to function
+    // new different reward account set
+    if (channelUpdateParameters.reward_account.unwrap().isSome) {
+      channel.rewardAccount = channelUpdateParameters.reward_account.unwrap().unwrap().toString()
+    } else { // reward account removed
+      delete channel.rewardAccount
+    }
   }
 
   await db.save<Channel>(channel)
@@ -354,12 +352,6 @@ export async function content_ChannelCensored(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  ChannelId,
-  Vec<u8>
-  */
-
   const channelId = event.params[1].value.toString()
   const channel = await db.get(Channel, { where: { id: channelId } })
 
@@ -377,12 +369,6 @@ export async function content_ChannelUncensored(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  ChannelId,
-  Vec<u8>
-  */
-
   const channelId = event.params[1].value.toString()
   const channel = await db.get(Channel, { where: { id: channelId } })
 
@@ -426,19 +412,15 @@ export async function content_ChannelCategoryCreated(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ChannelCategoryId,
-  ChannelCategory,
-  ChannelCategoryCreationParameters,
-  */
+  const {channelCategoryCreationParameters} = new Content.ChannelCategoryCreatedEvent(event).data
 
   const protobufContent = await readProtobuf(
     new ChannelCategory(),
-    (event.params[2].value as any).meta,
+    channelCategoryCreationParameters.meta,
     [],
     db,
     event,
-  ) // TODO: get rid of `any` typecast
+  )
 
   const channelCategory = new ChannelCategory({
     id: event.params[0].value.toString(), // ChannelCategoryId
@@ -455,13 +437,7 @@ export async function content_ChannelCategoryUpdated(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  ChannelCategoryId,
-  ChannelCategoryUpdateParameters,
-  */
-
-  const channelCategoryId = event.params[1].value.toString()
+  const {channelCategoryId, channelCategoryUpdateParameters} = new Content.ChannelCategoryUpdatedEvent(event).data
   const channelCategory = await db.get(ChannelCategory, { where: { id: channelCategoryId } })
 
   if (!channelCategory) {
@@ -470,11 +446,11 @@ export async function content_ChannelCategoryUpdated(
 
   const protobufContent = await readProtobuf(
     new ChannelCategory(),
-    (event.params[2].value as any).meta,
+    channelCategoryUpdateParameters.new_meta,
     [],
     db,
     event,
-  ) // TODO: get rid of `any` typecast
+  )
 
   // update all fields read from protobuf
   for (let [key, value] of Object(protobufContent).entries()) {
@@ -489,11 +465,7 @@ export async function content_ChannelCategoryDeleted(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  ChannelCategoryId
-  */
-  const channelCategoryId = event.params[1].value.toString()
+  const {channelCategoryId} = new Content.ChannelCategoryDeletedEvent(event).data
   const channelCategory = await db.get(ChannelCategory, { where: { id: channelCategoryId } })
 
   if (!channelCategory) {
@@ -510,22 +482,17 @@ export async function content_VideoCategoryCreated(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  VideoCategoryId,
-  VideoCategoryCreationParameters,
-  */
-
+  const {videoCategoryId, videoCategoryCreationParameters} = new Content.VideoCategoryCreatedEvent(event).data
   const protobufContent = readProtobuf(
     new VideoCategory(),
-    (event.params[2].value as any).meta,
+    videoCategoryCreationParameters.meta,
     [],
     db,
     event
-  ) // TODO: get rid of `any` typecast
+  )
 
   const videoCategory = new VideoCategory({
-    id: event.params[0].value.toString(), // ChannelId
+    id: videoCategoryId.toString(), // ChannelId
     isCensored: false,
     videos: [],
     happenedIn: await prepareBlock(db, event),
@@ -540,13 +507,7 @@ export async function content_VideoCategoryUpdated(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  VideoCategoryId,
-  VideoCategoryUpdateParameters,
-  */
-
-  const videoCategoryId = event.params[1].toString()
+  const {videoCategoryId, videoCategoryUpdateParameters} = new Content.VideoCategoryUpdatedEvent(event).data
   const videoCategory = await db.get(VideoCategory, { where: { id: videoCategoryId } })
 
   if (!videoCategory) {
@@ -555,11 +516,11 @@ export async function content_VideoCategoryUpdated(
 
   const protobufContent = await readProtobuf(
     new VideoCategory(),
-    (event.params[2].value as any).meta,
+    videoCategoryUpdateParameters.new_meta,
     [],
     db,
     event,
-  ) // TODO: get rid of `any` typecast
+  )
 
   // update all fields read from protobuf
   for (let [key, value] of Object(protobufContent).entries()) {
@@ -574,12 +535,7 @@ export async function content_VideoCategoryDeleted(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  VideoCategoryId,
-  */
-
-  const videoCategoryId = event.params[1].toString()
+  const {videoCategoryId} = new Content.VideoCategoryDeletedEvent(event).data
   const videoCategory = await db.get(VideoCategory, { where: { id: videoCategoryId } })
 
   if (!videoCategory) {
@@ -596,25 +552,19 @@ export async function content_VideoCreated(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  ChannelId,
-  VideoId,
-  VideoCreationParameters<ContentParameters>,
-  */
-
+  const {channelId, videoId, videoCreationParameters} = new Content.VideoCreatedEvent(event).data
   const protobufContent = await readProtobuf(
     new Video(),
-    (event.params[3].value as any).meta,
-    (event.params[3].value as any).assets,
+    videoCreationParameters.meta,
+    videoCreationParameters.assets,
     db,
     event,
-  ) // TODO: get rid of `any` typecast
+  )
 
   const channel = new Video({
-    id: event.params[2].toString(), // ChannelId
+    id: videoId,
     isCensored: false,
-    channel: event.params[1],
+    channel: channelId,
     happenedIn: await prepareBlock(db, event),
     ...Object(protobufContent)
   })
@@ -627,29 +577,26 @@ export async function content_VideoUpdated(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  VideoId,
-  VideoUpdateParameters<ContentParameters>,
-  */
-  const videoId = event.params[1].toString()
+  const {videoId, videoUpdateParameters} = new Content.VideoUpdatedEvent(event).data
   const video = await db.get(Video, { where: { id: videoId } })
 
   if (!video) {
     return inconsistentState()
   }
 
-  const protobufContent = await readProtobuf(
-    new Video(),
-    (event.params[2].value as any).meta,
-    (event.params[2].value as any).assets,
-    db,
-    event,
-  ) // TODO: get rid of `any` typecast
-
-  // update all fields read from protobuf
-  for (let [key, value] of Object(protobufContent).entries()) {
-    video[key] = value
+  if (videoUpdateParameters.new_meta.isSome) {
+    const protobufContent = await readProtobuf(
+      new Video(),
+      videoUpdateParameters.new_meta.unwrap(), // TODO: is there any better way to get value without unwrap?
+      videoUpdateParameters.assets.unwrapOr([]),
+      db,
+      event,
+    )
+
+    // update all fields read from protobuf
+    for (let [key, value] of Object(protobufContent).entries()) {
+      video[key] = value
+    }
   }
 
   await db.save<Video>(video)
@@ -660,12 +607,7 @@ export async function content_VideoDeleted(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  VideoCategoryId,
-  */
-
-  const videoId = event.params[1].toString()
+  const {videoId} = new Content.VideoDeletedEvent(event).data
   const video = await db.get(Video, { where: { id: videoId } })
 
   if (!video) {
@@ -680,13 +622,7 @@ export async function content_VideoCensored(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  VideoId,
-  Vec<u8>
-  */
-
-  const videoId = event.params[1].toString()
+  const {videoId} = new Content.VideoCensoredEvent(event).data
   const video = await db.get(Video, { where: { id: videoId } })
 
   if (!video) {
@@ -703,13 +639,7 @@ export async function content_VideoUncensored(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  VideoId,
-  Vec<u8>
-  */
-
-  const videoId = event.params[1].toString()
+  const {videoId} = new Content.VideoUncensoredEvent(event).data
   const video = await db.get(Video, { where: { id: videoId } })
 
   if (!video) {
@@ -726,20 +656,23 @@ export async function content_FeaturedVideosSet(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  /* event arguments
-  ContentActor,
-  Vec<VideoId>,
-  */
-
-  const videoIds = event.params[1].value as string[]
+  const {videoId: videoIds} = new Content.FeaturedVideosSetEvent(event).data
   const existingFeaturedVideos = await db.getMany(Video, { where: { isFeatured: true } })
 
   // comparsion utility
   const isSame = (videoIdA: string) => (videoIdB: string) => videoIdA == videoIdB
 
   // calculate diff sets
-  const toRemove = existingFeaturedVideos.filter(existingFV => !videoIds.some(isSame(existingFV.id)))
-  const toAdd = videoIds.filter(video => !existingFeaturedVideos.map(item => item.id).some(isSame(video)))
+  const toRemove = existingFeaturedVideos.filter(existingFV =>
+    !videoIds
+      .map(item => item.toHex())
+      .some(isSame(existingFV.id))
+  )
+  const toAdd = videoIds.filter(video =>
+    !existingFeaturedVideos
+      .map(item => item.id)
+      .some(isSame(video.toHex()))
+  )
 
   // mark previously featured videos as not-featured
   for (let video of toRemove) {

+ 2 - 2
query-node/mappings/membership.ts

@@ -6,8 +6,8 @@ import { DatabaseManager } from '@dzlzv/hydra-db-utils'
 
 import { prepareBlock } from './common'
 import { Members } from '../generated/types'
-import { MembershipEntryMethod, Membership } from 'query-node/dist/src/modules/membership/membership.model'
-import { Block } from 'query-node/dist/src/modules/block/block.model'
+import { MembershipEntryMethod, Membership } from 'query-node/src/modules/membership/membership.model'
+import { Block } from 'query-node/src/modules/block/block.model'
 
 async function getMemberById(db: DatabaseManager, id: MemberId): Promise<Membership> {
   const member = await db.get(Membership, { where: { id: id.toString() } })

+ 2 - 2
query-node/mappings/package.json

@@ -10,8 +10,8 @@
     "clean": "rm -rf lib"
   },
   "dependencies": {
-    "@dzlzv/hydra-common": "2.0.1-beta.9",
-    "@dzlzv/hydra-db-utils": "2.0.1-beta.9",
+    "@dzlzv/hydra-common": "2.0.1-beta.15",
+    "@dzlzv/hydra-db-utils": "2.0.1-beta.15",
     "@joystream/content-metadata-protobuf": "^1.0.0",
     "@joystream/types": "^0.16.0",
     "query-node": "^0.0.0",

+ 3 - 3
query-node/mappings/storage.ts

@@ -13,10 +13,10 @@ import {
 } from '@joystream/types/augment'
 import {
   AssetStorage,
-} from 'query-node/dist/src/modules/variants/variants.model'
-import { LiaisonJudgement } from 'query-node/dist/src/modules/enums/enums'
+} from 'query-node/src/modules/variants/variants.model'
+import { LiaisonJudgement } from 'query-node/src/modules/enums/enums'
 
-import { AssetDataObject } from 'query-node/dist/src/modules/asset-data-object/asset-data-object.model'
+import { AssetDataObject } from 'query-node/src/modules/asset-data-object/asset-data-object.model'
 
 export async function ContentAdded(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
   /* event arguments

+ 3 - 4
query-node/package.json

@@ -38,12 +38,11 @@
     "@types/bn.js": "^4.11.6",
     "bn.js": "^5.1.2",
     "@polkadot/metadata": "^4.1.1",
-    "@dzlzv/hydra-cli": "2.0.1-beta.9",
-    "@dzlzv/hydra-processor": "2.0.1-beta.9"
+    "@dzlzv/hydra-cli": "2.0.1-beta.15",
+    "@dzlzv/hydra-processor": "2.0.1-beta.15"
   },
   "devDependencies": {
-    "@dzlzv/hydra-typegen": "2.0.1-beta.9"
-    , "@polkadot/x-ws": "6.0.5"
+    "@dzlzv/hydra-typegen": "2.0.1-beta.15"
   },
   "volta": {
 		"extends": "../package.json"