From f3c0cd565101f6b756700e3adbb0f9fee08be94d Mon Sep 17 00:00:00 2001 From: Thomas Ailleaume Date: Sun, 4 Feb 2024 20:05:43 +0100 Subject: [PATCH 1/6] feat: change getAllLiquidity and GetAllMarket --- liquidity/liquidity.ts | 90 +++++++++++++++++------------------ market/market.ts | 62 ++++++++++++++----------- package-lock.json | 103 ++++++++++++++++++++++++----------------- package.json | 10 ++-- 4 files changed, 145 insertions(+), 120 deletions(-) diff --git a/liquidity/liquidity.ts b/liquidity/liquidity.ts index 6eb7baf..854c1f3 100644 --- a/liquidity/liquidity.ts +++ b/liquidity/liquidity.ts @@ -1,7 +1,6 @@ import { Commitment, Connection, PublicKey } from '@solana/web3.js'; import { Liquidity, - LIQUIDITY_STATE_LAYOUT_V4, LiquidityPoolKeys, Market, TokenAccount, @@ -14,6 +13,25 @@ import { import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { MinimalMarketLayoutV3 } from '../market'; import bs58 from 'bs58'; +import axios from 'axios'; + +interface LiquidityPool { + id: string; + baseMint: string; + quoteMint: string; + // ... autres propriétés +} + +interface LiquidityJsonResponse { + official: LiquidityPool[]; + unOfficial: LiquidityPool[]; +} + +interface MinimalLiquidityAccountData { + id: string; + version: number; + programId: string; +} export const RAYDIUM_LIQUIDITY_PROGRAM_ID_V4 = MAINNET_PROGRAM_ID.AmmV4; export const OPENBOOK_PROGRAM_ID = MAINNET_PROGRAM_ID.OPENBOOK_MARKET; @@ -24,55 +42,31 @@ export const MINIMAL_MARKET_STATE_LAYOUT_V3 = struct([ publicKey('asks'), ]); -export type MinimalLiquidityAccountData = { - id: PublicKey; - version: 4; - programId: PublicKey; -}; - export async function getAllAccountsV4( - connection: Connection, quoteMint: PublicKey, - commitment?: Commitment, -): Promise { - const { span } = LIQUIDITY_STATE_LAYOUT_V4; - const accounts = await connection.getProgramAccounts( - RAYDIUM_LIQUIDITY_PROGRAM_ID_V4, - { - dataSlice: { offset: 0, length: 0 }, - commitment: commitment, - filters: [ - { dataSize: span }, - { - memcmp: { - offset: LIQUIDITY_STATE_LAYOUT_V4.offsetOf('quoteMint'), - bytes: quoteMint.toBase58(), - }, - }, - { - memcmp: { - offset: LIQUIDITY_STATE_LAYOUT_V4.offsetOf('marketProgramId'), - bytes: OPENBOOK_PROGRAM_ID.toBase58(), - }, - }, - { - memcmp: { - offset: LIQUIDITY_STATE_LAYOUT_V4.offsetOf('status'), - bytes: bs58.encode([6, 0, 0, 0, 0, 0, 0, 0]), - }, - }, - ], - }, - ); - - return accounts.map( - (info) => - { - id: info.pubkey, - version: 4, - programId: RAYDIUM_LIQUIDITY_PROGRAM_ID_V4, - }, - ); +): Promise<{ id: string; version: number; programId: PublicKey }[]> { + const url = 'https://api.raydium.io/v2/sdk/liquidity/mainnet.json'; + try { + const response = await axios.get(url); + // @ts-ignore + const json = response.data; + const filteredPools = json.official.concat(json.unOfficial) + .filter(pool => { + if (!pool) { + console.log('Pool undefined:', pool); + return false; + } + return pool.quoteMint && pool.quoteMint === quoteMint.toBase58(); + }); + return filteredPools.map(pool => ({ + id: pool.id, + version: 4, + programId: RAYDIUM_LIQUIDITY_PROGRAM_ID_V4, // Assurez-vous que cette constante est définie + })); + } catch (error) { + console.error('Error during data retrieval:', error); + return []; + } } export function createPoolKeys( diff --git a/market/market.ts b/market/market.ts index bff51f0..b6bf288 100644 --- a/market/market.ts +++ b/market/market.ts @@ -1,12 +1,31 @@ -import { Commitment, Connection, PublicKey } from '@solana/web3.js'; +import {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 axios from 'axios'; + +interface AccountData { + data: string[]; + executable: boolean; + lamports: number; + owner: string; + rentEpoch: number; + space: number; +} + +interface MarketAccount { + account: AccountData; + pubkey: string; +} + +interface JsonResponse { + jsonrpc: string; + result: MarketAccount[]; +} export type MinimalOpenBookAccountData = { id: PublicKey; @@ -17,30 +36,21 @@ export type MinimalMarketLayoutV3 = GetStructureSchema; export async function getAllMarketsV3( - connection: Connection, - quoteMint: PublicKey, - commitment?: Commitment, -): Promise { - 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<{ id: string; programId: PublicKey }[]> { + const url = 'https://cache.prism.ag/openbook.json'; - return accounts.map( - (info) => - { - id: info.pubkey, + try { + const response = await axios.get(url); + // @ts-ignore + const json: JsonResponse = response.data; + + return json.result + .map(account => ({ + id: account.pubkey, programId: OPENBOOK_PROGRAM_ID, - }, - ); + })); + } catch (error) { + console.error('Error during data retrieval:', error); + return []; + } } diff --git a/package-lock.json b/package-lock.json index 91baa92..e6401bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,18 +7,20 @@ "name": "solana-sniper-bot", "dependencies": { "@raydium-io/raydium-sdk": "^1.3.1-beta.47", - "@solana/spl-token": "^0.3.11", + "@solana/spl-token": "^0.4.0", + "@solana/web3.js": "^1.89.1", + "axios": "^1.6.7", "bigint-buffer": "^1.1.5", "bn.js": "^5.2.1", "bs58": "^5.0.0", - "dotenv": "^16.3.2", - "pino": "^8.17.2", + "dotenv": "^16.4.1", + "pino": "^8.18.0", "pino-pretty": "^10.3.1", "pino-std-serializers": "^6.2.2" }, "devDependencies": { "@types/bn.js": "^5.1.5", - "prettier": "^3.2.1", + "prettier": "^3.2.4", "ts-node": "^10.9.2", "typescript": "^5.3.3" } @@ -113,6 +115,23 @@ "@solana/web3.js": "^1.73.0" } }, + "node_modules/@raydium-io/raydium-sdk/node_modules/@solana/spl-token": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.11.tgz", + "integrity": "sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "@solana/spl-token-metadata": "^0.1.2", + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.88.0" + } + }, "node_modules/@solana/buffer-layout": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", @@ -182,9 +201,9 @@ } }, "node_modules/@solana/spl-token": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.11.tgz", - "integrity": "sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.4.0.tgz", + "integrity": "sha512-jjBIBG9IsclqQVl5Y82npGE6utdCh7Z9VFcF5qgJa5EUq2XgspW3Dt1wujWjH/vQDRnkp9zGO+BqQU/HhX/3wg==", "dependencies": { "@solana/buffer-layout": "^4.0.0", "@solana/buffer-layout-utils": "^0.2.0", @@ -195,7 +214,7 @@ "node": ">=16" }, "peerDependencies": { - "@solana/web3.js": "^1.88.0" + "@solana/web3.js": "^1.89.1" } }, "node_modules/@solana/spl-token-metadata": { @@ -229,9 +248,9 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.89.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.89.0.tgz", - "integrity": "sha512-b6PJxNL/DX+J2zccj3kzxZ6HyUF92tc8L9CjMlnTYKCdotAk163ygQ/jbHDT0yYs7pGeXAszyLuaqUXJ8bxwpA==", + "version": "1.89.1", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.89.1.tgz", + "integrity": "sha512-t9TTLtPQxtQB3SAf/5E8xPXfVDsC6WGOsgKY02l2cbe0HLymT7ynE8Hu48Lk5qynHCquj6nhISfEHcjMkYpu/A==", "dependencies": { "@babel/runtime": "^7.23.4", "@noble/curves": "^1.2.0", @@ -266,6 +285,25 @@ "base-x": "^3.0.2" } }, + "node_modules/@solana/web3.js/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -383,9 +421,9 @@ } }, "node_modules/axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { "follow-redirects": "^1.15.4", "form-data": "^4.0.0", @@ -605,9 +643,9 @@ } }, "node_modules/dotenv": { - "version": "16.3.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.2.tgz", - "integrity": "sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==", + "version": "16.4.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", + "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", "engines": { "node": ">=12" }, @@ -880,25 +918,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/node-gyp-build": { "version": "4.8.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", @@ -924,9 +943,9 @@ } }, "node_modules/pino": { - "version": "8.17.2", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.17.2.tgz", - "integrity": "sha512-LA6qKgeDMLr2ux2y/YiUt47EfgQ+S9LznBWOJdN3q1dx2sv0ziDLUBeVpyVv17TEcGCBuWf0zNtg3M5m1NhhWQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.18.0.tgz", + "integrity": "sha512-Mz/gKiRyuXu4HnpHgi1YWdHQCoWMufapzooisvFn78zl4dZciAxS+YeRkUxXl1ee/SzU80YCz1zpECCh4oC6Aw==", "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", @@ -983,9 +1002,9 @@ "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" }, "node_modules/prettier": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.1.tgz", - "integrity": "sha512-qSUWshj1IobVbKc226Gw2pync27t0Kf0EdufZa9j7uBSJay1CC+B3K5lAAZoqgX3ASiKuWsk6OmzKRetXNObWg==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz", + "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" diff --git a/package.json b/package.json index c634a68..cb32719 100644 --- a/package.json +++ b/package.json @@ -6,18 +6,20 @@ }, "dependencies": { "@raydium-io/raydium-sdk": "^1.3.1-beta.47", - "@solana/spl-token": "^0.3.11", + "@solana/spl-token": "^0.4.0", + "@solana/web3.js": "^1.89.1", + "axios": "^1.6.7", "bigint-buffer": "^1.1.5", "bn.js": "^5.2.1", "bs58": "^5.0.0", - "dotenv": "^16.3.2", - "pino": "^8.17.2", + "dotenv": "^16.4.1", + "pino": "^8.18.0", "pino-pretty": "^10.3.1", "pino-std-serializers": "^6.2.2" }, "devDependencies": { "@types/bn.js": "^5.1.5", - "prettier": "^3.2.1", + "prettier": "^3.2.4", "ts-node": "^10.9.2", "typescript": "^5.3.3" } From b7774a5c201d2490c939637ea406ebefdcfe90a1 Mon Sep 17 00:00:00 2001 From: ThomAill Date: Sun, 4 Feb 2024 20:27:58 +0100 Subject: [PATCH 2/6] fix: change call getAllAccountsV4 and getALlMarketsV3 --- buy.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/buy.ts b/buy.ts index 18c2ede..a8e5c97 100644 --- a/buy.ts +++ b/buy.ts @@ -147,20 +147,14 @@ async function init(): Promise { // get all existing liquidity pools const allLiquidityPools = await getAllAccountsV4( - solanaConnection, quoteToken.mint, - commitment, ); existingLiquidityPools = new Set( allLiquidityPools.map((p) => p.id.toString()), ); // get all open-book markets - const allMarkets = await getAllMarketsV3( - solanaConnection, - quoteToken.mint, - commitment, - ); + const allMarkets = await getAllMarketsV3(); existingOpenBookMarkets = new Set(allMarkets.map((p) => p.id.toString())); logger.info( From 0c89f0d5e060e50a8e51686e8588f1b1cfba2bab Mon Sep 17 00:00:00 2001 From: ThomAill Date: Sun, 4 Feb 2024 20:29:13 +0100 Subject: [PATCH 3/6] fix: change call getAllAccountsV4 and getALlMarketsV3 --- buy.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/buy.ts b/buy.ts index a8e5c97..b0a23d2 100644 --- a/buy.ts +++ b/buy.ts @@ -164,6 +164,12 @@ async function init(): Promise { `Total ${quoteToken.symbol} pools ${existingLiquidityPools.size}`, ); + const tokenAccounts = await getTokenAccounts( + solanaConnection, + wallet.publicKey, + commitment, + ); + // check existing wallet for associated token account of quote mint const tokenAccounts = await getTokenAccounts( solanaConnection, From ee3e252de77d55d5e1217d4e944660aa1623feaa Mon Sep 17 00:00:00 2001 From: Filip Dunder Date: Fri, 9 Feb 2024 14:56:18 +0100 Subject: [PATCH 4/6] feat: use pool open time for pool detection --- buy.ts | 52 +++++++++------------ liquidity/liquidity.ts | 100 ----------------------------------------- market/market.ts | 62 +++++++++++-------------- 3 files changed, 47 insertions(+), 167 deletions(-) diff --git a/buy.ts b/buy.ts index b0a23d2..0e08f4f 100644 --- a/buy.ts +++ b/buy.ts @@ -25,7 +25,6 @@ import { Commitment, } from '@solana/web3.js'; import { - getAllAccountsV4, getTokenAccounts, RAYDIUM_LIQUIDITY_PROGRAM_ID_V4, OPENBOOK_PROGRAM_ID, @@ -145,31 +144,17 @@ async function init(): Promise { `Script will buy all new tokens using ${QUOTE_MINT}. Amount that will be used to buy each token is: ${quoteAmount.toFixed().toString()}`, ); - // get all existing liquidity pools - const allLiquidityPools = await getAllAccountsV4( - quoteToken.mint, - ); - existingLiquidityPools = new Set( - allLiquidityPools.map((p) => p.id.toString()), - ); - + logger.info(`Loading existing markets...`); // get all open-book markets - const allMarkets = await getAllMarketsV3(); - existingOpenBookMarkets = new Set(allMarkets.map((p) => p.id.toString())); - - logger.info( - `Total ${quoteToken.symbol} markets ${existingOpenBookMarkets.size}`, - ); - logger.info( - `Total ${quoteToken.symbol} pools ${existingLiquidityPools.size}`, - ); - - const tokenAccounts = await getTokenAccounts( + const allMarkets = await getAllMarketsV3( solanaConnection, - wallet.publicKey, + 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, @@ -202,18 +187,17 @@ async function init(): Promise { loadSnipeList(); } -export async function processRaydiumPool(updatedAccountInfo: KeyedAccountInfo) { +export async function processRaydiumPool( + id: PublicKey, + poolState: LiquidityStateV4, +) { let accountData: LiquidityStateV4 | undefined; try { - accountData = LIQUIDITY_STATE_LAYOUT_V4.decode( - updatedAccountInfo.accountInfo.data, - ); - - if (!shouldBuy(accountData.baseMint.toString())) { + if (!shouldBuy(poolState.baseMint.toString())) { return; } - await buy(updatedAccountInfo.accountId, accountData); + await buy(id, poolState); } catch (e) { logger.error({ ...accountData, error: e }, `Failed to process pool`); } @@ -343,14 +327,20 @@ function shouldBuy(key: string): boolean { const runListener = async () => { await init(); + const runTimestamp = Math.floor(new Date().getTime() / 1000); const raydiumSubscriptionId = solanaConnection.onProgramAccountChange( RAYDIUM_LIQUIDITY_PROGRAM_ID_V4, async (updatedAccountInfo) => { const key = updatedAccountInfo.accountId.toString(); + const poolState = LIQUIDITY_STATE_LAYOUT_V4.decode( + updatedAccountInfo.accountInfo.data, + ); + const poolOpenTime = parseInt(poolState.poolOpenTime.toString()); const existing = existingLiquidityPools.has(key); - if (!existing) { + + if (poolOpenTime > runTimestamp && !existing) { existingLiquidityPools.add(key); - const _ = processRaydiumPool(updatedAccountInfo); + const _ = processRaydiumPool(updatedAccountInfo.accountId, poolState); } }, commitment, diff --git a/liquidity/liquidity.ts b/liquidity/liquidity.ts index 854c1f3..38667a3 100644 --- a/liquidity/liquidity.ts +++ b/liquidity/liquidity.ts @@ -12,26 +12,6 @@ import { } from '@raydium-io/raydium-sdk'; import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { MinimalMarketLayoutV3 } from '../market'; -import bs58 from 'bs58'; -import axios from 'axios'; - -interface LiquidityPool { - id: string; - baseMint: string; - quoteMint: string; - // ... autres propriétés -} - -interface LiquidityJsonResponse { - official: LiquidityPool[]; - unOfficial: LiquidityPool[]; -} - -interface MinimalLiquidityAccountData { - id: string; - version: number; - programId: string; -} export const RAYDIUM_LIQUIDITY_PROGRAM_ID_V4 = MAINNET_PROGRAM_ID.AmmV4; export const OPENBOOK_PROGRAM_ID = MAINNET_PROGRAM_ID.OPENBOOK_MARKET; @@ -42,33 +22,6 @@ export const MINIMAL_MARKET_STATE_LAYOUT_V3 = struct([ publicKey('asks'), ]); -export async function getAllAccountsV4( - quoteMint: PublicKey, -): Promise<{ id: string; version: number; programId: PublicKey }[]> { - const url = 'https://api.raydium.io/v2/sdk/liquidity/mainnet.json'; - try { - const response = await axios.get(url); - // @ts-ignore - const json = response.data; - const filteredPools = json.official.concat(json.unOfficial) - .filter(pool => { - if (!pool) { - console.log('Pool undefined:', pool); - return false; - } - return pool.quoteMint && pool.quoteMint === quoteMint.toBase58(); - }); - return filteredPools.map(pool => ({ - id: pool.id, - version: 4, - programId: RAYDIUM_LIQUIDITY_PROGRAM_ID_V4, // Assurez-vous que cette constante est définie - })); - } catch (error) { - console.error('Error during data retrieval:', error); - return []; - } -} - export function createPoolKeys( id: PublicKey, accountData: LiquidityStateV4, @@ -109,59 +62,6 @@ export function createPoolKeys( }; } -export async function getAccountPoolKeysFromAccountDataV4( - connection: Connection, - id: PublicKey, - accountData: LiquidityStateV4, - commitment?: Commitment, -): Promise { - const marketInfo = await connection.getAccountInfo(accountData.marketId, { - commitment: commitment, - 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, - lookupTableAccount: PublicKey.default, - }; -} - export async function getTokenAccounts( connection: Connection, owner: PublicKey, diff --git a/market/market.ts b/market/market.ts index b6bf288..bff51f0 100644 --- a/market/market.ts +++ b/market/market.ts @@ -1,31 +1,12 @@ -import {PublicKey } from '@solana/web3.js'; +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 axios from 'axios'; - -interface AccountData { - data: string[]; - executable: boolean; - lamports: number; - owner: string; - rentEpoch: number; - space: number; -} - -interface MarketAccount { - account: AccountData; - pubkey: string; -} - -interface JsonResponse { - jsonrpc: string; - result: MarketAccount[]; -} export type MinimalOpenBookAccountData = { id: PublicKey; @@ -36,21 +17,30 @@ export type MinimalMarketLayoutV3 = GetStructureSchema; export async function getAllMarketsV3( -): Promise<{ id: string; programId: PublicKey }[]> { - const url = 'https://cache.prism.ag/openbook.json'; + connection: Connection, + quoteMint: PublicKey, + commitment?: Commitment, +): Promise { + 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(), + }, + }, + ], + }); - try { - const response = await axios.get(url); - // @ts-ignore - const json: JsonResponse = response.data; - - return json.result - .map(account => ({ - id: account.pubkey, + return accounts.map( + (info) => + { + id: info.pubkey, programId: OPENBOOK_PROGRAM_ID, - })); - } catch (error) { - console.error('Error during data retrieval:', error); - return []; - } + }, + ); } From 6228e389c4bae49ed56e53f7f38ff3365b49787e Mon Sep 17 00:00:00 2001 From: Filip Dunder Date: Fri, 9 Feb 2024 14:57:09 +0100 Subject: [PATCH 5/6] fix: initialization issue --- buy.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/buy.ts b/buy.ts index 0e08f4f..fe69c62 100644 --- a/buy.ts +++ b/buy.ts @@ -191,7 +191,6 @@ export async function processRaydiumPool( id: PublicKey, poolState: LiquidityStateV4, ) { - let accountData: LiquidityStateV4 | undefined; try { if (!shouldBuy(poolState.baseMint.toString())) { return; @@ -199,7 +198,7 @@ export async function processRaydiumPool( await buy(id, poolState); } catch (e) { - logger.error({ ...accountData, error: e }, `Failed to process pool`); + logger.error({ ...poolState, error: e }, `Failed to process pool`); } } From 1a6dbf2af99db61850d80ee5ca9678315ec9df49 Mon Sep 17 00:00:00 2001 From: Filip Dunder Date: Fri, 9 Feb 2024 16:42:38 +0100 Subject: [PATCH 6/6] fix: remove axios --- package-lock.json | 1 - package.json | 1 - 2 files changed, 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e6401bd..df907b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "@raydium-io/raydium-sdk": "^1.3.1-beta.47", "@solana/spl-token": "^0.4.0", "@solana/web3.js": "^1.89.1", - "axios": "^1.6.7", "bigint-buffer": "^1.1.5", "bn.js": "^5.2.1", "bs58": "^5.0.0", diff --git a/package.json b/package.json index cb32719..773698a 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "@raydium-io/raydium-sdk": "^1.3.1-beta.47", "@solana/spl-token": "^0.4.0", "@solana/web3.js": "^1.89.1", - "axios": "^1.6.7", "bigint-buffer": "^1.1.5", "bn.js": "^5.2.1", "bs58": "^5.0.0",