raydium-io / raydium-sdk-V2-demo

Open-source Typescript SDK demos
70 stars 35 forks source link

poolData = await raydium.tradeV2.fetchRoutePoolBasicInfo() make error #57

Closed YoungHorn1999 closed 4 months ago

YoungHorn1999 commented 4 months ago

when I set as https://api.mainnet-beta.solana.com, and run yarn dev src/trade/routeSwap.ts, the error is: Error: 410 Gone: {"jsonrpc":"2.0","error":{"code": 410, "message":"The RPC call or parameters have been disabled."}, "id": "6196952a-f539-4106-a947-30c7d78fad57" }

and when I set as https://rpc.ankr.com/solana, and run yarn dev src/trade/routeSwap.ts, the error is: StructError: Expected the value to satisfy a union of type | type, but received: [object Object]

I think the problem is poolData = await raydium.tradeV2.fetchRoutePoolBasicInfo(); make error Is it my rpc's problem?

and my code is: import { WSOLMint, RAYMint, USDCMint, toFeeConfig, toApiV3Token, Router, TokenAmount, Token, DEVNET_PROGRAM_ID, printSimulate, } from '@raydium-io/raydium-sdk-v2' import { NATIVE_MINT, TOKEN_2022_PROGRAM_ID } from '@solana/spl-token' import { initSdk, txVersion } from '../config' import { readCachePoolData, writeCachePoolData } from '../cache/utils' import { PublicKey } from '@solana/web3.js'

const poolType: Record<number, string> = { 4: 'AMM', 5: 'AMM Stable', 6: 'CLMM', 7: 'CPMM', }

async function routeSwap() { const raydium = await initSdk() await raydium.fetchChainTime()

const inputAmount = '100' const SOL = NATIVE_MINT // or WSOLMint const [inputMint, outputMint] = [USDCMint, SOL] const [inputMintStr, outputMintStr] = [inputMint.toBase58(), outputMint.toBase58()]

// strongly recommend cache all pool data, it will reduce lots of data fetching time // code below is a simple way to cache it, you can implement it with any other ways let poolData = readCachePoolData() // initial cache time is 10 mins(1000 60 10), if wants to cache longer, set bigger number in milliseconds // let poolData = readCachePoolData(1000 60 60 24 10) // example for cache 1 day if (poolData.ammPools.length === 0) { try { console.log('fetching all pool basic info, this might take a while (more than 30 seconds)..') poolData = await raydium.tradeV2.fetchRoutePoolBasicInfo(); console.log("poolData==="), poolData; writeCachePoolData(poolData) } catch (err) { console.log(JSON.stringify(err)); } }

console.log('computing swap route..') // route here also can cache for a time period by pair to reduce time // e.g.{inputMint}-${outputMint}'s routes, if poolData don't change, routes should be almost same const routes = raydium.tradeV2.getAllRoute({ inputMint, outputMint, ...poolData, })

// data here also can try to cache if you wants e.g. mintInfos // but rpc related info doesn't suggest to cache it for a long time, because base/quote reserve and pool price change by time const { routePathDict, mintInfos, ammPoolsRpcInfo, ammSimulateCache,

clmmPoolsRpcInfo,
computeClmmPoolInfo,
computePoolTickData,

computeCpmmData,

} = await raydium.tradeV2.fetchSwapRoutesData({ routes, inputMint, outputMint, })

console.log('calculating available swap routes...') const swapRoutes = raydium.tradeV2.getAllRouteComputeAmountOut({ inputTokenAmount: new TokenAmount( new Token({ mint: inputMintStr, decimals: mintInfos[inputMintStr].decimals, isToken2022: mintInfos[inputMintStr].programId.equals(TOKEN_2022_PROGRAM_ID), }), inputAmount ), directPath: routes.directPath.map( (p) => ammSimulateCache[p.id.toBase58()] || computeClmmPoolInfo[p.id.toBase58()] || computeCpmmData[p.id.toBase58()] ), routePathDict, simulateCache: ammSimulateCache, tickCache: computePoolTickData, mintInfos: mintInfos, outputToken: toApiV3Token({ ...mintInfos[outputMintStr], programId: mintInfos[outputMintStr].programId.toBase58(), address: outputMintStr, extensions: { feeConfig: toFeeConfig(mintInfos[outputMintStr].feeConfig), }, }), chainTime: Math.floor(raydium.chainTimeData?.chainTime ?? Date.now() / 1000), slippage: 0.005, epochInfo: await raydium.connection.getEpochInfo(), })

