Skip to content

Commit

Permalink
Merge branch 'raydium-io:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamle2 authored Dec 24, 2024
2 parents 551f83d + e88b606 commit f81ca67
Show file tree
Hide file tree
Showing 17 changed files with 695 additions and 28 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const { execute, transaction, builder, extInfo } = await raydium.clmm.openPositi
- `builder`: all instructions in transaction. e.g. builder.allInstructions, builder.AllTxData
- `extInfo`: transaction related publicKeys. (e.g: extInfo from raydium.cpmm.createPool includes poolId, programId...etc)

#### Fetch pool list by mints
#### Fetch pool list by mints (mainnet only)

```
import { PoolFetchType } from '@raydium-io/raydium-sdk-v2'
Expand Down Expand Up @@ -70,7 +70,7 @@ await raydium.account.fetchWalletTokenAccounts() // if need to force fetching to

### FAQ

#### Error: block height exceeded
#### Error: block height exceeded / exceeded CUs meter at BPF instruction

- transactions were expired, set higher priority fees (computeBudgetConfig) to make it go through smoothly
- if you are testing in devnet, remember to replace programId to devnet one.
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
"description": "Raydium SDK V2 demo.",
"license": "GPL-3.0",
"dependencies": {
"@raydium-io/raydium-sdk-v2": "0.1.92-alpha",
"@raydium-io/raydium-sdk-v2": "0.1.98-alpha",
"@solana/spl-token": "^0.4.6",
"@solana/web3.js": "^1.95.3",
"@triton-one/yellowstone-grpc": "^1.2.0",
"@types/jsonfile": "^6.1.4",
"bs58": "^5.0.0",
"decimal.js": "^10.4.3",
Expand Down
2 changes: 1 addition & 1 deletion src/amm/addLiquidity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const addLiquidity = async () => {
),
amountInB: new TokenAmount(
toToken(poolInfo.mintB),
new Decimal(r.maxAnotherAmount.toExact()).mul(10 ** poolInfo.mintA.decimals).toFixed(0)
new Decimal(r.maxAnotherAmount.toExact()).mul(10 ** poolInfo.mintB.decimals).toFixed(0)
),
otherAmountMin: r.minAnotherAmount,
fixedSide: 'a',
Expand Down
1 change: 1 addition & 0 deletions src/amm/createAmmPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const createAmmPool = async () => {
// check mint info here: https://api-v3.raydium.io/mint/list
// or get mint info by api: await raydium.token.getTokenInfo('mint address')

// amm pool doesn't support token 2022
const baseMintInfo = await raydium.token.getTokenInfo(baseMint)
const quoteMintInfo = await raydium.token.getTokenInfo(quoteMint)
const baseAmount = new BN(1000)
Expand Down
5 changes: 5 additions & 0 deletions src/amm/createMarket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ export const createMarket = async () => {

const { execute, extInfo, transactions } = await raydium.marketV2.create({
baseInfo: {
// create market doesn't support token 2022
mint: RAYMint,
decimals: 6,
},
quoteInfo: {
// create market doesn't support token 2022
mint: USDCMint,
decimals: 9,
},
Expand Down Expand Up @@ -49,6 +51,9 @@ export const createMarket = async () => {
sequentially: true,
})

console.log(
'note: create market does not support token 2022, if you need more detail error info, set txVersion to TxVersion.LEGACY'
)
console.log('create market txIds:', txIds)
process.exit() // if you don't want to end up node execution, comment this line
}
Expand Down
9 changes: 4 additions & 5 deletions src/amm/withdrawLiquidity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { isValidAmm } from './utils'
export const withdrawLiquidity = async () => {
const raydium = await initSdk()
// RAY-USDC pool
const poolId = '6UmmUiYoBjSrhakAobJw8BvkmJtDVxaeBtbt7rxWo1mg'
const poolId = 'FcZNWMNEyUrPY7GMqC92xiWV5otqjCHisUznFJApj8FH'
let poolKeys: AmmV4Keys | AmmV5Keys | undefined
let poolInfo: ApiV3PoolInfoStandardItem
const withdrawLpAmount = new BN(1)
const withdrawLpAmount = new BN(1000) // please check your token account lpMint balance

if (raydium.cluster === 'mainnet') {
// note: api doesn't support get devnet pool info, so in devnet else we go rpc method
Expand All @@ -25,19 +25,18 @@ export const withdrawLiquidity = async () => {
}

if (!isValidAmm(poolInfo.programId)) throw new Error('target pool is not AMM pool')

const [baseRatio, quoteRatio] = [
new Decimal(poolInfo.mintAmountA).div(poolInfo.lpAmount || 1),
new Decimal(poolInfo.mintAmountB).div(poolInfo.lpAmount || 1),
]

const withdrawAmountDe = new Decimal(withdrawLpAmount.toString())
const withdrawAmountDe = new Decimal(withdrawLpAmount.toString()).div(10 ** poolInfo.lpMint.decimals)
const [withdrawAmountA, withdrawAmountB] = [
withdrawAmountDe.mul(baseRatio).mul(10 ** (poolInfo?.mintA.decimals || 0)),
withdrawAmountDe.mul(quoteRatio).mul(10 ** (poolInfo?.mintB.decimals || 0)),
]

const lpSlippage = 0.001 // means 0.1%
const lpSlippage = 0.1 // means 1%

const { execute } = await raydium.liquidity.removeLiquidity({
poolInfo,
Expand Down
2 changes: 1 addition & 1 deletion src/api/swap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ interface SwapCompute {
export const apiSwap = async () => {
const inputMint = NATIVE_MINT.toBase58()
const outputMint = '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R' // RAY
const amount = 100
const amount = 10000
const slippage = 0.5 // in percent, for this example, 0.5 means 0.5%
const txVersion: string = 'V0' // or LEGACY
const isV0Tx = txVersion === 'V0'
Expand Down
3 changes: 3 additions & 0 deletions src/config.ts.template
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,6 @@ export const fetchTokenAccountData = async () => {
})
return tokenAccountData
}

export const grpcUrl = '<YOUR_GRPC_URL>'
export const grpcToken = '<YOUR_GRPC_TOKEN>'
15 changes: 9 additions & 6 deletions src/cpmm/deposit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ export const deposit = async () => {
const raydium = await initSdk()

// SOL - USDC pool
const poolId = '7JuwJuNU88gurFnyWeiyGKbFmExMWcmRZntn9imEzdny'
// const poolId = '7JuwJuNU88gurFnyWeiyGKbFmExMWcmRZntn9imEzdny'
const poolId = '6rXSohG2esLJMzKZzpFr1BXUeXg8Cr5Gv3TwbuXbrwQq'
let poolInfo: ApiV3PoolInfoStandardItemCpmm
let poolKeys: CpmmKeys | undefined

if (raydium.cluster === 'mainnet') {
if (raydium.cluster === 'devnet') {
// 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 })
Expand All @@ -24,6 +25,8 @@ export const deposit = async () => {
poolKeys = data.poolKeys
}

console.log(123123444, poolInfo)

const uiInputAmount = '0.0001'
const inputAmount = new BN(new Decimal(uiInputAmount).mul(10 ** poolInfo.mintA.decimals).toFixed(0))
const slippage = new Percent(1, 100) // 1%
Expand Down Expand Up @@ -63,10 +66,10 @@ export const deposit = async () => {
// },
})
// 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('pool deposited', { txId: `https://explorer.solana.com/tx/${txId}` })
process.exit() // if you don't want to end up node execution, comment this line
// const { txId } = await execute({ sendAndConfirm: true })
// console.log('pool deposited', { txId: `https://explorer.solana.com/tx/${txId}` })
// process.exit() // if you don't want to end up node execution, comment this line
}

