@hawksightco/hawk-sdk 1.3.265 → 1.3.267

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 (181) hide show
  1. package/dist/addresses.d.ts +37 -0
  2. package/dist/addresses.d.ts.map +1 -0
  3. package/dist/addresses.js +84 -0
  4. package/dist/anchor.d.ts +22 -0
  5. package/dist/anchor.d.ts.map +1 -0
  6. package/dist/anchor.js +121 -0
  7. package/dist/classes/AltStorage.d.ts +29 -0
  8. package/dist/classes/AltStorage.d.ts.map +1 -0
  9. package/dist/classes/AltStorage.js +58 -0
  10. package/dist/classes/Atomicity.d.ts +34 -0
  11. package/dist/classes/Atomicity.d.ts.map +1 -0
  12. package/dist/classes/Atomicity.js +110 -0
  13. package/dist/classes/Client.d.ts +35 -0
  14. package/dist/classes/Client.d.ts.map +1 -0
  15. package/dist/classes/Client.js +66 -0
  16. package/dist/classes/CombineTransactions.d.ts +11 -0
  17. package/dist/classes/CombineTransactions.d.ts.map +1 -0
  18. package/dist/classes/CombineTransactions.js +58 -0
  19. package/dist/classes/CreateTxMetadata.d.ts +100 -0
  20. package/dist/classes/CreateTxMetadata.d.ts.map +1 -0
  21. package/dist/classes/CreateTxMetadata.js +415 -0
  22. package/dist/classes/General.d.ts +87 -0
  23. package/dist/classes/General.d.ts.map +1 -0
  24. package/dist/classes/General.js +176 -0
  25. package/dist/classes/GeneralUtility.d.ts +79 -0
  26. package/dist/classes/GeneralUtility.d.ts.map +1 -0
  27. package/dist/classes/GeneralUtility.js +121 -0
  28. package/dist/classes/HawkAPI.d.ts +122 -0
  29. package/dist/classes/HawkAPI.d.ts.map +1 -0
  30. package/dist/classes/HawkAPI.js +169 -0
  31. package/dist/classes/Health.d.ts +29 -0
  32. package/dist/classes/Health.d.ts.map +1 -0
  33. package/dist/classes/Health.js +48 -0
  34. package/dist/classes/JupiterAlts.d.ts +37 -0
  35. package/dist/classes/JupiterAlts.d.ts.map +1 -0
  36. package/dist/classes/JupiterAlts.js +114 -0
  37. package/dist/classes/JupiterSwap.d.ts +21 -0
  38. package/dist/classes/JupiterSwap.d.ts.map +1 -0
  39. package/dist/classes/JupiterSwap.js +40 -0
  40. package/dist/classes/Logging.d.ts +13 -0
  41. package/dist/classes/Logging.d.ts.map +1 -0
  42. package/dist/classes/Logging.js +50 -0
  43. package/dist/classes/MultiTransaction.d.ts +75 -0
  44. package/dist/classes/MultiTransaction.d.ts.map +1 -0
  45. package/dist/classes/MultiTransaction.js +296 -0
  46. package/dist/classes/RaydiumSDK.d.ts +67 -0
  47. package/dist/classes/RaydiumSDK.d.ts.map +1 -0
  48. package/dist/classes/RaydiumSDK.js +206 -0
  49. package/dist/classes/Search.d.ts +100 -0
  50. package/dist/classes/Search.d.ts.map +1 -0
  51. package/dist/classes/Search.js +216 -0
  52. package/dist/classes/SimpleIxGenerator.d.ts +57 -0
  53. package/dist/classes/SimpleIxGenerator.d.ts.map +1 -0
  54. package/dist/classes/SimpleIxGenerator.js +62 -0
  55. package/dist/classes/SimplePdaGenerator.d.ts +28 -0
  56. package/dist/classes/SimplePdaGenerator.d.ts.map +1 -0
  57. package/dist/classes/SimplePdaGenerator.js +33 -0
  58. package/dist/classes/Transaction.d.ts +229 -0
  59. package/dist/classes/Transaction.d.ts.map +1 -0
  60. package/dist/classes/Transaction.js +643 -0
  61. package/dist/classes/Transaction2.d.ts +107 -0
  62. package/dist/classes/Transaction2.d.ts.map +1 -0
  63. package/dist/classes/Transaction2.js +249 -0
  64. package/dist/classes/Transaction3.d.ts +165 -0
  65. package/dist/classes/Transaction3.d.ts.map +1 -0
  66. package/dist/classes/Transaction3.js +416 -0
  67. package/dist/classes/TransactionBatchExecute.d.ts +163 -0
  68. package/dist/classes/TransactionBatchExecute.d.ts.map +1 -0
  69. package/dist/classes/TransactionBatchExecute.js +466 -0
  70. package/dist/classes/TransactionBatchExecute2.d.ts +99 -0
  71. package/dist/classes/TransactionBatchExecute2.d.ts.map +1 -0
  72. package/dist/classes/TransactionBatchExecute2.js +357 -0
  73. package/dist/classes/Transactions.d.ts +586 -0
  74. package/dist/classes/Transactions.d.ts.map +1 -0
  75. package/dist/classes/Transactions.js +7667 -0
  76. package/dist/classes/TxGenerator.d.ts +350 -0
  77. package/dist/classes/TxGenerator.d.ts.map +1 -0
  78. package/dist/classes/TxGenerator.js +1957 -0
  79. package/dist/classes/TxGeneratorAutomations.d.ts +186 -0
  80. package/dist/classes/TxGeneratorAutomations.d.ts.map +1 -0
  81. package/dist/classes/TxGeneratorAutomations.js +897 -0
  82. package/dist/classes/Util.d.ts +87 -0
  83. package/dist/classes/Util.d.ts.map +1 -0
  84. package/dist/classes/Util.js +148 -0
  85. package/dist/classes/account-cache/AccountCache.d.ts +54 -0
  86. package/dist/classes/account-cache/AccountCache.d.ts.map +1 -0
  87. package/dist/classes/account-cache/AccountCache.js +143 -0
  88. package/dist/classes/account-cache/MintCache.d.ts +33 -0
  89. package/dist/classes/account-cache/MintCache.d.ts.map +1 -0
  90. package/dist/classes/account-cache/MintCache.js +47 -0
  91. package/dist/classes/account-cache/TokenCache.d.ts +33 -0
  92. package/dist/classes/account-cache/TokenCache.d.ts.map +1 -0
  93. package/dist/classes/account-cache/TokenCache.js +47 -0
  94. package/dist/errors.d.ts +13 -0
  95. package/dist/errors.d.ts.map +1 -0
  96. package/dist/errors.js +96 -0
  97. package/dist/functions.d.ts +514 -0
  98. package/dist/functions.d.ts.map +1 -0
  99. package/dist/functions.js +1636 -0
  100. package/dist/hawksight.d.ts +53 -0
  101. package/dist/hawksight.d.ts.map +1 -0
  102. package/dist/hawksight.js +328 -0
  103. package/dist/hsToMeteora.d.ts +31 -0
  104. package/dist/hsToMeteora.d.ts.map +1 -0
  105. package/dist/hsToMeteora.js +3175 -0
  106. package/dist/idl/iyf-extension-idl.d.ts +14583 -0
  107. package/dist/idl/iyf-extension-idl.d.ts.map +1 -0
  108. package/dist/idl/iyf-extension-idl.js +14578 -0
  109. package/dist/idl/iyf-extension-wrapper.d.ts +112 -0
  110. package/dist/idl/iyf-extension-wrapper.d.ts.map +1 -0
  111. package/dist/idl/iyf-extension-wrapper.js +2 -0
  112. package/dist/idl/iyf-main-idl.d.ts +12078 -0
  113. package/dist/idl/iyf-main-idl.d.ts.map +1 -0
  114. package/dist/idl/iyf-main-idl.js +12073 -0
  115. package/dist/idl/iyf-main-wrapper.d.ts +112 -0
  116. package/dist/idl/iyf-main-wrapper.d.ts.map +1 -0
  117. package/dist/idl/iyf-main-wrapper.js +2 -0
  118. package/dist/idl/jupiter-idl.d.ts +3063 -0
  119. package/dist/idl/jupiter-idl.d.ts.map +1 -0
  120. package/dist/idl/jupiter-idl.js +3061 -0
  121. package/dist/idl/meteora-idl.d.ts +7371 -0
  122. package/dist/idl/meteora-idl.d.ts.map +1 -0
  123. package/dist/idl/meteora-idl.js +7372 -0
  124. package/dist/idl/orca-idl.d.ts +3833 -0
  125. package/dist/idl/orca-idl.d.ts.map +1 -0
  126. package/dist/idl/orca-idl.js +3834 -0
  127. package/dist/idl/raydium-idl.d.ts +3054 -0
  128. package/dist/idl/raydium-idl.d.ts.map +1 -0
  129. package/dist/idl/raydium-idl.js +3055 -0
  130. package/dist/index.d.ts +9 -0
  131. package/dist/index.d.ts.map +1 -0
  132. package/dist/index.js +31 -0
  133. package/dist/ixGenerator/IyfExtensionIxGenerator.d.ts +126 -0
  134. package/dist/ixGenerator/IyfExtensionIxGenerator.d.ts.map +1 -0
  135. package/dist/ixGenerator/IyfExtensionIxGenerator.js +467 -0
  136. package/dist/ixGenerator/IyfMainIxGenerator.d.ts +330 -0
  137. package/dist/ixGenerator/IyfMainIxGenerator.d.ts.map +1 -0
  138. package/dist/ixGenerator/IyfMainIxGenerator.js +1239 -0
  139. package/dist/ixGenerator/MeteoraDlmmIxGenerator.d.ts +685 -0
  140. package/dist/ixGenerator/MeteoraDlmmIxGenerator.d.ts.map +1 -0
  141. package/dist/ixGenerator/MeteoraDlmmIxGenerator.js +3008 -0
  142. package/dist/ixGenerator/OrcaIxGenerator.d.ts +119 -0
  143. package/dist/ixGenerator/OrcaIxGenerator.d.ts.map +1 -0
  144. package/dist/ixGenerator/OrcaIxGenerator.js +438 -0
  145. package/dist/ixGenerator/RaydiumIxGenerator.d.ts +99 -0
  146. package/dist/ixGenerator/RaydiumIxGenerator.d.ts.map +1 -0
  147. package/dist/ixGenerator/RaydiumIxGenerator.js +558 -0
  148. package/dist/ixGenerator/UtilIxGenerator.d.ts +20 -0
  149. package/dist/ixGenerator/UtilIxGenerator.d.ts.map +1 -0
  150. package/dist/ixGenerator/UtilIxGenerator.js +25 -0
  151. package/dist/meteora/index.d.ts +2 -0
  152. package/dist/meteora/index.d.ts.map +1 -0
  153. package/dist/meteora/index.js +17 -0
  154. package/dist/meteora/liquidityStrategy.d.ts +408 -0
  155. package/dist/meteora/liquidityStrategy.d.ts.map +1 -0
  156. package/dist/meteora/liquidityStrategy.js +1325 -0
  157. package/dist/meteora.d.ts +669 -0
  158. package/dist/meteora.d.ts.map +1 -0
  159. package/dist/meteora.js +1932 -0
  160. package/dist/orca.d.ts +57 -0
  161. package/dist/orca.d.ts.map +1 -0
  162. package/dist/orca.js +123 -0
  163. package/dist/pdaGenerator/HawksightPdaGenerator.d.ts +29 -0
  164. package/dist/pdaGenerator/HawksightPdaGenerator.d.ts.map +1 -0
  165. package/dist/pdaGenerator/HawksightPdaGenerator.js +75 -0
  166. package/dist/pdaGenerator/MeteoraPdaGenerator.d.ts +76 -0
  167. package/dist/pdaGenerator/MeteoraPdaGenerator.d.ts.map +1 -0
  168. package/dist/pdaGenerator/MeteoraPdaGenerator.js +166 -0
  169. package/dist/pdaGenerator/OrcaPdaGenerator.d.ts +23 -0
  170. package/dist/pdaGenerator/OrcaPdaGenerator.d.ts.map +1 -0
  171. package/dist/pdaGenerator/OrcaPdaGenerator.js +68 -0
  172. package/dist/pdaGenerator/RaydiumPdaGenerator.d.ts +49 -0
  173. package/dist/pdaGenerator/RaydiumPdaGenerator.d.ts.map +1 -0
  174. package/dist/pdaGenerator/RaydiumPdaGenerator.js +114 -0
  175. package/dist/pdaGenerator/UtilPdaGenerator.d.ts +8 -0
  176. package/dist/pdaGenerator/UtilPdaGenerator.d.ts.map +1 -0
  177. package/dist/pdaGenerator/UtilPdaGenerator.js +51 -0
  178. package/dist/types.d.ts +1104 -0
  179. package/dist/types.d.ts.map +1 -0
  180. package/dist/types.js +95 -0
  181. package/package.json +6 -5
