import type { Action, CollectibleApproval, CollectibleBurn, CollectibleMint, CollectibleTrade, CollectibleTransfer, ExchangeLiquidity, ExchangeStaking, ExchangeSwap, MetaverseBurn, MetaverseMint, MetaverseTrade, MetaverseTransfer, SocialComment, SocialDelete, SocialMint, SocialPost, SocialProfile, SocialProxy, SocialRevise, SocialReward, SocialShare, StakeStaking, StakeTransaction, StakerProfitSnapshot, TransactionApproval, TransactionBridge, TransactionBurn, TransactionEvent, TransactionMint, TransactionTransfer, } from "@rss3/api-core"; export function renderItemActionToHTML(actions: Action[]): string | undefined { let joint = ""; let i = 0; for (const action of actions) { const metadata = action.metadata; if (!metadata) { continue; } const { tag } = action; switch (tag) { case "social": joint += renderSocialTagContent(action); break; case "collectible": joint += renderCollectibleTagContent(action); break; case "metaverse": joint += renderMetaverseTagContent(action); break; case "exchange": joint += renderExchange(action); break; case "transaction": joint += renderTransaction(action); break; } if (i < actions.length - 1) joint += "
"; i++; } return joint; } const renderTransaction = (action: Action) => { let joint = ""; const { type } = action; const tag = "transaction"; switch (type) { case "transfer": case "burn": case "mint": case "approval": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ `

Transaction ${ type.toUpperCase().at(0) + type.slice(1) }

`, /* html */ `

Name: ${metadata.name}

`, /* html */ `

Value: ${metadata.value}

`, /* html */ `

Standard: ${metadata.standard}

`, /* html */ `

Symbol: ${metadata.symbol}

`, /* html */ `

Decimals: ${metadata.decimals}

`, /* html */ `

Address: ${metadata.address}

`, ]); break; } case "event": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Transaction Event

", /* html */ `

Block Hash: ${metadata.block.hash}

`, /* html */ `

Transaction Hash: ${metadata.transaction.hash}

`, ]); break; } case "bridge": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Transaction Bridge

", /* html */ `

Action: ${metadata.action}

`, /* html */ `

Source Network: ${metadata.sourceNetwork}

`, /* html */ `

Target Network: ${metadata.targetNetwork}

`, metadata.token && /* html */ `

Token name: ${metadata.token.name}

`, metadata.token && /* html */ `

Token Symbol: ${metadata.token.symbol}

`, metadata.token && /* html */ `

Token Value: ${metadata.token.value}

`, metadata.token && /* html */ `

Token Address: ${metadata.token.address}

`, ]); break; } } return buildSectionFooterHTML(joint, action); }; const renderExchange = (action: Action) => { let joint = ""; const { type } = action; const tag = "exchange"; switch (type) { case "liquidity": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Exchange Liquidity

", /* html */ `

Action: ${metadata.action}

`, /* html */ `

${metadata.tokens.map( (token) => /* html */ ``, )}
Address Value Name Symbol Decimals Standard
${token.address} ${token.value} ${token.name} ${token.symbol} ${token.decimals} ${token.standard}

`, ]); break; } case "staking": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Exchange Liquidity

", /* html */ `

Action: ${metadata.action}

`, metadata.token && /* html */ `

Token:

`, ]); break; } case "swap": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Exchange Swap

", /* html */ metadata.from && `

From: ${metadata.from.address}

`, /* html */ metadata.to && `

To: ${metadata.to?.address}

`, ]); } } return buildSectionFooterHTML(joint, action); }; const renderMetaverseTagContent = (action: Action) => { let joint = ""; const { from, to, type } = action; const tag = "metaverse"; switch (type) { case "burn": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Metaverse Burn

", /* html */ `

Name: ${metadata.name}

`, /* html */ `

Address: ${metadata.address}

`, /* html */ `

Symbol: ${metadata.symbol}

`, /* html */ `

Value: ${metadata.value}

`, /* html */ `

${from} --> ${to}

`, ]); break; } case "trade": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Metaverse Trade

", /* html */ `

Name: ${metadata.name}

`, /* html */ `

Address: ${metadata.address}

`, /* html */ `

Symbol: ${metadata.symbol}

`, /* html */ `

Value: ${metadata.value}

`, /* html */ `

${from} --> ${to}

`, ]); break; } case "mint": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Metaverse Mint

", /* html */ `

Name: ${metadata.name}

`, /* html */ `

Address: ${metadata.address}

`, /* html */ `

Symbol: ${metadata.symbol}

`, /* html */ `

Value: ${metadata.value}

`, /* html */ `

${from} --> ${to}

`, ]); } break; case "transfer": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Metaverse Transfer

", /* html */ `

Name: ${metadata.name}

`, /* html */ `

Address: ${metadata.address}

`, /* html */ `

Symbol: ${metadata.symbol}

`, /* html */ `

Value: ${metadata.value}

`, /* html */ `

${from} --> ${to}

`, ]); } } return buildSectionFooterHTML(joint, action); }; const renderCollectibleTagContent = (action: Action) => { let joint = ""; const { from, to, type } = action; const tag = "collectible"; switch (type) { case "approval": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Collectible Approval

", /* html */ `

Name: ${metadata.name}

`, /* html */ `

Address: ${metadata.address}

`, /* html */ `

Symbol: ${metadata.symbol}

`, /* html */ `

Value: ${metadata.value}

`, /* html */ `

${from} --> ${to}

`, ]); break; } case "burn": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Collectible Burn

", /* html */ `

Name: ${metadata.name}

`, /* html */ `

Address: ${metadata.address}

`, /* html */ `

Symbol: ${metadata.symbol}

`, /* html */ `

Value: ${metadata.value}

`, /* html */ `

${from} --> ${to}

`, ]); break; } case "trade": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Collectible Trade

", /* html */ `

Name: ${metadata.name}

`, /* html */ `

Address: ${metadata.address}

`, /* html */ `

Symbol: ${metadata.symbol}

`, /* html */ `

Value: ${metadata.value}

`, /* html */ `

${from} --> ${to}

`, ]); break; } case "mint": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Collectible Mint

", /* html */ `

Name: ${metadata.name}

`, /* html */ `

Address: ${metadata.address}

`, /* html */ `

Symbol: ${metadata.symbol}

`, /* html */ `

Value: ${metadata.value}

`, /* html */ `

${from} --> ${to}

`, ]); } break; case "transfer": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ "

Collectible Transfer

", /* html */ `

Name: ${metadata.name}

`, /* html */ `

Address: ${metadata.address}

`, /* html */ `

Symbol: ${metadata.symbol}

`, /* html */ `

Value: ${metadata.value}

`, /* html */ `

${from} --> ${to}

`, ]); } } return buildSectionFooterHTML(joint, action); }; const renderSocialTagContent = (action: Action) => { let joint = ""; const { type } = action; const tag = "social"; switch (type) { case "profile": { break; } case "mint": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ `${metadata.handle} mited a post
`, /* html */ metadata.body, ]); break; } case "delete": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ `${metadata.handle} deleted a post
`, ]); break; } case "post": { const metadata = extractMetadata(tag, type, action); if (!metadata || !metadata.body) { break; } joint += metadata.body; break; } case "comment": { const metadata = extractMetadata(tag, type, action); if (!metadata || !metadata.target) { break; } joint += buildHTML([ /* html */ `${metadata.handle} commented on ${metadata.target.handle}'s post
`, /* html */ `
${metadata.target.body}
`, /* html */ `RT: ${metadata.body}`, /* html */ metadata.media ?.map( (media) => ``, ) .join(""), ]); break; } case "reward": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ `${metadata.handle} rewarded a post
`, /* html */ metadata.body, ]); break; } case "revise": { const metadata = extractMetadata(tag, type, action); if (!metadata) { break; } joint += buildHTML([ /* html */ `${metadata.handle} revised a post
`, /* html */ metadata.body, ]); break; } case "proxy": { break; } case "share": { const metadata = extractMetadata(tag, type, action); if (!metadata || !metadata.target) { break; } joint += buildHTML([ /* html */ `${metadata.handle} shared a post by ${metadata.target.handle}
`, /* html */ metadata.target?.body, metadata.target.media ?.map( (media) => ``, ) .join(""), ]); break; } } return joint; }; function extractMetadata( _tag: T1, _type: T2, data: Action, ): GetRSS3DataMetadata | null { const metadata = data.metadata; if (!metadata) { return null; } return data.metadata as GetRSS3DataMetadata; } function buildHTML(arr: (string | boolean | undefined | null)[]): string { return arr.filter(Boolean).join("\n"); } const buildSectionFooterHTML = (string: string, action: Action) => buildHTML([ string, !!action.platform && `

Platform: ${action.platform}

`, /* html */ `

Related URLs:

  • ${action.relatedUrls .map((url) => `${url}`) .join("
  • ")}

`, ]); export type RSS3DataModels = { CollectibleApproval: CollectibleApproval; CollectibleBurn: CollectibleBurn; CollectibleMint: CollectibleMint; CollectibleTrade: CollectibleTrade; CollectibleTransfer: CollectibleTransfer; MetaverseBurn: MetaverseBurn; MetaverseMint: MetaverseMint; MetaverseTrade: MetaverseTrade; MetaverseTransfer: MetaverseTransfer; SocialComment: SocialComment; SocialDelete: SocialDelete; SocialMint: SocialMint; SocialPost: SocialPost; SocialProfile: SocialProfile; SocialProxy: SocialProxy; SocialRevise: SocialRevise; SocialReward: SocialReward; SocialShare: SocialShare; StakeStaking: StakeStaking; StakeTransaction: StakeTransaction; StakerProfitSnapshot: StakerProfitSnapshot; TransactionApproval: TransactionApproval; TransactionBridge: TransactionBridge; TransactionBurn: TransactionBurn; TransactionEvent: TransactionEvent; TransactionMint: TransactionMint; TransactionTransfer: TransactionTransfer; ExchangeLiquidity: ExchangeLiquidity; ExchangeStaking: ExchangeStaking; ExchangeSwap: ExchangeSwap; }; export type GetRSS3DataMetadata< FirstKey extends string, SecondKey extends string, > = `${Capitalize}${Capitalize}` extends keyof RSS3DataModels ? RSS3DataModels[`${Capitalize}${Capitalize}`] : null;