mirror of
https://github.com/fdundjer/solana-sniper-bot.git
synced 2025-11-09 20:12:06 +10:00
138 lines
3.7 KiB
TypeScript
138 lines
3.7 KiB
TypeScript
import { Commitment, Connection, PublicKey } from '@solana/web3.js';
|
|
import {
|
|
Liquidity,
|
|
LIQUIDITY_STATE_LAYOUT_V4,
|
|
LiquidityPoolKeys,
|
|
Market,
|
|
TokenAccount,
|
|
SPL_ACCOUNT_LAYOUT,
|
|
publicKey,
|
|
struct,
|
|
MAINNET_PROGRAM_ID,
|
|
} from '@raydium-io/raydium-sdk';
|
|
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
|
import { USDC_TOKEN_ID } from '../common';
|
|
|
|
export const RAYDIUM_LIQUIDITY_PROGRAM_ID_V4 = MAINNET_PROGRAM_ID.AmmV4;
|
|
export const OPENBOOK_PROGRAM_ID = MAINNET_PROGRAM_ID.OPENBOOK_MARKET;
|
|
|
|
export const MINIMAL_MARKET_STATE_LAYOUT_V3 = struct([
|
|
publicKey('eventQueue'),
|
|
publicKey('bids'),
|
|
publicKey('asks'),
|
|
]);
|
|
|
|
export type MinimalLiquidityAccountData = {
|
|
id: PublicKey;
|
|
version: 4;
|
|
programId: PublicKey;
|
|
};
|
|
|
|
export async function getAllAccountsV4(
|
|
connection: Connection,
|
|
): Promise<MinimalLiquidityAccountData[]> {
|
|
const { span } = LIQUIDITY_STATE_LAYOUT_V4;
|
|
const accounts = await connection.getProgramAccounts(
|
|
RAYDIUM_LIQUIDITY_PROGRAM_ID_V4,
|
|
{
|
|
dataSlice: { offset: 0, length: 0 },
|
|
commitment: 'processed',
|
|
filters: [
|
|
{ dataSize: span },
|
|
{
|
|
memcmp: {
|
|
offset: LIQUIDITY_STATE_LAYOUT_V4.offsetOf('quoteMint'),
|
|
bytes: USDC_TOKEN_ID.toBase58(),
|
|
},
|
|
},
|
|
{
|
|
memcmp: {
|
|
offset: LIQUIDITY_STATE_LAYOUT_V4.offsetOf('marketProgramId'),
|
|
bytes: OPENBOOK_PROGRAM_ID.toBase58(),
|
|
},
|
|
},
|
|
],
|
|
},
|
|
);
|
|
|
|
return accounts.map(
|
|
(info) =>
|
|
<MinimalLiquidityAccountData>{
|
|
id: info.pubkey,
|
|
version: 4,
|
|
programId: RAYDIUM_LIQUIDITY_PROGRAM_ID_V4,
|
|
},
|
|
);
|
|
}
|
|
|
|
export async function getAccountPoolKeysFromAccountDataV4(
|
|
connection: Connection,
|
|
id: PublicKey,
|
|
accountData: any,
|
|
commitment?: Commitment,
|
|
): Promise<LiquidityPoolKeys> {
|
|
const marketInfo = await connection.getAccountInfo(accountData.marketId, {
|
|
commitment: commitment ?? 'processed',
|
|
dataSlice: {
|
|
offset: 253, // eventQueue
|
|
length: 32 * 3,
|
|
},
|
|
});
|
|
|
|
const minimalMarketData = MINIMAL_MARKET_STATE_LAYOUT_V3.decode(
|
|
marketInfo!.data,
|
|
);
|
|
|
|
return {
|
|
id,
|
|
baseMint: accountData.baseMint,
|
|
quoteMint: accountData.quoteMint,
|
|
lpMint: accountData.lpMint,
|
|
baseDecimals: accountData.baseDecimal.toNumber(),
|
|
quoteDecimals: accountData.quoteDecimal.toNumber(),
|
|
lpDecimals: 5,
|
|
version: 4,
|
|
programId: RAYDIUM_LIQUIDITY_PROGRAM_ID_V4,
|
|
authority: Liquidity.getAssociatedAuthority({
|
|
programId: RAYDIUM_LIQUIDITY_PROGRAM_ID_V4,
|
|
}).publicKey,
|
|
openOrders: accountData.openOrders,
|
|
targetOrders: accountData.targetOrders,
|
|
baseVault: accountData.baseVault,
|
|
quoteVault: accountData.quoteVault,
|
|
marketVersion: 3,
|
|
marketProgramId: accountData.marketProgramId,
|
|
marketId: accountData.marketId,
|
|
marketAuthority: Market.getAssociatedAuthority({
|
|
programId: accountData.marketProgramId,
|
|
marketId: accountData.marketId,
|
|
}).publicKey,
|
|
marketBaseVault: accountData.baseVault,
|
|
marketQuoteVault: accountData.quoteVault,
|
|
marketBids: minimalMarketData.bids,
|
|
marketAsks: minimalMarketData.asks,
|
|
marketEventQueue: minimalMarketData.eventQueue,
|
|
withdrawQueue: accountData.withdrawQueue,
|
|
lpVault: accountData.lpVault,
|
|
};
|
|
}
|
|
|
|
export async function getTokenAccounts(
|
|
connection: Connection,
|
|
owner: PublicKey,
|
|
) {
|
|
const tokenResp = await connection.getTokenAccountsByOwner(owner, {
|
|
programId: TOKEN_PROGRAM_ID,
|
|
});
|
|
|
|
const accounts: TokenAccount[] = [];
|
|
for (const { pubkey, account } of tokenResp.value) {
|
|
accounts.push({
|
|
pubkey,
|
|
accountInfo: SPL_ACCOUNT_LAYOUT.decode(account.data),
|
|
});
|
|
}
|
|
|
|
return accounts;
|
|
}
|