@percolatorct/sdk 1.0.0-beta.24 → 1.0.0-beta.25

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/dist/index.js CHANGED
@@ -250,7 +250,7 @@ function encodeFeedId(feedId) {
250
250
  }
251
251
  return bytes;
252
252
  }
253
- var INIT_MARKET_DATA_LEN = 352;
253
+ var INIT_MARKET_DATA_LEN = 344;
254
254
  function encodeInitMarket(args) {
255
255
  const hMin = args.hMin ?? args.warmupPeriodSlots ?? 0n;
256
256
  const hMax = args.hMax ?? args.warmupPeriodSlots ?? 0n;
@@ -280,14 +280,13 @@ function encodeInitMarket(args) {
280
280
  encU128(args.insuranceFloor ?? 0n),
281
281
  // wire slot: old riskReductionThreshold → now insurance_floor
282
282
  encU64(hMax),
283
- // v12.15: h_max (u64) — was low 8 bytes of maintenanceFeePerSlot (u128)
284
- encU64(0n),
285
- // padding (u64) — remaining 8 bytes of old u128 slot
283
+ // h_max (u64)
286
284
  encU64(args.maxCrankStalenessSlots),
285
+ // v12.17: no padding between hMax and maxCrankStalenessSlots
287
286
  encU64(args.liquidationFeeBps),
288
287
  encU128(args.liquidationFeeCap),
289
288
  encU64(args.liquidationBufferBps ?? 0n),
290
- // wire slot: read as resolve_price_deviation_bps by program
289
+ // v12.17: read as resolve_price_deviation_bps by program
291
290
  encU128(args.minLiquidationAbs),
292
291
  encU128(args.minInitialDeposit),
293
292
  encU128(args.minNonzeroMmReq),
@@ -325,12 +324,28 @@ function encodeWithdrawCollateral(args) {
325
324
  encU64(args.amount)
326
325
  );
327
326
  }
327
+ var LiquidationPolicyTag = {
328
+ FullClose: 0,
329
+ ExactPartial: 1,
330
+ TouchOnly: 255
331
+ };
328
332
  function encodeKeeperCrank(args) {
329
- return concatBytes(
333
+ const parts = [
330
334
  encU8(IX_TAG.KeeperCrank),
331
335
  encU16(args.callerIdx),
332
- encU8(args.allowPanic ? 1 : 0)
333
- );
336
+ encU8(1)
337
+ // format_version = 1 (REQUIRED by v12.17)
338
+ ];
339
+ if (args.candidates) {
340
+ for (const c of args.candidates) {
341
+ parts.push(encU16(c.idx));
342
+ parts.push(encU8(c.policy));
343
+ if (c.policy === LiquidationPolicyTag.ExactPartial) {
344
+ parts.push(encU128(c.quantity));
345
+ }
346
+ }
347
+ }
348
+ return concatBytes(...parts);
334
349
  }
335
350
  function encodeTradeNoCpi(args) {
336
351
  return concatBytes(
@@ -357,7 +372,8 @@ function encodeTradeCpi(args) {
357
372
  encU8(IX_TAG.TradeCpi),
358
373
  encU16(args.lpIdx),
359
374
  encU16(args.userIdx),
360
- encI128(args.size)
375
+ encI128(args.size),
376
+ encU64(args.limitPriceE6)
361
377
  );
362
378
  }
363
379
  function encodeTradeCpiV2(args) {
@@ -369,6 +385,9 @@ function encodeTradeCpiV2(args) {
369
385
  encU8(args.bump)
370
386
  );
371
387
  }
388
+ function encodeUnresolveMarket(args) {
389
+ return concatBytes(encU8(IX_TAG.UnresolveMarket), encU64(args.confirmation));
390
+ }
372
391
  function encodeSetRiskThreshold(args) {
373
392
  return concatBytes(
374
393
  encU8(IX_TAG.SetRiskThreshold),
@@ -386,19 +405,10 @@ function encodeUpdateConfig(args) {
386
405
  encU8(IX_TAG.UpdateConfig),
387
406
  encU64(args.fundingHorizonSlots),
388
407
  encU64(args.fundingKBps),
389
- encU128(args.fundingInvScaleNotionalE6),
390
408
  encI64(args.fundingMaxPremiumBps),
391
409
  // Rust: i64 (can be negative)
392
- encI64(args.fundingMaxBpsPerSlot),
410
+ encI64(args.fundingMaxBpsPerSlot)
393
411
  // Rust: i64 (can be negative)
394
- encU128(args.threshFloor),
395
- encU64(args.threshRiskBps),
396
- encU64(args.threshUpdateIntervalSlots),
397
- encU64(args.threshStepBps),
398
- encU64(args.threshAlphaBps),
399
- encU128(args.threshMin),
400
- encU128(args.threshMax),
401
- encU128(args.threshMinStep)
402
412
  );
403
413
  }
404
414
  function encodeSetMaintenanceFee(args) {
@@ -480,23 +490,18 @@ function encodeSetPythOracle(args) {
480
490
  const dv3 = new DataView(buf.buffer);
481
491
  buf[0] = 32;
482
492
  buf.set(args.feedId, 1);
483
- dv3.setBigUint64(
484
- 33,
485
- args.maxStalenessSecs,
486
- /* little-endian */
487
- true
488
- );
493
+ dv3.setBigUint64(33, args.maxStalenessSecs, true);
489
494
  dv3.setUint16(41, args.confFilterBps, true);
490
495
  return buf;
491
496
  }
492
497
  var PYTH_RECEIVER_PROGRAM_ID = "rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ";
493
498
  async function derivePythPriceUpdateAccount(feedId, shardId = 0) {
494
- const { PublicKey: PublicKey15 } = await import("@solana/web3.js");
499
+ const { PublicKey: PublicKey16 } = await import("@solana/web3.js");
495
500
  const shardBuf = new Uint8Array(2);
496
501
  new DataView(shardBuf.buffer).setUint16(0, shardId, true);
497
- const [pda] = PublicKey15.findProgramAddressSync(
502
+ const [pda] = PublicKey16.findProgramAddressSync(
498
503
  [shardBuf, feedId],
499
- new PublicKey15(PYTH_RECEIVER_PROGRAM_ID)
504
+ new PublicKey16(PYTH_RECEIVER_PROGRAM_ID)
500
505
  );
501
506
  return pda.toBase58();
502
507
  }
@@ -1386,12 +1391,184 @@ function parseErrorFromLogs(logs) {
1386
1391
  return null;
1387
1392
  }
1388
1393
 
1389
- // src/solana/slab.ts
1394
+ // src/abi/nft.ts
1395
+ import { PublicKey as PublicKey4 } from "@solana/web3.js";
1396
+
1397
+ // src/config/program-ids.ts
1390
1398
  import { PublicKey as PublicKey3 } from "@solana/web3.js";
1399
+ function safeEnv(key) {
1400
+ try {
1401
+ return typeof process !== "undefined" && process?.env ? process.env[key] : void 0;
1402
+ } catch {
1403
+ return void 0;
1404
+ }
1405
+ }
1406
+ var PROGRAM_IDS = {
1407
+ devnet: {
1408
+ percolator: "FxfD37s1AZTeWfFQps9Zpebi2dNQ9QSSDtfMKdbsfKrD",
1409
+ matcher: "GTRgyTDfrMvBubALAqtHuQwT8tbGyXid7svXZKtWfC9k"
1410
+ },
1411
+ mainnet: {
1412
+ percolator: "ESa89R5Es3rJ5mnwGybVRG1GrNt9etP11Z5V2QWD4edv",
1413
+ matcher: "GDK8wx38kpiSVSfGTVNiSdptX3Z5R4kQyqh6Q3QX6wmi"
1414
+ }
1415
+ };
1416
+ function getProgramId(network) {
1417
+ const override = safeEnv("PROGRAM_ID");
1418
+ if (override) {
1419
+ console.warn(
1420
+ `[percolator-sdk] PROGRAM_ID env override active: ${override} \u2014 ensure this points to a trusted program`
1421
+ );
1422
+ return new PublicKey3(override);
1423
+ }
1424
+ const detectedNetwork = getCurrentNetwork();
1425
+ const targetNetwork = network ?? detectedNetwork;
1426
+ const programId = PROGRAM_IDS[targetNetwork].percolator;
1427
+ return new PublicKey3(programId);
1428
+ }
1429
+ function getMatcherProgramId(network) {
1430
+ const override = safeEnv("MATCHER_PROGRAM_ID");
1431
+ if (override) {
1432
+ console.warn(
1433
+ `[percolator-sdk] MATCHER_PROGRAM_ID env override active: ${override} \u2014 ensure this points to a trusted program`
1434
+ );
1435
+ return new PublicKey3(override);
1436
+ }
1437
+ const detectedNetwork = getCurrentNetwork();
1438
+ const targetNetwork = network ?? detectedNetwork;
1439
+ const programId = PROGRAM_IDS[targetNetwork].matcher;
1440
+ if (!programId) {
1441
+ throw new Error(`Matcher program not deployed on ${targetNetwork}`);
1442
+ }
1443
+ return new PublicKey3(programId);
1444
+ }
1445
+ function getCurrentNetwork() {
1446
+ const network = safeEnv("NETWORK")?.toLowerCase();
1447
+ if (network === "mainnet" || network === "mainnet-beta") {
1448
+ return "mainnet";
1449
+ }
1450
+ return "devnet";
1451
+ }
1452
+
1453
+ // src/abi/nft.ts
1454
+ var NFT_PROGRAM_OVERRIDE = safeEnv("NFT_PROGRAM_ID");
1455
+ var NFT_PROGRAM_ID = new PublicKey4(
1456
+ NFT_PROGRAM_OVERRIDE ?? "FqhKJT9gtScjrmfUuRMjeg7cXNpif1fqsy5Jh65tJmTS"
1457
+ );
1458
+ function getNftProgramId() {
1459
+ return NFT_PROGRAM_ID;
1460
+ }
1461
+ var NFT_IX_TAG = {
1462
+ MintPositionNft: 0,
1463
+ BurnPositionNft: 1,
1464
+ SettleFunding: 2,
1465
+ GetPositionValue: 3,
1466
+ ExecuteTransferHook: 4,
1467
+ EmergencyBurn: 5
1468
+ };
1469
+ function encodeNftMint(userIdx) {
1470
+ const buf = new Uint8Array(3);
1471
+ buf[0] = NFT_IX_TAG.MintPositionNft;
1472
+ buf[1] = userIdx & 255;
1473
+ buf[2] = userIdx >> 8 & 255;
1474
+ return buf;
1475
+ }
1476
+ function encodeNftBurn() {
1477
+ return new Uint8Array([NFT_IX_TAG.BurnPositionNft]);
1478
+ }
1479
+ function encodeNftSettleFunding() {
1480
+ return new Uint8Array([NFT_IX_TAG.SettleFunding]);
1481
+ }
1482
+ function encodeNftEmergencyBurn() {
1483
+ return new Uint8Array([NFT_IX_TAG.EmergencyBurn]);
1484
+ }
1485
+ var ACCOUNTS_NFT_MINT = [
1486
+ "sw",
1487
+ "w",
1488
+ "sw",
1489
+ "w",
1490
+ "r",
1491
+ "r",
1492
+ "r",
1493
+ "r",
1494
+ "r",
1495
+ "w"
1496
+ ];
1497
+ var ACCOUNTS_NFT_BURN = [
1498
+ "s",
1499
+ "w",
1500
+ "w",
1501
+ "w",
1502
+ "r",
1503
+ "r",
1504
+ "r"
1505
+ ];
1506
+ var ACCOUNTS_NFT_EMERGENCY_BURN = [
1507
+ "s",
1508
+ "w",
1509
+ "w",
1510
+ "w",
1511
+ "r",
1512
+ "r",
1513
+ "r"
1514
+ ];
1515
+ var TEXT = new TextEncoder();
1516
+ function idxBuf(userIdx) {
1517
+ const buf = new Uint8Array(2);
1518
+ new DataView(buf.buffer).setUint16(0, userIdx, true);
1519
+ return buf;
1520
+ }
1521
+ function deriveNftPda(slab, userIdx, programId = NFT_PROGRAM_ID) {
1522
+ return PublicKey4.findProgramAddressSync(
1523
+ [TEXT.encode("position_nft"), slab.toBytes(), idxBuf(userIdx)],
1524
+ programId
1525
+ );
1526
+ }
1527
+ function deriveNftMint(slab, userIdx, programId = NFT_PROGRAM_ID) {
1528
+ return PublicKey4.findProgramAddressSync(
1529
+ [TEXT.encode("position_nft_mint"), slab.toBytes(), idxBuf(userIdx)],
1530
+ programId
1531
+ );
1532
+ }
1533
+ function deriveMintAuthority(programId = NFT_PROGRAM_ID) {
1534
+ return PublicKey4.findProgramAddressSync(
1535
+ [TEXT.encode("mint_authority")],
1536
+ programId
1537
+ );
1538
+ }
1539
+ var POSITION_NFT_STATE_LEN = 208;
1540
+ function parsePositionNftAccount(data) {
1541
+ if (data.length < POSITION_NFT_STATE_LEN) {
1542
+ throw new Error(
1543
+ `PositionNft account too small: ${data.length} < ${POSITION_NFT_STATE_LEN}`
1544
+ );
1545
+ }
1546
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
1547
+ return {
1548
+ version: data[8],
1549
+ bump: data[9],
1550
+ slab: new PublicKey4(data.subarray(16, 48)),
1551
+ userIdx: view.getUint16(48, true),
1552
+ nftMint: new PublicKey4(data.subarray(56, 88)),
1553
+ entryPriceE6: view.getBigUint64(88, true),
1554
+ positionSize: view.getBigUint64(96, true),
1555
+ isLong: data[104] === 1,
1556
+ positionBasisQ: view.getBigInt64(112, true) | view.getBigInt64(120, true) << 64n,
1557
+ lastFundingIndexE18: view.getBigInt64(128, true) | view.getBigInt64(136, true) << 64n,
1558
+ mintedAt: view.getBigInt64(144, true),
1559
+ accountId: view.getBigUint64(152, true)
1560
+ };
1561
+ }
1562
+
1563
+ // src/solana/slab.ts
1564
+ import { PublicKey as PublicKey5 } from "@solana/web3.js";
1391
1565
  function dv(data) {
1392
1566
  return new DataView(data.buffer, data.byteOffset, data.byteLength);
1393
1567
  }
1394
1568
  function readU8(data, off) {
1569
+ if (off >= data.length) {
1570
+ throw new RangeError(`readU8: offset ${off} out of bounds (length ${data.length})`);
1571
+ }
1395
1572
  return data[off];
1396
1573
  }
1397
1574
  function readU16LE(data, off) {
@@ -1422,6 +1599,7 @@ function readU128LE(buf, offset) {
1422
1599
  return hi << 64n | lo;
1423
1600
  }
1424
1601
  var MAGIC = 0x504552434f4c4154n;
1602
+ var SLAB_MAGIC = MAGIC;
1425
1603
  var FLAG_RESOLVED = 1 << 0;
1426
1604
  var V0_HEADER_LEN = 72;
1427
1605
  var V0_CONFIG_LEN = 408;
@@ -1690,6 +1868,61 @@ var V12_15_ENGINE_PNL_POS_TOT_OFF = 368;
1690
1868
  var V12_15_ENGINE_PNL_MATURED_POS_TOT_OFF = 384;
1691
1869
  var V12_15_ENGINE_BITMAP_OFF = 862;
1692
1870
  var V12_15_SIZES = /* @__PURE__ */ new Map();
1871
+ var V12_17_ENGINE_OFF = 512;
1872
+ var V12_17_ACCOUNT_SIZE = 368;
1873
+ var V12_17_ENGINE_BITMAP_OFF = 752;
1874
+ var V12_17_RISK_BUF_LEN = 160;
1875
+ var V12_17_ENGINE_OFF_SBF = 504;
1876
+ var V12_17_ACCOUNT_SIZE_SBF = 352;
1877
+ var V12_17_ENGINE_BITMAP_OFF_SBF = 712;
1878
+ var V12_17_ACCT_CAPITAL_OFF = 0;
1879
+ var V12_17_ACCT_KIND_OFF = 16;
1880
+ var V12_17_ACCT_PNL_OFF = 32;
1881
+ var V12_17_ACCT_RESERVED_PNL_OFF = 48;
1882
+ var V12_17_ACCT_POSITION_BASIS_Q_OFF = 64;
1883
+ var V12_17_ACCT_ADL_A_BASIS_OFF = 80;
1884
+ var V12_17_ACCT_ADL_K_SNAP_OFF = 96;
1885
+ var V12_17_ACCT_F_SNAP_OFF = 112;
1886
+ var V12_17_ACCT_ADL_EPOCH_SNAP_OFF = 128;
1887
+ var V12_17_ACCT_MATCHER_PROGRAM_OFF = 136;
1888
+ var V12_17_ACCT_MATCHER_CONTEXT_OFF = 168;
1889
+ var V12_17_ACCT_OWNER_OFF = 200;
1890
+ var V12_17_ACCT_FEE_CREDITS_OFF = 232;
1891
+ var V12_17_ACCT_SCHED_PRESENT_OFF = 248;
1892
+ var V12_17_ACCT_SCHED_REMAINING_Q_OFF = 256;
1893
+ var V12_17_ACCT_SCHED_ANCHOR_Q_OFF = 272;
1894
+ var V12_17_ACCT_SCHED_START_SLOT_OFF = 288;
1895
+ var V12_17_ACCT_SCHED_HORIZON_OFF = 296;
1896
+ var V12_17_ACCT_SCHED_RELEASE_Q_OFF = 304;
1897
+ var V12_17_ACCT_PENDING_PRESENT_OFF = 320;
1898
+ var V12_17_ACCT_PENDING_REMAINING_Q_OFF = 336;
1899
+ var V12_17_ACCT_PENDING_HORIZON_OFF = 352;
1900
+ var V12_17_ACCT_PENDING_CREATED_SLOT_OFF = 360;
1901
+ var V12_17_ENGINE_PARAMS_OFF = 32;
1902
+ var V12_17_ENGINE_CURRENT_SLOT_OFF = 224;
1903
+ var V12_17_ENGINE_MARKET_MODE_OFF = 232;
1904
+ var V12_17_ENGINE_RESOLVED_K_LONG_OFF = 304;
1905
+ var V12_17_ENGINE_RESOLVED_K_SHORT_OFF = 320;
1906
+ var V12_17_ENGINE_RESOLVED_LIVE_PRICE_OFF = 336;
1907
+ var V12_17_ENGINE_C_TOT_OFF = 352;
1908
+ var V12_17_ENGINE_PNL_POS_TOT_OFF = 368;
1909
+ var V12_17_ENGINE_PNL_MATURED_POS_TOT_OFF = 384;
1910
+ var V12_17_ENGINE_NEG_PNL_COUNT_OFF = 648;
1911
+ var V12_17_ENGINE_LAST_ORACLE_PRICE_OFF = 656;
1912
+ var V12_17_ENGINE_FUND_PX_LAST_OFF = 664;
1913
+ var V12_17_ENGINE_F_LONG_NUM_OFF = 688;
1914
+ var V12_17_ENGINE_F_SHORT_NUM_OFF = 704;
1915
+ var V12_17_SBF_ENGINE_CURRENT_SLOT_OFF = 216;
1916
+ var V12_17_SBF_ENGINE_MARKET_MODE_OFF = 224;
1917
+ var V12_17_SBF_ENGINE_C_TOT_OFF = 336;
1918
+ var V12_17_SBF_ENGINE_PNL_POS_TOT_OFF = 352;
1919
+ var V12_17_SBF_ENGINE_PNL_MATURED_POS_TOT_OFF = 368;
1920
+ var V12_17_SBF_ENGINE_NEG_PNL_COUNT_OFF = 616;
1921
+ var V12_17_SBF_ENGINE_LAST_ORACLE_PRICE_OFF = 624;
1922
+ var V12_17_SBF_ENGINE_FUND_PX_LAST_OFF = 632;
1923
+ var V12_17_SBF_ENGINE_F_LONG_NUM_OFF = 648;
1924
+ var V12_17_SBF_ENGINE_F_SHORT_NUM_OFF = 664;
1925
+ var V12_17_SIZES = /* @__PURE__ */ new Map();
1693
1926
  var V1M_ENGINE_OFF = 640;
1694
1927
  var V1M_CONFIG_LEN = 536;
1695
1928
  var V1M_ACCOUNT_SIZE = 248;
@@ -1766,6 +1999,21 @@ for (const n of TIERS) {
1766
1999
  }
1767
2000
  V12_15_SIZES.set(computeSlabSize(V12_15_ENGINE_OFF, V12_15_ENGINE_BITMAP_OFF, V12_15_ACCOUNT_SIZE, 2048, 18), 2048);
1768
2001
  V12_15_SIZES.set(237512, 256);
2002
+ var V12_17_TIERS = [256, 1024, 4096];
2003
+ for (const n of V12_17_TIERS) {
2004
+ const bitmapWords = Math.ceil(n / 64);
2005
+ const bitmapBytes = bitmapWords * 8;
2006
+ const postBitmap = 4;
2007
+ const nextFreeBytes = n * 2;
2008
+ const preAccNative = V12_17_ENGINE_BITMAP_OFF + bitmapBytes + postBitmap + nextFreeBytes;
2009
+ const accountsOffNative = Math.ceil(preAccNative / 16) * 16;
2010
+ const nativeSize = V12_17_ENGINE_OFF + accountsOffNative + n * V12_17_ACCOUNT_SIZE + V12_17_RISK_BUF_LEN;
2011
+ V12_17_SIZES.set(nativeSize, n);
2012
+ const preAccSbf = V12_17_ENGINE_BITMAP_OFF_SBF + bitmapBytes + postBitmap + nextFreeBytes;
2013
+ const accountsOffSbf = Math.ceil(preAccSbf / 8) * 8;
2014
+ const sbfSize = V12_17_ENGINE_OFF_SBF + accountsOffSbf + n * V12_17_ACCOUNT_SIZE_SBF + V12_17_RISK_BUF_LEN;
2015
+ V12_17_SIZES.set(sbfSize, n);
2016
+ }
1769
2017
  var V12_1_SBF_ACCOUNT_SIZE = 280;
1770
2018
  var V12_1_SBF_ENGINE_OFF = 616;
1771
2019
  var V12_1_SBF_BITMAP_OFF = 584;
@@ -2253,6 +2501,14 @@ for (const [label, n] of [["Micro", 64], ["Small", 256], ["Medium", 1024], ["Med
2253
2501
  const size = computeSlabSize(V12_15_ENGINE_OFF, V12_15_ENGINE_BITMAP_OFF, V12_15_ACCOUNT_SIZE, n, 18);
2254
2502
  SLAB_TIERS_V12_15[label.toLowerCase()] = { maxAccounts: n, dataSize: size, label, description: `${n} slots (v12.15)` };
2255
2503
  }
2504
+ var SLAB_TIERS_V12_17 = {};
2505
+ for (const [label, n] of [["Small", 256], ["Medium", 1024], ["Large", 4096]]) {
2506
+ const bitmapBytes = Math.ceil(n / 64) * 8;
2507
+ const preAcc = V12_17_ENGINE_BITMAP_OFF_SBF + bitmapBytes + 4 + n * 2;
2508
+ const accountsOff = Math.ceil(preAcc / 8) * 8;
2509
+ const size = V12_17_ENGINE_OFF_SBF + accountsOff + n * V12_17_ACCOUNT_SIZE_SBF + V12_17_RISK_BUF_LEN;
2510
+ SLAB_TIERS_V12_17[label.toLowerCase()] = { maxAccounts: n, dataSize: size, label, description: `${n} slots (v12.17)` };
2511
+ }
2256
2512
  function buildLayoutVSetDexPool(maxAccounts) {
2257
2513
  const engineOff = V_SETDEXPOOL_ENGINE_OFF;
2258
2514
  const bitmapOff = V_ADL_ENGINE_BITMAP_OFF;
@@ -2551,7 +2807,84 @@ function buildLayoutV12_15(maxAccounts, dataLen) {
2551
2807
  engineInsuranceIsolationBpsOff: -1
2552
2808
  };
2553
2809
  }
2810
+ function buildLayoutV12_17(maxAccounts, dataLen) {
2811
+ const isSbf = (() => {
2812
+ const bitmapBytes2 = Math.ceil(maxAccounts / 64) * 8;
2813
+ const preAccNative = V12_17_ENGINE_BITMAP_OFF + bitmapBytes2 + 4 + maxAccounts * 2;
2814
+ const accountsOffNative = Math.ceil(preAccNative / 16) * 16;
2815
+ const nativeSize = V12_17_ENGINE_OFF + accountsOffNative + maxAccounts * V12_17_ACCOUNT_SIZE + V12_17_RISK_BUF_LEN;
2816
+ return dataLen !== nativeSize;
2817
+ })();
2818
+ const engineOff = isSbf ? V12_17_ENGINE_OFF_SBF : V12_17_ENGINE_OFF;
2819
+ const accountSize = isSbf ? V12_17_ACCOUNT_SIZE_SBF : V12_17_ACCOUNT_SIZE;
2820
+ const bitmapOff = isSbf ? V12_17_ENGINE_BITMAP_OFF_SBF : V12_17_ENGINE_BITMAP_OFF;
2821
+ const bitmapWords = Math.ceil(maxAccounts / 64);
2822
+ const bitmapBytes = bitmapWords * 8;
2823
+ const postBitmap = 4;
2824
+ const nextFreeBytes = maxAccounts * 2;
2825
+ const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;
2826
+ const acctAlign = isSbf ? 8 : 16;
2827
+ const accountsOffRel = Math.ceil(preAccountsLen / acctAlign) * acctAlign;
2828
+ return {
2829
+ version: 2,
2830
+ headerLen: V0_HEADER_LEN,
2831
+ // 72
2832
+ configOffset: V0_HEADER_LEN,
2833
+ // 72
2834
+ configLen: 432,
2835
+ // upstream 400 + dex_pool 32
2836
+ reservedOff: V1_RESERVED_OFF,
2837
+ // 80
2838
+ engineOff,
2839
+ accountSize,
2840
+ maxAccounts,
2841
+ bitmapWords,
2842
+ accountsOff: engineOff + accountsOffRel,
2843
+ engineInsuranceOff: 16,
2844
+ engineParamsOff: V12_17_ENGINE_PARAMS_OFF,
2845
+ // 32
2846
+ paramsSize: isSbf ? 184 : 192,
2847
+ engineCurrentSlotOff: isSbf ? V12_17_SBF_ENGINE_CURRENT_SLOT_OFF : V12_17_ENGINE_CURRENT_SLOT_OFF,
2848
+ engineFundingIndexOff: -1,
2849
+ // replaced by per-side f_long_num/f_short_num
2850
+ engineLastFundingSlotOff: -1,
2851
+ engineFundingRateBpsOff: -1,
2852
+ // no stored funding rate in v12.17
2853
+ engineMarkPriceOff: -1,
2854
+ engineLastCrankSlotOff: -1,
2855
+ engineMaxCrankStalenessOff: -1,
2856
+ engineTotalOiOff: -1,
2857
+ engineLongOiOff: -1,
2858
+ engineShortOiOff: -1,
2859
+ engineCTotOff: isSbf ? V12_17_SBF_ENGINE_C_TOT_OFF : V12_17_ENGINE_C_TOT_OFF,
2860
+ enginePnlPosTotOff: isSbf ? V12_17_SBF_ENGINE_PNL_POS_TOT_OFF : V12_17_ENGINE_PNL_POS_TOT_OFF,
2861
+ engineLiqCursorOff: -1,
2862
+ engineGcCursorOff: -1,
2863
+ engineLastSweepStartOff: -1,
2864
+ engineLastSweepCompleteOff: -1,
2865
+ engineCrankCursorOff: -1,
2866
+ engineSweepStartIdxOff: -1,
2867
+ engineLifetimeLiquidationsOff: -1,
2868
+ engineLifetimeForceClosesOff: -1,
2869
+ engineNetLpPosOff: -1,
2870
+ engineLpSumAbsOff: -1,
2871
+ engineLpMaxAbsOff: -1,
2872
+ engineLpMaxAbsSweepOff: -1,
2873
+ engineEmergencyOiModeOff: -1,
2874
+ engineEmergencyStartSlotOff: -1,
2875
+ engineLastBreakerSlotOff: -1,
2876
+ engineBitmapOff: bitmapOff,
2877
+ postBitmap,
2878
+ acctOwnerOff: isSbf ? 192 : V12_17_ACCT_OWNER_OFF,
2879
+ // SBF=192, native=200
2880
+ hasInsuranceIsolation: false,
2881
+ engineInsuranceIsolatedOff: -1,
2882
+ engineInsuranceIsolationBpsOff: -1
2883
+ };
2884
+ }
2554
2885
  function detectSlabLayout(dataLen, data) {
2886
+ const v1217n = V12_17_SIZES.get(dataLen);
2887
+ if (v1217n !== void 0) return buildLayoutV12_17(v1217n, dataLen);
2555
2888
  const v1215n = V12_15_SIZES.get(dataLen);
2556
2889
  if (v1215n !== void 0) return buildLayoutV12_15(v1215n, dataLen);
2557
2890
  const v121epn = V12_1_EP_SIZES.get(dataLen);
@@ -2681,7 +3014,7 @@ function parseHeader(data) {
2681
3014
  const version = readU32LE(data, 8);
2682
3015
  const bump = readU8(data, 12);
2683
3016
  const flags = readU8(data, 13);
2684
- const admin = new PublicKey3(data.subarray(16, 48));
3017
+ const admin = new PublicKey5(data.subarray(16, 48));
2685
3018
  const layout = detectSlabLayout(data.length, data);
2686
3019
  const roff = layout ? layout.reservedOff : V0_RESERVED_OFF;
2687
3020
  const nonce = readU64LE(data, roff);
@@ -2702,16 +3035,17 @@ function parseConfig(data, layoutHint) {
2702
3035
  const layout = layoutHint !== void 0 ? layoutHint : detectSlabLayout(data.length, data);
2703
3036
  const configOff = layout ? layout.configOffset : V0_HEADER_LEN;
2704
3037
  const configLen = layout ? layout.configLen : V0_CONFIG_LEN;
2705
- const minLen = configOff + Math.min(configLen, 120);
3038
+ const MIN_CONFIG_BYTES = 376;
3039
+ const minLen = configOff + Math.min(configLen, MIN_CONFIG_BYTES);
2706
3040
  if (data.length < minLen) {
2707
3041
  throw new Error(`Slab data too short for config: ${data.length} < ${minLen}`);
2708
3042
  }
2709
3043
  let off = configOff;
2710
- const collateralMint = new PublicKey3(data.subarray(off, off + 32));
3044
+ const collateralMint = new PublicKey5(data.subarray(off, off + 32));
2711
3045
  off += 32;
2712
- const vaultPubkey = new PublicKey3(data.subarray(off, off + 32));
3046
+ const vaultPubkey = new PublicKey5(data.subarray(off, off + 32));
2713
3047
  off += 32;
2714
- const indexFeedId = new PublicKey3(data.subarray(off, off + 32));
3048
+ const indexFeedId = new PublicKey5(data.subarray(off, off + 32));
2715
3049
  off += 32;
2716
3050
  const maxStalenessSlots = readU64LE(data, off);
2717
3051
  off += 8;
@@ -2749,7 +3083,7 @@ function parseConfig(data, layoutHint) {
2749
3083
  off += 16;
2750
3084
  const threshMinStep = readU128LE(data, off);
2751
3085
  off += 16;
2752
- const oracleAuthority = new PublicKey3(data.subarray(off, off + 32));
3086
+ const oracleAuthority = new PublicKey5(data.subarray(off, off + 32));
2753
3087
  off += 32;
2754
3088
  const authorityPriceE6 = readU64LE(data, off);
2755
3089
  off += 8;
@@ -2802,7 +3136,7 @@ function parseConfig(data, layoutHint) {
2802
3136
  if (configLen >= DEX_POOL_REL_OFF + 32 && data.length >= configOff + DEX_POOL_REL_OFF + 32) {
2803
3137
  const dexPoolBytes = data.subarray(configOff + DEX_POOL_REL_OFF, configOff + DEX_POOL_REL_OFF + 32);
2804
3138
  if (dexPoolBytes.some((b) => b !== 0)) {
2805
- dexPool = new PublicKey3(dexPoolBytes);
3139
+ dexPool = new PublicKey5(dexPoolBytes);
2806
3140
  }
2807
3141
  }
2808
3142
  return {
@@ -2857,8 +3191,9 @@ function parseParams(data, layoutHint) {
2857
3191
  const paramsOff = layout ? layout.engineParamsOff : V0_ENGINE_PARAMS_OFF;
2858
3192
  const paramsSize = layout ? layout.paramsSize : V0_PARAMS_SIZE;
2859
3193
  const base = engineOff + paramsOff;
2860
- if (data.length < base + Math.min(paramsSize, 56)) {
2861
- throw new Error("Slab data too short for RiskParams");
3194
+ const MIN_PARAMS_BYTES = paramsSize >= 144 ? 144 : 56;
3195
+ if (data.length < base + MIN_PARAMS_BYTES) {
3196
+ throw new Error(`Slab data too short for RiskParams: ${data.length} < ${base + MIN_PARAMS_BYTES}`);
2862
3197
  }
2863
3198
  const isV12_15Params = paramsSize === V12_15_PARAMS_SIZE || paramsSize === 184;
2864
3199
  const isV12_1Sbf = !isV12_15Params && layout !== null && layout !== void 0 && layout.engineOff === V12_1_SBF_ENGINE_OFF && paramsSize === 184;
@@ -2929,7 +3264,79 @@ function parseEngine(data) {
2929
3264
  throw new Error(`Unrecognized slab data length: ${data.length}. Cannot determine layout version.`);
2930
3265
  }
2931
3266
  const base = layout.engineOff;
2932
- const isV12_15 = (layout.accountSize === V12_15_ACCOUNT_SIZE || layout.accountSize === V12_15_ACCOUNT_SIZE_SMALL) && (layout.engineOff === V12_15_ENGINE_OFF || layout.engineOff === V12_15_ENGINE_OFF_SBF);
3267
+ const isV12_17 = layout.accountSize === V12_17_ACCOUNT_SIZE || layout.accountSize === V12_17_ACCOUNT_SIZE_SBF;
3268
+ const isV12_15 = !isV12_17 && (layout.accountSize === V12_15_ACCOUNT_SIZE || layout.accountSize === V12_15_ACCOUNT_SIZE_SMALL) && (layout.engineOff === V12_15_ENGINE_OFF || layout.engineOff === V12_15_ENGINE_OFF_SBF);
3269
+ if (isV12_17) {
3270
+ const isSbf = layout.engineOff === V12_17_ENGINE_OFF_SBF;
3271
+ const currentSlotOff = isSbf ? V12_17_SBF_ENGINE_CURRENT_SLOT_OFF : V12_17_ENGINE_CURRENT_SLOT_OFF;
3272
+ const marketModeOff = isSbf ? V12_17_SBF_ENGINE_MARKET_MODE_OFF : V12_17_ENGINE_MARKET_MODE_OFF;
3273
+ const cTotOff = isSbf ? V12_17_SBF_ENGINE_C_TOT_OFF : V12_17_ENGINE_C_TOT_OFF;
3274
+ const pnlPosTotOff = isSbf ? V12_17_SBF_ENGINE_PNL_POS_TOT_OFF : V12_17_ENGINE_PNL_POS_TOT_OFF;
3275
+ const pnlMaturedOff = isSbf ? V12_17_SBF_ENGINE_PNL_MATURED_POS_TOT_OFF : V12_17_ENGINE_PNL_MATURED_POS_TOT_OFF;
3276
+ const negPnlOff = isSbf ? V12_17_SBF_ENGINE_NEG_PNL_COUNT_OFF : V12_17_ENGINE_NEG_PNL_COUNT_OFF;
3277
+ const oraclePriceOff = isSbf ? V12_17_SBF_ENGINE_LAST_ORACLE_PRICE_OFF : V12_17_ENGINE_LAST_ORACLE_PRICE_OFF;
3278
+ const fundPxLastOff = isSbf ? V12_17_SBF_ENGINE_FUND_PX_LAST_OFF : V12_17_ENGINE_FUND_PX_LAST_OFF;
3279
+ const fLongNumOff = isSbf ? V12_17_SBF_ENGINE_F_LONG_NUM_OFF : V12_17_ENGINE_F_LONG_NUM_OFF;
3280
+ const fShortNumOff = isSbf ? V12_17_SBF_ENGINE_F_SHORT_NUM_OFF : V12_17_ENGINE_F_SHORT_NUM_OFF;
3281
+ const resolvedKLongOff = isSbf ? 288 : V12_17_ENGINE_RESOLVED_K_LONG_OFF;
3282
+ const resolvedKShortOff = isSbf ? 304 : V12_17_ENGINE_RESOLVED_K_SHORT_OFF;
3283
+ const resolvedLivePriceOff = isSbf ? 320 : V12_17_ENGINE_RESOLVED_LIVE_PRICE_OFF;
3284
+ const bitmapEnd = layout.engineBitmapOff + layout.bitmapWords * 8;
3285
+ return {
3286
+ vault: readU128LE(data, base),
3287
+ insuranceFund: {
3288
+ balance: readU128LE(data, base + 16),
3289
+ feeRevenue: 0n,
3290
+ isolatedBalance: 0n,
3291
+ isolationBps: 0
3292
+ },
3293
+ currentSlot: readU64LE(data, base + currentSlotOff),
3294
+ fundingIndexQpbE6: 0n,
3295
+ // replaced by per-side funding
3296
+ lastFundingSlot: 0n,
3297
+ fundingRateBpsPerSlotLast: 0n,
3298
+ // no stored funding rate in v12.17
3299
+ fundingRateE9: 0n,
3300
+ // no stored funding rate in v12.17
3301
+ marketMode: readU8(data, base + marketModeOff) === 1 ? 1 : 0,
3302
+ lastCrankSlot: 0n,
3303
+ maxCrankStalenessSlots: 0n,
3304
+ totalOpenInterest: 0n,
3305
+ longOi: 0n,
3306
+ shortOi: 0n,
3307
+ cTot: readU128LE(data, base + cTotOff),
3308
+ pnlPosTot: readU128LE(data, base + pnlPosTotOff),
3309
+ pnlMaturedPosTot: readU128LE(data, base + pnlMaturedOff),
3310
+ liqCursor: 0,
3311
+ gcCursor: 0,
3312
+ lastSweepStartSlot: 0n,
3313
+ lastSweepCompleteSlot: 0n,
3314
+ crankCursor: 0,
3315
+ sweepStartIdx: 0,
3316
+ lifetimeLiquidations: 0n,
3317
+ lifetimeForceCloses: 0n,
3318
+ netLpPos: 0n,
3319
+ lpSumAbs: 0n,
3320
+ lpMaxAbs: 0n,
3321
+ lpMaxAbsSweep: 0n,
3322
+ emergencyOiMode: false,
3323
+ emergencyStartSlot: 0n,
3324
+ lastBreakerSlot: 0n,
3325
+ markPriceE6: 0n,
3326
+ oraclePriceE6: readU64LE(data, base + oraclePriceOff),
3327
+ numUsedAccounts: readU16LE(data, base + bitmapEnd),
3328
+ nextAccountId: 0n,
3329
+ // removed in v12.17 (replaced by mat_counter in header)
3330
+ // V12_17 fields
3331
+ fLongNum: readI128LE(data, base + fLongNumOff),
3332
+ fShortNum: readI128LE(data, base + fShortNumOff),
3333
+ negPnlAccountCount: readU64LE(data, base + negPnlOff),
3334
+ fundPxLast: readU64LE(data, base + fundPxLastOff),
3335
+ resolvedKLongTerminalDelta: readI128LE(data, base + resolvedKLongOff),
3336
+ resolvedKShortTerminalDelta: readI128LE(data, base + resolvedKShortOff),
3337
+ resolvedLivePrice: readU64LE(data, base + resolvedLivePriceOff)
3338
+ };
3339
+ }
2933
3340
  const fundingRateBpsPerSlotLast = isV12_15 ? readI128LE(data, base + layout.engineFundingRateBpsOff) : readI64LE(data, base + layout.engineFundingRateBpsOff);
2934
3341
  return {
2935
3342
  vault: readU128LE(data, base),
@@ -2983,7 +3390,15 @@ function parseEngine(data) {
2983
3390
  const bw = layout.bitmapWords;
2984
3391
  const numUsedOff = layout.engineBitmapOff + bw * 8;
2985
3392
  return readU64LE(data, base + Math.ceil((numUsedOff + 2) / 8) * 8);
2986
- })()
3393
+ })(),
3394
+ // V12_17 fields (not present in pre-v12.17)
3395
+ fLongNum: 0n,
3396
+ fShortNum: 0n,
3397
+ negPnlAccountCount: 0n,
3398
+ fundPxLast: 0n,
3399
+ resolvedKLongTerminalDelta: 0n,
3400
+ resolvedKShortTerminalDelta: 0n,
3401
+ resolvedLivePrice: 0n
2987
3402
  };
2988
3403
  }
2989
3404
  function parseUsedIndices(data) {
@@ -3033,10 +3448,65 @@ function parseAccount(data, idx) {
3033
3448
  if (data.length < base + layout.accountSize) {
3034
3449
  throw new Error("Slab data too short for account");
3035
3450
  }
3036
- const isV12_15 = layout.accountSize === V12_15_ACCOUNT_SIZE || layout.accountSize === V12_15_ACCOUNT_SIZE_SMALL;
3037
- const isV12_1EP = !isV12_15 && layout.accountSize === V12_1_EP_SBF_ACCOUNT_SIZE && layout.engineOff === V12_1_SBF_ENGINE_OFF;
3038
- const isV12_1 = !isV12_15 && !isV12_1EP && (layout.engineOff === V12_1_ENGINE_OFF || layout.engineOff === V12_1_SBF_ENGINE_OFF) && (layout.accountSize === V12_1_ACCOUNT_SIZE || layout.accountSize === V12_1_ACCOUNT_SIZE_SBF);
3039
- const isAdl = !isV12_15 && (layout.accountSize >= 312 || isV12_1 || isV12_1EP);
3451
+ const isV12_17 = layout.accountSize === V12_17_ACCOUNT_SIZE || layout.accountSize === V12_17_ACCOUNT_SIZE_SBF;
3452
+ const isV12_15 = !isV12_17 && (layout.accountSize === V12_15_ACCOUNT_SIZE || layout.accountSize === V12_15_ACCOUNT_SIZE_SMALL);
3453
+ const isV12_1EP = !isV12_17 && !isV12_15 && layout.accountSize === V12_1_EP_SBF_ACCOUNT_SIZE && layout.engineOff === V12_1_SBF_ENGINE_OFF;
3454
+ const isV12_1 = !isV12_17 && !isV12_15 && !isV12_1EP && (layout.engineOff === V12_1_ENGINE_OFF || layout.engineOff === V12_1_SBF_ENGINE_OFF) && (layout.accountSize === V12_1_ACCOUNT_SIZE || layout.accountSize === V12_1_ACCOUNT_SIZE_SBF);
3455
+ const isAdl = !isV12_17 && !isV12_15 && (layout.accountSize >= 312 || isV12_1 || isV12_1EP);
3456
+ if (isV12_17) {
3457
+ const isSbf = layout.accountSize === V12_17_ACCOUNT_SIZE_SBF;
3458
+ const d1 = isSbf ? 8 : 0;
3459
+ const d2 = isSbf ? 16 : 0;
3460
+ const kindByte2 = readU8(data, base + V12_17_ACCT_KIND_OFF);
3461
+ const kind2 = kindByte2 === 1 ? 1 /* LP */ : 0 /* User */;
3462
+ return {
3463
+ kind: kind2,
3464
+ accountId: 0n,
3465
+ // removed in v12.17
3466
+ capital: readU128LE(data, base + V12_17_ACCT_CAPITAL_OFF),
3467
+ pnl: readI128LE(data, base + V12_17_ACCT_PNL_OFF - d1),
3468
+ reservedPnl: readU128LE(data, base + V12_17_ACCT_RESERVED_PNL_OFF - d1),
3469
+ warmupStartedAtSlot: 0n,
3470
+ // removed
3471
+ warmupSlopePerStep: 0n,
3472
+ // removed
3473
+ positionSize: readI128LE(data, base + V12_17_ACCT_POSITION_BASIS_Q_OFF - d1),
3474
+ entryPrice: 0n,
3475
+ // removed — compute off-chain from position_basis_q / effective_pos_q
3476
+ fundingIndex: 0n,
3477
+ // replaced by per-side f_long_num/f_short_num + per-account f_snap
3478
+ matcherProgram: new PublicKey5(data.subarray(base + V12_17_ACCT_MATCHER_PROGRAM_OFF - d1, base + V12_17_ACCT_MATCHER_PROGRAM_OFF - d1 + 32)),
3479
+ matcherContext: new PublicKey5(data.subarray(base + V12_17_ACCT_MATCHER_CONTEXT_OFF - d1, base + V12_17_ACCT_MATCHER_CONTEXT_OFF - d1 + 32)),
3480
+ owner: new PublicKey5(data.subarray(base + V12_17_ACCT_OWNER_OFF - d1, base + V12_17_ACCT_OWNER_OFF - d1 + 32)),
3481
+ feeCredits: readI128LE(data, base + V12_17_ACCT_FEE_CREDITS_OFF - d1),
3482
+ lastFeeSlot: 0n,
3483
+ // removed
3484
+ feesEarnedTotal: 0n,
3485
+ // removed in v12.17
3486
+ exactReserveCohorts: null,
3487
+ // replaced by two-bucket warmup
3488
+ exactCohortCount: null,
3489
+ overflowOlder: null,
3490
+ overflowOlderPresent: null,
3491
+ overflowNewest: null,
3492
+ overflowNewestPresent: null,
3493
+ // V12_17 fields
3494
+ fSnap: readI128LE(data, base + V12_17_ACCT_F_SNAP_OFF - d1),
3495
+ adlABasis: readU128LE(data, base + V12_17_ACCT_ADL_A_BASIS_OFF - d1),
3496
+ adlKSnap: readI128LE(data, base + V12_17_ACCT_ADL_K_SNAP_OFF - d1),
3497
+ adlEpochSnap: readU64LE(data, base + V12_17_ACCT_ADL_EPOCH_SNAP_OFF - d1),
3498
+ schedPresent: readU8(data, base + V12_17_ACCT_SCHED_PRESENT_OFF - d1) !== 0,
3499
+ schedRemainingQ: readU128LE(data, base + V12_17_ACCT_SCHED_REMAINING_Q_OFF - d1),
3500
+ schedAnchorQ: readU128LE(data, base + V12_17_ACCT_SCHED_ANCHOR_Q_OFF - d1),
3501
+ schedStartSlot: readU64LE(data, base + V12_17_ACCT_SCHED_START_SLOT_OFF - d1),
3502
+ schedHorizon: readU64LE(data, base + V12_17_ACCT_SCHED_HORIZON_OFF - d1),
3503
+ schedReleaseQ: readU128LE(data, base + V12_17_ACCT_SCHED_RELEASE_Q_OFF - d1),
3504
+ pendingPresent: readU8(data, base + V12_17_ACCT_PENDING_PRESENT_OFF - d1) !== 0,
3505
+ pendingRemainingQ: readU128LE(data, base + V12_17_ACCT_PENDING_REMAINING_Q_OFF - d2),
3506
+ pendingHorizon: readU64LE(data, base + V12_17_ACCT_PENDING_HORIZON_OFF - d2),
3507
+ pendingCreatedSlot: readU64LE(data, base + V12_17_ACCT_PENDING_CREATED_SLOT_OFF - d2)
3508
+ };
3509
+ }
3040
3510
  if (isV12_15) {
3041
3511
  const kindByte2 = readU8(data, base + V12_15_ACCT_KIND_OFF);
3042
3512
  const kind2 = kindByte2 === 1 ? 1 /* LP */ : 0 /* User */;
@@ -3062,9 +3532,9 @@ function parseAccount(data, idx) {
3062
3532
  entryPrice: readU64LE(data, base + V12_15_ACCT_ENTRY_PRICE_OFF),
3063
3533
  fundingIndex: 0n,
3064
3534
  // not present in v12.15 account struct
3065
- matcherProgram: new PublicKey3(data.subarray(base + V12_15_ACCT_MATCHER_PROGRAM_OFF, base + V12_15_ACCT_MATCHER_PROGRAM_OFF + 32)),
3066
- matcherContext: new PublicKey3(data.subarray(base + V12_15_ACCT_MATCHER_CONTEXT_OFF, base + V12_15_ACCT_MATCHER_CONTEXT_OFF + 32)),
3067
- owner: new PublicKey3(data.subarray(base + V12_15_ACCT_OWNER_OFF, base + V12_15_ACCT_OWNER_OFF + 32)),
3535
+ matcherProgram: new PublicKey5(data.subarray(base + V12_15_ACCT_MATCHER_PROGRAM_OFF, base + V12_15_ACCT_MATCHER_PROGRAM_OFF + 32)),
3536
+ matcherContext: new PublicKey5(data.subarray(base + V12_15_ACCT_MATCHER_CONTEXT_OFF, base + V12_15_ACCT_MATCHER_CONTEXT_OFF + 32)),
3537
+ owner: new PublicKey5(data.subarray(base + V12_15_ACCT_OWNER_OFF, base + V12_15_ACCT_OWNER_OFF + 32)),
3068
3538
  feeCredits: readI128LE(data, base + V12_15_ACCT_FEE_CREDITS_OFF),
3069
3539
  lastFeeSlot: 0n,
3070
3540
  // removed in v12.15
@@ -3074,7 +3544,22 @@ function parseAccount(data, idx) {
3074
3544
  overflowOlder: data.slice(base + V12_15_ACCT_OVERFLOW_OLDER_OFF, base + V12_15_ACCT_OVERFLOW_OLDER_OFF + 64),
3075
3545
  overflowOlderPresent,
3076
3546
  overflowNewest: data.slice(base + V12_15_ACCT_OVERFLOW_NEWEST_OFF, base + V12_15_ACCT_OVERFLOW_NEWEST_OFF + 64),
3077
- overflowNewestPresent
3547
+ overflowNewestPresent,
3548
+ // v12.17 fields (not present in v12.15)
3549
+ fSnap: 0n,
3550
+ adlABasis: 0n,
3551
+ adlKSnap: 0n,
3552
+ adlEpochSnap: 0n,
3553
+ schedPresent: null,
3554
+ schedRemainingQ: null,
3555
+ schedAnchorQ: null,
3556
+ schedStartSlot: null,
3557
+ schedHorizon: null,
3558
+ schedReleaseQ: null,
3559
+ pendingPresent: null,
3560
+ pendingRemainingQ: null,
3561
+ pendingHorizon: null,
3562
+ pendingCreatedSlot: null
3078
3563
  };
3079
3564
  }
3080
3565
  const warmupStartedOff = isAdl ? V_ADL_ACCT_WARMUP_STARTED_OFF : ACCT_WARMUP_STARTED_OFF;
@@ -3100,9 +3585,9 @@ function parseAccount(data, idx) {
3100
3585
  entryPrice: entryPriceOff >= 0 ? readU64LE(data, base + entryPriceOff) : 0n,
3101
3586
  // V12_1/V12_1_EP: funding_index not present in SBF layout
3102
3587
  fundingIndex: isV12_1 || isV12_1EP ? fundingIndexOff >= 0 ? BigInt(readI64LE(data, base + fundingIndexOff)) : 0n : readI128LE(data, base + fundingIndexOff),
3103
- matcherProgram: new PublicKey3(data.subarray(base + matcherProgOff, base + matcherProgOff + 32)),
3104
- matcherContext: new PublicKey3(data.subarray(base + matcherCtxOff, base + matcherCtxOff + 32)),
3105
- owner: new PublicKey3(data.subarray(base + layout.acctOwnerOff, base + layout.acctOwnerOff + 32)),
3588
+ matcherProgram: new PublicKey5(data.subarray(base + matcherProgOff, base + matcherProgOff + 32)),
3589
+ matcherContext: new PublicKey5(data.subarray(base + matcherCtxOff, base + matcherCtxOff + 32)),
3590
+ owner: new PublicKey5(data.subarray(base + layout.acctOwnerOff, base + layout.acctOwnerOff + 32)),
3106
3591
  feeCredits: readI128LE(data, base + feeCreditsOff),
3107
3592
  lastFeeSlot: readU64LE(data, base + lastFeeSlotOff),
3108
3593
  feesEarnedTotal: 0n,
@@ -3113,7 +3598,22 @@ function parseAccount(data, idx) {
3113
3598
  overflowOlder: null,
3114
3599
  overflowOlderPresent: null,
3115
3600
  overflowNewest: null,
3116
- overflowNewestPresent: null
3601
+ overflowNewestPresent: null,
3602
+ // v12.17 fields (not present in pre-v12.17)
3603
+ fSnap: 0n,
3604
+ adlABasis: 0n,
3605
+ adlKSnap: 0n,
3606
+ adlEpochSnap: 0n,
3607
+ schedPresent: null,
3608
+ schedRemainingQ: null,
3609
+ schedAnchorQ: null,
3610
+ schedStartSlot: null,
3611
+ schedHorizon: null,
3612
+ schedReleaseQ: null,
3613
+ pendingPresent: null,
3614
+ pendingRemainingQ: null,
3615
+ pendingHorizon: null,
3616
+ pendingCreatedSlot: null
3117
3617
  };
3118
3618
  }
3119
3619
  function parseAllAccounts(data) {
@@ -3133,16 +3633,16 @@ function parseAllAccounts(data) {
3133
3633
  }
3134
3634
 
3135
3635
  // src/solana/pda.ts
3136
- import { PublicKey as PublicKey4 } from "@solana/web3.js";
3636
+ import { PublicKey as PublicKey6 } from "@solana/web3.js";
3137
3637
  var textEncoder = new TextEncoder();
3138
3638
  function deriveVaultAuthority(programId, slab) {
3139
- return PublicKey4.findProgramAddressSync(
3639
+ return PublicKey6.findProgramAddressSync(
3140
3640
  [textEncoder.encode("vault"), slab.toBytes()],
3141
3641
  programId
3142
3642
  );
3143
3643
  }
3144
3644
  function deriveInsuranceLpMint(programId, slab) {
3145
- return PublicKey4.findProgramAddressSync(
3645
+ return PublicKey6.findProgramAddressSync(
3146
3646
  [textEncoder.encode("ins_lp"), slab.toBytes()],
3147
3647
  programId
3148
3648
  );
@@ -3154,28 +3654,28 @@ function deriveLpPda(programId, slab, lpIdx) {
3154
3654
  `deriveLpPda: lpIdx must be an integer in [0, ${LP_INDEX_U16_MAX}], got ${lpIdx}`
3155
3655
  );
3156
3656
  }
3157
- const idxBuf = new Uint8Array(2);
3158
- new DataView(idxBuf.buffer).setUint16(0, lpIdx, true);
3159
- return PublicKey4.findProgramAddressSync(
3160
- [textEncoder.encode("lp"), slab.toBytes(), idxBuf],
3657
+ const idxBuf2 = new Uint8Array(2);
3658
+ new DataView(idxBuf2.buffer).setUint16(0, lpIdx, true);
3659
+ return PublicKey6.findProgramAddressSync(
3660
+ [textEncoder.encode("lp"), slab.toBytes(), idxBuf2],
3161
3661
  programId
3162
3662
  );
3163
3663
  }
3164
- var PUMPSWAP_PROGRAM_ID = new PublicKey4(
3664
+ var PUMPSWAP_PROGRAM_ID = new PublicKey6(
3165
3665
  "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"
3166
3666
  );
3167
- var RAYDIUM_CLMM_PROGRAM_ID = new PublicKey4(
3667
+ var RAYDIUM_CLMM_PROGRAM_ID = new PublicKey6(
3168
3668
  "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK"
3169
3669
  );
3170
- var METEORA_DLMM_PROGRAM_ID = new PublicKey4(
3670
+ var METEORA_DLMM_PROGRAM_ID = new PublicKey6(
3171
3671
  "LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo"
3172
3672
  );
3173
- var PYTH_PUSH_ORACLE_PROGRAM_ID = new PublicKey4(
3673
+ var PYTH_PUSH_ORACLE_PROGRAM_ID = new PublicKey6(
3174
3674
  "pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT"
3175
3675
  );
3176
3676
  var CREATOR_LOCK_SEED = "creator_lock";
3177
3677
  function deriveCreatorLockPda(programId, slab) {
3178
- return PublicKey4.findProgramAddressSync(
3678
+ return PublicKey6.findProgramAddressSync(
3179
3679
  [textEncoder.encode(CREATOR_LOCK_SEED), slab.toBytes()],
3180
3680
  programId
3181
3681
  );
@@ -3200,7 +3700,7 @@ function derivePythPushOraclePDA(feedIdHex) {
3200
3700
  feedId[i] = parseInt(normalized.substring(i * 2, i * 2 + 2), 16);
3201
3701
  }
3202
3702
  const shardBuf = new Uint8Array(2);
3203
- return PublicKey4.findProgramAddressSync(
3703
+ return PublicKey6.findProgramAddressSync(
3204
3704
  [shardBuf, feedId],
3205
3705
  PYTH_PUSH_ORACLE_PROGRAM_ID
3206
3706
  );
@@ -3224,10 +3724,10 @@ async function fetchTokenAccount(connection, address, tokenProgramId = TOKEN_PRO
3224
3724
  }
3225
3725
 
3226
3726
  // src/solana/discovery.ts
3227
- import { PublicKey as PublicKey6 } from "@solana/web3.js";
3727
+ import { PublicKey as PublicKey8 } from "@solana/web3.js";
3228
3728
 
3229
3729
  // src/solana/static-markets.ts
3230
- import { PublicKey as PublicKey5 } from "@solana/web3.js";
3730
+ import { PublicKey as PublicKey7 } from "@solana/web3.js";
3231
3731
  var MAINNET_MARKETS = [
3232
3732
  { slabAddress: "7psyeWRts4pRX2cyAWD1NH87bR9ugXP7pe6ARgfG79Do", symbol: "SOL-PERP", name: "SOL/USDC Perpetual" }
3233
3733
  ];
@@ -3263,7 +3763,7 @@ function registerStaticMarkets(network, entries) {
3263
3763
  if (!entry.slabAddress) continue;
3264
3764
  if (seen.has(entry.slabAddress)) continue;
3265
3765
  try {
3266
- new PublicKey5(entry.slabAddress);
3766
+ new PublicKey7(entry.slabAddress);
3267
3767
  } catch {
3268
3768
  console.warn(
3269
3769
  `[registerStaticMarkets] Skipping invalid slabAddress: ${entry.slabAddress}`
@@ -3287,10 +3787,9 @@ function clearStaticMarkets(network) {
3287
3787
  var ENGINE_BITMAP_OFF_V0 = 320;
3288
3788
  var MAGIC_BYTES = new Uint8Array([84, 65, 76, 79, 67, 82, 69, 80]);
3289
3789
  var SLAB_TIERS = {
3290
- micro: SLAB_TIERS_V12_1["micro"],
3291
- small: SLAB_TIERS_V12_1["small"],
3292
- medium: SLAB_TIERS_V12_1["medium"],
3293
- large: SLAB_TIERS_V12_1["large"]
3790
+ small: SLAB_TIERS_V12_17["small"],
3791
+ medium: SLAB_TIERS_V12_17["medium"],
3792
+ large: SLAB_TIERS_V12_17["large"]
3294
3793
  };
3295
3794
  var SLAB_TIERS_V0 = {
3296
3795
  small: { maxAccounts: 256, dataSize: 62808, label: "Small", description: "256 slots \xB7 ~0.44 SOL" },
@@ -3425,6 +3924,13 @@ function parseEngineLight(data, layout, maxAccounts = 4096) {
3425
3924
  markPriceE6: 0n,
3426
3925
  // V0 engine has no mark_price field
3427
3926
  oraclePriceE6: 0n,
3927
+ fLongNum: 0n,
3928
+ fShortNum: 0n,
3929
+ negPnlAccountCount: 0n,
3930
+ fundPxLast: 0n,
3931
+ resolvedKLongTerminalDelta: 0n,
3932
+ resolvedKShortTerminalDelta: 0n,
3933
+ resolvedLivePrice: 0n,
3428
3934
  numUsedAccounts: canReadNumUsed ? readU16LE2(data, base + numUsedOff) : 0,
3429
3935
  nextAccountId: canReadNextId ? readU64LE2(data, base + nextAccountIdOff) : 0n
3430
3936
  };
@@ -3474,6 +3980,13 @@ function parseEngineLight(data, layout, maxAccounts = 4096) {
3474
3980
  markPriceE6: 0n,
3475
3981
  // V2 has no mark_price
3476
3982
  oraclePriceE6: 0n,
3983
+ fLongNum: 0n,
3984
+ fShortNum: 0n,
3985
+ negPnlAccountCount: 0n,
3986
+ fundPxLast: 0n,
3987
+ resolvedKLongTerminalDelta: 0n,
3988
+ resolvedKShortTerminalDelta: 0n,
3989
+ resolvedLivePrice: 0n,
3477
3990
  numUsedAccounts: canReadNumUsed ? readU16LE2(data, base + numUsedOff) : 0,
3478
3991
  nextAccountId: canReadNextId ? readU64LE2(data, base + nextAccountIdOff) : 0n
3479
3992
  };
@@ -3520,6 +4033,13 @@ function parseEngineLight(data, layout, maxAccounts = 4096) {
3520
4033
  lastBreakerSlot: l.engineLastBreakerSlotOff >= 0 ? readU64LE2(data, base + l.engineLastBreakerSlotOff) : 0n,
3521
4034
  markPriceE6: l.engineMarkPriceOff >= 0 ? readU64LE2(data, base + l.engineMarkPriceOff) : 0n,
3522
4035
  oraclePriceE6: 0n,
4036
+ fLongNum: 0n,
4037
+ fShortNum: 0n,
4038
+ negPnlAccountCount: 0n,
4039
+ fundPxLast: 0n,
4040
+ resolvedKLongTerminalDelta: 0n,
4041
+ resolvedKShortTerminalDelta: 0n,
4042
+ resolvedLivePrice: 0n,
3523
4043
  numUsedAccounts: canReadNumUsed ? readU16LE2(data, base + numUsedOff) : 0,
3524
4044
  nextAccountId: canReadNextId ? readU64LE2(data, base + nextAccountIdOff) : 0n
3525
4045
  };
@@ -3565,6 +4085,13 @@ function parseEngineLight(data, layout, maxAccounts = 4096) {
3565
4085
  markPriceE6: readU64LE2(data, base + 400),
3566
4086
  // PERC-1094: was 392
3567
4087
  oraclePriceE6: 0n,
4088
+ fLongNum: 0n,
4089
+ fShortNum: 0n,
4090
+ negPnlAccountCount: 0n,
4091
+ fundPxLast: 0n,
4092
+ resolvedKLongTerminalDelta: 0n,
4093
+ resolvedKShortTerminalDelta: 0n,
4094
+ resolvedLivePrice: 0n,
3568
4095
  numUsedAccounts: canReadNumUsed ? readU16LE2(data, base + numUsedOff) : 0,
3569
4096
  nextAccountId: canReadNextId ? readU64LE2(data, base + nextAccountIdOff) : 0n
3570
4097
  };
@@ -3586,12 +4113,19 @@ async function discoverMarkets(connection, programId, options = {}) {
3586
4113
  } = options;
3587
4114
  const ALL_TIERS = [
3588
4115
  ...Object.values(SLAB_TIERS),
4116
+ // v12.17 (default)
4117
+ ...Object.values(SLAB_TIERS_V12_15),
4118
+ // v12.15
4119
+ ...Object.values(SLAB_TIERS_V12_1),
4120
+ // v12.1
3589
4121
  ...Object.values(SLAB_TIERS_V0),
3590
4122
  ...Object.values(SLAB_TIERS_V1D),
3591
4123
  ...Object.values(SLAB_TIERS_V1D_LEGACY),
3592
4124
  ...Object.values(SLAB_TIERS_V2),
3593
4125
  ...Object.values(SLAB_TIERS_V1M),
3594
- ...Object.values(SLAB_TIERS_V_ADL)
4126
+ ...Object.values(SLAB_TIERS_V1M2),
4127
+ ...Object.values(SLAB_TIERS_V_ADL),
4128
+ ...Object.values(SLAB_TIERS_V_SETDEXPOOL)
3595
4129
  ];
3596
4130
  let rawAccounts = [];
3597
4131
  async function fetchTierWithRetry(tier) {
@@ -3889,7 +4423,7 @@ async function discoverMarketsViaApi(connection, programId, apiBaseUrl, options
3889
4423
  for (const entry of apiMarkets) {
3890
4424
  if (!entry.slab_address || typeof entry.slab_address !== "string") continue;
3891
4425
  try {
3892
- addresses.push(new PublicKey6(entry.slab_address));
4426
+ addresses.push(new PublicKey8(entry.slab_address));
3893
4427
  } catch {
3894
4428
  console.warn(
3895
4429
  `[discoverMarketsViaApi] Skipping invalid slab address: ${entry.slab_address}`
@@ -3911,7 +4445,7 @@ async function discoverMarketsViaStaticBundle(connection, programId, entries, op
3911
4445
  for (const entry of entries) {
3912
4446
  if (!entry.slabAddress || typeof entry.slabAddress !== "string") continue;
3913
4447
  try {
3914
- addresses.push(new PublicKey6(entry.slabAddress));
4448
+ addresses.push(new PublicKey8(entry.slabAddress));
3915
4449
  } catch {
3916
4450
  console.warn(
3917
4451
  `[discoverMarketsViaStaticBundle] Skipping invalid slab address: ${entry.slabAddress}`
@@ -3929,7 +4463,7 @@ async function discoverMarketsViaStaticBundle(connection, programId, entries, op
3929
4463
  }
3930
4464
 
3931
4465
  // src/solana/dex-oracle.ts
3932
- import { PublicKey as PublicKey7 } from "@solana/web3.js";
4466
+ import { PublicKey as PublicKey9 } from "@solana/web3.js";
3933
4467
  function detectDexType(ownerProgramId) {
3934
4468
  if (ownerProgramId.equals(PUMPSWAP_PROGRAM_ID)) return "pumpswap";
3935
4469
  if (ownerProgramId.equals(RAYDIUM_CLMM_PROGRAM_ID)) return "raydium-clmm";
@@ -3965,10 +4499,10 @@ function parsePumpSwapPool(poolAddress, data) {
3965
4499
  return {
3966
4500
  dexType: "pumpswap",
3967
4501
  poolAddress,
3968
- baseMint: new PublicKey7(data.slice(35, 67)),
3969
- quoteMint: new PublicKey7(data.slice(67, 99)),
3970
- baseVault: new PublicKey7(data.slice(131, 163)),
3971
- quoteVault: new PublicKey7(data.slice(163, 195))
4502
+ baseMint: new PublicKey9(data.slice(35, 67)),
4503
+ quoteMint: new PublicKey9(data.slice(67, 99)),
4504
+ baseVault: new PublicKey9(data.slice(131, 163)),
4505
+ quoteVault: new PublicKey9(data.slice(163, 195))
3972
4506
  };
3973
4507
  }
3974
4508
  var SPL_TOKEN_AMOUNT_MIN_LEN = 72;
@@ -3994,8 +4528,8 @@ function parseRaydiumClmmPool(poolAddress, data) {
3994
4528
  return {
3995
4529
  dexType: "raydium-clmm",
3996
4530
  poolAddress,
3997
- baseMint: new PublicKey7(data.slice(73, 105)),
3998
- quoteMint: new PublicKey7(data.slice(105, 137))
4531
+ baseMint: new PublicKey9(data.slice(73, 105)),
4532
+ quoteMint: new PublicKey9(data.slice(105, 137))
3999
4533
  };
4000
4534
  }
4001
4535
  var MAX_TOKEN_DECIMALS = 24;
@@ -4034,8 +4568,8 @@ function parseMeteoraPool(poolAddress, data) {
4034
4568
  return {
4035
4569
  dexType: "meteora-dlmm",
4036
4570
  poolAddress,
4037
- baseMint: new PublicKey7(data.slice(81, 113)),
4038
- quoteMint: new PublicKey7(data.slice(113, 145))
4571
+ baseMint: new PublicKey9(data.slice(81, 113)),
4572
+ quoteMint: new PublicKey9(data.slice(113, 145))
4039
4573
  };
4040
4574
  }
4041
4575
  var MAX_BIN_STEP = 1e4;
@@ -4130,9 +4664,9 @@ function isValidChainlinkOracle(data) {
4130
4664
  }
4131
4665
 
4132
4666
  // src/solana/token-program.ts
4133
- import { PublicKey as PublicKey8 } from "@solana/web3.js";
4667
+ import { PublicKey as PublicKey10 } from "@solana/web3.js";
4134
4668
  import { TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID3 } from "@solana/spl-token";
4135
- var TOKEN_2022_PROGRAM_ID = new PublicKey8(
4669
+ var TOKEN_2022_PROGRAM_ID = new PublicKey10(
4136
4670
  "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
4137
4671
  );
4138
4672
  async function detectTokenProgram(connection, mint) {
@@ -4148,66 +4682,8 @@ function isStandardToken(tokenProgramId) {
4148
4682
  }
4149
4683
 
4150
4684
  // src/solana/stake.ts
4151
- import { PublicKey as PublicKey10, SystemProgram as SystemProgram2, SYSVAR_RENT_PUBKEY as SYSVAR_RENT_PUBKEY2, SYSVAR_CLOCK_PUBKEY as SYSVAR_CLOCK_PUBKEY2 } from "@solana/web3.js";
4685
+ import { PublicKey as PublicKey11, SystemProgram as SystemProgram2, SYSVAR_RENT_PUBKEY as SYSVAR_RENT_PUBKEY2, SYSVAR_CLOCK_PUBKEY as SYSVAR_CLOCK_PUBKEY2 } from "@solana/web3.js";
4152
4686
  import { TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID4 } from "@solana/spl-token";
4153
-
4154
- // src/config/program-ids.ts
4155
- import { PublicKey as PublicKey9 } from "@solana/web3.js";
4156
- function safeEnv(key) {
4157
- try {
4158
- return typeof process !== "undefined" && process?.env ? process.env[key] : void 0;
4159
- } catch {
4160
- return void 0;
4161
- }
4162
- }
4163
- var PROGRAM_IDS = {
4164
- devnet: {
4165
- percolator: "FxfD37s1AZTeWfFQps9Zpebi2dNQ9QSSDtfMKdbsfKrD",
4166
- matcher: "GTRgyTDfrMvBubALAqtHuQwT8tbGyXid7svXZKtWfC9k"
4167
- },
4168
- mainnet: {
4169
- percolator: "ESa89R5Es3rJ5mnwGybVRG1GrNt9etP11Z5V2QWD4edv",
4170
- matcher: "DHP6DtwXP1yJsz8YzfoeigRFPB979gzmumkmCxDLSkUX"
4171
- }
4172
- };
4173
- function getProgramId(network) {
4174
- const override = safeEnv("PROGRAM_ID");
4175
- if (override) {
4176
- console.warn(
4177
- `[percolator-sdk] PROGRAM_ID env override active: ${override} \u2014 ensure this points to a trusted program`
4178
- );
4179
- return new PublicKey9(override);
4180
- }
4181
- const detectedNetwork = getCurrentNetwork();
4182
- const targetNetwork = network ?? detectedNetwork;
4183
- const programId = PROGRAM_IDS[targetNetwork].percolator;
4184
- return new PublicKey9(programId);
4185
- }
4186
- function getMatcherProgramId(network) {
4187
- const override = safeEnv("MATCHER_PROGRAM_ID");
4188
- if (override) {
4189
- console.warn(
4190
- `[percolator-sdk] MATCHER_PROGRAM_ID env override active: ${override} \u2014 ensure this points to a trusted program`
4191
- );
4192
- return new PublicKey9(override);
4193
- }
4194
- const detectedNetwork = getCurrentNetwork();
4195
- const targetNetwork = network ?? detectedNetwork;
4196
- const programId = PROGRAM_IDS[targetNetwork].matcher;
4197
- if (!programId) {
4198
- throw new Error(`Matcher program not deployed on ${targetNetwork}`);
4199
- }
4200
- return new PublicKey9(programId);
4201
- }
4202
- function getCurrentNetwork() {
4203
- const network = safeEnv("NETWORK")?.toLowerCase();
4204
- if (network === "mainnet" || network === "mainnet-beta") {
4205
- return "mainnet";
4206
- }
4207
- return "devnet";
4208
- }
4209
-
4210
- // src/solana/stake.ts
4211
4687
  var STAKE_PROGRAM_IDS = {
4212
4688
  devnet: "6aJb1F9CDCVWCNYFwj8aQsVb696YnW6J1FznteHq4Q6k",
4213
4689
  mainnet: "DC5fovFQD5SZYsetwvEqd4Wi4PFY1Yfnc669VMe6oa7F"
@@ -4218,7 +4694,7 @@ function getStakeProgramId(network) {
4218
4694
  console.warn(
4219
4695
  `[percolator-sdk] STAKE_PROGRAM_ID env override active: ${override} \u2014 ensure this points to a trusted program`
4220
4696
  );
4221
- return new PublicKey10(override);
4697
+ return new PublicKey11(override);
4222
4698
  }
4223
4699
  const detectedNetwork = network ?? (() => {
4224
4700
  const n = safeEnv("NEXT_PUBLIC_DEFAULT_NETWORK")?.toLowerCase() ?? safeEnv("NETWORK")?.toLowerCase() ?? "";
@@ -4233,9 +4709,9 @@ function getStakeProgramId(network) {
4233
4709
  `Stake program not deployed on ${detectedNetwork}. Set STAKE_PROGRAM_ID env var or wait for DevOps to deploy and update STAKE_PROGRAM_IDS.mainnet.`
4234
4710
  );
4235
4711
  }
4236
- return new PublicKey10(id);
4712
+ return new PublicKey11(id);
4237
4713
  }
4238
- var STAKE_PROGRAM_ID = new PublicKey10(STAKE_PROGRAM_IDS.devnet);
4714
+ var STAKE_PROGRAM_ID = new PublicKey11(STAKE_PROGRAM_IDS.devnet);
4239
4715
  var STAKE_IX = {
4240
4716
  InitPool: 0,
4241
4717
  Deposit: 1,
@@ -4260,22 +4736,22 @@ var STAKE_IX = {
4260
4736
  /** PERC-303: Deposit into junior (first-loss) tranche */
4261
4737
  DepositJunior: 16
4262
4738
  };
4263
- var TEXT = new TextEncoder();
4739
+ var TEXT2 = new TextEncoder();
4264
4740
  function deriveStakePool(slab, programId) {
4265
- return PublicKey10.findProgramAddressSync(
4266
- [TEXT.encode("stake_pool"), slab.toBytes()],
4741
+ return PublicKey11.findProgramAddressSync(
4742
+ [TEXT2.encode("stake_pool"), slab.toBytes()],
4267
4743
  programId ?? getStakeProgramId()
4268
4744
  );
4269
4745
  }
4270
4746
  function deriveStakeVaultAuth(pool, programId) {
4271
- return PublicKey10.findProgramAddressSync(
4272
- [TEXT.encode("vault_auth"), pool.toBytes()],
4747
+ return PublicKey11.findProgramAddressSync(
4748
+ [TEXT2.encode("vault_auth"), pool.toBytes()],
4273
4749
  programId ?? getStakeProgramId()
4274
4750
  );
4275
4751
  }
4276
4752
  function deriveDepositPda(pool, user, programId) {
4277
- return PublicKey10.findProgramAddressSync(
4278
- [TEXT.encode("stake_deposit"), pool.toBytes(), user.toBytes()],
4753
+ return PublicKey11.findProgramAddressSync(
4754
+ [TEXT2.encode("stake_deposit"), pool.toBytes(), user.toBytes()],
4279
4755
  programId ?? getStakeProgramId()
4280
4756
  );
4281
4757
  }
@@ -4425,15 +4901,15 @@ function decodeStakePool(data) {
4425
4901
  const adminTransferred = bytes[off] === 1;
4426
4902
  off += 1;
4427
4903
  off += 4;
4428
- const slab = new PublicKey10(bytes.subarray(off, off + 32));
4904
+ const slab = new PublicKey11(bytes.subarray(off, off + 32));
4429
4905
  off += 32;
4430
- const admin = new PublicKey10(bytes.subarray(off, off + 32));
4906
+ const admin = new PublicKey11(bytes.subarray(off, off + 32));
4431
4907
  off += 32;
4432
- const collateralMint = new PublicKey10(bytes.subarray(off, off + 32));
4908
+ const collateralMint = new PublicKey11(bytes.subarray(off, off + 32));
4433
4909
  off += 32;
4434
- const lpMint = new PublicKey10(bytes.subarray(off, off + 32));
4910
+ const lpMint = new PublicKey11(bytes.subarray(off, off + 32));
4435
4911
  off += 32;
4436
- const vault = new PublicKey10(bytes.subarray(off, off + 32));
4912
+ const vault = new PublicKey11(bytes.subarray(off, off + 32));
4437
4913
  off += 32;
4438
4914
  const totalDeposited = readU64LE4(bytes, off);
4439
4915
  off += 8;
@@ -4449,7 +4925,7 @@ function decodeStakePool(data) {
4449
4925
  off += 8;
4450
4926
  const totalWithdrawn = readU64LE4(bytes, off);
4451
4927
  off += 8;
4452
- const percolatorProgram = new PublicKey10(bytes.subarray(off, off + 32));
4928
+ const percolatorProgram = new PublicKey11(bytes.subarray(off, off + 32));
4453
4929
  off += 32;
4454
4930
  const totalFeesEarned = readU64LE4(bytes, off);
4455
4931
  off += 8;
@@ -4501,6 +4977,20 @@ function decodeStakePool(data) {
4501
4977
  juniorFeeMultBps
4502
4978
  };
4503
4979
  }
4980
+ var STAKE_DEPOSIT_SIZE = 152;
4981
+ function decodeDepositPda(data) {
4982
+ if (data.length < STAKE_DEPOSIT_SIZE) {
4983
+ throw new Error(`StakeDeposit data too short: ${data.length} < ${STAKE_DEPOSIT_SIZE}`);
4984
+ }
4985
+ return {
4986
+ isInitialized: data[0] === 1,
4987
+ bump: data[1],
4988
+ pool: new PublicKey11(data.subarray(8, 40)),
4989
+ user: new PublicKey11(data.subarray(40, 72)),
4990
+ lastDepositSlot: readU64LE4(data, 72),
4991
+ lpAmount: readU64LE4(data, 80)
4992
+ };
4993
+ }
4504
4994
  function initPoolAccounts(a) {
4505
4995
  return [
4506
4996
  { pubkey: a.admin, isSigner: true, isWritable: true },
@@ -5229,8 +5719,8 @@ function formatResult(result, jsonMode) {
5229
5719
  }
5230
5720
 
5231
5721
  // src/runtime/lighthouse.ts
5232
- import { PublicKey as PublicKey13, Transaction as Transaction2 } from "@solana/web3.js";
5233
- var LIGHTHOUSE_PROGRAM_ID = new PublicKey13(
5722
+ import { PublicKey as PublicKey14, Transaction as Transaction2 } from "@solana/web3.js";
5723
+ var LIGHTHOUSE_PROGRAM_ID = new PublicKey14(
5234
5724
  "L2TExMFKdjpN9kozasaurPirfHy9P8sbXoAN1qA3S95"
5235
5725
  );
5236
5726
  var LIGHTHOUSE_PROGRAM_ID_STR = "L2TExMFKdjpN9kozasaurPirfHy9P8sbXoAN1qA3S95";
@@ -5492,7 +5982,7 @@ function computeWarmupMaxPositionSize(initialMarginBps, totalCapital, currentSlo
5492
5982
  }
5493
5983
 
5494
5984
  // src/validation.ts
5495
- import { PublicKey as PublicKey14 } from "@solana/web3.js";
5985
+ import { PublicKey as PublicKey15 } from "@solana/web3.js";
5496
5986
  var U16_MAX2 = 65535;
5497
5987
  var U64_MAX = BigInt("18446744073709551615");
5498
5988
  var I64_MIN = BigInt("-9223372036854775808");
@@ -5522,7 +6012,7 @@ var ValidationError = class extends Error {
5522
6012
  };
5523
6013
  function validatePublicKey(value, field) {
5524
6014
  try {
5525
- return new PublicKey14(value);
6015
+ return new PublicKey15(value);
5526
6016
  } catch {
5527
6017
  throw new ValidationError(
5528
6018
  field,
@@ -5901,6 +6391,9 @@ export {
5901
6391
  ACCOUNTS_LIQUIDATE_AT_ORACLE,
5902
6392
  ACCOUNTS_LP_VAULT_WITHDRAW,
5903
6393
  ACCOUNTS_MINT_POSITION_NFT,
6394
+ ACCOUNTS_NFT_BURN,
6395
+ ACCOUNTS_NFT_EMERGENCY_BURN,
6396
+ ACCOUNTS_NFT_MINT,
5904
6397
  ACCOUNTS_PAUSE_MARKET,
5905
6398
  ACCOUNTS_PUSH_ORACLE_PRICE,
5906
6399
  ACCOUNTS_QUEUE_WITHDRAWAL,
@@ -5940,11 +6433,14 @@ export {
5940
6433
  LIGHTHOUSE_PROGRAM_ID,
5941
6434
  LIGHTHOUSE_PROGRAM_ID_STR,
5942
6435
  LIGHTHOUSE_USER_MESSAGE,
6436
+ LiquidationPolicyTag,
5943
6437
  MARK_PRICE_EMA_ALPHA_E6,
5944
6438
  MARK_PRICE_EMA_WINDOW_SLOTS,
5945
6439
  MAX_DECIMALS,
5946
6440
  MAX_ORACLE_PRICE,
5947
6441
  METEORA_DLMM_PROGRAM_ID,
6442
+ NFT_IX_TAG,
6443
+ NFT_PROGRAM_ID,
5948
6444
  ORACLE_PHASE_GROWING,
5949
6445
  ORACLE_PHASE_MATURE,
5950
6446
  ORACLE_PHASE_NASCENT,
@@ -5953,6 +6449,7 @@ export {
5953
6449
  PHASE1_VOLUME_MIN_SLOTS,
5954
6450
  PHASE2_MATURITY_SLOTS,
5955
6451
  PHASE2_VOLUME_THRESHOLD,
6452
+ POSITION_NFT_STATE_LEN,
5956
6453
  PROGRAM_IDS,
5957
6454
  PUMPSWAP_PROGRAM_ID,
5958
6455
  PYTH_PUSH_ORACLE_PROGRAM_ID,
@@ -5962,11 +6459,13 @@ export {
5962
6459
  RAYDIUM_CLMM_PROGRAM_ID,
5963
6460
  RENOUNCE_ADMIN_CONFIRMATION,
5964
6461
  RpcPool,
6462
+ SLAB_MAGIC,
5965
6463
  SLAB_TIERS,
5966
6464
  SLAB_TIERS_V0,
5967
6465
  SLAB_TIERS_V1,
5968
6466
  SLAB_TIERS_V12_1,
5969
6467
  SLAB_TIERS_V12_15,
6468
+ SLAB_TIERS_V12_17,
5970
6469
  SLAB_TIERS_V1D,
5971
6470
  SLAB_TIERS_V1D_LEGACY,
5972
6471
  SLAB_TIERS_V1M,
@@ -5975,6 +6474,7 @@ export {
5975
6474
  SLAB_TIERS_V_ADL,
5976
6475
  SLAB_TIERS_V_ADL_DISCOVERY,
5977
6476
  SLAB_TIERS_V_SETDEXPOOL,
6477
+ STAKE_DEPOSIT_SIZE,
5978
6478
  STAKE_IX,
5979
6479
  STAKE_POOL_SIZE,
5980
6480
  STAKE_PROGRAM_ID,
@@ -6014,6 +6514,7 @@ export {
6014
6514
  computeWarmupUnlockedCapital,
6015
6515
  concatBytes,
6016
6516
  countLighthouseInstructions,
6517
+ decodeDepositPda,
6017
6518
  decodeError,
6018
6519
  decodeStakePool,
6019
6520
  depositAccounts,
@@ -6021,6 +6522,9 @@ export {
6021
6522
  deriveDepositPda,
6022
6523
  deriveInsuranceLpMint,
6023
6524
  deriveLpPda,
6525
+ deriveMintAuthority,
6526
+ deriveNftMint,
6527
+ deriveNftPda,
6024
6528
  derivePythPriceUpdateAccount,
6025
6529
  derivePythPushOraclePDA,
6026
6530
  deriveStakePool,
@@ -6077,6 +6581,10 @@ export {
6077
6581
  encodeLpVaultDeposit,
6078
6582
  encodeLpVaultWithdraw,
6079
6583
  encodeMintPositionNft,
6584
+ encodeNftBurn,
6585
+ encodeNftEmergencyBurn,
6586
+ encodeNftMint,
6587
+ encodeNftSettleFunding,
6080
6588
  encodePauseMarket,
6081
6589
  encodePushOraclePrice,
6082
6590
  encodeQueueWithdrawal,
@@ -6124,6 +6632,7 @@ export {
6124
6632
  encodeTransferOwnershipCpi,
6125
6633
  encodeTransferPositionOwnership,
6126
6634
  encodeUnpauseMarket,
6635
+ encodeUnresolveMarket,
6127
6636
  encodeUpdateAdmin,
6128
6637
  encodeUpdateConfig,
6129
6638
  encodeUpdateHyperpMark,
@@ -6147,6 +6656,7 @@ export {
6147
6656
  getErrorName,
6148
6657
  getMarketsByAddress,
6149
6658
  getMatcherProgramId,
6659
+ getNftProgramId,
6150
6660
  getProgramId,
6151
6661
  getStakeProgramId,
6152
6662
  getStaticMarkets,
@@ -6170,6 +6680,7 @@ export {
6170
6680
  parseErrorFromLogs,
6171
6681
  parseHeader,
6172
6682
  parseParams,
6683
+ parsePositionNftAccount,
6173
6684
  parseUsedIndices,
6174
6685
  rankAdlPositions,
6175
6686
  readLastThrUpdateSlot,