raydium-io / raydium-sdk-V2-demo

Open-source Typescript SDK demos
48 stars 31 forks source link

Issue with token swap in CLMM pool: TransactionExpiredBlockheightExceededError #68

Closed olecsiuyae closed 2 months ago

olecsiuyae commented 2 months ago

Hello,

I am encountering an issue with position creation through the CLMM pool: error TransactionExpiredBlockheightExceededError. I noticed similar issues reported previously, where increasing the priority fee was suggested. Example is issue https://github.com/raydium-io/raydium-sdk-V2-demo/issues/52 .

Here is script:

import { ApiV3PoolInfoConcentratedItem, TickUtils, PoolUtils, ClmmKeys } from '@raydium-io/raydium-sdk-v2' import BN from 'bn.js' import { initSdk, txVersion } from '../config' import Decimal from 'decimal.js' import { isValidClmm } from './utils'

export const createPosition = async () => { const raydium = await initSdk()

let poolInfo: ApiV3PoolInfoConcentratedItem // RAY-USDC pool const poolId = '61R1ndXxvsWXXkWSyNkCxnzwd3zUNB8Q2ibmkiLPC8ht' //'Enfoa5Xdtirwa46xxa5LUVcQWe7EUb2pGzTjfvU7EBS1' //'61R1ndXxvsWXXkWSyNkCxnzwd3zUNB8Q2ibmkiLPC8ht' let poolKeys: ClmmKeys | undefined

if (raydium.cluster === 'mainnet') { // note: api doesn't support get devnet pool info, so in devnet else we go rpc method // if you wish to get pool info from rpc, also can modify logic to go rpc method directly const data = await raydium.api.fetchPoolById({ ids: poolId }) poolInfo = data[0] as ApiV3PoolInfoConcentratedItem if (!isValidClmm(poolInfo.programId)) throw new Error('target pool is not CLMM pool') } else { const data = await raydium.clmm.getPoolInfoFromRpc(poolId) poolInfo = data.poolInfo poolKeys = data.poolKeys }

/* code below will get on chain realtime price to avoid slippage error, uncomment it if necessary / const rpcData = await raydium.clmm.getRpcClmmPoolInfo({ poolId: poolInfo.id }) poolInfo.price = rpcData.currentPrice

const inputAmount = 1 // RAY amount const [startPrice, endPrice] = [0.00000001, 10000000]

const { tick: lowerTick } = TickUtils.getPriceAndTick({ poolInfo, price: new Decimal(startPrice), baseIn: true, })

const { tick: upperTick } = TickUtils.getPriceAndTick({ poolInfo, price: new Decimal(endPrice), baseIn: true, })

const epochInfo = await raydium.fetchEpochInfo() const res = await PoolUtils.getLiquidityAmountOutFromAmountIn({ poolInfo, slippage: 0, inputA: true, tickUpper: Math.max(lowerTick, upperTick), tickLower: Math.min(lowerTick, upperTick), amount: new BN(new Decimal(inputAmount || '0').mul(10 ** poolInfo.mintA.decimals).toFixed(0)), add: true, amountHasFee: true, epochInfo: epochInfo, })

const { execute, extInfo } = await raydium.clmm.openPositionFromBase({ poolInfo, poolKeys, tickUpper: Math.max(lowerTick, upperTick), tickLower: Math.min(lowerTick, upperTick), base: 'MintA', ownerInfo: { useSOLBalance: true, }, baseAmount: new BN(new Decimal(inputAmount || '0').mul(10 * poolInfo.mintA.decimals).toFixed(0)), otherAmountMax: res.amountSlippageB.amount, txVersion, // optional: set up priority fee here computeBudgetConfig: { units: 600000, microLamports: 2_000_000_000_000, //0.002 1_000_000_000 * 1_000_000, }, })

// don't want to wait confirm, set sendAndConfirm to false or don't pass any params to execute const { txId } = await execute({ sendAndConfirm: true }) console.log('clmm position opened:', { txId, nft: extInfo.nftMint.toBase58() }) }

/* uncomment code below to execute / createPosition()

As you can see, computeBudgetConfig is set.

It reproduces with any given microLamports/units value. Also it still happens when I used not modified code at all.

cruzshia commented 2 months ago

just adjust start/end price for in open position example to prevent edge tick edge case https://github.com/raydium-io/raydium-sdk-V2-demo/commit/71db0485c298fa589f543e9ad0c693b2356e087c#diff-48523ca379b3137e97b627026cfa0644bee9fc5d7c4fa4764a9666eaf219538bR32, after test, it should go through smoothly, if you still encounter TransactionExpiredBlockheightExceededError, should check your rpc node.

olecsiuyae commented 2 months ago

just adjust start/end price for in open position example to prevent edge tick edge case 71db048#diff-48523ca379b3137e97b627026cfa0644bee9fc5d7c4fa4764a9666eaf219538bR32, after test, it should go through smoothly, if you still encounter TransactionExpiredBlockheightExceededError, should check your rpc node.

Thank you for your response.

I have implemented all the recommendations from your previous message, including adjusting the prices, using the updated code, and trying different RPC endpoints. However, I am still encountering the following output:

connect to rpc https://mainnet.helius-rpc.com/?api-key=API_KEY in mainnet simulate tx string: [ 'ArZxABmpcbaBEnVw03U746cA48katDTp/3Ol/LXh/wmuQW6LanL3EZIA7q2V3klI14xWafJYslFToGYR74wQ2AzRVkg9BuRI8SrTeHga3ItuGsN01Yd01/tZ7Sx3z0j29zZGNLz2/XGfZ6bw6xrJpfC8oV3Mp+FbVp5Jc0opIzQDgAIABBEh7pbJVCNGaDQiSKzqZpb96VysnYbIqi/9RnezjxrJhbDmvwc3M1BCLkhLDgnC1soULUe+waw8mx/LrSO2Z6fJVh2G29cb1CuKpp6iTm53qqu9kkTyR9CbBZpkLFHXmgQ30SlAacm/ZDC2eWTPbCXKHlINbMucK0nmPKodJBBbgUplljwmzs4WLWSUw+M7/irDYFLbnzOkgaiIuWXek973C8eMUX2Ip+q5HUA6C2rZfww5eHTyUKOlY+S0vcF+cH+3tgCgDra3yLw0tK5Hz8Z04W080ukAxB7TN1OoVX4X23a3faVuK/fAuDMC0GkYwMBXHD9NisdJMRfIu+iSKdee0sL0EHVcF0T4ihjlDrmE6VpoDH5ml7t9lql/3L4ZgBFZH33W8JvlOwJHrfp4Gd4OGhbZFMbp9dbv3RiT+H1OdLi+HFaX2IpOKth1paLwePXaN5z8UZ//QCDzxx41Y8ZfzmiSYZ8RihbdTPrrcBKmlRwp92/jbj+43Xv495CKAC3/N6I35nSnpRWpLRV+Gs6HMgghHZKqb2RKzHMNnDBA4wMGRm/lIRcy/+ytunLDm+e8jOW7xfcSayxDmzpAAAAApdXKngTPXbWQtxS6L+MssVkTP8HBkrciV/0H05ywQB43mYzL8tBFi2FcvMaxo2fEdJ6f73MGYi4bG1iRASC8msb6evO+2606PWXzaqvJdDGxu+TC0vbg5HymAgNFL11hgSS66lRzSHxXApA3u73t4y6AyQun39JrAQ0kw/xJz8IDDQAJA6CGAQAAAAAADQAFAsAnCQAOFgAAAQIDBAUGBwgJCgsMERITFBUWDxA7TbhK1nBW8cc85P3/xMEBAJDb/f/wswEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBGY8fTDpFImPUE7LNF+vLwaDliHNk5iYaEqgXkuoWWj4ABgUAAgcIAw==' ] D:\Job\Research\Raydium\raydium-sdk-V2-demo-master\raydium-sdk-V2-demo-master\node_modules\@solana\web3.js\src\connection.ts:3957 throw new TransactionExpiredBlockheightExceededError(signature); ^ TransactionExpiredBlockheightExceededError: Signature 4eZVD55bLvXSSA7reWBJqNxsvb6kNxMLiG9ne48cQtduSWRUTF97gpGf6qgsjHBCWtxgDhkpQR1h3zVEriyLTbB1 has expired: block height exceeded. at Connection.confirmTransactionUsingBlockHeightExceedanceStrategy (D:\Job\Research\Raydium\raydium-sdk-V2-demo-master\raydium-sdk-V2-demo-master\node_modules\@solana\web3.js\src\connection.ts:3957:15) at processTicksAndRejections (node:internal/process/task_queues:95:5) at async Connection.confirmTransaction (D:\Job\Research\Raydium\raydium-sdk-V2-demo-master\raydium-sdk-V2-demo-master\node_modules\@solana\web3.js\src\connection.ts:3768:14) at async execute (D:\Job\Research\Raydium\raydium-sdk-V2-demo-master\raydium-sdk-V2-demo-master\node_modules\@raydium-io\raydium-sdk-v2\src\common\txTool\txTool.ts:463:13) { signature: '4eZVD55bLvXSSA7reWBJqNxsvb6kNxMLiG9ne48cQtduSWRUTF97gpGf6qgsjHBCWtxgDhkpQR1h3zVEriyLTbB1' } error Command failed with exit code 1.

cruzshia commented 2 months ago

you might put too less amount cause some error click simulate to preflight tx

image
cruzshia commented 2 months ago

just had another test and it still works well as usual there're some suggestions for you

  1. set up higher computeBudgetConfig to raise tx fee and ensure you have enough sol balance
  2. you can force demo code to get pool data from rpc (this line https://github.com/raydium-io/raydium-sdk-V2-demo/blob/master/src/clmm/createPosition.ts#L22) directly to prevent slippage error
  3. ensure your open liquidity is greater than 0 (set bigger input amount and enough mint balance)
    const res = await PoolUtils.getLiquidityAmountOutFromAmountIn({ xxx })
    !res.liquidity.isZero()

    image