ETH-Wallet-Monitor
Dies ist ein Content Creation, Multimodal AI-Bereich Automatisierungsworkflow mit 13 Nodes. Hauptsächlich werden Code, Discord, HttpRequest, ScheduleTrigger und andere Nodes verwendet. Tägliche ETH-Wallet-Überwachung mit Etherscan, CoinGecko-Preisen und Discord-Benachrichtigungen
- •Discord Bot Token oder Webhook
- •Möglicherweise sind Ziel-API-Anmeldedaten erforderlich
Verwendete Nodes (13)
Kategorie
{
"meta": {
"instanceId": "105694f414213a0eca348284005921253960bd1b0223294a4970522d0da53055",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "220614c6-c32f-41ba-9669-2532c13a21f6",
"name": "Zeitplan-Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
0,
0
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "45 7,17 * * *"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "2fbe1f25-d09c-43da-933e-6903c6b2155b",
"name": "HTTP-Anfrage",
"type": "n8n-nodes-base.httpRequest",
"position": [
208,
0
],
"parameters": {
"url": "=https://api.etherscan.io/v2/api?chainid=1&module=account&action=tokentx&address=YOUR_WALLET_HERE&sort=asc&apikey=YOUR_KEY_HERE",
"method": "=GET",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "755d4d95-2ff5-4023-8c37-005dc7f3ea69",
"name": "Code in JavaScript",
"type": "n8n-nodes-base.code",
"position": [
416,
0
],
"parameters": {
"jsCode": "// Input: JSON response from Etherscan tokentx endpoint\nconst wallet = \"YOUR_WALLET_ADDRESS\".toLowerCase();\nconst txs = items[0].json.result; // Assuming the HTTP node passed the Etherscan JSON\n\n// Reduce transactions into balances\nconst balances = {};\n\nfor (const tx of txs) {\n const symbol = tx.tokenSymbol;\n const decimals = parseInt(tx.tokenDecimal);\n const value = BigInt(tx.value);\n\n // Initialize token entry if missing\n if (!balances[symbol]) {\n balances[symbol] = {\n contract: tx.contractAddress,\n tokenName: tx.tokenName,\n tokenSymbol: tx.tokenSymbol,\n decimals: decimals,\n raw: BigInt(0)\n };\n }\n\n // If wallet is the recipient => add\n if (tx.to.toLowerCase() === wallet) {\n balances[symbol].raw += value;\n }\n\n // If wallet is the sender => subtract\n if (tx.from.toLowerCase() === wallet) {\n balances[symbol].raw -= value;\n }\n}\n\n// Convert raw balances to human-readable\nconst results = Object.values(balances).map(t => {\n return {\n token: t.tokenSymbol,\n contract: t.contract,\n amount: Number(t.raw) / (10 ** t.decimals),\n decimals: t.decimals\n };\n});\n\n// Return in N8N format\nreturn results.map(r => ({ json: r }));\n"
},
"typeVersion": 2
},
{
"id": "4abe9847-da8e-47a2-ae69-5918545e0cc1",
"name": "Code in JavaScript1",
"type": "n8n-nodes-base.code",
"position": [
624,
0
],
"parameters": {
"jsCode": "const balances = items.map(i => i.json);\n\n// Join all contract addresses into a comma-separated string\nconst contracts = balances.map(b => b.contract).join(',');\n\n// Pass both balances and contracts downstream\nreturn [\n {\n json: {\n balances,\n contracts\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "dd3ca09d-2eb4-45e0-ad0d-dc9c7f093404",
"name": "HTTP-Anfrage1",
"type": "n8n-nodes-base.httpRequest",
"position": [
1456,
0
],
"parameters": {
"url": "=https://api.coingecko.com/api/v3/simple/token_price/ethereum?contract_addresses={{ $('Code in JavaScript1').item.json.contracts }}&vs_currencies=usd",
"options": {},
"jsonHeaders": "{\n \"accept\": \"application/json\",\n \"x-cg-demo-api-key\": \"COIN_GECKO_KEY_HERE\"\n}\n",
"sendHeaders": true,
"specifyHeaders": "json"
},
"typeVersion": 4.2
},
{
"id": "21538827-f180-4012-ac7d-7567da5f251c",
"name": "Code in JavaScript2",
"type": "n8n-nodes-base.code",
"position": [
1664,
0
],
"parameters": {
"jsCode": "// ---- Pull inputs safely ----\nconst erc20 = $node[\"Code in JavaScript1\"].json?.balances ?? [];\nconst eth = $node[\"Code ETH Balance\"].json ?? null;\n\nconst cgTokenPrices = $node[\"HTTP Request1\"].json ?? {}; // { [contract]: { usd } }\nconst ethUsd = $node[\"HTTP Request ETH Price\"].json?.ethereum?.usd ?? 0;\n\n// ---- Combine balances (ETH + ERC-20) ----\nconst balances = eth ? [eth, ...erc20] : [...erc20];\n\n// ---- Build a single price map (token prices + ETH) ----\nconst priceMap = { ...cgTokenPrices };\n// Give ETH a fake \"contract\" key so it matches by contract like the tokens\nconst ETH_KEY = \"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\";\npriceMap[ETH_KEY] = { usd: ethUsd };\n\n// ---- Enrich balances with prices ----\nconst enriched = balances.map(b => {\n const key = (b.contract || \"\").toLowerCase();\n const usdPrice = priceMap[key]?.usd ?? 0;\n const amount = Number(b.amount || 0); // already human-readable amounts\n const usdValue = amount * usdPrice;\n\n return {\n token: b.token,\n contract: b.contract,\n amount,\n usdPrice,\n usdValue,\n };\n}).sort((a, b) => b.usdValue - a.usdValue);\n\n// ---- Totals & quick diagnostics ----\nconst totalUsd = enriched.reduce((s, t) => s + (t.usdValue || 0), 0);\nconst ethLine = enriched.find(t => t.token === \"ETH\");\nconst ethUsdValue = ethLine ? ethLine.usdValue : 0;\nconst restUsd = totalUsd - ethUsdValue;\n\n// ---- Discord message ----\nlet message = `**ETH Wallet Update 💰**\\n\\n`;\nmessage += `**Total Value:** $${totalUsd.toFixed(2)} USD\\n`;\nif (ethLine) {\n message += `• ETH: ${ethLine.amount.toFixed(6)} @ $${(ethLine.usdPrice||0).toFixed(2)} = $${ethUsdValue.toFixed(2)}\\n`;\n message += `• Other tokens (priced): $${restUsd.toFixed(2)}\\n\\n`;\n} else {\n message += `• No ETH price/balance found\\n\\n`;\n}\n\nmessage += enriched\n .filter(t => t.usdValue > 0.01)\n .map(t => `${t.token}: $${t.usdValue.toFixed(2)} (px $${t.usdPrice.toFixed(6)})`)\n .join(\"\\n\");\n\nreturn [{\n json: {\n totalUsd,\n tokens: enriched,\n discordMessage: message\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "a6dffe53-b602-40dc-bd08-87175da21bab",
"name": "Discord",
"type": "n8n-nodes-base.discord",
"position": [
1872,
0
],
"webhookId": "be4e3eba-3fcc-4329-9ba4-4aaea73cdf70",
"parameters": {
"content": "={{ $json.discordMessage }}",
"options": {},
"authentication": "webhook"
},
"credentials": {
"discordWebhookApi": {
"id": "6S341y8tVCvOIO8r",
"name": "All Ops Notis Discord Webhook"
}
},
"typeVersion": 2
},
{
"id": "f01b5fec-fdb8-42a5-9abf-6676a47ca321",
"name": "HTTP-Anfrage ETH",
"type": "n8n-nodes-base.httpRequest",
"position": [
832,
0
],
"parameters": {
"url": "https://api.etherscan.io/v2/api?chainid=1&module=account&action=balance&address=YOUR_WALLET_HERE&apikey=YOUR_KEY_HERE",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "8c0c8162-c9c4-442e-be11-1a8820ce43e4",
"name": "Code ETH Balance",
"type": "n8n-nodes-base.code",
"position": [
1040,
0
],
"parameters": {
"jsCode": "const wei = BigInt($node[\"HTTP Request ETH\"].json.result);\nconst eth = Number(wei) / 1e18;\n\nreturn [{\n json: {\n token: \"ETH\",\n contract: \"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\", // dummy\n amount: eth,\n decimals: 18\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "b7de03cb-f775-4aea-8445-d401ecca2f31",
"name": "HTTP-Anfrage ETH Price",
"type": "n8n-nodes-base.httpRequest",
"position": [
1248,
0
],
"parameters": {
"url": "https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd",
"options": {},
"jsonHeaders": "{\n \"accept\": \"application/json\",\n \"x-cg-demo-api-key\": \"COIN_GEKCO_KEY_HERE\"\n}\n",
"sendHeaders": true,
"specifyHeaders": "json"
},
"typeVersion": 4.2
},
{
"id": "85e8bac4-d42a-4d36-8496-2d1e6d19ea04",
"name": "Haftnotiz",
"type": "n8n-nodes-base.stickyNote",
"position": [
1264,
-160
],
"parameters": {
"height": 96,
"content": "## Set Coin Gecko Keys Here"
},
"typeVersion": 1
},
{
"id": "39647a8d-f10f-4cc2-aefe-1f53d304e59c",
"name": "Haftnotiz1",
"type": "n8n-nodes-base.stickyNote",
"position": [
272,
-240
],
"parameters": {
"height": 192,
"content": "## Add Etherscan API Key to first 2 HTTP nodes. Add Wallet Address to Code Block as well."
},
"typeVersion": 1
},
{
"id": "1b94d811-6947-46a1-b6b7-e928d74b7c73",
"name": "Haftnotiz2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-176,
-288
],
"parameters": {
"height": 256,
"content": "## Daily ETH Wallet Balance sent to Discord. Currently you get two updates. One in the Morning and Evening."
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"HTTP Request": {
"main": [
[
{
"node": "755d4d95-2ff5-4023-8c37-005dc7f3ea69",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request1": {
"main": [
[
{
"node": "21538827-f180-4012-ac7d-7567da5f251c",
"type": "main",
"index": 0
}
]
]
},
"8c0c8162-c9c4-442e-be11-1a8820ce43e4": {
"main": [
[
{
"node": "HTTP Request ETH Price",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request ETH": {
"main": [
[
{
"node": "8c0c8162-c9c4-442e-be11-1a8820ce43e4",
"type": "main",
"index": 0
}
]
]
},
"220614c6-c32f-41ba-9669-2532c13a21f6": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"755d4d95-2ff5-4023-8c37-005dc7f3ea69": {
"main": [
[
{
"node": "4abe9847-da8e-47a2-ae69-5918545e0cc1",
"type": "main",
"index": 0
}
]
]
},
"4abe9847-da8e-47a2-ae69-5918545e0cc1": {
"main": [
[
{
"node": "HTTP Request ETH",
"type": "main",
"index": 0
}
]
]
},
"21538827-f180-4012-ac7d-7567da5f251c": {
"main": [
[
{
"node": "a6dffe53-b602-40dc-bd08-87175da21bab",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request ETH Price": {
"main": [
[
{
"node": "HTTP Request1",
"type": "main",
"index": 0
}
]
]
}
}
}Wie verwende ich diesen Workflow?
Kopieren Sie den obigen JSON-Code, erstellen Sie einen neuen Workflow in Ihrer n8n-Instanz und wählen Sie "Aus JSON importieren". Fügen Sie die Konfiguration ein und passen Sie die Anmeldedaten nach Bedarf an.
Für welche Szenarien ist dieser Workflow geeignet?
Fortgeschritten - Content-Erstellung, Multimodales KI
Ist es kostenpflichtig?
Dieser Workflow ist völlig kostenlos. Beachten Sie jedoch, dass Drittanbieterdienste (wie OpenAI API), die im Workflow verwendet werden, möglicherweise kostenpflichtig sind.
Verwandte Workflows
Kaden Reese
@kadenreeseI started automating with Python in 2020 and still use it in workflows when needed, but I’ve recently leaned into n8n for client-facing solutions. Lately I’ve focused on real estate automations, though I also build workflows for email, scraping, and other use cases. Currently Building 👇🏻
Diesen Workflow teilen