outsmart 2.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +568 -0
  3. package/dist/cli.d.ts +44 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +1251 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/dex/byreal-clmm.d.ts +16 -0
  8. package/dist/dex/byreal-clmm.d.ts.map +1 -0
  9. package/dist/dex/byreal-clmm.js +39 -0
  10. package/dist/dex/byreal-clmm.js.map +1 -0
  11. package/dist/dex/dflow.d.ts +27 -0
  12. package/dist/dex/dflow.d.ts.map +1 -0
  13. package/dist/dex/dflow.js +200 -0
  14. package/dist/dex/dflow.js.map +1 -0
  15. package/dist/dex/fusion-amm.d.ts +44 -0
  16. package/dist/dex/fusion-amm.d.ts.map +1 -0
  17. package/dist/dex/fusion-amm.js +546 -0
  18. package/dist/dex/fusion-amm.js.map +1 -0
  19. package/dist/dex/futarchy-amm.d.ts +32 -0
  20. package/dist/dex/futarchy-amm.d.ts.map +1 -0
  21. package/dist/dex/futarchy-amm.js +443 -0
  22. package/dist/dex/futarchy-amm.js.map +1 -0
  23. package/dist/dex/futarchy-idl.d.ts +2568 -0
  24. package/dist/dex/futarchy-idl.d.ts.map +1 -0
  25. package/dist/dex/futarchy-idl.js +2570 -0
  26. package/dist/dex/futarchy-idl.js.map +1 -0
  27. package/dist/dex/futarchy-launchpad.d.ts +68 -0
  28. package/dist/dex/futarchy-launchpad.d.ts.map +1 -0
  29. package/dist/dex/futarchy-launchpad.js +377 -0
  30. package/dist/dex/futarchy-launchpad.js.map +1 -0
  31. package/dist/dex/index.d.ts +88 -0
  32. package/dist/dex/index.d.ts.map +1 -0
  33. package/dist/dex/index.js +159 -0
  34. package/dist/dex/index.js.map +1 -0
  35. package/dist/dex/jupiter-ultra.d.ts +27 -0
  36. package/dist/dex/jupiter-ultra.d.ts.map +1 -0
  37. package/dist/dex/jupiter-ultra.js +369 -0
  38. package/dist/dex/jupiter-ultra.js.map +1 -0
  39. package/dist/dex/meteora-damm-v1.d.ts +36 -0
  40. package/dist/dex/meteora-damm-v1.d.ts.map +1 -0
  41. package/dist/dex/meteora-damm-v1.js +314 -0
  42. package/dist/dex/meteora-damm-v1.js.map +1 -0
  43. package/dist/dex/meteora-damm-v2.d.ts +103 -0
  44. package/dist/dex/meteora-damm-v2.d.ts.map +1 -0
  45. package/dist/dex/meteora-damm-v2.js +1146 -0
  46. package/dist/dex/meteora-damm-v2.js.map +1 -0
  47. package/dist/dex/meteora-dbc.d.ts +38 -0
  48. package/dist/dex/meteora-dbc.d.ts.map +1 -0
  49. package/dist/dex/meteora-dbc.js +374 -0
  50. package/dist/dex/meteora-dbc.js.map +1 -0
  51. package/dist/dex/meteora-dlmm.d.ts +79 -0
  52. package/dist/dex/meteora-dlmm.d.ts.map +1 -0
  53. package/dist/dex/meteora-dlmm.js +735 -0
  54. package/dist/dex/meteora-dlmm.js.map +1 -0
  55. package/dist/dex/orca.d.ts +31 -0
  56. package/dist/dex/orca.d.ts.map +1 -0
  57. package/dist/dex/orca.js +536 -0
  58. package/dist/dex/orca.js.map +1 -0
  59. package/dist/dex/pancakeswap-clmm.d.ts +16 -0
  60. package/dist/dex/pancakeswap-clmm.d.ts.map +1 -0
  61. package/dist/dex/pancakeswap-clmm.js +39 -0
  62. package/dist/dex/pancakeswap-clmm.js.map +1 -0
  63. package/dist/dex/pumpfun-amm.d.ts +46 -0
  64. package/dist/dex/pumpfun-amm.d.ts.map +1 -0
  65. package/dist/dex/pumpfun-amm.js +692 -0
  66. package/dist/dex/pumpfun-amm.js.map +1 -0
  67. package/dist/dex/pumpfun.d.ts +41 -0
  68. package/dist/dex/pumpfun.d.ts.map +1 -0
  69. package/dist/dex/pumpfun.js +555 -0
  70. package/dist/dex/pumpfun.js.map +1 -0
  71. package/dist/dex/raydium-amm-v4.d.ts +11 -0
  72. package/dist/dex/raydium-amm-v4.d.ts.map +1 -0
  73. package/dist/dex/raydium-amm-v4.js +649 -0
  74. package/dist/dex/raydium-amm-v4.js.map +1 -0
  75. package/dist/dex/raydium-clmm.d.ts +12 -0
  76. package/dist/dex/raydium-clmm.d.ts.map +1 -0
  77. package/dist/dex/raydium-clmm.js +675 -0
  78. package/dist/dex/raydium-clmm.js.map +1 -0
  79. package/dist/dex/raydium-cpmm.d.ts +10 -0
  80. package/dist/dex/raydium-cpmm.d.ts.map +1 -0
  81. package/dist/dex/raydium-cpmm.js +613 -0
  82. package/dist/dex/raydium-cpmm.js.map +1 -0
  83. package/dist/dex/raydium-launchlab.d.ts +12 -0
  84. package/dist/dex/raydium-launchlab.d.ts.map +1 -0
  85. package/dist/dex/raydium-launchlab.js +530 -0
  86. package/dist/dex/raydium-launchlab.js.map +1 -0
  87. package/dist/dex/shared/clmm-base.d.ts +58 -0
  88. package/dist/dex/shared/clmm-base.d.ts.map +1 -0
  89. package/dist/dex/shared/clmm-base.js +891 -0
  90. package/dist/dex/shared/clmm-base.js.map +1 -0
  91. package/dist/dex/types.d.ts +601 -0
  92. package/dist/dex/types.d.ts.map +1 -0
  93. package/dist/dex/types.js +137 -0
  94. package/dist/dex/types.js.map +1 -0
  95. package/dist/dexscreener/index.d.ts +2 -0
  96. package/dist/dexscreener/index.d.ts.map +1 -0
  97. package/dist/dexscreener/index.js +18 -0
  98. package/dist/dexscreener/index.js.map +1 -0
  99. package/dist/dexscreener/info.d.ts +22 -0
  100. package/dist/dexscreener/info.d.ts.map +1 -0
  101. package/dist/dexscreener/info.js +104 -0
  102. package/dist/dexscreener/info.js.map +1 -0
  103. package/dist/helpers/check_balance.d.ts +10 -0
  104. package/dist/helpers/check_balance.d.ts.map +1 -0
  105. package/dist/helpers/check_balance.js +34 -0
  106. package/dist/helpers/check_balance.js.map +1 -0
  107. package/dist/helpers/config.d.ts +51 -0
  108. package/dist/helpers/config.d.ts.map +1 -0
  109. package/dist/helpers/config.js +118 -0
  110. package/dist/helpers/config.js.map +1 -0
  111. package/dist/helpers/index.d.ts +8 -0
  112. package/dist/helpers/index.d.ts.map +1 -0
  113. package/dist/helpers/index.js +29 -0
  114. package/dist/helpers/index.js.map +1 -0
  115. package/dist/helpers/logger.d.ts +27 -0
  116. package/dist/helpers/logger.d.ts.map +1 -0
  117. package/dist/helpers/logger.js +39 -0
  118. package/dist/helpers/logger.js.map +1 -0
  119. package/dist/helpers/token-2022.d.ts +32 -0
  120. package/dist/helpers/token-2022.d.ts.map +1 -0
  121. package/dist/helpers/token-2022.js +48 -0
  122. package/dist/helpers/token-2022.js.map +1 -0
  123. package/dist/helpers/unwrap_sol.d.ts +2 -0
  124. package/dist/helpers/unwrap_sol.d.ts.map +1 -0
  125. package/dist/helpers/unwrap_sol.js +67 -0
  126. package/dist/helpers/unwrap_sol.js.map +1 -0
  127. package/dist/helpers/util.d.ts +698 -0
  128. package/dist/helpers/util.d.ts.map +1 -0
  129. package/dist/helpers/util.js +181 -0
  130. package/dist/helpers/util.js.map +1 -0
  131. package/dist/helpers/utils.d.ts +10 -0
  132. package/dist/helpers/utils.d.ts.map +1 -0
  133. package/dist/helpers/utils.js +97 -0
  134. package/dist/helpers/utils.js.map +1 -0
  135. package/dist/helpers/wrap_sol.d.ts +3 -0
  136. package/dist/helpers/wrap_sol.d.ts.map +1 -0
  137. package/dist/helpers/wrap_sol.js +88 -0
  138. package/dist/helpers/wrap_sol.js.map +1 -0
  139. package/dist/index.d.ts +14 -0
  140. package/dist/index.d.ts.map +1 -0
  141. package/dist/index.js +32 -0
  142. package/dist/index.js.map +1 -0
  143. package/dist/transactions/bloXroute_tips_tx_executor.d.ts +4 -0
  144. package/dist/transactions/bloXroute_tips_tx_executor.d.ts.map +1 -0
  145. package/dist/transactions/bloXroute_tips_tx_executor.js +70 -0
  146. package/dist/transactions/bloXroute_tips_tx_executor.js.map +1 -0
  147. package/dist/transactions/index.d.ts +6 -0
  148. package/dist/transactions/index.d.ts.map +1 -0
  149. package/dist/transactions/index.js +30 -0
  150. package/dist/transactions/index.js.map +1 -0
  151. package/dist/transactions/jito_tips_tx_executor.d.ts +15 -0
  152. package/dist/transactions/jito_tips_tx_executor.d.ts.map +1 -0
  153. package/dist/transactions/jito_tips_tx_executor.js +99 -0
  154. package/dist/transactions/jito_tips_tx_executor.js.map +1 -0
  155. package/dist/transactions/landing/index.d.ts +30 -0
  156. package/dist/transactions/landing/index.d.ts.map +1 -0
  157. package/dist/transactions/landing/index.js +60 -0
  158. package/dist/transactions/landing/index.js.map +1 -0
  159. package/dist/transactions/landing/nonce-manager.d.ts +116 -0
  160. package/dist/transactions/landing/nonce-manager.d.ts.map +1 -0
  161. package/dist/transactions/landing/nonce-manager.js +393 -0
  162. package/dist/transactions/landing/nonce-manager.js.map +1 -0
  163. package/dist/transactions/landing/orchestrator.d.ts +104 -0
  164. package/dist/transactions/landing/orchestrator.d.ts.map +1 -0
  165. package/dist/transactions/landing/orchestrator.js +329 -0
  166. package/dist/transactions/landing/orchestrator.js.map +1 -0
  167. package/dist/transactions/landing/providers/astralane.d.ts +12 -0
  168. package/dist/transactions/landing/providers/astralane.d.ts.map +1 -0
  169. package/dist/transactions/landing/providers/astralane.js +132 -0
  170. package/dist/transactions/landing/providers/astralane.js.map +1 -0
  171. package/dist/transactions/landing/providers/blockrazor.d.ts +11 -0
  172. package/dist/transactions/landing/providers/blockrazor.d.ts.map +1 -0
  173. package/dist/transactions/landing/providers/blockrazor.js +134 -0
  174. package/dist/transactions/landing/providers/blockrazor.js.map +1 -0
  175. package/dist/transactions/landing/providers/bloxroute.d.ts +12 -0
  176. package/dist/transactions/landing/providers/bloxroute.d.ts.map +1 -0
  177. package/dist/transactions/landing/providers/bloxroute.js +102 -0
  178. package/dist/transactions/landing/providers/bloxroute.js.map +1 -0
  179. package/dist/transactions/landing/providers/flashblock.d.ts +10 -0
  180. package/dist/transactions/landing/providers/flashblock.d.ts.map +1 -0
  181. package/dist/transactions/landing/providers/flashblock.js +102 -0
  182. package/dist/transactions/landing/providers/flashblock.js.map +1 -0
  183. package/dist/transactions/landing/providers/helius-sender.d.ts +11 -0
  184. package/dist/transactions/landing/providers/helius-sender.d.ts.map +1 -0
  185. package/dist/transactions/landing/providers/helius-sender.js +101 -0
  186. package/dist/transactions/landing/providers/helius-sender.js.map +1 -0
  187. package/dist/transactions/landing/providers/jito.d.ts +16 -0
  188. package/dist/transactions/landing/providers/jito.d.ts.map +1 -0
  189. package/dist/transactions/landing/providers/jito.js +110 -0
  190. package/dist/transactions/landing/providers/jito.js.map +1 -0
  191. package/dist/transactions/landing/providers/nextblock.d.ts +11 -0
  192. package/dist/transactions/landing/providers/nextblock.d.ts.map +1 -0
  193. package/dist/transactions/landing/providers/nextblock.js +109 -0
  194. package/dist/transactions/landing/providers/nextblock.js.map +1 -0
  195. package/dist/transactions/landing/providers/node1.d.ts +11 -0
  196. package/dist/transactions/landing/providers/node1.d.ts.map +1 -0
  197. package/dist/transactions/landing/providers/node1.js +101 -0
  198. package/dist/transactions/landing/providers/node1.js.map +1 -0
  199. package/dist/transactions/landing/providers/nozomi.d.ts +11 -0
  200. package/dist/transactions/landing/providers/nozomi.d.ts.map +1 -0
  201. package/dist/transactions/landing/providers/nozomi.js +124 -0
  202. package/dist/transactions/landing/providers/nozomi.js.map +1 -0
  203. package/dist/transactions/landing/providers/soyas.d.ts +16 -0
  204. package/dist/transactions/landing/providers/soyas.d.ts.map +1 -0
  205. package/dist/transactions/landing/providers/soyas.js +192 -0
  206. package/dist/transactions/landing/providers/soyas.js.map +1 -0
  207. package/dist/transactions/landing/providers/stellium.d.ts +11 -0
  208. package/dist/transactions/landing/providers/stellium.d.ts.map +1 -0
  209. package/dist/transactions/landing/providers/stellium.js +102 -0
  210. package/dist/transactions/landing/providers/stellium.js.map +1 -0
  211. package/dist/transactions/landing/providers/zero-slot.d.ts +10 -0
  212. package/dist/transactions/landing/providers/zero-slot.d.ts.map +1 -0
  213. package/dist/transactions/landing/providers/zero-slot.js +92 -0
  214. package/dist/transactions/landing/providers/zero-slot.js.map +1 -0
  215. package/dist/transactions/landing/tip-accounts.d.ts +22 -0
  216. package/dist/transactions/landing/tip-accounts.d.ts.map +1 -0
  217. package/dist/transactions/landing/tip-accounts.js +140 -0
  218. package/dist/transactions/landing/tip-accounts.js.map +1 -0
  219. package/dist/transactions/landing/types.d.ts +98 -0
  220. package/dist/transactions/landing/types.d.ts.map +1 -0
  221. package/dist/transactions/landing/types.js +30 -0
  222. package/dist/transactions/landing/types.js.map +1 -0
  223. package/dist/transactions/nozomi/tx-submission.d.ts +14 -0
  224. package/dist/transactions/nozomi/tx-submission.d.ts.map +1 -0
  225. package/dist/transactions/nozomi/tx-submission.js +107 -0
  226. package/dist/transactions/nozomi/tx-submission.js.map +1 -0
  227. package/dist/transactions/send-rpc.d.ts +54 -0
  228. package/dist/transactions/send-rpc.d.ts.map +1 -0
  229. package/dist/transactions/send-rpc.js +126 -0
  230. package/dist/transactions/send-rpc.js.map +1 -0
  231. package/dist/transactions/simple_tx_executor.d.ts +10 -0
  232. package/dist/transactions/simple_tx_executor.d.ts.map +1 -0
  233. package/dist/transactions/simple_tx_executor.js +33 -0
  234. package/dist/transactions/simple_tx_executor.js.map +1 -0
  235. package/package.json +112 -0
