@percolatorct/sdk 0.5.1 → 1.0.0-beta.2

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.
@@ -0,0 +1,347 @@
1
+ import { Connection, type Commitment, type ConnectionConfig } from "@solana/web3.js";
2
+ /**
3
+ * Configuration for exponential-backoff retry on RPC calls.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * const retryConfig: RetryConfig = {
8
+ * maxRetries: 3,
9
+ * baseDelayMs: 500,
10
+ * maxDelayMs: 10_000,
11
+ * retryableStatusCodes: [429, 502, 503],
12
+ * };
13
+ * ```
14
+ */
15
+ export interface RetryConfig {
16
+ /**
17
+ * Maximum number of retry attempts after the initial request fails.
18
+ * @default 3
19
+ */
20
+ maxRetries?: number;
21
+ /**
22
+ * Base delay in ms for exponential backoff.
23
+ * Delay for attempt N is: `min(baseDelayMs * 2^N, maxDelayMs) + jitter`.
24
+ * @default 500
25
+ */
26
+ baseDelayMs?: number;
27
+ /**
28
+ * Maximum delay in ms (backoff cap).
29
+ * @default 10_000
30
+ */
31
+ maxDelayMs?: number;
32
+ /**
33
+ * Jitter factor (0–1). Applied as random `[0, jitterFactor * delay]` addition.
34
+ * @default 0.25
35
+ */
36
+ jitterFactor?: number;
37
+ /**
38
+ * HTTP status codes considered retryable.
39
+ * Errors matching these codes (or containing their string representation)
40
+ * will be retried.
41
+ * @default [429, 502, 503, 504]
42
+ */
43
+ retryableStatusCodes?: number[];
44
+ }
45
+ /**
46
+ * Configuration for a single RPC endpoint in the pool.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const endpoint: RpcEndpointConfig = {
51
+ * url: "https://mainnet.helius-rpc.com/?api-key=YOUR_KEY",
52
+ * weight: 10,
53
+ * label: "helius-primary",
54
+ * };
55
+ * ```
56
+ */
57
+ export interface RpcEndpointConfig {
58
+ /** RPC endpoint URL. */
59
+ url: string;
60
+ /**
61
+ * Relative weight for round-robin selection.
62
+ * Higher weight = more requests routed here.
63
+ * @default 1
64
+ */
65
+ weight?: number;
66
+ /**
67
+ * Human-readable label for logging / diagnostics.
68
+ * @default url hostname
69
+ */
70
+ label?: string;
71
+ /**
72
+ * Extra `ConnectionConfig` options (commitment, confirmTransactionInitialTimeout, etc.)
73
+ * merged into the Solana `Connection` constructor for this endpoint.
74
+ */
75
+ connectionConfig?: ConnectionConfig;
76
+ }
77
+ /**
78
+ * Strategy for selecting the next RPC endpoint from the pool.
79
+ *
80
+ * - `"round-robin"` — weighted round-robin across healthy endpoints.
81
+ * - `"failover"` — use the first healthy endpoint; only advance on failure.
82
+ */
83
+ export type SelectionStrategy = "round-robin" | "failover";
84
+ /**
85
+ * Full configuration for the RPC connection pool.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * import { RpcPool } from "@percolator/sdk";
90
+ *
91
+ * const pool = new RpcPool({
92
+ * endpoints: [
93
+ * { url: "https://mainnet.helius-rpc.com/?api-key=KEY", weight: 10, label: "helius" },
94
+ * { url: "https://api.mainnet-beta.solana.com", weight: 1, label: "public" },
95
+ * ],
96
+ * strategy: "failover",
97
+ * retry: { maxRetries: 3, baseDelayMs: 500 },
98
+ * requestTimeoutMs: 30_000,
99
+ * });
100
+ *
101
+ * // Use like a Connection — same surface
102
+ * const slot = await pool.call(conn => conn.getSlot());
103
+ * ```
104
+ */
105
+ export interface RpcPoolConfig {
106
+ /**
107
+ * One or more RPC endpoints. At least one is required.
108
+ * If a bare `string[]` is passed, each string is treated as `{ url: string }`.
109
+ */
110
+ endpoints: (RpcEndpointConfig | string)[];
111
+ /**
112
+ * How to pick the next endpoint.
113
+ * @default "failover"
114
+ */
115
+ strategy?: SelectionStrategy;
116
+ /**
117
+ * Retry config applied to every `call()`.
118
+ * Set to `false` to disable retries entirely.
119
+ * @default { maxRetries: 3, baseDelayMs: 500 }
120
+ */
121
+ retry?: RetryConfig | false;
122
+ /**
123
+ * Per-request timeout in ms. Applies an `AbortSignal` timeout to `Connection`
124
+ * calls where supported, and is used as a deadline for the health probe.
125
+ * @default 30_000
126
+ */
127
+ requestTimeoutMs?: number;
128
+ /**
129
+ * Default Solana commitment level for connections.
130
+ * @default "confirmed"
131
+ */
132
+ commitment?: Commitment;
133
+ /**
134
+ * If true, `console.warn` diagnostic messages on retries, failovers, etc.
135
+ * @default true
136
+ */
137
+ verbose?: boolean;
138
+ }
139
+ /**
140
+ * Result of an RPC health probe.
141
+ *
142
+ * @example
143
+ * ```ts
144
+ * import { checkRpcHealth } from "@percolator/sdk";
145
+ *
146
+ * const health = await checkRpcHealth("https://api.mainnet-beta.solana.com");
147
+ * console.log(`Slot: ${health.slot}, Latency: ${health.latencyMs}ms`);
148
+ * if (!health.healthy) console.warn(`Unhealthy: ${health.error}`);
149
+ * ```
150
+ */
151
+ export interface RpcHealthResult {
152
+ /** The endpoint that was probed. */
153
+ endpoint: string;
154
+ /** Whether the probe succeeded (getSlot returned without error). */
155
+ healthy: boolean;
156
+ /** Round-trip latency in milliseconds (0 if unhealthy). */
157
+ latencyMs: number;
158
+ /** Current slot height (0 if unhealthy). */
159
+ slot: number;
160
+ /** Error message if the probe failed. */
161
+ error?: string;
162
+ }
163
+ /**
164
+ * Probe an RPC endpoint's health by calling `getSlot()` and measuring latency.
165
+ *
166
+ * @param endpoint - RPC URL to probe
167
+ * @param timeoutMs - Timeout in ms for the probe request (default: 5000)
168
+ * @returns Health result with latency and slot height
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * import { checkRpcHealth } from "@percolator/sdk";
173
+ *
174
+ * const result = await checkRpcHealth("https://api.mainnet-beta.solana.com", 3000);
175
+ * if (result.healthy) {
176
+ * console.log(`Slot ${result.slot} — ${result.latencyMs}ms`);
177
+ * } else {
178
+ * console.error(`RPC down: ${result.error}`);
179
+ * }
180
+ * ```
181
+ */
182
+ export declare function checkRpcHealth(endpoint: string, timeoutMs?: number): Promise<RpcHealthResult>;
183
+ /** Resolved defaults for RetryConfig. */
184
+ interface ResolvedRetryConfig {
185
+ maxRetries: number;
186
+ baseDelayMs: number;
187
+ maxDelayMs: number;
188
+ jitterFactor: number;
189
+ retryableStatusCodes: number[];
190
+ }
191
+ declare function resolveRetryConfig(cfg?: RetryConfig | false): ResolvedRetryConfig | null;
192
+ declare function normalizeEndpoint(ep: RpcEndpointConfig | string): RpcEndpointConfig;
193
+ declare function endpointLabel(ep: RpcEndpointConfig): string;
194
+ declare function isRetryable(err: unknown, codes: number[]): boolean;
195
+ declare function computeDelay(attempt: number, config: ResolvedRetryConfig): number;
196
+ /**
197
+ * RPC connection pool with retry, failover, and round-robin support.
198
+ *
199
+ * Wraps one or more Solana RPC endpoints behind a single `call()` interface
200
+ * that automatically retries transient errors and fails over to alternate
201
+ * endpoints when one goes down.
202
+ *
203
+ * @example
204
+ * ```ts
205
+ * import { RpcPool } from "@percolator/sdk";
206
+ *
207
+ * const pool = new RpcPool({
208
+ * endpoints: [
209
+ * { url: "https://mainnet.helius-rpc.com/?api-key=KEY", weight: 10, label: "helius" },
210
+ * { url: "https://api.mainnet-beta.solana.com", weight: 1, label: "public" },
211
+ * ],
212
+ * strategy: "failover",
213
+ * retry: { maxRetries: 3 },
214
+ * requestTimeoutMs: 30_000,
215
+ * });
216
+ *
217
+ * // Execute any Connection method through the pool
218
+ * const slot = await pool.call(conn => conn.getSlot());
219
+ *
220
+ * // Or get a raw connection for one-off use
221
+ * const conn = pool.getConnection();
222
+ *
223
+ * // Health check all endpoints
224
+ * const results = await pool.healthCheck();
225
+ * ```
226
+ */
227
+ export declare class RpcPool {
228
+ private readonly endpoints;
229
+ private readonly strategy;
230
+ private readonly retryConfig;
231
+ private readonly requestTimeoutMs;
232
+ private readonly verbose;
233
+ /** Round-robin index tracker. */
234
+ private rrIndex;
235
+ /** Consecutive failure threshold before marking an endpoint unhealthy. */
236
+ private static readonly UNHEALTHY_THRESHOLD;
237
+ /** Minimum endpoints before auto-recovery is attempted. */
238
+ private static readonly MIN_HEALTHY;
239
+ constructor(config: RpcPoolConfig);
240
+ /**
241
+ * Execute a function against a pooled connection with automatic retry
242
+ * and failover.
243
+ *
244
+ * @param fn - Async function that receives a `Connection` and returns a result.
245
+ * @returns The result of `fn`.
246
+ * @throws The last error if all retries and failovers are exhausted.
247
+ *
248
+ * @example
249
+ * ```ts
250
+ * const balance = await pool.call(c => c.getBalance(pubkey));
251
+ * const markets = await pool.call(c => discoverMarkets(c, programId, opts));
252
+ * ```
253
+ */
254
+ call<T>(fn: (connection: Connection) => Promise<T>): Promise<T>;
255
+ /**
256
+ * Get a raw `Connection` from the current preferred endpoint.
257
+ * Useful when you need to pass a Connection to external code.
258
+ *
259
+ * NOTE: This bypasses retry and failover logic. Prefer `call()`.
260
+ *
261
+ * @returns Solana Connection from the current preferred endpoint.
262
+ *
263
+ * @example
264
+ * ```ts
265
+ * const conn = pool.getConnection();
266
+ * const balance = await conn.getBalance(pubkey);
267
+ * ```
268
+ */
269
+ getConnection(): Connection;
270
+ /**
271
+ * Run a health check against all endpoints in the pool.
272
+ *
273
+ * @param timeoutMs - Per-endpoint probe timeout (default: 5000)
274
+ * @returns Array of health results, one per endpoint.
275
+ *
276
+ * @example
277
+ * ```ts
278
+ * const results = await pool.healthCheck();
279
+ * for (const r of results) {
280
+ * console.log(`${r.endpoint}: ${r.healthy ? 'UP' : 'DOWN'} (${r.latencyMs}ms, slot ${r.slot})`);
281
+ * }
282
+ * ```
283
+ */
284
+ healthCheck(timeoutMs?: number): Promise<RpcHealthResult[]>;
285
+ /**
286
+ * Get the number of endpoints in the pool.
287
+ */
288
+ get size(): number;
289
+ /**
290
+ * Get the number of currently healthy endpoints.
291
+ */
292
+ get healthyCount(): number;
293
+ /**
294
+ * Get endpoint labels and their current status.
295
+ *
296
+ * @returns Array of `{ label, url, healthy, failures, lastLatencyMs }`.
297
+ */
298
+ status(): Array<{
299
+ label: string;
300
+ url: string;
301
+ healthy: boolean;
302
+ failures: number;
303
+ lastLatencyMs: number;
304
+ }>;
305
+ /**
306
+ * Select the next endpoint based on strategy.
307
+ * Returns -1 if no endpoint is available.
308
+ */
309
+ private selectEndpoint;
310
+ /**
311
+ * If all endpoints are unhealthy, reset them so we at least try again.
312
+ */
313
+ private maybeRecoverEndpoints;
314
+ }
315
+ /**
316
+ * Execute an async function with exponential-backoff retry.
317
+ *
318
+ * Use this when you already have a `Connection` and just want retry logic
319
+ * without a full pool.
320
+ *
321
+ * @param fn - Async function to execute
322
+ * @param config - Retry configuration (default: 3 retries, 500ms base delay)
323
+ * @returns Result of `fn`
324
+ * @throws The last error if all retries are exhausted
325
+ *
326
+ * @example
327
+ * ```ts
328
+ * import { withRetry } from "@percolator/sdk";
329
+ * import { Connection } from "@solana/web3.js";
330
+ *
331
+ * const conn = new Connection("https://api.mainnet-beta.solana.com");
332
+ * const slot = await withRetry(
333
+ * () => conn.getSlot(),
334
+ * { maxRetries: 3, baseDelayMs: 1000 },
335
+ * );
336
+ * ```
337
+ */
338
+ export declare function withRetry<T>(fn: () => Promise<T>, config?: RetryConfig): Promise<T>;
339
+ /** @internal — exposed for unit tests only */
340
+ export declare const _internal: {
341
+ readonly isRetryable: typeof isRetryable;
342
+ readonly computeDelay: typeof computeDelay;
343
+ readonly resolveRetryConfig: typeof resolveRetryConfig;
344
+ readonly normalizeEndpoint: typeof normalizeEndpoint;
345
+ readonly endpointLabel: typeof endpointLabel;
346
+ };
347
+ export {};
@@ -85,8 +85,10 @@ export declare const SLAB_TIERS_V1M: Record<string, {
85
85
  description: string;
86
86
  }>;
