mirror of
https://github.com/fdundjer/solana-sniper-bot.git
synced 2025-11-09 20:12:06 +10:00
fix: remove open book cache, improve startup speed
This commit is contained in:
61
buy.ts
61
buy.ts
@ -3,7 +3,6 @@ import {
|
||||
LIQUIDITY_STATE_LAYOUT_V4,
|
||||
LiquidityPoolKeys,
|
||||
LiquidityStateV4,
|
||||
MARKET_STATE_LAYOUT_V2,
|
||||
MARKET_STATE_LAYOUT_V3,
|
||||
MarketStateV3,
|
||||
Token,
|
||||
@ -31,7 +30,7 @@ import {
|
||||
createPoolKeys,
|
||||
} from './liquidity';
|
||||
import { retrieveEnvVariable } from './utils';
|
||||
import { getAllMarketsV3, MinimalMarketLayoutV3 } from './market';
|
||||
import { getMinimalMarketV3, MinimalMarketLayoutV3 } from './market';
|
||||
import pino from 'pino';
|
||||
import bs58 from 'bs58';
|
||||
import * as fs from 'fs';
|
||||
@ -144,17 +143,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()}`,
|
||||
);
|
||||
|
||||
logger.info(`Loading existing markets...`);
|
||||
// get all open-book markets
|
||||
const allMarkets = await getAllMarketsV3(
|
||||
solanaConnection,
|
||||
quoteToken.mint,
|
||||
commitment,
|
||||
);
|
||||
existingOpenBookMarkets = new Set(allMarkets.map((p) => p.id.toString()));
|
||||
logger.info(
|
||||
`Loaded ${existingOpenBookMarkets.size} ${quoteToken.symbol} markets`,
|
||||
);
|
||||
// check existing wallet for associated token account of quote mint
|
||||
const tokenAccounts = await getTokenAccounts(
|
||||
solanaConnection,
|
||||
@ -187,6 +175,21 @@ async function init(): Promise<void> {
|
||||
loadSnipeList();
|
||||
}
|
||||
|
||||
function saveTokenAccount(mint: PublicKey, accountData: MinimalMarketLayoutV3) {
|
||||
const ata = getAssociatedTokenAddressSync(mint, wallet.publicKey);
|
||||
const tokenAccount = <MinimalTokenAccountData>{
|
||||
address: ata,
|
||||
mint: mint,
|
||||
market: <MinimalMarketLayoutV3>{
|
||||
bids: accountData.bids,
|
||||
asks: accountData.asks,
|
||||
eventQueue: accountData.eventQueue,
|
||||
},
|
||||
};
|
||||
existingTokenAccounts.set(mint.toString(), tokenAccount);
|
||||
return tokenAccount;
|
||||
}
|
||||
|
||||
export async function processRaydiumPool(
|
||||
id: PublicKey,
|
||||
poolState: LiquidityStateV4,
|
||||
@ -216,21 +219,7 @@ export async function processOpenBookMarket(
|
||||
return;
|
||||
}
|
||||
|
||||
const ata = getAssociatedTokenAddressSync(
|
||||
accountData.baseMint,
|
||||
wallet.publicKey,
|
||||
);
|
||||
existingTokenAccounts.set(accountData.baseMint.toString(), <
|
||||
MinimalTokenAccountData
|
||||
>{
|
||||
address: ata,
|
||||
mint: accountData.baseMint,
|
||||
market: <MinimalMarketLayoutV3>{
|
||||
bids: accountData.bids,
|
||||
asks: accountData.asks,
|
||||
eventQueue: accountData.eventQueue,
|
||||
},
|
||||
});
|
||||
saveTokenAccount(accountData.baseMint, accountData);
|
||||
} catch (e) {
|
||||
logger.error({ ...accountData, error: e }, `Failed to process market`);
|
||||
}
|
||||
@ -240,12 +229,16 @@ async function buy(
|
||||
accountId: PublicKey,
|
||||
accountData: LiquidityStateV4,
|
||||
): Promise<void> {
|
||||
const tokenAccount = existingTokenAccounts.get(
|
||||
accountData.baseMint.toString(),
|
||||
);
|
||||
let tokenAccount = existingTokenAccounts.get(accountData.baseMint.toString());
|
||||
|
||||
if (!tokenAccount) {
|
||||
return;
|
||||
// it's possible that we didn't have time to fetch open book data
|
||||
const market = await getMinimalMarketV3(
|
||||
solanaConnection,
|
||||
accountData.marketId,
|
||||
commitment,
|
||||
);
|
||||
tokenAccount = saveTokenAccount(accountData.baseMint, market);
|
||||
}
|
||||
|
||||
tokenAccount.poolKeys = createPoolKeys(
|
||||
@ -378,10 +371,10 @@ const runListener = async () => {
|
||||
},
|
||||
commitment,
|
||||
[
|
||||
{ dataSize: MARKET_STATE_LAYOUT_V2.span },
|
||||
{ dataSize: MARKET_STATE_LAYOUT_V3.span },
|
||||
{
|
||||
memcmp: {
|
||||
offset: MARKET_STATE_LAYOUT_V2.offsetOf('quoteMint'),
|
||||
offset: MARKET_STATE_LAYOUT_V3.offsetOf('quoteMint'),
|
||||
bytes: quoteToken.mint.toBase58(),
|
||||
},
|
||||
},
|
||||
|
||||
@ -1,46 +1,23 @@
|
||||
import { Commitment, Connection, PublicKey } from '@solana/web3.js';
|
||||
import {
|
||||
GetStructureSchema,
|
||||
MARKET_STATE_LAYOUT_V3,
|
||||
} from '@raydium-io/raydium-sdk';
|
||||
import {
|
||||
MINIMAL_MARKET_STATE_LAYOUT_V3,
|
||||
OPENBOOK_PROGRAM_ID,
|
||||
} from '../liquidity';
|
||||
import { GetStructureSchema, MARKET_STATE_LAYOUT_V3 } from '@raydium-io/raydium-sdk';
|
||||
import { MINIMAL_MARKET_STATE_LAYOUT_V3 } from '../liquidity';
|
||||
|
||||
export type MinimalOpenBookAccountData = {
|
||||
id: PublicKey;
|
||||
programId: PublicKey;
|
||||
};
|
||||
export type MinimalMarketStateLayoutV3 = typeof MINIMAL_MARKET_STATE_LAYOUT_V3;
|
||||
export type MinimalMarketLayoutV3 =
|
||||
GetStructureSchema<MinimalMarketStateLayoutV3>;
|
||||
|
||||
export async function getAllMarketsV3(
|
||||
export async function getMinimalMarketV3(
|
||||
connection: Connection,
|
||||
quoteMint: PublicKey,
|
||||
marketId: PublicKey,
|
||||
commitment?: Commitment,
|
||||
): Promise<MinimalOpenBookAccountData[]> {
|
||||
const { span } = MARKET_STATE_LAYOUT_V3;
|
||||
const accounts = await connection.getProgramAccounts(OPENBOOK_PROGRAM_ID, {
|
||||
dataSlice: { offset: 0, length: 0 },
|
||||
commitment: commitment,
|
||||
filters: [
|
||||
{ dataSize: span },
|
||||
{
|
||||
memcmp: {
|
||||
offset: MARKET_STATE_LAYOUT_V3.offsetOf('quoteMint'),
|
||||
bytes: quoteMint.toBase58(),
|
||||
},
|
||||
},
|
||||
],
|
||||
): Promise<MinimalMarketLayoutV3> {
|
||||
const marketInfo = await connection.getAccountInfo(marketId, {
|
||||
commitment,
|
||||
dataSlice: {
|
||||
offset: MARKET_STATE_LAYOUT_V3.offsetOf('eventQueue'),
|
||||
length: 32 * 3,
|
||||
},
|
||||
});
|
||||
|
||||
return accounts.map(
|
||||
(info) =>
|
||||
<MinimalOpenBookAccountData>{
|
||||
id: info.pubkey,
|
||||
programId: OPENBOOK_PROGRAM_ID,
|
||||
},
|
||||
);
|
||||
return MINIMAL_MARKET_STATE_LAYOUT_V3.decode(marketInfo!.data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user