@hawksightco/hawk-sdk 1.3.180 → 1.3.182
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.
- package/dist/src/addresses.d.ts +2 -0
- package/dist/src/addresses.d.ts.map +1 -1
- package/dist/src/addresses.js +4 -1
- package/dist/src/classes/SimpleIxGenerator.d.ts +7 -0
- package/dist/src/classes/SimpleIxGenerator.d.ts.map +1 -1
- package/dist/src/classes/SimpleIxGenerator.js +7 -0
- package/dist/src/classes/SimplePdaGenerator.d.ts +7 -2
- package/dist/src/classes/SimplePdaGenerator.d.ts.map +1 -1
- package/dist/src/classes/SimplePdaGenerator.js +7 -2
- package/dist/src/classes/Transactions.d.ts +89 -1
- package/dist/src/classes/Transactions.d.ts.map +1 -1
- package/dist/src/classes/Transactions.js +525 -0
- package/dist/src/classes/TxGenerator.d.ts +24 -1
- package/dist/src/classes/TxGenerator.d.ts.map +1 -1
- package/dist/src/classes/TxGenerator.js +96 -0
- package/dist/src/classes/TxGeneratorAutomations.d.ts +59 -1
- package/dist/src/classes/TxGeneratorAutomations.d.ts.map +1 -1
- package/dist/src/classes/TxGeneratorAutomations.js +157 -0
- package/dist/src/functions.d.ts +7 -13
- package/dist/src/functions.d.ts.map +1 -1
- package/dist/src/functions.js +144 -92
- package/dist/src/ixGenerator/HatchIxGenerator.d.ts +92 -0
- package/dist/src/ixGenerator/HatchIxGenerator.d.ts.map +1 -0
- package/dist/src/ixGenerator/HatchIxGenerator.js +304 -0
- package/dist/src/ixGenerator/MeteoraDlmmIxGenerator.d.ts +192 -3
- package/dist/src/ixGenerator/MeteoraDlmmIxGenerator.d.ts.map +1 -1
- package/dist/src/ixGenerator/MeteoraDlmmIxGenerator.js +643 -33
- package/dist/src/pdaGenerator/HatchPdaGenerator.d.ts +41 -0
- package/dist/src/pdaGenerator/HatchPdaGenerator.d.ts.map +1 -0
- package/dist/src/pdaGenerator/HatchPdaGenerator.js +90 -0
- package/dist/src/types.d.ts +127 -0
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +7 -6
- package/CHANGELOG.md +0 -135
- package/test/artifacts/temp/.gitignore +0 -2
- package/test/artifacts/temp/accounts/.gitignore +0 -2
- package/test/logs/.gitignore +0 -2
- package/test/visualization/output/.gitignore +0 -2
|
@@ -156,27 +156,199 @@ class MeteoraDlmmIxGenerator {
|
|
|
156
156
|
const userPda = (0, functions_1.generateUserPda)(userWallet);
|
|
157
157
|
// Generate instruction
|
|
158
158
|
const width = upperBinId - lowerBinId + 1;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
159
|
+
// @ts-ignore
|
|
160
|
+
const iyfExtensionIx = yield anchor_1.Anchor.instance().iyfExtension
|
|
161
|
+
.methods
|
|
162
|
+
.meteoraDlmmInitializePositionAutomation(lowerBinId, width)
|
|
163
|
+
.accounts({
|
|
164
|
+
farm: addresses_1.USDC_FARM,
|
|
165
|
+
userPda,
|
|
166
|
+
authority: userWallet,
|
|
167
|
+
iyfProgram: addresses_1.IYF_MAIN,
|
|
168
|
+
hawksightAuthority: addresses_1.HS_AUTHORITY,
|
|
169
|
+
position,
|
|
170
|
+
lbPair,
|
|
171
|
+
systemProgram: web3.SystemProgram.programId,
|
|
172
|
+
rent: web3.SYSVAR_RENT_PUBKEY,
|
|
173
|
+
eventAuthority: METEORA_EVENT_AUTHORITY,
|
|
174
|
+
meteoraDlmmProgram: METEORA_DLMM_PROGRAM,
|
|
175
|
+
})
|
|
176
|
+
.instruction();
|
|
177
|
+
// Set position to writable
|
|
178
|
+
iyfExtensionIx.keys = iyfExtensionIx.keys.map(meta => {
|
|
179
|
+
if (meta.pubkey === position) {
|
|
180
|
+
meta.isWritable = true;
|
|
181
|
+
}
|
|
182
|
+
return meta;
|
|
179
183
|
});
|
|
184
|
+
return this.ix.iyfMain.iyfExtensionExecute(connection, { userWallet, iyfExtensionIx });
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
initializePositionRelativeAutomation(connection_1, _a) {
|
|
188
|
+
return __awaiter(this, arguments, void 0, function* (connection, { userWallet, lbPair, position, relativeLowerBinId, width, useFuelAccount }) {
|
|
189
|
+
// Initialize anchor
|
|
190
|
+
anchor_1.Anchor.initialize(connection);
|
|
191
|
+
// Width > 70 is invalid (will error on-chain)
|
|
192
|
+
if (width > 70) {
|
|
193
|
+
throw new Error("Width exceeds maximum allowed 70 bins");
|
|
194
|
+
}
|
|
195
|
+
// Generate user pda
|
|
196
|
+
const userPda = (0, functions_1.generateUserPda)(userWallet);
|
|
197
|
+
// Generate instruction
|
|
198
|
+
return this.ix.iyfMain.iyfExtensionExecuteV2(connection, { userPda, authority: addresses_1.HS_AUTHORITY, ix: new web3.TransactionInstruction({
|
|
199
|
+
data: Buffer.concat([
|
|
200
|
+
Buffer.from(util.sighash("meteora_dlmm_initialize_position_relative_automation")),
|
|
201
|
+
new bn_js_1.default(relativeLowerBinId).toTwos(16).toArrayLike(Buffer, "le", 2),
|
|
202
|
+
Buffer.from([width]),
|
|
203
|
+
]),
|
|
204
|
+
keys: [
|
|
205
|
+
{ pubkey: userPda, isSigner: false, isWritable: false },
|
|
206
|
+
{ pubkey: addresses_1.HS_AUTHORITY, isSigner: true, isWritable: false },
|
|
207
|
+
{ pubkey: position, isSigner: true, isWritable: true },
|
|
208
|
+
{ pubkey: lbPair, isSigner: false, isWritable: true },
|
|
209
|
+
{ pubkey: web3.SystemProgram.programId, isSigner: false, isWritable: false },
|
|
210
|
+
{ pubkey: web3.SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
|
|
211
|
+
{ pubkey: METEORA_EVENT_AUTHORITY, isSigner: false, isWritable: true },
|
|
212
|
+
{ pubkey: METEORA_DLMM_PROGRAM, isSigner: false, isWritable: true },
|
|
213
|
+
...useFuelAccount ? [{ pubkey: (0, functions_1.generateFuelAccount)(userWallet), isSigner: false, isWritable: true }] : [],
|
|
214
|
+
],
|
|
215
|
+
programId: addresses_1.IYF_EXTENSION,
|
|
216
|
+
}) });
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Add liquidity to an existing Meteora DLMM position using strategy parameters.
|
|
221
|
+
* This is the automation version that uses V2 execution (meteora_dlmm_deposit_2_automation).
|
|
222
|
+
*
|
|
223
|
+
* Key differences from depositAutomation:
|
|
224
|
+
* - Uses iyfExtensionExecuteV2 with Anchor-based instruction building
|
|
225
|
+
* - Supports remainingAccountsInfo for Token2022 transfer hooks
|
|
226
|
+
* - Authority is HS_AUTHORITY (automation wallet)
|
|
227
|
+
* - Does not require binArrayLower/binArrayUpper (bin arrays are auto-derived or created separately)
|
|
228
|
+
*
|
|
229
|
+
* @param connection - Solana connection
|
|
230
|
+
* @param params - AddLiquidityByStrategy2AutomationParams parameters
|
|
231
|
+
* @returns TransactionInstruction for adding liquidity
|
|
232
|
+
*/
|
|
233
|
+
meteoraDlmmDepositRelativeAutomation(_a) {
|
|
234
|
+
return __awaiter(this, arguments, void 0, function* ({ connection, userWallet, lbPair, position, tokenXMint, tokenYMint, tokenXProgram, tokenYProgram, activeId, relativeBinRange, strategyType, optionalTokenXAmount, optionalTokenYAmount, checkRange, remainingAccountsInfo, pdaTokenType }) {
|
|
235
|
+
var _b, _c, _d, _e;
|
|
236
|
+
// Initialize anchor
|
|
237
|
+
anchor_1.Anchor.initialize(connection);
|
|
238
|
+
// Derive reserves from the ACTUAL lbPair (not the one passed in, which may be incorrect)
|
|
239
|
+
const reserveX = this.pda.meteora.deriveReserve(tokenXMint, lbPair);
|
|
240
|
+
const reserveY = this.pda.meteora.deriveReserve(tokenYMint, lbPair);
|
|
241
|
+
// Derive bin array bitmap extension from actual lb_pair and check if it exists
|
|
242
|
+
const derivedBinArrayBitmapExtension = this.pda.meteora.deriveBinArrayBitmapExtension(lbPair);
|
|
243
|
+
const binArrayBitmapExtensionInfo = yield connection.getAccountInfo(derivedBinArrayBitmapExtension);
|
|
244
|
+
const actualBinArrayBitmapExtension = binArrayBitmapExtensionInfo
|
|
245
|
+
? derivedBinArrayBitmapExtension
|
|
246
|
+
: METEORA_DLMM_PROGRAM;
|
|
247
|
+
const userPda = (0, functions_1.generateUserPda)(userWallet);
|
|
248
|
+
// Determine user token accounts based on pdaTokenType
|
|
249
|
+
let userTokenX;
|
|
250
|
+
let userTokenY;
|
|
251
|
+
if (pdaTokenType === types_1.TokenType.LTA) {
|
|
252
|
+
userTokenX = (0, functions_1.generateLimitToken)(userPda, tokenXMint);
|
|
253
|
+
userTokenY = (0, functions_1.generateLimitToken)(userPda, tokenYMint);
|
|
254
|
+
}
|
|
255
|
+
else if (pdaTokenType === types_1.TokenType.STA) {
|
|
256
|
+
userTokenX = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenXMint);
|
|
257
|
+
userTokenY = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenYMint);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
// Default: ATA
|
|
261
|
+
userTokenX = (0, functions_1.generateAta)(userPda, tokenXMint, tokenXProgram);
|
|
262
|
+
userTokenY = (0, functions_1.generateAta)(userPda, tokenYMint, tokenYProgram);
|
|
263
|
+
}
|
|
264
|
+
// Serialize RemainingAccountsInfo as Vec<u8> (Borsh format)
|
|
265
|
+
// This is passed directly to the on-chain instruction which forwards it to Meteora
|
|
266
|
+
// For SPL tokens (non-Token2022), we still need to provide the slices structure with length=0
|
|
267
|
+
// This matches what Meteora SDK's getPotentialToken2022IxDataAndAccounts returns
|
|
268
|
+
// AccountsType enum: 0=TransferHookX, 1=TransferHookY, 2=TransferHookReward
|
|
269
|
+
const defaultSlices = [
|
|
270
|
+
{ accountsType: 0, length: 0 }, // TransferHookX with 0 accounts
|
|
271
|
+
{ accountsType: 1, length: 0 }, // TransferHookY with 0 accounts
|
|
272
|
+
];
|
|
273
|
+
const remainingAccountsInfoSerialized = this.serializeRemainingAccountsInfo({
|
|
274
|
+
slices: (_b = remainingAccountsInfo === null || remainingAccountsInfo === void 0 ? void 0 : remainingAccountsInfo.slices) !== null && _b !== void 0 ? _b : defaultSlices,
|
|
275
|
+
});
|
|
276
|
+
const lowerBinId = activeId + relativeBinRange.lowerRange;
|
|
277
|
+
const upperBinId = activeId + relativeBinRange.upperRange;
|
|
278
|
+
// Derive bin arrays needed for the deposit range using the lbPair from position
|
|
279
|
+
const binArrays = meteora_1.MeteoraFunctions.findMeteoraTickArrays(lbPair, lowerBinId, upperBinId);
|
|
280
|
+
const binArrayAccounts = binArrays.map(binArray => ({
|
|
281
|
+
pubkey: binArray,
|
|
282
|
+
isSigner: false,
|
|
283
|
+
isWritable: true,
|
|
284
|
+
}));
|
|
285
|
+
// Build remaining accounts: Token2022 transfer hook accounts first (described by remainingAccountsInfo),
|
|
286
|
+
// then bin arrays (not described - Meteora expects them at the end after transfer hooks)
|
|
287
|
+
const remainingAccounts = [
|
|
288
|
+
...((_c = remainingAccountsInfo === null || remainingAccountsInfo === void 0 ? void 0 : remainingAccountsInfo.accounts) !== null && _c !== void 0 ? _c : []),
|
|
289
|
+
...binArrayAccounts,
|
|
290
|
+
];
|
|
291
|
+
const remainingAccountsInfoLength = Buffer.alloc(4);
|
|
292
|
+
remainingAccountsInfoLength.writeUInt32LE(remainingAccountsInfoSerialized.length, 0);
|
|
293
|
+
const relativeLowerRange = Buffer.alloc(2);
|
|
294
|
+
relativeLowerRange.writeInt16LE(relativeBinRange.lowerRange, 0);
|
|
295
|
+
const relativeUpperRange = Buffer.alloc(2);
|
|
296
|
+
relativeUpperRange.writeInt16LE(relativeBinRange.upperRange, 0);
|
|
297
|
+
const checkLowerRange = Buffer.alloc(4);
|
|
298
|
+
checkLowerRange.writeInt32LE((_d = checkRange === null || checkRange === void 0 ? void 0 : checkRange.lowerRange) !== null && _d !== void 0 ? _d : 0, 0);
|
|
299
|
+
const checkUpperRange = Buffer.alloc(4);
|
|
300
|
+
checkUpperRange.writeInt32LE((_e = checkRange === null || checkRange === void 0 ? void 0 : checkRange.upperRange) !== null && _e !== void 0 ? _e : 0, 0);
|
|
301
|
+
const optionalTokenXAmountBuffer = optionalTokenXAmount ? Buffer.concat([
|
|
302
|
+
Buffer.from([1]),
|
|
303
|
+
Buffer.from(optionalTokenXAmount.toArrayLike(Buffer, "le", 8)),
|
|
304
|
+
]) : Buffer.from([0]);
|
|
305
|
+
const optionalTokenYAmountBuffer = optionalTokenYAmount ? Buffer.concat([
|
|
306
|
+
Buffer.from([1]),
|
|
307
|
+
Buffer.from(optionalTokenYAmount.toArrayLike(Buffer, "le", 8)),
|
|
308
|
+
]) : Buffer.from([0]);
|
|
309
|
+
const remainingAccountsInfoSerializedWithLength = Buffer.concat([
|
|
310
|
+
remainingAccountsInfoLength,
|
|
311
|
+
remainingAccountsInfoSerialized
|
|
312
|
+
]);
|
|
313
|
+
// Use Anchor to serialize the instruction (ensures proper Borsh serialization)
|
|
314
|
+
// @ts-ignore
|
|
315
|
+
const depositIx = new web3.TransactionInstruction({
|
|
316
|
+
data: Buffer.concat([
|
|
317
|
+
Buffer.from(util.sighash("meteora_dlmm_deposit_relative_automation")),
|
|
318
|
+
relativeLowerRange,
|
|
319
|
+
relativeUpperRange,
|
|
320
|
+
Buffer.from([strategyType]),
|
|
321
|
+
optionalTokenXAmountBuffer,
|
|
322
|
+
optionalTokenYAmountBuffer,
|
|
323
|
+
Buffer.from(!!checkRange ?
|
|
324
|
+
Buffer.concat([
|
|
325
|
+
Buffer.from([1]),
|
|
326
|
+
checkLowerRange,
|
|
327
|
+
checkUpperRange
|
|
328
|
+
]) : Buffer.from([0])),
|
|
329
|
+
remainingAccountsInfoSerializedWithLength,
|
|
330
|
+
]),
|
|
331
|
+
keys: [
|
|
332
|
+
{ pubkey: userPda, isSigner: false, isWritable: false },
|
|
333
|
+
{ pubkey: addresses_1.HS_AUTHORITY, isSigner: true, isWritable: false },
|
|
334
|
+
{ pubkey: position, isSigner: true, isWritable: true },
|
|
335
|
+
{ pubkey: lbPair, isSigner: false, isWritable: true },
|
|
336
|
+
{ pubkey: userTokenX, isSigner: false, isWritable: true },
|
|
337
|
+
{ pubkey: userTokenY, isSigner: false, isWritable: true },
|
|
338
|
+
{ pubkey: reserveX, isSigner: false, isWritable: true },
|
|
339
|
+
{ pubkey: reserveY, isSigner: false, isWritable: true },
|
|
340
|
+
{ pubkey: tokenXMint, isSigner: false, isWritable: false },
|
|
341
|
+
{ pubkey: tokenYMint, isSigner: false, isWritable: false },
|
|
342
|
+
{ pubkey: tokenXProgram, isSigner: false, isWritable: false },
|
|
343
|
+
{ pubkey: tokenYProgram, isSigner: false, isWritable: false },
|
|
344
|
+
{ pubkey: actualBinArrayBitmapExtension, isSigner: false, isWritable: true },
|
|
345
|
+
{ pubkey: METEORA_EVENT_AUTHORITY, isSigner: false, isWritable: true },
|
|
346
|
+
{ pubkey: METEORA_DLMM_PROGRAM, isSigner: false, isWritable: true },
|
|
347
|
+
...remainingAccounts,
|
|
348
|
+
],
|
|
349
|
+
programId: addresses_1.IYF_EXTENSION,
|
|
350
|
+
});
|
|
351
|
+
return this.ix.iyfMain.iyfExtensionExecuteV2(connection, { userPda, authority: addresses_1.HS_AUTHORITY, ix: depositIx });
|
|
180
352
|
});
|
|
181
353
|
}
|
|
182
354
|
redepositAutomation(connection_1, _a) {
|
|
@@ -701,25 +873,167 @@ class MeteoraDlmmIxGenerator {
|
|
|
701
873
|
});
|
|
702
874
|
});
|
|
703
875
|
}
|
|
704
|
-
|
|
705
|
-
|
|
876
|
+
/**
|
|
877
|
+
* Claim fees from a Meteora DLMM position via IYF Extension for automation.
|
|
878
|
+
*
|
|
879
|
+
* This is the automation version that uses HS_AUTHORITY as the signer.
|
|
880
|
+
*
|
|
881
|
+
* @param connection - Solana connection
|
|
882
|
+
* @param params - ClaimFee2AutomationParams parameters
|
|
883
|
+
* @returns TransactionInstruction for the claim_fee2 automation operation
|
|
884
|
+
*/
|
|
885
|
+
claimFee2Automation(connection_1, _a) {
|
|
886
|
+
return __awaiter(this, arguments, void 0, function* (connection, { userWallet, lbPair, position, tokenMintX, tokenMintY, tokenProgramX, tokenProgramY, lowerBinId, upperBinId, pdaTokenType, remainingAccountsInfo, }) {
|
|
887
|
+
var _b, _c;
|
|
706
888
|
// Initialize anchor
|
|
707
889
|
anchor_1.Anchor.initialize(connection);
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
890
|
+
const userPda = (0, functions_1.generateUserPda)(userWallet);
|
|
891
|
+
const reserveX = this.pda.meteora.deriveReserve(tokenMintX, lbPair);
|
|
892
|
+
const reserveY = this.pda.meteora.deriveReserve(tokenMintY, lbPair);
|
|
893
|
+
// Generate user token accounts based on pdaTokenType
|
|
894
|
+
let userTokenX;
|
|
895
|
+
let userTokenY;
|
|
896
|
+
if (pdaTokenType === types_1.TokenType.LTA) {
|
|
897
|
+
userTokenX = (0, functions_1.generateLimitToken)(userPda, tokenMintX);
|
|
898
|
+
userTokenY = (0, functions_1.generateLimitToken)(userPda, tokenMintY);
|
|
899
|
+
}
|
|
900
|
+
else if (pdaTokenType === types_1.TokenType.STA) {
|
|
901
|
+
userTokenX = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenMintX);
|
|
902
|
+
userTokenY = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenMintY);
|
|
903
|
+
}
|
|
904
|
+
else {
|
|
905
|
+
// Default: ATA
|
|
906
|
+
userTokenX = (0, functions_1.generateAta)(userPda, tokenMintX, tokenProgramX);
|
|
907
|
+
userTokenY = (0, functions_1.generateAta)(userPda, tokenMintY, tokenProgramY);
|
|
908
|
+
}
|
|
909
|
+
const ownerFeeX = (0, functions_1.generateAta)(addresses_1.SITE_FEE_OWNER, tokenMintX, tokenProgramX);
|
|
910
|
+
const ownerFeeY = (0, functions_1.generateAta)(addresses_1.SITE_FEE_OWNER, tokenMintY, tokenProgramY);
|
|
911
|
+
const binArrays = this.pda.meteora.deriveBinArrays(lbPair, lowerBinId, upperBinId);
|
|
912
|
+
const sighash = util.sighash("meteora_dlmm_claim_fee_2_automation");
|
|
913
|
+
const minBinId = Buffer.alloc(4);
|
|
914
|
+
const maxBinId = Buffer.alloc(4);
|
|
915
|
+
minBinId.writeInt32LE(lowerBinId, 0);
|
|
916
|
+
maxBinId.writeInt32LE(upperBinId, 0);
|
|
917
|
+
// Serialize RemainingAccountsInfo with Vec<u8> length prefix for Anchor
|
|
918
|
+
const remainingAccountsInfoContent = this.serializeRemainingAccountsInfo({
|
|
919
|
+
slices: (_b = remainingAccountsInfo === null || remainingAccountsInfo === void 0 ? void 0 : remainingAccountsInfo.slices) !== null && _b !== void 0 ? _b : [],
|
|
920
|
+
});
|
|
921
|
+
// For Anchor Vec<u8> parameter, we need to prepend the length as u32 LE
|
|
922
|
+
const remainingAccountsInfoVec = Buffer.alloc(4 + remainingAccountsInfoContent.length);
|
|
923
|
+
remainingAccountsInfoVec.writeUInt32LE(remainingAccountsInfoContent.length, 0);
|
|
924
|
+
remainingAccountsInfoContent.copy(remainingAccountsInfoVec, 4);
|
|
925
|
+
return yield this.ix.iyfMain.iyfExtensionExecuteV2(connection, {
|
|
926
|
+
userPda,
|
|
927
|
+
authority: addresses_1.HS_AUTHORITY,
|
|
928
|
+
ix: new web3.TransactionInstruction({
|
|
929
|
+
data: Buffer.concat([
|
|
930
|
+
new Uint8Array(sighash),
|
|
931
|
+
new Uint8Array(minBinId),
|
|
932
|
+
new Uint8Array(maxBinId),
|
|
933
|
+
new Uint8Array(remainingAccountsInfoVec),
|
|
934
|
+
]),
|
|
935
|
+
keys: [
|
|
936
|
+
{ pubkey: userPda, isSigner: false, isWritable: false },
|
|
937
|
+
{ pubkey: addresses_1.HS_AUTHORITY, isSigner: true, isWritable: false },
|
|
938
|
+
{ pubkey: lbPair, isSigner: false, isWritable: true },
|
|
939
|
+
{ pubkey: position, isSigner: false, isWritable: true },
|
|
940
|
+
{ pubkey: reserveX, isSigner: false, isWritable: true },
|
|
941
|
+
{ pubkey: reserveY, isSigner: false, isWritable: true },
|
|
942
|
+
{ pubkey: userTokenX, isSigner: false, isWritable: true },
|
|
943
|
+
{ pubkey: userTokenY, isSigner: false, isWritable: true },
|
|
944
|
+
{ pubkey: tokenMintX, isSigner: false, isWritable: false },
|
|
945
|
+
{ pubkey: tokenMintY, isSigner: false, isWritable: false },
|
|
946
|
+
{ pubkey: tokenProgramX, isSigner: false, isWritable: false },
|
|
947
|
+
{ pubkey: tokenProgramY, isSigner: false, isWritable: false },
|
|
948
|
+
{ pubkey: addresses_1.MEMO_PROGRAM, isSigner: false, isWritable: false },
|
|
949
|
+
{ pubkey: METEORA_EVENT_AUTHORITY, isSigner: false, isWritable: false },
|
|
950
|
+
{ pubkey: METEORA_DLMM_PROGRAM, isSigner: false, isWritable: false },
|
|
951
|
+
{ pubkey: ownerFeeX, isSigner: false, isWritable: true },
|
|
952
|
+
{ pubkey: ownerFeeY, isSigner: false, isWritable: true },
|
|
953
|
+
...binArrays.map(binArray => ({ pubkey: binArray, isSigner: false, isWritable: true })),
|
|
954
|
+
// Transfer hook accounts (if any)
|
|
955
|
+
...((_c = remainingAccountsInfo === null || remainingAccountsInfo === void 0 ? void 0 : remainingAccountsInfo.accounts) !== null && _c !== void 0 ? _c : []),
|
|
956
|
+
],
|
|
957
|
+
programId: addresses_1.IYF_EXTENSION,
|
|
958
|
+
})
|
|
712
959
|
});
|
|
713
960
|
});
|
|
714
961
|
}
|
|
715
|
-
|
|
716
|
-
|
|
962
|
+
/**
|
|
963
|
+
* Claim rewards from a Meteora DLMM position via IYF Extension for automation.
|
|
964
|
+
*
|
|
965
|
+
* This is the automation version that uses HS_AUTHORITY as the signer.
|
|
966
|
+
*
|
|
967
|
+
* @param connection - Solana connection
|
|
968
|
+
* @param params - ClaimReward2AutomationParams parameters
|
|
969
|
+
* @returns TransactionInstruction for the claim_reward2 automation operation
|
|
970
|
+
*/
|
|
971
|
+
claimReward2Automation(connection_1, _a) {
|
|
972
|
+
return __awaiter(this, arguments, void 0, function* (connection, { userWallet, lbPair, position, rewardIndex, rewardMint, rewardVault, tokenProgram, lowerBinId, upperBinId, pdaTokenType, remainingAccountsInfo, }) {
|
|
973
|
+
var _b, _c;
|
|
717
974
|
// Initialize anchor
|
|
718
975
|
anchor_1.Anchor.initialize(connection);
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
976
|
+
const userPda = (0, functions_1.generateUserPda)(userWallet);
|
|
977
|
+
// Generate user token account based on pdaTokenType
|
|
978
|
+
let userTokenAccount;
|
|
979
|
+
if (pdaTokenType === types_1.TokenType.LTA) {
|
|
980
|
+
userTokenAccount = (0, functions_1.generateLimitToken)(userPda, rewardMint);
|
|
981
|
+
}
|
|
982
|
+
else if (pdaTokenType === types_1.TokenType.STA) {
|
|
983
|
+
userTokenAccount = (0, functions_1.generateUserPdaStorageAccount)(userPda, rewardMint);
|
|
984
|
+
}
|
|
985
|
+
else {
|
|
986
|
+
// Default: ATA
|
|
987
|
+
userTokenAccount = (0, functions_1.generateAta)(userPda, rewardMint, tokenProgram);
|
|
988
|
+
}
|
|
989
|
+
const ownerFee = (0, functions_1.generateAta)(addresses_1.SITE_FEE_OWNER, rewardMint, tokenProgram);
|
|
990
|
+
const binArrays = this.pda.meteora.deriveBinArrays(lbPair, lowerBinId, upperBinId);
|
|
991
|
+
const sighash = util.sighash("meteora_dlmm_claim_reward_2_automation");
|
|
992
|
+
const minBinId = Buffer.alloc(4);
|
|
993
|
+
const maxBinId = Buffer.alloc(4);
|
|
994
|
+
minBinId.writeInt32LE(lowerBinId, 0);
|
|
995
|
+
maxBinId.writeInt32LE(upperBinId, 0);
|
|
996
|
+
// Serialize RemainingAccountsInfo with Vec<u8> length prefix for Anchor
|
|
997
|
+
const remainingAccountsInfoContent = this.serializeRemainingAccountsInfo({
|
|
998
|
+
slices: (_b = remainingAccountsInfo === null || remainingAccountsInfo === void 0 ? void 0 : remainingAccountsInfo.slices) !== null && _b !== void 0 ? _b : [],
|
|
999
|
+
});
|
|
1000
|
+
// For Anchor Vec<u8> parameter, we need to prepend the length as u32 LE
|
|
1001
|
+
const remainingAccountsInfoVec = Buffer.alloc(4 + remainingAccountsInfoContent.length);
|
|
1002
|
+
remainingAccountsInfoVec.writeUInt32LE(remainingAccountsInfoContent.length, 0);
|
|
1003
|
+
remainingAccountsInfoContent.copy(remainingAccountsInfoVec, 4);
|
|
1004
|
+
// Serialize rewardIndex as u64 (8 bytes, little endian)
|
|
1005
|
+
const rewardIndexBuffer = Buffer.alloc(8);
|
|
1006
|
+
rewardIndexBuffer.writeBigUInt64LE(BigInt(rewardIndex), 0);
|
|
1007
|
+
return yield this.ix.iyfMain.iyfExtensionExecuteV2(connection, {
|
|
1008
|
+
userPda,
|
|
1009
|
+
authority: addresses_1.HS_AUTHORITY,
|
|
1010
|
+
ix: new web3.TransactionInstruction({
|
|
1011
|
+
data: Buffer.concat([
|
|
1012
|
+
new Uint8Array(sighash),
|
|
1013
|
+
new Uint8Array(rewardIndexBuffer),
|
|
1014
|
+
new Uint8Array(minBinId),
|
|
1015
|
+
new Uint8Array(maxBinId),
|
|
1016
|
+
new Uint8Array(remainingAccountsInfoVec),
|
|
1017
|
+
]),
|
|
1018
|
+
keys: [
|
|
1019
|
+
{ pubkey: userPda, isSigner: false, isWritable: false },
|
|
1020
|
+
{ pubkey: addresses_1.HS_AUTHORITY, isSigner: true, isWritable: false },
|
|
1021
|
+
{ pubkey: lbPair, isSigner: false, isWritable: true },
|
|
1022
|
+
{ pubkey: position, isSigner: false, isWritable: true },
|
|
1023
|
+
{ pubkey: rewardVault, isSigner: false, isWritable: true },
|
|
1024
|
+
{ pubkey: rewardMint, isSigner: false, isWritable: true },
|
|
1025
|
+
{ pubkey: userTokenAccount, isSigner: false, isWritable: true },
|
|
1026
|
+
{ pubkey: tokenProgram, isSigner: false, isWritable: true },
|
|
1027
|
+
{ pubkey: addresses_1.MEMO_PROGRAM, isSigner: false, isWritable: false },
|
|
1028
|
+
{ pubkey: METEORA_EVENT_AUTHORITY, isSigner: false, isWritable: false },
|
|
1029
|
+
{ pubkey: METEORA_DLMM_PROGRAM, isSigner: false, isWritable: false },
|
|
1030
|
+
{ pubkey: ownerFee, isSigner: false, isWritable: true },
|
|
1031
|
+
...binArrays.map(binArray => ({ pubkey: binArray, isSigner: false, isWritable: true })),
|
|
1032
|
+
// Transfer hook accounts (if any)
|
|
1033
|
+
...((_c = remainingAccountsInfo === null || remainingAccountsInfo === void 0 ? void 0 : remainingAccountsInfo.accounts) !== null && _c !== void 0 ? _c : []),
|
|
1034
|
+
],
|
|
1035
|
+
programId: addresses_1.IYF_EXTENSION,
|
|
1036
|
+
})
|
|
723
1037
|
});
|
|
724
1038
|
});
|
|
725
1039
|
}
|
|
@@ -824,6 +1138,125 @@ class MeteoraDlmmIxGenerator {
|
|
|
824
1138
|
});
|
|
825
1139
|
});
|
|
826
1140
|
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Add liquidity to an existing Meteora DLMM position using strategy parameters.
|
|
1143
|
+
* This is the automation version that uses V2 execution (meteora_dlmm_deposit_2_automation).
|
|
1144
|
+
*
|
|
1145
|
+
* Key differences from depositAutomation:
|
|
1146
|
+
* - Uses iyfExtensionExecuteV2 with Anchor-based instruction building
|
|
1147
|
+
* - Supports remainingAccountsInfo for Token2022 transfer hooks
|
|
1148
|
+
* - Authority is HS_AUTHORITY (automation wallet)
|
|
1149
|
+
* - Does not require binArrayLower/binArrayUpper (bin arrays are auto-derived or created separately)
|
|
1150
|
+
*
|
|
1151
|
+
* @param connection - Solana connection
|
|
1152
|
+
* @param params - AddLiquidityByStrategy2AutomationParams parameters
|
|
1153
|
+
* @returns TransactionInstruction for adding liquidity
|
|
1154
|
+
*/
|
|
1155
|
+
addLiquidityByStrategy2Automation(connection, params) {
|
|
1156
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1157
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1158
|
+
// Initialize anchor
|
|
1159
|
+
anchor_1.Anchor.initialize(connection);
|
|
1160
|
+
// Derive reserves from the ACTUAL lbPair (not the one passed in, which may be incorrect)
|
|
1161
|
+
const actualReserveX = this.pda.meteora.deriveReserve(params.tokenXMint, params.lbPair);
|
|
1162
|
+
const actualReserveY = this.pda.meteora.deriveReserve(params.tokenYMint, params.lbPair);
|
|
1163
|
+
// Derive bin array bitmap extension from actual lb_pair and check if it exists
|
|
1164
|
+
const derivedBinArrayBitmapExtension = this.pda.meteora.deriveBinArrayBitmapExtension(params.lbPair);
|
|
1165
|
+
const binArrayBitmapExtensionInfo = yield connection.getAccountInfo(derivedBinArrayBitmapExtension);
|
|
1166
|
+
const actualBinArrayBitmapExtension = binArrayBitmapExtensionInfo
|
|
1167
|
+
? derivedBinArrayBitmapExtension
|
|
1168
|
+
: METEORA_DLMM_PROGRAM;
|
|
1169
|
+
const userPda = (0, functions_1.generateUserPda)(params.userWallet);
|
|
1170
|
+
// Determine user token accounts based on pdaTokenType
|
|
1171
|
+
let userTokenX;
|
|
1172
|
+
let userTokenY;
|
|
1173
|
+
if (params.pdaTokenType === types_1.TokenType.LTA) {
|
|
1174
|
+
userTokenX = (0, functions_1.generateLimitToken)(userPda, params.tokenXMint);
|
|
1175
|
+
userTokenY = (0, functions_1.generateLimitToken)(userPda, params.tokenYMint);
|
|
1176
|
+
}
|
|
1177
|
+
else if (params.pdaTokenType === types_1.TokenType.STA) {
|
|
1178
|
+
userTokenX = (0, functions_1.generateUserPdaStorageAccount)(userPda, params.tokenXMint);
|
|
1179
|
+
userTokenY = (0, functions_1.generateUserPdaStorageAccount)(userPda, params.tokenYMint);
|
|
1180
|
+
}
|
|
1181
|
+
else {
|
|
1182
|
+
// Default: ATA
|
|
1183
|
+
userTokenX = (0, functions_1.generateAta)(userPda, params.tokenXMint, params.tokenXProgram);
|
|
1184
|
+
userTokenY = (0, functions_1.generateAta)(userPda, params.tokenYMint, params.tokenYProgram);
|
|
1185
|
+
}
|
|
1186
|
+
// Serialize RemainingAccountsInfo as Vec<u8> (Borsh format)
|
|
1187
|
+
// This is passed directly to the on-chain instruction which forwards it to Meteora
|
|
1188
|
+
// For SPL tokens (non-Token2022), we still need to provide the slices structure with length=0
|
|
1189
|
+
// This matches what Meteora SDK's getPotentialToken2022IxDataAndAccounts returns
|
|
1190
|
+
// AccountsType enum: 0=TransferHookX, 1=TransferHookY, 2=TransferHookReward
|
|
1191
|
+
const defaultSlices = [
|
|
1192
|
+
{ accountsType: 0, length: 0 }, // TransferHookX with 0 accounts
|
|
1193
|
+
{ accountsType: 1, length: 0 }, // TransferHookY with 0 accounts
|
|
1194
|
+
];
|
|
1195
|
+
const remainingAccountsInfoSerialized = this.serializeRemainingAccountsInfo({
|
|
1196
|
+
slices: (_b = (_a = params.remainingAccountsInfo) === null || _a === void 0 ? void 0 : _a.slices) !== null && _b !== void 0 ? _b : defaultSlices,
|
|
1197
|
+
});
|
|
1198
|
+
// Use strategy parameters directly as absolute bin IDs
|
|
1199
|
+
// strategyParametersMinBinId and strategyParametersMaxBinId are ABSOLUTE bin IDs, not deltas from activeId
|
|
1200
|
+
const lowerBinId = params.strategyParametersMinBinId;
|
|
1201
|
+
const upperBinId = params.strategyParametersMaxBinId;
|
|
1202
|
+
// Derive bin arrays needed for the deposit range using the lbPair from position
|
|
1203
|
+
const binArrays = meteora_1.MeteoraFunctions.findMeteoraTickArrays(params.lbPair, lowerBinId, upperBinId);
|
|
1204
|
+
const binArrayAccounts = binArrays.map(binArray => ({
|
|
1205
|
+
pubkey: binArray,
|
|
1206
|
+
isSigner: false,
|
|
1207
|
+
isWritable: true,
|
|
1208
|
+
}));
|
|
1209
|
+
// Build remaining accounts: Token2022 transfer hook accounts first (described by remainingAccountsInfo),
|
|
1210
|
+
// then bin arrays (not described - Meteora expects them at the end after transfer hooks)
|
|
1211
|
+
const remainingAccounts = [
|
|
1212
|
+
...((_d = (_c = params.remainingAccountsInfo) === null || _c === void 0 ? void 0 : _c.accounts) !== null && _d !== void 0 ? _d : []),
|
|
1213
|
+
...binArrayAccounts,
|
|
1214
|
+
];
|
|
1215
|
+
console.log('remainingAccounts', remainingAccounts);
|
|
1216
|
+
// Use Anchor to serialize the instruction (ensures proper Borsh serialization)
|
|
1217
|
+
// @ts-ignore
|
|
1218
|
+
const depositIx = yield anchor_1.Anchor.instance().iyfExtension.methods
|
|
1219
|
+
.meteoraDlmmDeposit2Automation((_e = params.userTokenXAmount) !== null && _e !== void 0 ? _e : null, // Option<u64>
|
|
1220
|
+
(_f = params.userTokenYAmount) !== null && _f !== void 0 ? _f : null, // Option<u64>
|
|
1221
|
+
params.activeId, params.maxActiveBinSlippage, params.strategyParametersMinBinId, params.strategyParametersMaxBinId, params.strategyParametersStrategyType, params.strategyParametersParameters, Buffer.from(remainingAccountsInfoSerialized))
|
|
1222
|
+
.accounts({
|
|
1223
|
+
userPda,
|
|
1224
|
+
hawksightAuthority: addresses_1.HS_AUTHORITY,
|
|
1225
|
+
position: params.position,
|
|
1226
|
+
lbPair: params.lbPair,
|
|
1227
|
+
binArrayBitmapExtension: actualBinArrayBitmapExtension,
|
|
1228
|
+
userTokenX,
|
|
1229
|
+
userTokenY,
|
|
1230
|
+
reserveX: actualReserveX,
|
|
1231
|
+
reserveY: actualReserveY,
|
|
1232
|
+
tokenXMint: params.tokenXMint,
|
|
1233
|
+
tokenYMint: params.tokenYMint,
|
|
1234
|
+
tokenXProgram: params.tokenXProgram,
|
|
1235
|
+
tokenYProgram: params.tokenYProgram,
|
|
1236
|
+
eventAuthority: METEORA_EVENT_AUTHORITY,
|
|
1237
|
+
meteoraDlmmProgram: METEORA_DLMM_PROGRAM,
|
|
1238
|
+
memoProgram: addresses_1.MEMO_PROGRAM,
|
|
1239
|
+
})
|
|
1240
|
+
.remainingAccounts(remainingAccounts)
|
|
1241
|
+
.instruction();
|
|
1242
|
+
// Override sighash: Anchor's TypeScript client generates a different sighash than what
|
|
1243
|
+
// the on-chain program expects. We need to manually set the correct sighash.
|
|
1244
|
+
const sighash = util.sighash("meteora_dlmm_deposit_2_automation");
|
|
1245
|
+
depositIx.data.set(sighash, 0);
|
|
1246
|
+
// Generate instruction via IYF Main ExecuteV2
|
|
1247
|
+
// @ts-ignore
|
|
1248
|
+
const ix = yield anchor_1.Anchor.instance().iyfMain.methods
|
|
1249
|
+
.iyfExtensionExecuteV2(depositIx.data)
|
|
1250
|
+
.accounts({
|
|
1251
|
+
userPda,
|
|
1252
|
+
authority: addresses_1.HS_AUTHORITY,
|
|
1253
|
+
iyfExtensionProgram: addresses_1.IYF_EXTENSION,
|
|
1254
|
+
})
|
|
1255
|
+
.remainingAccounts(depositIx.keys.slice(2))
|
|
1256
|
+
.instruction();
|
|
1257
|
+
return ix;
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
827
1260
|
oneSideDeposit(connection, params) {
|
|
828
1261
|
return __awaiter(this, void 0, void 0, function* () {
|
|
829
1262
|
// Initialize anchor
|
|
@@ -857,6 +1290,43 @@ class MeteoraDlmmIxGenerator {
|
|
|
857
1290
|
});
|
|
858
1291
|
});
|
|
859
1292
|
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Close an empty Meteora DLMM position via IYF Extension for automation.
|
|
1295
|
+
*
|
|
1296
|
+
* This is the automation version that uses HS_AUTHORITY as the signer.
|
|
1297
|
+
*
|
|
1298
|
+
* @param params - ClosePositionIfEmptyAutomationParams parameters
|
|
1299
|
+
* @returns TransactionInstruction for the close_position_if_empty automation operation
|
|
1300
|
+
*/
|
|
1301
|
+
closePosition2Automation(_a) {
|
|
1302
|
+
return __awaiter(this, arguments, void 0, function* ({ connection, userWallet, position, lbPair, useFuelAccount, }) {
|
|
1303
|
+
// Initialize Anchor
|
|
1304
|
+
anchor_1.Anchor.initialize(connection);
|
|
1305
|
+
// Generate user PDA
|
|
1306
|
+
const userPda = (0, functions_1.generateUserPda)(userWallet);
|
|
1307
|
+
// Optional fuel account - use userPda as placeholder if not using fuel account
|
|
1308
|
+
// (userPda is already writable, while System Program cannot be writable)
|
|
1309
|
+
const fuelAccount = useFuelAccount ? (0, functions_1.generateFuelAccount)(userWallet) : userPda;
|
|
1310
|
+
// Generate instruction via IYF Extension
|
|
1311
|
+
return this.ix.iyfMain.iyfExtensionExecuteV2(connection, {
|
|
1312
|
+
userPda,
|
|
1313
|
+
authority: addresses_1.HS_AUTHORITY,
|
|
1314
|
+
ix: new web3.TransactionInstruction({
|
|
1315
|
+
data: Buffer.from(util.sighash("meteora_dlmm_close_position_automation_v2", undefined, true)),
|
|
1316
|
+
keys: [
|
|
1317
|
+
{ pubkey: userPda, isSigner: false, isWritable: false },
|
|
1318
|
+
{ pubkey: addresses_1.HS_AUTHORITY, isSigner: true, isWritable: true },
|
|
1319
|
+
{ pubkey: position, isSigner: false, isWritable: true },
|
|
1320
|
+
{ pubkey: lbPair, isSigner: false, isWritable: true },
|
|
1321
|
+
{ pubkey: METEORA_EVENT_AUTHORITY, isSigner: false, isWritable: false },
|
|
1322
|
+
{ pubkey: METEORA_DLMM_PROGRAM, isSigner: false, isWritable: false },
|
|
1323
|
+
{ pubkey: fuelAccount, isSigner: false, isWritable: true },
|
|
1324
|
+
],
|
|
1325
|
+
programId: addresses_1.IYF_EXTENSION,
|
|
1326
|
+
})
|
|
1327
|
+
});
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
860
1330
|
limitCloseAutomation(connection, params) {
|
|
861
1331
|
return __awaiter(this, void 0, void 0, function* () {
|
|
862
1332
|
// Initialize anchor
|
|
@@ -1269,6 +1739,43 @@ class MeteoraDlmmIxGenerator {
|
|
|
1269
1739
|
});
|
|
1270
1740
|
});
|
|
1271
1741
|
}
|
|
1742
|
+
increasePositionLengthAutomation(_a) {
|
|
1743
|
+
return __awaiter(this, arguments, void 0, function* ({ connection, userWallet, lbPair, position, lengthToAdd, side, useFuelAccount }) {
|
|
1744
|
+
// Initialize anchor
|
|
1745
|
+
anchor_1.Anchor.initialize(connection);
|
|
1746
|
+
// Generate user PDA
|
|
1747
|
+
const userPda = (0, functions_1.generateUserPda)(userWallet);
|
|
1748
|
+
// Build instruction data: sighash + lengthToAdd (u16) + side (u8)
|
|
1749
|
+
const lengthToAddBuffer = Buffer.alloc(2);
|
|
1750
|
+
lengthToAddBuffer.writeUInt16LE(lengthToAdd, 0);
|
|
1751
|
+
const sideBuffer = Buffer.alloc(1);
|
|
1752
|
+
sideBuffer.writeUInt8(side, 0);
|
|
1753
|
+
const fuelAccount = useFuelAccount ? (0, functions_1.generateFuelAccount)(userWallet) : web3.SystemProgram.programId;
|
|
1754
|
+
// Generate instruction
|
|
1755
|
+
return this.ix.iyfMain.iyfExtensionExecuteV2(connection, {
|
|
1756
|
+
userPda,
|
|
1757
|
+
authority: addresses_1.HS_AUTHORITY,
|
|
1758
|
+
ix: new web3.TransactionInstruction({
|
|
1759
|
+
data: Buffer.concat([
|
|
1760
|
+
Buffer.from(util.sighash("meteora_dlmm_increase_position_length_automation")),
|
|
1761
|
+
lengthToAddBuffer,
|
|
1762
|
+
sideBuffer,
|
|
1763
|
+
]),
|
|
1764
|
+
keys: [
|
|
1765
|
+
{ pubkey: userPda, isSigner: false, isWritable: false },
|
|
1766
|
+
{ pubkey: addresses_1.HS_AUTHORITY, isSigner: true, isWritable: true },
|
|
1767
|
+
{ pubkey: lbPair, isSigner: false, isWritable: false },
|
|
1768
|
+
{ pubkey: position, isSigner: false, isWritable: true },
|
|
1769
|
+
{ pubkey: METEORA_EVENT_AUTHORITY, isSigner: false, isWritable: false },
|
|
1770
|
+
{ pubkey: web3.SystemProgram.programId, isSigner: false, isWritable: false },
|
|
1771
|
+
{ pubkey: METEORA_DLMM_PROGRAM, isSigner: false, isWritable: false },
|
|
1772
|
+
{ pubkey: fuelAccount, isSigner: false, isWritable: useFuelAccount !== null && useFuelAccount !== void 0 ? useFuelAccount : false },
|
|
1773
|
+
],
|
|
1774
|
+
programId: addresses_1.IYF_EXTENSION,
|
|
1775
|
+
})
|
|
1776
|
+
});
|
|
1777
|
+
});
|
|
1778
|
+
}
|
|
1272
1779
|
/**
|
|
1273
1780
|
* Create a Meteora DLMM rebalance_liquidity instruction via IYF Main's meteora dynamic CPI.
|
|
1274
1781
|
*
|
|
@@ -1460,13 +1967,20 @@ class MeteoraDlmmIxGenerator {
|
|
|
1460
1967
|
}
|
|
1461
1968
|
/**
|
|
1462
1969
|
* Serialize RemainingAccountsInfo to match Rust struct layout
|
|
1970
|
+
*
|
|
1971
|
+
* The format is a Borsh Vec of AccountsTypeSlice:
|
|
1972
|
+
* - [slices_count: u32] - number of slices
|
|
1973
|
+
* - For each slice: [accountsType: u8 (or u8+u8 for TransferHookMultiReward)][length: u8]
|
|
1974
|
+
*
|
|
1975
|
+
* This is passed directly to Anchor methods which wrap it in another Vec<u8>.
|
|
1463
1976
|
*/
|
|
1464
1977
|
serializeRemainingAccountsInfo(info) {
|
|
1465
1978
|
const buffers = [];
|
|
1466
|
-
// Vec length (u32)
|
|
1979
|
+
// Vec length (u32) - number of slices
|
|
1467
1980
|
const lenBuf = Buffer.alloc(4);
|
|
1468
1981
|
lenBuf.writeUInt32LE(info.slices.length, 0);
|
|
1469
1982
|
buffers.push(lenBuf);
|
|
1983
|
+
// Serialize each slice
|
|
1470
1984
|
for (const slice of info.slices) {
|
|
1471
1985
|
// AccountsType enum (varies in size)
|
|
1472
1986
|
if (slice.accountsType === 3 && slice.multiRewardIndex !== undefined) {
|
|
@@ -1651,5 +2165,101 @@ class MeteoraDlmmIxGenerator {
|
|
|
1651
2165
|
});
|
|
1652
2166
|
});
|
|
1653
2167
|
}
|
|
2168
|
+
/**
|
|
2169
|
+
* Remove liquidity from a bin range in a Meteora DLMM position via IYF Extension for automation.
|
|
2170
|
+
*
|
|
2171
|
+
* This is the automation version that uses HS_AUTHORITY as the signer.
|
|
2172
|
+
* Supports larger bin ranges (not limited to 70-bin chunks).
|
|
2173
|
+
*
|
|
2174
|
+
* @param params - RemoveLiquidityByRange2AutomationParams parameters
|
|
2175
|
+
* @returns TransactionInstruction for the remove_liquidity_by_range2 automation operation
|
|
2176
|
+
*/
|
|
2177
|
+
removeLiquidityByRange2Automation(_a) {
|
|
2178
|
+
return __awaiter(this, arguments, void 0, function* ({ connection, userWallet, lbPair, position, tokenXMint, tokenYMint, tokenXProgram, tokenYProgram, fromBinId, toBinId, bpsToRemove, pdaTokenType, remainingAccountsInfo, }) {
|
|
2179
|
+
var _b, _c;
|
|
2180
|
+
// Initialize Anchor
|
|
2181
|
+
anchor_1.Anchor.initialize(connection);
|
|
2182
|
+
// Generate user PDA
|
|
2183
|
+
const userPda = (0, functions_1.generateUserPda)(userWallet);
|
|
2184
|
+
// Generate user token accounts based on pdaTokenType
|
|
2185
|
+
let userTokenX;
|
|
2186
|
+
let userTokenY;
|
|
2187
|
+
if (pdaTokenType === types_1.TokenType.LTA) {
|
|
2188
|
+
userTokenX = (0, functions_1.generateLimitToken)(userPda, tokenXMint);
|
|
2189
|
+
userTokenY = (0, functions_1.generateLimitToken)(userPda, tokenYMint);
|
|
2190
|
+
}
|
|
2191
|
+
else if (pdaTokenType === types_1.TokenType.STA) {
|
|
2192
|
+
userTokenX = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenXMint);
|
|
2193
|
+
userTokenY = (0, functions_1.generateUserPdaStorageAccount)(userPda, tokenYMint);
|
|
2194
|
+
}
|
|
2195
|
+
else {
|
|
2196
|
+
// Default: ATA
|
|
2197
|
+
userTokenX = (0, functions_1.generateAta)(userPda, tokenXMint, tokenXProgram);
|
|
2198
|
+
userTokenY = (0, functions_1.generateAta)(userPda, tokenYMint, tokenYProgram);
|
|
2199
|
+
}
|
|
2200
|
+
// Derive bin array bitmap extension (use program ID as placeholder if not needed)
|
|
2201
|
+
const binArrayBitmapExtension = METEORA_DLMM_PROGRAM;
|
|
2202
|
+
// Derive reserves
|
|
2203
|
+
const reserveX = this.pda.meteora.deriveReserve(tokenXMint, lbPair);
|
|
2204
|
+
const reserveY = this.pda.meteora.deriveReserve(tokenYMint, lbPair);
|
|
2205
|
+
// Derive bin arrays for the range
|
|
2206
|
+
const binArrays = this.pda.meteora.deriveBinArrays(lbPair, fromBinId, toBinId);
|
|
2207
|
+
// Build instruction data: fromBinId(i32) + toBinId(i32) + bpsToRemove(u16) + remainingAccountsInfo
|
|
2208
|
+
const fromBinIdBuffer = Buffer.alloc(4);
|
|
2209
|
+
fromBinIdBuffer.writeInt32LE(fromBinId, 0);
|
|
2210
|
+
const toBinIdBuffer = Buffer.alloc(4);
|
|
2211
|
+
toBinIdBuffer.writeInt32LE(toBinId, 0);
|
|
2212
|
+
const bpsToRemoveBuffer = Buffer.alloc(2);
|
|
2213
|
+
bpsToRemoveBuffer.writeUInt16LE(bpsToRemove, 0);
|
|
2214
|
+
// Serialize RemainingAccountsInfo
|
|
2215
|
+
const remainingAccountsInfoSerialized = this.serializeRemainingAccountsInfo({
|
|
2216
|
+
slices: (_b = remainingAccountsInfo === null || remainingAccountsInfo === void 0 ? void 0 : remainingAccountsInfo.slices) !== null && _b !== void 0 ? _b : [],
|
|
2217
|
+
});
|
|
2218
|
+
const instructionData = Buffer.concat([
|
|
2219
|
+
fromBinIdBuffer,
|
|
2220
|
+
toBinIdBuffer,
|
|
2221
|
+
bpsToRemoveBuffer,
|
|
2222
|
+
remainingAccountsInfoSerialized,
|
|
2223
|
+
]);
|
|
2224
|
+
// For Anchor Vec<u8> parameter, we need to prepend the length as u32 LE
|
|
2225
|
+
const instructionDataVec = Buffer.alloc(4 + instructionData.length);
|
|
2226
|
+
instructionDataVec.writeUInt32LE(instructionData.length, 0);
|
|
2227
|
+
instructionData.copy(instructionDataVec, 4);
|
|
2228
|
+
// Generate instruction via IYF Extension
|
|
2229
|
+
return this.ix.iyfMain.iyfExtensionExecuteV2(connection, {
|
|
2230
|
+
userPda,
|
|
2231
|
+
authority: addresses_1.HS_AUTHORITY,
|
|
2232
|
+
ix: new web3.TransactionInstruction({
|
|
2233
|
+
data: Buffer.concat([
|
|
2234
|
+
Buffer.from(util.sighash("meteora_dlmm_withdraw_2_automation")),
|
|
2235
|
+
instructionDataVec,
|
|
2236
|
+
]),
|
|
2237
|
+
keys: [
|
|
2238
|
+
{ pubkey: userPda, isSigner: false, isWritable: false },
|
|
2239
|
+
{ pubkey: addresses_1.HS_AUTHORITY, isSigner: true, isWritable: true },
|
|
2240
|
+
{ pubkey: position, isSigner: false, isWritable: true },
|
|
2241
|
+
{ pubkey: lbPair, isSigner: false, isWritable: true },
|
|
2242
|
+
{ pubkey: binArrayBitmapExtension, isSigner: false, isWritable: true },
|
|
2243
|
+
{ pubkey: userTokenX, isSigner: false, isWritable: true },
|
|
2244
|
+
{ pubkey: userTokenY, isSigner: false, isWritable: true },
|
|
2245
|
+
{ pubkey: reserveX, isSigner: false, isWritable: true },
|
|
2246
|
+
{ pubkey: reserveY, isSigner: false, isWritable: true },
|
|
2247
|
+
{ pubkey: tokenXMint, isSigner: false, isWritable: false },
|
|
2248
|
+
{ pubkey: tokenYMint, isSigner: false, isWritable: false },
|
|
2249
|
+
{ pubkey: tokenXProgram, isSigner: false, isWritable: false },
|
|
2250
|
+
{ pubkey: tokenYProgram, isSigner: false, isWritable: false },
|
|
2251
|
+
{ pubkey: METEORA_EVENT_AUTHORITY, isSigner: false, isWritable: false },
|
|
2252
|
+
{ pubkey: METEORA_DLMM_PROGRAM, isSigner: false, isWritable: false },
|
|
2253
|
+
{ pubkey: addresses_1.MEMO_PROGRAM, isSigner: false, isWritable: false },
|
|
2254
|
+
// Bin arrays as remaining accounts
|
|
2255
|
+
...binArrays.map(pubkey => ({ pubkey, isSigner: false, isWritable: true })),
|
|
2256
|
+
// Transfer hook accounts (if any)
|
|
2257
|
+
...((_c = remainingAccountsInfo === null || remainingAccountsInfo === void 0 ? void 0 : remainingAccountsInfo.accounts) !== null && _c !== void 0 ? _c : []),
|
|
2258
|
+
],
|
|
2259
|
+
programId: addresses_1.IYF_EXTENSION,
|
|
2260
|
+
})
|
|
2261
|
+
});
|
|
2262
|
+
});
|
|
2263
|
+
}
|
|
1654
2264
|
}
|
|
1655
2265
|
exports.MeteoraDlmmIxGenerator = MeteoraDlmmIxGenerator;
|