mirror of
https://github.com/fdundjer/solana-sniper-bot.git
synced 2025-11-12 07:42:39 +10:00
Add BN.js import and implement sell function
This commit is contained in:
147
buy.ts
147
buy.ts
@ -37,10 +37,11 @@ import pino from 'pino';
|
||||
import bs58 from 'bs58';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import BN from 'bn.js';
|
||||
|
||||
const transport = pino.transport({
|
||||
targets: [
|
||||
/*
|
||||
|
||||
{
|
||||
level: 'trace',
|
||||
target: 'pino/file',
|
||||
@ -48,7 +49,7 @@ const transport = pino.transport({
|
||||
destination: 'buy.log',
|
||||
},
|
||||
},
|
||||
*/
|
||||
|
||||
{
|
||||
level: 'trace',
|
||||
target: 'pino-pretty',
|
||||
@ -145,20 +146,6 @@ async function init(): Promise<void> {
|
||||
`Script will buy all new tokens using ${QUOTE_MINT}. Amount that will be used to buy each token is: ${quoteAmount.toFixed().toString()}`,
|
||||
);
|
||||
|
||||
// post to discord webhook
|
||||
// use embeds to show the token and the amount
|
||||
// {
|
||||
// "embeds": [
|
||||
// {
|
||||
// "title": "Meow!",
|
||||
// "color": 1127128
|
||||
// },
|
||||
// {
|
||||
// "title": "Meow-meow!",
|
||||
// "color": 14177041
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
|
||||
let message = {
|
||||
embeds: [
|
||||
@ -272,6 +259,9 @@ export async function processRaydiumPool(updatedAccountInfo: KeyedAccountInfo) {
|
||||
}
|
||||
|
||||
await buy(updatedAccountInfo.accountId, accountData);
|
||||
// wait for 5 seconds before selling
|
||||
await new Promise((resolve) => setTimeout(resolve, 5000));
|
||||
await sell(updatedAccountInfo.accountId, accountData);
|
||||
} catch (e) {
|
||||
logger.error({ ...accountData, error: e }, `Failed to process pool`);
|
||||
}
|
||||
@ -399,6 +389,131 @@ async function buy(
|
||||
});
|
||||
}
|
||||
|
||||
const maxRetries = 60;
|
||||
async function sell(
|
||||
accountId: PublicKey,
|
||||
accountData: LiquidityStateV4,
|
||||
): Promise<void> {
|
||||
const tokenAccount = existingTokenAccounts.get(
|
||||
accountData.baseMint.toString(),
|
||||
);
|
||||
|
||||
if (!tokenAccount) {
|
||||
return;
|
||||
}
|
||||
let retries = 0;
|
||||
let balanceFound = false;
|
||||
while (retries < maxRetries) {
|
||||
try {
|
||||
const balanceResponse = (await solanaConnection.getTokenAccountBalance(tokenAccount.address)).value.amount;
|
||||
if (balanceResponse !== null && Number(balanceResponse) > 0 && !balanceFound) {
|
||||
balanceFound = true;
|
||||
console.log("Token balance: ", balanceResponse);
|
||||
// send to discord
|
||||
const tokenBalanceMessage = {
|
||||
embeds: [
|
||||
{
|
||||
title: `Token balance: ${balanceResponse}`,
|
||||
color: 1127128,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger);
|
||||
// use native fetch to post to discord
|
||||
fetch(DISCORD_WEBHOOK, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(tokenBalanceMessage),
|
||||
});
|
||||
|
||||
tokenAccount.poolKeys = createPoolKeys(
|
||||
accountId,
|
||||
accountData,
|
||||
tokenAccount.market!,
|
||||
);
|
||||
const { innerTransaction, address } = Liquidity.makeSwapFixedInInstruction(
|
||||
{
|
||||
poolKeys: tokenAccount.poolKeys,
|
||||
userKeys: {
|
||||
tokenAccountIn: tokenAccount.address,
|
||||
tokenAccountOut: quoteTokenAssociatedAddress,
|
||||
owner: wallet.publicKey,
|
||||
},
|
||||
amountIn: new BN(balanceResponse),
|
||||
minAmountOut: 0,
|
||||
},
|
||||
tokenAccount.poolKeys.version,
|
||||
);
|
||||
|
||||
const latestBlockhash = await solanaConnection.getLatestBlockhash({
|
||||
commitment: commitment,
|
||||
});
|
||||
const messageV0 = new TransactionMessage({
|
||||
payerKey: wallet.publicKey,
|
||||
recentBlockhash: latestBlockhash.blockhash,
|
||||
instructions: [
|
||||
ComputeBudgetProgram.setComputeUnitLimit({ units: 400000 }),
|
||||
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 200000 }),
|
||||
createAssociatedTokenAccountIdempotentInstruction(
|
||||
wallet.publicKey,
|
||||
tokenAccount.address,
|
||||
wallet.publicKey,
|
||||
accountData.baseMint,
|
||||
),
|
||||
...innerTransaction.instructions,
|
||||
],
|
||||
}).compileToV0Message();
|
||||
const transaction = new VersionedTransaction(messageV0);
|
||||
transaction.sign([wallet, ...innerTransaction.signers]);
|
||||
const signature = await solanaConnection.sendRawTransaction(
|
||||
transaction.serialize(),
|
||||
{
|
||||
maxRetries: 5,
|
||||
preflightCommitment: commitment,
|
||||
},
|
||||
);
|
||||
logger.info(
|
||||
{
|
||||
mint: accountData.baseMint,
|
||||
url: `https://solscan.io/tx/${signature}?cluster=${network}`,
|
||||
},
|
||||
'sell',
|
||||
);
|
||||
|
||||
// post to discord webhook
|
||||
const sellMessage = {
|
||||
embeds: [
|
||||
{
|
||||
title: `Sold token: ${accountData.baseMint.toBase58()}`,
|
||||
color: 1127128,
|
||||
url: `https://solscan.io/tx/${signature}?cluster=${network}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger);
|
||||
// use native fetch to post to discord
|
||||
fetch(DISCORD_WEBHOOK, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(sellMessage),
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
}
|
||||
retries++;
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function loadSnipeList() {
|
||||
if (!USE_SNIPE_LIST) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user