@percolatorct/sdk 0.5.1 → 1.0.0-beta.10

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  TypeScript SDK for building clients, bots, and UIs on top of the [Percolator](https://github.com/dcccrypto/percolator) perpetual futures protocol on Solana.
4
4
 
5
- > **⚠️ RELEASE CANDIDATE** — `1.0.0-rc.1`. Security audit (0x-SquidSol) complete. Pending final mainnet program verification before `1.0.0` stable. Use at your own risk.
5
+ > **⚠️ BETA** — `1.0.0-beta.1`. Security audit (0x-SquidSol) complete. All 709 tests passing. Pending Helius API key + mainnet market deployment before `1.0.0` stable.
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/@percolator/sdk?color=14F195)](https://www.npmjs.com/package/@percolator/sdk)
8
8
  [![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)
@@ -27,10 +27,13 @@ npm install @percolator/sdk
27
27
  import {
28
28
  getProgramId,
29
29
  deriveVaultAuthority,
30
- buildInitUserIxData,
31
- buildDepositCollateralIxData,
32
- buildTradeNoCpiIxData,
33
- parseSlab,
30
+ encodeInitUser,
31
+ encodeDepositCollateral,
32
+ encodeTradeNoCpi,
33
+ parseHeader,
34
+ parseConfig,
35
+ parseAllAccounts,
36
+ detectSlabLayout,
34
37
  computeMarkPnl,
35
38
  computeLiqPrice,
36
39
  simulateOrSend,
@@ -43,8 +46,12 @@ const programId = getProgramId("devnet");
43
46
  const [vaultAuth, bump] = deriveVaultAuthority(programId, slabPubkey);
44
47
 
45
48
  // Read and parse on-chain slab account
46
- const slabData = await connection.getAccountInfo(slabPubkey);
47
- const { header, config, accounts } = parseSlab(slabData.data);
49
+ const slabInfo = await connection.getAccountInfo(slabPubkey);
50
+ const slabData = new Uint8Array(slabInfo!.data);
51
+ const header = parseHeader(slabData);
52
+ const layout = detectSlabLayout(slabData.length);
53
+ const config = parseConfig(slabData, layout!);
54
+ const accounts = parseAllAccounts(slabData);
48
55
 
49
56
  // Compute PnL for a position
50
57
  const pnl = computeMarkPnl(positionSize, entryPrice, oraclePrice);
@@ -153,9 +160,18 @@ See [`examples/admin-instructions.ts`](examples/admin-instructions.ts) for full
153
160
  Parse the on-chain slab account into typed TypeScript objects:
154
161
 
155
162
  ```typescript
156
- import { parseSlab, parseSlabHeader, parseMarketConfig } from "@percolator/sdk";
163
+ import {
164
+ parseHeader,
165
+ parseConfig,
166
+ parseAllAccounts,
167
+ detectSlabLayout,
168
+ } from "@percolator/sdk";
157
169
 
158
- const { header, config, accounts } = parseSlab(accountData);
170
+ const slabData = new Uint8Array(accountInfo.data);
171
+ const header = parseHeader(slabData);
172
+ const layout = detectSlabLayout(slabData.length)!;
173
+ const config = parseConfig(slabData, layout);
174
+ const accounts = parseAllAccounts(slabData);
159
175
 
160
176
  // header.magic, header.version, header.admin, header.nonce
161
177
  // header.resolved, header.paused
@@ -165,7 +181,8 @@ const { header, config, accounts } = parseSlab(accountData);
165
181
  // config.fundingHorizonSlots, config.fundingKBps
166
182
  // config.threshFloor, config.threshRiskBps
167
183
 
168
- // accounts[i].owner, accounts[i].capital, accounts[i].pnl, accounts[i].positionSize
184
+ // accounts[i].account.owner, accounts[i].account.capital,
185
+ // accounts[i].account.pnl, accounts[i].account.positionSize
169
186
  ```
170
187
 
171
188
  ### PDA Derivation
@@ -312,7 +329,7 @@ const event = parseAdlEvent(tx?.meta?.logMessages ?? []);
312
329
  import { fetchAdlRankings } from "@percolator/sdk";
313
330
 
314
331
  const result = await fetchAdlRankings(
315
- "https://api.percolatorlaunch.com",
332
+ "https://percolatorlaunch.com/api",
316
333
  slabAddress,
317
334
  );
318
335
  // result.slabAddress — slab public key (base58)
@@ -338,8 +355,8 @@ const result = await fetchAdlRankings(
338
355
 
339
356
  | Code | Name | Description |
340
357
  |------|------|-------------|
341
- | 61 | `EngineSideBlocked` | ADL blocked — dominant side already at cap |
342
- | 62 | `EngineCorruptState` | Slab state corrupt — contact support |
358
+ | 61 | `EngineSideBlocked` | Trade blocked — this side is in DrainOnly or ResetPending mode |
359
+ | 62 | `EngineCorruptState` | Slab state corrupt — critical internal error, please report |
343
360
  | 63 | `InsuranceFundNotDepleted` | ADL not triggered yet (insurance fund healthy) |
344
361
  | 64 | `NoAdlCandidates` | No eligible positions to deleverage |
345
362
  | 65 | `BankruptPositionAlreadyClosed` | Target position already closed |
@@ -372,12 +389,22 @@ const result = await simulateOrSend({
372
389
  Validate parameters before submitting transactions:
373
390
 
374
391
  ```typescript
375
- import { validateRiskParams, validateTradeParams } from "@percolator/sdk";
392
+ import {
393
+ validatePublicKey,
394
+ validateAmount,
395
+ validateBps,
396
+ validateI128,
397
+ validateIndex,
398
+ } from "@percolator/sdk";
376
399
 
377
- const errors = validateRiskParams(params);
378
- if (errors.length > 0) {
379
- console.error("Invalid risk params:", errors);
380
- }
400
+ // Validates a public key string (throws ValidationError on invalid input)
401
+ const slabKey = validatePublicKey(slabAddress, "slab");
402
+
403
+ // Validates a u64 amount (throws ValidationError if negative or > u64 max)
404
+ const amount = validateAmount("1000000000", "depositAmount");
405
+
406
+ // Validates basis points (0-10000)
407
+ const feeBps = validateBps("50", "tradingFee");
381
408
  ```
382
409
 
383
410
  ---
@@ -407,14 +434,82 @@ const markets = await discoverMarkets(connection);
407
434
 
408
435
  | Program | Network | Address |
409
436
  |---------|---------|---------|
410
- | Percolator | Mainnet | `FxfD37s1AZTeWfFQps9Zpebi2dNQ9QSSDtfMKdbsfKrD` |
411
- | Matcher | Mainnet | see `getMatcherProgramId("mainnet")` |
437
+ | Percolator | Mainnet | `GM8zjJ8LTBMv9xEsverh6H6wLyevgMHEJXcEzyY3rY24` |
438
+ | Matcher | Mainnet | `DHP6DtwXP1yJsz8YzfoeigRFPB979gzmumkmCxDLSkUX` |
412
439
  | Percolator | Devnet | `FxfD37s1AZTeWfFQps9Zpebi2dNQ9QSSDtfMKdbsfKrD` |
440
+ | Matcher | Devnet | `GTRgyTDfrMvBubALAqtHuQwT8tbGyXid7svXZKtWfC9k` |
413
441
 
414
442
  > Use `PROGRAM_ID` / `MATCHER_PROGRAM_ID` env vars to override for local test validators.
415
443
 
416
444
  ---
417
445
 
446
+ ## RPC Connection Pool, Retry, and Health Probes
447
+
448
+ The SDK provides a production-grade RPC connection pool with automatic retry,
449
+ failover, and health probing. Use `RpcPool` for mainnet reliability.
450
+
451
+ ### RpcPool — Multi-endpoint with failover/round-robin
452
+
453
+ ```typescript
454
+ import { RpcPool } from "@percolator/sdk";
455
+
456
+ const pool = new RpcPool({
457
+ endpoints: [
458
+ { url: "https://mainnet.helius-rpc.com/?api-key=KEY", weight: 10, label: "helius" },
459
+ { url: "https://api.mainnet-beta.solana.com", weight: 1, label: "public" },
460
+ ],
461
+ strategy: "failover", // or "round-robin"
462
+ retry: {
463
+ maxRetries: 3, // default: 3
464
+ baseDelayMs: 500, // default: 500 (exponential backoff)
465
+ maxDelayMs: 10_000, // default: 10s cap
466
+ jitterFactor: 0.25, // default: 0.25 (avoid thundering herd)
467
+ },
468
+ requestTimeoutMs: 30_000, // default: 30s per request
469
+ commitment: "confirmed", // default: confirmed
470
+ });
471
+
472
+ // Execute any async call through the pool — auto-retry + failover
473
+ const slot = await pool.call(conn => conn.getSlot());
474
+ const balance = await pool.call(conn => conn.getBalance(pubkey));
475
+
476
+ // Use with discoverMarkets
477
+ const markets = await pool.call(conn =>
478
+ discoverMarkets(conn, programId, { apiBaseUrl: "https://percolatorlaunch.com/api" })
479
+ );
480
+
481
+ // Pool status & diagnostics
482
+ console.log(pool.status()); // [{ label, url, healthy, failures, lastLatencyMs }]
483
+ console.log(`${pool.healthyCount}/${pool.size} endpoints healthy`);
484
+ ```
485
+
486
+ ### Standalone retry wrapper
487
+
488
+ ```typescript
489
+ import { withRetry } from "@percolator/sdk";
490
+ import { Connection } from "@solana/web3.js";
491
+
492
+ const conn = new Connection("https://api.mainnet-beta.solana.com");
493
+ const slot = await withRetry(
494
+ () => conn.getSlot(),
495
+ { maxRetries: 3, baseDelayMs: 1000 },
496
+ );
497
+ ```
498
+
499
+ ### RPC health probes
500
+
501
+ ```typescript
502
+ import { checkRpcHealth } from "@percolator/sdk";
503
+
504
+ const health = await checkRpcHealth("https://api.mainnet-beta.solana.com", 5000);
505
+ console.log(`${health.endpoint}: ${health.healthy ? "UP" : "DOWN"} — ${health.latencyMs}ms, slot ${health.slot}`);
506
+
507
+ // Or check all pool endpoints at once
508
+ const results = await pool.healthCheck();
509
+ ```
510
+
511
+ ---
512
+
418
513
  ## RPC Concurrency
419
514
 
420
515
  `discoverMarkets()` fires one `getProgramAccounts` request per known slab tier size.
@@ -438,8 +533,113 @@ const marketsCustom = await discoverMarkets(connection, { maxParallelTiers: 3 })
438
533
  ```
439
534
 
440
535
  > **Note:** Public mainnet-beta RPC (`api.mainnet-beta.solana.com`) rejects
441
- > `getProgramAccounts` calls entirely. A Helius or QuickNode endpoint is required for
442
- > `discoverMarkets()` in production.
536
+ > `getProgramAccounts` calls entirely. Use the **API fallback** (below) or a
537
+ > Helius/QuickNode endpoint.
538
+
539
+ ## Market Discovery — 3-Tier Fallback Chain
540
+
541
+ Public mainnet RPCs reject `getProgramAccounts`, which blocks `discoverMarkets()`.
542
+ The SDK provides a resilient 3-tier fallback chain that works on any RPC endpoint:
543
+
544
+ | Tier | Method | Requires |
545
+ |------|--------|----------|
546
+ | 1 | `getProgramAccounts` (RPC) | Helius/premium RPC key |
547
+ | 2 | REST API (`GET /markets`) | Percolator API online |
548
+ | 3 | Static bundle (bundled addresses) | Nothing — works offline |
549
+
550
+ All tiers verify data on-chain via `getMultipleAccounts` (works on all RPCs).
551
+
552
+ ### Recommended: Full 3-tier fallback
553
+
554
+ Pass both `apiBaseUrl` and `network` to enable all three tiers:
555
+
556
+ ```typescript
557
+ import { discoverMarkets, getProgramId } from "@percolator/sdk";
558
+ import { Connection } from "@solana/web3.js";
559
+
560
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
561
+ const markets = await discoverMarkets(connection, getProgramId("mainnet"), {
562
+ apiBaseUrl: "https://percolatorlaunch.com/api",
563
+ network: "mainnet", // enables tier-3 static fallback
564
+ });
565
+ ```
566
+
567
+ ### API-only discovery via `discoverMarketsViaApi()`
568
+
569
+ Skip `getProgramAccounts` entirely — query the REST API for slab addresses,
570
+ then fetch full on-chain data:
571
+
572
+ ```typescript
573
+ import { discoverMarketsViaApi, getProgramId } from "@percolator/sdk";
574
+ import { Connection } from "@solana/web3.js";
575
+
576
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
577
+ const programId = getProgramId("mainnet");
578
+ const markets = await discoverMarketsViaApi(
579
+ connection,
580
+ programId,
581
+ "https://percolatorlaunch.com/api",
582
+ );
583
+ ```
584
+
585
+ ### Static-only discovery via `discoverMarketsViaStaticBundle()`
586
+
587
+ Use the bundled address list directly (no network calls except `getMultipleAccounts`):
588
+
589
+ ```typescript
590
+ import {
591
+ discoverMarketsViaStaticBundle,
592
+ getStaticMarkets,
593
+ getProgramId,
594
+ } from "@percolator/sdk";
595
+ import { Connection } from "@solana/web3.js";
596
+
597
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
598
+ const entries = getStaticMarkets("mainnet");
599
+ const markets = await discoverMarketsViaStaticBundle(
600
+ connection,
601
+ getProgramId("mainnet"),
602
+ entries,
603
+ );
604
+ ```
605
+
606
+ ### Extending the static registry at runtime
607
+
608
+ The static bundle can be augmented before calling `discoverMarkets()`:
609
+
610
+ ```typescript
611
+ import { registerStaticMarkets, discoverMarkets, getProgramId } from "@percolator/sdk";
612
+ import { Connection } from "@solana/web3.js";
613
+
614
+ // Register known slab addresses before discovery
615
+ registerStaticMarkets("mainnet", [
616
+ { slabAddress: "ABC123...", symbol: "SOL-PERP" },
617
+ { slabAddress: "DEF456...", symbol: "ETH-PERP" },
618
+ ]);
619
+
620
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
621
+ const markets = await discoverMarkets(connection, getProgramId("mainnet"), {
622
+ apiBaseUrl: "https://percolatorlaunch.com/api",
623
+ network: "mainnet",
624
+ });
625
+ ```
626
+
627
+ ### Known addresses via `getMarketsByAddress()`
628
+
629
+ If you already know your market slab addresses (e.g. from an indexer or
630
+ hardcoded list), fetch them directly:
631
+
632
+ ```typescript
633
+ import { getMarketsByAddress, getProgramId } from "@percolator/sdk";
634
+ import { Connection, PublicKey } from "@solana/web3.js";
635
+
636
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
637
+ const markets = await getMarketsByAddress(
638
+ connection,
639
+ getProgramId("mainnet"),
640
+ [new PublicKey("..."), new PublicKey("...")],
641
+ );
642
+ ```
443
643
 
444
644
  ---
445
645
 
@@ -448,7 +648,7 @@ const marketsCustom = await discoverMarkets(connection, { maxParallelTiers: 3 })
448
648
  ```
449
649
  @percolator/sdk
450
650
  ├── abi/ # Binary encoding/decoding matching on-chain layout
451
- │ ├── instructions.ts # Instruction data builders (all 28+ instructions)
651
+ │ ├── instructions.ts # Instruction data builders (all 72 instructions)
452
652
  │ ├── accounts.ts # Account struct deserialization
453
653
  │ ├── encode.ts # Low-level binary encoding (u8/u16/u32/u64/i128/pubkey)
454
654
  │ ├── errors.ts # On-chain error code → human-readable parsing
@@ -457,6 +657,7 @@ const marketsCustom = await discoverMarkets(connection, { maxParallelTiers: 3 })
457
657
  │ ├── slab.ts # Slab account parser (header + config + accounts)
458
658
  │ ├── pda.ts # PDA derivation (vault, LP, insurance mint)
459
659
  │ ├── discovery.ts # Market discovery (find all Percolator markets)
660
+ │ ├── rpc-pool.ts # RPC connection pool, retry, failover, health probes
460
661
  │ ├── dex-oracle.ts # DEX oracle price integration
461
662
  │ ├── token-program.ts # SPL Token helpers
462
663
  │ ├── ata.ts # Associated Token Account helpers
@@ -117,21 +117,6 @@ export declare const ACCOUNTS_UNPAUSE_MARKET: readonly AccountSpec[];
117
117
  * remember the positional order, and errors clearly on missing names.
118
118
  */
119
119
  export declare function buildAccountMetas(spec: readonly AccountSpec[], keys: PublicKey[] | Record<string, PublicKey>): AccountMeta[];
120
- /**
121
- * CreateInsuranceMint: 9 accounts
122
- * Creates SPL mint PDA for insurance LP tokens. Admin only, once per market.
123
- */
124
- export declare const ACCOUNTS_CREATE_INSURANCE_MINT: readonly AccountSpec[];
125
- /**
126
- * DepositInsuranceLP: 8 accounts
127
- * Deposit collateral into insurance fund, receive LP tokens.
128
- */
129
- export declare const ACCOUNTS_DEPOSIT_INSURANCE_LP: readonly AccountSpec[];
130
- /**
131
- * WithdrawInsuranceLP: 8 accounts
132
- * Burn LP tokens and withdraw proportional share of insurance fund.
133
- */
134
- export declare const ACCOUNTS_WITHDRAW_INSURANCE_LP: readonly AccountSpec[];
135
120
  /**
136
121
  * LpVaultWithdraw: 10 accounts (tag 39, PERC-627 / GH#1926 / PERC-8287)
137
122
  *
@@ -249,6 +234,13 @@ export declare const ACCOUNTS_CLEAR_PENDING_SETTLEMENT: readonly AccountSpec[];
249
234
  * Sets the per-wallet position cap (admin only). capE6=0 disables.
250
235
  */
251
236
  export declare const ACCOUNTS_SET_WALLET_CAP: readonly AccountSpec[];
237
+ /**
238
+ * InitMatcherCtx: 5 accounts
239
+ * Admin CPI-initializes the matcher context account for an LP slot.
240
+ * The LP PDA signs via invoke_signed in the program — it must be included in
241
+ * the transaction's account list even though it carries 0 lamports.
242
+ */
243
+ export declare const ACCOUNTS_INIT_MATCHER_CTX: readonly AccountSpec[];
252
244
  export declare const WELL_KNOWN: {
253
245
  readonly tokenProgram: PublicKey;
254
246
  readonly clock: PublicKey;
@@ -19,16 +19,27 @@ export declare function getErrorName(code: number): string;
19
19
  * Get actionable hint for error code.
20
20
  */
21
21
  export declare function getErrorHint(code: number): string | undefined;
22
+ /**
23
+ * Check whether an error code is in the Anchor framework error range
24
+ * (used by Lighthouse, not Percolator).
25
+ */
26
+ export declare function isAnchorErrorCode(code: number): boolean;
22
27
  /**
23
28
  * Parse error from transaction logs.
24
29
  * Looks for "Program ... failed: custom program error: 0x..."
25
30
  *
26
31
  * Hex capture is bounded (1–8 digits) so pathological logs cannot feed unbounded
27
32
  * strings into `parseInt` or produce precision-loss codes above u32.
33
+ *
34
+ * Distinguishes between:
35
+ * - Percolator program errors (codes 0–65): returns Percolator error info
36
+ * - Anchor/Lighthouse errors (codes 0x1770–0x1FFF): returns Lighthouse-specific
37
+ * name and hint so callers can handle wallet middleware failures
28
38
  */
29
39
  export declare function parseErrorFromLogs(logs: string[]): {
30
40
  code: number;
31
41
  name: string;
32
42
  hint?: string;
43
+ source?: "percolator" | "lighthouse" | "unknown";
33
44
  } | null;
34
45
  export {};
@@ -1,4 +1,9 @@
1
1
  import { PublicKey } from "@solana/web3.js";
2
+ /**
3
+ * Oracle price constraints.
4
+ * Maximum oracle price that can be pushed to the on-chain oracle authority.
5
+ */
6
+ export declare const MAX_ORACLE_PRICE = 1000000000000n;
2
7
  /**
3
8
  * Instruction tags - exact match to Rust ix::Instruction::decode
4
9
  */
@@ -25,16 +30,20 @@ export declare const IX_TAG: {
25
30
  readonly ResolveMarket: 19;
26
31
  readonly WithdrawInsurance: 20;
27
32
  readonly AdminForceClose: 21;
28
- readonly UpdateRiskParams: 22;
29
- readonly RenounceAdmin: 23;
30
- readonly CreateInsuranceMint: 24;
31
- readonly DepositInsuranceLP: 25;
32
- readonly WithdrawInsuranceLP: 26;
33
- readonly PauseMarket: 27;
34
- readonly UnpauseMarket: 28;
35
- readonly AcceptAdmin: 29;
36
- readonly SetInsuranceWithdrawPolicy: 30;
37
- readonly WithdrawInsuranceLimited: 31;
33
+ readonly SetInsuranceWithdrawPolicy: 22;
34
+ /** @deprecated Use SetInsuranceWithdrawPolicy */ readonly UpdateRiskParams: 22;
35
+ readonly WithdrawInsuranceLimited: 23;
36
+ /** @deprecated Use WithdrawInsuranceLimited */ readonly RenounceAdmin: 23;
37
+ readonly QueryLpFees: 24;
38
+ readonly ReclaimEmptyAccount: 25;
39
+ readonly SettleAccount: 26;
40
+ readonly DepositFeeCredits: 27;
41
+ /** @deprecated No on-chain PauseMarket instruction */ readonly PauseMarket: 27;
42
+ readonly ConvertReleasedPnl: 28;
43
+ /** @deprecated No on-chain UnpauseMarket instruction */ readonly UnpauseMarket: 28;
44
+ readonly ResolvePermissionless: 29;
45
+ /** @deprecated Use ResolvePermissionless */ readonly AcceptAdmin: 29;
46
+ readonly ForceCloseResolved: 30;
38
47
  readonly SetPythOracle: 32;
39
48
  readonly UpdateMarkPrice: 33;
40
49
  readonly UpdateHyperpMark: 34;
@@ -106,6 +115,14 @@ export declare const IX_TAG: {
106
115
  readonly SetWalletCap: 70;
107
116
  /** PERC-8110: Set OI imbalance hard-block threshold (admin only). */
108
117
  readonly SetOiImbalanceHardBlock: 71;
118
+ /** PERC-8270: Rescue orphan vault — recover tokens from a closed market's vault (admin). */
119
+ readonly RescueOrphanVault: 72;
120
+ /** PERC-8270: Close orphan slab — reclaim rent from a slab whose market closed unexpectedly (admin). */
121
+ readonly CloseOrphanSlab: 73;
122
+ /** PERC-SetDexPool: Pin admin-approved DEX pool address for a HYPERP market (admin). */
123
+ readonly SetDexPool: 74;
124
+ /** CPI to the matcher program to initialize a matcher context account for an LP slot. Admin-only. */
125
+ readonly InitMatcherCtx: 75;
109
126
  };
110
127
  /**
111
128
  * InitMarket instruction data (256 bytes total)
@@ -125,6 +142,9 @@ export interface InitMarketArgs {
125
142
  invert: number;
126
143
  unitScale: number;
127
144
  initialMarkPriceE6: bigint | string;
145
+ maxMaintenanceFeePerSlot?: bigint | string;
146
+ maxInsuranceFloor?: bigint | string;
147
+ minOraclePriceCap?: bigint | string;
128
148
  warmupPeriodSlots: bigint | string;
129
149
  maintenanceMarginBps: bigint | string;
130
150
  initialMarginBps: bigint | string;
@@ -138,6 +158,9 @@ export interface InitMarketArgs {
138
158
  liquidationFeeCap: bigint | string;
139
159
  liquidationBufferBps: bigint | string;
140
160
  minLiquidationAbs: bigint | string;
161
+ minInitialDeposit: bigint | string;
162
+ minNonzeroMmReq: bigint | string;
163
+ minNonzeroImReq: bigint | string;
141
164
  }
142
165
  export declare function encodeInitMarket(args: InitMarketArgs): Uint8Array;
143
166
  /**
@@ -297,6 +320,17 @@ export interface PushOraclePriceArgs {
297
320
  priceE6: bigint | string;
298
321
  timestamp: bigint | string;
299
322
  }
323
+ /**
324
+ * Encode PushOraclePrice instruction data with validation.
325
+ *
326
+ * Validates oracle price constraints:
327
+ * - Price cannot be zero (division by zero in on-chain engine)
328
+ * - Price cannot exceed MAX_ORACLE_PRICE (prevents overflow in price math)
329
+ *
330
+ * @param args - PushOraclePrice arguments
331
+ * @returns Encoded instruction data (17 bytes)
332
+ * @throws Error if price is 0 or exceeds MAX_ORACLE_PRICE
333
+ */
300
334
  export declare function encodePushOraclePrice(args: PushOraclePriceArgs): Uint8Array;
301
335
  /**
302
336
  * SetOraclePriceCap instruction data (9 bytes)
@@ -366,27 +400,6 @@ export declare const UNRESOLVE_CONFIRMATION = 16045690984503054900n;
366
400
  * to prevent accidental invocation.
367
401
  */
368
402
  export declare function encodeRenounceAdmin(): Uint8Array;
369
- /**
370
- * CreateInsuranceMint instruction data (1 byte)
371
- * Creates the SPL mint PDA for insurance LP tokens. Admin only, once per market.
372
- */
373
- export declare function encodeCreateInsuranceMint(): Uint8Array;
374
- /**
375
- * DepositInsuranceLP instruction data (9 bytes)
376
- * Deposit collateral into insurance fund, receive LP tokens proportional to share.
377
- */
378
- export interface DepositInsuranceLPArgs {
379
- amount: bigint | string;
380
- }
381
- export declare function encodeDepositInsuranceLP(args: DepositInsuranceLPArgs): Uint8Array;
382
- /**
383
- * WithdrawInsuranceLP instruction data (9 bytes)
384
- * Burn LP tokens and withdraw proportional share of insurance fund.
385
- */
386
- export interface WithdrawInsuranceLPArgs {
387
- lpAmount: bigint | string;
388
- }
389
- export declare function encodeWithdrawInsuranceLP(args: WithdrawInsuranceLPArgs): Uint8Array;
390
403
  /**
391
404
  * LpVaultWithdraw (Tag 39, PERC-627 / GH#1926 / PERC-8287) — burn LP vault tokens and
392
405
  * withdraw proportional collateral.
@@ -988,3 +1001,111 @@ export interface SetWalletCapArgs {
988
1001
  capE6: bigint | string;
989
1002
  }
990
1003
  export declare function encodeSetWalletCap(args: SetWalletCapArgs): Uint8Array;
1004
+ /**
1005
+ * InitMatcherCtx (Tag 75) — admin initializes the matcher context account for an LP slot.
1006
+ *
1007
+ * The matcher program (DHP6DtwXP1yJsz8YzfoeigRFPB979gzmumkmCxDLSkUX) requires its context
1008
+ * account to be initialized before TradeCpi can work. Only the percolator program can sign
1009
+ * as the LP PDA via invoke_signed, so this instruction acts as the trusted initializer.
1010
+ *
1011
+ * Instruction data layout: tag(1) + lp_idx(2) + kind(1) + trading_fee_bps(4) +
1012
+ * base_spread_bps(4) + max_total_bps(4) + impact_k_bps(4) +
1013
+ * liquidity_notional_e6(16) + max_fill_abs(16) + max_inventory_abs(16) +
1014
+ * fee_to_insurance_bps(2) + skew_spread_mult_bps(2) = 72 bytes
1015
+ *
1016
+ * Accounts:
1017
+ * 0. [signer] admin
1018
+ * 1. [] slab (program-owned; used to verify admin + LP slot)
1019
+ * 2. [writable] matcherCtx (must match LP's stored matcher_context)
1020
+ * 3. [] matcherProg (executable; must match LP's stored matcher_program)
1021
+ * 4. [] lpPda (PDA ["lp", slab, lp_idx]; required by CPI as signer)
1022
+ */
1023
+ export interface InitMatcherCtxArgs {
1024
+ /** LP account index in the engine (0-based). */
1025
+ lpIdx: number;
1026
+ /** Matcher kind: 0=Passive, 1=vAMM. */
1027
+ kind: number;
1028
+ /** Base trading fee in bps (e.g. 30 = 0.30%). */
1029
+ tradingFeeBps: number;
1030
+ /** Base spread in bps. */
1031
+ baseSpreadBps: number;
1032
+ /** Max total spread in bps. */
1033
+ maxTotalBps: number;
1034
+ /** vAMM impact constant in bps (0 for passive matchers). */
1035
+ impactKBps: number;
1036
+ /** Liquidity notional in e6 units (0 for passive matchers). */
1037
+ liquidityNotionalE6: bigint | string;
1038
+ /** Max single fill size in absolute units (u128::MAX = no limit). */
1039
+ maxFillAbs: bigint | string;
1040
+ /** Max inventory size in absolute units (u128::MAX = no limit). */
1041
+ maxInventoryAbs: bigint | string;
1042
+ /** Fraction of fees routed to insurance fund in bps. */
1043
+ feeToInsuranceBps: number;
1044
+ /** Skew spread multiplier in bps (0 = disabled). */
1045
+ skewSpreadMultBps: number;
1046
+ }
1047
+ export declare function encodeInitMatcherCtx(args: InitMatcherCtxArgs): Uint8Array;
1048
+ /** SetInsuranceWithdrawPolicy (tag 22): authority + min_withdraw_base + max_withdraw_bps + cooldown_slots */
1049
+ export interface SetInsuranceWithdrawPolicyArgs {
1050
+ authority: PublicKey | string;
1051
+ minWithdrawBase: bigint | string;
1052
+ maxWithdrawBps: number;
1053
+ cooldownSlots: bigint | string;
1054
+ }
1055
+ export declare function encodeSetInsuranceWithdrawPolicy(args: SetInsuranceWithdrawPolicyArgs): Uint8Array;
1056
+ /** WithdrawInsuranceLimited (tag 23): amount */
1057
+ export declare function encodeWithdrawInsuranceLimited(args: {
1058
+ amount: bigint | string;
1059
+ }): Uint8Array;
1060
+ /** ResolvePermissionless (tag 29): no args */
1061
+ export declare function encodeResolvePermissionless(): Uint8Array;
1062
+ /** ForceCloseResolved (tag 30): user_idx */
1063
+ export declare function encodeForceCloseResolved(args: {
1064
+ userIdx: number;
1065
+ }): Uint8Array;
1066
+ /** CreateLpVault (tag 37): fee_share_bps + util_curve_enabled */
1067
+ export declare function encodeCreateLpVault(args: {
1068
+ feeShareBps: bigint | string;
1069
+ utilCurveEnabled?: boolean;
1070
+ }): Uint8Array;
1071
+ /** LpVaultDeposit (tag 38): amount */
1072
+ export declare function encodeLpVaultDeposit(args: {
1073
+ amount: bigint | string;
1074
+ }): Uint8Array;
1075
+ /** LpVaultCrankFees (tag 40): no args */
1076
+ export declare function encodeLpVaultCrankFees(): Uint8Array;
1077
+ /** ChallengeSettlement (tag 43): proposed_price_e6 */
1078
+ export declare function encodeChallengeSettlement(args: {
1079
+ proposedPriceE6: bigint | string;
1080
+ }): Uint8Array;
1081
+ /** ResolveDispute (tag 44): accept (0 = reject, 1 = accept) */
1082
+ export declare function encodeResolveDispute(args: {
1083
+ accept: number;
1084
+ }): Uint8Array;
1085
+ /** DepositLpCollateral (tag 45): user_idx + lp_amount */
1086
+ export declare function encodeDepositLpCollateral(args: {
1087
+ userIdx: number;
1088
+ lpAmount: bigint | string;
1089
+ }): Uint8Array;
1090
+ /** WithdrawLpCollateral (tag 46): user_idx + lp_amount */
1091
+ export declare function encodeWithdrawLpCollateral(args: {
1092
+ userIdx: number;
1093
+ lpAmount: bigint | string;
1094
+ }): Uint8Array;
1095
+ /** SetOffsetPair (tag 54): offset_bps */
1096
+ export declare function encodeSetOffsetPair(args: {
1097
+ offsetBps: number;
1098
+ }): Uint8Array;
1099
+ /** AttestCrossMargin (tag 55): user_idx_a + user_idx_b */
1100
+ export declare function encodeAttestCrossMargin(args: {
1101
+ userIdxA: number;
1102
+ userIdxB: number;
1103
+ }): Uint8Array;
1104
+ /** RescueOrphanVault (tag 72): no args */
1105
+ export declare function encodeRescueOrphanVault(): Uint8Array;
1106
+ /** CloseOrphanSlab (tag 73): no args */
1107
+ export declare function encodeCloseOrphanSlab(): Uint8Array;
1108
+ /** SetDexPool (tag 74): pool pubkey */
1109
+ export declare function encodeSetDexPool(args: {
1110
+ pool: PublicKey | string;
1111
+ }): Uint8Array;
@@ -17,7 +17,7 @@ export declare const PROGRAM_IDS: {
17
17
  readonly matcher: "GTRgyTDfrMvBubALAqtHuQwT8tbGyXid7svXZKtWfC9k";
18
18
  };
19
19
  readonly mainnet: {
20
- readonly percolator: "GM8zjJ8LTBMv9xEsverh6H6wLyevgMHEJXcEzyY3rY24";
20
+ readonly percolator: "ESa89R5Es3rJ5mnwGybVRG1GrNt9etP11Z5V2QWD4edv";
21
21
  readonly matcher: "DHP6DtwXP1yJsz8YzfoeigRFPB979gzmumkmCxDLSkUX";
22
22
  };
23
23
  };