@elmntl/jlpd-sdk 0.1.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 +363 -0
- package/dist/index.d.mts +743 -0
- package/dist/index.d.ts +743 -0
- package/dist/index.js +1843 -0
- package/dist/index.mjs +1753 -0
- package/package.json +30 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1843 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
AdminContext: () => AdminContext,
|
|
24
|
+
EXCHANGE_RATE_PRECISION: () => EXCHANGE_RATE_PRECISION,
|
|
25
|
+
FLAG_DEPOSITS_DISABLED: () => FLAG_DEPOSITS_DISABLED,
|
|
26
|
+
FLAG_JLP_DISABLED: () => FLAG_JLP_DISABLED,
|
|
27
|
+
FLAG_PAUSED: () => FLAG_PAUSED,
|
|
28
|
+
FLAG_REBALANCE_DISABLED: () => FLAG_REBALANCE_DISABLED,
|
|
29
|
+
FLAG_WITHDRAWALS_DISABLED: () => FLAG_WITHDRAWALS_DISABLED,
|
|
30
|
+
JLPD_PROGRAM_ID: () => JLPD_PROGRAM_ID,
|
|
31
|
+
JLP_VAULT_ACCOUNT_SIZE: () => JLP_VAULT_ACCOUNT_SIZE,
|
|
32
|
+
JLP_VAULT_DATA_SIZE: () => JLP_VAULT_DATA_SIZE,
|
|
33
|
+
JLP_VAULT_DISCRIMINATOR: () => JLP_VAULT_DISCRIMINATOR,
|
|
34
|
+
JUPITER_LEND_PROGRAM_ID: () => JUPITER_LEND_PROGRAM_ID,
|
|
35
|
+
JUPITER_SWAP_PROGRAM_ID: () => JUPITER_SWAP_PROGRAM_ID,
|
|
36
|
+
JUPUSD_POOL: () => JUPUSD_POOL,
|
|
37
|
+
JUP_LEND_PROGRAM_ID: () => JUPITER_LEND_PROGRAM_ID2,
|
|
38
|
+
JlpdClient: () => JlpdClient,
|
|
39
|
+
JlpdClientError: () => JlpdClientError,
|
|
40
|
+
LENDING_ADMIN: () => LENDING_ADMIN,
|
|
41
|
+
LIQUIDITY_PROGRAM_ID: () => LIQUIDITY_PROGRAM_ID,
|
|
42
|
+
LIQUIDITY_SINGLETON: () => LIQUIDITY_SINGLETON,
|
|
43
|
+
MINTS: () => MINTS,
|
|
44
|
+
ORACLES: () => ORACLES,
|
|
45
|
+
POOLS: () => POOLS,
|
|
46
|
+
PPS_DECIMALS: () => PPS_DECIMALS,
|
|
47
|
+
PoolContext: () => PoolContext,
|
|
48
|
+
SEED_JLP_VAULT: () => SEED_JLP_VAULT,
|
|
49
|
+
SEED_STV: () => SEED_STV,
|
|
50
|
+
STV_ACCOUNT_SIZE: () => STV_ACCOUNT_SIZE,
|
|
51
|
+
STV_DATA_SIZE: () => STV_DATA_SIZE,
|
|
52
|
+
STV_DISCRIMINATOR: () => STV_DISCRIMINATOR,
|
|
53
|
+
STV_INDEX: () => STV_INDEX,
|
|
54
|
+
SwapContext: () => SwapContext,
|
|
55
|
+
USDC_POOL: () => USDC_POOL,
|
|
56
|
+
WBTC_POOL: () => WBTC_POOL,
|
|
57
|
+
WETH_POOL: () => WETH_POOL,
|
|
58
|
+
WSOL_POOL: () => WSOL_POOL,
|
|
59
|
+
baseToJlx: () => baseToJlx,
|
|
60
|
+
baseToShares: () => baseToShares,
|
|
61
|
+
buildExchangeRateAccounts: () => buildExchangeRateAccounts,
|
|
62
|
+
buildJupEarnDepositAccounts: () => buildJupEarnDepositAccounts,
|
|
63
|
+
buildJupEarnWithdrawAccounts: () => buildJupEarnWithdrawAccounts,
|
|
64
|
+
buildSwapData: () => buildSwapData,
|
|
65
|
+
calculateExchangeRate: () => calculateExchangeRate,
|
|
66
|
+
calculateNav: () => calculateNav,
|
|
67
|
+
calculatePps: () => calculatePps,
|
|
68
|
+
clearAtaCache: () => clearAtaCache,
|
|
69
|
+
clearPdaCache: () => clearPdaCache,
|
|
70
|
+
createClaimFeesInstruction: () => createClaimFeesInstruction,
|
|
71
|
+
createDepositInstruction: () => createDepositInstruction,
|
|
72
|
+
createInitOrUpdateVaultInstruction: () => createInitOrUpdateVaultInstruction,
|
|
73
|
+
createInitializeStvInstruction: () => createInitializeStvInstruction,
|
|
74
|
+
createJupEarnInstruction: () => createJupEarnInstruction,
|
|
75
|
+
createMoveJlxInstruction: () => createMoveJlxInstruction,
|
|
76
|
+
createSettleYieldInstruction: () => createSettleYieldInstruction,
|
|
77
|
+
createSwapJlxJlpInstruction: () => createSwapJlxJlpInstruction,
|
|
78
|
+
createSwapJlxJlxInstruction: () => createSwapJlxJlxInstruction,
|
|
79
|
+
createUpdateStvInstruction: () => createUpdateStvInstruction,
|
|
80
|
+
createWithdrawInstruction: () => createWithdrawInstruction,
|
|
81
|
+
deriveAta: () => deriveAta,
|
|
82
|
+
deriveStvAtas: () => deriveStvAtas,
|
|
83
|
+
deriveStvPda: () => deriveStvPda,
|
|
84
|
+
deriveUserAtas: () => deriveUserAtas,
|
|
85
|
+
deriveVaultAtas: () => deriveVaultAtas,
|
|
86
|
+
deriveVaultPda: () => deriveVaultPda,
|
|
87
|
+
fetchAddressLookupTables: () => fetchAddressLookupTables,
|
|
88
|
+
fetchJlpRate: () => fetchJlpRate,
|
|
89
|
+
fetchJupiterPriceUsd: () => fetchJupiterPriceUsd,
|
|
90
|
+
getJupiterQuote: () => getJupiterQuote,
|
|
91
|
+
getJupiterSwapInstructions: () => getJupiterSwapInstructions,
|
|
92
|
+
getPoolByMint: () => getPoolByMint,
|
|
93
|
+
getPoolByName: () => getPoolByName,
|
|
94
|
+
jlxToBase: () => jlxToBase,
|
|
95
|
+
parseLendingAccount: () => parseLendingAccount,
|
|
96
|
+
parseRewardsRateModel: () => parseRewardsRateModel,
|
|
97
|
+
parseStv: () => parseStv,
|
|
98
|
+
parseSwapRemainingAccounts: () => parseSwapRemainingAccounts,
|
|
99
|
+
parseVault: () => parseVault,
|
|
100
|
+
sharesToBase: () => sharesToBase
|
|
101
|
+
});
|
|
102
|
+
module.exports = __toCommonJS(index_exports);
|
|
103
|
+
|
|
104
|
+
// src/client.ts
|
|
105
|
+
var import_web312 = require("@solana/web3.js");
|
|
106
|
+
var import_anchor5 = require("@coral-xyz/anchor");
|
|
107
|
+
var import_spl_token5 = require("@solana/spl-token");
|
|
108
|
+
|
|
109
|
+
// src/constants.ts
|
|
110
|
+
var import_web3 = require("@solana/web3.js");
|
|
111
|
+
var import_spl_token = require("@solana/spl-token");
|
|
112
|
+
var JLPD_PROGRAM_ID = new import_web3.PublicKey(
|
|
113
|
+
"ELEM2bAobpZNuysfhyF28XGVjA1aTUwm6rPYyv1JX3oq"
|
|
114
|
+
);
|
|
115
|
+
var JUPITER_LEND_PROGRAM_ID = new import_web3.PublicKey(
|
|
116
|
+
"jup3YeL8QhtSx1e253b2FDvsMNC87fDrgQZivbrndc9"
|
|
117
|
+
);
|
|
118
|
+
var JUPITER_SWAP_PROGRAM_ID = new import_web3.PublicKey(
|
|
119
|
+
"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"
|
|
120
|
+
);
|
|
121
|
+
var SEED_JLP_VAULT = "jlp_vault";
|
|
122
|
+
var SEED_STV = "stv";
|
|
123
|
+
var FLAG_PAUSED = 1;
|
|
124
|
+
var FLAG_DEPOSITS_DISABLED = 2;
|
|
125
|
+
var FLAG_WITHDRAWALS_DISABLED = 4;
|
|
126
|
+
var FLAG_JLP_DISABLED = 8;
|
|
127
|
+
var FLAG_REBALANCE_DISABLED = 16;
|
|
128
|
+
var PPS_DECIMALS = 1e9;
|
|
129
|
+
var EXCHANGE_RATE_PRECISION = 1e12;
|
|
130
|
+
var MINTS = {
|
|
131
|
+
JLP: new import_web3.PublicKey("27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4"),
|
|
132
|
+
WSOL: import_spl_token.NATIVE_MINT,
|
|
133
|
+
USDC: new import_web3.PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"),
|
|
134
|
+
WBTC: new import_web3.PublicKey("3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh"),
|
|
135
|
+
WETH: new import_web3.PublicKey("7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs"),
|
|
136
|
+
JupUSD: new import_web3.PublicKey("JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD")
|
|
137
|
+
};
|
|
138
|
+
var STV_INDEX = /* @__PURE__ */ ((STV_INDEX2) => {
|
|
139
|
+
STV_INDEX2[STV_INDEX2["BTC"] = 0] = "BTC";
|
|
140
|
+
STV_INDEX2[STV_INDEX2["ETH"] = 1] = "ETH";
|
|
141
|
+
STV_INDEX2[STV_INDEX2["SOL"] = 2] = "SOL";
|
|
142
|
+
STV_INDEX2[STV_INDEX2["USDC"] = 3] = "USDC";
|
|
143
|
+
STV_INDEX2[STV_INDEX2["JupUSD"] = 4] = "JupUSD";
|
|
144
|
+
return STV_INDEX2;
|
|
145
|
+
})(STV_INDEX || {});
|
|
146
|
+
var ORACLES = {
|
|
147
|
+
// Doves oracles (Jupiter Perps oracle system)
|
|
148
|
+
DOVES_BTC_USD: new import_web3.PublicKey("4HBbPx9QJdjJ7GUe6bsiJjGybvfpDhQMMPXP1UEa7VT5"),
|
|
149
|
+
DOVES_ETH_USD: new import_web3.PublicKey("5URYohbPy32nxK1t3jAHVNfdWY2xTubHiFvLrE3VhXEp"),
|
|
150
|
+
DOVES_SOL_USD: new import_web3.PublicKey("39cWjvHrpHNz2SbXv6ME4NPhqBDBd4KsjUYv5JkHEAJU"),
|
|
151
|
+
// Pyth oracle for JLP price
|
|
152
|
+
PYTH_JLP_USD: new import_web3.PublicKey("2TTGSRSezqFzeLUH8JwRUbtN66XLLaymfYsWRTMjfiMw")
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// src/accounts/pdas.ts
|
|
156
|
+
var import_web32 = require("@solana/web3.js");
|
|
157
|
+
var SEED_JLP_VAULT_BUFFER = Buffer.from(SEED_JLP_VAULT);
|
|
158
|
+
var SEED_STV_BUFFER = Buffer.from(SEED_STV);
|
|
159
|
+
var pdaCache = /* @__PURE__ */ new Map();
|
|
160
|
+
function deriveVaultPda(programId) {
|
|
161
|
+
const key = `vault:${programId.toBase58()}`;
|
|
162
|
+
let cached = pdaCache.get(key);
|
|
163
|
+
if (!cached) {
|
|
164
|
+
cached = import_web32.PublicKey.findProgramAddressSync(
|
|
165
|
+
[SEED_JLP_VAULT_BUFFER],
|
|
166
|
+
programId
|
|
167
|
+
);
|
|
168
|
+
pdaCache.set(key, cached);
|
|
169
|
+
}
|
|
170
|
+
return cached;
|
|
171
|
+
}
|
|
172
|
+
function deriveStvPda(baseMint, programId) {
|
|
173
|
+
const key = `stv:${baseMint.toBase58()}:${programId.toBase58()}`;
|
|
174
|
+
let cached = pdaCache.get(key);
|
|
175
|
+
if (!cached) {
|
|
176
|
+
cached = import_web32.PublicKey.findProgramAddressSync(
|
|
177
|
+
[SEED_STV_BUFFER, baseMint.toBuffer()],
|
|
178
|
+
programId
|
|
179
|
+
);
|
|
180
|
+
pdaCache.set(key, cached);
|
|
181
|
+
}
|
|
182
|
+
return cached;
|
|
183
|
+
}
|
|
184
|
+
function clearPdaCache() {
|
|
185
|
+
pdaCache.clear();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// src/accounts/vault.ts
|
|
189
|
+
var import_web33 = require("@solana/web3.js");
|
|
190
|
+
var import_anchor = require("@coral-xyz/anchor");
|
|
191
|
+
var JLP_VAULT_DATA_SIZE = 464;
|
|
192
|
+
var JLP_VAULT_ACCOUNT_SIZE = 8 + JLP_VAULT_DATA_SIZE;
|
|
193
|
+
var JLP_VAULT_DISCRIMINATOR = Buffer.from([
|
|
194
|
+
41,
|
|
195
|
+
108,
|
|
196
|
+
189,
|
|
197
|
+
168,
|
|
198
|
+
199,
|
|
199
|
+
152,
|
|
200
|
+
221,
|
|
201
|
+
119
|
|
202
|
+
]);
|
|
203
|
+
function parseVault(data) {
|
|
204
|
+
if (data.length < JLP_VAULT_ACCOUNT_SIZE) {
|
|
205
|
+
throw new Error(
|
|
206
|
+
`Invalid JLPVault data size: expected ${JLP_VAULT_ACCOUNT_SIZE}, got ${data.length}`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
const discriminator = data.subarray(0, 8);
|
|
210
|
+
if (!discriminator.equals(JLP_VAULT_DISCRIMINATOR)) {
|
|
211
|
+
throw new Error(
|
|
212
|
+
`Invalid JLPVault discriminator: expected ${JLP_VAULT_DISCRIMINATOR.toString("hex")}, got ${discriminator.toString("hex")}`
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
let offset = 8;
|
|
216
|
+
const admin = new import_web33.PublicKey(data.subarray(offset, offset + 32));
|
|
217
|
+
offset += 32;
|
|
218
|
+
const manager = new import_web33.PublicKey(data.subarray(offset, offset + 32));
|
|
219
|
+
offset += 32;
|
|
220
|
+
const feeReceiver = new import_web33.PublicKey(data.subarray(offset, offset + 32));
|
|
221
|
+
offset += 32;
|
|
222
|
+
const jlpMint = new import_web33.PublicKey(data.subarray(offset, offset + 32));
|
|
223
|
+
offset += 32;
|
|
224
|
+
const baseAssetMints = [];
|
|
225
|
+
for (let i = 0; i < 5; i++) {
|
|
226
|
+
baseAssetMints.push(new import_web33.PublicKey(data.subarray(offset, offset + 32)));
|
|
227
|
+
offset += 32;
|
|
228
|
+
}
|
|
229
|
+
const jlxAssetMints = [];
|
|
230
|
+
for (let i = 0; i < 5; i++) {
|
|
231
|
+
jlxAssetMints.push(new import_web33.PublicKey(data.subarray(offset, offset + 32)));
|
|
232
|
+
offset += 32;
|
|
233
|
+
}
|
|
234
|
+
const oracleStalenessThreshold = new import_anchor.BN(data.subarray(offset, offset + 8), "le");
|
|
235
|
+
offset += 8;
|
|
236
|
+
const flags = data.readUInt16LE(offset);
|
|
237
|
+
offset += 2;
|
|
238
|
+
const jlpSlippageBps = data.readUInt16LE(offset);
|
|
239
|
+
offset += 2;
|
|
240
|
+
const version = data.readUInt8(offset);
|
|
241
|
+
offset += 1;
|
|
242
|
+
const bump = data.readUInt8(offset);
|
|
243
|
+
offset += 1;
|
|
244
|
+
return {
|
|
245
|
+
admin,
|
|
246
|
+
manager,
|
|
247
|
+
feeReceiver,
|
|
248
|
+
jlpMint,
|
|
249
|
+
baseAssetMints,
|
|
250
|
+
jlxAssetMints,
|
|
251
|
+
oracleStalenessThreshold,
|
|
252
|
+
flags,
|
|
253
|
+
jlpSlippageBps,
|
|
254
|
+
version,
|
|
255
|
+
bump
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// src/accounts/stv.ts
|
|
260
|
+
var import_web34 = require("@solana/web3.js");
|
|
261
|
+
var import_anchor2 = require("@coral-xyz/anchor");
|
|
262
|
+
var STV_DATA_SIZE = 160;
|
|
263
|
+
var STV_ACCOUNT_SIZE = 8 + STV_DATA_SIZE;
|
|
264
|
+
var STV_DISCRIMINATOR = Buffer.from([
|
|
265
|
+
214,
|
|
266
|
+
2,
|
|
267
|
+
96,
|
|
268
|
+
41,
|
|
269
|
+
85,
|
|
270
|
+
163,
|
|
271
|
+
17,
|
|
272
|
+
230
|
|
273
|
+
]);
|
|
274
|
+
function parseStv(data) {
|
|
275
|
+
if (data.length < STV_ACCOUNT_SIZE) {
|
|
276
|
+
throw new Error(
|
|
277
|
+
`Invalid STV data size: expected ${STV_ACCOUNT_SIZE}, got ${data.length}`
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
const discriminator = data.subarray(0, 8);
|
|
281
|
+
if (!discriminator.equals(STV_DISCRIMINATOR)) {
|
|
282
|
+
throw new Error(
|
|
283
|
+
`Invalid STV discriminator: expected ${STV_DISCRIMINATOR.toString("hex")}, got ${discriminator.toString("hex")}`
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
let offset = 8;
|
|
287
|
+
const baseMint = new import_web34.PublicKey(data.subarray(offset, offset + 32));
|
|
288
|
+
offset += 32;
|
|
289
|
+
const jlMint = new import_web34.PublicKey(data.subarray(offset, offset + 32));
|
|
290
|
+
offset += 32;
|
|
291
|
+
const jvMint = new import_web34.PublicKey(data.subarray(offset, offset + 32));
|
|
292
|
+
offset += 32;
|
|
293
|
+
const pps = new import_anchor2.BN(data.subarray(offset, offset + 8), "le");
|
|
294
|
+
offset += 8;
|
|
295
|
+
const hwm = new import_anchor2.BN(data.subarray(offset, offset + 8), "le");
|
|
296
|
+
offset += 8;
|
|
297
|
+
const lastMgmtFeeTs = new import_anchor2.BN(data.subarray(offset, offset + 8), "le");
|
|
298
|
+
offset += 8;
|
|
299
|
+
const baseLoaned = new import_anchor2.BN(data.subarray(offset, offset + 8), "le");
|
|
300
|
+
offset += 8;
|
|
301
|
+
const accruedFeesJlx = new import_anchor2.BN(data.subarray(offset, offset + 8), "le");
|
|
302
|
+
offset += 8;
|
|
303
|
+
const maxDeposit = new import_anchor2.BN(data.subarray(offset, offset + 8), "le");
|
|
304
|
+
offset += 8;
|
|
305
|
+
const minDeposit = new import_anchor2.BN(data.subarray(offset, offset + 8), "le");
|
|
306
|
+
offset += 8;
|
|
307
|
+
const mgmtFeeBps = data.readUInt16LE(offset);
|
|
308
|
+
offset += 2;
|
|
309
|
+
const perfFeeBps = data.readUInt16LE(offset);
|
|
310
|
+
offset += 2;
|
|
311
|
+
const flags = data.readUInt16LE(offset);
|
|
312
|
+
offset += 2;
|
|
313
|
+
const version = data.readUInt8(offset);
|
|
314
|
+
offset += 1;
|
|
315
|
+
const bump = data.readUInt8(offset);
|
|
316
|
+
offset += 1;
|
|
317
|
+
return {
|
|
318
|
+
baseMint,
|
|
319
|
+
jlMint,
|
|
320
|
+
jvMint,
|
|
321
|
+
pps,
|
|
322
|
+
hwm,
|
|
323
|
+
lastMgmtFeeTs,
|
|
324
|
+
baseLoaned,
|
|
325
|
+
accruedFeesJlx,
|
|
326
|
+
maxDeposit,
|
|
327
|
+
minDeposit,
|
|
328
|
+
mgmtFeeBps,
|
|
329
|
+
perfFeeBps,
|
|
330
|
+
flags,
|
|
331
|
+
version,
|
|
332
|
+
bump
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/utils/ata.ts
|
|
337
|
+
var import_spl_token2 = require("@solana/spl-token");
|
|
338
|
+
var ataCache = /* @__PURE__ */ new Map();
|
|
339
|
+
function deriveAta(mint, owner, allowPda = false) {
|
|
340
|
+
const key = `${mint.toBase58()}:${owner.toBase58()}:${allowPda}`;
|
|
341
|
+
let cached = ataCache.get(key);
|
|
342
|
+
if (!cached) {
|
|
343
|
+
cached = (0, import_spl_token2.getAssociatedTokenAddressSync)(mint, owner, allowPda);
|
|
344
|
+
ataCache.set(key, cached);
|
|
345
|
+
}
|
|
346
|
+
return cached;
|
|
347
|
+
}
|
|
348
|
+
function deriveUserAtas(baseMint, jvMint, userWallet) {
|
|
349
|
+
return {
|
|
350
|
+
baseAta: deriveAta(baseMint, userWallet, false),
|
|
351
|
+
jvxAta: deriveAta(jvMint, userWallet, false)
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function deriveStvAtas(baseMint, jlxMint, stvPda) {
|
|
355
|
+
return {
|
|
356
|
+
baseAta: deriveAta(baseMint, stvPda, true),
|
|
357
|
+
jlxAta: deriveAta(jlxMint, stvPda, true)
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function deriveVaultAtas(jlxMint, jlpMint, vaultPda) {
|
|
361
|
+
return {
|
|
362
|
+
stagingAta: deriveAta(jlxMint, vaultPda, true),
|
|
363
|
+
jlpAta: deriveAta(jlpMint, vaultPda, true)
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function clearAtaCache() {
|
|
367
|
+
ataCache.clear();
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// src/utils/math.ts
|
|
371
|
+
var import_anchor3 = require("@coral-xyz/anchor");
|
|
372
|
+
var PPS_DECIMALS_BN = new import_anchor3.BN(PPS_DECIMALS);
|
|
373
|
+
var EXCHANGE_RATE_PRECISION_BN = new import_anchor3.BN(EXCHANGE_RATE_PRECISION);
|
|
374
|
+
var EXCHANGE_RATE_PRECISION_BI = BigInt(EXCHANGE_RATE_PRECISION);
|
|
375
|
+
var RETURN_PERCENT_PRECISION = EXCHANGE_RATE_PRECISION_BI * 100n;
|
|
376
|
+
var SECONDS_PER_YEAR = BigInt(365 * 24 * 60 * 60);
|
|
377
|
+
var MAX_REWARDS_RATE = 50n * EXCHANGE_RATE_PRECISION_BI;
|
|
378
|
+
function calculateNav(stvBaseBalance, stvJlxBalance, exchangeRate, baseLoaned) {
|
|
379
|
+
const jlxValue = stvJlxBalance.mul(new import_anchor3.BN(exchangeRate.toString())).div(EXCHANGE_RATE_PRECISION_BN);
|
|
380
|
+
return stvBaseBalance.add(jlxValue).add(baseLoaned);
|
|
381
|
+
}
|
|
382
|
+
function calculatePps(nav, jvSupply) {
|
|
383
|
+
if (jvSupply.isZero()) {
|
|
384
|
+
return new import_anchor3.BN(PPS_DECIMALS);
|
|
385
|
+
}
|
|
386
|
+
return nav.mul(PPS_DECIMALS_BN).div(jvSupply);
|
|
387
|
+
}
|
|
388
|
+
function sharesToBase(shares, pps) {
|
|
389
|
+
if (pps.isZero()) {
|
|
390
|
+
throw new Error("Price per share cannot be zero");
|
|
391
|
+
}
|
|
392
|
+
return shares.mul(pps).div(PPS_DECIMALS_BN);
|
|
393
|
+
}
|
|
394
|
+
function baseToShares(base, pps) {
|
|
395
|
+
if (pps.isZero()) {
|
|
396
|
+
throw new Error("Price per share cannot be zero");
|
|
397
|
+
}
|
|
398
|
+
return base.mul(PPS_DECIMALS_BN).div(pps);
|
|
399
|
+
}
|
|
400
|
+
function jlxToBase(jlxAmount, exchangeRate) {
|
|
401
|
+
if (exchangeRate.isZero()) {
|
|
402
|
+
throw new Error("Exchange rate cannot be zero");
|
|
403
|
+
}
|
|
404
|
+
return jlxAmount.mul(exchangeRate).div(EXCHANGE_RATE_PRECISION_BN);
|
|
405
|
+
}
|
|
406
|
+
function baseToJlx(baseAmount, exchangeRate) {
|
|
407
|
+
if (exchangeRate.isZero()) {
|
|
408
|
+
throw new Error("Exchange rate cannot be zero");
|
|
409
|
+
}
|
|
410
|
+
return baseAmount.mul(EXCHANGE_RATE_PRECISION_BN).div(exchangeRate);
|
|
411
|
+
}
|
|
412
|
+
function calculateExchangeRate(storedRate, rewardsRate, currentTimestamp, lastUpdateTimestamp, fTokenTotalSupply) {
|
|
413
|
+
if (fTokenTotalSupply === 0n) {
|
|
414
|
+
return storedRate;
|
|
415
|
+
}
|
|
416
|
+
const totalAssets = storedRate * fTokenTotalSupply / EXCHANGE_RATE_PRECISION_BI;
|
|
417
|
+
if (totalAssets === 0n || rewardsRate === 0n) {
|
|
418
|
+
return storedRate;
|
|
419
|
+
}
|
|
420
|
+
const timeDiff = currentTimestamp - lastUpdateTimestamp;
|
|
421
|
+
if (timeDiff <= 0n) {
|
|
422
|
+
return storedRate;
|
|
423
|
+
}
|
|
424
|
+
const rate = rewardsRate * RETURN_PERCENT_PRECISION / totalAssets;
|
|
425
|
+
const cappedRate = rate > MAX_REWARDS_RATE ? MAX_REWARDS_RATE : rate;
|
|
426
|
+
const priceIncrease = storedRate * cappedRate * timeDiff / RETURN_PERCENT_PRECISION / SECONDS_PER_YEAR;
|
|
427
|
+
return storedRate + priceIncrease;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// src/jupiter/pools.ts
|
|
431
|
+
var import_web35 = require("@solana/web3.js");
|
|
432
|
+
var import_spl_token3 = require("@solana/spl-token");
|
|
433
|
+
var LENDING_ADMIN = new import_web35.PublicKey("5nmGjA4s7ATzpBQXC5RNceRpaJ7pYw2wKsNBWyuSAZV6");
|
|
434
|
+
var LIQUIDITY_PROGRAM_ID = new import_web35.PublicKey("jupeiUmn818Jg1ekPURTpr4mFo29p46vygyykFJ3wZC");
|
|
435
|
+
var LIQUIDITY_SINGLETON = new import_web35.PublicKey("7s1da8DduuBFqGra5bJBjpnvL5E9mGzCuMk1Qkh4or2Z");
|
|
436
|
+
var WSOL_POOL = {
|
|
437
|
+
mint: import_spl_token3.NATIVE_MINT,
|
|
438
|
+
name: "SOL",
|
|
439
|
+
lending: new import_web35.PublicKey("BeAqbxfrcXmzEYT2Ra62oW2MqkuFDHaCtps47Mzg6Zj3"),
|
|
440
|
+
fTokenMint: new import_web35.PublicKey("2uQsyo1fXXQkDtcpXnLofWy88PxcvnfH2L8FPSE62FVU"),
|
|
441
|
+
tokenReservesLiquidity: new import_web35.PublicKey("4Y66HtUEqbbbpZdENGtFdVhUMS3tnagffn3M4do59Nfy"),
|
|
442
|
+
supplyPositionOnLiquidity: new import_web35.PublicKey("4SkEYxmiRgQ4VYyvh9VB4k39M49BpqazyzDUFDzJhXQm"),
|
|
443
|
+
rewardsRateModel: new import_web35.PublicKey("CkeQGDRsgMZcCaU8cZEdC2aFAohia4jLzL36RaLcUDsR"),
|
|
444
|
+
vault: new import_web35.PublicKey("BWeWnEbVmYKLmUpcrAXGrvDYxVA7VBS6TEnNc74jTerw"),
|
|
445
|
+
rateModel: new import_web35.PublicKey("Acvyi9HBGmqh3Exe1N4PjBVyY8fokq2AdC6fSLqV6KSo"),
|
|
446
|
+
claimAccount: new import_web35.PublicKey("6AQGR8zK4KTVZfZ9UZaRzyEL5ynvwVaF5ywVdmtJT24N"),
|
|
447
|
+
decimals: 9,
|
|
448
|
+
stvIndex: 2 /* SOL */,
|
|
449
|
+
hasJupiterLend: true
|
|
450
|
+
};
|
|
451
|
+
var USDC_POOL = {
|
|
452
|
+
mint: MINTS.USDC,
|
|
453
|
+
name: "USDC",
|
|
454
|
+
lending: new import_web35.PublicKey("2vVYHYM8VYnvZqQWpTJSj8o8DBf1wM8pVs3bsTgYZiqJ"),
|
|
455
|
+
fTokenMint: new import_web35.PublicKey("9BEcn9aPEmhSPbPQeFGjidRiEKki46fVQDyPpSQXPA2D"),
|
|
456
|
+
tokenReservesLiquidity: new import_web35.PublicKey("94vK29npVbyRHXH63rRcTiSr26SFhrQTzbpNJuhQEDu"),
|
|
457
|
+
supplyPositionOnLiquidity: new import_web35.PublicKey("Hf9gtkM4dpVBahVSzEXSVCAPpKzBsBcns3s8As3z77oF"),
|
|
458
|
+
rewardsRateModel: new import_web35.PublicKey("5xSPBiD3TibamAnwHDhZABdB4z4F9dcj5PnbteroBTTd"),
|
|
459
|
+
vault: new import_web35.PublicKey("BmkUoKMFYBxNSzWXyUjyMJjMAaVz4d8ZnxwwmhDCUXFB"),
|
|
460
|
+
rateModel: new import_web35.PublicKey("5pjzT5dFTsXcwixoab1QDLvZQvpYJxJeBphkyfHGn688"),
|
|
461
|
+
claimAccount: new import_web35.PublicKey("HN1r4VfkDn53xQQfeGDYrNuDKFdemAhZsHYRwBrFhsW"),
|
|
462
|
+
decimals: 6,
|
|
463
|
+
stvIndex: 3 /* USDC */,
|
|
464
|
+
hasJupiterLend: true
|
|
465
|
+
};
|
|
466
|
+
var JUPUSD_POOL = {
|
|
467
|
+
mint: MINTS.JupUSD,
|
|
468
|
+
name: "JupUSD",
|
|
469
|
+
lending: new import_web35.PublicKey("papYEgeG5uPE4niUWZhihUUzVVotJn1mAWbYo2UBSHi"),
|
|
470
|
+
fTokenMint: new import_web35.PublicKey("7GxATsNMnaC88vdwd2t3mwrFuQwwGvmYPrUQ4D6FotXk"),
|
|
471
|
+
tokenReservesLiquidity: new import_web35.PublicKey("2tQE8jVR5ezDw3PDa21BNzfyQ14Ug5cTf6n3swJNjkod"),
|
|
472
|
+
supplyPositionOnLiquidity: new import_web35.PublicKey("DXFoJruECdEch2KpzLQ2cSpxoBSsyg4bpYPnHYofsbD4"),
|
|
473
|
+
rewardsRateModel: new import_web35.PublicKey("E3U32h49TL9Qof3NeLja9qJxTrGYpY1o1NQPtrSLJjcc"),
|
|
474
|
+
vault: new import_web35.PublicKey("9kGqd5zsQGaFfFPdUuEgbRM4V7x72Jdt7WTS4uRouAQ7"),
|
|
475
|
+
rateModel: new import_web35.PublicKey("2hT44GA9r5PiqsbbmqN5CuF7ymtquoEdokRncAs9CVej"),
|
|
476
|
+
claimAccount: new import_web35.PublicKey("6q9vTzAsTMEPUCwuhEdJSJdpRNXnubwKZbi2go1B8nvg"),
|
|
477
|
+
decimals: 6,
|
|
478
|
+
stvIndex: 4 /* JupUSD */,
|
|
479
|
+
hasJupiterLend: true
|
|
480
|
+
};
|
|
481
|
+
var WBTC_POOL = {
|
|
482
|
+
mint: MINTS.WBTC,
|
|
483
|
+
name: "BTC",
|
|
484
|
+
lending: import_web35.PublicKey.default,
|
|
485
|
+
fTokenMint: MINTS.WBTC,
|
|
486
|
+
// jlBTC = WBTC (base-only)
|
|
487
|
+
tokenReservesLiquidity: import_web35.PublicKey.default,
|
|
488
|
+
supplyPositionOnLiquidity: import_web35.PublicKey.default,
|
|
489
|
+
rewardsRateModel: import_web35.PublicKey.default,
|
|
490
|
+
vault: import_web35.PublicKey.default,
|
|
491
|
+
rateModel: import_web35.PublicKey.default,
|
|
492
|
+
claimAccount: import_web35.PublicKey.default,
|
|
493
|
+
decimals: 8,
|
|
494
|
+
stvIndex: 0 /* BTC */,
|
|
495
|
+
hasJupiterLend: false
|
|
496
|
+
};
|
|
497
|
+
var WETH_POOL = {
|
|
498
|
+
mint: MINTS.WETH,
|
|
499
|
+
name: "ETH",
|
|
500
|
+
lending: import_web35.PublicKey.default,
|
|
501
|
+
fTokenMint: MINTS.WETH,
|
|
502
|
+
// jlETH = WETH (base-only)
|
|
503
|
+
tokenReservesLiquidity: import_web35.PublicKey.default,
|
|
504
|
+
supplyPositionOnLiquidity: import_web35.PublicKey.default,
|
|
505
|
+
rewardsRateModel: import_web35.PublicKey.default,
|
|
506
|
+
vault: import_web35.PublicKey.default,
|
|
507
|
+
rateModel: import_web35.PublicKey.default,
|
|
508
|
+
claimAccount: import_web35.PublicKey.default,
|
|
509
|
+
decimals: 8,
|
|
510
|
+
stvIndex: 1 /* ETH */,
|
|
511
|
+
hasJupiterLend: false
|
|
512
|
+
};
|
|
513
|
+
var POOLS = {
|
|
514
|
+
SOL: WSOL_POOL,
|
|
515
|
+
USDC: USDC_POOL,
|
|
516
|
+
JupUSD: JUPUSD_POOL,
|
|
517
|
+
BTC: WBTC_POOL,
|
|
518
|
+
ETH: WETH_POOL
|
|
519
|
+
};
|
|
520
|
+
var POOLS_BY_MINT = new Map(
|
|
521
|
+
Object.values(POOLS).map((p) => [p.mint.toBase58(), p])
|
|
522
|
+
);
|
|
523
|
+
function getPoolByName(name) {
|
|
524
|
+
return POOLS[name];
|
|
525
|
+
}
|
|
526
|
+
function getPoolByMint(mint) {
|
|
527
|
+
return POOLS_BY_MINT.get(mint.toBase58());
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// src/jupiter/lend.ts
|
|
531
|
+
var import_web36 = require("@solana/web3.js");
|
|
532
|
+
var import_spl_token4 = require("@solana/spl-token");
|
|
533
|
+
var JUPITER_LEND_PROGRAM_ID2 = new import_web36.PublicKey(
|
|
534
|
+
"jup3YeL8QhtSx1e253b2FDvsMNC87fDrgQZivbrndc9"
|
|
535
|
+
);
|
|
536
|
+
function buildExchangeRateAccounts(pool) {
|
|
537
|
+
if (!pool.hasJupiterLend) {
|
|
538
|
+
return null;
|
|
539
|
+
}
|
|
540
|
+
return {
|
|
541
|
+
lending: pool.lending,
|
|
542
|
+
rewardsRateModel: pool.rewardsRateModel
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
function buildJupEarnDepositAccounts(pool, stvPda, stvBaseAta, stvJlxAta) {
|
|
546
|
+
if (!pool.hasJupiterLend) {
|
|
547
|
+
throw new Error(`Pool ${pool.name} does not support Jupiter Lend`);
|
|
548
|
+
}
|
|
549
|
+
return [
|
|
550
|
+
{ pubkey: stvPda, isSigner: false, isWritable: true },
|
|
551
|
+
{ pubkey: stvBaseAta, isSigner: false, isWritable: true },
|
|
552
|
+
{ pubkey: stvJlxAta, isSigner: false, isWritable: true },
|
|
553
|
+
{ pubkey: pool.mint, isSigner: false, isWritable: false },
|
|
554
|
+
{ pubkey: LENDING_ADMIN, isSigner: false, isWritable: false },
|
|
555
|
+
{ pubkey: pool.lending, isSigner: false, isWritable: true },
|
|
556
|
+
{ pubkey: pool.fTokenMint, isSigner: false, isWritable: true },
|
|
557
|
+
{ pubkey: pool.tokenReservesLiquidity, isSigner: false, isWritable: true },
|
|
558
|
+
{ pubkey: pool.supplyPositionOnLiquidity, isSigner: false, isWritable: true },
|
|
559
|
+
{ pubkey: pool.rateModel, isSigner: false, isWritable: false },
|
|
560
|
+
{ pubkey: pool.vault, isSigner: false, isWritable: true },
|
|
561
|
+
{ pubkey: LIQUIDITY_SINGLETON, isSigner: false, isWritable: true },
|
|
562
|
+
{ pubkey: LIQUIDITY_PROGRAM_ID, isSigner: false, isWritable: true },
|
|
563
|
+
{ pubkey: pool.rewardsRateModel, isSigner: false, isWritable: false },
|
|
564
|
+
{ pubkey: import_spl_token4.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
565
|
+
{ pubkey: import_spl_token4.ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
566
|
+
{ pubkey: import_web36.SystemProgram.programId, isSigner: false, isWritable: false },
|
|
567
|
+
{ pubkey: JUPITER_LEND_PROGRAM_ID2, isSigner: false, isWritable: false }
|
|
568
|
+
];
|
|
569
|
+
}
|
|
570
|
+
function buildJupEarnWithdrawAccounts(pool, stvPda, stvJlxAta, stvBaseAta) {
|
|
571
|
+
if (!pool.hasJupiterLend) {
|
|
572
|
+
throw new Error(`Pool ${pool.name} does not support Jupiter Lend`);
|
|
573
|
+
}
|
|
574
|
+
return [
|
|
575
|
+
{ pubkey: stvPda, isSigner: false, isWritable: true },
|
|
576
|
+
{ pubkey: stvJlxAta, isSigner: false, isWritable: true },
|
|
577
|
+
{ pubkey: stvBaseAta, isSigner: false, isWritable: true },
|
|
578
|
+
{ pubkey: LENDING_ADMIN, isSigner: false, isWritable: false },
|
|
579
|
+
{ pubkey: pool.lending, isSigner: false, isWritable: true },
|
|
580
|
+
{ pubkey: pool.mint, isSigner: false, isWritable: false },
|
|
581
|
+
{ pubkey: pool.fTokenMint, isSigner: false, isWritable: true },
|
|
582
|
+
{ pubkey: pool.tokenReservesLiquidity, isSigner: false, isWritable: true },
|
|
583
|
+
{ pubkey: pool.supplyPositionOnLiquidity, isSigner: false, isWritable: true },
|
|
584
|
+
{ pubkey: pool.rateModel, isSigner: false, isWritable: false },
|
|
585
|
+
{ pubkey: pool.vault, isSigner: false, isWritable: true },
|
|
586
|
+
{ pubkey: pool.claimAccount, isSigner: false, isWritable: true },
|
|
587
|
+
{ pubkey: LIQUIDITY_SINGLETON, isSigner: false, isWritable: true },
|
|
588
|
+
{ pubkey: LIQUIDITY_PROGRAM_ID, isSigner: false, isWritable: true },
|
|
589
|
+
{ pubkey: pool.rewardsRateModel, isSigner: false, isWritable: false },
|
|
590
|
+
{ pubkey: import_spl_token4.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
591
|
+
{ pubkey: import_spl_token4.ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
592
|
+
{ pubkey: import_web36.SystemProgram.programId, isSigner: false, isWritable: false },
|
|
593
|
+
{ pubkey: JUPITER_LEND_PROGRAM_ID2, isSigner: false, isWritable: false }
|
|
594
|
+
];
|
|
595
|
+
}
|
|
596
|
+
function parseLendingAccount(data) {
|
|
597
|
+
return {
|
|
598
|
+
mint: new import_web36.PublicKey(data.slice(8, 40)),
|
|
599
|
+
fTokenMint: new import_web36.PublicKey(data.slice(40, 72)),
|
|
600
|
+
lendingId: data.readUInt16LE(72),
|
|
601
|
+
decimals: data[74],
|
|
602
|
+
rewardsRateModel: new import_web36.PublicKey(data.slice(75, 107)),
|
|
603
|
+
liquidityExchangePrice: data.readBigUInt64LE(107),
|
|
604
|
+
tokenExchangePrice: data.readBigUInt64LE(115),
|
|
605
|
+
lastUpdateTimestamp: data.readBigUInt64LE(123),
|
|
606
|
+
tokenReservesLiquidity: new import_web36.PublicKey(data.slice(131, 163)),
|
|
607
|
+
supplyPositionOnLiquidity: new import_web36.PublicKey(data.slice(163, 195)),
|
|
608
|
+
bump: data[195]
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
function parseRewardsRateModel(data) {
|
|
612
|
+
return {
|
|
613
|
+
mint: new import_web36.PublicKey(data.slice(8, 40)),
|
|
614
|
+
startTvl: data.readBigUInt64LE(40),
|
|
615
|
+
duration: data.readBigUInt64LE(48),
|
|
616
|
+
startTime: data.readBigUInt64LE(56),
|
|
617
|
+
yearlyReward: data.readBigUInt64LE(64),
|
|
618
|
+
nextDuration: data.readBigUInt64LE(72),
|
|
619
|
+
nextRewardAmount: data.readBigUInt64LE(80),
|
|
620
|
+
bump: data[88]
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// src/jupiter/swap.ts
|
|
625
|
+
var import_web37 = require("@solana/web3.js");
|
|
626
|
+
var JUPITER_API_BASE = "https://lite-api.jup.ag/swap/v1";
|
|
627
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
628
|
+
var MAX_RETRIES = 3;
|
|
629
|
+
var RETRY_DELAY_MS = 1e3;
|
|
630
|
+
function sleep(ms) {
|
|
631
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
632
|
+
}
|
|
633
|
+
async function fetchWithRetry(url, options = {}, timeoutMs = DEFAULT_TIMEOUT_MS, retries = MAX_RETRIES) {
|
|
634
|
+
let lastError = null;
|
|
635
|
+
for (let attempt = 0; attempt < retries; attempt++) {
|
|
636
|
+
try {
|
|
637
|
+
const controller = new AbortController();
|
|
638
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
639
|
+
const response = await fetch(url, {
|
|
640
|
+
...options,
|
|
641
|
+
signal: controller.signal
|
|
642
|
+
});
|
|
643
|
+
clearTimeout(timeoutId);
|
|
644
|
+
if (response.ok) {
|
|
645
|
+
return response;
|
|
646
|
+
}
|
|
647
|
+
if (response.status >= 400 && response.status < 500) {
|
|
648
|
+
const errorText = await response.text();
|
|
649
|
+
throw new Error(`Jupiter API error (${response.status}): ${errorText}`);
|
|
650
|
+
}
|
|
651
|
+
lastError = new Error(`Jupiter API returned ${response.status}`);
|
|
652
|
+
} catch (error) {
|
|
653
|
+
if (error instanceof Error) {
|
|
654
|
+
if (error.name === "AbortError") {
|
|
655
|
+
lastError = new Error(`Request timed out after ${timeoutMs}ms`);
|
|
656
|
+
} else {
|
|
657
|
+
lastError = error;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
if (attempt < retries - 1) {
|
|
662
|
+
await sleep(RETRY_DELAY_MS * (attempt + 1));
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
throw lastError ?? new Error("Unknown error during fetch");
|
|
666
|
+
}
|
|
667
|
+
async function getJupiterQuote(inputMint, outputMint, amount, slippageBps = 50, maxAccounts = 40) {
|
|
668
|
+
const params = new URLSearchParams({
|
|
669
|
+
inputMint: inputMint.toBase58(),
|
|
670
|
+
outputMint: outputMint.toBase58(),
|
|
671
|
+
amount: amount.toString(),
|
|
672
|
+
slippageBps: slippageBps.toString(),
|
|
673
|
+
maxAccounts: maxAccounts.toString()
|
|
674
|
+
});
|
|
675
|
+
const url = `${JUPITER_API_BASE}/quote?${params.toString()}`;
|
|
676
|
+
const response = await fetchWithRetry(url);
|
|
677
|
+
const data = await response.json();
|
|
678
|
+
if (data.error) {
|
|
679
|
+
throw new Error(`Jupiter quote error: ${data.error}`);
|
|
680
|
+
}
|
|
681
|
+
return data;
|
|
682
|
+
}
|
|
683
|
+
async function getJupiterSwapInstructions(quote, userPubkey) {
|
|
684
|
+
const url = `${JUPITER_API_BASE}/swap-instructions`;
|
|
685
|
+
const body = {
|
|
686
|
+
quoteResponse: quote,
|
|
687
|
+
userPublicKey: userPubkey.toBase58(),
|
|
688
|
+
wrapAndUnwrapSol: true,
|
|
689
|
+
useSharedAccounts: true,
|
|
690
|
+
dynamicComputeUnitLimit: true,
|
|
691
|
+
skipUserAccountsRpcCalls: false
|
|
692
|
+
};
|
|
693
|
+
const response = await fetchWithRetry(url, {
|
|
694
|
+
method: "POST",
|
|
695
|
+
headers: { "Content-Type": "application/json" },
|
|
696
|
+
body: JSON.stringify(body)
|
|
697
|
+
});
|
|
698
|
+
const data = await response.json();
|
|
699
|
+
if (data.error) {
|
|
700
|
+
throw new Error(`Jupiter swap instructions error: ${data.error}`);
|
|
701
|
+
}
|
|
702
|
+
return data;
|
|
703
|
+
}
|
|
704
|
+
function parseSwapRemainingAccounts(swapInstruction) {
|
|
705
|
+
return swapInstruction.accounts.map((acc) => ({
|
|
706
|
+
pubkey: new import_web37.PublicKey(acc.pubkey),
|
|
707
|
+
isSigner: acc.isSigner,
|
|
708
|
+
isWritable: acc.isWritable
|
|
709
|
+
}));
|
|
710
|
+
}
|
|
711
|
+
async function fetchAddressLookupTables(connection, addresses) {
|
|
712
|
+
if (addresses.length === 0) {
|
|
713
|
+
return [];
|
|
714
|
+
}
|
|
715
|
+
const pubkeys = addresses.map((addr) => new import_web37.PublicKey(addr));
|
|
716
|
+
const accountInfos = await connection.getMultipleAccountsInfo(pubkeys);
|
|
717
|
+
const tables = [];
|
|
718
|
+
for (let i = 0; i < accountInfos.length; i++) {
|
|
719
|
+
const info = accountInfos[i];
|
|
720
|
+
if (info === null) {
|
|
721
|
+
console.warn(`ALT not found: ${addresses[i]}`);
|
|
722
|
+
continue;
|
|
723
|
+
}
|
|
724
|
+
const table = new import_web37.AddressLookupTableAccount({
|
|
725
|
+
key: pubkeys[i],
|
|
726
|
+
state: import_web37.AddressLookupTableAccount.deserialize(info.data)
|
|
727
|
+
});
|
|
728
|
+
tables.push(table);
|
|
729
|
+
}
|
|
730
|
+
return tables;
|
|
731
|
+
}
|
|
732
|
+
async function buildSwapData(connection, inputMint, outputMint, amount, userPubkey, slippageBps = 50, maxAccounts = 40) {
|
|
733
|
+
const quote = await getJupiterQuote(
|
|
734
|
+
inputMint,
|
|
735
|
+
outputMint,
|
|
736
|
+
amount,
|
|
737
|
+
slippageBps,
|
|
738
|
+
maxAccounts
|
|
739
|
+
);
|
|
740
|
+
const instructions = await getJupiterSwapInstructions(quote, userPubkey);
|
|
741
|
+
const remainingAccounts = parseSwapRemainingAccounts(instructions.swapInstruction);
|
|
742
|
+
const addressLookupTables = await fetchAddressLookupTables(
|
|
743
|
+
connection,
|
|
744
|
+
instructions.addressLookupTableAddresses
|
|
745
|
+
);
|
|
746
|
+
return {
|
|
747
|
+
quote,
|
|
748
|
+
instructions,
|
|
749
|
+
remainingAccounts,
|
|
750
|
+
addressLookupTables
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// src/jupiter/price.ts
|
|
755
|
+
var import_anchor4 = require("@coral-xyz/anchor");
|
|
756
|
+
var DEFAULT_API_KEY = "9edc77aa-0be8-41cf-9264-907603c44150";
|
|
757
|
+
async function fetchJupiterPriceUsd(mint, apiKey = DEFAULT_API_KEY) {
|
|
758
|
+
const url = `https://api.jup.ag/price/v3?ids=${mint}`;
|
|
759
|
+
try {
|
|
760
|
+
const response = await fetch(url, {
|
|
761
|
+
headers: {
|
|
762
|
+
"x-api-key": apiKey
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
if (!response.ok) {
|
|
766
|
+
console.warn(`Jupiter Price API error: ${response.status}`);
|
|
767
|
+
return null;
|
|
768
|
+
}
|
|
769
|
+
const data = await response.json();
|
|
770
|
+
const priceData = data[mint];
|
|
771
|
+
if (!priceData?.usdPrice) {
|
|
772
|
+
console.warn(`No price data for ${mint}`);
|
|
773
|
+
return null;
|
|
774
|
+
}
|
|
775
|
+
return priceData.usdPrice;
|
|
776
|
+
} catch (error) {
|
|
777
|
+
console.warn(`Failed to fetch Jupiter price: ${error.message}`);
|
|
778
|
+
return null;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
async function fetchJlpRate(jlpMint, fallbackPrice = 4.6, apiKey = DEFAULT_API_KEY) {
|
|
782
|
+
const priceUsd = await fetchJupiterPriceUsd(jlpMint, apiKey);
|
|
783
|
+
if (priceUsd === null) {
|
|
784
|
+
console.warn(`Using fallback JLP price: $${fallbackPrice}`);
|
|
785
|
+
return new import_anchor4.BN(Math.round(fallbackPrice * 1e8));
|
|
786
|
+
}
|
|
787
|
+
console.log(`JLP price: $${priceUsd.toFixed(4)} -> ${Math.round(priceUsd * 1e8)} (8 decimals)`);
|
|
788
|
+
return new import_anchor4.BN(Math.round(priceUsd * 1e8));
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// src/instructions/admin.ts
|
|
792
|
+
var import_web38 = require("@solana/web3.js");
|
|
793
|
+
var INIT_OR_UPDATE_VAULT_DISCRIMINATOR = Buffer.from([
|
|
794
|
+
91,
|
|
795
|
+
101,
|
|
796
|
+
110,
|
|
797
|
+
100,
|
|
798
|
+
105,
|
|
799
|
+
110,
|
|
800
|
+
103,
|
|
801
|
+
93
|
|
802
|
+
]);
|
|
803
|
+
var INITIALIZE_STV_DISCRIMINATOR = Buffer.from([
|
|
804
|
+
105,
|
|
805
|
+
110,
|
|
806
|
+
105,
|
|
807
|
+
116,
|
|
808
|
+
95,
|
|
809
|
+
115,
|
|
810
|
+
116,
|
|
811
|
+
118
|
|
812
|
+
]);
|
|
813
|
+
var UPDATE_STV_DISCRIMINATOR = Buffer.from([
|
|
814
|
+
117,
|
|
815
|
+
112,
|
|
816
|
+
100,
|
|
817
|
+
95,
|
|
818
|
+
115,
|
|
819
|
+
116,
|
|
820
|
+
118,
|
|
821
|
+
0
|
|
822
|
+
]);
|
|
823
|
+
function serializeOptionPubkey(value) {
|
|
824
|
+
if (value === null) {
|
|
825
|
+
return Buffer.from([0]);
|
|
826
|
+
}
|
|
827
|
+
return Buffer.concat([Buffer.from([1]), value.toBuffer()]);
|
|
828
|
+
}
|
|
829
|
+
function serializeOptionU64(value) {
|
|
830
|
+
if (value === null) {
|
|
831
|
+
return Buffer.from([0]);
|
|
832
|
+
}
|
|
833
|
+
const buf = Buffer.alloc(9);
|
|
834
|
+
buf.writeUInt8(1, 0);
|
|
835
|
+
buf.writeBigUInt64LE(BigInt(value.toString()), 1);
|
|
836
|
+
return buf;
|
|
837
|
+
}
|
|
838
|
+
function serializeU16(value) {
|
|
839
|
+
const buf = Buffer.alloc(2);
|
|
840
|
+
buf.writeUInt16LE(value, 0);
|
|
841
|
+
return buf;
|
|
842
|
+
}
|
|
843
|
+
function serializeU64(value) {
|
|
844
|
+
const buf = Buffer.alloc(8);
|
|
845
|
+
buf.writeBigUInt64LE(BigInt(value.toString()), 0);
|
|
846
|
+
return buf;
|
|
847
|
+
}
|
|
848
|
+
function createInitOrUpdateVaultInstruction(params, accounts, programId = JLPD_PROGRAM_ID) {
|
|
849
|
+
const data = Buffer.concat([
|
|
850
|
+
INIT_OR_UPDATE_VAULT_DISCRIMINATOR,
|
|
851
|
+
serializeOptionPubkey(params.jlpMint),
|
|
852
|
+
// baseAssetMints - Option<[Pubkey; 5]>
|
|
853
|
+
params.baseAssetMints ? Buffer.concat([Buffer.from([1]), ...params.baseAssetMints.map((p) => p.toBuffer())]) : Buffer.from([0]),
|
|
854
|
+
// jlxAssetMints - Option<[Pubkey; 5]>
|
|
855
|
+
params.jlxAssetMints ? Buffer.concat([Buffer.from([1]), ...params.jlxAssetMints.map((p) => p.toBuffer())]) : Buffer.from([0]),
|
|
856
|
+
serializeOptionPubkey(params.newAdmin),
|
|
857
|
+
serializeOptionPubkey(params.manager ?? null),
|
|
858
|
+
serializeOptionPubkey(params.feeReceiver ?? null),
|
|
859
|
+
params.flags !== void 0 ? Buffer.concat([Buffer.from([1]), serializeU16(params.flags)]) : Buffer.from([0]),
|
|
860
|
+
params.jlpSlippageBps !== void 0 ? Buffer.concat([Buffer.from([1]), serializeU16(params.jlpSlippageBps)]) : Buffer.from([0]),
|
|
861
|
+
serializeOptionU64(params.oracleStalenessThreshold)
|
|
862
|
+
]);
|
|
863
|
+
const keys = [
|
|
864
|
+
{ pubkey: accounts.admin, isSigner: true, isWritable: true },
|
|
865
|
+
{ pubkey: accounts.jlpVault, isSigner: false, isWritable: true },
|
|
866
|
+
{ pubkey: accounts.systemProgram, isSigner: false, isWritable: false }
|
|
867
|
+
];
|
|
868
|
+
return new import_web38.TransactionInstruction({ keys, programId, data });
|
|
869
|
+
}
|
|
870
|
+
function createInitializeStvInstruction(params, accounts, programId = JLPD_PROGRAM_ID) {
|
|
871
|
+
const data = Buffer.concat([
|
|
872
|
+
INITIALIZE_STV_DISCRIMINATOR,
|
|
873
|
+
serializeU16(params.mgmtFeeBps),
|
|
874
|
+
serializeU16(params.perfFeeBps),
|
|
875
|
+
serializeU64(params.maxDeposit),
|
|
876
|
+
serializeU64(params.minDeposit)
|
|
877
|
+
]);
|
|
878
|
+
const keys = [
|
|
879
|
+
{ pubkey: accounts.admin, isSigner: true, isWritable: true },
|
|
880
|
+
{ pubkey: accounts.jlpVault, isSigner: false, isWritable: false },
|
|
881
|
+
{ pubkey: accounts.stv, isSigner: false, isWritable: true },
|
|
882
|
+
{ pubkey: accounts.baseMint, isSigner: false, isWritable: false },
|
|
883
|
+
{ pubkey: accounts.jlMint, isSigner: false, isWritable: false },
|
|
884
|
+
{ pubkey: accounts.jvMint, isSigner: true, isWritable: true },
|
|
885
|
+
{ pubkey: accounts.stvJlxAta, isSigner: false, isWritable: true },
|
|
886
|
+
{ pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
|
|
887
|
+
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
|
888
|
+
{ pubkey: accounts.associatedTokenProgram, isSigner: false, isWritable: false },
|
|
889
|
+
{ pubkey: accounts.rent, isSigner: false, isWritable: false }
|
|
890
|
+
];
|
|
891
|
+
return new import_web38.TransactionInstruction({ keys, programId, data });
|
|
892
|
+
}
|
|
893
|
+
function createUpdateStvInstruction(params, accounts, programId = JLPD_PROGRAM_ID) {
|
|
894
|
+
const data = Buffer.concat([
|
|
895
|
+
UPDATE_STV_DISCRIMINATOR,
|
|
896
|
+
params.mgmtFeeBps !== void 0 ? Buffer.concat([Buffer.from([1]), serializeU16(params.mgmtFeeBps)]) : Buffer.from([0]),
|
|
897
|
+
params.perfFeeBps !== void 0 ? Buffer.concat([Buffer.from([1]), serializeU16(params.perfFeeBps)]) : Buffer.from([0]),
|
|
898
|
+
params.flags !== void 0 ? Buffer.concat([Buffer.from([1]), serializeU16(params.flags)]) : Buffer.from([0]),
|
|
899
|
+
params.maxDeposit !== void 0 ? Buffer.concat([Buffer.from([1]), serializeU64(params.maxDeposit)]) : Buffer.from([0]),
|
|
900
|
+
params.minDeposit !== void 0 ? Buffer.concat([Buffer.from([1]), serializeU64(params.minDeposit)]) : Buffer.from([0])
|
|
901
|
+
]);
|
|
902
|
+
const keys = [
|
|
903
|
+
{ pubkey: accounts.admin, isSigner: true, isWritable: false },
|
|
904
|
+
{ pubkey: accounts.jlpVault, isSigner: false, isWritable: false },
|
|
905
|
+
{ pubkey: accounts.stv, isSigner: false, isWritable: true }
|
|
906
|
+
];
|
|
907
|
+
return new import_web38.TransactionInstruction({ keys, programId, data });
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// src/instructions/user.ts
|
|
911
|
+
var import_web39 = require("@solana/web3.js");
|
|
912
|
+
var DEPOSIT_DISCRIMINATOR = Buffer.from([
|
|
913
|
+
248,
|
|
914
|
+
198,
|
|
915
|
+
158,
|
|
916
|
+
145,
|
|
917
|
+
225,
|
|
918
|
+
117,
|
|
919
|
+
135,
|
|
920
|
+
200
|
|
921
|
+
]);
|
|
922
|
+
var WITHDRAW_DISCRIMINATOR = Buffer.from([
|
|
923
|
+
183,
|
|
924
|
+
18,
|
|
925
|
+
70,
|
|
926
|
+
156,
|
|
927
|
+
148,
|
|
928
|
+
109,
|
|
929
|
+
161,
|
|
930
|
+
34
|
|
931
|
+
]);
|
|
932
|
+
function serializeU642(value) {
|
|
933
|
+
const buf = Buffer.alloc(8);
|
|
934
|
+
buf.writeBigUInt64LE(BigInt(value.toString()), 0);
|
|
935
|
+
return buf;
|
|
936
|
+
}
|
|
937
|
+
function createDepositInstruction(amount, accounts, remainingAccounts = [], programId = JLPD_PROGRAM_ID) {
|
|
938
|
+
const data = Buffer.concat([DEPOSIT_DISCRIMINATOR, serializeU642(amount)]);
|
|
939
|
+
const keys = [
|
|
940
|
+
{ pubkey: accounts.user, isSigner: true, isWritable: true },
|
|
941
|
+
{ pubkey: accounts.jlpVault, isSigner: false, isWritable: false },
|
|
942
|
+
{ pubkey: accounts.stv, isSigner: false, isWritable: true },
|
|
943
|
+
{ pubkey: accounts.baseMint, isSigner: false, isWritable: false },
|
|
944
|
+
{ pubkey: accounts.jlMint, isSigner: false, isWritable: false },
|
|
945
|
+
{ pubkey: accounts.jvMint, isSigner: false, isWritable: true },
|
|
946
|
+
{ pubkey: accounts.userBaseAta, isSigner: false, isWritable: true },
|
|
947
|
+
{ pubkey: accounts.userJvxAta, isSigner: false, isWritable: true },
|
|
948
|
+
{ pubkey: accounts.stvBaseAta, isSigner: false, isWritable: true },
|
|
949
|
+
{ pubkey: accounts.stvJlxAta, isSigner: false, isWritable: false },
|
|
950
|
+
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
|
951
|
+
...remainingAccounts
|
|
952
|
+
];
|
|
953
|
+
return new import_web39.TransactionInstruction({ keys, programId, data });
|
|
954
|
+
}
|
|
955
|
+
function createWithdrawInstruction(sharesToBurn, accounts, remainingAccounts = [], programId = JLPD_PROGRAM_ID) {
|
|
956
|
+
const data = Buffer.concat([WITHDRAW_DISCRIMINATOR, serializeU642(sharesToBurn)]);
|
|
957
|
+
const keys = [
|
|
958
|
+
{ pubkey: accounts.user, isSigner: true, isWritable: true },
|
|
959
|
+
{ pubkey: accounts.jlpVault, isSigner: false, isWritable: false },
|
|
960
|
+
{ pubkey: accounts.stv, isSigner: false, isWritable: true },
|
|
961
|
+
{ pubkey: accounts.baseMint, isSigner: false, isWritable: false },
|
|
962
|
+
{ pubkey: accounts.jlMint, isSigner: false, isWritable: false },
|
|
963
|
+
{ pubkey: accounts.jvMint, isSigner: false, isWritable: true },
|
|
964
|
+
{ pubkey: accounts.userBaseAta, isSigner: false, isWritable: true },
|
|
965
|
+
{ pubkey: accounts.userJvxAta, isSigner: false, isWritable: true },
|
|
966
|
+
{ pubkey: accounts.stvBaseAta, isSigner: false, isWritable: true },
|
|
967
|
+
{ pubkey: accounts.stvJlxAta, isSigner: false, isWritable: false },
|
|
968
|
+
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
|
969
|
+
...remainingAccounts
|
|
970
|
+
];
|
|
971
|
+
return new import_web39.TransactionInstruction({ keys, programId, data });
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
// src/instructions/manager.ts
|
|
975
|
+
var import_web310 = require("@solana/web3.js");
|
|
976
|
+
var JUP_EARN_DISCRIMINATOR = Buffer.from([
|
|
977
|
+
161,
|
|
978
|
+
178,
|
|
979
|
+
195,
|
|
980
|
+
212,
|
|
981
|
+
229,
|
|
982
|
+
246,
|
|
983
|
+
7,
|
|
984
|
+
24
|
|
985
|
+
]);
|
|
986
|
+
var MOVE_STV_DISCRIMINATOR = Buffer.from([
|
|
987
|
+
41,
|
|
988
|
+
58,
|
|
989
|
+
75,
|
|
990
|
+
92,
|
|
991
|
+
109,
|
|
992
|
+
126,
|
|
993
|
+
143,
|
|
994
|
+
144
|
|
995
|
+
]);
|
|
996
|
+
var SWAP_JLX_JLX_DISCRIMINATOR = Buffer.from([
|
|
997
|
+
65,
|
|
998
|
+
82,
|
|
999
|
+
99,
|
|
1000
|
+
116,
|
|
1001
|
+
133,
|
|
1002
|
+
150,
|
|
1003
|
+
167,
|
|
1004
|
+
184
|
|
1005
|
+
]);
|
|
1006
|
+
var SWAP_JLX_JLP_DISCRIMINATOR = Buffer.from([
|
|
1007
|
+
201,
|
|
1008
|
+
218,
|
|
1009
|
+
235,
|
|
1010
|
+
252,
|
|
1011
|
+
13,
|
|
1012
|
+
30,
|
|
1013
|
+
47,
|
|
1014
|
+
48
|
|
1015
|
+
]);
|
|
1016
|
+
var SETTLE_YIELD_DISCRIMINATOR = Buffer.from([
|
|
1017
|
+
81,
|
|
1018
|
+
98,
|
|
1019
|
+
115,
|
|
1020
|
+
132,
|
|
1021
|
+
149,
|
|
1022
|
+
166,
|
|
1023
|
+
183,
|
|
1024
|
+
200
|
|
1025
|
+
]);
|
|
1026
|
+
function serializeU8(value) {
|
|
1027
|
+
const buf = Buffer.alloc(1);
|
|
1028
|
+
buf.writeUInt8(value, 0);
|
|
1029
|
+
return buf;
|
|
1030
|
+
}
|
|
1031
|
+
function serializeU643(value) {
|
|
1032
|
+
const buf = Buffer.alloc(8);
|
|
1033
|
+
buf.writeBigUInt64LE(BigInt(value.toString()), 0);
|
|
1034
|
+
return buf;
|
|
1035
|
+
}
|
|
1036
|
+
function createJupEarnInstruction(params, accounts, remainingAccounts = [], programId = JLPD_PROGRAM_ID) {
|
|
1037
|
+
const directionByte = params.direction === "Deposit" ? 0 : 1;
|
|
1038
|
+
const data = Buffer.concat([
|
|
1039
|
+
JUP_EARN_DISCRIMINATOR,
|
|
1040
|
+
serializeU8(directionByte),
|
|
1041
|
+
serializeU643(params.amount)
|
|
1042
|
+
]);
|
|
1043
|
+
const keys = [
|
|
1044
|
+
{ pubkey: accounts.manager, isSigner: true, isWritable: false },
|
|
1045
|
+
{ pubkey: accounts.jlpVault, isSigner: false, isWritable: false },
|
|
1046
|
+
{ pubkey: accounts.stv, isSigner: false, isWritable: false },
|
|
1047
|
+
{ pubkey: accounts.baseMint, isSigner: false, isWritable: false },
|
|
1048
|
+
{ pubkey: accounts.jlMint, isSigner: false, isWritable: true },
|
|
1049
|
+
{ pubkey: accounts.stvBaseAta, isSigner: false, isWritable: true },
|
|
1050
|
+
{ pubkey: accounts.stvJlxAta, isSigner: false, isWritable: true },
|
|
1051
|
+
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
|
1052
|
+
...remainingAccounts
|
|
1053
|
+
];
|
|
1054
|
+
return new import_web310.TransactionInstruction({ keys, programId, data });
|
|
1055
|
+
}
|
|
1056
|
+
function createMoveJlxInstruction(params, accounts, remainingAccounts = [], programId = JLPD_PROGRAM_ID) {
|
|
1057
|
+
const directionByte = params.direction === "ToVault" ? 0 : 1;
|
|
1058
|
+
const data = Buffer.concat([
|
|
1059
|
+
MOVE_STV_DISCRIMINATOR,
|
|
1060
|
+
serializeU643(params.amountJlx),
|
|
1061
|
+
serializeU8(directionByte)
|
|
1062
|
+
]);
|
|
1063
|
+
const keys = [
|
|
1064
|
+
{ pubkey: accounts.manager, isSigner: true, isWritable: false },
|
|
1065
|
+
{ pubkey: accounts.jlpVault, isSigner: false, isWritable: false },
|
|
1066
|
+
{ pubkey: accounts.stv, isSigner: false, isWritable: true },
|
|
1067
|
+
{ pubkey: accounts.baseMint, isSigner: false, isWritable: false },
|
|
1068
|
+
{ pubkey: accounts.jlMint, isSigner: false, isWritable: false },
|
|
1069
|
+
{ pubkey: accounts.stvJlxAta, isSigner: false, isWritable: true },
|
|
1070
|
+
{ pubkey: accounts.vaultStagingAta, isSigner: false, isWritable: true },
|
|
1071
|
+
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
|
1072
|
+
...remainingAccounts
|
|
1073
|
+
];
|
|
1074
|
+
return new import_web310.TransactionInstruction({ keys, programId, data });
|
|
1075
|
+
}
|
|
1076
|
+
function createSwapJlxJlxInstruction(params, accounts, remainingAccounts = [], programId = JLPD_PROGRAM_ID) {
|
|
1077
|
+
const lenBuf = Buffer.alloc(4);
|
|
1078
|
+
lenBuf.writeUInt32LE(params.jupiterData.length, 0);
|
|
1079
|
+
const data = Buffer.concat([
|
|
1080
|
+
SWAP_JLX_JLX_DISCRIMINATOR,
|
|
1081
|
+
serializeU8(params.fromIndex),
|
|
1082
|
+
serializeU8(params.toIndex),
|
|
1083
|
+
serializeU643(params.amountIn),
|
|
1084
|
+
serializeU643(params.minOut),
|
|
1085
|
+
lenBuf,
|
|
1086
|
+
params.jupiterData
|
|
1087
|
+
]);
|
|
1088
|
+
const keys = [
|
|
1089
|
+
{ pubkey: accounts.manager, isSigner: true, isWritable: false },
|
|
1090
|
+
{ pubkey: accounts.jlpVault, isSigner: false, isWritable: false },
|
|
1091
|
+
{ pubkey: accounts.fromJlxMint, isSigner: false, isWritable: false },
|
|
1092
|
+
{ pubkey: accounts.toJlxMint, isSigner: false, isWritable: false },
|
|
1093
|
+
{ pubkey: accounts.fromJlxAta, isSigner: false, isWritable: true },
|
|
1094
|
+
{ pubkey: accounts.toJlxAta, isSigner: false, isWritable: true },
|
|
1095
|
+
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
|
1096
|
+
{ pubkey: accounts.jupiterProgram, isSigner: false, isWritable: false },
|
|
1097
|
+
...remainingAccounts
|
|
1098
|
+
];
|
|
1099
|
+
return new import_web310.TransactionInstruction({ keys, programId, data });
|
|
1100
|
+
}
|
|
1101
|
+
function createSwapJlxJlpInstruction(params, accounts, remainingAccounts = [], programId = JLPD_PROGRAM_ID) {
|
|
1102
|
+
const directionByte = params.direction === "JlxToJlp" ? 0 : 1;
|
|
1103
|
+
const lenBuf = Buffer.alloc(4);
|
|
1104
|
+
lenBuf.writeUInt32LE(params.jupiterData.length, 0);
|
|
1105
|
+
const data = Buffer.concat([
|
|
1106
|
+
SWAP_JLX_JLP_DISCRIMINATOR,
|
|
1107
|
+
serializeU8(params.stvIndex),
|
|
1108
|
+
serializeU8(directionByte),
|
|
1109
|
+
serializeU643(params.amountIn),
|
|
1110
|
+
serializeU643(params.expectedAmountOut),
|
|
1111
|
+
lenBuf,
|
|
1112
|
+
params.jupiterData
|
|
1113
|
+
]);
|
|
1114
|
+
const keys = [
|
|
1115
|
+
{ pubkey: accounts.manager, isSigner: true, isWritable: false },
|
|
1116
|
+
{ pubkey: accounts.jlpVault, isSigner: false, isWritable: false },
|
|
1117
|
+
{ pubkey: accounts.vaultJlxAta, isSigner: false, isWritable: true },
|
|
1118
|
+
{ pubkey: accounts.vaultJlpAta, isSigner: false, isWritable: true },
|
|
1119
|
+
{ pubkey: accounts.jlpMint, isSigner: false, isWritable: false },
|
|
1120
|
+
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
|
1121
|
+
{ pubkey: accounts.jupiterProgram, isSigner: false, isWritable: false },
|
|
1122
|
+
...remainingAccounts
|
|
1123
|
+
];
|
|
1124
|
+
return new import_web310.TransactionInstruction({ keys, programId, data });
|
|
1125
|
+
}
|
|
1126
|
+
function createSettleYieldInstruction(params, accounts, remainingAccounts = [], programId = JLPD_PROGRAM_ID) {
|
|
1127
|
+
const data = Buffer.concat([
|
|
1128
|
+
SETTLE_YIELD_DISCRIMINATOR,
|
|
1129
|
+
serializeU643(params.jlpRate)
|
|
1130
|
+
]);
|
|
1131
|
+
const keys = [
|
|
1132
|
+
{ pubkey: accounts.manager, isSigner: true, isWritable: false },
|
|
1133
|
+
{ pubkey: accounts.jlpVault, isSigner: false, isWritable: true },
|
|
1134
|
+
{ pubkey: accounts.vaultJlpAta, isSigner: false, isWritable: false },
|
|
1135
|
+
{ pubkey: accounts.jlpMint, isSigner: false, isWritable: false },
|
|
1136
|
+
{ pubkey: accounts.stvBtc, isSigner: false, isWritable: true },
|
|
1137
|
+
{ pubkey: accounts.stvEth, isSigner: false, isWritable: true },
|
|
1138
|
+
{ pubkey: accounts.stvSol, isSigner: false, isWritable: true },
|
|
1139
|
+
{ pubkey: accounts.stvUsdc, isSigner: false, isWritable: true },
|
|
1140
|
+
{ pubkey: accounts.stvJupusd, isSigner: false, isWritable: true },
|
|
1141
|
+
{ pubkey: accounts.stagingBtc, isSigner: false, isWritable: false },
|
|
1142
|
+
{ pubkey: accounts.stagingEth, isSigner: false, isWritable: false },
|
|
1143
|
+
{ pubkey: accounts.stagingSol, isSigner: false, isWritable: false },
|
|
1144
|
+
{ pubkey: accounts.stagingUsdc, isSigner: false, isWritable: false },
|
|
1145
|
+
{ pubkey: accounts.stagingJupusd, isSigner: false, isWritable: false },
|
|
1146
|
+
{ pubkey: accounts.oracleBtc, isSigner: false, isWritable: false },
|
|
1147
|
+
{ pubkey: accounts.oracleEth, isSigner: false, isWritable: false },
|
|
1148
|
+
{ pubkey: accounts.oracleSol, isSigner: false, isWritable: false },
|
|
1149
|
+
{ pubkey: accounts.oracleJlp, isSigner: false, isWritable: false },
|
|
1150
|
+
...remainingAccounts
|
|
1151
|
+
];
|
|
1152
|
+
return new import_web310.TransactionInstruction({ keys, programId, data });
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
// src/instructions/fees.ts
|
|
1156
|
+
var import_web311 = require("@solana/web3.js");
|
|
1157
|
+
var CLAIM_FEES_DISCRIMINATOR = Buffer.from([
|
|
1158
|
+
209,
|
|
1159
|
+
226,
|
|
1160
|
+
243,
|
|
1161
|
+
4,
|
|
1162
|
+
21,
|
|
1163
|
+
38,
|
|
1164
|
+
55,
|
|
1165
|
+
72
|
|
1166
|
+
]);
|
|
1167
|
+
function createClaimFeesInstruction(accounts, remainingAccounts = [], programId = JLPD_PROGRAM_ID) {
|
|
1168
|
+
const data = CLAIM_FEES_DISCRIMINATOR;
|
|
1169
|
+
const keys = [
|
|
1170
|
+
{ pubkey: accounts.manager, isSigner: true, isWritable: false },
|
|
1171
|
+
{ pubkey: accounts.jlpVault, isSigner: false, isWritable: false },
|
|
1172
|
+
{ pubkey: accounts.stv, isSigner: false, isWritable: true },
|
|
1173
|
+
{ pubkey: accounts.baseMint, isSigner: false, isWritable: false },
|
|
1174
|
+
{ pubkey: accounts.jlMint, isSigner: false, isWritable: false },
|
|
1175
|
+
{ pubkey: accounts.jvMint, isSigner: false, isWritable: false },
|
|
1176
|
+
{ pubkey: accounts.stvBaseAta, isSigner: false, isWritable: false },
|
|
1177
|
+
{ pubkey: accounts.stvJlxAta, isSigner: false, isWritable: true },
|
|
1178
|
+
{ pubkey: accounts.feeReceiverJlxAta, isSigner: false, isWritable: true },
|
|
1179
|
+
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
|
1180
|
+
...remainingAccounts
|
|
1181
|
+
];
|
|
1182
|
+
return new import_web311.TransactionInstruction({ keys, programId, data });
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
// src/client.ts
|
|
1186
|
+
var JlpdClientError = class extends Error {
|
|
1187
|
+
constructor(message) {
|
|
1188
|
+
super(message);
|
|
1189
|
+
this.name = "JlpdClientError";
|
|
1190
|
+
}
|
|
1191
|
+
};
|
|
1192
|
+
var JlpdClient = class _JlpdClient {
|
|
1193
|
+
constructor(connection, programId = JLPD_PROGRAM_ID) {
|
|
1194
|
+
// Cache for PoolContext instances (avoids re-deriving PDAs/ATAs)
|
|
1195
|
+
this.poolContextCache = /* @__PURE__ */ new Map();
|
|
1196
|
+
this.connection = connection;
|
|
1197
|
+
this.programId = programId;
|
|
1198
|
+
const [vaultPda, vaultBump] = deriveVaultPda(programId);
|
|
1199
|
+
this.vaultPda = vaultPda;
|
|
1200
|
+
this.vaultBump = vaultBump;
|
|
1201
|
+
}
|
|
1202
|
+
static mainnet(connection) {
|
|
1203
|
+
return new _JlpdClient(connection, JLPD_PROGRAM_ID);
|
|
1204
|
+
}
|
|
1205
|
+
static devnet(connection) {
|
|
1206
|
+
const devnetProgramId = new import_web312.PublicKey(
|
|
1207
|
+
"AcVcAihjB9Z3Lg3ZiboWxni2sTzXUrrsF3unGX4ntn6p"
|
|
1208
|
+
);
|
|
1209
|
+
return new _JlpdClient(connection, devnetProgramId);
|
|
1210
|
+
}
|
|
1211
|
+
// Fetch vault account
|
|
1212
|
+
async fetchVault() {
|
|
1213
|
+
const accountInfo = await this.connection.getAccountInfo(this.vaultPda);
|
|
1214
|
+
if (!accountInfo) return null;
|
|
1215
|
+
return parseVault(accountInfo.data);
|
|
1216
|
+
}
|
|
1217
|
+
// Fetch STV by base mint
|
|
1218
|
+
async fetchStv(baseMint) {
|
|
1219
|
+
const [stvPda] = deriveStvPda(baseMint, this.programId);
|
|
1220
|
+
const accountInfo = await this.connection.getAccountInfo(stvPda);
|
|
1221
|
+
if (!accountInfo) return null;
|
|
1222
|
+
return parseStv(accountInfo.data);
|
|
1223
|
+
}
|
|
1224
|
+
// Fetch exchange rate for a pool
|
|
1225
|
+
async fetchExchangeRate(poolName) {
|
|
1226
|
+
const pool = getPoolByName(poolName);
|
|
1227
|
+
if (!pool) throw new JlpdClientError(`Unknown pool: ${poolName}`);
|
|
1228
|
+
if (!pool.hasJupiterLend) {
|
|
1229
|
+
return {
|
|
1230
|
+
rate: 1,
|
|
1231
|
+
rawRate: BigInt(EXCHANGE_RATE_PRECISION),
|
|
1232
|
+
storedRate: 1,
|
|
1233
|
+
staleness: 0,
|
|
1234
|
+
isFresh: true
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1237
|
+
const accounts = await this.connection.getMultipleAccountsInfo([
|
|
1238
|
+
pool.lending,
|
|
1239
|
+
pool.rewardsRateModel,
|
|
1240
|
+
pool.fTokenMint
|
|
1241
|
+
]);
|
|
1242
|
+
const [lendingInfo, rewardsInfo, mintInfo] = accounts;
|
|
1243
|
+
if (!lendingInfo || !rewardsInfo || !mintInfo) {
|
|
1244
|
+
throw new JlpdClientError("Failed to fetch Jupiter Lend accounts");
|
|
1245
|
+
}
|
|
1246
|
+
const lendingData = parseLendingAccount(lendingInfo.data);
|
|
1247
|
+
const rewardsData = parseRewardsRateModel(rewardsInfo.data);
|
|
1248
|
+
const slot = await this.connection.getSlot();
|
|
1249
|
+
const timestamp = await this.connection.getBlockTime(slot);
|
|
1250
|
+
if (!timestamp) throw new JlpdClientError("Failed to get block time");
|
|
1251
|
+
const supply = mintInfo.data.readBigUInt64LE(36);
|
|
1252
|
+
const rawRate = calculateExchangeRate(
|
|
1253
|
+
lendingData.tokenExchangePrice,
|
|
1254
|
+
rewardsData.yearlyReward,
|
|
1255
|
+
BigInt(timestamp),
|
|
1256
|
+
lendingData.lastUpdateTimestamp,
|
|
1257
|
+
supply
|
|
1258
|
+
);
|
|
1259
|
+
const rate = Number(rawRate) / EXCHANGE_RATE_PRECISION;
|
|
1260
|
+
const storedRate = Number(lendingData.tokenExchangePrice) / EXCHANGE_RATE_PRECISION;
|
|
1261
|
+
const staleness = timestamp - Number(lendingData.lastUpdateTimestamp);
|
|
1262
|
+
return {
|
|
1263
|
+
rate,
|
|
1264
|
+
rawRate,
|
|
1265
|
+
storedRate,
|
|
1266
|
+
staleness,
|
|
1267
|
+
isFresh: staleness < 300
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
// Get pool context for pool-specific operations (cached)
|
|
1271
|
+
pool(poolNameOrMint) {
|
|
1272
|
+
const key = typeof poolNameOrMint === "string" ? poolNameOrMint : poolNameOrMint.toBase58();
|
|
1273
|
+
let ctx = this.poolContextCache.get(key);
|
|
1274
|
+
if (!ctx) {
|
|
1275
|
+
const pool = typeof poolNameOrMint === "string" ? getPoolByName(poolNameOrMint) : getPoolByMint(poolNameOrMint);
|
|
1276
|
+
if (!pool) throw new JlpdClientError(`Unknown pool: ${key}`);
|
|
1277
|
+
ctx = new PoolContext(this, pool);
|
|
1278
|
+
this.poolContextCache.set(key, ctx);
|
|
1279
|
+
if (typeof poolNameOrMint === "string") {
|
|
1280
|
+
this.poolContextCache.set(pool.mint.toBase58(), ctx);
|
|
1281
|
+
} else {
|
|
1282
|
+
this.poolContextCache.set(pool.name, ctx);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
return ctx;
|
|
1286
|
+
}
|
|
1287
|
+
// Get swap context for swap operations
|
|
1288
|
+
swap() {
|
|
1289
|
+
return new SwapContext(this);
|
|
1290
|
+
}
|
|
1291
|
+
// Get admin context for admin operations
|
|
1292
|
+
admin() {
|
|
1293
|
+
return new AdminContext(this);
|
|
1294
|
+
}
|
|
1295
|
+
// Build a versioned transaction
|
|
1296
|
+
async buildTransaction(payer, ixs, alts = []) {
|
|
1297
|
+
const { blockhash } = await this.connection.getLatestBlockhash("confirmed");
|
|
1298
|
+
const message = new import_web312.TransactionMessage({
|
|
1299
|
+
payerKey: payer,
|
|
1300
|
+
recentBlockhash: blockhash,
|
|
1301
|
+
instructions: ixs
|
|
1302
|
+
}).compileToV0Message(alts);
|
|
1303
|
+
return new import_web312.VersionedTransaction(message);
|
|
1304
|
+
}
|
|
1305
|
+
};
|
|
1306
|
+
var PoolContext = class {
|
|
1307
|
+
constructor(client, pool) {
|
|
1308
|
+
this.client = client;
|
|
1309
|
+
this.pool = pool;
|
|
1310
|
+
const [pda, bump] = deriveStvPda(pool.mint, client.programId);
|
|
1311
|
+
this.stvPda = pda;
|
|
1312
|
+
this.stvBump = bump;
|
|
1313
|
+
const vaultAtas = deriveVaultAtas(pool.fTokenMint, MINTS.JLP, client.vaultPda);
|
|
1314
|
+
this.vaultStagingAta = vaultAtas.stagingAta;
|
|
1315
|
+
this.vaultJlpAta = vaultAtas.jlpAta;
|
|
1316
|
+
const stvAtas = deriveStvAtas(pool.mint, pool.fTokenMint, this.stvPda);
|
|
1317
|
+
this.stvBaseAta = stvAtas.baseAta;
|
|
1318
|
+
this.stvJlxAta = stvAtas.jlxAta;
|
|
1319
|
+
}
|
|
1320
|
+
// Deposit base asset and receive jvX shares
|
|
1321
|
+
async deposit(params) {
|
|
1322
|
+
if (params.amount.isZero() || params.amount.isNeg()) {
|
|
1323
|
+
throw new JlpdClientError("Deposit amount must be positive");
|
|
1324
|
+
}
|
|
1325
|
+
const [stv, { blockhash }] = await Promise.all([
|
|
1326
|
+
this.client.fetchStv(this.pool.mint),
|
|
1327
|
+
this.client.connection.getLatestBlockhash("confirmed")
|
|
1328
|
+
]);
|
|
1329
|
+
if (!stv) throw new JlpdClientError("STV not found");
|
|
1330
|
+
const userAtas = deriveUserAtas(this.pool.mint, stv.jvMint, params.user);
|
|
1331
|
+
const erAccounts = this.pool.hasJupiterLend ? buildExchangeRateAccounts(this.pool) : null;
|
|
1332
|
+
const ix = createDepositInstruction(
|
|
1333
|
+
params.amount,
|
|
1334
|
+
{
|
|
1335
|
+
user: params.user,
|
|
1336
|
+
jlpVault: this.client.vaultPda,
|
|
1337
|
+
stv: this.stvPda,
|
|
1338
|
+
baseMint: this.pool.mint,
|
|
1339
|
+
jlMint: this.pool.fTokenMint,
|
|
1340
|
+
jvMint: stv.jvMint,
|
|
1341
|
+
userBaseAta: userAtas.baseAta,
|
|
1342
|
+
userJvxAta: userAtas.jvxAta,
|
|
1343
|
+
stvBaseAta: this.stvBaseAta,
|
|
1344
|
+
stvJlxAta: this.stvJlxAta,
|
|
1345
|
+
tokenProgram: import_spl_token5.TOKEN_PROGRAM_ID
|
|
1346
|
+
},
|
|
1347
|
+
erAccounts ? [
|
|
1348
|
+
{ pubkey: erAccounts.lending, isSigner: false, isWritable: false },
|
|
1349
|
+
{ pubkey: erAccounts.rewardsRateModel, isSigner: false, isWritable: false }
|
|
1350
|
+
] : [],
|
|
1351
|
+
this.client.programId
|
|
1352
|
+
);
|
|
1353
|
+
const message = new import_web312.TransactionMessage({
|
|
1354
|
+
payerKey: params.user,
|
|
1355
|
+
recentBlockhash: blockhash,
|
|
1356
|
+
instructions: [ix]
|
|
1357
|
+
}).compileToV0Message();
|
|
1358
|
+
return new import_web312.VersionedTransaction(message);
|
|
1359
|
+
}
|
|
1360
|
+
// Burn jvX shares and withdraw base asset
|
|
1361
|
+
async withdraw(params) {
|
|
1362
|
+
if (params.shares.isZero() || params.shares.isNeg()) {
|
|
1363
|
+
throw new JlpdClientError("Withdraw shares must be positive");
|
|
1364
|
+
}
|
|
1365
|
+
const [stv, { blockhash }] = await Promise.all([
|
|
1366
|
+
this.client.fetchStv(this.pool.mint),
|
|
1367
|
+
this.client.connection.getLatestBlockhash("confirmed")
|
|
1368
|
+
]);
|
|
1369
|
+
if (!stv) throw new JlpdClientError("STV not found");
|
|
1370
|
+
const userAtas = deriveUserAtas(this.pool.mint, stv.jvMint, params.user);
|
|
1371
|
+
const erAccounts = this.pool.hasJupiterLend ? buildExchangeRateAccounts(this.pool) : null;
|
|
1372
|
+
const ix = createWithdrawInstruction(
|
|
1373
|
+
params.shares,
|
|
1374
|
+
{
|
|
1375
|
+
user: params.user,
|
|
1376
|
+
jlpVault: this.client.vaultPda,
|
|
1377
|
+
stv: this.stvPda,
|
|
1378
|
+
baseMint: this.pool.mint,
|
|
1379
|
+
jlMint: this.pool.fTokenMint,
|
|
1380
|
+
jvMint: stv.jvMint,
|
|
1381
|
+
userBaseAta: userAtas.baseAta,
|
|
1382
|
+
userJvxAta: userAtas.jvxAta,
|
|
1383
|
+
stvBaseAta: this.stvBaseAta,
|
|
1384
|
+
stvJlxAta: this.stvJlxAta,
|
|
1385
|
+
tokenProgram: import_spl_token5.TOKEN_PROGRAM_ID
|
|
1386
|
+
},
|
|
1387
|
+
erAccounts ? [
|
|
1388
|
+
{ pubkey: erAccounts.lending, isSigner: false, isWritable: false },
|
|
1389
|
+
{ pubkey: erAccounts.rewardsRateModel, isSigner: false, isWritable: false }
|
|
1390
|
+
] : [],
|
|
1391
|
+
this.client.programId
|
|
1392
|
+
);
|
|
1393
|
+
const message = new import_web312.TransactionMessage({
|
|
1394
|
+
payerKey: params.user,
|
|
1395
|
+
recentBlockhash: blockhash,
|
|
1396
|
+
instructions: [ix]
|
|
1397
|
+
}).compileToV0Message();
|
|
1398
|
+
return new import_web312.VersionedTransaction(message);
|
|
1399
|
+
}
|
|
1400
|
+
// Jupiter Earn deposit/withdraw
|
|
1401
|
+
async jupEarn(params) {
|
|
1402
|
+
if (!this.pool.hasJupiterLend) {
|
|
1403
|
+
throw new JlpdClientError(`Pool ${this.pool.name} does not support Jupiter Earn`);
|
|
1404
|
+
}
|
|
1405
|
+
const remainingAccounts = params.direction === "Deposit" ? buildJupEarnDepositAccounts(this.pool, this.stvPda, this.stvBaseAta, this.stvJlxAta) : buildJupEarnWithdrawAccounts(this.pool, this.stvPda, this.stvJlxAta, this.stvBaseAta);
|
|
1406
|
+
const ix = createJupEarnInstruction(
|
|
1407
|
+
{ direction: params.direction, amount: params.amount },
|
|
1408
|
+
{
|
|
1409
|
+
manager: params.manager,
|
|
1410
|
+
jlpVault: this.client.vaultPda,
|
|
1411
|
+
stv: this.stvPda,
|
|
1412
|
+
baseMint: this.pool.mint,
|
|
1413
|
+
jlMint: this.pool.fTokenMint,
|
|
1414
|
+
stvBaseAta: this.stvBaseAta,
|
|
1415
|
+
stvJlxAta: this.stvJlxAta,
|
|
1416
|
+
tokenProgram: import_spl_token5.TOKEN_PROGRAM_ID
|
|
1417
|
+
},
|
|
1418
|
+
remainingAccounts,
|
|
1419
|
+
this.client.programId
|
|
1420
|
+
);
|
|
1421
|
+
return this.client.buildTransaction(params.manager, [ix]);
|
|
1422
|
+
}
|
|
1423
|
+
// Move jlX between STV and vault
|
|
1424
|
+
async moveJlx(params) {
|
|
1425
|
+
const erAccounts = this.pool.hasJupiterLend ? buildExchangeRateAccounts(this.pool) : null;
|
|
1426
|
+
const ix = createMoveJlxInstruction(
|
|
1427
|
+
{ amountJlx: params.jlxAmount, direction: params.direction },
|
|
1428
|
+
{
|
|
1429
|
+
manager: params.manager,
|
|
1430
|
+
jlpVault: this.client.vaultPda,
|
|
1431
|
+
stv: this.stvPda,
|
|
1432
|
+
baseMint: this.pool.mint,
|
|
1433
|
+
jlMint: this.pool.fTokenMint,
|
|
1434
|
+
stvJlxAta: this.stvJlxAta,
|
|
1435
|
+
vaultStagingAta: this.vaultStagingAta,
|
|
1436
|
+
tokenProgram: import_spl_token5.TOKEN_PROGRAM_ID
|
|
1437
|
+
},
|
|
1438
|
+
erAccounts ? [
|
|
1439
|
+
{ pubkey: erAccounts.lending, isSigner: false, isWritable: false },
|
|
1440
|
+
{ pubkey: erAccounts.rewardsRateModel, isSigner: false, isWritable: false }
|
|
1441
|
+
] : [],
|
|
1442
|
+
this.client.programId
|
|
1443
|
+
);
|
|
1444
|
+
return this.client.buildTransaction(params.manager, [ix]);
|
|
1445
|
+
}
|
|
1446
|
+
// Claim fees
|
|
1447
|
+
async claimFees(params) {
|
|
1448
|
+
const [vault, stv] = await Promise.all([
|
|
1449
|
+
this.client.fetchVault(),
|
|
1450
|
+
this.client.fetchStv(this.pool.mint)
|
|
1451
|
+
]);
|
|
1452
|
+
if (!vault) throw new JlpdClientError("Vault not found");
|
|
1453
|
+
if (!stv) throw new JlpdClientError("STV not found");
|
|
1454
|
+
const feeReceiverJlxAta = (0, import_spl_token5.getAssociatedTokenAddressSync)(
|
|
1455
|
+
this.pool.fTokenMint,
|
|
1456
|
+
vault.feeReceiver,
|
|
1457
|
+
true
|
|
1458
|
+
);
|
|
1459
|
+
const erAccounts = this.pool.hasJupiterLend ? buildExchangeRateAccounts(this.pool) : null;
|
|
1460
|
+
const ix = createClaimFeesInstruction(
|
|
1461
|
+
{
|
|
1462
|
+
manager: params.manager,
|
|
1463
|
+
jlpVault: this.client.vaultPda,
|
|
1464
|
+
stv: this.stvPda,
|
|
1465
|
+
baseMint: this.pool.mint,
|
|
1466
|
+
jlMint: this.pool.fTokenMint,
|
|
1467
|
+
jvMint: stv.jvMint,
|
|
1468
|
+
stvBaseAta: this.stvBaseAta,
|
|
1469
|
+
stvJlxAta: this.stvJlxAta,
|
|
1470
|
+
feeReceiverJlxAta,
|
|
1471
|
+
tokenProgram: import_spl_token5.TOKEN_PROGRAM_ID
|
|
1472
|
+
},
|
|
1473
|
+
erAccounts ? [
|
|
1474
|
+
{ pubkey: erAccounts.lending, isSigner: false, isWritable: false },
|
|
1475
|
+
{ pubkey: erAccounts.rewardsRateModel, isSigner: false, isWritable: false }
|
|
1476
|
+
] : [],
|
|
1477
|
+
this.client.programId
|
|
1478
|
+
);
|
|
1479
|
+
return this.client.buildTransaction(params.manager, [ix]);
|
|
1480
|
+
}
|
|
1481
|
+
// Update STV parameters (admin only)
|
|
1482
|
+
async updateStv(params) {
|
|
1483
|
+
const ix = createUpdateStvInstruction(
|
|
1484
|
+
{
|
|
1485
|
+
mgmtFeeBps: params.mgmtFeeBps,
|
|
1486
|
+
perfFeeBps: params.perfFeeBps,
|
|
1487
|
+
flags: params.flags,
|
|
1488
|
+
maxDeposit: params.maxDeposit,
|
|
1489
|
+
minDeposit: params.minDeposit
|
|
1490
|
+
},
|
|
1491
|
+
{
|
|
1492
|
+
admin: params.admin,
|
|
1493
|
+
jlpVault: this.client.vaultPda,
|
|
1494
|
+
stv: this.stvPda
|
|
1495
|
+
},
|
|
1496
|
+
this.client.programId
|
|
1497
|
+
);
|
|
1498
|
+
return this.client.buildTransaction(params.admin, [ix]);
|
|
1499
|
+
}
|
|
1500
|
+
};
|
|
1501
|
+
var SwapContext = class {
|
|
1502
|
+
constructor(client) {
|
|
1503
|
+
this.client = client;
|
|
1504
|
+
}
|
|
1505
|
+
// Get a quote for jlX <-> JLP swap
|
|
1506
|
+
async quoteJlxJlp(params) {
|
|
1507
|
+
const poolConfig = getPoolByName(params.pool);
|
|
1508
|
+
if (!poolConfig) throw new JlpdClientError(`Unknown pool: ${params.pool}`);
|
|
1509
|
+
const inputMint = params.direction === "JlxToJlp" ? poolConfig.fTokenMint : MINTS.JLP;
|
|
1510
|
+
const outputMint = params.direction === "JlxToJlp" ? MINTS.JLP : poolConfig.fTokenMint;
|
|
1511
|
+
const quote = await getJupiterQuote(
|
|
1512
|
+
inputMint,
|
|
1513
|
+
outputMint,
|
|
1514
|
+
BigInt(params.amountIn.toString()),
|
|
1515
|
+
params.slippageBps ?? 30
|
|
1516
|
+
);
|
|
1517
|
+
const swapIxs = await getJupiterSwapInstructions(quote, this.client.vaultPda);
|
|
1518
|
+
const remainingAccounts = parseSwapRemainingAccounts(swapIxs.swapInstruction);
|
|
1519
|
+
const alts = await fetchAddressLookupTables(
|
|
1520
|
+
this.client.connection,
|
|
1521
|
+
swapIxs.addressLookupTableAddresses
|
|
1522
|
+
);
|
|
1523
|
+
return {
|
|
1524
|
+
inputMint,
|
|
1525
|
+
outputMint,
|
|
1526
|
+
inAmount: new import_anchor5.BN(quote.inAmount),
|
|
1527
|
+
outAmount: new import_anchor5.BN(quote.outAmount),
|
|
1528
|
+
minOutAmount: new import_anchor5.BN(quote.otherAmountThreshold),
|
|
1529
|
+
priceImpactPct: parseFloat(quote.priceImpactPct),
|
|
1530
|
+
route: quote.routePlan.map((r) => r.swapInfo.label || "unknown"),
|
|
1531
|
+
jupiterData: Buffer.from(swapIxs.swapInstruction.data, "base64"),
|
|
1532
|
+
remainingAccounts,
|
|
1533
|
+
addressLookupTables: alts,
|
|
1534
|
+
computeUnitLimit: swapIxs.computeUnitLimit ?? 6e5
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
// Build jlX <-> JLP swap transaction
|
|
1538
|
+
async swapJlxJlp(params) {
|
|
1539
|
+
const poolConfig = getPoolByName(params.pool);
|
|
1540
|
+
if (!poolConfig) throw new JlpdClientError(`Unknown pool: ${params.pool}`);
|
|
1541
|
+
const poolCtx = this.client.pool(params.pool);
|
|
1542
|
+
const computeIx = import_web312.ComputeBudgetProgram.setComputeUnitLimit({
|
|
1543
|
+
units: params.quote.computeUnitLimit
|
|
1544
|
+
});
|
|
1545
|
+
const jupiterProgram = params.quote.remainingAccounts[0]?.pubkey ?? import_web312.PublicKey.default;
|
|
1546
|
+
const swapIx = createSwapJlxJlpInstruction(
|
|
1547
|
+
{
|
|
1548
|
+
stvIndex: poolConfig.stvIndex,
|
|
1549
|
+
direction: params.direction,
|
|
1550
|
+
amountIn: params.amountIn,
|
|
1551
|
+
expectedAmountOut: params.expectedOut,
|
|
1552
|
+
jupiterData: params.quote.jupiterData
|
|
1553
|
+
},
|
|
1554
|
+
{
|
|
1555
|
+
manager: params.manager,
|
|
1556
|
+
jlpVault: this.client.vaultPda,
|
|
1557
|
+
vaultJlxAta: poolCtx.vaultStagingAta,
|
|
1558
|
+
vaultJlpAta: poolCtx.vaultJlpAta,
|
|
1559
|
+
jlpMint: MINTS.JLP,
|
|
1560
|
+
tokenProgram: import_spl_token5.TOKEN_PROGRAM_ID,
|
|
1561
|
+
jupiterProgram
|
|
1562
|
+
},
|
|
1563
|
+
params.quote.remainingAccounts,
|
|
1564
|
+
this.client.programId
|
|
1565
|
+
);
|
|
1566
|
+
const { blockhash } = await this.client.connection.getLatestBlockhash("confirmed");
|
|
1567
|
+
const message = new import_web312.TransactionMessage({
|
|
1568
|
+
payerKey: params.manager,
|
|
1569
|
+
recentBlockhash: blockhash,
|
|
1570
|
+
instructions: [computeIx, swapIx]
|
|
1571
|
+
}).compileToV0Message(params.quote.addressLookupTables);
|
|
1572
|
+
return new import_web312.VersionedTransaction(message);
|
|
1573
|
+
}
|
|
1574
|
+
// Get a quote for jlX <-> jlX swap
|
|
1575
|
+
async quoteJlxJlx(params) {
|
|
1576
|
+
const fromPoolConfig = getPoolByName(params.fromPool);
|
|
1577
|
+
const toPoolConfig = getPoolByName(params.toPool);
|
|
1578
|
+
if (!fromPoolConfig) throw new JlpdClientError(`Unknown pool: ${params.fromPool}`);
|
|
1579
|
+
if (!toPoolConfig) throw new JlpdClientError(`Unknown pool: ${params.toPool}`);
|
|
1580
|
+
const inputMint = fromPoolConfig.fTokenMint;
|
|
1581
|
+
const outputMint = toPoolConfig.fTokenMint;
|
|
1582
|
+
const quote = await getJupiterQuote(
|
|
1583
|
+
inputMint,
|
|
1584
|
+
outputMint,
|
|
1585
|
+
BigInt(params.amountIn.toString()),
|
|
1586
|
+
params.slippageBps ?? 30
|
|
1587
|
+
);
|
|
1588
|
+
const swapIxs = await getJupiterSwapInstructions(quote, this.client.vaultPda);
|
|
1589
|
+
const remainingAccounts = parseSwapRemainingAccounts(swapIxs.swapInstruction);
|
|
1590
|
+
const alts = await fetchAddressLookupTables(
|
|
1591
|
+
this.client.connection,
|
|
1592
|
+
swapIxs.addressLookupTableAddresses
|
|
1593
|
+
);
|
|
1594
|
+
return {
|
|
1595
|
+
inputMint,
|
|
1596
|
+
outputMint,
|
|
1597
|
+
inAmount: new import_anchor5.BN(quote.inAmount),
|
|
1598
|
+
outAmount: new import_anchor5.BN(quote.outAmount),
|
|
1599
|
+
minOutAmount: new import_anchor5.BN(quote.otherAmountThreshold),
|
|
1600
|
+
priceImpactPct: parseFloat(quote.priceImpactPct),
|
|
1601
|
+
route: quote.routePlan.map((r) => r.swapInfo.label || "unknown"),
|
|
1602
|
+
jupiterData: Buffer.from(swapIxs.swapInstruction.data, "base64"),
|
|
1603
|
+
remainingAccounts,
|
|
1604
|
+
addressLookupTables: alts,
|
|
1605
|
+
computeUnitLimit: swapIxs.computeUnitLimit ?? 6e5
|
|
1606
|
+
};
|
|
1607
|
+
}
|
|
1608
|
+
// Build jlX <-> jlX swap transaction
|
|
1609
|
+
async swapJlxJlx(params) {
|
|
1610
|
+
const fromPoolConfig = getPoolByName(params.fromPool);
|
|
1611
|
+
const toPoolConfig = getPoolByName(params.toPool);
|
|
1612
|
+
if (!fromPoolConfig) throw new JlpdClientError(`Unknown pool: ${params.fromPool}`);
|
|
1613
|
+
if (!toPoolConfig) throw new JlpdClientError(`Unknown pool: ${params.toPool}`);
|
|
1614
|
+
const fromPoolCtx = this.client.pool(params.fromPool);
|
|
1615
|
+
const toPoolCtx = this.client.pool(params.toPool);
|
|
1616
|
+
const computeIx = import_web312.ComputeBudgetProgram.setComputeUnitLimit({
|
|
1617
|
+
units: params.quote.computeUnitLimit
|
|
1618
|
+
});
|
|
1619
|
+
const jupiterProgram = params.quote.remainingAccounts[0]?.pubkey ?? import_web312.PublicKey.default;
|
|
1620
|
+
const swapIx = createSwapJlxJlxInstruction(
|
|
1621
|
+
{
|
|
1622
|
+
fromIndex: fromPoolConfig.stvIndex,
|
|
1623
|
+
toIndex: toPoolConfig.stvIndex,
|
|
1624
|
+
amountIn: params.amountIn,
|
|
1625
|
+
minOut: params.minOut,
|
|
1626
|
+
jupiterData: params.quote.jupiterData
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
manager: params.manager,
|
|
1630
|
+
jlpVault: this.client.vaultPda,
|
|
1631
|
+
fromJlxMint: fromPoolConfig.fTokenMint,
|
|
1632
|
+
toJlxMint: toPoolConfig.fTokenMint,
|
|
1633
|
+
fromJlxAta: fromPoolCtx.vaultStagingAta,
|
|
1634
|
+
toJlxAta: toPoolCtx.vaultStagingAta,
|
|
1635
|
+
tokenProgram: import_spl_token5.TOKEN_PROGRAM_ID,
|
|
1636
|
+
jupiterProgram
|
|
1637
|
+
},
|
|
1638
|
+
params.quote.remainingAccounts,
|
|
1639
|
+
this.client.programId
|
|
1640
|
+
);
|
|
1641
|
+
const { blockhash } = await this.client.connection.getLatestBlockhash("confirmed");
|
|
1642
|
+
const message = new import_web312.TransactionMessage({
|
|
1643
|
+
payerKey: params.manager,
|
|
1644
|
+
recentBlockhash: blockhash,
|
|
1645
|
+
instructions: [computeIx, swapIx]
|
|
1646
|
+
}).compileToV0Message(params.quote.addressLookupTables);
|
|
1647
|
+
return new import_web312.VersionedTransaction(message);
|
|
1648
|
+
}
|
|
1649
|
+
};
|
|
1650
|
+
var AdminContext = class {
|
|
1651
|
+
constructor(client) {
|
|
1652
|
+
this.client = client;
|
|
1653
|
+
}
|
|
1654
|
+
// Initialize or update vault
|
|
1655
|
+
async initOrUpdateVault(params) {
|
|
1656
|
+
const ix = createInitOrUpdateVaultInstruction(
|
|
1657
|
+
{
|
|
1658
|
+
jlpMint: params.jlpMint ?? null,
|
|
1659
|
+
baseAssetMints: params.baseAssetMints ?? null,
|
|
1660
|
+
jlxAssetMints: params.jlxAssetMints ?? null,
|
|
1661
|
+
newAdmin: params.newAdmin ?? null,
|
|
1662
|
+
manager: params.manager,
|
|
1663
|
+
feeReceiver: params.feeReceiver,
|
|
1664
|
+
flags: params.flags,
|
|
1665
|
+
jlpSlippageBps: params.jlpSlippageBps,
|
|
1666
|
+
oracleStalenessThreshold: params.oracleStalenessThreshold ?? null
|
|
1667
|
+
},
|
|
1668
|
+
{
|
|
1669
|
+
admin: params.admin,
|
|
1670
|
+
jlpVault: this.client.vaultPda,
|
|
1671
|
+
systemProgram: import_web312.SystemProgram.programId
|
|
1672
|
+
},
|
|
1673
|
+
this.client.programId
|
|
1674
|
+
);
|
|
1675
|
+
return this.client.buildTransaction(params.admin, [ix]);
|
|
1676
|
+
}
|
|
1677
|
+
// Initialize STV
|
|
1678
|
+
async initializeStv(params, jvMintKeypair) {
|
|
1679
|
+
const pool = getPoolByName(params.poolName);
|
|
1680
|
+
if (!pool) throw new JlpdClientError(`Unknown pool: ${params.poolName}`);
|
|
1681
|
+
const [stvPda] = deriveStvPda(pool.mint, this.client.programId);
|
|
1682
|
+
const stvJlxAta = (0, import_spl_token5.getAssociatedTokenAddressSync)(pool.fTokenMint, stvPda, true);
|
|
1683
|
+
const ix = createInitializeStvInstruction(
|
|
1684
|
+
{
|
|
1685
|
+
mgmtFeeBps: params.mgmtFeeBps,
|
|
1686
|
+
perfFeeBps: params.perfFeeBps,
|
|
1687
|
+
maxDeposit: params.maxDeposit,
|
|
1688
|
+
minDeposit: params.minDeposit
|
|
1689
|
+
},
|
|
1690
|
+
{
|
|
1691
|
+
admin: params.admin,
|
|
1692
|
+
jlpVault: this.client.vaultPda,
|
|
1693
|
+
stv: stvPda,
|
|
1694
|
+
baseMint: pool.mint,
|
|
1695
|
+
jlMint: pool.fTokenMint,
|
|
1696
|
+
jvMint: jvMintKeypair,
|
|
1697
|
+
stvJlxAta,
|
|
1698
|
+
systemProgram: import_web312.SystemProgram.programId,
|
|
1699
|
+
tokenProgram: import_spl_token5.TOKEN_PROGRAM_ID,
|
|
1700
|
+
associatedTokenProgram: import_spl_token5.ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
1701
|
+
rent: import_web312.SYSVAR_RENT_PUBKEY
|
|
1702
|
+
},
|
|
1703
|
+
this.client.programId
|
|
1704
|
+
);
|
|
1705
|
+
return this.client.buildTransaction(params.admin, [ix]);
|
|
1706
|
+
}
|
|
1707
|
+
// Settle yield across all STVs
|
|
1708
|
+
async settleYield(params) {
|
|
1709
|
+
const poolNames = ["BTC", "ETH", "SOL", "USDC", "JupUSD"];
|
|
1710
|
+
const pools = poolNames.map((name) => {
|
|
1711
|
+
const pool = getPoolByName(name);
|
|
1712
|
+
if (!pool) throw new JlpdClientError(`Unknown pool: ${name}`);
|
|
1713
|
+
return pool;
|
|
1714
|
+
});
|
|
1715
|
+
const stvPdas = pools.map((p) => deriveStvPda(p.mint, this.client.programId)[0]);
|
|
1716
|
+
const stagingAtas = pools.map(
|
|
1717
|
+
(p) => (0, import_spl_token5.getAssociatedTokenAddressSync)(p.fTokenMint, this.client.vaultPda, true)
|
|
1718
|
+
);
|
|
1719
|
+
const lendingAccounts = pools.map((p) => ({
|
|
1720
|
+
pubkey: p.hasJupiterLend ? p.lending : import_web312.PublicKey.default,
|
|
1721
|
+
isSigner: false,
|
|
1722
|
+
isWritable: false
|
|
1723
|
+
}));
|
|
1724
|
+
const rewardsAccounts = pools.map((p) => ({
|
|
1725
|
+
pubkey: p.hasJupiterLend ? p.rewardsRateModel : import_web312.PublicKey.default,
|
|
1726
|
+
isSigner: false,
|
|
1727
|
+
isWritable: false
|
|
1728
|
+
}));
|
|
1729
|
+
const mintAccounts = pools.map((p) => ({
|
|
1730
|
+
pubkey: p.fTokenMint,
|
|
1731
|
+
isSigner: false,
|
|
1732
|
+
isWritable: false
|
|
1733
|
+
}));
|
|
1734
|
+
const remainingAccounts = [...lendingAccounts, ...rewardsAccounts, ...mintAccounts];
|
|
1735
|
+
const ix = createSettleYieldInstruction(
|
|
1736
|
+
{ jlpRate: params.jlpRate },
|
|
1737
|
+
{
|
|
1738
|
+
manager: params.manager,
|
|
1739
|
+
jlpVault: this.client.vaultPda,
|
|
1740
|
+
vaultJlpAta: (0, import_spl_token5.getAssociatedTokenAddressSync)(MINTS.JLP, this.client.vaultPda, true),
|
|
1741
|
+
jlpMint: MINTS.JLP,
|
|
1742
|
+
stvBtc: stvPdas[0],
|
|
1743
|
+
stvEth: stvPdas[1],
|
|
1744
|
+
stvSol: stvPdas[2],
|
|
1745
|
+
stvUsdc: stvPdas[3],
|
|
1746
|
+
stvJupusd: stvPdas[4],
|
|
1747
|
+
stagingBtc: stagingAtas[0],
|
|
1748
|
+
stagingEth: stagingAtas[1],
|
|
1749
|
+
stagingSol: stagingAtas[2],
|
|
1750
|
+
stagingUsdc: stagingAtas[3],
|
|
1751
|
+
stagingJupusd: stagingAtas[4],
|
|
1752
|
+
oracleBtc: ORACLES.DOVES_BTC_USD,
|
|
1753
|
+
oracleEth: ORACLES.DOVES_ETH_USD,
|
|
1754
|
+
oracleSol: ORACLES.DOVES_SOL_USD,
|
|
1755
|
+
oracleJlp: ORACLES.PYTH_JLP_USD
|
|
1756
|
+
},
|
|
1757
|
+
remainingAccounts,
|
|
1758
|
+
this.client.programId
|
|
1759
|
+
);
|
|
1760
|
+
return this.client.buildTransaction(params.manager, [ix]);
|
|
1761
|
+
}
|
|
1762
|
+
};
|
|
1763
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1764
|
+
0 && (module.exports = {
|
|
1765
|
+
AdminContext,
|
|
1766
|
+
EXCHANGE_RATE_PRECISION,
|
|
1767
|
+
FLAG_DEPOSITS_DISABLED,
|
|
1768
|
+
FLAG_JLP_DISABLED,
|
|
1769
|
+
FLAG_PAUSED,
|
|
1770
|
+
FLAG_REBALANCE_DISABLED,
|
|
1771
|
+
FLAG_WITHDRAWALS_DISABLED,
|
|
1772
|
+
JLPD_PROGRAM_ID,
|
|
1773
|
+
JLP_VAULT_ACCOUNT_SIZE,
|
|
1774
|
+
JLP_VAULT_DATA_SIZE,
|
|
1775
|
+
JLP_VAULT_DISCRIMINATOR,
|
|
1776
|
+
JUPITER_LEND_PROGRAM_ID,
|
|
1777
|
+
JUPITER_SWAP_PROGRAM_ID,
|
|
1778
|
+
JUPUSD_POOL,
|
|
1779
|
+
JUP_LEND_PROGRAM_ID,
|
|
1780
|
+
JlpdClient,
|
|
1781
|
+
JlpdClientError,
|
|
1782
|
+
LENDING_ADMIN,
|
|
1783
|
+
LIQUIDITY_PROGRAM_ID,
|
|
1784
|
+
LIQUIDITY_SINGLETON,
|
|
1785
|
+
MINTS,
|
|
1786
|
+
ORACLES,
|
|
1787
|
+
POOLS,
|
|
1788
|
+
PPS_DECIMALS,
|
|
1789
|
+
PoolContext,
|
|
1790
|
+
SEED_JLP_VAULT,
|
|
1791
|
+
SEED_STV,
|
|
1792
|
+
STV_ACCOUNT_SIZE,
|
|
1793
|
+
STV_DATA_SIZE,
|
|
1794
|
+
STV_DISCRIMINATOR,
|
|
1795
|
+
STV_INDEX,
|
|
1796
|
+
SwapContext,
|
|
1797
|
+
USDC_POOL,
|
|
1798
|
+
WBTC_POOL,
|
|
1799
|
+
WETH_POOL,
|
|
1800
|
+
WSOL_POOL,
|
|
1801
|
+
baseToJlx,
|
|
1802
|
+
baseToShares,
|
|
1803
|
+
buildExchangeRateAccounts,
|
|
1804
|
+
buildJupEarnDepositAccounts,
|
|
1805
|
+
buildJupEarnWithdrawAccounts,
|
|
1806
|
+
buildSwapData,
|
|
1807
|
+
calculateExchangeRate,
|
|
1808
|
+
calculateNav,
|
|
1809
|
+
calculatePps,
|
|
1810
|
+
clearAtaCache,
|
|
1811
|
+
clearPdaCache,
|
|
1812
|
+
createClaimFeesInstruction,
|
|
1813
|
+
createDepositInstruction,
|
|
1814
|
+
createInitOrUpdateVaultInstruction,
|
|
1815
|
+
createInitializeStvInstruction,
|
|
1816
|
+
createJupEarnInstruction,
|
|
1817
|
+
createMoveJlxInstruction,
|
|
1818
|
+
createSettleYieldInstruction,
|
|
1819
|
+
createSwapJlxJlpInstruction,
|
|
1820
|
+
createSwapJlxJlxInstruction,
|
|
1821
|
+
createUpdateStvInstruction,
|
|
1822
|
+
createWithdrawInstruction,
|
|
1823
|
+
deriveAta,
|
|
1824
|
+
deriveStvAtas,
|
|
1825
|
+
deriveStvPda,
|
|
1826
|
+
deriveUserAtas,
|
|
1827
|
+
deriveVaultAtas,
|
|
1828
|
+
deriveVaultPda,
|
|
1829
|
+
fetchAddressLookupTables,
|
|
1830
|
+
fetchJlpRate,
|
|
1831
|
+
fetchJupiterPriceUsd,
|
|
1832
|
+
getJupiterQuote,
|
|
1833
|
+
getJupiterSwapInstructions,
|
|
1834
|
+
getPoolByMint,
|
|
1835
|
+
getPoolByName,
|
|
1836
|
+
jlxToBase,
|
|
1837
|
+
parseLendingAccount,
|
|
1838
|
+
parseRewardsRateModel,
|
|
1839
|
+
parseStv,
|
|
1840
|
+
parseSwapRemainingAccounts,
|
|
1841
|
+
parseVault,
|
|
1842
|
+
sharesToBase
|
|
1843
|
+
});
|