diff --git a/lib/routes/rss3/index.ts b/lib/routes/rss3/index.ts
index 49ad4ddd8..820e36c2b 100644
--- a/lib/routes/rss3/index.ts
+++ b/lib/routes/rss3/index.ts
@@ -1,6 +1,10 @@
-import { Route } from '@/types';
+/* eslint-disable default-case */
+import { Route, type DataItem } from '@/types';
+import { camelcaseKeys } from '@/utils/camelcase-keys';
import ofetch from '@/utils/ofetch';
+import type { Action } from '@rss3/sdk';
+import type { GetRSS3DataMetadata } from './interfaces/metadata';
export const route: Route = {
path: '/:account/:network?/:tag?',
@@ -132,17 +136,447 @@ async function handler(ctx) {
return {
title: `${account} activities`,
link: 'https://rss3.io',
- item: data.map((item) => ({
- title: `New ${item.tag} ${item.type} action on ${item.network}`,
- description: `New ${item.tag} ${item.type} action on ${item.network}
From: ${item.from}
To: ${item.to}`,
- link: item.actions?.[0]?.related_urls?.[0],
- guid: item.id,
- author: [
- {
- name: item.owner,
- avatar: `https://cdn.stamp.fyi/avatar/eth:${item.owner}`,
- },
- ],
- })),
+ item: data.map((item) => {
+ const content = parseItemActionToContent(camelcaseKeys(item.actions));
+
+ const description = `New ${item.tag} ${item.type} action on ${item.network}
From: ${item.from}
To: ${item.to}`;
+ return {
+ title: `New ${item.tag} ${item.type} action on ${item.network}`,
+ description: content ? `${description}
${content}` : description,
+ link: item.actions?.[0]?.related_urls?.[0],
+ guid: item.id,
+ author: [
+ {
+ name: item.owner,
+ avatar: `https://cdn.stamp.fyi/avatar/eth:${item.owner}`,
+ },
+ ],
+
+ _extra: { raw: item },
+ } as DataItem;
+ }),
};
}
+
+function parseItemActionToContent(actions: Action[]): string | undefined {
+ if (!actions) {
+ return;
+ }
+
+ let joint = '';
+
+ 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;
+ }
+
+ joint += '
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 */ `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 */ `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 */ `Action: ${metadata.action}
`, + /* html */ `+
| Address | +Value | +Name | +Symbol | +Decimals | +Standard | +
|---|---|---|---|---|---|
| ${token.address} | +${token.value} | +${token.name} | +${token.symbol} | +${token.decimals} | +${token.standard} | +
Action: ${metadata.action}
`, + metadata.token && + /* html */ `+ + Token: +
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 */ `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 */ `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 */ `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 */ `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 */ `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 */ `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 */ `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 */ `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 */ `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 { from, to, platform, type } = action; + const tag = 'social'; + switch (type) { + case 'profile': { + const metadata = extractMetadata(tag, type, action); + if (!metadata) { + break; + } + + joint += buildHTML([ + `Name: ${metadata.name}
`, + `Handle: ${metadata.handle}
`, + `Bio: ${metadata.bio}
`, + `Platform: ${platform}
`, + metadata.imageUri && `Title: ${metadata.title}
`, `${from} --> ${to}
`]); + break; + } + case 'delete': { + const metadata = extractMetadata(tag, type, action); + if (!metadata) { + break; + } + joint += buildHTML([`Title: ${metadata.title}
`]); + break; + } + case 'post': { + const metadata = extractMetadata(tag, type, action); + if (!metadata) { + break; + } + joint += buildHTML([ + /* html*/ `Title: ${metadata.title}
`, + /* html*/ `Author: ${metadata.handle}
`, + /* html*/ `Content:
${metadata.body}`,
+ /* html*/ `Platform: ${platform}
`, + ]); + break; + } + case 'comment': { + const metadata = extractMetadata(tag, type, action); + if (!metadata) { + break; + } + joint += buildHTML([ + /* html*/ `Comment Anchor:${metadata.handle}
`, + metadata.target && /* html*/ `Comment Target: ${metadata.target.title || metadata.targetUrl}
`, + ]); + + break; + } + case 'reward': + case 'revise': + case 'proxy': + case 'share': + break; + } + + return joint; +}; + +function extractMetadataPlatform: ${action.platform}
`, + + /* html */ `Related URLs: +