New here? If you haven't read Part 1 of this guide, we recommend checking it out first!
Part 1 covers the essential concepts, why sniping bots exist, how Solana bots work, and the architecture we're building. It'll give you the context you need to get the most out of this tutorial.
Already familiar with the concepts? Great! Let’s continue with the implementation.
The Solana sniper bot connects two essential layers into a single automated trading pipeline: a real-time data stream that listens for on-chain events and an execution engine that constructs and submits transactions the instant an opportunity is detected.
The first layer is powered by the Goldrush Streaming API, which delivers push-based event data, pair creations, liquidity additions, and token minting directly from Solana’s runtime without constant polling. The second layer interfaces with the Solana Transaction Instruction APIs to prepare, sign, and dispatch swap transactions through a chosen DEX, such as Raydium or pump.fun, in milliseconds.
While Part 1 explored the theory and architecture behind sniping bots and why speed and determinism matter, this second part takes a practical turn. You’ll set up your environment, configure your wallet, connect to the Solana network, and connect to a streaming endpoint using the Goldrush API to fetch new pairs being added on pump.fun and Raydium.
Node.js v22+ and a package manager (npm, yarn, or pnpm)
Familiarity with TypeScript, WebSockets, and Solana Dex (Raydium, pump.fun)
Wallet that supports Solana (i.e, Phantom)
Goldrush API key for event streaming
RPC providers
Before writing a single line of bot logic, we need a clean development workspace with the right tooling to interact with Solana and Goldrush’s streaming layer.
In your terminal, create a new directory and initialize a Node.js project:
mkdir Solana-bot
cd Solana-bot
npm init -yThis scaffolds a Node environment that we’ll build on.
Next, install the required dependencies:
npm install @covalenthq/client-sdk @solana/spl-token @solana/web3.js ws dotenv
npm install typescript ts-node @types/node --save-devLet’s break down what each of these does:

Once installed, initialize your TypeScript configuration:
npx tsc --initThis generates a tsconfig.json file. You’ll adjust this later to set your module target (ESNext), strict mode, and output directory for compiled JavaScript files.
Finally, create three files in your project directory: bot.ts, constant.ts, and .env. At this stage, your project folder should look like this:

