@exponent-labs/exponent-fetcher 0.1.8 → 0.9.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.
@@ -3,13 +3,14 @@ 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.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;
6
+ exports.fetchChainlinkRate = 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.anchorizedPNumToRawBigint = exports.deserializeEmission = exports.serializeEmission = exports.fetchAllKaminoObligationsByKaminoReserve = exports.fetchKaminoReserve = exports.deserializeYtPosition = exports.deserializeLpPosition = exports.deserializeMarketThree = 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
11
  const bs58_1 = __importDefault(require("bs58"));
12
12
  const decimal_js_1 = __importDefault(require("decimal.js"));
13
+ const chainlink_idl_1 = require("@exponent-labs/chainlink-idl");
13
14
  const exponent_clmm_idl_1 = require("@exponent-labs/exponent-clmm-idl");
14
15
  const exponent_idl_1 = require("@exponent-labs/exponent-idl");
15
16
  const exponent_orderbook_idl_1 = require("@exponent-labs/exponent-orderbook-idl");
@@ -28,6 +29,7 @@ const meteora_idl_1 = require("@exponent-labs/meteora-idl");
28
29
  const perena_sy_idl_1 = require("@exponent-labs/perena-sy-idl");
29
30
  const perena_sy_idl_2 = require("@exponent-labs/perena-sy-idl");
30
31
  const precise_number_1 = require("@exponent-labs/precise-number");
32
+ const constants_1 = require("./constants");
31
33
  const adrena_1 = require("./utils/adrena");
32
34
  const fragmetric_1 = require("./utils/fragmetric");
33
35
  const jito_1 = require("./utils/jito");
@@ -42,11 +44,6 @@ function serializeAnchorizedPNumFromJson(pnum) {
42
44
  return { 0: serializedArray };
43
45
  }
44
46
  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
- }
50
47
  function deserializeAnchorizedPNumFromJson(serialized) {
51
48
  const bnArray = serialized[0].map((str) => new anchor_1.BN(str));
52
49
  return { 0: bnArray };
@@ -317,6 +314,7 @@ class ExponentFetcher {
317
314
  ],
318
315
  });
319
316
  return marketsProgramAccounts
317
+ .filter(({ pubkey }) => !(0, constants_1.isMarketIgnored)(pubkey.toBase58()))
320
318
  .map(({ account, pubkey }) => {
321
319
  try {
322
320
  return this.exponentClmmProgram.coder.accounts.decode("marketThree", account.data);
@@ -328,12 +326,16 @@ class ExponentFetcher {
328
326
  .filter((m) => !!m);
329
327
  }
330
328
  async fetchMarketThree(address) {
329
+ const addressStr = address.toBase58();
330
+ if ((0, constants_1.isMarketIgnored)(addressStr)) {
331
+ throw new constants_1.IgnoredClmmEntityError("market", addressStr);
332
+ }
331
333
  try {
332
334
  const m = await this.exponentClmmProgram.account.marketThree.fetch(address);
333
335
  return deserializeMarketThree(m);
334
336
  }
335
337
  catch (e) {
336
- console.error(`Error fetching market ${address.toBase58()}`);
338
+ console.error(`Error fetching market ${addressStr}`);
337
339
  console.error(e);
338
340
  throw e;
339
341
  }
@@ -350,32 +352,75 @@ class ExponentFetcher {
350
352
  },
351
353
  ],
352
354
  });
353
- return ticksAccounts.map(({ account }) => deserializeMarketThreeTicks(account.data));
355
+ return ticksAccounts
356
+ .filter(({ pubkey }) => !(0, constants_1.isTicksIgnored)(pubkey.toBase58()))
357
+ .map(({ account }) => deserializeMarketThreeTicks(account.data));
354
358
  }
355
359
  async fetchMarketThreeTicks(address) {
360
+ const addressStr = address.toBase58();
361
+ if ((0, constants_1.isTicksIgnored)(addressStr)) {
362
+ throw new constants_1.IgnoredClmmEntityError("ticks", addressStr);
363
+ }
356
364
  try {
357
365
  const m = (await this.connection.getAccountInfo(address)).data;
358
366
  return deserializeMarketThreeTicks(m);
359
367
  }
360
368
  catch (e) {
361
- console.error(`Error fetching market ${address.toBase58()}`);
369
+ console.error(`Error fetching ticks ${addressStr}`);
362
370
  console.error(e);
363
371
  throw e;
364
372
  }
365
373
  }
