@exponent-labs/exponent-fetcher 0.1.7 → 0.1.8
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/build/exponentFetcher.d.ts +303 -31
- package/build/exponentFetcher.js +666 -168
- package/build/exponentFetcher.js.map +1 -1
- package/build/index.d.ts +10 -0
- package/build/index.js +10 -0
- package/build/index.js.map +1 -1
- package/build/utils/adrena.d.ts +13 -0
- package/build/utils/adrena.js +29 -0
- package/build/utils/adrena.js.map +1 -0
- package/build/utils/fragmetric.d.ts +17 -0
- package/build/utils/fragmetric.js +23 -0
- package/build/utils/fragmetric.js.map +1 -0
- package/build/utils/jito.d.ts +7 -0
- package/build/utils/jito.js +29 -0
- package/build/utils/jito.js.map +1 -0
- package/build/utils/jupiter.d.ts +30 -0
- package/build/utils/jupiter.js +63 -0
- package/build/utils/jupiter.js.map +1 -0
- package/build/utils/kamino.d.ts +5 -0
- package/build/utils/kamino.js +10 -0
- package/build/utils/kamino.js.map +1 -0
- package/build/utils/meteora.d.ts +19 -0
- package/build/utils/meteora.js +36 -1
- package/build/utils/meteora.js.map +1 -1
- package/build/utils/ore.d.ts +74 -0
- package/build/utils/ore.js +217 -0
- package/build/utils/ore.js.map +1 -0
- package/build/utils/perena.d.ts +12 -0
- package/build/utils/perena.js +27 -0
- package/build/utils/perena.js.map +1 -0
- package/build/utils/sanctum.d.ts +6 -0
- package/build/utils/sanctum.js +26 -0
- package/build/utils/sanctum.js.map +1 -0
- package/build/utils/solstice.d.ts +12 -0
- package/build/utils/solstice.js +45 -0
- package/build/utils/solstice.js.map +1 -0
- package/package.json +20 -18
- package/src/exponentFetcher.ts +1077 -222
- package/src/index.ts +10 -0
- package/src/utils/adrena.ts +44 -0
- package/src/utils/fragmetric.ts +34 -0
- package/src/utils/jito.ts +30 -0
- package/src/utils/jupiter.ts +98 -0
- package/src/utils/kamino.ts +6 -0
- package/src/utils/meteora.ts +73 -1
- package/src/utils/ore.ts +322 -0
- package/src/utils/perena.ts +28 -0
- package/src/utils/sanctum.ts +24 -0
- package/src/utils/solstice.ts +51 -0
- package/tsconfig.json +2 -0
package/build/exponentFetcher.js
CHANGED
|
@@ -3,18 +3,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.fetchSolsticeRedemptionRate = exports.fetchSanctumIndex = exports.fetchAdrenaIndex = exports.fetchMeteoraIndex = exports.fetchFragmetricSupportedTokenIndex = exports.fetchKaminoVaultIndex = exports.fetchJupiterLendIndex = exports.fetchFragmetricIndex = exports.fetchGenericSyMetaIndex = exports.fetchPyth = exports.fetchJupiterPerpsIndex = exports.fetchJitoRestaking = exports.fetchPerenaStablePoolData = exports.fetchSplStakePoolIndex = exports.deserializeEmission = exports.serializeEmission = exports.fetchAllKaminoObligationsByKaminoReserve = exports.fetchKaminoReserve = exports.ExponentFetcher = exports.MyWallet = exports.deserializeAnchorizedPNumFromJson = exports.serializeAnchorizedPNumFromJson = void 0;
|
|
6
|
+
exports.fetchOreExchangeRate = exports.fetchReflectRedemptionRate = exports.fetchSolsticeRedemptionRate = exports.fetchSanctumIndex = exports.fetchAdrenaIndex = exports.fetchMeteoraIndex = exports.fetchFragmetricSupportedTokenIndex = exports.fetchKaminoVaultIndex = exports.fetchJupiterLendIndex = exports.fetchFragmetricIndex = exports.fetchGenericSyMetaIndex = exports.fetchPyth = exports.fetchJupiterPerpsIndex = exports.fetchJitoRestaking = exports.fetchPerenaStablePoolData = exports.fetchSplStakePoolIndex = exports.deserializeEmission = exports.serializeEmission = exports.fetchAllKaminoObligationsByKaminoReserve = exports.fetchKaminoReserve = exports.deserializeYtPosition = exports.deserializeLpPosition = exports.deserializeMarketThreeTicks = exports.ExponentFetcher = exports.MyWallet = exports.deserializeAnchorizedPNumFromJson = exports.serializeAnchorizedPNumFromJson = void 0;
|
|
7
7
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
8
8
|
const anchor_2 = require("@coral-xyz/anchor");
|
|
9
9
|
const spl_stake_pool_1 = require("@solana/spl-stake-pool");
|
|
10
10
|
const spl_token_1 = require("@solana/spl-token");
|
|
11
|
-
const
|
|
11
|
+
const bs58_1 = __importDefault(require("bs58"));
|
|
12
12
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
13
|
+
const exponent_clmm_idl_1 = require("@exponent-labs/exponent-clmm-idl");
|
|
13
14
|
const exponent_idl_1 = require("@exponent-labs/exponent-idl");
|
|
15
|
+
const exponent_orderbook_idl_1 = require("@exponent-labs/exponent-orderbook-idl");
|
|
14
16
|
const exponent_types_1 = require("@exponent-labs/exponent-types");
|
|
15
|
-
const
|
|
16
|
-
const jupiter_lend_idl_1 = require("@exponent-labs/jupiter-lend-idl");
|
|
17
|
-
const kamino_vault_idl_1 = require("@exponent-labs/kamino-vault-idl");
|
|
17
|
+
const exponent_types_2 = require("@exponent-labs/exponent-types");
|
|
18
18
|
const generic_sy_idl_1 = require("@exponent-labs/generic-sy-idl");
|
|
19
19
|
const jito_restaking_sy_idl_1 = require("@exponent-labs/jito-restaking-sy-idl");
|
|
20
20
|
const jito_restaking_sy_idl_2 = require("@exponent-labs/jito-restaking-sy-idl");
|
|
@@ -22,22 +22,31 @@ const kamino_reserve_deserializer_1 = require("@exponent-labs/kamino-reserve-des
|
|
|
22
22
|
const kamino_reserve_deserializer_2 = require("@exponent-labs/kamino-reserve-deserializer");
|
|
23
23
|
const kamino_sy_idl_1 = require("@exponent-labs/kamino-sy-idl");
|
|
24
24
|
const kamino_sy_idl_2 = require("@exponent-labs/kamino-sy-idl");
|
|
25
|
+
const kamino_vault_idl_1 = require("@exponent-labs/kamino-vault-idl");
|
|
25
26
|
const marginfi_sy_idl_1 = require("@exponent-labs/marginfi-sy-idl");
|
|
26
27
|
const meteora_idl_1 = require("@exponent-labs/meteora-idl");
|
|
27
28
|
const perena_sy_idl_1 = require("@exponent-labs/perena-sy-idl");
|
|
28
29
|
const perena_sy_idl_2 = require("@exponent-labs/perena-sy-idl");
|
|
29
30
|
const precise_number_1 = require("@exponent-labs/precise-number");
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const
|
|
31
|
+
const adrena_1 = require("./utils/adrena");
|
|
32
|
+
const fragmetric_1 = require("./utils/fragmetric");
|
|
33
|
+
const jito_1 = require("./utils/jito");
|
|
34
|
+
const jupiter_1 = require("./utils/jupiter");
|
|
33
35
|
const meteora_1 = require("./utils/meteora");
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
+
const ore_1 = require("./utils/ore");
|
|
37
|
+
const perena_1 = require("./utils/perena");
|
|
38
|
+
const sanctum_1 = require("./utils/sanctum");
|
|
39
|
+
const solstice_1 = require("./utils/solstice");
|
|
36
40
|
function serializeAnchorizedPNumFromJson(pnum) {
|
|
37
41
|
const serializedArray = pnum[0].map((bn) => bn.toString());
|
|
38
42
|
return { 0: serializedArray };
|
|
39
43
|
}
|
|
40
44
|
exports.serializeAnchorizedPNumFromJson = serializeAnchorizedPNumFromJson;
|
|
45
|
+
function readU128LE(buf, offset) {
|
|
46
|
+
const lo = buf.readBigUInt64LE(offset);
|
|
47
|
+
const hi = buf.readBigUInt64LE(offset + 8);
|
|
48
|
+
return (hi << 64n) + lo;
|
|
49
|
+
}
|
|
41
50
|
function deserializeAnchorizedPNumFromJson(serialized) {
|
|
42
51
|
const bnArray = serialized[0].map((str) => new anchor_1.BN(str));
|
|
43
52
|
return { 0: bnArray };
|
|
@@ -81,6 +90,8 @@ class ExponentFetcher {
|
|
|
81
90
|
jitoRestakingSyProgram;
|
|
82
91
|
perenaSyProgram;
|
|
83
92
|
genericStandardProgram;
|
|
93
|
+
exponentClmmProgram;
|
|
94
|
+
orderbookProgram;
|
|
84
95
|
connection;
|
|
85
96
|
coreProgramId;
|
|
86
97
|
marginfiSyProgramId;
|
|
@@ -105,6 +116,8 @@ class ExponentFetcher {
|
|
|
105
116
|
this.jitoRestakingSyProgram = new anchor_1.Program(jito_restaking_sy_idl_2.IDL, provider);
|
|
106
117
|
this.perenaSyProgram = new anchor_1.Program(perena_sy_idl_2.IDL, provider);
|
|
107
118
|
this.genericStandardProgram = new anchor_1.Program(generic_sy_idl_1.IDL, provider);
|
|
119
|
+
this.exponentClmmProgram = new anchor_1.Program(exponent_clmm_idl_1.IDL, provider);
|
|
120
|
+
this.orderbookProgram = new anchor_1.Program(exponent_orderbook_idl_1.IDL, provider);
|
|
108
121
|
}
|
|
109
122
|
async fetchVault(address) {
|
|
110
123
|
try {
|
|
@@ -128,6 +141,28 @@ class ExponentFetcher {
|
|
|
128
141
|
throw e;
|
|
129
142
|
}
|
|
130
143
|
}
|
|
144
|
+
async fetchOrderbook(address) {
|
|
145
|
+
try {
|
|
146
|
+
const o = (await this.connection.getAccountInfo(address)).data;
|
|
147
|
+
return deserializeOrderbook(o);
|
|
148
|
+
}
|
|
149
|
+
catch (e) {
|
|
150
|
+
console.error(`Error fetching orderbook ${address.toBase58()}`);
|
|
151
|
+
console.error(e);
|
|
152
|
+
throw e;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async fetchOrderbookCpiAccounts(address) {
|
|
156
|
+
try {
|
|
157
|
+
const orderbookCpiAccounts = await this.orderbookProgram.account.cpiAccountsOrderbook.fetch(address);
|
|
158
|
+
return orderbookCpiAccounts;
|
|
159
|
+
}
|
|
160
|
+
catch (e) {
|
|
161
|
+
console.error(`Error fetching orderbook ${address.toBase58()}`);
|
|
162
|
+
console.error(e);
|
|
163
|
+
throw e;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
131
166
|
async fetchMarginfiSyMeta(address) {
|
|
132
167
|
const x = await this.marginfiSyProgram.account.syMeta.fetch(address);
|
|
133
168
|
return deserializeMarginfiSyMeta(x);
|
|
@@ -200,10 +235,59 @@ class ExponentFetcher {
|
|
|
200
235
|
const x = await this.program.account.lpPosition.fetch(address);
|
|
201
236
|
return deserializeLpPosition(x);
|
|
202
237
|
}
|
|
238
|
+
async fetchLpPositionCLMM(address) {
|
|
239
|
+
try {
|
|
240
|
+
const raw = await this.exponentClmmProgram.account.lpPosition.fetch(address);
|
|
241
|
+
const v = {
|
|
242
|
+
owner: raw.owner,
|
|
243
|
+
market: raw.market,
|
|
244
|
+
feeInsideLastPt: raw.feeInsideLastPt,
|
|
245
|
+
feeInsideLastSy: raw.feeInsideLastSy,
|
|
246
|
+
lpBalance: raw.lpBalance,
|
|
247
|
+
tokensOwedSy: raw.tokensOwedSy,
|
|
248
|
+
tokensOwedPt: raw.tokensOwedPt,
|
|
249
|
+
lowerTickIdx: raw.lowerTickIdx,
|
|
250
|
+
upperTickIdx: raw.upperTickIdx,
|
|
251
|
+
farms: {
|
|
252
|
+
trackers: raw.farms.trackers.map((t) => ({
|
|
253
|
+
staged: t.staged,
|
|
254
|
+
lastSeenIndex: t.lastSeenIndex,
|
|
255
|
+
})),
|
|
256
|
+
},
|
|
257
|
+
shareTrackers: {
|
|
258
|
+
trackers: raw.shareTrackers.trackers.map((tracker) => ({
|
|
259
|
+
tickIdx: tracker.tickIdx,
|
|
260
|
+
rightTickIdx: tracker.rightTickIdx,
|
|
261
|
+
splitEpoch: tracker.splitEpoch,
|
|
262
|
+
lpShare: tracker.lpShare,
|
|
263
|
+
emissions: {
|
|
264
|
+
trackers: tracker.emissions.trackers.map((e) => ({
|
|
265
|
+
staged: e.staged,
|
|
266
|
+
lastSeenIndex: e.lastSeenIndex,
|
|
267
|
+
})),
|
|
268
|
+
},
|
|
269
|
+
})),
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
return deserializeLpPositionCLMM(v);
|
|
273
|
+
}
|
|
274
|
+
catch (e) {
|
|
275
|
+
console.error(`Error fetching clmm lp position ${address.toBase58()}`);
|
|
276
|
+
console.error(e);
|
|
277
|
+
throw e;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
203
280
|
async fetchYtPosition(address) {
|
|
204
281
|
const x = await this.program.account.yieldTokenPosition.fetch(address);
|
|
205
282
|
return deserializeYtPosition(x);
|
|
206
283
|
}
|
|
284
|
+
/** Batch fetch multiple YT positions in a single RPC call */
|
|
285
|
+
async fetchYtPositions(addresses) {
|
|
286
|
+
if (addresses.length === 0)
|
|
287
|
+
return [];
|
|
288
|
+
const results = await this.program.account.yieldTokenPosition.fetchMultiple(addresses);
|
|
289
|
+
return results.map((x) => (x ? deserializeYtPosition(x) : null));
|
|
290
|
+
}
|
|
207
291
|
async fetchJitoRestakingSyMeta(address) {
|
|
208
292
|
const x = await this.jitoRestakingSyProgram.account.syMeta.fetch(address);
|
|
209
293
|
return (0, exponent_types_1.deserializeJitoRestakingSyMetaAccountRaw)(x);
|
|
@@ -216,8 +300,234 @@ class ExponentFetcher {
|
|
|
216
300
|
const x = await this.genericStandardProgram.account.syMeta.fetch(address);
|
|
217
301
|
return (0, exponent_types_1.deserializeGenericSyMetaAccountRaw)(x);
|
|
218
302
|
}
|
|
303
|
+
async fetchAllMarketThree() {
|
|
304
|
+
//TODO Replace with the following code when all damaged markets are removed onchain
|
|
305
|
+
// const marketsProgramAccounts: ProgramAccount<MarketThreeRaw>[] =
|
|
306
|
+
// await this.exponentClmmProgram.account.marketThree.all()
|
|
307
|
+
// return marketsProgramAccounts.map(({ account }) => deserializeMarketThree(account))
|
|
308
|
+
const MARKET_THREE_DISCRIMINATOR = Buffer.from([242, 240, 26, 15, 148, 186, 185, 205]);
|
|
309
|
+
const marketsProgramAccounts = await this.connection.getProgramAccounts(this.exponentClmmProgram.programId, {
|
|
310
|
+
filters: [
|
|
311
|
+
{
|
|
312
|
+
memcmp: {
|
|
313
|
+
offset: 0,
|
|
314
|
+
bytes: bs58_1.default.encode(MARKET_THREE_DISCRIMINATOR),
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
});
|
|
319
|
+
return marketsProgramAccounts
|
|
320
|
+
.map(({ account, pubkey }) => {
|
|
321
|
+
try {
|
|
322
|
+
return this.exponentClmmProgram.coder.accounts.decode("marketThree", account.data);
|
|
323
|
+
}
|
|
324
|
+
catch (error) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
})
|
|
328
|
+
.filter((m) => !!m);
|
|
329
|
+
}
|
|
330
|
+
async fetchMarketThree(address) {
|
|
331
|
+
try {
|
|
332
|
+
const m = await this.exponentClmmProgram.account.marketThree.fetch(address);
|
|
333
|
+
return deserializeMarketThree(m);
|
|
334
|
+
}
|
|
335
|
+
catch (e) {
|
|
336
|
+
console.error(`Error fetching market ${address.toBase58()}`);
|
|
337
|
+
console.error(e);
|
|
338
|
+
throw e;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
async fetchAllMarketThreeTicks() {
|
|
342
|
+
const TICKS_DISCRIMINATOR = Buffer.from([122, 104, 41, 141, 214, 36, 222, 37]);
|
|
343
|
+
const ticksAccounts = await this.connection.getProgramAccounts(this.exponentClmmProgram.programId, {
|
|
344
|
+
filters: [
|
|
345
|
+
{
|
|
346
|
+
memcmp: {
|
|
347
|
+
offset: 0,
|
|
348
|
+
bytes: bs58_1.default.encode(TICKS_DISCRIMINATOR),
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
],
|
|
352
|
+
});
|
|
353
|
+
return ticksAccounts.map(({ account }) => deserializeMarketThreeTicks(account.data));
|
|
354
|
+
}
|
|
355
|
+
async fetchMarketThreeTicks(address) {
|
|
356
|
+
try {
|
|
357
|
+
const m = (await this.connection.getAccountInfo(address)).data;
|
|
358
|
+
return deserializeMarketThreeTicks(m);
|
|
359
|
+
}
|
|
360
|
+
catch (e) {
|
|
361
|
+
console.error(`Error fetching market ${address.toBase58()}`);
|
|
362
|
+
console.error(e);
|
|
363
|
+
throw e;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
219
366
|
}
|
|
220
367
|
exports.ExponentFetcher = ExponentFetcher;
|
|
368
|
+
function deserializeMarketThreeTicks(data) {
|
|
369
|
+
let offset = 8;
|
|
370
|
+
const MAX_TICK_NODES = 100;
|
|
371
|
+
const PERSONAL_TICK_YIELD_TRACKER_SIZE = 3;
|
|
372
|
+
const readPubkey = () => {
|
|
373
|
+
const pk = new anchor_1.web3.PublicKey(data.slice(offset, offset + 32));
|
|
374
|
+
offset += 32;
|
|
375
|
+
return pk;
|
|
376
|
+
};
|
|
377
|
+
const readNumber = () => {
|
|
378
|
+
// Number is 32 bytes (4 x u64)
|
|
379
|
+
const nums = [];
|
|
380
|
+
for (let i = 0; i < 4; i++) {
|
|
381
|
+
nums.push(new anchor_1.BN(data.slice(offset + i * 8, offset + (i + 1) * 8), undefined, "le"));
|
|
382
|
+
}
|
|
383
|
+
offset += 32;
|
|
384
|
+
return parseFloat(precise_number_1.PreciseNumber.fromRaw(nums).valueString);
|
|
385
|
+
};
|
|
386
|
+
// ─── Parse RedBlackTree slab ───────────────────────────────────────────────
|
|
387
|
+
// repr(C) gives: root: u32, pad to align NodeAllocator's u64, then the NodeAllocator header
|
|
388
|
+
const root = data.readUInt32LE(offset);
|
|
389
|
+
offset += 4;
|
|
390
|
+
const padTo8 = 12;
|
|
391
|
+
offset += padTo8;
|
|
392
|
+
// NodeAllocator<T=RBNode<u32,PriceNode>, N=MAX_PRICE_NODES, R=3>
|
|
393
|
+
// header: size:u64, bump_index:u32, free_list_head:u32
|
|
394
|
+
const tickTreeSize = Number(data.readBigUInt64LE(offset));
|
|
395
|
+
offset += 8;
|
|
396
|
+
const ticksTreeBump = data.readUInt32LE(offset);
|
|
397
|
+
offset += 4;
|
|
398
|
+
const ticksTreeFreeIdx = data.readUInt32LE(offset);
|
|
399
|
+
offset += 4;
|
|
400
|
+
const ticks = [];
|
|
401
|
+
for (let i = 0; i < MAX_TICK_NODES; i++) {
|
|
402
|
+
const left = data.readUInt32LE(offset);
|
|
403
|
+
offset += 4;
|
|
404
|
+
const right = data.readUInt32LE(offset);
|
|
405
|
+
offset += 4;
|
|
406
|
+
const parent = data.readUInt32LE(offset);
|
|
407
|
+
offset += 4;
|
|
408
|
+
offset += 4; // skip color
|
|
409
|
+
const apyBasePoints = data.readUInt32LE(offset);
|
|
410
|
+
offset += 8;
|
|
411
|
+
const feeGrowthOutsidePt = readU128LE(data, offset);
|
|
412
|
+
offset += 16;
|
|
413
|
+
const feeGrowthOutsideSy = readU128LE(data, offset);
|
|
414
|
+
offset += 16;
|
|
415
|
+
const liquidityNet = data.readBigInt64LE(offset);
|
|
416
|
+
offset += 8;
|
|
417
|
+
const liquidityGross = data.readBigInt64LE(offset);
|
|
418
|
+
offset += 8;
|
|
419
|
+
const impliedRate = data.readDoubleLE(offset);
|
|
420
|
+
offset += 8;
|
|
421
|
+
const principalPt = data.readBigInt64LE(offset);
|
|
422
|
+
offset += 8;
|
|
423
|
+
const principalSy = data.readBigInt64LE(offset);
|
|
424
|
+
offset += 8;
|
|
425
|
+
const principalShareSupply = data.readBigInt64LE(offset);
|
|
426
|
+
offset += 8;
|
|
427
|
+
// Parse FarmYieldTrackers (3 trackers x 32 bytes each)
|
|
428
|
+
const farms = [];
|
|
429
|
+
for (let j = 0; j < PERSONAL_TICK_YIELD_TRACKER_SIZE; j++) {
|
|
430
|
+
farms.push({ lastSeenIndex: readNumber() });
|
|
431
|
+
}
|
|
432
|
+
// Parse EmissionYieldTrackers (3 trackers x 64 bytes each)
|
|
433
|
+
const emissions = [];
|
|
434
|
+
for (let j = 0; j < PERSONAL_TICK_YIELD_TRACKER_SIZE; j++) {
|
|
435
|
+
const lastSeenIndex = readNumber();
|
|
436
|
+
const lastPositionIndex = readNumber();
|
|
437
|
+
emissions.push({ lastSeenIndex, lastPositionIndex });
|
|
438
|
+
}
|
|
439
|
+
// Parse last_split_epoch (u64)
|
|
440
|
+
const lastSplitEpoch = data.readBigUInt64LE(offset);
|
|
441
|
+
offset += 8;
|
|
442
|
+
// Skip padding (u64)
|
|
443
|
+
offset += 8;
|
|
444
|
+
if (apyBasePoints === 0)
|
|
445
|
+
continue;
|
|
446
|
+
ticks.push({
|
|
447
|
+
apyBasePoints,
|
|
448
|
+
liquidityNet,
|
|
449
|
+
feeGrowthOutsidePt,
|
|
450
|
+
feeGrowthOutsideSy,
|
|
451
|
+
liquidityGross,
|
|
452
|
+
impliedRate,
|
|
453
|
+
principalPt,
|
|
454
|
+
principalSy,
|
|
455
|
+
principalShareSupply,
|
|
456
|
+
farms,
|
|
457
|
+
emissions,
|
|
458
|
+
lastSplitEpoch,
|
|
459
|
+
});
|
|
460
|
+
// console.log(ticks)
|
|
461
|
+
}
|
|
462
|
+
const market = readPubkey();
|
|
463
|
+
const feeGrowthIndexGlobalPt = readU128LE(data, offset);
|
|
464
|
+
offset += 16;
|
|
465
|
+
const feeGrowthIndexGlobalSy = readU128LE(data, offset);
|
|
466
|
+
offset += 16;
|
|
467
|
+
const currentPrefixSum = data.readBigUInt64LE(offset); // Active liquidity at current tick
|
|
468
|
+
offset += 8;
|
|
469
|
+
const currentSpotPrice = data.readDoubleLE(offset);
|
|
470
|
+
offset += 8;
|
|
471
|
+
const currentTick = data.readUint32LE(offset);
|
|
472
|
+
offset += 4;
|
|
473
|
+
offset += 12; // padding
|
|
474
|
+
return {
|
|
475
|
+
ticksTree: ticks,
|
|
476
|
+
market,
|
|
477
|
+
feeGrowthIndexGlobalPt,
|
|
478
|
+
feeGrowthIndexGlobalSy,
|
|
479
|
+
currentPrefixSum,
|
|
480
|
+
currentSpotPrice,
|
|
481
|
+
currentTick,
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
exports.deserializeMarketThreeTicks = deserializeMarketThreeTicks;
|
|
485
|
+
function deserializeMarketThree(m) {
|
|
486
|
+
return {
|
|
487
|
+
addressLookupTable: m.addressLookupTable,
|
|
488
|
+
mintSy: m.mintSy,
|
|
489
|
+
mintPt: m.mintPt,
|
|
490
|
+
vault: m.vault,
|
|
491
|
+
tokenSyEscrow: m.tokenSyEscrow,
|
|
492
|
+
tokenPtEscrow: m.tokenPtEscrow,
|
|
493
|
+
tokenFeeTreasurySy: m.tokenFeeTreasurySy,
|
|
494
|
+
tokenFeeTreasuryPt: m.tokenFeeTreasuryPt,
|
|
495
|
+
selfAddress: m.selfAddress,
|
|
496
|
+
syProgram: m.syProgram,
|
|
497
|
+
statusFlags: m.statusFlags,
|
|
498
|
+
cpiSyAccounts: m.cpiSyAccounts,
|
|
499
|
+
isCurrentFlashSwap: m.isCurrentFlashSwap,
|
|
500
|
+
lpFarm: m.lpFarm,
|
|
501
|
+
mintYt: m.mintYt,
|
|
502
|
+
tokenYtEscrow: m.tokenYtEscrow,
|
|
503
|
+
emissions: {
|
|
504
|
+
trackers: m.emissions.trackers.map((t) => ({
|
|
505
|
+
tokenEscrow: t.tokenEscrow,
|
|
506
|
+
lpShareIndex: deserializeAnchorizedPNum(t.lpShareIndex),
|
|
507
|
+
lastSeenStaged: Number(t.lastSeenStaged),
|
|
508
|
+
})),
|
|
509
|
+
},
|
|
510
|
+
liquidityNetBalanceLimits: m.liquidityNetBalanceLimits,
|
|
511
|
+
admin: m.admin,
|
|
512
|
+
ticks: m.ticks,
|
|
513
|
+
configurationOptions: {
|
|
514
|
+
lnFeeRateRoot: m.configurationOptions.lnFeeRateRoot,
|
|
515
|
+
treasuryFeeBps: m.configurationOptions.treasuryFeeBps,
|
|
516
|
+
minLpTickAmount: BigInt(m.configurationOptions.minLpTickAmount.toString()),
|
|
517
|
+
epsilonClamp: m.configurationOptions.epsilonClamp,
|
|
518
|
+
maxLpSupply: BigInt(m.configurationOptions.maxLpSupply.toString()),
|
|
519
|
+
tickSpace: m.configurationOptions.tickSpace,
|
|
520
|
+
},
|
|
521
|
+
financials: {
|
|
522
|
+
expirationTs: BigInt(m.financials.expirationTs),
|
|
523
|
+
ptBalance: BigInt(m.financials.ptBalance.toString()),
|
|
524
|
+
syBalance: BigInt(m.financials.syBalance.toString()),
|
|
525
|
+
liquidityBalance: BigInt(m.financials.liquidityBalance.toString()),
|
|
526
|
+
},
|
|
527
|
+
cpiCoreAccounts: m.cpiCoreAccounts,
|
|
528
|
+
exponentCoreProgram: m.exponentCoreProgram,
|
|
529
|
+
};
|
|
530
|
+
}
|
|
221
531
|
function deserializeMarketTwo(m) {
|
|
222
532
|
return {
|
|
223
533
|
ptBalance: BigInt(m.financials.ptBalance.toString()),
|
|
@@ -255,6 +565,33 @@ function deserializeMarketTwo(m) {
|
|
|
255
565
|
seedId: m.seedId,
|
|
256
566
|
};
|
|
257
567
|
}
|
|
568
|
+
function deserializeLpPositionCLMM(x) {
|
|
569
|
+
return {
|
|
570
|
+
owner: x.owner,
|
|
571
|
+
market: x.market,
|
|
572
|
+
feeInsideLastPt: BigInt(x.feeInsideLastPt.toString()),
|
|
573
|
+
feeInsideLastSy: BigInt(x.feeInsideLastSy.toString()),
|
|
574
|
+
lpBalance: BigInt(x.lpBalance.toString()),
|
|
575
|
+
tokensOwedSy: BigInt(x.tokensOwedSy.toString()),
|
|
576
|
+
tokensOwedPt: BigInt(x.tokensOwedPt.toString()),
|
|
577
|
+
lowerTickIdx: x.lowerTickIdx,
|
|
578
|
+
upperTickIdx: x.upperTickIdx,
|
|
579
|
+
farms: x.farms.trackers.map((t) => ({
|
|
580
|
+
staged: BigInt(t.staged.toString()),
|
|
581
|
+
lastSeenIndex: parseFloat(precise_number_1.PreciseNumber.fromRaw(t.lastSeenIndex[0]).valueString),
|
|
582
|
+
})),
|
|
583
|
+
shareTrackers: x.shareTrackers.trackers.map((tracker) => ({
|
|
584
|
+
tickIdx: tracker.tickIdx,
|
|
585
|
+
rightTickIdx: tracker.rightTickIdx,
|
|
586
|
+
splitEpoch: BigInt(tracker.splitEpoch.toString()),
|
|
587
|
+
lpShare: BigInt(tracker.lpShare.toString()),
|
|
588
|
+
emissions: tracker.emissions.trackers.map((e) => ({
|
|
589
|
+
staged: BigInt(e.staged.toString()),
|
|
590
|
+
lastSeenIndex: parseFloat(precise_number_1.PreciseNumber.fromRaw(e.lastSeenIndex[0]).valueString),
|
|
591
|
+
})),
|
|
592
|
+
})),
|
|
593
|
+
};
|
|
594
|
+
}
|
|
258
595
|
function deserializeVault(x) {
|
|
259
596
|
return {
|
|
260
597
|
syProgram: x.syProgram,
|
|
@@ -285,6 +622,227 @@ function deserializeVault(x) {
|
|
|
285
622
|
maxPySupply: BigInt(x.maxPySupply.toString()),
|
|
286
623
|
};
|
|
287
624
|
}
|
|
625
|
+
function deserializeOrderbook(data) {
|
|
626
|
+
let offset = 0;
|
|
627
|
+
// 1) Skip Anchor discriminator
|
|
628
|
+
offset += anchor_1.DISCRIMINATOR_SIZE;
|
|
629
|
+
const readPubkey = () => {
|
|
630
|
+
const pk = new anchor_1.web3.PublicKey(data.slice(offset, offset + 32));
|
|
631
|
+
offset += 32;
|
|
632
|
+
return pk;
|
|
633
|
+
};
|
|
634
|
+
// ConfigurationOptions struct
|
|
635
|
+
const thresholdAmount = data.readBigUInt64LE(offset);
|
|
636
|
+
offset += 8;
|
|
637
|
+
const lnMakerFeeRate = data.readDoubleLE(offset);
|
|
638
|
+
offset += 8;
|
|
639
|
+
const lnTakerFeeRate = data.readDoubleLE(offset);
|
|
640
|
+
offset += 8;
|
|
641
|
+
const priceDecimals = data.readUint8(offset);
|
|
642
|
+
offset += 1;
|
|
643
|
+
// Skip ConfigurationOptions padding: _placeholder_one[15] + _placeholder_two[32] + _placeholder_three[32] + _placeholder_four[32] = 111 bytes
|
|
644
|
+
offset += 111;
|
|
645
|
+
// Pubkeys
|
|
646
|
+
const vault = readPubkey();
|
|
647
|
+
const yieldPosition = readPubkey();
|
|
648
|
+
const addressLookupTable = readPubkey();
|
|
649
|
+
const exponentCoreProgram = readPubkey();
|
|
650
|
+
const syProgram = readPubkey();
|
|
651
|
+
const tokenEscrowSy = readPubkey();
|
|
652
|
+
const tokenEscrowYt = readPubkey();
|
|
653
|
+
const tokenEscrowPt = readPubkey();
|
|
654
|
+
const cpiAccountOrderbook = readPubkey();
|
|
655
|
+
const admin = readPubkey();
|
|
656
|
+
// Skip last_sy_exchange_rate (Number type = 32 bytes)
|
|
657
|
+
offset += 32;
|
|
658
|
+
// OrderbookFinancials struct
|
|
659
|
+
// Skip last_seen_sy_index (Number type = 32 bytes)
|
|
660
|
+
offset += 32;
|
|
661
|
+
const ytBalance = data.readBigUInt64LE(offset);
|
|
662
|
+
offset += 8;
|
|
663
|
+
const syBalance = data.readBigUInt64LE(offset);
|
|
664
|
+
offset += 8;
|
|
665
|
+
const ptBalance = data.readBigUInt64LE(offset);
|
|
666
|
+
offset += 8;
|
|
667
|
+
const ytFeeBalance = data.readBigUInt64LE(offset);
|
|
668
|
+
offset += 8;
|
|
669
|
+
const syFeeBalance = data.readBigUInt64LE(offset);
|
|
670
|
+
offset += 8;
|
|
671
|
+
const ptFeeBalance = data.readBigUInt64LE(offset);
|
|
672
|
+
offset += 8;
|
|
673
|
+
const stagedSyBalance = data.readBigUInt64LE(offset);
|
|
674
|
+
offset += 8;
|
|
675
|
+
const expirationTs = data.readUInt32LE(offset);
|
|
676
|
+
offset += 4;
|
|
677
|
+
// Skip financials _padding: [u8; 4]
|
|
678
|
+
offset += 4;
|
|
679
|
+
const configurationOptions = {
|
|
680
|
+
priceDecimals,
|
|
681
|
+
thresholdAmount,
|
|
682
|
+
lnMakerFeeRate,
|
|
683
|
+
lnTakerFeeRate,
|
|
684
|
+
};
|
|
685
|
+
const financials = {
|
|
686
|
+
expirationTs,
|
|
687
|
+
syBalance: syBalance,
|
|
688
|
+
ytBalance: ytBalance,
|
|
689
|
+
ptBalance: ptBalance,
|
|
690
|
+
ytFeeBalance,
|
|
691
|
+
syFeeBalance,
|
|
692
|
+
ptFeeBalance,
|
|
693
|
+
stagedSy: stagedSyBalance,
|
|
694
|
+
};
|
|
695
|
+
// console.log("financials", financials)
|
|
696
|
+
// ─── Parse RedBlackTree slab ───────────────────────────────────────────────
|
|
697
|
+
// repr(C) gives: root: u32, pad to align NodeAllocator’s u64, then the NodeAllocator header
|
|
698
|
+
const root = data.readUInt32LE(offset);
|
|
699
|
+
offset += 4;
|
|
700
|
+
const padTo8 = 8;
|
|
701
|
+
offset += padTo8;
|
|
702
|
+
// NodeAllocator<T=RBNode<u32,PriceNode>, N=MAX_PRICE_NODES, R=3>
|
|
703
|
+
// header: size:u64, bump_index:u32, free_list_head:u32
|
|
704
|
+
const priceTreeSize = Number(data.readBigUInt64LE(offset));
|
|
705
|
+
offset += 8;
|
|
706
|
+
const _priceTreeBump = data.readUInt32LE(offset);
|
|
707
|
+
offset += 4;
|
|
708
|
+
const _priceTreeFreeIdx = data.readUInt32LE(offset);
|
|
709
|
+
offset += 4;
|
|
710
|
+
// each RBNode entry = registers[3] + key:u32 + first_offer:u32
|
|
711
|
+
const prices = [];
|
|
712
|
+
for (let i = 0; i < exponent_types_2.MAX_PRICE_NODES; i++) {
|
|
713
|
+
const left = data.readUInt32LE(offset);
|
|
714
|
+
offset += 4;
|
|
715
|
+
const right = data.readUInt32LE(offset);
|
|
716
|
+
offset += 4;
|
|
717
|
+
const parent = data.readUInt32LE(offset);
|
|
718
|
+
offset += 4;
|
|
719
|
+
offset += 4; // skip color
|
|
720
|
+
const key = data.readUInt32LE(offset);
|
|
721
|
+
offset += 4;
|
|
722
|
+
const firstOfferSellYt = data.readUInt32LE(offset);
|
|
723
|
+
offset += 4;
|
|
724
|
+
const firstOfferBuyYt = data.readUInt32LE(offset);
|
|
725
|
+
offset += 4;
|
|
726
|
+
const lastOfferSellYt = data.readUInt32LE(offset);
|
|
727
|
+
offset += 4;
|
|
728
|
+
const lastOfferBuyYt = data.readUInt32LE(offset);
|
|
729
|
+
offset += 4;
|
|
730
|
+
if (key === 0)
|
|
731
|
+
continue;
|
|
732
|
+
prices.push({ key, firstOfferSellYt, firstOfferBuyYt, lastOfferSellYt, lastOfferBuyYt, parent, left, right });
|
|
733
|
+
}
|
|
734
|
+
// ─── Parse Offers slab ────────────────────────────────────────────────────
|
|
735
|
+
// NodeAllocator<Offer, MAX_OFFERS, 4>
|
|
736
|
+
// header: size:u64, bump_index:u32, free_list_head:u32
|
|
737
|
+
const offersSize = Number(data.readBigUInt64LE(offset));
|
|
738
|
+
offset += 8;
|
|
739
|
+
const _offersBump = data.readUInt32LE(offset);
|
|
740
|
+
offset += 4;
|
|
741
|
+
const _offersFreeIdx = data.readUInt32LE(offset);
|
|
742
|
+
offset += 4;
|
|
743
|
+
const offers = [];
|
|
744
|
+
for (let i = 0; i < exponent_types_2.MAX_OFFERS; i++) {
|
|
745
|
+
const register = data.readUInt32LE(offset);
|
|
746
|
+
offset += 4;
|
|
747
|
+
const nextOfferPointer = data.readUInt32LE(offset);
|
|
748
|
+
offset += 4;
|
|
749
|
+
const userVaultPointer = data.readUInt32LE(offset);
|
|
750
|
+
offset += 4;
|
|
751
|
+
const pricePointer = data.readUInt32LE(offset);
|
|
752
|
+
offset += 4;
|
|
753
|
+
const amount = data.readBigUInt64LE(offset);
|
|
754
|
+
offset += 8;
|
|
755
|
+
const expiryAt = data.readUInt32LE(offset);
|
|
756
|
+
offset += 4;
|
|
757
|
+
const createdAt = data.readUInt32LE(offset);
|
|
758
|
+
offset += 4;
|
|
759
|
+
const virtualOffer = data.readUInt8(offset) !== 0;
|
|
760
|
+
offset += 1;
|
|
761
|
+
const orderTypeFlag = data.readUInt8(offset);
|
|
762
|
+
offset += 1;
|
|
763
|
+
const fillOrKill = data.readUInt8(offset) !== 0;
|
|
764
|
+
offset += 1;
|
|
765
|
+
offset += 5; // reserved padding
|
|
766
|
+
if (userVaultPointer === 0)
|
|
767
|
+
continue;
|
|
768
|
+
offers.push({
|
|
769
|
+
nextOfferPointer,
|
|
770
|
+
amount,
|
|
771
|
+
userVaultPointer,
|
|
772
|
+
expiryAt,
|
|
773
|
+
createdAt,
|
|
774
|
+
virtualOffer,
|
|
775
|
+
orderTypeFlag,
|
|
776
|
+
fillOrKill,
|
|
777
|
+
pricePointer,
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
// ─── Parse UserEscrow slab ────────────────────────────────────────────────
|
|
781
|
+
// NodeAllocator<UserEscrow, MAX_USER_ESCROWS, 2>
|
|
782
|
+
// header: size:u64, bump_index:u32, free_list_head:u32
|
|
783
|
+
const escSize = Number(data.readBigUInt64LE(offset));
|
|
784
|
+
offset += 8;
|
|
785
|
+
const _escBump = data.readUInt32LE(offset);
|
|
786
|
+
offset += 4;
|
|
787
|
+
const _escFreeIdx = data.readUInt32LE(offset);
|
|
788
|
+
offset += 4;
|
|
789
|
+
// each Node = [ no registers ] + UserEscrow.value
|
|
790
|
+
const userEscrows = [];
|
|
791
|
+
for (let i = 0; i < exponent_types_2.MAX_USER_ESCROWS; i++) {
|
|
792
|
+
const register = data.readUInt32LE(offset);
|
|
793
|
+
offset += 4;
|
|
794
|
+
const register2 = data.readUInt32LE(offset);
|
|
795
|
+
offset += 4;
|
|
796
|
+
const user = new anchor_1.web3.PublicKey(data.slice(offset, offset + 32));
|
|
797
|
+
offset += 32;
|
|
798
|
+
/*const yieldIndex = data.readBigUInt64LE(offset).toString();*/ offset += 32;
|
|
799
|
+
const ptAmount = data.readBigUInt64LE(offset);
|
|
800
|
+
offset += 8;
|
|
801
|
+
const syAmount = data.readBigUInt64LE(offset);
|
|
802
|
+
offset += 8;
|
|
803
|
+
const ytAmount = data.readBigUInt64LE(offset);
|
|
804
|
+
offset += 8;
|
|
805
|
+
const stakedYtAmount = data.readBigInt64LE(offset);
|
|
806
|
+
offset += 8;
|
|
807
|
+
const staged = data.readBigInt64LE(offset);
|
|
808
|
+
offset += 8;
|
|
809
|
+
offset += 8; // reserved
|
|
810
|
+
if (user.toBase58() == "11111111111111111111111111111111")
|
|
811
|
+
continue;
|
|
812
|
+
userEscrows.push({ user, yieldIndex: 0, ptAmount, syAmount, ytAmount, stakedYtAmount, staged });
|
|
813
|
+
}
|
|
814
|
+
// ─── Finally, seed_id + signer_bump + reserved ─────────────────────────────
|
|
815
|
+
// seed_id: [u8; 4]
|
|
816
|
+
const seedId = [
|
|
817
|
+
data.readUInt8(offset),
|
|
818
|
+
data.readUInt8(offset + 1),
|
|
819
|
+
data.readUInt8(offset + 2),
|
|
820
|
+
data.readUInt8(offset + 3),
|
|
821
|
+
];
|
|
822
|
+
offset += 4;
|
|
823
|
+
// signer_bump: [u8; 1]
|
|
824
|
+
const signerBump = data.readUInt8(offset);
|
|
825
|
+
offset += 1;
|
|
826
|
+
// _reserved: [u8; 3] - skip
|
|
827
|
+
offset += 3;
|
|
828
|
+
return {
|
|
829
|
+
vault,
|
|
830
|
+
yieldPosition,
|
|
831
|
+
addressLookupTable,
|
|
832
|
+
exponentCoreProgram,
|
|
833
|
+
syProgram,
|
|
834
|
+
admin,
|
|
835
|
+
tokenEscrowSy,
|
|
836
|
+
tokenEscrowYt,
|
|
837
|
+
tokenEscrowPt,
|
|
838
|
+
cpiAccountOrderbook,
|
|
839
|
+
financials,
|
|
840
|
+
prices,
|
|
841
|
+
configurationOptions,
|
|
842
|
+
offers,
|
|
843
|
+
userEscrows,
|
|
844
|
+
};
|
|
845
|
+
}
|
|
288
846
|
function deserializeMarginfiSyMeta(x) {
|
|
289
847
|
return {
|
|
290
848
|
...x,
|
|
@@ -320,6 +878,7 @@ function deserializeLpPosition(x) {
|
|
|
320
878
|
})),
|
|
321
879
|
};
|
|
322
880
|
}
|
|
881
|
+
exports.deserializeLpPosition = deserializeLpPosition;
|
|
323
882
|
function deserializeYtPosition(x) {
|
|
324
883
|
return {
|
|
325
884
|
owner: x.owner,
|
|
@@ -329,6 +888,7 @@ function deserializeYtPosition(x) {
|
|
|
329
888
|
emissions: x.emissions.map(deserializeYieldTokenTracker),
|
|
330
889
|
};
|
|
331
890
|
}
|
|
891
|
+
exports.deserializeYtPosition = deserializeYtPosition;
|
|
332
892
|
function deserializeYieldTokenTracker(x) {
|
|
333
893
|
return {
|
|
334
894
|
staged: BigInt(x.staged.toString()),
|
|
@@ -340,10 +900,13 @@ async function fetchKaminoReserve(address, connection) {
|
|
|
340
900
|
if (!reserve) {
|
|
341
901
|
throw new Error("Reserve not found");
|
|
342
902
|
}
|
|
903
|
+
const rawScopePriceFeed = reserve.config.tokenInfo.scopeConfiguration.priceFeed;
|
|
904
|
+
const scopePriceFeed = rawScopePriceFeed.equals(anchor_1.web3.PublicKey.default) ? undefined : rawScopePriceFeed;
|
|
343
905
|
return {
|
|
344
906
|
lendingMarket: reserve.lendingMarket,
|
|
345
907
|
baseMint: reserve.liquidity.mintPubkey,
|
|
346
908
|
assetShareValue: reserve.getCollateralExchangeRate(),
|
|
909
|
+
scopePriceFeed,
|
|
347
910
|
};
|
|
348
911
|
}
|
|
349
912
|
exports.fetchKaminoReserve = fetchKaminoReserve;
|
|
@@ -406,24 +969,7 @@ function deserializeAnchorizedPNum(x) {
|
|
|
406
969
|
/** Fetch the exchange rate of a JitoRestaking vault's VRT to JitoSOL */
|
|
407
970
|
async function fetchJitoVaultData({ connection, vaultAddress, }) {
|
|
408
971
|
const vaultAccountInfo = await connection.getAccountInfo(vaultAddress);
|
|
409
|
-
|
|
410
|
-
// the vault has an 8 byte discriminator at the beginning
|
|
411
|
-
const discriminatorOffset = 8;
|
|
412
|
-
const vrtMintOffset = 32 + discriminatorOffset;
|
|
413
|
-
const vrtSupplyOffset = 96 + discriminatorOffset;
|
|
414
|
-
const jitoVaultTotalDepositsOffset = 104 + discriminatorOffset;
|
|
415
|
-
const mintBase = new anchor_1.web3.PublicKey(d.slice(vrtMintOffset, vrtMintOffset + 32));
|
|
416
|
-
// For Borsh, numbers are serialized in little-endian format
|
|
417
|
-
const jitoVaultTotalSharesBuffer = d.slice(vrtSupplyOffset, vrtSupplyOffset + 8);
|
|
418
|
-
const jitoVaultTotalShares = new anchor_1.BN(jitoVaultTotalSharesBuffer, "le");
|
|
419
|
-
const jitoVaultTotalDepositsBuffer = d.slice(jitoVaultTotalDepositsOffset, jitoVaultTotalDepositsOffset + 8);
|
|
420
|
-
const jitoVaultTotalDeposits = new anchor_1.BN(jitoVaultTotalDepositsBuffer, "le");
|
|
421
|
-
const jitoVaultTotalSharesD = new decimal_js_1.default(jitoVaultTotalShares.toString());
|
|
422
|
-
const jitoVaultTotalDepositsD = new decimal_js_1.default(jitoVaultTotalDeposits.toString());
|
|
423
|
-
const exchangeRate = jitoVaultTotalDepositsD.isZero()
|
|
424
|
-
? "1.0"
|
|
425
|
-
: jitoVaultTotalDepositsD.div(jitoVaultTotalSharesD).toString();
|
|
426
|
-
return { exchangeRate: parseFloat(exchangeRate), mintBase };
|
|
972
|
+
return (0, jito_1.decodeJitoVaultData)(vaultAccountInfo.data);
|
|
427
973
|
}
|
|
428
974
|
async function fetchJitoSolToSolExchangeRate({ connection, interfaceType, accounts, }) {
|
|
429
975
|
if (interfaceType.splStakePool) {
|
|
@@ -438,16 +984,13 @@ async function fetchSplStakePoolIndex({ connection, stakePool, }) {
|
|
|
438
984
|
}
|
|
439
985
|
exports.fetchSplStakePoolIndex = fetchSplStakePoolIndex;
|
|
440
986
|
async function fetchPerenaStablePoolData({ connection, perenaStablePool, }) {
|
|
441
|
-
const
|
|
987
|
+
const lpMint = (0, perena_1.getPerenaLpMint)(perenaStablePool);
|
|
442
988
|
const [accountInfo, lpMintInfo] = await connection.getMultipleAccountsInfo([perenaStablePool, lpMint]);
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
const invT = Buffer.from(invTBuffer).readBigUInt64LE(0);
|
|
449
|
-
const exchangeRate = new decimal_js_1.default(invT.toString()).div(new decimal_js_1.default(lpMintDeserialized.supply.toString())).toString();
|
|
450
|
-
return { lpSupply: lpMintDeserialized.supply, invT, exchangeRate, lpMint };
|
|
989
|
+
const { lpSupply, invT, exchangeRate } = (0, perena_1.getPerenaStablePoolData)({
|
|
990
|
+
perenaStablePoolData: accountInfo.data,
|
|
991
|
+
lpMintData: lpMintInfo.data,
|
|
992
|
+
});
|
|
993
|
+
return { lpSupply, invT, exchangeRate, lpMint };
|
|
451
994
|
}
|
|
452
995
|
exports.fetchPerenaStablePoolData = fetchPerenaStablePoolData;
|
|
453
996
|
/**
|
|
@@ -477,40 +1020,14 @@ exports.fetchJitoRestaking = fetchJitoRestaking;
|
|
|
477
1020
|
* and tracks last_* values to compute the next index increment similar to the program.
|
|
478
1021
|
*/
|
|
479
1022
|
async function fetchJupiterPerpsIndex({ connection, pool, lastFeeUsdResetUnixTimestamp, lastRealizedFeeUsd, lastAumUsd, currentIndex, lastRealizedFeeUsdUpdateUnixTimestamp, }) {
|
|
480
|
-
// Decode pool account using helper that leverages Anchor 0.29.0
|
|
481
1023
|
const accountInfo = await connection.getAccountInfo(pool);
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
const timeBetweenResets = Number(account.poolApr.lastUpdated) - lastFeeUsdResetUnixTimestamp;
|
|
490
|
-
const feeAprBps = new anchor_1.BN(account.poolApr.feeAprBps);
|
|
491
|
-
const estTotalFees = lastAumUsd.gt(new anchor_1.BN(0)) && timeBetweenResets > 0
|
|
492
|
-
? feeAprBps.mul(lastAumUsd).mul(new anchor_1.BN(timeBetweenResets)).div(new anchor_1.BN(SECONDS_PER_YEAR)).div(new anchor_1.BN(10_000))
|
|
493
|
-
: new anchor_1.BN(0);
|
|
494
|
-
const missingFees = estTotalFees.sub(lastRealizedFeeUsd);
|
|
495
|
-
const feesSinceReset = new anchor_1.BN(account.poolApr.realizedFeeUsd.toString());
|
|
496
|
-
newFeesBn = missingFees.add(feesSinceReset);
|
|
497
|
-
}
|
|
498
|
-
else {
|
|
499
|
-
newFeesBn = new anchor_1.BN(account.poolApr.realizedFeeUsd.toString()).sub(lastRealizedFeeUsd);
|
|
500
|
-
}
|
|
501
|
-
const aumUsd = new anchor_1.BN(account.aumUsd.toString());
|
|
502
|
-
const indexIncrease = new decimal_js_1.default(newFeesBn.toString()).div(new decimal_js_1.default(aumUsd.toString())).toNumber();
|
|
503
|
-
const currentIndexNum = parseFloat(precise_number_1.PreciseNumber.fromRaw(currentIndex[0]).valueString);
|
|
504
|
-
const nextIndex = currentIndexNum + indexIncrease;
|
|
505
|
-
return {
|
|
506
|
-
index: nextIndex,
|
|
507
|
-
newState: {
|
|
508
|
-
lastAumUsd: aumUsd,
|
|
509
|
-
lastRealizedFeeUsd: new anchor_1.BN(account.poolApr.realizedFeeUsd.toString()),
|
|
510
|
-
lastFeeUsdResetUnixTimestamp: Number(account.poolApr.lastUpdated),
|
|
511
|
-
lastRealizedFeeUsdUpdateUnixTimestamp: Math.floor(Date.now() / 1000),
|
|
512
|
-
},
|
|
513
|
-
};
|
|
1024
|
+
return (0, jupiter_1.calculateJupiterPerpsIndex)({ pool: accountInfo.data }, {
|
|
1025
|
+
lastFeeUsdResetUnixTimestamp,
|
|
1026
|
+
lastRealizedFeeUsd,
|
|
1027
|
+
lastAumUsd,
|
|
1028
|
+
currentIndex,
|
|
1029
|
+
lastRealizedFeeUsdUpdateUnixTimestamp,
|
|
1030
|
+
});
|
|
514
1031
|
}
|
|
515
1032
|
exports.fetchJupiterPerpsIndex = fetchJupiterPerpsIndex;
|
|
516
1033
|
async function fetchPyth(connection) {
|
|
@@ -543,28 +1060,27 @@ async function fetchGenericSyMetaIndex({ connection, genericSyMeta, }) {
|
|
|
543
1060
|
}
|
|
544
1061
|
exports.fetchGenericSyMetaIndex = fetchGenericSyMetaIndex;
|
|
545
1062
|
async function fetchFragmetricIndex({ connection, fragmetricFund, }) {
|
|
546
|
-
const
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
const receiptTokenMint = new anchor_1.web3.PublicKey(data.receipt_token_mint);
|
|
551
|
-
const wrappedTokenMint = new anchor_1.web3.PublicKey(data.wrapped_token.mint);
|
|
1063
|
+
const fragmetricFundRaw = await connection.getAccountInfo(fragmetricFund);
|
|
1064
|
+
const { index, receiptTokenMint, wrappedTokenMint } = (0, fragmetric_1.calculateFragmetricIndex)({
|
|
1065
|
+
fragmetricFund: fragmetricFundRaw.data,
|
|
1066
|
+
});
|
|
552
1067
|
return { index, receiptTokenMint, wrappedTokenMint };
|
|
553
1068
|
}
|
|
554
1069
|
exports.fetchFragmetricIndex = fetchFragmetricIndex;
|
|
555
1070
|
async function fetchJupiterLendIndex({ connection, jupiterLendAccount, }) {
|
|
556
1071
|
const account = await connection.getAccountInfo(jupiterLendAccount);
|
|
557
|
-
const coder = new anchor_2.BorshCoder(jupiter_lend_idl_1.IDL);
|
|
558
|
-
const data = coder.accounts.decode("Lending", account.data);
|
|
559
|
-
const index = Number(data.token_exchange_price) / Number(10 ** 12);
|
|
560
|
-
const tokenReservesLiquidity = data.token_reserves_liquidity;
|
|
561
|
-
const lendingSupplyPosition = data.supply_position_on_liquidity;
|
|
562
|
-
const rewardsRateModel = data.rewards_rate_model;
|
|
563
1072
|
const rateModel = jupiterLendAccount.equals(new anchor_1.web3.PublicKey("BeAqbxfrcXmzEYT2Ra62oW2MqkuFDHaCtps47Mzg6Zj3"))
|
|
564
1073
|
? new anchor_1.web3.PublicKey("Acvyi9HBGmqh3Exe1N4PjBVyY8fokq2AdC6fSLqV6KSo")
|
|
565
1074
|
: new anchor_1.web3.PublicKey("6iHHKAK9Mqjn57CVmWe4szAPyTH8s8pniXSj6vWaKW5r");
|
|
566
|
-
|
|
567
|
-
return {
|
|
1075
|
+
const { index, baseTokenMint, tokenReservesLiquidity, lendingSupplyPosition, rewardsRateModel } = (0, jupiter_1.calculateJupiterLendIndex)({ jupiterLend: account.data });
|
|
1076
|
+
return {
|
|
1077
|
+
rateModel,
|
|
1078
|
+
index,
|
|
1079
|
+
baseTokenMint,
|
|
1080
|
+
tokenReservesLiquidity,
|
|
1081
|
+
lendingSupplyPosition,
|
|
1082
|
+
rewardsRateModel,
|
|
1083
|
+
};
|
|
568
1084
|
}
|
|
569
1085
|
exports.fetchJupiterLendIndex = fetchJupiterLendIndex;
|
|
570
1086
|
async function fetchKaminoVaultIndex({ connection, kaminoVaultAccount, }) {
|
|
@@ -593,24 +1109,18 @@ async function fetchKaminoVaultIndex({ connection, kaminoVaultAccount, }) {
|
|
|
593
1109
|
exports.fetchKaminoVaultIndex = fetchKaminoVaultIndex;
|
|
594
1110
|
async function fetchFragmetricSupportedTokenIndex({ connection, fragmetricFund, index, }) {
|
|
595
1111
|
const account = await connection.getAccountInfo(fragmetricFund);
|
|
596
|
-
|
|
597
|
-
const data = coder.accounts.decode("FundAccount", account.data);
|
|
598
|
-
const syIndex = Number(10 ** data.supported_tokens[index].decimals) /
|
|
599
|
-
Number(data.supported_tokens[index].one_token_as_receipt_token);
|
|
600
|
-
const receiptTokenMint = new anchor_1.web3.PublicKey(data.receipt_token_mint);
|
|
601
|
-
const wrappedTokenMint = new anchor_1.web3.PublicKey(data.wrapped_token.mint);
|
|
602
|
-
return { index: syIndex, receiptTokenMint, wrappedTokenMint };
|
|
1112
|
+
return (0, fragmetric_1.calculateFragmetricSupportedTokenIndex)({ fragmetricFund: account.data }, index);
|
|
603
1113
|
}
|
|
604
1114
|
exports.fetchFragmetricSupportedTokenIndex = fetchFragmetricSupportedTokenIndex;
|
|
605
1115
|
async function fetchMeteoraIndex({ connection, accounts, onChainTime, }) {
|
|
606
1116
|
try {
|
|
607
1117
|
const VIRTUAL_PRICE_PRECISION = new anchor_1.BN(100_000_000);
|
|
608
|
-
const pool = await (0, meteora_idl_1.
|
|
1118
|
+
const pool = await (0, meteora_idl_1.fetchPoolAccount)(connection, accounts.pool);
|
|
609
1119
|
const poolMint = await (0, spl_token_1.getMint)(connection, pool.lpMint);
|
|
610
1120
|
const poolLpSupply = new anchor_1.BN(poolMint.supply.toString());
|
|
611
1121
|
const poolLpDecimals = Number(poolMint.decimals.toString());
|
|
612
|
-
const vaultA = await (0, meteora_idl_1.
|
|
613
|
-
const vaultB = await (0, meteora_idl_1.
|
|
1122
|
+
const vaultA = await (0, meteora_idl_1.fetchVaultAccount)(connection, accounts.vaultA);
|
|
1123
|
+
const vaultB = await (0, meteora_idl_1.fetchVaultAccount)(connection, accounts.vaultB);
|
|
614
1124
|
const vaultLpMintA = await (0, spl_token_1.getMint)(connection, vaultA.lpMint);
|
|
615
1125
|
const vaultLpMintB = await (0, spl_token_1.getMint)(connection, vaultB.lpMint);
|
|
616
1126
|
const vaultALpSupply = vaultLpMintA.supply;
|
|
@@ -640,7 +1150,6 @@ async function fetchMeteoraIndex({ connection, accounts, onChainTime, }) {
|
|
|
640
1150
|
exports.fetchMeteoraIndex = fetchMeteoraIndex;
|
|
641
1151
|
async function fetchAdrenaIndex({ connection, accounts, previousTotalFees, currentIndex, }) {
|
|
642
1152
|
try {
|
|
643
|
-
const zero = new anchor_1.BN(0);
|
|
644
1153
|
// Fetch all account data in a single RPC call
|
|
645
1154
|
const accountInfos = await connection.getMultipleAccountsInfo([
|
|
646
1155
|
accounts.pool,
|
|
@@ -652,19 +1161,13 @@ async function fetchAdrenaIndex({ connection, accounts, previousTotalFees, curre
|
|
|
652
1161
|
if (!accountInfos[0] || !accountInfos[1] || !accountInfos[2] || !accountInfos[3] || !accountInfos[4]) {
|
|
653
1162
|
throw new Error("One or more Adrena accounts not found");
|
|
654
1163
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
yieldIncrement = 0;
|
|
663
|
-
}
|
|
664
|
-
let feeDifference = currentTotalFees.gte(previousTotalFees) ? currentTotalFees.sub(previousTotalFees) : zero;
|
|
665
|
-
yieldIncrement = feeDifference.toNumber() / aumValue.toNumber();
|
|
666
|
-
let currentIndexNumber = parseFloat(precise_number_1.PreciseNumber.fromRaw(currentIndex[0]).valueString);
|
|
667
|
-
return { index: currentIndexNumber + yieldIncrement };
|
|
1164
|
+
return (0, adrena_1.calculateAdrenaIndex)({
|
|
1165
|
+
pool: accountInfos[0].data,
|
|
1166
|
+
custody1: accountInfos[1].data,
|
|
1167
|
+
custody2: accountInfos[2].data,
|
|
1168
|
+
custody3: accountInfos[3].data,
|
|
1169
|
+
custody4: accountInfos[4].data,
|
|
1170
|
+
}, previousTotalFees, currentIndex);
|
|
668
1171
|
}
|
|
669
1172
|
catch (error) {
|
|
670
1173
|
throw error;
|
|
@@ -672,70 +1175,65 @@ async function fetchAdrenaIndex({ connection, accounts, previousTotalFees, curre
|
|
|
672
1175
|
}
|
|
673
1176
|
exports.fetchAdrenaIndex = fetchAdrenaIndex;
|
|
674
1177
|
async function fetchSanctumIndex({ connection, accounts, }) {
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
const lpTokenSupplyBn = new anchor_1.BN(lpMint.supply.toString());
|
|
681
|
-
const poolTotalSolValueBn = new anchor_1.BN(poolState.totalSolValue.toString());
|
|
682
|
-
if (lpTokenSupplyBn.eq(zeroBn) || poolTotalSolValueBn.eq(zeroBn)) {
|
|
683
|
-
return 1;
|
|
684
|
-
}
|
|
685
|
-
const exchangeRateBn = lpTokenSupplyBn.mul(precision).div(poolTotalSolValueBn);
|
|
686
|
-
const exchangeRate = new decimal_js_1.default(exchangeRateBn.toString()).div(precision.toString()).toNumber();
|
|
687
|
-
return 1 / exchangeRate; // We return inverse exchange rate
|
|
688
|
-
}
|
|
689
|
-
catch (error) {
|
|
690
|
-
throw error;
|
|
691
|
-
}
|
|
1178
|
+
const [poolStateAccountRaw, lpMintAccountRaw] = await Promise.all([accounts.poolState, accounts.lpMint].map((pk) => connection.getAccountInfo(pk)));
|
|
1179
|
+
return (0, sanctum_1.calculateSanctumIndex)({
|
|
1180
|
+
poolStateAccountData: poolStateAccountRaw.data,
|
|
1181
|
+
lpMintAccountData: lpMintAccountRaw.data,
|
|
1182
|
+
});
|
|
692
1183
|
}
|
|
693
1184
|
exports.fetchSanctumIndex = fetchSanctumIndex;
|
|
694
1185
|
async function fetchSolsticeRedemptionRate({ connection, yieldPool, vestingSchedule, }) {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
throw new Error("One or more Solstice accounts not found");
|
|
700
|
-
}
|
|
701
|
-
// Decode accounts using solstice-idl package function
|
|
702
|
-
const { yieldPoolAccount, vestingScheduleAccount } = (0, solstice_idl_1.decodeYieldPoolAndVestingScheduleAccounts)(accountInfos);
|
|
703
|
-
// Extract fields for calculation (convert BN to bigint)
|
|
704
|
-
const poolTotalAssets = BigInt(yieldPoolAccount.total_assets.toString());
|
|
705
|
-
const poolSharesSupply = BigInt(yieldPoolAccount.shares_supply.toString());
|
|
706
|
-
const vestingAmount = BigInt(vestingScheduleAccount.vesting_amount.toString());
|
|
707
|
-
// Calculate total vested assets (mimicking the Rust logic)
|
|
708
|
-
let totalVestedAssets;
|
|
709
|
-
if (vestingAmount === 0n) {
|
|
710
|
-
totalVestedAssets = poolTotalAssets; // If no vesting amount, all assets are considered vested
|
|
711
|
-
}
|
|
712
|
-
else {
|
|
713
|
-
const vestingStart = BigInt(vestingScheduleAccount.start_time.toString());
|
|
714
|
-
const vestingEnd = BigInt(vestingScheduleAccount.end_time.toString());
|
|
715
|
-
const currentTime = BigInt(Math.floor(Date.now() / 1000)); // Current Unix timestamp
|
|
716
|
-
// Calculate unvested amount
|
|
717
|
-
let unvestedAmount;
|
|
718
|
-
if (currentTime > vestingEnd) {
|
|
719
|
-
unvestedAmount = 0n; // If current time passed the vesting end, no unvested amount
|
|
720
|
-
}
|
|
721
|
-
else {
|
|
722
|
-
unvestedAmount = (vestingAmount * (vestingEnd - currentTime)) / (vestingEnd - vestingStart);
|
|
723
|
-
}
|
|
724
|
-
totalVestedAssets = poolTotalAssets - unvestedAmount;
|
|
725
|
-
}
|
|
726
|
-
// Calculate redemption rate: (total_vested_assets + 1) / (pool_shares_supply + 1)
|
|
727
|
-
const redemptionRate = Number(totalVestedAssets + 1n) / Number(poolSharesSupply + 1n);
|
|
728
|
-
return {
|
|
729
|
-
redemptionRate,
|
|
730
|
-
totalAssets: poolTotalAssets.toString(),
|
|
731
|
-
sharesSupply: poolSharesSupply.toString(),
|
|
732
|
-
vestingAmount: vestingAmount.toString(),
|
|
733
|
-
totalVestedAssets: totalVestedAssets.toString(),
|
|
734
|
-
};
|
|
735
|
-
}
|
|
736
|
-
catch (error) {
|
|
737
|
-
throw error;
|
|
1186
|
+
// Fetch both accounts in a single RPC call for efficiency
|
|
1187
|
+
const accountInfos = await connection.getMultipleAccountsInfo([yieldPool, vestingSchedule]);
|
|
1188
|
+
if (!accountInfos[0] || !accountInfos[1]) {
|
|
1189
|
+
throw new Error("One or more Solstice accounts not found");
|
|
738
1190
|
}
|
|
1191
|
+
return (0, solstice_1.calculateSolsticeRedemptionRate)({ yieldPool: accountInfos[0].data, vestingSchedule: accountInfos[1].data });
|
|
739
1192
|
}
|
|
740
1193
|
exports.fetchSolsticeRedemptionRate = fetchSolsticeRedemptionRate;
|
|
1194
|
+
const REFLECT_ORACLE_LEN = 17;
|
|
1195
|
+
const REFLECT_MAX_STALENESS_SLOTS = 150;
|
|
1196
|
+
async function fetchReflectRedemptionRate({ connection, oracle, }) {
|
|
1197
|
+
const accountInfo = await connection.getAccountInfo(oracle);
|
|
1198
|
+
if (!accountInfo) {
|
|
1199
|
+
throw new Error("Reflect oracle account not found");
|
|
1200
|
+
}
|
|
1201
|
+
if (accountInfo.data.length !== REFLECT_ORACLE_LEN) {
|
|
1202
|
+
throw new Error(`Reflect oracle account has invalid length: ${accountInfo.data.length}`);
|
|
1203
|
+
}
|
|
1204
|
+
const slot = Number(accountInfo.data.readBigUInt64LE(0));
|
|
1205
|
+
const price = Number(accountInfo.data.readBigUInt64LE(8));
|
|
1206
|
+
const precision = accountInfo.data.readUInt8(16);
|
|
1207
|
+
const currentSlot = await connection.getSlot();
|
|
1208
|
+
if (slot > currentSlot) {
|
|
1209
|
+
throw new Error("Reflect oracle slot is ahead of the current slot");
|
|
1210
|
+
}
|
|
1211
|
+
const slotDelta = currentSlot - slot;
|
|
1212
|
+
if (slotDelta > REFLECT_MAX_STALENESS_SLOTS) {
|
|
1213
|
+
throw new Error("Reflect oracle data is stale");
|
|
1214
|
+
}
|
|
1215
|
+
const scale = Math.pow(10, precision);
|
|
1216
|
+
if (scale === 0) {
|
|
1217
|
+
throw new Error("Invalid oracle precision");
|
|
1218
|
+
}
|
|
1219
|
+
return price / scale;
|
|
1220
|
+
}
|
|
1221
|
+
exports.fetchReflectRedemptionRate = fetchReflectRedemptionRate;
|
|
1222
|
+
async function fetchOreExchangeRate({ connection, storeMint, stakeAccount, treasury, }) {
|
|
1223
|
+
// Fetch all accounts in parallel for efficiency
|
|
1224
|
+
const [storeMintInfo, stakeAccountInfo, treasuryAccountInfo] = await Promise.all([
|
|
1225
|
+
connection.getAccountInfo(storeMint),
|
|
1226
|
+
connection.getAccountInfo(stakeAccount),
|
|
1227
|
+
connection.getAccountInfo(treasury),
|
|
1228
|
+
]);
|
|
1229
|
+
if (!storeMintInfo || !stakeAccountInfo || !treasuryAccountInfo) {
|
|
1230
|
+
throw new Error("One or more ORE accounts not found");
|
|
1231
|
+
}
|
|
1232
|
+
return (0, ore_1.calculateOreExchangeRate)({
|
|
1233
|
+
stakeAccount: stakeAccountInfo.data,
|
|
1234
|
+
treasuryAccount: treasuryAccountInfo.data,
|
|
1235
|
+
storeMint: storeMintInfo.data,
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
exports.fetchOreExchangeRate = fetchOreExchangeRate;
|
|
741
1239
|
//# sourceMappingURL=exponentFetcher.js.map
|