@percolatorct/sdk 0.5.0 → 1.0.0-beta.1
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 +224 -23
- package/dist/abi/accounts.d.ts +7 -0
- package/dist/abi/errors.d.ts +11 -0
- package/dist/abi/instructions.d.ts +68 -0
- package/dist/index.js +1407 -188
- package/dist/index.js.map +1 -1
- package/dist/math/trading.d.ts +116 -1
- package/dist/math/warmup.d.ts +50 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/lighthouse.d.ts +170 -0
- package/dist/solana/discovery.d.ts +253 -24
- package/dist/solana/index.d.ts +2 -0
- package/dist/solana/oracle.d.ts +10 -2
- package/dist/solana/rpc-pool.d.ts +347 -0
- package/dist/solana/slab.d.ts +37 -5
- package/dist/solana/static-markets.d.ts +86 -0
- package/dist/validation.d.ts +26 -1
- package/package.json +5 -4
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
|
-
> **⚠️
|
|
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
|
[](https://www.npmjs.com/package/@percolator/sdk)
|
|
8
8
|
[](LICENSE)
|
|
@@ -27,10 +27,13 @@ npm install @percolator/sdk
|
|
|
27
27
|
import {
|
|
28
28
|
getProgramId,
|
|
29
29
|
deriveVaultAuthority,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
|
47
|
-
const
|
|
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 {
|
|
163
|
+
import {
|
|
164
|
+
parseHeader,
|
|
165
|
+
parseConfig,
|
|
166
|
+
parseAllAccounts,
|
|
167
|
+
detectSlabLayout,
|
|
168
|
+
} from "@percolator/sdk";
|
|
157
169
|
|
|
158
|
-
const
|
|
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,
|
|
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://
|
|
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` |
|
|
342
|
-
| 62 | `EngineCorruptState` | Slab state corrupt —
|
|
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 {
|
|
392
|
+
import {
|
|
393
|
+
validatePublicKey,
|
|
394
|
+
validateAmount,
|
|
395
|
+
validateBps,
|
|
396
|
+
validateI128,
|
|
397
|
+
validateIndex,
|
|
398
|
+
} from "@percolator/sdk";
|
|
376
399
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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 | `
|
|
411
|
-
| Matcher | 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.
|
|
442
|
-
>
|
|
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
|
|
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
|
package/dist/abi/accounts.d.ts
CHANGED
|
@@ -249,6 +249,13 @@ export declare const ACCOUNTS_CLEAR_PENDING_SETTLEMENT: readonly AccountSpec[];
|
|
|
249
249
|
* Sets the per-wallet position cap (admin only). capE6=0 disables.
|
|
250
250
|
*/
|
|
251
251
|
export declare const ACCOUNTS_SET_WALLET_CAP: readonly AccountSpec[];
|
|
252
|
+
/**
|
|
253
|
+
* InitMatcherCtx: 5 accounts
|
|
254
|
+
* Admin CPI-initializes the matcher context account for an LP slot.
|
|
255
|
+
* The LP PDA signs via invoke_signed in the program — it must be included in
|
|
256
|
+
* the transaction's account list even though it carries 0 lamports.
|
|
257
|
+
*/
|
|
258
|
+
export declare const ACCOUNTS_INIT_MATCHER_CTX: readonly AccountSpec[];
|
|
252
259
|
export declare const WELL_KNOWN: {
|
|
253
260
|
readonly tokenProgram: PublicKey;
|
|
254
261
|
readonly clock: PublicKey;
|
package/dist/abi/errors.d.ts
CHANGED
|
@@ -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
|
*/
|
|
@@ -106,6 +111,14 @@ export declare const IX_TAG: {
|
|
|
106
111
|
readonly SetWalletCap: 70;
|
|
107
112
|
/** PERC-8110: Set OI imbalance hard-block threshold (admin only). */
|
|
108
113
|
readonly SetOiImbalanceHardBlock: 71;
|
|
114
|
+
/** PERC-8270: Rescue orphan vault — recover tokens from a closed market's vault (admin). */
|
|
115
|
+
readonly RescueOrphanVault: 72;
|
|
116
|
+
/** PERC-8270: Close orphan slab — reclaim rent from a slab whose market closed unexpectedly (admin). */
|
|
117
|
+
readonly CloseOrphanSlab: 73;
|
|
118
|
+
/** PERC-SetDexPool: Pin admin-approved DEX pool address for a HYPERP market (admin). */
|
|
119
|
+
readonly SetDexPool: 74;
|
|
120
|
+
/** CPI to the matcher program to initialize a matcher context account for an LP slot. Admin-only. */
|
|
121
|
+
readonly InitMatcherCtx: 75;
|
|
109
122
|
};
|
|
110
123
|
/**
|
|
111
124
|
* InitMarket instruction data (256 bytes total)
|
|
@@ -297,6 +310,17 @@ export interface PushOraclePriceArgs {
|
|
|
297
310
|
priceE6: bigint | string;
|
|
298
311
|
timestamp: bigint | string;
|
|
299
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Encode PushOraclePrice instruction data with validation.
|
|
315
|
+
*
|
|
316
|
+
* Validates oracle price constraints:
|
|
317
|
+
* - Price cannot be zero (division by zero in on-chain engine)
|
|
318
|
+
* - Price cannot exceed MAX_ORACLE_PRICE (prevents overflow in price math)
|
|
319
|
+
*
|
|
320
|
+
* @param args - PushOraclePrice arguments
|
|
321
|
+
* @returns Encoded instruction data (17 bytes)
|
|
322
|
+
* @throws Error if price is 0 or exceeds MAX_ORACLE_PRICE
|
|
323
|
+
*/
|
|
300
324
|
export declare function encodePushOraclePrice(args: PushOraclePriceArgs): Uint8Array;
|
|
301
325
|
/**
|
|
302
326
|
* SetOraclePriceCap instruction data (9 bytes)
|
|
@@ -988,3 +1012,47 @@ export interface SetWalletCapArgs {
|
|
|
988
1012
|
capE6: bigint | string;
|
|
989
1013
|
}
|
|
990
1014
|
export declare function encodeSetWalletCap(args: SetWalletCapArgs): Uint8Array;
|
|
1015
|
+
/**
|
|
1016
|
+
* InitMatcherCtx (Tag 75) — admin initializes the matcher context account for an LP slot.
|
|
1017
|
+
*
|
|
1018
|
+
* The matcher program (DHP6DtwXP1yJsz8YzfoeigRFPB979gzmumkmCxDLSkUX) requires its context
|
|
1019
|
+
* account to be initialized before TradeCpi can work. Only the percolator program can sign
|
|
1020
|
+
* as the LP PDA via invoke_signed, so this instruction acts as the trusted initializer.
|
|
1021
|
+
*
|
|
1022
|
+
* Instruction data layout: tag(1) + lp_idx(2) + kind(1) + trading_fee_bps(4) +
|
|
1023
|
+
* base_spread_bps(4) + max_total_bps(4) + impact_k_bps(4) +
|
|
1024
|
+
* liquidity_notional_e6(16) + max_fill_abs(16) + max_inventory_abs(16) +
|
|
1025
|
+
* fee_to_insurance_bps(2) + skew_spread_mult_bps(2) = 72 bytes
|
|
1026
|
+
*
|
|
1027
|
+
* Accounts:
|
|
1028
|
+
* 0. [signer] admin
|
|
1029
|
+
* 1. [] slab (program-owned; used to verify admin + LP slot)
|
|
1030
|
+
* 2. [writable] matcherCtx (must match LP's stored matcher_context)
|
|
1031
|
+
* 3. [] matcherProg (executable; must match LP's stored matcher_program)
|
|
1032
|
+
* 4. [] lpPda (PDA ["lp", slab, lp_idx]; required by CPI as signer)
|
|
1033
|
+
*/
|
|
1034
|
+
export interface InitMatcherCtxArgs {
|
|
1035
|
+
/** LP account index in the engine (0-based). */
|
|
1036
|
+
lpIdx: number;
|
|
1037
|
+
/** Matcher kind: 0=Passive, 1=vAMM. */
|
|
1038
|
+
kind: number;
|
|
1039
|
+
/** Base trading fee in bps (e.g. 30 = 0.30%). */
|
|
1040
|
+
tradingFeeBps: number;
|
|
1041
|
+
/** Base spread in bps. */
|
|
1042
|
+
baseSpreadBps: number;
|
|
1043
|
+
/** Max total spread in bps. */
|
|
1044
|
+
maxTotalBps: number;
|
|
1045
|
+
/** vAMM impact constant in bps (0 for passive matchers). */
|
|
1046
|
+
impactKBps: number;
|
|
1047
|
+
/** Liquidity notional in e6 units (0 for passive matchers). */
|
|
1048
|
+
liquidityNotionalE6: bigint | string;
|
|
1049
|
+
/** Max single fill size in absolute units (u128::MAX = no limit). */
|
|
1050
|
+
maxFillAbs: bigint | string;
|
|
1051
|
+
/** Max inventory size in absolute units (u128::MAX = no limit). */
|
|
1052
|
+
maxInventoryAbs: bigint | string;
|
|
1053
|
+
/** Fraction of fees routed to insurance fund in bps. */
|
|
1054
|
+
feeToInsuranceBps: number;
|
|
1055
|
+
/** Skew spread multiplier in bps (0 = disabled). */
|
|
1056
|
+
skewSpreadMultBps: number;
|
|
1057
|
+
}
|
|
1058
|
+
export declare function encodeInitMatcherCtx(args: InitMatcherCtxArgs): Uint8Array;
|