366
374
  }
367
375
  exports.ExponentFetcher = ExponentFetcher;
376
+ /**
377
+ * Deserializes a CLMM Ticks account from raw buffer data.
378
+ *
379
+ * Layout matches Rust struct `Ticks` with `RedBlackTree<u32, Tick, 1000>`:
380
+ * - Discriminator: 8 bytes
381
+ * - RedBlackTree header: root(4) + padding(12) + size(8) + bump(4) + freeIdx(4) = 32 bytes
382
+ * - 1000 RBTree nodes, each: nodeHeader(16) + key(4) + padding(4) + Tick = variable bytes
383
+ * - Ticks footer: market(32) + feeGrowthPt(16) + feeGrowthSy(16) + prefixSum(8) + spotPrice(8) + currentTick(4) + padding(12) = 96 bytes
384
+ */
368
385
  function deserializeMarketThreeTicks(data) {
369
- let offset = 8;
370
- const MAX_TICK_NODES = 100;
371
- const PERSONAL_TICK_YIELD_TRACKER_SIZE = 3;
386
+ const MAX_TICK_NODES = 1000;
387
+ const PERSONAL_TICK_YIELD_TRACKER_SIZE = 2;
388
+ let offset = 8; // Skip discriminator
389
+ // ─── Helper functions ─────────────────────────────────────────────────────
390
+ const readU64 = () => {
391
+ const val = data.readBigUInt64LE(offset);
392
+ offset += 8;
393
+ return val;
394
+ };
395
+ const readU128 = () => {
396
+ const lo = data.readBigUInt64LE(offset);
397
+ const hi = data.readBigUInt64LE(offset + 8);
398
+ offset += 16;
399
+ return (hi << 64n) + lo;
400
+ };
401
+ const readI128 = () => {
402
+ const lo = data.readBigUInt64LE(offset);
403
+ const hi = data.readBigInt64LE(offset + 8); // High part is signed
404
+ offset += 16;
405
+ return (hi << 64n) + lo;
406
+ };
407
+ const readF64 = () => {
408
+ const val = data.readDoubleLE(offset);
409
+ offset += 8;
410
+ return val;
411
+ };
412
+ const readU32 = () => {
413
+ const val = data.readUInt32LE(offset);
414
+ offset += 4;
415
+ return val;
416
+ };
372
417
  const readPubkey = () => {
373
418
  const pk = new anchor_1.web3.PublicKey(data.slice(offset, offset + 32));
374
419
  offset += 32;
375
420
  return pk;
376
421
  };
377
- const readNumber = () => {
378
- // Number is 32 bytes (4 x u64)
422
+ /** Reads a PreciseNumber (Number type in Rust) as float - 32 bytes (4 x u64) */
423
+ const readPreciseNumberAsFloat = () => {
379
424
  const nums = [];
380
425
  for (let i = 0; i < 4; i++) {
381
426
  nums.push(new anchor_1.BN(data.slice(offset + i * 8, offset + (i + 1) * 8), undefined, "le"));
@@ -383,94 +428,81 @@ function deserializeMarketThreeTicks(data) {
383
428
  offset += 32;
384
429
  return parseFloat(precise_number_1.PreciseNumber.fromRaw(nums).valueString);
385
430
  };
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;
431
+ /** Reads a PreciseNumber (Number type in Rust) as raw bigint - 32 bytes (4 x u64 = 256 bits) */
432
+ const readPreciseNumberAsBigint = () => {
433
+ let val = 0n;
434
+ for (let i = 0; i < 4; i++) {
435
+ const chunk = data.readBigUInt64LE(offset + i * 8);
436
+ val += chunk << BigInt(i * 64);
437
+ }
438
+ offset += 32;
439
+ return val;
440
+ };
441
+ const skip = (bytes) => {
442
+ offset += bytes;
443
+ };
444
+ // ─── Parse RedBlackTree header ────────────────────────────────────────────
445
+ skip(4); // root: u32
446
+ skip(12); // padding to align NodeAllocator
447
+ skip(8); // size: u64
448
+ skip(4); // bump_index: u32
449
+ skip(4); // free_list_head: u32
450
+ // ─── Parse tick nodes ─────────────────────────────────────────────────────
400
451
  const ticks = [];
401
452
  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)
453
+ // RBNode header: left(4) + right(4) + parent(4) + color(4) = 16 bytes
454
+ skip(16);
455
+ // Key: u32 + padding to 8 bytes
456
+ const apyBasePoints = readU32();
457
+ skip(4); // padding
458
+ // Tick value (416 bytes total)
459
+ const feeGrowthOutsidePt = readU128(); // 16 bytes
460
+ const feeGrowthOutsideSy = readU128(); // 16 bytes
461
+ const liquidityNet = readI128(); // 16 bytes
462
+ const liquidityGross = readU64(); // 8 bytes
463
+ const spotPrice = readF64(); // 8 bytes
464
+ const principalPt = readU64(); // 8 bytes
465
+ const principalSy = readU64(); // 8 bytes
466
+ const principalShareSupply = readPreciseNumberAsBigint(); // 32 bytes - kept as bigint for arithmetic
467
+ // FarmYieldTrackers: 2 x FarmYieldTracker(32 bytes) = 64 bytes
428
468
  const farms = [];
429
469
  for (let j = 0; j < PERSONAL_TICK_YIELD_TRACKER_SIZE; j++) {
430
- farms.push({ lastSeenIndex: readNumber() });
470
+ farms.push({ lastSeenIndex: readPreciseNumberAsFloat() });
431
471
  }
432
- // Parse EmissionYieldTrackers (3 trackers x 64 bytes each)
472
+ // EmissionYieldTrackers: 2 x EmissionYieldTracker(64 bytes) = 128 bytes
433
473
  const emissions = [];
434
474
  for (let j = 0; j < PERSONAL_TICK_YIELD_TRACKER_SIZE; j++) {
435
- const lastSeenIndex = readNumber();
436
- const lastPositionIndex = readNumber();
437
- emissions.push({ lastSeenIndex, lastPositionIndex });
475
+ emissions.push({
476
+ lastSeenIndex: readPreciseNumberAsFloat(),
477
+ lastPositionIndex: readPreciseNumberAsFloat(),
478
+ });
438
479
  }
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;
480
+ const lastSplitEpoch = readU64(); // 8 bytes
481
+ const frozenLiquidity = readU64(); // 8 bytes
446
482
  ticks.push({
447
483
  apyBasePoints,
448
484
  liquidityNet,
449
485
  feeGrowthOutsidePt,
450
486
  feeGrowthOutsideSy,
451
487
  liquidityGross,
452
- impliedRate,
488
+ impliedRate: spotPrice, // Legacy field name kept for compatibility
453
489
  principalPt,
454
490
  principalSy,
455
491
  principalShareSupply,
456
492
  farms,
457
493
  emissions,
458
494
  lastSplitEpoch,
495
+ frozenLiquidity,
459
496
  });
460
- // console.log(ticks)
461
497
  }
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
498
+ // ─── Parse Ticks footer ───────────────────────────────────────────────────
499
+ const market = readPubkey(); // 32 bytes
500
+ const feeGrowthIndexGlobalPt = readU128(); // 16 bytes
501
+ const feeGrowthIndexGlobalSy = readU128(); // 16 bytes
502
+ const currentPrefixSum = readU64(); // 8 bytes
503
+ const currentSpotPrice = readF64(); // 8 bytes
504
+ const currentTick = readU32(); // 4 bytes
505
+ skip(12); // padding
474
506
  return {
475
507
  ticksTree: ticks,
476
508
  market,
@@ -482,7 +514,50 @@ function deserializeMarketThreeTicks(data) {
482
514
  };
483
515
  }
484
516
  exports.deserializeMarketThreeTicks = deserializeMarketThreeTicks;
517
+ /** Decoded account may use snake_case (from JSON IDL); normalize to camelCase for app use. */
518
+ function normalizeCpiContext(a) {
519
+ return {
520
+ altIndex: a.altIndex ?? a.alt_index ?? 0,
521
+ isSigner: a.isSigner ?? a.is_signer ?? false,
522
+ isWritable: a.isWritable ?? a.is_writable ?? false,
523
+ };
524
+ }
525
+ function normalizeCpiAccountIndexes(raw) {
526
+ const arr = (key, snake) => {
527
+ const a = raw[key] ?? raw[snake];
528
+ return Array.isArray(a) ? a.map((x) => normalizeCpiContext(x)) : [];
529
+ };
530
+ const arr2 = (key, snake) => {
531
+ const a = raw[key] ?? raw[snake];
532
+ return Array.isArray(a) ? a.map((inner) => (Array.isArray(inner) ? inner.map((x) => normalizeCpiContext(x)) : [])) : [];
533
+ };
534
+ return {
535
+ getSyState: arr("getSyState", "get_sy_state"),
536
+ withdrawSy: arr("withdrawSy", "withdraw_sy"),
537
+ depositSy: arr("depositSy", "deposit_sy"),
538
+ claimEmission: arr2("claimEmission", "claim_emission"),
539
+ getPositionState: arr("getPositionState", "get_position_state"),
540
+ };
541
+ }
542
+ function normalizeMarketCpiCoreIndexes(raw) {
543
+ const arr = (key, snake) => {
544
+ const a = raw[key] ?? raw[snake];
545
+ return Array.isArray(a) ? a.map((x) => normalizeCpiContext(x)) : [];
546
+ };
547
+ return {
548
+ stripSy: arr("stripSy", "strip_sy"),
549
+ mergeSy: arr("mergeSy", "merge_sy"),
550
+ };
551
+ }
485
552
  function deserializeMarketThree(m) {
553
+ const rawCpiSy = m.cpiSyAccounts ?? m.cpi_sy_accounts;
554
+ const rawCpiCore = m.cpiCoreAccounts ?? m.cpi_core_accounts;
555
+ const cpiSyAccounts = rawCpiSy != null && typeof rawCpiSy === "object"
556
+ ? normalizeCpiAccountIndexes(rawCpiSy)
557
+ : (m.cpiSyAccounts ?? { getSyState: [], withdrawSy: [], depositSy: [], claimEmission: [], getPositionState: [] });
558
+ const cpiCoreAccounts = rawCpiCore != null && typeof rawCpiCore === "object"
559
+ ? normalizeMarketCpiCoreIndexes(rawCpiCore)
560
+ : (m.cpiCoreAccounts ?? { stripSy: [], mergeSy: [] });
486
561
  return {
487
562
  addressLookupTable: m.addressLookupTable,
488
563
  mintSy: m.mintSy,
@@ -495,7 +570,7 @@ function deserializeMarketThree(m) {
495
570
  selfAddress: m.selfAddress,
496
571
  syProgram: m.syProgram,
497
572
  statusFlags: m.statusFlags,
498
- cpiSyAccounts: m.cpiSyAccounts,
573
+ cpiSyAccounts,
499
574
  isCurrentFlashSwap: m.isCurrentFlashSwap,
500
575
  lpFarm: m.lpFarm,
501
576
  mintYt: m.mintYt,
@@ -524,10 +599,12 @@ function deserializeMarketThree(m) {
524
599
  syBalance: BigInt(m.financials.syBalance.toString()),
525
600
  liquidityBalance: BigInt(m.financials.liquidityBalance.toString()),
526
601
  },
527
- cpiCoreAccounts: m.cpiCoreAccounts,
602
+ cpiCoreAccounts,
528
603
  exponentCoreProgram: m.exponentCoreProgram,
604
+ seedId: m.seedId,
529
605
  };
530
606
  }
607
+ exports.deserializeMarketThree = deserializeMarketThree;
531
608
  function deserializeMarketTwo(m) {
532
609
  return {
533
610
  ptBalance: BigInt(m.financials.ptBalance.toString()),
@@ -584,7 +661,7 @@ function deserializeLpPositionCLMM(x) {
584
661
  tickIdx: tracker.tickIdx,
585
662
  rightTickIdx: tracker.rightTickIdx,
586
663
  splitEpoch: BigInt(tracker.splitEpoch.toString()),
587
- lpShare: BigInt(tracker.lpShare.toString()),
664
+ lpShare: anchorizedPNumToRawBigint(tracker.lpShare),
588
665
  emissions: tracker.emissions.trackers.map((e) => ({
589
666
  staged: BigInt(e.staged.toString()),
590
667
  lastSeenIndex: parseFloat(precise_number_1.PreciseNumber.fromRaw(e.lastSeenIndex[0]).valueString),
@@ -640,8 +717,8 @@ function deserializeOrderbook(data) {
640
717
  offset += 8;
641
718
  const priceDecimals = data.readUint8(offset);
642
719
  offset += 1;
643
- // Skip ConfigurationOptions padding: _placeholder_one[15] + _placeholder_two[32] + _placeholder_three[32] + _placeholder_four[32] = 111 bytes
644
- offset += 111;
720
+ // Skip ConfigurationOptions padding: _placeholder_one[15] + _placeholder_two[32] + _placeholder_three[32] + _placeholder_four[32] + _reserved[1024] = 1135 bytes
721
+ offset += 1135;
645
722
  // Pubkeys
646
723
  const vault = readPubkey();
647
724
  const yieldPosition = readPubkey();
@@ -653,7 +730,14 @@ function deserializeOrderbook(data) {
653
730
  const tokenEscrowPt = readPubkey();
654
731
  const cpiAccountOrderbook = readPubkey();
655
732
  const admin = readPubkey();
656
- // Skip last_sy_exchange_rate (Number type = 32 bytes)
733
+ // last_sy_exchange_rate (Number type = 32 bytes, PreciseNumber with 12 decimals)
734
+ const lastSyExchangeRateRaw = (() => {
735
+ let val = 0n;
736
+ for (let i = 0; i < 4; i++) {
737
+ val += data.readBigUInt64LE(offset + i * 8) << BigInt(i * 64);
738
+ }
739
+ return val;
740
+ })();
657
741
  offset += 32;
658
742
  // OrderbookFinancials struct
659
743
  // Skip last_seen_sy_index (Number type = 32 bytes)
@@ -694,11 +778,12 @@ function deserializeOrderbook(data) {
694
778
  };
695
779
  // console.log("financials", financials)
696
780
  // ─── Parse RedBlackTree slab ───────────────────────────────────────────────
697
- // repr(C) gives: root: u32, pad to align NodeAllocator’s u64, then the NodeAllocator header
781
+ // RedBlackTree struct: root: u32, _padding: [u32; 3], allocator: NodeAllocator<...>
782
+ // Total before allocator = 4 + 12 = 16 bytes
698
783
  const root = data.readUInt32LE(offset);
699
784
  offset += 4;
700
- const padTo8 = 8;
701
- offset += padTo8;
785
+ const padding = 12; // _padding: [u32; 3] in RedBlackTree struct
786
+ offset += padding;
702
787
  // NodeAllocator<T=RBNode<u32,PriceNode>, N=MAX_PRICE_NODES, R=3>
703
788
  // header: size:u64, bump_index:u32, free_list_head:u32
704
789
  const priceTreeSize = Number(data.readBigUInt64LE(offset));
@@ -736,9 +821,9 @@ function deserializeOrderbook(data) {
736
821
  // header: size:u64, bump_index:u32, free_list_head:u32
737
822
  const offersSize = Number(data.readBigUInt64LE(offset));
738
823
  offset += 8;
739
- const _offersBump = data.readUInt32LE(offset);
824
+ const offersBumpIndex = data.readUInt32LE(offset);
740
825
  offset += 4;
741
- const _offersFreeIdx = data.readUInt32LE(offset);
826
+ const offersFreeListHead = data.readUInt32LE(offset);
742
827
  offset += 4;
743
828
  const offers = [];
744
829
  for (let i = 0; i < exponent_types_2.MAX_OFFERS; i++) {
@@ -766,6 +851,7 @@ function deserializeOrderbook(data) {
766
851
  if (userVaultPointer === 0)
767
852
  continue;
768
853
  offers.push({
854
+ offerIndex: i + 1,
769
855
  nextOfferPointer,
770
856
  amount,
771
857
  userVaultPointer,
@@ -795,7 +881,12 @@ function deserializeOrderbook(data) {
795
881
  offset += 4;
796
882
  const user = new anchor_1.web3.PublicKey(data.slice(offset, offset + 32));
797
883
  offset += 32;
798
- /*const yieldIndex = data.readBigUInt64LE(offset).toString();*/ offset += 32;
884
+ const yieldIndexRaw = [[new anchor_1.BN(0), new anchor_1.BN(0), new anchor_1.BN(0), new anchor_1.BN(0)]];
885
+ for (let word = 0; word < 4; word++) {
886
+ yieldIndexRaw[0][word] = new anchor_1.BN(data.subarray(offset + word * 8, offset + (word + 1) * 8), "le");
887
+ }
888
+ const yieldIndex = deserializeAnchorizedPNum(yieldIndexRaw);
889
+ offset += 32;
799
890
  const ptAmount = data.readBigUInt64LE(offset);
800
891
  offset += 8;
801
892
  const syAmount = data.readBigUInt64LE(offset);
@@ -807,9 +898,8 @@ function deserializeOrderbook(data) {
807
898
  const staged = data.readBigInt64LE(offset);
808
899
  offset += 8;
809
900
  offset += 8; // reserved
810
- if (user.toBase58() == "11111111111111111111111111111111")
811
- continue;
812
- userEscrows.push({ user, yieldIndex: 0, ptAmount, syAmount, ytAmount, stakedYtAmount, staged });
901
+ // if (user.toBase58() == "11111111111111111111111111111111") continue
902
+ userEscrows.push({ user, yieldIndex, ptAmount, syAmount, ytAmount, stakedYtAmount, staged });
813
903
  }
814
904
  // ─── Finally, seed_id + signer_bump + reserved ─────────────────────────────
815
905
  // seed_id: [u8; 4]
@@ -836,11 +926,14 @@ function deserializeOrderbook(data) {
836
926
  tokenEscrowYt,
837
927
  tokenEscrowPt,
838
928
  cpiAccountOrderbook,
929
+ lastSyExchangeRate: lastSyExchangeRateRaw,
839
930
  financials,
840
931
  prices,
841
932
  configurationOptions,
842
933
  offers,
843
934
  userEscrows,
935
+ offersBumpIndex,
936
+ offersFreeListHead,
844
937
  };
845
938
  }
846
939
  function deserializeMarginfiSyMeta(x) {
@@ -966,6 +1059,16 @@ exports.deserializeEmission = deserializeEmission;
966
1059
  function deserializeAnchorizedPNum(x) {
967
1060
  return parseFloat(precise_number_1.PreciseNumber.fromRaw(x[0]).valueString);
968
1061
  }
1062
+ /** Convert PreciseNumber (Number type in Rust) from Anchor format to raw 256-bit bigint */
1063
+ function anchorizedPNumToRawBigint(pnum) {
1064
+ const bnArray = pnum[0];
1065
+ let val = 0n;
1066
+ for (let i = 0; i < 4; i++) {
1067
+ val += BigInt(bnArray[i].toString()) << BigInt(i * 64);
1068
+ }
1069
+ return val;
1070
+ }
1071
+ exports.anchorizedPNumToRawBigint = anchorizedPNumToRawBigint;
969
1072
  /** Fetch the exchange rate of a JitoRestaking vault's VRT to JitoSOL */
970
1073
  async function fetchJitoVaultData({ connection, vaultAddress, }) {
971
1074
  const vaultAccountInfo = await connection.getAccountInfo(vaultAddress);
@@ -1192,7 +1295,7 @@ async function fetchSolsticeRedemptionRate({ connection, yieldPool, vestingSched
1192
1295
  }
1193
1296
  exports.fetchSolsticeRedemptionRate = fetchSolsticeRedemptionRate;
1194
1297
  const REFLECT_ORACLE_LEN = 17;
1195
- const REFLECT_MAX_STALENESS_SLOTS = 150;
1298
+ const REFLECT_MAX_STALENESS_SLOTS = 15000000;
1196
1299
  async function fetchReflectRedemptionRate({ connection, oracle, }) {
1197
1300
  const accountInfo = await connection.getAccountInfo(oracle);
1198
1301
  if (!accountInfo) {
@@ -1236,4 +1339,14 @@ async function fetchOreExchangeRate({ connection, storeMint, stakeAccount, treas
1236
1339
  });
1237
1340
  }
1238
1341
  exports.fetchOreExchangeRate = fetchOreExchangeRate;
1342
+ async function fetchChainlinkRate({ connection, priceFeed, }) {
1343
+ const accountInfo = await connection.getAccountInfo(priceFeed);
1344
+ if (!accountInfo) {
1345
+ throw new Error("Chainlink price feed account not found");
1346
+ }
1347
+ const { answer, header } = (0, chainlink_idl_1.decodeChainlinkPriceAccount)(accountInfo);
1348
+ const scale = Math.pow(10, header.decimals);
1349
+ return Number(answer) / scale;
1350
+ }
1351
+ exports.fetchChainlinkRate = fetchChainlinkRate;
1239
1352
  //# sourceMappingURL=exponentFetcher.js.map