@exponent-labs/exponent-fetcher 0.9.18 → 0.9.20

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.
@@ -1,3 +1,5 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
1
3
  export declare function calculateSolsticeRedemptionRate(accounts: {
2
4
  yieldPool: Buffer;
3
5
  vestingSchedule: Buffer;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateSolsticeRedemptionRate = calculateSolsticeRedemptionRate;
4
- exports.calculateSolsticeGlamVaultExchangeRate = calculateSolsticeGlamVaultExchangeRate;
3
+ exports.calculateSolsticeGlamVaultExchangeRate = exports.calculateSolsticeRedemptionRate = void 0;
5
4
  const solstice_idl_1 = require("@exponent-labs/solstice-idl");
6
5
  const spl_token_1 = require("@solana/spl-token");
7
6
  function calculateSolsticeRedemptionRate(accounts) {
@@ -43,6 +42,7 @@ function calculateSolsticeRedemptionRate(accounts) {
43
42
  totalVestedAssets: totalVestedAssets.toString(),
44
43
  };
45
44
  }
45
+ exports.calculateSolsticeRedemptionRate = calculateSolsticeRedemptionRate;
46
46
  /**
47
47
  * Calculates the Solstice GLAM vault stSLX exchange rate using the same account
48
48
  * layout and ratio as the Generic Standard on-chain interface.
@@ -60,4 +60,5 @@ function calculateSolsticeGlamVaultExchangeRate(accounts) {
60
60
  const denominator = stslxSupply * 10n ** BigInt(slxMint.decimals);
61
61
  return Number(numerator) / Number(denominator);
62
62
  }
63
+ exports.calculateSolsticeGlamVaultExchangeRate = calculateSolsticeGlamVaultExchangeRate;
63
64
  //# sourceMappingURL=solstice.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"solstice.js","sourceRoot":"","sources":["../../src/utils/solstice.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"solstice.js","sourceRoot":"","sources":["../../src/utils/solstice.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exponent-labs/exponent-fetcher",
3
- "version": "0.9.18",
3
+ "version": "0.9.20",
4
4
  "main": "build/index.js",
5
5
  "types": "build/index.d.ts",
6
6
  "license": "AGPL-3.0",
@@ -9,26 +9,26 @@
9
9
  },
10
10
  "dependencies": {
11
11
  "@coral-xyz/anchor": "0.30.0",
12
- "@exponent-labs/adrena-idl": "0.9.18",
13
- "@exponent-labs/chainlink-idl": "0.9.18",
14
- "@exponent-labs/exponent-idl": "0.9.18",
15
- "@exponent-labs/exponent-types": "0.9.18",
16
- "@exponent-labs/fragmetric-idl": "0.9.18",
17
- "@exponent-labs/generic-sy-idl": "0.9.18",
18
- "@exponent-labs/jito-restaking-sy-idl": "0.9.18",
19
- "@exponent-labs/jupiter-lend-idl": "0.9.18",
20
- "@exponent-labs/jupiter-perps-idl": "0.9.18",
21
- "@exponent-labs/kamino-reserve-deserializer": "0.9.18",
22
- "@exponent-labs/kamino-sy-idl": "0.9.18",
23
- "@exponent-labs/kamino-vault-idl": "0.9.18",
24
- "@exponent-labs/marginfi-sy-idl": "0.9.18",
25
- "@exponent-labs/meteora-idl": "0.9.18",
26
- "@exponent-labs/perena-sy-idl": "0.9.18",
27
- "@exponent-labs/precise-number": "0.9.18",
28
- "@exponent-labs/sanctum-idl": "0.9.18",
29
- "@exponent-labs/solstice-idl": "0.9.18",
30
- "@exponent-labs/exponent-clmm-idl": "0.9.18",
31
- "@exponent-labs/exponent-orderbook-idl": "0.9.18",
12
+ "@exponent-labs/adrena-idl": "0.9.20",
13
+ "@exponent-labs/chainlink-idl": "0.9.20",
14
+ "@exponent-labs/exponent-idl": "0.9.20",
15
+ "@exponent-labs/exponent-types": "0.9.20",
16
+ "@exponent-labs/fragmetric-idl": "0.9.20",
17
+ "@exponent-labs/generic-sy-idl": "0.9.20",
18
+ "@exponent-labs/jito-restaking-sy-idl": "0.9.20",
19
+ "@exponent-labs/jupiter-lend-idl": "0.9.20",
20
+ "@exponent-labs/jupiter-perps-idl": "0.9.20",
21
+ "@exponent-labs/kamino-reserve-deserializer": "0.9.20",
22
+ "@exponent-labs/kamino-sy-idl": "0.9.20",
23
+ "@exponent-labs/kamino-vault-idl": "0.9.20",
24
+ "@exponent-labs/marginfi-sy-idl": "0.9.20",
25
+ "@exponent-labs/meteora-idl": "0.9.20",
26
+ "@exponent-labs/perena-sy-idl": "0.9.20",
27
+ "@exponent-labs/precise-number": "0.9.20",
28
+ "@exponent-labs/sanctum-idl": "0.9.20",
29
+ "@exponent-labs/solstice-idl": "0.9.20",
30
+ "@exponent-labs/exponent-clmm-idl": "0.9.20",
31
+ "@exponent-labs/exponent-orderbook-idl": "0.9.20",
32
32
  "@solana/spl-stake-pool": "1.1.8",
33
33
  "@solana/spl-token": "0.4.6",
34
34
  "bn-sqrt": "^1.0.0",
@@ -37,6 +37,5 @@
37
37
  "devDependencies": {
38
38
  "@types/bn.js": "^5.1.0",
39
39
  "typescript": "5.4.5"
40
- },
41
- "gitHead": "209b8847e9a0fadb5b5ec96b9b47f0ace4a3bf9d"
40
+ }
42
41
  }
@@ -87,6 +87,8 @@ import { getPerenaLpMint, getPerenaStablePoolData } from "./utils/perena"
87
87
  import { calculateSanctumIndex } from "./utils/sanctum"
88
88
  import { calculateSolsticeGlamVaultExchangeRate, calculateSolsticeRedemptionRate } from "./utils/solstice"
89
89
 
90
+ const KAMINO_VAULT_GLOBAL_CONFIG = new web3.PublicKey("BKyTcUe6daNG8HbgBix2ugdRHbykG2dK9hPBBqhUyoEX")
91
+
90
92
  export function serializeAnchorizedPNumFromJson(pnum: AnchorizedPNum): AnchorizedPNumJson {
91
93
  const serializedArray = pnum[0].map((bn) => bn.toString())
92
94
  return { 0: serializedArray }
@@ -562,18 +564,23 @@ export function deserializeMarketThreeTicks(data: Buffer): Ticks {
562
564
  }
563
565
 
564
566
  // ─── Parse RedBlackTree header ────────────────────────────────────────────
565
- skip(4) // root: u32
567
+ const tickTreeRoot = readU32()
566
568
  skip(12) // padding to align NodeAllocator
567
- skip(8) // size: u64
568
- skip(4) // bump_index: u32
569
- skip(4) // free_list_head: u32
569
+ const tickTreeSize = readU64()
570
+ const tickTreeBumpIndex = readU32()
571
+ const tickTreeFreeListHead = readU32()
570
572
 
571
573
  // ─── Parse tick nodes ─────────────────────────────────────────────────────
572
574
  const ticks: Tick[] = []
573
575
 
574
576
  for (let i = 0; i < MAX_TICK_NODES; i++) {
575
577
  // RBNode header: left(4) + right(4) + parent(4) + color(4) = 16 bytes
576
- skip(16)
578
+ const treeNode = {
579
+ left: readU32(),
580
+ right: readU32(),
581
+ parent: readU32(),
582
+ colorOrFree: readU32(),
583
+ }
577
584
 
578
585
  // Key: u32 + padding to 8 bytes
579
586
  const apyBasePoints = readU32()
@@ -626,9 +633,36 @@ export function deserializeMarketThreeTicks(data: Buffer): Ticks {
626
633
  splitParentEpoch,
627
634
  frozenLiquidity,
628
635
  splitParentIdx,
636
+ treeNode,
637
+ isInitialized: false,
629
638
  })
630
639
  }
631
640
 
641
+ const initializedTickIndices = new Set<number>()
642
+ const stack = tickTreeRoot === 0 ? [] : [tickTreeRoot]
643
+ while (stack.length > 0) {
644
+ const tickIdx = stack.pop()!
645
+ if (tickIdx < 1 || tickIdx > MAX_TICK_NODES || initializedTickIndices.has(tickIdx)) {
646
+ continue
647
+ }
648
+
649
+ initializedTickIndices.add(tickIdx)
650
+ const node = ticks[tickIdx - 1]?.treeNode
651
+ if (!node) {
652
+ continue
653
+ }
654
+ if (node.left !== 0) {
655
+ stack.push(node.left)
656
+ }
657
+ if (node.right !== 0) {
658
+ stack.push(node.right)
659
+ }
660
+ }
661
+
662
+ for (let i = 0; i < ticks.length; i++) {
663
+ ticks[i].isInitialized = initializedTickIndices.has(i + 1)
664
+ }
665
+
632
666
  // ─── Parse Ticks footer ───────────────────────────────────────────────────
633
667
  const market = readPubkey() // 32 bytes
634
668
  const feeGrowthIndexGlobalPt = readU128() // 16 bytes
@@ -646,6 +680,10 @@ export function deserializeMarketThreeTicks(data: Buffer): Ticks {
646
680
  currentPrefixSum,
647
681
  currentSpotPrice,
648
682
  currentTick,
683
+ tickTreeRoot,
684
+ tickTreeSize,
685
+ tickTreeBumpIndex,
686
+ tickTreeFreeListHead,
649
687
  }
650
688
  }
651
689
 
@@ -812,6 +850,15 @@ function deserializeOrderbook(data: Buffer): Orderbook {
812
850
  return pk
813
851
  }
814
852
 
853
+ const readPreciseNumberAsFloat = (): number => {
854
+ const nums: BN[] = []
855
+ for (let i = 0; i < 4; i++) {
856
+ nums.push(new BN(data.slice(offset + i * 8, offset + (i + 1) * 8), undefined, "le"))
857
+ }
858
+ offset += 32
859
+ return parseFloat(PreciseNumber.fromRaw(nums).valueString)
860
+ }
861
+
815
862
  // ConfigurationOptions struct
816
863
  const thresholdAmount = data.readBigUInt64LE(offset)
817
864
  offset += 8
@@ -993,20 +1040,20 @@ function deserializeOrderbook(data: Buffer): Orderbook {
993
1040
  offset += 4
994
1041
  const user = new web3.PublicKey(data.slice(offset, offset + 32))
995
1042
  offset += 32
996
- /*const yieldIndex = data.readBigUInt64LE(offset).toString();*/ offset += 32
1043
+ const yieldIndex = readPreciseNumberAsFloat()
997
1044
  const ptAmount = data.readBigUInt64LE(offset)
998
1045
  offset += 8
999
1046
  const syAmount = data.readBigUInt64LE(offset)
1000
1047
  offset += 8
1001
1048
  const ytAmount = data.readBigUInt64LE(offset)
1002
1049
  offset += 8
1003
- const stakedYtAmount = data.readBigInt64LE(offset)
1050
+ const stakedYtAmount = data.readBigUInt64LE(offset)
1004
1051
  offset += 8
1005
- const staged = data.readBigInt64LE(offset)
1052
+ const staged = data.readBigUInt64LE(offset)
1006
1053
  offset += 8
1007
1054
  offset += 8 // reserved
1008
1055
  // if (user.toBase58() == "11111111111111111111111111111111") continue
1009
- userEscrows.push({ user, yieldIndex: 0, ptAmount, syAmount, ytAmount, stakedYtAmount, staged })
1056
+ userEscrows.push({ user, yieldIndex, ptAmount, syAmount, ytAmount, stakedYtAmount, staged })
1010
1057
  }
1011
1058
 
1012
1059
  // ─── Finally, seed_id + signer_bump + reserved ─────────────────────────────
@@ -1252,6 +1299,21 @@ export interface Ticks {
1252
1299
  currentPrefixSum: bigint
1253
1300
  /** Current spot price (ln implied rate) */
1254
1301
  currentSpotPrice: number
1302
+ /** Root node index of the on-chain RedBlackTree (0 is sentinel) */
1303
+ tickTreeRoot?: number
1304
+ /** Allocated live node count recorded by the on-chain allocator */
1305
+ tickTreeSize?: bigint
1306
+ /** Next allocator bump index recorded by the on-chain allocator */
1307
+ tickTreeBumpIndex?: number
1308
+ /** Free-list head recorded by the on-chain allocator */
1309
+ tickTreeFreeListHead?: number
1310
+ }
1311
+
1312
+ export interface TickTreeNode {
1313
+ left: number
1314
+ right: number
1315
+ parent: number
1316
+ colorOrFree: number
1255
1317
  }
1256
1318
 
1257
1319
  export interface Tick {
@@ -1281,6 +1343,10 @@ export interface Tick {
1281
1343
  frozenLiquidity: bigint
1282
1344
  /** Split-parent tick index for the current tick-split projection layout */
1283
1345
  splitParentIdx: number
1346
+ /** Raw RB-tree links for this 1-based tick node index */
1347
+ treeNode?: TickTreeNode
1348
+ /** True when reachable from tickTreeRoot in the on-chain RB tree */
1349
+ isInitialized?: boolean
1284
1350
  }
1285
1351
 
1286
1352
  export interface MarketThreeRaw {
@@ -1987,16 +2053,45 @@ export async function fetchKaminoVaultIndex({
1987
2053
 
1988
2054
  const data = coder.accounts.decode("VaultState", account.data)
1989
2055
 
1990
- const activeReserves = data.vault_allocation_strategy
1991
- .map((r) => r.reserve)
1992
- .filter((reserve) => reserve.toBase58() !== web3.PublicKey.default.toBase58())
2056
+ const activeAllocations = data.vault_allocation_strategy
2057
+ .filter((allocation) => allocation.reserve.toBase58() !== web3.PublicKey.default.toBase58())
2058
+ const activeReserves = activeAllocations.map((allocation) => allocation.reserve)
1993
2059
 
1994
- const activeReservesData = await connection.getMultipleAccountsInfo(activeReserves)
2060
+ const [activeReservesData, tokenMintInfo, sharesMintInfo] = await Promise.all([
2061
+ connection.getMultipleAccountsInfo(activeReserves),
2062
+ connection.getAccountInfo(data.token_mint),
2063
+ connection.getAccountInfo(data.shares_mint),
2064
+ ])
2065
+ const decodedReserves = activeReservesData.map((accountInfo, index) => {
2066
+ if (!accountInfo?.data) {
2067
+ throw new Error(`Missing Kamino reserve account ${activeReserves[index].toBase58()}`)
2068
+ }
2069
+ return Reserve.decode(accountInfo.data)
2070
+ })
2071
+ const collateralMintInfos = await connection.getMultipleAccountsInfo(
2072
+ decodedReserves.map((reserve) => reserve.collateral.mintPubkey),
2073
+ )
1995
2074
 
1996
2075
  const reserves = activeReserves.map((r, i) => {
2076
+ const reserveAccount = decodedReserves[i]
2077
+ const allocation = activeAllocations[i]
2078
+ const [lendingMarketAuthority] = web3.PublicKey.findProgramAddressSync(
2079
+ [Buffer.from("lma"), reserveAccount.lendingMarket.toBuffer()],
2080
+ new web3.PublicKey("KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD"),
2081
+ )
2082
+
1997
2083
  return {
1998
2084
  reserveAddress: r,
1999
- reserve: Reserve.decode(activeReservesData[i].data).lendingMarket,
2085
+ marketAddress: reserveAccount.lendingMarket,
2086
+ ctokenVault: allocation.ctoken_vault,
2087
+ lendingMarketAuthority,
2088
+ pythOracle: reserveAccount.config.tokenInfo.pythConfiguration.price,
2089
+ switchboardPriceOracle: reserveAccount.config.tokenInfo.switchboardConfiguration.priceAggregator,
2090
+ switchboardTwapOracle: reserveAccount.config.tokenInfo.switchboardConfiguration.twapAggregator,
2091
+ scopePrices: reserveAccount.config.tokenInfo.scopeConfiguration.priceFeed,
2092
+ reserveLiquiditySupply: reserveAccount.liquidity.supplyVault,
2093
+ reserveCollateralMint: reserveAccount.collateral.mintPubkey,
2094
+ reserveCollateralTokenProgram: collateralMintInfos[i]?.owner ?? web3.PublicKey.default,
2000
2095
  }
2001
2096
  })
2002
2097
 
@@ -2004,8 +2099,24 @@ export async function fetchKaminoVaultIndex({
2004
2099
  const tokenMint = data.token_mint
2005
2100
  const baseVaultAuthority = data.base_vault_authority
2006
2101
  const sharesMint = data.shares_mint
2102
+ const vaultLookupTable = data.vault_lookup_table ?? web3.PublicKey.default
2103
+ const tokenProgram = tokenMintInfo?.owner ?? web3.PublicKey.default
2104
+ const sharesTokenProgram = sharesMintInfo?.owner ?? web3.PublicKey.default
2007
2105
 
2008
- return { index: 1, tokenVault, tokenMint, baseVaultAuthority, sharesMint, reserves }
2106
+ return {
2107
+ index: 1,
2108
+ tokenVault,
2109
+ tokenMint,
2110
+ tokenProgram,
2111
+ // Kamino Vault withdraw expects the singleton program global config account.
2112
+ // It is not stored on VaultState, so fetch it from the known program-wide address.
2113
+ globalConfig: KAMINO_VAULT_GLOBAL_CONFIG,
2114
+ baseVaultAuthority,
2115
+ sharesMint,
2116
+ sharesTokenProgram,
2117
+ vaultLookupTable,
2118
+ reserves,
2119
+ }
2009
2120
  }
2010
2121
 
2011
2122
  export async function fetchFragmetricSupportedTokenIndex({
@@ -2200,7 +2311,7 @@ export async function fetchSolsticeGlamVaultExchangeRate({
2200
2311
  }
2201
2312
 
2202
2313
  const REFLECT_ORACLE_LEN = 17
2203
- const REFLECT_MAX_STALENESS_SLOTS = 15000000
2314
+ const REFLECT_MAX_STALENESS_SLOTS = 150000000000
2204
2315
 
2205
2316
  export async function fetchReflectRedemptionRate({
2206
2317
  connection,