@@ -0,0 +1,675 @@
1
+ "use strict";
2
+ /**
3
+ * Raydium CLMM (Concentrated Liquidity Market Maker) DEX Adapter
4
+ *
5
+ * Implements IDexAdapter for Raydium's CLMM program (CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK).
6
+ * Supports buy, sell, snipe, findPool, getPrice, and buildSwapIxs.
7
+ *
8
+ * Uses the native IX path (buy-v2.ts) for snipe and the SDK path for regular buy/sell.
9
+ *
10
+ * Ported from: 100x-algo-bots/trading-modules/raydium-clmm/
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ var __importDefault = (this && this.__importDefault) || function (mod) {
46
+ return (mod && mod.__esModule) ? mod : { "default": mod };
47
+ };
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ const web3_js_1 = require("@solana/web3.js");
50
+ const spl_token_1 = require("@solana/spl-token");
51
+ const bn_js_1 = __importDefault(require("bn.js"));
52
+ const decimal_js_1 = __importDefault(require("decimal.js"));
53
+ const types_1 = require("./types");
54
+ const index_1 = require("./index");
55
+ const config_1 = require("../helpers/config");
56
+ const landing_1 = require("../transactions/landing");
57
+ const send_rpc_1 = require("../transactions/send-rpc");
58
+ // ---------------------------------------------------------------------------
59
+ // Program constants
60
+ // ---------------------------------------------------------------------------
61
+ const RAYDIUM_CLMM_PROGRAM_ID = new web3_js_1.PublicKey("CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK");
62
+ const TOKEN_PROGRAM_ID_PK = new web3_js_1.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
63
+ const MEMO_PROGRAM_ID = new web3_js_1.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
64
+ const WSOL_MINT_PK = new web3_js_1.PublicKey(types_1.WSOL_MINT);
65
+ const USDC_MINT_PK = new web3_js_1.PublicKey(types_1.USDC_MINT);
66
+ const USDT_MINT_PK = new web3_js_1.PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
67
+ const USD1_MINT_PK = new web3_js_1.PublicKey("USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB");
68
+ // Swap V2 discriminator
69
+ const SWAP_V2_DISCRIMINATOR = Buffer.from([43, 4, 237, 11, 26, 201, 30, 98]);
70
+ // Tick array constants
71
+ const TICK_ARRAY_SIZE = 60;
72
+ const MIN_SQRT_PRICE_X64 = new bn_js_1.default("4295048016");
73
+ const MAX_SQRT_PRICE_X64 = new bn_js_1.default("79226673515401279992447579055");
74
+ // PDA seeds
75
+ const POOL_SEED = Buffer.from("pool", "utf8");
76
+ const POOL_VAULT_SEED = Buffer.from("pool_vault", "utf8");
77
+ const OBSERVATION_SEED = Buffer.from("observation", "utf8");
78
+ const TICK_ARRAY_SEED = Buffer.from("tick_array", "utf8");
79
+ const POOL_TICK_ARRAY_BITMAP_SEED = Buffer.from("pool_tick_array_bitmap_extension", "utf8");
80
+ const AMM_CONFIG_SEED = Buffer.from("amm_config", "utf8");
81
+ // ---------------------------------------------------------------------------
82
+ // PDA helpers (ported from raydium-clmm/utils/pda-native.ts)
83
+ // ---------------------------------------------------------------------------
84
+ function i32ToBytes(value) {
85
+ const buf = Buffer.alloc(4);
86
+ buf.writeInt32BE(value, 0);
87
+ return buf;
88
+ }
89
+ function u16ToBytes(value) {
90
+ const buf = Buffer.alloc(2);
91
+ buf.writeUInt16LE(value, 0);
92
+ return buf;
93
+ }
94
+ function derivePda(seeds) {
95
+ const [pda] = web3_js_1.PublicKey.findProgramAddressSync(seeds, RAYDIUM_CLMM_PROGRAM_ID);
96
+ return pda;
97
+ }
98
+ function derivePoolVault(poolId, vaultMint) {
99
+ return derivePda([POOL_VAULT_SEED, poolId.toBuffer(), vaultMint.toBuffer()]);
100
+ }
101
+ function deriveObservationState(poolId) {
102
+ return derivePda([OBSERVATION_SEED, poolId.toBuffer()]);
103
+ }
104
+ function deriveTickArray(poolId, startIndex) {
105
+ return derivePda([TICK_ARRAY_SEED, poolId.toBuffer(), i32ToBytes(startIndex)]);
106
+ }
107
+ function deriveTickArrayBitmapExtension(poolId) {
108
+ return derivePda([POOL_TICK_ARRAY_BITMAP_SEED, poolId.toBuffer()]);
109
+ }
110
+ function deriveAmmConfig(index) {
111
+ return derivePda([AMM_CONFIG_SEED, u16ToBytes(index)]);
112
+ }
113
+ function derivePoolId(ammConfig, mintA, mintB) {
114
+ return derivePda([POOL_SEED, ammConfig.toBuffer(), mintA.toBuffer(), mintB.toBuffer()]);
115
+ }
116
+ function decodeClmmPoolState(data) {
117
+ let offset = 8; // skip discriminator
118
+ const bump = data.readUInt8(offset);
119
+ offset += 1;
120
+ const ammConfig = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
121
+ offset += 32;
122
+ const owner = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
123
+ offset += 32;
124
+ const tokenMint0 = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
125
+ offset += 32;
126
+ const tokenMint1 = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
127
+ offset += 32;
128
+ const tokenVault0 = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
129
+ offset += 32;
130
+ const tokenVault1 = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
131
+ offset += 32;
132
+ const observationKey = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
133
+ offset += 32;
134
+ const mintDecimals0 = data.readUInt8(offset);
135
+ offset += 1;
136
+ const mintDecimals1 = data.readUInt8(offset);
137
+ offset += 1;
138
+ const tickSpacing = data.readUInt16LE(offset);
139
+ offset += 2;
140
+ const liquidity = new bn_js_1.default(data.slice(offset, offset + 16), "le");
141
+ offset += 16;
142
+ const sqrtPriceX64 = new bn_js_1.default(data.slice(offset, offset + 16), "le");
143
+ offset += 16;
144
+ const tickCurrent = data.readInt32LE(offset);
145
+ offset += 4;
146
+ // Skip padding3 (u16), padding4 (u16)
147
+ offset += 4;
148
+ // Skip fee_growth_global_0_x64 (u128), fee_growth_global_1_x64 (u128)
149
+ offset += 32;
150
+ // Skip protocol_fees_token_0 (u64), protocol_fees_token_1 (u64)
151
+ offset += 16;
152
+ // Skip swap_in_amount_token_0 (u128), swap_out_amount_token_1 (u128), swap_in_amount_token_1 (u128), swap_out_amount_token_0 (u128)
153
+ offset += 64;
154
+ const status = data.readUInt8(offset);
155
+ offset += 1;
156
+ // Skip padding (7 bytes)
157
+ offset += 7;
158
+ // Skip rewardInfos: 3 * 169 = 507 bytes
159
+ offset += 507;
160
+ // tickArrayBitmap: 16 u64 values
161
+ const tickArrayBitmap = [];
162
+ for (let i = 0; i < 16; i++) {
163
+ tickArrayBitmap.push(new bn_js_1.default(data.slice(offset, offset + 8), "le"));
164
+ offset += 8;
165
+ }
166
+ return {
167
+ bump, ammConfig, owner, tokenMint0, tokenMint1, tokenVault0, tokenVault1,
168
+ observationKey, mintDecimals0, mintDecimals1, tickSpacing, liquidity,
169
+ sqrtPriceX64, tickCurrent, status, tickArrayBitmap,
170
+ };
171
+ }
172
+ async function fetchClmmPoolState(connection, poolId) {
173
+ const accountInfo = await connection.getAccountInfo(poolId);
174
+ if (!accountInfo)
175
+ throw new Error(`Pool state account not found: ${poolId.toBase58()}`);
176
+ if (!accountInfo.owner.equals(RAYDIUM_CLMM_PROGRAM_ID)) {
177
+ throw new Error(`Invalid account owner for pool state: ${accountInfo.owner.toBase58()}`);
178
+ }
179
+ return decodeClmmPoolState(accountInfo.data);
180
+ }
181
+ // ---------------------------------------------------------------------------
182
+ // Tick array helpers
183
+ // ---------------------------------------------------------------------------
184
+ function tickToStartIndex(tick, tickSpacing) {
185
+ const ticksInArray = tickSpacing * TICK_ARRAY_SIZE;
186
+ // For both positive and negative ticks, floor division gives the correct start index.
187
+ // Math.floor(-20456 / 600) = -35, so startIndex = -35 * 600 = -21000.
188
+ // The tick -20456 is in range [-21000, -20400), which is correct.
189
+ // No special negative handling needed — Math.floor already rounds toward -∞.
190
+ return Math.floor(tick / ticksInArray) * ticksInArray;
191
+ }
192
+ function getNextTickArrayStartIndex(currentStartIndex, tickSpacing, zeroForOne) {
193
+ const ticksInArray = tickSpacing * TICK_ARRAY_SIZE;
194
+ return zeroForOne ? currentStartIndex - ticksInArray : currentStartIndex + ticksInArray;
195
+ }
196
+ async function getTickArraysForSwap(connection, poolId, tickCurrent, tickSpacing, zeroForOne, maxArrays = 3) {
197
+ const startIndex = tickToStartIndex(tickCurrent, tickSpacing);
198
+ const tickArrays = [];
199
+ let currentStart = startIndex;
200
+ for (let i = 0; i < maxArrays; i++) {
201
+ const tickArrayAddress = deriveTickArray(poolId, currentStart);
202
+ try {
203
+ const info = await connection.getAccountInfo(tickArrayAddress);
204
+ if (info && info.owner.equals(RAYDIUM_CLMM_PROGRAM_ID)) {
205
+ tickArrays.push(tickArrayAddress);
206
+ }
207
+ }
208
+ catch {
209
+ // Skip
210
+ }
211
+ currentStart = getNextTickArrayStartIndex(currentStart, tickSpacing, zeroForOne);
212
+ }
213
+ // Must have at least one tick array
214
+ if (tickArrays.length === 0) {
215
+ // Use the start index tick array anyway (it may get created)
216
+ tickArrays.push(deriveTickArray(poolId, startIndex));
217
+ }
218
+ return tickArrays;
219
+ }
220
+ // ---------------------------------------------------------------------------
221
+ // Token program detection
222
+ // ---------------------------------------------------------------------------
223
+ async function getTokenProgramForMint(connection, mint) {
224
+ const mintInfo = await connection.getAccountInfo(mint);
225
+ if (!mintInfo)
226
+ throw new Error(`Mint account not found: ${mint.toBase58()}`);
227
+ if (mintInfo.owner.equals(spl_token_1.TOKEN_2022_PROGRAM_ID))
228
+ return spl_token_1.TOKEN_2022_PROGRAM_ID;
229
+ return TOKEN_PROGRAM_ID_PK;
230
+ }
231
+ function isStablecoin(mint) {
232
+ return mint.equals(USDC_MINT_PK) || mint.equals(USDT_MINT_PK) || mint.equals(USD1_MINT_PK);
233
+ }
234
+ // ---------------------------------------------------------------------------
235
+ // Price calculation
236
+ // ---------------------------------------------------------------------------
237
+ function sqrtPriceX64ToPrice(sqrtPriceX64, decimalsA, decimalsB) {
238
+ try {
239
+ const { MathUtil } = require("@raydium-io/raydium-sdk-v2");
240
+ const price = MathUtil.x64ToDecimal(sqrtPriceX64)
241
+ .pow(2)
242
+ .mul(new decimal_js_1.default(10).pow(decimalsA - decimalsB));
243
+ return Number(price.toString());
244
+ }
245
+ catch {
246
+ // Fallback manual calculation
247
+ const sqrtPrice = Number(sqrtPriceX64.toString()) / 2 ** 64;
248
+ const price = sqrtPrice * sqrtPrice;
249
+ const decimalAdj = 10 ** (decimalsA - decimalsB);
250
+ return price * decimalAdj;
251
+ }
252
+ }
253
+ function createClmmSwapV2Ix(poolParams, payer, inputTokenAccount, outputTokenAccount, amount, otherAmountThreshold, sqrtPriceLimitX64, isBaseInput, tickArrays, inputVaultMint, outputVaultMint, tickArrayBitmapExtension, zeroForOne) {
254
+ // Use zeroForOne for vault direction (falls back to isBaseInput for backward compat)
255
+ const directionZeroForOne = zeroForOne ?? isBaseInput;
256
+ const inputVault = directionZeroForOne ? poolParams.tokenVault0 : poolParams.tokenVault1;
257
+ const outputVault = directionZeroForOne ? poolParams.tokenVault1 : poolParams.tokenVault0;
258
+ const accounts = [
259
+ { pubkey: payer, isSigner: true, isWritable: true },
260
+ { pubkey: poolParams.ammConfig, isSigner: false, isWritable: false },
261
+ { pubkey: poolParams.poolId, isSigner: false, isWritable: true },
262
+ { pubkey: inputTokenAccount, isSigner: false, isWritable: true },
263
+ { pubkey: outputTokenAccount, isSigner: false, isWritable: true },
264
+ { pubkey: inputVault, isSigner: false, isWritable: true },
265
+ { pubkey: outputVault, isSigner: false, isWritable: true },
266
+ { pubkey: poolParams.observationState, isSigner: false, isWritable: true },
267
+ { pubkey: TOKEN_PROGRAM_ID_PK, isSigner: false, isWritable: false },
268
+ { pubkey: spl_token_1.TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },
269
+ { pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },
270
+ { pubkey: inputVaultMint, isSigner: false, isWritable: false },
271
+ { pubkey: outputVaultMint, isSigner: false, isWritable: false },
272
+ { pubkey: tickArrayBitmapExtension, isSigner: false, isWritable: true },
273
+ { pubkey: tickArrays[0], isSigner: false, isWritable: true },
274
+ ];
275
+ // Additional tick arrays as remaining accounts
276
+ const remainingAccounts = tickArrays.slice(1).map((ta) => ({
277
+ pubkey: ta,
278
+ isSigner: false,
279
+ isWritable: true,
280
+ }));
281
+ // Data: discriminator (8) + amount (8) + threshold (8) + sqrtPriceLimit (16) + isBaseInput (1) = 41 bytes
282
+ const data = Buffer.alloc(41);
283
+ let offset = 0;
284
+ SWAP_V2_DISCRIMINATOR.copy(data, offset);
285
+ offset += 8;
286
+ data.writeBigUInt64LE(amount, offset);
287
+ offset += 8;
288
+ data.writeBigUInt64LE(otherAmountThreshold, offset);
289
+ offset += 8;
290
+ const sqrtPriceBytes = sqrtPriceLimitX64.toArrayLike(Buffer, "le", 16);
291
+ sqrtPriceBytes.copy(data, offset);
292
+ offset += 16;
293
+ data.writeUInt8(isBaseInput ? 1 : 0, offset);
294
+ return new web3_js_1.TransactionInstruction({
295
+ keys: [...accounts, ...remainingAccounts],
296
+ programId: RAYDIUM_CLMM_PROGRAM_ID,
297
+ data,
298
+ });
299
+ }
300
+ // ---------------------------------------------------------------------------
301
+ // Pool discovery
302
+ // ---------------------------------------------------------------------------
303
+ const COMMON_AMM_CONFIG = new web3_js_1.PublicKey("E64NGkDLLCdQ2yFNPcavaKptrEgmiQaNykUuLC1Qgwyp");
304
+ async function discoverClmmPool(connection, baseMint, quoteMint) {
305
+ // Try the common AMM config with both mint orderings
306
+ const candidates = [
307
+ derivePoolId(COMMON_AMM_CONFIG, baseMint, quoteMint),
308
+ derivePoolId(COMMON_AMM_CONFIG, quoteMint, baseMint),
309
+ ];
310
+ for (const poolId of candidates) {
311
+ try {
312
+ const info = await connection.getAccountInfo(poolId);
313
+ if (info && info.owner.equals(RAYDIUM_CLMM_PROGRAM_ID)) {
314
+ return poolId;
315
+ }
316
+ }
317
+ catch {
318
+ // skip
319
+ }
320
+ }
321
+ // Try via Raydium API as fallback
322
+ try {
323
+ const { Raydium } = await Promise.resolve().then(() => __importStar(require("@raydium-io/raydium-sdk-v2")));
324
+ const raydium = await Raydium.load({
325
+ connection,
326
+ disableLoadToken: true,
327
+ });
328
+ const pools = await raydium.api.fetchPoolByMints({
329
+ mint1: quoteMint.toBase58(),
330
+ mint2: baseMint.toBase58(),
331
+ });
332
+ for (const obj of pools) {
333
+ if (obj.type === "Concentrated") {
334
+ return new web3_js_1.PublicKey(obj.id);
335
+ }
336
+ }
337
+ }
338
+ catch {
339
+ // API unavailable
340
+ }
341
+ return null;
342
+ }
343
+ // ---------------------------------------------------------------------------
344
+ // Token balance helper
345
+ // ---------------------------------------------------------------------------
346
+ async function getTokenBalance(connection, mint, owner) {
347
+ const tokenProgram = await getTokenProgramForMint(connection, mint);
348
+ const ata = await (0, spl_token_1.getAssociatedTokenAddress)(mint, owner, tokenProgram.equals(spl_token_1.TOKEN_2022_PROGRAM_ID), tokenProgram);
349
+ try {
350
+ const res = await connection.getTokenAccountBalance(ata);
351
+ return { amount: BigInt(res.value.amount), decimals: res.value.decimals };
352
+ }
353
+ catch {
354
+ return { amount: 0n, decimals: 0 };
355
+ }
356
+ }
357
+ // ---------------------------------------------------------------------------
358
+ // Build swap instructions (shared between snipe and buildSwapIxs)
359
+ // ---------------------------------------------------------------------------
360
+ async function buildClmmSwapInstructions(connection, wallet, tokenMint, quoteMintPk, poolId, amountIn, minOut, priorityFee, includeComputeBudget) {
361
+ const poolState = await fetchClmmPoolState(connection, poolId);
362
+ // Detect base token program
363
+ const baseTokenProgram = await getTokenProgramForMint(connection, tokenMint);
364
+ // Determine swap direction
365
+ // We're buying tokenMint with quoteMint, so input is quoteMint
366
+ const isBaseInput = poolState.tokenMint0.equals(quoteMintPk);
367
+ const zeroForOne = isBaseInput;
368
+ // Calculate sqrt price limit
369
+ let sqrtPriceLimitX64;
370
+ if (isBaseInput) {
371
+ sqrtPriceLimitX64 = MIN_SQRT_PRICE_X64.add(new bn_js_1.default(1));
372
+ }
373
+ else {
374
+ sqrtPriceLimitX64 = MAX_SQRT_PRICE_X64.sub(new bn_js_1.default(1));
375
+ }
376
+ // Get tick arrays
377
+ const tickArrays = await getTickArraysForSwap(connection, poolId, poolState.tickCurrent, poolState.tickSpacing, zeroForOne);
378
+ // Build ATAs
379
+ const inputMintTokenProgram = await getTokenProgramForMint(connection, quoteMintPk);
380
+ const inputAta = await (0, spl_token_1.getAssociatedTokenAddress)(quoteMintPk, wallet.publicKey, inputMintTokenProgram.equals(spl_token_1.TOKEN_2022_PROGRAM_ID), inputMintTokenProgram);
381
+ const outputAta = await (0, spl_token_1.getAssociatedTokenAddress)(tokenMint, wallet.publicKey, baseTokenProgram.equals(spl_token_1.TOKEN_2022_PROGRAM_ID), baseTokenProgram);
382
+ const tickArrayBitmapExt = deriveTickArrayBitmapExtension(poolId);
383
+ // Determine input/output vault mints
384
+ const inputVaultMint = isBaseInput ? poolState.tokenMint0 : poolState.tokenMint1;
385
+ const outputVaultMint = isBaseInput ? poolState.tokenMint1 : poolState.tokenMint0;
386
+ const poolParams = {
387
+ poolId,
388
+ ammConfig: poolState.ammConfig,
389
+ observationState: poolState.observationKey,
390
+ tokenVault0: poolState.tokenVault0,
391
+ tokenVault1: poolState.tokenVault1,
392
+ tokenMint0: poolState.tokenMint0,
393
+ tokenMint1: poolState.tokenMint1,
394
+ };
395
+ const swapIx = createClmmSwapV2Ix(poolParams, wallet.publicKey, inputAta, outputAta, amountIn, minOut, sqrtPriceLimitX64, true, // isBaseInput — always exact input swap
396
+ tickArrays, inputVaultMint, outputVaultMint, tickArrayBitmapExt, zeroForOne);
397
+ // Build instruction list
398
+ const ixs = [];
399
+ if (includeComputeBudget) {
400
+ ixs.push(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priorityFee }));
401
+ }
402
+ ixs.push((0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(wallet.publicKey, inputAta, wallet.publicKey, quoteMintPk, inputMintTokenProgram), (0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(wallet.publicKey, outputAta, wallet.publicKey, tokenMint, baseTokenProgram.equals(spl_token_1.TOKEN_2022_PROGRAM_ID) ? spl_token_1.TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID_PK));
403
+ // WSOL wrapping
404
+ if (quoteMintPk.equals(WSOL_MINT_PK)) {
405
+ const lamports = Number(amountIn);
406
+ ixs.push(web3_js_1.SystemProgram.transfer({ fromPubkey: wallet.publicKey, toPubkey: inputAta, lamports }), (0, spl_token_1.createSyncNativeInstruction)(inputAta, TOKEN_PROGRAM_ID_PK));
407
+ }
408
+ ixs.push(swapIx);
409
+ // Close WSOL ATA
410
+ if (quoteMintPk.equals(WSOL_MINT_PK)) {
411
+ ixs.push((0, spl_token_1.createCloseAccountInstruction)(inputAta, wallet.publicKey, wallet.publicKey, [], TOKEN_PROGRAM_ID_PK));
412
+ }
413
+ return ixs;
414
+ }
415
+ // ---------------------------------------------------------------------------
416
+ // Build sell instructions
417
+ // ---------------------------------------------------------------------------
418
+ async function buildClmmSellInstructions(connection, wallet, tokenMint, quoteMintPk, poolId, sellAmount, minOut, priorityFee, includeComputeBudget) {
419
+ const poolState = await fetchClmmPoolState(connection, poolId);
420
+ const baseTokenProgram = await getTokenProgramForMint(connection, tokenMint);
421
+ // For sell: input is tokenMint, output is quoteMint.
422
+ // zeroForOne = true if tokenMint is token0 (selling token0 for token1).
423
+ // isBaseInput is ALWAYS true — we specify exact input amount, not exact output.
424
+ const zeroForOne = poolState.tokenMint0.equals(tokenMint);
425
+ let sqrtPriceLimitX64;
426
+ if (zeroForOne) {
427
+ sqrtPriceLimitX64 = MIN_SQRT_PRICE_X64.add(new bn_js_1.default(1));
428
+ }
429
+ else {
430
+ sqrtPriceLimitX64 = MAX_SQRT_PRICE_X64.sub(new bn_js_1.default(1));
431
+ }
432
+ const tickArrays = await getTickArraysForSwap(connection, poolId, poolState.tickCurrent, poolState.tickSpacing, zeroForOne);
433
+ const inputAta = await (0, spl_token_1.getAssociatedTokenAddress)(tokenMint, wallet.publicKey, baseTokenProgram.equals(spl_token_1.TOKEN_2022_PROGRAM_ID), baseTokenProgram);
434
+ const quoteMintTokenProgram = await getTokenProgramForMint(connection, quoteMintPk);
435
+ const outputAta = await (0, spl_token_1.getAssociatedTokenAddress)(quoteMintPk, wallet.publicKey);
436
+ const tickArrayBitmapExt = deriveTickArrayBitmapExtension(poolId);
437
+ const inputVaultMint = zeroForOne ? poolState.tokenMint0 : poolState.tokenMint1;
438
+ const outputVaultMint = zeroForOne ? poolState.tokenMint1 : poolState.tokenMint0;
439
+ const poolParams = {
440
+ poolId,
441
+ ammConfig: poolState.ammConfig,
442
+ observationState: poolState.observationKey,
443
+ tokenVault0: poolState.tokenVault0,
444
+ tokenVault1: poolState.tokenVault1,
445
+ tokenMint0: poolState.tokenMint0,
446
+ tokenMint1: poolState.tokenMint1,
447
+ };
448
+ // isBaseInput = true: we always specify exact input amount
449
+ // zeroForOne: direction flag for vault selection
450
+ const swapIx = createClmmSwapV2Ix(poolParams, wallet.publicKey, inputAta, outputAta, sellAmount, minOut, sqrtPriceLimitX64, true, // isBaseInput — exact input swap
451
+ tickArrays, inputVaultMint, outputVaultMint, tickArrayBitmapExt, zeroForOne);
452
+ const ixs = [];
453
+ if (includeComputeBudget) {
454
+ ixs.push(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priorityFee }));
455
+ }
456
+ // Create output ATA (WSOL) and ensure input ATA exists
457
+ ixs.push((0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(wallet.publicKey, outputAta, wallet.publicKey, quoteMintPk), swapIx);
458
+ // Close WSOL ATA to unwrap SOL proceeds
459
+ if (quoteMintPk.equals(WSOL_MINT_PK)) {
460
+ ixs.push((0, spl_token_1.createCloseAccountInstruction)(outputAta, wallet.publicKey, wallet.publicKey, [], TOKEN_PROGRAM_ID_PK));
461
+ }
462
+ return ixs;
463
+ }
464
+ // ---------------------------------------------------------------------------
465
+ // Adapter class
466
+ // ---------------------------------------------------------------------------
467
+ class RaydiumClmmAdapter {
468
+ name = "raydium-clmm";
469
+ protocol = "clmm";
470
+ capabilities = (0, types_1.defaultCapabilities)({
471
+ canBuy: true,
472
+ canSell: true,
473
+ canSnipe: true,
474
+ canFindPool: true,
475
+ canGetPrice: true,
476
+ });
477
+ // ----- Core: buy -----
478
+ async buy(params) {
479
+ const tokenMint = (0, types_1.requireTokenMint)(params, this.name);
480
+ const connection = (0, config_1.getConnection)();
481
+ const wallet = (0, config_1.getWallet)();
482
+ const tokenMintPk = new web3_js_1.PublicKey(tokenMint);
483
+ const quoteMintPk = params.quoteMint ? new web3_js_1.PublicKey(params.quoteMint) : WSOL_MINT_PK;
484
+ const priorityFee = params.opts?.priorityFeeMicroLamports ?? types_1.DEFAULT_PRIORITY_FEE_MICRO_LAMPORTS;
485
+ const computeUnits = params.opts?.computeUnitLimit ?? 300_000;
486
+ // Discover or use provided pool
487
+ let poolId;
488
+ if (params.poolAddress) {
489
+ poolId = new web3_js_1.PublicKey(params.poolAddress);
490
+ }
491
+ else {
492
+ const found = await discoverClmmPool(connection, tokenMintPk, quoteMintPk);
493
+ if (!found)
494
+ throw new types_1.PoolNotFoundError(this.name, tokenMint, params.quoteMint);
495
+ poolId = found;
496
+ }
497
+ // Calculate amounts
498
+ const quoteDecimals = quoteMintPk.equals(WSOL_MINT_PK) ? 9 : 6;
499
+ const amountIn = BigInt(Math.floor(params.amountSol * 10 ** quoteDecimals));
500
+ const ixs = await buildClmmSwapInstructions(connection, wallet, tokenMintPk, quoteMintPk, poolId, amountIn, 0n, priorityFee, true);
501
+ // Prepend compute unit limit
502
+ ixs.unshift(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnits }));
503
+ // Submit via RPC send+confirm
504
+ const result = await (0, send_rpc_1.sendAndConfirmVtx)(connection, ixs, wallet);
505
+ return {
506
+ txSignature: result.txSignature,
507
+ confirmed: result.confirmed,
508
+ amountIn: params.amountSol,
509
+ amountInToken: quoteMintPk.equals(WSOL_MINT_PK) ? "SOL" : quoteMintPk.toBase58(),
510
+ dex: this.name,
511
+ poolAddress: poolId.toBase58(),
512
+ };
513
+ }
514
+ // ----- Core: sell -----
515
+ async sell(params) {
516
+ const tokenMint = (0, types_1.requireTokenMint)(params, this.name);
517
+ const connection = (0, config_1.getConnection)();
518
+ const wallet = (0, config_1.getWallet)();
519
+ const tokenMintPk = new web3_js_1.PublicKey(tokenMint);
520
+ const quoteMintPk = params.quoteMint ? new web3_js_1.PublicKey(params.quoteMint) : WSOL_MINT_PK;
521
+ const priorityFee = params.opts?.priorityFeeMicroLamports ?? types_1.DEFAULT_PRIORITY_FEE_MICRO_LAMPORTS;
522
+ const computeUnits = params.opts?.computeUnitLimit ?? 300_000;
523
+ // Discover pool
524
+ let poolId;
525
+ if (params.poolAddress) {
526
+ poolId = new web3_js_1.PublicKey(params.poolAddress);
527
+ }
528
+ else {
529
+ const found = await discoverClmmPool(connection, tokenMintPk, quoteMintPk);
530
+ if (!found)
531
+ throw new types_1.PoolNotFoundError(this.name, tokenMint, params.quoteMint);
532
+ poolId = found;
533
+ }
534
+ // Get token balance
535
+ const balance = await getTokenBalance(connection, tokenMintPk, wallet.publicKey);
536
+ const sellAmount = (balance.amount * BigInt(Math.floor(params.percentage))) / 100n;
537
+ if (sellAmount === 0n) {
538
+ return {
539
+ txSignature: "",
540
+ confirmed: false,
541
+ amountIn: 0,
542
+ amountInToken: tokenMint,
543
+ dex: this.name,
544
+ poolAddress: poolId.toBase58(),
545
+ };
546
+ }
547
+ const ixs = await buildClmmSellInstructions(connection, wallet, tokenMintPk, quoteMintPk, poolId, sellAmount, 0n, priorityFee, true);
548
+ ixs.unshift(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnits }));
549
+ // Submit via RPC send+confirm
550
+ const result = await (0, send_rpc_1.sendAndConfirmVtx)(connection, ixs, wallet);
551
+ const humanSellAmount = Number(sellAmount) / 10 ** balance.decimals;
552
+ return {
553
+ txSignature: result.txSignature,
554
+ confirmed: result.confirmed,
555
+ amountIn: humanSellAmount,
556
+ amountInToken: tokenMint,
557
+ dex: this.name,
558
+ poolAddress: poolId.toBase58(),
559
+ };
560
+ }
561
+ // ----- Snipe (uses native IX path from buy-v2.ts) -----
562
+ async snipe(params) {
563
+ const connection = (0, config_1.getConnection)();
564
+ const wallet = (0, config_1.getWallet)();
565
+ const tokenMint = new web3_js_1.PublicKey(params.tokenMint);
566
+ const quoteMintPk = params.quoteMint ? new web3_js_1.PublicKey(params.quoteMint) : WSOL_MINT_PK;
567
+ const poolId = new web3_js_1.PublicKey(params.poolAddress);
568
+ const priorityFee = params.opts?.priorityFeeMicroLamports ?? 1_000_000;
569
+ const quoteDecimals = quoteMintPk.equals(WSOL_MINT_PK) ? 9 : 6;
570
+ const amountIn = BigInt(Math.floor(params.amountSol * 10 ** quoteDecimals));
571
+ const ixs = await buildClmmSwapInstructions(connection, wallet, tokenMint, quoteMintPk, poolId, amountIn, 0n, priorityFee, true);
572
+ const { blockhash } = await connection.getLatestBlockhash();
573
+ const results = await (0, landing_1.landTransaction)(ixs, wallet, blockhash, {
574
+ dex: this.name,
575
+ operation: "snipe",
576
+ tipSol: params.tipSol,
577
+ });
578
+ const firstAccepted = results.find((r) => r.accepted);
579
+ return {
580
+ txSignature: firstAccepted?.signature ?? "",
581
+ confirmed: !!firstAccepted?.accepted,
582
+ amountIn: params.amountSol,
583
+ amountInToken: quoteMintPk.equals(WSOL_MINT_PK) ? "SOL" : quoteMintPk.toBase58(),
584
+ dex: this.name,
585
+ poolAddress: poolId.toBase58(),
586
+ };
587
+ }
588
+ // ----- Build swap IXs -----
589
+ async buildSwapIxs(params) {
590
+ const tokenMint = (0, types_1.requireTokenMint)(params, this.name);
591
+ const connection = (0, config_1.getConnection)();
592
+ const wallet = (0, config_1.getWallet)();
593
+ const isBuy = "amountSol" in params;
594
+ const tokenMintPk = new web3_js_1.PublicKey(tokenMint);
595
+ const quoteMintPk = params.quoteMint ? new web3_js_1.PublicKey(params.quoteMint) : WSOL_MINT_PK;
596
+ let poolId;
597
+ if (params.poolAddress) {
598
+ poolId = new web3_js_1.PublicKey(params.poolAddress);
599
+ }
600
+ else {
601
+ const found = await discoverClmmPool(connection, tokenMintPk, quoteMintPk);
602
+ if (!found)
603
+ throw new types_1.PoolNotFoundError(this.name, tokenMint, params.quoteMint);
604
+ poolId = found;
605
+ }
606
+ let instructions;
607
+ if (isBuy) {
608
+ const buyParams = params;
609
+ const quoteDecimals = quoteMintPk.equals(WSOL_MINT_PK) ? 9 : 6;
610
+ const amountIn = BigInt(Math.floor(buyParams.amountSol * 10 ** quoteDecimals));
611
+ instructions = await buildClmmSwapInstructions(connection, wallet, tokenMintPk, quoteMintPk, poolId, amountIn, 0n, 0, false);
612
+ }
613
+ else {
614
+ const sellParams = params;
615
+ const balance = await getTokenBalance(connection, tokenMintPk, wallet.publicKey);
616
+ const sellAmount = (balance.amount * BigInt(Math.floor(sellParams.percentage))) / 100n;
617
+ instructions = await buildClmmSellInstructions(connection, wallet, tokenMintPk, quoteMintPk, poolId, sellAmount, 0n, 0, false);
618
+ }
619
+ return { instructions, signers: [] };
620
+ }
621
+ // ----- Pool discovery -----
622
+ async findPool(baseMint, quoteMint) {
623
+ const connection = (0, config_1.getConnection)();
624
+ const baseMintPk = new web3_js_1.PublicKey(baseMint);
625
+ const quoteMintPk = quoteMint ? new web3_js_1.PublicKey(quoteMint) : WSOL_MINT_PK;
626
+ const poolId = await discoverClmmPool(connection, baseMintPk, quoteMintPk);
627
+ if (!poolId)
628
+ return null;
629
+ try {
630
+ const poolState = await fetchClmmPoolState(connection, poolId);
631
+ const price = sqrtPriceX64ToPrice(poolState.sqrtPriceX64, poolState.mintDecimals0, poolState.mintDecimals1);
632
+ return {
633
+ address: poolId.toBase58(),
634
+ dex: this.name,
635
+ protocol: this.protocol,
636
+ baseMint: poolState.tokenMint0.toBase58(),
637
+ quoteMint: poolState.tokenMint1.toBase58(),
638
+ baseDecimals: poolState.mintDecimals0,
639
+ quoteDecimals: poolState.mintDecimals1,
640
+ price,
641
+ };
642
+ }
643
+ catch {
644
+ return {
645
+ address: poolId.toBase58(),
646
+ dex: this.name,
647
+ protocol: this.protocol,
648
+ baseMint,
649
+ quoteMint: quoteMintPk.toBase58(),
650
+ baseDecimals: 6,
651
+ quoteDecimals: quoteMintPk.equals(WSOL_MINT_PK) ? 9 : 6,
652
+ };
653
+ }
654
+ }
655
+ // ----- Price -----
656
+ async getPrice(poolAddress) {
657
+ const connection = (0, config_1.getConnection)();
658
+ const poolId = new web3_js_1.PublicKey(poolAddress);
659
+ const poolState = await fetchClmmPoolState(connection, poolId);
660
+ let price = sqrtPriceX64ToPrice(poolState.sqrtPriceX64, poolState.mintDecimals0, poolState.mintDecimals1);
661
+ return {
662
+ price,
663
+ baseMint: poolState.tokenMint0.toBase58(),
664
+ quoteMint: poolState.tokenMint1.toBase58(),
665
+ source: "on-chain",
666
+ poolAddress,
667
+ timestamp: Date.now(),
668
+ };
669
+ }
670
+ }
671
+ // ---------------------------------------------------------------------------
672
+ // Register adapter
673
+ // ---------------------------------------------------------------------------
674
+ (0, index_1.registerAdapter)(new RaydiumClmmAdapter());
675
+ //# sourceMappingURL=raydium-clmm.js.map