@percolatorct/sdk 1.0.0-beta.13 → 1.0.0-beta.15
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.d.ts +3455 -7
- package/dist/index.js +305 -837
- package/dist/index.js.map +1 -1
- package/package.json +5 -11
- package/LICENSE +0 -201
- package/README.md +0 -754
- package/dist/abi/accounts.d.ts +0 -249
- package/dist/abi/encode.d.ts +0 -46
- package/dist/abi/errors.d.ts +0 -45
- package/dist/abi/index.d.ts +0 -4
- package/dist/abi/instructions.d.ts +0 -1111
- package/dist/config/program-ids.d.ts +0 -50
- package/dist/math/index.d.ts +0 -2
- package/dist/math/trading.d.ts +0 -222
- package/dist/math/warmup.d.ts +0 -105
- package/dist/oracle/price-router.d.ts +0 -38
- package/dist/runtime/index.d.ts +0 -2
- package/dist/runtime/lighthouse.d.ts +0 -170
- package/dist/runtime/tx.d.ts +0 -31
- package/dist/solana/adl.d.ts +0 -305
- package/dist/solana/ata.d.ts +0 -18
- package/dist/solana/dex-oracle.d.ts +0 -49
- package/dist/solana/discovery.d.ts +0 -492
- package/dist/solana/index.d.ts +0 -11
- package/dist/solana/oracle.d.ts +0 -52
- package/dist/solana/pda.d.ts +0 -49
- package/dist/solana/rpc-pool.d.ts +0 -347
- package/dist/solana/slab.d.ts +0 -358
- package/dist/solana/stake.d.ts +0 -216
- package/dist/solana/static-markets.d.ts +0 -86
- package/dist/solana/token-program.d.ts +0 -19
- package/dist/validation.d.ts +0 -70
package/dist/index.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
// src/abi/encode.ts
|
|
2
2
|
import { PublicKey } from "@solana/web3.js";
|
|
3
|
+
var U8_MAX = 255;
|
|
4
|
+
var U16_MAX = 65535;
|
|
5
|
+
var U32_MAX = 4294967295;
|
|
3
6
|
function encU8(val) {
|
|
4
|
-
if (!Number.isInteger(val) || val < 0 || val >
|
|
7
|
+
if (!Number.isInteger(val) || val < 0 || val > U8_MAX) {
|
|
5
8
|
throw new Error(`encU8: value out of range (0..255), got ${val}`);
|
|
6
9
|
}
|
|
7
10
|
return new Uint8Array([val]);
|
|
8
11
|
}
|
|
9
12
|
function encU16(val) {
|
|
10
|
-
if (!Number.isInteger(val) || val < 0 || val >
|
|
13
|
+
if (!Number.isInteger(val) || val < 0 || val > U16_MAX) {
|
|
11
14
|
throw new Error(`encU16: value out of range (0..65535), got ${val}`);
|
|
12
15
|
}
|
|
13
16
|
const buf = new Uint8Array(2);
|
|
@@ -15,7 +18,7 @@ function encU16(val) {
|
|
|
15
18
|
return buf;
|
|
16
19
|
}
|
|
17
20
|
function encU32(val) {
|
|
18
|
-
if (!Number.isInteger(val) || val < 0 || val >
|
|
21
|
+
if (!Number.isInteger(val) || val < 0 || val > U32_MAX) {
|
|
19
22
|
throw new Error(`encU32: value out of range (0..4294967295), got ${val}`);
|
|
20
23
|
}
|
|
21
24
|
const buf = new Uint8Array(4);
|
|
@@ -131,13 +134,8 @@ var IX_TAG = {
|
|
|
131
134
|
ReclaimEmptyAccount: 25,
|
|
132
135
|
SettleAccount: 26,
|
|
133
136
|
// Tags 27-28: on-chain = DepositFeeCredits/ConvertReleasedPnl.
|
|
134
|
-
// Legacy aliases (PauseMarket/UnpauseMarket) kept — those instructions don't exist on-chain.
|
|
135
137
|
DepositFeeCredits: 27,
|
|
136
|
-
/** @deprecated No on-chain PauseMarket instruction */
|
|
137
|
-
PauseMarket: 27,
|
|
138
138
|
ConvertReleasedPnl: 28,
|
|
139
|
-
/** @deprecated No on-chain UnpauseMarket instruction */
|
|
140
|
-
UnpauseMarket: 28,
|
|
141
139
|
// Tags 29-30: on-chain = ResolvePermissionless/ForceCloseResolved.
|
|
142
140
|
ResolvePermissionless: 29,
|
|
143
141
|
/** @deprecated Use ResolvePermissionless */
|
|
@@ -225,7 +223,13 @@ var IX_TAG = {
|
|
|
225
223
|
/** PERC-SetDexPool: Pin admin-approved DEX pool address for a HYPERP market (admin). */
|
|
226
224
|
SetDexPool: 74,
|
|
227
225
|
/** CPI to the matcher program to initialize a matcher context account for an LP slot. Admin-only. */
|
|
228
|
-
InitMatcherCtx: 75
|
|
226
|
+
InitMatcherCtx: 75,
|
|
227
|
+
/** PauseMarket (tag 76): admin emergency pause. Blocks Trade/Deposit/Withdraw/InitUser. */
|
|
228
|
+
PauseMarket: 76,
|
|
229
|
+
/** UnpauseMarket (tag 77): admin unpause. Re-enables all operations. */
|
|
230
|
+
UnpauseMarket: 77,
|
|
231
|
+
/** CloseKeeperFund (tag 78): close keeper fund PDA and recover lamports to admin. */
|
|
232
|
+
CloseKeeperFund: 78
|
|
229
233
|
};
|
|
230
234
|
Object.freeze(IX_TAG);
|
|
231
235
|
var HEX_RE = /^[0-9a-fA-F]{64}$/;
|
|
@@ -264,19 +268,23 @@ function encodeInitMarket(args) {
|
|
|
264
268
|
encU128(args.maxMaintenanceFeePerSlot ?? 0n),
|
|
265
269
|
encU128(args.maxInsuranceFloor ?? 0n),
|
|
266
270
|
encU64(args.minOraclePriceCap ?? 0n),
|
|
267
|
-
// RiskParams
|
|
271
|
+
// RiskParams wire format — must match read_risk_params() in percolator.rs
|
|
272
|
+
// Note: insurance_floor occupies the old riskReductionThreshold slot,
|
|
273
|
+
// and liquidationBufferBps is read but discarded (kept for wire compat).
|
|
268
274
|
encU64(args.warmupPeriodSlots),
|
|
269
275
|
encU64(args.maintenanceMarginBps),
|
|
270
276
|
encU64(args.initialMarginBps),
|
|
271
277
|
encU64(args.tradingFeeBps),
|
|
272
278
|
encU64(args.maxAccounts),
|
|
273
279
|
encU128(args.newAccountFee),
|
|
274
|
-
encU128(args.
|
|
280
|
+
encU128(args.insuranceFloor ?? 0n),
|
|
281
|
+
// wire slot: old riskReductionThreshold → now insurance_floor
|
|
275
282
|
encU128(args.maintenanceFeePerSlot),
|
|
276
283
|
encU64(args.maxCrankStalenessSlots),
|
|
277
284
|
encU64(args.liquidationFeeBps),
|
|
278
285
|
encU128(args.liquidationFeeCap),
|
|
279
|
-
encU64(args.liquidationBufferBps),
|
|
286
|
+
encU64(args.liquidationBufferBps ?? 0n),
|
|
287
|
+
// wire slot: read and discarded by program
|
|
280
288
|
encU128(args.minLiquidationAbs),
|
|
281
289
|
encU128(args.minInitialDeposit),
|
|
282
290
|
encU128(args.minNonzeroMmReq),
|
|
@@ -480,12 +488,12 @@ function encodeSetPythOracle(args) {
|
|
|
480
488
|
}
|
|
481
489
|
var PYTH_RECEIVER_PROGRAM_ID = "rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ";
|
|
482
490
|
async function derivePythPriceUpdateAccount(feedId, shardId = 0) {
|
|
483
|
-
const { PublicKey:
|
|
491
|
+
const { PublicKey: PublicKey14 } = await import("@solana/web3.js");
|
|
484
492
|
const shardBuf = new Uint8Array(2);
|
|
485
493
|
new DataView(shardBuf.buffer).setUint16(0, shardId, true);
|
|
486
|
-
const [pda] =
|
|
494
|
+
const [pda] = PublicKey14.findProgramAddressSync(
|
|
487
495
|
[shardBuf, feedId],
|
|
488
|
-
new
|
|
496
|
+
new PublicKey14(PYTH_RECEIVER_PROGRAM_ID)
|
|
489
497
|
);
|
|
490
498
|
return pda.toBase58();
|
|
491
499
|
}
|
|
@@ -720,6 +728,18 @@ function encodeCloseOrphanSlab() {
|
|
|
720
728
|
function encodeSetDexPool(args) {
|
|
721
729
|
return concatBytes(encU8(IX_TAG.SetDexPool), encPubkey(args.pool));
|
|
722
730
|
}
|
|
731
|
+
function encodeCloseKeeperFund() {
|
|
732
|
+
return concatBytes(encU8(IX_TAG.CloseKeeperFund));
|
|
733
|
+
}
|
|
734
|
+
function encodeCreateInsuranceMint() {
|
|
735
|
+
return encodeCreateLpVault({ feeShareBps: 0n });
|
|
736
|
+
}
|
|
737
|
+
function encodeDepositInsuranceLP(args) {
|
|
738
|
+
return encodeLpVaultDeposit({ amount: args.amount });
|
|
739
|
+
}
|
|
740
|
+
function encodeWithdrawInsuranceLP(args) {
|
|
741
|
+
return encodeLpVaultWithdraw({ lpAmount: args.lpAmount });
|
|
742
|
+
}
|
|
723
743
|
|
|
724
744
|
// src/abi/accounts.ts
|
|
725
745
|
import {
|
|
@@ -744,7 +764,8 @@ var ACCOUNTS_INIT_USER = [
|
|
|
744
764
|
{ name: "slab", signer: false, writable: true },
|
|
745
765
|
{ name: "userAta", signer: false, writable: true },
|
|
746
766
|
{ name: "vault", signer: false, writable: true },
|
|
747
|
-
{ name: "tokenProgram", signer: false, writable: false }
|
|
767
|
+
{ name: "tokenProgram", signer: false, writable: false },
|
|
768
|
+
{ name: "clock", signer: false, writable: false }
|
|
748
769
|
];
|
|
749
770
|
var ACCOUNTS_INIT_LP = [
|
|
750
771
|
{ name: "user", signer: true, writable: true },
|
|
@@ -811,6 +832,7 @@ var ACCOUNTS_TRADE_CPI = [
|
|
|
811
832
|
{ name: "lpOwner", signer: false, writable: false },
|
|
812
833
|
// LP delegated to matcher - no signature needed
|
|
813
834
|
{ name: "slab", signer: false, writable: true },
|
|
835
|
+
{ name: "clock", signer: false, writable: false },
|
|
814
836
|
{ name: "oracle", signer: false, writable: false },
|
|
815
837
|
{ name: "matcherProg", signer: false, writable: false },
|
|
816
838
|
{ name: "matcherCtx", signer: false, writable: true },
|
|
@@ -894,6 +916,37 @@ function buildAccountMetas(spec, keys) {
|
|
|
894
916
|
isWritable: s.writable
|
|
895
917
|
}));
|
|
896
918
|
}
|
|
919
|
+
var ACCOUNTS_CREATE_INSURANCE_MINT = [
|
|
920
|
+
{ name: "admin", signer: true, writable: false },
|
|
921
|
+
{ name: "slab", signer: false, writable: false },
|
|
922
|
+
{ name: "insLpMint", signer: false, writable: true },
|
|
923
|
+
{ name: "vaultAuthority", signer: false, writable: false },
|
|
924
|
+
{ name: "collateralMint", signer: false, writable: false },
|
|
925
|
+
{ name: "systemProgram", signer: false, writable: false },
|
|
926
|
+
{ name: "tokenProgram", signer: false, writable: false },
|
|
927
|
+
{ name: "rent", signer: false, writable: false },
|
|
928
|
+
{ name: "payer", signer: true, writable: true }
|
|
929
|
+
];
|
|
930
|
+
var ACCOUNTS_DEPOSIT_INSURANCE_LP = [
|
|
931
|
+
{ name: "depositor", signer: true, writable: false },
|
|
932
|
+
{ name: "slab", signer: false, writable: true },
|
|
933
|
+
{ name: "depositorAta", signer: false, writable: true },
|
|
934
|
+
{ name: "vault", signer: false, writable: true },
|
|
935
|
+
{ name: "tokenProgram", signer: false, writable: false },
|
|
936
|
+
{ name: "insLpMint", signer: false, writable: true },
|
|
937
|
+
{ name: "depositorLpAta", signer: false, writable: true },
|
|
938
|
+
{ name: "vaultAuthority", signer: false, writable: false }
|
|
939
|
+
];
|
|
940
|
+
var ACCOUNTS_WITHDRAW_INSURANCE_LP = [
|
|
941
|
+
{ name: "withdrawer", signer: true, writable: false },
|
|
942
|
+
{ name: "slab", signer: false, writable: true },
|
|
943
|
+
{ name: "withdrawerAta", signer: false, writable: true },
|
|
944
|
+
{ name: "vault", signer: false, writable: true },
|
|
945
|
+
{ name: "tokenProgram", signer: false, writable: false },
|
|
946
|
+
{ name: "insLpMint", signer: false, writable: true },
|
|
947
|
+
{ name: "withdrawerLpAta", signer: false, writable: true },
|
|
948
|
+
{ name: "vaultAuthority", signer: false, writable: false }
|
|
949
|
+
];
|
|
897
950
|
var ACCOUNTS_LP_VAULT_WITHDRAW = [
|
|
898
951
|
{ name: "withdrawer", signer: true, writable: false },
|
|
899
952
|
{ name: "slab", signer: false, writable: true },
|
|
@@ -964,7 +1017,8 @@ var ACCOUNTS_ADVANCE_ORACLE_PHASE = [
|
|
|
964
1017
|
var ACCOUNTS_TOPUP_KEEPER_FUND = [
|
|
965
1018
|
{ name: "funder", signer: true, writable: true },
|
|
966
1019
|
{ name: "slab", signer: false, writable: true },
|
|
967
|
-
{ name: "keeperFund", signer: false, writable: true }
|
|
1020
|
+
{ name: "keeperFund", signer: false, writable: true },
|
|
1021
|
+
{ name: "systemProgram", signer: false, writable: false }
|
|
968
1022
|
];
|
|
969
1023
|
var ACCOUNTS_SET_OI_IMBALANCE_HARD_BLOCK = [
|
|
970
1024
|
{ name: "admin", signer: true, writable: false },
|
|
@@ -1015,6 +1069,11 @@ var ACCOUNTS_SET_WALLET_CAP = [
|
|
|
1015
1069
|
{ name: "admin", signer: true, writable: false },
|
|
1016
1070
|
{ name: "slab", signer: false, writable: true }
|
|
1017
1071
|
];
|
|
1072
|
+
var ACCOUNTS_SET_DEX_POOL = [
|
|
1073
|
+
{ name: "admin", signer: true, writable: false },
|
|
1074
|
+
{ name: "slab", signer: false, writable: true },
|
|
1075
|
+
{ name: "poolAccount", signer: false, writable: false }
|
|
1076
|
+
];
|
|
1018
1077
|
var ACCOUNTS_INIT_MATCHER_CTX = [
|
|
1019
1078
|
{ name: "admin", signer: true, writable: false },
|
|
1020
1079
|
{ name: "slab", signer: false, writable: false },
|
|
@@ -1306,24 +1365,11 @@ function getErrorName(code) {
|
|
|
1306
1365
|
function getErrorHint(code) {
|
|
1307
1366
|
return PERCOLATOR_ERRORS[code]?.hint;
|
|
1308
1367
|
}
|
|
1309
|
-
var LIGHTHOUSE_PROGRAM_ID_STR = "L2TExMFKdjpN9kozasaurPirfHy9P8sbXoAN1qA3S95";
|
|
1310
|
-
var ANCHOR_ERROR_RANGE_START = 6e3;
|
|
1311
|
-
var ANCHOR_ERROR_RANGE_END = 8191;
|
|
1312
|
-
var ANCHOR_ERROR_NAMES = {
|
|
1313
|
-
6032: "ConstraintMut",
|
|
1314
|
-
6036: "ConstraintOwner",
|
|
1315
|
-
6038: "ConstraintSeeds",
|
|
1316
|
-
6400: "ConstraintAddress"
|
|
1317
|
-
};
|
|
1318
|
-
function isAnchorErrorCode(code) {
|
|
1319
|
-
return code >= ANCHOR_ERROR_RANGE_START && code <= ANCHOR_ERROR_RANGE_END;
|
|
1320
|
-
}
|
|
1321
1368
|
var CUSTOM_ERROR_HEX_MAX_LEN = 8;
|
|
1322
1369
|
function parseErrorFromLogs(logs) {
|
|
1323
1370
|
if (!Array.isArray(logs)) {
|
|
1324
1371
|
return null;
|
|
1325
1372
|
}
|
|
1326
|
-
let insideLighthouse = false;
|
|
1327
1373
|
const re = new RegExp(
|
|
1328
1374
|
`custom program error: 0x([0-9a-fA-F]{1,${CUSTOM_ERROR_HEX_MAX_LEN}})(?![0-9a-fA-F])`,
|
|
1329
1375
|
"i"
|
|
@@ -1332,32 +1378,17 @@ function parseErrorFromLogs(logs) {
|
|
|
1332
1378
|
if (typeof log !== "string") {
|
|
1333
1379
|
continue;
|
|
1334
1380
|
}
|
|
1335
|
-
if (log.includes(`Program ${LIGHTHOUSE_PROGRAM_ID_STR} invoke`)) {
|
|
1336
|
-
insideLighthouse = true;
|
|
1337
|
-
} else if (log.includes(`Program ${LIGHTHOUSE_PROGRAM_ID_STR} success`)) {
|
|
1338
|
-
insideLighthouse = false;
|
|
1339
|
-
}
|
|
1340
1381
|
const match = log.match(re);
|
|
1341
1382
|
if (match) {
|
|
1342
1383
|
const code = parseInt(match[1], 16);
|
|
1343
1384
|
if (!Number.isFinite(code) || code < 0 || code > 4294967295) {
|
|
1344
1385
|
continue;
|
|
1345
1386
|
}
|
|
1346
|
-
if (isAnchorErrorCode(code) || insideLighthouse) {
|
|
1347
|
-
const anchorName = ANCHOR_ERROR_NAMES[code] ?? `AnchorError(0x${code.toString(16)})`;
|
|
1348
|
-
return {
|
|
1349
|
-
code,
|
|
1350
|
-
name: `Lighthouse:${anchorName}`,
|
|
1351
|
-
hint: "This error comes from the Lighthouse/Blowfish wallet guard, not from Percolator. The transaction itself is valid. Disable transaction simulation in your wallet settings, or use a wallet without Blowfish protection (e.g., Backpack, Solflare).",
|
|
1352
|
-
source: "lighthouse"
|
|
1353
|
-
};
|
|
1354
|
-
}
|
|
1355
1387
|
const info = decodeError(code);
|
|
1356
1388
|
return {
|
|
1357
1389
|
code,
|
|
1358
1390
|
name: info?.name ?? `Unknown(${code})`,
|
|
1359
|
-
hint: info?.hint
|
|
1360
|
-
source: info ? "percolator" : "unknown"
|
|
1391
|
+
hint: info?.hint
|
|
1361
1392
|
};
|
|
1362
1393
|
}
|
|
1363
1394
|
}
|
|
@@ -1588,6 +1619,10 @@ var V12_1_SBF_OFF_LAST_SWEEP_COMPLETE = 312;
|
|
|
1588
1619
|
var V12_1_SBF_OFF_CRANK_CURSOR = 320;
|
|
1589
1620
|
var V12_1_SBF_OFF_SWEEP_START_IDX = 322;
|
|
1590
1621
|
var V12_1_SBF_OFF_LIFETIME_LIQUIDATIONS = 328;
|
|
1622
|
+
var V12_1_SBF_OFF_TOTAL_OI = 448;
|
|
1623
|
+
var V12_1_SBF_OFF_LONG_OI = 464;
|
|
1624
|
+
var V12_1_SBF_OFF_SHORT_OI = 480;
|
|
1625
|
+
var V12_1_SBF_OFF_MARK_PRICE_E6 = 560;
|
|
1591
1626
|
var V12_1_ENGINE_CURRENT_SLOT_OFF = 448;
|
|
1592
1627
|
var V12_1_ENGINE_FUNDING_RATE_BPS_OFF = 456;
|
|
1593
1628
|
var V12_1_ENGINE_LAST_CRANK_SLOT_OFF = 464;
|
|
@@ -1622,7 +1657,13 @@ var V12_1_ACCT_FEE_CREDITS_OFF = 240;
|
|
|
1622
1657
|
var V12_1_ACCT_LAST_FEE_SLOT_OFF = 256;
|
|
1623
1658
|
var V12_1_ACCT_POSITION_SIZE_OFF = 88;
|
|
1624
1659
|
var V12_1_ACCT_ENTRY_PRICE_OFF = -1;
|
|
1625
|
-
var
|
|
1660
|
+
var V12_1_EP_SBF_ACCOUNT_SIZE = 288;
|
|
1661
|
+
var V12_1_EP_ACCT_ENTRY_PRICE_OFF = 144;
|
|
1662
|
+
var V12_1_EP_ACCT_MATCHER_PROGRAM_OFF = 152;
|
|
1663
|
+
var V12_1_EP_ACCT_MATCHER_CONTEXT_OFF = 184;
|
|
1664
|
+
var V12_1_EP_ACCT_OWNER_OFF = 216;
|
|
1665
|
+
var V12_1_EP_ACCT_FEE_CREDITS_OFF = 248;
|
|
1666
|
+
var V12_1_EP_ACCT_LAST_FEE_SLOT_OFF = 264;
|
|
1626
1667
|
var V1M_ENGINE_OFF = 640;
|
|
1627
1668
|
var V1M_CONFIG_LEN = 536;
|
|
1628
1669
|
var V1M_ACCOUNT_SIZE = 248;
|
|
@@ -1706,6 +1747,14 @@ for (const [, n] of [["Micro", 64], ["Small", 256], ["Medium", 1024], ["Large",
|
|
|
1706
1747
|
const total = V12_1_SBF_ENGINE_OFF + accountsOff + n * V12_1_SBF_ACCOUNT_SIZE;
|
|
1707
1748
|
V12_1_SIZES.set(total, n);
|
|
1708
1749
|
}
|
|
1750
|
+
var V12_1_EP_SIZES = /* @__PURE__ */ new Map();
|
|
1751
|
+
for (const [, n] of [["Micro", 64], ["Small", 256], ["Medium", 1024], ["Large", 4096]]) {
|
|
1752
|
+
const bitmapBytes = Math.ceil(n / 64) * 8;
|
|
1753
|
+
const preAccLen = V12_1_SBF_BITMAP_OFF + bitmapBytes + 18 + n * 2;
|
|
1754
|
+
const accountsOff = Math.ceil(preAccLen / 8) * 8;
|
|
1755
|
+
const total = V12_1_SBF_ENGINE_OFF + accountsOff + n * V12_1_EP_SBF_ACCOUNT_SIZE;
|
|
1756
|
+
V12_1_EP_SIZES.set(total, n);
|
|
1757
|
+
}
|
|
1709
1758
|
var SLAB_TIERS_V2 = {
|
|
1710
1759
|
small: { maxAccounts: 256, dataSize: 65088, label: "Small", description: "256 slots (V2 BPF intermediate)" },
|
|
1711
1760
|
large: { maxAccounts: 4096, dataSize: 1025568, label: "Large", description: "4,096 slots (V2 BPF intermediate)" }
|
|
@@ -2266,16 +2315,12 @@ function buildLayoutV12_1(maxAccounts, dataLen) {
|
|
|
2266
2315
|
engineLastFundingSlotOff: isSbf ? -1 : V12_1_ENGINE_LAST_FUNDING_SLOT_OFF,
|
|
2267
2316
|
// not in deployed struct
|
|
2268
2317
|
engineFundingRateBpsOff: isSbf ? V12_1_SBF_OFF_FUNDING_RATE : V12_1_ENGINE_FUNDING_RATE_BPS_OFF,
|
|
2269
|
-
engineMarkPriceOff: isSbf ?
|
|
2270
|
-
// not in deployed struct
|
|
2318
|
+
engineMarkPriceOff: isSbf ? V12_1_SBF_OFF_MARK_PRICE_E6 : V12_1_ENGINE_MARK_PRICE_OFF,
|
|
2271
2319
|
engineLastCrankSlotOff: isSbf ? V12_1_SBF_OFF_LAST_CRANK_SLOT : V12_1_ENGINE_LAST_CRANK_SLOT_OFF,
|
|
2272
2320
|
engineMaxCrankStalenessOff: isSbf ? V12_1_SBF_OFF_MAX_CRANK_STALENESS : V12_1_ENGINE_MAX_CRANK_STALENESS_OFF,
|
|
2273
|
-
engineTotalOiOff: isSbf ?
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
// not in deployed struct
|
|
2277
|
-
engineShortOiOff: isSbf ? -1 : V12_1_ENGINE_SHORT_OI_OFF,
|
|
2278
|
-
// not in deployed struct
|
|
2321
|
+
engineTotalOiOff: isSbf ? V12_1_SBF_OFF_TOTAL_OI : V12_1_ENGINE_TOTAL_OI_OFF,
|
|
2322
|
+
engineLongOiOff: isSbf ? V12_1_SBF_OFF_LONG_OI : V12_1_ENGINE_LONG_OI_OFF,
|
|
2323
|
+
engineShortOiOff: isSbf ? V12_1_SBF_OFF_SHORT_OI : V12_1_ENGINE_SHORT_OI_OFF,
|
|
2279
2324
|
engineCTotOff: isSbf ? V12_1_SBF_OFF_C_TOT : V12_1_ENGINE_C_TOT_OFF,
|
|
2280
2325
|
enginePnlPosTotOff: isSbf ? V12_1_SBF_OFF_PNL_POS_TOT : V12_1_ENGINE_PNL_POS_TOT_OFF,
|
|
2281
2326
|
engineLiqCursorOff: isSbf ? V12_1_SBF_OFF_LIQ_CURSOR : V12_1_ENGINE_LIQ_CURSOR_OFF,
|
|
@@ -2311,7 +2356,74 @@ function buildLayoutV12_1(maxAccounts, dataLen) {
|
|
|
2311
2356
|
engineInsuranceIsolationBpsOff: isSbf ? -1 : 64
|
|
2312
2357
|
};
|
|
2313
2358
|
}
|
|
2359
|
+
function buildLayoutV12_1EP(maxAccounts) {
|
|
2360
|
+
const engineOff = V12_1_SBF_ENGINE_OFF;
|
|
2361
|
+
const bitmapOff = V12_1_SBF_BITMAP_OFF;
|
|
2362
|
+
const accountSize = V12_1_EP_SBF_ACCOUNT_SIZE;
|
|
2363
|
+
const bitmapWords = Math.ceil(maxAccounts / 64);
|
|
2364
|
+
const bitmapBytes = bitmapWords * 8;
|
|
2365
|
+
const postBitmap = 18;
|
|
2366
|
+
const nextFreeBytes = maxAccounts * 2;
|
|
2367
|
+
const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;
|
|
2368
|
+
const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;
|
|
2369
|
+
return {
|
|
2370
|
+
version: 1,
|
|
2371
|
+
headerLen: 72,
|
|
2372
|
+
configOffset: 72,
|
|
2373
|
+
configLen: 544,
|
|
2374
|
+
reservedOff: 80,
|
|
2375
|
+
// V1_RESERVED_OFF
|
|
2376
|
+
engineOff,
|
|
2377
|
+
accountSize,
|
|
2378
|
+
maxAccounts,
|
|
2379
|
+
bitmapWords,
|
|
2380
|
+
accountsOff: engineOff + accountsOffRel,
|
|
2381
|
+
engineInsuranceOff: 16,
|
|
2382
|
+
engineParamsOff: 32,
|
|
2383
|
+
// V12_1_ENGINE_PARAMS_OFF_SBF
|
|
2384
|
+
paramsSize: 184,
|
|
2385
|
+
// V12_1_PARAMS_SIZE_SBF
|
|
2386
|
+
// Engine offsets identical to V12_1 SBF
|
|
2387
|
+
engineCurrentSlotOff: V12_1_SBF_OFF_CURRENT_SLOT,
|
|
2388
|
+
engineFundingIndexOff: -1,
|
|
2389
|
+
engineLastFundingSlotOff: -1,
|
|
2390
|
+
engineFundingRateBpsOff: V12_1_SBF_OFF_FUNDING_RATE,
|
|
2391
|
+
engineMarkPriceOff: V12_1_SBF_OFF_MARK_PRICE_E6,
|
|
2392
|
+
engineLastCrankSlotOff: V12_1_SBF_OFF_LAST_CRANK_SLOT,
|
|
2393
|
+
engineMaxCrankStalenessOff: V12_1_SBF_OFF_MAX_CRANK_STALENESS,
|
|
2394
|
+
engineTotalOiOff: V12_1_SBF_OFF_TOTAL_OI,
|
|
2395
|
+
engineLongOiOff: V12_1_SBF_OFF_LONG_OI,
|
|
2396
|
+
engineShortOiOff: V12_1_SBF_OFF_SHORT_OI,
|
|
2397
|
+
engineCTotOff: V12_1_SBF_OFF_C_TOT,
|
|
2398
|
+
enginePnlPosTotOff: V12_1_SBF_OFF_PNL_POS_TOT,
|
|
2399
|
+
engineLiqCursorOff: V12_1_SBF_OFF_LIQ_CURSOR,
|
|
2400
|
+
engineGcCursorOff: V12_1_SBF_OFF_GC_CURSOR,
|
|
2401
|
+
engineLastSweepStartOff: V12_1_SBF_OFF_LAST_SWEEP_START,
|
|
2402
|
+
engineLastSweepCompleteOff: V12_1_SBF_OFF_LAST_SWEEP_COMPLETE,
|
|
2403
|
+
engineCrankCursorOff: V12_1_SBF_OFF_CRANK_CURSOR,
|
|
2404
|
+
engineSweepStartIdxOff: V12_1_SBF_OFF_SWEEP_START_IDX,
|
|
2405
|
+
engineLifetimeLiquidationsOff: V12_1_SBF_OFF_LIFETIME_LIQUIDATIONS,
|
|
2406
|
+
engineLifetimeForceClosesOff: -1,
|
|
2407
|
+
engineNetLpPosOff: -1,
|
|
2408
|
+
engineLpSumAbsOff: -1,
|
|
2409
|
+
engineLpMaxAbsOff: -1,
|
|
2410
|
+
engineLpMaxAbsSweepOff: -1,
|
|
2411
|
+
engineEmergencyOiModeOff: -1,
|
|
2412
|
+
engineEmergencyStartSlotOff: -1,
|
|
2413
|
+
engineLastBreakerSlotOff: -1,
|
|
2414
|
+
engineBitmapOff: bitmapOff,
|
|
2415
|
+
postBitmap: 18,
|
|
2416
|
+
// Account offsets — shifted +8 from V12_1 due to entry_price insertion
|
|
2417
|
+
acctOwnerOff: V12_1_EP_ACCT_OWNER_OFF,
|
|
2418
|
+
// 216 (was 208)
|
|
2419
|
+
hasInsuranceIsolation: false,
|
|
2420
|
+
engineInsuranceIsolatedOff: -1,
|
|
2421
|
+
engineInsuranceIsolationBpsOff: -1
|
|
2422
|
+
};
|
|
2423
|
+
}
|
|
2314
2424
|
function detectSlabLayout(dataLen, data) {
|
|
2425
|
+
const v121epn = V12_1_EP_SIZES.get(dataLen);
|
|
2426
|
+
if (v121epn !== void 0) return buildLayoutV12_1EP(v121epn);
|
|
2315
2427
|
const v121n = V12_1_SIZES.get(dataLen);
|
|
2316
2428
|
if (v121n !== void 0) return buildLayoutV12_1(v121n, dataLen);
|
|
2317
2429
|
const vsdpn = V_SETDEXPOOL_SIZES.get(dataLen);
|
|
@@ -2358,6 +2470,15 @@ var PARAMS_LIQUIDATION_FEE_BPS_OFF = 96;
|
|
|
2358
2470
|
var PARAMS_LIQUIDATION_FEE_CAP_OFF = 104;
|
|
2359
2471
|
var PARAMS_LIQUIDATION_BUFFER_OFF = 120;
|
|
2360
2472
|
var PARAMS_MIN_LIQUIDATION_OFF = 128;
|
|
2473
|
+
var V12_1_PARAMS_MAINT_FEE_OFF = 56;
|
|
2474
|
+
var V12_1_PARAMS_MAX_CRANK_OFF = 72;
|
|
2475
|
+
var V12_1_PARAMS_LIQ_FEE_BPS_OFF = 80;
|
|
2476
|
+
var V12_1_PARAMS_LIQ_FEE_CAP_OFF = 88;
|
|
2477
|
+
var V12_1_PARAMS_MIN_LIQ_OFF = 104;
|
|
2478
|
+
var V12_1_PARAMS_MIN_INITIAL_DEP_OFF = 120;
|
|
2479
|
+
var V12_1_PARAMS_MIN_NZ_MM_OFF = 136;
|
|
2480
|
+
var V12_1_PARAMS_MIN_NZ_IM_OFF = 152;
|
|
2481
|
+
var V12_1_PARAMS_INS_FLOOR_OFF = 168;
|
|
2361
2482
|
var ACCT_ACCOUNT_ID_OFF = 0;
|
|
2362
2483
|
var ACCT_CAPITAL_OFF = 8;
|
|
2363
2484
|
var ACCT_KIND_OFF = 24;
|
|
@@ -2607,6 +2728,7 @@ function parseParams(data, layoutHint) {
|
|
|
2607
2728
|
if (data.length < base + Math.min(paramsSize, 56)) {
|
|
2608
2729
|
throw new Error("Slab data too short for RiskParams");
|
|
2609
2730
|
}
|
|
2731
|
+
const isV12_1Sbf = layout !== null && layout !== void 0 && layout.engineOff === V12_1_SBF_ENGINE_OFF && paramsSize === 184;
|
|
2610
2732
|
const result = {
|
|
2611
2733
|
warmupPeriodSlots: readU64LE(data, base + PARAMS_WARMUP_PERIOD_OFF),
|
|
2612
2734
|
maintenanceMarginBps: readU64LE(data, base + PARAMS_MAINTENANCE_MARGIN_OFF),
|
|
@@ -2614,16 +2736,30 @@ function parseParams(data, layoutHint) {
|
|
|
2614
2736
|
tradingFeeBps: readU64LE(data, base + PARAMS_TRADING_FEE_OFF),
|
|
2615
2737
|
maxAccounts: readU64LE(data, base + PARAMS_MAX_ACCOUNTS_OFF),
|
|
2616
2738
|
newAccountFee: readU128LE(data, base + PARAMS_NEW_ACCOUNT_FEE_OFF),
|
|
2617
|
-
// Extended params:
|
|
2739
|
+
// Extended params: defaults; overwritten below if layout supports them
|
|
2618
2740
|
riskReductionThreshold: 0n,
|
|
2619
2741
|
maintenanceFeePerSlot: 0n,
|
|
2620
2742
|
maxCrankStalenessSlots: 0n,
|
|
2621
2743
|
liquidationFeeBps: 0n,
|
|
2622
2744
|
liquidationFeeCap: 0n,
|
|
2623
2745
|
liquidationBufferBps: 0n,
|
|
2624
|
-
minLiquidationAbs: 0n
|
|
2746
|
+
minLiquidationAbs: 0n,
|
|
2747
|
+
minInitialDeposit: 0n,
|
|
2748
|
+
minNonzeroMmReq: 0n,
|
|
2749
|
+
minNonzeroImReq: 0n,
|
|
2750
|
+
insuranceFloor: 0n
|
|
2625
2751
|
};
|
|
2626
|
-
if (
|
|
2752
|
+
if (isV12_1Sbf) {
|
|
2753
|
+
result.maintenanceFeePerSlot = readU128LE(data, base + V12_1_PARAMS_MAINT_FEE_OFF);
|
|
2754
|
+
result.maxCrankStalenessSlots = readU64LE(data, base + V12_1_PARAMS_MAX_CRANK_OFF);
|
|
2755
|
+
result.liquidationFeeBps = readU64LE(data, base + V12_1_PARAMS_LIQ_FEE_BPS_OFF);
|
|
2756
|
+
result.liquidationFeeCap = readU128LE(data, base + V12_1_PARAMS_LIQ_FEE_CAP_OFF);
|
|
2757
|
+
result.minLiquidationAbs = readU128LE(data, base + V12_1_PARAMS_MIN_LIQ_OFF);
|
|
2758
|
+
result.minInitialDeposit = readU128LE(data, base + V12_1_PARAMS_MIN_INITIAL_DEP_OFF);
|
|
2759
|
+
result.minNonzeroMmReq = readU128LE(data, base + V12_1_PARAMS_MIN_NZ_MM_OFF);
|
|
2760
|
+
result.minNonzeroImReq = readU128LE(data, base + V12_1_PARAMS_MIN_NZ_IM_OFF);
|
|
2761
|
+
result.insuranceFloor = readU128LE(data, base + V12_1_PARAMS_INS_FLOOR_OFF);
|
|
2762
|
+
} else if (paramsSize >= 144) {
|
|
2627
2763
|
result.riskReductionThreshold = readU128LE(data, base + PARAMS_RISK_THRESHOLD_OFF);
|
|
2628
2764
|
result.maintenanceFeePerSlot = readU128LE(data, base + PARAMS_MAINTENANCE_FEE_OFF);
|
|
2629
2765
|
result.maxCrankStalenessSlots = readU64LE(data, base + PARAMS_MAX_CRANK_STALENESS_OFF);
|
|
@@ -2736,17 +2872,18 @@ function parseAccount(data, idx) {
|
|
|
2736
2872
|
if (data.length < base + layout.accountSize) {
|
|
2737
2873
|
throw new Error("Slab data too short for account");
|
|
2738
2874
|
}
|
|
2739
|
-
const
|
|
2740
|
-
const
|
|
2875
|
+
const isV12_1EP = layout.accountSize === V12_1_EP_SBF_ACCOUNT_SIZE && layout.engineOff === V12_1_SBF_ENGINE_OFF;
|
|
2876
|
+
const isV12_1 = !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);
|
|
2877
|
+
const isAdl = layout.accountSize >= 312 || isV12_1 || isV12_1EP;
|
|
2741
2878
|
const warmupStartedOff = isAdl ? V_ADL_ACCT_WARMUP_STARTED_OFF : ACCT_WARMUP_STARTED_OFF;
|
|
2742
2879
|
const warmupSlopeOff = isAdl ? V_ADL_ACCT_WARMUP_SLOPE_OFF : ACCT_WARMUP_SLOPE_OFF;
|
|
2743
|
-
const positionSizeOff = isV12_1 ? V12_1_ACCT_POSITION_SIZE_OFF : isAdl ? V_ADL_ACCT_POSITION_SIZE_OFF : ACCT_POSITION_SIZE_OFF;
|
|
2744
|
-
const entryPriceOff = isV12_1 ? V12_1_ACCT_ENTRY_PRICE_OFF : isAdl ? V_ADL_ACCT_ENTRY_PRICE_OFF : ACCT_ENTRY_PRICE_OFF;
|
|
2745
|
-
const fundingIndexOff = isV12_1 ?
|
|
2746
|
-
const matcherProgOff = isV12_1 ? V12_1_ACCT_MATCHER_PROGRAM_OFF : isAdl ? V_ADL_ACCT_MATCHER_PROGRAM_OFF : ACCT_MATCHER_PROGRAM_OFF;
|
|
2747
|
-
const matcherCtxOff = isV12_1 ? V12_1_ACCT_MATCHER_CONTEXT_OFF : isAdl ? V_ADL_ACCT_MATCHER_CONTEXT_OFF : ACCT_MATCHER_CONTEXT_OFF;
|
|
2748
|
-
const feeCreditsOff = isV12_1 ? V12_1_ACCT_FEE_CREDITS_OFF : isAdl ? V_ADL_ACCT_FEE_CREDITS_OFF : ACCT_FEE_CREDITS_OFF;
|
|
2749
|
-
const lastFeeSlotOff = isV12_1 ? V12_1_ACCT_LAST_FEE_SLOT_OFF : isAdl ? V_ADL_ACCT_LAST_FEE_SLOT_OFF : ACCT_LAST_FEE_SLOT_OFF;
|
|
2880
|
+
const positionSizeOff = isV12_1 || isV12_1EP ? V12_1_ACCT_POSITION_SIZE_OFF : isAdl ? V_ADL_ACCT_POSITION_SIZE_OFF : ACCT_POSITION_SIZE_OFF;
|
|
2881
|
+
const entryPriceOff = isV12_1EP ? V12_1_EP_ACCT_ENTRY_PRICE_OFF : isV12_1 ? V12_1_ACCT_ENTRY_PRICE_OFF : isAdl ? V_ADL_ACCT_ENTRY_PRICE_OFF : ACCT_ENTRY_PRICE_OFF;
|
|
2882
|
+
const fundingIndexOff = isV12_1 || isV12_1EP ? -1 : isAdl ? V_ADL_ACCT_FUNDING_INDEX_OFF : ACCT_FUNDING_INDEX_OFF;
|
|
2883
|
+
const matcherProgOff = isV12_1EP ? V12_1_EP_ACCT_MATCHER_PROGRAM_OFF : isV12_1 ? V12_1_ACCT_MATCHER_PROGRAM_OFF : isAdl ? V_ADL_ACCT_MATCHER_PROGRAM_OFF : ACCT_MATCHER_PROGRAM_OFF;
|
|
2884
|
+
const matcherCtxOff = isV12_1EP ? V12_1_EP_ACCT_MATCHER_CONTEXT_OFF : isV12_1 ? V12_1_ACCT_MATCHER_CONTEXT_OFF : isAdl ? V_ADL_ACCT_MATCHER_CONTEXT_OFF : ACCT_MATCHER_CONTEXT_OFF;
|
|
2885
|
+
const feeCreditsOff = isV12_1EP ? V12_1_EP_ACCT_FEE_CREDITS_OFF : isV12_1 ? V12_1_ACCT_FEE_CREDITS_OFF : isAdl ? V_ADL_ACCT_FEE_CREDITS_OFF : ACCT_FEE_CREDITS_OFF;
|
|
2886
|
+
const lastFeeSlotOff = isV12_1EP ? V12_1_EP_ACCT_LAST_FEE_SLOT_OFF : isV12_1 ? V12_1_ACCT_LAST_FEE_SLOT_OFF : isAdl ? V_ADL_ACCT_LAST_FEE_SLOT_OFF : ACCT_LAST_FEE_SLOT_OFF;
|
|
2750
2887
|
const kindByte = readU8(data, base + ACCT_KIND_OFF);
|
|
2751
2888
|
const kind = kindByte === 1 ? 1 /* LP */ : 0 /* User */;
|
|
2752
2889
|
return {
|
|
@@ -2759,9 +2896,8 @@ function parseAccount(data, idx) {
|
|
|
2759
2896
|
warmupSlopePerStep: readU128LE(data, base + warmupSlopeOff),
|
|
2760
2897
|
positionSize: readI128LE(data, base + positionSizeOff),
|
|
2761
2898
|
entryPrice: entryPriceOff >= 0 ? readU64LE(data, base + entryPriceOff) : 0n,
|
|
2762
|
-
// V12_1:
|
|
2763
|
-
|
|
2764
|
-
fundingIndex: isV12_1 ? BigInt(readI64LE(data, base + fundingIndexOff)) : readI128LE(data, base + fundingIndexOff),
|
|
2899
|
+
// V12_1/V12_1_EP: funding_index not present in SBF layout
|
|
2900
|
+
fundingIndex: isV12_1 || isV12_1EP ? fundingIndexOff >= 0 ? BigInt(readI64LE(data, base + fundingIndexOff)) : 0n : readI128LE(data, base + fundingIndexOff),
|
|
2765
2901
|
matcherProgram: new PublicKey3(data.subarray(base + matcherProgOff, base + matcherProgOff + 32)),
|
|
2766
2902
|
matcherContext: new PublicKey3(data.subarray(base + matcherCtxOff, base + matcherCtxOff + 32)),
|
|
2767
2903
|
owner: new PublicKey3(data.subarray(base + layout.acctOwnerOff, base + layout.acctOwnerOff + 32)),
|
|
@@ -2794,6 +2930,12 @@ function deriveVaultAuthority(programId, slab) {
|
|
|
2794
2930
|
programId
|
|
2795
2931
|
);
|
|
2796
2932
|
}
|
|
2933
|
+
function deriveInsuranceLpMint(programId, slab) {
|
|
2934
|
+
return PublicKey4.findProgramAddressSync(
|
|
2935
|
+
[textEncoder.encode("ins_lp"), slab.toBytes()],
|
|
2936
|
+
programId
|
|
2937
|
+
);
|
|
2938
|
+
}
|
|
2797
2939
|
var LP_INDEX_U16_MAX = 65535;
|
|
2798
2940
|
function deriveLpPda(programId, slab, lpIdx) {
|
|
2799
2941
|
if (typeof lpIdx !== "number" || !Number.isInteger(lpIdx) || lpIdx < 0 || lpIdx > LP_INDEX_U16_MAX) {
|
|
@@ -2850,14 +2992,7 @@ function derivePythPushOraclePDA(feedIdHex) {
|
|
|
2850
2992
|
}
|
|
2851
2993
|
const feedId = new Uint8Array(32);
|
|
2852
2994
|
for (let i = 0; i < 32; i++) {
|
|
2853
|
-
|
|
2854
|
-
const byte = parseInt(hexPair, 16);
|
|
2855
|
-
if (Number.isNaN(byte)) {
|
|
2856
|
-
throw new Error(
|
|
2857
|
-
`derivePythPushOraclePDA: failed to parse hex byte at position ${i}: "${hexPair}"`
|
|
2858
|
-
);
|
|
2859
|
-
}
|
|
2860
|
-
feedId[i] = byte;
|
|
2995
|
+
feedId[i] = parseInt(normalized.substring(i * 2, i * 2 + 2), 16);
|
|
2861
2996
|
}
|
|
2862
2997
|
const shardBuf = new Uint8Array(2);
|
|
2863
2998
|
return PublicKey4.findProgramAddressSync(
|
|
@@ -2889,9 +3024,7 @@ import { PublicKey as PublicKey6 } from "@solana/web3.js";
|
|
|
2889
3024
|
// src/solana/static-markets.ts
|
|
2890
3025
|
import { PublicKey as PublicKey5 } from "@solana/web3.js";
|
|
2891
3026
|
var MAINNET_MARKETS = [
|
|
2892
|
-
|
|
2893
|
-
// To add entries:
|
|
2894
|
-
// { slabAddress: "ABC123...", symbol: "SOL-PERP", name: "SOL Perpetual" },
|
|
3027
|
+
{ slabAddress: "7psyeWRts4pRX2cyAWD1NH87bR9ugXP7pe6ARgfG79Do", symbol: "SOL-PERP", name: "SOL/USDC Perpetual" }
|
|
2895
3028
|
];
|
|
2896
3029
|
var DEVNET_MARKETS = [
|
|
2897
3030
|
// Populated from prior discoverMarkets() runs on devnet.
|
|
@@ -3659,7 +3792,9 @@ function computeRaydiumClmmPriceE6(data) {
|
|
|
3659
3792
|
}
|
|
3660
3793
|
const sqrtPriceX64 = readU128LE3(dv3, 253);
|
|
3661
3794
|
if (sqrtPriceX64 === 0n) return 0n;
|
|
3662
|
-
const
|
|
3795
|
+
const scaledSqrt = sqrtPriceX64 * 1000000n;
|
|
3796
|
+
const term = scaledSqrt >> 64n;
|
|
3797
|
+
const priceE6Raw = term * sqrtPriceX64 >> 64n;
|
|
3663
3798
|
const decimalDiff = 6 + decimals0 - decimals1;
|
|
3664
3799
|
const adjustedDiff = decimalDiff - 6;
|
|
3665
3800
|
if (adjustedDiff >= 0) {
|
|
@@ -3700,26 +3835,13 @@ function computeMeteoraDlmmPriceE6(data) {
|
|
|
3700
3835
|
`Meteora DLMM: |activeId| ${Math.abs(activeId)} exceeds max ${MAX_ACTIVE_ID_ABS}`
|
|
3701
3836
|
);
|
|
3702
3837
|
}
|
|
3703
|
-
const MAX_ABS_BIN_ID = 5e5;
|
|
3704
|
-
if (activeId > MAX_ABS_BIN_ID || activeId < -MAX_ABS_BIN_ID) {
|
|
3705
|
-
throw new Error(
|
|
3706
|
-
`Meteora DLMM: activeId ${activeId} exceeds safe range (\xB1${MAX_ABS_BIN_ID})`
|
|
3707
|
-
);
|
|
3708
|
-
}
|
|
3709
3838
|
const SCALE = 1000000000000000000n;
|
|
3710
3839
|
const base = SCALE + BigInt(binStep) * SCALE / 10000n;
|
|
3711
3840
|
const isNeg = activeId < 0;
|
|
3712
3841
|
let exp = isNeg ? BigInt(-activeId) : BigInt(activeId);
|
|
3713
3842
|
let result = SCALE;
|
|
3714
3843
|
let b = base;
|
|
3715
|
-
let iterations = 0;
|
|
3716
|
-
const MAX_ITERATIONS = 25;
|
|
3717
3844
|
while (exp > 0n) {
|
|
3718
|
-
if (iterations++ >= MAX_ITERATIONS) {
|
|
3719
|
-
throw new Error(
|
|
3720
|
-
`Meteora DLMM: exponentiation loop exceeded ${MAX_ITERATIONS} iterations (activeId=${activeId})`
|
|
3721
|
-
);
|
|
3722
|
-
}
|
|
3723
3845
|
if (exp & 1n) {
|
|
3724
3846
|
result = result * b / SCALE;
|
|
3725
3847
|
}
|
|
@@ -3750,7 +3872,6 @@ function readU128LE3(dv3, offset) {
|
|
|
3750
3872
|
var CHAINLINK_MIN_SIZE = 224;
|
|
3751
3873
|
var MAX_DECIMALS = 18;
|
|
3752
3874
|
var CHAINLINK_DECIMALS_OFFSET = 138;
|
|
3753
|
-
var CHAINLINK_TIMESTAMP_OFFSET = 168;
|
|
3754
3875
|
var CHAINLINK_ANSWER_OFFSET = 216;
|
|
3755
3876
|
function readU82(data, off) {
|
|
3756
3877
|
return data[off];
|
|
@@ -3758,7 +3879,7 @@ function readU82(data, off) {
|
|
|
3758
3879
|
function readBigInt64LE(data, off) {
|
|
3759
3880
|
return new DataView(data.buffer, data.byteOffset, data.byteLength).getBigInt64(off, true);
|
|
3760
3881
|
}
|
|
3761
|
-
function parseChainlinkPrice(data
|
|
3882
|
+
function parseChainlinkPrice(data) {
|
|
3762
3883
|
if (data.length < CHAINLINK_MIN_SIZE) {
|
|
3763
3884
|
throw new Error(
|
|
3764
3885
|
`Oracle account data too small: ${data.length} bytes (need at least ${CHAINLINK_MIN_SIZE})`
|
|
@@ -3776,18 +3897,7 @@ function parseChainlinkPrice(data, options) {
|
|
|
3776
3897
|
`Oracle price is non-positive: ${price}`
|
|
3777
3898
|
);
|
|
3778
3899
|
}
|
|
3779
|
-
|
|
3780
|
-
const updatedAt = Number(updatedAtBig);
|
|
3781
|
-
if (options?.maxStalenessSeconds !== void 0 && updatedAt > 0) {
|
|
3782
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
3783
|
-
const age = now - updatedAt;
|
|
3784
|
-
if (age > options.maxStalenessSeconds) {
|
|
3785
|
-
throw new Error(
|
|
3786
|
-
`Oracle price is stale: last updated ${age}s ago (max ${options.maxStalenessSeconds}s)`
|
|
3787
|
-
);
|
|
3788
|
-
}
|
|
3789
|
-
}
|
|
3790
|
-
return { price, decimals, updatedAt: updatedAt > 0 ? updatedAt : void 0 };
|
|
3900
|
+
return { price, decimals };
|
|
3791
3901
|
}
|
|
3792
3902
|
function isValidChainlinkOracle(data) {
|
|
3793
3903
|
try {
|
|
@@ -3807,11 +3917,7 @@ var TOKEN_2022_PROGRAM_ID = new PublicKey8(
|
|
|
3807
3917
|
async function detectTokenProgram(connection, mint) {
|
|
3808
3918
|
const info = await connection.getAccountInfo(mint);
|
|
3809
3919
|
if (!info) throw new Error(`Mint account not found: ${mint.toBase58()}`);
|
|
3810
|
-
|
|
3811
|
-
if (info.owner.equals(TOKEN_2022_PROGRAM_ID)) return TOKEN_2022_PROGRAM_ID;
|
|
3812
|
-
throw new Error(
|
|
3813
|
-
`Mint ${mint.toBase58()} is owned by ${info.owner.toBase58()}, which is neither TOKEN_PROGRAM_ID nor TOKEN_2022_PROGRAM_ID`
|
|
3814
|
-
);
|
|
3920
|
+
return info.owner;
|
|
3815
3921
|
}
|
|
3816
3922
|
function isToken2022(tokenProgramId) {
|
|
3817
3923
|
return tokenProgramId.equals(TOKEN_2022_PROGRAM_ID);
|
|
@@ -3844,14 +3950,12 @@ var PROGRAM_IDS = {
|
|
|
3844
3950
|
}
|
|
3845
3951
|
};
|
|
3846
3952
|
function getProgramId(network) {
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
return new PublicKey9(override);
|
|
3854
|
-
}
|
|
3953
|
+
const override = safeEnv("PROGRAM_ID");
|
|
3954
|
+
if (override) {
|
|
3955
|
+
console.warn(
|
|
3956
|
+
`[percolator-sdk] PROGRAM_ID env override active: ${override} \u2014 ensure this points to a trusted program`
|
|
3957
|
+
);
|
|
3958
|
+
return new PublicKey9(override);
|
|
3855
3959
|
}
|
|
3856
3960
|
const detectedNetwork = getCurrentNetwork();
|
|
3857
3961
|
const targetNetwork = network ?? detectedNetwork;
|
|
@@ -3859,14 +3963,12 @@ function getProgramId(network) {
|
|
|
3859
3963
|
return new PublicKey9(programId);
|
|
3860
3964
|
}
|
|
3861
3965
|
function getMatcherProgramId(network) {
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
return new PublicKey9(override);
|
|
3869
|
-
}
|
|
3966
|
+
const override = safeEnv("MATCHER_PROGRAM_ID");
|
|
3967
|
+
if (override) {
|
|
3968
|
+
console.warn(
|
|
3969
|
+
`[percolator-sdk] MATCHER_PROGRAM_ID env override active: ${override} \u2014 ensure this points to a trusted program`
|
|
3970
|
+
);
|
|
3971
|
+
return new PublicKey9(override);
|
|
3870
3972
|
}
|
|
3871
3973
|
const detectedNetwork = getCurrentNetwork();
|
|
3872
3974
|
const targetNetwork = network ?? detectedNetwork;
|
|
@@ -3899,7 +4001,10 @@ function getStakeProgramId(network) {
|
|
|
3899
4001
|
}
|
|
3900
4002
|
const detectedNetwork = network ?? (() => {
|
|
3901
4003
|
const n = safeEnv("NEXT_PUBLIC_DEFAULT_NETWORK")?.toLowerCase() ?? safeEnv("NETWORK")?.toLowerCase() ?? "";
|
|
3902
|
-
|
|
4004
|
+
if (n === "mainnet" || n === "mainnet-beta") return "mainnet";
|
|
4005
|
+
if (n === "devnet") return "devnet";
|
|
4006
|
+
if (typeof window !== "undefined") return "mainnet";
|
|
4007
|
+
return "devnet";
|
|
3903
4008
|
})();
|
|
3904
4009
|
const id = STAKE_PROGRAM_IDS[detectedNetwork];
|
|
3905
4010
|
if (!id) {
|
|
@@ -3909,7 +4014,7 @@ function getStakeProgramId(network) {
|
|
|
3909
4014
|
}
|
|
3910
4015
|
return new PublicKey10(id);
|
|
3911
4016
|
}
|
|
3912
|
-
var STAKE_PROGRAM_ID = new PublicKey10(STAKE_PROGRAM_IDS.
|
|
4017
|
+
var STAKE_PROGRAM_ID = new PublicKey10(STAKE_PROGRAM_IDS.devnet);
|
|
3913
4018
|
var STAKE_IX = {
|
|
3914
4019
|
InitPool: 0,
|
|
3915
4020
|
Deposit: 1,
|
|
@@ -3970,9 +4075,6 @@ function readU16LE3(data, off) {
|
|
|
3970
4075
|
);
|
|
3971
4076
|
}
|
|
3972
4077
|
function u64Le(v) {
|
|
3973
|
-
if (typeof v === "number" && !Number.isSafeInteger(v)) {
|
|
3974
|
-
throw new Error(`u64Le: number ${v} exceeds Number.MAX_SAFE_INTEGER \u2014 use BigInt`);
|
|
3975
|
-
}
|
|
3976
4078
|
const big = BigInt(v);
|
|
3977
4079
|
if (big < 0n) throw new Error(`u64Le: value must be non-negative, got ${big}`);
|
|
3978
4080
|
if (big > 0xFFFFFFFFFFFFFFFFn) throw new Error(`u64Le: value exceeds u64 max`);
|
|
@@ -3981,9 +4083,6 @@ function u64Le(v) {
|
|
|
3981
4083
|
return arr;
|
|
3982
4084
|
}
|
|
3983
4085
|
function u128Le(v) {
|
|
3984
|
-
if (typeof v === "number" && !Number.isSafeInteger(v)) {
|
|
3985
|
-
throw new Error(`u128Le: number ${v} exceeds Number.MAX_SAFE_INTEGER \u2014 use BigInt`);
|
|
3986
|
-
}
|
|
3987
4086
|
const big = BigInt(v);
|
|
3988
4087
|
if (big < 0n) throw new Error(`u128Le: value must be non-negative, got ${big}`);
|
|
3989
4088
|
if (big > (1n << 128n) - 1n) throw new Error(`u128Le: value exceeds u128 max`);
|
|
@@ -3994,7 +4093,7 @@ function u128Le(v) {
|
|
|
3994
4093
|
return arr;
|
|
3995
4094
|
}
|
|
3996
4095
|
function u16Le(v) {
|
|
3997
|
-
if (
|
|
4096
|
+
if (v < 0 || v > 65535) throw new Error(`u16Le: value out of u16 range (0..65535), got ${v}`);
|
|
3998
4097
|
const arr = new Uint8Array(2);
|
|
3999
4098
|
new DataView(arr.buffer).setUint16(0, v, true);
|
|
4000
4099
|
return arr;
|
|
@@ -4249,9 +4348,7 @@ function computePnlPct(pnl, capital) {
|
|
|
4249
4348
|
}
|
|
4250
4349
|
function isAdlTriggered(slabData) {
|
|
4251
4350
|
const layout = detectSlabLayout(slabData.length);
|
|
4252
|
-
if (!layout)
|
|
4253
|
-
return false;
|
|
4254
|
-
}
|
|
4351
|
+
if (!layout) return false;
|
|
4255
4352
|
try {
|
|
4256
4353
|
const engine = parseEngine(slabData);
|
|
4257
4354
|
if (engine.pnlPosTot === 0n) return false;
|
|
@@ -4294,14 +4391,6 @@ function rankAdlPositions(slabData) {
|
|
|
4294
4391
|
if (account.kind !== 0 /* User */) continue;
|
|
4295
4392
|
if (account.positionSize === 0n) continue;
|
|
4296
4393
|
const side = account.positionSize > 0n ? "long" : "short";
|
|
4297
|
-
if (side === "long" && account.positionSize <= 0n) {
|
|
4298
|
-
console.warn(`[fetchAdlRankedPositions] account idx=${idx}: side=long but positionSize=${account.positionSize}`);
|
|
4299
|
-
continue;
|
|
4300
|
-
}
|
|
4301
|
-
if (side === "short" && account.positionSize >= 0n) {
|
|
4302
|
-
console.warn(`[fetchAdlRankedPositions] account idx=${idx}: side=short but positionSize=${account.positionSize}`);
|
|
4303
|
-
continue;
|
|
4304
|
-
}
|
|
4305
4394
|
const pnlPct = computePnlPct(account.pnl, account.capital);
|
|
4306
4395
|
positions.push({
|
|
4307
4396
|
idx,
|
|
@@ -4334,8 +4423,7 @@ function buildAdlInstruction(caller, slab, oracle, programId, targetIdx, backupO
|
|
|
4334
4423
|
`buildAdlInstruction: targetIdx must be a non-negative integer, got ${targetIdx}`
|
|
4335
4424
|
);
|
|
4336
4425
|
}
|
|
4337
|
-
const
|
|
4338
|
-
const data = Buffer.from(dataBytes);
|
|
4426
|
+
const data = Buffer.from(encodeExecuteAdl({ targetIdx }));
|
|
4339
4427
|
const keys = [
|
|
4340
4428
|
{ pubkey: caller, isSigner: true, isWritable: false },
|
|
4341
4429
|
{ pubkey: slab, isSigner: false, isWritable: true },
|
|
@@ -4375,11 +4463,7 @@ function parseAdlEvent(logs) {
|
|
|
4375
4463
|
}
|
|
4376
4464
|
if (tag !== ADL_EVENT_TAG) continue;
|
|
4377
4465
|
try {
|
|
4378
|
-
const
|
|
4379
|
-
if (targetIdxBig < 0n || targetIdxBig > 65535n) {
|
|
4380
|
-
continue;
|
|
4381
|
-
}
|
|
4382
|
-
const targetIdx = Number(targetIdxBig);
|
|
4466
|
+
const targetIdx = Number(BigInt(match[2]));
|
|
4383
4467
|
const price = BigInt(match[3]);
|
|
4384
4468
|
const closedLo = BigInt(match[4]);
|
|
4385
4469
|
const closedHi = BigInt(match[5]);
|
|
@@ -4407,387 +4491,9 @@ async function fetchAdlRankings(apiBase, slab, fetchFn = fetch) {
|
|
|
4407
4491
|
);
|
|
4408
4492
|
}
|
|
4409
4493
|
const json = await res.json();
|
|
4410
|
-
if (typeof json !== "object" || json === null) {
|
|
4411
|
-
throw new Error("fetchAdlRankings: API returned non-object response");
|
|
4412
|
-
}
|
|
4413
|
-
const obj = json;
|
|
4414
|
-
if (!Array.isArray(obj.rankings)) {
|
|
4415
|
-
throw new Error("fetchAdlRankings: API response missing rankings array");
|
|
4416
|
-
}
|
|
4417
|
-
for (const entry of obj.rankings) {
|
|
4418
|
-
if (typeof entry !== "object" || entry === null) {
|
|
4419
|
-
throw new Error("fetchAdlRankings: invalid ranking entry (not an object)");
|
|
4420
|
-
}
|
|
4421
|
-
const r = entry;
|
|
4422
|
-
if (typeof r.idx !== "number" || !Number.isInteger(r.idx) || r.idx < 0) {
|
|
4423
|
-
throw new Error(`fetchAdlRankings: invalid ranking idx: ${r.idx}`);
|
|
4424
|
-
}
|
|
4425
|
-
}
|
|
4426
4494
|
return json;
|
|
4427
4495
|
}
|
|
4428
4496
|
|
|
4429
|
-
// src/solana/rpc-pool.ts
|
|
4430
|
-
import {
|
|
4431
|
-
Connection as Connection5
|
|
4432
|
-
} from "@solana/web3.js";
|
|
4433
|
-
async function checkRpcHealth(endpoint, timeoutMs = 5e3) {
|
|
4434
|
-
const conn = new Connection5(endpoint, { commitment: "processed" });
|
|
4435
|
-
const start = performance.now();
|
|
4436
|
-
const timeout = rejectAfter(timeoutMs, `Health probe timed out after ${timeoutMs}ms`);
|
|
4437
|
-
try {
|
|
4438
|
-
const slot = await Promise.race([
|
|
4439
|
-
conn.getSlot("processed"),
|
|
4440
|
-
timeout.promise
|
|
4441
|
-
]);
|
|
4442
|
-
const latencyMs = Math.round(performance.now() - start);
|
|
4443
|
-
return { endpoint, healthy: true, latencyMs, slot };
|
|
4444
|
-
} catch (err) {
|
|
4445
|
-
const latencyMs = Math.round(performance.now() - start);
|
|
4446
|
-
return {
|
|
4447
|
-
endpoint,
|
|
4448
|
-
healthy: false,
|
|
4449
|
-
latencyMs,
|
|
4450
|
-
slot: 0,
|
|
4451
|
-
error: err instanceof Error ? err.message : String(err)
|
|
4452
|
-
};
|
|
4453
|
-
} finally {
|
|
4454
|
-
timeout.cancel();
|
|
4455
|
-
}
|
|
4456
|
-
}
|
|
4457
|
-
function resolveRetryConfig(cfg) {
|
|
4458
|
-
if (cfg === false) return null;
|
|
4459
|
-
const c = cfg ?? {};
|
|
4460
|
-
return {
|
|
4461
|
-
maxRetries: c.maxRetries ?? 3,
|
|
4462
|
-
baseDelayMs: c.baseDelayMs ?? 500,
|
|
4463
|
-
maxDelayMs: c.maxDelayMs ?? 1e4,
|
|
4464
|
-
jitterFactor: Math.max(0, Math.min(1, c.jitterFactor ?? 0.25)),
|
|
4465
|
-
retryableStatusCodes: c.retryableStatusCodes ?? [429, 502, 503, 504]
|
|
4466
|
-
};
|
|
4467
|
-
}
|
|
4468
|
-
function normalizeEndpoint(ep) {
|
|
4469
|
-
if (typeof ep === "string") return { url: ep };
|
|
4470
|
-
return ep;
|
|
4471
|
-
}
|
|
4472
|
-
function endpointLabel(ep) {
|
|
4473
|
-
if (ep.label) return ep.label;
|
|
4474
|
-
try {
|
|
4475
|
-
return new URL(ep.url).hostname;
|
|
4476
|
-
} catch {
|
|
4477
|
-
return ep.url.slice(0, 40);
|
|
4478
|
-
}
|
|
4479
|
-
}
|
|
4480
|
-
function isRetryable(err, codes) {
|
|
4481
|
-
if (!err) return false;
|
|
4482
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
4483
|
-
for (const code of codes) {
|
|
4484
|
-
if (msg.includes(String(code))) return true;
|
|
4485
|
-
}
|
|
4486
|
-
if (msg.toLowerCase().includes("rate limit") || msg.toLowerCase().includes("too many requests") || msg.toLowerCase().includes("econnreset") || msg.toLowerCase().includes("econnrefused") || msg.toLowerCase().includes("socket hang up") || msg.toLowerCase().includes("network") || msg.toLowerCase().includes("timeout") || msg.toLowerCase().includes("abort")) {
|
|
4487
|
-
return true;
|
|
4488
|
-
}
|
|
4489
|
-
return false;
|
|
4490
|
-
}
|
|
4491
|
-
function computeDelay(attempt, config) {
|
|
4492
|
-
const raw = Math.min(
|
|
4493
|
-
config.baseDelayMs * Math.pow(2, attempt),
|
|
4494
|
-
config.maxDelayMs
|
|
4495
|
-
);
|
|
4496
|
-
const jitter = Math.floor(Math.random() * raw * config.jitterFactor);
|
|
4497
|
-
return raw + jitter;
|
|
4498
|
-
}
|
|
4499
|
-
function rejectAfter(ms, message) {
|
|
4500
|
-
let timer;
|
|
4501
|
-
const promise = new Promise((_, reject) => {
|
|
4502
|
-
timer = setTimeout(() => reject(new Error(message)), ms);
|
|
4503
|
-
});
|
|
4504
|
-
return { promise, cancel: () => clearTimeout(timer) };
|
|
4505
|
-
}
|
|
4506
|
-
function sleep(ms) {
|
|
4507
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
4508
|
-
}
|
|
4509
|
-
function redactUrl(raw) {
|
|
4510
|
-
try {
|
|
4511
|
-
const u = new URL(raw);
|
|
4512
|
-
const sensitive = /^(api[-_]?key|access[-_]?token|auth[-_]?token|token|secret|key|password|bearer|credential|jwt)$/i;
|
|
4513
|
-
for (const k of [...u.searchParams.keys()]) {
|
|
4514
|
-
if (sensitive.test(k)) {
|
|
4515
|
-
u.searchParams.set(k, "***");
|
|
4516
|
-
}
|
|
4517
|
-
}
|
|
4518
|
-
return u.toString();
|
|
4519
|
-
} catch {
|
|
4520
|
-
return raw;
|
|
4521
|
-
}
|
|
4522
|
-
}
|
|
4523
|
-
var RpcPool = class _RpcPool {
|
|
4524
|
-
endpoints;
|
|
4525
|
-
strategy;
|
|
4526
|
-
retryConfig;
|
|
4527
|
-
requestTimeoutMs;
|
|
4528
|
-
verbose;
|
|
4529
|
-
/** Round-robin index tracker. */
|
|
4530
|
-
rrIndex = 0;
|
|
4531
|
-
/** Consecutive failure threshold before marking an endpoint unhealthy. */
|
|
4532
|
-
static UNHEALTHY_THRESHOLD = 3;
|
|
4533
|
-
/** Minimum endpoints before auto-recovery is attempted. */
|
|
4534
|
-
static MIN_HEALTHY = 1;
|
|
4535
|
-
constructor(config) {
|
|
4536
|
-
if (!config.endpoints || config.endpoints.length === 0) {
|
|
4537
|
-
throw new Error("RpcPool: at least one endpoint is required");
|
|
4538
|
-
}
|
|
4539
|
-
this.strategy = config.strategy ?? "failover";
|
|
4540
|
-
this.retryConfig = resolveRetryConfig(config.retry);
|
|
4541
|
-
this.requestTimeoutMs = config.requestTimeoutMs ?? 3e4;
|
|
4542
|
-
this.verbose = config.verbose ?? true;
|
|
4543
|
-
const commitment = config.commitment ?? "confirmed";
|
|
4544
|
-
this.endpoints = config.endpoints.map((raw) => {
|
|
4545
|
-
const ep = normalizeEndpoint(raw);
|
|
4546
|
-
const connConfig = {
|
|
4547
|
-
commitment,
|
|
4548
|
-
...ep.connectionConfig
|
|
4549
|
-
};
|
|
4550
|
-
return {
|
|
4551
|
-
config: ep,
|
|
4552
|
-
connection: new Connection5(ep.url, connConfig),
|
|
4553
|
-
label: endpointLabel(ep),
|
|
4554
|
-
weight: Math.max(1, ep.weight ?? 1),
|
|
4555
|
-
failures: 0,
|
|
4556
|
-
healthy: true,
|
|
4557
|
-
lastLatencyMs: -1
|
|
4558
|
-
};
|
|
4559
|
-
});
|
|
4560
|
-
}
|
|
4561
|
-
// -----------------------------------------------------------------------
|
|
4562
|
-
// Public API
|
|
4563
|
-
// -----------------------------------------------------------------------
|
|
4564
|
-
/**
|
|
4565
|
-
* Execute a function against a pooled connection with automatic retry
|
|
4566
|
-
* and failover.
|
|
4567
|
-
*
|
|
4568
|
-
* @param fn - Async function that receives a `Connection` and returns a result.
|
|
4569
|
-
* @returns The result of `fn`.
|
|
4570
|
-
* @throws The last error if all retries and failovers are exhausted.
|
|
4571
|
-
*
|
|
4572
|
-
* @example
|
|
4573
|
-
* ```ts
|
|
4574
|
-
* const balance = await pool.call(c => c.getBalance(pubkey));
|
|
4575
|
-
* const markets = await pool.call(c => discoverMarkets(c, programId, opts));
|
|
4576
|
-
* ```
|
|
4577
|
-
*/
|
|
4578
|
-
async call(fn) {
|
|
4579
|
-
const maxAttempts = this.retryConfig ? this.retryConfig.maxRetries + 1 : 1;
|
|
4580
|
-
let lastError;
|
|
4581
|
-
const triedEndpoints = /* @__PURE__ */ new Set();
|
|
4582
|
-
const maxTotalIterations = maxAttempts + this.endpoints.length;
|
|
4583
|
-
let totalIterations = 0;
|
|
4584
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
4585
|
-
if (++totalIterations > maxTotalIterations) break;
|
|
4586
|
-
const epIdx = this.selectEndpoint(triedEndpoints);
|
|
4587
|
-
if (epIdx === -1) {
|
|
4588
|
-
break;
|
|
4589
|
-
}
|
|
4590
|
-
const ep = this.endpoints[epIdx];
|
|
4591
|
-
const timeout = rejectAfter(this.requestTimeoutMs, `RPC request timed out after ${this.requestTimeoutMs}ms (${ep.label})`);
|
|
4592
|
-
try {
|
|
4593
|
-
const result = await Promise.race([
|
|
4594
|
-
fn(ep.connection),
|
|
4595
|
-
timeout.promise
|
|
4596
|
-
]);
|
|
4597
|
-
timeout.cancel();
|
|
4598
|
-
ep.failures = 0;
|
|
4599
|
-
ep.healthy = true;
|
|
4600
|
-
return result;
|
|
4601
|
-
} catch (err) {
|
|
4602
|
-
timeout.cancel();
|
|
4603
|
-
lastError = err;
|
|
4604
|
-
ep.failures++;
|
|
4605
|
-
if (ep.failures >= _RpcPool.UNHEALTHY_THRESHOLD) {
|
|
4606
|
-
ep.healthy = false;
|
|
4607
|
-
if (this.verbose) {
|
|
4608
|
-
console.warn(
|
|
4609
|
-
`[RpcPool] Endpoint ${ep.label} marked unhealthy after ${ep.failures} consecutive failures`
|
|
4610
|
-
);
|
|
4611
|
-
}
|
|
4612
|
-
}
|
|
4613
|
-
const retryable = this.retryConfig ? isRetryable(err, this.retryConfig.retryableStatusCodes) : false;
|
|
4614
|
-
if (!retryable) {
|
|
4615
|
-
if (this.strategy === "failover" && this.endpoints.length > 1) {
|
|
4616
|
-
triedEndpoints.add(epIdx);
|
|
4617
|
-
attempt--;
|
|
4618
|
-
if (triedEndpoints.size >= this.endpoints.length) break;
|
|
4619
|
-
continue;
|
|
4620
|
-
}
|
|
4621
|
-
throw err;
|
|
4622
|
-
}
|
|
4623
|
-
if (this.verbose) {
|
|
4624
|
-
console.warn(
|
|
4625
|
-
`[RpcPool] Retryable error on ${ep.label} (attempt ${attempt + 1}/${maxAttempts}):`,
|
|
4626
|
-
err instanceof Error ? err.message : err
|
|
4627
|
-
);
|
|
4628
|
-
}
|
|
4629
|
-
if (this.strategy === "failover" && this.endpoints.length > 1) {
|
|
4630
|
-
triedEndpoints.add(epIdx);
|
|
4631
|
-
}
|
|
4632
|
-
if (attempt < maxAttempts - 1 && this.retryConfig) {
|
|
4633
|
-
const delay = computeDelay(attempt, this.retryConfig);
|
|
4634
|
-
await sleep(delay);
|
|
4635
|
-
}
|
|
4636
|
-
}
|
|
4637
|
-
}
|
|
4638
|
-
this.maybeRecoverEndpoints();
|
|
4639
|
-
throw lastError ?? new Error("RpcPool: all endpoints exhausted");
|
|
4640
|
-
}
|
|
4641
|
-
/**
|
|
4642
|
-
* Get a raw `Connection` from the current preferred endpoint.
|
|
4643
|
-
* Useful when you need to pass a Connection to external code.
|
|
4644
|
-
*
|
|
4645
|
-
* NOTE: This bypasses retry and failover logic. Prefer `call()`.
|
|
4646
|
-
*
|
|
4647
|
-
* @returns Solana Connection from the current preferred endpoint.
|
|
4648
|
-
*
|
|
4649
|
-
* @example
|
|
4650
|
-
* ```ts
|
|
4651
|
-
* const conn = pool.getConnection();
|
|
4652
|
-
* const balance = await conn.getBalance(pubkey);
|
|
4653
|
-
* ```
|
|
4654
|
-
*/
|
|
4655
|
-
getConnection() {
|
|
4656
|
-
const idx = this.selectEndpoint();
|
|
4657
|
-
if (idx === -1) {
|
|
4658
|
-
this.maybeRecoverEndpoints();
|
|
4659
|
-
return this.endpoints[0].connection;
|
|
4660
|
-
}
|
|
4661
|
-
return this.endpoints[idx].connection;
|
|
4662
|
-
}
|
|
4663
|
-
/**
|
|
4664
|
-
* Run a health check against all endpoints in the pool.
|
|
4665
|
-
*
|
|
4666
|
-
* @param timeoutMs - Per-endpoint probe timeout (default: 5000)
|
|
4667
|
-
* @returns Array of health results, one per endpoint.
|
|
4668
|
-
*
|
|
4669
|
-
* @example
|
|
4670
|
-
* ```ts
|
|
4671
|
-
* const results = await pool.healthCheck();
|
|
4672
|
-
* for (const r of results) {
|
|
4673
|
-
* console.log(`${r.endpoint}: ${r.healthy ? 'UP' : 'DOWN'} (${r.latencyMs}ms, slot ${r.slot})`);
|
|
4674
|
-
* }
|
|
4675
|
-
* ```
|
|
4676
|
-
*/
|
|
4677
|
-
async healthCheck(timeoutMs = 5e3) {
|
|
4678
|
-
const results = await Promise.all(
|
|
4679
|
-
this.endpoints.map(async (ep) => {
|
|
4680
|
-
const result = await checkRpcHealth(ep.config.url, timeoutMs);
|
|
4681
|
-
ep.lastLatencyMs = result.latencyMs;
|
|
4682
|
-
ep.healthy = result.healthy;
|
|
4683
|
-
if (result.healthy) ep.failures = 0;
|
|
4684
|
-
result.endpoint = redactUrl(result.endpoint);
|
|
4685
|
-
return result;
|
|
4686
|
-
})
|
|
4687
|
-
);
|
|
4688
|
-
return results;
|
|
4689
|
-
}
|
|
4690
|
-
/**
|
|
4691
|
-
* Get the number of endpoints in the pool.
|
|
4692
|
-
*/
|
|
4693
|
-
get size() {
|
|
4694
|
-
return this.endpoints.length;
|
|
4695
|
-
}
|
|
4696
|
-
/**
|
|
4697
|
-
* Get the number of currently healthy endpoints.
|
|
4698
|
-
*/
|
|
4699
|
-
get healthyCount() {
|
|
4700
|
-
return this.endpoints.filter((ep) => ep.healthy).length;
|
|
4701
|
-
}
|
|
4702
|
-
/**
|
|
4703
|
-
* Get endpoint labels and their current status.
|
|
4704
|
-
*
|
|
4705
|
-
* @returns Array of `{ label, url, healthy, failures, lastLatencyMs }`.
|
|
4706
|
-
*/
|
|
4707
|
-
status() {
|
|
4708
|
-
return this.endpoints.map((ep) => ({
|
|
4709
|
-
label: ep.label,
|
|
4710
|
-
url: redactUrl(ep.config.url),
|
|
4711
|
-
healthy: ep.healthy,
|
|
4712
|
-
failures: ep.failures,
|
|
4713
|
-
lastLatencyMs: ep.lastLatencyMs
|
|
4714
|
-
}));
|
|
4715
|
-
}
|
|
4716
|
-
// -----------------------------------------------------------------------
|
|
4717
|
-
// Internals
|
|
4718
|
-
// -----------------------------------------------------------------------
|
|
4719
|
-
/**
|
|
4720
|
-
* Select the next endpoint based on strategy.
|
|
4721
|
-
* Returns -1 if no endpoint is available.
|
|
4722
|
-
*/
|
|
4723
|
-
selectEndpoint(exclude) {
|
|
4724
|
-
const healthy = this.endpoints.map((ep, i) => ({ ep, i })).filter(({ ep, i }) => ep.healthy && !exclude?.has(i));
|
|
4725
|
-
if (healthy.length === 0) {
|
|
4726
|
-
const remaining = this.endpoints.map((_, i) => i).filter((i) => !exclude?.has(i));
|
|
4727
|
-
return remaining.length > 0 ? remaining[0] : -1;
|
|
4728
|
-
}
|
|
4729
|
-
if (this.strategy === "failover") {
|
|
4730
|
-
return healthy[0].i;
|
|
4731
|
-
}
|
|
4732
|
-
const totalWeight = healthy.reduce((sum, { ep }) => sum + ep.weight, 0);
|
|
4733
|
-
this.rrIndex = (this.rrIndex + 1) % totalWeight;
|
|
4734
|
-
let cumulative = 0;
|
|
4735
|
-
for (const { ep, i } of healthy) {
|
|
4736
|
-
cumulative += ep.weight;
|
|
4737
|
-
if (this.rrIndex < cumulative) return i;
|
|
4738
|
-
}
|
|
4739
|
-
return healthy[healthy.length - 1].i;
|
|
4740
|
-
}
|
|
4741
|
-
/**
|
|
4742
|
-
* If all endpoints are unhealthy, reset them so we at least try again.
|
|
4743
|
-
*/
|
|
4744
|
-
maybeRecoverEndpoints() {
|
|
4745
|
-
const healthyCount = this.endpoints.filter((ep) => ep.healthy).length;
|
|
4746
|
-
if (healthyCount < _RpcPool.MIN_HEALTHY) {
|
|
4747
|
-
if (this.verbose) {
|
|
4748
|
-
console.warn("[RpcPool] All endpoints unhealthy \u2014 resetting for recovery");
|
|
4749
|
-
}
|
|
4750
|
-
for (const ep of this.endpoints) {
|
|
4751
|
-
ep.healthy = true;
|
|
4752
|
-
ep.failures = 0;
|
|
4753
|
-
}
|
|
4754
|
-
}
|
|
4755
|
-
}
|
|
4756
|
-
};
|
|
4757
|
-
async function withRetry(fn, config) {
|
|
4758
|
-
const resolved = resolveRetryConfig(config) ?? {
|
|
4759
|
-
maxRetries: 3,
|
|
4760
|
-
baseDelayMs: 500,
|
|
4761
|
-
maxDelayMs: 1e4,
|
|
4762
|
-
jitterFactor: 0.25,
|
|
4763
|
-
retryableStatusCodes: [429, 502, 503, 504]
|
|
4764
|
-
};
|
|
4765
|
-
let lastError;
|
|
4766
|
-
const maxAttempts = resolved.maxRetries + 1;
|
|
4767
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
4768
|
-
try {
|
|
4769
|
-
return await fn();
|
|
4770
|
-
} catch (err) {
|
|
4771
|
-
lastError = err;
|
|
4772
|
-
if (!isRetryable(err, resolved.retryableStatusCodes)) {
|
|
4773
|
-
throw err;
|
|
4774
|
-
}
|
|
4775
|
-
if (attempt < maxAttempts - 1) {
|
|
4776
|
-
const delay = computeDelay(attempt, resolved);
|
|
4777
|
-
await sleep(delay);
|
|
4778
|
-
}
|
|
4779
|
-
}
|
|
4780
|
-
}
|
|
4781
|
-
throw lastError ?? new Error("withRetry: all attempts exhausted");
|
|
4782
|
-
}
|
|
4783
|
-
var _internal = {
|
|
4784
|
-
isRetryable,
|
|
4785
|
-
computeDelay,
|
|
4786
|
-
resolveRetryConfig,
|
|
4787
|
-
normalizeEndpoint,
|
|
4788
|
-
endpointLabel
|
|
4789
|
-
};
|
|
4790
|
-
|
|
4791
4497
|
// src/runtime/tx.ts
|
|
4792
4498
|
import {
|
|
4793
4499
|
TransactionInstruction as TransactionInstruction2,
|
|
@@ -4939,139 +4645,6 @@ function formatResult(result, jsonMode) {
|
|
|
4939
4645
|
return lines.join("\n");
|
|
4940
4646
|
}
|
|
4941
4647
|
|
|
4942
|
-
// src/runtime/lighthouse.ts
|
|
4943
|
-
import { PublicKey as PublicKey13, Transaction as Transaction2 } from "@solana/web3.js";
|
|
4944
|
-
var LIGHTHOUSE_PROGRAM_ID = new PublicKey13(
|
|
4945
|
-
"L2TExMFKdjpN9kozasaurPirfHy9P8sbXoAN1qA3S95"
|
|
4946
|
-
);
|
|
4947
|
-
var LIGHTHOUSE_PROGRAM_ID_STR2 = "L2TExMFKdjpN9kozasaurPirfHy9P8sbXoAN1qA3S95";
|
|
4948
|
-
var LIGHTHOUSE_CONSTRAINT_ADDRESS = 6400;
|
|
4949
|
-
var LIGHTHOUSE_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
4950
|
-
6e3,
|
|
4951
|
-
// InstructionMissing
|
|
4952
|
-
6001,
|
|
4953
|
-
// InstructionFallbackNotFound
|
|
4954
|
-
6002,
|
|
4955
|
-
// InstructionDidNotDeserialize
|
|
4956
|
-
6003,
|
|
4957
|
-
// InstructionDidNotSerialize
|
|
4958
|
-
6016,
|
|
4959
|
-
// IdlInstructionStub
|
|
4960
|
-
6032,
|
|
4961
|
-
// ConstraintMut
|
|
4962
|
-
6033,
|
|
4963
|
-
// ConstraintHasOne
|
|
4964
|
-
6034,
|
|
4965
|
-
// ConstraintSigner
|
|
4966
|
-
6035,
|
|
4967
|
-
// ConstraintRaw
|
|
4968
|
-
6036,
|
|
4969
|
-
// ConstraintOwner
|
|
4970
|
-
6037,
|
|
4971
|
-
// ConstraintRentExempt
|
|
4972
|
-
6038,
|
|
4973
|
-
// ConstraintSeeds
|
|
4974
|
-
6039,
|
|
4975
|
-
// ConstraintExecutable
|
|
4976
|
-
6040,
|
|
4977
|
-
// ConstraintState
|
|
4978
|
-
6041,
|
|
4979
|
-
// ConstraintAssociated
|
|
4980
|
-
6042,
|
|
4981
|
-
// ConstraintAssociatedInit
|
|
4982
|
-
6043,
|
|
4983
|
-
// ConstraintClose
|
|
4984
|
-
6400
|
|
4985
|
-
// ConstraintAddress (the one we hit most often)
|
|
4986
|
-
]);
|
|
4987
|
-
function isLighthouseInstruction(ix) {
|
|
4988
|
-
return ix.programId.equals(LIGHTHOUSE_PROGRAM_ID);
|
|
4989
|
-
}
|
|
4990
|
-
function isLighthouseError(error) {
|
|
4991
|
-
const msg = extractErrorMessage(error);
|
|
4992
|
-
if (!msg) return false;
|
|
4993
|
-
if (msg.includes(LIGHTHOUSE_PROGRAM_ID_STR2)) return true;
|
|
4994
|
-
if (/custom\s+program\s+error:\s*0x1900\b/i.test(msg)) return true;
|
|
4995
|
-
if (/"Custom"\s*:\s*6400\b/.test(msg) && /InstructionError/i.test(msg)) return true;
|
|
4996
|
-
return false;
|
|
4997
|
-
}
|
|
4998
|
-
function isLighthouseFailureInLogs(logs) {
|
|
4999
|
-
if (!Array.isArray(logs)) return false;
|
|
5000
|
-
let insideLighthouse = false;
|
|
5001
|
-
for (const line of logs) {
|
|
5002
|
-
if (typeof line !== "string") continue;
|
|
5003
|
-
if (line.includes(`Program ${LIGHTHOUSE_PROGRAM_ID_STR2} invoke`)) {
|
|
5004
|
-
insideLighthouse = true;
|
|
5005
|
-
continue;
|
|
5006
|
-
}
|
|
5007
|
-
if (line.includes(`Program ${LIGHTHOUSE_PROGRAM_ID_STR2} success`)) {
|
|
5008
|
-
insideLighthouse = false;
|
|
5009
|
-
continue;
|
|
5010
|
-
}
|
|
5011
|
-
if (insideLighthouse && /failed/i.test(line)) {
|
|
5012
|
-
return true;
|
|
5013
|
-
}
|
|
5014
|
-
if (line.includes(`Program ${LIGHTHOUSE_PROGRAM_ID_STR2} failed`)) {
|
|
5015
|
-
return true;
|
|
5016
|
-
}
|
|
5017
|
-
}
|
|
5018
|
-
return false;
|
|
5019
|
-
}
|
|
5020
|
-
function stripLighthouseInstructions(instructions, percolatorProgramId) {
|
|
5021
|
-
if (percolatorProgramId) {
|
|
5022
|
-
const hasPercolatorIx = instructions.some(
|
|
5023
|
-
(ix) => ix.programId.equals(percolatorProgramId)
|
|
5024
|
-
);
|
|
5025
|
-
if (!hasPercolatorIx) {
|
|
5026
|
-
return instructions;
|
|
5027
|
-
}
|
|
5028
|
-
}
|
|
5029
|
-
return instructions.filter((ix) => !isLighthouseInstruction(ix));
|
|
5030
|
-
}
|
|
5031
|
-
function stripLighthouseFromTransaction(transaction, percolatorProgramId) {
|
|
5032
|
-
if (percolatorProgramId) {
|
|
5033
|
-
const hasPercolatorIx = transaction.instructions.some(
|
|
5034
|
-
(ix) => ix.programId.equals(percolatorProgramId)
|
|
5035
|
-
);
|
|
5036
|
-
if (!hasPercolatorIx) return transaction;
|
|
5037
|
-
}
|
|
5038
|
-
const hasLighthouse = transaction.instructions.some(isLighthouseInstruction);
|
|
5039
|
-
if (!hasLighthouse) return transaction;
|
|
5040
|
-
const clean = new Transaction2();
|
|
5041
|
-
clean.recentBlockhash = transaction.recentBlockhash;
|
|
5042
|
-
clean.feePayer = transaction.feePayer;
|
|
5043
|
-
for (const ix of transaction.instructions) {
|
|
5044
|
-
if (!isLighthouseInstruction(ix)) {
|
|
5045
|
-
clean.add(ix);
|
|
5046
|
-
}
|
|
5047
|
-
}
|
|
5048
|
-
return clean;
|
|
5049
|
-
}
|
|
5050
|
-
function countLighthouseInstructions(ixsOrTx) {
|
|
5051
|
-
const instructions = Array.isArray(ixsOrTx) ? ixsOrTx : ixsOrTx.instructions;
|
|
5052
|
-
return instructions.filter(isLighthouseInstruction).length;
|
|
5053
|
-
}
|
|
5054
|
-
var LIGHTHOUSE_USER_MESSAGE = "Your wallet's transaction guard (Blowfish/Lighthouse) is blocking this transaction. This is a known compatibility issue \u2014 the transaction itself is valid. Try one of these workarounds:\n1. Disable transaction simulation in your wallet settings\n2. Use a wallet without Blowfish protection (e.g., Backpack, Solflare)\n3. The SDK will automatically retry without the guard";
|
|
5055
|
-
function classifyLighthouseError(error) {
|
|
5056
|
-
if (isLighthouseError(error)) {
|
|
5057
|
-
return LIGHTHOUSE_USER_MESSAGE;
|
|
5058
|
-
}
|
|
5059
|
-
return null;
|
|
5060
|
-
}
|
|
5061
|
-
function extractErrorMessage(error) {
|
|
5062
|
-
if (!error) return null;
|
|
5063
|
-
if (typeof error === "string") return error;
|
|
5064
|
-
if (error instanceof Error) return error.message;
|
|
5065
|
-
if (typeof error === "object" && "message" in error) {
|
|
5066
|
-
return String(error.message);
|
|
5067
|
-
}
|
|
5068
|
-
try {
|
|
5069
|
-
return JSON.stringify(error);
|
|
5070
|
-
} catch {
|
|
5071
|
-
return null;
|
|
5072
|
-
}
|
|
5073
|
-
}
|
|
5074
|
-
|
|
5075
4648
|
// src/math/trading.ts
|
|
5076
4649
|
function computeMarkPnl(positionSize, entryPrice, oraclePrice) {
|
|
5077
4650
|
if (positionSize === 0n || oraclePrice === 0n) return 0n;
|
|
@@ -5096,10 +4669,16 @@ function computeLiqPrice(entryPrice, capital, positionSize, maintenanceMarginBps
|
|
|
5096
4669
|
function computePreTradeLiqPrice(oracleE6, margin, posSize, maintBps, feeBps, direction) {
|
|
5097
4670
|
if (oracleE6 === 0n || margin === 0n || posSize === 0n) return 0n;
|
|
5098
4671
|
const absPos = posSize < 0n ? -posSize : posSize;
|
|
5099
|
-
const fee = absPos * feeBps / 10000n;
|
|
5100
|
-
const effectiveCapital = margin > fee ? margin - fee : 0n;
|
|
5101
4672
|
const signedPos = direction === "long" ? absPos : -absPos;
|
|
5102
|
-
|
|
4673
|
+
const feeAdjust = oracleE6 * feeBps / 10000n;
|
|
4674
|
+
let adjustedEntry;
|
|
4675
|
+
if (direction === "long") {
|
|
4676
|
+
adjustedEntry = oracleE6 + feeAdjust;
|
|
4677
|
+
} else {
|
|
4678
|
+
const shortEntry = oracleE6 - feeAdjust;
|
|
4679
|
+
adjustedEntry = shortEntry > 0n ? shortEntry : 1n;
|
|
4680
|
+
}
|
|
4681
|
+
return computeLiqPrice(adjustedEntry, margin, signedPos, maintBps);
|
|
5103
4682
|
}
|
|
5104
4683
|
function computeTradingFee(notional, tradingFeeBps) {
|
|
5105
4684
|
return notional * tradingFeeBps / 10000n;
|
|
@@ -5119,20 +4698,9 @@ function computeFeeSplit(totalFee, config) {
|
|
|
5119
4698
|
if (config.lpBps === 0n && config.protocolBps === 0n && config.creatorBps === 0n) {
|
|
5120
4699
|
return [totalFee, 0n, 0n];
|
|
5121
4700
|
}
|
|
5122
|
-
const totalBps = config.lpBps + config.protocolBps + config.creatorBps;
|
|
5123
|
-
if (totalBps !== 10000n) {
|
|
5124
|
-
throw new Error(
|
|
5125
|
-
`Fee split must equal exactly 10000 bps (100%): lpBps=${config.lpBps} + protocolBps=${config.protocolBps} + creatorBps=${config.creatorBps} = ${totalBps}`
|
|
5126
|
-
);
|
|
5127
|
-
}
|
|
5128
4701
|
const lp = totalFee * config.lpBps / 10000n;
|
|
5129
4702
|
const protocol = totalFee * config.protocolBps / 10000n;
|
|
5130
4703
|
const creator = totalFee - lp - protocol;
|
|
5131
|
-
if (creator < 0n) {
|
|
5132
|
-
throw new Error(
|
|
5133
|
-
`Internal error: creator fee is negative (${creator}). This should not happen if lpBps + protocolBps + creatorBps === 10000.`
|
|
5134
|
-
);
|
|
5135
|
-
}
|
|
5136
4704
|
return [lp, protocol, creator];
|
|
5137
4705
|
}
|
|
5138
4706
|
function computePnlPercent(pnlTokens, capital) {
|
|
@@ -5147,17 +4715,10 @@ function computePnlPercent(pnlTokens, capital) {
|
|
|
5147
4715
|
}
|
|
5148
4716
|
function computeEstimatedEntryPrice(oracleE6, tradingFeeBps, direction) {
|
|
5149
4717
|
if (oracleE6 === 0n) return 0n;
|
|
5150
|
-
if (tradingFeeBps < 0n) {
|
|
5151
|
-
throw new Error(`computeEstimatedEntryPrice: tradingFeeBps must be non-negative, got ${tradingFeeBps}`);
|
|
5152
|
-
}
|
|
5153
4718
|
const feeImpact = oracleE6 * tradingFeeBps / 10000n;
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
`computeEstimatedEntryPrice: result ${result} is non-positive (tradingFeeBps=${tradingFeeBps} too high for oracle=${oracleE6})`
|
|
5158
|
-
);
|
|
5159
|
-
}
|
|
5160
|
-
return result;
|
|
4719
|
+
if (direction === "long") return oracleE6 + feeImpact;
|
|
4720
|
+
const shortEntry = oracleE6 - feeImpact;
|
|
4721
|
+
return shortEntry > 0n ? shortEntry : 1n;
|
|
5161
4722
|
}
|
|
5162
4723
|
var MAX_SAFE_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
|
|
5163
4724
|
var MIN_SAFE_BIGINT = BigInt(-Number.MAX_SAFE_INTEGER);
|
|
@@ -5178,12 +4739,7 @@ function computeMaxLeverage(initialMarginBps) {
|
|
|
5178
4739
|
if (initialMarginBps <= 0n) {
|
|
5179
4740
|
throw new Error("computeMaxLeverage: initialMarginBps must be positive");
|
|
5180
4741
|
}
|
|
5181
|
-
|
|
5182
|
-
return Number(scaledResult) / 1e6;
|
|
5183
|
-
}
|
|
5184
|
-
function computeMaxWithdrawable(capital, pnl, reservedPnl) {
|
|
5185
|
-
const maturedPnl = pnl - reservedPnl;
|
|
5186
|
-
return capital + (maturedPnl > 0n ? maturedPnl : 0n);
|
|
4742
|
+
return Number(10000n / initialMarginBps);
|
|
5187
4743
|
}
|
|
5188
4744
|
|
|
5189
4745
|
// src/math/warmup.ts
|
|
@@ -5195,9 +4751,6 @@ function computeWarmupUnlockedCapital(totalCapital, currentSlot, warmupStartSlot
|
|
|
5195
4751
|
return totalCapital * elapsed / warmupPeriodSlots;
|
|
5196
4752
|
}
|
|
5197
4753
|
function computeWarmupLeverageCap(initialMarginBps, totalCapital, currentSlot, warmupStartSlot, warmupPeriodSlots) {
|
|
5198
|
-
if (initialMarginBps <= 0n) {
|
|
5199
|
-
throw new Error("computeWarmupLeverageCap: initialMarginBps must be positive");
|
|
5200
|
-
}
|
|
5201
4754
|
const maxLev = computeMaxLeverage(initialMarginBps);
|
|
5202
4755
|
if (warmupPeriodSlots === 0n || warmupStartSlot === 0n) return maxLev;
|
|
5203
4756
|
if (totalCapital <= 0n) return 1;
|
|
@@ -5208,14 +4761,7 @@ function computeWarmupLeverageCap(initialMarginBps, totalCapital, currentSlot, w
|
|
|
5208
4761
|
warmupPeriodSlots
|
|
5209
4762
|
);
|
|
5210
4763
|
if (unlocked <= 0n) return 1;
|
|
5211
|
-
const
|
|
5212
|
-
if (scaledResult > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
5213
|
-
console.warn(
|
|
5214
|
-
`[computeWarmupLeverageCap] Warning: effective leverage ${scaledResult} exceeds MAX_SAFE_INTEGER, returning MAX_SAFE_INTEGER as a safety bound`
|
|
5215
|
-
);
|
|
5216
|
-
return Number.MAX_SAFE_INTEGER;
|
|
5217
|
-
}
|
|
5218
|
-
const effectiveLev = Number(scaledResult);
|
|
4764
|
+
const effectiveLev = Number(BigInt(maxLev) * unlocked / totalCapital);
|
|
5219
4765
|
return Math.max(1, effectiveLev);
|
|
5220
4766
|
}
|
|
5221
4767
|
function computeWarmupMaxPositionSize(initialMarginBps, totalCapital, currentSlot, warmupStartSlot, warmupPeriodSlots) {
|
|
@@ -5228,41 +4774,10 @@ function computeWarmupMaxPositionSize(initialMarginBps, totalCapital, currentSlo
|
|
|
5228
4774
|
);
|
|
5229
4775
|
return unlocked * BigInt(maxLev);
|
|
5230
4776
|
}
|
|
5231
|
-
function computeWarmupProgress(currentSlot, warmupStartedAtSlot, warmupPeriodSlots, pnl, reservedPnl) {
|
|
5232
|
-
if (warmupPeriodSlots === 0n || warmupStartedAtSlot === 0n) {
|
|
5233
|
-
return {
|
|
5234
|
-
maturedPnl: pnl > 0n ? pnl : 0n,
|
|
5235
|
-
reservedPnl: 0n,
|
|
5236
|
-
progressBps: 10000n,
|
|
5237
|
-
// 100%
|
|
5238
|
-
slotsRemaining: 0n
|
|
5239
|
-
};
|
|
5240
|
-
}
|
|
5241
|
-
const elapsed = currentSlot >= warmupStartedAtSlot ? currentSlot - warmupStartedAtSlot : 0n;
|
|
5242
|
-
if (elapsed >= warmupPeriodSlots) {
|
|
5243
|
-
return {
|
|
5244
|
-
maturedPnl: pnl > 0n ? pnl : 0n,
|
|
5245
|
-
reservedPnl: 0n,
|
|
5246
|
-
progressBps: 10000n,
|
|
5247
|
-
// 100%
|
|
5248
|
-
slotsRemaining: 0n
|
|
5249
|
-
};
|
|
5250
|
-
}
|
|
5251
|
-
const progressBps = elapsed * 10000n / warmupPeriodSlots;
|
|
5252
|
-
const slotsRemaining = warmupPeriodSlots - elapsed;
|
|
5253
|
-
const maturedPnl = pnl > 0n ? pnl * progressBps / 10000n : 0n;
|
|
5254
|
-
const locked = reservedPnl > 0n ? reservedPnl : 0n;
|
|
5255
|
-
return {
|
|
5256
|
-
maturedPnl,
|
|
5257
|
-
reservedPnl: locked,
|
|
5258
|
-
progressBps,
|
|
5259
|
-
slotsRemaining
|
|
5260
|
-
};
|
|
5261
|
-
}
|
|
5262
4777
|
|
|
5263
4778
|
// src/validation.ts
|
|
5264
|
-
import { PublicKey as
|
|
5265
|
-
var
|
|
4779
|
+
import { PublicKey as PublicKey13 } from "@solana/web3.js";
|
|
4780
|
+
var U16_MAX2 = 65535;
|
|
5266
4781
|
var U64_MAX = BigInt("18446744073709551615");
|
|
5267
4782
|
var I64_MIN = BigInt("-9223372036854775808");
|
|
5268
4783
|
var I64_MAX = BigInt("9223372036854775807");
|
|
@@ -5291,7 +4806,7 @@ var ValidationError = class extends Error {
|
|
|
5291
4806
|
};
|
|
5292
4807
|
function validatePublicKey(value, field) {
|
|
5293
4808
|
try {
|
|
5294
|
-
return new
|
|
4809
|
+
return new PublicKey13(value);
|
|
5295
4810
|
} catch {
|
|
5296
4811
|
throw new ValidationError(
|
|
5297
4812
|
field,
|
|
@@ -5302,26 +4817,24 @@ function validatePublicKey(value, field) {
|
|
|
5302
4817
|
function validateIndex(value, field) {
|
|
5303
4818
|
const t = requireDecimalUIntString(value, field);
|
|
5304
4819
|
const bi = BigInt(t);
|
|
5305
|
-
if (bi > BigInt(
|
|
4820
|
+
if (bi > BigInt(U16_MAX2)) {
|
|
5306
4821
|
throw new ValidationError(
|
|
5307
4822
|
field,
|
|
5308
|
-
`must be <= ${
|
|
4823
|
+
`must be <= ${U16_MAX2} (u16 max), got ${t}`
|
|
5309
4824
|
);
|
|
5310
4825
|
}
|
|
5311
|
-
if (bi > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
5312
|
-
throw new ValidationError(field, `internal error: u16 value exceeds MAX_SAFE_INTEGER`);
|
|
5313
|
-
}
|
|
5314
4826
|
return Number(bi);
|
|
5315
4827
|
}
|
|
5316
4828
|
function validateAmount(value, field) {
|
|
5317
|
-
|
|
5318
|
-
|
|
4829
|
+
let num;
|
|
4830
|
+
try {
|
|
4831
|
+
num = BigInt(value);
|
|
4832
|
+
} catch {
|
|
5319
4833
|
throw new ValidationError(
|
|
5320
4834
|
field,
|
|
5321
|
-
`"${value}" is not a valid
|
|
4835
|
+
`"${value}" is not a valid number. Use decimal digits only.`
|
|
5322
4836
|
);
|
|
5323
4837
|
}
|
|
5324
|
-
const num = BigInt(t);
|
|
5325
4838
|
if (num < 0n) {
|
|
5326
4839
|
throw new ValidationError(field, `must be non-negative, got ${num}`);
|
|
5327
4840
|
}
|
|
@@ -5334,14 +4847,15 @@ function validateAmount(value, field) {
|
|
|
5334
4847
|
return num;
|
|
5335
4848
|
}
|
|
5336
4849
|
function validateU128(value, field) {
|
|
5337
|
-
|
|
5338
|
-
|
|
4850
|
+
let num;
|
|
4851
|
+
try {
|
|
4852
|
+
num = BigInt(value);
|
|
4853
|
+
} catch {
|
|
5339
4854
|
throw new ValidationError(
|
|
5340
4855
|
field,
|
|
5341
|
-
`"${value}" is not a valid
|
|
4856
|
+
`"${value}" is not a valid number. Use decimal digits only.`
|
|
5342
4857
|
);
|
|
5343
4858
|
}
|
|
5344
|
-
const num = BigInt(t);
|
|
5345
4859
|
if (num < 0n) {
|
|
5346
4860
|
throw new ValidationError(field, `must be non-negative, got ${num}`);
|
|
5347
4861
|
}
|
|
@@ -5354,14 +4868,15 @@ function validateU128(value, field) {
|
|
|
5354
4868
|
return num;
|
|
5355
4869
|
}
|
|
5356
4870
|
function validateI64(value, field) {
|
|
5357
|
-
|
|
5358
|
-
|
|
4871
|
+
let num;
|
|
4872
|
+
try {
|
|
4873
|
+
num = BigInt(value);
|
|
4874
|
+
} catch {
|
|
5359
4875
|
throw new ValidationError(
|
|
5360
4876
|
field,
|
|
5361
|
-
`"${value}" is not a valid
|
|
4877
|
+
`"${value}" is not a valid number. Use decimal digits only, with optional leading minus.`
|
|
5362
4878
|
);
|
|
5363
4879
|
}
|
|
5364
|
-
const num = BigInt(t);
|
|
5365
4880
|
if (num < I64_MIN) {
|
|
5366
4881
|
throw new ValidationError(
|
|
5367
4882
|
field,
|
|
@@ -5377,14 +4892,15 @@ function validateI64(value, field) {
|
|
|
5377
4892
|
return num;
|
|
5378
4893
|
}
|
|
5379
4894
|
function validateI128(value, field) {
|
|
5380
|
-
|
|
5381
|
-
|
|
4895
|
+
let num;
|
|
4896
|
+
try {
|
|
4897
|
+
num = BigInt(value);
|
|
4898
|
+
} catch {
|
|
5382
4899
|
throw new ValidationError(
|
|
5383
4900
|
field,
|
|
5384
|
-
`"${value}" is not a valid
|
|
4901
|
+
`"${value}" is not a valid number. Use decimal digits only, with optional leading minus.`
|
|
5385
4902
|
);
|
|
5386
4903
|
}
|
|
5387
|
-
const num = BigInt(t);
|
|
5388
4904
|
if (num < I128_MIN) {
|
|
5389
4905
|
throw new ValidationError(
|
|
5390
4906
|
field,
|
|
@@ -5408,9 +4924,6 @@ function validateBps(value, field) {
|
|
|
5408
4924
|
`must be <= 10000 (100%), got ${t}`
|
|
5409
4925
|
);
|
|
5410
4926
|
}
|
|
5411
|
-
if (bi > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
5412
|
-
throw new ValidationError(field, `internal error: bps value exceeds MAX_SAFE_INTEGER`);
|
|
5413
|
-
}
|
|
5414
4927
|
return Number(bi);
|
|
5415
4928
|
}
|
|
5416
4929
|
function validateU64(value, field) {
|
|
@@ -5419,15 +4932,12 @@ function validateU64(value, field) {
|
|
|
5419
4932
|
function validateU16(value, field) {
|
|
5420
4933
|
const t = requireDecimalUIntString(value, field);
|
|
5421
4934
|
const bi = BigInt(t);
|
|
5422
|
-
if (bi > BigInt(
|
|
4935
|
+
if (bi > BigInt(U16_MAX2)) {
|
|
5423
4936
|
throw new ValidationError(
|
|
5424
4937
|
field,
|
|
5425
|
-
`must be <= ${
|
|
4938
|
+
`must be <= ${U16_MAX2} (u16 max), got ${t}`
|
|
5426
4939
|
);
|
|
5427
4940
|
}
|
|
5428
|
-
if (bi > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
5429
|
-
throw new ValidationError(field, `internal error: u16 value exceeds MAX_SAFE_INTEGER`);
|
|
5430
|
-
}
|
|
5431
4941
|
return Number(bi);
|
|
5432
4942
|
}
|
|
5433
4943
|
|
|
@@ -5478,9 +4988,7 @@ function parseDexScreenerPairs(json) {
|
|
|
5478
4988
|
else if (liquidity > 1e4) confidence = 60;
|
|
5479
4989
|
else if (liquidity > 1e3) confidence = 45;
|
|
5480
4990
|
const priceUsd = pair.priceUsd;
|
|
5481
|
-
const
|
|
5482
|
-
if (!Number.isFinite(rawPrice) || rawPrice <= 0) continue;
|
|
5483
|
-
const price = rawPrice;
|
|
4991
|
+
const price = typeof priceUsd === "string" || typeof priceUsd === "number" ? parseFloat(String(priceUsd)) || 0 : 0;
|
|
5484
4992
|
let baseSym = "?";
|
|
5485
4993
|
let quoteSym = "?";
|
|
5486
4994
|
if (isRecord(pair.baseToken) && typeof pair.baseToken.symbol === "string") {
|
|
@@ -5511,8 +5019,8 @@ function parseJupiterMintEntry(json, mint) {
|
|
|
5511
5019
|
if (!isRecord(row)) return null;
|
|
5512
5020
|
const rawPrice = row.price;
|
|
5513
5021
|
if (rawPrice === void 0 || rawPrice === null) return null;
|
|
5514
|
-
const price = parseFloat(String(rawPrice));
|
|
5515
|
-
if (
|
|
5022
|
+
const price = parseFloat(String(rawPrice)) || 0;
|
|
5023
|
+
if (price <= 0) return null;
|
|
5516
5024
|
let mintSymbol = "?";
|
|
5517
5025
|
if (typeof row.mintSymbol === "string") mintSymbol = row.mintSymbol;
|
|
5518
5026
|
return { price, mintSymbol };
|
|
@@ -5578,17 +5086,10 @@ async function fetchDexSources(mint, signal) {
|
|
|
5578
5086
|
headers: { "User-Agent": "percolator/1.0" }
|
|
5579
5087
|
}
|
|
5580
5088
|
);
|
|
5581
|
-
if (!resp.ok)
|
|
5582
|
-
console.debug(`[fetchDexSources] HTTP ${resp.status} for mint ${mint}`);
|
|
5583
|
-
return [];
|
|
5584
|
-
}
|
|
5089
|
+
if (!resp.ok) return [];
|
|
5585
5090
|
const json = await resp.json();
|
|
5586
5091
|
return parseDexScreenerPairs(json);
|
|
5587
|
-
} catch
|
|
5588
|
-
console.warn(
|
|
5589
|
-
`[fetchDexSources] Error fetching DexScreener data for mint ${mint}:`,
|
|
5590
|
-
err instanceof Error ? err.message : String(err)
|
|
5591
|
-
);
|
|
5092
|
+
} catch {
|
|
5592
5093
|
return [];
|
|
5593
5094
|
}
|
|
5594
5095
|
}
|
|
@@ -5599,7 +5100,7 @@ function lookupPythSource(mint) {
|
|
|
5599
5100
|
type: "pyth",
|
|
5600
5101
|
address: entry.feedId,
|
|
5601
5102
|
pairLabel: `${entry.symbol} / USD (Pyth)`,
|
|
5602
|
-
liquidity:
|
|
5103
|
+
liquidity: Infinity,
|
|
5603
5104
|
// Pyth is considered deep liquidity
|
|
5604
5105
|
price: 0,
|
|
5605
5106
|
// We don't fetch live price here; caller can enrich
|
|
@@ -5616,16 +5117,10 @@ async function fetchJupiterSource(mint, signal) {
|
|
|
5616
5117
|
headers: { "User-Agent": "percolator/1.0" }
|
|
5617
5118
|
}
|
|
5618
5119
|
);
|
|
5619
|
-
if (!resp.ok)
|
|
5620
|
-
console.debug(`[fetchJupiterSource] HTTP ${resp.status} for mint ${mint}`);
|
|
5621
|
-
return null;
|
|
5622
|
-
}
|
|
5120
|
+
if (!resp.ok) return null;
|
|
5623
5121
|
const json = await resp.json();
|
|
5624
5122
|
const row = parseJupiterMintEntry(json, mint);
|
|
5625
|
-
if (!row)
|
|
5626
|
-
console.debug(`[fetchJupiterSource] No price data from Jupiter for mint ${mint}`);
|
|
5627
|
-
return null;
|
|
5628
|
-
}
|
|
5123
|
+
if (!row) return null;
|
|
5629
5124
|
return {
|
|
5630
5125
|
type: "jupiter",
|
|
5631
5126
|
address: mint,
|
|
@@ -5636,39 +5131,23 @@ async function fetchJupiterSource(mint, signal) {
|
|
|
5636
5131
|
confidence: 40
|
|
5637
5132
|
// Fallback — lower confidence
|
|
5638
5133
|
};
|
|
5639
|
-
} catch
|
|
5640
|
-
console.warn(
|
|
5641
|
-
`[fetchJupiterSource] Error fetching Jupiter data for mint ${mint}:`,
|
|
5642
|
-
err instanceof Error ? err.message : String(err)
|
|
5643
|
-
);
|
|
5134
|
+
} catch {
|
|
5644
5135
|
return null;
|
|
5645
5136
|
}
|
|
5646
5137
|
}
|
|
5647
5138
|
async function resolvePrice(mint, signal, options) {
|
|
5648
5139
|
const timeoutMs = options?.timeoutMs ?? DEFAULT_RESOLVE_TIMEOUT_MS;
|
|
5649
5140
|
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
5650
|
-
const
|
|
5141
|
+
const combinedSignal = signal ? combineAbortSignals([signal, timeoutSignal]) : timeoutSignal;
|
|
5651
5142
|
const [dexSources, jupiterSource] = await Promise.all([
|
|
5652
|
-
fetchDexSources(mint,
|
|
5653
|
-
fetchJupiterSource(mint,
|
|
5143
|
+
fetchDexSources(mint, combinedSignal),
|
|
5144
|
+
fetchJupiterSource(mint, combinedSignal)
|
|
5654
5145
|
]);
|
|
5655
5146
|
const pythSource = lookupPythSource(mint);
|
|
5656
5147
|
const allSources = [];
|
|
5657
5148
|
if (pythSource) {
|
|
5658
|
-
const
|
|
5659
|
-
|
|
5660
|
-
if (dexPrice > 0 && jupPrice > 0) {
|
|
5661
|
-
const mid = (dexPrice + jupPrice) / 2;
|
|
5662
|
-
const deviation = Math.abs(dexPrice - jupPrice) / mid;
|
|
5663
|
-
if (deviation > 0.5) {
|
|
5664
|
-
pythSource.price = 0;
|
|
5665
|
-
pythSource.confidence = 20;
|
|
5666
|
-
} else {
|
|
5667
|
-
pythSource.price = mid;
|
|
5668
|
-
}
|
|
5669
|
-
} else {
|
|
5670
|
-
pythSource.price = dexPrice || jupPrice || 0;
|
|
5671
|
-
}
|
|
5149
|
+
const refPrice = dexSources[0]?.price || jupiterSource?.price || 0;
|
|
5150
|
+
pythSource.price = refPrice;
|
|
5672
5151
|
allSources.push(pythSource);
|
|
5673
5152
|
}
|
|
5674
5153
|
allSources.push(...dexSources);
|
|
@@ -5693,7 +5172,9 @@ export {
|
|
|
5693
5172
|
ACCOUNTS_CLOSE_ACCOUNT,
|
|
5694
5173
|
ACCOUNTS_CLOSE_SLAB,
|
|
5695
5174
|
ACCOUNTS_CLOSE_STALE_SLABS,
|
|
5175
|
+
ACCOUNTS_CREATE_INSURANCE_MINT,
|
|
5696
5176
|
ACCOUNTS_DEPOSIT_COLLATERAL,
|
|
5177
|
+
ACCOUNTS_DEPOSIT_INSURANCE_LP,
|
|
5697
5178
|
ACCOUNTS_EXECUTE_ADL,
|
|
5698
5179
|
ACCOUNTS_FUND_MARKET_INSURANCE,
|
|
5699
5180
|
ACCOUNTS_INIT_LP,
|
|
@@ -5709,6 +5190,7 @@ export {
|
|
|
5709
5190
|
ACCOUNTS_QUEUE_WITHDRAWAL,
|
|
5710
5191
|
ACCOUNTS_RECLAIM_SLAB_RENT,
|
|
5711
5192
|
ACCOUNTS_RESOLVE_MARKET,
|
|
5193
|
+
ACCOUNTS_SET_DEX_POOL,
|
|
5712
5194
|
ACCOUNTS_SET_INSURANCE_ISOLATION,
|
|
5713
5195
|
ACCOUNTS_SET_MAINTENANCE_FEE,
|
|
5714
5196
|
ACCOUNTS_SET_OI_IMBALANCE_HARD_BLOCK,
|
|
@@ -5727,22 +5209,17 @@ export {
|
|
|
5727
5209
|
ACCOUNTS_UPDATE_CONFIG,
|
|
5728
5210
|
ACCOUNTS_WITHDRAW_COLLATERAL,
|
|
5729
5211
|
ACCOUNTS_WITHDRAW_INSURANCE,
|
|
5212
|
+
ACCOUNTS_WITHDRAW_INSURANCE_LP,
|
|
5730
5213
|
AccountKind,
|
|
5731
5214
|
CHAINLINK_ANSWER_OFFSET,
|
|
5732
5215
|
CHAINLINK_DECIMALS_OFFSET,
|
|
5733
5216
|
CHAINLINK_MIN_SIZE,
|
|
5734
|
-
CHAINLINK_TIMESTAMP_OFFSET,
|
|
5735
5217
|
CREATOR_LOCK_SEED,
|
|
5736
5218
|
CTX_VAMM_OFFSET,
|
|
5737
5219
|
DEFAULT_OI_RAMP_SLOTS,
|
|
5738
5220
|
ENGINE_MARK_PRICE_OFF,
|
|
5739
5221
|
ENGINE_OFF,
|
|
5740
5222
|
IX_TAG,
|
|
5741
|
-
LIGHTHOUSE_CONSTRAINT_ADDRESS,
|
|
5742
|
-
LIGHTHOUSE_ERROR_CODES,
|
|
5743
|
-
LIGHTHOUSE_PROGRAM_ID,
|
|
5744
|
-
LIGHTHOUSE_PROGRAM_ID_STR2 as LIGHTHOUSE_PROGRAM_ID_STR,
|
|
5745
|
-
LIGHTHOUSE_USER_MESSAGE,
|
|
5746
5223
|
MARK_PRICE_EMA_ALPHA_E6,
|
|
5747
5224
|
MARK_PRICE_EMA_WINDOW_SLOTS,
|
|
5748
5225
|
MAX_DECIMALS,
|
|
@@ -5764,7 +5241,6 @@ export {
|
|
|
5764
5241
|
RAMP_START_BPS,
|
|
5765
5242
|
RAYDIUM_CLMM_PROGRAM_ID,
|
|
5766
5243
|
RENOUNCE_ADMIN_CONFIRMATION,
|
|
5767
|
-
RpcPool,
|
|
5768
5244
|
SLAB_TIERS,
|
|
5769
5245
|
SLAB_TIERS_V0,
|
|
5770
5246
|
SLAB_TIERS_V1,
|
|
@@ -5786,14 +5262,11 @@ export {
|
|
|
5786
5262
|
VAMM_MAGIC,
|
|
5787
5263
|
ValidationError,
|
|
5788
5264
|
WELL_KNOWN,
|
|
5789
|
-
_internal,
|
|
5790
5265
|
buildAccountMetas,
|
|
5791
5266
|
buildAdlInstruction,
|
|
5792
5267
|
buildAdlTransaction,
|
|
5793
5268
|
buildIx,
|
|
5794
5269
|
checkPhaseTransition,
|
|
5795
|
-
checkRpcHealth,
|
|
5796
|
-
classifyLighthouseError,
|
|
5797
5270
|
clearStaticMarkets,
|
|
5798
5271
|
computeDexSpotPriceE6,
|
|
5799
5272
|
computeDynamicFeeBps,
|
|
@@ -5806,7 +5279,6 @@ export {
|
|
|
5806
5279
|
computeLiqPrice,
|
|
5807
5280
|
computeMarkPnl,
|
|
5808
5281
|
computeMaxLeverage,
|
|
5809
|
-
computeMaxWithdrawable,
|
|
5810
5282
|
computePnlPercent,
|
|
5811
5283
|
computePreTradeLiqPrice,
|
|
5812
5284
|
computeRequiredMargin,
|
|
@@ -5814,15 +5286,14 @@ export {
|
|
|
5814
5286
|
computeVammQuote,
|
|
5815
5287
|
computeWarmupLeverageCap,
|
|
5816
5288
|
computeWarmupMaxPositionSize,
|
|
5817
|
-
computeWarmupProgress,
|
|
5818
5289
|
computeWarmupUnlockedCapital,
|
|
5819
5290
|
concatBytes,
|
|
5820
|
-
countLighthouseInstructions,
|
|
5821
5291
|
decodeError,
|
|
5822
5292
|
decodeStakePool,
|
|
5823
5293
|
depositAccounts,
|
|
5824
5294
|
deriveCreatorLockPda,
|
|
5825
5295
|
deriveDepositPda,
|
|
5296
|
+
deriveInsuranceLpMint,
|
|
5826
5297
|
deriveKeeperFund,
|
|
5827
5298
|
deriveLpPda,
|
|
5828
5299
|
derivePythPriceUpdateAccount,
|
|
@@ -5859,11 +5330,14 @@ export {
|
|
|
5859
5330
|
encodeClaimQueuedWithdrawal,
|
|
5860
5331
|
encodeClearPendingSettlement,
|
|
5861
5332
|
encodeCloseAccount,
|
|
5333
|
+
encodeCloseKeeperFund,
|
|
5862
5334
|
encodeCloseOrphanSlab,
|
|
5863
5335
|
encodeCloseSlab,
|
|
5864
5336
|
encodeCloseStaleSlabs,
|
|
5337
|
+
encodeCreateInsuranceMint,
|
|
5865
5338
|
encodeCreateLpVault,
|
|
5866
5339
|
encodeDepositCollateral,
|
|
5340
|
+
encodeDepositInsuranceLP,
|
|
5867
5341
|
encodeDepositLpCollateral,
|
|
5868
5342
|
encodeExecuteAdl,
|
|
5869
5343
|
encodeForceCloseResolved,
|
|
@@ -5934,6 +5408,7 @@ export {
|
|
|
5934
5408
|
encodeUpdateRiskParams,
|
|
5935
5409
|
encodeWithdrawCollateral,
|
|
5936
5410
|
encodeWithdrawInsurance,
|
|
5411
|
+
encodeWithdrawInsuranceLP,
|
|
5937
5412
|
encodeWithdrawInsuranceLimited,
|
|
5938
5413
|
encodeWithdrawLpCollateral,
|
|
5939
5414
|
fetchAdlRankedPositions,
|
|
@@ -5955,10 +5430,6 @@ export {
|
|
|
5955
5430
|
initPoolAccounts,
|
|
5956
5431
|
isAccountUsed,
|
|
5957
5432
|
isAdlTriggered,
|
|
5958
|
-
isAnchorErrorCode,
|
|
5959
|
-
isLighthouseError,
|
|
5960
|
-
isLighthouseFailureInLogs,
|
|
5961
|
-
isLighthouseInstruction,
|
|
5962
5433
|
isStandardToken,
|
|
5963
5434
|
isToken2022,
|
|
5964
5435
|
isValidChainlinkOracle,
|
|
@@ -5983,8 +5454,6 @@ export {
|
|
|
5983
5454
|
simulateOrSend,
|
|
5984
5455
|
slabDataSize,
|
|
5985
5456
|
slabDataSizeV1,
|
|
5986
|
-
stripLighthouseFromTransaction,
|
|
5987
|
-
stripLighthouseInstructions,
|
|
5988
5457
|
validateAmount,
|
|
5989
5458
|
validateBps,
|
|
5990
5459
|
validateI128,
|
|
@@ -5995,7 +5464,6 @@ export {
|
|
|
5995
5464
|
validateU128,
|
|
5996
5465
|
validateU16,
|
|
5997
5466
|
validateU64,
|
|
5998
|
-
withRetry,
|
|
5999
5467
|
withdrawAccounts
|
|
6000
5468
|
};
|
|
6001
5469
|
//# sourceMappingURL=index.js.map
|