87
87
  /**
88
- * V1M2 slab tier sizes — mainnet program with 312-byte accounts.
89
- * Same engine layout as V1M but larger accounts. Sizes match V_ADL exactly.
88
+ * V1M2 slab tier sizes — mainnet program rebuilt from main@4861c56 with 312-byte accounts.
89
+ * ENGINE_OFF=616, BITMAP_OFF=1008 (empirically verified from CCTegYZ...).
90
+ * Engine struct is layout-identical to V_ADL; differs only in engineOff (616 vs 624).
91
+ * Sizes are unique from V_ADL after the bitmap correction: medium=323312 vs V_ADL=323320.
90
92
  */
91
93
  export declare const SLAB_TIERS_V1M2: Record<string, {
92
94
  maxAccounts: number;
@@ -96,9 +98,9 @@ export declare const SLAB_TIERS_V1M2: Record<string, {
96
98
  }>;
97
99
  /**
98
100
  * V_ADL slab tier sizes — PERC-8270/8271 ADL-upgraded program.
99
- * ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312, postBitmap=18.
101
+ * ENGINE_OFF=624, BITMAP_OFF=1008, ACCOUNT_SIZE=312, postBitmap=18.
100
102
  * New account layout adds ADL tracking fields (+64 bytes/account including alignment padding).
101
- * BPF SLAB_LEN verified by cargo build-sbf in PERC-8271: large (4096) = 1288304 bytes.
103
+ * BPF SLAB_LEN verified by cargo build-sbf in PERC-8271: large (4096) = 1288320 bytes.
102
104
  */
103
105
  export declare const SLAB_TIERS_V_ADL: Record<string, {
104
106
  maxAccounts: number;
@@ -106,10 +108,32 @@ export declare const SLAB_TIERS_V_ADL: Record<string, {
106
108
  label: string;
107
109
  description: string;
108
110
  }>;
111
+ /**
112
+ * V_SETDEXPOOL slab tier sizes — PERC-SetDexPool security fix.
113
+ * ENGINE_OFF=632, BITMAP_OFF=1008, ACCOUNT_SIZE=312, CONFIG_LEN=528.
114
+ * e.g. large (4096 accts) = 1288336 bytes.
115
+ */
116
+ export declare const SLAB_TIERS_V_SETDEXPOOL: Record<string, {
117
+ maxAccounts: number;
118
+ dataSize: number;
119
+ label: string;
120
+ description: string;
121
+ }>;
122
+ /**
123
+ * V12_1 slab tier sizes — percolator-core v12.1 merge.
124
+ * ENGINE_OFF=648, BITMAP_OFF=1016, ACCOUNT_SIZE=320.
125
+ * Verified by cargo build-sbf compile-time assertions.
126
+ */
127
+ export declare const SLAB_TIERS_V12_1: Record<string, {
128
+ maxAccounts: number;
129
+ dataSize: number;
130
+ label: string;
131
+ description: string;
132
+ }>;
109
133
  /**
110
134
  * Detect the slab layout version from the raw account data length.
111
135
  * Returns the full SlabLayout descriptor, or null if the size is unrecognised.
112
- * Checks V_ADL, V1M, V0, V1D, V1D-legacy, V1, and V1-legacy sizes in priority order.
136
+ * Checks V12_1, V_SETDEXPOOL, V1M2, V_ADL, V1M, V0, V1D, V1D-legacy, V1, and V1-legacy sizes.
113
137
  *
114
138
  * When `data` is provided and the size matches V1D, the version field at offset 8 is read
115
139
  * to disambiguate V2 slabs (which produce identical sizes to V1D with postBitmap=2).
@@ -189,6 +213,14 @@ export interface MarketConfig {
189
213
  cumulativeVolumeE6: bigint;
190
214
  /** PERC-622: Slots elapsed from market creation to Phase 2 entry (u24) */
191
215
  phase2DeltaSlots: number;
216
+ /**
217
+ * PERC-SetDexPool: Admin-pinned DEX pool pubkey for HYPERP markets.
218
+ * Null when reading old slabs (pre-SetDexPool configLen < 528) or when
219
+ * SetDexPool has never been called (all-zero pubkey).
220
+ * Non-null means the program will reject any UpdateHyperpMark that passes
221
+ * a different pool account.
222
+ */
223
+ dexPool: PublicKey | null;
192
224
  }
193
225
  export interface InsuranceFund {
194
226
  balance: bigint;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Static market registry — bundled list of known Percolator slab addresses.
3
+ *
4
+ * This is the tier-3 fallback for `discoverMarkets()`: when both
5
+ * `getProgramAccounts` (tier 1) and the REST API (tier 2) are unavailable,
6
+ * the SDK falls back to this bundled list to bootstrap market discovery.
7
+ *
8
+ * The addresses are fetched on-chain via `getMarketsByAddress`
9
+ * (`getMultipleAccounts`), so all data is still verified on-chain. The static
10
+ * list only provides the *address directory* — no cached market data is used.
11
+ *
12
+ * ## Maintenance
13
+ *
14
+ * Update this list when new markets are deployed or old ones are retired.
15
+ * Run `scripts/update-static-markets.ts` to regenerate from a permissive RPC
16
+ * or the REST API.
17
+ *
18
+ * @module
19
+ */
20
+ import type { Network } from "../config/program-ids.js";
21
+ /**
22
+ * A single entry in the static market registry.
23
+ *
24
+ * Only the slab address (base58) is required. Optional metadata fields
25
+ * (`symbol`, `name`) are provided for debugging/logging purposes only —
26
+ * they are **not** used for on-chain data and may become stale.
27
+ */
28
+ export interface StaticMarketEntry {
29
+ /** Base58-encoded slab account address. */
30
+ slabAddress: string;
31
+ /** Optional human-readable symbol (e.g. "SOL-PERP"). */
32
+ symbol?: string;
33
+ /** Optional descriptive name. */
34
+ name?: string;
35
+ }
36
+ /**
37
+ * Get the bundled static market list for a given network.
38
+ *
39
+ * Returns the built-in list merged with any entries added via
40
+ * {@link registerStaticMarkets}. Duplicates (by `slabAddress`) are removed
41
+ * automatically — user-registered entries take precedence.
42
+ *
43
+ * @param network - Target network (`"mainnet"` or `"devnet"`)
44
+ * @returns Array of static market entries (may be empty if no markets are known)
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * import { getStaticMarkets } from "@percolator/sdk";
49
+ *
50
+ * const markets = getStaticMarkets("mainnet");
51
+ * console.log(`${markets.length} known mainnet slab addresses`);
52
+ * ```
53
+ */
54
+ export declare function getStaticMarkets(network: Network): StaticMarketEntry[];
55
+ /**
56
+ * Register additional static market entries at runtime.
57
+ *
58
+ * Use this to inject known slab addresses before calling `discoverMarkets()`
59
+ * so that tier-3 fallback has addresses to work with — especially useful
60
+ * right after mainnet launch when the bundled list may be empty.
61
+ *
62
+ * Entries are deduplicated by `slabAddress` — calling this multiple times
63
+ * with the same address is safe.
64
+ *
65
+ * @param network - Target network
66
+ * @param entries - One or more static market entries to register
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * import { registerStaticMarkets } from "@percolator/sdk";
71
+ *
72
+ * registerStaticMarkets("mainnet", [
73
+ * { slabAddress: "ABC123...", symbol: "SOL-PERP" },
74
+ * { slabAddress: "DEF456...", symbol: "ETH-PERP" },
75
+ * ]);
76
+ * ```
77
+ */
78
+ export declare function registerStaticMarkets(network: Network, entries: StaticMarketEntry[]): void;
79
+ /**
80
+ * Clear all user-registered static market entries for a network.
81
+ *
82
+ * Useful in tests or when resetting state.
83
+ *
84
+ * @param network - Target network to clear (omit to clear all networks)
85
+ */
86
+ export declare function clearStaticMarkets(network?: Network): void;
@@ -9,14 +9,34 @@ export declare class ValidationError extends Error {
9
9
  }
10
10
  /**
11
11
  * Validate a public key string.
12
+ *
13
+ * @param value - Base58-encoded public key string.
14
+ * @param field - Field name for error messages.
15
+ * @returns Parsed `PublicKey` instance.
16
+ * @throws {@link ValidationError} if the string is not a valid base58 public key.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const key = validatePublicKey("11111111111111111111111111111111", "slab");
21
+ * ```
12
22
  */
13
23
  export declare function validatePublicKey(value: string, field: string): PublicKey;
14
24
  /**
15
25
  * Validate a non-negative integer index (u16 range for accounts).
26
+ *
27
+ * @param value - Decimal string representing the index.
28
+ * @param field - Field name for error messages.
29
+ * @returns Parsed integer in `[0, 65535]`.
30
+ * @throws {@link ValidationError} if the value is not a valid u16 integer.
16
31
  */
17
32
  export declare function validateIndex(value: string, field: string): number;
18
33
  /**
19
34
  * Validate a non-negative amount (u64 range).
35
+ *
36
+ * @param value - Decimal string representing the amount.
37
+ * @param field - Field name for error messages.
38
+ * @returns Parsed `bigint` in `[0, 2^64 - 1]`.
39
+ * @throws {@link ValidationError} if the value is negative or exceeds u64 max.
20
40
  */
21
41
  export declare function validateAmount(value: string, field: string): bigint;
22
42
  /**
@@ -32,7 +52,12 @@ export declare function validateI64(value: string, field: string): bigint;
32
52
  */
33
53
  export declare function validateI128(value: string, field: string): bigint;
34
54
  /**
35
- * Validate a basis points value (0-10000).
55
+ * Validate a basis points value (010000).
56
+ *
57
+ * @param value - Decimal string representing basis points.
58
+ * @param field - Field name for error messages.
59
+ * @returns Parsed integer in `[0, 10000]`.
60
+ * @throws {@link ValidationError} if the value exceeds 10000.
36
61
  */
37
62
  export declare function validateBps(value: string, field: string): number;
38
63
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percolatorct/sdk",
3
- "version": "0.5.1",
3
+ "version": "1.0.0-beta.2",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "engines": {
@@ -10,10 +10,10 @@
10
10
  "types": "./dist/index.d.ts",
11
11
  "exports": {
12
12
  ".": {
13
+ "types": "./dist/index.d.ts",
13
14
  "import": "./dist/index.js",
14
15
  "require": "./dist/index.js",
15
- "default": "./dist/index.js",
16
- "types": "./dist/index.d.ts"
16
+ "default": "./dist/index.js"
17
17
  }
18
18
  },
19
19
  "files": [
@@ -22,7 +22,8 @@
22
22
  "scripts": {
23
23
  "build": "tsup && tsc --emitDeclarationOnly --declaration --outDir dist",
24
24
  "test": "tsx test/abi.test.ts && tsx test/slab.test.ts && tsx test/validation.test.ts && tsx test/dex-oracle.test.ts && tsx test/trading.test.ts && tsx test/warmup-leverage-cap.test.ts && tsx test/dynamic-fees.test.ts && tsx test/oracle.test.ts && vitest run",
25
- "lint": "tsc --noEmit"
25
+ "lint": "tsc --noEmit",
26
+ "verify-layout": "tsx scripts/verify-layout.ts"
26
27
  },
27
28
  "dependencies": {
28
29
  "@solana/spl-token": "^0.4.14",