@@ -0,0 +1,1932 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.InitializePositionAndAddLiquidityByStrategyPdaBuilder = exports.InitializePositionAndAddLiquidityByStrategyBuilderLabeled = exports.InitializePositionAndAddLiquidityByStrategyBuilder = exports.RemoveLiquidityPdaBuilder = exports.RemoveLiquidityBuilder = exports.AddLiquidityByStrategyBuilder = exports.ClaimAllRewardsByPositionBuilder = exports.MeteoraFunctions = exports.MeteoraDLMM = void 0;
49
+ const dlmm_1 = __importStar(require("@meteora-ag/dlmm"));
50
+ const bn_js_1 = __importDefault(require("bn.js"));
51
+ const web3 = __importStar(require("@solana/web3.js"));
52
+ const errors_1 = require("./errors");
53
+ const addresses_1 = require("./addresses");
54
+ const functions_1 = require("./functions");
55
+ const types_1 = require("./types");
56
+ const anchor_1 = require("./anchor");
57
+ const Logging_1 = require("./classes/Logging");
58
+ const bs58_1 = __importDefault(require("bs58"));
59
+ /**
60
+ * Manual implementation of getTokenProgramMapForMints using getMultipleAccounts
61
+ */
62
+ function getTokenProgramMapForMintsManual(connection, mints) {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ if (mints.length === 0) {
65
+ throw new Error(`No mints were passed in the parameter.`);
66
+ }
67
+ // Get multiple accounts info directly
68
+ const accountsInfo = yield connection.getMultipleAccountsInfo(mints);
69
+ let tokenProgramMap = {};
70
+ for (let i = 0; i < mints.length; i++) {
71
+ const pubkey = mints[i];
72
+ const accountInfo = accountsInfo[i];
73
+ if (!accountInfo) {
74
+ throw new Error(`Account info not found for mint: ${pubkey.toString()}`);
75
+ }
76
+ const tokenProgram = accountInfo.owner;
77
+ tokenProgramMap[pubkey.toString()] = tokenProgram;
78
+ }
79
+ return tokenProgramMap;
80
+ });
81
+ }
82
+ class MeteoraDLMM {
83
+ constructor(dlmm, ix) {
84
+ this.dlmm = dlmm;
85
+ this.ix = ix;
86
+ this.pubkey = this.dlmm.pubkey;
87
+ }
88
+ static create(connection, poolAddress, ix) {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ var _a;
91
+ if (this._instance == undefined || this._poolAddress !== poolAddress || ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.rpcEndpoint) !== connection.rpcEndpoint) {
92
+ const dlmm = yield dlmm_1.default.create(connection, poolAddress);
93
+ this._poolAddress = poolAddress;
94
+ this._connection = connection;
95
+ this._instance = new MeteoraDLMM(dlmm, ix);
96
+ this._program = dlmm.program;
97
+ }
98
+ return this._instance;
99
+ });
100
+ }
101
+ /**
102
+ * Meteora DLMM Program
103
+ *
104
+ * @param connection
105
+ */
106
+ static program(connection) {
107
+ return __awaiter(this, void 0, void 0, function* () {
108
+ if (this._program == undefined) {
109
+ const dlmm = yield dlmm_1.default.create(connection, addresses_1.SOME_METEORA_DLMM_POOL);
110
+ this._program = dlmm.program;
111
+ }
112
+ return this._program;
113
+ });
114
+ }
115
+ getXYAmountDistribution(distribution, activeBin, lowerRange, upperRange) {
116
+ let xYAmountDistribution;
117
+ const bins = [];
118
+ if (lowerRange >= upperRange) {
119
+ throw new errors_1.AppError(`Lower range (${lowerRange}) cannot be greater than or less than upper range ((${upperRange})).`, `getXYAmountDistribution`);
120
+ }
121
+ for (let i = lowerRange; i <= upperRange; i++) {
122
+ bins.push(i);
123
+ }
124
+ if (distribution === "SPOT") {
125
+ xYAmountDistribution = (0, dlmm_1.calculateSpotDistribution)(activeBin.binId, bins);
126
+ }
127
+ else if (distribution === "CURVE") {
128
+ xYAmountDistribution = (0, dlmm_1.calculateNormalDistribution)(activeBin.binId, bins);
129
+ }
130
+ else if (distribution === "BID-ASK") {
131
+ xYAmountDistribution = (0, dlmm_1.calculateBidAskDistribution)(activeBin.binId, bins);
132
+ }
133
+ else {
134
+ throw new errors_1.AppError(`Invalid strategy ${distribution}. Can only be SPOT, CURVE, or BID-ASK.`, `getXYAmountDistribution`);
135
+ }
136
+ return xYAmountDistribution;
137
+ }
138
+ getActiveBin() {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ return yield this.dlmm.getActiveBin();
141
+ });
142
+ }
143
+ getPositionsByUserAndLbPair(userPubKey) {
144
+ return __awaiter(this, void 0, void 0, function* () {
145
+ return yield this.dlmm.getPositionsByUserAndLbPair(userPubKey);
146
+ });
147
+ }
148
+ /**
149
+ * Initializes a position and adds liquidity to the specified strategy, with various steps including
150
+ * handling wrapped SOL tokens, depositing tokens, adding liquidity, and handling dust withdrawals.
151
+ *
152
+ * @param {web3.PublicKey} userWallet - The public key of the user's wallet executing the transaction.
153
+ * @param {web3.PublicKey} payer - The public key of the transaction payer.
154
+ * @param {Object} params - The parameters for initializing the position and adding liquidity.
155
+ * @param {web3.PublicKey} params.positionPubKey - The public key of the position to be initialized.
156
+ * @param {BN} params.totalXAmount - The total amount of X tokens to be used for liquidity.
157
+ * @param {BN} params.totalYAmount - The total amount of Y tokens to be used for liquidity.
158
+ * @param {Object} params.strategy - The strategy details for adding liquidity.
159
+ * @param {number} params.strategy.maxBinId - The maximum bin ID for the strategy.
160
+ * @param {number} params.strategy.minBinId - The minimum bin ID for the strategy.
161
+ * @param {StrategyType} params.strategy.strategyType - The type of strategy to be applied.
162
+ * @param {web3.PublicKey} params.user - The public key of the user executing the transaction.
163
+ * @param {number} [params.slippage] - Optional slippage tolerance for the transaction.
164
+ *
165
+ * @returns {Promise<web3.TransactionInstruction[]>} - A promise that resolves to an array of transaction instructions.
166
+ *
167
+ * @throws {Error} - Throws an error if input token(s) do not exist on the blockchain.
168
+ */
169
+ initializePositionAndAddLiquidityByStrategy(connection, userWallet, payer, params, meteoraToHawksight) {
170
+ return __awaiter(this, void 0, void 0, function* () {
171
+ var _a, _b, _c, _d, _e;
172
+ if (!!!params.skipInputTokenCheck) {
173
+ // Throw error if input token(s) do not exist on blockchain
174
+ yield (0, functions_1.inputTokenExists)(anchor_1.Anchor.instance().connection, userWallet, [
175
+ this.dlmm.tokenX.publicKey,
176
+ this.dlmm.tokenY.publicKey,
177
+ ]);
178
+ }
179
+ let singleSidedX;
180
+ const [strategyType, oneSide] = types_1.StrategyTypeMap2[params.strategy.strategyType];
181
+ if (oneSide) {
182
+ if (params.totalXAmount.gt(new bn_js_1.default(0)) && params.totalYAmount.eq(new bn_js_1.default(0))) {
183
+ singleSidedX = true;
184
+ }
185
+ else if (params.totalXAmount.eq(new bn_js_1.default(0)) && params.totalYAmount.gt(new bn_js_1.default(0))) {
186
+ singleSidedX = false;
187
+ }
188
+ else {
189
+ throw new errors_1.AppError("Total X or Y amount must be greater than 0 when adding liquidity one-sided", `initializePositionAndAddLiquidityByStrategy`);
190
+ }
191
+ }
192
+ const strategy = {
193
+ maxBinId: params.strategy.maxBinId,
194
+ minBinId: params.strategy.minBinId,
195
+ strategyType,
196
+ singleSidedX,
197
+ };
198
+ // Generate InitializePosition and AddLiquidityByStrategy instruction from Meteora API
199
+ const txn = yield this.dlmm.initializePositionAndAddLiquidityByStrategy({
200
+ positionPubKey: params.positionPubKey,
201
+ totalXAmount: params.totalXAmount,
202
+ totalYAmount: params.totalYAmount,
203
+ strategy,
204
+ user: params.user,
205
+ });
206
+ // Filter out non-meteora instructions
207
+ const ixs = (0, functions_1.getIxs)(txn).filter((ix) => ix.programId.equals(addresses_1.METEORA_DLMM_PROGRAM));
208
+ // Find mint from meteora instructions
209
+ const mints = (0, functions_1.getMintsFromInstruction)({
210
+ instructions: ixs,
211
+ find: {
212
+ AddLiquidityByStrategy: {
213
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
214
+ mintIndices: [7, 8],
215
+ },
216
+ "add_liquidity_by_strategy2": {
217
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
218
+ mintIndices: [7, 8],
219
+ manualSnakeCase: true,
220
+ },
221
+ AddLiquidityByStrategyOneSide: {
222
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
223
+ mintIndices: [5],
224
+ },
225
+ },
226
+ });
227
+ return new InitializePositionAndAddLiquidityByStrategyBuilder(
228
+ // Step 1: Init wSOL token account for user wallet (if X or Y token is wSOL)
229
+ // H-2106: also CreateIdempotent the non-wSOL source ATAs (see functions.ts).
230
+ [
231
+ ...(0, functions_1.wrapSolIfMintIsWsol)(userWallet, payer, [
232
+ { mint: this.dlmm.tokenX.publicKey, amount: params.totalXAmount },
233
+ { mint: this.dlmm.tokenY.publicKey, amount: params.totalYAmount },
234
+ ]),
235
+ ...yield (0, functions_1.createSourceAtasIdempotent)(connection, userWallet, payer, [
236
+ { mint: this.dlmm.tokenX.publicKey, amount: params.totalXAmount },
237
+ { mint: this.dlmm.tokenY.publicKey, amount: params.totalYAmount },
238
+ ]),
239
+ ],
240
+ // Step 2: Deposit X and Y token to UserPDA
241
+ yield this.ix.iyfMain.depositMultipleTokenWithToken2022({
242
+ connection,
243
+ payer: userWallet,
244
+ deposit: [
245
+ { mint: this.dlmm.tokenX.publicKey, amount: params.totalXAmount },
246
+ { mint: this.dlmm.tokenY.publicKey, amount: params.totalYAmount },
247
+ ],
248
+ pdaTokenType: (_a = params.opt) === null || _a === void 0 ? void 0 : _a.pdaTokenType,
249
+ }),
250
+ // Step 3: Initialize position and add liquidity by strategy
251
+ yield meteoraToHawksight({
252
+ ixs,
253
+ userPda: params.user,
254
+ authority: userWallet,
255
+ opt: {
256
+ pdaTokenType: (_b = params.opt) === null || _b === void 0 ? void 0 : _b.pdaTokenType,
257
+ params: {
258
+ withAmount: (_c = params.opt) === null || _c === void 0 ? void 0 : _c.withAmount,
259
+ fuelAccount: (_d = params.opt) === null || _d === void 0 ? void 0 : _d.fuelAccount,
260
+ },
261
+ },
262
+ }),
263
+ // Step 4: Withdraw dust to user wallet
264
+ yield this.ix.iyfMain.withdrawMultipleTokenWithToken2022({
265
+ connection,
266
+ payer: userWallet,
267
+ withdraw: mints.map((mint) => {
268
+ return { mint, amount: new bn_js_1.default(0) };
269
+ }),
270
+ pdaTokenType: (_e = params.opt) === null || _e === void 0 ? void 0 : _e.pdaTokenType,
271
+ hasAmount: false,
272
+ }),
273
+ // Step 5: Close wSOL account (if there's any)
274
+ (0, functions_1.unwrapSolIfMintIsWsol)(userWallet, mints));
275
+ });
276
+ }
277
+ /**
278
+ * Initializes a position and adds liquidity to the specified strategy, with various steps including
279
+ * handling wrapped SOL tokens, depositing tokens, adding liquidity, and handling dust withdrawals.
280
+ *
281
+ * @param {web3.PublicKey} userWallet - The public key of the user's wallet executing the transaction.
282
+ * @param {web3.PublicKey} payer - The public key of the transaction payer.
283
+ * @param {Object} params - The parameters for initializing the position and adding liquidity.
284
+ * @param {web3.PublicKey} params.positionPubKey - The public key of the position to be initialized.
285
+ * @param {BN} params.totalXAmount - The total amount of X tokens to be used for liquidity.
286
+ * @param {BN} params.totalYAmount - The total amount of Y tokens to be used for liquidity.
287
+ * @param {Object} params.strategy - The strategy details for adding liquidity.
288
+ * @param {number} params.strategy.maxBinId - The maximum bin ID for the strategy.
289
+ * @param {number} params.strategy.minBinId - The minimum bin ID for the strategy.
290
+ * @param {StrategyType} params.strategy.strategyType - The type of strategy to be applied.
291
+ * @param {web3.PublicKey} params.user - The public key of the user executing the transaction.
292
+ * @param {number} [params.slippage] - Optional slippage tolerance for the transaction.
293
+ *
294
+ * @returns {Promise<web3.TransactionInstruction[]>} - A promise that resolves to an array of transaction instructions.
295
+ *
296
+ * @throws {Error} - Throws an error if input token(s) do not exist on the blockchain.
297
+ */
298
+ initializePositionAndAddLiquidityByStrategyLabeled(connection, userWallet, payer, params, meteoraToHawksight) {
299
+ return __awaiter(this, void 0, void 0, function* () {
300
+ var _a, _b, _c, _d, _e;
301
+ if (!!!params.skipInputTokenCheck) {
302
+ // Throw error if input token(s) do not exist on blockchain
303
+ yield (0, functions_1.inputTokenExists)(anchor_1.Anchor.instance().connection, userWallet, [
304
+ this.dlmm.tokenX.publicKey,
305
+ this.dlmm.tokenY.publicKey,
306
+ ]);
307
+ }
308
+ let singleSidedX;
309
+ const [strategyType, oneSide] = types_1.StrategyTypeMap2[params.strategy.strategyType];
310
+ if (oneSide) {
311
+ if (params.totalXAmount.gt(new bn_js_1.default(0)) && params.totalYAmount.eq(new bn_js_1.default(0))) {
312
+ singleSidedX = true;
313
+ }
314
+ else if (params.totalXAmount.eq(new bn_js_1.default(0)) && params.totalYAmount.gt(new bn_js_1.default(0))) {
315
+ singleSidedX = false;
316
+ }
317
+ else {
318
+ throw new errors_1.AppError("Total X or Y amount must be greater than 0 when adding liquidity one-sided", `initializePositionAndAddLiquidityByStrategy`);
319
+ }
320
+ }
321
+ const strategy = {
322
+ maxBinId: params.strategy.maxBinId,
323
+ minBinId: params.strategy.minBinId,
324
+ strategyType,
325
+ singleSidedX,
326
+ };
327
+ // Generate InitializePosition and AddLiquidityByStrategy instruction from Meteora API
328
+ const txn = yield this.dlmm.initializePositionAndAddLiquidityByStrategy({
329
+ positionPubKey: params.positionPubKey,
330
+ totalXAmount: params.totalXAmount,
331
+ totalYAmount: params.totalYAmount,
332
+ strategy,
333
+ user: params.user,
334
+ });
335
+ // Filter out non-meteora instructions
336
+ const ixs = (0, functions_1.getIxs)(txn).filter((ix) => ix.programId.equals(addresses_1.METEORA_DLMM_PROGRAM));
337
+ // Find mint from meteora instructions
338
+ const mints = (0, functions_1.getMintsFromInstruction)({
339
+ instructions: ixs,
340
+ find: {
341
+ AddLiquidityByStrategy: {
342
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
343
+ mintIndices: [7, 8],
344
+ },
345
+ "add_liquidity_by_strategy2": {
346
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
347
+ mintIndices: [7, 8],
348
+ manualSnakeCase: true,
349
+ },
350
+ AddLiquidityByStrategyOneSide: {
351
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
352
+ mintIndices: [5],
353
+ },
354
+ },
355
+ });
356
+ return new InitializePositionAndAddLiquidityByStrategyBuilderLabeled(
357
+ // Step 1: Init wSOL token account for user wallet (if X or Y token is wSOL)
358
+ // H-2106: also CreateIdempotent the non-wSOL source ATAs (see functions.ts).
359
+ [
360
+ ...(0, functions_1.wrapSolIfMintIsWsolLabeled)(userWallet, payer, [
361
+ { mint: this.dlmm.tokenX.publicKey, amount: params.totalXAmount },
362
+ { mint: this.dlmm.tokenY.publicKey, amount: params.totalYAmount },
363
+ ]),
364
+ ...yield (0, functions_1.createSourceAtasIdempotentLabeled)(connection, userWallet, payer, [
365
+ { mint: this.dlmm.tokenX.publicKey, amount: params.totalXAmount },
366
+ { mint: this.dlmm.tokenY.publicKey, amount: params.totalYAmount },
367
+ ]),
368
+ ],
369
+ // Step 2: Deposit X and Y token to UserPDA
370
+ yield this.ix.iyfMain.depositMultipleTokenWithToken2022WithLabel({
371
+ connection,
372
+ payer: userWallet,
373
+ deposit: [
374
+ { mint: this.dlmm.tokenX.publicKey, amount: params.totalXAmount },
375
+ { mint: this.dlmm.tokenY.publicKey, amount: params.totalYAmount },
376
+ ],
377
+ pdaTokenType: (_a = params.opt) === null || _a === void 0 ? void 0 : _a.pdaTokenType,
378
+ }),
379
+ // Step 3: Initialize position and add liquidity by strategy
380
+ yield meteoraToHawksight({
381
+ ixs,
382
+ userPda: params.user,
383
+ authority: userWallet,
384
+ opt: {
385
+ pdaTokenType: (_b = params.opt) === null || _b === void 0 ? void 0 : _b.pdaTokenType,
386
+ params: {
387
+ withAmount: (_c = params.opt) === null || _c === void 0 ? void 0 : _c.withAmount,
388
+ fuelAccount: (_d = params.opt) === null || _d === void 0 ? void 0 : _d.fuelAccount,
389
+ },
390
+ },
391
+ classification: `initializePositionAndAddLiquidityByStrategyLabelled`,
392
+ }),
393
+ // Step 4: Withdraw dust to user wallet
394
+ yield this.ix.iyfMain.withdrawMultipleTokenWithToken2022WithLabel({
395
+ connection,
396
+ payer: userWallet,
397
+ withdraw: mints.map((mint) => {
398
+ return { mint, amount: new bn_js_1.default(0) };
399
+ }),
400
+ pdaTokenType: (_e = params.opt) === null || _e === void 0 ? void 0 : _e.pdaTokenType,
401
+ hasAmount: false,
402
+ }),
403
+ // Step 5: Close wSOL account (if there's any)
404
+ (0, functions_1.unwrapSolIfMintIsWsolLabeled)(userWallet, mints));
405
+ });
406
+ }
407
+ /**
408
+ * Initializes a position and adds liquidity to the specified strategy, with various steps including
409
+ * handling wrapped SOL tokens, depositing tokens, adding liquidity, and handling dust withdrawals.
410
+ *
411
+ * @param {web3.PublicKey} userWallet - The public key of the user's wallet executing the transaction.
412
+ * @param {web3.PublicKey} payer - The public key of the transaction payer.
413
+ * @param {Object} params - The parameters for initializing the position and adding liquidity.
414
+ * @param {web3.PublicKey} params.positionPubKey - The public key of the position to be initialized.
415
+ * @param {BN} params.totalXAmount - The total amount of X tokens to be used for liquidity.
416
+ * @param {BN} params.totalYAmount - The total amount of Y tokens to be used for liquidity.
417
+ * @param {Object} params.strategy - The strategy details for adding liquidity.
418
+ * @param {number} params.strategy.maxBinId - The maximum bin ID for the strategy.
419
+ * @param {number} params.strategy.minBinId - The minimum bin ID for the strategy.
420
+ * @param {StrategyType} params.strategy.strategyType - The type of strategy to be applied.
421
+ * @param {web3.PublicKey} params.user - The public key of the user executing the transaction.
422
+ * @param {number} [params.slippage] - Optional slippage tolerance for the transaction.
423
+ *
424
+ * @returns {Promise<web3.TransactionInstruction[]>} - A promise that resolves to an array of transaction instructions.
425
+ *
426
+ * @throws {Error} - Throws an error if input token(s) do not exist on the blockchain.
427
+ */
428
+ initializePositionAndAddLiquidityByStrategyPda(connection, userWallet, payer, params, meteoraToHawksight) {
429
+ return __awaiter(this, void 0, void 0, function* () {
430
+ if (!!!params.skipInputTokenCheck) {
431
+ // Throw error if input token(s) do not exist on blockchain
432
+ yield (0, functions_1.inputTokenExists)(anchor_1.Anchor.instance().connection, userWallet, [
433
+ this.dlmm.tokenX.publicKey,
434
+ this.dlmm.tokenY.publicKey,
435
+ ]);
436
+ }
437
+ const [strategyType, singleSidedX] = (0, functions_1.getMeteoraStrategyType)(params.strategy.strategyType, params.totalXAmount, params.totalYAmount);
438
+ // Generate InitializePosition and AddLiquidityByStrategy instruction from Meteora API
439
+ const txn = yield this.dlmm.initializePositionAndAddLiquidityByStrategy({
440
+ positionPubKey: params.positionPubKey,
441
+ totalXAmount: params.totalXAmount,
442
+ totalYAmount: params.totalYAmount,
443
+ strategy: {
444
+ maxBinId: params.strategy.maxBinId,
445
+ minBinId: params.strategy.minBinId,
446
+ strategyType,
447
+ singleSidedX,
448
+ },
449
+ user: params.user,
450
+ });
451
+ // Filter out non-meteora instructions
452
+ const ixs = (0, functions_1.getIxs)(txn).filter((ix) => ix.programId.equals(addresses_1.METEORA_DLMM_PROGRAM));
453
+ // Find mint from meteora instructions
454
+ const mints = (0, functions_1.getMintsFromInstruction)({
455
+ instructions: ixs,
456
+ find: {
457
+ AddLiquidityByStrategy: {
458
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
459
+ mintIndices: [7, 8],
460
+ },
461
+ "add_liquidity_by_strategy2": {
462
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
463
+ mintIndices: [7, 8],
464
+ manualSnakeCase: true,
465
+ },
466
+ AddLiquidityByStrategyOneSide: {
467
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
468
+ mintIndices: [5],
469
+ },
470
+ },
471
+ });
472
+ // Get token program map for mints (just for mint caching)
473
+ yield (0, functions_1.getTokenProgramMapForMints)(connection, mints);
474
+ return new InitializePositionAndAddLiquidityByStrategyPdaBuilder(
475
+ // Step 1: Initialize position and add liquidity by strategy
476
+ yield meteoraToHawksight({
477
+ ixs: ixs,
478
+ userPda: params.user,
479
+ authority: userWallet,
480
+ opt: {
481
+ pdaTokenType: params.pdaTokenType,
482
+ },
483
+ }));
484
+ });
485
+ }
486
+ /**
487
+ * Adds liquidity to an existing position according to a specified strategy.
488
+ *
489
+ * This method involves multiple steps including checking for token existence, handling wrapped SOL (wSOL), depositing tokens,
490
+ * adding liquidity, and handling dust withdrawals. It ensures that all necessary preparations and operations are performed
491
+ * to add liquidity based on the provided strategy.
492
+ *
493
+ * @param {web3.PublicKey} userWallet - The public key of the user's wallet executing the transaction.
494
+ * @param {web3.PublicKey} payer - The public key of the transaction payer.
495
+ * @param {Object} params - The parameters for adding liquidity to the position.
496
+ * @param {web3.PublicKey} params.positionPubKey - The public key of the position to add liquidity to.
497
+ * @param {BN} params.totalXAmount - The total amount of X tokens to be used for liquidity.
498
+ * @param {BN} params.totalYAmount - The total amount of Y tokens to be used for liquidity.
499
+ * @param {Object} params.strategy - The strategy details for adding liquidity.
500
+ * @param {number} params.strategy.maxBinId - The maximum bin ID for the strategy.
501
+ * @param {number} params.strategy.minBinId - The minimum bin ID for the strategy.
502
+ * @param {StrategyType} params.strategy.strategyType - The type of strategy to be applied.
503
+ * @param {web3.PublicKey} params.user - The public key of the user executing the transaction.
504
+ *
505
+ * @returns {Promise<web3.TransactionInstruction[]>} - A promise that resolves to an array of transaction instructions.
506
+ *
507
+ * @throws {Error} - Throws an error if input token(s) do not exist on the blockchain.
508
+ */
509
+ addLiquidityByStrategy(connection, userWallet, payer, params, meteoraToHawksight) {
510
+ return __awaiter(this, void 0, void 0, function* () {
511
+ if (!!!params.skipInputTokenCheck) {
512
+ // Throw error if input token(s) do not exist on blockchain
513
+ yield (0, functions_1.inputTokenExists)(anchor_1.Anchor.instance().connection, userWallet, [
514
+ this.dlmm.tokenX.publicKey,
515
+ this.dlmm.tokenY.publicKey,
516
+ ]);
517
+ }
518
+ const [strategyType, singleSidedX] = (0, functions_1.getMeteoraStrategyType)(params.strategy.strategyType, params.totalXAmount, params.totalYAmount);
519
+ // AddLiquidityByStrategy instruction from Meteora API
520
+ const txn = yield this.dlmm.addLiquidityByStrategy({
521
+ positionPubKey: params.positionPubKey,
522
+ totalXAmount: params.totalXAmount,
523
+ totalYAmount: params.totalYAmount,
524
+ strategy: {
525
+ maxBinId: params.strategy.maxBinId,
526
+ minBinId: params.strategy.minBinId,
527
+ strategyType,
528
+ singleSidedX,
529
+ },
530
+ user: params.user,
531
+ slippage: params.slippage,
532
+ });
533
+ // Filter out non-meteora instructions
534
+ const ixs = (0, functions_1.getIxs)(txn).filter((ix) => ix.programId.equals(addresses_1.METEORA_DLMM_PROGRAM));
535
+ // Find mint from meteora instructions
536
+ const mints = (0, functions_1.getMintsFromInstruction)({
537
+ instructions: ixs,
538
+ find: {
539
+ AddLiquidityByStrategy: {
540
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
541
+ mintIndices: [7, 8],
542
+ },
543
+ "add_liquidity_by_strategy2": {
544
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
545
+ mintIndices: [7, 8],
546
+ manualSnakeCase: true,
547
+ },
548
+ AddLiquidityByStrategyOneSide: {
549
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
550
+ mintIndices: [5],
551
+ },
552
+ },
553
+ });
554
+ // Populate mint cache for automation CPI
555
+ // Include both mints from instructions and DLMM pool mints
556
+ const allMints = [
557
+ ...mints,
558
+ this.dlmm.tokenX.publicKey,
559
+ this.dlmm.tokenY.publicKey
560
+ ];
561
+ if (allMints.length > 0) {
562
+ try {
563
+ yield (0, functions_1.getTokenProgramMapForMints)(connection, allMints);
564
+ }
565
+ catch (error) {
566
+ console.error(`Error populating cache:`, error);
567
+ throw error;
568
+ }
569
+ }
570
+ return new AddLiquidityByStrategyBuilder(
571
+ // Step 1: Init wSOL token account for user wallet (if X or Y token is wSOL)
572
+ // H-2106: also CreateIdempotent the non-wSOL source ATAs (see functions.ts).
573
+ [
574
+ ...(0, functions_1.wrapSolIfMintIsWsol)(userWallet, payer, [
575
+ { mint: this.dlmm.tokenX.publicKey, amount: params.totalXAmount },
576
+ { mint: this.dlmm.tokenY.publicKey, amount: params.totalYAmount },
577
+ ]),
578
+ ...yield (0, functions_1.createSourceAtasIdempotent)(connection, userWallet, payer, [
579
+ { mint: this.dlmm.tokenX.publicKey, amount: params.totalXAmount },
580
+ { mint: this.dlmm.tokenY.publicKey, amount: params.totalYAmount },
581
+ ]),
582
+ ],
583
+ // Step 2: Deposit X and Y token to UserPDA
584
+ yield this.ix.iyfMain.depositMultipleTokenWithToken2022({
585
+ connection,
586
+ payer: userWallet,
587
+ deposit: [
588
+ { mint: this.dlmm.tokenX.publicKey, amount: params.totalXAmount },
589
+ { mint: this.dlmm.tokenY.publicKey, amount: params.totalYAmount },
590
+ ],
591
+ pdaTokenType: params.pdaTokenType,
592
+ }),
593
+ // Step 3: Add liquidity by strategy
594
+ yield meteoraToHawksight({
595
+ ixs,
596
+ userPda: params.user,
597
+ authority: userWallet,
598
+ opt: {
599
+ pdaTokenType: params.pdaTokenType,
600
+ },
601
+ }),
602
+ // Step 4: Withdraw dust to user wallet
603
+ yield this.ix.iyfMain.withdrawMultipleTokenWithToken2022({
604
+ connection,
605
+ payer: userWallet,
606
+ withdraw: mints.map((mint) => {
607
+ return { mint, amount: new bn_js_1.default(0) };
608
+ }),
609
+ pdaTokenType: params.pdaTokenType,
610
+ hasAmount: false,
611
+ }),
612
+ // Step 5: Close wSOL account (if there's any)
613
+ (0, functions_1.unwrapSolIfMintIsWsol)(userWallet, mints));
614
+ });
615
+ }
616
+ /**
617
+ * Removes liquidity from an existing position.
618
+ *
619
+ * This method communicates with the DLMM (Dynamic Liquidity Market Maker) to remove liquidity
620
+ * from a specified trading position. It filters the transaction instructions to include only those
621
+ * relevant to the Meteora DLMM program.
622
+ *
623
+ * @param {web3.PublicKey} userWallet - The public key of the user's wallet executing the transaction.
624
+ * @param {web3.PublicKey} payer - The public key of the transaction payer.
625
+ * @param {Object} params - The parameters for removing liquidity from the position.
626
+ * @param {web3.PublicKey} params.user - The public key of the user executing the transaction.
627
+ * @param {web3.PublicKey} params.position - The public key of the position from which liquidity is being removed.
628
+ * @param {number[]} params.binIds - An array of bin IDs indicating which bins to remove liquidity from.
629
+ * @param {BN} params.bps - The basis points (in BN) indicating the proportion of liquidity to remove.
630
+ * @param {boolean} [params.shouldClaimAndClose] - Optional flag to indicate whether the position should be claimed and closed after removing liquidity.
631
+ *
632
+ * @returns {Promise<web3.TransactionInstruction[]>} - A promise that resolves to an array of transaction instructions relevant to the Meteora DLMM program.
633
+ */
634
+ removeLiquidity(connection, userWallet, payer, params, meteoraToHawksight) {
635
+ return __awaiter(this, void 0, void 0, function* () {
636
+ var _a;
637
+ // Claim fees and/or rewards, remove liquidity, and possibly close position from Meteora API (if set)
638
+ const txn = yield this.dlmm.removeLiquidity(params);
639
+ const lbPair = this.dlmm.pubkey;
640
+ // Filter out non-meteora instructions
641
+ const ixs = (0, functions_1.getIxs)(txn).filter((ix) => ix.programId.equals(addresses_1.METEORA_DLMM_PROGRAM));
642
+ // BUG FIX: Meteora SDK's removeLiquidity doesn't include claimReward instructions for LM farms.
643
+ // We need to manually generate claimReward instructions for each active reward farm
644
+ // and insert them before closePosition to prevent "NonEmptyPosition" error (6030).
645
+ // These are generated as IYF-wrapped instructions and added after transformation.
646
+ const claimRewardIxs = [];
647
+ const rewardMints = [];
648
+ if (params.shouldClaimAndClose) {
649
+ let rewardIndex = -1;
650
+ for (const reward of this.dlmm.rewards) {
651
+ rewardIndex++;
652
+ if (reward && !reward.mint.address.equals(web3.SystemProgram.programId)) {
653
+ const claimRewardIx = params.rewardClaimMode === 'automation'
654
+ ? yield this.ix.meteoraDlmm.claimReward2Automation(connection, {
655
+ userWallet,
656
+ lbPair,
657
+ position: params.position,
658
+ rewardIndex,
659
+ rewardMint: reward.mint.address,
660
+ rewardVault: reward.reserve,
661
+ tokenProgram: reward.owner,
662
+ lowerBinId: params.fromBinId,
663
+ upperBinId: params.toBinId,
664
+ pdaTokenType: (_a = params.pdaTokenType) !== null && _a !== void 0 ? _a : types_1.TokenType.ATA,
665
+ remainingAccountsInfo: yield (0, functions_1.fetchRemainingAccountsInfoForReward)(connection, reward.mint.address, reward.owner),
666
+ })
667
+ : yield this.ix.meteoraDlmm.claimReward2(connection, {
668
+ userWallet,
669
+ lbPair,
670
+ position: params.position,
671
+ rewardIndex,
672
+ rewardMint: reward.mint.address,
673
+ rewardVault: reward.reserve,
674
+ tokenProgram: reward.owner,
675
+ lowerBinId: params.fromBinId,
676
+ upperBinId: params.toBinId,
677
+ });
678
+ claimRewardIxs.push(claimRewardIx);
679
+ rewardMints.push(reward.mint.address);
680
+ }
681
+ }
682
+ }
683
+ // Find mint from meteora instructions
684
+ const mintsFromIxs = (0, functions_1.getMintsFromInstruction)({
685
+ instructions: ixs,
686
+ find: {
687
+ RemoveLiquidity: {
688
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
689
+ mintIndices: [7, 8],
690
+ },
691
+ "remove_liquidity2": {
692
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
693
+ mintIndices: [7, 8],
694
+ manualSnakeCase: true,
695
+ },
696
+ RemoveLiquidityByRange: {
697
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
698
+ mintIndices: [7, 8],
699
+ },
700
+ "remove_liquidity_by_range2": {
701
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
702
+ mintIndices: [7, 8],
703
+ manualSnakeCase: true,
704
+ },
705
+ ClaimFee: {
706
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
707
+ mintIndices: [9, 10],
708
+ },
709
+ "claim_fee2": {
710
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
711
+ mintIndices: [7, 8],
712
+ manualSnakeCase: true,
713
+ },
714
+ ClaimReward: {
715
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
716
+ mintIndices: [6],
717
+ },
718
+ "claim_reward2": {
719
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
720
+ mintIndices: [4],
721
+ manualSnakeCase: true,
722
+ },
723
+ },
724
+ });
725
+ // Combine mints from instructions with manually tracked reward mints
726
+ // (claimReward2 instructions generated above are wrapped in IYF Extension, so we track reward mints separately)
727
+ const mints = [...mintsFromIxs, ...rewardMints];
728
+ // TODO: take out redundant call
729
+ // Get token program map for mints (just for mint caching)
730
+ yield (0, functions_1.getTokenProgramMapForMints)(connection, mints);
731
+ // Get token mints (for caching) - manual implementation
732
+ const tokenProgramMap = yield getTokenProgramMapForMintsManual(connection, mints);
733
+ const ataIxs = (0, functions_1.createAtaIdempotentIxs)({
734
+ accounts: mints.map((mint) => {
735
+ return { owner: params.user, payer, mint, programId: tokenProgramMap[mint.toString()] };
736
+ }),
737
+ });
738
+ let mainIx = yield meteoraToHawksight({
739
+ ixs,
740
+ userPda: params.user,
741
+ authority: userWallet,
742
+ opt: {
743
+ pdaTokenType: params.pdaTokenType,
744
+ params: {
745
+ fuelAccount: params.fuelAccount,
746
+ lbPair: lbPair,
747
+ },
748
+ },
749
+ });
750
+ // Insert claimReward instructions before closePosition in mainIx
751
+ if (claimRewardIxs.length > 0) {
752
+ // Find closePosition index in transformed instructions
753
+ // ClosePosition instructions have sighash matching "MeteoraDlmmClosePosition2" or similar
754
+ const closePositionIndex = mainIx.findIndex((ix) => {
755
+ const dataWithoutIyfExtensionExecute = ix.data.subarray(12);
756
+ return (0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, 'MeteoraDlmmClosePosition2') ||
757
+ (0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, 'MeteoraDlmmClosePosition2Automation');
758
+ });
759
+ if (closePositionIndex !== -1) {
760
+ // Insert claimReward instructions before closePosition
761
+ mainIx = [
762
+ ...mainIx.slice(0, closePositionIndex),
763
+ ...claimRewardIxs,
764
+ ...mainIx.slice(closePositionIndex),
765
+ ];
766
+ }
767
+ else {
768
+ // No closePosition found, append claimReward instructions
769
+ mainIx = [...mainIx, ...claimRewardIxs];
770
+ }
771
+ }
772
+ const withdrawIx = yield this.ix.iyfMain.withdrawMultipleTokenWithToken2022({
773
+ connection,
774
+ payer: userWallet,
775
+ withdraw: mints.map((mint) => {
776
+ return { mint, amount: new bn_js_1.default(0) };
777
+ }),
778
+ pdaTokenType: params.pdaTokenType,
779
+ hasAmount: false,
780
+ });
781
+ const unwrapIxs = (0, functions_1.unwrapSolIfMintIsWsol)(userWallet, mints);
782
+ return new RemoveLiquidityBuilder(
783
+ // Step 1: Init ATA prior to withdrawal
784
+ ataIxs,
785
+ // Step 2: Claim fees and/or rewards, remove liquidity, and possibly close position (if set)
786
+ mainIx,
787
+ // Step 3: Withdraw tokens to user wallet
788
+ withdrawIx,
789
+ // Step 4: Close wSOL account (if there's any)
790
+ unwrapIxs);
791
+ });
792
+ }
793
+ /**
794
+ * Removes liquidity from an existing position to the user pda.
795
+ *
796
+ * This method communicates with the DLMM (Dynamic Liquidity Market Maker) to remove liquidity
797
+ * from a specified trading position. It filters the transaction instructions to include only those
798
+ * relevant to the Meteora DLMM program.
799
+ *
800
+ * @param {web3.PublicKey} userWallet - The public key of the user's wallet executing the transaction.
801
+ * @param {web3.PublicKey} payer - The public key of the transaction payer.
802
+ * @param {Object} params - The parameters for removing liquidity from the position.
803
+ * @param {web3.PublicKey} params.user - The public key of the user executing the transaction.
804
+ * @param {web3.PublicKey} params.position - The public key of the position from which liquidity is being removed.
805
+ * @param {number[]} params.binIds - An array of bin IDs indicating which bins to remove liquidity from.
806
+ * @param {BN} params.bps - The basis points (in BN) indicating the proportion of liquidity to remove.
807
+ * @param {boolean} [params.shouldClaimAndClose] - Optional flag to indicate whether the position should be claimed and closed after removing liquidity.
808
+ *
809
+ * @returns {Promise<web3.TransactionInstruction[]>} - A promise that resolves to an array of transaction instructions relevant to the Meteora DLMM program.
810
+ */
811
+ removeLiquidityPda(connection, userWallet, payer, params, meteoraToHawksight) {
812
+ return __awaiter(this, void 0, void 0, function* () {
813
+ // Claim fees and/or rewards, remove liquidity, and possibly close position from Meteora API (if set)
814
+ const txn = yield this.dlmm.removeLiquidity(params);
815
+ // Filter out non-meteora instructions
816
+ const ixs = (0, functions_1.getIxs)(txn).filter((ix) => ix.programId.equals(addresses_1.METEORA_DLMM_PROGRAM));
817
+ // Find mint from meteora instructions
818
+ const mints = (0, functions_1.getMintsFromInstruction)({
819
+ instructions: ixs,
820
+ find: {
821
+ RemoveLiquidity: {
822
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
823
+ mintIndices: [7, 8],
824
+ },
825
+ RemoveLiquidityByRange: {
826
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
827
+ mintIndices: [7, 8],
828
+ },
829
+ ClaimFee: {
830
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
831
+ mintIndices: [9, 10],
832
+ },
833
+ ClaimReward: {
834
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
835
+ mintIndices: [6],
836
+ },
837
+ },
838
+ });
839
+ const allMints = [
840
+ ...mints,
841
+ this.dlmm.tokenX.publicKey,
842
+ this.dlmm.tokenY.publicKey
843
+ ];
844
+ if (allMints.length > 0) {
845
+ try {
846
+ yield (0, functions_1.getTokenProgramMapForMints)(connection, allMints);
847
+ }
848
+ catch (error) {
849
+ console.error(`Error populating cache:`, error);
850
+ throw error;
851
+ }
852
+ }
853
+ return new RemoveLiquidityPdaBuilder(
854
+ // Step 1: Init ATA prior to withdrawal
855
+ // createAtaIdempotentIxs({
856
+ // accounts: mints.map((mint) => {
857
+ // return { owner: params.user, payer, mint };
858
+ // }),
859
+ // }),
860
+ // Step 2: Claim fees and/or rewards, remove liquidity, and possibly close position (if set)
861
+ yield meteoraToHawksight({
862
+ ixs,
863
+ userPda: params.user,
864
+ authority: userWallet,
865
+ opt: {
866
+ pdaTokenType: params.pdaTokenType,
867
+ },
868
+ }));
869
+ });
870
+ }
871
+ /**
872
+ * Claims all rewards for a specified position.
873
+ *
874
+ * This method communicates with the DLMM (Dynamic Liquidity Market Maker) to claim all rewards
875
+ * for a given position. It filters the transaction instructions to include only those relevant
876
+ * to the Meteora DLMM program. The method returns a `ClaimAllRewardsByPositionBuilder` object
877
+ * which provides a structured way to build the necessary transaction instructions for the reward
878
+ * claiming process.
879
+ *
880
+ * @param {web3.PublicKey} userWallet - The public key of the user's wallet executing the transaction.
881
+ * @param {web3.PublicKey} payer - The public key of the transaction payer.
882
+ * @param {Object} params - The parameters for claiming rewards.
883
+ * @param {web3.PublicKey} params.owner - The public key of the owner of the position.
884
+ * @param {LbPosition} params.position - The position object representing the liquidity position.
885
+ * @param {Function} meteoraToHawksight - A function to convert Meteora instructions to Hawksight instructions.
886
+ *
887
+ * @returns {Promise<ClaimAllRewardsByPositionBuilder>} - A promise that resolves to a `ClaimAllRewardsByPositionBuilder` object.
888
+ */
889
+ claimAllRewardsByPosition(connection, userWallet, payer, params, meteoraToHawksight) {
890
+ return __awaiter(this, void 0, void 0, function* () {
891
+ // Claim all fees and rewards instruction from Meteora API
892
+ const txn = yield this.dlmm.claimAllRewardsByPosition(params);
893
+ // Filter out non-meteora instructions
894
+ const ixs = (0, functions_1.getIxs)(txn).filter((ix) => ix.programId.equals(addresses_1.METEORA_DLMM_PROGRAM));
895
+ // Find mint from meteora instructions
896
+ const mints = (0, functions_1.getMintsFromInstruction)({
897
+ instructions: ixs,
898
+ find: {
899
+ ClaimFee: {
900
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
901
+ mintIndices: [9, 10],
902
+ },
903
+ "claim_fee2": {
904
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
905
+ mintIndices: [7, 8],
906
+ manualSnakeCase: true,
907
+ },
908
+ "claim_reward2": {
909
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
910
+ mintIndices: [4],
911
+ manualSnakeCase: true,
912
+ },
913
+ ClaimReward: {
914
+ programId: addresses_1.METEORA_DLMM_PROGRAM.toBase58(),
915
+ mintIndices: [6],
916
+ },
917
+ },
918
+ });
919
+ return new ClaimAllRewardsByPositionBuilder(
920
+ // Step 1: Init ATA prior to withdrawal
921
+ (0, functions_1.createAtaIdempotentIxs)({
922
+ accounts: mints.map((mint) => {
923
+ return { owner: params.owner, payer, mint };
924
+ }),
925
+ }),
926
+ // Step 2: Claim fees and/or rewards, remove liquidity, and possibly close position (if set)
927
+ yield meteoraToHawksight({
928
+ ixs,
929
+ userPda: params.owner,
930
+ authority: userWallet,
931
+ }),
932
+ // Step 3: Withdraw tokens to user wallet
933
+ yield this.ix.iyfMain.withdrawMultipleTokenWithToken2022({
934
+ connection,
935
+ payer: userWallet,
936
+ withdraw: mints.map((mint) => {
937
+ return { mint, amount: new bn_js_1.default(0) };
938
+ }),
939
+ pdaTokenType: types_1.TokenType.ATA,
940
+ hasAmount: false,
941
+ }),
942
+ // Step 4: Close wSOL account (if there's any)
943
+ (0, functions_1.unwrapSolIfMintIsWsol)(userWallet, mints));
944
+ });
945
+ }
946
+ /**
947
+ * Closes a specified liquidity position.
948
+ *
949
+ * This method communicates with the DLMM (Dynamic Liquidity Market Maker) to close a given liquidity
950
+ * position. It filters the transaction instructions to include only those relevant to the Meteora DLMM program.
951
+ *
952
+ * @param {Object} params - The parameters for closing the position.
953
+ * @param {web3.PublicKey} params.owner - The public key of the owner of the position.
954
+ * @param {LbPosition} params.position - The position object representing the liquidity position.
955
+ *
956
+ * @returns {Promise<web3.TransactionInstruction[]>} - A promise that resolves to an array of transaction instructions relevant to the Meteora DLMM program.
957
+ */
958
+ closePosition(userWallet, params, meteoraToHawksight) {
959
+ return __awaiter(this, void 0, void 0, function* () {
960
+ // Close position from Meteora API
961
+ const txn = yield this.dlmm.closePosition(params);
962
+ // Filter out non-meteora instructions
963
+ const ixs = (0, functions_1.getIxs)(txn).filter((ix) => ix.programId.equals(addresses_1.METEORA_DLMM_PROGRAM));
964
+ return [
965
+ // Step 1: Close meteora position
966
+ ...(yield meteoraToHawksight({
967
+ ixs,
968
+ userPda: params.owner,
969
+ authority: userWallet,
970
+ })),
971
+ ];
972
+ return ixs;
973
+ });
974
+ }
975
+ }
976
+ exports.MeteoraDLMM = MeteoraDLMM;
977
+ /**
978
+ * Meteora functions / transaction generators that we re-written for performance improvement purposes
979
+ */
980
+ class MeteoraFunctions {
981
+ constructor(ix) {
982
+ this.ix = ix;
983
+ /**
984
+ * Position cache (v1)
985
+ */
986
+ this.positions_v1 = {};
987
+ /**
988
+ * Position cache (v2)
989
+ */
990
+ this.positions_v2 = {};
991
+ /**
992
+ * Pool cache
993
+ */
994
+ this.pools = {};
995
+ }
996
+ /**
997
+ * Claims all rewards for a specified position.
998
+ *
999
+ * This method communicates with the DLMM (Dynamic Liquidity Market Maker) to claim all rewards
1000
+ * for a given position. It filters the transaction instructions to include only those relevant
1001
+ * to the Meteora DLMM program. The method returns a `ClaimAllRewardsByPositionBuilder` object
1002
+ * which provides a structured way to build the necessary transaction instructions for the reward
1003
+ * claiming process.
1004
+ *
1005
+ * @param {web3.PublicKey} userWallet - The public key of the user's wallet executing the transaction.
1006
+ * @param {web3.PublicKey} payer - The public key of the transaction payer.
1007
+ * @param {Object} params - The parameters for claiming rewards.
1008
+ * @param {web3.PublicKey} params.owner - The public key of the owner of the position.
1009
+ * @param {LbPosition} params.position - The position object representing the liquidity position.
1010
+ * @param {Function} meteoraToHawksight - A function to convert Meteora instructions to Hawksight instructions.
1011
+ *
1012
+ * @returns {Promise<ClaimAllRewardsByPositionBuilder>} - A promise that resolves to a `ClaimAllRewardsByPositionBuilder` object.
1013
+ */
1014
+ claimAllRewardsByPosition(connection, userWallet, payer, params, meteoraToHawksight) {
1015
+ return __awaiter(this, void 0, void 0, function* () {
1016
+ // Create DLMM instance
1017
+ const dlmm = yield dlmm_1.default.create(connection, params.lbPair);
1018
+ // Generate claim fee and reward instruction (fast generator)
1019
+ let [ixs, position] = yield Promise.all([
1020
+ this.claimFee2AndReward2Ixs(connection, params.lbPair, params.position, params.owner, dlmm.tokenX.owner, dlmm.tokenY.owner),
1021
+ dlmm.getPosition(params.position),
1022
+ ]);
1023
+ // Get tokenX and tokenY mints
1024
+ const mints = [
1025
+ dlmm.tokenX.mint.address,
1026
+ dlmm.tokenY.mint.address,
1027
+ ];
1028
+ // Get reward mints
1029
+ dlmm.rewards.forEach((reward) => {
1030
+ if (reward) {
1031
+ mints.push(reward.mint.address);
1032
+ }
1033
+ });
1034
+ // Get token program map for mints
1035
+ const tokenProgramMap = yield (0, functions_1.getTokenProgramMapForMints)(connection, mints);
1036
+ // Check if any of the mints has token2022 program id
1037
+ const hasToken2022 = mints.some((mint) => {
1038
+ return tokenProgramMap[mint.toString()].equals(addresses_1.TOKEN_2022_PROGRAM_ID);
1039
+ });
1040
+ if (hasToken2022) {
1041
+ const userPda = (0, functions_1.generateUserPda)(userWallet);
1042
+ const txn = yield dlmm.claimAllRewards({
1043
+ owner: userPda,
1044
+ positions: [
1045
+ position,
1046
+ ]
1047
+ });
1048
+ const _ixs = [];
1049
+ for (const tx of txn) {
1050
+ _ixs.push(...tx.instructions);
1051
+ }
1052
+ const claimIxs = [];
1053
+ for (const ix of _ixs) {
1054
+ const isMeteoraInstruction = ix.programId.equals(addresses_1.METEORA_DLMM_PROGRAM);
1055
+ const isClaimFee2Ix = (0, functions_1.sighashMatch)(ix.data, (0, functions_1.sighash)('claim_fee2', undefined, true), undefined, undefined, true);
1056
+ const isClaimReward2Ix = (0, functions_1.sighashMatch)(ix.data, (0, functions_1.sighash)('claim_reward2', undefined, true), undefined, undefined, true);
1057
+ if (isMeteoraInstruction && (isClaimFee2Ix || isClaimReward2Ix)) {
1058
+ claimIxs.push(ix);
1059
+ }
1060
+ }
1061
+ ixs = claimIxs;
1062
+ }
1063
+ return new ClaimAllRewardsByPositionBuilder(
1064
+ // Step 1: Init ATA prior to withdrawal
1065
+ params.pdaTokenType === types_1.TokenType.STA ? yield this.ix.iyfMain.initializeStorageTokenAccounts(connection, { userWallet, mints }) : (0, functions_1.createAtaIdempotentIxs)({
1066
+ accounts: mints.map((mint) => {
1067
+ return { owner: params.owner, payer, mint, programId: tokenProgramMap[mint.toString()] };
1068
+ }),
1069
+ }),
1070
+ // Step 2: Claim fees and/or rewards, remove liquidity, and possibly close position (if set)
1071
+ yield meteoraToHawksight({
1072
+ ixs,
1073
+ userPda: params.owner,
1074
+ authority: userWallet,
1075
+ opt: {
1076
+ pdaTokenType: params.pdaTokenType === types_1.TokenType.STA ? types_1.TokenType.STA : types_1.TokenType.ATA,
1077
+ },
1078
+ }),
1079
+ // Step 3: Withdraw tokens to user wallet
1080
+ yield this.ix.iyfMain.withdrawMultipleTokenWithToken2022({
1081
+ connection,
1082
+ payer: userWallet,
1083
+ withdraw: mints.map((mint) => {
1084
+ return { mint, amount: new bn_js_1.default(0) };
1085
+ }),
1086
+ pdaTokenType: params.pdaTokenType === types_1.TokenType.STA ? types_1.TokenType.STA : types_1.TokenType.ATA,
1087
+ hasAmount: false,
1088
+ }),
1089
+ // Step 4: Close wSOL account (if there's any)
1090
+ (0, functions_1.unwrapSolIfMintIsWsol)(userWallet, mints));
1091
+ });
1092
+ }
1093
+ constants(program) {
1094
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1095
+ const CONSTANTS = Object.entries(program.idl.constants);
1096
+ const MAX_BIN_ARRAY_SIZE = new bn_js_1.default((_b = ((_a = CONSTANTS.find(([k, v]) => v.name == "MAX_BIN_PER_ARRAY")) === null || _a === void 0 ? void 0 : _a[1]).value) !== null && _b !== void 0 ? _b : 0);
1097
+ const MAX_BIN_PER_POSITION = new bn_js_1.default((_d = ((_c = CONSTANTS.find(([k, v]) => v.name == "MAX_BIN_PER_POSITION")) === null || _c === void 0 ? void 0 : _c[1]).value) !== null && _d !== void 0 ? _d : 0);
1098
+ const BIN_ARRAY_BITMAP_SIZE = new bn_js_1.default((_f = ((_e = CONSTANTS.find(([k, v]) => v.name == "BIN_ARRAY_BITMAP_SIZE")) === null || _e === void 0 ? void 0 : _e[1]).value) !== null && _f !== void 0 ? _f : 0);
1099
+ const EXTENSION_BINARRAY_BITMAP_SIZE = new bn_js_1.default((_h = ((_g = CONSTANTS.find(([k, v]) => v.name == "EXTENSION_BINARRAY_BITMAP_SIZE")) === null || _g === void 0 ? void 0 : _g[1])
1100
+ .value) !== null && _h !== void 0 ? _h : 0);
1101
+ return {
1102
+ MAX_BIN_ARRAY_SIZE,
1103
+ MAX_BIN_PER_POSITION,
1104
+ BIN_ARRAY_BITMAP_SIZE,
1105
+ EXTENSION_BINARRAY_BITMAP_SIZE,
1106
+ };
1107
+ }
1108
+ static findMeteoraTickArrayIndices(minBinId, maxBinId) {
1109
+ const MAX_BIN_ARRAY_SIZE = new bn_js_1.default(anchor_1.Anchor.instance().meteoraProgram.idl.constants[1].value);
1110
+ const binIdStrings = {};
1111
+ for (let binId = minBinId; binId <= maxBinId; binId++) {
1112
+ binIdStrings[MeteoraFunctions.binIdToBinArrayIndex(MAX_BIN_ARRAY_SIZE, new bn_js_1.default(binId)).toString()] = 1;
1113
+ }
1114
+ const binIds = Object.keys(binIdStrings).map(v => new bn_js_1.default(v)).sort((a, b) => a.toNumber() - b.toNumber());
1115
+ return binIds;
1116
+ }
1117
+ static findMeteoraTickArrays(lbPair, minBinId, maxBinId) {
1118
+ const binIds = MeteoraFunctions.findMeteoraTickArrayIndices(minBinId, maxBinId);
1119
+ const tickArrays = binIds.map(binId => MeteoraFunctions.deriveBinArray(lbPair, binId));
1120
+ const tickArrayUpperIndex = binIds[binIds.length - 1].add(new bn_js_1.default(1));
1121
+ const tickArrayUpper = MeteoraFunctions.deriveBinArray(lbPair, tickArrayUpperIndex);
1122
+ tickArrays.push(tickArrayUpper);
1123
+ return tickArrays;
1124
+ }
1125
+ deriveReserve(token, lbPair) {
1126
+ const [reserve] = web3.PublicKey.findProgramAddressSync([
1127
+ lbPair.toBuffer(),
1128
+ token.toBuffer(),
1129
+ ], addresses_1.METEORA_DLMM_PROGRAM);
1130
+ return reserve;
1131
+ }
1132
+ static deriveBinArray(lbPair, index) {
1133
+ let binArrayBytes;
1134
+ if (index.isNeg()) {
1135
+ binArrayBytes = new Uint8Array(index.toTwos(64).toArrayLike(Buffer, "le", 8));
1136
+ }
1137
+ else {
1138
+ binArrayBytes = new Uint8Array(index.toArrayLike(Buffer, "le", 8));
1139
+ }
1140
+ const [binArray] = web3.PublicKey.findProgramAddressSync([Buffer.from("bin_array"), lbPair.toBytes(), binArrayBytes], addresses_1.METEORA_DLMM_PROGRAM);
1141
+ return binArray;
1142
+ }
1143
+ static binIdToBinArrayIndex(MAX_BIN_ARRAY_SIZE, binId) {
1144
+ const { div: idx, mod } = binId.divmod(MAX_BIN_ARRAY_SIZE);
1145
+ return binId.isNeg() && !mod.isZero() ? idx.sub(new bn_js_1.default(1)) : idx;
1146
+ }
1147
+ getPositionAndLbPair(connection, lbPair, position) {
1148
+ return __awaiter(this, void 0, void 0, function* () {
1149
+ const program = yield MeteoraDLMM.program(connection);
1150
+ // const constants = this.constants(program);
1151
+ const constants = {
1152
+ MAX_BIN_ARRAY_SIZE: new bn_js_1.default(70),
1153
+ MAX_BIN_PER_POSITION: new bn_js_1.default(70),
1154
+ BIN_ARRAY_BITMAP_SIZE: new bn_js_1.default(512),
1155
+ EXTENSION_BINARRAY_BITMAP_SIZE: new bn_js_1.default(12),
1156
+ };
1157
+ const [lbPairInfo, positionInfo] = yield connection.getMultipleAccountsInfo([lbPair, position]);
1158
+ const lbPairAccount = program.coder.accounts.decode('lbPair', lbPairInfo.data);
1159
+ const positionAccount = program.coder.accounts.decode('positionV2', positionInfo.data);
1160
+ return {
1161
+ lbPairAccount,
1162
+ positionAccount,
1163
+ constants,
1164
+ };
1165
+ });
1166
+ }
1167
+ /**
1168
+ * Returns all position of user
1169
+ *
1170
+ * @param connection
1171
+ * @param userPda
1172
+ */
1173
+ getAllUserPosition(connection, userPda) {
1174
+ return __awaiter(this, void 0, void 0, function* () {
1175
+ const program = yield MeteoraDLMM.program(connection);
1176
+ // Returns all position owned by user.
1177
+ // What is not sure is whether these positions are closed already.
1178
+ const promiseResult = yield Promise.all([
1179
+ userPda && program.account.position.all([
1180
+ {
1181
+ memcmp: {
1182
+ bytes: bs58_1.default.encode(userPda.toBuffer()),
1183
+ offset: 8 + 32
1184
+ }
1185
+ }
1186
+ ]),
1187
+ userPda && program.account.positionV2.all([
1188
+ {
1189
+ memcmp: {
1190
+ bytes: bs58_1.default.encode(userPda.toBuffer()),
1191
+ offset: 8 + 32
1192
+ }
1193
+ }
1194
+ ])
1195
+ ]);
1196
+ const [_positions, _positionsV2] = promiseResult;
1197
+ const positions = [..._positions, ..._positionsV2];
1198
+ // Remember v1 positions
1199
+ for (const position of _positions) {
1200
+ this.positions_v1[position.publicKey.toString()] = position.account;
1201
+ }
1202
+ // Remember v2 positions
1203
+ for (const position of _positionsV2) {
1204
+ this.positions_v2[position.publicKey.toString()] = position.account;
1205
+ }
1206
+ // Get all pools (lbPair)
1207
+ const temp = positions.map(position => position.account.lbPair);
1208
+ const pools = [];
1209
+ // Trim repeat pool (ensure that pools are unique)
1210
+ const unique = {};
1211
+ for (const pool of temp) {
1212
+ if (unique[pool.toString()] === undefined) {
1213
+ pools.push(pool);
1214
+ unique[pool.toString()] = pool;
1215
+ }
1216
+ }
1217
+ // Download all pools and update cache
1218
+ const lbPairs = yield program.account.lbPair.fetchMultiple(pools);
1219
+ lbPairs.map((lbPair, index) => {
1220
+ const key = pools[index].toString();
1221
+ if (lbPair !== undefined && lbPair !== null) {
1222
+ this.pools[key] = lbPair;
1223
+ }
1224
+ });
1225
+ return positions.map(position => position.publicKey);
1226
+ });
1227
+ }
1228
+ getPositions(dlmm, positions) {
1229
+ return __awaiter(this, void 0, void 0, function* () {
1230
+ const promises = [];
1231
+ for (const position of positions) {
1232
+ promises.push(Promise.all([
1233
+ dlmm.program.account.positionV2.fetch(position),
1234
+ dlmm.getPosition(position),
1235
+ ]));
1236
+ }
1237
+ const results = yield Promise.all(promises);
1238
+ return results;
1239
+ });
1240
+ }
1241
+ /**
1242
+ * Generate instruction that claims all fees and rewards by user
1243
+ *
1244
+ * @param connection
1245
+ * @param lbPair
1246
+ * @param positions
1247
+ * @param userPda
1248
+ * @returns
1249
+ */
1250
+ claimFeeAndRewardIxs2(connection, positions, userWallet, userPda, meteoraToHawksight, lbPair) {
1251
+ return __awaiter(this, void 0, void 0, function* () {
1252
+ // const result = await this.getPositionAndLbPair(connection, lbPair, position);
1253
+ // const result = await this.getPositionAndLbPair(connection, SOME_METEORA_DLMM_POOL, positions[0]);
1254
+ const dlmm = yield dlmm_1.default.create(connection, lbPair !== null && lbPair !== void 0 ? lbPair : addresses_1.SOME_METEORA_DLMM_POOL);
1255
+ // const program = await MeteoraDLMM.program(connection);
1256
+ // const constants = result.constants;
1257
+ // const constants = this.constants(program);
1258
+ // const constants = {
1259
+ // MAX_BIN_ARRAY_SIZE: new BN(70),
1260
+ // MAX_BIN_PER_POSITION: new BN(70),
1261
+ // BIN_ARRAY_BITMAP_SIZE: new BN(512),
1262
+ // EXTENSION_BINARRAY_BITMAP_SIZE: new BN(12),
1263
+ // };
1264
+ // await this.getAllUserPosition(connection, userPda);
1265
+ const ixs = [];
1266
+ const _positions = yield this.getPositions(dlmm, positions);
1267
+ const pairMints = [];
1268
+ const rewardMints = [];
1269
+ const claimFeeIxs = [];
1270
+ const claimRewardIxs = [];
1271
+ for (const position of _positions) {
1272
+ const positionAccount = position[0];
1273
+ const positionData = position[1];
1274
+ let txn = [];
1275
+ const claimFeeIx = yield this.ix.meteoraDlmm.claimFee2(connection, {
1276
+ userWallet,
1277
+ lbPair: positionAccount.lbPair,
1278
+ position: positionData.publicKey,
1279
+ tokenMintX: dlmm.tokenX.mint.address,
1280
+ tokenMintY: dlmm.tokenY.mint.address,
1281
+ tokenProgramX: dlmm.tokenX.owner,
1282
+ tokenProgramY: dlmm.tokenY.owner,
1283
+ lowerBinId: positionData.positionData.lowerBinId,
1284
+ upperBinId: positionData.positionData.upperBinId,
1285
+ });
1286
+ claimFeeIxs.push(claimFeeIx);
1287
+ pairMints.push(dlmm.tokenX.mint.address);
1288
+ pairMints.push(dlmm.tokenY.mint.address);
1289
+ let rewardIndex = -1;
1290
+ for (const reward of dlmm.rewards) {
1291
+ rewardIndex++;
1292
+ if (reward && !reward.mint.address.equals(web3.SystemProgram.programId)) {
1293
+ const claimRewardIx = yield this.ix.meteoraDlmm.claimReward2(connection, {
1294
+ userWallet,
1295
+ lbPair: positionAccount.lbPair,
1296
+ position: positionData.publicKey,
1297
+ rewardIndex,
1298
+ rewardMint: reward.mint.address,
1299
+ rewardVault: reward.reserve,
1300
+ tokenProgram: reward.owner,
1301
+ lowerBinId: positionData.positionData.lowerBinId,
1302
+ upperBinId: positionData.positionData.upperBinId,
1303
+ });
1304
+ claimRewardIxs.push(claimRewardIx);
1305
+ rewardMints.push(reward.mint.address);
1306
+ }
1307
+ }
1308
+ }
1309
+ // Find mint from meteora instructions
1310
+ const mints = (() => {
1311
+ const mints = [...pairMints, ...rewardMints];
1312
+ // Remove duplicates
1313
+ const set = new Set(mints.map(mint => mint.toString()));
1314
+ const unique = Array.from(set).map(mint => new web3.PublicKey(mint));
1315
+ return unique;
1316
+ })();
1317
+ // Get token program map for mints
1318
+ const tokenProgramMap = yield (0, functions_1.getTokenProgramMapForMints)(connection, mints);
1319
+ return new ClaimAllRewardsByPositionBuilder(
1320
+ // Step 1: Init ATA prior to withdrawal
1321
+ (0, functions_1.createAtaIdempotentIxs)({
1322
+ accounts: mints.map((mint) => {
1323
+ return { owner: userPda, payer: userWallet, mint, programId: tokenProgramMap[mint.toString()] };
1324
+ }),
1325
+ }),
1326
+ // Step 2: Claim fees and/or rewards, remove liquidity, and possibly close position (if set)
1327
+ [...claimFeeIxs, ...claimRewardIxs],
1328
+ // Step 3: Withdraw tokens to user wallet
1329
+ yield this.ix.iyfMain.withdrawMultipleTokenWithToken2022({
1330
+ connection,
1331
+ payer: userWallet,
1332
+ withdraw: mints.map((mint) => {
1333
+ return { mint, amount: new bn_js_1.default(0) };
1334
+ }),
1335
+ pdaTokenType: types_1.TokenType.ATA,
1336
+ hasAmount: false,
1337
+ }),
1338
+ // Step 4: Close wSOL account (if there's any)
1339
+ (0, functions_1.unwrapSolIfMintIsWsol)(userWallet, mints));
1340
+ });
1341
+ }
1342
+ claimFee2AndReward2Ixs(connection, lbPair, position, userPda, tokenProgramX, tokenProgramY) {
1343
+ return __awaiter(this, void 0, void 0, function* () {
1344
+ const result = yield this.getPositionAndLbPair(connection, lbPair, position);
1345
+ // Populate cache with reward mints to prevent "Reward mint not found in cache" errors
1346
+ const rewardMints = [];
1347
+ for (let i = 0; i < 2; i++) {
1348
+ const rewardInfo = result.lbPairAccount.rewardInfos[i];
1349
+ if (rewardInfo && !rewardInfo.mint.equals(web3.PublicKey.default)) {
1350
+ rewardMints.push(rewardInfo.mint);
1351
+ }
1352
+ }
1353
+ if (rewardMints.length > 0) {
1354
+ yield (0, functions_1.getTokenProgramMapForMints)(connection, rewardMints);
1355
+ }
1356
+ const claimFeeIx = this.claimFee2Ix(lbPair, position, userPda, tokenProgramX, tokenProgramY, result);
1357
+ const claimRewardIxs = this.claimReward2Ixs(lbPair, position, userPda, result);
1358
+ return [
1359
+ claimFeeIx,
1360
+ ...claimRewardIxs
1361
+ ];
1362
+ });
1363
+ }
1364
+ claimFee2Ix(lbPair, position, userPda, tokenProgramX, tokenProgramY, getPositionAndLbPairResult) {
1365
+ const tokenMintX = getPositionAndLbPairResult.lbPairAccount.tokenXMint;
1366
+ const tokenMintY = getPositionAndLbPairResult.lbPairAccount.tokenYMint;
1367
+ const { lowerBinId, upperBinId } = getPositionAndLbPairResult.positionAccount;
1368
+ const binArrays = this.ix.pda.meteora.deriveBinArrays(lbPair, lowerBinId, upperBinId);
1369
+ const userTokenX = (0, functions_1.generateAta)(userPda, tokenMintX);
1370
+ const userTokenY = (0, functions_1.generateAta)(userPda, tokenMintY);
1371
+ const reserveX = this.deriveReserve(tokenMintX, lbPair);
1372
+ const reserveY = this.deriveReserve(tokenMintY, lbPair);
1373
+ const ix = new web3.TransactionInstruction({
1374
+ programId: addresses_1.METEORA_DLMM_PROGRAM,
1375
+ keys: [
1376
+ { pubkey: lbPair, isSigner: false, isWritable: true },
1377
+ { pubkey: position, isSigner: false, isWritable: true },
1378
+ { pubkey: userPda, isSigner: false, isWritable: false },
1379
+ { pubkey: reserveX, isSigner: false, isWritable: true },
1380
+ { pubkey: reserveY, isSigner: false, isWritable: true },
1381
+ { pubkey: userTokenX, isSigner: false, isWritable: true },
1382
+ { pubkey: userTokenY, isSigner: false, isWritable: true },
1383
+ { pubkey: tokenMintX, isSigner: false, isWritable: false },
1384
+ { pubkey: tokenMintY, isSigner: false, isWritable: false },
1385
+ { pubkey: tokenProgramX, isSigner: false, isWritable: false },
1386
+ { pubkey: tokenProgramY, isSigner: false, isWritable: false },
1387
+ { pubkey: addresses_1.MEMO_PROGRAM, isSigner: false, isWritable: false },
1388
+ { pubkey: addresses_1.METEORA_EVENT_AUTHORITY, isSigner: false, isWritable: false },
1389
+ { pubkey: addresses_1.METEORA_DLMM_PROGRAM, isSigner: false, isWritable: false },
1390
+ ...binArrays.map(binArray => ({ pubkey: binArray, isSigner: false, isWritable: true })),
1391
+ ],
1392
+ data: Buffer.concat([
1393
+ new Uint8Array((0, functions_1.sighash)('claim_fee2', undefined, true)),
1394
+ new Uint8Array(new bn_js_1.default(lowerBinId).toTwos(32).toArrayLike(Buffer, 'le', 4)),
1395
+ new Uint8Array(new bn_js_1.default(upperBinId).toTwos(32).toArrayLike(Buffer, 'le', 4)),
1396
+ new Uint8Array([0x00, 0x00, 0x00, 0x00]),
1397
+ ]),
1398
+ });
1399
+ return ix;
1400
+ }
1401
+ claimReward2Ixs(lbPair, position, userPda, getPositionAndLbPairResult) {
1402
+ const { lowerBinId, upperBinId } = getPositionAndLbPairResult.positionAccount; // serve as minBinId and maxBinId as well
1403
+ const binArrays = this.ix.pda.meteora.deriveBinArrays(lbPair, lowerBinId, upperBinId);
1404
+ const ixs = [];
1405
+ for (let i = 0; i < 2; i++) {
1406
+ const rewardInfo = getPositionAndLbPairResult.lbPairAccount.rewardInfos[i];
1407
+ if (!rewardInfo || rewardInfo.mint.equals(web3.PublicKey.default))
1408
+ continue;
1409
+ const userTokenAccount = (0, functions_1.generateAta)(userPda, rewardInfo.mint);
1410
+ const ix = new web3.TransactionInstruction({
1411
+ programId: addresses_1.METEORA_DLMM_PROGRAM,
1412
+ keys: [
1413
+ { pubkey: lbPair, isSigner: false, isWritable: true },
1414
+ { pubkey: position, isSigner: false, isWritable: true },
1415
+ { pubkey: userPda, isSigner: false, isWritable: false },
1416
+ { pubkey: rewardInfo.vault, isSigner: false, isWritable: true },
1417
+ { pubkey: rewardInfo.mint, isSigner: false, isWritable: true },
1418
+ { pubkey: userTokenAccount, isSigner: false, isWritable: true },
1419
+ { pubkey: addresses_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
1420
+ { pubkey: addresses_1.MEMO_PROGRAM, isSigner: false, isWritable: false },
1421
+ { pubkey: addresses_1.METEORA_EVENT_AUTHORITY, isSigner: false, isWritable: false },
1422
+ { pubkey: addresses_1.METEORA_DLMM_PROGRAM, isSigner: false, isWritable: false },
1423
+ ...binArrays.map(binArray => ({ pubkey: binArray, isSigner: false, isWritable: true })),
1424
+ ],
1425
+ data: Buffer.concat([
1426
+ new Uint8Array((0, functions_1.sighash)('claim_reward2', undefined, true)),
1427
+ new Uint8Array((new bn_js_1.default(i)).toArrayLike(Buffer, 'le', 8)),
1428
+ new Uint8Array(new bn_js_1.default(lowerBinId).toTwos(32).toArrayLike(Buffer, 'le', 4)),
1429
+ new Uint8Array(new bn_js_1.default(upperBinId).toTwos(32).toArrayLike(Buffer, 'le', 4)),
1430
+ new Uint8Array([0x00, 0x00, 0x00, 0x00]),
1431
+ ]),
1432
+ });
1433
+ ixs.push(ix);
1434
+ }
1435
+ (0, Logging_1.Log)(`Reward ixs count: ` + ixs.length);
1436
+ return ixs;
1437
+ }
1438
+ }
1439
+ exports.MeteoraFunctions = MeteoraFunctions;
1440
+ /**
1441
+ * A builder class for constructing transaction instructions to claim all rewards by position.
1442
+ *
1443
+ * This class provides a structured way to build the necessary transaction instructions for claiming
1444
+ * rewards, removing liquidity, and managing wrapped SOL (wSOL) accounts.
1445
+ */
1446
+ class ClaimAllRewardsByPositionBuilder {
1447
+ /**
1448
+ * Constructs an instance of the ClaimAllRewardsByPositionBuilder class.
1449
+ *
1450
+ * @param {web3.TransactionInstruction[]} createAtaIxs - Instructions to create associated token accounts (ATAs) prior to withdrawal.
1451
+ * @param {web3.TransactionInstruction[]} mainIxs - Main instructions for claiming fees and/or rewards.
1452
+ * @param {web3.TransactionInstruction} withdrawMultipleTokenIx - Instruction to withdraw multiple tokens to the user wallet.
1453
+ * @param {web3.TransactionInstruction[]} unwrapWsolIxs - Instructions to close wSOL accounts, if any.
1454
+ */
1455
+ constructor(createAtaIxs, mainIxs, withdrawMultipleTokenIx, unwrapWsolIxs) {
1456
+ this.createAtaIxs = createAtaIxs;
1457
+ this.mainIxs = mainIxs;
1458
+ this.withdrawMultipleTokenIx = withdrawMultipleTokenIx;
1459
+ this.unwrapWsolIxs = unwrapWsolIxs;
1460
+ }
1461
+ /**
1462
+ * Builds the default sequence of transaction instructions for claiming all rewards by position.
1463
+ *
1464
+ * This method returns an array of transaction instructions that includes:
1465
+ * - Initializing ATAs prior to withdrawal
1466
+ * - Claiming fees and/or rewards
1467
+ * - Withdrawing tokens to the user wallet
1468
+ * - Closing wSOL accounts, if any
1469
+ *
1470
+ * @returns {web3.TransactionInstruction[]} - An array of transaction instructions in the required order.
1471
+ */
1472
+ default() {
1473
+ return [
1474
+ // Step 1: Init ATA prior to withdrawal
1475
+ ...this.createAtaIxs,
1476
+ // Step 2: Claim fees and/or rewards, remove liquidity, and possibly close position (if set)
1477
+ ...this.mainIxs,
1478
+ // Step 3: Withdraw tokens to user wallet
1479
+ this.withdrawMultipleTokenIx,
1480
+ // Step 4: Close wSOL account (if there's any)
1481
+ ...this.unwrapWsolIxs,
1482
+ ];
1483
+ }
1484
+ /**
1485
+ * Replaces claim fee token ixs into storage token account
1486
+ */
1487
+ replaceClaimFeeTokenToSTA() {
1488
+ const index = this.mainIxs.findIndex(mainIx => {
1489
+ const dataWithoutIyfExtensionExecute = mainIx.data.subarray(12);
1490
+ return (0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, "MeteoraDlmmClaimFee2Automation");
1491
+ });
1492
+ // Should never be empty
1493
+ if (index === -1) {
1494
+ // Throw error instead?
1495
+ console.warn(`Warn: claim fee instruction not found! This should not happen.`);
1496
+ return;
1497
+ }
1498
+ const userPda = this.mainIxs[index].keys[0].pubkey;
1499
+ const tokenXMint = this.mainIxs[index].keys[9].pubkey;
1500
+ const tokenYMint = this.mainIxs[index].keys[10].pubkey;
1501
+ const staTokenX = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenXMint);
1502
+ const staTokenY = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenYMint);
1503
+ this.mainIxs[index].keys[7].pubkey = staTokenX;
1504
+ this.mainIxs[index].keys[8].pubkey = staTokenY;
1505
+ }
1506
+ /**
1507
+ * Replaces reward token into storage token account for ALL reward claim instructions.
1508
+ * DLMM pools can have up to 2 reward farms, so we need to handle multiple reward claims.
1509
+ */
1510
+ replaceClaimRewardToSTA() {
1511
+ let foundAny = false;
1512
+ this.mainIxs.forEach((mainIx, index) => {
1513
+ const dataWithoutIyfExtensionExecute = mainIx.data.subarray(12);
1514
+ if ((0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, 'MeteoraDlmmClaimReward2Automation') ||
1515
+ (0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, 'MeteoraDlmmClaimReward2')) {
1516
+ foundAny = true;
1517
+ const userPda = this.mainIxs[index].keys[0].pubkey;
1518
+ const tokenMint = this.mainIxs[index].keys[6].pubkey;
1519
+ const staToken = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenMint);
1520
+ this.mainIxs[index].keys[7].pubkey = staToken;
1521
+ }
1522
+ });
1523
+ if (!foundAny) {
1524
+ console.warn('Warn: Reward instruction not found! This may happen if pool has no rewards');
1525
+ }
1526
+ }
1527
+ }
1528
+ exports.ClaimAllRewardsByPositionBuilder = ClaimAllRewardsByPositionBuilder;
1529
+ /**
1530
+ * A builder class for constructing transaction instructions to add liquidity according to a specified strategy.
1531
+ *
1532
+ * This class provides a structured way to build the necessary transaction instructions for adding liquidity to a position
1533
+ * based on a strategy, handling operations such as wrapping SOL, depositing tokens, adding liquidity, refunding dust, and
1534
+ * managing wrapped SOL (wSOL) accounts.
1535
+ */
1536
+ class AddLiquidityByStrategyBuilder {
1537
+ /**
1538
+ * Constructs an instance of the AddLiquidityByStrategyBuilder class.
1539
+ *
1540
+ * @param {web3.TransactionInstruction[]} wrapSolIxs - Instructions to wrap SOL to wSOL if needed.
1541
+ * @param {web3.TransactionInstruction} depositToPdaIxs - Instruction to deposit X and Y tokens to the UserPDA.
1542
+ * @param {web3.TransactionInstruction[]} mainIxs - Main instructions for adding liquidity by strategy.
1543
+ * @param {web3.TransactionInstruction} refundDustIxs - Instruction to refund dust tokens to the user wallet.
1544
+ * @param {web3.TransactionInstruction[]} unwrapWsolIxs - Instructions to unwrap wSOL to SOL if any.
1545
+ */
1546
+ constructor(wrapSolIxs, depositToPdaIxs, mainIxs, refundDustIxs, unwrapWsolIxs) {
1547
+ this.wrapSolIxs = wrapSolIxs;
1548
+ this.depositToPdaIxs = depositToPdaIxs;
1549
+ this.mainIxs = mainIxs;
1550
+ this.refundDustIxs = refundDustIxs;
1551
+ this.unwrapWsolIxs = unwrapWsolIxs;
1552
+ }
1553
+ /**
1554
+ * Builds the default sequence of transaction instructions for adding liquidity by strategy.
1555
+ *
1556
+ * This method returns an array of transaction instructions that includes:
1557
+ * - Initializing wSOL token accounts if needed
1558
+ * - Depositing X and Y tokens to the UserPDA
1559
+ * - Adding liquidity according to the strategy
1560
+ * - Refunding dust tokens to the user wallet
1561
+ * - Closing wSOL accounts if any
1562
+ *
1563
+ * @returns {web3.TransactionInstruction[]} - An array of transaction instructions in the required order.
1564
+ */
1565
+ default() {
1566
+ return [
1567
+ // Step 1: Init wSOL token account for user wallet (if X or Y token is wSOL)
1568
+ ...this.wrapSolIxs,
1569
+ // Step 2: Deposit X and Y token to UserPDA
1570
+ this.depositToPdaIxs,
1571
+ // Step 3: Add liquidity by strategy
1572
+ ...this.mainIxs,
1573
+ // Step 4: Refund dust to user wallet
1574
+ this.refundDustIxs,
1575
+ // Step 5: Close wSOL account (if there's any)
1576
+ ...this.unwrapWsolIxs,
1577
+ ];
1578
+ }
1579
+ }
1580
+ exports.AddLiquidityByStrategyBuilder = AddLiquidityByStrategyBuilder;
1581
+ /**
1582
+ * A builder class for constructing transaction instructions to remove liquidity from a position.
1583
+ *
1584
+ * This class provides a structured way to build the necessary transaction instructions for removing liquidity
1585
+ * from a position, handling operations such as creating associated token accounts (ATAs), claiming rewards,
1586
+ * withdrawing tokens, and managing wrapped SOL (wSOL) accounts.
1587
+ */
1588
+ class RemoveLiquidityBuilder {
1589
+ /**
1590
+ * Constructs an instance of the RemoveLiquidityBuilder class.
1591
+ *
1592
+ * @param {web3.TransactionInstruction[]} createAtaIxs - Instructions to create associated token accounts (ATAs) prior to withdrawal.
1593
+ * @param {web3.TransactionInstruction[]} mainIxs - Main instructions for claiming fees/rewards, removing liquidity, and possibly closing the position.
1594
+ * @param {web3.TransactionInstruction} withdrawMultipleTokenIx - Instruction to withdraw multiple tokens to the user wallet.
1595
+ * @param {web3.TransactionInstruction[]} unwrapWsolIxs - Instructions to close wSOL accounts, if any.
1596
+ */
1597
+ constructor(createAtaIxs, mainIxs, withdrawMultipleTokenIx, unwrapWsolIxs) {
1598
+ this.createAtaIxs = createAtaIxs;
1599
+ this.mainIxs = mainIxs;
1600
+ this.withdrawMultipleTokenIx = withdrawMultipleTokenIx;
1601
+ this.unwrapWsolIxs = unwrapWsolIxs;
1602
+ }
1603
+ /**
1604
+ * Builds the default sequence of transaction instructions for removing liquidity from a position.
1605
+ *
1606
+ * This method returns an array of transaction instructions that includes:
1607
+ * - Initializing associated token accounts (ATAs) prior to withdrawal
1608
+ * - Claiming fees and/or rewards, removing liquidity, and possibly closing the position
1609
+ * - Withdrawing tokens to the user wallet
1610
+ * - Closing wSOL accounts, if any
1611
+ *
1612
+ * @returns {web3.TransactionInstruction[]} - An array of transaction instructions in the required order.
1613
+ */
1614
+ default() {
1615
+ return [
1616
+ // Step 1: Init ATA prior to withdrawal
1617
+ ...this.createAtaIxs,
1618
+ // Step 2: Claim fees and/or rewards, remove liquidity, and possibly close position (if set)
1619
+ ...this.mainIxs,
1620
+ // Step 3: Withdraw tokens to user wallet
1621
+ this.withdrawMultipleTokenIx,
1622
+ // Step 4: Close wSOL account (if there's any)
1623
+ ...this.unwrapWsolIxs,
1624
+ ];
1625
+ }
1626
+ /**
1627
+ * Replaces claim fee token ixs into storage token account
1628
+ */
1629
+ replaceClaimFeeTokenToSTA() {
1630
+ const index = this.mainIxs.findIndex(mainIx => {
1631
+ const dataWithoutIyfExtensionExecute = mainIx.data.subarray(12);
1632
+ return (0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, "MeteoraDlmmClaimFee2Automation");
1633
+ });
1634
+ if (index === -1) {
1635
+ console.warn(`Warn: claim fee instruction not found! This should not happen if \`shouldClaimAndClose\` is set to true.`);
1636
+ return;
1637
+ }
1638
+ const userPda = this.mainIxs[index].keys[0].pubkey;
1639
+ const tokenXMint = this.mainIxs[index].keys[9].pubkey;
1640
+ const tokenYMint = this.mainIxs[index].keys[10].pubkey;
1641
+ const staTokenX = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenXMint);
1642
+ const staTokenY = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenYMint);
1643
+ this.mainIxs[index].keys[7].pubkey = staTokenX;
1644
+ this.mainIxs[index].keys[8].pubkey = staTokenY;
1645
+ }
1646
+ /**
1647
+ * Replaces reward token into storage token account for ALL reward claim instructions.
1648
+ * DLMM pools can have up to 2 reward farms, so we need to handle multiple reward claims.
1649
+ */
1650
+ replaceClaimRewardToSTA() {
1651
+ let foundAny = false;
1652
+ this.mainIxs.forEach((mainIx, index) => {
1653
+ const dataWithoutIyfExtensionExecute = mainIx.data.subarray(12);
1654
+ if ((0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, 'MeteoraDlmmClaimReward2Automation') ||
1655
+ (0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, 'MeteoraDlmmClaimReward2')) {
1656
+ foundAny = true;
1657
+ const userPda = this.mainIxs[index].keys[0].pubkey;
1658
+ const tokenMint = this.mainIxs[index].keys[6].pubkey;
1659
+ const staToken = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenMint);
1660
+ this.mainIxs[index].keys[7].pubkey = staToken;
1661
+ }
1662
+ });
1663
+ if (!foundAny) {
1664
+ console.warn('Warn: Reward instruction not found! This may happen if pool has no rewards');
1665
+ }
1666
+ }
1667
+ /**
1668
+ * Replaces claim fee token ixs into associated token account
1669
+ */
1670
+ replaceClaimFeeTokenToATA() {
1671
+ const index = this.mainIxs.findIndex(mainIx => {
1672
+ const dataWithoutIyfExtensionExecute = mainIx.data.subarray(12);
1673
+ return (0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, "MeteoraDlmmClaimFee2Automation");
1674
+ });
1675
+ if (index === -1) {
1676
+ console.warn(`Warn: claim fee instruction not found! This should not happen if \`shouldClaimAndClose\` is set to true.`);
1677
+ return;
1678
+ }
1679
+ const userPda = this.mainIxs[index].keys[0].pubkey;
1680
+ const tokenXMint = this.mainIxs[index].keys[9].pubkey;
1681
+ const tokenYMint = this.mainIxs[index].keys[10].pubkey;
1682
+ const staTokenX = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenXMint);
1683
+ const staTokenY = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenYMint);
1684
+ this.mainIxs[index].keys[7].pubkey = staTokenX;
1685
+ this.mainIxs[index].keys[8].pubkey = staTokenY;
1686
+ }
1687
+ /**
1688
+ * Replaces reward token into associated token account for ALL reward claim instructions.
1689
+ * DLMM pools can have up to 2 reward farms, so we need to handle multiple reward claims.
1690
+ */
1691
+ replaceClaimRewardToATA() {
1692
+ let foundAny = false;
1693
+ this.mainIxs.forEach((mainIx, index) => {
1694
+ const dataWithoutIyfExtensionExecute = mainIx.data.subarray(12);
1695
+ if ((0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, 'MeteoraDlmmClaimReward2Automation') ||
1696
+ (0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, 'MeteoraDlmmClaimReward2')) {
1697
+ foundAny = true;
1698
+ const userPda = this.mainIxs[index].keys[0].pubkey;
1699
+ const tokenMint = this.mainIxs[index].keys[6].pubkey;
1700
+ const ataToken = (0, functions_1.generateAta)(userPda, tokenMint);
1701
+ this.mainIxs[index].keys[7].pubkey = ataToken;
1702
+ }
1703
+ });
1704
+ if (!foundAny) {
1705
+ console.warn('Warn: Reward instruction not found! This may happen if pool has no rewards');
1706
+ }
1707
+ }
1708
+ }
1709
+ exports.RemoveLiquidityBuilder = RemoveLiquidityBuilder;
1710
+ /**
1711
+ * A builder class for constructing transaction instructions to remove liquidity from a position to the pda.
1712
+ *
1713
+ * This class provides a structured way to build the necessary transaction instructions for removing liquidity
1714
+ * from a position, handling operations such as creating associated token accounts (ATAs), claiming rewards,
1715
+ * withdrawing tokens, and managing wrapped SOL (wSOL) accounts.
1716
+ */
1717
+ class RemoveLiquidityPdaBuilder {
1718
+ /**
1719
+ * Constructs an instance of the RemoveLiquidityBuilder class.
1720
+ *
1721
+ * @param {web3.TransactionInstruction[]} createAtaIxs - Instructions to create associated token accounts (ATAs) prior to withdrawal.
1722
+ * @param {web3.TransactionInstruction[]} mainIxs - Main instructions for claiming fees/rewards, removing liquidity, and possibly closing the position.
1723
+ * @param {web3.TransactionInstruction[]} unwrapWsolIxs - Instructions to close wSOL accounts, if any.
1724
+ */
1725
+ constructor(
1726
+ // readonly createAtaIxs: web3.TransactionInstruction[],
1727
+ mainIxs) {
1728
+ this.mainIxs = mainIxs;
1729
+ }
1730
+ /**
1731
+ * Builds the default sequence of transaction instructions for removing liquidity from a position.
1732
+ *
1733
+ * This method returns an array of transaction instructions that includes:
1734
+ * - Initializing associated token accounts (ATAs) prior to withdrawal
1735
+ * - Claiming fees and/or rewards, removing liquidity, and possibly closing the position
1736
+ * - Withdrawing tokens to the user wallet
1737
+ * - Closing wSOL accounts, if any
1738
+ *
1739
+ * @returns {web3.TransactionInstruction[]} - An array of transaction instructions in the required order.
1740
+ */
1741
+ default() {
1742
+ return [
1743
+ // Step 1: Init ATA prior to withdrawal
1744
+ // ...this.createAtaIxs,
1745
+ // Step 2: Claim fees and/or rewards, remove liquidity, and possibly close position (if set)
1746
+ ...this.mainIxs,
1747
+ // // Step 3: Withdraw tokens to user wallet
1748
+ // this.withdrawMultipleTokenIx,
1749
+ // // Step 4: Close wSOL account (if there's any)
1750
+ // ...this.unwrapWsolIxs,
1751
+ ];
1752
+ }
1753
+ /**
1754
+ * Replaces claim fee token ixs into storage token account
1755
+ */
1756
+ replaceClaimFeeTokenToSTA() {
1757
+ const index = this.mainIxs.findIndex(mainIx => {
1758
+ const dataWithoutIyfExtensionExecute = mainIx.data.subarray(12);
1759
+ return (0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, "MeteoraDlmmClaimFee");
1760
+ });
1761
+ if (index === -1) {
1762
+ console.warn(`Warn: claim fee instruction not found! This should not happen if \`shouldClaimAndClose\` is set to true.`);
1763
+ return;
1764
+ }
1765
+ const userPda = this.mainIxs[index].keys[1].pubkey;
1766
+ const tokenXMint = this.mainIxs[index].keys[13].pubkey;
1767
+ const tokenYMint = this.mainIxs[index].keys[14].pubkey;
1768
+ const staTokenX = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenXMint);
1769
+ const staTokenY = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenYMint);
1770
+ this.mainIxs[index].keys[11].pubkey = staTokenX;
1771
+ this.mainIxs[index].keys[12].pubkey = staTokenY;
1772
+ }
1773
+ /**
1774
+ * Replaces reward token into storage token account for ALL reward claim instructions.
1775
+ * DLMM pools can have up to 2 reward farms, so we need to handle multiple reward claims.
1776
+ */
1777
+ replaceClaimRewardToSTA() {
1778
+ let foundAny = false;
1779
+ this.mainIxs.forEach((mainIx, index) => {
1780
+ const dataWithoutIyfExtensionExecute = mainIx.data.subarray(12);
1781
+ if ((0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, 'MeteoraDlmmClaimReward2Automation') ||
1782
+ (0, functions_1.sighashMatch)(dataWithoutIyfExtensionExecute, 'MeteoraDlmmClaimReward2')) {
1783
+ foundAny = true;
1784
+ const userPda = this.mainIxs[index].keys[0].pubkey;
1785
+ const tokenMint = this.mainIxs[index].keys[6].pubkey;
1786
+ const staToken = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenMint);
1787
+ this.mainIxs[index].keys[7].pubkey = staToken;
1788
+ }
1789
+ });
1790
+ if (!foundAny) {
1791
+ console.warn('Warn: Reward instruction not found! This may happen if pool has no rewards');
1792
+ }
1793
+ }
1794
+ }
1795
+ exports.RemoveLiquidityPdaBuilder = RemoveLiquidityPdaBuilder;
1796
+ /**
1797
+ * A builder class for constructing transaction instructions to remove liquidity from a position.
1798
+ *
1799
+ * This class provides a structured way to build the necessary transaction instructions for removing liquidity
1800
+ * from a position, handling operations such as creating associated token accounts (ATAs), claiming rewards,
1801
+ * withdrawing tokens, and managing wrapped SOL (wSOL) accounts.
1802
+ */
1803
+ class InitializePositionAndAddLiquidityByStrategyBuilder {
1804
+ /**
1805
+ * Constructs an instance of the InitializePositionAndAddLiquidityByStrategyBuilder class.
1806
+ *
1807
+ * @param {web3.TransactionInstruction[]} wrapSolIxs - Instructions to wrap SOL to wSOL if needed.
1808
+ * @param {web3.TransactionInstruction} depositToPdaIxs - Instruction to deposit X and Y tokens to the UserPDA.
1809
+ * @param {web3.TransactionInstruction[]} mainIxs - Main instructions for adding liquidity by strategy.
1810
+ * @param {web3.TransactionInstruction} refundDustIxs - Instruction to refund dust tokens to the user wallet.
1811
+ * @param {web3.TransactionInstruction[]} unwrapWsolIxs - Instructions to unwrap wSOL to SOL if any.
1812
+ */
1813
+ constructor(wrapSolIxs, depositToPdaIxs, mainIxs, refundDustIxs, unwrapWsolIxs) {
1814
+ this.wrapSolIxs = wrapSolIxs;
1815
+ this.depositToPdaIxs = depositToPdaIxs;
1816
+ this.mainIxs = mainIxs;
1817
+ this.refundDustIxs = refundDustIxs;
1818
+ this.unwrapWsolIxs = unwrapWsolIxs;
1819
+ }
1820
+ /**
1821
+ * Builds the default sequence of transaction instructions for removing liquidity from a position.
1822
+ *
1823
+ * This method returns an array of transaction instructions that includes:
1824
+ * - Initializing associated token accounts (ATAs) prior to withdrawal
1825
+ * - Claiming fees and/or rewards, removing liquidity, and possibly closing the position
1826
+ * - Withdrawing tokens to the user wallet
1827
+ * - Closing wSOL accounts, if any
1828
+ *
1829
+ * @returns {web3.TransactionInstruction[]} - An array of transaction instructions in the required order.
1830
+ */
1831
+ default() {
1832
+ return [
1833
+ // // Step 1: Init wSOL token account for user wallet (if X or Y token is wSOL)
1834
+ ...this.wrapSolIxs,
1835
+ // Step 2: Deposit X and Y token to UserPDA
1836
+ this.depositToPdaIxs,
1837
+ // Step 3: Add liquidity by strategy
1838
+ ...this.mainIxs,
1839
+ // // Step 4: Refund dust to user wallet
1840
+ // this.refundDustIxs,
1841
+ // // Step 5: Close wSOL account (if there's any)
1842
+ ...this.unwrapWsolIxs,
1843
+ ];
1844
+ }
1845
+ }
1846
+ exports.InitializePositionAndAddLiquidityByStrategyBuilder = InitializePositionAndAddLiquidityByStrategyBuilder;
1847
+ /**
1848
+ * A builder class for constructing transaction instructions to remove liquidity from a position.
1849
+ *
1850
+ * This class provides a structured way to build the necessary transaction instructions for removing liquidity
1851
+ * from a position, handling operations such as creating associated token accounts (ATAs), claiming rewards,
1852
+ * withdrawing tokens, and managing wrapped SOL (wSOL) accounts.
1853
+ */
1854
+ class InitializePositionAndAddLiquidityByStrategyBuilderLabeled {
1855
+ /**
1856
+ * Constructs an instance of the InitializePositionAndAddLiquidityByStrategyBuilderLabeled class.
1857
+ *
1858
+ * @param {LabeledInstruction[]} wrapSolIxs - Instructions to wrap SOL to wSOL if needed.
1859
+ * @param {LabeledInstruction} depositToPdaIxs - Instruction to deposit X and Y tokens to the UserPDA.
1860
+ * @param {LabeledInstruction[]} mainIxs - Main instructions for adding liquidity by strategy.
1861
+ * @param {LabeledInstruction} refundDustIxs - Instruction to refund dust tokens to the user wallet.
1862
+ * @param {LabeledInstruction[]} unwrapWsolIxs - Instructions to unwrap wSOL to SOL if any.
1863
+ */
1864
+ constructor(wrapSolIxs, depositToPdaIxs, mainIxs, refundDustIxs, unwrapWsolIxs) {
1865
+ this.wrapSolIxs = wrapSolIxs;
1866
+ this.depositToPdaIxs = depositToPdaIxs;
1867
+ this.mainIxs = mainIxs;
1868
+ this.refundDustIxs = refundDustIxs;
1869
+ this.unwrapWsolIxs = unwrapWsolIxs;
1870
+ }
1871
+ /**
1872
+ * Builds the default sequence of transaction instructions for removing liquidity from a position.
1873
+ *
1874
+ * This method returns an array of transaction instructions that includes:
1875
+ * - Initializing associated token accounts (ATAs) prior to withdrawal
1876
+ * - Claiming fees and/or rewards, removing liquidity, and possibly closing the position
1877
+ * - Withdrawing tokens to the user wallet
1878
+ * - Closing wSOL accounts, if any
1879
+ *
1880
+ * @returns {LabeledInstruction[]} - An array of transaction instructions in the required order.
1881
+ */
1882
+ default() {
1883
+ return [
1884
+ // // Step 1: Init wSOL token account for user wallet (if X or Y token is wSOL)
1885
+ ...this.wrapSolIxs,
1886
+ // Step 2: Deposit X and Y token to UserPDA
1887
+ this.depositToPdaIxs,
1888
+ // Step 3: Add liquidity by strategy
1889
+ ...this.mainIxs,
1890
+ // // Step 4: Refund dust to user wallet
1891
+ // this.refundDustIxs,
1892
+ // // Step 5: Close wSOL account (if there's any)
1893
+ ...this.unwrapWsolIxs,
1894
+ ];
1895
+ }
1896
+ }
1897
+ exports.InitializePositionAndAddLiquidityByStrategyBuilderLabeled = InitializePositionAndAddLiquidityByStrategyBuilderLabeled;
1898
+ /**
1899
+ * A builder class for constructing transaction instructions to remove liquidity from a position.
1900
+ *
1901
+ * This class provides a structured way to build the necessary transaction instructions for removing liquidity
1902
+ * from a position, handling operations such as creating associated token accounts (ATAs), claiming rewards,
1903
+ * withdrawing tokens, and managing wrapped SOL (wSOL) accounts.
1904
+ */
1905
+ class InitializePositionAndAddLiquidityByStrategyPdaBuilder {
1906
+ /**
1907
+ * Constructs an instance of the InitializePositionAndAddLiquidityByStrategyBuilder class.
1908
+ *
1909
+ * @param {web3.TransactionInstruction[]} mainIxs - Main instructions for adding liquidity by strategy.
1910
+ */
1911
+ constructor(mainIxs) {
1912
+ this.mainIxs = mainIxs;
1913
+ }
1914
+ /**
1915
+ * Builds the default sequence of transaction instructions for removing liquidity from a position.
1916
+ *
1917
+ * This method returns an array of transaction instructions that includes:
1918
+ * - Initializing associated token accounts (ATAs) prior to withdrawal
1919
+ * - Claiming fees and/or rewards, removing liquidity, and possibly closing the position
1920
+ * - Withdrawing tokens to the user wallet
1921
+ * - Closing wSOL accounts, if any
1922
+ *
1923
+ * @returns {web3.TransactionInstruction[]} - An array of transaction instructions in the required order.
1924
+ */
1925
+ default() {
1926
+ return [
1927
+ // Step 1: Init Position and add liquidity via pda
1928
+ ...this.mainIxs,
1929
+ ];
1930
+ }
1931
+ }
1932
+ exports.InitializePositionAndAddLiquidityByStrategyPdaBuilder = InitializePositionAndAddLiquidityByStrategyPdaBuilder;