@parqxchange/sdk 0.1.0 → 0.2.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.
@@ -8,7 +8,8 @@ async function addLiquidity(opts, accounts, args) {
8
8
  const [vaultAuthority] = (0, pda_1.vaultAuthorityPDA)(opts.marketId, opts.poolProgramId);
9
9
  const [lpMint] = (0, pda_1.lpMintPDA)(opts.marketId, opts.poolProgramId);
10
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 });
11
+ const [lpDead] = (0, pda_1.lpDeadPDA)(opts.marketId, opts.poolProgramId);
12
+ const ix = await opts.poolClient.depositIx({ poolState, usdcVault, vaultAuthority, lpMint, userLp: accounts.userLp, userUsdc: accounts.userUsdc, lpDead, depositor: accounts.depositor }, { amount: args.amountUsdc, minLpOut: args.minLpOut });
12
13
  return [ix];
13
14
  }
14
15
  async function removeLiquidity(opts, accounts, args) {
@@ -18,10 +18,10 @@ exports.decodeStakePosition = decodeStakePosition;
18
18
  exports.decodePayoutQueueEntry = decodePayoutQueueEntry;
19
19
  exports.decodeUserQueueClaims = decodeUserQueueClaims;
20
20
  exports.identifyAccountType = identifyAccountType;
21
- const node_crypto_1 = require("node:crypto");
21
+ const sha256_1 = require("@noble/hashes/sha256");
22
22
  const web3_js_1 = require("@solana/web3.js");
23
23
  function sha256Disc(name) {
24
- const hash = (0, node_crypto_1.createHash)("sha256").update(`account:${name}`).digest();
24
+ const hash = Buffer.from((0, sha256_1.sha256)(new TextEncoder().encode(`account:${name}`)));
25
25
  return hash.subarray(0, 8);
26
26
  }
27
27
  exports.DISCRIMINATORS = {
@@ -148,8 +148,8 @@ function decodePosition(data) {
148
148
  }
149
149
  function decodeMarketState(data) {
150
150
  checkDisc(data, exports.DISCRIMINATORS.MarketState, "MarketState");
151
- if (data.length !== 460 && data.length !== 476 && data.length !== 511) {
152
- checkLen(data, 511, "MarketState");
151
+ if (data.length !== 460 && data.length !== 476 && data.length !== 511 && data.length !== 515) {
152
+ checkLen(data, 515, "MarketState");
153
153
  }
154
154
  const v = makeView(data);
155
155
  const base = {
@@ -199,7 +199,7 @@ function decodeMarketState(data) {
199
199
  offHoursMaxOiShort: readU64LE(v, 468),
200
200
  };
201
201
  if (data.length >= 511) {
202
- return {
202
+ const v3 = {
203
203
  ...v2,
204
204
  adlFrozen: readU8(v, 476),
205
205
  adlTailTriggerUsdcRth: readU64LE(v, 477),
@@ -212,6 +212,14 @@ function decodeMarketState(data) {
212
212
  adlMaxFeedDivergenceBps: readU16LE(v, 507),
213
213
  initialMarginBps: readU16LE(v, 509),
214
214
  };
215
+ if (data.length >= 515) {
216
+ return {
217
+ ...v3,
218
+ liqFeeBps: readU16LE(v, 511),
219
+ partialLiqTargetHealth: readU16LE(v, 513),
220
+ };
221
+ }
222
+ return v3;
215
223
  }
216
224
  return v2;
217
225
  }
@@ -363,8 +371,11 @@ function decodeFeePool(data) {
363
371
  }
364
372
  function decodeStakingPool(data) {
365
373
  checkDisc(data, exports.DISCRIMINATORS.StakingPool, "StakingPool");
366
- checkLen(data, 282, "StakingPool");
374
+ if (data.byteLength !== 282 && data.byteLength !== 290) {
375
+ throw new DecoderError(`StakingPool: expected 282 or 290 bytes, got ${data.byteLength}`);
376
+ }
367
377
  const v = makeView(data);
378
+ const hasTotalClaimed = data.byteLength >= 290;
368
379
  return {
369
380
  admin: readPubkey(v, 8),
370
381
  tokenMint: readPubkey(v, 40),
@@ -382,6 +393,7 @@ function decodeStakingPool(data) {
382
393
  emittedSoFar: readU64LE(v, 265),
383
394
  lastUpdateTs: readI64LE(v, 273),
384
395
  bump: readU8(v, 281),
396
+ totalClaimed: hasTotalClaimed ? readU64LE(v, 282) : 0n,
385
397
  };
386
398
  }
387
399
  function decodeStakePosition(data) {
@@ -1,4 +1,4 @@
1
- import type { PositionOpenedEvent, PositionClosedEvent, LiquidatedEvent, BadDebtEvent, FundingUpdatedEvent, EnqueuedEvent, HarvestedEvent, EntryVoidedEvent, SideBucketCreditedEvent, QueueDrainedEvent, PhantomCreditDrainedEvent, FeesSweptEvent, FeesDistributedEvent, TreasuryWithdrawalEvent, StakedEvent, UnstakedEvent, RewardClaimedEvent, RewardIndexUpdatedEvent, CompoundedRewardEvent } from "../types";
1
+ import type { PositionOpenedEvent, PositionClosedEvent, LiquidatedEvent, BadDebtEvent, FundingUpdatedEvent, EnqueuedEvent, HarvestedEvent, EntryVoidedEvent, SideBucketCreditedEvent, QueueDrainedEvent, QueueLpDrawEvent, PhantomCreditDrainedEvent, FeesSweptEvent, FeesDistributedEvent, TreasuryWithdrawalEvent, StakedEvent, UnstakedEvent, RewardClaimedEvent, RewardIndexUpdatedEvent, CompoundedRewardEvent } from "../types";
2
2
  export type DecodedEvent = {
3
3
  type: "positionOpened";
4
4
  data: PositionOpenedEvent;
@@ -29,6 +29,9 @@ export type DecodedEvent = {
29
29
  } | {
30
30
  type: "queueDrained";
31
31
  data: QueueDrainedEvent;
32
+ } | {
33
+ type: "queueLpDraw";
34
+ data: QueueLpDrawEvent;
32
35
  } | {
33
36
  type: "phantomCreditDrained";
34
37
  data: PhantomCreditDrainedEvent;
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.decodeAnchorEvent = decodeAnchorEvent;
4
4
  const web3_js_1 = require("@solana/web3.js");
5
- const node_crypto_1 = require("node:crypto");
5
+ const sha256_1 = require("@noble/hashes/sha256");
6
6
  function sha256Disc(name) {
7
- return (0, node_crypto_1.createHash)("sha256").update(name).digest().subarray(0, 8);
7
+ return Buffer.from((0, sha256_1.sha256)(new TextEncoder().encode(name))).subarray(0, 8);
8
8
  }
9
9
  const EVENT_DISCS = {
10
10
  PositionOpened: sha256Disc("event:PositionOpened"),
@@ -17,6 +17,7 @@ const EVENT_DISCS = {
17
17
  EntryVoided: sha256Disc("event:EntryVoided"),
18
18
  SideBucketCredited: sha256Disc("event:SideBucketCredited"),
19
19
  QueueDrained: sha256Disc("event:QueueDrained"),
20
+ QueueLpDraw: sha256Disc("event:QueueLpDraw"),
20
21
  PhantomCreditDrained: sha256Disc("event:PhantomCreditDrained"),
21
22
  FeesSwept: sha256Disc("event:FeesSwept"),
22
23
  FeesDistributed: sha256Disc("event:FeesDistributed"),
@@ -160,6 +161,16 @@ function decodeQueueDrained(data) {
160
161
  residualToTreasury: readU64LE(v, 40),
161
162
  };
162
163
  }
164
+ function decodeQueueLpDraw(data) {
165
+ const v = makeView(data);
166
+ return {
167
+ marketId: readBytes(v, 8, 32),
168
+ idx: readU64LE(v, 40),
169
+ owner: readPubkey(v, 48),
170
+ amount: readU64LE(v, 80),
171
+ totalUsdcAfter: readU64LE(v, 88),
172
+ };
173
+ }
163
174
  function decodePhantomCreditDrained(data) {
164
175
  const v = makeView(data);
165
176
  return {
@@ -311,6 +322,12 @@ function decodeAnchorEvent(base64Data) {
311
322
  return { type: "queueDrained", data };
312
323
  return null;
313
324
  }
325
+ if (discMatches(raw, EVENT_DISCS.QueueLpDraw)) {
326
+ const data = tryDecodePayload(() => decodeQueueLpDraw(raw));
327
+ if (data)
328
+ return { type: "queueLpDraw", data };
329
+ return null;
330
+ }
314
331
  if (discMatches(raw, EVENT_DISCS.PhantomCreditDrained)) {
315
332
  const data = tryDecodePayload(() => decodePhantomCreditDrained(raw));
316
333
  if (data)
@@ -33,6 +33,7 @@ export declare class PoolClient {
33
33
  lpMint: PublicKey;
34
34
  userLp: PublicKey;
35
35
  userUsdc: PublicKey;
36
+ lpDead: PublicKey;
36
37
  depositor: PublicKey;
37
38
  }, args: {
38
39
  amount: bigint;
@@ -93,6 +94,17 @@ export declare class PoolClient {
93
94
  }, args: {
94
95
  amount: bigint;
95
96
  }): Promise<TransactionInstruction>;
97
+ sweepStrandedToInsuranceIx(accounts: {
98
+ poolState: PublicKey;
99
+ poolVaultUsdc: PublicKey;
100
+ vaultAuthority: PublicKey;
101
+ lpMint: PublicKey;
102
+ insuranceFund: PublicKey;
103
+ insuranceVault: PublicKey;
104
+ admin: PublicKey;
105
+ }, args: {
106
+ amount: bigint;
107
+ }): Promise<TransactionInstruction>;
96
108
  withdrawInsuranceIx(accounts: {
97
109
  insuranceFund: PublicKey;
98
110
  insuranceVault: PublicKey;
@@ -45,7 +45,11 @@ class PoolClient {
45
45
  async depositIx(accounts, args) {
46
46
  return this.program.methods
47
47
  .deposit(new anchor_1.BN(args.amount.toString()), new anchor_1.BN(args.minLpOut.toString()))
48
- .accounts({ ...accounts, tokenProgram: spl_token_1.TOKEN_PROGRAM_ID })
48
+ .accounts({
49
+ ...accounts,
50
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
51
+ systemProgram: web3_js_1.SystemProgram.programId,
52
+ })
49
53
  .instruction();
50
54
  }
51
55
  async withdrawIx(accounts, args) {
@@ -104,6 +108,15 @@ class PoolClient {
104
108
  })
105
109
  .instruction();
106
110
  }
111
+ async sweepStrandedToInsuranceIx(accounts, args) {
112
+ return this.program.methods
113
+ .sweepStrandedToInsurance(new anchor_1.BN(args.amount.toString()))
114
+ .accounts({
115
+ ...accounts,
116
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
117
+ })
118
+ .instruction();
119
+ }
107
120
  async withdrawInsuranceIx(accounts, args) {
108
121
  return this.program.methods
109
122
  .withdrawInsurance(new anchor_1.BN(args.amount.toString()))
@@ -65,6 +65,8 @@ export interface MarketState {
65
65
  adlMaxHaircutBps?: number;
66
66
  adlMaxFeedDivergenceBps?: number;
67
67
  initialMarginBps?: number;
68
+ liqFeeBps?: number;
69
+ partialLiqTargetHealth?: number;
68
70
  }
69
71
  export interface Market {
70
72
  marketId: Uint8Array;
@@ -199,6 +201,7 @@ export interface StakingPool {
199
201
  emittedSoFar: bigint;
200
202
  lastUpdateTs: bigint;
201
203
  bump: number;
204
+ totalClaimed: bigint;
202
205
  }
203
206
  export interface StakePosition {
204
207
  pool: PublicKey;
@@ -292,6 +295,13 @@ export interface QueueDrainedEvent {
292
295
  marketId: Uint8Array;
293
296
  residualToTreasury: bigint;
294
297
  }
298
+ export interface QueueLpDrawEvent {
299
+ marketId: Uint8Array;
300
+ idx: bigint;
301
+ owner: PublicKey;
302
+ amount: bigint;
303
+ totalUsdcAfter: bigint;
304
+ }
295
305
  export interface PhantomCreditDrainedEvent {
296
306
  owner: PublicKey;
297
307
  marketId: Uint8Array;
@@ -3,6 +3,7 @@ export declare function poolStatePDA(marketId: Uint8Array, programId: PublicKey)
3
3
  export declare function vaultAuthorityPDA(marketId: Uint8Array, programId: PublicKey): [PublicKey, number];
4
4
  export declare function usdcVaultPDA(marketId: Uint8Array, programId: PublicKey): [PublicKey, number];
5
5
  export declare function lpMintPDA(marketId: Uint8Array, programId: PublicKey): [PublicKey, number];
6
+ export declare function lpDeadPDA(marketId: Uint8Array, programId: PublicKey): [PublicKey, number];
6
7
  export declare function marketStatePDA(marketId: Uint8Array, programId: PublicKey): [PublicKey, number];
7
8
  export declare function positionPDA(owner: PublicKey, marketId: Uint8Array, nonce: bigint, programId: PublicKey): [PublicKey, number];
8
9
  export declare function tradingKeyPDA(wallet: PublicKey, programId: PublicKey): [PublicKey, number];
package/dist/utils/pda.js CHANGED
@@ -4,6 +4,7 @@ exports.poolStatePDA = poolStatePDA;
4
4
  exports.vaultAuthorityPDA = vaultAuthorityPDA;
5
5
  exports.usdcVaultPDA = usdcVaultPDA;
6
6
  exports.lpMintPDA = lpMintPDA;
7
+ exports.lpDeadPDA = lpDeadPDA;
7
8
  exports.marketStatePDA = marketStatePDA;
8
9
  exports.positionPDA = positionPDA;
9
10
  exports.tradingKeyPDA = tradingKeyPDA;
@@ -40,6 +41,9 @@ function usdcVaultPDA(marketId, programId) {
40
41
  function lpMintPDA(marketId, programId) {
41
42
  return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("lp_mint"), marketId instanceof Buffer ? marketId : Buffer.from(marketId)], programId);
42
43
  }
44
+ function lpDeadPDA(marketId, programId) {
45
+ return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("lp_dead"), marketId instanceof Buffer ? marketId : Buffer.from(marketId)], programId);
46
+ }
43
47
  function marketStatePDA(marketId, programId) {
44
48
  return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("market"), marketId instanceof Buffer ? marketId : Buffer.from(marketId)], programId);
45
49
  }
@@ -267,7 +267,7 @@
267
267
  {
268
268
  "name": "lp_mint",
269
269
  "docs": [
270
- "Ref 123 — pool-program reads these 3 from CPI remaining_accounts to",
270
+ "Followup #123 — pool-program reads these 3 from CPI remaining_accounts to",
271
271
  "decide whether lp_gain on a Treasury-routed losing close should be swept",
272
272
  "to insurance_vault (when lp_mint.supply == 0) instead of stranding in",
273
273
  "pool.total_usdc. Pool-program does all validation; perp-engine just",
@@ -996,7 +996,7 @@
996
996
  {
997
997
  "name": "lp_mint",
998
998
  "docs": [
999
- "Ref 123 — pool-program's release_and_settle reads lp_mint.supply",
999
+ "Followup #123 — pool-program's release_and_settle reads lp_mint.supply",
1000
1000
  "to decide whether a Treasury-routed lp_gain should be swept to",
1001
1001
  "insurance_vault (lp_supply == 0) instead of stranding in pool.total_usdc.",
1002
1002
  "Pool-program verifies vs pool.lp_mint."
@@ -1214,6 +1214,98 @@
1214
1214
  }
1215
1215
  ]
1216
1216
  },
1217
+ {
1218
+ "name": "migrate_market_state_v4",
1219
+ "docs": [
1220
+ "MarketState V3 → V4 (2026-06-09): appends liq_fee_bps (default 2000 = 20%) +",
1221
+ "partial_liq_target_health (default 0 = partial disabled) at offset 511. LEN 511→515."
1222
+ ],
1223
+ "discriminator": [
1224
+ 223,
1225
+ 134,
1226
+ 45,
1227
+ 244,
1228
+ 94,
1229
+ 137,
1230
+ 150,
1231
+ 101
1232
+ ],
1233
+ "accounts": [
1234
+ {
1235
+ "name": "market_state",
1236
+ "writable": true,
1237
+ "pda": {
1238
+ "seeds": [
1239
+ {
1240
+ "kind": "const",
1241
+ "value": [
1242
+ 109,
1243
+ 97,
1244
+ 114,
1245
+ 107,
1246
+ 101,
1247
+ 116
1248
+ ]
1249
+ },
1250
+ {
1251
+ "kind": "arg",
1252
+ "path": "market_id"
1253
+ }
1254
+ ]
1255
+ }
1256
+ },
1257
+ {
1258
+ "name": "protocol_config",
1259
+ "pda": {
1260
+ "seeds": [
1261
+ {
1262
+ "kind": "const",
1263
+ "value": [
1264
+ 112,
1265
+ 114,
1266
+ 111,
1267
+ 116,
1268
+ 111,
1269
+ 99,
1270
+ 111,
1271
+ 108,
1272
+ 95,
1273
+ 99,
1274
+ 111,
1275
+ 110,
1276
+ 102,
1277
+ 105,
1278
+ 103
1279
+ ]
1280
+ }
1281
+ ]
1282
+ }
1283
+ },
1284
+ {
1285
+ "name": "admin",
1286
+ "writable": true,
1287
+ "signer": true,
1288
+ "relations": [
1289
+ "protocol_config"
1290
+ ]
1291
+ },
1292
+ {
1293
+ "name": "system_program",
1294
+ "address": "11111111111111111111111111111111"
1295
+ }
1296
+ ],
1297
+ "args": [
1298
+ {
1299
+ "name": "market_id",
1300
+ "type": {
1301
+ "array": [
1302
+ "u8",
1303
+ 32
1304
+ ]
1305
+ }
1306
+ }
1307
+ ]
1308
+ },
1217
1309
  {
1218
1310
  "name": "migrate_protocol_config_v2",
1219
1311
  "discriminator": [
@@ -3057,6 +3149,14 @@
3057
3149
  {
3058
3150
  "name": "initial_margin_bps",
3059
3151
  "type": "u16"
3152
+ },
3153
+ {
3154
+ "name": "liq_fee_bps",
3155
+ "type": "u16"
3156
+ },
3157
+ {
3158
+ "name": "partial_liq_target_health",
3159
+ "type": "u16"
3060
3160
  }
3061
3161
  ]
3062
3162
  }
@@ -3338,6 +3438,15 @@
3338
3438
  {
3339
3439
  "name": "exit_price",
3340
3440
  "type": "u64"
3441
+ },
3442
+ {
3443
+ "name": "funding_charge",
3444
+ "docs": [
3445
+ "Signed funding settled at close, 6-dec USDC. `> 0` = trader paid funding,",
3446
+ "`< 0` = trader received it; subtracted from `net_return` on-chain. Appended",
3447
+ "last so the field is byte-additive (old decoders read the prefix unchanged)."
3448
+ ],
3449
+ "type": "i64"
3341
3450
  }
3342
3451
  ]
3343
3452
  }
@@ -3530,7 +3639,7 @@
3530
3639
  "without joining against `PositionClosed` rows — `size_usdc` is the close",
3531
3640
  "notional (for `volumeReferred`), `amount` is the rebate (for",
3532
3641
  "`rebatesEarned`), and the trade-count aggregate is just `COUNT(*)` filtered",
3533
- "by `affiliate`. Closes ref 99 (path A — emit canonical event from the",
3642
+ "by `affiliate`. Closes followup #99 (path A — emit canonical event from the",
3534
3643
  "rebate-credit site instead of polling AffiliateReward PDAs or approximating",
3535
3644
  "from referral-attribution PDAs)."
3536
3645
  ],
@@ -3847,6 +3956,18 @@
3847
3956
  "type": {
3848
3957
  "option": "u16"
3849
3958
  }
3959
+ },
3960
+ {
3961
+ "name": "liq_fee_bps",
3962
+ "type": {
3963
+ "option": "u16"
3964
+ }
3965
+ },
3966
+ {
3967
+ "name": "partial_liq_target_health",
3968
+ "type": {
3969
+ "option": "u16"
3970
+ }
3850
3971
  }
3851
3972
  ]
3852
3973
  }