/** uncomment code below to execute */
// deposit()
deposit()
1 change: 1 addition & 0 deletions src/grpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
All demos in this folder need to use grpc, you can contact the rpc service provider to purchase.
94 changes: 94 additions & 0 deletions src/grpc/ammPoolInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { liquidityStateV4Layout, splAccountLayout } from "@raydium-io/raydium-sdk-v2";
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
import Client from "@triton-one/yellowstone-grpc";
import base58 from "bs58";
import Decimal from "decimal.js";
import { grpcToken, grpcUrl } from "../config";

async function ammPoolInfo() {
const programId = '675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'
const auth = '5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1'

const client = new Client(grpcUrl, grpcToken, undefined);
const rpcConnInfo = await client.subscribe();

rpcConnInfo.on("data", (data) => {
callback(data, programId)
});

await new Promise<void>((resolve, reject) => {
if (rpcConnInfo === undefined) throw Error('rpc conn error')
rpcConnInfo.write({
slots: {},
accounts: {
ammUpdate: {
owner: [programId],
account: [],
filters: [{ datasize: `${liquidityStateV4Layout.span}` }],
nonemptyTxnSignature: true,
},
vaultUpdate: {
owner: [TOKEN_PROGRAM_ID.toString()],
account: [],
filters: [{ memcmp: { offset: `${splAccountLayout.offsetOf('owner')}`, base58: auth } }],
nonemptyTxnSignature: true,
},
},
transactions: {},
transactionsStatus: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
entry: {},
commitment: 1
}, (err: Error) => {
if (err === null || err === undefined) {
resolve();
} else {
reject(err);
}
});
}).catch((reason) => {
console.error(reason);
throw reason;
});
}

