Last active
December 5, 2024 04:20
-
-
Save LionelB5/882415f735153800e3ae61c502925643 to your computer and use it in GitHub Desktop.
find-solana-balance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Find a Solana address matching an arbitrary criteria that is based on: | |
// - Address's last activity | |
// - Balance of the address | |
// | |
// Script is rough and quickly put together, use at your own risk. Intended to be run in a Deno notebook. | |
import { Connection, PublicKey } from "npm:@solana/web3.js@latest"; | |
const RPC_ENDPOINT = "https://api.mainnet-beta.solana.com"; | |
const MIN_BALANCE = 20 * 1e9; // 20 SOL in lamports | |
const INACTIVE_PERIOD = 6 * 30 * 24 * 60 * 60; // 6 months in seconds | |
const connection = new Connection(RPC_ENDPOINT, { | |
fetch: async (url, options) => { | |
let retries = 0; | |
const maxRetries = Infinity; // Set the maximum number of retries you want | |
const retryDelay = 5000; // Delay between retries (in ms) | |
// Loop to retry indefinitely (or maxRetries times) | |
while (retries < maxRetries) { | |
try { | |
// Try making the fetch request | |
const response = await fetch(url, options); | |
if (response.ok) { | |
return response; | |
} else { | |
throw new Error(`Fetch failed with status: ${response.status}`); | |
} | |
} catch (error) { | |
retries++; | |
console.log(`Fetch attempt ${retries} failed: ${error.message}`); | |
if (retries >= maxRetries) { | |
throw new Error('Maximum retries reached'); | |
} | |
// Wait before retrying | |
await new Promise(resolve => setTimeout(resolve, retryDelay)); | |
} | |
} | |
}, | |
}); | |
async function findInactiveAddress(startingSlot) { | |
const minTimestamp = Math.floor(Date.now() / 1000) - INACTIVE_PERIOD; | |
let currentSlot = startingSlot; | |
while (currentSlot > 0) { | |
console.log(`Scanning block: ${currentSlot}`); | |
// Fetch transactions in the current slot | |
const blockData = await connection.getBlock(currentSlot, { | |
maxSupportedTransactionVersion: 0, | |
}); | |
if (!blockData || !blockData.transactions) { | |
console.log(`No transactions in block ${currentSlot}`); | |
currentSlot -= 1; | |
continue; | |
} | |
for (const transaction of blockData.transactions) { | |
if (!Array.isArray(transaction.transaction.message.accountKeys)) { | |
continue; | |
} | |
// Check all accounts involved in the transaction | |
for (const accountKey of transaction.transaction.message.accountKeys) { | |
const publicKey = new PublicKey(accountKey.toString()); | |
// Fetch balance | |
const balance = await connection.getBalance(publicKey); | |
// Skip if balance is less than MIN_BALANCE | |
if (balance < MIN_BALANCE) continue; | |
// Fetch recent transaction history | |
const recentTransactions = await connection.getSignaturesForAddress( | |
publicKey, | |
{ limit: 1 } | |
); | |
const isInactive = recentTransactions.length === 0 || | |
recentTransactions[0].blockTime < minTimestamp; | |
if (isInactive) { | |
console.log(`Found address: ${publicKey.toString()}`); | |
console.log(`Balance: ${balance / 1e9} SOL`); | |
return publicKey.toString(); // Exit once a match is found | |
} | |
} | |
} | |
currentSlot -= 1; // Move to the previous block | |
} | |
console.log("No address found meeting the criteria."); | |
return null; | |
} | |
// Replace this with the starting block number | |
const startingBlock = 204452876; // Example block number | |
await findInactiveAddress(startingBlock) | |
.then((result) => { | |
if (result) { | |
console.log(`Address found: ${result}`); | |
} else { | |
console.log("No suitable address found."); | |
} | |
}) | |
.catch((error) => { | |
console.error("Error occurred:", error); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment