Просмотр исходного кода

Merge pull request #70 from Journeytojah/master

Add MIN_POOL_SIZE environment variable and implement pool size check
Filip Dunđer 1 год назад
Родитель
Сommit
707e79ec21
5 измененных файлов с 40 добавлено и 4 удалено
  1. 2 1
      .env.copy
  2. 3 0
      .gitignore
  3. 2 0
      README.md
  4. 30 2
      buy.ts
  5. 3 1
      constants/constants.ts

+ 2 - 1
.env.copy

@@ -10,4 +10,5 @@ CHECK_IF_MINT_IS_RENOUNCED=false
 AUTO_SELL=true
 MAX_SELL_RETRIES=5
 AUTO_SELL_DELAY=1000
-LOG_LEVEL=info
+LOG_LEVEL=info
+MIN_POOL_SIZE=10

+ 3 - 0
.gitignore

@@ -122,6 +122,9 @@ dist
 # Stores VSCode versions used for testing VSCode extensions
 .vscode-test
 
+# PNPM
+pnpm-lock.yaml
+
 # yarn v2
 .yarn/cache
 .yarn/unplugged

+ 2 - 0
README.md

@@ -23,6 +23,8 @@ To run the script you need to:
   - USE_SNIPE_LIST (buy only tokens listed in snipe-list.txt)
   - SNIPE_LIST_REFRESH_INTERVAL (how often snipe list should be refreshed in milliseconds)
   - CHECK_IF_MINT_IS_RENOUNCED (script will buy only if mint is renounced)
+  - MIN_POOL_SIZE (EXPERIMENTAL) (script will buy only if pool size is greater than specified amount)
+    - set to 0 to disable pool size check
 - Install dependencies by typing: `npm install`
 - Run the script by typing: `npm run buy` in terminal
 

+ 30 - 2
buy.ts

@@ -47,6 +47,7 @@ import {
   RPC_WEBSOCKET_ENDPOINT,
   SNIPE_LIST_REFRESH_INTERVAL,
   USE_SNIPE_LIST,
+  MIN_POOL_SIZE,
 } from './constants';
 
 const solanaConnection = new Connection(RPC_ENDPOINT, {
@@ -58,7 +59,7 @@ export interface MinimalTokenAccountData {
   address: PublicKey;
   poolKeys?: LiquidityPoolKeys;
   market?: MinimalMarketLayoutV3;
-};
+}
 
 const existingLiquidityPools: Set<string> = new Set<string>();
 const existingOpenBookMarkets: Set<string> = new Set<string>();
@@ -68,6 +69,7 @@ let wallet: Keypair;
 let quoteToken: Token;
 let quoteTokenAssociatedAddress: PublicKey;
 let quoteAmount: TokenAmount;
+let quoteMinPoolSizeAmount: TokenAmount;
 
 let snipeList: string[] = [];
 
@@ -83,6 +85,7 @@ async function init(): Promise<void> {
     case 'WSOL': {
       quoteToken = Token.WSOL;
       quoteAmount = new TokenAmount(Token.WSOL, QUOTE_AMOUNT, false);
+      quoteMinPoolSizeAmount = new TokenAmount(quoteToken, MIN_POOL_SIZE, false);
       break;
     }
     case 'USDC': {
@@ -94,6 +97,7 @@ async function init(): Promise<void> {
         'USDC',
       );
       quoteAmount = new TokenAmount(quoteToken, QUOTE_AMOUNT, false);
+      quoteMinPoolSizeAmount = new TokenAmount(quoteToken, MIN_POOL_SIZE, false);
       break;
     }
     default: {
@@ -101,9 +105,14 @@ async function init(): Promise<void> {
     }
   }
 
+  logger.info(`Snipe list: ${USE_SNIPE_LIST}`);
+  logger.info(`Check mint renounced: ${CHECK_IF_MINT_IS_RENOUNCED}`);
   logger.info(
-    `Script will buy all new tokens using ${QUOTE_MINT}. Amount that will be used to buy each token is: ${quoteAmount.toFixed().toString()}`,
+    `Min pool size: ${quoteMinPoolSizeAmount.isZero() ? 'false' : quoteMinPoolSizeAmount.toFixed()} ${quoteToken.symbol}`,
   );
+  logger.info(`Buy amount: ${quoteAmount.toFixed()} ${quoteToken.symbol}`);
+  logger.info(`Auto sell: ${AUTO_SELL}`);
+  logger.info(`Sell delay: ${AUTO_SELL_DELAY === 0 ? 'false' : AUTO_SELL_DELAY}`);
 
   // check existing wallet for associated token account of quote mint
   const tokenAccounts = await getTokenAccounts(solanaConnection, wallet.publicKey, COMMITMENT_LEVEL);
@@ -147,6 +156,23 @@ export async function processRaydiumPool(id: PublicKey, poolState: LiquidityStat
     return;
   }
 
+  if (!quoteMinPoolSizeAmount.isZero()) {
+    const poolSize = new TokenAmount(quoteToken, poolState.swapQuoteInAmount, true);
+    logger.info(`Processing pool: ${id.toString()} with ${poolSize.toFixed()} ${quoteToken.symbol} in liquidity`);
+
+    if (poolSize.lt(quoteMinPoolSizeAmount)) {
+      logger.warn(
+        {
+          mint: poolState.baseMint,
+          pooled: `${poolSize.toFixed()} ${quoteToken.symbol}`,
+        },
+        `Skipping pool, smaller than ${quoteMinPoolSizeAmount.toFixed()} ${quoteToken.symbol}`,
+        `Swap quote in amount: ${poolSize.toFixed()}`,
+      );
+      return;
+    }
+  }
+
   if (CHECK_IF_MINT_IS_RENOUNCED) {
     const mintOption = await checkMintable(poolState.baseMint);
 
@@ -355,6 +381,8 @@ async function sell(accountId: PublicKey, mint: PublicKey, amount: BigNumberish)
       );
       sold = true;
     } catch (e: any) {
+      // wait for a bit before retrying
+      await new Promise((resolve) => setTimeout(resolve, 100));
       retries++;
       logger.debug(e);
       logger.error({ mint }, `Failed to sell token, retry: ${retries}/${MAX_SELL_RETRIES}`);

+ 3 - 1
constants/constants.ts

@@ -14,4 +14,6 @@ export const MAX_SELL_RETRIES = Number(retrieveEnvVariable('MAX_SELL_RETRIES', l
 export const AUTO_SELL_DELAY = Number(retrieveEnvVariable('AUTO_SELL_DELAY', logger));
 export const PRIVATE_KEY = retrieveEnvVariable('PRIVATE_KEY', logger);
 export const QUOTE_MINT = retrieveEnvVariable('QUOTE_MINT', logger);
-export const QUOTE_AMOUNT = retrieveEnvVariable('QUOTE_AMOUNT', logger);
+export const QUOTE_AMOUNT = retrieveEnvVariable('QUOTE_AMOUNT', logger);
+export const MIN_POOL_SIZE = retrieveEnvVariable('MIN_POOL_SIZE', logger);
+