ASSISTANT
If the tokens you're working with are not listed on CoinGecko but are available on Dexscreener, you'll need to fetch the token prices from Dexscreener instead. Let's adjust your script accordingly to fetch token prices from Dexscreener.
Dexscreener provides endpoint that allow fetching pair data, which includes prices. You'll need to identify the pairs for each token on the relevant DEX.
### Step 1: Determine API Endpoint for Dexscreener
Identify the correct API endpoint to fetch token prices from Dexscreener. Usually, it involves pair information where you can get the price.
### Step 2: Update `fetchTokenPrices` Function
Modify the function to get token prices from Dexscreener API instead of CoinGecko.
Here's an example of how you can adjust the script to fetch prices from Dexscreener:
```js
const axios = require('axios');
const Web3 = require('web3');
const BN = require('bn.js');
// Ethereum RPC endpoint
const ethereumRpcUrl = 'https://mainnet.gateway.tenderly.co';
const web3 = new Web3(new Web3.providers.HttpProvider(ethereumRpcUrl));
// Token configurations and your Telegram bot token and chat ID
const tokens = [
{
name: 'VIVEK',
contractAddress: '0x0C04fF41b11065EEd8c9EDA4d461BA6611591395',
decimals: 9,
dexscreenercoingeckoId: 'ethereum/0x0C04fF41b11065EEd8c9EDA4d461BA6611591395', // Example DEX pair
volumeThreshold: new BN('5000'), // 5000 USD threshold
priceUsd: 0 // Placeholder for TRUTH price in USD
},
{
name: 'blur',
contractAddress: '0x23D17de53aae4A767499A9d8b8C33b5b1C3ebdb0',
decimals: 18,
dexscreenercoingeckoId: 'ethereum/0x23D17de53aae4A767499A9d8b8C33b5b1C3ebdb0', // Example DEX pair
volumeThreshold: new BN('200'), // 200 USD threshold
priceUsd: 0 // Placeholder for BLUR price in USD
},
{
name: 'Flappy',
contractAddress: '0x590246Bfbf89b113D8ac36FaEeA12B7589f7FE5b',
decimals: 9,
dexscreenercoingeckoId: 'ethereum/0x590246Bfbf89b113D8ac36FaEeA12B7589f7FE5b', // Example DEX pair
volumeThreshold: new BN('10000'), // 10,000 USD threshold
priceUsd: 0 // Placeholder for FLAPPY price in USD
},
{
name: 'Draggy',
contractAddress: '0xd12A99dbC40036CEc6f1b776dccd2d36f5953B94',
decimals: 9,
dexscreenercoingeckoId: 'ethereum/0xd12A99dbC40036CEc6f1b776dccd2d36f5953B94', // Example DEX pair
volumeThreshold: new BN('2000'), // 2000 USD threshold
priceUsd: 0 // Placeholder for DRAGGY price in USD
}
];
const telegramBotToken = ''; // Your Telegram bot token
const telegramChatId = ''; // Your Telegram chat ID
const volumeThreshold = 100000; // 100,000 USD threshold
const timeWindow = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
// ERC20 Token Contract ABI (example ERC20 standard ABI)
const erc20Abi = [/* ABIs */];
let buyVolumes = tokens.map(token => ({
name: token.name,
volumes: [],
lastNotificationTime: 0
}));
let lastProcessedBlock = 0;
async function fetchTokenPrices() {
try {
for (const token of tokens) {
const response = await axios.get(`https://api.dexscreener.com/latest/dex/pairs/${token.dexscreenercoingeckoId}`);
if (response.data && response.data.pair && response.data.pair.priceUsd) {
token.priceUsd = parseFloat(response.data.pair.priceUsd);
console.log(`Fetched price for ${token.name}: ${token.priceUsd}`);
} else {
token.priceUsd = 0;
console.warn(`No price data for ${token.name}`);
}
}
} catch (error) {
console.error('Error fetching token prices:', error);
tokens.forEach(token => {
token.priceUsd = 0;
});
}
}
function calculateTotal24HourVolume(tokenName) {
const currentTime = Date.now();
const tokenVolume = buyVolumes.find(volume => volume.name === tokenName);
tokenVolume.volumes = tokenVolume.volumes.filter(vol => currentTime - vol.time <= timeWindow);
const totalVolume = tokenVolume.volumes.reduce((sum, vol) => sum.add(vol.value), new BN(0));
console.log(`Token: ${tokenName}, Volumes: ${tokenVolume.volumes.map(v => v.value.toString())}, Total Volume: ${totalVolume.toString()}`);
return totalVolume;
}
async function getBlockWithRetry(blockNumber) {
const maxRetries = 5;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await web3.eth.getBlock(blockNumber, true);
} catch (error) {
if (attempt === maxRetries) {
throw error;
}
console.error(`Error fetching block ${blockNumber}, attempt ${attempt}:`, error);
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
}
}
}
async function processBlock(blockNumber) {
try {
const block = await getBlockWithRetry(blockNumber);
let newTransfers = [];
for (const tx of block.transactions) {
for (const token of tokens) {
if (tx.to && tx.to.toLowerCase() === token.contractAddress.toLowerCase()) {
try {
const decodedInput = web3.eth.abi.decodeParameters(['address', 'uint256'], tx.input.slice(10));
const tokenAmount = new BN(decodedInput[1]);
const usdValue = tokenAmount.mul(new BN((token.priceUsd * 1e9).toString()))
.div(new BN(10).pow(new BN(token.decimals)));
console.log(`Decoded input for ${token.name}: ${decodedInput[1]}`);
console.log(`Token amount for ${token.name}: ${tokenAmount.toString()}`);
console.log(`USD value for ${token.name}: ${usdValue.toString()}`);
if (usdValue.isZero() || usdValue.gt(new BN('1000000000'))) {
console.warn(`Ignoring suspicious transaction with value: ${usdValue.toString()}`);
continue;
}
const currentTime = Date.now();
const tokenVolume = buyVolumes.find(volume => volume.name === token.name);
tokenVolume.volumes.push({ time: currentTime, value: usdValue });
newTransfers.push({ tokenName: token.name, usdValue: usdValue.toString() });
} catch (error) {
console.error(`Error processing transaction in block ${blockNumber} for ${token.name}:`, error);
}
}
}
}
// Logging new transfers after processing all transactions in the block
for (const transfer of newTransfers) {
console.log(`New transfer in block ${blockNumber} for ${transfer.tokenName}: ${transfer.usdValue} USD`);
}
// Calculating and logging total volume after processing the block
for (const token of tokens) {
const total24HourVolume = calculateTotal24HourVolume(token.name);
console.log(`Total 24-hour volume for ${token.name}: ${total24HourVolume.toString()} USD`);
const tokenVolume = buyVolumes.find(volume => volume.name === token.name);
const currentTime = Date.now();
if (total24HourVolume.gte(token.volumeThreshold) && currentTime - tokenVolume.lastNotificationTime > timeWindow) {
await sendTelegramNotification(`🚀 24-hour volume threshold reached for ${token.name}: ${total24HourVolume.toString()} USD 🚀`);
tokenVolume.lastNotificationTime = currentTime;
}
}
} catch (error) {
console.error(`Error processing block ${blockNumber}:`, error);
}
}
async function sendTelegramNotification(message) {
const telegramApiUrl = `https://api.telegram.org/bot${telegramBotToken}/sendMessage`;
try {
const response = await axios.post(telegramApiUrl, {
chat_id: telegramChatId,
text: message,
});
console.log('Notification sent to Telegram. Response:', response.data);
} catch (error) {
console.error('Error sending notification to Telegram:', error);
if (error.response) {
console.error('Telegram API response:', error.response.data);
}
}
}
async function monitorBlocks() {
try {
const latestBlock = await web3.eth.getBlockNumber();
if (lastProcessedBlock === 0) {
lastProcessedBlock = latestBlock - 1; // Start from the previous block
}
for (let i = lastProcessedBlock + 1; i <= latestBlock; i++) {
await processBlock(i);
lastProcessedBlock = i;
}
} catch (error) {
console.error('Error in monitorBlocks:', error);
}
// Schedule the next check
setTimeout(monitorBlocks, 3000); // Check every 3 seconds
}
// Start monitoring
(async () => {
await fetchTokenPrices();
monitorBlocks();
})();
// Keep the Node.js process running
setInterval(() => {
console.log('Script is still running...');
}, 60000);
process.on('uncaughtException', (error) => {
console.error('Uncaught Exception:', error);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
});
```
### Notes:
- Ensure that the `dexscreenercoingeckoId` represents the correct endpoint for the token price. You'll replace the sample DEX pair IDs with the actual ones for each token.
- This script now connects to Dexscreener’s API to get token prices and parses them in a format similar to CoinGecko.
- Adjust the DEX pair ID to match your specific tokens listed on Dexscreener.
Before running the script, make sure you replace the placeholder values (like DEX pair IDs) with actual values from the Dexscreener.