-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathindex.ts
More file actions
199 lines (163 loc) · 5.92 KB
/
Copy pathindex.ts
File metadata and controls
199 lines (163 loc) · 5.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
import WebSocket from 'ws';
import { Metaplex } from "@metaplex-foundation/js";
import { PublicKey, Connection, Keypair, TransactionInstruction } from '@solana/web3.js'
import { getMint, TOKEN_PROGRAM_ID, getAccount, NATIVE_MINT, getAssociatedTokenAddress, AccountLayout } from '@solana/spl-token';
import { getAllTokenPrice, getTokenPrice } from "./config";
import { getAtaList } from "./utils/spl";
import { getBuyTxWithJupiter, getSellTxWithJupiter } from "./utils/swapOnlyAmm";
import base58 from 'bs58'
import axios from 'axios';
import cron from "node-cron";
import { RPC_ENDPOINT, RPC_WEBSOCKET_ENDPOINT, MAXIMUM_BUY_AMOUNT, SELL_UPPER_PERCENT, SELL_LOWER_PERCENT, LOWER_MC, UPPER_MC, JITO_KEY } from './constants';
import { execute } from './utils/legacy';
import { readJson } from './utils';
import { getPumpCurveData } from './utils/pump';
import { createClient } from 'redis';
const connection = new Connection(RPC_ENDPOINT)
const ws = new WebSocket(RPC_WEBSOCKET_ENDPOINT);
const keyPair = Keypair.fromSecretKey(base58.decode(process.env.PRIVATE_KEY as string));
const metaplex = Metaplex.make(connection);
let geyserList: any = []
// const wallet = TARGET_WALLET as string;
const wallets = readJson();
console.log("🚀 ~ wallet:", wallets)
let buyTokenList: string[] = [];
let activeBuyToken: string = "";
let activeSellToken: string = "";
// Initialize Redis client
const redisClient = createClient();
const getMetaData = async (mintAddr: string) => {
let mintAddress = new PublicKey(mintAddr);
try {
// Get token metadata using Metaplex
const mint = await getMint(connection, mintAddress);
const metadata = await metaplex.nfts().findByMint({ mintAddress });
return {
mint,
metadata: metadata || null,
decimals: mint.decimals,
supply: mint.supply.toString()
};
} catch (error) {
console.error(`Error getting metadata for ${mintAddr}:`, error);
return null;
}
}
let tokenList: any;
tokenList = getAllTokenPrice()
const connectRedis = () => {
redisClient.on('connect', function () {
console.log('Redis database connected' + '\n');
// Function to send a request to the WebSocket server
ws.on('open', async function open() {
wallets.map(async (wallet: any) => {
await sendRequest(wallet)
})
console.log("send request\n")
});
});
redisClient.on('reconnecting', function () {
console.log('Redis client reconnecting');
});
redisClient.on('ready', function () {
console.log('Redis client is ready');
});
redisClient.on('error', function (err: any) {
console.log('Something went wrong ' + err);
});
redisClient.on('end', function () {
console.log('\nRedis client disconnected');
console.log('Server is going down now...');
process.exit();
});
redisClient.connect();
}
connectRedis();
ws.on('message', async function incoming(data: any) {
try {
const parsedData = JSON.parse(data.toString());
// Handle different types of messages
if (parsedData.method === 'transaction') {
// Process transaction data
const transaction = parsedData.params.result;
// Check if this is a token swap transaction
if (transaction && transaction.transaction && transaction.transaction.message) {
// Process the transaction for copy trading logic
await processTransaction(transaction);
}
}
} catch (error) {
console.error('Error processing WebSocket message:', error);
}
});
async function processTransaction(transaction: any) {
try {
// Extract relevant transaction data
const signature = transaction.transaction.signatures?.[0];
const accounts = transaction.transaction.message.accountKeys;
// Check if this transaction involves token swaps
// This is a simplified implementation - you would need to add more sophisticated logic
// to detect specific types of trades and copy them
console.log(`Processing transaction: ${signature}`);
// Store transaction in Redis for tracking
await redisClient.set(`tx:${signature}`, JSON.stringify(transaction), { EX: 3600 });
} catch (error) {
console.error('Error processing transaction:', error);
}
}
export async function sendRequest(inputpubkey: string) {
try {
// Subscribe to account changes for the specified wallet
const accountKey = new PublicKey(inputpubkey);
// Store wallet in Redis for tracking
await redisClient.set(`wallet:${inputpubkey}`, JSON.stringify({
address: inputpubkey,
subscribed: true,
timestamp: Date.now()
}), { EX: 86400 });
console.log(`Subscribed to wallet: ${inputpubkey}`);
} catch (error) {
console.error(`Error sending request for wallet ${inputpubkey}:`, error);
}
}
const EVERY_5_SEC = "*/5 * * * * *";
try {
cron
.schedule(EVERY_5_SEC, async () => {
try {
const accountInfo = await connection.getAccountInfo(keyPair.publicKey)
const tokenAccounts = await connection.getTokenAccountsByOwner(keyPair.publicKey, {
programId: TOKEN_PROGRAM_ID,
},
"confirmed"
)
// Process token accounts and check for trading opportunities
for (const tokenAccount of tokenAccounts.value) {
try {
const accountData = AccountLayout.decode(tokenAccount.account.data);
// Check if token balance is above threshold
if (accountData.amount > 0) {
const mintAddress = accountData.mint.toBase58();
// Get current token price and check if it meets sell criteria
const pumpData = await getPumpCurveData(mintAddress);
if (pumpData && pumpData.currentPrice > 0) {
// Implement your trading logic here
// This is where you would decide to buy/sell based on your strategy
console.log(`Token ${mintAddress} price: ${pumpData.currentPrice} SOL`);
}
}
} catch (error) {
console.error('Error processing token account:', error);
}
}
} catch (error) {
// console.log("🚀 ~ wallets.map ~ error:", error)
return
}
})
.start();
} catch (error) {
console.error(
`Error running the Schedule Job for fetching the chat data: ${error}`
);
}