These three files will handle:
bot.ts – the main logic and event listener.
constant.ts – configuration imports and shared constants.
env – your API keys and RPC credentials.
Before the bot can talk to Solana or listen to on-chain events, it needs a few key configuration values. These stay in your .env file.
Create a file named .env in the root of your project and add the following:
# API Keys & Authentication
GOLDRUSH_API_KEY= “Replace with your API key”
PRIVATE_KEY= “Replace with your private Key”
# Solana Network Configuration
RPC_ENDPOINT=https://api.mainnet-beta.solana.com
RPC_WEBSOCKET_ENDPOINT=wss://api.mainnet-beta.solana.com
# DEX Monitoring
MONITORED_DEXES=raydium,pump.fun
# Trading Parameters
QUOTE_MINT=SOL
QUOTE_AMOUNT=0.01
MIN_POOL_SIZE=10
MAX_POOL_SIZE=0
SLIPPAGE_BPS=500
# Safety & Validation
CHECK_IF_MINT_IS_RENOUNCED=true
ONE_TOKEN_AT_A_TIME=false
# Auto-Sell Configuration
AUTO_SELL=true
AUTO_SELL_DELAY=5000
MAX_SELL_RETRIES=5
# Take Profit & Stop Loss
TAKE_PROFIT_PERCENTAGE=0
STOP_LOSS_PERCENTAGE=0
# Logging
LOG_LEVEL=debug
# Bot Mode
DRY_RUN=falseLet’s break down what matters most for this stage:
Tip: For production testing, use a private RPC endpoint to avoid rate limits and latency issues.
To keep your bot modular and maintainable, load all environment variables from a single source.
Create a new file called constant.ts in your project root and add:
import { Commitment } from '@solana/web3.js';
// API Keys & Networks
export const GOLDRUSH_API_KEY = process.env.GOLDRUSH_API_KEY || '';
export const PRIVATE_KEY = process.env.PRIVATE_KEY || '';
export const RPC_ENDPOINT = process.env.RPC_ENDPOINT || 'https://api.mainnet-beta.solana.com';
export const RPC_WEBSOCKET_ENDPOINT = process.env.RPC_WEBSOCKET_ENDPOINT || 'wss://api.mainnet-beta.solana.com';
export const COMMITMENT_LEVEL = 'confirmed' as Commitment;
// Logging
export const LOG_LEVEL = process.env.LOG_LEVEL || 'info';
// Trading Configuration
export const QUOTE_MINT = process.env.QUOTE_MINT || 'SOL';
export const QUOTE_AMOUNT = process.env.QUOTE_AMOUNT ? Number(process.env.QUOTE_AMOUNT) : 0.1;
export const MIN_POOL_SIZE = process.env.MIN_POOL_SIZE ? Number(process.env.MIN_POOL_SIZE) : 0;
export const MAX_POOL_SIZE = process.env.MAX_POOL_SIZE ? Number(process.env.MAX_POOL_SIZE) : 0;
export const SLIPPAGE_BPS = process.env.SLIPPAGE_BPS ? Number(process.env.SLIPPAGE_BPS) : 500; // 5%
// DEX Settings
export const MONITORED_DEXES = (process.env.MONITORED_DEXES || 'raydium,pump.fun').split(',').map(s => s.trim());
// Auto-sell Configuration
export const AUTO_SELL = process.env.AUTO_SELL === 'true';
export const AUTO_SELL_DELAY = process.env.AUTO_SELL_DELAY ? Number(process.env.AUTO_SELL_DELAY) : 30000;
export const MAX_SELL_RETRIES = process.env.MAX_SELL_RETRIES ? Number(process.env.MAX_SELL_RETRIES) : 3;
// Safety Settings
export const CHECK_IF_MINT_IS_RENOUNCED = process.env.CHECK_IF_MINT_IS_RENOUNCED === 'true';
// Add this with your other exports
export const DRY_RUN = process.env.DRY_RUN === 'false' ? false : true;This approach ensures all configuration values are typed, centralized, and fail-safe.
Next, open bot.ts and set up your imports. We’ll start by loading dependencies and defining the configuration structure.
import 'dotenv/config';
import WebSocket from 'ws';
import { GoldRushClient, StreamingChain, StreamingProtocol } from "@covalenthq/client-sdk";
import {
GOLDRUSH_API_KEY,
PRIVATE_KEY,
RPC_ENDPOINT,
RPC_WEBSOCKET_ENDPOINT,
COMMITMENT_LEVEL,
LOG_LEVEL,
QUOTE_MINT,
QUOTE_AMOUNT,
MIN_POOL_SIZE,
MAX_POOL_SIZE,
AUTO_SELL,
AUTO_SELL_DELAY,
MAX_SELL_RETRIES,
MONITORED_DEXES,
CHECK_IF_MINT_IS_RENOUNCED,
SLIPPAGE_BPS,
DRY_RUN,
} from './constant';
import { Connection } from '@solana/web3.js';We’ll also define a few TypeScript interfaces to keep our configuration predictable and clean. These will make the bot easier to extend later when adding trading logic.
interface StreamPair {
pair_address: string;
base_token_metadata: {
contract_ticker_symbol: string;
};
quote_token_metadata: {
contract_ticker_symbol: string;
};
new_liquidity_data: any;
block_signed_at?: string;
}Inside bot.ts, our first task is to initialize the GoldRushClient, the core interface to Covalent’s GoldRush Streaming API. This client connects to a WebSocket endpoint that continuously pushes live on-chain data. In this context, we’ll be listening specifically for new liquidity pair events.
The GoldRush SDK doesn’t assume a WebSocket environment by default. To fix this, we manually bind a global WebSocket instance to ensure compatibility with Node.js:
// Set global WebSocket for the Covalent SDK and Solana connection in Node.js
(global as any).WebSocket = WebSocket;
const goldRushClient = new GoldRushClient(
GOLDRUSH_API_KEY,
({} as any),
{
onConnecting: () => console.log("Connecting to GoldRush Streaming..."),
onOpened: () => console.log(" Connected to GoldRush Streaming!"),
onClosed: () => console.warn(" Disconnected from GoldRush Streaming"),
onError: (error) => console.error("GoldRush Error:", error),
}
);Next, we’ll establish a connection to the Solana blockchain itself using both the JSON RPC and WebSocket endpoints. These allow us to verify token data and monitor live events emitted on-chain.
const solanaConnection = new Connection(RPC_ENDPOINT, {
wsEndpoint: RPC_WEBSOCKET_ENDPOINT,
});
const BOT_START_TIME = Date.now();
let skipFirstBatch = true;
(async () => {
try {
const blockHeight = await solanaConnection.getBlockHeight();
console.log(`Connected to Solana RPC at block height: ${blockHeight}`);
} catch (error) {
console.error("Failed to connect to Solana RPC:", error);
}
})();At this point, if the script runs without throwing any connection or handshake errors, you’re ready; the Solana connection is live and stable.

