@parqxchange/sdk 0.1.0

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.
Files changed (65) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +122 -0
  3. package/dist/accounts/marketOracle.d.ts +21 -0
  4. package/dist/accounts/marketOracle.js +114 -0
  5. package/dist/accounts/resolve.d.ts +75 -0
  6. package/dist/accounts/resolve.js +116 -0
  7. package/dist/actions/cranks.d.ts +8 -0
  8. package/dist/actions/cranks.js +10 -0
  9. package/dist/actions/liquidity.d.ts +23 -0
  10. package/dist/actions/liquidity.js +21 -0
  11. package/dist/actions/trading.d.ts +39 -0
  12. package/dist/actions/trading.js +95 -0
  13. package/dist/auth/tradingKey.d.ts +27 -0
  14. package/dist/auth/tradingKey.js +71 -0
  15. package/dist/decode/index.d.ts +39 -0
  16. package/dist/decode/index.js +445 -0
  17. package/dist/events/decoder.d.ts +60 -0
  18. package/dist/events/decoder.js +369 -0
  19. package/dist/events/emitter.d.ts +49 -0
  20. package/dist/events/emitter.js +153 -0
  21. package/dist/index.d.ts +25 -0
  22. package/dist/index.js +93 -0
  23. package/dist/indexer/client.d.ts +13 -0
  24. package/dist/indexer/client.js +36 -0
  25. package/dist/indexer/types.d.ts +9 -0
  26. package/dist/indexer/types.js +2 -0
  27. package/dist/minimal.d.ts +3 -0
  28. package/dist/minimal.js +13 -0
  29. package/dist/node.d.ts +1 -0
  30. package/dist/node.js +5 -0
  31. package/dist/programs/feeDistributor.d.ts +42 -0
  32. package/dist/programs/feeDistributor.js +42 -0
  33. package/dist/programs/oracle.d.ts +31 -0
  34. package/dist/programs/oracle.js +49 -0
  35. package/dist/programs/perp.d.ts +283 -0
  36. package/dist/programs/perp.js +346 -0
  37. package/dist/programs/pool.d.ts +113 -0
  38. package/dist/programs/pool.js +126 -0
  39. package/dist/programs/priceFeed.d.ts +13 -0
  40. package/dist/programs/priceFeed.js +21 -0
  41. package/dist/programs/staking.d.ts +76 -0
  42. package/dist/programs/staking.js +135 -0
  43. package/dist/types/index.d.ts +337 -0
  44. package/dist/types/index.js +9 -0
  45. package/dist/utils/computeBudget.d.ts +5 -0
  46. package/dist/utils/computeBudget.js +14 -0
  47. package/dist/utils/errors.d.ts +56 -0
  48. package/dist/utils/errors.js +138 -0
  49. package/dist/utils/pda.d.ts +28 -0
  50. package/dist/utils/pda.js +131 -0
  51. package/dist/utils/priceMath.d.ts +5 -0
  52. package/dist/utils/priceMath.js +46 -0
  53. package/dist/utils/tokenProgram.d.ts +2 -0
  54. package/dist/utils/tokenProgram.js +16 -0
  55. package/dist/utils/transaction.d.ts +2 -0
  56. package/dist/utils/transaction.js +12 -0
  57. package/dist/utils/version.d.ts +11 -0
  58. package/dist/utils/version.js +29 -0
  59. package/idl/fee_distributor.json +779 -0
  60. package/idl/oracle_adapter.json +767 -0
  61. package/idl/perp_engine.json +3908 -0
  62. package/idl/pool_program.json +2956 -0
  63. package/idl/price_feed.json +478 -0
  64. package/idl/staking.json +1336 -0
  65. package/package.json +98 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Parquet contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # Parquet SDK
