1

Could anyone give an example of python code that swaps on raydium?

Without having to make requests to the API: https://api.raydium.io/v2/sdk/liquidity/mainnet.json

Because the above request takes a long time to serialize the response

1 Answer 1

1

user kokiez did have some python code published on github that did a raydium swap all in python but I haven't been able to find it since.

The way I had solved this is I wrote all the code in typescript and then used a websocket to send the parameters from python to the typescript functions.

This could be helpful to get started for the code to swap on raydium: https://github.com/precious-void/raydium-swap

And regarding the pool keys, I have found two ways to get it reliably:

  1. FalconHit API ( costs 0.12 SOL per month): https://docs.valguibs.com/
  2. Using typescript to get the pool keys almost instantly only requiring the input and output token addresses. I had used some inspiration from this post. Here is what the code somewhat looks like:
import { PublicKey, Commitment, Connection } from '@solana/web3.js'
import {
  LIQUIDITY_STATE_LAYOUT_V4,
  Liquidity,
  LiquidityPoolKeysV4,
  MARKET_STATE_LAYOUT_V3,
  Market,
  SPL_MINT_LAYOUT
} from '@raydium-io/raydium-sdk'
import dotenv from 'dotenv';
dotenv.config()

// const rpcCon = new Connection(process.env.WEB3_SOL_PROVIDER, { commitment: 'finalized' })

async function getPoolKeys(connection: Connection, base: PublicKey, quote: PublicKey, commitment: Commitment = 'finalized') {
    const rsp = await fetchMarketAccounts(connection, base, quote, commitment)
    const poolKeys = await formatAmmKeysById(rsp[0].id, connection)
    return poolKeys
}
  
async function formatAmmKeysById(id: string, connection: Connection): Promise<LiquidityPoolKeysV4> {
    const account = await connection.getAccountInfo(new PublicKey(id))
    if (account === null) throw Error(' get id info error ')
    const info = LIQUIDITY_STATE_LAYOUT_V4.decode(account.data)

    const marketId = info.marketId
    const marketAccount = await connection.getAccountInfo(marketId)
    if (marketAccount === null) throw Error(' get market info error')
    const marketInfo = MARKET_STATE_LAYOUT_V3.decode(marketAccount.data)

    const lpMint = info.lpMint
    const lpMintAccount = await connection.getAccountInfo(lpMint)
    if (lpMintAccount === null) throw Error(' get lp mint info error')
    const lpMintInfo = SPL_MINT_LAYOUT.decode(lpMintAccount.data)

    return {
        id: new PublicKey(id),
        baseMint: info.baseMint,
        quoteMint: info.quoteMint,
        lpMint: info.lpMint,
        baseDecimals: info.baseDecimal.toNumber(),
        quoteDecimals: info.quoteDecimal.toNumber(),
        lpDecimals: lpMintInfo.decimals,
        version: 4,
        programId: account.owner,
        authority: Liquidity.getAssociatedAuthority({ programId: account.owner }).publicKey,
        openOrders: info.openOrders,
        targetOrders: info.targetOrders,
        baseVault: info.baseVault,
        quoteVault: info.quoteVault,
        withdrawQueue: info.withdrawQueue,
        lpVault: info.lpVault,
        marketVersion: 3,
        marketProgramId: info.marketProgramId,
        marketId: info.marketId,
        marketAuthority: Market.getAssociatedAuthority({ programId: info.marketProgramId, marketId: info.marketId }).publicKey,
        marketBaseVault: marketInfo.baseVault,
        marketQuoteVault: marketInfo.quoteVault,
        marketBids: marketInfo.bids,
        marketAsks: marketInfo.asks,
        marketEventQueue: marketInfo.eventQueue,
        lookupTableAccount: PublicKey.default,
    }
    }

async function fetchMarketAccounts(connection: Connection, base: PublicKey, quote: PublicKey, commitment: Commitment = 'finalized') {
    const marketProgramId = new PublicKey('675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8')
    const accounts = await connection.getProgramAccounts(
        marketProgramId,
        {
        commitment,
        filters: [
            { dataSize: LIQUIDITY_STATE_LAYOUT_V4.span },
            {
            memcmp: {
                offset: LIQUIDITY_STATE_LAYOUT_V4.offsetOf("baseMint"),
                bytes: base.toBase58(),
            },
            },
            {
            memcmp: {
                offset: LIQUIDITY_STATE_LAYOUT_V4.offsetOf("quoteMint"),
                bytes: quote.toBase58(),
            },
            },
        ],
        }
    );

    return accounts.map(({ pubkey, account }) => ({
        id: pubkey.toString(),
        ...LIQUIDITY_STATE_LAYOUT_V4.decode(account.data),
      }));
    }

// getPoolKeys(rpcCon, new PublicKey('HZ4Qund5mESBvNngcGNGXrsjAUjvZGP8pNcVwANnQMRG'), new PublicKey('So11111111111111111111111111111111111111112'))

export default getPoolKeys

If you have any question, don't hesitate to ask.

3
  • hey @sashavsthewrld, thanks for this. I used the code you sent and I could get the pool. II'm using this github.com/precious-void/raydium-swap as well. So instead of using the pool sending the poolInfo as radyium-swap does, I sent the poolKey got from your function getPoolKeys but then I received an error: lookupTableAddress: [poolKeys.lookupTableAccount].filter((i) => i && !i.equals(PublicKey.default)), any idea of what could be the issue? Thanks a lot.
    – Lücks
    Commented Mar 17 at 2:03
  • I formatted the response to match with the liquidity/mainnet.json and using one token as example, I noticed the lookupTableAccount in your code is returning the default one, which is different than the one present in liquidity/mainnet.json
    – Lücks
    Commented Mar 17 at 2:38
  • Hey @Lücks I'm really sorry for the very delayed response, I am currently working on the issue you mentioned and will get back to you as soon as I got a solution. Commented Mar 30 at 7:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.