@percolatorct/sdk 1.0.0-beta.13 → 1.0.0-beta.14
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 +3459 -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.d.ts
CHANGED
|
@@ -1,7 +1,3459 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { PublicKey, AccountMeta, Connection, TransactionInstruction, Keypair, Commitment } from '@solana/web3.js';
|
|
2
|
+
import { Account as Account$1 } from '@solana/spl-token';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Encode u8 (1 byte)
|
|
6
|
+
*/
|
|
7
|
+
declare function encU8(val: number): Uint8Array;
|
|
8
|
+
/**
|
|
9
|
+
* Encode u16 little-endian (2 bytes)
|
|
10
|
+
*/
|
|
11
|
+
declare function encU16(val: number): Uint8Array;
|
|
12
|
+
/**
|
|
13
|
+
* Encode u32 little-endian (4 bytes)
|
|
14
|
+
*/
|
|
15
|
+
declare function encU32(val: number): Uint8Array;
|
|
16
|
+
/**
|
|
17
|
+
* Encode u64 little-endian (8 bytes)
|
|
18
|
+
* Input: bigint or string (decimal)
|
|
19
|
+
*/
|
|
20
|
+
declare function encU64(val: bigint | string): Uint8Array;
|
|
21
|
+
/**
|
|
22
|
+
* Encode i64 little-endian (8 bytes), two's complement
|
|
23
|
+
* Input: bigint or string (decimal, may be negative)
|
|
24
|
+
*/
|
|
25
|
+
declare function encI64(val: bigint | string): Uint8Array;
|
|
26
|
+
/**
|
|
27
|
+
* Encode u128 little-endian (16 bytes)
|
|
28
|
+
* Input: bigint or string (decimal)
|
|
29
|
+
*/
|
|
30
|
+
declare function encU128(val: bigint | string): Uint8Array;
|
|
31
|
+
/**
|
|
32
|
+
* Encode i128 little-endian (16 bytes), two's complement
|
|
33
|
+
* Input: bigint or string (decimal, may be negative)
|
|
34
|
+
*/
|
|
35
|
+
declare function encI128(val: bigint | string): Uint8Array;
|
|
36
|
+
/**
|
|
37
|
+
* Encode a PublicKey (32 bytes)
|
|
38
|
+
* Input: PublicKey or base58 string
|
|
39
|
+
*/
|
|
40
|
+
declare function encPubkey(val: PublicKey | string): Uint8Array;
|
|
41
|
+
/**
|
|
42
|
+
* Encode a boolean as u8 (0 = false, 1 = true)
|
|
43
|
+
*/
|
|
44
|
+
declare function encBool(val: boolean): Uint8Array;
|
|
45
|
+
/**
|
|
46
|
+
* Concatenate multiple Uint8Arrays (replaces Buffer.concat)
|
|
47
|
+
*/
|
|
48
|
+
declare function concatBytes(...arrays: Uint8Array[]): Uint8Array;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Oracle price constraints.
|
|
52
|
+
* Maximum oracle price that can be pushed to the on-chain oracle authority.
|
|
53
|
+
*/
|
|
54
|
+
declare const MAX_ORACLE_PRICE = 1000000000000n;
|
|
55
|
+
/**
|
|
56
|
+
* Instruction tags - exact match to Rust ix::Instruction::decode
|
|
57
|
+
*/
|
|
58
|
+
declare const IX_TAG: {
|
|
59
|
+
readonly InitMarket: 0;
|
|
60
|
+
readonly InitUser: 1;
|
|
61
|
+
readonly InitLP: 2;
|
|
62
|
+
readonly DepositCollateral: 3;
|
|
63
|
+
readonly WithdrawCollateral: 4;
|
|
64
|
+
readonly KeeperCrank: 5;
|
|
65
|
+
readonly TradeNoCpi: 6;
|
|
66
|
+
readonly LiquidateAtOracle: 7;
|
|
67
|
+
readonly CloseAccount: 8;
|
|
68
|
+
readonly TopUpInsurance: 9;
|
|
69
|
+
readonly TradeCpi: 10;
|
|
70
|
+
readonly SetRiskThreshold: 11;
|
|
71
|
+
readonly UpdateAdmin: 12;
|
|
72
|
+
readonly CloseSlab: 13;
|
|
73
|
+
readonly UpdateConfig: 14;
|
|
74
|
+
readonly SetMaintenanceFee: 15;
|
|
75
|
+
readonly SetOracleAuthority: 16;
|
|
76
|
+
readonly PushOraclePrice: 17;
|
|
77
|
+
readonly SetOraclePriceCap: 18;
|
|
78
|
+
readonly ResolveMarket: 19;
|
|
79
|
+
readonly WithdrawInsurance: 20;
|
|
80
|
+
readonly AdminForceClose: 21;
|
|
81
|
+
readonly SetInsuranceWithdrawPolicy: 22;
|
|
82
|
+
/** @deprecated Use SetInsuranceWithdrawPolicy */ readonly UpdateRiskParams: 22;
|
|
83
|
+
readonly WithdrawInsuranceLimited: 23;
|
|
84
|
+
/** @deprecated Use WithdrawInsuranceLimited */ readonly RenounceAdmin: 23;
|
|
85
|
+
readonly QueryLpFees: 24;
|
|
86
|
+
readonly ReclaimEmptyAccount: 25;
|
|
87
|
+
readonly SettleAccount: 26;
|
|
88
|
+
readonly DepositFeeCredits: 27;
|
|
89
|
+
readonly ConvertReleasedPnl: 28;
|
|
90
|
+
readonly ResolvePermissionless: 29;
|
|
91
|
+
/** @deprecated Use ResolvePermissionless */ readonly AcceptAdmin: 29;
|
|
92
|
+
readonly ForceCloseResolved: 30;
|
|
93
|
+
readonly SetPythOracle: 32;
|
|
94
|
+
readonly UpdateMarkPrice: 33;
|
|
95
|
+
readonly UpdateHyperpMark: 34;
|
|
96
|
+
readonly TradeCpiV2: 35;
|
|
97
|
+
readonly UnresolveMarket: 36;
|
|
98
|
+
readonly CreateLpVault: 37;
|
|
99
|
+
readonly LpVaultDeposit: 38;
|
|
100
|
+
readonly LpVaultWithdraw: 39;
|
|
101
|
+
readonly LpVaultCrankFees: 40;
|
|
102
|
+
/** PERC-306: Fund per-market isolated insurance balance */
|
|
103
|
+
readonly FundMarketInsurance: 41;
|
|
104
|
+
/** PERC-306: Set insurance isolation BPS for a market */
|
|
105
|
+
readonly SetInsuranceIsolation: 42;
|
|
106
|
+
/** PERC-314: Challenge settlement price during dispute window */
|
|
107
|
+
readonly ChallengeSettlement: 43;
|
|
108
|
+
/** PERC-314: Resolve dispute (admin adjudication) */
|
|
109
|
+
readonly ResolveDispute: 44;
|
|
110
|
+
/** PERC-315: Deposit LP vault tokens as perp collateral */
|
|
111
|
+
readonly DepositLpCollateral: 45;
|
|
112
|
+
/** PERC-315: Withdraw LP collateral (position must be closed) */
|
|
113
|
+
readonly WithdrawLpCollateral: 46;
|
|
114
|
+
/** PERC-309: Queue a large LP withdrawal (user; creates withdraw_queue PDA). */
|
|
115
|
+
readonly QueueWithdrawal: 47;
|
|
116
|
+
/** PERC-309: Claim one epoch tranche from a queued LP withdrawal (user). */
|
|
117
|
+
readonly ClaimQueuedWithdrawal: 48;
|
|
118
|
+
/** PERC-309: Cancel a queued withdrawal, refund remaining LP tokens (user). */
|
|
119
|
+
readonly CancelQueuedWithdrawal: 49;
|
|
120
|
+
/** PERC-305: Auto-deleverage — surgically close profitable positions when PnL cap is exceeded (permissionless). */
|
|
121
|
+
readonly ExecuteAdl: 50;
|
|
122
|
+
/** Close a stale slab of an invalid/old layout and recover rent SOL (admin only). */
|
|
123
|
+
readonly CloseStaleSlabs: 51;
|
|
124
|
+
/** Reclaim rent from an uninitialised slab whose market creation failed mid-flow. Slab must sign. */
|
|
125
|
+
readonly ReclaimSlabRent: 52;
|
|
126
|
+
/** Permissionless on-chain audit crank: verifies conservation invariants and pauses market on violation. */
|
|
127
|
+
readonly AuditCrank: 53;
|
|
128
|
+
/** Cross-Market Portfolio Margining: SetOffsetPair */
|
|
129
|
+
readonly SetOffsetPair: 54;
|
|
130
|
+
/** Cross-Market Portfolio Margining: AttestCrossMargin */
|
|
131
|
+
readonly AttestCrossMargin: 55;
|
|
132
|
+
/** PERC-622: Advance oracle phase (permissionless crank) */
|
|
133
|
+
readonly AdvanceOraclePhase: 56;
|
|
134
|
+
/** PERC-623: Top up a market's keeper fund (permissionless) */
|
|
135
|
+
readonly TopUpKeeperFund: 57;
|
|
136
|
+
/** PERC-629: Slash a market creator's deposit (permissionless) */
|
|
137
|
+
readonly SlashCreationDeposit: 58;
|
|
138
|
+
/** PERC-628: Initialize the global shared vault (admin) */
|
|
139
|
+
readonly InitSharedVault: 59;
|
|
140
|
+
/** PERC-628: Allocate virtual liquidity to a market (admin) */
|
|
141
|
+
readonly AllocateMarket: 60;
|
|
142
|
+
/** PERC-628: Queue a withdrawal for the current epoch */
|
|
143
|
+
readonly QueueWithdrawalSV: 61;
|
|
144
|
+
/** PERC-628: Claim a queued withdrawal after epoch elapses */
|
|
145
|
+
readonly ClaimEpochWithdrawal: 62;
|
|
146
|
+
/** PERC-628: Advance the shared vault epoch (permissionless crank) */
|
|
147
|
+
readonly AdvanceEpoch: 63;
|
|
148
|
+
/** PERC-608: Mint a Position NFT for a user's open position. */
|
|
149
|
+
readonly MintPositionNft: 64;
|
|
150
|
+
/** PERC-608: Transfer position ownership via the NFT (keeper-gated). */
|
|
151
|
+
readonly TransferPositionOwnership: 65;
|
|
152
|
+
/** PERC-608: Burn the Position NFT when a position is closed. */
|
|
153
|
+
readonly BurnPositionNft: 66;
|
|
154
|
+
/** PERC-608: Keeper sets pending_settlement flag before a funding transfer. */
|
|
155
|
+
readonly SetPendingSettlement: 67;
|
|
156
|
+
/** PERC-608: Keeper clears pending_settlement flag after KeeperCrank. */
|
|
157
|
+
readonly ClearPendingSettlement: 68;
|
|
158
|
+
/** PERC-608: Internal CPI call from percolator-nft TransferHook to update on-chain owner. */
|
|
159
|
+
readonly TransferOwnershipCpi: 69;
|
|
160
|
+
/** PERC-8111: Set per-wallet position cap (admin only, cap_e6=0 disables). */
|
|
161
|
+
readonly SetWalletCap: 70;
|
|
162
|
+
/** PERC-8110: Set OI imbalance hard-block threshold (admin only). */
|
|
163
|
+
readonly SetOiImbalanceHardBlock: 71;
|
|
164
|
+
/** PERC-8270: Rescue orphan vault — recover tokens from a closed market's vault (admin). */
|
|
165
|
+
readonly RescueOrphanVault: 72;
|
|
166
|
+
/** PERC-8270: Close orphan slab — reclaim rent from a slab whose market closed unexpectedly (admin). */
|
|
167
|
+
readonly CloseOrphanSlab: 73;
|
|
168
|
+
/** PERC-SetDexPool: Pin admin-approved DEX pool address for a HYPERP market (admin). */
|
|
169
|
+
readonly SetDexPool: 74;
|
|
170
|
+
/** CPI to the matcher program to initialize a matcher context account for an LP slot. Admin-only. */
|
|
171
|
+
readonly InitMatcherCtx: 75;
|
|
172
|
+
/** PauseMarket (tag 76): admin emergency pause. Blocks Trade/Deposit/Withdraw/InitUser. */
|
|
173
|
+
readonly PauseMarket: 76;
|
|
174
|
+
/** UnpauseMarket (tag 77): admin unpause. Re-enables all operations. */
|
|
175
|
+
readonly UnpauseMarket: 77;
|
|
176
|
+
/** CloseKeeperFund (tag 78): close keeper fund PDA and recover lamports to admin. */
|
|
177
|
+
readonly CloseKeeperFund: 78;
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* InitMarket instruction data (256 bytes total)
|
|
181
|
+
* Layout: tag(1) + admin(32) + mint(32) + indexFeedId(32) +
|
|
182
|
+
* maxStaleSecs(8) + confFilter(2) + invert(1) + unitScale(4) +
|
|
183
|
+
* RiskParams(144)
|
|
184
|
+
*
|
|
185
|
+
* Note: indexFeedId is the Pyth Pull feed ID (32 bytes hex), NOT an oracle pubkey.
|
|
186
|
+
* The program validates PriceUpdateV2 accounts against this feed ID at runtime.
|
|
187
|
+
*/
|
|
188
|
+
interface InitMarketArgs {
|
|
189
|
+
admin: PublicKey | string;
|
|
190
|
+
collateralMint: PublicKey | string;
|
|
191
|
+
indexFeedId: string;
|
|
192
|
+
maxStalenessSecs: bigint | string;
|
|
193
|
+
confFilterBps: number;
|
|
194
|
+
invert: number;
|
|
195
|
+
unitScale: number;
|
|
196
|
+
initialMarkPriceE6: bigint | string;
|
|
197
|
+
maxMaintenanceFeePerSlot?: bigint | string;
|
|
198
|
+
maxInsuranceFloor?: bigint | string;
|
|
199
|
+
minOraclePriceCap?: bigint | string;
|
|
200
|
+
warmupPeriodSlots: bigint | string;
|
|
201
|
+
maintenanceMarginBps: bigint | string;
|
|
202
|
+
initialMarginBps: bigint | string;
|
|
203
|
+
tradingFeeBps: bigint | string;
|
|
204
|
+
maxAccounts: bigint | string;
|
|
205
|
+
newAccountFee: bigint | string;
|
|
206
|
+
insuranceFloor?: bigint | string;
|
|
207
|
+
maintenanceFeePerSlot: bigint | string;
|
|
208
|
+
maxCrankStalenessSlots: bigint | string;
|
|
209
|
+
liquidationFeeBps: bigint | string;
|
|
210
|
+
liquidationFeeCap: bigint | string;
|
|
211
|
+
liquidationBufferBps?: bigint | string;
|
|
212
|
+
minLiquidationAbs: bigint | string;
|
|
213
|
+
minInitialDeposit: bigint | string;
|
|
214
|
+
minNonzeroMmReq: bigint | string;
|
|
215
|
+
minNonzeroImReq: bigint | string;
|
|
216
|
+
}
|
|
217
|
+
declare function encodeInitMarket(args: InitMarketArgs): Uint8Array;
|
|
218
|
+
/**
|
|
219
|
+
* InitUser instruction data (9 bytes)
|
|
220
|
+
*/
|
|
221
|
+
interface InitUserArgs {
|
|
222
|
+
feePayment: bigint | string;
|
|
223
|
+
}
|
|
224
|
+
declare function encodeInitUser(args: InitUserArgs): Uint8Array;
|
|
225
|
+
/**
|
|
226
|
+
* InitLP instruction data (73 bytes)
|
|
227
|
+
*/
|
|
228
|
+
interface InitLPArgs {
|
|
229
|
+
matcherProgram: PublicKey | string;
|
|
230
|
+
matcherContext: PublicKey | string;
|
|
231
|
+
feePayment: bigint | string;
|
|
232
|
+
}
|
|
233
|
+
declare function encodeInitLP(args: InitLPArgs): Uint8Array;
|
|
234
|
+
/**
|
|
235
|
+
* DepositCollateral instruction data (11 bytes)
|
|
236
|
+
*/
|
|
237
|
+
interface DepositCollateralArgs {
|
|
238
|
+
userIdx: number;
|
|
239
|
+
amount: bigint | string;
|
|
240
|
+
}
|
|
241
|
+
declare function encodeDepositCollateral(args: DepositCollateralArgs): Uint8Array;
|
|
242
|
+
/**
|
|
243
|
+
* WithdrawCollateral instruction data (11 bytes)
|
|
244
|
+
*/
|
|
245
|
+
interface WithdrawCollateralArgs {
|
|
246
|
+
userIdx: number;
|
|
247
|
+
amount: bigint | string;
|
|
248
|
+
}
|
|
249
|
+
declare function encodeWithdrawCollateral(args: WithdrawCollateralArgs): Uint8Array;
|
|
250
|
+
/**
|
|
251
|
+
* KeeperCrank instruction data (4 bytes)
|
|
252
|
+
* Funding rate is computed on-chain from LP inventory.
|
|
253
|
+
*/
|
|
254
|
+
interface KeeperCrankArgs {
|
|
255
|
+
callerIdx: number;
|
|
256
|
+
allowPanic: boolean;
|
|
257
|
+
}
|
|
258
|
+
declare function encodeKeeperCrank(args: KeeperCrankArgs): Uint8Array;
|
|
259
|
+
/**
|
|
260
|
+
* TradeNoCpi instruction data (21 bytes)
|
|
261
|
+
*/
|
|
262
|
+
interface TradeNoCpiArgs {
|
|
263
|
+
lpIdx: number;
|
|
264
|
+
userIdx: number;
|
|
265
|
+
size: bigint | string;
|
|
266
|
+
}
|
|
267
|
+
declare function encodeTradeNoCpi(args: TradeNoCpiArgs): Uint8Array;
|
|
268
|
+
/**
|
|
269
|
+
* LiquidateAtOracle instruction data (3 bytes)
|
|
270
|
+
*/
|
|
271
|
+
interface LiquidateAtOracleArgs {
|
|
272
|
+
targetIdx: number;
|
|
273
|
+
}
|
|
274
|
+
declare function encodeLiquidateAtOracle(args: LiquidateAtOracleArgs): Uint8Array;
|
|
275
|
+
/**
|
|
276
|
+
* CloseAccount instruction data (3 bytes)
|
|
277
|
+
*/
|
|
278
|
+
interface CloseAccountArgs {
|
|
279
|
+
userIdx: number;
|
|
280
|
+
}
|
|
281
|
+
declare function encodeCloseAccount(args: CloseAccountArgs): Uint8Array;
|
|
282
|
+
/**
|
|
283
|
+
* TopUpInsurance instruction data (9 bytes)
|
|
284
|
+
*/
|
|
285
|
+
interface TopUpInsuranceArgs {
|
|
286
|
+
amount: bigint | string;
|
|
287
|
+
}
|
|
288
|
+
declare function encodeTopUpInsurance(args: TopUpInsuranceArgs): Uint8Array;
|
|
289
|
+
/**
|
|
290
|
+
* TradeCpi instruction data (21 bytes)
|
|
291
|
+
*/
|
|
292
|
+
interface TradeCpiArgs {
|
|
293
|
+
lpIdx: number;
|
|
294
|
+
userIdx: number;
|
|
295
|
+
size: bigint | string;
|
|
296
|
+
}
|
|
297
|
+
declare function encodeTradeCpi(args: TradeCpiArgs): Uint8Array;
|
|
298
|
+
/**
|
|
299
|
+
* TradeCpiV2 instruction data (22 bytes) — PERC-154 optimized trade CPI.
|
|
300
|
+
*
|
|
301
|
+
* Same as TradeCpi but includes a caller-provided PDA bump byte.
|
|
302
|
+
* Uses create_program_address instead of find_program_address,
|
|
303
|
+
* saving ~1500 CU per trade. The bump should be obtained once via
|
|
304
|
+
* deriveLpPda() and cached for the lifetime of the market.
|
|
305
|
+
*/
|
|
306
|
+
interface TradeCpiV2Args {
|
|
307
|
+
lpIdx: number;
|
|
308
|
+
userIdx: number;
|
|
309
|
+
size: bigint | string;
|
|
310
|
+
bump: number;
|
|
311
|
+
}
|
|
312
|
+
declare function encodeTradeCpiV2(args: TradeCpiV2Args): Uint8Array;
|
|
313
|
+
/**
|
|
314
|
+
* SetRiskThreshold instruction data (17 bytes)
|
|
315
|
+
*/
|
|
316
|
+
interface SetRiskThresholdArgs {
|
|
317
|
+
newThreshold: bigint | string;
|
|
318
|
+
}
|
|
319
|
+
declare function encodeSetRiskThreshold(args: SetRiskThresholdArgs): Uint8Array;
|
|
320
|
+
/**
|
|
321
|
+
* UpdateAdmin instruction data (33 bytes)
|
|
322
|
+
*/
|
|
323
|
+
interface UpdateAdminArgs {
|
|
324
|
+
newAdmin: PublicKey | string;
|
|
325
|
+
}
|
|
326
|
+
declare function encodeUpdateAdmin(args: UpdateAdminArgs): Uint8Array;
|
|
327
|
+
/**
|
|
328
|
+
* CloseSlab instruction data (1 byte)
|
|
329
|
+
*/
|
|
330
|
+
declare function encodeCloseSlab(): Uint8Array;
|
|
331
|
+
/**
|
|
332
|
+
* UpdateConfig instruction data
|
|
333
|
+
* Updates funding and threshold parameters at runtime (admin only)
|
|
334
|
+
*/
|
|
335
|
+
interface UpdateConfigArgs {
|
|
336
|
+
fundingHorizonSlots: bigint | string;
|
|
337
|
+
fundingKBps: bigint | string;
|
|
338
|
+
fundingInvScaleNotionalE6: bigint | string;
|
|
339
|
+
fundingMaxPremiumBps: bigint | string;
|
|
340
|
+
fundingMaxBpsPerSlot: bigint | string;
|
|
341
|
+
threshFloor: bigint | string;
|
|
342
|
+
threshRiskBps: bigint | string;
|
|
343
|
+
threshUpdateIntervalSlots: bigint | string;
|
|
344
|
+
threshStepBps: bigint | string;
|
|
345
|
+
threshAlphaBps: bigint | string;
|
|
346
|
+
threshMin: bigint | string;
|
|
347
|
+
threshMax: bigint | string;
|
|
348
|
+
threshMinStep: bigint | string;
|
|
349
|
+
}
|
|
350
|
+
declare function encodeUpdateConfig(args: UpdateConfigArgs): Uint8Array;
|
|
351
|
+
/**
|
|
352
|
+
* SetMaintenanceFee instruction data (17 bytes)
|
|
353
|
+
*/
|
|
354
|
+
interface SetMaintenanceFeeArgs {
|
|
355
|
+
newFee: bigint | string;
|
|
356
|
+
}
|
|
357
|
+
declare function encodeSetMaintenanceFee(args: SetMaintenanceFeeArgs): Uint8Array;
|
|
358
|
+
/**
|
|
359
|
+
* SetOracleAuthority instruction data (33 bytes)
|
|
360
|
+
* Sets the oracle price authority. Pass zero pubkey to disable and require Pyth/Chainlink.
|
|
361
|
+
*/
|
|
362
|
+
interface SetOracleAuthorityArgs {
|
|
363
|
+
newAuthority: PublicKey | string;
|
|
364
|
+
}
|
|
365
|
+
declare function encodeSetOracleAuthority(args: SetOracleAuthorityArgs): Uint8Array;
|
|
366
|
+
/**
|
|
367
|
+
* PushOraclePrice instruction data (17 bytes)
|
|
368
|
+
* Push a new oracle price (oracle authority only).
|
|
369
|
+
* The price should be in e6 format and already include any inversion/scaling.
|
|
370
|
+
*/
|
|
371
|
+
interface PushOraclePriceArgs {
|
|
372
|
+
priceE6: bigint | string;
|
|
373
|
+
timestamp: bigint | string;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Encode PushOraclePrice instruction data with validation.
|
|
377
|
+
*
|
|
378
|
+
* Validates oracle price constraints:
|
|
379
|
+
* - Price cannot be zero (division by zero in on-chain engine)
|
|
380
|
+
* - Price cannot exceed MAX_ORACLE_PRICE (prevents overflow in price math)
|
|
381
|
+
*
|
|
382
|
+
* @param args - PushOraclePrice arguments
|
|
383
|
+
* @returns Encoded instruction data (17 bytes)
|
|
384
|
+
* @throws Error if price is 0 or exceeds MAX_ORACLE_PRICE
|
|
385
|
+
*/
|
|
386
|
+
declare function encodePushOraclePrice(args: PushOraclePriceArgs): Uint8Array;
|
|
387
|
+
/**
|
|
388
|
+
* SetOraclePriceCap instruction data (9 bytes)
|
|
389
|
+
* Set oracle price circuit breaker cap (admin only).
|
|
390
|
+
*
|
|
391
|
+
* max_change_e2bps: maximum oracle price movement per slot in 0.01 bps units.
|
|
392
|
+
* 1_000_000 = 100% max move per slot.
|
|
393
|
+
*
|
|
394
|
+
* ⚠️ PERC-8191 (PR#150): cap=0 is NO LONGER accepted for admin-oracle markets.
|
|
395
|
+
* - Hyperp markets: rejected if cap < DEFAULT_HYPERP_PRICE_CAP_E2BPS (1000).
|
|
396
|
+
* - Admin-oracle markets: rejected if cap == 0 (circuit breaker bypass prevention).
|
|
397
|
+
* - Pyth-pinned markets: immune (oracle_authority zeroed), any value accepted.
|
|
398
|
+
*
|
|
399
|
+
* Use a non-zero cap for all admin-oracle and Hyperp markets.
|
|
400
|
+
*/
|
|
401
|
+
interface SetOraclePriceCapArgs {
|
|
402
|
+
maxChangeE2bps: bigint | string;
|
|
403
|
+
}
|
|
404
|
+
declare function encodeSetOraclePriceCap(args: SetOraclePriceCapArgs): Uint8Array;
|
|
405
|
+
/**
|
|
406
|
+
* ResolveMarket instruction data (1 byte)
|
|
407
|
+
* Resolves a binary/premarket - sets RESOLVED flag, positions force-closed via crank.
|
|
408
|
+
* Requires admin oracle price (authority_price_e6) to be set first.
|
|
409
|
+
*/
|
|
410
|
+
declare function encodeResolveMarket(): Uint8Array;
|
|
411
|
+
/**
|
|
412
|
+
* WithdrawInsurance instruction data (1 byte)
|
|
413
|
+
* Withdraw insurance fund to admin (requires RESOLVED and all positions closed).
|
|
414
|
+
*/
|
|
415
|
+
declare function encodeWithdrawInsurance(): Uint8Array;
|
|
416
|
+
/**
|
|
417
|
+
* AdminForceClose instruction data (3 bytes)
|
|
418
|
+
* Force-close any position at oracle price (admin only, skips margin checks).
|
|
419
|
+
*/
|
|
420
|
+
interface AdminForceCloseArgs {
|
|
421
|
+
targetIdx: number;
|
|
422
|
+
}
|
|
423
|
+
declare function encodeAdminForceClose(args: AdminForceCloseArgs): Uint8Array;
|
|
424
|
+
/**
|
|
425
|
+
* UpdateRiskParams instruction data (17 or 25 bytes)
|
|
426
|
+
* Update initial and maintenance margin BPS (admin only).
|
|
427
|
+
*
|
|
428
|
+
* R2-S13: The Rust program uses `data.len() >= 25` to detect the optional
|
|
429
|
+
* tradingFeeBps field, so variable-length encoding is safe. When tradingFeeBps
|
|
430
|
+
* is omitted, the data is 17 bytes (tag + 2×u64). When included, 25 bytes.
|
|
431
|
+
*/
|
|
432
|
+
interface UpdateRiskParamsArgs {
|
|
433
|
+
initialMarginBps: bigint | string;
|
|
434
|
+
maintenanceMarginBps: bigint | string;
|
|
435
|
+
tradingFeeBps?: bigint | string;
|
|
436
|
+
}
|
|
437
|
+
declare function encodeUpdateRiskParams(args: UpdateRiskParamsArgs): Uint8Array;
|
|
438
|
+
/**
|
|
439
|
+
* On-chain confirmation code for RenounceAdmin (must match program constant).
|
|
440
|
+
* ASCII "RENOUNCE" as u64 LE = 0x52454E4F554E4345.
|
|
441
|
+
*/
|
|
442
|
+
declare const RENOUNCE_ADMIN_CONFIRMATION = 5928230587143701317n;
|
|
443
|
+
/**
|
|
444
|
+
* On-chain confirmation code for UnresolveMarket (must match program constant).
|
|
445
|
+
*/
|
|
446
|
+
declare const UNRESOLVE_CONFIRMATION = 16045690984503054900n;
|
|
447
|
+
/**
|
|
448
|
+
* RenounceAdmin instruction data (9 bytes)
|
|
449
|
+
* Irreversibly set admin to all zeros. After this, all admin-only instructions fail.
|
|
450
|
+
*
|
|
451
|
+
* Requires the confirmation code 0x52454E4F554E4345 ("RENOUNCE" as u64 LE)
|
|
452
|
+
* to prevent accidental invocation.
|
|
453
|
+
*/
|
|
454
|
+
declare function encodeRenounceAdmin(): Uint8Array;
|
|
455
|
+
/**
|
|
456
|
+
* LpVaultWithdraw (Tag 39, PERC-627 / GH#1926 / PERC-8287) — burn LP vault tokens and
|
|
457
|
+
* withdraw proportional collateral.
|
|
458
|
+
*
|
|
459
|
+
* **BREAKING (PR#170):** accounts[9] = creatorLockPda is now REQUIRED.
|
|
460
|
+
* Always include `deriveCreatorLockPda(programId, slab)` at position 9.
|
|
461
|
+
* Non-creator withdrawers pass the derived PDA; if no lock exists on-chain
|
|
462
|
+
* the check is a no-op. Omitting this account causes `ExpectLenFailed` on-chain.
|
|
463
|
+
*
|
|
464
|
+
* Instruction data: tag(1) + lp_amount(8) = 9 bytes
|
|
465
|
+
*
|
|
466
|
+
* Accounts (use ACCOUNTS_LP_VAULT_WITHDRAW):
|
|
467
|
+
* [0] withdrawer signer
|
|
468
|
+
* [1] slab writable
|
|
469
|
+
* [2] withdrawerAta writable
|
|
470
|
+
* [3] vault writable
|
|
471
|
+
* [4] tokenProgram
|
|
472
|
+
* [5] lpVaultMint writable
|
|
473
|
+
* [6] withdrawerLpAta writable
|
|
474
|
+
* [7] vaultAuthority
|
|
475
|
+
* [8] lpVaultState writable
|
|
476
|
+
* [9] creatorLockPda writable ← derive with deriveCreatorLockPda(programId, slab)
|
|
477
|
+
*
|
|
478
|
+
* @param lpAmount - Amount of LP vault tokens to burn.
|
|
479
|
+
*
|
|
480
|
+
* @example
|
|
481
|
+
* ```ts
|
|
482
|
+
* import { encodeLpVaultWithdraw, ACCOUNTS_LP_VAULT_WITHDRAW, buildAccountMetas } from "@percolator/sdk";
|
|
483
|
+
* import { deriveCreatorLockPda, deriveVaultAuthority } from "@percolator/sdk";
|
|
484
|
+
*
|
|
485
|
+
* const [creatorLockPda] = deriveCreatorLockPda(PROGRAM_ID, slabKey);
|
|
486
|
+
* const [vaultAuthority] = deriveVaultAuthority(PROGRAM_ID, slabKey);
|
|
487
|
+
*
|
|
488
|
+
* const data = encodeLpVaultWithdraw({ lpAmount: 1_000_000_000n });
|
|
489
|
+
* const keys = buildAccountMetas(ACCOUNTS_LP_VAULT_WITHDRAW, {
|
|
490
|
+
* withdrawer, slab: slabKey, withdrawerAta, vault, tokenProgram: TOKEN_PROGRAM_ID,
|
|
491
|
+
* lpVaultMint, withdrawerLpAta, vaultAuthority, lpVaultState, creatorLockPda,
|
|
492
|
+
* });
|
|
493
|
+
* ```
|
|
494
|
+
*/
|
|
495
|
+
interface LpVaultWithdrawArgs {
|
|
496
|
+
/** Amount of LP vault tokens to burn. */
|
|
497
|
+
lpAmount: bigint | string;
|
|
498
|
+
}
|
|
499
|
+
declare function encodeLpVaultWithdraw(args: LpVaultWithdrawArgs): Uint8Array;
|
|
500
|
+
/**
|
|
501
|
+
* PauseMarket instruction data (1 byte)
|
|
502
|
+
* Pauses the market — disables trading, deposits, and withdrawals.
|
|
503
|
+
*/
|
|
504
|
+
declare function encodePauseMarket(): Uint8Array;
|
|
505
|
+
/**
|
|
506
|
+
* UnpauseMarket instruction data (1 byte)
|
|
507
|
+
* Unpauses the market — re-enables trading, deposits, and withdrawals.
|
|
508
|
+
*/
|
|
509
|
+
declare function encodeUnpauseMarket(): Uint8Array;
|
|
510
|
+
/**
|
|
511
|
+
* SetPythOracle (Tag 32) — switch a market to Pyth-pinned mode.
|
|
512
|
+
*
|
|
513
|
+
* After this instruction:
|
|
514
|
+
* - oracle_authority is cleared → PushOraclePrice is disabled
|
|
515
|
+
* - index_feed_id is set to feed_id → validated on every price read
|
|
516
|
+
* - max_staleness_secs and conf_filter_bps are updated
|
|
517
|
+
* - All price reads go directly to read_pyth_price_e6() with on-chain
|
|
518
|
+
* staleness + confidence + feed-ID validation (no silent fallback)
|
|
519
|
+
*
|
|
520
|
+
* Instruction data: tag(1) + feed_id(32) + max_staleness_secs(8) + conf_filter_bps(2) = 43 bytes
|
|
521
|
+
*
|
|
522
|
+
* Accounts:
|
|
523
|
+
* 0. [signer, writable] Admin
|
|
524
|
+
* 1. [writable] Slab
|
|
525
|
+
*/
|
|
526
|
+
interface SetPythOracleArgs {
|
|
527
|
+
/** 32-byte Pyth feed ID. All zeros is invalid (reserved for Hyperp mode). */
|
|
528
|
+
feedId: Uint8Array;
|
|
529
|
+
/** Maximum age of Pyth price in seconds before OracleStale is returned. Must be > 0. */
|
|
530
|
+
maxStalenessSecs: bigint;
|
|
531
|
+
/** Max confidence/price ratio in bps (0 = no confidence check). */
|
|
532
|
+
confFilterBps: number;
|
|
533
|
+
}
|
|
534
|
+
declare function encodeSetPythOracle(args: SetPythOracleArgs): Uint8Array;
|
|
535
|
+
/**
|
|
536
|
+
* Derive the expected Pyth PriceUpdateV2 account address for a given feed ID.
|
|
537
|
+
* Uses PDA seeds: [shard_id(2), feed_id(32)] under the Pyth Receiver program.
|
|
538
|
+
*
|
|
539
|
+
* @param feedId 32-byte Pyth feed ID
|
|
540
|
+
* @param shardId Shard index (default 0 for mainnet/devnet)
|
|
541
|
+
*/
|
|
542
|
+
declare const PYTH_RECEIVER_PROGRAM_ID = "rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ";
|
|
543
|
+
declare function derivePythPriceUpdateAccount(feedId: Uint8Array, shardId?: number): Promise<string>;
|
|
544
|
+
/**
|
|
545
|
+
* UpdateMarkPrice (Tag 33) — permissionless EMA mark price crank.
|
|
546
|
+
*
|
|
547
|
+
* Reads the current oracle price on-chain, applies 8-hour EMA smoothing
|
|
548
|
+
* with circuit breaker, and writes result to authority_price_e6.
|
|
549
|
+
*
|
|
550
|
+
* Instruction data: 1 byte (tag only — all params read from on-chain state)
|
|
551
|
+
*
|
|
552
|
+
* Accounts:
|
|
553
|
+
* 0. [writable] Slab
|
|
554
|
+
* 1. [] Oracle account (Pyth PriceUpdateV2 / Chainlink / DEX AMM)
|
|
555
|
+
* 2. [] Clock sysvar (SysvarC1ock11111111111111111111111111111111)
|
|
556
|
+
* 3..N [] Remaining accounts (PumpSwap vaults, etc. if needed)
|
|
557
|
+
*/
|
|
558
|
+
declare function encodeUpdateMarkPrice(): Uint8Array;
|
|
559
|
+
/**
|
|
560
|
+
* Mark price EMA parameters (must match program/src/percolator.rs constants).
|
|
561
|
+
*/
|
|
562
|
+
declare const MARK_PRICE_EMA_WINDOW_SLOTS = 72000n;
|
|
563
|
+
declare const MARK_PRICE_EMA_ALPHA_E6: bigint;
|
|
564
|
+
/**
|
|
565
|
+
* Compute the next EMA mark price step (TypeScript mirror of the on-chain function).
|
|
566
|
+
*/
|
|
567
|
+
declare function computeEmaMarkPrice(markPrevE6: bigint, oracleE6: bigint, dtSlots: bigint, alphaE6?: bigint, capE2bps?: bigint): bigint;
|
|
568
|
+
/**
|
|
569
|
+
* UpdateHyperpMark (Tag 34) — permissionless Hyperp EMA oracle crank.
|
|
570
|
+
*
|
|
571
|
+
* Reads the spot price from a PumpSwap, Raydium CLMM, or Meteora DLMM pool,
|
|
572
|
+
* applies 8-hour EMA smoothing with circuit breaker, and writes the new mark
|
|
573
|
+
* to authority_price_e6 on the slab.
|
|
574
|
+
*
|
|
575
|
+
* This is the core mechanism for permissionless token markets — no Pyth or
|
|
576
|
+
* Chainlink feed is needed. The DEX AMM IS the oracle.
|
|
577
|
+
*
|
|
578
|
+
* Instruction data: 1 byte (tag only)
|
|
579
|
+
*
|
|
580
|
+
* Accounts:
|
|
581
|
+
* 0. [writable] Slab
|
|
582
|
+
* 1. [] DEX pool account (PumpSwap / Raydium CLMM / Meteora DLMM)
|
|
583
|
+
* 2. [] Clock sysvar (SysvarC1ock11111111111111111111111111111111)
|
|
584
|
+
* 3..N [] Remaining accounts (e.g. PumpSwap vault0 + vault1)
|
|
585
|
+
*/
|
|
586
|
+
declare function encodeUpdateHyperpMark(): Uint8Array;
|
|
587
|
+
/**
|
|
588
|
+
* Fund per-market isolated insurance balance.
|
|
589
|
+
* Accounts: [admin(signer,writable), slab(writable), admin_ata(writable), vault(writable), token_program]
|
|
590
|
+
*/
|
|
591
|
+
declare function encodeFundMarketInsurance(args: {
|
|
592
|
+
amount: bigint;
|
|
593
|
+
}): Uint8Array;
|
|
594
|
+
/**
|
|
595
|
+
* Set insurance isolation BPS for a market.
|
|
596
|
+
* Accounts: [admin(signer), slab(writable)]
|
|
597
|
+
*/
|
|
598
|
+
declare function encodeSetInsuranceIsolation(args: {
|
|
599
|
+
bps: number;
|
|
600
|
+
}): Uint8Array;
|
|
601
|
+
/**
|
|
602
|
+
* QueueWithdrawal (Tag 47, PERC-309) — queue a large LP withdrawal.
|
|
603
|
+
*
|
|
604
|
+
* Creates a withdraw_queue PDA. The LP tokens are claimed in epoch tranches
|
|
605
|
+
* via ClaimQueuedWithdrawal. Call CancelQueuedWithdrawal to abort.
|
|
606
|
+
*
|
|
607
|
+
* Accounts: [user(signer,writable), slab(writable), lpVaultState, withdrawQueue(writable), systemProgram]
|
|
608
|
+
*
|
|
609
|
+
* @param lpAmount - Amount of LP tokens to queue for withdrawal.
|
|
610
|
+
*
|
|
611
|
+
* @example
|
|
612
|
+
* ```ts
|
|
613
|
+
* const data = encodeQueueWithdrawal({ lpAmount: 1_000_000_000n });
|
|
614
|
+
* ```
|
|
615
|
+
*/
|
|
616
|
+
declare function encodeQueueWithdrawal(args: {
|
|
617
|
+
lpAmount: bigint | string;
|
|
618
|
+
}): Uint8Array;
|
|
619
|
+
/**
|
|
620
|
+
* ClaimQueuedWithdrawal (Tag 48, PERC-309) — claim one epoch tranche from a queued withdrawal.
|
|
621
|
+
*
|
|
622
|
+
* Burns LP tokens and releases one tranche of SOL to the user.
|
|
623
|
+
* Call once per epoch until epochs_remaining == 0.
|
|
624
|
+
*
|
|
625
|
+
* Accounts: [user(signer,writable), slab(writable), withdrawQueue(writable),
|
|
626
|
+
* lpVaultMint(writable), userLpAta(writable), vault(writable),
|
|
627
|
+
* userAta(writable), vaultAuthority, tokenProgram, lpVaultState(writable)]
|
|
628
|
+
*/
|
|
629
|
+
declare function encodeClaimQueuedWithdrawal(): Uint8Array;
|
|
630
|
+
/**
|
|
631
|
+
* CancelQueuedWithdrawal (Tag 49, PERC-309) — cancel a queued withdrawal, refund remaining LP.
|
|
632
|
+
*
|
|
633
|
+
* Closes the withdraw_queue PDA and returns its rent lamports to the user.
|
|
634
|
+
* The queued LP amount that was not yet claimed is NOT refunded — it is burned.
|
|
635
|
+
* Use only to abandon a partial withdrawal.
|
|
636
|
+
*
|
|
637
|
+
* Accounts: [user(signer,writable), slab, withdrawQueue(writable)]
|
|
638
|
+
*/
|
|
639
|
+
declare function encodeCancelQueuedWithdrawal(): Uint8Array;
|
|
640
|
+
/**
|
|
641
|
+
* ExecuteAdl (Tag 50, PERC-305) — auto-deleverage the most profitable position.
|
|
642
|
+
*
|
|
643
|
+
* Permissionless. Surgically closes or reduces `targetIdx` position when
|
|
644
|
+
* `pnl_pos_tot > max_pnl_cap` on the market. The caller receives no reward —
|
|
645
|
+
* the incentive is unblocking the market for normal trading.
|
|
646
|
+
*
|
|
647
|
+
* Requires `UpdateRiskParams.max_pnl_cap > 0` on the market.
|
|
648
|
+
*
|
|
649
|
+
* Accounts: [caller(signer), slab(writable), clock, oracle, ...backupOracles?]
|
|
650
|
+
*
|
|
651
|
+
* @param targetIdx - Account index of the position to deleverage.
|
|
652
|
+
*
|
|
653
|
+
* @example
|
|
654
|
+
* ```ts
|
|
655
|
+
* const data = encodeExecuteAdl({ targetIdx: 5 });
|
|
656
|
+
* ```
|
|
657
|
+
*/
|
|
658
|
+
interface ExecuteAdlArgs {
|
|
659
|
+
targetIdx: number;
|
|
660
|
+
}
|
|
661
|
+
declare function encodeExecuteAdl(args: ExecuteAdlArgs): Uint8Array;
|
|
662
|
+
/**
|
|
663
|
+
* CloseStaleSlabs (Tag 51) — close a slab of an invalid/old layout and recover rent SOL.
|
|
664
|
+
*
|
|
665
|
+
* Admin only. Skips slab_guard; validates header magic + admin authority instead.
|
|
666
|
+
* Use for slabs created by old program layouts (e.g. pre-PERC-120 devnet deploys)
|
|
667
|
+
* whose size does not match any current valid tier.
|
|
668
|
+
*
|
|
669
|
+
* Accounts: [dest(signer,writable), slab(writable)]
|
|
670
|
+
*/
|
|
671
|
+
declare function encodeCloseStaleSlabs(): Uint8Array;
|
|
672
|
+
/**
|
|
673
|
+
* ReclaimSlabRent (Tag 52) — reclaim rent from an uninitialised slab.
|
|
674
|
+
*
|
|
675
|
+
* For use when market creation failed mid-flow (slab funded but InitMarket not called).
|
|
676
|
+
* The slab account must sign (proves the caller holds the slab keypair).
|
|
677
|
+
* Cannot close an initialised slab (magic == PERCOLAT) — use CloseSlab (tag 13).
|
|
678
|
+
*
|
|
679
|
+
* Accounts: [dest(signer,writable), slab(signer,writable)]
|
|
680
|
+
*/
|
|
681
|
+
declare function encodeReclaimSlabRent(): Uint8Array;
|
|
682
|
+
/**
|
|
683
|
+
* AuditCrank (Tag 53) — verify conservation invariants on-chain (permissionless).
|
|
684
|
+
*
|
|
685
|
+
* Walks all accounts and verifies: capital sum, pnl_pos_tot, total_oi, LP consistency,
|
|
686
|
+
* and solvency. Sets FLAG_PAUSED on violation (with a 150-slot cooldown guard to
|
|
687
|
+
* prevent DoS from transient failures).
|
|
688
|
+
*
|
|
689
|
+
* Accounts: [slab(writable)]
|
|
690
|
+
*
|
|
691
|
+
* @example
|
|
692
|
+
* ```ts
|
|
693
|
+
* const data = encodeAuditCrank();
|
|
694
|
+
* ```
|
|
695
|
+
*/
|
|
696
|
+
declare function encodeAuditCrank(): Uint8Array;
|
|
697
|
+
/**
|
|
698
|
+
* Parsed vAMM matcher parameters (from on-chain matcher context account)
|
|
699
|
+
*/
|
|
700
|
+
interface VammMatcherParams {
|
|
701
|
+
mode: number;
|
|
702
|
+
tradingFeeBps: number;
|
|
703
|
+
baseSpreadBps: number;
|
|
704
|
+
maxTotalBps: number;
|
|
705
|
+
impactKBps: number;
|
|
706
|
+
liquidityNotionalE6: bigint;
|
|
707
|
+
}
|
|
708
|
+
/** Magic bytes identifying a vAMM matcher context: "PERCMATC" as u64 LE */
|
|
709
|
+
declare const VAMM_MAGIC = 5784119745439683651n;
|
|
710
|
+
/** Offset into matcher context where vAMM params start */
|
|
711
|
+
declare const CTX_VAMM_OFFSET = 64;
|
|
712
|
+
/**
|
|
713
|
+
* Compute execution price for a given LP quote.
|
|
714
|
+
* For buys (isLong=true): price above oracle.
|
|
715
|
+
* For sells (isLong=false): price below oracle.
|
|
716
|
+
*/
|
|
717
|
+
declare function computeVammQuote(params: VammMatcherParams, oraclePriceE6: bigint, tradeSize: bigint, isLong: boolean): bigint;
|
|
718
|
+
/**
|
|
719
|
+
* AdvanceOraclePhase (Tag 56) — permissionless oracle phase advancement.
|
|
720
|
+
*
|
|
721
|
+
* Checks if a market should transition from Phase 0→1→2 based on
|
|
722
|
+
* time elapsed and cumulative volume. Anyone can call this.
|
|
723
|
+
*
|
|
724
|
+
* Instruction data: 1 byte (tag only)
|
|
725
|
+
*
|
|
726
|
+
* Accounts:
|
|
727
|
+
* 0. [writable] Slab
|
|
728
|
+
*/
|
|
729
|
+
declare function encodeAdvanceOraclePhase(): Uint8Array;
|
|
730
|
+
/** Oracle phase constants matching on-chain values */
|
|
731
|
+
declare const ORACLE_PHASE_NASCENT = 0;
|
|
732
|
+
declare const ORACLE_PHASE_GROWING = 1;
|
|
733
|
+
declare const ORACLE_PHASE_MATURE = 2;
|
|
734
|
+
/** Phase transition thresholds (must match program constants) */
|
|
735
|
+
declare const PHASE1_MIN_SLOTS = 648000n;
|
|
736
|
+
declare const PHASE1_VOLUME_MIN_SLOTS = 36000n;
|
|
737
|
+
declare const PHASE2_VOLUME_THRESHOLD = 100000000000n;
|
|
738
|
+
declare const PHASE2_MATURITY_SLOTS = 3024000n;
|
|
739
|
+
/**
|
|
740
|
+
* Check if an oracle phase transition is due (TypeScript mirror of on-chain logic).
|
|
741
|
+
*
|
|
742
|
+
* @returns [newPhase, shouldTransition]
|
|
743
|
+
*/
|
|
744
|
+
declare function checkPhaseTransition(currentSlot: bigint, marketCreatedSlot: bigint, oraclePhase: number, cumulativeVolumeE6: bigint, phase2DeltaSlots: number, hasMatureOracle: boolean): [number, boolean];
|
|
745
|
+
/**
|
|
746
|
+
* TopUpKeeperFund (Tag 57) — permissionless keeper fund top-up.
|
|
747
|
+
*
|
|
748
|
+
* Instruction data: tag(1) + amount(8) = 9 bytes
|
|
749
|
+
*
|
|
750
|
+
* Accounts:
|
|
751
|
+
* 0. [signer, writable] Funder
|
|
752
|
+
* 1. [writable] Slab
|
|
753
|
+
* 2. [writable] Keeper fund PDA
|
|
754
|
+
* 3. [] System program
|
|
755
|
+
*/
|
|
756
|
+
interface TopUpKeeperFundArgs {
|
|
757
|
+
amount: bigint | string;
|
|
758
|
+
}
|
|
759
|
+
declare function encodeTopUpKeeperFund(args: TopUpKeeperFundArgs): Uint8Array;
|
|
760
|
+
/**
|
|
761
|
+
* SlashCreationDeposit (Tag 58) — permissionless: slash a market creator's deposit
|
|
762
|
+
* after the spam grace period has elapsed (PERC-629).
|
|
763
|
+
*
|
|
764
|
+
* **WARNING**: Tag 58 is reserved in tags.rs but has NO instruction decoder or
|
|
765
|
+
* handler in the on-chain program. Sending this instruction will fail with
|
|
766
|
+
* `InvalidInstructionData`. Do not use until the on-chain handler is deployed.
|
|
767
|
+
*
|
|
768
|
+
* Instruction data: 1 byte (tag only)
|
|
769
|
+
*
|
|
770
|
+
* Accounts:
|
|
771
|
+
* 0. [signer] Caller (anyone)
|
|
772
|
+
* 1. [] Slab
|
|
773
|
+
* 2. [writable] Creator history PDA
|
|
774
|
+
* 3. [writable] Insurance vault
|
|
775
|
+
* 4. [writable] Treasury
|
|
776
|
+
* 5. [] System program
|
|
777
|
+
*
|
|
778
|
+
* @deprecated Not yet implemented on-chain — will fail with InvalidInstructionData.
|
|
779
|
+
*/
|
|
780
|
+
declare function encodeSlashCreationDeposit(): Uint8Array;
|
|
781
|
+
/**
|
|
782
|
+
* InitSharedVault (Tag 59) — admin: create the global shared vault PDA (PERC-628).
|
|
783
|
+
*
|
|
784
|
+
* Instruction data: tag(1) + epochDurationSlots(8) + maxMarketExposureBps(2) = 11 bytes
|
|
785
|
+
*
|
|
786
|
+
* Accounts:
|
|
787
|
+
* 0. [signer] Admin
|
|
788
|
+
* 1. [writable] Shared vault PDA
|
|
789
|
+
* 2. [] System program
|
|
790
|
+
*/
|
|
791
|
+
interface InitSharedVaultArgs {
|
|
792
|
+
epochDurationSlots: bigint | string;
|
|
793
|
+
maxMarketExposureBps: number;
|
|
794
|
+
}
|
|
795
|
+
declare function encodeInitSharedVault(args: InitSharedVaultArgs): Uint8Array;
|
|
796
|
+
/**
|
|
797
|
+
* AllocateMarket (Tag 60) — admin: allocate virtual liquidity from the shared vault
|
|
798
|
+
* to a market (PERC-628).
|
|
799
|
+
*
|
|
800
|
+
* Instruction data: tag(1) + amount(16) = 17 bytes
|
|
801
|
+
*
|
|
802
|
+
* Accounts:
|
|
803
|
+
* 0. [signer] Admin
|
|
804
|
+
* 1. [] Slab
|
|
805
|
+
* 2. [writable] Shared vault PDA
|
|
806
|
+
* 3. [writable] Market alloc PDA
|
|
807
|
+
* 4. [] System program
|
|
808
|
+
*/
|
|
809
|
+
interface AllocateMarketArgs {
|
|
810
|
+
amount: bigint | string;
|
|
811
|
+
}
|
|
812
|
+
declare function encodeAllocateMarket(args: AllocateMarketArgs): Uint8Array;
|
|
813
|
+
/**
|
|
814
|
+
* QueueWithdrawalSV (Tag 61) — user: queue a withdrawal request for the current
|
|
815
|
+
* epoch (PERC-628). Tokens are locked until the epoch elapses.
|
|
816
|
+
*
|
|
817
|
+
* Instruction data: tag(1) + lpAmount(8) = 9 bytes
|
|
818
|
+
*
|
|
819
|
+
* Accounts:
|
|
820
|
+
* 0. [signer] User
|
|
821
|
+
* 1. [writable] Shared vault PDA
|
|
822
|
+
* 2. [writable] Withdraw request PDA
|
|
823
|
+
* 3. [] System program
|
|
824
|
+
*/
|
|
825
|
+
interface QueueWithdrawalSVArgs {
|
|
826
|
+
lpAmount: bigint | string;
|
|
827
|
+
}
|
|
828
|
+
declare function encodeQueueWithdrawalSV(args: QueueWithdrawalSVArgs): Uint8Array;
|
|
829
|
+
/**
|
|
830
|
+
* ClaimEpochWithdrawal (Tag 62) — user: claim a queued withdrawal after the epoch
|
|
831
|
+
* has elapsed (PERC-628). Receives pro-rata collateral from the vault.
|
|
832
|
+
*
|
|
833
|
+
* Instruction data: 1 byte (tag only)
|
|
834
|
+
*
|
|
835
|
+
* Accounts:
|
|
836
|
+
* 0. [signer] User
|
|
837
|
+
* 1. [writable] Shared vault PDA
|
|
838
|
+
* 2. [writable] Withdraw request PDA
|
|
839
|
+
* 3. [] Slab
|
|
840
|
+
* 4. [writable] Vault
|
|
841
|
+
* 5. [writable] User ATA
|
|
842
|
+
* 6. [] Vault authority
|
|
843
|
+
* 7. [] Token program
|
|
844
|
+
*/
|
|
845
|
+
declare function encodeClaimEpochWithdrawal(): Uint8Array;
|
|
846
|
+
/**
|
|
847
|
+
* AdvanceEpoch (Tag 63) — permissionless crank: move the shared vault to the next
|
|
848
|
+
* epoch once `epoch_duration_slots` have elapsed (PERC-628).
|
|
849
|
+
*
|
|
850
|
+
* Instruction data: 1 byte (tag only)
|
|
851
|
+
*
|
|
852
|
+
* Accounts:
|
|
853
|
+
* 0. [signer] Caller (anyone)
|
|
854
|
+
* 1. [writable] Shared vault PDA
|
|
855
|
+
*/
|
|
856
|
+
declare function encodeAdvanceEpoch(): Uint8Array;
|
|
857
|
+
/**
|
|
858
|
+
* SetOiImbalanceHardBlock (Tag 71, PERC-8110) — set OI imbalance hard-block threshold (admin only).
|
|
859
|
+
*
|
|
860
|
+
* When `|long_oi − short_oi| / total_oi * 10_000 >= threshold_bps`, any new trade that would
|
|
861
|
+
* *increase* the imbalance is rejected with `OiImbalanceHardBlock` (error code 59).
|
|
862
|
+
*
|
|
863
|
+
* - `threshold_bps = 0`: hard block disabled.
|
|
864
|
+
* - `threshold_bps = 8_000`: block trades that push skew above 80%.
|
|
865
|
+
* - `threshold_bps = 10_000`: never allow >100% skew (always blocks one side when oi > 0).
|
|
866
|
+
*
|
|
867
|
+
* Instruction data layout: tag(1) + threshold_bps(2) = 3 bytes
|
|
868
|
+
*
|
|
869
|
+
* Accounts:
|
|
870
|
+
* 0. [signer] admin
|
|
871
|
+
* 1. [writable] slab
|
|
872
|
+
*
|
|
873
|
+
* @example
|
|
874
|
+
* ```ts
|
|
875
|
+
* const ix = new TransactionInstruction({
|
|
876
|
+
* programId: PROGRAM_ID,
|
|
877
|
+
* keys: buildAccountMetas(ACCOUNTS_SET_OI_IMBALANCE_HARD_BLOCK, { admin, slab }),
|
|
878
|
+
* data: Buffer.from(encodeSetOiImbalanceHardBlock({ thresholdBps: 8_000 })),
|
|
879
|
+
* });
|
|
880
|
+
* ```
|
|
881
|
+
*/
|
|
882
|
+
declare function encodeSetOiImbalanceHardBlock(args: {
|
|
883
|
+
thresholdBps: number;
|
|
884
|
+
}): Uint8Array;
|
|
885
|
+
/**
|
|
886
|
+
* MintPositionNft (Tag 64, PERC-608) — mint a Token-2022 NFT representing a position.
|
|
887
|
+
*
|
|
888
|
+
* Creates a PositionNft PDA + Token-2022 mint with metadata, then mints 1 NFT to the
|
|
889
|
+
* position owner's ATA. The NFT represents ownership of `user_idx` in the slab.
|
|
890
|
+
*
|
|
891
|
+
* Instruction data layout: tag(1) + user_idx(2) = 3 bytes
|
|
892
|
+
*
|
|
893
|
+
* Accounts:
|
|
894
|
+
* 0. [signer, writable] payer
|
|
895
|
+
* 1. [writable] slab
|
|
896
|
+
* 2. [writable] position_nft PDA (created — seeds: ["position_nft", slab, user_idx])
|
|
897
|
+
* 3. [writable] nft_mint PDA (created)
|
|
898
|
+
* 4. [writable] owner_ata (Token-2022 ATA for owner)
|
|
899
|
+
* 5. [signer] owner (must match engine account owner)
|
|
900
|
+
* 6. [] vault_authority PDA
|
|
901
|
+
* 7. [] token_2022_program
|
|
902
|
+
* 8. [] system_program
|
|
903
|
+
* 9. [] rent sysvar
|
|
904
|
+
*
|
|
905
|
+
* @example
|
|
906
|
+
* ```ts
|
|
907
|
+
* const ix = new TransactionInstruction({
|
|
908
|
+
* programId: PROGRAM_ID,
|
|
909
|
+
* keys: buildAccountMetas(ACCOUNTS_MINT_POSITION_NFT, [payer, slab, nftPda, nftMint, ownerAta, owner, vaultAuth, TOKEN_2022_PROGRAM_ID, SystemProgram.programId, SYSVAR_RENT_PUBKEY]),
|
|
910
|
+
* data: Buffer.from(encodeMintPositionNft({ userIdx: 5 })),
|
|
911
|
+
* });
|
|
912
|
+
* ```
|
|
913
|
+
*/
|
|
914
|
+
interface MintPositionNftArgs {
|
|
915
|
+
userIdx: number;
|
|
916
|
+
}
|
|
917
|
+
declare function encodeMintPositionNft(args: MintPositionNftArgs): Uint8Array;
|
|
918
|
+
/**
|
|
919
|
+
* TransferPositionOwnership (Tag 65, PERC-608) — transfer an open position to a new owner.
|
|
920
|
+
*
|
|
921
|
+
* Transfers the Token-2022 NFT from current owner to new owner and updates the on-chain
|
|
922
|
+
* engine account's owner field. Requires `pending_settlement == 0`.
|
|
923
|
+
*
|
|
924
|
+
* Instruction data layout: tag(1) + user_idx(2) = 3 bytes
|
|
925
|
+
*
|
|
926
|
+
* Accounts:
|
|
927
|
+
* 0. [signer, writable] current_owner
|
|
928
|
+
* 1. [writable] slab
|
|
929
|
+
* 2. [writable] position_nft PDA
|
|
930
|
+
* 3. [writable] nft_mint PDA
|
|
931
|
+
* 4. [writable] current_owner_ata (source Token-2022 ATA)
|
|
932
|
+
* 5. [writable] new_owner_ata (destination Token-2022 ATA)
|
|
933
|
+
* 6. [] new_owner
|
|
934
|
+
* 7. [] token_2022_program
|
|
935
|
+
*/
|
|
936
|
+
interface TransferPositionOwnershipArgs {
|
|
937
|
+
userIdx: number;
|
|
938
|
+
}
|
|
939
|
+
declare function encodeTransferPositionOwnership(args: TransferPositionOwnershipArgs): Uint8Array;
|
|
940
|
+
/**
|
|
941
|
+
* BurnPositionNft (Tag 66, PERC-608) — burn the Position NFT when a position is closed.
|
|
942
|
+
*
|
|
943
|
+
* Burns the NFT, closes the PositionNft PDA and the mint PDA, returning rent to the owner.
|
|
944
|
+
* Can only be called after the position is fully closed (size == 0).
|
|
945
|
+
*
|
|
946
|
+
* Instruction data layout: tag(1) + user_idx(2) = 3 bytes
|
|
947
|
+
*
|
|
948
|
+
* Accounts:
|
|
949
|
+
* 0. [signer, writable] owner
|
|
950
|
+
* 1. [writable] slab
|
|
951
|
+
* 2. [writable] position_nft PDA (closed — rent to owner)
|
|
952
|
+
* 3. [writable] nft_mint PDA (closed via Token-2022 close_account)
|
|
953
|
+
* 4. [writable] owner_ata (Token-2022 ATA, balance burned)
|
|
954
|
+
* 5. [] vault_authority PDA
|
|
955
|
+
* 6. [] token_2022_program
|
|
956
|
+
*/
|
|
957
|
+
interface BurnPositionNftArgs {
|
|
958
|
+
userIdx: number;
|
|
959
|
+
}
|
|
960
|
+
declare function encodeBurnPositionNft(args: BurnPositionNftArgs): Uint8Array;
|
|
961
|
+
/**
|
|
962
|
+
* SetPendingSettlement (Tag 67, PERC-608) — keeper sets the pending_settlement flag.
|
|
963
|
+
*
|
|
964
|
+
* Called by the keeper/admin before performing a funding settlement transfer.
|
|
965
|
+
* Blocks NFT transfers until ClearPendingSettlement is called.
|
|
966
|
+
* Admin-only (protected by GH#1475 keeper allowlist guard).
|
|
967
|
+
*
|
|
968
|
+
* Instruction data layout: tag(1) + user_idx(2) = 3 bytes
|
|
969
|
+
*
|
|
970
|
+
* Accounts:
|
|
971
|
+
* 0. [signer] keeper / admin
|
|
972
|
+
* 1. [] slab (read — for PDA verification + admin check)
|
|
973
|
+
* 2. [writable] position_nft PDA
|
|
974
|
+
*/
|
|
975
|
+
interface SetPendingSettlementArgs {
|
|
976
|
+
userIdx: number;
|
|
977
|
+
}
|
|
978
|
+
declare function encodeSetPendingSettlement(args: SetPendingSettlementArgs): Uint8Array;
|
|
979
|
+
/**
|
|
980
|
+
* ClearPendingSettlement (Tag 68, PERC-608) — keeper clears the pending_settlement flag.
|
|
981
|
+
*
|
|
982
|
+
* Called by the keeper/admin after KeeperCrank has run and funding is settled.
|
|
983
|
+
* Admin-only (protected by GH#1475 keeper allowlist guard).
|
|
984
|
+
*
|
|
985
|
+
* Instruction data layout: tag(1) + user_idx(2) = 3 bytes
|
|
986
|
+
*
|
|
987
|
+
* Accounts:
|
|
988
|
+
* 0. [signer] keeper / admin
|
|
989
|
+
* 1. [] slab (read — for PDA verification + admin check)
|
|
990
|
+
* 2. [writable] position_nft PDA
|
|
991
|
+
*/
|
|
992
|
+
interface ClearPendingSettlementArgs {
|
|
993
|
+
userIdx: number;
|
|
994
|
+
}
|
|
995
|
+
declare function encodeClearPendingSettlement(args: ClearPendingSettlementArgs): Uint8Array;
|
|
996
|
+
/**
|
|
997
|
+
* TransferOwnershipCpi (Tag 69, PERC-608) — internal CPI target for percolator-nft TransferHook.
|
|
998
|
+
*
|
|
999
|
+
* Called by the Token-2022 TransferHook on the percolator-nft program during an NFT transfer.
|
|
1000
|
+
* Updates the engine account's owner field to the new_owner public key.
|
|
1001
|
+
* NOT intended for direct external use — always called via Token-2022 CPI.
|
|
1002
|
+
*
|
|
1003
|
+
* Instruction data layout: tag(1) + user_idx(2) + new_owner(32) = 35 bytes
|
|
1004
|
+
*
|
|
1005
|
+
* Accounts:
|
|
1006
|
+
* 0. [signer] nft TransferHook program (CPI caller)
|
|
1007
|
+
* 1. [writable] slab
|
|
1008
|
+
* (remaining accounts per Token-2022 ExtraAccountMeta spec)
|
|
1009
|
+
*/
|
|
1010
|
+
interface TransferOwnershipCpiArgs {
|
|
1011
|
+
userIdx: number;
|
|
1012
|
+
newOwner: PublicKey | string;
|
|
1013
|
+
}
|
|
1014
|
+
declare function encodeTransferOwnershipCpi(args: TransferOwnershipCpiArgs): Uint8Array;
|
|
1015
|
+
/**
|
|
1016
|
+
* SetWalletCap (Tag 70, PERC-8111) — set the per-wallet position cap (admin only).
|
|
1017
|
+
*
|
|
1018
|
+
* Limits the maximum absolute position size any single wallet may hold on this market.
|
|
1019
|
+
* Enforced on every trade (TradeNoCpi + TradeCpi) after execute_trade.
|
|
1020
|
+
*
|
|
1021
|
+
* - `capE6 = 0`: disable per-wallet cap (no limit, default).
|
|
1022
|
+
* - `capE6 > 0`: max |position_size| in e6 units ($1 = 1_000_000).
|
|
1023
|
+
* Phase 1 launch value: 1_000_000_000n ($1,000).
|
|
1024
|
+
*
|
|
1025
|
+
* When a trade would breach the cap, the on-chain error `WalletPositionCapExceeded`
|
|
1026
|
+
* (error code 58) is returned.
|
|
1027
|
+
*
|
|
1028
|
+
* Instruction data layout: tag(1) + cap_e6(8) = 9 bytes
|
|
1029
|
+
*
|
|
1030
|
+
* Accounts:
|
|
1031
|
+
* 0. [signer] admin
|
|
1032
|
+
* 1. [writable] slab
|
|
1033
|
+
*
|
|
1034
|
+
* @example
|
|
1035
|
+
* ```ts
|
|
1036
|
+
* // Set $1K per-wallet cap
|
|
1037
|
+
* const ix = new TransactionInstruction({
|
|
1038
|
+
* programId: PROGRAM_ID,
|
|
1039
|
+
* keys: buildAccountMetas(ACCOUNTS_SET_WALLET_CAP, [admin, slab]),
|
|
1040
|
+
* data: Buffer.from(encodeSetWalletCap({ capE6: 1_000_000_000n })),
|
|
1041
|
+
* });
|
|
1042
|
+
*
|
|
1043
|
+
* // Disable cap
|
|
1044
|
+
* const disableIx = new TransactionInstruction({
|
|
1045
|
+
* programId: PROGRAM_ID,
|
|
1046
|
+
* keys: buildAccountMetas(ACCOUNTS_SET_WALLET_CAP, [admin, slab]),
|
|
1047
|
+
* data: Buffer.from(encodeSetWalletCap({ capE6: 0n })),
|
|
1048
|
+
* });
|
|
1049
|
+
* ```
|
|
1050
|
+
*/
|
|
1051
|
+
interface SetWalletCapArgs {
|
|
1052
|
+
/** Max position size in e6 units. 0 = disabled. $1 = 1_000_000n, $1K = 1_000_000_000n. */
|
|
1053
|
+
capE6: bigint | string;
|
|
1054
|
+
}
|
|
1055
|
+
declare function encodeSetWalletCap(args: SetWalletCapArgs): Uint8Array;
|
|
1056
|
+
/**
|
|
1057
|
+
* InitMatcherCtx (Tag 75) — admin initializes the matcher context account for an LP slot.
|
|
1058
|
+
*
|
|
1059
|
+
* The matcher program (DHP6DtwXP1yJsz8YzfoeigRFPB979gzmumkmCxDLSkUX) requires its context
|
|
1060
|
+
* account to be initialized before TradeCpi can work. Only the percolator program can sign
|
|
1061
|
+
* as the LP PDA via invoke_signed, so this instruction acts as the trusted initializer.
|
|
1062
|
+
*
|
|
1063
|
+
* Instruction data layout: tag(1) + lp_idx(2) + kind(1) + trading_fee_bps(4) +
|
|
1064
|
+
* base_spread_bps(4) + max_total_bps(4) + impact_k_bps(4) +
|
|
1065
|
+
* liquidity_notional_e6(16) + max_fill_abs(16) + max_inventory_abs(16) +
|
|
1066
|
+
* fee_to_insurance_bps(2) + skew_spread_mult_bps(2) = 72 bytes
|
|
1067
|
+
*
|
|
1068
|
+
* Accounts:
|
|
1069
|
+
* 0. [signer] admin
|
|
1070
|
+
* 1. [] slab (program-owned; used to verify admin + LP slot)
|
|
1071
|
+
* 2. [writable] matcherCtx (must match LP's stored matcher_context)
|
|
1072
|
+
* 3. [] matcherProg (executable; must match LP's stored matcher_program)
|
|
1073
|
+
* 4. [] lpPda (PDA ["lp", slab, lp_idx]; required by CPI as signer)
|
|
1074
|
+
*/
|
|
1075
|
+
interface InitMatcherCtxArgs {
|
|
1076
|
+
/** LP account index in the engine (0-based). */
|
|
1077
|
+
lpIdx: number;
|
|
1078
|
+
/** Matcher kind: 0=Passive, 1=vAMM. */
|
|
1079
|
+
kind: number;
|
|
1080
|
+
/** Base trading fee in bps (e.g. 30 = 0.30%). */
|
|
1081
|
+
tradingFeeBps: number;
|
|
1082
|
+
/** Base spread in bps. */
|
|
1083
|
+
baseSpreadBps: number;
|
|
1084
|
+
/** Max total spread in bps. */
|
|
1085
|
+
maxTotalBps: number;
|
|
1086
|
+
/** vAMM impact constant in bps (0 for passive matchers). */
|
|
1087
|
+
impactKBps: number;
|
|
1088
|
+
/** Liquidity notional in e6 units (0 for passive matchers). */
|
|
1089
|
+
liquidityNotionalE6: bigint | string;
|
|
1090
|
+
/** Max single fill size in absolute units (u128::MAX = no limit). */
|
|
1091
|
+
maxFillAbs: bigint | string;
|
|
1092
|
+
/** Max inventory size in absolute units (u128::MAX = no limit). */
|
|
1093
|
+
maxInventoryAbs: bigint | string;
|
|
1094
|
+
/** Fraction of fees routed to insurance fund in bps. */
|
|
1095
|
+
feeToInsuranceBps: number;
|
|
1096
|
+
/** Skew spread multiplier in bps (0 = disabled). */
|
|
1097
|
+
skewSpreadMultBps: number;
|
|
1098
|
+
}
|
|
1099
|
+
declare function encodeInitMatcherCtx(args: InitMatcherCtxArgs): Uint8Array;
|
|
1100
|
+
/** SetInsuranceWithdrawPolicy (tag 22): authority + min_withdraw_base + max_withdraw_bps + cooldown_slots */
|
|
1101
|
+
interface SetInsuranceWithdrawPolicyArgs {
|
|
1102
|
+
authority: PublicKey | string;
|
|
1103
|
+
minWithdrawBase: bigint | string;
|
|
1104
|
+
maxWithdrawBps: number;
|
|
1105
|
+
cooldownSlots: bigint | string;
|
|
1106
|
+
}
|
|
1107
|
+
declare function encodeSetInsuranceWithdrawPolicy(args: SetInsuranceWithdrawPolicyArgs): Uint8Array;
|
|
1108
|
+
/** WithdrawInsuranceLimited (tag 23): amount */
|
|
1109
|
+
declare function encodeWithdrawInsuranceLimited(args: {
|
|
1110
|
+
amount: bigint | string;
|
|
1111
|
+
}): Uint8Array;
|
|
1112
|
+
/** ResolvePermissionless (tag 29): no args */
|
|
1113
|
+
declare function encodeResolvePermissionless(): Uint8Array;
|
|
1114
|
+
/** ForceCloseResolved (tag 30): user_idx */
|
|
1115
|
+
declare function encodeForceCloseResolved(args: {
|
|
1116
|
+
userIdx: number;
|
|
1117
|
+
}): Uint8Array;
|
|
1118
|
+
/** CreateLpVault (tag 37): fee_share_bps + util_curve_enabled */
|
|
1119
|
+
declare function encodeCreateLpVault(args: {
|
|
1120
|
+
feeShareBps: bigint | string;
|
|
1121
|
+
utilCurveEnabled?: boolean;
|
|
1122
|
+
}): Uint8Array;
|
|
1123
|
+
/** LpVaultDeposit (tag 38): amount */
|
|
1124
|
+
declare function encodeLpVaultDeposit(args: {
|
|
1125
|
+
amount: bigint | string;
|
|
1126
|
+
}): Uint8Array;
|
|
1127
|
+
/** LpVaultCrankFees (tag 40): no args */
|
|
1128
|
+
declare function encodeLpVaultCrankFees(): Uint8Array;
|
|
1129
|
+
/** ChallengeSettlement (tag 43): proposed_price_e6 */
|
|
1130
|
+
declare function encodeChallengeSettlement(args: {
|
|
1131
|
+
proposedPriceE6: bigint | string;
|
|
1132
|
+
}): Uint8Array;
|
|
1133
|
+
/** ResolveDispute (tag 44): accept (0 = reject, 1 = accept) */
|
|
1134
|
+
declare function encodeResolveDispute(args: {
|
|
1135
|
+
accept: number;
|
|
1136
|
+
}): Uint8Array;
|
|
1137
|
+
/** DepositLpCollateral (tag 45): user_idx + lp_amount */
|
|
1138
|
+
declare function encodeDepositLpCollateral(args: {
|
|
1139
|
+
userIdx: number;
|
|
1140
|
+
lpAmount: bigint | string;
|
|
1141
|
+
}): Uint8Array;
|
|
1142
|
+
/** WithdrawLpCollateral (tag 46): user_idx + lp_amount */
|
|
1143
|
+
declare function encodeWithdrawLpCollateral(args: {
|
|
1144
|
+
userIdx: number;
|
|
1145
|
+
lpAmount: bigint | string;
|
|
1146
|
+
}): Uint8Array;
|
|
1147
|
+
/** SetOffsetPair (tag 54): offset_bps */
|
|
1148
|
+
declare function encodeSetOffsetPair(args: {
|
|
1149
|
+
offsetBps: number;
|
|
1150
|
+
}): Uint8Array;
|
|
1151
|
+
/** AttestCrossMargin (tag 55): user_idx_a + user_idx_b */
|
|
1152
|
+
declare function encodeAttestCrossMargin(args: {
|
|
1153
|
+
userIdxA: number;
|
|
1154
|
+
userIdxB: number;
|
|
1155
|
+
}): Uint8Array;
|
|
1156
|
+
/** RescueOrphanVault (tag 72): no args */
|
|
1157
|
+
declare function encodeRescueOrphanVault(): Uint8Array;
|
|
1158
|
+
/** CloseOrphanSlab (tag 73): no args */
|
|
1159
|
+
declare function encodeCloseOrphanSlab(): Uint8Array;
|
|
1160
|
+
/** SetDexPool (tag 74): pool pubkey */
|
|
1161
|
+
declare function encodeSetDexPool(args: {
|
|
1162
|
+
pool: PublicKey | string;
|
|
1163
|
+
}): Uint8Array;
|
|
1164
|
+
/** CloseKeeperFund (tag 78): no args. Accounts: [admin(signer,writable), slab, keeper_fund_pda(writable)] */
|
|
1165
|
+
declare function encodeCloseKeeperFund(): Uint8Array;
|
|
1166
|
+
/** CreateInsuranceMint: creates the insurance LP mint PDA (tag 37, same as CreateLpVault) */
|
|
1167
|
+
declare function encodeCreateInsuranceMint(): Uint8Array;
|
|
1168
|
+
/** DepositInsuranceLP: deposit collateral, receive LP tokens (tag 38, same as LpVaultDeposit) */
|
|
1169
|
+
declare function encodeDepositInsuranceLP(args: {
|
|
1170
|
+
amount: bigint | string;
|
|
1171
|
+
}): Uint8Array;
|
|
1172
|
+
/** WithdrawInsuranceLP: burn LP tokens, withdraw collateral (tag 39, same as LpVaultWithdraw) */
|
|
1173
|
+
declare function encodeWithdrawInsuranceLP(args: {
|
|
1174
|
+
lpAmount: bigint | string;
|
|
1175
|
+
}): Uint8Array;
|
|
1176
|
+
|
|
1177
|
+
/**
|
|
1178
|
+
* Account spec for building instruction account metas.
|
|
1179
|
+
* Each instruction has a fixed ordering that matches the Rust processor.
|
|
1180
|
+
*/
|
|
1181
|
+
interface AccountSpec {
|
|
1182
|
+
name: string;
|
|
1183
|
+
signer: boolean;
|
|
1184
|
+
writable: boolean;
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* InitMarket: 9 accounts (Pyth Pull - feed_id is in instruction data, not as accounts)
|
|
1188
|
+
*/
|
|
1189
|
+
declare const ACCOUNTS_INIT_MARKET: readonly AccountSpec[];
|
|
1190
|
+
/**
|
|
1191
|
+
* InitUser: 5 accounts (clock/oracle removed in commit 410f947)
|
|
1192
|
+
*/
|
|
1193
|
+
declare const ACCOUNTS_INIT_USER: readonly AccountSpec[];
|
|
1194
|
+
/**
|
|
1195
|
+
* InitLP: 5 accounts (clock/oracle removed in commit 410f947)
|
|
1196
|
+
*/
|
|
1197
|
+
declare const ACCOUNTS_INIT_LP: readonly AccountSpec[];
|
|
1198
|
+
/**
|
|
1199
|
+
* DepositCollateral: 6 accounts
|
|
1200
|
+
*/
|
|
1201
|
+
declare const ACCOUNTS_DEPOSIT_COLLATERAL: readonly AccountSpec[];
|
|
1202
|
+
/**
|
|
1203
|
+
* WithdrawCollateral: 8 accounts
|
|
1204
|
+
*/
|
|
1205
|
+
declare const ACCOUNTS_WITHDRAW_COLLATERAL: readonly AccountSpec[];
|
|
1206
|
+
/**
|
|
1207
|
+
* KeeperCrank: 4 accounts
|
|
1208
|
+
*/
|
|
1209
|
+
declare const ACCOUNTS_KEEPER_CRANK: readonly AccountSpec[];
|
|
1210
|
+
/**
|
|
1211
|
+
* TradeNoCpi: 4 accounts (PERC-199: clock sysvar removed — uses Clock::get() syscall)
|
|
1212
|
+
*/
|
|
1213
|
+
declare const ACCOUNTS_TRADE_NOCPI: readonly AccountSpec[];
|
|
1214
|
+
/**
|
|
1215
|
+
* LiquidateAtOracle: 4 accounts
|
|
1216
|
+
* Note: account[0] is unused but must be present
|
|
1217
|
+
*/
|
|
1218
|
+
declare const ACCOUNTS_LIQUIDATE_AT_ORACLE: readonly AccountSpec[];
|
|
1219
|
+
/**
|
|
1220
|
+
* CloseAccount: 8 accounts
|
|
1221
|
+
*/
|
|
1222
|
+
declare const ACCOUNTS_CLOSE_ACCOUNT: readonly AccountSpec[];
|
|
1223
|
+
/**
|
|
1224
|
+
* TopUpInsurance: 5 accounts
|
|
1225
|
+
*/
|
|
1226
|
+
declare const ACCOUNTS_TOPUP_INSURANCE: readonly AccountSpec[];
|
|
1227
|
+
/**
|
|
1228
|
+
* TradeCpi: 8 accounts (deployed program expects clock sysvar at index 3)
|
|
1229
|
+
*/
|
|
1230
|
+
declare const ACCOUNTS_TRADE_CPI: readonly AccountSpec[];
|
|
1231
|
+
/**
|
|
1232
|
+
* SetRiskThreshold: 2 accounts
|
|
1233
|
+
*/
|
|
1234
|
+
declare const ACCOUNTS_SET_RISK_THRESHOLD: readonly AccountSpec[];
|
|
1235
|
+
/**
|
|
1236
|
+
* UpdateAdmin: 2 accounts
|
|
1237
|
+
*/
|
|
1238
|
+
declare const ACCOUNTS_UPDATE_ADMIN: readonly AccountSpec[];
|
|
1239
|
+
/**
|
|
1240
|
+
* CloseSlab: 2 accounts
|
|
1241
|
+
*/
|
|
1242
|
+
declare const ACCOUNTS_CLOSE_SLAB: readonly AccountSpec[];
|
|
1243
|
+
/**
|
|
1244
|
+
* UpdateConfig: 2 accounts
|
|
1245
|
+
*/
|
|
1246
|
+
declare const ACCOUNTS_UPDATE_CONFIG: readonly AccountSpec[];
|
|
1247
|
+
/**
|
|
1248
|
+
* SetMaintenanceFee: 2 accounts
|
|
1249
|
+
*/
|
|
1250
|
+
declare const ACCOUNTS_SET_MAINTENANCE_FEE: readonly AccountSpec[];
|
|
1251
|
+
/**
|
|
1252
|
+
* SetOracleAuthority: 2 accounts
|
|
1253
|
+
* Sets the oracle price authority (admin only)
|
|
1254
|
+
*/
|
|
1255
|
+
declare const ACCOUNTS_SET_ORACLE_AUTHORITY: readonly AccountSpec[];
|
|
1256
|
+
/**
|
|
1257
|
+
* SetOraclePriceCap: 2 accounts
|
|
1258
|
+
* Set oracle price circuit breaker cap (admin only)
|
|
1259
|
+
*/
|
|
1260
|
+
declare const ACCOUNTS_SET_ORACLE_PRICE_CAP: readonly AccountSpec[];
|
|
1261
|
+
/**
|
|
1262
|
+
* PushOraclePrice: 2 accounts
|
|
1263
|
+
* Push oracle price (oracle authority only)
|
|
1264
|
+
*/
|
|
1265
|
+
declare const ACCOUNTS_PUSH_ORACLE_PRICE: readonly AccountSpec[];
|
|
1266
|
+
/**
|
|
1267
|
+
* ResolveMarket: 2 accounts
|
|
1268
|
+
* Resolves a binary/premarket (admin only)
|
|
1269
|
+
*/
|
|
1270
|
+
declare const ACCOUNTS_RESOLVE_MARKET: readonly AccountSpec[];
|
|
1271
|
+
/**
|
|
1272
|
+
* WithdrawInsurance: 6 accounts
|
|
1273
|
+
* Withdraw insurance fund after market resolution (admin only)
|
|
1274
|
+
*/
|
|
1275
|
+
declare const ACCOUNTS_WITHDRAW_INSURANCE: readonly AccountSpec[];
|
|
1276
|
+
/**
|
|
1277
|
+
* PauseMarket: 2 accounts
|
|
1278
|
+
*/
|
|
1279
|
+
declare const ACCOUNTS_PAUSE_MARKET: readonly AccountSpec[];
|
|
1280
|
+
/**
|
|
1281
|
+
* UnpauseMarket: 2 accounts
|
|
1282
|
+
*/
|
|
1283
|
+
declare const ACCOUNTS_UNPAUSE_MARKET: readonly AccountSpec[];
|
|
1284
|
+
/**
|
|
1285
|
+
* Build AccountMeta array from spec and provided pubkeys.
|
|
1286
|
+
*
|
|
1287
|
+
* Accepts either:
|
|
1288
|
+
* - `PublicKey[]` — ordered array, one entry per spec account (legacy form)
|
|
1289
|
+
* - `Record<string, PublicKey>` — named map keyed by account `name` (preferred form)
|
|
1290
|
+
*
|
|
1291
|
+
* Named-map form resolves accounts by spec name so callers don't have to
|
|
1292
|
+
* remember the positional order, and errors clearly on missing names.
|
|
1293
|
+
*/
|
|
1294
|
+
declare function buildAccountMetas(spec: readonly AccountSpec[], keys: PublicKey[] | Record<string, PublicKey>): AccountMeta[];
|
|
1295
|
+
/**
|
|
1296
|
+
* CreateInsuranceMint: 9 accounts
|
|
1297
|
+
* Creates SPL mint PDA for insurance LP tokens. Admin only, once per market.
|
|
1298
|
+
*/
|
|
1299
|
+
declare const ACCOUNTS_CREATE_INSURANCE_MINT: readonly AccountSpec[];
|
|
1300
|
+
/**
|
|
1301
|
+
* DepositInsuranceLP: 8 accounts
|
|
1302
|
+
* Deposit collateral into insurance fund, receive LP tokens.
|
|
1303
|
+
*/
|
|
1304
|
+
declare const ACCOUNTS_DEPOSIT_INSURANCE_LP: readonly AccountSpec[];
|
|
1305
|
+
/**
|
|
1306
|
+
* WithdrawInsuranceLP: 8 accounts
|
|
1307
|
+
* Burn LP tokens and withdraw proportional share of insurance fund.
|
|
1308
|
+
*/
|
|
1309
|
+
declare const ACCOUNTS_WITHDRAW_INSURANCE_LP: readonly AccountSpec[];
|
|
1310
|
+
/**
|
|
1311
|
+
* LpVaultWithdraw: 10 accounts (tag 39, PERC-627 / GH#1926 / PERC-8287)
|
|
1312
|
+
*
|
|
1313
|
+
* Burn LP vault tokens and withdraw proportional collateral from the LP vault.
|
|
1314
|
+
*
|
|
1315
|
+
* accounts[9] = creatorLockPda is REQUIRED since percolator-prog PR#170.
|
|
1316
|
+
* Non-creator withdrawers must pass the derived PDA key; if no lock exists
|
|
1317
|
+
* on-chain the enforcement is a no-op. Omitting it was the bypass vector
|
|
1318
|
+
* fixed in GH#1926. Use `deriveCreatorLockPda(programId, slab)` to compute.
|
|
1319
|
+
*
|
|
1320
|
+
* Accounts:
|
|
1321
|
+
* [0] withdrawer signer, read-only
|
|
1322
|
+
* [1] slab writable
|
|
1323
|
+
* [2] withdrawerAta writable (collateral destination)
|
|
1324
|
+
* [3] vault writable (collateral source)
|
|
1325
|
+
* [4] tokenProgram read-only
|
|
1326
|
+
* [5] lpVaultMint writable (LP tokens burned from here)
|
|
1327
|
+
* [6] withdrawerLpAta writable (LP tokens source)
|
|
1328
|
+
* [7] vaultAuthority read-only (PDA that signs token transfers)
|
|
1329
|
+
* [8] lpVaultState writable
|
|
1330
|
+
* [9] creatorLockPda writable (REQUIRED — derived from ["creator_lock", slab])
|
|
1331
|
+
*/
|
|
1332
|
+
declare const ACCOUNTS_LP_VAULT_WITHDRAW: readonly AccountSpec[];
|
|
1333
|
+
/**
|
|
1334
|
+
* FundMarketInsurance: 5 accounts (PERC-306)
|
|
1335
|
+
* Fund per-market isolated insurance balance.
|
|
1336
|
+
*/
|
|
1337
|
+
declare const ACCOUNTS_FUND_MARKET_INSURANCE: readonly AccountSpec[];
|
|
1338
|
+
/**
|
|
1339
|
+
* SetInsuranceIsolation: 2 accounts (PERC-306)
|
|
1340
|
+
* Set max % of global fund this market can access.
|
|
1341
|
+
*/
|
|
1342
|
+
declare const ACCOUNTS_SET_INSURANCE_ISOLATION: readonly AccountSpec[];
|
|
1343
|
+
/**
|
|
1344
|
+
* QueueWithdrawal: 5 accounts (PERC-309)
|
|
1345
|
+
* User queues a large LP withdrawal. Creates withdraw_queue PDA.
|
|
1346
|
+
*/
|
|
1347
|
+
declare const ACCOUNTS_QUEUE_WITHDRAWAL: readonly AccountSpec[];
|
|
1348
|
+
/**
|
|
1349
|
+
* ClaimQueuedWithdrawal: 10 accounts (PERC-309)
|
|
1350
|
+
* Burns LP tokens and releases one epoch tranche of SOL.
|
|
1351
|
+
*/
|
|
1352
|
+
declare const ACCOUNTS_CLAIM_QUEUED_WITHDRAWAL: readonly AccountSpec[];
|
|
1353
|
+
/**
|
|
1354
|
+
* CancelQueuedWithdrawal: 3 accounts (PERC-309)
|
|
1355
|
+
* Cancels queue, closes withdraw_queue PDA, returns rent to user.
|
|
1356
|
+
*/
|
|
1357
|
+
declare const ACCOUNTS_CANCEL_QUEUED_WITHDRAWAL: readonly AccountSpec[];
|
|
1358
|
+
/**
|
|
1359
|
+
* ExecuteAdl: 4+ accounts (PERC-305, tag 50)
|
|
1360
|
+
* Permissionless — surgically close/reduce the most profitable position
|
|
1361
|
+
* when pnl_pos_tot > max_pnl_cap. For non-Hyperp markets with backup oracles,
|
|
1362
|
+
* pass additional oracle accounts at accounts[4..].
|
|
1363
|
+
*/
|
|
1364
|
+
declare const ACCOUNTS_EXECUTE_ADL: readonly AccountSpec[];
|
|
1365
|
+
/**
|
|
1366
|
+
* CloseStaleSlabs: 2 accounts (tag 51)
|
|
1367
|
+
* Admin closes a slab of an invalid/old layout and recovers rent SOL.
|
|
1368
|
+
*/
|
|
1369
|
+
declare const ACCOUNTS_CLOSE_STALE_SLABS: readonly AccountSpec[];
|
|
1370
|
+
/**
|
|
1371
|
+
* ReclaimSlabRent: 2 accounts (tag 52)
|
|
1372
|
+
* Reclaim rent from an uninitialised slab. Both dest and slab must sign.
|
|
1373
|
+
*/
|
|
1374
|
+
declare const ACCOUNTS_RECLAIM_SLAB_RENT: readonly AccountSpec[];
|
|
1375
|
+
/**
|
|
1376
|
+
* AuditCrank: 1 account (tag 53)
|
|
1377
|
+
* Permissionless. Verifies conservation invariants; pauses market on violation.
|
|
1378
|
+
*/
|
|
1379
|
+
declare const ACCOUNTS_AUDIT_CRANK: readonly AccountSpec[];
|
|
1380
|
+
/**
|
|
1381
|
+
* AdvanceOraclePhase: 1 account
|
|
1382
|
+
* Permissionless — no signer required beyond fee payer.
|
|
1383
|
+
*/
|
|
1384
|
+
declare const ACCOUNTS_ADVANCE_ORACLE_PHASE: readonly AccountSpec[];
|
|
1385
|
+
/**
|
|
1386
|
+
* TopUpKeeperFund: 3 accounts
|
|
1387
|
+
* Permissionless — anyone can fund. System program required for SOL transfer.
|
|
1388
|
+
*/
|
|
1389
|
+
declare const ACCOUNTS_TOPUP_KEEPER_FUND: readonly AccountSpec[];
|
|
1390
|
+
/**
|
|
1391
|
+
* SetOiImbalanceHardBlock: 2 accounts
|
|
1392
|
+
* Sets the OI imbalance hard-block threshold (admin only)
|
|
1393
|
+
*/
|
|
1394
|
+
declare const ACCOUNTS_SET_OI_IMBALANCE_HARD_BLOCK: readonly AccountSpec[];
|
|
1395
|
+
/**
|
|
1396
|
+
* MintPositionNft: 10 accounts
|
|
1397
|
+
* Creates a Token-2022 position NFT for an open position.
|
|
1398
|
+
*/
|
|
1399
|
+
declare const ACCOUNTS_MINT_POSITION_NFT: readonly AccountSpec[];
|
|
1400
|
+
/**
|
|
1401
|
+
* TransferPositionOwnership: 8 accounts
|
|
1402
|
+
* Transfer position NFT and update on-chain owner. Requires pending_settlement == 0.
|
|
1403
|
+
*/
|
|
1404
|
+
declare const ACCOUNTS_TRANSFER_POSITION_OWNERSHIP: readonly AccountSpec[];
|
|
1405
|
+
/**
|
|
1406
|
+
* BurnPositionNft: 7 accounts
|
|
1407
|
+
* Burns NFT and closes PositionNft + mint PDAs after position is closed.
|
|
1408
|
+
*/
|
|
1409
|
+
declare const ACCOUNTS_BURN_POSITION_NFT: readonly AccountSpec[];
|
|
1410
|
+
/**
|
|
1411
|
+
* SetPendingSettlement: 3 accounts
|
|
1412
|
+
* Keeper/admin sets pending_settlement flag before funding transfer.
|
|
1413
|
+
* Protected by admin allowlist (GH#1475).
|
|
1414
|
+
*/
|
|
1415
|
+
declare const ACCOUNTS_SET_PENDING_SETTLEMENT: readonly AccountSpec[];
|
|
1416
|
+
/**
|
|
1417
|
+
* ClearPendingSettlement: 3 accounts
|
|
1418
|
+
* Keeper/admin clears pending_settlement flag after KeeperCrank.
|
|
1419
|
+
* Protected by admin allowlist (GH#1475).
|
|
1420
|
+
*/
|
|
1421
|
+
declare const ACCOUNTS_CLEAR_PENDING_SETTLEMENT: readonly AccountSpec[];
|
|
1422
|
+
/**
|
|
1423
|
+
* SetWalletCap: 2 accounts
|
|
1424
|
+
* Sets the per-wallet position cap (admin only). capE6=0 disables.
|
|
1425
|
+
*/
|
|
1426
|
+
declare const ACCOUNTS_SET_WALLET_CAP: readonly AccountSpec[];
|
|
1427
|
+
/**
|
|
1428
|
+
* SetDexPool: 3 accounts
|
|
1429
|
+
* Admin pins the approved DEX pool address for a HYPERP market.
|
|
1430
|
+
* After this call, UpdateHyperpMark rejects any pool that does not match.
|
|
1431
|
+
*/
|
|
1432
|
+
declare const ACCOUNTS_SET_DEX_POOL: readonly AccountSpec[];
|
|
1433
|
+
/**
|
|
1434
|
+
* InitMatcherCtx: 5 accounts
|
|
1435
|
+
* Admin CPI-initializes the matcher context account for an LP slot.
|
|
1436
|
+
* The LP PDA signs via invoke_signed in the program — it must be included in
|
|
1437
|
+
* the transaction's account list even though it carries 0 lamports.
|
|
1438
|
+
*/
|
|
1439
|
+
declare const ACCOUNTS_INIT_MATCHER_CTX: readonly AccountSpec[];
|
|
1440
|
+
declare const WELL_KNOWN: {
|
|
1441
|
+
readonly tokenProgram: PublicKey;
|
|
1442
|
+
readonly clock: PublicKey;
|
|
1443
|
+
readonly rent: PublicKey;
|
|
1444
|
+
readonly systemProgram: PublicKey;
|
|
1445
|
+
};
|
|
1446
|
+
|
|
1447
|
+
/**
|
|
1448
|
+
* Percolator program error definitions.
|
|
1449
|
+
* Each error includes a name and actionable guidance.
|
|
1450
|
+
*/
|
|
1451
|
+
interface ErrorInfo {
|
|
1452
|
+
name: string;
|
|
1453
|
+
hint: string;
|
|
1454
|
+
}
|
|
1455
|
+
declare const PERCOLATOR_ERRORS: Record<number, ErrorInfo>;
|
|
1456
|
+
/**
|
|
1457
|
+
* Decode a custom program error code to its info.
|
|
1458
|
+
*/
|
|
1459
|
+
declare function decodeError(code: number): ErrorInfo | undefined;
|
|
1460
|
+
/**
|
|
1461
|
+
* Get error name from code.
|
|
1462
|
+
*/
|
|
1463
|
+
declare function getErrorName(code: number): string;
|
|
1464
|
+
/**
|
|
1465
|
+
* Get actionable hint for error code.
|
|
1466
|
+
*/
|
|
1467
|
+
declare function getErrorHint(code: number): string | undefined;
|
|
1468
|
+
/**
|
|
1469
|
+
* Parse error from transaction logs.
|
|
1470
|
+
* Looks for "Program ... failed: custom program error: 0x..."
|
|
1471
|
+
*
|
|
1472
|
+
* Hex capture is bounded (1–8 digits) so pathological logs cannot feed unbounded
|
|
1473
|
+
* strings into `parseInt` or produce precision-loss codes above u32.
|
|
1474
|
+
*/
|
|
1475
|
+
declare function parseErrorFromLogs(logs: string[]): {
|
|
1476
|
+
code: number;
|
|
1477
|
+
name: string;
|
|
1478
|
+
hint?: string;
|
|
1479
|
+
} | null;
|
|
1480
|
+
|
|
1481
|
+
/**
|
|
1482
|
+
* Full slab layout descriptor. Returned by detectSlabLayout().
|
|
1483
|
+
* All engine field offsets are relative to engineOff.
|
|
1484
|
+
*/
|
|
1485
|
+
interface SlabLayout {
|
|
1486
|
+
version: 0 | 1 | 2;
|
|
1487
|
+
headerLen: number;
|
|
1488
|
+
configOffset: number;
|
|
1489
|
+
configLen: number;
|
|
1490
|
+
reservedOff: number;
|
|
1491
|
+
engineOff: number;
|
|
1492
|
+
accountSize: number;
|
|
1493
|
+
maxAccounts: number;
|
|
1494
|
+
bitmapWords: number;
|
|
1495
|
+
accountsOff: number;
|
|
1496
|
+
engineInsuranceOff: number;
|
|
1497
|
+
engineParamsOff: number;
|
|
1498
|
+
paramsSize: number;
|
|
1499
|
+
engineCurrentSlotOff: number;
|
|
1500
|
+
engineFundingIndexOff: number;
|
|
1501
|
+
engineLastFundingSlotOff: number;
|
|
1502
|
+
engineFundingRateBpsOff: number;
|
|
1503
|
+
engineMarkPriceOff: number;
|
|
1504
|
+
engineLastCrankSlotOff: number;
|
|
1505
|
+
engineMaxCrankStalenessOff: number;
|
|
1506
|
+
engineTotalOiOff: number;
|
|
1507
|
+
engineLongOiOff: number;
|
|
1508
|
+
engineShortOiOff: number;
|
|
1509
|
+
engineCTotOff: number;
|
|
1510
|
+
enginePnlPosTotOff: number;
|
|
1511
|
+
engineLiqCursorOff: number;
|
|
1512
|
+
engineGcCursorOff: number;
|
|
1513
|
+
engineLastSweepStartOff: number;
|
|
1514
|
+
engineLastSweepCompleteOff: number;
|
|
1515
|
+
engineCrankCursorOff: number;
|
|
1516
|
+
engineSweepStartIdxOff: number;
|
|
1517
|
+
engineLifetimeLiquidationsOff: number;
|
|
1518
|
+
engineLifetimeForceClosesOff: number;
|
|
1519
|
+
engineNetLpPosOff: number;
|
|
1520
|
+
engineLpSumAbsOff: number;
|
|
1521
|
+
engineLpMaxAbsOff: number;
|
|
1522
|
+
engineLpMaxAbsSweepOff: number;
|
|
1523
|
+
engineEmergencyOiModeOff: number;
|
|
1524
|
+
engineEmergencyStartSlotOff: number;
|
|
1525
|
+
engineLastBreakerSlotOff: number;
|
|
1526
|
+
engineBitmapOff: number;
|
|
1527
|
+
postBitmap: number;
|
|
1528
|
+
acctOwnerOff: number;
|
|
1529
|
+
hasInsuranceIsolation: boolean;
|
|
1530
|
+
engineInsuranceIsolatedOff: number;
|
|
1531
|
+
engineInsuranceIsolationBpsOff: number;
|
|
1532
|
+
}
|
|
1533
|
+
declare const ENGINE_OFF = 600;
|
|
1534
|
+
declare const ENGINE_MARK_PRICE_OFF = 400;
|
|
1535
|
+
/**
|
|
1536
|
+
* V2 slab tier sizes (small and large) for discovery.
|
|
1537
|
+
* V2 uses ENGINE_OFF=600, BITMAP_OFF=432, ACCOUNT_SIZE=248, postBitmap=18.
|
|
1538
|
+
* Sizes overlap with V1D (postBitmap=2) — disambiguation requires reading the version field.
|
|
1539
|
+
*/
|
|
1540
|
+
declare const SLAB_TIERS_V2: {
|
|
1541
|
+
readonly small: {
|
|
1542
|
+
readonly maxAccounts: 256;
|
|
1543
|
+
readonly dataSize: 65088;
|
|
1544
|
+
readonly label: "Small";
|
|
1545
|
+
readonly description: "256 slots (V2 BPF intermediate)";
|
|
1546
|
+
};
|
|
1547
|
+
readonly large: {
|
|
1548
|
+
readonly maxAccounts: 4096;
|
|
1549
|
+
readonly dataSize: 1025568;
|
|
1550
|
+
readonly label: "Large";
|
|
1551
|
+
readonly description: "4,096 slots (V2 BPF intermediate)";
|
|
1552
|
+
};
|
|
1553
|
+
};
|
|
1554
|
+
/**
|
|
1555
|
+
* V1M slab tier sizes — mainnet-deployed V1 program (ESa89R5).
|
|
1556
|
+
* ENGINE_OFF=640, BITMAP_OFF=726, ACCOUNT_SIZE=248, postBitmap=18.
|
|
1557
|
+
* Expanded RiskParams (336 bytes) and trade_twap runtime fields.
|
|
1558
|
+
* Confirmed by on-chain probing of slab 8NY7rvQ (SOL/USDC Perpetual, 257512 bytes).
|
|
1559
|
+
*/
|
|
1560
|
+
declare const SLAB_TIERS_V1M: Record<string, {
|
|
1561
|
+
maxAccounts: number;
|
|
1562
|
+
dataSize: number;
|
|
1563
|
+
label: string;
|
|
1564
|
+
description: string;
|
|
1565
|
+
}>;
|
|
1566
|
+
/**
|
|
1567
|
+
* V1M2 slab tier sizes — mainnet program rebuilt from main@4861c56 with 312-byte accounts.
|
|
1568
|
+
* ENGINE_OFF=616, BITMAP_OFF=1008 (empirically verified from CCTegYZ...).
|
|
1569
|
+
* Engine struct is layout-identical to V_ADL; differs only in engineOff (616 vs 624).
|
|
1570
|
+
* Sizes are unique from V_ADL after the bitmap correction: medium=323312 vs V_ADL=323320.
|
|
1571
|
+
*/
|
|
1572
|
+
declare const SLAB_TIERS_V1M2: Record<string, {
|
|
1573
|
+
maxAccounts: number;
|
|
1574
|
+
dataSize: number;
|
|
1575
|
+
label: string;
|
|
1576
|
+
description: string;
|
|
1577
|
+
}>;
|
|
1578
|
+
/**
|
|
1579
|
+
* V_ADL slab tier sizes — PERC-8270/8271 ADL-upgraded program.
|
|
1580
|
+
* ENGINE_OFF=624, BITMAP_OFF=1008, ACCOUNT_SIZE=312, postBitmap=18.
|
|
1581
|
+
* New account layout adds ADL tracking fields (+64 bytes/account including alignment padding).
|
|
1582
|
+
* BPF SLAB_LEN verified by cargo build-sbf in PERC-8271: large (4096) = 1288320 bytes.
|
|
1583
|
+
*/
|
|
1584
|
+
declare const SLAB_TIERS_V_ADL: Record<string, {
|
|
1585
|
+
maxAccounts: number;
|
|
1586
|
+
dataSize: number;
|
|
1587
|
+
label: string;
|
|
1588
|
+
description: string;
|
|
1589
|
+
}>;
|
|
1590
|
+
/**
|
|
1591
|
+
* V_SETDEXPOOL slab tier sizes — PERC-SetDexPool security fix.
|
|
1592
|
+
* ENGINE_OFF=632, BITMAP_OFF=1008, ACCOUNT_SIZE=312, CONFIG_LEN=528.
|
|
1593
|
+
* e.g. large (4096 accts) = 1288336 bytes.
|
|
1594
|
+
*/
|
|
1595
|
+
declare const SLAB_TIERS_V_SETDEXPOOL: Record<string, {
|
|
1596
|
+
maxAccounts: number;
|
|
1597
|
+
dataSize: number;
|
|
1598
|
+
label: string;
|
|
1599
|
+
description: string;
|
|
1600
|
+
}>;
|
|
1601
|
+
/**
|
|
1602
|
+
* V12_1 slab tier sizes — percolator-core v12.1 merge.
|
|
1603
|
+
* ENGINE_OFF=648, BITMAP_OFF=1016, ACCOUNT_SIZE=320.
|
|
1604
|
+
* Verified by cargo build-sbf compile-time assertions.
|
|
1605
|
+
*/
|
|
1606
|
+
declare const SLAB_TIERS_V12_1: Record<string, {
|
|
1607
|
+
maxAccounts: number;
|
|
1608
|
+
dataSize: number;
|
|
1609
|
+
label: string;
|
|
1610
|
+
description: string;
|
|
1611
|
+
}>;
|
|
1612
|
+
/**
|
|
1613
|
+
* Detect the slab layout version from the raw account data length.
|
|
1614
|
+
* Returns the full SlabLayout descriptor, or null if the size is unrecognised.
|
|
1615
|
+
* Checks V12_1, V_SETDEXPOOL, V1M2, V_ADL, V1M, V0, V1D, V1D-legacy, V1, and V1-legacy sizes.
|
|
1616
|
+
*
|
|
1617
|
+
* When `data` is provided and the size matches V1D, the version field at offset 8 is read
|
|
1618
|
+
* to disambiguate V2 slabs (which produce identical sizes to V1D with postBitmap=2).
|
|
1619
|
+
* V2 slabs have version===2 at offset 8 (u32 LE).
|
|
1620
|
+
*
|
|
1621
|
+
* @param dataLen - The slab account data length in bytes
|
|
1622
|
+
* @param data - Optional raw slab data for version-field disambiguation
|
|
1623
|
+
*/
|
|
1624
|
+
declare function detectSlabLayout(dataLen: number, data?: Uint8Array): SlabLayout | null;
|
|
1625
|
+
/**
|
|
1626
|
+
* Legacy detectLayout for backward compat.
|
|
1627
|
+
* Returns { bitmapWords, accountsOff, maxAccounts } or null.
|
|
1628
|
+
*
|
|
1629
|
+
* GH#1238: previously recomputed accountsOff with hardcoded postBitmap=18, which gave a value
|
|
1630
|
+
* 16 bytes too large for V1D slabs (which use postBitmap=2). Now delegates directly to the
|
|
1631
|
+
* SlabLayout descriptor so each variant uses its own correct accountsOff.
|
|
1632
|
+
*/
|
|
1633
|
+
declare function detectLayout(dataLen: number): {
|
|
1634
|
+
bitmapWords: number;
|
|
1635
|
+
accountsOff: number;
|
|
1636
|
+
maxAccounts: number;
|
|
1637
|
+
} | null;
|
|
1638
|
+
interface SlabHeader {
|
|
1639
|
+
magic: bigint;
|
|
1640
|
+
version: number;
|
|
1641
|
+
bump: number;
|
|
1642
|
+
flags: number;
|
|
1643
|
+
resolved: boolean;
|
|
1644
|
+
paused: boolean;
|
|
1645
|
+
admin: PublicKey;
|
|
1646
|
+
nonce: bigint;
|
|
1647
|
+
lastThrUpdateSlot: bigint;
|
|
1648
|
+
}
|
|
1649
|
+
interface MarketConfig {
|
|
1650
|
+
collateralMint: PublicKey;
|
|
1651
|
+
vaultPubkey: PublicKey;
|
|
1652
|
+
indexFeedId: PublicKey;
|
|
1653
|
+
maxStalenessSlots: bigint;
|
|
1654
|
+
confFilterBps: number;
|
|
1655
|
+
vaultAuthorityBump: number;
|
|
1656
|
+
invert: number;
|
|
1657
|
+
unitScale: number;
|
|
1658
|
+
fundingHorizonSlots: bigint;
|
|
1659
|
+
fundingKBps: bigint;
|
|
1660
|
+
fundingInvScaleNotionalE6: bigint;
|
|
1661
|
+
fundingMaxPremiumBps: bigint;
|
|
1662
|
+
fundingMaxBpsPerSlot: bigint;
|
|
1663
|
+
/** @deprecated Removed in V12_1 — always 0 */ fundingPremiumWeightBps: bigint;
|
|
1664
|
+
/** @deprecated Removed in V12_1 — always 0 */ fundingSettlementIntervalSlots: bigint;
|
|
1665
|
+
/** @deprecated Removed in V12_1 — always 0 */ fundingPremiumDampeningE6: bigint;
|
|
1666
|
+
/** @deprecated Removed in V12_1 — always 0 */ fundingPremiumMaxBpsPerSlot: bigint;
|
|
1667
|
+
threshFloor: bigint;
|
|
1668
|
+
threshRiskBps: bigint;
|
|
1669
|
+
threshUpdateIntervalSlots: bigint;
|
|
1670
|
+
threshStepBps: bigint;
|
|
1671
|
+
threshAlphaBps: bigint;
|
|
1672
|
+
threshMin: bigint;
|
|
1673
|
+
threshMax: bigint;
|
|
1674
|
+
threshMinStep: bigint;
|
|
1675
|
+
oracleAuthority: PublicKey;
|
|
1676
|
+
authorityPriceE6: bigint;
|
|
1677
|
+
authorityTimestamp: bigint;
|
|
1678
|
+
oraclePriceCapE2bps: bigint;
|
|
1679
|
+
lastEffectivePriceE6: bigint;
|
|
1680
|
+
oiCapMultiplierBps: bigint;
|
|
1681
|
+
maxPnlCap: bigint;
|
|
1682
|
+
adaptiveFundingEnabled: boolean;
|
|
1683
|
+
adaptiveScaleBps: number;
|
|
1684
|
+
adaptiveMaxFundingBps: bigint;
|
|
1685
|
+
marketCreatedSlot: bigint;
|
|
1686
|
+
oiRampSlots: bigint;
|
|
1687
|
+
resolvedSlot: bigint;
|
|
1688
|
+
insuranceIsolationBps: number;
|
|
1689
|
+
/** PERC-622: Oracle phase (0=Nascent, 1=Growing, 2=Mature) */
|
|
1690
|
+
oraclePhase: number;
|
|
1691
|
+
/** PERC-622: Cumulative trade volume in e6 format */
|
|
1692
|
+
cumulativeVolumeE6: bigint;
|
|
1693
|
+
/** PERC-622: Slots elapsed from market creation to Phase 2 entry (u24) */
|
|
1694
|
+
phase2DeltaSlots: number;
|
|
1695
|
+
/**
|
|
1696
|
+
* PERC-SetDexPool: Admin-pinned DEX pool pubkey for HYPERP markets.
|
|
1697
|
+
* Null when reading old slabs (pre-SetDexPool configLen < 528) or when
|
|
1698
|
+
* SetDexPool has never been called (all-zero pubkey).
|
|
1699
|
+
* Non-null means the program will reject any UpdateHyperpMark that passes
|
|
1700
|
+
* a different pool account.
|
|
1701
|
+
*/
|
|
1702
|
+
dexPool: PublicKey | null;
|
|
1703
|
+
}
|
|
1704
|
+
interface InsuranceFund {
|
|
1705
|
+
balance: bigint;
|
|
1706
|
+
feeRevenue: bigint;
|
|
1707
|
+
isolatedBalance: bigint;
|
|
1708
|
+
isolationBps: number;
|
|
1709
|
+
}
|
|
1710
|
+
interface RiskParams {
|
|
1711
|
+
warmupPeriodSlots: bigint;
|
|
1712
|
+
maintenanceMarginBps: bigint;
|
|
1713
|
+
initialMarginBps: bigint;
|
|
1714
|
+
tradingFeeBps: bigint;
|
|
1715
|
+
maxAccounts: bigint;
|
|
1716
|
+
newAccountFee: bigint;
|
|
1717
|
+
riskReductionThreshold: bigint;
|
|
1718
|
+
maintenanceFeePerSlot: bigint;
|
|
1719
|
+
maxCrankStalenessSlots: bigint;
|
|
1720
|
+
liquidationFeeBps: bigint;
|
|
1721
|
+
liquidationFeeCap: bigint;
|
|
1722
|
+
liquidationBufferBps: bigint;
|
|
1723
|
+
minLiquidationAbs: bigint;
|
|
1724
|
+
/** Minimum initial deposit to open an account (V12_1+ only) */
|
|
1725
|
+
minInitialDeposit: bigint;
|
|
1726
|
+
/** Minimum nonzero maintenance margin requirement (V12_1+ only) */
|
|
1727
|
+
minNonzeroMmReq: bigint;
|
|
1728
|
+
/** Minimum nonzero initial margin requirement (V12_1+ only) */
|
|
1729
|
+
minNonzeroImReq: bigint;
|
|
1730
|
+
/** Insurance fund floor (V12_1+ only) */
|
|
1731
|
+
insuranceFloor: bigint;
|
|
1732
|
+
}
|
|
1733
|
+
interface EngineState {
|
|
1734
|
+
vault: bigint;
|
|
1735
|
+
insuranceFund: InsuranceFund;
|
|
1736
|
+
currentSlot: bigint;
|
|
1737
|
+
fundingIndexQpbE6: bigint;
|
|
1738
|
+
lastFundingSlot: bigint;
|
|
1739
|
+
fundingRateBpsPerSlotLast: bigint;
|
|
1740
|
+
lastCrankSlot: bigint;
|
|
1741
|
+
maxCrankStalenessSlots: bigint;
|
|
1742
|
+
totalOpenInterest: bigint;
|
|
1743
|
+
longOi: bigint;
|
|
1744
|
+
shortOi: bigint;
|
|
1745
|
+
cTot: bigint;
|
|
1746
|
+
pnlPosTot: bigint;
|
|
1747
|
+
liqCursor: number;
|
|
1748
|
+
gcCursor: number;
|
|
1749
|
+
lastSweepStartSlot: bigint;
|
|
1750
|
+
lastSweepCompleteSlot: bigint;
|
|
1751
|
+
crankCursor: number;
|
|
1752
|
+
sweepStartIdx: number;
|
|
1753
|
+
lifetimeLiquidations: bigint;
|
|
1754
|
+
lifetimeForceCloses: bigint;
|
|
1755
|
+
netLpPos: bigint;
|
|
1756
|
+
lpSumAbs: bigint;
|
|
1757
|
+
lpMaxAbs: bigint;
|
|
1758
|
+
lpMaxAbsSweep: bigint;
|
|
1759
|
+
emergencyOiMode: boolean;
|
|
1760
|
+
emergencyStartSlot: bigint;
|
|
1761
|
+
lastBreakerSlot: bigint;
|
|
1762
|
+
numUsedAccounts: number;
|
|
1763
|
+
nextAccountId: bigint;
|
|
1764
|
+
markPriceE6: bigint;
|
|
1765
|
+
}
|
|
1766
|
+
declare enum AccountKind {
|
|
1767
|
+
User = 0,
|
|
1768
|
+
LP = 1
|
|
1769
|
+
}
|
|
1770
|
+
interface Account {
|
|
1771
|
+
kind: AccountKind;
|
|
1772
|
+
accountId: bigint;
|
|
1773
|
+
capital: bigint;
|
|
1774
|
+
pnl: bigint;
|
|
1775
|
+
reservedPnl: bigint;
|
|
1776
|
+
warmupStartedAtSlot: bigint;
|
|
1777
|
+
warmupSlopePerStep: bigint;
|
|
1778
|
+
positionSize: bigint;
|
|
1779
|
+
entryPrice: bigint;
|
|
1780
|
+
fundingIndex: bigint;
|
|
1781
|
+
matcherProgram: PublicKey;
|
|
1782
|
+
matcherContext: PublicKey;
|
|
1783
|
+
owner: PublicKey;
|
|
1784
|
+
feeCredits: bigint;
|
|
1785
|
+
lastFeeSlot: bigint;
|
|
1786
|
+
}
|
|
1787
|
+
declare function fetchSlab(connection: Connection, slabPubkey: PublicKey): Promise<Uint8Array>;
|
|
1788
|
+
declare const RAMP_START_BPS = 1000n;
|
|
1789
|
+
declare const DEFAULT_OI_RAMP_SLOTS = 432000n;
|
|
1790
|
+
declare function computeEffectiveOiCapBps(config: MarketConfig, currentSlot: bigint): bigint;
|
|
1791
|
+
declare function readNonce(data: Uint8Array): bigint;
|
|
1792
|
+
declare function readLastThrUpdateSlot(data: Uint8Array): bigint;
|
|
1793
|
+
/**
|
|
1794
|
+
* Parse slab header (first 72 bytes — layout-independent).
|
|
1795
|
+
*/
|
|
1796
|
+
declare function parseHeader(data: Uint8Array): SlabHeader;
|
|
1797
|
+
/**
|
|
1798
|
+
* Parse market config. Layout-version aware.
|
|
1799
|
+
* For V0 slabs, fields beyond the basic config are read if present in the data,
|
|
1800
|
+
* otherwise defaults are returned.
|
|
1801
|
+
*
|
|
1802
|
+
* @param data - Slab data (may be a partial slice for discovery; pass layoutHint in that case)
|
|
1803
|
+
* @param layoutHint - Pre-detected layout to use; if omitted, detected from data.length.
|
|
1804
|
+
*/
|
|
1805
|
+
declare function parseConfig(data: Uint8Array, layoutHint?: SlabLayout | null): MarketConfig;
|
|
1806
|
+
/**
|
|
1807
|
+
* Parse RiskParams from engine data. Layout-version aware.
|
|
1808
|
+
* For V0 slabs, extended params (risk_threshold, maintenance_fee, etc.) are
|
|
1809
|
+
* not present on-chain, so defaults (0) are returned.
|
|
1810
|
+
*
|
|
1811
|
+
* @param data - Slab data (may be a partial slice; pass layoutHint in that case)
|
|
1812
|
+
* @param layoutHint - Pre-detected layout to use; if omitted, detected from data.length.
|
|
1813
|
+
*/
|
|
1814
|
+
declare function parseParams(data: Uint8Array, layoutHint?: SlabLayout | null): RiskParams;
|
|
1815
|
+
/**
|
|
1816
|
+
* Parse RiskEngine state (excluding accounts array). Layout-version aware.
|
|
1817
|
+
*/
|
|
1818
|
+
declare function parseEngine(data: Uint8Array): EngineState;
|
|
1819
|
+
/**
|
|
1820
|
+
* Read bitmap to get list of used account indices.
|
|
1821
|
+
*/
|
|
1822
|
+
/**
|
|
1823
|
+
* Return all account indices whose bitmap bit is set (i.e. slot is in use).
|
|
1824
|
+
* Uses the layout-aware bitmap offset so V1_LEGACY slabs (bitmap at rel+672) are handled correctly.
|
|
1825
|
+
*/
|
|
1826
|
+
declare function parseUsedIndices(data: Uint8Array): number[];
|
|
1827
|
+
/**
|
|
1828
|
+
* Check if a specific account index is used.
|
|
1829
|
+
*/
|
|
1830
|
+
declare function isAccountUsed(data: Uint8Array, idx: number): boolean;
|
|
1831
|
+
/**
|
|
1832
|
+
* Calculate the maximum valid account index for a given slab size.
|
|
1833
|
+
*/
|
|
1834
|
+
declare function maxAccountIndex(dataLen: number): number;
|
|
1835
|
+
/**
|
|
1836
|
+
* Parse a single account by index.
|
|
1837
|
+
*/
|
|
1838
|
+
declare function parseAccount(data: Uint8Array, idx: number): Account;
|
|
1839
|
+
/**
|
|
1840
|
+
* Parse all used accounts.
|
|
1841
|
+
*/
|
|
1842
|
+
declare function parseAllAccounts(data: Uint8Array): {
|
|
1843
|
+
idx: number;
|
|
1844
|
+
account: Account;
|
|
1845
|
+
}[];
|
|
1846
|
+
|
|
1847
|
+
/**
|
|
1848
|
+
* Derive vault authority PDA.
|
|
1849
|
+
* Seeds: ["vault", slab_key]
|
|
1850
|
+
*/
|
|
1851
|
+
declare function deriveVaultAuthority(programId: PublicKey, slab: PublicKey): [PublicKey, number];
|
|
1852
|
+
/**
|
|
1853
|
+
* Derive insurance LP mint PDA.
|
|
1854
|
+
* Seeds: ["ins_lp", slab_key]
|
|
1855
|
+
*/
|
|
1856
|
+
declare function deriveInsuranceLpMint(programId: PublicKey, slab: PublicKey): [PublicKey, number];
|
|
1857
|
+
/**
|
|
1858
|
+
* Derive LP PDA for TradeCpi.
|
|
1859
|
+
* Seeds: ["lp", slab_key, lp_idx as u16 LE]
|
|
1860
|
+
*/
|
|
1861
|
+
declare function deriveLpPda(programId: PublicKey, slab: PublicKey, lpIdx: number): [PublicKey, number];
|
|
1862
|
+
/**
|
|
1863
|
+
* Derive keeper fund PDA.
|
|
1864
|
+
* Seeds: ["keeper_fund", slab_key]
|
|
1865
|
+
*/
|
|
1866
|
+
declare function deriveKeeperFund(programId: PublicKey, slab: PublicKey): [PublicKey, number];
|
|
1867
|
+
/** PumpSwap AMM program ID. */
|
|
1868
|
+
declare const PUMPSWAP_PROGRAM_ID: PublicKey;
|
|
1869
|
+
/** Raydium CLMM (Concentrated Liquidity) program ID. */
|
|
1870
|
+
declare const RAYDIUM_CLMM_PROGRAM_ID: PublicKey;
|
|
1871
|
+
/** Meteora DLMM (Dynamic Liquidity Market Maker) program ID. */
|
|
1872
|
+
declare const METEORA_DLMM_PROGRAM_ID: PublicKey;
|
|
1873
|
+
/** Pyth Push Oracle program on mainnet. */
|
|
1874
|
+
declare const PYTH_PUSH_ORACLE_PROGRAM_ID: PublicKey;
|
|
1875
|
+
/**
|
|
1876
|
+
* Seed used to derive the creator lock PDA.
|
|
1877
|
+
* Matches `creator_lock::CREATOR_LOCK_SEED` in percolator-prog.
|
|
1878
|
+
*/
|
|
1879
|
+
declare const CREATOR_LOCK_SEED = "creator_lock";
|
|
1880
|
+
/**
|
|
1881
|
+
* Derive the creator lock PDA for a given slab.
|
|
1882
|
+
* Seeds: ["creator_lock", slab_key]
|
|
1883
|
+
*
|
|
1884
|
+
* This PDA is required as accounts[9] in every LpVaultWithdraw instruction
|
|
1885
|
+
* since percolator-prog PR#170 (GH#1926 / PERC-8287).
|
|
1886
|
+
* Non-creator withdrawers must pass this key; if no lock exists on-chain the
|
|
1887
|
+
* enforcement is a no-op. The SDK must ALWAYS include it — passing it is mandatory.
|
|
1888
|
+
*
|
|
1889
|
+
* @param programId - The percolator program ID.
|
|
1890
|
+
* @param slab - The slab (market) public key.
|
|
1891
|
+
* @returns [pda, bump]
|
|
1892
|
+
*
|
|
1893
|
+
* @example
|
|
1894
|
+
* ```ts
|
|
1895
|
+
* const [creatorLockPda] = deriveCreatorLockPda(PROGRAM_ID, slabKey);
|
|
1896
|
+
* ```
|
|
1897
|
+
*/
|
|
1898
|
+
declare function deriveCreatorLockPda(programId: PublicKey, slab: PublicKey): [PublicKey, number];
|
|
1899
|
+
declare function derivePythPushOraclePDA(feedIdHex: string): [PublicKey, number];
|
|
1900
|
+
|
|
1901
|
+
/**
|
|
1902
|
+
* Get the associated token address for an owner and mint.
|
|
1903
|
+
* Supports both standard SPL Token and Token2022 via optional tokenProgramId.
|
|
1904
|
+
*/
|
|
1905
|
+
declare function getAta(owner: PublicKey, mint: PublicKey, allowOwnerOffCurve?: boolean, tokenProgramId?: PublicKey): Promise<PublicKey>;
|
|
1906
|
+
/**
|
|
1907
|
+
* Synchronous version of getAta.
|
|
1908
|
+
* Supports both standard SPL Token and Token2022 via optional tokenProgramId.
|
|
1909
|
+
*/
|
|
1910
|
+
declare function getAtaSync(owner: PublicKey, mint: PublicKey, allowOwnerOffCurve?: boolean, tokenProgramId?: PublicKey): PublicKey;
|
|
1911
|
+
/**
|
|
1912
|
+
* Fetch token account info.
|
|
1913
|
+
* Supports both standard SPL Token and Token2022 via optional tokenProgramId.
|
|
1914
|
+
* Throws if account doesn't exist.
|
|
1915
|
+
*/
|
|
1916
|
+
declare function fetchTokenAccount(connection: Connection, address: PublicKey, tokenProgramId?: PublicKey): Promise<Account$1>;
|
|
1917
|
+
|
|
1918
|
+
/**
|
|
1919
|
+
* Read an environment variable safely. Returns `undefined` in browser
|
|
1920
|
+
* environments where `process` is not defined, avoiding a
|
|
1921
|
+
* `ReferenceError` crash at import time.
|
|
1922
|
+
*/
|
|
1923
|
+
declare function safeEnv(key: string): string | undefined;
|
|
1924
|
+
/**
|
|
1925
|
+
* Centralized PROGRAM_ID configuration
|
|
1926
|
+
*
|
|
1927
|
+
* Default to environment variable, then fall back to network-specific defaults.
|
|
1928
|
+
* This prevents hard-coded program IDs scattered across the codebase.
|
|
1929
|
+
*/
|
|
1930
|
+
declare const PROGRAM_IDS: {
|
|
1931
|
+
readonly devnet: {
|
|
1932
|
+
readonly percolator: "FxfD37s1AZTeWfFQps9Zpebi2dNQ9QSSDtfMKdbsfKrD";
|
|
1933
|
+
readonly matcher: "GTRgyTDfrMvBubALAqtHuQwT8tbGyXid7svXZKtWfC9k";
|
|
1934
|
+
};
|
|
1935
|
+
readonly mainnet: {
|
|
1936
|
+
readonly percolator: "ESa89R5Es3rJ5mnwGybVRG1GrNt9etP11Z5V2QWD4edv";
|
|
1937
|
+
readonly matcher: "DHP6DtwXP1yJsz8YzfoeigRFPB979gzmumkmCxDLSkUX";
|
|
1938
|
+
};
|
|
1939
|
+
};
|
|
1940
|
+
type Network = "devnet" | "mainnet";
|
|
1941
|
+
/**
|
|
1942
|
+
* Get the Percolator program ID for the current network
|
|
1943
|
+
*
|
|
1944
|
+
* Priority:
|
|
1945
|
+
* 1. PROGRAM_ID env var (explicit override)
|
|
1946
|
+
* 2. Network-specific default (NETWORK env var)
|
|
1947
|
+
* 3. Devnet default (safest fallback — bug bounty PERC-697)
|
|
1948
|
+
*/
|
|
1949
|
+
declare function getProgramId(network?: Network): PublicKey;
|
|
1950
|
+
/**
|
|
1951
|
+
* Get the Matcher program ID for the current network
|
|
1952
|
+
*/
|
|
1953
|
+
declare function getMatcherProgramId(network?: Network): PublicKey;
|
|
1954
|
+
/**
|
|
1955
|
+
* Get the current network from environment.
|
|
1956
|
+
*
|
|
1957
|
+
* SECURITY (PERC-697): Removed silent mainnet default.
|
|
1958
|
+
* Previously defaulted to "mainnet" when NETWORK was unset, which could cause
|
|
1959
|
+
* crank/keeper scripts run without env vars to silently target mainnet program IDs.
|
|
1960
|
+
*
|
|
1961
|
+
* Now defaults to "devnet" — the safer fallback for a devnet-first protocol.
|
|
1962
|
+
* Production deployments always set NETWORK explicitly via Railway/env.
|
|
1963
|
+
* For mainnet operations use networkValidation.ts (ensureNetworkConfigValid) which
|
|
1964
|
+
* enforces FORCE_MAINNET=1.
|
|
1965
|
+
*/
|
|
1966
|
+
declare function getCurrentNetwork(): Network;
|
|
1967
|
+
|
|
1968
|
+
/**
|
|
1969
|
+
* Static market registry — bundled list of known Percolator slab addresses.
|
|
1970
|
+
*
|
|
1971
|
+
* This is the tier-3 fallback for `discoverMarkets()`: when both
|
|
1972
|
+
* `getProgramAccounts` (tier 1) and the REST API (tier 2) are unavailable,
|
|
1973
|
+
* the SDK falls back to this bundled list to bootstrap market discovery.
|
|
1974
|
+
*
|
|
1975
|
+
* The addresses are fetched on-chain via `getMarketsByAddress`
|
|
1976
|
+
* (`getMultipleAccounts`), so all data is still verified on-chain. The static
|
|
1977
|
+
* list only provides the *address directory* — no cached market data is used.
|
|
1978
|
+
*
|
|
1979
|
+
* ## Maintenance
|
|
1980
|
+
*
|
|
1981
|
+
* Update this list when new markets are deployed or old ones are retired.
|
|
1982
|
+
* Run `scripts/update-static-markets.ts` to regenerate from a permissive RPC
|
|
1983
|
+
* or the REST API.
|
|
1984
|
+
*
|
|
1985
|
+
* @module
|
|
1986
|
+
*/
|
|
1987
|
+
|
|
1988
|
+
/**
|
|
1989
|
+
* A single entry in the static market registry.
|
|
1990
|
+
*
|
|
1991
|
+
* Only the slab address (base58) is required. Optional metadata fields
|
|
1992
|
+
* (`symbol`, `name`) are provided for debugging/logging purposes only —
|
|
1993
|
+
* they are **not** used for on-chain data and may become stale.
|
|
1994
|
+
*/
|
|
1995
|
+
interface StaticMarketEntry {
|
|
1996
|
+
/** Base58-encoded slab account address. */
|
|
1997
|
+
slabAddress: string;
|
|
1998
|
+
/** Optional human-readable symbol (e.g. "SOL-PERP"). */
|
|
1999
|
+
symbol?: string;
|
|
2000
|
+
/** Optional descriptive name. */
|
|
2001
|
+
name?: string;
|
|
2002
|
+
}
|
|
2003
|
+
/**
|
|
2004
|
+
* Get the bundled static market list for a given network.
|
|
2005
|
+
*
|
|
2006
|
+
* Returns the built-in list merged with any entries added via
|
|
2007
|
+
* {@link registerStaticMarkets}. Duplicates (by `slabAddress`) are removed
|
|
2008
|
+
* automatically — user-registered entries take precedence.
|
|
2009
|
+
*
|
|
2010
|
+
* @param network - Target network (`"mainnet"` or `"devnet"`)
|
|
2011
|
+
* @returns Array of static market entries (may be empty if no markets are known)
|
|
2012
|
+
*
|
|
2013
|
+
* @example
|
|
2014
|
+
* ```ts
|
|
2015
|
+
* import { getStaticMarkets } from "@percolator/sdk";
|
|
2016
|
+
*
|
|
2017
|
+
* const markets = getStaticMarkets("mainnet");
|
|
2018
|
+
* console.log(`${markets.length} known mainnet slab addresses`);
|
|
2019
|
+
* ```
|
|
2020
|
+
*/
|
|
2021
|
+
declare function getStaticMarkets(network: Network): StaticMarketEntry[];
|
|
2022
|
+
/**
|
|
2023
|
+
* Register additional static market entries at runtime.
|
|
2024
|
+
*
|
|
2025
|
+
* Use this to inject known slab addresses before calling `discoverMarkets()`
|
|
2026
|
+
* so that tier-3 fallback has addresses to work with — especially useful
|
|
2027
|
+
* right after mainnet launch when the bundled list may be empty.
|
|
2028
|
+
*
|
|
2029
|
+
* Entries are deduplicated by `slabAddress` — calling this multiple times
|
|
2030
|
+
* with the same address is safe.
|
|
2031
|
+
*
|
|
2032
|
+
* @param network - Target network
|
|
2033
|
+
* @param entries - One or more static market entries to register
|
|
2034
|
+
*
|
|
2035
|
+
* @example
|
|
2036
|
+
* ```ts
|
|
2037
|
+
* import { registerStaticMarkets } from "@percolator/sdk";
|
|
2038
|
+
*
|
|
2039
|
+
* registerStaticMarkets("mainnet", [
|
|
2040
|
+
* { slabAddress: "ABC123...", symbol: "SOL-PERP" },
|
|
2041
|
+
* { slabAddress: "DEF456...", symbol: "ETH-PERP" },
|
|
2042
|
+
* ]);
|
|
2043
|
+
* ```
|
|
2044
|
+
*/
|
|
2045
|
+
declare function registerStaticMarkets(network: Network, entries: StaticMarketEntry[]): void;
|
|
2046
|
+
/**
|
|
2047
|
+
* Clear all user-registered static market entries for a network.
|
|
2048
|
+
*
|
|
2049
|
+
* Useful in tests or when resetting state.
|
|
2050
|
+
*
|
|
2051
|
+
* @param network - Target network to clear (omit to clear all networks)
|
|
2052
|
+
*/
|
|
2053
|
+
declare function clearStaticMarkets(network?: Network): void;
|
|
2054
|
+
|
|
2055
|
+
/**
|
|
2056
|
+
* A discovered Percolator market from on-chain program accounts.
|
|
2057
|
+
*/
|
|
2058
|
+
interface DiscoveredMarket {
|
|
2059
|
+
slabAddress: PublicKey;
|
|
2060
|
+
/** The program that owns this slab account */
|
|
2061
|
+
programId: PublicKey;
|
|
2062
|
+
header: SlabHeader;
|
|
2063
|
+
config: MarketConfig;
|
|
2064
|
+
engine: EngineState;
|
|
2065
|
+
params: RiskParams;
|
|
2066
|
+
}
|
|
2067
|
+
/**
|
|
2068
|
+
* Slab tier definitions — V1 layout (all tiers upgraded as of 2026-03-13).
|
|
2069
|
+
* IMPORTANT: dataSize must match the compiled program's SLAB_LEN for that MAX_ACCOUNTS.
|
|
2070
|
+
* The on-chain program has a hardcoded SLAB_LEN — slab account data.len() must equal it exactly.
|
|
2071
|
+
*
|
|
2072
|
+
* Layout: HEADER(104) + CONFIG(536) + RiskEngine(variable by tier)
|
|
2073
|
+
* ENGINE_OFF = 640 (HEADER=104 + CONFIG=536, padded to 8-byte align on SBF)
|
|
2074
|
+
* RiskEngine = fixed(656) + bitmap(BW*8) + post_bitmap(18) + next_free(N*2) + pad + accounts(N*248)
|
|
2075
|
+
*
|
|
2076
|
+
* Values are empirically verified against on-chain initialized accounts (GH #1109):
|
|
2077
|
+
* small = 65,352 (256-acct program, verified on-chain post-V1 upgrade)
|
|
2078
|
+
* medium = 257,448 (1024-acct program g9msRSV3, verified on-chain)
|
|
2079
|
+
* large = 1,025,832 (4096-acct program FxfD37s1, pre-PERC-118, matches slabDataSizeV1(4096) formula)
|
|
2080
|
+
*
|
|
2081
|
+
* NOTE: small program (FwfBKZXb) redeployed with --features small,devnet (2026-03-13).
|
|
2082
|
+
* Large program FxfD37s1 is pre-PERC-118 — SLAB_LEN=1,025,832, matching formula.
|
|
2083
|
+
* See GH #1109, GH #1112.
|
|
2084
|
+
*
|
|
2085
|
+
* History: Small was V0 (62_808) until 2026-03-13 program upgrade. V0 values preserved
|
|
2086
|
+
* in SLAB_TIERS_V0 for discovery of legacy on-chain accounts.
|
|
2087
|
+
*/
|
|
2088
|
+
/**
|
|
2089
|
+
* Default slab tiers for the current mainnet program (v12.1).
|
|
2090
|
+
* These are used by useCreateMarket to allocate slab accounts of the correct size.
|
|
2091
|
+
*/
|
|
2092
|
+
declare const SLAB_TIERS: {
|
|
2093
|
+
readonly micro: {
|
|
2094
|
+
maxAccounts: number;
|
|
2095
|
+
dataSize: number;
|
|
2096
|
+
label: string;
|
|
2097
|
+
description: string;
|
|
2098
|
+
};
|
|
2099
|
+
readonly small: {
|
|
2100
|
+
maxAccounts: number;
|
|
2101
|
+
dataSize: number;
|
|
2102
|
+
label: string;
|
|
2103
|
+
description: string;
|
|
2104
|
+
};
|
|
2105
|
+
readonly medium: {
|
|
2106
|
+
maxAccounts: number;
|
|
2107
|
+
dataSize: number;
|
|
2108
|
+
label: string;
|
|
2109
|
+
description: string;
|
|
2110
|
+
};
|
|
2111
|
+
readonly large: {
|
|
2112
|
+
maxAccounts: number;
|
|
2113
|
+
dataSize: number;
|
|
2114
|
+
label: string;
|
|
2115
|
+
description: string;
|
|
2116
|
+
};
|
|
2117
|
+
};
|
|
2118
|
+
/** @deprecated V0 slab sizes — kept for backward compatibility with old on-chain slabs */
|
|
2119
|
+
declare const SLAB_TIERS_V0: {
|
|
2120
|
+
readonly small: {
|
|
2121
|
+
readonly maxAccounts: 256;
|
|
2122
|
+
readonly dataSize: 62808;
|
|
2123
|
+
readonly label: "Small";
|
|
2124
|
+
readonly description: "256 slots · ~0.44 SOL";
|
|
2125
|
+
};
|
|
2126
|
+
readonly medium: {
|
|
2127
|
+
readonly maxAccounts: 1024;
|
|
2128
|
+
readonly dataSize: 248760;
|
|
2129
|
+
readonly label: "Medium";
|
|
2130
|
+
readonly description: "1,024 slots · ~1.73 SOL";
|
|
2131
|
+
};
|
|
2132
|
+
readonly large: {
|
|
2133
|
+
readonly maxAccounts: 4096;
|
|
2134
|
+
readonly dataSize: 992568;
|
|
2135
|
+
readonly label: "Large";
|
|
2136
|
+
readonly description: "4,096 slots · ~6.90 SOL";
|
|
2137
|
+
};
|
|
2138
|
+
};
|
|
2139
|
+
/**
|
|
2140
|
+
* V1D slab sizes — actually-deployed devnet V1 program (ENGINE_OFF=424, BITMAP_OFF=624).
|
|
2141
|
+
* PR #1200 added V1D layout detection in slab.ts but discovery.ts ALL_TIERS was missing
|
|
2142
|
+
* these sizes, causing V1D slabs to fall through to the memcmp fallback with wrong dataSize
|
|
2143
|
+
* hints → detectSlabLayout returning null → parse failure (GH#1205).
|
|
2144
|
+
*
|
|
2145
|
+
* Sizes computed via computeSlabSize(ENGINE_OFF=424, BITMAP_OFF=624, ACCOUNT_SIZE=248, N, postBitmap=2):
|
|
2146
|
+
* The V1D deployed program uses postBitmap=2 (free_head u16 only — no num_used/pad/next_account_id).
|
|
2147
|
+
* This is 16 bytes smaller per tier than the SDK default (postBitmap=18). GH#1234.
|
|
2148
|
+
* micro = 17,064 (64 slots)
|
|
2149
|
+
* small = 65,088 (256 slots)
|
|
2150
|
+
* medium = 257,184 (1,024 slots)
|
|
2151
|
+
* large = 1,025,568 (4,096 slots)
|
|
2152
|
+
*/
|
|
2153
|
+
declare const SLAB_TIERS_V1D: {
|
|
2154
|
+
readonly micro: {
|
|
2155
|
+
readonly maxAccounts: 64;
|
|
2156
|
+
readonly dataSize: 17064;
|
|
2157
|
+
readonly label: "Micro";
|
|
2158
|
+
readonly description: "64 slots (V1D devnet)";
|
|
2159
|
+
};
|
|
2160
|
+
readonly small: {
|
|
2161
|
+
readonly maxAccounts: 256;
|
|
2162
|
+
readonly dataSize: 65088;
|
|
2163
|
+
readonly label: "Small";
|
|
2164
|
+
readonly description: "256 slots (V1D devnet)";
|
|
2165
|
+
};
|
|
2166
|
+
readonly medium: {
|
|
2167
|
+
readonly maxAccounts: 1024;
|
|
2168
|
+
readonly dataSize: 257184;
|
|
2169
|
+
readonly label: "Medium";
|
|
2170
|
+
readonly description: "1,024 slots (V1D devnet)";
|
|
2171
|
+
};
|
|
2172
|
+
readonly large: {
|
|
2173
|
+
readonly maxAccounts: 4096;
|
|
2174
|
+
readonly dataSize: 1025568;
|
|
2175
|
+
readonly label: "Large";
|
|
2176
|
+
readonly description: "4,096 slots (V1D devnet)";
|
|
2177
|
+
};
|
|
2178
|
+
};
|
|
2179
|
+
/**
|
|
2180
|
+
* V1D legacy slab sizes — on-chain V1D slabs created before GH#1234 when the SDK assumed
|
|
2181
|
+
* postBitmap=18. These are 16 bytes larger per tier than SLAB_TIERS_V1D.
|
|
2182
|
+
* PR #1236 fixed postBitmap for new slabs (→2) but caused slab 6ZytbpV4 (65104 bytes,
|
|
2183
|
+
* top active market ~$15k 24h vol) to be unrecognized → "Failed to load market". GH#1237.
|
|
2184
|
+
*
|
|
2185
|
+
* Sizes computed via computeSlabSize(ENGINE_OFF=424, BITMAP_OFF=624, ACCOUNT_SIZE=248, N, postBitmap=18):
|
|
2186
|
+
* micro = 17,080 (64 slots)
|
|
2187
|
+
* small = 65,104 (256 slots) ← slab 6ZytbpV4 TEST/USD
|
|
2188
|
+
* medium = 257,200 (1,024 slots)
|
|
2189
|
+
* large = 1,025,584 (4,096 slots)
|
|
2190
|
+
*/
|
|
2191
|
+
declare const SLAB_TIERS_V1D_LEGACY: {
|
|
2192
|
+
readonly micro: {
|
|
2193
|
+
readonly maxAccounts: 64;
|
|
2194
|
+
readonly dataSize: 17080;
|
|
2195
|
+
readonly label: "Micro";
|
|
2196
|
+
readonly description: "64 slots (V1D legacy, postBitmap=18)";
|
|
2197
|
+
};
|
|
2198
|
+
readonly small: {
|
|
2199
|
+
readonly maxAccounts: 256;
|
|
2200
|
+
readonly dataSize: 65104;
|
|
2201
|
+
readonly label: "Small";
|
|
2202
|
+
readonly description: "256 slots (V1D legacy, postBitmap=18)";
|
|
2203
|
+
};
|
|
2204
|
+
readonly medium: {
|
|
2205
|
+
readonly maxAccounts: 1024;
|
|
2206
|
+
readonly dataSize: 257200;
|
|
2207
|
+
readonly label: "Medium";
|
|
2208
|
+
readonly description: "1,024 slots (V1D legacy, postBitmap=18)";
|
|
2209
|
+
};
|
|
2210
|
+
readonly large: {
|
|
2211
|
+
readonly maxAccounts: 4096;
|
|
2212
|
+
readonly dataSize: 1025584;
|
|
2213
|
+
readonly label: "Large";
|
|
2214
|
+
readonly description: "4,096 slots (V1D legacy, postBitmap=18)";
|
|
2215
|
+
};
|
|
2216
|
+
};
|
|
2217
|
+
/** @deprecated Alias — use SLAB_TIERS (already V1) */
|
|
2218
|
+
declare const SLAB_TIERS_V1: {
|
|
2219
|
+
readonly micro: {
|
|
2220
|
+
maxAccounts: number;
|
|
2221
|
+
dataSize: number;
|
|
2222
|
+
label: string;
|
|
2223
|
+
description: string;
|
|
2224
|
+
};
|
|
2225
|
+
readonly small: {
|
|
2226
|
+
maxAccounts: number;
|
|
2227
|
+
dataSize: number;
|
|
2228
|
+
label: string;
|
|
2229
|
+
description: string;
|
|
2230
|
+
};
|
|
2231
|
+
readonly medium: {
|
|
2232
|
+
maxAccounts: number;
|
|
2233
|
+
dataSize: number;
|
|
2234
|
+
label: string;
|
|
2235
|
+
description: string;
|
|
2236
|
+
};
|
|
2237
|
+
readonly large: {
|
|
2238
|
+
maxAccounts: number;
|
|
2239
|
+
dataSize: number;
|
|
2240
|
+
label: string;
|
|
2241
|
+
description: string;
|
|
2242
|
+
};
|
|
2243
|
+
};
|
|
2244
|
+
/**
|
|
2245
|
+
* V_ADL slab tier sizes — PERC-8270/8271 ADL-upgraded program.
|
|
2246
|
+
* ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312, postBitmap=18.
|
|
2247
|
+
* New account layout adds ADL tracking fields (+64 bytes/account).
|
|
2248
|
+
* BPF SLAB_LEN verified by cargo build-sbf in PERC-8271: large (4096) = 1288304 bytes.
|
|
2249
|
+
*/
|
|
2250
|
+
declare const SLAB_TIERS_V_ADL_DISCOVERY: Record<string, {
|
|
2251
|
+
maxAccounts: number;
|
|
2252
|
+
dataSize: number;
|
|
2253
|
+
label: string;
|
|
2254
|
+
description: string;
|
|
2255
|
+
}>;
|
|
2256
|
+
type SlabTierKey = keyof typeof SLAB_TIERS;
|
|
2257
|
+
/** Calculate slab data size for arbitrary account count.
|
|
2258
|
+
*
|
|
2259
|
+
* Layout (SBF, u128 align = 8):
|
|
2260
|
+
* HEADER(104) + CONFIG(536) → ENGINE_OFF = 640
|
|
2261
|
+
* RiskEngine fixed scalars: 656 bytes (PERC-299: +24 emergency OI, +32 long/short OI)
|
|
2262
|
+
* + bitmap: ceil(N/64)*8
|
|
2263
|
+
* + num_used_accounts(u16) + pad(6) + next_account_id(u64) + free_head(u16) = 18
|
|
2264
|
+
* + next_free: N*2
|
|
2265
|
+
* + pad to 8-byte alignment for Account array
|
|
2266
|
+
* + accounts: N*248
|
|
2267
|
+
*
|
|
2268
|
+
* Must match the on-chain program's SLAB_LEN exactly.
|
|
2269
|
+
*/
|
|
2270
|
+
declare function slabDataSize(maxAccounts: number): number;
|
|
2271
|
+
/**
|
|
2272
|
+
* Calculate slab data size for V1 layout (ENGINE_OFF=640).
|
|
2273
|
+
*
|
|
2274
|
+
* NOTE: This formula is accurate for small (256) and medium (1024) tiers but
|
|
2275
|
+
* underestimates large (4096) by 16 bytes — likely due to a padding/alignment
|
|
2276
|
+
* difference at high account counts or a post-PERC-118 struct addition in the
|
|
2277
|
+
* deployed binary. Always prefer the hardcoded SLAB_TIERS values (empirically
|
|
2278
|
+
* verified on-chain) over this formula for production use.
|
|
2279
|
+
*/
|
|
2280
|
+
declare function slabDataSizeV1(maxAccounts: number): number;
|
|
2281
|
+
/**
|
|
2282
|
+
* Validate that a slab data size matches one of the known tier sizes.
|
|
2283
|
+
* Use this to catch tier↔program mismatches early (PERC-277).
|
|
2284
|
+
*
|
|
2285
|
+
* @param dataSize - The expected slab data size (from SLAB_TIERS[tier].dataSize)
|
|
2286
|
+
* @param programSlabLen - The program's compiled SLAB_LEN (from on-chain error logs or program introspection)
|
|
2287
|
+
* @returns true if sizes match, false if there's a mismatch
|
|
2288
|
+
*/
|
|
2289
|
+
declare function validateSlabTierMatch(dataSize: number, programSlabLen: number): boolean;
|
|
2290
|
+
/** Options for `discoverMarkets`. */
|
|
2291
|
+
interface DiscoverMarketsOptions {
|
|
2292
|
+
/**
|
|
2293
|
+
* Run tier queries sequentially with per-tier retry on HTTP 429 instead of
|
|
2294
|
+
* firing all in parallel. Reduces RPC rate-limit pressure at the cost of
|
|
2295
|
+
* slightly slower discovery (~14 round-trips instead of 1 concurrent batch).
|
|
2296
|
+
* Default: false (preserves original parallel behaviour).
|
|
2297
|
+
*
|
|
2298
|
+
* PERC-1650: keeper uses this flag to avoid 429 storms on its fallback RPC
|
|
2299
|
+
* (Helius starter tier). Pass `sequential: true` from CrankService.discover().
|
|
2300
|
+
*/
|
|
2301
|
+
sequential?: boolean;
|
|
2302
|
+
/**
|
|
2303
|
+
* Delay in ms between sequential tier queries (only used when sequential=true).
|
|
2304
|
+
* Default: 200 ms.
|
|
2305
|
+
*/
|
|
2306
|
+
interTierDelayMs?: number;
|
|
2307
|
+
/**
|
|
2308
|
+
* Per-tier retry backoff delays on 429 (ms). Jitter of up to +25% is applied.
|
|
2309
|
+
* Only used when sequential=true. Default: [1_000, 3_000, 9_000, 27_000].
|
|
2310
|
+
*/
|
|
2311
|
+
rateLimitBackoffMs?: number[];
|
|
2312
|
+
/**
|
|
2313
|
+
* In parallel mode (the default), cap how many tier RPC requests are in-flight
|
|
2314
|
+
* at once to avoid accidental RPC storms from client code.
|
|
2315
|
+
*
|
|
2316
|
+
* Default: 6
|
|
2317
|
+
*/
|
|
2318
|
+
maxParallelTiers?: number;
|
|
2319
|
+
/**
|
|
2320
|
+
* Hard cap on how many tier dataSize queries are attempted.
|
|
2321
|
+
* Default: all known tiers.
|
|
2322
|
+
*/
|
|
2323
|
+
maxTierQueries?: number;
|
|
2324
|
+
/**
|
|
2325
|
+
* Base URL of the Percolator REST API (e.g. `"https://percolatorlaunch.com/api"`).
|
|
2326
|
+
*
|
|
2327
|
+
* When set, `discoverMarkets` will fall back to the REST API's `GET /markets`
|
|
2328
|
+
* endpoint if `getProgramAccounts` fails or returns 0 results (common on public
|
|
2329
|
+
* mainnet RPCs that reject `getProgramAccounts`).
|
|
2330
|
+
*
|
|
2331
|
+
* The API returns slab addresses which are then fetched on-chain via
|
|
2332
|
+
* `getMarketsByAddress` (uses `getMultipleAccounts`, works on all RPCs).
|
|
2333
|
+
*
|
|
2334
|
+
* GH#59 / PERC-8424: Unblocks mainnet users without a Helius API key.
|
|
2335
|
+
*
|
|
2336
|
+
* @example
|
|
2337
|
+
* ```ts
|
|
2338
|
+
* const markets = await discoverMarkets(connection, programId, {
|
|
2339
|
+
* apiBaseUrl: "https://percolatorlaunch.com/api",
|
|
2340
|
+
* });
|
|
2341
|
+
* ```
|
|
2342
|
+
*/
|
|
2343
|
+
apiBaseUrl?: string;
|
|
2344
|
+
/**
|
|
2345
|
+
* Timeout in ms for the API fallback HTTP request.
|
|
2346
|
+
* Only used when `apiBaseUrl` is set.
|
|
2347
|
+
* Default: 10_000 (10 seconds).
|
|
2348
|
+
*/
|
|
2349
|
+
apiTimeoutMs?: number;
|
|
2350
|
+
/**
|
|
2351
|
+
* Network hint for tier-3 static bundle fallback (`"mainnet"` or `"devnet"`).
|
|
2352
|
+
*
|
|
2353
|
+
* When both `getProgramAccounts` (tier 1) and the REST API (tier 2) fail,
|
|
2354
|
+
* `discoverMarkets` will fall back to a bundled static list of known slab
|
|
2355
|
+
* addresses for the specified network. The addresses are fetched on-chain
|
|
2356
|
+
* via `getMarketsByAddress` (`getMultipleAccounts` — works on all RPCs).
|
|
2357
|
+
*
|
|
2358
|
+
* If not set, tier-3 fallback is disabled.
|
|
2359
|
+
*
|
|
2360
|
+
* The static list can be extended at runtime via `registerStaticMarkets()`.
|
|
2361
|
+
*
|
|
2362
|
+
* @see {@link registerStaticMarkets} to add addresses at runtime
|
|
2363
|
+
* @see {@link getStaticMarkets} to inspect the current static list
|
|
2364
|
+
*
|
|
2365
|
+
* @example
|
|
2366
|
+
* ```ts
|
|
2367
|
+
* const markets = await discoverMarkets(connection, programId, {
|
|
2368
|
+
* apiBaseUrl: "https://percolatorlaunch.com/api",
|
|
2369
|
+
* network: "mainnet", // enables tier-3 static fallback
|
|
2370
|
+
* });
|
|
2371
|
+
* ```
|
|
2372
|
+
*/
|
|
2373
|
+
network?: Network;
|
|
2374
|
+
}
|
|
2375
|
+
/**
|
|
2376
|
+
* Discover all Percolator markets owned by the given program.
|
|
2377
|
+
* Uses getProgramAccounts with dataSize filter + dataSlice to download only ~1400 bytes per slab.
|
|
2378
|
+
*
|
|
2379
|
+
* @param options.sequential - Run tier queries sequentially with 429 retry (PERC-1650).
|
|
2380
|
+
*/
|
|
2381
|
+
declare function discoverMarkets(connection: Connection, programId: PublicKey, options?: DiscoverMarketsOptions): Promise<DiscoveredMarket[]>;
|
|
2382
|
+
/**
|
|
2383
|
+
* Options for `getMarketsByAddress`.
|
|
2384
|
+
*/
|
|
2385
|
+
interface GetMarketsByAddressOptions {
|
|
2386
|
+
/**
|
|
2387
|
+
* Maximum number of addresses per `getMultipleAccounts` RPC call.
|
|
2388
|
+
* Solana limits a single call to 100 accounts; callers may lower this
|
|
2389
|
+
* to reduce per-request payload size or avoid 429s.
|
|
2390
|
+
*
|
|
2391
|
+
* Default: 100 (Solana maximum).
|
|
2392
|
+
*/
|
|
2393
|
+
batchSize?: number;
|
|
2394
|
+
/**
|
|
2395
|
+
* Delay in ms between batches when the address list exceeds `batchSize`.
|
|
2396
|
+
* Helps avoid rate-limiting on public RPCs.
|
|
2397
|
+
*
|
|
2398
|
+
* Default: 0 (no delay).
|
|
2399
|
+
*/
|
|
2400
|
+
interBatchDelayMs?: number;
|
|
2401
|
+
}
|
|
2402
|
+
/**
|
|
2403
|
+
* Fetch and parse Percolator markets by their known slab addresses.
|
|
2404
|
+
*
|
|
2405
|
+
* Unlike `discoverMarkets()` — which uses `getProgramAccounts` and is blocked
|
|
2406
|
+
* on public mainnet RPCs — this function uses `getMultipleAccounts`, which works
|
|
2407
|
+
* on any RPC endpoint (including `api.mainnet-beta.solana.com`).
|
|
2408
|
+
*
|
|
2409
|
+
* Callers must already know the market slab addresses (e.g. from an indexer,
|
|
2410
|
+
* a hardcoded registry, or a previous `discoverMarkets` call on a permissive RPC).
|
|
2411
|
+
*
|
|
2412
|
+
* @param connection - Solana RPC connection
|
|
2413
|
+
* @param programId - The Percolator program that owns these slabs
|
|
2414
|
+
* @param addresses - Array of slab account public keys to fetch
|
|
2415
|
+
* @param options - Optional batching/delay configuration
|
|
2416
|
+
* @returns Parsed markets for all valid slab accounts; invalid/missing accounts are silently skipped.
|
|
2417
|
+
*
|
|
2418
|
+
* @example
|
|
2419
|
+
* ```ts
|
|
2420
|
+
* import { getMarketsByAddress, getProgramId } from "@percolator/sdk";
|
|
2421
|
+
* import { Connection, PublicKey } from "@solana/web3.js";
|
|
2422
|
+
*
|
|
2423
|
+
* const connection = new Connection("https://api.mainnet-beta.solana.com");
|
|
2424
|
+
* const programId = getProgramId("mainnet");
|
|
2425
|
+
* const slabs = [
|
|
2426
|
+
* new PublicKey("So11111111111111111111111111111111111111112"),
|
|
2427
|
+
* // ... more known slab addresses
|
|
2428
|
+
* ];
|
|
2429
|
+
*
|
|
2430
|
+
* const markets = await getMarketsByAddress(connection, programId, slabs);
|
|
2431
|
+
* console.log(`Found ${markets.length} markets`);
|
|
2432
|
+
* ```
|
|
2433
|
+
*/
|
|
2434
|
+
declare function getMarketsByAddress(connection: Connection, programId: PublicKey, addresses: PublicKey[], options?: GetMarketsByAddressOptions): Promise<DiscoveredMarket[]>;
|
|
2435
|
+
/**
|
|
2436
|
+
* Shape of a single market entry returned by the Percolator REST API
|
|
2437
|
+
* (`GET /markets`). Only the fields needed for discovery are typed here;
|
|
2438
|
+
* the full API response may contain additional statistics fields.
|
|
2439
|
+
*/
|
|
2440
|
+
interface ApiMarketEntry {
|
|
2441
|
+
slab_address: string;
|
|
2442
|
+
symbol?: string;
|
|
2443
|
+
name?: string;
|
|
2444
|
+
decimals?: number;
|
|
2445
|
+
status?: string;
|
|
2446
|
+
[key: string]: unknown;
|
|
2447
|
+
}
|
|
2448
|
+
/** Options for {@link discoverMarketsViaApi}. */
|
|
2449
|
+
interface DiscoverMarketsViaApiOptions {
|
|
2450
|
+
/**
|
|
2451
|
+
* Timeout in ms for the HTTP request to the REST API.
|
|
2452
|
+
* Default: 10_000 (10 seconds).
|
|
2453
|
+
*/
|
|
2454
|
+
timeoutMs?: number;
|
|
2455
|
+
/**
|
|
2456
|
+
* Options forwarded to {@link getMarketsByAddress} for the on-chain fetch
|
|
2457
|
+
* step (batch size, inter-batch delay).
|
|
2458
|
+
*/
|
|
2459
|
+
onChainOptions?: GetMarketsByAddressOptions;
|
|
2460
|
+
}
|
|
2461
|
+
/**
|
|
2462
|
+
* Discover Percolator markets by first querying the REST API for slab addresses,
|
|
2463
|
+
* then fetching full on-chain data via `getMarketsByAddress` (which uses
|
|
2464
|
+
* `getMultipleAccounts` — works on all RPCs including public mainnet nodes).
|
|
2465
|
+
*
|
|
2466
|
+
* This is the recommended discovery path for mainnet users who do not have a
|
|
2467
|
+
* Helius API key, since `getProgramAccounts` is rejected by public RPCs.
|
|
2468
|
+
*
|
|
2469
|
+
* The REST API acts as an address directory only — all market data is verified
|
|
2470
|
+
* on-chain via `getMarketsByAddress`, so the caller gets the same
|
|
2471
|
+
* `DiscoveredMarket[]` result as `discoverMarkets()`.
|
|
2472
|
+
*
|
|
2473
|
+
* @param connection - Solana RPC connection (any endpoint, including public)
|
|
2474
|
+
* @param programId - The Percolator program that owns the slabs
|
|
2475
|
+
* @param apiBaseUrl - Base URL of the Percolator REST API
|
|
2476
|
+
* (e.g. `"https://percolatorlaunch.com/api"`)
|
|
2477
|
+
* @param options - Optional timeout and on-chain fetch configuration
|
|
2478
|
+
* @returns Parsed markets for all valid slab accounts discovered via the API
|
|
2479
|
+
*
|
|
2480
|
+
* @example
|
|
2481
|
+
* ```ts
|
|
2482
|
+
* import { discoverMarketsViaApi, getProgramId } from "@percolator/sdk";
|
|
2483
|
+
* import { Connection } from "@solana/web3.js";
|
|
2484
|
+
*
|
|
2485
|
+
* const connection = new Connection("https://api.mainnet-beta.solana.com");
|
|
2486
|
+
* const programId = getProgramId("mainnet");
|
|
2487
|
+
* const markets = await discoverMarketsViaApi(
|
|
2488
|
+
* connection,
|
|
2489
|
+
* programId,
|
|
2490
|
+
* "https://percolatorlaunch.com/api",
|
|
2491
|
+
* );
|
|
2492
|
+
* console.log(`Discovered ${markets.length} markets via API fallback`);
|
|
2493
|
+
* ```
|
|
2494
|
+
*/
|
|
2495
|
+
declare function discoverMarketsViaApi(connection: Connection, programId: PublicKey, apiBaseUrl: string, options?: DiscoverMarketsViaApiOptions): Promise<DiscoveredMarket[]>;
|
|
2496
|
+
/** Options for {@link discoverMarketsViaStaticBundle}. */
|
|
2497
|
+
interface DiscoverMarketsViaStaticBundleOptions {
|
|
2498
|
+
/**
|
|
2499
|
+
* Options forwarded to {@link getMarketsByAddress} for the on-chain fetch
|
|
2500
|
+
* step (batch size, inter-batch delay).
|
|
2501
|
+
*/
|
|
2502
|
+
onChainOptions?: GetMarketsByAddressOptions;
|
|
2503
|
+
}
|
|
2504
|
+
/**
|
|
2505
|
+
* Discover Percolator markets from a static list of known slab addresses.
|
|
2506
|
+
*
|
|
2507
|
+
* This is the tier-3 (last-resort) fallback for `discoverMarkets()`. It uses
|
|
2508
|
+
* a bundled list of known slab addresses and fetches their full account data
|
|
2509
|
+
* on-chain via `getMarketsByAddress` (`getMultipleAccounts` — works on all RPCs).
|
|
2510
|
+
*
|
|
2511
|
+
* The static list acts as an address directory only — all market data is verified
|
|
2512
|
+
* on-chain, so stale entries are silently skipped (the account won't have valid
|
|
2513
|
+
* magic bytes or will have been closed).
|
|
2514
|
+
*
|
|
2515
|
+
* @param connection - Solana RPC connection (any endpoint)
|
|
2516
|
+
* @param programId - The Percolator program that owns the slabs
|
|
2517
|
+
* @param entries - Static market entries (typically from {@link getStaticMarkets})
|
|
2518
|
+
* @param options - Optional on-chain fetch configuration
|
|
2519
|
+
* @returns Parsed markets for all valid slab accounts; stale/missing entries are skipped.
|
|
2520
|
+
*
|
|
2521
|
+
* @example
|
|
2522
|
+
* ```ts
|
|
2523
|
+
* import {
|
|
2524
|
+
* discoverMarketsViaStaticBundle,
|
|
2525
|
+
* getStaticMarkets,
|
|
2526
|
+
* getProgramId,
|
|
2527
|
+
* } from "@percolator/sdk";
|
|
2528
|
+
* import { Connection } from "@solana/web3.js";
|
|
2529
|
+
*
|
|
2530
|
+
* const connection = new Connection("https://api.mainnet-beta.solana.com");
|
|
2531
|
+
* const programId = getProgramId("mainnet");
|
|
2532
|
+
* const entries = getStaticMarkets("mainnet");
|
|
2533
|
+
*
|
|
2534
|
+
* const markets = await discoverMarketsViaStaticBundle(
|
|
2535
|
+
* connection,
|
|
2536
|
+
* programId,
|
|
2537
|
+
* entries,
|
|
2538
|
+
* );
|
|
2539
|
+
* console.log(`Recovered ${markets.length} markets from static bundle`);
|
|
2540
|
+
* ```
|
|
2541
|
+
*/
|
|
2542
|
+
declare function discoverMarketsViaStaticBundle(connection: Connection, programId: PublicKey, entries: StaticMarketEntry[], options?: DiscoverMarketsViaStaticBundleOptions): Promise<DiscoveredMarket[]>;
|
|
2543
|
+
|
|
2544
|
+
type DexType = "pumpswap" | "raydium-clmm" | "meteora-dlmm";
|
|
2545
|
+
interface DexPoolInfo {
|
|
2546
|
+
dexType: DexType;
|
|
2547
|
+
poolAddress: PublicKey;
|
|
2548
|
+
baseMint: PublicKey;
|
|
2549
|
+
quoteMint: PublicKey;
|
|
2550
|
+
baseVault?: PublicKey;
|
|
2551
|
+
quoteVault?: PublicKey;
|
|
2552
|
+
}
|
|
2553
|
+
/**
|
|
2554
|
+
* Detect DEX type from the program that owns the pool account.
|
|
2555
|
+
*
|
|
2556
|
+
* @param ownerProgramId - The program ID that owns the pool account
|
|
2557
|
+
* @returns The detected DEX type, or `null` if the owner is not a supported DEX program
|
|
2558
|
+
*
|
|
2559
|
+
* Supported DEX programs:
|
|
2560
|
+
* - PumpSwap (constant-product AMM)
|
|
2561
|
+
* - Raydium CLMM (concentrated liquidity)
|
|
2562
|
+
* - Meteora DLMM (discretized liquidity)
|
|
2563
|
+
*/
|
|
2564
|
+
declare function detectDexType(ownerProgramId: PublicKey): DexType | null;
|
|
2565
|
+
/**
|
|
2566
|
+
* Parse a DEX pool account into a {@link DexPoolInfo} struct.
|
|
2567
|
+
*
|
|
2568
|
+
* @param dexType - The type of DEX (pumpswap, raydium-clmm, or meteora-dlmm)
|
|
2569
|
+
* @param poolAddress - The on-chain address of the pool account
|
|
2570
|
+
* @param data - Raw account data bytes
|
|
2571
|
+
* @returns Parsed pool info including mints and (for PumpSwap) vault addresses
|
|
2572
|
+
* @throws Error if data is too short for the given DEX type
|
|
2573
|
+
*/
|
|
2574
|
+
declare function parseDexPool(dexType: DexType, poolAddress: PublicKey, data: Uint8Array): DexPoolInfo;
|
|
2575
|
+
/**
|
|
2576
|
+
* Compute the spot price from a DEX pool in e6 format (i.e., 1.0 = 1_000_000).
|
|
2577
|
+
*
|
|
2578
|
+
* **SECURITY NOTE:** DEX spot prices have no staleness or confidence checks and are
|
|
2579
|
+
* vulnerable to flash-loan manipulation within a single transaction. For high-value
|
|
2580
|
+
* markets, prefer Pyth or Chainlink oracles.
|
|
2581
|
+
*
|
|
2582
|
+
* @param dexType - The type of DEX
|
|
2583
|
+
* @param data - Raw pool account data
|
|
2584
|
+
* @param vaultData - For PumpSwap only: base and quote vault account data
|
|
2585
|
+
* @returns Price in e6 format (quote per base token)
|
|
2586
|
+
* @throws Error if data is too short or computation fails
|
|
2587
|
+
*/
|
|
2588
|
+
declare function computeDexSpotPriceE6(dexType: DexType, data: Uint8Array, vaultData?: {
|
|
2589
|
+
base: Uint8Array;
|
|
2590
|
+
quote: Uint8Array;
|
|
2591
|
+
}): bigint;
|
|
2592
|
+
|
|
2593
|
+
/**
|
|
2594
|
+
* Oracle account parsing utilities.
|
|
2595
|
+
*
|
|
2596
|
+
* Chainlink aggregator layout on Solana (from Toly's percolator-cli):
|
|
2597
|
+
* offset 138: decimals (u8)
|
|
2598
|
+
* offset 216: latest answer (i64 LE)
|
|
2599
|
+
*
|
|
2600
|
+
* Minimum account size: 224 bytes (offset 216 + 8 bytes for i64).
|
|
2601
|
+
*
|
|
2602
|
+
* These utilities validate oracle data BEFORE parsing to prevent silent
|
|
2603
|
+
* propagation of stale or malformed Chainlink data as price.
|
|
2604
|
+
*/
|
|
2605
|
+
/** Minimum buffer size to read Chainlink price data */
|
|
2606
|
+
declare const CHAINLINK_MIN_SIZE = 224;
|
|
2607
|
+
/** Maximum reasonable decimals for a price feed */
|
|
2608
|
+
declare const MAX_DECIMALS = 18;
|
|
2609
|
+
/** Offset of decimals field in Chainlink aggregator account */
|
|
2610
|
+
declare const CHAINLINK_DECIMALS_OFFSET = 138;
|
|
2611
|
+
/** Offset of latest answer in Chainlink aggregator account */
|
|
2612
|
+
declare const CHAINLINK_ANSWER_OFFSET = 216;
|
|
2613
|
+
interface OraclePrice {
|
|
2614
|
+
price: bigint;
|
|
2615
|
+
decimals: number;
|
|
2616
|
+
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Parse price data from a Chainlink aggregator account buffer.
|
|
2619
|
+
*
|
|
2620
|
+
* Validates:
|
|
2621
|
+
* - Buffer is large enough to contain the required fields (≥ 224 bytes)
|
|
2622
|
+
* - Decimals are in a reasonable range (0-18)
|
|
2623
|
+
* - Price is positive (non-zero)
|
|
2624
|
+
*
|
|
2625
|
+
* @param data - Raw account data from Chainlink aggregator
|
|
2626
|
+
* @returns Parsed oracle price with decimals
|
|
2627
|
+
* @throws if the buffer is invalid or contains unreasonable data
|
|
2628
|
+
*/
|
|
2629
|
+
declare function parseChainlinkPrice(data: Uint8Array): OraclePrice;
|
|
2630
|
+
/**
|
|
2631
|
+
* Validate that a buffer looks like a valid Chainlink aggregator account.
|
|
2632
|
+
* Returns true if the buffer passes all validation checks, false otherwise.
|
|
2633
|
+
* Use this for non-throwing validation.
|
|
2634
|
+
*/
|
|
2635
|
+
declare function isValidChainlinkOracle(data: Uint8Array): boolean;
|
|
2636
|
+
|
|
2637
|
+
/**
|
|
2638
|
+
* Token2022 (Token Extensions) program ID.
|
|
2639
|
+
*/
|
|
2640
|
+
declare const TOKEN_2022_PROGRAM_ID: PublicKey;
|
|
2641
|
+
/**
|
|
2642
|
+
* Detect which token program owns a given mint account.
|
|
2643
|
+
* Returns the owner program ID (TOKEN_PROGRAM_ID or TOKEN_2022_PROGRAM_ID).
|
|
2644
|
+
* Throws if the mint account doesn't exist.
|
|
2645
|
+
*/
|
|
2646
|
+
declare function detectTokenProgram(connection: Connection, mint: PublicKey): Promise<PublicKey>;
|
|
2647
|
+
/**
|
|
2648
|
+
* Check if a given token program ID is Token2022.
|
|
2649
|
+
*/
|
|
2650
|
+
declare function isToken2022(tokenProgramId: PublicKey): boolean;
|
|
2651
|
+
/**
|
|
2652
|
+
* Check if a given token program ID is the standard SPL Token program.
|
|
2653
|
+
*/
|
|
2654
|
+
declare function isStandardToken(tokenProgramId: PublicKey): boolean;
|
|
2655
|
+
|
|
2656
|
+
/**
|
|
2657
|
+
* @module stake
|
|
2658
|
+
* Percolator Insurance LP Staking program — instruction encoders, PDA derivation, and account specs.
|
|
2659
|
+
*
|
|
2660
|
+
* Program: percolator-stake (dcccrypto/percolator-stake)
|
|
2661
|
+
* Deployed devnet: 6aJb1F9CDCVWCNYFwj8aQsVb696YnW6J1FznteHq4Q6k
|
|
2662
|
+
* Deployed mainnet: DC5fovFQD5SZYsetwvEqd4Wi4PFY1Yfnc669VMe6oa7F
|
|
2663
|
+
*/
|
|
2664
|
+
|
|
2665
|
+
/** Known stake program addresses per network. Mainnet is empty until deployed. */
|
|
2666
|
+
declare const STAKE_PROGRAM_IDS: {
|
|
2667
|
+
readonly devnet: "6aJb1F9CDCVWCNYFwj8aQsVb696YnW6J1FznteHq4Q6k";
|
|
2668
|
+
readonly mainnet: "DC5fovFQD5SZYsetwvEqd4Wi4PFY1Yfnc669VMe6oa7F";
|
|
2669
|
+
};
|
|
2670
|
+
/**
|
|
2671
|
+
* Resolve the stake program ID for the given network.
|
|
2672
|
+
*
|
|
2673
|
+
* Priority:
|
|
2674
|
+
* 1. STAKE_PROGRAM_ID env var (explicit override — DevOps sets this for mainnet until constant is filled)
|
|
2675
|
+
* 2. Network-specific constant from STAKE_PROGRAM_IDS
|
|
2676
|
+
*
|
|
2677
|
+
* Throws a clear error on mainnet when no address is available so callers
|
|
2678
|
+
* surface the gap instead of silently hitting the devnet program.
|
|
2679
|
+
*/
|
|
2680
|
+
declare function getStakeProgramId(network?: 'devnet' | 'mainnet'): PublicKey;
|
|
2681
|
+
/**
|
|
2682
|
+
* Default export — resolves for the current runtime network.
|
|
2683
|
+
* Use getStakeProgramId() with an explicit network argument where possible.
|
|
2684
|
+
*
|
|
2685
|
+
* @deprecated Direct use of STAKE_PROGRAM_ID is being phased out in favour of
|
|
2686
|
+
* getStakeProgramId() so mainnet callers get a clear error rather than silently
|
|
2687
|
+
* resolving to the devnet address.
|
|
2688
|
+
*/
|
|
2689
|
+
declare const STAKE_PROGRAM_ID: PublicKey;
|
|
2690
|
+
declare const STAKE_IX: {
|
|
2691
|
+
readonly InitPool: 0;
|
|
2692
|
+
readonly Deposit: 1;
|
|
2693
|
+
readonly Withdraw: 2;
|
|
2694
|
+
readonly FlushToInsurance: 3;
|
|
2695
|
+
readonly UpdateConfig: 4;
|
|
2696
|
+
readonly TransferAdmin: 5;
|
|
2697
|
+
readonly AdminSetOracleAuthority: 6;
|
|
2698
|
+
readonly AdminSetRiskThreshold: 7;
|
|
2699
|
+
readonly AdminSetMaintenanceFee: 8;
|
|
2700
|
+
readonly AdminResolveMarket: 9;
|
|
2701
|
+
readonly AdminWithdrawInsurance: 10;
|
|
2702
|
+
readonly AdminSetInsurancePolicy: 11;
|
|
2703
|
+
/** PERC-272: Accrue trading fees to LP vault */
|
|
2704
|
+
readonly AccrueFees: 12;
|
|
2705
|
+
/** PERC-272: Init pool in trading LP mode */
|
|
2706
|
+
readonly InitTradingPool: 13;
|
|
2707
|
+
/** PERC-313: Set HWM config (enable + floor bps) */
|
|
2708
|
+
readonly AdminSetHwmConfig: 14;
|
|
2709
|
+
/** PERC-303: Enable/configure senior-junior LP tranches */
|
|
2710
|
+
readonly AdminSetTrancheConfig: 15;
|
|
2711
|
+
/** PERC-303: Deposit into junior (first-loss) tranche */
|
|
2712
|
+
readonly DepositJunior: 16;
|
|
2713
|
+
};
|
|
2714
|
+
/** Derive the stake pool PDA for a given slab (market). */
|
|
2715
|
+
declare function deriveStakePool(slab: PublicKey, programId?: PublicKey): [PublicKey, number];
|
|
2716
|
+
/** Derive the vault authority PDA (signs CPI, owns LP mint + vault). */
|
|
2717
|
+
declare function deriveStakeVaultAuth(pool: PublicKey, programId?: PublicKey): [PublicKey, number];
|
|
2718
|
+
/** Derive the per-user deposit PDA (tracks cooldown, deposit time). */
|
|
2719
|
+
declare function deriveDepositPda(pool: PublicKey, user: PublicKey, programId?: PublicKey): [PublicKey, number];
|
|
2720
|
+
/** Tag 0: InitPool — create stake pool for a slab. */
|
|
2721
|
+
declare function encodeStakeInitPool(cooldownSlots: bigint | number, depositCap: bigint | number): Uint8Array;
|
|
2722
|
+
/** Tag 1: Deposit — deposit collateral, receive LP tokens. */
|
|
2723
|
+
declare function encodeStakeDeposit(amount: bigint | number): Uint8Array;
|
|
2724
|
+
/** Tag 2: Withdraw — burn LP tokens, receive collateral (subject to cooldown). */
|
|
2725
|
+
declare function encodeStakeWithdraw(lpAmount: bigint | number): Uint8Array;
|
|
2726
|
+
/** Tag 3: FlushToInsurance — move collateral from stake vault to wrapper insurance. */
|
|
2727
|
+
declare function encodeStakeFlushToInsurance(amount: bigint | number): Uint8Array;
|
|
2728
|
+
/** Tag 4: UpdateConfig — update cooldown and/or deposit cap. */
|
|
2729
|
+
declare function encodeStakeUpdateConfig(newCooldownSlots?: bigint | number, newDepositCap?: bigint | number): Uint8Array;
|
|
2730
|
+
/** Tag 5: TransferAdmin — transfer wrapper admin to pool PDA. */
|
|
2731
|
+
declare function encodeStakeTransferAdmin(): Uint8Array;
|
|
2732
|
+
/** Tag 6: AdminSetOracleAuthority — forward to wrapper via CPI. */
|
|
2733
|
+
declare function encodeStakeAdminSetOracleAuthority(newAuthority: PublicKey): Uint8Array;
|
|
2734
|
+
/** Tag 7: AdminSetRiskThreshold — forward to wrapper via CPI. */
|
|
2735
|
+
declare function encodeStakeAdminSetRiskThreshold(newThreshold: bigint | number): Uint8Array;
|
|
2736
|
+
/** Tag 8: AdminSetMaintenanceFee — forward to wrapper via CPI. */
|
|
2737
|
+
declare function encodeStakeAdminSetMaintenanceFee(newFee: bigint | number): Uint8Array;
|
|
2738
|
+
/** Tag 9: AdminResolveMarket — forward to wrapper via CPI. */
|
|
2739
|
+
declare function encodeStakeAdminResolveMarket(): Uint8Array;
|
|
2740
|
+
/** Tag 10: AdminWithdrawInsurance — withdraw insurance after market resolution. */
|
|
2741
|
+
declare function encodeStakeAdminWithdrawInsurance(amount: bigint | number): Uint8Array;
|
|
2742
|
+
/** Tag 12: AccrueFees — permissionless: accrue trading fees to LP vault. */
|
|
2743
|
+
declare function encodeStakeAccrueFees(): Uint8Array;
|
|
2744
|
+
/** Tag 13: InitTradingPool — create pool in trading LP mode (pool_mode = 1). */
|
|
2745
|
+
declare function encodeStakeInitTradingPool(cooldownSlots: bigint | number, depositCap: bigint | number): Uint8Array;
|
|
2746
|
+
/** Tag 14 (PERC-313): AdminSetHwmConfig — enable HWM protection and set floor BPS. */
|
|
2747
|
+
declare function encodeStakeAdminSetHwmConfig(enabled: boolean, hwmFloorBps: number): Uint8Array;
|
|
2748
|
+
/** Tag 15 (PERC-303): AdminSetTrancheConfig — enable senior/junior LP tranches. */
|
|
2749
|
+
declare function encodeStakeAdminSetTrancheConfig(juniorFeeMultBps: number): Uint8Array;
|
|
2750
|
+
/** Tag 16 (PERC-303): DepositJunior — deposit into first-loss junior tranche. */
|
|
2751
|
+
declare function encodeStakeDepositJunior(amount: bigint | number): Uint8Array;
|
|
2752
|
+
/** Tag 11: AdminSetInsurancePolicy — set withdrawal policy on wrapper. */
|
|
2753
|
+
declare function encodeStakeAdminSetInsurancePolicy(authority: PublicKey, minWithdrawBase: bigint | number, maxWithdrawBps: number, cooldownSlots: bigint | number): Uint8Array;
|
|
2754
|
+
/**
|
|
2755
|
+
* Decoded StakePool state (352 bytes on-chain).
|
|
2756
|
+
* Includes PERC-272 (fee yield), PERC-313 (HWM), and PERC-303 (tranches).
|
|
2757
|
+
*/
|
|
2758
|
+
interface StakePoolState {
|
|
2759
|
+
isInitialized: boolean;
|
|
2760
|
+
bump: number;
|
|
2761
|
+
vaultAuthorityBump: number;
|
|
2762
|
+
adminTransferred: boolean;
|
|
2763
|
+
slab: PublicKey;
|
|
2764
|
+
admin: PublicKey;
|
|
2765
|
+
collateralMint: PublicKey;
|
|
2766
|
+
lpMint: PublicKey;
|
|
2767
|
+
vault: PublicKey;
|
|
2768
|
+
totalDeposited: bigint;
|
|
2769
|
+
totalLpSupply: bigint;
|
|
2770
|
+
cooldownSlots: bigint;
|
|
2771
|
+
depositCap: bigint;
|
|
2772
|
+
totalFlushed: bigint;
|
|
2773
|
+
totalReturned: bigint;
|
|
2774
|
+
totalWithdrawn: bigint;
|
|
2775
|
+
percolatorProgram: PublicKey;
|
|
2776
|
+
totalFeesEarned: bigint;
|
|
2777
|
+
lastFeeAccrualSlot: bigint;
|
|
2778
|
+
lastVaultSnapshot: bigint;
|
|
2779
|
+
poolMode: number;
|
|
2780
|
+
hwmEnabled: boolean;
|
|
2781
|
+
epochHighWaterTvl: bigint;
|
|
2782
|
+
hwmFloorBps: number;
|
|
2783
|
+
trancheEnabled: boolean;
|
|
2784
|
+
juniorBalance: bigint;
|
|
2785
|
+
juniorTotalLp: bigint;
|
|
2786
|
+
juniorFeeMultBps: number;
|
|
2787
|
+
}
|
|
2788
|
+
/** Size of StakePool on-chain (bytes). */
|
|
2789
|
+
declare const STAKE_POOL_SIZE = 352;
|
|
2790
|
+
/**
|
|
2791
|
+
* Decode a StakePool account from raw data buffer. * Uses DataView for all u64/u16 reads — browser-safe.
|
|
2792
|
+
*/
|
|
2793
|
+
declare function decodeStakePool(data: Uint8Array): StakePoolState;
|
|
2794
|
+
interface StakeAccounts {
|
|
2795
|
+
/** InitPool accounts */
|
|
2796
|
+
initPool: {
|
|
2797
|
+
admin: PublicKey;
|
|
2798
|
+
slab: PublicKey;
|
|
2799
|
+
pool: PublicKey;
|
|
2800
|
+
lpMint: PublicKey;
|
|
2801
|
+
vault: PublicKey;
|
|
2802
|
+
vaultAuth: PublicKey;
|
|
2803
|
+
collateralMint: PublicKey;
|
|
2804
|
+
percolatorProgram: PublicKey;
|
|
2805
|
+
};
|
|
2806
|
+
/** Deposit accounts */
|
|
2807
|
+
deposit: {
|
|
2808
|
+
user: PublicKey;
|
|
2809
|
+
pool: PublicKey;
|
|
2810
|
+
userCollateralAta: PublicKey;
|
|
2811
|
+
vault: PublicKey;
|
|
2812
|
+
lpMint: PublicKey;
|
|
2813
|
+
userLpAta: PublicKey;
|
|
2814
|
+
vaultAuth: PublicKey;
|
|
2815
|
+
depositPda: PublicKey;
|
|
2816
|
+
};
|
|
2817
|
+
/** Withdraw accounts */
|
|
2818
|
+
withdraw: {
|
|
2819
|
+
user: PublicKey;
|
|
2820
|
+
pool: PublicKey;
|
|
2821
|
+
userLpAta: PublicKey;
|
|
2822
|
+
lpMint: PublicKey;
|
|
2823
|
+
vault: PublicKey;
|
|
2824
|
+
userCollateralAta: PublicKey;
|
|
2825
|
+
vaultAuth: PublicKey;
|
|
2826
|
+
depositPda: PublicKey;
|
|
2827
|
+
};
|
|
2828
|
+
/** FlushToInsurance accounts (CPI from stake → percolator) */
|
|
2829
|
+
flushToInsurance: {
|
|
2830
|
+
caller: PublicKey;
|
|
2831
|
+
pool: PublicKey;
|
|
2832
|
+
vault: PublicKey;
|
|
2833
|
+
vaultAuth: PublicKey;
|
|
2834
|
+
slab: PublicKey;
|
|
2835
|
+
wrapperVault: PublicKey;
|
|
2836
|
+
percolatorProgram: PublicKey;
|
|
2837
|
+
};
|
|
2838
|
+
}
|
|
2839
|
+
/**
|
|
2840
|
+
* Build account keys for InitPool instruction.
|
|
2841
|
+
* Returns array of {pubkey, isSigner, isWritable} in the order the program expects.
|
|
2842
|
+
*/
|
|
2843
|
+
declare function initPoolAccounts(a: StakeAccounts['initPool']): {
|
|
2844
|
+
pubkey: PublicKey;
|
|
2845
|
+
isSigner: boolean;
|
|
2846
|
+
isWritable: boolean;
|
|
2847
|
+
}[];
|
|
2848
|
+
/**
|
|
2849
|
+
* Build account keys for Deposit instruction.
|
|
2850
|
+
*/
|
|
2851
|
+
declare function depositAccounts(a: StakeAccounts['deposit']): {
|
|
2852
|
+
pubkey: PublicKey;
|
|
2853
|
+
isSigner: boolean;
|
|
2854
|
+
isWritable: boolean;
|
|
2855
|
+
}[];
|
|
2856
|
+
/**
|
|
2857
|
+
* Build account keys for Withdraw instruction.
|
|
2858
|
+
*/
|
|
2859
|
+
declare function withdrawAccounts(a: StakeAccounts['withdraw']): {
|
|
2860
|
+
pubkey: PublicKey;
|
|
2861
|
+
isSigner: boolean;
|
|
2862
|
+
isWritable: boolean;
|
|
2863
|
+
}[];
|
|
2864
|
+
/**
|
|
2865
|
+
* Build account keys for FlushToInsurance instruction.
|
|
2866
|
+
*/
|
|
2867
|
+
declare function flushToInsuranceAccounts(a: StakeAccounts['flushToInsurance']): {
|
|
2868
|
+
pubkey: PublicKey;
|
|
2869
|
+
isSigner: boolean;
|
|
2870
|
+
isWritable: boolean;
|
|
2871
|
+
}[];
|
|
2872
|
+
|
|
2873
|
+
/**
|
|
2874
|
+
* @module adl
|
|
2875
|
+
* Percolator ADL (Auto-Deleveraging) client utilities.
|
|
2876
|
+
*
|
|
2877
|
+
* PERC-8278 / PERC-8312 / PERC-305: ADL is triggered when `pnl_pos_tot > max_pnl_cap`
|
|
2878
|
+
* on a market (PnL cap exceeded) AND the insurance fund is fully depleted (balance == 0).
|
|
2879
|
+
* The most profitable positions on the dominant side are deleveraged first.
|
|
2880
|
+
*
|
|
2881
|
+
* **Note on caller permissions:** `ExecuteAdl` (tag 50) requires the caller to be the
|
|
2882
|
+
* market admin/keeper key (`header.admin`). It is NOT permissionless despite the
|
|
2883
|
+
* instruction being structurally available to any signer.
|
|
2884
|
+
*
|
|
2885
|
+
* API surface:
|
|
2886
|
+
* - fetchAdlRankedPositions() — fetch slab + rank all open positions by PnL%
|
|
2887
|
+
* - rankAdlPositions() — pure (no-RPC) variant for already-fetched slab bytes
|
|
2888
|
+
* - isAdlTriggered() — check if slab's pnl_pos_tot exceeds max_pnl_cap
|
|
2889
|
+
* - buildAdlInstruction() — build a single ExecuteAdl TransactionInstruction
|
|
2890
|
+
* - buildAdlTransaction() — fetch + rank + pick top target + return instruction
|
|
2891
|
+
* - parseAdlEvent() — decode AdlEvent from transaction log lines
|
|
2892
|
+
* - fetchAdlRankings() — call /api/adl/rankings HTTP endpoint
|
|
2893
|
+
* - AdlRankedPosition — position record with adl_rank and computed pnlPct
|
|
2894
|
+
* - AdlRankingResult — full ranking with trigger status
|
|
2895
|
+
* - AdlEvent — decoded on-chain AdlEvent log entry (tag 0xAD1E_0001)
|
|
2896
|
+
* - AdlApiRanking — single ranked position from /api/adl/rankings
|
|
2897
|
+
* - AdlApiResult — full result from /api/adl/rankings
|
|
2898
|
+
* - AdlSide — "long" | "short"
|
|
2899
|
+
*/
|
|
2900
|
+
|
|
2901
|
+
/** Position side derived from positionSize sign. */
|
|
2902
|
+
type AdlSide = "long" | "short";
|
|
2903
|
+
/**
|
|
2904
|
+
* A ranked open position for ADL purposes.
|
|
2905
|
+
* Positions are ranked descending by `pnlPct` — rank 0 is the most profitable
|
|
2906
|
+
* and will be deleveraged first.
|
|
2907
|
+
*/
|
|
2908
|
+
interface AdlRankedPosition {
|
|
2909
|
+
/** Account index in the slab (used as `targetIdx` in ExecuteAdl). */
|
|
2910
|
+
idx: number;
|
|
2911
|
+
/** Owner public key. */
|
|
2912
|
+
owner: PublicKey;
|
|
2913
|
+
/** Raw position size (i128 — negative = short, positive = long). */
|
|
2914
|
+
positionSize: bigint;
|
|
2915
|
+
/** Realised + mark-to-market PnL in lamports (i128 from slab). */
|
|
2916
|
+
pnl: bigint;
|
|
2917
|
+
/** Capital at entry in lamports (u128). */
|
|
2918
|
+
capital: bigint;
|
|
2919
|
+
/**
|
|
2920
|
+
* PnL as a fraction of capital, expressed as basis points (scaled × 10_000).
|
|
2921
|
+
* pnlPct = pnl * 10_000 / capital.
|
|
2922
|
+
* Higher = more profitable = deleveraged first.
|
|
2923
|
+
*/
|
|
2924
|
+
pnlPct: bigint;
|
|
2925
|
+
/** Long or short. */
|
|
2926
|
+
side: AdlSide;
|
|
2927
|
+
/**
|
|
2928
|
+
* ADL rank among positions on the same side (0 = highest PnL%, deleveraged first).
|
|
2929
|
+
* `-1` if position size is zero (inactive).
|
|
2930
|
+
*/
|
|
2931
|
+
adlRank: number;
|
|
2932
|
+
}
|
|
2933
|
+
/**
|
|
2934
|
+
* Result of `fetchAdlRankedPositions`.
|
|
2935
|
+
*/
|
|
2936
|
+
interface AdlRankingResult {
|
|
2937
|
+
/** All open (non-zero) user positions, sorted descending by PnLPct, ranked. */
|
|
2938
|
+
ranked: AdlRankedPosition[];
|
|
2939
|
+
/**
|
|
2940
|
+
* Longs ranked separately (adlRank within this subset).
|
|
2941
|
+
* Rank 0 = most profitable long = first to be deleveraged on a net-long market.
|
|
2942
|
+
*/
|
|
2943
|
+
longs: AdlRankedPosition[];
|
|
2944
|
+
/**
|
|
2945
|
+
* Shorts ranked separately (adlRank within this subset).
|
|
2946
|
+
* Rank 0 = most profitable short (most negative pnlPct magnitude — i.e., highest
|
|
2947
|
+
* unrealised gain for the short-side holder).
|
|
2948
|
+
*/
|
|
2949
|
+
shorts: AdlRankedPosition[];
|
|
2950
|
+
/** Whether ADL is currently triggered (pnlPosTot > maxPnlCap). */
|
|
2951
|
+
isTriggered: boolean;
|
|
2952
|
+
/** pnl_pos_tot from engine state. */
|
|
2953
|
+
pnlPosTot: bigint;
|
|
2954
|
+
/** max_pnl_cap from market config. */
|
|
2955
|
+
maxPnlCap: bigint;
|
|
2956
|
+
}
|
|
2957
|
+
/**
|
|
2958
|
+
* Check whether ADL is currently triggered on a slab.
|
|
2959
|
+
*
|
|
2960
|
+
* ADL triggers when pnl_pos_tot > max_pnl_cap (max_pnl_cap must be > 0).
|
|
2961
|
+
*
|
|
2962
|
+
* @param slabData - Raw slab account bytes.
|
|
2963
|
+
* @returns true if ADL is triggered.
|
|
2964
|
+
*
|
|
2965
|
+
* @example
|
|
2966
|
+
* ```ts
|
|
2967
|
+
* const data = await fetchSlab(connection, slabKey);
|
|
2968
|
+
* if (isAdlTriggered(data)) {
|
|
2969
|
+
* const ranking = await fetchAdlRankedPositions(connection, slabKey);
|
|
2970
|
+
* }
|
|
2971
|
+
* ```
|
|
2972
|
+
*/
|
|
2973
|
+
declare function isAdlTriggered(slabData: Uint8Array): boolean;
|
|
2974
|
+
/**
|
|
2975
|
+
* Fetch a slab and rank all open user positions by PnL% for ADL targeting.
|
|
2976
|
+
*
|
|
2977
|
+
* Positions are ranked separately per side:
|
|
2978
|
+
* - Longs: rank 0 = highest positive PnL% (most profitable long)
|
|
2979
|
+
* - Shorts: rank 0 = highest negative PnL% by abs value (most profitable short)
|
|
2980
|
+
*
|
|
2981
|
+
* Rank ordering matches the on-chain ADL engine in percolator-prog (PERC-8273):
|
|
2982
|
+
* the position at rank 0 of the dominant side is deleveraged first.
|
|
2983
|
+
*
|
|
2984
|
+
* @param connection - Solana connection.
|
|
2985
|
+
* @param slab - Slab (market) public key.
|
|
2986
|
+
* @returns AdlRankingResult with ranked longs, ranked shorts, and trigger status.
|
|
2987
|
+
*
|
|
2988
|
+
* @example
|
|
2989
|
+
* ```ts
|
|
2990
|
+
* const { ranked, longs, isTriggered } = await fetchAdlRankedPositions(connection, slabKey);
|
|
2991
|
+
* if (isTriggered && longs.length > 0) {
|
|
2992
|
+
* const target = longs[0]; // highest PnL long
|
|
2993
|
+
* const ix = buildAdlInstruction(caller, slabKey, oracleKey, programId, target.idx);
|
|
2994
|
+
* }
|
|
2995
|
+
* ```
|
|
2996
|
+
*/
|
|
2997
|
+
declare function fetchAdlRankedPositions(connection: Connection, slab: PublicKey): Promise<AdlRankingResult>;
|
|
2998
|
+
/**
|
|
2999
|
+
* Pure (no-RPC) variant — rank positions from already-fetched slab bytes.
|
|
3000
|
+
* Useful when you already have the slab data (e.g., from a subscription).
|
|
3001
|
+
*/
|
|
3002
|
+
declare function rankAdlPositions(slabData: Uint8Array): AdlRankingResult;
|
|
3003
|
+
/**
|
|
3004
|
+
* Build a single `ExecuteAdl` TransactionInstruction (tag 50, PERC-305).
|
|
3005
|
+
*
|
|
3006
|
+
* Does NOT fetch the slab or check trigger status — use `fetchAdlRankedPositions`
|
|
3007
|
+
* first to determine the correct `targetIdx`.
|
|
3008
|
+
*
|
|
3009
|
+
* **Caller requirement:** The on-chain handler requires the caller to be the market
|
|
3010
|
+
* admin/keeper authority (`header.admin`). Passing any other signer will result in
|
|
3011
|
+
* `EngineUnauthorized`.
|
|
3012
|
+
*
|
|
3013
|
+
* @param caller - Signer — must be the market keeper/admin authority.
|
|
3014
|
+
* @param slab - Slab (market) public key.
|
|
3015
|
+
* @param oracle - Primary oracle public key for this market.
|
|
3016
|
+
* @param programId - Percolator program ID.
|
|
3017
|
+
* @param targetIdx - Account index to deleverage (from `AdlRankedPosition.idx`).
|
|
3018
|
+
* @param backupOracles - Optional additional oracle accounts (non-Hyperp markets).
|
|
3019
|
+
*
|
|
3020
|
+
* @example
|
|
3021
|
+
* ```ts
|
|
3022
|
+
* import { fetchAdlRankedPositions, buildAdlInstruction } from "@percolator/sdk";
|
|
3023
|
+
*
|
|
3024
|
+
* const { longs, isTriggered } = await fetchAdlRankedPositions(connection, slabKey);
|
|
3025
|
+
* if (isTriggered && longs.length > 0) {
|
|
3026
|
+
* const ix = buildAdlInstruction(
|
|
3027
|
+
* caller.publicKey, slabKey, oracleKey, PROGRAM_ID, longs[0].idx
|
|
3028
|
+
* );
|
|
3029
|
+
* await sendAndConfirmTransaction(connection, new Transaction().add(ix), [caller]);
|
|
3030
|
+
* }
|
|
3031
|
+
* ```
|
|
3032
|
+
*/
|
|
3033
|
+
declare function buildAdlInstruction(caller: PublicKey, slab: PublicKey, oracle: PublicKey, programId: PublicKey, targetIdx: number, backupOracles?: PublicKey[]): TransactionInstruction;
|
|
3034
|
+
/**
|
|
3035
|
+
* Convenience builder: fetch slab, rank positions, pick the highest-ranked
|
|
3036
|
+
* target on the given side, and return a ready-to-send `TransactionInstruction`.
|
|
3037
|
+
*
|
|
3038
|
+
* Returns `null` when ADL is not triggered or no eligible positions exist.
|
|
3039
|
+
*
|
|
3040
|
+
* @param connection - Solana connection.
|
|
3041
|
+
* @param caller - Signer — must be the market keeper/admin authority.
|
|
3042
|
+
* @param slab - Slab (market) public key.
|
|
3043
|
+
* @param oracle - Primary oracle public key.
|
|
3044
|
+
* @param programId - Percolator program ID.
|
|
3045
|
+
* @param preferSide - Optional: target "long" or "short" side only.
|
|
3046
|
+
* If omitted, picks the overall top-ranked position.
|
|
3047
|
+
* @param backupOracles - Optional extra oracle accounts.
|
|
3048
|
+
*
|
|
3049
|
+
* @example
|
|
3050
|
+
* ```ts
|
|
3051
|
+
* const ix = await buildAdlTransaction(
|
|
3052
|
+
* connection, caller.publicKey, slabKey, oracleKey, PROGRAM_ID
|
|
3053
|
+
* );
|
|
3054
|
+
* if (ix) {
|
|
3055
|
+
* await sendAndConfirmTransaction(connection, new Transaction().add(ix), [caller]);
|
|
3056
|
+
* }
|
|
3057
|
+
* ```
|
|
3058
|
+
*/
|
|
3059
|
+
declare function buildAdlTransaction(connection: Connection, caller: PublicKey, slab: PublicKey, oracle: PublicKey, programId: PublicKey, preferSide?: AdlSide, backupOracles?: PublicKey[]): Promise<TransactionInstruction | null>;
|
|
3060
|
+
/**
|
|
3061
|
+
* Decoded on-chain AdlEvent emitted by the `ExecuteAdl` instruction handler.
|
|
3062
|
+
*
|
|
3063
|
+
* The on-chain handler emits via `sol_log_64(0xAD1E_0001, target_idx, price, closed_lo, closed_hi)`.
|
|
3064
|
+
* `sol_log_64` prints 5 decimal u64 values separated by spaces on a single "Program log:" line.
|
|
3065
|
+
*
|
|
3066
|
+
* Fields:
|
|
3067
|
+
* - `tag` — always `0xAD1E_0001` (2970353665n)
|
|
3068
|
+
* - `targetIdx` — slab account index that was deleveraged
|
|
3069
|
+
* - `price` — oracle price used (in market price units, e.g. e6)
|
|
3070
|
+
* - `closedAbs` — absolute size of the position closed (i128, reassembled from lo+hi u64 parts)
|
|
3071
|
+
*
|
|
3072
|
+
* @example
|
|
3073
|
+
* ```ts
|
|
3074
|
+
* const logs = tx.meta?.logMessages ?? [];
|
|
3075
|
+
* const event = parseAdlEvent(logs);
|
|
3076
|
+
* if (event) {
|
|
3077
|
+
* console.log("ADL closed position", event.targetIdx, "size", event.closedAbs);
|
|
3078
|
+
* }
|
|
3079
|
+
* ```
|
|
3080
|
+
*/
|
|
3081
|
+
interface AdlEvent {
|
|
3082
|
+
/** Tag discriminator — always 0xAD1E_0001n (2970353665). */
|
|
3083
|
+
tag: bigint;
|
|
3084
|
+
/** Slab account index that was deleveraged. */
|
|
3085
|
+
targetIdx: number;
|
|
3086
|
+
/** Oracle price used for the deleverage (market-native units, e.g. lamports/e6). */
|
|
3087
|
+
price: bigint;
|
|
3088
|
+
/**
|
|
3089
|
+
* Absolute position size closed (reassembled from lo+hi u64).
|
|
3090
|
+
* This is the i128 absolute value — always non-negative.
|
|
3091
|
+
*/
|
|
3092
|
+
closedAbs: bigint;
|
|
3093
|
+
}
|
|
3094
|
+
/**
|
|
3095
|
+
* Parse the AdlEvent from a transaction's log messages.
|
|
3096
|
+
*
|
|
3097
|
+
* Searches for a "Program log: <a> <b> <c> <d> <e>" line where the first
|
|
3098
|
+
* decimal value equals `0xAD1E_0001` (2970353665). Returns `null` if not found.
|
|
3099
|
+
*
|
|
3100
|
+
* @param logs - Array of log message strings (from `tx.meta.logMessages`).
|
|
3101
|
+
* @returns Decoded `AdlEvent` or `null` if the log is not present.
|
|
3102
|
+
*
|
|
3103
|
+
* @example
|
|
3104
|
+
* ```ts
|
|
3105
|
+
* const event = parseAdlEvent(tx.meta?.logMessages ?? []);
|
|
3106
|
+
* if (event) {
|
|
3107
|
+
* console.log(`ADL: idx=${event.targetIdx} price=${event.price} closed=${event.closedAbs}`);
|
|
3108
|
+
* }
|
|
3109
|
+
* ```
|
|
3110
|
+
*/
|
|
3111
|
+
declare function parseAdlEvent(logs: string[]): AdlEvent | null;
|
|
3112
|
+
/**
|
|
3113
|
+
* A single ranked position as returned by the /api/adl/rankings endpoint.
|
|
3114
|
+
*/
|
|
3115
|
+
interface AdlApiRanking {
|
|
3116
|
+
/** 1-based rank (1 = highest PnL%, first to be deleveraged). */
|
|
3117
|
+
rank: number;
|
|
3118
|
+
/** Slab account index. Pass as `targetIdx` to `buildAdlInstruction`. */
|
|
3119
|
+
idx: number;
|
|
3120
|
+
/** Absolute PnL (lamports) as a decimal string. */
|
|
3121
|
+
pnlAbs: string;
|
|
3122
|
+
/** Capital at entry (lamports) as a decimal string. */
|
|
3123
|
+
capital: string;
|
|
3124
|
+
/** PnL as millionths of capital (pnl * 1_000_000 / capital). */
|
|
3125
|
+
pnlPctMillionths: string;
|
|
3126
|
+
}
|
|
3127
|
+
/**
|
|
3128
|
+
* Full result from the /api/adl/rankings endpoint.
|
|
3129
|
+
*/
|
|
3130
|
+
interface AdlApiResult {
|
|
3131
|
+
slabAddress: string;
|
|
3132
|
+
/** pnl_pos_tot from slab engine state (decimal string). */
|
|
3133
|
+
pnlPosTot: string;
|
|
3134
|
+
/** max_pnl_cap from market config (decimal string, "0" if unconfigured). */
|
|
3135
|
+
maxPnlCap: string;
|
|
3136
|
+
/** Insurance fund balance (decimal string). */
|
|
3137
|
+
insuranceFundBalance: string;
|
|
3138
|
+
/** Insurance fund lifetime fee revenue (decimal string). */
|
|
3139
|
+
insuranceFundFeeRevenue: string;
|
|
3140
|
+
/** Insurance utilization in basis points (0–10000). */
|
|
3141
|
+
insuranceUtilizationBps: number;
|
|
3142
|
+
/** true if pnlPosTot > maxPnlCap. */
|
|
3143
|
+
capExceeded: boolean;
|
|
3144
|
+
/** true if insurance fund is fully depleted (balance == 0). */
|
|
3145
|
+
insuranceDepleted: boolean;
|
|
3146
|
+
/** true if utilization BPS exceeds the configured ADL threshold. */
|
|
3147
|
+
utilizationTriggered: boolean;
|
|
3148
|
+
/** true if ADL is needed (capExceeded or utilizationTriggered). */
|
|
3149
|
+
adlNeeded: boolean;
|
|
3150
|
+
/** Excess PnL above cap (decimal string). */
|
|
3151
|
+
excess: string;
|
|
3152
|
+
/** Ranked positions (empty if adlNeeded=false). */
|
|
3153
|
+
rankings: AdlApiRanking[];
|
|
3154
|
+
}
|
|
3155
|
+
/**
|
|
3156
|
+
* Fetch ADL rankings from the Percolator API.
|
|
3157
|
+
*
|
|
3158
|
+
* Calls `GET <apiBase>/api/adl/rankings?slab=<address>` and returns the
|
|
3159
|
+
* parsed result. Use this from the frontend or keeper to determine ADL
|
|
3160
|
+
* trigger status and pick the target index.
|
|
3161
|
+
*
|
|
3162
|
+
* @param apiBase - Base URL of the Percolator API (e.g. `https://api.percolator.io`).
|
|
3163
|
+
* @param slab - Slab (market) public key or base58 address string.
|
|
3164
|
+
* @param fetchFn - Optional custom fetch implementation (defaults to global `fetch`).
|
|
3165
|
+
* @returns Parsed `AdlApiResult`.
|
|
3166
|
+
* @throws On HTTP error or JSON parse failure.
|
|
3167
|
+
*
|
|
3168
|
+
* @example
|
|
3169
|
+
* ```ts
|
|
3170
|
+
* const result = await fetchAdlRankings("https://api.percolator.io", slabKey);
|
|
3171
|
+
* if (result.adlNeeded && result.rankings.length > 0) {
|
|
3172
|
+
* const target = result.rankings[0]; // rank 1 = highest PnL%
|
|
3173
|
+
* const ix = buildAdlInstruction(caller, slabKey, oracleKey, PROGRAM_ID, target.idx);
|
|
3174
|
+
* }
|
|
3175
|
+
* ```
|
|
3176
|
+
*/
|
|
3177
|
+
declare function fetchAdlRankings(apiBase: string, slab: PublicKey | string, fetchFn?: typeof fetch): Promise<AdlApiResult>;
|
|
3178
|
+
|
|
3179
|
+
interface BuildIxParams {
|
|
3180
|
+
programId: PublicKey;
|
|
3181
|
+
keys: AccountMeta[];
|
|
3182
|
+
data: Uint8Array | Buffer;
|
|
3183
|
+
}
|
|
3184
|
+
/**
|
|
3185
|
+
* Build a transaction instruction.
|
|
3186
|
+
*/
|
|
3187
|
+
declare function buildIx(params: BuildIxParams): TransactionInstruction;
|
|
3188
|
+
interface TxResult {
|
|
3189
|
+
signature: string;
|
|
3190
|
+
slot: number;
|
|
3191
|
+
err: string | null;
|
|
3192
|
+
hint?: string;
|
|
3193
|
+
logs: string[];
|
|
3194
|
+
unitsConsumed?: number;
|
|
3195
|
+
}
|
|
3196
|
+
interface SimulateOrSendParams {
|
|
3197
|
+
connection: Connection;
|
|
3198
|
+
ix: TransactionInstruction;
|
|
3199
|
+
signers: Keypair[];
|
|
3200
|
+
simulate: boolean;
|
|
3201
|
+
commitment?: Commitment;
|
|
3202
|
+
computeUnitLimit?: number;
|
|
3203
|
+
}
|
|
3204
|
+
declare function simulateOrSend(params: SimulateOrSendParams): Promise<TxResult>;
|
|
3205
|
+
/**
|
|
3206
|
+
* Format transaction result for output.
|
|
3207
|
+
*/
|
|
3208
|
+
declare function formatResult(result: TxResult, jsonMode: boolean): string;
|
|
3209
|
+
|
|
3210
|
+
/**
|
|
3211
|
+
* Coin-margined perpetual trade math utilities.
|
|
3212
|
+
*
|
|
3213
|
+
* On-chain PnL formula:
|
|
3214
|
+
* mark_pnl = (oracle - entry) * abs_pos / oracle (longs)
|
|
3215
|
+
* mark_pnl = (entry - oracle) * abs_pos / oracle (shorts)
|
|
3216
|
+
*
|
|
3217
|
+
* All prices are in e6 format (1 USD = 1_000_000).
|
|
3218
|
+
* All token amounts are in native units (e.g. lamports).
|
|
3219
|
+
*/
|
|
3220
|
+
/**
|
|
3221
|
+
* Compute mark-to-market PnL for an open position.
|
|
3222
|
+
*/
|
|
3223
|
+
declare function computeMarkPnl(positionSize: bigint, entryPrice: bigint, oraclePrice: bigint): bigint;
|
|
3224
|
+
/**
|
|
3225
|
+
* Compute liquidation price given entry, capital, position and maintenance margin.
|
|
3226
|
+
* Uses pure BigInt arithmetic for precision (no Number() truncation).
|
|
3227
|
+
*/
|
|
3228
|
+
declare function computeLiqPrice(entryPrice: bigint, capital: bigint, positionSize: bigint, maintenanceMarginBps: bigint): bigint;
|
|
3229
|
+
/**
|
|
3230
|
+
* Compute estimated liquidation price BEFORE opening a trade.
|
|
3231
|
+
* Accounts for trading fees reducing effective capital.
|
|
3232
|
+
*/
|
|
3233
|
+
declare function computePreTradeLiqPrice(oracleE6: bigint, margin: bigint, posSize: bigint, maintBps: bigint, feeBps: bigint, direction: "long" | "short"): bigint;
|
|
3234
|
+
/**
|
|
3235
|
+
* Compute trading fee from notional value and fee rate in bps.
|
|
3236
|
+
*/
|
|
3237
|
+
declare function computeTradingFee(notional: bigint, tradingFeeBps: bigint): bigint;
|
|
3238
|
+
/**
|
|
3239
|
+
* Dynamic fee tier configuration.
|
|
3240
|
+
*/
|
|
3241
|
+
interface FeeTierConfig {
|
|
3242
|
+
/** Base trading fee (Tier 1) in bps */
|
|
3243
|
+
baseBps: bigint;
|
|
3244
|
+
/** Tier 2 fee in bps (0 = disabled) */
|
|
3245
|
+
tier2Bps: bigint;
|
|
3246
|
+
/** Tier 3 fee in bps (0 = disabled) */
|
|
3247
|
+
tier3Bps: bigint;
|
|
3248
|
+
/** Notional threshold to enter Tier 2 (0 = tiered fees disabled) */
|
|
3249
|
+
tier2Threshold: bigint;
|
|
3250
|
+
/** Notional threshold to enter Tier 3 */
|
|
3251
|
+
tier3Threshold: bigint;
|
|
3252
|
+
}
|
|
3253
|
+
/**
|
|
3254
|
+
* Compute the effective fee rate in bps using the tiered fee schedule.
|
|
3255
|
+
*
|
|
3256
|
+
* Mirrors on-chain `compute_dynamic_fee_bps` logic:
|
|
3257
|
+
* - notional < tier2Threshold → baseBps (Tier 1)
|
|
3258
|
+
* - notional < tier3Threshold → tier2Bps (Tier 2)
|
|
3259
|
+
* - notional >= tier3Threshold → tier3Bps (Tier 3)
|
|
3260
|
+
*
|
|
3261
|
+
* If tier2Threshold == 0, tiered fees are disabled (flat baseBps).
|
|
3262
|
+
*/
|
|
3263
|
+
declare function computeDynamicFeeBps(notional: bigint, config: FeeTierConfig): bigint;
|
|
3264
|
+
/**
|
|
3265
|
+
* Compute the dynamic trading fee for a given notional and tier config.
|
|
3266
|
+
*
|
|
3267
|
+
* Uses ceiling division to match on-chain behavior (prevents fee evasion
|
|
3268
|
+
* via micro-trades).
|
|
3269
|
+
*/
|
|
3270
|
+
declare function computeDynamicTradingFee(notional: bigint, config: FeeTierConfig): bigint;
|
|
3271
|
+
/**
|
|
3272
|
+
* Fee split configuration.
|
|
3273
|
+
*/
|
|
3274
|
+
interface FeeSplitConfig {
|
|
3275
|
+
/** LP vault share in bps (0–10_000) */
|
|
3276
|
+
lpBps: bigint;
|
|
3277
|
+
/** Protocol treasury share in bps */
|
|
3278
|
+
protocolBps: bigint;
|
|
3279
|
+
/** Market creator share in bps */
|
|
3280
|
+
creatorBps: bigint;
|
|
3281
|
+
}
|
|
3282
|
+
/**
|
|
3283
|
+
* Compute fee split for a total fee amount.
|
|
3284
|
+
*
|
|
3285
|
+
* Returns [lpShare, protocolShare, creatorShare].
|
|
3286
|
+
* If all split params are 0, 100% goes to LP (legacy behavior).
|
|
3287
|
+
* Creator gets the rounding remainder to ensure total is preserved.
|
|
3288
|
+
*/
|
|
3289
|
+
declare function computeFeeSplit(totalFee: bigint, config: FeeSplitConfig): [bigint, bigint, bigint];
|
|
3290
|
+
/**
|
|
3291
|
+
* Compute PnL as a percentage of capital.
|
|
3292
|
+
*
|
|
3293
|
+
* Uses BigInt scaling to avoid precision loss from Number(bigint) conversion.
|
|
3294
|
+
* Number(bigint) silently truncates values above 2^53, which can produce
|
|
3295
|
+
* incorrect percentages for large positions (e.g., tokens with 9 decimals
|
|
3296
|
+
* where capital > ~9M tokens in native units exceeds MAX_SAFE_INTEGER).
|
|
3297
|
+
*/
|
|
3298
|
+
declare function computePnlPercent(pnlTokens: bigint, capital: bigint): number;
|
|
3299
|
+
/**
|
|
3300
|
+
* Estimate entry price including fee impact (slippage approximation).
|
|
3301
|
+
*/
|
|
3302
|
+
declare function computeEstimatedEntryPrice(oracleE6: bigint, tradingFeeBps: bigint, direction: "long" | "short"): bigint;
|
|
3303
|
+
/**
|
|
3304
|
+
* Convert per-slot funding rate (bps) to annualized percentage.
|
|
3305
|
+
*/
|
|
3306
|
+
declare function computeFundingRateAnnualized(fundingRateBpsPerSlot: bigint): number;
|
|
3307
|
+
/**
|
|
3308
|
+
* Compute margin required for a given notional and initial margin bps.
|
|
3309
|
+
*/
|
|
3310
|
+
declare function computeRequiredMargin(notional: bigint, initialMarginBps: bigint): bigint;
|
|
3311
|
+
/**
|
|
3312
|
+
* Compute maximum leverage from initial margin bps.
|
|
3313
|
+
*
|
|
3314
|
+
* @throws Error if initialMarginBps is zero (infinite leverage is undefined)
|
|
3315
|
+
*/
|
|
3316
|
+
declare function computeMaxLeverage(initialMarginBps: bigint): number;
|
|
3317
|
+
|
|
3318
|
+
/**
|
|
3319
|
+
* Warmup leverage cap utilities.
|
|
3320
|
+
*
|
|
3321
|
+
* During the market warmup period, capital is released linearly over
|
|
3322
|
+
* `warmupPeriodSlots` slots, which constrains the effective leverage
|
|
3323
|
+
* and maximum position size available to traders.
|
|
3324
|
+
*/
|
|
3325
|
+
/**
|
|
3326
|
+
* Compute unlocked capital during the warmup period.
|
|
3327
|
+
*
|
|
3328
|
+
* Capital is released linearly over `warmupPeriodSlots` slots starting from
|
|
3329
|
+
* `warmupStartedAtSlot`. Before warmup starts (startSlot === 0) or if the
|
|
3330
|
+
* warmup period is 0, all capital is considered unlocked.
|
|
3331
|
+
*
|
|
3332
|
+
* @param totalCapital - Total deposited capital (native units).
|
|
3333
|
+
* @param currentSlot - The current on-chain slot.
|
|
3334
|
+
* @param warmupStartSlot - Slot at which warmup started (0 = not started).
|
|
3335
|
+
* @param warmupPeriodSlots - Total slots in the warmup period.
|
|
3336
|
+
* @returns The amount of capital currently unlocked.
|
|
3337
|
+
*/
|
|
3338
|
+
declare function computeWarmupUnlockedCapital(totalCapital: bigint, currentSlot: bigint, warmupStartSlot: bigint, warmupPeriodSlots: bigint): bigint;
|
|
3339
|
+
/**
|
|
3340
|
+
* Compute the effective maximum leverage during the warmup period.
|
|
3341
|
+
*
|
|
3342
|
+
* During warmup, only unlocked capital can be used as margin. The effective
|
|
3343
|
+
* leverage relative to *total* capital is therefore capped at:
|
|
3344
|
+
*
|
|
3345
|
+
* effectiveMaxLeverage = maxLeverage × (unlockedCapital / totalCapital)
|
|
3346
|
+
*
|
|
3347
|
+
* This returns a floored integer value (leverage is always a whole number
|
|
3348
|
+
* in the UI), with a minimum of 1x if any capital is unlocked.
|
|
3349
|
+
*
|
|
3350
|
+
* @param initialMarginBps - Initial margin requirement in basis points.
|
|
3351
|
+
* @param totalCapital - Total deposited capital (native units).
|
|
3352
|
+
* @param currentSlot - The current on-chain slot.
|
|
3353
|
+
* @param warmupStartSlot - Slot at which warmup started (0 = not started).
|
|
3354
|
+
* @param warmupPeriodSlots - Total slots in the warmup period.
|
|
3355
|
+
* @returns The effective maximum leverage (integer, ≥ 1).
|
|
3356
|
+
*/
|
|
3357
|
+
declare function computeWarmupLeverageCap(initialMarginBps: bigint, totalCapital: bigint, currentSlot: bigint, warmupStartSlot: bigint, warmupPeriodSlots: bigint): number;
|
|
3358
|
+
/**
|
|
3359
|
+
* Compute the maximum position size allowed during warmup.
|
|
3360
|
+
*
|
|
3361
|
+
* This is the unlocked capital multiplied by the base max leverage.
|
|
3362
|
+
* Unlike `computeWarmupLeverageCap` (which gives effective leverage
|
|
3363
|
+
* relative to total capital), this gives the absolute notional cap.
|
|
3364
|
+
*
|
|
3365
|
+
* @param initialMarginBps - Initial margin requirement in basis points.
|
|
3366
|
+
* @param totalCapital - Total deposited capital (native units).
|
|
3367
|
+
* @param currentSlot - The current on-chain slot.
|
|
3368
|
+
* @param warmupStartSlot - Slot at which warmup started (0 = not started).
|
|
3369
|
+
* @param warmupPeriodSlots - Total slots in the warmup period.
|
|
3370
|
+
* @returns Maximum position size in native units.
|
|
3371
|
+
*/
|
|
3372
|
+
declare function computeWarmupMaxPositionSize(initialMarginBps: bigint, totalCapital: bigint, currentSlot: bigint, warmupStartSlot: bigint, warmupPeriodSlots: bigint): bigint;
|
|
3373
|
+
|
|
3374
|
+
/**
|
|
3375
|
+
* Input validation utilities for CLI commands.
|
|
3376
|
+
* Provides descriptive error messages for invalid input.
|
|
3377
|
+
*/
|
|
3378
|
+
|
|
3379
|
+
declare class ValidationError extends Error {
|
|
3380
|
+
readonly field: string;
|
|
3381
|
+
constructor(field: string, message: string);
|
|
3382
|
+
}
|
|
3383
|
+
/**
|
|
3384
|
+
* Validate a public key string.
|
|
3385
|
+
*/
|
|
3386
|
+
declare function validatePublicKey(value: string, field: string): PublicKey;
|
|
3387
|
+
/**
|
|
3388
|
+
* Validate a non-negative integer index (u16 range for accounts).
|
|
3389
|
+
*/
|
|
3390
|
+
declare function validateIndex(value: string, field: string): number;
|
|
3391
|
+
/**
|
|
3392
|
+
* Validate a non-negative amount (u64 range).
|
|
3393
|
+
*/
|
|
3394
|
+
declare function validateAmount(value: string, field: string): bigint;
|
|
3395
|
+
/**
|
|
3396
|
+
* Validate a u128 value.
|
|
3397
|
+
*/
|
|
3398
|
+
declare function validateU128(value: string, field: string): bigint;
|
|
3399
|
+
/**
|
|
3400
|
+
* Validate an i64 value.
|
|
3401
|
+
*/
|
|
3402
|
+
declare function validateI64(value: string, field: string): bigint;
|
|
3403
|
+
/**
|
|
3404
|
+
* Validate an i128 value (trade sizes).
|
|
3405
|
+
*/
|
|
3406
|
+
declare function validateI128(value: string, field: string): bigint;
|
|
3407
|
+
/**
|
|
3408
|
+
* Validate a basis points value (0-10000).
|
|
3409
|
+
*/
|
|
3410
|
+
declare function validateBps(value: string, field: string): number;
|
|
3411
|
+
/**
|
|
3412
|
+
* Validate a u64 value.
|
|
3413
|
+
*/
|
|
3414
|
+
declare function validateU64(value: string, field: string): bigint;
|
|
3415
|
+
/**
|
|
3416
|
+
* Validate a u16 value.
|
|
3417
|
+
*/
|
|
3418
|
+
declare function validateU16(value: string, field: string): number;
|
|
3419
|
+
|
|
3420
|
+
/**
|
|
3421
|
+
* Smart Price Router — automatic oracle selection for any token.
|
|
3422
|
+
*
|
|
3423
|
+
* Given a token mint, discovers all available price sources (DexScreener, Pyth, Jupiter),
|
|
3424
|
+
* ranks them by liquidity/reliability, and returns the best oracle config.
|
|
3425
|
+
*/
|
|
3426
|
+
type PriceSourceType = "pyth" | "dex" | "jupiter";
|
|
3427
|
+
interface PriceSource {
|
|
3428
|
+
type: PriceSourceType;
|
|
3429
|
+
/** Pool address (dex), Pyth feed ID (pyth), or mint (jupiter) */
|
|
3430
|
+
address: string;
|
|
3431
|
+
/** DEX id for dex sources */
|
|
3432
|
+
dexId?: string;
|
|
3433
|
+
/** Pair label e.g. "SOL / USDC" */
|
|
3434
|
+
pairLabel?: string;
|
|
3435
|
+
/** USD liquidity depth — higher is better */
|
|
3436
|
+
liquidity: number;
|
|
3437
|
+
/** Latest spot price in USD */
|
|
3438
|
+
price: number;
|
|
3439
|
+
/** Confidence score 0-100 (composite of liquidity, staleness, reliability) */
|
|
3440
|
+
confidence: number;
|
|
3441
|
+
}
|
|
3442
|
+
interface PriceRouterResult {
|
|
3443
|
+
mint: string;
|
|
3444
|
+
bestSource: PriceSource | null;
|
|
3445
|
+
allSources: PriceSource[];
|
|
3446
|
+
/** ISO timestamp of resolution */
|
|
3447
|
+
resolvedAt: string;
|
|
3448
|
+
}
|
|
3449
|
+
/** Options for {@link resolvePrice}. */
|
|
3450
|
+
interface ResolvePriceOptions {
|
|
3451
|
+
timeoutMs?: number;
|
|
3452
|
+
}
|
|
3453
|
+
declare const PYTH_SOLANA_FEEDS: Record<string, {
|
|
3454
|
+
symbol: string;
|
|
3455
|
+
mint: string;
|
|
3456
|
+
}>;
|
|
3457
|
+
declare function resolvePrice(mint: string, signal?: AbortSignal, options?: ResolvePriceOptions): Promise<PriceRouterResult>;
|
|
3458
|
+
|
|
3459
|
+
export { ACCOUNTS_ADVANCE_ORACLE_PHASE, ACCOUNTS_AUDIT_CRANK, ACCOUNTS_BURN_POSITION_NFT, ACCOUNTS_CANCEL_QUEUED_WITHDRAWAL, ACCOUNTS_CLAIM_QUEUED_WITHDRAWAL, ACCOUNTS_CLEAR_PENDING_SETTLEMENT, ACCOUNTS_CLOSE_ACCOUNT, ACCOUNTS_CLOSE_SLAB, ACCOUNTS_CLOSE_STALE_SLABS, ACCOUNTS_CREATE_INSURANCE_MINT, ACCOUNTS_DEPOSIT_COLLATERAL, ACCOUNTS_DEPOSIT_INSURANCE_LP, ACCOUNTS_EXECUTE_ADL, ACCOUNTS_FUND_MARKET_INSURANCE, ACCOUNTS_INIT_LP, ACCOUNTS_INIT_MARKET, ACCOUNTS_INIT_MATCHER_CTX, ACCOUNTS_INIT_USER, ACCOUNTS_KEEPER_CRANK, ACCOUNTS_LIQUIDATE_AT_ORACLE, ACCOUNTS_LP_VAULT_WITHDRAW, ACCOUNTS_MINT_POSITION_NFT, ACCOUNTS_PAUSE_MARKET, ACCOUNTS_PUSH_ORACLE_PRICE, ACCOUNTS_QUEUE_WITHDRAWAL, ACCOUNTS_RECLAIM_SLAB_RENT, ACCOUNTS_RESOLVE_MARKET, ACCOUNTS_SET_DEX_POOL, ACCOUNTS_SET_INSURANCE_ISOLATION, ACCOUNTS_SET_MAINTENANCE_FEE, ACCOUNTS_SET_OI_IMBALANCE_HARD_BLOCK, ACCOUNTS_SET_ORACLE_AUTHORITY, ACCOUNTS_SET_ORACLE_PRICE_CAP, ACCOUNTS_SET_PENDING_SETTLEMENT, ACCOUNTS_SET_RISK_THRESHOLD, ACCOUNTS_SET_WALLET_CAP, ACCOUNTS_TOPUP_INSURANCE, ACCOUNTS_TOPUP_KEEPER_FUND, ACCOUNTS_TRADE_CPI, ACCOUNTS_TRADE_NOCPI, ACCOUNTS_TRANSFER_POSITION_OWNERSHIP, ACCOUNTS_UNPAUSE_MARKET, ACCOUNTS_UPDATE_ADMIN, ACCOUNTS_UPDATE_CONFIG, ACCOUNTS_WITHDRAW_COLLATERAL, ACCOUNTS_WITHDRAW_INSURANCE, ACCOUNTS_WITHDRAW_INSURANCE_LP, type Account, AccountKind, type AccountSpec, type AdlApiRanking, type AdlApiResult, type AdlEvent, type AdlRankedPosition, type AdlRankingResult, type AdlSide, type AdminForceCloseArgs, type AllocateMarketArgs, type ApiMarketEntry, type BuildIxParams, type BurnPositionNftArgs, CHAINLINK_ANSWER_OFFSET, CHAINLINK_DECIMALS_OFFSET, CHAINLINK_MIN_SIZE, CREATOR_LOCK_SEED, CTX_VAMM_OFFSET, type ClearPendingSettlementArgs, type CloseAccountArgs, DEFAULT_OI_RAMP_SLOTS, type DepositCollateralArgs, type DexPoolInfo, type DexType, type DiscoverMarketsOptions, type DiscoverMarketsViaApiOptions, type DiscoverMarketsViaStaticBundleOptions, type DiscoveredMarket, ENGINE_MARK_PRICE_OFF, ENGINE_OFF, type EngineState, type ExecuteAdlArgs, type FeeSplitConfig, type FeeTierConfig, type GetMarketsByAddressOptions, IX_TAG, type InitLPArgs, type InitMarketArgs, type InitMatcherCtxArgs, type InitSharedVaultArgs, type InitUserArgs, type InsuranceFund, type KeeperCrankArgs, type LiquidateAtOracleArgs, type LpVaultWithdrawArgs, MARK_PRICE_EMA_ALPHA_E6, MARK_PRICE_EMA_WINDOW_SLOTS, MAX_DECIMALS, MAX_ORACLE_PRICE, METEORA_DLMM_PROGRAM_ID, type MarketConfig, type MintPositionNftArgs, type Network, ORACLE_PHASE_GROWING, ORACLE_PHASE_MATURE, ORACLE_PHASE_NASCENT, type OraclePrice, PERCOLATOR_ERRORS, PHASE1_MIN_SLOTS, PHASE1_VOLUME_MIN_SLOTS, PHASE2_MATURITY_SLOTS, PHASE2_VOLUME_THRESHOLD, PROGRAM_IDS, PUMPSWAP_PROGRAM_ID, PYTH_PUSH_ORACLE_PROGRAM_ID, PYTH_RECEIVER_PROGRAM_ID, PYTH_SOLANA_FEEDS, type PriceRouterResult, type PriceSource, type PriceSourceType, type PushOraclePriceArgs, type QueueWithdrawalSVArgs, RAMP_START_BPS, RAYDIUM_CLMM_PROGRAM_ID, RENOUNCE_ADMIN_CONFIRMATION, type ResolvePriceOptions, type RiskParams, SLAB_TIERS, SLAB_TIERS_V0, SLAB_TIERS_V1, SLAB_TIERS_V12_1, SLAB_TIERS_V1D, SLAB_TIERS_V1D_LEGACY, SLAB_TIERS_V1M, SLAB_TIERS_V1M2, SLAB_TIERS_V2, SLAB_TIERS_V_ADL, SLAB_TIERS_V_ADL_DISCOVERY, SLAB_TIERS_V_SETDEXPOOL, STAKE_IX, STAKE_POOL_SIZE, STAKE_PROGRAM_ID, STAKE_PROGRAM_IDS, type SetInsuranceWithdrawPolicyArgs, type SetMaintenanceFeeArgs, type SetOracleAuthorityArgs, type SetOraclePriceCapArgs, type SetPendingSettlementArgs, type SetPythOracleArgs, type SetRiskThresholdArgs, type SetWalletCapArgs, type SimulateOrSendParams, type SlabHeader, type SlabLayout, type SlabTierKey, type StakeAccounts, type StakePoolState, type StaticMarketEntry, TOKEN_2022_PROGRAM_ID, type TopUpInsuranceArgs, type TopUpKeeperFundArgs, type TradeCpiArgs, type TradeCpiV2Args, type TradeNoCpiArgs, type TransferOwnershipCpiArgs, type TransferPositionOwnershipArgs, type TxResult, UNRESOLVE_CONFIRMATION, type UpdateAdminArgs, type UpdateConfigArgs, type UpdateRiskParamsArgs, VAMM_MAGIC, ValidationError, type VammMatcherParams, WELL_KNOWN, type WithdrawCollateralArgs, buildAccountMetas, buildAdlInstruction, buildAdlTransaction, buildIx, checkPhaseTransition, clearStaticMarkets, computeDexSpotPriceE6, computeDynamicFeeBps, computeDynamicTradingFee, computeEffectiveOiCapBps, computeEmaMarkPrice, computeEstimatedEntryPrice, computeFeeSplit, computeFundingRateAnnualized, computeLiqPrice, computeMarkPnl, computeMaxLeverage, computePnlPercent, computePreTradeLiqPrice, computeRequiredMargin, computeTradingFee, computeVammQuote, computeWarmupLeverageCap, computeWarmupMaxPositionSize, computeWarmupUnlockedCapital, concatBytes, decodeError, decodeStakePool, depositAccounts, deriveCreatorLockPda, deriveDepositPda, deriveInsuranceLpMint, deriveKeeperFund, deriveLpPda, derivePythPriceUpdateAccount, derivePythPushOraclePDA, deriveStakePool, deriveStakeVaultAuth, deriveVaultAuthority, detectDexType, detectLayout, detectSlabLayout, detectTokenProgram, discoverMarkets, discoverMarketsViaApi, discoverMarketsViaStaticBundle, encBool, encI128, encI64, encPubkey, encU128, encU16, encU32, encU64, encU8, encodeAdminForceClose, encodeAdvanceEpoch, encodeAdvanceOraclePhase, encodeAllocateMarket, encodeAttestCrossMargin, encodeAuditCrank, encodeBurnPositionNft, encodeCancelQueuedWithdrawal, encodeChallengeSettlement, encodeClaimEpochWithdrawal, encodeClaimQueuedWithdrawal, encodeClearPendingSettlement, encodeCloseAccount, encodeCloseKeeperFund, encodeCloseOrphanSlab, encodeCloseSlab, encodeCloseStaleSlabs, encodeCreateInsuranceMint, encodeCreateLpVault, encodeDepositCollateral, encodeDepositInsuranceLP, encodeDepositLpCollateral, encodeExecuteAdl, encodeForceCloseResolved, encodeFundMarketInsurance, encodeInitLP, encodeInitMarket, encodeInitMatcherCtx, encodeInitSharedVault, encodeInitUser, encodeKeeperCrank, encodeLiquidateAtOracle, encodeLpVaultCrankFees, encodeLpVaultDeposit, encodeLpVaultWithdraw, encodeMintPositionNft, encodePauseMarket, encodePushOraclePrice, encodeQueueWithdrawal, encodeQueueWithdrawalSV, encodeReclaimSlabRent, encodeRenounceAdmin, encodeRescueOrphanVault, encodeResolveDispute, encodeResolveMarket, encodeResolvePermissionless, encodeSetDexPool, encodeSetInsuranceIsolation, encodeSetInsuranceWithdrawPolicy, encodeSetMaintenanceFee, encodeSetOffsetPair, encodeSetOiImbalanceHardBlock, encodeSetOracleAuthority, encodeSetOraclePriceCap, encodeSetPendingSettlement, encodeSetPythOracle, encodeSetRiskThreshold, encodeSetWalletCap, encodeSlashCreationDeposit, encodeStakeAccrueFees, encodeStakeAdminResolveMarket, encodeStakeAdminSetHwmConfig, encodeStakeAdminSetInsurancePolicy, encodeStakeAdminSetMaintenanceFee, encodeStakeAdminSetOracleAuthority, encodeStakeAdminSetRiskThreshold, encodeStakeAdminSetTrancheConfig, encodeStakeAdminWithdrawInsurance, encodeStakeDeposit, encodeStakeDepositJunior, encodeStakeFlushToInsurance, encodeStakeInitPool, encodeStakeInitTradingPool, encodeStakeTransferAdmin, encodeStakeUpdateConfig, encodeStakeWithdraw, encodeTopUpInsurance, encodeTopUpKeeperFund, encodeTradeCpi, encodeTradeCpiV2, encodeTradeNoCpi, encodeTransferOwnershipCpi, encodeTransferPositionOwnership, encodeUnpauseMarket, encodeUpdateAdmin, encodeUpdateConfig, encodeUpdateHyperpMark, encodeUpdateMarkPrice, encodeUpdateRiskParams, encodeWithdrawCollateral, encodeWithdrawInsurance, encodeWithdrawInsuranceLP, encodeWithdrawInsuranceLimited, encodeWithdrawLpCollateral, fetchAdlRankedPositions, fetchAdlRankings, fetchSlab, fetchTokenAccount, flushToInsuranceAccounts, formatResult, getAta, getAtaSync, getCurrentNetwork, getErrorHint, getErrorName, getMarketsByAddress, getMatcherProgramId, getProgramId, getStakeProgramId, getStaticMarkets, initPoolAccounts, isAccountUsed, isAdlTriggered, isStandardToken, isToken2022, isValidChainlinkOracle, maxAccountIndex, parseAccount, parseAdlEvent, parseAllAccounts, parseChainlinkPrice, parseConfig, parseDexPool, parseEngine, parseErrorFromLogs, parseHeader, parseParams, parseUsedIndices, rankAdlPositions, readLastThrUpdateSlot, readNonce, registerStaticMarkets, resolvePrice, safeEnv, simulateOrSend, slabDataSize, slabDataSizeV1, validateAmount, validateBps, validateI128, validateI64, validateIndex, validatePublicKey, validateSlabTierMatch, validateU128, validateU16, validateU64, withdrawAccounts };
|