2
+
3
+ TypeScript client for the [Parquet](https://parquet.exchange) perpetuals protocol on Solana — Anchor program clients, account decoders, PDA helpers, dual-feed oracle resolution, and a typed indexer client.
4
+
5
+ Instruction builders return `TransactionInstruction[]` only. **You build, sign, and send** — the SDK never holds keys or sends transactions for you.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @parqxchange/sdk
11
+ # or: yarn add @parqxchange/sdk / pnpm add @parqxchange/sdk
12
+ ```
13
+
14
+ Peer-pinned against `@solana/web3.js` and `@coral-xyz/anchor` — pin both in your lockfile. Node `>=18` (uses `node:crypto` for discriminators and `AbortSignal.timeout` in the indexer client).
15
+
16
+ ## Getting Started
17
+
18
+ ```typescript
19
+ import { Connection, PublicKey } from "@solana/web3.js";
20
+ import {
21
+ PROGRAM_IDS_V4,
22
+ IndexerClient,
23
+ getMarketOracleFeeds,
24
+ openPosition,
25
+ PerpClient,
26
+ } from "@parqxchange/sdk";
27
+
28
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
29
+
30
+ // 1. Read market stats from the indexer.
31
+ const indexer = new IndexerClient("https://api.parquet.exchange");
32
+ const stats = await indexer.getStats("aapl-usdc");
33
+ console.log(stats.markPrice, stats.openInterest);
34
+
35
+ // 2. Resolve the dual-feed oracle accounts for a market.
36
+ const oracleProgramId = new PublicKey(PROGRAM_IDS_V4.ORACLE_ADAPTER);
37
+ const marketId = new TextEncoder().encode("aapl-usdc"); // market id = ascii symbol
38
+ const { primaryFeed, secondaryFeed } = await getMarketOracleFeeds(
39
+ connection,
40
+ marketId,
41
+ oracleProgramId,
42
+ );
43
+
44
+ // 3. Build an openPosition instruction (you sign + send it).
45
+ const perpClient = new PerpClient(program); // your Anchor Program for the perp-engine
46
+ const ixs = await openPosition(
47
+ {
48
+ perpClient,
49
+ perpEngineId: new PublicKey(PROGRAM_IDS_V4.PERP_ENGINE),
50
+ poolProgramId: new PublicKey(PROGRAM_IDS_V4.POOL_PROGRAM),
51
+ oracleProgramId,
52
+ marketId,
53
+ primaryFeedAccount: primaryFeed,
54
+ secondaryFeedAccount: secondaryFeed,
55
+ },
56
+ { signer: wallet.publicKey, signerUsdc: usdcAta },
57
+ {
58
+ side: { long: {} },
59
+ sizeUsdc: 1_000_000_000n, // 1,000 USDC notional (6 decimals)
60
+ walletCollateral: 100_000_000n, // 100 USDC margin
61
+ fromQueueAmount: 0n,
62
+ acceptablePrice: 0n, // ⚠️ 0 = no slippage guard — set a real limit in prod
63
+ minOutputUsdc: 0n,
64
+ positionNonce: 0n,
65
+ referralCode: Array(32).fill(0),
66
+ },
67
+ );
68
+ // → add ixs to a transaction, sign with `wallet`, and send.
69
+ ```
70
+
71
+ ## Entry points
72
+
73
+ | Import | Use |
74
+ |--------|-----|
75
+ | `@parqxchange/sdk` | Full surface — program clients, decoders, events, indexer, PDA + oracle helpers. |
76
+ | `@parqxchange/sdk/minimal` | Perp trading actions + `getMarketOracleFeeds` only (smaller dependency graph). |
77
+ | `@parqxchange/sdk/node` | `loadTradingKeypair` and other Node/`fs` helpers. **Never import from browser bundles.** |
78
+
79
+ ## API surface
80
+
81
+ - **Program clients** — `PerpClient`, `PoolClient`, `OracleClient`, `PriceFeedClient`, `FeeDistributorClient`, `StakingClient`
82
+ - **Actions** (build instructions) — `openPosition`, `closePosition`, `updateMargin`, `addLiquidity`, `removeLiquidity`, `crankFundingRate`
83
+ - **Account resolvers** — `resolveOpenPositionAccounts`, `resolveClosePositionAccounts`, `resolveUpdateMarginAccounts`, `resolveLiquidityAccounts`
84
+ - **Oracle** — `getMarketOracleFeeds`, `clearMarketOracleFeedsCache`
85
+ - **Decoders** — `decodePosition`, `decodeMarketState`, `decodePoolState`, `decodeOrder`, … and `identifyAccountType`
86
+ - **Events** — `ParquetEventEmitter`, `decodeAnchorEvent`
87
+ - **Indexer** — `IndexerClient` (`getStats`)
88
+ - **Auth** — `registerTradingKey` / `revokeTradingKey` (+ `buildRegisterTradingKeyIx` / `buildRevokeTradingKeyIx`)
89
+ - **Constants / utils** — `PROGRAM_IDS_V4`, `withComputeBudget`, `buildVersionedTransaction`, PDA helpers
90
+
91
+ ## Decoding on-chain errors
92
+
93
+ ```typescript
94
+ import { decodeError, isParquetError, ParquetError } from "@parqxchange/sdk";
95
+
96
+ try {
97
+ await program.methods.openPosition(/* … */).rpc();
98
+ } catch (err) {
99
+ // Pass the caught error OBJECT (Anchor error or RPC "custom program error: 0x…").
100
+ if (isParquetError(err, ParquetError.BelowMinCollateral)) {
101
+ // handle insufficient collateral
102
+ }
103
+ console.log(decodeError(err)); // → ParquetError code, or null
104
+ }
105
+ ```
106
+
107
+ `decodeError` takes the caught error object, never a raw number.
108
+
109
+ ## Production notes
110
+
111
+ - **Set slippage guards.** `acceptablePrice` / `minOutputUsdc` of `0n` disable protection.
112
+ - **Always pass both oracle feeds** from `getMarketOracleFeeds` (or a resolver) on open/close — never hardcode feed PDAs.
113
+ - **Keep `loadTradingKeypair` server-side** (`/node` entry) so bundlers don't pull `fs` into the browser.
114
+ - `decodeAnchorEvent` returns `null` for unknown/malformed/truncated payloads — validate at app boundaries.
115
+
116
+ ## Documentation
117
+
118
+ Full reference, market ids, and the complete production checklist: **[docs.parquet.exchange/developer/sdk](https://docs.parquet.exchange/developer/sdk)**
119
+
120
+ ## License
121
+
122
+ MIT
@@ -0,0 +1,21 @@
1
+ import { Connection, PublicKey } from "@solana/web3.js";
2
+ export declare const MARKET_ORACLE_V2_LEN = 158;
3
+ export type OracleType = "switchboard" | "pyth";
4
+ export interface MarketOracleFeeds {
5
+ primaryFeed: PublicKey;
6
+ secondaryFeed: PublicKey;
7
+ primaryOracleType: OracleType;
8
+ secondaryOracleType: OracleType;
9
+ primaryMaxStalenessSecs: number;
10
+ secondaryMaxStalenessSecs: number;
11
+ maxConfidencePctBps: number;
12
+ }
13
+ export declare function clearMarketOracleFeedsCache(): void;
14
+ export declare function getMarketOracleFeeds(connection: Connection, marketId: Uint8Array, oracleProgramId: PublicKey): Promise<MarketOracleFeeds>;
15
+ export interface DecodedFeedPrice {
16
+ price: bigint;
17
+ confidence: bigint;
18
+ timestamp: number;
19
+ }
20
+ export declare function decodePythPriceUpdate(data: Buffer | Uint8Array): DecodedFeedPrice;
21
+ export declare function decodeSwitchboardPriceFeed(data: Buffer | Uint8Array): DecodedFeedPrice;
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MARKET_ORACLE_V2_LEN = void 0;
4
+ exports.clearMarketOracleFeedsCache = clearMarketOracleFeedsCache;
5
+ exports.getMarketOracleFeeds = getMarketOracleFeeds;
6
+ exports.decodePythPriceUpdate = decodePythPriceUpdate;
7
+ exports.decodeSwitchboardPriceFeed = decodeSwitchboardPriceFeed;
8
+ const web3_js_1 = require("@solana/web3.js");
9
+ const pda_1 = require("../utils/pda");
10
+ const PRIMARY_FEED_OFFSET = 8 + 32 + 32 + 1 + 1;
11
+ const SECONDARY_FEED_OFFSET = PRIMARY_FEED_OFFSET + 32 + 8 + 1;
12
+ exports.MARKET_ORACLE_V2_LEN = 158;
13
+ const PRIMARY_ORACLE_TYPE_OFFSET = 8 + 32 + 32 + 1;
14
+ const PRIMARY_STALENESS_OFFSET = PRIMARY_ORACLE_TYPE_OFFSET + 1 + 32;
15
+ const SECONDARY_ORACLE_TYPE_OFFSET = PRIMARY_STALENESS_OFFSET + 8;
16
+ const SECONDARY_STALENESS_OFFSET = SECONDARY_ORACLE_TYPE_OFFSET + 1 + 32;
17
+ const MAX_CONF_PCT_OFFSET = SECONDARY_STALENESS_OFFSET + 8;
18
+ function oracleTypeAt(buf, offset) {
19
+ const v = buf.readUInt8(offset);
20
+ if (v === 0)
21
+ return "pyth";
22
+ if (v === 1)
23
+ return "switchboard";
24
+ throw new Error(`MarketOracle unknown oracle_type byte: ${v}`);
25
+ }
26
+ const cache = new Map();
27
+ function clearMarketOracleFeedsCache() {
28
+ cache.clear();
29
+ }
30
+ async function getMarketOracleFeeds(connection, marketId, oracleProgramId) {
31
+ const [marketOracle] = (0, pda_1.marketOraclePDA)(marketId, oracleProgramId);
32
+ const cacheKey = `${connection.rpcEndpoint}::${marketOracle.toBase58()}`;
33
+ const cached = cache.get(cacheKey);
34
+ if (cached)
35
+ return cached;
36
+ const info = await connection.getAccountInfo(marketOracle);
37
+ if (!info) {
38
+ throw new Error(`MarketOracle PDA not found: ${marketOracle.toBase58()}`);
39
+ }
40
+ if (info.data.length < exports.MARKET_ORACLE_V2_LEN) {
41
+ throw new Error(`MarketOracle ${marketOracle.toBase58()} data too short for V2 layout ` +
42
+ `(${info.data.length} < ${exports.MARKET_ORACLE_V2_LEN} bytes); ` +
43
+ "run migrate_market_oracle_v2 before dual-feed reads.");
44
+ }
45
+ const buf = Buffer.isBuffer(info.data) ? info.data : Buffer.from(info.data);
46
+ const feeds = {
47
+ primaryFeed: new web3_js_1.PublicKey(buf.subarray(PRIMARY_FEED_OFFSET, PRIMARY_FEED_OFFSET + 32)),
48
+ secondaryFeed: new web3_js_1.PublicKey(buf.subarray(SECONDARY_FEED_OFFSET, SECONDARY_FEED_OFFSET + 32)),
49
+ primaryOracleType: oracleTypeAt(buf, PRIMARY_ORACLE_TYPE_OFFSET),
50
+ secondaryOracleType: oracleTypeAt(buf, SECONDARY_ORACLE_TYPE_OFFSET),
51
+ primaryMaxStalenessSecs: Number(buf.readBigUInt64LE(PRIMARY_STALENESS_OFFSET)),
52
+ secondaryMaxStalenessSecs: Number(buf.readBigUInt64LE(SECONDARY_STALENESS_OFFSET)),
53
+ maxConfidencePctBps: buf.readUInt16LE(MAX_CONF_PCT_OFFSET),
54
+ };
55
+ cache.set(cacheKey, feeds);
56
+ return feeds;
57
+ }
58
+ function decodePythPriceUpdate(data) {
59
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
60
+ if (buf.length < 101) {
61
+ throw new Error(`Pyth PriceUpdateV2 too short: ${buf.length} < 101`);
62
+ }
63
+ const rawPrice = buf.readBigInt64LE(73);
64
+ const rawConf = buf.readBigUInt64LE(81);
65
+ const exponent = buf.readInt32LE(89);
66
+ const timestamp = Number(buf.readBigInt64LE(93));
67
+ if (exponent < -12 || exponent > 0) {
68
+ throw new Error(`Pyth exponent out of range: ${exponent}`);
69
+ }
70
+ if (rawPrice <= 0n) {
71
+ throw new Error(`Pyth raw_price not positive: ${rawPrice}`);
72
+ }
73
+ const diff = exponent - -9;
74
+ const price = applyExponent(rawPrice, diff);
75
+ const confidence = applyExponent(rawConf, diff);
76
+ return { price, confidence, timestamp };
77
+ }
78
+ function decodeSwitchboardPriceFeed(data) {
79
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
80
+ if (buf.length < 4365) {
81
+ throw new Error(`PriceFeed PDA too short: ${buf.length} < 4365`);
82
+ }
83
+ const low = buf.readBigUInt64LE(4337);
84
+ const high = buf.readBigInt64LE(4345);
85
+ const mantissa = (high << 64n) | low;
86
+ if (mantissa <= 0n) {
87
+ throw new Error(`PriceFeed mantissa not positive: ${mantissa}`);
88
+ }
89
+ const scale = buf.readUInt32LE(4353);
90
+ const timestamp = Number(buf.readBigInt64LE(4357));
91
+ const absMantissa = mantissa < 0n ? -mantissa : mantissa;
92
+ let price1e9;
93
+ if (scale >= 9) {
94
+ price1e9 = absMantissa / 10n ** BigInt(scale - 9);
95
+ }
96
+ else {
97
+ price1e9 = absMantissa * 10n ** BigInt(9 - scale);
98
+ }
99
+ if (price1e9 > U64_MAX) {
100
+ throw new Error(`PriceFeed price exceeds u64 range: ${price1e9}`);
101
+ }
102
+ return { price: price1e9, confidence: 0n, timestamp };
103
+ }
104
+ const U64_MAX = (1n << 64n) - 1n;
105
+ function applyExponent(value, diff) {
106
+ if (diff >= 0) {
107
+ const result = value * 10n ** BigInt(diff);
108
+ if (result > U64_MAX) {
109
+ throw new Error(`Pyth apply_exponent overflow: ${result} > u64::MAX`);
110
+ }
111
+ return result;
112
+ }
113
+ return value / 10n ** BigInt(-diff);
114
+ }
@@ -0,0 +1,75 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ export interface ProgramIds {
3
+ perpEngineId: PublicKey;
4
+ poolProgramId: PublicKey;
5
+ oracleProgramId: PublicKey;
6
+ priceFeedProgramId: PublicKey;
7
+ }
8
+ export declare function resolveOpenPositionAccounts(marketId: Uint8Array, signer: PublicKey, nonce: bigint, usdcMint: PublicKey, primaryFeedAccount: PublicKey, secondaryFeedAccount: PublicKey, programs: ProgramIds, tradingKeyPda?: PublicKey | null, referralConfig?: PublicKey, referralCodeAccount?: PublicKey, traderReferral?: PublicKey): {
9
+ accounts: {
10
+ marketState: PublicKey;
11
+ position: PublicKey;
12
+ engineAuth: PublicKey;
13
+ marketOracle: PublicKey;
14
+ poolState: PublicKey;
15
+ vaultUsdc: PublicKey;
16
+ signerUsdc: PublicKey;
17
+ feeSettings: PublicKey;
18
+ tradingKey: PublicKey | null;
19
+ referralConfig: PublicKey;
20
+ referralCodeAccount: PublicKey;
21
+ traderReferral: PublicKey;
22
+ poolProgram: PublicKey;
23
+ oracleProgram: PublicKey;
24
+ };
25
+ primaryFeedAccount: PublicKey;
26
+ secondaryFeedAccount: PublicKey;
27
+ };
28
+ export declare function resolveClosePositionAccounts(marketId: Uint8Array, owner: PublicKey, signer: PublicKey, position: PublicKey, usdcMint: PublicKey, primaryFeedAccount: PublicKey, secondaryFeedAccount: PublicKey, programs: ProgramIds, tradingKeyPda?: PublicKey | null, referralConfig?: PublicKey, referralCodeAccount?: PublicKey, traderReferral?: PublicKey): {
29
+ accounts: {
30
+ marketState: PublicKey;
31
+ position: PublicKey;
32
+ engineAuth: PublicKey;
33
+ marketOracle: PublicKey;
34
+ poolState: PublicKey;
35
+ vaultUsdc: PublicKey;
36
+ vaultAuthority: PublicKey;
37
+ userUsdc: PublicKey;
38
+ owner: PublicKey;
39
+ signer: PublicKey;
40
+ tradingKey: PublicKey | null;
41
+ referralConfig: PublicKey;
42
+ referralCodeAccount: PublicKey;
43
+ traderReferral: PublicKey;
44
+ poolProgram: PublicKey;
45
+ oracleProgram: PublicKey;
46
+ lpMint: PublicKey;
47
+ insuranceFund: PublicKey;
48
+ insuranceVault: PublicKey;
49
+ };
50
+ primaryFeedAccount: PublicKey;
51
+ secondaryFeedAccount: PublicKey;
52
+ };
53
+ export declare function resolveUpdateMarginAccounts(marketId: Uint8Array, owner: PublicKey, signer: PublicKey, position: PublicKey, usdcMint: PublicKey, programs: ProgramIds, tradingKeyPda?: PublicKey | null): {
54
+ accounts: {
55
+ marketState: PublicKey;
56
+ position: PublicKey;
57
+ engineAuth: PublicKey;
58
+ poolState: PublicKey;
59
+ vaultUsdc: PublicKey;
60
+ vaultAuthority: PublicKey;
61
+ signerUsdc: PublicKey;
62
+ owner: PublicKey;
63
+ signer: PublicKey;
64
+ tradingKey: PublicKey | null;
65
+ poolProgram: PublicKey;
66
+ };
67
+ };
68
+ export declare function resolveLiquidityAccounts(marketId: Uint8Array, user: PublicKey, usdcMint: PublicKey, programs: ProgramIds): {
69
+ poolState: PublicKey;
70
+ usdcVault: PublicKey;
71
+ vaultAuthority: PublicKey;
72
+ lpMint: PublicKey;
73
+ userLp: PublicKey;
74
+ userUsdc: PublicKey;
75
+ };
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveOpenPositionAccounts = resolveOpenPositionAccounts;
4
+ exports.resolveClosePositionAccounts = resolveClosePositionAccounts;
5
+ exports.resolveUpdateMarginAccounts = resolveUpdateMarginAccounts;
6
+ exports.resolveLiquidityAccounts = resolveLiquidityAccounts;
7
+ const web3_js_1 = require("@solana/web3.js");
8
+ const spl_token_1 = require("@solana/spl-token");
9
+ const pda_1 = require("../utils/pda");
10
+ const SYSTEM_PROGRAM = new web3_js_1.PublicKey("11111111111111111111111111111111");
11
+ function resolveOpenPositionAccounts(marketId, signer, nonce, usdcMint, primaryFeedAccount, secondaryFeedAccount, programs, tradingKeyPda, referralConfig, referralCodeAccount, traderReferral) {
12
+ const [marketState] = (0, pda_1.marketStatePDA)(marketId, programs.perpEngineId);
13
+ const [position] = (0, pda_1.positionPDA)(signer, marketId, nonce, programs.perpEngineId);
14
+ const [engineAuth] = (0, pda_1.engineAuthPDA)(marketId, programs.perpEngineId);
15
+ const [marketOracle] = (0, pda_1.marketOraclePDA)(marketId, programs.oracleProgramId);
16
+ const [poolState] = (0, pda_1.poolStatePDA)(marketId, programs.poolProgramId);
17
+ const [vaultUsdc] = (0, pda_1.usdcVaultPDA)(marketId, programs.poolProgramId);
18
+ const signerUsdc = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, signer);
19
+ const [feeSettings] = (0, pda_1.feeSettingsPDA)(marketId, programs.poolProgramId);
20
+ return {
21
+ accounts: {
22
+ marketState,
23
+ position,
24
+ engineAuth,
25
+ marketOracle,
26
+ poolState,
27
+ vaultUsdc,
28
+ signerUsdc,
29
+ feeSettings,
30
+ tradingKey: tradingKeyPda ?? null,
31
+ referralConfig: referralConfig ?? SYSTEM_PROGRAM,
32
+ referralCodeAccount: referralCodeAccount ?? SYSTEM_PROGRAM,
33
+ traderReferral: traderReferral ?? SYSTEM_PROGRAM,
34
+ poolProgram: programs.poolProgramId,
35
+ oracleProgram: programs.oracleProgramId,
36
+ },
37
+ primaryFeedAccount,
38
+ secondaryFeedAccount,
39
+ };
40
+ }
41
+ function resolveClosePositionAccounts(marketId, owner, signer, position, usdcMint, primaryFeedAccount, secondaryFeedAccount, programs, tradingKeyPda, referralConfig, referralCodeAccount, traderReferral) {
42
+ const [marketState] = (0, pda_1.marketStatePDA)(marketId, programs.perpEngineId);
43
+ const [engineAuth] = (0, pda_1.engineAuthPDA)(marketId, programs.perpEngineId);
44
+ const [marketOracle] = (0, pda_1.marketOraclePDA)(marketId, programs.oracleProgramId);
45
+ const [poolState] = (0, pda_1.poolStatePDA)(marketId, programs.poolProgramId);
46
+ const [vaultUsdc] = (0, pda_1.usdcVaultPDA)(marketId, programs.poolProgramId);
47
+ const [vaultAuthority] = (0, pda_1.vaultAuthorityPDA)(marketId, programs.poolProgramId);
48
+ const [lpMint] = (0, pda_1.lpMintPDA)(marketId, programs.poolProgramId);
49
+ const [insuranceFund] = (0, pda_1.insuranceFundPda)(programs.poolProgramId);
50
+ const [insuranceVault] = (0, pda_1.insuranceVaultPda)(programs.poolProgramId);
51
+ const userUsdc = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, owner);
52
+ return {
53
+ accounts: {
54
+ marketState,
55
+ position,
56
+ engineAuth,
57
+ marketOracle,
58
+ poolState,
59
+ vaultUsdc,
60
+ vaultAuthority,
61
+ userUsdc,
62
+ owner,
63
+ signer,
64
+ tradingKey: tradingKeyPda ?? null,
65
+ referralConfig: referralConfig ?? SYSTEM_PROGRAM,
66
+ referralCodeAccount: referralCodeAccount ?? SYSTEM_PROGRAM,
67
+ traderReferral: traderReferral ?? SYSTEM_PROGRAM,
68
+ poolProgram: programs.poolProgramId,
69
+ oracleProgram: programs.oracleProgramId,
70
+ lpMint,
71
+ insuranceFund,
72
+ insuranceVault,
73
+ },
74
+ primaryFeedAccount,
75
+ secondaryFeedAccount,
76
+ };
77
+ }
78
+ function resolveUpdateMarginAccounts(marketId, owner, signer, position, usdcMint, programs, tradingKeyPda) {
79
+ const [marketState] = (0, pda_1.marketStatePDA)(marketId, programs.perpEngineId);
80
+ const [vaultUsdc] = (0, pda_1.usdcVaultPDA)(marketId, programs.poolProgramId);
81
+ const [engineAuth] = (0, pda_1.engineAuthPDA)(marketId, programs.perpEngineId);
82
+ const [poolState] = (0, pda_1.poolStatePDA)(marketId, programs.poolProgramId);
83
+ const [vaultAuthority] = (0, pda_1.vaultAuthorityPDA)(marketId, programs.poolProgramId);
84
+ const signerUsdc = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, signer);
85
+ return {
86
+ accounts: {
87
+ marketState,
88
+ position,
89
+ engineAuth,
90
+ poolState,
91
+ vaultUsdc,
92
+ vaultAuthority,
93
+ signerUsdc,
94
+ owner,
95
+ signer,
96
+ tradingKey: tradingKeyPda ?? null,
97
+ poolProgram: programs.poolProgramId,
98
+ },
99
+ };
100
+ }
101
+ function resolveLiquidityAccounts(marketId, user, usdcMint, programs) {
102
+ const [poolState] = (0, pda_1.poolStatePDA)(marketId, programs.poolProgramId);
103
+ const [vaultAuthority] = (0, pda_1.vaultAuthorityPDA)(marketId, programs.poolProgramId);
104
+ const [lpMint] = (0, pda_1.lpMintPDA)(marketId, programs.poolProgramId);
105
+ const [usdcVault] = (0, pda_1.usdcVaultPDA)(marketId, programs.poolProgramId);
106
+ const userUsdc = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, user);
107
+ const userLp = (0, spl_token_1.getAssociatedTokenAddressSync)(lpMint, user);
108
+ return {
109
+ poolState,
110
+ usdcVault,
111
+ vaultAuthority,
112
+ lpMint,
113
+ userLp,
114
+ userUsdc,
115
+ };
116
+ }
@@ -0,0 +1,8 @@
1
+ import { PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ import { PerpClient } from "../programs/perp";
3
+ export declare function crankFundingRate(opts: {
4
+ perpClient: PerpClient;
5
+ perpEngineId: PublicKey;
6
+ poolProgramId: PublicKey;
7
+ marketId: Uint8Array;
8
+ }): Promise<TransactionInstruction[]>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.crankFundingRate = crankFundingRate;
4
+ const pda_1 = require("../utils/pda");
5
+ async function crankFundingRate(opts) {
6
+ const [marketState] = (0, pda_1.marketStatePDA)(opts.marketId, opts.perpEngineId);
7
+ const [poolState] = (0, pda_1.poolStatePDA)(opts.marketId, opts.poolProgramId);
8
+ const ix = await opts.perpClient.updateFundingRateIx({ marketState, poolState });
9
+ return [ix];
10
+ }
@@ -0,0 +1,23 @@
1
+ import { PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ import { PoolClient } from "../programs/pool";
3
+ export interface LiquidityOpts {
4
+ poolClient: PoolClient;
5
+ poolProgramId: PublicKey;
6
+ marketId: Uint8Array;
7
+ }
8
+ export declare function addLiquidity(opts: LiquidityOpts, accounts: {
9
+ depositor: PublicKey;
10
+ userUsdc: PublicKey;
11
+ userLp: PublicKey;
12
+ }, args: {
13
+ amountUsdc: bigint;
14
+ minLpOut: bigint;
15
+ }): Promise<TransactionInstruction[]>;
16
+ export declare function removeLiquidity(opts: LiquidityOpts, accounts: {
17
+ withdrawer: PublicKey;
18
+ userUsdc: PublicKey;
19
+ userLp: PublicKey;
20
+ }, args: {
21
+ lpAmount: bigint;
22
+ minOut: bigint;
23
+ }): Promise<TransactionInstruction[]>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addLiquidity = addLiquidity;
4
+ exports.removeLiquidity = removeLiquidity;
5
+ const pda_1 = require("../utils/pda");
6
+ async function addLiquidity(opts, accounts, args) {
7
+ const [poolState] = (0, pda_1.poolStatePDA)(opts.marketId, opts.poolProgramId);
8
+ const [vaultAuthority] = (0, pda_1.vaultAuthorityPDA)(opts.marketId, opts.poolProgramId);
9
+ const [lpMint] = (0, pda_1.lpMintPDA)(opts.marketId, opts.poolProgramId);
10
+ const [usdcVault] = (0, pda_1.usdcVaultPDA)(opts.marketId, opts.poolProgramId);
11
+ const ix = await opts.poolClient.depositIx({ poolState, usdcVault, vaultAuthority, lpMint, userLp: accounts.userLp, userUsdc: accounts.userUsdc, depositor: accounts.depositor }, { amount: args.amountUsdc, minLpOut: args.minLpOut });
12
+ return [ix];
13
+ }
14
+ async function removeLiquidity(opts, accounts, args) {
15
+ const [poolState] = (0, pda_1.poolStatePDA)(opts.marketId, opts.poolProgramId);
16
+ const [vaultAuthority] = (0, pda_1.vaultAuthorityPDA)(opts.marketId, opts.poolProgramId);
17
+ const [lpMint] = (0, pda_1.lpMintPDA)(opts.marketId, opts.poolProgramId);
18
+ const [usdcVault] = (0, pda_1.usdcVaultPDA)(opts.marketId, opts.poolProgramId);
19
+ const ix = await opts.poolClient.withdrawIx({ poolState, usdcVault, vaultAuthority, lpMint, userLp: accounts.userLp, userUsdc: accounts.userUsdc, withdrawer: accounts.withdrawer }, { lpAmount: args.lpAmount, minOut: args.minOut });
20
+ return [ix];
21
+ }
@@ -0,0 +1,39 @@
1
+ import { PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ import { PerpClient, OpenPositionArgs } from "../programs/perp";
3
+ export interface TradingOpts {
4
+ perpClient: PerpClient;
5
+ perpEngineId: PublicKey;
6
+ poolProgramId: PublicKey;
7
+ oracleProgramId: PublicKey;
8
+ marketId: Uint8Array;
9
+ primaryFeedAccount: PublicKey;
10
+ secondaryFeedAccount: PublicKey;
11
+ }
12
+ export declare function openPosition(opts: TradingOpts, accounts: {
13
+ signer: PublicKey;
14
+ signerUsdc: PublicKey;
15
+ tradingKey?: PublicKey | null;
16
+ referralConfig?: PublicKey;
17
+ referralCodeAccount?: PublicKey;
18
+ traderReferral?: PublicKey;
19
+ userClaims?: PublicKey;
20
+ }, args: OpenPositionArgs): Promise<TransactionInstruction[]>;
21
+ export declare function closePosition(opts: TradingOpts, accounts: {
22
+ position: PublicKey;
23
+ owner: PublicKey;
24
+ signer: PublicKey;
25
+ userUsdc: PublicKey;
26
+ tradingKey?: PublicKey | null;
27
+ referralConfig?: PublicKey;
28
+ referralCodeAccount?: PublicKey;
29
+ traderReferral?: PublicKey;
30
+ queueEntryPda?: PublicKey;
31
+ userClaimsPda?: PublicKey;
32
+ }, closeSize: bigint | null, minOutputUsdc?: bigint): Promise<TransactionInstruction[]>;
33
+ export declare function updateMargin(opts: TradingOpts, accounts: {
34
+ position: PublicKey;
35
+ owner: PublicKey;
36
+ signer: PublicKey;
37
+ signerUsdc: PublicKey;
38
+ tradingKey?: PublicKey | null;
39
+ }, delta: bigint): Promise<TransactionInstruction[]>;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.openPosition = openPosition;
4
+ exports.closePosition = closePosition;
5
+ exports.updateMargin = updateMargin;
6
+ const pda_1 = require("../utils/pda");
7
+ async function openPosition(opts, accounts, args) {
8
+ const [marketState] = (0, pda_1.marketStatePDA)(opts.marketId, opts.perpEngineId);
9
+ const [position] = (0, pda_1.positionPDA)(accounts.signer, opts.marketId, args.positionNonce, opts.perpEngineId);
10
+ const [engineAuth] = (0, pda_1.engineAuthPDA)(opts.marketId, opts.perpEngineId);
11
+ const [marketOracle] = (0, pda_1.marketOraclePDA)(opts.marketId, opts.oracleProgramId);
12
+ const [poolState] = (0, pda_1.poolStatePDA)(opts.marketId, opts.poolProgramId);
13
+ const [vaultUsdc] = (0, pda_1.usdcVaultPDA)(opts.marketId, opts.poolProgramId);
14
+ const [feeSettings] = (0, pda_1.feeSettingsPDA)(opts.marketId, opts.poolProgramId);
15
+ const [defaultUserClaims] = (0, pda_1.userQueueClaimsPDA)(opts.marketId, accounts.signer, opts.poolProgramId);
16
+ const ix = await opts.perpClient.openPositionIx({
17
+ marketState,
18
+ position,
19
+ tradingKey: accounts.tradingKey ?? null,
20
+ signer: accounts.signer,
21
+ signerUsdc: accounts.signerUsdc,
22
+ vaultUsdc,
23
+ poolState,
24
+ poolProgram: opts.poolProgramId,
25
+ oracleProgram: opts.oracleProgramId,
26
+ marketOracle,
27
+ engineAuth,
28
+ userClaims: accounts.userClaims ?? defaultUserClaims,
29
+ feeSettings,
30
+ referralConfig: accounts.referralConfig,
31
+ referralCodeAccount: accounts.referralCodeAccount,
32
+ traderReferral: accounts.traderReferral,
33
+ }, args, opts.primaryFeedAccount, opts.secondaryFeedAccount);
34
+ return [ix];
35
+ }
36
+ async function closePosition(opts, accounts, closeSize, minOutputUsdc) {
37
+ const [marketState] = (0, pda_1.marketStatePDA)(opts.marketId, opts.perpEngineId);
38
+ const [engineAuth] = (0, pda_1.engineAuthPDA)(opts.marketId, opts.perpEngineId);
39
+ const [marketOracle] = (0, pda_1.marketOraclePDA)(opts.marketId, opts.oracleProgramId);
40
+ const [poolState] = (0, pda_1.poolStatePDA)(opts.marketId, opts.poolProgramId);
41
+ const [vaultAuthority] = (0, pda_1.vaultAuthorityPDA)(opts.marketId, opts.poolProgramId);
42
+ const [vaultUsdc] = (0, pda_1.usdcVaultPDA)(opts.marketId, opts.poolProgramId);
43
+ const [feeSettings] = (0, pda_1.feeSettingsPDA)(opts.marketId, opts.poolProgramId);
44
+ const [lpMint] = (0, pda_1.lpMintPDA)(opts.marketId, opts.poolProgramId);
45
+ const [insuranceFund] = (0, pda_1.insuranceFundPda)(opts.poolProgramId);
46
+ const [insuranceVault] = (0, pda_1.insuranceVaultPda)(opts.poolProgramId);
47
+ const ix = await opts.perpClient.closePositionIx({
48
+ marketState,
49
+ position: accounts.position,
50
+ tradingKey: accounts.tradingKey ?? null,
51
+ signer: accounts.signer,
52
+ owner: accounts.owner,
53
+ userUsdc: accounts.userUsdc,
54
+ poolState,
55
+ poolProgram: opts.poolProgramId,
56
+ oracleProgram: opts.oracleProgramId,
57
+ marketOracle,
58
+ vaultUsdc,
59
+ vaultAuthority,
60
+ engineAuth,
61
+ feeSettings,
62
+ referralConfig: accounts.referralConfig,
63
+ referralCodeAccount: accounts.referralCodeAccount,
64
+ traderReferral: accounts.traderReferral,
65
+ lpMint,
66
+ insuranceFund,
67
+ insuranceVault,
68
+ }, closeSize, opts.primaryFeedAccount, opts.secondaryFeedAccount, minOutputUsdc, accounts.queueEntryPda, accounts.userClaimsPda);
69
+ return [ix];
70
+ }
71
+ async function updateMargin(opts, accounts, delta) {
72
+ const [marketState] = (0, pda_1.marketStatePDA)(opts.marketId, opts.perpEngineId);
73
+ const [vaultUsdc] = (0, pda_1.usdcVaultPDA)(opts.marketId, opts.poolProgramId);
74
+ const [engineAuth] = (0, pda_1.engineAuthPDA)(opts.marketId, opts.perpEngineId);
75
+ const [poolState] = (0, pda_1.poolStatePDA)(opts.marketId, opts.poolProgramId);
76
+ const [vaultAuthority] = (0, pda_1.vaultAuthorityPDA)(opts.marketId, opts.poolProgramId);
77
+ const [marketOracle] = (0, pda_1.marketOraclePDA)(opts.marketId, opts.oracleProgramId);
78
+ const ix = await opts.perpClient.updatePositionMarginIx({
79
+ marketState,
80
+ position: accounts.position,
81
+ tradingKey: accounts.tradingKey ?? null,
82
+ signer: accounts.signer,
83
+ owner: accounts.owner,
84
+ signerUsdc: accounts.signerUsdc,
85
+ vaultUsdc,
86
+ userUsdc: accounts.signerUsdc,
87
+ vaultAuthority,
88
+ poolState,
89
+ poolProgram: opts.poolProgramId,
90
+ engineAuth,
91
+ oracleProgram: opts.oracleProgramId,
92
+ marketOracle,
93
+ }, delta, opts.primaryFeedAccount, opts.secondaryFeedAccount);
94
+ return [ix];
95
+ }