@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
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Connection, PublicKey } from "@solana/web3.js";
|
|
2
2
|
import { type SlabHeader, type MarketConfig, type EngineState, type RiskParams } from "./slab.js";
|
|
3
|
+
import { type StaticMarketEntry } from "./static-markets.js";
|
|
4
|
+
import { type Network } from "../config/program-ids.js";
|
|
3
5
|
/**
|
|
4
6
|
* A discovered Percolator market from on-chain program accounts.
|
|
5
7
|
*/
|
|
@@ -33,24 +35,34 @@ export interface DiscoveredMarket {
|
|
|
33
35
|
* History: Small was V0 (62_808) until 2026-03-13 program upgrade. V0 values preserved
|
|
34
36
|
* in SLAB_TIERS_V0 for discovery of legacy on-chain accounts.
|
|
35
37
|
*/
|
|
38
|
+
/**
|
|
39
|
+
* Default slab tiers for the current mainnet program (v12.1).
|
|
40
|
+
* These are used by useCreateMarket to allocate slab accounts of the correct size.
|
|
41
|
+
*/
|
|
36
42
|
export declare const SLAB_TIERS: {
|
|
43
|
+
readonly micro: {
|
|
44
|
+
maxAccounts: number;
|
|
45
|
+
dataSize: number;
|
|
46
|
+
label: string;
|
|
47
|
+
description: string;
|
|
48
|
+
};
|
|
37
49
|
readonly small: {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
maxAccounts: number;
|
|
51
|
+
dataSize: number;
|
|
52
|
+
label: string;
|
|
53
|
+
description: string;
|
|
42
54
|
};
|
|
43
55
|
readonly medium: {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
maxAccounts: number;
|
|
57
|
+
dataSize: number;
|
|
58
|
+
label: string;
|
|
59
|
+
description: string;
|
|
48
60
|
};
|
|
49
61
|
readonly large: {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
62
|
+
maxAccounts: number;
|
|
63
|
+
dataSize: number;
|
|
64
|
+
label: string;
|
|
65
|
+
description: string;
|
|
54
66
|
};
|
|
55
67
|
};
|
|
56
68
|
/** @deprecated V0 slab sizes — kept for backward compatibility with old on-chain slabs */
|
|
@@ -154,23 +166,29 @@ export declare const SLAB_TIERS_V1D_LEGACY: {
|
|
|
154
166
|
};
|
|
155
167
|
/** @deprecated Alias — use SLAB_TIERS (already V1) */
|
|
156
168
|
export declare const SLAB_TIERS_V1: {
|
|
169
|
+
readonly micro: {
|
|
170
|
+
maxAccounts: number;
|
|
171
|
+
dataSize: number;
|
|
172
|
+
label: string;
|
|
173
|
+
description: string;
|
|
174
|
+
};
|
|
157
175
|
readonly small: {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
176
|
+
maxAccounts: number;
|
|
177
|
+
dataSize: number;
|
|
178
|
+
label: string;
|
|
179
|
+
description: string;
|
|
162
180
|
};
|
|
163
181
|
readonly medium: {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
182
|
+
maxAccounts: number;
|
|
183
|
+
dataSize: number;
|
|
184
|
+
label: string;
|
|
185
|
+
description: string;
|
|
168
186
|
};
|
|
169
187
|
readonly large: {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
188
|
+
maxAccounts: number;
|
|
189
|
+
dataSize: number;
|
|
190
|
+
label: string;
|
|
191
|
+
description: string;
|
|
174
192
|
};
|
|
175
193
|
};
|
|
176
194
|
/**
|
|
@@ -253,6 +271,56 @@ export interface DiscoverMarketsOptions {
|
|
|
253
271
|
* Default: all known tiers.
|
|
254
272
|
*/
|
|
255
273
|
maxTierQueries?: number;
|
|
274
|
+
/**
|
|
275
|
+
* Base URL of the Percolator REST API (e.g. `"https://percolatorlaunch.com/api"`).
|
|
276
|
+
*
|
|
277
|
+
* When set, `discoverMarkets` will fall back to the REST API's `GET /markets`
|
|
278
|
+
* endpoint if `getProgramAccounts` fails or returns 0 results (common on public
|
|
279
|
+
* mainnet RPCs that reject `getProgramAccounts`).
|
|
280
|
+
*
|
|
281
|
+
* The API returns slab addresses which are then fetched on-chain via
|
|
282
|
+
* `getMarketsByAddress` (uses `getMultipleAccounts`, works on all RPCs).
|
|
283
|
+
*
|
|
284
|
+
* GH#59 / PERC-8424: Unblocks mainnet users without a Helius API key.
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```ts
|
|
288
|
+
* const markets = await discoverMarkets(connection, programId, {
|
|
289
|
+
* apiBaseUrl: "https://percolatorlaunch.com/api",
|
|
290
|
+
* });
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
apiBaseUrl?: string;
|
|
294
|
+
/**
|
|
295
|
+
* Timeout in ms for the API fallback HTTP request.
|
|
296
|
+
* Only used when `apiBaseUrl` is set.
|
|
297
|
+
* Default: 10_000 (10 seconds).
|
|
298
|
+
*/
|
|
299
|
+
apiTimeoutMs?: number;
|
|
300
|
+
/**
|
|
301
|
+
* Network hint for tier-3 static bundle fallback (`"mainnet"` or `"devnet"`).
|
|
302
|
+
*
|
|
303
|
+
* When both `getProgramAccounts` (tier 1) and the REST API (tier 2) fail,
|
|
304
|
+
* `discoverMarkets` will fall back to a bundled static list of known slab
|
|
305
|
+
* addresses for the specified network. The addresses are fetched on-chain
|
|
306
|
+
* via `getMarketsByAddress` (`getMultipleAccounts` — works on all RPCs).
|
|
307
|
+
*
|
|
308
|
+
* If not set, tier-3 fallback is disabled.
|
|
309
|
+
*
|
|
310
|
+
* The static list can be extended at runtime via `registerStaticMarkets()`.
|
|
311
|
+
*
|
|
312
|
+
* @see {@link registerStaticMarkets} to add addresses at runtime
|
|
313
|
+
* @see {@link getStaticMarkets} to inspect the current static list
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* ```ts
|
|
317
|
+
* const markets = await discoverMarkets(connection, programId, {
|
|
318
|
+
* apiBaseUrl: "https://percolatorlaunch.com/api",
|
|
319
|
+
* network: "mainnet", // enables tier-3 static fallback
|
|
320
|
+
* });
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
network?: Network;
|
|
256
324
|
}
|
|
257
325
|
/**
|
|
258
326
|
* Discover all Percolator markets owned by the given program.
|
|
@@ -261,3 +329,164 @@ export interface DiscoverMarketsOptions {
|
|
|
261
329
|
* @param options.sequential - Run tier queries sequentially with 429 retry (PERC-1650).
|
|
262
330
|
*/
|
|
263
331
|
export declare function discoverMarkets(connection: Connection, programId: PublicKey, options?: DiscoverMarketsOptions): Promise<DiscoveredMarket[]>;
|
|
332
|
+
/**
|
|
333
|
+
* Options for `getMarketsByAddress`.
|
|
334
|
+
*/
|
|
335
|
+
export interface GetMarketsByAddressOptions {
|
|
336
|
+
/**
|
|
337
|
+
* Maximum number of addresses per `getMultipleAccounts` RPC call.
|
|
338
|
+
* Solana limits a single call to 100 accounts; callers may lower this
|
|
339
|
+
* to reduce per-request payload size or avoid 429s.
|
|
340
|
+
*
|
|
341
|
+
* Default: 100 (Solana maximum).
|
|
342
|
+
*/
|
|
343
|
+
batchSize?: number;
|
|
344
|
+
/**
|
|
345
|
+
* Delay in ms between batches when the address list exceeds `batchSize`.
|
|
346
|
+
* Helps avoid rate-limiting on public RPCs.
|
|
347
|
+
*
|
|
348
|
+
* Default: 0 (no delay).
|
|
349
|
+
*/
|
|
350
|
+
interBatchDelayMs?: number;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Fetch and parse Percolator markets by their known slab addresses.
|
|
354
|
+
*
|
|
355
|
+
* Unlike `discoverMarkets()` — which uses `getProgramAccounts` and is blocked
|
|
356
|
+
* on public mainnet RPCs — this function uses `getMultipleAccounts`, which works
|
|
357
|
+
* on any RPC endpoint (including `api.mainnet-beta.solana.com`).
|
|
358
|
+
*
|
|
359
|
+
* Callers must already know the market slab addresses (e.g. from an indexer,
|
|
360
|
+
* a hardcoded registry, or a previous `discoverMarkets` call on a permissive RPC).
|
|
361
|
+
*
|
|
362
|
+
* @param connection - Solana RPC connection
|
|
363
|
+
* @param programId - The Percolator program that owns these slabs
|
|
364
|
+
* @param addresses - Array of slab account public keys to fetch
|
|
365
|
+
* @param options - Optional batching/delay configuration
|
|
366
|
+
* @returns Parsed markets for all valid slab accounts; invalid/missing accounts are silently skipped.
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```ts
|
|
370
|
+
* import { getMarketsByAddress, getProgramId } from "@percolator/sdk";
|
|
371
|
+
* import { Connection, PublicKey } from "@solana/web3.js";
|
|
372
|
+
*
|
|
373
|
+
* const connection = new Connection("https://api.mainnet-beta.solana.com");
|
|
374
|
+
* const programId = getProgramId("mainnet");
|
|
375
|
+
* const slabs = [
|
|
376
|
+
* new PublicKey("So11111111111111111111111111111111111111112"),
|
|
377
|
+
* // ... more known slab addresses
|
|
378
|
+
* ];
|
|
379
|
+
*
|
|
380
|
+
* const markets = await getMarketsByAddress(connection, programId, slabs);
|
|
381
|
+
* console.log(`Found ${markets.length} markets`);
|
|
382
|
+
* ```
|
|
383
|
+
*/
|
|
384
|
+
export declare function getMarketsByAddress(connection: Connection, programId: PublicKey, addresses: PublicKey[], options?: GetMarketsByAddressOptions): Promise<DiscoveredMarket[]>;
|
|
385
|
+
/**
|
|
386
|
+
* Shape of a single market entry returned by the Percolator REST API
|
|
387
|
+
* (`GET /markets`). Only the fields needed for discovery are typed here;
|
|
388
|
+
* the full API response may contain additional statistics fields.
|
|
389
|
+
*/
|
|
390
|
+
export interface ApiMarketEntry {
|
|
391
|
+
slab_address: string;
|
|
392
|
+
symbol?: string;
|
|
393
|
+
name?: string;
|
|
394
|
+
decimals?: number;
|
|
395
|
+
status?: string;
|
|
396
|
+
[key: string]: unknown;
|
|
397
|
+
}
|
|
398
|
+
/** Options for {@link discoverMarketsViaApi}. */
|
|
399
|
+
export interface DiscoverMarketsViaApiOptions {
|
|
400
|
+
/**
|
|
401
|
+
* Timeout in ms for the HTTP request to the REST API.
|
|
402
|
+
* Default: 10_000 (10 seconds).
|
|
403
|
+
*/
|
|
404
|
+
timeoutMs?: number;
|
|
405
|
+
/**
|
|
406
|
+
* Options forwarded to {@link getMarketsByAddress} for the on-chain fetch
|
|
407
|
+
* step (batch size, inter-batch delay).
|
|
408
|
+
*/
|
|
409
|
+
onChainOptions?: GetMarketsByAddressOptions;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Discover Percolator markets by first querying the REST API for slab addresses,
|
|
413
|
+
* then fetching full on-chain data via `getMarketsByAddress` (which uses
|
|
414
|
+
* `getMultipleAccounts` — works on all RPCs including public mainnet nodes).
|
|
415
|
+
*
|
|
416
|
+
* This is the recommended discovery path for mainnet users who do not have a
|
|
417
|
+
* Helius API key, since `getProgramAccounts` is rejected by public RPCs.
|
|
418
|
+
*
|
|
419
|
+
* The REST API acts as an address directory only — all market data is verified
|
|
420
|
+
* on-chain via `getMarketsByAddress`, so the caller gets the same
|
|
421
|
+
* `DiscoveredMarket[]` result as `discoverMarkets()`.
|
|
422
|
+
*
|
|
423
|
+
* @param connection - Solana RPC connection (any endpoint, including public)
|
|
424
|
+
* @param programId - The Percolator program that owns the slabs
|
|
425
|
+
* @param apiBaseUrl - Base URL of the Percolator REST API
|
|
426
|
+
* (e.g. `"https://percolatorlaunch.com/api"`)
|
|
427
|
+
* @param options - Optional timeout and on-chain fetch configuration
|
|
428
|
+
* @returns Parsed markets for all valid slab accounts discovered via the API
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* ```ts
|
|
432
|
+
* import { discoverMarketsViaApi, getProgramId } from "@percolator/sdk";
|
|
433
|
+
* import { Connection } from "@solana/web3.js";
|
|
434
|
+
*
|
|
435
|
+
* const connection = new Connection("https://api.mainnet-beta.solana.com");
|
|
436
|
+
* const programId = getProgramId("mainnet");
|
|
437
|
+
* const markets = await discoverMarketsViaApi(
|
|
438
|
+
* connection,
|
|
439
|
+
* programId,
|
|
440
|
+
* "https://percolatorlaunch.com/api",
|
|
441
|
+
* );
|
|
442
|
+
* console.log(`Discovered ${markets.length} markets via API fallback`);
|
|
443
|
+
* ```
|
|
444
|
+
*/
|
|
445
|
+
export declare function discoverMarketsViaApi(connection: Connection, programId: PublicKey, apiBaseUrl: string, options?: DiscoverMarketsViaApiOptions): Promise<DiscoveredMarket[]>;
|
|
446
|
+
/** Options for {@link discoverMarketsViaStaticBundle}. */
|
|
447
|
+
export interface DiscoverMarketsViaStaticBundleOptions {
|
|
448
|
+
/**
|
|
449
|
+
* Options forwarded to {@link getMarketsByAddress} for the on-chain fetch
|
|
450
|
+
* step (batch size, inter-batch delay).
|
|
451
|
+
*/
|
|
452
|
+
onChainOptions?: GetMarketsByAddressOptions;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Discover Percolator markets from a static list of known slab addresses.
|
|
456
|
+
*
|
|
457
|
+
* This is the tier-3 (last-resort) fallback for `discoverMarkets()`. It uses
|
|
458
|
+
* a bundled list of known slab addresses and fetches their full account data
|
|
459
|
+
* on-chain via `getMarketsByAddress` (`getMultipleAccounts` — works on all RPCs).
|
|
460
|
+
*
|
|
461
|
+
* The static list acts as an address directory only — all market data is verified
|
|
462
|
+
* on-chain, so stale entries are silently skipped (the account won't have valid
|
|
463
|
+
* magic bytes or will have been closed).
|
|
464
|
+
*
|
|
465
|
+
* @param connection - Solana RPC connection (any endpoint)
|
|
466
|
+
* @param programId - The Percolator program that owns the slabs
|
|
467
|
+
* @param entries - Static market entries (typically from {@link getStaticMarkets})
|
|
468
|
+
* @param options - Optional on-chain fetch configuration
|
|
469
|
+
* @returns Parsed markets for all valid slab accounts; stale/missing entries are skipped.
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* ```ts
|
|
473
|
+
* import {
|
|
474
|
+
* discoverMarketsViaStaticBundle,
|
|
475
|
+
* getStaticMarkets,
|
|
476
|
+
* getProgramId,
|
|
477
|
+
* } from "@percolator/sdk";
|
|
478
|
+
* import { Connection } from "@solana/web3.js";
|
|
479
|
+
*
|
|
480
|
+
* const connection = new Connection("https://api.mainnet-beta.solana.com");
|
|
481
|
+
* const programId = getProgramId("mainnet");
|
|
482
|
+
* const entries = getStaticMarkets("mainnet");
|
|
483
|
+
*
|
|
484
|
+
* const markets = await discoverMarketsViaStaticBundle(
|
|
485
|
+
* connection,
|
|
486
|
+
* programId,
|
|
487
|
+
* entries,
|
|
488
|
+
* );
|
|
489
|
+
* console.log(`Recovered ${markets.length} markets from static bundle`);
|
|
490
|
+
* ```
|
|
491
|
+
*/
|
|
492
|
+
export declare function discoverMarketsViaStaticBundle(connection: Connection, programId: PublicKey, entries: StaticMarketEntry[], options?: DiscoverMarketsViaStaticBundleOptions): Promise<DiscoveredMarket[]>;
|
package/dist/solana/index.d.ts
CHANGED
|
@@ -2,8 +2,10 @@ export * from "./slab.js";
|
|
|
2
2
|
export * from "./pda.js";
|
|
3
3
|
export * from "./ata.js";
|
|
4
4
|
export * from "./discovery.js";
|
|
5
|
+
export * from "./static-markets.js";
|
|
5
6
|
export * from "./dex-oracle.js";
|
|
6
7
|
export * from "./oracle.js";
|
|
7
8
|
export * from "./token-program.js";
|
|
8
9
|
export * from "./stake.js";
|
|
9
10
|
export * from "./adl.js";
|
|
11
|
+
export * from "./rpc-pool.js";
|
package/dist/solana/oracle.d.ts
CHANGED
|
@@ -16,11 +16,19 @@ declare const CHAINLINK_MIN_SIZE = 224;
|
|
|
16
16
|
declare const MAX_DECIMALS = 18;
|
|
17
17
|
/** Offset of decimals field in Chainlink aggregator account */
|
|
18
18
|
declare const CHAINLINK_DECIMALS_OFFSET = 138;
|
|
19
|
+
/** Offset of updated_at timestamp (i64 LE, Unix seconds) in Chainlink aggregator */
|
|
20
|
+
declare const CHAINLINK_TIMESTAMP_OFFSET = 168;
|
|
19
21
|
/** Offset of latest answer in Chainlink aggregator account */
|
|
20
22
|
declare const CHAINLINK_ANSWER_OFFSET = 216;
|
|
21
23
|
export interface OraclePrice {
|
|
22
24
|
price: bigint;
|
|
23
25
|
decimals: number;
|
|
26
|
+
/** Unix timestamp (seconds) of the last oracle update, if available. */
|
|
27
|
+
updatedAt?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface ParseChainlinkOptions {
|
|
30
|
+
/** Maximum allowed staleness in seconds. If the oracle update is older, an error is thrown. */
|
|
31
|
+
maxStalenessSeconds?: number;
|
|
24
32
|
}
|
|
25
33
|
/**
|
|
26
34
|
* Parse price data from a Chainlink aggregator account buffer.
|
|
@@ -34,11 +42,11 @@ export interface OraclePrice {
|
|
|
34
42
|
* @returns Parsed oracle price with decimals
|
|
35
43
|
* @throws if the buffer is invalid or contains unreasonable data
|
|
36
44
|
*/
|
|
37
|
-
export declare function parseChainlinkPrice(data: Uint8Array): OraclePrice;
|
|
45
|
+
export declare function parseChainlinkPrice(data: Uint8Array, options?: ParseChainlinkOptions): OraclePrice;
|
|
38
46
|
/**
|
|
39
47
|
* Validate that a buffer looks like a valid Chainlink aggregator account.
|
|
40
48
|
* Returns true if the buffer passes all validation checks, false otherwise.
|
|
41
49
|
* Use this for non-throwing validation.
|
|
42
50
|
*/
|
|
43
51
|
export declare function isValidChainlinkOracle(data: Uint8Array): boolean;
|
|
44
|
-
export { CHAINLINK_MIN_SIZE, CHAINLINK_DECIMALS_OFFSET, CHAINLINK_ANSWER_OFFSET, MAX_DECIMALS };
|
|
52
|
+
export { CHAINLINK_MIN_SIZE, CHAINLINK_DECIMALS_OFFSET, CHAINLINK_TIMESTAMP_OFFSET, CHAINLINK_ANSWER_OFFSET, MAX_DECIMALS };
|