Now that the environment is stable, we can start listening for new token pair deployments. Using the GoldRush Streaming Client, we subscribe to real-time updates from DEX protocols such as Raydium, Pump.fun, or others supported by Covalent.
function mapToStreamingProtocol(dex: string): StreamingProtocol | undefined {
switch (dex.toLowerCase()) {
case 'raydium':
return StreamingProtocol.RAYDIUM_AMM;
case 'pump.fun':
return StreamingProtocol.PUMP_DOT_FUN;
default:
console.warn(`Unsupported DEX: ${dex}`);
return undefined;
}
}
async function subscribeToNewPairs() {
console.log('Subscribing to new pairs...');
const protocols = MONITORED_DEXES
.map(dex => mapToStreamingProtocol(dex))
.filter((p): p is StreamingProtocol => Boolean(p));
goldRushClient.StreamingService.subscribeToNewPairs(
{
chain_name: StreamingChain.SOLANA_MAINNET,
protocols: protocols,
},
{
next: async (data: any) => {
// Skip initial backlog
if (skipFirstBatch) {
console.log('⏭️ Skipping initial backlog...\n');
skipFirstBatch = false;
return;
}
const pairs: StreamPair[] = Array.isArray(data) ? data : data.newPairs;
if (!pairs?.length) return;
console.log(`Received ${pairs.length} new pair(s):`);
pairs.forEach((pair: StreamPair) => {
// Skip if created before bot started
if (pair.block_signed_at) {
const pairTime = new Date(pair.block_signed_at).getTime();
if (pairTime < BOT_START_TIME) return;
}
console.log(`- ${pair.pair_address} (${pair.base_token_metadata.contract_ticker_symbol}/${pair.quote_token_metadata.contract_ticker_symbol})`);
});
},
error: (err) => console.error('Stream error:', err),
}
);
}
subscribeToNewPairs();This function maps human-readable DEX names (like "raydium") to their SDK-supported enums, then listens for streaming updates. Each time a new pool is deployed, it emits metadata about the pair, including token addresses, symbols, and liquidity data.
Unlike REST APIs, where you’d poll for updates, the GoldRush API uses a push-based model. That means the server automatically sends new data to your bot the instant a new pool is deployed – no polling, no delays. This architecture significantly reduces latency and improves performance for trading bots or memecoin snipers reacting to on-chain events in real time.
Finally, execute the bot using npx ts-node bot.ts.
You should start seeing live logs like:

Each line represents a real-time pool creation event streamed from the GoldRush API. To verify your feed, open pump.fun and check the newly listed pairs. In this guide’s example, we picked up the ESCO/SOL pair, confirming that our connection to both GoldRush and Solana is working as expected.

This shows our code is fetching real-time pairs.
When you run the bot:
It loads all environment variables securely from .env.
Establishes a persistent connection to Solana’s JSON RPC and WebSocket endpoints.
Subscribes to the GoldRush Streaming API, listening for new liquidity pairs from supported DEXes.
Logs each detected event with its token metadata and liquidity from Pump.fun and Raydium.
This means our project is working as expected. The moment a token pair appears on-chain, the bot receives the event in real time.
We’ve now equipped our bot with the ability to detect new pairs as they’re created on our monitored dexes. In Part 3, we’ll expand this to include:
Buy logic and transaction execution.
Automated position management and exit conditions
Test our bot.
Happy building, and see you in Part 3.