const vaultToPoolId: { [key: string]: { poolId: string, type: 'base' | 'quote' } } = {}
const poolInfoCache: { [key: string]: { poolInfo: ReturnType<typeof liquidityStateV4Layout.decode>, vaultA: ReturnType<typeof splAccountLayout.decode> | undefined, vaultB: ReturnType<typeof splAccountLayout.decode> | undefined } } = {}

async function callback(_data: any, programId: string) {
if (_data.filters.includes('ammUpdate')) {
const data = _data.account

const formatData = liquidityStateV4Layout.decode(data.account.data)
const pk = base58.encode(data.account.pubkey)

poolInfoCache[pk] = { poolInfo: formatData, vaultA: undefined, vaultB: undefined }
vaultToPoolId[formatData.baseVault.toString()] = { poolId: pk, type: 'base' }
vaultToPoolId[formatData.quoteVault.toString()] = { poolId: pk, type: 'quote' }
} else if (_data.filters.includes('vaultUpdate')) {
const data = _data.account

const formatData = splAccountLayout.decode(data.account.data)
const pk = base58.encode(data.account.pubkey)

if (vaultToPoolId[pk] === undefined) return

const _poolType = vaultToPoolId[pk]

if (_poolType.type === 'base') {
poolInfoCache[_poolType.poolId].vaultA = formatData
} else {
poolInfoCache[_poolType.poolId].vaultB = formatData
}

if (poolInfoCache[_poolType.poolId].vaultA === undefined || poolInfoCache[_poolType.poolId].vaultB === undefined) return

const vaultA = new Decimal(poolInfoCache[_poolType.poolId].vaultA!.amount.sub(poolInfoCache[_poolType.poolId].poolInfo.baseNeedTakePnl).toString()).div(10 ** poolInfoCache[_poolType.poolId].poolInfo.baseDecimal.toNumber())
const vaultB = new Decimal(poolInfoCache[_poolType.poolId].vaultB!.amount.sub(poolInfoCache[_poolType.poolId].poolInfo.quoteNeedTakePnl).toString()).div(10 ** poolInfoCache[_poolType.poolId].poolInfo.quoteDecimal.toNumber())
console.log(_poolType.poolId, vaultA, vaultB, vaultB.div(vaultA))
}
}

ammPoolInfo()
57 changes: 57 additions & 0 deletions src/grpc/clmmPoolInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { PoolInfoLayout, SqrtPriceMath } from '@raydium-io/raydium-sdk-v2';
import Client from "@triton-one/yellowstone-grpc";
import base58 from "bs58";
import { grpcToken, grpcUrl } from "../config";

async function clmmPoolInfo() {
const programId = 'CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK'

const client = new Client(grpcUrl, grpcToken, undefined);
const rpcConnInfo = await client.subscribe();

rpcConnInfo.on("data", (data) => {
callback(data, programId)
});

await new Promise<void>((resolve, reject) => {
if (rpcConnInfo === undefined) throw Error('rpc conn error')
rpcConnInfo.write({
slots: {},
accounts: {
ammUpdate: {
owner: [programId],
account: [],
filters: [{ datasize: `${PoolInfoLayout.span}` }],
nonemptyTxnSignature: true,
},
},
transactions: {},
transactionsStatus: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
entry: {},
commitment: 1
}, (err: Error) => {
if (err === null || err === undefined) {
resolve();
} else {
reject(err);
}
});
}).catch((reason) => {
console.error(reason);
throw reason;
});
}

async function callback(_data: any, programId: string) {
const data = _data.account

const formatData = PoolInfoLayout.decode(data.account.data)
const pk = base58.encode(data.account.pubkey)

console.log(pk, SqrtPriceMath.sqrtPriceX64ToPrice(formatData.sqrtPriceX64, formatData.mintDecimalsA, formatData.mintDecimalsB))
}

clmmPoolInfo()
Loading

0 comments on commit f81ca67

Please sign in to comment.