liquidity.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import { Commitment, Connection, PublicKey } from '@solana/web3.js';
  2. import {
  3. Liquidity,
  4. LIQUIDITY_STATE_LAYOUT_V4,
  5. LiquidityPoolKeys,
  6. Market,
  7. TokenAccount,
  8. SPL_ACCOUNT_LAYOUT,
  9. publicKey,
  10. struct,
  11. MAINNET_PROGRAM_ID,
  12. } from '@raydium-io/raydium-sdk';
  13. import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
  14. import { USDC_TOKEN_ID } from '../common';
  15. export const RAYDIUM_LIQUIDITY_PROGRAM_ID_V4 = MAINNET_PROGRAM_ID.AmmV4;
  16. export const OPENBOOK_PROGRAM_ID = MAINNET_PROGRAM_ID.OPENBOOK_MARKET;
  17. export const MINIMAL_MARKET_STATE_LAYOUT_V3 = struct([
  18. publicKey('eventQueue'),
  19. publicKey('bids'),
  20. publicKey('asks'),
  21. ]);
  22. export type MinimalLiquidityAccountData = {
  23. id: PublicKey;
  24. version: 4;
  25. programId: PublicKey;
  26. };
  27. export async function getAllAccountsV4(
  28. connection: Connection,
  29. ): Promise<MinimalLiquidityAccountData[]> {
  30. const { span } = LIQUIDITY_STATE_LAYOUT_V4;
  31. const accounts = await connection.getProgramAccounts(
  32. RAYDIUM_LIQUIDITY_PROGRAM_ID_V4,
  33. {
  34. dataSlice: { offset: 0, length: 0 },
  35. commitment: 'processed',
  36. filters: [
  37. { dataSize: span },
  38. {
  39. memcmp: {
  40. offset: LIQUIDITY_STATE_LAYOUT_V4.offsetOf('quoteMint'),
  41. bytes: USDC_TOKEN_ID.toBase58(),
  42. },
  43. },
  44. {
  45. memcmp: {
  46. offset: LIQUIDITY_STATE_LAYOUT_V4.offsetOf('marketProgramId'),
  47. bytes: OPENBOOK_PROGRAM_ID.toBase58(),
  48. },
  49. },
  50. ],
  51. },
  52. );
  53. return accounts.map(
  54. (info) =>
  55. <MinimalLiquidityAccountData>{
  56. id: info.pubkey,
  57. version: 4,
  58. programId: RAYDIUM_LIQUIDITY_PROGRAM_ID_V4,
  59. },
  60. );
  61. }
  62. export async function getAccountPoolKeysFromAccountDataV4(
  63. connection: Connection,
  64. id: PublicKey,
  65. accountData: any,
  66. commitment?: Commitment,
  67. ): Promise<LiquidityPoolKeys> {
  68. const marketInfo = await connection.getAccountInfo(accountData.marketId, {
  69. commitment: commitment ?? 'processed',
  70. dataSlice: {
  71. offset: 253, // eventQueue
  72. length: 32 * 3,
  73. },
  74. });
  75. const minimalMarketData = MINIMAL_MARKET_STATE_LAYOUT_V3.decode(
  76. marketInfo!.data,
  77. );
  78. return {
  79. id,
  80. baseMint: accountData.baseMint,
  81. quoteMint: accountData.quoteMint,
  82. lpMint: accountData.lpMint,
  83. baseDecimals: accountData.baseDecimal.toNumber(),
  84. quoteDecimals: accountData.quoteDecimal.toNumber(),
  85. lpDecimals: 5,
  86. version: 4,
  87. programId: RAYDIUM_LIQUIDITY_PROGRAM_ID_V4,
  88. authority: Liquidity.getAssociatedAuthority({
  89. programId: RAYDIUM_LIQUIDITY_PROGRAM_ID_V4,
  90. }).publicKey,
  91. openOrders: accountData.openOrders,
  92. targetOrders: accountData.targetOrders,
  93. baseVault: accountData.baseVault,
  94. quoteVault: accountData.quoteVault,
  95. marketVersion: 3,
  96. marketProgramId: accountData.marketProgramId,
  97. marketId: accountData.marketId,
  98. marketAuthority: Market.getAssociatedAuthority({
  99. programId: accountData.marketProgramId,
  100. marketId: accountData.marketId,
  101. }).publicKey,
  102. marketBaseVault: accountData.baseVault,
  103. marketQuoteVault: accountData.quoteVault,
  104. marketBids: minimalMarketData.bids,
  105. marketAsks: minimalMarketData.asks,
  106. marketEventQueue: minimalMarketData.eventQueue,
  107. withdrawQueue: accountData.withdrawQueue,
  108. lpVault: accountData.lpVault,
  109. };
  110. }
  111. export async function getTokenAccounts(
  112. connection: Connection,
  113. owner: PublicKey,
  114. ) {
  115. const tokenResp = await connection.getTokenAccountsByOwner(owner, {
  116. programId: TOKEN_PROGRAM_ID,
  117. });
  118. const accounts: TokenAccount[] = [];
  119. for (const { pubkey, account } of tokenResp.value) {
  120. accounts.push({
  121. pubkey,
  122. accountInfo: SPL_ACCOUNT_LAYOUT.decode(account.data),
  123. });
  124. }
  125. return accounts;
  126. }