@meteora-ag/zap-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/dist/index.d.mts +381 -0
- package/dist/index.d.ts +381 -0
- package/dist/index.js +1055 -0
- package/dist/index.mjs +1022 -0
- package/package.json +49 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1022 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var __async = (__this, __arguments, generator) => {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
var fulfilled = (value) => {
|
|
23
|
+
try {
|
|
24
|
+
step(generator.next(value));
|
|
25
|
+
} catch (e) {
|
|
26
|
+
reject(e);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var rejected = (value) => {
|
|
30
|
+
try {
|
|
31
|
+
step(generator.throw(value));
|
|
32
|
+
} catch (e) {
|
|
33
|
+
reject(e);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
37
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// src/zap.ts
|
|
42
|
+
import { PublicKey as PublicKey7 } from "@solana/web3.js";
|
|
43
|
+
import { BN as BN3, Program } from "@coral-xyz/anchor";
|
|
44
|
+
|
|
45
|
+
// src/idl/zap/idl.json
|
|
46
|
+
var idl_default = {
|
|
47
|
+
address: "zapvX9M3uf5pvy4wRPAbQgdQsM1xmuiFnkfHKPvwMiz",
|
|
48
|
+
metadata: {
|
|
49
|
+
name: "zap",
|
|
50
|
+
version: "0.1.0",
|
|
51
|
+
spec: "0.1.0",
|
|
52
|
+
description: "Created with Anchor"
|
|
53
|
+
},
|
|
54
|
+
instructions: [
|
|
55
|
+
{
|
|
56
|
+
name: "zap_out",
|
|
57
|
+
discriminator: [
|
|
58
|
+
155,
|
|
59
|
+
108,
|
|
60
|
+
185,
|
|
61
|
+
112,
|
|
62
|
+
104,
|
|
63
|
+
210,
|
|
64
|
+
161,
|
|
65
|
+
64
|
|
66
|
+
],
|
|
67
|
+
accounts: [
|
|
68
|
+
{
|
|
69
|
+
name: "user_token_in_account",
|
|
70
|
+
writable: true
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "amm_program"
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
args: [
|
|
77
|
+
{
|
|
78
|
+
name: "params",
|
|
79
|
+
type: {
|
|
80
|
+
defined: {
|
|
81
|
+
name: "ZapOutParameters"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
errors: [
|
|
89
|
+
{
|
|
90
|
+
code: 6e3,
|
|
91
|
+
name: "MathOverflow",
|
|
92
|
+
msg: "Math operation overflow"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
code: 6001,
|
|
96
|
+
name: "InvalidOffset",
|
|
97
|
+
msg: "Invalid offset"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
code: 6002,
|
|
101
|
+
name: "InvalidZapOutParameters",
|
|
102
|
+
msg: "Math operation overflow"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
code: 6003,
|
|
106
|
+
name: "TypeCastFailed",
|
|
107
|
+
msg: "Type cast error"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
code: 6004,
|
|
111
|
+
name: "AmmIsNotSupported",
|
|
112
|
+
msg: "Amm program is not supported"
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
types: [
|
|
116
|
+
{
|
|
117
|
+
name: "ZapOutParameters",
|
|
118
|
+
type: {
|
|
119
|
+
kind: "struct",
|
|
120
|
+
fields: [
|
|
121
|
+
{
|
|
122
|
+
name: "percentage",
|
|
123
|
+
type: "u8"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "offset_amount_in",
|
|
127
|
+
type: "u16"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "pre_user_token_balance",
|
|
131
|
+
type: "u64"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: "max_swap_amount",
|
|
135
|
+
type: "u64"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "payload_data",
|
|
139
|
+
type: "bytes"
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// src/helpers/jupiter.ts
|
|
148
|
+
function getJupiterQuote(inputMint, outputMint, amount, maxAccounts, slippageBps, onlyDirectRoutes, restrictIntermediateTokens, apiUrl = "https://lite-api.jup.ag", apiKey) {
|
|
149
|
+
return __async(this, null, function* () {
|
|
150
|
+
const params = new URLSearchParams({
|
|
151
|
+
inputMint: inputMint.toString(),
|
|
152
|
+
outputMint: outputMint.toString(),
|
|
153
|
+
amount: amount.toString(),
|
|
154
|
+
slippageBps: slippageBps.toString(),
|
|
155
|
+
maxAccounts: maxAccounts.toString(),
|
|
156
|
+
onlyDirectRoutes: onlyDirectRoutes.toString(),
|
|
157
|
+
restrictIntermediateTokens: restrictIntermediateTokens.toString()
|
|
158
|
+
});
|
|
159
|
+
const url = `${apiUrl}/swap/v1/quote?${params.toString()}`;
|
|
160
|
+
console.log(url);
|
|
161
|
+
const response = yield fetch(url, {
|
|
162
|
+
method: "GET",
|
|
163
|
+
headers: __spreadValues({
|
|
164
|
+
Accept: "application/json"
|
|
165
|
+
}, apiKey ? { "x-api-key": apiKey } : {})
|
|
166
|
+
});
|
|
167
|
+
if (!response.ok) {
|
|
168
|
+
const errorText = yield response.text();
|
|
169
|
+
throw new Error(`Jupiter quote failed (${response.status}): ${errorText}`);
|
|
170
|
+
}
|
|
171
|
+
const result = yield response.json();
|
|
172
|
+
return result;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function getJupiterSwapInstruction(userPublicKey, quoteResponse, apiUrl = "https://lite-api.jup.ag", apiKey) {
|
|
176
|
+
return __async(this, null, function* () {
|
|
177
|
+
const url = `${apiUrl}/swap/v1/swap-instructions`;
|
|
178
|
+
const requestBody = {
|
|
179
|
+
userPublicKey: userPublicKey.toString(),
|
|
180
|
+
quoteResponse
|
|
181
|
+
};
|
|
182
|
+
const response = yield fetch(url, {
|
|
183
|
+
method: "POST",
|
|
184
|
+
headers: __spreadValues({
|
|
185
|
+
"Content-Type": "application/json",
|
|
186
|
+
Accept: "application/json"
|
|
187
|
+
}, apiKey ? { "x-api-key": apiKey } : {}),
|
|
188
|
+
body: JSON.stringify(requestBody)
|
|
189
|
+
});
|
|
190
|
+
if (!response.ok) {
|
|
191
|
+
const errorText = yield response.text();
|
|
192
|
+
throw new Error(
|
|
193
|
+
`Jupiter swap instruction failed (${response.status}): ${errorText}`
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
const result = yield response.json();
|
|
197
|
+
return result;
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// src/helpers/dammV2.ts
|
|
202
|
+
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
|
203
|
+
|
|
204
|
+
// src/constants.ts
|
|
205
|
+
import { PublicKey } from "@solana/web3.js";
|
|
206
|
+
import BN from "bn.js";
|
|
207
|
+
import {
|
|
208
|
+
BIN_ARRAY_BITMAP_SIZE,
|
|
209
|
+
EXTENSION_BINARRAY_BITMAP_SIZE
|
|
210
|
+
} from "@meteora-ag/dlmm";
|
|
211
|
+
var ZAP_PROGRAM_ID = new PublicKey(idl_default.address);
|
|
212
|
+
var JUP_V6_PROGRAM_ID = new PublicKey(
|
|
213
|
+
"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"
|
|
214
|
+
);
|
|
215
|
+
var DAMM_V2_PROGRAM_ID = new PublicKey(
|
|
216
|
+
"cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG"
|
|
217
|
+
);
|
|
218
|
+
var DLMM_PROGRAM_ID = new PublicKey(
|
|
219
|
+
"LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo"
|
|
220
|
+
);
|
|
221
|
+
var MEMO_PROGRAM_ID = new PublicKey(
|
|
222
|
+
"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"
|
|
223
|
+
);
|
|
224
|
+
var BIN_ARRAY_INDEX_BOUND = [
|
|
225
|
+
BIN_ARRAY_BITMAP_SIZE.mul(
|
|
226
|
+
EXTENSION_BINARRAY_BITMAP_SIZE.add(new BN(1))
|
|
227
|
+
).neg(),
|
|
228
|
+
BIN_ARRAY_BITMAP_SIZE.mul(EXTENSION_BINARRAY_BITMAP_SIZE.add(new BN(1))).sub(
|
|
229
|
+
new BN(1)
|
|
230
|
+
)
|
|
231
|
+
];
|
|
232
|
+
var AccountsType = {
|
|
233
|
+
TransferHookX: {
|
|
234
|
+
transferHookX: {}
|
|
235
|
+
},
|
|
236
|
+
TransferHookY: {
|
|
237
|
+
transferHookY: {}
|
|
238
|
+
},
|
|
239
|
+
TransferHookReward: {
|
|
240
|
+
transferHookReward: {}
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
var DLMM_SWAP_DISCRIMINATOR = [65, 75, 63, 76, 235, 91, 91, 136];
|
|
244
|
+
var AMOUNT_IN_DLMM_OFFSET = 8;
|
|
245
|
+
var AMOUNT_IN_JUP_V6_REVERSE_OFFSET = 19;
|
|
246
|
+
var AMOUNT_IN_DAMM_V2_OFFSET = 8;
|
|
247
|
+
var DAMM_V2_SWAP_DISCRIMINATOR = [
|
|
248
|
+
248,
|
|
249
|
+
198,
|
|
250
|
+
158,
|
|
251
|
+
145,
|
|
252
|
+
225,
|
|
253
|
+
117,
|
|
254
|
+
135,
|
|
255
|
+
200
|
|
256
|
+
];
|
|
257
|
+
|
|
258
|
+
// src/helpers/dammV2.ts
|
|
259
|
+
import { CpAmm, derivePoolAuthority } from "@meteora-ag/cp-amm-sdk";
|
|
260
|
+
|
|
261
|
+
// src/helpers/pda.ts
|
|
262
|
+
import { PublicKey as PublicKey2 } from "@solana/web3.js";
|
|
263
|
+
function deriveDammV2EventAuthority() {
|
|
264
|
+
return PublicKey2.findProgramAddressSync(
|
|
265
|
+
[Buffer.from("__event_authority")],
|
|
266
|
+
DAMM_V2_PROGRAM_ID
|
|
267
|
+
)[0];
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// src/helpers/dammV2.ts
|
|
271
|
+
function getDammV2Pool(connection, poolAddress) {
|
|
272
|
+
return __async(this, null, function* () {
|
|
273
|
+
const cpAmmClient = new CpAmm(connection);
|
|
274
|
+
return yield cpAmmClient.fetchPoolState(poolAddress);
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
function getDammV2RemainingAccounts(_0, _1, _2, _3) {
|
|
278
|
+
return __async(this, arguments, function* (poolAddress, user, userInputTokenAccount, userTokenOutAccount, tokenAProgram = TOKEN_PROGRAM_ID, tokenBProgram = TOKEN_PROGRAM_ID, poolState) {
|
|
279
|
+
const remainingAccounts = [
|
|
280
|
+
{
|
|
281
|
+
isSigner: false,
|
|
282
|
+
isWritable: false,
|
|
283
|
+
pubkey: derivePoolAuthority()
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
isSigner: false,
|
|
287
|
+
isWritable: true,
|
|
288
|
+
pubkey: poolAddress
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
isSigner: false,
|
|
292
|
+
isWritable: true,
|
|
293
|
+
pubkey: userInputTokenAccount
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
isSigner: false,
|
|
297
|
+
isWritable: true,
|
|
298
|
+
pubkey: userTokenOutAccount
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
isSigner: false,
|
|
302
|
+
isWritable: true,
|
|
303
|
+
pubkey: poolState.tokenAVault
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
isSigner: false,
|
|
307
|
+
isWritable: true,
|
|
308
|
+
pubkey: poolState.tokenBVault
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
isSigner: false,
|
|
312
|
+
isWritable: false,
|
|
313
|
+
pubkey: poolState.tokenAMint
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
isSigner: false,
|
|
317
|
+
isWritable: false,
|
|
318
|
+
pubkey: poolState.tokenBMint
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
isSigner: true,
|
|
322
|
+
isWritable: false,
|
|
323
|
+
pubkey: user
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
isSigner: false,
|
|
327
|
+
isWritable: false,
|
|
328
|
+
pubkey: tokenAProgram
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
isSigner: false,
|
|
332
|
+
isWritable: false,
|
|
333
|
+
pubkey: tokenBProgram
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
isSigner: false,
|
|
337
|
+
isWritable: false,
|
|
338
|
+
pubkey: DAMM_V2_PROGRAM_ID
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
isSigner: false,
|
|
342
|
+
isWritable: false,
|
|
343
|
+
pubkey: deriveDammV2EventAuthority()
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
isSigner: false,
|
|
347
|
+
isWritable: false,
|
|
348
|
+
pubkey: DAMM_V2_PROGRAM_ID
|
|
349
|
+
}
|
|
350
|
+
];
|
|
351
|
+
return remainingAccounts;
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
function createDammV2SwapPayload(amountIn, minimumSwapAmountOut) {
|
|
355
|
+
return Buffer.concat([
|
|
356
|
+
Buffer.from(DAMM_V2_SWAP_DISCRIMINATOR),
|
|
357
|
+
amountIn.toArrayLike(Buffer, "le", 8),
|
|
358
|
+
minimumSwapAmountOut.toArrayLike(Buffer, "le", 8)
|
|
359
|
+
]);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// src/helpers/common.ts
|
|
363
|
+
import {
|
|
364
|
+
NATIVE_MINT,
|
|
365
|
+
TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID2
|
|
366
|
+
} from "@solana/spl-token";
|
|
367
|
+
import { PublicKey as PublicKey3 } from "@solana/web3.js";
|
|
368
|
+
function getTokenProgramFromMint(connection, mint) {
|
|
369
|
+
return __async(this, null, function* () {
|
|
370
|
+
if (mint.equals(NATIVE_MINT)) {
|
|
371
|
+
return TOKEN_PROGRAM_ID2;
|
|
372
|
+
}
|
|
373
|
+
try {
|
|
374
|
+
const mintInfo = yield connection.getAccountInfo(mint);
|
|
375
|
+
if (!mintInfo) {
|
|
376
|
+
throw new Error(`Mint account not found: ${mint.toString()}`);
|
|
377
|
+
}
|
|
378
|
+
if (mintInfo.owner.equals(
|
|
379
|
+
new PublicKey3("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb")
|
|
380
|
+
)) {
|
|
381
|
+
return new PublicKey3("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");
|
|
382
|
+
} else {
|
|
383
|
+
return TOKEN_PROGRAM_ID2;
|
|
384
|
+
}
|
|
385
|
+
} catch (error) {
|
|
386
|
+
console.warn(
|
|
387
|
+
`Failed to determine token program for ${mint.toString()}, defaulting to TOKEN_PROGRAM_ID:`,
|
|
388
|
+
error
|
|
389
|
+
);
|
|
390
|
+
return TOKEN_PROGRAM_ID2;
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// src/helpers/token.ts
|
|
396
|
+
import {
|
|
397
|
+
createAssociatedTokenAccountIdempotentInstruction,
|
|
398
|
+
createCloseAccountInstruction,
|
|
399
|
+
getAccount,
|
|
400
|
+
getAssociatedTokenAddressSync,
|
|
401
|
+
NATIVE_MINT as NATIVE_MINT2,
|
|
402
|
+
TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID3,
|
|
403
|
+
TokenAccountNotFoundError,
|
|
404
|
+
TokenInvalidAccountOwnerError
|
|
405
|
+
} from "@solana/spl-token";
|
|
406
|
+
import {
|
|
407
|
+
SystemProgram,
|
|
408
|
+
TransactionInstruction
|
|
409
|
+
} from "@solana/web3.js";
|
|
410
|
+
var getOrCreateATAInstruction = (connection, tokenMint, owner, payer, allowOwnerOffCurve = true, tokenProgram) => __async(null, null, function* () {
|
|
411
|
+
const toAccount = getAssociatedTokenAddressSync(
|
|
412
|
+
tokenMint,
|
|
413
|
+
owner,
|
|
414
|
+
allowOwnerOffCurve,
|
|
415
|
+
tokenProgram
|
|
416
|
+
);
|
|
417
|
+
try {
|
|
418
|
+
yield getAccount(connection, toAccount);
|
|
419
|
+
return { ataPubkey: toAccount, ix: void 0 };
|
|
420
|
+
} catch (e) {
|
|
421
|
+
if (e instanceof TokenAccountNotFoundError || e instanceof TokenInvalidAccountOwnerError) {
|
|
422
|
+
const ix = createAssociatedTokenAccountIdempotentInstruction(
|
|
423
|
+
payer,
|
|
424
|
+
toAccount,
|
|
425
|
+
owner,
|
|
426
|
+
tokenMint,
|
|
427
|
+
tokenProgram
|
|
428
|
+
);
|
|
429
|
+
return { ataPubkey: toAccount, ix };
|
|
430
|
+
} else {
|
|
431
|
+
console.error("Error::getOrCreateATAInstruction", e);
|
|
432
|
+
throw e;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
function unwrapSOLInstruction(owner, receiver, allowOwnerOffCurve = true) {
|
|
437
|
+
const wSolATAAccount = getAssociatedTokenAddressSync(
|
|
438
|
+
NATIVE_MINT2,
|
|
439
|
+
owner,
|
|
440
|
+
allowOwnerOffCurve
|
|
441
|
+
);
|
|
442
|
+
if (wSolATAAccount) {
|
|
443
|
+
const closedWrappedSolInstruction = createCloseAccountInstruction(
|
|
444
|
+
wSolATAAccount,
|
|
445
|
+
receiver,
|
|
446
|
+
owner,
|
|
447
|
+
[],
|
|
448
|
+
TOKEN_PROGRAM_ID3
|
|
449
|
+
);
|
|
450
|
+
return closedWrappedSolInstruction;
|
|
451
|
+
}
|
|
452
|
+
return null;
|
|
453
|
+
}
|
|
454
|
+
function wrapSOLInstruction(from, to, amount, tokenProgram = TOKEN_PROGRAM_ID3) {
|
|
455
|
+
return [
|
|
456
|
+
SystemProgram.transfer({
|
|
457
|
+
fromPubkey: from,
|
|
458
|
+
toPubkey: to,
|
|
459
|
+
lamports: amount
|
|
460
|
+
}),
|
|
461
|
+
new TransactionInstruction({
|
|
462
|
+
keys: [
|
|
463
|
+
{
|
|
464
|
+
pubkey: to,
|
|
465
|
+
isSigner: false,
|
|
466
|
+
isWritable: true
|
|
467
|
+
}
|
|
468
|
+
],
|
|
469
|
+
data: Buffer.from(new Uint8Array([17])),
|
|
470
|
+
programId: tokenProgram
|
|
471
|
+
})
|
|
472
|
+
];
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// src/helpers/dlmm.ts
|
|
476
|
+
import { PublicKey as PublicKey6 } from "@solana/web3.js";
|
|
477
|
+
import BN2 from "bn.js";
|
|
478
|
+
import DLMM, {
|
|
479
|
+
isOverflowDefaultBinArrayBitmap,
|
|
480
|
+
BIN_ARRAY_BITMAP_SIZE as BIN_ARRAY_BITMAP_SIZE2,
|
|
481
|
+
createProgram,
|
|
482
|
+
deriveBinArrayBitmapExtension,
|
|
483
|
+
deriveOracle,
|
|
484
|
+
deriveEventAuthority
|
|
485
|
+
} from "@meteora-ag/dlmm";
|
|
486
|
+
|
|
487
|
+
// src/helpers/token2022.ts
|
|
488
|
+
import {
|
|
489
|
+
createTransferCheckedWithTransferHookInstruction,
|
|
490
|
+
getTransferHook,
|
|
491
|
+
TOKEN_2022_PROGRAM_ID as TOKEN_2022_PROGRAM_ID2,
|
|
492
|
+
TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID4,
|
|
493
|
+
unpackMint
|
|
494
|
+
} from "@solana/spl-token";
|
|
495
|
+
import { PublicKey as PublicKey5 } from "@solana/web3.js";
|
|
496
|
+
function getExtraAccountMetasForTransferHook(connection, mint) {
|
|
497
|
+
return __async(this, null, function* () {
|
|
498
|
+
const info = yield connection.getAccountInfo(mint);
|
|
499
|
+
if (!info) {
|
|
500
|
+
return [];
|
|
501
|
+
}
|
|
502
|
+
if (info.owner.equals(TOKEN_PROGRAM_ID4)) {
|
|
503
|
+
return [];
|
|
504
|
+
}
|
|
505
|
+
const accountInfoWithBuffer = __spreadProps(__spreadValues({}, info), {
|
|
506
|
+
data: Buffer.from(info.data)
|
|
507
|
+
});
|
|
508
|
+
const mintInfo = unpackMint(
|
|
509
|
+
mint,
|
|
510
|
+
accountInfoWithBuffer,
|
|
511
|
+
TOKEN_2022_PROGRAM_ID2
|
|
512
|
+
);
|
|
513
|
+
const transferHook = getTransferHook(mintInfo);
|
|
514
|
+
if (!transferHook) {
|
|
515
|
+
return [];
|
|
516
|
+
} else {
|
|
517
|
+
const transferWithHookIx = createTransferCheckedWithTransferHookInstruction(
|
|
518
|
+
connection,
|
|
519
|
+
PublicKey5.default,
|
|
520
|
+
mint,
|
|
521
|
+
PublicKey5.default,
|
|
522
|
+
PublicKey5.default,
|
|
523
|
+
BigInt(0),
|
|
524
|
+
mintInfo.decimals,
|
|
525
|
+
[],
|
|
526
|
+
"confirmed",
|
|
527
|
+
TOKEN_2022_PROGRAM_ID2
|
|
528
|
+
);
|
|
529
|
+
return (yield transferWithHookIx).keys.slice(4);
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// src/helpers/dlmm.ts
|
|
535
|
+
function getLbPairState(connection, lbPair) {
|
|
536
|
+
return __async(this, null, function* () {
|
|
537
|
+
const dlmmClient = yield DLMM.create(connection, lbPair, {
|
|
538
|
+
cluster: "mainnet-beta",
|
|
539
|
+
programId: new PublicKey6(DLMM_PROGRAM_ID)
|
|
540
|
+
});
|
|
541
|
+
return dlmmClient.lbPair;
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
function getBinArrayBitmapExtension(connection, binArray) {
|
|
545
|
+
return __async(this, null, function* () {
|
|
546
|
+
const program = createProgram(connection);
|
|
547
|
+
const account = yield connection.getAccountInfo(binArray);
|
|
548
|
+
if (!account) {
|
|
549
|
+
return null;
|
|
550
|
+
}
|
|
551
|
+
return program.coder.accounts.decode(
|
|
552
|
+
"binArrayBitmapExtension",
|
|
553
|
+
Buffer.from(account.data)
|
|
554
|
+
);
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
function getBitFromBinArrayIndexInBitmapExtension(binArrayIndex, state) {
|
|
558
|
+
const idx = binArrayIndex.isNeg() ? binArrayIndex.add(new BN2(1)).abs().sub(BIN_ARRAY_BITMAP_SIZE2) : binArrayIndex.sub(BIN_ARRAY_BITMAP_SIZE2);
|
|
559
|
+
const bitmapOffset = idx.div(BIN_ARRAY_BITMAP_SIZE2);
|
|
560
|
+
const bitmap = binArrayIndex.isNeg() ? state.negativeBinArrayBitmap[bitmapOffset.toNumber()] : state.positiveBinArrayBitmap[bitmapOffset.toNumber()];
|
|
561
|
+
const { div: offsetToU64InBitmap, mod: offsetToBit } = idx.divmod(new BN2(64));
|
|
562
|
+
const { mod: offsetToU64InChunkBitmap } = offsetToU64InBitmap.divmod(
|
|
563
|
+
new BN2(8)
|
|
564
|
+
);
|
|
565
|
+
if (!bitmap) {
|
|
566
|
+
console.log(binArrayIndex.toString());
|
|
567
|
+
console.log(bitmapOffset.toString());
|
|
568
|
+
}
|
|
569
|
+
const chunkedBitmap = bitmap[offsetToU64InChunkBitmap.toNumber()];
|
|
570
|
+
return chunkedBitmap.testn(offsetToBit.toNumber());
|
|
571
|
+
}
|
|
572
|
+
function getNextBinArrayIndexWithLiquidity(binArrayIndex, pairState, swapForY, state) {
|
|
573
|
+
const [minBinArrayIndex, maxBinArrayIndex] = BIN_ARRAY_INDEX_BOUND;
|
|
574
|
+
const step = swapForY ? new BN2(-1) : new BN2(1);
|
|
575
|
+
while (true) {
|
|
576
|
+
if (isOverflowDefaultBinArrayBitmap(binArrayIndex)) {
|
|
577
|
+
if (state) {
|
|
578
|
+
const isBitSet = getBitFromBinArrayIndexInBitmapExtension(
|
|
579
|
+
binArrayIndex,
|
|
580
|
+
state
|
|
581
|
+
);
|
|
582
|
+
if (isBitSet) {
|
|
583
|
+
return binArrayIndex;
|
|
584
|
+
}
|
|
585
|
+
} else {
|
|
586
|
+
break;
|
|
587
|
+
}
|
|
588
|
+
} else {
|
|
589
|
+
const actualIdx = binArrayIndex.add(BIN_ARRAY_BITMAP_SIZE2);
|
|
590
|
+
let { div: offsetInFullBitmap, mod: index } = actualIdx.divmod(
|
|
591
|
+
new BN2(64)
|
|
592
|
+
);
|
|
593
|
+
if (pairState.binArrayBitmap[offsetInFullBitmap.toNumber()].testn(
|
|
594
|
+
index.toNumber()
|
|
595
|
+
)) {
|
|
596
|
+
return binArrayIndex;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
binArrayIndex = binArrayIndex.add(step);
|
|
600
|
+
if (binArrayIndex.gt(maxBinArrayIndex) || binArrayIndex.lt(minBinArrayIndex)) {
|
|
601
|
+
break;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
606
|
+
function getDlmmRemainingAccounts(connection, lbPair, user, userInputTokenAccount, userTokenOutAccount, tokenXProgram, tokenYProgram, lbPairState) {
|
|
607
|
+
return __async(this, null, function* () {
|
|
608
|
+
let [binArrayBitmapExtension] = deriveBinArrayBitmapExtension(
|
|
609
|
+
lbPair,
|
|
610
|
+
DLMM_PROGRAM_ID
|
|
611
|
+
);
|
|
612
|
+
const binArrayBitmapExtensionState = yield connection.getAccountInfo(
|
|
613
|
+
binArrayBitmapExtension
|
|
614
|
+
);
|
|
615
|
+
if (!binArrayBitmapExtensionState) {
|
|
616
|
+
binArrayBitmapExtension = new PublicKey6(DLMM_PROGRAM_ID);
|
|
617
|
+
}
|
|
618
|
+
const transferHookXAccounts = yield getExtraAccountMetasForTransferHook(
|
|
619
|
+
connection,
|
|
620
|
+
lbPairState.tokenXMint
|
|
621
|
+
);
|
|
622
|
+
const transferHookYAccounts = yield getExtraAccountMetasForTransferHook(
|
|
623
|
+
connection,
|
|
624
|
+
lbPairState.tokenYMint
|
|
625
|
+
);
|
|
626
|
+
let remainingAccountsInfo = { slices: [] };
|
|
627
|
+
if (transferHookXAccounts.length > 0) {
|
|
628
|
+
remainingAccountsInfo.slices.push({
|
|
629
|
+
accountsType: AccountsType.TransferHookX,
|
|
630
|
+
length: transferHookXAccounts.length
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
if (transferHookYAccounts.length > 0) {
|
|
634
|
+
remainingAccountsInfo.slices.push({
|
|
635
|
+
accountsType: AccountsType.TransferHookY,
|
|
636
|
+
length: transferHookYAccounts.length
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
const [oracle] = deriveOracle(lbPair, DLMM_PROGRAM_ID);
|
|
640
|
+
const [eventAuthority] = deriveEventAuthority(DLMM_PROGRAM_ID);
|
|
641
|
+
const remainingAccounts = [
|
|
642
|
+
{
|
|
643
|
+
isSigner: false,
|
|
644
|
+
isWritable: true,
|
|
645
|
+
pubkey: lbPair
|
|
646
|
+
},
|
|
647
|
+
{
|
|
648
|
+
isSigner: false,
|
|
649
|
+
isWritable: false,
|
|
650
|
+
pubkey: binArrayBitmapExtension
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
isSigner: false,
|
|
654
|
+
isWritable: true,
|
|
655
|
+
pubkey: lbPairState.reserveX
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
isSigner: false,
|
|
659
|
+
isWritable: true,
|
|
660
|
+
pubkey: lbPairState.reserveY
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
isSigner: false,
|
|
664
|
+
isWritable: true,
|
|
665
|
+
pubkey: userInputTokenAccount
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
isSigner: false,
|
|
669
|
+
isWritable: true,
|
|
670
|
+
pubkey: userTokenOutAccount
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
isSigner: false,
|
|
674
|
+
isWritable: false,
|
|
675
|
+
pubkey: lbPairState.tokenXMint
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
isSigner: false,
|
|
679
|
+
isWritable: false,
|
|
680
|
+
pubkey: lbPairState.tokenYMint
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
isSigner: false,
|
|
684
|
+
isWritable: true,
|
|
685
|
+
pubkey: oracle
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
isSigner: false,
|
|
689
|
+
isWritable: true,
|
|
690
|
+
pubkey: new PublicKey6(DLMM_PROGRAM_ID)
|
|
691
|
+
// host fee option
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
isSigner: true,
|
|
695
|
+
isWritable: false,
|
|
696
|
+
pubkey: user
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
isSigner: false,
|
|
700
|
+
isWritable: false,
|
|
701
|
+
pubkey: tokenXProgram
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
isSigner: false,
|
|
705
|
+
isWritable: false,
|
|
706
|
+
pubkey: tokenYProgram
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
isSigner: false,
|
|
710
|
+
isWritable: false,
|
|
711
|
+
pubkey: MEMO_PROGRAM_ID
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
isSigner: false,
|
|
715
|
+
isWritable: false,
|
|
716
|
+
pubkey: eventAuthority
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
isSigner: false,
|
|
720
|
+
isWritable: false,
|
|
721
|
+
pubkey: DLMM_PROGRAM_ID
|
|
722
|
+
}
|
|
723
|
+
];
|
|
724
|
+
const dlmmClient = yield DLMM.create(connection, lbPair, {
|
|
725
|
+
cluster: "mainnet-beta",
|
|
726
|
+
programId: new PublicKey6(DLMM_PROGRAM_ID)
|
|
727
|
+
});
|
|
728
|
+
const binArrays = yield dlmmClient.getBinArrayForSwap(true, 5);
|
|
729
|
+
const binArraysAccountMeta = binArrays.map((binArray) => {
|
|
730
|
+
return {
|
|
731
|
+
isSigner: false,
|
|
732
|
+
isWritable: true,
|
|
733
|
+
pubkey: binArray.publicKey
|
|
734
|
+
};
|
|
735
|
+
});
|
|
736
|
+
remainingAccounts.push(
|
|
737
|
+
...[...transferHookXAccounts, ...transferHookYAccounts]
|
|
738
|
+
);
|
|
739
|
+
remainingAccounts.push(...binArraysAccountMeta);
|
|
740
|
+
return {
|
|
741
|
+
remainingAccounts,
|
|
742
|
+
remainingAccountsInfo
|
|
743
|
+
};
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
function convertAccountTypeToNumber(accountType) {
|
|
747
|
+
if (JSON.stringify(accountType) === JSON.stringify({ transferHookX: {} })) {
|
|
748
|
+
return 0;
|
|
749
|
+
}
|
|
750
|
+
if (JSON.stringify(accountType) === JSON.stringify({ transferHookY: {} })) {
|
|
751
|
+
return 1;
|
|
752
|
+
}
|
|
753
|
+
if (JSON.stringify(accountType) === JSON.stringify({ transferHookReward: {} })) {
|
|
754
|
+
return 2;
|
|
755
|
+
}
|
|
756
|
+
throw new Error(`Unknown account type: ${JSON.stringify(accountType)}`);
|
|
757
|
+
}
|
|
758
|
+
function createDlmmSwapPayload(amountIn, minimumSwapAmountOut, remainingAccountsInfo) {
|
|
759
|
+
const sliceCount = Buffer.alloc(4);
|
|
760
|
+
sliceCount.writeUInt32LE(remainingAccountsInfo.slices.length, 0);
|
|
761
|
+
const slicesData = Buffer.concat(
|
|
762
|
+
remainingAccountsInfo.slices.map((slice) => {
|
|
763
|
+
const sliceBuffer = Buffer.alloc(2);
|
|
764
|
+
sliceBuffer.writeUInt8(convertAccountTypeToNumber(slice.accountsType), 0);
|
|
765
|
+
sliceBuffer.writeUInt8(slice.length, 1);
|
|
766
|
+
return sliceBuffer;
|
|
767
|
+
})
|
|
768
|
+
);
|
|
769
|
+
return Buffer.concat([
|
|
770
|
+
Buffer.from(DLMM_SWAP_DISCRIMINATOR),
|
|
771
|
+
amountIn.toArrayLike(Buffer, "le", 8),
|
|
772
|
+
minimumSwapAmountOut.toArrayLike(Buffer, "le", 8),
|
|
773
|
+
sliceCount,
|
|
774
|
+
slicesData
|
|
775
|
+
]);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// src/zap.ts
|
|
779
|
+
import { getTokenProgram } from "@meteora-ag/cp-amm-sdk";
|
|
780
|
+
var Zap = class {
|
|
781
|
+
constructor(connection) {
|
|
782
|
+
this.connection = connection;
|
|
783
|
+
this.zapProgram = new Program(idl_default, { connection });
|
|
784
|
+
}
|
|
785
|
+
/////// ZAPOUT PROGRAM ///////
|
|
786
|
+
/**
|
|
787
|
+
* Executes a generic zap out operation with custom parameters.
|
|
788
|
+
*
|
|
789
|
+
* @param params - Zap out operation parameters
|
|
790
|
+
* @param params.userTokenInAccount - Token ledger account to zap out from
|
|
791
|
+
* @param params.zapOutParams - Zap out parameters
|
|
792
|
+
* @param params.remainingAccounts - Additional accounts needed for the operation
|
|
793
|
+
* @param params.ammProgram - AMM program ID to interact with
|
|
794
|
+
* @param params.preInstructions - Instructions to run before the zap out
|
|
795
|
+
* @param params.postInstructions - Instructions to run after the zap out
|
|
796
|
+
* @returns builder transaction
|
|
797
|
+
*/
|
|
798
|
+
zapOut(params) {
|
|
799
|
+
return __async(this, null, function* () {
|
|
800
|
+
const {
|
|
801
|
+
zapOutParams,
|
|
802
|
+
userTokenInAccount,
|
|
803
|
+
remainingAccounts,
|
|
804
|
+
ammProgram,
|
|
805
|
+
preInstructions,
|
|
806
|
+
postInstructions
|
|
807
|
+
} = params;
|
|
808
|
+
return this.zapProgram.methods.zapOut(zapOutParams).accountsPartial({
|
|
809
|
+
userTokenInAccount,
|
|
810
|
+
ammProgram
|
|
811
|
+
}).remainingAccounts(remainingAccounts).preInstructions(preInstructions).postInstructions(postInstructions).transaction();
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Performs a token swap using Jupiter V6 protocol as part of a zap out operation.
|
|
816
|
+
* Swaps tokens from the input token ledger to the user's output token account.
|
|
817
|
+
*
|
|
818
|
+
* @param params - Jupiter V6 swap parameters from Jupiter API
|
|
819
|
+
* @param params.user - Public key of the user performing the swap
|
|
820
|
+
* @param params.inputMint - Token mint being swapped from
|
|
821
|
+
* @param params.outputMint - Token mint being swapped to
|
|
822
|
+
* @param params.jupiterSwapResponse - Jupiter swap instruction response
|
|
823
|
+
* @param params.inputTokenProgram - Token program for the input token (defaults to SPL Token)
|
|
824
|
+
* @param params.outputTokenProgram - Token program for the output token (defaults to SPL Token)
|
|
825
|
+
* @param params.maxSwapAmount - Maximum amount of input token to swap
|
|
826
|
+
* @param params.percentageToZapOut - Percentage of input token to zap out
|
|
827
|
+
* @returns built transaction
|
|
828
|
+
*/
|
|
829
|
+
zapOutThroughJupiter(params) {
|
|
830
|
+
return __async(this, null, function* () {
|
|
831
|
+
const {
|
|
832
|
+
inputTokenAccount,
|
|
833
|
+
jupiterSwapResponse,
|
|
834
|
+
maxSwapAmount,
|
|
835
|
+
percentageToZapOut,
|
|
836
|
+
preInstructions,
|
|
837
|
+
postInstructions
|
|
838
|
+
} = params;
|
|
839
|
+
const preUserTokenBalance = (yield this.connection.getTokenAccountBalance(inputTokenAccount)).value.amount;
|
|
840
|
+
const remainingAccounts = jupiterSwapResponse.swapInstruction.accounts.map(
|
|
841
|
+
(account) => {
|
|
842
|
+
let pubkey = typeof account.pubkey === "string" ? new PublicKey7(account.pubkey) : account.pubkey;
|
|
843
|
+
return {
|
|
844
|
+
pubkey,
|
|
845
|
+
isSigner: account.isSigner,
|
|
846
|
+
isWritable: account.isWritable
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
);
|
|
850
|
+
const payloadData = Buffer.from(
|
|
851
|
+
jupiterSwapResponse.swapInstruction.data,
|
|
852
|
+
"base64"
|
|
853
|
+
);
|
|
854
|
+
const offsetAmountIn = payloadData.length - AMOUNT_IN_JUP_V6_REVERSE_OFFSET;
|
|
855
|
+
return yield this.zapOut({
|
|
856
|
+
userTokenInAccount: inputTokenAccount,
|
|
857
|
+
zapOutParams: {
|
|
858
|
+
percentage: percentageToZapOut,
|
|
859
|
+
offsetAmountIn,
|
|
860
|
+
preUserTokenBalance: new BN3(preUserTokenBalance),
|
|
861
|
+
maxSwapAmount,
|
|
862
|
+
payloadData
|
|
863
|
+
},
|
|
864
|
+
remainingAccounts,
|
|
865
|
+
ammProgram: JUP_V6_PROGRAM_ID,
|
|
866
|
+
preInstructions: preInstructions || [],
|
|
867
|
+
postInstructions: postInstructions || []
|
|
868
|
+
});
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* Performs a token swap using Damms V2 protocol as part of a zap out operation.
|
|
873
|
+
* Swaps tokens from the input token ledger to the user's output token account.
|
|
874
|
+
*
|
|
875
|
+
* @param params - Damms V2 swap parameters
|
|
876
|
+
* @param params.user - Public key of the user performing the swap
|
|
877
|
+
* @param params.poolAddress - Address of the pool to swap through
|
|
878
|
+
* @param params.inputMint - Token mint being swapped from
|
|
879
|
+
* @param params.inputTokenProgram - Token program for the input token (defaults to SPL Token)
|
|
880
|
+
* @param params.amountIn - Amount of input token to swap
|
|
881
|
+
* @param params.minimumSwapAmountOut - Minimum amount of output token to receive
|
|
882
|
+
* @param params.maxSwapAmount - Maximum amount of input token to swap
|
|
883
|
+
* @param params.percentageToZapOut - Percentage of input token to zap out
|
|
884
|
+
*/
|
|
885
|
+
zapOutThroughDammV2(params) {
|
|
886
|
+
return __async(this, null, function* () {
|
|
887
|
+
const {
|
|
888
|
+
user,
|
|
889
|
+
poolAddress,
|
|
890
|
+
inputTokenAccount,
|
|
891
|
+
outputTokenAccount,
|
|
892
|
+
amountIn,
|
|
893
|
+
minimumSwapAmountOut,
|
|
894
|
+
maxSwapAmount,
|
|
895
|
+
percentageToZapOut,
|
|
896
|
+
preInstructions,
|
|
897
|
+
postInstructions
|
|
898
|
+
} = params;
|
|
899
|
+
const poolState = yield getDammV2Pool(this.connection, poolAddress);
|
|
900
|
+
const preUserTokenBalance = (yield this.connection.getTokenAccountBalance(inputTokenAccount)).value.amount;
|
|
901
|
+
const remainingAccounts = yield getDammV2RemainingAccounts(
|
|
902
|
+
poolAddress,
|
|
903
|
+
user,
|
|
904
|
+
inputTokenAccount,
|
|
905
|
+
outputTokenAccount,
|
|
906
|
+
getTokenProgram(poolState.tokenAFlag),
|
|
907
|
+
getTokenProgram(poolState.tokenBFlag),
|
|
908
|
+
poolState
|
|
909
|
+
);
|
|
910
|
+
const payloadData = createDammV2SwapPayload(amountIn, minimumSwapAmountOut);
|
|
911
|
+
const offsetAmountIn = AMOUNT_IN_DAMM_V2_OFFSET;
|
|
912
|
+
return yield this.zapOut({
|
|
913
|
+
userTokenInAccount: inputTokenAccount,
|
|
914
|
+
zapOutParams: {
|
|
915
|
+
percentage: percentageToZapOut,
|
|
916
|
+
offsetAmountIn,
|
|
917
|
+
preUserTokenBalance: new BN3(preUserTokenBalance),
|
|
918
|
+
maxSwapAmount,
|
|
919
|
+
payloadData
|
|
920
|
+
},
|
|
921
|
+
remainingAccounts,
|
|
922
|
+
ammProgram: DAMM_V2_PROGRAM_ID,
|
|
923
|
+
preInstructions: preInstructions || [],
|
|
924
|
+
postInstructions: postInstructions || []
|
|
925
|
+
});
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
929
|
+
* Performs a token swap using Dlmm protocol as part of a zap out operation.
|
|
930
|
+
* Swaps tokens from the input token ledger to the user's output token account.
|
|
931
|
+
*
|
|
932
|
+
* @param params - Dlmm swap parameters
|
|
933
|
+
* @param params.user - Public key of the user performing the swap
|
|
934
|
+
* @param params.lbPairAddress - Address of the lbPair to swap through
|
|
935
|
+
* @param params.inputMint - Token mint being swapped from
|
|
936
|
+
* @param params.inputTokenProgram - Token program for the input token (defaults to SPL Token)
|
|
937
|
+
* @param params.amountIn - Amount of input token to swap
|
|
938
|
+
* @param params.minimumSwapAmountOut - Minimum amount of output token to receive
|
|
939
|
+
* @param params.maxSwapAmount - Maximum amount of input token to swap
|
|
940
|
+
* @param params.percentageToZapOut - Percentage of input token to zap out
|
|
941
|
+
*/
|
|
942
|
+
zapOutThroughDlmm(params) {
|
|
943
|
+
return __async(this, null, function* () {
|
|
944
|
+
const {
|
|
945
|
+
user,
|
|
946
|
+
lbPairAddress,
|
|
947
|
+
inputTokenAccount,
|
|
948
|
+
outputTokenAccount,
|
|
949
|
+
amountIn,
|
|
950
|
+
minimumSwapAmountOut,
|
|
951
|
+
maxSwapAmount,
|
|
952
|
+
percentageToZapOut,
|
|
953
|
+
preInstructions,
|
|
954
|
+
postInstructions
|
|
955
|
+
} = params;
|
|
956
|
+
const lbPairState = yield getLbPairState(this.connection, lbPairAddress);
|
|
957
|
+
const preUserTokenBalance = (yield this.connection.getTokenAccountBalance(inputTokenAccount)).value.amount;
|
|
958
|
+
const { remainingAccounts, remainingAccountsInfo } = yield getDlmmRemainingAccounts(
|
|
959
|
+
this.connection,
|
|
960
|
+
lbPairAddress,
|
|
961
|
+
user,
|
|
962
|
+
inputTokenAccount,
|
|
963
|
+
outputTokenAccount,
|
|
964
|
+
getTokenProgram(lbPairState.tokenMintXProgramFlag),
|
|
965
|
+
getTokenProgram(lbPairState.tokenMintYProgramFlag),
|
|
966
|
+
lbPairState
|
|
967
|
+
);
|
|
968
|
+
const payloadData = createDlmmSwapPayload(
|
|
969
|
+
amountIn,
|
|
970
|
+
minimumSwapAmountOut,
|
|
971
|
+
remainingAccountsInfo
|
|
972
|
+
);
|
|
973
|
+
return yield this.zapOut({
|
|
974
|
+
userTokenInAccount: inputTokenAccount,
|
|
975
|
+
zapOutParams: {
|
|
976
|
+
percentage: percentageToZapOut,
|
|
977
|
+
offsetAmountIn: AMOUNT_IN_DLMM_OFFSET,
|
|
978
|
+
preUserTokenBalance: new BN3(preUserTokenBalance),
|
|
979
|
+
maxSwapAmount,
|
|
980
|
+
payloadData
|
|
981
|
+
},
|
|
982
|
+
remainingAccounts,
|
|
983
|
+
ammProgram: DLMM_PROGRAM_ID,
|
|
984
|
+
preInstructions: preInstructions || [],
|
|
985
|
+
postInstructions: postInstructions || []
|
|
986
|
+
});
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
};
|
|
990
|
+
export {
|
|
991
|
+
AMOUNT_IN_DAMM_V2_OFFSET,
|
|
992
|
+
AMOUNT_IN_DLMM_OFFSET,
|
|
993
|
+
AMOUNT_IN_JUP_V6_REVERSE_OFFSET,
|
|
994
|
+
AccountsType,
|
|
995
|
+
BIN_ARRAY_INDEX_BOUND,
|
|
996
|
+
DAMM_V2_PROGRAM_ID,
|
|
997
|
+
DAMM_V2_SWAP_DISCRIMINATOR,
|
|
998
|
+
DLMM_PROGRAM_ID,
|
|
999
|
+
DLMM_SWAP_DISCRIMINATOR,
|
|
1000
|
+
JUP_V6_PROGRAM_ID,
|
|
1001
|
+
MEMO_PROGRAM_ID,
|
|
1002
|
+
ZAP_PROGRAM_ID,
|
|
1003
|
+
Zap,
|
|
1004
|
+
convertAccountTypeToNumber,
|
|
1005
|
+
createDammV2SwapPayload,
|
|
1006
|
+
createDlmmSwapPayload,
|
|
1007
|
+
deriveDammV2EventAuthority,
|
|
1008
|
+
getBinArrayBitmapExtension,
|
|
1009
|
+
getBitFromBinArrayIndexInBitmapExtension,
|
|
1010
|
+
getDammV2Pool,
|
|
1011
|
+
getDammV2RemainingAccounts,
|
|
1012
|
+
getDlmmRemainingAccounts,
|
|
1013
|
+
getExtraAccountMetasForTransferHook,
|
|
1014
|
+
getJupiterQuote,
|
|
1015
|
+
getJupiterSwapInstruction,
|
|
1016
|
+
getLbPairState,
|
|
1017
|
+
getNextBinArrayIndexWithLiquidity,
|
|
1018
|
+
getOrCreateATAInstruction,
|
|
1019
|
+
getTokenProgramFromMint,
|
|
1020
|
+
unwrapSOLInstruction,
|
|
1021
|
+
wrapSOLInstruction
|
|
1022
|
+
};
|