Skip to content

Commit

Permalink
stream-metadata: add eventId to space image url to cache bust on open…
Browse files Browse the repository at this point in the history
…sea (#1284)

Co-authored-by: texuf <[email protected]>
  • Loading branch information
miguel-nascimento and texuf authored Oct 18, 2024
1 parent e34492d commit 11711ad
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 11 deletions.
8 changes: 4 additions & 4 deletions packages/sdk/src/streamStateView_Space.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class StreamStateView_Space extends StreamStateView_AbstractContent {
readonly streamId: string
readonly spaceChannelsMetadata = new Map<string, ParsedChannelProperties>()
private spaceImage: ChunkedMedia | undefined
private encryptedSpaceImage: EncryptedData | undefined
public encryptedSpaceImage: { eventId: string; data: EncryptedData } | undefined
private decryptionInProgress:
| { encryptedData: EncryptedData; promise: Promise<ChunkedMedia | undefined> }
| undefined
Expand All @@ -55,7 +55,7 @@ export class StreamStateView_Space extends StreamStateView_AbstractContent {
}

if (content.spaceImage?.data) {
this.encryptedSpaceImage = content.spaceImage.data
this.encryptedSpaceImage = { data: content.spaceImage.data, eventId: eventHash }
}
}

Expand Down Expand Up @@ -125,7 +125,7 @@ export class StreamStateView_Space extends StreamStateView_AbstractContent {
)
break
case 'spaceImage':
this.encryptedSpaceImage = payload.content.value
this.encryptedSpaceImage = { data: payload.content.value, eventId: event.hashStr }
stateEmitter?.emit('spaceImageUpdated', this.streamId)
break
case undefined:
Expand All @@ -138,7 +138,7 @@ export class StreamStateView_Space extends StreamStateView_AbstractContent {
public async getSpaceImage(): Promise<ChunkedMedia | undefined> {
// if we have an encrypted space image, decrypt it
if (this.encryptedSpaceImage) {
const encryptedData = this.encryptedSpaceImage
const encryptedData = this.encryptedSpaceImage?.data
this.encryptedSpaceImage = undefined
this.decryptionInProgress = {
promise: this.decryptSpaceImage(encryptedData),
Expand Down
1 change: 1 addition & 0 deletions packages/stream-metadata/src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export function setupRoutes(srv: Server) {
srv.get('/media/:mediaStreamId', fetchMedia)
srv.get('/user/:userId/image', fetchUserProfileImage)
srv.get('/space/:spaceAddress/image', fetchSpaceImage)
srv.get('/space/:spaceAddress/image/:eventId', fetchSpaceImage)
srv.get('/space/:spaceAddress', fetchSpaceMetadata)
srv.get('/space/:spaceAddress/token/:tokenId', fetchSpaceMemberMetadata)
srv.get('/user/:userId/bio', fetchUserBio)
Expand Down
5 changes: 3 additions & 2 deletions packages/stream-metadata/src/routes/spaceImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const paramsSchema = z.object({
.refine(isValidEthereumAddress, {
message: 'Invalid spaceAddress format',
}),
eventId: z.string().optional(),
})

const CACHE_CONTROL = {
Expand All @@ -40,8 +41,8 @@ export async function fetchSpaceImage(request: FastifyRequest, reply: FastifyRep
.send({ error: 'Bad Request', message: errorMessage })
}

const { spaceAddress } = parseResult.data
logger.info({ spaceAddress }, 'Fetching space image')
const { spaceAddress, eventId } = parseResult.data
logger.info({ spaceAddress, eventId }, 'Fetching space image')

let stream: StreamStateView
try {
Expand Down
23 changes: 20 additions & 3 deletions packages/stream-metadata/src/routes/spaceMemberMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { FastifyReply, FastifyRequest } from 'fastify'
import { FastifyReply, FastifyRequest, type FastifyBaseLogger } from 'fastify'
import { z } from 'zod'
import { StreamPrefix, makeStreamId } from '@river-build/sdk'

import { config } from '../environment'
import { isValidEthereumAddress } from '../validators'
import { spaceDapp } from '../contract-utils'
import { getStream } from '../riverStreamRpcClient'

const paramsSchema = z.object({
spaceAddress: z
Expand Down Expand Up @@ -46,7 +48,7 @@ export async function fetchSpaceMemberMetadata(request: FastifyRequest, reply: F
const { spaceAddress, tokenId } = parseResult.data

try {
const metadata = await getSpaceMemberMetadata(spaceAddress, tokenId)
const metadata = await getSpaceMemberMetadata(logger, spaceAddress, tokenId)
return reply
.header('Content-Type', 'application/json')
.header('Cache-Control', CACHE_CONTROL[200])
Expand All @@ -61,6 +63,7 @@ export async function fetchSpaceMemberMetadata(request: FastifyRequest, reply: F
}

const getSpaceMemberMetadata = async (
logger: FastifyBaseLogger,
spaceAddress: string,
tokenId: string,
): Promise<SpaceMemberMetadataResponse> => {
Expand All @@ -69,6 +72,20 @@ const getSpaceMemberMetadata = async (
throw new Error('Space contract not found')
}

let imageEventId: string = 'default'
try {
const streamId = makeStreamId(StreamPrefix.Space, spaceAddress)
const streamView = await getStream(logger, streamId)
if (
streamView.contentKind === 'spaceContent' &&
streamView.spaceContent.encryptedSpaceImage?.eventId
) {
imageEventId = streamView.spaceContent.encryptedSpaceImage.eventId
}
} catch (error) {
// no-op
}

const [name, renewalPrice, membershipExpiration, isBanned] = await Promise.all([
space.SpaceOwner.read.getSpaceInfo(spaceAddress).then((spaceInfo) => spaceInfo.name),
space.Membership.read.getMembershipRenewalPrice(tokenId),
Expand All @@ -79,7 +96,7 @@ const getSpaceMemberMetadata = async (
return {
name: `${name} - Member`,
description: `Member of ${name}`,
image: `${config.streamMetadataBaseUrl}/space/${spaceAddress}/image`,
image: `${config.streamMetadataBaseUrl}/space/${spaceAddress}/image/${imageEventId}`,
attributes: [
{
trait_type: 'Renewal Price',
Expand Down
18 changes: 17 additions & 1 deletion packages/stream-metadata/src/routes/spaceMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { FastifyReply, FastifyRequest } from 'fastify'
import { SpaceInfo } from '@river-build/web3'
import { z } from 'zod'
import { makeStreamId, StreamPrefix } from '@river-build/sdk'

import { config } from '../environment'
import { isValidEthereumAddress } from '../validators'
import { spaceDapp } from '../contract-utils'
import { getStream } from '../riverStreamRpcClient'

export const spaceMetadataBaseUrl = `${config.streamMetadataBaseUrl}/space`.toLowerCase()

Expand Down Expand Up @@ -67,10 +69,24 @@ export async function fetchSpaceMetadata(request: FastifyRequest, reply: Fastify
.send({ error: 'Not Found', message: 'Space contract not found' })
}

let imageEventId: string = 'default'
try {
const streamId = makeStreamId(StreamPrefix.Space, spaceAddress)
const streamView = await getStream(logger, streamId)
if (
streamView.contentKind === 'spaceContent' &&
streamView.spaceContent.encryptedSpaceImage?.eventId
) {
imageEventId = streamView.spaceContent.encryptedSpaceImage.eventId
}
} catch (error) {
// no-op
}

// Normalize the contractUri for case-insensitive comparison and handle empty string
const defaultSpaceTokenUri = `${spaceMetadataBaseUrl}/${spaceAddress}`

const image = `${defaultSpaceTokenUri}/image`
const image = `${defaultSpaceTokenUri}/image/${imageEventId}`
const spaceMetadata: SpaceMetadataResponse = {
name: spaceInfo.name,
description: getSpaceDecription(spaceInfo),
Expand Down
2 changes: 1 addition & 1 deletion packages/stream-metadata/src/routes/spaceRefresh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export async function spaceRefreshOnResponse(

try {
await CloudfrontManager.createCloudfrontInvalidation({
paths: [`/space/${spaceAddress}/image`],
paths: [`/space/${spaceAddress}/image*`],
logger,
waitUntilFinished: true,
})
Expand Down

0 comments on commit 11711ad

Please sign in to comment.