|
@@ -1,9 +1,7 @@
|
|
|
// TODO: solve events' relations to videos and other entites that can be changed or deleted
|
|
|
-// TODO: solve transactionalStatus for OwnedNFT + how to set it up for first time auctioned NFT?
|
|
|
-// TODO: walkthrough bidding events once again and ensure all data are saved properly
|
|
|
|
|
|
import { EventContext, StoreContext, DatabaseManager } from '@joystream/hydra-common'
|
|
|
-import { genericEventFields, inconsistentState } from '../common'
|
|
|
+import { genericEventFields, inconsistentState, unexpectedData, logger } from '../common'
|
|
|
import {
|
|
|
// entities
|
|
|
Auction,
|
|
@@ -14,6 +12,14 @@ import {
|
|
|
Membership,
|
|
|
OwnedNft,
|
|
|
Video,
|
|
|
+ TransactionalStatusInitiatedOfferToMember,
|
|
|
+ TransactionalStatusIdle,
|
|
|
+ TransactionalStatusBuyNow,
|
|
|
+ TransactionalStatusAuction,
|
|
|
+ ContentActor,
|
|
|
+ ContentActorMember,
|
|
|
+ ContentActorCurator,
|
|
|
+ Curator,
|
|
|
|
|
|
// events
|
|
|
AuctionStartedEvent,
|
|
@@ -33,6 +39,7 @@ import {
|
|
|
} from 'query-node/dist/model'
|
|
|
import * as joystreamTypes from '@joystream/types/augment/all/types'
|
|
|
import { Content } from '../generated/types'
|
|
|
+import { FindConditions } from 'typeorm'
|
|
|
import BN from 'bn.js'
|
|
|
|
|
|
// definition of generic type for Hydra DatabaseManager's methods
|
|
@@ -92,6 +99,45 @@ async function getAuctionFromVideo(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+async function getNftFromVideo(
|
|
|
+ store: DatabaseManager,
|
|
|
+ videoId: string,
|
|
|
+ errorMessageForVideo: string,
|
|
|
+ errorMessageForNft: string
|
|
|
+): Promise<{ video: Video; nft: OwnedNft }> {
|
|
|
+ // load video
|
|
|
+ const video = await getRequiredExistingEntity(store, Video, videoId.toString(), errorMessageForVideo, ['nft'])
|
|
|
+
|
|
|
+ // get auction
|
|
|
+ const nft = video.nft
|
|
|
+
|
|
|
+ // ensure auction exists
|
|
|
+ if (!nft) {
|
|
|
+ return inconsistentState(errorMessageForNft, videoId)
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ video,
|
|
|
+ nft,
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+async function resetNftTransactionalStatusFromVideo(store: DatabaseManager, videoId: string, errorMessage: string) {
|
|
|
+ // load NFT
|
|
|
+ const nft = await store.get(OwnedNft, { where: { video: { id: videoId.toString() } } as FindConditions<OwnedNft> })
|
|
|
+
|
|
|
+ // ensure NFT
|
|
|
+ if (!nft) {
|
|
|
+ return inconsistentState(errorMessage, videoId.toString())
|
|
|
+ }
|
|
|
+
|
|
|
+ // reset transactional status
|
|
|
+ nft.transactionalStatus = new TransactionalStatusIdle()
|
|
|
+
|
|
|
+ // save NFT
|
|
|
+ await store.save<OwnedNft>(nft)
|
|
|
+}
|
|
|
+
|
|
|
async function getRequiredExistingEntites<Type extends Video | Membership>(
|
|
|
store: DatabaseManager,
|
|
|
entityType: EntityType<Type>,
|
|
@@ -117,17 +163,53 @@ async function getRequiredExistingEntites<Type extends Video | Membership>(
|
|
|
return entities
|
|
|
}
|
|
|
|
|
|
+async function convertContentActor(
|
|
|
+ store: DatabaseManager,
|
|
|
+ contentActor: joystreamTypes.ContentActor
|
|
|
+): Promise<typeof ContentActor> {
|
|
|
+ if (contentActor.isMember) {
|
|
|
+ const memberId = contentActor.asMember.toNumber()
|
|
|
+ const member = await store.get(Membership, { where: { id: memberId.toString() } as FindConditions<Membership> })
|
|
|
+
|
|
|
+ // ensure member exists
|
|
|
+ if (!member) {
|
|
|
+ return inconsistentState(`Actor is non-existing member`, memberId)
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = new ContentActorMember()
|
|
|
+ result.member = member
|
|
|
+
|
|
|
+ return result
|
|
|
+ }
|
|
|
+
|
|
|
+ if (contentActor.isCurator) {
|
|
|
+ const curatorId = contentActor.asCurator[1].toNumber()
|
|
|
+ const curator = await store.get(Curator, {
|
|
|
+ where: { id: curatorId.toString() } as FindConditions<Curator>,
|
|
|
+ })
|
|
|
+
|
|
|
+ // ensure curator group exists
|
|
|
+ if (!curator) {
|
|
|
+ return inconsistentState('Actor is non-existing curator group', curatorId)
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = new ContentActorCurator()
|
|
|
+ result.curator = curator
|
|
|
+
|
|
|
+ return result
|
|
|
+ }
|
|
|
+
|
|
|
+ // contentActor.isLead not supported (not needed) now
|
|
|
+
|
|
|
+ logger.error('Not implemented ContentActor type', { contentActor: contentActor.toString() })
|
|
|
+ throw new Error('Not-implemented ContentActor type used')
|
|
|
+}
|
|
|
+
|
|
|
export async function contentNft_AuctionStarted({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
|
// common event processing
|
|
|
|
|
|
const [ownerId, videoId, auctionParams] = new Content.AuctionStartedEvent(event).params
|
|
|
|
|
|
- const announcingPeriodStartedEvent = new AuctionStartedEvent({
|
|
|
- ...genericEventFields(event),
|
|
|
- })
|
|
|
-
|
|
|
- await store.save<AuctionStartedEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
// specific event processing
|
|
|
|
|
|
// load video
|
|
@@ -135,9 +217,15 @@ export async function contentNft_AuctionStarted({ event, store }: EventContext &
|
|
|
store,
|
|
|
Video,
|
|
|
videoId.toString(),
|
|
|
- `Non-existing video's auction started`
|
|
|
+ `Non-existing video's auction started`,
|
|
|
+ ['nft']
|
|
|
)
|
|
|
|
|
|
+ // ensure NFT has been issued
|
|
|
+ if (!video.nft) {
|
|
|
+ return inconsistentState('Non-existing NFT auctioned', video.id.toString())
|
|
|
+ }
|
|
|
+
|
|
|
// load member
|
|
|
const member = await getRequiredExistingEntity(
|
|
|
store,
|
|
@@ -169,6 +257,29 @@ export async function contentNft_AuctionStarted({ event, store }: EventContext &
|
|
|
|
|
|
// save auction
|
|
|
await store.save<Auction>(auction)
|
|
|
+
|
|
|
+ const transactionalStatus = new TransactionalStatusAuction()
|
|
|
+ transactionalStatus.auction = auction
|
|
|
+
|
|
|
+ video.nft.transactionalStatus = transactionalStatus
|
|
|
+
|
|
|
+ // save NFT
|
|
|
+ await store.save<OwnedNft>(video.nft)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
+
|
|
|
+ const actor = new ContentActorMember()
|
|
|
+ actor.member = new Membership({ id: ownerId.toString() })
|
|
|
+
|
|
|
+ const announcingPeriodStartedEvent = new AuctionStartedEvent({
|
|
|
+ ...genericEventFields(event),
|
|
|
+
|
|
|
+ actor,
|
|
|
+ video,
|
|
|
+ auction,
|
|
|
+ })
|
|
|
+
|
|
|
+ await store.save<AuctionStartedEvent>(announcingPeriodStartedEvent)
|
|
|
}
|
|
|
|
|
|
// create auction type variant from raw runtime auction type
|
|
@@ -198,12 +309,6 @@ export async function contentNft_NftIssued({ event, store }: EventContext & Stor
|
|
|
|
|
|
const [actor, videoId, royalty, metadata, mbNewOwnerId] = new Content.NftIssuedEvent(event).params
|
|
|
|
|
|
- const announcingPeriodStartedEvent = new NftIssuedEvent({
|
|
|
- ...genericEventFields(event),
|
|
|
- })
|
|
|
-
|
|
|
- await store.save<NftIssuedEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
// specific event processing
|
|
|
|
|
|
// load video
|
|
@@ -220,10 +325,25 @@ export async function contentNft_NftIssued({ event, store }: EventContext & Stor
|
|
|
ownerMember: newOwner,
|
|
|
creatorRoyalty,
|
|
|
metadata: metadata.toString(),
|
|
|
+ transactionalStatus: new TransactionalStatusIdle(),
|
|
|
})
|
|
|
|
|
|
// save nft
|
|
|
await store.save<OwnedNft>(ownedNft)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
+
|
|
|
+ const announcingPeriodStartedEvent = new NftIssuedEvent({
|
|
|
+ ...genericEventFields(event),
|
|
|
+
|
|
|
+ contentActor: await convertContentActor(store, actor),
|
|
|
+ video,
|
|
|
+ royalty: creatorRoyalty,
|
|
|
+ metadata: metadata.toString(),
|
|
|
+ newOwner,
|
|
|
+ })
|
|
|
+
|
|
|
+ await store.save<NftIssuedEvent>(announcingPeriodStartedEvent)
|
|
|
}
|
|
|
|
|
|
export async function contentNft_AuctionBidMade({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
@@ -231,12 +351,6 @@ export async function contentNft_AuctionBidMade({ event, store }: EventContext &
|
|
|
|
|
|
const [memberId, videoId, bidAmount, extendsAuction] = new Content.AuctionBidMadeEvent(event).params
|
|
|
|
|
|
- const announcingPeriodStartedEvent = new AuctionBidMadeEvent({
|
|
|
- ...genericEventFields(event),
|
|
|
- })
|
|
|
-
|
|
|
- await store.save<AuctionBidMadeEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
// specific event processing
|
|
|
|
|
|
// load member
|
|
@@ -272,6 +386,19 @@ export async function contentNft_AuctionBidMade({ event, store }: EventContext &
|
|
|
auction.lastBid = bid
|
|
|
|
|
|
await store.save<Auction>(auction)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
+
|
|
|
+ const announcingPeriodStartedEvent = new AuctionBidMadeEvent({
|
|
|
+ ...genericEventFields(event),
|
|
|
+
|
|
|
+ member,
|
|
|
+ video,
|
|
|
+ bidAmount,
|
|
|
+ extendsAuction: extendsAuction.isTrue,
|
|
|
+ })
|
|
|
+
|
|
|
+ await store.save<AuctionBidMadeEvent>(announcingPeriodStartedEvent)
|
|
|
}
|
|
|
|
|
|
export async function contentNft_AuctionBidCanceled({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
@@ -279,12 +406,6 @@ export async function contentNft_AuctionBidCanceled({ event, store }: EventConte
|
|
|
|
|
|
const [memberId, videoId] = new Content.AuctionBidCanceledEvent(event).params
|
|
|
|
|
|
- const announcingPeriodStartedEvent = new AuctionBidCanceledEvent({
|
|
|
- ...genericEventFields(event),
|
|
|
- })
|
|
|
-
|
|
|
- await store.save<AuctionBidCanceledEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
// specific event processing
|
|
|
|
|
|
// load video and auction
|
|
@@ -306,6 +427,17 @@ export async function contentNft_AuctionBidCanceled({ event, store }: EventConte
|
|
|
|
|
|
// save auction
|
|
|
await store.save<Auction>(auction)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
+
|
|
|
+ const announcingPeriodStartedEvent = new AuctionBidCanceledEvent({
|
|
|
+ ...genericEventFields(event),
|
|
|
+
|
|
|
+ member: new Membership({ id: memberId.toString() }),
|
|
|
+ video,
|
|
|
+ })
|
|
|
+
|
|
|
+ await store.save<AuctionBidCanceledEvent>(announcingPeriodStartedEvent)
|
|
|
}
|
|
|
|
|
|
export async function contentNft_AuctionCanceled({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
@@ -313,12 +445,6 @@ export async function contentNft_AuctionCanceled({ event, store }: EventContext
|
|
|
|
|
|
const [contentActor, videoId] = new Content.AuctionCanceledEvent(event).params
|
|
|
|
|
|
- const announcingPeriodStartedEvent = new AuctionCanceledEvent({
|
|
|
- ...genericEventFields(event),
|
|
|
- })
|
|
|
-
|
|
|
- await store.save<AuctionCanceledEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
// specific event processing
|
|
|
|
|
|
// load video and auction
|
|
@@ -329,11 +455,25 @@ export async function contentNft_AuctionCanceled({ event, store }: EventContext
|
|
|
'Non-existing auction got bid canceled'
|
|
|
)
|
|
|
|
|
|
+ // update NFT's transactional status
|
|
|
+ await resetNftTransactionalStatusFromVideo(store, videoId.toString(), `Non-existing NFT's auction canceled`)
|
|
|
+
|
|
|
// mark auction as canceled
|
|
|
auction.isCanceled = true
|
|
|
|
|
|
// save auction
|
|
|
await store.save<Auction>(auction)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
+
|
|
|
+ const announcingPeriodStartedEvent = new AuctionCanceledEvent({
|
|
|
+ ...genericEventFields(event),
|
|
|
+
|
|
|
+ contentActor: await convertContentActor(store, contentActor),
|
|
|
+ video,
|
|
|
+ })
|
|
|
+
|
|
|
+ await store.save<AuctionCanceledEvent>(announcingPeriodStartedEvent)
|
|
|
}
|
|
|
|
|
|
export async function contentNft_EnglishAuctionCompleted({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
@@ -341,12 +481,6 @@ export async function contentNft_EnglishAuctionCompleted({ event, store }: Event
|
|
|
|
|
|
const [memberId, videoId] = new Content.EnglishAuctionCompletedEvent(event).params
|
|
|
|
|
|
- const announcingPeriodStartedEvent = new EnglishAuctionCompletedEvent({
|
|
|
- ...genericEventFields(event),
|
|
|
- })
|
|
|
-
|
|
|
- await store.save<EnglishAuctionCompletedEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
// specific event processing
|
|
|
|
|
|
// load member
|
|
@@ -365,12 +499,26 @@ export async function contentNft_EnglishAuctionCompleted({ event, store }: Event
|
|
|
'Non-existing english-type auction was completed'
|
|
|
)
|
|
|
|
|
|
+ // update NFT's transactional status
|
|
|
+ await resetNftTransactionalStatusFromVideo(store, videoId.toString(), `Non-existing NFT's auction completed`)
|
|
|
+
|
|
|
// update auction
|
|
|
auction.isCompleted = true
|
|
|
auction.winningMember = member
|
|
|
|
|
|
// save auction
|
|
|
await store.save<Auction>(auction)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
+
|
|
|
+ const announcingPeriodStartedEvent = new EnglishAuctionCompletedEvent({
|
|
|
+ ...genericEventFields(event),
|
|
|
+
|
|
|
+ member,
|
|
|
+ video,
|
|
|
+ })
|
|
|
+
|
|
|
+ await store.save<EnglishAuctionCompletedEvent>(announcingPeriodStartedEvent)
|
|
|
}
|
|
|
|
|
|
export async function contentNft_BidMadeCompletingAuction({
|
|
@@ -381,12 +529,6 @@ export async function contentNft_BidMadeCompletingAuction({
|
|
|
|
|
|
const [memberId, videoId] = new Content.BidMadeCompletingAuctionEvent(event).params
|
|
|
|
|
|
- const announcingPeriodStartedEvent = new BidMadeCompletingAuctionEvent({
|
|
|
- ...genericEventFields(event),
|
|
|
- })
|
|
|
-
|
|
|
- await store.save<BidMadeCompletingAuctionEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
// specific event processing
|
|
|
|
|
|
// load member
|
|
@@ -405,110 +547,286 @@ export async function contentNft_BidMadeCompletingAuction({
|
|
|
`Non-existing auction was completed by buy-now bid`
|
|
|
)
|
|
|
|
|
|
+ // update NFT's transactional status
|
|
|
+ await resetNftTransactionalStatusFromVideo(store, videoId.toString(), `Non-existing NFT's auction completed by bid`)
|
|
|
+
|
|
|
// update auction
|
|
|
auction.isCompleted = true
|
|
|
auction.winningMember = member
|
|
|
|
|
|
// save auction
|
|
|
await store.save<Auction>(auction)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
+
|
|
|
+ const announcingPeriodStartedEvent = new BidMadeCompletingAuctionEvent({
|
|
|
+ ...genericEventFields(event),
|
|
|
+
|
|
|
+ member,
|
|
|
+ video,
|
|
|
+ })
|
|
|
+
|
|
|
+ await store.save<BidMadeCompletingAuctionEvent>(announcingPeriodStartedEvent)
|
|
|
}
|
|
|
|
|
|
export async function contentNft_OpenAuctionBidAccepted({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
|
// common event processing
|
|
|
|
|
|
- const [contentActor, video] = new Content.OpenAuctionBidAcceptedEvent(event).params
|
|
|
+ const [contentActor, videoId] = new Content.OpenAuctionBidAcceptedEvent(event).params
|
|
|
+
|
|
|
+ // specific event processing
|
|
|
+
|
|
|
+ // load video and auction
|
|
|
+ const { video, auction } = await getAuctionFromVideo(
|
|
|
+ store,
|
|
|
+ videoId.toString(),
|
|
|
+ `Non-existing video's auction accepted a bid`,
|
|
|
+ `Non-existing auction accepted a bid`
|
|
|
+ )
|
|
|
+
|
|
|
+ // ensure member won the auction (only contentActor allowed)
|
|
|
+ const tmpContentActor = await convertContentActor(store, contentActor)
|
|
|
+ if (!(tmpContentActor instanceof ContentActorMember)) {
|
|
|
+ return unexpectedData(`Unexpected content actor. Only Members allowed here.`)
|
|
|
+ }
|
|
|
+ const member = tmpContentActor.member
|
|
|
+
|
|
|
+ // update NFT's transactional status
|
|
|
+ await resetNftTransactionalStatusFromVideo(store, videoId.toString(), `Non-existing NFT's auction completed by bid`)
|
|
|
+
|
|
|
+ // update auction
|
|
|
+ auction.isCompleted = true
|
|
|
+ auction.winningMember = member
|
|
|
+
|
|
|
+ // save auction
|
|
|
+ await store.save<Auction>(auction)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
|
|
|
const announcingPeriodStartedEvent = new OpenAuctionBidAcceptedEvent({
|
|
|
...genericEventFields(event),
|
|
|
+
|
|
|
+ contentActor: await convertContentActor(store, contentActor),
|
|
|
+ video,
|
|
|
})
|
|
|
|
|
|
await store.save<OpenAuctionBidAcceptedEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
- // specific event processing
|
|
|
-
|
|
|
- // TODO: what exactly should happen here?
|
|
|
}
|
|
|
|
|
|
export async function contentNft_OfferStarted({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
|
// common event processing
|
|
|
|
|
|
- const [video, contentActor, member, price] = new Content.OfferStartedEvent(event).params
|
|
|
+ const [videoId, contentActor, memberId, price] = new Content.OfferStartedEvent(event).params
|
|
|
+
|
|
|
+ // specific event processing
|
|
|
+
|
|
|
+ // load NFT
|
|
|
+ const { video, nft } = await getNftFromVideo(
|
|
|
+ store,
|
|
|
+ videoId.toString(),
|
|
|
+ 'Non-existing video was offered',
|
|
|
+ 'Non-existing nft was offered'
|
|
|
+ )
|
|
|
+
|
|
|
+ // create offer
|
|
|
+ const transactionalStatus = new TransactionalStatusInitiatedOfferToMember()
|
|
|
+ transactionalStatus.memberId = memberId.toNumber()
|
|
|
+ transactionalStatus.price = price.unwrapOr(undefined)
|
|
|
+
|
|
|
+ // update NFT
|
|
|
+ nft.transactionalStatus = transactionalStatus
|
|
|
+
|
|
|
+ // save NFT
|
|
|
+ await store.save<OwnedNft>(nft)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
|
|
|
const announcingPeriodStartedEvent = new OfferStartedEvent({
|
|
|
...genericEventFields(event),
|
|
|
+
|
|
|
+ video,
|
|
|
+ contentActor: await convertContentActor(store, contentActor),
|
|
|
+ member: new Membership({ id: memberId.toString() }),
|
|
|
+ price: price.unwrapOr(undefined),
|
|
|
})
|
|
|
|
|
|
await store.save<OfferStartedEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
- // specific event processing
|
|
|
}
|
|
|
|
|
|
export async function contentNft_OfferAccepted({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
|
// common event processing
|
|
|
|
|
|
- const [video] = new Content.OfferAcceptedEvent(event).params
|
|
|
+ const [videoId] = new Content.OfferAcceptedEvent(event).params
|
|
|
+
|
|
|
+ // specific event processing
|
|
|
+
|
|
|
+ // load NFT
|
|
|
+ const { video, nft } = await getNftFromVideo(
|
|
|
+ store,
|
|
|
+ videoId.toString(),
|
|
|
+ 'Non-existing video sell offer was accepted',
|
|
|
+ 'Non-existing nft sell offer was accepted'
|
|
|
+ )
|
|
|
+
|
|
|
+ // read member from offer
|
|
|
+ const memberId = (nft.transactionalStatus as TransactionalStatusInitiatedOfferToMember).memberId
|
|
|
+ const member = new Membership({ id: memberId.toString() })
|
|
|
+
|
|
|
+ // update NFT
|
|
|
+ nft.transactionalStatus = new TransactionalStatusIdle()
|
|
|
+ nft.ownerMember = member
|
|
|
+
|
|
|
+ // save NFT
|
|
|
+ await store.save<OwnedNft>(nft)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
|
|
|
const announcingPeriodStartedEvent = new OfferAcceptedEvent({
|
|
|
...genericEventFields(event),
|
|
|
+
|
|
|
+ video,
|
|
|
})
|
|
|
|
|
|
await store.save<OfferAcceptedEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
- // specific event processing
|
|
|
}
|
|
|
|
|
|
export async function contentNft_OfferCanceled({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
|
// common event processing
|
|
|
|
|
|
- const [video, contentActor] = new Content.OfferCanceledEvent(event).params
|
|
|
+ const [videoId, contentActor] = new Content.OfferCanceledEvent(event).params
|
|
|
+
|
|
|
+ // specific event processing
|
|
|
+
|
|
|
+ // load NFT
|
|
|
+ const { video, nft } = await getNftFromVideo(
|
|
|
+ store,
|
|
|
+ videoId.toString(),
|
|
|
+ 'Non-existing video sell offer was canceled',
|
|
|
+ 'Non-existing nft sell offer was canceled'
|
|
|
+ )
|
|
|
+
|
|
|
+ // update NFT
|
|
|
+ nft.transactionalStatus = new TransactionalStatusIdle()
|
|
|
+
|
|
|
+ // save NFT
|
|
|
+ await store.save<OwnedNft>(nft)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
|
|
|
const announcingPeriodStartedEvent = new OfferCanceledEvent({
|
|
|
...genericEventFields(event),
|
|
|
+
|
|
|
+ video,
|
|
|
+ contentActor: await convertContentActor(store, contentActor),
|
|
|
})
|
|
|
|
|
|
await store.save<OfferCanceledEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
- // specific event processing
|
|
|
}
|
|
|
|
|
|
export async function contentNft_NftSellOrderMade({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
|
// common event processing
|
|
|
|
|
|
- const [video, contentActor, price] = new Content.NFTSellOrderMadeEvent(event).params
|
|
|
+ const [videoId, contentActor, price] = new Content.NFTSellOrderMadeEvent(event).params
|
|
|
+
|
|
|
+ // specific event processing
|
|
|
+
|
|
|
+ // load NFT
|
|
|
+ const { video, nft } = await getNftFromVideo(
|
|
|
+ store,
|
|
|
+ videoId.toString(),
|
|
|
+ 'Non-existing video was offered',
|
|
|
+ 'Non-existing nft was offered'
|
|
|
+ )
|
|
|
+
|
|
|
+ // create buy now offer
|
|
|
+ const transactionalStatus = new TransactionalStatusBuyNow()
|
|
|
+ transactionalStatus.price = price
|
|
|
+
|
|
|
+ // update NFT
|
|
|
+ nft.transactionalStatus = transactionalStatus
|
|
|
+
|
|
|
+ // save NFT
|
|
|
+ await store.save<OwnedNft>(nft)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
|
|
|
const announcingPeriodStartedEvent = new NftSellOrderMadeEvent({
|
|
|
...genericEventFields(event),
|
|
|
+
|
|
|
+ video,
|
|
|
+ contentActor: await convertContentActor(store, contentActor),
|
|
|
+ price,
|
|
|
})
|
|
|
|
|
|
await store.save<NftSellOrderMadeEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
- // specific event processing
|
|
|
}
|
|
|
|
|
|
export async function contentNft_NftBought({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
|
// common event processing
|
|
|
|
|
|
- const [video, member] = new Content.NFTBoughtEvent(event).params
|
|
|
+ const [videoId, memberId] = new Content.NFTBoughtEvent(event).params
|
|
|
+
|
|
|
+ // specific event processing
|
|
|
+
|
|
|
+ // load NFT
|
|
|
+ const { video, nft } = await getNftFromVideo(
|
|
|
+ store,
|
|
|
+ videoId.toString(),
|
|
|
+ 'Non-existing video was bought',
|
|
|
+ 'Non-existing nft was bought'
|
|
|
+ )
|
|
|
+
|
|
|
+ // read member
|
|
|
+ const member = new Membership({ id: memberId.toString() })
|
|
|
+
|
|
|
+ // update NFT
|
|
|
+ nft.transactionalStatus = new TransactionalStatusIdle()
|
|
|
+ nft.ownerMember = member
|
|
|
+
|
|
|
+ // save NFT
|
|
|
+ await store.save<OwnedNft>(nft)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
|
|
|
const announcingPeriodStartedEvent = new NftBoughtEvent({
|
|
|
...genericEventFields(event),
|
|
|
+
|
|
|
+ video,
|
|
|
+ member,
|
|
|
})
|
|
|
|
|
|
await store.save<NftBoughtEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
- // specific event processing
|
|
|
}
|
|
|
|
|
|
export async function contentNft_BuyNowCanceled({ event, store }: EventContext & StoreContext): Promise<void> {
|
|
|
// common event processing
|
|
|
|
|
|
- const [video, contentActor] = new Content.BuyNowCanceledEvent(event).params
|
|
|
+ const [videoId, contentActor] = new Content.BuyNowCanceledEvent(event).params
|
|
|
+
|
|
|
+ // specific event processing
|
|
|
+
|
|
|
+ // load NFT
|
|
|
+ const { video, nft } = await getNftFromVideo(
|
|
|
+ store,
|
|
|
+ videoId.toString(),
|
|
|
+ 'Non-existing video was bought',
|
|
|
+ 'Non-existing nft was bought'
|
|
|
+ )
|
|
|
+
|
|
|
+ // update NFT
|
|
|
+ nft.transactionalStatus = new TransactionalStatusIdle()
|
|
|
+
|
|
|
+ // save NFT
|
|
|
+ await store.save<OwnedNft>(nft)
|
|
|
+
|
|
|
+ // common event processing - second
|
|
|
|
|
|
const announcingPeriodStartedEvent = new BuyNowCanceledEvent({
|
|
|
...genericEventFields(event),
|
|
|
+
|
|
|
+ video,
|
|
|
+ contentActor: await convertContentActor(store, contentActor),
|
|
|
})
|
|
|
|
|
|
await store.save<BuyNowCanceledEvent>(announcingPeriodStartedEvent)
|
|
|
-
|
|
|
- // specific event processing
|
|
|
}
|