// swapRoutes are sorted by out amount, so first one should be the best route const targetRoute = swapRoutes[0] if (!targetRoute) throw new Error('no swap routes were found')

console.log('best swap route:', { input: targetRoute.amountIn.amount.toExact(), output: targetRoute.amountOut.amount.toExact(), minimumOut: targetRoute.minAmountOut.amount.toExact(), swapType: targetRoute.routeType, routes: targetRoute.poolInfoList.map((p) => ${poolType[p.version]} ${p.id} ${(p as any).status}).join(->), })

console.log('fetching swap route pool keys..') const poolKeys = await raydium.tradeV2.computePoolToPoolKeys({ pools: targetRoute.poolInfoList, ammRpcData: ammPoolsRpcInfo, clmmRpcData: clmmPoolsRpcInfo, })

console.log('build swap tx..') const { execute, transactions } = await raydium.tradeV2.swap({ routeProgram: Router, txVersion, swapInfo: targetRoute, swapPoolKeys: poolKeys, ownerInfo: { associatedOnly: true, checkCreateATAOwner: true, }, computeBudgetConfig: { units: 600000, microLamports: 1000000, }, })

// printSimulate(transactions)

console.log('execute tx..') const { txIds } = await execute({ sequentially: true }) console.log('txIds:', txIds) } /* uncomment code below to execute / routeSwap()

cruzshia commented 4 months ago

copied your code and test it with our rpc and it works smoothly, I think you might need to find a new rpc

image
YoungHorn1999 commented 4 months ago

I just use the https://api.mainnet-beta.solana.com, it's not work? And where can I find a rpc can work?

cruzshia commented 4 months ago

That's a free rpc and has lots of limitations, maybe you should get a paid rpc like helius and it will work, because raydium has a huge pool data (probably more than 2MB). If you don't want to get a paid rpc, I suggest you to use src/api/swap to do routeSwap and it's all calculated by raydium api

YoungHorn1999 commented 4 months ago

I try to use the helius paid rpc, but it still can't get the pool data, is there have another way to get all the raydium pool data?

截屏2024-07-10 19 58 57
cruzshia commented 4 months ago

looks like your computer's memory doesn't enough to get all pool data, you can take a reference source code here and customize yourself.

YoungHorn1999 commented 4 months ago

I got the pool data, but I meet TransactionExpiredBlockheightExceededError, I set computeBudgetConfig: { units: 600000, microLamports: 50000000, }, It means 0.05SOL Prioritization Fees, right? As this config, the tx is expired, so how can I make the tx on chain?

cruzshia commented 4 months ago

Set higher priority fee and ensure you set commitment to finalized https://github.com/raydium-io/raydium-sdk-V2-demo/blob/master/src/config.ts.template#L22

YoungHorn1999 commented 4 months ago

yes my commitment is finalized, and I set microLamports: 100000000, it's very high, but still expired. I only add microLamports, should I add units?

cruzshia commented 4 months ago

no, I think you should try more times, in my side it also failed sometimes, you can't guarantee rpc will 100% confirm

cruzshia commented 4 months ago

if you don't want to wait your tx confirmed or want to retry sending until confirmed you can send tx by following code.

const { txId, signedTx } = await execute({ sendAndConfirm: false })
 raydium.connection.sendTransaction(signedTx as VersionedTransaction, { skipPreflight: true }) // loop send tx here and stop it until tx confirmed
YoungHorn1999 commented 4 months ago

I am running src/trade/routeSwap, and the excute params don't include sendAndConfirm like below:

interface MultiTxExecuteParam extends ExecuteParams { sequentially: boolean; onTxUpdate?: (completeTxs: TxUpdateParams[]) => void; }