diff --git a/docs/other.md b/docs/other.md
index 1e9fec2ff3..ddc37a0945 100644
--- a/docs/other.md
+++ b/docs/other.md
@@ -109,6 +109,12 @@ pageClass: routes
+## Etherscan
+
+### Etherscan 转账追踪
+
+
+
## Grand-Challenge
### Challenge 列表
diff --git a/lib/router.js b/lib/router.js
index fd2a5aec0b..b97696251e 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -4221,6 +4221,9 @@ router.get('/now/news/rank', lazyloadRouteHandler('./routes/now/rank'));
// s-hentai
router.get('/s-hentai/:id?', lazyloadRouteHandler('./routes/s-hentai'));
+// etherscan
+router.get('/etherscan/transactions/:address', lazyloadRouteHandler('./routes/etherscan/transactions'));
+
// foreverblog
router.get('/blogs/foreverblog', lazyloadRouteHandler('./routes/blogs/foreverblog'));
diff --git a/lib/routes/etherscan/transactions.js b/lib/routes/etherscan/transactions.js
new file mode 100644
index 0000000000..f43eca4664
--- /dev/null
+++ b/lib/routes/etherscan/transactions.js
@@ -0,0 +1,37 @@
+const got = require('@/utils/got');
+const { parseDate } = require('@/utils/parse-date');
+
+module.exports = async (ctx) => {
+ const { address } = ctx.params;
+
+ const response = await got({
+ method: 'get',
+ url: `https://api.etherscan.io/api?module=account&action=txlist&address=${address}&page=1&offset=0&sort=desc`,
+ });
+
+ const list = response.data.result.slice(0, 20);
+
+ ctx.state.data = {
+ title: 'etherscan transactions',
+ link: 'https://etherscan.io/',
+ language: 'en',
+ description: 'ethereum address transactions',
+ item:
+ list &&
+ list.map((item) => {
+ const title = ` TransactionHash: ${item.hash} `;
+ const value = (parseFloat(item.value) / 10 ** 18).toFixed(8);
+ const description = `
+ From: ${item.from}
To: ${item.to}
Value: ${value}
Block: ${item.blockNumber}`;
+ const link = `https://etherscan.io/tx/${item.hash}`;
+
+ return {
+ title,
+ description,
+ link,
+ pubDate: parseDate(item.timestamp),
+ guid: item.hash,
+ };
+ }),
+ };
+};